[PR80803 1/2] Streamline SRA access enqueuing
[official-gcc.git] / gcc / tree-sra.c
blob05bc3d0e806f14629a7fd0215a5b694bf322d20d
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 /* We need to dive through V_C_Es in order to get the size of its parameter
1179 and not the result type. Ada produces such statements. We are also
1180 capable of handling the topmost V_C_E but not any of those buried in other
1181 handled components. */
1182 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR && !storage_order_barrier_p (expr))
1183 expr = TREE_OPERAND (expr, 0);
1185 if (contains_view_convert_expr_p (expr))
1187 disqualify_base_of_expr (expr, "V_C_E under a different handled "
1188 "component.");
1189 return NULL;
1191 if (TREE_THIS_VOLATILE (expr))
1193 disqualify_base_of_expr (expr, "part of a volatile reference.");
1194 return NULL;
1197 switch (TREE_CODE (expr))
1199 case MEM_REF:
1200 if (TREE_CODE (TREE_OPERAND (expr, 0)) != ADDR_EXPR
1201 && sra_mode != SRA_MODE_EARLY_IPA)
1202 return NULL;
1203 /* fall through */
1204 case VAR_DECL:
1205 case PARM_DECL:
1206 case RESULT_DECL:
1207 case COMPONENT_REF:
1208 case ARRAY_REF:
1209 case ARRAY_RANGE_REF:
1210 ret = create_access (expr, stmt, write);
1211 break;
1213 default:
1214 break;
1217 if (write && partial_ref && ret)
1218 ret->grp_partial_lhs = 1;
1220 return ret;
1223 /* Scan expression EXPR and create access structures for all accesses to
1224 candidates for scalarization. Return true if any access has been inserted.
1225 STMT must be the statement from which the expression is taken, WRITE must be
1226 true if the expression is a store and false otherwise. */
1228 static bool
1229 build_access_from_expr (tree expr, gimple *stmt, bool write)
1231 struct access *access;
1233 access = build_access_from_expr_1 (expr, stmt, write);
1234 if (access)
1236 /* This means the aggregate is accesses as a whole in a way other than an
1237 assign statement and thus cannot be removed even if we had a scalar
1238 replacement for everything. */
1239 if (cannot_scalarize_away_bitmap)
1240 bitmap_set_bit (cannot_scalarize_away_bitmap, DECL_UID (access->base));
1241 return true;
1243 return false;
1246 /* Return the single non-EH successor edge of BB or NULL if there is none or
1247 more than one. */
1249 static edge
1250 single_non_eh_succ (basic_block bb)
1252 edge e, res = NULL;
1253 edge_iterator ei;
1255 FOR_EACH_EDGE (e, ei, bb->succs)
1256 if (!(e->flags & EDGE_EH))
1258 if (res)
1259 return NULL;
1260 res = e;
1263 return res;
1266 /* Disqualify LHS and RHS for scalarization if STMT has to terminate its BB and
1267 there is no alternative spot where to put statements SRA might need to
1268 generate after it. The spot we are looking for is an edge leading to a
1269 single non-EH successor, if it exists and is indeed single. RHS may be
1270 NULL, in that case ignore it. */
1272 static bool
1273 disqualify_if_bad_bb_terminating_stmt (gimple *stmt, tree lhs, tree rhs)
1275 if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1276 && stmt_ends_bb_p (stmt))
1278 if (single_non_eh_succ (gimple_bb (stmt)))
1279 return false;
1281 disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
1282 if (rhs)
1283 disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
1284 return true;
1286 return false;
1289 /* Return true if the nature of BASE is such that it contains data even if
1290 there is no write to it in the function. */
1292 static bool
1293 comes_initialized_p (tree base)
1295 return TREE_CODE (base) == PARM_DECL || constant_decl_p (base);
1298 /* Scan expressions occurring in STMT, create access structures for all accesses
1299 to candidates for scalarization and remove those candidates which occur in
1300 statements or expressions that prevent them from being split apart. Return
1301 true if any access has been inserted. */
1303 static bool
1304 build_accesses_from_assign (gimple *stmt)
1306 tree lhs, rhs;
1307 struct access *lacc, *racc;
1309 if (!gimple_assign_single_p (stmt)
1310 /* Scope clobbers don't influence scalarization. */
1311 || gimple_clobber_p (stmt))
1312 return false;
1314 lhs = gimple_assign_lhs (stmt);
1315 rhs = gimple_assign_rhs1 (stmt);
1317 if (disqualify_if_bad_bb_terminating_stmt (stmt, lhs, rhs))
1318 return false;
1320 racc = build_access_from_expr_1 (rhs, stmt, false);
1321 lacc = build_access_from_expr_1 (lhs, stmt, true);
1323 if (lacc)
1325 lacc->grp_assignment_write = 1;
1326 if (storage_order_barrier_p (rhs))
1327 lacc->grp_unscalarizable_region = 1;
1330 if (racc)
1332 racc->grp_assignment_read = 1;
1333 if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
1334 && !is_gimple_reg_type (racc->type))
1335 bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
1336 if (storage_order_barrier_p (lhs))
1337 racc->grp_unscalarizable_region = 1;
1340 if (lacc && racc
1341 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1342 && !lacc->grp_unscalarizable_region
1343 && !racc->grp_unscalarizable_region
1344 && AGGREGATE_TYPE_P (TREE_TYPE (lhs))
1345 && lacc->size == racc->size
1346 && useless_type_conversion_p (lacc->type, racc->type))
1348 struct assign_link *link;
1350 link = assign_link_pool.allocate ();
1351 memset (link, 0, sizeof (struct assign_link));
1353 link->lacc = lacc;
1354 link->racc = racc;
1355 add_link_to_rhs (racc, link);
1356 /* Let's delay marking the areas as written until propagation of accesses
1357 across link, unless the nature of rhs tells us that its data comes
1358 from elsewhere. */
1359 if (!comes_initialized_p (racc->base))
1360 lacc->write = false;
1363 return lacc || racc;
1366 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1367 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1369 static bool
1370 asm_visit_addr (gimple *, tree op, tree, void *)
1372 op = get_base_address (op);
1373 if (op
1374 && DECL_P (op))
1375 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
1377 return false;
1380 /* Return true iff callsite CALL has at least as many actual arguments as there
1381 are formal parameters of the function currently processed by IPA-SRA and
1382 that their types match. */
1384 static inline bool
1385 callsite_arguments_match_p (gimple *call)
1387 if (gimple_call_num_args (call) < (unsigned) func_param_count)
1388 return false;
1390 tree parm;
1391 int i;
1392 for (parm = DECL_ARGUMENTS (current_function_decl), i = 0;
1393 parm;
1394 parm = DECL_CHAIN (parm), i++)
1396 tree arg = gimple_call_arg (call, i);
1397 if (!useless_type_conversion_p (TREE_TYPE (parm), TREE_TYPE (arg)))
1398 return false;
1400 return true;
1403 /* Scan function and look for interesting expressions and create access
1404 structures for them. Return true iff any access is created. */
1406 static bool
1407 scan_function (void)
1409 basic_block bb;
1410 bool ret = false;
1412 FOR_EACH_BB_FN (bb, cfun)
1414 gimple_stmt_iterator gsi;
1415 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1417 gimple *stmt = gsi_stmt (gsi);
1418 tree t;
1419 unsigned i;
1421 if (final_bbs && stmt_can_throw_external (stmt))
1422 bitmap_set_bit (final_bbs, bb->index);
1423 switch (gimple_code (stmt))
1425 case GIMPLE_RETURN:
1426 t = gimple_return_retval (as_a <greturn *> (stmt));
1427 if (t != NULL_TREE)
1428 ret |= build_access_from_expr (t, stmt, false);
1429 if (final_bbs)
1430 bitmap_set_bit (final_bbs, bb->index);
1431 break;
1433 case GIMPLE_ASSIGN:
1434 ret |= build_accesses_from_assign (stmt);
1435 break;
1437 case GIMPLE_CALL:
1438 for (i = 0; i < gimple_call_num_args (stmt); i++)
1439 ret |= build_access_from_expr (gimple_call_arg (stmt, i),
1440 stmt, false);
1442 if (sra_mode == SRA_MODE_EARLY_IPA)
1444 tree dest = gimple_call_fndecl (stmt);
1445 int flags = gimple_call_flags (stmt);
1447 if (dest)
1449 if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1450 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1451 encountered_apply_args = true;
1452 if (recursive_call_p (current_function_decl, dest))
1454 encountered_recursive_call = true;
1455 if (!callsite_arguments_match_p (stmt))
1456 encountered_unchangable_recursive_call = true;
1460 if (final_bbs
1461 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1462 bitmap_set_bit (final_bbs, bb->index);
1465 t = gimple_call_lhs (stmt);
1466 if (t && !disqualify_if_bad_bb_terminating_stmt (stmt, t, NULL))
1467 ret |= build_access_from_expr (t, stmt, true);
1468 break;
1470 case GIMPLE_ASM:
1472 gasm *asm_stmt = as_a <gasm *> (stmt);
1473 walk_stmt_load_store_addr_ops (asm_stmt, NULL, NULL, NULL,
1474 asm_visit_addr);
1475 if (final_bbs)
1476 bitmap_set_bit (final_bbs, bb->index);
1478 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
1480 t = TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
1481 ret |= build_access_from_expr (t, asm_stmt, false);
1483 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
1485 t = TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
1486 ret |= build_access_from_expr (t, asm_stmt, true);
1489 break;
1491 default:
1492 break;
1497 return ret;
1500 /* Helper of QSORT function. There are pointers to accesses in the array. An
1501 access is considered smaller than another if it has smaller offset or if the
1502 offsets are the same but is size is bigger. */
1504 static int
1505 compare_access_positions (const void *a, const void *b)
1507 const access_p *fp1 = (const access_p *) a;
1508 const access_p *fp2 = (const access_p *) b;
1509 const access_p f1 = *fp1;
1510 const access_p f2 = *fp2;
1512 if (f1->offset != f2->offset)
1513 return f1->offset < f2->offset ? -1 : 1;
1515 if (f1->size == f2->size)
1517 if (f1->type == f2->type)
1518 return 0;
1519 /* Put any non-aggregate type before any aggregate type. */
1520 else if (!is_gimple_reg_type (f1->type)
1521 && is_gimple_reg_type (f2->type))
1522 return 1;
1523 else if (is_gimple_reg_type (f1->type)
1524 && !is_gimple_reg_type (f2->type))
1525 return -1;
1526 /* Put any complex or vector type before any other scalar type. */
1527 else if (TREE_CODE (f1->type) != COMPLEX_TYPE
1528 && TREE_CODE (f1->type) != VECTOR_TYPE
1529 && (TREE_CODE (f2->type) == COMPLEX_TYPE
1530 || TREE_CODE (f2->type) == VECTOR_TYPE))
1531 return 1;
1532 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
1533 || TREE_CODE (f1->type) == VECTOR_TYPE)
1534 && TREE_CODE (f2->type) != COMPLEX_TYPE
1535 && TREE_CODE (f2->type) != VECTOR_TYPE)
1536 return -1;
1537 /* Put the integral type with the bigger precision first. */
1538 else if (INTEGRAL_TYPE_P (f1->type)
1539 && INTEGRAL_TYPE_P (f2->type))
1540 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
1541 /* Put any integral type with non-full precision last. */
1542 else if (INTEGRAL_TYPE_P (f1->type)
1543 && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type))
1544 != TYPE_PRECISION (f1->type)))
1545 return 1;
1546 else if (INTEGRAL_TYPE_P (f2->type)
1547 && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type))
1548 != TYPE_PRECISION (f2->type)))
1549 return -1;
1550 /* Stabilize the sort. */
1551 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1554 /* We want the bigger accesses first, thus the opposite operator in the next
1555 line: */
1556 return f1->size > f2->size ? -1 : 1;
1560 /* Append a name of the declaration to the name obstack. A helper function for
1561 make_fancy_name. */
1563 static void
1564 make_fancy_decl_name (tree decl)
1566 char buffer[32];
1568 tree name = DECL_NAME (decl);
1569 if (name)
1570 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1571 IDENTIFIER_LENGTH (name));
1572 else
1574 sprintf (buffer, "D%u", DECL_UID (decl));
1575 obstack_grow (&name_obstack, buffer, strlen (buffer));
1579 /* Helper for make_fancy_name. */
1581 static void
1582 make_fancy_name_1 (tree expr)
1584 char buffer[32];
1585 tree index;
1587 if (DECL_P (expr))
1589 make_fancy_decl_name (expr);
1590 return;
1593 switch (TREE_CODE (expr))
1595 case COMPONENT_REF:
1596 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1597 obstack_1grow (&name_obstack, '$');
1598 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1599 break;
1601 case ARRAY_REF:
1602 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1603 obstack_1grow (&name_obstack, '$');
1604 /* Arrays with only one element may not have a constant as their
1605 index. */
1606 index = TREE_OPERAND (expr, 1);
1607 if (TREE_CODE (index) != INTEGER_CST)
1608 break;
1609 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1610 obstack_grow (&name_obstack, buffer, strlen (buffer));
1611 break;
1613 case ADDR_EXPR:
1614 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1615 break;
1617 case MEM_REF:
1618 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1619 if (!integer_zerop (TREE_OPERAND (expr, 1)))
1621 obstack_1grow (&name_obstack, '$');
1622 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC,
1623 TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)));
1624 obstack_grow (&name_obstack, buffer, strlen (buffer));
1626 break;
1628 case BIT_FIELD_REF:
1629 case REALPART_EXPR:
1630 case IMAGPART_EXPR:
1631 gcc_unreachable (); /* we treat these as scalars. */
1632 break;
1633 default:
1634 break;
1638 /* Create a human readable name for replacement variable of ACCESS. */
1640 static char *
1641 make_fancy_name (tree expr)
1643 make_fancy_name_1 (expr);
1644 obstack_1grow (&name_obstack, '\0');
1645 return XOBFINISH (&name_obstack, char *);
1648 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1649 EXP_TYPE at the given OFFSET and with storage order REVERSE. If BASE is
1650 something for which get_addr_base_and_unit_offset returns NULL, gsi must
1651 be non-NULL and is used to insert new statements either before or below
1652 the current one as specified by INSERT_AFTER. This function is not capable
1653 of handling bitfields. */
1655 tree
1656 build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
1657 bool reverse, tree exp_type, gimple_stmt_iterator *gsi,
1658 bool insert_after)
1660 tree prev_base = base;
1661 tree off;
1662 tree mem_ref;
1663 HOST_WIDE_INT base_offset;
1664 unsigned HOST_WIDE_INT misalign;
1665 unsigned int align;
1667 /* Preserve address-space information. */
1668 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (base));
1669 if (as != TYPE_ADDR_SPACE (exp_type))
1670 exp_type = build_qualified_type (exp_type,
1671 TYPE_QUALS (exp_type)
1672 | ENCODE_QUAL_ADDR_SPACE (as));
1674 gcc_checking_assert (offset % BITS_PER_UNIT == 0);
1675 get_object_alignment_1 (base, &align, &misalign);
1676 base = get_addr_base_and_unit_offset (base, &base_offset);
1678 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1679 offset such as array[var_index]. */
1680 if (!base)
1682 gassign *stmt;
1683 tree tmp, addr;
1685 gcc_checking_assert (gsi);
1686 tmp = make_ssa_name (build_pointer_type (TREE_TYPE (prev_base)));
1687 addr = build_fold_addr_expr (unshare_expr (prev_base));
1688 STRIP_USELESS_TYPE_CONVERSION (addr);
1689 stmt = gimple_build_assign (tmp, addr);
1690 gimple_set_location (stmt, loc);
1691 if (insert_after)
1692 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
1693 else
1694 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1696 off = build_int_cst (reference_alias_ptr_type (prev_base),
1697 offset / BITS_PER_UNIT);
1698 base = tmp;
1700 else if (TREE_CODE (base) == MEM_REF)
1702 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1703 base_offset + offset / BITS_PER_UNIT);
1704 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1705 base = unshare_expr (TREE_OPERAND (base, 0));
1707 else
1709 off = build_int_cst (reference_alias_ptr_type (prev_base),
1710 base_offset + offset / BITS_PER_UNIT);
1711 base = build_fold_addr_expr (unshare_expr (base));
1714 misalign = (misalign + offset) & (align - 1);
1715 if (misalign != 0)
1716 align = least_bit_hwi (misalign);
1717 if (align != TYPE_ALIGN (exp_type))
1718 exp_type = build_aligned_type (exp_type, align);
1720 mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off);
1721 REF_REVERSE_STORAGE_ORDER (mem_ref) = reverse;
1722 if (TREE_THIS_VOLATILE (prev_base))
1723 TREE_THIS_VOLATILE (mem_ref) = 1;
1724 if (TREE_SIDE_EFFECTS (prev_base))
1725 TREE_SIDE_EFFECTS (mem_ref) = 1;
1726 return mem_ref;
1729 /* Construct a memory reference to a part of an aggregate BASE at the given
1730 OFFSET and of the same type as MODEL. In case this is a reference to a
1731 bit-field, the function will replicate the last component_ref of model's
1732 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1733 build_ref_for_offset. */
1735 static tree
1736 build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1737 struct access *model, gimple_stmt_iterator *gsi,
1738 bool insert_after)
1740 if (TREE_CODE (model->expr) == COMPONENT_REF
1741 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1743 /* This access represents a bit-field. */
1744 tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
1746 offset -= int_bit_position (fld);
1747 exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
1748 t = build_ref_for_offset (loc, base, offset, model->reverse, exp_type,
1749 gsi, insert_after);
1750 /* The flag will be set on the record type. */
1751 REF_REVERSE_STORAGE_ORDER (t) = 0;
1752 return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
1753 NULL_TREE);
1755 else
1756 return
1757 build_ref_for_offset (loc, base, offset, model->reverse, model->type,
1758 gsi, insert_after);
1761 /* Attempt to build a memory reference that we could but into a gimple
1762 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1763 create statements and return s NULL instead. This function also ignores
1764 alignment issues and so its results should never end up in non-debug
1765 statements. */
1767 static tree
1768 build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1769 struct access *model)
1771 HOST_WIDE_INT base_offset;
1772 tree off;
1774 if (TREE_CODE (model->expr) == COMPONENT_REF
1775 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1776 return NULL_TREE;
1778 base = get_addr_base_and_unit_offset (base, &base_offset);
1779 if (!base)
1780 return NULL_TREE;
1781 if (TREE_CODE (base) == MEM_REF)
1783 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1784 base_offset + offset / BITS_PER_UNIT);
1785 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1786 base = unshare_expr (TREE_OPERAND (base, 0));
1788 else
1790 off = build_int_cst (reference_alias_ptr_type (base),
1791 base_offset + offset / BITS_PER_UNIT);
1792 base = build_fold_addr_expr (unshare_expr (base));
1795 return fold_build2_loc (loc, MEM_REF, model->type, base, off);
1798 /* Construct a memory reference consisting of component_refs and array_refs to
1799 a part of an aggregate *RES (which is of type TYPE). The requested part
1800 should have type EXP_TYPE at be the given OFFSET. This function might not
1801 succeed, it returns true when it does and only then *RES points to something
1802 meaningful. This function should be used only to build expressions that we
1803 might need to present to user (e.g. in warnings). In all other situations,
1804 build_ref_for_model or build_ref_for_offset should be used instead. */
1806 static bool
1807 build_user_friendly_ref_for_offset (tree *res, tree type, HOST_WIDE_INT offset,
1808 tree exp_type)
1810 while (1)
1812 tree fld;
1813 tree tr_size, index, minidx;
1814 HOST_WIDE_INT el_size;
1816 if (offset == 0 && exp_type
1817 && types_compatible_p (exp_type, type))
1818 return true;
1820 switch (TREE_CODE (type))
1822 case UNION_TYPE:
1823 case QUAL_UNION_TYPE:
1824 case RECORD_TYPE:
1825 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
1827 HOST_WIDE_INT pos, size;
1828 tree tr_pos, expr, *expr_ptr;
1830 if (TREE_CODE (fld) != FIELD_DECL)
1831 continue;
1833 tr_pos = bit_position (fld);
1834 if (!tr_pos || !tree_fits_uhwi_p (tr_pos))
1835 continue;
1836 pos = tree_to_uhwi (tr_pos);
1837 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1838 tr_size = DECL_SIZE (fld);
1839 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1840 continue;
1841 size = tree_to_uhwi (tr_size);
1842 if (size == 0)
1844 if (pos != offset)
1845 continue;
1847 else if (pos > offset || (pos + size) <= offset)
1848 continue;
1850 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1851 NULL_TREE);
1852 expr_ptr = &expr;
1853 if (build_user_friendly_ref_for_offset (expr_ptr, TREE_TYPE (fld),
1854 offset - pos, exp_type))
1856 *res = expr;
1857 return true;
1860 return false;
1862 case ARRAY_TYPE:
1863 tr_size = TYPE_SIZE (TREE_TYPE (type));
1864 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1865 return false;
1866 el_size = tree_to_uhwi (tr_size);
1868 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1869 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
1870 return false;
1871 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1872 if (!integer_zerop (minidx))
1873 index = int_const_binop (PLUS_EXPR, index, minidx);
1874 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1875 NULL_TREE, NULL_TREE);
1876 offset = offset % el_size;
1877 type = TREE_TYPE (type);
1878 break;
1880 default:
1881 if (offset != 0)
1882 return false;
1884 if (exp_type)
1885 return false;
1886 else
1887 return true;
1892 /* Return true iff TYPE is stdarg va_list type. */
1894 static inline bool
1895 is_va_list_type (tree type)
1897 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1900 /* Print message to dump file why a variable was rejected. */
1902 static void
1903 reject (tree var, const char *msg)
1905 if (dump_file && (dump_flags & TDF_DETAILS))
1907 fprintf (dump_file, "Rejected (%d): %s: ", DECL_UID (var), msg);
1908 print_generic_expr (dump_file, var);
1909 fprintf (dump_file, "\n");
1913 /* Return true if VAR is a candidate for SRA. */
1915 static bool
1916 maybe_add_sra_candidate (tree var)
1918 tree type = TREE_TYPE (var);
1919 const char *msg;
1920 tree_node **slot;
1922 if (!AGGREGATE_TYPE_P (type))
1924 reject (var, "not aggregate");
1925 return false;
1927 /* Allow constant-pool entries (that "need to live in memory")
1928 unless we are doing IPA SRA. */
1929 if (needs_to_live_in_memory (var)
1930 && (sra_mode == SRA_MODE_EARLY_IPA || !constant_decl_p (var)))
1932 reject (var, "needs to live in memory");
1933 return false;
1935 if (TREE_THIS_VOLATILE (var))
1937 reject (var, "is volatile");
1938 return false;
1940 if (!COMPLETE_TYPE_P (type))
1942 reject (var, "has incomplete type");
1943 return false;
1945 if (!tree_fits_uhwi_p (TYPE_SIZE (type)))
1947 reject (var, "type size not fixed");
1948 return false;
1950 if (tree_to_uhwi (TYPE_SIZE (type)) == 0)
1952 reject (var, "type size is zero");
1953 return false;
1955 if (type_internals_preclude_sra_p (type, &msg))
1957 reject (var, msg);
1958 return false;
1960 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1961 we also want to schedule it rather late. Thus we ignore it in
1962 the early pass. */
1963 (sra_mode == SRA_MODE_EARLY_INTRA
1964 && is_va_list_type (type)))
1966 reject (var, "is va_list");
1967 return false;
1970 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
1971 slot = candidates->find_slot_with_hash (var, DECL_UID (var), INSERT);
1972 *slot = var;
1974 if (dump_file && (dump_flags & TDF_DETAILS))
1976 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
1977 print_generic_expr (dump_file, var);
1978 fprintf (dump_file, "\n");
1981 return true;
1984 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1985 those with type which is suitable for scalarization. */
1987 static bool
1988 find_var_candidates (void)
1990 tree var, parm;
1991 unsigned int i;
1992 bool ret = false;
1994 for (parm = DECL_ARGUMENTS (current_function_decl);
1995 parm;
1996 parm = DECL_CHAIN (parm))
1997 ret |= maybe_add_sra_candidate (parm);
1999 FOR_EACH_LOCAL_DECL (cfun, i, var)
2001 if (!VAR_P (var))
2002 continue;
2004 ret |= maybe_add_sra_candidate (var);
2007 return ret;
2010 /* Sort all accesses for the given variable, check for partial overlaps and
2011 return NULL if there are any. If there are none, pick a representative for
2012 each combination of offset and size and create a linked list out of them.
2013 Return the pointer to the first representative and make sure it is the first
2014 one in the vector of accesses. */
2016 static struct access *
2017 sort_and_splice_var_accesses (tree var)
2019 int i, j, access_count;
2020 struct access *res, **prev_acc_ptr = &res;
2021 vec<access_p> *access_vec;
2022 bool first = true;
2023 HOST_WIDE_INT low = -1, high = 0;
2025 access_vec = get_base_access_vector (var);
2026 if (!access_vec)
2027 return NULL;
2028 access_count = access_vec->length ();
2030 /* Sort by <OFFSET, SIZE>. */
2031 access_vec->qsort (compare_access_positions);
2033 i = 0;
2034 while (i < access_count)
2036 struct access *access = (*access_vec)[i];
2037 bool grp_write = access->write;
2038 bool grp_read = !access->write;
2039 bool grp_scalar_write = access->write
2040 && is_gimple_reg_type (access->type);
2041 bool grp_scalar_read = !access->write
2042 && is_gimple_reg_type (access->type);
2043 bool grp_assignment_read = access->grp_assignment_read;
2044 bool grp_assignment_write = access->grp_assignment_write;
2045 bool multiple_scalar_reads = false;
2046 bool total_scalarization = access->grp_total_scalarization;
2047 bool grp_partial_lhs = access->grp_partial_lhs;
2048 bool first_scalar = is_gimple_reg_type (access->type);
2049 bool unscalarizable_region = access->grp_unscalarizable_region;
2051 if (first || access->offset >= high)
2053 first = false;
2054 low = access->offset;
2055 high = access->offset + access->size;
2057 else if (access->offset > low && access->offset + access->size > high)
2058 return NULL;
2059 else
2060 gcc_assert (access->offset >= low
2061 && access->offset + access->size <= high);
2063 j = i + 1;
2064 while (j < access_count)
2066 struct access *ac2 = (*access_vec)[j];
2067 if (ac2->offset != access->offset || ac2->size != access->size)
2068 break;
2069 if (ac2->write)
2071 grp_write = true;
2072 grp_scalar_write = (grp_scalar_write
2073 || is_gimple_reg_type (ac2->type));
2075 else
2077 grp_read = true;
2078 if (is_gimple_reg_type (ac2->type))
2080 if (grp_scalar_read)
2081 multiple_scalar_reads = true;
2082 else
2083 grp_scalar_read = true;
2086 grp_assignment_read |= ac2->grp_assignment_read;
2087 grp_assignment_write |= ac2->grp_assignment_write;
2088 grp_partial_lhs |= ac2->grp_partial_lhs;
2089 unscalarizable_region |= ac2->grp_unscalarizable_region;
2090 total_scalarization |= ac2->grp_total_scalarization;
2091 relink_to_new_repr (access, ac2);
2093 /* If there are both aggregate-type and scalar-type accesses with
2094 this combination of size and offset, the comparison function
2095 should have put the scalars first. */
2096 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
2097 ac2->group_representative = access;
2098 j++;
2101 i = j;
2103 access->group_representative = access;
2104 access->grp_write = grp_write;
2105 access->grp_read = grp_read;
2106 access->grp_scalar_read = grp_scalar_read;
2107 access->grp_scalar_write = grp_scalar_write;
2108 access->grp_assignment_read = grp_assignment_read;
2109 access->grp_assignment_write = grp_assignment_write;
2110 access->grp_hint = total_scalarization
2111 || (multiple_scalar_reads && !constant_decl_p (var));
2112 access->grp_total_scalarization = total_scalarization;
2113 access->grp_partial_lhs = grp_partial_lhs;
2114 access->grp_unscalarizable_region = unscalarizable_region;
2115 add_access_to_work_queue (access);
2117 *prev_acc_ptr = access;
2118 prev_acc_ptr = &access->next_grp;
2121 gcc_assert (res == (*access_vec)[0]);
2122 return res;
2125 /* Create a variable for the given ACCESS which determines the type, name and a
2126 few other properties. Return the variable declaration and store it also to
2127 ACCESS->replacement. */
2129 static tree
2130 create_access_replacement (struct access *access)
2132 tree repl;
2134 if (access->grp_to_be_debug_replaced)
2136 repl = create_tmp_var_raw (access->type);
2137 DECL_CONTEXT (repl) = current_function_decl;
2139 else
2140 /* Drop any special alignment on the type if it's not on the main
2141 variant. This avoids issues with weirdo ABIs like AAPCS. */
2142 repl = create_tmp_var (build_qualified_type
2143 (TYPE_MAIN_VARIANT (access->type),
2144 TYPE_QUALS (access->type)), "SR");
2145 if (TREE_CODE (access->type) == COMPLEX_TYPE
2146 || TREE_CODE (access->type) == VECTOR_TYPE)
2148 if (!access->grp_partial_lhs)
2149 DECL_GIMPLE_REG_P (repl) = 1;
2151 else if (access->grp_partial_lhs
2152 && is_gimple_reg_type (access->type))
2153 TREE_ADDRESSABLE (repl) = 1;
2155 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
2156 DECL_ARTIFICIAL (repl) = 1;
2157 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
2159 if (DECL_NAME (access->base)
2160 && !DECL_IGNORED_P (access->base)
2161 && !DECL_ARTIFICIAL (access->base))
2163 char *pretty_name = make_fancy_name (access->expr);
2164 tree debug_expr = unshare_expr_without_location (access->expr), d;
2165 bool fail = false;
2167 DECL_NAME (repl) = get_identifier (pretty_name);
2168 DECL_NAMELESS (repl) = 1;
2169 obstack_free (&name_obstack, pretty_name);
2171 /* Get rid of any SSA_NAMEs embedded in debug_expr,
2172 as DECL_DEBUG_EXPR isn't considered when looking for still
2173 used SSA_NAMEs and thus they could be freed. All debug info
2174 generation cares is whether something is constant or variable
2175 and that get_ref_base_and_extent works properly on the
2176 expression. It cannot handle accesses at a non-constant offset
2177 though, so just give up in those cases. */
2178 for (d = debug_expr;
2179 !fail && (handled_component_p (d) || TREE_CODE (d) == MEM_REF);
2180 d = TREE_OPERAND (d, 0))
2181 switch (TREE_CODE (d))
2183 case ARRAY_REF:
2184 case ARRAY_RANGE_REF:
2185 if (TREE_OPERAND (d, 1)
2186 && TREE_CODE (TREE_OPERAND (d, 1)) != INTEGER_CST)
2187 fail = true;
2188 if (TREE_OPERAND (d, 3)
2189 && TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST)
2190 fail = true;
2191 /* FALLTHRU */
2192 case COMPONENT_REF:
2193 if (TREE_OPERAND (d, 2)
2194 && TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST)
2195 fail = true;
2196 break;
2197 case MEM_REF:
2198 if (TREE_CODE (TREE_OPERAND (d, 0)) != ADDR_EXPR)
2199 fail = true;
2200 else
2201 d = TREE_OPERAND (d, 0);
2202 break;
2203 default:
2204 break;
2206 if (!fail)
2208 SET_DECL_DEBUG_EXPR (repl, debug_expr);
2209 DECL_HAS_DEBUG_EXPR_P (repl) = 1;
2211 if (access->grp_no_warning)
2212 TREE_NO_WARNING (repl) = 1;
2213 else
2214 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
2216 else
2217 TREE_NO_WARNING (repl) = 1;
2219 if (dump_file)
2221 if (access->grp_to_be_debug_replaced)
2223 fprintf (dump_file, "Created a debug-only replacement for ");
2224 print_generic_expr (dump_file, access->base);
2225 fprintf (dump_file, " offset: %u, size: %u\n",
2226 (unsigned) access->offset, (unsigned) access->size);
2228 else
2230 fprintf (dump_file, "Created a replacement for ");
2231 print_generic_expr (dump_file, access->base);
2232 fprintf (dump_file, " offset: %u, size: %u: ",
2233 (unsigned) access->offset, (unsigned) access->size);
2234 print_generic_expr (dump_file, repl);
2235 fprintf (dump_file, "\n");
2238 sra_stats.replacements++;
2240 return repl;
2243 /* Return ACCESS scalar replacement, which must exist. */
2245 static inline tree
2246 get_access_replacement (struct access *access)
2248 gcc_checking_assert (access->replacement_decl);
2249 return access->replacement_decl;
2253 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2254 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2255 to it is not "within" the root. Return false iff some accesses partially
2256 overlap. */
2258 static bool
2259 build_access_subtree (struct access **access)
2261 struct access *root = *access, *last_child = NULL;
2262 HOST_WIDE_INT limit = root->offset + root->size;
2264 *access = (*access)->next_grp;
2265 while (*access && (*access)->offset + (*access)->size <= limit)
2267 if (!last_child)
2268 root->first_child = *access;
2269 else
2270 last_child->next_sibling = *access;
2271 last_child = *access;
2272 (*access)->parent = root;
2273 (*access)->grp_write |= root->grp_write;
2275 if (!build_access_subtree (access))
2276 return false;
2279 if (*access && (*access)->offset < limit)
2280 return false;
2282 return true;
2285 /* Build a tree of access representatives, ACCESS is the pointer to the first
2286 one, others are linked in a list by the next_grp field. Return false iff
2287 some accesses partially overlap. */
2289 static bool
2290 build_access_trees (struct access *access)
2292 while (access)
2294 struct access *root = access;
2296 if (!build_access_subtree (&access))
2297 return false;
2298 root->next_grp = access;
2300 return true;
2303 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2304 array. */
2306 static bool
2307 expr_with_var_bounded_array_refs_p (tree expr)
2309 while (handled_component_p (expr))
2311 if (TREE_CODE (expr) == ARRAY_REF
2312 && !tree_fits_shwi_p (array_ref_low_bound (expr)))
2313 return true;
2314 expr = TREE_OPERAND (expr, 0);
2316 return false;
2319 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2320 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2321 sorts of access flags appropriately along the way, notably always set
2322 grp_read and grp_assign_read according to MARK_READ and grp_write when
2323 MARK_WRITE is true.
2325 Creating a replacement for a scalar access is considered beneficial if its
2326 grp_hint is set (this means we are either attempting total scalarization or
2327 there is more than one direct read access) or according to the following
2328 table:
2330 Access written to through a scalar type (once or more times)
2332 | Written to in an assignment statement
2334 | | Access read as scalar _once_
2335 | | |
2336 | | | Read in an assignment statement
2337 | | | |
2338 | | | | Scalarize Comment
2339 -----------------------------------------------------------------------------
2340 0 0 0 0 No access for the scalar
2341 0 0 0 1 No access for the scalar
2342 0 0 1 0 No Single read - won't help
2343 0 0 1 1 No The same case
2344 0 1 0 0 No access for the scalar
2345 0 1 0 1 No access for the scalar
2346 0 1 1 0 Yes s = *g; return s.i;
2347 0 1 1 1 Yes The same case as above
2348 1 0 0 0 No Won't help
2349 1 0 0 1 Yes s.i = 1; *g = s;
2350 1 0 1 0 Yes s.i = 5; g = s.i;
2351 1 0 1 1 Yes The same case as above
2352 1 1 0 0 No Won't help.
2353 1 1 0 1 Yes s.i = 1; *g = s;
2354 1 1 1 0 Yes s = *g; return s.i;
2355 1 1 1 1 Yes Any of the above yeses */
2357 static bool
2358 analyze_access_subtree (struct access *root, struct access *parent,
2359 bool allow_replacements)
2361 struct access *child;
2362 HOST_WIDE_INT limit = root->offset + root->size;
2363 HOST_WIDE_INT covered_to = root->offset;
2364 bool scalar = is_gimple_reg_type (root->type);
2365 bool hole = false, sth_created = false;
2367 if (parent)
2369 if (parent->grp_read)
2370 root->grp_read = 1;
2371 if (parent->grp_assignment_read)
2372 root->grp_assignment_read = 1;
2373 if (parent->grp_write)
2374 root->grp_write = 1;
2375 if (parent->grp_assignment_write)
2376 root->grp_assignment_write = 1;
2377 if (parent->grp_total_scalarization)
2378 root->grp_total_scalarization = 1;
2381 if (root->grp_unscalarizable_region)
2382 allow_replacements = false;
2384 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
2385 allow_replacements = false;
2387 for (child = root->first_child; child; child = child->next_sibling)
2389 hole |= covered_to < child->offset;
2390 sth_created |= analyze_access_subtree (child, root,
2391 allow_replacements && !scalar);
2393 root->grp_unscalarized_data |= child->grp_unscalarized_data;
2394 root->grp_total_scalarization &= child->grp_total_scalarization;
2395 if (child->grp_covered)
2396 covered_to += child->size;
2397 else
2398 hole = true;
2401 if (allow_replacements && scalar && !root->first_child
2402 && (root->grp_hint
2403 || ((root->grp_scalar_read || root->grp_assignment_read)
2404 && (root->grp_scalar_write || root->grp_assignment_write))))
2406 /* Always create access replacements that cover the whole access.
2407 For integral types this means the precision has to match.
2408 Avoid assumptions based on the integral type kind, too. */
2409 if (INTEGRAL_TYPE_P (root->type)
2410 && (TREE_CODE (root->type) != INTEGER_TYPE
2411 || TYPE_PRECISION (root->type) != root->size)
2412 /* But leave bitfield accesses alone. */
2413 && (TREE_CODE (root->expr) != COMPONENT_REF
2414 || !DECL_BIT_FIELD (TREE_OPERAND (root->expr, 1))))
2416 tree rt = root->type;
2417 gcc_assert ((root->offset % BITS_PER_UNIT) == 0
2418 && (root->size % BITS_PER_UNIT) == 0);
2419 root->type = build_nonstandard_integer_type (root->size,
2420 TYPE_UNSIGNED (rt));
2421 root->expr = build_ref_for_offset (UNKNOWN_LOCATION, root->base,
2422 root->offset, root->reverse,
2423 root->type, NULL, false);
2425 if (dump_file && (dump_flags & TDF_DETAILS))
2427 fprintf (dump_file, "Changing the type of a replacement for ");
2428 print_generic_expr (dump_file, root->base);
2429 fprintf (dump_file, " offset: %u, size: %u ",
2430 (unsigned) root->offset, (unsigned) root->size);
2431 fprintf (dump_file, " to an integer.\n");
2435 root->grp_to_be_replaced = 1;
2436 root->replacement_decl = create_access_replacement (root);
2437 sth_created = true;
2438 hole = false;
2440 else
2442 if (allow_replacements
2443 && scalar && !root->first_child
2444 && (root->grp_scalar_write || root->grp_assignment_write)
2445 && !bitmap_bit_p (cannot_scalarize_away_bitmap,
2446 DECL_UID (root->base)))
2448 gcc_checking_assert (!root->grp_scalar_read
2449 && !root->grp_assignment_read);
2450 sth_created = true;
2451 if (MAY_HAVE_DEBUG_STMTS)
2453 root->grp_to_be_debug_replaced = 1;
2454 root->replacement_decl = create_access_replacement (root);
2458 if (covered_to < limit)
2459 hole = true;
2460 if (scalar || !allow_replacements)
2461 root->grp_total_scalarization = 0;
2464 if (!hole || root->grp_total_scalarization)
2465 root->grp_covered = 1;
2466 else if (root->grp_write || comes_initialized_p (root->base))
2467 root->grp_unscalarized_data = 1; /* not covered and written to */
2468 return sth_created;
2471 /* Analyze all access trees linked by next_grp by the means of
2472 analyze_access_subtree. */
2473 static bool
2474 analyze_access_trees (struct access *access)
2476 bool ret = false;
2478 while (access)
2480 if (analyze_access_subtree (access, NULL, true))
2481 ret = true;
2482 access = access->next_grp;
2485 return ret;
2488 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2489 SIZE would conflict with an already existing one. If exactly such a child
2490 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2492 static bool
2493 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
2494 HOST_WIDE_INT size, struct access **exact_match)
2496 struct access *child;
2498 for (child = lacc->first_child; child; child = child->next_sibling)
2500 if (child->offset == norm_offset && child->size == size)
2502 *exact_match = child;
2503 return true;
2506 if (child->offset < norm_offset + size
2507 && child->offset + child->size > norm_offset)
2508 return true;
2511 return false;
2514 /* Create a new child access of PARENT, with all properties just like MODEL
2515 except for its offset and with its grp_write false and grp_read true.
2516 Return the new access or NULL if it cannot be created. Note that this
2517 access is created long after all splicing and sorting, it's not located in
2518 any access vector and is automatically a representative of its group. Set
2519 the gpr_write flag of the new accesss if SET_GRP_WRITE is true. */
2521 static struct access *
2522 create_artificial_child_access (struct access *parent, struct access *model,
2523 HOST_WIDE_INT new_offset,
2524 bool set_grp_write)
2526 struct access **child;
2527 tree expr = parent->base;
2529 gcc_assert (!model->grp_unscalarizable_region);
2531 struct access *access = access_pool.allocate ();
2532 memset (access, 0, sizeof (struct access));
2533 if (!build_user_friendly_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
2534 model->type))
2536 access->grp_no_warning = true;
2537 expr = build_ref_for_model (EXPR_LOCATION (parent->base), parent->base,
2538 new_offset, model, NULL, false);
2541 access->base = parent->base;
2542 access->expr = expr;
2543 access->offset = new_offset;
2544 access->size = model->size;
2545 access->type = model->type;
2546 access->grp_write = set_grp_write;
2547 access->grp_read = false;
2548 access->reverse = model->reverse;
2550 child = &parent->first_child;
2551 while (*child && (*child)->offset < new_offset)
2552 child = &(*child)->next_sibling;
2554 access->next_sibling = *child;
2555 *child = access;
2557 return access;
2561 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
2562 true if any new subaccess was created. Additionally, if RACC is a scalar
2563 access but LACC is not, change the type of the latter, if possible. */
2565 static bool
2566 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
2568 struct access *rchild;
2569 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
2570 bool ret = false;
2572 /* IF the LHS is still not marked as being written to, we only need to do so
2573 if the RHS at this level actually was. */
2574 if (!lacc->grp_write)
2576 gcc_checking_assert (!comes_initialized_p (racc->base));
2577 if (racc->grp_write)
2579 lacc->grp_write = true;
2580 ret = true;
2584 if (is_gimple_reg_type (lacc->type)
2585 || lacc->grp_unscalarizable_region
2586 || racc->grp_unscalarizable_region)
2588 ret |= !lacc->grp_write;
2589 lacc->grp_write = true;
2590 return ret;
2593 if (is_gimple_reg_type (racc->type))
2595 if (!lacc->first_child && !racc->first_child)
2597 tree t = lacc->base;
2599 lacc->type = racc->type;
2600 if (build_user_friendly_ref_for_offset (&t, TREE_TYPE (t),
2601 lacc->offset, racc->type))
2602 lacc->expr = t;
2603 else
2605 lacc->expr = build_ref_for_model (EXPR_LOCATION (lacc->base),
2606 lacc->base, lacc->offset,
2607 racc, NULL, false);
2608 lacc->grp_no_warning = true;
2611 return ret;
2614 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
2616 struct access *new_acc = NULL;
2617 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
2619 if (rchild->grp_unscalarizable_region)
2621 lacc->grp_write = true;
2622 continue;
2625 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
2626 &new_acc))
2628 if (new_acc)
2630 if (!new_acc->grp_write
2631 && (lacc->grp_write || rchild->grp_write))
2633 new_acc ->grp_write = true;
2634 ret = true;
2637 rchild->grp_hint = 1;
2638 new_acc->grp_hint |= new_acc->grp_read;
2639 if (rchild->first_child)
2640 ret |= propagate_subaccesses_across_link (new_acc, rchild);
2642 else
2643 lacc->grp_write = true;
2644 continue;
2647 rchild->grp_hint = 1;
2648 new_acc = create_artificial_child_access (lacc, rchild, norm_offset,
2649 lacc->grp_write
2650 || rchild->grp_write);
2651 if (new_acc)
2653 ret = true;
2654 if (racc->first_child)
2655 propagate_subaccesses_across_link (new_acc, rchild);
2659 return ret;
2662 /* Beginning with ACCESS, traverse its whole access subtree and mark all
2663 sub-trees as written to. If any of them has not been marked so previously
2664 and has assignment links leading from it, re-enqueue it. */
2666 static void
2667 subtree_mark_written_and_enqueue (struct access *access)
2669 if (access->grp_write)
2670 return;
2671 access->grp_write = true;
2672 add_access_to_work_queue (access);
2674 struct access *child;
2675 for (child = access->first_child; child; child = child->next_sibling)
2676 subtree_mark_written_and_enqueue (child);
2681 /* Propagate all subaccesses across assignment links. */
2683 static void
2684 propagate_all_subaccesses (void)
2686 while (work_queue_head)
2688 struct access *racc = pop_access_from_work_queue ();
2689 struct assign_link *link;
2691 gcc_assert (racc->first_link);
2693 for (link = racc->first_link; link; link = link->next)
2695 struct access *lacc = link->lacc;
2697 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
2698 continue;
2699 lacc = lacc->group_representative;
2701 bool reque_parents = false;
2702 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (racc->base)))
2704 if (!lacc->grp_write)
2706 subtree_mark_written_and_enqueue (lacc);
2707 reque_parents = true;
2710 else if (propagate_subaccesses_across_link (lacc, racc))
2711 reque_parents = true;
2713 if (reque_parents)
2716 add_access_to_work_queue (lacc);
2717 lacc = lacc->parent;
2719 while (lacc);
2724 /* Go through all accesses collected throughout the (intraprocedural) analysis
2725 stage, exclude overlapping ones, identify representatives and build trees
2726 out of them, making decisions about scalarization on the way. Return true
2727 iff there are any to-be-scalarized variables after this stage. */
2729 static bool
2730 analyze_all_variable_accesses (void)
2732 int res = 0;
2733 bitmap tmp = BITMAP_ALLOC (NULL);
2734 bitmap_iterator bi;
2735 unsigned i;
2736 bool optimize_speed_p = !optimize_function_for_size_p (cfun);
2738 enum compiler_param param = optimize_speed_p
2739 ? PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED
2740 : PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE;
2742 /* If the user didn't set PARAM_SRA_MAX_SCALARIZATION_SIZE_<...>,
2743 fall back to a target default. */
2744 unsigned HOST_WIDE_INT max_scalarization_size
2745 = global_options_set.x_param_values[param]
2746 ? PARAM_VALUE (param)
2747 : get_move_ratio (optimize_speed_p) * UNITS_PER_WORD;
2749 max_scalarization_size *= BITS_PER_UNIT;
2751 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
2752 if (bitmap_bit_p (should_scalarize_away_bitmap, i)
2753 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
2755 tree var = candidate (i);
2757 if (VAR_P (var) && scalarizable_type_p (TREE_TYPE (var),
2758 constant_decl_p (var)))
2760 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var)))
2761 <= max_scalarization_size)
2763 create_total_scalarization_access (var);
2764 completely_scalarize (var, TREE_TYPE (var), 0, var);
2765 statistics_counter_event (cfun,
2766 "Totally-scalarized aggregates", 1);
2767 if (dump_file && (dump_flags & TDF_DETAILS))
2769 fprintf (dump_file, "Will attempt to totally scalarize ");
2770 print_generic_expr (dump_file, var);
2771 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2774 else if (dump_file && (dump_flags & TDF_DETAILS))
2776 fprintf (dump_file, "Too big to totally scalarize: ");
2777 print_generic_expr (dump_file, var);
2778 fprintf (dump_file, " (UID: %u)\n", DECL_UID (var));
2783 bitmap_copy (tmp, candidate_bitmap);
2784 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2786 tree var = candidate (i);
2787 struct access *access;
2789 access = sort_and_splice_var_accesses (var);
2790 if (!access || !build_access_trees (access))
2791 disqualify_candidate (var,
2792 "No or inhibitingly overlapping accesses.");
2795 propagate_all_subaccesses ();
2797 bitmap_copy (tmp, candidate_bitmap);
2798 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2800 tree var = candidate (i);
2801 struct access *access = get_first_repr_for_decl (var);
2803 if (analyze_access_trees (access))
2805 res++;
2806 if (dump_file && (dump_flags & TDF_DETAILS))
2808 fprintf (dump_file, "\nAccess trees for ");
2809 print_generic_expr (dump_file, var);
2810 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2811 dump_access_tree (dump_file, access);
2812 fprintf (dump_file, "\n");
2815 else
2816 disqualify_candidate (var, "No scalar replacements to be created.");
2819 BITMAP_FREE (tmp);
2821 if (res)
2823 statistics_counter_event (cfun, "Scalarized aggregates", res);
2824 return true;
2826 else
2827 return false;
2830 /* Generate statements copying scalar replacements of accesses within a subtree
2831 into or out of AGG. ACCESS, all its children, siblings and their children
2832 are to be processed. AGG is an aggregate type expression (can be a
2833 declaration but does not have to be, it can for example also be a mem_ref or
2834 a series of handled components). TOP_OFFSET is the offset of the processed
2835 subtree which has to be subtracted from offsets of individual accesses to
2836 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2837 replacements in the interval <start_offset, start_offset + chunk_size>,
2838 otherwise copy all. GSI is a statement iterator used to place the new
2839 statements. WRITE should be true when the statements should write from AGG
2840 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2841 statements will be added after the current statement in GSI, they will be
2842 added before the statement otherwise. */
2844 static void
2845 generate_subtree_copies (struct access *access, tree agg,
2846 HOST_WIDE_INT top_offset,
2847 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
2848 gimple_stmt_iterator *gsi, bool write,
2849 bool insert_after, location_t loc)
2851 /* Never write anything into constant pool decls. See PR70602. */
2852 if (!write && constant_decl_p (agg))
2853 return;
2856 if (chunk_size && access->offset >= start_offset + chunk_size)
2857 return;
2859 if (access->grp_to_be_replaced
2860 && (chunk_size == 0
2861 || access->offset + access->size > start_offset))
2863 tree expr, repl = get_access_replacement (access);
2864 gassign *stmt;
2866 expr = build_ref_for_model (loc, agg, access->offset - top_offset,
2867 access, gsi, insert_after);
2869 if (write)
2871 if (access->grp_partial_lhs)
2872 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
2873 !insert_after,
2874 insert_after ? GSI_NEW_STMT
2875 : GSI_SAME_STMT);
2876 stmt = gimple_build_assign (repl, expr);
2878 else
2880 TREE_NO_WARNING (repl) = 1;
2881 if (access->grp_partial_lhs)
2882 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2883 !insert_after,
2884 insert_after ? GSI_NEW_STMT
2885 : GSI_SAME_STMT);
2886 stmt = gimple_build_assign (expr, repl);
2888 gimple_set_location (stmt, loc);
2890 if (insert_after)
2891 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2892 else
2893 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2894 update_stmt (stmt);
2895 sra_stats.subtree_copies++;
2897 else if (write
2898 && access->grp_to_be_debug_replaced
2899 && (chunk_size == 0
2900 || access->offset + access->size > start_offset))
2902 gdebug *ds;
2903 tree drhs = build_debug_ref_for_model (loc, agg,
2904 access->offset - top_offset,
2905 access);
2906 ds = gimple_build_debug_bind (get_access_replacement (access),
2907 drhs, gsi_stmt (*gsi));
2908 if (insert_after)
2909 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2910 else
2911 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2914 if (access->first_child)
2915 generate_subtree_copies (access->first_child, agg, top_offset,
2916 start_offset, chunk_size, gsi,
2917 write, insert_after, loc);
2919 access = access->next_sibling;
2921 while (access);
2924 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2925 root of the subtree to be processed. GSI is the statement iterator used
2926 for inserting statements which are added after the current statement if
2927 INSERT_AFTER is true or before it otherwise. */
2929 static void
2930 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
2931 bool insert_after, location_t loc)
2934 struct access *child;
2936 if (access->grp_to_be_replaced)
2938 gassign *stmt;
2940 stmt = gimple_build_assign (get_access_replacement (access),
2941 build_zero_cst (access->type));
2942 if (insert_after)
2943 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2944 else
2945 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2946 update_stmt (stmt);
2947 gimple_set_location (stmt, loc);
2949 else if (access->grp_to_be_debug_replaced)
2951 gdebug *ds
2952 = gimple_build_debug_bind (get_access_replacement (access),
2953 build_zero_cst (access->type),
2954 gsi_stmt (*gsi));
2955 if (insert_after)
2956 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2957 else
2958 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2961 for (child = access->first_child; child; child = child->next_sibling)
2962 init_subtree_with_zero (child, gsi, insert_after, loc);
2965 /* Clobber all scalar replacements in an access subtree. ACCESS is the
2966 root of the subtree to be processed. GSI is the statement iterator used
2967 for inserting statements which are added after the current statement if
2968 INSERT_AFTER is true or before it otherwise. */
2970 static void
2971 clobber_subtree (struct access *access, gimple_stmt_iterator *gsi,
2972 bool insert_after, location_t loc)
2975 struct access *child;
2977 if (access->grp_to_be_replaced)
2979 tree rep = get_access_replacement (access);
2980 tree clobber = build_constructor (access->type, NULL);
2981 TREE_THIS_VOLATILE (clobber) = 1;
2982 gimple *stmt = gimple_build_assign (rep, clobber);
2984 if (insert_after)
2985 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2986 else
2987 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2988 update_stmt (stmt);
2989 gimple_set_location (stmt, loc);
2992 for (child = access->first_child; child; child = child->next_sibling)
2993 clobber_subtree (child, gsi, insert_after, loc);
2996 /* Search for an access representative for the given expression EXPR and
2997 return it or NULL if it cannot be found. */
2999 static struct access *
3000 get_access_for_expr (tree expr)
3002 HOST_WIDE_INT offset, size, max_size;
3003 tree base;
3004 bool reverse;
3006 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
3007 a different size than the size of its argument and we need the latter
3008 one. */
3009 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
3010 expr = TREE_OPERAND (expr, 0);
3012 base = get_ref_base_and_extent (expr, &offset, &size, &max_size, &reverse);
3013 if (max_size == -1 || !DECL_P (base))
3014 return NULL;
3016 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
3017 return NULL;
3019 return get_var_base_offset_size_access (base, offset, max_size);
3022 /* Replace the expression EXPR with a scalar replacement if there is one and
3023 generate other statements to do type conversion or subtree copying if
3024 necessary. GSI is used to place newly created statements, WRITE is true if
3025 the expression is being written to (it is on a LHS of a statement or output
3026 in an assembly statement). */
3028 static bool
3029 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
3031 location_t loc;
3032 struct access *access;
3033 tree type, bfr, orig_expr;
3035 if (TREE_CODE (*expr) == BIT_FIELD_REF)
3037 bfr = *expr;
3038 expr = &TREE_OPERAND (*expr, 0);
3040 else
3041 bfr = NULL_TREE;
3043 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
3044 expr = &TREE_OPERAND (*expr, 0);
3045 access = get_access_for_expr (*expr);
3046 if (!access)
3047 return false;
3048 type = TREE_TYPE (*expr);
3049 orig_expr = *expr;
3051 loc = gimple_location (gsi_stmt (*gsi));
3052 gimple_stmt_iterator alt_gsi = gsi_none ();
3053 if (write && stmt_ends_bb_p (gsi_stmt (*gsi)))
3055 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
3056 gsi = &alt_gsi;
3059 if (access->grp_to_be_replaced)
3061 tree repl = get_access_replacement (access);
3062 /* If we replace a non-register typed access simply use the original
3063 access expression to extract the scalar component afterwards.
3064 This happens if scalarizing a function return value or parameter
3065 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
3066 gcc.c-torture/compile/20011217-1.c.
3068 We also want to use this when accessing a complex or vector which can
3069 be accessed as a different type too, potentially creating a need for
3070 type conversion (see PR42196) and when scalarized unions are involved
3071 in assembler statements (see PR42398). */
3072 if (!useless_type_conversion_p (type, access->type))
3074 tree ref;
3076 ref = build_ref_for_model (loc, orig_expr, 0, access, gsi, false);
3078 if (write)
3080 gassign *stmt;
3082 if (access->grp_partial_lhs)
3083 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
3084 false, GSI_NEW_STMT);
3085 stmt = gimple_build_assign (repl, ref);
3086 gimple_set_location (stmt, loc);
3087 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
3089 else
3091 gassign *stmt;
3093 if (access->grp_partial_lhs)
3094 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
3095 true, GSI_SAME_STMT);
3096 stmt = gimple_build_assign (ref, repl);
3097 gimple_set_location (stmt, loc);
3098 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
3101 else
3102 *expr = repl;
3103 sra_stats.exprs++;
3105 else if (write && access->grp_to_be_debug_replaced)
3107 gdebug *ds = gimple_build_debug_bind (get_access_replacement (access),
3108 NULL_TREE,
3109 gsi_stmt (*gsi));
3110 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
3113 if (access->first_child)
3115 HOST_WIDE_INT start_offset, chunk_size;
3116 if (bfr
3117 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 1))
3118 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 2)))
3120 chunk_size = tree_to_uhwi (TREE_OPERAND (bfr, 1));
3121 start_offset = access->offset
3122 + tree_to_uhwi (TREE_OPERAND (bfr, 2));
3124 else
3125 start_offset = chunk_size = 0;
3127 generate_subtree_copies (access->first_child, orig_expr, access->offset,
3128 start_offset, chunk_size, gsi, write, write,
3129 loc);
3131 return true;
3134 /* Where scalar replacements of the RHS have been written to when a replacement
3135 of a LHS of an assigments cannot be direclty loaded from a replacement of
3136 the RHS. */
3137 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
3138 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
3139 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
3141 struct subreplacement_assignment_data
3143 /* Offset of the access representing the lhs of the assignment. */
3144 HOST_WIDE_INT left_offset;
3146 /* LHS and RHS of the original assignment. */
3147 tree assignment_lhs, assignment_rhs;
3149 /* Access representing the rhs of the whole assignment. */
3150 struct access *top_racc;
3152 /* Stmt iterator used for statement insertions after the original assignment.
3153 It points to the main GSI used to traverse a BB during function body
3154 modification. */
3155 gimple_stmt_iterator *new_gsi;
3157 /* Stmt iterator used for statement insertions before the original
3158 assignment. Keeps on pointing to the original statement. */
3159 gimple_stmt_iterator old_gsi;
3161 /* Location of the assignment. */
3162 location_t loc;
3164 /* Keeps the information whether we have needed to refresh replacements of
3165 the LHS and from which side of the assignments this takes place. */
3166 enum unscalarized_data_handling refreshed;
3169 /* Store all replacements in the access tree rooted in TOP_RACC either to their
3170 base aggregate if there are unscalarized data or directly to LHS of the
3171 statement that is pointed to by GSI otherwise. */
3173 static void
3174 handle_unscalarized_data_in_subtree (struct subreplacement_assignment_data *sad)
3176 tree src;
3177 if (sad->top_racc->grp_unscalarized_data)
3179 src = sad->assignment_rhs;
3180 sad->refreshed = SRA_UDH_RIGHT;
3182 else
3184 src = sad->assignment_lhs;
3185 sad->refreshed = SRA_UDH_LEFT;
3187 generate_subtree_copies (sad->top_racc->first_child, src,
3188 sad->top_racc->offset, 0, 0,
3189 &sad->old_gsi, false, false, sad->loc);
3192 /* Try to generate statements to load all sub-replacements in an access subtree
3193 formed by children of LACC from scalar replacements in the SAD->top_racc
3194 subtree. If that is not possible, refresh the SAD->top_racc base aggregate
3195 and load the accesses from it. */
3197 static void
3198 load_assign_lhs_subreplacements (struct access *lacc,
3199 struct subreplacement_assignment_data *sad)
3201 for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling)
3203 HOST_WIDE_INT offset;
3204 offset = lacc->offset - sad->left_offset + sad->top_racc->offset;
3206 if (lacc->grp_to_be_replaced)
3208 struct access *racc;
3209 gassign *stmt;
3210 tree rhs;
3212 racc = find_access_in_subtree (sad->top_racc, offset, lacc->size);
3213 if (racc && racc->grp_to_be_replaced)
3215 rhs = get_access_replacement (racc);
3216 if (!useless_type_conversion_p (lacc->type, racc->type))
3217 rhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
3218 lacc->type, rhs);
3220 if (racc->grp_partial_lhs && lacc->grp_partial_lhs)
3221 rhs = force_gimple_operand_gsi (&sad->old_gsi, rhs, true,
3222 NULL_TREE, true, GSI_SAME_STMT);
3224 else
3226 /* No suitable access on the right hand side, need to load from
3227 the aggregate. See if we have to update it first... */
3228 if (sad->refreshed == SRA_UDH_NONE)
3229 handle_unscalarized_data_in_subtree (sad);
3231 if (sad->refreshed == SRA_UDH_LEFT)
3232 rhs = build_ref_for_model (sad->loc, sad->assignment_lhs,
3233 lacc->offset - sad->left_offset,
3234 lacc, sad->new_gsi, true);
3235 else
3236 rhs = build_ref_for_model (sad->loc, sad->assignment_rhs,
3237 lacc->offset - sad->left_offset,
3238 lacc, sad->new_gsi, true);
3239 if (lacc->grp_partial_lhs)
3240 rhs = force_gimple_operand_gsi (sad->new_gsi,
3241 rhs, true, NULL_TREE,
3242 false, GSI_NEW_STMT);
3245 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
3246 gsi_insert_after (sad->new_gsi, stmt, GSI_NEW_STMT);
3247 gimple_set_location (stmt, sad->loc);
3248 update_stmt (stmt);
3249 sra_stats.subreplacements++;
3251 else
3253 if (sad->refreshed == SRA_UDH_NONE
3254 && lacc->grp_read && !lacc->grp_covered)
3255 handle_unscalarized_data_in_subtree (sad);
3257 if (lacc && lacc->grp_to_be_debug_replaced)
3259 gdebug *ds;
3260 tree drhs;
3261 struct access *racc = find_access_in_subtree (sad->top_racc,
3262 offset,
3263 lacc->size);
3265 if (racc && racc->grp_to_be_replaced)
3267 if (racc->grp_write || constant_decl_p (racc->base))
3268 drhs = get_access_replacement (racc);
3269 else
3270 drhs = NULL;
3272 else if (sad->refreshed == SRA_UDH_LEFT)
3273 drhs = build_debug_ref_for_model (sad->loc, lacc->base,
3274 lacc->offset, lacc);
3275 else if (sad->refreshed == SRA_UDH_RIGHT)
3276 drhs = build_debug_ref_for_model (sad->loc, sad->top_racc->base,
3277 offset, lacc);
3278 else
3279 drhs = NULL_TREE;
3280 if (drhs
3281 && !useless_type_conversion_p (lacc->type, TREE_TYPE (drhs)))
3282 drhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
3283 lacc->type, drhs);
3284 ds = gimple_build_debug_bind (get_access_replacement (lacc),
3285 drhs, gsi_stmt (sad->old_gsi));
3286 gsi_insert_after (sad->new_gsi, ds, GSI_NEW_STMT);
3290 if (lacc->first_child)
3291 load_assign_lhs_subreplacements (lacc, sad);
3295 /* Result code for SRA assignment modification. */
3296 enum assignment_mod_result { SRA_AM_NONE, /* nothing done for the stmt */
3297 SRA_AM_MODIFIED, /* stmt changed but not
3298 removed */
3299 SRA_AM_REMOVED }; /* stmt eliminated */
3301 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
3302 to the assignment and GSI is the statement iterator pointing at it. Returns
3303 the same values as sra_modify_assign. */
3305 static enum assignment_mod_result
3306 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3308 tree lhs = gimple_assign_lhs (stmt);
3309 struct access *acc = get_access_for_expr (lhs);
3310 if (!acc)
3311 return SRA_AM_NONE;
3312 location_t loc = gimple_location (stmt);
3314 if (gimple_clobber_p (stmt))
3316 /* Clobber the replacement variable. */
3317 clobber_subtree (acc, gsi, !acc->grp_covered, loc);
3318 /* Remove clobbers of fully scalarized variables, they are dead. */
3319 if (acc->grp_covered)
3321 unlink_stmt_vdef (stmt);
3322 gsi_remove (gsi, true);
3323 release_defs (stmt);
3324 return SRA_AM_REMOVED;
3326 else
3327 return SRA_AM_MODIFIED;
3330 if (CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt)) > 0)
3332 /* I have never seen this code path trigger but if it can happen the
3333 following should handle it gracefully. */
3334 if (access_has_children_p (acc))
3335 generate_subtree_copies (acc->first_child, lhs, acc->offset, 0, 0, gsi,
3336 true, true, loc);
3337 return SRA_AM_MODIFIED;
3340 if (acc->grp_covered)
3342 init_subtree_with_zero (acc, gsi, false, loc);
3343 unlink_stmt_vdef (stmt);
3344 gsi_remove (gsi, true);
3345 release_defs (stmt);
3346 return SRA_AM_REMOVED;
3348 else
3350 init_subtree_with_zero (acc, gsi, true, loc);
3351 return SRA_AM_MODIFIED;
3355 /* Create and return a new suitable default definition SSA_NAME for RACC which
3356 is an access describing an uninitialized part of an aggregate that is being
3357 loaded. */
3359 static tree
3360 get_repl_default_def_ssa_name (struct access *racc)
3362 gcc_checking_assert (!racc->grp_to_be_replaced
3363 && !racc->grp_to_be_debug_replaced);
3364 if (!racc->replacement_decl)
3365 racc->replacement_decl = create_access_replacement (racc);
3366 return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
3369 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3370 bit-field field declaration somewhere in it. */
3372 static inline bool
3373 contains_vce_or_bfcref_p (const_tree ref)
3375 while (handled_component_p (ref))
3377 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
3378 || (TREE_CODE (ref) == COMPONENT_REF
3379 && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
3380 return true;
3381 ref = TREE_OPERAND (ref, 0);
3384 return false;
3387 /* Examine both sides of the assignment statement pointed to by STMT, replace
3388 them with a scalare replacement if there is one and generate copying of
3389 replacements if scalarized aggregates have been used in the assignment. GSI
3390 is used to hold generated statements for type conversions and subtree
3391 copying. */
3393 static enum assignment_mod_result
3394 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3396 struct access *lacc, *racc;
3397 tree lhs, rhs;
3398 bool modify_this_stmt = false;
3399 bool force_gimple_rhs = false;
3400 location_t loc;
3401 gimple_stmt_iterator orig_gsi = *gsi;
3403 if (!gimple_assign_single_p (stmt))
3404 return SRA_AM_NONE;
3405 lhs = gimple_assign_lhs (stmt);
3406 rhs = gimple_assign_rhs1 (stmt);
3408 if (TREE_CODE (rhs) == CONSTRUCTOR)
3409 return sra_modify_constructor_assign (stmt, gsi);
3411 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
3412 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
3413 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
3415 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (stmt),
3416 gsi, false);
3417 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (stmt),
3418 gsi, true);
3419 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3422 lacc = get_access_for_expr (lhs);
3423 racc = get_access_for_expr (rhs);
3424 if (!lacc && !racc)
3425 return SRA_AM_NONE;
3426 /* Avoid modifying initializations of constant-pool replacements. */
3427 if (racc && (racc->replacement_decl == lhs))
3428 return SRA_AM_NONE;
3430 loc = gimple_location (stmt);
3431 if (lacc && lacc->grp_to_be_replaced)
3433 lhs = get_access_replacement (lacc);
3434 gimple_assign_set_lhs (stmt, lhs);
3435 modify_this_stmt = true;
3436 if (lacc->grp_partial_lhs)
3437 force_gimple_rhs = true;
3438 sra_stats.exprs++;
3441 if (racc && racc->grp_to_be_replaced)
3443 rhs = get_access_replacement (racc);
3444 modify_this_stmt = true;
3445 if (racc->grp_partial_lhs)
3446 force_gimple_rhs = true;
3447 sra_stats.exprs++;
3449 else if (racc
3450 && !racc->grp_unscalarized_data
3451 && !racc->grp_unscalarizable_region
3452 && TREE_CODE (lhs) == SSA_NAME
3453 && !access_has_replacements_p (racc))
3455 rhs = get_repl_default_def_ssa_name (racc);
3456 modify_this_stmt = true;
3457 sra_stats.exprs++;
3460 if (modify_this_stmt)
3462 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3464 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3465 ??? This should move to fold_stmt which we simply should
3466 call after building a VIEW_CONVERT_EXPR here. */
3467 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
3468 && !contains_bitfld_component_ref_p (lhs))
3470 lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
3471 gimple_assign_set_lhs (stmt, lhs);
3473 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
3474 && !contains_vce_or_bfcref_p (rhs))
3475 rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
3477 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3479 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
3480 rhs);
3481 if (is_gimple_reg_type (TREE_TYPE (lhs))
3482 && TREE_CODE (lhs) != SSA_NAME)
3483 force_gimple_rhs = true;
3488 if (lacc && lacc->grp_to_be_debug_replaced)
3490 tree dlhs = get_access_replacement (lacc);
3491 tree drhs = unshare_expr (rhs);
3492 if (!useless_type_conversion_p (TREE_TYPE (dlhs), TREE_TYPE (drhs)))
3494 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs))
3495 && !contains_vce_or_bfcref_p (drhs))
3496 drhs = build_debug_ref_for_model (loc, drhs, 0, lacc);
3497 if (drhs
3498 && !useless_type_conversion_p (TREE_TYPE (dlhs),
3499 TREE_TYPE (drhs)))
3500 drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
3501 TREE_TYPE (dlhs), drhs);
3503 gdebug *ds = gimple_build_debug_bind (dlhs, drhs, stmt);
3504 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3507 /* From this point on, the function deals with assignments in between
3508 aggregates when at least one has scalar reductions of some of its
3509 components. There are three possible scenarios: Both the LHS and RHS have
3510 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3512 In the first case, we would like to load the LHS components from RHS
3513 components whenever possible. If that is not possible, we would like to
3514 read it directly from the RHS (after updating it by storing in it its own
3515 components). If there are some necessary unscalarized data in the LHS,
3516 those will be loaded by the original assignment too. If neither of these
3517 cases happen, the original statement can be removed. Most of this is done
3518 by load_assign_lhs_subreplacements.
3520 In the second case, we would like to store all RHS scalarized components
3521 directly into LHS and if they cover the aggregate completely, remove the
3522 statement too. In the third case, we want the LHS components to be loaded
3523 directly from the RHS (DSE will remove the original statement if it
3524 becomes redundant).
3526 This is a bit complex but manageable when types match and when unions do
3527 not cause confusion in a way that we cannot really load a component of LHS
3528 from the RHS or vice versa (the access representing this level can have
3529 subaccesses that are accessible only through a different union field at a
3530 higher level - different from the one used in the examined expression).
3531 Unions are fun.
3533 Therefore, I specially handle a fourth case, happening when there is a
3534 specific type cast or it is impossible to locate a scalarized subaccess on
3535 the other side of the expression. If that happens, I simply "refresh" the
3536 RHS by storing in it is scalarized components leave the original statement
3537 there to do the copying and then load the scalar replacements of the LHS.
3538 This is what the first branch does. */
3540 if (modify_this_stmt
3541 || gimple_has_volatile_ops (stmt)
3542 || contains_vce_or_bfcref_p (rhs)
3543 || contains_vce_or_bfcref_p (lhs)
3544 || stmt_ends_bb_p (stmt))
3546 /* No need to copy into a constant-pool, it comes pre-initialized. */
3547 if (access_has_children_p (racc) && !constant_decl_p (racc->base))
3548 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3549 gsi, false, false, loc);
3550 if (access_has_children_p (lacc))
3552 gimple_stmt_iterator alt_gsi = gsi_none ();
3553 if (stmt_ends_bb_p (stmt))
3555 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
3556 gsi = &alt_gsi;
3558 generate_subtree_copies (lacc->first_child, lhs, lacc->offset, 0, 0,
3559 gsi, true, true, loc);
3561 sra_stats.separate_lhs_rhs_handling++;
3563 /* This gimplification must be done after generate_subtree_copies,
3564 lest we insert the subtree copies in the middle of the gimplified
3565 sequence. */
3566 if (force_gimple_rhs)
3567 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
3568 true, GSI_SAME_STMT);
3569 if (gimple_assign_rhs1 (stmt) != rhs)
3571 modify_this_stmt = true;
3572 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
3573 gcc_assert (stmt == gsi_stmt (orig_gsi));
3576 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3578 else
3580 if (access_has_children_p (lacc)
3581 && access_has_children_p (racc)
3582 /* When an access represents an unscalarizable region, it usually
3583 represents accesses with variable offset and thus must not be used
3584 to generate new memory accesses. */
3585 && !lacc->grp_unscalarizable_region
3586 && !racc->grp_unscalarizable_region)
3588 struct subreplacement_assignment_data sad;
3590 sad.left_offset = lacc->offset;
3591 sad.assignment_lhs = lhs;
3592 sad.assignment_rhs = rhs;
3593 sad.top_racc = racc;
3594 sad.old_gsi = *gsi;
3595 sad.new_gsi = gsi;
3596 sad.loc = gimple_location (stmt);
3597 sad.refreshed = SRA_UDH_NONE;
3599 if (lacc->grp_read && !lacc->grp_covered)
3600 handle_unscalarized_data_in_subtree (&sad);
3602 load_assign_lhs_subreplacements (lacc, &sad);
3603 if (sad.refreshed != SRA_UDH_RIGHT)
3605 gsi_next (gsi);
3606 unlink_stmt_vdef (stmt);
3607 gsi_remove (&sad.old_gsi, true);
3608 release_defs (stmt);
3609 sra_stats.deleted++;
3610 return SRA_AM_REMOVED;
3613 else
3615 if (access_has_children_p (racc)
3616 && !racc->grp_unscalarized_data
3617 && TREE_CODE (lhs) != SSA_NAME)
3619 if (dump_file)
3621 fprintf (dump_file, "Removing load: ");
3622 print_gimple_stmt (dump_file, stmt, 0);
3624 generate_subtree_copies (racc->first_child, lhs,
3625 racc->offset, 0, 0, gsi,
3626 false, false, loc);
3627 gcc_assert (stmt == gsi_stmt (*gsi));
3628 unlink_stmt_vdef (stmt);
3629 gsi_remove (gsi, true);
3630 release_defs (stmt);
3631 sra_stats.deleted++;
3632 return SRA_AM_REMOVED;
3634 /* Restore the aggregate RHS from its components so the
3635 prevailing aggregate copy does the right thing. */
3636 if (access_has_children_p (racc))
3637 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3638 gsi, false, false, loc);
3639 /* Re-load the components of the aggregate copy destination.
3640 But use the RHS aggregate to load from to expose more
3641 optimization opportunities. */
3642 if (access_has_children_p (lacc))
3643 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
3644 0, 0, gsi, true, true, loc);
3647 return SRA_AM_NONE;
3651 /* Set any scalar replacements of values in the constant pool to the initial
3652 value of the constant. (Constant-pool decls like *.LC0 have effectively
3653 been initialized before the program starts, we must do the same for their
3654 replacements.) Thus, we output statements like 'SR.1 = *.LC0[0];' into
3655 the function's entry block. */
3657 static void
3658 initialize_constant_pool_replacements (void)
3660 gimple_seq seq = NULL;
3661 gimple_stmt_iterator gsi = gsi_start (seq);
3662 bitmap_iterator bi;
3663 unsigned i;
3665 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
3667 tree var = candidate (i);
3668 if (!constant_decl_p (var))
3669 continue;
3670 vec<access_p> *access_vec = get_base_access_vector (var);
3671 if (!access_vec)
3672 continue;
3673 for (unsigned i = 0; i < access_vec->length (); i++)
3675 struct access *access = (*access_vec)[i];
3676 if (!access->replacement_decl)
3677 continue;
3678 gassign *stmt
3679 = gimple_build_assign (get_access_replacement (access),
3680 unshare_expr (access->expr));
3681 if (dump_file && (dump_flags & TDF_DETAILS))
3683 fprintf (dump_file, "Generating constant initializer: ");
3684 print_gimple_stmt (dump_file, stmt, 0);
3685 fprintf (dump_file, "\n");
3687 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
3688 update_stmt (stmt);
3692 seq = gsi_seq (gsi);
3693 if (seq)
3694 gsi_insert_seq_on_edge_immediate (
3695 single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3698 /* Traverse the function body and all modifications as decided in
3699 analyze_all_variable_accesses. Return true iff the CFG has been
3700 changed. */
3702 static bool
3703 sra_modify_function_body (void)
3705 bool cfg_changed = false;
3706 basic_block bb;
3708 initialize_constant_pool_replacements ();
3710 FOR_EACH_BB_FN (bb, cfun)
3712 gimple_stmt_iterator gsi = gsi_start_bb (bb);
3713 while (!gsi_end_p (gsi))
3715 gimple *stmt = gsi_stmt (gsi);
3716 enum assignment_mod_result assign_result;
3717 bool modified = false, deleted = false;
3718 tree *t;
3719 unsigned i;
3721 switch (gimple_code (stmt))
3723 case GIMPLE_RETURN:
3724 t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
3725 if (*t != NULL_TREE)
3726 modified |= sra_modify_expr (t, &gsi, false);
3727 break;
3729 case GIMPLE_ASSIGN:
3730 assign_result = sra_modify_assign (stmt, &gsi);
3731 modified |= assign_result == SRA_AM_MODIFIED;
3732 deleted = assign_result == SRA_AM_REMOVED;
3733 break;
3735 case GIMPLE_CALL:
3736 /* Operands must be processed before the lhs. */
3737 for (i = 0; i < gimple_call_num_args (stmt); i++)
3739 t = gimple_call_arg_ptr (stmt, i);
3740 modified |= sra_modify_expr (t, &gsi, false);
3743 if (gimple_call_lhs (stmt))
3745 t = gimple_call_lhs_ptr (stmt);
3746 modified |= sra_modify_expr (t, &gsi, true);
3748 break;
3750 case GIMPLE_ASM:
3752 gasm *asm_stmt = as_a <gasm *> (stmt);
3753 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
3755 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
3756 modified |= sra_modify_expr (t, &gsi, false);
3758 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
3760 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
3761 modified |= sra_modify_expr (t, &gsi, true);
3764 break;
3766 default:
3767 break;
3770 if (modified)
3772 update_stmt (stmt);
3773 if (maybe_clean_eh_stmt (stmt)
3774 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
3775 cfg_changed = true;
3777 if (!deleted)
3778 gsi_next (&gsi);
3782 gsi_commit_edge_inserts ();
3783 return cfg_changed;
3786 /* Generate statements initializing scalar replacements of parts of function
3787 parameters. */
3789 static void
3790 initialize_parameter_reductions (void)
3792 gimple_stmt_iterator gsi;
3793 gimple_seq seq = NULL;
3794 tree parm;
3796 gsi = gsi_start (seq);
3797 for (parm = DECL_ARGUMENTS (current_function_decl);
3798 parm;
3799 parm = DECL_CHAIN (parm))
3801 vec<access_p> *access_vec;
3802 struct access *access;
3804 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3805 continue;
3806 access_vec = get_base_access_vector (parm);
3807 if (!access_vec)
3808 continue;
3810 for (access = (*access_vec)[0];
3811 access;
3812 access = access->next_grp)
3813 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true,
3814 EXPR_LOCATION (parm));
3817 seq = gsi_seq (gsi);
3818 if (seq)
3819 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3822 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3823 it reveals there are components of some aggregates to be scalarized, it runs
3824 the required transformations. */
3825 static unsigned int
3826 perform_intra_sra (void)
3828 int ret = 0;
3829 sra_initialize ();
3831 if (!find_var_candidates ())
3832 goto out;
3834 if (!scan_function ())
3835 goto out;
3837 if (!analyze_all_variable_accesses ())
3838 goto out;
3840 if (sra_modify_function_body ())
3841 ret = TODO_update_ssa | TODO_cleanup_cfg;
3842 else
3843 ret = TODO_update_ssa;
3844 initialize_parameter_reductions ();
3846 statistics_counter_event (cfun, "Scalar replacements created",
3847 sra_stats.replacements);
3848 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
3849 statistics_counter_event (cfun, "Subtree copy stmts",
3850 sra_stats.subtree_copies);
3851 statistics_counter_event (cfun, "Subreplacement stmts",
3852 sra_stats.subreplacements);
3853 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
3854 statistics_counter_event (cfun, "Separate LHS and RHS handling",
3855 sra_stats.separate_lhs_rhs_handling);
3857 out:
3858 sra_deinitialize ();
3859 return ret;
3862 /* Perform early intraprocedural SRA. */
3863 static unsigned int
3864 early_intra_sra (void)
3866 sra_mode = SRA_MODE_EARLY_INTRA;
3867 return perform_intra_sra ();
3870 /* Perform "late" intraprocedural SRA. */
3871 static unsigned int
3872 late_intra_sra (void)
3874 sra_mode = SRA_MODE_INTRA;
3875 return perform_intra_sra ();
3879 static bool
3880 gate_intra_sra (void)
3882 return flag_tree_sra != 0 && dbg_cnt (tree_sra);
3886 namespace {
3888 const pass_data pass_data_sra_early =
3890 GIMPLE_PASS, /* type */
3891 "esra", /* name */
3892 OPTGROUP_NONE, /* optinfo_flags */
3893 TV_TREE_SRA, /* tv_id */
3894 ( PROP_cfg | PROP_ssa ), /* properties_required */
3895 0, /* properties_provided */
3896 0, /* properties_destroyed */
3897 0, /* todo_flags_start */
3898 TODO_update_ssa, /* todo_flags_finish */
3901 class pass_sra_early : public gimple_opt_pass
3903 public:
3904 pass_sra_early (gcc::context *ctxt)
3905 : gimple_opt_pass (pass_data_sra_early, ctxt)
3908 /* opt_pass methods: */
3909 virtual bool gate (function *) { return gate_intra_sra (); }
3910 virtual unsigned int execute (function *) { return early_intra_sra (); }
3912 }; // class pass_sra_early
3914 } // anon namespace
3916 gimple_opt_pass *
3917 make_pass_sra_early (gcc::context *ctxt)
3919 return new pass_sra_early (ctxt);
3922 namespace {
3924 const pass_data pass_data_sra =
3926 GIMPLE_PASS, /* type */
3927 "sra", /* name */
3928 OPTGROUP_NONE, /* optinfo_flags */
3929 TV_TREE_SRA, /* tv_id */
3930 ( PROP_cfg | PROP_ssa ), /* properties_required */
3931 0, /* properties_provided */
3932 0, /* properties_destroyed */
3933 TODO_update_address_taken, /* todo_flags_start */
3934 TODO_update_ssa, /* todo_flags_finish */
3937 class pass_sra : public gimple_opt_pass
3939 public:
3940 pass_sra (gcc::context *ctxt)
3941 : gimple_opt_pass (pass_data_sra, ctxt)
3944 /* opt_pass methods: */
3945 virtual bool gate (function *) { return gate_intra_sra (); }
3946 virtual unsigned int execute (function *) { return late_intra_sra (); }
3948 }; // class pass_sra
3950 } // anon namespace
3952 gimple_opt_pass *
3953 make_pass_sra (gcc::context *ctxt)
3955 return new pass_sra (ctxt);
3959 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3960 parameter. */
3962 static bool
3963 is_unused_scalar_param (tree parm)
3965 tree name;
3966 return (is_gimple_reg (parm)
3967 && (!(name = ssa_default_def (cfun, parm))
3968 || has_zero_uses (name)));
3971 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3972 examine whether there are any direct or otherwise infeasible ones. If so,
3973 return true, otherwise return false. PARM must be a gimple register with a
3974 non-NULL default definition. */
3976 static bool
3977 ptr_parm_has_direct_uses (tree parm)
3979 imm_use_iterator ui;
3980 gimple *stmt;
3981 tree name = ssa_default_def (cfun, parm);
3982 bool ret = false;
3984 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
3986 int uses_ok = 0;
3987 use_operand_p use_p;
3989 if (is_gimple_debug (stmt))
3990 continue;
3992 /* Valid uses include dereferences on the lhs and the rhs. */
3993 if (gimple_has_lhs (stmt))
3995 tree lhs = gimple_get_lhs (stmt);
3996 while (handled_component_p (lhs))
3997 lhs = TREE_OPERAND (lhs, 0);
3998 if (TREE_CODE (lhs) == MEM_REF
3999 && TREE_OPERAND (lhs, 0) == name
4000 && integer_zerop (TREE_OPERAND (lhs, 1))
4001 && types_compatible_p (TREE_TYPE (lhs),
4002 TREE_TYPE (TREE_TYPE (name)))
4003 && !TREE_THIS_VOLATILE (lhs))
4004 uses_ok++;
4006 if (gimple_assign_single_p (stmt))
4008 tree rhs = gimple_assign_rhs1 (stmt);
4009 while (handled_component_p (rhs))
4010 rhs = TREE_OPERAND (rhs, 0);
4011 if (TREE_CODE (rhs) == MEM_REF
4012 && TREE_OPERAND (rhs, 0) == name
4013 && integer_zerop (TREE_OPERAND (rhs, 1))
4014 && types_compatible_p (TREE_TYPE (rhs),
4015 TREE_TYPE (TREE_TYPE (name)))
4016 && !TREE_THIS_VOLATILE (rhs))
4017 uses_ok++;
4019 else if (is_gimple_call (stmt))
4021 unsigned i;
4022 for (i = 0; i < gimple_call_num_args (stmt); ++i)
4024 tree arg = gimple_call_arg (stmt, i);
4025 while (handled_component_p (arg))
4026 arg = TREE_OPERAND (arg, 0);
4027 if (TREE_CODE (arg) == MEM_REF
4028 && TREE_OPERAND (arg, 0) == name
4029 && integer_zerop (TREE_OPERAND (arg, 1))
4030 && types_compatible_p (TREE_TYPE (arg),
4031 TREE_TYPE (TREE_TYPE (name)))
4032 && !TREE_THIS_VOLATILE (arg))
4033 uses_ok++;
4037 /* If the number of valid uses does not match the number of
4038 uses in this stmt there is an unhandled use. */
4039 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
4040 --uses_ok;
4042 if (uses_ok != 0)
4043 ret = true;
4045 if (ret)
4046 BREAK_FROM_IMM_USE_STMT (ui);
4049 return ret;
4052 /* Identify candidates for reduction for IPA-SRA based on their type and mark
4053 them in candidate_bitmap. Note that these do not necessarily include
4054 parameter which are unused and thus can be removed. Return true iff any
4055 such candidate has been found. */
4057 static bool
4058 find_param_candidates (void)
4060 tree parm;
4061 int count = 0;
4062 bool ret = false;
4063 const char *msg;
4065 for (parm = DECL_ARGUMENTS (current_function_decl);
4066 parm;
4067 parm = DECL_CHAIN (parm))
4069 tree type = TREE_TYPE (parm);
4070 tree_node **slot;
4072 count++;
4074 if (TREE_THIS_VOLATILE (parm)
4075 || TREE_ADDRESSABLE (parm)
4076 || (!is_gimple_reg_type (type) && is_va_list_type (type)))
4077 continue;
4079 if (is_unused_scalar_param (parm))
4081 ret = true;
4082 continue;
4085 if (POINTER_TYPE_P (type))
4087 type = TREE_TYPE (type);
4089 if (TREE_CODE (type) == FUNCTION_TYPE
4090 || TYPE_VOLATILE (type)
4091 || (TREE_CODE (type) == ARRAY_TYPE
4092 && TYPE_NONALIASED_COMPONENT (type))
4093 || !is_gimple_reg (parm)
4094 || is_va_list_type (type)
4095 || ptr_parm_has_direct_uses (parm))
4096 continue;
4098 else if (!AGGREGATE_TYPE_P (type))
4099 continue;
4101 if (!COMPLETE_TYPE_P (type)
4102 || !tree_fits_uhwi_p (TYPE_SIZE (type))
4103 || tree_to_uhwi (TYPE_SIZE (type)) == 0
4104 || (AGGREGATE_TYPE_P (type)
4105 && type_internals_preclude_sra_p (type, &msg)))
4106 continue;
4108 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
4109 slot = candidates->find_slot_with_hash (parm, DECL_UID (parm), INSERT);
4110 *slot = parm;
4112 ret = true;
4113 if (dump_file && (dump_flags & TDF_DETAILS))
4115 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
4116 print_generic_expr (dump_file, parm);
4117 fprintf (dump_file, "\n");
4121 func_param_count = count;
4122 return ret;
4125 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
4126 maybe_modified. */
4128 static bool
4129 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
4130 void *data)
4132 struct access *repr = (struct access *) data;
4134 repr->grp_maybe_modified = 1;
4135 return true;
4138 /* Analyze what representatives (in linked lists accessible from
4139 REPRESENTATIVES) can be modified by side effects of statements in the
4140 current function. */
4142 static void
4143 analyze_modified_params (vec<access_p> representatives)
4145 int i;
4147 for (i = 0; i < func_param_count; i++)
4149 struct access *repr;
4151 for (repr = representatives[i];
4152 repr;
4153 repr = repr->next_grp)
4155 struct access *access;
4156 bitmap visited;
4157 ao_ref ar;
4159 if (no_accesses_p (repr))
4160 continue;
4161 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
4162 || repr->grp_maybe_modified)
4163 continue;
4165 ao_ref_init (&ar, repr->expr);
4166 visited = BITMAP_ALLOC (NULL);
4167 for (access = repr; access; access = access->next_sibling)
4169 /* All accesses are read ones, otherwise grp_maybe_modified would
4170 be trivially set. */
4171 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
4172 mark_maybe_modified, repr, &visited);
4173 if (repr->grp_maybe_modified)
4174 break;
4176 BITMAP_FREE (visited);
4181 /* Propagate distances in bb_dereferences in the opposite direction than the
4182 control flow edges, in each step storing the maximum of the current value
4183 and the minimum of all successors. These steps are repeated until the table
4184 stabilizes. Note that BBs which might terminate the functions (according to
4185 final_bbs bitmap) never updated in this way. */
4187 static void
4188 propagate_dereference_distances (void)
4190 basic_block bb;
4192 auto_vec<basic_block> queue (last_basic_block_for_fn (cfun));
4193 queue.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun));
4194 FOR_EACH_BB_FN (bb, cfun)
4196 queue.quick_push (bb);
4197 bb->aux = bb;
4200 while (!queue.is_empty ())
4202 edge_iterator ei;
4203 edge e;
4204 bool change = false;
4205 int i;
4207 bb = queue.pop ();
4208 bb->aux = NULL;
4210 if (bitmap_bit_p (final_bbs, bb->index))
4211 continue;
4213 for (i = 0; i < func_param_count; i++)
4215 int idx = bb->index * func_param_count + i;
4216 bool first = true;
4217 HOST_WIDE_INT inh = 0;
4219 FOR_EACH_EDGE (e, ei, bb->succs)
4221 int succ_idx = e->dest->index * func_param_count + i;
4223 if (e->src == EXIT_BLOCK_PTR_FOR_FN (cfun))
4224 continue;
4226 if (first)
4228 first = false;
4229 inh = bb_dereferences [succ_idx];
4231 else if (bb_dereferences [succ_idx] < inh)
4232 inh = bb_dereferences [succ_idx];
4235 if (!first && bb_dereferences[idx] < inh)
4237 bb_dereferences[idx] = inh;
4238 change = true;
4242 if (change && !bitmap_bit_p (final_bbs, bb->index))
4243 FOR_EACH_EDGE (e, ei, bb->preds)
4245 if (e->src->aux)
4246 continue;
4248 e->src->aux = e->src;
4249 queue.quick_push (e->src);
4254 /* Dump a dereferences TABLE with heading STR to file F. */
4256 static void
4257 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
4259 basic_block bb;
4261 fprintf (dump_file, "%s", str);
4262 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
4263 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
4265 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
4266 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
4268 int i;
4269 for (i = 0; i < func_param_count; i++)
4271 int idx = bb->index * func_param_count + i;
4272 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
4275 fprintf (f, "\n");
4277 fprintf (dump_file, "\n");
4280 /* Determine what (parts of) parameters passed by reference that are not
4281 assigned to are not certainly dereferenced in this function and thus the
4282 dereferencing cannot be safely moved to the caller without potentially
4283 introducing a segfault. Mark such REPRESENTATIVES as
4284 grp_not_necessarilly_dereferenced.
4286 The dereferenced maximum "distance," i.e. the offset + size of the accessed
4287 part is calculated rather than simple booleans are calculated for each
4288 pointer parameter to handle cases when only a fraction of the whole
4289 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
4290 an example).
4292 The maximum dereference distances for each pointer parameter and BB are
4293 already stored in bb_dereference. This routine simply propagates these
4294 values upwards by propagate_dereference_distances and then compares the
4295 distances of individual parameters in the ENTRY BB to the equivalent
4296 distances of each representative of a (fraction of a) parameter. */
4298 static void
4299 analyze_caller_dereference_legality (vec<access_p> representatives)
4301 int i;
4303 if (dump_file && (dump_flags & TDF_DETAILS))
4304 dump_dereferences_table (dump_file,
4305 "Dereference table before propagation:\n",
4306 bb_dereferences);
4308 propagate_dereference_distances ();
4310 if (dump_file && (dump_flags & TDF_DETAILS))
4311 dump_dereferences_table (dump_file,
4312 "Dereference table after propagation:\n",
4313 bb_dereferences);
4315 for (i = 0; i < func_param_count; i++)
4317 struct access *repr = representatives[i];
4318 int idx = ENTRY_BLOCK_PTR_FOR_FN (cfun)->index * func_param_count + i;
4320 if (!repr || no_accesses_p (repr))
4321 continue;
4325 if ((repr->offset + repr->size) > bb_dereferences[idx])
4326 repr->grp_not_necessarilly_dereferenced = 1;
4327 repr = repr->next_grp;
4329 while (repr);
4333 /* Return the representative access for the parameter declaration PARM if it is
4334 a scalar passed by reference which is not written to and the pointer value
4335 is not used directly. Thus, if it is legal to dereference it in the caller
4336 and we can rule out modifications through aliases, such parameter should be
4337 turned into one passed by value. Return NULL otherwise. */
4339 static struct access *
4340 unmodified_by_ref_scalar_representative (tree parm)
4342 int i, access_count;
4343 struct access *repr;
4344 vec<access_p> *access_vec;
4346 access_vec = get_base_access_vector (parm);
4347 gcc_assert (access_vec);
4348 repr = (*access_vec)[0];
4349 if (repr->write)
4350 return NULL;
4351 repr->group_representative = repr;
4353 access_count = access_vec->length ();
4354 for (i = 1; i < access_count; i++)
4356 struct access *access = (*access_vec)[i];
4357 if (access->write)
4358 return NULL;
4359 access->group_representative = repr;
4360 access->next_sibling = repr->next_sibling;
4361 repr->next_sibling = access;
4364 repr->grp_read = 1;
4365 repr->grp_scalar_ptr = 1;
4366 return repr;
4369 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
4370 associated with. REQ_ALIGN is the minimum required alignment. */
4372 static bool
4373 access_precludes_ipa_sra_p (struct access *access, unsigned int req_align)
4375 unsigned int exp_align;
4376 /* Avoid issues such as the second simple testcase in PR 42025. The problem
4377 is incompatible assign in a call statement (and possibly even in asm
4378 statements). This can be relaxed by using a new temporary but only for
4379 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
4380 intraprocedural SRA we deal with this by keeping the old aggregate around,
4381 something we cannot do in IPA-SRA.) */
4382 if (access->write
4383 && (is_gimple_call (access->stmt)
4384 || gimple_code (access->stmt) == GIMPLE_ASM))
4385 return true;
4387 exp_align = get_object_alignment (access->expr);
4388 if (exp_align < req_align)
4389 return true;
4391 return false;
4395 /* Sort collected accesses for parameter PARM, identify representatives for
4396 each accessed region and link them together. Return NULL if there are
4397 different but overlapping accesses, return the special ptr value meaning
4398 there are no accesses for this parameter if that is the case and return the
4399 first representative otherwise. Set *RO_GRP if there is a group of accesses
4400 with only read (i.e. no write) accesses. */
4402 static struct access *
4403 splice_param_accesses (tree parm, bool *ro_grp)
4405 int i, j, access_count, group_count;
4406 int agg_size, total_size = 0;
4407 struct access *access, *res, **prev_acc_ptr = &res;
4408 vec<access_p> *access_vec;
4410 access_vec = get_base_access_vector (parm);
4411 if (!access_vec)
4412 return &no_accesses_representant;
4413 access_count = access_vec->length ();
4415 access_vec->qsort (compare_access_positions);
4417 i = 0;
4418 total_size = 0;
4419 group_count = 0;
4420 while (i < access_count)
4422 bool modification;
4423 tree a1_alias_type;
4424 access = (*access_vec)[i];
4425 modification = access->write;
4426 if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type)))
4427 return NULL;
4428 a1_alias_type = reference_alias_ptr_type (access->expr);
4430 /* Access is about to become group representative unless we find some
4431 nasty overlap which would preclude us from breaking this parameter
4432 apart. */
4434 j = i + 1;
4435 while (j < access_count)
4437 struct access *ac2 = (*access_vec)[j];
4438 if (ac2->offset != access->offset)
4440 /* All or nothing law for parameters. */
4441 if (access->offset + access->size > ac2->offset)
4442 return NULL;
4443 else
4444 break;
4446 else if (ac2->size != access->size)
4447 return NULL;
4449 if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type))
4450 || (ac2->type != access->type
4451 && (TREE_ADDRESSABLE (ac2->type)
4452 || TREE_ADDRESSABLE (access->type)))
4453 || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
4454 return NULL;
4456 modification |= ac2->write;
4457 ac2->group_representative = access;
4458 ac2->next_sibling = access->next_sibling;
4459 access->next_sibling = ac2;
4460 j++;
4463 group_count++;
4464 access->grp_maybe_modified = modification;
4465 if (!modification)
4466 *ro_grp = true;
4467 *prev_acc_ptr = access;
4468 prev_acc_ptr = &access->next_grp;
4469 total_size += access->size;
4470 i = j;
4473 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4474 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4475 else
4476 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4477 if (total_size >= agg_size)
4478 return NULL;
4480 gcc_assert (group_count > 0);
4481 return res;
4484 /* Decide whether parameters with representative accesses given by REPR should
4485 be reduced into components. */
4487 static int
4488 decide_one_param_reduction (struct access *repr)
4490 int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
4491 bool by_ref;
4492 tree parm;
4494 parm = repr->base;
4495 cur_parm_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4496 gcc_assert (cur_parm_size > 0);
4498 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4500 by_ref = true;
4501 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4503 else
4505 by_ref = false;
4506 agg_size = cur_parm_size;
4509 if (dump_file)
4511 struct access *acc;
4512 fprintf (dump_file, "Evaluating PARAM group sizes for ");
4513 print_generic_expr (dump_file, parm);
4514 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
4515 for (acc = repr; acc; acc = acc->next_grp)
4516 dump_access (dump_file, acc, true);
4519 total_size = 0;
4520 new_param_count = 0;
4522 for (; repr; repr = repr->next_grp)
4524 gcc_assert (parm == repr->base);
4526 /* Taking the address of a non-addressable field is verboten. */
4527 if (by_ref && repr->non_addressable)
4528 return 0;
4530 /* Do not decompose a non-BLKmode param in a way that would
4531 create BLKmode params. Especially for by-reference passing
4532 (thus, pointer-type param) this is hardly worthwhile. */
4533 if (DECL_MODE (parm) != BLKmode
4534 && TYPE_MODE (repr->type) == BLKmode)
4535 return 0;
4537 if (!by_ref || (!repr->grp_maybe_modified
4538 && !repr->grp_not_necessarilly_dereferenced))
4539 total_size += repr->size;
4540 else
4541 total_size += cur_parm_size;
4543 new_param_count++;
4546 gcc_assert (new_param_count > 0);
4548 if (optimize_function_for_size_p (cfun))
4549 parm_size_limit = cur_parm_size;
4550 else
4551 parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
4552 * cur_parm_size);
4554 if (total_size < agg_size
4555 && total_size <= parm_size_limit)
4557 if (dump_file)
4558 fprintf (dump_file, " ....will be split into %i components\n",
4559 new_param_count);
4560 return new_param_count;
4562 else
4563 return 0;
4566 /* The order of the following enums is important, we need to do extra work for
4567 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4568 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
4569 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
4571 /* Identify representatives of all accesses to all candidate parameters for
4572 IPA-SRA. Return result based on what representatives have been found. */
4574 static enum ipa_splicing_result
4575 splice_all_param_accesses (vec<access_p> &representatives)
4577 enum ipa_splicing_result result = NO_GOOD_ACCESS;
4578 tree parm;
4579 struct access *repr;
4581 representatives.create (func_param_count);
4583 for (parm = DECL_ARGUMENTS (current_function_decl);
4584 parm;
4585 parm = DECL_CHAIN (parm))
4587 if (is_unused_scalar_param (parm))
4589 representatives.quick_push (&no_accesses_representant);
4590 if (result == NO_GOOD_ACCESS)
4591 result = UNUSED_PARAMS;
4593 else if (POINTER_TYPE_P (TREE_TYPE (parm))
4594 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
4595 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4597 repr = unmodified_by_ref_scalar_representative (parm);
4598 representatives.quick_push (repr);
4599 if (repr)
4600 result = UNMODIF_BY_REF_ACCESSES;
4602 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4604 bool ro_grp = false;
4605 repr = splice_param_accesses (parm, &ro_grp);
4606 representatives.quick_push (repr);
4608 if (repr && !no_accesses_p (repr))
4610 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4612 if (ro_grp)
4613 result = UNMODIF_BY_REF_ACCESSES;
4614 else if (result < MODIF_BY_REF_ACCESSES)
4615 result = MODIF_BY_REF_ACCESSES;
4617 else if (result < BY_VAL_ACCESSES)
4618 result = BY_VAL_ACCESSES;
4620 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
4621 result = UNUSED_PARAMS;
4623 else
4624 representatives.quick_push (NULL);
4627 if (result == NO_GOOD_ACCESS)
4629 representatives.release ();
4630 return NO_GOOD_ACCESS;
4633 return result;
4636 /* Return the index of BASE in PARMS. Abort if it is not found. */
4638 static inline int
4639 get_param_index (tree base, vec<tree> parms)
4641 int i, len;
4643 len = parms.length ();
4644 for (i = 0; i < len; i++)
4645 if (parms[i] == base)
4646 return i;
4647 gcc_unreachable ();
4650 /* Convert the decisions made at the representative level into compact
4651 parameter adjustments. REPRESENTATIVES are pointers to first
4652 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4653 final number of adjustments. */
4655 static ipa_parm_adjustment_vec
4656 turn_representatives_into_adjustments (vec<access_p> representatives,
4657 int adjustments_count)
4659 vec<tree> parms;
4660 ipa_parm_adjustment_vec adjustments;
4661 tree parm;
4662 int i;
4664 gcc_assert (adjustments_count > 0);
4665 parms = ipa_get_vector_of_formal_parms (current_function_decl);
4666 adjustments.create (adjustments_count);
4667 parm = DECL_ARGUMENTS (current_function_decl);
4668 for (i = 0; i < func_param_count; i++, parm = DECL_CHAIN (parm))
4670 struct access *repr = representatives[i];
4672 if (!repr || no_accesses_p (repr))
4674 struct ipa_parm_adjustment adj;
4676 memset (&adj, 0, sizeof (adj));
4677 adj.base_index = get_param_index (parm, parms);
4678 adj.base = parm;
4679 if (!repr)
4680 adj.op = IPA_PARM_OP_COPY;
4681 else
4682 adj.op = IPA_PARM_OP_REMOVE;
4683 adj.arg_prefix = "ISRA";
4684 adjustments.quick_push (adj);
4686 else
4688 struct ipa_parm_adjustment adj;
4689 int index = get_param_index (parm, parms);
4691 for (; repr; repr = repr->next_grp)
4693 memset (&adj, 0, sizeof (adj));
4694 gcc_assert (repr->base == parm);
4695 adj.base_index = index;
4696 adj.base = repr->base;
4697 adj.type = repr->type;
4698 adj.alias_ptr_type = reference_alias_ptr_type (repr->expr);
4699 adj.offset = repr->offset;
4700 adj.reverse = repr->reverse;
4701 adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
4702 && (repr->grp_maybe_modified
4703 || repr->grp_not_necessarilly_dereferenced));
4704 adj.arg_prefix = "ISRA";
4705 adjustments.quick_push (adj);
4709 parms.release ();
4710 return adjustments;
4713 /* Analyze the collected accesses and produce a plan what to do with the
4714 parameters in the form of adjustments, NULL meaning nothing. */
4716 static ipa_parm_adjustment_vec
4717 analyze_all_param_acesses (void)
4719 enum ipa_splicing_result repr_state;
4720 bool proceed = false;
4721 int i, adjustments_count = 0;
4722 vec<access_p> representatives;
4723 ipa_parm_adjustment_vec adjustments;
4725 repr_state = splice_all_param_accesses (representatives);
4726 if (repr_state == NO_GOOD_ACCESS)
4727 return ipa_parm_adjustment_vec ();
4729 /* If there are any parameters passed by reference which are not modified
4730 directly, we need to check whether they can be modified indirectly. */
4731 if (repr_state == UNMODIF_BY_REF_ACCESSES)
4733 analyze_caller_dereference_legality (representatives);
4734 analyze_modified_params (representatives);
4737 for (i = 0; i < func_param_count; i++)
4739 struct access *repr = representatives[i];
4741 if (repr && !no_accesses_p (repr))
4743 if (repr->grp_scalar_ptr)
4745 adjustments_count++;
4746 if (repr->grp_not_necessarilly_dereferenced
4747 || repr->grp_maybe_modified)
4748 representatives[i] = NULL;
4749 else
4751 proceed = true;
4752 sra_stats.scalar_by_ref_to_by_val++;
4755 else
4757 int new_components = decide_one_param_reduction (repr);
4759 if (new_components == 0)
4761 representatives[i] = NULL;
4762 adjustments_count++;
4764 else
4766 adjustments_count += new_components;
4767 sra_stats.aggregate_params_reduced++;
4768 sra_stats.param_reductions_created += new_components;
4769 proceed = true;
4773 else
4775 if (no_accesses_p (repr))
4777 proceed = true;
4778 sra_stats.deleted_unused_parameters++;
4780 adjustments_count++;
4784 if (!proceed && dump_file)
4785 fprintf (dump_file, "NOT proceeding to change params.\n");
4787 if (proceed)
4788 adjustments = turn_representatives_into_adjustments (representatives,
4789 adjustments_count);
4790 else
4791 adjustments = ipa_parm_adjustment_vec ();
4793 representatives.release ();
4794 return adjustments;
4797 /* If a parameter replacement identified by ADJ does not yet exist in the form
4798 of declaration, create it and record it, otherwise return the previously
4799 created one. */
4801 static tree
4802 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
4804 tree repl;
4805 if (!adj->new_ssa_base)
4807 char *pretty_name = make_fancy_name (adj->base);
4809 repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR");
4810 DECL_NAME (repl) = get_identifier (pretty_name);
4811 DECL_NAMELESS (repl) = 1;
4812 obstack_free (&name_obstack, pretty_name);
4814 adj->new_ssa_base = repl;
4816 else
4817 repl = adj->new_ssa_base;
4818 return repl;
4821 /* Find the first adjustment for a particular parameter BASE in a vector of
4822 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4823 adjustment. */
4825 static struct ipa_parm_adjustment *
4826 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
4828 int i, len;
4830 len = adjustments.length ();
4831 for (i = 0; i < len; i++)
4833 struct ipa_parm_adjustment *adj;
4835 adj = &adjustments[i];
4836 if (adj->op != IPA_PARM_OP_COPY && adj->base == base)
4837 return adj;
4840 return NULL;
4843 /* If OLD_NAME, which is being defined by statement STMT, is an SSA_NAME of a
4844 parameter which is to be removed because its value is not used, create a new
4845 SSA_NAME relating to a replacement VAR_DECL, replace all uses of the
4846 original with it and return it. If there is no need to re-map, return NULL.
4847 ADJUSTMENTS is a pointer to a vector of IPA-SRA adjustments. */
4849 static tree
4850 replace_removed_params_ssa_names (tree old_name, gimple *stmt,
4851 ipa_parm_adjustment_vec adjustments)
4853 struct ipa_parm_adjustment *adj;
4854 tree decl, repl, new_name;
4856 if (TREE_CODE (old_name) != SSA_NAME)
4857 return NULL;
4859 decl = SSA_NAME_VAR (old_name);
4860 if (decl == NULL_TREE
4861 || TREE_CODE (decl) != PARM_DECL)
4862 return NULL;
4864 adj = get_adjustment_for_base (adjustments, decl);
4865 if (!adj)
4866 return NULL;
4868 repl = get_replaced_param_substitute (adj);
4869 new_name = make_ssa_name (repl, stmt);
4870 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name)
4871 = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name);
4873 if (dump_file)
4875 fprintf (dump_file, "replacing an SSA name of a removed param ");
4876 print_generic_expr (dump_file, old_name);
4877 fprintf (dump_file, " with ");
4878 print_generic_expr (dump_file, new_name);
4879 fprintf (dump_file, "\n");
4882 replace_uses_by (old_name, new_name);
4883 return new_name;
4886 /* If the statement STMT contains any expressions that need to replaced with a
4887 different one as noted by ADJUSTMENTS, do so. Handle any potential type
4888 incompatibilities (GSI is used to accommodate conversion statements and must
4889 point to the statement). Return true iff the statement was modified. */
4891 static bool
4892 sra_ipa_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi,
4893 ipa_parm_adjustment_vec adjustments)
4895 tree *lhs_p, *rhs_p;
4896 bool any;
4898 if (!gimple_assign_single_p (stmt))
4899 return false;
4901 rhs_p = gimple_assign_rhs1_ptr (stmt);
4902 lhs_p = gimple_assign_lhs_ptr (stmt);
4904 any = ipa_modify_expr (rhs_p, false, adjustments);
4905 any |= ipa_modify_expr (lhs_p, false, adjustments);
4906 if (any)
4908 tree new_rhs = NULL_TREE;
4910 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
4912 if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
4914 /* V_C_Es of constructors can cause trouble (PR 42714). */
4915 if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
4916 *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
4917 else
4918 *rhs_p = build_constructor (TREE_TYPE (*lhs_p),
4919 NULL);
4921 else
4922 new_rhs = fold_build1_loc (gimple_location (stmt),
4923 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
4924 *rhs_p);
4926 else if (REFERENCE_CLASS_P (*rhs_p)
4927 && is_gimple_reg_type (TREE_TYPE (*lhs_p))
4928 && !is_gimple_reg (*lhs_p))
4929 /* This can happen when an assignment in between two single field
4930 structures is turned into an assignment in between two pointers to
4931 scalars (PR 42237). */
4932 new_rhs = *rhs_p;
4934 if (new_rhs)
4936 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
4937 true, GSI_SAME_STMT);
4939 gimple_assign_set_rhs_from_tree (gsi, tmp);
4942 return true;
4945 return false;
4948 /* Traverse the function body and all modifications as described in
4949 ADJUSTMENTS. Return true iff the CFG has been changed. */
4951 bool
4952 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
4954 bool cfg_changed = false;
4955 basic_block bb;
4957 FOR_EACH_BB_FN (bb, cfun)
4959 gimple_stmt_iterator gsi;
4961 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4963 gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
4964 tree new_lhs, old_lhs = gimple_phi_result (phi);
4965 new_lhs = replace_removed_params_ssa_names (old_lhs, phi, adjustments);
4966 if (new_lhs)
4968 gimple_phi_set_result (phi, new_lhs);
4969 release_ssa_name (old_lhs);
4973 gsi = gsi_start_bb (bb);
4974 while (!gsi_end_p (gsi))
4976 gimple *stmt = gsi_stmt (gsi);
4977 bool modified = false;
4978 tree *t;
4979 unsigned i;
4981 switch (gimple_code (stmt))
4983 case GIMPLE_RETURN:
4984 t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
4985 if (*t != NULL_TREE)
4986 modified |= ipa_modify_expr (t, true, adjustments);
4987 break;
4989 case GIMPLE_ASSIGN:
4990 modified |= sra_ipa_modify_assign (stmt, &gsi, adjustments);
4991 break;
4993 case GIMPLE_CALL:
4994 /* Operands must be processed before the lhs. */
4995 for (i = 0; i < gimple_call_num_args (stmt); i++)
4997 t = gimple_call_arg_ptr (stmt, i);
4998 modified |= ipa_modify_expr (t, true, adjustments);
5001 if (gimple_call_lhs (stmt))
5003 t = gimple_call_lhs_ptr (stmt);
5004 modified |= ipa_modify_expr (t, false, adjustments);
5006 break;
5008 case GIMPLE_ASM:
5010 gasm *asm_stmt = as_a <gasm *> (stmt);
5011 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
5013 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
5014 modified |= ipa_modify_expr (t, true, adjustments);
5016 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
5018 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
5019 modified |= ipa_modify_expr (t, false, adjustments);
5022 break;
5024 default:
5025 break;
5028 def_operand_p defp;
5029 ssa_op_iter iter;
5030 FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF)
5032 tree old_def = DEF_FROM_PTR (defp);
5033 if (tree new_def = replace_removed_params_ssa_names (old_def, stmt,
5034 adjustments))
5036 SET_DEF (defp, new_def);
5037 release_ssa_name (old_def);
5038 modified = true;
5042 if (modified)
5044 update_stmt (stmt);
5045 if (maybe_clean_eh_stmt (stmt)
5046 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
5047 cfg_changed = true;
5049 gsi_next (&gsi);
5053 return cfg_changed;
5056 /* Call gimple_debug_bind_reset_value on all debug statements describing
5057 gimple register parameters that are being removed or replaced. */
5059 static void
5060 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
5062 int i, len;
5063 gimple_stmt_iterator *gsip = NULL, gsi;
5065 if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
5067 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
5068 gsip = &gsi;
5070 len = adjustments.length ();
5071 for (i = 0; i < len; i++)
5073 struct ipa_parm_adjustment *adj;
5074 imm_use_iterator ui;
5075 gimple *stmt;
5076 gdebug *def_temp;
5077 tree name, vexpr, copy = NULL_TREE;
5078 use_operand_p use_p;
5080 adj = &adjustments[i];
5081 if (adj->op == IPA_PARM_OP_COPY || !is_gimple_reg (adj->base))
5082 continue;
5083 name = ssa_default_def (cfun, adj->base);
5084 vexpr = NULL;
5085 if (name)
5086 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
5088 if (gimple_clobber_p (stmt))
5090 gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
5091 unlink_stmt_vdef (stmt);
5092 gsi_remove (&cgsi, true);
5093 release_defs (stmt);
5094 continue;
5096 /* All other users must have been removed by
5097 ipa_sra_modify_function_body. */
5098 gcc_assert (is_gimple_debug (stmt));
5099 if (vexpr == NULL && gsip != NULL)
5101 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
5102 vexpr = make_node (DEBUG_EXPR_DECL);
5103 def_temp = gimple_build_debug_source_bind (vexpr, adj->base,
5104 NULL);
5105 DECL_ARTIFICIAL (vexpr) = 1;
5106 TREE_TYPE (vexpr) = TREE_TYPE (name);
5107 SET_DECL_MODE (vexpr, DECL_MODE (adj->base));
5108 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
5110 if (vexpr)
5112 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
5113 SET_USE (use_p, vexpr);
5115 else
5116 gimple_debug_bind_reset_value (stmt);
5117 update_stmt (stmt);
5119 /* Create a VAR_DECL for debug info purposes. */
5120 if (!DECL_IGNORED_P (adj->base))
5122 copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
5123 VAR_DECL, DECL_NAME (adj->base),
5124 TREE_TYPE (adj->base));
5125 if (DECL_PT_UID_SET_P (adj->base))
5126 SET_DECL_PT_UID (copy, DECL_PT_UID (adj->base));
5127 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (adj->base);
5128 TREE_READONLY (copy) = TREE_READONLY (adj->base);
5129 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (adj->base);
5130 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (adj->base);
5131 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (adj->base);
5132 DECL_IGNORED_P (copy) = DECL_IGNORED_P (adj->base);
5133 DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (adj->base);
5134 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
5135 SET_DECL_RTL (copy, 0);
5136 TREE_USED (copy) = 1;
5137 DECL_CONTEXT (copy) = current_function_decl;
5138 add_local_decl (cfun, copy);
5139 DECL_CHAIN (copy) =
5140 BLOCK_VARS (DECL_INITIAL (current_function_decl));
5141 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
5143 if (gsip != NULL && copy && target_for_debug_bind (adj->base))
5145 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
5146 if (vexpr)
5147 def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
5148 else
5149 def_temp = gimple_build_debug_source_bind (copy, adj->base,
5150 NULL);
5151 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
5156 /* Return false if all callers have at least as many actual arguments as there
5157 are formal parameters in the current function and that their types
5158 match. */
5160 static bool
5161 some_callers_have_mismatched_arguments_p (struct cgraph_node *node,
5162 void *data ATTRIBUTE_UNUSED)
5164 struct cgraph_edge *cs;
5165 for (cs = node->callers; cs; cs = cs->next_caller)
5166 if (!cs->call_stmt || !callsite_arguments_match_p (cs->call_stmt))
5167 return true;
5169 return false;
5172 /* Return false if all callers have vuse attached to a call statement. */
5174 static bool
5175 some_callers_have_no_vuse_p (struct cgraph_node *node,
5176 void *data ATTRIBUTE_UNUSED)
5178 struct cgraph_edge *cs;
5179 for (cs = node->callers; cs; cs = cs->next_caller)
5180 if (!cs->call_stmt || !gimple_vuse (cs->call_stmt))
5181 return true;
5183 return false;
5186 /* Convert all callers of NODE. */
5188 static bool
5189 convert_callers_for_node (struct cgraph_node *node,
5190 void *data)
5192 ipa_parm_adjustment_vec *adjustments = (ipa_parm_adjustment_vec *) data;
5193 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
5194 struct cgraph_edge *cs;
5196 for (cs = node->callers; cs; cs = cs->next_caller)
5198 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
5200 if (dump_file)
5201 fprintf (dump_file, "Adjusting call %s -> %s\n",
5202 cs->caller->dump_name (), cs->callee->dump_name ());
5204 ipa_modify_call_arguments (cs, cs->call_stmt, *adjustments);
5206 pop_cfun ();
5209 for (cs = node->callers; cs; cs = cs->next_caller)
5210 if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
5211 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
5212 compute_fn_summary (cs->caller, true);
5213 BITMAP_FREE (recomputed_callers);
5215 return true;
5218 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
5220 static void
5221 convert_callers (struct cgraph_node *node, tree old_decl,
5222 ipa_parm_adjustment_vec adjustments)
5224 basic_block this_block;
5226 node->call_for_symbol_and_aliases (convert_callers_for_node,
5227 &adjustments, false);
5229 if (!encountered_recursive_call)
5230 return;
5232 FOR_EACH_BB_FN (this_block, cfun)
5234 gimple_stmt_iterator gsi;
5236 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
5238 gcall *stmt;
5239 tree call_fndecl;
5240 stmt = dyn_cast <gcall *> (gsi_stmt (gsi));
5241 if (!stmt)
5242 continue;
5243 call_fndecl = gimple_call_fndecl (stmt);
5244 if (call_fndecl == old_decl)
5246 if (dump_file)
5247 fprintf (dump_file, "Adjusting recursive call");
5248 gimple_call_set_fndecl (stmt, node->decl);
5249 ipa_modify_call_arguments (NULL, stmt, adjustments);
5254 return;
5257 /* Perform all the modification required in IPA-SRA for NODE to have parameters
5258 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
5260 static bool
5261 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
5263 struct cgraph_node *new_node;
5264 bool cfg_changed;
5266 cgraph_edge::rebuild_edges ();
5267 free_dominance_info (CDI_DOMINATORS);
5268 pop_cfun ();
5270 /* This must be done after rebuilding cgraph edges for node above.
5271 Otherwise any recursive calls to node that are recorded in
5272 redirect_callers will be corrupted. */
5273 vec<cgraph_edge *> redirect_callers = node->collect_callers ();
5274 new_node = node->create_version_clone_with_body (redirect_callers, NULL,
5275 NULL, false, NULL, NULL,
5276 "isra");
5277 redirect_callers.release ();
5279 push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
5280 ipa_modify_formal_parameters (current_function_decl, adjustments);
5281 cfg_changed = ipa_sra_modify_function_body (adjustments);
5282 sra_ipa_reset_debug_stmts (adjustments);
5283 convert_callers (new_node, node->decl, adjustments);
5284 new_node->make_local ();
5285 return cfg_changed;
5288 /* Means of communication between ipa_sra_check_caller and
5289 ipa_sra_preliminary_function_checks. */
5291 struct ipa_sra_check_caller_data
5293 bool has_callers;
5294 bool bad_arg_alignment;
5295 bool has_thunk;
5298 /* If NODE has a caller, mark that fact in DATA which is pointer to
5299 ipa_sra_check_caller_data. Also check all aggregate arguments in all known
5300 calls if they are unit aligned and if not, set the appropriate flag in DATA
5301 too. */
5303 static bool
5304 ipa_sra_check_caller (struct cgraph_node *node, void *data)
5306 if (!node->callers)
5307 return false;
5309 struct ipa_sra_check_caller_data *iscc;
5310 iscc = (struct ipa_sra_check_caller_data *) data;
5311 iscc->has_callers = true;
5313 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
5315 if (cs->caller->thunk.thunk_p)
5317 iscc->has_thunk = true;
5318 return true;
5320 gimple *call_stmt = cs->call_stmt;
5321 unsigned count = gimple_call_num_args (call_stmt);
5322 for (unsigned i = 0; i < count; i++)
5324 tree arg = gimple_call_arg (call_stmt, i);
5325 if (is_gimple_reg (arg))
5326 continue;
5328 tree offset;
5329 HOST_WIDE_INT bitsize, bitpos;
5330 machine_mode mode;
5331 int unsignedp, reversep, volatilep = 0;
5332 get_inner_reference (arg, &bitsize, &bitpos, &offset, &mode,
5333 &unsignedp, &reversep, &volatilep);
5334 if (bitpos % BITS_PER_UNIT)
5336 iscc->bad_arg_alignment = true;
5337 return true;
5342 return false;
5345 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
5346 attributes, return true otherwise. NODE is the cgraph node of the current
5347 function. */
5349 static bool
5350 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
5352 if (!node->can_be_local_p ())
5354 if (dump_file)
5355 fprintf (dump_file, "Function not local to this compilation unit.\n");
5356 return false;
5359 if (!node->local.can_change_signature)
5361 if (dump_file)
5362 fprintf (dump_file, "Function can not change signature.\n");
5363 return false;
5366 if (!tree_versionable_function_p (node->decl))
5368 if (dump_file)
5369 fprintf (dump_file, "Function is not versionable.\n");
5370 return false;
5373 if (!opt_for_fn (node->decl, optimize)
5374 || !opt_for_fn (node->decl, flag_ipa_sra))
5376 if (dump_file)
5377 fprintf (dump_file, "Function not optimized.\n");
5378 return false;
5381 if (DECL_VIRTUAL_P (current_function_decl))
5383 if (dump_file)
5384 fprintf (dump_file, "Function is a virtual method.\n");
5385 return false;
5388 if ((DECL_ONE_ONLY (node->decl) || DECL_EXTERNAL (node->decl))
5389 && ipa_fn_summaries->get (node)->size >= MAX_INLINE_INSNS_AUTO)
5391 if (dump_file)
5392 fprintf (dump_file, "Function too big to be made truly local.\n");
5393 return false;
5396 if (cfun->stdarg)
5398 if (dump_file)
5399 fprintf (dump_file, "Function uses stdarg. \n");
5400 return false;
5403 if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
5404 return false;
5406 if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
5408 if (dump_file)
5409 fprintf (dump_file, "Always inline function will be inlined "
5410 "anyway. \n");
5411 return false;
5414 struct ipa_sra_check_caller_data iscc;
5415 memset (&iscc, 0, sizeof(iscc));
5416 node->call_for_symbol_and_aliases (ipa_sra_check_caller, &iscc, true);
5417 if (!iscc.has_callers)
5419 if (dump_file)
5420 fprintf (dump_file,
5421 "Function has no callers in this compilation unit.\n");
5422 return false;
5425 if (iscc.bad_arg_alignment)
5427 if (dump_file)
5428 fprintf (dump_file,
5429 "A function call has an argument with non-unit alignment.\n");
5430 return false;
5433 if (iscc.has_thunk)
5435 if (dump_file)
5436 fprintf (dump_file,
5437 "A has thunk.\n");
5438 return false;
5441 return true;
5444 /* Perform early interprocedural SRA. */
5446 static unsigned int
5447 ipa_early_sra (void)
5449 struct cgraph_node *node = cgraph_node::get (current_function_decl);
5450 ipa_parm_adjustment_vec adjustments;
5451 int ret = 0;
5453 if (!ipa_sra_preliminary_function_checks (node))
5454 return 0;
5456 sra_initialize ();
5457 sra_mode = SRA_MODE_EARLY_IPA;
5459 if (!find_param_candidates ())
5461 if (dump_file)
5462 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
5463 goto simple_out;
5466 if (node->call_for_symbol_and_aliases
5467 (some_callers_have_mismatched_arguments_p, NULL, true))
5469 if (dump_file)
5470 fprintf (dump_file, "There are callers with insufficient number of "
5471 "arguments or arguments with type mismatches.\n");
5472 goto simple_out;
5475 if (node->call_for_symbol_and_aliases
5476 (some_callers_have_no_vuse_p, NULL, true))
5478 if (dump_file)
5479 fprintf (dump_file, "There are callers with no VUSE attached "
5480 "to a call stmt.\n");
5481 goto simple_out;
5484 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
5485 func_param_count
5486 * last_basic_block_for_fn (cfun));
5487 final_bbs = BITMAP_ALLOC (NULL);
5489 scan_function ();
5490 if (encountered_apply_args)
5492 if (dump_file)
5493 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
5494 goto out;
5497 if (encountered_unchangable_recursive_call)
5499 if (dump_file)
5500 fprintf (dump_file, "Function calls itself with insufficient "
5501 "number of arguments.\n");
5502 goto out;
5505 adjustments = analyze_all_param_acesses ();
5506 if (!adjustments.exists ())
5507 goto out;
5508 if (dump_file)
5509 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
5511 if (modify_function (node, adjustments))
5512 ret = TODO_update_ssa | TODO_cleanup_cfg;
5513 else
5514 ret = TODO_update_ssa;
5515 adjustments.release ();
5517 statistics_counter_event (cfun, "Unused parameters deleted",
5518 sra_stats.deleted_unused_parameters);
5519 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
5520 sra_stats.scalar_by_ref_to_by_val);
5521 statistics_counter_event (cfun, "Aggregate parameters broken up",
5522 sra_stats.aggregate_params_reduced);
5523 statistics_counter_event (cfun, "Aggregate parameter components created",
5524 sra_stats.param_reductions_created);
5526 out:
5527 BITMAP_FREE (final_bbs);
5528 free (bb_dereferences);
5529 simple_out:
5530 sra_deinitialize ();
5531 return ret;
5534 namespace {
5536 const pass_data pass_data_early_ipa_sra =
5538 GIMPLE_PASS, /* type */
5539 "eipa_sra", /* name */
5540 OPTGROUP_NONE, /* optinfo_flags */
5541 TV_IPA_SRA, /* tv_id */
5542 0, /* properties_required */
5543 0, /* properties_provided */
5544 0, /* properties_destroyed */
5545 0, /* todo_flags_start */
5546 TODO_dump_symtab, /* todo_flags_finish */
5549 class pass_early_ipa_sra : public gimple_opt_pass
5551 public:
5552 pass_early_ipa_sra (gcc::context *ctxt)
5553 : gimple_opt_pass (pass_data_early_ipa_sra, ctxt)
5556 /* opt_pass methods: */
5557 virtual bool gate (function *) { return flag_ipa_sra && dbg_cnt (eipa_sra); }
5558 virtual unsigned int execute (function *) { return ipa_early_sra (); }
5560 }; // class pass_early_ipa_sra
5562 } // anon namespace
5564 gimple_opt_pass *
5565 make_pass_early_ipa_sra (gcc::context *ctxt)
5567 return new pass_early_ipa_sra (ctxt);