2010-04-20 Richard Guenther <rguenther@suse.de>
[official-gcc.git] / gcc / tree-sra.c
blobe1dd0d777e377ea9c380153c48f7be8cc3102b06
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 if (DECL_P (op))
1070 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
1072 return false;
1075 /* Return true iff callsite CALL has at least as many actual arguments as there
1076 are formal parameters of the function currently processed by IPA-SRA. */
1078 static inline bool
1079 callsite_has_enough_arguments_p (gimple call)
1081 return gimple_call_num_args (call) >= (unsigned) func_param_count;
1084 /* Scan function and look for interesting statements. Return true if any has
1085 been found or processed, as indicated by callbacks. SCAN_EXPR is a callback
1086 called on all expressions within statements except assign statements and
1087 those deemed entirely unsuitable for some reason (all operands in such
1088 statements and expression are removed from candidate_bitmap). SCAN_ASSIGN
1089 is a callback called on all assign statements, HANDLE_SSA_DEFS is a callback
1090 called on assign statements and those call statements which have a lhs, it
1091 can be NULL. ANALYSIS_STAGE is true when running in the analysis stage of a
1092 pass and thus no statement is being modified. DATA is a pointer passed to
1093 all callbacks. If any single callback returns true, this function also
1094 returns true, otherwise it returns false. */
1096 static bool
1097 scan_function (bool (*scan_expr) (tree *, gimple_stmt_iterator *, bool, void *),
1098 enum scan_assign_result (*scan_assign) (gimple *,
1099 gimple_stmt_iterator *,
1100 void *),
1101 bool (*handle_ssa_defs)(gimple, void *),
1102 bool analysis_stage, void *data)
1104 gimple_stmt_iterator gsi;
1105 basic_block bb;
1106 unsigned i;
1107 tree *t;
1108 bool ret = false;
1110 FOR_EACH_BB (bb)
1112 bool bb_changed = false;
1114 if (handle_ssa_defs)
1115 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1116 ret |= handle_ssa_defs (gsi_stmt (gsi), data);
1118 gsi = gsi_start_bb (bb);
1119 while (!gsi_end_p (gsi))
1121 gimple stmt = gsi_stmt (gsi);
1122 enum scan_assign_result assign_result;
1123 bool any = false, deleted = false;
1125 if (analysis_stage && final_bbs && stmt_can_throw_external (stmt))
1126 bitmap_set_bit (final_bbs, bb->index);
1127 switch (gimple_code (stmt))
1129 case GIMPLE_RETURN:
1130 t = gimple_return_retval_ptr (stmt);
1131 if (*t != NULL_TREE)
1132 any |= scan_expr (t, &gsi, false, data);
1133 if (analysis_stage && final_bbs)
1134 bitmap_set_bit (final_bbs, bb->index);
1135 break;
1137 case GIMPLE_ASSIGN:
1138 assign_result = scan_assign (&stmt, &gsi, data);
1139 any |= assign_result == SRA_SA_PROCESSED;
1140 deleted = assign_result == SRA_SA_REMOVED;
1141 if (handle_ssa_defs && assign_result != SRA_SA_REMOVED)
1142 any |= handle_ssa_defs (stmt, data);
1143 break;
1145 case GIMPLE_CALL:
1146 /* Operands must be processed before the lhs. */
1147 for (i = 0; i < gimple_call_num_args (stmt); i++)
1149 tree *argp = gimple_call_arg_ptr (stmt, i);
1150 any |= scan_expr (argp, &gsi, false, data);
1153 if (analysis_stage && sra_mode == SRA_MODE_EARLY_IPA)
1155 tree dest = gimple_call_fndecl (stmt);
1156 int flags = gimple_call_flags (stmt);
1158 if (dest)
1160 if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1161 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1162 encountered_apply_args = true;
1163 if (cgraph_get_node (dest)
1164 == cgraph_get_node (current_function_decl))
1166 encountered_recursive_call = true;
1167 if (!callsite_has_enough_arguments_p (stmt))
1168 encountered_unchangable_recursive_call = true;
1172 if (final_bbs
1173 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1174 bitmap_set_bit (final_bbs, bb->index);
1177 if (gimple_call_lhs (stmt))
1179 tree *lhs_ptr = gimple_call_lhs_ptr (stmt);
1180 if (!analysis_stage
1181 || !disqualify_ops_if_throwing_stmt (stmt,
1182 *lhs_ptr, NULL))
1184 any |= scan_expr (lhs_ptr, &gsi, true, data);
1185 if (handle_ssa_defs)
1186 any |= handle_ssa_defs (stmt, data);
1189 break;
1191 case GIMPLE_ASM:
1192 if (analysis_stage)
1194 walk_stmt_load_store_addr_ops (stmt, NULL, NULL, NULL,
1195 asm_visit_addr);
1196 if (final_bbs)
1197 bitmap_set_bit (final_bbs, bb->index);
1199 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
1201 tree *op = &TREE_VALUE (gimple_asm_input_op (stmt, i));
1202 any |= scan_expr (op, &gsi, false, data);
1204 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
1206 tree *op = &TREE_VALUE (gimple_asm_output_op (stmt, i));
1207 any |= scan_expr (op, &gsi, true, data);
1209 break;
1211 default:
1212 break;
1215 if (any)
1217 ret = true;
1219 if (!analysis_stage)
1221 bb_changed = true;
1222 update_stmt (stmt);
1223 maybe_clean_eh_stmt (stmt);
1226 if (deleted)
1227 bb_changed = true;
1228 else
1230 gsi_next (&gsi);
1231 ret = true;
1234 if (!analysis_stage && bb_changed && sra_mode == SRA_MODE_EARLY_IPA)
1235 gimple_purge_dead_eh_edges (bb);
1238 return ret;
1241 /* Helper of QSORT function. There are pointers to accesses in the array. An
1242 access is considered smaller than another if it has smaller offset or if the
1243 offsets are the same but is size is bigger. */
1245 static int
1246 compare_access_positions (const void *a, const void *b)
1248 const access_p *fp1 = (const access_p *) a;
1249 const access_p *fp2 = (const access_p *) b;
1250 const access_p f1 = *fp1;
1251 const access_p f2 = *fp2;
1253 if (f1->offset != f2->offset)
1254 return f1->offset < f2->offset ? -1 : 1;
1256 if (f1->size == f2->size)
1258 if (f1->type == f2->type)
1259 return 0;
1260 /* Put any non-aggregate type before any aggregate type. */
1261 else if (!is_gimple_reg_type (f1->type)
1262 && is_gimple_reg_type (f2->type))
1263 return 1;
1264 else if (is_gimple_reg_type (f1->type)
1265 && !is_gimple_reg_type (f2->type))
1266 return -1;
1267 /* Put any complex or vector type before any other scalar type. */
1268 else if (TREE_CODE (f1->type) != COMPLEX_TYPE
1269 && TREE_CODE (f1->type) != VECTOR_TYPE
1270 && (TREE_CODE (f2->type) == COMPLEX_TYPE
1271 || TREE_CODE (f2->type) == VECTOR_TYPE))
1272 return 1;
1273 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
1274 || TREE_CODE (f1->type) == VECTOR_TYPE)
1275 && TREE_CODE (f2->type) != COMPLEX_TYPE
1276 && TREE_CODE (f2->type) != VECTOR_TYPE)
1277 return -1;
1278 /* Put the integral type with the bigger precision first. */
1279 else if (INTEGRAL_TYPE_P (f1->type)
1280 && INTEGRAL_TYPE_P (f2->type))
1281 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
1282 /* Put any integral type with non-full precision last. */
1283 else if (INTEGRAL_TYPE_P (f1->type)
1284 && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type))
1285 != TYPE_PRECISION (f1->type)))
1286 return 1;
1287 else if (INTEGRAL_TYPE_P (f2->type)
1288 && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type))
1289 != TYPE_PRECISION (f2->type)))
1290 return -1;
1291 /* Stabilize the sort. */
1292 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1295 /* We want the bigger accesses first, thus the opposite operator in the next
1296 line: */
1297 return f1->size > f2->size ? -1 : 1;
1301 /* Append a name of the declaration to the name obstack. A helper function for
1302 make_fancy_name. */
1304 static void
1305 make_fancy_decl_name (tree decl)
1307 char buffer[32];
1309 tree name = DECL_NAME (decl);
1310 if (name)
1311 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1312 IDENTIFIER_LENGTH (name));
1313 else
1315 sprintf (buffer, "D%u", DECL_UID (decl));
1316 obstack_grow (&name_obstack, buffer, strlen (buffer));
1320 /* Helper for make_fancy_name. */
1322 static void
1323 make_fancy_name_1 (tree expr)
1325 char buffer[32];
1326 tree index;
1328 if (DECL_P (expr))
1330 make_fancy_decl_name (expr);
1331 return;
1334 switch (TREE_CODE (expr))
1336 case COMPONENT_REF:
1337 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1338 obstack_1grow (&name_obstack, '$');
1339 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1340 break;
1342 case ARRAY_REF:
1343 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1344 obstack_1grow (&name_obstack, '$');
1345 /* Arrays with only one element may not have a constant as their
1346 index. */
1347 index = TREE_OPERAND (expr, 1);
1348 if (TREE_CODE (index) != INTEGER_CST)
1349 break;
1350 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1351 obstack_grow (&name_obstack, buffer, strlen (buffer));
1353 break;
1355 case BIT_FIELD_REF:
1356 case REALPART_EXPR:
1357 case IMAGPART_EXPR:
1358 gcc_unreachable (); /* we treat these as scalars. */
1359 break;
1360 default:
1361 break;
1365 /* Create a human readable name for replacement variable of ACCESS. */
1367 static char *
1368 make_fancy_name (tree expr)
1370 make_fancy_name_1 (expr);
1371 obstack_1grow (&name_obstack, '\0');
1372 return XOBFINISH (&name_obstack, char *);
1375 /* Helper function for build_ref_for_offset. */
1377 static bool
1378 build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset,
1379 tree exp_type)
1381 while (1)
1383 tree fld;
1384 tree tr_size, index, minidx;
1385 HOST_WIDE_INT el_size;
1387 if (offset == 0 && exp_type
1388 && types_compatible_p (exp_type, type))
1389 return true;
1391 switch (TREE_CODE (type))
1393 case UNION_TYPE:
1394 case QUAL_UNION_TYPE:
1395 case RECORD_TYPE:
1396 for (fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
1398 HOST_WIDE_INT pos, size;
1399 tree expr, *expr_ptr;
1401 if (TREE_CODE (fld) != FIELD_DECL)
1402 continue;
1404 pos = int_bit_position (fld);
1405 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1406 tr_size = DECL_SIZE (fld);
1407 if (!tr_size || !host_integerp (tr_size, 1))
1408 continue;
1409 size = tree_low_cst (tr_size, 1);
1410 if (size == 0)
1412 if (pos != offset)
1413 continue;
1415 else if (pos > offset || (pos + size) <= offset)
1416 continue;
1418 if (res)
1420 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1421 NULL_TREE);
1422 expr_ptr = &expr;
1424 else
1425 expr_ptr = NULL;
1426 if (build_ref_for_offset_1 (expr_ptr, TREE_TYPE (fld),
1427 offset - pos, exp_type))
1429 if (res)
1430 *res = expr;
1431 return true;
1434 return false;
1436 case ARRAY_TYPE:
1437 tr_size = TYPE_SIZE (TREE_TYPE (type));
1438 if (!tr_size || !host_integerp (tr_size, 1))
1439 return false;
1440 el_size = tree_low_cst (tr_size, 1);
1442 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1443 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
1444 return false;
1445 if (res)
1447 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1448 if (!integer_zerop (minidx))
1449 index = int_const_binop (PLUS_EXPR, index, minidx, 0);
1450 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1451 NULL_TREE, NULL_TREE);
1453 offset = offset % el_size;
1454 type = TREE_TYPE (type);
1455 break;
1457 default:
1458 if (offset != 0)
1459 return false;
1461 if (exp_type)
1462 return false;
1463 else
1464 return true;
1469 /* Construct an expression that would reference a part of aggregate *EXPR of
1470 type TYPE at the given OFFSET of the type EXP_TYPE. If EXPR is NULL, the
1471 function only determines whether it can build such a reference without
1472 actually doing it, otherwise, the tree it points to is unshared first and
1473 then used as a base for furhter sub-references.
1475 FIXME: Eventually this should be replaced with
1476 maybe_fold_offset_to_reference() from tree-ssa-ccp.c but that requires a
1477 minor rewrite of fold_stmt.
1480 bool
1481 build_ref_for_offset (tree *expr, tree type, HOST_WIDE_INT offset,
1482 tree exp_type, bool allow_ptr)
1484 location_t loc = expr ? EXPR_LOCATION (*expr) : UNKNOWN_LOCATION;
1486 if (expr)
1487 *expr = unshare_expr (*expr);
1489 if (allow_ptr && POINTER_TYPE_P (type))
1491 type = TREE_TYPE (type);
1492 if (expr)
1493 *expr = fold_build1_loc (loc, INDIRECT_REF, type, *expr);
1496 return build_ref_for_offset_1 (expr, type, offset, exp_type);
1499 /* Return true iff TYPE is stdarg va_list type. */
1501 static inline bool
1502 is_va_list_type (tree type)
1504 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1507 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1508 those with type which is suitable for scalarization. */
1510 static bool
1511 find_var_candidates (void)
1513 tree var, type;
1514 referenced_var_iterator rvi;
1515 bool ret = false;
1517 FOR_EACH_REFERENCED_VAR (var, rvi)
1519 if (TREE_CODE (var) != VAR_DECL && TREE_CODE (var) != PARM_DECL)
1520 continue;
1521 type = TREE_TYPE (var);
1523 if (!AGGREGATE_TYPE_P (type)
1524 || needs_to_live_in_memory (var)
1525 || TREE_THIS_VOLATILE (var)
1526 || !COMPLETE_TYPE_P (type)
1527 || !host_integerp (TYPE_SIZE (type), 1)
1528 || tree_low_cst (TYPE_SIZE (type), 1) == 0
1529 || type_internals_preclude_sra_p (type)
1530 /* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1531 we also want to schedule it rather late. Thus we ignore it in
1532 the early pass. */
1533 || (sra_mode == SRA_MODE_EARLY_INTRA
1534 && is_va_list_type (type)))
1535 continue;
1537 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
1539 if (dump_file && (dump_flags & TDF_DETAILS))
1541 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
1542 print_generic_expr (dump_file, var, 0);
1543 fprintf (dump_file, "\n");
1545 ret = true;
1548 return ret;
1551 /* Sort all accesses for the given variable, check for partial overlaps and
1552 return NULL if there are any. If there are none, pick a representative for
1553 each combination of offset and size and create a linked list out of them.
1554 Return the pointer to the first representative and make sure it is the first
1555 one in the vector of accesses. */
1557 static struct access *
1558 sort_and_splice_var_accesses (tree var)
1560 int i, j, access_count;
1561 struct access *res, **prev_acc_ptr = &res;
1562 VEC (access_p, heap) *access_vec;
1563 bool first = true;
1564 HOST_WIDE_INT low = -1, high = 0;
1566 access_vec = get_base_access_vector (var);
1567 if (!access_vec)
1568 return NULL;
1569 access_count = VEC_length (access_p, access_vec);
1571 /* Sort by <OFFSET, SIZE>. */
1572 qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
1573 compare_access_positions);
1575 i = 0;
1576 while (i < access_count)
1578 struct access *access = VEC_index (access_p, access_vec, i);
1579 bool grp_write = access->write;
1580 bool grp_read = !access->write;
1581 bool multiple_reads = false;
1582 bool total_scalarization = access->total_scalarization;
1583 bool grp_partial_lhs = access->grp_partial_lhs;
1584 bool first_scalar = is_gimple_reg_type (access->type);
1585 bool unscalarizable_region = access->grp_unscalarizable_region;
1587 if (first || access->offset >= high)
1589 first = false;
1590 low = access->offset;
1591 high = access->offset + access->size;
1593 else if (access->offset > low && access->offset + access->size > high)
1594 return NULL;
1595 else
1596 gcc_assert (access->offset >= low
1597 && access->offset + access->size <= high);
1599 j = i + 1;
1600 while (j < access_count)
1602 struct access *ac2 = VEC_index (access_p, access_vec, j);
1603 if (ac2->offset != access->offset || ac2->size != access->size)
1604 break;
1605 if (ac2->write)
1606 grp_write = true;
1607 else
1609 if (grp_read)
1610 multiple_reads = true;
1611 else
1612 grp_read = true;
1614 grp_partial_lhs |= ac2->grp_partial_lhs;
1615 unscalarizable_region |= ac2->grp_unscalarizable_region;
1616 total_scalarization |= ac2->total_scalarization;
1617 relink_to_new_repr (access, ac2);
1619 /* If there are both aggregate-type and scalar-type accesses with
1620 this combination of size and offset, the comparison function
1621 should have put the scalars first. */
1622 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
1623 ac2->group_representative = access;
1624 j++;
1627 i = j;
1629 access->group_representative = access;
1630 access->grp_write = grp_write;
1631 access->grp_read = grp_read;
1632 access->grp_hint = multiple_reads || total_scalarization;
1633 access->grp_partial_lhs = grp_partial_lhs;
1634 access->grp_unscalarizable_region = unscalarizable_region;
1635 if (access->first_link)
1636 add_access_to_work_queue (access);
1638 *prev_acc_ptr = access;
1639 prev_acc_ptr = &access->next_grp;
1642 gcc_assert (res == VEC_index (access_p, access_vec, 0));
1643 return res;
1646 /* Create a variable for the given ACCESS which determines the type, name and a
1647 few other properties. Return the variable declaration and store it also to
1648 ACCESS->replacement. */
1650 static tree
1651 create_access_replacement (struct access *access)
1653 tree repl;
1655 repl = create_tmp_var (access->type, "SR");
1656 get_var_ann (repl);
1657 add_referenced_var (repl);
1658 mark_sym_for_renaming (repl);
1660 if (!access->grp_partial_lhs
1661 && (TREE_CODE (access->type) == COMPLEX_TYPE
1662 || TREE_CODE (access->type) == VECTOR_TYPE))
1663 DECL_GIMPLE_REG_P (repl) = 1;
1665 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
1666 DECL_ARTIFICIAL (repl) = 1;
1667 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
1669 if (DECL_NAME (access->base)
1670 && !DECL_IGNORED_P (access->base)
1671 && !DECL_ARTIFICIAL (access->base))
1673 char *pretty_name = make_fancy_name (access->expr);
1675 DECL_NAME (repl) = get_identifier (pretty_name);
1676 obstack_free (&name_obstack, pretty_name);
1678 SET_DECL_DEBUG_EXPR (repl, access->expr);
1679 DECL_DEBUG_EXPR_IS_FROM (repl) = 1;
1680 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
1682 else
1683 TREE_NO_WARNING (repl) = 1;
1685 if (dump_file)
1687 fprintf (dump_file, "Created a replacement for ");
1688 print_generic_expr (dump_file, access->base, 0);
1689 fprintf (dump_file, " offset: %u, size: %u: ",
1690 (unsigned) access->offset, (unsigned) access->size);
1691 print_generic_expr (dump_file, repl, 0);
1692 fprintf (dump_file, "\n");
1694 sra_stats.replacements++;
1696 return repl;
1699 /* Return ACCESS scalar replacement, create it if it does not exist yet. */
1701 static inline tree
1702 get_access_replacement (struct access *access)
1704 gcc_assert (access->grp_to_be_replaced);
1706 if (!access->replacement_decl)
1707 access->replacement_decl = create_access_replacement (access);
1708 return access->replacement_decl;
1711 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
1712 linked list along the way. Stop when *ACCESS is NULL or the access pointed
1713 to it is not "within" the root. */
1715 static void
1716 build_access_subtree (struct access **access)
1718 struct access *root = *access, *last_child = NULL;
1719 HOST_WIDE_INT limit = root->offset + root->size;
1721 *access = (*access)->next_grp;
1722 while (*access && (*access)->offset + (*access)->size <= limit)
1724 if (!last_child)
1725 root->first_child = *access;
1726 else
1727 last_child->next_sibling = *access;
1728 last_child = *access;
1730 build_access_subtree (access);
1734 /* Build a tree of access representatives, ACCESS is the pointer to the first
1735 one, others are linked in a list by the next_grp field. Decide about scalar
1736 replacements on the way, return true iff any are to be created. */
1738 static void
1739 build_access_trees (struct access *access)
1741 while (access)
1743 struct access *root = access;
1745 build_access_subtree (&access);
1746 root->next_grp = access;
1750 /* Return true if expr contains some ARRAY_REFs into a variable bounded
1751 array. */
1753 static bool
1754 expr_with_var_bounded_array_refs_p (tree expr)
1756 while (handled_component_p (expr))
1758 if (TREE_CODE (expr) == ARRAY_REF
1759 && !host_integerp (array_ref_low_bound (expr), 0))
1760 return true;
1761 expr = TREE_OPERAND (expr, 0);
1763 return false;
1766 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
1767 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set
1768 all sorts of access flags appropriately along the way, notably always ser
1769 grp_read when MARK_READ is true and grp_write when MARK_WRITE is true. */
1771 static bool
1772 analyze_access_subtree (struct access *root, bool allow_replacements,
1773 bool mark_read, bool mark_write)
1775 struct access *child;
1776 HOST_WIDE_INT limit = root->offset + root->size;
1777 HOST_WIDE_INT covered_to = root->offset;
1778 bool scalar = is_gimple_reg_type (root->type);
1779 bool hole = false, sth_created = false;
1780 bool direct_read = root->grp_read;
1782 if (mark_read)
1783 root->grp_read = true;
1784 else if (root->grp_read)
1785 mark_read = true;
1787 if (mark_write)
1788 root->grp_write = true;
1789 else if (root->grp_write)
1790 mark_write = true;
1792 if (root->grp_unscalarizable_region)
1793 allow_replacements = false;
1795 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
1796 allow_replacements = false;
1798 for (child = root->first_child; child; child = child->next_sibling)
1800 if (!hole && child->offset < covered_to)
1801 hole = true;
1802 else
1803 covered_to += child->size;
1805 sth_created |= analyze_access_subtree (child, allow_replacements,
1806 mark_read, mark_write);
1808 root->grp_unscalarized_data |= child->grp_unscalarized_data;
1809 hole |= !child->grp_covered;
1812 if (allow_replacements && scalar && !root->first_child
1813 && (root->grp_hint
1814 || (direct_read && root->grp_write))
1815 /* We must not ICE later on when trying to build an access to the
1816 original data within the aggregate even when it is impossible to do in
1817 a defined way like in the PR 42703 testcase. Therefore we check
1818 pre-emptively here that we will be able to do that. */
1819 && build_ref_for_offset (NULL, TREE_TYPE (root->base), root->offset,
1820 root->type, false))
1822 if (dump_file && (dump_flags & TDF_DETAILS))
1824 fprintf (dump_file, "Marking ");
1825 print_generic_expr (dump_file, root->base, 0);
1826 fprintf (dump_file, " offset: %u, size: %u: ",
1827 (unsigned) root->offset, (unsigned) root->size);
1828 fprintf (dump_file, " to be replaced.\n");
1831 root->grp_to_be_replaced = 1;
1832 sth_created = true;
1833 hole = false;
1835 else if (covered_to < limit)
1836 hole = true;
1838 if (sth_created && !hole)
1840 root->grp_covered = 1;
1841 return true;
1843 if (root->grp_write || TREE_CODE (root->base) == PARM_DECL)
1844 root->grp_unscalarized_data = 1; /* not covered and written to */
1845 if (sth_created)
1846 return true;
1847 return false;
1850 /* Analyze all access trees linked by next_grp by the means of
1851 analyze_access_subtree. */
1852 static bool
1853 analyze_access_trees (struct access *access)
1855 bool ret = false;
1857 while (access)
1859 if (analyze_access_subtree (access, true, false, false))
1860 ret = true;
1861 access = access->next_grp;
1864 return ret;
1867 /* Return true iff a potential new child of LACC at offset OFFSET and with size
1868 SIZE would conflict with an already existing one. If exactly such a child
1869 already exists in LACC, store a pointer to it in EXACT_MATCH. */
1871 static bool
1872 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
1873 HOST_WIDE_INT size, struct access **exact_match)
1875 struct access *child;
1877 for (child = lacc->first_child; child; child = child->next_sibling)
1879 if (child->offset == norm_offset && child->size == size)
1881 *exact_match = child;
1882 return true;
1885 if (child->offset < norm_offset + size
1886 && child->offset + child->size > norm_offset)
1887 return true;
1890 return false;
1893 /* Create a new child access of PARENT, with all properties just like MODEL
1894 except for its offset and with its grp_write false and grp_read true.
1895 Return the new access or NULL if it cannot be created. Note that this access
1896 is created long after all splicing and sorting, it's not located in any
1897 access vector and is automatically a representative of its group. */
1899 static struct access *
1900 create_artificial_child_access (struct access *parent, struct access *model,
1901 HOST_WIDE_INT new_offset)
1903 struct access *access;
1904 struct access **child;
1905 tree expr = parent->base;;
1907 gcc_assert (!model->grp_unscalarizable_region);
1909 if (!build_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
1910 model->type, false))
1911 return NULL;
1913 access = (struct access *) pool_alloc (access_pool);
1914 memset (access, 0, sizeof (struct access));
1915 access->base = parent->base;
1916 access->expr = expr;
1917 access->offset = new_offset;
1918 access->size = model->size;
1919 access->type = model->type;
1920 access->grp_write = true;
1921 access->grp_read = false;
1923 child = &parent->first_child;
1924 while (*child && (*child)->offset < new_offset)
1925 child = &(*child)->next_sibling;
1927 access->next_sibling = *child;
1928 *child = access;
1930 return access;
1934 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
1935 true if any new subaccess was created. Additionally, if RACC is a scalar
1936 access but LACC is not, change the type of the latter, if possible. */
1938 static bool
1939 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
1941 struct access *rchild;
1942 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
1943 bool ret = false;
1945 if (is_gimple_reg_type (lacc->type)
1946 || lacc->grp_unscalarizable_region
1947 || racc->grp_unscalarizable_region)
1948 return false;
1950 if (!lacc->first_child && !racc->first_child
1951 && is_gimple_reg_type (racc->type))
1953 tree t = lacc->base;
1955 if (build_ref_for_offset (&t, TREE_TYPE (t), lacc->offset, racc->type,
1956 false))
1958 lacc->expr = t;
1959 lacc->type = racc->type;
1961 return false;
1964 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
1966 struct access *new_acc = NULL;
1967 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
1969 if (rchild->grp_unscalarizable_region)
1970 continue;
1972 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
1973 &new_acc))
1975 if (new_acc)
1977 rchild->grp_hint = 1;
1978 new_acc->grp_hint |= new_acc->grp_read;
1979 if (rchild->first_child)
1980 ret |= propagate_subaccesses_across_link (new_acc, rchild);
1982 continue;
1985 /* If a (part of) a union field is on the RHS of an assignment, it can
1986 have sub-accesses which do not make sense on the LHS (PR 40351).
1987 Check that this is not the case. */
1988 if (!build_ref_for_offset (NULL, TREE_TYPE (lacc->base), norm_offset,
1989 rchild->type, false))
1990 continue;
1992 rchild->grp_hint = 1;
1993 new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
1994 if (new_acc)
1996 ret = true;
1997 if (racc->first_child)
1998 propagate_subaccesses_across_link (new_acc, rchild);
2002 return ret;
2005 /* Propagate all subaccesses across assignment links. */
2007 static void
2008 propagate_all_subaccesses (void)
2010 while (work_queue_head)
2012 struct access *racc = pop_access_from_work_queue ();
2013 struct assign_link *link;
2015 gcc_assert (racc->first_link);
2017 for (link = racc->first_link; link; link = link->next)
2019 struct access *lacc = link->lacc;
2021 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
2022 continue;
2023 lacc = lacc->group_representative;
2024 if (propagate_subaccesses_across_link (lacc, racc)
2025 && lacc->first_link)
2026 add_access_to_work_queue (lacc);
2031 /* Go through all accesses collected throughout the (intraprocedural) analysis
2032 stage, exclude overlapping ones, identify representatives and build trees
2033 out of them, making decisions about scalarization on the way. Return true
2034 iff there are any to-be-scalarized variables after this stage. */
2036 static bool
2037 analyze_all_variable_accesses (void)
2039 int res = 0;
2040 bitmap tmp = BITMAP_ALLOC (NULL);
2041 bitmap_iterator bi;
2042 unsigned i, max_total_scalarization_size;
2044 max_total_scalarization_size = UNITS_PER_WORD * BITS_PER_UNIT
2045 * MOVE_RATIO (optimize_function_for_speed_p (cfun));
2047 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
2048 if (bitmap_bit_p (should_scalarize_away_bitmap, i)
2049 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
2051 tree var = referenced_var (i);
2053 if (TREE_CODE (var) == VAR_DECL
2054 && ((unsigned) tree_low_cst (TYPE_SIZE (TREE_TYPE (var)), 1)
2055 <= max_total_scalarization_size)
2056 && type_consists_of_records_p (TREE_TYPE (var)))
2058 completely_scalarize_record (var, var, 0);
2059 if (dump_file && (dump_flags & TDF_DETAILS))
2061 fprintf (dump_file, "Will attempt to totally scalarize ");
2062 print_generic_expr (dump_file, var, 0);
2063 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2068 bitmap_copy (tmp, candidate_bitmap);
2069 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2071 tree var = referenced_var (i);
2072 struct access *access;
2074 access = sort_and_splice_var_accesses (var);
2075 if (access)
2076 build_access_trees (access);
2077 else
2078 disqualify_candidate (var,
2079 "No or inhibitingly overlapping accesses.");
2082 propagate_all_subaccesses ();
2084 bitmap_copy (tmp, candidate_bitmap);
2085 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2087 tree var = referenced_var (i);
2088 struct access *access = get_first_repr_for_decl (var);
2090 if (analyze_access_trees (access))
2092 res++;
2093 if (dump_file && (dump_flags & TDF_DETAILS))
2095 fprintf (dump_file, "\nAccess trees for ");
2096 print_generic_expr (dump_file, var, 0);
2097 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2098 dump_access_tree (dump_file, access);
2099 fprintf (dump_file, "\n");
2102 else
2103 disqualify_candidate (var, "No scalar replacements to be created.");
2106 BITMAP_FREE (tmp);
2108 if (res)
2110 statistics_counter_event (cfun, "Scalarized aggregates", res);
2111 return true;
2113 else
2114 return false;
2117 /* Return true iff a reference statement into aggregate AGG can be built for
2118 every single to-be-replaced accesses that is a child of ACCESS, its sibling
2119 or a child of its sibling. TOP_OFFSET is the offset from the processed
2120 access subtree that has to be subtracted from offset of each access. */
2122 static bool
2123 ref_expr_for_all_replacements_p (struct access *access, tree agg,
2124 HOST_WIDE_INT top_offset)
2128 if (access->grp_to_be_replaced
2129 && !build_ref_for_offset (NULL, TREE_TYPE (agg),
2130 access->offset - top_offset,
2131 access->type, false))
2132 return false;
2134 if (access->first_child
2135 && !ref_expr_for_all_replacements_p (access->first_child, agg,
2136 top_offset))
2137 return false;
2139 access = access->next_sibling;
2141 while (access);
2143 return true;
2146 /* Generate statements copying scalar replacements of accesses within a subtree
2147 into or out of AGG. ACCESS is the first child of the root of the subtree to
2148 be processed. AGG is an aggregate type expression (can be a declaration but
2149 does not have to be, it can for example also be an indirect_ref).
2150 TOP_OFFSET is the offset of the processed subtree which has to be subtracted
2151 from offsets of individual accesses to get corresponding offsets for AGG.
2152 If CHUNK_SIZE is non-null, copy only replacements in the interval
2153 <start_offset, start_offset + chunk_size>, otherwise copy all. GSI is a
2154 statement iterator used to place the new statements. WRITE should be true
2155 when the statements should write from AGG to the replacement and false if
2156 vice versa. if INSERT_AFTER is true, new statements will be added after the
2157 current statement in GSI, they will be added before the statement
2158 otherwise. */
2160 static void
2161 generate_subtree_copies (struct access *access, tree agg,
2162 HOST_WIDE_INT top_offset,
2163 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
2164 gimple_stmt_iterator *gsi, bool write,
2165 bool insert_after)
2169 tree expr = agg;
2171 if (chunk_size && access->offset >= start_offset + chunk_size)
2172 return;
2174 if (access->grp_to_be_replaced
2175 && (chunk_size == 0
2176 || access->offset + access->size > start_offset))
2178 tree repl = get_access_replacement (access);
2179 bool ref_found;
2180 gimple stmt;
2182 ref_found = build_ref_for_offset (&expr, TREE_TYPE (agg),
2183 access->offset - top_offset,
2184 access->type, false);
2185 gcc_assert (ref_found);
2187 if (write)
2189 if (access->grp_partial_lhs)
2190 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
2191 !insert_after,
2192 insert_after ? GSI_NEW_STMT
2193 : GSI_SAME_STMT);
2194 stmt = gimple_build_assign (repl, expr);
2196 else
2198 TREE_NO_WARNING (repl) = 1;
2199 if (access->grp_partial_lhs)
2200 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2201 !insert_after,
2202 insert_after ? GSI_NEW_STMT
2203 : GSI_SAME_STMT);
2204 stmt = gimple_build_assign (expr, repl);
2207 if (insert_after)
2208 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2209 else
2210 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2211 update_stmt (stmt);
2212 sra_stats.subtree_copies++;
2215 if (access->first_child)
2216 generate_subtree_copies (access->first_child, agg, top_offset,
2217 start_offset, chunk_size, gsi,
2218 write, insert_after);
2220 access = access->next_sibling;
2222 while (access);
2225 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2226 the root of the subtree to be processed. GSI is the statement iterator used
2227 for inserting statements which are added after the current statement if
2228 INSERT_AFTER is true or before it otherwise. */
2230 static void
2231 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
2232 bool insert_after)
2235 struct access *child;
2237 if (access->grp_to_be_replaced)
2239 gimple stmt;
2241 stmt = gimple_build_assign (get_access_replacement (access),
2242 fold_convert (access->type,
2243 integer_zero_node));
2244 if (insert_after)
2245 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2246 else
2247 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2248 update_stmt (stmt);
2251 for (child = access->first_child; child; child = child->next_sibling)
2252 init_subtree_with_zero (child, gsi, insert_after);
2255 /* Search for an access representative for the given expression EXPR and
2256 return it or NULL if it cannot be found. */
2258 static struct access *
2259 get_access_for_expr (tree expr)
2261 HOST_WIDE_INT offset, size, max_size;
2262 tree base;
2264 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2265 a different size than the size of its argument and we need the latter
2266 one. */
2267 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
2268 expr = TREE_OPERAND (expr, 0);
2270 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
2271 if (max_size == -1 || !DECL_P (base))
2272 return NULL;
2274 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
2275 return NULL;
2277 return get_var_base_offset_size_access (base, offset, max_size);
2280 /* Callback for scan_function. Replace the expression EXPR with a scalar
2281 replacement if there is one and generate other statements to do type
2282 conversion or subtree copying if necessary. GSI is used to place newly
2283 created statements, WRITE is true if the expression is being written to (it
2284 is on a LHS of a statement or output in an assembly statement). */
2286 static bool
2287 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write,
2288 void *data ATTRIBUTE_UNUSED)
2290 struct access *access;
2291 tree type, bfr;
2293 if (TREE_CODE (*expr) == BIT_FIELD_REF)
2295 bfr = *expr;
2296 expr = &TREE_OPERAND (*expr, 0);
2298 else
2299 bfr = NULL_TREE;
2301 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
2302 expr = &TREE_OPERAND (*expr, 0);
2303 access = get_access_for_expr (*expr);
2304 if (!access)
2305 return false;
2306 type = TREE_TYPE (*expr);
2308 if (access->grp_to_be_replaced)
2310 tree repl = get_access_replacement (access);
2311 /* If we replace a non-register typed access simply use the original
2312 access expression to extract the scalar component afterwards.
2313 This happens if scalarizing a function return value or parameter
2314 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2315 gcc.c-torture/compile/20011217-1.c.
2317 We also want to use this when accessing a complex or vector which can
2318 be accessed as a different type too, potentially creating a need for
2319 type conversion (see PR42196) and when scalarized unions are involved
2320 in assembler statements (see PR42398). */
2321 if (!useless_type_conversion_p (type, access->type))
2323 tree ref = access->base;
2324 bool ok;
2326 ok = build_ref_for_offset (&ref, TREE_TYPE (ref),
2327 access->offset, access->type, false);
2328 gcc_assert (ok);
2330 if (write)
2332 gimple stmt;
2334 if (access->grp_partial_lhs)
2335 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
2336 false, GSI_NEW_STMT);
2337 stmt = gimple_build_assign (repl, ref);
2338 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2340 else
2342 gimple stmt;
2344 if (access->grp_partial_lhs)
2345 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2346 true, GSI_SAME_STMT);
2347 stmt = gimple_build_assign (ref, repl);
2348 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2351 else
2352 *expr = repl;
2353 sra_stats.exprs++;
2356 if (access->first_child)
2358 HOST_WIDE_INT start_offset, chunk_size;
2359 if (bfr
2360 && host_integerp (TREE_OPERAND (bfr, 1), 1)
2361 && host_integerp (TREE_OPERAND (bfr, 2), 1))
2363 chunk_size = tree_low_cst (TREE_OPERAND (bfr, 1), 1);
2364 start_offset = access->offset
2365 + tree_low_cst (TREE_OPERAND (bfr, 2), 1);
2367 else
2368 start_offset = chunk_size = 0;
2370 generate_subtree_copies (access->first_child, access->base, 0,
2371 start_offset, chunk_size, gsi, write, write);
2373 return true;
2376 /* Where scalar replacements of the RHS have been written to when a replacement
2377 of a LHS of an assigments cannot be direclty loaded from a replacement of
2378 the RHS. */
2379 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
2380 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
2381 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
2383 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2384 base aggregate if there are unscalarized data or directly to LHS
2385 otherwise. */
2387 static enum unscalarized_data_handling
2388 handle_unscalarized_data_in_subtree (struct access *top_racc, tree lhs,
2389 gimple_stmt_iterator *gsi)
2391 if (top_racc->grp_unscalarized_data)
2393 generate_subtree_copies (top_racc->first_child, top_racc->base, 0, 0, 0,
2394 gsi, false, false);
2395 return SRA_UDH_RIGHT;
2397 else
2399 generate_subtree_copies (top_racc->first_child, lhs, top_racc->offset,
2400 0, 0, gsi, false, false);
2401 return SRA_UDH_LEFT;
2406 /* Try to generate statements to load all sub-replacements in an access
2407 (sub)tree (LACC is the first child) from scalar replacements in the TOP_RACC
2408 (sub)tree. If that is not possible, refresh the TOP_RACC base aggregate and
2409 load the accesses from it. LEFT_OFFSET is the offset of the left whole
2410 subtree being copied, RIGHT_OFFSET is the same thing for the right subtree.
2411 GSI is stmt iterator used for statement insertions. *REFRESHED is true iff
2412 the rhs top aggregate has already been refreshed by contents of its scalar
2413 reductions and is set to true if this function has to do it. */
2415 static void
2416 load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
2417 HOST_WIDE_INT left_offset,
2418 HOST_WIDE_INT right_offset,
2419 gimple_stmt_iterator *old_gsi,
2420 gimple_stmt_iterator *new_gsi,
2421 enum unscalarized_data_handling *refreshed,
2422 tree lhs)
2424 location_t loc = EXPR_LOCATION (lacc->expr);
2427 if (lacc->grp_to_be_replaced)
2429 struct access *racc;
2430 HOST_WIDE_INT offset = lacc->offset - left_offset + right_offset;
2431 gimple stmt;
2432 tree rhs;
2434 racc = find_access_in_subtree (top_racc, offset, lacc->size);
2435 if (racc && racc->grp_to_be_replaced)
2437 rhs = get_access_replacement (racc);
2438 if (!useless_type_conversion_p (lacc->type, racc->type))
2439 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, lacc->type, rhs);
2441 else
2443 /* No suitable access on the right hand side, need to load from
2444 the aggregate. See if we have to update it first... */
2445 if (*refreshed == SRA_UDH_NONE)
2446 *refreshed = handle_unscalarized_data_in_subtree (top_racc,
2447 lhs, old_gsi);
2449 if (*refreshed == SRA_UDH_LEFT)
2451 bool repl_found;
2453 rhs = lacc->base;
2454 repl_found = build_ref_for_offset (&rhs, TREE_TYPE (rhs),
2455 lacc->offset, lacc->type,
2456 false);
2457 gcc_assert (repl_found);
2459 else
2461 bool repl_found;
2463 rhs = top_racc->base;
2464 repl_found = build_ref_for_offset (&rhs,
2465 TREE_TYPE (top_racc->base),
2466 offset, lacc->type, false);
2467 gcc_assert (repl_found);
2471 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
2472 gsi_insert_after (new_gsi, stmt, GSI_NEW_STMT);
2473 update_stmt (stmt);
2474 sra_stats.subreplacements++;
2476 else if (*refreshed == SRA_UDH_NONE
2477 && lacc->grp_read && !lacc->grp_covered)
2478 *refreshed = handle_unscalarized_data_in_subtree (top_racc, lhs,
2479 old_gsi);
2481 if (lacc->first_child)
2482 load_assign_lhs_subreplacements (lacc->first_child, top_racc,
2483 left_offset, right_offset,
2484 old_gsi, new_gsi, refreshed, lhs);
2485 lacc = lacc->next_sibling;
2487 while (lacc);
2490 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
2491 to the assignment and GSI is the statement iterator pointing at it. Returns
2492 the same values as sra_modify_assign. */
2494 static enum scan_assign_result
2495 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
2497 tree lhs = gimple_assign_lhs (*stmt);
2498 struct access *acc;
2500 acc = get_access_for_expr (lhs);
2501 if (!acc)
2502 return SRA_SA_NONE;
2504 if (VEC_length (constructor_elt,
2505 CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt))) > 0)
2507 /* I have never seen this code path trigger but if it can happen the
2508 following should handle it gracefully. */
2509 if (access_has_children_p (acc))
2510 generate_subtree_copies (acc->first_child, acc->base, 0, 0, 0, gsi,
2511 true, true);
2512 return SRA_SA_PROCESSED;
2515 if (acc->grp_covered)
2517 init_subtree_with_zero (acc, gsi, false);
2518 unlink_stmt_vdef (*stmt);
2519 gsi_remove (gsi, true);
2520 return SRA_SA_REMOVED;
2522 else
2524 init_subtree_with_zero (acc, gsi, true);
2525 return SRA_SA_PROCESSED;
2530 /* Callback of scan_function to process assign statements. It examines both
2531 sides of the statement, replaces them with a scalare replacement if there is
2532 one and generating copying of replacements if scalarized aggregates have been
2533 used in the assignment. STMT is a pointer to the assign statement, GSI is
2534 used to hold generated statements for type conversions and subtree
2535 copying. */
2537 static enum scan_assign_result
2538 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi,
2539 void *data ATTRIBUTE_UNUSED)
2541 struct access *lacc, *racc;
2542 tree lhs, rhs;
2543 bool modify_this_stmt = false;
2544 bool force_gimple_rhs = false;
2545 location_t loc = gimple_location (*stmt);
2546 gimple_stmt_iterator orig_gsi = *gsi;
2548 if (!gimple_assign_single_p (*stmt))
2549 return SRA_SA_NONE;
2550 lhs = gimple_assign_lhs (*stmt);
2551 rhs = gimple_assign_rhs1 (*stmt);
2553 if (TREE_CODE (rhs) == CONSTRUCTOR)
2554 return sra_modify_constructor_assign (stmt, gsi);
2556 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
2557 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
2558 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
2560 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (*stmt),
2561 gsi, false, data);
2562 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (*stmt),
2563 gsi, true, data);
2564 return modify_this_stmt ? SRA_SA_PROCESSED : SRA_SA_NONE;
2567 lacc = get_access_for_expr (lhs);
2568 racc = get_access_for_expr (rhs);
2569 if (!lacc && !racc)
2570 return SRA_SA_NONE;
2572 if (lacc && lacc->grp_to_be_replaced)
2574 lhs = get_access_replacement (lacc);
2575 gimple_assign_set_lhs (*stmt, lhs);
2576 modify_this_stmt = true;
2577 if (lacc->grp_partial_lhs)
2578 force_gimple_rhs = true;
2579 sra_stats.exprs++;
2582 if (racc && racc->grp_to_be_replaced)
2584 rhs = get_access_replacement (racc);
2585 modify_this_stmt = true;
2586 if (racc->grp_partial_lhs)
2587 force_gimple_rhs = true;
2588 sra_stats.exprs++;
2591 if (modify_this_stmt)
2593 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
2595 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
2596 ??? This should move to fold_stmt which we simply should
2597 call after building a VIEW_CONVERT_EXPR here. */
2598 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
2599 && !access_has_children_p (lacc))
2601 tree expr = lhs;
2602 if (build_ref_for_offset (&expr, TREE_TYPE (lhs), 0,
2603 TREE_TYPE (rhs), false))
2605 lhs = expr;
2606 gimple_assign_set_lhs (*stmt, expr);
2609 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
2610 && !access_has_children_p (racc))
2612 tree expr = rhs;
2613 if (build_ref_for_offset (&expr, TREE_TYPE (rhs), 0,
2614 TREE_TYPE (lhs), false))
2615 rhs = expr;
2617 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
2619 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs);
2620 if (is_gimple_reg_type (TREE_TYPE (lhs))
2621 && TREE_CODE (lhs) != SSA_NAME)
2622 force_gimple_rhs = true;
2627 /* From this point on, the function deals with assignments in between
2628 aggregates when at least one has scalar reductions of some of its
2629 components. There are three possible scenarios: Both the LHS and RHS have
2630 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
2632 In the first case, we would like to load the LHS components from RHS
2633 components whenever possible. If that is not possible, we would like to
2634 read it directly from the RHS (after updating it by storing in it its own
2635 components). If there are some necessary unscalarized data in the LHS,
2636 those will be loaded by the original assignment too. If neither of these
2637 cases happen, the original statement can be removed. Most of this is done
2638 by load_assign_lhs_subreplacements.
2640 In the second case, we would like to store all RHS scalarized components
2641 directly into LHS and if they cover the aggregate completely, remove the
2642 statement too. In the third case, we want the LHS components to be loaded
2643 directly from the RHS (DSE will remove the original statement if it
2644 becomes redundant).
2646 This is a bit complex but manageable when types match and when unions do
2647 not cause confusion in a way that we cannot really load a component of LHS
2648 from the RHS or vice versa (the access representing this level can have
2649 subaccesses that are accessible only through a different union field at a
2650 higher level - different from the one used in the examined expression).
2651 Unions are fun.
2653 Therefore, I specially handle a fourth case, happening when there is a
2654 specific type cast or it is impossible to locate a scalarized subaccess on
2655 the other side of the expression. If that happens, I simply "refresh" the
2656 RHS by storing in it is scalarized components leave the original statement
2657 there to do the copying and then load the scalar replacements of the LHS.
2658 This is what the first branch does. */
2660 if (gimple_has_volatile_ops (*stmt)
2661 || contains_view_convert_expr_p (rhs)
2662 || contains_view_convert_expr_p (lhs)
2663 || (access_has_children_p (racc)
2664 && !ref_expr_for_all_replacements_p (racc, lhs, racc->offset))
2665 || (access_has_children_p (lacc)
2666 && !ref_expr_for_all_replacements_p (lacc, rhs, lacc->offset)))
2668 if (access_has_children_p (racc))
2669 generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
2670 gsi, false, false);
2671 if (access_has_children_p (lacc))
2672 generate_subtree_copies (lacc->first_child, lacc->base, 0, 0, 0,
2673 gsi, true, true);
2674 sra_stats.separate_lhs_rhs_handling++;
2676 else
2678 if (access_has_children_p (lacc) && access_has_children_p (racc))
2680 gimple_stmt_iterator orig_gsi = *gsi;
2681 enum unscalarized_data_handling refreshed;
2683 if (lacc->grp_read && !lacc->grp_covered)
2684 refreshed = handle_unscalarized_data_in_subtree (racc, lhs, gsi);
2685 else
2686 refreshed = SRA_UDH_NONE;
2688 load_assign_lhs_subreplacements (lacc->first_child, racc,
2689 lacc->offset, racc->offset,
2690 &orig_gsi, gsi, &refreshed, lhs);
2691 if (refreshed != SRA_UDH_RIGHT)
2693 if (*stmt == gsi_stmt (*gsi))
2694 gsi_next (gsi);
2696 unlink_stmt_vdef (*stmt);
2697 gsi_remove (&orig_gsi, true);
2698 sra_stats.deleted++;
2699 return SRA_SA_REMOVED;
2702 else
2704 if (access_has_children_p (racc))
2706 if (!racc->grp_unscalarized_data
2707 /* Do not remove SSA name definitions (PR 42704). */
2708 && TREE_CODE (lhs) != SSA_NAME)
2710 generate_subtree_copies (racc->first_child, lhs,
2711 racc->offset, 0, 0, gsi,
2712 false, false);
2713 gcc_assert (*stmt == gsi_stmt (*gsi));
2714 unlink_stmt_vdef (*stmt);
2715 gsi_remove (gsi, true);
2716 sra_stats.deleted++;
2717 return SRA_SA_REMOVED;
2719 else
2720 generate_subtree_copies (racc->first_child, lhs,
2721 racc->offset, 0, 0, gsi, false, true);
2723 else if (access_has_children_p (lacc))
2724 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
2725 0, 0, gsi, true, true);
2729 /* This gimplification must be done after generate_subtree_copies, lest we
2730 insert the subtree copies in the middle of the gimplified sequence. */
2731 if (force_gimple_rhs)
2732 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
2733 true, GSI_SAME_STMT);
2734 if (gimple_assign_rhs1 (*stmt) != rhs)
2736 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
2737 gcc_assert (*stmt == gsi_stmt (orig_gsi));
2740 return modify_this_stmt ? SRA_SA_PROCESSED : SRA_SA_NONE;
2743 /* Generate statements initializing scalar replacements of parts of function
2744 parameters. */
2746 static void
2747 initialize_parameter_reductions (void)
2749 gimple_stmt_iterator gsi;
2750 gimple_seq seq = NULL;
2751 tree parm;
2753 for (parm = DECL_ARGUMENTS (current_function_decl);
2754 parm;
2755 parm = TREE_CHAIN (parm))
2757 VEC (access_p, heap) *access_vec;
2758 struct access *access;
2760 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
2761 continue;
2762 access_vec = get_base_access_vector (parm);
2763 if (!access_vec)
2764 continue;
2766 if (!seq)
2768 seq = gimple_seq_alloc ();
2769 gsi = gsi_start (seq);
2772 for (access = VEC_index (access_p, access_vec, 0);
2773 access;
2774 access = access->next_grp)
2775 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true);
2778 if (seq)
2779 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR), seq);
2782 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
2783 it reveals there are components of some aggregates to be scalarized, it runs
2784 the required transformations. */
2785 static unsigned int
2786 perform_intra_sra (void)
2788 int ret = 0;
2789 sra_initialize ();
2791 if (!find_var_candidates ())
2792 goto out;
2794 if (!scan_function (build_access_from_expr, build_accesses_from_assign, NULL,
2795 true, NULL))
2796 goto out;
2798 if (!analyze_all_variable_accesses ())
2799 goto out;
2801 scan_function (sra_modify_expr, sra_modify_assign, NULL, false, NULL);
2802 initialize_parameter_reductions ();
2804 statistics_counter_event (cfun, "Scalar replacements created",
2805 sra_stats.replacements);
2806 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
2807 statistics_counter_event (cfun, "Subtree copy stmts",
2808 sra_stats.subtree_copies);
2809 statistics_counter_event (cfun, "Subreplacement stmts",
2810 sra_stats.subreplacements);
2811 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
2812 statistics_counter_event (cfun, "Separate LHS and RHS handling",
2813 sra_stats.separate_lhs_rhs_handling);
2815 ret = TODO_update_ssa;
2817 out:
2818 sra_deinitialize ();
2819 return ret;
2822 /* Perform early intraprocedural SRA. */
2823 static unsigned int
2824 early_intra_sra (void)
2826 sra_mode = SRA_MODE_EARLY_INTRA;
2827 return perform_intra_sra ();
2830 /* Perform "late" intraprocedural SRA. */
2831 static unsigned int
2832 late_intra_sra (void)
2834 sra_mode = SRA_MODE_INTRA;
2835 return perform_intra_sra ();
2839 static bool
2840 gate_intra_sra (void)
2842 return flag_tree_sra != 0;
2846 struct gimple_opt_pass pass_sra_early =
2849 GIMPLE_PASS,
2850 "esra", /* name */
2851 gate_intra_sra, /* gate */
2852 early_intra_sra, /* execute */
2853 NULL, /* sub */
2854 NULL, /* next */
2855 0, /* static_pass_number */
2856 TV_TREE_SRA, /* tv_id */
2857 PROP_cfg | PROP_ssa, /* properties_required */
2858 0, /* properties_provided */
2859 0, /* properties_destroyed */
2860 0, /* todo_flags_start */
2861 TODO_dump_func
2862 | TODO_update_ssa
2863 | TODO_ggc_collect
2864 | TODO_verify_ssa /* todo_flags_finish */
2868 struct gimple_opt_pass pass_sra =
2871 GIMPLE_PASS,
2872 "sra", /* name */
2873 gate_intra_sra, /* gate */
2874 late_intra_sra, /* execute */
2875 NULL, /* sub */
2876 NULL, /* next */
2877 0, /* static_pass_number */
2878 TV_TREE_SRA, /* tv_id */
2879 PROP_cfg | PROP_ssa, /* properties_required */
2880 0, /* properties_provided */
2881 0, /* properties_destroyed */
2882 TODO_update_address_taken, /* todo_flags_start */
2883 TODO_dump_func
2884 | TODO_update_ssa
2885 | TODO_ggc_collect
2886 | TODO_verify_ssa /* todo_flags_finish */
2891 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
2892 parameter. */
2894 static bool
2895 is_unused_scalar_param (tree parm)
2897 tree name;
2898 return (is_gimple_reg (parm)
2899 && (!(name = gimple_default_def (cfun, parm))
2900 || has_zero_uses (name)));
2903 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
2904 examine whether there are any direct or otherwise infeasible ones. If so,
2905 return true, otherwise return false. PARM must be a gimple register with a
2906 non-NULL default definition. */
2908 static bool
2909 ptr_parm_has_direct_uses (tree parm)
2911 imm_use_iterator ui;
2912 gimple stmt;
2913 tree name = gimple_default_def (cfun, parm);
2914 bool ret = false;
2916 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
2918 int uses_ok = 0;
2919 use_operand_p use_p;
2921 if (is_gimple_debug (stmt))
2922 continue;
2924 /* Valid uses include dereferences on the lhs and the rhs. */
2925 if (gimple_has_lhs (stmt))
2927 tree lhs = gimple_get_lhs (stmt);
2928 while (handled_component_p (lhs))
2929 lhs = TREE_OPERAND (lhs, 0);
2930 if (INDIRECT_REF_P (lhs)
2931 && TREE_OPERAND (lhs, 0) == name)
2932 uses_ok++;
2934 if (gimple_assign_single_p (stmt))
2936 tree rhs = gimple_assign_rhs1 (stmt);
2937 while (handled_component_p (rhs))
2938 rhs = TREE_OPERAND (rhs, 0);
2939 if (INDIRECT_REF_P (rhs)
2940 && TREE_OPERAND (rhs, 0) == name)
2941 uses_ok++;
2943 else if (is_gimple_call (stmt))
2945 unsigned i;
2946 for (i = 0; i < gimple_call_num_args (stmt); ++i)
2948 tree arg = gimple_call_arg (stmt, i);
2949 while (handled_component_p (arg))
2950 arg = TREE_OPERAND (arg, 0);
2951 if (INDIRECT_REF_P (arg)
2952 && TREE_OPERAND (arg, 0) == name)
2953 uses_ok++;
2957 /* If the number of valid uses does not match the number of
2958 uses in this stmt there is an unhandled use. */
2959 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
2960 --uses_ok;
2962 if (uses_ok != 0)
2963 ret = true;
2965 if (ret)
2966 BREAK_FROM_IMM_USE_STMT (ui);
2969 return ret;
2972 /* Identify candidates for reduction for IPA-SRA based on their type and mark
2973 them in candidate_bitmap. Note that these do not necessarily include
2974 parameter which are unused and thus can be removed. Return true iff any
2975 such candidate has been found. */
2977 static bool
2978 find_param_candidates (void)
2980 tree parm;
2981 int count = 0;
2982 bool ret = false;
2984 for (parm = DECL_ARGUMENTS (current_function_decl);
2985 parm;
2986 parm = TREE_CHAIN (parm))
2988 tree type = TREE_TYPE (parm);
2990 count++;
2992 if (TREE_THIS_VOLATILE (parm)
2993 || TREE_ADDRESSABLE (parm)
2994 || is_va_list_type (type))
2995 continue;
2997 if (is_unused_scalar_param (parm))
2999 ret = true;
3000 continue;
3003 if (POINTER_TYPE_P (type))
3005 type = TREE_TYPE (type);
3007 if (TREE_CODE (type) == FUNCTION_TYPE
3008 || TYPE_VOLATILE (type)
3009 || !is_gimple_reg (parm)
3010 || is_va_list_type (type)
3011 || ptr_parm_has_direct_uses (parm))
3012 continue;
3014 else if (!AGGREGATE_TYPE_P (type))
3015 continue;
3017 if (!COMPLETE_TYPE_P (type)
3018 || !host_integerp (TYPE_SIZE (type), 1)
3019 || tree_low_cst (TYPE_SIZE (type), 1) == 0
3020 || (AGGREGATE_TYPE_P (type)
3021 && type_internals_preclude_sra_p (type)))
3022 continue;
3024 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
3025 ret = true;
3026 if (dump_file && (dump_flags & TDF_DETAILS))
3028 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
3029 print_generic_expr (dump_file, parm, 0);
3030 fprintf (dump_file, "\n");
3034 func_param_count = count;
3035 return ret;
3038 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
3039 maybe_modified. */
3041 static bool
3042 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
3043 void *data)
3045 struct access *repr = (struct access *) data;
3047 repr->grp_maybe_modified = 1;
3048 return true;
3051 /* Analyze what representatives (in linked lists accessible from
3052 REPRESENTATIVES) can be modified by side effects of statements in the
3053 current function. */
3055 static void
3056 analyze_modified_params (VEC (access_p, heap) *representatives)
3058 int i;
3060 for (i = 0; i < func_param_count; i++)
3062 struct access *repr;
3064 for (repr = VEC_index (access_p, representatives, i);
3065 repr;
3066 repr = repr->next_grp)
3068 struct access *access;
3069 bitmap visited;
3070 ao_ref ar;
3072 if (no_accesses_p (repr))
3073 continue;
3074 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
3075 || repr->grp_maybe_modified)
3076 continue;
3078 ao_ref_init (&ar, repr->expr);
3079 visited = BITMAP_ALLOC (NULL);
3080 for (access = repr; access; access = access->next_sibling)
3082 /* All accesses are read ones, otherwise grp_maybe_modified would
3083 be trivially set. */
3084 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
3085 mark_maybe_modified, repr, &visited);
3086 if (repr->grp_maybe_modified)
3087 break;
3089 BITMAP_FREE (visited);
3094 /* Propagate distances in bb_dereferences in the opposite direction than the
3095 control flow edges, in each step storing the maximum of the current value
3096 and the minimum of all successors. These steps are repeated until the table
3097 stabilizes. Note that BBs which might terminate the functions (according to
3098 final_bbs bitmap) never updated in this way. */
3100 static void
3101 propagate_dereference_distances (void)
3103 VEC (basic_block, heap) *queue;
3104 basic_block bb;
3106 queue = VEC_alloc (basic_block, heap, last_basic_block_for_function (cfun));
3107 VEC_quick_push (basic_block, queue, ENTRY_BLOCK_PTR);
3108 FOR_EACH_BB (bb)
3110 VEC_quick_push (basic_block, queue, bb);
3111 bb->aux = bb;
3114 while (!VEC_empty (basic_block, queue))
3116 edge_iterator ei;
3117 edge e;
3118 bool change = false;
3119 int i;
3121 bb = VEC_pop (basic_block, queue);
3122 bb->aux = NULL;
3124 if (bitmap_bit_p (final_bbs, bb->index))
3125 continue;
3127 for (i = 0; i < func_param_count; i++)
3129 int idx = bb->index * func_param_count + i;
3130 bool first = true;
3131 HOST_WIDE_INT inh = 0;
3133 FOR_EACH_EDGE (e, ei, bb->succs)
3135 int succ_idx = e->dest->index * func_param_count + i;
3137 if (e->src == EXIT_BLOCK_PTR)
3138 continue;
3140 if (first)
3142 first = false;
3143 inh = bb_dereferences [succ_idx];
3145 else if (bb_dereferences [succ_idx] < inh)
3146 inh = bb_dereferences [succ_idx];
3149 if (!first && bb_dereferences[idx] < inh)
3151 bb_dereferences[idx] = inh;
3152 change = true;
3156 if (change && !bitmap_bit_p (final_bbs, bb->index))
3157 FOR_EACH_EDGE (e, ei, bb->preds)
3159 if (e->src->aux)
3160 continue;
3162 e->src->aux = e->src;
3163 VEC_quick_push (basic_block, queue, e->src);
3167 VEC_free (basic_block, heap, queue);
3170 /* Dump a dereferences TABLE with heading STR to file F. */
3172 static void
3173 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
3175 basic_block bb;
3177 fprintf (dump_file, str);
3178 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
3180 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
3181 if (bb != EXIT_BLOCK_PTR)
3183 int i;
3184 for (i = 0; i < func_param_count; i++)
3186 int idx = bb->index * func_param_count + i;
3187 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
3190 fprintf (f, "\n");
3192 fprintf (dump_file, "\n");
3195 /* Determine what (parts of) parameters passed by reference that are not
3196 assigned to are not certainly dereferenced in this function and thus the
3197 dereferencing cannot be safely moved to the caller without potentially
3198 introducing a segfault. Mark such REPRESENTATIVES as
3199 grp_not_necessarilly_dereferenced.
3201 The dereferenced maximum "distance," i.e. the offset + size of the accessed
3202 part is calculated rather than simple booleans are calculated for each
3203 pointer parameter to handle cases when only a fraction of the whole
3204 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
3205 an example).
3207 The maximum dereference distances for each pointer parameter and BB are
3208 already stored in bb_dereference. This routine simply propagates these
3209 values upwards by propagate_dereference_distances and then compares the
3210 distances of individual parameters in the ENTRY BB to the equivalent
3211 distances of each representative of a (fraction of a) parameter. */
3213 static void
3214 analyze_caller_dereference_legality (VEC (access_p, heap) *representatives)
3216 int i;
3218 if (dump_file && (dump_flags & TDF_DETAILS))
3219 dump_dereferences_table (dump_file,
3220 "Dereference table before propagation:\n",
3221 bb_dereferences);
3223 propagate_dereference_distances ();
3225 if (dump_file && (dump_flags & TDF_DETAILS))
3226 dump_dereferences_table (dump_file,
3227 "Dereference table after propagation:\n",
3228 bb_dereferences);
3230 for (i = 0; i < func_param_count; i++)
3232 struct access *repr = VEC_index (access_p, representatives, i);
3233 int idx = ENTRY_BLOCK_PTR->index * func_param_count + i;
3235 if (!repr || no_accesses_p (repr))
3236 continue;
3240 if ((repr->offset + repr->size) > bb_dereferences[idx])
3241 repr->grp_not_necessarilly_dereferenced = 1;
3242 repr = repr->next_grp;
3244 while (repr);
3248 /* Return the representative access for the parameter declaration PARM if it is
3249 a scalar passed by reference which is not written to and the pointer value
3250 is not used directly. Thus, if it is legal to dereference it in the caller
3251 and we can rule out modifications through aliases, such parameter should be
3252 turned into one passed by value. Return NULL otherwise. */
3254 static struct access *
3255 unmodified_by_ref_scalar_representative (tree parm)
3257 int i, access_count;
3258 struct access *repr;
3259 VEC (access_p, heap) *access_vec;
3261 access_vec = get_base_access_vector (parm);
3262 gcc_assert (access_vec);
3263 repr = VEC_index (access_p, access_vec, 0);
3264 if (repr->write)
3265 return NULL;
3266 repr->group_representative = repr;
3268 access_count = VEC_length (access_p, access_vec);
3269 for (i = 1; i < access_count; i++)
3271 struct access *access = VEC_index (access_p, access_vec, i);
3272 if (access->write)
3273 return NULL;
3274 access->group_representative = repr;
3275 access->next_sibling = repr->next_sibling;
3276 repr->next_sibling = access;
3279 repr->grp_read = 1;
3280 repr->grp_scalar_ptr = 1;
3281 return repr;
3284 /* Return true iff this access precludes IPA-SRA of the parameter it is
3285 associated with. */
3287 static bool
3288 access_precludes_ipa_sra_p (struct access *access)
3290 /* Avoid issues such as the second simple testcase in PR 42025. The problem
3291 is incompatible assign in a call statement (and possibly even in asm
3292 statements). This can be relaxed by using a new temporary but only for
3293 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
3294 intraprocedural SRA we deal with this by keeping the old aggregate around,
3295 something we cannot do in IPA-SRA.) */
3296 if (access->write
3297 && (is_gimple_call (access->stmt)
3298 || gimple_code (access->stmt) == GIMPLE_ASM))
3299 return true;
3301 return false;
3305 /* Sort collected accesses for parameter PARM, identify representatives for
3306 each accessed region and link them together. Return NULL if there are
3307 different but overlapping accesses, return the special ptr value meaning
3308 there are no accesses for this parameter if that is the case and return the
3309 first representative otherwise. Set *RO_GRP if there is a group of accesses
3310 with only read (i.e. no write) accesses. */
3312 static struct access *
3313 splice_param_accesses (tree parm, bool *ro_grp)
3315 int i, j, access_count, group_count;
3316 int agg_size, total_size = 0;
3317 struct access *access, *res, **prev_acc_ptr = &res;
3318 VEC (access_p, heap) *access_vec;
3320 access_vec = get_base_access_vector (parm);
3321 if (!access_vec)
3322 return &no_accesses_representant;
3323 access_count = VEC_length (access_p, access_vec);
3325 qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
3326 compare_access_positions);
3328 i = 0;
3329 total_size = 0;
3330 group_count = 0;
3331 while (i < access_count)
3333 bool modification;
3334 access = VEC_index (access_p, access_vec, i);
3335 modification = access->write;
3336 if (access_precludes_ipa_sra_p (access))
3337 return NULL;
3339 /* Access is about to become group representative unless we find some
3340 nasty overlap which would preclude us from breaking this parameter
3341 apart. */
3343 j = i + 1;
3344 while (j < access_count)
3346 struct access *ac2 = VEC_index (access_p, access_vec, j);
3347 if (ac2->offset != access->offset)
3349 /* All or nothing law for parameters. */
3350 if (access->offset + access->size > ac2->offset)
3351 return NULL;
3352 else
3353 break;
3355 else if (ac2->size != access->size)
3356 return NULL;
3358 if (access_precludes_ipa_sra_p (ac2))
3359 return NULL;
3361 modification |= ac2->write;
3362 ac2->group_representative = access;
3363 ac2->next_sibling = access->next_sibling;
3364 access->next_sibling = ac2;
3365 j++;
3368 group_count++;
3369 access->grp_maybe_modified = modification;
3370 if (!modification)
3371 *ro_grp = true;
3372 *prev_acc_ptr = access;
3373 prev_acc_ptr = &access->next_grp;
3374 total_size += access->size;
3375 i = j;
3378 if (POINTER_TYPE_P (TREE_TYPE (parm)))
3379 agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))), 1);
3380 else
3381 agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (parm)), 1);
3382 if (total_size >= agg_size)
3383 return NULL;
3385 gcc_assert (group_count > 0);
3386 return res;
3389 /* Decide whether parameters with representative accesses given by REPR should
3390 be reduced into components. */
3392 static int
3393 decide_one_param_reduction (struct access *repr)
3395 int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
3396 bool by_ref;
3397 tree parm;
3399 parm = repr->base;
3400 cur_parm_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (parm)), 1);
3401 gcc_assert (cur_parm_size > 0);
3403 if (POINTER_TYPE_P (TREE_TYPE (parm)))
3405 by_ref = true;
3406 agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))), 1);
3408 else
3410 by_ref = false;
3411 agg_size = cur_parm_size;
3414 if (dump_file)
3416 struct access *acc;
3417 fprintf (dump_file, "Evaluating PARAM group sizes for ");
3418 print_generic_expr (dump_file, parm, 0);
3419 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
3420 for (acc = repr; acc; acc = acc->next_grp)
3421 dump_access (dump_file, acc, true);
3424 total_size = 0;
3425 new_param_count = 0;
3427 for (; repr; repr = repr->next_grp)
3429 gcc_assert (parm == repr->base);
3430 new_param_count++;
3432 if (!by_ref || (!repr->grp_maybe_modified
3433 && !repr->grp_not_necessarilly_dereferenced))
3434 total_size += repr->size;
3435 else
3436 total_size += cur_parm_size;
3439 gcc_assert (new_param_count > 0);
3441 if (optimize_function_for_size_p (cfun))
3442 parm_size_limit = cur_parm_size;
3443 else
3444 parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
3445 * cur_parm_size);
3447 if (total_size < agg_size
3448 && total_size <= parm_size_limit)
3450 if (dump_file)
3451 fprintf (dump_file, " ....will be split into %i components\n",
3452 new_param_count);
3453 return new_param_count;
3455 else
3456 return 0;
3459 /* The order of the following enums is important, we need to do extra work for
3460 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
3461 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
3462 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
3464 /* Identify representatives of all accesses to all candidate parameters for
3465 IPA-SRA. Return result based on what representatives have been found. */
3467 static enum ipa_splicing_result
3468 splice_all_param_accesses (VEC (access_p, heap) **representatives)
3470 enum ipa_splicing_result result = NO_GOOD_ACCESS;
3471 tree parm;
3472 struct access *repr;
3474 *representatives = VEC_alloc (access_p, heap, func_param_count);
3476 for (parm = DECL_ARGUMENTS (current_function_decl);
3477 parm;
3478 parm = TREE_CHAIN (parm))
3480 if (is_unused_scalar_param (parm))
3482 VEC_quick_push (access_p, *representatives,
3483 &no_accesses_representant);
3484 if (result == NO_GOOD_ACCESS)
3485 result = UNUSED_PARAMS;
3487 else if (POINTER_TYPE_P (TREE_TYPE (parm))
3488 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
3489 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3491 repr = unmodified_by_ref_scalar_representative (parm);
3492 VEC_quick_push (access_p, *representatives, repr);
3493 if (repr)
3494 result = UNMODIF_BY_REF_ACCESSES;
3496 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3498 bool ro_grp = false;
3499 repr = splice_param_accesses (parm, &ro_grp);
3500 VEC_quick_push (access_p, *representatives, repr);
3502 if (repr && !no_accesses_p (repr))
3504 if (POINTER_TYPE_P (TREE_TYPE (parm)))
3506 if (ro_grp)
3507 result = UNMODIF_BY_REF_ACCESSES;
3508 else if (result < MODIF_BY_REF_ACCESSES)
3509 result = MODIF_BY_REF_ACCESSES;
3511 else if (result < BY_VAL_ACCESSES)
3512 result = BY_VAL_ACCESSES;
3514 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
3515 result = UNUSED_PARAMS;
3517 else
3518 VEC_quick_push (access_p, *representatives, NULL);
3521 if (result == NO_GOOD_ACCESS)
3523 VEC_free (access_p, heap, *representatives);
3524 *representatives = NULL;
3525 return NO_GOOD_ACCESS;
3528 return result;
3531 /* Return the index of BASE in PARMS. Abort if it is not found. */
3533 static inline int
3534 get_param_index (tree base, VEC(tree, heap) *parms)
3536 int i, len;
3538 len = VEC_length (tree, parms);
3539 for (i = 0; i < len; i++)
3540 if (VEC_index (tree, parms, i) == base)
3541 return i;
3542 gcc_unreachable ();
3545 /* Convert the decisions made at the representative level into compact
3546 parameter adjustments. REPRESENTATIVES are pointers to first
3547 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
3548 final number of adjustments. */
3550 static ipa_parm_adjustment_vec
3551 turn_representatives_into_adjustments (VEC (access_p, heap) *representatives,
3552 int adjustments_count)
3554 VEC (tree, heap) *parms;
3555 ipa_parm_adjustment_vec adjustments;
3556 tree parm;
3557 int i;
3559 gcc_assert (adjustments_count > 0);
3560 parms = ipa_get_vector_of_formal_parms (current_function_decl);
3561 adjustments = VEC_alloc (ipa_parm_adjustment_t, heap, adjustments_count);
3562 parm = DECL_ARGUMENTS (current_function_decl);
3563 for (i = 0; i < func_param_count; i++, parm = TREE_CHAIN (parm))
3565 struct access *repr = VEC_index (access_p, representatives, i);
3567 if (!repr || no_accesses_p (repr))
3569 struct ipa_parm_adjustment *adj;
3571 adj = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
3572 memset (adj, 0, sizeof (*adj));
3573 adj->base_index = get_param_index (parm, parms);
3574 adj->base = parm;
3575 if (!repr)
3576 adj->copy_param = 1;
3577 else
3578 adj->remove_param = 1;
3580 else
3582 struct ipa_parm_adjustment *adj;
3583 int index = get_param_index (parm, parms);
3585 for (; repr; repr = repr->next_grp)
3587 adj = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
3588 memset (adj, 0, sizeof (*adj));
3589 gcc_assert (repr->base == parm);
3590 adj->base_index = index;
3591 adj->base = repr->base;
3592 adj->type = repr->type;
3593 adj->offset = repr->offset;
3594 adj->by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
3595 && (repr->grp_maybe_modified
3596 || repr->grp_not_necessarilly_dereferenced));
3601 VEC_free (tree, heap, parms);
3602 return adjustments;
3605 /* Analyze the collected accesses and produce a plan what to do with the
3606 parameters in the form of adjustments, NULL meaning nothing. */
3608 static ipa_parm_adjustment_vec
3609 analyze_all_param_acesses (void)
3611 enum ipa_splicing_result repr_state;
3612 bool proceed = false;
3613 int i, adjustments_count = 0;
3614 VEC (access_p, heap) *representatives;
3615 ipa_parm_adjustment_vec adjustments;
3617 repr_state = splice_all_param_accesses (&representatives);
3618 if (repr_state == NO_GOOD_ACCESS)
3619 return NULL;
3621 /* If there are any parameters passed by reference which are not modified
3622 directly, we need to check whether they can be modified indirectly. */
3623 if (repr_state == UNMODIF_BY_REF_ACCESSES)
3625 analyze_caller_dereference_legality (representatives);
3626 analyze_modified_params (representatives);
3629 for (i = 0; i < func_param_count; i++)
3631 struct access *repr = VEC_index (access_p, representatives, i);
3633 if (repr && !no_accesses_p (repr))
3635 if (repr->grp_scalar_ptr)
3637 adjustments_count++;
3638 if (repr->grp_not_necessarilly_dereferenced
3639 || repr->grp_maybe_modified)
3640 VEC_replace (access_p, representatives, i, NULL);
3641 else
3643 proceed = true;
3644 sra_stats.scalar_by_ref_to_by_val++;
3647 else
3649 int new_components = decide_one_param_reduction (repr);
3651 if (new_components == 0)
3653 VEC_replace (access_p, representatives, i, NULL);
3654 adjustments_count++;
3656 else
3658 adjustments_count += new_components;
3659 sra_stats.aggregate_params_reduced++;
3660 sra_stats.param_reductions_created += new_components;
3661 proceed = true;
3665 else
3667 if (no_accesses_p (repr))
3669 proceed = true;
3670 sra_stats.deleted_unused_parameters++;
3672 adjustments_count++;
3676 if (!proceed && dump_file)
3677 fprintf (dump_file, "NOT proceeding to change params.\n");
3679 if (proceed)
3680 adjustments = turn_representatives_into_adjustments (representatives,
3681 adjustments_count);
3682 else
3683 adjustments = NULL;
3685 VEC_free (access_p, heap, representatives);
3686 return adjustments;
3689 /* If a parameter replacement identified by ADJ does not yet exist in the form
3690 of declaration, create it and record it, otherwise return the previously
3691 created one. */
3693 static tree
3694 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
3696 tree repl;
3697 if (!adj->new_ssa_base)
3699 char *pretty_name = make_fancy_name (adj->base);
3701 repl = create_tmp_var (TREE_TYPE (adj->base), "ISR");
3702 if (TREE_CODE (TREE_TYPE (repl)) == COMPLEX_TYPE
3703 || TREE_CODE (TREE_TYPE (repl)) == VECTOR_TYPE)
3704 DECL_GIMPLE_REG_P (repl) = 1;
3705 DECL_NAME (repl) = get_identifier (pretty_name);
3706 obstack_free (&name_obstack, pretty_name);
3708 get_var_ann (repl);
3709 add_referenced_var (repl);
3710 adj->new_ssa_base = repl;
3712 else
3713 repl = adj->new_ssa_base;
3714 return repl;
3717 /* Find the first adjustment for a particular parameter BASE in a vector of
3718 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
3719 adjustment. */
3721 static struct ipa_parm_adjustment *
3722 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
3724 int i, len;
3726 len = VEC_length (ipa_parm_adjustment_t, adjustments);
3727 for (i = 0; i < len; i++)
3729 struct ipa_parm_adjustment *adj;
3731 adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3732 if (!adj->copy_param && adj->base == base)
3733 return adj;
3736 return NULL;
3739 /* Callback for scan_function. If the statement STMT defines an SSA_NAME of a
3740 parameter which is to be removed because its value is not used, replace the
3741 SSA_NAME with a one relating to a created VAR_DECL and replace all of its
3742 uses too and return true (update_stmt is then issued for the statement by
3743 the caller). DATA is a pointer to an adjustments vector. */
3745 static bool
3746 replace_removed_params_ssa_names (gimple stmt, void *data)
3748 VEC (ipa_parm_adjustment_t, heap) *adjustments;
3749 struct ipa_parm_adjustment *adj;
3750 tree lhs, decl, repl, name;
3752 adjustments = (VEC (ipa_parm_adjustment_t, heap) *) data;
3753 if (gimple_code (stmt) == GIMPLE_PHI)
3754 lhs = gimple_phi_result (stmt);
3755 else if (is_gimple_assign (stmt))
3756 lhs = gimple_assign_lhs (stmt);
3757 else if (is_gimple_call (stmt))
3758 lhs = gimple_call_lhs (stmt);
3759 else
3760 gcc_unreachable ();
3762 if (TREE_CODE (lhs) != SSA_NAME)
3763 return false;
3764 decl = SSA_NAME_VAR (lhs);
3765 if (TREE_CODE (decl) != PARM_DECL)
3766 return false;
3768 adj = get_adjustment_for_base (adjustments, decl);
3769 if (!adj)
3770 return false;
3772 repl = get_replaced_param_substitute (adj);
3773 name = make_ssa_name (repl, stmt);
3775 if (dump_file)
3777 fprintf (dump_file, "replacing an SSA name of a removed param ");
3778 print_generic_expr (dump_file, lhs, 0);
3779 fprintf (dump_file, " with ");
3780 print_generic_expr (dump_file, name, 0);
3781 fprintf (dump_file, "\n");
3784 if (is_gimple_assign (stmt))
3785 gimple_assign_set_lhs (stmt, name);
3786 else if (is_gimple_call (stmt))
3787 gimple_call_set_lhs (stmt, name);
3788 else
3789 gimple_phi_set_result (stmt, name);
3791 replace_uses_by (lhs, name);
3792 return true;
3795 /* Callback for scan_function and helper to sra_ipa_modify_assign. If the
3796 expression *EXPR should be replaced by a reduction of a parameter, do so.
3797 DATA is a pointer to a vector of adjustments. DONT_CONVERT specifies
3798 whether the function should care about type incompatibility the current and
3799 new expressions. If it is true, the function will leave incompatibility
3800 issues to the caller.
3802 When called directly by scan_function, DONT_CONVERT is true when the EXPR is
3803 a write (LHS) expression. */
3805 static bool
3806 sra_ipa_modify_expr (tree *expr, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
3807 bool dont_convert, void *data)
3809 ipa_parm_adjustment_vec adjustments;
3810 int i, len;
3811 struct ipa_parm_adjustment *adj, *cand = NULL;
3812 HOST_WIDE_INT offset, size, max_size;
3813 tree base, src;
3815 adjustments = (VEC (ipa_parm_adjustment_t, heap) *) data;
3816 len = VEC_length (ipa_parm_adjustment_t, adjustments);
3818 if (TREE_CODE (*expr) == BIT_FIELD_REF
3819 || TREE_CODE (*expr) == IMAGPART_EXPR
3820 || TREE_CODE (*expr) == REALPART_EXPR)
3822 expr = &TREE_OPERAND (*expr, 0);
3823 dont_convert = false;
3826 base = get_ref_base_and_extent (*expr, &offset, &size, &max_size);
3827 if (!base || size == -1 || max_size == -1)
3828 return false;
3830 if (INDIRECT_REF_P (base))
3831 base = TREE_OPERAND (base, 0);
3833 base = get_ssa_base_param (base);
3834 if (!base || TREE_CODE (base) != PARM_DECL)
3835 return false;
3837 for (i = 0; i < len; i++)
3839 adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3841 if (adj->base == base &&
3842 (adj->offset == offset || adj->remove_param))
3844 cand = adj;
3845 break;
3848 if (!cand || cand->copy_param || cand->remove_param)
3849 return false;
3851 if (cand->by_ref)
3853 tree folded;
3854 src = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (cand->reduction)),
3855 cand->reduction);
3856 folded = gimple_fold_indirect_ref (src);
3857 if (folded)
3858 src = folded;
3860 else
3861 src = cand->reduction;
3863 if (dump_file && (dump_flags & TDF_DETAILS))
3865 fprintf (dump_file, "About to replace expr ");
3866 print_generic_expr (dump_file, *expr, 0);
3867 fprintf (dump_file, " with ");
3868 print_generic_expr (dump_file, src, 0);
3869 fprintf (dump_file, "\n");
3872 if (!dont_convert
3873 && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
3875 tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
3876 *expr = vce;
3878 else
3879 *expr = src;
3880 return true;
3883 /* Callback for scan_function to process assign statements. Performs
3884 essentially the same function like sra_ipa_modify_expr. */
3886 static enum scan_assign_result
3887 sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi, void *data)
3889 gimple stmt = *stmt_ptr;
3890 tree *lhs_p, *rhs_p;
3891 bool any;
3893 if (!gimple_assign_single_p (stmt))
3894 return SRA_SA_NONE;
3896 rhs_p = gimple_assign_rhs1_ptr (stmt);
3897 lhs_p = gimple_assign_lhs_ptr (stmt);
3899 any = sra_ipa_modify_expr (rhs_p, gsi, true, data);
3900 any |= sra_ipa_modify_expr (lhs_p, gsi, true, data);
3901 if (any)
3903 tree new_rhs = NULL_TREE;
3905 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
3907 if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
3909 /* V_C_Es of constructors can cause trouble (PR 42714). */
3910 if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
3911 *rhs_p = fold_convert (TREE_TYPE (*lhs_p), integer_zero_node);
3912 else
3913 *rhs_p = build_constructor (TREE_TYPE (*lhs_p), 0);
3915 else
3916 new_rhs = fold_build1_loc (gimple_location (stmt),
3917 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
3918 *rhs_p);
3920 else if (REFERENCE_CLASS_P (*rhs_p)
3921 && is_gimple_reg_type (TREE_TYPE (*lhs_p))
3922 && !is_gimple_reg (*lhs_p))
3923 /* This can happen when an assignment in between two single field
3924 structures is turned into an assignment in between two pointers to
3925 scalars (PR 42237). */
3926 new_rhs = *rhs_p;
3928 if (new_rhs)
3930 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
3931 true, GSI_SAME_STMT);
3933 gimple_assign_set_rhs_from_tree (gsi, tmp);
3936 return SRA_SA_PROCESSED;
3939 return SRA_SA_NONE;
3942 /* Call gimple_debug_bind_reset_value on all debug statements describing
3943 gimple register parameters that are being removed or replaced. */
3945 static void
3946 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
3948 int i, len;
3950 len = VEC_length (ipa_parm_adjustment_t, adjustments);
3951 for (i = 0; i < len; i++)
3953 struct ipa_parm_adjustment *adj;
3954 imm_use_iterator ui;
3955 gimple stmt;
3956 tree name;
3958 adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3959 if (adj->copy_param || !is_gimple_reg (adj->base))
3960 continue;
3961 name = gimple_default_def (cfun, adj->base);
3962 if (!name)
3963 continue;
3964 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
3966 /* All other users must have been removed by scan_function. */
3967 gcc_assert (is_gimple_debug (stmt));
3968 gimple_debug_bind_reset_value (stmt);
3969 update_stmt (stmt);
3974 /* Return true iff all callers have at least as many actual arguments as there
3975 are formal parameters in the current function. */
3977 static bool
3978 all_callers_have_enough_arguments_p (struct cgraph_node *node)
3980 struct cgraph_edge *cs;
3981 for (cs = node->callers; cs; cs = cs->next_caller)
3982 if (!callsite_has_enough_arguments_p (cs->call_stmt))
3983 return false;
3985 return true;
3989 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
3991 static void
3992 convert_callers (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
3994 tree old_cur_fndecl = current_function_decl;
3995 struct cgraph_edge *cs;
3996 basic_block this_block;
3997 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
3999 for (cs = node->callers; cs; cs = cs->next_caller)
4001 current_function_decl = cs->caller->decl;
4002 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
4004 if (dump_file)
4005 fprintf (dump_file, "Adjusting call (%i -> %i) %s -> %s\n",
4006 cs->caller->uid, cs->callee->uid,
4007 cgraph_node_name (cs->caller),
4008 cgraph_node_name (cs->callee));
4010 ipa_modify_call_arguments (cs, cs->call_stmt, adjustments);
4012 pop_cfun ();
4015 for (cs = node->callers; cs; cs = cs->next_caller)
4016 if (!bitmap_bit_p (recomputed_callers, cs->caller->uid))
4018 compute_inline_parameters (cs->caller);
4019 bitmap_set_bit (recomputed_callers, cs->caller->uid);
4021 BITMAP_FREE (recomputed_callers);
4023 current_function_decl = old_cur_fndecl;
4025 if (!encountered_recursive_call)
4026 return;
4028 FOR_EACH_BB (this_block)
4030 gimple_stmt_iterator gsi;
4032 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
4034 gimple stmt = gsi_stmt (gsi);
4035 tree call_fndecl;
4036 if (gimple_code (stmt) != GIMPLE_CALL)
4037 continue;
4038 call_fndecl = gimple_call_fndecl (stmt);
4039 if (call_fndecl && cgraph_get_node (call_fndecl) == node)
4041 if (dump_file)
4042 fprintf (dump_file, "Adjusting recursive call");
4043 ipa_modify_call_arguments (NULL, stmt, adjustments);
4048 return;
4051 /* Create an abstract origin declaration for OLD_DECL and make it an abstract
4052 origin of the provided decl so that there are preserved parameters for debug
4053 information. */
4055 static void
4056 create_abstract_origin (tree old_decl)
4058 if (!DECL_ABSTRACT_ORIGIN (old_decl))
4060 tree new_decl = copy_node (old_decl);
4062 DECL_ABSTRACT (new_decl) = 1;
4063 SET_DECL_ASSEMBLER_NAME (new_decl, NULL_TREE);
4064 SET_DECL_RTL (new_decl, NULL);
4065 DECL_STRUCT_FUNCTION (new_decl) = NULL;
4066 DECL_ARTIFICIAL (old_decl) = 1;
4067 DECL_ABSTRACT_ORIGIN (old_decl) = new_decl;
4071 /* Perform all the modification required in IPA-SRA for NODE to have parameters
4072 as given in ADJUSTMENTS. */
4074 static void
4075 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
4077 struct cgraph_node *alias;
4078 for (alias = node->same_body; alias; alias = alias->next)
4079 ipa_modify_formal_parameters (alias->decl, adjustments, "ISRA");
4080 /* current_function_decl must be handled last, after same_body aliases,
4081 as following functions will use what it computed. */
4082 create_abstract_origin (current_function_decl);
4083 ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA");
4084 scan_function (sra_ipa_modify_expr, sra_ipa_modify_assign,
4085 replace_removed_params_ssa_names, false, adjustments);
4086 sra_ipa_reset_debug_stmts (adjustments);
4087 convert_callers (node, adjustments);
4088 cgraph_make_node_local (node);
4089 return;
4092 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
4093 attributes, return true otherwise. NODE is the cgraph node of the current
4094 function. */
4096 static bool
4097 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
4099 if (!cgraph_node_can_be_local_p (node))
4101 if (dump_file)
4102 fprintf (dump_file, "Function not local to this compilation unit.\n");
4103 return false;
4106 if (DECL_VIRTUAL_P (current_function_decl))
4108 if (dump_file)
4109 fprintf (dump_file, "Function is a virtual method.\n");
4110 return false;
4113 if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
4114 && node->global.size >= MAX_INLINE_INSNS_AUTO)
4116 if (dump_file)
4117 fprintf (dump_file, "Function too big to be made truly local.\n");
4118 return false;
4121 if (!node->callers)
4123 if (dump_file)
4124 fprintf (dump_file,
4125 "Function has no callers in this compilation unit.\n");
4126 return false;
4129 if (cfun->stdarg)
4131 if (dump_file)
4132 fprintf (dump_file, "Function uses stdarg. \n");
4133 return false;
4136 return true;
4139 /* Perform early interprocedural SRA. */
4141 static unsigned int
4142 ipa_early_sra (void)
4144 struct cgraph_node *node = cgraph_node (current_function_decl);
4145 ipa_parm_adjustment_vec adjustments;
4146 int ret = 0;
4148 if (!ipa_sra_preliminary_function_checks (node))
4149 return 0;
4151 sra_initialize ();
4152 sra_mode = SRA_MODE_EARLY_IPA;
4154 if (!find_param_candidates ())
4156 if (dump_file)
4157 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
4158 goto simple_out;
4161 if (!all_callers_have_enough_arguments_p (node))
4163 if (dump_file)
4164 fprintf (dump_file, "There are callers with insufficient number of "
4165 "arguments.\n");
4166 goto simple_out;
4169 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
4170 func_param_count
4171 * last_basic_block_for_function (cfun));
4172 final_bbs = BITMAP_ALLOC (NULL);
4174 scan_function (build_access_from_expr, build_accesses_from_assign,
4175 NULL, true, NULL);
4176 if (encountered_apply_args)
4178 if (dump_file)
4179 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
4180 goto out;
4183 if (encountered_unchangable_recursive_call)
4185 if (dump_file)
4186 fprintf (dump_file, "Function calls itself with insufficient "
4187 "number of arguments.\n");
4188 goto out;
4191 adjustments = analyze_all_param_acesses ();
4192 if (!adjustments)
4193 goto out;
4194 if (dump_file)
4195 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
4197 modify_function (node, adjustments);
4198 VEC_free (ipa_parm_adjustment_t, heap, adjustments);
4199 ret = TODO_update_ssa;
4201 statistics_counter_event (cfun, "Unused parameters deleted",
4202 sra_stats.deleted_unused_parameters);
4203 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
4204 sra_stats.scalar_by_ref_to_by_val);
4205 statistics_counter_event (cfun, "Aggregate parameters broken up",
4206 sra_stats.aggregate_params_reduced);
4207 statistics_counter_event (cfun, "Aggregate parameter components created",
4208 sra_stats.param_reductions_created);
4210 out:
4211 BITMAP_FREE (final_bbs);
4212 free (bb_dereferences);
4213 simple_out:
4214 sra_deinitialize ();
4215 return ret;
4218 /* Return if early ipa sra shall be performed. */
4219 static bool
4220 ipa_early_sra_gate (void)
4222 return flag_ipa_sra;
4225 struct gimple_opt_pass pass_early_ipa_sra =
4228 GIMPLE_PASS,
4229 "eipa_sra", /* name */
4230 ipa_early_sra_gate, /* gate */
4231 ipa_early_sra, /* execute */
4232 NULL, /* sub */
4233 NULL, /* next */
4234 0, /* static_pass_number */
4235 TV_IPA_SRA, /* tv_id */
4236 0, /* properties_required */
4237 0, /* properties_provided */
4238 0, /* properties_destroyed */
4239 0, /* todo_flags_start */
4240 TODO_dump_func | TODO_dump_cgraph /* todo_flags_finish */