* gcc.dg/vect/slp-perm-1.c (main): Make sure loops aren't vectorized.
[official-gcc.git] / gcc / tree-sra.c
blobe4971d2385b7cfc39baee24a578ce553e62928a7
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, 2009, 2010 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 "alloc-pool.h"
78 #include "tm.h"
79 #include "tree.h"
80 #include "gimple.h"
81 #include "cgraph.h"
82 #include "tree-flow.h"
83 #include "ipa-prop.h"
84 #include "tree-pretty-print.h"
85 #include "statistics.h"
86 #include "tree-dump.h"
87 #include "timevar.h"
88 #include "params.h"
89 #include "target.h"
90 #include "flags.h"
91 #include "dbgcnt.h"
92 #include "tree-inline.h"
94 /* Enumeration of all aggregate reductions we can do. */
95 enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
96 SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
97 SRA_MODE_INTRA }; /* late intraprocedural SRA */
99 /* Global variable describing which aggregate reduction we are performing at
100 the moment. */
101 static enum sra_mode sra_mode;
103 struct assign_link;
105 /* ACCESS represents each access to an aggregate variable (as a whole or a
106 part). It can also represent a group of accesses that refer to exactly the
107 same fragment of an aggregate (i.e. those that have exactly the same offset
108 and size). Such representatives for a single aggregate, once determined,
109 are linked in a linked list and have the group fields set.
111 Moreover, when doing intraprocedural SRA, a tree is built from those
112 representatives (by the means of first_child and next_sibling pointers), in
113 which all items in a subtree are "within" the root, i.e. their offset is
114 greater or equal to offset of the root and offset+size is smaller or equal
115 to offset+size of the root. Children of an access are sorted by offset.
117 Note that accesses to parts of vector and complex number types always
118 represented by an access to the whole complex number or a vector. It is a
119 duty of the modifying functions to replace them appropriately. */
121 struct access
123 /* Values returned by `get_ref_base_and_extent' for each component reference
124 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
125 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
126 HOST_WIDE_INT offset;
127 HOST_WIDE_INT size;
128 tree base;
130 /* Expression. It is context dependent so do not use it to create new
131 expressions to access the original aggregate. See PR 42154 for a
132 testcase. */
133 tree expr;
134 /* Type. */
135 tree type;
137 /* The statement this access belongs to. */
138 gimple stmt;
140 /* Next group representative for this aggregate. */
141 struct access *next_grp;
143 /* Pointer to the group representative. Pointer to itself if the struct is
144 the representative. */
145 struct access *group_representative;
147 /* If this access has any children (in terms of the definition above), this
148 points to the first one. */
149 struct access *first_child;
151 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
152 described above. In IPA-SRA this is a pointer to the next access
153 belonging to the same group (having the same representative). */
154 struct access *next_sibling;
156 /* Pointers to the first and last element in the linked list of assign
157 links. */
158 struct assign_link *first_link, *last_link;
160 /* Pointer to the next access in the work queue. */
161 struct access *next_queued;
163 /* Replacement variable for this access "region." Never to be accessed
164 directly, always only by the means of get_access_replacement() and only
165 when grp_to_be_replaced flag is set. */
166 tree replacement_decl;
168 /* Is this particular access write access? */
169 unsigned write : 1;
171 /* Is this access an artificial one created to scalarize some record
172 entirely? */
173 unsigned total_scalarization : 1;
175 /* Is this access currently in the work queue? */
176 unsigned grp_queued : 1;
178 /* Does this group contain a write access? This flag is propagated down the
179 access tree. */
180 unsigned grp_write : 1;
182 /* Does this group contain a read access? This flag is propagated down the
183 access tree. */
184 unsigned grp_read : 1;
186 /* Does this group contain a read access that comes from an assignment
187 statement? This flag is propagated down the access tree. */
188 unsigned grp_assignment_read : 1;
190 /* Other passes of the analysis use this bit to make function
191 analyze_access_subtree create scalar replacements for this group if
192 possible. */
193 unsigned grp_hint : 1;
195 /* Is the subtree rooted in this access fully covered by scalar
196 replacements? */
197 unsigned grp_covered : 1;
199 /* If set to true, this access and all below it in an access tree must not be
200 scalarized. */
201 unsigned grp_unscalarizable_region : 1;
203 /* Whether data have been written to parts of the aggregate covered by this
204 access which is not to be scalarized. This flag is propagated up in the
205 access tree. */
206 unsigned grp_unscalarized_data : 1;
208 /* Does this access and/or group contain a write access through a
209 BIT_FIELD_REF? */
210 unsigned grp_partial_lhs : 1;
212 /* Set when a scalar replacement should be created for this variable. We do
213 the decision and creation at different places because create_tmp_var
214 cannot be called from within FOR_EACH_REFERENCED_VAR. */
215 unsigned grp_to_be_replaced : 1;
217 /* Is it possible that the group refers to data which might be (directly or
218 otherwise) modified? */
219 unsigned grp_maybe_modified : 1;
221 /* Set when this is a representative of a pointer to scalar (i.e. by
222 reference) parameter which we consider for turning into a plain scalar
223 (i.e. a by value parameter). */
224 unsigned grp_scalar_ptr : 1;
226 /* Set when we discover that this pointer is not safe to dereference in the
227 caller. */
228 unsigned grp_not_necessarilly_dereferenced : 1;
231 typedef struct access *access_p;
233 DEF_VEC_P (access_p);
234 DEF_VEC_ALLOC_P (access_p, heap);
236 /* Alloc pool for allocating access structures. */
237 static alloc_pool access_pool;
239 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
240 are used to propagate subaccesses from rhs to lhs as long as they don't
241 conflict with what is already there. */
242 struct assign_link
244 struct access *lacc, *racc;
245 struct assign_link *next;
248 /* Alloc pool for allocating assign link structures. */
249 static alloc_pool link_pool;
251 /* Base (tree) -> Vector (VEC(access_p,heap) *) map. */
252 static struct pointer_map_t *base_access_vec;
254 /* Bitmap of candidates. */
255 static bitmap candidate_bitmap;
257 /* Bitmap of candidates which we should try to entirely scalarize away and
258 those which cannot be (because they are and need be used as a whole). */
259 static bitmap should_scalarize_away_bitmap, cannot_scalarize_away_bitmap;
261 /* Obstack for creation of fancy names. */
262 static struct obstack name_obstack;
264 /* Head of a linked list of accesses that need to have its subaccesses
265 propagated to their assignment counterparts. */
266 static struct access *work_queue_head;
268 /* Number of parameters of the analyzed function when doing early ipa SRA. */
269 static int func_param_count;
271 /* scan_function sets the following to true if it encounters a call to
272 __builtin_apply_args. */
273 static bool encountered_apply_args;
275 /* Set by scan_function when it finds a recursive call. */
276 static bool encountered_recursive_call;
278 /* Set by scan_function when it finds a recursive call with less actual
279 arguments than formal parameters.. */
280 static bool encountered_unchangable_recursive_call;
282 /* This is a table in which for each basic block and parameter there is a
283 distance (offset + size) in that parameter which is dereferenced and
284 accessed in that BB. */
285 static HOST_WIDE_INT *bb_dereferences;
286 /* Bitmap of BBs that can cause the function to "stop" progressing by
287 returning, throwing externally, looping infinitely or calling a function
288 which might abort etc.. */
289 static bitmap final_bbs;
291 /* Representative of no accesses at all. */
292 static struct access no_accesses_representant;
294 /* Predicate to test the special value. */
296 static inline bool
297 no_accesses_p (struct access *access)
299 return access == &no_accesses_representant;
302 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
303 representative fields are dumped, otherwise those which only describe the
304 individual access are. */
306 static struct
308 /* Number of processed aggregates is readily available in
309 analyze_all_variable_accesses and so is not stored here. */
311 /* Number of created scalar replacements. */
312 int replacements;
314 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
315 expression. */
316 int exprs;
318 /* Number of statements created by generate_subtree_copies. */
319 int subtree_copies;
321 /* Number of statements created by load_assign_lhs_subreplacements. */
322 int subreplacements;
324 /* Number of times sra_modify_assign has deleted a statement. */
325 int deleted;
327 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
328 RHS reparately due to type conversions or nonexistent matching
329 references. */
330 int separate_lhs_rhs_handling;
332 /* Number of parameters that were removed because they were unused. */
333 int deleted_unused_parameters;
335 /* Number of scalars passed as parameters by reference that have been
336 converted to be passed by value. */
337 int scalar_by_ref_to_by_val;
339 /* Number of aggregate parameters that were replaced by one or more of their
340 components. */
341 int aggregate_params_reduced;
343 /* Numbber of components created when splitting aggregate parameters. */
344 int param_reductions_created;
345 } sra_stats;
347 static void
348 dump_access (FILE *f, struct access *access, bool grp)
350 fprintf (f, "access { ");
351 fprintf (f, "base = (%d)'", DECL_UID (access->base));
352 print_generic_expr (f, access->base, 0);
353 fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
354 fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
355 fprintf (f, ", expr = ");
356 print_generic_expr (f, access->expr, 0);
357 fprintf (f, ", type = ");
358 print_generic_expr (f, access->type, 0);
359 if (grp)
360 fprintf (f, ", grp_write = %d, total_scalarization = %d, "
361 "grp_read = %d, grp_hint = %d, grp_assignment_read = %d,"
362 "grp_covered = %d, grp_unscalarizable_region = %d, "
363 "grp_unscalarized_data = %d, grp_partial_lhs = %d, "
364 "grp_to_be_replaced = %d, grp_maybe_modified = %d, "
365 "grp_not_necessarilly_dereferenced = %d\n",
366 access->grp_write, access->total_scalarization,
367 access->grp_read, access->grp_hint, access->grp_assignment_read,
368 access->grp_covered, access->grp_unscalarizable_region,
369 access->grp_unscalarized_data, access->grp_partial_lhs,
370 access->grp_to_be_replaced, access->grp_maybe_modified,
371 access->grp_not_necessarilly_dereferenced);
372 else
373 fprintf (f, ", write = %d, total_scalarization = %d, "
374 "grp_partial_lhs = %d\n",
375 access->write, access->total_scalarization,
376 access->grp_partial_lhs);
379 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
381 static void
382 dump_access_tree_1 (FILE *f, struct access *access, int level)
386 int i;
388 for (i = 0; i < level; i++)
389 fputs ("* ", dump_file);
391 dump_access (f, access, true);
393 if (access->first_child)
394 dump_access_tree_1 (f, access->first_child, level + 1);
396 access = access->next_sibling;
398 while (access);
401 /* Dump all access trees for a variable, given the pointer to the first root in
402 ACCESS. */
404 static void
405 dump_access_tree (FILE *f, struct access *access)
407 for (; access; access = access->next_grp)
408 dump_access_tree_1 (f, access, 0);
411 /* Return true iff ACC is non-NULL and has subaccesses. */
413 static inline bool
414 access_has_children_p (struct access *acc)
416 return acc && acc->first_child;
419 /* Return a vector of pointers to accesses for the variable given in BASE or
420 NULL if there is none. */
422 static VEC (access_p, heap) *
423 get_base_access_vector (tree base)
425 void **slot;
427 slot = pointer_map_contains (base_access_vec, base);
428 if (!slot)
429 return NULL;
430 else
431 return *(VEC (access_p, heap) **) slot;
434 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
435 in ACCESS. Return NULL if it cannot be found. */
437 static struct access *
438 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
439 HOST_WIDE_INT size)
441 while (access && (access->offset != offset || access->size != size))
443 struct access *child = access->first_child;
445 while (child && (child->offset + child->size <= offset))
446 child = child->next_sibling;
447 access = child;
450 return access;
453 /* Return the first group representative for DECL or NULL if none exists. */
455 static struct access *
456 get_first_repr_for_decl (tree base)
458 VEC (access_p, heap) *access_vec;
460 access_vec = get_base_access_vector (base);
461 if (!access_vec)
462 return NULL;
464 return VEC_index (access_p, access_vec, 0);
467 /* Find an access representative for the variable BASE and given OFFSET and
468 SIZE. Requires that access trees have already been built. Return NULL if
469 it cannot be found. */
471 static struct access *
472 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
473 HOST_WIDE_INT size)
475 struct access *access;
477 access = get_first_repr_for_decl (base);
478 while (access && (access->offset + access->size <= offset))
479 access = access->next_grp;
480 if (!access)
481 return NULL;
483 return find_access_in_subtree (access, offset, size);
486 /* Add LINK to the linked list of assign links of RACC. */
487 static void
488 add_link_to_rhs (struct access *racc, struct assign_link *link)
490 gcc_assert (link->racc == racc);
492 if (!racc->first_link)
494 gcc_assert (!racc->last_link);
495 racc->first_link = link;
497 else
498 racc->last_link->next = link;
500 racc->last_link = link;
501 link->next = NULL;
504 /* Move all link structures in their linked list in OLD_RACC to the linked list
505 in NEW_RACC. */
506 static void
507 relink_to_new_repr (struct access *new_racc, struct access *old_racc)
509 if (!old_racc->first_link)
511 gcc_assert (!old_racc->last_link);
512 return;
515 if (new_racc->first_link)
517 gcc_assert (!new_racc->last_link->next);
518 gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
520 new_racc->last_link->next = old_racc->first_link;
521 new_racc->last_link = old_racc->last_link;
523 else
525 gcc_assert (!new_racc->last_link);
527 new_racc->first_link = old_racc->first_link;
528 new_racc->last_link = old_racc->last_link;
530 old_racc->first_link = old_racc->last_link = NULL;
533 /* Add ACCESS to the work queue (which is actually a stack). */
535 static void
536 add_access_to_work_queue (struct access *access)
538 if (!access->grp_queued)
540 gcc_assert (!access->next_queued);
541 access->next_queued = work_queue_head;
542 access->grp_queued = 1;
543 work_queue_head = access;
547 /* Pop an access from the work queue, and return it, assuming there is one. */
549 static struct access *
550 pop_access_from_work_queue (void)
552 struct access *access = work_queue_head;
554 work_queue_head = access->next_queued;
555 access->next_queued = NULL;
556 access->grp_queued = 0;
557 return access;
561 /* Allocate necessary structures. */
563 static void
564 sra_initialize (void)
566 candidate_bitmap = BITMAP_ALLOC (NULL);
567 should_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
568 cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
569 gcc_obstack_init (&name_obstack);
570 access_pool = create_alloc_pool ("SRA accesses", sizeof (struct access), 16);
571 link_pool = create_alloc_pool ("SRA links", sizeof (struct assign_link), 16);
572 base_access_vec = pointer_map_create ();
573 memset (&sra_stats, 0, sizeof (sra_stats));
574 encountered_apply_args = false;
575 encountered_recursive_call = false;
576 encountered_unchangable_recursive_call = false;
579 /* Hook fed to pointer_map_traverse, deallocate stored vectors. */
581 static bool
582 delete_base_accesses (const void *key ATTRIBUTE_UNUSED, void **value,
583 void *data ATTRIBUTE_UNUSED)
585 VEC (access_p, heap) *access_vec;
586 access_vec = (VEC (access_p, heap) *) *value;
587 VEC_free (access_p, heap, access_vec);
589 return true;
592 /* Deallocate all general structures. */
594 static void
595 sra_deinitialize (void)
597 BITMAP_FREE (candidate_bitmap);
598 BITMAP_FREE (should_scalarize_away_bitmap);
599 BITMAP_FREE (cannot_scalarize_away_bitmap);
600 free_alloc_pool (access_pool);
601 free_alloc_pool (link_pool);
602 obstack_free (&name_obstack, NULL);
604 pointer_map_traverse (base_access_vec, delete_base_accesses, NULL);
605 pointer_map_destroy (base_access_vec);
608 /* Remove DECL from candidates for SRA and write REASON to the dump file if
609 there is one. */
610 static void
611 disqualify_candidate (tree decl, const char *reason)
613 bitmap_clear_bit (candidate_bitmap, DECL_UID (decl));
615 if (dump_file && (dump_flags & TDF_DETAILS))
617 fprintf (dump_file, "! Disqualifying ");
618 print_generic_expr (dump_file, decl, 0);
619 fprintf (dump_file, " - %s\n", reason);
623 /* Return true iff the type contains a field or an element which does not allow
624 scalarization. */
626 static bool
627 type_internals_preclude_sra_p (tree type)
629 tree fld;
630 tree et;
632 switch (TREE_CODE (type))
634 case RECORD_TYPE:
635 case UNION_TYPE:
636 case QUAL_UNION_TYPE:
637 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
638 if (TREE_CODE (fld) == FIELD_DECL)
640 tree ft = TREE_TYPE (fld);
642 if (TREE_THIS_VOLATILE (fld)
643 || !DECL_FIELD_OFFSET (fld) || !DECL_SIZE (fld)
644 || !host_integerp (DECL_FIELD_OFFSET (fld), 1)
645 || !host_integerp (DECL_SIZE (fld), 1))
646 return true;
648 if (AGGREGATE_TYPE_P (ft)
649 && type_internals_preclude_sra_p (ft))
650 return true;
653 return false;
655 case ARRAY_TYPE:
656 et = TREE_TYPE (type);
658 if (AGGREGATE_TYPE_P (et))
659 return type_internals_preclude_sra_p (et);
660 else
661 return false;
663 default:
664 return false;
668 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
669 base variable if it is. Return T if it is not an SSA_NAME. */
671 static tree
672 get_ssa_base_param (tree t)
674 if (TREE_CODE (t) == SSA_NAME)
676 if (SSA_NAME_IS_DEFAULT_DEF (t))
677 return SSA_NAME_VAR (t);
678 else
679 return NULL_TREE;
681 return t;
684 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
685 belongs to, unless the BB has already been marked as a potentially
686 final. */
688 static void
689 mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple stmt)
691 basic_block bb = gimple_bb (stmt);
692 int idx, parm_index = 0;
693 tree parm;
695 if (bitmap_bit_p (final_bbs, bb->index))
696 return;
698 for (parm = DECL_ARGUMENTS (current_function_decl);
699 parm && parm != base;
700 parm = DECL_CHAIN (parm))
701 parm_index++;
703 gcc_assert (parm_index < func_param_count);
705 idx = bb->index * func_param_count + parm_index;
706 if (bb_dereferences[idx] < dist)
707 bb_dereferences[idx] = dist;
710 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
711 the three fields. Also add it to the vector of accesses corresponding to
712 the base. Finally, return the new access. */
714 static struct access *
715 create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
717 VEC (access_p, heap) *vec;
718 struct access *access;
719 void **slot;
721 access = (struct access *) pool_alloc (access_pool);
722 memset (access, 0, sizeof (struct access));
723 access->base = base;
724 access->offset = offset;
725 access->size = size;
727 slot = pointer_map_contains (base_access_vec, base);
728 if (slot)
729 vec = (VEC (access_p, heap) *) *slot;
730 else
731 vec = VEC_alloc (access_p, heap, 32);
733 VEC_safe_push (access_p, heap, vec, access);
735 *((struct VEC (access_p,heap) **)
736 pointer_map_insert (base_access_vec, base)) = vec;
738 return access;
741 /* Create and insert access for EXPR. Return created access, or NULL if it is
742 not possible. */
744 static struct access *
745 create_access (tree expr, gimple stmt, bool write)
747 struct access *access;
748 HOST_WIDE_INT offset, size, max_size;
749 tree base = expr;
750 bool ptr, unscalarizable_region = false;
752 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
754 if (sra_mode == SRA_MODE_EARLY_IPA
755 && TREE_CODE (base) == MEM_REF)
757 base = get_ssa_base_param (TREE_OPERAND (base, 0));
758 if (!base)
759 return NULL;
760 ptr = true;
762 else
763 ptr = false;
765 if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
766 return NULL;
768 if (sra_mode == SRA_MODE_EARLY_IPA)
770 if (size < 0 || size != max_size)
772 disqualify_candidate (base, "Encountered a variable sized access.");
773 return NULL;
775 if ((offset % BITS_PER_UNIT) != 0 || (size % BITS_PER_UNIT) != 0)
777 disqualify_candidate (base,
778 "Encountered an acces not aligned to a byte.");
779 return NULL;
782 if (ptr)
783 mark_parm_dereference (base, offset + size, stmt);
785 else
787 if (size != max_size)
789 size = max_size;
790 unscalarizable_region = true;
792 if (size < 0)
794 disqualify_candidate (base, "Encountered an unconstrained access.");
795 return NULL;
799 access = create_access_1 (base, offset, size);
800 access->expr = expr;
801 access->type = TREE_TYPE (expr);
802 access->write = write;
803 access->grp_unscalarizable_region = unscalarizable_region;
804 access->stmt = stmt;
806 return access;
810 /* Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple
811 register types or (recursively) records with only these two kinds of fields.
812 It also returns false if any of these records has a zero-size field as its
813 last field. */
815 static bool
816 type_consists_of_records_p (tree type)
818 tree fld;
819 bool last_fld_has_zero_size = false;
821 if (TREE_CODE (type) != RECORD_TYPE)
822 return false;
824 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
825 if (TREE_CODE (fld) == FIELD_DECL)
827 tree ft = TREE_TYPE (fld);
829 if (!is_gimple_reg_type (ft)
830 && !type_consists_of_records_p (ft))
831 return false;
833 last_fld_has_zero_size = tree_low_cst (DECL_SIZE (fld), 1) == 0;
836 if (last_fld_has_zero_size)
837 return false;
839 return true;
842 /* Create total_scalarization accesses for all scalar type fields in DECL that
843 must be of a RECORD_TYPE conforming to type_consists_of_records_p. BASE
844 must be the top-most VAR_DECL representing the variable, OFFSET must be the
845 offset of DECL within BASE. */
847 static void
848 completely_scalarize_record (tree base, tree decl, HOST_WIDE_INT offset)
850 tree fld, decl_type = TREE_TYPE (decl);
852 for (fld = TYPE_FIELDS (decl_type); fld; fld = DECL_CHAIN (fld))
853 if (TREE_CODE (fld) == FIELD_DECL)
855 HOST_WIDE_INT pos = offset + int_bit_position (fld);
856 tree ft = TREE_TYPE (fld);
858 if (is_gimple_reg_type (ft))
860 struct access *access;
861 HOST_WIDE_INT size;
862 tree expr;
863 bool ok;
865 size = tree_low_cst (DECL_SIZE (fld), 1);
866 expr = base;
867 ok = build_ref_for_offset (&expr, TREE_TYPE (base), pos,
868 ft, false);
869 gcc_assert (ok);
871 access = create_access_1 (base, pos, size);
872 access->expr = expr;
873 access->type = ft;
874 access->total_scalarization = 1;
875 /* Accesses for intraprocedural SRA can have their stmt NULL. */
877 else
878 completely_scalarize_record (base, fld, pos);
883 /* Search the given tree for a declaration by skipping handled components and
884 exclude it from the candidates. */
886 static void
887 disqualify_base_of_expr (tree t, const char *reason)
889 t = get_base_address (t);
890 if (sra_mode == SRA_MODE_EARLY_IPA
891 && TREE_CODE (t) == MEM_REF)
892 t = get_ssa_base_param (TREE_OPERAND (t, 0));
894 if (t && DECL_P (t))
895 disqualify_candidate (t, reason);
898 /* Scan expression EXPR and create access structures for all accesses to
899 candidates for scalarization. Return the created access or NULL if none is
900 created. */
902 static struct access *
903 build_access_from_expr_1 (tree expr, gimple stmt, bool write)
905 struct access *ret = NULL;
906 bool partial_ref;
908 if (TREE_CODE (expr) == BIT_FIELD_REF
909 || TREE_CODE (expr) == IMAGPART_EXPR
910 || TREE_CODE (expr) == REALPART_EXPR)
912 expr = TREE_OPERAND (expr, 0);
913 partial_ref = true;
915 else
916 partial_ref = false;
918 /* We need to dive through V_C_Es in order to get the size of its parameter
919 and not the result type. Ada produces such statements. We are also
920 capable of handling the topmost V_C_E but not any of those buried in other
921 handled components. */
922 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
923 expr = TREE_OPERAND (expr, 0);
925 if (contains_view_convert_expr_p (expr))
927 disqualify_base_of_expr (expr, "V_C_E under a different handled "
928 "component.");
929 return NULL;
932 switch (TREE_CODE (expr))
934 case MEM_REF:
935 if (TREE_CODE (TREE_OPERAND (expr, 0)) != ADDR_EXPR
936 && sra_mode != SRA_MODE_EARLY_IPA)
937 return NULL;
938 /* fall through */
939 case VAR_DECL:
940 case PARM_DECL:
941 case RESULT_DECL:
942 case COMPONENT_REF:
943 case ARRAY_REF:
944 case ARRAY_RANGE_REF:
945 ret = create_access (expr, stmt, write);
946 break;
948 default:
949 break;
952 if (write && partial_ref && ret)
953 ret->grp_partial_lhs = 1;
955 return ret;
958 /* Scan expression EXPR and create access structures for all accesses to
959 candidates for scalarization. Return true if any access has been inserted.
960 STMT must be the statement from which the expression is taken, WRITE must be
961 true if the expression is a store and false otherwise. */
963 static bool
964 build_access_from_expr (tree expr, gimple stmt, bool write)
966 struct access *access;
968 access = build_access_from_expr_1 (expr, stmt, write);
969 if (access)
971 /* This means the aggregate is accesses as a whole in a way other than an
972 assign statement and thus cannot be removed even if we had a scalar
973 replacement for everything. */
974 if (cannot_scalarize_away_bitmap)
975 bitmap_set_bit (cannot_scalarize_away_bitmap, DECL_UID (access->base));
976 return true;
978 return false;
981 /* Disqualify LHS and RHS for scalarization if STMT must end its basic block in
982 modes in which it matters, return true iff they have been disqualified. RHS
983 may be NULL, in that case ignore it. If we scalarize an aggregate in
984 intra-SRA we may need to add statements after each statement. This is not
985 possible if a statement unconditionally has to end the basic block. */
986 static bool
987 disqualify_ops_if_throwing_stmt (gimple stmt, tree lhs, tree rhs)
989 if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
990 && (stmt_can_throw_internal (stmt) || stmt_ends_bb_p (stmt)))
992 disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
993 if (rhs)
994 disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
995 return true;
997 return false;
1000 /* Scan expressions occuring in STMT, create access structures for all accesses
1001 to candidates for scalarization and remove those candidates which occur in
1002 statements or expressions that prevent them from being split apart. Return
1003 true if any access has been inserted. */
1005 static bool
1006 build_accesses_from_assign (gimple stmt)
1008 tree lhs, rhs;
1009 struct access *lacc, *racc;
1011 if (!gimple_assign_single_p (stmt))
1012 return false;
1014 lhs = gimple_assign_lhs (stmt);
1015 rhs = gimple_assign_rhs1 (stmt);
1017 if (disqualify_ops_if_throwing_stmt (stmt, lhs, rhs))
1018 return false;
1020 racc = build_access_from_expr_1 (rhs, stmt, false);
1021 lacc = build_access_from_expr_1 (lhs, stmt, true);
1023 if (racc)
1025 racc->grp_assignment_read = 1;
1026 if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
1027 && !is_gimple_reg_type (racc->type))
1028 bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
1031 if (lacc && racc
1032 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1033 && !lacc->grp_unscalarizable_region
1034 && !racc->grp_unscalarizable_region
1035 && AGGREGATE_TYPE_P (TREE_TYPE (lhs))
1036 /* FIXME: Turn the following line into an assert after PR 40058 is
1037 fixed. */
1038 && lacc->size == racc->size
1039 && useless_type_conversion_p (lacc->type, racc->type))
1041 struct assign_link *link;
1043 link = (struct assign_link *) pool_alloc (link_pool);
1044 memset (link, 0, sizeof (struct assign_link));
1046 link->lacc = lacc;
1047 link->racc = racc;
1049 add_link_to_rhs (racc, link);
1052 return lacc || racc;
1055 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1056 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1058 static bool
1059 asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED, tree op,
1060 void *data ATTRIBUTE_UNUSED)
1062 op = get_base_address (op);
1063 if (op
1064 && DECL_P (op))
1065 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
1067 return false;
1070 /* Return true iff callsite CALL has at least as many actual arguments as there
1071 are formal parameters of the function currently processed by IPA-SRA. */
1073 static inline bool
1074 callsite_has_enough_arguments_p (gimple call)
1076 return gimple_call_num_args (call) >= (unsigned) func_param_count;
1079 /* Scan function and look for interesting expressions and create access
1080 structures for them. Return true iff any access is created. */
1082 static bool
1083 scan_function (void)
1085 basic_block bb;
1086 bool ret = false;
1088 FOR_EACH_BB (bb)
1090 gimple_stmt_iterator gsi;
1091 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1093 gimple stmt = gsi_stmt (gsi);
1094 tree t;
1095 unsigned i;
1097 if (final_bbs && stmt_can_throw_external (stmt))
1098 bitmap_set_bit (final_bbs, bb->index);
1099 switch (gimple_code (stmt))
1101 case GIMPLE_RETURN:
1102 t = gimple_return_retval (stmt);
1103 if (t != NULL_TREE)
1104 ret |= build_access_from_expr (t, stmt, false);
1105 if (final_bbs)
1106 bitmap_set_bit (final_bbs, bb->index);
1107 break;
1109 case GIMPLE_ASSIGN:
1110 ret |= build_accesses_from_assign (stmt);
1111 break;
1113 case GIMPLE_CALL:
1114 for (i = 0; i < gimple_call_num_args (stmt); i++)
1115 ret |= build_access_from_expr (gimple_call_arg (stmt, i),
1116 stmt, false);
1118 if (sra_mode == SRA_MODE_EARLY_IPA)
1120 tree dest = gimple_call_fndecl (stmt);
1121 int flags = gimple_call_flags (stmt);
1123 if (dest)
1125 if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1126 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1127 encountered_apply_args = true;
1128 if (cgraph_get_node (dest)
1129 == cgraph_get_node (current_function_decl))
1131 encountered_recursive_call = true;
1132 if (!callsite_has_enough_arguments_p (stmt))
1133 encountered_unchangable_recursive_call = true;
1137 if (final_bbs
1138 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1139 bitmap_set_bit (final_bbs, bb->index);
1142 t = gimple_call_lhs (stmt);
1143 if (t && !disqualify_ops_if_throwing_stmt (stmt, t, NULL))
1144 ret |= build_access_from_expr (t, stmt, true);
1145 break;
1147 case GIMPLE_ASM:
1148 walk_stmt_load_store_addr_ops (stmt, NULL, NULL, NULL,
1149 asm_visit_addr);
1150 if (final_bbs)
1151 bitmap_set_bit (final_bbs, bb->index);
1153 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
1155 t = TREE_VALUE (gimple_asm_input_op (stmt, i));
1156 ret |= build_access_from_expr (t, stmt, false);
1158 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
1160 t = TREE_VALUE (gimple_asm_output_op (stmt, i));
1161 ret |= build_access_from_expr (t, stmt, true);
1163 break;
1165 default:
1166 break;
1171 return ret;
1174 /* Helper of QSORT function. There are pointers to accesses in the array. An
1175 access is considered smaller than another if it has smaller offset or if the
1176 offsets are the same but is size is bigger. */
1178 static int
1179 compare_access_positions (const void *a, const void *b)
1181 const access_p *fp1 = (const access_p *) a;
1182 const access_p *fp2 = (const access_p *) b;
1183 const access_p f1 = *fp1;
1184 const access_p f2 = *fp2;
1186 if (f1->offset != f2->offset)
1187 return f1->offset < f2->offset ? -1 : 1;
1189 if (f1->size == f2->size)
1191 if (f1->type == f2->type)
1192 return 0;
1193 /* Put any non-aggregate type before any aggregate type. */
1194 else if (!is_gimple_reg_type (f1->type)
1195 && is_gimple_reg_type (f2->type))
1196 return 1;
1197 else if (is_gimple_reg_type (f1->type)
1198 && !is_gimple_reg_type (f2->type))
1199 return -1;
1200 /* Put any complex or vector type before any other scalar type. */
1201 else if (TREE_CODE (f1->type) != COMPLEX_TYPE
1202 && TREE_CODE (f1->type) != VECTOR_TYPE
1203 && (TREE_CODE (f2->type) == COMPLEX_TYPE
1204 || TREE_CODE (f2->type) == VECTOR_TYPE))
1205 return 1;
1206 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
1207 || TREE_CODE (f1->type) == VECTOR_TYPE)
1208 && TREE_CODE (f2->type) != COMPLEX_TYPE
1209 && TREE_CODE (f2->type) != VECTOR_TYPE)
1210 return -1;
1211 /* Put the integral type with the bigger precision first. */
1212 else if (INTEGRAL_TYPE_P (f1->type)
1213 && INTEGRAL_TYPE_P (f2->type))
1214 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
1215 /* Put any integral type with non-full precision last. */
1216 else if (INTEGRAL_TYPE_P (f1->type)
1217 && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type))
1218 != TYPE_PRECISION (f1->type)))
1219 return 1;
1220 else if (INTEGRAL_TYPE_P (f2->type)
1221 && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type))
1222 != TYPE_PRECISION (f2->type)))
1223 return -1;
1224 /* Stabilize the sort. */
1225 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1228 /* We want the bigger accesses first, thus the opposite operator in the next
1229 line: */
1230 return f1->size > f2->size ? -1 : 1;
1234 /* Append a name of the declaration to the name obstack. A helper function for
1235 make_fancy_name. */
1237 static void
1238 make_fancy_decl_name (tree decl)
1240 char buffer[32];
1242 tree name = DECL_NAME (decl);
1243 if (name)
1244 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1245 IDENTIFIER_LENGTH (name));
1246 else
1248 sprintf (buffer, "D%u", DECL_UID (decl));
1249 obstack_grow (&name_obstack, buffer, strlen (buffer));
1253 /* Helper for make_fancy_name. */
1255 static void
1256 make_fancy_name_1 (tree expr)
1258 char buffer[32];
1259 tree index;
1261 if (DECL_P (expr))
1263 make_fancy_decl_name (expr);
1264 return;
1267 switch (TREE_CODE (expr))
1269 case COMPONENT_REF:
1270 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1271 obstack_1grow (&name_obstack, '$');
1272 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1273 break;
1275 case ARRAY_REF:
1276 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1277 obstack_1grow (&name_obstack, '$');
1278 /* Arrays with only one element may not have a constant as their
1279 index. */
1280 index = TREE_OPERAND (expr, 1);
1281 if (TREE_CODE (index) != INTEGER_CST)
1282 break;
1283 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1284 obstack_grow (&name_obstack, buffer, strlen (buffer));
1285 break;
1287 case ADDR_EXPR:
1288 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1289 break;
1291 case MEM_REF:
1292 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1293 if (!integer_zerop (TREE_OPERAND (expr, 1)))
1295 obstack_1grow (&name_obstack, '$');
1296 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC,
1297 TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)));
1298 obstack_grow (&name_obstack, buffer, strlen (buffer));
1300 break;
1302 case BIT_FIELD_REF:
1303 case REALPART_EXPR:
1304 case IMAGPART_EXPR:
1305 gcc_unreachable (); /* we treat these as scalars. */
1306 break;
1307 default:
1308 break;
1312 /* Create a human readable name for replacement variable of ACCESS. */
1314 static char *
1315 make_fancy_name (tree expr)
1317 make_fancy_name_1 (expr);
1318 obstack_1grow (&name_obstack, '\0');
1319 return XOBFINISH (&name_obstack, char *);
1322 /* Helper function for build_ref_for_offset.
1324 FIXME: Eventually this should be rewritten to either re-use the
1325 original access expression unshared (which is good for alias
1326 analysis) or to build a MEM_REF expression. */
1328 static bool
1329 build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset,
1330 tree exp_type)
1332 while (1)
1334 tree fld;
1335 tree tr_size, index, minidx;
1336 HOST_WIDE_INT el_size;
1338 if (offset == 0 && exp_type
1339 && types_compatible_p (exp_type, type))
1340 return true;
1342 switch (TREE_CODE (type))
1344 case UNION_TYPE:
1345 case QUAL_UNION_TYPE:
1346 case RECORD_TYPE:
1347 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
1349 HOST_WIDE_INT pos, size;
1350 tree expr, *expr_ptr;
1352 if (TREE_CODE (fld) != FIELD_DECL)
1353 continue;
1355 pos = int_bit_position (fld);
1356 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1357 tr_size = DECL_SIZE (fld);
1358 if (!tr_size || !host_integerp (tr_size, 1))
1359 continue;
1360 size = tree_low_cst (tr_size, 1);
1361 if (size == 0)
1363 if (pos != offset)
1364 continue;
1366 else if (pos > offset || (pos + size) <= offset)
1367 continue;
1369 if (res)
1371 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1372 NULL_TREE);
1373 expr_ptr = &expr;
1375 else
1376 expr_ptr = NULL;
1377 if (build_ref_for_offset_1 (expr_ptr, TREE_TYPE (fld),
1378 offset - pos, exp_type))
1380 if (res)
1381 *res = expr;
1382 return true;
1385 return false;
1387 case ARRAY_TYPE:
1388 tr_size = TYPE_SIZE (TREE_TYPE (type));
1389 if (!tr_size || !host_integerp (tr_size, 1))
1390 return false;
1391 el_size = tree_low_cst (tr_size, 1);
1393 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1394 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
1395 return false;
1396 if (res)
1398 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1399 if (!integer_zerop (minidx))
1400 index = int_const_binop (PLUS_EXPR, index, minidx, 0);
1401 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1402 NULL_TREE, NULL_TREE);
1404 offset = offset % el_size;
1405 type = TREE_TYPE (type);
1406 break;
1408 default:
1409 if (offset != 0)
1410 return false;
1412 if (exp_type)
1413 return false;
1414 else
1415 return true;
1420 /* Construct an expression that would reference a part of aggregate *EXPR of
1421 type TYPE at the given OFFSET of the type EXP_TYPE. If EXPR is NULL, the
1422 function only determines whether it can build such a reference without
1423 actually doing it, otherwise, the tree it points to is unshared first and
1424 then used as a base for furhter sub-references. */
1426 bool
1427 build_ref_for_offset (tree *expr, tree type, HOST_WIDE_INT offset,
1428 tree exp_type, bool allow_ptr)
1430 location_t loc = expr ? EXPR_LOCATION (*expr) : UNKNOWN_LOCATION;
1432 if (expr)
1433 *expr = unshare_expr (*expr);
1435 if (allow_ptr && POINTER_TYPE_P (type))
1437 type = TREE_TYPE (type);
1438 if (expr)
1439 *expr = build_simple_mem_ref_loc (loc, *expr);
1442 return build_ref_for_offset_1 (expr, type, offset, exp_type);
1445 /* Return true iff TYPE is stdarg va_list type. */
1447 static inline bool
1448 is_va_list_type (tree type)
1450 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1453 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1454 those with type which is suitable for scalarization. */
1456 static bool
1457 find_var_candidates (void)
1459 tree var, type;
1460 referenced_var_iterator rvi;
1461 bool ret = false;
1463 FOR_EACH_REFERENCED_VAR (var, rvi)
1465 if (TREE_CODE (var) != VAR_DECL && TREE_CODE (var) != PARM_DECL)
1466 continue;
1467 type = TREE_TYPE (var);
1469 if (!AGGREGATE_TYPE_P (type)
1470 || needs_to_live_in_memory (var)
1471 || TREE_THIS_VOLATILE (var)
1472 || !COMPLETE_TYPE_P (type)
1473 || !host_integerp (TYPE_SIZE (type), 1)
1474 || tree_low_cst (TYPE_SIZE (type), 1) == 0
1475 || type_internals_preclude_sra_p (type)
1476 /* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1477 we also want to schedule it rather late. Thus we ignore it in
1478 the early pass. */
1479 || (sra_mode == SRA_MODE_EARLY_INTRA
1480 && is_va_list_type (type)))
1481 continue;
1483 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
1485 if (dump_file && (dump_flags & TDF_DETAILS))
1487 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
1488 print_generic_expr (dump_file, var, 0);
1489 fprintf (dump_file, "\n");
1491 ret = true;
1494 return ret;
1497 /* Sort all accesses for the given variable, check for partial overlaps and
1498 return NULL if there are any. If there are none, pick a representative for
1499 each combination of offset and size and create a linked list out of them.
1500 Return the pointer to the first representative and make sure it is the first
1501 one in the vector of accesses. */
1503 static struct access *
1504 sort_and_splice_var_accesses (tree var)
1506 int i, j, access_count;
1507 struct access *res, **prev_acc_ptr = &res;
1508 VEC (access_p, heap) *access_vec;
1509 bool first = true;
1510 HOST_WIDE_INT low = -1, high = 0;
1512 access_vec = get_base_access_vector (var);
1513 if (!access_vec)
1514 return NULL;
1515 access_count = VEC_length (access_p, access_vec);
1517 /* Sort by <OFFSET, SIZE>. */
1518 qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
1519 compare_access_positions);
1521 i = 0;
1522 while (i < access_count)
1524 struct access *access = VEC_index (access_p, access_vec, i);
1525 bool grp_write = access->write;
1526 bool grp_read = !access->write;
1527 bool grp_assignment_read = access->grp_assignment_read;
1528 bool multiple_reads = false;
1529 bool total_scalarization = access->total_scalarization;
1530 bool grp_partial_lhs = access->grp_partial_lhs;
1531 bool first_scalar = is_gimple_reg_type (access->type);
1532 bool unscalarizable_region = access->grp_unscalarizable_region;
1534 if (first || access->offset >= high)
1536 first = false;
1537 low = access->offset;
1538 high = access->offset + access->size;
1540 else if (access->offset > low && access->offset + access->size > high)
1541 return NULL;
1542 else
1543 gcc_assert (access->offset >= low
1544 && access->offset + access->size <= high);
1546 j = i + 1;
1547 while (j < access_count)
1549 struct access *ac2 = VEC_index (access_p, access_vec, j);
1550 if (ac2->offset != access->offset || ac2->size != access->size)
1551 break;
1552 if (ac2->write)
1553 grp_write = true;
1554 else
1556 if (grp_read)
1557 multiple_reads = true;
1558 else
1559 grp_read = true;
1561 grp_assignment_read |= ac2->grp_assignment_read;
1562 grp_partial_lhs |= ac2->grp_partial_lhs;
1563 unscalarizable_region |= ac2->grp_unscalarizable_region;
1564 total_scalarization |= ac2->total_scalarization;
1565 relink_to_new_repr (access, ac2);
1567 /* If there are both aggregate-type and scalar-type accesses with
1568 this combination of size and offset, the comparison function
1569 should have put the scalars first. */
1570 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
1571 ac2->group_representative = access;
1572 j++;
1575 i = j;
1577 access->group_representative = access;
1578 access->grp_write = grp_write;
1579 access->grp_read = grp_read;
1580 access->grp_assignment_read = grp_assignment_read;
1581 access->grp_hint = multiple_reads || total_scalarization;
1582 access->grp_partial_lhs = grp_partial_lhs;
1583 access->grp_unscalarizable_region = unscalarizable_region;
1584 if (access->first_link)
1585 add_access_to_work_queue (access);
1587 *prev_acc_ptr = access;
1588 prev_acc_ptr = &access->next_grp;
1591 gcc_assert (res == VEC_index (access_p, access_vec, 0));
1592 return res;
1595 /* Create a variable for the given ACCESS which determines the type, name and a
1596 few other properties. Return the variable declaration and store it also to
1597 ACCESS->replacement. */
1599 static tree
1600 create_access_replacement (struct access *access, bool rename)
1602 tree repl;
1604 repl = create_tmp_var (access->type, "SR");
1605 get_var_ann (repl);
1606 add_referenced_var (repl);
1607 if (rename)
1608 mark_sym_for_renaming (repl);
1610 if (!access->grp_partial_lhs
1611 && (TREE_CODE (access->type) == COMPLEX_TYPE
1612 || TREE_CODE (access->type) == VECTOR_TYPE))
1613 DECL_GIMPLE_REG_P (repl) = 1;
1615 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
1616 DECL_ARTIFICIAL (repl) = 1;
1617 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
1619 if (DECL_NAME (access->base)
1620 && !DECL_IGNORED_P (access->base)
1621 && !DECL_ARTIFICIAL (access->base))
1623 char *pretty_name = make_fancy_name (access->expr);
1624 tree debug_expr = unshare_expr (access->expr), d;
1626 DECL_NAME (repl) = get_identifier (pretty_name);
1627 obstack_free (&name_obstack, pretty_name);
1629 /* Get rid of any SSA_NAMEs embedded in debug_expr,
1630 as DECL_DEBUG_EXPR isn't considered when looking for still
1631 used SSA_NAMEs and thus they could be freed. All debug info
1632 generation cares is whether something is constant or variable
1633 and that get_ref_base_and_extent works properly on the
1634 expression. */
1635 for (d = debug_expr; handled_component_p (d); d = TREE_OPERAND (d, 0))
1636 switch (TREE_CODE (d))
1638 case ARRAY_REF:
1639 case ARRAY_RANGE_REF:
1640 if (TREE_OPERAND (d, 1)
1641 && TREE_CODE (TREE_OPERAND (d, 1)) == SSA_NAME)
1642 TREE_OPERAND (d, 1) = SSA_NAME_VAR (TREE_OPERAND (d, 1));
1643 if (TREE_OPERAND (d, 3)
1644 && TREE_CODE (TREE_OPERAND (d, 3)) == SSA_NAME)
1645 TREE_OPERAND (d, 3) = SSA_NAME_VAR (TREE_OPERAND (d, 3));
1646 /* FALLTHRU */
1647 case COMPONENT_REF:
1648 if (TREE_OPERAND (d, 2)
1649 && TREE_CODE (TREE_OPERAND (d, 2)) == SSA_NAME)
1650 TREE_OPERAND (d, 2) = SSA_NAME_VAR (TREE_OPERAND (d, 2));
1651 break;
1652 default:
1653 break;
1655 SET_DECL_DEBUG_EXPR (repl, debug_expr);
1656 DECL_DEBUG_EXPR_IS_FROM (repl) = 1;
1657 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
1659 else
1660 TREE_NO_WARNING (repl) = 1;
1662 if (dump_file)
1664 fprintf (dump_file, "Created a replacement for ");
1665 print_generic_expr (dump_file, access->base, 0);
1666 fprintf (dump_file, " offset: %u, size: %u: ",
1667 (unsigned) access->offset, (unsigned) access->size);
1668 print_generic_expr (dump_file, repl, 0);
1669 fprintf (dump_file, "\n");
1671 sra_stats.replacements++;
1673 return repl;
1676 /* Return ACCESS scalar replacement, create it if it does not exist yet. */
1678 static inline tree
1679 get_access_replacement (struct access *access)
1681 gcc_assert (access->grp_to_be_replaced);
1683 if (!access->replacement_decl)
1684 access->replacement_decl = create_access_replacement (access, true);
1685 return access->replacement_decl;
1688 /* Return ACCESS scalar replacement, create it if it does not exist yet but do
1689 not mark it for renaming. */
1691 static inline tree
1692 get_unrenamed_access_replacement (struct access *access)
1694 gcc_assert (!access->grp_to_be_replaced);
1696 if (!access->replacement_decl)
1697 access->replacement_decl = create_access_replacement (access, false);
1698 return access->replacement_decl;
1702 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
1703 linked list along the way. Stop when *ACCESS is NULL or the access pointed
1704 to it is not "within" the root. Return false iff some accesses partially
1705 overlap. */
1707 static bool
1708 build_access_subtree (struct access **access)
1710 struct access *root = *access, *last_child = NULL;
1711 HOST_WIDE_INT limit = root->offset + root->size;
1713 *access = (*access)->next_grp;
1714 while (*access && (*access)->offset + (*access)->size <= limit)
1716 if (!last_child)
1717 root->first_child = *access;
1718 else
1719 last_child->next_sibling = *access;
1720 last_child = *access;
1722 if (!build_access_subtree (access))
1723 return false;
1726 if (*access && (*access)->offset < limit)
1727 return false;
1729 return true;
1732 /* Build a tree of access representatives, ACCESS is the pointer to the first
1733 one, others are linked in a list by the next_grp field. Return false iff
1734 some accesses partially overlap. */
1736 static bool
1737 build_access_trees (struct access *access)
1739 while (access)
1741 struct access *root = access;
1743 if (!build_access_subtree (&access))
1744 return false;
1745 root->next_grp = access;
1747 return true;
1750 /* Return true if expr contains some ARRAY_REFs into a variable bounded
1751 array. */
1753 static bool
1754 expr_with_var_bounded_array_refs_p (tree expr)
1756 while (handled_component_p (expr))
1758 if (TREE_CODE (expr) == ARRAY_REF
1759 && !host_integerp (array_ref_low_bound (expr), 0))
1760 return true;
1761 expr = TREE_OPERAND (expr, 0);
1763 return false;
1766 enum mark_read_status { SRA_MR_NOT_READ, SRA_MR_READ, SRA_MR_ASSIGN_READ};
1768 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
1769 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
1770 sorts of access flags appropriately along the way, notably always set
1771 grp_read and grp_assign_read according to MARK_READ and grp_write when
1772 MARK_WRITE is true. */
1774 static bool
1775 analyze_access_subtree (struct access *root, bool allow_replacements,
1776 enum mark_read_status mark_read, bool mark_write)
1778 struct access *child;
1779 HOST_WIDE_INT limit = root->offset + root->size;
1780 HOST_WIDE_INT covered_to = root->offset;
1781 bool scalar = is_gimple_reg_type (root->type);
1782 bool hole = false, sth_created = false;
1783 bool direct_read = root->grp_read;
1785 if (mark_read == SRA_MR_ASSIGN_READ)
1787 root->grp_read = 1;
1788 root->grp_assignment_read = 1;
1790 if (mark_read == SRA_MR_READ)
1791 root->grp_read = 1;
1792 else if (root->grp_assignment_read)
1793 mark_read = SRA_MR_ASSIGN_READ;
1794 else if (root->grp_read)
1795 mark_read = SRA_MR_READ;
1797 if (mark_write)
1798 root->grp_write = true;
1799 else if (root->grp_write)
1800 mark_write = true;
1802 if (root->grp_unscalarizable_region)
1803 allow_replacements = false;
1805 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
1806 allow_replacements = false;
1808 for (child = root->first_child; child; child = child->next_sibling)
1810 if (!hole && child->offset < covered_to)
1811 hole = true;
1812 else
1813 covered_to += child->size;
1815 sth_created |= analyze_access_subtree (child,
1816 allow_replacements && !scalar,
1817 mark_read, mark_write);
1819 root->grp_unscalarized_data |= child->grp_unscalarized_data;
1820 hole |= !child->grp_covered;
1823 if (allow_replacements && scalar && !root->first_child
1824 && (root->grp_hint
1825 || (root->grp_write && (direct_read || root->grp_assignment_read)))
1826 /* We must not ICE later on when trying to build an access to the
1827 original data within the aggregate even when it is impossible to do in
1828 a defined way like in the PR 42703 testcase. Therefore we check
1829 pre-emptively here that we will be able to do that. */
1830 && build_ref_for_offset (NULL, TREE_TYPE (root->base), root->offset,
1831 root->type, false))
1833 if (dump_file && (dump_flags & TDF_DETAILS))
1835 fprintf (dump_file, "Marking ");
1836 print_generic_expr (dump_file, root->base, 0);
1837 fprintf (dump_file, " offset: %u, size: %u: ",
1838 (unsigned) root->offset, (unsigned) root->size);
1839 fprintf (dump_file, " to be replaced.\n");
1842 root->grp_to_be_replaced = 1;
1843 sth_created = true;
1844 hole = false;
1846 else if (covered_to < limit)
1847 hole = true;
1849 if (sth_created && !hole)
1851 root->grp_covered = 1;
1852 return true;
1854 if (root->grp_write || TREE_CODE (root->base) == PARM_DECL)
1855 root->grp_unscalarized_data = 1; /* not covered and written to */
1856 if (sth_created)
1857 return true;
1858 return false;
1861 /* Analyze all access trees linked by next_grp by the means of
1862 analyze_access_subtree. */
1863 static bool
1864 analyze_access_trees (struct access *access)
1866 bool ret = false;
1868 while (access)
1870 if (analyze_access_subtree (access, true, SRA_MR_NOT_READ, false))
1871 ret = true;
1872 access = access->next_grp;
1875 return ret;
1878 /* Return true iff a potential new child of LACC at offset OFFSET and with size
1879 SIZE would conflict with an already existing one. If exactly such a child
1880 already exists in LACC, store a pointer to it in EXACT_MATCH. */
1882 static bool
1883 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
1884 HOST_WIDE_INT size, struct access **exact_match)
1886 struct access *child;
1888 for (child = lacc->first_child; child; child = child->next_sibling)
1890 if (child->offset == norm_offset && child->size == size)
1892 *exact_match = child;
1893 return true;
1896 if (child->offset < norm_offset + size
1897 && child->offset + child->size > norm_offset)
1898 return true;
1901 return false;
1904 /* Create a new child access of PARENT, with all properties just like MODEL
1905 except for its offset and with its grp_write false and grp_read true.
1906 Return the new access or NULL if it cannot be created. Note that this access
1907 is created long after all splicing and sorting, it's not located in any
1908 access vector and is automatically a representative of its group. */
1910 static struct access *
1911 create_artificial_child_access (struct access *parent, struct access *model,
1912 HOST_WIDE_INT new_offset)
1914 struct access *access;
1915 struct access **child;
1916 tree expr = parent->base;;
1918 gcc_assert (!model->grp_unscalarizable_region);
1920 if (!build_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
1921 model->type, false))
1922 return NULL;
1924 access = (struct access *) pool_alloc (access_pool);
1925 memset (access, 0, sizeof (struct access));
1926 access->base = parent->base;
1927 access->expr = expr;
1928 access->offset = new_offset;
1929 access->size = model->size;
1930 access->type = model->type;
1931 access->grp_write = true;
1932 access->grp_read = false;
1934 child = &parent->first_child;
1935 while (*child && (*child)->offset < new_offset)
1936 child = &(*child)->next_sibling;
1938 access->next_sibling = *child;
1939 *child = access;
1941 return access;
1945 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
1946 true if any new subaccess was created. Additionally, if RACC is a scalar
1947 access but LACC is not, change the type of the latter, if possible. */
1949 static bool
1950 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
1952 struct access *rchild;
1953 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
1954 bool ret = false;
1956 if (is_gimple_reg_type (lacc->type)
1957 || lacc->grp_unscalarizable_region
1958 || racc->grp_unscalarizable_region)
1959 return false;
1961 if (!lacc->first_child && !racc->first_child
1962 && is_gimple_reg_type (racc->type))
1964 tree t = lacc->base;
1966 if (build_ref_for_offset (&t, TREE_TYPE (t), lacc->offset, racc->type,
1967 false))
1969 lacc->expr = t;
1970 lacc->type = racc->type;
1972 return false;
1975 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
1977 struct access *new_acc = NULL;
1978 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
1980 if (rchild->grp_unscalarizable_region)
1981 continue;
1983 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
1984 &new_acc))
1986 if (new_acc)
1988 rchild->grp_hint = 1;
1989 new_acc->grp_hint |= new_acc->grp_read;
1990 if (rchild->first_child)
1991 ret |= propagate_subaccesses_across_link (new_acc, rchild);
1993 continue;
1996 /* If a (part of) a union field is on the RHS of an assignment, it can
1997 have sub-accesses which do not make sense on the LHS (PR 40351).
1998 Check that this is not the case. */
1999 if (!build_ref_for_offset (NULL, TREE_TYPE (lacc->base), norm_offset,
2000 rchild->type, false))
2001 continue;
2003 rchild->grp_hint = 1;
2004 new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
2005 if (new_acc)
2007 ret = true;
2008 if (racc->first_child)
2009 propagate_subaccesses_across_link (new_acc, rchild);
2013 return ret;
2016 /* Propagate all subaccesses across assignment links. */
2018 static void
2019 propagate_all_subaccesses (void)
2021 while (work_queue_head)
2023 struct access *racc = pop_access_from_work_queue ();
2024 struct assign_link *link;
2026 gcc_assert (racc->first_link);
2028 for (link = racc->first_link; link; link = link->next)
2030 struct access *lacc = link->lacc;
2032 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
2033 continue;
2034 lacc = lacc->group_representative;
2035 if (propagate_subaccesses_across_link (lacc, racc)
2036 && lacc->first_link)
2037 add_access_to_work_queue (lacc);
2042 /* Go through all accesses collected throughout the (intraprocedural) analysis
2043 stage, exclude overlapping ones, identify representatives and build trees
2044 out of them, making decisions about scalarization on the way. Return true
2045 iff there are any to-be-scalarized variables after this stage. */
2047 static bool
2048 analyze_all_variable_accesses (void)
2050 int res = 0;
2051 bitmap tmp = BITMAP_ALLOC (NULL);
2052 bitmap_iterator bi;
2053 unsigned i, max_total_scalarization_size;
2055 max_total_scalarization_size = UNITS_PER_WORD * BITS_PER_UNIT
2056 * MOVE_RATIO (optimize_function_for_speed_p (cfun));
2058 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
2059 if (bitmap_bit_p (should_scalarize_away_bitmap, i)
2060 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
2062 tree var = referenced_var (i);
2064 if (TREE_CODE (var) == VAR_DECL
2065 && ((unsigned) tree_low_cst (TYPE_SIZE (TREE_TYPE (var)), 1)
2066 <= max_total_scalarization_size)
2067 && type_consists_of_records_p (TREE_TYPE (var)))
2069 completely_scalarize_record (var, var, 0);
2070 if (dump_file && (dump_flags & TDF_DETAILS))
2072 fprintf (dump_file, "Will attempt to totally scalarize ");
2073 print_generic_expr (dump_file, var, 0);
2074 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2079 bitmap_copy (tmp, candidate_bitmap);
2080 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2082 tree var = referenced_var (i);
2083 struct access *access;
2085 access = sort_and_splice_var_accesses (var);
2086 if (!access || !build_access_trees (access))
2087 disqualify_candidate (var,
2088 "No or inhibitingly overlapping accesses.");
2091 propagate_all_subaccesses ();
2093 bitmap_copy (tmp, candidate_bitmap);
2094 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2096 tree var = referenced_var (i);
2097 struct access *access = get_first_repr_for_decl (var);
2099 if (analyze_access_trees (access))
2101 res++;
2102 if (dump_file && (dump_flags & TDF_DETAILS))
2104 fprintf (dump_file, "\nAccess trees for ");
2105 print_generic_expr (dump_file, var, 0);
2106 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2107 dump_access_tree (dump_file, access);
2108 fprintf (dump_file, "\n");
2111 else
2112 disqualify_candidate (var, "No scalar replacements to be created.");
2115 BITMAP_FREE (tmp);
2117 if (res)
2119 statistics_counter_event (cfun, "Scalarized aggregates", res);
2120 return true;
2122 else
2123 return false;
2126 /* Return true iff a reference statement into aggregate AGG can be built for
2127 every single to-be-replaced accesses that is a child of ACCESS, its sibling
2128 or a child of its sibling. TOP_OFFSET is the offset from the processed
2129 access subtree that has to be subtracted from offset of each access. */
2131 static bool
2132 ref_expr_for_all_replacements_p (struct access *access, tree agg,
2133 HOST_WIDE_INT top_offset)
2137 if (access->grp_to_be_replaced
2138 && !build_ref_for_offset (NULL, TREE_TYPE (agg),
2139 access->offset - top_offset,
2140 access->type, false))
2141 return false;
2143 if (access->first_child
2144 && !ref_expr_for_all_replacements_p (access->first_child, agg,
2145 top_offset))
2146 return false;
2148 access = access->next_sibling;
2150 while (access);
2152 return true;
2155 /* Generate statements copying scalar replacements of accesses within a subtree
2156 into or out of AGG. ACCESS is the first child of the root of the subtree to
2157 be processed. AGG is an aggregate type expression (can be a declaration but
2158 does not have to be, it can for example also be an indirect_ref).
2159 TOP_OFFSET is the offset of the processed subtree which has to be subtracted
2160 from offsets of individual accesses to get corresponding offsets for AGG.
2161 If CHUNK_SIZE is non-null, copy only replacements in the interval
2162 <start_offset, start_offset + chunk_size>, otherwise copy all. GSI is a
2163 statement iterator used to place the new statements. WRITE should be true
2164 when the statements should write from AGG to the replacement and false if
2165 vice versa. if INSERT_AFTER is true, new statements will be added after the
2166 current statement in GSI, they will be added before the statement
2167 otherwise. */
2169 static void
2170 generate_subtree_copies (struct access *access, tree agg,
2171 HOST_WIDE_INT top_offset,
2172 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
2173 gimple_stmt_iterator *gsi, bool write,
2174 bool insert_after)
2178 tree expr = agg;
2180 if (chunk_size && access->offset >= start_offset + chunk_size)
2181 return;
2183 if (access->grp_to_be_replaced
2184 && (chunk_size == 0
2185 || access->offset + access->size > start_offset))
2187 tree repl = get_access_replacement (access);
2188 bool ref_found;
2189 gimple stmt;
2191 ref_found = build_ref_for_offset (&expr, TREE_TYPE (agg),
2192 access->offset - top_offset,
2193 access->type, false);
2194 gcc_assert (ref_found);
2196 if (write)
2198 if (access->grp_partial_lhs)
2199 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
2200 !insert_after,
2201 insert_after ? GSI_NEW_STMT
2202 : GSI_SAME_STMT);
2203 stmt = gimple_build_assign (repl, expr);
2205 else
2207 TREE_NO_WARNING (repl) = 1;
2208 if (access->grp_partial_lhs)
2209 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2210 !insert_after,
2211 insert_after ? GSI_NEW_STMT
2212 : GSI_SAME_STMT);
2213 stmt = gimple_build_assign (expr, repl);
2216 if (insert_after)
2217 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2218 else
2219 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2220 update_stmt (stmt);
2221 sra_stats.subtree_copies++;
2224 if (access->first_child)
2225 generate_subtree_copies (access->first_child, agg, top_offset,
2226 start_offset, chunk_size, gsi,
2227 write, insert_after);
2229 access = access->next_sibling;
2231 while (access);
2234 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2235 the root of the subtree to be processed. GSI is the statement iterator used
2236 for inserting statements which are added after the current statement if
2237 INSERT_AFTER is true or before it otherwise. */
2239 static void
2240 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
2241 bool insert_after)
2244 struct access *child;
2246 if (access->grp_to_be_replaced)
2248 gimple stmt;
2250 stmt = gimple_build_assign (get_access_replacement (access),
2251 fold_convert (access->type,
2252 integer_zero_node));
2253 if (insert_after)
2254 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2255 else
2256 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2257 update_stmt (stmt);
2260 for (child = access->first_child; child; child = child->next_sibling)
2261 init_subtree_with_zero (child, gsi, insert_after);
2264 /* Search for an access representative for the given expression EXPR and
2265 return it or NULL if it cannot be found. */
2267 static struct access *
2268 get_access_for_expr (tree expr)
2270 HOST_WIDE_INT offset, size, max_size;
2271 tree base;
2273 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2274 a different size than the size of its argument and we need the latter
2275 one. */
2276 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
2277 expr = TREE_OPERAND (expr, 0);
2279 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
2280 if (max_size == -1 || !DECL_P (base))
2281 return NULL;
2283 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
2284 return NULL;
2286 return get_var_base_offset_size_access (base, offset, max_size);
2289 /* Replace the expression EXPR with a scalar replacement if there is one and
2290 generate other statements to do type conversion or subtree copying if
2291 necessary. GSI is used to place newly created statements, WRITE is true if
2292 the expression is being written to (it is on a LHS of a statement or output
2293 in an assembly statement). */
2295 static bool
2296 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
2298 struct access *access;
2299 tree type, bfr;
2301 if (TREE_CODE (*expr) == BIT_FIELD_REF)
2303 bfr = *expr;
2304 expr = &TREE_OPERAND (*expr, 0);
2306 else
2307 bfr = NULL_TREE;
2309 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
2310 expr = &TREE_OPERAND (*expr, 0);
2311 access = get_access_for_expr (*expr);
2312 if (!access)
2313 return false;
2314 type = TREE_TYPE (*expr);
2316 if (access->grp_to_be_replaced)
2318 tree repl = get_access_replacement (access);
2319 /* If we replace a non-register typed access simply use the original
2320 access expression to extract the scalar component afterwards.
2321 This happens if scalarizing a function return value or parameter
2322 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2323 gcc.c-torture/compile/20011217-1.c.
2325 We also want to use this when accessing a complex or vector which can
2326 be accessed as a different type too, potentially creating a need for
2327 type conversion (see PR42196) and when scalarized unions are involved
2328 in assembler statements (see PR42398). */
2329 if (!useless_type_conversion_p (type, access->type))
2331 tree ref = access->base;
2332 bool ok;
2334 ok = build_ref_for_offset (&ref, TREE_TYPE (ref),
2335 access->offset, access->type, false);
2336 gcc_assert (ok);
2338 if (write)
2340 gimple stmt;
2342 if (access->grp_partial_lhs)
2343 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
2344 false, GSI_NEW_STMT);
2345 stmt = gimple_build_assign (repl, ref);
2346 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2348 else
2350 gimple stmt;
2352 if (access->grp_partial_lhs)
2353 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2354 true, GSI_SAME_STMT);
2355 stmt = gimple_build_assign (ref, repl);
2356 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2359 else
2360 *expr = repl;
2361 sra_stats.exprs++;
2364 if (access->first_child)
2366 HOST_WIDE_INT start_offset, chunk_size;
2367 if (bfr
2368 && host_integerp (TREE_OPERAND (bfr, 1), 1)
2369 && host_integerp (TREE_OPERAND (bfr, 2), 1))
2371 chunk_size = tree_low_cst (TREE_OPERAND (bfr, 1), 1);
2372 start_offset = access->offset
2373 + tree_low_cst (TREE_OPERAND (bfr, 2), 1);
2375 else
2376 start_offset = chunk_size = 0;
2378 generate_subtree_copies (access->first_child, access->base, 0,
2379 start_offset, chunk_size, gsi, write, write);
2381 return true;
2384 /* Where scalar replacements of the RHS have been written to when a replacement
2385 of a LHS of an assigments cannot be direclty loaded from a replacement of
2386 the RHS. */
2387 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
2388 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
2389 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
2391 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2392 base aggregate if there are unscalarized data or directly to LHS
2393 otherwise. */
2395 static enum unscalarized_data_handling
2396 handle_unscalarized_data_in_subtree (struct access *top_racc, tree lhs,
2397 gimple_stmt_iterator *gsi)
2399 if (top_racc->grp_unscalarized_data)
2401 generate_subtree_copies (top_racc->first_child, top_racc->base, 0, 0, 0,
2402 gsi, false, false);
2403 return SRA_UDH_RIGHT;
2405 else
2407 generate_subtree_copies (top_racc->first_child, lhs, top_racc->offset,
2408 0, 0, gsi, false, false);
2409 return SRA_UDH_LEFT;
2414 /* Try to generate statements to load all sub-replacements in an access
2415 (sub)tree (LACC is the first child) from scalar replacements in the TOP_RACC
2416 (sub)tree. If that is not possible, refresh the TOP_RACC base aggregate and
2417 load the accesses from it. LEFT_OFFSET is the offset of the left whole
2418 subtree being copied, RIGHT_OFFSET is the same thing for the right subtree.
2419 GSI is stmt iterator used for statement insertions. *REFRESHED is true iff
2420 the rhs top aggregate has already been refreshed by contents of its scalar
2421 reductions and is set to true if this function has to do it. */
2423 static void
2424 load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
2425 HOST_WIDE_INT left_offset,
2426 HOST_WIDE_INT right_offset,
2427 gimple_stmt_iterator *old_gsi,
2428 gimple_stmt_iterator *new_gsi,
2429 enum unscalarized_data_handling *refreshed,
2430 tree lhs)
2432 location_t loc = EXPR_LOCATION (lacc->expr);
2435 if (lacc->grp_to_be_replaced)
2437 struct access *racc;
2438 HOST_WIDE_INT offset = lacc->offset - left_offset + right_offset;
2439 gimple stmt;
2440 tree rhs;
2442 racc = find_access_in_subtree (top_racc, offset, lacc->size);
2443 if (racc && racc->grp_to_be_replaced)
2445 rhs = get_access_replacement (racc);
2446 if (!useless_type_conversion_p (lacc->type, racc->type))
2447 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, lacc->type, rhs);
2449 else
2451 /* No suitable access on the right hand side, need to load from
2452 the aggregate. See if we have to update it first... */
2453 if (*refreshed == SRA_UDH_NONE)
2454 *refreshed = handle_unscalarized_data_in_subtree (top_racc,
2455 lhs, old_gsi);
2457 if (*refreshed == SRA_UDH_LEFT)
2459 bool repl_found;
2461 rhs = lacc->base;
2462 repl_found = build_ref_for_offset (&rhs, TREE_TYPE (rhs),
2463 lacc->offset, lacc->type,
2464 false);
2465 gcc_assert (repl_found);
2467 else
2469 bool repl_found;
2471 rhs = top_racc->base;
2472 repl_found = build_ref_for_offset (&rhs,
2473 TREE_TYPE (top_racc->base),
2474 offset, lacc->type, false);
2475 gcc_assert (repl_found);
2479 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
2480 gsi_insert_after (new_gsi, stmt, GSI_NEW_STMT);
2481 update_stmt (stmt);
2482 sra_stats.subreplacements++;
2484 else if (*refreshed == SRA_UDH_NONE
2485 && lacc->grp_read && !lacc->grp_covered)
2486 *refreshed = handle_unscalarized_data_in_subtree (top_racc, lhs,
2487 old_gsi);
2489 if (lacc->first_child)
2490 load_assign_lhs_subreplacements (lacc->first_child, top_racc,
2491 left_offset, right_offset,
2492 old_gsi, new_gsi, refreshed, lhs);
2493 lacc = lacc->next_sibling;
2495 while (lacc);
2498 /* Result code for SRA assignment modification. */
2499 enum assignment_mod_result { SRA_AM_NONE, /* nothing done for the stmt */
2500 SRA_AM_MODIFIED, /* stmt changed but not
2501 removed */
2502 SRA_AM_REMOVED }; /* stmt eliminated */
2504 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
2505 to the assignment and GSI is the statement iterator pointing at it. Returns
2506 the same values as sra_modify_assign. */
2508 static enum assignment_mod_result
2509 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
2511 tree lhs = gimple_assign_lhs (*stmt);
2512 struct access *acc;
2514 acc = get_access_for_expr (lhs);
2515 if (!acc)
2516 return SRA_AM_NONE;
2518 if (VEC_length (constructor_elt,
2519 CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt))) > 0)
2521 /* I have never seen this code path trigger but if it can happen the
2522 following should handle it gracefully. */
2523 if (access_has_children_p (acc))
2524 generate_subtree_copies (acc->first_child, acc->base, 0, 0, 0, gsi,
2525 true, true);
2526 return SRA_AM_MODIFIED;
2529 if (acc->grp_covered)
2531 init_subtree_with_zero (acc, gsi, false);
2532 unlink_stmt_vdef (*stmt);
2533 gsi_remove (gsi, true);
2534 return SRA_AM_REMOVED;
2536 else
2538 init_subtree_with_zero (acc, gsi, true);
2539 return SRA_AM_MODIFIED;
2543 /* Create a new suitable default definition SSA_NAME and replace all uses of
2544 SSA with it, RACC is access describing the uninitialized part of an
2545 aggregate that is being loaded. */
2547 static void
2548 replace_uses_with_default_def_ssa_name (tree ssa, struct access *racc)
2550 tree repl, decl;
2552 decl = get_unrenamed_access_replacement (racc);
2554 repl = gimple_default_def (cfun, decl);
2555 if (!repl)
2557 repl = make_ssa_name (decl, gimple_build_nop ());
2558 set_default_def (decl, repl);
2561 replace_uses_by (ssa, repl);
2564 /* Examine both sides of the assignment statement pointed to by STMT, replace
2565 them with a scalare replacement if there is one and generate copying of
2566 replacements if scalarized aggregates have been used in the assignment. GSI
2567 is used to hold generated statements for type conversions and subtree
2568 copying. */
2570 static enum assignment_mod_result
2571 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
2573 struct access *lacc, *racc;
2574 tree lhs, rhs;
2575 bool modify_this_stmt = false;
2576 bool force_gimple_rhs = false;
2577 location_t loc = gimple_location (*stmt);
2578 gimple_stmt_iterator orig_gsi = *gsi;
2580 if (!gimple_assign_single_p (*stmt))
2581 return SRA_AM_NONE;
2582 lhs = gimple_assign_lhs (*stmt);
2583 rhs = gimple_assign_rhs1 (*stmt);
2585 if (TREE_CODE (rhs) == CONSTRUCTOR)
2586 return sra_modify_constructor_assign (stmt, gsi);
2588 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
2589 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
2590 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
2592 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (*stmt),
2593 gsi, false);
2594 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (*stmt),
2595 gsi, true);
2596 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
2599 lacc = get_access_for_expr (lhs);
2600 racc = get_access_for_expr (rhs);
2601 if (!lacc && !racc)
2602 return SRA_AM_NONE;
2604 if (lacc && lacc->grp_to_be_replaced)
2606 lhs = get_access_replacement (lacc);
2607 gimple_assign_set_lhs (*stmt, lhs);
2608 modify_this_stmt = true;
2609 if (lacc->grp_partial_lhs)
2610 force_gimple_rhs = true;
2611 sra_stats.exprs++;
2614 if (racc && racc->grp_to_be_replaced)
2616 rhs = get_access_replacement (racc);
2617 modify_this_stmt = true;
2618 if (racc->grp_partial_lhs)
2619 force_gimple_rhs = true;
2620 sra_stats.exprs++;
2623 if (modify_this_stmt)
2625 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
2627 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
2628 ??? This should move to fold_stmt which we simply should
2629 call after building a VIEW_CONVERT_EXPR here. */
2630 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
2631 && !access_has_children_p (lacc))
2633 tree expr = lhs;
2634 if (build_ref_for_offset (&expr, TREE_TYPE (lhs), 0,
2635 TREE_TYPE (rhs), false))
2637 lhs = expr;
2638 gimple_assign_set_lhs (*stmt, expr);
2641 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
2642 && !access_has_children_p (racc))
2644 tree expr = rhs;
2645 if (build_ref_for_offset (&expr, TREE_TYPE (rhs), 0,
2646 TREE_TYPE (lhs), false))
2647 rhs = expr;
2649 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
2651 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs);
2652 if (is_gimple_reg_type (TREE_TYPE (lhs))
2653 && TREE_CODE (lhs) != SSA_NAME)
2654 force_gimple_rhs = true;
2659 /* From this point on, the function deals with assignments in between
2660 aggregates when at least one has scalar reductions of some of its
2661 components. There are three possible scenarios: Both the LHS and RHS have
2662 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
2664 In the first case, we would like to load the LHS components from RHS
2665 components whenever possible. If that is not possible, we would like to
2666 read it directly from the RHS (after updating it by storing in it its own
2667 components). If there are some necessary unscalarized data in the LHS,
2668 those will be loaded by the original assignment too. If neither of these
2669 cases happen, the original statement can be removed. Most of this is done
2670 by load_assign_lhs_subreplacements.
2672 In the second case, we would like to store all RHS scalarized components
2673 directly into LHS and if they cover the aggregate completely, remove the
2674 statement too. In the third case, we want the LHS components to be loaded
2675 directly from the RHS (DSE will remove the original statement if it
2676 becomes redundant).
2678 This is a bit complex but manageable when types match and when unions do
2679 not cause confusion in a way that we cannot really load a component of LHS
2680 from the RHS or vice versa (the access representing this level can have
2681 subaccesses that are accessible only through a different union field at a
2682 higher level - different from the one used in the examined expression).
2683 Unions are fun.
2685 Therefore, I specially handle a fourth case, happening when there is a
2686 specific type cast or it is impossible to locate a scalarized subaccess on
2687 the other side of the expression. If that happens, I simply "refresh" the
2688 RHS by storing in it is scalarized components leave the original statement
2689 there to do the copying and then load the scalar replacements of the LHS.
2690 This is what the first branch does. */
2692 if (gimple_has_volatile_ops (*stmt)
2693 || contains_view_convert_expr_p (rhs)
2694 || contains_view_convert_expr_p (lhs)
2695 || (access_has_children_p (racc)
2696 && !ref_expr_for_all_replacements_p (racc, lhs, racc->offset))
2697 || (access_has_children_p (lacc)
2698 && !ref_expr_for_all_replacements_p (lacc, rhs, lacc->offset)))
2700 if (access_has_children_p (racc))
2701 generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
2702 gsi, false, false);
2703 if (access_has_children_p (lacc))
2704 generate_subtree_copies (lacc->first_child, lacc->base, 0, 0, 0,
2705 gsi, true, true);
2706 sra_stats.separate_lhs_rhs_handling++;
2708 else
2710 if (access_has_children_p (lacc) && access_has_children_p (racc))
2712 gimple_stmt_iterator orig_gsi = *gsi;
2713 enum unscalarized_data_handling refreshed;
2715 if (lacc->grp_read && !lacc->grp_covered)
2716 refreshed = handle_unscalarized_data_in_subtree (racc, lhs, gsi);
2717 else
2718 refreshed = SRA_UDH_NONE;
2720 load_assign_lhs_subreplacements (lacc->first_child, racc,
2721 lacc->offset, racc->offset,
2722 &orig_gsi, gsi, &refreshed, lhs);
2723 if (refreshed != SRA_UDH_RIGHT)
2725 if (*stmt == gsi_stmt (*gsi))
2726 gsi_next (gsi);
2728 unlink_stmt_vdef (*stmt);
2729 gsi_remove (&orig_gsi, true);
2730 sra_stats.deleted++;
2731 return SRA_AM_REMOVED;
2734 else
2736 if (racc)
2738 if (!racc->grp_to_be_replaced && !racc->grp_unscalarized_data)
2740 if (racc->first_child)
2741 generate_subtree_copies (racc->first_child, lhs,
2742 racc->offset, 0, 0, gsi,
2743 false, false);
2744 gcc_assert (*stmt == gsi_stmt (*gsi));
2745 if (TREE_CODE (lhs) == SSA_NAME)
2746 replace_uses_with_default_def_ssa_name (lhs, racc);
2748 unlink_stmt_vdef (*stmt);
2749 gsi_remove (gsi, true);
2750 sra_stats.deleted++;
2751 return SRA_AM_REMOVED;
2753 else if (racc->first_child)
2754 generate_subtree_copies (racc->first_child, lhs,
2755 racc->offset, 0, 0, gsi, false, true);
2757 if (access_has_children_p (lacc))
2758 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
2759 0, 0, gsi, true, true);
2763 /* This gimplification must be done after generate_subtree_copies, lest we
2764 insert the subtree copies in the middle of the gimplified sequence. */
2765 if (force_gimple_rhs)
2766 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
2767 true, GSI_SAME_STMT);
2768 if (gimple_assign_rhs1 (*stmt) != rhs)
2770 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
2771 gcc_assert (*stmt == gsi_stmt (orig_gsi));
2774 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
2777 /* Traverse the function body and all modifications as decided in
2778 analyze_all_variable_accesses. */
2780 static void
2781 sra_modify_function_body (void)
2783 basic_block bb;
2785 FOR_EACH_BB (bb)
2787 gimple_stmt_iterator gsi = gsi_start_bb (bb);
2788 while (!gsi_end_p (gsi))
2790 gimple stmt = gsi_stmt (gsi);
2791 enum assignment_mod_result assign_result;
2792 bool modified = false, deleted = false;
2793 tree *t;
2794 unsigned i;
2796 switch (gimple_code (stmt))
2798 case GIMPLE_RETURN:
2799 t = gimple_return_retval_ptr (stmt);
2800 if (*t != NULL_TREE)
2801 modified |= sra_modify_expr (t, &gsi, false);
2802 break;
2804 case GIMPLE_ASSIGN:
2805 assign_result = sra_modify_assign (&stmt, &gsi);
2806 modified |= assign_result == SRA_AM_MODIFIED;
2807 deleted = assign_result == SRA_AM_REMOVED;
2808 break;
2810 case GIMPLE_CALL:
2811 /* Operands must be processed before the lhs. */
2812 for (i = 0; i < gimple_call_num_args (stmt); i++)
2814 t = gimple_call_arg_ptr (stmt, i);
2815 modified |= sra_modify_expr (t, &gsi, false);
2818 if (gimple_call_lhs (stmt))
2820 t = gimple_call_lhs_ptr (stmt);
2821 modified |= sra_modify_expr (t, &gsi, true);
2823 break;
2825 case GIMPLE_ASM:
2826 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
2828 t = &TREE_VALUE (gimple_asm_input_op (stmt, i));
2829 modified |= sra_modify_expr (t, &gsi, false);
2831 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
2833 t = &TREE_VALUE (gimple_asm_output_op (stmt, i));
2834 modified |= sra_modify_expr (t, &gsi, true);
2836 break;
2838 default:
2839 break;
2842 if (modified)
2844 update_stmt (stmt);
2845 maybe_clean_eh_stmt (stmt);
2847 if (!deleted)
2848 gsi_next (&gsi);
2853 /* Generate statements initializing scalar replacements of parts of function
2854 parameters. */
2856 static void
2857 initialize_parameter_reductions (void)
2859 gimple_stmt_iterator gsi;
2860 gimple_seq seq = NULL;
2861 tree parm;
2863 for (parm = DECL_ARGUMENTS (current_function_decl);
2864 parm;
2865 parm = DECL_CHAIN (parm))
2867 VEC (access_p, heap) *access_vec;
2868 struct access *access;
2870 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
2871 continue;
2872 access_vec = get_base_access_vector (parm);
2873 if (!access_vec)
2874 continue;
2876 if (!seq)
2878 seq = gimple_seq_alloc ();
2879 gsi = gsi_start (seq);
2882 for (access = VEC_index (access_p, access_vec, 0);
2883 access;
2884 access = access->next_grp)
2885 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true);
2888 if (seq)
2889 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR), seq);
2892 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
2893 it reveals there are components of some aggregates to be scalarized, it runs
2894 the required transformations. */
2895 static unsigned int
2896 perform_intra_sra (void)
2898 int ret = 0;
2899 sra_initialize ();
2901 if (!find_var_candidates ())
2902 goto out;
2904 if (!scan_function ())
2905 goto out;
2907 if (!analyze_all_variable_accesses ())
2908 goto out;
2910 sra_modify_function_body ();
2911 initialize_parameter_reductions ();
2913 statistics_counter_event (cfun, "Scalar replacements created",
2914 sra_stats.replacements);
2915 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
2916 statistics_counter_event (cfun, "Subtree copy stmts",
2917 sra_stats.subtree_copies);
2918 statistics_counter_event (cfun, "Subreplacement stmts",
2919 sra_stats.subreplacements);
2920 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
2921 statistics_counter_event (cfun, "Separate LHS and RHS handling",
2922 sra_stats.separate_lhs_rhs_handling);
2924 ret = TODO_update_ssa;
2926 out:
2927 sra_deinitialize ();
2928 return ret;
2931 /* Perform early intraprocedural SRA. */
2932 static unsigned int
2933 early_intra_sra (void)
2935 sra_mode = SRA_MODE_EARLY_INTRA;
2936 return perform_intra_sra ();
2939 /* Perform "late" intraprocedural SRA. */
2940 static unsigned int
2941 late_intra_sra (void)
2943 sra_mode = SRA_MODE_INTRA;
2944 return perform_intra_sra ();
2948 static bool
2949 gate_intra_sra (void)
2951 return flag_tree_sra != 0 && dbg_cnt (tree_sra);
2955 struct gimple_opt_pass pass_sra_early =
2958 GIMPLE_PASS,
2959 "esra", /* name */
2960 gate_intra_sra, /* gate */
2961 early_intra_sra, /* execute */
2962 NULL, /* sub */
2963 NULL, /* next */
2964 0, /* static_pass_number */
2965 TV_TREE_SRA, /* tv_id */
2966 PROP_cfg | PROP_ssa, /* properties_required */
2967 0, /* properties_provided */
2968 0, /* properties_destroyed */
2969 0, /* todo_flags_start */
2970 TODO_dump_func
2971 | TODO_update_ssa
2972 | TODO_ggc_collect
2973 | TODO_verify_ssa /* todo_flags_finish */
2977 struct gimple_opt_pass pass_sra =
2980 GIMPLE_PASS,
2981 "sra", /* name */
2982 gate_intra_sra, /* gate */
2983 late_intra_sra, /* execute */
2984 NULL, /* sub */
2985 NULL, /* next */
2986 0, /* static_pass_number */
2987 TV_TREE_SRA, /* tv_id */
2988 PROP_cfg | PROP_ssa, /* properties_required */
2989 0, /* properties_provided */
2990 0, /* properties_destroyed */
2991 TODO_update_address_taken, /* todo_flags_start */
2992 TODO_dump_func
2993 | TODO_update_ssa
2994 | TODO_ggc_collect
2995 | TODO_verify_ssa /* todo_flags_finish */
3000 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3001 parameter. */
3003 static bool
3004 is_unused_scalar_param (tree parm)
3006 tree name;
3007 return (is_gimple_reg (parm)
3008 && (!(name = gimple_default_def (cfun, parm))
3009 || has_zero_uses (name)));
3012 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3013 examine whether there are any direct or otherwise infeasible ones. If so,
3014 return true, otherwise return false. PARM must be a gimple register with a
3015 non-NULL default definition. */
3017 static bool
3018 ptr_parm_has_direct_uses (tree parm)
3020 imm_use_iterator ui;
3021 gimple stmt;
3022 tree name = gimple_default_def (cfun, parm);
3023 bool ret = false;
3025 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
3027 int uses_ok = 0;
3028 use_operand_p use_p;
3030 if (is_gimple_debug (stmt))
3031 continue;
3033 /* Valid uses include dereferences on the lhs and the rhs. */
3034 if (gimple_has_lhs (stmt))
3036 tree lhs = gimple_get_lhs (stmt);
3037 while (handled_component_p (lhs))
3038 lhs = TREE_OPERAND (lhs, 0);
3039 if (TREE_CODE (lhs) == MEM_REF
3040 && TREE_OPERAND (lhs, 0) == name
3041 && integer_zerop (TREE_OPERAND (lhs, 1))
3042 && types_compatible_p (TREE_TYPE (lhs),
3043 TREE_TYPE (TREE_TYPE (name))))
3044 uses_ok++;
3046 if (gimple_assign_single_p (stmt))
3048 tree rhs = gimple_assign_rhs1 (stmt);
3049 while (handled_component_p (rhs))
3050 rhs = TREE_OPERAND (rhs, 0);
3051 if (TREE_CODE (rhs) == MEM_REF
3052 && TREE_OPERAND (rhs, 0) == name
3053 && integer_zerop (TREE_OPERAND (rhs, 1))
3054 && types_compatible_p (TREE_TYPE (rhs),
3055 TREE_TYPE (TREE_TYPE (name))))
3056 uses_ok++;
3058 else if (is_gimple_call (stmt))
3060 unsigned i;
3061 for (i = 0; i < gimple_call_num_args (stmt); ++i)
3063 tree arg = gimple_call_arg (stmt, i);
3064 while (handled_component_p (arg))
3065 arg = TREE_OPERAND (arg, 0);
3066 if (TREE_CODE (arg) == MEM_REF
3067 && TREE_OPERAND (arg, 0) == name
3068 && integer_zerop (TREE_OPERAND (arg, 1))
3069 && types_compatible_p (TREE_TYPE (arg),
3070 TREE_TYPE (TREE_TYPE (name))))
3071 uses_ok++;
3075 /* If the number of valid uses does not match the number of
3076 uses in this stmt there is an unhandled use. */
3077 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
3078 --uses_ok;
3080 if (uses_ok != 0)
3081 ret = true;
3083 if (ret)
3084 BREAK_FROM_IMM_USE_STMT (ui);
3087 return ret;
3090 /* Identify candidates for reduction for IPA-SRA based on their type and mark
3091 them in candidate_bitmap. Note that these do not necessarily include
3092 parameter which are unused and thus can be removed. Return true iff any
3093 such candidate has been found. */
3095 static bool
3096 find_param_candidates (void)
3098 tree parm;
3099 int count = 0;
3100 bool ret = false;
3102 for (parm = DECL_ARGUMENTS (current_function_decl);
3103 parm;
3104 parm = DECL_CHAIN (parm))
3106 tree type = TREE_TYPE (parm);
3108 count++;
3110 if (TREE_THIS_VOLATILE (parm)
3111 || TREE_ADDRESSABLE (parm)
3112 || (!is_gimple_reg_type (type) && is_va_list_type (type)))
3113 continue;
3115 if (is_unused_scalar_param (parm))
3117 ret = true;
3118 continue;
3121 if (POINTER_TYPE_P (type))
3123 type = TREE_TYPE (type);
3125 if (TREE_CODE (type) == FUNCTION_TYPE
3126 || TYPE_VOLATILE (type)
3127 || !is_gimple_reg (parm)
3128 || is_va_list_type (type)
3129 || ptr_parm_has_direct_uses (parm))
3130 continue;
3132 else if (!AGGREGATE_TYPE_P (type))
3133 continue;
3135 if (!COMPLETE_TYPE_P (type)
3136 || !host_integerp (TYPE_SIZE (type), 1)
3137 || tree_low_cst (TYPE_SIZE (type), 1) == 0
3138 || (AGGREGATE_TYPE_P (type)
3139 && type_internals_preclude_sra_p (type)))
3140 continue;
3142 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
3143 ret = true;
3144 if (dump_file && (dump_flags & TDF_DETAILS))
3146 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
3147 print_generic_expr (dump_file, parm, 0);
3148 fprintf (dump_file, "\n");
3152 func_param_count = count;
3153 return ret;
3156 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
3157 maybe_modified. */
3159 static bool
3160 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
3161 void *data)
3163 struct access *repr = (struct access *) data;
3165 repr->grp_maybe_modified = 1;
3166 return true;
3169 /* Analyze what representatives (in linked lists accessible from
3170 REPRESENTATIVES) can be modified by side effects of statements in the
3171 current function. */
3173 static void
3174 analyze_modified_params (VEC (access_p, heap) *representatives)
3176 int i;
3178 for (i = 0; i < func_param_count; i++)
3180 struct access *repr;
3182 for (repr = VEC_index (access_p, representatives, i);
3183 repr;
3184 repr = repr->next_grp)
3186 struct access *access;
3187 bitmap visited;
3188 ao_ref ar;
3190 if (no_accesses_p (repr))
3191 continue;
3192 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
3193 || repr->grp_maybe_modified)
3194 continue;
3196 ao_ref_init (&ar, repr->expr);
3197 visited = BITMAP_ALLOC (NULL);
3198 for (access = repr; access; access = access->next_sibling)
3200 /* All accesses are read ones, otherwise grp_maybe_modified would
3201 be trivially set. */
3202 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
3203 mark_maybe_modified, repr, &visited);
3204 if (repr->grp_maybe_modified)
3205 break;
3207 BITMAP_FREE (visited);
3212 /* Propagate distances in bb_dereferences in the opposite direction than the
3213 control flow edges, in each step storing the maximum of the current value
3214 and the minimum of all successors. These steps are repeated until the table
3215 stabilizes. Note that BBs which might terminate the functions (according to
3216 final_bbs bitmap) never updated in this way. */
3218 static void
3219 propagate_dereference_distances (void)
3221 VEC (basic_block, heap) *queue;
3222 basic_block bb;
3224 queue = VEC_alloc (basic_block, heap, last_basic_block_for_function (cfun));
3225 VEC_quick_push (basic_block, queue, ENTRY_BLOCK_PTR);
3226 FOR_EACH_BB (bb)
3228 VEC_quick_push (basic_block, queue, bb);
3229 bb->aux = bb;
3232 while (!VEC_empty (basic_block, queue))
3234 edge_iterator ei;
3235 edge e;
3236 bool change = false;
3237 int i;
3239 bb = VEC_pop (basic_block, queue);
3240 bb->aux = NULL;
3242 if (bitmap_bit_p (final_bbs, bb->index))
3243 continue;
3245 for (i = 0; i < func_param_count; i++)
3247 int idx = bb->index * func_param_count + i;
3248 bool first = true;
3249 HOST_WIDE_INT inh = 0;
3251 FOR_EACH_EDGE (e, ei, bb->succs)
3253 int succ_idx = e->dest->index * func_param_count + i;
3255 if (e->src == EXIT_BLOCK_PTR)
3256 continue;
3258 if (first)
3260 first = false;
3261 inh = bb_dereferences [succ_idx];
3263 else if (bb_dereferences [succ_idx] < inh)
3264 inh = bb_dereferences [succ_idx];
3267 if (!first && bb_dereferences[idx] < inh)
3269 bb_dereferences[idx] = inh;
3270 change = true;
3274 if (change && !bitmap_bit_p (final_bbs, bb->index))
3275 FOR_EACH_EDGE (e, ei, bb->preds)
3277 if (e->src->aux)
3278 continue;
3280 e->src->aux = e->src;
3281 VEC_quick_push (basic_block, queue, e->src);
3285 VEC_free (basic_block, heap, queue);
3288 /* Dump a dereferences TABLE with heading STR to file F. */
3290 static void
3291 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
3293 basic_block bb;
3295 fprintf (dump_file, str);
3296 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
3298 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
3299 if (bb != EXIT_BLOCK_PTR)
3301 int i;
3302 for (i = 0; i < func_param_count; i++)
3304 int idx = bb->index * func_param_count + i;
3305 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
3308 fprintf (f, "\n");
3310 fprintf (dump_file, "\n");
3313 /* Determine what (parts of) parameters passed by reference that are not
3314 assigned to are not certainly dereferenced in this function and thus the
3315 dereferencing cannot be safely moved to the caller without potentially
3316 introducing a segfault. Mark such REPRESENTATIVES as
3317 grp_not_necessarilly_dereferenced.
3319 The dereferenced maximum "distance," i.e. the offset + size of the accessed
3320 part is calculated rather than simple booleans are calculated for each
3321 pointer parameter to handle cases when only a fraction of the whole
3322 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
3323 an example).
3325 The maximum dereference distances for each pointer parameter and BB are
3326 already stored in bb_dereference. This routine simply propagates these
3327 values upwards by propagate_dereference_distances and then compares the
3328 distances of individual parameters in the ENTRY BB to the equivalent
3329 distances of each representative of a (fraction of a) parameter. */
3331 static void
3332 analyze_caller_dereference_legality (VEC (access_p, heap) *representatives)
3334 int i;
3336 if (dump_file && (dump_flags & TDF_DETAILS))
3337 dump_dereferences_table (dump_file,
3338 "Dereference table before propagation:\n",
3339 bb_dereferences);
3341 propagate_dereference_distances ();
3343 if (dump_file && (dump_flags & TDF_DETAILS))
3344 dump_dereferences_table (dump_file,
3345 "Dereference table after propagation:\n",
3346 bb_dereferences);
3348 for (i = 0; i < func_param_count; i++)
3350 struct access *repr = VEC_index (access_p, representatives, i);
3351 int idx = ENTRY_BLOCK_PTR->index * func_param_count + i;
3353 if (!repr || no_accesses_p (repr))
3354 continue;
3358 if ((repr->offset + repr->size) > bb_dereferences[idx])
3359 repr->grp_not_necessarilly_dereferenced = 1;
3360 repr = repr->next_grp;
3362 while (repr);
3366 /* Return the representative access for the parameter declaration PARM if it is
3367 a scalar passed by reference which is not written to and the pointer value
3368 is not used directly. Thus, if it is legal to dereference it in the caller
3369 and we can rule out modifications through aliases, such parameter should be
3370 turned into one passed by value. Return NULL otherwise. */
3372 static struct access *
3373 unmodified_by_ref_scalar_representative (tree parm)
3375 int i, access_count;
3376 struct access *repr;
3377 VEC (access_p, heap) *access_vec;
3379 access_vec = get_base_access_vector (parm);
3380 gcc_assert (access_vec);
3381 repr = VEC_index (access_p, access_vec, 0);
3382 if (repr->write)
3383 return NULL;
3384 repr->group_representative = repr;
3386 access_count = VEC_length (access_p, access_vec);
3387 for (i = 1; i < access_count; i++)
3389 struct access *access = VEC_index (access_p, access_vec, i);
3390 if (access->write)
3391 return NULL;
3392 access->group_representative = repr;
3393 access->next_sibling = repr->next_sibling;
3394 repr->next_sibling = access;
3397 repr->grp_read = 1;
3398 repr->grp_scalar_ptr = 1;
3399 return repr;
3402 /* Return true iff this access precludes IPA-SRA of the parameter it is
3403 associated with. */
3405 static bool
3406 access_precludes_ipa_sra_p (struct access *access)
3408 /* Avoid issues such as the second simple testcase in PR 42025. The problem
3409 is incompatible assign in a call statement (and possibly even in asm
3410 statements). This can be relaxed by using a new temporary but only for
3411 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
3412 intraprocedural SRA we deal with this by keeping the old aggregate around,
3413 something we cannot do in IPA-SRA.) */
3414 if (access->write
3415 && (is_gimple_call (access->stmt)
3416 || gimple_code (access->stmt) == GIMPLE_ASM))
3417 return true;
3419 return false;
3423 /* Sort collected accesses for parameter PARM, identify representatives for
3424 each accessed region and link them together. Return NULL if there are
3425 different but overlapping accesses, return the special ptr value meaning
3426 there are no accesses for this parameter if that is the case and return the
3427 first representative otherwise. Set *RO_GRP if there is a group of accesses
3428 with only read (i.e. no write) accesses. */
3430 static struct access *
3431 splice_param_accesses (tree parm, bool *ro_grp)
3433 int i, j, access_count, group_count;
3434 int agg_size, total_size = 0;
3435 struct access *access, *res, **prev_acc_ptr = &res;
3436 VEC (access_p, heap) *access_vec;
3438 access_vec = get_base_access_vector (parm);
3439 if (!access_vec)
3440 return &no_accesses_representant;
3441 access_count = VEC_length (access_p, access_vec);
3443 qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
3444 compare_access_positions);
3446 i = 0;
3447 total_size = 0;
3448 group_count = 0;
3449 while (i < access_count)
3451 bool modification;
3452 access = VEC_index (access_p, access_vec, i);
3453 modification = access->write;
3454 if (access_precludes_ipa_sra_p (access))
3455 return NULL;
3457 /* Access is about to become group representative unless we find some
3458 nasty overlap which would preclude us from breaking this parameter
3459 apart. */
3461 j = i + 1;
3462 while (j < access_count)
3464 struct access *ac2 = VEC_index (access_p, access_vec, j);
3465 if (ac2->offset != access->offset)
3467 /* All or nothing law for parameters. */
3468 if (access->offset + access->size > ac2->offset)
3469 return NULL;
3470 else
3471 break;
3473 else if (ac2->size != access->size)
3474 return NULL;
3476 if (access_precludes_ipa_sra_p (ac2))
3477 return NULL;
3479 modification |= ac2->write;
3480 ac2->group_representative = access;
3481 ac2->next_sibling = access->next_sibling;
3482 access->next_sibling = ac2;
3483 j++;
3486 group_count++;
3487 access->grp_maybe_modified = modification;
3488 if (!modification)
3489 *ro_grp = true;
3490 *prev_acc_ptr = access;
3491 prev_acc_ptr = &access->next_grp;
3492 total_size += access->size;
3493 i = j;
3496 if (POINTER_TYPE_P (TREE_TYPE (parm)))
3497 agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))), 1);
3498 else
3499 agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (parm)), 1);
3500 if (total_size >= agg_size)
3501 return NULL;
3503 gcc_assert (group_count > 0);
3504 return res;
3507 /* Decide whether parameters with representative accesses given by REPR should
3508 be reduced into components. */
3510 static int
3511 decide_one_param_reduction (struct access *repr)
3513 int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
3514 bool by_ref;
3515 tree parm;
3517 parm = repr->base;
3518 cur_parm_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (parm)), 1);
3519 gcc_assert (cur_parm_size > 0);
3521 if (POINTER_TYPE_P (TREE_TYPE (parm)))
3523 by_ref = true;
3524 agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))), 1);
3526 else
3528 by_ref = false;
3529 agg_size = cur_parm_size;
3532 if (dump_file)
3534 struct access *acc;
3535 fprintf (dump_file, "Evaluating PARAM group sizes for ");
3536 print_generic_expr (dump_file, parm, 0);
3537 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
3538 for (acc = repr; acc; acc = acc->next_grp)
3539 dump_access (dump_file, acc, true);
3542 total_size = 0;
3543 new_param_count = 0;
3545 for (; repr; repr = repr->next_grp)
3547 gcc_assert (parm == repr->base);
3548 new_param_count++;
3550 if (!by_ref || (!repr->grp_maybe_modified
3551 && !repr->grp_not_necessarilly_dereferenced))
3552 total_size += repr->size;
3553 else
3554 total_size += cur_parm_size;
3557 gcc_assert (new_param_count > 0);
3559 if (optimize_function_for_size_p (cfun))
3560 parm_size_limit = cur_parm_size;
3561 else
3562 parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
3563 * cur_parm_size);
3565 if (total_size < agg_size
3566 && total_size <= parm_size_limit)
3568 if (dump_file)
3569 fprintf (dump_file, " ....will be split into %i components\n",
3570 new_param_count);
3571 return new_param_count;
3573 else
3574 return 0;
3577 /* The order of the following enums is important, we need to do extra work for
3578 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
3579 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
3580 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
3582 /* Identify representatives of all accesses to all candidate parameters for
3583 IPA-SRA. Return result based on what representatives have been found. */
3585 static enum ipa_splicing_result
3586 splice_all_param_accesses (VEC (access_p, heap) **representatives)
3588 enum ipa_splicing_result result = NO_GOOD_ACCESS;
3589 tree parm;
3590 struct access *repr;
3592 *representatives = VEC_alloc (access_p, heap, func_param_count);
3594 for (parm = DECL_ARGUMENTS (current_function_decl);
3595 parm;
3596 parm = DECL_CHAIN (parm))
3598 if (is_unused_scalar_param (parm))
3600 VEC_quick_push (access_p, *representatives,
3601 &no_accesses_representant);
3602 if (result == NO_GOOD_ACCESS)
3603 result = UNUSED_PARAMS;
3605 else if (POINTER_TYPE_P (TREE_TYPE (parm))
3606 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
3607 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3609 repr = unmodified_by_ref_scalar_representative (parm);
3610 VEC_quick_push (access_p, *representatives, repr);
3611 if (repr)
3612 result = UNMODIF_BY_REF_ACCESSES;
3614 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3616 bool ro_grp = false;
3617 repr = splice_param_accesses (parm, &ro_grp);
3618 VEC_quick_push (access_p, *representatives, repr);
3620 if (repr && !no_accesses_p (repr))
3622 if (POINTER_TYPE_P (TREE_TYPE (parm)))
3624 if (ro_grp)
3625 result = UNMODIF_BY_REF_ACCESSES;
3626 else if (result < MODIF_BY_REF_ACCESSES)
3627 result = MODIF_BY_REF_ACCESSES;
3629 else if (result < BY_VAL_ACCESSES)
3630 result = BY_VAL_ACCESSES;
3632 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
3633 result = UNUSED_PARAMS;
3635 else
3636 VEC_quick_push (access_p, *representatives, NULL);
3639 if (result == NO_GOOD_ACCESS)
3641 VEC_free (access_p, heap, *representatives);
3642 *representatives = NULL;
3643 return NO_GOOD_ACCESS;
3646 return result;
3649 /* Return the index of BASE in PARMS. Abort if it is not found. */
3651 static inline int
3652 get_param_index (tree base, VEC(tree, heap) *parms)
3654 int i, len;
3656 len = VEC_length (tree, parms);
3657 for (i = 0; i < len; i++)
3658 if (VEC_index (tree, parms, i) == base)
3659 return i;
3660 gcc_unreachable ();
3663 /* Convert the decisions made at the representative level into compact
3664 parameter adjustments. REPRESENTATIVES are pointers to first
3665 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
3666 final number of adjustments. */
3668 static ipa_parm_adjustment_vec
3669 turn_representatives_into_adjustments (VEC (access_p, heap) *representatives,
3670 int adjustments_count)
3672 VEC (tree, heap) *parms;
3673 ipa_parm_adjustment_vec adjustments;
3674 tree parm;
3675 int i;
3677 gcc_assert (adjustments_count > 0);
3678 parms = ipa_get_vector_of_formal_parms (current_function_decl);
3679 adjustments = VEC_alloc (ipa_parm_adjustment_t, heap, adjustments_count);
3680 parm = DECL_ARGUMENTS (current_function_decl);
3681 for (i = 0; i < func_param_count; i++, parm = DECL_CHAIN (parm))
3683 struct access *repr = VEC_index (access_p, representatives, i);
3685 if (!repr || no_accesses_p (repr))
3687 struct ipa_parm_adjustment *adj;
3689 adj = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
3690 memset (adj, 0, sizeof (*adj));
3691 adj->base_index = get_param_index (parm, parms);
3692 adj->base = parm;
3693 if (!repr)
3694 adj->copy_param = 1;
3695 else
3696 adj->remove_param = 1;
3698 else
3700 struct ipa_parm_adjustment *adj;
3701 int index = get_param_index (parm, parms);
3703 for (; repr; repr = repr->next_grp)
3705 adj = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
3706 memset (adj, 0, sizeof (*adj));
3707 gcc_assert (repr->base == parm);
3708 adj->base_index = index;
3709 adj->base = repr->base;
3710 adj->type = repr->type;
3711 adj->offset = repr->offset;
3712 adj->by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
3713 && (repr->grp_maybe_modified
3714 || repr->grp_not_necessarilly_dereferenced));
3719 VEC_free (tree, heap, parms);
3720 return adjustments;
3723 /* Analyze the collected accesses and produce a plan what to do with the
3724 parameters in the form of adjustments, NULL meaning nothing. */
3726 static ipa_parm_adjustment_vec
3727 analyze_all_param_acesses (void)
3729 enum ipa_splicing_result repr_state;
3730 bool proceed = false;
3731 int i, adjustments_count = 0;
3732 VEC (access_p, heap) *representatives;
3733 ipa_parm_adjustment_vec adjustments;
3735 repr_state = splice_all_param_accesses (&representatives);
3736 if (repr_state == NO_GOOD_ACCESS)
3737 return NULL;
3739 /* If there are any parameters passed by reference which are not modified
3740 directly, we need to check whether they can be modified indirectly. */
3741 if (repr_state == UNMODIF_BY_REF_ACCESSES)
3743 analyze_caller_dereference_legality (representatives);
3744 analyze_modified_params (representatives);
3747 for (i = 0; i < func_param_count; i++)
3749 struct access *repr = VEC_index (access_p, representatives, i);
3751 if (repr && !no_accesses_p (repr))
3753 if (repr->grp_scalar_ptr)
3755 adjustments_count++;
3756 if (repr->grp_not_necessarilly_dereferenced
3757 || repr->grp_maybe_modified)
3758 VEC_replace (access_p, representatives, i, NULL);
3759 else
3761 proceed = true;
3762 sra_stats.scalar_by_ref_to_by_val++;
3765 else
3767 int new_components = decide_one_param_reduction (repr);
3769 if (new_components == 0)
3771 VEC_replace (access_p, representatives, i, NULL);
3772 adjustments_count++;
3774 else
3776 adjustments_count += new_components;
3777 sra_stats.aggregate_params_reduced++;
3778 sra_stats.param_reductions_created += new_components;
3779 proceed = true;
3783 else
3785 if (no_accesses_p (repr))
3787 proceed = true;
3788 sra_stats.deleted_unused_parameters++;
3790 adjustments_count++;
3794 if (!proceed && dump_file)
3795 fprintf (dump_file, "NOT proceeding to change params.\n");
3797 if (proceed)
3798 adjustments = turn_representatives_into_adjustments (representatives,
3799 adjustments_count);
3800 else
3801 adjustments = NULL;
3803 VEC_free (access_p, heap, representatives);
3804 return adjustments;
3807 /* If a parameter replacement identified by ADJ does not yet exist in the form
3808 of declaration, create it and record it, otherwise return the previously
3809 created one. */
3811 static tree
3812 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
3814 tree repl;
3815 if (!adj->new_ssa_base)
3817 char *pretty_name = make_fancy_name (adj->base);
3819 repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR");
3820 DECL_NAME (repl) = get_identifier (pretty_name);
3821 obstack_free (&name_obstack, pretty_name);
3823 get_var_ann (repl);
3824 add_referenced_var (repl);
3825 adj->new_ssa_base = repl;
3827 else
3828 repl = adj->new_ssa_base;
3829 return repl;
3832 /* Find the first adjustment for a particular parameter BASE in a vector of
3833 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
3834 adjustment. */
3836 static struct ipa_parm_adjustment *
3837 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
3839 int i, len;
3841 len = VEC_length (ipa_parm_adjustment_t, adjustments);
3842 for (i = 0; i < len; i++)
3844 struct ipa_parm_adjustment *adj;
3846 adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3847 if (!adj->copy_param && adj->base == base)
3848 return adj;
3851 return NULL;
3854 /* If the statement STMT defines an SSA_NAME of a parameter which is to be
3855 removed because its value is not used, replace the SSA_NAME with a one
3856 relating to a created VAR_DECL together all of its uses and return true.
3857 ADJUSTMENTS is a pointer to an adjustments vector. */
3859 static bool
3860 replace_removed_params_ssa_names (gimple stmt,
3861 ipa_parm_adjustment_vec adjustments)
3863 struct ipa_parm_adjustment *adj;
3864 tree lhs, decl, repl, name;
3866 if (gimple_code (stmt) == GIMPLE_PHI)
3867 lhs = gimple_phi_result (stmt);
3868 else if (is_gimple_assign (stmt))
3869 lhs = gimple_assign_lhs (stmt);
3870 else if (is_gimple_call (stmt))
3871 lhs = gimple_call_lhs (stmt);
3872 else
3873 gcc_unreachable ();
3875 if (TREE_CODE (lhs) != SSA_NAME)
3876 return false;
3877 decl = SSA_NAME_VAR (lhs);
3878 if (TREE_CODE (decl) != PARM_DECL)
3879 return false;
3881 adj = get_adjustment_for_base (adjustments, decl);
3882 if (!adj)
3883 return false;
3885 repl = get_replaced_param_substitute (adj);
3886 name = make_ssa_name (repl, stmt);
3888 if (dump_file)
3890 fprintf (dump_file, "replacing an SSA name of a removed param ");
3891 print_generic_expr (dump_file, lhs, 0);
3892 fprintf (dump_file, " with ");
3893 print_generic_expr (dump_file, name, 0);
3894 fprintf (dump_file, "\n");
3897 if (is_gimple_assign (stmt))
3898 gimple_assign_set_lhs (stmt, name);
3899 else if (is_gimple_call (stmt))
3900 gimple_call_set_lhs (stmt, name);
3901 else
3902 gimple_phi_set_result (stmt, name);
3904 replace_uses_by (lhs, name);
3905 release_ssa_name (lhs);
3906 return true;
3909 /* If the expression *EXPR should be replaced by a reduction of a parameter, do
3910 so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
3911 specifies whether the function should care about type incompatibility the
3912 current and new expressions. If it is false, the function will leave
3913 incompatibility issues to the caller. Return true iff the expression
3914 was modified. */
3916 static bool
3917 sra_ipa_modify_expr (tree *expr, bool convert,
3918 ipa_parm_adjustment_vec adjustments)
3920 int i, len;
3921 struct ipa_parm_adjustment *adj, *cand = NULL;
3922 HOST_WIDE_INT offset, size, max_size;
3923 tree base, src;
3925 len = VEC_length (ipa_parm_adjustment_t, adjustments);
3927 if (TREE_CODE (*expr) == BIT_FIELD_REF
3928 || TREE_CODE (*expr) == IMAGPART_EXPR
3929 || TREE_CODE (*expr) == REALPART_EXPR)
3931 expr = &TREE_OPERAND (*expr, 0);
3932 convert = true;
3935 base = get_ref_base_and_extent (*expr, &offset, &size, &max_size);
3936 if (!base || size == -1 || max_size == -1)
3937 return false;
3939 if (TREE_CODE (base) == MEM_REF)
3941 offset += mem_ref_offset (base).low * BITS_PER_UNIT;
3942 base = TREE_OPERAND (base, 0);
3945 base = get_ssa_base_param (base);
3946 if (!base || TREE_CODE (base) != PARM_DECL)
3947 return false;
3949 for (i = 0; i < len; i++)
3951 adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3953 if (adj->base == base &&
3954 (adj->offset == offset || adj->remove_param))
3956 cand = adj;
3957 break;
3960 if (!cand || cand->copy_param || cand->remove_param)
3961 return false;
3963 if (cand->by_ref)
3964 src = build_simple_mem_ref (cand->reduction);
3965 else
3966 src = cand->reduction;
3968 if (dump_file && (dump_flags & TDF_DETAILS))
3970 fprintf (dump_file, "About to replace expr ");
3971 print_generic_expr (dump_file, *expr, 0);
3972 fprintf (dump_file, " with ");
3973 print_generic_expr (dump_file, src, 0);
3974 fprintf (dump_file, "\n");
3977 if (convert && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
3979 tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
3980 *expr = vce;
3982 else
3983 *expr = src;
3984 return true;
3987 /* If the statement pointed to by STMT_PTR contains any expressions that need
3988 to replaced with a different one as noted by ADJUSTMENTS, do so. Handle any
3989 potential type incompatibilities (GSI is used to accommodate conversion
3990 statements and must point to the statement). Return true iff the statement
3991 was modified. */
3993 static bool
3994 sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi,
3995 ipa_parm_adjustment_vec adjustments)
3997 gimple stmt = *stmt_ptr;
3998 tree *lhs_p, *rhs_p;
3999 bool any;
4001 if (!gimple_assign_single_p (stmt))
4002 return false;
4004 rhs_p = gimple_assign_rhs1_ptr (stmt);
4005 lhs_p = gimple_assign_lhs_ptr (stmt);
4007 any = sra_ipa_modify_expr (rhs_p, false, adjustments);
4008 any |= sra_ipa_modify_expr (lhs_p, false, adjustments);
4009 if (any)
4011 tree new_rhs = NULL_TREE;
4013 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
4015 if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
4017 /* V_C_Es of constructors can cause trouble (PR 42714). */
4018 if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
4019 *rhs_p = fold_convert (TREE_TYPE (*lhs_p), integer_zero_node);
4020 else
4021 *rhs_p = build_constructor (TREE_TYPE (*lhs_p), 0);
4023 else
4024 new_rhs = fold_build1_loc (gimple_location (stmt),
4025 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
4026 *rhs_p);
4028 else if (REFERENCE_CLASS_P (*rhs_p)
4029 && is_gimple_reg_type (TREE_TYPE (*lhs_p))
4030 && !is_gimple_reg (*lhs_p))
4031 /* This can happen when an assignment in between two single field
4032 structures is turned into an assignment in between two pointers to
4033 scalars (PR 42237). */
4034 new_rhs = *rhs_p;
4036 if (new_rhs)
4038 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
4039 true, GSI_SAME_STMT);
4041 gimple_assign_set_rhs_from_tree (gsi, tmp);
4044 return true;
4047 return false;
4050 /* Traverse the function body and all modifications as described in
4051 ADJUSTMENTS. */
4053 static void
4054 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
4056 basic_block bb;
4058 FOR_EACH_BB (bb)
4060 gimple_stmt_iterator gsi;
4061 bool bb_changed = false;
4063 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4064 replace_removed_params_ssa_names (gsi_stmt (gsi), adjustments);
4066 gsi = gsi_start_bb (bb);
4067 while (!gsi_end_p (gsi))
4069 gimple stmt = gsi_stmt (gsi);
4070 bool modified = false;
4071 tree *t;
4072 unsigned i;
4074 switch (gimple_code (stmt))
4076 case GIMPLE_RETURN:
4077 t = gimple_return_retval_ptr (stmt);
4078 if (*t != NULL_TREE)
4079 modified |= sra_ipa_modify_expr (t, true, adjustments);
4080 break;
4082 case GIMPLE_ASSIGN:
4083 modified |= sra_ipa_modify_assign (&stmt, &gsi, adjustments);
4084 modified |= replace_removed_params_ssa_names (stmt, adjustments);
4085 break;
4087 case GIMPLE_CALL:
4088 /* Operands must be processed before the lhs. */
4089 for (i = 0; i < gimple_call_num_args (stmt); i++)
4091 t = gimple_call_arg_ptr (stmt, i);
4092 modified |= sra_ipa_modify_expr (t, true, adjustments);
4095 if (gimple_call_lhs (stmt))
4097 t = gimple_call_lhs_ptr (stmt);
4098 modified |= sra_ipa_modify_expr (t, false, adjustments);
4099 modified |= replace_removed_params_ssa_names (stmt,
4100 adjustments);
4102 break;
4104 case GIMPLE_ASM:
4105 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
4107 t = &TREE_VALUE (gimple_asm_input_op (stmt, i));
4108 modified |= sra_ipa_modify_expr (t, true, adjustments);
4110 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
4112 t = &TREE_VALUE (gimple_asm_output_op (stmt, i));
4113 modified |= sra_ipa_modify_expr (t, false, adjustments);
4115 break;
4117 default:
4118 break;
4121 if (modified)
4123 bb_changed = true;
4124 update_stmt (stmt);
4125 maybe_clean_eh_stmt (stmt);
4127 gsi_next (&gsi);
4129 if (bb_changed)
4130 gimple_purge_dead_eh_edges (bb);
4134 /* Call gimple_debug_bind_reset_value on all debug statements describing
4135 gimple register parameters that are being removed or replaced. */
4137 static void
4138 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
4140 int i, len;
4142 len = VEC_length (ipa_parm_adjustment_t, adjustments);
4143 for (i = 0; i < len; i++)
4145 struct ipa_parm_adjustment *adj;
4146 imm_use_iterator ui;
4147 gimple stmt;
4148 tree name;
4150 adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
4151 if (adj->copy_param || !is_gimple_reg (adj->base))
4152 continue;
4153 name = gimple_default_def (cfun, adj->base);
4154 if (!name)
4155 continue;
4156 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
4158 /* All other users must have been removed by
4159 ipa_sra_modify_function_body. */
4160 gcc_assert (is_gimple_debug (stmt));
4161 gimple_debug_bind_reset_value (stmt);
4162 update_stmt (stmt);
4167 /* Return true iff all callers have at least as many actual arguments as there
4168 are formal parameters in the current function. */
4170 static bool
4171 all_callers_have_enough_arguments_p (struct cgraph_node *node)
4173 struct cgraph_edge *cs;
4174 for (cs = node->callers; cs; cs = cs->next_caller)
4175 if (!callsite_has_enough_arguments_p (cs->call_stmt))
4176 return false;
4178 return true;
4182 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
4184 static void
4185 convert_callers (struct cgraph_node *node, tree old_decl,
4186 ipa_parm_adjustment_vec adjustments)
4188 tree old_cur_fndecl = current_function_decl;
4189 struct cgraph_edge *cs;
4190 basic_block this_block;
4191 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
4193 for (cs = node->callers; cs; cs = cs->next_caller)
4195 current_function_decl = cs->caller->decl;
4196 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
4198 if (dump_file)
4199 fprintf (dump_file, "Adjusting call (%i -> %i) %s -> %s\n",
4200 cs->caller->uid, cs->callee->uid,
4201 cgraph_node_name (cs->caller),
4202 cgraph_node_name (cs->callee));
4204 ipa_modify_call_arguments (cs, cs->call_stmt, adjustments);
4206 pop_cfun ();
4209 for (cs = node->callers; cs; cs = cs->next_caller)
4210 if (!bitmap_bit_p (recomputed_callers, cs->caller->uid))
4212 compute_inline_parameters (cs->caller);
4213 bitmap_set_bit (recomputed_callers, cs->caller->uid);
4215 BITMAP_FREE (recomputed_callers);
4217 current_function_decl = old_cur_fndecl;
4219 if (!encountered_recursive_call)
4220 return;
4222 FOR_EACH_BB (this_block)
4224 gimple_stmt_iterator gsi;
4226 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
4228 gimple stmt = gsi_stmt (gsi);
4229 tree call_fndecl;
4230 if (gimple_code (stmt) != GIMPLE_CALL)
4231 continue;
4232 call_fndecl = gimple_call_fndecl (stmt);
4233 if (call_fndecl == old_decl)
4235 if (dump_file)
4236 fprintf (dump_file, "Adjusting recursive call");
4237 gimple_call_set_fndecl (stmt, node->decl);
4238 ipa_modify_call_arguments (NULL, stmt, adjustments);
4243 return;
4246 /* Perform all the modification required in IPA-SRA for NODE to have parameters
4247 as given in ADJUSTMENTS. */
4249 static void
4250 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
4252 struct cgraph_node *new_node;
4253 struct cgraph_edge *cs;
4254 VEC (cgraph_edge_p, heap) * redirect_callers;
4255 int node_callers;
4257 node_callers = 0;
4258 for (cs = node->callers; cs != NULL; cs = cs->next_caller)
4259 node_callers++;
4260 redirect_callers = VEC_alloc (cgraph_edge_p, heap, node_callers);
4261 for (cs = node->callers; cs != NULL; cs = cs->next_caller)
4262 VEC_quick_push (cgraph_edge_p, redirect_callers, cs);
4264 rebuild_cgraph_edges ();
4265 pop_cfun ();
4266 current_function_decl = NULL_TREE;
4268 new_node = cgraph_function_versioning (node, redirect_callers, NULL, NULL,
4269 NULL, NULL, "isra");
4270 current_function_decl = new_node->decl;
4271 push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
4273 ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA");
4274 ipa_sra_modify_function_body (adjustments);
4275 sra_ipa_reset_debug_stmts (adjustments);
4276 convert_callers (new_node, node->decl, adjustments);
4277 cgraph_make_node_local (new_node);
4278 return;
4281 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
4282 attributes, return true otherwise. NODE is the cgraph node of the current
4283 function. */
4285 static bool
4286 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
4288 if (!cgraph_node_can_be_local_p (node))
4290 if (dump_file)
4291 fprintf (dump_file, "Function not local to this compilation unit.\n");
4292 return false;
4295 if (!tree_versionable_function_p (node->decl))
4297 if (dump_file)
4298 fprintf (dump_file, "Function not local to this compilation unit.\n");
4299 return false;
4302 if (DECL_VIRTUAL_P (current_function_decl))
4304 if (dump_file)
4305 fprintf (dump_file, "Function is a virtual method.\n");
4306 return false;
4309 if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
4310 && node->global.size >= MAX_INLINE_INSNS_AUTO)
4312 if (dump_file)
4313 fprintf (dump_file, "Function too big to be made truly local.\n");
4314 return false;
4317 if (!node->callers)
4319 if (dump_file)
4320 fprintf (dump_file,
4321 "Function has no callers in this compilation unit.\n");
4322 return false;
4325 if (cfun->stdarg)
4327 if (dump_file)
4328 fprintf (dump_file, "Function uses stdarg. \n");
4329 return false;
4332 if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
4333 return false;
4335 return true;
4338 /* Perform early interprocedural SRA. */
4340 static unsigned int
4341 ipa_early_sra (void)
4343 struct cgraph_node *node = cgraph_node (current_function_decl);
4344 ipa_parm_adjustment_vec adjustments;
4345 int ret = 0;
4347 if (!ipa_sra_preliminary_function_checks (node))
4348 return 0;
4350 sra_initialize ();
4351 sra_mode = SRA_MODE_EARLY_IPA;
4353 if (!find_param_candidates ())
4355 if (dump_file)
4356 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
4357 goto simple_out;
4360 if (!all_callers_have_enough_arguments_p (node))
4362 if (dump_file)
4363 fprintf (dump_file, "There are callers with insufficient number of "
4364 "arguments.\n");
4365 goto simple_out;
4368 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
4369 func_param_count
4370 * last_basic_block_for_function (cfun));
4371 final_bbs = BITMAP_ALLOC (NULL);
4373 scan_function ();
4374 if (encountered_apply_args)
4376 if (dump_file)
4377 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
4378 goto out;
4381 if (encountered_unchangable_recursive_call)
4383 if (dump_file)
4384 fprintf (dump_file, "Function calls itself with insufficient "
4385 "number of arguments.\n");
4386 goto out;
4389 adjustments = analyze_all_param_acesses ();
4390 if (!adjustments)
4391 goto out;
4392 if (dump_file)
4393 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
4395 modify_function (node, adjustments);
4396 VEC_free (ipa_parm_adjustment_t, heap, adjustments);
4397 ret = TODO_update_ssa;
4399 statistics_counter_event (cfun, "Unused parameters deleted",
4400 sra_stats.deleted_unused_parameters);
4401 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
4402 sra_stats.scalar_by_ref_to_by_val);
4403 statistics_counter_event (cfun, "Aggregate parameters broken up",
4404 sra_stats.aggregate_params_reduced);
4405 statistics_counter_event (cfun, "Aggregate parameter components created",
4406 sra_stats.param_reductions_created);
4408 out:
4409 BITMAP_FREE (final_bbs);
4410 free (bb_dereferences);
4411 simple_out:
4412 sra_deinitialize ();
4413 return ret;
4416 /* Return if early ipa sra shall be performed. */
4417 static bool
4418 ipa_early_sra_gate (void)
4420 return flag_ipa_sra;
4423 struct gimple_opt_pass pass_early_ipa_sra =
4426 GIMPLE_PASS,
4427 "eipa_sra", /* name */
4428 ipa_early_sra_gate, /* gate */
4429 ipa_early_sra, /* execute */
4430 NULL, /* sub */
4431 NULL, /* next */
4432 0, /* static_pass_number */
4433 TV_IPA_SRA, /* tv_id */
4434 0, /* properties_required */
4435 0, /* properties_provided */
4436 0, /* properties_destroyed */
4437 0, /* todo_flags_start */
4438 TODO_dump_func | TODO_dump_cgraph /* todo_flags_finish */