2012-11-04 Janus Weil <janus@gcc.gnu.org>
[official-gcc.git] / gcc / tree-sra.c
blob8dd5cb497c2498daf061f592fe33dcc44b6c1cfd
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, 2011, 2012 Free Software Foundation, Inc.
5 Contributed by Martin Jambor <mjambor@suse.cz>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* This file implements Scalar Reduction of Aggregates (SRA). SRA is run
24 twice, once in the early stages of compilation (early SRA) and once in the
25 late stages (late SRA). The aim of both is to turn references to scalar
26 parts of aggregates into uses of independent scalar variables.
28 The two passes are nearly identical, the only difference is that early SRA
29 does not scalarize unions which are used as the result in a GIMPLE_RETURN
30 statement because together with inlining this can lead to weird type
31 conversions.
33 Both passes operate in four stages:
35 1. The declarations that have properties which make them candidates for
36 scalarization are identified in function find_var_candidates(). The
37 candidates are stored in candidate_bitmap.
39 2. The function body is scanned. In the process, declarations which are
40 used in a manner that prevent their scalarization are removed from the
41 candidate bitmap. More importantly, for every access into an aggregate,
42 an access structure (struct access) is created by create_access() and
43 stored in a vector associated with the aggregate. Among other
44 information, the aggregate declaration, the offset and size of the access
45 and its type are stored in the structure.
47 On a related note, assign_link structures are created for every assign
48 statement between candidate aggregates and attached to the related
49 accesses.
51 3. The vectors of accesses are analyzed. They are first sorted according to
52 their offset and size and then scanned for partially overlapping accesses
53 (i.e. those which overlap but one is not entirely within another). Such
54 an access disqualifies the whole aggregate from being scalarized.
56 If there is no such inhibiting overlap, a representative access structure
57 is chosen for every unique combination of offset and size. Afterwards,
58 the pass builds a set of trees from these structures, in which children
59 of an access are within their parent (in terms of offset and size).
61 Then accesses are propagated whenever possible (i.e. in cases when it
62 does not create a partially overlapping access) across assign_links from
63 the right hand side to the left hand side.
65 Then the set of trees for each declaration is traversed again and those
66 accesses which should be replaced by a scalar are identified.
68 4. The function is traversed again, and for every reference into an
69 aggregate that has some component which is about to be scalarized,
70 statements are amended and new statements are created as necessary.
71 Finally, if a parameter got scalarized, the scalar replacements are
72 initialized with values from respective parameter aggregates. */
74 #include "config.h"
75 #include "system.h"
76 #include "coretypes.h"
77 #include "alloc-pool.h"
78 #include "tm.h"
79 #include "tree.h"
80 #include "gimple.h"
81 #include "cgraph.h"
82 #include "tree-flow.h"
83 #include "tree-pass.h"
84 #include "ipa-prop.h"
85 #include "statistics.h"
86 #include "params.h"
87 #include "target.h"
88 #include "flags.h"
89 #include "dbgcnt.h"
90 #include "tree-inline.h"
91 #include "gimple-pretty-print.h"
92 #include "ipa-inline.h"
94 /* Enumeration of all aggregate reductions we can do. */
95 enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
96 SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
97 SRA_MODE_INTRA }; /* late intraprocedural SRA */
99 /* Global variable describing which aggregate reduction we are performing at
100 the moment. */
101 static enum sra_mode sra_mode;
103 struct assign_link;
105 /* ACCESS represents each access to an aggregate variable (as a whole or a
106 part). It can also represent a group of accesses that refer to exactly the
107 same fragment of an aggregate (i.e. those that have exactly the same offset
108 and size). Such representatives for a single aggregate, once determined,
109 are linked in a linked list and have the group fields set.
111 Moreover, when doing intraprocedural SRA, a tree is built from those
112 representatives (by the means of first_child and next_sibling pointers), in
113 which all items in a subtree are "within" the root, i.e. their offset is
114 greater or equal to offset of the root and offset+size is smaller or equal
115 to offset+size of the root. Children of an access are sorted by offset.
117 Note that accesses to parts of vector and complex number types always
118 represented by an access to the whole complex number or a vector. It is a
119 duty of the modifying functions to replace them appropriately. */
121 struct access
123 /* Values returned by `get_ref_base_and_extent' for each component reference
124 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
125 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
126 HOST_WIDE_INT offset;
127 HOST_WIDE_INT size;
128 tree base;
130 /* Expression. It is context dependent so do not use it to create new
131 expressions to access the original aggregate. See PR 42154 for a
132 testcase. */
133 tree expr;
134 /* Type. */
135 tree type;
137 /* The statement this access belongs to. */
138 gimple stmt;
140 /* Next group representative for this aggregate. */
141 struct access *next_grp;
143 /* Pointer to the group representative. Pointer to itself if the struct is
144 the representative. */
145 struct access *group_representative;
147 /* If this access has any children (in terms of the definition above), this
148 points to the first one. */
149 struct access *first_child;
151 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
152 described above. In IPA-SRA this is a pointer to the next access
153 belonging to the same group (having the same representative). */
154 struct access *next_sibling;
156 /* Pointers to the first and last element in the linked list of assign
157 links. */
158 struct assign_link *first_link, *last_link;
160 /* Pointer to the next access in the work queue. */
161 struct access *next_queued;
163 /* Replacement variable for this access "region." Never to be accessed
164 directly, always only by the means of get_access_replacement() and only
165 when grp_to_be_replaced flag is set. */
166 tree replacement_decl;
168 /* Is this particular access write access? */
169 unsigned write : 1;
171 /* Is this access an access to a non-addressable field? */
172 unsigned non_addressable : 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 /* Does this group contain a read access that comes from an assignment
186 statement? This flag is propagated down the access tree. */
187 unsigned grp_assignment_read : 1;
189 /* Does this group contain a write access that comes from an assignment
190 statement? This flag is propagated down the access tree. */
191 unsigned grp_assignment_write : 1;
193 /* Does this group contain a read access through a scalar type? This flag is
194 not propagated in the access tree in any direction. */
195 unsigned grp_scalar_read : 1;
197 /* Does this group contain a write access through a scalar type? This flag
198 is not propagated in the access tree in any direction. */
199 unsigned grp_scalar_write : 1;
201 /* Is this access an artificial one created to scalarize some record
202 entirely? */
203 unsigned grp_total_scalarization : 1;
205 /* Other passes of the analysis use this bit to make function
206 analyze_access_subtree create scalar replacements for this group if
207 possible. */
208 unsigned grp_hint : 1;
210 /* Is the subtree rooted in this access fully covered by scalar
211 replacements? */
212 unsigned grp_covered : 1;
214 /* If set to true, this access and all below it in an access tree must not be
215 scalarized. */
216 unsigned grp_unscalarizable_region : 1;
218 /* Whether data have been written to parts of the aggregate covered by this
219 access which is not to be scalarized. This flag is propagated up in the
220 access tree. */
221 unsigned grp_unscalarized_data : 1;
223 /* Does this access and/or group contain a write access through a
224 BIT_FIELD_REF? */
225 unsigned grp_partial_lhs : 1;
227 /* Set when a scalar replacement should be created for this variable. */
228 unsigned grp_to_be_replaced : 1;
230 /* Set when we want a replacement for the sole purpose of having it in
231 generated debug statements. */
232 unsigned grp_to_be_debug_replaced : 1;
234 /* Should TREE_NO_WARNING of a replacement be set? */
235 unsigned grp_no_warning : 1;
237 /* Is it possible that the group refers to data which might be (directly or
238 otherwise) modified? */
239 unsigned grp_maybe_modified : 1;
241 /* Set when this is a representative of a pointer to scalar (i.e. by
242 reference) parameter which we consider for turning into a plain scalar
243 (i.e. a by value parameter). */
244 unsigned grp_scalar_ptr : 1;
246 /* Set when we discover that this pointer is not safe to dereference in the
247 caller. */
248 unsigned grp_not_necessarilly_dereferenced : 1;
251 typedef struct access *access_p;
253 DEF_VEC_P (access_p);
254 DEF_VEC_ALLOC_P (access_p, heap);
256 /* Alloc pool for allocating access structures. */
257 static alloc_pool access_pool;
259 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
260 are used to propagate subaccesses from rhs to lhs as long as they don't
261 conflict with what is already there. */
262 struct assign_link
264 struct access *lacc, *racc;
265 struct assign_link *next;
268 /* Alloc pool for allocating assign link structures. */
269 static alloc_pool link_pool;
271 /* Base (tree) -> Vector (VEC(access_p,heap) *) map. */
272 static struct pointer_map_t *base_access_vec;
274 /* Set of candidates. */
275 static bitmap candidate_bitmap;
276 static htab_t candidates;
278 /* For a candidate UID return the candidates decl. */
280 static inline tree
281 candidate (unsigned uid)
283 struct tree_decl_minimal t;
284 t.uid = uid;
285 return (tree) htab_find_with_hash (candidates, &t, uid);
288 /* Bitmap of candidates which we should try to entirely scalarize away and
289 those which cannot be (because they are and need be used as a whole). */
290 static bitmap should_scalarize_away_bitmap, cannot_scalarize_away_bitmap;
292 /* Obstack for creation of fancy names. */
293 static struct obstack name_obstack;
295 /* Head of a linked list of accesses that need to have its subaccesses
296 propagated to their assignment counterparts. */
297 static struct access *work_queue_head;
299 /* Number of parameters of the analyzed function when doing early ipa SRA. */
300 static int func_param_count;
302 /* scan_function sets the following to true if it encounters a call to
303 __builtin_apply_args. */
304 static bool encountered_apply_args;
306 /* Set by scan_function when it finds a recursive call. */
307 static bool encountered_recursive_call;
309 /* Set by scan_function when it finds a recursive call with less actual
310 arguments than formal parameters.. */
311 static bool encountered_unchangable_recursive_call;
313 /* This is a table in which for each basic block and parameter there is a
314 distance (offset + size) in that parameter which is dereferenced and
315 accessed in that BB. */
316 static HOST_WIDE_INT *bb_dereferences;
317 /* Bitmap of BBs that can cause the function to "stop" progressing by
318 returning, throwing externally, looping infinitely or calling a function
319 which might abort etc.. */
320 static bitmap final_bbs;
322 /* Representative of no accesses at all. */
323 static struct access no_accesses_representant;
325 /* Predicate to test the special value. */
327 static inline bool
328 no_accesses_p (struct access *access)
330 return access == &no_accesses_representant;
333 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
334 representative fields are dumped, otherwise those which only describe the
335 individual access are. */
337 static struct
339 /* Number of processed aggregates is readily available in
340 analyze_all_variable_accesses and so is not stored here. */
342 /* Number of created scalar replacements. */
343 int replacements;
345 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
346 expression. */
347 int exprs;
349 /* Number of statements created by generate_subtree_copies. */
350 int subtree_copies;
352 /* Number of statements created by load_assign_lhs_subreplacements. */
353 int subreplacements;
355 /* Number of times sra_modify_assign has deleted a statement. */
356 int deleted;
358 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
359 RHS reparately due to type conversions or nonexistent matching
360 references. */
361 int separate_lhs_rhs_handling;
363 /* Number of parameters that were removed because they were unused. */
364 int deleted_unused_parameters;
366 /* Number of scalars passed as parameters by reference that have been
367 converted to be passed by value. */
368 int scalar_by_ref_to_by_val;
370 /* Number of aggregate parameters that were replaced by one or more of their
371 components. */
372 int aggregate_params_reduced;
374 /* Numbber of components created when splitting aggregate parameters. */
375 int param_reductions_created;
376 } sra_stats;
378 static void
379 dump_access (FILE *f, struct access *access, bool grp)
381 fprintf (f, "access { ");
382 fprintf (f, "base = (%d)'", DECL_UID (access->base));
383 print_generic_expr (f, access->base, 0);
384 fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
385 fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
386 fprintf (f, ", expr = ");
387 print_generic_expr (f, access->expr, 0);
388 fprintf (f, ", type = ");
389 print_generic_expr (f, access->type, 0);
390 if (grp)
391 fprintf (f, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
392 "grp_assignment_write = %d, grp_scalar_read = %d, "
393 "grp_scalar_write = %d, grp_total_scalarization = %d, "
394 "grp_hint = %d, grp_covered = %d, "
395 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
396 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
397 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
398 "grp_not_necessarilly_dereferenced = %d\n",
399 access->grp_read, access->grp_write, access->grp_assignment_read,
400 access->grp_assignment_write, access->grp_scalar_read,
401 access->grp_scalar_write, access->grp_total_scalarization,
402 access->grp_hint, access->grp_covered,
403 access->grp_unscalarizable_region, access->grp_unscalarized_data,
404 access->grp_partial_lhs, access->grp_to_be_replaced,
405 access->grp_to_be_debug_replaced, access->grp_maybe_modified,
406 access->grp_not_necessarilly_dereferenced);
407 else
408 fprintf (f, ", write = %d, grp_total_scalarization = %d, "
409 "grp_partial_lhs = %d\n",
410 access->write, access->grp_total_scalarization,
411 access->grp_partial_lhs);
414 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
416 static void
417 dump_access_tree_1 (FILE *f, struct access *access, int level)
421 int i;
423 for (i = 0; i < level; i++)
424 fputs ("* ", dump_file);
426 dump_access (f, access, true);
428 if (access->first_child)
429 dump_access_tree_1 (f, access->first_child, level + 1);
431 access = access->next_sibling;
433 while (access);
436 /* Dump all access trees for a variable, given the pointer to the first root in
437 ACCESS. */
439 static void
440 dump_access_tree (FILE *f, struct access *access)
442 for (; access; access = access->next_grp)
443 dump_access_tree_1 (f, access, 0);
446 /* Return true iff ACC is non-NULL and has subaccesses. */
448 static inline bool
449 access_has_children_p (struct access *acc)
451 return acc && acc->first_child;
454 /* Return true iff ACC is (partly) covered by at least one replacement. */
456 static bool
457 access_has_replacements_p (struct access *acc)
459 struct access *child;
460 if (acc->grp_to_be_replaced)
461 return true;
462 for (child = acc->first_child; child; child = child->next_sibling)
463 if (access_has_replacements_p (child))
464 return true;
465 return false;
468 /* Return a vector of pointers to accesses for the variable given in BASE or
469 NULL if there is none. */
471 static VEC (access_p, heap) *
472 get_base_access_vector (tree base)
474 void **slot;
476 slot = pointer_map_contains (base_access_vec, base);
477 if (!slot)
478 return NULL;
479 else
480 return *(VEC (access_p, heap) **) slot;
483 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
484 in ACCESS. Return NULL if it cannot be found. */
486 static struct access *
487 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
488 HOST_WIDE_INT size)
490 while (access && (access->offset != offset || access->size != size))
492 struct access *child = access->first_child;
494 while (child && (child->offset + child->size <= offset))
495 child = child->next_sibling;
496 access = child;
499 return access;
502 /* Return the first group representative for DECL or NULL if none exists. */
504 static struct access *
505 get_first_repr_for_decl (tree base)
507 VEC (access_p, heap) *access_vec;
509 access_vec = get_base_access_vector (base);
510 if (!access_vec)
511 return NULL;
513 return VEC_index (access_p, access_vec, 0);
516 /* Find an access representative for the variable BASE and given OFFSET and
517 SIZE. Requires that access trees have already been built. Return NULL if
518 it cannot be found. */
520 static struct access *
521 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
522 HOST_WIDE_INT size)
524 struct access *access;
526 access = get_first_repr_for_decl (base);
527 while (access && (access->offset + access->size <= offset))
528 access = access->next_grp;
529 if (!access)
530 return NULL;
532 return find_access_in_subtree (access, offset, size);
535 /* Add LINK to the linked list of assign links of RACC. */
536 static void
537 add_link_to_rhs (struct access *racc, struct assign_link *link)
539 gcc_assert (link->racc == racc);
541 if (!racc->first_link)
543 gcc_assert (!racc->last_link);
544 racc->first_link = link;
546 else
547 racc->last_link->next = link;
549 racc->last_link = link;
550 link->next = NULL;
553 /* Move all link structures in their linked list in OLD_RACC to the linked list
554 in NEW_RACC. */
555 static void
556 relink_to_new_repr (struct access *new_racc, struct access *old_racc)
558 if (!old_racc->first_link)
560 gcc_assert (!old_racc->last_link);
561 return;
564 if (new_racc->first_link)
566 gcc_assert (!new_racc->last_link->next);
567 gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
569 new_racc->last_link->next = old_racc->first_link;
570 new_racc->last_link = old_racc->last_link;
572 else
574 gcc_assert (!new_racc->last_link);
576 new_racc->first_link = old_racc->first_link;
577 new_racc->last_link = old_racc->last_link;
579 old_racc->first_link = old_racc->last_link = NULL;
582 /* Add ACCESS to the work queue (which is actually a stack). */
584 static void
585 add_access_to_work_queue (struct access *access)
587 if (!access->grp_queued)
589 gcc_assert (!access->next_queued);
590 access->next_queued = work_queue_head;
591 access->grp_queued = 1;
592 work_queue_head = access;
596 /* Pop an access from the work queue, and return it, assuming there is one. */
598 static struct access *
599 pop_access_from_work_queue (void)
601 struct access *access = work_queue_head;
603 work_queue_head = access->next_queued;
604 access->next_queued = NULL;
605 access->grp_queued = 0;
606 return access;
610 /* Allocate necessary structures. */
612 static void
613 sra_initialize (void)
615 candidate_bitmap = BITMAP_ALLOC (NULL);
616 candidates = htab_create (VEC_length (tree, cfun->local_decls) / 2,
617 uid_decl_map_hash, uid_decl_map_eq, NULL);
618 should_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
619 cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
620 gcc_obstack_init (&name_obstack);
621 access_pool = create_alloc_pool ("SRA accesses", sizeof (struct access), 16);
622 link_pool = create_alloc_pool ("SRA links", sizeof (struct assign_link), 16);
623 base_access_vec = pointer_map_create ();
624 memset (&sra_stats, 0, sizeof (sra_stats));
625 encountered_apply_args = false;
626 encountered_recursive_call = false;
627 encountered_unchangable_recursive_call = false;
630 /* Hook fed to pointer_map_traverse, deallocate stored vectors. */
632 static bool
633 delete_base_accesses (const void *key ATTRIBUTE_UNUSED, void **value,
634 void *data ATTRIBUTE_UNUSED)
636 VEC (access_p, heap) *access_vec;
637 access_vec = (VEC (access_p, heap) *) *value;
638 VEC_free (access_p, heap, access_vec);
640 return true;
643 /* Deallocate all general structures. */
645 static void
646 sra_deinitialize (void)
648 BITMAP_FREE (candidate_bitmap);
649 htab_delete (candidates);
650 BITMAP_FREE (should_scalarize_away_bitmap);
651 BITMAP_FREE (cannot_scalarize_away_bitmap);
652 free_alloc_pool (access_pool);
653 free_alloc_pool (link_pool);
654 obstack_free (&name_obstack, NULL);
656 pointer_map_traverse (base_access_vec, delete_base_accesses, NULL);
657 pointer_map_destroy (base_access_vec);
660 /* Remove DECL from candidates for SRA and write REASON to the dump file if
661 there is one. */
662 static void
663 disqualify_candidate (tree decl, const char *reason)
665 if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl)))
666 htab_clear_slot (candidates,
667 htab_find_slot_with_hash (candidates, decl,
668 DECL_UID (decl), NO_INSERT));
670 if (dump_file && (dump_flags & TDF_DETAILS))
672 fprintf (dump_file, "! Disqualifying ");
673 print_generic_expr (dump_file, decl, 0);
674 fprintf (dump_file, " - %s\n", reason);
678 /* Return true iff the type contains a field or an element which does not allow
679 scalarization. */
681 static bool
682 type_internals_preclude_sra_p (tree type, const char **msg)
684 tree fld;
685 tree et;
687 switch (TREE_CODE (type))
689 case RECORD_TYPE:
690 case UNION_TYPE:
691 case QUAL_UNION_TYPE:
692 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
693 if (TREE_CODE (fld) == FIELD_DECL)
695 tree ft = TREE_TYPE (fld);
697 if (TREE_THIS_VOLATILE (fld))
699 *msg = "volatile structure field";
700 return true;
702 if (!DECL_FIELD_OFFSET (fld))
704 *msg = "no structure field offset";
705 return true;
707 if (!DECL_SIZE (fld))
709 *msg = "zero structure field size";
710 return true;
712 if (!host_integerp (DECL_FIELD_OFFSET (fld), 1))
714 *msg = "structure field offset not fixed";
715 return true;
717 if (!host_integerp (DECL_SIZE (fld), 1))
719 *msg = "structure field size not fixed";
720 return true;
722 if (AGGREGATE_TYPE_P (ft)
723 && int_bit_position (fld) % BITS_PER_UNIT != 0)
725 *msg = "structure field is bit field";
726 return true;
729 if (AGGREGATE_TYPE_P (ft) && type_internals_preclude_sra_p (ft, msg))
730 return true;
733 return false;
735 case ARRAY_TYPE:
736 et = TREE_TYPE (type);
738 if (TYPE_VOLATILE (et))
740 *msg = "element type is volatile";
741 return true;
744 if (AGGREGATE_TYPE_P (et) && type_internals_preclude_sra_p (et, msg))
745 return true;
747 return false;
749 default:
750 return false;
754 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
755 base variable if it is. Return T if it is not an SSA_NAME. */
757 static tree
758 get_ssa_base_param (tree t)
760 if (TREE_CODE (t) == SSA_NAME)
762 if (SSA_NAME_IS_DEFAULT_DEF (t))
763 return SSA_NAME_VAR (t);
764 else
765 return NULL_TREE;
767 return t;
770 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
771 belongs to, unless the BB has already been marked as a potentially
772 final. */
774 static void
775 mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple stmt)
777 basic_block bb = gimple_bb (stmt);
778 int idx, parm_index = 0;
779 tree parm;
781 if (bitmap_bit_p (final_bbs, bb->index))
782 return;
784 for (parm = DECL_ARGUMENTS (current_function_decl);
785 parm && parm != base;
786 parm = DECL_CHAIN (parm))
787 parm_index++;
789 gcc_assert (parm_index < func_param_count);
791 idx = bb->index * func_param_count + parm_index;
792 if (bb_dereferences[idx] < dist)
793 bb_dereferences[idx] = dist;
796 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
797 the three fields. Also add it to the vector of accesses corresponding to
798 the base. Finally, return the new access. */
800 static struct access *
801 create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
803 VEC (access_p, heap) *vec;
804 struct access *access;
805 void **slot;
807 access = (struct access *) pool_alloc (access_pool);
808 memset (access, 0, sizeof (struct access));
809 access->base = base;
810 access->offset = offset;
811 access->size = size;
813 slot = pointer_map_contains (base_access_vec, base);
814 if (slot)
815 vec = (VEC (access_p, heap) *) *slot;
816 else
817 vec = VEC_alloc (access_p, heap, 32);
819 VEC_safe_push (access_p, heap, vec, access);
821 *((struct VEC (access_p,heap) **)
822 pointer_map_insert (base_access_vec, base)) = vec;
824 return access;
827 /* Create and insert access for EXPR. Return created access, or NULL if it is
828 not possible. */
830 static struct access *
831 create_access (tree expr, gimple stmt, bool write)
833 struct access *access;
834 HOST_WIDE_INT offset, size, max_size;
835 tree base = expr;
836 bool ptr, unscalarizable_region = false;
838 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
840 if (sra_mode == SRA_MODE_EARLY_IPA
841 && TREE_CODE (base) == MEM_REF)
843 base = get_ssa_base_param (TREE_OPERAND (base, 0));
844 if (!base)
845 return NULL;
846 ptr = true;
848 else
849 ptr = false;
851 if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
852 return NULL;
854 if (sra_mode == SRA_MODE_EARLY_IPA)
856 if (size < 0 || size != max_size)
858 disqualify_candidate (base, "Encountered a variable sized access.");
859 return NULL;
861 if (TREE_CODE (expr) == COMPONENT_REF
862 && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))
864 disqualify_candidate (base, "Encountered a bit-field access.");
865 return NULL;
867 gcc_checking_assert ((offset % BITS_PER_UNIT) == 0);
869 if (ptr)
870 mark_parm_dereference (base, offset + size, stmt);
872 else
874 if (size != max_size)
876 size = max_size;
877 unscalarizable_region = true;
879 if (size < 0)
881 disqualify_candidate (base, "Encountered an unconstrained access.");
882 return NULL;
886 access = create_access_1 (base, offset, size);
887 access->expr = expr;
888 access->type = TREE_TYPE (expr);
889 access->write = write;
890 access->grp_unscalarizable_region = unscalarizable_region;
891 access->stmt = stmt;
893 if (TREE_CODE (expr) == COMPONENT_REF
894 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1)))
895 access->non_addressable = 1;
897 return access;
901 /* Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple
902 register types or (recursively) records with only these two kinds of fields.
903 It also returns false if any of these records contains a bit-field. */
905 static bool
906 type_consists_of_records_p (tree type)
908 tree fld;
910 if (TREE_CODE (type) != RECORD_TYPE)
911 return false;
913 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
914 if (TREE_CODE (fld) == FIELD_DECL)
916 tree ft = TREE_TYPE (fld);
918 if (DECL_BIT_FIELD (fld))
919 return false;
921 if (!is_gimple_reg_type (ft)
922 && !type_consists_of_records_p (ft))
923 return false;
926 return true;
929 /* Create total_scalarization accesses for all scalar type fields in DECL that
930 must be of a RECORD_TYPE conforming to type_consists_of_records_p. BASE
931 must be the top-most VAR_DECL representing the variable, OFFSET must be the
932 offset of DECL within BASE. REF must be the memory reference expression for
933 the given decl. */
935 static void
936 completely_scalarize_record (tree base, tree decl, HOST_WIDE_INT offset,
937 tree ref)
939 tree fld, decl_type = TREE_TYPE (decl);
941 for (fld = TYPE_FIELDS (decl_type); fld; fld = DECL_CHAIN (fld))
942 if (TREE_CODE (fld) == FIELD_DECL)
944 HOST_WIDE_INT pos = offset + int_bit_position (fld);
945 tree ft = TREE_TYPE (fld);
946 tree nref = build3 (COMPONENT_REF, TREE_TYPE (fld), ref, fld,
947 NULL_TREE);
949 if (is_gimple_reg_type (ft))
951 struct access *access;
952 HOST_WIDE_INT size;
954 size = tree_low_cst (DECL_SIZE (fld), 1);
955 access = create_access_1 (base, pos, size);
956 access->expr = nref;
957 access->type = ft;
958 access->grp_total_scalarization = 1;
959 /* Accesses for intraprocedural SRA can have their stmt NULL. */
961 else
962 completely_scalarize_record (base, fld, pos, nref);
966 /* Create total_scalarization accesses for all scalar type fields in VAR and
967 for VAR a a whole. VAR must be of a RECORD_TYPE conforming to
968 type_consists_of_records_p. */
970 static void
971 completely_scalarize_var (tree var)
973 HOST_WIDE_INT size = tree_low_cst (DECL_SIZE (var), 1);
974 struct access *access;
976 access = create_access_1 (var, 0, size);
977 access->expr = var;
978 access->type = TREE_TYPE (var);
979 access->grp_total_scalarization = 1;
981 completely_scalarize_record (var, var, 0, var);
984 /* Search the given tree for a declaration by skipping handled components and
985 exclude it from the candidates. */
987 static void
988 disqualify_base_of_expr (tree t, const char *reason)
990 t = get_base_address (t);
991 if (sra_mode == SRA_MODE_EARLY_IPA
992 && TREE_CODE (t) == MEM_REF)
993 t = get_ssa_base_param (TREE_OPERAND (t, 0));
995 if (t && DECL_P (t))
996 disqualify_candidate (t, reason);
999 /* Scan expression EXPR and create access structures for all accesses to
1000 candidates for scalarization. Return the created access or NULL if none is
1001 created. */
1003 static struct access *
1004 build_access_from_expr_1 (tree expr, gimple stmt, bool write)
1006 struct access *ret = NULL;
1007 bool partial_ref;
1009 if (TREE_CODE (expr) == BIT_FIELD_REF
1010 || TREE_CODE (expr) == IMAGPART_EXPR
1011 || TREE_CODE (expr) == REALPART_EXPR)
1013 expr = TREE_OPERAND (expr, 0);
1014 partial_ref = true;
1016 else
1017 partial_ref = false;
1019 /* We need to dive through V_C_Es in order to get the size of its parameter
1020 and not the result type. Ada produces such statements. We are also
1021 capable of handling the topmost V_C_E but not any of those buried in other
1022 handled components. */
1023 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
1024 expr = TREE_OPERAND (expr, 0);
1026 if (contains_view_convert_expr_p (expr))
1028 disqualify_base_of_expr (expr, "V_C_E under a different handled "
1029 "component.");
1030 return NULL;
1033 switch (TREE_CODE (expr))
1035 case MEM_REF:
1036 if (TREE_CODE (TREE_OPERAND (expr, 0)) != ADDR_EXPR
1037 && sra_mode != SRA_MODE_EARLY_IPA)
1038 return NULL;
1039 /* fall through */
1040 case VAR_DECL:
1041 case PARM_DECL:
1042 case RESULT_DECL:
1043 case COMPONENT_REF:
1044 case ARRAY_REF:
1045 case ARRAY_RANGE_REF:
1046 ret = create_access (expr, stmt, write);
1047 break;
1049 default:
1050 break;
1053 if (write && partial_ref && ret)
1054 ret->grp_partial_lhs = 1;
1056 return ret;
1059 /* Scan expression EXPR and create access structures for all accesses to
1060 candidates for scalarization. Return true if any access has been inserted.
1061 STMT must be the statement from which the expression is taken, WRITE must be
1062 true if the expression is a store and false otherwise. */
1064 static bool
1065 build_access_from_expr (tree expr, gimple stmt, bool write)
1067 struct access *access;
1069 access = build_access_from_expr_1 (expr, stmt, write);
1070 if (access)
1072 /* This means the aggregate is accesses as a whole in a way other than an
1073 assign statement and thus cannot be removed even if we had a scalar
1074 replacement for everything. */
1075 if (cannot_scalarize_away_bitmap)
1076 bitmap_set_bit (cannot_scalarize_away_bitmap, DECL_UID (access->base));
1077 return true;
1079 return false;
1082 /* Disqualify LHS and RHS for scalarization if STMT must end its basic block in
1083 modes in which it matters, return true iff they have been disqualified. RHS
1084 may be NULL, in that case ignore it. If we scalarize an aggregate in
1085 intra-SRA we may need to add statements after each statement. This is not
1086 possible if a statement unconditionally has to end the basic block. */
1087 static bool
1088 disqualify_ops_if_throwing_stmt (gimple stmt, tree lhs, tree rhs)
1090 if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1091 && (stmt_can_throw_internal (stmt) || stmt_ends_bb_p (stmt)))
1093 disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
1094 if (rhs)
1095 disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
1096 return true;
1098 return false;
1101 /* Scan expressions occurring in STMT, create access structures for all accesses
1102 to candidates for scalarization and remove those candidates which occur in
1103 statements or expressions that prevent them from being split apart. Return
1104 true if any access has been inserted. */
1106 static bool
1107 build_accesses_from_assign (gimple stmt)
1109 tree lhs, rhs;
1110 struct access *lacc, *racc;
1112 if (!gimple_assign_single_p (stmt)
1113 /* Scope clobbers don't influence scalarization. */
1114 || gimple_clobber_p (stmt))
1115 return false;
1117 lhs = gimple_assign_lhs (stmt);
1118 rhs = gimple_assign_rhs1 (stmt);
1120 if (disqualify_ops_if_throwing_stmt (stmt, lhs, rhs))
1121 return false;
1123 racc = build_access_from_expr_1 (rhs, stmt, false);
1124 lacc = build_access_from_expr_1 (lhs, stmt, true);
1126 if (lacc)
1127 lacc->grp_assignment_write = 1;
1129 if (racc)
1131 racc->grp_assignment_read = 1;
1132 if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
1133 && !is_gimple_reg_type (racc->type))
1134 bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
1137 if (lacc && racc
1138 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1139 && !lacc->grp_unscalarizable_region
1140 && !racc->grp_unscalarizable_region
1141 && AGGREGATE_TYPE_P (TREE_TYPE (lhs))
1142 && lacc->size == racc->size
1143 && useless_type_conversion_p (lacc->type, racc->type))
1145 struct assign_link *link;
1147 link = (struct assign_link *) pool_alloc (link_pool);
1148 memset (link, 0, sizeof (struct assign_link));
1150 link->lacc = lacc;
1151 link->racc = racc;
1153 add_link_to_rhs (racc, link);
1156 return lacc || racc;
1159 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1160 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1162 static bool
1163 asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED, tree op,
1164 void *data ATTRIBUTE_UNUSED)
1166 op = get_base_address (op);
1167 if (op
1168 && DECL_P (op))
1169 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
1171 return false;
1174 /* Return true iff callsite CALL has at least as many actual arguments as there
1175 are formal parameters of the function currently processed by IPA-SRA. */
1177 static inline bool
1178 callsite_has_enough_arguments_p (gimple call)
1180 return gimple_call_num_args (call) >= (unsigned) func_param_count;
1183 /* Scan function and look for interesting expressions and create access
1184 structures for them. Return true iff any access is created. */
1186 static bool
1187 scan_function (void)
1189 basic_block bb;
1190 bool ret = false;
1192 FOR_EACH_BB (bb)
1194 gimple_stmt_iterator gsi;
1195 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1197 gimple stmt = gsi_stmt (gsi);
1198 tree t;
1199 unsigned i;
1201 if (final_bbs && stmt_can_throw_external (stmt))
1202 bitmap_set_bit (final_bbs, bb->index);
1203 switch (gimple_code (stmt))
1205 case GIMPLE_RETURN:
1206 t = gimple_return_retval (stmt);
1207 if (t != NULL_TREE)
1208 ret |= build_access_from_expr (t, stmt, false);
1209 if (final_bbs)
1210 bitmap_set_bit (final_bbs, bb->index);
1211 break;
1213 case GIMPLE_ASSIGN:
1214 ret |= build_accesses_from_assign (stmt);
1215 break;
1217 case GIMPLE_CALL:
1218 for (i = 0; i < gimple_call_num_args (stmt); i++)
1219 ret |= build_access_from_expr (gimple_call_arg (stmt, i),
1220 stmt, false);
1222 if (sra_mode == SRA_MODE_EARLY_IPA)
1224 tree dest = gimple_call_fndecl (stmt);
1225 int flags = gimple_call_flags (stmt);
1227 if (dest)
1229 if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1230 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1231 encountered_apply_args = true;
1232 if (cgraph_get_node (dest)
1233 == cgraph_get_node (current_function_decl))
1235 encountered_recursive_call = true;
1236 if (!callsite_has_enough_arguments_p (stmt))
1237 encountered_unchangable_recursive_call = true;
1241 if (final_bbs
1242 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1243 bitmap_set_bit (final_bbs, bb->index);
1246 t = gimple_call_lhs (stmt);
1247 if (t && !disqualify_ops_if_throwing_stmt (stmt, t, NULL))
1248 ret |= build_access_from_expr (t, stmt, true);
1249 break;
1251 case GIMPLE_ASM:
1252 walk_stmt_load_store_addr_ops (stmt, NULL, NULL, NULL,
1253 asm_visit_addr);
1254 if (final_bbs)
1255 bitmap_set_bit (final_bbs, bb->index);
1257 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
1259 t = TREE_VALUE (gimple_asm_input_op (stmt, i));
1260 ret |= build_access_from_expr (t, stmt, false);
1262 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
1264 t = TREE_VALUE (gimple_asm_output_op (stmt, i));
1265 ret |= build_access_from_expr (t, stmt, true);
1267 break;
1269 default:
1270 break;
1275 return ret;
1278 /* Helper of QSORT function. There are pointers to accesses in the array. An
1279 access is considered smaller than another if it has smaller offset or if the
1280 offsets are the same but is size is bigger. */
1282 static int
1283 compare_access_positions (const void *a, const void *b)
1285 const access_p *fp1 = (const access_p *) a;
1286 const access_p *fp2 = (const access_p *) b;
1287 const access_p f1 = *fp1;
1288 const access_p f2 = *fp2;
1290 if (f1->offset != f2->offset)
1291 return f1->offset < f2->offset ? -1 : 1;
1293 if (f1->size == f2->size)
1295 if (f1->type == f2->type)
1296 return 0;
1297 /* Put any non-aggregate type before any aggregate type. */
1298 else if (!is_gimple_reg_type (f1->type)
1299 && is_gimple_reg_type (f2->type))
1300 return 1;
1301 else if (is_gimple_reg_type (f1->type)
1302 && !is_gimple_reg_type (f2->type))
1303 return -1;
1304 /* Put any complex or vector type before any other scalar type. */
1305 else if (TREE_CODE (f1->type) != COMPLEX_TYPE
1306 && TREE_CODE (f1->type) != VECTOR_TYPE
1307 && (TREE_CODE (f2->type) == COMPLEX_TYPE
1308 || TREE_CODE (f2->type) == VECTOR_TYPE))
1309 return 1;
1310 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
1311 || TREE_CODE (f1->type) == VECTOR_TYPE)
1312 && TREE_CODE (f2->type) != COMPLEX_TYPE
1313 && TREE_CODE (f2->type) != VECTOR_TYPE)
1314 return -1;
1315 /* Put the integral type with the bigger precision first. */
1316 else if (INTEGRAL_TYPE_P (f1->type)
1317 && INTEGRAL_TYPE_P (f2->type))
1318 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
1319 /* Put any integral type with non-full precision last. */
1320 else if (INTEGRAL_TYPE_P (f1->type)
1321 && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type))
1322 != TYPE_PRECISION (f1->type)))
1323 return 1;
1324 else if (INTEGRAL_TYPE_P (f2->type)
1325 && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type))
1326 != TYPE_PRECISION (f2->type)))
1327 return -1;
1328 /* Stabilize the sort. */
1329 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1332 /* We want the bigger accesses first, thus the opposite operator in the next
1333 line: */
1334 return f1->size > f2->size ? -1 : 1;
1338 /* Append a name of the declaration to the name obstack. A helper function for
1339 make_fancy_name. */
1341 static void
1342 make_fancy_decl_name (tree decl)
1344 char buffer[32];
1346 tree name = DECL_NAME (decl);
1347 if (name)
1348 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1349 IDENTIFIER_LENGTH (name));
1350 else
1352 sprintf (buffer, "D%u", DECL_UID (decl));
1353 obstack_grow (&name_obstack, buffer, strlen (buffer));
1357 /* Helper for make_fancy_name. */
1359 static void
1360 make_fancy_name_1 (tree expr)
1362 char buffer[32];
1363 tree index;
1365 if (DECL_P (expr))
1367 make_fancy_decl_name (expr);
1368 return;
1371 switch (TREE_CODE (expr))
1373 case COMPONENT_REF:
1374 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1375 obstack_1grow (&name_obstack, '$');
1376 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1377 break;
1379 case ARRAY_REF:
1380 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1381 obstack_1grow (&name_obstack, '$');
1382 /* Arrays with only one element may not have a constant as their
1383 index. */
1384 index = TREE_OPERAND (expr, 1);
1385 if (TREE_CODE (index) != INTEGER_CST)
1386 break;
1387 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1388 obstack_grow (&name_obstack, buffer, strlen (buffer));
1389 break;
1391 case ADDR_EXPR:
1392 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1393 break;
1395 case MEM_REF:
1396 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1397 if (!integer_zerop (TREE_OPERAND (expr, 1)))
1399 obstack_1grow (&name_obstack, '$');
1400 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC,
1401 TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)));
1402 obstack_grow (&name_obstack, buffer, strlen (buffer));
1404 break;
1406 case BIT_FIELD_REF:
1407 case REALPART_EXPR:
1408 case IMAGPART_EXPR:
1409 gcc_unreachable (); /* we treat these as scalars. */
1410 break;
1411 default:
1412 break;
1416 /* Create a human readable name for replacement variable of ACCESS. */
1418 static char *
1419 make_fancy_name (tree expr)
1421 make_fancy_name_1 (expr);
1422 obstack_1grow (&name_obstack, '\0');
1423 return XOBFINISH (&name_obstack, char *);
1426 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1427 EXP_TYPE at the given OFFSET. If BASE is something for which
1428 get_addr_base_and_unit_offset returns NULL, gsi must be non-NULL and is used
1429 to insert new statements either before or below the current one as specified
1430 by INSERT_AFTER. This function is not capable of handling bitfields. */
1432 tree
1433 build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
1434 tree exp_type, gimple_stmt_iterator *gsi,
1435 bool insert_after)
1437 tree prev_base = base;
1438 tree off;
1439 HOST_WIDE_INT base_offset;
1440 unsigned HOST_WIDE_INT misalign;
1441 unsigned int align;
1443 gcc_checking_assert (offset % BITS_PER_UNIT == 0);
1445 base = get_addr_base_and_unit_offset (base, &base_offset);
1447 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1448 offset such as array[var_index]. */
1449 if (!base)
1451 gimple stmt;
1452 tree tmp, addr;
1454 gcc_checking_assert (gsi);
1455 tmp = make_ssa_name (build_pointer_type (TREE_TYPE (prev_base)), NULL);
1456 addr = build_fold_addr_expr (unshare_expr (prev_base));
1457 STRIP_USELESS_TYPE_CONVERSION (addr);
1458 stmt = gimple_build_assign (tmp, addr);
1459 gimple_set_location (stmt, loc);
1460 if (insert_after)
1461 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
1462 else
1463 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1465 off = build_int_cst (reference_alias_ptr_type (prev_base),
1466 offset / BITS_PER_UNIT);
1467 base = tmp;
1469 else if (TREE_CODE (base) == MEM_REF)
1471 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1472 base_offset + offset / BITS_PER_UNIT);
1473 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1474 base = unshare_expr (TREE_OPERAND (base, 0));
1476 else
1478 off = build_int_cst (reference_alias_ptr_type (base),
1479 base_offset + offset / BITS_PER_UNIT);
1480 base = build_fold_addr_expr (unshare_expr (base));
1483 /* If prev_base were always an originally performed access
1484 we can extract more optimistic alignment information
1485 by looking at the access mode. That would constrain the
1486 alignment of base + base_offset which we would need to
1487 adjust according to offset. */
1488 if (!get_pointer_alignment_1 (base, &align, &misalign))
1490 gcc_assert (misalign == 0);
1491 if (TREE_CODE (prev_base) == MEM_REF
1492 || TREE_CODE (prev_base) == TARGET_MEM_REF)
1493 align = TYPE_ALIGN (TREE_TYPE (prev_base));
1495 misalign += (tree_to_double_int (off)
1496 .sext (TYPE_PRECISION (TREE_TYPE (off))).low
1497 * BITS_PER_UNIT);
1498 misalign = misalign & (align - 1);
1499 if (misalign != 0)
1500 align = (misalign & -misalign);
1501 if (align < TYPE_ALIGN (exp_type))
1502 exp_type = build_aligned_type (exp_type, align);
1504 return fold_build2_loc (loc, MEM_REF, exp_type, base, off);
1507 /* Construct a memory reference to a part of an aggregate BASE at the given
1508 OFFSET and of the same type as MODEL. In case this is a reference to a
1509 bit-field, the function will replicate the last component_ref of model's
1510 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1511 build_ref_for_offset. */
1513 static tree
1514 build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1515 struct access *model, gimple_stmt_iterator *gsi,
1516 bool insert_after)
1518 if (TREE_CODE (model->expr) == COMPONENT_REF
1519 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1521 /* This access represents a bit-field. */
1522 tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
1524 offset -= int_bit_position (fld);
1525 exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
1526 t = build_ref_for_offset (loc, base, offset, exp_type, gsi, insert_after);
1527 return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
1528 NULL_TREE);
1530 else
1531 return build_ref_for_offset (loc, base, offset, model->type,
1532 gsi, insert_after);
1535 /* Attempt to build a memory reference that we could but into a gimple
1536 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1537 create statements and return s NULL instead. This function also ignores
1538 alignment issues and so its results should never end up in non-debug
1539 statements. */
1541 static tree
1542 build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1543 struct access *model)
1545 HOST_WIDE_INT base_offset;
1546 tree off;
1548 if (TREE_CODE (model->expr) == COMPONENT_REF
1549 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1550 return NULL_TREE;
1552 base = get_addr_base_and_unit_offset (base, &base_offset);
1553 if (!base)
1554 return NULL_TREE;
1555 if (TREE_CODE (base) == MEM_REF)
1557 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1558 base_offset + offset / BITS_PER_UNIT);
1559 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1560 base = unshare_expr (TREE_OPERAND (base, 0));
1562 else
1564 off = build_int_cst (reference_alias_ptr_type (base),
1565 base_offset + offset / BITS_PER_UNIT);
1566 base = build_fold_addr_expr (unshare_expr (base));
1569 return fold_build2_loc (loc, MEM_REF, model->type, base, off);
1572 /* Construct a memory reference consisting of component_refs and array_refs to
1573 a part of an aggregate *RES (which is of type TYPE). The requested part
1574 should have type EXP_TYPE at be the given OFFSET. This function might not
1575 succeed, it returns true when it does and only then *RES points to something
1576 meaningful. This function should be used only to build expressions that we
1577 might need to present to user (e.g. in warnings). In all other situations,
1578 build_ref_for_model or build_ref_for_offset should be used instead. */
1580 static bool
1581 build_user_friendly_ref_for_offset (tree *res, tree type, HOST_WIDE_INT offset,
1582 tree exp_type)
1584 while (1)
1586 tree fld;
1587 tree tr_size, index, minidx;
1588 HOST_WIDE_INT el_size;
1590 if (offset == 0 && exp_type
1591 && types_compatible_p (exp_type, type))
1592 return true;
1594 switch (TREE_CODE (type))
1596 case UNION_TYPE:
1597 case QUAL_UNION_TYPE:
1598 case RECORD_TYPE:
1599 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
1601 HOST_WIDE_INT pos, size;
1602 tree tr_pos, expr, *expr_ptr;
1604 if (TREE_CODE (fld) != FIELD_DECL)
1605 continue;
1607 tr_pos = bit_position (fld);
1608 if (!tr_pos || !host_integerp (tr_pos, 1))
1609 continue;
1610 pos = TREE_INT_CST_LOW (tr_pos);
1611 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1612 tr_size = DECL_SIZE (fld);
1613 if (!tr_size || !host_integerp (tr_size, 1))
1614 continue;
1615 size = TREE_INT_CST_LOW (tr_size);
1616 if (size == 0)
1618 if (pos != offset)
1619 continue;
1621 else if (pos > offset || (pos + size) <= offset)
1622 continue;
1624 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1625 NULL_TREE);
1626 expr_ptr = &expr;
1627 if (build_user_friendly_ref_for_offset (expr_ptr, TREE_TYPE (fld),
1628 offset - pos, exp_type))
1630 *res = expr;
1631 return true;
1634 return false;
1636 case ARRAY_TYPE:
1637 tr_size = TYPE_SIZE (TREE_TYPE (type));
1638 if (!tr_size || !host_integerp (tr_size, 1))
1639 return false;
1640 el_size = tree_low_cst (tr_size, 1);
1642 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1643 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
1644 return false;
1645 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1646 if (!integer_zerop (minidx))
1647 index = int_const_binop (PLUS_EXPR, index, minidx);
1648 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1649 NULL_TREE, NULL_TREE);
1650 offset = offset % el_size;
1651 type = TREE_TYPE (type);
1652 break;
1654 default:
1655 if (offset != 0)
1656 return false;
1658 if (exp_type)
1659 return false;
1660 else
1661 return true;
1666 /* Return true iff TYPE is stdarg va_list type. */
1668 static inline bool
1669 is_va_list_type (tree type)
1671 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1674 /* Print message to dump file why a variable was rejected. */
1676 static void
1677 reject (tree var, const char *msg)
1679 if (dump_file && (dump_flags & TDF_DETAILS))
1681 fprintf (dump_file, "Rejected (%d): %s: ", DECL_UID (var), msg);
1682 print_generic_expr (dump_file, var, 0);
1683 fprintf (dump_file, "\n");
1687 /* Return true if VAR is a candidate for SRA. */
1689 static bool
1690 maybe_add_sra_candidate (tree var)
1692 tree type = TREE_TYPE (var);
1693 const char *msg;
1694 void **slot;
1696 if (!AGGREGATE_TYPE_P (type))
1698 reject (var, "not aggregate");
1699 return false;
1701 if (needs_to_live_in_memory (var))
1703 reject (var, "needs to live in memory");
1704 return false;
1706 if (TREE_THIS_VOLATILE (var))
1708 reject (var, "is volatile");
1709 return false;
1711 if (!COMPLETE_TYPE_P (type))
1713 reject (var, "has incomplete type");
1714 return false;
1716 if (!host_integerp (TYPE_SIZE (type), 1))
1718 reject (var, "type size not fixed");
1719 return false;
1721 if (tree_low_cst (TYPE_SIZE (type), 1) == 0)
1723 reject (var, "type size is zero");
1724 return false;
1726 if (type_internals_preclude_sra_p (type, &msg))
1728 reject (var, msg);
1729 return false;
1731 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1732 we also want to schedule it rather late. Thus we ignore it in
1733 the early pass. */
1734 (sra_mode == SRA_MODE_EARLY_INTRA
1735 && is_va_list_type (type)))
1737 reject (var, "is va_list");
1738 return false;
1741 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
1742 slot = htab_find_slot_with_hash (candidates, var, DECL_UID (var), INSERT);
1743 *slot = (void *) var;
1745 if (dump_file && (dump_flags & TDF_DETAILS))
1747 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
1748 print_generic_expr (dump_file, var, 0);
1749 fprintf (dump_file, "\n");
1752 return true;
1755 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1756 those with type which is suitable for scalarization. */
1758 static bool
1759 find_var_candidates (void)
1761 tree var, parm;
1762 unsigned int i;
1763 bool ret = false;
1765 for (parm = DECL_ARGUMENTS (current_function_decl);
1766 parm;
1767 parm = DECL_CHAIN (parm))
1768 ret |= maybe_add_sra_candidate (parm);
1770 FOR_EACH_LOCAL_DECL (cfun, i, var)
1772 if (TREE_CODE (var) != VAR_DECL)
1773 continue;
1775 ret |= maybe_add_sra_candidate (var);
1778 return ret;
1781 /* Sort all accesses for the given variable, check for partial overlaps and
1782 return NULL if there are any. If there are none, pick a representative for
1783 each combination of offset and size and create a linked list out of them.
1784 Return the pointer to the first representative and make sure it is the first
1785 one in the vector of accesses. */
1787 static struct access *
1788 sort_and_splice_var_accesses (tree var)
1790 int i, j, access_count;
1791 struct access *res, **prev_acc_ptr = &res;
1792 VEC (access_p, heap) *access_vec;
1793 bool first = true;
1794 HOST_WIDE_INT low = -1, high = 0;
1796 access_vec = get_base_access_vector (var);
1797 if (!access_vec)
1798 return NULL;
1799 access_count = VEC_length (access_p, access_vec);
1801 /* Sort by <OFFSET, SIZE>. */
1802 VEC_qsort (access_p, access_vec, compare_access_positions);
1804 i = 0;
1805 while (i < access_count)
1807 struct access *access = VEC_index (access_p, access_vec, i);
1808 bool grp_write = access->write;
1809 bool grp_read = !access->write;
1810 bool grp_scalar_write = access->write
1811 && is_gimple_reg_type (access->type);
1812 bool grp_scalar_read = !access->write
1813 && is_gimple_reg_type (access->type);
1814 bool grp_assignment_read = access->grp_assignment_read;
1815 bool grp_assignment_write = access->grp_assignment_write;
1816 bool multiple_scalar_reads = false;
1817 bool total_scalarization = access->grp_total_scalarization;
1818 bool grp_partial_lhs = access->grp_partial_lhs;
1819 bool first_scalar = is_gimple_reg_type (access->type);
1820 bool unscalarizable_region = access->grp_unscalarizable_region;
1822 if (first || access->offset >= high)
1824 first = false;
1825 low = access->offset;
1826 high = access->offset + access->size;
1828 else if (access->offset > low && access->offset + access->size > high)
1829 return NULL;
1830 else
1831 gcc_assert (access->offset >= low
1832 && access->offset + access->size <= high);
1834 j = i + 1;
1835 while (j < access_count)
1837 struct access *ac2 = VEC_index (access_p, access_vec, j);
1838 if (ac2->offset != access->offset || ac2->size != access->size)
1839 break;
1840 if (ac2->write)
1842 grp_write = true;
1843 grp_scalar_write = (grp_scalar_write
1844 || is_gimple_reg_type (ac2->type));
1846 else
1848 grp_read = true;
1849 if (is_gimple_reg_type (ac2->type))
1851 if (grp_scalar_read)
1852 multiple_scalar_reads = true;
1853 else
1854 grp_scalar_read = true;
1857 grp_assignment_read |= ac2->grp_assignment_read;
1858 grp_assignment_write |= ac2->grp_assignment_write;
1859 grp_partial_lhs |= ac2->grp_partial_lhs;
1860 unscalarizable_region |= ac2->grp_unscalarizable_region;
1861 total_scalarization |= ac2->grp_total_scalarization;
1862 relink_to_new_repr (access, ac2);
1864 /* If there are both aggregate-type and scalar-type accesses with
1865 this combination of size and offset, the comparison function
1866 should have put the scalars first. */
1867 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
1868 ac2->group_representative = access;
1869 j++;
1872 i = j;
1874 access->group_representative = access;
1875 access->grp_write = grp_write;
1876 access->grp_read = grp_read;
1877 access->grp_scalar_read = grp_scalar_read;
1878 access->grp_scalar_write = grp_scalar_write;
1879 access->grp_assignment_read = grp_assignment_read;
1880 access->grp_assignment_write = grp_assignment_write;
1881 access->grp_hint = multiple_scalar_reads || total_scalarization;
1882 access->grp_total_scalarization = total_scalarization;
1883 access->grp_partial_lhs = grp_partial_lhs;
1884 access->grp_unscalarizable_region = unscalarizable_region;
1885 if (access->first_link)
1886 add_access_to_work_queue (access);
1888 *prev_acc_ptr = access;
1889 prev_acc_ptr = &access->next_grp;
1892 gcc_assert (res == VEC_index (access_p, access_vec, 0));
1893 return res;
1896 /* Create a variable for the given ACCESS which determines the type, name and a
1897 few other properties. Return the variable declaration and store it also to
1898 ACCESS->replacement. */
1900 static tree
1901 create_access_replacement (struct access *access)
1903 tree repl;
1905 if (access->grp_to_be_debug_replaced)
1907 repl = create_tmp_var_raw (access->type, NULL);
1908 DECL_CONTEXT (repl) = current_function_decl;
1910 else
1911 repl = create_tmp_var (access->type, "SR");
1912 if (TREE_CODE (access->type) == COMPLEX_TYPE
1913 || TREE_CODE (access->type) == VECTOR_TYPE)
1915 if (!access->grp_partial_lhs)
1916 DECL_GIMPLE_REG_P (repl) = 1;
1918 else if (access->grp_partial_lhs
1919 && is_gimple_reg_type (access->type))
1920 TREE_ADDRESSABLE (repl) = 1;
1922 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
1923 DECL_ARTIFICIAL (repl) = 1;
1924 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
1926 if (DECL_NAME (access->base)
1927 && !DECL_IGNORED_P (access->base)
1928 && !DECL_ARTIFICIAL (access->base))
1930 char *pretty_name = make_fancy_name (access->expr);
1931 tree debug_expr = unshare_expr (access->expr), d;
1932 bool fail = false;
1934 DECL_NAME (repl) = get_identifier (pretty_name);
1935 obstack_free (&name_obstack, pretty_name);
1937 /* Get rid of any SSA_NAMEs embedded in debug_expr,
1938 as DECL_DEBUG_EXPR isn't considered when looking for still
1939 used SSA_NAMEs and thus they could be freed. All debug info
1940 generation cares is whether something is constant or variable
1941 and that get_ref_base_and_extent works properly on the
1942 expression. It cannot handle accesses at a non-constant offset
1943 though, so just give up in those cases. */
1944 for (d = debug_expr;
1945 !fail && (handled_component_p (d) || TREE_CODE (d) == MEM_REF);
1946 d = TREE_OPERAND (d, 0))
1947 switch (TREE_CODE (d))
1949 case ARRAY_REF:
1950 case ARRAY_RANGE_REF:
1951 if (TREE_OPERAND (d, 1)
1952 && TREE_CODE (TREE_OPERAND (d, 1)) != INTEGER_CST)
1953 fail = true;
1954 if (TREE_OPERAND (d, 3)
1955 && TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST)
1956 fail = true;
1957 /* FALLTHRU */
1958 case COMPONENT_REF:
1959 if (TREE_OPERAND (d, 2)
1960 && TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST)
1961 fail = true;
1962 break;
1963 case MEM_REF:
1964 if (TREE_CODE (TREE_OPERAND (d, 0)) != ADDR_EXPR)
1965 fail = true;
1966 else
1967 d = TREE_OPERAND (d, 0);
1968 break;
1969 default:
1970 break;
1972 if (!fail)
1974 SET_DECL_DEBUG_EXPR (repl, debug_expr);
1975 DECL_DEBUG_EXPR_IS_FROM (repl) = 1;
1977 if (access->grp_no_warning)
1978 TREE_NO_WARNING (repl) = 1;
1979 else
1980 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
1982 else
1983 TREE_NO_WARNING (repl) = 1;
1985 if (dump_file)
1987 if (access->grp_to_be_debug_replaced)
1989 fprintf (dump_file, "Created a debug-only replacement for ");
1990 print_generic_expr (dump_file, access->base, 0);
1991 fprintf (dump_file, " offset: %u, size: %u\n",
1992 (unsigned) access->offset, (unsigned) access->size);
1994 else
1996 fprintf (dump_file, "Created a replacement for ");
1997 print_generic_expr (dump_file, access->base, 0);
1998 fprintf (dump_file, " offset: %u, size: %u: ",
1999 (unsigned) access->offset, (unsigned) access->size);
2000 print_generic_expr (dump_file, repl, 0);
2001 fprintf (dump_file, "\n");
2004 sra_stats.replacements++;
2006 return repl;
2009 /* Return ACCESS scalar replacement, create it if it does not exist yet. */
2011 static inline tree
2012 get_access_replacement (struct access *access)
2014 if (!access->replacement_decl)
2015 access->replacement_decl = create_access_replacement (access);
2016 return access->replacement_decl;
2020 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2021 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2022 to it is not "within" the root. Return false iff some accesses partially
2023 overlap. */
2025 static bool
2026 build_access_subtree (struct access **access)
2028 struct access *root = *access, *last_child = NULL;
2029 HOST_WIDE_INT limit = root->offset + root->size;
2031 *access = (*access)->next_grp;
2032 while (*access && (*access)->offset + (*access)->size <= limit)
2034 if (!last_child)
2035 root->first_child = *access;
2036 else
2037 last_child->next_sibling = *access;
2038 last_child = *access;
2040 if (!build_access_subtree (access))
2041 return false;
2044 if (*access && (*access)->offset < limit)
2045 return false;
2047 return true;
2050 /* Build a tree of access representatives, ACCESS is the pointer to the first
2051 one, others are linked in a list by the next_grp field. Return false iff
2052 some accesses partially overlap. */
2054 static bool
2055 build_access_trees (struct access *access)
2057 while (access)
2059 struct access *root = access;
2061 if (!build_access_subtree (&access))
2062 return false;
2063 root->next_grp = access;
2065 return true;
2068 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2069 array. */
2071 static bool
2072 expr_with_var_bounded_array_refs_p (tree expr)
2074 while (handled_component_p (expr))
2076 if (TREE_CODE (expr) == ARRAY_REF
2077 && !host_integerp (array_ref_low_bound (expr), 0))
2078 return true;
2079 expr = TREE_OPERAND (expr, 0);
2081 return false;
2084 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2085 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2086 sorts of access flags appropriately along the way, notably always set
2087 grp_read and grp_assign_read according to MARK_READ and grp_write when
2088 MARK_WRITE is true.
2090 Creating a replacement for a scalar access is considered beneficial if its
2091 grp_hint is set (this means we are either attempting total scalarization or
2092 there is more than one direct read access) or according to the following
2093 table:
2095 Access written to through a scalar type (once or more times)
2097 | Written to in an assignment statement
2099 | | Access read as scalar _once_
2100 | | |
2101 | | | Read in an assignment statement
2102 | | | |
2103 | | | | Scalarize Comment
2104 -----------------------------------------------------------------------------
2105 0 0 0 0 No access for the scalar
2106 0 0 0 1 No access for the scalar
2107 0 0 1 0 No Single read - won't help
2108 0 0 1 1 No The same case
2109 0 1 0 0 No access for the scalar
2110 0 1 0 1 No access for the scalar
2111 0 1 1 0 Yes s = *g; return s.i;
2112 0 1 1 1 Yes The same case as above
2113 1 0 0 0 No Won't help
2114 1 0 0 1 Yes s.i = 1; *g = s;
2115 1 0 1 0 Yes s.i = 5; g = s.i;
2116 1 0 1 1 Yes The same case as above
2117 1 1 0 0 No Won't help.
2118 1 1 0 1 Yes s.i = 1; *g = s;
2119 1 1 1 0 Yes s = *g; return s.i;
2120 1 1 1 1 Yes Any of the above yeses */
2122 static bool
2123 analyze_access_subtree (struct access *root, struct access *parent,
2124 bool allow_replacements)
2126 struct access *child;
2127 HOST_WIDE_INT limit = root->offset + root->size;
2128 HOST_WIDE_INT covered_to = root->offset;
2129 bool scalar = is_gimple_reg_type (root->type);
2130 bool hole = false, sth_created = false;
2132 if (parent)
2134 if (parent->grp_read)
2135 root->grp_read = 1;
2136 if (parent->grp_assignment_read)
2137 root->grp_assignment_read = 1;
2138 if (parent->grp_write)
2139 root->grp_write = 1;
2140 if (parent->grp_assignment_write)
2141 root->grp_assignment_write = 1;
2142 if (parent->grp_total_scalarization)
2143 root->grp_total_scalarization = 1;
2146 if (root->grp_unscalarizable_region)
2147 allow_replacements = false;
2149 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
2150 allow_replacements = false;
2152 for (child = root->first_child; child; child = child->next_sibling)
2154 hole |= covered_to < child->offset;
2155 sth_created |= analyze_access_subtree (child, root,
2156 allow_replacements && !scalar);
2158 root->grp_unscalarized_data |= child->grp_unscalarized_data;
2159 root->grp_total_scalarization &= child->grp_total_scalarization;
2160 if (child->grp_covered)
2161 covered_to += child->size;
2162 else
2163 hole = true;
2166 if (allow_replacements && scalar && !root->first_child
2167 && (root->grp_hint
2168 || ((root->grp_scalar_read || root->grp_assignment_read)
2169 && (root->grp_scalar_write || root->grp_assignment_write))))
2171 bool new_integer_type;
2172 /* Always create access replacements that cover the whole access.
2173 For integral types this means the precision has to match.
2174 Avoid assumptions based on the integral type kind, too. */
2175 if (INTEGRAL_TYPE_P (root->type)
2176 && (TREE_CODE (root->type) != INTEGER_TYPE
2177 || TYPE_PRECISION (root->type) != root->size)
2178 /* But leave bitfield accesses alone. */
2179 && (TREE_CODE (root->expr) != COMPONENT_REF
2180 || !DECL_BIT_FIELD (TREE_OPERAND (root->expr, 1))))
2182 tree rt = root->type;
2183 gcc_assert ((root->offset % BITS_PER_UNIT) == 0
2184 && (root->size % BITS_PER_UNIT) == 0);
2185 root->type = build_nonstandard_integer_type (root->size,
2186 TYPE_UNSIGNED (rt));
2187 root->expr = build_ref_for_offset (UNKNOWN_LOCATION,
2188 root->base, root->offset,
2189 root->type, NULL, false);
2190 new_integer_type = true;
2192 else
2193 new_integer_type = false;
2195 if (dump_file && (dump_flags & TDF_DETAILS))
2197 fprintf (dump_file, "Marking ");
2198 print_generic_expr (dump_file, root->base, 0);
2199 fprintf (dump_file, " offset: %u, size: %u ",
2200 (unsigned) root->offset, (unsigned) root->size);
2201 fprintf (dump_file, " to be replaced%s.\n",
2202 new_integer_type ? " with an integer": "");
2205 root->grp_to_be_replaced = 1;
2206 sth_created = true;
2207 hole = false;
2209 else
2211 if (MAY_HAVE_DEBUG_STMTS && allow_replacements
2212 && scalar && !root->first_child
2213 && (root->grp_scalar_write || root->grp_assignment_write))
2215 gcc_checking_assert (!root->grp_scalar_read
2216 && !root->grp_assignment_read);
2217 root->grp_to_be_debug_replaced = 1;
2218 if (dump_file && (dump_flags & TDF_DETAILS))
2220 fprintf (dump_file, "Marking ");
2221 print_generic_expr (dump_file, root->base, 0);
2222 fprintf (dump_file, " offset: %u, size: %u ",
2223 (unsigned) root->offset, (unsigned) root->size);
2224 fprintf (dump_file, " to be replaced with debug statements.\n");
2228 if (covered_to < limit)
2229 hole = true;
2230 if (scalar)
2231 root->grp_total_scalarization = 0;
2234 if (sth_created
2235 && (!hole || root->grp_total_scalarization))
2237 root->grp_covered = 1;
2238 return true;
2240 if (root->grp_write || TREE_CODE (root->base) == PARM_DECL)
2241 root->grp_unscalarized_data = 1; /* not covered and written to */
2242 if (sth_created)
2243 return true;
2244 return false;
2247 /* Analyze all access trees linked by next_grp by the means of
2248 analyze_access_subtree. */
2249 static bool
2250 analyze_access_trees (struct access *access)
2252 bool ret = false;
2254 while (access)
2256 if (analyze_access_subtree (access, NULL, true))
2257 ret = true;
2258 access = access->next_grp;
2261 return ret;
2264 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2265 SIZE would conflict with an already existing one. If exactly such a child
2266 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2268 static bool
2269 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
2270 HOST_WIDE_INT size, struct access **exact_match)
2272 struct access *child;
2274 for (child = lacc->first_child; child; child = child->next_sibling)
2276 if (child->offset == norm_offset && child->size == size)
2278 *exact_match = child;
2279 return true;
2282 if (child->offset < norm_offset + size
2283 && child->offset + child->size > norm_offset)
2284 return true;
2287 return false;
2290 /* Create a new child access of PARENT, with all properties just like MODEL
2291 except for its offset and with its grp_write false and grp_read true.
2292 Return the new access or NULL if it cannot be created. Note that this access
2293 is created long after all splicing and sorting, it's not located in any
2294 access vector and is automatically a representative of its group. */
2296 static struct access *
2297 create_artificial_child_access (struct access *parent, struct access *model,
2298 HOST_WIDE_INT new_offset)
2300 struct access *access;
2301 struct access **child;
2302 tree expr = parent->base;
2304 gcc_assert (!model->grp_unscalarizable_region);
2306 access = (struct access *) pool_alloc (access_pool);
2307 memset (access, 0, sizeof (struct access));
2308 if (!build_user_friendly_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
2309 model->type))
2311 access->grp_no_warning = true;
2312 expr = build_ref_for_model (EXPR_LOCATION (parent->base), parent->base,
2313 new_offset, model, NULL, false);
2316 access->base = parent->base;
2317 access->expr = expr;
2318 access->offset = new_offset;
2319 access->size = model->size;
2320 access->type = model->type;
2321 access->grp_write = true;
2322 access->grp_read = false;
2324 child = &parent->first_child;
2325 while (*child && (*child)->offset < new_offset)
2326 child = &(*child)->next_sibling;
2328 access->next_sibling = *child;
2329 *child = access;
2331 return access;
2335 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
2336 true if any new subaccess was created. Additionally, if RACC is a scalar
2337 access but LACC is not, change the type of the latter, if possible. */
2339 static bool
2340 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
2342 struct access *rchild;
2343 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
2344 bool ret = false;
2346 if (is_gimple_reg_type (lacc->type)
2347 || lacc->grp_unscalarizable_region
2348 || racc->grp_unscalarizable_region)
2349 return false;
2351 if (is_gimple_reg_type (racc->type))
2353 if (!lacc->first_child && !racc->first_child)
2355 tree t = lacc->base;
2357 lacc->type = racc->type;
2358 if (build_user_friendly_ref_for_offset (&t, TREE_TYPE (t),
2359 lacc->offset, racc->type))
2360 lacc->expr = t;
2361 else
2363 lacc->expr = build_ref_for_model (EXPR_LOCATION (lacc->base),
2364 lacc->base, lacc->offset,
2365 racc, NULL, false);
2366 lacc->grp_no_warning = true;
2369 return false;
2372 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
2374 struct access *new_acc = NULL;
2375 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
2377 if (rchild->grp_unscalarizable_region)
2378 continue;
2380 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
2381 &new_acc))
2383 if (new_acc)
2385 rchild->grp_hint = 1;
2386 new_acc->grp_hint |= new_acc->grp_read;
2387 if (rchild->first_child)
2388 ret |= propagate_subaccesses_across_link (new_acc, rchild);
2390 continue;
2393 rchild->grp_hint = 1;
2394 new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
2395 if (new_acc)
2397 ret = true;
2398 if (racc->first_child)
2399 propagate_subaccesses_across_link (new_acc, rchild);
2403 return ret;
2406 /* Propagate all subaccesses across assignment links. */
2408 static void
2409 propagate_all_subaccesses (void)
2411 while (work_queue_head)
2413 struct access *racc = pop_access_from_work_queue ();
2414 struct assign_link *link;
2416 gcc_assert (racc->first_link);
2418 for (link = racc->first_link; link; link = link->next)
2420 struct access *lacc = link->lacc;
2422 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
2423 continue;
2424 lacc = lacc->group_representative;
2425 if (propagate_subaccesses_across_link (lacc, racc)
2426 && lacc->first_link)
2427 add_access_to_work_queue (lacc);
2432 /* Go through all accesses collected throughout the (intraprocedural) analysis
2433 stage, exclude overlapping ones, identify representatives and build trees
2434 out of them, making decisions about scalarization on the way. Return true
2435 iff there are any to-be-scalarized variables after this stage. */
2437 static bool
2438 analyze_all_variable_accesses (void)
2440 int res = 0;
2441 bitmap tmp = BITMAP_ALLOC (NULL);
2442 bitmap_iterator bi;
2443 unsigned i, max_total_scalarization_size;
2445 max_total_scalarization_size = UNITS_PER_WORD * BITS_PER_UNIT
2446 * MOVE_RATIO (optimize_function_for_speed_p (cfun));
2448 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
2449 if (bitmap_bit_p (should_scalarize_away_bitmap, i)
2450 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
2452 tree var = candidate (i);
2454 if (TREE_CODE (var) == VAR_DECL
2455 && type_consists_of_records_p (TREE_TYPE (var)))
2457 if ((unsigned) tree_low_cst (TYPE_SIZE (TREE_TYPE (var)), 1)
2458 <= max_total_scalarization_size)
2460 completely_scalarize_var (var);
2461 if (dump_file && (dump_flags & TDF_DETAILS))
2463 fprintf (dump_file, "Will attempt to totally scalarize ");
2464 print_generic_expr (dump_file, var, 0);
2465 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2468 else if (dump_file && (dump_flags & TDF_DETAILS))
2470 fprintf (dump_file, "Too big to totally scalarize: ");
2471 print_generic_expr (dump_file, var, 0);
2472 fprintf (dump_file, " (UID: %u)\n", DECL_UID (var));
2477 bitmap_copy (tmp, candidate_bitmap);
2478 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2480 tree var = candidate (i);
2481 struct access *access;
2483 access = sort_and_splice_var_accesses (var);
2484 if (!access || !build_access_trees (access))
2485 disqualify_candidate (var,
2486 "No or inhibitingly overlapping accesses.");
2489 propagate_all_subaccesses ();
2491 bitmap_copy (tmp, candidate_bitmap);
2492 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2494 tree var = candidate (i);
2495 struct access *access = get_first_repr_for_decl (var);
2497 if (analyze_access_trees (access))
2499 res++;
2500 if (dump_file && (dump_flags & TDF_DETAILS))
2502 fprintf (dump_file, "\nAccess trees for ");
2503 print_generic_expr (dump_file, var, 0);
2504 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2505 dump_access_tree (dump_file, access);
2506 fprintf (dump_file, "\n");
2509 else
2510 disqualify_candidate (var, "No scalar replacements to be created.");
2513 BITMAP_FREE (tmp);
2515 if (res)
2517 statistics_counter_event (cfun, "Scalarized aggregates", res);
2518 return true;
2520 else
2521 return false;
2524 /* Generate statements copying scalar replacements of accesses within a subtree
2525 into or out of AGG. ACCESS, all its children, siblings and their children
2526 are to be processed. AGG is an aggregate type expression (can be a
2527 declaration but does not have to be, it can for example also be a mem_ref or
2528 a series of handled components). TOP_OFFSET is the offset of the processed
2529 subtree which has to be subtracted from offsets of individual accesses to
2530 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2531 replacements in the interval <start_offset, start_offset + chunk_size>,
2532 otherwise copy all. GSI is a statement iterator used to place the new
2533 statements. WRITE should be true when the statements should write from AGG
2534 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2535 statements will be added after the current statement in GSI, they will be
2536 added before the statement otherwise. */
2538 static void
2539 generate_subtree_copies (struct access *access, tree agg,
2540 HOST_WIDE_INT top_offset,
2541 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
2542 gimple_stmt_iterator *gsi, bool write,
2543 bool insert_after, location_t loc)
2547 if (chunk_size && access->offset >= start_offset + chunk_size)
2548 return;
2550 if (access->grp_to_be_replaced
2551 && (chunk_size == 0
2552 || access->offset + access->size > start_offset))
2554 tree expr, repl = get_access_replacement (access);
2555 gimple stmt;
2557 expr = build_ref_for_model (loc, agg, access->offset - top_offset,
2558 access, gsi, insert_after);
2560 if (write)
2562 if (access->grp_partial_lhs)
2563 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
2564 !insert_after,
2565 insert_after ? GSI_NEW_STMT
2566 : GSI_SAME_STMT);
2567 stmt = gimple_build_assign (repl, expr);
2569 else
2571 TREE_NO_WARNING (repl) = 1;
2572 if (access->grp_partial_lhs)
2573 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2574 !insert_after,
2575 insert_after ? GSI_NEW_STMT
2576 : GSI_SAME_STMT);
2577 stmt = gimple_build_assign (expr, repl);
2579 gimple_set_location (stmt, loc);
2581 if (insert_after)
2582 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2583 else
2584 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2585 update_stmt (stmt);
2586 sra_stats.subtree_copies++;
2588 else if (write
2589 && access->grp_to_be_debug_replaced
2590 && (chunk_size == 0
2591 || access->offset + access->size > start_offset))
2593 gimple ds;
2594 tree drhs = build_debug_ref_for_model (loc, agg,
2595 access->offset - top_offset,
2596 access);
2597 ds = gimple_build_debug_bind (get_access_replacement (access),
2598 drhs, gsi_stmt (*gsi));
2599 if (insert_after)
2600 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2601 else
2602 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2605 if (access->first_child)
2606 generate_subtree_copies (access->first_child, agg, top_offset,
2607 start_offset, chunk_size, gsi,
2608 write, insert_after, loc);
2610 access = access->next_sibling;
2612 while (access);
2615 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2616 the root of the subtree to be processed. GSI is the statement iterator used
2617 for inserting statements which are added after the current statement if
2618 INSERT_AFTER is true or before it otherwise. */
2620 static void
2621 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
2622 bool insert_after, location_t loc)
2625 struct access *child;
2627 if (access->grp_to_be_replaced)
2629 gimple stmt;
2631 stmt = gimple_build_assign (get_access_replacement (access),
2632 build_zero_cst (access->type));
2633 if (insert_after)
2634 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2635 else
2636 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2637 update_stmt (stmt);
2638 gimple_set_location (stmt, loc);
2640 else if (access->grp_to_be_debug_replaced)
2642 gimple ds = gimple_build_debug_bind (get_access_replacement (access),
2643 build_zero_cst (access->type),
2644 gsi_stmt (*gsi));
2645 if (insert_after)
2646 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2647 else
2648 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2651 for (child = access->first_child; child; child = child->next_sibling)
2652 init_subtree_with_zero (child, gsi, insert_after, loc);
2655 /* Search for an access representative for the given expression EXPR and
2656 return it or NULL if it cannot be found. */
2658 static struct access *
2659 get_access_for_expr (tree expr)
2661 HOST_WIDE_INT offset, size, max_size;
2662 tree base;
2664 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2665 a different size than the size of its argument and we need the latter
2666 one. */
2667 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
2668 expr = TREE_OPERAND (expr, 0);
2670 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
2671 if (max_size == -1 || !DECL_P (base))
2672 return NULL;
2674 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
2675 return NULL;
2677 return get_var_base_offset_size_access (base, offset, max_size);
2680 /* Replace the expression EXPR with a scalar replacement if there is one and
2681 generate other statements to do type conversion or subtree copying if
2682 necessary. GSI is used to place newly created statements, WRITE is true if
2683 the expression is being written to (it is on a LHS of a statement or output
2684 in an assembly statement). */
2686 static bool
2687 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
2689 location_t loc;
2690 struct access *access;
2691 tree type, bfr;
2693 if (TREE_CODE (*expr) == BIT_FIELD_REF)
2695 bfr = *expr;
2696 expr = &TREE_OPERAND (*expr, 0);
2698 else
2699 bfr = NULL_TREE;
2701 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
2702 expr = &TREE_OPERAND (*expr, 0);
2703 access = get_access_for_expr (*expr);
2704 if (!access)
2705 return false;
2706 type = TREE_TYPE (*expr);
2708 loc = gimple_location (gsi_stmt (*gsi));
2709 if (access->grp_to_be_replaced)
2711 tree repl = get_access_replacement (access);
2712 /* If we replace a non-register typed access simply use the original
2713 access expression to extract the scalar component afterwards.
2714 This happens if scalarizing a function return value or parameter
2715 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2716 gcc.c-torture/compile/20011217-1.c.
2718 We also want to use this when accessing a complex or vector which can
2719 be accessed as a different type too, potentially creating a need for
2720 type conversion (see PR42196) and when scalarized unions are involved
2721 in assembler statements (see PR42398). */
2722 if (!useless_type_conversion_p (type, access->type))
2724 tree ref;
2726 ref = build_ref_for_model (loc, access->base, access->offset, access,
2727 NULL, false);
2729 if (write)
2731 gimple stmt;
2733 if (access->grp_partial_lhs)
2734 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
2735 false, GSI_NEW_STMT);
2736 stmt = gimple_build_assign (repl, ref);
2737 gimple_set_location (stmt, loc);
2738 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2740 else
2742 gimple stmt;
2744 if (access->grp_partial_lhs)
2745 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2746 true, GSI_SAME_STMT);
2747 stmt = gimple_build_assign (ref, repl);
2748 gimple_set_location (stmt, loc);
2749 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2752 else
2753 *expr = repl;
2754 sra_stats.exprs++;
2756 else if (write && access->grp_to_be_debug_replaced)
2758 gimple ds = gimple_build_debug_bind (get_access_replacement (access),
2759 NULL_TREE,
2760 gsi_stmt (*gsi));
2761 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2764 if (access->first_child)
2766 HOST_WIDE_INT start_offset, chunk_size;
2767 if (bfr
2768 && host_integerp (TREE_OPERAND (bfr, 1), 1)
2769 && host_integerp (TREE_OPERAND (bfr, 2), 1))
2771 chunk_size = tree_low_cst (TREE_OPERAND (bfr, 1), 1);
2772 start_offset = access->offset
2773 + tree_low_cst (TREE_OPERAND (bfr, 2), 1);
2775 else
2776 start_offset = chunk_size = 0;
2778 generate_subtree_copies (access->first_child, access->base, 0,
2779 start_offset, chunk_size, gsi, write, write,
2780 loc);
2782 return true;
2785 /* Where scalar replacements of the RHS have been written to when a replacement
2786 of a LHS of an assigments cannot be direclty loaded from a replacement of
2787 the RHS. */
2788 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
2789 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
2790 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
2792 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2793 base aggregate if there are unscalarized data or directly to LHS of the
2794 statement that is pointed to by GSI otherwise. */
2796 static enum unscalarized_data_handling
2797 handle_unscalarized_data_in_subtree (struct access *top_racc,
2798 gimple_stmt_iterator *gsi)
2800 if (top_racc->grp_unscalarized_data)
2802 generate_subtree_copies (top_racc->first_child, top_racc->base, 0, 0, 0,
2803 gsi, false, false,
2804 gimple_location (gsi_stmt (*gsi)));
2805 return SRA_UDH_RIGHT;
2807 else
2809 tree lhs = gimple_assign_lhs (gsi_stmt (*gsi));
2810 generate_subtree_copies (top_racc->first_child, lhs, top_racc->offset,
2811 0, 0, gsi, false, false,
2812 gimple_location (gsi_stmt (*gsi)));
2813 return SRA_UDH_LEFT;
2818 /* Try to generate statements to load all sub-replacements in an access subtree
2819 formed by children of LACC from scalar replacements in the TOP_RACC subtree.
2820 If that is not possible, refresh the TOP_RACC base aggregate and load the
2821 accesses from it. LEFT_OFFSET is the offset of the left whole subtree being
2822 copied. NEW_GSI is stmt iterator used for statement insertions after the
2823 original assignment, OLD_GSI is used to insert statements before the
2824 assignment. *REFRESHED keeps the information whether we have needed to
2825 refresh replacements of the LHS and from which side of the assignments this
2826 takes place. */
2828 static void
2829 load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
2830 HOST_WIDE_INT left_offset,
2831 gimple_stmt_iterator *old_gsi,
2832 gimple_stmt_iterator *new_gsi,
2833 enum unscalarized_data_handling *refreshed)
2835 location_t loc = gimple_location (gsi_stmt (*old_gsi));
2836 for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling)
2838 HOST_WIDE_INT offset = lacc->offset - left_offset + top_racc->offset;
2840 if (lacc->grp_to_be_replaced)
2842 struct access *racc;
2843 gimple stmt;
2844 tree rhs;
2846 racc = find_access_in_subtree (top_racc, offset, lacc->size);
2847 if (racc && racc->grp_to_be_replaced)
2849 rhs = get_access_replacement (racc);
2850 if (!useless_type_conversion_p (lacc->type, racc->type))
2851 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, lacc->type, rhs);
2853 if (racc->grp_partial_lhs && lacc->grp_partial_lhs)
2854 rhs = force_gimple_operand_gsi (old_gsi, rhs, true, NULL_TREE,
2855 true, GSI_SAME_STMT);
2857 else
2859 /* No suitable access on the right hand side, need to load from
2860 the aggregate. See if we have to update it first... */
2861 if (*refreshed == SRA_UDH_NONE)
2862 *refreshed = handle_unscalarized_data_in_subtree (top_racc,
2863 old_gsi);
2865 if (*refreshed == SRA_UDH_LEFT)
2866 rhs = build_ref_for_model (loc, lacc->base, lacc->offset, lacc,
2867 new_gsi, true);
2868 else
2869 rhs = build_ref_for_model (loc, top_racc->base, offset, lacc,
2870 new_gsi, true);
2871 if (lacc->grp_partial_lhs)
2872 rhs = force_gimple_operand_gsi (new_gsi, rhs, true, NULL_TREE,
2873 false, GSI_NEW_STMT);
2876 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
2877 gsi_insert_after (new_gsi, stmt, GSI_NEW_STMT);
2878 gimple_set_location (stmt, loc);
2879 update_stmt (stmt);
2880 sra_stats.subreplacements++;
2882 else
2884 if (*refreshed == SRA_UDH_NONE
2885 && lacc->grp_read && !lacc->grp_covered)
2886 *refreshed = handle_unscalarized_data_in_subtree (top_racc,
2887 old_gsi);
2888 if (lacc && lacc->grp_to_be_debug_replaced)
2890 gimple ds;
2891 tree drhs;
2892 struct access *racc = find_access_in_subtree (top_racc, offset,
2893 lacc->size);
2895 if (racc && racc->grp_to_be_replaced)
2896 drhs = get_access_replacement (racc);
2897 else if (*refreshed == SRA_UDH_LEFT)
2898 drhs = build_debug_ref_for_model (loc, lacc->base, lacc->offset,
2899 lacc);
2900 else if (*refreshed == SRA_UDH_RIGHT)
2901 drhs = build_debug_ref_for_model (loc, top_racc->base, offset,
2902 lacc);
2903 else
2904 drhs = NULL_TREE;
2905 ds = gimple_build_debug_bind (get_access_replacement (lacc),
2906 drhs, gsi_stmt (*old_gsi));
2907 gsi_insert_after (new_gsi, ds, GSI_NEW_STMT);
2911 if (lacc->first_child)
2912 load_assign_lhs_subreplacements (lacc, top_racc, left_offset,
2913 old_gsi, new_gsi, refreshed);
2917 /* Result code for SRA assignment modification. */
2918 enum assignment_mod_result { SRA_AM_NONE, /* nothing done for the stmt */
2919 SRA_AM_MODIFIED, /* stmt changed but not
2920 removed */
2921 SRA_AM_REMOVED }; /* stmt eliminated */
2923 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
2924 to the assignment and GSI is the statement iterator pointing at it. Returns
2925 the same values as sra_modify_assign. */
2927 static enum assignment_mod_result
2928 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
2930 tree lhs = gimple_assign_lhs (*stmt);
2931 struct access *acc;
2932 location_t loc;
2934 acc = get_access_for_expr (lhs);
2935 if (!acc)
2936 return SRA_AM_NONE;
2938 if (gimple_clobber_p (*stmt))
2940 /* Remove clobbers of fully scalarized variables, otherwise
2941 do nothing. */
2942 if (acc->grp_covered)
2944 unlink_stmt_vdef (*stmt);
2945 gsi_remove (gsi, true);
2946 release_defs (*stmt);
2947 return SRA_AM_REMOVED;
2949 else
2950 return SRA_AM_NONE;
2953 loc = gimple_location (*stmt);
2954 if (VEC_length (constructor_elt,
2955 CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt))) > 0)
2957 /* I have never seen this code path trigger but if it can happen the
2958 following should handle it gracefully. */
2959 if (access_has_children_p (acc))
2960 generate_subtree_copies (acc->first_child, acc->base, 0, 0, 0, gsi,
2961 true, true, loc);
2962 return SRA_AM_MODIFIED;
2965 if (acc->grp_covered)
2967 init_subtree_with_zero (acc, gsi, false, loc);
2968 unlink_stmt_vdef (*stmt);
2969 gsi_remove (gsi, true);
2970 release_defs (*stmt);
2971 return SRA_AM_REMOVED;
2973 else
2975 init_subtree_with_zero (acc, gsi, true, loc);
2976 return SRA_AM_MODIFIED;
2980 /* Create and return a new suitable default definition SSA_NAME for RACC which
2981 is an access describing an uninitialized part of an aggregate that is being
2982 loaded. */
2984 static tree
2985 get_repl_default_def_ssa_name (struct access *racc)
2987 return get_or_create_ssa_default_def (cfun, get_access_replacement (racc));
2990 /* Return true if REF has a COMPONENT_REF with a bit-field field declaration
2991 somewhere in it. */
2993 static inline bool
2994 contains_bitfld_comp_ref_p (const_tree ref)
2996 while (handled_component_p (ref))
2998 if (TREE_CODE (ref) == COMPONENT_REF
2999 && DECL_BIT_FIELD (TREE_OPERAND (ref, 1)))
3000 return true;
3001 ref = TREE_OPERAND (ref, 0);
3004 return false;
3007 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3008 bit-field field declaration somewhere in it. */
3010 static inline bool
3011 contains_vce_or_bfcref_p (const_tree ref)
3013 while (handled_component_p (ref))
3015 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
3016 || (TREE_CODE (ref) == COMPONENT_REF
3017 && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
3018 return true;
3019 ref = TREE_OPERAND (ref, 0);
3022 return false;
3025 /* Examine both sides of the assignment statement pointed to by STMT, replace
3026 them with a scalare replacement if there is one and generate copying of
3027 replacements if scalarized aggregates have been used in the assignment. GSI
3028 is used to hold generated statements for type conversions and subtree
3029 copying. */
3031 static enum assignment_mod_result
3032 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3034 struct access *lacc, *racc;
3035 tree lhs, rhs;
3036 bool modify_this_stmt = false;
3037 bool force_gimple_rhs = false;
3038 location_t loc;
3039 gimple_stmt_iterator orig_gsi = *gsi;
3041 if (!gimple_assign_single_p (*stmt))
3042 return SRA_AM_NONE;
3043 lhs = gimple_assign_lhs (*stmt);
3044 rhs = gimple_assign_rhs1 (*stmt);
3046 if (TREE_CODE (rhs) == CONSTRUCTOR)
3047 return sra_modify_constructor_assign (stmt, gsi);
3049 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
3050 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
3051 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
3053 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (*stmt),
3054 gsi, false);
3055 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (*stmt),
3056 gsi, true);
3057 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3060 lacc = get_access_for_expr (lhs);
3061 racc = get_access_for_expr (rhs);
3062 if (!lacc && !racc)
3063 return SRA_AM_NONE;
3065 loc = gimple_location (*stmt);
3066 if (lacc && lacc->grp_to_be_replaced)
3068 lhs = get_access_replacement (lacc);
3069 gimple_assign_set_lhs (*stmt, lhs);
3070 modify_this_stmt = true;
3071 if (lacc->grp_partial_lhs)
3072 force_gimple_rhs = true;
3073 sra_stats.exprs++;
3076 if (racc && racc->grp_to_be_replaced)
3078 rhs = get_access_replacement (racc);
3079 modify_this_stmt = true;
3080 if (racc->grp_partial_lhs)
3081 force_gimple_rhs = true;
3082 sra_stats.exprs++;
3084 else if (racc
3085 && !racc->grp_unscalarized_data
3086 && TREE_CODE (lhs) == SSA_NAME
3087 && !access_has_replacements_p (racc))
3089 rhs = get_repl_default_def_ssa_name (racc);
3090 modify_this_stmt = true;
3091 sra_stats.exprs++;
3094 if (modify_this_stmt)
3096 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3098 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3099 ??? This should move to fold_stmt which we simply should
3100 call after building a VIEW_CONVERT_EXPR here. */
3101 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
3102 && !contains_bitfld_comp_ref_p (lhs)
3103 && !access_has_children_p (lacc))
3105 lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
3106 gimple_assign_set_lhs (*stmt, lhs);
3108 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
3109 && !contains_vce_or_bfcref_p (rhs)
3110 && !access_has_children_p (racc))
3111 rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
3113 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3115 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
3116 rhs);
3117 if (is_gimple_reg_type (TREE_TYPE (lhs))
3118 && TREE_CODE (lhs) != SSA_NAME)
3119 force_gimple_rhs = true;
3124 if (lacc && lacc->grp_to_be_debug_replaced)
3126 gimple ds = gimple_build_debug_bind (get_access_replacement (lacc),
3127 unshare_expr (rhs), *stmt);
3128 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3131 /* From this point on, the function deals with assignments in between
3132 aggregates when at least one has scalar reductions of some of its
3133 components. There are three possible scenarios: Both the LHS and RHS have
3134 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3136 In the first case, we would like to load the LHS components from RHS
3137 components whenever possible. If that is not possible, we would like to
3138 read it directly from the RHS (after updating it by storing in it its own
3139 components). If there are some necessary unscalarized data in the LHS,
3140 those will be loaded by the original assignment too. If neither of these
3141 cases happen, the original statement can be removed. Most of this is done
3142 by load_assign_lhs_subreplacements.
3144 In the second case, we would like to store all RHS scalarized components
3145 directly into LHS and if they cover the aggregate completely, remove the
3146 statement too. In the third case, we want the LHS components to be loaded
3147 directly from the RHS (DSE will remove the original statement if it
3148 becomes redundant).
3150 This is a bit complex but manageable when types match and when unions do
3151 not cause confusion in a way that we cannot really load a component of LHS
3152 from the RHS or vice versa (the access representing this level can have
3153 subaccesses that are accessible only through a different union field at a
3154 higher level - different from the one used in the examined expression).
3155 Unions are fun.
3157 Therefore, I specially handle a fourth case, happening when there is a
3158 specific type cast or it is impossible to locate a scalarized subaccess on
3159 the other side of the expression. If that happens, I simply "refresh" the
3160 RHS by storing in it is scalarized components leave the original statement
3161 there to do the copying and then load the scalar replacements of the LHS.
3162 This is what the first branch does. */
3164 if (modify_this_stmt
3165 || gimple_has_volatile_ops (*stmt)
3166 || contains_vce_or_bfcref_p (rhs)
3167 || contains_vce_or_bfcref_p (lhs))
3169 if (access_has_children_p (racc))
3170 generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
3171 gsi, false, false, loc);
3172 if (access_has_children_p (lacc))
3173 generate_subtree_copies (lacc->first_child, lacc->base, 0, 0, 0,
3174 gsi, true, true, loc);
3175 sra_stats.separate_lhs_rhs_handling++;
3177 /* This gimplification must be done after generate_subtree_copies,
3178 lest we insert the subtree copies in the middle of the gimplified
3179 sequence. */
3180 if (force_gimple_rhs)
3181 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
3182 true, GSI_SAME_STMT);
3183 if (gimple_assign_rhs1 (*stmt) != rhs)
3185 modify_this_stmt = true;
3186 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
3187 gcc_assert (*stmt == gsi_stmt (orig_gsi));
3190 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3192 else
3194 if (access_has_children_p (lacc)
3195 && access_has_children_p (racc)
3196 /* When an access represents an unscalarizable region, it usually
3197 represents accesses with variable offset and thus must not be used
3198 to generate new memory accesses. */
3199 && !lacc->grp_unscalarizable_region
3200 && !racc->grp_unscalarizable_region)
3202 gimple_stmt_iterator orig_gsi = *gsi;
3203 enum unscalarized_data_handling refreshed;
3205 if (lacc->grp_read && !lacc->grp_covered)
3206 refreshed = handle_unscalarized_data_in_subtree (racc, gsi);
3207 else
3208 refreshed = SRA_UDH_NONE;
3210 load_assign_lhs_subreplacements (lacc, racc, lacc->offset,
3211 &orig_gsi, gsi, &refreshed);
3212 if (refreshed != SRA_UDH_RIGHT)
3214 gsi_next (gsi);
3215 unlink_stmt_vdef (*stmt);
3216 gsi_remove (&orig_gsi, true);
3217 release_defs (*stmt);
3218 sra_stats.deleted++;
3219 return SRA_AM_REMOVED;
3222 else
3224 if (access_has_children_p (racc)
3225 && !racc->grp_unscalarized_data)
3227 if (dump_file)
3229 fprintf (dump_file, "Removing load: ");
3230 print_gimple_stmt (dump_file, *stmt, 0, 0);
3232 generate_subtree_copies (racc->first_child, lhs,
3233 racc->offset, 0, 0, gsi,
3234 false, false, loc);
3235 gcc_assert (*stmt == gsi_stmt (*gsi));
3236 unlink_stmt_vdef (*stmt);
3237 gsi_remove (gsi, true);
3238 release_defs (*stmt);
3239 sra_stats.deleted++;
3240 return SRA_AM_REMOVED;
3242 /* Restore the aggregate RHS from its components so the
3243 prevailing aggregate copy does the right thing. */
3244 if (access_has_children_p (racc))
3245 generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
3246 gsi, false, false, loc);
3247 /* Re-load the components of the aggregate copy destination.
3248 But use the RHS aggregate to load from to expose more
3249 optimization opportunities. */
3250 if (access_has_children_p (lacc))
3251 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
3252 0, 0, gsi, true, true, loc);
3255 return SRA_AM_NONE;
3259 /* Traverse the function body and all modifications as decided in
3260 analyze_all_variable_accesses. Return true iff the CFG has been
3261 changed. */
3263 static bool
3264 sra_modify_function_body (void)
3266 bool cfg_changed = false;
3267 basic_block bb;
3269 FOR_EACH_BB (bb)
3271 gimple_stmt_iterator gsi = gsi_start_bb (bb);
3272 while (!gsi_end_p (gsi))
3274 gimple stmt = gsi_stmt (gsi);
3275 enum assignment_mod_result assign_result;
3276 bool modified = false, deleted = false;
3277 tree *t;
3278 unsigned i;
3280 switch (gimple_code (stmt))
3282 case GIMPLE_RETURN:
3283 t = gimple_return_retval_ptr (stmt);
3284 if (*t != NULL_TREE)
3285 modified |= sra_modify_expr (t, &gsi, false);
3286 break;
3288 case GIMPLE_ASSIGN:
3289 assign_result = sra_modify_assign (&stmt, &gsi);
3290 modified |= assign_result == SRA_AM_MODIFIED;
3291 deleted = assign_result == SRA_AM_REMOVED;
3292 break;
3294 case GIMPLE_CALL:
3295 /* Operands must be processed before the lhs. */
3296 for (i = 0; i < gimple_call_num_args (stmt); i++)
3298 t = gimple_call_arg_ptr (stmt, i);
3299 modified |= sra_modify_expr (t, &gsi, false);
3302 if (gimple_call_lhs (stmt))
3304 t = gimple_call_lhs_ptr (stmt);
3305 modified |= sra_modify_expr (t, &gsi, true);
3307 break;
3309 case GIMPLE_ASM:
3310 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
3312 t = &TREE_VALUE (gimple_asm_input_op (stmt, i));
3313 modified |= sra_modify_expr (t, &gsi, false);
3315 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
3317 t = &TREE_VALUE (gimple_asm_output_op (stmt, i));
3318 modified |= sra_modify_expr (t, &gsi, true);
3320 break;
3322 default:
3323 break;
3326 if (modified)
3328 update_stmt (stmt);
3329 if (maybe_clean_eh_stmt (stmt)
3330 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
3331 cfg_changed = true;
3333 if (!deleted)
3334 gsi_next (&gsi);
3338 return cfg_changed;
3341 /* Generate statements initializing scalar replacements of parts of function
3342 parameters. */
3344 static void
3345 initialize_parameter_reductions (void)
3347 gimple_stmt_iterator gsi;
3348 gimple_seq seq = NULL;
3349 tree parm;
3351 gsi = gsi_start (seq);
3352 for (parm = DECL_ARGUMENTS (current_function_decl);
3353 parm;
3354 parm = DECL_CHAIN (parm))
3356 VEC (access_p, heap) *access_vec;
3357 struct access *access;
3359 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3360 continue;
3361 access_vec = get_base_access_vector (parm);
3362 if (!access_vec)
3363 continue;
3365 for (access = VEC_index (access_p, access_vec, 0);
3366 access;
3367 access = access->next_grp)
3368 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true,
3369 EXPR_LOCATION (parm));
3372 seq = gsi_seq (gsi);
3373 if (seq)
3374 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR), seq);
3377 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3378 it reveals there are components of some aggregates to be scalarized, it runs
3379 the required transformations. */
3380 static unsigned int
3381 perform_intra_sra (void)
3383 int ret = 0;
3384 sra_initialize ();
3386 if (!find_var_candidates ())
3387 goto out;
3389 if (!scan_function ())
3390 goto out;
3392 if (!analyze_all_variable_accesses ())
3393 goto out;
3395 if (sra_modify_function_body ())
3396 ret = TODO_update_ssa | TODO_cleanup_cfg;
3397 else
3398 ret = TODO_update_ssa;
3399 initialize_parameter_reductions ();
3401 statistics_counter_event (cfun, "Scalar replacements created",
3402 sra_stats.replacements);
3403 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
3404 statistics_counter_event (cfun, "Subtree copy stmts",
3405 sra_stats.subtree_copies);
3406 statistics_counter_event (cfun, "Subreplacement stmts",
3407 sra_stats.subreplacements);
3408 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
3409 statistics_counter_event (cfun, "Separate LHS and RHS handling",
3410 sra_stats.separate_lhs_rhs_handling);
3412 out:
3413 sra_deinitialize ();
3414 return ret;
3417 /* Perform early intraprocedural SRA. */
3418 static unsigned int
3419 early_intra_sra (void)
3421 sra_mode = SRA_MODE_EARLY_INTRA;
3422 return perform_intra_sra ();
3425 /* Perform "late" intraprocedural SRA. */
3426 static unsigned int
3427 late_intra_sra (void)
3429 sra_mode = SRA_MODE_INTRA;
3430 return perform_intra_sra ();
3434 static bool
3435 gate_intra_sra (void)
3437 return flag_tree_sra != 0 && dbg_cnt (tree_sra);
3441 struct gimple_opt_pass pass_sra_early =
3444 GIMPLE_PASS,
3445 "esra", /* name */
3446 OPTGROUP_NONE, /* optinfo_flags */
3447 gate_intra_sra, /* gate */
3448 early_intra_sra, /* execute */
3449 NULL, /* sub */
3450 NULL, /* next */
3451 0, /* static_pass_number */
3452 TV_TREE_SRA, /* tv_id */
3453 PROP_cfg | PROP_ssa, /* properties_required */
3454 0, /* properties_provided */
3455 0, /* properties_destroyed */
3456 0, /* todo_flags_start */
3457 TODO_update_ssa
3458 | TODO_ggc_collect
3459 | TODO_verify_ssa /* todo_flags_finish */
3463 struct gimple_opt_pass pass_sra =
3466 GIMPLE_PASS,
3467 "sra", /* name */
3468 OPTGROUP_NONE, /* optinfo_flags */
3469 gate_intra_sra, /* gate */
3470 late_intra_sra, /* execute */
3471 NULL, /* sub */
3472 NULL, /* next */
3473 0, /* static_pass_number */
3474 TV_TREE_SRA, /* tv_id */
3475 PROP_cfg | PROP_ssa, /* properties_required */
3476 0, /* properties_provided */
3477 0, /* properties_destroyed */
3478 TODO_update_address_taken, /* todo_flags_start */
3479 TODO_update_ssa
3480 | TODO_ggc_collect
3481 | TODO_verify_ssa /* todo_flags_finish */
3486 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3487 parameter. */
3489 static bool
3490 is_unused_scalar_param (tree parm)
3492 tree name;
3493 return (is_gimple_reg (parm)
3494 && (!(name = ssa_default_def (cfun, parm))
3495 || has_zero_uses (name)));
3498 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3499 examine whether there are any direct or otherwise infeasible ones. If so,
3500 return true, otherwise return false. PARM must be a gimple register with a
3501 non-NULL default definition. */
3503 static bool
3504 ptr_parm_has_direct_uses (tree parm)
3506 imm_use_iterator ui;
3507 gimple stmt;
3508 tree name = ssa_default_def (cfun, parm);
3509 bool ret = false;
3511 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
3513 int uses_ok = 0;
3514 use_operand_p use_p;
3516 if (is_gimple_debug (stmt))
3517 continue;
3519 /* Valid uses include dereferences on the lhs and the rhs. */
3520 if (gimple_has_lhs (stmt))
3522 tree lhs = gimple_get_lhs (stmt);
3523 while (handled_component_p (lhs))
3524 lhs = TREE_OPERAND (lhs, 0);
3525 if (TREE_CODE (lhs) == MEM_REF
3526 && TREE_OPERAND (lhs, 0) == name
3527 && integer_zerop (TREE_OPERAND (lhs, 1))
3528 && types_compatible_p (TREE_TYPE (lhs),
3529 TREE_TYPE (TREE_TYPE (name)))
3530 && !TREE_THIS_VOLATILE (lhs))
3531 uses_ok++;
3533 if (gimple_assign_single_p (stmt))
3535 tree rhs = gimple_assign_rhs1 (stmt);
3536 while (handled_component_p (rhs))
3537 rhs = TREE_OPERAND (rhs, 0);
3538 if (TREE_CODE (rhs) == MEM_REF
3539 && TREE_OPERAND (rhs, 0) == name
3540 && integer_zerop (TREE_OPERAND (rhs, 1))
3541 && types_compatible_p (TREE_TYPE (rhs),
3542 TREE_TYPE (TREE_TYPE (name)))
3543 && !TREE_THIS_VOLATILE (rhs))
3544 uses_ok++;
3546 else if (is_gimple_call (stmt))
3548 unsigned i;
3549 for (i = 0; i < gimple_call_num_args (stmt); ++i)
3551 tree arg = gimple_call_arg (stmt, i);
3552 while (handled_component_p (arg))
3553 arg = TREE_OPERAND (arg, 0);
3554 if (TREE_CODE (arg) == MEM_REF
3555 && TREE_OPERAND (arg, 0) == name
3556 && integer_zerop (TREE_OPERAND (arg, 1))
3557 && types_compatible_p (TREE_TYPE (arg),
3558 TREE_TYPE (TREE_TYPE (name)))
3559 && !TREE_THIS_VOLATILE (arg))
3560 uses_ok++;
3564 /* If the number of valid uses does not match the number of
3565 uses in this stmt there is an unhandled use. */
3566 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
3567 --uses_ok;
3569 if (uses_ok != 0)
3570 ret = true;
3572 if (ret)
3573 BREAK_FROM_IMM_USE_STMT (ui);
3576 return ret;
3579 /* Identify candidates for reduction for IPA-SRA based on their type and mark
3580 them in candidate_bitmap. Note that these do not necessarily include
3581 parameter which are unused and thus can be removed. Return true iff any
3582 such candidate has been found. */
3584 static bool
3585 find_param_candidates (void)
3587 tree parm;
3588 int count = 0;
3589 bool ret = false;
3590 const char *msg;
3592 for (parm = DECL_ARGUMENTS (current_function_decl);
3593 parm;
3594 parm = DECL_CHAIN (parm))
3596 tree type = TREE_TYPE (parm);
3597 void **slot;
3599 count++;
3601 if (TREE_THIS_VOLATILE (parm)
3602 || TREE_ADDRESSABLE (parm)
3603 || (!is_gimple_reg_type (type) && is_va_list_type (type)))
3604 continue;
3606 if (is_unused_scalar_param (parm))
3608 ret = true;
3609 continue;
3612 if (POINTER_TYPE_P (type))
3614 type = TREE_TYPE (type);
3616 if (TREE_CODE (type) == FUNCTION_TYPE
3617 || TYPE_VOLATILE (type)
3618 || (TREE_CODE (type) == ARRAY_TYPE
3619 && TYPE_NONALIASED_COMPONENT (type))
3620 || !is_gimple_reg (parm)
3621 || is_va_list_type (type)
3622 || ptr_parm_has_direct_uses (parm))
3623 continue;
3625 else if (!AGGREGATE_TYPE_P (type))
3626 continue;
3628 if (!COMPLETE_TYPE_P (type)
3629 || !host_integerp (TYPE_SIZE (type), 1)
3630 || tree_low_cst (TYPE_SIZE (type), 1) == 0
3631 || (AGGREGATE_TYPE_P (type)
3632 && type_internals_preclude_sra_p (type, &msg)))
3633 continue;
3635 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
3636 slot = htab_find_slot_with_hash (candidates, parm,
3637 DECL_UID (parm), INSERT);
3638 *slot = (void *) parm;
3640 ret = true;
3641 if (dump_file && (dump_flags & TDF_DETAILS))
3643 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
3644 print_generic_expr (dump_file, parm, 0);
3645 fprintf (dump_file, "\n");
3649 func_param_count = count;
3650 return ret;
3653 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
3654 maybe_modified. */
3656 static bool
3657 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
3658 void *data)
3660 struct access *repr = (struct access *) data;
3662 repr->grp_maybe_modified = 1;
3663 return true;
3666 /* Analyze what representatives (in linked lists accessible from
3667 REPRESENTATIVES) can be modified by side effects of statements in the
3668 current function. */
3670 static void
3671 analyze_modified_params (VEC (access_p, heap) *representatives)
3673 int i;
3675 for (i = 0; i < func_param_count; i++)
3677 struct access *repr;
3679 for (repr = VEC_index (access_p, representatives, i);
3680 repr;
3681 repr = repr->next_grp)
3683 struct access *access;
3684 bitmap visited;
3685 ao_ref ar;
3687 if (no_accesses_p (repr))
3688 continue;
3689 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
3690 || repr->grp_maybe_modified)
3691 continue;
3693 ao_ref_init (&ar, repr->expr);
3694 visited = BITMAP_ALLOC (NULL);
3695 for (access = repr; access; access = access->next_sibling)
3697 /* All accesses are read ones, otherwise grp_maybe_modified would
3698 be trivially set. */
3699 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
3700 mark_maybe_modified, repr, &visited);
3701 if (repr->grp_maybe_modified)
3702 break;
3704 BITMAP_FREE (visited);
3709 /* Propagate distances in bb_dereferences in the opposite direction than the
3710 control flow edges, in each step storing the maximum of the current value
3711 and the minimum of all successors. These steps are repeated until the table
3712 stabilizes. Note that BBs which might terminate the functions (according to
3713 final_bbs bitmap) never updated in this way. */
3715 static void
3716 propagate_dereference_distances (void)
3718 VEC (basic_block, heap) *queue;
3719 basic_block bb;
3721 queue = VEC_alloc (basic_block, heap, last_basic_block_for_function (cfun));
3722 VEC_quick_push (basic_block, queue, ENTRY_BLOCK_PTR);
3723 FOR_EACH_BB (bb)
3725 VEC_quick_push (basic_block, queue, bb);
3726 bb->aux = bb;
3729 while (!VEC_empty (basic_block, queue))
3731 edge_iterator ei;
3732 edge e;
3733 bool change = false;
3734 int i;
3736 bb = VEC_pop (basic_block, queue);
3737 bb->aux = NULL;
3739 if (bitmap_bit_p (final_bbs, bb->index))
3740 continue;
3742 for (i = 0; i < func_param_count; i++)
3744 int idx = bb->index * func_param_count + i;
3745 bool first = true;
3746 HOST_WIDE_INT inh = 0;
3748 FOR_EACH_EDGE (e, ei, bb->succs)
3750 int succ_idx = e->dest->index * func_param_count + i;
3752 if (e->src == EXIT_BLOCK_PTR)
3753 continue;
3755 if (first)
3757 first = false;
3758 inh = bb_dereferences [succ_idx];
3760 else if (bb_dereferences [succ_idx] < inh)
3761 inh = bb_dereferences [succ_idx];
3764 if (!first && bb_dereferences[idx] < inh)
3766 bb_dereferences[idx] = inh;
3767 change = true;
3771 if (change && !bitmap_bit_p (final_bbs, bb->index))
3772 FOR_EACH_EDGE (e, ei, bb->preds)
3774 if (e->src->aux)
3775 continue;
3777 e->src->aux = e->src;
3778 VEC_quick_push (basic_block, queue, e->src);
3782 VEC_free (basic_block, heap, queue);
3785 /* Dump a dereferences TABLE with heading STR to file F. */
3787 static void
3788 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
3790 basic_block bb;
3792 fprintf (dump_file, str);
3793 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
3795 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
3796 if (bb != EXIT_BLOCK_PTR)
3798 int i;
3799 for (i = 0; i < func_param_count; i++)
3801 int idx = bb->index * func_param_count + i;
3802 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
3805 fprintf (f, "\n");
3807 fprintf (dump_file, "\n");
3810 /* Determine what (parts of) parameters passed by reference that are not
3811 assigned to are not certainly dereferenced in this function and thus the
3812 dereferencing cannot be safely moved to the caller without potentially
3813 introducing a segfault. Mark such REPRESENTATIVES as
3814 grp_not_necessarilly_dereferenced.
3816 The dereferenced maximum "distance," i.e. the offset + size of the accessed
3817 part is calculated rather than simple booleans are calculated for each
3818 pointer parameter to handle cases when only a fraction of the whole
3819 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
3820 an example).
3822 The maximum dereference distances for each pointer parameter and BB are
3823 already stored in bb_dereference. This routine simply propagates these
3824 values upwards by propagate_dereference_distances and then compares the
3825 distances of individual parameters in the ENTRY BB to the equivalent
3826 distances of each representative of a (fraction of a) parameter. */
3828 static void
3829 analyze_caller_dereference_legality (VEC (access_p, heap) *representatives)
3831 int i;
3833 if (dump_file && (dump_flags & TDF_DETAILS))
3834 dump_dereferences_table (dump_file,
3835 "Dereference table before propagation:\n",
3836 bb_dereferences);
3838 propagate_dereference_distances ();
3840 if (dump_file && (dump_flags & TDF_DETAILS))
3841 dump_dereferences_table (dump_file,
3842 "Dereference table after propagation:\n",
3843 bb_dereferences);
3845 for (i = 0; i < func_param_count; i++)
3847 struct access *repr = VEC_index (access_p, representatives, i);
3848 int idx = ENTRY_BLOCK_PTR->index * func_param_count + i;
3850 if (!repr || no_accesses_p (repr))
3851 continue;
3855 if ((repr->offset + repr->size) > bb_dereferences[idx])
3856 repr->grp_not_necessarilly_dereferenced = 1;
3857 repr = repr->next_grp;
3859 while (repr);
3863 /* Return the representative access for the parameter declaration PARM if it is
3864 a scalar passed by reference which is not written to and the pointer value
3865 is not used directly. Thus, if it is legal to dereference it in the caller
3866 and we can rule out modifications through aliases, such parameter should be
3867 turned into one passed by value. Return NULL otherwise. */
3869 static struct access *
3870 unmodified_by_ref_scalar_representative (tree parm)
3872 int i, access_count;
3873 struct access *repr;
3874 VEC (access_p, heap) *access_vec;
3876 access_vec = get_base_access_vector (parm);
3877 gcc_assert (access_vec);
3878 repr = VEC_index (access_p, access_vec, 0);
3879 if (repr->write)
3880 return NULL;
3881 repr->group_representative = repr;
3883 access_count = VEC_length (access_p, access_vec);
3884 for (i = 1; i < access_count; i++)
3886 struct access *access = VEC_index (access_p, access_vec, i);
3887 if (access->write)
3888 return NULL;
3889 access->group_representative = repr;
3890 access->next_sibling = repr->next_sibling;
3891 repr->next_sibling = access;
3894 repr->grp_read = 1;
3895 repr->grp_scalar_ptr = 1;
3896 return repr;
3899 /* Return true iff this access precludes IPA-SRA of the parameter it is
3900 associated with. */
3902 static bool
3903 access_precludes_ipa_sra_p (struct access *access)
3905 /* Avoid issues such as the second simple testcase in PR 42025. The problem
3906 is incompatible assign in a call statement (and possibly even in asm
3907 statements). This can be relaxed by using a new temporary but only for
3908 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
3909 intraprocedural SRA we deal with this by keeping the old aggregate around,
3910 something we cannot do in IPA-SRA.) */
3911 if (access->write
3912 && (is_gimple_call (access->stmt)
3913 || gimple_code (access->stmt) == GIMPLE_ASM))
3914 return true;
3916 return false;
3920 /* Sort collected accesses for parameter PARM, identify representatives for
3921 each accessed region and link them together. Return NULL if there are
3922 different but overlapping accesses, return the special ptr value meaning
3923 there are no accesses for this parameter if that is the case and return the
3924 first representative otherwise. Set *RO_GRP if there is a group of accesses
3925 with only read (i.e. no write) accesses. */
3927 static struct access *
3928 splice_param_accesses (tree parm, bool *ro_grp)
3930 int i, j, access_count, group_count;
3931 int agg_size, total_size = 0;
3932 struct access *access, *res, **prev_acc_ptr = &res;
3933 VEC (access_p, heap) *access_vec;
3935 access_vec = get_base_access_vector (parm);
3936 if (!access_vec)
3937 return &no_accesses_representant;
3938 access_count = VEC_length (access_p, access_vec);
3940 VEC_qsort (access_p, access_vec, compare_access_positions);
3942 i = 0;
3943 total_size = 0;
3944 group_count = 0;
3945 while (i < access_count)
3947 bool modification;
3948 tree a1_alias_type;
3949 access = VEC_index (access_p, access_vec, i);
3950 modification = access->write;
3951 if (access_precludes_ipa_sra_p (access))
3952 return NULL;
3953 a1_alias_type = reference_alias_ptr_type (access->expr);
3955 /* Access is about to become group representative unless we find some
3956 nasty overlap which would preclude us from breaking this parameter
3957 apart. */
3959 j = i + 1;
3960 while (j < access_count)
3962 struct access *ac2 = VEC_index (access_p, access_vec, j);
3963 if (ac2->offset != access->offset)
3965 /* All or nothing law for parameters. */
3966 if (access->offset + access->size > ac2->offset)
3967 return NULL;
3968 else
3969 break;
3971 else if (ac2->size != access->size)
3972 return NULL;
3974 if (access_precludes_ipa_sra_p (ac2)
3975 || (ac2->type != access->type
3976 && (TREE_ADDRESSABLE (ac2->type)
3977 || TREE_ADDRESSABLE (access->type)))
3978 || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
3979 return NULL;
3981 modification |= ac2->write;
3982 ac2->group_representative = access;
3983 ac2->next_sibling = access->next_sibling;
3984 access->next_sibling = ac2;
3985 j++;
3988 group_count++;
3989 access->grp_maybe_modified = modification;
3990 if (!modification)
3991 *ro_grp = true;
3992 *prev_acc_ptr = access;
3993 prev_acc_ptr = &access->next_grp;
3994 total_size += access->size;
3995 i = j;
3998 if (POINTER_TYPE_P (TREE_TYPE (parm)))
3999 agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))), 1);
4000 else
4001 agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (parm)), 1);
4002 if (total_size >= agg_size)
4003 return NULL;
4005 gcc_assert (group_count > 0);
4006 return res;
4009 /* Decide whether parameters with representative accesses given by REPR should
4010 be reduced into components. */
4012 static int
4013 decide_one_param_reduction (struct access *repr)
4015 int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
4016 bool by_ref;
4017 tree parm;
4019 parm = repr->base;
4020 cur_parm_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (parm)), 1);
4021 gcc_assert (cur_parm_size > 0);
4023 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4025 by_ref = true;
4026 agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))), 1);
4028 else
4030 by_ref = false;
4031 agg_size = cur_parm_size;
4034 if (dump_file)
4036 struct access *acc;
4037 fprintf (dump_file, "Evaluating PARAM group sizes for ");
4038 print_generic_expr (dump_file, parm, 0);
4039 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
4040 for (acc = repr; acc; acc = acc->next_grp)
4041 dump_access (dump_file, acc, true);
4044 total_size = 0;
4045 new_param_count = 0;
4047 for (; repr; repr = repr->next_grp)
4049 gcc_assert (parm == repr->base);
4051 /* Taking the address of a non-addressable field is verboten. */
4052 if (by_ref && repr->non_addressable)
4053 return 0;
4055 /* Do not decompose a non-BLKmode param in a way that would
4056 create BLKmode params. Especially for by-reference passing
4057 (thus, pointer-type param) this is hardly worthwhile. */
4058 if (DECL_MODE (parm) != BLKmode
4059 && TYPE_MODE (repr->type) == BLKmode)
4060 return 0;
4062 if (!by_ref || (!repr->grp_maybe_modified
4063 && !repr->grp_not_necessarilly_dereferenced))
4064 total_size += repr->size;
4065 else
4066 total_size += cur_parm_size;
4068 new_param_count++;
4071 gcc_assert (new_param_count > 0);
4073 if (optimize_function_for_size_p (cfun))
4074 parm_size_limit = cur_parm_size;
4075 else
4076 parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
4077 * cur_parm_size);
4079 if (total_size < agg_size
4080 && total_size <= parm_size_limit)
4082 if (dump_file)
4083 fprintf (dump_file, " ....will be split into %i components\n",
4084 new_param_count);
4085 return new_param_count;
4087 else
4088 return 0;
4091 /* The order of the following enums is important, we need to do extra work for
4092 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4093 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
4094 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
4096 /* Identify representatives of all accesses to all candidate parameters for
4097 IPA-SRA. Return result based on what representatives have been found. */
4099 static enum ipa_splicing_result
4100 splice_all_param_accesses (VEC (access_p, heap) **representatives)
4102 enum ipa_splicing_result result = NO_GOOD_ACCESS;
4103 tree parm;
4104 struct access *repr;
4106 *representatives = VEC_alloc (access_p, heap, func_param_count);
4108 for (parm = DECL_ARGUMENTS (current_function_decl);
4109 parm;
4110 parm = DECL_CHAIN (parm))
4112 if (is_unused_scalar_param (parm))
4114 VEC_quick_push (access_p, *representatives,
4115 &no_accesses_representant);
4116 if (result == NO_GOOD_ACCESS)
4117 result = UNUSED_PARAMS;
4119 else if (POINTER_TYPE_P (TREE_TYPE (parm))
4120 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
4121 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4123 repr = unmodified_by_ref_scalar_representative (parm);
4124 VEC_quick_push (access_p, *representatives, repr);
4125 if (repr)
4126 result = UNMODIF_BY_REF_ACCESSES;
4128 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4130 bool ro_grp = false;
4131 repr = splice_param_accesses (parm, &ro_grp);
4132 VEC_quick_push (access_p, *representatives, repr);
4134 if (repr && !no_accesses_p (repr))
4136 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4138 if (ro_grp)
4139 result = UNMODIF_BY_REF_ACCESSES;
4140 else if (result < MODIF_BY_REF_ACCESSES)
4141 result = MODIF_BY_REF_ACCESSES;
4143 else if (result < BY_VAL_ACCESSES)
4144 result = BY_VAL_ACCESSES;
4146 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
4147 result = UNUSED_PARAMS;
4149 else
4150 VEC_quick_push (access_p, *representatives, NULL);
4153 if (result == NO_GOOD_ACCESS)
4155 VEC_free (access_p, heap, *representatives);
4156 *representatives = NULL;
4157 return NO_GOOD_ACCESS;
4160 return result;
4163 /* Return the index of BASE in PARMS. Abort if it is not found. */
4165 static inline int
4166 get_param_index (tree base, VEC(tree, heap) *parms)
4168 int i, len;
4170 len = VEC_length (tree, parms);
4171 for (i = 0; i < len; i++)
4172 if (VEC_index (tree, parms, i) == base)
4173 return i;
4174 gcc_unreachable ();
4177 /* Convert the decisions made at the representative level into compact
4178 parameter adjustments. REPRESENTATIVES are pointers to first
4179 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4180 final number of adjustments. */
4182 static ipa_parm_adjustment_vec
4183 turn_representatives_into_adjustments (VEC (access_p, heap) *representatives,
4184 int adjustments_count)
4186 VEC (tree, heap) *parms;
4187 ipa_parm_adjustment_vec adjustments;
4188 tree parm;
4189 int i;
4191 gcc_assert (adjustments_count > 0);
4192 parms = ipa_get_vector_of_formal_parms (current_function_decl);
4193 adjustments = VEC_alloc (ipa_parm_adjustment_t, heap, adjustments_count);
4194 parm = DECL_ARGUMENTS (current_function_decl);
4195 for (i = 0; i < func_param_count; i++, parm = DECL_CHAIN (parm))
4197 struct access *repr = VEC_index (access_p, representatives, i);
4199 if (!repr || no_accesses_p (repr))
4201 struct ipa_parm_adjustment adj;
4203 memset (&adj, 0, sizeof (adj));
4204 adj.base_index = get_param_index (parm, parms);
4205 adj.base = parm;
4206 if (!repr)
4207 adj.copy_param = 1;
4208 else
4209 adj.remove_param = 1;
4210 VEC_quick_push (ipa_parm_adjustment_t, adjustments, adj);
4212 else
4214 struct ipa_parm_adjustment adj;
4215 int index = get_param_index (parm, parms);
4217 for (; repr; repr = repr->next_grp)
4219 memset (&adj, 0, sizeof (adj));
4220 gcc_assert (repr->base == parm);
4221 adj.base_index = index;
4222 adj.base = repr->base;
4223 adj.type = repr->type;
4224 adj.alias_ptr_type = reference_alias_ptr_type (repr->expr);
4225 adj.offset = repr->offset;
4226 adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
4227 && (repr->grp_maybe_modified
4228 || repr->grp_not_necessarilly_dereferenced));
4229 VEC_quick_push (ipa_parm_adjustment_t, adjustments, adj);
4233 VEC_free (tree, heap, parms);
4234 return adjustments;
4237 /* Analyze the collected accesses and produce a plan what to do with the
4238 parameters in the form of adjustments, NULL meaning nothing. */
4240 static ipa_parm_adjustment_vec
4241 analyze_all_param_acesses (void)
4243 enum ipa_splicing_result repr_state;
4244 bool proceed = false;
4245 int i, adjustments_count = 0;
4246 VEC (access_p, heap) *representatives;
4247 ipa_parm_adjustment_vec adjustments;
4249 repr_state = splice_all_param_accesses (&representatives);
4250 if (repr_state == NO_GOOD_ACCESS)
4251 return NULL;
4253 /* If there are any parameters passed by reference which are not modified
4254 directly, we need to check whether they can be modified indirectly. */
4255 if (repr_state == UNMODIF_BY_REF_ACCESSES)
4257 analyze_caller_dereference_legality (representatives);
4258 analyze_modified_params (representatives);
4261 for (i = 0; i < func_param_count; i++)
4263 struct access *repr = VEC_index (access_p, representatives, i);
4265 if (repr && !no_accesses_p (repr))
4267 if (repr->grp_scalar_ptr)
4269 adjustments_count++;
4270 if (repr->grp_not_necessarilly_dereferenced
4271 || repr->grp_maybe_modified)
4272 VEC_replace (access_p, representatives, i, NULL);
4273 else
4275 proceed = true;
4276 sra_stats.scalar_by_ref_to_by_val++;
4279 else
4281 int new_components = decide_one_param_reduction (repr);
4283 if (new_components == 0)
4285 VEC_replace (access_p, representatives, i, NULL);
4286 adjustments_count++;
4288 else
4290 adjustments_count += new_components;
4291 sra_stats.aggregate_params_reduced++;
4292 sra_stats.param_reductions_created += new_components;
4293 proceed = true;
4297 else
4299 if (no_accesses_p (repr))
4301 proceed = true;
4302 sra_stats.deleted_unused_parameters++;
4304 adjustments_count++;
4308 if (!proceed && dump_file)
4309 fprintf (dump_file, "NOT proceeding to change params.\n");
4311 if (proceed)
4312 adjustments = turn_representatives_into_adjustments (representatives,
4313 adjustments_count);
4314 else
4315 adjustments = NULL;
4317 VEC_free (access_p, heap, representatives);
4318 return adjustments;
4321 /* If a parameter replacement identified by ADJ does not yet exist in the form
4322 of declaration, create it and record it, otherwise return the previously
4323 created one. */
4325 static tree
4326 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
4328 tree repl;
4329 if (!adj->new_ssa_base)
4331 char *pretty_name = make_fancy_name (adj->base);
4333 repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR");
4334 DECL_NAME (repl) = get_identifier (pretty_name);
4335 obstack_free (&name_obstack, pretty_name);
4337 adj->new_ssa_base = repl;
4339 else
4340 repl = adj->new_ssa_base;
4341 return repl;
4344 /* Find the first adjustment for a particular parameter BASE in a vector of
4345 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4346 adjustment. */
4348 static struct ipa_parm_adjustment *
4349 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
4351 int i, len;
4353 len = VEC_length (ipa_parm_adjustment_t, adjustments);
4354 for (i = 0; i < len; i++)
4356 struct ipa_parm_adjustment *adj;
4358 adj = &VEC_index (ipa_parm_adjustment_t, adjustments, i);
4359 if (!adj->copy_param && adj->base == base)
4360 return adj;
4363 return NULL;
4366 /* If the statement STMT defines an SSA_NAME of a parameter which is to be
4367 removed because its value is not used, replace the SSA_NAME with a one
4368 relating to a created VAR_DECL together all of its uses and return true.
4369 ADJUSTMENTS is a pointer to an adjustments vector. */
4371 static bool
4372 replace_removed_params_ssa_names (gimple stmt,
4373 ipa_parm_adjustment_vec adjustments)
4375 struct ipa_parm_adjustment *adj;
4376 tree lhs, decl, repl, name;
4378 if (gimple_code (stmt) == GIMPLE_PHI)
4379 lhs = gimple_phi_result (stmt);
4380 else if (is_gimple_assign (stmt))
4381 lhs = gimple_assign_lhs (stmt);
4382 else if (is_gimple_call (stmt))
4383 lhs = gimple_call_lhs (stmt);
4384 else
4385 gcc_unreachable ();
4387 if (TREE_CODE (lhs) != SSA_NAME)
4388 return false;
4390 decl = SSA_NAME_VAR (lhs);
4391 if (decl == NULL_TREE
4392 || TREE_CODE (decl) != PARM_DECL)
4393 return false;
4395 adj = get_adjustment_for_base (adjustments, decl);
4396 if (!adj)
4397 return false;
4399 repl = get_replaced_param_substitute (adj);
4400 name = make_ssa_name (repl, stmt);
4402 if (dump_file)
4404 fprintf (dump_file, "replacing an SSA name of a removed param ");
4405 print_generic_expr (dump_file, lhs, 0);
4406 fprintf (dump_file, " with ");
4407 print_generic_expr (dump_file, name, 0);
4408 fprintf (dump_file, "\n");
4411 if (is_gimple_assign (stmt))
4412 gimple_assign_set_lhs (stmt, name);
4413 else if (is_gimple_call (stmt))
4414 gimple_call_set_lhs (stmt, name);
4415 else
4416 gimple_phi_set_result (stmt, name);
4418 replace_uses_by (lhs, name);
4419 release_ssa_name (lhs);
4420 return true;
4423 /* If the expression *EXPR should be replaced by a reduction of a parameter, do
4424 so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
4425 specifies whether the function should care about type incompatibility the
4426 current and new expressions. If it is false, the function will leave
4427 incompatibility issues to the caller. Return true iff the expression
4428 was modified. */
4430 static bool
4431 sra_ipa_modify_expr (tree *expr, bool convert,
4432 ipa_parm_adjustment_vec adjustments)
4434 int i, len;
4435 struct ipa_parm_adjustment *adj, *cand = NULL;
4436 HOST_WIDE_INT offset, size, max_size;
4437 tree base, src;
4439 len = VEC_length (ipa_parm_adjustment_t, adjustments);
4441 if (TREE_CODE (*expr) == BIT_FIELD_REF
4442 || TREE_CODE (*expr) == IMAGPART_EXPR
4443 || TREE_CODE (*expr) == REALPART_EXPR)
4445 expr = &TREE_OPERAND (*expr, 0);
4446 convert = true;
4449 base = get_ref_base_and_extent (*expr, &offset, &size, &max_size);
4450 if (!base || size == -1 || max_size == -1)
4451 return false;
4453 if (TREE_CODE (base) == MEM_REF)
4455 offset += mem_ref_offset (base).low * BITS_PER_UNIT;
4456 base = TREE_OPERAND (base, 0);
4459 base = get_ssa_base_param (base);
4460 if (!base || TREE_CODE (base) != PARM_DECL)
4461 return false;
4463 for (i = 0; i < len; i++)
4465 adj = &VEC_index (ipa_parm_adjustment_t, adjustments, i);
4467 if (adj->base == base &&
4468 (adj->offset == offset || adj->remove_param))
4470 cand = adj;
4471 break;
4474 if (!cand || cand->copy_param || cand->remove_param)
4475 return false;
4477 if (cand->by_ref)
4478 src = build_simple_mem_ref (cand->reduction);
4479 else
4480 src = cand->reduction;
4482 if (dump_file && (dump_flags & TDF_DETAILS))
4484 fprintf (dump_file, "About to replace expr ");
4485 print_generic_expr (dump_file, *expr, 0);
4486 fprintf (dump_file, " with ");
4487 print_generic_expr (dump_file, src, 0);
4488 fprintf (dump_file, "\n");
4491 if (convert && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
4493 tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
4494 *expr = vce;
4496 else
4497 *expr = src;
4498 return true;
4501 /* If the statement pointed to by STMT_PTR contains any expressions that need
4502 to replaced with a different one as noted by ADJUSTMENTS, do so. Handle any
4503 potential type incompatibilities (GSI is used to accommodate conversion
4504 statements and must point to the statement). Return true iff the statement
4505 was modified. */
4507 static bool
4508 sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi,
4509 ipa_parm_adjustment_vec adjustments)
4511 gimple stmt = *stmt_ptr;
4512 tree *lhs_p, *rhs_p;
4513 bool any;
4515 if (!gimple_assign_single_p (stmt))
4516 return false;
4518 rhs_p = gimple_assign_rhs1_ptr (stmt);
4519 lhs_p = gimple_assign_lhs_ptr (stmt);
4521 any = sra_ipa_modify_expr (rhs_p, false, adjustments);
4522 any |= sra_ipa_modify_expr (lhs_p, false, adjustments);
4523 if (any)
4525 tree new_rhs = NULL_TREE;
4527 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
4529 if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
4531 /* V_C_Es of constructors can cause trouble (PR 42714). */
4532 if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
4533 *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
4534 else
4535 *rhs_p = build_constructor (TREE_TYPE (*lhs_p), 0);
4537 else
4538 new_rhs = fold_build1_loc (gimple_location (stmt),
4539 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
4540 *rhs_p);
4542 else if (REFERENCE_CLASS_P (*rhs_p)
4543 && is_gimple_reg_type (TREE_TYPE (*lhs_p))
4544 && !is_gimple_reg (*lhs_p))
4545 /* This can happen when an assignment in between two single field
4546 structures is turned into an assignment in between two pointers to
4547 scalars (PR 42237). */
4548 new_rhs = *rhs_p;
4550 if (new_rhs)
4552 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
4553 true, GSI_SAME_STMT);
4555 gimple_assign_set_rhs_from_tree (gsi, tmp);
4558 return true;
4561 return false;
4564 /* Traverse the function body and all modifications as described in
4565 ADJUSTMENTS. Return true iff the CFG has been changed. */
4567 static bool
4568 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
4570 bool cfg_changed = false;
4571 basic_block bb;
4573 FOR_EACH_BB (bb)
4575 gimple_stmt_iterator gsi;
4577 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4578 replace_removed_params_ssa_names (gsi_stmt (gsi), adjustments);
4580 gsi = gsi_start_bb (bb);
4581 while (!gsi_end_p (gsi))
4583 gimple stmt = gsi_stmt (gsi);
4584 bool modified = false;
4585 tree *t;
4586 unsigned i;
4588 switch (gimple_code (stmt))
4590 case GIMPLE_RETURN:
4591 t = gimple_return_retval_ptr (stmt);
4592 if (*t != NULL_TREE)
4593 modified |= sra_ipa_modify_expr (t, true, adjustments);
4594 break;
4596 case GIMPLE_ASSIGN:
4597 modified |= sra_ipa_modify_assign (&stmt, &gsi, adjustments);
4598 modified |= replace_removed_params_ssa_names (stmt, adjustments);
4599 break;
4601 case GIMPLE_CALL:
4602 /* Operands must be processed before the lhs. */
4603 for (i = 0; i < gimple_call_num_args (stmt); i++)
4605 t = gimple_call_arg_ptr (stmt, i);
4606 modified |= sra_ipa_modify_expr (t, true, adjustments);
4609 if (gimple_call_lhs (stmt))
4611 t = gimple_call_lhs_ptr (stmt);
4612 modified |= sra_ipa_modify_expr (t, false, adjustments);
4613 modified |= replace_removed_params_ssa_names (stmt,
4614 adjustments);
4616 break;
4618 case GIMPLE_ASM:
4619 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
4621 t = &TREE_VALUE (gimple_asm_input_op (stmt, i));
4622 modified |= sra_ipa_modify_expr (t, true, adjustments);
4624 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
4626 t = &TREE_VALUE (gimple_asm_output_op (stmt, i));
4627 modified |= sra_ipa_modify_expr (t, false, adjustments);
4629 break;
4631 default:
4632 break;
4635 if (modified)
4637 update_stmt (stmt);
4638 if (maybe_clean_eh_stmt (stmt)
4639 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
4640 cfg_changed = true;
4642 gsi_next (&gsi);
4646 return cfg_changed;
4649 /* Call gimple_debug_bind_reset_value on all debug statements describing
4650 gimple register parameters that are being removed or replaced. */
4652 static void
4653 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
4655 int i, len;
4656 gimple_stmt_iterator *gsip = NULL, gsi;
4658 if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR))
4660 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
4661 gsip = &gsi;
4663 len = VEC_length (ipa_parm_adjustment_t, adjustments);
4664 for (i = 0; i < len; i++)
4666 struct ipa_parm_adjustment *adj;
4667 imm_use_iterator ui;
4668 gimple stmt, def_temp;
4669 tree name, vexpr, copy = NULL_TREE;
4670 use_operand_p use_p;
4672 adj = &VEC_index (ipa_parm_adjustment_t, adjustments, i);
4673 if (adj->copy_param || !is_gimple_reg (adj->base))
4674 continue;
4675 name = ssa_default_def (cfun, adj->base);
4676 vexpr = NULL;
4677 if (name)
4678 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
4680 /* All other users must have been removed by
4681 ipa_sra_modify_function_body. */
4682 gcc_assert (is_gimple_debug (stmt));
4683 if (vexpr == NULL && gsip != NULL)
4685 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
4686 vexpr = make_node (DEBUG_EXPR_DECL);
4687 def_temp = gimple_build_debug_source_bind (vexpr, adj->base,
4688 NULL);
4689 DECL_ARTIFICIAL (vexpr) = 1;
4690 TREE_TYPE (vexpr) = TREE_TYPE (name);
4691 DECL_MODE (vexpr) = DECL_MODE (adj->base);
4692 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
4694 if (vexpr)
4696 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
4697 SET_USE (use_p, vexpr);
4699 else
4700 gimple_debug_bind_reset_value (stmt);
4701 update_stmt (stmt);
4703 /* Create a VAR_DECL for debug info purposes. */
4704 if (!DECL_IGNORED_P (adj->base))
4706 copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
4707 VAR_DECL, DECL_NAME (adj->base),
4708 TREE_TYPE (adj->base));
4709 if (DECL_PT_UID_SET_P (adj->base))
4710 SET_DECL_PT_UID (copy, DECL_PT_UID (adj->base));
4711 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (adj->base);
4712 TREE_READONLY (copy) = TREE_READONLY (adj->base);
4713 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (adj->base);
4714 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (adj->base);
4715 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (adj->base);
4716 DECL_IGNORED_P (copy) = DECL_IGNORED_P (adj->base);
4717 DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (adj->base);
4718 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
4719 SET_DECL_RTL (copy, 0);
4720 TREE_USED (copy) = 1;
4721 DECL_CONTEXT (copy) = current_function_decl;
4722 add_local_decl (cfun, copy);
4723 DECL_CHAIN (copy) =
4724 BLOCK_VARS (DECL_INITIAL (current_function_decl));
4725 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
4727 if (gsip != NULL && copy && target_for_debug_bind (adj->base))
4729 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
4730 if (vexpr)
4731 def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
4732 else
4733 def_temp = gimple_build_debug_source_bind (copy, adj->base,
4734 NULL);
4735 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
4740 /* Return false iff all callers have at least as many actual arguments as there
4741 are formal parameters in the current function. */
4743 static bool
4744 not_all_callers_have_enough_arguments_p (struct cgraph_node *node,
4745 void *data ATTRIBUTE_UNUSED)
4747 struct cgraph_edge *cs;
4748 for (cs = node->callers; cs; cs = cs->next_caller)
4749 if (!callsite_has_enough_arguments_p (cs->call_stmt))
4750 return true;
4752 return false;
4755 /* Convert all callers of NODE. */
4757 static bool
4758 convert_callers_for_node (struct cgraph_node *node,
4759 void *data)
4761 ipa_parm_adjustment_vec adjustments = (ipa_parm_adjustment_vec)data;
4762 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
4763 struct cgraph_edge *cs;
4765 for (cs = node->callers; cs; cs = cs->next_caller)
4767 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->symbol.decl));
4769 if (dump_file)
4770 fprintf (dump_file, "Adjusting call (%i -> %i) %s -> %s\n",
4771 cs->caller->uid, cs->callee->uid,
4772 xstrdup (cgraph_node_name (cs->caller)),
4773 xstrdup (cgraph_node_name (cs->callee)));
4775 ipa_modify_call_arguments (cs, cs->call_stmt, adjustments);
4777 pop_cfun ();
4780 for (cs = node->callers; cs; cs = cs->next_caller)
4781 if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
4782 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->symbol.decl)))
4783 compute_inline_parameters (cs->caller, true);
4784 BITMAP_FREE (recomputed_callers);
4786 return true;
4789 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
4791 static void
4792 convert_callers (struct cgraph_node *node, tree old_decl,
4793 ipa_parm_adjustment_vec adjustments)
4795 basic_block this_block;
4797 cgraph_for_node_and_aliases (node, convert_callers_for_node,
4798 adjustments, false);
4800 if (!encountered_recursive_call)
4801 return;
4803 FOR_EACH_BB (this_block)
4805 gimple_stmt_iterator gsi;
4807 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
4809 gimple stmt = gsi_stmt (gsi);
4810 tree call_fndecl;
4811 if (gimple_code (stmt) != GIMPLE_CALL)
4812 continue;
4813 call_fndecl = gimple_call_fndecl (stmt);
4814 if (call_fndecl == old_decl)
4816 if (dump_file)
4817 fprintf (dump_file, "Adjusting recursive call");
4818 gimple_call_set_fndecl (stmt, node->symbol.decl);
4819 ipa_modify_call_arguments (NULL, stmt, adjustments);
4824 return;
4827 /* Perform all the modification required in IPA-SRA for NODE to have parameters
4828 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
4830 static bool
4831 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
4833 struct cgraph_node *new_node;
4834 bool cfg_changed;
4835 VEC (cgraph_edge_p, heap) * redirect_callers = collect_callers_of_node (node);
4837 rebuild_cgraph_edges ();
4838 free_dominance_info (CDI_DOMINATORS);
4839 pop_cfun ();
4841 new_node = cgraph_function_versioning (node, redirect_callers, NULL, NULL,
4842 false, NULL, NULL, "isra");
4843 VEC_free (cgraph_edge_p, heap, redirect_callers);
4845 push_cfun (DECL_STRUCT_FUNCTION (new_node->symbol.decl));
4846 ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA");
4847 cfg_changed = ipa_sra_modify_function_body (adjustments);
4848 sra_ipa_reset_debug_stmts (adjustments);
4849 convert_callers (new_node, node->symbol.decl, adjustments);
4850 cgraph_make_node_local (new_node);
4851 return cfg_changed;
4854 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
4855 attributes, return true otherwise. NODE is the cgraph node of the current
4856 function. */
4858 static bool
4859 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
4861 if (!cgraph_node_can_be_local_p (node))
4863 if (dump_file)
4864 fprintf (dump_file, "Function not local to this compilation unit.\n");
4865 return false;
4868 if (!node->local.can_change_signature)
4870 if (dump_file)
4871 fprintf (dump_file, "Function can not change signature.\n");
4872 return false;
4875 if (!tree_versionable_function_p (node->symbol.decl))
4877 if (dump_file)
4878 fprintf (dump_file, "Function is not versionable.\n");
4879 return false;
4882 if (DECL_VIRTUAL_P (current_function_decl))
4884 if (dump_file)
4885 fprintf (dump_file, "Function is a virtual method.\n");
4886 return false;
4889 if ((DECL_COMDAT (node->symbol.decl) || DECL_EXTERNAL (node->symbol.decl))
4890 && inline_summary(node)->size >= MAX_INLINE_INSNS_AUTO)
4892 if (dump_file)
4893 fprintf (dump_file, "Function too big to be made truly local.\n");
4894 return false;
4897 if (!node->callers)
4899 if (dump_file)
4900 fprintf (dump_file,
4901 "Function has no callers in this compilation unit.\n");
4902 return false;
4905 if (cfun->stdarg)
4907 if (dump_file)
4908 fprintf (dump_file, "Function uses stdarg. \n");
4909 return false;
4912 if (TYPE_ATTRIBUTES (TREE_TYPE (node->symbol.decl)))
4913 return false;
4915 return true;
4918 /* Perform early interprocedural SRA. */
4920 static unsigned int
4921 ipa_early_sra (void)
4923 struct cgraph_node *node = cgraph_get_node (current_function_decl);
4924 ipa_parm_adjustment_vec adjustments;
4925 int ret = 0;
4927 if (!ipa_sra_preliminary_function_checks (node))
4928 return 0;
4930 sra_initialize ();
4931 sra_mode = SRA_MODE_EARLY_IPA;
4933 if (!find_param_candidates ())
4935 if (dump_file)
4936 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
4937 goto simple_out;
4940 if (cgraph_for_node_and_aliases (node, not_all_callers_have_enough_arguments_p,
4941 NULL, true))
4943 if (dump_file)
4944 fprintf (dump_file, "There are callers with insufficient number of "
4945 "arguments.\n");
4946 goto simple_out;
4949 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
4950 func_param_count
4951 * last_basic_block_for_function (cfun));
4952 final_bbs = BITMAP_ALLOC (NULL);
4954 scan_function ();
4955 if (encountered_apply_args)
4957 if (dump_file)
4958 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
4959 goto out;
4962 if (encountered_unchangable_recursive_call)
4964 if (dump_file)
4965 fprintf (dump_file, "Function calls itself with insufficient "
4966 "number of arguments.\n");
4967 goto out;
4970 adjustments = analyze_all_param_acesses ();
4971 if (!adjustments)
4972 goto out;
4973 if (dump_file)
4974 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
4976 if (modify_function (node, adjustments))
4977 ret = TODO_update_ssa | TODO_cleanup_cfg;
4978 else
4979 ret = TODO_update_ssa;
4980 VEC_free (ipa_parm_adjustment_t, heap, adjustments);
4982 statistics_counter_event (cfun, "Unused parameters deleted",
4983 sra_stats.deleted_unused_parameters);
4984 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
4985 sra_stats.scalar_by_ref_to_by_val);
4986 statistics_counter_event (cfun, "Aggregate parameters broken up",
4987 sra_stats.aggregate_params_reduced);
4988 statistics_counter_event (cfun, "Aggregate parameter components created",
4989 sra_stats.param_reductions_created);
4991 out:
4992 BITMAP_FREE (final_bbs);
4993 free (bb_dereferences);
4994 simple_out:
4995 sra_deinitialize ();
4996 return ret;
4999 /* Return if early ipa sra shall be performed. */
5000 static bool
5001 ipa_early_sra_gate (void)
5003 return flag_ipa_sra && dbg_cnt (eipa_sra);
5006 struct gimple_opt_pass pass_early_ipa_sra =
5009 GIMPLE_PASS,
5010 "eipa_sra", /* name */
5011 OPTGROUP_NONE, /* optinfo_flags */
5012 ipa_early_sra_gate, /* gate */
5013 ipa_early_sra, /* execute */
5014 NULL, /* sub */
5015 NULL, /* next */
5016 0, /* static_pass_number */
5017 TV_IPA_SRA, /* tv_id */
5018 0, /* properties_required */
5019 0, /* properties_provided */
5020 0, /* properties_destroyed */
5021 0, /* todo_flags_start */
5022 TODO_dump_symtab /* todo_flags_finish */