* gcc.dg/gomp/openmp-simd-1.c: Cleanup original tree dump.
[official-gcc.git] / gcc / tree-sra.c
blob0890613852b138c2e796909cdb45497c6c6ac47b
1 /* Scalar Replacement of Aggregates (SRA) converts some structure
2 references into scalar references, exposing them to the scalar
3 optimizers.
4 Copyright (C) 2008-2013 Free Software Foundation, Inc.
5 Contributed by Martin Jambor <mjambor@suse.cz>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* This file implements Scalar Reduction of Aggregates (SRA). SRA is run
24 twice, once in the early stages of compilation (early SRA) and once in the
25 late stages (late SRA). The aim of both is to turn references to scalar
26 parts of aggregates into uses of independent scalar variables.
28 The two passes are nearly identical, the only difference is that early SRA
29 does not scalarize unions which are used as the result in a GIMPLE_RETURN
30 statement because together with inlining this can lead to weird type
31 conversions.
33 Both passes operate in four stages:
35 1. The declarations that have properties which make them candidates for
36 scalarization are identified in function find_var_candidates(). The
37 candidates are stored in candidate_bitmap.
39 2. The function body is scanned. In the process, declarations which are
40 used in a manner that prevent their scalarization are removed from the
41 candidate bitmap. More importantly, for every access into an aggregate,
42 an access structure (struct access) is created by create_access() and
43 stored in a vector associated with the aggregate. Among other
44 information, the aggregate declaration, the offset and size of the access
45 and its type are stored in the structure.
47 On a related note, assign_link structures are created for every assign
48 statement between candidate aggregates and attached to the related
49 accesses.
51 3. The vectors of accesses are analyzed. They are first sorted according to
52 their offset and size and then scanned for partially overlapping accesses
53 (i.e. those which overlap but one is not entirely within another). Such
54 an access disqualifies the whole aggregate from being scalarized.
56 If there is no such inhibiting overlap, a representative access structure
57 is chosen for every unique combination of offset and size. Afterwards,
58 the pass builds a set of trees from these structures, in which children
59 of an access are within their parent (in terms of offset and size).
61 Then accesses are propagated whenever possible (i.e. in cases when it
62 does not create a partially overlapping access) across assign_links from
63 the right hand side to the left hand side.
65 Then the set of trees for each declaration is traversed again and those
66 accesses which should be replaced by a scalar are identified.
68 4. The function is traversed again, and for every reference into an
69 aggregate that has some component which is about to be scalarized,
70 statements are amended and new statements are created as necessary.
71 Finally, if a parameter got scalarized, the scalar replacements are
72 initialized with values from respective parameter aggregates. */
74 #include "config.h"
75 #include "system.h"
76 #include "coretypes.h"
77 #include "hash-table.h"
78 #include "alloc-pool.h"
79 #include "tm.h"
80 #include "tree.h"
81 #include "pointer-set.h"
82 #include "basic-block.h"
83 #include "tree-ssa-alias.h"
84 #include "internal-fn.h"
85 #include "tree-eh.h"
86 #include "gimple-expr.h"
87 #include "is-a.h"
88 #include "gimple.h"
89 #include "stor-layout.h"
90 #include "gimplify.h"
91 #include "gimple-iterator.h"
92 #include "gimplify-me.h"
93 #include "gimple-walk.h"
94 #include "bitmap.h"
95 #include "gimple-ssa.h"
96 #include "tree-cfg.h"
97 #include "tree-phinodes.h"
98 #include "ssa-iterators.h"
99 #include "stringpool.h"
100 #include "tree-ssanames.h"
101 #include "expr.h"
102 #include "tree-dfa.h"
103 #include "tree-ssa.h"
104 #include "tree-pass.h"
105 #include "ipa-prop.h"
106 #include "statistics.h"
107 #include "params.h"
108 #include "target.h"
109 #include "flags.h"
110 #include "dbgcnt.h"
111 #include "tree-inline.h"
112 #include "gimple-pretty-print.h"
113 #include "ipa-inline.h"
114 #include "ipa-utils.h"
116 /* Enumeration of all aggregate reductions we can do. */
117 enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
118 SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
119 SRA_MODE_INTRA }; /* late intraprocedural SRA */
121 /* Global variable describing which aggregate reduction we are performing at
122 the moment. */
123 static enum sra_mode sra_mode;
125 struct assign_link;
127 /* ACCESS represents each access to an aggregate variable (as a whole or a
128 part). It can also represent a group of accesses that refer to exactly the
129 same fragment of an aggregate (i.e. those that have exactly the same offset
130 and size). Such representatives for a single aggregate, once determined,
131 are linked in a linked list and have the group fields set.
133 Moreover, when doing intraprocedural SRA, a tree is built from those
134 representatives (by the means of first_child and next_sibling pointers), in
135 which all items in a subtree are "within" the root, i.e. their offset is
136 greater or equal to offset of the root and offset+size is smaller or equal
137 to offset+size of the root. Children of an access are sorted by offset.
139 Note that accesses to parts of vector and complex number types always
140 represented by an access to the whole complex number or a vector. It is a
141 duty of the modifying functions to replace them appropriately. */
143 struct access
145 /* Values returned by `get_ref_base_and_extent' for each component reference
146 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
147 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
148 HOST_WIDE_INT offset;
149 HOST_WIDE_INT size;
150 tree base;
152 /* Expression. It is context dependent so do not use it to create new
153 expressions to access the original aggregate. See PR 42154 for a
154 testcase. */
155 tree expr;
156 /* Type. */
157 tree type;
159 /* The statement this access belongs to. */
160 gimple stmt;
162 /* Next group representative for this aggregate. */
163 struct access *next_grp;
165 /* Pointer to the group representative. Pointer to itself if the struct is
166 the representative. */
167 struct access *group_representative;
169 /* If this access has any children (in terms of the definition above), this
170 points to the first one. */
171 struct access *first_child;
173 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
174 described above. In IPA-SRA this is a pointer to the next access
175 belonging to the same group (having the same representative). */
176 struct access *next_sibling;
178 /* Pointers to the first and last element in the linked list of assign
179 links. */
180 struct assign_link *first_link, *last_link;
182 /* Pointer to the next access in the work queue. */
183 struct access *next_queued;
185 /* Replacement variable for this access "region." Never to be accessed
186 directly, always only by the means of get_access_replacement() and only
187 when grp_to_be_replaced flag is set. */
188 tree replacement_decl;
190 /* Is this particular access write access? */
191 unsigned write : 1;
193 /* Is this access an access to a non-addressable field? */
194 unsigned non_addressable : 1;
196 /* Is this access currently in the work queue? */
197 unsigned grp_queued : 1;
199 /* Does this group contain a write access? This flag is propagated down the
200 access tree. */
201 unsigned grp_write : 1;
203 /* Does this group contain a read access? This flag is propagated down the
204 access tree. */
205 unsigned grp_read : 1;
207 /* Does this group contain a read access that comes from an assignment
208 statement? This flag is propagated down the access tree. */
209 unsigned grp_assignment_read : 1;
211 /* Does this group contain a write access that comes from an assignment
212 statement? This flag is propagated down the access tree. */
213 unsigned grp_assignment_write : 1;
215 /* Does this group contain a read access through a scalar type? This flag is
216 not propagated in the access tree in any direction. */
217 unsigned grp_scalar_read : 1;
219 /* Does this group contain a write access through a scalar type? This flag
220 is not propagated in the access tree in any direction. */
221 unsigned grp_scalar_write : 1;
223 /* Is this access an artificial one created to scalarize some record
224 entirely? */
225 unsigned grp_total_scalarization : 1;
227 /* Other passes of the analysis use this bit to make function
228 analyze_access_subtree create scalar replacements for this group if
229 possible. */
230 unsigned grp_hint : 1;
232 /* Is the subtree rooted in this access fully covered by scalar
233 replacements? */
234 unsigned grp_covered : 1;
236 /* If set to true, this access and all below it in an access tree must not be
237 scalarized. */
238 unsigned grp_unscalarizable_region : 1;
240 /* Whether data have been written to parts of the aggregate covered by this
241 access which is not to be scalarized. This flag is propagated up in the
242 access tree. */
243 unsigned grp_unscalarized_data : 1;
245 /* Does this access and/or group contain a write access through a
246 BIT_FIELD_REF? */
247 unsigned grp_partial_lhs : 1;
249 /* Set when a scalar replacement should be created for this variable. */
250 unsigned grp_to_be_replaced : 1;
252 /* Set when we want a replacement for the sole purpose of having it in
253 generated debug statements. */
254 unsigned grp_to_be_debug_replaced : 1;
256 /* Should TREE_NO_WARNING of a replacement be set? */
257 unsigned grp_no_warning : 1;
259 /* Is it possible that the group refers to data which might be (directly or
260 otherwise) modified? */
261 unsigned grp_maybe_modified : 1;
263 /* Set when this is a representative of a pointer to scalar (i.e. by
264 reference) parameter which we consider for turning into a plain scalar
265 (i.e. a by value parameter). */
266 unsigned grp_scalar_ptr : 1;
268 /* Set when we discover that this pointer is not safe to dereference in the
269 caller. */
270 unsigned grp_not_necessarilly_dereferenced : 1;
273 typedef struct access *access_p;
276 /* Alloc pool for allocating access structures. */
277 static alloc_pool access_pool;
279 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
280 are used to propagate subaccesses from rhs to lhs as long as they don't
281 conflict with what is already there. */
282 struct assign_link
284 struct access *lacc, *racc;
285 struct assign_link *next;
288 /* Alloc pool for allocating assign link structures. */
289 static alloc_pool link_pool;
291 /* Base (tree) -> Vector (vec<access_p> *) map. */
292 static struct pointer_map_t *base_access_vec;
294 /* Candidate hash table helpers. */
296 struct uid_decl_hasher : typed_noop_remove <tree_node>
298 typedef tree_node value_type;
299 typedef tree_node compare_type;
300 static inline hashval_t hash (const value_type *);
301 static inline bool equal (const value_type *, const compare_type *);
304 /* Hash a tree in a uid_decl_map. */
306 inline hashval_t
307 uid_decl_hasher::hash (const value_type *item)
309 return item->decl_minimal.uid;
312 /* Return true if the DECL_UID in both trees are equal. */
314 inline bool
315 uid_decl_hasher::equal (const value_type *a, const compare_type *b)
317 return (a->decl_minimal.uid == b->decl_minimal.uid);
320 /* Set of candidates. */
321 static bitmap candidate_bitmap;
322 static hash_table <uid_decl_hasher> candidates;
324 /* For a candidate UID return the candidates decl. */
326 static inline tree
327 candidate (unsigned uid)
329 tree_node t;
330 t.decl_minimal.uid = uid;
331 return candidates.find_with_hash (&t, static_cast <hashval_t> (uid));
334 /* Bitmap of candidates which we should try to entirely scalarize away and
335 those which cannot be (because they are and need be used as a whole). */
336 static bitmap should_scalarize_away_bitmap, cannot_scalarize_away_bitmap;
338 /* Obstack for creation of fancy names. */
339 static struct obstack name_obstack;
341 /* Head of a linked list of accesses that need to have its subaccesses
342 propagated to their assignment counterparts. */
343 static struct access *work_queue_head;
345 /* Number of parameters of the analyzed function when doing early ipa SRA. */
346 static int func_param_count;
348 /* scan_function sets the following to true if it encounters a call to
349 __builtin_apply_args. */
350 static bool encountered_apply_args;
352 /* Set by scan_function when it finds a recursive call. */
353 static bool encountered_recursive_call;
355 /* Set by scan_function when it finds a recursive call with less actual
356 arguments than formal parameters.. */
357 static bool encountered_unchangable_recursive_call;
359 /* This is a table in which for each basic block and parameter there is a
360 distance (offset + size) in that parameter which is dereferenced and
361 accessed in that BB. */
362 static HOST_WIDE_INT *bb_dereferences;
363 /* Bitmap of BBs that can cause the function to "stop" progressing by
364 returning, throwing externally, looping infinitely or calling a function
365 which might abort etc.. */
366 static bitmap final_bbs;
368 /* Representative of no accesses at all. */
369 static struct access no_accesses_representant;
371 /* Predicate to test the special value. */
373 static inline bool
374 no_accesses_p (struct access *access)
376 return access == &no_accesses_representant;
379 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
380 representative fields are dumped, otherwise those which only describe the
381 individual access are. */
383 static struct
385 /* Number of processed aggregates is readily available in
386 analyze_all_variable_accesses and so is not stored here. */
388 /* Number of created scalar replacements. */
389 int replacements;
391 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
392 expression. */
393 int exprs;
395 /* Number of statements created by generate_subtree_copies. */
396 int subtree_copies;
398 /* Number of statements created by load_assign_lhs_subreplacements. */
399 int subreplacements;
401 /* Number of times sra_modify_assign has deleted a statement. */
402 int deleted;
404 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
405 RHS reparately due to type conversions or nonexistent matching
406 references. */
407 int separate_lhs_rhs_handling;
409 /* Number of parameters that were removed because they were unused. */
410 int deleted_unused_parameters;
412 /* Number of scalars passed as parameters by reference that have been
413 converted to be passed by value. */
414 int scalar_by_ref_to_by_val;
416 /* Number of aggregate parameters that were replaced by one or more of their
417 components. */
418 int aggregate_params_reduced;
420 /* Numbber of components created when splitting aggregate parameters. */
421 int param_reductions_created;
422 } sra_stats;
424 static void
425 dump_access (FILE *f, struct access *access, bool grp)
427 fprintf (f, "access { ");
428 fprintf (f, "base = (%d)'", DECL_UID (access->base));
429 print_generic_expr (f, access->base, 0);
430 fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
431 fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
432 fprintf (f, ", expr = ");
433 print_generic_expr (f, access->expr, 0);
434 fprintf (f, ", type = ");
435 print_generic_expr (f, access->type, 0);
436 if (grp)
437 fprintf (f, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
438 "grp_assignment_write = %d, grp_scalar_read = %d, "
439 "grp_scalar_write = %d, grp_total_scalarization = %d, "
440 "grp_hint = %d, grp_covered = %d, "
441 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
442 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
443 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
444 "grp_not_necessarilly_dereferenced = %d\n",
445 access->grp_read, access->grp_write, access->grp_assignment_read,
446 access->grp_assignment_write, access->grp_scalar_read,
447 access->grp_scalar_write, access->grp_total_scalarization,
448 access->grp_hint, access->grp_covered,
449 access->grp_unscalarizable_region, access->grp_unscalarized_data,
450 access->grp_partial_lhs, access->grp_to_be_replaced,
451 access->grp_to_be_debug_replaced, access->grp_maybe_modified,
452 access->grp_not_necessarilly_dereferenced);
453 else
454 fprintf (f, ", write = %d, grp_total_scalarization = %d, "
455 "grp_partial_lhs = %d\n",
456 access->write, access->grp_total_scalarization,
457 access->grp_partial_lhs);
460 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
462 static void
463 dump_access_tree_1 (FILE *f, struct access *access, int level)
467 int i;
469 for (i = 0; i < level; i++)
470 fputs ("* ", dump_file);
472 dump_access (f, access, true);
474 if (access->first_child)
475 dump_access_tree_1 (f, access->first_child, level + 1);
477 access = access->next_sibling;
479 while (access);
482 /* Dump all access trees for a variable, given the pointer to the first root in
483 ACCESS. */
485 static void
486 dump_access_tree (FILE *f, struct access *access)
488 for (; access; access = access->next_grp)
489 dump_access_tree_1 (f, access, 0);
492 /* Return true iff ACC is non-NULL and has subaccesses. */
494 static inline bool
495 access_has_children_p (struct access *acc)
497 return acc && acc->first_child;
500 /* Return true iff ACC is (partly) covered by at least one replacement. */
502 static bool
503 access_has_replacements_p (struct access *acc)
505 struct access *child;
506 if (acc->grp_to_be_replaced)
507 return true;
508 for (child = acc->first_child; child; child = child->next_sibling)
509 if (access_has_replacements_p (child))
510 return true;
511 return false;
514 /* Return a vector of pointers to accesses for the variable given in BASE or
515 NULL if there is none. */
517 static vec<access_p> *
518 get_base_access_vector (tree base)
520 void **slot;
522 slot = pointer_map_contains (base_access_vec, base);
523 if (!slot)
524 return NULL;
525 else
526 return *(vec<access_p> **) slot;
529 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
530 in ACCESS. Return NULL if it cannot be found. */
532 static struct access *
533 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
534 HOST_WIDE_INT size)
536 while (access && (access->offset != offset || access->size != size))
538 struct access *child = access->first_child;
540 while (child && (child->offset + child->size <= offset))
541 child = child->next_sibling;
542 access = child;
545 return access;
548 /* Return the first group representative for DECL or NULL if none exists. */
550 static struct access *
551 get_first_repr_for_decl (tree base)
553 vec<access_p> *access_vec;
555 access_vec = get_base_access_vector (base);
556 if (!access_vec)
557 return NULL;
559 return (*access_vec)[0];
562 /* Find an access representative for the variable BASE and given OFFSET and
563 SIZE. Requires that access trees have already been built. Return NULL if
564 it cannot be found. */
566 static struct access *
567 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
568 HOST_WIDE_INT size)
570 struct access *access;
572 access = get_first_repr_for_decl (base);
573 while (access && (access->offset + access->size <= offset))
574 access = access->next_grp;
575 if (!access)
576 return NULL;
578 return find_access_in_subtree (access, offset, size);
581 /* Add LINK to the linked list of assign links of RACC. */
582 static void
583 add_link_to_rhs (struct access *racc, struct assign_link *link)
585 gcc_assert (link->racc == racc);
587 if (!racc->first_link)
589 gcc_assert (!racc->last_link);
590 racc->first_link = link;
592 else
593 racc->last_link->next = link;
595 racc->last_link = link;
596 link->next = NULL;
599 /* Move all link structures in their linked list in OLD_RACC to the linked list
600 in NEW_RACC. */
601 static void
602 relink_to_new_repr (struct access *new_racc, struct access *old_racc)
604 if (!old_racc->first_link)
606 gcc_assert (!old_racc->last_link);
607 return;
610 if (new_racc->first_link)
612 gcc_assert (!new_racc->last_link->next);
613 gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
615 new_racc->last_link->next = old_racc->first_link;
616 new_racc->last_link = old_racc->last_link;
618 else
620 gcc_assert (!new_racc->last_link);
622 new_racc->first_link = old_racc->first_link;
623 new_racc->last_link = old_racc->last_link;
625 old_racc->first_link = old_racc->last_link = NULL;
628 /* Add ACCESS to the work queue (which is actually a stack). */
630 static void
631 add_access_to_work_queue (struct access *access)
633 if (!access->grp_queued)
635 gcc_assert (!access->next_queued);
636 access->next_queued = work_queue_head;
637 access->grp_queued = 1;
638 work_queue_head = access;
642 /* Pop an access from the work queue, and return it, assuming there is one. */
644 static struct access *
645 pop_access_from_work_queue (void)
647 struct access *access = work_queue_head;
649 work_queue_head = access->next_queued;
650 access->next_queued = NULL;
651 access->grp_queued = 0;
652 return access;
656 /* Allocate necessary structures. */
658 static void
659 sra_initialize (void)
661 candidate_bitmap = BITMAP_ALLOC (NULL);
662 candidates.create (vec_safe_length (cfun->local_decls) / 2);
663 should_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
664 cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
665 gcc_obstack_init (&name_obstack);
666 access_pool = create_alloc_pool ("SRA accesses", sizeof (struct access), 16);
667 link_pool = create_alloc_pool ("SRA links", sizeof (struct assign_link), 16);
668 base_access_vec = pointer_map_create ();
669 memset (&sra_stats, 0, sizeof (sra_stats));
670 encountered_apply_args = false;
671 encountered_recursive_call = false;
672 encountered_unchangable_recursive_call = false;
675 /* Hook fed to pointer_map_traverse, deallocate stored vectors. */
677 static bool
678 delete_base_accesses (const void *key ATTRIBUTE_UNUSED, void **value,
679 void *data ATTRIBUTE_UNUSED)
681 vec<access_p> *access_vec = (vec<access_p> *) *value;
682 vec_free (access_vec);
683 return true;
686 /* Deallocate all general structures. */
688 static void
689 sra_deinitialize (void)
691 BITMAP_FREE (candidate_bitmap);
692 candidates.dispose ();
693 BITMAP_FREE (should_scalarize_away_bitmap);
694 BITMAP_FREE (cannot_scalarize_away_bitmap);
695 free_alloc_pool (access_pool);
696 free_alloc_pool (link_pool);
697 obstack_free (&name_obstack, NULL);
699 pointer_map_traverse (base_access_vec, delete_base_accesses, NULL);
700 pointer_map_destroy (base_access_vec);
703 /* Remove DECL from candidates for SRA and write REASON to the dump file if
704 there is one. */
705 static void
706 disqualify_candidate (tree decl, const char *reason)
708 if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl)))
709 candidates.clear_slot (candidates.find_slot_with_hash (decl,
710 DECL_UID (decl),
711 NO_INSERT));
713 if (dump_file && (dump_flags & TDF_DETAILS))
715 fprintf (dump_file, "! Disqualifying ");
716 print_generic_expr (dump_file, decl, 0);
717 fprintf (dump_file, " - %s\n", reason);
721 /* Return true iff the type contains a field or an element which does not allow
722 scalarization. */
724 static bool
725 type_internals_preclude_sra_p (tree type, const char **msg)
727 tree fld;
728 tree et;
730 switch (TREE_CODE (type))
732 case RECORD_TYPE:
733 case UNION_TYPE:
734 case QUAL_UNION_TYPE:
735 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
736 if (TREE_CODE (fld) == FIELD_DECL)
738 tree ft = TREE_TYPE (fld);
740 if (TREE_THIS_VOLATILE (fld))
742 *msg = "volatile structure field";
743 return true;
745 if (!DECL_FIELD_OFFSET (fld))
747 *msg = "no structure field offset";
748 return true;
750 if (!DECL_SIZE (fld))
752 *msg = "zero structure field size";
753 return true;
755 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
757 *msg = "structure field offset not fixed";
758 return true;
760 if (!tree_fits_uhwi_p (DECL_SIZE (fld)))
762 *msg = "structure field size not fixed";
763 return true;
765 if (!tree_fits_shwi_p (bit_position (fld)))
767 *msg = "structure field size too big";
768 return true;
770 if (AGGREGATE_TYPE_P (ft)
771 && int_bit_position (fld) % BITS_PER_UNIT != 0)
773 *msg = "structure field is bit field";
774 return true;
777 if (AGGREGATE_TYPE_P (ft) && type_internals_preclude_sra_p (ft, msg))
778 return true;
781 return false;
783 case ARRAY_TYPE:
784 et = TREE_TYPE (type);
786 if (TYPE_VOLATILE (et))
788 *msg = "element type is volatile";
789 return true;
792 if (AGGREGATE_TYPE_P (et) && type_internals_preclude_sra_p (et, msg))
793 return true;
795 return false;
797 default:
798 return false;
802 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
803 base variable if it is. Return T if it is not an SSA_NAME. */
805 static tree
806 get_ssa_base_param (tree t)
808 if (TREE_CODE (t) == SSA_NAME)
810 if (SSA_NAME_IS_DEFAULT_DEF (t))
811 return SSA_NAME_VAR (t);
812 else
813 return NULL_TREE;
815 return t;
818 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
819 belongs to, unless the BB has already been marked as a potentially
820 final. */
822 static void
823 mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple stmt)
825 basic_block bb = gimple_bb (stmt);
826 int idx, parm_index = 0;
827 tree parm;
829 if (bitmap_bit_p (final_bbs, bb->index))
830 return;
832 for (parm = DECL_ARGUMENTS (current_function_decl);
833 parm && parm != base;
834 parm = DECL_CHAIN (parm))
835 parm_index++;
837 gcc_assert (parm_index < func_param_count);
839 idx = bb->index * func_param_count + parm_index;
840 if (bb_dereferences[idx] < dist)
841 bb_dereferences[idx] = dist;
844 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
845 the three fields. Also add it to the vector of accesses corresponding to
846 the base. Finally, return the new access. */
848 static struct access *
849 create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
851 vec<access_p> *v;
852 struct access *access;
853 void **slot;
855 access = (struct access *) pool_alloc (access_pool);
856 memset (access, 0, sizeof (struct access));
857 access->base = base;
858 access->offset = offset;
859 access->size = size;
861 slot = pointer_map_contains (base_access_vec, base);
862 if (slot)
863 v = (vec<access_p> *) *slot;
864 else
865 vec_alloc (v, 32);
867 v->safe_push (access);
869 *((vec<access_p> **)
870 pointer_map_insert (base_access_vec, base)) = v;
872 return access;
875 /* Create and insert access for EXPR. Return created access, or NULL if it is
876 not possible. */
878 static struct access *
879 create_access (tree expr, gimple stmt, bool write)
881 struct access *access;
882 HOST_WIDE_INT offset, size, max_size;
883 tree base = expr;
884 bool ptr, unscalarizable_region = false;
886 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
888 if (sra_mode == SRA_MODE_EARLY_IPA
889 && TREE_CODE (base) == MEM_REF)
891 base = get_ssa_base_param (TREE_OPERAND (base, 0));
892 if (!base)
893 return NULL;
894 ptr = true;
896 else
897 ptr = false;
899 if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
900 return NULL;
902 if (sra_mode == SRA_MODE_EARLY_IPA)
904 if (size < 0 || size != max_size)
906 disqualify_candidate (base, "Encountered a variable sized access.");
907 return NULL;
909 if (TREE_CODE (expr) == COMPONENT_REF
910 && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))
912 disqualify_candidate (base, "Encountered a bit-field access.");
913 return NULL;
915 gcc_checking_assert ((offset % BITS_PER_UNIT) == 0);
917 if (ptr)
918 mark_parm_dereference (base, offset + size, stmt);
920 else
922 if (size != max_size)
924 size = max_size;
925 unscalarizable_region = true;
927 if (size < 0)
929 disqualify_candidate (base, "Encountered an unconstrained access.");
930 return NULL;
934 access = create_access_1 (base, offset, size);
935 access->expr = expr;
936 access->type = TREE_TYPE (expr);
937 access->write = write;
938 access->grp_unscalarizable_region = unscalarizable_region;
939 access->stmt = stmt;
941 if (TREE_CODE (expr) == COMPONENT_REF
942 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1)))
943 access->non_addressable = 1;
945 return access;
949 /* Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple
950 register types or (recursively) records with only these two kinds of fields.
951 It also returns false if any of these records contains a bit-field. */
953 static bool
954 type_consists_of_records_p (tree type)
956 tree fld;
958 if (TREE_CODE (type) != RECORD_TYPE)
959 return false;
961 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
962 if (TREE_CODE (fld) == FIELD_DECL)
964 tree ft = TREE_TYPE (fld);
966 if (DECL_BIT_FIELD (fld))
967 return false;
969 if (!is_gimple_reg_type (ft)
970 && !type_consists_of_records_p (ft))
971 return false;
974 return true;
977 /* Create total_scalarization accesses for all scalar type fields in DECL that
978 must be of a RECORD_TYPE conforming to type_consists_of_records_p. BASE
979 must be the top-most VAR_DECL representing the variable, OFFSET must be the
980 offset of DECL within BASE. REF must be the memory reference expression for
981 the given decl. */
983 static void
984 completely_scalarize_record (tree base, tree decl, HOST_WIDE_INT offset,
985 tree ref)
987 tree fld, decl_type = TREE_TYPE (decl);
989 for (fld = TYPE_FIELDS (decl_type); fld; fld = DECL_CHAIN (fld))
990 if (TREE_CODE (fld) == FIELD_DECL)
992 HOST_WIDE_INT pos = offset + int_bit_position (fld);
993 tree ft = TREE_TYPE (fld);
994 tree nref = build3 (COMPONENT_REF, TREE_TYPE (fld), ref, fld,
995 NULL_TREE);
997 if (is_gimple_reg_type (ft))
999 struct access *access;
1000 HOST_WIDE_INT size;
1002 size = tree_to_uhwi (DECL_SIZE (fld));
1003 access = create_access_1 (base, pos, size);
1004 access->expr = nref;
1005 access->type = ft;
1006 access->grp_total_scalarization = 1;
1007 /* Accesses for intraprocedural SRA can have their stmt NULL. */
1009 else
1010 completely_scalarize_record (base, fld, pos, nref);
1014 /* Create total_scalarization accesses for all scalar type fields in VAR and
1015 for VAR a a whole. VAR must be of a RECORD_TYPE conforming to
1016 type_consists_of_records_p. */
1018 static void
1019 completely_scalarize_var (tree var)
1021 HOST_WIDE_INT size = tree_to_uhwi (DECL_SIZE (var));
1022 struct access *access;
1024 access = create_access_1 (var, 0, size);
1025 access->expr = var;
1026 access->type = TREE_TYPE (var);
1027 access->grp_total_scalarization = 1;
1029 completely_scalarize_record (var, var, 0, var);
1032 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1034 static inline bool
1035 contains_view_convert_expr_p (const_tree ref)
1037 while (handled_component_p (ref))
1039 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
1040 return true;
1041 ref = TREE_OPERAND (ref, 0);
1044 return false;
1047 /* Search the given tree for a declaration by skipping handled components and
1048 exclude it from the candidates. */
1050 static void
1051 disqualify_base_of_expr (tree t, const char *reason)
1053 t = get_base_address (t);
1054 if (sra_mode == SRA_MODE_EARLY_IPA
1055 && TREE_CODE (t) == MEM_REF)
1056 t = get_ssa_base_param (TREE_OPERAND (t, 0));
1058 if (t && DECL_P (t))
1059 disqualify_candidate (t, reason);
1062 /* Scan expression EXPR and create access structures for all accesses to
1063 candidates for scalarization. Return the created access or NULL if none is
1064 created. */
1066 static struct access *
1067 build_access_from_expr_1 (tree expr, gimple stmt, bool write)
1069 struct access *ret = NULL;
1070 bool partial_ref;
1072 if (TREE_CODE (expr) == BIT_FIELD_REF
1073 || TREE_CODE (expr) == IMAGPART_EXPR
1074 || TREE_CODE (expr) == REALPART_EXPR)
1076 expr = TREE_OPERAND (expr, 0);
1077 partial_ref = true;
1079 else
1080 partial_ref = false;
1082 /* We need to dive through V_C_Es in order to get the size of its parameter
1083 and not the result type. Ada produces such statements. We are also
1084 capable of handling the topmost V_C_E but not any of those buried in other
1085 handled components. */
1086 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
1087 expr = TREE_OPERAND (expr, 0);
1089 if (contains_view_convert_expr_p (expr))
1091 disqualify_base_of_expr (expr, "V_C_E under a different handled "
1092 "component.");
1093 return NULL;
1096 switch (TREE_CODE (expr))
1098 case MEM_REF:
1099 if (TREE_CODE (TREE_OPERAND (expr, 0)) != ADDR_EXPR
1100 && sra_mode != SRA_MODE_EARLY_IPA)
1101 return NULL;
1102 /* fall through */
1103 case VAR_DECL:
1104 case PARM_DECL:
1105 case RESULT_DECL:
1106 case COMPONENT_REF:
1107 case ARRAY_REF:
1108 case ARRAY_RANGE_REF:
1109 ret = create_access (expr, stmt, write);
1110 break;
1112 default:
1113 break;
1116 if (write && partial_ref && ret)
1117 ret->grp_partial_lhs = 1;
1119 return ret;
1122 /* Scan expression EXPR and create access structures for all accesses to
1123 candidates for scalarization. Return true if any access has been inserted.
1124 STMT must be the statement from which the expression is taken, WRITE must be
1125 true if the expression is a store and false otherwise. */
1127 static bool
1128 build_access_from_expr (tree expr, gimple stmt, bool write)
1130 struct access *access;
1132 access = build_access_from_expr_1 (expr, stmt, write);
1133 if (access)
1135 /* This means the aggregate is accesses as a whole in a way other than an
1136 assign statement and thus cannot be removed even if we had a scalar
1137 replacement for everything. */
1138 if (cannot_scalarize_away_bitmap)
1139 bitmap_set_bit (cannot_scalarize_away_bitmap, DECL_UID (access->base));
1140 return true;
1142 return false;
1145 /* Disqualify LHS and RHS for scalarization if STMT must end its basic block in
1146 modes in which it matters, return true iff they have been disqualified. RHS
1147 may be NULL, in that case ignore it. If we scalarize an aggregate in
1148 intra-SRA we may need to add statements after each statement. This is not
1149 possible if a statement unconditionally has to end the basic block. */
1150 static bool
1151 disqualify_ops_if_throwing_stmt (gimple stmt, tree lhs, tree rhs)
1153 if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1154 && (stmt_can_throw_internal (stmt) || stmt_ends_bb_p (stmt)))
1156 disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
1157 if (rhs)
1158 disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
1159 return true;
1161 return false;
1164 /* Scan expressions occurring in STMT, create access structures for all accesses
1165 to candidates for scalarization and remove those candidates which occur in
1166 statements or expressions that prevent them from being split apart. Return
1167 true if any access has been inserted. */
1169 static bool
1170 build_accesses_from_assign (gimple stmt)
1172 tree lhs, rhs;
1173 struct access *lacc, *racc;
1175 if (!gimple_assign_single_p (stmt)
1176 /* Scope clobbers don't influence scalarization. */
1177 || gimple_clobber_p (stmt))
1178 return false;
1180 lhs = gimple_assign_lhs (stmt);
1181 rhs = gimple_assign_rhs1 (stmt);
1183 if (disqualify_ops_if_throwing_stmt (stmt, lhs, rhs))
1184 return false;
1186 racc = build_access_from_expr_1 (rhs, stmt, false);
1187 lacc = build_access_from_expr_1 (lhs, stmt, true);
1189 if (lacc)
1190 lacc->grp_assignment_write = 1;
1192 if (racc)
1194 racc->grp_assignment_read = 1;
1195 if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
1196 && !is_gimple_reg_type (racc->type))
1197 bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
1200 if (lacc && racc
1201 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1202 && !lacc->grp_unscalarizable_region
1203 && !racc->grp_unscalarizable_region
1204 && AGGREGATE_TYPE_P (TREE_TYPE (lhs))
1205 && lacc->size == racc->size
1206 && useless_type_conversion_p (lacc->type, racc->type))
1208 struct assign_link *link;
1210 link = (struct assign_link *) pool_alloc (link_pool);
1211 memset (link, 0, sizeof (struct assign_link));
1213 link->lacc = lacc;
1214 link->racc = racc;
1216 add_link_to_rhs (racc, link);
1219 return lacc || racc;
1222 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1223 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1225 static bool
1226 asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED, tree op,
1227 void *data ATTRIBUTE_UNUSED)
1229 op = get_base_address (op);
1230 if (op
1231 && DECL_P (op))
1232 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
1234 return false;
1237 /* Return true iff callsite CALL has at least as many actual arguments as there
1238 are formal parameters of the function currently processed by IPA-SRA. */
1240 static inline bool
1241 callsite_has_enough_arguments_p (gimple call)
1243 return gimple_call_num_args (call) >= (unsigned) func_param_count;
1246 /* Scan function and look for interesting expressions and create access
1247 structures for them. Return true iff any access is created. */
1249 static bool
1250 scan_function (void)
1252 basic_block bb;
1253 bool ret = false;
1255 FOR_EACH_BB (bb)
1257 gimple_stmt_iterator gsi;
1258 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1260 gimple stmt = gsi_stmt (gsi);
1261 tree t;
1262 unsigned i;
1264 if (final_bbs && stmt_can_throw_external (stmt))
1265 bitmap_set_bit (final_bbs, bb->index);
1266 switch (gimple_code (stmt))
1268 case GIMPLE_RETURN:
1269 t = gimple_return_retval (stmt);
1270 if (t != NULL_TREE)
1271 ret |= build_access_from_expr (t, stmt, false);
1272 if (final_bbs)
1273 bitmap_set_bit (final_bbs, bb->index);
1274 break;
1276 case GIMPLE_ASSIGN:
1277 ret |= build_accesses_from_assign (stmt);
1278 break;
1280 case GIMPLE_CALL:
1281 for (i = 0; i < gimple_call_num_args (stmt); i++)
1282 ret |= build_access_from_expr (gimple_call_arg (stmt, i),
1283 stmt, false);
1285 if (sra_mode == SRA_MODE_EARLY_IPA)
1287 tree dest = gimple_call_fndecl (stmt);
1288 int flags = gimple_call_flags (stmt);
1290 if (dest)
1292 if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1293 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1294 encountered_apply_args = true;
1295 if (recursive_call_p (current_function_decl, dest))
1297 encountered_recursive_call = true;
1298 if (!callsite_has_enough_arguments_p (stmt))
1299 encountered_unchangable_recursive_call = true;
1303 if (final_bbs
1304 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1305 bitmap_set_bit (final_bbs, bb->index);
1308 t = gimple_call_lhs (stmt);
1309 if (t && !disqualify_ops_if_throwing_stmt (stmt, t, NULL))
1310 ret |= build_access_from_expr (t, stmt, true);
1311 break;
1313 case GIMPLE_ASM:
1314 walk_stmt_load_store_addr_ops (stmt, NULL, NULL, NULL,
1315 asm_visit_addr);
1316 if (final_bbs)
1317 bitmap_set_bit (final_bbs, bb->index);
1319 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
1321 t = TREE_VALUE (gimple_asm_input_op (stmt, i));
1322 ret |= build_access_from_expr (t, stmt, false);
1324 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
1326 t = TREE_VALUE (gimple_asm_output_op (stmt, i));
1327 ret |= build_access_from_expr (t, stmt, true);
1329 break;
1331 default:
1332 break;
1337 return ret;
1340 /* Helper of QSORT function. There are pointers to accesses in the array. An
1341 access is considered smaller than another if it has smaller offset or if the
1342 offsets are the same but is size is bigger. */
1344 static int
1345 compare_access_positions (const void *a, const void *b)
1347 const access_p *fp1 = (const access_p *) a;
1348 const access_p *fp2 = (const access_p *) b;
1349 const access_p f1 = *fp1;
1350 const access_p f2 = *fp2;
1352 if (f1->offset != f2->offset)
1353 return f1->offset < f2->offset ? -1 : 1;
1355 if (f1->size == f2->size)
1357 if (f1->type == f2->type)
1358 return 0;
1359 /* Put any non-aggregate type before any aggregate type. */
1360 else if (!is_gimple_reg_type (f1->type)
1361 && is_gimple_reg_type (f2->type))
1362 return 1;
1363 else if (is_gimple_reg_type (f1->type)
1364 && !is_gimple_reg_type (f2->type))
1365 return -1;
1366 /* Put any complex or vector type before any other scalar type. */
1367 else if (TREE_CODE (f1->type) != COMPLEX_TYPE
1368 && TREE_CODE (f1->type) != VECTOR_TYPE
1369 && (TREE_CODE (f2->type) == COMPLEX_TYPE
1370 || TREE_CODE (f2->type) == VECTOR_TYPE))
1371 return 1;
1372 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
1373 || TREE_CODE (f1->type) == VECTOR_TYPE)
1374 && TREE_CODE (f2->type) != COMPLEX_TYPE
1375 && TREE_CODE (f2->type) != VECTOR_TYPE)
1376 return -1;
1377 /* Put the integral type with the bigger precision first. */
1378 else if (INTEGRAL_TYPE_P (f1->type)
1379 && INTEGRAL_TYPE_P (f2->type))
1380 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
1381 /* Put any integral type with non-full precision last. */
1382 else if (INTEGRAL_TYPE_P (f1->type)
1383 && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type))
1384 != TYPE_PRECISION (f1->type)))
1385 return 1;
1386 else if (INTEGRAL_TYPE_P (f2->type)
1387 && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type))
1388 != TYPE_PRECISION (f2->type)))
1389 return -1;
1390 /* Stabilize the sort. */
1391 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1394 /* We want the bigger accesses first, thus the opposite operator in the next
1395 line: */
1396 return f1->size > f2->size ? -1 : 1;
1400 /* Append a name of the declaration to the name obstack. A helper function for
1401 make_fancy_name. */
1403 static void
1404 make_fancy_decl_name (tree decl)
1406 char buffer[32];
1408 tree name = DECL_NAME (decl);
1409 if (name)
1410 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1411 IDENTIFIER_LENGTH (name));
1412 else
1414 sprintf (buffer, "D%u", DECL_UID (decl));
1415 obstack_grow (&name_obstack, buffer, strlen (buffer));
1419 /* Helper for make_fancy_name. */
1421 static void
1422 make_fancy_name_1 (tree expr)
1424 char buffer[32];
1425 tree index;
1427 if (DECL_P (expr))
1429 make_fancy_decl_name (expr);
1430 return;
1433 switch (TREE_CODE (expr))
1435 case COMPONENT_REF:
1436 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1437 obstack_1grow (&name_obstack, '$');
1438 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1439 break;
1441 case ARRAY_REF:
1442 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1443 obstack_1grow (&name_obstack, '$');
1444 /* Arrays with only one element may not have a constant as their
1445 index. */
1446 index = TREE_OPERAND (expr, 1);
1447 if (TREE_CODE (index) != INTEGER_CST)
1448 break;
1449 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1450 obstack_grow (&name_obstack, buffer, strlen (buffer));
1451 break;
1453 case ADDR_EXPR:
1454 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1455 break;
1457 case MEM_REF:
1458 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1459 if (!integer_zerop (TREE_OPERAND (expr, 1)))
1461 obstack_1grow (&name_obstack, '$');
1462 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC,
1463 TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)));
1464 obstack_grow (&name_obstack, buffer, strlen (buffer));
1466 break;
1468 case BIT_FIELD_REF:
1469 case REALPART_EXPR:
1470 case IMAGPART_EXPR:
1471 gcc_unreachable (); /* we treat these as scalars. */
1472 break;
1473 default:
1474 break;
1478 /* Create a human readable name for replacement variable of ACCESS. */
1480 static char *
1481 make_fancy_name (tree expr)
1483 make_fancy_name_1 (expr);
1484 obstack_1grow (&name_obstack, '\0');
1485 return XOBFINISH (&name_obstack, char *);
1488 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1489 EXP_TYPE at the given OFFSET. If BASE is something for which
1490 get_addr_base_and_unit_offset returns NULL, gsi must be non-NULL and is used
1491 to insert new statements either before or below the current one as specified
1492 by INSERT_AFTER. This function is not capable of handling bitfields.
1494 BASE must be either a declaration or a memory reference that has correct
1495 alignment ifformation embeded in it (e.g. a pre-existing one in SRA). */
1497 tree
1498 build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
1499 tree exp_type, gimple_stmt_iterator *gsi,
1500 bool insert_after)
1502 tree prev_base = base;
1503 tree off;
1504 tree mem_ref;
1505 HOST_WIDE_INT base_offset;
1506 unsigned HOST_WIDE_INT misalign;
1507 unsigned int align;
1509 gcc_checking_assert (offset % BITS_PER_UNIT == 0);
1510 get_object_alignment_1 (base, &align, &misalign);
1511 base = get_addr_base_and_unit_offset (base, &base_offset);
1513 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1514 offset such as array[var_index]. */
1515 if (!base)
1517 gimple stmt;
1518 tree tmp, addr;
1520 gcc_checking_assert (gsi);
1521 tmp = make_ssa_name (build_pointer_type (TREE_TYPE (prev_base)), NULL);
1522 addr = build_fold_addr_expr (unshare_expr (prev_base));
1523 STRIP_USELESS_TYPE_CONVERSION (addr);
1524 stmt = gimple_build_assign (tmp, addr);
1525 gimple_set_location (stmt, loc);
1526 if (insert_after)
1527 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
1528 else
1529 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1531 off = build_int_cst (reference_alias_ptr_type (prev_base),
1532 offset / BITS_PER_UNIT);
1533 base = tmp;
1535 else if (TREE_CODE (base) == MEM_REF)
1537 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1538 base_offset + offset / BITS_PER_UNIT);
1539 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1540 base = unshare_expr (TREE_OPERAND (base, 0));
1542 else
1544 off = build_int_cst (reference_alias_ptr_type (base),
1545 base_offset + offset / BITS_PER_UNIT);
1546 base = build_fold_addr_expr (unshare_expr (base));
1549 misalign = (misalign + offset) & (align - 1);
1550 if (misalign != 0)
1551 align = (misalign & -misalign);
1552 if (align < TYPE_ALIGN (exp_type))
1553 exp_type = build_aligned_type (exp_type, align);
1555 mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off);
1556 if (TREE_THIS_VOLATILE (prev_base))
1557 TREE_THIS_VOLATILE (mem_ref) = 1;
1558 if (TREE_SIDE_EFFECTS (prev_base))
1559 TREE_SIDE_EFFECTS (mem_ref) = 1;
1560 return mem_ref;
1563 /* Construct a memory reference to a part of an aggregate BASE at the given
1564 OFFSET and of the same type as MODEL. In case this is a reference to a
1565 bit-field, the function will replicate the last component_ref of model's
1566 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1567 build_ref_for_offset. */
1569 static tree
1570 build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1571 struct access *model, gimple_stmt_iterator *gsi,
1572 bool insert_after)
1574 if (TREE_CODE (model->expr) == COMPONENT_REF
1575 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1577 /* This access represents a bit-field. */
1578 tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
1580 offset -= int_bit_position (fld);
1581 exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
1582 t = build_ref_for_offset (loc, base, offset, exp_type, gsi, insert_after);
1583 return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
1584 NULL_TREE);
1586 else
1587 return build_ref_for_offset (loc, base, offset, model->type,
1588 gsi, insert_after);
1591 /* Attempt to build a memory reference that we could but into a gimple
1592 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1593 create statements and return s NULL instead. This function also ignores
1594 alignment issues and so its results should never end up in non-debug
1595 statements. */
1597 static tree
1598 build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1599 struct access *model)
1601 HOST_WIDE_INT base_offset;
1602 tree off;
1604 if (TREE_CODE (model->expr) == COMPONENT_REF
1605 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1606 return NULL_TREE;
1608 base = get_addr_base_and_unit_offset (base, &base_offset);
1609 if (!base)
1610 return NULL_TREE;
1611 if (TREE_CODE (base) == MEM_REF)
1613 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1614 base_offset + offset / BITS_PER_UNIT);
1615 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1616 base = unshare_expr (TREE_OPERAND (base, 0));
1618 else
1620 off = build_int_cst (reference_alias_ptr_type (base),
1621 base_offset + offset / BITS_PER_UNIT);
1622 base = build_fold_addr_expr (unshare_expr (base));
1625 return fold_build2_loc (loc, MEM_REF, model->type, base, off);
1628 /* Construct a memory reference consisting of component_refs and array_refs to
1629 a part of an aggregate *RES (which is of type TYPE). The requested part
1630 should have type EXP_TYPE at be the given OFFSET. This function might not
1631 succeed, it returns true when it does and only then *RES points to something
1632 meaningful. This function should be used only to build expressions that we
1633 might need to present to user (e.g. in warnings). In all other situations,
1634 build_ref_for_model or build_ref_for_offset should be used instead. */
1636 static bool
1637 build_user_friendly_ref_for_offset (tree *res, tree type, HOST_WIDE_INT offset,
1638 tree exp_type)
1640 while (1)
1642 tree fld;
1643 tree tr_size, index, minidx;
1644 HOST_WIDE_INT el_size;
1646 if (offset == 0 && exp_type
1647 && types_compatible_p (exp_type, type))
1648 return true;
1650 switch (TREE_CODE (type))
1652 case UNION_TYPE:
1653 case QUAL_UNION_TYPE:
1654 case RECORD_TYPE:
1655 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
1657 HOST_WIDE_INT pos, size;
1658 tree tr_pos, expr, *expr_ptr;
1660 if (TREE_CODE (fld) != FIELD_DECL)
1661 continue;
1663 tr_pos = bit_position (fld);
1664 if (!tr_pos || !tree_fits_uhwi_p (tr_pos))
1665 continue;
1666 pos = tree_to_uhwi (tr_pos);
1667 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1668 tr_size = DECL_SIZE (fld);
1669 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1670 continue;
1671 size = tree_to_uhwi (tr_size);
1672 if (size == 0)
1674 if (pos != offset)
1675 continue;
1677 else if (pos > offset || (pos + size) <= offset)
1678 continue;
1680 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1681 NULL_TREE);
1682 expr_ptr = &expr;
1683 if (build_user_friendly_ref_for_offset (expr_ptr, TREE_TYPE (fld),
1684 offset - pos, exp_type))
1686 *res = expr;
1687 return true;
1690 return false;
1692 case ARRAY_TYPE:
1693 tr_size = TYPE_SIZE (TREE_TYPE (type));
1694 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1695 return false;
1696 el_size = tree_to_uhwi (tr_size);
1698 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1699 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
1700 return false;
1701 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1702 if (!integer_zerop (minidx))
1703 index = int_const_binop (PLUS_EXPR, index, minidx);
1704 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1705 NULL_TREE, NULL_TREE);
1706 offset = offset % el_size;
1707 type = TREE_TYPE (type);
1708 break;
1710 default:
1711 if (offset != 0)
1712 return false;
1714 if (exp_type)
1715 return false;
1716 else
1717 return true;
1722 /* Return true iff TYPE is stdarg va_list type. */
1724 static inline bool
1725 is_va_list_type (tree type)
1727 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1730 /* Print message to dump file why a variable was rejected. */
1732 static void
1733 reject (tree var, const char *msg)
1735 if (dump_file && (dump_flags & TDF_DETAILS))
1737 fprintf (dump_file, "Rejected (%d): %s: ", DECL_UID (var), msg);
1738 print_generic_expr (dump_file, var, 0);
1739 fprintf (dump_file, "\n");
1743 /* Return true if VAR is a candidate for SRA. */
1745 static bool
1746 maybe_add_sra_candidate (tree var)
1748 tree type = TREE_TYPE (var);
1749 const char *msg;
1750 tree_node **slot;
1752 if (!AGGREGATE_TYPE_P (type))
1754 reject (var, "not aggregate");
1755 return false;
1757 if (needs_to_live_in_memory (var))
1759 reject (var, "needs to live in memory");
1760 return false;
1762 if (TREE_THIS_VOLATILE (var))
1764 reject (var, "is volatile");
1765 return false;
1767 if (!COMPLETE_TYPE_P (type))
1769 reject (var, "has incomplete type");
1770 return false;
1772 if (!tree_fits_uhwi_p (TYPE_SIZE (type)))
1774 reject (var, "type size not fixed");
1775 return false;
1777 if (tree_to_uhwi (TYPE_SIZE (type)) == 0)
1779 reject (var, "type size is zero");
1780 return false;
1782 if (type_internals_preclude_sra_p (type, &msg))
1784 reject (var, msg);
1785 return false;
1787 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1788 we also want to schedule it rather late. Thus we ignore it in
1789 the early pass. */
1790 (sra_mode == SRA_MODE_EARLY_INTRA
1791 && is_va_list_type (type)))
1793 reject (var, "is va_list");
1794 return false;
1797 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
1798 slot = candidates.find_slot_with_hash (var, DECL_UID (var), INSERT);
1799 *slot = var;
1801 if (dump_file && (dump_flags & TDF_DETAILS))
1803 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
1804 print_generic_expr (dump_file, var, 0);
1805 fprintf (dump_file, "\n");
1808 return true;
1811 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1812 those with type which is suitable for scalarization. */
1814 static bool
1815 find_var_candidates (void)
1817 tree var, parm;
1818 unsigned int i;
1819 bool ret = false;
1821 for (parm = DECL_ARGUMENTS (current_function_decl);
1822 parm;
1823 parm = DECL_CHAIN (parm))
1824 ret |= maybe_add_sra_candidate (parm);
1826 FOR_EACH_LOCAL_DECL (cfun, i, var)
1828 if (TREE_CODE (var) != VAR_DECL)
1829 continue;
1831 ret |= maybe_add_sra_candidate (var);
1834 return ret;
1837 /* Sort all accesses for the given variable, check for partial overlaps and
1838 return NULL if there are any. If there are none, pick a representative for
1839 each combination of offset and size and create a linked list out of them.
1840 Return the pointer to the first representative and make sure it is the first
1841 one in the vector of accesses. */
1843 static struct access *
1844 sort_and_splice_var_accesses (tree var)
1846 int i, j, access_count;
1847 struct access *res, **prev_acc_ptr = &res;
1848 vec<access_p> *access_vec;
1849 bool first = true;
1850 HOST_WIDE_INT low = -1, high = 0;
1852 access_vec = get_base_access_vector (var);
1853 if (!access_vec)
1854 return NULL;
1855 access_count = access_vec->length ();
1857 /* Sort by <OFFSET, SIZE>. */
1858 access_vec->qsort (compare_access_positions);
1860 i = 0;
1861 while (i < access_count)
1863 struct access *access = (*access_vec)[i];
1864 bool grp_write = access->write;
1865 bool grp_read = !access->write;
1866 bool grp_scalar_write = access->write
1867 && is_gimple_reg_type (access->type);
1868 bool grp_scalar_read = !access->write
1869 && is_gimple_reg_type (access->type);
1870 bool grp_assignment_read = access->grp_assignment_read;
1871 bool grp_assignment_write = access->grp_assignment_write;
1872 bool multiple_scalar_reads = false;
1873 bool total_scalarization = access->grp_total_scalarization;
1874 bool grp_partial_lhs = access->grp_partial_lhs;
1875 bool first_scalar = is_gimple_reg_type (access->type);
1876 bool unscalarizable_region = access->grp_unscalarizable_region;
1878 if (first || access->offset >= high)
1880 first = false;
1881 low = access->offset;
1882 high = access->offset + access->size;
1884 else if (access->offset > low && access->offset + access->size > high)
1885 return NULL;
1886 else
1887 gcc_assert (access->offset >= low
1888 && access->offset + access->size <= high);
1890 j = i + 1;
1891 while (j < access_count)
1893 struct access *ac2 = (*access_vec)[j];
1894 if (ac2->offset != access->offset || ac2->size != access->size)
1895 break;
1896 if (ac2->write)
1898 grp_write = true;
1899 grp_scalar_write = (grp_scalar_write
1900 || is_gimple_reg_type (ac2->type));
1902 else
1904 grp_read = true;
1905 if (is_gimple_reg_type (ac2->type))
1907 if (grp_scalar_read)
1908 multiple_scalar_reads = true;
1909 else
1910 grp_scalar_read = true;
1913 grp_assignment_read |= ac2->grp_assignment_read;
1914 grp_assignment_write |= ac2->grp_assignment_write;
1915 grp_partial_lhs |= ac2->grp_partial_lhs;
1916 unscalarizable_region |= ac2->grp_unscalarizable_region;
1917 total_scalarization |= ac2->grp_total_scalarization;
1918 relink_to_new_repr (access, ac2);
1920 /* If there are both aggregate-type and scalar-type accesses with
1921 this combination of size and offset, the comparison function
1922 should have put the scalars first. */
1923 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
1924 ac2->group_representative = access;
1925 j++;
1928 i = j;
1930 access->group_representative = access;
1931 access->grp_write = grp_write;
1932 access->grp_read = grp_read;
1933 access->grp_scalar_read = grp_scalar_read;
1934 access->grp_scalar_write = grp_scalar_write;
1935 access->grp_assignment_read = grp_assignment_read;
1936 access->grp_assignment_write = grp_assignment_write;
1937 access->grp_hint = multiple_scalar_reads || total_scalarization;
1938 access->grp_total_scalarization = total_scalarization;
1939 access->grp_partial_lhs = grp_partial_lhs;
1940 access->grp_unscalarizable_region = unscalarizable_region;
1941 if (access->first_link)
1942 add_access_to_work_queue (access);
1944 *prev_acc_ptr = access;
1945 prev_acc_ptr = &access->next_grp;
1948 gcc_assert (res == (*access_vec)[0]);
1949 return res;
1952 /* Create a variable for the given ACCESS which determines the type, name and a
1953 few other properties. Return the variable declaration and store it also to
1954 ACCESS->replacement. */
1956 static tree
1957 create_access_replacement (struct access *access)
1959 tree repl;
1961 if (access->grp_to_be_debug_replaced)
1963 repl = create_tmp_var_raw (access->type, NULL);
1964 DECL_CONTEXT (repl) = current_function_decl;
1966 else
1967 repl = create_tmp_var (access->type, "SR");
1968 if (TREE_CODE (access->type) == COMPLEX_TYPE
1969 || TREE_CODE (access->type) == VECTOR_TYPE)
1971 if (!access->grp_partial_lhs)
1972 DECL_GIMPLE_REG_P (repl) = 1;
1974 else if (access->grp_partial_lhs
1975 && is_gimple_reg_type (access->type))
1976 TREE_ADDRESSABLE (repl) = 1;
1978 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
1979 DECL_ARTIFICIAL (repl) = 1;
1980 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
1982 if (DECL_NAME (access->base)
1983 && !DECL_IGNORED_P (access->base)
1984 && !DECL_ARTIFICIAL (access->base))
1986 char *pretty_name = make_fancy_name (access->expr);
1987 tree debug_expr = unshare_expr_without_location (access->expr), d;
1988 bool fail = false;
1990 DECL_NAME (repl) = get_identifier (pretty_name);
1991 obstack_free (&name_obstack, pretty_name);
1993 /* Get rid of any SSA_NAMEs embedded in debug_expr,
1994 as DECL_DEBUG_EXPR isn't considered when looking for still
1995 used SSA_NAMEs and thus they could be freed. All debug info
1996 generation cares is whether something is constant or variable
1997 and that get_ref_base_and_extent works properly on the
1998 expression. It cannot handle accesses at a non-constant offset
1999 though, so just give up in those cases. */
2000 for (d = debug_expr;
2001 !fail && (handled_component_p (d) || TREE_CODE (d) == MEM_REF);
2002 d = TREE_OPERAND (d, 0))
2003 switch (TREE_CODE (d))
2005 case ARRAY_REF:
2006 case ARRAY_RANGE_REF:
2007 if (TREE_OPERAND (d, 1)
2008 && TREE_CODE (TREE_OPERAND (d, 1)) != INTEGER_CST)
2009 fail = true;
2010 if (TREE_OPERAND (d, 3)
2011 && TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST)
2012 fail = true;
2013 /* FALLTHRU */
2014 case COMPONENT_REF:
2015 if (TREE_OPERAND (d, 2)
2016 && TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST)
2017 fail = true;
2018 break;
2019 case MEM_REF:
2020 if (TREE_CODE (TREE_OPERAND (d, 0)) != ADDR_EXPR)
2021 fail = true;
2022 else
2023 d = TREE_OPERAND (d, 0);
2024 break;
2025 default:
2026 break;
2028 if (!fail)
2030 SET_DECL_DEBUG_EXPR (repl, debug_expr);
2031 DECL_HAS_DEBUG_EXPR_P (repl) = 1;
2033 if (access->grp_no_warning)
2034 TREE_NO_WARNING (repl) = 1;
2035 else
2036 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
2038 else
2039 TREE_NO_WARNING (repl) = 1;
2041 if (dump_file)
2043 if (access->grp_to_be_debug_replaced)
2045 fprintf (dump_file, "Created a debug-only replacement for ");
2046 print_generic_expr (dump_file, access->base, 0);
2047 fprintf (dump_file, " offset: %u, size: %u\n",
2048 (unsigned) access->offset, (unsigned) access->size);
2050 else
2052 fprintf (dump_file, "Created a replacement for ");
2053 print_generic_expr (dump_file, access->base, 0);
2054 fprintf (dump_file, " offset: %u, size: %u: ",
2055 (unsigned) access->offset, (unsigned) access->size);
2056 print_generic_expr (dump_file, repl, 0);
2057 fprintf (dump_file, "\n");
2060 sra_stats.replacements++;
2062 return repl;
2065 /* Return ACCESS scalar replacement, create it if it does not exist yet. */
2067 static inline tree
2068 get_access_replacement (struct access *access)
2070 gcc_checking_assert (access->replacement_decl);
2071 return access->replacement_decl;
2075 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2076 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2077 to it is not "within" the root. Return false iff some accesses partially
2078 overlap. */
2080 static bool
2081 build_access_subtree (struct access **access)
2083 struct access *root = *access, *last_child = NULL;
2084 HOST_WIDE_INT limit = root->offset + root->size;
2086 *access = (*access)->next_grp;
2087 while (*access && (*access)->offset + (*access)->size <= limit)
2089 if (!last_child)
2090 root->first_child = *access;
2091 else
2092 last_child->next_sibling = *access;
2093 last_child = *access;
2095 if (!build_access_subtree (access))
2096 return false;
2099 if (*access && (*access)->offset < limit)
2100 return false;
2102 return true;
2105 /* Build a tree of access representatives, ACCESS is the pointer to the first
2106 one, others are linked in a list by the next_grp field. Return false iff
2107 some accesses partially overlap. */
2109 static bool
2110 build_access_trees (struct access *access)
2112 while (access)
2114 struct access *root = access;
2116 if (!build_access_subtree (&access))
2117 return false;
2118 root->next_grp = access;
2120 return true;
2123 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2124 array. */
2126 static bool
2127 expr_with_var_bounded_array_refs_p (tree expr)
2129 while (handled_component_p (expr))
2131 if (TREE_CODE (expr) == ARRAY_REF
2132 && !tree_fits_shwi_p (array_ref_low_bound (expr)))
2133 return true;
2134 expr = TREE_OPERAND (expr, 0);
2136 return false;
2139 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2140 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2141 sorts of access flags appropriately along the way, notably always set
2142 grp_read and grp_assign_read according to MARK_READ and grp_write when
2143 MARK_WRITE is true.
2145 Creating a replacement for a scalar access is considered beneficial if its
2146 grp_hint is set (this means we are either attempting total scalarization or
2147 there is more than one direct read access) or according to the following
2148 table:
2150 Access written to through a scalar type (once or more times)
2152 | Written to in an assignment statement
2154 | | Access read as scalar _once_
2155 | | |
2156 | | | Read in an assignment statement
2157 | | | |
2158 | | | | Scalarize Comment
2159 -----------------------------------------------------------------------------
2160 0 0 0 0 No access for the scalar
2161 0 0 0 1 No access for the scalar
2162 0 0 1 0 No Single read - won't help
2163 0 0 1 1 No The same case
2164 0 1 0 0 No access for the scalar
2165 0 1 0 1 No access for the scalar
2166 0 1 1 0 Yes s = *g; return s.i;
2167 0 1 1 1 Yes The same case as above
2168 1 0 0 0 No Won't help
2169 1 0 0 1 Yes s.i = 1; *g = s;
2170 1 0 1 0 Yes s.i = 5; g = s.i;
2171 1 0 1 1 Yes The same case as above
2172 1 1 0 0 No Won't help.
2173 1 1 0 1 Yes s.i = 1; *g = s;
2174 1 1 1 0 Yes s = *g; return s.i;
2175 1 1 1 1 Yes Any of the above yeses */
2177 static bool
2178 analyze_access_subtree (struct access *root, struct access *parent,
2179 bool allow_replacements)
2181 struct access *child;
2182 HOST_WIDE_INT limit = root->offset + root->size;
2183 HOST_WIDE_INT covered_to = root->offset;
2184 bool scalar = is_gimple_reg_type (root->type);
2185 bool hole = false, sth_created = false;
2187 if (parent)
2189 if (parent->grp_read)
2190 root->grp_read = 1;
2191 if (parent->grp_assignment_read)
2192 root->grp_assignment_read = 1;
2193 if (parent->grp_write)
2194 root->grp_write = 1;
2195 if (parent->grp_assignment_write)
2196 root->grp_assignment_write = 1;
2197 if (parent->grp_total_scalarization)
2198 root->grp_total_scalarization = 1;
2201 if (root->grp_unscalarizable_region)
2202 allow_replacements = false;
2204 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
2205 allow_replacements = false;
2207 for (child = root->first_child; child; child = child->next_sibling)
2209 hole |= covered_to < child->offset;
2210 sth_created |= analyze_access_subtree (child, root,
2211 allow_replacements && !scalar);
2213 root->grp_unscalarized_data |= child->grp_unscalarized_data;
2214 root->grp_total_scalarization &= child->grp_total_scalarization;
2215 if (child->grp_covered)
2216 covered_to += child->size;
2217 else
2218 hole = true;
2221 if (allow_replacements && scalar && !root->first_child
2222 && (root->grp_hint
2223 || ((root->grp_scalar_read || root->grp_assignment_read)
2224 && (root->grp_scalar_write || root->grp_assignment_write))))
2226 /* Always create access replacements that cover the whole access.
2227 For integral types this means the precision has to match.
2228 Avoid assumptions based on the integral type kind, too. */
2229 if (INTEGRAL_TYPE_P (root->type)
2230 && (TREE_CODE (root->type) != INTEGER_TYPE
2231 || TYPE_PRECISION (root->type) != root->size)
2232 /* But leave bitfield accesses alone. */
2233 && (TREE_CODE (root->expr) != COMPONENT_REF
2234 || !DECL_BIT_FIELD (TREE_OPERAND (root->expr, 1))))
2236 tree rt = root->type;
2237 gcc_assert ((root->offset % BITS_PER_UNIT) == 0
2238 && (root->size % BITS_PER_UNIT) == 0);
2239 root->type = build_nonstandard_integer_type (root->size,
2240 TYPE_UNSIGNED (rt));
2241 root->expr = build_ref_for_offset (UNKNOWN_LOCATION,
2242 root->base, root->offset,
2243 root->type, NULL, false);
2245 if (dump_file && (dump_flags & TDF_DETAILS))
2247 fprintf (dump_file, "Changing the type of a replacement for ");
2248 print_generic_expr (dump_file, root->base, 0);
2249 fprintf (dump_file, " offset: %u, size: %u ",
2250 (unsigned) root->offset, (unsigned) root->size);
2251 fprintf (dump_file, " to an integer.\n");
2255 root->grp_to_be_replaced = 1;
2256 root->replacement_decl = create_access_replacement (root);
2257 sth_created = true;
2258 hole = false;
2260 else
2262 if (allow_replacements
2263 && scalar && !root->first_child
2264 && (root->grp_scalar_write || root->grp_assignment_write)
2265 && !bitmap_bit_p (cannot_scalarize_away_bitmap,
2266 DECL_UID (root->base)))
2268 gcc_checking_assert (!root->grp_scalar_read
2269 && !root->grp_assignment_read);
2270 sth_created = true;
2271 if (MAY_HAVE_DEBUG_STMTS)
2273 root->grp_to_be_debug_replaced = 1;
2274 root->replacement_decl = create_access_replacement (root);
2278 if (covered_to < limit)
2279 hole = true;
2280 if (scalar)
2281 root->grp_total_scalarization = 0;
2284 if (!hole || root->grp_total_scalarization)
2285 root->grp_covered = 1;
2286 else if (root->grp_write || TREE_CODE (root->base) == PARM_DECL)
2287 root->grp_unscalarized_data = 1; /* not covered and written to */
2288 return sth_created;
2291 /* Analyze all access trees linked by next_grp by the means of
2292 analyze_access_subtree. */
2293 static bool
2294 analyze_access_trees (struct access *access)
2296 bool ret = false;
2298 while (access)
2300 if (analyze_access_subtree (access, NULL, true))
2301 ret = true;
2302 access = access->next_grp;
2305 return ret;
2308 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2309 SIZE would conflict with an already existing one. If exactly such a child
2310 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2312 static bool
2313 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
2314 HOST_WIDE_INT size, struct access **exact_match)
2316 struct access *child;
2318 for (child = lacc->first_child; child; child = child->next_sibling)
2320 if (child->offset == norm_offset && child->size == size)
2322 *exact_match = child;
2323 return true;
2326 if (child->offset < norm_offset + size
2327 && child->offset + child->size > norm_offset)
2328 return true;
2331 return false;
2334 /* Create a new child access of PARENT, with all properties just like MODEL
2335 except for its offset and with its grp_write false and grp_read true.
2336 Return the new access or NULL if it cannot be created. Note that this access
2337 is created long after all splicing and sorting, it's not located in any
2338 access vector and is automatically a representative of its group. */
2340 static struct access *
2341 create_artificial_child_access (struct access *parent, struct access *model,
2342 HOST_WIDE_INT new_offset)
2344 struct access *access;
2345 struct access **child;
2346 tree expr = parent->base;
2348 gcc_assert (!model->grp_unscalarizable_region);
2350 access = (struct access *) pool_alloc (access_pool);
2351 memset (access, 0, sizeof (struct access));
2352 if (!build_user_friendly_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
2353 model->type))
2355 access->grp_no_warning = true;
2356 expr = build_ref_for_model (EXPR_LOCATION (parent->base), parent->base,
2357 new_offset, model, NULL, false);
2360 access->base = parent->base;
2361 access->expr = expr;
2362 access->offset = new_offset;
2363 access->size = model->size;
2364 access->type = model->type;
2365 access->grp_write = true;
2366 access->grp_read = false;
2368 child = &parent->first_child;
2369 while (*child && (*child)->offset < new_offset)
2370 child = &(*child)->next_sibling;
2372 access->next_sibling = *child;
2373 *child = access;
2375 return access;
2379 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
2380 true if any new subaccess was created. Additionally, if RACC is a scalar
2381 access but LACC is not, change the type of the latter, if possible. */
2383 static bool
2384 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
2386 struct access *rchild;
2387 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
2388 bool ret = false;
2390 if (is_gimple_reg_type (lacc->type)
2391 || lacc->grp_unscalarizable_region
2392 || racc->grp_unscalarizable_region)
2393 return false;
2395 if (is_gimple_reg_type (racc->type))
2397 if (!lacc->first_child && !racc->first_child)
2399 tree t = lacc->base;
2401 lacc->type = racc->type;
2402 if (build_user_friendly_ref_for_offset (&t, TREE_TYPE (t),
2403 lacc->offset, racc->type))
2404 lacc->expr = t;
2405 else
2407 lacc->expr = build_ref_for_model (EXPR_LOCATION (lacc->base),
2408 lacc->base, lacc->offset,
2409 racc, NULL, false);
2410 lacc->grp_no_warning = true;
2413 return false;
2416 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
2418 struct access *new_acc = NULL;
2419 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
2421 if (rchild->grp_unscalarizable_region)
2422 continue;
2424 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
2425 &new_acc))
2427 if (new_acc)
2429 rchild->grp_hint = 1;
2430 new_acc->grp_hint |= new_acc->grp_read;
2431 if (rchild->first_child)
2432 ret |= propagate_subaccesses_across_link (new_acc, rchild);
2434 continue;
2437 rchild->grp_hint = 1;
2438 new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
2439 if (new_acc)
2441 ret = true;
2442 if (racc->first_child)
2443 propagate_subaccesses_across_link (new_acc, rchild);
2447 return ret;
2450 /* Propagate all subaccesses across assignment links. */
2452 static void
2453 propagate_all_subaccesses (void)
2455 while (work_queue_head)
2457 struct access *racc = pop_access_from_work_queue ();
2458 struct assign_link *link;
2460 gcc_assert (racc->first_link);
2462 for (link = racc->first_link; link; link = link->next)
2464 struct access *lacc = link->lacc;
2466 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
2467 continue;
2468 lacc = lacc->group_representative;
2469 if (propagate_subaccesses_across_link (lacc, racc)
2470 && lacc->first_link)
2471 add_access_to_work_queue (lacc);
2476 /* Go through all accesses collected throughout the (intraprocedural) analysis
2477 stage, exclude overlapping ones, identify representatives and build trees
2478 out of them, making decisions about scalarization on the way. Return true
2479 iff there are any to-be-scalarized variables after this stage. */
2481 static bool
2482 analyze_all_variable_accesses (void)
2484 int res = 0;
2485 bitmap tmp = BITMAP_ALLOC (NULL);
2486 bitmap_iterator bi;
2487 unsigned i, max_total_scalarization_size;
2489 max_total_scalarization_size = UNITS_PER_WORD * BITS_PER_UNIT
2490 * MOVE_RATIO (optimize_function_for_speed_p (cfun));
2492 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
2493 if (bitmap_bit_p (should_scalarize_away_bitmap, i)
2494 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
2496 tree var = candidate (i);
2498 if (TREE_CODE (var) == VAR_DECL
2499 && type_consists_of_records_p (TREE_TYPE (var)))
2501 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var)))
2502 <= max_total_scalarization_size)
2504 completely_scalarize_var (var);
2505 if (dump_file && (dump_flags & TDF_DETAILS))
2507 fprintf (dump_file, "Will attempt to totally scalarize ");
2508 print_generic_expr (dump_file, var, 0);
2509 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2512 else if (dump_file && (dump_flags & TDF_DETAILS))
2514 fprintf (dump_file, "Too big to totally scalarize: ");
2515 print_generic_expr (dump_file, var, 0);
2516 fprintf (dump_file, " (UID: %u)\n", DECL_UID (var));
2521 bitmap_copy (tmp, candidate_bitmap);
2522 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2524 tree var = candidate (i);
2525 struct access *access;
2527 access = sort_and_splice_var_accesses (var);
2528 if (!access || !build_access_trees (access))
2529 disqualify_candidate (var,
2530 "No or inhibitingly overlapping accesses.");
2533 propagate_all_subaccesses ();
2535 bitmap_copy (tmp, candidate_bitmap);
2536 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2538 tree var = candidate (i);
2539 struct access *access = get_first_repr_for_decl (var);
2541 if (analyze_access_trees (access))
2543 res++;
2544 if (dump_file && (dump_flags & TDF_DETAILS))
2546 fprintf (dump_file, "\nAccess trees for ");
2547 print_generic_expr (dump_file, var, 0);
2548 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2549 dump_access_tree (dump_file, access);
2550 fprintf (dump_file, "\n");
2553 else
2554 disqualify_candidate (var, "No scalar replacements to be created.");
2557 BITMAP_FREE (tmp);
2559 if (res)
2561 statistics_counter_event (cfun, "Scalarized aggregates", res);
2562 return true;
2564 else
2565 return false;
2568 /* Generate statements copying scalar replacements of accesses within a subtree
2569 into or out of AGG. ACCESS, all its children, siblings and their children
2570 are to be processed. AGG is an aggregate type expression (can be a
2571 declaration but does not have to be, it can for example also be a mem_ref or
2572 a series of handled components). TOP_OFFSET is the offset of the processed
2573 subtree which has to be subtracted from offsets of individual accesses to
2574 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2575 replacements in the interval <start_offset, start_offset + chunk_size>,
2576 otherwise copy all. GSI is a statement iterator used to place the new
2577 statements. WRITE should be true when the statements should write from AGG
2578 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2579 statements will be added after the current statement in GSI, they will be
2580 added before the statement otherwise. */
2582 static void
2583 generate_subtree_copies (struct access *access, tree agg,
2584 HOST_WIDE_INT top_offset,
2585 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
2586 gimple_stmt_iterator *gsi, bool write,
2587 bool insert_after, location_t loc)
2591 if (chunk_size && access->offset >= start_offset + chunk_size)
2592 return;
2594 if (access->grp_to_be_replaced
2595 && (chunk_size == 0
2596 || access->offset + access->size > start_offset))
2598 tree expr, repl = get_access_replacement (access);
2599 gimple stmt;
2601 expr = build_ref_for_model (loc, agg, access->offset - top_offset,
2602 access, gsi, insert_after);
2604 if (write)
2606 if (access->grp_partial_lhs)
2607 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
2608 !insert_after,
2609 insert_after ? GSI_NEW_STMT
2610 : GSI_SAME_STMT);
2611 stmt = gimple_build_assign (repl, expr);
2613 else
2615 TREE_NO_WARNING (repl) = 1;
2616 if (access->grp_partial_lhs)
2617 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2618 !insert_after,
2619 insert_after ? GSI_NEW_STMT
2620 : GSI_SAME_STMT);
2621 stmt = gimple_build_assign (expr, repl);
2623 gimple_set_location (stmt, loc);
2625 if (insert_after)
2626 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2627 else
2628 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2629 update_stmt (stmt);
2630 sra_stats.subtree_copies++;
2632 else if (write
2633 && access->grp_to_be_debug_replaced
2634 && (chunk_size == 0
2635 || access->offset + access->size > start_offset))
2637 gimple ds;
2638 tree drhs = build_debug_ref_for_model (loc, agg,
2639 access->offset - top_offset,
2640 access);
2641 ds = gimple_build_debug_bind (get_access_replacement (access),
2642 drhs, gsi_stmt (*gsi));
2643 if (insert_after)
2644 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2645 else
2646 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2649 if (access->first_child)
2650 generate_subtree_copies (access->first_child, agg, top_offset,
2651 start_offset, chunk_size, gsi,
2652 write, insert_after, loc);
2654 access = access->next_sibling;
2656 while (access);
2659 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2660 the root of the subtree to be processed. GSI is the statement iterator used
2661 for inserting statements which are added after the current statement if
2662 INSERT_AFTER is true or before it otherwise. */
2664 static void
2665 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
2666 bool insert_after, location_t loc)
2669 struct access *child;
2671 if (access->grp_to_be_replaced)
2673 gimple stmt;
2675 stmt = gimple_build_assign (get_access_replacement (access),
2676 build_zero_cst (access->type));
2677 if (insert_after)
2678 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2679 else
2680 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2681 update_stmt (stmt);
2682 gimple_set_location (stmt, loc);
2684 else if (access->grp_to_be_debug_replaced)
2686 gimple ds = gimple_build_debug_bind (get_access_replacement (access),
2687 build_zero_cst (access->type),
2688 gsi_stmt (*gsi));
2689 if (insert_after)
2690 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2691 else
2692 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2695 for (child = access->first_child; child; child = child->next_sibling)
2696 init_subtree_with_zero (child, gsi, insert_after, loc);
2699 /* Search for an access representative for the given expression EXPR and
2700 return it or NULL if it cannot be found. */
2702 static struct access *
2703 get_access_for_expr (tree expr)
2705 HOST_WIDE_INT offset, size, max_size;
2706 tree base;
2708 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2709 a different size than the size of its argument and we need the latter
2710 one. */
2711 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
2712 expr = TREE_OPERAND (expr, 0);
2714 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
2715 if (max_size == -1 || !DECL_P (base))
2716 return NULL;
2718 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
2719 return NULL;
2721 return get_var_base_offset_size_access (base, offset, max_size);
2724 /* Replace the expression EXPR with a scalar replacement if there is one and
2725 generate other statements to do type conversion or subtree copying if
2726 necessary. GSI is used to place newly created statements, WRITE is true if
2727 the expression is being written to (it is on a LHS of a statement or output
2728 in an assembly statement). */
2730 static bool
2731 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
2733 location_t loc;
2734 struct access *access;
2735 tree type, bfr;
2737 if (TREE_CODE (*expr) == BIT_FIELD_REF)
2739 bfr = *expr;
2740 expr = &TREE_OPERAND (*expr, 0);
2742 else
2743 bfr = NULL_TREE;
2745 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
2746 expr = &TREE_OPERAND (*expr, 0);
2747 access = get_access_for_expr (*expr);
2748 if (!access)
2749 return false;
2750 type = TREE_TYPE (*expr);
2752 loc = gimple_location (gsi_stmt (*gsi));
2753 if (access->grp_to_be_replaced)
2755 tree repl = get_access_replacement (access);
2756 /* If we replace a non-register typed access simply use the original
2757 access expression to extract the scalar component afterwards.
2758 This happens if scalarizing a function return value or parameter
2759 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2760 gcc.c-torture/compile/20011217-1.c.
2762 We also want to use this when accessing a complex or vector which can
2763 be accessed as a different type too, potentially creating a need for
2764 type conversion (see PR42196) and when scalarized unions are involved
2765 in assembler statements (see PR42398). */
2766 if (!useless_type_conversion_p (type, access->type))
2768 tree ref;
2770 ref = build_ref_for_model (loc, access->base, access->offset, access,
2771 NULL, false);
2773 if (write)
2775 gimple stmt;
2777 if (access->grp_partial_lhs)
2778 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
2779 false, GSI_NEW_STMT);
2780 stmt = gimple_build_assign (repl, ref);
2781 gimple_set_location (stmt, loc);
2782 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2784 else
2786 gimple stmt;
2788 if (access->grp_partial_lhs)
2789 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2790 true, GSI_SAME_STMT);
2791 stmt = gimple_build_assign (ref, repl);
2792 gimple_set_location (stmt, loc);
2793 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2796 else
2797 *expr = repl;
2798 sra_stats.exprs++;
2800 else if (write && access->grp_to_be_debug_replaced)
2802 gimple ds = gimple_build_debug_bind (get_access_replacement (access),
2803 NULL_TREE,
2804 gsi_stmt (*gsi));
2805 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2808 if (access->first_child)
2810 HOST_WIDE_INT start_offset, chunk_size;
2811 if (bfr
2812 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 1))
2813 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 2)))
2815 chunk_size = tree_to_uhwi (TREE_OPERAND (bfr, 1));
2816 start_offset = access->offset
2817 + tree_to_uhwi (TREE_OPERAND (bfr, 2));
2819 else
2820 start_offset = chunk_size = 0;
2822 generate_subtree_copies (access->first_child, access->base, 0,
2823 start_offset, chunk_size, gsi, write, write,
2824 loc);
2826 return true;
2829 /* Where scalar replacements of the RHS have been written to when a replacement
2830 of a LHS of an assigments cannot be direclty loaded from a replacement of
2831 the RHS. */
2832 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
2833 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
2834 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
2836 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2837 base aggregate if there are unscalarized data or directly to LHS of the
2838 statement that is pointed to by GSI otherwise. */
2840 static enum unscalarized_data_handling
2841 handle_unscalarized_data_in_subtree (struct access *top_racc,
2842 gimple_stmt_iterator *gsi)
2844 if (top_racc->grp_unscalarized_data)
2846 generate_subtree_copies (top_racc->first_child, top_racc->base, 0, 0, 0,
2847 gsi, false, false,
2848 gimple_location (gsi_stmt (*gsi)));
2849 return SRA_UDH_RIGHT;
2851 else
2853 tree lhs = gimple_assign_lhs (gsi_stmt (*gsi));
2854 generate_subtree_copies (top_racc->first_child, lhs, top_racc->offset,
2855 0, 0, gsi, false, false,
2856 gimple_location (gsi_stmt (*gsi)));
2857 return SRA_UDH_LEFT;
2862 /* Try to generate statements to load all sub-replacements in an access subtree
2863 formed by children of LACC from scalar replacements in the TOP_RACC subtree.
2864 If that is not possible, refresh the TOP_RACC base aggregate and load the
2865 accesses from it. LEFT_OFFSET is the offset of the left whole subtree being
2866 copied. NEW_GSI is stmt iterator used for statement insertions after the
2867 original assignment, OLD_GSI is used to insert statements before the
2868 assignment. *REFRESHED keeps the information whether we have needed to
2869 refresh replacements of the LHS and from which side of the assignments this
2870 takes place. */
2872 static void
2873 load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
2874 HOST_WIDE_INT left_offset,
2875 gimple_stmt_iterator *old_gsi,
2876 gimple_stmt_iterator *new_gsi,
2877 enum unscalarized_data_handling *refreshed)
2879 location_t loc = gimple_location (gsi_stmt (*old_gsi));
2880 for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling)
2882 HOST_WIDE_INT offset = lacc->offset - left_offset + top_racc->offset;
2884 if (lacc->grp_to_be_replaced)
2886 struct access *racc;
2887 gimple stmt;
2888 tree rhs;
2890 racc = find_access_in_subtree (top_racc, offset, lacc->size);
2891 if (racc && racc->grp_to_be_replaced)
2893 rhs = get_access_replacement (racc);
2894 if (!useless_type_conversion_p (lacc->type, racc->type))
2895 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, lacc->type, rhs);
2897 if (racc->grp_partial_lhs && lacc->grp_partial_lhs)
2898 rhs = force_gimple_operand_gsi (old_gsi, rhs, true, NULL_TREE,
2899 true, GSI_SAME_STMT);
2901 else
2903 /* No suitable access on the right hand side, need to load from
2904 the aggregate. See if we have to update it first... */
2905 if (*refreshed == SRA_UDH_NONE)
2906 *refreshed = handle_unscalarized_data_in_subtree (top_racc,
2907 old_gsi);
2909 if (*refreshed == SRA_UDH_LEFT)
2910 rhs = build_ref_for_model (loc, lacc->base, lacc->offset, lacc,
2911 new_gsi, true);
2912 else
2913 rhs = build_ref_for_model (loc, top_racc->base, offset, lacc,
2914 new_gsi, true);
2915 if (lacc->grp_partial_lhs)
2916 rhs = force_gimple_operand_gsi (new_gsi, rhs, true, NULL_TREE,
2917 false, GSI_NEW_STMT);
2920 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
2921 gsi_insert_after (new_gsi, stmt, GSI_NEW_STMT);
2922 gimple_set_location (stmt, loc);
2923 update_stmt (stmt);
2924 sra_stats.subreplacements++;
2926 else
2928 if (*refreshed == SRA_UDH_NONE
2929 && lacc->grp_read && !lacc->grp_covered)
2930 *refreshed = handle_unscalarized_data_in_subtree (top_racc,
2931 old_gsi);
2932 if (lacc && lacc->grp_to_be_debug_replaced)
2934 gimple ds;
2935 tree drhs;
2936 struct access *racc = find_access_in_subtree (top_racc, offset,
2937 lacc->size);
2939 if (racc && racc->grp_to_be_replaced)
2941 if (racc->grp_write)
2942 drhs = get_access_replacement (racc);
2943 else
2944 drhs = NULL;
2946 else if (*refreshed == SRA_UDH_LEFT)
2947 drhs = build_debug_ref_for_model (loc, lacc->base, lacc->offset,
2948 lacc);
2949 else if (*refreshed == SRA_UDH_RIGHT)
2950 drhs = build_debug_ref_for_model (loc, top_racc->base, offset,
2951 lacc);
2952 else
2953 drhs = NULL_TREE;
2954 ds = gimple_build_debug_bind (get_access_replacement (lacc),
2955 drhs, gsi_stmt (*old_gsi));
2956 gsi_insert_after (new_gsi, ds, GSI_NEW_STMT);
2960 if (lacc->first_child)
2961 load_assign_lhs_subreplacements (lacc, top_racc, left_offset,
2962 old_gsi, new_gsi, refreshed);
2966 /* Result code for SRA assignment modification. */
2967 enum assignment_mod_result { SRA_AM_NONE, /* nothing done for the stmt */
2968 SRA_AM_MODIFIED, /* stmt changed but not
2969 removed */
2970 SRA_AM_REMOVED }; /* stmt eliminated */
2972 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
2973 to the assignment and GSI is the statement iterator pointing at it. Returns
2974 the same values as sra_modify_assign. */
2976 static enum assignment_mod_result
2977 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
2979 tree lhs = gimple_assign_lhs (*stmt);
2980 struct access *acc;
2981 location_t loc;
2983 acc = get_access_for_expr (lhs);
2984 if (!acc)
2985 return SRA_AM_NONE;
2987 if (gimple_clobber_p (*stmt))
2989 /* Remove clobbers of fully scalarized variables, otherwise
2990 do nothing. */
2991 if (acc->grp_covered)
2993 unlink_stmt_vdef (*stmt);
2994 gsi_remove (gsi, true);
2995 release_defs (*stmt);
2996 return SRA_AM_REMOVED;
2998 else
2999 return SRA_AM_NONE;
3002 loc = gimple_location (*stmt);
3003 if (vec_safe_length (CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt))) > 0)
3005 /* I have never seen this code path trigger but if it can happen the
3006 following should handle it gracefully. */
3007 if (access_has_children_p (acc))
3008 generate_subtree_copies (acc->first_child, acc->base, 0, 0, 0, gsi,
3009 true, true, loc);
3010 return SRA_AM_MODIFIED;
3013 if (acc->grp_covered)
3015 init_subtree_with_zero (acc, gsi, false, loc);
3016 unlink_stmt_vdef (*stmt);
3017 gsi_remove (gsi, true);
3018 release_defs (*stmt);
3019 return SRA_AM_REMOVED;
3021 else
3023 init_subtree_with_zero (acc, gsi, true, loc);
3024 return SRA_AM_MODIFIED;
3028 /* Create and return a new suitable default definition SSA_NAME for RACC which
3029 is an access describing an uninitialized part of an aggregate that is being
3030 loaded. */
3032 static tree
3033 get_repl_default_def_ssa_name (struct access *racc)
3035 gcc_checking_assert (!racc->grp_to_be_replaced
3036 && !racc->grp_to_be_debug_replaced);
3037 if (!racc->replacement_decl)
3038 racc->replacement_decl = create_access_replacement (racc);
3039 return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
3042 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3043 bit-field field declaration somewhere in it. */
3045 static inline bool
3046 contains_vce_or_bfcref_p (const_tree ref)
3048 while (handled_component_p (ref))
3050 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
3051 || (TREE_CODE (ref) == COMPONENT_REF
3052 && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
3053 return true;
3054 ref = TREE_OPERAND (ref, 0);
3057 return false;
3060 /* Examine both sides of the assignment statement pointed to by STMT, replace
3061 them with a scalare replacement if there is one and generate copying of
3062 replacements if scalarized aggregates have been used in the assignment. GSI
3063 is used to hold generated statements for type conversions and subtree
3064 copying. */
3066 static enum assignment_mod_result
3067 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3069 struct access *lacc, *racc;
3070 tree lhs, rhs;
3071 bool modify_this_stmt = false;
3072 bool force_gimple_rhs = false;
3073 location_t loc;
3074 gimple_stmt_iterator orig_gsi = *gsi;
3076 if (!gimple_assign_single_p (*stmt))
3077 return SRA_AM_NONE;
3078 lhs = gimple_assign_lhs (*stmt);
3079 rhs = gimple_assign_rhs1 (*stmt);
3081 if (TREE_CODE (rhs) == CONSTRUCTOR)
3082 return sra_modify_constructor_assign (stmt, gsi);
3084 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
3085 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
3086 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
3088 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (*stmt),
3089 gsi, false);
3090 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (*stmt),
3091 gsi, true);
3092 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3095 lacc = get_access_for_expr (lhs);
3096 racc = get_access_for_expr (rhs);
3097 if (!lacc && !racc)
3098 return SRA_AM_NONE;
3100 loc = gimple_location (*stmt);
3101 if (lacc && lacc->grp_to_be_replaced)
3103 lhs = get_access_replacement (lacc);
3104 gimple_assign_set_lhs (*stmt, lhs);
3105 modify_this_stmt = true;
3106 if (lacc->grp_partial_lhs)
3107 force_gimple_rhs = true;
3108 sra_stats.exprs++;
3111 if (racc && racc->grp_to_be_replaced)
3113 rhs = get_access_replacement (racc);
3114 modify_this_stmt = true;
3115 if (racc->grp_partial_lhs)
3116 force_gimple_rhs = true;
3117 sra_stats.exprs++;
3119 else if (racc
3120 && !racc->grp_unscalarized_data
3121 && TREE_CODE (lhs) == SSA_NAME
3122 && !access_has_replacements_p (racc))
3124 rhs = get_repl_default_def_ssa_name (racc);
3125 modify_this_stmt = true;
3126 sra_stats.exprs++;
3129 if (modify_this_stmt)
3131 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3133 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3134 ??? This should move to fold_stmt which we simply should
3135 call after building a VIEW_CONVERT_EXPR here. */
3136 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
3137 && !contains_bitfld_component_ref_p (lhs))
3139 lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
3140 gimple_assign_set_lhs (*stmt, lhs);
3142 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
3143 && !contains_vce_or_bfcref_p (rhs))
3144 rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
3146 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3148 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
3149 rhs);
3150 if (is_gimple_reg_type (TREE_TYPE (lhs))
3151 && TREE_CODE (lhs) != SSA_NAME)
3152 force_gimple_rhs = true;
3157 if (lacc && lacc->grp_to_be_debug_replaced)
3159 tree dlhs = get_access_replacement (lacc);
3160 tree drhs = unshare_expr (rhs);
3161 if (!useless_type_conversion_p (TREE_TYPE (dlhs), TREE_TYPE (drhs)))
3163 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs))
3164 && !contains_vce_or_bfcref_p (drhs))
3165 drhs = build_debug_ref_for_model (loc, drhs, 0, lacc);
3166 if (drhs
3167 && !useless_type_conversion_p (TREE_TYPE (dlhs),
3168 TREE_TYPE (drhs)))
3169 drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
3170 TREE_TYPE (dlhs), drhs);
3172 gimple ds = gimple_build_debug_bind (dlhs, drhs, *stmt);
3173 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3176 /* From this point on, the function deals with assignments in between
3177 aggregates when at least one has scalar reductions of some of its
3178 components. There are three possible scenarios: Both the LHS and RHS have
3179 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3181 In the first case, we would like to load the LHS components from RHS
3182 components whenever possible. If that is not possible, we would like to
3183 read it directly from the RHS (after updating it by storing in it its own
3184 components). If there are some necessary unscalarized data in the LHS,
3185 those will be loaded by the original assignment too. If neither of these
3186 cases happen, the original statement can be removed. Most of this is done
3187 by load_assign_lhs_subreplacements.
3189 In the second case, we would like to store all RHS scalarized components
3190 directly into LHS and if they cover the aggregate completely, remove the
3191 statement too. In the third case, we want the LHS components to be loaded
3192 directly from the RHS (DSE will remove the original statement if it
3193 becomes redundant).
3195 This is a bit complex but manageable when types match and when unions do
3196 not cause confusion in a way that we cannot really load a component of LHS
3197 from the RHS or vice versa (the access representing this level can have
3198 subaccesses that are accessible only through a different union field at a
3199 higher level - different from the one used in the examined expression).
3200 Unions are fun.
3202 Therefore, I specially handle a fourth case, happening when there is a
3203 specific type cast or it is impossible to locate a scalarized subaccess on
3204 the other side of the expression. If that happens, I simply "refresh" the
3205 RHS by storing in it is scalarized components leave the original statement
3206 there to do the copying and then load the scalar replacements of the LHS.
3207 This is what the first branch does. */
3209 if (modify_this_stmt
3210 || gimple_has_volatile_ops (*stmt)
3211 || contains_vce_or_bfcref_p (rhs)
3212 || contains_vce_or_bfcref_p (lhs))
3214 if (access_has_children_p (racc))
3215 generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
3216 gsi, false, false, loc);
3217 if (access_has_children_p (lacc))
3218 generate_subtree_copies (lacc->first_child, lacc->base, 0, 0, 0,
3219 gsi, true, true, loc);
3220 sra_stats.separate_lhs_rhs_handling++;
3222 /* This gimplification must be done after generate_subtree_copies,
3223 lest we insert the subtree copies in the middle of the gimplified
3224 sequence. */
3225 if (force_gimple_rhs)
3226 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
3227 true, GSI_SAME_STMT);
3228 if (gimple_assign_rhs1 (*stmt) != rhs)
3230 modify_this_stmt = true;
3231 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
3232 gcc_assert (*stmt == gsi_stmt (orig_gsi));
3235 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3237 else
3239 if (access_has_children_p (lacc)
3240 && access_has_children_p (racc)
3241 /* When an access represents an unscalarizable region, it usually
3242 represents accesses with variable offset and thus must not be used
3243 to generate new memory accesses. */
3244 && !lacc->grp_unscalarizable_region
3245 && !racc->grp_unscalarizable_region)
3247 gimple_stmt_iterator orig_gsi = *gsi;
3248 enum unscalarized_data_handling refreshed;
3250 if (lacc->grp_read && !lacc->grp_covered)
3251 refreshed = handle_unscalarized_data_in_subtree (racc, gsi);
3252 else
3253 refreshed = SRA_UDH_NONE;
3255 load_assign_lhs_subreplacements (lacc, racc, lacc->offset,
3256 &orig_gsi, gsi, &refreshed);
3257 if (refreshed != SRA_UDH_RIGHT)
3259 gsi_next (gsi);
3260 unlink_stmt_vdef (*stmt);
3261 gsi_remove (&orig_gsi, true);
3262 release_defs (*stmt);
3263 sra_stats.deleted++;
3264 return SRA_AM_REMOVED;
3267 else
3269 if (access_has_children_p (racc)
3270 && !racc->grp_unscalarized_data)
3272 if (dump_file)
3274 fprintf (dump_file, "Removing load: ");
3275 print_gimple_stmt (dump_file, *stmt, 0, 0);
3277 generate_subtree_copies (racc->first_child, lhs,
3278 racc->offset, 0, 0, gsi,
3279 false, false, loc);
3280 gcc_assert (*stmt == gsi_stmt (*gsi));
3281 unlink_stmt_vdef (*stmt);
3282 gsi_remove (gsi, true);
3283 release_defs (*stmt);
3284 sra_stats.deleted++;
3285 return SRA_AM_REMOVED;
3287 /* Restore the aggregate RHS from its components so the
3288 prevailing aggregate copy does the right thing. */
3289 if (access_has_children_p (racc))
3290 generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
3291 gsi, false, false, loc);
3292 /* Re-load the components of the aggregate copy destination.
3293 But use the RHS aggregate to load from to expose more
3294 optimization opportunities. */
3295 if (access_has_children_p (lacc))
3296 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
3297 0, 0, gsi, true, true, loc);
3300 return SRA_AM_NONE;
3304 /* Traverse the function body and all modifications as decided in
3305 analyze_all_variable_accesses. Return true iff the CFG has been
3306 changed. */
3308 static bool
3309 sra_modify_function_body (void)
3311 bool cfg_changed = false;
3312 basic_block bb;
3314 FOR_EACH_BB (bb)
3316 gimple_stmt_iterator gsi = gsi_start_bb (bb);
3317 while (!gsi_end_p (gsi))
3319 gimple stmt = gsi_stmt (gsi);
3320 enum assignment_mod_result assign_result;
3321 bool modified = false, deleted = false;
3322 tree *t;
3323 unsigned i;
3325 switch (gimple_code (stmt))
3327 case GIMPLE_RETURN:
3328 t = gimple_return_retval_ptr (stmt);
3329 if (*t != NULL_TREE)
3330 modified |= sra_modify_expr (t, &gsi, false);
3331 break;
3333 case GIMPLE_ASSIGN:
3334 assign_result = sra_modify_assign (&stmt, &gsi);
3335 modified |= assign_result == SRA_AM_MODIFIED;
3336 deleted = assign_result == SRA_AM_REMOVED;
3337 break;
3339 case GIMPLE_CALL:
3340 /* Operands must be processed before the lhs. */
3341 for (i = 0; i < gimple_call_num_args (stmt); i++)
3343 t = gimple_call_arg_ptr (stmt, i);
3344 modified |= sra_modify_expr (t, &gsi, false);
3347 if (gimple_call_lhs (stmt))
3349 t = gimple_call_lhs_ptr (stmt);
3350 modified |= sra_modify_expr (t, &gsi, true);
3352 break;
3354 case GIMPLE_ASM:
3355 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
3357 t = &TREE_VALUE (gimple_asm_input_op (stmt, i));
3358 modified |= sra_modify_expr (t, &gsi, false);
3360 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
3362 t = &TREE_VALUE (gimple_asm_output_op (stmt, i));
3363 modified |= sra_modify_expr (t, &gsi, true);
3365 break;
3367 default:
3368 break;
3371 if (modified)
3373 update_stmt (stmt);
3374 if (maybe_clean_eh_stmt (stmt)
3375 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
3376 cfg_changed = true;
3378 if (!deleted)
3379 gsi_next (&gsi);
3383 return cfg_changed;
3386 /* Generate statements initializing scalar replacements of parts of function
3387 parameters. */
3389 static void
3390 initialize_parameter_reductions (void)
3392 gimple_stmt_iterator gsi;
3393 gimple_seq seq = NULL;
3394 tree parm;
3396 gsi = gsi_start (seq);
3397 for (parm = DECL_ARGUMENTS (current_function_decl);
3398 parm;
3399 parm = DECL_CHAIN (parm))
3401 vec<access_p> *access_vec;
3402 struct access *access;
3404 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3405 continue;
3406 access_vec = get_base_access_vector (parm);
3407 if (!access_vec)
3408 continue;
3410 for (access = (*access_vec)[0];
3411 access;
3412 access = access->next_grp)
3413 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true,
3414 EXPR_LOCATION (parm));
3417 seq = gsi_seq (gsi);
3418 if (seq)
3419 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3422 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3423 it reveals there are components of some aggregates to be scalarized, it runs
3424 the required transformations. */
3425 static unsigned int
3426 perform_intra_sra (void)
3428 int ret = 0;
3429 sra_initialize ();
3431 if (!find_var_candidates ())
3432 goto out;
3434 if (!scan_function ())
3435 goto out;
3437 if (!analyze_all_variable_accesses ())
3438 goto out;
3440 if (sra_modify_function_body ())
3441 ret = TODO_update_ssa | TODO_cleanup_cfg;
3442 else
3443 ret = TODO_update_ssa;
3444 initialize_parameter_reductions ();
3446 statistics_counter_event (cfun, "Scalar replacements created",
3447 sra_stats.replacements);
3448 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
3449 statistics_counter_event (cfun, "Subtree copy stmts",
3450 sra_stats.subtree_copies);
3451 statistics_counter_event (cfun, "Subreplacement stmts",
3452 sra_stats.subreplacements);
3453 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
3454 statistics_counter_event (cfun, "Separate LHS and RHS handling",
3455 sra_stats.separate_lhs_rhs_handling);
3457 out:
3458 sra_deinitialize ();
3459 return ret;
3462 /* Perform early intraprocedural SRA. */
3463 static unsigned int
3464 early_intra_sra (void)
3466 sra_mode = SRA_MODE_EARLY_INTRA;
3467 return perform_intra_sra ();
3470 /* Perform "late" intraprocedural SRA. */
3471 static unsigned int
3472 late_intra_sra (void)
3474 sra_mode = SRA_MODE_INTRA;
3475 return perform_intra_sra ();
3479 static bool
3480 gate_intra_sra (void)
3482 return flag_tree_sra != 0 && dbg_cnt (tree_sra);
3486 namespace {
3488 const pass_data pass_data_sra_early =
3490 GIMPLE_PASS, /* type */
3491 "esra", /* name */
3492 OPTGROUP_NONE, /* optinfo_flags */
3493 true, /* has_gate */
3494 true, /* has_execute */
3495 TV_TREE_SRA, /* tv_id */
3496 ( PROP_cfg | PROP_ssa ), /* properties_required */
3497 0, /* properties_provided */
3498 0, /* properties_destroyed */
3499 0, /* todo_flags_start */
3500 ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */
3503 class pass_sra_early : public gimple_opt_pass
3505 public:
3506 pass_sra_early (gcc::context *ctxt)
3507 : gimple_opt_pass (pass_data_sra_early, ctxt)
3510 /* opt_pass methods: */
3511 bool gate () { return gate_intra_sra (); }
3512 unsigned int execute () { return early_intra_sra (); }
3514 }; // class pass_sra_early
3516 } // anon namespace
3518 gimple_opt_pass *
3519 make_pass_sra_early (gcc::context *ctxt)
3521 return new pass_sra_early (ctxt);
3524 namespace {
3526 const pass_data pass_data_sra =
3528 GIMPLE_PASS, /* type */
3529 "sra", /* name */
3530 OPTGROUP_NONE, /* optinfo_flags */
3531 true, /* has_gate */
3532 true, /* has_execute */
3533 TV_TREE_SRA, /* tv_id */
3534 ( PROP_cfg | PROP_ssa ), /* properties_required */
3535 0, /* properties_provided */
3536 0, /* properties_destroyed */
3537 TODO_update_address_taken, /* todo_flags_start */
3538 ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */
3541 class pass_sra : public gimple_opt_pass
3543 public:
3544 pass_sra (gcc::context *ctxt)
3545 : gimple_opt_pass (pass_data_sra, ctxt)
3548 /* opt_pass methods: */
3549 bool gate () { return gate_intra_sra (); }
3550 unsigned int execute () { return late_intra_sra (); }
3552 }; // class pass_sra
3554 } // anon namespace
3556 gimple_opt_pass *
3557 make_pass_sra (gcc::context *ctxt)
3559 return new pass_sra (ctxt);
3563 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3564 parameter. */
3566 static bool
3567 is_unused_scalar_param (tree parm)
3569 tree name;
3570 return (is_gimple_reg (parm)
3571 && (!(name = ssa_default_def (cfun, parm))
3572 || has_zero_uses (name)));
3575 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3576 examine whether there are any direct or otherwise infeasible ones. If so,
3577 return true, otherwise return false. PARM must be a gimple register with a
3578 non-NULL default definition. */
3580 static bool
3581 ptr_parm_has_direct_uses (tree parm)
3583 imm_use_iterator ui;
3584 gimple stmt;
3585 tree name = ssa_default_def (cfun, parm);
3586 bool ret = false;
3588 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
3590 int uses_ok = 0;
3591 use_operand_p use_p;
3593 if (is_gimple_debug (stmt))
3594 continue;
3596 /* Valid uses include dereferences on the lhs and the rhs. */
3597 if (gimple_has_lhs (stmt))
3599 tree lhs = gimple_get_lhs (stmt);
3600 while (handled_component_p (lhs))
3601 lhs = TREE_OPERAND (lhs, 0);
3602 if (TREE_CODE (lhs) == MEM_REF
3603 && TREE_OPERAND (lhs, 0) == name
3604 && integer_zerop (TREE_OPERAND (lhs, 1))
3605 && types_compatible_p (TREE_TYPE (lhs),
3606 TREE_TYPE (TREE_TYPE (name)))
3607 && !TREE_THIS_VOLATILE (lhs))
3608 uses_ok++;
3610 if (gimple_assign_single_p (stmt))
3612 tree rhs = gimple_assign_rhs1 (stmt);
3613 while (handled_component_p (rhs))
3614 rhs = TREE_OPERAND (rhs, 0);
3615 if (TREE_CODE (rhs) == MEM_REF
3616 && TREE_OPERAND (rhs, 0) == name
3617 && integer_zerop (TREE_OPERAND (rhs, 1))
3618 && types_compatible_p (TREE_TYPE (rhs),
3619 TREE_TYPE (TREE_TYPE (name)))
3620 && !TREE_THIS_VOLATILE (rhs))
3621 uses_ok++;
3623 else if (is_gimple_call (stmt))
3625 unsigned i;
3626 for (i = 0; i < gimple_call_num_args (stmt); ++i)
3628 tree arg = gimple_call_arg (stmt, i);
3629 while (handled_component_p (arg))
3630 arg = TREE_OPERAND (arg, 0);
3631 if (TREE_CODE (arg) == MEM_REF
3632 && TREE_OPERAND (arg, 0) == name
3633 && integer_zerop (TREE_OPERAND (arg, 1))
3634 && types_compatible_p (TREE_TYPE (arg),
3635 TREE_TYPE (TREE_TYPE (name)))
3636 && !TREE_THIS_VOLATILE (arg))
3637 uses_ok++;
3641 /* If the number of valid uses does not match the number of
3642 uses in this stmt there is an unhandled use. */
3643 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
3644 --uses_ok;
3646 if (uses_ok != 0)
3647 ret = true;
3649 if (ret)
3650 BREAK_FROM_IMM_USE_STMT (ui);
3653 return ret;
3656 /* Identify candidates for reduction for IPA-SRA based on their type and mark
3657 them in candidate_bitmap. Note that these do not necessarily include
3658 parameter which are unused and thus can be removed. Return true iff any
3659 such candidate has been found. */
3661 static bool
3662 find_param_candidates (void)
3664 tree parm;
3665 int count = 0;
3666 bool ret = false;
3667 const char *msg;
3669 for (parm = DECL_ARGUMENTS (current_function_decl);
3670 parm;
3671 parm = DECL_CHAIN (parm))
3673 tree type = TREE_TYPE (parm);
3674 tree_node **slot;
3676 count++;
3678 if (TREE_THIS_VOLATILE (parm)
3679 || TREE_ADDRESSABLE (parm)
3680 || (!is_gimple_reg_type (type) && is_va_list_type (type)))
3681 continue;
3683 if (is_unused_scalar_param (parm))
3685 ret = true;
3686 continue;
3689 if (POINTER_TYPE_P (type))
3691 type = TREE_TYPE (type);
3693 if (TREE_CODE (type) == FUNCTION_TYPE
3694 || TYPE_VOLATILE (type)
3695 || (TREE_CODE (type) == ARRAY_TYPE
3696 && TYPE_NONALIASED_COMPONENT (type))
3697 || !is_gimple_reg (parm)
3698 || is_va_list_type (type)
3699 || ptr_parm_has_direct_uses (parm))
3700 continue;
3702 else if (!AGGREGATE_TYPE_P (type))
3703 continue;
3705 if (!COMPLETE_TYPE_P (type)
3706 || !tree_fits_uhwi_p (TYPE_SIZE (type))
3707 || tree_to_uhwi (TYPE_SIZE (type)) == 0
3708 || (AGGREGATE_TYPE_P (type)
3709 && type_internals_preclude_sra_p (type, &msg)))
3710 continue;
3712 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
3713 slot = candidates.find_slot_with_hash (parm, DECL_UID (parm), INSERT);
3714 *slot = parm;
3716 ret = true;
3717 if (dump_file && (dump_flags & TDF_DETAILS))
3719 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
3720 print_generic_expr (dump_file, parm, 0);
3721 fprintf (dump_file, "\n");
3725 func_param_count = count;
3726 return ret;
3729 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
3730 maybe_modified. */
3732 static bool
3733 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
3734 void *data)
3736 struct access *repr = (struct access *) data;
3738 repr->grp_maybe_modified = 1;
3739 return true;
3742 /* Analyze what representatives (in linked lists accessible from
3743 REPRESENTATIVES) can be modified by side effects of statements in the
3744 current function. */
3746 static void
3747 analyze_modified_params (vec<access_p> representatives)
3749 int i;
3751 for (i = 0; i < func_param_count; i++)
3753 struct access *repr;
3755 for (repr = representatives[i];
3756 repr;
3757 repr = repr->next_grp)
3759 struct access *access;
3760 bitmap visited;
3761 ao_ref ar;
3763 if (no_accesses_p (repr))
3764 continue;
3765 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
3766 || repr->grp_maybe_modified)
3767 continue;
3769 ao_ref_init (&ar, repr->expr);
3770 visited = BITMAP_ALLOC (NULL);
3771 for (access = repr; access; access = access->next_sibling)
3773 /* All accesses are read ones, otherwise grp_maybe_modified would
3774 be trivially set. */
3775 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
3776 mark_maybe_modified, repr, &visited);
3777 if (repr->grp_maybe_modified)
3778 break;
3780 BITMAP_FREE (visited);
3785 /* Propagate distances in bb_dereferences in the opposite direction than the
3786 control flow edges, in each step storing the maximum of the current value
3787 and the minimum of all successors. These steps are repeated until the table
3788 stabilizes. Note that BBs which might terminate the functions (according to
3789 final_bbs bitmap) never updated in this way. */
3791 static void
3792 propagate_dereference_distances (void)
3794 basic_block bb;
3796 auto_vec<basic_block> queue (last_basic_block_for_function (cfun));
3797 queue.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun));
3798 FOR_EACH_BB (bb)
3800 queue.quick_push (bb);
3801 bb->aux = bb;
3804 while (!queue.is_empty ())
3806 edge_iterator ei;
3807 edge e;
3808 bool change = false;
3809 int i;
3811 bb = queue.pop ();
3812 bb->aux = NULL;
3814 if (bitmap_bit_p (final_bbs, bb->index))
3815 continue;
3817 for (i = 0; i < func_param_count; i++)
3819 int idx = bb->index * func_param_count + i;
3820 bool first = true;
3821 HOST_WIDE_INT inh = 0;
3823 FOR_EACH_EDGE (e, ei, bb->succs)
3825 int succ_idx = e->dest->index * func_param_count + i;
3827 if (e->src == EXIT_BLOCK_PTR_FOR_FN (cfun))
3828 continue;
3830 if (first)
3832 first = false;
3833 inh = bb_dereferences [succ_idx];
3835 else if (bb_dereferences [succ_idx] < inh)
3836 inh = bb_dereferences [succ_idx];
3839 if (!first && bb_dereferences[idx] < inh)
3841 bb_dereferences[idx] = inh;
3842 change = true;
3846 if (change && !bitmap_bit_p (final_bbs, bb->index))
3847 FOR_EACH_EDGE (e, ei, bb->preds)
3849 if (e->src->aux)
3850 continue;
3852 e->src->aux = e->src;
3853 queue.quick_push (e->src);
3858 /* Dump a dereferences TABLE with heading STR to file F. */
3860 static void
3861 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
3863 basic_block bb;
3865 fprintf (dump_file, str);
3866 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
3867 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
3869 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
3870 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
3872 int i;
3873 for (i = 0; i < func_param_count; i++)
3875 int idx = bb->index * func_param_count + i;
3876 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
3879 fprintf (f, "\n");
3881 fprintf (dump_file, "\n");
3884 /* Determine what (parts of) parameters passed by reference that are not
3885 assigned to are not certainly dereferenced in this function and thus the
3886 dereferencing cannot be safely moved to the caller without potentially
3887 introducing a segfault. Mark such REPRESENTATIVES as
3888 grp_not_necessarilly_dereferenced.
3890 The dereferenced maximum "distance," i.e. the offset + size of the accessed
3891 part is calculated rather than simple booleans are calculated for each
3892 pointer parameter to handle cases when only a fraction of the whole
3893 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
3894 an example).
3896 The maximum dereference distances for each pointer parameter and BB are
3897 already stored in bb_dereference. This routine simply propagates these
3898 values upwards by propagate_dereference_distances and then compares the
3899 distances of individual parameters in the ENTRY BB to the equivalent
3900 distances of each representative of a (fraction of a) parameter. */
3902 static void
3903 analyze_caller_dereference_legality (vec<access_p> representatives)
3905 int i;
3907 if (dump_file && (dump_flags & TDF_DETAILS))
3908 dump_dereferences_table (dump_file,
3909 "Dereference table before propagation:\n",
3910 bb_dereferences);
3912 propagate_dereference_distances ();
3914 if (dump_file && (dump_flags & TDF_DETAILS))
3915 dump_dereferences_table (dump_file,
3916 "Dereference table after propagation:\n",
3917 bb_dereferences);
3919 for (i = 0; i < func_param_count; i++)
3921 struct access *repr = representatives[i];
3922 int idx = ENTRY_BLOCK_PTR_FOR_FN (cfun)->index * func_param_count + i;
3924 if (!repr || no_accesses_p (repr))
3925 continue;
3929 if ((repr->offset + repr->size) > bb_dereferences[idx])
3930 repr->grp_not_necessarilly_dereferenced = 1;
3931 repr = repr->next_grp;
3933 while (repr);
3937 /* Return the representative access for the parameter declaration PARM if it is
3938 a scalar passed by reference which is not written to and the pointer value
3939 is not used directly. Thus, if it is legal to dereference it in the caller
3940 and we can rule out modifications through aliases, such parameter should be
3941 turned into one passed by value. Return NULL otherwise. */
3943 static struct access *
3944 unmodified_by_ref_scalar_representative (tree parm)
3946 int i, access_count;
3947 struct access *repr;
3948 vec<access_p> *access_vec;
3950 access_vec = get_base_access_vector (parm);
3951 gcc_assert (access_vec);
3952 repr = (*access_vec)[0];
3953 if (repr->write)
3954 return NULL;
3955 repr->group_representative = repr;
3957 access_count = access_vec->length ();
3958 for (i = 1; i < access_count; i++)
3960 struct access *access = (*access_vec)[i];
3961 if (access->write)
3962 return NULL;
3963 access->group_representative = repr;
3964 access->next_sibling = repr->next_sibling;
3965 repr->next_sibling = access;
3968 repr->grp_read = 1;
3969 repr->grp_scalar_ptr = 1;
3970 return repr;
3973 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
3974 associated with. REQ_ALIGN is the minimum required alignment. */
3976 static bool
3977 access_precludes_ipa_sra_p (struct access *access, unsigned int req_align)
3979 unsigned int exp_align;
3980 /* Avoid issues such as the second simple testcase in PR 42025. The problem
3981 is incompatible assign in a call statement (and possibly even in asm
3982 statements). This can be relaxed by using a new temporary but only for
3983 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
3984 intraprocedural SRA we deal with this by keeping the old aggregate around,
3985 something we cannot do in IPA-SRA.) */
3986 if (access->write
3987 && (is_gimple_call (access->stmt)
3988 || gimple_code (access->stmt) == GIMPLE_ASM))
3989 return true;
3991 exp_align = get_object_alignment (access->expr);
3992 if (exp_align < req_align)
3993 return true;
3995 return false;
3999 /* Sort collected accesses for parameter PARM, identify representatives for
4000 each accessed region and link them together. Return NULL if there are
4001 different but overlapping accesses, return the special ptr value meaning
4002 there are no accesses for this parameter if that is the case and return the
4003 first representative otherwise. Set *RO_GRP if there is a group of accesses
4004 with only read (i.e. no write) accesses. */
4006 static struct access *
4007 splice_param_accesses (tree parm, bool *ro_grp)
4009 int i, j, access_count, group_count;
4010 int agg_size, total_size = 0;
4011 struct access *access, *res, **prev_acc_ptr = &res;
4012 vec<access_p> *access_vec;
4014 access_vec = get_base_access_vector (parm);
4015 if (!access_vec)
4016 return &no_accesses_representant;
4017 access_count = access_vec->length ();
4019 access_vec->qsort (compare_access_positions);
4021 i = 0;
4022 total_size = 0;
4023 group_count = 0;
4024 while (i < access_count)
4026 bool modification;
4027 tree a1_alias_type;
4028 access = (*access_vec)[i];
4029 modification = access->write;
4030 if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type)))
4031 return NULL;
4032 a1_alias_type = reference_alias_ptr_type (access->expr);
4034 /* Access is about to become group representative unless we find some
4035 nasty overlap which would preclude us from breaking this parameter
4036 apart. */
4038 j = i + 1;
4039 while (j < access_count)
4041 struct access *ac2 = (*access_vec)[j];
4042 if (ac2->offset != access->offset)
4044 /* All or nothing law for parameters. */
4045 if (access->offset + access->size > ac2->offset)
4046 return NULL;
4047 else
4048 break;
4050 else if (ac2->size != access->size)
4051 return NULL;
4053 if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type))
4054 || (ac2->type != access->type
4055 && (TREE_ADDRESSABLE (ac2->type)
4056 || TREE_ADDRESSABLE (access->type)))
4057 || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
4058 return NULL;
4060 modification |= ac2->write;
4061 ac2->group_representative = access;
4062 ac2->next_sibling = access->next_sibling;
4063 access->next_sibling = ac2;
4064 j++;
4067 group_count++;
4068 access->grp_maybe_modified = modification;
4069 if (!modification)
4070 *ro_grp = true;
4071 *prev_acc_ptr = access;
4072 prev_acc_ptr = &access->next_grp;
4073 total_size += access->size;
4074 i = j;
4077 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4078 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4079 else
4080 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4081 if (total_size >= agg_size)
4082 return NULL;
4084 gcc_assert (group_count > 0);
4085 return res;
4088 /* Decide whether parameters with representative accesses given by REPR should
4089 be reduced into components. */
4091 static int
4092 decide_one_param_reduction (struct access *repr)
4094 int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
4095 bool by_ref;
4096 tree parm;
4098 parm = repr->base;
4099 cur_parm_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4100 gcc_assert (cur_parm_size > 0);
4102 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4104 by_ref = true;
4105 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4107 else
4109 by_ref = false;
4110 agg_size = cur_parm_size;
4113 if (dump_file)
4115 struct access *acc;
4116 fprintf (dump_file, "Evaluating PARAM group sizes for ");
4117 print_generic_expr (dump_file, parm, 0);
4118 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
4119 for (acc = repr; acc; acc = acc->next_grp)
4120 dump_access (dump_file, acc, true);
4123 total_size = 0;
4124 new_param_count = 0;
4126 for (; repr; repr = repr->next_grp)
4128 gcc_assert (parm == repr->base);
4130 /* Taking the address of a non-addressable field is verboten. */
4131 if (by_ref && repr->non_addressable)
4132 return 0;
4134 /* Do not decompose a non-BLKmode param in a way that would
4135 create BLKmode params. Especially for by-reference passing
4136 (thus, pointer-type param) this is hardly worthwhile. */
4137 if (DECL_MODE (parm) != BLKmode
4138 && TYPE_MODE (repr->type) == BLKmode)
4139 return 0;
4141 if (!by_ref || (!repr->grp_maybe_modified
4142 && !repr->grp_not_necessarilly_dereferenced))
4143 total_size += repr->size;
4144 else
4145 total_size += cur_parm_size;
4147 new_param_count++;
4150 gcc_assert (new_param_count > 0);
4152 if (optimize_function_for_size_p (cfun))
4153 parm_size_limit = cur_parm_size;
4154 else
4155 parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
4156 * cur_parm_size);
4158 if (total_size < agg_size
4159 && total_size <= parm_size_limit)
4161 if (dump_file)
4162 fprintf (dump_file, " ....will be split into %i components\n",
4163 new_param_count);
4164 return new_param_count;
4166 else
4167 return 0;
4170 /* The order of the following enums is important, we need to do extra work for
4171 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4172 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
4173 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
4175 /* Identify representatives of all accesses to all candidate parameters for
4176 IPA-SRA. Return result based on what representatives have been found. */
4178 static enum ipa_splicing_result
4179 splice_all_param_accesses (vec<access_p> &representatives)
4181 enum ipa_splicing_result result = NO_GOOD_ACCESS;
4182 tree parm;
4183 struct access *repr;
4185 representatives.create (func_param_count);
4187 for (parm = DECL_ARGUMENTS (current_function_decl);
4188 parm;
4189 parm = DECL_CHAIN (parm))
4191 if (is_unused_scalar_param (parm))
4193 representatives.quick_push (&no_accesses_representant);
4194 if (result == NO_GOOD_ACCESS)
4195 result = UNUSED_PARAMS;
4197 else if (POINTER_TYPE_P (TREE_TYPE (parm))
4198 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
4199 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4201 repr = unmodified_by_ref_scalar_representative (parm);
4202 representatives.quick_push (repr);
4203 if (repr)
4204 result = UNMODIF_BY_REF_ACCESSES;
4206 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4208 bool ro_grp = false;
4209 repr = splice_param_accesses (parm, &ro_grp);
4210 representatives.quick_push (repr);
4212 if (repr && !no_accesses_p (repr))
4214 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4216 if (ro_grp)
4217 result = UNMODIF_BY_REF_ACCESSES;
4218 else if (result < MODIF_BY_REF_ACCESSES)
4219 result = MODIF_BY_REF_ACCESSES;
4221 else if (result < BY_VAL_ACCESSES)
4222 result = BY_VAL_ACCESSES;
4224 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
4225 result = UNUSED_PARAMS;
4227 else
4228 representatives.quick_push (NULL);
4231 if (result == NO_GOOD_ACCESS)
4233 representatives.release ();
4234 return NO_GOOD_ACCESS;
4237 return result;
4240 /* Return the index of BASE in PARMS. Abort if it is not found. */
4242 static inline int
4243 get_param_index (tree base, vec<tree> parms)
4245 int i, len;
4247 len = parms.length ();
4248 for (i = 0; i < len; i++)
4249 if (parms[i] == base)
4250 return i;
4251 gcc_unreachable ();
4254 /* Convert the decisions made at the representative level into compact
4255 parameter adjustments. REPRESENTATIVES are pointers to first
4256 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4257 final number of adjustments. */
4259 static ipa_parm_adjustment_vec
4260 turn_representatives_into_adjustments (vec<access_p> representatives,
4261 int adjustments_count)
4263 vec<tree> parms;
4264 ipa_parm_adjustment_vec adjustments;
4265 tree parm;
4266 int i;
4268 gcc_assert (adjustments_count > 0);
4269 parms = ipa_get_vector_of_formal_parms (current_function_decl);
4270 adjustments.create (adjustments_count);
4271 parm = DECL_ARGUMENTS (current_function_decl);
4272 for (i = 0; i < func_param_count; i++, parm = DECL_CHAIN (parm))
4274 struct access *repr = representatives[i];
4276 if (!repr || no_accesses_p (repr))
4278 struct ipa_parm_adjustment adj;
4280 memset (&adj, 0, sizeof (adj));
4281 adj.base_index = get_param_index (parm, parms);
4282 adj.base = parm;
4283 if (!repr)
4284 adj.op = IPA_PARM_OP_COPY;
4285 else
4286 adj.op = IPA_PARM_OP_REMOVE;
4287 adj.arg_prefix = "ISRA";
4288 adjustments.quick_push (adj);
4290 else
4292 struct ipa_parm_adjustment adj;
4293 int index = get_param_index (parm, parms);
4295 for (; repr; repr = repr->next_grp)
4297 memset (&adj, 0, sizeof (adj));
4298 gcc_assert (repr->base == parm);
4299 adj.base_index = index;
4300 adj.base = repr->base;
4301 adj.type = repr->type;
4302 adj.alias_ptr_type = reference_alias_ptr_type (repr->expr);
4303 adj.offset = repr->offset;
4304 adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
4305 && (repr->grp_maybe_modified
4306 || repr->grp_not_necessarilly_dereferenced));
4307 adj.arg_prefix = "ISRA";
4308 adjustments.quick_push (adj);
4312 parms.release ();
4313 return adjustments;
4316 /* Analyze the collected accesses and produce a plan what to do with the
4317 parameters in the form of adjustments, NULL meaning nothing. */
4319 static ipa_parm_adjustment_vec
4320 analyze_all_param_acesses (void)
4322 enum ipa_splicing_result repr_state;
4323 bool proceed = false;
4324 int i, adjustments_count = 0;
4325 vec<access_p> representatives;
4326 ipa_parm_adjustment_vec adjustments;
4328 repr_state = splice_all_param_accesses (representatives);
4329 if (repr_state == NO_GOOD_ACCESS)
4330 return ipa_parm_adjustment_vec ();
4332 /* If there are any parameters passed by reference which are not modified
4333 directly, we need to check whether they can be modified indirectly. */
4334 if (repr_state == UNMODIF_BY_REF_ACCESSES)
4336 analyze_caller_dereference_legality (representatives);
4337 analyze_modified_params (representatives);
4340 for (i = 0; i < func_param_count; i++)
4342 struct access *repr = representatives[i];
4344 if (repr && !no_accesses_p (repr))
4346 if (repr->grp_scalar_ptr)
4348 adjustments_count++;
4349 if (repr->grp_not_necessarilly_dereferenced
4350 || repr->grp_maybe_modified)
4351 representatives[i] = NULL;
4352 else
4354 proceed = true;
4355 sra_stats.scalar_by_ref_to_by_val++;
4358 else
4360 int new_components = decide_one_param_reduction (repr);
4362 if (new_components == 0)
4364 representatives[i] = NULL;
4365 adjustments_count++;
4367 else
4369 adjustments_count += new_components;
4370 sra_stats.aggregate_params_reduced++;
4371 sra_stats.param_reductions_created += new_components;
4372 proceed = true;
4376 else
4378 if (no_accesses_p (repr))
4380 proceed = true;
4381 sra_stats.deleted_unused_parameters++;
4383 adjustments_count++;
4387 if (!proceed && dump_file)
4388 fprintf (dump_file, "NOT proceeding to change params.\n");
4390 if (proceed)
4391 adjustments = turn_representatives_into_adjustments (representatives,
4392 adjustments_count);
4393 else
4394 adjustments = ipa_parm_adjustment_vec ();
4396 representatives.release ();
4397 return adjustments;
4400 /* If a parameter replacement identified by ADJ does not yet exist in the form
4401 of declaration, create it and record it, otherwise return the previously
4402 created one. */
4404 static tree
4405 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
4407 tree repl;
4408 if (!adj->new_ssa_base)
4410 char *pretty_name = make_fancy_name (adj->base);
4412 repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR");
4413 DECL_NAME (repl) = get_identifier (pretty_name);
4414 obstack_free (&name_obstack, pretty_name);
4416 adj->new_ssa_base = repl;
4418 else
4419 repl = adj->new_ssa_base;
4420 return repl;
4423 /* Find the first adjustment for a particular parameter BASE in a vector of
4424 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4425 adjustment. */
4427 static struct ipa_parm_adjustment *
4428 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
4430 int i, len;
4432 len = adjustments.length ();
4433 for (i = 0; i < len; i++)
4435 struct ipa_parm_adjustment *adj;
4437 adj = &adjustments[i];
4438 if (adj->op != IPA_PARM_OP_COPY && adj->base == base)
4439 return adj;
4442 return NULL;
4445 /* If the statement STMT defines an SSA_NAME of a parameter which is to be
4446 removed because its value is not used, replace the SSA_NAME with a one
4447 relating to a created VAR_DECL together all of its uses and return true.
4448 ADJUSTMENTS is a pointer to an adjustments vector. */
4450 static bool
4451 replace_removed_params_ssa_names (gimple stmt,
4452 ipa_parm_adjustment_vec adjustments)
4454 struct ipa_parm_adjustment *adj;
4455 tree lhs, decl, repl, name;
4457 if (gimple_code (stmt) == GIMPLE_PHI)
4458 lhs = gimple_phi_result (stmt);
4459 else if (is_gimple_assign (stmt))
4460 lhs = gimple_assign_lhs (stmt);
4461 else if (is_gimple_call (stmt))
4462 lhs = gimple_call_lhs (stmt);
4463 else
4464 gcc_unreachable ();
4466 if (TREE_CODE (lhs) != SSA_NAME)
4467 return false;
4469 decl = SSA_NAME_VAR (lhs);
4470 if (decl == NULL_TREE
4471 || TREE_CODE (decl) != PARM_DECL)
4472 return false;
4474 adj = get_adjustment_for_base (adjustments, decl);
4475 if (!adj)
4476 return false;
4478 repl = get_replaced_param_substitute (adj);
4479 name = make_ssa_name (repl, stmt);
4481 if (dump_file)
4483 fprintf (dump_file, "replacing an SSA name of a removed param ");
4484 print_generic_expr (dump_file, lhs, 0);
4485 fprintf (dump_file, " with ");
4486 print_generic_expr (dump_file, name, 0);
4487 fprintf (dump_file, "\n");
4490 if (is_gimple_assign (stmt))
4491 gimple_assign_set_lhs (stmt, name);
4492 else if (is_gimple_call (stmt))
4493 gimple_call_set_lhs (stmt, name);
4494 else
4495 gimple_phi_set_result (stmt, name);
4497 replace_uses_by (lhs, name);
4498 release_ssa_name (lhs);
4499 return true;
4502 /* If the statement pointed to by STMT_PTR contains any expressions that need
4503 to replaced with a different one as noted by ADJUSTMENTS, do so. Handle any
4504 potential type incompatibilities (GSI is used to accommodate conversion
4505 statements and must point to the statement). Return true iff the statement
4506 was modified. */
4508 static bool
4509 sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi,
4510 ipa_parm_adjustment_vec adjustments)
4512 gimple stmt = *stmt_ptr;
4513 tree *lhs_p, *rhs_p;
4514 bool any;
4516 if (!gimple_assign_single_p (stmt))
4517 return false;
4519 rhs_p = gimple_assign_rhs1_ptr (stmt);
4520 lhs_p = gimple_assign_lhs_ptr (stmt);
4522 any = ipa_modify_expr (rhs_p, false, adjustments);
4523 any |= ipa_modify_expr (lhs_p, false, adjustments);
4524 if (any)
4526 tree new_rhs = NULL_TREE;
4528 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
4530 if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
4532 /* V_C_Es of constructors can cause trouble (PR 42714). */
4533 if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
4534 *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
4535 else
4536 *rhs_p = build_constructor (TREE_TYPE (*lhs_p),
4537 NULL);
4539 else
4540 new_rhs = fold_build1_loc (gimple_location (stmt),
4541 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
4542 *rhs_p);
4544 else if (REFERENCE_CLASS_P (*rhs_p)
4545 && is_gimple_reg_type (TREE_TYPE (*lhs_p))
4546 && !is_gimple_reg (*lhs_p))
4547 /* This can happen when an assignment in between two single field
4548 structures is turned into an assignment in between two pointers to
4549 scalars (PR 42237). */
4550 new_rhs = *rhs_p;
4552 if (new_rhs)
4554 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
4555 true, GSI_SAME_STMT);
4557 gimple_assign_set_rhs_from_tree (gsi, tmp);
4560 return true;
4563 return false;
4566 /* Traverse the function body and all modifications as described in
4567 ADJUSTMENTS. Return true iff the CFG has been changed. */
4569 bool
4570 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
4572 bool cfg_changed = false;
4573 basic_block bb;
4575 FOR_EACH_BB (bb)
4577 gimple_stmt_iterator gsi;
4579 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4580 replace_removed_params_ssa_names (gsi_stmt (gsi), adjustments);
4582 gsi = gsi_start_bb (bb);
4583 while (!gsi_end_p (gsi))
4585 gimple stmt = gsi_stmt (gsi);
4586 bool modified = false;
4587 tree *t;
4588 unsigned i;
4590 switch (gimple_code (stmt))
4592 case GIMPLE_RETURN:
4593 t = gimple_return_retval_ptr (stmt);
4594 if (*t != NULL_TREE)
4595 modified |= ipa_modify_expr (t, true, adjustments);
4596 break;
4598 case GIMPLE_ASSIGN:
4599 modified |= sra_ipa_modify_assign (&stmt, &gsi, adjustments);
4600 modified |= replace_removed_params_ssa_names (stmt, adjustments);
4601 break;
4603 case GIMPLE_CALL:
4604 /* Operands must be processed before the lhs. */
4605 for (i = 0; i < gimple_call_num_args (stmt); i++)
4607 t = gimple_call_arg_ptr (stmt, i);
4608 modified |= ipa_modify_expr (t, true, adjustments);
4611 if (gimple_call_lhs (stmt))
4613 t = gimple_call_lhs_ptr (stmt);
4614 modified |= ipa_modify_expr (t, false, adjustments);
4615 modified |= replace_removed_params_ssa_names (stmt,
4616 adjustments);
4618 break;
4620 case GIMPLE_ASM:
4621 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
4623 t = &TREE_VALUE (gimple_asm_input_op (stmt, i));
4624 modified |= ipa_modify_expr (t, true, adjustments);
4626 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
4628 t = &TREE_VALUE (gimple_asm_output_op (stmt, i));
4629 modified |= ipa_modify_expr (t, false, adjustments);
4631 break;
4633 default:
4634 break;
4637 if (modified)
4639 update_stmt (stmt);
4640 if (maybe_clean_eh_stmt (stmt)
4641 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
4642 cfg_changed = true;
4644 gsi_next (&gsi);
4648 return cfg_changed;
4651 /* Call gimple_debug_bind_reset_value on all debug statements describing
4652 gimple register parameters that are being removed or replaced. */
4654 static void
4655 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
4657 int i, len;
4658 gimple_stmt_iterator *gsip = NULL, gsi;
4660 if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
4662 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
4663 gsip = &gsi;
4665 len = adjustments.length ();
4666 for (i = 0; i < len; i++)
4668 struct ipa_parm_adjustment *adj;
4669 imm_use_iterator ui;
4670 gimple stmt, def_temp;
4671 tree name, vexpr, copy = NULL_TREE;
4672 use_operand_p use_p;
4674 adj = &adjustments[i];
4675 if (adj->op == IPA_PARM_OP_COPY || !is_gimple_reg (adj->base))
4676 continue;
4677 name = ssa_default_def (cfun, adj->base);
4678 vexpr = NULL;
4679 if (name)
4680 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
4682 if (gimple_clobber_p (stmt))
4684 gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
4685 unlink_stmt_vdef (stmt);
4686 gsi_remove (&cgsi, true);
4687 release_defs (stmt);
4688 continue;
4690 /* All other users must have been removed by
4691 ipa_sra_modify_function_body. */
4692 gcc_assert (is_gimple_debug (stmt));
4693 if (vexpr == NULL && gsip != NULL)
4695 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
4696 vexpr = make_node (DEBUG_EXPR_DECL);
4697 def_temp = gimple_build_debug_source_bind (vexpr, adj->base,
4698 NULL);
4699 DECL_ARTIFICIAL (vexpr) = 1;
4700 TREE_TYPE (vexpr) = TREE_TYPE (name);
4701 DECL_MODE (vexpr) = DECL_MODE (adj->base);
4702 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
4704 if (vexpr)
4706 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
4707 SET_USE (use_p, vexpr);
4709 else
4710 gimple_debug_bind_reset_value (stmt);
4711 update_stmt (stmt);
4713 /* Create a VAR_DECL for debug info purposes. */
4714 if (!DECL_IGNORED_P (adj->base))
4716 copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
4717 VAR_DECL, DECL_NAME (adj->base),
4718 TREE_TYPE (adj->base));
4719 if (DECL_PT_UID_SET_P (adj->base))
4720 SET_DECL_PT_UID (copy, DECL_PT_UID (adj->base));
4721 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (adj->base);
4722 TREE_READONLY (copy) = TREE_READONLY (adj->base);
4723 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (adj->base);
4724 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (adj->base);
4725 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (adj->base);
4726 DECL_IGNORED_P (copy) = DECL_IGNORED_P (adj->base);
4727 DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (adj->base);
4728 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
4729 SET_DECL_RTL (copy, 0);
4730 TREE_USED (copy) = 1;
4731 DECL_CONTEXT (copy) = current_function_decl;
4732 add_local_decl (cfun, copy);
4733 DECL_CHAIN (copy) =
4734 BLOCK_VARS (DECL_INITIAL (current_function_decl));
4735 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
4737 if (gsip != NULL && copy && target_for_debug_bind (adj->base))
4739 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
4740 if (vexpr)
4741 def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
4742 else
4743 def_temp = gimple_build_debug_source_bind (copy, adj->base,
4744 NULL);
4745 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
4750 /* Return false iff all callers have at least as many actual arguments as there
4751 are formal parameters in the current function. */
4753 static bool
4754 not_all_callers_have_enough_arguments_p (struct cgraph_node *node,
4755 void *data ATTRIBUTE_UNUSED)
4757 struct cgraph_edge *cs;
4758 for (cs = node->callers; cs; cs = cs->next_caller)
4759 if (!callsite_has_enough_arguments_p (cs->call_stmt))
4760 return true;
4762 return false;
4765 /* Convert all callers of NODE. */
4767 static bool
4768 convert_callers_for_node (struct cgraph_node *node,
4769 void *data)
4771 ipa_parm_adjustment_vec *adjustments = (ipa_parm_adjustment_vec *) data;
4772 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
4773 struct cgraph_edge *cs;
4775 for (cs = node->callers; cs; cs = cs->next_caller)
4777 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
4779 if (dump_file)
4780 fprintf (dump_file, "Adjusting call %s/%i -> %s/%i\n",
4781 xstrdup (cs->caller->name ()),
4782 cs->caller->order,
4783 xstrdup (cs->callee->name ()),
4784 cs->callee->order);
4786 ipa_modify_call_arguments (cs, cs->call_stmt, *adjustments);
4788 pop_cfun ();
4791 for (cs = node->callers; cs; cs = cs->next_caller)
4792 if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
4793 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
4794 compute_inline_parameters (cs->caller, true);
4795 BITMAP_FREE (recomputed_callers);
4797 return true;
4800 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
4802 static void
4803 convert_callers (struct cgraph_node *node, tree old_decl,
4804 ipa_parm_adjustment_vec adjustments)
4806 basic_block this_block;
4808 cgraph_for_node_and_aliases (node, convert_callers_for_node,
4809 &adjustments, false);
4811 if (!encountered_recursive_call)
4812 return;
4814 FOR_EACH_BB (this_block)
4816 gimple_stmt_iterator gsi;
4818 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
4820 gimple stmt = gsi_stmt (gsi);
4821 tree call_fndecl;
4822 if (gimple_code (stmt) != GIMPLE_CALL)
4823 continue;
4824 call_fndecl = gimple_call_fndecl (stmt);
4825 if (call_fndecl == old_decl)
4827 if (dump_file)
4828 fprintf (dump_file, "Adjusting recursive call");
4829 gimple_call_set_fndecl (stmt, node->decl);
4830 ipa_modify_call_arguments (NULL, stmt, adjustments);
4835 return;
4838 /* Perform all the modification required in IPA-SRA for NODE to have parameters
4839 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
4841 static bool
4842 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
4844 struct cgraph_node *new_node;
4845 bool cfg_changed;
4846 vec<cgraph_edge_p> redirect_callers = collect_callers_of_node (node);
4848 rebuild_cgraph_edges ();
4849 free_dominance_info (CDI_DOMINATORS);
4850 pop_cfun ();
4852 new_node = cgraph_function_versioning (node, redirect_callers,
4853 NULL,
4854 NULL, false, NULL, NULL, "isra");
4855 redirect_callers.release ();
4857 push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
4858 ipa_modify_formal_parameters (current_function_decl, adjustments);
4859 cfg_changed = ipa_sra_modify_function_body (adjustments);
4860 sra_ipa_reset_debug_stmts (adjustments);
4861 convert_callers (new_node, node->decl, adjustments);
4862 cgraph_make_node_local (new_node);
4863 return cfg_changed;
4866 /* If NODE has a caller, return true. */
4868 static bool
4869 has_caller_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
4871 if (node->callers)
4872 return true;
4873 return false;
4876 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
4877 attributes, return true otherwise. NODE is the cgraph node of the current
4878 function. */
4880 static bool
4881 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
4883 if (!cgraph_node_can_be_local_p (node))
4885 if (dump_file)
4886 fprintf (dump_file, "Function not local to this compilation unit.\n");
4887 return false;
4890 if (!node->local.can_change_signature)
4892 if (dump_file)
4893 fprintf (dump_file, "Function can not change signature.\n");
4894 return false;
4897 if (!tree_versionable_function_p (node->decl))
4899 if (dump_file)
4900 fprintf (dump_file, "Function is not versionable.\n");
4901 return false;
4904 if (DECL_VIRTUAL_P (current_function_decl))
4906 if (dump_file)
4907 fprintf (dump_file, "Function is a virtual method.\n");
4908 return false;
4911 if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
4912 && inline_summary (node)->size >= MAX_INLINE_INSNS_AUTO)
4914 if (dump_file)
4915 fprintf (dump_file, "Function too big to be made truly local.\n");
4916 return false;
4919 if (!cgraph_for_node_and_aliases (node, has_caller_p, NULL, true))
4921 if (dump_file)
4922 fprintf (dump_file,
4923 "Function has no callers in this compilation unit.\n");
4924 return false;
4927 if (cfun->stdarg)
4929 if (dump_file)
4930 fprintf (dump_file, "Function uses stdarg. \n");
4931 return false;
4934 if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
4935 return false;
4937 return true;
4940 /* Perform early interprocedural SRA. */
4942 static unsigned int
4943 ipa_early_sra (void)
4945 struct cgraph_node *node = cgraph_get_node (current_function_decl);
4946 ipa_parm_adjustment_vec adjustments;
4947 int ret = 0;
4949 if (!ipa_sra_preliminary_function_checks (node))
4950 return 0;
4952 sra_initialize ();
4953 sra_mode = SRA_MODE_EARLY_IPA;
4955 if (!find_param_candidates ())
4957 if (dump_file)
4958 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
4959 goto simple_out;
4962 if (cgraph_for_node_and_aliases (node, not_all_callers_have_enough_arguments_p,
4963 NULL, true))
4965 if (dump_file)
4966 fprintf (dump_file, "There are callers with insufficient number of "
4967 "arguments.\n");
4968 goto simple_out;
4971 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
4972 func_param_count
4973 * last_basic_block_for_function (cfun));
4974 final_bbs = BITMAP_ALLOC (NULL);
4976 scan_function ();
4977 if (encountered_apply_args)
4979 if (dump_file)
4980 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
4981 goto out;
4984 if (encountered_unchangable_recursive_call)
4986 if (dump_file)
4987 fprintf (dump_file, "Function calls itself with insufficient "
4988 "number of arguments.\n");
4989 goto out;
4992 adjustments = analyze_all_param_acesses ();
4993 if (!adjustments.exists ())
4994 goto out;
4995 if (dump_file)
4996 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
4998 if (modify_function (node, adjustments))
4999 ret = TODO_update_ssa | TODO_cleanup_cfg;
5000 else
5001 ret = TODO_update_ssa;
5002 adjustments.release ();
5004 statistics_counter_event (cfun, "Unused parameters deleted",
5005 sra_stats.deleted_unused_parameters);
5006 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
5007 sra_stats.scalar_by_ref_to_by_val);
5008 statistics_counter_event (cfun, "Aggregate parameters broken up",
5009 sra_stats.aggregate_params_reduced);
5010 statistics_counter_event (cfun, "Aggregate parameter components created",
5011 sra_stats.param_reductions_created);
5013 out:
5014 BITMAP_FREE (final_bbs);
5015 free (bb_dereferences);
5016 simple_out:
5017 sra_deinitialize ();
5018 return ret;
5021 /* Return if early ipa sra shall be performed. */
5022 static bool
5023 ipa_early_sra_gate (void)
5025 return flag_ipa_sra && dbg_cnt (eipa_sra);
5028 namespace {
5030 const pass_data pass_data_early_ipa_sra =
5032 GIMPLE_PASS, /* type */
5033 "eipa_sra", /* name */
5034 OPTGROUP_NONE, /* optinfo_flags */
5035 true, /* has_gate */
5036 true, /* has_execute */
5037 TV_IPA_SRA, /* tv_id */
5038 0, /* properties_required */
5039 0, /* properties_provided */
5040 0, /* properties_destroyed */
5041 0, /* todo_flags_start */
5042 TODO_dump_symtab, /* todo_flags_finish */
5045 class pass_early_ipa_sra : public gimple_opt_pass
5047 public:
5048 pass_early_ipa_sra (gcc::context *ctxt)
5049 : gimple_opt_pass (pass_data_early_ipa_sra, ctxt)
5052 /* opt_pass methods: */
5053 bool gate () { return ipa_early_sra_gate (); }
5054 unsigned int execute () { return ipa_early_sra (); }
5056 }; // class pass_early_ipa_sra
5058 } // anon namespace
5060 gimple_opt_pass *
5061 make_pass_early_ipa_sra (gcc::context *ctxt)
5063 return new pass_early_ipa_sra (ctxt);