[gcc/]
[official-gcc.git] / gcc / tree-sra.c
blobf9d39acff202088578a6ee43c27f2fcd5ba62abb
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-2014 Free Software Foundation, Inc.
5 Contributed by Martin Jambor <mjambor@suse.cz>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* This file implements Scalar Reduction of Aggregates (SRA). SRA is run
24 twice, once in the early stages of compilation (early SRA) and once in the
25 late stages (late SRA). The aim of both is to turn references to scalar
26 parts of aggregates into uses of independent scalar variables.
28 The two passes are nearly identical, the only difference is that early SRA
29 does not scalarize unions which are used as the result in a GIMPLE_RETURN
30 statement because together with inlining this can lead to weird type
31 conversions.
33 Both passes operate in four stages:
35 1. The declarations that have properties which make them candidates for
36 scalarization are identified in function find_var_candidates(). The
37 candidates are stored in candidate_bitmap.
39 2. The function body is scanned. In the process, declarations which are
40 used in a manner that prevent their scalarization are removed from the
41 candidate bitmap. More importantly, for every access into an aggregate,
42 an access structure (struct access) is created by create_access() and
43 stored in a vector associated with the aggregate. Among other
44 information, the aggregate declaration, the offset and size of the access
45 and its type are stored in the structure.
47 On a related note, assign_link structures are created for every assign
48 statement between candidate aggregates and attached to the related
49 accesses.
51 3. The vectors of accesses are analyzed. They are first sorted according to
52 their offset and size and then scanned for partially overlapping accesses
53 (i.e. those which overlap but one is not entirely within another). Such
54 an access disqualifies the whole aggregate from being scalarized.
56 If there is no such inhibiting overlap, a representative access structure
57 is chosen for every unique combination of offset and size. Afterwards,
58 the pass builds a set of trees from these structures, in which children
59 of an access are within their parent (in terms of offset and size).
61 Then accesses are propagated whenever possible (i.e. in cases when it
62 does not create a partially overlapping access) across assign_links from
63 the right hand side to the left hand side.
65 Then the set of trees for each declaration is traversed again and those
66 accesses which should be replaced by a scalar are identified.
68 4. The function is traversed again, and for every reference into an
69 aggregate that has some component which is about to be scalarized,
70 statements are amended and new statements are created as necessary.
71 Finally, if a parameter got scalarized, the scalar replacements are
72 initialized with values from respective parameter aggregates. */
74 #include "config.h"
75 #include "system.h"
76 #include "coretypes.h"
77 #include "hash-table.h"
78 #include "alloc-pool.h"
79 #include "tm.h"
80 #include "tree.h"
81 #include "pointer-set.h"
82 #include "basic-block.h"
83 #include "tree-ssa-alias.h"
84 #include "internal-fn.h"
85 #include "tree-eh.h"
86 #include "gimple-expr.h"
87 #include "is-a.h"
88 #include "gimple.h"
89 #include "stor-layout.h"
90 #include "gimplify.h"
91 #include "gimple-iterator.h"
92 #include "gimplify-me.h"
93 #include "gimple-walk.h"
94 #include "bitmap.h"
95 #include "gimple-ssa.h"
96 #include "tree-cfg.h"
97 #include "tree-phinodes.h"
98 #include "ssa-iterators.h"
99 #include "stringpool.h"
100 #include "tree-ssanames.h"
101 #include "expr.h"
102 #include "tree-dfa.h"
103 #include "tree-ssa.h"
104 #include "tree-pass.h"
105 #include "ipa-prop.h"
106 #include "statistics.h"
107 #include "params.h"
108 #include "target.h"
109 #include "flags.h"
110 #include "dbgcnt.h"
111 #include "tree-inline.h"
112 #include "gimple-pretty-print.h"
113 #include "ipa-inline.h"
114 #include "ipa-utils.h"
115 #include "builtins.h"
117 /* Enumeration of all aggregate reductions we can do. */
118 enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
119 SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
120 SRA_MODE_INTRA }; /* late intraprocedural SRA */
122 /* Global variable describing which aggregate reduction we are performing at
123 the moment. */
124 static enum sra_mode sra_mode;
126 struct assign_link;
128 /* ACCESS represents each access to an aggregate variable (as a whole or a
129 part). It can also represent a group of accesses that refer to exactly the
130 same fragment of an aggregate (i.e. those that have exactly the same offset
131 and size). Such representatives for a single aggregate, once determined,
132 are linked in a linked list and have the group fields set.
134 Moreover, when doing intraprocedural SRA, a tree is built from those
135 representatives (by the means of first_child and next_sibling pointers), in
136 which all items in a subtree are "within" the root, i.e. their offset is
137 greater or equal to offset of the root and offset+size is smaller or equal
138 to offset+size of the root. Children of an access are sorted by offset.
140 Note that accesses to parts of vector and complex number types always
141 represented by an access to the whole complex number or a vector. It is a
142 duty of the modifying functions to replace them appropriately. */
144 struct access
146 /* Values returned by `get_ref_base_and_extent' for each component reference
147 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
148 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
149 HOST_WIDE_INT offset;
150 HOST_WIDE_INT size;
151 tree base;
153 /* Expression. It is context dependent so do not use it to create new
154 expressions to access the original aggregate. See PR 42154 for a
155 testcase. */
156 tree expr;
157 /* Type. */
158 tree type;
160 /* The statement this access belongs to. */
161 gimple stmt;
163 /* Next group representative for this aggregate. */
164 struct access *next_grp;
166 /* Pointer to the group representative. Pointer to itself if the struct is
167 the representative. */
168 struct access *group_representative;
170 /* If this access has any children (in terms of the definition above), this
171 points to the first one. */
172 struct access *first_child;
174 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
175 described above. In IPA-SRA this is a pointer to the next access
176 belonging to the same group (having the same representative). */
177 struct access *next_sibling;
179 /* Pointers to the first and last element in the linked list of assign
180 links. */
181 struct assign_link *first_link, *last_link;
183 /* Pointer to the next access in the work queue. */
184 struct access *next_queued;
186 /* Replacement variable for this access "region." Never to be accessed
187 directly, always only by the means of get_access_replacement() and only
188 when grp_to_be_replaced flag is set. */
189 tree replacement_decl;
191 /* Is this particular access write access? */
192 unsigned write : 1;
194 /* Is this access an access to a non-addressable field? */
195 unsigned non_addressable : 1;
197 /* Is this access currently in the work queue? */
198 unsigned grp_queued : 1;
200 /* Does this group contain a write access? This flag is propagated down the
201 access tree. */
202 unsigned grp_write : 1;
204 /* Does this group contain a read access? This flag is propagated down the
205 access tree. */
206 unsigned grp_read : 1;
208 /* Does this group contain a read access that comes from an assignment
209 statement? This flag is propagated down the access tree. */
210 unsigned grp_assignment_read : 1;
212 /* Does this group contain a write access that comes from an assignment
213 statement? This flag is propagated down the access tree. */
214 unsigned grp_assignment_write : 1;
216 /* Does this group contain a read access through a scalar type? This flag is
217 not propagated in the access tree in any direction. */
218 unsigned grp_scalar_read : 1;
220 /* Does this group contain a write access through a scalar type? This flag
221 is not propagated in the access tree in any direction. */
222 unsigned grp_scalar_write : 1;
224 /* Is this access an artificial one created to scalarize some record
225 entirely? */
226 unsigned grp_total_scalarization : 1;
228 /* Other passes of the analysis use this bit to make function
229 analyze_access_subtree create scalar replacements for this group if
230 possible. */
231 unsigned grp_hint : 1;
233 /* Is the subtree rooted in this access fully covered by scalar
234 replacements? */
235 unsigned grp_covered : 1;
237 /* If set to true, this access and all below it in an access tree must not be
238 scalarized. */
239 unsigned grp_unscalarizable_region : 1;
241 /* Whether data have been written to parts of the aggregate covered by this
242 access which is not to be scalarized. This flag is propagated up in the
243 access tree. */
244 unsigned grp_unscalarized_data : 1;
246 /* Does this access and/or group contain a write access through a
247 BIT_FIELD_REF? */
248 unsigned grp_partial_lhs : 1;
250 /* Set when a scalar replacement should be created for this variable. */
251 unsigned grp_to_be_replaced : 1;
253 /* Set when we want a replacement for the sole purpose of having it in
254 generated debug statements. */
255 unsigned grp_to_be_debug_replaced : 1;
257 /* Should TREE_NO_WARNING of a replacement be set? */
258 unsigned grp_no_warning : 1;
260 /* Is it possible that the group refers to data which might be (directly or
261 otherwise) modified? */
262 unsigned grp_maybe_modified : 1;
264 /* Set when this is a representative of a pointer to scalar (i.e. by
265 reference) parameter which we consider for turning into a plain scalar
266 (i.e. a by value parameter). */
267 unsigned grp_scalar_ptr : 1;
269 /* Set when we discover that this pointer is not safe to dereference in the
270 caller. */
271 unsigned grp_not_necessarilly_dereferenced : 1;
274 typedef struct access *access_p;
277 /* Alloc pool for allocating access structures. */
278 static alloc_pool access_pool;
280 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
281 are used to propagate subaccesses from rhs to lhs as long as they don't
282 conflict with what is already there. */
283 struct assign_link
285 struct access *lacc, *racc;
286 struct assign_link *next;
289 /* Alloc pool for allocating assign link structures. */
290 static alloc_pool link_pool;
292 /* Base (tree) -> Vector (vec<access_p> *) map. */
293 static struct pointer_map_t *base_access_vec;
295 /* Candidate hash table helpers. */
297 struct uid_decl_hasher : typed_noop_remove <tree_node>
299 typedef tree_node value_type;
300 typedef tree_node compare_type;
301 static inline hashval_t hash (const value_type *);
302 static inline bool equal (const value_type *, const compare_type *);
305 /* Hash a tree in a uid_decl_map. */
307 inline hashval_t
308 uid_decl_hasher::hash (const value_type *item)
310 return item->decl_minimal.uid;
313 /* Return true if the DECL_UID in both trees are equal. */
315 inline bool
316 uid_decl_hasher::equal (const value_type *a, const compare_type *b)
318 return (a->decl_minimal.uid == b->decl_minimal.uid);
321 /* Set of candidates. */
322 static bitmap candidate_bitmap;
323 static hash_table<uid_decl_hasher> *candidates;
325 /* For a candidate UID return the candidates decl. */
327 static inline tree
328 candidate (unsigned uid)
330 tree_node t;
331 t.decl_minimal.uid = uid;
332 return candidates->find_with_hash (&t, static_cast <hashval_t> (uid));
335 /* Bitmap of candidates which we should try to entirely scalarize away and
336 those which cannot be (because they are and need be used as a whole). */
337 static bitmap should_scalarize_away_bitmap, cannot_scalarize_away_bitmap;
339 /* Obstack for creation of fancy names. */
340 static struct obstack name_obstack;
342 /* Head of a linked list of accesses that need to have its subaccesses
343 propagated to their assignment counterparts. */
344 static struct access *work_queue_head;
346 /* Number of parameters of the analyzed function when doing early ipa SRA. */
347 static int func_param_count;
349 /* scan_function sets the following to true if it encounters a call to
350 __builtin_apply_args. */
351 static bool encountered_apply_args;
353 /* Set by scan_function when it finds a recursive call. */
354 static bool encountered_recursive_call;
356 /* Set by scan_function when it finds a recursive call with less actual
357 arguments than formal parameters.. */
358 static bool encountered_unchangable_recursive_call;
360 /* This is a table in which for each basic block and parameter there is a
361 distance (offset + size) in that parameter which is dereferenced and
362 accessed in that BB. */
363 static HOST_WIDE_INT *bb_dereferences;
364 /* Bitmap of BBs that can cause the function to "stop" progressing by
365 returning, throwing externally, looping infinitely or calling a function
366 which might abort etc.. */
367 static bitmap final_bbs;
369 /* Representative of no accesses at all. */
370 static struct access no_accesses_representant;
372 /* Predicate to test the special value. */
374 static inline bool
375 no_accesses_p (struct access *access)
377 return access == &no_accesses_representant;
380 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
381 representative fields are dumped, otherwise those which only describe the
382 individual access are. */
384 static struct
386 /* Number of processed aggregates is readily available in
387 analyze_all_variable_accesses and so is not stored here. */
389 /* Number of created scalar replacements. */
390 int replacements;
392 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
393 expression. */
394 int exprs;
396 /* Number of statements created by generate_subtree_copies. */
397 int subtree_copies;
399 /* Number of statements created by load_assign_lhs_subreplacements. */
400 int subreplacements;
402 /* Number of times sra_modify_assign has deleted a statement. */
403 int deleted;
405 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
406 RHS reparately due to type conversions or nonexistent matching
407 references. */
408 int separate_lhs_rhs_handling;
410 /* Number of parameters that were removed because they were unused. */
411 int deleted_unused_parameters;
413 /* Number of scalars passed as parameters by reference that have been
414 converted to be passed by value. */
415 int scalar_by_ref_to_by_val;
417 /* Number of aggregate parameters that were replaced by one or more of their
418 components. */
419 int aggregate_params_reduced;
421 /* Numbber of components created when splitting aggregate parameters. */
422 int param_reductions_created;
423 } sra_stats;
425 static void
426 dump_access (FILE *f, struct access *access, bool grp)
428 fprintf (f, "access { ");
429 fprintf (f, "base = (%d)'", DECL_UID (access->base));
430 print_generic_expr (f, access->base, 0);
431 fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
432 fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
433 fprintf (f, ", expr = ");
434 print_generic_expr (f, access->expr, 0);
435 fprintf (f, ", type = ");
436 print_generic_expr (f, access->type, 0);
437 if (grp)
438 fprintf (f, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
439 "grp_assignment_write = %d, grp_scalar_read = %d, "
440 "grp_scalar_write = %d, grp_total_scalarization = %d, "
441 "grp_hint = %d, grp_covered = %d, "
442 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
443 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
444 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
445 "grp_not_necessarilly_dereferenced = %d\n",
446 access->grp_read, access->grp_write, access->grp_assignment_read,
447 access->grp_assignment_write, access->grp_scalar_read,
448 access->grp_scalar_write, access->grp_total_scalarization,
449 access->grp_hint, access->grp_covered,
450 access->grp_unscalarizable_region, access->grp_unscalarized_data,
451 access->grp_partial_lhs, access->grp_to_be_replaced,
452 access->grp_to_be_debug_replaced, access->grp_maybe_modified,
453 access->grp_not_necessarilly_dereferenced);
454 else
455 fprintf (f, ", write = %d, grp_total_scalarization = %d, "
456 "grp_partial_lhs = %d\n",
457 access->write, access->grp_total_scalarization,
458 access->grp_partial_lhs);
461 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
463 static void
464 dump_access_tree_1 (FILE *f, struct access *access, int level)
468 int i;
470 for (i = 0; i < level; i++)
471 fputs ("* ", dump_file);
473 dump_access (f, access, true);
475 if (access->first_child)
476 dump_access_tree_1 (f, access->first_child, level + 1);
478 access = access->next_sibling;
480 while (access);
483 /* Dump all access trees for a variable, given the pointer to the first root in
484 ACCESS. */
486 static void
487 dump_access_tree (FILE *f, struct access *access)
489 for (; access; access = access->next_grp)
490 dump_access_tree_1 (f, access, 0);
493 /* Return true iff ACC is non-NULL and has subaccesses. */
495 static inline bool
496 access_has_children_p (struct access *acc)
498 return acc && acc->first_child;
501 /* Return true iff ACC is (partly) covered by at least one replacement. */
503 static bool
504 access_has_replacements_p (struct access *acc)
506 struct access *child;
507 if (acc->grp_to_be_replaced)
508 return true;
509 for (child = acc->first_child; child; child = child->next_sibling)
510 if (access_has_replacements_p (child))
511 return true;
512 return false;
515 /* Return a vector of pointers to accesses for the variable given in BASE or
516 NULL if there is none. */
518 static vec<access_p> *
519 get_base_access_vector (tree base)
521 void **slot;
523 slot = pointer_map_contains (base_access_vec, base);
524 if (!slot)
525 return NULL;
526 else
527 return *(vec<access_p> **) slot;
530 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
531 in ACCESS. Return NULL if it cannot be found. */
533 static struct access *
534 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
535 HOST_WIDE_INT size)
537 while (access && (access->offset != offset || access->size != size))
539 struct access *child = access->first_child;
541 while (child && (child->offset + child->size <= offset))
542 child = child->next_sibling;
543 access = child;
546 return access;
549 /* Return the first group representative for DECL or NULL if none exists. */
551 static struct access *
552 get_first_repr_for_decl (tree base)
554 vec<access_p> *access_vec;
556 access_vec = get_base_access_vector (base);
557 if (!access_vec)
558 return NULL;
560 return (*access_vec)[0];
563 /* Find an access representative for the variable BASE and given OFFSET and
564 SIZE. Requires that access trees have already been built. Return NULL if
565 it cannot be found. */
567 static struct access *
568 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
569 HOST_WIDE_INT size)
571 struct access *access;
573 access = get_first_repr_for_decl (base);
574 while (access && (access->offset + access->size <= offset))
575 access = access->next_grp;
576 if (!access)
577 return NULL;
579 return find_access_in_subtree (access, offset, size);
582 /* Add LINK to the linked list of assign links of RACC. */
583 static void
584 add_link_to_rhs (struct access *racc, struct assign_link *link)
586 gcc_assert (link->racc == racc);
588 if (!racc->first_link)
590 gcc_assert (!racc->last_link);
591 racc->first_link = link;
593 else
594 racc->last_link->next = link;
596 racc->last_link = link;
597 link->next = NULL;
600 /* Move all link structures in their linked list in OLD_RACC to the linked list
601 in NEW_RACC. */
602 static void
603 relink_to_new_repr (struct access *new_racc, struct access *old_racc)
605 if (!old_racc->first_link)
607 gcc_assert (!old_racc->last_link);
608 return;
611 if (new_racc->first_link)
613 gcc_assert (!new_racc->last_link->next);
614 gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
616 new_racc->last_link->next = old_racc->first_link;
617 new_racc->last_link = old_racc->last_link;
619 else
621 gcc_assert (!new_racc->last_link);
623 new_racc->first_link = old_racc->first_link;
624 new_racc->last_link = old_racc->last_link;
626 old_racc->first_link = old_racc->last_link = NULL;
629 /* Add ACCESS to the work queue (which is actually a stack). */
631 static void
632 add_access_to_work_queue (struct access *access)
634 if (!access->grp_queued)
636 gcc_assert (!access->next_queued);
637 access->next_queued = work_queue_head;
638 access->grp_queued = 1;
639 work_queue_head = access;
643 /* Pop an access from the work queue, and return it, assuming there is one. */
645 static struct access *
646 pop_access_from_work_queue (void)
648 struct access *access = work_queue_head;
650 work_queue_head = access->next_queued;
651 access->next_queued = NULL;
652 access->grp_queued = 0;
653 return access;
657 /* Allocate necessary structures. */
659 static void
660 sra_initialize (void)
662 candidate_bitmap = BITMAP_ALLOC (NULL);
663 candidates = new hash_table<uid_decl_hasher>
664 (vec_safe_length (cfun->local_decls) / 2);
665 should_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
666 cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
667 gcc_obstack_init (&name_obstack);
668 access_pool = create_alloc_pool ("SRA accesses", sizeof (struct access), 16);
669 link_pool = create_alloc_pool ("SRA links", sizeof (struct assign_link), 16);
670 base_access_vec = pointer_map_create ();
671 memset (&sra_stats, 0, sizeof (sra_stats));
672 encountered_apply_args = false;
673 encountered_recursive_call = false;
674 encountered_unchangable_recursive_call = false;
677 /* Hook fed to pointer_map_traverse, deallocate stored vectors. */
679 static bool
680 delete_base_accesses (const void *key ATTRIBUTE_UNUSED, void **value,
681 void *data ATTRIBUTE_UNUSED)
683 vec<access_p> *access_vec = (vec<access_p> *) *value;
684 vec_free (access_vec);
685 return true;
688 /* Deallocate all general structures. */
690 static void
691 sra_deinitialize (void)
693 BITMAP_FREE (candidate_bitmap);
694 delete candidates;
695 candidates = NULL;
696 BITMAP_FREE (should_scalarize_away_bitmap);
697 BITMAP_FREE (cannot_scalarize_away_bitmap);
698 free_alloc_pool (access_pool);
699 free_alloc_pool (link_pool);
700 obstack_free (&name_obstack, NULL);
702 pointer_map_traverse (base_access_vec, delete_base_accesses, NULL);
703 pointer_map_destroy (base_access_vec);
706 /* Remove DECL from candidates for SRA and write REASON to the dump file if
707 there is one. */
708 static void
709 disqualify_candidate (tree decl, const char *reason)
711 if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl)))
712 candidates->remove_elt_with_hash (decl, DECL_UID (decl));
714 if (dump_file && (dump_flags & TDF_DETAILS))
716 fprintf (dump_file, "! Disqualifying ");
717 print_generic_expr (dump_file, decl, 0);
718 fprintf (dump_file, " - %s\n", reason);
722 /* Return true iff the type contains a field or an element which does not allow
723 scalarization. */
725 static bool
726 type_internals_preclude_sra_p (tree type, const char **msg)
728 tree fld;
729 tree et;
731 switch (TREE_CODE (type))
733 case RECORD_TYPE:
734 case UNION_TYPE:
735 case QUAL_UNION_TYPE:
736 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
737 if (TREE_CODE (fld) == FIELD_DECL)
739 tree ft = TREE_TYPE (fld);
741 if (TREE_THIS_VOLATILE (fld))
743 *msg = "volatile structure field";
744 return true;
746 if (!DECL_FIELD_OFFSET (fld))
748 *msg = "no structure field offset";
749 return true;
751 if (!DECL_SIZE (fld))
753 *msg = "zero structure field size";
754 return true;
756 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
758 *msg = "structure field offset not fixed";
759 return true;
761 if (!tree_fits_uhwi_p (DECL_SIZE (fld)))
763 *msg = "structure field size not fixed";
764 return true;
766 if (!tree_fits_shwi_p (bit_position (fld)))
768 *msg = "structure field size too big";
769 return true;
771 if (AGGREGATE_TYPE_P (ft)
772 && int_bit_position (fld) % BITS_PER_UNIT != 0)
774 *msg = "structure field is bit field";
775 return true;
778 if (AGGREGATE_TYPE_P (ft) && type_internals_preclude_sra_p (ft, msg))
779 return true;
782 return false;
784 case ARRAY_TYPE:
785 et = TREE_TYPE (type);
787 if (TYPE_VOLATILE (et))
789 *msg = "element type is volatile";
790 return true;
793 if (AGGREGATE_TYPE_P (et) && type_internals_preclude_sra_p (et, msg))
794 return true;
796 return false;
798 default:
799 return false;
803 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
804 base variable if it is. Return T if it is not an SSA_NAME. */
806 static tree
807 get_ssa_base_param (tree t)
809 if (TREE_CODE (t) == SSA_NAME)
811 if (SSA_NAME_IS_DEFAULT_DEF (t))
812 return SSA_NAME_VAR (t);
813 else
814 return NULL_TREE;
816 return t;
819 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
820 belongs to, unless the BB has already been marked as a potentially
821 final. */
823 static void
824 mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple stmt)
826 basic_block bb = gimple_bb (stmt);
827 int idx, parm_index = 0;
828 tree parm;
830 if (bitmap_bit_p (final_bbs, bb->index))
831 return;
833 for (parm = DECL_ARGUMENTS (current_function_decl);
834 parm && parm != base;
835 parm = DECL_CHAIN (parm))
836 parm_index++;
838 gcc_assert (parm_index < func_param_count);
840 idx = bb->index * func_param_count + parm_index;
841 if (bb_dereferences[idx] < dist)
842 bb_dereferences[idx] = dist;
845 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
846 the three fields. Also add it to the vector of accesses corresponding to
847 the base. Finally, return the new access. */
849 static struct access *
850 create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
852 vec<access_p> *v;
853 struct access *access;
854 void **slot;
856 access = (struct access *) pool_alloc (access_pool);
857 memset (access, 0, sizeof (struct access));
858 access->base = base;
859 access->offset = offset;
860 access->size = size;
862 slot = pointer_map_contains (base_access_vec, base);
863 if (slot)
864 v = (vec<access_p> *) *slot;
865 else
866 vec_alloc (v, 32);
868 v->safe_push (access);
870 *((vec<access_p> **)
871 pointer_map_insert (base_access_vec, base)) = v;
873 return access;
876 /* Create and insert access for EXPR. Return created access, or NULL if it is
877 not possible. */
879 static struct access *
880 create_access (tree expr, gimple stmt, bool write)
882 struct access *access;
883 HOST_WIDE_INT offset, size, max_size;
884 tree base = expr;
885 bool ptr, unscalarizable_region = false;
887 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
889 if (sra_mode == SRA_MODE_EARLY_IPA
890 && TREE_CODE (base) == MEM_REF)
892 base = get_ssa_base_param (TREE_OPERAND (base, 0));
893 if (!base)
894 return NULL;
895 ptr = true;
897 else
898 ptr = false;
900 if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
901 return NULL;
903 if (sra_mode == SRA_MODE_EARLY_IPA)
905 if (size < 0 || size != max_size)
907 disqualify_candidate (base, "Encountered a variable sized access.");
908 return NULL;
910 if (TREE_CODE (expr) == COMPONENT_REF
911 && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))
913 disqualify_candidate (base, "Encountered a bit-field access.");
914 return NULL;
916 gcc_checking_assert ((offset % BITS_PER_UNIT) == 0);
918 if (ptr)
919 mark_parm_dereference (base, offset + size, stmt);
921 else
923 if (size != max_size)
925 size = max_size;
926 unscalarizable_region = true;
928 if (size < 0)
930 disqualify_candidate (base, "Encountered an unconstrained access.");
931 return NULL;
935 access = create_access_1 (base, offset, size);
936 access->expr = expr;
937 access->type = TREE_TYPE (expr);
938 access->write = write;
939 access->grp_unscalarizable_region = unscalarizable_region;
940 access->stmt = stmt;
942 if (TREE_CODE (expr) == COMPONENT_REF
943 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1)))
944 access->non_addressable = 1;
946 return access;
950 /* Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple
951 register types or (recursively) records with only these two kinds of fields.
952 It also returns false if any of these records contains a bit-field. */
954 static bool
955 type_consists_of_records_p (tree type)
957 tree fld;
959 if (TREE_CODE (type) != RECORD_TYPE)
960 return false;
962 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
963 if (TREE_CODE (fld) == FIELD_DECL)
965 tree ft = TREE_TYPE (fld);
967 if (DECL_BIT_FIELD (fld))
968 return false;
970 if (!is_gimple_reg_type (ft)
971 && !type_consists_of_records_p (ft))
972 return false;
975 return true;
978 /* Create total_scalarization accesses for all scalar type fields in DECL that
979 must be of a RECORD_TYPE conforming to type_consists_of_records_p. BASE
980 must be the top-most VAR_DECL representing the variable, OFFSET must be the
981 offset of DECL within BASE. REF must be the memory reference expression for
982 the given decl. */
984 static void
985 completely_scalarize_record (tree base, tree decl, HOST_WIDE_INT offset,
986 tree ref)
988 tree fld, decl_type = TREE_TYPE (decl);
990 for (fld = TYPE_FIELDS (decl_type); fld; fld = DECL_CHAIN (fld))
991 if (TREE_CODE (fld) == FIELD_DECL)
993 HOST_WIDE_INT pos = offset + int_bit_position (fld);
994 tree ft = TREE_TYPE (fld);
995 tree nref = build3 (COMPONENT_REF, TREE_TYPE (fld), ref, fld,
996 NULL_TREE);
998 if (is_gimple_reg_type (ft))
1000 struct access *access;
1001 HOST_WIDE_INT size;
1003 size = tree_to_uhwi (DECL_SIZE (fld));
1004 access = create_access_1 (base, pos, size);
1005 access->expr = nref;
1006 access->type = ft;
1007 access->grp_total_scalarization = 1;
1008 /* Accesses for intraprocedural SRA can have their stmt NULL. */
1010 else
1011 completely_scalarize_record (base, fld, pos, nref);
1015 /* Create total_scalarization accesses for all scalar type fields in VAR and
1016 for VAR a a whole. VAR must be of a RECORD_TYPE conforming to
1017 type_consists_of_records_p. */
1019 static void
1020 completely_scalarize_var (tree var)
1022 HOST_WIDE_INT size = tree_to_uhwi (DECL_SIZE (var));
1023 struct access *access;
1025 access = create_access_1 (var, 0, size);
1026 access->expr = var;
1027 access->type = TREE_TYPE (var);
1028 access->grp_total_scalarization = 1;
1030 completely_scalarize_record (var, var, 0, var);
1033 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1035 static inline bool
1036 contains_view_convert_expr_p (const_tree ref)
1038 while (handled_component_p (ref))
1040 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
1041 return true;
1042 ref = TREE_OPERAND (ref, 0);
1045 return false;
1048 /* Search the given tree for a declaration by skipping handled components and
1049 exclude it from the candidates. */
1051 static void
1052 disqualify_base_of_expr (tree t, const char *reason)
1054 t = get_base_address (t);
1055 if (sra_mode == SRA_MODE_EARLY_IPA
1056 && TREE_CODE (t) == MEM_REF)
1057 t = get_ssa_base_param (TREE_OPERAND (t, 0));
1059 if (t && DECL_P (t))
1060 disqualify_candidate (t, reason);
1063 /* Scan expression EXPR and create access structures for all accesses to
1064 candidates for scalarization. Return the created access or NULL if none is
1065 created. */
1067 static struct access *
1068 build_access_from_expr_1 (tree expr, gimple stmt, bool write)
1070 struct access *ret = NULL;
1071 bool partial_ref;
1073 if (TREE_CODE (expr) == BIT_FIELD_REF
1074 || TREE_CODE (expr) == IMAGPART_EXPR
1075 || TREE_CODE (expr) == REALPART_EXPR)
1077 expr = TREE_OPERAND (expr, 0);
1078 partial_ref = true;
1080 else
1081 partial_ref = false;
1083 /* We need to dive through V_C_Es in order to get the size of its parameter
1084 and not the result type. Ada produces such statements. We are also
1085 capable of handling the topmost V_C_E but not any of those buried in other
1086 handled components. */
1087 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
1088 expr = TREE_OPERAND (expr, 0);
1090 if (contains_view_convert_expr_p (expr))
1092 disqualify_base_of_expr (expr, "V_C_E under a different handled "
1093 "component.");
1094 return NULL;
1097 switch (TREE_CODE (expr))
1099 case MEM_REF:
1100 if (TREE_CODE (TREE_OPERAND (expr, 0)) != ADDR_EXPR
1101 && sra_mode != SRA_MODE_EARLY_IPA)
1102 return NULL;
1103 /* fall through */
1104 case VAR_DECL:
1105 case PARM_DECL:
1106 case RESULT_DECL:
1107 case COMPONENT_REF:
1108 case ARRAY_REF:
1109 case ARRAY_RANGE_REF:
1110 ret = create_access (expr, stmt, write);
1111 break;
1113 default:
1114 break;
1117 if (write && partial_ref && ret)
1118 ret->grp_partial_lhs = 1;
1120 return ret;
1123 /* Scan expression EXPR and create access structures for all accesses to
1124 candidates for scalarization. Return true if any access has been inserted.
1125 STMT must be the statement from which the expression is taken, WRITE must be
1126 true if the expression is a store and false otherwise. */
1128 static bool
1129 build_access_from_expr (tree expr, gimple stmt, bool write)
1131 struct access *access;
1133 access = build_access_from_expr_1 (expr, stmt, write);
1134 if (access)
1136 /* This means the aggregate is accesses as a whole in a way other than an
1137 assign statement and thus cannot be removed even if we had a scalar
1138 replacement for everything. */
1139 if (cannot_scalarize_away_bitmap)
1140 bitmap_set_bit (cannot_scalarize_away_bitmap, DECL_UID (access->base));
1141 return true;
1143 return false;
1146 /* Return the single non-EH successor edge of BB or NULL if there is none or
1147 more than one. */
1149 static edge
1150 single_non_eh_succ (basic_block bb)
1152 edge e, res = NULL;
1153 edge_iterator ei;
1155 FOR_EACH_EDGE (e, ei, bb->succs)
1156 if (!(e->flags & EDGE_EH))
1158 if (res)
1159 return NULL;
1160 res = e;
1163 return res;
1166 /* Disqualify LHS and RHS for scalarization if STMT has to terminate its BB and
1167 there is no alternative spot where to put statements SRA might need to
1168 generate after it. The spot we are looking for is an edge leading to a
1169 single non-EH successor, if it exists and is indeed single. RHS may be
1170 NULL, in that case ignore it. */
1172 static bool
1173 disqualify_if_bad_bb_terminating_stmt (gimple stmt, tree lhs, tree rhs)
1175 if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1176 && stmt_ends_bb_p (stmt))
1178 if (single_non_eh_succ (gimple_bb (stmt)))
1179 return false;
1181 disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
1182 if (rhs)
1183 disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
1184 return true;
1186 return false;
1189 /* Scan expressions occurring in STMT, create access structures for all accesses
1190 to candidates for scalarization and remove those candidates which occur in
1191 statements or expressions that prevent them from being split apart. Return
1192 true if any access has been inserted. */
1194 static bool
1195 build_accesses_from_assign (gimple stmt)
1197 tree lhs, rhs;
1198 struct access *lacc, *racc;
1200 if (!gimple_assign_single_p (stmt)
1201 /* Scope clobbers don't influence scalarization. */
1202 || gimple_clobber_p (stmt))
1203 return false;
1205 lhs = gimple_assign_lhs (stmt);
1206 rhs = gimple_assign_rhs1 (stmt);
1208 if (disqualify_if_bad_bb_terminating_stmt (stmt, lhs, rhs))
1209 return false;
1211 racc = build_access_from_expr_1 (rhs, stmt, false);
1212 lacc = build_access_from_expr_1 (lhs, stmt, true);
1214 if (lacc)
1215 lacc->grp_assignment_write = 1;
1217 if (racc)
1219 racc->grp_assignment_read = 1;
1220 if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
1221 && !is_gimple_reg_type (racc->type))
1222 bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
1225 if (lacc && racc
1226 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1227 && !lacc->grp_unscalarizable_region
1228 && !racc->grp_unscalarizable_region
1229 && AGGREGATE_TYPE_P (TREE_TYPE (lhs))
1230 && lacc->size == racc->size
1231 && useless_type_conversion_p (lacc->type, racc->type))
1233 struct assign_link *link;
1235 link = (struct assign_link *) pool_alloc (link_pool);
1236 memset (link, 0, sizeof (struct assign_link));
1238 link->lacc = lacc;
1239 link->racc = racc;
1241 add_link_to_rhs (racc, link);
1244 return lacc || racc;
1247 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1248 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1250 static bool
1251 asm_visit_addr (gimple, tree op, tree, void *)
1253 op = get_base_address (op);
1254 if (op
1255 && DECL_P (op))
1256 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
1258 return false;
1261 /* Return true iff callsite CALL has at least as many actual arguments as there
1262 are formal parameters of the function currently processed by IPA-SRA and
1263 that their types match. */
1265 static inline bool
1266 callsite_arguments_match_p (gimple call)
1268 if (gimple_call_num_args (call) < (unsigned) func_param_count)
1269 return false;
1271 tree parm;
1272 int i;
1273 for (parm = DECL_ARGUMENTS (current_function_decl), i = 0;
1274 parm;
1275 parm = DECL_CHAIN (parm), i++)
1277 tree arg = gimple_call_arg (call, i);
1278 if (!useless_type_conversion_p (TREE_TYPE (parm), TREE_TYPE (arg)))
1279 return false;
1281 return true;
1284 /* Scan function and look for interesting expressions and create access
1285 structures for them. Return true iff any access is created. */
1287 static bool
1288 scan_function (void)
1290 basic_block bb;
1291 bool ret = false;
1293 FOR_EACH_BB_FN (bb, cfun)
1295 gimple_stmt_iterator gsi;
1296 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1298 gimple stmt = gsi_stmt (gsi);
1299 tree t;
1300 unsigned i;
1302 if (final_bbs && stmt_can_throw_external (stmt))
1303 bitmap_set_bit (final_bbs, bb->index);
1304 switch (gimple_code (stmt))
1306 case GIMPLE_RETURN:
1307 t = gimple_return_retval (stmt);
1308 if (t != NULL_TREE)
1309 ret |= build_access_from_expr (t, stmt, false);
1310 if (final_bbs)
1311 bitmap_set_bit (final_bbs, bb->index);
1312 break;
1314 case GIMPLE_ASSIGN:
1315 ret |= build_accesses_from_assign (stmt);
1316 break;
1318 case GIMPLE_CALL:
1319 for (i = 0; i < gimple_call_num_args (stmt); i++)
1320 ret |= build_access_from_expr (gimple_call_arg (stmt, i),
1321 stmt, false);
1323 if (sra_mode == SRA_MODE_EARLY_IPA)
1325 tree dest = gimple_call_fndecl (stmt);
1326 int flags = gimple_call_flags (stmt);
1328 if (dest)
1330 if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1331 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1332 encountered_apply_args = true;
1333 if (recursive_call_p (current_function_decl, dest))
1335 encountered_recursive_call = true;
1336 if (!callsite_arguments_match_p (stmt))
1337 encountered_unchangable_recursive_call = true;
1341 if (final_bbs
1342 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1343 bitmap_set_bit (final_bbs, bb->index);
1346 t = gimple_call_lhs (stmt);
1347 if (t && !disqualify_if_bad_bb_terminating_stmt (stmt, t, NULL))
1348 ret |= build_access_from_expr (t, stmt, true);
1349 break;
1351 case GIMPLE_ASM:
1352 walk_stmt_load_store_addr_ops (stmt, NULL, NULL, NULL,
1353 asm_visit_addr);
1354 if (final_bbs)
1355 bitmap_set_bit (final_bbs, bb->index);
1357 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
1359 t = TREE_VALUE (gimple_asm_input_op (stmt, i));
1360 ret |= build_access_from_expr (t, stmt, false);
1362 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
1364 t = TREE_VALUE (gimple_asm_output_op (stmt, i));
1365 ret |= build_access_from_expr (t, stmt, true);
1367 break;
1369 default:
1370 break;
1375 return ret;
1378 /* Helper of QSORT function. There are pointers to accesses in the array. An
1379 access is considered smaller than another if it has smaller offset or if the
1380 offsets are the same but is size is bigger. */
1382 static int
1383 compare_access_positions (const void *a, const void *b)
1385 const access_p *fp1 = (const access_p *) a;
1386 const access_p *fp2 = (const access_p *) b;
1387 const access_p f1 = *fp1;
1388 const access_p f2 = *fp2;
1390 if (f1->offset != f2->offset)
1391 return f1->offset < f2->offset ? -1 : 1;
1393 if (f1->size == f2->size)
1395 if (f1->type == f2->type)
1396 return 0;
1397 /* Put any non-aggregate type before any aggregate type. */
1398 else if (!is_gimple_reg_type (f1->type)
1399 && is_gimple_reg_type (f2->type))
1400 return 1;
1401 else if (is_gimple_reg_type (f1->type)
1402 && !is_gimple_reg_type (f2->type))
1403 return -1;
1404 /* Put any complex or vector type before any other scalar type. */
1405 else if (TREE_CODE (f1->type) != COMPLEX_TYPE
1406 && TREE_CODE (f1->type) != VECTOR_TYPE
1407 && (TREE_CODE (f2->type) == COMPLEX_TYPE
1408 || TREE_CODE (f2->type) == VECTOR_TYPE))
1409 return 1;
1410 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
1411 || TREE_CODE (f1->type) == VECTOR_TYPE)
1412 && TREE_CODE (f2->type) != COMPLEX_TYPE
1413 && TREE_CODE (f2->type) != VECTOR_TYPE)
1414 return -1;
1415 /* Put the integral type with the bigger precision first. */
1416 else if (INTEGRAL_TYPE_P (f1->type)
1417 && INTEGRAL_TYPE_P (f2->type))
1418 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
1419 /* Put any integral type with non-full precision last. */
1420 else if (INTEGRAL_TYPE_P (f1->type)
1421 && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type))
1422 != TYPE_PRECISION (f1->type)))
1423 return 1;
1424 else if (INTEGRAL_TYPE_P (f2->type)
1425 && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type))
1426 != TYPE_PRECISION (f2->type)))
1427 return -1;
1428 /* Stabilize the sort. */
1429 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1432 /* We want the bigger accesses first, thus the opposite operator in the next
1433 line: */
1434 return f1->size > f2->size ? -1 : 1;
1438 /* Append a name of the declaration to the name obstack. A helper function for
1439 make_fancy_name. */
1441 static void
1442 make_fancy_decl_name (tree decl)
1444 char buffer[32];
1446 tree name = DECL_NAME (decl);
1447 if (name)
1448 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1449 IDENTIFIER_LENGTH (name));
1450 else
1452 sprintf (buffer, "D%u", DECL_UID (decl));
1453 obstack_grow (&name_obstack, buffer, strlen (buffer));
1457 /* Helper for make_fancy_name. */
1459 static void
1460 make_fancy_name_1 (tree expr)
1462 char buffer[32];
1463 tree index;
1465 if (DECL_P (expr))
1467 make_fancy_decl_name (expr);
1468 return;
1471 switch (TREE_CODE (expr))
1473 case COMPONENT_REF:
1474 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1475 obstack_1grow (&name_obstack, '$');
1476 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1477 break;
1479 case ARRAY_REF:
1480 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1481 obstack_1grow (&name_obstack, '$');
1482 /* Arrays with only one element may not have a constant as their
1483 index. */
1484 index = TREE_OPERAND (expr, 1);
1485 if (TREE_CODE (index) != INTEGER_CST)
1486 break;
1487 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1488 obstack_grow (&name_obstack, buffer, strlen (buffer));
1489 break;
1491 case ADDR_EXPR:
1492 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1493 break;
1495 case MEM_REF:
1496 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1497 if (!integer_zerop (TREE_OPERAND (expr, 1)))
1499 obstack_1grow (&name_obstack, '$');
1500 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC,
1501 TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)));
1502 obstack_grow (&name_obstack, buffer, strlen (buffer));
1504 break;
1506 case BIT_FIELD_REF:
1507 case REALPART_EXPR:
1508 case IMAGPART_EXPR:
1509 gcc_unreachable (); /* we treat these as scalars. */
1510 break;
1511 default:
1512 break;
1516 /* Create a human readable name for replacement variable of ACCESS. */
1518 static char *
1519 make_fancy_name (tree expr)
1521 make_fancy_name_1 (expr);
1522 obstack_1grow (&name_obstack, '\0');
1523 return XOBFINISH (&name_obstack, char *);
1526 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1527 EXP_TYPE at the given OFFSET. If BASE is something for which
1528 get_addr_base_and_unit_offset returns NULL, gsi must be non-NULL and is used
1529 to insert new statements either before or below the current one as specified
1530 by INSERT_AFTER. This function is not capable of handling bitfields.
1532 BASE must be either a declaration or a memory reference that has correct
1533 alignment ifformation embeded in it (e.g. a pre-existing one in SRA). */
1535 tree
1536 build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
1537 tree exp_type, gimple_stmt_iterator *gsi,
1538 bool insert_after)
1540 tree prev_base = base;
1541 tree off;
1542 tree mem_ref;
1543 HOST_WIDE_INT base_offset;
1544 unsigned HOST_WIDE_INT misalign;
1545 unsigned int align;
1547 gcc_checking_assert (offset % BITS_PER_UNIT == 0);
1548 get_object_alignment_1 (base, &align, &misalign);
1549 base = get_addr_base_and_unit_offset (base, &base_offset);
1551 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1552 offset such as array[var_index]. */
1553 if (!base)
1555 gimple stmt;
1556 tree tmp, addr;
1558 gcc_checking_assert (gsi);
1559 tmp = make_ssa_name (build_pointer_type (TREE_TYPE (prev_base)), NULL);
1560 addr = build_fold_addr_expr (unshare_expr (prev_base));
1561 STRIP_USELESS_TYPE_CONVERSION (addr);
1562 stmt = gimple_build_assign (tmp, addr);
1563 gimple_set_location (stmt, loc);
1564 if (insert_after)
1565 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
1566 else
1567 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1569 off = build_int_cst (reference_alias_ptr_type (prev_base),
1570 offset / BITS_PER_UNIT);
1571 base = tmp;
1573 else if (TREE_CODE (base) == MEM_REF)
1575 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1576 base_offset + offset / BITS_PER_UNIT);
1577 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1578 base = unshare_expr (TREE_OPERAND (base, 0));
1580 else
1582 off = build_int_cst (reference_alias_ptr_type (base),
1583 base_offset + offset / BITS_PER_UNIT);
1584 base = build_fold_addr_expr (unshare_expr (base));
1587 misalign = (misalign + offset) & (align - 1);
1588 if (misalign != 0)
1589 align = (misalign & -misalign);
1590 if (align < TYPE_ALIGN (exp_type))
1591 exp_type = build_aligned_type (exp_type, align);
1593 mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off);
1594 if (TREE_THIS_VOLATILE (prev_base))
1595 TREE_THIS_VOLATILE (mem_ref) = 1;
1596 if (TREE_SIDE_EFFECTS (prev_base))
1597 TREE_SIDE_EFFECTS (mem_ref) = 1;
1598 return mem_ref;
1601 /* Construct a memory reference to a part of an aggregate BASE at the given
1602 OFFSET and of the same type as MODEL. In case this is a reference to a
1603 bit-field, the function will replicate the last component_ref of model's
1604 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1605 build_ref_for_offset. */
1607 static tree
1608 build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1609 struct access *model, gimple_stmt_iterator *gsi,
1610 bool insert_after)
1612 if (TREE_CODE (model->expr) == COMPONENT_REF
1613 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1615 /* This access represents a bit-field. */
1616 tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
1618 offset -= int_bit_position (fld);
1619 exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
1620 t = build_ref_for_offset (loc, base, offset, exp_type, gsi, insert_after);
1621 return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
1622 NULL_TREE);
1624 else
1625 return build_ref_for_offset (loc, base, offset, model->type,
1626 gsi, insert_after);
1629 /* Attempt to build a memory reference that we could but into a gimple
1630 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1631 create statements and return s NULL instead. This function also ignores
1632 alignment issues and so its results should never end up in non-debug
1633 statements. */
1635 static tree
1636 build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1637 struct access *model)
1639 HOST_WIDE_INT base_offset;
1640 tree off;
1642 if (TREE_CODE (model->expr) == COMPONENT_REF
1643 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1644 return NULL_TREE;
1646 base = get_addr_base_and_unit_offset (base, &base_offset);
1647 if (!base)
1648 return NULL_TREE;
1649 if (TREE_CODE (base) == MEM_REF)
1651 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1652 base_offset + offset / BITS_PER_UNIT);
1653 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1654 base = unshare_expr (TREE_OPERAND (base, 0));
1656 else
1658 off = build_int_cst (reference_alias_ptr_type (base),
1659 base_offset + offset / BITS_PER_UNIT);
1660 base = build_fold_addr_expr (unshare_expr (base));
1663 return fold_build2_loc (loc, MEM_REF, model->type, base, off);
1666 /* Construct a memory reference consisting of component_refs and array_refs to
1667 a part of an aggregate *RES (which is of type TYPE). The requested part
1668 should have type EXP_TYPE at be the given OFFSET. This function might not
1669 succeed, it returns true when it does and only then *RES points to something
1670 meaningful. This function should be used only to build expressions that we
1671 might need to present to user (e.g. in warnings). In all other situations,
1672 build_ref_for_model or build_ref_for_offset should be used instead. */
1674 static bool
1675 build_user_friendly_ref_for_offset (tree *res, tree type, HOST_WIDE_INT offset,
1676 tree exp_type)
1678 while (1)
1680 tree fld;
1681 tree tr_size, index, minidx;
1682 HOST_WIDE_INT el_size;
1684 if (offset == 0 && exp_type
1685 && types_compatible_p (exp_type, type))
1686 return true;
1688 switch (TREE_CODE (type))
1690 case UNION_TYPE:
1691 case QUAL_UNION_TYPE:
1692 case RECORD_TYPE:
1693 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
1695 HOST_WIDE_INT pos, size;
1696 tree tr_pos, expr, *expr_ptr;
1698 if (TREE_CODE (fld) != FIELD_DECL)
1699 continue;
1701 tr_pos = bit_position (fld);
1702 if (!tr_pos || !tree_fits_uhwi_p (tr_pos))
1703 continue;
1704 pos = tree_to_uhwi (tr_pos);
1705 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1706 tr_size = DECL_SIZE (fld);
1707 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1708 continue;
1709 size = tree_to_uhwi (tr_size);
1710 if (size == 0)
1712 if (pos != offset)
1713 continue;
1715 else if (pos > offset || (pos + size) <= offset)
1716 continue;
1718 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1719 NULL_TREE);
1720 expr_ptr = &expr;
1721 if (build_user_friendly_ref_for_offset (expr_ptr, TREE_TYPE (fld),
1722 offset - pos, exp_type))
1724 *res = expr;
1725 return true;
1728 return false;
1730 case ARRAY_TYPE:
1731 tr_size = TYPE_SIZE (TREE_TYPE (type));
1732 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1733 return false;
1734 el_size = tree_to_uhwi (tr_size);
1736 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1737 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
1738 return false;
1739 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1740 if (!integer_zerop (minidx))
1741 index = int_const_binop (PLUS_EXPR, index, minidx);
1742 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1743 NULL_TREE, NULL_TREE);
1744 offset = offset % el_size;
1745 type = TREE_TYPE (type);
1746 break;
1748 default:
1749 if (offset != 0)
1750 return false;
1752 if (exp_type)
1753 return false;
1754 else
1755 return true;
1760 /* Return true iff TYPE is stdarg va_list type. */
1762 static inline bool
1763 is_va_list_type (tree type)
1765 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1768 /* Print message to dump file why a variable was rejected. */
1770 static void
1771 reject (tree var, const char *msg)
1773 if (dump_file && (dump_flags & TDF_DETAILS))
1775 fprintf (dump_file, "Rejected (%d): %s: ", DECL_UID (var), msg);
1776 print_generic_expr (dump_file, var, 0);
1777 fprintf (dump_file, "\n");
1781 /* Return true if VAR is a candidate for SRA. */
1783 static bool
1784 maybe_add_sra_candidate (tree var)
1786 tree type = TREE_TYPE (var);
1787 const char *msg;
1788 tree_node **slot;
1790 if (!AGGREGATE_TYPE_P (type))
1792 reject (var, "not aggregate");
1793 return false;
1795 if (needs_to_live_in_memory (var))
1797 reject (var, "needs to live in memory");
1798 return false;
1800 if (TREE_THIS_VOLATILE (var))
1802 reject (var, "is volatile");
1803 return false;
1805 if (!COMPLETE_TYPE_P (type))
1807 reject (var, "has incomplete type");
1808 return false;
1810 if (!tree_fits_uhwi_p (TYPE_SIZE (type)))
1812 reject (var, "type size not fixed");
1813 return false;
1815 if (tree_to_uhwi (TYPE_SIZE (type)) == 0)
1817 reject (var, "type size is zero");
1818 return false;
1820 if (type_internals_preclude_sra_p (type, &msg))
1822 reject (var, msg);
1823 return false;
1825 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1826 we also want to schedule it rather late. Thus we ignore it in
1827 the early pass. */
1828 (sra_mode == SRA_MODE_EARLY_INTRA
1829 && is_va_list_type (type)))
1831 reject (var, "is va_list");
1832 return false;
1835 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
1836 slot = candidates->find_slot_with_hash (var, DECL_UID (var), INSERT);
1837 *slot = var;
1839 if (dump_file && (dump_flags & TDF_DETAILS))
1841 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
1842 print_generic_expr (dump_file, var, 0);
1843 fprintf (dump_file, "\n");
1846 return true;
1849 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1850 those with type which is suitable for scalarization. */
1852 static bool
1853 find_var_candidates (void)
1855 tree var, parm;
1856 unsigned int i;
1857 bool ret = false;
1859 for (parm = DECL_ARGUMENTS (current_function_decl);
1860 parm;
1861 parm = DECL_CHAIN (parm))
1862 ret |= maybe_add_sra_candidate (parm);
1864 FOR_EACH_LOCAL_DECL (cfun, i, var)
1866 if (TREE_CODE (var) != VAR_DECL)
1867 continue;
1869 ret |= maybe_add_sra_candidate (var);
1872 return ret;
1875 /* Sort all accesses for the given variable, check for partial overlaps and
1876 return NULL if there are any. If there are none, pick a representative for
1877 each combination of offset and size and create a linked list out of them.
1878 Return the pointer to the first representative and make sure it is the first
1879 one in the vector of accesses. */
1881 static struct access *
1882 sort_and_splice_var_accesses (tree var)
1884 int i, j, access_count;
1885 struct access *res, **prev_acc_ptr = &res;
1886 vec<access_p> *access_vec;
1887 bool first = true;
1888 HOST_WIDE_INT low = -1, high = 0;
1890 access_vec = get_base_access_vector (var);
1891 if (!access_vec)
1892 return NULL;
1893 access_count = access_vec->length ();
1895 /* Sort by <OFFSET, SIZE>. */
1896 access_vec->qsort (compare_access_positions);
1898 i = 0;
1899 while (i < access_count)
1901 struct access *access = (*access_vec)[i];
1902 bool grp_write = access->write;
1903 bool grp_read = !access->write;
1904 bool grp_scalar_write = access->write
1905 && is_gimple_reg_type (access->type);
1906 bool grp_scalar_read = !access->write
1907 && is_gimple_reg_type (access->type);
1908 bool grp_assignment_read = access->grp_assignment_read;
1909 bool grp_assignment_write = access->grp_assignment_write;
1910 bool multiple_scalar_reads = false;
1911 bool total_scalarization = access->grp_total_scalarization;
1912 bool grp_partial_lhs = access->grp_partial_lhs;
1913 bool first_scalar = is_gimple_reg_type (access->type);
1914 bool unscalarizable_region = access->grp_unscalarizable_region;
1916 if (first || access->offset >= high)
1918 first = false;
1919 low = access->offset;
1920 high = access->offset + access->size;
1922 else if (access->offset > low && access->offset + access->size > high)
1923 return NULL;
1924 else
1925 gcc_assert (access->offset >= low
1926 && access->offset + access->size <= high);
1928 j = i + 1;
1929 while (j < access_count)
1931 struct access *ac2 = (*access_vec)[j];
1932 if (ac2->offset != access->offset || ac2->size != access->size)
1933 break;
1934 if (ac2->write)
1936 grp_write = true;
1937 grp_scalar_write = (grp_scalar_write
1938 || is_gimple_reg_type (ac2->type));
1940 else
1942 grp_read = true;
1943 if (is_gimple_reg_type (ac2->type))
1945 if (grp_scalar_read)
1946 multiple_scalar_reads = true;
1947 else
1948 grp_scalar_read = true;
1951 grp_assignment_read |= ac2->grp_assignment_read;
1952 grp_assignment_write |= ac2->grp_assignment_write;
1953 grp_partial_lhs |= ac2->grp_partial_lhs;
1954 unscalarizable_region |= ac2->grp_unscalarizable_region;
1955 total_scalarization |= ac2->grp_total_scalarization;
1956 relink_to_new_repr (access, ac2);
1958 /* If there are both aggregate-type and scalar-type accesses with
1959 this combination of size and offset, the comparison function
1960 should have put the scalars first. */
1961 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
1962 ac2->group_representative = access;
1963 j++;
1966 i = j;
1968 access->group_representative = access;
1969 access->grp_write = grp_write;
1970 access->grp_read = grp_read;
1971 access->grp_scalar_read = grp_scalar_read;
1972 access->grp_scalar_write = grp_scalar_write;
1973 access->grp_assignment_read = grp_assignment_read;
1974 access->grp_assignment_write = grp_assignment_write;
1975 access->grp_hint = multiple_scalar_reads || total_scalarization;
1976 access->grp_total_scalarization = total_scalarization;
1977 access->grp_partial_lhs = grp_partial_lhs;
1978 access->grp_unscalarizable_region = unscalarizable_region;
1979 if (access->first_link)
1980 add_access_to_work_queue (access);
1982 *prev_acc_ptr = access;
1983 prev_acc_ptr = &access->next_grp;
1986 gcc_assert (res == (*access_vec)[0]);
1987 return res;
1990 /* Create a variable for the given ACCESS which determines the type, name and a
1991 few other properties. Return the variable declaration and store it also to
1992 ACCESS->replacement. */
1994 static tree
1995 create_access_replacement (struct access *access)
1997 tree repl;
1999 if (access->grp_to_be_debug_replaced)
2001 repl = create_tmp_var_raw (access->type, NULL);
2002 DECL_CONTEXT (repl) = current_function_decl;
2004 else
2005 repl = create_tmp_var (access->type, "SR");
2006 if (TREE_CODE (access->type) == COMPLEX_TYPE
2007 || TREE_CODE (access->type) == VECTOR_TYPE)
2009 if (!access->grp_partial_lhs)
2010 DECL_GIMPLE_REG_P (repl) = 1;
2012 else if (access->grp_partial_lhs
2013 && is_gimple_reg_type (access->type))
2014 TREE_ADDRESSABLE (repl) = 1;
2016 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
2017 DECL_ARTIFICIAL (repl) = 1;
2018 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
2020 if (DECL_NAME (access->base)
2021 && !DECL_IGNORED_P (access->base)
2022 && !DECL_ARTIFICIAL (access->base))
2024 char *pretty_name = make_fancy_name (access->expr);
2025 tree debug_expr = unshare_expr_without_location (access->expr), d;
2026 bool fail = false;
2028 DECL_NAME (repl) = get_identifier (pretty_name);
2029 obstack_free (&name_obstack, pretty_name);
2031 /* Get rid of any SSA_NAMEs embedded in debug_expr,
2032 as DECL_DEBUG_EXPR isn't considered when looking for still
2033 used SSA_NAMEs and thus they could be freed. All debug info
2034 generation cares is whether something is constant or variable
2035 and that get_ref_base_and_extent works properly on the
2036 expression. It cannot handle accesses at a non-constant offset
2037 though, so just give up in those cases. */
2038 for (d = debug_expr;
2039 !fail && (handled_component_p (d) || TREE_CODE (d) == MEM_REF);
2040 d = TREE_OPERAND (d, 0))
2041 switch (TREE_CODE (d))
2043 case ARRAY_REF:
2044 case ARRAY_RANGE_REF:
2045 if (TREE_OPERAND (d, 1)
2046 && TREE_CODE (TREE_OPERAND (d, 1)) != INTEGER_CST)
2047 fail = true;
2048 if (TREE_OPERAND (d, 3)
2049 && TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST)
2050 fail = true;
2051 /* FALLTHRU */
2052 case COMPONENT_REF:
2053 if (TREE_OPERAND (d, 2)
2054 && TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST)
2055 fail = true;
2056 break;
2057 case MEM_REF:
2058 if (TREE_CODE (TREE_OPERAND (d, 0)) != ADDR_EXPR)
2059 fail = true;
2060 else
2061 d = TREE_OPERAND (d, 0);
2062 break;
2063 default:
2064 break;
2066 if (!fail)
2068 SET_DECL_DEBUG_EXPR (repl, debug_expr);
2069 DECL_HAS_DEBUG_EXPR_P (repl) = 1;
2071 if (access->grp_no_warning)
2072 TREE_NO_WARNING (repl) = 1;
2073 else
2074 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
2076 else
2077 TREE_NO_WARNING (repl) = 1;
2079 if (dump_file)
2081 if (access->grp_to_be_debug_replaced)
2083 fprintf (dump_file, "Created a debug-only replacement for ");
2084 print_generic_expr (dump_file, access->base, 0);
2085 fprintf (dump_file, " offset: %u, size: %u\n",
2086 (unsigned) access->offset, (unsigned) access->size);
2088 else
2090 fprintf (dump_file, "Created a replacement for ");
2091 print_generic_expr (dump_file, access->base, 0);
2092 fprintf (dump_file, " offset: %u, size: %u: ",
2093 (unsigned) access->offset, (unsigned) access->size);
2094 print_generic_expr (dump_file, repl, 0);
2095 fprintf (dump_file, "\n");
2098 sra_stats.replacements++;
2100 return repl;
2103 /* Return ACCESS scalar replacement, create it if it does not exist yet. */
2105 static inline tree
2106 get_access_replacement (struct access *access)
2108 gcc_checking_assert (access->replacement_decl);
2109 return access->replacement_decl;
2113 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2114 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2115 to it is not "within" the root. Return false iff some accesses partially
2116 overlap. */
2118 static bool
2119 build_access_subtree (struct access **access)
2121 struct access *root = *access, *last_child = NULL;
2122 HOST_WIDE_INT limit = root->offset + root->size;
2124 *access = (*access)->next_grp;
2125 while (*access && (*access)->offset + (*access)->size <= limit)
2127 if (!last_child)
2128 root->first_child = *access;
2129 else
2130 last_child->next_sibling = *access;
2131 last_child = *access;
2133 if (!build_access_subtree (access))
2134 return false;
2137 if (*access && (*access)->offset < limit)
2138 return false;
2140 return true;
2143 /* Build a tree of access representatives, ACCESS is the pointer to the first
2144 one, others are linked in a list by the next_grp field. Return false iff
2145 some accesses partially overlap. */
2147 static bool
2148 build_access_trees (struct access *access)
2150 while (access)
2152 struct access *root = access;
2154 if (!build_access_subtree (&access))
2155 return false;
2156 root->next_grp = access;
2158 return true;
2161 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2162 array. */
2164 static bool
2165 expr_with_var_bounded_array_refs_p (tree expr)
2167 while (handled_component_p (expr))
2169 if (TREE_CODE (expr) == ARRAY_REF
2170 && !tree_fits_shwi_p (array_ref_low_bound (expr)))
2171 return true;
2172 expr = TREE_OPERAND (expr, 0);
2174 return false;
2177 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2178 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2179 sorts of access flags appropriately along the way, notably always set
2180 grp_read and grp_assign_read according to MARK_READ and grp_write when
2181 MARK_WRITE is true.
2183 Creating a replacement for a scalar access is considered beneficial if its
2184 grp_hint is set (this means we are either attempting total scalarization or
2185 there is more than one direct read access) or according to the following
2186 table:
2188 Access written to through a scalar type (once or more times)
2190 | Written to in an assignment statement
2192 | | Access read as scalar _once_
2193 | | |
2194 | | | Read in an assignment statement
2195 | | | |
2196 | | | | Scalarize Comment
2197 -----------------------------------------------------------------------------
2198 0 0 0 0 No access for the scalar
2199 0 0 0 1 No access for the scalar
2200 0 0 1 0 No Single read - won't help
2201 0 0 1 1 No The same case
2202 0 1 0 0 No access for the scalar
2203 0 1 0 1 No access for the scalar
2204 0 1 1 0 Yes s = *g; return s.i;
2205 0 1 1 1 Yes The same case as above
2206 1 0 0 0 No Won't help
2207 1 0 0 1 Yes s.i = 1; *g = s;
2208 1 0 1 0 Yes s.i = 5; g = s.i;
2209 1 0 1 1 Yes The same case as above
2210 1 1 0 0 No Won't help.
2211 1 1 0 1 Yes s.i = 1; *g = s;
2212 1 1 1 0 Yes s = *g; return s.i;
2213 1 1 1 1 Yes Any of the above yeses */
2215 static bool
2216 analyze_access_subtree (struct access *root, struct access *parent,
2217 bool allow_replacements)
2219 struct access *child;
2220 HOST_WIDE_INT limit = root->offset + root->size;
2221 HOST_WIDE_INT covered_to = root->offset;
2222 bool scalar = is_gimple_reg_type (root->type);
2223 bool hole = false, sth_created = false;
2225 if (parent)
2227 if (parent->grp_read)
2228 root->grp_read = 1;
2229 if (parent->grp_assignment_read)
2230 root->grp_assignment_read = 1;
2231 if (parent->grp_write)
2232 root->grp_write = 1;
2233 if (parent->grp_assignment_write)
2234 root->grp_assignment_write = 1;
2235 if (parent->grp_total_scalarization)
2236 root->grp_total_scalarization = 1;
2239 if (root->grp_unscalarizable_region)
2240 allow_replacements = false;
2242 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
2243 allow_replacements = false;
2245 for (child = root->first_child; child; child = child->next_sibling)
2247 hole |= covered_to < child->offset;
2248 sth_created |= analyze_access_subtree (child, root,
2249 allow_replacements && !scalar);
2251 root->grp_unscalarized_data |= child->grp_unscalarized_data;
2252 root->grp_total_scalarization &= child->grp_total_scalarization;
2253 if (child->grp_covered)
2254 covered_to += child->size;
2255 else
2256 hole = true;
2259 if (allow_replacements && scalar && !root->first_child
2260 && (root->grp_hint
2261 || ((root->grp_scalar_read || root->grp_assignment_read)
2262 && (root->grp_scalar_write || root->grp_assignment_write))))
2264 /* Always create access replacements that cover the whole access.
2265 For integral types this means the precision has to match.
2266 Avoid assumptions based on the integral type kind, too. */
2267 if (INTEGRAL_TYPE_P (root->type)
2268 && (TREE_CODE (root->type) != INTEGER_TYPE
2269 || TYPE_PRECISION (root->type) != root->size)
2270 /* But leave bitfield accesses alone. */
2271 && (TREE_CODE (root->expr) != COMPONENT_REF
2272 || !DECL_BIT_FIELD (TREE_OPERAND (root->expr, 1))))
2274 tree rt = root->type;
2275 gcc_assert ((root->offset % BITS_PER_UNIT) == 0
2276 && (root->size % BITS_PER_UNIT) == 0);
2277 root->type = build_nonstandard_integer_type (root->size,
2278 TYPE_UNSIGNED (rt));
2279 root->expr = build_ref_for_offset (UNKNOWN_LOCATION,
2280 root->base, root->offset,
2281 root->type, NULL, false);
2283 if (dump_file && (dump_flags & TDF_DETAILS))
2285 fprintf (dump_file, "Changing the type of a replacement for ");
2286 print_generic_expr (dump_file, root->base, 0);
2287 fprintf (dump_file, " offset: %u, size: %u ",
2288 (unsigned) root->offset, (unsigned) root->size);
2289 fprintf (dump_file, " to an integer.\n");
2293 root->grp_to_be_replaced = 1;
2294 root->replacement_decl = create_access_replacement (root);
2295 sth_created = true;
2296 hole = false;
2298 else
2300 if (allow_replacements
2301 && scalar && !root->first_child
2302 && (root->grp_scalar_write || root->grp_assignment_write)
2303 && !bitmap_bit_p (cannot_scalarize_away_bitmap,
2304 DECL_UID (root->base)))
2306 gcc_checking_assert (!root->grp_scalar_read
2307 && !root->grp_assignment_read);
2308 sth_created = true;
2309 if (MAY_HAVE_DEBUG_STMTS)
2311 root->grp_to_be_debug_replaced = 1;
2312 root->replacement_decl = create_access_replacement (root);
2316 if (covered_to < limit)
2317 hole = true;
2318 if (scalar)
2319 root->grp_total_scalarization = 0;
2322 if (!hole || root->grp_total_scalarization)
2323 root->grp_covered = 1;
2324 else if (root->grp_write || TREE_CODE (root->base) == PARM_DECL)
2325 root->grp_unscalarized_data = 1; /* not covered and written to */
2326 return sth_created;
2329 /* Analyze all access trees linked by next_grp by the means of
2330 analyze_access_subtree. */
2331 static bool
2332 analyze_access_trees (struct access *access)
2334 bool ret = false;
2336 while (access)
2338 if (analyze_access_subtree (access, NULL, true))
2339 ret = true;
2340 access = access->next_grp;
2343 return ret;
2346 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2347 SIZE would conflict with an already existing one. If exactly such a child
2348 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2350 static bool
2351 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
2352 HOST_WIDE_INT size, struct access **exact_match)
2354 struct access *child;
2356 for (child = lacc->first_child; child; child = child->next_sibling)
2358 if (child->offset == norm_offset && child->size == size)
2360 *exact_match = child;
2361 return true;
2364 if (child->offset < norm_offset + size
2365 && child->offset + child->size > norm_offset)
2366 return true;
2369 return false;
2372 /* Create a new child access of PARENT, with all properties just like MODEL
2373 except for its offset and with its grp_write false and grp_read true.
2374 Return the new access or NULL if it cannot be created. Note that this access
2375 is created long after all splicing and sorting, it's not located in any
2376 access vector and is automatically a representative of its group. */
2378 static struct access *
2379 create_artificial_child_access (struct access *parent, struct access *model,
2380 HOST_WIDE_INT new_offset)
2382 struct access *access;
2383 struct access **child;
2384 tree expr = parent->base;
2386 gcc_assert (!model->grp_unscalarizable_region);
2388 access = (struct access *) pool_alloc (access_pool);
2389 memset (access, 0, sizeof (struct access));
2390 if (!build_user_friendly_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
2391 model->type))
2393 access->grp_no_warning = true;
2394 expr = build_ref_for_model (EXPR_LOCATION (parent->base), parent->base,
2395 new_offset, model, NULL, false);
2398 access->base = parent->base;
2399 access->expr = expr;
2400 access->offset = new_offset;
2401 access->size = model->size;
2402 access->type = model->type;
2403 access->grp_write = true;
2404 access->grp_read = false;
2406 child = &parent->first_child;
2407 while (*child && (*child)->offset < new_offset)
2408 child = &(*child)->next_sibling;
2410 access->next_sibling = *child;
2411 *child = access;
2413 return access;
2417 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
2418 true if any new subaccess was created. Additionally, if RACC is a scalar
2419 access but LACC is not, change the type of the latter, if possible. */
2421 static bool
2422 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
2424 struct access *rchild;
2425 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
2426 bool ret = false;
2428 if (is_gimple_reg_type (lacc->type)
2429 || lacc->grp_unscalarizable_region
2430 || racc->grp_unscalarizable_region)
2431 return false;
2433 if (is_gimple_reg_type (racc->type))
2435 if (!lacc->first_child && !racc->first_child)
2437 tree t = lacc->base;
2439 lacc->type = racc->type;
2440 if (build_user_friendly_ref_for_offset (&t, TREE_TYPE (t),
2441 lacc->offset, racc->type))
2442 lacc->expr = t;
2443 else
2445 lacc->expr = build_ref_for_model (EXPR_LOCATION (lacc->base),
2446 lacc->base, lacc->offset,
2447 racc, NULL, false);
2448 lacc->grp_no_warning = true;
2451 return false;
2454 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
2456 struct access *new_acc = NULL;
2457 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
2459 if (rchild->grp_unscalarizable_region)
2460 continue;
2462 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
2463 &new_acc))
2465 if (new_acc)
2467 rchild->grp_hint = 1;
2468 new_acc->grp_hint |= new_acc->grp_read;
2469 if (rchild->first_child)
2470 ret |= propagate_subaccesses_across_link (new_acc, rchild);
2472 continue;
2475 rchild->grp_hint = 1;
2476 new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
2477 if (new_acc)
2479 ret = true;
2480 if (racc->first_child)
2481 propagate_subaccesses_across_link (new_acc, rchild);
2485 return ret;
2488 /* Propagate all subaccesses across assignment links. */
2490 static void
2491 propagate_all_subaccesses (void)
2493 while (work_queue_head)
2495 struct access *racc = pop_access_from_work_queue ();
2496 struct assign_link *link;
2498 gcc_assert (racc->first_link);
2500 for (link = racc->first_link; link; link = link->next)
2502 struct access *lacc = link->lacc;
2504 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
2505 continue;
2506 lacc = lacc->group_representative;
2507 if (propagate_subaccesses_across_link (lacc, racc)
2508 && lacc->first_link)
2509 add_access_to_work_queue (lacc);
2514 /* Go through all accesses collected throughout the (intraprocedural) analysis
2515 stage, exclude overlapping ones, identify representatives and build trees
2516 out of them, making decisions about scalarization on the way. Return true
2517 iff there are any to-be-scalarized variables after this stage. */
2519 static bool
2520 analyze_all_variable_accesses (void)
2522 int res = 0;
2523 bitmap tmp = BITMAP_ALLOC (NULL);
2524 bitmap_iterator bi;
2525 unsigned i, max_total_scalarization_size;
2527 max_total_scalarization_size = UNITS_PER_WORD * BITS_PER_UNIT
2528 * MOVE_RATIO (optimize_function_for_speed_p (cfun));
2530 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
2531 if (bitmap_bit_p (should_scalarize_away_bitmap, i)
2532 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
2534 tree var = candidate (i);
2536 if (TREE_CODE (var) == VAR_DECL
2537 && type_consists_of_records_p (TREE_TYPE (var)))
2539 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var)))
2540 <= max_total_scalarization_size)
2542 completely_scalarize_var (var);
2543 if (dump_file && (dump_flags & TDF_DETAILS))
2545 fprintf (dump_file, "Will attempt to totally scalarize ");
2546 print_generic_expr (dump_file, var, 0);
2547 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2550 else if (dump_file && (dump_flags & TDF_DETAILS))
2552 fprintf (dump_file, "Too big to totally scalarize: ");
2553 print_generic_expr (dump_file, var, 0);
2554 fprintf (dump_file, " (UID: %u)\n", DECL_UID (var));
2559 bitmap_copy (tmp, candidate_bitmap);
2560 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2562 tree var = candidate (i);
2563 struct access *access;
2565 access = sort_and_splice_var_accesses (var);
2566 if (!access || !build_access_trees (access))
2567 disqualify_candidate (var,
2568 "No or inhibitingly overlapping accesses.");
2571 propagate_all_subaccesses ();
2573 bitmap_copy (tmp, candidate_bitmap);
2574 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2576 tree var = candidate (i);
2577 struct access *access = get_first_repr_for_decl (var);
2579 if (analyze_access_trees (access))
2581 res++;
2582 if (dump_file && (dump_flags & TDF_DETAILS))
2584 fprintf (dump_file, "\nAccess trees for ");
2585 print_generic_expr (dump_file, var, 0);
2586 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2587 dump_access_tree (dump_file, access);
2588 fprintf (dump_file, "\n");
2591 else
2592 disqualify_candidate (var, "No scalar replacements to be created.");
2595 BITMAP_FREE (tmp);
2597 if (res)
2599 statistics_counter_event (cfun, "Scalarized aggregates", res);
2600 return true;
2602 else
2603 return false;
2606 /* Generate statements copying scalar replacements of accesses within a subtree
2607 into or out of AGG. ACCESS, all its children, siblings and their children
2608 are to be processed. AGG is an aggregate type expression (can be a
2609 declaration but does not have to be, it can for example also be a mem_ref or
2610 a series of handled components). TOP_OFFSET is the offset of the processed
2611 subtree which has to be subtracted from offsets of individual accesses to
2612 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2613 replacements in the interval <start_offset, start_offset + chunk_size>,
2614 otherwise copy all. GSI is a statement iterator used to place the new
2615 statements. WRITE should be true when the statements should write from AGG
2616 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2617 statements will be added after the current statement in GSI, they will be
2618 added before the statement otherwise. */
2620 static void
2621 generate_subtree_copies (struct access *access, tree agg,
2622 HOST_WIDE_INT top_offset,
2623 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
2624 gimple_stmt_iterator *gsi, bool write,
2625 bool insert_after, location_t loc)
2629 if (chunk_size && access->offset >= start_offset + chunk_size)
2630 return;
2632 if (access->grp_to_be_replaced
2633 && (chunk_size == 0
2634 || access->offset + access->size > start_offset))
2636 tree expr, repl = get_access_replacement (access);
2637 gimple stmt;
2639 expr = build_ref_for_model (loc, agg, access->offset - top_offset,
2640 access, gsi, insert_after);
2642 if (write)
2644 if (access->grp_partial_lhs)
2645 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
2646 !insert_after,
2647 insert_after ? GSI_NEW_STMT
2648 : GSI_SAME_STMT);
2649 stmt = gimple_build_assign (repl, expr);
2651 else
2653 TREE_NO_WARNING (repl) = 1;
2654 if (access->grp_partial_lhs)
2655 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2656 !insert_after,
2657 insert_after ? GSI_NEW_STMT
2658 : GSI_SAME_STMT);
2659 stmt = gimple_build_assign (expr, repl);
2661 gimple_set_location (stmt, loc);
2663 if (insert_after)
2664 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2665 else
2666 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2667 update_stmt (stmt);
2668 sra_stats.subtree_copies++;
2670 else if (write
2671 && access->grp_to_be_debug_replaced
2672 && (chunk_size == 0
2673 || access->offset + access->size > start_offset))
2675 gimple ds;
2676 tree drhs = build_debug_ref_for_model (loc, agg,
2677 access->offset - top_offset,
2678 access);
2679 ds = gimple_build_debug_bind (get_access_replacement (access),
2680 drhs, gsi_stmt (*gsi));
2681 if (insert_after)
2682 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2683 else
2684 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2687 if (access->first_child)
2688 generate_subtree_copies (access->first_child, agg, top_offset,
2689 start_offset, chunk_size, gsi,
2690 write, insert_after, loc);
2692 access = access->next_sibling;
2694 while (access);
2697 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2698 the root of the subtree to be processed. GSI is the statement iterator used
2699 for inserting statements which are added after the current statement if
2700 INSERT_AFTER is true or before it otherwise. */
2702 static void
2703 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
2704 bool insert_after, location_t loc)
2707 struct access *child;
2709 if (access->grp_to_be_replaced)
2711 gimple stmt;
2713 stmt = gimple_build_assign (get_access_replacement (access),
2714 build_zero_cst (access->type));
2715 if (insert_after)
2716 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2717 else
2718 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2719 update_stmt (stmt);
2720 gimple_set_location (stmt, loc);
2722 else if (access->grp_to_be_debug_replaced)
2724 gimple ds = gimple_build_debug_bind (get_access_replacement (access),
2725 build_zero_cst (access->type),
2726 gsi_stmt (*gsi));
2727 if (insert_after)
2728 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2729 else
2730 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2733 for (child = access->first_child; child; child = child->next_sibling)
2734 init_subtree_with_zero (child, gsi, insert_after, loc);
2737 /* Search for an access representative for the given expression EXPR and
2738 return it or NULL if it cannot be found. */
2740 static struct access *
2741 get_access_for_expr (tree expr)
2743 HOST_WIDE_INT offset, size, max_size;
2744 tree base;
2746 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2747 a different size than the size of its argument and we need the latter
2748 one. */
2749 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
2750 expr = TREE_OPERAND (expr, 0);
2752 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
2753 if (max_size == -1 || !DECL_P (base))
2754 return NULL;
2756 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
2757 return NULL;
2759 return get_var_base_offset_size_access (base, offset, max_size);
2762 /* Replace the expression EXPR with a scalar replacement if there is one and
2763 generate other statements to do type conversion or subtree copying if
2764 necessary. GSI is used to place newly created statements, WRITE is true if
2765 the expression is being written to (it is on a LHS of a statement or output
2766 in an assembly statement). */
2768 static bool
2769 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
2771 location_t loc;
2772 struct access *access;
2773 tree type, bfr, orig_expr;
2775 if (TREE_CODE (*expr) == BIT_FIELD_REF)
2777 bfr = *expr;
2778 expr = &TREE_OPERAND (*expr, 0);
2780 else
2781 bfr = NULL_TREE;
2783 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
2784 expr = &TREE_OPERAND (*expr, 0);
2785 access = get_access_for_expr (*expr);
2786 if (!access)
2787 return false;
2788 type = TREE_TYPE (*expr);
2789 orig_expr = *expr;
2791 loc = gimple_location (gsi_stmt (*gsi));
2792 gimple_stmt_iterator alt_gsi = gsi_none ();
2793 if (write && stmt_ends_bb_p (gsi_stmt (*gsi)))
2795 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
2796 gsi = &alt_gsi;
2799 if (access->grp_to_be_replaced)
2801 tree repl = get_access_replacement (access);
2802 /* If we replace a non-register typed access simply use the original
2803 access expression to extract the scalar component afterwards.
2804 This happens if scalarizing a function return value or parameter
2805 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2806 gcc.c-torture/compile/20011217-1.c.
2808 We also want to use this when accessing a complex or vector which can
2809 be accessed as a different type too, potentially creating a need for
2810 type conversion (see PR42196) and when scalarized unions are involved
2811 in assembler statements (see PR42398). */
2812 if (!useless_type_conversion_p (type, access->type))
2814 tree ref;
2816 ref = build_ref_for_model (loc, orig_expr, 0, access, gsi, false);
2818 if (write)
2820 gimple stmt;
2822 if (access->grp_partial_lhs)
2823 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
2824 false, GSI_NEW_STMT);
2825 stmt = gimple_build_assign (repl, ref);
2826 gimple_set_location (stmt, loc);
2827 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2829 else
2831 gimple stmt;
2833 if (access->grp_partial_lhs)
2834 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2835 true, GSI_SAME_STMT);
2836 stmt = gimple_build_assign (ref, repl);
2837 gimple_set_location (stmt, loc);
2838 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2841 else
2842 *expr = repl;
2843 sra_stats.exprs++;
2845 else if (write && access->grp_to_be_debug_replaced)
2847 gimple ds = gimple_build_debug_bind (get_access_replacement (access),
2848 NULL_TREE,
2849 gsi_stmt (*gsi));
2850 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2853 if (access->first_child)
2855 HOST_WIDE_INT start_offset, chunk_size;
2856 if (bfr
2857 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 1))
2858 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 2)))
2860 chunk_size = tree_to_uhwi (TREE_OPERAND (bfr, 1));
2861 start_offset = access->offset
2862 + tree_to_uhwi (TREE_OPERAND (bfr, 2));
2864 else
2865 start_offset = chunk_size = 0;
2867 generate_subtree_copies (access->first_child, orig_expr, access->offset,
2868 start_offset, chunk_size, gsi, write, write,
2869 loc);
2871 return true;
2874 /* Where scalar replacements of the RHS have been written to when a replacement
2875 of a LHS of an assigments cannot be direclty loaded from a replacement of
2876 the RHS. */
2877 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
2878 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
2879 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
2881 struct subreplacement_assignment_data
2883 /* Offset of the access representing the lhs of the assignment. */
2884 HOST_WIDE_INT left_offset;
2886 /* LHS and RHS of the original assignment. */
2887 tree assignment_lhs, assignment_rhs;
2889 /* Access representing the rhs of the whole assignment. */
2890 struct access *top_racc;
2892 /* Stmt iterator used for statement insertions after the original assignment.
2893 It points to the main GSI used to traverse a BB during function body
2894 modification. */
2895 gimple_stmt_iterator *new_gsi;
2897 /* Stmt iterator used for statement insertions before the original
2898 assignment. Keeps on pointing to the original statement. */
2899 gimple_stmt_iterator old_gsi;
2901 /* Location of the assignment. */
2902 location_t loc;
2904 /* Keeps the information whether we have needed to refresh replacements of
2905 the LHS and from which side of the assignments this takes place. */
2906 enum unscalarized_data_handling refreshed;
2909 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2910 base aggregate if there are unscalarized data or directly to LHS of the
2911 statement that is pointed to by GSI otherwise. */
2913 static void
2914 handle_unscalarized_data_in_subtree (struct subreplacement_assignment_data *sad)
2916 tree src;
2917 if (sad->top_racc->grp_unscalarized_data)
2919 src = sad->assignment_rhs;
2920 sad->refreshed = SRA_UDH_RIGHT;
2922 else
2924 src = sad->assignment_lhs;
2925 sad->refreshed = SRA_UDH_LEFT;
2927 generate_subtree_copies (sad->top_racc->first_child, src,
2928 sad->top_racc->offset, 0, 0,
2929 &sad->old_gsi, false, false, sad->loc);
2932 /* Try to generate statements to load all sub-replacements in an access subtree
2933 formed by children of LACC from scalar replacements in the SAD->top_racc
2934 subtree. If that is not possible, refresh the SAD->top_racc base aggregate
2935 and load the accesses from it. */
2937 static void
2938 load_assign_lhs_subreplacements (struct access *lacc,
2939 struct subreplacement_assignment_data *sad)
2941 for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling)
2943 HOST_WIDE_INT offset;
2944 offset = lacc->offset - sad->left_offset + sad->top_racc->offset;
2946 if (lacc->grp_to_be_replaced)
2948 struct access *racc;
2949 gimple stmt;
2950 tree rhs;
2952 racc = find_access_in_subtree (sad->top_racc, offset, lacc->size);
2953 if (racc && racc->grp_to_be_replaced)
2955 rhs = get_access_replacement (racc);
2956 if (!useless_type_conversion_p (lacc->type, racc->type))
2957 rhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
2958 lacc->type, rhs);
2960 if (racc->grp_partial_lhs && lacc->grp_partial_lhs)
2961 rhs = force_gimple_operand_gsi (&sad->old_gsi, rhs, true,
2962 NULL_TREE, true, GSI_SAME_STMT);
2964 else
2966 /* No suitable access on the right hand side, need to load from
2967 the aggregate. See if we have to update it first... */
2968 if (sad->refreshed == SRA_UDH_NONE)
2969 handle_unscalarized_data_in_subtree (sad);
2971 if (sad->refreshed == SRA_UDH_LEFT)
2972 rhs = build_ref_for_model (sad->loc, sad->assignment_lhs,
2973 lacc->offset - sad->left_offset,
2974 lacc, sad->new_gsi, true);
2975 else
2976 rhs = build_ref_for_model (sad->loc, sad->assignment_rhs,
2977 lacc->offset - sad->left_offset,
2978 lacc, sad->new_gsi, true);
2979 if (lacc->grp_partial_lhs)
2980 rhs = force_gimple_operand_gsi (sad->new_gsi,
2981 rhs, true, NULL_TREE,
2982 false, GSI_NEW_STMT);
2985 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
2986 gsi_insert_after (sad->new_gsi, stmt, GSI_NEW_STMT);
2987 gimple_set_location (stmt, sad->loc);
2988 update_stmt (stmt);
2989 sra_stats.subreplacements++;
2991 else
2993 if (sad->refreshed == SRA_UDH_NONE
2994 && lacc->grp_read && !lacc->grp_covered)
2995 handle_unscalarized_data_in_subtree (sad);
2997 if (lacc && lacc->grp_to_be_debug_replaced)
2999 gimple ds;
3000 tree drhs;
3001 struct access *racc = find_access_in_subtree (sad->top_racc,
3002 offset,
3003 lacc->size);
3005 if (racc && racc->grp_to_be_replaced)
3007 if (racc->grp_write)
3008 drhs = get_access_replacement (racc);
3009 else
3010 drhs = NULL;
3012 else if (sad->refreshed == SRA_UDH_LEFT)
3013 drhs = build_debug_ref_for_model (sad->loc, lacc->base,
3014 lacc->offset, lacc);
3015 else if (sad->refreshed == SRA_UDH_RIGHT)
3016 drhs = build_debug_ref_for_model (sad->loc, sad->top_racc->base,
3017 offset, lacc);
3018 else
3019 drhs = NULL_TREE;
3020 if (drhs
3021 && !useless_type_conversion_p (lacc->type, TREE_TYPE (drhs)))
3022 drhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
3023 lacc->type, drhs);
3024 ds = gimple_build_debug_bind (get_access_replacement (lacc),
3025 drhs, gsi_stmt (sad->old_gsi));
3026 gsi_insert_after (sad->new_gsi, ds, GSI_NEW_STMT);
3030 if (lacc->first_child)
3031 load_assign_lhs_subreplacements (lacc, sad);
3035 /* Result code for SRA assignment modification. */
3036 enum assignment_mod_result { SRA_AM_NONE, /* nothing done for the stmt */
3037 SRA_AM_MODIFIED, /* stmt changed but not
3038 removed */
3039 SRA_AM_REMOVED }; /* stmt eliminated */
3041 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
3042 to the assignment and GSI is the statement iterator pointing at it. Returns
3043 the same values as sra_modify_assign. */
3045 static enum assignment_mod_result
3046 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3048 tree lhs = gimple_assign_lhs (*stmt);
3049 struct access *acc;
3050 location_t loc;
3052 acc = get_access_for_expr (lhs);
3053 if (!acc)
3054 return SRA_AM_NONE;
3056 if (gimple_clobber_p (*stmt))
3058 /* Remove clobbers of fully scalarized variables, otherwise
3059 do nothing. */
3060 if (acc->grp_covered)
3062 unlink_stmt_vdef (*stmt);
3063 gsi_remove (gsi, true);
3064 release_defs (*stmt);
3065 return SRA_AM_REMOVED;
3067 else
3068 return SRA_AM_NONE;
3071 loc = gimple_location (*stmt);
3072 if (vec_safe_length (CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt))) > 0)
3074 /* I have never seen this code path trigger but if it can happen the
3075 following should handle it gracefully. */
3076 if (access_has_children_p (acc))
3077 generate_subtree_copies (acc->first_child, lhs, acc->offset, 0, 0, gsi,
3078 true, true, loc);
3079 return SRA_AM_MODIFIED;
3082 if (acc->grp_covered)
3084 init_subtree_with_zero (acc, gsi, false, loc);
3085 unlink_stmt_vdef (*stmt);
3086 gsi_remove (gsi, true);
3087 release_defs (*stmt);
3088 return SRA_AM_REMOVED;
3090 else
3092 init_subtree_with_zero (acc, gsi, true, loc);
3093 return SRA_AM_MODIFIED;
3097 /* Create and return a new suitable default definition SSA_NAME for RACC which
3098 is an access describing an uninitialized part of an aggregate that is being
3099 loaded. */
3101 static tree
3102 get_repl_default_def_ssa_name (struct access *racc)
3104 gcc_checking_assert (!racc->grp_to_be_replaced
3105 && !racc->grp_to_be_debug_replaced);
3106 if (!racc->replacement_decl)
3107 racc->replacement_decl = create_access_replacement (racc);
3108 return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
3111 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3112 bit-field field declaration somewhere in it. */
3114 static inline bool
3115 contains_vce_or_bfcref_p (const_tree ref)
3117 while (handled_component_p (ref))
3119 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
3120 || (TREE_CODE (ref) == COMPONENT_REF
3121 && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
3122 return true;
3123 ref = TREE_OPERAND (ref, 0);
3126 return false;
3129 /* Examine both sides of the assignment statement pointed to by STMT, replace
3130 them with a scalare replacement if there is one and generate copying of
3131 replacements if scalarized aggregates have been used in the assignment. GSI
3132 is used to hold generated statements for type conversions and subtree
3133 copying. */
3135 static enum assignment_mod_result
3136 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3138 struct access *lacc, *racc;
3139 tree lhs, rhs;
3140 bool modify_this_stmt = false;
3141 bool force_gimple_rhs = false;
3142 location_t loc;
3143 gimple_stmt_iterator orig_gsi = *gsi;
3145 if (!gimple_assign_single_p (*stmt))
3146 return SRA_AM_NONE;
3147 lhs = gimple_assign_lhs (*stmt);
3148 rhs = gimple_assign_rhs1 (*stmt);
3150 if (TREE_CODE (rhs) == CONSTRUCTOR)
3151 return sra_modify_constructor_assign (stmt, gsi);
3153 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
3154 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
3155 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
3157 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (*stmt),
3158 gsi, false);
3159 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (*stmt),
3160 gsi, true);
3161 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3164 lacc = get_access_for_expr (lhs);
3165 racc = get_access_for_expr (rhs);
3166 if (!lacc && !racc)
3167 return SRA_AM_NONE;
3169 loc = gimple_location (*stmt);
3170 if (lacc && lacc->grp_to_be_replaced)
3172 lhs = get_access_replacement (lacc);
3173 gimple_assign_set_lhs (*stmt, lhs);
3174 modify_this_stmt = true;
3175 if (lacc->grp_partial_lhs)
3176 force_gimple_rhs = true;
3177 sra_stats.exprs++;
3180 if (racc && racc->grp_to_be_replaced)
3182 rhs = get_access_replacement (racc);
3183 modify_this_stmt = true;
3184 if (racc->grp_partial_lhs)
3185 force_gimple_rhs = true;
3186 sra_stats.exprs++;
3188 else if (racc
3189 && !racc->grp_unscalarized_data
3190 && TREE_CODE (lhs) == SSA_NAME
3191 && !access_has_replacements_p (racc))
3193 rhs = get_repl_default_def_ssa_name (racc);
3194 modify_this_stmt = true;
3195 sra_stats.exprs++;
3198 if (modify_this_stmt)
3200 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3202 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3203 ??? This should move to fold_stmt which we simply should
3204 call after building a VIEW_CONVERT_EXPR here. */
3205 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
3206 && !contains_bitfld_component_ref_p (lhs))
3208 lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
3209 gimple_assign_set_lhs (*stmt, lhs);
3211 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
3212 && !contains_vce_or_bfcref_p (rhs))
3213 rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
3215 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3217 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
3218 rhs);
3219 if (is_gimple_reg_type (TREE_TYPE (lhs))
3220 && TREE_CODE (lhs) != SSA_NAME)
3221 force_gimple_rhs = true;
3226 if (lacc && lacc->grp_to_be_debug_replaced)
3228 tree dlhs = get_access_replacement (lacc);
3229 tree drhs = unshare_expr (rhs);
3230 if (!useless_type_conversion_p (TREE_TYPE (dlhs), TREE_TYPE (drhs)))
3232 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs))
3233 && !contains_vce_or_bfcref_p (drhs))
3234 drhs = build_debug_ref_for_model (loc, drhs, 0, lacc);
3235 if (drhs
3236 && !useless_type_conversion_p (TREE_TYPE (dlhs),
3237 TREE_TYPE (drhs)))
3238 drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
3239 TREE_TYPE (dlhs), drhs);
3241 gimple ds = gimple_build_debug_bind (dlhs, drhs, *stmt);
3242 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3245 /* From this point on, the function deals with assignments in between
3246 aggregates when at least one has scalar reductions of some of its
3247 components. There are three possible scenarios: Both the LHS and RHS have
3248 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3250 In the first case, we would like to load the LHS components from RHS
3251 components whenever possible. If that is not possible, we would like to
3252 read it directly from the RHS (after updating it by storing in it its own
3253 components). If there are some necessary unscalarized data in the LHS,
3254 those will be loaded by the original assignment too. If neither of these
3255 cases happen, the original statement can be removed. Most of this is done
3256 by load_assign_lhs_subreplacements.
3258 In the second case, we would like to store all RHS scalarized components
3259 directly into LHS and if they cover the aggregate completely, remove the
3260 statement too. In the third case, we want the LHS components to be loaded
3261 directly from the RHS (DSE will remove the original statement if it
3262 becomes redundant).
3264 This is a bit complex but manageable when types match and when unions do
3265 not cause confusion in a way that we cannot really load a component of LHS
3266 from the RHS or vice versa (the access representing this level can have
3267 subaccesses that are accessible only through a different union field at a
3268 higher level - different from the one used in the examined expression).
3269 Unions are fun.
3271 Therefore, I specially handle a fourth case, happening when there is a
3272 specific type cast or it is impossible to locate a scalarized subaccess on
3273 the other side of the expression. If that happens, I simply "refresh" the
3274 RHS by storing in it is scalarized components leave the original statement
3275 there to do the copying and then load the scalar replacements of the LHS.
3276 This is what the first branch does. */
3278 if (modify_this_stmt
3279 || gimple_has_volatile_ops (*stmt)
3280 || contains_vce_or_bfcref_p (rhs)
3281 || contains_vce_or_bfcref_p (lhs)
3282 || stmt_ends_bb_p (*stmt))
3284 if (access_has_children_p (racc))
3285 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3286 gsi, false, false, loc);
3287 if (access_has_children_p (lacc))
3289 gimple_stmt_iterator alt_gsi = gsi_none ();
3290 if (stmt_ends_bb_p (*stmt))
3292 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
3293 gsi = &alt_gsi;
3295 generate_subtree_copies (lacc->first_child, lhs, lacc->offset, 0, 0,
3296 gsi, true, true, loc);
3298 sra_stats.separate_lhs_rhs_handling++;
3300 /* This gimplification must be done after generate_subtree_copies,
3301 lest we insert the subtree copies in the middle of the gimplified
3302 sequence. */
3303 if (force_gimple_rhs)
3304 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
3305 true, GSI_SAME_STMT);
3306 if (gimple_assign_rhs1 (*stmt) != rhs)
3308 modify_this_stmt = true;
3309 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
3310 gcc_assert (*stmt == gsi_stmt (orig_gsi));
3313 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3315 else
3317 if (access_has_children_p (lacc)
3318 && access_has_children_p (racc)
3319 /* When an access represents an unscalarizable region, it usually
3320 represents accesses with variable offset and thus must not be used
3321 to generate new memory accesses. */
3322 && !lacc->grp_unscalarizable_region
3323 && !racc->grp_unscalarizable_region)
3325 struct subreplacement_assignment_data sad;
3327 sad.left_offset = lacc->offset;
3328 sad.assignment_lhs = lhs;
3329 sad.assignment_rhs = rhs;
3330 sad.top_racc = racc;
3331 sad.old_gsi = *gsi;
3332 sad.new_gsi = gsi;
3333 sad.loc = gimple_location (*stmt);
3334 sad.refreshed = SRA_UDH_NONE;
3336 if (lacc->grp_read && !lacc->grp_covered)
3337 handle_unscalarized_data_in_subtree (&sad);
3339 load_assign_lhs_subreplacements (lacc, &sad);
3340 if (sad.refreshed != SRA_UDH_RIGHT)
3342 gsi_next (gsi);
3343 unlink_stmt_vdef (*stmt);
3344 gsi_remove (&sad.old_gsi, true);
3345 release_defs (*stmt);
3346 sra_stats.deleted++;
3347 return SRA_AM_REMOVED;
3350 else
3352 if (access_has_children_p (racc)
3353 && !racc->grp_unscalarized_data)
3355 if (dump_file)
3357 fprintf (dump_file, "Removing load: ");
3358 print_gimple_stmt (dump_file, *stmt, 0, 0);
3360 generate_subtree_copies (racc->first_child, lhs,
3361 racc->offset, 0, 0, gsi,
3362 false, false, loc);
3363 gcc_assert (*stmt == gsi_stmt (*gsi));
3364 unlink_stmt_vdef (*stmt);
3365 gsi_remove (gsi, true);
3366 release_defs (*stmt);
3367 sra_stats.deleted++;
3368 return SRA_AM_REMOVED;
3370 /* Restore the aggregate RHS from its components so the
3371 prevailing aggregate copy does the right thing. */
3372 if (access_has_children_p (racc))
3373 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3374 gsi, false, false, loc);
3375 /* Re-load the components of the aggregate copy destination.
3376 But use the RHS aggregate to load from to expose more
3377 optimization opportunities. */
3378 if (access_has_children_p (lacc))
3379 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
3380 0, 0, gsi, true, true, loc);
3383 return SRA_AM_NONE;
3387 /* Traverse the function body and all modifications as decided in
3388 analyze_all_variable_accesses. Return true iff the CFG has been
3389 changed. */
3391 static bool
3392 sra_modify_function_body (void)
3394 bool cfg_changed = false;
3395 basic_block bb;
3397 FOR_EACH_BB_FN (bb, cfun)
3399 gimple_stmt_iterator gsi = gsi_start_bb (bb);
3400 while (!gsi_end_p (gsi))
3402 gimple stmt = gsi_stmt (gsi);
3403 enum assignment_mod_result assign_result;
3404 bool modified = false, deleted = false;
3405 tree *t;
3406 unsigned i;
3408 switch (gimple_code (stmt))
3410 case GIMPLE_RETURN:
3411 t = gimple_return_retval_ptr (stmt);
3412 if (*t != NULL_TREE)
3413 modified |= sra_modify_expr (t, &gsi, false);
3414 break;
3416 case GIMPLE_ASSIGN:
3417 assign_result = sra_modify_assign (&stmt, &gsi);
3418 modified |= assign_result == SRA_AM_MODIFIED;
3419 deleted = assign_result == SRA_AM_REMOVED;
3420 break;
3422 case GIMPLE_CALL:
3423 /* Operands must be processed before the lhs. */
3424 for (i = 0; i < gimple_call_num_args (stmt); i++)
3426 t = gimple_call_arg_ptr (stmt, i);
3427 modified |= sra_modify_expr (t, &gsi, false);
3430 if (gimple_call_lhs (stmt))
3432 t = gimple_call_lhs_ptr (stmt);
3433 modified |= sra_modify_expr (t, &gsi, true);
3435 break;
3437 case GIMPLE_ASM:
3438 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
3440 t = &TREE_VALUE (gimple_asm_input_op (stmt, i));
3441 modified |= sra_modify_expr (t, &gsi, false);
3443 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
3445 t = &TREE_VALUE (gimple_asm_output_op (stmt, i));
3446 modified |= sra_modify_expr (t, &gsi, true);
3448 break;
3450 default:
3451 break;
3454 if (modified)
3456 update_stmt (stmt);
3457 if (maybe_clean_eh_stmt (stmt)
3458 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
3459 cfg_changed = true;
3461 if (!deleted)
3462 gsi_next (&gsi);
3466 gsi_commit_edge_inserts ();
3467 return cfg_changed;
3470 /* Generate statements initializing scalar replacements of parts of function
3471 parameters. */
3473 static void
3474 initialize_parameter_reductions (void)
3476 gimple_stmt_iterator gsi;
3477 gimple_seq seq = NULL;
3478 tree parm;
3480 gsi = gsi_start (seq);
3481 for (parm = DECL_ARGUMENTS (current_function_decl);
3482 parm;
3483 parm = DECL_CHAIN (parm))
3485 vec<access_p> *access_vec;
3486 struct access *access;
3488 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3489 continue;
3490 access_vec = get_base_access_vector (parm);
3491 if (!access_vec)
3492 continue;
3494 for (access = (*access_vec)[0];
3495 access;
3496 access = access->next_grp)
3497 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true,
3498 EXPR_LOCATION (parm));
3501 seq = gsi_seq (gsi);
3502 if (seq)
3503 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3506 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3507 it reveals there are components of some aggregates to be scalarized, it runs
3508 the required transformations. */
3509 static unsigned int
3510 perform_intra_sra (void)
3512 int ret = 0;
3513 sra_initialize ();
3515 if (!find_var_candidates ())
3516 goto out;
3518 if (!scan_function ())
3519 goto out;
3521 if (!analyze_all_variable_accesses ())
3522 goto out;
3524 if (sra_modify_function_body ())
3525 ret = TODO_update_ssa | TODO_cleanup_cfg;
3526 else
3527 ret = TODO_update_ssa;
3528 initialize_parameter_reductions ();
3530 statistics_counter_event (cfun, "Scalar replacements created",
3531 sra_stats.replacements);
3532 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
3533 statistics_counter_event (cfun, "Subtree copy stmts",
3534 sra_stats.subtree_copies);
3535 statistics_counter_event (cfun, "Subreplacement stmts",
3536 sra_stats.subreplacements);
3537 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
3538 statistics_counter_event (cfun, "Separate LHS and RHS handling",
3539 sra_stats.separate_lhs_rhs_handling);
3541 out:
3542 sra_deinitialize ();
3543 return ret;
3546 /* Perform early intraprocedural SRA. */
3547 static unsigned int
3548 early_intra_sra (void)
3550 sra_mode = SRA_MODE_EARLY_INTRA;
3551 return perform_intra_sra ();
3554 /* Perform "late" intraprocedural SRA. */
3555 static unsigned int
3556 late_intra_sra (void)
3558 sra_mode = SRA_MODE_INTRA;
3559 return perform_intra_sra ();
3563 static bool
3564 gate_intra_sra (void)
3566 return flag_tree_sra != 0 && dbg_cnt (tree_sra);
3570 namespace {
3572 const pass_data pass_data_sra_early =
3574 GIMPLE_PASS, /* type */
3575 "esra", /* name */
3576 OPTGROUP_NONE, /* optinfo_flags */
3577 TV_TREE_SRA, /* tv_id */
3578 ( PROP_cfg | PROP_ssa ), /* properties_required */
3579 0, /* properties_provided */
3580 0, /* properties_destroyed */
3581 0, /* todo_flags_start */
3582 TODO_update_ssa, /* todo_flags_finish */
3585 class pass_sra_early : public gimple_opt_pass
3587 public:
3588 pass_sra_early (gcc::context *ctxt)
3589 : gimple_opt_pass (pass_data_sra_early, ctxt)
3592 /* opt_pass methods: */
3593 virtual bool gate (function *) { return gate_intra_sra (); }
3594 virtual unsigned int execute (function *) { return early_intra_sra (); }
3596 }; // class pass_sra_early
3598 } // anon namespace
3600 gimple_opt_pass *
3601 make_pass_sra_early (gcc::context *ctxt)
3603 return new pass_sra_early (ctxt);
3606 namespace {
3608 const pass_data pass_data_sra =
3610 GIMPLE_PASS, /* type */
3611 "sra", /* name */
3612 OPTGROUP_NONE, /* optinfo_flags */
3613 TV_TREE_SRA, /* tv_id */
3614 ( PROP_cfg | PROP_ssa ), /* properties_required */
3615 0, /* properties_provided */
3616 0, /* properties_destroyed */
3617 TODO_update_address_taken, /* todo_flags_start */
3618 TODO_update_ssa, /* todo_flags_finish */
3621 class pass_sra : public gimple_opt_pass
3623 public:
3624 pass_sra (gcc::context *ctxt)
3625 : gimple_opt_pass (pass_data_sra, ctxt)
3628 /* opt_pass methods: */
3629 virtual bool gate (function *) { return gate_intra_sra (); }
3630 virtual unsigned int execute (function *) { return late_intra_sra (); }
3632 }; // class pass_sra
3634 } // anon namespace
3636 gimple_opt_pass *
3637 make_pass_sra (gcc::context *ctxt)
3639 return new pass_sra (ctxt);
3643 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3644 parameter. */
3646 static bool
3647 is_unused_scalar_param (tree parm)
3649 tree name;
3650 return (is_gimple_reg (parm)
3651 && (!(name = ssa_default_def (cfun, parm))
3652 || has_zero_uses (name)));
3655 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3656 examine whether there are any direct or otherwise infeasible ones. If so,
3657 return true, otherwise return false. PARM must be a gimple register with a
3658 non-NULL default definition. */
3660 static bool
3661 ptr_parm_has_direct_uses (tree parm)
3663 imm_use_iterator ui;
3664 gimple stmt;
3665 tree name = ssa_default_def (cfun, parm);
3666 bool ret = false;
3668 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
3670 int uses_ok = 0;
3671 use_operand_p use_p;
3673 if (is_gimple_debug (stmt))
3674 continue;
3676 /* Valid uses include dereferences on the lhs and the rhs. */
3677 if (gimple_has_lhs (stmt))
3679 tree lhs = gimple_get_lhs (stmt);
3680 while (handled_component_p (lhs))
3681 lhs = TREE_OPERAND (lhs, 0);
3682 if (TREE_CODE (lhs) == MEM_REF
3683 && TREE_OPERAND (lhs, 0) == name
3684 && integer_zerop (TREE_OPERAND (lhs, 1))
3685 && types_compatible_p (TREE_TYPE (lhs),
3686 TREE_TYPE (TREE_TYPE (name)))
3687 && !TREE_THIS_VOLATILE (lhs))
3688 uses_ok++;
3690 if (gimple_assign_single_p (stmt))
3692 tree rhs = gimple_assign_rhs1 (stmt);
3693 while (handled_component_p (rhs))
3694 rhs = TREE_OPERAND (rhs, 0);
3695 if (TREE_CODE (rhs) == MEM_REF
3696 && TREE_OPERAND (rhs, 0) == name
3697 && integer_zerop (TREE_OPERAND (rhs, 1))
3698 && types_compatible_p (TREE_TYPE (rhs),
3699 TREE_TYPE (TREE_TYPE (name)))
3700 && !TREE_THIS_VOLATILE (rhs))
3701 uses_ok++;
3703 else if (is_gimple_call (stmt))
3705 unsigned i;
3706 for (i = 0; i < gimple_call_num_args (stmt); ++i)
3708 tree arg = gimple_call_arg (stmt, i);
3709 while (handled_component_p (arg))
3710 arg = TREE_OPERAND (arg, 0);
3711 if (TREE_CODE (arg) == MEM_REF
3712 && TREE_OPERAND (arg, 0) == name
3713 && integer_zerop (TREE_OPERAND (arg, 1))
3714 && types_compatible_p (TREE_TYPE (arg),
3715 TREE_TYPE (TREE_TYPE (name)))
3716 && !TREE_THIS_VOLATILE (arg))
3717 uses_ok++;
3721 /* If the number of valid uses does not match the number of
3722 uses in this stmt there is an unhandled use. */
3723 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
3724 --uses_ok;
3726 if (uses_ok != 0)
3727 ret = true;
3729 if (ret)
3730 BREAK_FROM_IMM_USE_STMT (ui);
3733 return ret;
3736 /* Identify candidates for reduction for IPA-SRA based on their type and mark
3737 them in candidate_bitmap. Note that these do not necessarily include
3738 parameter which are unused and thus can be removed. Return true iff any
3739 such candidate has been found. */
3741 static bool
3742 find_param_candidates (void)
3744 tree parm;
3745 int count = 0;
3746 bool ret = false;
3747 const char *msg;
3749 for (parm = DECL_ARGUMENTS (current_function_decl);
3750 parm;
3751 parm = DECL_CHAIN (parm))
3753 tree type = TREE_TYPE (parm);
3754 tree_node **slot;
3756 count++;
3758 if (TREE_THIS_VOLATILE (parm)
3759 || TREE_ADDRESSABLE (parm)
3760 || (!is_gimple_reg_type (type) && is_va_list_type (type)))
3761 continue;
3763 if (is_unused_scalar_param (parm))
3765 ret = true;
3766 continue;
3769 if (POINTER_TYPE_P (type))
3771 type = TREE_TYPE (type);
3773 if (TREE_CODE (type) == FUNCTION_TYPE
3774 || TYPE_VOLATILE (type)
3775 || (TREE_CODE (type) == ARRAY_TYPE
3776 && TYPE_NONALIASED_COMPONENT (type))
3777 || !is_gimple_reg (parm)
3778 || is_va_list_type (type)
3779 || ptr_parm_has_direct_uses (parm))
3780 continue;
3782 else if (!AGGREGATE_TYPE_P (type))
3783 continue;
3785 if (!COMPLETE_TYPE_P (type)
3786 || !tree_fits_uhwi_p (TYPE_SIZE (type))
3787 || tree_to_uhwi (TYPE_SIZE (type)) == 0
3788 || (AGGREGATE_TYPE_P (type)
3789 && type_internals_preclude_sra_p (type, &msg)))
3790 continue;
3792 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
3793 slot = candidates->find_slot_with_hash (parm, DECL_UID (parm), INSERT);
3794 *slot = parm;
3796 ret = true;
3797 if (dump_file && (dump_flags & TDF_DETAILS))
3799 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
3800 print_generic_expr (dump_file, parm, 0);
3801 fprintf (dump_file, "\n");
3805 func_param_count = count;
3806 return ret;
3809 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
3810 maybe_modified. */
3812 static bool
3813 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
3814 void *data)
3816 struct access *repr = (struct access *) data;
3818 repr->grp_maybe_modified = 1;
3819 return true;
3822 /* Analyze what representatives (in linked lists accessible from
3823 REPRESENTATIVES) can be modified by side effects of statements in the
3824 current function. */
3826 static void
3827 analyze_modified_params (vec<access_p> representatives)
3829 int i;
3831 for (i = 0; i < func_param_count; i++)
3833 struct access *repr;
3835 for (repr = representatives[i];
3836 repr;
3837 repr = repr->next_grp)
3839 struct access *access;
3840 bitmap visited;
3841 ao_ref ar;
3843 if (no_accesses_p (repr))
3844 continue;
3845 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
3846 || repr->grp_maybe_modified)
3847 continue;
3849 ao_ref_init (&ar, repr->expr);
3850 visited = BITMAP_ALLOC (NULL);
3851 for (access = repr; access; access = access->next_sibling)
3853 /* All accesses are read ones, otherwise grp_maybe_modified would
3854 be trivially set. */
3855 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
3856 mark_maybe_modified, repr, &visited);
3857 if (repr->grp_maybe_modified)
3858 break;
3860 BITMAP_FREE (visited);
3865 /* Propagate distances in bb_dereferences in the opposite direction than the
3866 control flow edges, in each step storing the maximum of the current value
3867 and the minimum of all successors. These steps are repeated until the table
3868 stabilizes. Note that BBs which might terminate the functions (according to
3869 final_bbs bitmap) never updated in this way. */
3871 static void
3872 propagate_dereference_distances (void)
3874 basic_block bb;
3876 auto_vec<basic_block> queue (last_basic_block_for_fn (cfun));
3877 queue.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun));
3878 FOR_EACH_BB_FN (bb, cfun)
3880 queue.quick_push (bb);
3881 bb->aux = bb;
3884 while (!queue.is_empty ())
3886 edge_iterator ei;
3887 edge e;
3888 bool change = false;
3889 int i;
3891 bb = queue.pop ();
3892 bb->aux = NULL;
3894 if (bitmap_bit_p (final_bbs, bb->index))
3895 continue;
3897 for (i = 0; i < func_param_count; i++)
3899 int idx = bb->index * func_param_count + i;
3900 bool first = true;
3901 HOST_WIDE_INT inh = 0;
3903 FOR_EACH_EDGE (e, ei, bb->succs)
3905 int succ_idx = e->dest->index * func_param_count + i;
3907 if (e->src == EXIT_BLOCK_PTR_FOR_FN (cfun))
3908 continue;
3910 if (first)
3912 first = false;
3913 inh = bb_dereferences [succ_idx];
3915 else if (bb_dereferences [succ_idx] < inh)
3916 inh = bb_dereferences [succ_idx];
3919 if (!first && bb_dereferences[idx] < inh)
3921 bb_dereferences[idx] = inh;
3922 change = true;
3926 if (change && !bitmap_bit_p (final_bbs, bb->index))
3927 FOR_EACH_EDGE (e, ei, bb->preds)
3929 if (e->src->aux)
3930 continue;
3932 e->src->aux = e->src;
3933 queue.quick_push (e->src);
3938 /* Dump a dereferences TABLE with heading STR to file F. */
3940 static void
3941 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
3943 basic_block bb;
3945 fprintf (dump_file, str);
3946 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
3947 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
3949 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
3950 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
3952 int i;
3953 for (i = 0; i < func_param_count; i++)
3955 int idx = bb->index * func_param_count + i;
3956 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
3959 fprintf (f, "\n");
3961 fprintf (dump_file, "\n");
3964 /* Determine what (parts of) parameters passed by reference that are not
3965 assigned to are not certainly dereferenced in this function and thus the
3966 dereferencing cannot be safely moved to the caller without potentially
3967 introducing a segfault. Mark such REPRESENTATIVES as
3968 grp_not_necessarilly_dereferenced.
3970 The dereferenced maximum "distance," i.e. the offset + size of the accessed
3971 part is calculated rather than simple booleans are calculated for each
3972 pointer parameter to handle cases when only a fraction of the whole
3973 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
3974 an example).
3976 The maximum dereference distances for each pointer parameter and BB are
3977 already stored in bb_dereference. This routine simply propagates these
3978 values upwards by propagate_dereference_distances and then compares the
3979 distances of individual parameters in the ENTRY BB to the equivalent
3980 distances of each representative of a (fraction of a) parameter. */
3982 static void
3983 analyze_caller_dereference_legality (vec<access_p> representatives)
3985 int i;
3987 if (dump_file && (dump_flags & TDF_DETAILS))
3988 dump_dereferences_table (dump_file,
3989 "Dereference table before propagation:\n",
3990 bb_dereferences);
3992 propagate_dereference_distances ();
3994 if (dump_file && (dump_flags & TDF_DETAILS))
3995 dump_dereferences_table (dump_file,
3996 "Dereference table after propagation:\n",
3997 bb_dereferences);
3999 for (i = 0; i < func_param_count; i++)
4001 struct access *repr = representatives[i];
4002 int idx = ENTRY_BLOCK_PTR_FOR_FN (cfun)->index * func_param_count + i;
4004 if (!repr || no_accesses_p (repr))
4005 continue;
4009 if ((repr->offset + repr->size) > bb_dereferences[idx])
4010 repr->grp_not_necessarilly_dereferenced = 1;
4011 repr = repr->next_grp;
4013 while (repr);
4017 /* Return the representative access for the parameter declaration PARM if it is
4018 a scalar passed by reference which is not written to and the pointer value
4019 is not used directly. Thus, if it is legal to dereference it in the caller
4020 and we can rule out modifications through aliases, such parameter should be
4021 turned into one passed by value. Return NULL otherwise. */
4023 static struct access *
4024 unmodified_by_ref_scalar_representative (tree parm)
4026 int i, access_count;
4027 struct access *repr;
4028 vec<access_p> *access_vec;
4030 access_vec = get_base_access_vector (parm);
4031 gcc_assert (access_vec);
4032 repr = (*access_vec)[0];
4033 if (repr->write)
4034 return NULL;
4035 repr->group_representative = repr;
4037 access_count = access_vec->length ();
4038 for (i = 1; i < access_count; i++)
4040 struct access *access = (*access_vec)[i];
4041 if (access->write)
4042 return NULL;
4043 access->group_representative = repr;
4044 access->next_sibling = repr->next_sibling;
4045 repr->next_sibling = access;
4048 repr->grp_read = 1;
4049 repr->grp_scalar_ptr = 1;
4050 return repr;
4053 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
4054 associated with. REQ_ALIGN is the minimum required alignment. */
4056 static bool
4057 access_precludes_ipa_sra_p (struct access *access, unsigned int req_align)
4059 unsigned int exp_align;
4060 /* Avoid issues such as the second simple testcase in PR 42025. The problem
4061 is incompatible assign in a call statement (and possibly even in asm
4062 statements). This can be relaxed by using a new temporary but only for
4063 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
4064 intraprocedural SRA we deal with this by keeping the old aggregate around,
4065 something we cannot do in IPA-SRA.) */
4066 if (access->write
4067 && (is_gimple_call (access->stmt)
4068 || gimple_code (access->stmt) == GIMPLE_ASM))
4069 return true;
4071 exp_align = get_object_alignment (access->expr);
4072 if (exp_align < req_align)
4073 return true;
4075 return false;
4079 /* Sort collected accesses for parameter PARM, identify representatives for
4080 each accessed region and link them together. Return NULL if there are
4081 different but overlapping accesses, return the special ptr value meaning
4082 there are no accesses for this parameter if that is the case and return the
4083 first representative otherwise. Set *RO_GRP if there is a group of accesses
4084 with only read (i.e. no write) accesses. */
4086 static struct access *
4087 splice_param_accesses (tree parm, bool *ro_grp)
4089 int i, j, access_count, group_count;
4090 int agg_size, total_size = 0;
4091 struct access *access, *res, **prev_acc_ptr = &res;
4092 vec<access_p> *access_vec;
4094 access_vec = get_base_access_vector (parm);
4095 if (!access_vec)
4096 return &no_accesses_representant;
4097 access_count = access_vec->length ();
4099 access_vec->qsort (compare_access_positions);
4101 i = 0;
4102 total_size = 0;
4103 group_count = 0;
4104 while (i < access_count)
4106 bool modification;
4107 tree a1_alias_type;
4108 access = (*access_vec)[i];
4109 modification = access->write;
4110 if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type)))
4111 return NULL;
4112 a1_alias_type = reference_alias_ptr_type (access->expr);
4114 /* Access is about to become group representative unless we find some
4115 nasty overlap which would preclude us from breaking this parameter
4116 apart. */
4118 j = i + 1;
4119 while (j < access_count)
4121 struct access *ac2 = (*access_vec)[j];
4122 if (ac2->offset != access->offset)
4124 /* All or nothing law for parameters. */
4125 if (access->offset + access->size > ac2->offset)
4126 return NULL;
4127 else
4128 break;
4130 else if (ac2->size != access->size)
4131 return NULL;
4133 if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type))
4134 || (ac2->type != access->type
4135 && (TREE_ADDRESSABLE (ac2->type)
4136 || TREE_ADDRESSABLE (access->type)))
4137 || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
4138 return NULL;
4140 modification |= ac2->write;
4141 ac2->group_representative = access;
4142 ac2->next_sibling = access->next_sibling;
4143 access->next_sibling = ac2;
4144 j++;
4147 group_count++;
4148 access->grp_maybe_modified = modification;
4149 if (!modification)
4150 *ro_grp = true;
4151 *prev_acc_ptr = access;
4152 prev_acc_ptr = &access->next_grp;
4153 total_size += access->size;
4154 i = j;
4157 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4158 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4159 else
4160 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4161 if (total_size >= agg_size)
4162 return NULL;
4164 gcc_assert (group_count > 0);
4165 return res;
4168 /* Decide whether parameters with representative accesses given by REPR should
4169 be reduced into components. */
4171 static int
4172 decide_one_param_reduction (struct access *repr)
4174 int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
4175 bool by_ref;
4176 tree parm;
4178 parm = repr->base;
4179 cur_parm_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4180 gcc_assert (cur_parm_size > 0);
4182 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4184 by_ref = true;
4185 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4187 else
4189 by_ref = false;
4190 agg_size = cur_parm_size;
4193 if (dump_file)
4195 struct access *acc;
4196 fprintf (dump_file, "Evaluating PARAM group sizes for ");
4197 print_generic_expr (dump_file, parm, 0);
4198 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
4199 for (acc = repr; acc; acc = acc->next_grp)
4200 dump_access (dump_file, acc, true);
4203 total_size = 0;
4204 new_param_count = 0;
4206 for (; repr; repr = repr->next_grp)
4208 gcc_assert (parm == repr->base);
4210 /* Taking the address of a non-addressable field is verboten. */
4211 if (by_ref && repr->non_addressable)
4212 return 0;
4214 /* Do not decompose a non-BLKmode param in a way that would
4215 create BLKmode params. Especially for by-reference passing
4216 (thus, pointer-type param) this is hardly worthwhile. */
4217 if (DECL_MODE (parm) != BLKmode
4218 && TYPE_MODE (repr->type) == BLKmode)
4219 return 0;
4221 if (!by_ref || (!repr->grp_maybe_modified
4222 && !repr->grp_not_necessarilly_dereferenced))
4223 total_size += repr->size;
4224 else
4225 total_size += cur_parm_size;
4227 new_param_count++;
4230 gcc_assert (new_param_count > 0);
4232 if (optimize_function_for_size_p (cfun))
4233 parm_size_limit = cur_parm_size;
4234 else
4235 parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
4236 * cur_parm_size);
4238 if (total_size < agg_size
4239 && total_size <= parm_size_limit)
4241 if (dump_file)
4242 fprintf (dump_file, " ....will be split into %i components\n",
4243 new_param_count);
4244 return new_param_count;
4246 else
4247 return 0;
4250 /* The order of the following enums is important, we need to do extra work for
4251 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4252 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
4253 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
4255 /* Identify representatives of all accesses to all candidate parameters for
4256 IPA-SRA. Return result based on what representatives have been found. */
4258 static enum ipa_splicing_result
4259 splice_all_param_accesses (vec<access_p> &representatives)
4261 enum ipa_splicing_result result = NO_GOOD_ACCESS;
4262 tree parm;
4263 struct access *repr;
4265 representatives.create (func_param_count);
4267 for (parm = DECL_ARGUMENTS (current_function_decl);
4268 parm;
4269 parm = DECL_CHAIN (parm))
4271 if (is_unused_scalar_param (parm))
4273 representatives.quick_push (&no_accesses_representant);
4274 if (result == NO_GOOD_ACCESS)
4275 result = UNUSED_PARAMS;
4277 else if (POINTER_TYPE_P (TREE_TYPE (parm))
4278 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
4279 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4281 repr = unmodified_by_ref_scalar_representative (parm);
4282 representatives.quick_push (repr);
4283 if (repr)
4284 result = UNMODIF_BY_REF_ACCESSES;
4286 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4288 bool ro_grp = false;
4289 repr = splice_param_accesses (parm, &ro_grp);
4290 representatives.quick_push (repr);
4292 if (repr && !no_accesses_p (repr))
4294 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4296 if (ro_grp)
4297 result = UNMODIF_BY_REF_ACCESSES;
4298 else if (result < MODIF_BY_REF_ACCESSES)
4299 result = MODIF_BY_REF_ACCESSES;
4301 else if (result < BY_VAL_ACCESSES)
4302 result = BY_VAL_ACCESSES;
4304 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
4305 result = UNUSED_PARAMS;
4307 else
4308 representatives.quick_push (NULL);
4311 if (result == NO_GOOD_ACCESS)
4313 representatives.release ();
4314 return NO_GOOD_ACCESS;
4317 return result;
4320 /* Return the index of BASE in PARMS. Abort if it is not found. */
4322 static inline int
4323 get_param_index (tree base, vec<tree> parms)
4325 int i, len;
4327 len = parms.length ();
4328 for (i = 0; i < len; i++)
4329 if (parms[i] == base)
4330 return i;
4331 gcc_unreachable ();
4334 /* Convert the decisions made at the representative level into compact
4335 parameter adjustments. REPRESENTATIVES are pointers to first
4336 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4337 final number of adjustments. */
4339 static ipa_parm_adjustment_vec
4340 turn_representatives_into_adjustments (vec<access_p> representatives,
4341 int adjustments_count)
4343 vec<tree> parms;
4344 ipa_parm_adjustment_vec adjustments;
4345 tree parm;
4346 int i;
4348 gcc_assert (adjustments_count > 0);
4349 parms = ipa_get_vector_of_formal_parms (current_function_decl);
4350 adjustments.create (adjustments_count);
4351 parm = DECL_ARGUMENTS (current_function_decl);
4352 for (i = 0; i < func_param_count; i++, parm = DECL_CHAIN (parm))
4354 struct access *repr = representatives[i];
4356 if (!repr || no_accesses_p (repr))
4358 struct ipa_parm_adjustment adj;
4360 memset (&adj, 0, sizeof (adj));
4361 adj.base_index = get_param_index (parm, parms);
4362 adj.base = parm;
4363 if (!repr)
4364 adj.op = IPA_PARM_OP_COPY;
4365 else
4366 adj.op = IPA_PARM_OP_REMOVE;
4367 adj.arg_prefix = "ISRA";
4368 adjustments.quick_push (adj);
4370 else
4372 struct ipa_parm_adjustment adj;
4373 int index = get_param_index (parm, parms);
4375 for (; repr; repr = repr->next_grp)
4377 memset (&adj, 0, sizeof (adj));
4378 gcc_assert (repr->base == parm);
4379 adj.base_index = index;
4380 adj.base = repr->base;
4381 adj.type = repr->type;
4382 adj.alias_ptr_type = reference_alias_ptr_type (repr->expr);
4383 adj.offset = repr->offset;
4384 adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
4385 && (repr->grp_maybe_modified
4386 || repr->grp_not_necessarilly_dereferenced));
4387 adj.arg_prefix = "ISRA";
4388 adjustments.quick_push (adj);
4392 parms.release ();
4393 return adjustments;
4396 /* Analyze the collected accesses and produce a plan what to do with the
4397 parameters in the form of adjustments, NULL meaning nothing. */
4399 static ipa_parm_adjustment_vec
4400 analyze_all_param_acesses (void)
4402 enum ipa_splicing_result repr_state;
4403 bool proceed = false;
4404 int i, adjustments_count = 0;
4405 vec<access_p> representatives;
4406 ipa_parm_adjustment_vec adjustments;
4408 repr_state = splice_all_param_accesses (representatives);
4409 if (repr_state == NO_GOOD_ACCESS)
4410 return ipa_parm_adjustment_vec ();
4412 /* If there are any parameters passed by reference which are not modified
4413 directly, we need to check whether they can be modified indirectly. */
4414 if (repr_state == UNMODIF_BY_REF_ACCESSES)
4416 analyze_caller_dereference_legality (representatives);
4417 analyze_modified_params (representatives);
4420 for (i = 0; i < func_param_count; i++)
4422 struct access *repr = representatives[i];
4424 if (repr && !no_accesses_p (repr))
4426 if (repr->grp_scalar_ptr)
4428 adjustments_count++;
4429 if (repr->grp_not_necessarilly_dereferenced
4430 || repr->grp_maybe_modified)
4431 representatives[i] = NULL;
4432 else
4434 proceed = true;
4435 sra_stats.scalar_by_ref_to_by_val++;
4438 else
4440 int new_components = decide_one_param_reduction (repr);
4442 if (new_components == 0)
4444 representatives[i] = NULL;
4445 adjustments_count++;
4447 else
4449 adjustments_count += new_components;
4450 sra_stats.aggregate_params_reduced++;
4451 sra_stats.param_reductions_created += new_components;
4452 proceed = true;
4456 else
4458 if (no_accesses_p (repr))
4460 proceed = true;
4461 sra_stats.deleted_unused_parameters++;
4463 adjustments_count++;
4467 if (!proceed && dump_file)
4468 fprintf (dump_file, "NOT proceeding to change params.\n");
4470 if (proceed)
4471 adjustments = turn_representatives_into_adjustments (representatives,
4472 adjustments_count);
4473 else
4474 adjustments = ipa_parm_adjustment_vec ();
4476 representatives.release ();
4477 return adjustments;
4480 /* If a parameter replacement identified by ADJ does not yet exist in the form
4481 of declaration, create it and record it, otherwise return the previously
4482 created one. */
4484 static tree
4485 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
4487 tree repl;
4488 if (!adj->new_ssa_base)
4490 char *pretty_name = make_fancy_name (adj->base);
4492 repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR");
4493 DECL_NAME (repl) = get_identifier (pretty_name);
4494 obstack_free (&name_obstack, pretty_name);
4496 adj->new_ssa_base = repl;
4498 else
4499 repl = adj->new_ssa_base;
4500 return repl;
4503 /* Find the first adjustment for a particular parameter BASE in a vector of
4504 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4505 adjustment. */
4507 static struct ipa_parm_adjustment *
4508 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
4510 int i, len;
4512 len = adjustments.length ();
4513 for (i = 0; i < len; i++)
4515 struct ipa_parm_adjustment *adj;
4517 adj = &adjustments[i];
4518 if (adj->op != IPA_PARM_OP_COPY && adj->base == base)
4519 return adj;
4522 return NULL;
4525 /* If the statement STMT defines an SSA_NAME of a parameter which is to be
4526 removed because its value is not used, replace the SSA_NAME with a one
4527 relating to a created VAR_DECL together all of its uses and return true.
4528 ADJUSTMENTS is a pointer to an adjustments vector. */
4530 static bool
4531 replace_removed_params_ssa_names (gimple stmt,
4532 ipa_parm_adjustment_vec adjustments)
4534 struct ipa_parm_adjustment *adj;
4535 tree lhs, decl, repl, name;
4537 if (gimple_code (stmt) == GIMPLE_PHI)
4538 lhs = gimple_phi_result (stmt);
4539 else if (is_gimple_assign (stmt))
4540 lhs = gimple_assign_lhs (stmt);
4541 else if (is_gimple_call (stmt))
4542 lhs = gimple_call_lhs (stmt);
4543 else
4544 gcc_unreachable ();
4546 if (TREE_CODE (lhs) != SSA_NAME)
4547 return false;
4549 decl = SSA_NAME_VAR (lhs);
4550 if (decl == NULL_TREE
4551 || TREE_CODE (decl) != PARM_DECL)
4552 return false;
4554 adj = get_adjustment_for_base (adjustments, decl);
4555 if (!adj)
4556 return false;
4558 repl = get_replaced_param_substitute (adj);
4559 name = make_ssa_name (repl, stmt);
4561 if (dump_file)
4563 fprintf (dump_file, "replacing an SSA name of a removed param ");
4564 print_generic_expr (dump_file, lhs, 0);
4565 fprintf (dump_file, " with ");
4566 print_generic_expr (dump_file, name, 0);
4567 fprintf (dump_file, "\n");
4570 if (is_gimple_assign (stmt))
4571 gimple_assign_set_lhs (stmt, name);
4572 else if (is_gimple_call (stmt))
4573 gimple_call_set_lhs (stmt, name);
4574 else
4575 gimple_phi_set_result (stmt, name);
4577 replace_uses_by (lhs, name);
4578 release_ssa_name (lhs);
4579 return true;
4582 /* If the statement pointed to by STMT_PTR contains any expressions that need
4583 to replaced with a different one as noted by ADJUSTMENTS, do so. Handle any
4584 potential type incompatibilities (GSI is used to accommodate conversion
4585 statements and must point to the statement). Return true iff the statement
4586 was modified. */
4588 static bool
4589 sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi,
4590 ipa_parm_adjustment_vec adjustments)
4592 gimple stmt = *stmt_ptr;
4593 tree *lhs_p, *rhs_p;
4594 bool any;
4596 if (!gimple_assign_single_p (stmt))
4597 return false;
4599 rhs_p = gimple_assign_rhs1_ptr (stmt);
4600 lhs_p = gimple_assign_lhs_ptr (stmt);
4602 any = ipa_modify_expr (rhs_p, false, adjustments);
4603 any |= ipa_modify_expr (lhs_p, false, adjustments);
4604 if (any)
4606 tree new_rhs = NULL_TREE;
4608 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
4610 if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
4612 /* V_C_Es of constructors can cause trouble (PR 42714). */
4613 if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
4614 *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
4615 else
4616 *rhs_p = build_constructor (TREE_TYPE (*lhs_p),
4617 NULL);
4619 else
4620 new_rhs = fold_build1_loc (gimple_location (stmt),
4621 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
4622 *rhs_p);
4624 else if (REFERENCE_CLASS_P (*rhs_p)
4625 && is_gimple_reg_type (TREE_TYPE (*lhs_p))
4626 && !is_gimple_reg (*lhs_p))
4627 /* This can happen when an assignment in between two single field
4628 structures is turned into an assignment in between two pointers to
4629 scalars (PR 42237). */
4630 new_rhs = *rhs_p;
4632 if (new_rhs)
4634 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
4635 true, GSI_SAME_STMT);
4637 gimple_assign_set_rhs_from_tree (gsi, tmp);
4640 return true;
4643 return false;
4646 /* Traverse the function body and all modifications as described in
4647 ADJUSTMENTS. Return true iff the CFG has been changed. */
4649 bool
4650 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
4652 bool cfg_changed = false;
4653 basic_block bb;
4655 FOR_EACH_BB_FN (bb, cfun)
4657 gimple_stmt_iterator gsi;
4659 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4660 replace_removed_params_ssa_names (gsi_stmt (gsi), adjustments);
4662 gsi = gsi_start_bb (bb);
4663 while (!gsi_end_p (gsi))
4665 gimple stmt = gsi_stmt (gsi);
4666 bool modified = false;
4667 tree *t;
4668 unsigned i;
4670 switch (gimple_code (stmt))
4672 case GIMPLE_RETURN:
4673 t = gimple_return_retval_ptr (stmt);
4674 if (*t != NULL_TREE)
4675 modified |= ipa_modify_expr (t, true, adjustments);
4676 break;
4678 case GIMPLE_ASSIGN:
4679 modified |= sra_ipa_modify_assign (&stmt, &gsi, adjustments);
4680 modified |= replace_removed_params_ssa_names (stmt, adjustments);
4681 break;
4683 case GIMPLE_CALL:
4684 /* Operands must be processed before the lhs. */
4685 for (i = 0; i < gimple_call_num_args (stmt); i++)
4687 t = gimple_call_arg_ptr (stmt, i);
4688 modified |= ipa_modify_expr (t, true, adjustments);
4691 if (gimple_call_lhs (stmt))
4693 t = gimple_call_lhs_ptr (stmt);
4694 modified |= ipa_modify_expr (t, false, adjustments);
4695 modified |= replace_removed_params_ssa_names (stmt,
4696 adjustments);
4698 break;
4700 case GIMPLE_ASM:
4701 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
4703 t = &TREE_VALUE (gimple_asm_input_op (stmt, i));
4704 modified |= ipa_modify_expr (t, true, adjustments);
4706 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
4708 t = &TREE_VALUE (gimple_asm_output_op (stmt, i));
4709 modified |= ipa_modify_expr (t, false, adjustments);
4711 break;
4713 default:
4714 break;
4717 if (modified)
4719 update_stmt (stmt);
4720 if (maybe_clean_eh_stmt (stmt)
4721 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
4722 cfg_changed = true;
4724 gsi_next (&gsi);
4728 return cfg_changed;
4731 /* Call gimple_debug_bind_reset_value on all debug statements describing
4732 gimple register parameters that are being removed or replaced. */
4734 static void
4735 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
4737 int i, len;
4738 gimple_stmt_iterator *gsip = NULL, gsi;
4740 if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
4742 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
4743 gsip = &gsi;
4745 len = adjustments.length ();
4746 for (i = 0; i < len; i++)
4748 struct ipa_parm_adjustment *adj;
4749 imm_use_iterator ui;
4750 gimple stmt, def_temp;
4751 tree name, vexpr, copy = NULL_TREE;
4752 use_operand_p use_p;
4754 adj = &adjustments[i];
4755 if (adj->op == IPA_PARM_OP_COPY || !is_gimple_reg (adj->base))
4756 continue;
4757 name = ssa_default_def (cfun, adj->base);
4758 vexpr = NULL;
4759 if (name)
4760 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
4762 if (gimple_clobber_p (stmt))
4764 gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
4765 unlink_stmt_vdef (stmt);
4766 gsi_remove (&cgsi, true);
4767 release_defs (stmt);
4768 continue;
4770 /* All other users must have been removed by
4771 ipa_sra_modify_function_body. */
4772 gcc_assert (is_gimple_debug (stmt));
4773 if (vexpr == NULL && gsip != NULL)
4775 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
4776 vexpr = make_node (DEBUG_EXPR_DECL);
4777 def_temp = gimple_build_debug_source_bind (vexpr, adj->base,
4778 NULL);
4779 DECL_ARTIFICIAL (vexpr) = 1;
4780 TREE_TYPE (vexpr) = TREE_TYPE (name);
4781 DECL_MODE (vexpr) = DECL_MODE (adj->base);
4782 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
4784 if (vexpr)
4786 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
4787 SET_USE (use_p, vexpr);
4789 else
4790 gimple_debug_bind_reset_value (stmt);
4791 update_stmt (stmt);
4793 /* Create a VAR_DECL for debug info purposes. */
4794 if (!DECL_IGNORED_P (adj->base))
4796 copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
4797 VAR_DECL, DECL_NAME (adj->base),
4798 TREE_TYPE (adj->base));
4799 if (DECL_PT_UID_SET_P (adj->base))
4800 SET_DECL_PT_UID (copy, DECL_PT_UID (adj->base));
4801 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (adj->base);
4802 TREE_READONLY (copy) = TREE_READONLY (adj->base);
4803 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (adj->base);
4804 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (adj->base);
4805 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (adj->base);
4806 DECL_IGNORED_P (copy) = DECL_IGNORED_P (adj->base);
4807 DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (adj->base);
4808 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
4809 SET_DECL_RTL (copy, 0);
4810 TREE_USED (copy) = 1;
4811 DECL_CONTEXT (copy) = current_function_decl;
4812 add_local_decl (cfun, copy);
4813 DECL_CHAIN (copy) =
4814 BLOCK_VARS (DECL_INITIAL (current_function_decl));
4815 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
4817 if (gsip != NULL && copy && target_for_debug_bind (adj->base))
4819 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
4820 if (vexpr)
4821 def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
4822 else
4823 def_temp = gimple_build_debug_source_bind (copy, adj->base,
4824 NULL);
4825 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
4830 /* Return false if all callers have at least as many actual arguments as there
4831 are formal parameters in the current function and that their types
4832 match. */
4834 static bool
4835 some_callers_have_mismatched_arguments_p (struct cgraph_node *node,
4836 void *data ATTRIBUTE_UNUSED)
4838 struct cgraph_edge *cs;
4839 for (cs = node->callers; cs; cs = cs->next_caller)
4840 if (!callsite_arguments_match_p (cs->call_stmt))
4841 return true;
4843 return false;
4846 /* Convert all callers of NODE. */
4848 static bool
4849 convert_callers_for_node (struct cgraph_node *node,
4850 void *data)
4852 ipa_parm_adjustment_vec *adjustments = (ipa_parm_adjustment_vec *) data;
4853 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
4854 struct cgraph_edge *cs;
4856 for (cs = node->callers; cs; cs = cs->next_caller)
4858 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
4860 if (dump_file)
4861 fprintf (dump_file, "Adjusting call %s/%i -> %s/%i\n",
4862 xstrdup (cs->caller->name ()),
4863 cs->caller->order,
4864 xstrdup (cs->callee->name ()),
4865 cs->callee->order);
4867 ipa_modify_call_arguments (cs, cs->call_stmt, *adjustments);
4869 pop_cfun ();
4872 for (cs = node->callers; cs; cs = cs->next_caller)
4873 if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
4874 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
4875 compute_inline_parameters (cs->caller, true);
4876 BITMAP_FREE (recomputed_callers);
4878 return true;
4881 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
4883 static void
4884 convert_callers (struct cgraph_node *node, tree old_decl,
4885 ipa_parm_adjustment_vec adjustments)
4887 basic_block this_block;
4889 node->call_for_symbol_thunks_and_aliases (convert_callers_for_node,
4890 &adjustments, false);
4892 if (!encountered_recursive_call)
4893 return;
4895 FOR_EACH_BB_FN (this_block, cfun)
4897 gimple_stmt_iterator gsi;
4899 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
4901 gimple stmt = gsi_stmt (gsi);
4902 tree call_fndecl;
4903 if (gimple_code (stmt) != GIMPLE_CALL)
4904 continue;
4905 call_fndecl = gimple_call_fndecl (stmt);
4906 if (call_fndecl == old_decl)
4908 if (dump_file)
4909 fprintf (dump_file, "Adjusting recursive call");
4910 gimple_call_set_fndecl (stmt, node->decl);
4911 ipa_modify_call_arguments (NULL, stmt, adjustments);
4916 return;
4919 /* Perform all the modification required in IPA-SRA for NODE to have parameters
4920 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
4922 static bool
4923 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
4925 struct cgraph_node *new_node;
4926 bool cfg_changed;
4928 rebuild_cgraph_edges ();
4929 free_dominance_info (CDI_DOMINATORS);
4930 pop_cfun ();
4932 /* This must be done after rebuilding cgraph edges for node above.
4933 Otherwise any recursive calls to node that are recorded in
4934 redirect_callers will be corrupted. */
4935 vec<cgraph_edge *> redirect_callers = node->collect_callers ();
4936 new_node = node->create_version_clone_with_body (redirect_callers, NULL,
4937 NULL, false, NULL, NULL,
4938 "isra");
4939 redirect_callers.release ();
4941 push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
4942 ipa_modify_formal_parameters (current_function_decl, adjustments);
4943 cfg_changed = ipa_sra_modify_function_body (adjustments);
4944 sra_ipa_reset_debug_stmts (adjustments);
4945 convert_callers (new_node, node->decl, adjustments);
4946 new_node->make_local ();
4947 return cfg_changed;
4950 /* If NODE has a caller, return true. */
4952 static bool
4953 has_caller_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
4955 if (node->callers)
4956 return true;
4957 return false;
4960 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
4961 attributes, return true otherwise. NODE is the cgraph node of the current
4962 function. */
4964 static bool
4965 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
4967 if (!node->can_be_local_p ())
4969 if (dump_file)
4970 fprintf (dump_file, "Function not local to this compilation unit.\n");
4971 return false;
4974 if (!node->local.can_change_signature)
4976 if (dump_file)
4977 fprintf (dump_file, "Function can not change signature.\n");
4978 return false;
4981 if (!tree_versionable_function_p (node->decl))
4983 if (dump_file)
4984 fprintf (dump_file, "Function is not versionable.\n");
4985 return false;
4988 if (!opt_for_fn (node->decl, optimize)
4989 || !opt_for_fn (node->decl, flag_ipa_sra))
4991 if (dump_file)
4992 fprintf (dump_file, "Function not optimized.\n");
4993 return false;
4996 if (DECL_VIRTUAL_P (current_function_decl))
4998 if (dump_file)
4999 fprintf (dump_file, "Function is a virtual method.\n");
5000 return false;
5003 if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
5004 && inline_summary (node)->size >= MAX_INLINE_INSNS_AUTO)
5006 if (dump_file)
5007 fprintf (dump_file, "Function too big to be made truly local.\n");
5008 return false;
5011 if (!node->call_for_symbol_thunks_and_aliases (has_caller_p, NULL, true))
5013 if (dump_file)
5014 fprintf (dump_file,
5015 "Function has no callers in this compilation unit.\n");
5016 return false;
5019 if (cfun->stdarg)
5021 if (dump_file)
5022 fprintf (dump_file, "Function uses stdarg. \n");
5023 return false;
5026 if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
5027 return false;
5029 if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
5031 if (dump_file)
5032 fprintf (dump_file, "Always inline function will be inlined "
5033 "anyway. \n");
5034 return false;
5037 return true;
5040 /* Perform early interprocedural SRA. */
5042 static unsigned int
5043 ipa_early_sra (void)
5045 struct cgraph_node *node = cgraph_node::get (current_function_decl);
5046 ipa_parm_adjustment_vec adjustments;
5047 int ret = 0;
5049 if (!ipa_sra_preliminary_function_checks (node))
5050 return 0;
5052 sra_initialize ();
5053 sra_mode = SRA_MODE_EARLY_IPA;
5055 if (!find_param_candidates ())
5057 if (dump_file)
5058 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
5059 goto simple_out;
5062 if (node->call_for_symbol_thunks_and_aliases
5063 (some_callers_have_mismatched_arguments_p, NULL, true))
5065 if (dump_file)
5066 fprintf (dump_file, "There are callers with insufficient number of "
5067 "arguments or arguments with type mismatches.\n");
5068 goto simple_out;
5071 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
5072 func_param_count
5073 * last_basic_block_for_fn (cfun));
5074 final_bbs = BITMAP_ALLOC (NULL);
5076 scan_function ();
5077 if (encountered_apply_args)
5079 if (dump_file)
5080 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
5081 goto out;
5084 if (encountered_unchangable_recursive_call)
5086 if (dump_file)
5087 fprintf (dump_file, "Function calls itself with insufficient "
5088 "number of arguments.\n");
5089 goto out;
5092 adjustments = analyze_all_param_acesses ();
5093 if (!adjustments.exists ())
5094 goto out;
5095 if (dump_file)
5096 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
5098 if (modify_function (node, adjustments))
5099 ret = TODO_update_ssa | TODO_cleanup_cfg;
5100 else
5101 ret = TODO_update_ssa;
5102 adjustments.release ();
5104 statistics_counter_event (cfun, "Unused parameters deleted",
5105 sra_stats.deleted_unused_parameters);
5106 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
5107 sra_stats.scalar_by_ref_to_by_val);
5108 statistics_counter_event (cfun, "Aggregate parameters broken up",
5109 sra_stats.aggregate_params_reduced);
5110 statistics_counter_event (cfun, "Aggregate parameter components created",
5111 sra_stats.param_reductions_created);
5113 out:
5114 BITMAP_FREE (final_bbs);
5115 free (bb_dereferences);
5116 simple_out:
5117 sra_deinitialize ();
5118 return ret;
5121 namespace {
5123 const pass_data pass_data_early_ipa_sra =
5125 GIMPLE_PASS, /* type */
5126 "eipa_sra", /* name */
5127 OPTGROUP_NONE, /* optinfo_flags */
5128 TV_IPA_SRA, /* tv_id */
5129 0, /* properties_required */
5130 0, /* properties_provided */
5131 0, /* properties_destroyed */
5132 0, /* todo_flags_start */
5133 TODO_dump_symtab, /* todo_flags_finish */
5136 class pass_early_ipa_sra : public gimple_opt_pass
5138 public:
5139 pass_early_ipa_sra (gcc::context *ctxt)
5140 : gimple_opt_pass (pass_data_early_ipa_sra, ctxt)
5143 /* opt_pass methods: */
5144 virtual bool gate (function *) { return flag_ipa_sra && dbg_cnt (eipa_sra); }
5145 virtual unsigned int execute (function *) { return ipa_early_sra (); }
5147 }; // class pass_early_ipa_sra
5149 } // anon namespace
5151 gimple_opt_pass *
5152 make_pass_early_ipa_sra (gcc::context *ctxt)
5154 return new pass_early_ipa_sra (ctxt);