Merge from trunk: 215733-215743
[official-gcc.git] / gcc-4_9 / gcc / tree-sra.c
blob6a337f31d75045919fe975d84d3884dd486f01b4
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 "toplev.h"
109 #include "target.h"
110 #include "flags.h"
111 #include "dbgcnt.h"
112 #include "tree-inline.h"
113 #include "gimple-pretty-print.h"
114 #include "l-ipo.h"
115 #include "ipa-inline.h"
116 #include "ipa-utils.h"
118 /* Enumeration of all aggregate reductions we can do. */
119 enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
120 SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
121 SRA_MODE_INTRA }; /* late intraprocedural SRA */
123 /* Global variable describing which aggregate reduction we are performing at
124 the moment. */
125 static enum sra_mode sra_mode;
127 struct assign_link;
129 /* ACCESS represents each access to an aggregate variable (as a whole or a
130 part). It can also represent a group of accesses that refer to exactly the
131 same fragment of an aggregate (i.e. those that have exactly the same offset
132 and size). Such representatives for a single aggregate, once determined,
133 are linked in a linked list and have the group fields set.
135 Moreover, when doing intraprocedural SRA, a tree is built from those
136 representatives (by the means of first_child and next_sibling pointers), in
137 which all items in a subtree are "within" the root, i.e. their offset is
138 greater or equal to offset of the root and offset+size is smaller or equal
139 to offset+size of the root. Children of an access are sorted by offset.
141 Note that accesses to parts of vector and complex number types always
142 represented by an access to the whole complex number or a vector. It is a
143 duty of the modifying functions to replace them appropriately. */
145 struct access
147 /* Values returned by `get_ref_base_and_extent' for each component reference
148 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
149 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
150 HOST_WIDE_INT offset;
151 HOST_WIDE_INT size;
152 tree base;
154 /* Expression. It is context dependent so do not use it to create new
155 expressions to access the original aggregate. See PR 42154 for a
156 testcase. */
157 tree expr;
158 /* Type. */
159 tree type;
161 /* The statement this access belongs to. */
162 gimple stmt;
164 /* Next group representative for this aggregate. */
165 struct access *next_grp;
167 /* Pointer to the group representative. Pointer to itself if the struct is
168 the representative. */
169 struct access *group_representative;
171 /* If this access has any children (in terms of the definition above), this
172 points to the first one. */
173 struct access *first_child;
175 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
176 described above. In IPA-SRA this is a pointer to the next access
177 belonging to the same group (having the same representative). */
178 struct access *next_sibling;
180 /* Pointers to the first and last element in the linked list of assign
181 links. */
182 struct assign_link *first_link, *last_link;
184 /* Pointer to the next access in the work queue. */
185 struct access *next_queued;
187 /* Replacement variable for this access "region." Never to be accessed
188 directly, always only by the means of get_access_replacement() and only
189 when grp_to_be_replaced flag is set. */
190 tree replacement_decl;
192 /* Is this particular access write access? */
193 unsigned write : 1;
195 /* Is this access an access to a non-addressable field? */
196 unsigned non_addressable : 1;
198 /* Is this access currently in the work queue? */
199 unsigned grp_queued : 1;
201 /* Does this group contain a write access? This flag is propagated down the
202 access tree. */
203 unsigned grp_write : 1;
205 /* Does this group contain a read access? This flag is propagated down the
206 access tree. */
207 unsigned grp_read : 1;
209 /* Does this group contain a read access that comes from an assignment
210 statement? This flag is propagated down the access tree. */
211 unsigned grp_assignment_read : 1;
213 /* Does this group contain a write access that comes from an assignment
214 statement? This flag is propagated down the access tree. */
215 unsigned grp_assignment_write : 1;
217 /* Does this group contain a read access through a scalar type? This flag is
218 not propagated in the access tree in any direction. */
219 unsigned grp_scalar_read : 1;
221 /* Does this group contain a write access through a scalar type? This flag
222 is not propagated in the access tree in any direction. */
223 unsigned grp_scalar_write : 1;
225 /* Is this access an artificial one created to scalarize some record
226 entirely? */
227 unsigned grp_total_scalarization : 1;
229 /* Other passes of the analysis use this bit to make function
230 analyze_access_subtree create scalar replacements for this group if
231 possible. */
232 unsigned grp_hint : 1;
234 /* Is the subtree rooted in this access fully covered by scalar
235 replacements? */
236 unsigned grp_covered : 1;
238 /* If set to true, this access and all below it in an access tree must not be
239 scalarized. */
240 unsigned grp_unscalarizable_region : 1;
242 /* Whether data have been written to parts of the aggregate covered by this
243 access which is not to be scalarized. This flag is propagated up in the
244 access tree. */
245 unsigned grp_unscalarized_data : 1;
247 /* Does this access and/or group contain a write access through a
248 BIT_FIELD_REF? */
249 unsigned grp_partial_lhs : 1;
251 /* Set when a scalar replacement should be created for this variable. */
252 unsigned grp_to_be_replaced : 1;
254 /* Set when we want a replacement for the sole purpose of having it in
255 generated debug statements. */
256 unsigned grp_to_be_debug_replaced : 1;
258 /* Should TREE_NO_WARNING of a replacement be set? */
259 unsigned grp_no_warning : 1;
261 /* Is it possible that the group refers to data which might be (directly or
262 otherwise) modified? */
263 unsigned grp_maybe_modified : 1;
265 /* Set when this is a representative of a pointer to scalar (i.e. by
266 reference) parameter which we consider for turning into a plain scalar
267 (i.e. a by value parameter). */
268 unsigned grp_scalar_ptr : 1;
270 /* Set when we discover that this pointer is not safe to dereference in the
271 caller. */
272 unsigned grp_not_necessarilly_dereferenced : 1;
275 typedef struct access *access_p;
278 /* Alloc pool for allocating access structures. */
279 static alloc_pool access_pool;
281 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
282 are used to propagate subaccesses from rhs to lhs as long as they don't
283 conflict with what is already there. */
284 struct assign_link
286 struct access *lacc, *racc;
287 struct assign_link *next;
290 /* Alloc pool for allocating assign link structures. */
291 static alloc_pool link_pool;
293 /* Base (tree) -> Vector (vec<access_p> *) map. */
294 static struct pointer_map_t *base_access_vec;
296 /* Candidate hash table helpers. */
298 struct uid_decl_hasher : typed_noop_remove <tree_node>
300 typedef tree_node value_type;
301 typedef tree_node compare_type;
302 static inline hashval_t hash (const value_type *);
303 static inline bool equal (const value_type *, const compare_type *);
306 /* Hash a tree in a uid_decl_map. */
308 inline hashval_t
309 uid_decl_hasher::hash (const value_type *item)
311 return item->decl_minimal.uid;
314 /* Return true if the DECL_UID in both trees are equal. */
316 inline bool
317 uid_decl_hasher::equal (const value_type *a, const compare_type *b)
319 return (a->decl_minimal.uid == b->decl_minimal.uid);
322 /* Set of candidates. */
323 static bitmap candidate_bitmap;
324 static hash_table <uid_decl_hasher> candidates;
326 /* For a candidate UID return the candidates decl. */
328 static inline tree
329 candidate (unsigned uid)
331 tree_node t;
332 t.decl_minimal.uid = uid;
333 return candidates.find_with_hash (&t, static_cast <hashval_t> (uid));
336 /* Bitmap of candidates which we should try to entirely scalarize away and
337 those which cannot be (because they are and need be used as a whole). */
338 static bitmap should_scalarize_away_bitmap, cannot_scalarize_away_bitmap;
340 /* Obstack for creation of fancy names. */
341 static struct obstack name_obstack;
343 /* Head of a linked list of accesses that need to have its subaccesses
344 propagated to their assignment counterparts. */
345 static struct access *work_queue_head;
347 /* Number of parameters of the analyzed function when doing early ipa SRA. */
348 static int func_param_count;
350 /* scan_function sets the following to true if it encounters a call to
351 __builtin_apply_args. */
352 static bool encountered_apply_args;
354 /* Set by scan_function when it finds a recursive call. */
355 static bool encountered_recursive_call;
357 /* Set by scan_function when it finds a recursive call with less actual
358 arguments than formal parameters.. */
359 static bool encountered_unchangable_recursive_call;
361 /* This is a table in which for each basic block and parameter there is a
362 distance (offset + size) in that parameter which is dereferenced and
363 accessed in that BB. */
364 static HOST_WIDE_INT *bb_dereferences;
365 /* Bitmap of BBs that can cause the function to "stop" progressing by
366 returning, throwing externally, looping infinitely or calling a function
367 which might abort etc.. */
368 static bitmap final_bbs;
370 /* Representative of no accesses at all. */
371 static struct access no_accesses_representant;
373 /* Predicate to test the special value. */
375 static inline bool
376 no_accesses_p (struct access *access)
378 return access == &no_accesses_representant;
381 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
382 representative fields are dumped, otherwise those which only describe the
383 individual access are. */
385 static struct
387 /* Number of processed aggregates is readily available in
388 analyze_all_variable_accesses and so is not stored here. */
390 /* Number of created scalar replacements. */
391 int replacements;
393 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
394 expression. */
395 int exprs;
397 /* Number of statements created by generate_subtree_copies. */
398 int subtree_copies;
400 /* Number of statements created by load_assign_lhs_subreplacements. */
401 int subreplacements;
403 /* Number of times sra_modify_assign has deleted a statement. */
404 int deleted;
406 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
407 RHS reparately due to type conversions or nonexistent matching
408 references. */
409 int separate_lhs_rhs_handling;
411 /* Number of parameters that were removed because they were unused. */
412 int deleted_unused_parameters;
414 /* Number of scalars passed as parameters by reference that have been
415 converted to be passed by value. */
416 int scalar_by_ref_to_by_val;
418 /* Number of aggregate parameters that were replaced by one or more of their
419 components. */
420 int aggregate_params_reduced;
422 /* Numbber of components created when splitting aggregate parameters. */
423 int param_reductions_created;
424 } sra_stats;
426 static void
427 dump_access (FILE *f, struct access *access, bool grp)
429 fprintf (f, "access { ");
430 fprintf (f, "base = (%d)'", DECL_UID (access->base));
431 print_generic_expr (f, access->base, 0);
432 fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
433 fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
434 fprintf (f, ", expr = ");
435 print_generic_expr (f, access->expr, 0);
436 fprintf (f, ", type = ");
437 print_generic_expr (f, access->type, 0);
438 if (grp)
439 fprintf (f, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
440 "grp_assignment_write = %d, grp_scalar_read = %d, "
441 "grp_scalar_write = %d, grp_total_scalarization = %d, "
442 "grp_hint = %d, grp_covered = %d, "
443 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
444 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
445 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
446 "grp_not_necessarilly_dereferenced = %d\n",
447 access->grp_read, access->grp_write, access->grp_assignment_read,
448 access->grp_assignment_write, access->grp_scalar_read,
449 access->grp_scalar_write, access->grp_total_scalarization,
450 access->grp_hint, access->grp_covered,
451 access->grp_unscalarizable_region, access->grp_unscalarized_data,
452 access->grp_partial_lhs, access->grp_to_be_replaced,
453 access->grp_to_be_debug_replaced, access->grp_maybe_modified,
454 access->grp_not_necessarilly_dereferenced);
455 else
456 fprintf (f, ", write = %d, grp_total_scalarization = %d, "
457 "grp_partial_lhs = %d\n",
458 access->write, access->grp_total_scalarization,
459 access->grp_partial_lhs);
462 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
464 static void
465 dump_access_tree_1 (FILE *f, struct access *access, int level)
469 int i;
471 for (i = 0; i < level; i++)
472 fputs ("* ", dump_file);
474 dump_access (f, access, true);
476 if (access->first_child)
477 dump_access_tree_1 (f, access->first_child, level + 1);
479 access = access->next_sibling;
481 while (access);
484 /* Dump all access trees for a variable, given the pointer to the first root in
485 ACCESS. */
487 static void
488 dump_access_tree (FILE *f, struct access *access)
490 for (; access; access = access->next_grp)
491 dump_access_tree_1 (f, access, 0);
494 /* Return true iff ACC is non-NULL and has subaccesses. */
496 static inline bool
497 access_has_children_p (struct access *acc)
499 return acc && acc->first_child;
502 /* Return true iff ACC is (partly) covered by at least one replacement. */
504 static bool
505 access_has_replacements_p (struct access *acc)
507 struct access *child;
508 if (acc->grp_to_be_replaced)
509 return true;
510 for (child = acc->first_child; child; child = child->next_sibling)
511 if (access_has_replacements_p (child))
512 return true;
513 return false;
516 /* Return a vector of pointers to accesses for the variable given in BASE or
517 NULL if there is none. */
519 static vec<access_p> *
520 get_base_access_vector (tree base)
522 void **slot;
524 slot = pointer_map_contains (base_access_vec, base);
525 if (!slot)
526 return NULL;
527 else
528 return *(vec<access_p> **) slot;
531 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
532 in ACCESS. Return NULL if it cannot be found. */
534 static struct access *
535 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
536 HOST_WIDE_INT size)
538 while (access && (access->offset != offset || access->size != size))
540 struct access *child = access->first_child;
542 while (child && (child->offset + child->size <= offset))
543 child = child->next_sibling;
544 access = child;
547 return access;
550 /* Return the first group representative for DECL or NULL if none exists. */
552 static struct access *
553 get_first_repr_for_decl (tree base)
555 vec<access_p> *access_vec;
557 access_vec = get_base_access_vector (base);
558 if (!access_vec)
559 return NULL;
561 return (*access_vec)[0];
564 /* Find an access representative for the variable BASE and given OFFSET and
565 SIZE. Requires that access trees have already been built. Return NULL if
566 it cannot be found. */
568 static struct access *
569 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
570 HOST_WIDE_INT size)
572 struct access *access;
574 access = get_first_repr_for_decl (base);
575 while (access && (access->offset + access->size <= offset))
576 access = access->next_grp;
577 if (!access)
578 return NULL;
580 return find_access_in_subtree (access, offset, size);
583 /* Add LINK to the linked list of assign links of RACC. */
584 static void
585 add_link_to_rhs (struct access *racc, struct assign_link *link)
587 gcc_assert (link->racc == racc);
589 if (!racc->first_link)
591 gcc_assert (!racc->last_link);
592 racc->first_link = link;
594 else
595 racc->last_link->next = link;
597 racc->last_link = link;
598 link->next = NULL;
601 /* Move all link structures in their linked list in OLD_RACC to the linked list
602 in NEW_RACC. */
603 static void
604 relink_to_new_repr (struct access *new_racc, struct access *old_racc)
606 if (!old_racc->first_link)
608 gcc_assert (!old_racc->last_link);
609 return;
612 if (new_racc->first_link)
614 gcc_assert (!new_racc->last_link->next);
615 gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
617 new_racc->last_link->next = old_racc->first_link;
618 new_racc->last_link = old_racc->last_link;
620 else
622 gcc_assert (!new_racc->last_link);
624 new_racc->first_link = old_racc->first_link;
625 new_racc->last_link = old_racc->last_link;
627 old_racc->first_link = old_racc->last_link = NULL;
630 /* Add ACCESS to the work queue (which is actually a stack). */
632 static void
633 add_access_to_work_queue (struct access *access)
635 if (!access->grp_queued)
637 gcc_assert (!access->next_queued);
638 access->next_queued = work_queue_head;
639 access->grp_queued = 1;
640 work_queue_head = access;
644 /* Pop an access from the work queue, and return it, assuming there is one. */
646 static struct access *
647 pop_access_from_work_queue (void)
649 struct access *access = work_queue_head;
651 work_queue_head = access->next_queued;
652 access->next_queued = NULL;
653 access->grp_queued = 0;
654 return access;
658 /* Allocate necessary structures. */
660 static void
661 sra_initialize (void)
663 candidate_bitmap = BITMAP_ALLOC (NULL);
664 candidates.create (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 candidates.dispose ();
695 BITMAP_FREE (should_scalarize_away_bitmap);
696 BITMAP_FREE (cannot_scalarize_away_bitmap);
697 free_alloc_pool (access_pool);
698 free_alloc_pool (link_pool);
699 obstack_free (&name_obstack, NULL);
701 pointer_map_traverse (base_access_vec, delete_base_accesses, NULL);
702 pointer_map_destroy (base_access_vec);
705 /* Remove DECL from candidates for SRA and write REASON to the dump file if
706 there is one. */
707 static void
708 disqualify_candidate (tree decl, const char *reason)
710 if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl)))
711 candidates.clear_slot (candidates.find_slot_with_hash (decl,
712 DECL_UID (decl),
713 NO_INSERT));
715 if (dump_file && (dump_flags & TDF_DETAILS))
717 fprintf (dump_file, "! Disqualifying ");
718 print_generic_expr (dump_file, decl, 0);
719 fprintf (dump_file, " - %s\n", reason);
723 /* Return true iff the type contains a field or an element which does not allow
724 scalarization. */
726 static bool
727 type_internals_preclude_sra_p (tree type, const char **msg)
729 tree fld;
730 tree et;
732 switch (TREE_CODE (type))
734 case RECORD_TYPE:
735 case UNION_TYPE:
736 case QUAL_UNION_TYPE:
737 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
738 if (TREE_CODE (fld) == FIELD_DECL)
740 tree ft = TREE_TYPE (fld);
742 if (TREE_THIS_VOLATILE (fld))
744 *msg = "volatile structure field";
745 return true;
747 if (!DECL_FIELD_OFFSET (fld))
749 *msg = "no structure field offset";
750 return true;
752 if (!DECL_SIZE (fld))
754 *msg = "zero structure field size";
755 return true;
757 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
759 *msg = "structure field offset not fixed";
760 return true;
762 if (!tree_fits_uhwi_p (DECL_SIZE (fld)))
764 *msg = "structure field size not fixed";
765 return true;
767 if (!tree_fits_shwi_p (bit_position (fld)))
769 *msg = "structure field size too big";
770 return true;
772 if (AGGREGATE_TYPE_P (ft)
773 && int_bit_position (fld) % BITS_PER_UNIT != 0)
775 *msg = "structure field is bit field";
776 return true;
779 if (AGGREGATE_TYPE_P (ft) && type_internals_preclude_sra_p (ft, msg))
780 return true;
783 return false;
785 case ARRAY_TYPE:
786 et = TREE_TYPE (type);
788 if (TYPE_VOLATILE (et))
790 *msg = "element type is volatile";
791 return true;
794 if (AGGREGATE_TYPE_P (et) && type_internals_preclude_sra_p (et, msg))
795 return true;
797 return false;
799 default:
800 return false;
804 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
805 base variable if it is. Return T if it is not an SSA_NAME. */
807 static tree
808 get_ssa_base_param (tree t)
810 if (TREE_CODE (t) == SSA_NAME)
812 if (SSA_NAME_IS_DEFAULT_DEF (t))
813 return SSA_NAME_VAR (t);
814 else
815 return NULL_TREE;
817 return t;
820 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
821 belongs to, unless the BB has already been marked as a potentially
822 final. */
824 static void
825 mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple stmt)
827 basic_block bb = gimple_bb (stmt);
828 int idx, parm_index = 0;
829 tree parm;
831 if (bitmap_bit_p (final_bbs, bb->index))
832 return;
834 for (parm = DECL_ARGUMENTS (current_function_decl);
835 parm && parm != base;
836 parm = DECL_CHAIN (parm))
837 parm_index++;
839 gcc_assert (parm_index < func_param_count);
841 idx = bb->index * func_param_count + parm_index;
842 if (bb_dereferences[idx] < dist)
843 bb_dereferences[idx] = dist;
846 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
847 the three fields. Also add it to the vector of accesses corresponding to
848 the base. Finally, return the new access. */
850 static struct access *
851 create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
853 vec<access_p> *v;
854 struct access *access;
855 void **slot;
857 access = (struct access *) pool_alloc (access_pool);
858 memset (access, 0, sizeof (struct access));
859 access->base = base;
860 access->offset = offset;
861 access->size = size;
863 slot = pointer_map_contains (base_access_vec, base);
864 if (slot)
865 v = (vec<access_p> *) *slot;
866 else
867 vec_alloc (v, 32);
869 v->safe_push (access);
871 *((vec<access_p> **)
872 pointer_map_insert (base_access_vec, base)) = v;
874 return access;
877 /* Create and insert access for EXPR. Return created access, or NULL if it is
878 not possible. */
880 static struct access *
881 create_access (tree expr, gimple stmt, bool write)
883 struct access *access;
884 HOST_WIDE_INT offset, size, max_size;
885 tree base = expr;
886 bool ptr, unscalarizable_region = false;
888 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
890 if (sra_mode == SRA_MODE_EARLY_IPA
891 && TREE_CODE (base) == MEM_REF)
893 base = get_ssa_base_param (TREE_OPERAND (base, 0));
894 if (!base)
895 return NULL;
896 ptr = true;
898 else
899 ptr = false;
901 if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
902 return NULL;
904 if (sra_mode == SRA_MODE_EARLY_IPA)
906 if (size < 0 || size != max_size)
908 disqualify_candidate (base, "Encountered a variable sized access.");
909 return NULL;
911 if (TREE_CODE (expr) == COMPONENT_REF
912 && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))
914 disqualify_candidate (base, "Encountered a bit-field access.");
915 return NULL;
917 gcc_checking_assert ((offset % BITS_PER_UNIT) == 0);
919 if (ptr)
920 mark_parm_dereference (base, offset + size, stmt);
922 else
924 if (size != max_size)
926 size = max_size;
927 unscalarizable_region = true;
929 if (size < 0)
931 disqualify_candidate (base, "Encountered an unconstrained access.");
932 return NULL;
936 access = create_access_1 (base, offset, size);
937 access->expr = expr;
938 access->type = TREE_TYPE (expr);
939 access->write = write;
940 access->grp_unscalarizable_region = unscalarizable_region;
941 access->stmt = stmt;
943 if (TREE_CODE (expr) == COMPONENT_REF
944 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1)))
945 access->non_addressable = 1;
947 return access;
951 /* Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple
952 register types or (recursively) records with only these two kinds of fields.
953 It also returns false if any of these records contains a bit-field. */
955 static bool
956 type_consists_of_records_p (tree type)
958 tree fld;
960 if (TREE_CODE (type) != RECORD_TYPE)
961 return false;
963 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
964 if (TREE_CODE (fld) == FIELD_DECL)
966 tree ft = TREE_TYPE (fld);
968 if (DECL_BIT_FIELD (fld))
969 return false;
971 if (!is_gimple_reg_type (ft)
972 && !type_consists_of_records_p (ft))
973 return false;
976 return true;
979 /* Create total_scalarization accesses for all scalar type fields in DECL that
980 must be of a RECORD_TYPE conforming to type_consists_of_records_p. BASE
981 must be the top-most VAR_DECL representing the variable, OFFSET must be the
982 offset of DECL within BASE. REF must be the memory reference expression for
983 the given decl. */
985 static void
986 completely_scalarize_record (tree base, tree decl, HOST_WIDE_INT offset,
987 tree ref)
989 tree fld, decl_type = TREE_TYPE (decl);
991 for (fld = TYPE_FIELDS (decl_type); fld; fld = DECL_CHAIN (fld))
992 if (TREE_CODE (fld) == FIELD_DECL)
994 HOST_WIDE_INT pos = offset + int_bit_position (fld);
995 tree ft = TREE_TYPE (fld);
996 tree nref = build3 (COMPONENT_REF, TREE_TYPE (fld), ref, fld,
997 NULL_TREE);
999 if (is_gimple_reg_type (ft))
1001 struct access *access;
1002 HOST_WIDE_INT size;
1004 size = tree_to_uhwi (DECL_SIZE (fld));
1005 access = create_access_1 (base, pos, size);
1006 access->expr = nref;
1007 access->type = ft;
1008 access->grp_total_scalarization = 1;
1009 /* Accesses for intraprocedural SRA can have their stmt NULL. */
1011 else
1012 completely_scalarize_record (base, fld, pos, nref);
1016 /* Create total_scalarization accesses for all scalar type fields in VAR and
1017 for VAR a a whole. VAR must be of a RECORD_TYPE conforming to
1018 type_consists_of_records_p. */
1020 static void
1021 completely_scalarize_var (tree var)
1023 HOST_WIDE_INT size = tree_to_uhwi (DECL_SIZE (var));
1024 struct access *access;
1026 access = create_access_1 (var, 0, size);
1027 access->expr = var;
1028 access->type = TREE_TYPE (var);
1029 access->grp_total_scalarization = 1;
1031 completely_scalarize_record (var, var, 0, var);
1034 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1036 static inline bool
1037 contains_view_convert_expr_p (const_tree ref)
1039 while (handled_component_p (ref))
1041 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
1042 return true;
1043 ref = TREE_OPERAND (ref, 0);
1046 return false;
1049 /* Search the given tree for a declaration by skipping handled components and
1050 exclude it from the candidates. */
1052 static void
1053 disqualify_base_of_expr (tree t, const char *reason)
1055 t = get_base_address (t);
1056 if (sra_mode == SRA_MODE_EARLY_IPA
1057 && TREE_CODE (t) == MEM_REF)
1058 t = get_ssa_base_param (TREE_OPERAND (t, 0));
1060 if (t && DECL_P (t))
1061 disqualify_candidate (t, reason);
1064 /* Scan expression EXPR and create access structures for all accesses to
1065 candidates for scalarization. Return the created access or NULL if none is
1066 created. */
1068 static struct access *
1069 build_access_from_expr_1 (tree expr, gimple stmt, bool write)
1071 struct access *ret = NULL;
1072 bool partial_ref;
1074 if (TREE_CODE (expr) == BIT_FIELD_REF
1075 || TREE_CODE (expr) == IMAGPART_EXPR
1076 || TREE_CODE (expr) == REALPART_EXPR)
1078 expr = TREE_OPERAND (expr, 0);
1079 partial_ref = true;
1081 else
1082 partial_ref = false;
1084 /* We need to dive through V_C_Es in order to get the size of its parameter
1085 and not the result type. Ada produces such statements. We are also
1086 capable of handling the topmost V_C_E but not any of those buried in other
1087 handled components. */
1088 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
1089 expr = TREE_OPERAND (expr, 0);
1091 if (contains_view_convert_expr_p (expr))
1093 disqualify_base_of_expr (expr, "V_C_E under a different handled "
1094 "component.");
1095 return NULL;
1097 if (TREE_THIS_VOLATILE (expr))
1099 disqualify_base_of_expr (expr, "part of a volatile reference.");
1100 return NULL;
1103 switch (TREE_CODE (expr))
1105 case MEM_REF:
1106 if (TREE_CODE (TREE_OPERAND (expr, 0)) != ADDR_EXPR
1107 && sra_mode != SRA_MODE_EARLY_IPA)
1108 return NULL;
1109 /* fall through */
1110 case VAR_DECL:
1111 case PARM_DECL:
1112 case RESULT_DECL:
1113 case COMPONENT_REF:
1114 case ARRAY_REF:
1115 case ARRAY_RANGE_REF:
1116 ret = create_access (expr, stmt, write);
1117 break;
1119 default:
1120 break;
1123 if (write && partial_ref && ret)
1124 ret->grp_partial_lhs = 1;
1126 return ret;
1129 /* Scan expression EXPR and create access structures for all accesses to
1130 candidates for scalarization. Return true if any access has been inserted.
1131 STMT must be the statement from which the expression is taken, WRITE must be
1132 true if the expression is a store and false otherwise. */
1134 static bool
1135 build_access_from_expr (tree expr, gimple stmt, bool write)
1137 struct access *access;
1139 access = build_access_from_expr_1 (expr, stmt, write);
1140 if (access)
1142 /* This means the aggregate is accesses as a whole in a way other than an
1143 assign statement and thus cannot be removed even if we had a scalar
1144 replacement for everything. */
1145 if (cannot_scalarize_away_bitmap)
1146 bitmap_set_bit (cannot_scalarize_away_bitmap, DECL_UID (access->base));
1147 return true;
1149 return false;
1152 /* Disqualify LHS and RHS for scalarization if STMT must end its basic block in
1153 modes in which it matters, return true iff they have been disqualified. RHS
1154 may be NULL, in that case ignore it. If we scalarize an aggregate in
1155 intra-SRA we may need to add statements after each statement. This is not
1156 possible if a statement unconditionally has to end the basic block. */
1157 static bool
1158 disqualify_ops_if_throwing_stmt (gimple stmt, tree lhs, tree rhs)
1160 if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1161 && (stmt_can_throw_internal (stmt) || stmt_ends_bb_p (stmt)))
1163 disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
1164 if (rhs)
1165 disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
1166 return true;
1168 return false;
1171 /* Scan expressions occurring in STMT, create access structures for all accesses
1172 to candidates for scalarization and remove those candidates which occur in
1173 statements or expressions that prevent them from being split apart. Return
1174 true if any access has been inserted. */
1176 static bool
1177 build_accesses_from_assign (gimple stmt)
1179 tree lhs, rhs;
1180 struct access *lacc, *racc;
1182 if (!gimple_assign_single_p (stmt)
1183 /* Scope clobbers don't influence scalarization. */
1184 || gimple_clobber_p (stmt))
1185 return false;
1187 lhs = gimple_assign_lhs (stmt);
1188 rhs = gimple_assign_rhs1 (stmt);
1190 if (disqualify_ops_if_throwing_stmt (stmt, lhs, rhs))
1191 return false;
1193 racc = build_access_from_expr_1 (rhs, stmt, false);
1194 lacc = build_access_from_expr_1 (lhs, stmt, true);
1196 if (lacc)
1197 lacc->grp_assignment_write = 1;
1199 if (racc)
1201 racc->grp_assignment_read = 1;
1202 if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
1203 && !is_gimple_reg_type (racc->type))
1204 bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
1207 if (lacc && racc
1208 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1209 && !lacc->grp_unscalarizable_region
1210 && !racc->grp_unscalarizable_region
1211 && AGGREGATE_TYPE_P (TREE_TYPE (lhs))
1212 && lacc->size == racc->size
1213 && useless_type_conversion_p (lacc->type, racc->type))
1215 struct assign_link *link;
1217 link = (struct assign_link *) pool_alloc (link_pool);
1218 memset (link, 0, sizeof (struct assign_link));
1220 link->lacc = lacc;
1221 link->racc = racc;
1223 add_link_to_rhs (racc, link);
1226 return lacc || racc;
1229 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1230 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1232 static bool
1233 asm_visit_addr (gimple, tree op, tree, void *)
1235 op = get_base_address (op);
1236 if (op
1237 && DECL_P (op))
1238 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
1240 return false;
1243 /* Return true iff callsite CALL has at least as many actual arguments as there
1244 are formal parameters of the function currently processed by IPA-SRA and
1245 that their types match. */
1247 static inline bool
1248 callsite_arguments_match_p (gimple call)
1250 if (gimple_call_num_args (call) < (unsigned) func_param_count)
1251 return false;
1253 tree parm;
1254 int i;
1255 for (parm = DECL_ARGUMENTS (current_function_decl), i = 0;
1256 parm;
1257 parm = DECL_CHAIN (parm), i++)
1259 tree arg = gimple_call_arg (call, i);
1260 if (!useless_type_conversion_p (TREE_TYPE (parm), TREE_TYPE (arg)))
1261 return false;
1263 return true;
1266 /* Scan function and look for interesting expressions and create access
1267 structures for them. Return true iff any access is created. */
1269 static bool
1270 scan_function (void)
1272 basic_block bb;
1273 bool ret = false;
1275 FOR_EACH_BB_FN (bb, cfun)
1277 gimple_stmt_iterator gsi;
1278 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1280 gimple stmt = gsi_stmt (gsi);
1281 tree t;
1282 unsigned i;
1284 if (final_bbs && stmt_can_throw_external (stmt))
1285 bitmap_set_bit (final_bbs, bb->index);
1286 switch (gimple_code (stmt))
1288 case GIMPLE_RETURN:
1289 t = gimple_return_retval (stmt);
1290 if (t != NULL_TREE)
1291 ret |= build_access_from_expr (t, stmt, false);
1292 if (final_bbs)
1293 bitmap_set_bit (final_bbs, bb->index);
1294 break;
1296 case GIMPLE_ASSIGN:
1297 ret |= build_accesses_from_assign (stmt);
1298 break;
1300 case GIMPLE_CALL:
1301 for (i = 0; i < gimple_call_num_args (stmt); i++)
1302 ret |= build_access_from_expr (gimple_call_arg (stmt, i),
1303 stmt, false);
1305 if (sra_mode == SRA_MODE_EARLY_IPA)
1307 tree dest = gimple_call_fndecl (stmt);
1308 int flags = gimple_call_flags (stmt);
1310 if (dest)
1312 if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1313 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1314 encountered_apply_args = true;
1315 if (recursive_call_p (current_function_decl, dest))
1317 encountered_recursive_call = true;
1318 if (!callsite_arguments_match_p (stmt))
1319 encountered_unchangable_recursive_call = true;
1323 if (final_bbs
1324 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1325 bitmap_set_bit (final_bbs, bb->index);
1328 t = gimple_call_lhs (stmt);
1329 if (t && !disqualify_ops_if_throwing_stmt (stmt, t, NULL))
1330 ret |= build_access_from_expr (t, stmt, true);
1331 break;
1333 case GIMPLE_ASM:
1334 walk_stmt_load_store_addr_ops (stmt, NULL, NULL, NULL,
1335 asm_visit_addr);
1336 if (final_bbs)
1337 bitmap_set_bit (final_bbs, bb->index);
1339 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
1341 t = TREE_VALUE (gimple_asm_input_op (stmt, i));
1342 ret |= build_access_from_expr (t, stmt, false);
1344 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
1346 t = TREE_VALUE (gimple_asm_output_op (stmt, i));
1347 ret |= build_access_from_expr (t, stmt, true);
1349 break;
1351 default:
1352 break;
1357 return ret;
1360 /* Helper of QSORT function. There are pointers to accesses in the array. An
1361 access is considered smaller than another if it has smaller offset or if the
1362 offsets are the same but is size is bigger. */
1364 static int
1365 compare_access_positions (const void *a, const void *b)
1367 const access_p *fp1 = (const access_p *) a;
1368 const access_p *fp2 = (const access_p *) b;
1369 const access_p f1 = *fp1;
1370 const access_p f2 = *fp2;
1372 if (f1->offset != f2->offset)
1373 return f1->offset < f2->offset ? -1 : 1;
1375 if (f1->size == f2->size)
1377 if (f1->type == f2->type)
1378 return 0;
1379 /* Put any non-aggregate type before any aggregate type. */
1380 else if (!is_gimple_reg_type (f1->type)
1381 && is_gimple_reg_type (f2->type))
1382 return 1;
1383 else if (is_gimple_reg_type (f1->type)
1384 && !is_gimple_reg_type (f2->type))
1385 return -1;
1386 /* Put any complex or vector type before any other scalar type. */
1387 else if (TREE_CODE (f1->type) != COMPLEX_TYPE
1388 && TREE_CODE (f1->type) != VECTOR_TYPE
1389 && (TREE_CODE (f2->type) == COMPLEX_TYPE
1390 || TREE_CODE (f2->type) == VECTOR_TYPE))
1391 return 1;
1392 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
1393 || TREE_CODE (f1->type) == VECTOR_TYPE)
1394 && TREE_CODE (f2->type) != COMPLEX_TYPE
1395 && TREE_CODE (f2->type) != VECTOR_TYPE)
1396 return -1;
1397 /* Put the integral type with the bigger precision first. */
1398 else if (INTEGRAL_TYPE_P (f1->type)
1399 && INTEGRAL_TYPE_P (f2->type))
1400 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
1401 /* Put any integral type with non-full precision last. */
1402 else if (INTEGRAL_TYPE_P (f1->type)
1403 && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type))
1404 != TYPE_PRECISION (f1->type)))
1405 return 1;
1406 else if (INTEGRAL_TYPE_P (f2->type)
1407 && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type))
1408 != TYPE_PRECISION (f2->type)))
1409 return -1;
1410 /* Stabilize the sort. */
1411 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1414 /* We want the bigger accesses first, thus the opposite operator in the next
1415 line: */
1416 return f1->size > f2->size ? -1 : 1;
1420 /* Append a name of the declaration to the name obstack. A helper function for
1421 make_fancy_name. */
1423 static void
1424 make_fancy_decl_name (tree decl)
1426 char buffer[32];
1428 tree name = DECL_NAME (decl);
1429 if (name)
1430 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1431 IDENTIFIER_LENGTH (name));
1432 else
1434 sprintf (buffer, "D%u", DECL_UID (decl));
1435 obstack_grow (&name_obstack, buffer, strlen (buffer));
1439 /* Helper for make_fancy_name. */
1441 static void
1442 make_fancy_name_1 (tree expr)
1444 char buffer[32];
1445 tree index;
1447 if (DECL_P (expr))
1449 make_fancy_decl_name (expr);
1450 return;
1453 switch (TREE_CODE (expr))
1455 case COMPONENT_REF:
1456 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1457 obstack_1grow (&name_obstack, '$');
1458 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1459 break;
1461 case ARRAY_REF:
1462 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1463 obstack_1grow (&name_obstack, '$');
1464 /* Arrays with only one element may not have a constant as their
1465 index. */
1466 index = TREE_OPERAND (expr, 1);
1467 if (TREE_CODE (index) != INTEGER_CST)
1468 break;
1469 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1470 obstack_grow (&name_obstack, buffer, strlen (buffer));
1471 break;
1473 case ADDR_EXPR:
1474 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1475 break;
1477 case MEM_REF:
1478 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1479 if (!integer_zerop (TREE_OPERAND (expr, 1)))
1481 obstack_1grow (&name_obstack, '$');
1482 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC,
1483 TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)));
1484 obstack_grow (&name_obstack, buffer, strlen (buffer));
1486 break;
1488 case BIT_FIELD_REF:
1489 case REALPART_EXPR:
1490 case IMAGPART_EXPR:
1491 gcc_unreachable (); /* we treat these as scalars. */
1492 break;
1493 default:
1494 break;
1498 /* Create a human readable name for replacement variable of ACCESS. */
1500 static char *
1501 make_fancy_name (tree expr)
1503 make_fancy_name_1 (expr);
1504 obstack_1grow (&name_obstack, '\0');
1505 return XOBFINISH (&name_obstack, char *);
1508 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1509 EXP_TYPE at the given OFFSET. If BASE is something for which
1510 get_addr_base_and_unit_offset returns NULL, gsi must be non-NULL and is used
1511 to insert new statements either before or below the current one as specified
1512 by INSERT_AFTER. This function is not capable of handling bitfields.
1514 BASE must be either a declaration or a memory reference that has correct
1515 alignment ifformation embeded in it (e.g. a pre-existing one in SRA). */
1517 tree
1518 build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
1519 tree exp_type, gimple_stmt_iterator *gsi,
1520 bool insert_after)
1522 tree prev_base = base;
1523 tree off;
1524 tree mem_ref;
1525 HOST_WIDE_INT base_offset;
1526 unsigned HOST_WIDE_INT misalign;
1527 unsigned int align;
1529 gcc_checking_assert (offset % BITS_PER_UNIT == 0);
1530 get_object_alignment_1 (base, &align, &misalign);
1531 base = get_addr_base_and_unit_offset (base, &base_offset);
1533 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1534 offset such as array[var_index]. */
1535 if (!base)
1537 gimple stmt;
1538 tree tmp, addr;
1540 gcc_checking_assert (gsi);
1541 tmp = make_ssa_name (build_pointer_type (TREE_TYPE (prev_base)), NULL);
1542 addr = build_fold_addr_expr (unshare_expr (prev_base));
1543 STRIP_USELESS_TYPE_CONVERSION (addr);
1544 stmt = gimple_build_assign (tmp, addr);
1545 gimple_set_location (stmt, loc);
1546 if (insert_after)
1547 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
1548 else
1549 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1551 off = build_int_cst (reference_alias_ptr_type (prev_base),
1552 offset / BITS_PER_UNIT);
1553 base = tmp;
1555 else if (TREE_CODE (base) == MEM_REF)
1557 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1558 base_offset + offset / BITS_PER_UNIT);
1559 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1560 base = unshare_expr (TREE_OPERAND (base, 0));
1562 else
1564 off = build_int_cst (reference_alias_ptr_type (base),
1565 base_offset + offset / BITS_PER_UNIT);
1566 base = build_fold_addr_expr (unshare_expr (base));
1569 misalign = (misalign + offset) & (align - 1);
1570 if (misalign != 0)
1571 align = (misalign & -misalign);
1572 if (align < TYPE_ALIGN (exp_type))
1573 exp_type = build_aligned_type (exp_type, align);
1575 mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off);
1576 if (TREE_THIS_VOLATILE (prev_base))
1577 TREE_THIS_VOLATILE (mem_ref) = 1;
1578 if (TREE_SIDE_EFFECTS (prev_base))
1579 TREE_SIDE_EFFECTS (mem_ref) = 1;
1580 return mem_ref;
1583 /* Construct a memory reference to a part of an aggregate BASE at the given
1584 OFFSET and of the same type as MODEL. In case this is a reference to a
1585 bit-field, the function will replicate the last component_ref of model's
1586 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1587 build_ref_for_offset. */
1589 static tree
1590 build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1591 struct access *model, gimple_stmt_iterator *gsi,
1592 bool insert_after)
1594 if (TREE_CODE (model->expr) == COMPONENT_REF
1595 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1597 /* This access represents a bit-field. */
1598 tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
1600 offset -= int_bit_position (fld);
1601 exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
1602 t = build_ref_for_offset (loc, base, offset, exp_type, gsi, insert_after);
1603 return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
1604 NULL_TREE);
1606 else
1607 return build_ref_for_offset (loc, base, offset, model->type,
1608 gsi, insert_after);
1611 /* Attempt to build a memory reference that we could but into a gimple
1612 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1613 create statements and return s NULL instead. This function also ignores
1614 alignment issues and so its results should never end up in non-debug
1615 statements. */
1617 static tree
1618 build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1619 struct access *model)
1621 HOST_WIDE_INT base_offset;
1622 tree off;
1624 if (TREE_CODE (model->expr) == COMPONENT_REF
1625 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1626 return NULL_TREE;
1628 base = get_addr_base_and_unit_offset (base, &base_offset);
1629 if (!base)
1630 return NULL_TREE;
1631 if (TREE_CODE (base) == MEM_REF)
1633 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1634 base_offset + offset / BITS_PER_UNIT);
1635 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1636 base = unshare_expr (TREE_OPERAND (base, 0));
1638 else
1640 off = build_int_cst (reference_alias_ptr_type (base),
1641 base_offset + offset / BITS_PER_UNIT);
1642 base = build_fold_addr_expr (unshare_expr (base));
1645 return fold_build2_loc (loc, MEM_REF, model->type, base, off);
1648 /* Construct a memory reference consisting of component_refs and array_refs to
1649 a part of an aggregate *RES (which is of type TYPE). The requested part
1650 should have type EXP_TYPE at be the given OFFSET. This function might not
1651 succeed, it returns true when it does and only then *RES points to something
1652 meaningful. This function should be used only to build expressions that we
1653 might need to present to user (e.g. in warnings). In all other situations,
1654 build_ref_for_model or build_ref_for_offset should be used instead. */
1656 static bool
1657 build_user_friendly_ref_for_offset (tree *res, tree type, HOST_WIDE_INT offset,
1658 tree exp_type)
1660 while (1)
1662 tree fld;
1663 tree tr_size, index, minidx;
1664 HOST_WIDE_INT el_size;
1666 if (offset == 0 && exp_type
1667 && types_compatible_p (exp_type, type))
1668 return true;
1670 switch (TREE_CODE (type))
1672 case UNION_TYPE:
1673 case QUAL_UNION_TYPE:
1674 case RECORD_TYPE:
1675 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
1677 HOST_WIDE_INT pos, size;
1678 tree tr_pos, expr, *expr_ptr;
1680 if (TREE_CODE (fld) != FIELD_DECL)
1681 continue;
1683 tr_pos = bit_position (fld);
1684 if (!tr_pos || !tree_fits_uhwi_p (tr_pos))
1685 continue;
1686 pos = tree_to_uhwi (tr_pos);
1687 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1688 tr_size = DECL_SIZE (fld);
1689 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1690 continue;
1691 size = tree_to_uhwi (tr_size);
1692 if (size == 0)
1694 if (pos != offset)
1695 continue;
1697 else if (pos > offset || (pos + size) <= offset)
1698 continue;
1700 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1701 NULL_TREE);
1702 expr_ptr = &expr;
1703 if (build_user_friendly_ref_for_offset (expr_ptr, TREE_TYPE (fld),
1704 offset - pos, exp_type))
1706 *res = expr;
1707 return true;
1710 return false;
1712 case ARRAY_TYPE:
1713 tr_size = TYPE_SIZE (TREE_TYPE (type));
1714 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1715 return false;
1716 el_size = tree_to_uhwi (tr_size);
1718 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1719 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
1720 return false;
1721 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1722 if (!integer_zerop (minidx))
1723 index = int_const_binop (PLUS_EXPR, index, minidx);
1724 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1725 NULL_TREE, NULL_TREE);
1726 offset = offset % el_size;
1727 type = TREE_TYPE (type);
1728 break;
1730 default:
1731 if (offset != 0)
1732 return false;
1734 if (exp_type)
1735 return false;
1736 else
1737 return true;
1742 /* Return true iff TYPE is stdarg va_list type. */
1744 static inline bool
1745 is_va_list_type (tree type)
1747 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1750 /* Print message to dump file why a variable was rejected. */
1752 static void
1753 reject (tree var, const char *msg)
1755 if (dump_file && (dump_flags & TDF_DETAILS))
1757 fprintf (dump_file, "Rejected (%d): %s: ", DECL_UID (var), msg);
1758 print_generic_expr (dump_file, var, 0);
1759 fprintf (dump_file, "\n");
1763 /* Return true if VAR is a candidate for SRA. */
1765 static bool
1766 maybe_add_sra_candidate (tree var)
1768 tree type = TREE_TYPE (var);
1769 const char *msg;
1770 tree_node **slot;
1772 if (!AGGREGATE_TYPE_P (type))
1774 reject (var, "not aggregate");
1775 return false;
1777 if (needs_to_live_in_memory (var))
1779 reject (var, "needs to live in memory");
1780 return false;
1782 if (TREE_THIS_VOLATILE (var))
1784 reject (var, "is volatile");
1785 return false;
1787 if (!COMPLETE_TYPE_P (type))
1789 reject (var, "has incomplete type");
1790 return false;
1792 if (!tree_fits_uhwi_p (TYPE_SIZE (type)))
1794 reject (var, "type size not fixed");
1795 return false;
1797 if (tree_to_uhwi (TYPE_SIZE (type)) == 0)
1799 reject (var, "type size is zero");
1800 return false;
1802 if (type_internals_preclude_sra_p (type, &msg))
1804 reject (var, msg);
1805 return false;
1807 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1808 we also want to schedule it rather late. Thus we ignore it in
1809 the early pass. */
1810 (sra_mode == SRA_MODE_EARLY_INTRA
1811 && is_va_list_type (type)))
1813 reject (var, "is va_list");
1814 return false;
1817 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
1818 slot = candidates.find_slot_with_hash (var, DECL_UID (var), INSERT);
1819 *slot = var;
1821 if (dump_file && (dump_flags & TDF_DETAILS))
1823 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
1824 print_generic_expr (dump_file, var, 0);
1825 fprintf (dump_file, "\n");
1828 return true;
1831 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1832 those with type which is suitable for scalarization. */
1834 static bool
1835 find_var_candidates (void)
1837 tree var, parm;
1838 unsigned int i;
1839 bool ret = false;
1841 for (parm = DECL_ARGUMENTS (current_function_decl);
1842 parm;
1843 parm = DECL_CHAIN (parm))
1844 ret |= maybe_add_sra_candidate (parm);
1846 FOR_EACH_LOCAL_DECL (cfun, i, var)
1848 if (TREE_CODE (var) != VAR_DECL)
1849 continue;
1851 ret |= maybe_add_sra_candidate (var);
1854 return ret;
1857 /* Sort all accesses for the given variable, check for partial overlaps and
1858 return NULL if there are any. If there are none, pick a representative for
1859 each combination of offset and size and create a linked list out of them.
1860 Return the pointer to the first representative and make sure it is the first
1861 one in the vector of accesses. */
1863 static struct access *
1864 sort_and_splice_var_accesses (tree var)
1866 int i, j, access_count;
1867 struct access *res, **prev_acc_ptr = &res;
1868 vec<access_p> *access_vec;
1869 bool first = true;
1870 HOST_WIDE_INT low = -1, high = 0;
1872 access_vec = get_base_access_vector (var);
1873 if (!access_vec)
1874 return NULL;
1875 access_count = access_vec->length ();
1877 /* Sort by <OFFSET, SIZE>. */
1878 access_vec->qsort (compare_access_positions);
1880 i = 0;
1881 while (i < access_count)
1883 struct access *access = (*access_vec)[i];
1884 bool grp_write = access->write;
1885 bool grp_read = !access->write;
1886 bool grp_scalar_write = access->write
1887 && is_gimple_reg_type (access->type);
1888 bool grp_scalar_read = !access->write
1889 && is_gimple_reg_type (access->type);
1890 bool grp_assignment_read = access->grp_assignment_read;
1891 bool grp_assignment_write = access->grp_assignment_write;
1892 bool multiple_scalar_reads = false;
1893 bool total_scalarization = access->grp_total_scalarization;
1894 bool grp_partial_lhs = access->grp_partial_lhs;
1895 bool first_scalar = is_gimple_reg_type (access->type);
1896 bool unscalarizable_region = access->grp_unscalarizable_region;
1898 if (first || access->offset >= high)
1900 first = false;
1901 low = access->offset;
1902 high = access->offset + access->size;
1904 else if (access->offset > low && access->offset + access->size > high)
1905 return NULL;
1906 else
1907 gcc_assert (access->offset >= low
1908 && access->offset + access->size <= high);
1910 j = i + 1;
1911 while (j < access_count)
1913 struct access *ac2 = (*access_vec)[j];
1914 if (ac2->offset != access->offset || ac2->size != access->size)
1915 break;
1916 if (ac2->write)
1918 grp_write = true;
1919 grp_scalar_write = (grp_scalar_write
1920 || is_gimple_reg_type (ac2->type));
1922 else
1924 grp_read = true;
1925 if (is_gimple_reg_type (ac2->type))
1927 if (grp_scalar_read)
1928 multiple_scalar_reads = true;
1929 else
1930 grp_scalar_read = true;
1933 grp_assignment_read |= ac2->grp_assignment_read;
1934 grp_assignment_write |= ac2->grp_assignment_write;
1935 grp_partial_lhs |= ac2->grp_partial_lhs;
1936 unscalarizable_region |= ac2->grp_unscalarizable_region;
1937 total_scalarization |= ac2->grp_total_scalarization;
1938 relink_to_new_repr (access, ac2);
1940 /* If there are both aggregate-type and scalar-type accesses with
1941 this combination of size and offset, the comparison function
1942 should have put the scalars first. */
1943 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
1944 ac2->group_representative = access;
1945 j++;
1948 i = j;
1950 access->group_representative = access;
1951 access->grp_write = grp_write;
1952 access->grp_read = grp_read;
1953 access->grp_scalar_read = grp_scalar_read;
1954 access->grp_scalar_write = grp_scalar_write;
1955 access->grp_assignment_read = grp_assignment_read;
1956 access->grp_assignment_write = grp_assignment_write;
1957 access->grp_hint = multiple_scalar_reads || total_scalarization;
1958 access->grp_total_scalarization = total_scalarization;
1959 access->grp_partial_lhs = grp_partial_lhs;
1960 access->grp_unscalarizable_region = unscalarizable_region;
1961 if (access->first_link)
1962 add_access_to_work_queue (access);
1964 *prev_acc_ptr = access;
1965 prev_acc_ptr = &access->next_grp;
1968 gcc_assert (res == (*access_vec)[0]);
1969 return res;
1972 /* Create a variable for the given ACCESS which determines the type, name and a
1973 few other properties. Return the variable declaration and store it also to
1974 ACCESS->replacement. */
1976 static tree
1977 create_access_replacement (struct access *access)
1979 tree repl;
1981 if (access->grp_to_be_debug_replaced)
1983 repl = create_tmp_var_raw (access->type, NULL);
1984 DECL_CONTEXT (repl) = current_function_decl;
1986 else
1987 repl = create_tmp_var (access->type, "SR");
1988 if (TREE_CODE (access->type) == COMPLEX_TYPE
1989 || TREE_CODE (access->type) == VECTOR_TYPE)
1991 if (!access->grp_partial_lhs)
1992 DECL_GIMPLE_REG_P (repl) = 1;
1994 else if (access->grp_partial_lhs
1995 && is_gimple_reg_type (access->type))
1996 TREE_ADDRESSABLE (repl) = 1;
1998 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
1999 DECL_ARTIFICIAL (repl) = 1;
2000 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
2002 if (DECL_NAME (access->base)
2003 && !DECL_IGNORED_P (access->base)
2004 && !DECL_ARTIFICIAL (access->base))
2006 char *pretty_name = make_fancy_name (access->expr);
2007 tree debug_expr = unshare_expr_without_location (access->expr), d;
2008 bool fail = false;
2010 DECL_NAME (repl) = get_identifier (pretty_name);
2011 obstack_free (&name_obstack, pretty_name);
2013 /* Get rid of any SSA_NAMEs embedded in debug_expr,
2014 as DECL_DEBUG_EXPR isn't considered when looking for still
2015 used SSA_NAMEs and thus they could be freed. All debug info
2016 generation cares is whether something is constant or variable
2017 and that get_ref_base_and_extent works properly on the
2018 expression. It cannot handle accesses at a non-constant offset
2019 though, so just give up in those cases. */
2020 for (d = debug_expr;
2021 !fail && (handled_component_p (d) || TREE_CODE (d) == MEM_REF);
2022 d = TREE_OPERAND (d, 0))
2023 switch (TREE_CODE (d))
2025 case ARRAY_REF:
2026 case ARRAY_RANGE_REF:
2027 if (TREE_OPERAND (d, 1)
2028 && TREE_CODE (TREE_OPERAND (d, 1)) != INTEGER_CST)
2029 fail = true;
2030 if (TREE_OPERAND (d, 3)
2031 && TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST)
2032 fail = true;
2033 /* FALLTHRU */
2034 case COMPONENT_REF:
2035 if (TREE_OPERAND (d, 2)
2036 && TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST)
2037 fail = true;
2038 break;
2039 case MEM_REF:
2040 if (TREE_CODE (TREE_OPERAND (d, 0)) != ADDR_EXPR)
2041 fail = true;
2042 else
2043 d = TREE_OPERAND (d, 0);
2044 break;
2045 default:
2046 break;
2048 if (!fail)
2050 SET_DECL_DEBUG_EXPR (repl, debug_expr);
2051 DECL_HAS_DEBUG_EXPR_P (repl) = 1;
2053 if (access->grp_no_warning)
2054 TREE_NO_WARNING (repl) = 1;
2055 else
2056 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
2058 else
2059 TREE_NO_WARNING (repl) = 1;
2061 if (dump_file)
2063 if (access->grp_to_be_debug_replaced)
2065 fprintf (dump_file, "Created a debug-only replacement for ");
2066 print_generic_expr (dump_file, access->base, 0);
2067 fprintf (dump_file, " offset: %u, size: %u\n",
2068 (unsigned) access->offset, (unsigned) access->size);
2070 else
2072 fprintf (dump_file, "Created a replacement for ");
2073 print_generic_expr (dump_file, access->base, 0);
2074 fprintf (dump_file, " offset: %u, size: %u: ",
2075 (unsigned) access->offset, (unsigned) access->size);
2076 print_generic_expr (dump_file, repl, 0);
2077 fprintf (dump_file, "\n");
2080 sra_stats.replacements++;
2082 return repl;
2085 /* Return ACCESS scalar replacement, create it if it does not exist yet. */
2087 static inline tree
2088 get_access_replacement (struct access *access)
2090 gcc_checking_assert (access->replacement_decl);
2091 return access->replacement_decl;
2095 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2096 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2097 to it is not "within" the root. Return false iff some accesses partially
2098 overlap. */
2100 static bool
2101 build_access_subtree (struct access **access)
2103 struct access *root = *access, *last_child = NULL;
2104 HOST_WIDE_INT limit = root->offset + root->size;
2106 *access = (*access)->next_grp;
2107 while (*access && (*access)->offset + (*access)->size <= limit)
2109 if (!last_child)
2110 root->first_child = *access;
2111 else
2112 last_child->next_sibling = *access;
2113 last_child = *access;
2115 if (!build_access_subtree (access))
2116 return false;
2119 if (*access && (*access)->offset < limit)
2120 return false;
2122 return true;
2125 /* Build a tree of access representatives, ACCESS is the pointer to the first
2126 one, others are linked in a list by the next_grp field. Return false iff
2127 some accesses partially overlap. */
2129 static bool
2130 build_access_trees (struct access *access)
2132 while (access)
2134 struct access *root = access;
2136 if (!build_access_subtree (&access))
2137 return false;
2138 root->next_grp = access;
2140 return true;
2143 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2144 array. */
2146 static bool
2147 expr_with_var_bounded_array_refs_p (tree expr)
2149 while (handled_component_p (expr))
2151 if (TREE_CODE (expr) == ARRAY_REF
2152 && !tree_fits_shwi_p (array_ref_low_bound (expr)))
2153 return true;
2154 expr = TREE_OPERAND (expr, 0);
2156 return false;
2159 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2160 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2161 sorts of access flags appropriately along the way, notably always set
2162 grp_read and grp_assign_read according to MARK_READ and grp_write when
2163 MARK_WRITE is true.
2165 Creating a replacement for a scalar access is considered beneficial if its
2166 grp_hint is set (this means we are either attempting total scalarization or
2167 there is more than one direct read access) or according to the following
2168 table:
2170 Access written to through a scalar type (once or more times)
2172 | Written to in an assignment statement
2174 | | Access read as scalar _once_
2175 | | |
2176 | | | Read in an assignment statement
2177 | | | |
2178 | | | | Scalarize Comment
2179 -----------------------------------------------------------------------------
2180 0 0 0 0 No access for the scalar
2181 0 0 0 1 No access for the scalar
2182 0 0 1 0 No Single read - won't help
2183 0 0 1 1 No The same case
2184 0 1 0 0 No access for the scalar
2185 0 1 0 1 No access for the scalar
2186 0 1 1 0 Yes s = *g; return s.i;
2187 0 1 1 1 Yes The same case as above
2188 1 0 0 0 No Won't help
2189 1 0 0 1 Yes s.i = 1; *g = s;
2190 1 0 1 0 Yes s.i = 5; g = s.i;
2191 1 0 1 1 Yes The same case as above
2192 1 1 0 0 No Won't help.
2193 1 1 0 1 Yes s.i = 1; *g = s;
2194 1 1 1 0 Yes s = *g; return s.i;
2195 1 1 1 1 Yes Any of the above yeses */
2197 static bool
2198 analyze_access_subtree (struct access *root, struct access *parent,
2199 bool allow_replacements)
2201 struct access *child;
2202 HOST_WIDE_INT limit = root->offset + root->size;
2203 HOST_WIDE_INT covered_to = root->offset;
2204 bool scalar = is_gimple_reg_type (root->type);
2205 bool hole = false, sth_created = false;
2207 if (parent)
2209 if (parent->grp_read)
2210 root->grp_read = 1;
2211 if (parent->grp_assignment_read)
2212 root->grp_assignment_read = 1;
2213 if (parent->grp_write)
2214 root->grp_write = 1;
2215 if (parent->grp_assignment_write)
2216 root->grp_assignment_write = 1;
2217 if (parent->grp_total_scalarization)
2218 root->grp_total_scalarization = 1;
2221 if (root->grp_unscalarizable_region)
2222 allow_replacements = false;
2224 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
2225 allow_replacements = false;
2227 for (child = root->first_child; child; child = child->next_sibling)
2229 hole |= covered_to < child->offset;
2230 sth_created |= analyze_access_subtree (child, root,
2231 allow_replacements && !scalar);
2233 root->grp_unscalarized_data |= child->grp_unscalarized_data;
2234 root->grp_total_scalarization &= child->grp_total_scalarization;
2235 if (child->grp_covered)
2236 covered_to += child->size;
2237 else
2238 hole = true;
2241 if (allow_replacements && scalar && !root->first_child
2242 && (root->grp_hint
2243 || ((root->grp_scalar_read || root->grp_assignment_read)
2244 && (root->grp_scalar_write || root->grp_assignment_write))))
2246 /* Always create access replacements that cover the whole access.
2247 For integral types this means the precision has to match.
2248 Avoid assumptions based on the integral type kind, too. */
2249 if (INTEGRAL_TYPE_P (root->type)
2250 && (TREE_CODE (root->type) != INTEGER_TYPE
2251 || TYPE_PRECISION (root->type) != root->size)
2252 /* But leave bitfield accesses alone. */
2253 && (TREE_CODE (root->expr) != COMPONENT_REF
2254 || !DECL_BIT_FIELD (TREE_OPERAND (root->expr, 1))))
2256 tree rt = root->type;
2257 gcc_assert ((root->offset % BITS_PER_UNIT) == 0
2258 && (root->size % BITS_PER_UNIT) == 0);
2259 root->type = build_nonstandard_integer_type (root->size,
2260 TYPE_UNSIGNED (rt));
2261 root->expr = build_ref_for_offset (UNKNOWN_LOCATION,
2262 root->base, root->offset,
2263 root->type, NULL, false);
2265 if (dump_file && (dump_flags & TDF_DETAILS))
2267 fprintf (dump_file, "Changing the type of a replacement for ");
2268 print_generic_expr (dump_file, root->base, 0);
2269 fprintf (dump_file, " offset: %u, size: %u ",
2270 (unsigned) root->offset, (unsigned) root->size);
2271 fprintf (dump_file, " to an integer.\n");
2275 root->grp_to_be_replaced = 1;
2276 root->replacement_decl = create_access_replacement (root);
2277 sth_created = true;
2278 hole = false;
2280 else
2282 if (allow_replacements
2283 && scalar && !root->first_child
2284 && (root->grp_scalar_write || root->grp_assignment_write)
2285 && !bitmap_bit_p (cannot_scalarize_away_bitmap,
2286 DECL_UID (root->base)))
2288 gcc_checking_assert (!root->grp_scalar_read
2289 && !root->grp_assignment_read);
2290 sth_created = true;
2291 if (MAY_HAVE_DEBUG_STMTS)
2293 root->grp_to_be_debug_replaced = 1;
2294 root->replacement_decl = create_access_replacement (root);
2298 if (covered_to < limit)
2299 hole = true;
2300 if (scalar)
2301 root->grp_total_scalarization = 0;
2304 if (!hole || root->grp_total_scalarization)
2305 root->grp_covered = 1;
2306 else if (root->grp_write || TREE_CODE (root->base) == PARM_DECL)
2307 root->grp_unscalarized_data = 1; /* not covered and written to */
2308 return sth_created;
2311 /* Analyze all access trees linked by next_grp by the means of
2312 analyze_access_subtree. */
2313 static bool
2314 analyze_access_trees (struct access *access)
2316 bool ret = false;
2318 while (access)
2320 if (analyze_access_subtree (access, NULL, true))
2321 ret = true;
2322 access = access->next_grp;
2325 return ret;
2328 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2329 SIZE would conflict with an already existing one. If exactly such a child
2330 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2332 static bool
2333 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
2334 HOST_WIDE_INT size, struct access **exact_match)
2336 struct access *child;
2338 for (child = lacc->first_child; child; child = child->next_sibling)
2340 if (child->offset == norm_offset && child->size == size)
2342 *exact_match = child;
2343 return true;
2346 if (child->offset < norm_offset + size
2347 && child->offset + child->size > norm_offset)
2348 return true;
2351 return false;
2354 /* Create a new child access of PARENT, with all properties just like MODEL
2355 except for its offset and with its grp_write false and grp_read true.
2356 Return the new access or NULL if it cannot be created. Note that this access
2357 is created long after all splicing and sorting, it's not located in any
2358 access vector and is automatically a representative of its group. */
2360 static struct access *
2361 create_artificial_child_access (struct access *parent, struct access *model,
2362 HOST_WIDE_INT new_offset)
2364 struct access *access;
2365 struct access **child;
2366 tree expr = parent->base;
2368 gcc_assert (!model->grp_unscalarizable_region);
2370 access = (struct access *) pool_alloc (access_pool);
2371 memset (access, 0, sizeof (struct access));
2372 if (!build_user_friendly_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
2373 model->type))
2375 access->grp_no_warning = true;
2376 expr = build_ref_for_model (EXPR_LOCATION (parent->base), parent->base,
2377 new_offset, model, NULL, false);
2380 access->base = parent->base;
2381 access->expr = expr;
2382 access->offset = new_offset;
2383 access->size = model->size;
2384 access->type = model->type;
2385 access->grp_write = true;
2386 access->grp_read = false;
2388 child = &parent->first_child;
2389 while (*child && (*child)->offset < new_offset)
2390 child = &(*child)->next_sibling;
2392 access->next_sibling = *child;
2393 *child = access;
2395 return access;
2399 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
2400 true if any new subaccess was created. Additionally, if RACC is a scalar
2401 access but LACC is not, change the type of the latter, if possible. */
2403 static bool
2404 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
2406 struct access *rchild;
2407 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
2408 bool ret = false;
2410 if (is_gimple_reg_type (lacc->type)
2411 || lacc->grp_unscalarizable_region
2412 || racc->grp_unscalarizable_region)
2413 return false;
2415 if (is_gimple_reg_type (racc->type))
2417 if (!lacc->first_child && !racc->first_child)
2419 tree t = lacc->base;
2421 lacc->type = racc->type;
2422 if (build_user_friendly_ref_for_offset (&t, TREE_TYPE (t),
2423 lacc->offset, racc->type))
2424 lacc->expr = t;
2425 else
2427 lacc->expr = build_ref_for_model (EXPR_LOCATION (lacc->base),
2428 lacc->base, lacc->offset,
2429 racc, NULL, false);
2430 lacc->grp_no_warning = true;
2433 return false;
2436 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
2438 struct access *new_acc = NULL;
2439 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
2441 if (rchild->grp_unscalarizable_region)
2442 continue;
2444 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
2445 &new_acc))
2447 if (new_acc)
2449 rchild->grp_hint = 1;
2450 new_acc->grp_hint |= new_acc->grp_read;
2451 if (rchild->first_child)
2452 ret |= propagate_subaccesses_across_link (new_acc, rchild);
2454 continue;
2457 rchild->grp_hint = 1;
2458 new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
2459 if (new_acc)
2461 ret = true;
2462 if (racc->first_child)
2463 propagate_subaccesses_across_link (new_acc, rchild);
2467 return ret;
2470 /* Propagate all subaccesses across assignment links. */
2472 static void
2473 propagate_all_subaccesses (void)
2475 while (work_queue_head)
2477 struct access *racc = pop_access_from_work_queue ();
2478 struct assign_link *link;
2480 gcc_assert (racc->first_link);
2482 for (link = racc->first_link; link; link = link->next)
2484 struct access *lacc = link->lacc;
2486 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
2487 continue;
2488 lacc = lacc->group_representative;
2489 if (propagate_subaccesses_across_link (lacc, racc)
2490 && lacc->first_link)
2491 add_access_to_work_queue (lacc);
2496 /* Go through all accesses collected throughout the (intraprocedural) analysis
2497 stage, exclude overlapping ones, identify representatives and build trees
2498 out of them, making decisions about scalarization on the way. Return true
2499 iff there are any to-be-scalarized variables after this stage. */
2501 static bool
2502 analyze_all_variable_accesses (void)
2504 int res = 0;
2505 bitmap tmp = BITMAP_ALLOC (NULL);
2506 bitmap_iterator bi;
2507 unsigned i, max_total_scalarization_size;
2509 max_total_scalarization_size = UNITS_PER_WORD * BITS_PER_UNIT
2510 * MOVE_RATIO (optimize_function_for_speed_p (cfun));
2512 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
2513 if (bitmap_bit_p (should_scalarize_away_bitmap, i)
2514 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
2516 tree var = candidate (i);
2518 if (TREE_CODE (var) == VAR_DECL
2519 && type_consists_of_records_p (TREE_TYPE (var)))
2521 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var)))
2522 <= max_total_scalarization_size)
2524 completely_scalarize_var (var);
2525 if (dump_file && (dump_flags & TDF_DETAILS))
2527 fprintf (dump_file, "Will attempt to totally scalarize ");
2528 print_generic_expr (dump_file, var, 0);
2529 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2532 else if (dump_file && (dump_flags & TDF_DETAILS))
2534 fprintf (dump_file, "Too big to totally scalarize: ");
2535 print_generic_expr (dump_file, var, 0);
2536 fprintf (dump_file, " (UID: %u)\n", DECL_UID (var));
2541 bitmap_copy (tmp, candidate_bitmap);
2542 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2544 tree var = candidate (i);
2545 struct access *access;
2547 access = sort_and_splice_var_accesses (var);
2548 if (!access || !build_access_trees (access))
2549 disqualify_candidate (var,
2550 "No or inhibitingly overlapping accesses.");
2553 propagate_all_subaccesses ();
2555 bitmap_copy (tmp, candidate_bitmap);
2556 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2558 tree var = candidate (i);
2559 struct access *access = get_first_repr_for_decl (var);
2561 if (analyze_access_trees (access))
2563 res++;
2564 if (dump_file && (dump_flags & TDF_DETAILS))
2566 fprintf (dump_file, "\nAccess trees for ");
2567 print_generic_expr (dump_file, var, 0);
2568 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2569 dump_access_tree (dump_file, access);
2570 fprintf (dump_file, "\n");
2573 else
2574 disqualify_candidate (var, "No scalar replacements to be created.");
2577 BITMAP_FREE (tmp);
2579 if (res)
2581 statistics_counter_event (cfun, "Scalarized aggregates", res);
2582 return true;
2584 else
2585 return false;
2588 /* Generate statements copying scalar replacements of accesses within a subtree
2589 into or out of AGG. ACCESS, all its children, siblings and their children
2590 are to be processed. AGG is an aggregate type expression (can be a
2591 declaration but does not have to be, it can for example also be a mem_ref or
2592 a series of handled components). TOP_OFFSET is the offset of the processed
2593 subtree which has to be subtracted from offsets of individual accesses to
2594 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2595 replacements in the interval <start_offset, start_offset + chunk_size>,
2596 otherwise copy all. GSI is a statement iterator used to place the new
2597 statements. WRITE should be true when the statements should write from AGG
2598 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2599 statements will be added after the current statement in GSI, they will be
2600 added before the statement otherwise. */
2602 static void
2603 generate_subtree_copies (struct access *access, tree agg,
2604 HOST_WIDE_INT top_offset,
2605 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
2606 gimple_stmt_iterator *gsi, bool write,
2607 bool insert_after, location_t loc)
2611 if (chunk_size && access->offset >= start_offset + chunk_size)
2612 return;
2614 if (access->grp_to_be_replaced
2615 && (chunk_size == 0
2616 || access->offset + access->size > start_offset))
2618 tree expr, repl = get_access_replacement (access);
2619 gimple stmt;
2621 expr = build_ref_for_model (loc, agg, access->offset - top_offset,
2622 access, gsi, insert_after);
2624 if (write)
2626 if (access->grp_partial_lhs)
2627 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
2628 !insert_after,
2629 insert_after ? GSI_NEW_STMT
2630 : GSI_SAME_STMT);
2631 stmt = gimple_build_assign (repl, expr);
2633 else
2635 TREE_NO_WARNING (repl) = 1;
2636 if (access->grp_partial_lhs)
2637 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2638 !insert_after,
2639 insert_after ? GSI_NEW_STMT
2640 : GSI_SAME_STMT);
2641 stmt = gimple_build_assign (expr, repl);
2643 gimple_set_location (stmt, loc);
2645 if (insert_after)
2646 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2647 else
2648 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2649 update_stmt (stmt);
2650 sra_stats.subtree_copies++;
2652 else if (write
2653 && access->grp_to_be_debug_replaced
2654 && (chunk_size == 0
2655 || access->offset + access->size > start_offset))
2657 gimple ds;
2658 tree drhs = build_debug_ref_for_model (loc, agg,
2659 access->offset - top_offset,
2660 access);
2661 ds = gimple_build_debug_bind (get_access_replacement (access),
2662 drhs, gsi_stmt (*gsi));
2663 if (insert_after)
2664 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2665 else
2666 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2669 if (access->first_child)
2670 generate_subtree_copies (access->first_child, agg, top_offset,
2671 start_offset, chunk_size, gsi,
2672 write, insert_after, loc);
2674 access = access->next_sibling;
2676 while (access);
2679 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2680 the root of the subtree to be processed. GSI is the statement iterator used
2681 for inserting statements which are added after the current statement if
2682 INSERT_AFTER is true or before it otherwise. */
2684 static void
2685 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
2686 bool insert_after, location_t loc)
2689 struct access *child;
2691 if (access->grp_to_be_replaced)
2693 gimple stmt;
2695 stmt = gimple_build_assign (get_access_replacement (access),
2696 build_zero_cst (access->type));
2697 if (insert_after)
2698 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2699 else
2700 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2701 update_stmt (stmt);
2702 gimple_set_location (stmt, loc);
2704 else if (access->grp_to_be_debug_replaced)
2706 gimple ds = gimple_build_debug_bind (get_access_replacement (access),
2707 build_zero_cst (access->type),
2708 gsi_stmt (*gsi));
2709 if (insert_after)
2710 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2711 else
2712 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2715 for (child = access->first_child; child; child = child->next_sibling)
2716 init_subtree_with_zero (child, gsi, insert_after, loc);
2719 /* Search for an access representative for the given expression EXPR and
2720 return it or NULL if it cannot be found. */
2722 static struct access *
2723 get_access_for_expr (tree expr)
2725 HOST_WIDE_INT offset, size, max_size;
2726 tree base;
2728 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2729 a different size than the size of its argument and we need the latter
2730 one. */
2731 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
2732 expr = TREE_OPERAND (expr, 0);
2734 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
2735 if (max_size == -1 || !DECL_P (base))
2736 return NULL;
2738 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
2739 return NULL;
2741 return get_var_base_offset_size_access (base, offset, max_size);
2744 /* Replace the expression EXPR with a scalar replacement if there is one and
2745 generate other statements to do type conversion or subtree copying if
2746 necessary. GSI is used to place newly created statements, WRITE is true if
2747 the expression is being written to (it is on a LHS of a statement or output
2748 in an assembly statement). */
2750 static bool
2751 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
2753 location_t loc;
2754 struct access *access;
2755 tree type, bfr;
2757 if (TREE_CODE (*expr) == BIT_FIELD_REF)
2759 bfr = *expr;
2760 expr = &TREE_OPERAND (*expr, 0);
2762 else
2763 bfr = NULL_TREE;
2765 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
2766 expr = &TREE_OPERAND (*expr, 0);
2767 access = get_access_for_expr (*expr);
2768 if (!access)
2769 return false;
2770 type = TREE_TYPE (*expr);
2772 loc = gimple_location (gsi_stmt (*gsi));
2773 if (access->grp_to_be_replaced)
2775 tree repl = get_access_replacement (access);
2776 /* If we replace a non-register typed access simply use the original
2777 access expression to extract the scalar component afterwards.
2778 This happens if scalarizing a function return value or parameter
2779 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2780 gcc.c-torture/compile/20011217-1.c.
2782 We also want to use this when accessing a complex or vector which can
2783 be accessed as a different type too, potentially creating a need for
2784 type conversion (see PR42196) and when scalarized unions are involved
2785 in assembler statements (see PR42398). */
2786 if (!useless_type_conversion_p (type, access->type))
2788 tree ref;
2790 ref = build_ref_for_model (loc, access->base, access->offset, access,
2791 NULL, false);
2793 if (write)
2795 gimple stmt;
2797 if (access->grp_partial_lhs)
2798 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
2799 false, GSI_NEW_STMT);
2800 stmt = gimple_build_assign (repl, ref);
2801 gimple_set_location (stmt, loc);
2802 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2804 else
2806 gimple stmt;
2808 if (access->grp_partial_lhs)
2809 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2810 true, GSI_SAME_STMT);
2811 stmt = gimple_build_assign (ref, repl);
2812 gimple_set_location (stmt, loc);
2813 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2816 else
2817 *expr = repl;
2818 sra_stats.exprs++;
2820 else if (write && access->grp_to_be_debug_replaced)
2822 gimple ds = gimple_build_debug_bind (get_access_replacement (access),
2823 NULL_TREE,
2824 gsi_stmt (*gsi));
2825 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2828 if (access->first_child)
2830 HOST_WIDE_INT start_offset, chunk_size;
2831 if (bfr
2832 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 1))
2833 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 2)))
2835 chunk_size = tree_to_uhwi (TREE_OPERAND (bfr, 1));
2836 start_offset = access->offset
2837 + tree_to_uhwi (TREE_OPERAND (bfr, 2));
2839 else
2840 start_offset = chunk_size = 0;
2842 generate_subtree_copies (access->first_child, access->base, 0,
2843 start_offset, chunk_size, gsi, write, write,
2844 loc);
2846 return true;
2849 /* Where scalar replacements of the RHS have been written to when a replacement
2850 of a LHS of an assigments cannot be direclty loaded from a replacement of
2851 the RHS. */
2852 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
2853 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
2854 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
2856 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2857 base aggregate if there are unscalarized data or directly to LHS of the
2858 statement that is pointed to by GSI otherwise. */
2860 static enum unscalarized_data_handling
2861 handle_unscalarized_data_in_subtree (struct access *top_racc,
2862 gimple_stmt_iterator *gsi)
2864 if (top_racc->grp_unscalarized_data)
2866 generate_subtree_copies (top_racc->first_child, top_racc->base, 0, 0, 0,
2867 gsi, false, false,
2868 gimple_location (gsi_stmt (*gsi)));
2869 return SRA_UDH_RIGHT;
2871 else
2873 tree lhs = gimple_assign_lhs (gsi_stmt (*gsi));
2874 generate_subtree_copies (top_racc->first_child, lhs, top_racc->offset,
2875 0, 0, gsi, false, false,
2876 gimple_location (gsi_stmt (*gsi)));
2877 return SRA_UDH_LEFT;
2882 /* Try to generate statements to load all sub-replacements in an access subtree
2883 formed by children of LACC from scalar replacements in the TOP_RACC subtree.
2884 If that is not possible, refresh the TOP_RACC base aggregate and load the
2885 accesses from it. LEFT_OFFSET is the offset of the left whole subtree being
2886 copied. NEW_GSI is stmt iterator used for statement insertions after the
2887 original assignment, OLD_GSI is used to insert statements before the
2888 assignment. *REFRESHED keeps the information whether we have needed to
2889 refresh replacements of the LHS and from which side of the assignments this
2890 takes place. */
2892 static void
2893 load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
2894 HOST_WIDE_INT left_offset,
2895 gimple_stmt_iterator *old_gsi,
2896 gimple_stmt_iterator *new_gsi,
2897 enum unscalarized_data_handling *refreshed)
2899 location_t loc = gimple_location (gsi_stmt (*old_gsi));
2900 for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling)
2902 HOST_WIDE_INT offset = lacc->offset - left_offset + top_racc->offset;
2904 if (lacc->grp_to_be_replaced)
2906 struct access *racc;
2907 gimple stmt;
2908 tree rhs;
2910 racc = find_access_in_subtree (top_racc, offset, lacc->size);
2911 if (racc && racc->grp_to_be_replaced)
2913 rhs = get_access_replacement (racc);
2914 if (!useless_type_conversion_p (lacc->type, racc->type))
2915 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, lacc->type, rhs);
2917 if (racc->grp_partial_lhs && lacc->grp_partial_lhs)
2918 rhs = force_gimple_operand_gsi (old_gsi, rhs, true, NULL_TREE,
2919 true, GSI_SAME_STMT);
2921 else
2923 /* No suitable access on the right hand side, need to load from
2924 the aggregate. See if we have to update it first... */
2925 if (*refreshed == SRA_UDH_NONE)
2926 *refreshed = handle_unscalarized_data_in_subtree (top_racc,
2927 old_gsi);
2929 if (*refreshed == SRA_UDH_LEFT)
2930 rhs = build_ref_for_model (loc, lacc->base, lacc->offset, lacc,
2931 new_gsi, true);
2932 else
2933 rhs = build_ref_for_model (loc, top_racc->base, offset, lacc,
2934 new_gsi, true);
2935 if (lacc->grp_partial_lhs)
2936 rhs = force_gimple_operand_gsi (new_gsi, rhs, true, NULL_TREE,
2937 false, GSI_NEW_STMT);
2940 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
2941 gsi_insert_after (new_gsi, stmt, GSI_NEW_STMT);
2942 gimple_set_location (stmt, loc);
2943 update_stmt (stmt);
2944 sra_stats.subreplacements++;
2946 else
2948 if (*refreshed == SRA_UDH_NONE
2949 && lacc->grp_read && !lacc->grp_covered)
2950 *refreshed = handle_unscalarized_data_in_subtree (top_racc,
2951 old_gsi);
2952 if (lacc && lacc->grp_to_be_debug_replaced)
2954 gimple ds;
2955 tree drhs;
2956 struct access *racc = find_access_in_subtree (top_racc, offset,
2957 lacc->size);
2959 if (racc && racc->grp_to_be_replaced)
2961 if (racc->grp_write)
2962 drhs = get_access_replacement (racc);
2963 else
2964 drhs = NULL;
2966 else if (*refreshed == SRA_UDH_LEFT)
2967 drhs = build_debug_ref_for_model (loc, lacc->base, lacc->offset,
2968 lacc);
2969 else if (*refreshed == SRA_UDH_RIGHT)
2970 drhs = build_debug_ref_for_model (loc, top_racc->base, offset,
2971 lacc);
2972 else
2973 drhs = NULL_TREE;
2974 if (drhs
2975 && !useless_type_conversion_p (lacc->type, TREE_TYPE (drhs)))
2976 drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
2977 lacc->type, drhs);
2978 ds = gimple_build_debug_bind (get_access_replacement (lacc),
2979 drhs, gsi_stmt (*old_gsi));
2980 gsi_insert_after (new_gsi, ds, GSI_NEW_STMT);
2984 if (lacc->first_child)
2985 load_assign_lhs_subreplacements (lacc, top_racc, left_offset,
2986 old_gsi, new_gsi, refreshed);
2990 /* Result code for SRA assignment modification. */
2991 enum assignment_mod_result { SRA_AM_NONE, /* nothing done for the stmt */
2992 SRA_AM_MODIFIED, /* stmt changed but not
2993 removed */
2994 SRA_AM_REMOVED }; /* stmt eliminated */
2996 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
2997 to the assignment and GSI is the statement iterator pointing at it. Returns
2998 the same values as sra_modify_assign. */
3000 static enum assignment_mod_result
3001 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3003 tree lhs = gimple_assign_lhs (*stmt);
3004 struct access *acc;
3005 location_t loc;
3007 acc = get_access_for_expr (lhs);
3008 if (!acc)
3009 return SRA_AM_NONE;
3011 if (gimple_clobber_p (*stmt))
3013 /* Remove clobbers of fully scalarized variables, otherwise
3014 do nothing. */
3015 if (acc->grp_covered)
3017 unlink_stmt_vdef (*stmt);
3018 gsi_remove (gsi, true);
3019 release_defs (*stmt);
3020 return SRA_AM_REMOVED;
3022 else
3023 return SRA_AM_NONE;
3026 loc = gimple_location (*stmt);
3027 if (vec_safe_length (CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt))) > 0)
3029 /* I have never seen this code path trigger but if it can happen the
3030 following should handle it gracefully. */
3031 if (access_has_children_p (acc))
3032 generate_subtree_copies (acc->first_child, acc->base, 0, 0, 0, gsi,
3033 true, true, loc);
3034 return SRA_AM_MODIFIED;
3037 if (acc->grp_covered)
3039 init_subtree_with_zero (acc, gsi, false, loc);
3040 unlink_stmt_vdef (*stmt);
3041 gsi_remove (gsi, true);
3042 release_defs (*stmt);
3043 return SRA_AM_REMOVED;
3045 else
3047 init_subtree_with_zero (acc, gsi, true, loc);
3048 return SRA_AM_MODIFIED;
3052 /* Create and return a new suitable default definition SSA_NAME for RACC which
3053 is an access describing an uninitialized part of an aggregate that is being
3054 loaded. */
3056 static tree
3057 get_repl_default_def_ssa_name (struct access *racc)
3059 gcc_checking_assert (!racc->grp_to_be_replaced
3060 && !racc->grp_to_be_debug_replaced);
3061 if (!racc->replacement_decl)
3062 racc->replacement_decl = create_access_replacement (racc);
3063 return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
3066 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3067 bit-field field declaration somewhere in it. */
3069 static inline bool
3070 contains_vce_or_bfcref_p (const_tree ref)
3072 while (handled_component_p (ref))
3074 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
3075 || (TREE_CODE (ref) == COMPONENT_REF
3076 && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
3077 return true;
3078 ref = TREE_OPERAND (ref, 0);
3081 return false;
3084 /* Examine both sides of the assignment statement pointed to by STMT, replace
3085 them with a scalare replacement if there is one and generate copying of
3086 replacements if scalarized aggregates have been used in the assignment. GSI
3087 is used to hold generated statements for type conversions and subtree
3088 copying. */
3090 static enum assignment_mod_result
3091 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3093 struct access *lacc, *racc;
3094 tree lhs, rhs;
3095 bool modify_this_stmt = false;
3096 bool force_gimple_rhs = false;
3097 location_t loc;
3098 gimple_stmt_iterator orig_gsi = *gsi;
3100 if (!gimple_assign_single_p (*stmt))
3101 return SRA_AM_NONE;
3102 lhs = gimple_assign_lhs (*stmt);
3103 rhs = gimple_assign_rhs1 (*stmt);
3105 if (TREE_CODE (rhs) == CONSTRUCTOR)
3106 return sra_modify_constructor_assign (stmt, gsi);
3108 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
3109 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
3110 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
3112 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (*stmt),
3113 gsi, false);
3114 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (*stmt),
3115 gsi, true);
3116 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3119 lacc = get_access_for_expr (lhs);
3120 racc = get_access_for_expr (rhs);
3121 if (!lacc && !racc)
3122 return SRA_AM_NONE;
3124 loc = gimple_location (*stmt);
3125 if (lacc && lacc->grp_to_be_replaced)
3127 lhs = get_access_replacement (lacc);
3128 gimple_assign_set_lhs (*stmt, lhs);
3129 modify_this_stmt = true;
3130 if (lacc->grp_partial_lhs)
3131 force_gimple_rhs = true;
3132 sra_stats.exprs++;
3135 if (racc && racc->grp_to_be_replaced)
3137 rhs = get_access_replacement (racc);
3138 modify_this_stmt = true;
3139 if (racc->grp_partial_lhs)
3140 force_gimple_rhs = true;
3141 sra_stats.exprs++;
3143 else if (racc
3144 && !racc->grp_unscalarized_data
3145 && TREE_CODE (lhs) == SSA_NAME
3146 && !access_has_replacements_p (racc))
3148 rhs = get_repl_default_def_ssa_name (racc);
3149 modify_this_stmt = true;
3150 sra_stats.exprs++;
3153 if (modify_this_stmt)
3155 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3157 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3158 ??? This should move to fold_stmt which we simply should
3159 call after building a VIEW_CONVERT_EXPR here. */
3160 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
3161 && !contains_bitfld_component_ref_p (lhs))
3163 lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
3164 gimple_assign_set_lhs (*stmt, lhs);
3166 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
3167 && !contains_vce_or_bfcref_p (rhs))
3168 rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
3170 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3172 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
3173 rhs);
3174 if (is_gimple_reg_type (TREE_TYPE (lhs))
3175 && TREE_CODE (lhs) != SSA_NAME)
3176 force_gimple_rhs = true;
3181 if (lacc && lacc->grp_to_be_debug_replaced)
3183 tree dlhs = get_access_replacement (lacc);
3184 tree drhs = unshare_expr (rhs);
3185 if (!useless_type_conversion_p (TREE_TYPE (dlhs), TREE_TYPE (drhs)))
3187 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs))
3188 && !contains_vce_or_bfcref_p (drhs))
3189 drhs = build_debug_ref_for_model (loc, drhs, 0, lacc);
3190 if (drhs
3191 && !useless_type_conversion_p (TREE_TYPE (dlhs),
3192 TREE_TYPE (drhs)))
3193 drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
3194 TREE_TYPE (dlhs), drhs);
3196 gimple ds = gimple_build_debug_bind (dlhs, drhs, *stmt);
3197 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3200 /* From this point on, the function deals with assignments in between
3201 aggregates when at least one has scalar reductions of some of its
3202 components. There are three possible scenarios: Both the LHS and RHS have
3203 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3205 In the first case, we would like to load the LHS components from RHS
3206 components whenever possible. If that is not possible, we would like to
3207 read it directly from the RHS (after updating it by storing in it its own
3208 components). If there are some necessary unscalarized data in the LHS,
3209 those will be loaded by the original assignment too. If neither of these
3210 cases happen, the original statement can be removed. Most of this is done
3211 by load_assign_lhs_subreplacements.
3213 In the second case, we would like to store all RHS scalarized components
3214 directly into LHS and if they cover the aggregate completely, remove the
3215 statement too. In the third case, we want the LHS components to be loaded
3216 directly from the RHS (DSE will remove the original statement if it
3217 becomes redundant).
3219 This is a bit complex but manageable when types match and when unions do
3220 not cause confusion in a way that we cannot really load a component of LHS
3221 from the RHS or vice versa (the access representing this level can have
3222 subaccesses that are accessible only through a different union field at a
3223 higher level - different from the one used in the examined expression).
3224 Unions are fun.
3226 Therefore, I specially handle a fourth case, happening when there is a
3227 specific type cast or it is impossible to locate a scalarized subaccess on
3228 the other side of the expression. If that happens, I simply "refresh" the
3229 RHS by storing in it is scalarized components leave the original statement
3230 there to do the copying and then load the scalar replacements of the LHS.
3231 This is what the first branch does. */
3233 if (modify_this_stmt
3234 || gimple_has_volatile_ops (*stmt)
3235 || contains_vce_or_bfcref_p (rhs)
3236 || contains_vce_or_bfcref_p (lhs))
3238 if (access_has_children_p (racc))
3239 generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
3240 gsi, false, false, loc);
3241 if (access_has_children_p (lacc))
3242 generate_subtree_copies (lacc->first_child, lacc->base, 0, 0, 0,
3243 gsi, true, true, loc);
3244 sra_stats.separate_lhs_rhs_handling++;
3246 /* This gimplification must be done after generate_subtree_copies,
3247 lest we insert the subtree copies in the middle of the gimplified
3248 sequence. */
3249 if (force_gimple_rhs)
3250 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
3251 true, GSI_SAME_STMT);
3252 if (gimple_assign_rhs1 (*stmt) != rhs)
3254 modify_this_stmt = true;
3255 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
3256 gcc_assert (*stmt == gsi_stmt (orig_gsi));
3259 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3261 else
3263 if (access_has_children_p (lacc)
3264 && access_has_children_p (racc)
3265 /* When an access represents an unscalarizable region, it usually
3266 represents accesses with variable offset and thus must not be used
3267 to generate new memory accesses. */
3268 && !lacc->grp_unscalarizable_region
3269 && !racc->grp_unscalarizable_region)
3271 gimple_stmt_iterator orig_gsi = *gsi;
3272 enum unscalarized_data_handling refreshed;
3274 if (lacc->grp_read && !lacc->grp_covered)
3275 refreshed = handle_unscalarized_data_in_subtree (racc, gsi);
3276 else
3277 refreshed = SRA_UDH_NONE;
3279 load_assign_lhs_subreplacements (lacc, racc, lacc->offset,
3280 &orig_gsi, gsi, &refreshed);
3281 if (refreshed != SRA_UDH_RIGHT)
3283 gsi_next (gsi);
3284 unlink_stmt_vdef (*stmt);
3285 gsi_remove (&orig_gsi, true);
3286 release_defs (*stmt);
3287 sra_stats.deleted++;
3288 return SRA_AM_REMOVED;
3291 else
3293 if (access_has_children_p (racc)
3294 && !racc->grp_unscalarized_data)
3296 if (dump_file)
3298 fprintf (dump_file, "Removing load: ");
3299 print_gimple_stmt (dump_file, *stmt, 0, 0);
3301 generate_subtree_copies (racc->first_child, lhs,
3302 racc->offset, 0, 0, gsi,
3303 false, false, loc);
3304 gcc_assert (*stmt == gsi_stmt (*gsi));
3305 unlink_stmt_vdef (*stmt);
3306 gsi_remove (gsi, true);
3307 release_defs (*stmt);
3308 sra_stats.deleted++;
3309 return SRA_AM_REMOVED;
3311 /* Restore the aggregate RHS from its components so the
3312 prevailing aggregate copy does the right thing. */
3313 if (access_has_children_p (racc))
3314 generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
3315 gsi, false, false, loc);
3316 /* Re-load the components of the aggregate copy destination.
3317 But use the RHS aggregate to load from to expose more
3318 optimization opportunities. */
3319 if (access_has_children_p (lacc))
3320 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
3321 0, 0, gsi, true, true, loc);
3324 return SRA_AM_NONE;
3328 /* Traverse the function body and all modifications as decided in
3329 analyze_all_variable_accesses. Return true iff the CFG has been
3330 changed. */
3332 static bool
3333 sra_modify_function_body (void)
3335 bool cfg_changed = false;
3336 basic_block bb;
3338 FOR_EACH_BB_FN (bb, cfun)
3340 gimple_stmt_iterator gsi = gsi_start_bb (bb);
3341 while (!gsi_end_p (gsi))
3343 gimple stmt = gsi_stmt (gsi);
3344 enum assignment_mod_result assign_result;
3345 bool modified = false, deleted = false;
3346 tree *t;
3347 unsigned i;
3349 switch (gimple_code (stmt))
3351 case GIMPLE_RETURN:
3352 t = gimple_return_retval_ptr (stmt);
3353 if (*t != NULL_TREE)
3354 modified |= sra_modify_expr (t, &gsi, false);
3355 break;
3357 case GIMPLE_ASSIGN:
3358 assign_result = sra_modify_assign (&stmt, &gsi);
3359 modified |= assign_result == SRA_AM_MODIFIED;
3360 deleted = assign_result == SRA_AM_REMOVED;
3361 break;
3363 case GIMPLE_CALL:
3364 /* Operands must be processed before the lhs. */
3365 for (i = 0; i < gimple_call_num_args (stmt); i++)
3367 t = gimple_call_arg_ptr (stmt, i);
3368 modified |= sra_modify_expr (t, &gsi, false);
3371 if (gimple_call_lhs (stmt))
3373 t = gimple_call_lhs_ptr (stmt);
3374 modified |= sra_modify_expr (t, &gsi, true);
3376 break;
3378 case GIMPLE_ASM:
3379 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
3381 t = &TREE_VALUE (gimple_asm_input_op (stmt, i));
3382 modified |= sra_modify_expr (t, &gsi, false);
3384 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
3386 t = &TREE_VALUE (gimple_asm_output_op (stmt, i));
3387 modified |= sra_modify_expr (t, &gsi, true);
3389 break;
3391 default:
3392 break;
3395 if (modified)
3397 update_stmt (stmt);
3398 if (maybe_clean_eh_stmt (stmt)
3399 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
3400 cfg_changed = true;
3402 if (!deleted)
3403 gsi_next (&gsi);
3407 return cfg_changed;
3410 /* Generate statements initializing scalar replacements of parts of function
3411 parameters. */
3413 static void
3414 initialize_parameter_reductions (void)
3416 gimple_stmt_iterator gsi;
3417 gimple_seq seq = NULL;
3418 tree parm;
3420 gsi = gsi_start (seq);
3421 for (parm = DECL_ARGUMENTS (current_function_decl);
3422 parm;
3423 parm = DECL_CHAIN (parm))
3425 vec<access_p> *access_vec;
3426 struct access *access;
3428 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3429 continue;
3430 access_vec = get_base_access_vector (parm);
3431 if (!access_vec)
3432 continue;
3434 for (access = (*access_vec)[0];
3435 access;
3436 access = access->next_grp)
3437 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true,
3438 EXPR_LOCATION (parm));
3441 seq = gsi_seq (gsi);
3442 if (seq)
3443 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3446 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3447 it reveals there are components of some aggregates to be scalarized, it runs
3448 the required transformations. */
3449 static unsigned int
3450 perform_intra_sra (void)
3452 int ret = 0;
3453 sra_initialize ();
3455 if (!find_var_candidates ())
3456 goto out;
3458 if (!scan_function ())
3459 goto out;
3461 if (!analyze_all_variable_accesses ())
3462 goto out;
3464 if (sra_modify_function_body ())
3465 ret = TODO_update_ssa | TODO_cleanup_cfg;
3466 else
3467 ret = TODO_update_ssa;
3468 initialize_parameter_reductions ();
3470 statistics_counter_event (cfun, "Scalar replacements created",
3471 sra_stats.replacements);
3472 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
3473 statistics_counter_event (cfun, "Subtree copy stmts",
3474 sra_stats.subtree_copies);
3475 statistics_counter_event (cfun, "Subreplacement stmts",
3476 sra_stats.subreplacements);
3477 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
3478 statistics_counter_event (cfun, "Separate LHS and RHS handling",
3479 sra_stats.separate_lhs_rhs_handling);
3481 out:
3482 sra_deinitialize ();
3483 return ret;
3486 /* Perform early intraprocedural SRA. */
3487 static unsigned int
3488 early_intra_sra (void)
3490 sra_mode = SRA_MODE_EARLY_INTRA;
3491 return perform_intra_sra ();
3494 /* Perform "late" intraprocedural SRA. */
3495 static unsigned int
3496 late_intra_sra (void)
3498 sra_mode = SRA_MODE_INTRA;
3499 return perform_intra_sra ();
3503 static bool
3504 gate_intra_sra (void)
3506 return flag_tree_sra != 0 && dbg_cnt (tree_sra);
3510 namespace {
3512 const pass_data pass_data_sra_early =
3514 GIMPLE_PASS, /* type */
3515 "esra", /* name */
3516 OPTGROUP_NONE, /* optinfo_flags */
3517 true, /* has_gate */
3518 true, /* has_execute */
3519 TV_TREE_SRA, /* tv_id */
3520 ( PROP_cfg | PROP_ssa ), /* properties_required */
3521 0, /* properties_provided */
3522 0, /* properties_destroyed */
3523 0, /* todo_flags_start */
3524 ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */
3527 class pass_sra_early : public gimple_opt_pass
3529 public:
3530 pass_sra_early (gcc::context *ctxt)
3531 : gimple_opt_pass (pass_data_sra_early, ctxt)
3534 /* opt_pass methods: */
3535 bool gate () { return gate_intra_sra (); }
3536 unsigned int execute () { return early_intra_sra (); }
3538 }; // class pass_sra_early
3540 } // anon namespace
3542 gimple_opt_pass *
3543 make_pass_sra_early (gcc::context *ctxt)
3545 return new pass_sra_early (ctxt);
3548 namespace {
3550 const pass_data pass_data_sra =
3552 GIMPLE_PASS, /* type */
3553 "sra", /* name */
3554 OPTGROUP_NONE, /* optinfo_flags */
3555 true, /* has_gate */
3556 true, /* has_execute */
3557 TV_TREE_SRA, /* tv_id */
3558 ( PROP_cfg | PROP_ssa ), /* properties_required */
3559 0, /* properties_provided */
3560 0, /* properties_destroyed */
3561 TODO_update_address_taken, /* todo_flags_start */
3562 ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */
3565 class pass_sra : public gimple_opt_pass
3567 public:
3568 pass_sra (gcc::context *ctxt)
3569 : gimple_opt_pass (pass_data_sra, ctxt)
3572 /* opt_pass methods: */
3573 bool gate () { return gate_intra_sra (); }
3574 unsigned int execute () { return late_intra_sra (); }
3576 }; // class pass_sra
3578 } // anon namespace
3580 gimple_opt_pass *
3581 make_pass_sra (gcc::context *ctxt)
3583 return new pass_sra (ctxt);
3587 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3588 parameter. */
3590 static bool
3591 is_unused_scalar_param (tree parm)
3593 tree name;
3594 return (is_gimple_reg (parm)
3595 && (!(name = ssa_default_def (cfun, parm))
3596 || has_zero_uses (name)));
3599 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3600 examine whether there are any direct or otherwise infeasible ones. If so,
3601 return true, otherwise return false. PARM must be a gimple register with a
3602 non-NULL default definition. */
3604 static bool
3605 ptr_parm_has_direct_uses (tree parm)
3607 imm_use_iterator ui;
3608 gimple stmt;
3609 tree name = ssa_default_def (cfun, parm);
3610 bool ret = false;
3612 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
3614 int uses_ok = 0;
3615 use_operand_p use_p;
3617 if (is_gimple_debug (stmt))
3618 continue;
3620 /* Valid uses include dereferences on the lhs and the rhs. */
3621 if (gimple_has_lhs (stmt))
3623 tree lhs = gimple_get_lhs (stmt);
3624 while (handled_component_p (lhs))
3625 lhs = TREE_OPERAND (lhs, 0);
3626 if (TREE_CODE (lhs) == MEM_REF
3627 && TREE_OPERAND (lhs, 0) == name
3628 && integer_zerop (TREE_OPERAND (lhs, 1))
3629 && types_compatible_p (TREE_TYPE (lhs),
3630 TREE_TYPE (TREE_TYPE (name)))
3631 && !TREE_THIS_VOLATILE (lhs))
3632 uses_ok++;
3634 if (gimple_assign_single_p (stmt))
3636 tree rhs = gimple_assign_rhs1 (stmt);
3637 while (handled_component_p (rhs))
3638 rhs = TREE_OPERAND (rhs, 0);
3639 if (TREE_CODE (rhs) == MEM_REF
3640 && TREE_OPERAND (rhs, 0) == name
3641 && integer_zerop (TREE_OPERAND (rhs, 1))
3642 && types_compatible_p (TREE_TYPE (rhs),
3643 TREE_TYPE (TREE_TYPE (name)))
3644 && !TREE_THIS_VOLATILE (rhs))
3645 uses_ok++;
3647 else if (is_gimple_call (stmt))
3649 unsigned i;
3650 for (i = 0; i < gimple_call_num_args (stmt); ++i)
3652 tree arg = gimple_call_arg (stmt, i);
3653 while (handled_component_p (arg))
3654 arg = TREE_OPERAND (arg, 0);
3655 if (TREE_CODE (arg) == MEM_REF
3656 && TREE_OPERAND (arg, 0) == name
3657 && integer_zerop (TREE_OPERAND (arg, 1))
3658 && types_compatible_p (TREE_TYPE (arg),
3659 TREE_TYPE (TREE_TYPE (name)))
3660 && !TREE_THIS_VOLATILE (arg))
3661 uses_ok++;
3665 /* If the number of valid uses does not match the number of
3666 uses in this stmt there is an unhandled use. */
3667 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
3668 --uses_ok;
3670 if (uses_ok != 0)
3671 ret = true;
3673 if (ret)
3674 BREAK_FROM_IMM_USE_STMT (ui);
3677 return ret;
3680 /* Identify candidates for reduction for IPA-SRA based on their type and mark
3681 them in candidate_bitmap. Note that these do not necessarily include
3682 parameter which are unused and thus can be removed. Return true iff any
3683 such candidate has been found. */
3685 static bool
3686 find_param_candidates (void)
3688 tree parm;
3689 int count = 0;
3690 bool ret = false;
3691 const char *msg;
3693 for (parm = DECL_ARGUMENTS (current_function_decl);
3694 parm;
3695 parm = DECL_CHAIN (parm))
3697 tree type = TREE_TYPE (parm);
3698 tree_node **slot;
3700 count++;
3702 if (TREE_THIS_VOLATILE (parm)
3703 || TREE_ADDRESSABLE (parm)
3704 || (!is_gimple_reg_type (type) && is_va_list_type (type)))
3705 continue;
3707 if (is_unused_scalar_param (parm))
3709 ret = true;
3710 continue;
3713 if (POINTER_TYPE_P (type))
3715 type = TREE_TYPE (type);
3717 if (TREE_CODE (type) == FUNCTION_TYPE
3718 || TYPE_VOLATILE (type)
3719 || (TREE_CODE (type) == ARRAY_TYPE
3720 && TYPE_NONALIASED_COMPONENT (type))
3721 || !is_gimple_reg (parm)
3722 || is_va_list_type (type)
3723 || ptr_parm_has_direct_uses (parm))
3724 continue;
3726 else if (!AGGREGATE_TYPE_P (type))
3727 continue;
3729 if (!COMPLETE_TYPE_P (type)
3730 || !tree_fits_uhwi_p (TYPE_SIZE (type))
3731 || tree_to_uhwi (TYPE_SIZE (type)) == 0
3732 || (AGGREGATE_TYPE_P (type)
3733 && type_internals_preclude_sra_p (type, &msg)))
3734 continue;
3736 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
3737 slot = candidates.find_slot_with_hash (parm, DECL_UID (parm), INSERT);
3738 *slot = parm;
3740 ret = true;
3741 if (dump_file && (dump_flags & TDF_DETAILS))
3743 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
3744 print_generic_expr (dump_file, parm, 0);
3745 fprintf (dump_file, "\n");
3749 func_param_count = count;
3750 return ret;
3753 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
3754 maybe_modified. */
3756 static bool
3757 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
3758 void *data)
3760 struct access *repr = (struct access *) data;
3762 repr->grp_maybe_modified = 1;
3763 return true;
3766 /* Analyze what representatives (in linked lists accessible from
3767 REPRESENTATIVES) can be modified by side effects of statements in the
3768 current function. */
3770 static void
3771 analyze_modified_params (vec<access_p> representatives)
3773 int i;
3775 for (i = 0; i < func_param_count; i++)
3777 struct access *repr;
3779 for (repr = representatives[i];
3780 repr;
3781 repr = repr->next_grp)
3783 struct access *access;
3784 bitmap visited;
3785 ao_ref ar;
3787 if (no_accesses_p (repr))
3788 continue;
3789 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
3790 || repr->grp_maybe_modified)
3791 continue;
3793 ao_ref_init (&ar, repr->expr);
3794 visited = BITMAP_ALLOC (NULL);
3795 for (access = repr; access; access = access->next_sibling)
3797 /* All accesses are read ones, otherwise grp_maybe_modified would
3798 be trivially set. */
3799 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
3800 mark_maybe_modified, repr, &visited);
3801 if (repr->grp_maybe_modified)
3802 break;
3804 BITMAP_FREE (visited);
3809 /* Propagate distances in bb_dereferences in the opposite direction than the
3810 control flow edges, in each step storing the maximum of the current value
3811 and the minimum of all successors. These steps are repeated until the table
3812 stabilizes. Note that BBs which might terminate the functions (according to
3813 final_bbs bitmap) never updated in this way. */
3815 static void
3816 propagate_dereference_distances (void)
3818 basic_block bb;
3820 auto_vec<basic_block> queue (last_basic_block_for_fn (cfun));
3821 queue.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun));
3822 FOR_EACH_BB_FN (bb, cfun)
3824 queue.quick_push (bb);
3825 bb->aux = bb;
3828 while (!queue.is_empty ())
3830 edge_iterator ei;
3831 edge e;
3832 bool change = false;
3833 int i;
3835 bb = queue.pop ();
3836 bb->aux = NULL;
3838 if (bitmap_bit_p (final_bbs, bb->index))
3839 continue;
3841 for (i = 0; i < func_param_count; i++)
3843 int idx = bb->index * func_param_count + i;
3844 bool first = true;
3845 HOST_WIDE_INT inh = 0;
3847 FOR_EACH_EDGE (e, ei, bb->succs)
3849 int succ_idx = e->dest->index * func_param_count + i;
3851 if (e->src == EXIT_BLOCK_PTR_FOR_FN (cfun))
3852 continue;
3854 if (first)
3856 first = false;
3857 inh = bb_dereferences [succ_idx];
3859 else if (bb_dereferences [succ_idx] < inh)
3860 inh = bb_dereferences [succ_idx];
3863 if (!first && bb_dereferences[idx] < inh)
3865 bb_dereferences[idx] = inh;
3866 change = true;
3870 if (change && !bitmap_bit_p (final_bbs, bb->index))
3871 FOR_EACH_EDGE (e, ei, bb->preds)
3873 if (e->src->aux)
3874 continue;
3876 e->src->aux = e->src;
3877 queue.quick_push (e->src);
3882 /* Dump a dereferences TABLE with heading STR to file F. */
3884 static void
3885 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
3887 basic_block bb;
3889 fprintf (dump_file, str);
3890 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
3891 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
3893 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
3894 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
3896 int i;
3897 for (i = 0; i < func_param_count; i++)
3899 int idx = bb->index * func_param_count + i;
3900 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
3903 fprintf (f, "\n");
3905 fprintf (dump_file, "\n");
3908 /* Determine what (parts of) parameters passed by reference that are not
3909 assigned to are not certainly dereferenced in this function and thus the
3910 dereferencing cannot be safely moved to the caller without potentially
3911 introducing a segfault. Mark such REPRESENTATIVES as
3912 grp_not_necessarilly_dereferenced.
3914 The dereferenced maximum "distance," i.e. the offset + size of the accessed
3915 part is calculated rather than simple booleans are calculated for each
3916 pointer parameter to handle cases when only a fraction of the whole
3917 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
3918 an example).
3920 The maximum dereference distances for each pointer parameter and BB are
3921 already stored in bb_dereference. This routine simply propagates these
3922 values upwards by propagate_dereference_distances and then compares the
3923 distances of individual parameters in the ENTRY BB to the equivalent
3924 distances of each representative of a (fraction of a) parameter. */
3926 static void
3927 analyze_caller_dereference_legality (vec<access_p> representatives)
3929 int i;
3931 if (dump_file && (dump_flags & TDF_DETAILS))
3932 dump_dereferences_table (dump_file,
3933 "Dereference table before propagation:\n",
3934 bb_dereferences);
3936 propagate_dereference_distances ();
3938 if (dump_file && (dump_flags & TDF_DETAILS))
3939 dump_dereferences_table (dump_file,
3940 "Dereference table after propagation:\n",
3941 bb_dereferences);
3943 for (i = 0; i < func_param_count; i++)
3945 struct access *repr = representatives[i];
3946 int idx = ENTRY_BLOCK_PTR_FOR_FN (cfun)->index * func_param_count + i;
3948 if (!repr || no_accesses_p (repr))
3949 continue;
3953 if ((repr->offset + repr->size) > bb_dereferences[idx])
3954 repr->grp_not_necessarilly_dereferenced = 1;
3955 repr = repr->next_grp;
3957 while (repr);
3961 /* Return the representative access for the parameter declaration PARM if it is
3962 a scalar passed by reference which is not written to and the pointer value
3963 is not used directly. Thus, if it is legal to dereference it in the caller
3964 and we can rule out modifications through aliases, such parameter should be
3965 turned into one passed by value. Return NULL otherwise. */
3967 static struct access *
3968 unmodified_by_ref_scalar_representative (tree parm)
3970 int i, access_count;
3971 struct access *repr;
3972 vec<access_p> *access_vec;
3974 access_vec = get_base_access_vector (parm);
3975 gcc_assert (access_vec);
3976 repr = (*access_vec)[0];
3977 if (repr->write)
3978 return NULL;
3979 repr->group_representative = repr;
3981 access_count = access_vec->length ();
3982 for (i = 1; i < access_count; i++)
3984 struct access *access = (*access_vec)[i];
3985 if (access->write)
3986 return NULL;
3987 access->group_representative = repr;
3988 access->next_sibling = repr->next_sibling;
3989 repr->next_sibling = access;
3992 repr->grp_read = 1;
3993 repr->grp_scalar_ptr = 1;
3994 return repr;
3997 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
3998 associated with. REQ_ALIGN is the minimum required alignment. */
4000 static bool
4001 access_precludes_ipa_sra_p (struct access *access, unsigned int req_align)
4003 unsigned int exp_align;
4004 /* Avoid issues such as the second simple testcase in PR 42025. The problem
4005 is incompatible assign in a call statement (and possibly even in asm
4006 statements). This can be relaxed by using a new temporary but only for
4007 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
4008 intraprocedural SRA we deal with this by keeping the old aggregate around,
4009 something we cannot do in IPA-SRA.) */
4010 if (access->write
4011 && (is_gimple_call (access->stmt)
4012 || gimple_code (access->stmt) == GIMPLE_ASM))
4013 return true;
4015 exp_align = get_object_alignment (access->expr);
4016 if (exp_align < req_align)
4017 return true;
4019 return false;
4023 /* Sort collected accesses for parameter PARM, identify representatives for
4024 each accessed region and link them together. Return NULL if there are
4025 different but overlapping accesses, return the special ptr value meaning
4026 there are no accesses for this parameter if that is the case and return the
4027 first representative otherwise. Set *RO_GRP if there is a group of accesses
4028 with only read (i.e. no write) accesses. */
4030 static struct access *
4031 splice_param_accesses (tree parm, bool *ro_grp)
4033 int i, j, access_count, group_count;
4034 int agg_size, total_size = 0;
4035 struct access *access, *res, **prev_acc_ptr = &res;
4036 vec<access_p> *access_vec;
4038 access_vec = get_base_access_vector (parm);
4039 if (!access_vec)
4040 return &no_accesses_representant;
4041 access_count = access_vec->length ();
4043 access_vec->qsort (compare_access_positions);
4045 i = 0;
4046 total_size = 0;
4047 group_count = 0;
4048 while (i < access_count)
4050 bool modification;
4051 tree a1_alias_type;
4052 access = (*access_vec)[i];
4053 modification = access->write;
4054 if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type)))
4055 return NULL;
4056 a1_alias_type = reference_alias_ptr_type (access->expr);
4058 /* Access is about to become group representative unless we find some
4059 nasty overlap which would preclude us from breaking this parameter
4060 apart. */
4062 j = i + 1;
4063 while (j < access_count)
4065 struct access *ac2 = (*access_vec)[j];
4066 if (ac2->offset != access->offset)
4068 /* All or nothing law for parameters. */
4069 if (access->offset + access->size > ac2->offset)
4070 return NULL;
4071 else
4072 break;
4074 else if (ac2->size != access->size)
4075 return NULL;
4077 if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type))
4078 || (ac2->type != access->type
4079 && (TREE_ADDRESSABLE (ac2->type)
4080 || TREE_ADDRESSABLE (access->type)))
4081 || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
4082 return NULL;
4084 modification |= ac2->write;
4085 ac2->group_representative = access;
4086 ac2->next_sibling = access->next_sibling;
4087 access->next_sibling = ac2;
4088 j++;
4091 group_count++;
4092 access->grp_maybe_modified = modification;
4093 if (!modification)
4094 *ro_grp = true;
4095 *prev_acc_ptr = access;
4096 prev_acc_ptr = &access->next_grp;
4097 total_size += access->size;
4098 i = j;
4101 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4102 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4103 else
4104 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4105 if (total_size >= agg_size)
4106 return NULL;
4108 gcc_assert (group_count > 0);
4109 return res;
4112 /* Decide whether parameters with representative accesses given by REPR should
4113 be reduced into components. */
4115 static int
4116 decide_one_param_reduction (struct access *repr)
4118 int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
4119 bool by_ref;
4120 tree parm;
4122 parm = repr->base;
4123 cur_parm_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4124 gcc_assert (cur_parm_size > 0);
4126 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4128 by_ref = true;
4129 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4131 else
4133 by_ref = false;
4134 agg_size = cur_parm_size;
4137 if (dump_file)
4139 struct access *acc;
4140 fprintf (dump_file, "Evaluating PARAM group sizes for ");
4141 print_generic_expr (dump_file, parm, 0);
4142 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
4143 for (acc = repr; acc; acc = acc->next_grp)
4144 dump_access (dump_file, acc, true);
4147 total_size = 0;
4148 new_param_count = 0;
4150 for (; repr; repr = repr->next_grp)
4152 gcc_assert (parm == repr->base);
4154 /* Taking the address of a non-addressable field is verboten. */
4155 if (by_ref && repr->non_addressable)
4156 return 0;
4158 /* Do not decompose a non-BLKmode param in a way that would
4159 create BLKmode params. Especially for by-reference passing
4160 (thus, pointer-type param) this is hardly worthwhile. */
4161 if (DECL_MODE (parm) != BLKmode
4162 && TYPE_MODE (repr->type) == BLKmode)
4163 return 0;
4165 if (!by_ref || (!repr->grp_maybe_modified
4166 && !repr->grp_not_necessarilly_dereferenced))
4167 total_size += repr->size;
4168 else
4169 total_size += cur_parm_size;
4171 new_param_count++;
4174 gcc_assert (new_param_count > 0);
4176 if (optimize_function_for_size_p (cfun))
4177 parm_size_limit = cur_parm_size;
4178 else
4179 parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
4180 * cur_parm_size);
4182 if (total_size < agg_size
4183 && total_size <= parm_size_limit)
4185 if (dump_file)
4186 fprintf (dump_file, " ....will be split into %i components\n",
4187 new_param_count);
4188 return new_param_count;
4190 else
4191 return 0;
4194 /* The order of the following enums is important, we need to do extra work for
4195 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4196 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
4197 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
4199 /* Identify representatives of all accesses to all candidate parameters for
4200 IPA-SRA. Return result based on what representatives have been found. */
4202 static enum ipa_splicing_result
4203 splice_all_param_accesses (vec<access_p> &representatives)
4205 enum ipa_splicing_result result = NO_GOOD_ACCESS;
4206 tree parm;
4207 struct access *repr;
4209 representatives.create (func_param_count);
4211 for (parm = DECL_ARGUMENTS (current_function_decl);
4212 parm;
4213 parm = DECL_CHAIN (parm))
4215 if (is_unused_scalar_param (parm))
4217 representatives.quick_push (&no_accesses_representant);
4218 if (result == NO_GOOD_ACCESS)
4219 result = UNUSED_PARAMS;
4221 else if (POINTER_TYPE_P (TREE_TYPE (parm))
4222 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
4223 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4225 repr = unmodified_by_ref_scalar_representative (parm);
4226 representatives.quick_push (repr);
4227 if (repr)
4228 result = UNMODIF_BY_REF_ACCESSES;
4230 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4232 bool ro_grp = false;
4233 repr = splice_param_accesses (parm, &ro_grp);
4234 representatives.quick_push (repr);
4236 if (repr && !no_accesses_p (repr))
4238 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4240 if (ro_grp)
4241 result = UNMODIF_BY_REF_ACCESSES;
4242 else if (result < MODIF_BY_REF_ACCESSES)
4243 result = MODIF_BY_REF_ACCESSES;
4245 else if (result < BY_VAL_ACCESSES)
4246 result = BY_VAL_ACCESSES;
4248 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
4249 result = UNUSED_PARAMS;
4251 else
4252 representatives.quick_push (NULL);
4255 if (result == NO_GOOD_ACCESS)
4257 representatives.release ();
4258 return NO_GOOD_ACCESS;
4261 return result;
4264 /* Return the index of BASE in PARMS. Abort if it is not found. */
4266 static inline int
4267 get_param_index (tree base, vec<tree> parms)
4269 int i, len;
4271 len = parms.length ();
4272 for (i = 0; i < len; i++)
4273 if (parms[i] == base)
4274 return i;
4275 gcc_unreachable ();
4278 /* Convert the decisions made at the representative level into compact
4279 parameter adjustments. REPRESENTATIVES are pointers to first
4280 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4281 final number of adjustments. */
4283 static ipa_parm_adjustment_vec
4284 turn_representatives_into_adjustments (vec<access_p> representatives,
4285 int adjustments_count)
4287 vec<tree> parms;
4288 ipa_parm_adjustment_vec adjustments;
4289 tree parm;
4290 int i;
4292 gcc_assert (adjustments_count > 0);
4293 parms = ipa_get_vector_of_formal_parms (current_function_decl);
4294 adjustments.create (adjustments_count);
4295 parm = DECL_ARGUMENTS (current_function_decl);
4296 for (i = 0; i < func_param_count; i++, parm = DECL_CHAIN (parm))
4298 struct access *repr = representatives[i];
4300 if (!repr || no_accesses_p (repr))
4302 struct ipa_parm_adjustment adj;
4304 memset (&adj, 0, sizeof (adj));
4305 adj.base_index = get_param_index (parm, parms);
4306 adj.base = parm;
4307 if (!repr)
4308 adj.op = IPA_PARM_OP_COPY;
4309 else
4310 adj.op = IPA_PARM_OP_REMOVE;
4311 adj.arg_prefix = "ISRA";
4312 adjustments.quick_push (adj);
4314 else
4316 struct ipa_parm_adjustment adj;
4317 int index = get_param_index (parm, parms);
4319 for (; repr; repr = repr->next_grp)
4321 memset (&adj, 0, sizeof (adj));
4322 gcc_assert (repr->base == parm);
4323 adj.base_index = index;
4324 adj.base = repr->base;
4325 adj.type = repr->type;
4326 adj.alias_ptr_type = reference_alias_ptr_type (repr->expr);
4327 adj.offset = repr->offset;
4328 adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
4329 && (repr->grp_maybe_modified
4330 || repr->grp_not_necessarilly_dereferenced));
4331 adj.arg_prefix = "ISRA";
4332 adjustments.quick_push (adj);
4336 parms.release ();
4337 return adjustments;
4340 /* Analyze the collected accesses and produce a plan what to do with the
4341 parameters in the form of adjustments, NULL meaning nothing. */
4343 static ipa_parm_adjustment_vec
4344 analyze_all_param_acesses (void)
4346 enum ipa_splicing_result repr_state;
4347 bool proceed = false;
4348 int i, adjustments_count = 0;
4349 vec<access_p> representatives;
4350 ipa_parm_adjustment_vec adjustments;
4352 repr_state = splice_all_param_accesses (representatives);
4353 if (repr_state == NO_GOOD_ACCESS)
4354 return ipa_parm_adjustment_vec ();
4356 /* If there are any parameters passed by reference which are not modified
4357 directly, we need to check whether they can be modified indirectly. */
4358 if (repr_state == UNMODIF_BY_REF_ACCESSES)
4360 analyze_caller_dereference_legality (representatives);
4361 analyze_modified_params (representatives);
4364 for (i = 0; i < func_param_count; i++)
4366 struct access *repr = representatives[i];
4368 if (repr && !no_accesses_p (repr))
4370 if (repr->grp_scalar_ptr)
4372 adjustments_count++;
4373 if (repr->grp_not_necessarilly_dereferenced
4374 || repr->grp_maybe_modified)
4375 representatives[i] = NULL;
4376 else
4378 proceed = true;
4379 sra_stats.scalar_by_ref_to_by_val++;
4382 else
4384 int new_components = decide_one_param_reduction (repr);
4386 if (new_components == 0)
4388 representatives[i] = NULL;
4389 adjustments_count++;
4391 else
4393 adjustments_count += new_components;
4394 sra_stats.aggregate_params_reduced++;
4395 sra_stats.param_reductions_created += new_components;
4396 proceed = true;
4400 else
4402 if (no_accesses_p (repr))
4404 proceed = true;
4405 sra_stats.deleted_unused_parameters++;
4407 adjustments_count++;
4411 if (!proceed && dump_file)
4412 fprintf (dump_file, "NOT proceeding to change params.\n");
4414 if (proceed)
4415 adjustments = turn_representatives_into_adjustments (representatives,
4416 adjustments_count);
4417 else
4418 adjustments = ipa_parm_adjustment_vec ();
4420 representatives.release ();
4421 return adjustments;
4424 /* If a parameter replacement identified by ADJ does not yet exist in the form
4425 of declaration, create it and record it, otherwise return the previously
4426 created one. */
4428 static tree
4429 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
4431 tree repl;
4432 if (!adj->new_ssa_base)
4434 char *pretty_name = make_fancy_name (adj->base);
4436 repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR");
4437 DECL_NAME (repl) = get_identifier (pretty_name);
4438 obstack_free (&name_obstack, pretty_name);
4440 adj->new_ssa_base = repl;
4442 else
4443 repl = adj->new_ssa_base;
4444 return repl;
4447 /* Find the first adjustment for a particular parameter BASE in a vector of
4448 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4449 adjustment. */
4451 static struct ipa_parm_adjustment *
4452 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
4454 int i, len;
4456 len = adjustments.length ();
4457 for (i = 0; i < len; i++)
4459 struct ipa_parm_adjustment *adj;
4461 adj = &adjustments[i];
4462 if (adj->op != IPA_PARM_OP_COPY && adj->base == base)
4463 return adj;
4466 return NULL;
4469 /* If the statement STMT defines an SSA_NAME of a parameter which is to be
4470 removed because its value is not used, replace the SSA_NAME with a one
4471 relating to a created VAR_DECL together all of its uses and return true.
4472 ADJUSTMENTS is a pointer to an adjustments vector. */
4474 static bool
4475 replace_removed_params_ssa_names (gimple stmt,
4476 ipa_parm_adjustment_vec adjustments)
4478 struct ipa_parm_adjustment *adj;
4479 tree lhs, decl, repl, name;
4481 if (gimple_code (stmt) == GIMPLE_PHI)
4482 lhs = gimple_phi_result (stmt);
4483 else if (is_gimple_assign (stmt))
4484 lhs = gimple_assign_lhs (stmt);
4485 else if (is_gimple_call (stmt))
4486 lhs = gimple_call_lhs (stmt);
4487 else
4488 gcc_unreachable ();
4490 if (TREE_CODE (lhs) != SSA_NAME)
4491 return false;
4493 decl = SSA_NAME_VAR (lhs);
4494 if (decl == NULL_TREE
4495 || TREE_CODE (decl) != PARM_DECL)
4496 return false;
4498 adj = get_adjustment_for_base (adjustments, decl);
4499 if (!adj)
4500 return false;
4502 repl = get_replaced_param_substitute (adj);
4503 name = make_ssa_name (repl, stmt);
4505 if (dump_file)
4507 fprintf (dump_file, "replacing an SSA name of a removed param ");
4508 print_generic_expr (dump_file, lhs, 0);
4509 fprintf (dump_file, " with ");
4510 print_generic_expr (dump_file, name, 0);
4511 fprintf (dump_file, "\n");
4514 if (is_gimple_assign (stmt))
4515 gimple_assign_set_lhs (stmt, name);
4516 else if (is_gimple_call (stmt))
4517 gimple_call_set_lhs (stmt, name);
4518 else
4519 gimple_phi_set_result (stmt, name);
4521 replace_uses_by (lhs, name);
4522 release_ssa_name (lhs);
4523 return true;
4526 /* If the statement pointed to by STMT_PTR contains any expressions that need
4527 to replaced with a different one as noted by ADJUSTMENTS, do so. Handle any
4528 potential type incompatibilities (GSI is used to accommodate conversion
4529 statements and must point to the statement). Return true iff the statement
4530 was modified. */
4532 static bool
4533 sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi,
4534 ipa_parm_adjustment_vec adjustments)
4536 gimple stmt = *stmt_ptr;
4537 tree *lhs_p, *rhs_p;
4538 bool any;
4540 if (!gimple_assign_single_p (stmt))
4541 return false;
4543 rhs_p = gimple_assign_rhs1_ptr (stmt);
4544 lhs_p = gimple_assign_lhs_ptr (stmt);
4546 any = ipa_modify_expr (rhs_p, false, adjustments);
4547 any |= ipa_modify_expr (lhs_p, false, adjustments);
4548 if (any)
4550 tree new_rhs = NULL_TREE;
4552 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
4554 if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
4556 /* V_C_Es of constructors can cause trouble (PR 42714). */
4557 if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
4558 *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
4559 else
4560 *rhs_p = build_constructor (TREE_TYPE (*lhs_p),
4561 NULL);
4563 else
4564 new_rhs = fold_build1_loc (gimple_location (stmt),
4565 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
4566 *rhs_p);
4568 else if (REFERENCE_CLASS_P (*rhs_p)
4569 && is_gimple_reg_type (TREE_TYPE (*lhs_p))
4570 && !is_gimple_reg (*lhs_p))
4571 /* This can happen when an assignment in between two single field
4572 structures is turned into an assignment in between two pointers to
4573 scalars (PR 42237). */
4574 new_rhs = *rhs_p;
4576 if (new_rhs)
4578 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
4579 true, GSI_SAME_STMT);
4581 gimple_assign_set_rhs_from_tree (gsi, tmp);
4584 return true;
4587 return false;
4590 /* Traverse the function body and all modifications as described in
4591 ADJUSTMENTS. Return true iff the CFG has been changed. */
4593 bool
4594 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
4596 bool cfg_changed = false;
4597 basic_block bb;
4599 FOR_EACH_BB_FN (bb, cfun)
4601 gimple_stmt_iterator gsi;
4603 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4604 replace_removed_params_ssa_names (gsi_stmt (gsi), adjustments);
4606 gsi = gsi_start_bb (bb);
4607 while (!gsi_end_p (gsi))
4609 gimple stmt = gsi_stmt (gsi);
4610 bool modified = false;
4611 tree *t;
4612 unsigned i;
4614 switch (gimple_code (stmt))
4616 case GIMPLE_RETURN:
4617 t = gimple_return_retval_ptr (stmt);
4618 if (*t != NULL_TREE)
4619 modified |= ipa_modify_expr (t, true, adjustments);
4620 break;
4622 case GIMPLE_ASSIGN:
4623 modified |= sra_ipa_modify_assign (&stmt, &gsi, adjustments);
4624 modified |= replace_removed_params_ssa_names (stmt, adjustments);
4625 break;
4627 case GIMPLE_CALL:
4628 /* Operands must be processed before the lhs. */
4629 for (i = 0; i < gimple_call_num_args (stmt); i++)
4631 t = gimple_call_arg_ptr (stmt, i);
4632 modified |= ipa_modify_expr (t, true, adjustments);
4635 if (gimple_call_lhs (stmt))
4637 t = gimple_call_lhs_ptr (stmt);
4638 modified |= ipa_modify_expr (t, false, adjustments);
4639 modified |= replace_removed_params_ssa_names (stmt,
4640 adjustments);
4642 break;
4644 case GIMPLE_ASM:
4645 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
4647 t = &TREE_VALUE (gimple_asm_input_op (stmt, i));
4648 modified |= ipa_modify_expr (t, true, adjustments);
4650 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
4652 t = &TREE_VALUE (gimple_asm_output_op (stmt, i));
4653 modified |= ipa_modify_expr (t, false, adjustments);
4655 break;
4657 default:
4658 break;
4661 if (modified)
4663 update_stmt (stmt);
4664 if (maybe_clean_eh_stmt (stmt)
4665 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
4666 cfg_changed = true;
4668 gsi_next (&gsi);
4672 return cfg_changed;
4675 /* Call gimple_debug_bind_reset_value on all debug statements describing
4676 gimple register parameters that are being removed or replaced. */
4678 static void
4679 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
4681 int i, len;
4682 gimple_stmt_iterator *gsip = NULL, gsi;
4684 if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
4686 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
4687 gsip = &gsi;
4689 len = adjustments.length ();
4690 for (i = 0; i < len; i++)
4692 struct ipa_parm_adjustment *adj;
4693 imm_use_iterator ui;
4694 gimple stmt, def_temp;
4695 tree name, vexpr, copy = NULL_TREE;
4696 use_operand_p use_p;
4698 adj = &adjustments[i];
4699 if (adj->op == IPA_PARM_OP_COPY || !is_gimple_reg (adj->base))
4700 continue;
4701 name = ssa_default_def (cfun, adj->base);
4702 vexpr = NULL;
4703 if (name)
4704 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
4706 if (gimple_clobber_p (stmt))
4708 gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
4709 unlink_stmt_vdef (stmt);
4710 gsi_remove (&cgsi, true);
4711 release_defs (stmt);
4712 continue;
4714 /* All other users must have been removed by
4715 ipa_sra_modify_function_body. */
4716 gcc_assert (is_gimple_debug (stmt));
4717 if (vexpr == NULL && gsip != NULL)
4719 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
4720 vexpr = make_node (DEBUG_EXPR_DECL);
4721 def_temp = gimple_build_debug_source_bind (vexpr, adj->base,
4722 NULL);
4723 DECL_ARTIFICIAL (vexpr) = 1;
4724 TREE_TYPE (vexpr) = TREE_TYPE (name);
4725 DECL_MODE (vexpr) = DECL_MODE (adj->base);
4726 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
4728 if (vexpr)
4730 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
4731 SET_USE (use_p, vexpr);
4733 else
4734 gimple_debug_bind_reset_value (stmt);
4735 update_stmt (stmt);
4737 /* Create a VAR_DECL for debug info purposes. */
4738 if (!DECL_IGNORED_P (adj->base))
4740 copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
4741 VAR_DECL, DECL_NAME (adj->base),
4742 TREE_TYPE (adj->base));
4743 if (DECL_PT_UID_SET_P (adj->base))
4744 SET_DECL_PT_UID (copy, DECL_PT_UID (adj->base));
4745 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (adj->base);
4746 TREE_READONLY (copy) = TREE_READONLY (adj->base);
4747 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (adj->base);
4748 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (adj->base);
4749 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (adj->base);
4750 DECL_IGNORED_P (copy) = DECL_IGNORED_P (adj->base);
4751 DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (adj->base);
4752 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
4753 SET_DECL_RTL (copy, 0);
4754 TREE_USED (copy) = 1;
4755 DECL_CONTEXT (copy) = current_function_decl;
4756 add_local_decl (cfun, copy);
4757 DECL_CHAIN (copy) =
4758 BLOCK_VARS (DECL_INITIAL (current_function_decl));
4759 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
4761 if (gsip != NULL && copy && target_for_debug_bind (adj->base))
4763 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
4764 if (vexpr)
4765 def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
4766 else
4767 def_temp = gimple_build_debug_source_bind (copy, adj->base,
4768 NULL);
4769 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
4774 /* Return false if all callers have at least as many actual arguments as there
4775 are formal parameters in the current function and that their types
4776 match. */
4778 static bool
4779 some_callers_have_mismatched_arguments_p (struct cgraph_node *node,
4780 void *data ATTRIBUTE_UNUSED)
4782 struct cgraph_edge *cs;
4783 for (cs = node->callers; cs; cs = cs->next_caller)
4784 if (!callsite_arguments_match_p (cs->call_stmt))
4785 return true;
4787 return false;
4790 /* Convert all callers of NODE. */
4792 static bool
4793 convert_callers_for_node (struct cgraph_node *node,
4794 void *data)
4796 ipa_parm_adjustment_vec *adjustments = (ipa_parm_adjustment_vec *) data;
4797 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
4798 struct cgraph_edge *cs;
4800 for (cs = node->callers; cs; cs = cs->next_caller)
4802 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
4804 if (dump_file)
4805 fprintf (dump_file, "Adjusting call %s/%i -> %s/%i\n",
4806 xstrdup (cs->caller->name ()),
4807 cs->caller->order,
4808 xstrdup (cs->callee->name ()),
4809 cs->callee->order);
4811 if (cs->call_stmt)
4812 ipa_modify_call_arguments (cs, cs->call_stmt, *adjustments);
4814 pop_cfun ();
4817 for (cs = node->callers; cs; cs = cs->next_caller)
4818 if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
4819 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
4820 compute_inline_parameters (cs->caller, true);
4821 BITMAP_FREE (recomputed_callers);
4823 return true;
4826 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
4828 static void
4829 convert_callers (struct cgraph_node *node, tree old_decl,
4830 ipa_parm_adjustment_vec adjustments)
4832 basic_block this_block;
4834 cgraph_for_node_and_aliases (node, convert_callers_for_node,
4835 &adjustments, false);
4837 if (!encountered_recursive_call)
4838 return;
4840 FOR_EACH_BB_FN (this_block, cfun)
4842 gimple_stmt_iterator gsi;
4844 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
4846 gimple stmt = gsi_stmt (gsi);
4847 tree call_fndecl;
4848 if (gimple_code (stmt) != GIMPLE_CALL)
4849 continue;
4850 call_fndecl = gimple_call_fndecl (stmt);
4851 if (call_fndecl == old_decl)
4853 if (dump_file)
4854 fprintf (dump_file, "Adjusting recursive call");
4855 gimple_call_set_fndecl (stmt, node->decl);
4856 ipa_modify_call_arguments (NULL, stmt, adjustments);
4861 return;
4864 /* Perform all the modification required in IPA-SRA for NODE to have parameters
4865 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
4867 static bool
4868 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
4870 struct cgraph_node *new_node;
4871 bool cfg_changed;
4873 rebuild_cgraph_edges ();
4874 free_dominance_info (CDI_DOMINATORS);
4875 pop_cfun ();
4877 /* This must be done after rebuilding cgraph edges for node above.
4878 Otherwise any recursive calls to node that are recorded in
4879 redirect_callers will be corrupted. */
4880 vec<cgraph_edge_p> redirect_callers = collect_callers_of_node (node);
4881 new_node = cgraph_function_versioning (node, redirect_callers,
4882 NULL,
4883 NULL, false, NULL, NULL, "isra");
4884 redirect_callers.release ();
4886 push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
4887 ipa_modify_formal_parameters (current_function_decl, adjustments);
4888 cfg_changed = ipa_sra_modify_function_body (adjustments);
4889 sra_ipa_reset_debug_stmts (adjustments);
4890 convert_callers (new_node, node->decl, adjustments);
4891 cgraph_make_node_local (new_node);
4893 return cfg_changed;
4896 /* If NODE has a caller, return true. */
4898 static bool
4899 has_caller_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
4901 if (node->callers)
4902 return true;
4903 return false;
4906 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
4907 attributes, return true otherwise. NODE is the cgraph node of the current
4908 function. */
4910 static bool
4911 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
4913 if (!cgraph_node_can_be_local_p (node))
4915 if (dump_file)
4916 fprintf (dump_file, "Function not local to this compilation unit.\n");
4917 return false;
4920 if (!node->local.can_change_signature)
4922 if (dump_file)
4923 fprintf (dump_file, "Function can not change signature.\n");
4924 return false;
4927 if (!tree_versionable_function_p (node->decl))
4929 if (dump_file)
4930 fprintf (dump_file, "Function is not versionable.\n");
4931 return false;
4934 if (!opt_for_fn (node->decl, optimize)
4935 || !opt_for_fn (node->decl, flag_ipa_sra))
4937 if (dump_file)
4938 fprintf (dump_file, "Function not optimized.\n");
4939 return false;
4942 if (DECL_VIRTUAL_P (current_function_decl))
4944 if (dump_file)
4945 fprintf (dump_file, "Function is a virtual method.\n");
4946 return false;
4949 if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
4950 && inline_summary (node)->size >= MAX_INLINE_INSNS_AUTO)
4952 if (dump_file)
4953 fprintf (dump_file, "Function too big to be made truly local.\n");
4954 return false;
4957 if (!cgraph_for_node_and_aliases (node, has_caller_p, NULL, true))
4959 if (dump_file)
4960 fprintf (dump_file,
4961 "Function has no callers in this compilation unit.\n");
4962 return false;
4965 if (cfun->stdarg)
4967 if (dump_file)
4968 fprintf (dump_file, "Function uses stdarg. \n");
4969 return false;
4972 if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
4973 return false;
4975 return true;
4978 /* Perform early interprocedural SRA. */
4980 static unsigned int
4981 ipa_early_sra (void)
4983 struct cgraph_node *node = cgraph_get_node (current_function_decl);
4984 ipa_parm_adjustment_vec adjustments;
4985 int ret = 0;
4987 if (!ipa_sra_preliminary_function_checks (node))
4988 return 0;
4990 sra_initialize ();
4991 sra_mode = SRA_MODE_EARLY_IPA;
4993 if (!find_param_candidates ())
4995 if (dump_file)
4996 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
4997 goto simple_out;
5000 if (cgraph_for_node_and_aliases (node,
5001 some_callers_have_mismatched_arguments_p,
5002 NULL, true))
5004 if (dump_file)
5005 fprintf (dump_file, "There are callers with insufficient number of "
5006 "arguments or arguments with type mismatches.\n");
5007 goto simple_out;
5010 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
5011 func_param_count
5012 * last_basic_block_for_fn (cfun));
5013 final_bbs = BITMAP_ALLOC (NULL);
5015 scan_function ();
5016 if (encountered_apply_args)
5018 if (dump_file)
5019 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
5020 goto out;
5023 if (encountered_unchangable_recursive_call)
5025 if (dump_file)
5026 fprintf (dump_file, "Function calls itself with insufficient "
5027 "number of arguments.\n");
5028 goto out;
5031 adjustments = analyze_all_param_acesses ();
5032 if (!adjustments.exists ())
5033 goto out;
5034 if (dump_file)
5035 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
5037 if (modify_function (node, adjustments))
5038 ret = TODO_update_ssa | TODO_cleanup_cfg;
5039 else
5040 ret = TODO_update_ssa;
5041 adjustments.release ();
5043 statistics_counter_event (cfun, "Unused parameters deleted",
5044 sra_stats.deleted_unused_parameters);
5045 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
5046 sra_stats.scalar_by_ref_to_by_val);
5047 statistics_counter_event (cfun, "Aggregate parameters broken up",
5048 sra_stats.aggregate_params_reduced);
5049 statistics_counter_event (cfun, "Aggregate parameter components created",
5050 sra_stats.param_reductions_created);
5052 out:
5053 BITMAP_FREE (final_bbs);
5054 free (bb_dereferences);
5055 simple_out:
5056 sra_deinitialize ();
5057 return ret;
5060 /* Return if early ipa sra shall be performed. */
5061 static bool
5062 ipa_early_sra_gate (void)
5064 return flag_ipa_sra && !flag_dyn_ipa && dbg_cnt (eipa_sra);
5067 namespace {
5069 const pass_data pass_data_early_ipa_sra =
5071 GIMPLE_PASS, /* type */
5072 "eipa_sra", /* name */
5073 OPTGROUP_NONE, /* optinfo_flags */
5074 true, /* has_gate */
5075 true, /* has_execute */
5076 TV_IPA_SRA, /* tv_id */
5077 0, /* properties_required */
5078 0, /* properties_provided */
5079 0, /* properties_destroyed */
5080 0, /* todo_flags_start */
5081 TODO_dump_symtab, /* todo_flags_finish */
5084 class pass_early_ipa_sra : public gimple_opt_pass
5086 public:
5087 pass_early_ipa_sra (gcc::context *ctxt)
5088 : gimple_opt_pass (pass_data_early_ipa_sra, ctxt)
5091 /* opt_pass methods: */
5092 bool gate () { return ipa_early_sra_gate (); }
5093 unsigned int execute () { return ipa_early_sra (); }
5095 }; // class pass_early_ipa_sra
5097 } // anon namespace
5099 gimple_opt_pass *
5100 make_pass_early_ipa_sra (gcc::context *ctxt)
5102 return new pass_early_ipa_sra (ctxt);