Introduce gimple_omp_continue
[official-gcc.git] / gcc / tree-sra.c
blob3cdd10029a58e9f040b4dea4314d108add163685
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-map.h"
78 #include "hash-table.h"
79 #include "alloc-pool.h"
80 #include "tm.h"
81 #include "tree.h"
82 #include "basic-block.h"
83 #include "tree-ssa-alias.h"
84 #include "internal-fn.h"
85 #include "tree-eh.h"
86 #include "gimple-expr.h"
87 #include "is-a.h"
88 #include "gimple.h"
89 #include "stor-layout.h"
90 #include "gimplify.h"
91 #include "gimple-iterator.h"
92 #include "gimplify-me.h"
93 #include "gimple-walk.h"
94 #include "bitmap.h"
95 #include "gimple-ssa.h"
96 #include "tree-cfg.h"
97 #include "tree-phinodes.h"
98 #include "ssa-iterators.h"
99 #include "stringpool.h"
100 #include "tree-ssanames.h"
101 #include "expr.h"
102 #include "tree-dfa.h"
103 #include "tree-ssa.h"
104 #include "tree-pass.h"
105 #include "ipa-prop.h"
106 #include "statistics.h"
107 #include "params.h"
108 #include "target.h"
109 #include "flags.h"
110 #include "dbgcnt.h"
111 #include "tree-inline.h"
112 #include "gimple-pretty-print.h"
113 #include "ipa-inline.h"
114 #include "ipa-utils.h"
115 #include "builtins.h"
117 /* Enumeration of all aggregate reductions we can do. */
118 enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
119 SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
120 SRA_MODE_INTRA }; /* late intraprocedural SRA */
122 /* Global variable describing which aggregate reduction we are performing at
123 the moment. */
124 static enum sra_mode sra_mode;
126 struct assign_link;
128 /* ACCESS represents each access to an aggregate variable (as a whole or a
129 part). It can also represent a group of accesses that refer to exactly the
130 same fragment of an aggregate (i.e. those that have exactly the same offset
131 and size). Such representatives for a single aggregate, once determined,
132 are linked in a linked list and have the group fields set.
134 Moreover, when doing intraprocedural SRA, a tree is built from those
135 representatives (by the means of first_child and next_sibling pointers), in
136 which all items in a subtree are "within" the root, i.e. their offset is
137 greater or equal to offset of the root and offset+size is smaller or equal
138 to offset+size of the root. Children of an access are sorted by offset.
140 Note that accesses to parts of vector and complex number types always
141 represented by an access to the whole complex number or a vector. It is a
142 duty of the modifying functions to replace them appropriately. */
144 struct access
146 /* Values returned by `get_ref_base_and_extent' for each component reference
147 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
148 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
149 HOST_WIDE_INT offset;
150 HOST_WIDE_INT size;
151 tree base;
153 /* Expression. It is context dependent so do not use it to create new
154 expressions to access the original aggregate. See PR 42154 for a
155 testcase. */
156 tree expr;
157 /* Type. */
158 tree type;
160 /* The statement this access belongs to. */
161 gimple stmt;
163 /* Next group representative for this aggregate. */
164 struct access *next_grp;
166 /* Pointer to the group representative. Pointer to itself if the struct is
167 the representative. */
168 struct access *group_representative;
170 /* If this access has any children (in terms of the definition above), this
171 points to the first one. */
172 struct access *first_child;
174 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
175 described above. In IPA-SRA this is a pointer to the next access
176 belonging to the same group (having the same representative). */
177 struct access *next_sibling;
179 /* Pointers to the first and last element in the linked list of assign
180 links. */
181 struct assign_link *first_link, *last_link;
183 /* Pointer to the next access in the work queue. */
184 struct access *next_queued;
186 /* Replacement variable for this access "region." Never to be accessed
187 directly, always only by the means of get_access_replacement() and only
188 when grp_to_be_replaced flag is set. */
189 tree replacement_decl;
191 /* Is this particular access write access? */
192 unsigned write : 1;
194 /* Is this access an access to a non-addressable field? */
195 unsigned non_addressable : 1;
197 /* Is this access currently in the work queue? */
198 unsigned grp_queued : 1;
200 /* Does this group contain a write access? This flag is propagated down the
201 access tree. */
202 unsigned grp_write : 1;
204 /* Does this group contain a read access? This flag is propagated down the
205 access tree. */
206 unsigned grp_read : 1;
208 /* Does this group contain a read access that comes from an assignment
209 statement? This flag is propagated down the access tree. */
210 unsigned grp_assignment_read : 1;
212 /* Does this group contain a write access that comes from an assignment
213 statement? This flag is propagated down the access tree. */
214 unsigned grp_assignment_write : 1;
216 /* Does this group contain a read access through a scalar type? This flag is
217 not propagated in the access tree in any direction. */
218 unsigned grp_scalar_read : 1;
220 /* Does this group contain a write access through a scalar type? This flag
221 is not propagated in the access tree in any direction. */
222 unsigned grp_scalar_write : 1;
224 /* Is this access an artificial one created to scalarize some record
225 entirely? */
226 unsigned grp_total_scalarization : 1;
228 /* Other passes of the analysis use this bit to make function
229 analyze_access_subtree create scalar replacements for this group if
230 possible. */
231 unsigned grp_hint : 1;
233 /* Is the subtree rooted in this access fully covered by scalar
234 replacements? */
235 unsigned grp_covered : 1;
237 /* If set to true, this access and all below it in an access tree must not be
238 scalarized. */
239 unsigned grp_unscalarizable_region : 1;
241 /* Whether data have been written to parts of the aggregate covered by this
242 access which is not to be scalarized. This flag is propagated up in the
243 access tree. */
244 unsigned grp_unscalarized_data : 1;
246 /* Does this access and/or group contain a write access through a
247 BIT_FIELD_REF? */
248 unsigned grp_partial_lhs : 1;
250 /* Set when a scalar replacement should be created for this variable. */
251 unsigned grp_to_be_replaced : 1;
253 /* Set when we want a replacement for the sole purpose of having it in
254 generated debug statements. */
255 unsigned grp_to_be_debug_replaced : 1;
257 /* Should TREE_NO_WARNING of a replacement be set? */
258 unsigned grp_no_warning : 1;
260 /* Is it possible that the group refers to data which might be (directly or
261 otherwise) modified? */
262 unsigned grp_maybe_modified : 1;
264 /* Set when this is a representative of a pointer to scalar (i.e. by
265 reference) parameter which we consider for turning into a plain scalar
266 (i.e. a by value parameter). */
267 unsigned grp_scalar_ptr : 1;
269 /* Set when we discover that this pointer is not safe to dereference in the
270 caller. */
271 unsigned grp_not_necessarilly_dereferenced : 1;
274 typedef struct access *access_p;
277 /* Alloc pool for allocating access structures. */
278 static alloc_pool access_pool;
280 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
281 are used to propagate subaccesses from rhs to lhs as long as they don't
282 conflict with what is already there. */
283 struct assign_link
285 struct access *lacc, *racc;
286 struct assign_link *next;
289 /* Alloc pool for allocating assign link structures. */
290 static alloc_pool link_pool;
292 /* Base (tree) -> Vector (vec<access_p> *) map. */
293 static hash_map<tree, auto_vec<access_p> > *base_access_vec;
295 /* Candidate hash table helpers. */
297 struct uid_decl_hasher : typed_noop_remove <tree_node>
299 typedef tree_node value_type;
300 typedef tree_node compare_type;
301 static inline hashval_t hash (const value_type *);
302 static inline bool equal (const value_type *, const compare_type *);
305 /* Hash a tree in a uid_decl_map. */
307 inline hashval_t
308 uid_decl_hasher::hash (const value_type *item)
310 return item->decl_minimal.uid;
313 /* Return true if the DECL_UID in both trees are equal. */
315 inline bool
316 uid_decl_hasher::equal (const value_type *a, const compare_type *b)
318 return (a->decl_minimal.uid == b->decl_minimal.uid);
321 /* Set of candidates. */
322 static bitmap candidate_bitmap;
323 static hash_table<uid_decl_hasher> *candidates;
325 /* For a candidate UID return the candidates decl. */
327 static inline tree
328 candidate (unsigned uid)
330 tree_node t;
331 t.decl_minimal.uid = uid;
332 return candidates->find_with_hash (&t, static_cast <hashval_t> (uid));
335 /* Bitmap of candidates which we should try to entirely scalarize away and
336 those which cannot be (because they are and need be used as a whole). */
337 static bitmap should_scalarize_away_bitmap, cannot_scalarize_away_bitmap;
339 /* Obstack for creation of fancy names. */
340 static struct obstack name_obstack;
342 /* Head of a linked list of accesses that need to have its subaccesses
343 propagated to their assignment counterparts. */
344 static struct access *work_queue_head;
346 /* Number of parameters of the analyzed function when doing early ipa SRA. */
347 static int func_param_count;
349 /* scan_function sets the following to true if it encounters a call to
350 __builtin_apply_args. */
351 static bool encountered_apply_args;
353 /* Set by scan_function when it finds a recursive call. */
354 static bool encountered_recursive_call;
356 /* Set by scan_function when it finds a recursive call with less actual
357 arguments than formal parameters.. */
358 static bool encountered_unchangable_recursive_call;
360 /* This is a table in which for each basic block and parameter there is a
361 distance (offset + size) in that parameter which is dereferenced and
362 accessed in that BB. */
363 static HOST_WIDE_INT *bb_dereferences;
364 /* Bitmap of BBs that can cause the function to "stop" progressing by
365 returning, throwing externally, looping infinitely or calling a function
366 which might abort etc.. */
367 static bitmap final_bbs;
369 /* Representative of no accesses at all. */
370 static struct access no_accesses_representant;
372 /* Predicate to test the special value. */
374 static inline bool
375 no_accesses_p (struct access *access)
377 return access == &no_accesses_representant;
380 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
381 representative fields are dumped, otherwise those which only describe the
382 individual access are. */
384 static struct
386 /* Number of processed aggregates is readily available in
387 analyze_all_variable_accesses and so is not stored here. */
389 /* Number of created scalar replacements. */
390 int replacements;
392 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
393 expression. */
394 int exprs;
396 /* Number of statements created by generate_subtree_copies. */
397 int subtree_copies;
399 /* Number of statements created by load_assign_lhs_subreplacements. */
400 int subreplacements;
402 /* Number of times sra_modify_assign has deleted a statement. */
403 int deleted;
405 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
406 RHS reparately due to type conversions or nonexistent matching
407 references. */
408 int separate_lhs_rhs_handling;
410 /* Number of parameters that were removed because they were unused. */
411 int deleted_unused_parameters;
413 /* Number of scalars passed as parameters by reference that have been
414 converted to be passed by value. */
415 int scalar_by_ref_to_by_val;
417 /* Number of aggregate parameters that were replaced by one or more of their
418 components. */
419 int aggregate_params_reduced;
421 /* Numbber of components created when splitting aggregate parameters. */
422 int param_reductions_created;
423 } sra_stats;
425 static void
426 dump_access (FILE *f, struct access *access, bool grp)
428 fprintf (f, "access { ");
429 fprintf (f, "base = (%d)'", DECL_UID (access->base));
430 print_generic_expr (f, access->base, 0);
431 fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
432 fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
433 fprintf (f, ", expr = ");
434 print_generic_expr (f, access->expr, 0);
435 fprintf (f, ", type = ");
436 print_generic_expr (f, access->type, 0);
437 if (grp)
438 fprintf (f, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
439 "grp_assignment_write = %d, grp_scalar_read = %d, "
440 "grp_scalar_write = %d, grp_total_scalarization = %d, "
441 "grp_hint = %d, grp_covered = %d, "
442 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
443 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
444 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
445 "grp_not_necessarilly_dereferenced = %d\n",
446 access->grp_read, access->grp_write, access->grp_assignment_read,
447 access->grp_assignment_write, access->grp_scalar_read,
448 access->grp_scalar_write, access->grp_total_scalarization,
449 access->grp_hint, access->grp_covered,
450 access->grp_unscalarizable_region, access->grp_unscalarized_data,
451 access->grp_partial_lhs, access->grp_to_be_replaced,
452 access->grp_to_be_debug_replaced, access->grp_maybe_modified,
453 access->grp_not_necessarilly_dereferenced);
454 else
455 fprintf (f, ", write = %d, grp_total_scalarization = %d, "
456 "grp_partial_lhs = %d\n",
457 access->write, access->grp_total_scalarization,
458 access->grp_partial_lhs);
461 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
463 static void
464 dump_access_tree_1 (FILE *f, struct access *access, int level)
468 int i;
470 for (i = 0; i < level; i++)
471 fputs ("* ", dump_file);
473 dump_access (f, access, true);
475 if (access->first_child)
476 dump_access_tree_1 (f, access->first_child, level + 1);
478 access = access->next_sibling;
480 while (access);
483 /* Dump all access trees for a variable, given the pointer to the first root in
484 ACCESS. */
486 static void
487 dump_access_tree (FILE *f, struct access *access)
489 for (; access; access = access->next_grp)
490 dump_access_tree_1 (f, access, 0);
493 /* Return true iff ACC is non-NULL and has subaccesses. */
495 static inline bool
496 access_has_children_p (struct access *acc)
498 return acc && acc->first_child;
501 /* Return true iff ACC is (partly) covered by at least one replacement. */
503 static bool
504 access_has_replacements_p (struct access *acc)
506 struct access *child;
507 if (acc->grp_to_be_replaced)
508 return true;
509 for (child = acc->first_child; child; child = child->next_sibling)
510 if (access_has_replacements_p (child))
511 return true;
512 return false;
515 /* Return a vector of pointers to accesses for the variable given in BASE or
516 NULL if there is none. */
518 static vec<access_p> *
519 get_base_access_vector (tree base)
521 return base_access_vec->get (base);
524 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
525 in ACCESS. Return NULL if it cannot be found. */
527 static struct access *
528 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
529 HOST_WIDE_INT size)
531 while (access && (access->offset != offset || access->size != size))
533 struct access *child = access->first_child;
535 while (child && (child->offset + child->size <= offset))
536 child = child->next_sibling;
537 access = child;
540 return access;
543 /* Return the first group representative for DECL or NULL if none exists. */
545 static struct access *
546 get_first_repr_for_decl (tree base)
548 vec<access_p> *access_vec;
550 access_vec = get_base_access_vector (base);
551 if (!access_vec)
552 return NULL;
554 return (*access_vec)[0];
557 /* Find an access representative for the variable BASE and given OFFSET and
558 SIZE. Requires that access trees have already been built. Return NULL if
559 it cannot be found. */
561 static struct access *
562 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
563 HOST_WIDE_INT size)
565 struct access *access;
567 access = get_first_repr_for_decl (base);
568 while (access && (access->offset + access->size <= offset))
569 access = access->next_grp;
570 if (!access)
571 return NULL;
573 return find_access_in_subtree (access, offset, size);
576 /* Add LINK to the linked list of assign links of RACC. */
577 static void
578 add_link_to_rhs (struct access *racc, struct assign_link *link)
580 gcc_assert (link->racc == racc);
582 if (!racc->first_link)
584 gcc_assert (!racc->last_link);
585 racc->first_link = link;
587 else
588 racc->last_link->next = link;
590 racc->last_link = link;
591 link->next = NULL;
594 /* Move all link structures in their linked list in OLD_RACC to the linked list
595 in NEW_RACC. */
596 static void
597 relink_to_new_repr (struct access *new_racc, struct access *old_racc)
599 if (!old_racc->first_link)
601 gcc_assert (!old_racc->last_link);
602 return;
605 if (new_racc->first_link)
607 gcc_assert (!new_racc->last_link->next);
608 gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
610 new_racc->last_link->next = old_racc->first_link;
611 new_racc->last_link = old_racc->last_link;
613 else
615 gcc_assert (!new_racc->last_link);
617 new_racc->first_link = old_racc->first_link;
618 new_racc->last_link = old_racc->last_link;
620 old_racc->first_link = old_racc->last_link = NULL;
623 /* Add ACCESS to the work queue (which is actually a stack). */
625 static void
626 add_access_to_work_queue (struct access *access)
628 if (!access->grp_queued)
630 gcc_assert (!access->next_queued);
631 access->next_queued = work_queue_head;
632 access->grp_queued = 1;
633 work_queue_head = access;
637 /* Pop an access from the work queue, and return it, assuming there is one. */
639 static struct access *
640 pop_access_from_work_queue (void)
642 struct access *access = work_queue_head;
644 work_queue_head = access->next_queued;
645 access->next_queued = NULL;
646 access->grp_queued = 0;
647 return access;
651 /* Allocate necessary structures. */
653 static void
654 sra_initialize (void)
656 candidate_bitmap = BITMAP_ALLOC (NULL);
657 candidates = new hash_table<uid_decl_hasher>
658 (vec_safe_length (cfun->local_decls) / 2);
659 should_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
660 cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
661 gcc_obstack_init (&name_obstack);
662 access_pool = create_alloc_pool ("SRA accesses", sizeof (struct access), 16);
663 link_pool = create_alloc_pool ("SRA links", sizeof (struct assign_link), 16);
664 base_access_vec = new hash_map<tree, auto_vec<access_p> >;
665 memset (&sra_stats, 0, sizeof (sra_stats));
666 encountered_apply_args = false;
667 encountered_recursive_call = false;
668 encountered_unchangable_recursive_call = false;
671 /* Deallocate all general structures. */
673 static void
674 sra_deinitialize (void)
676 BITMAP_FREE (candidate_bitmap);
677 delete candidates;
678 candidates = NULL;
679 BITMAP_FREE (should_scalarize_away_bitmap);
680 BITMAP_FREE (cannot_scalarize_away_bitmap);
681 free_alloc_pool (access_pool);
682 free_alloc_pool (link_pool);
683 obstack_free (&name_obstack, NULL);
685 delete base_access_vec;
688 /* Remove DECL from candidates for SRA and write REASON to the dump file if
689 there is one. */
690 static void
691 disqualify_candidate (tree decl, const char *reason)
693 if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl)))
694 candidates->remove_elt_with_hash (decl, DECL_UID (decl));
696 if (dump_file && (dump_flags & TDF_DETAILS))
698 fprintf (dump_file, "! Disqualifying ");
699 print_generic_expr (dump_file, decl, 0);
700 fprintf (dump_file, " - %s\n", reason);
704 /* Return true iff the type contains a field or an element which does not allow
705 scalarization. */
707 static bool
708 type_internals_preclude_sra_p (tree type, const char **msg)
710 tree fld;
711 tree et;
713 switch (TREE_CODE (type))
715 case RECORD_TYPE:
716 case UNION_TYPE:
717 case QUAL_UNION_TYPE:
718 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
719 if (TREE_CODE (fld) == FIELD_DECL)
721 tree ft = TREE_TYPE (fld);
723 if (TREE_THIS_VOLATILE (fld))
725 *msg = "volatile structure field";
726 return true;
728 if (!DECL_FIELD_OFFSET (fld))
730 *msg = "no structure field offset";
731 return true;
733 if (!DECL_SIZE (fld))
735 *msg = "zero structure field size";
736 return true;
738 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
740 *msg = "structure field offset not fixed";
741 return true;
743 if (!tree_fits_uhwi_p (DECL_SIZE (fld)))
745 *msg = "structure field size not fixed";
746 return true;
748 if (!tree_fits_shwi_p (bit_position (fld)))
750 *msg = "structure field size too big";
751 return true;
753 if (AGGREGATE_TYPE_P (ft)
754 && int_bit_position (fld) % BITS_PER_UNIT != 0)
756 *msg = "structure field is bit field";
757 return true;
760 if (AGGREGATE_TYPE_P (ft) && type_internals_preclude_sra_p (ft, msg))
761 return true;
764 return false;
766 case ARRAY_TYPE:
767 et = TREE_TYPE (type);
769 if (TYPE_VOLATILE (et))
771 *msg = "element type is volatile";
772 return true;
775 if (AGGREGATE_TYPE_P (et) && type_internals_preclude_sra_p (et, msg))
776 return true;
778 return false;
780 default:
781 return false;
785 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
786 base variable if it is. Return T if it is not an SSA_NAME. */
788 static tree
789 get_ssa_base_param (tree t)
791 if (TREE_CODE (t) == SSA_NAME)
793 if (SSA_NAME_IS_DEFAULT_DEF (t))
794 return SSA_NAME_VAR (t);
795 else
796 return NULL_TREE;
798 return t;
801 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
802 belongs to, unless the BB has already been marked as a potentially
803 final. */
805 static void
806 mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple stmt)
808 basic_block bb = gimple_bb (stmt);
809 int idx, parm_index = 0;
810 tree parm;
812 if (bitmap_bit_p (final_bbs, bb->index))
813 return;
815 for (parm = DECL_ARGUMENTS (current_function_decl);
816 parm && parm != base;
817 parm = DECL_CHAIN (parm))
818 parm_index++;
820 gcc_assert (parm_index < func_param_count);
822 idx = bb->index * func_param_count + parm_index;
823 if (bb_dereferences[idx] < dist)
824 bb_dereferences[idx] = dist;
827 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
828 the three fields. Also add it to the vector of accesses corresponding to
829 the base. Finally, return the new access. */
831 static struct access *
832 create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
834 struct access *access;
836 access = (struct access *) pool_alloc (access_pool);
837 memset (access, 0, sizeof (struct access));
838 access->base = base;
839 access->offset = offset;
840 access->size = size;
842 base_access_vec->get_or_insert (base).safe_push (access);
844 return access;
847 /* Create and insert access for EXPR. Return created access, or NULL if it is
848 not possible. */
850 static struct access *
851 create_access (tree expr, gimple stmt, bool write)
853 struct access *access;
854 HOST_WIDE_INT offset, size, max_size;
855 tree base = expr;
856 bool ptr, unscalarizable_region = false;
858 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
860 if (sra_mode == SRA_MODE_EARLY_IPA
861 && TREE_CODE (base) == MEM_REF)
863 base = get_ssa_base_param (TREE_OPERAND (base, 0));
864 if (!base)
865 return NULL;
866 ptr = true;
868 else
869 ptr = false;
871 if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
872 return NULL;
874 if (sra_mode == SRA_MODE_EARLY_IPA)
876 if (size < 0 || size != max_size)
878 disqualify_candidate (base, "Encountered a variable sized access.");
879 return NULL;
881 if (TREE_CODE (expr) == COMPONENT_REF
882 && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))
884 disqualify_candidate (base, "Encountered a bit-field access.");
885 return NULL;
887 gcc_checking_assert ((offset % BITS_PER_UNIT) == 0);
889 if (ptr)
890 mark_parm_dereference (base, offset + size, stmt);
892 else
894 if (size != max_size)
896 size = max_size;
897 unscalarizable_region = true;
899 if (size < 0)
901 disqualify_candidate (base, "Encountered an unconstrained access.");
902 return NULL;
906 access = create_access_1 (base, offset, size);
907 access->expr = expr;
908 access->type = TREE_TYPE (expr);
909 access->write = write;
910 access->grp_unscalarizable_region = unscalarizable_region;
911 access->stmt = stmt;
913 if (TREE_CODE (expr) == COMPONENT_REF
914 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1)))
915 access->non_addressable = 1;
917 return access;
921 /* Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple
922 register types or (recursively) records with only these two kinds of fields.
923 It also returns false if any of these records contains a bit-field. */
925 static bool
926 type_consists_of_records_p (tree type)
928 tree fld;
930 if (TREE_CODE (type) != RECORD_TYPE)
931 return false;
933 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
934 if (TREE_CODE (fld) == FIELD_DECL)
936 tree ft = TREE_TYPE (fld);
938 if (DECL_BIT_FIELD (fld))
939 return false;
941 if (!is_gimple_reg_type (ft)
942 && !type_consists_of_records_p (ft))
943 return false;
946 return true;
949 /* Create total_scalarization accesses for all scalar type fields in DECL that
950 must be of a RECORD_TYPE conforming to type_consists_of_records_p. BASE
951 must be the top-most VAR_DECL representing the variable, OFFSET must be the
952 offset of DECL within BASE. REF must be the memory reference expression for
953 the given decl. */
955 static void
956 completely_scalarize_record (tree base, tree decl, HOST_WIDE_INT offset,
957 tree ref)
959 tree fld, decl_type = TREE_TYPE (decl);
961 for (fld = TYPE_FIELDS (decl_type); fld; fld = DECL_CHAIN (fld))
962 if (TREE_CODE (fld) == FIELD_DECL)
964 HOST_WIDE_INT pos = offset + int_bit_position (fld);
965 tree ft = TREE_TYPE (fld);
966 tree nref = build3 (COMPONENT_REF, TREE_TYPE (fld), ref, fld,
967 NULL_TREE);
969 if (is_gimple_reg_type (ft))
971 struct access *access;
972 HOST_WIDE_INT size;
974 size = tree_to_uhwi (DECL_SIZE (fld));
975 access = create_access_1 (base, pos, size);
976 access->expr = nref;
977 access->type = ft;
978 access->grp_total_scalarization = 1;
979 /* Accesses for intraprocedural SRA can have their stmt NULL. */
981 else
982 completely_scalarize_record (base, fld, pos, nref);
986 /* Create total_scalarization accesses for all scalar type fields in VAR and
987 for VAR a a whole. VAR must be of a RECORD_TYPE conforming to
988 type_consists_of_records_p. */
990 static void
991 completely_scalarize_var (tree var)
993 HOST_WIDE_INT size = tree_to_uhwi (DECL_SIZE (var));
994 struct access *access;
996 access = create_access_1 (var, 0, size);
997 access->expr = var;
998 access->type = TREE_TYPE (var);
999 access->grp_total_scalarization = 1;
1001 completely_scalarize_record (var, var, 0, var);
1004 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1006 static inline bool
1007 contains_view_convert_expr_p (const_tree ref)
1009 while (handled_component_p (ref))
1011 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
1012 return true;
1013 ref = TREE_OPERAND (ref, 0);
1016 return false;
1019 /* Search the given tree for a declaration by skipping handled components and
1020 exclude it from the candidates. */
1022 static void
1023 disqualify_base_of_expr (tree t, const char *reason)
1025 t = get_base_address (t);
1026 if (sra_mode == SRA_MODE_EARLY_IPA
1027 && TREE_CODE (t) == MEM_REF)
1028 t = get_ssa_base_param (TREE_OPERAND (t, 0));
1030 if (t && DECL_P (t))
1031 disqualify_candidate (t, reason);
1034 /* Scan expression EXPR and create access structures for all accesses to
1035 candidates for scalarization. Return the created access or NULL if none is
1036 created. */
1038 static struct access *
1039 build_access_from_expr_1 (tree expr, gimple stmt, bool write)
1041 struct access *ret = NULL;
1042 bool partial_ref;
1044 if (TREE_CODE (expr) == BIT_FIELD_REF
1045 || TREE_CODE (expr) == IMAGPART_EXPR
1046 || TREE_CODE (expr) == REALPART_EXPR)
1048 expr = TREE_OPERAND (expr, 0);
1049 partial_ref = true;
1051 else
1052 partial_ref = false;
1054 /* We need to dive through V_C_Es in order to get the size of its parameter
1055 and not the result type. Ada produces such statements. We are also
1056 capable of handling the topmost V_C_E but not any of those buried in other
1057 handled components. */
1058 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
1059 expr = TREE_OPERAND (expr, 0);
1061 if (contains_view_convert_expr_p (expr))
1063 disqualify_base_of_expr (expr, "V_C_E under a different handled "
1064 "component.");
1065 return NULL;
1067 if (TREE_THIS_VOLATILE (expr))
1069 disqualify_base_of_expr (expr, "part of a volatile reference.");
1070 return NULL;
1073 switch (TREE_CODE (expr))
1075 case MEM_REF:
1076 if (TREE_CODE (TREE_OPERAND (expr, 0)) != ADDR_EXPR
1077 && sra_mode != SRA_MODE_EARLY_IPA)
1078 return NULL;
1079 /* fall through */
1080 case VAR_DECL:
1081 case PARM_DECL:
1082 case RESULT_DECL:
1083 case COMPONENT_REF:
1084 case ARRAY_REF:
1085 case ARRAY_RANGE_REF:
1086 ret = create_access (expr, stmt, write);
1087 break;
1089 default:
1090 break;
1093 if (write && partial_ref && ret)
1094 ret->grp_partial_lhs = 1;
1096 return ret;
1099 /* Scan expression EXPR and create access structures for all accesses to
1100 candidates for scalarization. Return true if any access has been inserted.
1101 STMT must be the statement from which the expression is taken, WRITE must be
1102 true if the expression is a store and false otherwise. */
1104 static bool
1105 build_access_from_expr (tree expr, gimple stmt, bool write)
1107 struct access *access;
1109 access = build_access_from_expr_1 (expr, stmt, write);
1110 if (access)
1112 /* This means the aggregate is accesses as a whole in a way other than an
1113 assign statement and thus cannot be removed even if we had a scalar
1114 replacement for everything. */
1115 if (cannot_scalarize_away_bitmap)
1116 bitmap_set_bit (cannot_scalarize_away_bitmap, DECL_UID (access->base));
1117 return true;
1119 return false;
1122 /* Return the single non-EH successor edge of BB or NULL if there is none or
1123 more than one. */
1125 static edge
1126 single_non_eh_succ (basic_block bb)
1128 edge e, res = NULL;
1129 edge_iterator ei;
1131 FOR_EACH_EDGE (e, ei, bb->succs)
1132 if (!(e->flags & EDGE_EH))
1134 if (res)
1135 return NULL;
1136 res = e;
1139 return res;
1142 /* Disqualify LHS and RHS for scalarization if STMT has to terminate its BB and
1143 there is no alternative spot where to put statements SRA might need to
1144 generate after it. The spot we are looking for is an edge leading to a
1145 single non-EH successor, if it exists and is indeed single. RHS may be
1146 NULL, in that case ignore it. */
1148 static bool
1149 disqualify_if_bad_bb_terminating_stmt (gimple stmt, tree lhs, tree rhs)
1151 if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1152 && stmt_ends_bb_p (stmt))
1154 if (single_non_eh_succ (gimple_bb (stmt)))
1155 return false;
1157 disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
1158 if (rhs)
1159 disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
1160 return true;
1162 return false;
1165 /* Scan expressions occurring in STMT, create access structures for all accesses
1166 to candidates for scalarization and remove those candidates which occur in
1167 statements or expressions that prevent them from being split apart. Return
1168 true if any access has been inserted. */
1170 static bool
1171 build_accesses_from_assign (gimple stmt)
1173 tree lhs, rhs;
1174 struct access *lacc, *racc;
1176 if (!gimple_assign_single_p (stmt)
1177 /* Scope clobbers don't influence scalarization. */
1178 || gimple_clobber_p (stmt))
1179 return false;
1181 lhs = gimple_assign_lhs (stmt);
1182 rhs = gimple_assign_rhs1 (stmt);
1184 if (disqualify_if_bad_bb_terminating_stmt (stmt, lhs, rhs))
1185 return false;
1187 racc = build_access_from_expr_1 (rhs, stmt, false);
1188 lacc = build_access_from_expr_1 (lhs, stmt, true);
1190 if (lacc)
1191 lacc->grp_assignment_write = 1;
1193 if (racc)
1195 racc->grp_assignment_read = 1;
1196 if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
1197 && !is_gimple_reg_type (racc->type))
1198 bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
1201 if (lacc && racc
1202 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1203 && !lacc->grp_unscalarizable_region
1204 && !racc->grp_unscalarizable_region
1205 && AGGREGATE_TYPE_P (TREE_TYPE (lhs))
1206 && lacc->size == racc->size
1207 && useless_type_conversion_p (lacc->type, racc->type))
1209 struct assign_link *link;
1211 link = (struct assign_link *) pool_alloc (link_pool);
1212 memset (link, 0, sizeof (struct assign_link));
1214 link->lacc = lacc;
1215 link->racc = racc;
1217 add_link_to_rhs (racc, link);
1220 return lacc || racc;
1223 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1224 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1226 static bool
1227 asm_visit_addr (gimple, tree op, tree, void *)
1229 op = get_base_address (op);
1230 if (op
1231 && DECL_P (op))
1232 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
1234 return false;
1237 /* Return true iff callsite CALL has at least as many actual arguments as there
1238 are formal parameters of the function currently processed by IPA-SRA and
1239 that their types match. */
1241 static inline bool
1242 callsite_arguments_match_p (gimple call)
1244 if (gimple_call_num_args (call) < (unsigned) func_param_count)
1245 return false;
1247 tree parm;
1248 int i;
1249 for (parm = DECL_ARGUMENTS (current_function_decl), i = 0;
1250 parm;
1251 parm = DECL_CHAIN (parm), i++)
1253 tree arg = gimple_call_arg (call, i);
1254 if (!useless_type_conversion_p (TREE_TYPE (parm), TREE_TYPE (arg)))
1255 return false;
1257 return true;
1260 /* Scan function and look for interesting expressions and create access
1261 structures for them. Return true iff any access is created. */
1263 static bool
1264 scan_function (void)
1266 basic_block bb;
1267 bool ret = false;
1269 FOR_EACH_BB_FN (bb, cfun)
1271 gimple_stmt_iterator gsi;
1272 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1274 gimple stmt = gsi_stmt (gsi);
1275 tree t;
1276 unsigned i;
1278 if (final_bbs && stmt_can_throw_external (stmt))
1279 bitmap_set_bit (final_bbs, bb->index);
1280 switch (gimple_code (stmt))
1282 case GIMPLE_RETURN:
1283 t = gimple_return_retval (stmt);
1284 if (t != NULL_TREE)
1285 ret |= build_access_from_expr (t, stmt, false);
1286 if (final_bbs)
1287 bitmap_set_bit (final_bbs, bb->index);
1288 break;
1290 case GIMPLE_ASSIGN:
1291 ret |= build_accesses_from_assign (stmt);
1292 break;
1294 case GIMPLE_CALL:
1295 for (i = 0; i < gimple_call_num_args (stmt); i++)
1296 ret |= build_access_from_expr (gimple_call_arg (stmt, i),
1297 stmt, false);
1299 if (sra_mode == SRA_MODE_EARLY_IPA)
1301 tree dest = gimple_call_fndecl (stmt);
1302 int flags = gimple_call_flags (stmt);
1304 if (dest)
1306 if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1307 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1308 encountered_apply_args = true;
1309 if (recursive_call_p (current_function_decl, dest))
1311 encountered_recursive_call = true;
1312 if (!callsite_arguments_match_p (stmt))
1313 encountered_unchangable_recursive_call = true;
1317 if (final_bbs
1318 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1319 bitmap_set_bit (final_bbs, bb->index);
1322 t = gimple_call_lhs (stmt);
1323 if (t && !disqualify_if_bad_bb_terminating_stmt (stmt, t, NULL))
1324 ret |= build_access_from_expr (t, stmt, true);
1325 break;
1327 case GIMPLE_ASM:
1329 gimple_asm asm_stmt = as_a <gimple_asm> (stmt);
1330 walk_stmt_load_store_addr_ops (asm_stmt, NULL, NULL, NULL,
1331 asm_visit_addr);
1332 if (final_bbs)
1333 bitmap_set_bit (final_bbs, bb->index);
1335 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
1337 t = TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
1338 ret |= build_access_from_expr (t, asm_stmt, false);
1340 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
1342 t = TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
1343 ret |= build_access_from_expr (t, asm_stmt, true);
1346 break;
1348 default:
1349 break;
1354 return ret;
1357 /* Helper of QSORT function. There are pointers to accesses in the array. An
1358 access is considered smaller than another if it has smaller offset or if the
1359 offsets are the same but is size is bigger. */
1361 static int
1362 compare_access_positions (const void *a, const void *b)
1364 const access_p *fp1 = (const access_p *) a;
1365 const access_p *fp2 = (const access_p *) b;
1366 const access_p f1 = *fp1;
1367 const access_p f2 = *fp2;
1369 if (f1->offset != f2->offset)
1370 return f1->offset < f2->offset ? -1 : 1;
1372 if (f1->size == f2->size)
1374 if (f1->type == f2->type)
1375 return 0;
1376 /* Put any non-aggregate type before any aggregate type. */
1377 else if (!is_gimple_reg_type (f1->type)
1378 && is_gimple_reg_type (f2->type))
1379 return 1;
1380 else if (is_gimple_reg_type (f1->type)
1381 && !is_gimple_reg_type (f2->type))
1382 return -1;
1383 /* Put any complex or vector type before any other scalar type. */
1384 else if (TREE_CODE (f1->type) != COMPLEX_TYPE
1385 && TREE_CODE (f1->type) != VECTOR_TYPE
1386 && (TREE_CODE (f2->type) == COMPLEX_TYPE
1387 || TREE_CODE (f2->type) == VECTOR_TYPE))
1388 return 1;
1389 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
1390 || TREE_CODE (f1->type) == VECTOR_TYPE)
1391 && TREE_CODE (f2->type) != COMPLEX_TYPE
1392 && TREE_CODE (f2->type) != VECTOR_TYPE)
1393 return -1;
1394 /* Put the integral type with the bigger precision first. */
1395 else if (INTEGRAL_TYPE_P (f1->type)
1396 && INTEGRAL_TYPE_P (f2->type))
1397 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
1398 /* Put any integral type with non-full precision last. */
1399 else if (INTEGRAL_TYPE_P (f1->type)
1400 && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type))
1401 != TYPE_PRECISION (f1->type)))
1402 return 1;
1403 else if (INTEGRAL_TYPE_P (f2->type)
1404 && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type))
1405 != TYPE_PRECISION (f2->type)))
1406 return -1;
1407 /* Stabilize the sort. */
1408 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1411 /* We want the bigger accesses first, thus the opposite operator in the next
1412 line: */
1413 return f1->size > f2->size ? -1 : 1;
1417 /* Append a name of the declaration to the name obstack. A helper function for
1418 make_fancy_name. */
1420 static void
1421 make_fancy_decl_name (tree decl)
1423 char buffer[32];
1425 tree name = DECL_NAME (decl);
1426 if (name)
1427 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1428 IDENTIFIER_LENGTH (name));
1429 else
1431 sprintf (buffer, "D%u", DECL_UID (decl));
1432 obstack_grow (&name_obstack, buffer, strlen (buffer));
1436 /* Helper for make_fancy_name. */
1438 static void
1439 make_fancy_name_1 (tree expr)
1441 char buffer[32];
1442 tree index;
1444 if (DECL_P (expr))
1446 make_fancy_decl_name (expr);
1447 return;
1450 switch (TREE_CODE (expr))
1452 case COMPONENT_REF:
1453 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1454 obstack_1grow (&name_obstack, '$');
1455 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1456 break;
1458 case ARRAY_REF:
1459 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1460 obstack_1grow (&name_obstack, '$');
1461 /* Arrays with only one element may not have a constant as their
1462 index. */
1463 index = TREE_OPERAND (expr, 1);
1464 if (TREE_CODE (index) != INTEGER_CST)
1465 break;
1466 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1467 obstack_grow (&name_obstack, buffer, strlen (buffer));
1468 break;
1470 case ADDR_EXPR:
1471 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1472 break;
1474 case MEM_REF:
1475 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1476 if (!integer_zerop (TREE_OPERAND (expr, 1)))
1478 obstack_1grow (&name_obstack, '$');
1479 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC,
1480 TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)));
1481 obstack_grow (&name_obstack, buffer, strlen (buffer));
1483 break;
1485 case BIT_FIELD_REF:
1486 case REALPART_EXPR:
1487 case IMAGPART_EXPR:
1488 gcc_unreachable (); /* we treat these as scalars. */
1489 break;
1490 default:
1491 break;
1495 /* Create a human readable name for replacement variable of ACCESS. */
1497 static char *
1498 make_fancy_name (tree expr)
1500 make_fancy_name_1 (expr);
1501 obstack_1grow (&name_obstack, '\0');
1502 return XOBFINISH (&name_obstack, char *);
1505 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1506 EXP_TYPE at the given OFFSET. If BASE is something for which
1507 get_addr_base_and_unit_offset returns NULL, gsi must be non-NULL and is used
1508 to insert new statements either before or below the current one as specified
1509 by INSERT_AFTER. This function is not capable of handling bitfields.
1511 BASE must be either a declaration or a memory reference that has correct
1512 alignment ifformation embeded in it (e.g. a pre-existing one in SRA). */
1514 tree
1515 build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
1516 tree exp_type, gimple_stmt_iterator *gsi,
1517 bool insert_after)
1519 tree prev_base = base;
1520 tree off;
1521 tree mem_ref;
1522 HOST_WIDE_INT base_offset;
1523 unsigned HOST_WIDE_INT misalign;
1524 unsigned int align;
1526 gcc_checking_assert (offset % BITS_PER_UNIT == 0);
1527 get_object_alignment_1 (base, &align, &misalign);
1528 base = get_addr_base_and_unit_offset (base, &base_offset);
1530 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1531 offset such as array[var_index]. */
1532 if (!base)
1534 gimple_assign stmt;
1535 tree tmp, addr;
1537 gcc_checking_assert (gsi);
1538 tmp = make_ssa_name (build_pointer_type (TREE_TYPE (prev_base)), NULL);
1539 addr = build_fold_addr_expr (unshare_expr (prev_base));
1540 STRIP_USELESS_TYPE_CONVERSION (addr);
1541 stmt = gimple_build_assign (tmp, addr);
1542 gimple_set_location (stmt, loc);
1543 if (insert_after)
1544 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
1545 else
1546 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1548 off = build_int_cst (reference_alias_ptr_type (prev_base),
1549 offset / BITS_PER_UNIT);
1550 base = tmp;
1552 else if (TREE_CODE (base) == MEM_REF)
1554 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1555 base_offset + offset / BITS_PER_UNIT);
1556 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1557 base = unshare_expr (TREE_OPERAND (base, 0));
1559 else
1561 off = build_int_cst (reference_alias_ptr_type (base),
1562 base_offset + offset / BITS_PER_UNIT);
1563 base = build_fold_addr_expr (unshare_expr (base));
1566 misalign = (misalign + offset) & (align - 1);
1567 if (misalign != 0)
1568 align = (misalign & -misalign);
1569 if (align < TYPE_ALIGN (exp_type))
1570 exp_type = build_aligned_type (exp_type, align);
1572 mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off);
1573 if (TREE_THIS_VOLATILE (prev_base))
1574 TREE_THIS_VOLATILE (mem_ref) = 1;
1575 if (TREE_SIDE_EFFECTS (prev_base))
1576 TREE_SIDE_EFFECTS (mem_ref) = 1;
1577 return mem_ref;
1580 /* Construct a memory reference to a part of an aggregate BASE at the given
1581 OFFSET and of the same type as MODEL. In case this is a reference to a
1582 bit-field, the function will replicate the last component_ref of model's
1583 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1584 build_ref_for_offset. */
1586 static tree
1587 build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1588 struct access *model, gimple_stmt_iterator *gsi,
1589 bool insert_after)
1591 if (TREE_CODE (model->expr) == COMPONENT_REF
1592 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1594 /* This access represents a bit-field. */
1595 tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
1597 offset -= int_bit_position (fld);
1598 exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
1599 t = build_ref_for_offset (loc, base, offset, exp_type, gsi, insert_after);
1600 return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
1601 NULL_TREE);
1603 else
1604 return build_ref_for_offset (loc, base, offset, model->type,
1605 gsi, insert_after);
1608 /* Attempt to build a memory reference that we could but into a gimple
1609 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1610 create statements and return s NULL instead. This function also ignores
1611 alignment issues and so its results should never end up in non-debug
1612 statements. */
1614 static tree
1615 build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1616 struct access *model)
1618 HOST_WIDE_INT base_offset;
1619 tree off;
1621 if (TREE_CODE (model->expr) == COMPONENT_REF
1622 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1623 return NULL_TREE;
1625 base = get_addr_base_and_unit_offset (base, &base_offset);
1626 if (!base)
1627 return NULL_TREE;
1628 if (TREE_CODE (base) == MEM_REF)
1630 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1631 base_offset + offset / BITS_PER_UNIT);
1632 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1633 base = unshare_expr (TREE_OPERAND (base, 0));
1635 else
1637 off = build_int_cst (reference_alias_ptr_type (base),
1638 base_offset + offset / BITS_PER_UNIT);
1639 base = build_fold_addr_expr (unshare_expr (base));
1642 return fold_build2_loc (loc, MEM_REF, model->type, base, off);
1645 /* Construct a memory reference consisting of component_refs and array_refs to
1646 a part of an aggregate *RES (which is of type TYPE). The requested part
1647 should have type EXP_TYPE at be the given OFFSET. This function might not
1648 succeed, it returns true when it does and only then *RES points to something
1649 meaningful. This function should be used only to build expressions that we
1650 might need to present to user (e.g. in warnings). In all other situations,
1651 build_ref_for_model or build_ref_for_offset should be used instead. */
1653 static bool
1654 build_user_friendly_ref_for_offset (tree *res, tree type, HOST_WIDE_INT offset,
1655 tree exp_type)
1657 while (1)
1659 tree fld;
1660 tree tr_size, index, minidx;
1661 HOST_WIDE_INT el_size;
1663 if (offset == 0 && exp_type
1664 && types_compatible_p (exp_type, type))
1665 return true;
1667 switch (TREE_CODE (type))
1669 case UNION_TYPE:
1670 case QUAL_UNION_TYPE:
1671 case RECORD_TYPE:
1672 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
1674 HOST_WIDE_INT pos, size;
1675 tree tr_pos, expr, *expr_ptr;
1677 if (TREE_CODE (fld) != FIELD_DECL)
1678 continue;
1680 tr_pos = bit_position (fld);
1681 if (!tr_pos || !tree_fits_uhwi_p (tr_pos))
1682 continue;
1683 pos = tree_to_uhwi (tr_pos);
1684 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1685 tr_size = DECL_SIZE (fld);
1686 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1687 continue;
1688 size = tree_to_uhwi (tr_size);
1689 if (size == 0)
1691 if (pos != offset)
1692 continue;
1694 else if (pos > offset || (pos + size) <= offset)
1695 continue;
1697 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1698 NULL_TREE);
1699 expr_ptr = &expr;
1700 if (build_user_friendly_ref_for_offset (expr_ptr, TREE_TYPE (fld),
1701 offset - pos, exp_type))
1703 *res = expr;
1704 return true;
1707 return false;
1709 case ARRAY_TYPE:
1710 tr_size = TYPE_SIZE (TREE_TYPE (type));
1711 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1712 return false;
1713 el_size = tree_to_uhwi (tr_size);
1715 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1716 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
1717 return false;
1718 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1719 if (!integer_zerop (minidx))
1720 index = int_const_binop (PLUS_EXPR, index, minidx);
1721 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1722 NULL_TREE, NULL_TREE);
1723 offset = offset % el_size;
1724 type = TREE_TYPE (type);
1725 break;
1727 default:
1728 if (offset != 0)
1729 return false;
1731 if (exp_type)
1732 return false;
1733 else
1734 return true;
1739 /* Return true iff TYPE is stdarg va_list type. */
1741 static inline bool
1742 is_va_list_type (tree type)
1744 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1747 /* Print message to dump file why a variable was rejected. */
1749 static void
1750 reject (tree var, const char *msg)
1752 if (dump_file && (dump_flags & TDF_DETAILS))
1754 fprintf (dump_file, "Rejected (%d): %s: ", DECL_UID (var), msg);
1755 print_generic_expr (dump_file, var, 0);
1756 fprintf (dump_file, "\n");
1760 /* Return true if VAR is a candidate for SRA. */
1762 static bool
1763 maybe_add_sra_candidate (tree var)
1765 tree type = TREE_TYPE (var);
1766 const char *msg;
1767 tree_node **slot;
1769 if (!AGGREGATE_TYPE_P (type))
1771 reject (var, "not aggregate");
1772 return false;
1774 if (needs_to_live_in_memory (var))
1776 reject (var, "needs to live in memory");
1777 return false;
1779 if (TREE_THIS_VOLATILE (var))
1781 reject (var, "is volatile");
1782 return false;
1784 if (!COMPLETE_TYPE_P (type))
1786 reject (var, "has incomplete type");
1787 return false;
1789 if (!tree_fits_uhwi_p (TYPE_SIZE (type)))
1791 reject (var, "type size not fixed");
1792 return false;
1794 if (tree_to_uhwi (TYPE_SIZE (type)) == 0)
1796 reject (var, "type size is zero");
1797 return false;
1799 if (type_internals_preclude_sra_p (type, &msg))
1801 reject (var, msg);
1802 return false;
1804 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1805 we also want to schedule it rather late. Thus we ignore it in
1806 the early pass. */
1807 (sra_mode == SRA_MODE_EARLY_INTRA
1808 && is_va_list_type (type)))
1810 reject (var, "is va_list");
1811 return false;
1814 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
1815 slot = candidates->find_slot_with_hash (var, DECL_UID (var), INSERT);
1816 *slot = var;
1818 if (dump_file && (dump_flags & TDF_DETAILS))
1820 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
1821 print_generic_expr (dump_file, var, 0);
1822 fprintf (dump_file, "\n");
1825 return true;
1828 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1829 those with type which is suitable for scalarization. */
1831 static bool
1832 find_var_candidates (void)
1834 tree var, parm;
1835 unsigned int i;
1836 bool ret = false;
1838 for (parm = DECL_ARGUMENTS (current_function_decl);
1839 parm;
1840 parm = DECL_CHAIN (parm))
1841 ret |= maybe_add_sra_candidate (parm);
1843 FOR_EACH_LOCAL_DECL (cfun, i, var)
1845 if (TREE_CODE (var) != VAR_DECL)
1846 continue;
1848 ret |= maybe_add_sra_candidate (var);
1851 return ret;
1854 /* Sort all accesses for the given variable, check for partial overlaps and
1855 return NULL if there are any. If there are none, pick a representative for
1856 each combination of offset and size and create a linked list out of them.
1857 Return the pointer to the first representative and make sure it is the first
1858 one in the vector of accesses. */
1860 static struct access *
1861 sort_and_splice_var_accesses (tree var)
1863 int i, j, access_count;
1864 struct access *res, **prev_acc_ptr = &res;
1865 vec<access_p> *access_vec;
1866 bool first = true;
1867 HOST_WIDE_INT low = -1, high = 0;
1869 access_vec = get_base_access_vector (var);
1870 if (!access_vec)
1871 return NULL;
1872 access_count = access_vec->length ();
1874 /* Sort by <OFFSET, SIZE>. */
1875 access_vec->qsort (compare_access_positions);
1877 i = 0;
1878 while (i < access_count)
1880 struct access *access = (*access_vec)[i];
1881 bool grp_write = access->write;
1882 bool grp_read = !access->write;
1883 bool grp_scalar_write = access->write
1884 && is_gimple_reg_type (access->type);
1885 bool grp_scalar_read = !access->write
1886 && is_gimple_reg_type (access->type);
1887 bool grp_assignment_read = access->grp_assignment_read;
1888 bool grp_assignment_write = access->grp_assignment_write;
1889 bool multiple_scalar_reads = false;
1890 bool total_scalarization = access->grp_total_scalarization;
1891 bool grp_partial_lhs = access->grp_partial_lhs;
1892 bool first_scalar = is_gimple_reg_type (access->type);
1893 bool unscalarizable_region = access->grp_unscalarizable_region;
1895 if (first || access->offset >= high)
1897 first = false;
1898 low = access->offset;
1899 high = access->offset + access->size;
1901 else if (access->offset > low && access->offset + access->size > high)
1902 return NULL;
1903 else
1904 gcc_assert (access->offset >= low
1905 && access->offset + access->size <= high);
1907 j = i + 1;
1908 while (j < access_count)
1910 struct access *ac2 = (*access_vec)[j];
1911 if (ac2->offset != access->offset || ac2->size != access->size)
1912 break;
1913 if (ac2->write)
1915 grp_write = true;
1916 grp_scalar_write = (grp_scalar_write
1917 || is_gimple_reg_type (ac2->type));
1919 else
1921 grp_read = true;
1922 if (is_gimple_reg_type (ac2->type))
1924 if (grp_scalar_read)
1925 multiple_scalar_reads = true;
1926 else
1927 grp_scalar_read = true;
1930 grp_assignment_read |= ac2->grp_assignment_read;
1931 grp_assignment_write |= ac2->grp_assignment_write;
1932 grp_partial_lhs |= ac2->grp_partial_lhs;
1933 unscalarizable_region |= ac2->grp_unscalarizable_region;
1934 total_scalarization |= ac2->grp_total_scalarization;
1935 relink_to_new_repr (access, ac2);
1937 /* If there are both aggregate-type and scalar-type accesses with
1938 this combination of size and offset, the comparison function
1939 should have put the scalars first. */
1940 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
1941 ac2->group_representative = access;
1942 j++;
1945 i = j;
1947 access->group_representative = access;
1948 access->grp_write = grp_write;
1949 access->grp_read = grp_read;
1950 access->grp_scalar_read = grp_scalar_read;
1951 access->grp_scalar_write = grp_scalar_write;
1952 access->grp_assignment_read = grp_assignment_read;
1953 access->grp_assignment_write = grp_assignment_write;
1954 access->grp_hint = multiple_scalar_reads || total_scalarization;
1955 access->grp_total_scalarization = total_scalarization;
1956 access->grp_partial_lhs = grp_partial_lhs;
1957 access->grp_unscalarizable_region = unscalarizable_region;
1958 if (access->first_link)
1959 add_access_to_work_queue (access);
1961 *prev_acc_ptr = access;
1962 prev_acc_ptr = &access->next_grp;
1965 gcc_assert (res == (*access_vec)[0]);
1966 return res;
1969 /* Create a variable for the given ACCESS which determines the type, name and a
1970 few other properties. Return the variable declaration and store it also to
1971 ACCESS->replacement. */
1973 static tree
1974 create_access_replacement (struct access *access)
1976 tree repl;
1978 if (access->grp_to_be_debug_replaced)
1980 repl = create_tmp_var_raw (access->type, NULL);
1981 DECL_CONTEXT (repl) = current_function_decl;
1983 else
1984 repl = create_tmp_var (access->type, "SR");
1985 if (TREE_CODE (access->type) == COMPLEX_TYPE
1986 || TREE_CODE (access->type) == VECTOR_TYPE)
1988 if (!access->grp_partial_lhs)
1989 DECL_GIMPLE_REG_P (repl) = 1;
1991 else if (access->grp_partial_lhs
1992 && is_gimple_reg_type (access->type))
1993 TREE_ADDRESSABLE (repl) = 1;
1995 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
1996 DECL_ARTIFICIAL (repl) = 1;
1997 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
1999 if (DECL_NAME (access->base)
2000 && !DECL_IGNORED_P (access->base)
2001 && !DECL_ARTIFICIAL (access->base))
2003 char *pretty_name = make_fancy_name (access->expr);
2004 tree debug_expr = unshare_expr_without_location (access->expr), d;
2005 bool fail = false;
2007 DECL_NAME (repl) = get_identifier (pretty_name);
2008 obstack_free (&name_obstack, pretty_name);
2010 /* Get rid of any SSA_NAMEs embedded in debug_expr,
2011 as DECL_DEBUG_EXPR isn't considered when looking for still
2012 used SSA_NAMEs and thus they could be freed. All debug info
2013 generation cares is whether something is constant or variable
2014 and that get_ref_base_and_extent works properly on the
2015 expression. It cannot handle accesses at a non-constant offset
2016 though, so just give up in those cases. */
2017 for (d = debug_expr;
2018 !fail && (handled_component_p (d) || TREE_CODE (d) == MEM_REF);
2019 d = TREE_OPERAND (d, 0))
2020 switch (TREE_CODE (d))
2022 case ARRAY_REF:
2023 case ARRAY_RANGE_REF:
2024 if (TREE_OPERAND (d, 1)
2025 && TREE_CODE (TREE_OPERAND (d, 1)) != INTEGER_CST)
2026 fail = true;
2027 if (TREE_OPERAND (d, 3)
2028 && TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST)
2029 fail = true;
2030 /* FALLTHRU */
2031 case COMPONENT_REF:
2032 if (TREE_OPERAND (d, 2)
2033 && TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST)
2034 fail = true;
2035 break;
2036 case MEM_REF:
2037 if (TREE_CODE (TREE_OPERAND (d, 0)) != ADDR_EXPR)
2038 fail = true;
2039 else
2040 d = TREE_OPERAND (d, 0);
2041 break;
2042 default:
2043 break;
2045 if (!fail)
2047 SET_DECL_DEBUG_EXPR (repl, debug_expr);
2048 DECL_HAS_DEBUG_EXPR_P (repl) = 1;
2050 if (access->grp_no_warning)
2051 TREE_NO_WARNING (repl) = 1;
2052 else
2053 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
2055 else
2056 TREE_NO_WARNING (repl) = 1;
2058 if (dump_file)
2060 if (access->grp_to_be_debug_replaced)
2062 fprintf (dump_file, "Created a debug-only replacement for ");
2063 print_generic_expr (dump_file, access->base, 0);
2064 fprintf (dump_file, " offset: %u, size: %u\n",
2065 (unsigned) access->offset, (unsigned) access->size);
2067 else
2069 fprintf (dump_file, "Created a replacement for ");
2070 print_generic_expr (dump_file, access->base, 0);
2071 fprintf (dump_file, " offset: %u, size: %u: ",
2072 (unsigned) access->offset, (unsigned) access->size);
2073 print_generic_expr (dump_file, repl, 0);
2074 fprintf (dump_file, "\n");
2077 sra_stats.replacements++;
2079 return repl;
2082 /* Return ACCESS scalar replacement, create it if it does not exist yet. */
2084 static inline tree
2085 get_access_replacement (struct access *access)
2087 gcc_checking_assert (access->replacement_decl);
2088 return access->replacement_decl;
2092 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2093 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2094 to it is not "within" the root. Return false iff some accesses partially
2095 overlap. */
2097 static bool
2098 build_access_subtree (struct access **access)
2100 struct access *root = *access, *last_child = NULL;
2101 HOST_WIDE_INT limit = root->offset + root->size;
2103 *access = (*access)->next_grp;
2104 while (*access && (*access)->offset + (*access)->size <= limit)
2106 if (!last_child)
2107 root->first_child = *access;
2108 else
2109 last_child->next_sibling = *access;
2110 last_child = *access;
2112 if (!build_access_subtree (access))
2113 return false;
2116 if (*access && (*access)->offset < limit)
2117 return false;
2119 return true;
2122 /* Build a tree of access representatives, ACCESS is the pointer to the first
2123 one, others are linked in a list by the next_grp field. Return false iff
2124 some accesses partially overlap. */
2126 static bool
2127 build_access_trees (struct access *access)
2129 while (access)
2131 struct access *root = access;
2133 if (!build_access_subtree (&access))
2134 return false;
2135 root->next_grp = access;
2137 return true;
2140 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2141 array. */
2143 static bool
2144 expr_with_var_bounded_array_refs_p (tree expr)
2146 while (handled_component_p (expr))
2148 if (TREE_CODE (expr) == ARRAY_REF
2149 && !tree_fits_shwi_p (array_ref_low_bound (expr)))
2150 return true;
2151 expr = TREE_OPERAND (expr, 0);
2153 return false;
2156 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2157 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2158 sorts of access flags appropriately along the way, notably always set
2159 grp_read and grp_assign_read according to MARK_READ and grp_write when
2160 MARK_WRITE is true.
2162 Creating a replacement for a scalar access is considered beneficial if its
2163 grp_hint is set (this means we are either attempting total scalarization or
2164 there is more than one direct read access) or according to the following
2165 table:
2167 Access written to through a scalar type (once or more times)
2169 | Written to in an assignment statement
2171 | | Access read as scalar _once_
2172 | | |
2173 | | | Read in an assignment statement
2174 | | | |
2175 | | | | Scalarize Comment
2176 -----------------------------------------------------------------------------
2177 0 0 0 0 No access for the scalar
2178 0 0 0 1 No access for the scalar
2179 0 0 1 0 No Single read - won't help
2180 0 0 1 1 No The same case
2181 0 1 0 0 No access for the scalar
2182 0 1 0 1 No access for the scalar
2183 0 1 1 0 Yes s = *g; return s.i;
2184 0 1 1 1 Yes The same case as above
2185 1 0 0 0 No Won't help
2186 1 0 0 1 Yes s.i = 1; *g = s;
2187 1 0 1 0 Yes s.i = 5; g = s.i;
2188 1 0 1 1 Yes The same case as above
2189 1 1 0 0 No Won't help.
2190 1 1 0 1 Yes s.i = 1; *g = s;
2191 1 1 1 0 Yes s = *g; return s.i;
2192 1 1 1 1 Yes Any of the above yeses */
2194 static bool
2195 analyze_access_subtree (struct access *root, struct access *parent,
2196 bool allow_replacements)
2198 struct access *child;
2199 HOST_WIDE_INT limit = root->offset + root->size;
2200 HOST_WIDE_INT covered_to = root->offset;
2201 bool scalar = is_gimple_reg_type (root->type);
2202 bool hole = false, sth_created = false;
2204 if (parent)
2206 if (parent->grp_read)
2207 root->grp_read = 1;
2208 if (parent->grp_assignment_read)
2209 root->grp_assignment_read = 1;
2210 if (parent->grp_write)
2211 root->grp_write = 1;
2212 if (parent->grp_assignment_write)
2213 root->grp_assignment_write = 1;
2214 if (parent->grp_total_scalarization)
2215 root->grp_total_scalarization = 1;
2218 if (root->grp_unscalarizable_region)
2219 allow_replacements = false;
2221 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
2222 allow_replacements = false;
2224 for (child = root->first_child; child; child = child->next_sibling)
2226 hole |= covered_to < child->offset;
2227 sth_created |= analyze_access_subtree (child, root,
2228 allow_replacements && !scalar);
2230 root->grp_unscalarized_data |= child->grp_unscalarized_data;
2231 root->grp_total_scalarization &= child->grp_total_scalarization;
2232 if (child->grp_covered)
2233 covered_to += child->size;
2234 else
2235 hole = true;
2238 if (allow_replacements && scalar && !root->first_child
2239 && (root->grp_hint
2240 || ((root->grp_scalar_read || root->grp_assignment_read)
2241 && (root->grp_scalar_write || root->grp_assignment_write))))
2243 /* Always create access replacements that cover the whole access.
2244 For integral types this means the precision has to match.
2245 Avoid assumptions based on the integral type kind, too. */
2246 if (INTEGRAL_TYPE_P (root->type)
2247 && (TREE_CODE (root->type) != INTEGER_TYPE
2248 || TYPE_PRECISION (root->type) != root->size)
2249 /* But leave bitfield accesses alone. */
2250 && (TREE_CODE (root->expr) != COMPONENT_REF
2251 || !DECL_BIT_FIELD (TREE_OPERAND (root->expr, 1))))
2253 tree rt = root->type;
2254 gcc_assert ((root->offset % BITS_PER_UNIT) == 0
2255 && (root->size % BITS_PER_UNIT) == 0);
2256 root->type = build_nonstandard_integer_type (root->size,
2257 TYPE_UNSIGNED (rt));
2258 root->expr = build_ref_for_offset (UNKNOWN_LOCATION,
2259 root->base, root->offset,
2260 root->type, NULL, false);
2262 if (dump_file && (dump_flags & TDF_DETAILS))
2264 fprintf (dump_file, "Changing the type of a replacement for ");
2265 print_generic_expr (dump_file, root->base, 0);
2266 fprintf (dump_file, " offset: %u, size: %u ",
2267 (unsigned) root->offset, (unsigned) root->size);
2268 fprintf (dump_file, " to an integer.\n");
2272 root->grp_to_be_replaced = 1;
2273 root->replacement_decl = create_access_replacement (root);
2274 sth_created = true;
2275 hole = false;
2277 else
2279 if (allow_replacements
2280 && scalar && !root->first_child
2281 && (root->grp_scalar_write || root->grp_assignment_write)
2282 && !bitmap_bit_p (cannot_scalarize_away_bitmap,
2283 DECL_UID (root->base)))
2285 gcc_checking_assert (!root->grp_scalar_read
2286 && !root->grp_assignment_read);
2287 sth_created = true;
2288 if (MAY_HAVE_DEBUG_STMTS)
2290 root->grp_to_be_debug_replaced = 1;
2291 root->replacement_decl = create_access_replacement (root);
2295 if (covered_to < limit)
2296 hole = true;
2297 if (scalar)
2298 root->grp_total_scalarization = 0;
2301 if (!hole || root->grp_total_scalarization)
2302 root->grp_covered = 1;
2303 else if (root->grp_write || TREE_CODE (root->base) == PARM_DECL)
2304 root->grp_unscalarized_data = 1; /* not covered and written to */
2305 return sth_created;
2308 /* Analyze all access trees linked by next_grp by the means of
2309 analyze_access_subtree. */
2310 static bool
2311 analyze_access_trees (struct access *access)
2313 bool ret = false;
2315 while (access)
2317 if (analyze_access_subtree (access, NULL, true))
2318 ret = true;
2319 access = access->next_grp;
2322 return ret;
2325 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2326 SIZE would conflict with an already existing one. If exactly such a child
2327 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2329 static bool
2330 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
2331 HOST_WIDE_INT size, struct access **exact_match)
2333 struct access *child;
2335 for (child = lacc->first_child; child; child = child->next_sibling)
2337 if (child->offset == norm_offset && child->size == size)
2339 *exact_match = child;
2340 return true;
2343 if (child->offset < norm_offset + size
2344 && child->offset + child->size > norm_offset)
2345 return true;
2348 return false;
2351 /* Create a new child access of PARENT, with all properties just like MODEL
2352 except for its offset and with its grp_write false and grp_read true.
2353 Return the new access or NULL if it cannot be created. Note that this access
2354 is created long after all splicing and sorting, it's not located in any
2355 access vector and is automatically a representative of its group. */
2357 static struct access *
2358 create_artificial_child_access (struct access *parent, struct access *model,
2359 HOST_WIDE_INT new_offset)
2361 struct access *access;
2362 struct access **child;
2363 tree expr = parent->base;
2365 gcc_assert (!model->grp_unscalarizable_region);
2367 access = (struct access *) pool_alloc (access_pool);
2368 memset (access, 0, sizeof (struct access));
2369 if (!build_user_friendly_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
2370 model->type))
2372 access->grp_no_warning = true;
2373 expr = build_ref_for_model (EXPR_LOCATION (parent->base), parent->base,
2374 new_offset, model, NULL, false);
2377 access->base = parent->base;
2378 access->expr = expr;
2379 access->offset = new_offset;
2380 access->size = model->size;
2381 access->type = model->type;
2382 access->grp_write = true;
2383 access->grp_read = false;
2385 child = &parent->first_child;
2386 while (*child && (*child)->offset < new_offset)
2387 child = &(*child)->next_sibling;
2389 access->next_sibling = *child;
2390 *child = access;
2392 return access;
2396 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
2397 true if any new subaccess was created. Additionally, if RACC is a scalar
2398 access but LACC is not, change the type of the latter, if possible. */
2400 static bool
2401 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
2403 struct access *rchild;
2404 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
2405 bool ret = false;
2407 if (is_gimple_reg_type (lacc->type)
2408 || lacc->grp_unscalarizable_region
2409 || racc->grp_unscalarizable_region)
2410 return false;
2412 if (is_gimple_reg_type (racc->type))
2414 if (!lacc->first_child && !racc->first_child)
2416 tree t = lacc->base;
2418 lacc->type = racc->type;
2419 if (build_user_friendly_ref_for_offset (&t, TREE_TYPE (t),
2420 lacc->offset, racc->type))
2421 lacc->expr = t;
2422 else
2424 lacc->expr = build_ref_for_model (EXPR_LOCATION (lacc->base),
2425 lacc->base, lacc->offset,
2426 racc, NULL, false);
2427 lacc->grp_no_warning = true;
2430 return false;
2433 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
2435 struct access *new_acc = NULL;
2436 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
2438 if (rchild->grp_unscalarizable_region)
2439 continue;
2441 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
2442 &new_acc))
2444 if (new_acc)
2446 rchild->grp_hint = 1;
2447 new_acc->grp_hint |= new_acc->grp_read;
2448 if (rchild->first_child)
2449 ret |= propagate_subaccesses_across_link (new_acc, rchild);
2451 continue;
2454 rchild->grp_hint = 1;
2455 new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
2456 if (new_acc)
2458 ret = true;
2459 if (racc->first_child)
2460 propagate_subaccesses_across_link (new_acc, rchild);
2464 return ret;
2467 /* Propagate all subaccesses across assignment links. */
2469 static void
2470 propagate_all_subaccesses (void)
2472 while (work_queue_head)
2474 struct access *racc = pop_access_from_work_queue ();
2475 struct assign_link *link;
2477 gcc_assert (racc->first_link);
2479 for (link = racc->first_link; link; link = link->next)
2481 struct access *lacc = link->lacc;
2483 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
2484 continue;
2485 lacc = lacc->group_representative;
2486 if (propagate_subaccesses_across_link (lacc, racc)
2487 && lacc->first_link)
2488 add_access_to_work_queue (lacc);
2493 /* Go through all accesses collected throughout the (intraprocedural) analysis
2494 stage, exclude overlapping ones, identify representatives and build trees
2495 out of them, making decisions about scalarization on the way. Return true
2496 iff there are any to-be-scalarized variables after this stage. */
2498 static bool
2499 analyze_all_variable_accesses (void)
2501 int res = 0;
2502 bitmap tmp = BITMAP_ALLOC (NULL);
2503 bitmap_iterator bi;
2504 unsigned i, max_total_scalarization_size;
2506 max_total_scalarization_size = UNITS_PER_WORD * BITS_PER_UNIT
2507 * MOVE_RATIO (optimize_function_for_speed_p (cfun));
2509 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
2510 if (bitmap_bit_p (should_scalarize_away_bitmap, i)
2511 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
2513 tree var = candidate (i);
2515 if (TREE_CODE (var) == VAR_DECL
2516 && type_consists_of_records_p (TREE_TYPE (var)))
2518 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var)))
2519 <= max_total_scalarization_size)
2521 completely_scalarize_var (var);
2522 if (dump_file && (dump_flags & TDF_DETAILS))
2524 fprintf (dump_file, "Will attempt to totally scalarize ");
2525 print_generic_expr (dump_file, var, 0);
2526 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2529 else if (dump_file && (dump_flags & TDF_DETAILS))
2531 fprintf (dump_file, "Too big to totally scalarize: ");
2532 print_generic_expr (dump_file, var, 0);
2533 fprintf (dump_file, " (UID: %u)\n", DECL_UID (var));
2538 bitmap_copy (tmp, candidate_bitmap);
2539 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2541 tree var = candidate (i);
2542 struct access *access;
2544 access = sort_and_splice_var_accesses (var);
2545 if (!access || !build_access_trees (access))
2546 disqualify_candidate (var,
2547 "No or inhibitingly overlapping accesses.");
2550 propagate_all_subaccesses ();
2552 bitmap_copy (tmp, candidate_bitmap);
2553 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2555 tree var = candidate (i);
2556 struct access *access = get_first_repr_for_decl (var);
2558 if (analyze_access_trees (access))
2560 res++;
2561 if (dump_file && (dump_flags & TDF_DETAILS))
2563 fprintf (dump_file, "\nAccess trees for ");
2564 print_generic_expr (dump_file, var, 0);
2565 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2566 dump_access_tree (dump_file, access);
2567 fprintf (dump_file, "\n");
2570 else
2571 disqualify_candidate (var, "No scalar replacements to be created.");
2574 BITMAP_FREE (tmp);
2576 if (res)
2578 statistics_counter_event (cfun, "Scalarized aggregates", res);
2579 return true;
2581 else
2582 return false;
2585 /* Generate statements copying scalar replacements of accesses within a subtree
2586 into or out of AGG. ACCESS, all its children, siblings and their children
2587 are to be processed. AGG is an aggregate type expression (can be a
2588 declaration but does not have to be, it can for example also be a mem_ref or
2589 a series of handled components). TOP_OFFSET is the offset of the processed
2590 subtree which has to be subtracted from offsets of individual accesses to
2591 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2592 replacements in the interval <start_offset, start_offset + chunk_size>,
2593 otherwise copy all. GSI is a statement iterator used to place the new
2594 statements. WRITE should be true when the statements should write from AGG
2595 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2596 statements will be added after the current statement in GSI, they will be
2597 added before the statement otherwise. */
2599 static void
2600 generate_subtree_copies (struct access *access, tree agg,
2601 HOST_WIDE_INT top_offset,
2602 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
2603 gimple_stmt_iterator *gsi, bool write,
2604 bool insert_after, location_t loc)
2608 if (chunk_size && access->offset >= start_offset + chunk_size)
2609 return;
2611 if (access->grp_to_be_replaced
2612 && (chunk_size == 0
2613 || access->offset + access->size > start_offset))
2615 tree expr, repl = get_access_replacement (access);
2616 gimple_assign stmt;
2618 expr = build_ref_for_model (loc, agg, access->offset - top_offset,
2619 access, gsi, insert_after);
2621 if (write)
2623 if (access->grp_partial_lhs)
2624 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
2625 !insert_after,
2626 insert_after ? GSI_NEW_STMT
2627 : GSI_SAME_STMT);
2628 stmt = gimple_build_assign (repl, expr);
2630 else
2632 TREE_NO_WARNING (repl) = 1;
2633 if (access->grp_partial_lhs)
2634 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2635 !insert_after,
2636 insert_after ? GSI_NEW_STMT
2637 : GSI_SAME_STMT);
2638 stmt = gimple_build_assign (expr, repl);
2640 gimple_set_location (stmt, loc);
2642 if (insert_after)
2643 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2644 else
2645 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2646 update_stmt (stmt);
2647 sra_stats.subtree_copies++;
2649 else if (write
2650 && access->grp_to_be_debug_replaced
2651 && (chunk_size == 0
2652 || access->offset + access->size > start_offset))
2654 gimple_debug ds;
2655 tree drhs = build_debug_ref_for_model (loc, agg,
2656 access->offset - top_offset,
2657 access);
2658 ds = gimple_build_debug_bind (get_access_replacement (access),
2659 drhs, gsi_stmt (*gsi));
2660 if (insert_after)
2661 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2662 else
2663 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2666 if (access->first_child)
2667 generate_subtree_copies (access->first_child, agg, top_offset,
2668 start_offset, chunk_size, gsi,
2669 write, insert_after, loc);
2671 access = access->next_sibling;
2673 while (access);
2676 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2677 the root of the subtree to be processed. GSI is the statement iterator used
2678 for inserting statements which are added after the current statement if
2679 INSERT_AFTER is true or before it otherwise. */
2681 static void
2682 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
2683 bool insert_after, location_t loc)
2686 struct access *child;
2688 if (access->grp_to_be_replaced)
2690 gimple_assign stmt;
2692 stmt = gimple_build_assign (get_access_replacement (access),
2693 build_zero_cst (access->type));
2694 if (insert_after)
2695 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2696 else
2697 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2698 update_stmt (stmt);
2699 gimple_set_location (stmt, loc);
2701 else if (access->grp_to_be_debug_replaced)
2703 gimple_debug ds =
2704 gimple_build_debug_bind (get_access_replacement (access),
2705 build_zero_cst (access->type),
2706 gsi_stmt (*gsi));
2707 if (insert_after)
2708 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2709 else
2710 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2713 for (child = access->first_child; child; child = child->next_sibling)
2714 init_subtree_with_zero (child, gsi, insert_after, loc);
2717 /* Search for an access representative for the given expression EXPR and
2718 return it or NULL if it cannot be found. */
2720 static struct access *
2721 get_access_for_expr (tree expr)
2723 HOST_WIDE_INT offset, size, max_size;
2724 tree base;
2726 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2727 a different size than the size of its argument and we need the latter
2728 one. */
2729 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
2730 expr = TREE_OPERAND (expr, 0);
2732 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
2733 if (max_size == -1 || !DECL_P (base))
2734 return NULL;
2736 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
2737 return NULL;
2739 return get_var_base_offset_size_access (base, offset, max_size);
2742 /* Replace the expression EXPR with a scalar replacement if there is one and
2743 generate other statements to do type conversion or subtree copying if
2744 necessary. GSI is used to place newly created statements, WRITE is true if
2745 the expression is being written to (it is on a LHS of a statement or output
2746 in an assembly statement). */
2748 static bool
2749 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
2751 location_t loc;
2752 struct access *access;
2753 tree type, bfr, orig_expr;
2755 if (TREE_CODE (*expr) == BIT_FIELD_REF)
2757 bfr = *expr;
2758 expr = &TREE_OPERAND (*expr, 0);
2760 else
2761 bfr = NULL_TREE;
2763 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
2764 expr = &TREE_OPERAND (*expr, 0);
2765 access = get_access_for_expr (*expr);
2766 if (!access)
2767 return false;
2768 type = TREE_TYPE (*expr);
2769 orig_expr = *expr;
2771 loc = gimple_location (gsi_stmt (*gsi));
2772 gimple_stmt_iterator alt_gsi = gsi_none ();
2773 if (write && stmt_ends_bb_p (gsi_stmt (*gsi)))
2775 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
2776 gsi = &alt_gsi;
2779 if (access->grp_to_be_replaced)
2781 tree repl = get_access_replacement (access);
2782 /* If we replace a non-register typed access simply use the original
2783 access expression to extract the scalar component afterwards.
2784 This happens if scalarizing a function return value or parameter
2785 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2786 gcc.c-torture/compile/20011217-1.c.
2788 We also want to use this when accessing a complex or vector which can
2789 be accessed as a different type too, potentially creating a need for
2790 type conversion (see PR42196) and when scalarized unions are involved
2791 in assembler statements (see PR42398). */
2792 if (!useless_type_conversion_p (type, access->type))
2794 tree ref;
2796 ref = build_ref_for_model (loc, orig_expr, 0, access, gsi, false);
2798 if (write)
2800 gimple_assign stmt;
2802 if (access->grp_partial_lhs)
2803 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
2804 false, GSI_NEW_STMT);
2805 stmt = gimple_build_assign (repl, ref);
2806 gimple_set_location (stmt, loc);
2807 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2809 else
2811 gimple_assign stmt;
2813 if (access->grp_partial_lhs)
2814 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2815 true, GSI_SAME_STMT);
2816 stmt = gimple_build_assign (ref, repl);
2817 gimple_set_location (stmt, loc);
2818 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2821 else
2822 *expr = repl;
2823 sra_stats.exprs++;
2825 else if (write && access->grp_to_be_debug_replaced)
2827 gimple_debug ds =
2828 gimple_build_debug_bind (get_access_replacement (access),
2829 NULL_TREE,
2830 gsi_stmt (*gsi));
2831 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2834 if (access->first_child)
2836 HOST_WIDE_INT start_offset, chunk_size;
2837 if (bfr
2838 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 1))
2839 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 2)))
2841 chunk_size = tree_to_uhwi (TREE_OPERAND (bfr, 1));
2842 start_offset = access->offset
2843 + tree_to_uhwi (TREE_OPERAND (bfr, 2));
2845 else
2846 start_offset = chunk_size = 0;
2848 generate_subtree_copies (access->first_child, orig_expr, access->offset,
2849 start_offset, chunk_size, gsi, write, write,
2850 loc);
2852 return true;
2855 /* Where scalar replacements of the RHS have been written to when a replacement
2856 of a LHS of an assigments cannot be direclty loaded from a replacement of
2857 the RHS. */
2858 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
2859 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
2860 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
2862 struct subreplacement_assignment_data
2864 /* Offset of the access representing the lhs of the assignment. */
2865 HOST_WIDE_INT left_offset;
2867 /* LHS and RHS of the original assignment. */
2868 tree assignment_lhs, assignment_rhs;
2870 /* Access representing the rhs of the whole assignment. */
2871 struct access *top_racc;
2873 /* Stmt iterator used for statement insertions after the original assignment.
2874 It points to the main GSI used to traverse a BB during function body
2875 modification. */
2876 gimple_stmt_iterator *new_gsi;
2878 /* Stmt iterator used for statement insertions before the original
2879 assignment. Keeps on pointing to the original statement. */
2880 gimple_stmt_iterator old_gsi;
2882 /* Location of the assignment. */
2883 location_t loc;
2885 /* Keeps the information whether we have needed to refresh replacements of
2886 the LHS and from which side of the assignments this takes place. */
2887 enum unscalarized_data_handling refreshed;
2890 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2891 base aggregate if there are unscalarized data or directly to LHS of the
2892 statement that is pointed to by GSI otherwise. */
2894 static void
2895 handle_unscalarized_data_in_subtree (struct subreplacement_assignment_data *sad)
2897 tree src;
2898 if (sad->top_racc->grp_unscalarized_data)
2900 src = sad->assignment_rhs;
2901 sad->refreshed = SRA_UDH_RIGHT;
2903 else
2905 src = sad->assignment_lhs;
2906 sad->refreshed = SRA_UDH_LEFT;
2908 generate_subtree_copies (sad->top_racc->first_child, src,
2909 sad->top_racc->offset, 0, 0,
2910 &sad->old_gsi, false, false, sad->loc);
2913 /* Try to generate statements to load all sub-replacements in an access subtree
2914 formed by children of LACC from scalar replacements in the SAD->top_racc
2915 subtree. If that is not possible, refresh the SAD->top_racc base aggregate
2916 and load the accesses from it. */
2918 static void
2919 load_assign_lhs_subreplacements (struct access *lacc,
2920 struct subreplacement_assignment_data *sad)
2922 for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling)
2924 HOST_WIDE_INT offset;
2925 offset = lacc->offset - sad->left_offset + sad->top_racc->offset;
2927 if (lacc->grp_to_be_replaced)
2929 struct access *racc;
2930 gimple_assign stmt;
2931 tree rhs;
2933 racc = find_access_in_subtree (sad->top_racc, offset, lacc->size);
2934 if (racc && racc->grp_to_be_replaced)
2936 rhs = get_access_replacement (racc);
2937 if (!useless_type_conversion_p (lacc->type, racc->type))
2938 rhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
2939 lacc->type, rhs);
2941 if (racc->grp_partial_lhs && lacc->grp_partial_lhs)
2942 rhs = force_gimple_operand_gsi (&sad->old_gsi, rhs, true,
2943 NULL_TREE, true, GSI_SAME_STMT);
2945 else
2947 /* No suitable access on the right hand side, need to load from
2948 the aggregate. See if we have to update it first... */
2949 if (sad->refreshed == SRA_UDH_NONE)
2950 handle_unscalarized_data_in_subtree (sad);
2952 if (sad->refreshed == SRA_UDH_LEFT)
2953 rhs = build_ref_for_model (sad->loc, sad->assignment_lhs,
2954 lacc->offset - sad->left_offset,
2955 lacc, sad->new_gsi, true);
2956 else
2957 rhs = build_ref_for_model (sad->loc, sad->assignment_rhs,
2958 lacc->offset - sad->left_offset,
2959 lacc, sad->new_gsi, true);
2960 if (lacc->grp_partial_lhs)
2961 rhs = force_gimple_operand_gsi (sad->new_gsi,
2962 rhs, true, NULL_TREE,
2963 false, GSI_NEW_STMT);
2966 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
2967 gsi_insert_after (sad->new_gsi, stmt, GSI_NEW_STMT);
2968 gimple_set_location (stmt, sad->loc);
2969 update_stmt (stmt);
2970 sra_stats.subreplacements++;
2972 else
2974 if (sad->refreshed == SRA_UDH_NONE
2975 && lacc->grp_read && !lacc->grp_covered)
2976 handle_unscalarized_data_in_subtree (sad);
2978 if (lacc && lacc->grp_to_be_debug_replaced)
2980 gimple_debug ds;
2981 tree drhs;
2982 struct access *racc = find_access_in_subtree (sad->top_racc,
2983 offset,
2984 lacc->size);
2986 if (racc && racc->grp_to_be_replaced)
2988 if (racc->grp_write)
2989 drhs = get_access_replacement (racc);
2990 else
2991 drhs = NULL;
2993 else if (sad->refreshed == SRA_UDH_LEFT)
2994 drhs = build_debug_ref_for_model (sad->loc, lacc->base,
2995 lacc->offset, lacc);
2996 else if (sad->refreshed == SRA_UDH_RIGHT)
2997 drhs = build_debug_ref_for_model (sad->loc, sad->top_racc->base,
2998 offset, lacc);
2999 else
3000 drhs = NULL_TREE;
3001 if (drhs
3002 && !useless_type_conversion_p (lacc->type, TREE_TYPE (drhs)))
3003 drhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
3004 lacc->type, drhs);
3005 ds = gimple_build_debug_bind (get_access_replacement (lacc),
3006 drhs, gsi_stmt (sad->old_gsi));
3007 gsi_insert_after (sad->new_gsi, ds, GSI_NEW_STMT);
3011 if (lacc->first_child)
3012 load_assign_lhs_subreplacements (lacc, sad);
3016 /* Result code for SRA assignment modification. */
3017 enum assignment_mod_result { SRA_AM_NONE, /* nothing done for the stmt */
3018 SRA_AM_MODIFIED, /* stmt changed but not
3019 removed */
3020 SRA_AM_REMOVED }; /* stmt eliminated */
3022 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
3023 to the assignment and GSI is the statement iterator pointing at it. Returns
3024 the same values as sra_modify_assign. */
3026 static enum assignment_mod_result
3027 sra_modify_constructor_assign (gimple stmt, gimple_stmt_iterator *gsi)
3029 tree lhs = gimple_assign_lhs (stmt);
3030 struct access *acc;
3031 location_t loc;
3033 acc = get_access_for_expr (lhs);
3034 if (!acc)
3035 return SRA_AM_NONE;
3037 if (gimple_clobber_p (stmt))
3039 /* Remove clobbers of fully scalarized variables, otherwise
3040 do nothing. */
3041 if (acc->grp_covered)
3043 unlink_stmt_vdef (stmt);
3044 gsi_remove (gsi, true);
3045 release_defs (stmt);
3046 return SRA_AM_REMOVED;
3048 else
3049 return SRA_AM_NONE;
3052 loc = gimple_location (stmt);
3053 if (vec_safe_length (CONSTRUCTOR_ELTS (gimple_assign_rhs1 (stmt))) > 0)
3055 /* I have never seen this code path trigger but if it can happen the
3056 following should handle it gracefully. */
3057 if (access_has_children_p (acc))
3058 generate_subtree_copies (acc->first_child, lhs, acc->offset, 0, 0, gsi,
3059 true, true, loc);
3060 return SRA_AM_MODIFIED;
3063 if (acc->grp_covered)
3065 init_subtree_with_zero (acc, gsi, false, loc);
3066 unlink_stmt_vdef (stmt);
3067 gsi_remove (gsi, true);
3068 release_defs (stmt);
3069 return SRA_AM_REMOVED;
3071 else
3073 init_subtree_with_zero (acc, gsi, true, loc);
3074 return SRA_AM_MODIFIED;
3078 /* Create and return a new suitable default definition SSA_NAME for RACC which
3079 is an access describing an uninitialized part of an aggregate that is being
3080 loaded. */
3082 static tree
3083 get_repl_default_def_ssa_name (struct access *racc)
3085 gcc_checking_assert (!racc->grp_to_be_replaced
3086 && !racc->grp_to_be_debug_replaced);
3087 if (!racc->replacement_decl)
3088 racc->replacement_decl = create_access_replacement (racc);
3089 return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
3092 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3093 bit-field field declaration somewhere in it. */
3095 static inline bool
3096 contains_vce_or_bfcref_p (const_tree ref)
3098 while (handled_component_p (ref))
3100 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
3101 || (TREE_CODE (ref) == COMPONENT_REF
3102 && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
3103 return true;
3104 ref = TREE_OPERAND (ref, 0);
3107 return false;
3110 /* Examine both sides of the assignment statement pointed to by STMT, replace
3111 them with a scalare replacement if there is one and generate copying of
3112 replacements if scalarized aggregates have been used in the assignment. GSI
3113 is used to hold generated statements for type conversions and subtree
3114 copying. */
3116 static enum assignment_mod_result
3117 sra_modify_assign (gimple stmt, gimple_stmt_iterator *gsi)
3119 struct access *lacc, *racc;
3120 tree lhs, rhs;
3121 bool modify_this_stmt = false;
3122 bool force_gimple_rhs = false;
3123 location_t loc;
3124 gimple_stmt_iterator orig_gsi = *gsi;
3126 if (!gimple_assign_single_p (stmt))
3127 return SRA_AM_NONE;
3128 lhs = gimple_assign_lhs (stmt);
3129 rhs = gimple_assign_rhs1 (stmt);
3131 if (TREE_CODE (rhs) == CONSTRUCTOR)
3132 return sra_modify_constructor_assign (stmt, gsi);
3134 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
3135 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
3136 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
3138 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (stmt),
3139 gsi, false);
3140 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (stmt),
3141 gsi, true);
3142 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3145 lacc = get_access_for_expr (lhs);
3146 racc = get_access_for_expr (rhs);
3147 if (!lacc && !racc)
3148 return SRA_AM_NONE;
3150 loc = gimple_location (stmt);
3151 if (lacc && lacc->grp_to_be_replaced)
3153 lhs = get_access_replacement (lacc);
3154 gimple_assign_set_lhs (stmt, lhs);
3155 modify_this_stmt = true;
3156 if (lacc->grp_partial_lhs)
3157 force_gimple_rhs = true;
3158 sra_stats.exprs++;
3161 if (racc && racc->grp_to_be_replaced)
3163 rhs = get_access_replacement (racc);
3164 modify_this_stmt = true;
3165 if (racc->grp_partial_lhs)
3166 force_gimple_rhs = true;
3167 sra_stats.exprs++;
3169 else if (racc
3170 && !racc->grp_unscalarized_data
3171 && TREE_CODE (lhs) == SSA_NAME
3172 && !access_has_replacements_p (racc))
3174 rhs = get_repl_default_def_ssa_name (racc);
3175 modify_this_stmt = true;
3176 sra_stats.exprs++;
3179 if (modify_this_stmt)
3181 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3183 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3184 ??? This should move to fold_stmt which we simply should
3185 call after building a VIEW_CONVERT_EXPR here. */
3186 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
3187 && !contains_bitfld_component_ref_p (lhs))
3189 lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
3190 gimple_assign_set_lhs (stmt, lhs);
3192 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
3193 && !contains_vce_or_bfcref_p (rhs))
3194 rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
3196 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3198 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
3199 rhs);
3200 if (is_gimple_reg_type (TREE_TYPE (lhs))
3201 && TREE_CODE (lhs) != SSA_NAME)
3202 force_gimple_rhs = true;
3207 if (lacc && lacc->grp_to_be_debug_replaced)
3209 tree dlhs = get_access_replacement (lacc);
3210 tree drhs = unshare_expr (rhs);
3211 if (!useless_type_conversion_p (TREE_TYPE (dlhs), TREE_TYPE (drhs)))
3213 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs))
3214 && !contains_vce_or_bfcref_p (drhs))
3215 drhs = build_debug_ref_for_model (loc, drhs, 0, lacc);
3216 if (drhs
3217 && !useless_type_conversion_p (TREE_TYPE (dlhs),
3218 TREE_TYPE (drhs)))
3219 drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
3220 TREE_TYPE (dlhs), drhs);
3222 gimple_debug ds = gimple_build_debug_bind (dlhs, drhs, stmt);
3223 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3226 /* From this point on, the function deals with assignments in between
3227 aggregates when at least one has scalar reductions of some of its
3228 components. There are three possible scenarios: Both the LHS and RHS have
3229 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3231 In the first case, we would like to load the LHS components from RHS
3232 components whenever possible. If that is not possible, we would like to
3233 read it directly from the RHS (after updating it by storing in it its own
3234 components). If there are some necessary unscalarized data in the LHS,
3235 those will be loaded by the original assignment too. If neither of these
3236 cases happen, the original statement can be removed. Most of this is done
3237 by load_assign_lhs_subreplacements.
3239 In the second case, we would like to store all RHS scalarized components
3240 directly into LHS and if they cover the aggregate completely, remove the
3241 statement too. In the third case, we want the LHS components to be loaded
3242 directly from the RHS (DSE will remove the original statement if it
3243 becomes redundant).
3245 This is a bit complex but manageable when types match and when unions do
3246 not cause confusion in a way that we cannot really load a component of LHS
3247 from the RHS or vice versa (the access representing this level can have
3248 subaccesses that are accessible only through a different union field at a
3249 higher level - different from the one used in the examined expression).
3250 Unions are fun.
3252 Therefore, I specially handle a fourth case, happening when there is a
3253 specific type cast or it is impossible to locate a scalarized subaccess on
3254 the other side of the expression. If that happens, I simply "refresh" the
3255 RHS by storing in it is scalarized components leave the original statement
3256 there to do the copying and then load the scalar replacements of the LHS.
3257 This is what the first branch does. */
3259 if (modify_this_stmt
3260 || gimple_has_volatile_ops (stmt)
3261 || contains_vce_or_bfcref_p (rhs)
3262 || contains_vce_or_bfcref_p (lhs)
3263 || stmt_ends_bb_p (stmt))
3265 if (access_has_children_p (racc))
3266 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3267 gsi, false, false, loc);
3268 if (access_has_children_p (lacc))
3270 gimple_stmt_iterator alt_gsi = gsi_none ();
3271 if (stmt_ends_bb_p (stmt))
3273 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
3274 gsi = &alt_gsi;
3276 generate_subtree_copies (lacc->first_child, lhs, lacc->offset, 0, 0,
3277 gsi, true, true, loc);
3279 sra_stats.separate_lhs_rhs_handling++;
3281 /* This gimplification must be done after generate_subtree_copies,
3282 lest we insert the subtree copies in the middle of the gimplified
3283 sequence. */
3284 if (force_gimple_rhs)
3285 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
3286 true, GSI_SAME_STMT);
3287 if (gimple_assign_rhs1 (stmt) != rhs)
3289 modify_this_stmt = true;
3290 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
3291 gcc_assert (stmt == gsi_stmt (orig_gsi));
3294 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3296 else
3298 if (access_has_children_p (lacc)
3299 && access_has_children_p (racc)
3300 /* When an access represents an unscalarizable region, it usually
3301 represents accesses with variable offset and thus must not be used
3302 to generate new memory accesses. */
3303 && !lacc->grp_unscalarizable_region
3304 && !racc->grp_unscalarizable_region)
3306 struct subreplacement_assignment_data sad;
3308 sad.left_offset = lacc->offset;
3309 sad.assignment_lhs = lhs;
3310 sad.assignment_rhs = rhs;
3311 sad.top_racc = racc;
3312 sad.old_gsi = *gsi;
3313 sad.new_gsi = gsi;
3314 sad.loc = gimple_location (stmt);
3315 sad.refreshed = SRA_UDH_NONE;
3317 if (lacc->grp_read && !lacc->grp_covered)
3318 handle_unscalarized_data_in_subtree (&sad);
3320 load_assign_lhs_subreplacements (lacc, &sad);
3321 if (sad.refreshed != SRA_UDH_RIGHT)
3323 gsi_next (gsi);
3324 unlink_stmt_vdef (stmt);
3325 gsi_remove (&sad.old_gsi, true);
3326 release_defs (stmt);
3327 sra_stats.deleted++;
3328 return SRA_AM_REMOVED;
3331 else
3333 if (access_has_children_p (racc)
3334 && !racc->grp_unscalarized_data)
3336 if (dump_file)
3338 fprintf (dump_file, "Removing load: ");
3339 print_gimple_stmt (dump_file, stmt, 0, 0);
3341 generate_subtree_copies (racc->first_child, lhs,
3342 racc->offset, 0, 0, gsi,
3343 false, false, loc);
3344 gcc_assert (stmt == gsi_stmt (*gsi));
3345 unlink_stmt_vdef (stmt);
3346 gsi_remove (gsi, true);
3347 release_defs (stmt);
3348 sra_stats.deleted++;
3349 return SRA_AM_REMOVED;
3351 /* Restore the aggregate RHS from its components so the
3352 prevailing aggregate copy does the right thing. */
3353 if (access_has_children_p (racc))
3354 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3355 gsi, false, false, loc);
3356 /* Re-load the components of the aggregate copy destination.
3357 But use the RHS aggregate to load from to expose more
3358 optimization opportunities. */
3359 if (access_has_children_p (lacc))
3360 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
3361 0, 0, gsi, true, true, loc);
3364 return SRA_AM_NONE;
3368 /* Traverse the function body and all modifications as decided in
3369 analyze_all_variable_accesses. Return true iff the CFG has been
3370 changed. */
3372 static bool
3373 sra_modify_function_body (void)
3375 bool cfg_changed = false;
3376 basic_block bb;
3378 FOR_EACH_BB_FN (bb, cfun)
3380 gimple_stmt_iterator gsi = gsi_start_bb (bb);
3381 while (!gsi_end_p (gsi))
3383 gimple stmt = gsi_stmt (gsi);
3384 enum assignment_mod_result assign_result;
3385 bool modified = false, deleted = false;
3386 tree *t;
3387 unsigned i;
3389 switch (gimple_code (stmt))
3391 case GIMPLE_RETURN:
3392 t = gimple_return_retval_ptr (stmt);
3393 if (*t != NULL_TREE)
3394 modified |= sra_modify_expr (t, &gsi, false);
3395 break;
3397 case GIMPLE_ASSIGN:
3398 assign_result = sra_modify_assign (stmt, &gsi);
3399 modified |= assign_result == SRA_AM_MODIFIED;
3400 deleted = assign_result == SRA_AM_REMOVED;
3401 break;
3403 case GIMPLE_CALL:
3404 /* Operands must be processed before the lhs. */
3405 for (i = 0; i < gimple_call_num_args (stmt); i++)
3407 t = gimple_call_arg_ptr (stmt, i);
3408 modified |= sra_modify_expr (t, &gsi, false);
3411 if (gimple_call_lhs (stmt))
3413 t = gimple_call_lhs_ptr (stmt);
3414 modified |= sra_modify_expr (t, &gsi, true);
3416 break;
3418 case GIMPLE_ASM:
3420 gimple_asm asm_stmt = as_a <gimple_asm> (stmt);
3421 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
3423 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
3424 modified |= sra_modify_expr (t, &gsi, false);
3426 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
3428 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
3429 modified |= sra_modify_expr (t, &gsi, true);
3432 break;
3434 default:
3435 break;
3438 if (modified)
3440 update_stmt (stmt);
3441 if (maybe_clean_eh_stmt (stmt)
3442 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
3443 cfg_changed = true;
3445 if (!deleted)
3446 gsi_next (&gsi);
3450 gsi_commit_edge_inserts ();
3451 return cfg_changed;
3454 /* Generate statements initializing scalar replacements of parts of function
3455 parameters. */
3457 static void
3458 initialize_parameter_reductions (void)
3460 gimple_stmt_iterator gsi;
3461 gimple_seq seq = NULL;
3462 tree parm;
3464 gsi = gsi_start (seq);
3465 for (parm = DECL_ARGUMENTS (current_function_decl);
3466 parm;
3467 parm = DECL_CHAIN (parm))
3469 vec<access_p> *access_vec;
3470 struct access *access;
3472 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3473 continue;
3474 access_vec = get_base_access_vector (parm);
3475 if (!access_vec)
3476 continue;
3478 for (access = (*access_vec)[0];
3479 access;
3480 access = access->next_grp)
3481 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true,
3482 EXPR_LOCATION (parm));
3485 seq = gsi_seq (gsi);
3486 if (seq)
3487 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3490 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3491 it reveals there are components of some aggregates to be scalarized, it runs
3492 the required transformations. */
3493 static unsigned int
3494 perform_intra_sra (void)
3496 int ret = 0;
3497 sra_initialize ();
3499 if (!find_var_candidates ())
3500 goto out;
3502 if (!scan_function ())
3503 goto out;
3505 if (!analyze_all_variable_accesses ())
3506 goto out;
3508 if (sra_modify_function_body ())
3509 ret = TODO_update_ssa | TODO_cleanup_cfg;
3510 else
3511 ret = TODO_update_ssa;
3512 initialize_parameter_reductions ();
3514 statistics_counter_event (cfun, "Scalar replacements created",
3515 sra_stats.replacements);
3516 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
3517 statistics_counter_event (cfun, "Subtree copy stmts",
3518 sra_stats.subtree_copies);
3519 statistics_counter_event (cfun, "Subreplacement stmts",
3520 sra_stats.subreplacements);
3521 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
3522 statistics_counter_event (cfun, "Separate LHS and RHS handling",
3523 sra_stats.separate_lhs_rhs_handling);
3525 out:
3526 sra_deinitialize ();
3527 return ret;
3530 /* Perform early intraprocedural SRA. */
3531 static unsigned int
3532 early_intra_sra (void)
3534 sra_mode = SRA_MODE_EARLY_INTRA;
3535 return perform_intra_sra ();
3538 /* Perform "late" intraprocedural SRA. */
3539 static unsigned int
3540 late_intra_sra (void)
3542 sra_mode = SRA_MODE_INTRA;
3543 return perform_intra_sra ();
3547 static bool
3548 gate_intra_sra (void)
3550 return flag_tree_sra != 0 && dbg_cnt (tree_sra);
3554 namespace {
3556 const pass_data pass_data_sra_early =
3558 GIMPLE_PASS, /* type */
3559 "esra", /* name */
3560 OPTGROUP_NONE, /* optinfo_flags */
3561 TV_TREE_SRA, /* tv_id */
3562 ( PROP_cfg | PROP_ssa ), /* properties_required */
3563 0, /* properties_provided */
3564 0, /* properties_destroyed */
3565 0, /* todo_flags_start */
3566 TODO_update_ssa, /* todo_flags_finish */
3569 class pass_sra_early : public gimple_opt_pass
3571 public:
3572 pass_sra_early (gcc::context *ctxt)
3573 : gimple_opt_pass (pass_data_sra_early, ctxt)
3576 /* opt_pass methods: */
3577 virtual bool gate (function *) { return gate_intra_sra (); }
3578 virtual unsigned int execute (function *) { return early_intra_sra (); }
3580 }; // class pass_sra_early
3582 } // anon namespace
3584 gimple_opt_pass *
3585 make_pass_sra_early (gcc::context *ctxt)
3587 return new pass_sra_early (ctxt);
3590 namespace {
3592 const pass_data pass_data_sra =
3594 GIMPLE_PASS, /* type */
3595 "sra", /* name */
3596 OPTGROUP_NONE, /* optinfo_flags */
3597 TV_TREE_SRA, /* tv_id */
3598 ( PROP_cfg | PROP_ssa ), /* properties_required */
3599 0, /* properties_provided */
3600 0, /* properties_destroyed */
3601 TODO_update_address_taken, /* todo_flags_start */
3602 TODO_update_ssa, /* todo_flags_finish */
3605 class pass_sra : public gimple_opt_pass
3607 public:
3608 pass_sra (gcc::context *ctxt)
3609 : gimple_opt_pass (pass_data_sra, ctxt)
3612 /* opt_pass methods: */
3613 virtual bool gate (function *) { return gate_intra_sra (); }
3614 virtual unsigned int execute (function *) { return late_intra_sra (); }
3616 }; // class pass_sra
3618 } // anon namespace
3620 gimple_opt_pass *
3621 make_pass_sra (gcc::context *ctxt)
3623 return new pass_sra (ctxt);
3627 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3628 parameter. */
3630 static bool
3631 is_unused_scalar_param (tree parm)
3633 tree name;
3634 return (is_gimple_reg (parm)
3635 && (!(name = ssa_default_def (cfun, parm))
3636 || has_zero_uses (name)));
3639 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3640 examine whether there are any direct or otherwise infeasible ones. If so,
3641 return true, otherwise return false. PARM must be a gimple register with a
3642 non-NULL default definition. */
3644 static bool
3645 ptr_parm_has_direct_uses (tree parm)
3647 imm_use_iterator ui;
3648 gimple stmt;
3649 tree name = ssa_default_def (cfun, parm);
3650 bool ret = false;
3652 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
3654 int uses_ok = 0;
3655 use_operand_p use_p;
3657 if (is_gimple_debug (stmt))
3658 continue;
3660 /* Valid uses include dereferences on the lhs and the rhs. */
3661 if (gimple_has_lhs (stmt))
3663 tree lhs = gimple_get_lhs (stmt);
3664 while (handled_component_p (lhs))
3665 lhs = TREE_OPERAND (lhs, 0);
3666 if (TREE_CODE (lhs) == MEM_REF
3667 && TREE_OPERAND (lhs, 0) == name
3668 && integer_zerop (TREE_OPERAND (lhs, 1))
3669 && types_compatible_p (TREE_TYPE (lhs),
3670 TREE_TYPE (TREE_TYPE (name)))
3671 && !TREE_THIS_VOLATILE (lhs))
3672 uses_ok++;
3674 if (gimple_assign_single_p (stmt))
3676 tree rhs = gimple_assign_rhs1 (stmt);
3677 while (handled_component_p (rhs))
3678 rhs = TREE_OPERAND (rhs, 0);
3679 if (TREE_CODE (rhs) == MEM_REF
3680 && TREE_OPERAND (rhs, 0) == name
3681 && integer_zerop (TREE_OPERAND (rhs, 1))
3682 && types_compatible_p (TREE_TYPE (rhs),
3683 TREE_TYPE (TREE_TYPE (name)))
3684 && !TREE_THIS_VOLATILE (rhs))
3685 uses_ok++;
3687 else if (is_gimple_call (stmt))
3689 unsigned i;
3690 for (i = 0; i < gimple_call_num_args (stmt); ++i)
3692 tree arg = gimple_call_arg (stmt, i);
3693 while (handled_component_p (arg))
3694 arg = TREE_OPERAND (arg, 0);
3695 if (TREE_CODE (arg) == MEM_REF
3696 && TREE_OPERAND (arg, 0) == name
3697 && integer_zerop (TREE_OPERAND (arg, 1))
3698 && types_compatible_p (TREE_TYPE (arg),
3699 TREE_TYPE (TREE_TYPE (name)))
3700 && !TREE_THIS_VOLATILE (arg))
3701 uses_ok++;
3705 /* If the number of valid uses does not match the number of
3706 uses in this stmt there is an unhandled use. */
3707 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
3708 --uses_ok;
3710 if (uses_ok != 0)
3711 ret = true;
3713 if (ret)
3714 BREAK_FROM_IMM_USE_STMT (ui);
3717 return ret;
3720 /* Identify candidates for reduction for IPA-SRA based on their type and mark
3721 them in candidate_bitmap. Note that these do not necessarily include
3722 parameter which are unused and thus can be removed. Return true iff any
3723 such candidate has been found. */
3725 static bool
3726 find_param_candidates (void)
3728 tree parm;
3729 int count = 0;
3730 bool ret = false;
3731 const char *msg;
3733 for (parm = DECL_ARGUMENTS (current_function_decl);
3734 parm;
3735 parm = DECL_CHAIN (parm))
3737 tree type = TREE_TYPE (parm);
3738 tree_node **slot;
3740 count++;
3742 if (TREE_THIS_VOLATILE (parm)
3743 || TREE_ADDRESSABLE (parm)
3744 || (!is_gimple_reg_type (type) && is_va_list_type (type)))
3745 continue;
3747 if (is_unused_scalar_param (parm))
3749 ret = true;
3750 continue;
3753 if (POINTER_TYPE_P (type))
3755 type = TREE_TYPE (type);
3757 if (TREE_CODE (type) == FUNCTION_TYPE
3758 || TYPE_VOLATILE (type)
3759 || (TREE_CODE (type) == ARRAY_TYPE
3760 && TYPE_NONALIASED_COMPONENT (type))
3761 || !is_gimple_reg (parm)
3762 || is_va_list_type (type)
3763 || ptr_parm_has_direct_uses (parm))
3764 continue;
3766 else if (!AGGREGATE_TYPE_P (type))
3767 continue;
3769 if (!COMPLETE_TYPE_P (type)
3770 || !tree_fits_uhwi_p (TYPE_SIZE (type))
3771 || tree_to_uhwi (TYPE_SIZE (type)) == 0
3772 || (AGGREGATE_TYPE_P (type)
3773 && type_internals_preclude_sra_p (type, &msg)))
3774 continue;
3776 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
3777 slot = candidates->find_slot_with_hash (parm, DECL_UID (parm), INSERT);
3778 *slot = parm;
3780 ret = true;
3781 if (dump_file && (dump_flags & TDF_DETAILS))
3783 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
3784 print_generic_expr (dump_file, parm, 0);
3785 fprintf (dump_file, "\n");
3789 func_param_count = count;
3790 return ret;
3793 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
3794 maybe_modified. */
3796 static bool
3797 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
3798 void *data)
3800 struct access *repr = (struct access *) data;
3802 repr->grp_maybe_modified = 1;
3803 return true;
3806 /* Analyze what representatives (in linked lists accessible from
3807 REPRESENTATIVES) can be modified by side effects of statements in the
3808 current function. */
3810 static void
3811 analyze_modified_params (vec<access_p> representatives)
3813 int i;
3815 for (i = 0; i < func_param_count; i++)
3817 struct access *repr;
3819 for (repr = representatives[i];
3820 repr;
3821 repr = repr->next_grp)
3823 struct access *access;
3824 bitmap visited;
3825 ao_ref ar;
3827 if (no_accesses_p (repr))
3828 continue;
3829 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
3830 || repr->grp_maybe_modified)
3831 continue;
3833 ao_ref_init (&ar, repr->expr);
3834 visited = BITMAP_ALLOC (NULL);
3835 for (access = repr; access; access = access->next_sibling)
3837 /* All accesses are read ones, otherwise grp_maybe_modified would
3838 be trivially set. */
3839 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
3840 mark_maybe_modified, repr, &visited);
3841 if (repr->grp_maybe_modified)
3842 break;
3844 BITMAP_FREE (visited);
3849 /* Propagate distances in bb_dereferences in the opposite direction than the
3850 control flow edges, in each step storing the maximum of the current value
3851 and the minimum of all successors. These steps are repeated until the table
3852 stabilizes. Note that BBs which might terminate the functions (according to
3853 final_bbs bitmap) never updated in this way. */
3855 static void
3856 propagate_dereference_distances (void)
3858 basic_block bb;
3860 auto_vec<basic_block> queue (last_basic_block_for_fn (cfun));
3861 queue.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun));
3862 FOR_EACH_BB_FN (bb, cfun)
3864 queue.quick_push (bb);
3865 bb->aux = bb;
3868 while (!queue.is_empty ())
3870 edge_iterator ei;
3871 edge e;
3872 bool change = false;
3873 int i;
3875 bb = queue.pop ();
3876 bb->aux = NULL;
3878 if (bitmap_bit_p (final_bbs, bb->index))
3879 continue;
3881 for (i = 0; i < func_param_count; i++)
3883 int idx = bb->index * func_param_count + i;
3884 bool first = true;
3885 HOST_WIDE_INT inh = 0;
3887 FOR_EACH_EDGE (e, ei, bb->succs)
3889 int succ_idx = e->dest->index * func_param_count + i;
3891 if (e->src == EXIT_BLOCK_PTR_FOR_FN (cfun))
3892 continue;
3894 if (first)
3896 first = false;
3897 inh = bb_dereferences [succ_idx];
3899 else if (bb_dereferences [succ_idx] < inh)
3900 inh = bb_dereferences [succ_idx];
3903 if (!first && bb_dereferences[idx] < inh)
3905 bb_dereferences[idx] = inh;
3906 change = true;
3910 if (change && !bitmap_bit_p (final_bbs, bb->index))
3911 FOR_EACH_EDGE (e, ei, bb->preds)
3913 if (e->src->aux)
3914 continue;
3916 e->src->aux = e->src;
3917 queue.quick_push (e->src);
3922 /* Dump a dereferences TABLE with heading STR to file F. */
3924 static void
3925 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
3927 basic_block bb;
3929 fprintf (dump_file, str);
3930 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
3931 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
3933 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
3934 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
3936 int i;
3937 for (i = 0; i < func_param_count; i++)
3939 int idx = bb->index * func_param_count + i;
3940 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
3943 fprintf (f, "\n");
3945 fprintf (dump_file, "\n");
3948 /* Determine what (parts of) parameters passed by reference that are not
3949 assigned to are not certainly dereferenced in this function and thus the
3950 dereferencing cannot be safely moved to the caller without potentially
3951 introducing a segfault. Mark such REPRESENTATIVES as
3952 grp_not_necessarilly_dereferenced.
3954 The dereferenced maximum "distance," i.e. the offset + size of the accessed
3955 part is calculated rather than simple booleans are calculated for each
3956 pointer parameter to handle cases when only a fraction of the whole
3957 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
3958 an example).
3960 The maximum dereference distances for each pointer parameter and BB are
3961 already stored in bb_dereference. This routine simply propagates these
3962 values upwards by propagate_dereference_distances and then compares the
3963 distances of individual parameters in the ENTRY BB to the equivalent
3964 distances of each representative of a (fraction of a) parameter. */
3966 static void
3967 analyze_caller_dereference_legality (vec<access_p> representatives)
3969 int i;
3971 if (dump_file && (dump_flags & TDF_DETAILS))
3972 dump_dereferences_table (dump_file,
3973 "Dereference table before propagation:\n",
3974 bb_dereferences);
3976 propagate_dereference_distances ();
3978 if (dump_file && (dump_flags & TDF_DETAILS))
3979 dump_dereferences_table (dump_file,
3980 "Dereference table after propagation:\n",
3981 bb_dereferences);
3983 for (i = 0; i < func_param_count; i++)
3985 struct access *repr = representatives[i];
3986 int idx = ENTRY_BLOCK_PTR_FOR_FN (cfun)->index * func_param_count + i;
3988 if (!repr || no_accesses_p (repr))
3989 continue;
3993 if ((repr->offset + repr->size) > bb_dereferences[idx])
3994 repr->grp_not_necessarilly_dereferenced = 1;
3995 repr = repr->next_grp;
3997 while (repr);
4001 /* Return the representative access for the parameter declaration PARM if it is
4002 a scalar passed by reference which is not written to and the pointer value
4003 is not used directly. Thus, if it is legal to dereference it in the caller
4004 and we can rule out modifications through aliases, such parameter should be
4005 turned into one passed by value. Return NULL otherwise. */
4007 static struct access *
4008 unmodified_by_ref_scalar_representative (tree parm)
4010 int i, access_count;
4011 struct access *repr;
4012 vec<access_p> *access_vec;
4014 access_vec = get_base_access_vector (parm);
4015 gcc_assert (access_vec);
4016 repr = (*access_vec)[0];
4017 if (repr->write)
4018 return NULL;
4019 repr->group_representative = repr;
4021 access_count = access_vec->length ();
4022 for (i = 1; i < access_count; i++)
4024 struct access *access = (*access_vec)[i];
4025 if (access->write)
4026 return NULL;
4027 access->group_representative = repr;
4028 access->next_sibling = repr->next_sibling;
4029 repr->next_sibling = access;
4032 repr->grp_read = 1;
4033 repr->grp_scalar_ptr = 1;
4034 return repr;
4037 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
4038 associated with. REQ_ALIGN is the minimum required alignment. */
4040 static bool
4041 access_precludes_ipa_sra_p (struct access *access, unsigned int req_align)
4043 unsigned int exp_align;
4044 /* Avoid issues such as the second simple testcase in PR 42025. The problem
4045 is incompatible assign in a call statement (and possibly even in asm
4046 statements). This can be relaxed by using a new temporary but only for
4047 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
4048 intraprocedural SRA we deal with this by keeping the old aggregate around,
4049 something we cannot do in IPA-SRA.) */
4050 if (access->write
4051 && (is_gimple_call (access->stmt)
4052 || gimple_code (access->stmt) == GIMPLE_ASM))
4053 return true;
4055 exp_align = get_object_alignment (access->expr);
4056 if (exp_align < req_align)
4057 return true;
4059 return false;
4063 /* Sort collected accesses for parameter PARM, identify representatives for
4064 each accessed region and link them together. Return NULL if there are
4065 different but overlapping accesses, return the special ptr value meaning
4066 there are no accesses for this parameter if that is the case and return the
4067 first representative otherwise. Set *RO_GRP if there is a group of accesses
4068 with only read (i.e. no write) accesses. */
4070 static struct access *
4071 splice_param_accesses (tree parm, bool *ro_grp)
4073 int i, j, access_count, group_count;
4074 int agg_size, total_size = 0;
4075 struct access *access, *res, **prev_acc_ptr = &res;
4076 vec<access_p> *access_vec;
4078 access_vec = get_base_access_vector (parm);
4079 if (!access_vec)
4080 return &no_accesses_representant;
4081 access_count = access_vec->length ();
4083 access_vec->qsort (compare_access_positions);
4085 i = 0;
4086 total_size = 0;
4087 group_count = 0;
4088 while (i < access_count)
4090 bool modification;
4091 tree a1_alias_type;
4092 access = (*access_vec)[i];
4093 modification = access->write;
4094 if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type)))
4095 return NULL;
4096 a1_alias_type = reference_alias_ptr_type (access->expr);
4098 /* Access is about to become group representative unless we find some
4099 nasty overlap which would preclude us from breaking this parameter
4100 apart. */
4102 j = i + 1;
4103 while (j < access_count)
4105 struct access *ac2 = (*access_vec)[j];
4106 if (ac2->offset != access->offset)
4108 /* All or nothing law for parameters. */
4109 if (access->offset + access->size > ac2->offset)
4110 return NULL;
4111 else
4112 break;
4114 else if (ac2->size != access->size)
4115 return NULL;
4117 if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type))
4118 || (ac2->type != access->type
4119 && (TREE_ADDRESSABLE (ac2->type)
4120 || TREE_ADDRESSABLE (access->type)))
4121 || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
4122 return NULL;
4124 modification |= ac2->write;
4125 ac2->group_representative = access;
4126 ac2->next_sibling = access->next_sibling;
4127 access->next_sibling = ac2;
4128 j++;
4131 group_count++;
4132 access->grp_maybe_modified = modification;
4133 if (!modification)
4134 *ro_grp = true;
4135 *prev_acc_ptr = access;
4136 prev_acc_ptr = &access->next_grp;
4137 total_size += access->size;
4138 i = j;
4141 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4142 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4143 else
4144 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4145 if (total_size >= agg_size)
4146 return NULL;
4148 gcc_assert (group_count > 0);
4149 return res;
4152 /* Decide whether parameters with representative accesses given by REPR should
4153 be reduced into components. */
4155 static int
4156 decide_one_param_reduction (struct access *repr)
4158 int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
4159 bool by_ref;
4160 tree parm;
4162 parm = repr->base;
4163 cur_parm_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4164 gcc_assert (cur_parm_size > 0);
4166 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4168 by_ref = true;
4169 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4171 else
4173 by_ref = false;
4174 agg_size = cur_parm_size;
4177 if (dump_file)
4179 struct access *acc;
4180 fprintf (dump_file, "Evaluating PARAM group sizes for ");
4181 print_generic_expr (dump_file, parm, 0);
4182 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
4183 for (acc = repr; acc; acc = acc->next_grp)
4184 dump_access (dump_file, acc, true);
4187 total_size = 0;
4188 new_param_count = 0;
4190 for (; repr; repr = repr->next_grp)
4192 gcc_assert (parm == repr->base);
4194 /* Taking the address of a non-addressable field is verboten. */
4195 if (by_ref && repr->non_addressable)
4196 return 0;
4198 /* Do not decompose a non-BLKmode param in a way that would
4199 create BLKmode params. Especially for by-reference passing
4200 (thus, pointer-type param) this is hardly worthwhile. */
4201 if (DECL_MODE (parm) != BLKmode
4202 && TYPE_MODE (repr->type) == BLKmode)
4203 return 0;
4205 if (!by_ref || (!repr->grp_maybe_modified
4206 && !repr->grp_not_necessarilly_dereferenced))
4207 total_size += repr->size;
4208 else
4209 total_size += cur_parm_size;
4211 new_param_count++;
4214 gcc_assert (new_param_count > 0);
4216 if (optimize_function_for_size_p (cfun))
4217 parm_size_limit = cur_parm_size;
4218 else
4219 parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
4220 * cur_parm_size);
4222 if (total_size < agg_size
4223 && total_size <= parm_size_limit)
4225 if (dump_file)
4226 fprintf (dump_file, " ....will be split into %i components\n",
4227 new_param_count);
4228 return new_param_count;
4230 else
4231 return 0;
4234 /* The order of the following enums is important, we need to do extra work for
4235 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4236 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
4237 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
4239 /* Identify representatives of all accesses to all candidate parameters for
4240 IPA-SRA. Return result based on what representatives have been found. */
4242 static enum ipa_splicing_result
4243 splice_all_param_accesses (vec<access_p> &representatives)
4245 enum ipa_splicing_result result = NO_GOOD_ACCESS;
4246 tree parm;
4247 struct access *repr;
4249 representatives.create (func_param_count);
4251 for (parm = DECL_ARGUMENTS (current_function_decl);
4252 parm;
4253 parm = DECL_CHAIN (parm))
4255 if (is_unused_scalar_param (parm))
4257 representatives.quick_push (&no_accesses_representant);
4258 if (result == NO_GOOD_ACCESS)
4259 result = UNUSED_PARAMS;
4261 else if (POINTER_TYPE_P (TREE_TYPE (parm))
4262 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
4263 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4265 repr = unmodified_by_ref_scalar_representative (parm);
4266 representatives.quick_push (repr);
4267 if (repr)
4268 result = UNMODIF_BY_REF_ACCESSES;
4270 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4272 bool ro_grp = false;
4273 repr = splice_param_accesses (parm, &ro_grp);
4274 representatives.quick_push (repr);
4276 if (repr && !no_accesses_p (repr))
4278 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4280 if (ro_grp)
4281 result = UNMODIF_BY_REF_ACCESSES;
4282 else if (result < MODIF_BY_REF_ACCESSES)
4283 result = MODIF_BY_REF_ACCESSES;
4285 else if (result < BY_VAL_ACCESSES)
4286 result = BY_VAL_ACCESSES;
4288 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
4289 result = UNUSED_PARAMS;
4291 else
4292 representatives.quick_push (NULL);
4295 if (result == NO_GOOD_ACCESS)
4297 representatives.release ();
4298 return NO_GOOD_ACCESS;
4301 return result;
4304 /* Return the index of BASE in PARMS. Abort if it is not found. */
4306 static inline int
4307 get_param_index (tree base, vec<tree> parms)
4309 int i, len;
4311 len = parms.length ();
4312 for (i = 0; i < len; i++)
4313 if (parms[i] == base)
4314 return i;
4315 gcc_unreachable ();
4318 /* Convert the decisions made at the representative level into compact
4319 parameter adjustments. REPRESENTATIVES are pointers to first
4320 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4321 final number of adjustments. */
4323 static ipa_parm_adjustment_vec
4324 turn_representatives_into_adjustments (vec<access_p> representatives,
4325 int adjustments_count)
4327 vec<tree> parms;
4328 ipa_parm_adjustment_vec adjustments;
4329 tree parm;
4330 int i;
4332 gcc_assert (adjustments_count > 0);
4333 parms = ipa_get_vector_of_formal_parms (current_function_decl);
4334 adjustments.create (adjustments_count);
4335 parm = DECL_ARGUMENTS (current_function_decl);
4336 for (i = 0; i < func_param_count; i++, parm = DECL_CHAIN (parm))
4338 struct access *repr = representatives[i];
4340 if (!repr || no_accesses_p (repr))
4342 struct ipa_parm_adjustment adj;
4344 memset (&adj, 0, sizeof (adj));
4345 adj.base_index = get_param_index (parm, parms);
4346 adj.base = parm;
4347 if (!repr)
4348 adj.op = IPA_PARM_OP_COPY;
4349 else
4350 adj.op = IPA_PARM_OP_REMOVE;
4351 adj.arg_prefix = "ISRA";
4352 adjustments.quick_push (adj);
4354 else
4356 struct ipa_parm_adjustment adj;
4357 int index = get_param_index (parm, parms);
4359 for (; repr; repr = repr->next_grp)
4361 memset (&adj, 0, sizeof (adj));
4362 gcc_assert (repr->base == parm);
4363 adj.base_index = index;
4364 adj.base = repr->base;
4365 adj.type = repr->type;
4366 adj.alias_ptr_type = reference_alias_ptr_type (repr->expr);
4367 adj.offset = repr->offset;
4368 adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
4369 && (repr->grp_maybe_modified
4370 || repr->grp_not_necessarilly_dereferenced));
4371 adj.arg_prefix = "ISRA";
4372 adjustments.quick_push (adj);
4376 parms.release ();
4377 return adjustments;
4380 /* Analyze the collected accesses and produce a plan what to do with the
4381 parameters in the form of adjustments, NULL meaning nothing. */
4383 static ipa_parm_adjustment_vec
4384 analyze_all_param_acesses (void)
4386 enum ipa_splicing_result repr_state;
4387 bool proceed = false;
4388 int i, adjustments_count = 0;
4389 vec<access_p> representatives;
4390 ipa_parm_adjustment_vec adjustments;
4392 repr_state = splice_all_param_accesses (representatives);
4393 if (repr_state == NO_GOOD_ACCESS)
4394 return ipa_parm_adjustment_vec ();
4396 /* If there are any parameters passed by reference which are not modified
4397 directly, we need to check whether they can be modified indirectly. */
4398 if (repr_state == UNMODIF_BY_REF_ACCESSES)
4400 analyze_caller_dereference_legality (representatives);
4401 analyze_modified_params (representatives);
4404 for (i = 0; i < func_param_count; i++)
4406 struct access *repr = representatives[i];
4408 if (repr && !no_accesses_p (repr))
4410 if (repr->grp_scalar_ptr)
4412 adjustments_count++;
4413 if (repr->grp_not_necessarilly_dereferenced
4414 || repr->grp_maybe_modified)
4415 representatives[i] = NULL;
4416 else
4418 proceed = true;
4419 sra_stats.scalar_by_ref_to_by_val++;
4422 else
4424 int new_components = decide_one_param_reduction (repr);
4426 if (new_components == 0)
4428 representatives[i] = NULL;
4429 adjustments_count++;
4431 else
4433 adjustments_count += new_components;
4434 sra_stats.aggregate_params_reduced++;
4435 sra_stats.param_reductions_created += new_components;
4436 proceed = true;
4440 else
4442 if (no_accesses_p (repr))
4444 proceed = true;
4445 sra_stats.deleted_unused_parameters++;
4447 adjustments_count++;
4451 if (!proceed && dump_file)
4452 fprintf (dump_file, "NOT proceeding to change params.\n");
4454 if (proceed)
4455 adjustments = turn_representatives_into_adjustments (representatives,
4456 adjustments_count);
4457 else
4458 adjustments = ipa_parm_adjustment_vec ();
4460 representatives.release ();
4461 return adjustments;
4464 /* If a parameter replacement identified by ADJ does not yet exist in the form
4465 of declaration, create it and record it, otherwise return the previously
4466 created one. */
4468 static tree
4469 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
4471 tree repl;
4472 if (!adj->new_ssa_base)
4474 char *pretty_name = make_fancy_name (adj->base);
4476 repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR");
4477 DECL_NAME (repl) = get_identifier (pretty_name);
4478 obstack_free (&name_obstack, pretty_name);
4480 adj->new_ssa_base = repl;
4482 else
4483 repl = adj->new_ssa_base;
4484 return repl;
4487 /* Find the first adjustment for a particular parameter BASE in a vector of
4488 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4489 adjustment. */
4491 static struct ipa_parm_adjustment *
4492 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
4494 int i, len;
4496 len = adjustments.length ();
4497 for (i = 0; i < len; i++)
4499 struct ipa_parm_adjustment *adj;
4501 adj = &adjustments[i];
4502 if (adj->op != IPA_PARM_OP_COPY && adj->base == base)
4503 return adj;
4506 return NULL;
4509 /* If the statement STMT defines an SSA_NAME of a parameter which is to be
4510 removed because its value is not used, replace the SSA_NAME with a one
4511 relating to a created VAR_DECL together all of its uses and return true.
4512 ADJUSTMENTS is a pointer to an adjustments vector. */
4514 static bool
4515 replace_removed_params_ssa_names (gimple stmt,
4516 ipa_parm_adjustment_vec adjustments)
4518 struct ipa_parm_adjustment *adj;
4519 tree lhs, decl, repl, name;
4521 if (gimple_code (stmt) == GIMPLE_PHI)
4522 lhs = gimple_phi_result (stmt);
4523 else if (is_gimple_assign (stmt))
4524 lhs = gimple_assign_lhs (stmt);
4525 else if (is_gimple_call (stmt))
4526 lhs = gimple_call_lhs (stmt);
4527 else
4528 gcc_unreachable ();
4530 if (TREE_CODE (lhs) != SSA_NAME)
4531 return false;
4533 decl = SSA_NAME_VAR (lhs);
4534 if (decl == NULL_TREE
4535 || TREE_CODE (decl) != PARM_DECL)
4536 return false;
4538 adj = get_adjustment_for_base (adjustments, decl);
4539 if (!adj)
4540 return false;
4542 repl = get_replaced_param_substitute (adj);
4543 name = make_ssa_name (repl, stmt);
4545 if (dump_file)
4547 fprintf (dump_file, "replacing an SSA name of a removed param ");
4548 print_generic_expr (dump_file, lhs, 0);
4549 fprintf (dump_file, " with ");
4550 print_generic_expr (dump_file, name, 0);
4551 fprintf (dump_file, "\n");
4554 if (is_gimple_assign (stmt))
4555 gimple_assign_set_lhs (stmt, name);
4556 else if (is_gimple_call (stmt))
4557 gimple_call_set_lhs (stmt, name);
4558 else
4559 gimple_phi_set_result (stmt, name);
4561 replace_uses_by (lhs, name);
4562 release_ssa_name (lhs);
4563 return true;
4566 /* If the statement STMT contains any expressions that need to replaced with a
4567 different one as noted by ADJUSTMENTS, do so. Handle any potential type
4568 incompatibilities (GSI is used to accommodate conversion statements and must
4569 point to the statement). Return true iff the statement was modified. */
4571 static bool
4572 sra_ipa_modify_assign (gimple stmt, gimple_stmt_iterator *gsi,
4573 ipa_parm_adjustment_vec adjustments)
4575 tree *lhs_p, *rhs_p;
4576 bool any;
4578 if (!gimple_assign_single_p (stmt))
4579 return false;
4581 rhs_p = gimple_assign_rhs1_ptr (stmt);
4582 lhs_p = gimple_assign_lhs_ptr (stmt);
4584 any = ipa_modify_expr (rhs_p, false, adjustments);
4585 any |= ipa_modify_expr (lhs_p, false, adjustments);
4586 if (any)
4588 tree new_rhs = NULL_TREE;
4590 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
4592 if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
4594 /* V_C_Es of constructors can cause trouble (PR 42714). */
4595 if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
4596 *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
4597 else
4598 *rhs_p = build_constructor (TREE_TYPE (*lhs_p),
4599 NULL);
4601 else
4602 new_rhs = fold_build1_loc (gimple_location (stmt),
4603 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
4604 *rhs_p);
4606 else if (REFERENCE_CLASS_P (*rhs_p)
4607 && is_gimple_reg_type (TREE_TYPE (*lhs_p))
4608 && !is_gimple_reg (*lhs_p))
4609 /* This can happen when an assignment in between two single field
4610 structures is turned into an assignment in between two pointers to
4611 scalars (PR 42237). */
4612 new_rhs = *rhs_p;
4614 if (new_rhs)
4616 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
4617 true, GSI_SAME_STMT);
4619 gimple_assign_set_rhs_from_tree (gsi, tmp);
4622 return true;
4625 return false;
4628 /* Traverse the function body and all modifications as described in
4629 ADJUSTMENTS. Return true iff the CFG has been changed. */
4631 bool
4632 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
4634 bool cfg_changed = false;
4635 basic_block bb;
4637 FOR_EACH_BB_FN (bb, cfun)
4639 gimple_stmt_iterator gsi;
4641 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4642 replace_removed_params_ssa_names (gsi_stmt (gsi), adjustments);
4644 gsi = gsi_start_bb (bb);
4645 while (!gsi_end_p (gsi))
4647 gimple stmt = gsi_stmt (gsi);
4648 bool modified = false;
4649 tree *t;
4650 unsigned i;
4652 switch (gimple_code (stmt))
4654 case GIMPLE_RETURN:
4655 t = gimple_return_retval_ptr (stmt);
4656 if (*t != NULL_TREE)
4657 modified |= ipa_modify_expr (t, true, adjustments);
4658 break;
4660 case GIMPLE_ASSIGN:
4661 modified |= sra_ipa_modify_assign (stmt, &gsi, adjustments);
4662 modified |= replace_removed_params_ssa_names (stmt, adjustments);
4663 break;
4665 case GIMPLE_CALL:
4666 /* Operands must be processed before the lhs. */
4667 for (i = 0; i < gimple_call_num_args (stmt); i++)
4669 t = gimple_call_arg_ptr (stmt, i);
4670 modified |= ipa_modify_expr (t, true, adjustments);
4673 if (gimple_call_lhs (stmt))
4675 t = gimple_call_lhs_ptr (stmt);
4676 modified |= ipa_modify_expr (t, false, adjustments);
4677 modified |= replace_removed_params_ssa_names (stmt,
4678 adjustments);
4680 break;
4682 case GIMPLE_ASM:
4684 gimple_asm asm_stmt = as_a <gimple_asm> (stmt);
4685 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
4687 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
4688 modified |= ipa_modify_expr (t, true, adjustments);
4690 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
4692 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
4693 modified |= ipa_modify_expr (t, false, adjustments);
4696 break;
4698 default:
4699 break;
4702 if (modified)
4704 update_stmt (stmt);
4705 if (maybe_clean_eh_stmt (stmt)
4706 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
4707 cfg_changed = true;
4709 gsi_next (&gsi);
4713 return cfg_changed;
4716 /* Call gimple_debug_bind_reset_value on all debug statements describing
4717 gimple register parameters that are being removed or replaced. */
4719 static void
4720 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
4722 int i, len;
4723 gimple_stmt_iterator *gsip = NULL, gsi;
4725 if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
4727 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
4728 gsip = &gsi;
4730 len = adjustments.length ();
4731 for (i = 0; i < len; i++)
4733 struct ipa_parm_adjustment *adj;
4734 imm_use_iterator ui;
4735 gimple stmt;
4736 gimple_debug def_temp;
4737 tree name, vexpr, copy = NULL_TREE;
4738 use_operand_p use_p;
4740 adj = &adjustments[i];
4741 if (adj->op == IPA_PARM_OP_COPY || !is_gimple_reg (adj->base))
4742 continue;
4743 name = ssa_default_def (cfun, adj->base);
4744 vexpr = NULL;
4745 if (name)
4746 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
4748 if (gimple_clobber_p (stmt))
4750 gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
4751 unlink_stmt_vdef (stmt);
4752 gsi_remove (&cgsi, true);
4753 release_defs (stmt);
4754 continue;
4756 /* All other users must have been removed by
4757 ipa_sra_modify_function_body. */
4758 gcc_assert (is_gimple_debug (stmt));
4759 if (vexpr == NULL && gsip != NULL)
4761 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
4762 vexpr = make_node (DEBUG_EXPR_DECL);
4763 def_temp = gimple_build_debug_source_bind (vexpr, adj->base,
4764 NULL);
4765 DECL_ARTIFICIAL (vexpr) = 1;
4766 TREE_TYPE (vexpr) = TREE_TYPE (name);
4767 DECL_MODE (vexpr) = DECL_MODE (adj->base);
4768 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
4770 if (vexpr)
4772 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
4773 SET_USE (use_p, vexpr);
4775 else
4776 gimple_debug_bind_reset_value (stmt);
4777 update_stmt (stmt);
4779 /* Create a VAR_DECL for debug info purposes. */
4780 if (!DECL_IGNORED_P (adj->base))
4782 copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
4783 VAR_DECL, DECL_NAME (adj->base),
4784 TREE_TYPE (adj->base));
4785 if (DECL_PT_UID_SET_P (adj->base))
4786 SET_DECL_PT_UID (copy, DECL_PT_UID (adj->base));
4787 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (adj->base);
4788 TREE_READONLY (copy) = TREE_READONLY (adj->base);
4789 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (adj->base);
4790 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (adj->base);
4791 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (adj->base);
4792 DECL_IGNORED_P (copy) = DECL_IGNORED_P (adj->base);
4793 DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (adj->base);
4794 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
4795 SET_DECL_RTL (copy, 0);
4796 TREE_USED (copy) = 1;
4797 DECL_CONTEXT (copy) = current_function_decl;
4798 add_local_decl (cfun, copy);
4799 DECL_CHAIN (copy) =
4800 BLOCK_VARS (DECL_INITIAL (current_function_decl));
4801 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
4803 if (gsip != NULL && copy && target_for_debug_bind (adj->base))
4805 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
4806 if (vexpr)
4807 def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
4808 else
4809 def_temp = gimple_build_debug_source_bind (copy, adj->base,
4810 NULL);
4811 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
4816 /* Return false if all callers have at least as many actual arguments as there
4817 are formal parameters in the current function and that their types
4818 match. */
4820 static bool
4821 some_callers_have_mismatched_arguments_p (struct cgraph_node *node,
4822 void *data ATTRIBUTE_UNUSED)
4824 struct cgraph_edge *cs;
4825 for (cs = node->callers; cs; cs = cs->next_caller)
4826 if (!callsite_arguments_match_p (cs->call_stmt))
4827 return true;
4829 return false;
4832 /* Convert all callers of NODE. */
4834 static bool
4835 convert_callers_for_node (struct cgraph_node *node,
4836 void *data)
4838 ipa_parm_adjustment_vec *adjustments = (ipa_parm_adjustment_vec *) data;
4839 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
4840 struct cgraph_edge *cs;
4842 for (cs = node->callers; cs; cs = cs->next_caller)
4844 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
4846 if (dump_file)
4847 fprintf (dump_file, "Adjusting call %s/%i -> %s/%i\n",
4848 xstrdup (cs->caller->name ()),
4849 cs->caller->order,
4850 xstrdup (cs->callee->name ()),
4851 cs->callee->order);
4853 ipa_modify_call_arguments (cs, cs->call_stmt, *adjustments);
4855 pop_cfun ();
4858 for (cs = node->callers; cs; cs = cs->next_caller)
4859 if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
4860 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
4861 compute_inline_parameters (cs->caller, true);
4862 BITMAP_FREE (recomputed_callers);
4864 return true;
4867 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
4869 static void
4870 convert_callers (struct cgraph_node *node, tree old_decl,
4871 ipa_parm_adjustment_vec adjustments)
4873 basic_block this_block;
4875 node->call_for_symbol_thunks_and_aliases (convert_callers_for_node,
4876 &adjustments, false);
4878 if (!encountered_recursive_call)
4879 return;
4881 FOR_EACH_BB_FN (this_block, cfun)
4883 gimple_stmt_iterator gsi;
4885 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
4887 gimple stmt = gsi_stmt (gsi);
4888 tree call_fndecl;
4889 if (gimple_code (stmt) != GIMPLE_CALL)
4890 continue;
4891 call_fndecl = gimple_call_fndecl (stmt);
4892 if (call_fndecl == old_decl)
4894 if (dump_file)
4895 fprintf (dump_file, "Adjusting recursive call");
4896 gimple_call_set_fndecl (stmt, node->decl);
4897 ipa_modify_call_arguments (NULL, stmt, adjustments);
4902 return;
4905 /* Perform all the modification required in IPA-SRA for NODE to have parameters
4906 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
4908 static bool
4909 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
4911 struct cgraph_node *new_node;
4912 bool cfg_changed;
4914 cgraph_edge::rebuild_edges ();
4915 free_dominance_info (CDI_DOMINATORS);
4916 pop_cfun ();
4918 /* This must be done after rebuilding cgraph edges for node above.
4919 Otherwise any recursive calls to node that are recorded in
4920 redirect_callers will be corrupted. */
4921 vec<cgraph_edge *> redirect_callers = node->collect_callers ();
4922 new_node = node->create_version_clone_with_body (redirect_callers, NULL,
4923 NULL, false, NULL, NULL,
4924 "isra");
4925 redirect_callers.release ();
4927 push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
4928 ipa_modify_formal_parameters (current_function_decl, adjustments);
4929 cfg_changed = ipa_sra_modify_function_body (adjustments);
4930 sra_ipa_reset_debug_stmts (adjustments);
4931 convert_callers (new_node, node->decl, adjustments);
4932 new_node->make_local ();
4933 return cfg_changed;
4936 /* If NODE has a caller, return true. */
4938 static bool
4939 has_caller_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
4941 if (node->callers)
4942 return true;
4943 return false;
4946 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
4947 attributes, return true otherwise. NODE is the cgraph node of the current
4948 function. */
4950 static bool
4951 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
4953 if (!node->can_be_local_p ())
4955 if (dump_file)
4956 fprintf (dump_file, "Function not local to this compilation unit.\n");
4957 return false;
4960 if (!node->local.can_change_signature)
4962 if (dump_file)
4963 fprintf (dump_file, "Function can not change signature.\n");
4964 return false;
4967 if (!tree_versionable_function_p (node->decl))
4969 if (dump_file)
4970 fprintf (dump_file, "Function is not versionable.\n");
4971 return false;
4974 if (!opt_for_fn (node->decl, optimize)
4975 || !opt_for_fn (node->decl, flag_ipa_sra))
4977 if (dump_file)
4978 fprintf (dump_file, "Function not optimized.\n");
4979 return false;
4982 if (DECL_VIRTUAL_P (current_function_decl))
4984 if (dump_file)
4985 fprintf (dump_file, "Function is a virtual method.\n");
4986 return false;
4989 if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
4990 && inline_summary (node)->size >= MAX_INLINE_INSNS_AUTO)
4992 if (dump_file)
4993 fprintf (dump_file, "Function too big to be made truly local.\n");
4994 return false;
4997 if (!node->call_for_symbol_thunks_and_aliases (has_caller_p, NULL, true))
4999 if (dump_file)
5000 fprintf (dump_file,
5001 "Function has no callers in this compilation unit.\n");
5002 return false;
5005 if (cfun->stdarg)
5007 if (dump_file)
5008 fprintf (dump_file, "Function uses stdarg. \n");
5009 return false;
5012 if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
5013 return false;
5015 if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
5017 if (dump_file)
5018 fprintf (dump_file, "Always inline function will be inlined "
5019 "anyway. \n");
5020 return false;
5023 return true;
5026 /* Perform early interprocedural SRA. */
5028 static unsigned int
5029 ipa_early_sra (void)
5031 struct cgraph_node *node = cgraph_node::get (current_function_decl);
5032 ipa_parm_adjustment_vec adjustments;
5033 int ret = 0;
5035 if (!ipa_sra_preliminary_function_checks (node))
5036 return 0;
5038 sra_initialize ();
5039 sra_mode = SRA_MODE_EARLY_IPA;
5041 if (!find_param_candidates ())
5043 if (dump_file)
5044 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
5045 goto simple_out;
5048 if (node->call_for_symbol_thunks_and_aliases
5049 (some_callers_have_mismatched_arguments_p, NULL, true))
5051 if (dump_file)
5052 fprintf (dump_file, "There are callers with insufficient number of "
5053 "arguments or arguments with type mismatches.\n");
5054 goto simple_out;
5057 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
5058 func_param_count
5059 * last_basic_block_for_fn (cfun));
5060 final_bbs = BITMAP_ALLOC (NULL);
5062 scan_function ();
5063 if (encountered_apply_args)
5065 if (dump_file)
5066 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
5067 goto out;
5070 if (encountered_unchangable_recursive_call)
5072 if (dump_file)
5073 fprintf (dump_file, "Function calls itself with insufficient "
5074 "number of arguments.\n");
5075 goto out;
5078 adjustments = analyze_all_param_acesses ();
5079 if (!adjustments.exists ())
5080 goto out;
5081 if (dump_file)
5082 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
5084 if (modify_function (node, adjustments))
5085 ret = TODO_update_ssa | TODO_cleanup_cfg;
5086 else
5087 ret = TODO_update_ssa;
5088 adjustments.release ();
5090 statistics_counter_event (cfun, "Unused parameters deleted",
5091 sra_stats.deleted_unused_parameters);
5092 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
5093 sra_stats.scalar_by_ref_to_by_val);
5094 statistics_counter_event (cfun, "Aggregate parameters broken up",
5095 sra_stats.aggregate_params_reduced);
5096 statistics_counter_event (cfun, "Aggregate parameter components created",
5097 sra_stats.param_reductions_created);
5099 out:
5100 BITMAP_FREE (final_bbs);
5101 free (bb_dereferences);
5102 simple_out:
5103 sra_deinitialize ();
5104 return ret;
5107 namespace {
5109 const pass_data pass_data_early_ipa_sra =
5111 GIMPLE_PASS, /* type */
5112 "eipa_sra", /* name */
5113 OPTGROUP_NONE, /* optinfo_flags */
5114 TV_IPA_SRA, /* tv_id */
5115 0, /* properties_required */
5116 0, /* properties_provided */
5117 0, /* properties_destroyed */
5118 0, /* todo_flags_start */
5119 TODO_dump_symtab, /* todo_flags_finish */
5122 class pass_early_ipa_sra : public gimple_opt_pass
5124 public:
5125 pass_early_ipa_sra (gcc::context *ctxt)
5126 : gimple_opt_pass (pass_data_early_ipa_sra, ctxt)
5129 /* opt_pass methods: */
5130 virtual bool gate (function *) { return flag_ipa_sra && dbg_cnt (eipa_sra); }
5131 virtual unsigned int execute (function *) { return ipa_early_sra (); }
5133 }; // class pass_early_ipa_sra
5135 } // anon namespace
5137 gimple_opt_pass *
5138 make_pass_early_ipa_sra (gcc::context *ctxt)
5140 return new pass_early_ipa_sra (ctxt);