PR tree-optimization/78496
[official-gcc.git] / gcc / tree-sra.c
blob1606573aeadcf3d3901493d39b5ba4c3d37aa35e
1 /* Scalar Replacement of Aggregates (SRA) converts some structure
2 references into scalar references, exposing them to the scalar
3 optimizers.
4 Copyright (C) 2008-2017 Free Software Foundation, Inc.
5 Contributed by Martin Jambor <mjambor@suse.cz>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* This file implements Scalar Reduction of Aggregates (SRA). SRA is run
24 twice, once in the early stages of compilation (early SRA) and once in the
25 late stages (late SRA). The aim of both is to turn references to scalar
26 parts of aggregates into uses of independent scalar variables.
28 The two passes are nearly identical, the only difference is that early SRA
29 does not scalarize unions which are used as the result in a GIMPLE_RETURN
30 statement because together with inlining this can lead to weird type
31 conversions.
33 Both passes operate in four stages:
35 1. The declarations that have properties which make them candidates for
36 scalarization are identified in function find_var_candidates(). The
37 candidates are stored in candidate_bitmap.
39 2. The function body is scanned. In the process, declarations which are
40 used in a manner that prevent their scalarization are removed from the
41 candidate bitmap. More importantly, for every access into an aggregate,
42 an access structure (struct access) is created by create_access() and
43 stored in a vector associated with the aggregate. Among other
44 information, the aggregate declaration, the offset and size of the access
45 and its type are stored in the structure.
47 On a related note, assign_link structures are created for every assign
48 statement between candidate aggregates and attached to the related
49 accesses.
51 3. The vectors of accesses are analyzed. They are first sorted according to
52 their offset and size and then scanned for partially overlapping accesses
53 (i.e. those which overlap but one is not entirely within another). Such
54 an access disqualifies the whole aggregate from being scalarized.
56 If there is no such inhibiting overlap, a representative access structure
57 is chosen for every unique combination of offset and size. Afterwards,
58 the pass builds a set of trees from these structures, in which children
59 of an access are within their parent (in terms of offset and size).
61 Then accesses are propagated whenever possible (i.e. in cases when it
62 does not create a partially overlapping access) across assign_links from
63 the right hand side to the left hand side.
65 Then the set of trees for each declaration is traversed again and those
66 accesses which should be replaced by a scalar are identified.
68 4. The function is traversed again, and for every reference into an
69 aggregate that has some component which is about to be scalarized,
70 statements are amended and new statements are created as necessary.
71 Finally, if a parameter got scalarized, the scalar replacements are
72 initialized with values from respective parameter aggregates. */
74 #include "config.h"
75 #include "system.h"
76 #include "coretypes.h"
77 #include "backend.h"
78 #include "target.h"
79 #include "rtl.h"
80 #include "tree.h"
81 #include "gimple.h"
82 #include "predict.h"
83 #include "alloc-pool.h"
84 #include "tree-pass.h"
85 #include "ssa.h"
86 #include "cgraph.h"
87 #include "gimple-pretty-print.h"
88 #include "alias.h"
89 #include "fold-const.h"
90 #include "tree-eh.h"
91 #include "stor-layout.h"
92 #include "gimplify.h"
93 #include "gimple-iterator.h"
94 #include "gimplify-me.h"
95 #include "gimple-walk.h"
96 #include "tree-cfg.h"
97 #include "tree-dfa.h"
98 #include "tree-ssa.h"
99 #include "symbol-summary.h"
100 #include "ipa-prop.h"
101 #include "params.h"
102 #include "dbgcnt.h"
103 #include "tree-inline.h"
104 #include "ipa-inline.h"
105 #include "ipa-utils.h"
106 #include "builtins.h"
108 /* Enumeration of all aggregate reductions we can do. */
109 enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
110 SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
111 SRA_MODE_INTRA }; /* late intraprocedural SRA */
113 /* Global variable describing which aggregate reduction we are performing at
114 the moment. */
115 static enum sra_mode sra_mode;
117 struct assign_link;
119 /* ACCESS represents each access to an aggregate variable (as a whole or a
120 part). It can also represent a group of accesses that refer to exactly the
121 same fragment of an aggregate (i.e. those that have exactly the same offset
122 and size). Such representatives for a single aggregate, once determined,
123 are linked in a linked list and have the group fields set.
125 Moreover, when doing intraprocedural SRA, a tree is built from those
126 representatives (by the means of first_child and next_sibling pointers), in
127 which all items in a subtree are "within" the root, i.e. their offset is
128 greater or equal to offset of the root and offset+size is smaller or equal
129 to offset+size of the root. Children of an access are sorted by offset.
131 Note that accesses to parts of vector and complex number types always
132 represented by an access to the whole complex number or a vector. It is a
133 duty of the modifying functions to replace them appropriately. */
135 struct access
137 /* Values returned by `get_ref_base_and_extent' for each component reference
138 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
139 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
140 HOST_WIDE_INT offset;
141 HOST_WIDE_INT size;
142 tree base;
144 /* Expression. It is context dependent so do not use it to create new
145 expressions to access the original aggregate. See PR 42154 for a
146 testcase. */
147 tree expr;
148 /* Type. */
149 tree type;
151 /* The statement this access belongs to. */
152 gimple *stmt;
154 /* Next group representative for this aggregate. */
155 struct access *next_grp;
157 /* Pointer to the group representative. Pointer to itself if the struct is
158 the representative. */
159 struct access *group_representative;
161 /* After access tree has been constructed, this points to the parent of the
162 current access, if there is one. NULL for roots. */
163 struct access *parent;
165 /* If this access has any children (in terms of the definition above), this
166 points to the first one. */
167 struct access *first_child;
169 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
170 described above. In IPA-SRA this is a pointer to the next access
171 belonging to the same group (having the same representative). */
172 struct access *next_sibling;
174 /* Pointers to the first and last element in the linked list of assign
175 links. */
176 struct assign_link *first_link, *last_link;
178 /* Pointer to the next access in the work queue. */
179 struct access *next_queued;
181 /* Replacement variable for this access "region." Never to be accessed
182 directly, always only by the means of get_access_replacement() and only
183 when grp_to_be_replaced flag is set. */
184 tree replacement_decl;
186 /* Is this access an access to a non-addressable field? */
187 unsigned non_addressable : 1;
189 /* Is this access made in reverse storage order? */
190 unsigned reverse : 1;
192 /* Is this particular access write access? */
193 unsigned write : 1;
195 /* Is this access currently in the work queue? */
196 unsigned grp_queued : 1;
198 /* Does this group contain a write access? This flag is propagated down the
199 access tree. */
200 unsigned grp_write : 1;
202 /* Does this group contain a read access? This flag is propagated down the
203 access tree. */
204 unsigned grp_read : 1;
206 /* Does this group contain a read access that comes from an assignment
207 statement? This flag is propagated down the access tree. */
208 unsigned grp_assignment_read : 1;
210 /* Does this group contain a write access that comes from an assignment
211 statement? This flag is propagated down the access tree. */
212 unsigned grp_assignment_write : 1;
214 /* Does this group contain a read access through a scalar type? This flag is
215 not propagated in the access tree in any direction. */
216 unsigned grp_scalar_read : 1;
218 /* Does this group contain a write access through a scalar type? This flag
219 is not propagated in the access tree in any direction. */
220 unsigned grp_scalar_write : 1;
222 /* Is this access an artificial one created to scalarize some record
223 entirely? */
224 unsigned grp_total_scalarization : 1;
226 /* Other passes of the analysis use this bit to make function
227 analyze_access_subtree create scalar replacements for this group if
228 possible. */
229 unsigned grp_hint : 1;
231 /* Is the subtree rooted in this access fully covered by scalar
232 replacements? */
233 unsigned grp_covered : 1;
235 /* If set to true, this access and all below it in an access tree must not be
236 scalarized. */
237 unsigned grp_unscalarizable_region : 1;
239 /* Whether data have been written to parts of the aggregate covered by this
240 access which is not to be scalarized. This flag is propagated up in the
241 access tree. */
242 unsigned grp_unscalarized_data : 1;
244 /* Does this access and/or group contain a write access through a
245 BIT_FIELD_REF? */
246 unsigned grp_partial_lhs : 1;
248 /* Set when a scalar replacement should be created for this variable. */
249 unsigned grp_to_be_replaced : 1;
251 /* Set when we want a replacement for the sole purpose of having it in
252 generated debug statements. */
253 unsigned grp_to_be_debug_replaced : 1;
255 /* Should TREE_NO_WARNING of a replacement be set? */
256 unsigned grp_no_warning : 1;
258 /* Is it possible that the group refers to data which might be (directly or
259 otherwise) modified? */
260 unsigned grp_maybe_modified : 1;
262 /* Set when this is a representative of a pointer to scalar (i.e. by
263 reference) parameter which we consider for turning into a plain scalar
264 (i.e. a by value parameter). */
265 unsigned grp_scalar_ptr : 1;
267 /* Set when we discover that this pointer is not safe to dereference in the
268 caller. */
269 unsigned grp_not_necessarilly_dereferenced : 1;
272 typedef struct access *access_p;
275 /* Alloc pool for allocating access structures. */
276 static object_allocator<struct access> access_pool ("SRA accesses");
278 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
279 are used to propagate subaccesses from rhs to lhs as long as they don't
280 conflict with what is already there. */
281 struct assign_link
283 struct access *lacc, *racc;
284 struct assign_link *next;
287 /* Alloc pool for allocating assign link structures. */
288 static object_allocator<assign_link> assign_link_pool ("SRA links");
290 /* Base (tree) -> Vector (vec<access_p> *) map. */
291 static hash_map<tree, auto_vec<access_p> > *base_access_vec;
293 /* Candidate hash table helpers. */
295 struct uid_decl_hasher : nofree_ptr_hash <tree_node>
297 static inline hashval_t hash (const tree_node *);
298 static inline bool equal (const tree_node *, const tree_node *);
301 /* Hash a tree in a uid_decl_map. */
303 inline hashval_t
304 uid_decl_hasher::hash (const tree_node *item)
306 return item->decl_minimal.uid;
309 /* Return true if the DECL_UID in both trees are equal. */
311 inline bool
312 uid_decl_hasher::equal (const tree_node *a, const tree_node *b)
314 return (a->decl_minimal.uid == b->decl_minimal.uid);
317 /* Set of candidates. */
318 static bitmap candidate_bitmap;
319 static hash_table<uid_decl_hasher> *candidates;
321 /* For a candidate UID return the candidates decl. */
323 static inline tree
324 candidate (unsigned uid)
326 tree_node t;
327 t.decl_minimal.uid = uid;
328 return candidates->find_with_hash (&t, static_cast <hashval_t> (uid));
331 /* Bitmap of candidates which we should try to entirely scalarize away and
332 those which cannot be (because they are and need be used as a whole). */
333 static bitmap should_scalarize_away_bitmap, cannot_scalarize_away_bitmap;
335 /* Bitmap of candidates in the constant pool, which cannot be scalarized
336 because this would produce non-constant expressions (e.g. Ada). */
337 static bitmap disqualified_constants;
339 /* Obstack for creation of fancy names. */
340 static struct obstack name_obstack;
342 /* Head of a linked list of accesses that need to have its subaccesses
343 propagated to their assignment counterparts. */
344 static struct access *work_queue_head;
346 /* Number of parameters of the analyzed function when doing early ipa SRA. */
347 static int func_param_count;
349 /* scan_function sets the following to true if it encounters a call to
350 __builtin_apply_args. */
351 static bool encountered_apply_args;
353 /* Set by scan_function when it finds a recursive call. */
354 static bool encountered_recursive_call;
356 /* Set by scan_function when it finds a recursive call with less actual
357 arguments than formal parameters.. */
358 static bool encountered_unchangable_recursive_call;
360 /* This is a table in which for each basic block and parameter there is a
361 distance (offset + size) in that parameter which is dereferenced and
362 accessed in that BB. */
363 static HOST_WIDE_INT *bb_dereferences;
364 /* Bitmap of BBs that can cause the function to "stop" progressing by
365 returning, throwing externally, looping infinitely or calling a function
366 which might abort etc.. */
367 static bitmap final_bbs;
369 /* Representative of no accesses at all. */
370 static struct access no_accesses_representant;
372 /* Predicate to test the special value. */
374 static inline bool
375 no_accesses_p (struct access *access)
377 return access == &no_accesses_representant;
380 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
381 representative fields are dumped, otherwise those which only describe the
382 individual access are. */
384 static struct
386 /* Number of processed aggregates is readily available in
387 analyze_all_variable_accesses and so is not stored here. */
389 /* Number of created scalar replacements. */
390 int replacements;
392 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
393 expression. */
394 int exprs;
396 /* Number of statements created by generate_subtree_copies. */
397 int subtree_copies;
399 /* Number of statements created by load_assign_lhs_subreplacements. */
400 int subreplacements;
402 /* Number of times sra_modify_assign has deleted a statement. */
403 int deleted;
405 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
406 RHS reparately due to type conversions or nonexistent matching
407 references. */
408 int separate_lhs_rhs_handling;
410 /* Number of parameters that were removed because they were unused. */
411 int deleted_unused_parameters;
413 /* Number of scalars passed as parameters by reference that have been
414 converted to be passed by value. */
415 int scalar_by_ref_to_by_val;
417 /* Number of aggregate parameters that were replaced by one or more of their
418 components. */
419 int aggregate_params_reduced;
421 /* Numbber of components created when splitting aggregate parameters. */
422 int param_reductions_created;
423 } sra_stats;
425 static void
426 dump_access (FILE *f, struct access *access, bool grp)
428 fprintf (f, "access { ");
429 fprintf (f, "base = (%d)'", DECL_UID (access->base));
430 print_generic_expr (f, access->base, 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 fprintf (f, ", non_addressable = %d, reverse = %d",
438 access->non_addressable, access->reverse);
439 if (grp)
440 fprintf (f, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
441 "grp_assignment_write = %d, grp_scalar_read = %d, "
442 "grp_scalar_write = %d, grp_total_scalarization = %d, "
443 "grp_hint = %d, grp_covered = %d, "
444 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
445 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
446 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
447 "grp_not_necessarilly_dereferenced = %d\n",
448 access->grp_read, access->grp_write, access->grp_assignment_read,
449 access->grp_assignment_write, access->grp_scalar_read,
450 access->grp_scalar_write, access->grp_total_scalarization,
451 access->grp_hint, access->grp_covered,
452 access->grp_unscalarizable_region, access->grp_unscalarized_data,
453 access->grp_partial_lhs, access->grp_to_be_replaced,
454 access->grp_to_be_debug_replaced, access->grp_maybe_modified,
455 access->grp_not_necessarilly_dereferenced);
456 else
457 fprintf (f, ", write = %d, grp_total_scalarization = %d, "
458 "grp_partial_lhs = %d\n",
459 access->write, access->grp_total_scalarization,
460 access->grp_partial_lhs);
463 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
465 static void
466 dump_access_tree_1 (FILE *f, struct access *access, int level)
470 int i;
472 for (i = 0; i < level; i++)
473 fputs ("* ", dump_file);
475 dump_access (f, access, true);
477 if (access->first_child)
478 dump_access_tree_1 (f, access->first_child, level + 1);
480 access = access->next_sibling;
482 while (access);
485 /* Dump all access trees for a variable, given the pointer to the first root in
486 ACCESS. */
488 static void
489 dump_access_tree (FILE *f, struct access *access)
491 for (; access; access = access->next_grp)
492 dump_access_tree_1 (f, access, 0);
495 /* Return true iff ACC is non-NULL and has subaccesses. */
497 static inline bool
498 access_has_children_p (struct access *acc)
500 return acc && acc->first_child;
503 /* Return true iff ACC is (partly) covered by at least one replacement. */
505 static bool
506 access_has_replacements_p (struct access *acc)
508 struct access *child;
509 if (acc->grp_to_be_replaced)
510 return true;
511 for (child = acc->first_child; child; child = child->next_sibling)
512 if (access_has_replacements_p (child))
513 return true;
514 return false;
517 /* Return a vector of pointers to accesses for the variable given in BASE or
518 NULL if there is none. */
520 static vec<access_p> *
521 get_base_access_vector (tree base)
523 return base_access_vec->get (base);
526 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
527 in ACCESS. Return NULL if it cannot be found. */
529 static struct access *
530 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
531 HOST_WIDE_INT size)
533 while (access && (access->offset != offset || access->size != size))
535 struct access *child = access->first_child;
537 while (child && (child->offset + child->size <= offset))
538 child = child->next_sibling;
539 access = child;
542 return access;
545 /* Return the first group representative for DECL or NULL if none exists. */
547 static struct access *
548 get_first_repr_for_decl (tree base)
550 vec<access_p> *access_vec;
552 access_vec = get_base_access_vector (base);
553 if (!access_vec)
554 return NULL;
556 return (*access_vec)[0];
559 /* Find an access representative for the variable BASE and given OFFSET and
560 SIZE. Requires that access trees have already been built. Return NULL if
561 it cannot be found. */
563 static struct access *
564 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
565 HOST_WIDE_INT size)
567 struct access *access;
569 access = get_first_repr_for_decl (base);
570 while (access && (access->offset + access->size <= offset))
571 access = access->next_grp;
572 if (!access)
573 return NULL;
575 return find_access_in_subtree (access, offset, size);
578 /* Add LINK to the linked list of assign links of RACC. */
579 static void
580 add_link_to_rhs (struct access *racc, struct assign_link *link)
582 gcc_assert (link->racc == racc);
584 if (!racc->first_link)
586 gcc_assert (!racc->last_link);
587 racc->first_link = link;
589 else
590 racc->last_link->next = link;
592 racc->last_link = link;
593 link->next = NULL;
596 /* Move all link structures in their linked list in OLD_RACC to the linked list
597 in NEW_RACC. */
598 static void
599 relink_to_new_repr (struct access *new_racc, struct access *old_racc)
601 if (!old_racc->first_link)
603 gcc_assert (!old_racc->last_link);
604 return;
607 if (new_racc->first_link)
609 gcc_assert (!new_racc->last_link->next);
610 gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
612 new_racc->last_link->next = old_racc->first_link;
613 new_racc->last_link = old_racc->last_link;
615 else
617 gcc_assert (!new_racc->last_link);
619 new_racc->first_link = old_racc->first_link;
620 new_racc->last_link = old_racc->last_link;
622 old_racc->first_link = old_racc->last_link = NULL;
625 /* Add ACCESS to the work queue (which is actually a stack). */
627 static void
628 add_access_to_work_queue (struct access *access)
630 if (!access->grp_queued)
632 gcc_assert (!access->next_queued);
633 access->next_queued = work_queue_head;
634 access->grp_queued = 1;
635 work_queue_head = access;
639 /* Pop an access from the work queue, and return it, assuming there is one. */
641 static struct access *
642 pop_access_from_work_queue (void)
644 struct access *access = work_queue_head;
646 work_queue_head = access->next_queued;
647 access->next_queued = NULL;
648 access->grp_queued = 0;
649 return access;
653 /* Allocate necessary structures. */
655 static void
656 sra_initialize (void)
658 candidate_bitmap = BITMAP_ALLOC (NULL);
659 candidates = new hash_table<uid_decl_hasher>
660 (vec_safe_length (cfun->local_decls) / 2);
661 should_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
662 cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
663 disqualified_constants = BITMAP_ALLOC (NULL);
664 gcc_obstack_init (&name_obstack);
665 base_access_vec = new hash_map<tree, auto_vec<access_p> >;
666 memset (&sra_stats, 0, sizeof (sra_stats));
667 encountered_apply_args = false;
668 encountered_recursive_call = false;
669 encountered_unchangable_recursive_call = false;
672 /* Deallocate all general structures. */
674 static void
675 sra_deinitialize (void)
677 BITMAP_FREE (candidate_bitmap);
678 delete candidates;
679 candidates = NULL;
680 BITMAP_FREE (should_scalarize_away_bitmap);
681 BITMAP_FREE (cannot_scalarize_away_bitmap);
682 BITMAP_FREE (disqualified_constants);
683 access_pool.release ();
684 assign_link_pool.release ();
685 obstack_free (&name_obstack, NULL);
687 delete base_access_vec;
690 /* Return true if DECL is a VAR_DECL in the constant pool, false otherwise. */
692 static bool constant_decl_p (tree decl)
694 return VAR_P (decl) && DECL_IN_CONSTANT_POOL (decl);
698 /* Mark LHS of assign links out of ACCESS and its children as written to. */
700 static void
701 process_subtree_disqualification (struct access *access)
703 struct access *child;
704 for (struct assign_link *link = access->first_link; link; link = link->next)
705 link->lacc->grp_write = true;
706 for (child = access->first_child; child; child = child->next_sibling)
707 process_subtree_disqualification (child);
710 /* Remove DECL from candidates for SRA and write REASON to the dump file if
711 there is one. */
712 static void
713 disqualify_candidate (tree decl, const char *reason)
715 if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl)))
716 candidates->remove_elt_with_hash (decl, DECL_UID (decl));
717 if (constant_decl_p (decl))
718 bitmap_set_bit (disqualified_constants, DECL_UID (decl));
720 if (dump_file && (dump_flags & TDF_DETAILS))
722 fprintf (dump_file, "! Disqualifying ");
723 print_generic_expr (dump_file, decl, 0);
724 fprintf (dump_file, " - %s\n", reason);
727 struct access *access = get_first_repr_for_decl (decl);
728 while (access)
730 process_subtree_disqualification (access);
731 access = access->next_grp;
735 /* Return true iff the type contains a field or an element which does not allow
736 scalarization. */
738 static bool
739 type_internals_preclude_sra_p (tree type, const char **msg)
741 tree fld;
742 tree et;
744 switch (TREE_CODE (type))
746 case RECORD_TYPE:
747 case UNION_TYPE:
748 case QUAL_UNION_TYPE:
749 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
750 if (TREE_CODE (fld) == FIELD_DECL)
752 tree ft = TREE_TYPE (fld);
754 if (TREE_THIS_VOLATILE (fld))
756 *msg = "volatile structure field";
757 return true;
759 if (!DECL_FIELD_OFFSET (fld))
761 *msg = "no structure field offset";
762 return true;
764 if (!DECL_SIZE (fld))
766 *msg = "zero structure field size";
767 return true;
769 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
771 *msg = "structure field offset not fixed";
772 return true;
774 if (!tree_fits_uhwi_p (DECL_SIZE (fld)))
776 *msg = "structure field size not fixed";
777 return true;
779 if (!tree_fits_shwi_p (bit_position (fld)))
781 *msg = "structure field size too big";
782 return true;
784 if (AGGREGATE_TYPE_P (ft)
785 && int_bit_position (fld) % BITS_PER_UNIT != 0)
787 *msg = "structure field is bit field";
788 return true;
791 if (AGGREGATE_TYPE_P (ft) && type_internals_preclude_sra_p (ft, msg))
792 return true;
795 return false;
797 case ARRAY_TYPE:
798 et = TREE_TYPE (type);
800 if (TYPE_VOLATILE (et))
802 *msg = "element type is volatile";
803 return true;
806 if (AGGREGATE_TYPE_P (et) && type_internals_preclude_sra_p (et, msg))
807 return true;
809 return false;
811 default:
812 return false;
816 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
817 base variable if it is. Return T if it is not an SSA_NAME. */
819 static tree
820 get_ssa_base_param (tree t)
822 if (TREE_CODE (t) == SSA_NAME)
824 if (SSA_NAME_IS_DEFAULT_DEF (t))
825 return SSA_NAME_VAR (t);
826 else
827 return NULL_TREE;
829 return t;
832 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
833 belongs to, unless the BB has already been marked as a potentially
834 final. */
836 static void
837 mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple *stmt)
839 basic_block bb = gimple_bb (stmt);
840 int idx, parm_index = 0;
841 tree parm;
843 if (bitmap_bit_p (final_bbs, bb->index))
844 return;
846 for (parm = DECL_ARGUMENTS (current_function_decl);
847 parm && parm != base;
848 parm = DECL_CHAIN (parm))
849 parm_index++;
851 gcc_assert (parm_index < func_param_count);
853 idx = bb->index * func_param_count + parm_index;
854 if (bb_dereferences[idx] < dist)
855 bb_dereferences[idx] = dist;
858 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
859 the three fields. Also add it to the vector of accesses corresponding to
860 the base. Finally, return the new access. */
862 static struct access *
863 create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
865 struct access *access = access_pool.allocate ();
867 memset (access, 0, sizeof (struct access));
868 access->base = base;
869 access->offset = offset;
870 access->size = size;
872 base_access_vec->get_or_insert (base).safe_push (access);
874 return access;
877 static bool maybe_add_sra_candidate (tree);
879 /* Create and insert access for EXPR. Return created access, or NULL if it is
880 not possible. Also scan for uses of constant pool as we go along and add
881 to candidates. */
883 static struct access *
884 create_access (tree expr, gimple *stmt, bool write)
886 struct access *access;
887 HOST_WIDE_INT offset, size, max_size;
888 tree base = expr;
889 bool reverse, ptr, unscalarizable_region = false;
891 base = get_ref_base_and_extent (expr, &offset, &size, &max_size, &reverse);
893 if (sra_mode == SRA_MODE_EARLY_IPA
894 && TREE_CODE (base) == MEM_REF)
896 base = get_ssa_base_param (TREE_OPERAND (base, 0));
897 if (!base)
898 return NULL;
899 ptr = true;
901 else
902 ptr = false;
904 /* For constant-pool entries, check we can substitute the constant value. */
905 if (constant_decl_p (base)
906 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA))
908 gcc_assert (!bitmap_bit_p (disqualified_constants, DECL_UID (base)));
909 if (expr != base
910 && !is_gimple_reg_type (TREE_TYPE (expr))
911 && dump_file && (dump_flags & TDF_DETAILS))
913 /* This occurs in Ada with accesses to ARRAY_RANGE_REFs,
914 and elements of multidimensional arrays (which are
915 multi-element arrays in their own right). */
916 fprintf (dump_file, "Allowing non-reg-type load of part"
917 " of constant-pool entry: ");
918 print_generic_expr (dump_file, expr, 0);
920 maybe_add_sra_candidate (base);
923 if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
924 return NULL;
926 if (sra_mode == SRA_MODE_EARLY_IPA)
928 if (size < 0 || size != max_size)
930 disqualify_candidate (base, "Encountered a variable sized access.");
931 return NULL;
933 if (TREE_CODE (expr) == COMPONENT_REF
934 && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))
936 disqualify_candidate (base, "Encountered a bit-field access.");
937 return NULL;
939 gcc_checking_assert ((offset % BITS_PER_UNIT) == 0);
941 if (ptr)
942 mark_parm_dereference (base, offset + size, stmt);
944 else
946 if (size != max_size)
948 size = max_size;
949 unscalarizable_region = true;
951 if (size < 0)
953 disqualify_candidate (base, "Encountered an unconstrained access.");
954 return NULL;
958 access = create_access_1 (base, offset, size);
959 access->expr = expr;
960 access->type = TREE_TYPE (expr);
961 access->write = write;
962 access->grp_unscalarizable_region = unscalarizable_region;
963 access->stmt = stmt;
964 access->reverse = reverse;
966 if (TREE_CODE (expr) == COMPONENT_REF
967 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1)))
968 access->non_addressable = 1;
970 return access;
974 /* Return true iff TYPE is scalarizable - i.e. a RECORD_TYPE or fixed-length
975 ARRAY_TYPE with fields that are either of gimple register types (excluding
976 bit-fields) or (recursively) scalarizable types. CONST_DECL must be true if
977 we are considering a decl from constant pool. If it is false, char arrays
978 will be refused. */
980 static bool
981 scalarizable_type_p (tree type, bool const_decl)
983 gcc_assert (!is_gimple_reg_type (type));
984 if (type_contains_placeholder_p (type))
985 return false;
987 switch (TREE_CODE (type))
989 case RECORD_TYPE:
990 for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
991 if (TREE_CODE (fld) == FIELD_DECL)
993 tree ft = TREE_TYPE (fld);
995 if (DECL_BIT_FIELD (fld))
996 return false;
998 if (!is_gimple_reg_type (ft)
999 && !scalarizable_type_p (ft, const_decl))
1000 return false;
1003 return true;
1005 case ARRAY_TYPE:
1007 HOST_WIDE_INT min_elem_size;
1008 if (const_decl)
1009 min_elem_size = 0;
1010 else
1011 min_elem_size = BITS_PER_UNIT;
1013 if (TYPE_DOMAIN (type) == NULL_TREE
1014 || !tree_fits_shwi_p (TYPE_SIZE (type))
1015 || !tree_fits_shwi_p (TYPE_SIZE (TREE_TYPE (type)))
1016 || (tree_to_shwi (TYPE_SIZE (TREE_TYPE (type))) <= min_elem_size)
1017 || !tree_fits_shwi_p (TYPE_MIN_VALUE (TYPE_DOMAIN (type))))
1018 return false;
1019 if (tree_to_shwi (TYPE_SIZE (type)) == 0
1020 && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE)
1021 /* Zero-element array, should not prevent scalarization. */
1023 else if ((tree_to_shwi (TYPE_SIZE (type)) <= 0)
1024 || !tree_fits_shwi_p (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
1025 /* Variable-length array, do not allow scalarization. */
1026 return false;
1028 tree elem = TREE_TYPE (type);
1029 if (!is_gimple_reg_type (elem)
1030 && !scalarizable_type_p (elem, const_decl))
1031 return false;
1032 return true;
1034 default:
1035 return false;
1039 static void scalarize_elem (tree, HOST_WIDE_INT, HOST_WIDE_INT, bool, tree, tree);
1041 /* Create total_scalarization accesses for all scalar fields of a member
1042 of type DECL_TYPE conforming to scalarizable_type_p. BASE
1043 must be the top-most VAR_DECL representing the variable; within that,
1044 OFFSET locates the member and REF must be the memory reference expression for
1045 the member. */
1047 static void
1048 completely_scalarize (tree base, tree decl_type, HOST_WIDE_INT offset, tree ref)
1050 switch (TREE_CODE (decl_type))
1052 case RECORD_TYPE:
1053 for (tree fld = TYPE_FIELDS (decl_type); fld; fld = DECL_CHAIN (fld))
1054 if (TREE_CODE (fld) == FIELD_DECL)
1056 HOST_WIDE_INT pos = offset + int_bit_position (fld);
1057 tree ft = TREE_TYPE (fld);
1058 tree nref = build3 (COMPONENT_REF, ft, ref, fld, NULL_TREE);
1060 scalarize_elem (base, pos, tree_to_uhwi (DECL_SIZE (fld)),
1061 TYPE_REVERSE_STORAGE_ORDER (decl_type),
1062 nref, ft);
1064 break;
1065 case ARRAY_TYPE:
1067 tree elemtype = TREE_TYPE (decl_type);
1068 tree elem_size = TYPE_SIZE (elemtype);
1069 gcc_assert (elem_size && tree_fits_shwi_p (elem_size));
1070 HOST_WIDE_INT el_size = tree_to_shwi (elem_size);
1071 gcc_assert (el_size > 0);
1073 tree minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (decl_type));
1074 gcc_assert (TREE_CODE (minidx) == INTEGER_CST);
1075 tree maxidx = TYPE_MAX_VALUE (TYPE_DOMAIN (decl_type));
1076 /* Skip (some) zero-length arrays; others have MAXIDX == MINIDX - 1. */
1077 if (maxidx)
1079 gcc_assert (TREE_CODE (maxidx) == INTEGER_CST);
1080 tree domain = TYPE_DOMAIN (decl_type);
1081 /* MINIDX and MAXIDX are inclusive, and must be interpreted in
1082 DOMAIN (e.g. signed int, whereas min/max may be size_int). */
1083 offset_int idx = wi::to_offset (minidx);
1084 offset_int max = wi::to_offset (maxidx);
1085 if (!TYPE_UNSIGNED (domain))
1087 idx = wi::sext (idx, TYPE_PRECISION (domain));
1088 max = wi::sext (max, TYPE_PRECISION (domain));
1090 for (int el_off = offset; idx <= max; ++idx)
1092 tree nref = build4 (ARRAY_REF, elemtype,
1093 ref,
1094 wide_int_to_tree (domain, idx),
1095 NULL_TREE, NULL_TREE);
1096 scalarize_elem (base, el_off, el_size,
1097 TYPE_REVERSE_STORAGE_ORDER (decl_type),
1098 nref, elemtype);
1099 el_off += el_size;
1103 break;
1104 default:
1105 gcc_unreachable ();
1109 /* Create total_scalarization accesses for a member of type TYPE, which must
1110 satisfy either is_gimple_reg_type or scalarizable_type_p. BASE must be the
1111 top-most VAR_DECL representing the variable; within that, POS and SIZE locate
1112 the member, REVERSE gives its torage order. and REF must be the reference
1113 expression for it. */
1115 static void
1116 scalarize_elem (tree base, HOST_WIDE_INT pos, HOST_WIDE_INT size, bool reverse,
1117 tree ref, tree type)
1119 if (is_gimple_reg_type (type))
1121 struct access *access = create_access_1 (base, pos, size);
1122 access->expr = ref;
1123 access->type = type;
1124 access->grp_total_scalarization = 1;
1125 access->reverse = reverse;
1126 /* Accesses for intraprocedural SRA can have their stmt NULL. */
1128 else
1129 completely_scalarize (base, type, pos, ref);
1132 /* Create a total_scalarization access for VAR as a whole. VAR must be of a
1133 RECORD_TYPE or ARRAY_TYPE conforming to scalarizable_type_p. */
1135 static void
1136 create_total_scalarization_access (tree var)
1138 HOST_WIDE_INT size = tree_to_uhwi (DECL_SIZE (var));
1139 struct access *access;
1141 access = create_access_1 (var, 0, size);
1142 access->expr = var;
1143 access->type = TREE_TYPE (var);
1144 access->grp_total_scalarization = 1;
1147 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1149 static inline bool
1150 contains_view_convert_expr_p (const_tree ref)
1152 while (handled_component_p (ref))
1154 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
1155 return true;
1156 ref = TREE_OPERAND (ref, 0);
1159 return false;
1162 /* Search the given tree for a declaration by skipping handled components and
1163 exclude it from the candidates. */
1165 static void
1166 disqualify_base_of_expr (tree t, const char *reason)
1168 t = get_base_address (t);
1169 if (sra_mode == SRA_MODE_EARLY_IPA
1170 && TREE_CODE (t) == MEM_REF)
1171 t = get_ssa_base_param (TREE_OPERAND (t, 0));
1173 if (t && DECL_P (t))
1174 disqualify_candidate (t, reason);
1177 /* Scan expression EXPR and create access structures for all accesses to
1178 candidates for scalarization. Return the created access or NULL if none is
1179 created. */
1181 static struct access *
1182 build_access_from_expr_1 (tree expr, gimple *stmt, bool write)
1184 struct access *ret = NULL;
1185 bool partial_ref;
1187 if (TREE_CODE (expr) == BIT_FIELD_REF
1188 || TREE_CODE (expr) == IMAGPART_EXPR
1189 || TREE_CODE (expr) == REALPART_EXPR)
1191 expr = TREE_OPERAND (expr, 0);
1192 partial_ref = true;
1194 else
1195 partial_ref = false;
1197 /* We need to dive through V_C_Es in order to get the size of its parameter
1198 and not the result type. Ada produces such statements. We are also
1199 capable of handling the topmost V_C_E but not any of those buried in other
1200 handled components. */
1201 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR && !storage_order_barrier_p (expr))
1202 expr = TREE_OPERAND (expr, 0);
1204 if (contains_view_convert_expr_p (expr))
1206 disqualify_base_of_expr (expr, "V_C_E under a different handled "
1207 "component.");
1208 return NULL;
1210 if (TREE_THIS_VOLATILE (expr))
1212 disqualify_base_of_expr (expr, "part of a volatile reference.");
1213 return NULL;
1216 switch (TREE_CODE (expr))
1218 case MEM_REF:
1219 if (TREE_CODE (TREE_OPERAND (expr, 0)) != ADDR_EXPR
1220 && sra_mode != SRA_MODE_EARLY_IPA)
1221 return NULL;
1222 /* fall through */
1223 case VAR_DECL:
1224 case PARM_DECL:
1225 case RESULT_DECL:
1226 case COMPONENT_REF:
1227 case ARRAY_REF:
1228 case ARRAY_RANGE_REF:
1229 ret = create_access (expr, stmt, write);
1230 break;
1232 default:
1233 break;
1236 if (write && partial_ref && ret)
1237 ret->grp_partial_lhs = 1;
1239 return ret;
1242 /* Scan expression EXPR and create access structures for all accesses to
1243 candidates for scalarization. Return true if any access has been inserted.
1244 STMT must be the statement from which the expression is taken, WRITE must be
1245 true if the expression is a store and false otherwise. */
1247 static bool
1248 build_access_from_expr (tree expr, gimple *stmt, bool write)
1250 struct access *access;
1252 access = build_access_from_expr_1 (expr, stmt, write);
1253 if (access)
1255 /* This means the aggregate is accesses as a whole in a way other than an
1256 assign statement and thus cannot be removed even if we had a scalar
1257 replacement for everything. */
1258 if (cannot_scalarize_away_bitmap)
1259 bitmap_set_bit (cannot_scalarize_away_bitmap, DECL_UID (access->base));
1260 return true;
1262 return false;
1265 /* Return the single non-EH successor edge of BB or NULL if there is none or
1266 more than one. */
1268 static edge
1269 single_non_eh_succ (basic_block bb)
1271 edge e, res = NULL;
1272 edge_iterator ei;
1274 FOR_EACH_EDGE (e, ei, bb->succs)
1275 if (!(e->flags & EDGE_EH))
1277 if (res)
1278 return NULL;
1279 res = e;
1282 return res;
1285 /* Disqualify LHS and RHS for scalarization if STMT has to terminate its BB and
1286 there is no alternative spot where to put statements SRA might need to
1287 generate after it. The spot we are looking for is an edge leading to a
1288 single non-EH successor, if it exists and is indeed single. RHS may be
1289 NULL, in that case ignore it. */
1291 static bool
1292 disqualify_if_bad_bb_terminating_stmt (gimple *stmt, tree lhs, tree rhs)
1294 if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1295 && stmt_ends_bb_p (stmt))
1297 if (single_non_eh_succ (gimple_bb (stmt)))
1298 return false;
1300 disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
1301 if (rhs)
1302 disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
1303 return true;
1305 return false;
1308 /* Scan expressions occurring in STMT, create access structures for all accesses
1309 to candidates for scalarization and remove those candidates which occur in
1310 statements or expressions that prevent them from being split apart. Return
1311 true if any access has been inserted. */
1313 static bool
1314 build_accesses_from_assign (gimple *stmt)
1316 tree lhs, rhs;
1317 struct access *lacc, *racc;
1319 if (!gimple_assign_single_p (stmt)
1320 /* Scope clobbers don't influence scalarization. */
1321 || gimple_clobber_p (stmt))
1322 return false;
1324 lhs = gimple_assign_lhs (stmt);
1325 rhs = gimple_assign_rhs1 (stmt);
1327 if (disqualify_if_bad_bb_terminating_stmt (stmt, lhs, rhs))
1328 return false;
1330 racc = build_access_from_expr_1 (rhs, stmt, false);
1331 lacc = build_access_from_expr_1 (lhs, stmt, true);
1333 if (lacc)
1335 lacc->grp_assignment_write = 1;
1336 if (storage_order_barrier_p (rhs))
1337 lacc->grp_unscalarizable_region = 1;
1340 if (racc)
1342 racc->grp_assignment_read = 1;
1343 if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
1344 && !is_gimple_reg_type (racc->type))
1345 bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
1346 if (storage_order_barrier_p (lhs))
1347 racc->grp_unscalarizable_region = 1;
1350 if (lacc && racc
1351 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1352 && !lacc->grp_unscalarizable_region
1353 && !racc->grp_unscalarizable_region
1354 && AGGREGATE_TYPE_P (TREE_TYPE (lhs))
1355 && lacc->size == racc->size
1356 && useless_type_conversion_p (lacc->type, racc->type))
1358 struct assign_link *link;
1360 link = assign_link_pool.allocate ();
1361 memset (link, 0, sizeof (struct assign_link));
1363 link->lacc = lacc;
1364 link->racc = racc;
1365 add_link_to_rhs (racc, link);
1366 /* Let's delay marking the areas as written until propagation of accesses
1367 across link. */
1368 lacc->write = false;
1371 return lacc || racc;
1374 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1375 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1377 static bool
1378 asm_visit_addr (gimple *, tree op, tree, void *)
1380 op = get_base_address (op);
1381 if (op
1382 && DECL_P (op))
1383 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
1385 return false;
1388 /* Return true iff callsite CALL has at least as many actual arguments as there
1389 are formal parameters of the function currently processed by IPA-SRA and
1390 that their types match. */
1392 static inline bool
1393 callsite_arguments_match_p (gimple *call)
1395 if (gimple_call_num_args (call) < (unsigned) func_param_count)
1396 return false;
1398 tree parm;
1399 int i;
1400 for (parm = DECL_ARGUMENTS (current_function_decl), i = 0;
1401 parm;
1402 parm = DECL_CHAIN (parm), i++)
1404 tree arg = gimple_call_arg (call, i);
1405 if (!useless_type_conversion_p (TREE_TYPE (parm), TREE_TYPE (arg)))
1406 return false;
1408 return true;
1411 /* Scan function and look for interesting expressions and create access
1412 structures for them. Return true iff any access is created. */
1414 static bool
1415 scan_function (void)
1417 basic_block bb;
1418 bool ret = false;
1420 FOR_EACH_BB_FN (bb, cfun)
1422 gimple_stmt_iterator gsi;
1423 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1425 gimple *stmt = gsi_stmt (gsi);
1426 tree t;
1427 unsigned i;
1429 if (final_bbs && stmt_can_throw_external (stmt))
1430 bitmap_set_bit (final_bbs, bb->index);
1431 switch (gimple_code (stmt))
1433 case GIMPLE_RETURN:
1434 t = gimple_return_retval (as_a <greturn *> (stmt));
1435 if (t != NULL_TREE)
1436 ret |= build_access_from_expr (t, stmt, false);
1437 if (final_bbs)
1438 bitmap_set_bit (final_bbs, bb->index);
1439 break;
1441 case GIMPLE_ASSIGN:
1442 ret |= build_accesses_from_assign (stmt);
1443 break;
1445 case GIMPLE_CALL:
1446 for (i = 0; i < gimple_call_num_args (stmt); i++)
1447 ret |= build_access_from_expr (gimple_call_arg (stmt, i),
1448 stmt, false);
1450 if (sra_mode == SRA_MODE_EARLY_IPA)
1452 tree dest = gimple_call_fndecl (stmt);
1453 int flags = gimple_call_flags (stmt);
1455 if (dest)
1457 if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1458 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1459 encountered_apply_args = true;
1460 if (recursive_call_p (current_function_decl, dest))
1462 encountered_recursive_call = true;
1463 if (!callsite_arguments_match_p (stmt))
1464 encountered_unchangable_recursive_call = true;
1468 if (final_bbs
1469 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1470 bitmap_set_bit (final_bbs, bb->index);
1473 t = gimple_call_lhs (stmt);
1474 if (t && !disqualify_if_bad_bb_terminating_stmt (stmt, t, NULL))
1475 ret |= build_access_from_expr (t, stmt, true);
1476 break;
1478 case GIMPLE_ASM:
1480 gasm *asm_stmt = as_a <gasm *> (stmt);
1481 walk_stmt_load_store_addr_ops (asm_stmt, NULL, NULL, NULL,
1482 asm_visit_addr);
1483 if (final_bbs)
1484 bitmap_set_bit (final_bbs, bb->index);
1486 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
1488 t = TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
1489 ret |= build_access_from_expr (t, asm_stmt, false);
1491 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
1493 t = TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
1494 ret |= build_access_from_expr (t, asm_stmt, true);
1497 break;
1499 default:
1500 break;
1505 return ret;
1508 /* Helper of QSORT function. There are pointers to accesses in the array. An
1509 access is considered smaller than another if it has smaller offset or if the
1510 offsets are the same but is size is bigger. */
1512 static int
1513 compare_access_positions (const void *a, const void *b)
1515 const access_p *fp1 = (const access_p *) a;
1516 const access_p *fp2 = (const access_p *) b;
1517 const access_p f1 = *fp1;
1518 const access_p f2 = *fp2;
1520 if (f1->offset != f2->offset)
1521 return f1->offset < f2->offset ? -1 : 1;
1523 if (f1->size == f2->size)
1525 if (f1->type == f2->type)
1526 return 0;
1527 /* Put any non-aggregate type before any aggregate type. */
1528 else if (!is_gimple_reg_type (f1->type)
1529 && is_gimple_reg_type (f2->type))
1530 return 1;
1531 else if (is_gimple_reg_type (f1->type)
1532 && !is_gimple_reg_type (f2->type))
1533 return -1;
1534 /* Put any complex or vector type before any other scalar type. */
1535 else if (TREE_CODE (f1->type) != COMPLEX_TYPE
1536 && TREE_CODE (f1->type) != VECTOR_TYPE
1537 && (TREE_CODE (f2->type) == COMPLEX_TYPE
1538 || TREE_CODE (f2->type) == VECTOR_TYPE))
1539 return 1;
1540 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
1541 || TREE_CODE (f1->type) == VECTOR_TYPE)
1542 && TREE_CODE (f2->type) != COMPLEX_TYPE
1543 && TREE_CODE (f2->type) != VECTOR_TYPE)
1544 return -1;
1545 /* Put the integral type with the bigger precision first. */
1546 else if (INTEGRAL_TYPE_P (f1->type)
1547 && INTEGRAL_TYPE_P (f2->type))
1548 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
1549 /* Put any integral type with non-full precision last. */
1550 else if (INTEGRAL_TYPE_P (f1->type)
1551 && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type))
1552 != TYPE_PRECISION (f1->type)))
1553 return 1;
1554 else if (INTEGRAL_TYPE_P (f2->type)
1555 && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type))
1556 != TYPE_PRECISION (f2->type)))
1557 return -1;
1558 /* Stabilize the sort. */
1559 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1562 /* We want the bigger accesses first, thus the opposite operator in the next
1563 line: */
1564 return f1->size > f2->size ? -1 : 1;
1568 /* Append a name of the declaration to the name obstack. A helper function for
1569 make_fancy_name. */
1571 static void
1572 make_fancy_decl_name (tree decl)
1574 char buffer[32];
1576 tree name = DECL_NAME (decl);
1577 if (name)
1578 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1579 IDENTIFIER_LENGTH (name));
1580 else
1582 sprintf (buffer, "D%u", DECL_UID (decl));
1583 obstack_grow (&name_obstack, buffer, strlen (buffer));
1587 /* Helper for make_fancy_name. */
1589 static void
1590 make_fancy_name_1 (tree expr)
1592 char buffer[32];
1593 tree index;
1595 if (DECL_P (expr))
1597 make_fancy_decl_name (expr);
1598 return;
1601 switch (TREE_CODE (expr))
1603 case COMPONENT_REF:
1604 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1605 obstack_1grow (&name_obstack, '$');
1606 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1607 break;
1609 case ARRAY_REF:
1610 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1611 obstack_1grow (&name_obstack, '$');
1612 /* Arrays with only one element may not have a constant as their
1613 index. */
1614 index = TREE_OPERAND (expr, 1);
1615 if (TREE_CODE (index) != INTEGER_CST)
1616 break;
1617 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1618 obstack_grow (&name_obstack, buffer, strlen (buffer));
1619 break;
1621 case ADDR_EXPR:
1622 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1623 break;
1625 case MEM_REF:
1626 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1627 if (!integer_zerop (TREE_OPERAND (expr, 1)))
1629 obstack_1grow (&name_obstack, '$');
1630 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC,
1631 TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)));
1632 obstack_grow (&name_obstack, buffer, strlen (buffer));
1634 break;
1636 case BIT_FIELD_REF:
1637 case REALPART_EXPR:
1638 case IMAGPART_EXPR:
1639 gcc_unreachable (); /* we treat these as scalars. */
1640 break;
1641 default:
1642 break;
1646 /* Create a human readable name for replacement variable of ACCESS. */
1648 static char *
1649 make_fancy_name (tree expr)
1651 make_fancy_name_1 (expr);
1652 obstack_1grow (&name_obstack, '\0');
1653 return XOBFINISH (&name_obstack, char *);
1656 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1657 EXP_TYPE at the given OFFSET and with storage order REVERSE. If BASE is
1658 something for which get_addr_base_and_unit_offset returns NULL, gsi must
1659 be non-NULL and is used to insert new statements either before or below
1660 the current one as specified by INSERT_AFTER. This function is not capable
1661 of handling bitfields. */
1663 tree
1664 build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
1665 bool reverse, tree exp_type, gimple_stmt_iterator *gsi,
1666 bool insert_after)
1668 tree prev_base = base;
1669 tree off;
1670 tree mem_ref;
1671 HOST_WIDE_INT base_offset;
1672 unsigned HOST_WIDE_INT misalign;
1673 unsigned int align;
1675 /* Preserve address-space information. */
1676 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (base));
1677 if (as != TYPE_ADDR_SPACE (exp_type))
1678 exp_type = build_qualified_type (exp_type,
1679 TYPE_QUALS (exp_type)
1680 | ENCODE_QUAL_ADDR_SPACE (as));
1682 gcc_checking_assert (offset % BITS_PER_UNIT == 0);
1683 get_object_alignment_1 (base, &align, &misalign);
1684 base = get_addr_base_and_unit_offset (base, &base_offset);
1686 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1687 offset such as array[var_index]. */
1688 if (!base)
1690 gassign *stmt;
1691 tree tmp, addr;
1693 gcc_checking_assert (gsi);
1694 tmp = make_ssa_name (build_pointer_type (TREE_TYPE (prev_base)));
1695 addr = build_fold_addr_expr (unshare_expr (prev_base));
1696 STRIP_USELESS_TYPE_CONVERSION (addr);
1697 stmt = gimple_build_assign (tmp, addr);
1698 gimple_set_location (stmt, loc);
1699 if (insert_after)
1700 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
1701 else
1702 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1704 off = build_int_cst (reference_alias_ptr_type (prev_base),
1705 offset / BITS_PER_UNIT);
1706 base = tmp;
1708 else if (TREE_CODE (base) == MEM_REF)
1710 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1711 base_offset + offset / BITS_PER_UNIT);
1712 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1713 base = unshare_expr (TREE_OPERAND (base, 0));
1715 else
1717 off = build_int_cst (reference_alias_ptr_type (prev_base),
1718 base_offset + offset / BITS_PER_UNIT);
1719 base = build_fold_addr_expr (unshare_expr (base));
1722 misalign = (misalign + offset) & (align - 1);
1723 if (misalign != 0)
1724 align = least_bit_hwi (misalign);
1725 if (align != TYPE_ALIGN (exp_type))
1726 exp_type = build_aligned_type (exp_type, align);
1728 mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off);
1729 REF_REVERSE_STORAGE_ORDER (mem_ref) = reverse;
1730 if (TREE_THIS_VOLATILE (prev_base))
1731 TREE_THIS_VOLATILE (mem_ref) = 1;
1732 if (TREE_SIDE_EFFECTS (prev_base))
1733 TREE_SIDE_EFFECTS (mem_ref) = 1;
1734 return mem_ref;
1737 /* Construct a memory reference to a part of an aggregate BASE at the given
1738 OFFSET and of the same type as MODEL. In case this is a reference to a
1739 bit-field, the function will replicate the last component_ref of model's
1740 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1741 build_ref_for_offset. */
1743 static tree
1744 build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1745 struct access *model, gimple_stmt_iterator *gsi,
1746 bool insert_after)
1748 if (TREE_CODE (model->expr) == COMPONENT_REF
1749 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1751 /* This access represents a bit-field. */
1752 tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
1754 offset -= int_bit_position (fld);
1755 exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
1756 t = build_ref_for_offset (loc, base, offset, model->reverse, exp_type,
1757 gsi, insert_after);
1758 /* The flag will be set on the record type. */
1759 REF_REVERSE_STORAGE_ORDER (t) = 0;
1760 return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
1761 NULL_TREE);
1763 else
1764 return
1765 build_ref_for_offset (loc, base, offset, model->reverse, model->type,
1766 gsi, insert_after);
1769 /* Attempt to build a memory reference that we could but into a gimple
1770 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1771 create statements and return s NULL instead. This function also ignores
1772 alignment issues and so its results should never end up in non-debug
1773 statements. */
1775 static tree
1776 build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1777 struct access *model)
1779 HOST_WIDE_INT base_offset;
1780 tree off;
1782 if (TREE_CODE (model->expr) == COMPONENT_REF
1783 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1784 return NULL_TREE;
1786 base = get_addr_base_and_unit_offset (base, &base_offset);
1787 if (!base)
1788 return NULL_TREE;
1789 if (TREE_CODE (base) == MEM_REF)
1791 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1792 base_offset + offset / BITS_PER_UNIT);
1793 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1794 base = unshare_expr (TREE_OPERAND (base, 0));
1796 else
1798 off = build_int_cst (reference_alias_ptr_type (base),
1799 base_offset + offset / BITS_PER_UNIT);
1800 base = build_fold_addr_expr (unshare_expr (base));
1803 return fold_build2_loc (loc, MEM_REF, model->type, base, off);
1806 /* Construct a memory reference consisting of component_refs and array_refs to
1807 a part of an aggregate *RES (which is of type TYPE). The requested part
1808 should have type EXP_TYPE at be the given OFFSET. This function might not
1809 succeed, it returns true when it does and only then *RES points to something
1810 meaningful. This function should be used only to build expressions that we
1811 might need to present to user (e.g. in warnings). In all other situations,
1812 build_ref_for_model or build_ref_for_offset should be used instead. */
1814 static bool
1815 build_user_friendly_ref_for_offset (tree *res, tree type, HOST_WIDE_INT offset,
1816 tree exp_type)
1818 while (1)
1820 tree fld;
1821 tree tr_size, index, minidx;
1822 HOST_WIDE_INT el_size;
1824 if (offset == 0 && exp_type
1825 && types_compatible_p (exp_type, type))
1826 return true;
1828 switch (TREE_CODE (type))
1830 case UNION_TYPE:
1831 case QUAL_UNION_TYPE:
1832 case RECORD_TYPE:
1833 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
1835 HOST_WIDE_INT pos, size;
1836 tree tr_pos, expr, *expr_ptr;
1838 if (TREE_CODE (fld) != FIELD_DECL)
1839 continue;
1841 tr_pos = bit_position (fld);
1842 if (!tr_pos || !tree_fits_uhwi_p (tr_pos))
1843 continue;
1844 pos = tree_to_uhwi (tr_pos);
1845 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1846 tr_size = DECL_SIZE (fld);
1847 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1848 continue;
1849 size = tree_to_uhwi (tr_size);
1850 if (size == 0)
1852 if (pos != offset)
1853 continue;
1855 else if (pos > offset || (pos + size) <= offset)
1856 continue;
1858 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1859 NULL_TREE);
1860 expr_ptr = &expr;
1861 if (build_user_friendly_ref_for_offset (expr_ptr, TREE_TYPE (fld),
1862 offset - pos, exp_type))
1864 *res = expr;
1865 return true;
1868 return false;
1870 case ARRAY_TYPE:
1871 tr_size = TYPE_SIZE (TREE_TYPE (type));
1872 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1873 return false;
1874 el_size = tree_to_uhwi (tr_size);
1876 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1877 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
1878 return false;
1879 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1880 if (!integer_zerop (minidx))
1881 index = int_const_binop (PLUS_EXPR, index, minidx);
1882 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1883 NULL_TREE, NULL_TREE);
1884 offset = offset % el_size;
1885 type = TREE_TYPE (type);
1886 break;
1888 default:
1889 if (offset != 0)
1890 return false;
1892 if (exp_type)
1893 return false;
1894 else
1895 return true;
1900 /* Return true iff TYPE is stdarg va_list type. */
1902 static inline bool
1903 is_va_list_type (tree type)
1905 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1908 /* Print message to dump file why a variable was rejected. */
1910 static void
1911 reject (tree var, const char *msg)
1913 if (dump_file && (dump_flags & TDF_DETAILS))
1915 fprintf (dump_file, "Rejected (%d): %s: ", DECL_UID (var), msg);
1916 print_generic_expr (dump_file, var, 0);
1917 fprintf (dump_file, "\n");
1921 /* Return true if VAR is a candidate for SRA. */
1923 static bool
1924 maybe_add_sra_candidate (tree var)
1926 tree type = TREE_TYPE (var);
1927 const char *msg;
1928 tree_node **slot;
1930 if (!AGGREGATE_TYPE_P (type))
1932 reject (var, "not aggregate");
1933 return false;
1935 /* Allow constant-pool entries (that "need to live in memory")
1936 unless we are doing IPA SRA. */
1937 if (needs_to_live_in_memory (var)
1938 && (sra_mode == SRA_MODE_EARLY_IPA || !constant_decl_p (var)))
1940 reject (var, "needs to live in memory");
1941 return false;
1943 if (TREE_THIS_VOLATILE (var))
1945 reject (var, "is volatile");
1946 return false;
1948 if (!COMPLETE_TYPE_P (type))
1950 reject (var, "has incomplete type");
1951 return false;
1953 if (!tree_fits_uhwi_p (TYPE_SIZE (type)))
1955 reject (var, "type size not fixed");
1956 return false;
1958 if (tree_to_uhwi (TYPE_SIZE (type)) == 0)
1960 reject (var, "type size is zero");
1961 return false;
1963 if (type_internals_preclude_sra_p (type, &msg))
1965 reject (var, msg);
1966 return false;
1968 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1969 we also want to schedule it rather late. Thus we ignore it in
1970 the early pass. */
1971 (sra_mode == SRA_MODE_EARLY_INTRA
1972 && is_va_list_type (type)))
1974 reject (var, "is va_list");
1975 return false;
1978 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
1979 slot = candidates->find_slot_with_hash (var, DECL_UID (var), INSERT);
1980 *slot = var;
1982 if (dump_file && (dump_flags & TDF_DETAILS))
1984 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
1985 print_generic_expr (dump_file, var, 0);
1986 fprintf (dump_file, "\n");
1989 return true;
1992 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1993 those with type which is suitable for scalarization. */
1995 static bool
1996 find_var_candidates (void)
1998 tree var, parm;
1999 unsigned int i;
2000 bool ret = false;
2002 for (parm = DECL_ARGUMENTS (current_function_decl);
2003 parm;
2004 parm = DECL_CHAIN (parm))
2005 ret |= maybe_add_sra_candidate (parm);
2007 FOR_EACH_LOCAL_DECL (cfun, i, var)
2009 if (!VAR_P (var))
2010 continue;
2012 ret |= maybe_add_sra_candidate (var);
2015 return ret;
2018 /* Sort all accesses for the given variable, check for partial overlaps and
2019 return NULL if there are any. If there are none, pick a representative for
2020 each combination of offset and size and create a linked list out of them.
2021 Return the pointer to the first representative and make sure it is the first
2022 one in the vector of accesses. */
2024 static struct access *
2025 sort_and_splice_var_accesses (tree var)
2027 int i, j, access_count;
2028 struct access *res, **prev_acc_ptr = &res;
2029 vec<access_p> *access_vec;
2030 bool first = true;
2031 HOST_WIDE_INT low = -1, high = 0;
2033 access_vec = get_base_access_vector (var);
2034 if (!access_vec)
2035 return NULL;
2036 access_count = access_vec->length ();
2038 /* Sort by <OFFSET, SIZE>. */
2039 access_vec->qsort (compare_access_positions);
2041 i = 0;
2042 while (i < access_count)
2044 struct access *access = (*access_vec)[i];
2045 bool grp_write = access->write;
2046 bool grp_read = !access->write;
2047 bool grp_scalar_write = access->write
2048 && is_gimple_reg_type (access->type);
2049 bool grp_scalar_read = !access->write
2050 && is_gimple_reg_type (access->type);
2051 bool grp_assignment_read = access->grp_assignment_read;
2052 bool grp_assignment_write = access->grp_assignment_write;
2053 bool multiple_scalar_reads = false;
2054 bool total_scalarization = access->grp_total_scalarization;
2055 bool grp_partial_lhs = access->grp_partial_lhs;
2056 bool first_scalar = is_gimple_reg_type (access->type);
2057 bool unscalarizable_region = access->grp_unscalarizable_region;
2059 if (first || access->offset >= high)
2061 first = false;
2062 low = access->offset;
2063 high = access->offset + access->size;
2065 else if (access->offset > low && access->offset + access->size > high)
2066 return NULL;
2067 else
2068 gcc_assert (access->offset >= low
2069 && access->offset + access->size <= high);
2071 j = i + 1;
2072 while (j < access_count)
2074 struct access *ac2 = (*access_vec)[j];
2075 if (ac2->offset != access->offset || ac2->size != access->size)
2076 break;
2077 if (ac2->write)
2079 grp_write = true;
2080 grp_scalar_write = (grp_scalar_write
2081 || is_gimple_reg_type (ac2->type));
2083 else
2085 grp_read = true;
2086 if (is_gimple_reg_type (ac2->type))
2088 if (grp_scalar_read)
2089 multiple_scalar_reads = true;
2090 else
2091 grp_scalar_read = true;
2094 grp_assignment_read |= ac2->grp_assignment_read;
2095 grp_assignment_write |= ac2->grp_assignment_write;
2096 grp_partial_lhs |= ac2->grp_partial_lhs;
2097 unscalarizable_region |= ac2->grp_unscalarizable_region;
2098 total_scalarization |= ac2->grp_total_scalarization;
2099 relink_to_new_repr (access, ac2);
2101 /* If there are both aggregate-type and scalar-type accesses with
2102 this combination of size and offset, the comparison function
2103 should have put the scalars first. */
2104 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
2105 ac2->group_representative = access;
2106 j++;
2109 i = j;
2111 access->group_representative = access;
2112 access->grp_write = grp_write;
2113 access->grp_read = grp_read;
2114 access->grp_scalar_read = grp_scalar_read;
2115 access->grp_scalar_write = grp_scalar_write;
2116 access->grp_assignment_read = grp_assignment_read;
2117 access->grp_assignment_write = grp_assignment_write;
2118 access->grp_hint = total_scalarization
2119 || (multiple_scalar_reads && !constant_decl_p (var));
2120 access->grp_total_scalarization = total_scalarization;
2121 access->grp_partial_lhs = grp_partial_lhs;
2122 access->grp_unscalarizable_region = unscalarizable_region;
2123 if (access->first_link)
2124 add_access_to_work_queue (access);
2126 *prev_acc_ptr = access;
2127 prev_acc_ptr = &access->next_grp;
2130 gcc_assert (res == (*access_vec)[0]);
2131 return res;
2134 /* Create a variable for the given ACCESS which determines the type, name and a
2135 few other properties. Return the variable declaration and store it also to
2136 ACCESS->replacement. */
2138 static tree
2139 create_access_replacement (struct access *access)
2141 tree repl;
2143 if (access->grp_to_be_debug_replaced)
2145 repl = create_tmp_var_raw (access->type);
2146 DECL_CONTEXT (repl) = current_function_decl;
2148 else
2149 /* Drop any special alignment on the type if it's not on the main
2150 variant. This avoids issues with weirdo ABIs like AAPCS. */
2151 repl = create_tmp_var (build_qualified_type
2152 (TYPE_MAIN_VARIANT (access->type),
2153 TYPE_QUALS (access->type)), "SR");
2154 if (TREE_CODE (access->type) == COMPLEX_TYPE
2155 || TREE_CODE (access->type) == VECTOR_TYPE)
2157 if (!access->grp_partial_lhs)
2158 DECL_GIMPLE_REG_P (repl) = 1;
2160 else if (access->grp_partial_lhs
2161 && is_gimple_reg_type (access->type))
2162 TREE_ADDRESSABLE (repl) = 1;
2164 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
2165 DECL_ARTIFICIAL (repl) = 1;
2166 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
2168 if (DECL_NAME (access->base)
2169 && !DECL_IGNORED_P (access->base)
2170 && !DECL_ARTIFICIAL (access->base))
2172 char *pretty_name = make_fancy_name (access->expr);
2173 tree debug_expr = unshare_expr_without_location (access->expr), d;
2174 bool fail = false;
2176 DECL_NAME (repl) = get_identifier (pretty_name);
2177 DECL_NAMELESS (repl) = 1;
2178 obstack_free (&name_obstack, pretty_name);
2180 /* Get rid of any SSA_NAMEs embedded in debug_expr,
2181 as DECL_DEBUG_EXPR isn't considered when looking for still
2182 used SSA_NAMEs and thus they could be freed. All debug info
2183 generation cares is whether something is constant or variable
2184 and that get_ref_base_and_extent works properly on the
2185 expression. It cannot handle accesses at a non-constant offset
2186 though, so just give up in those cases. */
2187 for (d = debug_expr;
2188 !fail && (handled_component_p (d) || TREE_CODE (d) == MEM_REF);
2189 d = TREE_OPERAND (d, 0))
2190 switch (TREE_CODE (d))
2192 case ARRAY_REF:
2193 case ARRAY_RANGE_REF:
2194 if (TREE_OPERAND (d, 1)
2195 && TREE_CODE (TREE_OPERAND (d, 1)) != INTEGER_CST)
2196 fail = true;
2197 if (TREE_OPERAND (d, 3)
2198 && TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST)
2199 fail = true;
2200 /* FALLTHRU */
2201 case COMPONENT_REF:
2202 if (TREE_OPERAND (d, 2)
2203 && TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST)
2204 fail = true;
2205 break;
2206 case MEM_REF:
2207 if (TREE_CODE (TREE_OPERAND (d, 0)) != ADDR_EXPR)
2208 fail = true;
2209 else
2210 d = TREE_OPERAND (d, 0);
2211 break;
2212 default:
2213 break;
2215 if (!fail)
2217 SET_DECL_DEBUG_EXPR (repl, debug_expr);
2218 DECL_HAS_DEBUG_EXPR_P (repl) = 1;
2220 if (access->grp_no_warning)
2221 TREE_NO_WARNING (repl) = 1;
2222 else
2223 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
2225 else
2226 TREE_NO_WARNING (repl) = 1;
2228 if (dump_file)
2230 if (access->grp_to_be_debug_replaced)
2232 fprintf (dump_file, "Created a debug-only replacement for ");
2233 print_generic_expr (dump_file, access->base, 0);
2234 fprintf (dump_file, " offset: %u, size: %u\n",
2235 (unsigned) access->offset, (unsigned) access->size);
2237 else
2239 fprintf (dump_file, "Created a replacement for ");
2240 print_generic_expr (dump_file, access->base, 0);
2241 fprintf (dump_file, " offset: %u, size: %u: ",
2242 (unsigned) access->offset, (unsigned) access->size);
2243 print_generic_expr (dump_file, repl, 0);
2244 fprintf (dump_file, "\n");
2247 sra_stats.replacements++;
2249 return repl;
2252 /* Return ACCESS scalar replacement, which must exist. */
2254 static inline tree
2255 get_access_replacement (struct access *access)
2257 gcc_checking_assert (access->replacement_decl);
2258 return access->replacement_decl;
2262 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2263 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2264 to it is not "within" the root. Return false iff some accesses partially
2265 overlap. */
2267 static bool
2268 build_access_subtree (struct access **access)
2270 struct access *root = *access, *last_child = NULL;
2271 HOST_WIDE_INT limit = root->offset + root->size;
2273 *access = (*access)->next_grp;
2274 while (*access && (*access)->offset + (*access)->size <= limit)
2276 if (!last_child)
2277 root->first_child = *access;
2278 else
2279 last_child->next_sibling = *access;
2280 last_child = *access;
2281 (*access)->parent = root;
2282 (*access)->grp_write |= root->grp_write;
2284 if (!build_access_subtree (access))
2285 return false;
2288 if (*access && (*access)->offset < limit)
2289 return false;
2291 return true;
2294 /* Build a tree of access representatives, ACCESS is the pointer to the first
2295 one, others are linked in a list by the next_grp field. Return false iff
2296 some accesses partially overlap. */
2298 static bool
2299 build_access_trees (struct access *access)
2301 while (access)
2303 struct access *root = access;
2305 if (!build_access_subtree (&access))
2306 return false;
2307 root->next_grp = access;
2309 return true;
2312 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2313 array. */
2315 static bool
2316 expr_with_var_bounded_array_refs_p (tree expr)
2318 while (handled_component_p (expr))
2320 if (TREE_CODE (expr) == ARRAY_REF
2321 && !tree_fits_shwi_p (array_ref_low_bound (expr)))
2322 return true;
2323 expr = TREE_OPERAND (expr, 0);
2325 return false;
2328 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2329 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2330 sorts of access flags appropriately along the way, notably always set
2331 grp_read and grp_assign_read according to MARK_READ and grp_write when
2332 MARK_WRITE is true.
2334 Creating a replacement for a scalar access is considered beneficial if its
2335 grp_hint is set (this means we are either attempting total scalarization or
2336 there is more than one direct read access) or according to the following
2337 table:
2339 Access written to through a scalar type (once or more times)
2341 | Written to in an assignment statement
2343 | | Access read as scalar _once_
2344 | | |
2345 | | | Read in an assignment statement
2346 | | | |
2347 | | | | Scalarize Comment
2348 -----------------------------------------------------------------------------
2349 0 0 0 0 No access for the scalar
2350 0 0 0 1 No access for the scalar
2351 0 0 1 0 No Single read - won't help
2352 0 0 1 1 No The same case
2353 0 1 0 0 No access for the scalar
2354 0 1 0 1 No access for the scalar
2355 0 1 1 0 Yes s = *g; return s.i;
2356 0 1 1 1 Yes The same case as above
2357 1 0 0 0 No Won't help
2358 1 0 0 1 Yes s.i = 1; *g = s;
2359 1 0 1 0 Yes s.i = 5; g = s.i;
2360 1 0 1 1 Yes The same case as above
2361 1 1 0 0 No Won't help.
2362 1 1 0 1 Yes s.i = 1; *g = s;
2363 1 1 1 0 Yes s = *g; return s.i;
2364 1 1 1 1 Yes Any of the above yeses */
2366 static bool
2367 analyze_access_subtree (struct access *root, struct access *parent,
2368 bool allow_replacements)
2370 struct access *child;
2371 HOST_WIDE_INT limit = root->offset + root->size;
2372 HOST_WIDE_INT covered_to = root->offset;
2373 bool scalar = is_gimple_reg_type (root->type);
2374 bool hole = false, sth_created = false;
2376 if (parent)
2378 if (parent->grp_read)
2379 root->grp_read = 1;
2380 if (parent->grp_assignment_read)
2381 root->grp_assignment_read = 1;
2382 if (parent->grp_write)
2383 root->grp_write = 1;
2384 if (parent->grp_assignment_write)
2385 root->grp_assignment_write = 1;
2386 if (parent->grp_total_scalarization)
2387 root->grp_total_scalarization = 1;
2390 if (root->grp_unscalarizable_region)
2391 allow_replacements = false;
2393 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
2394 allow_replacements = false;
2396 for (child = root->first_child; child; child = child->next_sibling)
2398 hole |= covered_to < child->offset;
2399 sth_created |= analyze_access_subtree (child, root,
2400 allow_replacements && !scalar);
2402 root->grp_unscalarized_data |= child->grp_unscalarized_data;
2403 root->grp_total_scalarization &= child->grp_total_scalarization;
2404 if (child->grp_covered)
2405 covered_to += child->size;
2406 else
2407 hole = true;
2410 if (allow_replacements && scalar && !root->first_child
2411 && (root->grp_hint
2412 || ((root->grp_scalar_read || root->grp_assignment_read)
2413 && (root->grp_scalar_write || root->grp_assignment_write))))
2415 /* Always create access replacements that cover the whole access.
2416 For integral types this means the precision has to match.
2417 Avoid assumptions based on the integral type kind, too. */
2418 if (INTEGRAL_TYPE_P (root->type)
2419 && (TREE_CODE (root->type) != INTEGER_TYPE
2420 || TYPE_PRECISION (root->type) != root->size)
2421 /* But leave bitfield accesses alone. */
2422 && (TREE_CODE (root->expr) != COMPONENT_REF
2423 || !DECL_BIT_FIELD (TREE_OPERAND (root->expr, 1))))
2425 tree rt = root->type;
2426 gcc_assert ((root->offset % BITS_PER_UNIT) == 0
2427 && (root->size % BITS_PER_UNIT) == 0);
2428 root->type = build_nonstandard_integer_type (root->size,
2429 TYPE_UNSIGNED (rt));
2430 root->expr = build_ref_for_offset (UNKNOWN_LOCATION, root->base,
2431 root->offset, root->reverse,
2432 root->type, NULL, false);
2434 if (dump_file && (dump_flags & TDF_DETAILS))
2436 fprintf (dump_file, "Changing the type of a replacement for ");
2437 print_generic_expr (dump_file, root->base, 0);
2438 fprintf (dump_file, " offset: %u, size: %u ",
2439 (unsigned) root->offset, (unsigned) root->size);
2440 fprintf (dump_file, " to an integer.\n");
2444 root->grp_to_be_replaced = 1;
2445 root->replacement_decl = create_access_replacement (root);
2446 sth_created = true;
2447 hole = false;
2449 else
2451 if (allow_replacements
2452 && scalar && !root->first_child
2453 && (root->grp_scalar_write || root->grp_assignment_write)
2454 && !bitmap_bit_p (cannot_scalarize_away_bitmap,
2455 DECL_UID (root->base)))
2457 gcc_checking_assert (!root->grp_scalar_read
2458 && !root->grp_assignment_read);
2459 sth_created = true;
2460 if (MAY_HAVE_DEBUG_STMTS)
2462 root->grp_to_be_debug_replaced = 1;
2463 root->replacement_decl = create_access_replacement (root);
2467 if (covered_to < limit)
2468 hole = true;
2469 if (scalar || !allow_replacements)
2470 root->grp_total_scalarization = 0;
2473 if (!hole || root->grp_total_scalarization)
2474 root->grp_covered = 1;
2475 else if (root->grp_write || TREE_CODE (root->base) == PARM_DECL
2476 || constant_decl_p (root->base))
2477 root->grp_unscalarized_data = 1; /* not covered and written to */
2478 return sth_created;
2481 /* Analyze all access trees linked by next_grp by the means of
2482 analyze_access_subtree. */
2483 static bool
2484 analyze_access_trees (struct access *access)
2486 bool ret = false;
2488 while (access)
2490 if (analyze_access_subtree (access, NULL, true))
2491 ret = true;
2492 access = access->next_grp;
2495 return ret;
2498 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2499 SIZE would conflict with an already existing one. If exactly such a child
2500 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2502 static bool
2503 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
2504 HOST_WIDE_INT size, struct access **exact_match)
2506 struct access *child;
2508 for (child = lacc->first_child; child; child = child->next_sibling)
2510 if (child->offset == norm_offset && child->size == size)
2512 *exact_match = child;
2513 return true;
2516 if (child->offset < norm_offset + size
2517 && child->offset + child->size > norm_offset)
2518 return true;
2521 return false;
2524 /* Create a new child access of PARENT, with all properties just like MODEL
2525 except for its offset and with its grp_write false and grp_read true.
2526 Return the new access or NULL if it cannot be created. Note that this
2527 access is created long after all splicing and sorting, it's not located in
2528 any access vector and is automatically a representative of its group. Set
2529 the gpr_write flag of the new accesss if SET_GRP_WRITE is true. */
2531 static struct access *
2532 create_artificial_child_access (struct access *parent, struct access *model,
2533 HOST_WIDE_INT new_offset,
2534 bool set_grp_write)
2536 struct access **child;
2537 tree expr = parent->base;
2539 gcc_assert (!model->grp_unscalarizable_region);
2541 struct access *access = access_pool.allocate ();
2542 memset (access, 0, sizeof (struct access));
2543 if (!build_user_friendly_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
2544 model->type))
2546 access->grp_no_warning = true;
2547 expr = build_ref_for_model (EXPR_LOCATION (parent->base), parent->base,
2548 new_offset, model, NULL, false);
2551 access->base = parent->base;
2552 access->expr = expr;
2553 access->offset = new_offset;
2554 access->size = model->size;
2555 access->type = model->type;
2556 access->grp_write = set_grp_write;
2557 access->grp_read = false;
2558 access->reverse = model->reverse;
2560 child = &parent->first_child;
2561 while (*child && (*child)->offset < new_offset)
2562 child = &(*child)->next_sibling;
2564 access->next_sibling = *child;
2565 *child = access;
2567 return access;
2571 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
2572 true if any new subaccess was created. Additionally, if RACC is a scalar
2573 access but LACC is not, change the type of the latter, if possible. */
2575 static bool
2576 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
2578 struct access *rchild;
2579 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
2580 bool ret = false;
2582 /* IF the LHS is still not marked as being written to, we only need to do so
2583 if the RHS at this level actually was. */
2584 if (!lacc->grp_write &&
2585 (racc->grp_write || TREE_CODE (racc->base) == PARM_DECL))
2587 lacc->grp_write = true;
2588 ret = true;
2591 if (is_gimple_reg_type (lacc->type)
2592 || lacc->grp_unscalarizable_region
2593 || racc->grp_unscalarizable_region)
2595 ret |= !lacc->grp_write;
2596 lacc->grp_write = true;
2597 return ret;
2600 if (is_gimple_reg_type (racc->type))
2602 if (!lacc->first_child && !racc->first_child)
2604 tree t = lacc->base;
2606 lacc->type = racc->type;
2607 if (build_user_friendly_ref_for_offset (&t, TREE_TYPE (t),
2608 lacc->offset, racc->type))
2609 lacc->expr = t;
2610 else
2612 lacc->expr = build_ref_for_model (EXPR_LOCATION (lacc->base),
2613 lacc->base, lacc->offset,
2614 racc, NULL, false);
2615 lacc->grp_no_warning = true;
2618 return ret;
2621 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
2623 struct access *new_acc = NULL;
2624 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
2626 if (rchild->grp_unscalarizable_region)
2628 lacc->grp_write = true;
2629 continue;
2632 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
2633 &new_acc))
2635 if (new_acc)
2637 if (!new_acc->grp_write
2638 && (lacc->grp_write || rchild->grp_write))
2640 new_acc ->grp_write = true;
2641 ret = true;
2644 rchild->grp_hint = 1;
2645 new_acc->grp_hint |= new_acc->grp_read;
2646 if (rchild->first_child)
2647 ret |= propagate_subaccesses_across_link (new_acc, rchild);
2649 else
2650 lacc->grp_write = true;
2651 continue;
2654 rchild->grp_hint = 1;
2655 new_acc = create_artificial_child_access (lacc, rchild, norm_offset,
2656 lacc->grp_write
2657 || rchild->grp_write);
2658 if (new_acc)
2660 ret = true;
2661 if (racc->first_child)
2662 propagate_subaccesses_across_link (new_acc, rchild);
2666 return ret;
2669 /* Propagate all subaccesses across assignment links. */
2671 static void
2672 propagate_all_subaccesses (void)
2674 while (work_queue_head)
2676 struct access *racc = pop_access_from_work_queue ();
2677 struct assign_link *link;
2679 gcc_assert (racc->first_link);
2681 for (link = racc->first_link; link; link = link->next)
2683 struct access *lacc = link->lacc;
2685 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
2686 continue;
2687 lacc = lacc->group_representative;
2688 if (propagate_subaccesses_across_link (lacc, racc))
2691 if (lacc->first_link)
2693 add_access_to_work_queue (lacc);
2694 break;
2696 lacc = lacc->parent;
2698 while (lacc);
2703 /* Go through all accesses collected throughout the (intraprocedural) analysis
2704 stage, exclude overlapping ones, identify representatives and build trees
2705 out of them, making decisions about scalarization on the way. Return true
2706 iff there are any to-be-scalarized variables after this stage. */
2708 static bool
2709 analyze_all_variable_accesses (void)
2711 int res = 0;
2712 bitmap tmp = BITMAP_ALLOC (NULL);
2713 bitmap_iterator bi;
2714 unsigned i;
2715 bool optimize_speed_p = !optimize_function_for_size_p (cfun);
2717 enum compiler_param param = optimize_speed_p
2718 ? PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED
2719 : PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE;
2721 /* If the user didn't set PARAM_SRA_MAX_SCALARIZATION_SIZE_<...>,
2722 fall back to a target default. */
2723 unsigned HOST_WIDE_INT max_scalarization_size
2724 = global_options_set.x_param_values[param]
2725 ? PARAM_VALUE (param)
2726 : get_move_ratio (optimize_speed_p) * UNITS_PER_WORD;
2728 max_scalarization_size *= BITS_PER_UNIT;
2730 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
2731 if (bitmap_bit_p (should_scalarize_away_bitmap, i)
2732 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
2734 tree var = candidate (i);
2736 if (VAR_P (var) && scalarizable_type_p (TREE_TYPE (var),
2737 constant_decl_p (var)))
2739 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var)))
2740 <= max_scalarization_size)
2742 create_total_scalarization_access (var);
2743 completely_scalarize (var, TREE_TYPE (var), 0, var);
2744 statistics_counter_event (cfun,
2745 "Totally-scalarized aggregates", 1);
2746 if (dump_file && (dump_flags & TDF_DETAILS))
2748 fprintf (dump_file, "Will attempt to totally scalarize ");
2749 print_generic_expr (dump_file, var, 0);
2750 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2753 else if (dump_file && (dump_flags & TDF_DETAILS))
2755 fprintf (dump_file, "Too big to totally scalarize: ");
2756 print_generic_expr (dump_file, var, 0);
2757 fprintf (dump_file, " (UID: %u)\n", DECL_UID (var));
2762 bitmap_copy (tmp, candidate_bitmap);
2763 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2765 tree var = candidate (i);
2766 struct access *access;
2768 access = sort_and_splice_var_accesses (var);
2769 if (!access || !build_access_trees (access))
2770 disqualify_candidate (var,
2771 "No or inhibitingly overlapping accesses.");
2774 propagate_all_subaccesses ();
2776 bitmap_copy (tmp, candidate_bitmap);
2777 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2779 tree var = candidate (i);
2780 struct access *access = get_first_repr_for_decl (var);
2782 if (analyze_access_trees (access))
2784 res++;
2785 if (dump_file && (dump_flags & TDF_DETAILS))
2787 fprintf (dump_file, "\nAccess trees for ");
2788 print_generic_expr (dump_file, var, 0);
2789 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2790 dump_access_tree (dump_file, access);
2791 fprintf (dump_file, "\n");
2794 else
2795 disqualify_candidate (var, "No scalar replacements to be created.");
2798 BITMAP_FREE (tmp);
2800 if (res)
2802 statistics_counter_event (cfun, "Scalarized aggregates", res);
2803 return true;
2805 else
2806 return false;
2809 /* Generate statements copying scalar replacements of accesses within a subtree
2810 into or out of AGG. ACCESS, all its children, siblings and their children
2811 are to be processed. AGG is an aggregate type expression (can be a
2812 declaration but does not have to be, it can for example also be a mem_ref or
2813 a series of handled components). TOP_OFFSET is the offset of the processed
2814 subtree which has to be subtracted from offsets of individual accesses to
2815 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2816 replacements in the interval <start_offset, start_offset + chunk_size>,
2817 otherwise copy all. GSI is a statement iterator used to place the new
2818 statements. WRITE should be true when the statements should write from AGG
2819 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2820 statements will be added after the current statement in GSI, they will be
2821 added before the statement otherwise. */
2823 static void
2824 generate_subtree_copies (struct access *access, tree agg,
2825 HOST_WIDE_INT top_offset,
2826 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
2827 gimple_stmt_iterator *gsi, bool write,
2828 bool insert_after, location_t loc)
2830 /* Never write anything into constant pool decls. See PR70602. */
2831 if (!write && constant_decl_p (agg))
2832 return;
2835 if (chunk_size && access->offset >= start_offset + chunk_size)
2836 return;
2838 if (access->grp_to_be_replaced
2839 && (chunk_size == 0
2840 || access->offset + access->size > start_offset))
2842 tree expr, repl = get_access_replacement (access);
2843 gassign *stmt;
2845 expr = build_ref_for_model (loc, agg, access->offset - top_offset,
2846 access, gsi, insert_after);
2848 if (write)
2850 if (access->grp_partial_lhs)
2851 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
2852 !insert_after,
2853 insert_after ? GSI_NEW_STMT
2854 : GSI_SAME_STMT);
2855 stmt = gimple_build_assign (repl, expr);
2857 else
2859 TREE_NO_WARNING (repl) = 1;
2860 if (access->grp_partial_lhs)
2861 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2862 !insert_after,
2863 insert_after ? GSI_NEW_STMT
2864 : GSI_SAME_STMT);
2865 stmt = gimple_build_assign (expr, repl);
2867 gimple_set_location (stmt, loc);
2869 if (insert_after)
2870 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2871 else
2872 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2873 update_stmt (stmt);
2874 sra_stats.subtree_copies++;
2876 else if (write
2877 && access->grp_to_be_debug_replaced
2878 && (chunk_size == 0
2879 || access->offset + access->size > start_offset))
2881 gdebug *ds;
2882 tree drhs = build_debug_ref_for_model (loc, agg,
2883 access->offset - top_offset,
2884 access);
2885 ds = gimple_build_debug_bind (get_access_replacement (access),
2886 drhs, gsi_stmt (*gsi));
2887 if (insert_after)
2888 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2889 else
2890 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2893 if (access->first_child)
2894 generate_subtree_copies (access->first_child, agg, top_offset,
2895 start_offset, chunk_size, gsi,
2896 write, insert_after, loc);
2898 access = access->next_sibling;
2900 while (access);
2903 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2904 root of the subtree to be processed. GSI is the statement iterator used
2905 for inserting statements which are added after the current statement if
2906 INSERT_AFTER is true or before it otherwise. */
2908 static void
2909 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
2910 bool insert_after, location_t loc)
2913 struct access *child;
2915 if (access->grp_to_be_replaced)
2917 gassign *stmt;
2919 stmt = gimple_build_assign (get_access_replacement (access),
2920 build_zero_cst (access->type));
2921 if (insert_after)
2922 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2923 else
2924 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2925 update_stmt (stmt);
2926 gimple_set_location (stmt, loc);
2928 else if (access->grp_to_be_debug_replaced)
2930 gdebug *ds
2931 = gimple_build_debug_bind (get_access_replacement (access),
2932 build_zero_cst (access->type),
2933 gsi_stmt (*gsi));
2934 if (insert_after)
2935 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2936 else
2937 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2940 for (child = access->first_child; child; child = child->next_sibling)
2941 init_subtree_with_zero (child, gsi, insert_after, loc);
2944 /* Clobber all scalar replacements in an access subtree. ACCESS is the
2945 root of the subtree to be processed. GSI is the statement iterator used
2946 for inserting statements which are added after the current statement if
2947 INSERT_AFTER is true or before it otherwise. */
2949 static void
2950 clobber_subtree (struct access *access, gimple_stmt_iterator *gsi,
2951 bool insert_after, location_t loc)
2954 struct access *child;
2956 if (access->grp_to_be_replaced)
2958 tree rep = get_access_replacement (access);
2959 tree clobber = build_constructor (access->type, NULL);
2960 TREE_THIS_VOLATILE (clobber) = 1;
2961 gimple *stmt = gimple_build_assign (rep, clobber);
2963 if (insert_after)
2964 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2965 else
2966 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2967 update_stmt (stmt);
2968 gimple_set_location (stmt, loc);
2971 for (child = access->first_child; child; child = child->next_sibling)
2972 clobber_subtree (child, gsi, insert_after, loc);
2975 /* Search for an access representative for the given expression EXPR and
2976 return it or NULL if it cannot be found. */
2978 static struct access *
2979 get_access_for_expr (tree expr)
2981 HOST_WIDE_INT offset, size, max_size;
2982 tree base;
2983 bool reverse;
2985 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2986 a different size than the size of its argument and we need the latter
2987 one. */
2988 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
2989 expr = TREE_OPERAND (expr, 0);
2991 base = get_ref_base_and_extent (expr, &offset, &size, &max_size, &reverse);
2992 if (max_size == -1 || !DECL_P (base))
2993 return NULL;
2995 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
2996 return NULL;
2998 return get_var_base_offset_size_access (base, offset, max_size);
3001 /* Replace the expression EXPR with a scalar replacement if there is one and
3002 generate other statements to do type conversion or subtree copying if
3003 necessary. GSI is used to place newly created statements, WRITE is true if
3004 the expression is being written to (it is on a LHS of a statement or output
3005 in an assembly statement). */
3007 static bool
3008 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
3010 location_t loc;
3011 struct access *access;
3012 tree type, bfr, orig_expr;
3014 if (TREE_CODE (*expr) == BIT_FIELD_REF)
3016 bfr = *expr;
3017 expr = &TREE_OPERAND (*expr, 0);
3019 else
3020 bfr = NULL_TREE;
3022 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
3023 expr = &TREE_OPERAND (*expr, 0);
3024 access = get_access_for_expr (*expr);
3025 if (!access)
3026 return false;
3027 type = TREE_TYPE (*expr);
3028 orig_expr = *expr;
3030 loc = gimple_location (gsi_stmt (*gsi));
3031 gimple_stmt_iterator alt_gsi = gsi_none ();
3032 if (write && stmt_ends_bb_p (gsi_stmt (*gsi)))
3034 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
3035 gsi = &alt_gsi;
3038 if (access->grp_to_be_replaced)
3040 tree repl = get_access_replacement (access);
3041 /* If we replace a non-register typed access simply use the original
3042 access expression to extract the scalar component afterwards.
3043 This happens if scalarizing a function return value or parameter
3044 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
3045 gcc.c-torture/compile/20011217-1.c.
3047 We also want to use this when accessing a complex or vector which can
3048 be accessed as a different type too, potentially creating a need for
3049 type conversion (see PR42196) and when scalarized unions are involved
3050 in assembler statements (see PR42398). */
3051 if (!useless_type_conversion_p (type, access->type))
3053 tree ref;
3055 ref = build_ref_for_model (loc, orig_expr, 0, access, gsi, false);
3057 if (write)
3059 gassign *stmt;
3061 if (access->grp_partial_lhs)
3062 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
3063 false, GSI_NEW_STMT);
3064 stmt = gimple_build_assign (repl, ref);
3065 gimple_set_location (stmt, loc);
3066 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
3068 else
3070 gassign *stmt;
3072 if (access->grp_partial_lhs)
3073 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
3074 true, GSI_SAME_STMT);
3075 stmt = gimple_build_assign (ref, repl);
3076 gimple_set_location (stmt, loc);
3077 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
3080 else
3081 *expr = repl;
3082 sra_stats.exprs++;
3084 else if (write && access->grp_to_be_debug_replaced)
3086 gdebug *ds = gimple_build_debug_bind (get_access_replacement (access),
3087 NULL_TREE,
3088 gsi_stmt (*gsi));
3089 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
3092 if (access->first_child)
3094 HOST_WIDE_INT start_offset, chunk_size;
3095 if (bfr
3096 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 1))
3097 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 2)))
3099 chunk_size = tree_to_uhwi (TREE_OPERAND (bfr, 1));
3100 start_offset = access->offset
3101 + tree_to_uhwi (TREE_OPERAND (bfr, 2));
3103 else
3104 start_offset = chunk_size = 0;
3106 generate_subtree_copies (access->first_child, orig_expr, access->offset,
3107 start_offset, chunk_size, gsi, write, write,
3108 loc);
3110 return true;
3113 /* Where scalar replacements of the RHS have been written to when a replacement
3114 of a LHS of an assigments cannot be direclty loaded from a replacement of
3115 the RHS. */
3116 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
3117 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
3118 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
3120 struct subreplacement_assignment_data
3122 /* Offset of the access representing the lhs of the assignment. */
3123 HOST_WIDE_INT left_offset;
3125 /* LHS and RHS of the original assignment. */
3126 tree assignment_lhs, assignment_rhs;
3128 /* Access representing the rhs of the whole assignment. */
3129 struct access *top_racc;
3131 /* Stmt iterator used for statement insertions after the original assignment.
3132 It points to the main GSI used to traverse a BB during function body
3133 modification. */
3134 gimple_stmt_iterator *new_gsi;
3136 /* Stmt iterator used for statement insertions before the original
3137 assignment. Keeps on pointing to the original statement. */
3138 gimple_stmt_iterator old_gsi;
3140 /* Location of the assignment. */
3141 location_t loc;
3143 /* Keeps the information whether we have needed to refresh replacements of
3144 the LHS and from which side of the assignments this takes place. */
3145 enum unscalarized_data_handling refreshed;
3148 /* Store all replacements in the access tree rooted in TOP_RACC either to their
3149 base aggregate if there are unscalarized data or directly to LHS of the
3150 statement that is pointed to by GSI otherwise. */
3152 static void
3153 handle_unscalarized_data_in_subtree (struct subreplacement_assignment_data *sad)
3155 tree src;
3156 if (sad->top_racc->grp_unscalarized_data)
3158 src = sad->assignment_rhs;
3159 sad->refreshed = SRA_UDH_RIGHT;
3161 else
3163 src = sad->assignment_lhs;
3164 sad->refreshed = SRA_UDH_LEFT;
3166 generate_subtree_copies (sad->top_racc->first_child, src,
3167 sad->top_racc->offset, 0, 0,
3168 &sad->old_gsi, false, false, sad->loc);
3171 /* Try to generate statements to load all sub-replacements in an access subtree
3172 formed by children of LACC from scalar replacements in the SAD->top_racc
3173 subtree. If that is not possible, refresh the SAD->top_racc base aggregate
3174 and load the accesses from it. */
3176 static void
3177 load_assign_lhs_subreplacements (struct access *lacc,
3178 struct subreplacement_assignment_data *sad)
3180 for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling)
3182 HOST_WIDE_INT offset;
3183 offset = lacc->offset - sad->left_offset + sad->top_racc->offset;
3185 if (lacc->grp_to_be_replaced)
3187 struct access *racc;
3188 gassign *stmt;
3189 tree rhs;
3191 racc = find_access_in_subtree (sad->top_racc, offset, lacc->size);
3192 if (racc && racc->grp_to_be_replaced)
3194 rhs = get_access_replacement (racc);
3195 if (!useless_type_conversion_p (lacc->type, racc->type))
3196 rhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
3197 lacc->type, rhs);
3199 if (racc->grp_partial_lhs && lacc->grp_partial_lhs)
3200 rhs = force_gimple_operand_gsi (&sad->old_gsi, rhs, true,
3201 NULL_TREE, true, GSI_SAME_STMT);
3203 else
3205 /* No suitable access on the right hand side, need to load from
3206 the aggregate. See if we have to update it first... */
3207 if (sad->refreshed == SRA_UDH_NONE)
3208 handle_unscalarized_data_in_subtree (sad);
3210 if (sad->refreshed == SRA_UDH_LEFT)
3211 rhs = build_ref_for_model (sad->loc, sad->assignment_lhs,
3212 lacc->offset - sad->left_offset,
3213 lacc, sad->new_gsi, true);
3214 else
3215 rhs = build_ref_for_model (sad->loc, sad->assignment_rhs,
3216 lacc->offset - sad->left_offset,
3217 lacc, sad->new_gsi, true);
3218 if (lacc->grp_partial_lhs)
3219 rhs = force_gimple_operand_gsi (sad->new_gsi,
3220 rhs, true, NULL_TREE,
3221 false, GSI_NEW_STMT);
3224 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
3225 gsi_insert_after (sad->new_gsi, stmt, GSI_NEW_STMT);
3226 gimple_set_location (stmt, sad->loc);
3227 update_stmt (stmt);
3228 sra_stats.subreplacements++;
3230 else
3232 if (sad->refreshed == SRA_UDH_NONE
3233 && lacc->grp_read && !lacc->grp_covered)
3234 handle_unscalarized_data_in_subtree (sad);
3236 if (lacc && lacc->grp_to_be_debug_replaced)
3238 gdebug *ds;
3239 tree drhs;
3240 struct access *racc = find_access_in_subtree (sad->top_racc,
3241 offset,
3242 lacc->size);
3244 if (racc && racc->grp_to_be_replaced)
3246 if (racc->grp_write || constant_decl_p (racc->base))
3247 drhs = get_access_replacement (racc);
3248 else
3249 drhs = NULL;
3251 else if (sad->refreshed == SRA_UDH_LEFT)
3252 drhs = build_debug_ref_for_model (sad->loc, lacc->base,
3253 lacc->offset, lacc);
3254 else if (sad->refreshed == SRA_UDH_RIGHT)
3255 drhs = build_debug_ref_for_model (sad->loc, sad->top_racc->base,
3256 offset, lacc);
3257 else
3258 drhs = NULL_TREE;
3259 if (drhs
3260 && !useless_type_conversion_p (lacc->type, TREE_TYPE (drhs)))
3261 drhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
3262 lacc->type, drhs);
3263 ds = gimple_build_debug_bind (get_access_replacement (lacc),
3264 drhs, gsi_stmt (sad->old_gsi));
3265 gsi_insert_after (sad->new_gsi, ds, GSI_NEW_STMT);
3269 if (lacc->first_child)
3270 load_assign_lhs_subreplacements (lacc, sad);
3274 /* Result code for SRA assignment modification. */
3275 enum assignment_mod_result { SRA_AM_NONE, /* nothing done for the stmt */
3276 SRA_AM_MODIFIED, /* stmt changed but not
3277 removed */
3278 SRA_AM_REMOVED }; /* stmt eliminated */
3280 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
3281 to the assignment and GSI is the statement iterator pointing at it. Returns
3282 the same values as sra_modify_assign. */
3284 static enum assignment_mod_result
3285 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3287 tree lhs = gimple_assign_lhs (stmt);
3288 struct access *acc = get_access_for_expr (lhs);
3289 if (!acc)
3290 return SRA_AM_NONE;
3291 location_t loc = gimple_location (stmt);
3293 if (gimple_clobber_p (stmt))
3295 /* Clobber the replacement variable. */
3296 clobber_subtree (acc, gsi, !acc->grp_covered, loc);
3297 /* Remove clobbers of fully scalarized variables, they are dead. */
3298 if (acc->grp_covered)
3300 unlink_stmt_vdef (stmt);
3301 gsi_remove (gsi, true);
3302 release_defs (stmt);
3303 return SRA_AM_REMOVED;
3305 else
3306 return SRA_AM_MODIFIED;
3309 if (CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt)) > 0)
3311 /* I have never seen this code path trigger but if it can happen the
3312 following should handle it gracefully. */
3313 if (access_has_children_p (acc))
3314 generate_subtree_copies (acc->first_child, lhs, acc->offset, 0, 0, gsi,
3315 true, true, loc);
3316 return SRA_AM_MODIFIED;
3319 if (acc->grp_covered)
3321 init_subtree_with_zero (acc, gsi, false, loc);
3322 unlink_stmt_vdef (stmt);
3323 gsi_remove (gsi, true);
3324 release_defs (stmt);
3325 return SRA_AM_REMOVED;
3327 else
3329 init_subtree_with_zero (acc, gsi, true, loc);
3330 return SRA_AM_MODIFIED;
3334 /* Create and return a new suitable default definition SSA_NAME for RACC which
3335 is an access describing an uninitialized part of an aggregate that is being
3336 loaded. */
3338 static tree
3339 get_repl_default_def_ssa_name (struct access *racc)
3341 gcc_checking_assert (!racc->grp_to_be_replaced
3342 && !racc->grp_to_be_debug_replaced);
3343 if (!racc->replacement_decl)
3344 racc->replacement_decl = create_access_replacement (racc);
3345 return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
3348 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3349 bit-field field declaration somewhere in it. */
3351 static inline bool
3352 contains_vce_or_bfcref_p (const_tree ref)
3354 while (handled_component_p (ref))
3356 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
3357 || (TREE_CODE (ref) == COMPONENT_REF
3358 && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
3359 return true;
3360 ref = TREE_OPERAND (ref, 0);
3363 return false;
3366 /* Examine both sides of the assignment statement pointed to by STMT, replace
3367 them with a scalare replacement if there is one and generate copying of
3368 replacements if scalarized aggregates have been used in the assignment. GSI
3369 is used to hold generated statements for type conversions and subtree
3370 copying. */
3372 static enum assignment_mod_result
3373 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3375 struct access *lacc, *racc;
3376 tree lhs, rhs;
3377 bool modify_this_stmt = false;
3378 bool force_gimple_rhs = false;
3379 location_t loc;
3380 gimple_stmt_iterator orig_gsi = *gsi;
3382 if (!gimple_assign_single_p (stmt))
3383 return SRA_AM_NONE;
3384 lhs = gimple_assign_lhs (stmt);
3385 rhs = gimple_assign_rhs1 (stmt);
3387 if (TREE_CODE (rhs) == CONSTRUCTOR)
3388 return sra_modify_constructor_assign (stmt, gsi);
3390 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
3391 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
3392 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
3394 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (stmt),
3395 gsi, false);
3396 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (stmt),
3397 gsi, true);
3398 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3401 lacc = get_access_for_expr (lhs);
3402 racc = get_access_for_expr (rhs);
3403 if (!lacc && !racc)
3404 return SRA_AM_NONE;
3405 /* Avoid modifying initializations of constant-pool replacements. */
3406 if (racc && (racc->replacement_decl == lhs))
3407 return SRA_AM_NONE;
3409 loc = gimple_location (stmt);
3410 if (lacc && lacc->grp_to_be_replaced)
3412 lhs = get_access_replacement (lacc);
3413 gimple_assign_set_lhs (stmt, lhs);
3414 modify_this_stmt = true;
3415 if (lacc->grp_partial_lhs)
3416 force_gimple_rhs = true;
3417 sra_stats.exprs++;
3420 if (racc && racc->grp_to_be_replaced)
3422 rhs = get_access_replacement (racc);
3423 modify_this_stmt = true;
3424 if (racc->grp_partial_lhs)
3425 force_gimple_rhs = true;
3426 sra_stats.exprs++;
3428 else if (racc
3429 && !racc->grp_unscalarized_data
3430 && !racc->grp_unscalarizable_region
3431 && TREE_CODE (lhs) == SSA_NAME
3432 && !access_has_replacements_p (racc))
3434 rhs = get_repl_default_def_ssa_name (racc);
3435 modify_this_stmt = true;
3436 sra_stats.exprs++;
3439 if (modify_this_stmt)
3441 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3443 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3444 ??? This should move to fold_stmt which we simply should
3445 call after building a VIEW_CONVERT_EXPR here. */
3446 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
3447 && !contains_bitfld_component_ref_p (lhs))
3449 lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
3450 gimple_assign_set_lhs (stmt, lhs);
3452 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
3453 && !contains_vce_or_bfcref_p (rhs))
3454 rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
3456 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3458 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
3459 rhs);
3460 if (is_gimple_reg_type (TREE_TYPE (lhs))
3461 && TREE_CODE (lhs) != SSA_NAME)
3462 force_gimple_rhs = true;
3467 if (lacc && lacc->grp_to_be_debug_replaced)
3469 tree dlhs = get_access_replacement (lacc);
3470 tree drhs = unshare_expr (rhs);
3471 if (!useless_type_conversion_p (TREE_TYPE (dlhs), TREE_TYPE (drhs)))
3473 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs))
3474 && !contains_vce_or_bfcref_p (drhs))
3475 drhs = build_debug_ref_for_model (loc, drhs, 0, lacc);
3476 if (drhs
3477 && !useless_type_conversion_p (TREE_TYPE (dlhs),
3478 TREE_TYPE (drhs)))
3479 drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
3480 TREE_TYPE (dlhs), drhs);
3482 gdebug *ds = gimple_build_debug_bind (dlhs, drhs, stmt);
3483 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3486 /* From this point on, the function deals with assignments in between
3487 aggregates when at least one has scalar reductions of some of its
3488 components. There are three possible scenarios: Both the LHS and RHS have
3489 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3491 In the first case, we would like to load the LHS components from RHS
3492 components whenever possible. If that is not possible, we would like to
3493 read it directly from the RHS (after updating it by storing in it its own
3494 components). If there are some necessary unscalarized data in the LHS,
3495 those will be loaded by the original assignment too. If neither of these
3496 cases happen, the original statement can be removed. Most of this is done
3497 by load_assign_lhs_subreplacements.
3499 In the second case, we would like to store all RHS scalarized components
3500 directly into LHS and if they cover the aggregate completely, remove the
3501 statement too. In the third case, we want the LHS components to be loaded
3502 directly from the RHS (DSE will remove the original statement if it
3503 becomes redundant).
3505 This is a bit complex but manageable when types match and when unions do
3506 not cause confusion in a way that we cannot really load a component of LHS
3507 from the RHS or vice versa (the access representing this level can have
3508 subaccesses that are accessible only through a different union field at a
3509 higher level - different from the one used in the examined expression).
3510 Unions are fun.
3512 Therefore, I specially handle a fourth case, happening when there is a
3513 specific type cast or it is impossible to locate a scalarized subaccess on
3514 the other side of the expression. If that happens, I simply "refresh" the
3515 RHS by storing in it is scalarized components leave the original statement
3516 there to do the copying and then load the scalar replacements of the LHS.
3517 This is what the first branch does. */
3519 if (modify_this_stmt
3520 || gimple_has_volatile_ops (stmt)
3521 || contains_vce_or_bfcref_p (rhs)
3522 || contains_vce_or_bfcref_p (lhs)
3523 || stmt_ends_bb_p (stmt))
3525 /* No need to copy into a constant-pool, it comes pre-initialized. */
3526 if (access_has_children_p (racc) && !constant_decl_p (racc->base))
3527 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3528 gsi, false, false, loc);
3529 if (access_has_children_p (lacc))
3531 gimple_stmt_iterator alt_gsi = gsi_none ();
3532 if (stmt_ends_bb_p (stmt))
3534 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
3535 gsi = &alt_gsi;
3537 generate_subtree_copies (lacc->first_child, lhs, lacc->offset, 0, 0,
3538 gsi, true, true, loc);
3540 sra_stats.separate_lhs_rhs_handling++;
3542 /* This gimplification must be done after generate_subtree_copies,
3543 lest we insert the subtree copies in the middle of the gimplified
3544 sequence. */
3545 if (force_gimple_rhs)
3546 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
3547 true, GSI_SAME_STMT);
3548 if (gimple_assign_rhs1 (stmt) != rhs)
3550 modify_this_stmt = true;
3551 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
3552 gcc_assert (stmt == gsi_stmt (orig_gsi));
3555 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3557 else
3559 if (access_has_children_p (lacc)
3560 && access_has_children_p (racc)
3561 /* When an access represents an unscalarizable region, it usually
3562 represents accesses with variable offset and thus must not be used
3563 to generate new memory accesses. */
3564 && !lacc->grp_unscalarizable_region
3565 && !racc->grp_unscalarizable_region)
3567 struct subreplacement_assignment_data sad;
3569 sad.left_offset = lacc->offset;
3570 sad.assignment_lhs = lhs;
3571 sad.assignment_rhs = rhs;
3572 sad.top_racc = racc;
3573 sad.old_gsi = *gsi;
3574 sad.new_gsi = gsi;
3575 sad.loc = gimple_location (stmt);
3576 sad.refreshed = SRA_UDH_NONE;
3578 if (lacc->grp_read && !lacc->grp_covered)
3579 handle_unscalarized_data_in_subtree (&sad);
3581 load_assign_lhs_subreplacements (lacc, &sad);
3582 if (sad.refreshed != SRA_UDH_RIGHT)
3584 gsi_next (gsi);
3585 unlink_stmt_vdef (stmt);
3586 gsi_remove (&sad.old_gsi, true);
3587 release_defs (stmt);
3588 sra_stats.deleted++;
3589 return SRA_AM_REMOVED;
3592 else
3594 if (access_has_children_p (racc)
3595 && !racc->grp_unscalarized_data
3596 && TREE_CODE (lhs) != SSA_NAME)
3598 if (dump_file)
3600 fprintf (dump_file, "Removing load: ");
3601 print_gimple_stmt (dump_file, stmt, 0, 0);
3603 generate_subtree_copies (racc->first_child, lhs,
3604 racc->offset, 0, 0, gsi,
3605 false, false, loc);
3606 gcc_assert (stmt == gsi_stmt (*gsi));
3607 unlink_stmt_vdef (stmt);
3608 gsi_remove (gsi, true);
3609 release_defs (stmt);
3610 sra_stats.deleted++;
3611 return SRA_AM_REMOVED;
3613 /* Restore the aggregate RHS from its components so the
3614 prevailing aggregate copy does the right thing. */
3615 if (access_has_children_p (racc))
3616 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3617 gsi, false, false, loc);
3618 /* Re-load the components of the aggregate copy destination.
3619 But use the RHS aggregate to load from to expose more
3620 optimization opportunities. */
3621 if (access_has_children_p (lacc))
3622 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
3623 0, 0, gsi, true, true, loc);
3626 return SRA_AM_NONE;
3630 /* Set any scalar replacements of values in the constant pool to the initial
3631 value of the constant. (Constant-pool decls like *.LC0 have effectively
3632 been initialized before the program starts, we must do the same for their
3633 replacements.) Thus, we output statements like 'SR.1 = *.LC0[0];' into
3634 the function's entry block. */
3636 static void
3637 initialize_constant_pool_replacements (void)
3639 gimple_seq seq = NULL;
3640 gimple_stmt_iterator gsi = gsi_start (seq);
3641 bitmap_iterator bi;
3642 unsigned i;
3644 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
3646 tree var = candidate (i);
3647 if (!constant_decl_p (var))
3648 continue;
3649 vec<access_p> *access_vec = get_base_access_vector (var);
3650 if (!access_vec)
3651 continue;
3652 for (unsigned i = 0; i < access_vec->length (); i++)
3654 struct access *access = (*access_vec)[i];
3655 if (!access->replacement_decl)
3656 continue;
3657 gassign *stmt
3658 = gimple_build_assign (get_access_replacement (access),
3659 unshare_expr (access->expr));
3660 if (dump_file && (dump_flags & TDF_DETAILS))
3662 fprintf (dump_file, "Generating constant initializer: ");
3663 print_gimple_stmt (dump_file, stmt, 0, 1);
3664 fprintf (dump_file, "\n");
3666 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
3667 update_stmt (stmt);
3671 seq = gsi_seq (gsi);
3672 if (seq)
3673 gsi_insert_seq_on_edge_immediate (
3674 single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3677 /* Traverse the function body and all modifications as decided in
3678 analyze_all_variable_accesses. Return true iff the CFG has been
3679 changed. */
3681 static bool
3682 sra_modify_function_body (void)
3684 bool cfg_changed = false;
3685 basic_block bb;
3687 initialize_constant_pool_replacements ();
3689 FOR_EACH_BB_FN (bb, cfun)
3691 gimple_stmt_iterator gsi = gsi_start_bb (bb);
3692 while (!gsi_end_p (gsi))
3694 gimple *stmt = gsi_stmt (gsi);
3695 enum assignment_mod_result assign_result;
3696 bool modified = false, deleted = false;
3697 tree *t;
3698 unsigned i;
3700 switch (gimple_code (stmt))
3702 case GIMPLE_RETURN:
3703 t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
3704 if (*t != NULL_TREE)
3705 modified |= sra_modify_expr (t, &gsi, false);
3706 break;
3708 case GIMPLE_ASSIGN:
3709 assign_result = sra_modify_assign (stmt, &gsi);
3710 modified |= assign_result == SRA_AM_MODIFIED;
3711 deleted = assign_result == SRA_AM_REMOVED;
3712 break;
3714 case GIMPLE_CALL:
3715 /* Operands must be processed before the lhs. */
3716 for (i = 0; i < gimple_call_num_args (stmt); i++)
3718 t = gimple_call_arg_ptr (stmt, i);
3719 modified |= sra_modify_expr (t, &gsi, false);
3722 if (gimple_call_lhs (stmt))
3724 t = gimple_call_lhs_ptr (stmt);
3725 modified |= sra_modify_expr (t, &gsi, true);
3727 break;
3729 case GIMPLE_ASM:
3731 gasm *asm_stmt = as_a <gasm *> (stmt);
3732 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
3734 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
3735 modified |= sra_modify_expr (t, &gsi, false);
3737 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
3739 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
3740 modified |= sra_modify_expr (t, &gsi, true);
3743 break;
3745 default:
3746 break;
3749 if (modified)
3751 update_stmt (stmt);
3752 if (maybe_clean_eh_stmt (stmt)
3753 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
3754 cfg_changed = true;
3756 if (!deleted)
3757 gsi_next (&gsi);
3761 gsi_commit_edge_inserts ();
3762 return cfg_changed;
3765 /* Generate statements initializing scalar replacements of parts of function
3766 parameters. */
3768 static void
3769 initialize_parameter_reductions (void)
3771 gimple_stmt_iterator gsi;
3772 gimple_seq seq = NULL;
3773 tree parm;
3775 gsi = gsi_start (seq);
3776 for (parm = DECL_ARGUMENTS (current_function_decl);
3777 parm;
3778 parm = DECL_CHAIN (parm))
3780 vec<access_p> *access_vec;
3781 struct access *access;
3783 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3784 continue;
3785 access_vec = get_base_access_vector (parm);
3786 if (!access_vec)
3787 continue;
3789 for (access = (*access_vec)[0];
3790 access;
3791 access = access->next_grp)
3792 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true,
3793 EXPR_LOCATION (parm));
3796 seq = gsi_seq (gsi);
3797 if (seq)
3798 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3801 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3802 it reveals there are components of some aggregates to be scalarized, it runs
3803 the required transformations. */
3804 static unsigned int
3805 perform_intra_sra (void)
3807 int ret = 0;
3808 sra_initialize ();
3810 if (!find_var_candidates ())
3811 goto out;
3813 if (!scan_function ())
3814 goto out;
3816 if (!analyze_all_variable_accesses ())
3817 goto out;
3819 if (sra_modify_function_body ())
3820 ret = TODO_update_ssa | TODO_cleanup_cfg;
3821 else
3822 ret = TODO_update_ssa;
3823 initialize_parameter_reductions ();
3825 statistics_counter_event (cfun, "Scalar replacements created",
3826 sra_stats.replacements);
3827 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
3828 statistics_counter_event (cfun, "Subtree copy stmts",
3829 sra_stats.subtree_copies);
3830 statistics_counter_event (cfun, "Subreplacement stmts",
3831 sra_stats.subreplacements);
3832 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
3833 statistics_counter_event (cfun, "Separate LHS and RHS handling",
3834 sra_stats.separate_lhs_rhs_handling);
3836 out:
3837 sra_deinitialize ();
3838 return ret;
3841 /* Perform early intraprocedural SRA. */
3842 static unsigned int
3843 early_intra_sra (void)
3845 sra_mode = SRA_MODE_EARLY_INTRA;
3846 return perform_intra_sra ();
3849 /* Perform "late" intraprocedural SRA. */
3850 static unsigned int
3851 late_intra_sra (void)
3853 sra_mode = SRA_MODE_INTRA;
3854 return perform_intra_sra ();
3858 static bool
3859 gate_intra_sra (void)
3861 return flag_tree_sra != 0 && dbg_cnt (tree_sra);
3865 namespace {
3867 const pass_data pass_data_sra_early =
3869 GIMPLE_PASS, /* type */
3870 "esra", /* name */
3871 OPTGROUP_NONE, /* optinfo_flags */
3872 TV_TREE_SRA, /* tv_id */
3873 ( PROP_cfg | PROP_ssa ), /* properties_required */
3874 0, /* properties_provided */
3875 0, /* properties_destroyed */
3876 0, /* todo_flags_start */
3877 TODO_update_ssa, /* todo_flags_finish */
3880 class pass_sra_early : public gimple_opt_pass
3882 public:
3883 pass_sra_early (gcc::context *ctxt)
3884 : gimple_opt_pass (pass_data_sra_early, ctxt)
3887 /* opt_pass methods: */
3888 virtual bool gate (function *) { return gate_intra_sra (); }
3889 virtual unsigned int execute (function *) { return early_intra_sra (); }
3891 }; // class pass_sra_early
3893 } // anon namespace
3895 gimple_opt_pass *
3896 make_pass_sra_early (gcc::context *ctxt)
3898 return new pass_sra_early (ctxt);
3901 namespace {
3903 const pass_data pass_data_sra =
3905 GIMPLE_PASS, /* type */
3906 "sra", /* name */
3907 OPTGROUP_NONE, /* optinfo_flags */
3908 TV_TREE_SRA, /* tv_id */
3909 ( PROP_cfg | PROP_ssa ), /* properties_required */
3910 0, /* properties_provided */
3911 0, /* properties_destroyed */
3912 TODO_update_address_taken, /* todo_flags_start */
3913 TODO_update_ssa, /* todo_flags_finish */
3916 class pass_sra : public gimple_opt_pass
3918 public:
3919 pass_sra (gcc::context *ctxt)
3920 : gimple_opt_pass (pass_data_sra, ctxt)
3923 /* opt_pass methods: */
3924 virtual bool gate (function *) { return gate_intra_sra (); }
3925 virtual unsigned int execute (function *) { return late_intra_sra (); }
3927 }; // class pass_sra
3929 } // anon namespace
3931 gimple_opt_pass *
3932 make_pass_sra (gcc::context *ctxt)
3934 return new pass_sra (ctxt);
3938 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3939 parameter. */
3941 static bool
3942 is_unused_scalar_param (tree parm)
3944 tree name;
3945 return (is_gimple_reg (parm)
3946 && (!(name = ssa_default_def (cfun, parm))
3947 || has_zero_uses (name)));
3950 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3951 examine whether there are any direct or otherwise infeasible ones. If so,
3952 return true, otherwise return false. PARM must be a gimple register with a
3953 non-NULL default definition. */
3955 static bool
3956 ptr_parm_has_direct_uses (tree parm)
3958 imm_use_iterator ui;
3959 gimple *stmt;
3960 tree name = ssa_default_def (cfun, parm);
3961 bool ret = false;
3963 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
3965 int uses_ok = 0;
3966 use_operand_p use_p;
3968 if (is_gimple_debug (stmt))
3969 continue;
3971 /* Valid uses include dereferences on the lhs and the rhs. */
3972 if (gimple_has_lhs (stmt))
3974 tree lhs = gimple_get_lhs (stmt);
3975 while (handled_component_p (lhs))
3976 lhs = TREE_OPERAND (lhs, 0);
3977 if (TREE_CODE (lhs) == MEM_REF
3978 && TREE_OPERAND (lhs, 0) == name
3979 && integer_zerop (TREE_OPERAND (lhs, 1))
3980 && types_compatible_p (TREE_TYPE (lhs),
3981 TREE_TYPE (TREE_TYPE (name)))
3982 && !TREE_THIS_VOLATILE (lhs))
3983 uses_ok++;
3985 if (gimple_assign_single_p (stmt))
3987 tree rhs = gimple_assign_rhs1 (stmt);
3988 while (handled_component_p (rhs))
3989 rhs = TREE_OPERAND (rhs, 0);
3990 if (TREE_CODE (rhs) == MEM_REF
3991 && TREE_OPERAND (rhs, 0) == name
3992 && integer_zerop (TREE_OPERAND (rhs, 1))
3993 && types_compatible_p (TREE_TYPE (rhs),
3994 TREE_TYPE (TREE_TYPE (name)))
3995 && !TREE_THIS_VOLATILE (rhs))
3996 uses_ok++;
3998 else if (is_gimple_call (stmt))
4000 unsigned i;
4001 for (i = 0; i < gimple_call_num_args (stmt); ++i)
4003 tree arg = gimple_call_arg (stmt, i);
4004 while (handled_component_p (arg))
4005 arg = TREE_OPERAND (arg, 0);
4006 if (TREE_CODE (arg) == MEM_REF
4007 && TREE_OPERAND (arg, 0) == name
4008 && integer_zerop (TREE_OPERAND (arg, 1))
4009 && types_compatible_p (TREE_TYPE (arg),
4010 TREE_TYPE (TREE_TYPE (name)))
4011 && !TREE_THIS_VOLATILE (arg))
4012 uses_ok++;
4016 /* If the number of valid uses does not match the number of
4017 uses in this stmt there is an unhandled use. */
4018 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
4019 --uses_ok;
4021 if (uses_ok != 0)
4022 ret = true;
4024 if (ret)
4025 BREAK_FROM_IMM_USE_STMT (ui);
4028 return ret;
4031 /* Identify candidates for reduction for IPA-SRA based on their type and mark
4032 them in candidate_bitmap. Note that these do not necessarily include
4033 parameter which are unused and thus can be removed. Return true iff any
4034 such candidate has been found. */
4036 static bool
4037 find_param_candidates (void)
4039 tree parm;
4040 int count = 0;
4041 bool ret = false;
4042 const char *msg;
4044 for (parm = DECL_ARGUMENTS (current_function_decl);
4045 parm;
4046 parm = DECL_CHAIN (parm))
4048 tree type = TREE_TYPE (parm);
4049 tree_node **slot;
4051 count++;
4053 if (TREE_THIS_VOLATILE (parm)
4054 || TREE_ADDRESSABLE (parm)
4055 || (!is_gimple_reg_type (type) && is_va_list_type (type)))
4056 continue;
4058 if (is_unused_scalar_param (parm))
4060 ret = true;
4061 continue;
4064 if (POINTER_TYPE_P (type))
4066 type = TREE_TYPE (type);
4068 if (TREE_CODE (type) == FUNCTION_TYPE
4069 || TYPE_VOLATILE (type)
4070 || (TREE_CODE (type) == ARRAY_TYPE
4071 && TYPE_NONALIASED_COMPONENT (type))
4072 || !is_gimple_reg (parm)
4073 || is_va_list_type (type)
4074 || ptr_parm_has_direct_uses (parm))
4075 continue;
4077 else if (!AGGREGATE_TYPE_P (type))
4078 continue;
4080 if (!COMPLETE_TYPE_P (type)
4081 || !tree_fits_uhwi_p (TYPE_SIZE (type))
4082 || tree_to_uhwi (TYPE_SIZE (type)) == 0
4083 || (AGGREGATE_TYPE_P (type)
4084 && type_internals_preclude_sra_p (type, &msg)))
4085 continue;
4087 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
4088 slot = candidates->find_slot_with_hash (parm, DECL_UID (parm), INSERT);
4089 *slot = parm;
4091 ret = true;
4092 if (dump_file && (dump_flags & TDF_DETAILS))
4094 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
4095 print_generic_expr (dump_file, parm, 0);
4096 fprintf (dump_file, "\n");
4100 func_param_count = count;
4101 return ret;
4104 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
4105 maybe_modified. */
4107 static bool
4108 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
4109 void *data)
4111 struct access *repr = (struct access *) data;
4113 repr->grp_maybe_modified = 1;
4114 return true;
4117 /* Analyze what representatives (in linked lists accessible from
4118 REPRESENTATIVES) can be modified by side effects of statements in the
4119 current function. */
4121 static void
4122 analyze_modified_params (vec<access_p> representatives)
4124 int i;
4126 for (i = 0; i < func_param_count; i++)
4128 struct access *repr;
4130 for (repr = representatives[i];
4131 repr;
4132 repr = repr->next_grp)
4134 struct access *access;
4135 bitmap visited;
4136 ao_ref ar;
4138 if (no_accesses_p (repr))
4139 continue;
4140 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
4141 || repr->grp_maybe_modified)
4142 continue;
4144 ao_ref_init (&ar, repr->expr);
4145 visited = BITMAP_ALLOC (NULL);
4146 for (access = repr; access; access = access->next_sibling)
4148 /* All accesses are read ones, otherwise grp_maybe_modified would
4149 be trivially set. */
4150 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
4151 mark_maybe_modified, repr, &visited);
4152 if (repr->grp_maybe_modified)
4153 break;
4155 BITMAP_FREE (visited);
4160 /* Propagate distances in bb_dereferences in the opposite direction than the
4161 control flow edges, in each step storing the maximum of the current value
4162 and the minimum of all successors. These steps are repeated until the table
4163 stabilizes. Note that BBs which might terminate the functions (according to
4164 final_bbs bitmap) never updated in this way. */
4166 static void
4167 propagate_dereference_distances (void)
4169 basic_block bb;
4171 auto_vec<basic_block> queue (last_basic_block_for_fn (cfun));
4172 queue.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun));
4173 FOR_EACH_BB_FN (bb, cfun)
4175 queue.quick_push (bb);
4176 bb->aux = bb;
4179 while (!queue.is_empty ())
4181 edge_iterator ei;
4182 edge e;
4183 bool change = false;
4184 int i;
4186 bb = queue.pop ();
4187 bb->aux = NULL;
4189 if (bitmap_bit_p (final_bbs, bb->index))
4190 continue;
4192 for (i = 0; i < func_param_count; i++)
4194 int idx = bb->index * func_param_count + i;
4195 bool first = true;
4196 HOST_WIDE_INT inh = 0;
4198 FOR_EACH_EDGE (e, ei, bb->succs)
4200 int succ_idx = e->dest->index * func_param_count + i;
4202 if (e->src == EXIT_BLOCK_PTR_FOR_FN (cfun))
4203 continue;
4205 if (first)
4207 first = false;
4208 inh = bb_dereferences [succ_idx];
4210 else if (bb_dereferences [succ_idx] < inh)
4211 inh = bb_dereferences [succ_idx];
4214 if (!first && bb_dereferences[idx] < inh)
4216 bb_dereferences[idx] = inh;
4217 change = true;
4221 if (change && !bitmap_bit_p (final_bbs, bb->index))
4222 FOR_EACH_EDGE (e, ei, bb->preds)
4224 if (e->src->aux)
4225 continue;
4227 e->src->aux = e->src;
4228 queue.quick_push (e->src);
4233 /* Dump a dereferences TABLE with heading STR to file F. */
4235 static void
4236 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
4238 basic_block bb;
4240 fprintf (dump_file, "%s", str);
4241 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
4242 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
4244 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
4245 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
4247 int i;
4248 for (i = 0; i < func_param_count; i++)
4250 int idx = bb->index * func_param_count + i;
4251 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
4254 fprintf (f, "\n");
4256 fprintf (dump_file, "\n");
4259 /* Determine what (parts of) parameters passed by reference that are not
4260 assigned to are not certainly dereferenced in this function and thus the
4261 dereferencing cannot be safely moved to the caller without potentially
4262 introducing a segfault. Mark such REPRESENTATIVES as
4263 grp_not_necessarilly_dereferenced.
4265 The dereferenced maximum "distance," i.e. the offset + size of the accessed
4266 part is calculated rather than simple booleans are calculated for each
4267 pointer parameter to handle cases when only a fraction of the whole
4268 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
4269 an example).
4271 The maximum dereference distances for each pointer parameter and BB are
4272 already stored in bb_dereference. This routine simply propagates these
4273 values upwards by propagate_dereference_distances and then compares the
4274 distances of individual parameters in the ENTRY BB to the equivalent
4275 distances of each representative of a (fraction of a) parameter. */
4277 static void
4278 analyze_caller_dereference_legality (vec<access_p> representatives)
4280 int i;
4282 if (dump_file && (dump_flags & TDF_DETAILS))
4283 dump_dereferences_table (dump_file,
4284 "Dereference table before propagation:\n",
4285 bb_dereferences);
4287 propagate_dereference_distances ();
4289 if (dump_file && (dump_flags & TDF_DETAILS))
4290 dump_dereferences_table (dump_file,
4291 "Dereference table after propagation:\n",
4292 bb_dereferences);
4294 for (i = 0; i < func_param_count; i++)
4296 struct access *repr = representatives[i];
4297 int idx = ENTRY_BLOCK_PTR_FOR_FN (cfun)->index * func_param_count + i;
4299 if (!repr || no_accesses_p (repr))
4300 continue;
4304 if ((repr->offset + repr->size) > bb_dereferences[idx])
4305 repr->grp_not_necessarilly_dereferenced = 1;
4306 repr = repr->next_grp;
4308 while (repr);
4312 /* Return the representative access for the parameter declaration PARM if it is
4313 a scalar passed by reference which is not written to and the pointer value
4314 is not used directly. Thus, if it is legal to dereference it in the caller
4315 and we can rule out modifications through aliases, such parameter should be
4316 turned into one passed by value. Return NULL otherwise. */
4318 static struct access *
4319 unmodified_by_ref_scalar_representative (tree parm)
4321 int i, access_count;
4322 struct access *repr;
4323 vec<access_p> *access_vec;
4325 access_vec = get_base_access_vector (parm);
4326 gcc_assert (access_vec);
4327 repr = (*access_vec)[0];
4328 if (repr->write)
4329 return NULL;
4330 repr->group_representative = repr;
4332 access_count = access_vec->length ();
4333 for (i = 1; i < access_count; i++)
4335 struct access *access = (*access_vec)[i];
4336 if (access->write)
4337 return NULL;
4338 access->group_representative = repr;
4339 access->next_sibling = repr->next_sibling;
4340 repr->next_sibling = access;
4343 repr->grp_read = 1;
4344 repr->grp_scalar_ptr = 1;
4345 return repr;
4348 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
4349 associated with. REQ_ALIGN is the minimum required alignment. */
4351 static bool
4352 access_precludes_ipa_sra_p (struct access *access, unsigned int req_align)
4354 unsigned int exp_align;
4355 /* Avoid issues such as the second simple testcase in PR 42025. The problem
4356 is incompatible assign in a call statement (and possibly even in asm
4357 statements). This can be relaxed by using a new temporary but only for
4358 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
4359 intraprocedural SRA we deal with this by keeping the old aggregate around,
4360 something we cannot do in IPA-SRA.) */
4361 if (access->write
4362 && (is_gimple_call (access->stmt)
4363 || gimple_code (access->stmt) == GIMPLE_ASM))
4364 return true;
4366 exp_align = get_object_alignment (access->expr);
4367 if (exp_align < req_align)
4368 return true;
4370 return false;
4374 /* Sort collected accesses for parameter PARM, identify representatives for
4375 each accessed region and link them together. Return NULL if there are
4376 different but overlapping accesses, return the special ptr value meaning
4377 there are no accesses for this parameter if that is the case and return the
4378 first representative otherwise. Set *RO_GRP if there is a group of accesses
4379 with only read (i.e. no write) accesses. */
4381 static struct access *
4382 splice_param_accesses (tree parm, bool *ro_grp)
4384 int i, j, access_count, group_count;
4385 int agg_size, total_size = 0;
4386 struct access *access, *res, **prev_acc_ptr = &res;
4387 vec<access_p> *access_vec;
4389 access_vec = get_base_access_vector (parm);
4390 if (!access_vec)
4391 return &no_accesses_representant;
4392 access_count = access_vec->length ();
4394 access_vec->qsort (compare_access_positions);
4396 i = 0;
4397 total_size = 0;
4398 group_count = 0;
4399 while (i < access_count)
4401 bool modification;
4402 tree a1_alias_type;
4403 access = (*access_vec)[i];
4404 modification = access->write;
4405 if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type)))
4406 return NULL;
4407 a1_alias_type = reference_alias_ptr_type (access->expr);
4409 /* Access is about to become group representative unless we find some
4410 nasty overlap which would preclude us from breaking this parameter
4411 apart. */
4413 j = i + 1;
4414 while (j < access_count)
4416 struct access *ac2 = (*access_vec)[j];
4417 if (ac2->offset != access->offset)
4419 /* All or nothing law for parameters. */
4420 if (access->offset + access->size > ac2->offset)
4421 return NULL;
4422 else
4423 break;
4425 else if (ac2->size != access->size)
4426 return NULL;
4428 if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type))
4429 || (ac2->type != access->type
4430 && (TREE_ADDRESSABLE (ac2->type)
4431 || TREE_ADDRESSABLE (access->type)))
4432 || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
4433 return NULL;
4435 modification |= ac2->write;
4436 ac2->group_representative = access;
4437 ac2->next_sibling = access->next_sibling;
4438 access->next_sibling = ac2;
4439 j++;
4442 group_count++;
4443 access->grp_maybe_modified = modification;
4444 if (!modification)
4445 *ro_grp = true;
4446 *prev_acc_ptr = access;
4447 prev_acc_ptr = &access->next_grp;
4448 total_size += access->size;
4449 i = j;
4452 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4453 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4454 else
4455 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4456 if (total_size >= agg_size)
4457 return NULL;
4459 gcc_assert (group_count > 0);
4460 return res;
4463 /* Decide whether parameters with representative accesses given by REPR should
4464 be reduced into components. */
4466 static int
4467 decide_one_param_reduction (struct access *repr)
4469 int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
4470 bool by_ref;
4471 tree parm;
4473 parm = repr->base;
4474 cur_parm_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4475 gcc_assert (cur_parm_size > 0);
4477 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4479 by_ref = true;
4480 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4482 else
4484 by_ref = false;
4485 agg_size = cur_parm_size;
4488 if (dump_file)
4490 struct access *acc;
4491 fprintf (dump_file, "Evaluating PARAM group sizes for ");
4492 print_generic_expr (dump_file, parm, 0);
4493 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
4494 for (acc = repr; acc; acc = acc->next_grp)
4495 dump_access (dump_file, acc, true);
4498 total_size = 0;
4499 new_param_count = 0;
4501 for (; repr; repr = repr->next_grp)
4503 gcc_assert (parm == repr->base);
4505 /* Taking the address of a non-addressable field is verboten. */
4506 if (by_ref && repr->non_addressable)
4507 return 0;
4509 /* Do not decompose a non-BLKmode param in a way that would
4510 create BLKmode params. Especially for by-reference passing
4511 (thus, pointer-type param) this is hardly worthwhile. */
4512 if (DECL_MODE (parm) != BLKmode
4513 && TYPE_MODE (repr->type) == BLKmode)
4514 return 0;
4516 if (!by_ref || (!repr->grp_maybe_modified
4517 && !repr->grp_not_necessarilly_dereferenced))
4518 total_size += repr->size;
4519 else
4520 total_size += cur_parm_size;
4522 new_param_count++;
4525 gcc_assert (new_param_count > 0);
4527 if (optimize_function_for_size_p (cfun))
4528 parm_size_limit = cur_parm_size;
4529 else
4530 parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
4531 * cur_parm_size);
4533 if (total_size < agg_size
4534 && total_size <= parm_size_limit)
4536 if (dump_file)
4537 fprintf (dump_file, " ....will be split into %i components\n",
4538 new_param_count);
4539 return new_param_count;
4541 else
4542 return 0;
4545 /* The order of the following enums is important, we need to do extra work for
4546 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4547 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
4548 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
4550 /* Identify representatives of all accesses to all candidate parameters for
4551 IPA-SRA. Return result based on what representatives have been found. */
4553 static enum ipa_splicing_result
4554 splice_all_param_accesses (vec<access_p> &representatives)
4556 enum ipa_splicing_result result = NO_GOOD_ACCESS;
4557 tree parm;
4558 struct access *repr;
4560 representatives.create (func_param_count);
4562 for (parm = DECL_ARGUMENTS (current_function_decl);
4563 parm;
4564 parm = DECL_CHAIN (parm))
4566 if (is_unused_scalar_param (parm))
4568 representatives.quick_push (&no_accesses_representant);
4569 if (result == NO_GOOD_ACCESS)
4570 result = UNUSED_PARAMS;
4572 else if (POINTER_TYPE_P (TREE_TYPE (parm))
4573 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
4574 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4576 repr = unmodified_by_ref_scalar_representative (parm);
4577 representatives.quick_push (repr);
4578 if (repr)
4579 result = UNMODIF_BY_REF_ACCESSES;
4581 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4583 bool ro_grp = false;
4584 repr = splice_param_accesses (parm, &ro_grp);
4585 representatives.quick_push (repr);
4587 if (repr && !no_accesses_p (repr))
4589 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4591 if (ro_grp)
4592 result = UNMODIF_BY_REF_ACCESSES;
4593 else if (result < MODIF_BY_REF_ACCESSES)
4594 result = MODIF_BY_REF_ACCESSES;
4596 else if (result < BY_VAL_ACCESSES)
4597 result = BY_VAL_ACCESSES;
4599 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
4600 result = UNUSED_PARAMS;
4602 else
4603 representatives.quick_push (NULL);
4606 if (result == NO_GOOD_ACCESS)
4608 representatives.release ();
4609 return NO_GOOD_ACCESS;
4612 return result;
4615 /* Return the index of BASE in PARMS. Abort if it is not found. */
4617 static inline int
4618 get_param_index (tree base, vec<tree> parms)
4620 int i, len;
4622 len = parms.length ();
4623 for (i = 0; i < len; i++)
4624 if (parms[i] == base)
4625 return i;
4626 gcc_unreachable ();
4629 /* Convert the decisions made at the representative level into compact
4630 parameter adjustments. REPRESENTATIVES are pointers to first
4631 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4632 final number of adjustments. */
4634 static ipa_parm_adjustment_vec
4635 turn_representatives_into_adjustments (vec<access_p> representatives,
4636 int adjustments_count)
4638 vec<tree> parms;
4639 ipa_parm_adjustment_vec adjustments;
4640 tree parm;
4641 int i;
4643 gcc_assert (adjustments_count > 0);
4644 parms = ipa_get_vector_of_formal_parms (current_function_decl);
4645 adjustments.create (adjustments_count);
4646 parm = DECL_ARGUMENTS (current_function_decl);
4647 for (i = 0; i < func_param_count; i++, parm = DECL_CHAIN (parm))
4649 struct access *repr = representatives[i];
4651 if (!repr || no_accesses_p (repr))
4653 struct ipa_parm_adjustment adj;
4655 memset (&adj, 0, sizeof (adj));
4656 adj.base_index = get_param_index (parm, parms);
4657 adj.base = parm;
4658 if (!repr)
4659 adj.op = IPA_PARM_OP_COPY;
4660 else
4661 adj.op = IPA_PARM_OP_REMOVE;
4662 adj.arg_prefix = "ISRA";
4663 adjustments.quick_push (adj);
4665 else
4667 struct ipa_parm_adjustment adj;
4668 int index = get_param_index (parm, parms);
4670 for (; repr; repr = repr->next_grp)
4672 memset (&adj, 0, sizeof (adj));
4673 gcc_assert (repr->base == parm);
4674 adj.base_index = index;
4675 adj.base = repr->base;
4676 adj.type = repr->type;
4677 adj.alias_ptr_type = reference_alias_ptr_type (repr->expr);
4678 adj.offset = repr->offset;
4679 adj.reverse = repr->reverse;
4680 adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
4681 && (repr->grp_maybe_modified
4682 || repr->grp_not_necessarilly_dereferenced));
4683 adj.arg_prefix = "ISRA";
4684 adjustments.quick_push (adj);
4688 parms.release ();
4689 return adjustments;
4692 /* Analyze the collected accesses and produce a plan what to do with the
4693 parameters in the form of adjustments, NULL meaning nothing. */
4695 static ipa_parm_adjustment_vec
4696 analyze_all_param_acesses (void)
4698 enum ipa_splicing_result repr_state;
4699 bool proceed = false;
4700 int i, adjustments_count = 0;
4701 vec<access_p> representatives;
4702 ipa_parm_adjustment_vec adjustments;
4704 repr_state = splice_all_param_accesses (representatives);
4705 if (repr_state == NO_GOOD_ACCESS)
4706 return ipa_parm_adjustment_vec ();
4708 /* If there are any parameters passed by reference which are not modified
4709 directly, we need to check whether they can be modified indirectly. */
4710 if (repr_state == UNMODIF_BY_REF_ACCESSES)
4712 analyze_caller_dereference_legality (representatives);
4713 analyze_modified_params (representatives);
4716 for (i = 0; i < func_param_count; i++)
4718 struct access *repr = representatives[i];
4720 if (repr && !no_accesses_p (repr))
4722 if (repr->grp_scalar_ptr)
4724 adjustments_count++;
4725 if (repr->grp_not_necessarilly_dereferenced
4726 || repr->grp_maybe_modified)
4727 representatives[i] = NULL;
4728 else
4730 proceed = true;
4731 sra_stats.scalar_by_ref_to_by_val++;
4734 else
4736 int new_components = decide_one_param_reduction (repr);
4738 if (new_components == 0)
4740 representatives[i] = NULL;
4741 adjustments_count++;
4743 else
4745 adjustments_count += new_components;
4746 sra_stats.aggregate_params_reduced++;
4747 sra_stats.param_reductions_created += new_components;
4748 proceed = true;
4752 else
4754 if (no_accesses_p (repr))
4756 proceed = true;
4757 sra_stats.deleted_unused_parameters++;
4759 adjustments_count++;
4763 if (!proceed && dump_file)
4764 fprintf (dump_file, "NOT proceeding to change params.\n");
4766 if (proceed)
4767 adjustments = turn_representatives_into_adjustments (representatives,
4768 adjustments_count);
4769 else
4770 adjustments = ipa_parm_adjustment_vec ();
4772 representatives.release ();
4773 return adjustments;
4776 /* If a parameter replacement identified by ADJ does not yet exist in the form
4777 of declaration, create it and record it, otherwise return the previously
4778 created one. */
4780 static tree
4781 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
4783 tree repl;
4784 if (!adj->new_ssa_base)
4786 char *pretty_name = make_fancy_name (adj->base);
4788 repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR");
4789 DECL_NAME (repl) = get_identifier (pretty_name);
4790 DECL_NAMELESS (repl) = 1;
4791 obstack_free (&name_obstack, pretty_name);
4793 adj->new_ssa_base = repl;
4795 else
4796 repl = adj->new_ssa_base;
4797 return repl;
4800 /* Find the first adjustment for a particular parameter BASE in a vector of
4801 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4802 adjustment. */
4804 static struct ipa_parm_adjustment *
4805 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
4807 int i, len;
4809 len = adjustments.length ();
4810 for (i = 0; i < len; i++)
4812 struct ipa_parm_adjustment *adj;
4814 adj = &adjustments[i];
4815 if (adj->op != IPA_PARM_OP_COPY && adj->base == base)
4816 return adj;
4819 return NULL;
4822 /* If OLD_NAME, which is being defined by statement STMT, is an SSA_NAME of a
4823 parameter which is to be removed because its value is not used, create a new
4824 SSA_NAME relating to a replacement VAR_DECL, replace all uses of the
4825 original with it and return it. If there is no need to re-map, return NULL.
4826 ADJUSTMENTS is a pointer to a vector of IPA-SRA adjustments. */
4828 static tree
4829 replace_removed_params_ssa_names (tree old_name, gimple *stmt,
4830 ipa_parm_adjustment_vec adjustments)
4832 struct ipa_parm_adjustment *adj;
4833 tree decl, repl, new_name;
4835 if (TREE_CODE (old_name) != SSA_NAME)
4836 return NULL;
4838 decl = SSA_NAME_VAR (old_name);
4839 if (decl == NULL_TREE
4840 || TREE_CODE (decl) != PARM_DECL)
4841 return NULL;
4843 adj = get_adjustment_for_base (adjustments, decl);
4844 if (!adj)
4845 return NULL;
4847 repl = get_replaced_param_substitute (adj);
4848 new_name = make_ssa_name (repl, stmt);
4849 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name)
4850 = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name);
4852 if (dump_file)
4854 fprintf (dump_file, "replacing an SSA name of a removed param ");
4855 print_generic_expr (dump_file, old_name, 0);
4856 fprintf (dump_file, " with ");
4857 print_generic_expr (dump_file, new_name, 0);
4858 fprintf (dump_file, "\n");
4861 replace_uses_by (old_name, new_name);
4862 return new_name;
4865 /* If the statement STMT contains any expressions that need to replaced with a
4866 different one as noted by ADJUSTMENTS, do so. Handle any potential type
4867 incompatibilities (GSI is used to accommodate conversion statements and must
4868 point to the statement). Return true iff the statement was modified. */
4870 static bool
4871 sra_ipa_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi,
4872 ipa_parm_adjustment_vec adjustments)
4874 tree *lhs_p, *rhs_p;
4875 bool any;
4877 if (!gimple_assign_single_p (stmt))
4878 return false;
4880 rhs_p = gimple_assign_rhs1_ptr (stmt);
4881 lhs_p = gimple_assign_lhs_ptr (stmt);
4883 any = ipa_modify_expr (rhs_p, false, adjustments);
4884 any |= ipa_modify_expr (lhs_p, false, adjustments);
4885 if (any)
4887 tree new_rhs = NULL_TREE;
4889 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
4891 if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
4893 /* V_C_Es of constructors can cause trouble (PR 42714). */
4894 if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
4895 *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
4896 else
4897 *rhs_p = build_constructor (TREE_TYPE (*lhs_p),
4898 NULL);
4900 else
4901 new_rhs = fold_build1_loc (gimple_location (stmt),
4902 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
4903 *rhs_p);
4905 else if (REFERENCE_CLASS_P (*rhs_p)
4906 && is_gimple_reg_type (TREE_TYPE (*lhs_p))
4907 && !is_gimple_reg (*lhs_p))
4908 /* This can happen when an assignment in between two single field
4909 structures is turned into an assignment in between two pointers to
4910 scalars (PR 42237). */
4911 new_rhs = *rhs_p;
4913 if (new_rhs)
4915 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
4916 true, GSI_SAME_STMT);
4918 gimple_assign_set_rhs_from_tree (gsi, tmp);
4921 return true;
4924 return false;
4927 /* Traverse the function body and all modifications as described in
4928 ADJUSTMENTS. Return true iff the CFG has been changed. */
4930 bool
4931 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
4933 bool cfg_changed = false;
4934 basic_block bb;
4936 FOR_EACH_BB_FN (bb, cfun)
4938 gimple_stmt_iterator gsi;
4940 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4942 gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
4943 tree new_lhs, old_lhs = gimple_phi_result (phi);
4944 new_lhs = replace_removed_params_ssa_names (old_lhs, phi, adjustments);
4945 if (new_lhs)
4947 gimple_phi_set_result (phi, new_lhs);
4948 release_ssa_name (old_lhs);
4952 gsi = gsi_start_bb (bb);
4953 while (!gsi_end_p (gsi))
4955 gimple *stmt = gsi_stmt (gsi);
4956 bool modified = false;
4957 tree *t;
4958 unsigned i;
4960 switch (gimple_code (stmt))
4962 case GIMPLE_RETURN:
4963 t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
4964 if (*t != NULL_TREE)
4965 modified |= ipa_modify_expr (t, true, adjustments);
4966 break;
4968 case GIMPLE_ASSIGN:
4969 modified |= sra_ipa_modify_assign (stmt, &gsi, adjustments);
4970 break;
4972 case GIMPLE_CALL:
4973 /* Operands must be processed before the lhs. */
4974 for (i = 0; i < gimple_call_num_args (stmt); i++)
4976 t = gimple_call_arg_ptr (stmt, i);
4977 modified |= ipa_modify_expr (t, true, adjustments);
4980 if (gimple_call_lhs (stmt))
4982 t = gimple_call_lhs_ptr (stmt);
4983 modified |= ipa_modify_expr (t, false, adjustments);
4985 break;
4987 case GIMPLE_ASM:
4989 gasm *asm_stmt = as_a <gasm *> (stmt);
4990 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
4992 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
4993 modified |= ipa_modify_expr (t, true, adjustments);
4995 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
4997 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
4998 modified |= ipa_modify_expr (t, false, adjustments);
5001 break;
5003 default:
5004 break;
5007 def_operand_p defp;
5008 ssa_op_iter iter;
5009 FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF)
5011 tree old_def = DEF_FROM_PTR (defp);
5012 if (tree new_def = replace_removed_params_ssa_names (old_def, stmt,
5013 adjustments))
5015 SET_DEF (defp, new_def);
5016 release_ssa_name (old_def);
5017 modified = true;
5021 if (modified)
5023 update_stmt (stmt);
5024 if (maybe_clean_eh_stmt (stmt)
5025 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
5026 cfg_changed = true;
5028 gsi_next (&gsi);
5032 return cfg_changed;
5035 /* Call gimple_debug_bind_reset_value on all debug statements describing
5036 gimple register parameters that are being removed or replaced. */
5038 static void
5039 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
5041 int i, len;
5042 gimple_stmt_iterator *gsip = NULL, gsi;
5044 if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
5046 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
5047 gsip = &gsi;
5049 len = adjustments.length ();
5050 for (i = 0; i < len; i++)
5052 struct ipa_parm_adjustment *adj;
5053 imm_use_iterator ui;
5054 gimple *stmt;
5055 gdebug *def_temp;
5056 tree name, vexpr, copy = NULL_TREE;
5057 use_operand_p use_p;
5059 adj = &adjustments[i];
5060 if (adj->op == IPA_PARM_OP_COPY || !is_gimple_reg (adj->base))
5061 continue;
5062 name = ssa_default_def (cfun, adj->base);
5063 vexpr = NULL;
5064 if (name)
5065 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
5067 if (gimple_clobber_p (stmt))
5069 gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
5070 unlink_stmt_vdef (stmt);
5071 gsi_remove (&cgsi, true);
5072 release_defs (stmt);
5073 continue;
5075 /* All other users must have been removed by
5076 ipa_sra_modify_function_body. */
5077 gcc_assert (is_gimple_debug (stmt));
5078 if (vexpr == NULL && gsip != NULL)
5080 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
5081 vexpr = make_node (DEBUG_EXPR_DECL);
5082 def_temp = gimple_build_debug_source_bind (vexpr, adj->base,
5083 NULL);
5084 DECL_ARTIFICIAL (vexpr) = 1;
5085 TREE_TYPE (vexpr) = TREE_TYPE (name);
5086 SET_DECL_MODE (vexpr, DECL_MODE (adj->base));
5087 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
5089 if (vexpr)
5091 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
5092 SET_USE (use_p, vexpr);
5094 else
5095 gimple_debug_bind_reset_value (stmt);
5096 update_stmt (stmt);
5098 /* Create a VAR_DECL for debug info purposes. */
5099 if (!DECL_IGNORED_P (adj->base))
5101 copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
5102 VAR_DECL, DECL_NAME (adj->base),
5103 TREE_TYPE (adj->base));
5104 if (DECL_PT_UID_SET_P (adj->base))
5105 SET_DECL_PT_UID (copy, DECL_PT_UID (adj->base));
5106 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (adj->base);
5107 TREE_READONLY (copy) = TREE_READONLY (adj->base);
5108 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (adj->base);
5109 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (adj->base);
5110 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (adj->base);
5111 DECL_IGNORED_P (copy) = DECL_IGNORED_P (adj->base);
5112 DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (adj->base);
5113 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
5114 SET_DECL_RTL (copy, 0);
5115 TREE_USED (copy) = 1;
5116 DECL_CONTEXT (copy) = current_function_decl;
5117 add_local_decl (cfun, copy);
5118 DECL_CHAIN (copy) =
5119 BLOCK_VARS (DECL_INITIAL (current_function_decl));
5120 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
5122 if (gsip != NULL && copy && target_for_debug_bind (adj->base))
5124 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
5125 if (vexpr)
5126 def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
5127 else
5128 def_temp = gimple_build_debug_source_bind (copy, adj->base,
5129 NULL);
5130 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
5135 /* Return false if all callers have at least as many actual arguments as there
5136 are formal parameters in the current function and that their types
5137 match. */
5139 static bool
5140 some_callers_have_mismatched_arguments_p (struct cgraph_node *node,
5141 void *data ATTRIBUTE_UNUSED)
5143 struct cgraph_edge *cs;
5144 for (cs = node->callers; cs; cs = cs->next_caller)
5145 if (!cs->call_stmt || !callsite_arguments_match_p (cs->call_stmt))
5146 return true;
5148 return false;
5151 /* Return false if all callers have vuse attached to a call statement. */
5153 static bool
5154 some_callers_have_no_vuse_p (struct cgraph_node *node,
5155 void *data ATTRIBUTE_UNUSED)
5157 struct cgraph_edge *cs;
5158 for (cs = node->callers; cs; cs = cs->next_caller)
5159 if (!cs->call_stmt || !gimple_vuse (cs->call_stmt))
5160 return true;
5162 return false;
5165 /* Convert all callers of NODE. */
5167 static bool
5168 convert_callers_for_node (struct cgraph_node *node,
5169 void *data)
5171 ipa_parm_adjustment_vec *adjustments = (ipa_parm_adjustment_vec *) data;
5172 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
5173 struct cgraph_edge *cs;
5175 for (cs = node->callers; cs; cs = cs->next_caller)
5177 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
5179 if (dump_file)
5180 fprintf (dump_file, "Adjusting call %s/%i -> %s/%i\n",
5181 xstrdup_for_dump (cs->caller->name ()),
5182 cs->caller->order,
5183 xstrdup_for_dump (cs->callee->name ()),
5184 cs->callee->order);
5186 ipa_modify_call_arguments (cs, cs->call_stmt, *adjustments);
5188 pop_cfun ();
5191 for (cs = node->callers; cs; cs = cs->next_caller)
5192 if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
5193 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
5194 compute_inline_parameters (cs->caller, true);
5195 BITMAP_FREE (recomputed_callers);
5197 return true;
5200 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
5202 static void
5203 convert_callers (struct cgraph_node *node, tree old_decl,
5204 ipa_parm_adjustment_vec adjustments)
5206 basic_block this_block;
5208 node->call_for_symbol_and_aliases (convert_callers_for_node,
5209 &adjustments, false);
5211 if (!encountered_recursive_call)
5212 return;
5214 FOR_EACH_BB_FN (this_block, cfun)
5216 gimple_stmt_iterator gsi;
5218 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
5220 gcall *stmt;
5221 tree call_fndecl;
5222 stmt = dyn_cast <gcall *> (gsi_stmt (gsi));
5223 if (!stmt)
5224 continue;
5225 call_fndecl = gimple_call_fndecl (stmt);
5226 if (call_fndecl == old_decl)
5228 if (dump_file)
5229 fprintf (dump_file, "Adjusting recursive call");
5230 gimple_call_set_fndecl (stmt, node->decl);
5231 ipa_modify_call_arguments (NULL, stmt, adjustments);
5236 return;
5239 /* Perform all the modification required in IPA-SRA for NODE to have parameters
5240 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
5242 static bool
5243 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
5245 struct cgraph_node *new_node;
5246 bool cfg_changed;
5248 cgraph_edge::rebuild_edges ();
5249 free_dominance_info (CDI_DOMINATORS);
5250 pop_cfun ();
5252 /* This must be done after rebuilding cgraph edges for node above.
5253 Otherwise any recursive calls to node that are recorded in
5254 redirect_callers will be corrupted. */
5255 vec<cgraph_edge *> redirect_callers = node->collect_callers ();
5256 new_node = node->create_version_clone_with_body (redirect_callers, NULL,
5257 NULL, false, NULL, NULL,
5258 "isra");
5259 redirect_callers.release ();
5261 push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
5262 ipa_modify_formal_parameters (current_function_decl, adjustments);
5263 cfg_changed = ipa_sra_modify_function_body (adjustments);
5264 sra_ipa_reset_debug_stmts (adjustments);
5265 convert_callers (new_node, node->decl, adjustments);
5266 new_node->make_local ();
5267 return cfg_changed;
5270 /* Means of communication between ipa_sra_check_caller and
5271 ipa_sra_preliminary_function_checks. */
5273 struct ipa_sra_check_caller_data
5275 bool has_callers;
5276 bool bad_arg_alignment;
5277 bool has_thunk;
5280 /* If NODE has a caller, mark that fact in DATA which is pointer to
5281 ipa_sra_check_caller_data. Also check all aggregate arguments in all known
5282 calls if they are unit aligned and if not, set the appropriate flag in DATA
5283 too. */
5285 static bool
5286 ipa_sra_check_caller (struct cgraph_node *node, void *data)
5288 if (!node->callers)
5289 return false;
5291 struct ipa_sra_check_caller_data *iscc;
5292 iscc = (struct ipa_sra_check_caller_data *) data;
5293 iscc->has_callers = true;
5295 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
5297 if (cs->caller->thunk.thunk_p)
5299 iscc->has_thunk = true;
5300 return true;
5302 gimple *call_stmt = cs->call_stmt;
5303 unsigned count = gimple_call_num_args (call_stmt);
5304 for (unsigned i = 0; i < count; i++)
5306 tree arg = gimple_call_arg (call_stmt, i);
5307 if (is_gimple_reg (arg))
5308 continue;
5310 tree offset;
5311 HOST_WIDE_INT bitsize, bitpos;
5312 machine_mode mode;
5313 int unsignedp, reversep, volatilep = 0;
5314 get_inner_reference (arg, &bitsize, &bitpos, &offset, &mode,
5315 &unsignedp, &reversep, &volatilep);
5316 if (bitpos % BITS_PER_UNIT)
5318 iscc->bad_arg_alignment = true;
5319 return true;
5324 return false;
5327 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
5328 attributes, return true otherwise. NODE is the cgraph node of the current
5329 function. */
5331 static bool
5332 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
5334 if (!node->can_be_local_p ())
5336 if (dump_file)
5337 fprintf (dump_file, "Function not local to this compilation unit.\n");
5338 return false;
5341 if (!node->local.can_change_signature)
5343 if (dump_file)
5344 fprintf (dump_file, "Function can not change signature.\n");
5345 return false;
5348 if (!tree_versionable_function_p (node->decl))
5350 if (dump_file)
5351 fprintf (dump_file, "Function is not versionable.\n");
5352 return false;
5355 if (!opt_for_fn (node->decl, optimize)
5356 || !opt_for_fn (node->decl, flag_ipa_sra))
5358 if (dump_file)
5359 fprintf (dump_file, "Function not optimized.\n");
5360 return false;
5363 if (DECL_VIRTUAL_P (current_function_decl))
5365 if (dump_file)
5366 fprintf (dump_file, "Function is a virtual method.\n");
5367 return false;
5370 if ((DECL_ONE_ONLY (node->decl) || DECL_EXTERNAL (node->decl))
5371 && inline_summaries->get (node)->size >= MAX_INLINE_INSNS_AUTO)
5373 if (dump_file)
5374 fprintf (dump_file, "Function too big to be made truly local.\n");
5375 return false;
5378 if (cfun->stdarg)
5380 if (dump_file)
5381 fprintf (dump_file, "Function uses stdarg. \n");
5382 return false;
5385 if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
5386 return false;
5388 if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
5390 if (dump_file)
5391 fprintf (dump_file, "Always inline function will be inlined "
5392 "anyway. \n");
5393 return false;
5396 struct ipa_sra_check_caller_data iscc;
5397 memset (&iscc, 0, sizeof(iscc));
5398 node->call_for_symbol_and_aliases (ipa_sra_check_caller, &iscc, true);
5399 if (!iscc.has_callers)
5401 if (dump_file)
5402 fprintf (dump_file,
5403 "Function has no callers in this compilation unit.\n");
5404 return false;
5407 if (iscc.bad_arg_alignment)
5409 if (dump_file)
5410 fprintf (dump_file,
5411 "A function call has an argument with non-unit alignment.\n");
5412 return false;
5415 if (iscc.has_thunk)
5417 if (dump_file)
5418 fprintf (dump_file,
5419 "A has thunk.\n");
5420 return false;
5423 return true;
5426 /* Perform early interprocedural SRA. */
5428 static unsigned int
5429 ipa_early_sra (void)
5431 struct cgraph_node *node = cgraph_node::get (current_function_decl);
5432 ipa_parm_adjustment_vec adjustments;
5433 int ret = 0;
5435 if (!ipa_sra_preliminary_function_checks (node))
5436 return 0;
5438 sra_initialize ();
5439 sra_mode = SRA_MODE_EARLY_IPA;
5441 if (!find_param_candidates ())
5443 if (dump_file)
5444 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
5445 goto simple_out;
5448 if (node->call_for_symbol_and_aliases
5449 (some_callers_have_mismatched_arguments_p, NULL, true))
5451 if (dump_file)
5452 fprintf (dump_file, "There are callers with insufficient number of "
5453 "arguments or arguments with type mismatches.\n");
5454 goto simple_out;
5457 if (node->call_for_symbol_and_aliases
5458 (some_callers_have_no_vuse_p, NULL, true))
5460 if (dump_file)
5461 fprintf (dump_file, "There are callers with no VUSE attached "
5462 "to a call stmt.\n");
5463 goto simple_out;
5466 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
5467 func_param_count
5468 * last_basic_block_for_fn (cfun));
5469 final_bbs = BITMAP_ALLOC (NULL);
5471 scan_function ();
5472 if (encountered_apply_args)
5474 if (dump_file)
5475 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
5476 goto out;
5479 if (encountered_unchangable_recursive_call)
5481 if (dump_file)
5482 fprintf (dump_file, "Function calls itself with insufficient "
5483 "number of arguments.\n");
5484 goto out;
5487 adjustments = analyze_all_param_acesses ();
5488 if (!adjustments.exists ())
5489 goto out;
5490 if (dump_file)
5491 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
5493 if (modify_function (node, adjustments))
5494 ret = TODO_update_ssa | TODO_cleanup_cfg;
5495 else
5496 ret = TODO_update_ssa;
5497 adjustments.release ();
5499 statistics_counter_event (cfun, "Unused parameters deleted",
5500 sra_stats.deleted_unused_parameters);
5501 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
5502 sra_stats.scalar_by_ref_to_by_val);
5503 statistics_counter_event (cfun, "Aggregate parameters broken up",
5504 sra_stats.aggregate_params_reduced);
5505 statistics_counter_event (cfun, "Aggregate parameter components created",
5506 sra_stats.param_reductions_created);
5508 out:
5509 BITMAP_FREE (final_bbs);
5510 free (bb_dereferences);
5511 simple_out:
5512 sra_deinitialize ();
5513 return ret;
5516 namespace {
5518 const pass_data pass_data_early_ipa_sra =
5520 GIMPLE_PASS, /* type */
5521 "eipa_sra", /* name */
5522 OPTGROUP_NONE, /* optinfo_flags */
5523 TV_IPA_SRA, /* tv_id */
5524 0, /* properties_required */
5525 0, /* properties_provided */
5526 0, /* properties_destroyed */
5527 0, /* todo_flags_start */
5528 TODO_dump_symtab, /* todo_flags_finish */
5531 class pass_early_ipa_sra : public gimple_opt_pass
5533 public:
5534 pass_early_ipa_sra (gcc::context *ctxt)
5535 : gimple_opt_pass (pass_data_early_ipa_sra, ctxt)
5538 /* opt_pass methods: */
5539 virtual bool gate (function *) { return flag_ipa_sra && dbg_cnt (eipa_sra); }
5540 virtual unsigned int execute (function *) { return ipa_early_sra (); }
5542 }; // class pass_early_ipa_sra
5544 } // anon namespace
5546 gimple_opt_pass *
5547 make_pass_early_ipa_sra (gcc::context *ctxt)
5549 return new pass_early_ipa_sra (ctxt);