* ifcvt.c (noce_try_cmove_arith): Fix long lines.
[official-gcc.git] / gcc / tree-sra.c
blob0635aa7f4a813c7a288042a329479b0a274673ab
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 "expr.h"
81 #include "gimple.h"
82 #include "cgraph.h"
83 #include "tree-flow.h"
84 #include "ipa-prop.h"
85 #include "diagnostic.h"
86 #include "statistics.h"
87 #include "tree-dump.h"
88 #include "timevar.h"
89 #include "params.h"
90 #include "target.h"
91 #include "flags.h"
93 /* Enumeration of all aggregate reductions we can do. */
94 enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
95 SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
96 SRA_MODE_INTRA }; /* late intraprocedural SRA */
98 /* Global variable describing which aggregate reduction we are performing at
99 the moment. */
100 static enum sra_mode sra_mode;
102 struct assign_link;
104 /* ACCESS represents each access to an aggregate variable (as a whole or a
105 part). It can also represent a group of accesses that refer to exactly the
106 same fragment of an aggregate (i.e. those that have exactly the same offset
107 and size). Such representatives for a single aggregate, once determined,
108 are linked in a linked list and have the group fields set.
110 Moreover, when doing intraprocedural SRA, a tree is built from those
111 representatives (by the means of first_child and next_sibling pointers), in
112 which all items in a subtree are "within" the root, i.e. their offset is
113 greater or equal to offset of the root and offset+size is smaller or equal
114 to offset+size of the root. Children of an access are sorted by offset.
116 Note that accesses to parts of vector and complex number types always
117 represented by an access to the whole complex number or a vector. It is a
118 duty of the modifying functions to replace them appropriately. */
120 struct access
122 /* Values returned by `get_ref_base_and_extent' for each component reference
123 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
124 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
125 HOST_WIDE_INT offset;
126 HOST_WIDE_INT size;
127 tree base;
129 /* Expression. It is context dependent so do not use it to create new
130 expressions to access the original aggregate. See PR 42154 for a
131 testcase. */
132 tree expr;
133 /* Type. */
134 tree type;
136 /* The statement this access belongs to. */
137 gimple stmt;
139 /* Next group representative for this aggregate. */
140 struct access *next_grp;
142 /* Pointer to the group representative. Pointer to itself if the struct is
143 the representative. */
144 struct access *group_representative;
146 /* If this access has any children (in terms of the definition above), this
147 points to the first one. */
148 struct access *first_child;
150 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
151 described above. In IPA-SRA this is a pointer to the next access
152 belonging to the same group (having the same representative). */
153 struct access *next_sibling;
155 /* Pointers to the first and last element in the linked list of assign
156 links. */
157 struct assign_link *first_link, *last_link;
159 /* Pointer to the next access in the work queue. */
160 struct access *next_queued;
162 /* Replacement variable for this access "region." Never to be accessed
163 directly, always only by the means of get_access_replacement() and only
164 when grp_to_be_replaced flag is set. */
165 tree replacement_decl;
167 /* Is this particular access write access? */
168 unsigned write : 1;
170 /* Is this access an artificial one created to scalarize some record
171 entirely? */
172 unsigned total_scalarization : 1;
174 /* Is this access currently in the work queue? */
175 unsigned grp_queued : 1;
177 /* Does this group contain a write access? This flag is propagated down the
178 access tree. */
179 unsigned grp_write : 1;
181 /* Does this group contain a read access? This flag is propagated down the
182 access tree. */
183 unsigned grp_read : 1;
185 /* Other passes of the analysis use this bit to make function
186 analyze_access_subtree create scalar replacements for this group if
187 possible. */
188 unsigned grp_hint : 1;
190 /* Is the subtree rooted in this access fully covered by scalar
191 replacements? */
192 unsigned grp_covered : 1;
194 /* If set to true, this access and all below it in an access tree must not be
195 scalarized. */
196 unsigned grp_unscalarizable_region : 1;
198 /* Whether data have been written to parts of the aggregate covered by this
199 access which is not to be scalarized. This flag is propagated up in the
200 access tree. */
201 unsigned grp_unscalarized_data : 1;
203 /* Does this access and/or group contain a write access through a
204 BIT_FIELD_REF? */
205 unsigned grp_partial_lhs : 1;
207 /* Set when a scalar replacement should be created for this variable. We do
208 the decision and creation at different places because create_tmp_var
209 cannot be called from within FOR_EACH_REFERENCED_VAR. */
210 unsigned grp_to_be_replaced : 1;
212 /* Is it possible that the group refers to data which might be (directly or
213 otherwise) modified? */
214 unsigned grp_maybe_modified : 1;
216 /* Set when this is a representative of a pointer to scalar (i.e. by
217 reference) parameter which we consider for turning into a plain scalar
218 (i.e. a by value parameter). */
219 unsigned grp_scalar_ptr : 1;
221 /* Set when we discover that this pointer is not safe to dereference in the
222 caller. */
223 unsigned grp_not_necessarilly_dereferenced : 1;
226 typedef struct access *access_p;
228 DEF_VEC_P (access_p);
229 DEF_VEC_ALLOC_P (access_p, heap);
231 /* Alloc pool for allocating access structures. */
232 static alloc_pool access_pool;
234 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
235 are used to propagate subaccesses from rhs to lhs as long as they don't
236 conflict with what is already there. */
237 struct assign_link
239 struct access *lacc, *racc;
240 struct assign_link *next;
243 /* Alloc pool for allocating assign link structures. */
244 static alloc_pool link_pool;
246 /* Base (tree) -> Vector (VEC(access_p,heap) *) map. */
247 static struct pointer_map_t *base_access_vec;
249 /* Bitmap of candidates. */
250 static bitmap candidate_bitmap;
252 /* Bitmap of candidates which we should try to entirely scalarize away and
253 those which cannot be (because they are and need be used as a whole). */
254 static bitmap should_scalarize_away_bitmap, cannot_scalarize_away_bitmap;
256 /* Obstack for creation of fancy names. */
257 static struct obstack name_obstack;
259 /* Head of a linked list of accesses that need to have its subaccesses
260 propagated to their assignment counterparts. */
261 static struct access *work_queue_head;
263 /* Number of parameters of the analyzed function when doing early ipa SRA. */
264 static int func_param_count;
266 /* scan_function sets the following to true if it encounters a call to
267 __builtin_apply_args. */
268 static bool encountered_apply_args;
270 /* Set by scan_function when it finds a recursive call. */
271 static bool encountered_recursive_call;
273 /* Set by scan_function when it finds a recursive call with less actual
274 arguments than formal parameters.. */
275 static bool encountered_unchangable_recursive_call;
277 /* This is a table in which for each basic block and parameter there is a
278 distance (offset + size) in that parameter which is dereferenced and
279 accessed in that BB. */
280 static HOST_WIDE_INT *bb_dereferences;
281 /* Bitmap of BBs that can cause the function to "stop" progressing by
282 returning, throwing externally, looping infinitely or calling a function
283 which might abort etc.. */
284 static bitmap final_bbs;
286 /* Representative of no accesses at all. */
287 static struct access no_accesses_representant;
289 /* Predicate to test the special value. */
291 static inline bool
292 no_accesses_p (struct access *access)
294 return access == &no_accesses_representant;
297 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
298 representative fields are dumped, otherwise those which only describe the
299 individual access are. */
301 static struct
303 /* Number of processed aggregates is readily available in
304 analyze_all_variable_accesses and so is not stored here. */
306 /* Number of created scalar replacements. */
307 int replacements;
309 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
310 expression. */
311 int exprs;
313 /* Number of statements created by generate_subtree_copies. */
314 int subtree_copies;
316 /* Number of statements created by load_assign_lhs_subreplacements. */
317 int subreplacements;
319 /* Number of times sra_modify_assign has deleted a statement. */
320 int deleted;
322 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
323 RHS reparately due to type conversions or nonexistent matching
324 references. */
325 int separate_lhs_rhs_handling;
327 /* Number of parameters that were removed because they were unused. */
328 int deleted_unused_parameters;
330 /* Number of scalars passed as parameters by reference that have been
331 converted to be passed by value. */
332 int scalar_by_ref_to_by_val;
334 /* Number of aggregate parameters that were replaced by one or more of their
335 components. */
336 int aggregate_params_reduced;
338 /* Numbber of components created when splitting aggregate parameters. */
339 int param_reductions_created;
340 } sra_stats;
342 static void
343 dump_access (FILE *f, struct access *access, bool grp)
345 fprintf (f, "access { ");
346 fprintf (f, "base = (%d)'", DECL_UID (access->base));
347 print_generic_expr (f, access->base, 0);
348 fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
349 fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
350 fprintf (f, ", expr = ");
351 print_generic_expr (f, access->expr, 0);
352 fprintf (f, ", type = ");
353 print_generic_expr (f, access->type, 0);
354 if (grp)
355 fprintf (f, ", grp_write = %d, total_scalarization = %d, "
356 "grp_read = %d, grp_hint = %d, "
357 "grp_covered = %d, grp_unscalarizable_region = %d, "
358 "grp_unscalarized_data = %d, grp_partial_lhs = %d, "
359 "grp_to_be_replaced = %d, grp_maybe_modified = %d, "
360 "grp_not_necessarilly_dereferenced = %d\n",
361 access->grp_write, access->total_scalarization,
362 access->grp_read, access->grp_hint,
363 access->grp_covered, access->grp_unscalarizable_region,
364 access->grp_unscalarized_data, access->grp_partial_lhs,
365 access->grp_to_be_replaced, access->grp_maybe_modified,
366 access->grp_not_necessarilly_dereferenced);
367 else
368 fprintf (f, ", write = %d, total_scalarization = %d, "
369 "grp_partial_lhs = %d\n",
370 access->write, access->total_scalarization,
371 access->grp_partial_lhs);
374 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
376 static void
377 dump_access_tree_1 (FILE *f, struct access *access, int level)
381 int i;
383 for (i = 0; i < level; i++)
384 fputs ("* ", dump_file);
386 dump_access (f, access, true);
388 if (access->first_child)
389 dump_access_tree_1 (f, access->first_child, level + 1);
391 access = access->next_sibling;
393 while (access);
396 /* Dump all access trees for a variable, given the pointer to the first root in
397 ACCESS. */
399 static void
400 dump_access_tree (FILE *f, struct access *access)
402 for (; access; access = access->next_grp)
403 dump_access_tree_1 (f, access, 0);
406 /* Return true iff ACC is non-NULL and has subaccesses. */
408 static inline bool
409 access_has_children_p (struct access *acc)
411 return acc && acc->first_child;
414 /* Return a vector of pointers to accesses for the variable given in BASE or
415 NULL if there is none. */
417 static VEC (access_p, heap) *
418 get_base_access_vector (tree base)
420 void **slot;
422 slot = pointer_map_contains (base_access_vec, base);
423 if (!slot)
424 return NULL;
425 else
426 return *(VEC (access_p, heap) **) slot;
429 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
430 in ACCESS. Return NULL if it cannot be found. */
432 static struct access *
433 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
434 HOST_WIDE_INT size)
436 while (access && (access->offset != offset || access->size != size))
438 struct access *child = access->first_child;
440 while (child && (child->offset + child->size <= offset))
441 child = child->next_sibling;
442 access = child;
445 return access;
448 /* Return the first group representative for DECL or NULL if none exists. */
450 static struct access *
451 get_first_repr_for_decl (tree base)
453 VEC (access_p, heap) *access_vec;
455 access_vec = get_base_access_vector (base);
456 if (!access_vec)
457 return NULL;
459 return VEC_index (access_p, access_vec, 0);
462 /* Find an access representative for the variable BASE and given OFFSET and
463 SIZE. Requires that access trees have already been built. Return NULL if
464 it cannot be found. */
466 static struct access *
467 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
468 HOST_WIDE_INT size)
470 struct access *access;
472 access = get_first_repr_for_decl (base);
473 while (access && (access->offset + access->size <= offset))
474 access = access->next_grp;
475 if (!access)
476 return NULL;
478 return find_access_in_subtree (access, offset, size);
481 /* Add LINK to the linked list of assign links of RACC. */
482 static void
483 add_link_to_rhs (struct access *racc, struct assign_link *link)
485 gcc_assert (link->racc == racc);
487 if (!racc->first_link)
489 gcc_assert (!racc->last_link);
490 racc->first_link = link;
492 else
493 racc->last_link->next = link;
495 racc->last_link = link;
496 link->next = NULL;
499 /* Move all link structures in their linked list in OLD_RACC to the linked list
500 in NEW_RACC. */
501 static void
502 relink_to_new_repr (struct access *new_racc, struct access *old_racc)
504 if (!old_racc->first_link)
506 gcc_assert (!old_racc->last_link);
507 return;
510 if (new_racc->first_link)
512 gcc_assert (!new_racc->last_link->next);
513 gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
515 new_racc->last_link->next = old_racc->first_link;
516 new_racc->last_link = old_racc->last_link;
518 else
520 gcc_assert (!new_racc->last_link);
522 new_racc->first_link = old_racc->first_link;
523 new_racc->last_link = old_racc->last_link;
525 old_racc->first_link = old_racc->last_link = NULL;
528 /* Add ACCESS to the work queue (which is actually a stack). */
530 static void
531 add_access_to_work_queue (struct access *access)
533 if (!access->grp_queued)
535 gcc_assert (!access->next_queued);
536 access->next_queued = work_queue_head;
537 access->grp_queued = 1;
538 work_queue_head = access;
542 /* Pop an access from the work queue, and return it, assuming there is one. */
544 static struct access *
545 pop_access_from_work_queue (void)
547 struct access *access = work_queue_head;
549 work_queue_head = access->next_queued;
550 access->next_queued = NULL;
551 access->grp_queued = 0;
552 return access;
556 /* Allocate necessary structures. */
558 static void
559 sra_initialize (void)
561 candidate_bitmap = BITMAP_ALLOC (NULL);
562 should_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
563 cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
564 gcc_obstack_init (&name_obstack);
565 access_pool = create_alloc_pool ("SRA accesses", sizeof (struct access), 16);
566 link_pool = create_alloc_pool ("SRA links", sizeof (struct assign_link), 16);
567 base_access_vec = pointer_map_create ();
568 memset (&sra_stats, 0, sizeof (sra_stats));
569 encountered_apply_args = false;
570 encountered_recursive_call = false;
571 encountered_unchangable_recursive_call = false;
574 /* Hook fed to pointer_map_traverse, deallocate stored vectors. */
576 static bool
577 delete_base_accesses (const void *key ATTRIBUTE_UNUSED, void **value,
578 void *data ATTRIBUTE_UNUSED)
580 VEC (access_p, heap) *access_vec;
581 access_vec = (VEC (access_p, heap) *) *value;
582 VEC_free (access_p, heap, access_vec);
584 return true;
587 /* Deallocate all general structures. */
589 static void
590 sra_deinitialize (void)
592 BITMAP_FREE (candidate_bitmap);
593 BITMAP_FREE (should_scalarize_away_bitmap);
594 BITMAP_FREE (cannot_scalarize_away_bitmap);
595 free_alloc_pool (access_pool);
596 free_alloc_pool (link_pool);
597 obstack_free (&name_obstack, NULL);
599 pointer_map_traverse (base_access_vec, delete_base_accesses, NULL);
600 pointer_map_destroy (base_access_vec);
603 /* Remove DECL from candidates for SRA and write REASON to the dump file if
604 there is one. */
605 static void
606 disqualify_candidate (tree decl, const char *reason)
608 bitmap_clear_bit (candidate_bitmap, DECL_UID (decl));
610 if (dump_file && (dump_flags & TDF_DETAILS))
612 fprintf (dump_file, "! Disqualifying ");
613 print_generic_expr (dump_file, decl, 0);
614 fprintf (dump_file, " - %s\n", reason);
618 /* Return true iff the type contains a field or an element which does not allow
619 scalarization. */
621 static bool
622 type_internals_preclude_sra_p (tree type)
624 tree fld;
625 tree et;
627 switch (TREE_CODE (type))
629 case RECORD_TYPE:
630 case UNION_TYPE:
631 case QUAL_UNION_TYPE:
632 for (fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
633 if (TREE_CODE (fld) == FIELD_DECL)
635 tree ft = TREE_TYPE (fld);
637 if (TREE_THIS_VOLATILE (fld)
638 || !DECL_FIELD_OFFSET (fld) || !DECL_SIZE (fld)
639 || !host_integerp (DECL_FIELD_OFFSET (fld), 1)
640 || !host_integerp (DECL_SIZE (fld), 1))
641 return true;
643 if (AGGREGATE_TYPE_P (ft)
644 && type_internals_preclude_sra_p (ft))
645 return true;
648 return false;
650 case ARRAY_TYPE:
651 et = TREE_TYPE (type);
653 if (AGGREGATE_TYPE_P (et))
654 return type_internals_preclude_sra_p (et);
655 else
656 return false;
658 default:
659 return false;
663 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
664 base variable if it is. Return T if it is not an SSA_NAME. */
666 static tree
667 get_ssa_base_param (tree t)
669 if (TREE_CODE (t) == SSA_NAME)
671 if (SSA_NAME_IS_DEFAULT_DEF (t))
672 return SSA_NAME_VAR (t);
673 else
674 return NULL_TREE;
676 return t;
679 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
680 belongs to, unless the BB has already been marked as a potentially
681 final. */
683 static void
684 mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple stmt)
686 basic_block bb = gimple_bb (stmt);
687 int idx, parm_index = 0;
688 tree parm;
690 if (bitmap_bit_p (final_bbs, bb->index))
691 return;
693 for (parm = DECL_ARGUMENTS (current_function_decl);
694 parm && parm != base;
695 parm = TREE_CHAIN (parm))
696 parm_index++;
698 gcc_assert (parm_index < func_param_count);
700 idx = bb->index * func_param_count + parm_index;
701 if (bb_dereferences[idx] < dist)
702 bb_dereferences[idx] = dist;
705 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
706 the three fields. Also add it to the vector of accesses corresponding to
707 the base. Finally, return the new access. */
709 static struct access *
710 create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
712 VEC (access_p, heap) *vec;
713 struct access *access;
714 void **slot;
716 access = (struct access *) pool_alloc (access_pool);
717 memset (access, 0, sizeof (struct access));
718 access->base = base;
719 access->offset = offset;
720 access->size = size;
722 slot = pointer_map_contains (base_access_vec, base);
723 if (slot)
724 vec = (VEC (access_p, heap) *) *slot;
725 else
726 vec = VEC_alloc (access_p, heap, 32);
728 VEC_safe_push (access_p, heap, vec, access);
730 *((struct VEC (access_p,heap) **)
731 pointer_map_insert (base_access_vec, base)) = vec;
733 return access;
736 /* Create and insert access for EXPR. Return created access, or NULL if it is
737 not possible. */
739 static struct access *
740 create_access (tree expr, gimple stmt, bool write)
742 struct access *access;
743 HOST_WIDE_INT offset, size, max_size;
744 tree base = expr;
745 bool ptr, unscalarizable_region = false;
747 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
749 if (sra_mode == SRA_MODE_EARLY_IPA && INDIRECT_REF_P (base))
751 base = get_ssa_base_param (TREE_OPERAND (base, 0));
752 if (!base)
753 return NULL;
754 ptr = true;
756 else
757 ptr = false;
759 if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
760 return NULL;
762 if (sra_mode == SRA_MODE_EARLY_IPA)
764 if (size < 0 || size != max_size)
766 disqualify_candidate (base, "Encountered a variable sized access.");
767 return NULL;
769 if ((offset % BITS_PER_UNIT) != 0 || (size % BITS_PER_UNIT) != 0)
771 disqualify_candidate (base,
772 "Encountered an acces not aligned to a byte.");
773 return NULL;
776 if (ptr)
777 mark_parm_dereference (base, offset + size, stmt);
779 else
781 if (size != max_size)
783 size = max_size;
784 unscalarizable_region = true;
786 if (size < 0)
788 disqualify_candidate (base, "Encountered an unconstrained access.");
789 return NULL;
793 access = create_access_1 (base, offset, size);
794 access->expr = expr;
795 access->type = TREE_TYPE (expr);
796 access->write = write;
797 access->grp_unscalarizable_region = unscalarizable_region;
798 access->stmt = stmt;
800 return access;
804 /* Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple
805 register types or (recursively) records with only these two kinds of fields.
806 It also returns false if any of these records has a zero-size field as its
807 last field. */
809 static bool
810 type_consists_of_records_p (tree type)
812 tree fld;
813 bool last_fld_has_zero_size = false;
815 if (TREE_CODE (type) != RECORD_TYPE)
816 return false;
818 for (fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
819 if (TREE_CODE (fld) == FIELD_DECL)
821 tree ft = TREE_TYPE (fld);
823 if (!is_gimple_reg_type (ft)
824 && !type_consists_of_records_p (ft))
825 return false;
827 last_fld_has_zero_size = tree_low_cst (DECL_SIZE (fld), 1) == 0;
830 if (last_fld_has_zero_size)
831 return false;
833 return true;
836 /* Create total_scalarization accesses for all scalar type fields in DECL that
837 must be of a RECORD_TYPE conforming to type_consists_of_records_p. BASE
838 must be the top-most VAR_DECL representing the variable, OFFSET must be the
839 offset of DECL within BASE. */
841 static void
842 completely_scalarize_record (tree base, tree decl, HOST_WIDE_INT offset)
844 tree fld, decl_type = TREE_TYPE (decl);
846 for (fld = TYPE_FIELDS (decl_type); fld; fld = TREE_CHAIN (fld))
847 if (TREE_CODE (fld) == FIELD_DECL)
849 HOST_WIDE_INT pos = offset + int_bit_position (fld);
850 tree ft = TREE_TYPE (fld);
852 if (is_gimple_reg_type (ft))
854 struct access *access;
855 HOST_WIDE_INT size;
856 tree expr;
857 bool ok;
859 size = tree_low_cst (DECL_SIZE (fld), 1);
860 expr = base;
861 ok = build_ref_for_offset (&expr, TREE_TYPE (base), pos,
862 ft, false);
863 gcc_assert (ok);
865 access = create_access_1 (base, pos, size);
866 access->expr = expr;
867 access->type = ft;
868 access->total_scalarization = 1;
869 /* Accesses for intraprocedural SRA can have their stmt NULL. */
871 else
872 completely_scalarize_record (base, fld, pos);
877 /* Search the given tree for a declaration by skipping handled components and
878 exclude it from the candidates. */
880 static void
881 disqualify_base_of_expr (tree t, const char *reason)
883 while (handled_component_p (t))
884 t = TREE_OPERAND (t, 0);
886 if (sra_mode == SRA_MODE_EARLY_IPA)
888 if (INDIRECT_REF_P (t))
889 t = TREE_OPERAND (t, 0);
890 t = get_ssa_base_param (t);
893 if (t && DECL_P (t))
894 disqualify_candidate (t, reason);
897 /* Scan expression EXPR and create access structures for all accesses to
898 candidates for scalarization. Return the created access or NULL if none is
899 created. */
901 static struct access *
902 build_access_from_expr_1 (tree *expr_ptr, gimple stmt, bool write)
904 struct access *ret = NULL;
905 tree expr = *expr_ptr;
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 INDIRECT_REF:
935 if (sra_mode != SRA_MODE_EARLY_IPA)
936 return NULL;
937 /* fall through */
938 case VAR_DECL:
939 case PARM_DECL:
940 case RESULT_DECL:
941 case COMPONENT_REF:
942 case ARRAY_REF:
943 case ARRAY_RANGE_REF:
944 ret = create_access (expr, stmt, write);
945 break;
947 default:
948 break;
951 if (write && partial_ref && ret)
952 ret->grp_partial_lhs = 1;
954 return ret;
957 /* Callback of scan_function. Scan expression EXPR and create access
958 structures for all accesses to candidates for scalarization. Return true if
959 any access has been inserted. */
961 static bool
962 build_access_from_expr (tree *expr_ptr,
963 gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED, bool write,
964 void *data ATTRIBUTE_UNUSED)
966 struct access *access;
968 access = build_access_from_expr_1 (expr_ptr, gsi_stmt (*gsi), 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;
1001 /* Result code for scan_assign callback for scan_function. */
1002 enum scan_assign_result { SRA_SA_NONE, /* nothing done for the stmt */
1003 SRA_SA_PROCESSED, /* stmt analyzed/changed */
1004 SRA_SA_REMOVED }; /* stmt redundant and eliminated */
1007 /* Callback of scan_function. Scan expressions occuring in the statement
1008 pointed to by STMT_EXPR, create access structures for all accesses to
1009 candidates for scalarization and remove those candidates which occur in
1010 statements or expressions that prevent them from being split apart. Return
1011 true if any access has been inserted. */
1013 static enum scan_assign_result
1014 build_accesses_from_assign (gimple *stmt_ptr,
1015 gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
1016 void *data ATTRIBUTE_UNUSED)
1018 gimple stmt = *stmt_ptr;
1019 tree *lhs_ptr, *rhs_ptr;
1020 struct access *lacc, *racc;
1022 if (!gimple_assign_single_p (stmt))
1023 return SRA_SA_NONE;
1025 lhs_ptr = gimple_assign_lhs_ptr (stmt);
1026 rhs_ptr = gimple_assign_rhs1_ptr (stmt);
1028 if (disqualify_ops_if_throwing_stmt (stmt, *lhs_ptr, *rhs_ptr))
1029 return SRA_SA_NONE;
1031 racc = build_access_from_expr_1 (rhs_ptr, stmt, false);
1032 lacc = build_access_from_expr_1 (lhs_ptr, stmt, true);
1034 if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
1035 && racc && !is_gimple_reg_type (racc->type))
1036 bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
1038 if (lacc && racc
1039 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1040 && !lacc->grp_unscalarizable_region
1041 && !racc->grp_unscalarizable_region
1042 && AGGREGATE_TYPE_P (TREE_TYPE (*lhs_ptr))
1043 /* FIXME: Turn the following line into an assert after PR 40058 is
1044 fixed. */
1045 && lacc->size == racc->size
1046 && useless_type_conversion_p (lacc->type, racc->type))
1048 struct assign_link *link;
1050 link = (struct assign_link *) pool_alloc (link_pool);
1051 memset (link, 0, sizeof (struct assign_link));
1053 link->lacc = lacc;
1054 link->racc = racc;
1056 add_link_to_rhs (racc, link);
1059 return (lacc || racc) ? SRA_SA_PROCESSED : SRA_SA_NONE;
1062 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1063 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1065 static bool
1066 asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED, tree op,
1067 void *data ATTRIBUTE_UNUSED)
1069 op = get_base_address (op);
1070 if (op
1071 && DECL_P (op))
1072 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
1074 return false;
1077 /* Return true iff callsite CALL has at least as many actual arguments as there
1078 are formal parameters of the function currently processed by IPA-SRA. */
1080 static inline bool
1081 callsite_has_enough_arguments_p (gimple call)
1083 return gimple_call_num_args (call) >= (unsigned) func_param_count;
1086 /* Scan function and look for interesting statements. Return true if any has
1087 been found or processed, as indicated by callbacks. SCAN_EXPR is a callback
1088 called on all expressions within statements except assign statements and
1089 those deemed entirely unsuitable for some reason (all operands in such
1090 statements and expression are removed from candidate_bitmap). SCAN_ASSIGN
1091 is a callback called on all assign statements, HANDLE_SSA_DEFS is a callback
1092 called on assign statements and those call statements which have a lhs, it
1093 can be NULL. ANALYSIS_STAGE is true when running in the analysis stage of a
1094 pass and thus no statement is being modified. DATA is a pointer passed to
1095 all callbacks. If any single callback returns true, this function also
1096 returns true, otherwise it returns false. */
1098 static bool
1099 scan_function (bool (*scan_expr) (tree *, gimple_stmt_iterator *, bool, void *),
1100 enum scan_assign_result (*scan_assign) (gimple *,
1101 gimple_stmt_iterator *,
1102 void *),
1103 bool (*handle_ssa_defs)(gimple, void *),
1104 bool analysis_stage, void *data)
1106 gimple_stmt_iterator gsi;
1107 basic_block bb;
1108 unsigned i;
1109 tree *t;
1110 bool ret = false;
1112 FOR_EACH_BB (bb)
1114 bool bb_changed = false;
1116 if (handle_ssa_defs)
1117 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1118 ret |= handle_ssa_defs (gsi_stmt (gsi), data);
1120 gsi = gsi_start_bb (bb);
1121 while (!gsi_end_p (gsi))
1123 gimple stmt = gsi_stmt (gsi);
1124 enum scan_assign_result assign_result;
1125 bool any = false, deleted = false;
1127 if (analysis_stage && final_bbs && stmt_can_throw_external (stmt))
1128 bitmap_set_bit (final_bbs, bb->index);
1129 switch (gimple_code (stmt))
1131 case GIMPLE_RETURN:
1132 t = gimple_return_retval_ptr (stmt);
1133 if (*t != NULL_TREE)
1134 any |= scan_expr (t, &gsi, false, data);
1135 if (analysis_stage && final_bbs)
1136 bitmap_set_bit (final_bbs, bb->index);
1137 break;
1139 case GIMPLE_ASSIGN:
1140 assign_result = scan_assign (&stmt, &gsi, data);
1141 any |= assign_result == SRA_SA_PROCESSED;
1142 deleted = assign_result == SRA_SA_REMOVED;
1143 if (handle_ssa_defs && assign_result != SRA_SA_REMOVED)
1144 any |= handle_ssa_defs (stmt, data);
1145 break;
1147 case GIMPLE_CALL:
1148 /* Operands must be processed before the lhs. */
1149 for (i = 0; i < gimple_call_num_args (stmt); i++)
1151 tree *argp = gimple_call_arg_ptr (stmt, i);
1152 any |= scan_expr (argp, &gsi, false, data);
1155 if (analysis_stage && sra_mode == SRA_MODE_EARLY_IPA)
1157 tree dest = gimple_call_fndecl (stmt);
1158 int flags = gimple_call_flags (stmt);
1160 if (dest)
1162 if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1163 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1164 encountered_apply_args = true;
1165 if (cgraph_get_node (dest)
1166 == cgraph_get_node (current_function_decl))
1168 encountered_recursive_call = true;
1169 if (!callsite_has_enough_arguments_p (stmt))
1170 encountered_unchangable_recursive_call = true;
1174 if (final_bbs
1175 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1176 bitmap_set_bit (final_bbs, bb->index);
1179 if (gimple_call_lhs (stmt))
1181 tree *lhs_ptr = gimple_call_lhs_ptr (stmt);
1182 if (!analysis_stage
1183 || !disqualify_ops_if_throwing_stmt (stmt,
1184 *lhs_ptr, NULL))
1186 any |= scan_expr (lhs_ptr, &gsi, true, data);
1187 if (handle_ssa_defs)
1188 any |= handle_ssa_defs (stmt, data);
1191 break;
1193 case GIMPLE_ASM:
1194 if (analysis_stage)
1196 walk_stmt_load_store_addr_ops (stmt, NULL, NULL, NULL,
1197 asm_visit_addr);
1198 if (final_bbs)
1199 bitmap_set_bit (final_bbs, bb->index);
1201 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
1203 tree *op = &TREE_VALUE (gimple_asm_input_op (stmt, i));
1204 any |= scan_expr (op, &gsi, false, data);
1206 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
1208 tree *op = &TREE_VALUE (gimple_asm_output_op (stmt, i));
1209 any |= scan_expr (op, &gsi, true, data);
1211 break;
1213 default:
1214 break;
1217 if (any)
1219 ret = true;
1221 if (!analysis_stage)
1223 bb_changed = true;
1224 update_stmt (stmt);
1225 maybe_clean_eh_stmt (stmt);
1228 if (deleted)
1229 bb_changed = true;
1230 else
1232 gsi_next (&gsi);
1233 ret = true;
1236 if (!analysis_stage && bb_changed && sra_mode == SRA_MODE_EARLY_IPA)
1237 gimple_purge_dead_eh_edges (bb);
1240 return ret;
1243 /* Helper of QSORT function. There are pointers to accesses in the array. An
1244 access is considered smaller than another if it has smaller offset or if the
1245 offsets are the same but is size is bigger. */
1247 static int
1248 compare_access_positions (const void *a, const void *b)
1250 const access_p *fp1 = (const access_p *) a;
1251 const access_p *fp2 = (const access_p *) b;
1252 const access_p f1 = *fp1;
1253 const access_p f2 = *fp2;
1255 if (f1->offset != f2->offset)
1256 return f1->offset < f2->offset ? -1 : 1;
1258 if (f1->size == f2->size)
1260 if (f1->type == f2->type)
1261 return 0;
1262 /* Put any non-aggregate type before any aggregate type. */
1263 else if (!is_gimple_reg_type (f1->type)
1264 && is_gimple_reg_type (f2->type))
1265 return 1;
1266 else if (is_gimple_reg_type (f1->type)
1267 && !is_gimple_reg_type (f2->type))
1268 return -1;
1269 /* Put any complex or vector type before any other scalar type. */
1270 else if (TREE_CODE (f1->type) != COMPLEX_TYPE
1271 && TREE_CODE (f1->type) != VECTOR_TYPE
1272 && (TREE_CODE (f2->type) == COMPLEX_TYPE
1273 || TREE_CODE (f2->type) == VECTOR_TYPE))
1274 return 1;
1275 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
1276 || TREE_CODE (f1->type) == VECTOR_TYPE)
1277 && TREE_CODE (f2->type) != COMPLEX_TYPE
1278 && TREE_CODE (f2->type) != VECTOR_TYPE)
1279 return -1;
1280 /* Put the integral type with the bigger precision first. */
1281 else if (INTEGRAL_TYPE_P (f1->type)
1282 && INTEGRAL_TYPE_P (f2->type))
1283 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
1284 /* Put any integral type with non-full precision last. */
1285 else if (INTEGRAL_TYPE_P (f1->type)
1286 && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type))
1287 != TYPE_PRECISION (f1->type)))
1288 return 1;
1289 else if (INTEGRAL_TYPE_P (f2->type)
1290 && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type))
1291 != TYPE_PRECISION (f2->type)))
1292 return -1;
1293 /* Stabilize the sort. */
1294 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1297 /* We want the bigger accesses first, thus the opposite operator in the next
1298 line: */
1299 return f1->size > f2->size ? -1 : 1;
1303 /* Append a name of the declaration to the name obstack. A helper function for
1304 make_fancy_name. */
1306 static void
1307 make_fancy_decl_name (tree decl)
1309 char buffer[32];
1311 tree name = DECL_NAME (decl);
1312 if (name)
1313 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1314 IDENTIFIER_LENGTH (name));
1315 else
1317 sprintf (buffer, "D%u", DECL_UID (decl));
1318 obstack_grow (&name_obstack, buffer, strlen (buffer));
1322 /* Helper for make_fancy_name. */
1324 static void
1325 make_fancy_name_1 (tree expr)
1327 char buffer[32];
1328 tree index;
1330 if (DECL_P (expr))
1332 make_fancy_decl_name (expr);
1333 return;
1336 switch (TREE_CODE (expr))
1338 case COMPONENT_REF:
1339 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1340 obstack_1grow (&name_obstack, '$');
1341 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1342 break;
1344 case ARRAY_REF:
1345 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1346 obstack_1grow (&name_obstack, '$');
1347 /* Arrays with only one element may not have a constant as their
1348 index. */
1349 index = TREE_OPERAND (expr, 1);
1350 if (TREE_CODE (index) != INTEGER_CST)
1351 break;
1352 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1353 obstack_grow (&name_obstack, buffer, strlen (buffer));
1355 break;
1357 case BIT_FIELD_REF:
1358 case REALPART_EXPR:
1359 case IMAGPART_EXPR:
1360 gcc_unreachable (); /* we treat these as scalars. */
1361 break;
1362 default:
1363 break;
1367 /* Create a human readable name for replacement variable of ACCESS. */
1369 static char *
1370 make_fancy_name (tree expr)
1372 make_fancy_name_1 (expr);
1373 obstack_1grow (&name_obstack, '\0');
1374 return XOBFINISH (&name_obstack, char *);
1377 /* Helper function for build_ref_for_offset. */
1379 static bool
1380 build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset,
1381 tree exp_type)
1383 while (1)
1385 tree fld;
1386 tree tr_size, index, minidx;
1387 HOST_WIDE_INT el_size;
1389 if (offset == 0 && exp_type
1390 && types_compatible_p (exp_type, type))
1391 return true;
1393 switch (TREE_CODE (type))
1395 case UNION_TYPE:
1396 case QUAL_UNION_TYPE:
1397 case RECORD_TYPE:
1398 for (fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
1400 HOST_WIDE_INT pos, size;
1401 tree expr, *expr_ptr;
1403 if (TREE_CODE (fld) != FIELD_DECL)
1404 continue;
1406 pos = int_bit_position (fld);
1407 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1408 tr_size = DECL_SIZE (fld);
1409 if (!tr_size || !host_integerp (tr_size, 1))
1410 continue;
1411 size = tree_low_cst (tr_size, 1);
1412 if (size == 0)
1414 if (pos != offset)
1415 continue;
1417 else if (pos > offset || (pos + size) <= offset)
1418 continue;
1420 if (res)
1422 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1423 NULL_TREE);
1424 expr_ptr = &expr;
1426 else
1427 expr_ptr = NULL;
1428 if (build_ref_for_offset_1 (expr_ptr, TREE_TYPE (fld),
1429 offset - pos, exp_type))
1431 if (res)
1432 *res = expr;
1433 return true;
1436 return false;
1438 case ARRAY_TYPE:
1439 tr_size = TYPE_SIZE (TREE_TYPE (type));
1440 if (!tr_size || !host_integerp (tr_size, 1))
1441 return false;
1442 el_size = tree_low_cst (tr_size, 1);
1444 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1445 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
1446 return false;
1447 if (res)
1449 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1450 if (!integer_zerop (minidx))
1451 index = int_const_binop (PLUS_EXPR, index, minidx, 0);
1452 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1453 NULL_TREE, NULL_TREE);
1455 offset = offset % el_size;
1456 type = TREE_TYPE (type);
1457 break;
1459 default:
1460 if (offset != 0)
1461 return false;
1463 if (exp_type)
1464 return false;
1465 else
1466 return true;
1471 /* Construct an expression that would reference a part of aggregate *EXPR of
1472 type TYPE at the given OFFSET of the type EXP_TYPE. If EXPR is NULL, the
1473 function only determines whether it can build such a reference without
1474 actually doing it, otherwise, the tree it points to is unshared first and
1475 then used as a base for furhter sub-references.
1477 FIXME: Eventually this should be replaced with
1478 maybe_fold_offset_to_reference() from tree-ssa-ccp.c but that requires a
1479 minor rewrite of fold_stmt.
1482 bool
1483 build_ref_for_offset (tree *expr, tree type, HOST_WIDE_INT offset,
1484 tree exp_type, bool allow_ptr)
1486 location_t loc = expr ? EXPR_LOCATION (*expr) : UNKNOWN_LOCATION;
1488 if (expr)
1489 *expr = unshare_expr (*expr);
1491 if (allow_ptr && POINTER_TYPE_P (type))
1493 type = TREE_TYPE (type);
1494 if (expr)
1495 *expr = fold_build1_loc (loc, INDIRECT_REF, type, *expr);
1498 return build_ref_for_offset_1 (expr, type, offset, exp_type);
1501 /* Return true iff TYPE is stdarg va_list type. */
1503 static inline bool
1504 is_va_list_type (tree type)
1506 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1509 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1510 those with type which is suitable for scalarization. */
1512 static bool
1513 find_var_candidates (void)
1515 tree var, type;
1516 referenced_var_iterator rvi;
1517 bool ret = false;
1519 FOR_EACH_REFERENCED_VAR (var, rvi)
1521 if (TREE_CODE (var) != VAR_DECL && TREE_CODE (var) != PARM_DECL)
1522 continue;
1523 type = TREE_TYPE (var);
1525 if (!AGGREGATE_TYPE_P (type)
1526 || needs_to_live_in_memory (var)
1527 || TREE_THIS_VOLATILE (var)
1528 || !COMPLETE_TYPE_P (type)
1529 || !host_integerp (TYPE_SIZE (type), 1)
1530 || tree_low_cst (TYPE_SIZE (type), 1) == 0
1531 || type_internals_preclude_sra_p (type)
1532 /* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1533 we also want to schedule it rather late. Thus we ignore it in
1534 the early pass. */
1535 || (sra_mode == SRA_MODE_EARLY_INTRA
1536 && is_va_list_type (type)))
1537 continue;
1539 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
1541 if (dump_file && (dump_flags & TDF_DETAILS))
1543 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
1544 print_generic_expr (dump_file, var, 0);
1545 fprintf (dump_file, "\n");
1547 ret = true;
1550 return ret;
1553 /* Sort all accesses for the given variable, check for partial overlaps and
1554 return NULL if there are any. If there are none, pick a representative for
1555 each combination of offset and size and create a linked list out of them.
1556 Return the pointer to the first representative and make sure it is the first
1557 one in the vector of accesses. */
1559 static struct access *
1560 sort_and_splice_var_accesses (tree var)
1562 int i, j, access_count;
1563 struct access *res, **prev_acc_ptr = &res;
1564 VEC (access_p, heap) *access_vec;
1565 bool first = true;
1566 HOST_WIDE_INT low = -1, high = 0;
1568 access_vec = get_base_access_vector (var);
1569 if (!access_vec)
1570 return NULL;
1571 access_count = VEC_length (access_p, access_vec);
1573 /* Sort by <OFFSET, SIZE>. */
1574 qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
1575 compare_access_positions);
1577 i = 0;
1578 while (i < access_count)
1580 struct access *access = VEC_index (access_p, access_vec, i);
1581 bool grp_write = access->write;
1582 bool grp_read = !access->write;
1583 bool multiple_reads = false;
1584 bool total_scalarization = access->total_scalarization;
1585 bool grp_partial_lhs = access->grp_partial_lhs;
1586 bool first_scalar = is_gimple_reg_type (access->type);
1587 bool unscalarizable_region = access->grp_unscalarizable_region;
1589 if (first || access->offset >= high)
1591 first = false;
1592 low = access->offset;
1593 high = access->offset + access->size;
1595 else if (access->offset > low && access->offset + access->size > high)
1596 return NULL;
1597 else
1598 gcc_assert (access->offset >= low
1599 && access->offset + access->size <= high);
1601 j = i + 1;
1602 while (j < access_count)
1604 struct access *ac2 = VEC_index (access_p, access_vec, j);
1605 if (ac2->offset != access->offset || ac2->size != access->size)
1606 break;
1607 if (ac2->write)
1608 grp_write = true;
1609 else
1611 if (grp_read)
1612 multiple_reads = true;
1613 else
1614 grp_read = true;
1616 grp_partial_lhs |= ac2->grp_partial_lhs;
1617 unscalarizable_region |= ac2->grp_unscalarizable_region;
1618 total_scalarization |= ac2->total_scalarization;
1619 relink_to_new_repr (access, ac2);
1621 /* If there are both aggregate-type and scalar-type accesses with
1622 this combination of size and offset, the comparison function
1623 should have put the scalars first. */
1624 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
1625 ac2->group_representative = access;
1626 j++;
1629 i = j;
1631 access->group_representative = access;
1632 access->grp_write = grp_write;
1633 access->grp_read = grp_read;
1634 access->grp_hint = multiple_reads || total_scalarization;
1635 access->grp_partial_lhs = grp_partial_lhs;
1636 access->grp_unscalarizable_region = unscalarizable_region;
1637 if (access->first_link)
1638 add_access_to_work_queue (access);
1640 *prev_acc_ptr = access;
1641 prev_acc_ptr = &access->next_grp;
1644 gcc_assert (res == VEC_index (access_p, access_vec, 0));
1645 return res;
1648 /* Create a variable for the given ACCESS which determines the type, name and a
1649 few other properties. Return the variable declaration and store it also to
1650 ACCESS->replacement. */
1652 static tree
1653 create_access_replacement (struct access *access)
1655 tree repl;
1657 repl = create_tmp_var (access->type, "SR");
1658 get_var_ann (repl);
1659 add_referenced_var (repl);
1660 mark_sym_for_renaming (repl);
1662 if (!access->grp_partial_lhs
1663 && (TREE_CODE (access->type) == COMPLEX_TYPE
1664 || TREE_CODE (access->type) == VECTOR_TYPE))
1665 DECL_GIMPLE_REG_P (repl) = 1;
1667 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
1668 DECL_ARTIFICIAL (repl) = 1;
1669 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
1671 if (DECL_NAME (access->base)
1672 && !DECL_IGNORED_P (access->base)
1673 && !DECL_ARTIFICIAL (access->base))
1675 char *pretty_name = make_fancy_name (access->expr);
1677 DECL_NAME (repl) = get_identifier (pretty_name);
1678 obstack_free (&name_obstack, pretty_name);
1680 SET_DECL_DEBUG_EXPR (repl, access->expr);
1681 DECL_DEBUG_EXPR_IS_FROM (repl) = 1;
1682 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
1684 else
1685 TREE_NO_WARNING (repl) = 1;
1687 if (dump_file)
1689 fprintf (dump_file, "Created a replacement for ");
1690 print_generic_expr (dump_file, access->base, 0);
1691 fprintf (dump_file, " offset: %u, size: %u: ",
1692 (unsigned) access->offset, (unsigned) access->size);
1693 print_generic_expr (dump_file, repl, 0);
1694 fprintf (dump_file, "\n");
1696 sra_stats.replacements++;
1698 return repl;
1701 /* Return ACCESS scalar replacement, create it if it does not exist yet. */
1703 static inline tree
1704 get_access_replacement (struct access *access)
1706 gcc_assert (access->grp_to_be_replaced);
1708 if (!access->replacement_decl)
1709 access->replacement_decl = create_access_replacement (access);
1710 return access->replacement_decl;
1713 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
1714 linked list along the way. Stop when *ACCESS is NULL or the access pointed
1715 to it is not "within" the root. */
1717 static void
1718 build_access_subtree (struct access **access)
1720 struct access *root = *access, *last_child = NULL;
1721 HOST_WIDE_INT limit = root->offset + root->size;
1723 *access = (*access)->next_grp;
1724 while (*access && (*access)->offset + (*access)->size <= limit)
1726 if (!last_child)
1727 root->first_child = *access;
1728 else
1729 last_child->next_sibling = *access;
1730 last_child = *access;
1732 build_access_subtree (access);
1736 /* Build a tree of access representatives, ACCESS is the pointer to the first
1737 one, others are linked in a list by the next_grp field. Decide about scalar
1738 replacements on the way, return true iff any are to be created. */
1740 static void
1741 build_access_trees (struct access *access)
1743 while (access)
1745 struct access *root = access;
1747 build_access_subtree (&access);
1748 root->next_grp = access;
1752 /* Return true if expr contains some ARRAY_REFs into a variable bounded
1753 array. */
1755 static bool
1756 expr_with_var_bounded_array_refs_p (tree expr)
1758 while (handled_component_p (expr))
1760 if (TREE_CODE (expr) == ARRAY_REF
1761 && !host_integerp (array_ref_low_bound (expr), 0))
1762 return true;
1763 expr = TREE_OPERAND (expr, 0);
1765 return false;
1768 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
1769 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set
1770 all sorts of access flags appropriately along the way, notably always ser
1771 grp_read when MARK_READ is true and grp_write when MARK_WRITE is true. */
1773 static bool
1774 analyze_access_subtree (struct access *root, bool allow_replacements,
1775 bool mark_read, bool mark_write)
1777 struct access *child;
1778 HOST_WIDE_INT limit = root->offset + root->size;
1779 HOST_WIDE_INT covered_to = root->offset;
1780 bool scalar = is_gimple_reg_type (root->type);
1781 bool hole = false, sth_created = false;
1782 bool direct_read = root->grp_read;
1784 if (mark_read)
1785 root->grp_read = true;
1786 else if (root->grp_read)
1787 mark_read = true;
1789 if (mark_write)
1790 root->grp_write = true;
1791 else if (root->grp_write)
1792 mark_write = true;
1794 if (root->grp_unscalarizable_region)
1795 allow_replacements = false;
1797 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
1798 allow_replacements = false;
1800 for (child = root->first_child; child; child = child->next_sibling)
1802 if (!hole && child->offset < covered_to)
1803 hole = true;
1804 else
1805 covered_to += child->size;
1807 sth_created |= analyze_access_subtree (child, allow_replacements,
1808 mark_read, mark_write);
1810 root->grp_unscalarized_data |= child->grp_unscalarized_data;
1811 hole |= !child->grp_covered;
1814 if (allow_replacements && scalar && !root->first_child
1815 && (root->grp_hint
1816 || (direct_read && root->grp_write))
1817 /* We must not ICE later on when trying to build an access to the
1818 original data within the aggregate even when it is impossible to do in
1819 a defined way like in the PR 42703 testcase. Therefore we check
1820 pre-emptively here that we will be able to do that. */
1821 && build_ref_for_offset (NULL, TREE_TYPE (root->base), root->offset,
1822 root->type, false))
1824 if (dump_file && (dump_flags & TDF_DETAILS))
1826 fprintf (dump_file, "Marking ");
1827 print_generic_expr (dump_file, root->base, 0);
1828 fprintf (dump_file, " offset: %u, size: %u: ",
1829 (unsigned) root->offset, (unsigned) root->size);
1830 fprintf (dump_file, " to be replaced.\n");
1833 root->grp_to_be_replaced = 1;
1834 sth_created = true;
1835 hole = false;
1837 else if (covered_to < limit)
1838 hole = true;
1840 if (sth_created && !hole)
1842 root->grp_covered = 1;
1843 return true;
1845 if (root->grp_write || TREE_CODE (root->base) == PARM_DECL)
1846 root->grp_unscalarized_data = 1; /* not covered and written to */
1847 if (sth_created)
1848 return true;
1849 return false;
1852 /* Analyze all access trees linked by next_grp by the means of
1853 analyze_access_subtree. */
1854 static bool
1855 analyze_access_trees (struct access *access)
1857 bool ret = false;
1859 while (access)
1861 if (analyze_access_subtree (access, true, false, false))
1862 ret = true;
1863 access = access->next_grp;
1866 return ret;
1869 /* Return true iff a potential new child of LACC at offset OFFSET and with size
1870 SIZE would conflict with an already existing one. If exactly such a child
1871 already exists in LACC, store a pointer to it in EXACT_MATCH. */
1873 static bool
1874 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
1875 HOST_WIDE_INT size, struct access **exact_match)
1877 struct access *child;
1879 for (child = lacc->first_child; child; child = child->next_sibling)
1881 if (child->offset == norm_offset && child->size == size)
1883 *exact_match = child;
1884 return true;
1887 if (child->offset < norm_offset + size
1888 && child->offset + child->size > norm_offset)
1889 return true;
1892 return false;
1895 /* Create a new child access of PARENT, with all properties just like MODEL
1896 except for its offset and with its grp_write false and grp_read true.
1897 Return the new access or NULL if it cannot be created. Note that this access
1898 is created long after all splicing and sorting, it's not located in any
1899 access vector and is automatically a representative of its group. */
1901 static struct access *
1902 create_artificial_child_access (struct access *parent, struct access *model,
1903 HOST_WIDE_INT new_offset)
1905 struct access *access;
1906 struct access **child;
1907 tree expr = parent->base;;
1909 gcc_assert (!model->grp_unscalarizable_region);
1911 if (!build_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
1912 model->type, false))
1913 return NULL;
1915 access = (struct access *) pool_alloc (access_pool);
1916 memset (access, 0, sizeof (struct access));
1917 access->base = parent->base;
1918 access->expr = expr;
1919 access->offset = new_offset;
1920 access->size = model->size;
1921 access->type = model->type;
1922 access->grp_write = true;
1923 access->grp_read = false;
1925 child = &parent->first_child;
1926 while (*child && (*child)->offset < new_offset)
1927 child = &(*child)->next_sibling;
1929 access->next_sibling = *child;
1930 *child = access;
1932 return access;
1936 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
1937 true if any new subaccess was created. Additionally, if RACC is a scalar
1938 access but LACC is not, change the type of the latter, if possible. */
1940 static bool
1941 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
1943 struct access *rchild;
1944 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
1945 bool ret = false;
1947 if (is_gimple_reg_type (lacc->type)
1948 || lacc->grp_unscalarizable_region
1949 || racc->grp_unscalarizable_region)
1950 return false;
1952 if (!lacc->first_child && !racc->first_child
1953 && is_gimple_reg_type (racc->type))
1955 tree t = lacc->base;
1957 if (build_ref_for_offset (&t, TREE_TYPE (t), lacc->offset, racc->type,
1958 false))
1960 lacc->expr = t;
1961 lacc->type = racc->type;
1963 return false;
1966 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
1968 struct access *new_acc = NULL;
1969 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
1971 if (rchild->grp_unscalarizable_region)
1972 continue;
1974 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
1975 &new_acc))
1977 if (new_acc)
1979 rchild->grp_hint = 1;
1980 new_acc->grp_hint |= new_acc->grp_read;
1981 if (rchild->first_child)
1982 ret |= propagate_subaccesses_across_link (new_acc, rchild);
1984 continue;
1987 /* If a (part of) a union field is on the RHS of an assignment, it can
1988 have sub-accesses which do not make sense on the LHS (PR 40351).
1989 Check that this is not the case. */
1990 if (!build_ref_for_offset (NULL, TREE_TYPE (lacc->base), norm_offset,
1991 rchild->type, false))
1992 continue;
1994 rchild->grp_hint = 1;
1995 new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
1996 if (new_acc)
1998 ret = true;
1999 if (racc->first_child)
2000 propagate_subaccesses_across_link (new_acc, rchild);
2004 return ret;
2007 /* Propagate all subaccesses across assignment links. */
2009 static void
2010 propagate_all_subaccesses (void)
2012 while (work_queue_head)
2014 struct access *racc = pop_access_from_work_queue ();
2015 struct assign_link *link;
2017 gcc_assert (racc->first_link);
2019 for (link = racc->first_link; link; link = link->next)
2021 struct access *lacc = link->lacc;
2023 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
2024 continue;
2025 lacc = lacc->group_representative;
2026 if (propagate_subaccesses_across_link (lacc, racc)
2027 && lacc->first_link)
2028 add_access_to_work_queue (lacc);
2033 /* Go through all accesses collected throughout the (intraprocedural) analysis
2034 stage, exclude overlapping ones, identify representatives and build trees
2035 out of them, making decisions about scalarization on the way. Return true
2036 iff there are any to-be-scalarized variables after this stage. */
2038 static bool
2039 analyze_all_variable_accesses (void)
2041 int res = 0;
2042 bitmap tmp = BITMAP_ALLOC (NULL);
2043 bitmap_iterator bi;
2044 unsigned i, max_total_scalarization_size;
2046 max_total_scalarization_size = UNITS_PER_WORD * BITS_PER_UNIT
2047 * MOVE_RATIO (optimize_function_for_speed_p (cfun));
2049 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
2050 if (bitmap_bit_p (should_scalarize_away_bitmap, i)
2051 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
2053 tree var = referenced_var (i);
2055 if (TREE_CODE (var) == VAR_DECL
2056 && ((unsigned) tree_low_cst (TYPE_SIZE (TREE_TYPE (var)), 1)
2057 <= max_total_scalarization_size)
2058 && type_consists_of_records_p (TREE_TYPE (var)))
2060 completely_scalarize_record (var, var, 0);
2061 if (dump_file && (dump_flags & TDF_DETAILS))
2063 fprintf (dump_file, "Will attempt to totally scalarize ");
2064 print_generic_expr (dump_file, var, 0);
2065 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2070 bitmap_copy (tmp, candidate_bitmap);
2071 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2073 tree var = referenced_var (i);
2074 struct access *access;
2076 access = sort_and_splice_var_accesses (var);
2077 if (access)
2078 build_access_trees (access);
2079 else
2080 disqualify_candidate (var,
2081 "No or inhibitingly overlapping accesses.");
2084 propagate_all_subaccesses ();
2086 bitmap_copy (tmp, candidate_bitmap);
2087 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2089 tree var = referenced_var (i);
2090 struct access *access = get_first_repr_for_decl (var);
2092 if (analyze_access_trees (access))
2094 res++;
2095 if (dump_file && (dump_flags & TDF_DETAILS))
2097 fprintf (dump_file, "\nAccess trees for ");
2098 print_generic_expr (dump_file, var, 0);
2099 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2100 dump_access_tree (dump_file, access);
2101 fprintf (dump_file, "\n");
2104 else
2105 disqualify_candidate (var, "No scalar replacements to be created.");
2108 BITMAP_FREE (tmp);
2110 if (res)
2112 statistics_counter_event (cfun, "Scalarized aggregates", res);
2113 return true;
2115 else
2116 return false;
2119 /* Return true iff a reference statement into aggregate AGG can be built for
2120 every single to-be-replaced accesses that is a child of ACCESS, its sibling
2121 or a child of its sibling. TOP_OFFSET is the offset from the processed
2122 access subtree that has to be subtracted from offset of each access. */
2124 static bool
2125 ref_expr_for_all_replacements_p (struct access *access, tree agg,
2126 HOST_WIDE_INT top_offset)
2130 if (access->grp_to_be_replaced
2131 && !build_ref_for_offset (NULL, TREE_TYPE (agg),
2132 access->offset - top_offset,
2133 access->type, false))
2134 return false;
2136 if (access->first_child
2137 && !ref_expr_for_all_replacements_p (access->first_child, agg,
2138 top_offset))
2139 return false;
2141 access = access->next_sibling;
2143 while (access);
2145 return true;
2148 /* Generate statements copying scalar replacements of accesses within a subtree
2149 into or out of AGG. ACCESS is the first child of the root of the subtree to
2150 be processed. AGG is an aggregate type expression (can be a declaration but
2151 does not have to be, it can for example also be an indirect_ref).
2152 TOP_OFFSET is the offset of the processed subtree which has to be subtracted
2153 from offsets of individual accesses to get corresponding offsets for AGG.
2154 If CHUNK_SIZE is non-null, copy only replacements in the interval
2155 <start_offset, start_offset + chunk_size>, otherwise copy all. GSI is a
2156 statement iterator used to place the new statements. WRITE should be true
2157 when the statements should write from AGG to the replacement and false if
2158 vice versa. if INSERT_AFTER is true, new statements will be added after the
2159 current statement in GSI, they will be added before the statement
2160 otherwise. */
2162 static void
2163 generate_subtree_copies (struct access *access, tree agg,
2164 HOST_WIDE_INT top_offset,
2165 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
2166 gimple_stmt_iterator *gsi, bool write,
2167 bool insert_after)
2171 tree expr = agg;
2173 if (chunk_size && access->offset >= start_offset + chunk_size)
2174 return;
2176 if (access->grp_to_be_replaced
2177 && (chunk_size == 0
2178 || access->offset + access->size > start_offset))
2180 tree repl = get_access_replacement (access);
2181 bool ref_found;
2182 gimple stmt;
2184 ref_found = build_ref_for_offset (&expr, TREE_TYPE (agg),
2185 access->offset - top_offset,
2186 access->type, false);
2187 gcc_assert (ref_found);
2189 if (write)
2191 if (access->grp_partial_lhs)
2192 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
2193 !insert_after,
2194 insert_after ? GSI_NEW_STMT
2195 : GSI_SAME_STMT);
2196 stmt = gimple_build_assign (repl, expr);
2198 else
2200 TREE_NO_WARNING (repl) = 1;
2201 if (access->grp_partial_lhs)
2202 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2203 !insert_after,
2204 insert_after ? GSI_NEW_STMT
2205 : GSI_SAME_STMT);
2206 stmt = gimple_build_assign (expr, repl);
2209 if (insert_after)
2210 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2211 else
2212 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2213 update_stmt (stmt);
2214 sra_stats.subtree_copies++;
2217 if (access->first_child)
2218 generate_subtree_copies (access->first_child, agg, top_offset,
2219 start_offset, chunk_size, gsi,
2220 write, insert_after);
2222 access = access->next_sibling;
2224 while (access);
2227 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2228 the root of the subtree to be processed. GSI is the statement iterator used
2229 for inserting statements which are added after the current statement if
2230 INSERT_AFTER is true or before it otherwise. */
2232 static void
2233 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
2234 bool insert_after)
2237 struct access *child;
2239 if (access->grp_to_be_replaced)
2241 gimple stmt;
2243 stmt = gimple_build_assign (get_access_replacement (access),
2244 fold_convert (access->type,
2245 integer_zero_node));
2246 if (insert_after)
2247 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2248 else
2249 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2250 update_stmt (stmt);
2253 for (child = access->first_child; child; child = child->next_sibling)
2254 init_subtree_with_zero (child, gsi, insert_after);
2257 /* Search for an access representative for the given expression EXPR and
2258 return it or NULL if it cannot be found. */
2260 static struct access *
2261 get_access_for_expr (tree expr)
2263 HOST_WIDE_INT offset, size, max_size;
2264 tree base;
2266 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2267 a different size than the size of its argument and we need the latter
2268 one. */
2269 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
2270 expr = TREE_OPERAND (expr, 0);
2272 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
2273 if (max_size == -1 || !DECL_P (base))
2274 return NULL;
2276 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
2277 return NULL;
2279 return get_var_base_offset_size_access (base, offset, max_size);
2282 /* Callback for scan_function. Replace the expression EXPR with a scalar
2283 replacement if there is one and generate other statements to do type
2284 conversion or subtree copying if necessary. GSI is used to place newly
2285 created statements, WRITE is true if the expression is being written to (it
2286 is on a LHS of a statement or output in an assembly statement). */
2288 static bool
2289 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write,
2290 void *data ATTRIBUTE_UNUSED)
2292 struct access *access;
2293 tree type, bfr;
2295 if (TREE_CODE (*expr) == BIT_FIELD_REF)
2297 bfr = *expr;
2298 expr = &TREE_OPERAND (*expr, 0);
2300 else
2301 bfr = NULL_TREE;
2303 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
2304 expr = &TREE_OPERAND (*expr, 0);
2305 access = get_access_for_expr (*expr);
2306 if (!access)
2307 return false;
2308 type = TREE_TYPE (*expr);
2310 if (access->grp_to_be_replaced)
2312 tree repl = get_access_replacement (access);
2313 /* If we replace a non-register typed access simply use the original
2314 access expression to extract the scalar component afterwards.
2315 This happens if scalarizing a function return value or parameter
2316 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2317 gcc.c-torture/compile/20011217-1.c.
2319 We also want to use this when accessing a complex or vector which can
2320 be accessed as a different type too, potentially creating a need for
2321 type conversion (see PR42196) and when scalarized unions are involved
2322 in assembler statements (see PR42398). */
2323 if (!useless_type_conversion_p (type, access->type))
2325 tree ref = access->base;
2326 bool ok;
2328 ok = build_ref_for_offset (&ref, TREE_TYPE (ref),
2329 access->offset, access->type, false);
2330 gcc_assert (ok);
2332 if (write)
2334 gimple stmt;
2336 if (access->grp_partial_lhs)
2337 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
2338 false, GSI_NEW_STMT);
2339 stmt = gimple_build_assign (repl, ref);
2340 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2342 else
2344 gimple stmt;
2346 if (access->grp_partial_lhs)
2347 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2348 true, GSI_SAME_STMT);
2349 stmt = gimple_build_assign (ref, repl);
2350 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2353 else
2354 *expr = repl;
2355 sra_stats.exprs++;
2358 if (access->first_child)
2360 HOST_WIDE_INT start_offset, chunk_size;
2361 if (bfr
2362 && host_integerp (TREE_OPERAND (bfr, 1), 1)
2363 && host_integerp (TREE_OPERAND (bfr, 2), 1))
2365 chunk_size = tree_low_cst (TREE_OPERAND (bfr, 1), 1);
2366 start_offset = access->offset
2367 + tree_low_cst (TREE_OPERAND (bfr, 2), 1);
2369 else
2370 start_offset = chunk_size = 0;
2372 generate_subtree_copies (access->first_child, access->base, 0,
2373 start_offset, chunk_size, gsi, write, write);
2375 return true;
2378 /* Where scalar replacements of the RHS have been written to when a replacement
2379 of a LHS of an assigments cannot be direclty loaded from a replacement of
2380 the RHS. */
2381 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
2382 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
2383 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
2385 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2386 base aggregate if there are unscalarized data or directly to LHS
2387 otherwise. */
2389 static enum unscalarized_data_handling
2390 handle_unscalarized_data_in_subtree (struct access *top_racc, tree lhs,
2391 gimple_stmt_iterator *gsi)
2393 if (top_racc->grp_unscalarized_data)
2395 generate_subtree_copies (top_racc->first_child, top_racc->base, 0, 0, 0,
2396 gsi, false, false);
2397 return SRA_UDH_RIGHT;
2399 else
2401 generate_subtree_copies (top_racc->first_child, lhs, top_racc->offset,
2402 0, 0, gsi, false, false);
2403 return SRA_UDH_LEFT;
2408 /* Try to generate statements to load all sub-replacements in an access
2409 (sub)tree (LACC is the first child) from scalar replacements in the TOP_RACC
2410 (sub)tree. If that is not possible, refresh the TOP_RACC base aggregate and
2411 load the accesses from it. LEFT_OFFSET is the offset of the left whole
2412 subtree being copied, RIGHT_OFFSET is the same thing for the right subtree.
2413 GSI is stmt iterator used for statement insertions. *REFRESHED is true iff
2414 the rhs top aggregate has already been refreshed by contents of its scalar
2415 reductions and is set to true if this function has to do it. */
2417 static void
2418 load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
2419 HOST_WIDE_INT left_offset,
2420 HOST_WIDE_INT right_offset,
2421 gimple_stmt_iterator *old_gsi,
2422 gimple_stmt_iterator *new_gsi,
2423 enum unscalarized_data_handling *refreshed,
2424 tree lhs)
2426 location_t loc = EXPR_LOCATION (lacc->expr);
2429 if (lacc->grp_to_be_replaced)
2431 struct access *racc;
2432 HOST_WIDE_INT offset = lacc->offset - left_offset + right_offset;
2433 gimple stmt;
2434 tree rhs;
2436 racc = find_access_in_subtree (top_racc, offset, lacc->size);
2437 if (racc && racc->grp_to_be_replaced)
2439 rhs = get_access_replacement (racc);
2440 if (!useless_type_conversion_p (lacc->type, racc->type))
2441 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, lacc->type, rhs);
2443 else
2445 /* No suitable access on the right hand side, need to load from
2446 the aggregate. See if we have to update it first... */
2447 if (*refreshed == SRA_UDH_NONE)
2448 *refreshed = handle_unscalarized_data_in_subtree (top_racc,
2449 lhs, old_gsi);
2451 if (*refreshed == SRA_UDH_LEFT)
2453 bool repl_found;
2455 rhs = lacc->base;
2456 repl_found = build_ref_for_offset (&rhs, TREE_TYPE (rhs),
2457 lacc->offset, lacc->type,
2458 false);
2459 gcc_assert (repl_found);
2461 else
2463 bool repl_found;
2465 rhs = top_racc->base;
2466 repl_found = build_ref_for_offset (&rhs,
2467 TREE_TYPE (top_racc->base),
2468 offset, lacc->type, false);
2469 gcc_assert (repl_found);
2473 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
2474 gsi_insert_after (new_gsi, stmt, GSI_NEW_STMT);
2475 update_stmt (stmt);
2476 sra_stats.subreplacements++;
2478 else if (*refreshed == SRA_UDH_NONE
2479 && lacc->grp_read && !lacc->grp_covered)
2480 *refreshed = handle_unscalarized_data_in_subtree (top_racc, lhs,
2481 old_gsi);
2483 if (lacc->first_child)
2484 load_assign_lhs_subreplacements (lacc->first_child, top_racc,
2485 left_offset, right_offset,
2486 old_gsi, new_gsi, refreshed, lhs);
2487 lacc = lacc->next_sibling;
2489 while (lacc);
2492 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
2493 to the assignment and GSI is the statement iterator pointing at it. Returns
2494 the same values as sra_modify_assign. */
2496 static enum scan_assign_result
2497 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
2499 tree lhs = gimple_assign_lhs (*stmt);
2500 struct access *acc;
2502 acc = get_access_for_expr (lhs);
2503 if (!acc)
2504 return SRA_SA_NONE;
2506 if (VEC_length (constructor_elt,
2507 CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt))) > 0)
2509 /* I have never seen this code path trigger but if it can happen the
2510 following should handle it gracefully. */
2511 if (access_has_children_p (acc))
2512 generate_subtree_copies (acc->first_child, acc->base, 0, 0, 0, gsi,
2513 true, true);
2514 return SRA_SA_PROCESSED;
2517 if (acc->grp_covered)
2519 init_subtree_with_zero (acc, gsi, false);
2520 unlink_stmt_vdef (*stmt);
2521 gsi_remove (gsi, true);
2522 return SRA_SA_REMOVED;
2524 else
2526 init_subtree_with_zero (acc, gsi, true);
2527 return SRA_SA_PROCESSED;
2531 /* Create a new suitable default definition SSA_NAME and replace all uses of
2532 SSA with it. */
2534 static void
2535 replace_uses_with_default_def_ssa_name (tree ssa)
2537 tree repl, decl = SSA_NAME_VAR (ssa);
2538 if (TREE_CODE (decl) == PARM_DECL)
2540 tree tmp = create_tmp_reg (TREE_TYPE (decl), "SR");
2542 get_var_ann (tmp);
2543 add_referenced_var (tmp);
2544 repl = make_ssa_name (tmp, gimple_build_nop ());
2545 set_default_def (tmp, repl);
2547 else
2549 repl = gimple_default_def (cfun, decl);
2550 if (!repl)
2552 repl = make_ssa_name (decl, gimple_build_nop ());
2553 set_default_def (decl, repl);
2557 replace_uses_by (ssa, repl);
2560 /* Callback of scan_function to process assign statements. It examines both
2561 sides of the statement, replaces them with a scalare replacement if there is
2562 one and generating copying of replacements if scalarized aggregates have been
2563 used in the assignment. STMT is a pointer to the assign statement, GSI is
2564 used to hold generated statements for type conversions and subtree
2565 copying. */
2567 static enum scan_assign_result
2568 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi,
2569 void *data ATTRIBUTE_UNUSED)
2571 struct access *lacc, *racc;
2572 tree lhs, rhs;
2573 bool modify_this_stmt = false;
2574 bool force_gimple_rhs = false;
2575 location_t loc = gimple_location (*stmt);
2576 gimple_stmt_iterator orig_gsi = *gsi;
2578 if (!gimple_assign_single_p (*stmt))
2579 return SRA_SA_NONE;
2580 lhs = gimple_assign_lhs (*stmt);
2581 rhs = gimple_assign_rhs1 (*stmt);
2583 if (TREE_CODE (rhs) == CONSTRUCTOR)
2584 return sra_modify_constructor_assign (stmt, gsi);
2586 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
2587 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
2588 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
2590 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (*stmt),
2591 gsi, false, data);
2592 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (*stmt),
2593 gsi, true, data);
2594 return modify_this_stmt ? SRA_SA_PROCESSED : SRA_SA_NONE;
2597 lacc = get_access_for_expr (lhs);
2598 racc = get_access_for_expr (rhs);
2599 if (!lacc && !racc)
2600 return SRA_SA_NONE;
2602 if (lacc && lacc->grp_to_be_replaced)
2604 lhs = get_access_replacement (lacc);
2605 gimple_assign_set_lhs (*stmt, lhs);
2606 modify_this_stmt = true;
2607 if (lacc->grp_partial_lhs)
2608 force_gimple_rhs = true;
2609 sra_stats.exprs++;
2612 if (racc && racc->grp_to_be_replaced)
2614 rhs = get_access_replacement (racc);
2615 modify_this_stmt = true;
2616 if (racc->grp_partial_lhs)
2617 force_gimple_rhs = true;
2618 sra_stats.exprs++;
2621 if (modify_this_stmt)
2623 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
2625 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
2626 ??? This should move to fold_stmt which we simply should
2627 call after building a VIEW_CONVERT_EXPR here. */
2628 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
2629 && !access_has_children_p (lacc))
2631 tree expr = lhs;
2632 if (build_ref_for_offset (&expr, TREE_TYPE (lhs), 0,
2633 TREE_TYPE (rhs), false))
2635 lhs = expr;
2636 gimple_assign_set_lhs (*stmt, expr);
2639 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
2640 && !access_has_children_p (racc))
2642 tree expr = rhs;
2643 if (build_ref_for_offset (&expr, TREE_TYPE (rhs), 0,
2644 TREE_TYPE (lhs), false))
2645 rhs = expr;
2647 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
2649 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs);
2650 if (is_gimple_reg_type (TREE_TYPE (lhs))
2651 && TREE_CODE (lhs) != SSA_NAME)
2652 force_gimple_rhs = true;
2657 /* From this point on, the function deals with assignments in between
2658 aggregates when at least one has scalar reductions of some of its
2659 components. There are three possible scenarios: Both the LHS and RHS have
2660 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
2662 In the first case, we would like to load the LHS components from RHS
2663 components whenever possible. If that is not possible, we would like to
2664 read it directly from the RHS (after updating it by storing in it its own
2665 components). If there are some necessary unscalarized data in the LHS,
2666 those will be loaded by the original assignment too. If neither of these
2667 cases happen, the original statement can be removed. Most of this is done
2668 by load_assign_lhs_subreplacements.
2670 In the second case, we would like to store all RHS scalarized components
2671 directly into LHS and if they cover the aggregate completely, remove the
2672 statement too. In the third case, we want the LHS components to be loaded
2673 directly from the RHS (DSE will remove the original statement if it
2674 becomes redundant).
2676 This is a bit complex but manageable when types match and when unions do
2677 not cause confusion in a way that we cannot really load a component of LHS
2678 from the RHS or vice versa (the access representing this level can have
2679 subaccesses that are accessible only through a different union field at a
2680 higher level - different from the one used in the examined expression).
2681 Unions are fun.
2683 Therefore, I specially handle a fourth case, happening when there is a
2684 specific type cast or it is impossible to locate a scalarized subaccess on
2685 the other side of the expression. If that happens, I simply "refresh" the
2686 RHS by storing in it is scalarized components leave the original statement
2687 there to do the copying and then load the scalar replacements of the LHS.
2688 This is what the first branch does. */
2690 if (gimple_has_volatile_ops (*stmt)
2691 || contains_view_convert_expr_p (rhs)
2692 || contains_view_convert_expr_p (lhs)
2693 || (access_has_children_p (racc)
2694 && !ref_expr_for_all_replacements_p (racc, lhs, racc->offset))
2695 || (access_has_children_p (lacc)
2696 && !ref_expr_for_all_replacements_p (lacc, rhs, lacc->offset)))
2698 if (access_has_children_p (racc))
2699 generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
2700 gsi, false, false);
2701 if (access_has_children_p (lacc))
2702 generate_subtree_copies (lacc->first_child, lacc->base, 0, 0, 0,
2703 gsi, true, true);
2704 sra_stats.separate_lhs_rhs_handling++;
2706 else
2708 if (access_has_children_p (lacc) && access_has_children_p (racc))
2710 gimple_stmt_iterator orig_gsi = *gsi;
2711 enum unscalarized_data_handling refreshed;
2713 if (lacc->grp_read && !lacc->grp_covered)
2714 refreshed = handle_unscalarized_data_in_subtree (racc, lhs, gsi);
2715 else
2716 refreshed = SRA_UDH_NONE;
2718 load_assign_lhs_subreplacements (lacc->first_child, racc,
2719 lacc->offset, racc->offset,
2720 &orig_gsi, gsi, &refreshed, lhs);
2721 if (refreshed != SRA_UDH_RIGHT)
2723 if (*stmt == gsi_stmt (*gsi))
2724 gsi_next (gsi);
2726 unlink_stmt_vdef (*stmt);
2727 gsi_remove (&orig_gsi, true);
2728 sra_stats.deleted++;
2729 return SRA_SA_REMOVED;
2732 else
2734 if (racc)
2736 if (!racc->grp_to_be_replaced && !racc->grp_unscalarized_data)
2738 if (racc->first_child)
2739 generate_subtree_copies (racc->first_child, lhs,
2740 racc->offset, 0, 0, gsi,
2741 false, false);
2742 gcc_assert (*stmt == gsi_stmt (*gsi));
2743 if (TREE_CODE (lhs) == SSA_NAME)
2744 replace_uses_with_default_def_ssa_name (lhs);
2746 unlink_stmt_vdef (*stmt);
2747 gsi_remove (gsi, true);
2748 sra_stats.deleted++;
2749 return SRA_SA_REMOVED;
2751 else if (racc->first_child)
2752 generate_subtree_copies (racc->first_child, lhs,
2753 racc->offset, 0, 0, gsi, false, true);
2755 if (access_has_children_p (lacc))
2756 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
2757 0, 0, gsi, true, true);
2761 /* This gimplification must be done after generate_subtree_copies, lest we
2762 insert the subtree copies in the middle of the gimplified sequence. */
2763 if (force_gimple_rhs)
2764 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
2765 true, GSI_SAME_STMT);
2766 if (gimple_assign_rhs1 (*stmt) != rhs)
2768 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
2769 gcc_assert (*stmt == gsi_stmt (orig_gsi));
2772 return modify_this_stmt ? SRA_SA_PROCESSED : SRA_SA_NONE;
2775 /* Generate statements initializing scalar replacements of parts of function
2776 parameters. */
2778 static void
2779 initialize_parameter_reductions (void)
2781 gimple_stmt_iterator gsi;
2782 gimple_seq seq = NULL;
2783 tree parm;
2785 for (parm = DECL_ARGUMENTS (current_function_decl);
2786 parm;
2787 parm = TREE_CHAIN (parm))
2789 VEC (access_p, heap) *access_vec;
2790 struct access *access;
2792 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
2793 continue;
2794 access_vec = get_base_access_vector (parm);
2795 if (!access_vec)
2796 continue;
2798 if (!seq)
2800 seq = gimple_seq_alloc ();
2801 gsi = gsi_start (seq);
2804 for (access = VEC_index (access_p, access_vec, 0);
2805 access;
2806 access = access->next_grp)
2807 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true);
2810 if (seq)
2811 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR), seq);
2814 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
2815 it reveals there are components of some aggregates to be scalarized, it runs
2816 the required transformations. */
2817 static unsigned int
2818 perform_intra_sra (void)
2820 int ret = 0;
2821 sra_initialize ();
2823 if (!find_var_candidates ())
2824 goto out;
2826 if (!scan_function (build_access_from_expr, build_accesses_from_assign, NULL,
2827 true, NULL))
2828 goto out;
2830 if (!analyze_all_variable_accesses ())
2831 goto out;
2833 scan_function (sra_modify_expr, sra_modify_assign, NULL, false, NULL);
2834 initialize_parameter_reductions ();
2836 statistics_counter_event (cfun, "Scalar replacements created",
2837 sra_stats.replacements);
2838 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
2839 statistics_counter_event (cfun, "Subtree copy stmts",
2840 sra_stats.subtree_copies);
2841 statistics_counter_event (cfun, "Subreplacement stmts",
2842 sra_stats.subreplacements);
2843 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
2844 statistics_counter_event (cfun, "Separate LHS and RHS handling",
2845 sra_stats.separate_lhs_rhs_handling);
2847 ret = TODO_update_ssa;
2849 out:
2850 sra_deinitialize ();
2851 return ret;
2854 /* Perform early intraprocedural SRA. */
2855 static unsigned int
2856 early_intra_sra (void)
2858 sra_mode = SRA_MODE_EARLY_INTRA;
2859 return perform_intra_sra ();
2862 /* Perform "late" intraprocedural SRA. */
2863 static unsigned int
2864 late_intra_sra (void)
2866 sra_mode = SRA_MODE_INTRA;
2867 return perform_intra_sra ();
2871 static bool
2872 gate_intra_sra (void)
2874 return flag_tree_sra != 0;
2878 struct gimple_opt_pass pass_sra_early =
2881 GIMPLE_PASS,
2882 "esra", /* name */
2883 gate_intra_sra, /* gate */
2884 early_intra_sra, /* execute */
2885 NULL, /* sub */
2886 NULL, /* next */
2887 0, /* static_pass_number */
2888 TV_TREE_SRA, /* tv_id */
2889 PROP_cfg | PROP_ssa, /* properties_required */
2890 0, /* properties_provided */
2891 0, /* properties_destroyed */
2892 0, /* todo_flags_start */
2893 TODO_dump_func
2894 | TODO_update_ssa
2895 | TODO_ggc_collect
2896 | TODO_verify_ssa /* todo_flags_finish */
2900 struct gimple_opt_pass pass_sra =
2903 GIMPLE_PASS,
2904 "sra", /* name */
2905 gate_intra_sra, /* gate */
2906 late_intra_sra, /* execute */
2907 NULL, /* sub */
2908 NULL, /* next */
2909 0, /* static_pass_number */
2910 TV_TREE_SRA, /* tv_id */
2911 PROP_cfg | PROP_ssa, /* properties_required */
2912 0, /* properties_provided */
2913 0, /* properties_destroyed */
2914 TODO_update_address_taken, /* todo_flags_start */
2915 TODO_dump_func
2916 | TODO_update_ssa
2917 | TODO_ggc_collect
2918 | TODO_verify_ssa /* todo_flags_finish */
2923 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
2924 parameter. */
2926 static bool
2927 is_unused_scalar_param (tree parm)
2929 tree name;
2930 return (is_gimple_reg (parm)
2931 && (!(name = gimple_default_def (cfun, parm))
2932 || has_zero_uses (name)));
2935 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
2936 examine whether there are any direct or otherwise infeasible ones. If so,
2937 return true, otherwise return false. PARM must be a gimple register with a
2938 non-NULL default definition. */
2940 static bool
2941 ptr_parm_has_direct_uses (tree parm)
2943 imm_use_iterator ui;
2944 gimple stmt;
2945 tree name = gimple_default_def (cfun, parm);
2946 bool ret = false;
2948 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
2950 int uses_ok = 0;
2951 use_operand_p use_p;
2953 if (is_gimple_debug (stmt))
2954 continue;
2956 /* Valid uses include dereferences on the lhs and the rhs. */
2957 if (gimple_has_lhs (stmt))
2959 tree lhs = gimple_get_lhs (stmt);
2960 while (handled_component_p (lhs))
2961 lhs = TREE_OPERAND (lhs, 0);
2962 if (INDIRECT_REF_P (lhs)
2963 && TREE_OPERAND (lhs, 0) == name)
2964 uses_ok++;
2966 if (gimple_assign_single_p (stmt))
2968 tree rhs = gimple_assign_rhs1 (stmt);
2969 while (handled_component_p (rhs))
2970 rhs = TREE_OPERAND (rhs, 0);
2971 if (INDIRECT_REF_P (rhs)
2972 && TREE_OPERAND (rhs, 0) == name)
2973 uses_ok++;
2975 else if (is_gimple_call (stmt))
2977 unsigned i;
2978 for (i = 0; i < gimple_call_num_args (stmt); ++i)
2980 tree arg = gimple_call_arg (stmt, i);
2981 while (handled_component_p (arg))
2982 arg = TREE_OPERAND (arg, 0);
2983 if (INDIRECT_REF_P (arg)
2984 && TREE_OPERAND (arg, 0) == name)
2985 uses_ok++;
2989 /* If the number of valid uses does not match the number of
2990 uses in this stmt there is an unhandled use. */
2991 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
2992 --uses_ok;
2994 if (uses_ok != 0)
2995 ret = true;
2997 if (ret)
2998 BREAK_FROM_IMM_USE_STMT (ui);
3001 return ret;
3004 /* Identify candidates for reduction for IPA-SRA based on their type and mark
3005 them in candidate_bitmap. Note that these do not necessarily include
3006 parameter which are unused and thus can be removed. Return true iff any
3007 such candidate has been found. */
3009 static bool
3010 find_param_candidates (void)
3012 tree parm;
3013 int count = 0;
3014 bool ret = false;
3016 for (parm = DECL_ARGUMENTS (current_function_decl);
3017 parm;
3018 parm = TREE_CHAIN (parm))
3020 tree type = TREE_TYPE (parm);
3022 count++;
3024 if (TREE_THIS_VOLATILE (parm)
3025 || TREE_ADDRESSABLE (parm)
3026 || (!is_gimple_reg_type (type) && is_va_list_type (type)))
3027 continue;
3029 if (is_unused_scalar_param (parm))
3031 ret = true;
3032 continue;
3035 if (POINTER_TYPE_P (type))
3037 type = TREE_TYPE (type);
3039 if (TREE_CODE (type) == FUNCTION_TYPE
3040 || TYPE_VOLATILE (type)
3041 || !is_gimple_reg (parm)
3042 || is_va_list_type (type)
3043 || ptr_parm_has_direct_uses (parm))
3044 continue;
3046 else if (!AGGREGATE_TYPE_P (type))
3047 continue;
3049 if (!COMPLETE_TYPE_P (type)
3050 || !host_integerp (TYPE_SIZE (type), 1)
3051 || tree_low_cst (TYPE_SIZE (type), 1) == 0
3052 || (AGGREGATE_TYPE_P (type)
3053 && type_internals_preclude_sra_p (type)))
3054 continue;
3056 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
3057 ret = true;
3058 if (dump_file && (dump_flags & TDF_DETAILS))
3060 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
3061 print_generic_expr (dump_file, parm, 0);
3062 fprintf (dump_file, "\n");
3066 func_param_count = count;
3067 return ret;
3070 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
3071 maybe_modified. */
3073 static bool
3074 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
3075 void *data)
3077 struct access *repr = (struct access *) data;
3079 repr->grp_maybe_modified = 1;
3080 return true;
3083 /* Analyze what representatives (in linked lists accessible from
3084 REPRESENTATIVES) can be modified by side effects of statements in the
3085 current function. */
3087 static void
3088 analyze_modified_params (VEC (access_p, heap) *representatives)
3090 int i;
3092 for (i = 0; i < func_param_count; i++)
3094 struct access *repr;
3096 for (repr = VEC_index (access_p, representatives, i);
3097 repr;
3098 repr = repr->next_grp)
3100 struct access *access;
3101 bitmap visited;
3102 ao_ref ar;
3104 if (no_accesses_p (repr))
3105 continue;
3106 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
3107 || repr->grp_maybe_modified)
3108 continue;
3110 ao_ref_init (&ar, repr->expr);
3111 visited = BITMAP_ALLOC (NULL);
3112 for (access = repr; access; access = access->next_sibling)
3114 /* All accesses are read ones, otherwise grp_maybe_modified would
3115 be trivially set. */
3116 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
3117 mark_maybe_modified, repr, &visited);
3118 if (repr->grp_maybe_modified)
3119 break;
3121 BITMAP_FREE (visited);
3126 /* Propagate distances in bb_dereferences in the opposite direction than the
3127 control flow edges, in each step storing the maximum of the current value
3128 and the minimum of all successors. These steps are repeated until the table
3129 stabilizes. Note that BBs which might terminate the functions (according to
3130 final_bbs bitmap) never updated in this way. */
3132 static void
3133 propagate_dereference_distances (void)
3135 VEC (basic_block, heap) *queue;
3136 basic_block bb;
3138 queue = VEC_alloc (basic_block, heap, last_basic_block_for_function (cfun));
3139 VEC_quick_push (basic_block, queue, ENTRY_BLOCK_PTR);
3140 FOR_EACH_BB (bb)
3142 VEC_quick_push (basic_block, queue, bb);
3143 bb->aux = bb;
3146 while (!VEC_empty (basic_block, queue))
3148 edge_iterator ei;
3149 edge e;
3150 bool change = false;
3151 int i;
3153 bb = VEC_pop (basic_block, queue);
3154 bb->aux = NULL;
3156 if (bitmap_bit_p (final_bbs, bb->index))
3157 continue;
3159 for (i = 0; i < func_param_count; i++)
3161 int idx = bb->index * func_param_count + i;
3162 bool first = true;
3163 HOST_WIDE_INT inh = 0;
3165 FOR_EACH_EDGE (e, ei, bb->succs)
3167 int succ_idx = e->dest->index * func_param_count + i;
3169 if (e->src == EXIT_BLOCK_PTR)
3170 continue;
3172 if (first)
3174 first = false;
3175 inh = bb_dereferences [succ_idx];
3177 else if (bb_dereferences [succ_idx] < inh)
3178 inh = bb_dereferences [succ_idx];
3181 if (!first && bb_dereferences[idx] < inh)
3183 bb_dereferences[idx] = inh;
3184 change = true;
3188 if (change && !bitmap_bit_p (final_bbs, bb->index))
3189 FOR_EACH_EDGE (e, ei, bb->preds)
3191 if (e->src->aux)
3192 continue;
3194 e->src->aux = e->src;
3195 VEC_quick_push (basic_block, queue, e->src);
3199 VEC_free (basic_block, heap, queue);
3202 /* Dump a dereferences TABLE with heading STR to file F. */
3204 static void
3205 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
3207 basic_block bb;
3209 fprintf (dump_file, str);
3210 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
3212 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
3213 if (bb != EXIT_BLOCK_PTR)
3215 int i;
3216 for (i = 0; i < func_param_count; i++)
3218 int idx = bb->index * func_param_count + i;
3219 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
3222 fprintf (f, "\n");
3224 fprintf (dump_file, "\n");
3227 /* Determine what (parts of) parameters passed by reference that are not
3228 assigned to are not certainly dereferenced in this function and thus the
3229 dereferencing cannot be safely moved to the caller without potentially
3230 introducing a segfault. Mark such REPRESENTATIVES as
3231 grp_not_necessarilly_dereferenced.
3233 The dereferenced maximum "distance," i.e. the offset + size of the accessed
3234 part is calculated rather than simple booleans are calculated for each
3235 pointer parameter to handle cases when only a fraction of the whole
3236 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
3237 an example).
3239 The maximum dereference distances for each pointer parameter and BB are
3240 already stored in bb_dereference. This routine simply propagates these
3241 values upwards by propagate_dereference_distances and then compares the
3242 distances of individual parameters in the ENTRY BB to the equivalent
3243 distances of each representative of a (fraction of a) parameter. */
3245 static void
3246 analyze_caller_dereference_legality (VEC (access_p, heap) *representatives)
3248 int i;
3250 if (dump_file && (dump_flags & TDF_DETAILS))
3251 dump_dereferences_table (dump_file,
3252 "Dereference table before propagation:\n",
3253 bb_dereferences);
3255 propagate_dereference_distances ();
3257 if (dump_file && (dump_flags & TDF_DETAILS))
3258 dump_dereferences_table (dump_file,
3259 "Dereference table after propagation:\n",
3260 bb_dereferences);
3262 for (i = 0; i < func_param_count; i++)
3264 struct access *repr = VEC_index (access_p, representatives, i);
3265 int idx = ENTRY_BLOCK_PTR->index * func_param_count + i;
3267 if (!repr || no_accesses_p (repr))
3268 continue;
3272 if ((repr->offset + repr->size) > bb_dereferences[idx])
3273 repr->grp_not_necessarilly_dereferenced = 1;
3274 repr = repr->next_grp;
3276 while (repr);
3280 /* Return the representative access for the parameter declaration PARM if it is
3281 a scalar passed by reference which is not written to and the pointer value
3282 is not used directly. Thus, if it is legal to dereference it in the caller
3283 and we can rule out modifications through aliases, such parameter should be
3284 turned into one passed by value. Return NULL otherwise. */
3286 static struct access *
3287 unmodified_by_ref_scalar_representative (tree parm)
3289 int i, access_count;
3290 struct access *repr;
3291 VEC (access_p, heap) *access_vec;
3293 access_vec = get_base_access_vector (parm);
3294 gcc_assert (access_vec);
3295 repr = VEC_index (access_p, access_vec, 0);
3296 if (repr->write)
3297 return NULL;
3298 repr->group_representative = repr;
3300 access_count = VEC_length (access_p, access_vec);
3301 for (i = 1; i < access_count; i++)
3303 struct access *access = VEC_index (access_p, access_vec, i);
3304 if (access->write)
3305 return NULL;
3306 access->group_representative = repr;
3307 access->next_sibling = repr->next_sibling;
3308 repr->next_sibling = access;
3311 repr->grp_read = 1;
3312 repr->grp_scalar_ptr = 1;
3313 return repr;
3316 /* Return true iff this access precludes IPA-SRA of the parameter it is
3317 associated with. */
3319 static bool
3320 access_precludes_ipa_sra_p (struct access *access)
3322 /* Avoid issues such as the second simple testcase in PR 42025. The problem
3323 is incompatible assign in a call statement (and possibly even in asm
3324 statements). This can be relaxed by using a new temporary but only for
3325 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
3326 intraprocedural SRA we deal with this by keeping the old aggregate around,
3327 something we cannot do in IPA-SRA.) */
3328 if (access->write
3329 && (is_gimple_call (access->stmt)
3330 || gimple_code (access->stmt) == GIMPLE_ASM))
3331 return true;
3333 return false;
3337 /* Sort collected accesses for parameter PARM, identify representatives for
3338 each accessed region and link them together. Return NULL if there are
3339 different but overlapping accesses, return the special ptr value meaning
3340 there are no accesses for this parameter if that is the case and return the
3341 first representative otherwise. Set *RO_GRP if there is a group of accesses
3342 with only read (i.e. no write) accesses. */
3344 static struct access *
3345 splice_param_accesses (tree parm, bool *ro_grp)
3347 int i, j, access_count, group_count;
3348 int agg_size, total_size = 0;
3349 struct access *access, *res, **prev_acc_ptr = &res;
3350 VEC (access_p, heap) *access_vec;
3352 access_vec = get_base_access_vector (parm);
3353 if (!access_vec)
3354 return &no_accesses_representant;
3355 access_count = VEC_length (access_p, access_vec);
3357 qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
3358 compare_access_positions);
3360 i = 0;
3361 total_size = 0;
3362 group_count = 0;
3363 while (i < access_count)
3365 bool modification;
3366 access = VEC_index (access_p, access_vec, i);
3367 modification = access->write;
3368 if (access_precludes_ipa_sra_p (access))
3369 return NULL;
3371 /* Access is about to become group representative unless we find some
3372 nasty overlap which would preclude us from breaking this parameter
3373 apart. */
3375 j = i + 1;
3376 while (j < access_count)
3378 struct access *ac2 = VEC_index (access_p, access_vec, j);
3379 if (ac2->offset != access->offset)
3381 /* All or nothing law for parameters. */
3382 if (access->offset + access->size > ac2->offset)
3383 return NULL;
3384 else
3385 break;
3387 else if (ac2->size != access->size)
3388 return NULL;
3390 if (access_precludes_ipa_sra_p (ac2))
3391 return NULL;
3393 modification |= ac2->write;
3394 ac2->group_representative = access;
3395 ac2->next_sibling = access->next_sibling;
3396 access->next_sibling = ac2;
3397 j++;
3400 group_count++;
3401 access->grp_maybe_modified = modification;
3402 if (!modification)
3403 *ro_grp = true;
3404 *prev_acc_ptr = access;
3405 prev_acc_ptr = &access->next_grp;
3406 total_size += access->size;
3407 i = j;
3410 if (POINTER_TYPE_P (TREE_TYPE (parm)))
3411 agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))), 1);
3412 else
3413 agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (parm)), 1);
3414 if (total_size >= agg_size)
3415 return NULL;
3417 gcc_assert (group_count > 0);
3418 return res;
3421 /* Decide whether parameters with representative accesses given by REPR should
3422 be reduced into components. */
3424 static int
3425 decide_one_param_reduction (struct access *repr)
3427 int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
3428 bool by_ref;
3429 tree parm;
3431 parm = repr->base;
3432 cur_parm_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (parm)), 1);
3433 gcc_assert (cur_parm_size > 0);
3435 if (POINTER_TYPE_P (TREE_TYPE (parm)))
3437 by_ref = true;
3438 agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))), 1);
3440 else
3442 by_ref = false;
3443 agg_size = cur_parm_size;
3446 if (dump_file)
3448 struct access *acc;
3449 fprintf (dump_file, "Evaluating PARAM group sizes for ");
3450 print_generic_expr (dump_file, parm, 0);
3451 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
3452 for (acc = repr; acc; acc = acc->next_grp)
3453 dump_access (dump_file, acc, true);
3456 total_size = 0;
3457 new_param_count = 0;
3459 for (; repr; repr = repr->next_grp)
3461 gcc_assert (parm == repr->base);
3462 new_param_count++;
3464 if (!by_ref || (!repr->grp_maybe_modified
3465 && !repr->grp_not_necessarilly_dereferenced))
3466 total_size += repr->size;
3467 else
3468 total_size += cur_parm_size;
3471 gcc_assert (new_param_count > 0);
3473 if (optimize_function_for_size_p (cfun))
3474 parm_size_limit = cur_parm_size;
3475 else
3476 parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
3477 * cur_parm_size);
3479 if (total_size < agg_size
3480 && total_size <= parm_size_limit)
3482 if (dump_file)
3483 fprintf (dump_file, " ....will be split into %i components\n",
3484 new_param_count);
3485 return new_param_count;
3487 else
3488 return 0;
3491 /* The order of the following enums is important, we need to do extra work for
3492 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
3493 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
3494 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
3496 /* Identify representatives of all accesses to all candidate parameters for
3497 IPA-SRA. Return result based on what representatives have been found. */
3499 static enum ipa_splicing_result
3500 splice_all_param_accesses (VEC (access_p, heap) **representatives)
3502 enum ipa_splicing_result result = NO_GOOD_ACCESS;
3503 tree parm;
3504 struct access *repr;
3506 *representatives = VEC_alloc (access_p, heap, func_param_count);
3508 for (parm = DECL_ARGUMENTS (current_function_decl);
3509 parm;
3510 parm = TREE_CHAIN (parm))
3512 if (is_unused_scalar_param (parm))
3514 VEC_quick_push (access_p, *representatives,
3515 &no_accesses_representant);
3516 if (result == NO_GOOD_ACCESS)
3517 result = UNUSED_PARAMS;
3519 else if (POINTER_TYPE_P (TREE_TYPE (parm))
3520 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
3521 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3523 repr = unmodified_by_ref_scalar_representative (parm);
3524 VEC_quick_push (access_p, *representatives, repr);
3525 if (repr)
3526 result = UNMODIF_BY_REF_ACCESSES;
3528 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3530 bool ro_grp = false;
3531 repr = splice_param_accesses (parm, &ro_grp);
3532 VEC_quick_push (access_p, *representatives, repr);
3534 if (repr && !no_accesses_p (repr))
3536 if (POINTER_TYPE_P (TREE_TYPE (parm)))
3538 if (ro_grp)
3539 result = UNMODIF_BY_REF_ACCESSES;
3540 else if (result < MODIF_BY_REF_ACCESSES)
3541 result = MODIF_BY_REF_ACCESSES;
3543 else if (result < BY_VAL_ACCESSES)
3544 result = BY_VAL_ACCESSES;
3546 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
3547 result = UNUSED_PARAMS;
3549 else
3550 VEC_quick_push (access_p, *representatives, NULL);
3553 if (result == NO_GOOD_ACCESS)
3555 VEC_free (access_p, heap, *representatives);
3556 *representatives = NULL;
3557 return NO_GOOD_ACCESS;
3560 return result;
3563 /* Return the index of BASE in PARMS. Abort if it is not found. */
3565 static inline int
3566 get_param_index (tree base, VEC(tree, heap) *parms)
3568 int i, len;
3570 len = VEC_length (tree, parms);
3571 for (i = 0; i < len; i++)
3572 if (VEC_index (tree, parms, i) == base)
3573 return i;
3574 gcc_unreachable ();
3577 /* Convert the decisions made at the representative level into compact
3578 parameter adjustments. REPRESENTATIVES are pointers to first
3579 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
3580 final number of adjustments. */
3582 static ipa_parm_adjustment_vec
3583 turn_representatives_into_adjustments (VEC (access_p, heap) *representatives,
3584 int adjustments_count)
3586 VEC (tree, heap) *parms;
3587 ipa_parm_adjustment_vec adjustments;
3588 tree parm;
3589 int i;
3591 gcc_assert (adjustments_count > 0);
3592 parms = ipa_get_vector_of_formal_parms (current_function_decl);
3593 adjustments = VEC_alloc (ipa_parm_adjustment_t, heap, adjustments_count);
3594 parm = DECL_ARGUMENTS (current_function_decl);
3595 for (i = 0; i < func_param_count; i++, parm = TREE_CHAIN (parm))
3597 struct access *repr = VEC_index (access_p, representatives, i);
3599 if (!repr || no_accesses_p (repr))
3601 struct ipa_parm_adjustment *adj;
3603 adj = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
3604 memset (adj, 0, sizeof (*adj));
3605 adj->base_index = get_param_index (parm, parms);
3606 adj->base = parm;
3607 if (!repr)
3608 adj->copy_param = 1;
3609 else
3610 adj->remove_param = 1;
3612 else
3614 struct ipa_parm_adjustment *adj;
3615 int index = get_param_index (parm, parms);
3617 for (; repr; repr = repr->next_grp)
3619 adj = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
3620 memset (adj, 0, sizeof (*adj));
3621 gcc_assert (repr->base == parm);
3622 adj->base_index = index;
3623 adj->base = repr->base;
3624 adj->type = repr->type;
3625 adj->offset = repr->offset;
3626 adj->by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
3627 && (repr->grp_maybe_modified
3628 || repr->grp_not_necessarilly_dereferenced));
3633 VEC_free (tree, heap, parms);
3634 return adjustments;
3637 /* Analyze the collected accesses and produce a plan what to do with the
3638 parameters in the form of adjustments, NULL meaning nothing. */
3640 static ipa_parm_adjustment_vec
3641 analyze_all_param_acesses (void)
3643 enum ipa_splicing_result repr_state;
3644 bool proceed = false;
3645 int i, adjustments_count = 0;
3646 VEC (access_p, heap) *representatives;
3647 ipa_parm_adjustment_vec adjustments;
3649 repr_state = splice_all_param_accesses (&representatives);
3650 if (repr_state == NO_GOOD_ACCESS)
3651 return NULL;
3653 /* If there are any parameters passed by reference which are not modified
3654 directly, we need to check whether they can be modified indirectly. */
3655 if (repr_state == UNMODIF_BY_REF_ACCESSES)
3657 analyze_caller_dereference_legality (representatives);
3658 analyze_modified_params (representatives);
3661 for (i = 0; i < func_param_count; i++)
3663 struct access *repr = VEC_index (access_p, representatives, i);
3665 if (repr && !no_accesses_p (repr))
3667 if (repr->grp_scalar_ptr)
3669 adjustments_count++;
3670 if (repr->grp_not_necessarilly_dereferenced
3671 || repr->grp_maybe_modified)
3672 VEC_replace (access_p, representatives, i, NULL);
3673 else
3675 proceed = true;
3676 sra_stats.scalar_by_ref_to_by_val++;
3679 else
3681 int new_components = decide_one_param_reduction (repr);
3683 if (new_components == 0)
3685 VEC_replace (access_p, representatives, i, NULL);
3686 adjustments_count++;
3688 else
3690 adjustments_count += new_components;
3691 sra_stats.aggregate_params_reduced++;
3692 sra_stats.param_reductions_created += new_components;
3693 proceed = true;
3697 else
3699 if (no_accesses_p (repr))
3701 proceed = true;
3702 sra_stats.deleted_unused_parameters++;
3704 adjustments_count++;
3708 if (!proceed && dump_file)
3709 fprintf (dump_file, "NOT proceeding to change params.\n");
3711 if (proceed)
3712 adjustments = turn_representatives_into_adjustments (representatives,
3713 adjustments_count);
3714 else
3715 adjustments = NULL;
3717 VEC_free (access_p, heap, representatives);
3718 return adjustments;
3721 /* If a parameter replacement identified by ADJ does not yet exist in the form
3722 of declaration, create it and record it, otherwise return the previously
3723 created one. */
3725 static tree
3726 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
3728 tree repl;
3729 if (!adj->new_ssa_base)
3731 char *pretty_name = make_fancy_name (adj->base);
3733 repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR");
3734 DECL_NAME (repl) = get_identifier (pretty_name);
3735 obstack_free (&name_obstack, pretty_name);
3737 get_var_ann (repl);
3738 add_referenced_var (repl);
3739 adj->new_ssa_base = repl;
3741 else
3742 repl = adj->new_ssa_base;
3743 return repl;
3746 /* Find the first adjustment for a particular parameter BASE in a vector of
3747 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
3748 adjustment. */
3750 static struct ipa_parm_adjustment *
3751 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
3753 int i, len;
3755 len = VEC_length (ipa_parm_adjustment_t, adjustments);
3756 for (i = 0; i < len; i++)
3758 struct ipa_parm_adjustment *adj;
3760 adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3761 if (!adj->copy_param && adj->base == base)
3762 return adj;
3765 return NULL;
3768 /* Callback for scan_function. If the statement STMT defines an SSA_NAME of a
3769 parameter which is to be removed because its value is not used, replace the
3770 SSA_NAME with a one relating to a created VAR_DECL and replace all of its
3771 uses too and return true (update_stmt is then issued for the statement by
3772 the caller). DATA is a pointer to an adjustments vector. */
3774 static bool
3775 replace_removed_params_ssa_names (gimple stmt, void *data)
3777 VEC (ipa_parm_adjustment_t, heap) *adjustments;
3778 struct ipa_parm_adjustment *adj;
3779 tree lhs, decl, repl, name;
3781 adjustments = (VEC (ipa_parm_adjustment_t, heap) *) data;
3782 if (gimple_code (stmt) == GIMPLE_PHI)
3783 lhs = gimple_phi_result (stmt);
3784 else if (is_gimple_assign (stmt))
3785 lhs = gimple_assign_lhs (stmt);
3786 else if (is_gimple_call (stmt))
3787 lhs = gimple_call_lhs (stmt);
3788 else
3789 gcc_unreachable ();
3791 if (TREE_CODE (lhs) != SSA_NAME)
3792 return false;
3793 decl = SSA_NAME_VAR (lhs);
3794 if (TREE_CODE (decl) != PARM_DECL)
3795 return false;
3797 adj = get_adjustment_for_base (adjustments, decl);
3798 if (!adj)
3799 return false;
3801 repl = get_replaced_param_substitute (adj);
3802 name = make_ssa_name (repl, stmt);
3804 if (dump_file)
3806 fprintf (dump_file, "replacing an SSA name of a removed param ");
3807 print_generic_expr (dump_file, lhs, 0);
3808 fprintf (dump_file, " with ");
3809 print_generic_expr (dump_file, name, 0);
3810 fprintf (dump_file, "\n");
3813 if (is_gimple_assign (stmt))
3814 gimple_assign_set_lhs (stmt, name);
3815 else if (is_gimple_call (stmt))
3816 gimple_call_set_lhs (stmt, name);
3817 else
3818 gimple_phi_set_result (stmt, name);
3820 replace_uses_by (lhs, name);
3821 return true;
3824 /* Callback for scan_function and helper to sra_ipa_modify_assign. If the
3825 expression *EXPR should be replaced by a reduction of a parameter, do so.
3826 DATA is a pointer to a vector of adjustments. DONT_CONVERT specifies
3827 whether the function should care about type incompatibility the current and
3828 new expressions. If it is true, the function will leave incompatibility
3829 issues to the caller.
3831 When called directly by scan_function, DONT_CONVERT is true when the EXPR is
3832 a write (LHS) expression. */
3834 static bool
3835 sra_ipa_modify_expr (tree *expr, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
3836 bool dont_convert, void *data)
3838 ipa_parm_adjustment_vec adjustments;
3839 int i, len;
3840 struct ipa_parm_adjustment *adj, *cand = NULL;
3841 HOST_WIDE_INT offset, size, max_size;
3842 tree base, src;
3844 adjustments = (VEC (ipa_parm_adjustment_t, heap) *) data;
3845 len = VEC_length (ipa_parm_adjustment_t, adjustments);
3847 if (TREE_CODE (*expr) == BIT_FIELD_REF
3848 || TREE_CODE (*expr) == IMAGPART_EXPR
3849 || TREE_CODE (*expr) == REALPART_EXPR)
3851 expr = &TREE_OPERAND (*expr, 0);
3852 dont_convert = false;
3855 base = get_ref_base_and_extent (*expr, &offset, &size, &max_size);
3856 if (!base || size == -1 || max_size == -1)
3857 return false;
3859 if (INDIRECT_REF_P (base))
3860 base = TREE_OPERAND (base, 0);
3862 base = get_ssa_base_param (base);
3863 if (!base || TREE_CODE (base) != PARM_DECL)
3864 return false;
3866 for (i = 0; i < len; i++)
3868 adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3870 if (adj->base == base &&
3871 (adj->offset == offset || adj->remove_param))
3873 cand = adj;
3874 break;
3877 if (!cand || cand->copy_param || cand->remove_param)
3878 return false;
3880 if (cand->by_ref)
3882 tree folded;
3883 src = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (cand->reduction)),
3884 cand->reduction);
3885 folded = gimple_fold_indirect_ref (src);
3886 if (folded)
3887 src = folded;
3889 else
3890 src = cand->reduction;
3892 if (dump_file && (dump_flags & TDF_DETAILS))
3894 fprintf (dump_file, "About to replace expr ");
3895 print_generic_expr (dump_file, *expr, 0);
3896 fprintf (dump_file, " with ");
3897 print_generic_expr (dump_file, src, 0);
3898 fprintf (dump_file, "\n");
3901 if (!dont_convert
3902 && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
3904 tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
3905 *expr = vce;
3907 else
3908 *expr = src;
3909 return true;
3912 /* Callback for scan_function to process assign statements. Performs
3913 essentially the same function like sra_ipa_modify_expr. */
3915 static enum scan_assign_result
3916 sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi, void *data)
3918 gimple stmt = *stmt_ptr;
3919 tree *lhs_p, *rhs_p;
3920 bool any;
3922 if (!gimple_assign_single_p (stmt))
3923 return SRA_SA_NONE;
3925 rhs_p = gimple_assign_rhs1_ptr (stmt);
3926 lhs_p = gimple_assign_lhs_ptr (stmt);
3928 any = sra_ipa_modify_expr (rhs_p, gsi, true, data);
3929 any |= sra_ipa_modify_expr (lhs_p, gsi, true, data);
3930 if (any)
3932 tree new_rhs = NULL_TREE;
3934 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
3936 if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
3938 /* V_C_Es of constructors can cause trouble (PR 42714). */
3939 if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
3940 *rhs_p = fold_convert (TREE_TYPE (*lhs_p), integer_zero_node);
3941 else
3942 *rhs_p = build_constructor (TREE_TYPE (*lhs_p), 0);
3944 else
3945 new_rhs = fold_build1_loc (gimple_location (stmt),
3946 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
3947 *rhs_p);
3949 else if (REFERENCE_CLASS_P (*rhs_p)
3950 && is_gimple_reg_type (TREE_TYPE (*lhs_p))
3951 && !is_gimple_reg (*lhs_p))
3952 /* This can happen when an assignment in between two single field
3953 structures is turned into an assignment in between two pointers to
3954 scalars (PR 42237). */
3955 new_rhs = *rhs_p;
3957 if (new_rhs)
3959 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
3960 true, GSI_SAME_STMT);
3962 gimple_assign_set_rhs_from_tree (gsi, tmp);
3965 return SRA_SA_PROCESSED;
3968 return SRA_SA_NONE;
3971 /* Call gimple_debug_bind_reset_value on all debug statements describing
3972 gimple register parameters that are being removed or replaced. */
3974 static void
3975 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
3977 int i, len;
3979 len = VEC_length (ipa_parm_adjustment_t, adjustments);
3980 for (i = 0; i < len; i++)
3982 struct ipa_parm_adjustment *adj;
3983 imm_use_iterator ui;
3984 gimple stmt;
3985 tree name;
3987 adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3988 if (adj->copy_param || !is_gimple_reg (adj->base))
3989 continue;
3990 name = gimple_default_def (cfun, adj->base);
3991 if (!name)
3992 continue;
3993 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
3995 /* All other users must have been removed by scan_function. */
3996 gcc_assert (is_gimple_debug (stmt));
3997 gimple_debug_bind_reset_value (stmt);
3998 update_stmt (stmt);
4003 /* Return true iff all callers have at least as many actual arguments as there
4004 are formal parameters in the current function. */
4006 static bool
4007 all_callers_have_enough_arguments_p (struct cgraph_node *node)
4009 struct cgraph_edge *cs;
4010 for (cs = node->callers; cs; cs = cs->next_caller)
4011 if (!callsite_has_enough_arguments_p (cs->call_stmt))
4012 return false;
4014 return true;
4018 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
4020 static void
4021 convert_callers (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
4023 tree old_cur_fndecl = current_function_decl;
4024 struct cgraph_edge *cs;
4025 basic_block this_block;
4026 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
4028 for (cs = node->callers; cs; cs = cs->next_caller)
4030 current_function_decl = cs->caller->decl;
4031 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
4033 if (dump_file)
4034 fprintf (dump_file, "Adjusting call (%i -> %i) %s -> %s\n",
4035 cs->caller->uid, cs->callee->uid,
4036 cgraph_node_name (cs->caller),
4037 cgraph_node_name (cs->callee));
4039 ipa_modify_call_arguments (cs, cs->call_stmt, adjustments);
4041 pop_cfun ();
4044 for (cs = node->callers; cs; cs = cs->next_caller)
4045 if (!bitmap_bit_p (recomputed_callers, cs->caller->uid))
4047 compute_inline_parameters (cs->caller);
4048 bitmap_set_bit (recomputed_callers, cs->caller->uid);
4050 BITMAP_FREE (recomputed_callers);
4052 current_function_decl = old_cur_fndecl;
4054 if (!encountered_recursive_call)
4055 return;
4057 FOR_EACH_BB (this_block)
4059 gimple_stmt_iterator gsi;
4061 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
4063 gimple stmt = gsi_stmt (gsi);
4064 tree call_fndecl;
4065 if (gimple_code (stmt) != GIMPLE_CALL)
4066 continue;
4067 call_fndecl = gimple_call_fndecl (stmt);
4068 if (call_fndecl && cgraph_get_node (call_fndecl) == node)
4070 if (dump_file)
4071 fprintf (dump_file, "Adjusting recursive call");
4072 ipa_modify_call_arguments (NULL, stmt, adjustments);
4077 return;
4080 /* Create an abstract origin declaration for OLD_DECL and make it an abstract
4081 origin of the provided decl so that there are preserved parameters for debug
4082 information. */
4084 static void
4085 create_abstract_origin (tree old_decl)
4087 if (!DECL_ABSTRACT_ORIGIN (old_decl))
4089 tree new_decl = copy_node (old_decl);
4091 DECL_ABSTRACT (new_decl) = 1;
4092 SET_DECL_ASSEMBLER_NAME (new_decl, NULL_TREE);
4093 SET_DECL_RTL (new_decl, NULL);
4094 DECL_STRUCT_FUNCTION (new_decl) = NULL;
4095 DECL_ARTIFICIAL (old_decl) = 1;
4096 DECL_ABSTRACT_ORIGIN (old_decl) = new_decl;
4100 /* Perform all the modification required in IPA-SRA for NODE to have parameters
4101 as given in ADJUSTMENTS. */
4103 static void
4104 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
4106 struct cgraph_node *alias;
4107 for (alias = node->same_body; alias; alias = alias->next)
4108 ipa_modify_formal_parameters (alias->decl, adjustments, "ISRA");
4109 /* current_function_decl must be handled last, after same_body aliases,
4110 as following functions will use what it computed. */
4111 create_abstract_origin (current_function_decl);
4112 ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA");
4113 scan_function (sra_ipa_modify_expr, sra_ipa_modify_assign,
4114 replace_removed_params_ssa_names, false, adjustments);
4115 sra_ipa_reset_debug_stmts (adjustments);
4116 convert_callers (node, adjustments);
4117 cgraph_make_node_local (node);
4118 return;
4121 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
4122 attributes, return true otherwise. NODE is the cgraph node of the current
4123 function. */
4125 static bool
4126 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
4128 if (!cgraph_node_can_be_local_p (node))
4130 if (dump_file)
4131 fprintf (dump_file, "Function not local to this compilation unit.\n");
4132 return false;
4135 if (DECL_VIRTUAL_P (current_function_decl))
4137 if (dump_file)
4138 fprintf (dump_file, "Function is a virtual method.\n");
4139 return false;
4142 if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
4143 && node->global.size >= MAX_INLINE_INSNS_AUTO)
4145 if (dump_file)
4146 fprintf (dump_file, "Function too big to be made truly local.\n");
4147 return false;
4150 if (!node->callers)
4152 if (dump_file)
4153 fprintf (dump_file,
4154 "Function has no callers in this compilation unit.\n");
4155 return false;
4158 if (cfun->stdarg)
4160 if (dump_file)
4161 fprintf (dump_file, "Function uses stdarg. \n");
4162 return false;
4165 return true;
4168 /* Perform early interprocedural SRA. */
4170 static unsigned int
4171 ipa_early_sra (void)
4173 struct cgraph_node *node = cgraph_node (current_function_decl);
4174 ipa_parm_adjustment_vec adjustments;
4175 int ret = 0;
4177 if (!ipa_sra_preliminary_function_checks (node))
4178 return 0;
4180 sra_initialize ();
4181 sra_mode = SRA_MODE_EARLY_IPA;
4183 if (!find_param_candidates ())
4185 if (dump_file)
4186 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
4187 goto simple_out;
4190 if (!all_callers_have_enough_arguments_p (node))
4192 if (dump_file)
4193 fprintf (dump_file, "There are callers with insufficient number of "
4194 "arguments.\n");
4195 goto simple_out;
4198 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
4199 func_param_count
4200 * last_basic_block_for_function (cfun));
4201 final_bbs = BITMAP_ALLOC (NULL);
4203 scan_function (build_access_from_expr, build_accesses_from_assign,
4204 NULL, true, NULL);
4205 if (encountered_apply_args)
4207 if (dump_file)
4208 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
4209 goto out;
4212 if (encountered_unchangable_recursive_call)
4214 if (dump_file)
4215 fprintf (dump_file, "Function calls itself with insufficient "
4216 "number of arguments.\n");
4217 goto out;
4220 adjustments = analyze_all_param_acesses ();
4221 if (!adjustments)
4222 goto out;
4223 if (dump_file)
4224 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
4226 modify_function (node, adjustments);
4227 VEC_free (ipa_parm_adjustment_t, heap, adjustments);
4228 ret = TODO_update_ssa;
4230 statistics_counter_event (cfun, "Unused parameters deleted",
4231 sra_stats.deleted_unused_parameters);
4232 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
4233 sra_stats.scalar_by_ref_to_by_val);
4234 statistics_counter_event (cfun, "Aggregate parameters broken up",
4235 sra_stats.aggregate_params_reduced);
4236 statistics_counter_event (cfun, "Aggregate parameter components created",
4237 sra_stats.param_reductions_created);
4239 out:
4240 BITMAP_FREE (final_bbs);
4241 free (bb_dereferences);
4242 simple_out:
4243 sra_deinitialize ();
4244 return ret;
4247 /* Return if early ipa sra shall be performed. */
4248 static bool
4249 ipa_early_sra_gate (void)
4251 return flag_ipa_sra;
4254 struct gimple_opt_pass pass_early_ipa_sra =
4257 GIMPLE_PASS,
4258 "eipa_sra", /* name */
4259 ipa_early_sra_gate, /* gate */
4260 ipa_early_sra, /* execute */
4261 NULL, /* sub */
4262 NULL, /* next */
4263 0, /* static_pass_number */
4264 TV_IPA_SRA, /* tv_id */
4265 0, /* properties_required */
4266 0, /* properties_provided */
4267 0, /* properties_destroyed */
4268 0, /* todo_flags_start */
4269 TODO_dump_func | TODO_dump_cgraph /* todo_flags_finish */