PR rtl-optimization/82913
[official-gcc.git] / gcc / tree-sra.c
blobdb490b20c3ed1049380dd3a51555f0de17c3afa3
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-param-manipulation.h"
101 #include "ipa-prop.h"
102 #include "params.h"
103 #include "dbgcnt.h"
104 #include "tree-inline.h"
105 #include "ipa-fnsummary.h"
106 #include "ipa-utils.h"
107 #include "builtins.h"
109 /* Enumeration of all aggregate reductions we can do. */
110 enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
111 SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
112 SRA_MODE_INTRA }; /* late intraprocedural SRA */
114 /* Global variable describing which aggregate reduction we are performing at
115 the moment. */
116 static enum sra_mode sra_mode;
118 struct assign_link;
120 /* ACCESS represents each access to an aggregate variable (as a whole or a
121 part). It can also represent a group of accesses that refer to exactly the
122 same fragment of an aggregate (i.e. those that have exactly the same offset
123 and size). Such representatives for a single aggregate, once determined,
124 are linked in a linked list and have the group fields set.
126 Moreover, when doing intraprocedural SRA, a tree is built from those
127 representatives (by the means of first_child and next_sibling pointers), in
128 which all items in a subtree are "within" the root, i.e. their offset is
129 greater or equal to offset of the root and offset+size is smaller or equal
130 to offset+size of the root. Children of an access are sorted by offset.
132 Note that accesses to parts of vector and complex number types always
133 represented by an access to the whole complex number or a vector. It is a
134 duty of the modifying functions to replace them appropriately. */
136 struct access
138 /* Values returned by `get_ref_base_and_extent' for each component reference
139 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
140 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
141 HOST_WIDE_INT offset;
142 HOST_WIDE_INT size;
143 tree base;
145 /* Expression. It is context dependent so do not use it to create new
146 expressions to access the original aggregate. See PR 42154 for a
147 testcase. */
148 tree expr;
149 /* Type. */
150 tree type;
152 /* The statement this access belongs to. */
153 gimple *stmt;
155 /* Next group representative for this aggregate. */
156 struct access *next_grp;
158 /* Pointer to the group representative. Pointer to itself if the struct is
159 the representative. */
160 struct access *group_representative;
162 /* After access tree has been constructed, this points to the parent of the
163 current access, if there is one. NULL for roots. */
164 struct access *parent;
166 /* If this access has any children (in terms of the definition above), this
167 points to the first one. */
168 struct access *first_child;
170 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
171 described above. In IPA-SRA this is a pointer to the next access
172 belonging to the same group (having the same representative). */
173 struct access *next_sibling;
175 /* Pointers to the first and last element in the linked list of assign
176 links. */
177 struct assign_link *first_link, *last_link;
179 /* Pointer to the next access in the work queue. */
180 struct access *next_queued;
182 /* Replacement variable for this access "region." Never to be accessed
183 directly, always only by the means of get_access_replacement() and only
184 when grp_to_be_replaced flag is set. */
185 tree replacement_decl;
187 /* Is this access an access to a non-addressable field? */
188 unsigned non_addressable : 1;
190 /* Is this access made in reverse storage order? */
191 unsigned reverse : 1;
193 /* Is this particular access write access? */
194 unsigned write : 1;
196 /* Is this access currently in the work queue? */
197 unsigned grp_queued : 1;
199 /* Does this group contain a write access? This flag is propagated down the
200 access tree. */
201 unsigned grp_write : 1;
203 /* Does this group contain a read access? This flag is propagated down the
204 access tree. */
205 unsigned grp_read : 1;
207 /* Does this group contain a read access that comes from an assignment
208 statement? This flag is propagated down the access tree. */
209 unsigned grp_assignment_read : 1;
211 /* Does this group contain a write access that comes from an assignment
212 statement? This flag is propagated down the access tree. */
213 unsigned grp_assignment_write : 1;
215 /* Does this group contain a read access through a scalar type? This flag is
216 not propagated in the access tree in any direction. */
217 unsigned grp_scalar_read : 1;
219 /* Does this group contain a write access through a scalar type? This flag
220 is not propagated in the access tree in any direction. */
221 unsigned grp_scalar_write : 1;
223 /* Is this access an artificial one created to scalarize some record
224 entirely? */
225 unsigned grp_total_scalarization : 1;
227 /* Other passes of the analysis use this bit to make function
228 analyze_access_subtree create scalar replacements for this group if
229 possible. */
230 unsigned grp_hint : 1;
232 /* Is the subtree rooted in this access fully covered by scalar
233 replacements? */
234 unsigned grp_covered : 1;
236 /* If set to true, this access and all below it in an access tree must not be
237 scalarized. */
238 unsigned grp_unscalarizable_region : 1;
240 /* Whether data have been written to parts of the aggregate covered by this
241 access which is not to be scalarized. This flag is propagated up in the
242 access tree. */
243 unsigned grp_unscalarized_data : 1;
245 /* Does this access and/or group contain a write access through a
246 BIT_FIELD_REF? */
247 unsigned grp_partial_lhs : 1;
249 /* Set when a scalar replacement should be created for this variable. */
250 unsigned grp_to_be_replaced : 1;
252 /* Set when we want a replacement for the sole purpose of having it in
253 generated debug statements. */
254 unsigned grp_to_be_debug_replaced : 1;
256 /* Should TREE_NO_WARNING of a replacement be set? */
257 unsigned grp_no_warning : 1;
259 /* Is it possible that the group refers to data which might be (directly or
260 otherwise) modified? */
261 unsigned grp_maybe_modified : 1;
263 /* Set when this is a representative of a pointer to scalar (i.e. by
264 reference) parameter which we consider for turning into a plain scalar
265 (i.e. a by value parameter). */
266 unsigned grp_scalar_ptr : 1;
268 /* Set when we discover that this pointer is not safe to dereference in the
269 caller. */
270 unsigned grp_not_necessarilly_dereferenced : 1;
273 typedef struct access *access_p;
276 /* Alloc pool for allocating access structures. */
277 static object_allocator<struct access> access_pool ("SRA accesses");
279 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
280 are used to propagate subaccesses from rhs to lhs as long as they don't
281 conflict with what is already there. */
282 struct assign_link
284 struct access *lacc, *racc;
285 struct assign_link *next;
288 /* Alloc pool for allocating assign link structures. */
289 static object_allocator<assign_link> assign_link_pool ("SRA links");
291 /* Base (tree) -> Vector (vec<access_p> *) map. */
292 static hash_map<tree, auto_vec<access_p> > *base_access_vec;
294 /* Candidate hash table helpers. */
296 struct uid_decl_hasher : nofree_ptr_hash <tree_node>
298 static inline hashval_t hash (const tree_node *);
299 static inline bool equal (const tree_node *, const tree_node *);
302 /* Hash a tree in a uid_decl_map. */
304 inline hashval_t
305 uid_decl_hasher::hash (const tree_node *item)
307 return item->decl_minimal.uid;
310 /* Return true if the DECL_UID in both trees are equal. */
312 inline bool
313 uid_decl_hasher::equal (const tree_node *a, const tree_node *b)
315 return (a->decl_minimal.uid == b->decl_minimal.uid);
318 /* Set of candidates. */
319 static bitmap candidate_bitmap;
320 static hash_table<uid_decl_hasher> *candidates;
322 /* For a candidate UID return the candidates decl. */
324 static inline tree
325 candidate (unsigned uid)
327 tree_node t;
328 t.decl_minimal.uid = uid;
329 return candidates->find_with_hash (&t, static_cast <hashval_t> (uid));
332 /* Bitmap of candidates which we should try to entirely scalarize away and
333 those which cannot be (because they are and need be used as a whole). */
334 static bitmap should_scalarize_away_bitmap, cannot_scalarize_away_bitmap;
336 /* Bitmap of candidates in the constant pool, which cannot be scalarized
337 because this would produce non-constant expressions (e.g. Ada). */
338 static bitmap disqualified_constants;
340 /* Obstack for creation of fancy names. */
341 static struct obstack name_obstack;
343 /* Head of a linked list of accesses that need to have its subaccesses
344 propagated to their assignment counterparts. */
345 static struct access *work_queue_head;
347 /* Number of parameters of the analyzed function when doing early ipa SRA. */
348 static int func_param_count;
350 /* scan_function sets the following to true if it encounters a call to
351 __builtin_apply_args. */
352 static bool encountered_apply_args;
354 /* Set by scan_function when it finds a recursive call. */
355 static bool encountered_recursive_call;
357 /* Set by scan_function when it finds a recursive call with less actual
358 arguments than formal parameters.. */
359 static bool encountered_unchangable_recursive_call;
361 /* This is a table in which for each basic block and parameter there is a
362 distance (offset + size) in that parameter which is dereferenced and
363 accessed in that BB. */
364 static HOST_WIDE_INT *bb_dereferences;
365 /* Bitmap of BBs that can cause the function to "stop" progressing by
366 returning, throwing externally, looping infinitely or calling a function
367 which might abort etc.. */
368 static bitmap final_bbs;
370 /* Representative of no accesses at all. */
371 static struct access no_accesses_representant;
373 /* Predicate to test the special value. */
375 static inline bool
376 no_accesses_p (struct access *access)
378 return access == &no_accesses_representant;
381 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
382 representative fields are dumped, otherwise those which only describe the
383 individual access are. */
385 static struct
387 /* Number of processed aggregates is readily available in
388 analyze_all_variable_accesses and so is not stored here. */
390 /* Number of created scalar replacements. */
391 int replacements;
393 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
394 expression. */
395 int exprs;
397 /* Number of statements created by generate_subtree_copies. */
398 int subtree_copies;
400 /* Number of statements created by load_assign_lhs_subreplacements. */
401 int subreplacements;
403 /* Number of times sra_modify_assign has deleted a statement. */
404 int deleted;
406 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
407 RHS reparately due to type conversions or nonexistent matching
408 references. */
409 int separate_lhs_rhs_handling;
411 /* Number of parameters that were removed because they were unused. */
412 int deleted_unused_parameters;
414 /* Number of scalars passed as parameters by reference that have been
415 converted to be passed by value. */
416 int scalar_by_ref_to_by_val;
418 /* Number of aggregate parameters that were replaced by one or more of their
419 components. */
420 int aggregate_params_reduced;
422 /* Numbber of components created when splitting aggregate parameters. */
423 int param_reductions_created;
424 } sra_stats;
426 static void
427 dump_access (FILE *f, struct access *access, bool grp)
429 fprintf (f, "access { ");
430 fprintf (f, "base = (%d)'", DECL_UID (access->base));
431 print_generic_expr (f, access->base);
432 fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
433 fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
434 fprintf (f, ", expr = ");
435 print_generic_expr (f, access->expr);
436 fprintf (f, ", type = ");
437 print_generic_expr (f, access->type);
438 fprintf (f, ", non_addressable = %d, reverse = %d",
439 access->non_addressable, access->reverse);
440 if (grp)
441 fprintf (f, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
442 "grp_assignment_write = %d, grp_scalar_read = %d, "
443 "grp_scalar_write = %d, grp_total_scalarization = %d, "
444 "grp_hint = %d, grp_covered = %d, "
445 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
446 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
447 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
448 "grp_not_necessarilly_dereferenced = %d\n",
449 access->grp_read, access->grp_write, access->grp_assignment_read,
450 access->grp_assignment_write, access->grp_scalar_read,
451 access->grp_scalar_write, access->grp_total_scalarization,
452 access->grp_hint, access->grp_covered,
453 access->grp_unscalarizable_region, access->grp_unscalarized_data,
454 access->grp_partial_lhs, access->grp_to_be_replaced,
455 access->grp_to_be_debug_replaced, access->grp_maybe_modified,
456 access->grp_not_necessarilly_dereferenced);
457 else
458 fprintf (f, ", write = %d, grp_total_scalarization = %d, "
459 "grp_partial_lhs = %d\n",
460 access->write, access->grp_total_scalarization,
461 access->grp_partial_lhs);
464 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
466 static void
467 dump_access_tree_1 (FILE *f, struct access *access, int level)
471 int i;
473 for (i = 0; i < level; i++)
474 fputs ("* ", f);
476 dump_access (f, access, true);
478 if (access->first_child)
479 dump_access_tree_1 (f, access->first_child, level + 1);
481 access = access->next_sibling;
483 while (access);
486 /* Dump all access trees for a variable, given the pointer to the first root in
487 ACCESS. */
489 static void
490 dump_access_tree (FILE *f, struct access *access)
492 for (; access; access = access->next_grp)
493 dump_access_tree_1 (f, access, 0);
496 /* Return true iff ACC is non-NULL and has subaccesses. */
498 static inline bool
499 access_has_children_p (struct access *acc)
501 return acc && acc->first_child;
504 /* Return true iff ACC is (partly) covered by at least one replacement. */
506 static bool
507 access_has_replacements_p (struct access *acc)
509 struct access *child;
510 if (acc->grp_to_be_replaced)
511 return true;
512 for (child = acc->first_child; child; child = child->next_sibling)
513 if (access_has_replacements_p (child))
514 return true;
515 return false;
518 /* Return a vector of pointers to accesses for the variable given in BASE or
519 NULL if there is none. */
521 static vec<access_p> *
522 get_base_access_vector (tree base)
524 return base_access_vec->get (base);
527 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
528 in ACCESS. Return NULL if it cannot be found. */
530 static struct access *
531 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
532 HOST_WIDE_INT size)
534 while (access && (access->offset != offset || access->size != size))
536 struct access *child = access->first_child;
538 while (child && (child->offset + child->size <= offset))
539 child = child->next_sibling;
540 access = child;
543 return access;
546 /* Return the first group representative for DECL or NULL if none exists. */
548 static struct access *
549 get_first_repr_for_decl (tree base)
551 vec<access_p> *access_vec;
553 access_vec = get_base_access_vector (base);
554 if (!access_vec)
555 return NULL;
557 return (*access_vec)[0];
560 /* Find an access representative for the variable BASE and given OFFSET and
561 SIZE. Requires that access trees have already been built. Return NULL if
562 it cannot be found. */
564 static struct access *
565 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
566 HOST_WIDE_INT size)
568 struct access *access;
570 access = get_first_repr_for_decl (base);
571 while (access && (access->offset + access->size <= offset))
572 access = access->next_grp;
573 if (!access)
574 return NULL;
576 return find_access_in_subtree (access, offset, size);
579 /* Add LINK to the linked list of assign links of RACC. */
580 static void
581 add_link_to_rhs (struct access *racc, struct assign_link *link)
583 gcc_assert (link->racc == racc);
585 if (!racc->first_link)
587 gcc_assert (!racc->last_link);
588 racc->first_link = link;
590 else
591 racc->last_link->next = link;
593 racc->last_link = link;
594 link->next = NULL;
597 /* Move all link structures in their linked list in OLD_RACC to the linked list
598 in NEW_RACC. */
599 static void
600 relink_to_new_repr (struct access *new_racc, struct access *old_racc)
602 if (!old_racc->first_link)
604 gcc_assert (!old_racc->last_link);
605 return;
608 if (new_racc->first_link)
610 gcc_assert (!new_racc->last_link->next);
611 gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
613 new_racc->last_link->next = old_racc->first_link;
614 new_racc->last_link = old_racc->last_link;
616 else
618 gcc_assert (!new_racc->last_link);
620 new_racc->first_link = old_racc->first_link;
621 new_racc->last_link = old_racc->last_link;
623 old_racc->first_link = old_racc->last_link = NULL;
626 /* Add ACCESS to the work queue (which is actually a stack). */
628 static void
629 add_access_to_work_queue (struct access *access)
631 if (access->first_link && !access->grp_queued)
633 gcc_assert (!access->next_queued);
634 access->next_queued = work_queue_head;
635 access->grp_queued = 1;
636 work_queue_head = access;
640 /* Pop an access from the work queue, and return it, assuming there is one. */
642 static struct access *
643 pop_access_from_work_queue (void)
645 struct access *access = work_queue_head;
647 work_queue_head = access->next_queued;
648 access->next_queued = NULL;
649 access->grp_queued = 0;
650 return access;
654 /* Allocate necessary structures. */
656 static void
657 sra_initialize (void)
659 candidate_bitmap = BITMAP_ALLOC (NULL);
660 candidates = new hash_table<uid_decl_hasher>
661 (vec_safe_length (cfun->local_decls) / 2);
662 should_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
663 cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
664 disqualified_constants = BITMAP_ALLOC (NULL);
665 gcc_obstack_init (&name_obstack);
666 base_access_vec = new hash_map<tree, auto_vec<access_p> >;
667 memset (&sra_stats, 0, sizeof (sra_stats));
668 encountered_apply_args = false;
669 encountered_recursive_call = false;
670 encountered_unchangable_recursive_call = false;
673 /* Deallocate all general structures. */
675 static void
676 sra_deinitialize (void)
678 BITMAP_FREE (candidate_bitmap);
679 delete candidates;
680 candidates = NULL;
681 BITMAP_FREE (should_scalarize_away_bitmap);
682 BITMAP_FREE (cannot_scalarize_away_bitmap);
683 BITMAP_FREE (disqualified_constants);
684 access_pool.release ();
685 assign_link_pool.release ();
686 obstack_free (&name_obstack, NULL);
688 delete base_access_vec;
691 /* Return true if DECL is a VAR_DECL in the constant pool, false otherwise. */
693 static bool constant_decl_p (tree decl)
695 return VAR_P (decl) && DECL_IN_CONSTANT_POOL (decl);
698 /* Remove DECL from candidates for SRA and write REASON to the dump file if
699 there is one. */
701 static void
702 disqualify_candidate (tree decl, const char *reason)
704 if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl)))
705 candidates->remove_elt_with_hash (decl, DECL_UID (decl));
706 if (constant_decl_p (decl))
707 bitmap_set_bit (disqualified_constants, DECL_UID (decl));
709 if (dump_file && (dump_flags & TDF_DETAILS))
711 fprintf (dump_file, "! Disqualifying ");
712 print_generic_expr (dump_file, decl);
713 fprintf (dump_file, " - %s\n", reason);
717 /* Return true iff the type contains a field or an element which does not allow
718 scalarization. */
720 static bool
721 type_internals_preclude_sra_p (tree type, const char **msg)
723 tree fld;
724 tree et;
726 switch (TREE_CODE (type))
728 case RECORD_TYPE:
729 case UNION_TYPE:
730 case QUAL_UNION_TYPE:
731 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
732 if (TREE_CODE (fld) == FIELD_DECL)
734 tree ft = TREE_TYPE (fld);
736 if (TREE_THIS_VOLATILE (fld))
738 *msg = "volatile structure field";
739 return true;
741 if (!DECL_FIELD_OFFSET (fld))
743 *msg = "no structure field offset";
744 return true;
746 if (!DECL_SIZE (fld))
748 *msg = "zero structure field size";
749 return true;
751 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
753 *msg = "structure field offset not fixed";
754 return true;
756 if (!tree_fits_uhwi_p (DECL_SIZE (fld)))
758 *msg = "structure field size not fixed";
759 return true;
761 if (!tree_fits_shwi_p (bit_position (fld)))
763 *msg = "structure field size too big";
764 return true;
766 if (AGGREGATE_TYPE_P (ft)
767 && int_bit_position (fld) % BITS_PER_UNIT != 0)
769 *msg = "structure field is bit field";
770 return true;
773 if (AGGREGATE_TYPE_P (ft) && type_internals_preclude_sra_p (ft, msg))
774 return true;
777 return false;
779 case ARRAY_TYPE:
780 et = TREE_TYPE (type);
782 if (TYPE_VOLATILE (et))
784 *msg = "element type is volatile";
785 return true;
788 if (AGGREGATE_TYPE_P (et) && type_internals_preclude_sra_p (et, msg))
789 return true;
791 return false;
793 default:
794 return false;
798 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
799 base variable if it is. Return T if it is not an SSA_NAME. */
801 static tree
802 get_ssa_base_param (tree t)
804 if (TREE_CODE (t) == SSA_NAME)
806 if (SSA_NAME_IS_DEFAULT_DEF (t))
807 return SSA_NAME_VAR (t);
808 else
809 return NULL_TREE;
811 return t;
814 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
815 belongs to, unless the BB has already been marked as a potentially
816 final. */
818 static void
819 mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple *stmt)
821 basic_block bb = gimple_bb (stmt);
822 int idx, parm_index = 0;
823 tree parm;
825 if (bitmap_bit_p (final_bbs, bb->index))
826 return;
828 for (parm = DECL_ARGUMENTS (current_function_decl);
829 parm && parm != base;
830 parm = DECL_CHAIN (parm))
831 parm_index++;
833 gcc_assert (parm_index < func_param_count);
835 idx = bb->index * func_param_count + parm_index;
836 if (bb_dereferences[idx] < dist)
837 bb_dereferences[idx] = dist;
840 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
841 the three fields. Also add it to the vector of accesses corresponding to
842 the base. Finally, return the new access. */
844 static struct access *
845 create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
847 struct access *access = access_pool.allocate ();
849 memset (access, 0, sizeof (struct access));
850 access->base = base;
851 access->offset = offset;
852 access->size = size;
854 base_access_vec->get_or_insert (base).safe_push (access);
856 return access;
859 static bool maybe_add_sra_candidate (tree);
861 /* Create and insert access for EXPR. Return created access, or NULL if it is
862 not possible. Also scan for uses of constant pool as we go along and add
863 to candidates. */
865 static struct access *
866 create_access (tree expr, gimple *stmt, bool write)
868 struct access *access;
869 HOST_WIDE_INT offset, size, max_size;
870 tree base = expr;
871 bool reverse, ptr, unscalarizable_region = false;
873 base = get_ref_base_and_extent (expr, &offset, &size, &max_size, &reverse);
875 if (sra_mode == SRA_MODE_EARLY_IPA
876 && TREE_CODE (base) == MEM_REF)
878 base = get_ssa_base_param (TREE_OPERAND (base, 0));
879 if (!base)
880 return NULL;
881 ptr = true;
883 else
884 ptr = false;
886 /* For constant-pool entries, check we can substitute the constant value. */
887 if (constant_decl_p (base)
888 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA))
890 gcc_assert (!bitmap_bit_p (disqualified_constants, DECL_UID (base)));
891 if (expr != base
892 && !is_gimple_reg_type (TREE_TYPE (expr))
893 && dump_file && (dump_flags & TDF_DETAILS))
895 /* This occurs in Ada with accesses to ARRAY_RANGE_REFs,
896 and elements of multidimensional arrays (which are
897 multi-element arrays in their own right). */
898 fprintf (dump_file, "Allowing non-reg-type load of part"
899 " of constant-pool entry: ");
900 print_generic_expr (dump_file, expr);
902 maybe_add_sra_candidate (base);
905 if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
906 return NULL;
908 if (sra_mode == SRA_MODE_EARLY_IPA)
910 if (size < 0 || size != max_size)
912 disqualify_candidate (base, "Encountered a variable sized access.");
913 return NULL;
915 if (TREE_CODE (expr) == COMPONENT_REF
916 && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))
918 disqualify_candidate (base, "Encountered a bit-field access.");
919 return NULL;
921 gcc_checking_assert ((offset % BITS_PER_UNIT) == 0);
923 if (ptr)
924 mark_parm_dereference (base, offset + size, stmt);
926 else
928 if (size != max_size)
930 size = max_size;
931 unscalarizable_region = true;
933 if (size < 0)
935 disqualify_candidate (base, "Encountered an unconstrained access.");
936 return NULL;
940 access = create_access_1 (base, offset, size);
941 access->expr = expr;
942 access->type = TREE_TYPE (expr);
943 access->write = write;
944 access->grp_unscalarizable_region = unscalarizable_region;
945 access->stmt = stmt;
946 access->reverse = reverse;
948 if (TREE_CODE (expr) == COMPONENT_REF
949 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1)))
950 access->non_addressable = 1;
952 return access;
956 /* Return true iff TYPE is scalarizable - i.e. a RECORD_TYPE or fixed-length
957 ARRAY_TYPE with fields that are either of gimple register types (excluding
958 bit-fields) or (recursively) scalarizable types. CONST_DECL must be true if
959 we are considering a decl from constant pool. If it is false, char arrays
960 will be refused. */
962 static bool
963 scalarizable_type_p (tree type, bool const_decl)
965 gcc_assert (!is_gimple_reg_type (type));
966 if (type_contains_placeholder_p (type))
967 return false;
969 switch (TREE_CODE (type))
971 case RECORD_TYPE:
972 for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
973 if (TREE_CODE (fld) == FIELD_DECL)
975 tree ft = TREE_TYPE (fld);
977 if (DECL_BIT_FIELD (fld))
978 return false;
980 if (!is_gimple_reg_type (ft)
981 && !scalarizable_type_p (ft, const_decl))
982 return false;
985 return true;
987 case ARRAY_TYPE:
989 HOST_WIDE_INT min_elem_size;
990 if (const_decl)
991 min_elem_size = 0;
992 else
993 min_elem_size = BITS_PER_UNIT;
995 if (TYPE_DOMAIN (type) == NULL_TREE
996 || !tree_fits_shwi_p (TYPE_SIZE (type))
997 || !tree_fits_shwi_p (TYPE_SIZE (TREE_TYPE (type)))
998 || (tree_to_shwi (TYPE_SIZE (TREE_TYPE (type))) <= min_elem_size)
999 || !tree_fits_shwi_p (TYPE_MIN_VALUE (TYPE_DOMAIN (type))))
1000 return false;
1001 if (tree_to_shwi (TYPE_SIZE (type)) == 0
1002 && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE)
1003 /* Zero-element array, should not prevent scalarization. */
1005 else if ((tree_to_shwi (TYPE_SIZE (type)) <= 0)
1006 || !tree_fits_shwi_p (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
1007 /* Variable-length array, do not allow scalarization. */
1008 return false;
1010 tree elem = TREE_TYPE (type);
1011 if (!is_gimple_reg_type (elem)
1012 && !scalarizable_type_p (elem, const_decl))
1013 return false;
1014 return true;
1016 default:
1017 return false;
1021 static void scalarize_elem (tree, HOST_WIDE_INT, HOST_WIDE_INT, bool, tree, tree);
1023 /* Create total_scalarization accesses for all scalar fields of a member
1024 of type DECL_TYPE conforming to scalarizable_type_p. BASE
1025 must be the top-most VAR_DECL representing the variable; within that,
1026 OFFSET locates the member and REF must be the memory reference expression for
1027 the member. */
1029 static void
1030 completely_scalarize (tree base, tree decl_type, HOST_WIDE_INT offset, tree ref)
1032 switch (TREE_CODE (decl_type))
1034 case RECORD_TYPE:
1035 for (tree fld = TYPE_FIELDS (decl_type); fld; fld = DECL_CHAIN (fld))
1036 if (TREE_CODE (fld) == FIELD_DECL)
1038 HOST_WIDE_INT pos = offset + int_bit_position (fld);
1039 tree ft = TREE_TYPE (fld);
1040 tree nref = build3 (COMPONENT_REF, ft, ref, fld, NULL_TREE);
1042 scalarize_elem (base, pos, tree_to_uhwi (DECL_SIZE (fld)),
1043 TYPE_REVERSE_STORAGE_ORDER (decl_type),
1044 nref, ft);
1046 break;
1047 case ARRAY_TYPE:
1049 tree elemtype = TREE_TYPE (decl_type);
1050 tree elem_size = TYPE_SIZE (elemtype);
1051 gcc_assert (elem_size && tree_fits_shwi_p (elem_size));
1052 HOST_WIDE_INT el_size = tree_to_shwi (elem_size);
1053 gcc_assert (el_size > 0);
1055 tree minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (decl_type));
1056 gcc_assert (TREE_CODE (minidx) == INTEGER_CST);
1057 tree maxidx = TYPE_MAX_VALUE (TYPE_DOMAIN (decl_type));
1058 /* Skip (some) zero-length arrays; others have MAXIDX == MINIDX - 1. */
1059 if (maxidx)
1061 gcc_assert (TREE_CODE (maxidx) == INTEGER_CST);
1062 tree domain = TYPE_DOMAIN (decl_type);
1063 /* MINIDX and MAXIDX are inclusive, and must be interpreted in
1064 DOMAIN (e.g. signed int, whereas min/max may be size_int). */
1065 offset_int idx = wi::to_offset (minidx);
1066 offset_int max = wi::to_offset (maxidx);
1067 if (!TYPE_UNSIGNED (domain))
1069 idx = wi::sext (idx, TYPE_PRECISION (domain));
1070 max = wi::sext (max, TYPE_PRECISION (domain));
1072 for (int el_off = offset; idx <= max; ++idx)
1074 tree nref = build4 (ARRAY_REF, elemtype,
1075 ref,
1076 wide_int_to_tree (domain, idx),
1077 NULL_TREE, NULL_TREE);
1078 scalarize_elem (base, el_off, el_size,
1079 TYPE_REVERSE_STORAGE_ORDER (decl_type),
1080 nref, elemtype);
1081 el_off += el_size;
1085 break;
1086 default:
1087 gcc_unreachable ();
1091 /* Create total_scalarization accesses for a member of type TYPE, which must
1092 satisfy either is_gimple_reg_type or scalarizable_type_p. BASE must be the
1093 top-most VAR_DECL representing the variable; within that, POS and SIZE locate
1094 the member, REVERSE gives its torage order. and REF must be the reference
1095 expression for it. */
1097 static void
1098 scalarize_elem (tree base, HOST_WIDE_INT pos, HOST_WIDE_INT size, bool reverse,
1099 tree ref, tree type)
1101 if (is_gimple_reg_type (type))
1103 struct access *access = create_access_1 (base, pos, size);
1104 access->expr = ref;
1105 access->type = type;
1106 access->grp_total_scalarization = 1;
1107 access->reverse = reverse;
1108 /* Accesses for intraprocedural SRA can have their stmt NULL. */
1110 else
1111 completely_scalarize (base, type, pos, ref);
1114 /* Create a total_scalarization access for VAR as a whole. VAR must be of a
1115 RECORD_TYPE or ARRAY_TYPE conforming to scalarizable_type_p. */
1117 static void
1118 create_total_scalarization_access (tree var)
1120 HOST_WIDE_INT size = tree_to_uhwi (DECL_SIZE (var));
1121 struct access *access;
1123 access = create_access_1 (var, 0, size);
1124 access->expr = var;
1125 access->type = TREE_TYPE (var);
1126 access->grp_total_scalarization = 1;
1129 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1131 static inline bool
1132 contains_view_convert_expr_p (const_tree ref)
1134 while (handled_component_p (ref))
1136 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
1137 return true;
1138 ref = TREE_OPERAND (ref, 0);
1141 return false;
1144 /* Search the given tree for a declaration by skipping handled components and
1145 exclude it from the candidates. */
1147 static void
1148 disqualify_base_of_expr (tree t, const char *reason)
1150 t = get_base_address (t);
1151 if (sra_mode == SRA_MODE_EARLY_IPA
1152 && TREE_CODE (t) == MEM_REF)
1153 t = get_ssa_base_param (TREE_OPERAND (t, 0));
1155 if (t && DECL_P (t))
1156 disqualify_candidate (t, reason);
1159 /* Scan expression EXPR and create access structures for all accesses to
1160 candidates for scalarization. Return the created access or NULL if none is
1161 created. */
1163 static struct access *
1164 build_access_from_expr_1 (tree expr, gimple *stmt, bool write)
1166 struct access *ret = NULL;
1167 bool partial_ref;
1169 if (TREE_CODE (expr) == BIT_FIELD_REF
1170 || TREE_CODE (expr) == IMAGPART_EXPR
1171 || TREE_CODE (expr) == REALPART_EXPR)
1173 expr = TREE_OPERAND (expr, 0);
1174 partial_ref = true;
1176 else
1177 partial_ref = false;
1179 if (storage_order_barrier_p (expr))
1181 disqualify_base_of_expr (expr, "storage order barrier.");
1182 return NULL;
1185 /* We need to dive through V_C_Es in order to get the size of its parameter
1186 and not the result type. Ada produces such statements. We are also
1187 capable of handling the topmost V_C_E but not any of those buried in other
1188 handled components. */
1189 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
1190 expr = TREE_OPERAND (expr, 0);
1192 if (contains_view_convert_expr_p (expr))
1194 disqualify_base_of_expr (expr, "V_C_E under a different handled "
1195 "component.");
1196 return NULL;
1198 if (TREE_THIS_VOLATILE (expr))
1200 disqualify_base_of_expr (expr, "part of a volatile reference.");
1201 return NULL;
1204 switch (TREE_CODE (expr))
1206 case MEM_REF:
1207 if (TREE_CODE (TREE_OPERAND (expr, 0)) != ADDR_EXPR
1208 && sra_mode != SRA_MODE_EARLY_IPA)
1209 return NULL;
1210 /* fall through */
1211 case VAR_DECL:
1212 case PARM_DECL:
1213 case RESULT_DECL:
1214 case COMPONENT_REF:
1215 case ARRAY_REF:
1216 case ARRAY_RANGE_REF:
1217 ret = create_access (expr, stmt, write);
1218 break;
1220 default:
1221 break;
1224 if (write && partial_ref && ret)
1225 ret->grp_partial_lhs = 1;
1227 return ret;
1230 /* Scan expression EXPR and create access structures for all accesses to
1231 candidates for scalarization. Return true if any access has been inserted.
1232 STMT must be the statement from which the expression is taken, WRITE must be
1233 true if the expression is a store and false otherwise. */
1235 static bool
1236 build_access_from_expr (tree expr, gimple *stmt, bool write)
1238 struct access *access;
1240 access = build_access_from_expr_1 (expr, stmt, write);
1241 if (access)
1243 /* This means the aggregate is accesses as a whole in a way other than an
1244 assign statement and thus cannot be removed even if we had a scalar
1245 replacement for everything. */
1246 if (cannot_scalarize_away_bitmap)
1247 bitmap_set_bit (cannot_scalarize_away_bitmap, DECL_UID (access->base));
1248 return true;
1250 return false;
1253 /* Return the single non-EH successor edge of BB or NULL if there is none or
1254 more than one. */
1256 static edge
1257 single_non_eh_succ (basic_block bb)
1259 edge e, res = NULL;
1260 edge_iterator ei;
1262 FOR_EACH_EDGE (e, ei, bb->succs)
1263 if (!(e->flags & EDGE_EH))
1265 if (res)
1266 return NULL;
1267 res = e;
1270 return res;
1273 /* Disqualify LHS and RHS for scalarization if STMT has to terminate its BB and
1274 there is no alternative spot where to put statements SRA might need to
1275 generate after it. The spot we are looking for is an edge leading to a
1276 single non-EH successor, if it exists and is indeed single. RHS may be
1277 NULL, in that case ignore it. */
1279 static bool
1280 disqualify_if_bad_bb_terminating_stmt (gimple *stmt, tree lhs, tree rhs)
1282 if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1283 && stmt_ends_bb_p (stmt))
1285 if (single_non_eh_succ (gimple_bb (stmt)))
1286 return false;
1288 disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
1289 if (rhs)
1290 disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
1291 return true;
1293 return false;
1296 /* Return true if the nature of BASE is such that it contains data even if
1297 there is no write to it in the function. */
1299 static bool
1300 comes_initialized_p (tree base)
1302 return TREE_CODE (base) == PARM_DECL || constant_decl_p (base);
1305 /* Scan expressions occurring in STMT, create access structures for all accesses
1306 to candidates for scalarization and remove those candidates which occur in
1307 statements or expressions that prevent them from being split apart. Return
1308 true if any access has been inserted. */
1310 static bool
1311 build_accesses_from_assign (gimple *stmt)
1313 tree lhs, rhs;
1314 struct access *lacc, *racc;
1316 if (!gimple_assign_single_p (stmt)
1317 /* Scope clobbers don't influence scalarization. */
1318 || gimple_clobber_p (stmt))
1319 return false;
1321 lhs = gimple_assign_lhs (stmt);
1322 rhs = gimple_assign_rhs1 (stmt);
1324 if (disqualify_if_bad_bb_terminating_stmt (stmt, lhs, rhs))
1325 return false;
1327 racc = build_access_from_expr_1 (rhs, stmt, false);
1328 lacc = build_access_from_expr_1 (lhs, stmt, true);
1330 if (lacc)
1332 lacc->grp_assignment_write = 1;
1333 if (storage_order_barrier_p (rhs))
1334 lacc->grp_unscalarizable_region = 1;
1337 if (racc)
1339 racc->grp_assignment_read = 1;
1340 if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
1341 && !is_gimple_reg_type (racc->type))
1342 bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
1343 if (storage_order_barrier_p (lhs))
1344 racc->grp_unscalarizable_region = 1;
1347 if (lacc && racc
1348 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1349 && !lacc->grp_unscalarizable_region
1350 && !racc->grp_unscalarizable_region
1351 && AGGREGATE_TYPE_P (TREE_TYPE (lhs))
1352 && lacc->size == racc->size
1353 && useless_type_conversion_p (lacc->type, racc->type))
1355 struct assign_link *link;
1357 link = assign_link_pool.allocate ();
1358 memset (link, 0, sizeof (struct assign_link));
1360 link->lacc = lacc;
1361 link->racc = racc;
1362 add_link_to_rhs (racc, link);
1363 add_access_to_work_queue (racc);
1365 /* Let's delay marking the areas as written until propagation of accesses
1366 across link, unless the nature of rhs tells us that its data comes
1367 from elsewhere. */
1368 if (!comes_initialized_p (racc->base))
1369 lacc->write = false;
1372 return lacc || racc;
1375 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1376 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1378 static bool
1379 asm_visit_addr (gimple *, tree op, tree, void *)
1381 op = get_base_address (op);
1382 if (op
1383 && DECL_P (op))
1384 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
1386 return false;
1389 /* Return true iff callsite CALL has at least as many actual arguments as there
1390 are formal parameters of the function currently processed by IPA-SRA and
1391 that their types match. */
1393 static inline bool
1394 callsite_arguments_match_p (gimple *call)
1396 if (gimple_call_num_args (call) < (unsigned) func_param_count)
1397 return false;
1399 tree parm;
1400 int i;
1401 for (parm = DECL_ARGUMENTS (current_function_decl), i = 0;
1402 parm;
1403 parm = DECL_CHAIN (parm), i++)
1405 tree arg = gimple_call_arg (call, i);
1406 if (!useless_type_conversion_p (TREE_TYPE (parm), TREE_TYPE (arg)))
1407 return false;
1409 return true;
1412 /* Scan function and look for interesting expressions and create access
1413 structures for them. Return true iff any access is created. */
1415 static bool
1416 scan_function (void)
1418 basic_block bb;
1419 bool ret = false;
1421 FOR_EACH_BB_FN (bb, cfun)
1423 gimple_stmt_iterator gsi;
1424 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1426 gimple *stmt = gsi_stmt (gsi);
1427 tree t;
1428 unsigned i;
1430 if (final_bbs && stmt_can_throw_external (stmt))
1431 bitmap_set_bit (final_bbs, bb->index);
1432 switch (gimple_code (stmt))
1434 case GIMPLE_RETURN:
1435 t = gimple_return_retval (as_a <greturn *> (stmt));
1436 if (t != NULL_TREE)
1437 ret |= build_access_from_expr (t, stmt, false);
1438 if (final_bbs)
1439 bitmap_set_bit (final_bbs, bb->index);
1440 break;
1442 case GIMPLE_ASSIGN:
1443 ret |= build_accesses_from_assign (stmt);
1444 break;
1446 case GIMPLE_CALL:
1447 for (i = 0; i < gimple_call_num_args (stmt); i++)
1448 ret |= build_access_from_expr (gimple_call_arg (stmt, i),
1449 stmt, false);
1451 if (sra_mode == SRA_MODE_EARLY_IPA)
1453 tree dest = gimple_call_fndecl (stmt);
1454 int flags = gimple_call_flags (stmt);
1456 if (dest)
1458 if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1459 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1460 encountered_apply_args = true;
1461 if (recursive_call_p (current_function_decl, dest))
1463 encountered_recursive_call = true;
1464 if (!callsite_arguments_match_p (stmt))
1465 encountered_unchangable_recursive_call = true;
1469 if (final_bbs
1470 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1471 bitmap_set_bit (final_bbs, bb->index);
1474 t = gimple_call_lhs (stmt);
1475 if (t && !disqualify_if_bad_bb_terminating_stmt (stmt, t, NULL))
1476 ret |= build_access_from_expr (t, stmt, true);
1477 break;
1479 case GIMPLE_ASM:
1481 gasm *asm_stmt = as_a <gasm *> (stmt);
1482 walk_stmt_load_store_addr_ops (asm_stmt, NULL, NULL, NULL,
1483 asm_visit_addr);
1484 if (final_bbs)
1485 bitmap_set_bit (final_bbs, bb->index);
1487 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
1489 t = TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
1490 ret |= build_access_from_expr (t, asm_stmt, false);
1492 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
1494 t = TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
1495 ret |= build_access_from_expr (t, asm_stmt, true);
1498 break;
1500 default:
1501 break;
1506 return ret;
1509 /* Helper of QSORT function. There are pointers to accesses in the array. An
1510 access is considered smaller than another if it has smaller offset or if the
1511 offsets are the same but is size is bigger. */
1513 static int
1514 compare_access_positions (const void *a, const void *b)
1516 const access_p *fp1 = (const access_p *) a;
1517 const access_p *fp2 = (const access_p *) b;
1518 const access_p f1 = *fp1;
1519 const access_p f2 = *fp2;
1521 if (f1->offset != f2->offset)
1522 return f1->offset < f2->offset ? -1 : 1;
1524 if (f1->size == f2->size)
1526 if (f1->type == f2->type)
1527 return 0;
1528 /* Put any non-aggregate type before any aggregate type. */
1529 else if (!is_gimple_reg_type (f1->type)
1530 && is_gimple_reg_type (f2->type))
1531 return 1;
1532 else if (is_gimple_reg_type (f1->type)
1533 && !is_gimple_reg_type (f2->type))
1534 return -1;
1535 /* Put any complex or vector type before any other scalar type. */
1536 else if (TREE_CODE (f1->type) != COMPLEX_TYPE
1537 && TREE_CODE (f1->type) != VECTOR_TYPE
1538 && (TREE_CODE (f2->type) == COMPLEX_TYPE
1539 || TREE_CODE (f2->type) == VECTOR_TYPE))
1540 return 1;
1541 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
1542 || TREE_CODE (f1->type) == VECTOR_TYPE)
1543 && TREE_CODE (f2->type) != COMPLEX_TYPE
1544 && TREE_CODE (f2->type) != VECTOR_TYPE)
1545 return -1;
1546 /* Put any integral type before any non-integral type. When splicing, we
1547 make sure that those with insufficient precision and occupying the
1548 same space are not scalarized. */
1549 else if (INTEGRAL_TYPE_P (f1->type)
1550 && !INTEGRAL_TYPE_P (f2->type))
1551 return -1;
1552 else if (!INTEGRAL_TYPE_P (f1->type)
1553 && INTEGRAL_TYPE_P (f2->type))
1554 return 1;
1555 /* Put the integral type with the bigger precision first. */
1556 else if (INTEGRAL_TYPE_P (f1->type)
1557 && INTEGRAL_TYPE_P (f2->type)
1558 && (TYPE_PRECISION (f2->type) != TYPE_PRECISION (f1->type)))
1559 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
1560 /* Stabilize the sort. */
1561 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1564 /* We want the bigger accesses first, thus the opposite operator in the next
1565 line: */
1566 return f1->size > f2->size ? -1 : 1;
1570 /* Append a name of the declaration to the name obstack. A helper function for
1571 make_fancy_name. */
1573 static void
1574 make_fancy_decl_name (tree decl)
1576 char buffer[32];
1578 tree name = DECL_NAME (decl);
1579 if (name)
1580 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1581 IDENTIFIER_LENGTH (name));
1582 else
1584 sprintf (buffer, "D%u", DECL_UID (decl));
1585 obstack_grow (&name_obstack, buffer, strlen (buffer));
1589 /* Helper for make_fancy_name. */
1591 static void
1592 make_fancy_name_1 (tree expr)
1594 char buffer[32];
1595 tree index;
1597 if (DECL_P (expr))
1599 make_fancy_decl_name (expr);
1600 return;
1603 switch (TREE_CODE (expr))
1605 case COMPONENT_REF:
1606 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1607 obstack_1grow (&name_obstack, '$');
1608 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1609 break;
1611 case ARRAY_REF:
1612 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1613 obstack_1grow (&name_obstack, '$');
1614 /* Arrays with only one element may not have a constant as their
1615 index. */
1616 index = TREE_OPERAND (expr, 1);
1617 if (TREE_CODE (index) != INTEGER_CST)
1618 break;
1619 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1620 obstack_grow (&name_obstack, buffer, strlen (buffer));
1621 break;
1623 case ADDR_EXPR:
1624 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1625 break;
1627 case MEM_REF:
1628 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1629 if (!integer_zerop (TREE_OPERAND (expr, 1)))
1631 obstack_1grow (&name_obstack, '$');
1632 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC,
1633 TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)));
1634 obstack_grow (&name_obstack, buffer, strlen (buffer));
1636 break;
1638 case BIT_FIELD_REF:
1639 case REALPART_EXPR:
1640 case IMAGPART_EXPR:
1641 gcc_unreachable (); /* we treat these as scalars. */
1642 break;
1643 default:
1644 break;
1648 /* Create a human readable name for replacement variable of ACCESS. */
1650 static char *
1651 make_fancy_name (tree expr)
1653 make_fancy_name_1 (expr);
1654 obstack_1grow (&name_obstack, '\0');
1655 return XOBFINISH (&name_obstack, char *);
1658 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1659 EXP_TYPE at the given OFFSET and with storage order REVERSE. If BASE is
1660 something for which get_addr_base_and_unit_offset returns NULL, gsi must
1661 be non-NULL and is used to insert new statements either before or below
1662 the current one as specified by INSERT_AFTER. This function is not capable
1663 of handling bitfields. */
1665 tree
1666 build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
1667 bool reverse, tree exp_type, gimple_stmt_iterator *gsi,
1668 bool insert_after)
1670 tree prev_base = base;
1671 tree off;
1672 tree mem_ref;
1673 HOST_WIDE_INT base_offset;
1674 unsigned HOST_WIDE_INT misalign;
1675 unsigned int align;
1677 /* Preserve address-space information. */
1678 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (base));
1679 if (as != TYPE_ADDR_SPACE (exp_type))
1680 exp_type = build_qualified_type (exp_type,
1681 TYPE_QUALS (exp_type)
1682 | ENCODE_QUAL_ADDR_SPACE (as));
1684 gcc_checking_assert (offset % BITS_PER_UNIT == 0);
1685 get_object_alignment_1 (base, &align, &misalign);
1686 base = get_addr_base_and_unit_offset (base, &base_offset);
1688 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1689 offset such as array[var_index]. */
1690 if (!base)
1692 gassign *stmt;
1693 tree tmp, addr;
1695 gcc_checking_assert (gsi);
1696 tmp = make_ssa_name (build_pointer_type (TREE_TYPE (prev_base)));
1697 addr = build_fold_addr_expr (unshare_expr (prev_base));
1698 STRIP_USELESS_TYPE_CONVERSION (addr);
1699 stmt = gimple_build_assign (tmp, addr);
1700 gimple_set_location (stmt, loc);
1701 if (insert_after)
1702 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
1703 else
1704 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1706 off = build_int_cst (reference_alias_ptr_type (prev_base),
1707 offset / BITS_PER_UNIT);
1708 base = tmp;
1710 else if (TREE_CODE (base) == MEM_REF)
1712 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1713 base_offset + offset / BITS_PER_UNIT);
1714 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1715 base = unshare_expr (TREE_OPERAND (base, 0));
1717 else
1719 off = build_int_cst (reference_alias_ptr_type (prev_base),
1720 base_offset + offset / BITS_PER_UNIT);
1721 base = build_fold_addr_expr (unshare_expr (base));
1724 misalign = (misalign + offset) & (align - 1);
1725 if (misalign != 0)
1726 align = least_bit_hwi (misalign);
1727 if (align != TYPE_ALIGN (exp_type))
1728 exp_type = build_aligned_type (exp_type, align);
1730 mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off);
1731 REF_REVERSE_STORAGE_ORDER (mem_ref) = reverse;
1732 if (TREE_THIS_VOLATILE (prev_base))
1733 TREE_THIS_VOLATILE (mem_ref) = 1;
1734 if (TREE_SIDE_EFFECTS (prev_base))
1735 TREE_SIDE_EFFECTS (mem_ref) = 1;
1736 return mem_ref;
1739 /* Construct a memory reference to a part of an aggregate BASE at the given
1740 OFFSET and of the same type as MODEL. In case this is a reference to a
1741 bit-field, the function will replicate the last component_ref of model's
1742 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1743 build_ref_for_offset. */
1745 static tree
1746 build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1747 struct access *model, gimple_stmt_iterator *gsi,
1748 bool insert_after)
1750 if (TREE_CODE (model->expr) == COMPONENT_REF
1751 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1753 /* This access represents a bit-field. */
1754 tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
1756 offset -= int_bit_position (fld);
1757 exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
1758 t = build_ref_for_offset (loc, base, offset, model->reverse, exp_type,
1759 gsi, insert_after);
1760 /* The flag will be set on the record type. */
1761 REF_REVERSE_STORAGE_ORDER (t) = 0;
1762 return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
1763 NULL_TREE);
1765 else
1766 return
1767 build_ref_for_offset (loc, base, offset, model->reverse, model->type,
1768 gsi, insert_after);
1771 /* Attempt to build a memory reference that we could but into a gimple
1772 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1773 create statements and return s NULL instead. This function also ignores
1774 alignment issues and so its results should never end up in non-debug
1775 statements. */
1777 static tree
1778 build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1779 struct access *model)
1781 HOST_WIDE_INT base_offset;
1782 tree off;
1784 if (TREE_CODE (model->expr) == COMPONENT_REF
1785 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1786 return NULL_TREE;
1788 base = get_addr_base_and_unit_offset (base, &base_offset);
1789 if (!base)
1790 return NULL_TREE;
1791 if (TREE_CODE (base) == MEM_REF)
1793 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1794 base_offset + offset / BITS_PER_UNIT);
1795 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1796 base = unshare_expr (TREE_OPERAND (base, 0));
1798 else
1800 off = build_int_cst (reference_alias_ptr_type (base),
1801 base_offset + offset / BITS_PER_UNIT);
1802 base = build_fold_addr_expr (unshare_expr (base));
1805 return fold_build2_loc (loc, MEM_REF, model->type, base, off);
1808 /* Construct a memory reference consisting of component_refs and array_refs to
1809 a part of an aggregate *RES (which is of type TYPE). The requested part
1810 should have type EXP_TYPE at be the given OFFSET. This function might not
1811 succeed, it returns true when it does and only then *RES points to something
1812 meaningful. This function should be used only to build expressions that we
1813 might need to present to user (e.g. in warnings). In all other situations,
1814 build_ref_for_model or build_ref_for_offset should be used instead. */
1816 static bool
1817 build_user_friendly_ref_for_offset (tree *res, tree type, HOST_WIDE_INT offset,
1818 tree exp_type)
1820 while (1)
1822 tree fld;
1823 tree tr_size, index, minidx;
1824 HOST_WIDE_INT el_size;
1826 if (offset == 0 && exp_type
1827 && types_compatible_p (exp_type, type))
1828 return true;
1830 switch (TREE_CODE (type))
1832 case UNION_TYPE:
1833 case QUAL_UNION_TYPE:
1834 case RECORD_TYPE:
1835 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
1837 HOST_WIDE_INT pos, size;
1838 tree tr_pos, expr, *expr_ptr;
1840 if (TREE_CODE (fld) != FIELD_DECL)
1841 continue;
1843 tr_pos = bit_position (fld);
1844 if (!tr_pos || !tree_fits_uhwi_p (tr_pos))
1845 continue;
1846 pos = tree_to_uhwi (tr_pos);
1847 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1848 tr_size = DECL_SIZE (fld);
1849 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1850 continue;
1851 size = tree_to_uhwi (tr_size);
1852 if (size == 0)
1854 if (pos != offset)
1855 continue;
1857 else if (pos > offset || (pos + size) <= offset)
1858 continue;
1860 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1861 NULL_TREE);
1862 expr_ptr = &expr;
1863 if (build_user_friendly_ref_for_offset (expr_ptr, TREE_TYPE (fld),
1864 offset - pos, exp_type))
1866 *res = expr;
1867 return true;
1870 return false;
1872 case ARRAY_TYPE:
1873 tr_size = TYPE_SIZE (TREE_TYPE (type));
1874 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1875 return false;
1876 el_size = tree_to_uhwi (tr_size);
1878 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1879 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
1880 return false;
1881 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1882 if (!integer_zerop (minidx))
1883 index = int_const_binop (PLUS_EXPR, index, minidx);
1884 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1885 NULL_TREE, NULL_TREE);
1886 offset = offset % el_size;
1887 type = TREE_TYPE (type);
1888 break;
1890 default:
1891 if (offset != 0)
1892 return false;
1894 if (exp_type)
1895 return false;
1896 else
1897 return true;
1902 /* Return true iff TYPE is stdarg va_list type. */
1904 static inline bool
1905 is_va_list_type (tree type)
1907 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1910 /* Print message to dump file why a variable was rejected. */
1912 static void
1913 reject (tree var, const char *msg)
1915 if (dump_file && (dump_flags & TDF_DETAILS))
1917 fprintf (dump_file, "Rejected (%d): %s: ", DECL_UID (var), msg);
1918 print_generic_expr (dump_file, var);
1919 fprintf (dump_file, "\n");
1923 /* Return true if VAR is a candidate for SRA. */
1925 static bool
1926 maybe_add_sra_candidate (tree var)
1928 tree type = TREE_TYPE (var);
1929 const char *msg;
1930 tree_node **slot;
1932 if (!AGGREGATE_TYPE_P (type))
1934 reject (var, "not aggregate");
1935 return false;
1937 /* Allow constant-pool entries (that "need to live in memory")
1938 unless we are doing IPA SRA. */
1939 if (needs_to_live_in_memory (var)
1940 && (sra_mode == SRA_MODE_EARLY_IPA || !constant_decl_p (var)))
1942 reject (var, "needs to live in memory");
1943 return false;
1945 if (TREE_THIS_VOLATILE (var))
1947 reject (var, "is volatile");
1948 return false;
1950 if (!COMPLETE_TYPE_P (type))
1952 reject (var, "has incomplete type");
1953 return false;
1955 if (!tree_fits_uhwi_p (TYPE_SIZE (type)))
1957 reject (var, "type size not fixed");
1958 return false;
1960 if (tree_to_uhwi (TYPE_SIZE (type)) == 0)
1962 reject (var, "type size is zero");
1963 return false;
1965 if (type_internals_preclude_sra_p (type, &msg))
1967 reject (var, msg);
1968 return false;
1970 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1971 we also want to schedule it rather late. Thus we ignore it in
1972 the early pass. */
1973 (sra_mode == SRA_MODE_EARLY_INTRA
1974 && is_va_list_type (type)))
1976 reject (var, "is va_list");
1977 return false;
1980 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
1981 slot = candidates->find_slot_with_hash (var, DECL_UID (var), INSERT);
1982 *slot = var;
1984 if (dump_file && (dump_flags & TDF_DETAILS))
1986 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
1987 print_generic_expr (dump_file, var);
1988 fprintf (dump_file, "\n");
1991 return true;
1994 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1995 those with type which is suitable for scalarization. */
1997 static bool
1998 find_var_candidates (void)
2000 tree var, parm;
2001 unsigned int i;
2002 bool ret = false;
2004 for (parm = DECL_ARGUMENTS (current_function_decl);
2005 parm;
2006 parm = DECL_CHAIN (parm))
2007 ret |= maybe_add_sra_candidate (parm);
2009 FOR_EACH_LOCAL_DECL (cfun, i, var)
2011 if (!VAR_P (var))
2012 continue;
2014 ret |= maybe_add_sra_candidate (var);
2017 return ret;
2020 /* Sort all accesses for the given variable, check for partial overlaps and
2021 return NULL if there are any. If there are none, pick a representative for
2022 each combination of offset and size and create a linked list out of them.
2023 Return the pointer to the first representative and make sure it is the first
2024 one in the vector of accesses. */
2026 static struct access *
2027 sort_and_splice_var_accesses (tree var)
2029 int i, j, access_count;
2030 struct access *res, **prev_acc_ptr = &res;
2031 vec<access_p> *access_vec;
2032 bool first = true;
2033 HOST_WIDE_INT low = -1, high = 0;
2035 access_vec = get_base_access_vector (var);
2036 if (!access_vec)
2037 return NULL;
2038 access_count = access_vec->length ();
2040 /* Sort by <OFFSET, SIZE>. */
2041 access_vec->qsort (compare_access_positions);
2043 i = 0;
2044 while (i < access_count)
2046 struct access *access = (*access_vec)[i];
2047 bool grp_write = access->write;
2048 bool grp_read = !access->write;
2049 bool grp_scalar_write = access->write
2050 && is_gimple_reg_type (access->type);
2051 bool grp_scalar_read = !access->write
2052 && is_gimple_reg_type (access->type);
2053 bool grp_assignment_read = access->grp_assignment_read;
2054 bool grp_assignment_write = access->grp_assignment_write;
2055 bool multiple_scalar_reads = false;
2056 bool total_scalarization = access->grp_total_scalarization;
2057 bool grp_partial_lhs = access->grp_partial_lhs;
2058 bool first_scalar = is_gimple_reg_type (access->type);
2059 bool unscalarizable_region = access->grp_unscalarizable_region;
2060 bool bf_non_full_precision
2061 = (INTEGRAL_TYPE_P (access->type)
2062 && TYPE_PRECISION (access->type) != access->size
2063 && TREE_CODE (access->expr) == COMPONENT_REF
2064 && DECL_BIT_FIELD (TREE_OPERAND (access->expr, 1)));
2066 if (first || access->offset >= high)
2068 first = false;
2069 low = access->offset;
2070 high = access->offset + access->size;
2072 else if (access->offset > low && access->offset + access->size > high)
2073 return NULL;
2074 else
2075 gcc_assert (access->offset >= low
2076 && access->offset + access->size <= high);
2078 j = i + 1;
2079 while (j < access_count)
2081 struct access *ac2 = (*access_vec)[j];
2082 if (ac2->offset != access->offset || ac2->size != access->size)
2083 break;
2084 if (ac2->write)
2086 grp_write = true;
2087 grp_scalar_write = (grp_scalar_write
2088 || is_gimple_reg_type (ac2->type));
2090 else
2092 grp_read = true;
2093 if (is_gimple_reg_type (ac2->type))
2095 if (grp_scalar_read)
2096 multiple_scalar_reads = true;
2097 else
2098 grp_scalar_read = true;
2101 grp_assignment_read |= ac2->grp_assignment_read;
2102 grp_assignment_write |= ac2->grp_assignment_write;
2103 grp_partial_lhs |= ac2->grp_partial_lhs;
2104 unscalarizable_region |= ac2->grp_unscalarizable_region;
2105 total_scalarization |= ac2->grp_total_scalarization;
2106 relink_to_new_repr (access, ac2);
2108 /* If there are both aggregate-type and scalar-type accesses with
2109 this combination of size and offset, the comparison function
2110 should have put the scalars first. */
2111 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
2112 /* It also prefers integral types to non-integral. However, when the
2113 precision of the selected type does not span the entire area and
2114 should also be used for a non-integer (i.e. float), we must not
2115 let that happen. Normally analyze_access_subtree expands the type
2116 to cover the entire area but for bit-fields it doesn't. */
2117 if (bf_non_full_precision && !INTEGRAL_TYPE_P (ac2->type))
2119 if (dump_file && (dump_flags & TDF_DETAILS))
2121 fprintf (dump_file, "Cannot scalarize the following access "
2122 "because insufficient precision integer type was "
2123 "selected.\n ");
2124 dump_access (dump_file, access, false);
2126 unscalarizable_region = true;
2128 ac2->group_representative = access;
2129 j++;
2132 i = j;
2134 access->group_representative = access;
2135 access->grp_write = grp_write;
2136 access->grp_read = grp_read;
2137 access->grp_scalar_read = grp_scalar_read;
2138 access->grp_scalar_write = grp_scalar_write;
2139 access->grp_assignment_read = grp_assignment_read;
2140 access->grp_assignment_write = grp_assignment_write;
2141 access->grp_hint = total_scalarization
2142 || (multiple_scalar_reads && !constant_decl_p (var));
2143 access->grp_total_scalarization = total_scalarization;
2144 access->grp_partial_lhs = grp_partial_lhs;
2145 access->grp_unscalarizable_region = unscalarizable_region;
2147 *prev_acc_ptr = access;
2148 prev_acc_ptr = &access->next_grp;
2151 gcc_assert (res == (*access_vec)[0]);
2152 return res;
2155 /* Create a variable for the given ACCESS which determines the type, name and a
2156 few other properties. Return the variable declaration and store it also to
2157 ACCESS->replacement. */
2159 static tree
2160 create_access_replacement (struct access *access)
2162 tree repl;
2164 if (access->grp_to_be_debug_replaced)
2166 repl = create_tmp_var_raw (access->type);
2167 DECL_CONTEXT (repl) = current_function_decl;
2169 else
2170 /* Drop any special alignment on the type if it's not on the main
2171 variant. This avoids issues with weirdo ABIs like AAPCS. */
2172 repl = create_tmp_var (build_qualified_type
2173 (TYPE_MAIN_VARIANT (access->type),
2174 TYPE_QUALS (access->type)), "SR");
2175 if (TREE_CODE (access->type) == COMPLEX_TYPE
2176 || TREE_CODE (access->type) == VECTOR_TYPE)
2178 if (!access->grp_partial_lhs)
2179 DECL_GIMPLE_REG_P (repl) = 1;
2181 else if (access->grp_partial_lhs
2182 && is_gimple_reg_type (access->type))
2183 TREE_ADDRESSABLE (repl) = 1;
2185 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
2186 DECL_ARTIFICIAL (repl) = 1;
2187 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
2189 if (DECL_NAME (access->base)
2190 && !DECL_IGNORED_P (access->base)
2191 && !DECL_ARTIFICIAL (access->base))
2193 char *pretty_name = make_fancy_name (access->expr);
2194 tree debug_expr = unshare_expr_without_location (access->expr), d;
2195 bool fail = false;
2197 DECL_NAME (repl) = get_identifier (pretty_name);
2198 DECL_NAMELESS (repl) = 1;
2199 obstack_free (&name_obstack, pretty_name);
2201 /* Get rid of any SSA_NAMEs embedded in debug_expr,
2202 as DECL_DEBUG_EXPR isn't considered when looking for still
2203 used SSA_NAMEs and thus they could be freed. All debug info
2204 generation cares is whether something is constant or variable
2205 and that get_ref_base_and_extent works properly on the
2206 expression. It cannot handle accesses at a non-constant offset
2207 though, so just give up in those cases. */
2208 for (d = debug_expr;
2209 !fail && (handled_component_p (d) || TREE_CODE (d) == MEM_REF);
2210 d = TREE_OPERAND (d, 0))
2211 switch (TREE_CODE (d))
2213 case ARRAY_REF:
2214 case ARRAY_RANGE_REF:
2215 if (TREE_OPERAND (d, 1)
2216 && TREE_CODE (TREE_OPERAND (d, 1)) != INTEGER_CST)
2217 fail = true;
2218 if (TREE_OPERAND (d, 3)
2219 && TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST)
2220 fail = true;
2221 /* FALLTHRU */
2222 case COMPONENT_REF:
2223 if (TREE_OPERAND (d, 2)
2224 && TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST)
2225 fail = true;
2226 break;
2227 case MEM_REF:
2228 if (TREE_CODE (TREE_OPERAND (d, 0)) != ADDR_EXPR)
2229 fail = true;
2230 else
2231 d = TREE_OPERAND (d, 0);
2232 break;
2233 default:
2234 break;
2236 if (!fail)
2238 SET_DECL_DEBUG_EXPR (repl, debug_expr);
2239 DECL_HAS_DEBUG_EXPR_P (repl) = 1;
2241 if (access->grp_no_warning)
2242 TREE_NO_WARNING (repl) = 1;
2243 else
2244 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
2246 else
2247 TREE_NO_WARNING (repl) = 1;
2249 if (dump_file)
2251 if (access->grp_to_be_debug_replaced)
2253 fprintf (dump_file, "Created a debug-only replacement for ");
2254 print_generic_expr (dump_file, access->base);
2255 fprintf (dump_file, " offset: %u, size: %u\n",
2256 (unsigned) access->offset, (unsigned) access->size);
2258 else
2260 fprintf (dump_file, "Created a replacement for ");
2261 print_generic_expr (dump_file, access->base);
2262 fprintf (dump_file, " offset: %u, size: %u: ",
2263 (unsigned) access->offset, (unsigned) access->size);
2264 print_generic_expr (dump_file, repl);
2265 fprintf (dump_file, "\n");
2268 sra_stats.replacements++;
2270 return repl;
2273 /* Return ACCESS scalar replacement, which must exist. */
2275 static inline tree
2276 get_access_replacement (struct access *access)
2278 gcc_checking_assert (access->replacement_decl);
2279 return access->replacement_decl;
2283 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2284 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2285 to it is not "within" the root. Return false iff some accesses partially
2286 overlap. */
2288 static bool
2289 build_access_subtree (struct access **access)
2291 struct access *root = *access, *last_child = NULL;
2292 HOST_WIDE_INT limit = root->offset + root->size;
2294 *access = (*access)->next_grp;
2295 while (*access && (*access)->offset + (*access)->size <= limit)
2297 if (!last_child)
2298 root->first_child = *access;
2299 else
2300 last_child->next_sibling = *access;
2301 last_child = *access;
2302 (*access)->parent = root;
2303 (*access)->grp_write |= root->grp_write;
2305 if (!build_access_subtree (access))
2306 return false;
2309 if (*access && (*access)->offset < limit)
2310 return false;
2312 return true;
2315 /* Build a tree of access representatives, ACCESS is the pointer to the first
2316 one, others are linked in a list by the next_grp field. Return false iff
2317 some accesses partially overlap. */
2319 static bool
2320 build_access_trees (struct access *access)
2322 while (access)
2324 struct access *root = access;
2326 if (!build_access_subtree (&access))
2327 return false;
2328 root->next_grp = access;
2330 return true;
2333 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2334 array. */
2336 static bool
2337 expr_with_var_bounded_array_refs_p (tree expr)
2339 while (handled_component_p (expr))
2341 if (TREE_CODE (expr) == ARRAY_REF
2342 && !tree_fits_shwi_p (array_ref_low_bound (expr)))
2343 return true;
2344 expr = TREE_OPERAND (expr, 0);
2346 return false;
2349 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2350 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2351 sorts of access flags appropriately along the way, notably always set
2352 grp_read and grp_assign_read according to MARK_READ and grp_write when
2353 MARK_WRITE is true.
2355 Creating a replacement for a scalar access is considered beneficial if its
2356 grp_hint is set (this means we are either attempting total scalarization or
2357 there is more than one direct read access) or according to the following
2358 table:
2360 Access written to through a scalar type (once or more times)
2362 | Written to in an assignment statement
2364 | | Access read as scalar _once_
2365 | | |
2366 | | | Read in an assignment statement
2367 | | | |
2368 | | | | Scalarize Comment
2369 -----------------------------------------------------------------------------
2370 0 0 0 0 No access for the scalar
2371 0 0 0 1 No access for the scalar
2372 0 0 1 0 No Single read - won't help
2373 0 0 1 1 No The same case
2374 0 1 0 0 No access for the scalar
2375 0 1 0 1 No access for the scalar
2376 0 1 1 0 Yes s = *g; return s.i;
2377 0 1 1 1 Yes The same case as above
2378 1 0 0 0 No Won't help
2379 1 0 0 1 Yes s.i = 1; *g = s;
2380 1 0 1 0 Yes s.i = 5; g = s.i;
2381 1 0 1 1 Yes The same case as above
2382 1 1 0 0 No Won't help.
2383 1 1 0 1 Yes s.i = 1; *g = s;
2384 1 1 1 0 Yes s = *g; return s.i;
2385 1 1 1 1 Yes Any of the above yeses */
2387 static bool
2388 analyze_access_subtree (struct access *root, struct access *parent,
2389 bool allow_replacements)
2391 struct access *child;
2392 HOST_WIDE_INT limit = root->offset + root->size;
2393 HOST_WIDE_INT covered_to = root->offset;
2394 bool scalar = is_gimple_reg_type (root->type);
2395 bool hole = false, sth_created = false;
2397 if (parent)
2399 if (parent->grp_read)
2400 root->grp_read = 1;
2401 if (parent->grp_assignment_read)
2402 root->grp_assignment_read = 1;
2403 if (parent->grp_write)
2404 root->grp_write = 1;
2405 if (parent->grp_assignment_write)
2406 root->grp_assignment_write = 1;
2407 if (parent->grp_total_scalarization)
2408 root->grp_total_scalarization = 1;
2411 if (root->grp_unscalarizable_region)
2412 allow_replacements = false;
2414 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
2415 allow_replacements = false;
2417 for (child = root->first_child; child; child = child->next_sibling)
2419 hole |= covered_to < child->offset;
2420 sth_created |= analyze_access_subtree (child, root,
2421 allow_replacements && !scalar);
2423 root->grp_unscalarized_data |= child->grp_unscalarized_data;
2424 root->grp_total_scalarization &= child->grp_total_scalarization;
2425 if (child->grp_covered)
2426 covered_to += child->size;
2427 else
2428 hole = true;
2431 if (allow_replacements && scalar && !root->first_child
2432 && (root->grp_hint
2433 || ((root->grp_scalar_read || root->grp_assignment_read)
2434 && (root->grp_scalar_write || root->grp_assignment_write))))
2436 /* Always create access replacements that cover the whole access.
2437 For integral types this means the precision has to match.
2438 Avoid assumptions based on the integral type kind, too. */
2439 if (INTEGRAL_TYPE_P (root->type)
2440 && (TREE_CODE (root->type) != INTEGER_TYPE
2441 || TYPE_PRECISION (root->type) != root->size)
2442 /* But leave bitfield accesses alone. */
2443 && (TREE_CODE (root->expr) != COMPONENT_REF
2444 || !DECL_BIT_FIELD (TREE_OPERAND (root->expr, 1))))
2446 tree rt = root->type;
2447 gcc_assert ((root->offset % BITS_PER_UNIT) == 0
2448 && (root->size % BITS_PER_UNIT) == 0);
2449 root->type = build_nonstandard_integer_type (root->size,
2450 TYPE_UNSIGNED (rt));
2451 root->expr = build_ref_for_offset (UNKNOWN_LOCATION, root->base,
2452 root->offset, root->reverse,
2453 root->type, NULL, false);
2455 if (dump_file && (dump_flags & TDF_DETAILS))
2457 fprintf (dump_file, "Changing the type of a replacement for ");
2458 print_generic_expr (dump_file, root->base);
2459 fprintf (dump_file, " offset: %u, size: %u ",
2460 (unsigned) root->offset, (unsigned) root->size);
2461 fprintf (dump_file, " to an integer.\n");
2465 root->grp_to_be_replaced = 1;
2466 root->replacement_decl = create_access_replacement (root);
2467 sth_created = true;
2468 hole = false;
2470 else
2472 if (allow_replacements
2473 && scalar && !root->first_child
2474 && (root->grp_scalar_write || root->grp_assignment_write)
2475 && !bitmap_bit_p (cannot_scalarize_away_bitmap,
2476 DECL_UID (root->base)))
2478 gcc_checking_assert (!root->grp_scalar_read
2479 && !root->grp_assignment_read);
2480 sth_created = true;
2481 if (MAY_HAVE_DEBUG_STMTS)
2483 root->grp_to_be_debug_replaced = 1;
2484 root->replacement_decl = create_access_replacement (root);
2488 if (covered_to < limit)
2489 hole = true;
2490 if (scalar || !allow_replacements)
2491 root->grp_total_scalarization = 0;
2494 if (!hole || root->grp_total_scalarization)
2495 root->grp_covered = 1;
2496 else if (root->grp_write || comes_initialized_p (root->base))
2497 root->grp_unscalarized_data = 1; /* not covered and written to */
2498 return sth_created;
2501 /* Analyze all access trees linked by next_grp by the means of
2502 analyze_access_subtree. */
2503 static bool
2504 analyze_access_trees (struct access *access)
2506 bool ret = false;
2508 while (access)
2510 if (analyze_access_subtree (access, NULL, true))
2511 ret = true;
2512 access = access->next_grp;
2515 return ret;
2518 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2519 SIZE would conflict with an already existing one. If exactly such a child
2520 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2522 static bool
2523 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
2524 HOST_WIDE_INT size, struct access **exact_match)
2526 struct access *child;
2528 for (child = lacc->first_child; child; child = child->next_sibling)
2530 if (child->offset == norm_offset && child->size == size)
2532 *exact_match = child;
2533 return true;
2536 if (child->offset < norm_offset + size
2537 && child->offset + child->size > norm_offset)
2538 return true;
2541 return false;
2544 /* Create a new child access of PARENT, with all properties just like MODEL
2545 except for its offset and with its grp_write false and grp_read true.
2546 Return the new access or NULL if it cannot be created. Note that this
2547 access is created long after all splicing and sorting, it's not located in
2548 any access vector and is automatically a representative of its group. Set
2549 the gpr_write flag of the new accesss if SET_GRP_WRITE is true. */
2551 static struct access *
2552 create_artificial_child_access (struct access *parent, struct access *model,
2553 HOST_WIDE_INT new_offset,
2554 bool set_grp_write)
2556 struct access **child;
2557 tree expr = parent->base;
2559 gcc_assert (!model->grp_unscalarizable_region);
2561 struct access *access = access_pool.allocate ();
2562 memset (access, 0, sizeof (struct access));
2563 if (!build_user_friendly_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
2564 model->type))
2566 access->grp_no_warning = true;
2567 expr = build_ref_for_model (EXPR_LOCATION (parent->base), parent->base,
2568 new_offset, model, NULL, false);
2571 access->base = parent->base;
2572 access->expr = expr;
2573 access->offset = new_offset;
2574 access->size = model->size;
2575 access->type = model->type;
2576 access->grp_write = set_grp_write;
2577 access->grp_read = false;
2578 access->reverse = model->reverse;
2580 child = &parent->first_child;
2581 while (*child && (*child)->offset < new_offset)
2582 child = &(*child)->next_sibling;
2584 access->next_sibling = *child;
2585 *child = access;
2587 return access;
2591 /* Beginning with ACCESS, traverse its whole access subtree and mark all
2592 sub-trees as written to. If any of them has not been marked so previously
2593 and has assignment links leading from it, re-enqueue it. */
2595 static void
2596 subtree_mark_written_and_enqueue (struct access *access)
2598 if (access->grp_write)
2599 return;
2600 access->grp_write = true;
2601 add_access_to_work_queue (access);
2603 struct access *child;
2604 for (child = access->first_child; child; child = child->next_sibling)
2605 subtree_mark_written_and_enqueue (child);
2608 /* Propagate subaccesses and grp_write flags of RACC across an assignment link
2609 to LACC. Enqueue sub-accesses as necessary so that the write flag is
2610 propagated transitively. Return true if anything changed. Additionally, if
2611 RACC is a scalar access but LACC is not, change the type of the latter, if
2612 possible. */
2614 static bool
2615 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
2617 struct access *rchild;
2618 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
2619 bool ret = false;
2621 /* IF the LHS is still not marked as being written to, we only need to do so
2622 if the RHS at this level actually was. */
2623 if (!lacc->grp_write)
2625 gcc_checking_assert (!comes_initialized_p (racc->base));
2626 if (racc->grp_write)
2628 subtree_mark_written_and_enqueue (lacc);
2629 ret = true;
2633 if (is_gimple_reg_type (lacc->type)
2634 || lacc->grp_unscalarizable_region
2635 || racc->grp_unscalarizable_region)
2637 if (!lacc->grp_write)
2639 ret = true;
2640 subtree_mark_written_and_enqueue (lacc);
2642 return ret;
2645 if (is_gimple_reg_type (racc->type))
2647 if (!lacc->grp_write)
2649 ret = true;
2650 subtree_mark_written_and_enqueue (lacc);
2652 if (!lacc->first_child && !racc->first_child)
2654 tree t = lacc->base;
2656 lacc->type = racc->type;
2657 if (build_user_friendly_ref_for_offset (&t, TREE_TYPE (t),
2658 lacc->offset, racc->type))
2659 lacc->expr = t;
2660 else
2662 lacc->expr = build_ref_for_model (EXPR_LOCATION (lacc->base),
2663 lacc->base, lacc->offset,
2664 racc, NULL, false);
2665 lacc->grp_no_warning = true;
2668 return ret;
2671 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
2673 struct access *new_acc = NULL;
2674 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
2676 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
2677 &new_acc))
2679 if (new_acc)
2681 if (!new_acc->grp_write && rchild->grp_write)
2683 gcc_assert (!lacc->grp_write);
2684 subtree_mark_written_and_enqueue (new_acc);
2685 ret = true;
2688 rchild->grp_hint = 1;
2689 new_acc->grp_hint |= new_acc->grp_read;
2690 if (rchild->first_child)
2691 ret |= propagate_subaccesses_across_link (new_acc, rchild);
2693 else
2695 if (!lacc->grp_write)
2697 ret = true;
2698 subtree_mark_written_and_enqueue (lacc);
2701 continue;
2704 if (rchild->grp_unscalarizable_region)
2706 if (rchild->grp_write && !lacc->grp_write)
2708 ret = true;
2709 subtree_mark_written_and_enqueue (lacc);
2711 continue;
2714 rchild->grp_hint = 1;
2715 new_acc = create_artificial_child_access (lacc, rchild, norm_offset,
2716 lacc->grp_write
2717 || rchild->grp_write);
2718 gcc_checking_assert (new_acc);
2719 if (racc->first_child)
2720 propagate_subaccesses_across_link (new_acc, rchild);
2722 add_access_to_work_queue (lacc);
2723 ret = true;
2726 return ret;
2729 /* Propagate all subaccesses across assignment links. */
2731 static void
2732 propagate_all_subaccesses (void)
2734 while (work_queue_head)
2736 struct access *racc = pop_access_from_work_queue ();
2737 struct assign_link *link;
2739 if (racc->group_representative)
2740 racc= racc->group_representative;
2741 gcc_assert (racc->first_link);
2743 for (link = racc->first_link; link; link = link->next)
2745 struct access *lacc = link->lacc;
2747 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
2748 continue;
2749 lacc = lacc->group_representative;
2751 bool reque_parents = false;
2752 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (racc->base)))
2754 if (!lacc->grp_write)
2756 subtree_mark_written_and_enqueue (lacc);
2757 reque_parents = true;
2760 else if (propagate_subaccesses_across_link (lacc, racc))
2761 reque_parents = true;
2763 if (reque_parents)
2766 add_access_to_work_queue (lacc);
2767 lacc = lacc->parent;
2769 while (lacc);
2774 /* Go through all accesses collected throughout the (intraprocedural) analysis
2775 stage, exclude overlapping ones, identify representatives and build trees
2776 out of them, making decisions about scalarization on the way. Return true
2777 iff there are any to-be-scalarized variables after this stage. */
2779 static bool
2780 analyze_all_variable_accesses (void)
2782 int res = 0;
2783 bitmap tmp = BITMAP_ALLOC (NULL);
2784 bitmap_iterator bi;
2785 unsigned i;
2786 bool optimize_speed_p = !optimize_function_for_size_p (cfun);
2788 enum compiler_param param = optimize_speed_p
2789 ? PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED
2790 : PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE;
2792 /* If the user didn't set PARAM_SRA_MAX_SCALARIZATION_SIZE_<...>,
2793 fall back to a target default. */
2794 unsigned HOST_WIDE_INT max_scalarization_size
2795 = global_options_set.x_param_values[param]
2796 ? PARAM_VALUE (param)
2797 : get_move_ratio (optimize_speed_p) * UNITS_PER_WORD;
2799 max_scalarization_size *= BITS_PER_UNIT;
2801 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
2802 if (bitmap_bit_p (should_scalarize_away_bitmap, i)
2803 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
2805 tree var = candidate (i);
2807 if (VAR_P (var) && scalarizable_type_p (TREE_TYPE (var),
2808 constant_decl_p (var)))
2810 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var)))
2811 <= max_scalarization_size)
2813 create_total_scalarization_access (var);
2814 completely_scalarize (var, TREE_TYPE (var), 0, var);
2815 statistics_counter_event (cfun,
2816 "Totally-scalarized aggregates", 1);
2817 if (dump_file && (dump_flags & TDF_DETAILS))
2819 fprintf (dump_file, "Will attempt to totally scalarize ");
2820 print_generic_expr (dump_file, var);
2821 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2824 else if (dump_file && (dump_flags & TDF_DETAILS))
2826 fprintf (dump_file, "Too big to totally scalarize: ");
2827 print_generic_expr (dump_file, var);
2828 fprintf (dump_file, " (UID: %u)\n", DECL_UID (var));
2833 bitmap_copy (tmp, candidate_bitmap);
2834 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2836 tree var = candidate (i);
2837 struct access *access;
2839 access = sort_and_splice_var_accesses (var);
2840 if (!access || !build_access_trees (access))
2841 disqualify_candidate (var,
2842 "No or inhibitingly overlapping accesses.");
2845 propagate_all_subaccesses ();
2847 bitmap_copy (tmp, candidate_bitmap);
2848 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2850 tree var = candidate (i);
2851 struct access *access = get_first_repr_for_decl (var);
2853 if (analyze_access_trees (access))
2855 res++;
2856 if (dump_file && (dump_flags & TDF_DETAILS))
2858 fprintf (dump_file, "\nAccess trees for ");
2859 print_generic_expr (dump_file, var);
2860 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2861 dump_access_tree (dump_file, access);
2862 fprintf (dump_file, "\n");
2865 else
2866 disqualify_candidate (var, "No scalar replacements to be created.");
2869 BITMAP_FREE (tmp);
2871 if (res)
2873 statistics_counter_event (cfun, "Scalarized aggregates", res);
2874 return true;
2876 else
2877 return false;
2880 /* Generate statements copying scalar replacements of accesses within a subtree
2881 into or out of AGG. ACCESS, all its children, siblings and their children
2882 are to be processed. AGG is an aggregate type expression (can be a
2883 declaration but does not have to be, it can for example also be a mem_ref or
2884 a series of handled components). TOP_OFFSET is the offset of the processed
2885 subtree which has to be subtracted from offsets of individual accesses to
2886 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2887 replacements in the interval <start_offset, start_offset + chunk_size>,
2888 otherwise copy all. GSI is a statement iterator used to place the new
2889 statements. WRITE should be true when the statements should write from AGG
2890 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2891 statements will be added after the current statement in GSI, they will be
2892 added before the statement otherwise. */
2894 static void
2895 generate_subtree_copies (struct access *access, tree agg,
2896 HOST_WIDE_INT top_offset,
2897 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
2898 gimple_stmt_iterator *gsi, bool write,
2899 bool insert_after, location_t loc)
2901 /* Never write anything into constant pool decls. See PR70602. */
2902 if (!write && constant_decl_p (agg))
2903 return;
2906 if (chunk_size && access->offset >= start_offset + chunk_size)
2907 return;
2909 if (access->grp_to_be_replaced
2910 && (chunk_size == 0
2911 || access->offset + access->size > start_offset))
2913 tree expr, repl = get_access_replacement (access);
2914 gassign *stmt;
2916 expr = build_ref_for_model (loc, agg, access->offset - top_offset,
2917 access, gsi, insert_after);
2919 if (write)
2921 if (access->grp_partial_lhs)
2922 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
2923 !insert_after,
2924 insert_after ? GSI_NEW_STMT
2925 : GSI_SAME_STMT);
2926 stmt = gimple_build_assign (repl, expr);
2928 else
2930 TREE_NO_WARNING (repl) = 1;
2931 if (access->grp_partial_lhs)
2932 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2933 !insert_after,
2934 insert_after ? GSI_NEW_STMT
2935 : GSI_SAME_STMT);
2936 stmt = gimple_build_assign (expr, repl);
2938 gimple_set_location (stmt, loc);
2940 if (insert_after)
2941 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2942 else
2943 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2944 update_stmt (stmt);
2945 sra_stats.subtree_copies++;
2947 else if (write
2948 && access->grp_to_be_debug_replaced
2949 && (chunk_size == 0
2950 || access->offset + access->size > start_offset))
2952 gdebug *ds;
2953 tree drhs = build_debug_ref_for_model (loc, agg,
2954 access->offset - top_offset,
2955 access);
2956 ds = gimple_build_debug_bind (get_access_replacement (access),
2957 drhs, gsi_stmt (*gsi));
2958 if (insert_after)
2959 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2960 else
2961 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2964 if (access->first_child)
2965 generate_subtree_copies (access->first_child, agg, top_offset,
2966 start_offset, chunk_size, gsi,
2967 write, insert_after, loc);
2969 access = access->next_sibling;
2971 while (access);
2974 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2975 root of the subtree to be processed. GSI is the statement iterator used
2976 for inserting statements which are added after the current statement if
2977 INSERT_AFTER is true or before it otherwise. */
2979 static void
2980 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
2981 bool insert_after, location_t loc)
2984 struct access *child;
2986 if (access->grp_to_be_replaced)
2988 gassign *stmt;
2990 stmt = gimple_build_assign (get_access_replacement (access),
2991 build_zero_cst (access->type));
2992 if (insert_after)
2993 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2994 else
2995 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2996 update_stmt (stmt);
2997 gimple_set_location (stmt, loc);
2999 else if (access->grp_to_be_debug_replaced)
3001 gdebug *ds
3002 = gimple_build_debug_bind (get_access_replacement (access),
3003 build_zero_cst (access->type),
3004 gsi_stmt (*gsi));
3005 if (insert_after)
3006 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
3007 else
3008 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3011 for (child = access->first_child; child; child = child->next_sibling)
3012 init_subtree_with_zero (child, gsi, insert_after, loc);
3015 /* Clobber all scalar replacements in an access subtree. ACCESS is the
3016 root of the subtree to be processed. GSI is the statement iterator used
3017 for inserting statements which are added after the current statement if
3018 INSERT_AFTER is true or before it otherwise. */
3020 static void
3021 clobber_subtree (struct access *access, gimple_stmt_iterator *gsi,
3022 bool insert_after, location_t loc)
3025 struct access *child;
3027 if (access->grp_to_be_replaced)
3029 tree rep = get_access_replacement (access);
3030 tree clobber = build_constructor (access->type, NULL);
3031 TREE_THIS_VOLATILE (clobber) = 1;
3032 gimple *stmt = gimple_build_assign (rep, clobber);
3034 if (insert_after)
3035 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
3036 else
3037 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
3038 update_stmt (stmt);
3039 gimple_set_location (stmt, loc);
3042 for (child = access->first_child; child; child = child->next_sibling)
3043 clobber_subtree (child, gsi, insert_after, loc);
3046 /* Search for an access representative for the given expression EXPR and
3047 return it or NULL if it cannot be found. */
3049 static struct access *
3050 get_access_for_expr (tree expr)
3052 HOST_WIDE_INT offset, size, max_size;
3053 tree base;
3054 bool reverse;
3056 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
3057 a different size than the size of its argument and we need the latter
3058 one. */
3059 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
3060 expr = TREE_OPERAND (expr, 0);
3062 base = get_ref_base_and_extent (expr, &offset, &size, &max_size, &reverse);
3063 if (max_size == -1 || !DECL_P (base))
3064 return NULL;
3066 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
3067 return NULL;
3069 return get_var_base_offset_size_access (base, offset, max_size);
3072 /* Replace the expression EXPR with a scalar replacement if there is one and
3073 generate other statements to do type conversion or subtree copying if
3074 necessary. GSI is used to place newly created statements, WRITE is true if
3075 the expression is being written to (it is on a LHS of a statement or output
3076 in an assembly statement). */
3078 static bool
3079 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
3081 location_t loc;
3082 struct access *access;
3083 tree type, bfr, orig_expr;
3085 if (TREE_CODE (*expr) == BIT_FIELD_REF)
3087 bfr = *expr;
3088 expr = &TREE_OPERAND (*expr, 0);
3090 else
3091 bfr = NULL_TREE;
3093 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
3094 expr = &TREE_OPERAND (*expr, 0);
3095 access = get_access_for_expr (*expr);
3096 if (!access)
3097 return false;
3098 type = TREE_TYPE (*expr);
3099 orig_expr = *expr;
3101 loc = gimple_location (gsi_stmt (*gsi));
3102 gimple_stmt_iterator alt_gsi = gsi_none ();
3103 if (write && stmt_ends_bb_p (gsi_stmt (*gsi)))
3105 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
3106 gsi = &alt_gsi;
3109 if (access->grp_to_be_replaced)
3111 tree repl = get_access_replacement (access);
3112 /* If we replace a non-register typed access simply use the original
3113 access expression to extract the scalar component afterwards.
3114 This happens if scalarizing a function return value or parameter
3115 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
3116 gcc.c-torture/compile/20011217-1.c.
3118 We also want to use this when accessing a complex or vector which can
3119 be accessed as a different type too, potentially creating a need for
3120 type conversion (see PR42196) and when scalarized unions are involved
3121 in assembler statements (see PR42398). */
3122 if (!useless_type_conversion_p (type, access->type))
3124 tree ref;
3126 ref = build_ref_for_model (loc, orig_expr, 0, access, gsi, false);
3128 if (write)
3130 gassign *stmt;
3132 if (access->grp_partial_lhs)
3133 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
3134 false, GSI_NEW_STMT);
3135 stmt = gimple_build_assign (repl, ref);
3136 gimple_set_location (stmt, loc);
3137 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
3139 else
3141 gassign *stmt;
3143 if (access->grp_partial_lhs)
3144 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
3145 true, GSI_SAME_STMT);
3146 stmt = gimple_build_assign (ref, repl);
3147 gimple_set_location (stmt, loc);
3148 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
3151 else
3152 *expr = repl;
3153 sra_stats.exprs++;
3155 else if (write && access->grp_to_be_debug_replaced)
3157 gdebug *ds = gimple_build_debug_bind (get_access_replacement (access),
3158 NULL_TREE,
3159 gsi_stmt (*gsi));
3160 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
3163 if (access->first_child)
3165 HOST_WIDE_INT start_offset, chunk_size;
3166 if (bfr
3167 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 1))
3168 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 2)))
3170 chunk_size = tree_to_uhwi (TREE_OPERAND (bfr, 1));
3171 start_offset = access->offset
3172 + tree_to_uhwi (TREE_OPERAND (bfr, 2));
3174 else
3175 start_offset = chunk_size = 0;
3177 generate_subtree_copies (access->first_child, orig_expr, access->offset,
3178 start_offset, chunk_size, gsi, write, write,
3179 loc);
3181 return true;
3184 /* Where scalar replacements of the RHS have been written to when a replacement
3185 of a LHS of an assigments cannot be direclty loaded from a replacement of
3186 the RHS. */
3187 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
3188 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
3189 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
3191 struct subreplacement_assignment_data
3193 /* Offset of the access representing the lhs of the assignment. */
3194 HOST_WIDE_INT left_offset;
3196 /* LHS and RHS of the original assignment. */
3197 tree assignment_lhs, assignment_rhs;
3199 /* Access representing the rhs of the whole assignment. */
3200 struct access *top_racc;
3202 /* Stmt iterator used for statement insertions after the original assignment.
3203 It points to the main GSI used to traverse a BB during function body
3204 modification. */
3205 gimple_stmt_iterator *new_gsi;
3207 /* Stmt iterator used for statement insertions before the original
3208 assignment. Keeps on pointing to the original statement. */
3209 gimple_stmt_iterator old_gsi;
3211 /* Location of the assignment. */
3212 location_t loc;
3214 /* Keeps the information whether we have needed to refresh replacements of
3215 the LHS and from which side of the assignments this takes place. */
3216 enum unscalarized_data_handling refreshed;
3219 /* Store all replacements in the access tree rooted in TOP_RACC either to their
3220 base aggregate if there are unscalarized data or directly to LHS of the
3221 statement that is pointed to by GSI otherwise. */
3223 static void
3224 handle_unscalarized_data_in_subtree (struct subreplacement_assignment_data *sad)
3226 tree src;
3227 if (sad->top_racc->grp_unscalarized_data)
3229 src = sad->assignment_rhs;
3230 sad->refreshed = SRA_UDH_RIGHT;
3232 else
3234 src = sad->assignment_lhs;
3235 sad->refreshed = SRA_UDH_LEFT;
3237 generate_subtree_copies (sad->top_racc->first_child, src,
3238 sad->top_racc->offset, 0, 0,
3239 &sad->old_gsi, false, false, sad->loc);
3242 /* Try to generate statements to load all sub-replacements in an access subtree
3243 formed by children of LACC from scalar replacements in the SAD->top_racc
3244 subtree. If that is not possible, refresh the SAD->top_racc base aggregate
3245 and load the accesses from it. */
3247 static void
3248 load_assign_lhs_subreplacements (struct access *lacc,
3249 struct subreplacement_assignment_data *sad)
3251 for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling)
3253 HOST_WIDE_INT offset;
3254 offset = lacc->offset - sad->left_offset + sad->top_racc->offset;
3256 if (lacc->grp_to_be_replaced)
3258 struct access *racc;
3259 gassign *stmt;
3260 tree rhs;
3262 racc = find_access_in_subtree (sad->top_racc, offset, lacc->size);
3263 if (racc && racc->grp_to_be_replaced)
3265 rhs = get_access_replacement (racc);
3266 if (!useless_type_conversion_p (lacc->type, racc->type))
3267 rhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
3268 lacc->type, rhs);
3270 if (racc->grp_partial_lhs && lacc->grp_partial_lhs)
3271 rhs = force_gimple_operand_gsi (&sad->old_gsi, rhs, true,
3272 NULL_TREE, true, GSI_SAME_STMT);
3274 else
3276 /* No suitable access on the right hand side, need to load from
3277 the aggregate. See if we have to update it first... */
3278 if (sad->refreshed == SRA_UDH_NONE)
3279 handle_unscalarized_data_in_subtree (sad);
3281 if (sad->refreshed == SRA_UDH_LEFT)
3282 rhs = build_ref_for_model (sad->loc, sad->assignment_lhs,
3283 lacc->offset - sad->left_offset,
3284 lacc, sad->new_gsi, true);
3285 else
3286 rhs = build_ref_for_model (sad->loc, sad->assignment_rhs,
3287 lacc->offset - sad->left_offset,
3288 lacc, sad->new_gsi, true);
3289 if (lacc->grp_partial_lhs)
3290 rhs = force_gimple_operand_gsi (sad->new_gsi,
3291 rhs, true, NULL_TREE,
3292 false, GSI_NEW_STMT);
3295 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
3296 gsi_insert_after (sad->new_gsi, stmt, GSI_NEW_STMT);
3297 gimple_set_location (stmt, sad->loc);
3298 update_stmt (stmt);
3299 sra_stats.subreplacements++;
3301 else
3303 if (sad->refreshed == SRA_UDH_NONE
3304 && lacc->grp_read && !lacc->grp_covered)
3305 handle_unscalarized_data_in_subtree (sad);
3307 if (lacc && lacc->grp_to_be_debug_replaced)
3309 gdebug *ds;
3310 tree drhs;
3311 struct access *racc = find_access_in_subtree (sad->top_racc,
3312 offset,
3313 lacc->size);
3315 if (racc && racc->grp_to_be_replaced)
3317 if (racc->grp_write || constant_decl_p (racc->base))
3318 drhs = get_access_replacement (racc);
3319 else
3320 drhs = NULL;
3322 else if (sad->refreshed == SRA_UDH_LEFT)
3323 drhs = build_debug_ref_for_model (sad->loc, lacc->base,
3324 lacc->offset, lacc);
3325 else if (sad->refreshed == SRA_UDH_RIGHT)
3326 drhs = build_debug_ref_for_model (sad->loc, sad->top_racc->base,
3327 offset, lacc);
3328 else
3329 drhs = NULL_TREE;
3330 if (drhs
3331 && !useless_type_conversion_p (lacc->type, TREE_TYPE (drhs)))
3332 drhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
3333 lacc->type, drhs);
3334 ds = gimple_build_debug_bind (get_access_replacement (lacc),
3335 drhs, gsi_stmt (sad->old_gsi));
3336 gsi_insert_after (sad->new_gsi, ds, GSI_NEW_STMT);
3340 if (lacc->first_child)
3341 load_assign_lhs_subreplacements (lacc, sad);
3345 /* Result code for SRA assignment modification. */
3346 enum assignment_mod_result { SRA_AM_NONE, /* nothing done for the stmt */
3347 SRA_AM_MODIFIED, /* stmt changed but not
3348 removed */
3349 SRA_AM_REMOVED }; /* stmt eliminated */
3351 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
3352 to the assignment and GSI is the statement iterator pointing at it. Returns
3353 the same values as sra_modify_assign. */
3355 static enum assignment_mod_result
3356 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3358 tree lhs = gimple_assign_lhs (stmt);
3359 struct access *acc = get_access_for_expr (lhs);
3360 if (!acc)
3361 return SRA_AM_NONE;
3362 location_t loc = gimple_location (stmt);
3364 if (gimple_clobber_p (stmt))
3366 /* Clobber the replacement variable. */
3367 clobber_subtree (acc, gsi, !acc->grp_covered, loc);
3368 /* Remove clobbers of fully scalarized variables, they are dead. */
3369 if (acc->grp_covered)
3371 unlink_stmt_vdef (stmt);
3372 gsi_remove (gsi, true);
3373 release_defs (stmt);
3374 return SRA_AM_REMOVED;
3376 else
3377 return SRA_AM_MODIFIED;
3380 if (CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt)) > 0)
3382 /* I have never seen this code path trigger but if it can happen the
3383 following should handle it gracefully. */
3384 if (access_has_children_p (acc))
3385 generate_subtree_copies (acc->first_child, lhs, acc->offset, 0, 0, gsi,
3386 true, true, loc);
3387 return SRA_AM_MODIFIED;
3390 if (acc->grp_covered)
3392 init_subtree_with_zero (acc, gsi, false, loc);
3393 unlink_stmt_vdef (stmt);
3394 gsi_remove (gsi, true);
3395 release_defs (stmt);
3396 return SRA_AM_REMOVED;
3398 else
3400 init_subtree_with_zero (acc, gsi, true, loc);
3401 return SRA_AM_MODIFIED;
3405 /* Create and return a new suitable default definition SSA_NAME for RACC which
3406 is an access describing an uninitialized part of an aggregate that is being
3407 loaded. */
3409 static tree
3410 get_repl_default_def_ssa_name (struct access *racc)
3412 gcc_checking_assert (!racc->grp_to_be_replaced
3413 && !racc->grp_to_be_debug_replaced);
3414 if (!racc->replacement_decl)
3415 racc->replacement_decl = create_access_replacement (racc);
3416 return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
3419 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3420 bit-field field declaration somewhere in it. */
3422 static inline bool
3423 contains_vce_or_bfcref_p (const_tree ref)
3425 while (handled_component_p (ref))
3427 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
3428 || (TREE_CODE (ref) == COMPONENT_REF
3429 && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
3430 return true;
3431 ref = TREE_OPERAND (ref, 0);
3434 return false;
3437 /* Examine both sides of the assignment statement pointed to by STMT, replace
3438 them with a scalare replacement if there is one and generate copying of
3439 replacements if scalarized aggregates have been used in the assignment. GSI
3440 is used to hold generated statements for type conversions and subtree
3441 copying. */
3443 static enum assignment_mod_result
3444 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3446 struct access *lacc, *racc;
3447 tree lhs, rhs;
3448 bool modify_this_stmt = false;
3449 bool force_gimple_rhs = false;
3450 location_t loc;
3451 gimple_stmt_iterator orig_gsi = *gsi;
3453 if (!gimple_assign_single_p (stmt))
3454 return SRA_AM_NONE;
3455 lhs = gimple_assign_lhs (stmt);
3456 rhs = gimple_assign_rhs1 (stmt);
3458 if (TREE_CODE (rhs) == CONSTRUCTOR)
3459 return sra_modify_constructor_assign (stmt, gsi);
3461 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
3462 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
3463 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
3465 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (stmt),
3466 gsi, false);
3467 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (stmt),
3468 gsi, true);
3469 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3472 lacc = get_access_for_expr (lhs);
3473 racc = get_access_for_expr (rhs);
3474 if (!lacc && !racc)
3475 return SRA_AM_NONE;
3476 /* Avoid modifying initializations of constant-pool replacements. */
3477 if (racc && (racc->replacement_decl == lhs))
3478 return SRA_AM_NONE;
3480 loc = gimple_location (stmt);
3481 if (lacc && lacc->grp_to_be_replaced)
3483 lhs = get_access_replacement (lacc);
3484 gimple_assign_set_lhs (stmt, lhs);
3485 modify_this_stmt = true;
3486 if (lacc->grp_partial_lhs)
3487 force_gimple_rhs = true;
3488 sra_stats.exprs++;
3491 if (racc && racc->grp_to_be_replaced)
3493 rhs = get_access_replacement (racc);
3494 modify_this_stmt = true;
3495 if (racc->grp_partial_lhs)
3496 force_gimple_rhs = true;
3497 sra_stats.exprs++;
3499 else if (racc
3500 && !racc->grp_unscalarized_data
3501 && !racc->grp_unscalarizable_region
3502 && TREE_CODE (lhs) == SSA_NAME
3503 && !access_has_replacements_p (racc))
3505 rhs = get_repl_default_def_ssa_name (racc);
3506 modify_this_stmt = true;
3507 sra_stats.exprs++;
3510 if (modify_this_stmt)
3512 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3514 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3515 ??? This should move to fold_stmt which we simply should
3516 call after building a VIEW_CONVERT_EXPR here. */
3517 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
3518 && !contains_bitfld_component_ref_p (lhs))
3520 lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
3521 gimple_assign_set_lhs (stmt, lhs);
3523 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
3524 && !contains_vce_or_bfcref_p (rhs))
3525 rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
3527 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3529 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
3530 rhs);
3531 if (is_gimple_reg_type (TREE_TYPE (lhs))
3532 && TREE_CODE (lhs) != SSA_NAME)
3533 force_gimple_rhs = true;
3538 if (lacc && lacc->grp_to_be_debug_replaced)
3540 tree dlhs = get_access_replacement (lacc);
3541 tree drhs = unshare_expr (rhs);
3542 if (!useless_type_conversion_p (TREE_TYPE (dlhs), TREE_TYPE (drhs)))
3544 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs))
3545 && !contains_vce_or_bfcref_p (drhs))
3546 drhs = build_debug_ref_for_model (loc, drhs, 0, lacc);
3547 if (drhs
3548 && !useless_type_conversion_p (TREE_TYPE (dlhs),
3549 TREE_TYPE (drhs)))
3550 drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
3551 TREE_TYPE (dlhs), drhs);
3553 gdebug *ds = gimple_build_debug_bind (dlhs, drhs, stmt);
3554 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3557 /* From this point on, the function deals with assignments in between
3558 aggregates when at least one has scalar reductions of some of its
3559 components. There are three possible scenarios: Both the LHS and RHS have
3560 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3562 In the first case, we would like to load the LHS components from RHS
3563 components whenever possible. If that is not possible, we would like to
3564 read it directly from the RHS (after updating it by storing in it its own
3565 components). If there are some necessary unscalarized data in the LHS,
3566 those will be loaded by the original assignment too. If neither of these
3567 cases happen, the original statement can be removed. Most of this is done
3568 by load_assign_lhs_subreplacements.
3570 In the second case, we would like to store all RHS scalarized components
3571 directly into LHS and if they cover the aggregate completely, remove the
3572 statement too. In the third case, we want the LHS components to be loaded
3573 directly from the RHS (DSE will remove the original statement if it
3574 becomes redundant).
3576 This is a bit complex but manageable when types match and when unions do
3577 not cause confusion in a way that we cannot really load a component of LHS
3578 from the RHS or vice versa (the access representing this level can have
3579 subaccesses that are accessible only through a different union field at a
3580 higher level - different from the one used in the examined expression).
3581 Unions are fun.
3583 Therefore, I specially handle a fourth case, happening when there is a
3584 specific type cast or it is impossible to locate a scalarized subaccess on
3585 the other side of the expression. If that happens, I simply "refresh" the
3586 RHS by storing in it is scalarized components leave the original statement
3587 there to do the copying and then load the scalar replacements of the LHS.
3588 This is what the first branch does. */
3590 if (modify_this_stmt
3591 || gimple_has_volatile_ops (stmt)
3592 || contains_vce_or_bfcref_p (rhs)
3593 || contains_vce_or_bfcref_p (lhs)
3594 || stmt_ends_bb_p (stmt))
3596 /* No need to copy into a constant-pool, it comes pre-initialized. */
3597 if (access_has_children_p (racc) && !constant_decl_p (racc->base))
3598 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3599 gsi, false, false, loc);
3600 if (access_has_children_p (lacc))
3602 gimple_stmt_iterator alt_gsi = gsi_none ();
3603 if (stmt_ends_bb_p (stmt))
3605 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
3606 gsi = &alt_gsi;
3608 generate_subtree_copies (lacc->first_child, lhs, lacc->offset, 0, 0,
3609 gsi, true, true, loc);
3611 sra_stats.separate_lhs_rhs_handling++;
3613 /* This gimplification must be done after generate_subtree_copies,
3614 lest we insert the subtree copies in the middle of the gimplified
3615 sequence. */
3616 if (force_gimple_rhs)
3617 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
3618 true, GSI_SAME_STMT);
3619 if (gimple_assign_rhs1 (stmt) != rhs)
3621 modify_this_stmt = true;
3622 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
3623 gcc_assert (stmt == gsi_stmt (orig_gsi));
3626 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3628 else
3630 if (access_has_children_p (lacc)
3631 && access_has_children_p (racc)
3632 /* When an access represents an unscalarizable region, it usually
3633 represents accesses with variable offset and thus must not be used
3634 to generate new memory accesses. */
3635 && !lacc->grp_unscalarizable_region
3636 && !racc->grp_unscalarizable_region)
3638 struct subreplacement_assignment_data sad;
3640 sad.left_offset = lacc->offset;
3641 sad.assignment_lhs = lhs;
3642 sad.assignment_rhs = rhs;
3643 sad.top_racc = racc;
3644 sad.old_gsi = *gsi;
3645 sad.new_gsi = gsi;
3646 sad.loc = gimple_location (stmt);
3647 sad.refreshed = SRA_UDH_NONE;
3649 if (lacc->grp_read && !lacc->grp_covered)
3650 handle_unscalarized_data_in_subtree (&sad);
3652 load_assign_lhs_subreplacements (lacc, &sad);
3653 if (sad.refreshed != SRA_UDH_RIGHT)
3655 gsi_next (gsi);
3656 unlink_stmt_vdef (stmt);
3657 gsi_remove (&sad.old_gsi, true);
3658 release_defs (stmt);
3659 sra_stats.deleted++;
3660 return SRA_AM_REMOVED;
3663 else
3665 if (access_has_children_p (racc)
3666 && !racc->grp_unscalarized_data
3667 && TREE_CODE (lhs) != SSA_NAME)
3669 if (dump_file)
3671 fprintf (dump_file, "Removing load: ");
3672 print_gimple_stmt (dump_file, stmt, 0);
3674 generate_subtree_copies (racc->first_child, lhs,
3675 racc->offset, 0, 0, gsi,
3676 false, false, loc);
3677 gcc_assert (stmt == gsi_stmt (*gsi));
3678 unlink_stmt_vdef (stmt);
3679 gsi_remove (gsi, true);
3680 release_defs (stmt);
3681 sra_stats.deleted++;
3682 return SRA_AM_REMOVED;
3684 /* Restore the aggregate RHS from its components so the
3685 prevailing aggregate copy does the right thing. */
3686 if (access_has_children_p (racc))
3687 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3688 gsi, false, false, loc);
3689 /* Re-load the components of the aggregate copy destination.
3690 But use the RHS aggregate to load from to expose more
3691 optimization opportunities. */
3692 if (access_has_children_p (lacc))
3693 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
3694 0, 0, gsi, true, true, loc);
3697 return SRA_AM_NONE;
3701 /* Set any scalar replacements of values in the constant pool to the initial
3702 value of the constant. (Constant-pool decls like *.LC0 have effectively
3703 been initialized before the program starts, we must do the same for their
3704 replacements.) Thus, we output statements like 'SR.1 = *.LC0[0];' into
3705 the function's entry block. */
3707 static void
3708 initialize_constant_pool_replacements (void)
3710 gimple_seq seq = NULL;
3711 gimple_stmt_iterator gsi = gsi_start (seq);
3712 bitmap_iterator bi;
3713 unsigned i;
3715 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
3717 tree var = candidate (i);
3718 if (!constant_decl_p (var))
3719 continue;
3720 vec<access_p> *access_vec = get_base_access_vector (var);
3721 if (!access_vec)
3722 continue;
3723 for (unsigned i = 0; i < access_vec->length (); i++)
3725 struct access *access = (*access_vec)[i];
3726 if (!access->replacement_decl)
3727 continue;
3728 gassign *stmt
3729 = gimple_build_assign (get_access_replacement (access),
3730 unshare_expr (access->expr));
3731 if (dump_file && (dump_flags & TDF_DETAILS))
3733 fprintf (dump_file, "Generating constant initializer: ");
3734 print_gimple_stmt (dump_file, stmt, 0);
3735 fprintf (dump_file, "\n");
3737 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
3738 update_stmt (stmt);
3742 seq = gsi_seq (gsi);
3743 if (seq)
3744 gsi_insert_seq_on_edge_immediate (
3745 single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3748 /* Traverse the function body and all modifications as decided in
3749 analyze_all_variable_accesses. Return true iff the CFG has been
3750 changed. */
3752 static bool
3753 sra_modify_function_body (void)
3755 bool cfg_changed = false;
3756 basic_block bb;
3758 initialize_constant_pool_replacements ();
3760 FOR_EACH_BB_FN (bb, cfun)
3762 gimple_stmt_iterator gsi = gsi_start_bb (bb);
3763 while (!gsi_end_p (gsi))
3765 gimple *stmt = gsi_stmt (gsi);
3766 enum assignment_mod_result assign_result;
3767 bool modified = false, deleted = false;
3768 tree *t;
3769 unsigned i;
3771 switch (gimple_code (stmt))
3773 case GIMPLE_RETURN:
3774 t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
3775 if (*t != NULL_TREE)
3776 modified |= sra_modify_expr (t, &gsi, false);
3777 break;
3779 case GIMPLE_ASSIGN:
3780 assign_result = sra_modify_assign (stmt, &gsi);
3781 modified |= assign_result == SRA_AM_MODIFIED;
3782 deleted = assign_result == SRA_AM_REMOVED;
3783 break;
3785 case GIMPLE_CALL:
3786 /* Operands must be processed before the lhs. */
3787 for (i = 0; i < gimple_call_num_args (stmt); i++)
3789 t = gimple_call_arg_ptr (stmt, i);
3790 modified |= sra_modify_expr (t, &gsi, false);
3793 if (gimple_call_lhs (stmt))
3795 t = gimple_call_lhs_ptr (stmt);
3796 modified |= sra_modify_expr (t, &gsi, true);
3798 break;
3800 case GIMPLE_ASM:
3802 gasm *asm_stmt = as_a <gasm *> (stmt);
3803 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
3805 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
3806 modified |= sra_modify_expr (t, &gsi, false);
3808 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
3810 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
3811 modified |= sra_modify_expr (t, &gsi, true);
3814 break;
3816 default:
3817 break;
3820 if (modified)
3822 update_stmt (stmt);
3823 if (maybe_clean_eh_stmt (stmt)
3824 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
3825 cfg_changed = true;
3827 if (!deleted)
3828 gsi_next (&gsi);
3832 gsi_commit_edge_inserts ();
3833 return cfg_changed;
3836 /* Generate statements initializing scalar replacements of parts of function
3837 parameters. */
3839 static void
3840 initialize_parameter_reductions (void)
3842 gimple_stmt_iterator gsi;
3843 gimple_seq seq = NULL;
3844 tree parm;
3846 gsi = gsi_start (seq);
3847 for (parm = DECL_ARGUMENTS (current_function_decl);
3848 parm;
3849 parm = DECL_CHAIN (parm))
3851 vec<access_p> *access_vec;
3852 struct access *access;
3854 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3855 continue;
3856 access_vec = get_base_access_vector (parm);
3857 if (!access_vec)
3858 continue;
3860 for (access = (*access_vec)[0];
3861 access;
3862 access = access->next_grp)
3863 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true,
3864 EXPR_LOCATION (parm));
3867 seq = gsi_seq (gsi);
3868 if (seq)
3869 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3872 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3873 it reveals there are components of some aggregates to be scalarized, it runs
3874 the required transformations. */
3875 static unsigned int
3876 perform_intra_sra (void)
3878 int ret = 0;
3879 sra_initialize ();
3881 if (!find_var_candidates ())
3882 goto out;
3884 if (!scan_function ())
3885 goto out;
3887 if (!analyze_all_variable_accesses ())
3888 goto out;
3890 if (sra_modify_function_body ())
3891 ret = TODO_update_ssa | TODO_cleanup_cfg;
3892 else
3893 ret = TODO_update_ssa;
3894 initialize_parameter_reductions ();
3896 statistics_counter_event (cfun, "Scalar replacements created",
3897 sra_stats.replacements);
3898 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
3899 statistics_counter_event (cfun, "Subtree copy stmts",
3900 sra_stats.subtree_copies);
3901 statistics_counter_event (cfun, "Subreplacement stmts",
3902 sra_stats.subreplacements);
3903 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
3904 statistics_counter_event (cfun, "Separate LHS and RHS handling",
3905 sra_stats.separate_lhs_rhs_handling);
3907 out:
3908 sra_deinitialize ();
3909 return ret;
3912 /* Perform early intraprocedural SRA. */
3913 static unsigned int
3914 early_intra_sra (void)
3916 sra_mode = SRA_MODE_EARLY_INTRA;
3917 return perform_intra_sra ();
3920 /* Perform "late" intraprocedural SRA. */
3921 static unsigned int
3922 late_intra_sra (void)
3924 sra_mode = SRA_MODE_INTRA;
3925 return perform_intra_sra ();
3929 static bool
3930 gate_intra_sra (void)
3932 return flag_tree_sra != 0 && dbg_cnt (tree_sra);
3936 namespace {
3938 const pass_data pass_data_sra_early =
3940 GIMPLE_PASS, /* type */
3941 "esra", /* name */
3942 OPTGROUP_NONE, /* optinfo_flags */
3943 TV_TREE_SRA, /* tv_id */
3944 ( PROP_cfg | PROP_ssa ), /* properties_required */
3945 0, /* properties_provided */
3946 0, /* properties_destroyed */
3947 0, /* todo_flags_start */
3948 TODO_update_ssa, /* todo_flags_finish */
3951 class pass_sra_early : public gimple_opt_pass
3953 public:
3954 pass_sra_early (gcc::context *ctxt)
3955 : gimple_opt_pass (pass_data_sra_early, ctxt)
3958 /* opt_pass methods: */
3959 virtual bool gate (function *) { return gate_intra_sra (); }
3960 virtual unsigned int execute (function *) { return early_intra_sra (); }
3962 }; // class pass_sra_early
3964 } // anon namespace
3966 gimple_opt_pass *
3967 make_pass_sra_early (gcc::context *ctxt)
3969 return new pass_sra_early (ctxt);
3972 namespace {
3974 const pass_data pass_data_sra =
3976 GIMPLE_PASS, /* type */
3977 "sra", /* name */
3978 OPTGROUP_NONE, /* optinfo_flags */
3979 TV_TREE_SRA, /* tv_id */
3980 ( PROP_cfg | PROP_ssa ), /* properties_required */
3981 0, /* properties_provided */
3982 0, /* properties_destroyed */
3983 TODO_update_address_taken, /* todo_flags_start */
3984 TODO_update_ssa, /* todo_flags_finish */
3987 class pass_sra : public gimple_opt_pass
3989 public:
3990 pass_sra (gcc::context *ctxt)
3991 : gimple_opt_pass (pass_data_sra, ctxt)
3994 /* opt_pass methods: */
3995 virtual bool gate (function *) { return gate_intra_sra (); }
3996 virtual unsigned int execute (function *) { return late_intra_sra (); }
3998 }; // class pass_sra
4000 } // anon namespace
4002 gimple_opt_pass *
4003 make_pass_sra (gcc::context *ctxt)
4005 return new pass_sra (ctxt);
4009 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
4010 parameter. */
4012 static bool
4013 is_unused_scalar_param (tree parm)
4015 tree name;
4016 return (is_gimple_reg (parm)
4017 && (!(name = ssa_default_def (cfun, parm))
4018 || has_zero_uses (name)));
4021 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
4022 examine whether there are any direct or otherwise infeasible ones. If so,
4023 return true, otherwise return false. PARM must be a gimple register with a
4024 non-NULL default definition. */
4026 static bool
4027 ptr_parm_has_direct_uses (tree parm)
4029 imm_use_iterator ui;
4030 gimple *stmt;
4031 tree name = ssa_default_def (cfun, parm);
4032 bool ret = false;
4034 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
4036 int uses_ok = 0;
4037 use_operand_p use_p;
4039 if (is_gimple_debug (stmt))
4040 continue;
4042 /* Valid uses include dereferences on the lhs and the rhs. */
4043 if (gimple_has_lhs (stmt))
4045 tree lhs = gimple_get_lhs (stmt);
4046 while (handled_component_p (lhs))
4047 lhs = TREE_OPERAND (lhs, 0);
4048 if (TREE_CODE (lhs) == MEM_REF
4049 && TREE_OPERAND (lhs, 0) == name
4050 && integer_zerop (TREE_OPERAND (lhs, 1))
4051 && types_compatible_p (TREE_TYPE (lhs),
4052 TREE_TYPE (TREE_TYPE (name)))
4053 && !TREE_THIS_VOLATILE (lhs))
4054 uses_ok++;
4056 if (gimple_assign_single_p (stmt))
4058 tree rhs = gimple_assign_rhs1 (stmt);
4059 while (handled_component_p (rhs))
4060 rhs = TREE_OPERAND (rhs, 0);
4061 if (TREE_CODE (rhs) == MEM_REF
4062 && TREE_OPERAND (rhs, 0) == name
4063 && integer_zerop (TREE_OPERAND (rhs, 1))
4064 && types_compatible_p (TREE_TYPE (rhs),
4065 TREE_TYPE (TREE_TYPE (name)))
4066 && !TREE_THIS_VOLATILE (rhs))
4067 uses_ok++;
4069 else if (is_gimple_call (stmt))
4071 unsigned i;
4072 for (i = 0; i < gimple_call_num_args (stmt); ++i)
4074 tree arg = gimple_call_arg (stmt, i);
4075 while (handled_component_p (arg))
4076 arg = TREE_OPERAND (arg, 0);
4077 if (TREE_CODE (arg) == MEM_REF
4078 && TREE_OPERAND (arg, 0) == name
4079 && integer_zerop (TREE_OPERAND (arg, 1))
4080 && types_compatible_p (TREE_TYPE (arg),
4081 TREE_TYPE (TREE_TYPE (name)))
4082 && !TREE_THIS_VOLATILE (arg))
4083 uses_ok++;
4087 /* If the number of valid uses does not match the number of
4088 uses in this stmt there is an unhandled use. */
4089 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
4090 --uses_ok;
4092 if (uses_ok != 0)
4093 ret = true;
4095 if (ret)
4096 BREAK_FROM_IMM_USE_STMT (ui);
4099 return ret;
4102 /* Identify candidates for reduction for IPA-SRA based on their type and mark
4103 them in candidate_bitmap. Note that these do not necessarily include
4104 parameter which are unused and thus can be removed. Return true iff any
4105 such candidate has been found. */
4107 static bool
4108 find_param_candidates (void)
4110 tree parm;
4111 int count = 0;
4112 bool ret = false;
4113 const char *msg;
4115 for (parm = DECL_ARGUMENTS (current_function_decl);
4116 parm;
4117 parm = DECL_CHAIN (parm))
4119 tree type = TREE_TYPE (parm);
4120 tree_node **slot;
4122 count++;
4124 if (TREE_THIS_VOLATILE (parm)
4125 || TREE_ADDRESSABLE (parm)
4126 || (!is_gimple_reg_type (type) && is_va_list_type (type)))
4127 continue;
4129 if (is_unused_scalar_param (parm))
4131 ret = true;
4132 continue;
4135 if (POINTER_TYPE_P (type))
4137 type = TREE_TYPE (type);
4139 if (TREE_CODE (type) == FUNCTION_TYPE
4140 || TYPE_VOLATILE (type)
4141 || (TREE_CODE (type) == ARRAY_TYPE
4142 && TYPE_NONALIASED_COMPONENT (type))
4143 || !is_gimple_reg (parm)
4144 || is_va_list_type (type)
4145 || ptr_parm_has_direct_uses (parm))
4146 continue;
4148 else if (!AGGREGATE_TYPE_P (type))
4149 continue;
4151 if (!COMPLETE_TYPE_P (type)
4152 || !tree_fits_uhwi_p (TYPE_SIZE (type))
4153 || tree_to_uhwi (TYPE_SIZE (type)) == 0
4154 || (AGGREGATE_TYPE_P (type)
4155 && type_internals_preclude_sra_p (type, &msg)))
4156 continue;
4158 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
4159 slot = candidates->find_slot_with_hash (parm, DECL_UID (parm), INSERT);
4160 *slot = parm;
4162 ret = true;
4163 if (dump_file && (dump_flags & TDF_DETAILS))
4165 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
4166 print_generic_expr (dump_file, parm);
4167 fprintf (dump_file, "\n");
4171 func_param_count = count;
4172 return ret;
4175 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
4176 maybe_modified. */
4178 static bool
4179 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
4180 void *data)
4182 struct access *repr = (struct access *) data;
4184 repr->grp_maybe_modified = 1;
4185 return true;
4188 /* Analyze what representatives (in linked lists accessible from
4189 REPRESENTATIVES) can be modified by side effects of statements in the
4190 current function. */
4192 static void
4193 analyze_modified_params (vec<access_p> representatives)
4195 int i;
4197 for (i = 0; i < func_param_count; i++)
4199 struct access *repr;
4201 for (repr = representatives[i];
4202 repr;
4203 repr = repr->next_grp)
4205 struct access *access;
4206 bitmap visited;
4207 ao_ref ar;
4209 if (no_accesses_p (repr))
4210 continue;
4211 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
4212 || repr->grp_maybe_modified)
4213 continue;
4215 ao_ref_init (&ar, repr->expr);
4216 visited = BITMAP_ALLOC (NULL);
4217 for (access = repr; access; access = access->next_sibling)
4219 /* All accesses are read ones, otherwise grp_maybe_modified would
4220 be trivially set. */
4221 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
4222 mark_maybe_modified, repr, &visited);
4223 if (repr->grp_maybe_modified)
4224 break;
4226 BITMAP_FREE (visited);
4231 /* Propagate distances in bb_dereferences in the opposite direction than the
4232 control flow edges, in each step storing the maximum of the current value
4233 and the minimum of all successors. These steps are repeated until the table
4234 stabilizes. Note that BBs which might terminate the functions (according to
4235 final_bbs bitmap) never updated in this way. */
4237 static void
4238 propagate_dereference_distances (void)
4240 basic_block bb;
4242 auto_vec<basic_block> queue (last_basic_block_for_fn (cfun));
4243 queue.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun));
4244 FOR_EACH_BB_FN (bb, cfun)
4246 queue.quick_push (bb);
4247 bb->aux = bb;
4250 while (!queue.is_empty ())
4252 edge_iterator ei;
4253 edge e;
4254 bool change = false;
4255 int i;
4257 bb = queue.pop ();
4258 bb->aux = NULL;
4260 if (bitmap_bit_p (final_bbs, bb->index))
4261 continue;
4263 for (i = 0; i < func_param_count; i++)
4265 int idx = bb->index * func_param_count + i;
4266 bool first = true;
4267 HOST_WIDE_INT inh = 0;
4269 FOR_EACH_EDGE (e, ei, bb->succs)
4271 int succ_idx = e->dest->index * func_param_count + i;
4273 if (e->src == EXIT_BLOCK_PTR_FOR_FN (cfun))
4274 continue;
4276 if (first)
4278 first = false;
4279 inh = bb_dereferences [succ_idx];
4281 else if (bb_dereferences [succ_idx] < inh)
4282 inh = bb_dereferences [succ_idx];
4285 if (!first && bb_dereferences[idx] < inh)
4287 bb_dereferences[idx] = inh;
4288 change = true;
4292 if (change && !bitmap_bit_p (final_bbs, bb->index))
4293 FOR_EACH_EDGE (e, ei, bb->preds)
4295 if (e->src->aux)
4296 continue;
4298 e->src->aux = e->src;
4299 queue.quick_push (e->src);
4304 /* Dump a dereferences TABLE with heading STR to file F. */
4306 static void
4307 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
4309 basic_block bb;
4311 fprintf (dump_file, "%s", str);
4312 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
4313 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
4315 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
4316 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
4318 int i;
4319 for (i = 0; i < func_param_count; i++)
4321 int idx = bb->index * func_param_count + i;
4322 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
4325 fprintf (f, "\n");
4327 fprintf (dump_file, "\n");
4330 /* Determine what (parts of) parameters passed by reference that are not
4331 assigned to are not certainly dereferenced in this function and thus the
4332 dereferencing cannot be safely moved to the caller without potentially
4333 introducing a segfault. Mark such REPRESENTATIVES as
4334 grp_not_necessarilly_dereferenced.
4336 The dereferenced maximum "distance," i.e. the offset + size of the accessed
4337 part is calculated rather than simple booleans are calculated for each
4338 pointer parameter to handle cases when only a fraction of the whole
4339 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
4340 an example).
4342 The maximum dereference distances for each pointer parameter and BB are
4343 already stored in bb_dereference. This routine simply propagates these
4344 values upwards by propagate_dereference_distances and then compares the
4345 distances of individual parameters in the ENTRY BB to the equivalent
4346 distances of each representative of a (fraction of a) parameter. */
4348 static void
4349 analyze_caller_dereference_legality (vec<access_p> representatives)
4351 int i;
4353 if (dump_file && (dump_flags & TDF_DETAILS))
4354 dump_dereferences_table (dump_file,
4355 "Dereference table before propagation:\n",
4356 bb_dereferences);
4358 propagate_dereference_distances ();
4360 if (dump_file && (dump_flags & TDF_DETAILS))
4361 dump_dereferences_table (dump_file,
4362 "Dereference table after propagation:\n",
4363 bb_dereferences);
4365 for (i = 0; i < func_param_count; i++)
4367 struct access *repr = representatives[i];
4368 int idx = ENTRY_BLOCK_PTR_FOR_FN (cfun)->index * func_param_count + i;
4370 if (!repr || no_accesses_p (repr))
4371 continue;
4375 if ((repr->offset + repr->size) > bb_dereferences[idx])
4376 repr->grp_not_necessarilly_dereferenced = 1;
4377 repr = repr->next_grp;
4379 while (repr);
4383 /* Return the representative access for the parameter declaration PARM if it is
4384 a scalar passed by reference which is not written to and the pointer value
4385 is not used directly. Thus, if it is legal to dereference it in the caller
4386 and we can rule out modifications through aliases, such parameter should be
4387 turned into one passed by value. Return NULL otherwise. */
4389 static struct access *
4390 unmodified_by_ref_scalar_representative (tree parm)
4392 int i, access_count;
4393 struct access *repr;
4394 vec<access_p> *access_vec;
4396 access_vec = get_base_access_vector (parm);
4397 gcc_assert (access_vec);
4398 repr = (*access_vec)[0];
4399 if (repr->write)
4400 return NULL;
4401 repr->group_representative = repr;
4403 access_count = access_vec->length ();
4404 for (i = 1; i < access_count; i++)
4406 struct access *access = (*access_vec)[i];
4407 if (access->write)
4408 return NULL;
4409 access->group_representative = repr;
4410 access->next_sibling = repr->next_sibling;
4411 repr->next_sibling = access;
4414 repr->grp_read = 1;
4415 repr->grp_scalar_ptr = 1;
4416 return repr;
4419 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
4420 associated with. REQ_ALIGN is the minimum required alignment. */
4422 static bool
4423 access_precludes_ipa_sra_p (struct access *access, unsigned int req_align)
4425 unsigned int exp_align;
4426 /* Avoid issues such as the second simple testcase in PR 42025. The problem
4427 is incompatible assign in a call statement (and possibly even in asm
4428 statements). This can be relaxed by using a new temporary but only for
4429 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
4430 intraprocedural SRA we deal with this by keeping the old aggregate around,
4431 something we cannot do in IPA-SRA.) */
4432 if (access->write
4433 && (is_gimple_call (access->stmt)
4434 || gimple_code (access->stmt) == GIMPLE_ASM))
4435 return true;
4437 exp_align = get_object_alignment (access->expr);
4438 if (exp_align < req_align)
4439 return true;
4441 return false;
4445 /* Sort collected accesses for parameter PARM, identify representatives for
4446 each accessed region and link them together. Return NULL if there are
4447 different but overlapping accesses, return the special ptr value meaning
4448 there are no accesses for this parameter if that is the case and return the
4449 first representative otherwise. Set *RO_GRP if there is a group of accesses
4450 with only read (i.e. no write) accesses. */
4452 static struct access *
4453 splice_param_accesses (tree parm, bool *ro_grp)
4455 int i, j, access_count, group_count;
4456 int agg_size, total_size = 0;
4457 struct access *access, *res, **prev_acc_ptr = &res;
4458 vec<access_p> *access_vec;
4460 access_vec = get_base_access_vector (parm);
4461 if (!access_vec)
4462 return &no_accesses_representant;
4463 access_count = access_vec->length ();
4465 access_vec->qsort (compare_access_positions);
4467 i = 0;
4468 total_size = 0;
4469 group_count = 0;
4470 while (i < access_count)
4472 bool modification;
4473 tree a1_alias_type;
4474 access = (*access_vec)[i];
4475 modification = access->write;
4476 if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type)))
4477 return NULL;
4478 a1_alias_type = reference_alias_ptr_type (access->expr);
4480 /* Access is about to become group representative unless we find some
4481 nasty overlap which would preclude us from breaking this parameter
4482 apart. */
4484 j = i + 1;
4485 while (j < access_count)
4487 struct access *ac2 = (*access_vec)[j];
4488 if (ac2->offset != access->offset)
4490 /* All or nothing law for parameters. */
4491 if (access->offset + access->size > ac2->offset)
4492 return NULL;
4493 else
4494 break;
4496 else if (ac2->size != access->size)
4497 return NULL;
4499 if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type))
4500 || (ac2->type != access->type
4501 && (TREE_ADDRESSABLE (ac2->type)
4502 || TREE_ADDRESSABLE (access->type)))
4503 || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
4504 return NULL;
4506 modification |= ac2->write;
4507 ac2->group_representative = access;
4508 ac2->next_sibling = access->next_sibling;
4509 access->next_sibling = ac2;
4510 j++;
4513 group_count++;
4514 access->grp_maybe_modified = modification;
4515 if (!modification)
4516 *ro_grp = true;
4517 *prev_acc_ptr = access;
4518 prev_acc_ptr = &access->next_grp;
4519 total_size += access->size;
4520 i = j;
4523 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4524 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4525 else
4526 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4527 if (total_size >= agg_size)
4528 return NULL;
4530 gcc_assert (group_count > 0);
4531 return res;
4534 /* Decide whether parameters with representative accesses given by REPR should
4535 be reduced into components. */
4537 static int
4538 decide_one_param_reduction (struct access *repr)
4540 int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
4541 bool by_ref;
4542 tree parm;
4544 parm = repr->base;
4545 cur_parm_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4546 gcc_assert (cur_parm_size > 0);
4548 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4550 by_ref = true;
4551 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4553 else
4555 by_ref = false;
4556 agg_size = cur_parm_size;
4559 if (dump_file)
4561 struct access *acc;
4562 fprintf (dump_file, "Evaluating PARAM group sizes for ");
4563 print_generic_expr (dump_file, parm);
4564 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
4565 for (acc = repr; acc; acc = acc->next_grp)
4566 dump_access (dump_file, acc, true);
4569 total_size = 0;
4570 new_param_count = 0;
4572 for (; repr; repr = repr->next_grp)
4574 gcc_assert (parm == repr->base);
4576 /* Taking the address of a non-addressable field is verboten. */
4577 if (by_ref && repr->non_addressable)
4578 return 0;
4580 /* Do not decompose a non-BLKmode param in a way that would
4581 create BLKmode params. Especially for by-reference passing
4582 (thus, pointer-type param) this is hardly worthwhile. */
4583 if (DECL_MODE (parm) != BLKmode
4584 && TYPE_MODE (repr->type) == BLKmode)
4585 return 0;
4587 if (!by_ref || (!repr->grp_maybe_modified
4588 && !repr->grp_not_necessarilly_dereferenced))
4589 total_size += repr->size;
4590 else
4591 total_size += cur_parm_size;
4593 new_param_count++;
4596 gcc_assert (new_param_count > 0);
4598 if (optimize_function_for_size_p (cfun))
4599 parm_size_limit = cur_parm_size;
4600 else
4601 parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
4602 * cur_parm_size);
4604 if (total_size < agg_size
4605 && total_size <= parm_size_limit)
4607 if (dump_file)
4608 fprintf (dump_file, " ....will be split into %i components\n",
4609 new_param_count);
4610 return new_param_count;
4612 else
4613 return 0;
4616 /* The order of the following enums is important, we need to do extra work for
4617 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4618 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
4619 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
4621 /* Identify representatives of all accesses to all candidate parameters for
4622 IPA-SRA. Return result based on what representatives have been found. */
4624 static enum ipa_splicing_result
4625 splice_all_param_accesses (vec<access_p> &representatives)
4627 enum ipa_splicing_result result = NO_GOOD_ACCESS;
4628 tree parm;
4629 struct access *repr;
4631 representatives.create (func_param_count);
4633 for (parm = DECL_ARGUMENTS (current_function_decl);
4634 parm;
4635 parm = DECL_CHAIN (parm))
4637 if (is_unused_scalar_param (parm))
4639 representatives.quick_push (&no_accesses_representant);
4640 if (result == NO_GOOD_ACCESS)
4641 result = UNUSED_PARAMS;
4643 else if (POINTER_TYPE_P (TREE_TYPE (parm))
4644 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
4645 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4647 repr = unmodified_by_ref_scalar_representative (parm);
4648 representatives.quick_push (repr);
4649 if (repr)
4650 result = UNMODIF_BY_REF_ACCESSES;
4652 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4654 bool ro_grp = false;
4655 repr = splice_param_accesses (parm, &ro_grp);
4656 representatives.quick_push (repr);
4658 if (repr && !no_accesses_p (repr))
4660 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4662 if (ro_grp)
4663 result = UNMODIF_BY_REF_ACCESSES;
4664 else if (result < MODIF_BY_REF_ACCESSES)
4665 result = MODIF_BY_REF_ACCESSES;
4667 else if (result < BY_VAL_ACCESSES)
4668 result = BY_VAL_ACCESSES;
4670 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
4671 result = UNUSED_PARAMS;
4673 else
4674 representatives.quick_push (NULL);
4677 if (result == NO_GOOD_ACCESS)
4679 representatives.release ();
4680 return NO_GOOD_ACCESS;
4683 return result;
4686 /* Return the index of BASE in PARMS. Abort if it is not found. */
4688 static inline int
4689 get_param_index (tree base, vec<tree> parms)
4691 int i, len;
4693 len = parms.length ();
4694 for (i = 0; i < len; i++)
4695 if (parms[i] == base)
4696 return i;
4697 gcc_unreachable ();
4700 /* Convert the decisions made at the representative level into compact
4701 parameter adjustments. REPRESENTATIVES are pointers to first
4702 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4703 final number of adjustments. */
4705 static ipa_parm_adjustment_vec
4706 turn_representatives_into_adjustments (vec<access_p> representatives,
4707 int adjustments_count)
4709 vec<tree> parms;
4710 ipa_parm_adjustment_vec adjustments;
4711 tree parm;
4712 int i;
4714 gcc_assert (adjustments_count > 0);
4715 parms = ipa_get_vector_of_formal_parms (current_function_decl);
4716 adjustments.create (adjustments_count);
4717 parm = DECL_ARGUMENTS (current_function_decl);
4718 for (i = 0; i < func_param_count; i++, parm = DECL_CHAIN (parm))
4720 struct access *repr = representatives[i];
4722 if (!repr || no_accesses_p (repr))
4724 struct ipa_parm_adjustment adj;
4726 memset (&adj, 0, sizeof (adj));
4727 adj.base_index = get_param_index (parm, parms);
4728 adj.base = parm;
4729 if (!repr)
4730 adj.op = IPA_PARM_OP_COPY;
4731 else
4732 adj.op = IPA_PARM_OP_REMOVE;
4733 adj.arg_prefix = "ISRA";
4734 adjustments.quick_push (adj);
4736 else
4738 struct ipa_parm_adjustment adj;
4739 int index = get_param_index (parm, parms);
4741 for (; repr; repr = repr->next_grp)
4743 memset (&adj, 0, sizeof (adj));
4744 gcc_assert (repr->base == parm);
4745 adj.base_index = index;
4746 adj.base = repr->base;
4747 adj.type = repr->type;
4748 adj.alias_ptr_type = reference_alias_ptr_type (repr->expr);
4749 adj.offset = repr->offset;
4750 adj.reverse = repr->reverse;
4751 adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
4752 && (repr->grp_maybe_modified
4753 || repr->grp_not_necessarilly_dereferenced));
4754 adj.arg_prefix = "ISRA";
4755 adjustments.quick_push (adj);
4759 parms.release ();
4760 return adjustments;
4763 /* Analyze the collected accesses and produce a plan what to do with the
4764 parameters in the form of adjustments, NULL meaning nothing. */
4766 static ipa_parm_adjustment_vec
4767 analyze_all_param_acesses (void)
4769 enum ipa_splicing_result repr_state;
4770 bool proceed = false;
4771 int i, adjustments_count = 0;
4772 vec<access_p> representatives;
4773 ipa_parm_adjustment_vec adjustments;
4775 repr_state = splice_all_param_accesses (representatives);
4776 if (repr_state == NO_GOOD_ACCESS)
4777 return ipa_parm_adjustment_vec ();
4779 /* If there are any parameters passed by reference which are not modified
4780 directly, we need to check whether they can be modified indirectly. */
4781 if (repr_state == UNMODIF_BY_REF_ACCESSES)
4783 analyze_caller_dereference_legality (representatives);
4784 analyze_modified_params (representatives);
4787 for (i = 0; i < func_param_count; i++)
4789 struct access *repr = representatives[i];
4791 if (repr && !no_accesses_p (repr))
4793 if (repr->grp_scalar_ptr)
4795 adjustments_count++;
4796 if (repr->grp_not_necessarilly_dereferenced
4797 || repr->grp_maybe_modified)
4798 representatives[i] = NULL;
4799 else
4801 proceed = true;
4802 sra_stats.scalar_by_ref_to_by_val++;
4805 else
4807 int new_components = decide_one_param_reduction (repr);
4809 if (new_components == 0)
4811 representatives[i] = NULL;
4812 adjustments_count++;
4814 else
4816 adjustments_count += new_components;
4817 sra_stats.aggregate_params_reduced++;
4818 sra_stats.param_reductions_created += new_components;
4819 proceed = true;
4823 else
4825 if (no_accesses_p (repr))
4827 proceed = true;
4828 sra_stats.deleted_unused_parameters++;
4830 adjustments_count++;
4834 if (!proceed && dump_file)
4835 fprintf (dump_file, "NOT proceeding to change params.\n");
4837 if (proceed)
4838 adjustments = turn_representatives_into_adjustments (representatives,
4839 adjustments_count);
4840 else
4841 adjustments = ipa_parm_adjustment_vec ();
4843 representatives.release ();
4844 return adjustments;
4847 /* If a parameter replacement identified by ADJ does not yet exist in the form
4848 of declaration, create it and record it, otherwise return the previously
4849 created one. */
4851 static tree
4852 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
4854 tree repl;
4855 if (!adj->new_ssa_base)
4857 char *pretty_name = make_fancy_name (adj->base);
4859 repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR");
4860 DECL_NAME (repl) = get_identifier (pretty_name);
4861 DECL_NAMELESS (repl) = 1;
4862 obstack_free (&name_obstack, pretty_name);
4864 adj->new_ssa_base = repl;
4866 else
4867 repl = adj->new_ssa_base;
4868 return repl;
4871 /* Find the first adjustment for a particular parameter BASE in a vector of
4872 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4873 adjustment. */
4875 static struct ipa_parm_adjustment *
4876 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
4878 int i, len;
4880 len = adjustments.length ();
4881 for (i = 0; i < len; i++)
4883 struct ipa_parm_adjustment *adj;
4885 adj = &adjustments[i];
4886 if (adj->op != IPA_PARM_OP_COPY && adj->base == base)
4887 return adj;
4890 return NULL;
4893 /* If OLD_NAME, which is being defined by statement STMT, is an SSA_NAME of a
4894 parameter which is to be removed because its value is not used, create a new
4895 SSA_NAME relating to a replacement VAR_DECL, replace all uses of the
4896 original with it and return it. If there is no need to re-map, return NULL.
4897 ADJUSTMENTS is a pointer to a vector of IPA-SRA adjustments. */
4899 static tree
4900 replace_removed_params_ssa_names (tree old_name, gimple *stmt,
4901 ipa_parm_adjustment_vec adjustments)
4903 struct ipa_parm_adjustment *adj;
4904 tree decl, repl, new_name;
4906 if (TREE_CODE (old_name) != SSA_NAME)
4907 return NULL;
4909 decl = SSA_NAME_VAR (old_name);
4910 if (decl == NULL_TREE
4911 || TREE_CODE (decl) != PARM_DECL)
4912 return NULL;
4914 adj = get_adjustment_for_base (adjustments, decl);
4915 if (!adj)
4916 return NULL;
4918 repl = get_replaced_param_substitute (adj);
4919 new_name = make_ssa_name (repl, stmt);
4920 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name)
4921 = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name);
4923 if (dump_file)
4925 fprintf (dump_file, "replacing an SSA name of a removed param ");
4926 print_generic_expr (dump_file, old_name);
4927 fprintf (dump_file, " with ");
4928 print_generic_expr (dump_file, new_name);
4929 fprintf (dump_file, "\n");
4932 replace_uses_by (old_name, new_name);
4933 return new_name;
4936 /* If the statement STMT contains any expressions that need to replaced with a
4937 different one as noted by ADJUSTMENTS, do so. Handle any potential type
4938 incompatibilities (GSI is used to accommodate conversion statements and must
4939 point to the statement). Return true iff the statement was modified. */
4941 static bool
4942 sra_ipa_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi,
4943 ipa_parm_adjustment_vec adjustments)
4945 tree *lhs_p, *rhs_p;
4946 bool any;
4948 if (!gimple_assign_single_p (stmt))
4949 return false;
4951 rhs_p = gimple_assign_rhs1_ptr (stmt);
4952 lhs_p = gimple_assign_lhs_ptr (stmt);
4954 any = ipa_modify_expr (rhs_p, false, adjustments);
4955 any |= ipa_modify_expr (lhs_p, false, adjustments);
4956 if (any)
4958 tree new_rhs = NULL_TREE;
4960 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
4962 if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
4964 /* V_C_Es of constructors can cause trouble (PR 42714). */
4965 if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
4966 *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
4967 else
4968 *rhs_p = build_constructor (TREE_TYPE (*lhs_p),
4969 NULL);
4971 else
4972 new_rhs = fold_build1_loc (gimple_location (stmt),
4973 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
4974 *rhs_p);
4976 else if (REFERENCE_CLASS_P (*rhs_p)
4977 && is_gimple_reg_type (TREE_TYPE (*lhs_p))
4978 && !is_gimple_reg (*lhs_p))
4979 /* This can happen when an assignment in between two single field
4980 structures is turned into an assignment in between two pointers to
4981 scalars (PR 42237). */
4982 new_rhs = *rhs_p;
4984 if (new_rhs)
4986 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
4987 true, GSI_SAME_STMT);
4989 gimple_assign_set_rhs_from_tree (gsi, tmp);
4992 return true;
4995 return false;
4998 /* Traverse the function body and all modifications as described in
4999 ADJUSTMENTS. Return true iff the CFG has been changed. */
5001 bool
5002 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
5004 bool cfg_changed = false;
5005 basic_block bb;
5007 FOR_EACH_BB_FN (bb, cfun)
5009 gimple_stmt_iterator gsi;
5011 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5013 gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
5014 tree new_lhs, old_lhs = gimple_phi_result (phi);
5015 new_lhs = replace_removed_params_ssa_names (old_lhs, phi, adjustments);
5016 if (new_lhs)
5018 gimple_phi_set_result (phi, new_lhs);
5019 release_ssa_name (old_lhs);
5023 gsi = gsi_start_bb (bb);
5024 while (!gsi_end_p (gsi))
5026 gimple *stmt = gsi_stmt (gsi);
5027 bool modified = false;
5028 tree *t;
5029 unsigned i;
5031 switch (gimple_code (stmt))
5033 case GIMPLE_RETURN:
5034 t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
5035 if (*t != NULL_TREE)
5036 modified |= ipa_modify_expr (t, true, adjustments);
5037 break;
5039 case GIMPLE_ASSIGN:
5040 modified |= sra_ipa_modify_assign (stmt, &gsi, adjustments);
5041 break;
5043 case GIMPLE_CALL:
5044 /* Operands must be processed before the lhs. */
5045 for (i = 0; i < gimple_call_num_args (stmt); i++)
5047 t = gimple_call_arg_ptr (stmt, i);
5048 modified |= ipa_modify_expr (t, true, adjustments);
5051 if (gimple_call_lhs (stmt))
5053 t = gimple_call_lhs_ptr (stmt);
5054 modified |= ipa_modify_expr (t, false, adjustments);
5056 break;
5058 case GIMPLE_ASM:
5060 gasm *asm_stmt = as_a <gasm *> (stmt);
5061 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
5063 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
5064 modified |= ipa_modify_expr (t, true, adjustments);
5066 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
5068 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
5069 modified |= ipa_modify_expr (t, false, adjustments);
5072 break;
5074 default:
5075 break;
5078 def_operand_p defp;
5079 ssa_op_iter iter;
5080 FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF)
5082 tree old_def = DEF_FROM_PTR (defp);
5083 if (tree new_def = replace_removed_params_ssa_names (old_def, stmt,
5084 adjustments))
5086 SET_DEF (defp, new_def);
5087 release_ssa_name (old_def);
5088 modified = true;
5092 if (modified)
5094 update_stmt (stmt);
5095 if (maybe_clean_eh_stmt (stmt)
5096 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
5097 cfg_changed = true;
5099 gsi_next (&gsi);
5103 return cfg_changed;
5106 /* Call gimple_debug_bind_reset_value on all debug statements describing
5107 gimple register parameters that are being removed or replaced. */
5109 static void
5110 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
5112 int i, len;
5113 gimple_stmt_iterator *gsip = NULL, gsi;
5115 if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
5117 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
5118 gsip = &gsi;
5120 len = adjustments.length ();
5121 for (i = 0; i < len; i++)
5123 struct ipa_parm_adjustment *adj;
5124 imm_use_iterator ui;
5125 gimple *stmt;
5126 gdebug *def_temp;
5127 tree name, vexpr, copy = NULL_TREE;
5128 use_operand_p use_p;
5130 adj = &adjustments[i];
5131 if (adj->op == IPA_PARM_OP_COPY || !is_gimple_reg (adj->base))
5132 continue;
5133 name = ssa_default_def (cfun, adj->base);
5134 vexpr = NULL;
5135 if (name)
5136 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
5138 if (gimple_clobber_p (stmt))
5140 gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
5141 unlink_stmt_vdef (stmt);
5142 gsi_remove (&cgsi, true);
5143 release_defs (stmt);
5144 continue;
5146 /* All other users must have been removed by
5147 ipa_sra_modify_function_body. */
5148 gcc_assert (is_gimple_debug (stmt));
5149 if (vexpr == NULL && gsip != NULL)
5151 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
5152 vexpr = make_node (DEBUG_EXPR_DECL);
5153 def_temp = gimple_build_debug_source_bind (vexpr, adj->base,
5154 NULL);
5155 DECL_ARTIFICIAL (vexpr) = 1;
5156 TREE_TYPE (vexpr) = TREE_TYPE (name);
5157 SET_DECL_MODE (vexpr, DECL_MODE (adj->base));
5158 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
5160 if (vexpr)
5162 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
5163 SET_USE (use_p, vexpr);
5165 else
5166 gimple_debug_bind_reset_value (stmt);
5167 update_stmt (stmt);
5169 /* Create a VAR_DECL for debug info purposes. */
5170 if (!DECL_IGNORED_P (adj->base))
5172 copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
5173 VAR_DECL, DECL_NAME (adj->base),
5174 TREE_TYPE (adj->base));
5175 if (DECL_PT_UID_SET_P (adj->base))
5176 SET_DECL_PT_UID (copy, DECL_PT_UID (adj->base));
5177 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (adj->base);
5178 TREE_READONLY (copy) = TREE_READONLY (adj->base);
5179 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (adj->base);
5180 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (adj->base);
5181 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (adj->base);
5182 DECL_IGNORED_P (copy) = DECL_IGNORED_P (adj->base);
5183 DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (adj->base);
5184 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
5185 SET_DECL_RTL (copy, 0);
5186 TREE_USED (copy) = 1;
5187 DECL_CONTEXT (copy) = current_function_decl;
5188 add_local_decl (cfun, copy);
5189 DECL_CHAIN (copy) =
5190 BLOCK_VARS (DECL_INITIAL (current_function_decl));
5191 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
5193 if (gsip != NULL && copy && target_for_debug_bind (adj->base))
5195 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
5196 if (vexpr)
5197 def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
5198 else
5199 def_temp = gimple_build_debug_source_bind (copy, adj->base,
5200 NULL);
5201 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
5206 /* Return false if all callers have at least as many actual arguments as there
5207 are formal parameters in the current function and that their types
5208 match. */
5210 static bool
5211 some_callers_have_mismatched_arguments_p (struct cgraph_node *node,
5212 void *data ATTRIBUTE_UNUSED)
5214 struct cgraph_edge *cs;
5215 for (cs = node->callers; cs; cs = cs->next_caller)
5216 if (!cs->call_stmt || !callsite_arguments_match_p (cs->call_stmt))
5217 return true;
5219 return false;
5222 /* Return false if all callers have vuse attached to a call statement. */
5224 static bool
5225 some_callers_have_no_vuse_p (struct cgraph_node *node,
5226 void *data ATTRIBUTE_UNUSED)
5228 struct cgraph_edge *cs;
5229 for (cs = node->callers; cs; cs = cs->next_caller)
5230 if (!cs->call_stmt || !gimple_vuse (cs->call_stmt))
5231 return true;
5233 return false;
5236 /* Convert all callers of NODE. */
5238 static bool
5239 convert_callers_for_node (struct cgraph_node *node,
5240 void *data)
5242 ipa_parm_adjustment_vec *adjustments = (ipa_parm_adjustment_vec *) data;
5243 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
5244 struct cgraph_edge *cs;
5246 for (cs = node->callers; cs; cs = cs->next_caller)
5248 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
5250 if (dump_file)
5251 fprintf (dump_file, "Adjusting call %s -> %s\n",
5252 cs->caller->dump_name (), cs->callee->dump_name ());
5254 ipa_modify_call_arguments (cs, cs->call_stmt, *adjustments);
5256 pop_cfun ();
5259 for (cs = node->callers; cs; cs = cs->next_caller)
5260 if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
5261 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
5262 compute_fn_summary (cs->caller, true);
5263 BITMAP_FREE (recomputed_callers);
5265 return true;
5268 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
5270 static void
5271 convert_callers (struct cgraph_node *node, tree old_decl,
5272 ipa_parm_adjustment_vec adjustments)
5274 basic_block this_block;
5276 node->call_for_symbol_and_aliases (convert_callers_for_node,
5277 &adjustments, false);
5279 if (!encountered_recursive_call)
5280 return;
5282 FOR_EACH_BB_FN (this_block, cfun)
5284 gimple_stmt_iterator gsi;
5286 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
5288 gcall *stmt;
5289 tree call_fndecl;
5290 stmt = dyn_cast <gcall *> (gsi_stmt (gsi));
5291 if (!stmt)
5292 continue;
5293 call_fndecl = gimple_call_fndecl (stmt);
5294 if (call_fndecl == old_decl)
5296 if (dump_file)
5297 fprintf (dump_file, "Adjusting recursive call");
5298 gimple_call_set_fndecl (stmt, node->decl);
5299 ipa_modify_call_arguments (NULL, stmt, adjustments);
5304 return;
5307 /* Perform all the modification required in IPA-SRA for NODE to have parameters
5308 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
5310 static bool
5311 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
5313 struct cgraph_node *new_node;
5314 bool cfg_changed;
5316 cgraph_edge::rebuild_edges ();
5317 free_dominance_info (CDI_DOMINATORS);
5318 pop_cfun ();
5320 /* This must be done after rebuilding cgraph edges for node above.
5321 Otherwise any recursive calls to node that are recorded in
5322 redirect_callers will be corrupted. */
5323 vec<cgraph_edge *> redirect_callers = node->collect_callers ();
5324 new_node = node->create_version_clone_with_body (redirect_callers, NULL,
5325 NULL, false, NULL, NULL,
5326 "isra");
5327 redirect_callers.release ();
5329 push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
5330 ipa_modify_formal_parameters (current_function_decl, adjustments);
5331 cfg_changed = ipa_sra_modify_function_body (adjustments);
5332 sra_ipa_reset_debug_stmts (adjustments);
5333 convert_callers (new_node, node->decl, adjustments);
5334 new_node->make_local ();
5335 return cfg_changed;
5338 /* Means of communication between ipa_sra_check_caller and
5339 ipa_sra_preliminary_function_checks. */
5341 struct ipa_sra_check_caller_data
5343 bool has_callers;
5344 bool bad_arg_alignment;
5345 bool has_thunk;
5348 /* If NODE has a caller, mark that fact in DATA which is pointer to
5349 ipa_sra_check_caller_data. Also check all aggregate arguments in all known
5350 calls if they are unit aligned and if not, set the appropriate flag in DATA
5351 too. */
5353 static bool
5354 ipa_sra_check_caller (struct cgraph_node *node, void *data)
5356 if (!node->callers)
5357 return false;
5359 struct ipa_sra_check_caller_data *iscc;
5360 iscc = (struct ipa_sra_check_caller_data *) data;
5361 iscc->has_callers = true;
5363 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
5365 if (cs->caller->thunk.thunk_p)
5367 iscc->has_thunk = true;
5368 return true;
5370 gimple *call_stmt = cs->call_stmt;
5371 unsigned count = gimple_call_num_args (call_stmt);
5372 for (unsigned i = 0; i < count; i++)
5374 tree arg = gimple_call_arg (call_stmt, i);
5375 if (is_gimple_reg (arg))
5376 continue;
5378 tree offset;
5379 HOST_WIDE_INT bitsize, bitpos;
5380 machine_mode mode;
5381 int unsignedp, reversep, volatilep = 0;
5382 get_inner_reference (arg, &bitsize, &bitpos, &offset, &mode,
5383 &unsignedp, &reversep, &volatilep);
5384 if (bitpos % BITS_PER_UNIT)
5386 iscc->bad_arg_alignment = true;
5387 return true;
5392 return false;
5395 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
5396 attributes, return true otherwise. NODE is the cgraph node of the current
5397 function. */
5399 static bool
5400 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
5402 if (!node->can_be_local_p ())
5404 if (dump_file)
5405 fprintf (dump_file, "Function not local to this compilation unit.\n");
5406 return false;
5409 if (!node->local.can_change_signature)
5411 if (dump_file)
5412 fprintf (dump_file, "Function can not change signature.\n");
5413 return false;
5416 if (!tree_versionable_function_p (node->decl))
5418 if (dump_file)
5419 fprintf (dump_file, "Function is not versionable.\n");
5420 return false;
5423 if (!opt_for_fn (node->decl, optimize)
5424 || !opt_for_fn (node->decl, flag_ipa_sra))
5426 if (dump_file)
5427 fprintf (dump_file, "Function not optimized.\n");
5428 return false;
5431 if (DECL_VIRTUAL_P (current_function_decl))
5433 if (dump_file)
5434 fprintf (dump_file, "Function is a virtual method.\n");
5435 return false;
5438 if ((DECL_ONE_ONLY (node->decl) || DECL_EXTERNAL (node->decl))
5439 && ipa_fn_summaries->get (node)->size >= MAX_INLINE_INSNS_AUTO)
5441 if (dump_file)
5442 fprintf (dump_file, "Function too big to be made truly local.\n");
5443 return false;
5446 if (cfun->stdarg)
5448 if (dump_file)
5449 fprintf (dump_file, "Function uses stdarg. \n");
5450 return false;
5453 if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
5454 return false;
5456 if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
5458 if (dump_file)
5459 fprintf (dump_file, "Always inline function will be inlined "
5460 "anyway. \n");
5461 return false;
5464 struct ipa_sra_check_caller_data iscc;
5465 memset (&iscc, 0, sizeof(iscc));
5466 node->call_for_symbol_and_aliases (ipa_sra_check_caller, &iscc, true);
5467 if (!iscc.has_callers)
5469 if (dump_file)
5470 fprintf (dump_file,
5471 "Function has no callers in this compilation unit.\n");
5472 return false;
5475 if (iscc.bad_arg_alignment)
5477 if (dump_file)
5478 fprintf (dump_file,
5479 "A function call has an argument with non-unit alignment.\n");
5480 return false;
5483 if (iscc.has_thunk)
5485 if (dump_file)
5486 fprintf (dump_file,
5487 "A has thunk.\n");
5488 return false;
5491 return true;
5494 /* Perform early interprocedural SRA. */
5496 static unsigned int
5497 ipa_early_sra (void)
5499 struct cgraph_node *node = cgraph_node::get (current_function_decl);
5500 ipa_parm_adjustment_vec adjustments;
5501 int ret = 0;
5503 if (!ipa_sra_preliminary_function_checks (node))
5504 return 0;
5506 sra_initialize ();
5507 sra_mode = SRA_MODE_EARLY_IPA;
5509 if (!find_param_candidates ())
5511 if (dump_file)
5512 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
5513 goto simple_out;
5516 if (node->call_for_symbol_and_aliases
5517 (some_callers_have_mismatched_arguments_p, NULL, true))
5519 if (dump_file)
5520 fprintf (dump_file, "There are callers with insufficient number of "
5521 "arguments or arguments with type mismatches.\n");
5522 goto simple_out;
5525 if (node->call_for_symbol_and_aliases
5526 (some_callers_have_no_vuse_p, NULL, true))
5528 if (dump_file)
5529 fprintf (dump_file, "There are callers with no VUSE attached "
5530 "to a call stmt.\n");
5531 goto simple_out;
5534 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
5535 func_param_count
5536 * last_basic_block_for_fn (cfun));
5537 final_bbs = BITMAP_ALLOC (NULL);
5539 scan_function ();
5540 if (encountered_apply_args)
5542 if (dump_file)
5543 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
5544 goto out;
5547 if (encountered_unchangable_recursive_call)
5549 if (dump_file)
5550 fprintf (dump_file, "Function calls itself with insufficient "
5551 "number of arguments.\n");
5552 goto out;
5555 adjustments = analyze_all_param_acesses ();
5556 if (!adjustments.exists ())
5557 goto out;
5558 if (dump_file)
5559 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
5561 if (modify_function (node, adjustments))
5562 ret = TODO_update_ssa | TODO_cleanup_cfg;
5563 else
5564 ret = TODO_update_ssa;
5565 adjustments.release ();
5567 statistics_counter_event (cfun, "Unused parameters deleted",
5568 sra_stats.deleted_unused_parameters);
5569 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
5570 sra_stats.scalar_by_ref_to_by_val);
5571 statistics_counter_event (cfun, "Aggregate parameters broken up",
5572 sra_stats.aggregate_params_reduced);
5573 statistics_counter_event (cfun, "Aggregate parameter components created",
5574 sra_stats.param_reductions_created);
5576 out:
5577 BITMAP_FREE (final_bbs);
5578 free (bb_dereferences);
5579 simple_out:
5580 sra_deinitialize ();
5581 return ret;
5584 namespace {
5586 const pass_data pass_data_early_ipa_sra =
5588 GIMPLE_PASS, /* type */
5589 "eipa_sra", /* name */
5590 OPTGROUP_NONE, /* optinfo_flags */
5591 TV_IPA_SRA, /* tv_id */
5592 0, /* properties_required */
5593 0, /* properties_provided */
5594 0, /* properties_destroyed */
5595 0, /* todo_flags_start */
5596 TODO_dump_symtab, /* todo_flags_finish */
5599 class pass_early_ipa_sra : public gimple_opt_pass
5601 public:
5602 pass_early_ipa_sra (gcc::context *ctxt)
5603 : gimple_opt_pass (pass_data_early_ipa_sra, ctxt)
5606 /* opt_pass methods: */
5607 virtual bool gate (function *) { return flag_ipa_sra && dbg_cnt (eipa_sra); }
5608 virtual unsigned int execute (function *) { return ipa_early_sra (); }
5610 }; // class pass_early_ipa_sra
5612 } // anon namespace
5614 gimple_opt_pass *
5615 make_pass_early_ipa_sra (gcc::context *ctxt)
5617 return new pass_early_ipa_sra (ctxt);