Update .po files.
[official-gcc.git] / gcc / tree-sra.c
blob68edbce21b327589ddc8098a5f956f7f74ca77f1
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-2017 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 "backend.h"
78 #include "target.h"
79 #include "rtl.h"
80 #include "tree.h"
81 #include "gimple.h"
82 #include "predict.h"
83 #include "alloc-pool.h"
84 #include "tree-pass.h"
85 #include "ssa.h"
86 #include "cgraph.h"
87 #include "gimple-pretty-print.h"
88 #include "alias.h"
89 #include "fold-const.h"
90 #include "tree-eh.h"
91 #include "stor-layout.h"
92 #include "gimplify.h"
93 #include "gimple-iterator.h"
94 #include "gimplify-me.h"
95 #include "gimple-walk.h"
96 #include "tree-cfg.h"
97 #include "tree-dfa.h"
98 #include "tree-ssa.h"
99 #include "symbol-summary.h"
100 #include "ipa-prop.h"
101 #include "params.h"
102 #include "dbgcnt.h"
103 #include "tree-inline.h"
104 #include "ipa-fnsummary.h"
105 #include "ipa-utils.h"
106 #include "builtins.h"
108 /* Enumeration of all aggregate reductions we can do. */
109 enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
110 SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
111 SRA_MODE_INTRA }; /* late intraprocedural SRA */
113 /* Global variable describing which aggregate reduction we are performing at
114 the moment. */
115 static enum sra_mode sra_mode;
117 struct assign_link;
119 /* ACCESS represents each access to an aggregate variable (as a whole or a
120 part). It can also represent a group of accesses that refer to exactly the
121 same fragment of an aggregate (i.e. those that have exactly the same offset
122 and size). Such representatives for a single aggregate, once determined,
123 are linked in a linked list and have the group fields set.
125 Moreover, when doing intraprocedural SRA, a tree is built from those
126 representatives (by the means of first_child and next_sibling pointers), in
127 which all items in a subtree are "within" the root, i.e. their offset is
128 greater or equal to offset of the root and offset+size is smaller or equal
129 to offset+size of the root. Children of an access are sorted by offset.
131 Note that accesses to parts of vector and complex number types always
132 represented by an access to the whole complex number or a vector. It is a
133 duty of the modifying functions to replace them appropriately. */
135 struct access
137 /* Values returned by `get_ref_base_and_extent' for each component reference
138 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
139 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
140 HOST_WIDE_INT offset;
141 HOST_WIDE_INT size;
142 tree base;
144 /* Expression. It is context dependent so do not use it to create new
145 expressions to access the original aggregate. See PR 42154 for a
146 testcase. */
147 tree expr;
148 /* Type. */
149 tree type;
151 /* The statement this access belongs to. */
152 gimple *stmt;
154 /* Next group representative for this aggregate. */
155 struct access *next_grp;
157 /* Pointer to the group representative. Pointer to itself if the struct is
158 the representative. */
159 struct access *group_representative;
161 /* After access tree has been constructed, this points to the parent of the
162 current access, if there is one. NULL for roots. */
163 struct access *parent;
165 /* If this access has any children (in terms of the definition above), this
166 points to the first one. */
167 struct access *first_child;
169 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
170 described above. In IPA-SRA this is a pointer to the next access
171 belonging to the same group (having the same representative). */
172 struct access *next_sibling;
174 /* Pointers to the first and last element in the linked list of assign
175 links. */
176 struct assign_link *first_link, *last_link;
178 /* Pointer to the next access in the work queue. */
179 struct access *next_queued;
181 /* Replacement variable for this access "region." Never to be accessed
182 directly, always only by the means of get_access_replacement() and only
183 when grp_to_be_replaced flag is set. */
184 tree replacement_decl;
186 /* Is this access an access to a non-addressable field? */
187 unsigned non_addressable : 1;
189 /* Is this access made in reverse storage order? */
190 unsigned reverse : 1;
192 /* Is this particular access write access? */
193 unsigned write : 1;
195 /* Is this access currently in the work queue? */
196 unsigned grp_queued : 1;
198 /* Does this group contain a write access? This flag is propagated down the
199 access tree. */
200 unsigned grp_write : 1;
202 /* Does this group contain a read access? This flag is propagated down the
203 access tree. */
204 unsigned grp_read : 1;
206 /* Does this group contain a read access that comes from an assignment
207 statement? This flag is propagated down the access tree. */
208 unsigned grp_assignment_read : 1;
210 /* Does this group contain a write access that comes from an assignment
211 statement? This flag is propagated down the access tree. */
212 unsigned grp_assignment_write : 1;
214 /* Does this group contain a read access through a scalar type? This flag is
215 not propagated in the access tree in any direction. */
216 unsigned grp_scalar_read : 1;
218 /* Does this group contain a write access through a scalar type? This flag
219 is not propagated in the access tree in any direction. */
220 unsigned grp_scalar_write : 1;
222 /* Is this access an artificial one created to scalarize some record
223 entirely? */
224 unsigned grp_total_scalarization : 1;
226 /* Other passes of the analysis use this bit to make function
227 analyze_access_subtree create scalar replacements for this group if
228 possible. */
229 unsigned grp_hint : 1;
231 /* Is the subtree rooted in this access fully covered by scalar
232 replacements? */
233 unsigned grp_covered : 1;
235 /* If set to true, this access and all below it in an access tree must not be
236 scalarized. */
237 unsigned grp_unscalarizable_region : 1;
239 /* Whether data have been written to parts of the aggregate covered by this
240 access which is not to be scalarized. This flag is propagated up in the
241 access tree. */
242 unsigned grp_unscalarized_data : 1;
244 /* Does this access and/or group contain a write access through a
245 BIT_FIELD_REF? */
246 unsigned grp_partial_lhs : 1;
248 /* Set when a scalar replacement should be created for this variable. */
249 unsigned grp_to_be_replaced : 1;
251 /* Set when we want a replacement for the sole purpose of having it in
252 generated debug statements. */
253 unsigned grp_to_be_debug_replaced : 1;
255 /* Should TREE_NO_WARNING of a replacement be set? */
256 unsigned grp_no_warning : 1;
258 /* Is it possible that the group refers to data which might be (directly or
259 otherwise) modified? */
260 unsigned grp_maybe_modified : 1;
262 /* Set when this is a representative of a pointer to scalar (i.e. by
263 reference) parameter which we consider for turning into a plain scalar
264 (i.e. a by value parameter). */
265 unsigned grp_scalar_ptr : 1;
267 /* Set when we discover that this pointer is not safe to dereference in the
268 caller. */
269 unsigned grp_not_necessarilly_dereferenced : 1;
272 typedef struct access *access_p;
275 /* Alloc pool for allocating access structures. */
276 static object_allocator<struct access> access_pool ("SRA accesses");
278 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
279 are used to propagate subaccesses from rhs to lhs as long as they don't
280 conflict with what is already there. */
281 struct assign_link
283 struct access *lacc, *racc;
284 struct assign_link *next;
287 /* Alloc pool for allocating assign link structures. */
288 static object_allocator<assign_link> assign_link_pool ("SRA links");
290 /* Base (tree) -> Vector (vec<access_p> *) map. */
291 static hash_map<tree, auto_vec<access_p> > *base_access_vec;
293 /* Candidate hash table helpers. */
295 struct uid_decl_hasher : nofree_ptr_hash <tree_node>
297 static inline hashval_t hash (const tree_node *);
298 static inline bool equal (const tree_node *, const tree_node *);
301 /* Hash a tree in a uid_decl_map. */
303 inline hashval_t
304 uid_decl_hasher::hash (const tree_node *item)
306 return item->decl_minimal.uid;
309 /* Return true if the DECL_UID in both trees are equal. */
311 inline bool
312 uid_decl_hasher::equal (const tree_node *a, const tree_node *b)
314 return (a->decl_minimal.uid == b->decl_minimal.uid);
317 /* Set of candidates. */
318 static bitmap candidate_bitmap;
319 static hash_table<uid_decl_hasher> *candidates;
321 /* For a candidate UID return the candidates decl. */
323 static inline tree
324 candidate (unsigned uid)
326 tree_node t;
327 t.decl_minimal.uid = uid;
328 return candidates->find_with_hash (&t, static_cast <hashval_t> (uid));
331 /* Bitmap of candidates which we should try to entirely scalarize away and
332 those which cannot be (because they are and need be used as a whole). */
333 static bitmap should_scalarize_away_bitmap, cannot_scalarize_away_bitmap;
335 /* Bitmap of candidates in the constant pool, which cannot be scalarized
336 because this would produce non-constant expressions (e.g. Ada). */
337 static bitmap disqualified_constants;
339 /* Obstack for creation of fancy names. */
340 static struct obstack name_obstack;
342 /* Head of a linked list of accesses that need to have its subaccesses
343 propagated to their assignment counterparts. */
344 static struct access *work_queue_head;
346 /* Number of parameters of the analyzed function when doing early ipa SRA. */
347 static int func_param_count;
349 /* scan_function sets the following to true if it encounters a call to
350 __builtin_apply_args. */
351 static bool encountered_apply_args;
353 /* Set by scan_function when it finds a recursive call. */
354 static bool encountered_recursive_call;
356 /* Set by scan_function when it finds a recursive call with less actual
357 arguments than formal parameters.. */
358 static bool encountered_unchangable_recursive_call;
360 /* This is a table in which for each basic block and parameter there is a
361 distance (offset + size) in that parameter which is dereferenced and
362 accessed in that BB. */
363 static HOST_WIDE_INT *bb_dereferences;
364 /* Bitmap of BBs that can cause the function to "stop" progressing by
365 returning, throwing externally, looping infinitely or calling a function
366 which might abort etc.. */
367 static bitmap final_bbs;
369 /* Representative of no accesses at all. */
370 static struct access no_accesses_representant;
372 /* Predicate to test the special value. */
374 static inline bool
375 no_accesses_p (struct access *access)
377 return access == &no_accesses_representant;
380 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
381 representative fields are dumped, otherwise those which only describe the
382 individual access are. */
384 static struct
386 /* Number of processed aggregates is readily available in
387 analyze_all_variable_accesses and so is not stored here. */
389 /* Number of created scalar replacements. */
390 int replacements;
392 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
393 expression. */
394 int exprs;
396 /* Number of statements created by generate_subtree_copies. */
397 int subtree_copies;
399 /* Number of statements created by load_assign_lhs_subreplacements. */
400 int subreplacements;
402 /* Number of times sra_modify_assign has deleted a statement. */
403 int deleted;
405 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
406 RHS reparately due to type conversions or nonexistent matching
407 references. */
408 int separate_lhs_rhs_handling;
410 /* Number of parameters that were removed because they were unused. */
411 int deleted_unused_parameters;
413 /* Number of scalars passed as parameters by reference that have been
414 converted to be passed by value. */
415 int scalar_by_ref_to_by_val;
417 /* Number of aggregate parameters that were replaced by one or more of their
418 components. */
419 int aggregate_params_reduced;
421 /* Numbber of components created when splitting aggregate parameters. */
422 int param_reductions_created;
423 } sra_stats;
425 static void
426 dump_access (FILE *f, struct access *access, bool grp)
428 fprintf (f, "access { ");
429 fprintf (f, "base = (%d)'", DECL_UID (access->base));
430 print_generic_expr (f, access->base);
431 fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
432 fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
433 fprintf (f, ", expr = ");
434 print_generic_expr (f, access->expr);
435 fprintf (f, ", type = ");
436 print_generic_expr (f, access->type);
437 fprintf (f, ", non_addressable = %d, reverse = %d",
438 access->non_addressable, access->reverse);
439 if (grp)
440 fprintf (f, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
441 "grp_assignment_write = %d, grp_scalar_read = %d, "
442 "grp_scalar_write = %d, grp_total_scalarization = %d, "
443 "grp_hint = %d, grp_covered = %d, "
444 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
445 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
446 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
447 "grp_not_necessarilly_dereferenced = %d\n",
448 access->grp_read, access->grp_write, access->grp_assignment_read,
449 access->grp_assignment_write, access->grp_scalar_read,
450 access->grp_scalar_write, access->grp_total_scalarization,
451 access->grp_hint, access->grp_covered,
452 access->grp_unscalarizable_region, access->grp_unscalarized_data,
453 access->grp_partial_lhs, access->grp_to_be_replaced,
454 access->grp_to_be_debug_replaced, access->grp_maybe_modified,
455 access->grp_not_necessarilly_dereferenced);
456 else
457 fprintf (f, ", write = %d, grp_total_scalarization = %d, "
458 "grp_partial_lhs = %d\n",
459 access->write, access->grp_total_scalarization,
460 access->grp_partial_lhs);
463 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
465 static void
466 dump_access_tree_1 (FILE *f, struct access *access, int level)
470 int i;
472 for (i = 0; i < level; i++)
473 fputs ("* ", f);
475 dump_access (f, access, true);
477 if (access->first_child)
478 dump_access_tree_1 (f, access->first_child, level + 1);
480 access = access->next_sibling;
482 while (access);
485 /* Dump all access trees for a variable, given the pointer to the first root in
486 ACCESS. */
488 static void
489 dump_access_tree (FILE *f, struct access *access)
491 for (; access; access = access->next_grp)
492 dump_access_tree_1 (f, access, 0);
495 /* Return true iff ACC is non-NULL and has subaccesses. */
497 static inline bool
498 access_has_children_p (struct access *acc)
500 return acc && acc->first_child;
503 /* Return true iff ACC is (partly) covered by at least one replacement. */
505 static bool
506 access_has_replacements_p (struct access *acc)
508 struct access *child;
509 if (acc->grp_to_be_replaced)
510 return true;
511 for (child = acc->first_child; child; child = child->next_sibling)
512 if (access_has_replacements_p (child))
513 return true;
514 return false;
517 /* Return a vector of pointers to accesses for the variable given in BASE or
518 NULL if there is none. */
520 static vec<access_p> *
521 get_base_access_vector (tree base)
523 return base_access_vec->get (base);
526 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
527 in ACCESS. Return NULL if it cannot be found. */
529 static struct access *
530 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
531 HOST_WIDE_INT size)
533 while (access && (access->offset != offset || access->size != size))
535 struct access *child = access->first_child;
537 while (child && (child->offset + child->size <= offset))
538 child = child->next_sibling;
539 access = child;
542 return access;
545 /* Return the first group representative for DECL or NULL if none exists. */
547 static struct access *
548 get_first_repr_for_decl (tree base)
550 vec<access_p> *access_vec;
552 access_vec = get_base_access_vector (base);
553 if (!access_vec)
554 return NULL;
556 return (*access_vec)[0];
559 /* Find an access representative for the variable BASE and given OFFSET and
560 SIZE. Requires that access trees have already been built. Return NULL if
561 it cannot be found. */
563 static struct access *
564 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
565 HOST_WIDE_INT size)
567 struct access *access;
569 access = get_first_repr_for_decl (base);
570 while (access && (access->offset + access->size <= offset))
571 access = access->next_grp;
572 if (!access)
573 return NULL;
575 return find_access_in_subtree (access, offset, size);
578 /* Add LINK to the linked list of assign links of RACC. */
579 static void
580 add_link_to_rhs (struct access *racc, struct assign_link *link)
582 gcc_assert (link->racc == racc);
584 if (!racc->first_link)
586 gcc_assert (!racc->last_link);
587 racc->first_link = link;
589 else
590 racc->last_link->next = link;
592 racc->last_link = link;
593 link->next = NULL;
596 /* Move all link structures in their linked list in OLD_RACC to the linked list
597 in NEW_RACC. */
598 static void
599 relink_to_new_repr (struct access *new_racc, struct access *old_racc)
601 if (!old_racc->first_link)
603 gcc_assert (!old_racc->last_link);
604 return;
607 if (new_racc->first_link)
609 gcc_assert (!new_racc->last_link->next);
610 gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
612 new_racc->last_link->next = old_racc->first_link;
613 new_racc->last_link = old_racc->last_link;
615 else
617 gcc_assert (!new_racc->last_link);
619 new_racc->first_link = old_racc->first_link;
620 new_racc->last_link = old_racc->last_link;
622 old_racc->first_link = old_racc->last_link = NULL;
625 /* Add ACCESS to the work queue (which is actually a stack). */
627 static void
628 add_access_to_work_queue (struct access *access)
630 if (access->first_link && !access->grp_queued)
632 gcc_assert (!access->next_queued);
633 access->next_queued = work_queue_head;
634 access->grp_queued = 1;
635 work_queue_head = access;
639 /* Pop an access from the work queue, and return it, assuming there is one. */
641 static struct access *
642 pop_access_from_work_queue (void)
644 struct access *access = work_queue_head;
646 work_queue_head = access->next_queued;
647 access->next_queued = NULL;
648 access->grp_queued = 0;
649 return access;
653 /* Allocate necessary structures. */
655 static void
656 sra_initialize (void)
658 candidate_bitmap = BITMAP_ALLOC (NULL);
659 candidates = new hash_table<uid_decl_hasher>
660 (vec_safe_length (cfun->local_decls) / 2);
661 should_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
662 cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
663 disqualified_constants = BITMAP_ALLOC (NULL);
664 gcc_obstack_init (&name_obstack);
665 base_access_vec = new hash_map<tree, auto_vec<access_p> >;
666 memset (&sra_stats, 0, sizeof (sra_stats));
667 encountered_apply_args = false;
668 encountered_recursive_call = false;
669 encountered_unchangable_recursive_call = false;
672 /* Deallocate all general structures. */
674 static void
675 sra_deinitialize (void)
677 BITMAP_FREE (candidate_bitmap);
678 delete candidates;
679 candidates = NULL;
680 BITMAP_FREE (should_scalarize_away_bitmap);
681 BITMAP_FREE (cannot_scalarize_away_bitmap);
682 BITMAP_FREE (disqualified_constants);
683 access_pool.release ();
684 assign_link_pool.release ();
685 obstack_free (&name_obstack, NULL);
687 delete base_access_vec;
690 /* Return true if DECL is a VAR_DECL in the constant pool, false otherwise. */
692 static bool constant_decl_p (tree decl)
694 return VAR_P (decl) && DECL_IN_CONSTANT_POOL (decl);
697 /* Remove DECL from candidates for SRA and write REASON to the dump file if
698 there is one. */
700 static void
701 disqualify_candidate (tree decl, const char *reason)
703 if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl)))
704 candidates->remove_elt_with_hash (decl, DECL_UID (decl));
705 if (constant_decl_p (decl))
706 bitmap_set_bit (disqualified_constants, DECL_UID (decl));
708 if (dump_file && (dump_flags & TDF_DETAILS))
710 fprintf (dump_file, "! Disqualifying ");
711 print_generic_expr (dump_file, decl);
712 fprintf (dump_file, " - %s\n", reason);
716 /* Return true iff the type contains a field or an element which does not allow
717 scalarization. */
719 static bool
720 type_internals_preclude_sra_p (tree type, const char **msg)
722 tree fld;
723 tree et;
725 switch (TREE_CODE (type))
727 case RECORD_TYPE:
728 case UNION_TYPE:
729 case QUAL_UNION_TYPE:
730 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
731 if (TREE_CODE (fld) == FIELD_DECL)
733 tree ft = TREE_TYPE (fld);
735 if (TREE_THIS_VOLATILE (fld))
737 *msg = "volatile structure field";
738 return true;
740 if (!DECL_FIELD_OFFSET (fld))
742 *msg = "no structure field offset";
743 return true;
745 if (!DECL_SIZE (fld))
747 *msg = "zero structure field size";
748 return true;
750 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
752 *msg = "structure field offset not fixed";
753 return true;
755 if (!tree_fits_uhwi_p (DECL_SIZE (fld)))
757 *msg = "structure field size not fixed";
758 return true;
760 if (!tree_fits_shwi_p (bit_position (fld)))
762 *msg = "structure field size too big";
763 return true;
765 if (AGGREGATE_TYPE_P (ft)
766 && int_bit_position (fld) % BITS_PER_UNIT != 0)
768 *msg = "structure field is bit field";
769 return true;
772 if (AGGREGATE_TYPE_P (ft) && type_internals_preclude_sra_p (ft, msg))
773 return true;
776 return false;
778 case ARRAY_TYPE:
779 et = TREE_TYPE (type);
781 if (TYPE_VOLATILE (et))
783 *msg = "element type is volatile";
784 return true;
787 if (AGGREGATE_TYPE_P (et) && type_internals_preclude_sra_p (et, msg))
788 return true;
790 return false;
792 default:
793 return false;
797 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
798 base variable if it is. Return T if it is not an SSA_NAME. */
800 static tree
801 get_ssa_base_param (tree t)
803 if (TREE_CODE (t) == SSA_NAME)
805 if (SSA_NAME_IS_DEFAULT_DEF (t))
806 return SSA_NAME_VAR (t);
807 else
808 return NULL_TREE;
810 return t;
813 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
814 belongs to, unless the BB has already been marked as a potentially
815 final. */
817 static void
818 mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple *stmt)
820 basic_block bb = gimple_bb (stmt);
821 int idx, parm_index = 0;
822 tree parm;
824 if (bitmap_bit_p (final_bbs, bb->index))
825 return;
827 for (parm = DECL_ARGUMENTS (current_function_decl);
828 parm && parm != base;
829 parm = DECL_CHAIN (parm))
830 parm_index++;
832 gcc_assert (parm_index < func_param_count);
834 idx = bb->index * func_param_count + parm_index;
835 if (bb_dereferences[idx] < dist)
836 bb_dereferences[idx] = dist;
839 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
840 the three fields. Also add it to the vector of accesses corresponding to
841 the base. Finally, return the new access. */
843 static struct access *
844 create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
846 struct access *access = access_pool.allocate ();
848 memset (access, 0, sizeof (struct access));
849 access->base = base;
850 access->offset = offset;
851 access->size = size;
853 base_access_vec->get_or_insert (base).safe_push (access);
855 return access;
858 static bool maybe_add_sra_candidate (tree);
860 /* Create and insert access for EXPR. Return created access, or NULL if it is
861 not possible. Also scan for uses of constant pool as we go along and add
862 to candidates. */
864 static struct access *
865 create_access (tree expr, gimple *stmt, bool write)
867 struct access *access;
868 HOST_WIDE_INT offset, size, max_size;
869 tree base = expr;
870 bool reverse, ptr, unscalarizable_region = false;
872 base = get_ref_base_and_extent (expr, &offset, &size, &max_size, &reverse);
874 if (sra_mode == SRA_MODE_EARLY_IPA
875 && TREE_CODE (base) == MEM_REF)
877 base = get_ssa_base_param (TREE_OPERAND (base, 0));
878 if (!base)
879 return NULL;
880 ptr = true;
882 else
883 ptr = false;
885 /* For constant-pool entries, check we can substitute the constant value. */
886 if (constant_decl_p (base)
887 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA))
889 gcc_assert (!bitmap_bit_p (disqualified_constants, DECL_UID (base)));
890 if (expr != base
891 && !is_gimple_reg_type (TREE_TYPE (expr))
892 && dump_file && (dump_flags & TDF_DETAILS))
894 /* This occurs in Ada with accesses to ARRAY_RANGE_REFs,
895 and elements of multidimensional arrays (which are
896 multi-element arrays in their own right). */
897 fprintf (dump_file, "Allowing non-reg-type load of part"
898 " of constant-pool entry: ");
899 print_generic_expr (dump_file, expr);
901 maybe_add_sra_candidate (base);
904 if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
905 return NULL;
907 if (sra_mode == SRA_MODE_EARLY_IPA)
909 if (size < 0 || size != max_size)
911 disqualify_candidate (base, "Encountered a variable sized access.");
912 return NULL;
914 if (TREE_CODE (expr) == COMPONENT_REF
915 && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))
917 disqualify_candidate (base, "Encountered a bit-field access.");
918 return NULL;
920 gcc_checking_assert ((offset % BITS_PER_UNIT) == 0);
922 if (ptr)
923 mark_parm_dereference (base, offset + size, stmt);
925 else
927 if (size != max_size)
929 size = max_size;
930 unscalarizable_region = true;
932 if (size < 0)
934 disqualify_candidate (base, "Encountered an unconstrained access.");
935 return NULL;
939 access = create_access_1 (base, offset, size);
940 access->expr = expr;
941 access->type = TREE_TYPE (expr);
942 access->write = write;
943 access->grp_unscalarizable_region = unscalarizable_region;
944 access->stmt = stmt;
945 access->reverse = reverse;
947 if (TREE_CODE (expr) == COMPONENT_REF
948 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1)))
949 access->non_addressable = 1;
951 return access;
955 /* Return true iff TYPE is scalarizable - i.e. a RECORD_TYPE or fixed-length
956 ARRAY_TYPE with fields that are either of gimple register types (excluding
957 bit-fields) or (recursively) scalarizable types. CONST_DECL must be true if
958 we are considering a decl from constant pool. If it is false, char arrays
959 will be refused. */
961 static bool
962 scalarizable_type_p (tree type, bool const_decl)
964 gcc_assert (!is_gimple_reg_type (type));
965 if (type_contains_placeholder_p (type))
966 return false;
968 switch (TREE_CODE (type))
970 case RECORD_TYPE:
971 for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
972 if (TREE_CODE (fld) == FIELD_DECL)
974 tree ft = TREE_TYPE (fld);
976 if (DECL_BIT_FIELD (fld))
977 return false;
979 if (!is_gimple_reg_type (ft)
980 && !scalarizable_type_p (ft, const_decl))
981 return false;
984 return true;
986 case ARRAY_TYPE:
988 HOST_WIDE_INT min_elem_size;
989 if (const_decl)
990 min_elem_size = 0;
991 else
992 min_elem_size = BITS_PER_UNIT;
994 if (TYPE_DOMAIN (type) == NULL_TREE
995 || !tree_fits_shwi_p (TYPE_SIZE (type))
996 || !tree_fits_shwi_p (TYPE_SIZE (TREE_TYPE (type)))
997 || (tree_to_shwi (TYPE_SIZE (TREE_TYPE (type))) <= min_elem_size)
998 || !tree_fits_shwi_p (TYPE_MIN_VALUE (TYPE_DOMAIN (type))))
999 return false;
1000 if (tree_to_shwi (TYPE_SIZE (type)) == 0
1001 && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE)
1002 /* Zero-element array, should not prevent scalarization. */
1004 else if ((tree_to_shwi (TYPE_SIZE (type)) <= 0)
1005 || !tree_fits_shwi_p (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
1006 /* Variable-length array, do not allow scalarization. */
1007 return false;
1009 tree elem = TREE_TYPE (type);
1010 if (!is_gimple_reg_type (elem)
1011 && !scalarizable_type_p (elem, const_decl))
1012 return false;
1013 return true;
1015 default:
1016 return false;
1020 static void scalarize_elem (tree, HOST_WIDE_INT, HOST_WIDE_INT, bool, tree, tree);
1022 /* Create total_scalarization accesses for all scalar fields of a member
1023 of type DECL_TYPE conforming to scalarizable_type_p. BASE
1024 must be the top-most VAR_DECL representing the variable; within that,
1025 OFFSET locates the member and REF must be the memory reference expression for
1026 the member. */
1028 static void
1029 completely_scalarize (tree base, tree decl_type, HOST_WIDE_INT offset, tree ref)
1031 switch (TREE_CODE (decl_type))
1033 case RECORD_TYPE:
1034 for (tree fld = TYPE_FIELDS (decl_type); fld; fld = DECL_CHAIN (fld))
1035 if (TREE_CODE (fld) == FIELD_DECL)
1037 HOST_WIDE_INT pos = offset + int_bit_position (fld);
1038 tree ft = TREE_TYPE (fld);
1039 tree nref = build3 (COMPONENT_REF, ft, ref, fld, NULL_TREE);
1041 scalarize_elem (base, pos, tree_to_uhwi (DECL_SIZE (fld)),
1042 TYPE_REVERSE_STORAGE_ORDER (decl_type),
1043 nref, ft);
1045 break;
1046 case ARRAY_TYPE:
1048 tree elemtype = TREE_TYPE (decl_type);
1049 tree elem_size = TYPE_SIZE (elemtype);
1050 gcc_assert (elem_size && tree_fits_shwi_p (elem_size));
1051 HOST_WIDE_INT el_size = tree_to_shwi (elem_size);
1052 gcc_assert (el_size > 0);
1054 tree minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (decl_type));
1055 gcc_assert (TREE_CODE (minidx) == INTEGER_CST);
1056 tree maxidx = TYPE_MAX_VALUE (TYPE_DOMAIN (decl_type));
1057 /* Skip (some) zero-length arrays; others have MAXIDX == MINIDX - 1. */
1058 if (maxidx)
1060 gcc_assert (TREE_CODE (maxidx) == INTEGER_CST);
1061 tree domain = TYPE_DOMAIN (decl_type);
1062 /* MINIDX and MAXIDX are inclusive, and must be interpreted in
1063 DOMAIN (e.g. signed int, whereas min/max may be size_int). */
1064 offset_int idx = wi::to_offset (minidx);
1065 offset_int max = wi::to_offset (maxidx);
1066 if (!TYPE_UNSIGNED (domain))
1068 idx = wi::sext (idx, TYPE_PRECISION (domain));
1069 max = wi::sext (max, TYPE_PRECISION (domain));
1071 for (int el_off = offset; idx <= max; ++idx)
1073 tree nref = build4 (ARRAY_REF, elemtype,
1074 ref,
1075 wide_int_to_tree (domain, idx),
1076 NULL_TREE, NULL_TREE);
1077 scalarize_elem (base, el_off, el_size,
1078 TYPE_REVERSE_STORAGE_ORDER (decl_type),
1079 nref, elemtype);
1080 el_off += el_size;
1084 break;
1085 default:
1086 gcc_unreachable ();
1090 /* Create total_scalarization accesses for a member of type TYPE, which must
1091 satisfy either is_gimple_reg_type or scalarizable_type_p. BASE must be the
1092 top-most VAR_DECL representing the variable; within that, POS and SIZE locate
1093 the member, REVERSE gives its torage order. and REF must be the reference
1094 expression for it. */
1096 static void
1097 scalarize_elem (tree base, HOST_WIDE_INT pos, HOST_WIDE_INT size, bool reverse,
1098 tree ref, tree type)
1100 if (is_gimple_reg_type (type))
1102 struct access *access = create_access_1 (base, pos, size);
1103 access->expr = ref;
1104 access->type = type;
1105 access->grp_total_scalarization = 1;
1106 access->reverse = reverse;
1107 /* Accesses for intraprocedural SRA can have their stmt NULL. */
1109 else
1110 completely_scalarize (base, type, pos, ref);
1113 /* Create a total_scalarization access for VAR as a whole. VAR must be of a
1114 RECORD_TYPE or ARRAY_TYPE conforming to scalarizable_type_p. */
1116 static void
1117 create_total_scalarization_access (tree var)
1119 HOST_WIDE_INT size = tree_to_uhwi (DECL_SIZE (var));
1120 struct access *access;
1122 access = create_access_1 (var, 0, size);
1123 access->expr = var;
1124 access->type = TREE_TYPE (var);
1125 access->grp_total_scalarization = 1;
1128 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1130 static inline bool
1131 contains_view_convert_expr_p (const_tree ref)
1133 while (handled_component_p (ref))
1135 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
1136 return true;
1137 ref = TREE_OPERAND (ref, 0);
1140 return false;
1143 /* Search the given tree for a declaration by skipping handled components and
1144 exclude it from the candidates. */
1146 static void
1147 disqualify_base_of_expr (tree t, const char *reason)
1149 t = get_base_address (t);
1150 if (sra_mode == SRA_MODE_EARLY_IPA
1151 && TREE_CODE (t) == MEM_REF)
1152 t = get_ssa_base_param (TREE_OPERAND (t, 0));
1154 if (t && DECL_P (t))
1155 disqualify_candidate (t, reason);
1158 /* Scan expression EXPR and create access structures for all accesses to
1159 candidates for scalarization. Return the created access or NULL if none is
1160 created. */
1162 static struct access *
1163 build_access_from_expr_1 (tree expr, gimple *stmt, bool write)
1165 struct access *ret = NULL;
1166 bool partial_ref;
1168 if (TREE_CODE (expr) == BIT_FIELD_REF
1169 || TREE_CODE (expr) == IMAGPART_EXPR
1170 || TREE_CODE (expr) == REALPART_EXPR)
1172 expr = TREE_OPERAND (expr, 0);
1173 partial_ref = true;
1175 else
1176 partial_ref = false;
1178 if (storage_order_barrier_p (expr))
1180 disqualify_base_of_expr (expr, "storage order barrier.");
1181 return NULL;
1184 /* We need to dive through V_C_Es in order to get the size of its parameter
1185 and not the result type. Ada produces such statements. We are also
1186 capable of handling the topmost V_C_E but not any of those buried in other
1187 handled components. */
1188 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
1189 expr = TREE_OPERAND (expr, 0);
1191 if (contains_view_convert_expr_p (expr))
1193 disqualify_base_of_expr (expr, "V_C_E under a different handled "
1194 "component.");
1195 return NULL;
1197 if (TREE_THIS_VOLATILE (expr))
1199 disqualify_base_of_expr (expr, "part of a volatile reference.");
1200 return NULL;
1203 switch (TREE_CODE (expr))
1205 case MEM_REF:
1206 if (TREE_CODE (TREE_OPERAND (expr, 0)) != ADDR_EXPR
1207 && sra_mode != SRA_MODE_EARLY_IPA)
1208 return NULL;
1209 /* fall through */
1210 case VAR_DECL:
1211 case PARM_DECL:
1212 case RESULT_DECL:
1213 case COMPONENT_REF:
1214 case ARRAY_REF:
1215 case ARRAY_RANGE_REF:
1216 ret = create_access (expr, stmt, write);
1217 break;
1219 default:
1220 break;
1223 if (write && partial_ref && ret)
1224 ret->grp_partial_lhs = 1;
1226 return ret;
1229 /* Scan expression EXPR and create access structures for all accesses to
1230 candidates for scalarization. Return true if any access has been inserted.
1231 STMT must be the statement from which the expression is taken, WRITE must be
1232 true if the expression is a store and false otherwise. */
1234 static bool
1235 build_access_from_expr (tree expr, gimple *stmt, bool write)
1237 struct access *access;
1239 access = build_access_from_expr_1 (expr, stmt, write);
1240 if (access)
1242 /* This means the aggregate is accesses as a whole in a way other than an
1243 assign statement and thus cannot be removed even if we had a scalar
1244 replacement for everything. */
1245 if (cannot_scalarize_away_bitmap)
1246 bitmap_set_bit (cannot_scalarize_away_bitmap, DECL_UID (access->base));
1247 return true;
1249 return false;
1252 /* Return the single non-EH successor edge of BB or NULL if there is none or
1253 more than one. */
1255 static edge
1256 single_non_eh_succ (basic_block bb)
1258 edge e, res = NULL;
1259 edge_iterator ei;
1261 FOR_EACH_EDGE (e, ei, bb->succs)
1262 if (!(e->flags & EDGE_EH))
1264 if (res)
1265 return NULL;
1266 res = e;
1269 return res;
1272 /* Disqualify LHS and RHS for scalarization if STMT has to terminate its BB and
1273 there is no alternative spot where to put statements SRA might need to
1274 generate after it. The spot we are looking for is an edge leading to a
1275 single non-EH successor, if it exists and is indeed single. RHS may be
1276 NULL, in that case ignore it. */
1278 static bool
1279 disqualify_if_bad_bb_terminating_stmt (gimple *stmt, tree lhs, tree rhs)
1281 if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1282 && stmt_ends_bb_p (stmt))
1284 if (single_non_eh_succ (gimple_bb (stmt)))
1285 return false;
1287 disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
1288 if (rhs)
1289 disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
1290 return true;
1292 return false;
1295 /* Return true if the nature of BASE is such that it contains data even if
1296 there is no write to it in the function. */
1298 static bool
1299 comes_initialized_p (tree base)
1301 return TREE_CODE (base) == PARM_DECL || constant_decl_p (base);
1304 /* Scan expressions occurring in STMT, create access structures for all accesses
1305 to candidates for scalarization and remove those candidates which occur in
1306 statements or expressions that prevent them from being split apart. Return
1307 true if any access has been inserted. */
1309 static bool
1310 build_accesses_from_assign (gimple *stmt)
1312 tree lhs, rhs;
1313 struct access *lacc, *racc;
1315 if (!gimple_assign_single_p (stmt)
1316 /* Scope clobbers don't influence scalarization. */
1317 || gimple_clobber_p (stmt))
1318 return false;
1320 lhs = gimple_assign_lhs (stmt);
1321 rhs = gimple_assign_rhs1 (stmt);
1323 if (disqualify_if_bad_bb_terminating_stmt (stmt, lhs, rhs))
1324 return false;
1326 racc = build_access_from_expr_1 (rhs, stmt, false);
1327 lacc = build_access_from_expr_1 (lhs, stmt, true);
1329 if (lacc)
1331 lacc->grp_assignment_write = 1;
1332 if (storage_order_barrier_p (rhs))
1333 lacc->grp_unscalarizable_region = 1;
1336 if (racc)
1338 racc->grp_assignment_read = 1;
1339 if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
1340 && !is_gimple_reg_type (racc->type))
1341 bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
1342 if (storage_order_barrier_p (lhs))
1343 racc->grp_unscalarizable_region = 1;
1346 if (lacc && racc
1347 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1348 && !lacc->grp_unscalarizable_region
1349 && !racc->grp_unscalarizable_region
1350 && AGGREGATE_TYPE_P (TREE_TYPE (lhs))
1351 && lacc->size == racc->size
1352 && useless_type_conversion_p (lacc->type, racc->type))
1354 struct assign_link *link;
1356 link = assign_link_pool.allocate ();
1357 memset (link, 0, sizeof (struct assign_link));
1359 link->lacc = lacc;
1360 link->racc = racc;
1361 add_link_to_rhs (racc, link);
1362 /* Let's delay marking the areas as written until propagation of accesses
1363 across link, unless the nature of rhs tells us that its data comes
1364 from elsewhere. */
1365 if (!comes_initialized_p (racc->base))
1366 lacc->write = false;
1369 return lacc || racc;
1372 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1373 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1375 static bool
1376 asm_visit_addr (gimple *, tree op, tree, void *)
1378 op = get_base_address (op);
1379 if (op
1380 && DECL_P (op))
1381 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
1383 return false;
1386 /* Return true iff callsite CALL has at least as many actual arguments as there
1387 are formal parameters of the function currently processed by IPA-SRA and
1388 that their types match. */
1390 static inline bool
1391 callsite_arguments_match_p (gimple *call)
1393 if (gimple_call_num_args (call) < (unsigned) func_param_count)
1394 return false;
1396 tree parm;
1397 int i;
1398 for (parm = DECL_ARGUMENTS (current_function_decl), i = 0;
1399 parm;
1400 parm = DECL_CHAIN (parm), i++)
1402 tree arg = gimple_call_arg (call, i);
1403 if (!useless_type_conversion_p (TREE_TYPE (parm), TREE_TYPE (arg)))
1404 return false;
1406 return true;
1409 /* Scan function and look for interesting expressions and create access
1410 structures for them. Return true iff any access is created. */
1412 static bool
1413 scan_function (void)
1415 basic_block bb;
1416 bool ret = false;
1418 FOR_EACH_BB_FN (bb, cfun)
1420 gimple_stmt_iterator gsi;
1421 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1423 gimple *stmt = gsi_stmt (gsi);
1424 tree t;
1425 unsigned i;
1427 if (final_bbs && stmt_can_throw_external (stmt))
1428 bitmap_set_bit (final_bbs, bb->index);
1429 switch (gimple_code (stmt))
1431 case GIMPLE_RETURN:
1432 t = gimple_return_retval (as_a <greturn *> (stmt));
1433 if (t != NULL_TREE)
1434 ret |= build_access_from_expr (t, stmt, false);
1435 if (final_bbs)
1436 bitmap_set_bit (final_bbs, bb->index);
1437 break;
1439 case GIMPLE_ASSIGN:
1440 ret |= build_accesses_from_assign (stmt);
1441 break;
1443 case GIMPLE_CALL:
1444 for (i = 0; i < gimple_call_num_args (stmt); i++)
1445 ret |= build_access_from_expr (gimple_call_arg (stmt, i),
1446 stmt, false);
1448 if (sra_mode == SRA_MODE_EARLY_IPA)
1450 tree dest = gimple_call_fndecl (stmt);
1451 int flags = gimple_call_flags (stmt);
1453 if (dest)
1455 if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1456 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1457 encountered_apply_args = true;
1458 if (recursive_call_p (current_function_decl, dest))
1460 encountered_recursive_call = true;
1461 if (!callsite_arguments_match_p (stmt))
1462 encountered_unchangable_recursive_call = true;
1466 if (final_bbs
1467 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1468 bitmap_set_bit (final_bbs, bb->index);
1471 t = gimple_call_lhs (stmt);
1472 if (t && !disqualify_if_bad_bb_terminating_stmt (stmt, t, NULL))
1473 ret |= build_access_from_expr (t, stmt, true);
1474 break;
1476 case GIMPLE_ASM:
1478 gasm *asm_stmt = as_a <gasm *> (stmt);
1479 walk_stmt_load_store_addr_ops (asm_stmt, NULL, NULL, NULL,
1480 asm_visit_addr);
1481 if (final_bbs)
1482 bitmap_set_bit (final_bbs, bb->index);
1484 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
1486 t = TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
1487 ret |= build_access_from_expr (t, asm_stmt, false);
1489 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
1491 t = TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
1492 ret |= build_access_from_expr (t, asm_stmt, true);
1495 break;
1497 default:
1498 break;
1503 return ret;
1506 /* Helper of QSORT function. There are pointers to accesses in the array. An
1507 access is considered smaller than another if it has smaller offset or if the
1508 offsets are the same but is size is bigger. */
1510 static int
1511 compare_access_positions (const void *a, const void *b)
1513 const access_p *fp1 = (const access_p *) a;
1514 const access_p *fp2 = (const access_p *) b;
1515 const access_p f1 = *fp1;
1516 const access_p f2 = *fp2;
1518 if (f1->offset != f2->offset)
1519 return f1->offset < f2->offset ? -1 : 1;
1521 if (f1->size == f2->size)
1523 if (f1->type == f2->type)
1524 return 0;
1525 /* Put any non-aggregate type before any aggregate type. */
1526 else if (!is_gimple_reg_type (f1->type)
1527 && is_gimple_reg_type (f2->type))
1528 return 1;
1529 else if (is_gimple_reg_type (f1->type)
1530 && !is_gimple_reg_type (f2->type))
1531 return -1;
1532 /* Put any complex or vector type before any other scalar type. */
1533 else if (TREE_CODE (f1->type) != COMPLEX_TYPE
1534 && TREE_CODE (f1->type) != VECTOR_TYPE
1535 && (TREE_CODE (f2->type) == COMPLEX_TYPE
1536 || TREE_CODE (f2->type) == VECTOR_TYPE))
1537 return 1;
1538 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
1539 || TREE_CODE (f1->type) == VECTOR_TYPE)
1540 && TREE_CODE (f2->type) != COMPLEX_TYPE
1541 && TREE_CODE (f2->type) != VECTOR_TYPE)
1542 return -1;
1543 /* Put the integral type with the bigger precision first. */
1544 else if (INTEGRAL_TYPE_P (f1->type)
1545 && INTEGRAL_TYPE_P (f2->type))
1546 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
1547 /* Put any integral type with non-full precision last. */
1548 else if (INTEGRAL_TYPE_P (f1->type)
1549 && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type))
1550 != TYPE_PRECISION (f1->type)))
1551 return 1;
1552 else if (INTEGRAL_TYPE_P (f2->type)
1553 && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type))
1554 != TYPE_PRECISION (f2->type)))
1555 return -1;
1556 /* Stabilize the sort. */
1557 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1560 /* We want the bigger accesses first, thus the opposite operator in the next
1561 line: */
1562 return f1->size > f2->size ? -1 : 1;
1566 /* Append a name of the declaration to the name obstack. A helper function for
1567 make_fancy_name. */
1569 static void
1570 make_fancy_decl_name (tree decl)
1572 char buffer[32];
1574 tree name = DECL_NAME (decl);
1575 if (name)
1576 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1577 IDENTIFIER_LENGTH (name));
1578 else
1580 sprintf (buffer, "D%u", DECL_UID (decl));
1581 obstack_grow (&name_obstack, buffer, strlen (buffer));
1585 /* Helper for make_fancy_name. */
1587 static void
1588 make_fancy_name_1 (tree expr)
1590 char buffer[32];
1591 tree index;
1593 if (DECL_P (expr))
1595 make_fancy_decl_name (expr);
1596 return;
1599 switch (TREE_CODE (expr))
1601 case COMPONENT_REF:
1602 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1603 obstack_1grow (&name_obstack, '$');
1604 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1605 break;
1607 case ARRAY_REF:
1608 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1609 obstack_1grow (&name_obstack, '$');
1610 /* Arrays with only one element may not have a constant as their
1611 index. */
1612 index = TREE_OPERAND (expr, 1);
1613 if (TREE_CODE (index) != INTEGER_CST)
1614 break;
1615 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1616 obstack_grow (&name_obstack, buffer, strlen (buffer));
1617 break;
1619 case ADDR_EXPR:
1620 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1621 break;
1623 case MEM_REF:
1624 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1625 if (!integer_zerop (TREE_OPERAND (expr, 1)))
1627 obstack_1grow (&name_obstack, '$');
1628 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC,
1629 TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)));
1630 obstack_grow (&name_obstack, buffer, strlen (buffer));
1632 break;
1634 case BIT_FIELD_REF:
1635 case REALPART_EXPR:
1636 case IMAGPART_EXPR:
1637 gcc_unreachable (); /* we treat these as scalars. */
1638 break;
1639 default:
1640 break;
1644 /* Create a human readable name for replacement variable of ACCESS. */
1646 static char *
1647 make_fancy_name (tree expr)
1649 make_fancy_name_1 (expr);
1650 obstack_1grow (&name_obstack, '\0');
1651 return XOBFINISH (&name_obstack, char *);
1654 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1655 EXP_TYPE at the given OFFSET and with storage order REVERSE. If BASE is
1656 something for which get_addr_base_and_unit_offset returns NULL, gsi must
1657 be non-NULL and is used to insert new statements either before or below
1658 the current one as specified by INSERT_AFTER. This function is not capable
1659 of handling bitfields. */
1661 tree
1662 build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
1663 bool reverse, tree exp_type, gimple_stmt_iterator *gsi,
1664 bool insert_after)
1666 tree prev_base = base;
1667 tree off;
1668 tree mem_ref;
1669 HOST_WIDE_INT base_offset;
1670 unsigned HOST_WIDE_INT misalign;
1671 unsigned int align;
1673 /* Preserve address-space information. */
1674 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (base));
1675 if (as != TYPE_ADDR_SPACE (exp_type))
1676 exp_type = build_qualified_type (exp_type,
1677 TYPE_QUALS (exp_type)
1678 | ENCODE_QUAL_ADDR_SPACE (as));
1680 gcc_checking_assert (offset % BITS_PER_UNIT == 0);
1681 get_object_alignment_1 (base, &align, &misalign);
1682 base = get_addr_base_and_unit_offset (base, &base_offset);
1684 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1685 offset such as array[var_index]. */
1686 if (!base)
1688 gassign *stmt;
1689 tree tmp, addr;
1691 gcc_checking_assert (gsi);
1692 tmp = make_ssa_name (build_pointer_type (TREE_TYPE (prev_base)));
1693 addr = build_fold_addr_expr (unshare_expr (prev_base));
1694 STRIP_USELESS_TYPE_CONVERSION (addr);
1695 stmt = gimple_build_assign (tmp, addr);
1696 gimple_set_location (stmt, loc);
1697 if (insert_after)
1698 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
1699 else
1700 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1702 off = build_int_cst (reference_alias_ptr_type (prev_base),
1703 offset / BITS_PER_UNIT);
1704 base = tmp;
1706 else if (TREE_CODE (base) == MEM_REF)
1708 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1709 base_offset + offset / BITS_PER_UNIT);
1710 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1711 base = unshare_expr (TREE_OPERAND (base, 0));
1713 else
1715 off = build_int_cst (reference_alias_ptr_type (prev_base),
1716 base_offset + offset / BITS_PER_UNIT);
1717 base = build_fold_addr_expr (unshare_expr (base));
1720 misalign = (misalign + offset) & (align - 1);
1721 if (misalign != 0)
1722 align = least_bit_hwi (misalign);
1723 if (align != TYPE_ALIGN (exp_type))
1724 exp_type = build_aligned_type (exp_type, align);
1726 mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off);
1727 REF_REVERSE_STORAGE_ORDER (mem_ref) = reverse;
1728 if (TREE_THIS_VOLATILE (prev_base))
1729 TREE_THIS_VOLATILE (mem_ref) = 1;
1730 if (TREE_SIDE_EFFECTS (prev_base))
1731 TREE_SIDE_EFFECTS (mem_ref) = 1;
1732 return mem_ref;
1735 /* Construct a memory reference to a part of an aggregate BASE at the given
1736 OFFSET and of the same type as MODEL. In case this is a reference to a
1737 bit-field, the function will replicate the last component_ref of model's
1738 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1739 build_ref_for_offset. */
1741 static tree
1742 build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1743 struct access *model, gimple_stmt_iterator *gsi,
1744 bool insert_after)
1746 if (TREE_CODE (model->expr) == COMPONENT_REF
1747 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1749 /* This access represents a bit-field. */
1750 tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
1752 offset -= int_bit_position (fld);
1753 exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
1754 t = build_ref_for_offset (loc, base, offset, model->reverse, exp_type,
1755 gsi, insert_after);
1756 /* The flag will be set on the record type. */
1757 REF_REVERSE_STORAGE_ORDER (t) = 0;
1758 return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
1759 NULL_TREE);
1761 else
1762 return
1763 build_ref_for_offset (loc, base, offset, model->reverse, model->type,
1764 gsi, insert_after);
1767 /* Attempt to build a memory reference that we could but into a gimple
1768 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1769 create statements and return s NULL instead. This function also ignores
1770 alignment issues and so its results should never end up in non-debug
1771 statements. */
1773 static tree
1774 build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1775 struct access *model)
1777 HOST_WIDE_INT base_offset;
1778 tree off;
1780 if (TREE_CODE (model->expr) == COMPONENT_REF
1781 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1782 return NULL_TREE;
1784 base = get_addr_base_and_unit_offset (base, &base_offset);
1785 if (!base)
1786 return NULL_TREE;
1787 if (TREE_CODE (base) == MEM_REF)
1789 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1790 base_offset + offset / BITS_PER_UNIT);
1791 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1792 base = unshare_expr (TREE_OPERAND (base, 0));
1794 else
1796 off = build_int_cst (reference_alias_ptr_type (base),
1797 base_offset + offset / BITS_PER_UNIT);
1798 base = build_fold_addr_expr (unshare_expr (base));
1801 return fold_build2_loc (loc, MEM_REF, model->type, base, off);
1804 /* Construct a memory reference consisting of component_refs and array_refs to
1805 a part of an aggregate *RES (which is of type TYPE). The requested part
1806 should have type EXP_TYPE at be the given OFFSET. This function might not
1807 succeed, it returns true when it does and only then *RES points to something
1808 meaningful. This function should be used only to build expressions that we
1809 might need to present to user (e.g. in warnings). In all other situations,
1810 build_ref_for_model or build_ref_for_offset should be used instead. */
1812 static bool
1813 build_user_friendly_ref_for_offset (tree *res, tree type, HOST_WIDE_INT offset,
1814 tree exp_type)
1816 while (1)
1818 tree fld;
1819 tree tr_size, index, minidx;
1820 HOST_WIDE_INT el_size;
1822 if (offset == 0 && exp_type
1823 && types_compatible_p (exp_type, type))
1824 return true;
1826 switch (TREE_CODE (type))
1828 case UNION_TYPE:
1829 case QUAL_UNION_TYPE:
1830 case RECORD_TYPE:
1831 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
1833 HOST_WIDE_INT pos, size;
1834 tree tr_pos, expr, *expr_ptr;
1836 if (TREE_CODE (fld) != FIELD_DECL)
1837 continue;
1839 tr_pos = bit_position (fld);
1840 if (!tr_pos || !tree_fits_uhwi_p (tr_pos))
1841 continue;
1842 pos = tree_to_uhwi (tr_pos);
1843 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1844 tr_size = DECL_SIZE (fld);
1845 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1846 continue;
1847 size = tree_to_uhwi (tr_size);
1848 if (size == 0)
1850 if (pos != offset)
1851 continue;
1853 else if (pos > offset || (pos + size) <= offset)
1854 continue;
1856 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1857 NULL_TREE);
1858 expr_ptr = &expr;
1859 if (build_user_friendly_ref_for_offset (expr_ptr, TREE_TYPE (fld),
1860 offset - pos, exp_type))
1862 *res = expr;
1863 return true;
1866 return false;
1868 case ARRAY_TYPE:
1869 tr_size = TYPE_SIZE (TREE_TYPE (type));
1870 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1871 return false;
1872 el_size = tree_to_uhwi (tr_size);
1874 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1875 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
1876 return false;
1877 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1878 if (!integer_zerop (minidx))
1879 index = int_const_binop (PLUS_EXPR, index, minidx);
1880 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1881 NULL_TREE, NULL_TREE);
1882 offset = offset % el_size;
1883 type = TREE_TYPE (type);
1884 break;
1886 default:
1887 if (offset != 0)
1888 return false;
1890 if (exp_type)
1891 return false;
1892 else
1893 return true;
1898 /* Return true iff TYPE is stdarg va_list type. */
1900 static inline bool
1901 is_va_list_type (tree type)
1903 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1906 /* Print message to dump file why a variable was rejected. */
1908 static void
1909 reject (tree var, const char *msg)
1911 if (dump_file && (dump_flags & TDF_DETAILS))
1913 fprintf (dump_file, "Rejected (%d): %s: ", DECL_UID (var), msg);
1914 print_generic_expr (dump_file, var);
1915 fprintf (dump_file, "\n");
1919 /* Return true if VAR is a candidate for SRA. */
1921 static bool
1922 maybe_add_sra_candidate (tree var)
1924 tree type = TREE_TYPE (var);
1925 const char *msg;
1926 tree_node **slot;
1928 if (!AGGREGATE_TYPE_P (type))
1930 reject (var, "not aggregate");
1931 return false;
1933 /* Allow constant-pool entries (that "need to live in memory")
1934 unless we are doing IPA SRA. */
1935 if (needs_to_live_in_memory (var)
1936 && (sra_mode == SRA_MODE_EARLY_IPA || !constant_decl_p (var)))
1938 reject (var, "needs to live in memory");
1939 return false;
1941 if (TREE_THIS_VOLATILE (var))
1943 reject (var, "is volatile");
1944 return false;
1946 if (!COMPLETE_TYPE_P (type))
1948 reject (var, "has incomplete type");
1949 return false;
1951 if (!tree_fits_uhwi_p (TYPE_SIZE (type)))
1953 reject (var, "type size not fixed");
1954 return false;
1956 if (tree_to_uhwi (TYPE_SIZE (type)) == 0)
1958 reject (var, "type size is zero");
1959 return false;
1961 if (type_internals_preclude_sra_p (type, &msg))
1963 reject (var, msg);
1964 return false;
1966 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1967 we also want to schedule it rather late. Thus we ignore it in
1968 the early pass. */
1969 (sra_mode == SRA_MODE_EARLY_INTRA
1970 && is_va_list_type (type)))
1972 reject (var, "is va_list");
1973 return false;
1976 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
1977 slot = candidates->find_slot_with_hash (var, DECL_UID (var), INSERT);
1978 *slot = var;
1980 if (dump_file && (dump_flags & TDF_DETAILS))
1982 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
1983 print_generic_expr (dump_file, var);
1984 fprintf (dump_file, "\n");
1987 return true;
1990 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1991 those with type which is suitable for scalarization. */
1993 static bool
1994 find_var_candidates (void)
1996 tree var, parm;
1997 unsigned int i;
1998 bool ret = false;
2000 for (parm = DECL_ARGUMENTS (current_function_decl);
2001 parm;
2002 parm = DECL_CHAIN (parm))
2003 ret |= maybe_add_sra_candidate (parm);
2005 FOR_EACH_LOCAL_DECL (cfun, i, var)
2007 if (!VAR_P (var))
2008 continue;
2010 ret |= maybe_add_sra_candidate (var);
2013 return ret;
2016 /* Sort all accesses for the given variable, check for partial overlaps and
2017 return NULL if there are any. If there are none, pick a representative for
2018 each combination of offset and size and create a linked list out of them.
2019 Return the pointer to the first representative and make sure it is the first
2020 one in the vector of accesses. */
2022 static struct access *
2023 sort_and_splice_var_accesses (tree var)
2025 int i, j, access_count;
2026 struct access *res, **prev_acc_ptr = &res;
2027 vec<access_p> *access_vec;
2028 bool first = true;
2029 HOST_WIDE_INT low = -1, high = 0;
2031 access_vec = get_base_access_vector (var);
2032 if (!access_vec)
2033 return NULL;
2034 access_count = access_vec->length ();
2036 /* Sort by <OFFSET, SIZE>. */
2037 access_vec->qsort (compare_access_positions);
2039 i = 0;
2040 while (i < access_count)
2042 struct access *access = (*access_vec)[i];
2043 bool grp_write = access->write;
2044 bool grp_read = !access->write;
2045 bool grp_scalar_write = access->write
2046 && is_gimple_reg_type (access->type);
2047 bool grp_scalar_read = !access->write
2048 && is_gimple_reg_type (access->type);
2049 bool grp_assignment_read = access->grp_assignment_read;
2050 bool grp_assignment_write = access->grp_assignment_write;
2051 bool multiple_scalar_reads = false;
2052 bool total_scalarization = access->grp_total_scalarization;
2053 bool grp_partial_lhs = access->grp_partial_lhs;
2054 bool first_scalar = is_gimple_reg_type (access->type);
2055 bool unscalarizable_region = access->grp_unscalarizable_region;
2057 if (first || access->offset >= high)
2059 first = false;
2060 low = access->offset;
2061 high = access->offset + access->size;
2063 else if (access->offset > low && access->offset + access->size > high)
2064 return NULL;
2065 else
2066 gcc_assert (access->offset >= low
2067 && access->offset + access->size <= high);
2069 j = i + 1;
2070 while (j < access_count)
2072 struct access *ac2 = (*access_vec)[j];
2073 if (ac2->offset != access->offset || ac2->size != access->size)
2074 break;
2075 if (ac2->write)
2077 grp_write = true;
2078 grp_scalar_write = (grp_scalar_write
2079 || is_gimple_reg_type (ac2->type));
2081 else
2083 grp_read = true;
2084 if (is_gimple_reg_type (ac2->type))
2086 if (grp_scalar_read)
2087 multiple_scalar_reads = true;
2088 else
2089 grp_scalar_read = true;
2092 grp_assignment_read |= ac2->grp_assignment_read;
2093 grp_assignment_write |= ac2->grp_assignment_write;
2094 grp_partial_lhs |= ac2->grp_partial_lhs;
2095 unscalarizable_region |= ac2->grp_unscalarizable_region;
2096 total_scalarization |= ac2->grp_total_scalarization;
2097 relink_to_new_repr (access, ac2);
2099 /* If there are both aggregate-type and scalar-type accesses with
2100 this combination of size and offset, the comparison function
2101 should have put the scalars first. */
2102 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
2103 ac2->group_representative = access;
2104 j++;
2107 i = j;
2109 access->group_representative = access;
2110 access->grp_write = grp_write;
2111 access->grp_read = grp_read;
2112 access->grp_scalar_read = grp_scalar_read;
2113 access->grp_scalar_write = grp_scalar_write;
2114 access->grp_assignment_read = grp_assignment_read;
2115 access->grp_assignment_write = grp_assignment_write;
2116 access->grp_hint = total_scalarization
2117 || (multiple_scalar_reads && !constant_decl_p (var));
2118 access->grp_total_scalarization = total_scalarization;
2119 access->grp_partial_lhs = grp_partial_lhs;
2120 access->grp_unscalarizable_region = unscalarizable_region;
2121 add_access_to_work_queue (access);
2123 *prev_acc_ptr = access;
2124 prev_acc_ptr = &access->next_grp;
2127 gcc_assert (res == (*access_vec)[0]);
2128 return res;
2131 /* Create a variable for the given ACCESS which determines the type, name and a
2132 few other properties. Return the variable declaration and store it also to
2133 ACCESS->replacement. */
2135 static tree
2136 create_access_replacement (struct access *access)
2138 tree repl;
2140 if (access->grp_to_be_debug_replaced)
2142 repl = create_tmp_var_raw (access->type);
2143 DECL_CONTEXT (repl) = current_function_decl;
2145 else
2146 /* Drop any special alignment on the type if it's not on the main
2147 variant. This avoids issues with weirdo ABIs like AAPCS. */
2148 repl = create_tmp_var (build_qualified_type
2149 (TYPE_MAIN_VARIANT (access->type),
2150 TYPE_QUALS (access->type)), "SR");
2151 if (TREE_CODE (access->type) == COMPLEX_TYPE
2152 || TREE_CODE (access->type) == VECTOR_TYPE)
2154 if (!access->grp_partial_lhs)
2155 DECL_GIMPLE_REG_P (repl) = 1;
2157 else if (access->grp_partial_lhs
2158 && is_gimple_reg_type (access->type))
2159 TREE_ADDRESSABLE (repl) = 1;
2161 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
2162 DECL_ARTIFICIAL (repl) = 1;
2163 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
2165 if (DECL_NAME (access->base)
2166 && !DECL_IGNORED_P (access->base)
2167 && !DECL_ARTIFICIAL (access->base))
2169 char *pretty_name = make_fancy_name (access->expr);
2170 tree debug_expr = unshare_expr_without_location (access->expr), d;
2171 bool fail = false;
2173 DECL_NAME (repl) = get_identifier (pretty_name);
2174 DECL_NAMELESS (repl) = 1;
2175 obstack_free (&name_obstack, pretty_name);
2177 /* Get rid of any SSA_NAMEs embedded in debug_expr,
2178 as DECL_DEBUG_EXPR isn't considered when looking for still
2179 used SSA_NAMEs and thus they could be freed. All debug info
2180 generation cares is whether something is constant or variable
2181 and that get_ref_base_and_extent works properly on the
2182 expression. It cannot handle accesses at a non-constant offset
2183 though, so just give up in those cases. */
2184 for (d = debug_expr;
2185 !fail && (handled_component_p (d) || TREE_CODE (d) == MEM_REF);
2186 d = TREE_OPERAND (d, 0))
2187 switch (TREE_CODE (d))
2189 case ARRAY_REF:
2190 case ARRAY_RANGE_REF:
2191 if (TREE_OPERAND (d, 1)
2192 && TREE_CODE (TREE_OPERAND (d, 1)) != INTEGER_CST)
2193 fail = true;
2194 if (TREE_OPERAND (d, 3)
2195 && TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST)
2196 fail = true;
2197 /* FALLTHRU */
2198 case COMPONENT_REF:
2199 if (TREE_OPERAND (d, 2)
2200 && TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST)
2201 fail = true;
2202 break;
2203 case MEM_REF:
2204 if (TREE_CODE (TREE_OPERAND (d, 0)) != ADDR_EXPR)
2205 fail = true;
2206 else
2207 d = TREE_OPERAND (d, 0);
2208 break;
2209 default:
2210 break;
2212 if (!fail)
2214 SET_DECL_DEBUG_EXPR (repl, debug_expr);
2215 DECL_HAS_DEBUG_EXPR_P (repl) = 1;
2217 if (access->grp_no_warning)
2218 TREE_NO_WARNING (repl) = 1;
2219 else
2220 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
2222 else
2223 TREE_NO_WARNING (repl) = 1;
2225 if (dump_file)
2227 if (access->grp_to_be_debug_replaced)
2229 fprintf (dump_file, "Created a debug-only replacement for ");
2230 print_generic_expr (dump_file, access->base);
2231 fprintf (dump_file, " offset: %u, size: %u\n",
2232 (unsigned) access->offset, (unsigned) access->size);
2234 else
2236 fprintf (dump_file, "Created a replacement for ");
2237 print_generic_expr (dump_file, access->base);
2238 fprintf (dump_file, " offset: %u, size: %u: ",
2239 (unsigned) access->offset, (unsigned) access->size);
2240 print_generic_expr (dump_file, repl);
2241 fprintf (dump_file, "\n");
2244 sra_stats.replacements++;
2246 return repl;
2249 /* Return ACCESS scalar replacement, which must exist. */
2251 static inline tree
2252 get_access_replacement (struct access *access)
2254 gcc_checking_assert (access->replacement_decl);
2255 return access->replacement_decl;
2259 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2260 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2261 to it is not "within" the root. Return false iff some accesses partially
2262 overlap. */
2264 static bool
2265 build_access_subtree (struct access **access)
2267 struct access *root = *access, *last_child = NULL;
2268 HOST_WIDE_INT limit = root->offset + root->size;
2270 *access = (*access)->next_grp;
2271 while (*access && (*access)->offset + (*access)->size <= limit)
2273 if (!last_child)
2274 root->first_child = *access;
2275 else
2276 last_child->next_sibling = *access;
2277 last_child = *access;
2278 (*access)->parent = root;
2279 (*access)->grp_write |= root->grp_write;
2281 if (!build_access_subtree (access))
2282 return false;
2285 if (*access && (*access)->offset < limit)
2286 return false;
2288 return true;
2291 /* Build a tree of access representatives, ACCESS is the pointer to the first
2292 one, others are linked in a list by the next_grp field. Return false iff
2293 some accesses partially overlap. */
2295 static bool
2296 build_access_trees (struct access *access)
2298 while (access)
2300 struct access *root = access;
2302 if (!build_access_subtree (&access))
2303 return false;
2304 root->next_grp = access;
2306 return true;
2309 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2310 array. */
2312 static bool
2313 expr_with_var_bounded_array_refs_p (tree expr)
2315 while (handled_component_p (expr))
2317 if (TREE_CODE (expr) == ARRAY_REF
2318 && !tree_fits_shwi_p (array_ref_low_bound (expr)))
2319 return true;
2320 expr = TREE_OPERAND (expr, 0);
2322 return false;
2325 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2326 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2327 sorts of access flags appropriately along the way, notably always set
2328 grp_read and grp_assign_read according to MARK_READ and grp_write when
2329 MARK_WRITE is true.
2331 Creating a replacement for a scalar access is considered beneficial if its
2332 grp_hint is set (this means we are either attempting total scalarization or
2333 there is more than one direct read access) or according to the following
2334 table:
2336 Access written to through a scalar type (once or more times)
2338 | Written to in an assignment statement
2340 | | Access read as scalar _once_
2341 | | |
2342 | | | Read in an assignment statement
2343 | | | |
2344 | | | | Scalarize Comment
2345 -----------------------------------------------------------------------------
2346 0 0 0 0 No access for the scalar
2347 0 0 0 1 No access for the scalar
2348 0 0 1 0 No Single read - won't help
2349 0 0 1 1 No The same case
2350 0 1 0 0 No access for the scalar
2351 0 1 0 1 No access for the scalar
2352 0 1 1 0 Yes s = *g; return s.i;
2353 0 1 1 1 Yes The same case as above
2354 1 0 0 0 No Won't help
2355 1 0 0 1 Yes s.i = 1; *g = s;
2356 1 0 1 0 Yes s.i = 5; g = s.i;
2357 1 0 1 1 Yes The same case as above
2358 1 1 0 0 No Won't help.
2359 1 1 0 1 Yes s.i = 1; *g = s;
2360 1 1 1 0 Yes s = *g; return s.i;
2361 1 1 1 1 Yes Any of the above yeses */
2363 static bool
2364 analyze_access_subtree (struct access *root, struct access *parent,
2365 bool allow_replacements)
2367 struct access *child;
2368 HOST_WIDE_INT limit = root->offset + root->size;
2369 HOST_WIDE_INT covered_to = root->offset;
2370 bool scalar = is_gimple_reg_type (root->type);
2371 bool hole = false, sth_created = false;
2373 if (parent)
2375 if (parent->grp_read)
2376 root->grp_read = 1;
2377 if (parent->grp_assignment_read)
2378 root->grp_assignment_read = 1;
2379 if (parent->grp_write)
2380 root->grp_write = 1;
2381 if (parent->grp_assignment_write)
2382 root->grp_assignment_write = 1;
2383 if (parent->grp_total_scalarization)
2384 root->grp_total_scalarization = 1;
2387 if (root->grp_unscalarizable_region)
2388 allow_replacements = false;
2390 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
2391 allow_replacements = false;
2393 for (child = root->first_child; child; child = child->next_sibling)
2395 hole |= covered_to < child->offset;
2396 sth_created |= analyze_access_subtree (child, root,
2397 allow_replacements && !scalar);
2399 root->grp_unscalarized_data |= child->grp_unscalarized_data;
2400 root->grp_total_scalarization &= child->grp_total_scalarization;
2401 if (child->grp_covered)
2402 covered_to += child->size;
2403 else
2404 hole = true;
2407 if (allow_replacements && scalar && !root->first_child
2408 && (root->grp_hint
2409 || ((root->grp_scalar_read || root->grp_assignment_read)
2410 && (root->grp_scalar_write || root->grp_assignment_write))))
2412 /* Always create access replacements that cover the whole access.
2413 For integral types this means the precision has to match.
2414 Avoid assumptions based on the integral type kind, too. */
2415 if (INTEGRAL_TYPE_P (root->type)
2416 && (TREE_CODE (root->type) != INTEGER_TYPE
2417 || TYPE_PRECISION (root->type) != root->size)
2418 /* But leave bitfield accesses alone. */
2419 && (TREE_CODE (root->expr) != COMPONENT_REF
2420 || !DECL_BIT_FIELD (TREE_OPERAND (root->expr, 1))))
2422 tree rt = root->type;
2423 gcc_assert ((root->offset % BITS_PER_UNIT) == 0
2424 && (root->size % BITS_PER_UNIT) == 0);
2425 root->type = build_nonstandard_integer_type (root->size,
2426 TYPE_UNSIGNED (rt));
2427 root->expr = build_ref_for_offset (UNKNOWN_LOCATION, root->base,
2428 root->offset, root->reverse,
2429 root->type, NULL, false);
2431 if (dump_file && (dump_flags & TDF_DETAILS))
2433 fprintf (dump_file, "Changing the type of a replacement for ");
2434 print_generic_expr (dump_file, root->base);
2435 fprintf (dump_file, " offset: %u, size: %u ",
2436 (unsigned) root->offset, (unsigned) root->size);
2437 fprintf (dump_file, " to an integer.\n");
2441 root->grp_to_be_replaced = 1;
2442 root->replacement_decl = create_access_replacement (root);
2443 sth_created = true;
2444 hole = false;
2446 else
2448 if (allow_replacements
2449 && scalar && !root->first_child
2450 && (root->grp_scalar_write || root->grp_assignment_write)
2451 && !bitmap_bit_p (cannot_scalarize_away_bitmap,
2452 DECL_UID (root->base)))
2454 gcc_checking_assert (!root->grp_scalar_read
2455 && !root->grp_assignment_read);
2456 sth_created = true;
2457 if (MAY_HAVE_DEBUG_STMTS)
2459 root->grp_to_be_debug_replaced = 1;
2460 root->replacement_decl = create_access_replacement (root);
2464 if (covered_to < limit)
2465 hole = true;
2466 if (scalar || !allow_replacements)
2467 root->grp_total_scalarization = 0;
2470 if (!hole || root->grp_total_scalarization)
2471 root->grp_covered = 1;
2472 else if (root->grp_write || comes_initialized_p (root->base))
2473 root->grp_unscalarized_data = 1; /* not covered and written to */
2474 return sth_created;
2477 /* Analyze all access trees linked by next_grp by the means of
2478 analyze_access_subtree. */
2479 static bool
2480 analyze_access_trees (struct access *access)
2482 bool ret = false;
2484 while (access)
2486 if (analyze_access_subtree (access, NULL, true))
2487 ret = true;
2488 access = access->next_grp;
2491 return ret;
2494 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2495 SIZE would conflict with an already existing one. If exactly such a child
2496 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2498 static bool
2499 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
2500 HOST_WIDE_INT size, struct access **exact_match)
2502 struct access *child;
2504 for (child = lacc->first_child; child; child = child->next_sibling)
2506 if (child->offset == norm_offset && child->size == size)
2508 *exact_match = child;
2509 return true;
2512 if (child->offset < norm_offset + size
2513 && child->offset + child->size > norm_offset)
2514 return true;
2517 return false;
2520 /* Create a new child access of PARENT, with all properties just like MODEL
2521 except for its offset and with its grp_write false and grp_read true.
2522 Return the new access or NULL if it cannot be created. Note that this
2523 access is created long after all splicing and sorting, it's not located in
2524 any access vector and is automatically a representative of its group. Set
2525 the gpr_write flag of the new accesss if SET_GRP_WRITE is true. */
2527 static struct access *
2528 create_artificial_child_access (struct access *parent, struct access *model,
2529 HOST_WIDE_INT new_offset,
2530 bool set_grp_write)
2532 struct access **child;
2533 tree expr = parent->base;
2535 gcc_assert (!model->grp_unscalarizable_region);
2537 struct access *access = access_pool.allocate ();
2538 memset (access, 0, sizeof (struct access));
2539 if (!build_user_friendly_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
2540 model->type))
2542 access->grp_no_warning = true;
2543 expr = build_ref_for_model (EXPR_LOCATION (parent->base), parent->base,
2544 new_offset, model, NULL, false);
2547 access->base = parent->base;
2548 access->expr = expr;
2549 access->offset = new_offset;
2550 access->size = model->size;
2551 access->type = model->type;
2552 access->grp_write = set_grp_write;
2553 access->grp_read = false;
2554 access->reverse = model->reverse;
2556 child = &parent->first_child;
2557 while (*child && (*child)->offset < new_offset)
2558 child = &(*child)->next_sibling;
2560 access->next_sibling = *child;
2561 *child = access;
2563 return access;
2567 /* Beginning with ACCESS, traverse its whole access subtree and mark all
2568 sub-trees as written to. If any of them has not been marked so previously
2569 and has assignment links leading from it, re-enqueue it. */
2571 static void
2572 subtree_mark_written_and_enqueue (struct access *access)
2574 if (access->grp_write)
2575 return;
2576 access->grp_write = true;
2577 add_access_to_work_queue (access);
2579 struct access *child;
2580 for (child = access->first_child; child; child = child->next_sibling)
2581 subtree_mark_written_and_enqueue (child);
2584 /* Propagate subaccesses and grp_write flags of RACC across an assignment link
2585 to LACC. Enqueue sub-accesses as necessary so that the write flag is
2586 propagated transitively. Return true if anything changed. Additionally, if
2587 RACC is a scalar access but LACC is not, change the type of the latter, if
2588 possible. */
2590 static bool
2591 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
2593 struct access *rchild;
2594 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
2595 bool ret = false;
2597 /* IF the LHS is still not marked as being written to, we only need to do so
2598 if the RHS at this level actually was. */
2599 if (!lacc->grp_write)
2601 gcc_checking_assert (!comes_initialized_p (racc->base));
2602 if (racc->grp_write)
2604 subtree_mark_written_and_enqueue (lacc);
2605 ret = true;
2609 if (is_gimple_reg_type (lacc->type)
2610 || lacc->grp_unscalarizable_region
2611 || racc->grp_unscalarizable_region)
2613 if (!lacc->grp_write)
2615 ret = true;
2616 subtree_mark_written_and_enqueue (lacc);
2618 return ret;
2621 if (is_gimple_reg_type (racc->type))
2623 if (!lacc->grp_write)
2625 ret = true;
2626 subtree_mark_written_and_enqueue (lacc);
2628 if (!lacc->first_child && !racc->first_child)
2630 tree t = lacc->base;
2632 lacc->type = racc->type;
2633 if (build_user_friendly_ref_for_offset (&t, TREE_TYPE (t),
2634 lacc->offset, racc->type))
2635 lacc->expr = t;
2636 else
2638 lacc->expr = build_ref_for_model (EXPR_LOCATION (lacc->base),
2639 lacc->base, lacc->offset,
2640 racc, NULL, false);
2641 lacc->grp_no_warning = true;
2644 return ret;
2647 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
2649 struct access *new_acc = NULL;
2650 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
2652 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
2653 &new_acc))
2655 if (new_acc)
2657 if (!new_acc->grp_write && rchild->grp_write)
2659 gcc_assert (!lacc->grp_write);
2660 subtree_mark_written_and_enqueue (new_acc);
2661 ret = true;
2664 rchild->grp_hint = 1;
2665 new_acc->grp_hint |= new_acc->grp_read;
2666 if (rchild->first_child)
2667 ret |= propagate_subaccesses_across_link (new_acc, rchild);
2669 else
2671 if (rchild->grp_write && !lacc->grp_write)
2673 ret = true;
2674 subtree_mark_written_and_enqueue (lacc);
2677 continue;
2680 if (rchild->grp_unscalarizable_region)
2682 if (rchild->grp_write && !lacc->grp_write)
2684 ret = true;
2685 subtree_mark_written_and_enqueue (lacc);
2687 continue;
2690 rchild->grp_hint = 1;
2691 new_acc = create_artificial_child_access (lacc, rchild, norm_offset,
2692 lacc->grp_write
2693 || rchild->grp_write);
2694 gcc_checking_assert (new_acc);
2695 if (racc->first_child)
2696 propagate_subaccesses_across_link (new_acc, rchild);
2698 add_access_to_work_queue (lacc);
2699 ret = true;
2702 return ret;
2705 /* Propagate all subaccesses across assignment links. */
2707 static void
2708 propagate_all_subaccesses (void)
2710 while (work_queue_head)
2712 struct access *racc = pop_access_from_work_queue ();
2713 struct assign_link *link;
2715 gcc_assert (racc->first_link);
2717 for (link = racc->first_link; link; link = link->next)
2719 struct access *lacc = link->lacc;
2721 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
2722 continue;
2723 lacc = lacc->group_representative;
2725 bool reque_parents = false;
2726 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (racc->base)))
2728 if (!lacc->grp_write)
2730 subtree_mark_written_and_enqueue (lacc);
2731 reque_parents = true;
2734 else if (propagate_subaccesses_across_link (lacc, racc))
2735 reque_parents = true;
2737 if (reque_parents)
2740 add_access_to_work_queue (lacc);
2741 lacc = lacc->parent;
2743 while (lacc);
2748 /* Go through all accesses collected throughout the (intraprocedural) analysis
2749 stage, exclude overlapping ones, identify representatives and build trees
2750 out of them, making decisions about scalarization on the way. Return true
2751 iff there are any to-be-scalarized variables after this stage. */
2753 static bool
2754 analyze_all_variable_accesses (void)
2756 int res = 0;
2757 bitmap tmp = BITMAP_ALLOC (NULL);
2758 bitmap_iterator bi;
2759 unsigned i;
2760 bool optimize_speed_p = !optimize_function_for_size_p (cfun);
2762 enum compiler_param param = optimize_speed_p
2763 ? PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED
2764 : PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE;
2766 /* If the user didn't set PARAM_SRA_MAX_SCALARIZATION_SIZE_<...>,
2767 fall back to a target default. */
2768 unsigned HOST_WIDE_INT max_scalarization_size
2769 = global_options_set.x_param_values[param]
2770 ? PARAM_VALUE (param)
2771 : get_move_ratio (optimize_speed_p) * UNITS_PER_WORD;
2773 max_scalarization_size *= BITS_PER_UNIT;
2775 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
2776 if (bitmap_bit_p (should_scalarize_away_bitmap, i)
2777 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
2779 tree var = candidate (i);
2781 if (VAR_P (var) && scalarizable_type_p (TREE_TYPE (var),
2782 constant_decl_p (var)))
2784 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var)))
2785 <= max_scalarization_size)
2787 create_total_scalarization_access (var);
2788 completely_scalarize (var, TREE_TYPE (var), 0, var);
2789 statistics_counter_event (cfun,
2790 "Totally-scalarized aggregates", 1);
2791 if (dump_file && (dump_flags & TDF_DETAILS))
2793 fprintf (dump_file, "Will attempt to totally scalarize ");
2794 print_generic_expr (dump_file, var);
2795 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2798 else if (dump_file && (dump_flags & TDF_DETAILS))
2800 fprintf (dump_file, "Too big to totally scalarize: ");
2801 print_generic_expr (dump_file, var);
2802 fprintf (dump_file, " (UID: %u)\n", DECL_UID (var));
2807 bitmap_copy (tmp, candidate_bitmap);
2808 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2810 tree var = candidate (i);
2811 struct access *access;
2813 access = sort_and_splice_var_accesses (var);
2814 if (!access || !build_access_trees (access))
2815 disqualify_candidate (var,
2816 "No or inhibitingly overlapping accesses.");
2819 propagate_all_subaccesses ();
2821 bitmap_copy (tmp, candidate_bitmap);
2822 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2824 tree var = candidate (i);
2825 struct access *access = get_first_repr_for_decl (var);
2827 if (analyze_access_trees (access))
2829 res++;
2830 if (dump_file && (dump_flags & TDF_DETAILS))
2832 fprintf (dump_file, "\nAccess trees for ");
2833 print_generic_expr (dump_file, var);
2834 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2835 dump_access_tree (dump_file, access);
2836 fprintf (dump_file, "\n");
2839 else
2840 disqualify_candidate (var, "No scalar replacements to be created.");
2843 BITMAP_FREE (tmp);
2845 if (res)
2847 statistics_counter_event (cfun, "Scalarized aggregates", res);
2848 return true;
2850 else
2851 return false;
2854 /* Generate statements copying scalar replacements of accesses within a subtree
2855 into or out of AGG. ACCESS, all its children, siblings and their children
2856 are to be processed. AGG is an aggregate type expression (can be a
2857 declaration but does not have to be, it can for example also be a mem_ref or
2858 a series of handled components). TOP_OFFSET is the offset of the processed
2859 subtree which has to be subtracted from offsets of individual accesses to
2860 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2861 replacements in the interval <start_offset, start_offset + chunk_size>,
2862 otherwise copy all. GSI is a statement iterator used to place the new
2863 statements. WRITE should be true when the statements should write from AGG
2864 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2865 statements will be added after the current statement in GSI, they will be
2866 added before the statement otherwise. */
2868 static void
2869 generate_subtree_copies (struct access *access, tree agg,
2870 HOST_WIDE_INT top_offset,
2871 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
2872 gimple_stmt_iterator *gsi, bool write,
2873 bool insert_after, location_t loc)
2875 /* Never write anything into constant pool decls. See PR70602. */
2876 if (!write && constant_decl_p (agg))
2877 return;
2880 if (chunk_size && access->offset >= start_offset + chunk_size)
2881 return;
2883 if (access->grp_to_be_replaced
2884 && (chunk_size == 0
2885 || access->offset + access->size > start_offset))
2887 tree expr, repl = get_access_replacement (access);
2888 gassign *stmt;
2890 expr = build_ref_for_model (loc, agg, access->offset - top_offset,
2891 access, gsi, insert_after);
2893 if (write)
2895 if (access->grp_partial_lhs)
2896 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
2897 !insert_after,
2898 insert_after ? GSI_NEW_STMT
2899 : GSI_SAME_STMT);
2900 stmt = gimple_build_assign (repl, expr);
2902 else
2904 TREE_NO_WARNING (repl) = 1;
2905 if (access->grp_partial_lhs)
2906 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2907 !insert_after,
2908 insert_after ? GSI_NEW_STMT
2909 : GSI_SAME_STMT);
2910 stmt = gimple_build_assign (expr, repl);
2912 gimple_set_location (stmt, loc);
2914 if (insert_after)
2915 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2916 else
2917 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2918 update_stmt (stmt);
2919 sra_stats.subtree_copies++;
2921 else if (write
2922 && access->grp_to_be_debug_replaced
2923 && (chunk_size == 0
2924 || access->offset + access->size > start_offset))
2926 gdebug *ds;
2927 tree drhs = build_debug_ref_for_model (loc, agg,
2928 access->offset - top_offset,
2929 access);
2930 ds = gimple_build_debug_bind (get_access_replacement (access),
2931 drhs, gsi_stmt (*gsi));
2932 if (insert_after)
2933 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2934 else
2935 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2938 if (access->first_child)
2939 generate_subtree_copies (access->first_child, agg, top_offset,
2940 start_offset, chunk_size, gsi,
2941 write, insert_after, loc);
2943 access = access->next_sibling;
2945 while (access);
2948 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2949 root of the subtree to be processed. GSI is the statement iterator used
2950 for inserting statements which are added after the current statement if
2951 INSERT_AFTER is true or before it otherwise. */
2953 static void
2954 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
2955 bool insert_after, location_t loc)
2958 struct access *child;
2960 if (access->grp_to_be_replaced)
2962 gassign *stmt;
2964 stmt = gimple_build_assign (get_access_replacement (access),
2965 build_zero_cst (access->type));
2966 if (insert_after)
2967 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2968 else
2969 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2970 update_stmt (stmt);
2971 gimple_set_location (stmt, loc);
2973 else if (access->grp_to_be_debug_replaced)
2975 gdebug *ds
2976 = gimple_build_debug_bind (get_access_replacement (access),
2977 build_zero_cst (access->type),
2978 gsi_stmt (*gsi));
2979 if (insert_after)
2980 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2981 else
2982 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2985 for (child = access->first_child; child; child = child->next_sibling)
2986 init_subtree_with_zero (child, gsi, insert_after, loc);
2989 /* Clobber all scalar replacements in an access subtree. ACCESS is the
2990 root of the subtree to be processed. GSI is the statement iterator used
2991 for inserting statements which are added after the current statement if
2992 INSERT_AFTER is true or before it otherwise. */
2994 static void
2995 clobber_subtree (struct access *access, gimple_stmt_iterator *gsi,
2996 bool insert_after, location_t loc)
2999 struct access *child;
3001 if (access->grp_to_be_replaced)
3003 tree rep = get_access_replacement (access);
3004 tree clobber = build_constructor (access->type, NULL);
3005 TREE_THIS_VOLATILE (clobber) = 1;
3006 gimple *stmt = gimple_build_assign (rep, clobber);
3008 if (insert_after)
3009 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
3010 else
3011 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
3012 update_stmt (stmt);
3013 gimple_set_location (stmt, loc);
3016 for (child = access->first_child; child; child = child->next_sibling)
3017 clobber_subtree (child, gsi, insert_after, loc);
3020 /* Search for an access representative for the given expression EXPR and
3021 return it or NULL if it cannot be found. */
3023 static struct access *
3024 get_access_for_expr (tree expr)
3026 HOST_WIDE_INT offset, size, max_size;
3027 tree base;
3028 bool reverse;
3030 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
3031 a different size than the size of its argument and we need the latter
3032 one. */
3033 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
3034 expr = TREE_OPERAND (expr, 0);
3036 base = get_ref_base_and_extent (expr, &offset, &size, &max_size, &reverse);
3037 if (max_size == -1 || !DECL_P (base))
3038 return NULL;
3040 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
3041 return NULL;
3043 return get_var_base_offset_size_access (base, offset, max_size);
3046 /* Replace the expression EXPR with a scalar replacement if there is one and
3047 generate other statements to do type conversion or subtree copying if
3048 necessary. GSI is used to place newly created statements, WRITE is true if
3049 the expression is being written to (it is on a LHS of a statement or output
3050 in an assembly statement). */
3052 static bool
3053 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
3055 location_t loc;
3056 struct access *access;
3057 tree type, bfr, orig_expr;
3059 if (TREE_CODE (*expr) == BIT_FIELD_REF)
3061 bfr = *expr;
3062 expr = &TREE_OPERAND (*expr, 0);
3064 else
3065 bfr = NULL_TREE;
3067 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
3068 expr = &TREE_OPERAND (*expr, 0);
3069 access = get_access_for_expr (*expr);
3070 if (!access)
3071 return false;
3072 type = TREE_TYPE (*expr);
3073 orig_expr = *expr;
3075 loc = gimple_location (gsi_stmt (*gsi));
3076 gimple_stmt_iterator alt_gsi = gsi_none ();
3077 if (write && stmt_ends_bb_p (gsi_stmt (*gsi)))
3079 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
3080 gsi = &alt_gsi;
3083 if (access->grp_to_be_replaced)
3085 tree repl = get_access_replacement (access);
3086 /* If we replace a non-register typed access simply use the original
3087 access expression to extract the scalar component afterwards.
3088 This happens if scalarizing a function return value or parameter
3089 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
3090 gcc.c-torture/compile/20011217-1.c.
3092 We also want to use this when accessing a complex or vector which can
3093 be accessed as a different type too, potentially creating a need for
3094 type conversion (see PR42196) and when scalarized unions are involved
3095 in assembler statements (see PR42398). */
3096 if (!useless_type_conversion_p (type, access->type))
3098 tree ref;
3100 ref = build_ref_for_model (loc, orig_expr, 0, access, gsi, false);
3102 if (write)
3104 gassign *stmt;
3106 if (access->grp_partial_lhs)
3107 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
3108 false, GSI_NEW_STMT);
3109 stmt = gimple_build_assign (repl, ref);
3110 gimple_set_location (stmt, loc);
3111 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
3113 else
3115 gassign *stmt;
3117 if (access->grp_partial_lhs)
3118 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
3119 true, GSI_SAME_STMT);
3120 stmt = gimple_build_assign (ref, repl);
3121 gimple_set_location (stmt, loc);
3122 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
3125 else
3126 *expr = repl;
3127 sra_stats.exprs++;
3129 else if (write && access->grp_to_be_debug_replaced)
3131 gdebug *ds = gimple_build_debug_bind (get_access_replacement (access),
3132 NULL_TREE,
3133 gsi_stmt (*gsi));
3134 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
3137 if (access->first_child)
3139 HOST_WIDE_INT start_offset, chunk_size;
3140 if (bfr
3141 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 1))
3142 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 2)))
3144 chunk_size = tree_to_uhwi (TREE_OPERAND (bfr, 1));
3145 start_offset = access->offset
3146 + tree_to_uhwi (TREE_OPERAND (bfr, 2));
3148 else
3149 start_offset = chunk_size = 0;
3151 generate_subtree_copies (access->first_child, orig_expr, access->offset,
3152 start_offset, chunk_size, gsi, write, write,
3153 loc);
3155 return true;
3158 /* Where scalar replacements of the RHS have been written to when a replacement
3159 of a LHS of an assigments cannot be direclty loaded from a replacement of
3160 the RHS. */
3161 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
3162 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
3163 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
3165 struct subreplacement_assignment_data
3167 /* Offset of the access representing the lhs of the assignment. */
3168 HOST_WIDE_INT left_offset;
3170 /* LHS and RHS of the original assignment. */
3171 tree assignment_lhs, assignment_rhs;
3173 /* Access representing the rhs of the whole assignment. */
3174 struct access *top_racc;
3176 /* Stmt iterator used for statement insertions after the original assignment.
3177 It points to the main GSI used to traverse a BB during function body
3178 modification. */
3179 gimple_stmt_iterator *new_gsi;
3181 /* Stmt iterator used for statement insertions before the original
3182 assignment. Keeps on pointing to the original statement. */
3183 gimple_stmt_iterator old_gsi;
3185 /* Location of the assignment. */
3186 location_t loc;
3188 /* Keeps the information whether we have needed to refresh replacements of
3189 the LHS and from which side of the assignments this takes place. */
3190 enum unscalarized_data_handling refreshed;
3193 /* Store all replacements in the access tree rooted in TOP_RACC either to their
3194 base aggregate if there are unscalarized data or directly to LHS of the
3195 statement that is pointed to by GSI otherwise. */
3197 static void
3198 handle_unscalarized_data_in_subtree (struct subreplacement_assignment_data *sad)
3200 tree src;
3201 if (sad->top_racc->grp_unscalarized_data)
3203 src = sad->assignment_rhs;
3204 sad->refreshed = SRA_UDH_RIGHT;
3206 else
3208 src = sad->assignment_lhs;
3209 sad->refreshed = SRA_UDH_LEFT;
3211 generate_subtree_copies (sad->top_racc->first_child, src,
3212 sad->top_racc->offset, 0, 0,
3213 &sad->old_gsi, false, false, sad->loc);
3216 /* Try to generate statements to load all sub-replacements in an access subtree
3217 formed by children of LACC from scalar replacements in the SAD->top_racc
3218 subtree. If that is not possible, refresh the SAD->top_racc base aggregate
3219 and load the accesses from it. */
3221 static void
3222 load_assign_lhs_subreplacements (struct access *lacc,
3223 struct subreplacement_assignment_data *sad)
3225 for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling)
3227 HOST_WIDE_INT offset;
3228 offset = lacc->offset - sad->left_offset + sad->top_racc->offset;
3230 if (lacc->grp_to_be_replaced)
3232 struct access *racc;
3233 gassign *stmt;
3234 tree rhs;
3236 racc = find_access_in_subtree (sad->top_racc, offset, lacc->size);
3237 if (racc && racc->grp_to_be_replaced)
3239 rhs = get_access_replacement (racc);
3240 if (!useless_type_conversion_p (lacc->type, racc->type))
3241 rhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
3242 lacc->type, rhs);
3244 if (racc->grp_partial_lhs && lacc->grp_partial_lhs)
3245 rhs = force_gimple_operand_gsi (&sad->old_gsi, rhs, true,
3246 NULL_TREE, true, GSI_SAME_STMT);
3248 else
3250 /* No suitable access on the right hand side, need to load from
3251 the aggregate. See if we have to update it first... */
3252 if (sad->refreshed == SRA_UDH_NONE)
3253 handle_unscalarized_data_in_subtree (sad);
3255 if (sad->refreshed == SRA_UDH_LEFT)
3256 rhs = build_ref_for_model (sad->loc, sad->assignment_lhs,
3257 lacc->offset - sad->left_offset,
3258 lacc, sad->new_gsi, true);
3259 else
3260 rhs = build_ref_for_model (sad->loc, sad->assignment_rhs,
3261 lacc->offset - sad->left_offset,
3262 lacc, sad->new_gsi, true);
3263 if (lacc->grp_partial_lhs)
3264 rhs = force_gimple_operand_gsi (sad->new_gsi,
3265 rhs, true, NULL_TREE,
3266 false, GSI_NEW_STMT);
3269 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
3270 gsi_insert_after (sad->new_gsi, stmt, GSI_NEW_STMT);
3271 gimple_set_location (stmt, sad->loc);
3272 update_stmt (stmt);
3273 sra_stats.subreplacements++;
3275 else
3277 if (sad->refreshed == SRA_UDH_NONE
3278 && lacc->grp_read && !lacc->grp_covered)
3279 handle_unscalarized_data_in_subtree (sad);
3281 if (lacc && lacc->grp_to_be_debug_replaced)
3283 gdebug *ds;
3284 tree drhs;
3285 struct access *racc = find_access_in_subtree (sad->top_racc,
3286 offset,
3287 lacc->size);
3289 if (racc && racc->grp_to_be_replaced)
3291 if (racc->grp_write || constant_decl_p (racc->base))
3292 drhs = get_access_replacement (racc);
3293 else
3294 drhs = NULL;
3296 else if (sad->refreshed == SRA_UDH_LEFT)
3297 drhs = build_debug_ref_for_model (sad->loc, lacc->base,
3298 lacc->offset, lacc);
3299 else if (sad->refreshed == SRA_UDH_RIGHT)
3300 drhs = build_debug_ref_for_model (sad->loc, sad->top_racc->base,
3301 offset, lacc);
3302 else
3303 drhs = NULL_TREE;
3304 if (drhs
3305 && !useless_type_conversion_p (lacc->type, TREE_TYPE (drhs)))
3306 drhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
3307 lacc->type, drhs);
3308 ds = gimple_build_debug_bind (get_access_replacement (lacc),
3309 drhs, gsi_stmt (sad->old_gsi));
3310 gsi_insert_after (sad->new_gsi, ds, GSI_NEW_STMT);
3314 if (lacc->first_child)
3315 load_assign_lhs_subreplacements (lacc, sad);
3319 /* Result code for SRA assignment modification. */
3320 enum assignment_mod_result { SRA_AM_NONE, /* nothing done for the stmt */
3321 SRA_AM_MODIFIED, /* stmt changed but not
3322 removed */
3323 SRA_AM_REMOVED }; /* stmt eliminated */
3325 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
3326 to the assignment and GSI is the statement iterator pointing at it. Returns
3327 the same values as sra_modify_assign. */
3329 static enum assignment_mod_result
3330 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3332 tree lhs = gimple_assign_lhs (stmt);
3333 struct access *acc = get_access_for_expr (lhs);
3334 if (!acc)
3335 return SRA_AM_NONE;
3336 location_t loc = gimple_location (stmt);
3338 if (gimple_clobber_p (stmt))
3340 /* Clobber the replacement variable. */
3341 clobber_subtree (acc, gsi, !acc->grp_covered, loc);
3342 /* Remove clobbers of fully scalarized variables, they are dead. */
3343 if (acc->grp_covered)
3345 unlink_stmt_vdef (stmt);
3346 gsi_remove (gsi, true);
3347 release_defs (stmt);
3348 return SRA_AM_REMOVED;
3350 else
3351 return SRA_AM_MODIFIED;
3354 if (CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt)) > 0)
3356 /* I have never seen this code path trigger but if it can happen the
3357 following should handle it gracefully. */
3358 if (access_has_children_p (acc))
3359 generate_subtree_copies (acc->first_child, lhs, acc->offset, 0, 0, gsi,
3360 true, true, loc);
3361 return SRA_AM_MODIFIED;
3364 if (acc->grp_covered)
3366 init_subtree_with_zero (acc, gsi, false, loc);
3367 unlink_stmt_vdef (stmt);
3368 gsi_remove (gsi, true);
3369 release_defs (stmt);
3370 return SRA_AM_REMOVED;
3372 else
3374 init_subtree_with_zero (acc, gsi, true, loc);
3375 return SRA_AM_MODIFIED;
3379 /* Create and return a new suitable default definition SSA_NAME for RACC which
3380 is an access describing an uninitialized part of an aggregate that is being
3381 loaded. */
3383 static tree
3384 get_repl_default_def_ssa_name (struct access *racc)
3386 gcc_checking_assert (!racc->grp_to_be_replaced
3387 && !racc->grp_to_be_debug_replaced);
3388 if (!racc->replacement_decl)
3389 racc->replacement_decl = create_access_replacement (racc);
3390 return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
3393 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3394 bit-field field declaration somewhere in it. */
3396 static inline bool
3397 contains_vce_or_bfcref_p (const_tree ref)
3399 while (handled_component_p (ref))
3401 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
3402 || (TREE_CODE (ref) == COMPONENT_REF
3403 && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
3404 return true;
3405 ref = TREE_OPERAND (ref, 0);
3408 return false;
3411 /* Examine both sides of the assignment statement pointed to by STMT, replace
3412 them with a scalare replacement if there is one and generate copying of
3413 replacements if scalarized aggregates have been used in the assignment. GSI
3414 is used to hold generated statements for type conversions and subtree
3415 copying. */
3417 static enum assignment_mod_result
3418 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3420 struct access *lacc, *racc;
3421 tree lhs, rhs;
3422 bool modify_this_stmt = false;
3423 bool force_gimple_rhs = false;
3424 location_t loc;
3425 gimple_stmt_iterator orig_gsi = *gsi;
3427 if (!gimple_assign_single_p (stmt))
3428 return SRA_AM_NONE;
3429 lhs = gimple_assign_lhs (stmt);
3430 rhs = gimple_assign_rhs1 (stmt);
3432 if (TREE_CODE (rhs) == CONSTRUCTOR)
3433 return sra_modify_constructor_assign (stmt, gsi);
3435 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
3436 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
3437 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
3439 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (stmt),
3440 gsi, false);
3441 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (stmt),
3442 gsi, true);
3443 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3446 lacc = get_access_for_expr (lhs);
3447 racc = get_access_for_expr (rhs);
3448 if (!lacc && !racc)
3449 return SRA_AM_NONE;
3450 /* Avoid modifying initializations of constant-pool replacements. */
3451 if (racc && (racc->replacement_decl == lhs))
3452 return SRA_AM_NONE;
3454 loc = gimple_location (stmt);
3455 if (lacc && lacc->grp_to_be_replaced)
3457 lhs = get_access_replacement (lacc);
3458 gimple_assign_set_lhs (stmt, lhs);
3459 modify_this_stmt = true;
3460 if (lacc->grp_partial_lhs)
3461 force_gimple_rhs = true;
3462 sra_stats.exprs++;
3465 if (racc && racc->grp_to_be_replaced)
3467 rhs = get_access_replacement (racc);
3468 modify_this_stmt = true;
3469 if (racc->grp_partial_lhs)
3470 force_gimple_rhs = true;
3471 sra_stats.exprs++;
3473 else if (racc
3474 && !racc->grp_unscalarized_data
3475 && !racc->grp_unscalarizable_region
3476 && TREE_CODE (lhs) == SSA_NAME
3477 && !access_has_replacements_p (racc))
3479 rhs = get_repl_default_def_ssa_name (racc);
3480 modify_this_stmt = true;
3481 sra_stats.exprs++;
3484 if (modify_this_stmt)
3486 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3488 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3489 ??? This should move to fold_stmt which we simply should
3490 call after building a VIEW_CONVERT_EXPR here. */
3491 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
3492 && !contains_bitfld_component_ref_p (lhs))
3494 lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
3495 gimple_assign_set_lhs (stmt, lhs);
3497 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
3498 && !contains_vce_or_bfcref_p (rhs))
3499 rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
3501 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3503 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
3504 rhs);
3505 if (is_gimple_reg_type (TREE_TYPE (lhs))
3506 && TREE_CODE (lhs) != SSA_NAME)
3507 force_gimple_rhs = true;
3512 if (lacc && lacc->grp_to_be_debug_replaced)
3514 tree dlhs = get_access_replacement (lacc);
3515 tree drhs = unshare_expr (rhs);
3516 if (!useless_type_conversion_p (TREE_TYPE (dlhs), TREE_TYPE (drhs)))
3518 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs))
3519 && !contains_vce_or_bfcref_p (drhs))
3520 drhs = build_debug_ref_for_model (loc, drhs, 0, lacc);
3521 if (drhs
3522 && !useless_type_conversion_p (TREE_TYPE (dlhs),
3523 TREE_TYPE (drhs)))
3524 drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
3525 TREE_TYPE (dlhs), drhs);
3527 gdebug *ds = gimple_build_debug_bind (dlhs, drhs, stmt);
3528 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3531 /* From this point on, the function deals with assignments in between
3532 aggregates when at least one has scalar reductions of some of its
3533 components. There are three possible scenarios: Both the LHS and RHS have
3534 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3536 In the first case, we would like to load the LHS components from RHS
3537 components whenever possible. If that is not possible, we would like to
3538 read it directly from the RHS (after updating it by storing in it its own
3539 components). If there are some necessary unscalarized data in the LHS,
3540 those will be loaded by the original assignment too. If neither of these
3541 cases happen, the original statement can be removed. Most of this is done
3542 by load_assign_lhs_subreplacements.
3544 In the second case, we would like to store all RHS scalarized components
3545 directly into LHS and if they cover the aggregate completely, remove the
3546 statement too. In the third case, we want the LHS components to be loaded
3547 directly from the RHS (DSE will remove the original statement if it
3548 becomes redundant).
3550 This is a bit complex but manageable when types match and when unions do
3551 not cause confusion in a way that we cannot really load a component of LHS
3552 from the RHS or vice versa (the access representing this level can have
3553 subaccesses that are accessible only through a different union field at a
3554 higher level - different from the one used in the examined expression).
3555 Unions are fun.
3557 Therefore, I specially handle a fourth case, happening when there is a
3558 specific type cast or it is impossible to locate a scalarized subaccess on
3559 the other side of the expression. If that happens, I simply "refresh" the
3560 RHS by storing in it is scalarized components leave the original statement
3561 there to do the copying and then load the scalar replacements of the LHS.
3562 This is what the first branch does. */
3564 if (modify_this_stmt
3565 || gimple_has_volatile_ops (stmt)
3566 || contains_vce_or_bfcref_p (rhs)
3567 || contains_vce_or_bfcref_p (lhs)
3568 || stmt_ends_bb_p (stmt))
3570 /* No need to copy into a constant-pool, it comes pre-initialized. */
3571 if (access_has_children_p (racc) && !constant_decl_p (racc->base))
3572 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3573 gsi, false, false, loc);
3574 if (access_has_children_p (lacc))
3576 gimple_stmt_iterator alt_gsi = gsi_none ();
3577 if (stmt_ends_bb_p (stmt))
3579 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
3580 gsi = &alt_gsi;
3582 generate_subtree_copies (lacc->first_child, lhs, lacc->offset, 0, 0,
3583 gsi, true, true, loc);
3585 sra_stats.separate_lhs_rhs_handling++;
3587 /* This gimplification must be done after generate_subtree_copies,
3588 lest we insert the subtree copies in the middle of the gimplified
3589 sequence. */
3590 if (force_gimple_rhs)
3591 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
3592 true, GSI_SAME_STMT);
3593 if (gimple_assign_rhs1 (stmt) != rhs)
3595 modify_this_stmt = true;
3596 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
3597 gcc_assert (stmt == gsi_stmt (orig_gsi));
3600 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3602 else
3604 if (access_has_children_p (lacc)
3605 && access_has_children_p (racc)
3606 /* When an access represents an unscalarizable region, it usually
3607 represents accesses with variable offset and thus must not be used
3608 to generate new memory accesses. */
3609 && !lacc->grp_unscalarizable_region
3610 && !racc->grp_unscalarizable_region)
3612 struct subreplacement_assignment_data sad;
3614 sad.left_offset = lacc->offset;
3615 sad.assignment_lhs = lhs;
3616 sad.assignment_rhs = rhs;
3617 sad.top_racc = racc;
3618 sad.old_gsi = *gsi;
3619 sad.new_gsi = gsi;
3620 sad.loc = gimple_location (stmt);
3621 sad.refreshed = SRA_UDH_NONE;
3623 if (lacc->grp_read && !lacc->grp_covered)
3624 handle_unscalarized_data_in_subtree (&sad);
3626 load_assign_lhs_subreplacements (lacc, &sad);
3627 if (sad.refreshed != SRA_UDH_RIGHT)
3629 gsi_next (gsi);
3630 unlink_stmt_vdef (stmt);
3631 gsi_remove (&sad.old_gsi, true);
3632 release_defs (stmt);
3633 sra_stats.deleted++;
3634 return SRA_AM_REMOVED;
3637 else
3639 if (access_has_children_p (racc)
3640 && !racc->grp_unscalarized_data
3641 && TREE_CODE (lhs) != SSA_NAME)
3643 if (dump_file)
3645 fprintf (dump_file, "Removing load: ");
3646 print_gimple_stmt (dump_file, stmt, 0);
3648 generate_subtree_copies (racc->first_child, lhs,
3649 racc->offset, 0, 0, gsi,
3650 false, false, loc);
3651 gcc_assert (stmt == gsi_stmt (*gsi));
3652 unlink_stmt_vdef (stmt);
3653 gsi_remove (gsi, true);
3654 release_defs (stmt);
3655 sra_stats.deleted++;
3656 return SRA_AM_REMOVED;
3658 /* Restore the aggregate RHS from its components so the
3659 prevailing aggregate copy does the right thing. */
3660 if (access_has_children_p (racc))
3661 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3662 gsi, false, false, loc);
3663 /* Re-load the components of the aggregate copy destination.
3664 But use the RHS aggregate to load from to expose more
3665 optimization opportunities. */
3666 if (access_has_children_p (lacc))
3667 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
3668 0, 0, gsi, true, true, loc);
3671 return SRA_AM_NONE;
3675 /* Set any scalar replacements of values in the constant pool to the initial
3676 value of the constant. (Constant-pool decls like *.LC0 have effectively
3677 been initialized before the program starts, we must do the same for their
3678 replacements.) Thus, we output statements like 'SR.1 = *.LC0[0];' into
3679 the function's entry block. */
3681 static void
3682 initialize_constant_pool_replacements (void)
3684 gimple_seq seq = NULL;
3685 gimple_stmt_iterator gsi = gsi_start (seq);
3686 bitmap_iterator bi;
3687 unsigned i;
3689 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
3691 tree var = candidate (i);
3692 if (!constant_decl_p (var))
3693 continue;
3694 vec<access_p> *access_vec = get_base_access_vector (var);
3695 if (!access_vec)
3696 continue;
3697 for (unsigned i = 0; i < access_vec->length (); i++)
3699 struct access *access = (*access_vec)[i];
3700 if (!access->replacement_decl)
3701 continue;
3702 gassign *stmt
3703 = gimple_build_assign (get_access_replacement (access),
3704 unshare_expr (access->expr));
3705 if (dump_file && (dump_flags & TDF_DETAILS))
3707 fprintf (dump_file, "Generating constant initializer: ");
3708 print_gimple_stmt (dump_file, stmt, 0);
3709 fprintf (dump_file, "\n");
3711 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
3712 update_stmt (stmt);
3716 seq = gsi_seq (gsi);
3717 if (seq)
3718 gsi_insert_seq_on_edge_immediate (
3719 single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3722 /* Traverse the function body and all modifications as decided in
3723 analyze_all_variable_accesses. Return true iff the CFG has been
3724 changed. */
3726 static bool
3727 sra_modify_function_body (void)
3729 bool cfg_changed = false;
3730 basic_block bb;
3732 initialize_constant_pool_replacements ();
3734 FOR_EACH_BB_FN (bb, cfun)
3736 gimple_stmt_iterator gsi = gsi_start_bb (bb);
3737 while (!gsi_end_p (gsi))
3739 gimple *stmt = gsi_stmt (gsi);
3740 enum assignment_mod_result assign_result;
3741 bool modified = false, deleted = false;
3742 tree *t;
3743 unsigned i;
3745 switch (gimple_code (stmt))
3747 case GIMPLE_RETURN:
3748 t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
3749 if (*t != NULL_TREE)
3750 modified |= sra_modify_expr (t, &gsi, false);
3751 break;
3753 case GIMPLE_ASSIGN:
3754 assign_result = sra_modify_assign (stmt, &gsi);
3755 modified |= assign_result == SRA_AM_MODIFIED;
3756 deleted = assign_result == SRA_AM_REMOVED;
3757 break;
3759 case GIMPLE_CALL:
3760 /* Operands must be processed before the lhs. */
3761 for (i = 0; i < gimple_call_num_args (stmt); i++)
3763 t = gimple_call_arg_ptr (stmt, i);
3764 modified |= sra_modify_expr (t, &gsi, false);
3767 if (gimple_call_lhs (stmt))
3769 t = gimple_call_lhs_ptr (stmt);
3770 modified |= sra_modify_expr (t, &gsi, true);
3772 break;
3774 case GIMPLE_ASM:
3776 gasm *asm_stmt = as_a <gasm *> (stmt);
3777 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
3779 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
3780 modified |= sra_modify_expr (t, &gsi, false);
3782 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
3784 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
3785 modified |= sra_modify_expr (t, &gsi, true);
3788 break;
3790 default:
3791 break;
3794 if (modified)
3796 update_stmt (stmt);
3797 if (maybe_clean_eh_stmt (stmt)
3798 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
3799 cfg_changed = true;
3801 if (!deleted)
3802 gsi_next (&gsi);
3806 gsi_commit_edge_inserts ();
3807 return cfg_changed;
3810 /* Generate statements initializing scalar replacements of parts of function
3811 parameters. */
3813 static void
3814 initialize_parameter_reductions (void)
3816 gimple_stmt_iterator gsi;
3817 gimple_seq seq = NULL;
3818 tree parm;
3820 gsi = gsi_start (seq);
3821 for (parm = DECL_ARGUMENTS (current_function_decl);
3822 parm;
3823 parm = DECL_CHAIN (parm))
3825 vec<access_p> *access_vec;
3826 struct access *access;
3828 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3829 continue;
3830 access_vec = get_base_access_vector (parm);
3831 if (!access_vec)
3832 continue;
3834 for (access = (*access_vec)[0];
3835 access;
3836 access = access->next_grp)
3837 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true,
3838 EXPR_LOCATION (parm));
3841 seq = gsi_seq (gsi);
3842 if (seq)
3843 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3846 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3847 it reveals there are components of some aggregates to be scalarized, it runs
3848 the required transformations. */
3849 static unsigned int
3850 perform_intra_sra (void)
3852 int ret = 0;
3853 sra_initialize ();
3855 if (!find_var_candidates ())
3856 goto out;
3858 if (!scan_function ())
3859 goto out;
3861 if (!analyze_all_variable_accesses ())
3862 goto out;
3864 if (sra_modify_function_body ())
3865 ret = TODO_update_ssa | TODO_cleanup_cfg;
3866 else
3867 ret = TODO_update_ssa;
3868 initialize_parameter_reductions ();
3870 statistics_counter_event (cfun, "Scalar replacements created",
3871 sra_stats.replacements);
3872 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
3873 statistics_counter_event (cfun, "Subtree copy stmts",
3874 sra_stats.subtree_copies);
3875 statistics_counter_event (cfun, "Subreplacement stmts",
3876 sra_stats.subreplacements);
3877 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
3878 statistics_counter_event (cfun, "Separate LHS and RHS handling",
3879 sra_stats.separate_lhs_rhs_handling);
3881 out:
3882 sra_deinitialize ();
3883 return ret;
3886 /* Perform early intraprocedural SRA. */
3887 static unsigned int
3888 early_intra_sra (void)
3890 sra_mode = SRA_MODE_EARLY_INTRA;
3891 return perform_intra_sra ();
3894 /* Perform "late" intraprocedural SRA. */
3895 static unsigned int
3896 late_intra_sra (void)
3898 sra_mode = SRA_MODE_INTRA;
3899 return perform_intra_sra ();
3903 static bool
3904 gate_intra_sra (void)
3906 return flag_tree_sra != 0 && dbg_cnt (tree_sra);
3910 namespace {
3912 const pass_data pass_data_sra_early =
3914 GIMPLE_PASS, /* type */
3915 "esra", /* name */
3916 OPTGROUP_NONE, /* optinfo_flags */
3917 TV_TREE_SRA, /* tv_id */
3918 ( PROP_cfg | PROP_ssa ), /* properties_required */
3919 0, /* properties_provided */
3920 0, /* properties_destroyed */
3921 0, /* todo_flags_start */
3922 TODO_update_ssa, /* todo_flags_finish */
3925 class pass_sra_early : public gimple_opt_pass
3927 public:
3928 pass_sra_early (gcc::context *ctxt)
3929 : gimple_opt_pass (pass_data_sra_early, ctxt)
3932 /* opt_pass methods: */
3933 virtual bool gate (function *) { return gate_intra_sra (); }
3934 virtual unsigned int execute (function *) { return early_intra_sra (); }
3936 }; // class pass_sra_early
3938 } // anon namespace
3940 gimple_opt_pass *
3941 make_pass_sra_early (gcc::context *ctxt)
3943 return new pass_sra_early (ctxt);
3946 namespace {
3948 const pass_data pass_data_sra =
3950 GIMPLE_PASS, /* type */
3951 "sra", /* name */
3952 OPTGROUP_NONE, /* optinfo_flags */
3953 TV_TREE_SRA, /* tv_id */
3954 ( PROP_cfg | PROP_ssa ), /* properties_required */
3955 0, /* properties_provided */
3956 0, /* properties_destroyed */
3957 TODO_update_address_taken, /* todo_flags_start */
3958 TODO_update_ssa, /* todo_flags_finish */
3961 class pass_sra : public gimple_opt_pass
3963 public:
3964 pass_sra (gcc::context *ctxt)
3965 : gimple_opt_pass (pass_data_sra, ctxt)
3968 /* opt_pass methods: */
3969 virtual bool gate (function *) { return gate_intra_sra (); }
3970 virtual unsigned int execute (function *) { return late_intra_sra (); }
3972 }; // class pass_sra
3974 } // anon namespace
3976 gimple_opt_pass *
3977 make_pass_sra (gcc::context *ctxt)
3979 return new pass_sra (ctxt);
3983 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3984 parameter. */
3986 static bool
3987 is_unused_scalar_param (tree parm)
3989 tree name;
3990 return (is_gimple_reg (parm)
3991 && (!(name = ssa_default_def (cfun, parm))
3992 || has_zero_uses (name)));
3995 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3996 examine whether there are any direct or otherwise infeasible ones. If so,
3997 return true, otherwise return false. PARM must be a gimple register with a
3998 non-NULL default definition. */
4000 static bool
4001 ptr_parm_has_direct_uses (tree parm)
4003 imm_use_iterator ui;
4004 gimple *stmt;
4005 tree name = ssa_default_def (cfun, parm);
4006 bool ret = false;
4008 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
4010 int uses_ok = 0;
4011 use_operand_p use_p;
4013 if (is_gimple_debug (stmt))
4014 continue;
4016 /* Valid uses include dereferences on the lhs and the rhs. */
4017 if (gimple_has_lhs (stmt))
4019 tree lhs = gimple_get_lhs (stmt);
4020 while (handled_component_p (lhs))
4021 lhs = TREE_OPERAND (lhs, 0);
4022 if (TREE_CODE (lhs) == MEM_REF
4023 && TREE_OPERAND (lhs, 0) == name
4024 && integer_zerop (TREE_OPERAND (lhs, 1))
4025 && types_compatible_p (TREE_TYPE (lhs),
4026 TREE_TYPE (TREE_TYPE (name)))
4027 && !TREE_THIS_VOLATILE (lhs))
4028 uses_ok++;
4030 if (gimple_assign_single_p (stmt))
4032 tree rhs = gimple_assign_rhs1 (stmt);
4033 while (handled_component_p (rhs))
4034 rhs = TREE_OPERAND (rhs, 0);
4035 if (TREE_CODE (rhs) == MEM_REF
4036 && TREE_OPERAND (rhs, 0) == name
4037 && integer_zerop (TREE_OPERAND (rhs, 1))
4038 && types_compatible_p (TREE_TYPE (rhs),
4039 TREE_TYPE (TREE_TYPE (name)))
4040 && !TREE_THIS_VOLATILE (rhs))
4041 uses_ok++;
4043 else if (is_gimple_call (stmt))
4045 unsigned i;
4046 for (i = 0; i < gimple_call_num_args (stmt); ++i)
4048 tree arg = gimple_call_arg (stmt, i);
4049 while (handled_component_p (arg))
4050 arg = TREE_OPERAND (arg, 0);
4051 if (TREE_CODE (arg) == MEM_REF
4052 && TREE_OPERAND (arg, 0) == name
4053 && integer_zerop (TREE_OPERAND (arg, 1))
4054 && types_compatible_p (TREE_TYPE (arg),
4055 TREE_TYPE (TREE_TYPE (name)))
4056 && !TREE_THIS_VOLATILE (arg))
4057 uses_ok++;
4061 /* If the number of valid uses does not match the number of
4062 uses in this stmt there is an unhandled use. */
4063 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
4064 --uses_ok;
4066 if (uses_ok != 0)
4067 ret = true;
4069 if (ret)
4070 BREAK_FROM_IMM_USE_STMT (ui);
4073 return ret;
4076 /* Identify candidates for reduction for IPA-SRA based on their type and mark
4077 them in candidate_bitmap. Note that these do not necessarily include
4078 parameter which are unused and thus can be removed. Return true iff any
4079 such candidate has been found. */
4081 static bool
4082 find_param_candidates (void)
4084 tree parm;
4085 int count = 0;
4086 bool ret = false;
4087 const char *msg;
4089 for (parm = DECL_ARGUMENTS (current_function_decl);
4090 parm;
4091 parm = DECL_CHAIN (parm))
4093 tree type = TREE_TYPE (parm);
4094 tree_node **slot;
4096 count++;
4098 if (TREE_THIS_VOLATILE (parm)
4099 || TREE_ADDRESSABLE (parm)
4100 || (!is_gimple_reg_type (type) && is_va_list_type (type)))
4101 continue;
4103 if (is_unused_scalar_param (parm))
4105 ret = true;
4106 continue;
4109 if (POINTER_TYPE_P (type))
4111 type = TREE_TYPE (type);
4113 if (TREE_CODE (type) == FUNCTION_TYPE
4114 || TYPE_VOLATILE (type)
4115 || (TREE_CODE (type) == ARRAY_TYPE
4116 && TYPE_NONALIASED_COMPONENT (type))
4117 || !is_gimple_reg (parm)
4118 || is_va_list_type (type)
4119 || ptr_parm_has_direct_uses (parm))
4120 continue;
4122 else if (!AGGREGATE_TYPE_P (type))
4123 continue;
4125 if (!COMPLETE_TYPE_P (type)
4126 || !tree_fits_uhwi_p (TYPE_SIZE (type))
4127 || tree_to_uhwi (TYPE_SIZE (type)) == 0
4128 || (AGGREGATE_TYPE_P (type)
4129 && type_internals_preclude_sra_p (type, &msg)))
4130 continue;
4132 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
4133 slot = candidates->find_slot_with_hash (parm, DECL_UID (parm), INSERT);
4134 *slot = parm;
4136 ret = true;
4137 if (dump_file && (dump_flags & TDF_DETAILS))
4139 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
4140 print_generic_expr (dump_file, parm);
4141 fprintf (dump_file, "\n");
4145 func_param_count = count;
4146 return ret;
4149 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
4150 maybe_modified. */
4152 static bool
4153 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
4154 void *data)
4156 struct access *repr = (struct access *) data;
4158 repr->grp_maybe_modified = 1;
4159 return true;
4162 /* Analyze what representatives (in linked lists accessible from
4163 REPRESENTATIVES) can be modified by side effects of statements in the
4164 current function. */
4166 static void
4167 analyze_modified_params (vec<access_p> representatives)
4169 int i;
4171 for (i = 0; i < func_param_count; i++)
4173 struct access *repr;
4175 for (repr = representatives[i];
4176 repr;
4177 repr = repr->next_grp)
4179 struct access *access;
4180 bitmap visited;
4181 ao_ref ar;
4183 if (no_accesses_p (repr))
4184 continue;
4185 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
4186 || repr->grp_maybe_modified)
4187 continue;
4189 ao_ref_init (&ar, repr->expr);
4190 visited = BITMAP_ALLOC (NULL);
4191 for (access = repr; access; access = access->next_sibling)
4193 /* All accesses are read ones, otherwise grp_maybe_modified would
4194 be trivially set. */
4195 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
4196 mark_maybe_modified, repr, &visited);
4197 if (repr->grp_maybe_modified)
4198 break;
4200 BITMAP_FREE (visited);
4205 /* Propagate distances in bb_dereferences in the opposite direction than the
4206 control flow edges, in each step storing the maximum of the current value
4207 and the minimum of all successors. These steps are repeated until the table
4208 stabilizes. Note that BBs which might terminate the functions (according to
4209 final_bbs bitmap) never updated in this way. */
4211 static void
4212 propagate_dereference_distances (void)
4214 basic_block bb;
4216 auto_vec<basic_block> queue (last_basic_block_for_fn (cfun));
4217 queue.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun));
4218 FOR_EACH_BB_FN (bb, cfun)
4220 queue.quick_push (bb);
4221 bb->aux = bb;
4224 while (!queue.is_empty ())
4226 edge_iterator ei;
4227 edge e;
4228 bool change = false;
4229 int i;
4231 bb = queue.pop ();
4232 bb->aux = NULL;
4234 if (bitmap_bit_p (final_bbs, bb->index))
4235 continue;
4237 for (i = 0; i < func_param_count; i++)
4239 int idx = bb->index * func_param_count + i;
4240 bool first = true;
4241 HOST_WIDE_INT inh = 0;
4243 FOR_EACH_EDGE (e, ei, bb->succs)
4245 int succ_idx = e->dest->index * func_param_count + i;
4247 if (e->src == EXIT_BLOCK_PTR_FOR_FN (cfun))
4248 continue;
4250 if (first)
4252 first = false;
4253 inh = bb_dereferences [succ_idx];
4255 else if (bb_dereferences [succ_idx] < inh)
4256 inh = bb_dereferences [succ_idx];
4259 if (!first && bb_dereferences[idx] < inh)
4261 bb_dereferences[idx] = inh;
4262 change = true;
4266 if (change && !bitmap_bit_p (final_bbs, bb->index))
4267 FOR_EACH_EDGE (e, ei, bb->preds)
4269 if (e->src->aux)
4270 continue;
4272 e->src->aux = e->src;
4273 queue.quick_push (e->src);
4278 /* Dump a dereferences TABLE with heading STR to file F. */
4280 static void
4281 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
4283 basic_block bb;
4285 fprintf (dump_file, "%s", str);
4286 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
4287 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
4289 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
4290 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
4292 int i;
4293 for (i = 0; i < func_param_count; i++)
4295 int idx = bb->index * func_param_count + i;
4296 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
4299 fprintf (f, "\n");
4301 fprintf (dump_file, "\n");
4304 /* Determine what (parts of) parameters passed by reference that are not
4305 assigned to are not certainly dereferenced in this function and thus the
4306 dereferencing cannot be safely moved to the caller without potentially
4307 introducing a segfault. Mark such REPRESENTATIVES as
4308 grp_not_necessarilly_dereferenced.
4310 The dereferenced maximum "distance," i.e. the offset + size of the accessed
4311 part is calculated rather than simple booleans are calculated for each
4312 pointer parameter to handle cases when only a fraction of the whole
4313 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
4314 an example).
4316 The maximum dereference distances for each pointer parameter and BB are
4317 already stored in bb_dereference. This routine simply propagates these
4318 values upwards by propagate_dereference_distances and then compares the
4319 distances of individual parameters in the ENTRY BB to the equivalent
4320 distances of each representative of a (fraction of a) parameter. */
4322 static void
4323 analyze_caller_dereference_legality (vec<access_p> representatives)
4325 int i;
4327 if (dump_file && (dump_flags & TDF_DETAILS))
4328 dump_dereferences_table (dump_file,
4329 "Dereference table before propagation:\n",
4330 bb_dereferences);
4332 propagate_dereference_distances ();
4334 if (dump_file && (dump_flags & TDF_DETAILS))
4335 dump_dereferences_table (dump_file,
4336 "Dereference table after propagation:\n",
4337 bb_dereferences);
4339 for (i = 0; i < func_param_count; i++)
4341 struct access *repr = representatives[i];
4342 int idx = ENTRY_BLOCK_PTR_FOR_FN (cfun)->index * func_param_count + i;
4344 if (!repr || no_accesses_p (repr))
4345 continue;
4349 if ((repr->offset + repr->size) > bb_dereferences[idx])
4350 repr->grp_not_necessarilly_dereferenced = 1;
4351 repr = repr->next_grp;
4353 while (repr);
4357 /* Return the representative access for the parameter declaration PARM if it is
4358 a scalar passed by reference which is not written to and the pointer value
4359 is not used directly. Thus, if it is legal to dereference it in the caller
4360 and we can rule out modifications through aliases, such parameter should be
4361 turned into one passed by value. Return NULL otherwise. */
4363 static struct access *
4364 unmodified_by_ref_scalar_representative (tree parm)
4366 int i, access_count;
4367 struct access *repr;
4368 vec<access_p> *access_vec;
4370 access_vec = get_base_access_vector (parm);
4371 gcc_assert (access_vec);
4372 repr = (*access_vec)[0];
4373 if (repr->write)
4374 return NULL;
4375 repr->group_representative = repr;
4377 access_count = access_vec->length ();
4378 for (i = 1; i < access_count; i++)
4380 struct access *access = (*access_vec)[i];
4381 if (access->write)
4382 return NULL;
4383 access->group_representative = repr;
4384 access->next_sibling = repr->next_sibling;
4385 repr->next_sibling = access;
4388 repr->grp_read = 1;
4389 repr->grp_scalar_ptr = 1;
4390 return repr;
4393 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
4394 associated with. REQ_ALIGN is the minimum required alignment. */
4396 static bool
4397 access_precludes_ipa_sra_p (struct access *access, unsigned int req_align)
4399 unsigned int exp_align;
4400 /* Avoid issues such as the second simple testcase in PR 42025. The problem
4401 is incompatible assign in a call statement (and possibly even in asm
4402 statements). This can be relaxed by using a new temporary but only for
4403 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
4404 intraprocedural SRA we deal with this by keeping the old aggregate around,
4405 something we cannot do in IPA-SRA.) */
4406 if (access->write
4407 && (is_gimple_call (access->stmt)
4408 || gimple_code (access->stmt) == GIMPLE_ASM))
4409 return true;
4411 exp_align = get_object_alignment (access->expr);
4412 if (exp_align < req_align)
4413 return true;
4415 return false;
4419 /* Sort collected accesses for parameter PARM, identify representatives for
4420 each accessed region and link them together. Return NULL if there are
4421 different but overlapping accesses, return the special ptr value meaning
4422 there are no accesses for this parameter if that is the case and return the
4423 first representative otherwise. Set *RO_GRP if there is a group of accesses
4424 with only read (i.e. no write) accesses. */
4426 static struct access *
4427 splice_param_accesses (tree parm, bool *ro_grp)
4429 int i, j, access_count, group_count;
4430 int agg_size, total_size = 0;
4431 struct access *access, *res, **prev_acc_ptr = &res;
4432 vec<access_p> *access_vec;
4434 access_vec = get_base_access_vector (parm);
4435 if (!access_vec)
4436 return &no_accesses_representant;
4437 access_count = access_vec->length ();
4439 access_vec->qsort (compare_access_positions);
4441 i = 0;
4442 total_size = 0;
4443 group_count = 0;
4444 while (i < access_count)
4446 bool modification;
4447 tree a1_alias_type;
4448 access = (*access_vec)[i];
4449 modification = access->write;
4450 if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type)))
4451 return NULL;
4452 a1_alias_type = reference_alias_ptr_type (access->expr);
4454 /* Access is about to become group representative unless we find some
4455 nasty overlap which would preclude us from breaking this parameter
4456 apart. */
4458 j = i + 1;
4459 while (j < access_count)
4461 struct access *ac2 = (*access_vec)[j];
4462 if (ac2->offset != access->offset)
4464 /* All or nothing law for parameters. */
4465 if (access->offset + access->size > ac2->offset)
4466 return NULL;
4467 else
4468 break;
4470 else if (ac2->size != access->size)
4471 return NULL;
4473 if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type))
4474 || (ac2->type != access->type
4475 && (TREE_ADDRESSABLE (ac2->type)
4476 || TREE_ADDRESSABLE (access->type)))
4477 || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
4478 return NULL;
4480 modification |= ac2->write;
4481 ac2->group_representative = access;
4482 ac2->next_sibling = access->next_sibling;
4483 access->next_sibling = ac2;
4484 j++;
4487 group_count++;
4488 access->grp_maybe_modified = modification;
4489 if (!modification)
4490 *ro_grp = true;
4491 *prev_acc_ptr = access;
4492 prev_acc_ptr = &access->next_grp;
4493 total_size += access->size;
4494 i = j;
4497 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4498 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4499 else
4500 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4501 if (total_size >= agg_size)
4502 return NULL;
4504 gcc_assert (group_count > 0);
4505 return res;
4508 /* Decide whether parameters with representative accesses given by REPR should
4509 be reduced into components. */
4511 static int
4512 decide_one_param_reduction (struct access *repr)
4514 int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
4515 bool by_ref;
4516 tree parm;
4518 parm = repr->base;
4519 cur_parm_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4520 gcc_assert (cur_parm_size > 0);
4522 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4524 by_ref = true;
4525 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4527 else
4529 by_ref = false;
4530 agg_size = cur_parm_size;
4533 if (dump_file)
4535 struct access *acc;
4536 fprintf (dump_file, "Evaluating PARAM group sizes for ");
4537 print_generic_expr (dump_file, parm);
4538 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
4539 for (acc = repr; acc; acc = acc->next_grp)
4540 dump_access (dump_file, acc, true);
4543 total_size = 0;
4544 new_param_count = 0;
4546 for (; repr; repr = repr->next_grp)
4548 gcc_assert (parm == repr->base);
4550 /* Taking the address of a non-addressable field is verboten. */
4551 if (by_ref && repr->non_addressable)
4552 return 0;
4554 /* Do not decompose a non-BLKmode param in a way that would
4555 create BLKmode params. Especially for by-reference passing
4556 (thus, pointer-type param) this is hardly worthwhile. */
4557 if (DECL_MODE (parm) != BLKmode
4558 && TYPE_MODE (repr->type) == BLKmode)
4559 return 0;
4561 if (!by_ref || (!repr->grp_maybe_modified
4562 && !repr->grp_not_necessarilly_dereferenced))
4563 total_size += repr->size;
4564 else
4565 total_size += cur_parm_size;
4567 new_param_count++;
4570 gcc_assert (new_param_count > 0);
4572 if (optimize_function_for_size_p (cfun))
4573 parm_size_limit = cur_parm_size;
4574 else
4575 parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
4576 * cur_parm_size);
4578 if (total_size < agg_size
4579 && total_size <= parm_size_limit)
4581 if (dump_file)
4582 fprintf (dump_file, " ....will be split into %i components\n",
4583 new_param_count);
4584 return new_param_count;
4586 else
4587 return 0;
4590 /* The order of the following enums is important, we need to do extra work for
4591 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4592 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
4593 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
4595 /* Identify representatives of all accesses to all candidate parameters for
4596 IPA-SRA. Return result based on what representatives have been found. */
4598 static enum ipa_splicing_result
4599 splice_all_param_accesses (vec<access_p> &representatives)
4601 enum ipa_splicing_result result = NO_GOOD_ACCESS;
4602 tree parm;
4603 struct access *repr;
4605 representatives.create (func_param_count);
4607 for (parm = DECL_ARGUMENTS (current_function_decl);
4608 parm;
4609 parm = DECL_CHAIN (parm))
4611 if (is_unused_scalar_param (parm))
4613 representatives.quick_push (&no_accesses_representant);
4614 if (result == NO_GOOD_ACCESS)
4615 result = UNUSED_PARAMS;
4617 else if (POINTER_TYPE_P (TREE_TYPE (parm))
4618 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
4619 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4621 repr = unmodified_by_ref_scalar_representative (parm);
4622 representatives.quick_push (repr);
4623 if (repr)
4624 result = UNMODIF_BY_REF_ACCESSES;
4626 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4628 bool ro_grp = false;
4629 repr = splice_param_accesses (parm, &ro_grp);
4630 representatives.quick_push (repr);
4632 if (repr && !no_accesses_p (repr))
4634 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4636 if (ro_grp)
4637 result = UNMODIF_BY_REF_ACCESSES;
4638 else if (result < MODIF_BY_REF_ACCESSES)
4639 result = MODIF_BY_REF_ACCESSES;
4641 else if (result < BY_VAL_ACCESSES)
4642 result = BY_VAL_ACCESSES;
4644 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
4645 result = UNUSED_PARAMS;
4647 else
4648 representatives.quick_push (NULL);
4651 if (result == NO_GOOD_ACCESS)
4653 representatives.release ();
4654 return NO_GOOD_ACCESS;
4657 return result;
4660 /* Return the index of BASE in PARMS. Abort if it is not found. */
4662 static inline int
4663 get_param_index (tree base, vec<tree> parms)
4665 int i, len;
4667 len = parms.length ();
4668 for (i = 0; i < len; i++)
4669 if (parms[i] == base)
4670 return i;
4671 gcc_unreachable ();
4674 /* Convert the decisions made at the representative level into compact
4675 parameter adjustments. REPRESENTATIVES are pointers to first
4676 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4677 final number of adjustments. */
4679 static ipa_parm_adjustment_vec
4680 turn_representatives_into_adjustments (vec<access_p> representatives,
4681 int adjustments_count)
4683 vec<tree> parms;
4684 ipa_parm_adjustment_vec adjustments;
4685 tree parm;
4686 int i;
4688 gcc_assert (adjustments_count > 0);
4689 parms = ipa_get_vector_of_formal_parms (current_function_decl);
4690 adjustments.create (adjustments_count);
4691 parm = DECL_ARGUMENTS (current_function_decl);
4692 for (i = 0; i < func_param_count; i++, parm = DECL_CHAIN (parm))
4694 struct access *repr = representatives[i];
4696 if (!repr || no_accesses_p (repr))
4698 struct ipa_parm_adjustment adj;
4700 memset (&adj, 0, sizeof (adj));
4701 adj.base_index = get_param_index (parm, parms);
4702 adj.base = parm;
4703 if (!repr)
4704 adj.op = IPA_PARM_OP_COPY;
4705 else
4706 adj.op = IPA_PARM_OP_REMOVE;
4707 adj.arg_prefix = "ISRA";
4708 adjustments.quick_push (adj);
4710 else
4712 struct ipa_parm_adjustment adj;
4713 int index = get_param_index (parm, parms);
4715 for (; repr; repr = repr->next_grp)
4717 memset (&adj, 0, sizeof (adj));
4718 gcc_assert (repr->base == parm);
4719 adj.base_index = index;
4720 adj.base = repr->base;
4721 adj.type = repr->type;
4722 adj.alias_ptr_type = reference_alias_ptr_type (repr->expr);
4723 adj.offset = repr->offset;
4724 adj.reverse = repr->reverse;
4725 adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
4726 && (repr->grp_maybe_modified
4727 || repr->grp_not_necessarilly_dereferenced));
4728 adj.arg_prefix = "ISRA";
4729 adjustments.quick_push (adj);
4733 parms.release ();
4734 return adjustments;
4737 /* Analyze the collected accesses and produce a plan what to do with the
4738 parameters in the form of adjustments, NULL meaning nothing. */
4740 static ipa_parm_adjustment_vec
4741 analyze_all_param_acesses (void)
4743 enum ipa_splicing_result repr_state;
4744 bool proceed = false;
4745 int i, adjustments_count = 0;
4746 vec<access_p> representatives;
4747 ipa_parm_adjustment_vec adjustments;
4749 repr_state = splice_all_param_accesses (representatives);
4750 if (repr_state == NO_GOOD_ACCESS)
4751 return ipa_parm_adjustment_vec ();
4753 /* If there are any parameters passed by reference which are not modified
4754 directly, we need to check whether they can be modified indirectly. */
4755 if (repr_state == UNMODIF_BY_REF_ACCESSES)
4757 analyze_caller_dereference_legality (representatives);
4758 analyze_modified_params (representatives);
4761 for (i = 0; i < func_param_count; i++)
4763 struct access *repr = representatives[i];
4765 if (repr && !no_accesses_p (repr))
4767 if (repr->grp_scalar_ptr)
4769 adjustments_count++;
4770 if (repr->grp_not_necessarilly_dereferenced
4771 || repr->grp_maybe_modified)
4772 representatives[i] = NULL;
4773 else
4775 proceed = true;
4776 sra_stats.scalar_by_ref_to_by_val++;
4779 else
4781 int new_components = decide_one_param_reduction (repr);
4783 if (new_components == 0)
4785 representatives[i] = NULL;
4786 adjustments_count++;
4788 else
4790 adjustments_count += new_components;
4791 sra_stats.aggregate_params_reduced++;
4792 sra_stats.param_reductions_created += new_components;
4793 proceed = true;
4797 else
4799 if (no_accesses_p (repr))
4801 proceed = true;
4802 sra_stats.deleted_unused_parameters++;
4804 adjustments_count++;
4808 if (!proceed && dump_file)
4809 fprintf (dump_file, "NOT proceeding to change params.\n");
4811 if (proceed)
4812 adjustments = turn_representatives_into_adjustments (representatives,
4813 adjustments_count);
4814 else
4815 adjustments = ipa_parm_adjustment_vec ();
4817 representatives.release ();
4818 return adjustments;
4821 /* If a parameter replacement identified by ADJ does not yet exist in the form
4822 of declaration, create it and record it, otherwise return the previously
4823 created one. */
4825 static tree
4826 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
4828 tree repl;
4829 if (!adj->new_ssa_base)
4831 char *pretty_name = make_fancy_name (adj->base);
4833 repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR");
4834 DECL_NAME (repl) = get_identifier (pretty_name);
4835 DECL_NAMELESS (repl) = 1;
4836 obstack_free (&name_obstack, pretty_name);
4838 adj->new_ssa_base = repl;
4840 else
4841 repl = adj->new_ssa_base;
4842 return repl;
4845 /* Find the first adjustment for a particular parameter BASE in a vector of
4846 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4847 adjustment. */
4849 static struct ipa_parm_adjustment *
4850 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
4852 int i, len;
4854 len = adjustments.length ();
4855 for (i = 0; i < len; i++)
4857 struct ipa_parm_adjustment *adj;
4859 adj = &adjustments[i];
4860 if (adj->op != IPA_PARM_OP_COPY && adj->base == base)
4861 return adj;
4864 return NULL;
4867 /* If OLD_NAME, which is being defined by statement STMT, is an SSA_NAME of a
4868 parameter which is to be removed because its value is not used, create a new
4869 SSA_NAME relating to a replacement VAR_DECL, replace all uses of the
4870 original with it and return it. If there is no need to re-map, return NULL.
4871 ADJUSTMENTS is a pointer to a vector of IPA-SRA adjustments. */
4873 static tree
4874 replace_removed_params_ssa_names (tree old_name, gimple *stmt,
4875 ipa_parm_adjustment_vec adjustments)
4877 struct ipa_parm_adjustment *adj;
4878 tree decl, repl, new_name;
4880 if (TREE_CODE (old_name) != SSA_NAME)
4881 return NULL;
4883 decl = SSA_NAME_VAR (old_name);
4884 if (decl == NULL_TREE
4885 || TREE_CODE (decl) != PARM_DECL)
4886 return NULL;
4888 adj = get_adjustment_for_base (adjustments, decl);
4889 if (!adj)
4890 return NULL;
4892 repl = get_replaced_param_substitute (adj);
4893 new_name = make_ssa_name (repl, stmt);
4894 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name)
4895 = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name);
4897 if (dump_file)
4899 fprintf (dump_file, "replacing an SSA name of a removed param ");
4900 print_generic_expr (dump_file, old_name);
4901 fprintf (dump_file, " with ");
4902 print_generic_expr (dump_file, new_name);
4903 fprintf (dump_file, "\n");
4906 replace_uses_by (old_name, new_name);
4907 return new_name;
4910 /* If the statement STMT contains any expressions that need to replaced with a
4911 different one as noted by ADJUSTMENTS, do so. Handle any potential type
4912 incompatibilities (GSI is used to accommodate conversion statements and must
4913 point to the statement). Return true iff the statement was modified. */
4915 static bool
4916 sra_ipa_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi,
4917 ipa_parm_adjustment_vec adjustments)
4919 tree *lhs_p, *rhs_p;
4920 bool any;
4922 if (!gimple_assign_single_p (stmt))
4923 return false;
4925 rhs_p = gimple_assign_rhs1_ptr (stmt);
4926 lhs_p = gimple_assign_lhs_ptr (stmt);
4928 any = ipa_modify_expr (rhs_p, false, adjustments);
4929 any |= ipa_modify_expr (lhs_p, false, adjustments);
4930 if (any)
4932 tree new_rhs = NULL_TREE;
4934 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
4936 if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
4938 /* V_C_Es of constructors can cause trouble (PR 42714). */
4939 if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
4940 *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
4941 else
4942 *rhs_p = build_constructor (TREE_TYPE (*lhs_p),
4943 NULL);
4945 else
4946 new_rhs = fold_build1_loc (gimple_location (stmt),
4947 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
4948 *rhs_p);
4950 else if (REFERENCE_CLASS_P (*rhs_p)
4951 && is_gimple_reg_type (TREE_TYPE (*lhs_p))
4952 && !is_gimple_reg (*lhs_p))
4953 /* This can happen when an assignment in between two single field
4954 structures is turned into an assignment in between two pointers to
4955 scalars (PR 42237). */
4956 new_rhs = *rhs_p;
4958 if (new_rhs)
4960 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
4961 true, GSI_SAME_STMT);
4963 gimple_assign_set_rhs_from_tree (gsi, tmp);
4966 return true;
4969 return false;
4972 /* Traverse the function body and all modifications as described in
4973 ADJUSTMENTS. Return true iff the CFG has been changed. */
4975 bool
4976 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
4978 bool cfg_changed = false;
4979 basic_block bb;
4981 FOR_EACH_BB_FN (bb, cfun)
4983 gimple_stmt_iterator gsi;
4985 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4987 gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
4988 tree new_lhs, old_lhs = gimple_phi_result (phi);
4989 new_lhs = replace_removed_params_ssa_names (old_lhs, phi, adjustments);
4990 if (new_lhs)
4992 gimple_phi_set_result (phi, new_lhs);
4993 release_ssa_name (old_lhs);
4997 gsi = gsi_start_bb (bb);
4998 while (!gsi_end_p (gsi))
5000 gimple *stmt = gsi_stmt (gsi);
5001 bool modified = false;
5002 tree *t;
5003 unsigned i;
5005 switch (gimple_code (stmt))
5007 case GIMPLE_RETURN:
5008 t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
5009 if (*t != NULL_TREE)
5010 modified |= ipa_modify_expr (t, true, adjustments);
5011 break;
5013 case GIMPLE_ASSIGN:
5014 modified |= sra_ipa_modify_assign (stmt, &gsi, adjustments);
5015 break;
5017 case GIMPLE_CALL:
5018 /* Operands must be processed before the lhs. */
5019 for (i = 0; i < gimple_call_num_args (stmt); i++)
5021 t = gimple_call_arg_ptr (stmt, i);
5022 modified |= ipa_modify_expr (t, true, adjustments);
5025 if (gimple_call_lhs (stmt))
5027 t = gimple_call_lhs_ptr (stmt);
5028 modified |= ipa_modify_expr (t, false, adjustments);
5030 break;
5032 case GIMPLE_ASM:
5034 gasm *asm_stmt = as_a <gasm *> (stmt);
5035 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
5037 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
5038 modified |= ipa_modify_expr (t, true, adjustments);
5040 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
5042 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
5043 modified |= ipa_modify_expr (t, false, adjustments);
5046 break;
5048 default:
5049 break;
5052 def_operand_p defp;
5053 ssa_op_iter iter;
5054 FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF)
5056 tree old_def = DEF_FROM_PTR (defp);
5057 if (tree new_def = replace_removed_params_ssa_names (old_def, stmt,
5058 adjustments))
5060 SET_DEF (defp, new_def);
5061 release_ssa_name (old_def);
5062 modified = true;
5066 if (modified)
5068 update_stmt (stmt);
5069 if (maybe_clean_eh_stmt (stmt)
5070 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
5071 cfg_changed = true;
5073 gsi_next (&gsi);
5077 return cfg_changed;
5080 /* Call gimple_debug_bind_reset_value on all debug statements describing
5081 gimple register parameters that are being removed or replaced. */
5083 static void
5084 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
5086 int i, len;
5087 gimple_stmt_iterator *gsip = NULL, gsi;
5089 if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
5091 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
5092 gsip = &gsi;
5094 len = adjustments.length ();
5095 for (i = 0; i < len; i++)
5097 struct ipa_parm_adjustment *adj;
5098 imm_use_iterator ui;
5099 gimple *stmt;
5100 gdebug *def_temp;
5101 tree name, vexpr, copy = NULL_TREE;
5102 use_operand_p use_p;
5104 adj = &adjustments[i];
5105 if (adj->op == IPA_PARM_OP_COPY || !is_gimple_reg (adj->base))
5106 continue;
5107 name = ssa_default_def (cfun, adj->base);
5108 vexpr = NULL;
5109 if (name)
5110 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
5112 if (gimple_clobber_p (stmt))
5114 gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
5115 unlink_stmt_vdef (stmt);
5116 gsi_remove (&cgsi, true);
5117 release_defs (stmt);
5118 continue;
5120 /* All other users must have been removed by
5121 ipa_sra_modify_function_body. */
5122 gcc_assert (is_gimple_debug (stmt));
5123 if (vexpr == NULL && gsip != NULL)
5125 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
5126 vexpr = make_node (DEBUG_EXPR_DECL);
5127 def_temp = gimple_build_debug_source_bind (vexpr, adj->base,
5128 NULL);
5129 DECL_ARTIFICIAL (vexpr) = 1;
5130 TREE_TYPE (vexpr) = TREE_TYPE (name);
5131 SET_DECL_MODE (vexpr, DECL_MODE (adj->base));
5132 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
5134 if (vexpr)
5136 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
5137 SET_USE (use_p, vexpr);
5139 else
5140 gimple_debug_bind_reset_value (stmt);
5141 update_stmt (stmt);
5143 /* Create a VAR_DECL for debug info purposes. */
5144 if (!DECL_IGNORED_P (adj->base))
5146 copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
5147 VAR_DECL, DECL_NAME (adj->base),
5148 TREE_TYPE (adj->base));
5149 if (DECL_PT_UID_SET_P (adj->base))
5150 SET_DECL_PT_UID (copy, DECL_PT_UID (adj->base));
5151 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (adj->base);
5152 TREE_READONLY (copy) = TREE_READONLY (adj->base);
5153 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (adj->base);
5154 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (adj->base);
5155 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (adj->base);
5156 DECL_IGNORED_P (copy) = DECL_IGNORED_P (adj->base);
5157 DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (adj->base);
5158 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
5159 SET_DECL_RTL (copy, 0);
5160 TREE_USED (copy) = 1;
5161 DECL_CONTEXT (copy) = current_function_decl;
5162 add_local_decl (cfun, copy);
5163 DECL_CHAIN (copy) =
5164 BLOCK_VARS (DECL_INITIAL (current_function_decl));
5165 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
5167 if (gsip != NULL && copy && target_for_debug_bind (adj->base))
5169 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
5170 if (vexpr)
5171 def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
5172 else
5173 def_temp = gimple_build_debug_source_bind (copy, adj->base,
5174 NULL);
5175 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
5180 /* Return false if all callers have at least as many actual arguments as there
5181 are formal parameters in the current function and that their types
5182 match. */
5184 static bool
5185 some_callers_have_mismatched_arguments_p (struct cgraph_node *node,
5186 void *data ATTRIBUTE_UNUSED)
5188 struct cgraph_edge *cs;
5189 for (cs = node->callers; cs; cs = cs->next_caller)
5190 if (!cs->call_stmt || !callsite_arguments_match_p (cs->call_stmt))
5191 return true;
5193 return false;
5196 /* Return false if all callers have vuse attached to a call statement. */
5198 static bool
5199 some_callers_have_no_vuse_p (struct cgraph_node *node,
5200 void *data ATTRIBUTE_UNUSED)
5202 struct cgraph_edge *cs;
5203 for (cs = node->callers; cs; cs = cs->next_caller)
5204 if (!cs->call_stmt || !gimple_vuse (cs->call_stmt))
5205 return true;
5207 return false;
5210 /* Convert all callers of NODE. */
5212 static bool
5213 convert_callers_for_node (struct cgraph_node *node,
5214 void *data)
5216 ipa_parm_adjustment_vec *adjustments = (ipa_parm_adjustment_vec *) data;
5217 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
5218 struct cgraph_edge *cs;
5220 for (cs = node->callers; cs; cs = cs->next_caller)
5222 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
5224 if (dump_file)
5225 fprintf (dump_file, "Adjusting call %s -> %s\n",
5226 cs->caller->dump_name (), cs->callee->dump_name ());
5228 ipa_modify_call_arguments (cs, cs->call_stmt, *adjustments);
5230 pop_cfun ();
5233 for (cs = node->callers; cs; cs = cs->next_caller)
5234 if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
5235 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
5236 compute_fn_summary (cs->caller, true);
5237 BITMAP_FREE (recomputed_callers);
5239 return true;
5242 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
5244 static void
5245 convert_callers (struct cgraph_node *node, tree old_decl,
5246 ipa_parm_adjustment_vec adjustments)
5248 basic_block this_block;
5250 node->call_for_symbol_and_aliases (convert_callers_for_node,
5251 &adjustments, false);
5253 if (!encountered_recursive_call)
5254 return;
5256 FOR_EACH_BB_FN (this_block, cfun)
5258 gimple_stmt_iterator gsi;
5260 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
5262 gcall *stmt;
5263 tree call_fndecl;
5264 stmt = dyn_cast <gcall *> (gsi_stmt (gsi));
5265 if (!stmt)
5266 continue;
5267 call_fndecl = gimple_call_fndecl (stmt);
5268 if (call_fndecl == old_decl)
5270 if (dump_file)
5271 fprintf (dump_file, "Adjusting recursive call");
5272 gimple_call_set_fndecl (stmt, node->decl);
5273 ipa_modify_call_arguments (NULL, stmt, adjustments);
5278 return;
5281 /* Perform all the modification required in IPA-SRA for NODE to have parameters
5282 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
5284 static bool
5285 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
5287 struct cgraph_node *new_node;
5288 bool cfg_changed;
5290 cgraph_edge::rebuild_edges ();
5291 free_dominance_info (CDI_DOMINATORS);
5292 pop_cfun ();
5294 /* This must be done after rebuilding cgraph edges for node above.
5295 Otherwise any recursive calls to node that are recorded in
5296 redirect_callers will be corrupted. */
5297 vec<cgraph_edge *> redirect_callers = node->collect_callers ();
5298 new_node = node->create_version_clone_with_body (redirect_callers, NULL,
5299 NULL, false, NULL, NULL,
5300 "isra");
5301 redirect_callers.release ();
5303 push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
5304 ipa_modify_formal_parameters (current_function_decl, adjustments);
5305 cfg_changed = ipa_sra_modify_function_body (adjustments);
5306 sra_ipa_reset_debug_stmts (adjustments);
5307 convert_callers (new_node, node->decl, adjustments);
5308 new_node->make_local ();
5309 return cfg_changed;
5312 /* Means of communication between ipa_sra_check_caller and
5313 ipa_sra_preliminary_function_checks. */
5315 struct ipa_sra_check_caller_data
5317 bool has_callers;
5318 bool bad_arg_alignment;
5319 bool has_thunk;
5322 /* If NODE has a caller, mark that fact in DATA which is pointer to
5323 ipa_sra_check_caller_data. Also check all aggregate arguments in all known
5324 calls if they are unit aligned and if not, set the appropriate flag in DATA
5325 too. */
5327 static bool
5328 ipa_sra_check_caller (struct cgraph_node *node, void *data)
5330 if (!node->callers)
5331 return false;
5333 struct ipa_sra_check_caller_data *iscc;
5334 iscc = (struct ipa_sra_check_caller_data *) data;
5335 iscc->has_callers = true;
5337 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
5339 if (cs->caller->thunk.thunk_p)
5341 iscc->has_thunk = true;
5342 return true;
5344 gimple *call_stmt = cs->call_stmt;
5345 unsigned count = gimple_call_num_args (call_stmt);
5346 for (unsigned i = 0; i < count; i++)
5348 tree arg = gimple_call_arg (call_stmt, i);
5349 if (is_gimple_reg (arg))
5350 continue;
5352 tree offset;
5353 HOST_WIDE_INT bitsize, bitpos;
5354 machine_mode mode;
5355 int unsignedp, reversep, volatilep = 0;
5356 get_inner_reference (arg, &bitsize, &bitpos, &offset, &mode,
5357 &unsignedp, &reversep, &volatilep);
5358 if (bitpos % BITS_PER_UNIT)
5360 iscc->bad_arg_alignment = true;
5361 return true;
5366 return false;
5369 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
5370 attributes, return true otherwise. NODE is the cgraph node of the current
5371 function. */
5373 static bool
5374 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
5376 if (!node->can_be_local_p ())
5378 if (dump_file)
5379 fprintf (dump_file, "Function not local to this compilation unit.\n");
5380 return false;
5383 if (!node->local.can_change_signature)
5385 if (dump_file)
5386 fprintf (dump_file, "Function can not change signature.\n");
5387 return false;
5390 if (!tree_versionable_function_p (node->decl))
5392 if (dump_file)
5393 fprintf (dump_file, "Function is not versionable.\n");
5394 return false;
5397 if (!opt_for_fn (node->decl, optimize)
5398 || !opt_for_fn (node->decl, flag_ipa_sra))
5400 if (dump_file)
5401 fprintf (dump_file, "Function not optimized.\n");
5402 return false;
5405 if (DECL_VIRTUAL_P (current_function_decl))
5407 if (dump_file)
5408 fprintf (dump_file, "Function is a virtual method.\n");
5409 return false;
5412 if ((DECL_ONE_ONLY (node->decl) || DECL_EXTERNAL (node->decl))
5413 && ipa_fn_summaries->get (node)->size >= MAX_INLINE_INSNS_AUTO)
5415 if (dump_file)
5416 fprintf (dump_file, "Function too big to be made truly local.\n");
5417 return false;
5420 if (cfun->stdarg)
5422 if (dump_file)
5423 fprintf (dump_file, "Function uses stdarg. \n");
5424 return false;
5427 if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
5428 return false;
5430 if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
5432 if (dump_file)
5433 fprintf (dump_file, "Always inline function will be inlined "
5434 "anyway. \n");
5435 return false;
5438 struct ipa_sra_check_caller_data iscc;
5439 memset (&iscc, 0, sizeof(iscc));
5440 node->call_for_symbol_and_aliases (ipa_sra_check_caller, &iscc, true);
5441 if (!iscc.has_callers)
5443 if (dump_file)
5444 fprintf (dump_file,
5445 "Function has no callers in this compilation unit.\n");
5446 return false;
5449 if (iscc.bad_arg_alignment)
5451 if (dump_file)
5452 fprintf (dump_file,
5453 "A function call has an argument with non-unit alignment.\n");
5454 return false;
5457 if (iscc.has_thunk)
5459 if (dump_file)
5460 fprintf (dump_file,
5461 "A has thunk.\n");
5462 return false;
5465 return true;
5468 /* Perform early interprocedural SRA. */
5470 static unsigned int
5471 ipa_early_sra (void)
5473 struct cgraph_node *node = cgraph_node::get (current_function_decl);
5474 ipa_parm_adjustment_vec adjustments;
5475 int ret = 0;
5477 if (!ipa_sra_preliminary_function_checks (node))
5478 return 0;
5480 sra_initialize ();
5481 sra_mode = SRA_MODE_EARLY_IPA;
5483 if (!find_param_candidates ())
5485 if (dump_file)
5486 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
5487 goto simple_out;
5490 if (node->call_for_symbol_and_aliases
5491 (some_callers_have_mismatched_arguments_p, NULL, true))
5493 if (dump_file)
5494 fprintf (dump_file, "There are callers with insufficient number of "
5495 "arguments or arguments with type mismatches.\n");
5496 goto simple_out;
5499 if (node->call_for_symbol_and_aliases
5500 (some_callers_have_no_vuse_p, NULL, true))
5502 if (dump_file)
5503 fprintf (dump_file, "There are callers with no VUSE attached "
5504 "to a call stmt.\n");
5505 goto simple_out;
5508 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
5509 func_param_count
5510 * last_basic_block_for_fn (cfun));
5511 final_bbs = BITMAP_ALLOC (NULL);
5513 scan_function ();
5514 if (encountered_apply_args)
5516 if (dump_file)
5517 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
5518 goto out;
5521 if (encountered_unchangable_recursive_call)
5523 if (dump_file)
5524 fprintf (dump_file, "Function calls itself with insufficient "
5525 "number of arguments.\n");
5526 goto out;
5529 adjustments = analyze_all_param_acesses ();
5530 if (!adjustments.exists ())
5531 goto out;
5532 if (dump_file)
5533 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
5535 if (modify_function (node, adjustments))
5536 ret = TODO_update_ssa | TODO_cleanup_cfg;
5537 else
5538 ret = TODO_update_ssa;
5539 adjustments.release ();
5541 statistics_counter_event (cfun, "Unused parameters deleted",
5542 sra_stats.deleted_unused_parameters);
5543 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
5544 sra_stats.scalar_by_ref_to_by_val);
5545 statistics_counter_event (cfun, "Aggregate parameters broken up",
5546 sra_stats.aggregate_params_reduced);
5547 statistics_counter_event (cfun, "Aggregate parameter components created",
5548 sra_stats.param_reductions_created);
5550 out:
5551 BITMAP_FREE (final_bbs);
5552 free (bb_dereferences);
5553 simple_out:
5554 sra_deinitialize ();
5555 return ret;
5558 namespace {
5560 const pass_data pass_data_early_ipa_sra =
5562 GIMPLE_PASS, /* type */
5563 "eipa_sra", /* name */
5564 OPTGROUP_NONE, /* optinfo_flags */
5565 TV_IPA_SRA, /* tv_id */
5566 0, /* properties_required */
5567 0, /* properties_provided */
5568 0, /* properties_destroyed */
5569 0, /* todo_flags_start */
5570 TODO_dump_symtab, /* todo_flags_finish */
5573 class pass_early_ipa_sra : public gimple_opt_pass
5575 public:
5576 pass_early_ipa_sra (gcc::context *ctxt)
5577 : gimple_opt_pass (pass_data_early_ipa_sra, ctxt)
5580 /* opt_pass methods: */
5581 virtual bool gate (function *) { return flag_ipa_sra && dbg_cnt (eipa_sra); }
5582 virtual unsigned int execute (function *) { return ipa_early_sra (); }
5584 }; // class pass_early_ipa_sra
5586 } // anon namespace
5588 gimple_opt_pass *
5589 make_pass_early_ipa_sra (gcc::context *ctxt)
5591 return new pass_early_ipa_sra (ctxt);