1 /* Scalar Replacement of Aggregates (SRA) converts some structure
2 references into scalar references, exposing them to the scalar
4 Copyright (C) 2008-2018 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
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
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
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
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. */
76 #include "coretypes.h"
83 #include "alloc-pool.h"
84 #include "tree-pass.h"
87 #include "gimple-pretty-print.h"
89 #include "fold-const.h"
91 #include "stor-layout.h"
93 #include "gimple-iterator.h"
94 #include "gimplify-me.h"
95 #include "gimple-walk.h"
99 #include "symbol-summary.h"
100 #include "ipa-param-manipulation.h"
101 #include "ipa-prop.h"
104 #include "tree-inline.h"
105 #include "ipa-fnsummary.h"
106 #include "ipa-utils.h"
107 #include "builtins.h"
109 /* Enumeration of all aggregate reductions we can do. */
110 enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
111 SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
112 SRA_MODE_INTRA }; /* late intraprocedural SRA */
114 /* Global variable describing which aggregate reduction we are performing at
116 static enum sra_mode sra_mode;
120 /* ACCESS represents each access to an aggregate variable (as a whole or a
121 part). It can also represent a group of accesses that refer to exactly the
122 same fragment of an aggregate (i.e. those that have exactly the same offset
123 and size). Such representatives for a single aggregate, once determined,
124 are linked in a linked list and have the group fields set.
126 Moreover, when doing intraprocedural SRA, a tree is built from those
127 representatives (by the means of first_child and next_sibling pointers), in
128 which all items in a subtree are "within" the root, i.e. their offset is
129 greater or equal to offset of the root and offset+size is smaller or equal
130 to offset+size of the root. Children of an access are sorted by offset.
132 Note that accesses to parts of vector and complex number types always
133 represented by an access to the whole complex number or a vector. It is a
134 duty of the modifying functions to replace them appropriately. */
138 /* Values returned by `get_ref_base_and_extent' for each component reference
139 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
140 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
141 HOST_WIDE_INT offset;
145 /* Expression. It is context dependent so do not use it to create new
146 expressions to access the original aggregate. See PR 42154 for a
152 /* The statement this access belongs to. */
155 /* Next group representative for this aggregate. */
156 struct access *next_grp;
158 /* Pointer to the group representative. Pointer to itself if the struct is
159 the representative. */
160 struct access *group_representative;
162 /* After access tree has been constructed, this points to the parent of the
163 current access, if there is one. NULL for roots. */
164 struct access *parent;
166 /* If this access has any children (in terms of the definition above), this
167 points to the first one. */
168 struct access *first_child;
170 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
171 described above. In IPA-SRA this is a pointer to the next access
172 belonging to the same group (having the same representative). */
173 struct access *next_sibling;
175 /* Pointers to the first and last element in the linked list of assign
177 struct assign_link *first_link, *last_link;
179 /* Pointer to the next access in the work queue. */
180 struct access *next_queued;
182 /* Replacement variable for this access "region." Never to be accessed
183 directly, always only by the means of get_access_replacement() and only
184 when grp_to_be_replaced flag is set. */
185 tree replacement_decl;
187 /* Is this access an access to a non-addressable field? */
188 unsigned non_addressable : 1;
190 /* Is this access made in reverse storage order? */
191 unsigned reverse : 1;
193 /* Is this particular access write access? */
196 /* Is this access currently in the work queue? */
197 unsigned grp_queued : 1;
199 /* Does this group contain a write access? This flag is propagated down the
201 unsigned grp_write : 1;
203 /* Does this group contain a read access? This flag is propagated down the
205 unsigned grp_read : 1;
207 /* Does this group contain a read access that comes from an assignment
208 statement? This flag is propagated down the access tree. */
209 unsigned grp_assignment_read : 1;
211 /* Does this group contain a write access that comes from an assignment
212 statement? This flag is propagated down the access tree. */
213 unsigned grp_assignment_write : 1;
215 /* Does this group contain a read access through a scalar type? This flag is
216 not propagated in the access tree in any direction. */
217 unsigned grp_scalar_read : 1;
219 /* Does this group contain a write access through a scalar type? This flag
220 is not propagated in the access tree in any direction. */
221 unsigned grp_scalar_write : 1;
223 /* Is this access an artificial one created to scalarize some record
225 unsigned grp_total_scalarization : 1;
227 /* Other passes of the analysis use this bit to make function
228 analyze_access_subtree create scalar replacements for this group if
230 unsigned grp_hint : 1;
232 /* Is the subtree rooted in this access fully covered by scalar
234 unsigned grp_covered : 1;
236 /* If set to true, this access and all below it in an access tree must not be
238 unsigned grp_unscalarizable_region : 1;
240 /* Whether data have been written to parts of the aggregate covered by this
241 access which is not to be scalarized. This flag is propagated up in the
243 unsigned grp_unscalarized_data : 1;
245 /* Does this access and/or group contain a write access through a
247 unsigned grp_partial_lhs : 1;
249 /* Set when a scalar replacement should be created for this variable. */
250 unsigned grp_to_be_replaced : 1;
252 /* Set when we want a replacement for the sole purpose of having it in
253 generated debug statements. */
254 unsigned grp_to_be_debug_replaced : 1;
256 /* Should TREE_NO_WARNING of a replacement be set? */
257 unsigned grp_no_warning : 1;
259 /* Is it possible that the group refers to data which might be (directly or
260 otherwise) modified? */
261 unsigned grp_maybe_modified : 1;
263 /* Set when this is a representative of a pointer to scalar (i.e. by
264 reference) parameter which we consider for turning into a plain scalar
265 (i.e. a by value parameter). */
266 unsigned grp_scalar_ptr : 1;
268 /* Set when we discover that this pointer is not safe to dereference in the
270 unsigned grp_not_necessarilly_dereferenced : 1;
273 typedef struct access *access_p;
276 /* Alloc pool for allocating access structures. */
277 static object_allocator<struct access> access_pool ("SRA accesses");
279 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
280 are used to propagate subaccesses from rhs to lhs as long as they don't
281 conflict with what is already there. */
284 struct access *lacc, *racc;
285 struct assign_link *next;
288 /* Alloc pool for allocating assign link structures. */
289 static object_allocator<assign_link> assign_link_pool ("SRA links");
291 /* Base (tree) -> Vector (vec<access_p> *) map. */
292 static hash_map<tree, auto_vec<access_p> > *base_access_vec;
294 /* Candidate hash table helpers. */
296 struct uid_decl_hasher : nofree_ptr_hash <tree_node>
298 static inline hashval_t hash (const tree_node *);
299 static inline bool equal (const tree_node *, const tree_node *);
302 /* Hash a tree in a uid_decl_map. */
305 uid_decl_hasher::hash (const tree_node *item)
307 return item->decl_minimal.uid;
310 /* Return true if the DECL_UID in both trees are equal. */
313 uid_decl_hasher::equal (const tree_node *a, const tree_node *b)
315 return (a->decl_minimal.uid == b->decl_minimal.uid);
318 /* Set of candidates. */
319 static bitmap candidate_bitmap;
320 static hash_table<uid_decl_hasher> *candidates;
322 /* For a candidate UID return the candidates decl. */
325 candidate (unsigned uid)
328 t.decl_minimal.uid = uid;
329 return candidates->find_with_hash (&t, static_cast <hashval_t> (uid));
332 /* Bitmap of candidates which we should try to entirely scalarize away and
333 those which cannot be (because they are and need be used as a whole). */
334 static bitmap should_scalarize_away_bitmap, cannot_scalarize_away_bitmap;
336 /* Bitmap of candidates in the constant pool, which cannot be scalarized
337 because this would produce non-constant expressions (e.g. Ada). */
338 static bitmap disqualified_constants;
340 /* Obstack for creation of fancy names. */
341 static struct obstack name_obstack;
343 /* Head of a linked list of accesses that need to have its subaccesses
344 propagated to their assignment counterparts. */
345 static struct access *work_queue_head;
347 /* Number of parameters of the analyzed function when doing early ipa SRA. */
348 static int func_param_count;
350 /* scan_function sets the following to true if it encounters a call to
351 __builtin_apply_args. */
352 static bool encountered_apply_args;
354 /* Set by scan_function when it finds a recursive call. */
355 static bool encountered_recursive_call;
357 /* Set by scan_function when it finds a recursive call with less actual
358 arguments than formal parameters.. */
359 static bool encountered_unchangable_recursive_call;
361 /* This is a table in which for each basic block and parameter there is a
362 distance (offset + size) in that parameter which is dereferenced and
363 accessed in that BB. */
364 static HOST_WIDE_INT *bb_dereferences;
365 /* Bitmap of BBs that can cause the function to "stop" progressing by
366 returning, throwing externally, looping infinitely or calling a function
367 which might abort etc.. */
368 static bitmap final_bbs;
370 /* Representative of no accesses at all. */
371 static struct access no_accesses_representant;
373 /* Predicate to test the special value. */
376 no_accesses_p (struct access *access)
378 return access == &no_accesses_representant;
381 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
382 representative fields are dumped, otherwise those which only describe the
383 individual access are. */
387 /* Number of processed aggregates is readily available in
388 analyze_all_variable_accesses and so is not stored here. */
390 /* Number of created scalar replacements. */
393 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
397 /* Number of statements created by generate_subtree_copies. */
400 /* Number of statements created by load_assign_lhs_subreplacements. */
403 /* Number of times sra_modify_assign has deleted a statement. */
406 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
407 RHS reparately due to type conversions or nonexistent matching
409 int separate_lhs_rhs_handling;
411 /* Number of parameters that were removed because they were unused. */
412 int deleted_unused_parameters;
414 /* Number of scalars passed as parameters by reference that have been
415 converted to be passed by value. */
416 int scalar_by_ref_to_by_val;
418 /* Number of aggregate parameters that were replaced by one or more of their
420 int aggregate_params_reduced;
422 /* Numbber of components created when splitting aggregate parameters. */
423 int param_reductions_created;
427 dump_access (FILE *f, struct access *access, bool grp)
429 fprintf (f, "access { ");
430 fprintf (f, "base = (%d)'", DECL_UID (access->base));
431 print_generic_expr (f, access->base);
432 fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
433 fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
434 fprintf (f, ", expr = ");
435 print_generic_expr (f, access->expr);
436 fprintf (f, ", type = ");
437 print_generic_expr (f, access->type);
438 fprintf (f, ", non_addressable = %d, reverse = %d",
439 access->non_addressable, access->reverse);
441 fprintf (f, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
442 "grp_assignment_write = %d, grp_scalar_read = %d, "
443 "grp_scalar_write = %d, grp_total_scalarization = %d, "
444 "grp_hint = %d, grp_covered = %d, "
445 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
446 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
447 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
448 "grp_not_necessarilly_dereferenced = %d\n",
449 access->grp_read, access->grp_write, access->grp_assignment_read,
450 access->grp_assignment_write, access->grp_scalar_read,
451 access->grp_scalar_write, access->grp_total_scalarization,
452 access->grp_hint, access->grp_covered,
453 access->grp_unscalarizable_region, access->grp_unscalarized_data,
454 access->grp_partial_lhs, access->grp_to_be_replaced,
455 access->grp_to_be_debug_replaced, access->grp_maybe_modified,
456 access->grp_not_necessarilly_dereferenced);
458 fprintf (f, ", write = %d, grp_total_scalarization = %d, "
459 "grp_partial_lhs = %d\n",
460 access->write, access->grp_total_scalarization,
461 access->grp_partial_lhs);
464 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
467 dump_access_tree_1 (FILE *f, struct access *access, int level)
473 for (i = 0; i < level; i++)
476 dump_access (f, access, true);
478 if (access->first_child)
479 dump_access_tree_1 (f, access->first_child, level + 1);
481 access = access->next_sibling;
486 /* Dump all access trees for a variable, given the pointer to the first root in
490 dump_access_tree (FILE *f, struct access *access)
492 for (; access; access = access->next_grp)
493 dump_access_tree_1 (f, access, 0);
496 /* Return true iff ACC is non-NULL and has subaccesses. */
499 access_has_children_p (struct access *acc)
501 return acc && acc->first_child;
504 /* Return true iff ACC is (partly) covered by at least one replacement. */
507 access_has_replacements_p (struct access *acc)
509 struct access *child;
510 if (acc->grp_to_be_replaced)
512 for (child = acc->first_child; child; child = child->next_sibling)
513 if (access_has_replacements_p (child))
518 /* Return a vector of pointers to accesses for the variable given in BASE or
519 NULL if there is none. */
521 static vec<access_p> *
522 get_base_access_vector (tree base)
524 return base_access_vec->get (base);
527 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
528 in ACCESS. Return NULL if it cannot be found. */
530 static struct access *
531 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
534 while (access && (access->offset != offset || access->size != size))
536 struct access *child = access->first_child;
538 while (child && (child->offset + child->size <= offset))
539 child = child->next_sibling;
546 /* Return the first group representative for DECL or NULL if none exists. */
548 static struct access *
549 get_first_repr_for_decl (tree base)
551 vec<access_p> *access_vec;
553 access_vec = get_base_access_vector (base);
557 return (*access_vec)[0];
560 /* Find an access representative for the variable BASE and given OFFSET and
561 SIZE. Requires that access trees have already been built. Return NULL if
562 it cannot be found. */
564 static struct access *
565 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
568 struct access *access;
570 access = get_first_repr_for_decl (base);
571 while (access && (access->offset + access->size <= offset))
572 access = access->next_grp;
576 return find_access_in_subtree (access, offset, size);
579 /* Add LINK to the linked list of assign links of RACC. */
581 add_link_to_rhs (struct access *racc, struct assign_link *link)
583 gcc_assert (link->racc == racc);
585 if (!racc->first_link)
587 gcc_assert (!racc->last_link);
588 racc->first_link = link;
591 racc->last_link->next = link;
593 racc->last_link = link;
597 /* Move all link structures in their linked list in OLD_RACC to the linked list
600 relink_to_new_repr (struct access *new_racc, struct access *old_racc)
602 if (!old_racc->first_link)
604 gcc_assert (!old_racc->last_link);
608 if (new_racc->first_link)
610 gcc_assert (!new_racc->last_link->next);
611 gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
613 new_racc->last_link->next = old_racc->first_link;
614 new_racc->last_link = old_racc->last_link;
618 gcc_assert (!new_racc->last_link);
620 new_racc->first_link = old_racc->first_link;
621 new_racc->last_link = old_racc->last_link;
623 old_racc->first_link = old_racc->last_link = NULL;
626 /* Add ACCESS to the work queue (which is actually a stack). */
629 add_access_to_work_queue (struct access *access)
631 if (access->first_link && !access->grp_queued)
633 gcc_assert (!access->next_queued);
634 access->next_queued = work_queue_head;
635 access->grp_queued = 1;
636 work_queue_head = access;
640 /* Pop an access from the work queue, and return it, assuming there is one. */
642 static struct access *
643 pop_access_from_work_queue (void)
645 struct access *access = work_queue_head;
647 work_queue_head = access->next_queued;
648 access->next_queued = NULL;
649 access->grp_queued = 0;
654 /* Allocate necessary structures. */
657 sra_initialize (void)
659 candidate_bitmap = BITMAP_ALLOC (NULL);
660 candidates = new hash_table<uid_decl_hasher>
661 (vec_safe_length (cfun->local_decls) / 2);
662 should_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
663 cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
664 disqualified_constants = BITMAP_ALLOC (NULL);
665 gcc_obstack_init (&name_obstack);
666 base_access_vec = new hash_map<tree, auto_vec<access_p> >;
667 memset (&sra_stats, 0, sizeof (sra_stats));
668 encountered_apply_args = false;
669 encountered_recursive_call = false;
670 encountered_unchangable_recursive_call = false;
673 /* Deallocate all general structures. */
676 sra_deinitialize (void)
678 BITMAP_FREE (candidate_bitmap);
681 BITMAP_FREE (should_scalarize_away_bitmap);
682 BITMAP_FREE (cannot_scalarize_away_bitmap);
683 BITMAP_FREE (disqualified_constants);
684 access_pool.release ();
685 assign_link_pool.release ();
686 obstack_free (&name_obstack, NULL);
688 delete base_access_vec;
691 /* Return true if DECL is a VAR_DECL in the constant pool, false otherwise. */
693 static bool constant_decl_p (tree decl)
695 return VAR_P (decl) && DECL_IN_CONSTANT_POOL (decl);
698 /* Remove DECL from candidates for SRA and write REASON to the dump file if
702 disqualify_candidate (tree decl, const char *reason)
704 if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl)))
705 candidates->remove_elt_with_hash (decl, DECL_UID (decl));
706 if (constant_decl_p (decl))
707 bitmap_set_bit (disqualified_constants, DECL_UID (decl));
709 if (dump_file && (dump_flags & TDF_DETAILS))
711 fprintf (dump_file, "! Disqualifying ");
712 print_generic_expr (dump_file, decl);
713 fprintf (dump_file, " - %s\n", reason);
717 /* Return true iff the type contains a field or an element which does not allow
721 type_internals_preclude_sra_p (tree type, const char **msg)
726 switch (TREE_CODE (type))
730 case QUAL_UNION_TYPE:
731 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
732 if (TREE_CODE (fld) == FIELD_DECL)
734 tree ft = TREE_TYPE (fld);
736 if (TREE_THIS_VOLATILE (fld))
738 *msg = "volatile structure field";
741 if (!DECL_FIELD_OFFSET (fld))
743 *msg = "no structure field offset";
746 if (!DECL_SIZE (fld))
748 *msg = "zero structure field size";
751 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
753 *msg = "structure field offset not fixed";
756 if (!tree_fits_uhwi_p (DECL_SIZE (fld)))
758 *msg = "structure field size not fixed";
761 if (!tree_fits_shwi_p (bit_position (fld)))
763 *msg = "structure field size too big";
766 if (AGGREGATE_TYPE_P (ft)
767 && int_bit_position (fld) % BITS_PER_UNIT != 0)
769 *msg = "structure field is bit field";
773 if (AGGREGATE_TYPE_P (ft) && type_internals_preclude_sra_p (ft, msg))
780 et = TREE_TYPE (type);
782 if (TYPE_VOLATILE (et))
784 *msg = "element type is volatile";
788 if (AGGREGATE_TYPE_P (et) && type_internals_preclude_sra_p (et, msg))
798 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
799 base variable if it is. Return T if it is not an SSA_NAME. */
802 get_ssa_base_param (tree t)
804 if (TREE_CODE (t) == SSA_NAME)
806 if (SSA_NAME_IS_DEFAULT_DEF (t))
807 return SSA_NAME_VAR (t);
814 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
815 belongs to, unless the BB has already been marked as a potentially
819 mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple *stmt)
821 basic_block bb = gimple_bb (stmt);
822 int idx, parm_index = 0;
825 if (bitmap_bit_p (final_bbs, bb->index))
828 for (parm = DECL_ARGUMENTS (current_function_decl);
829 parm && parm != base;
830 parm = DECL_CHAIN (parm))
833 gcc_assert (parm_index < func_param_count);
835 idx = bb->index * func_param_count + parm_index;
836 if (bb_dereferences[idx] < dist)
837 bb_dereferences[idx] = dist;
840 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
841 the three fields. Also add it to the vector of accesses corresponding to
842 the base. Finally, return the new access. */
844 static struct access *
845 create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
847 struct access *access = access_pool.allocate ();
849 memset (access, 0, sizeof (struct access));
851 access->offset = offset;
854 base_access_vec->get_or_insert (base).safe_push (access);
859 static bool maybe_add_sra_candidate (tree);
861 /* Create and insert access for EXPR. Return created access, or NULL if it is
862 not possible. Also scan for uses of constant pool as we go along and add
865 static struct access *
866 create_access (tree expr, gimple *stmt, bool write)
868 struct access *access;
869 poly_int64 poffset, psize, pmax_size;
870 HOST_WIDE_INT offset, size, max_size;
872 bool reverse, ptr, unscalarizable_region = false;
874 base = get_ref_base_and_extent (expr, &poffset, &psize, &pmax_size,
876 if (!poffset.is_constant (&offset)
877 || !psize.is_constant (&size)
878 || !pmax_size.is_constant (&max_size))
880 disqualify_candidate (base, "Encountered a polynomial-sized access.");
884 if (sra_mode == SRA_MODE_EARLY_IPA
885 && TREE_CODE (base) == MEM_REF)
887 base = get_ssa_base_param (TREE_OPERAND (base, 0));
895 /* For constant-pool entries, check we can substitute the constant value. */
896 if (constant_decl_p (base)
897 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA))
899 gcc_assert (!bitmap_bit_p (disqualified_constants, DECL_UID (base)));
901 && !is_gimple_reg_type (TREE_TYPE (expr))
902 && dump_file && (dump_flags & TDF_DETAILS))
904 /* This occurs in Ada with accesses to ARRAY_RANGE_REFs,
905 and elements of multidimensional arrays (which are
906 multi-element arrays in their own right). */
907 fprintf (dump_file, "Allowing non-reg-type load of part"
908 " of constant-pool entry: ");
909 print_generic_expr (dump_file, expr);
911 maybe_add_sra_candidate (base);
914 if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
917 if (sra_mode == SRA_MODE_EARLY_IPA)
919 if (size < 0 || size != max_size)
921 disqualify_candidate (base, "Encountered a variable sized access.");
924 if (TREE_CODE (expr) == COMPONENT_REF
925 && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))
927 disqualify_candidate (base, "Encountered a bit-field access.");
930 gcc_checking_assert ((offset % BITS_PER_UNIT) == 0);
933 mark_parm_dereference (base, offset + size, stmt);
937 if (size != max_size)
940 unscalarizable_region = true;
944 disqualify_candidate (base, "Encountered an unconstrained access.");
949 access = create_access_1 (base, offset, size);
951 access->type = TREE_TYPE (expr);
952 access->write = write;
953 access->grp_unscalarizable_region = unscalarizable_region;
955 access->reverse = reverse;
957 if (TREE_CODE (expr) == COMPONENT_REF
958 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1)))
959 access->non_addressable = 1;
965 /* Return true iff TYPE is scalarizable - i.e. a RECORD_TYPE or fixed-length
966 ARRAY_TYPE with fields that are either of gimple register types (excluding
967 bit-fields) or (recursively) scalarizable types. CONST_DECL must be true if
968 we are considering a decl from constant pool. If it is false, char arrays
972 scalarizable_type_p (tree type, bool const_decl)
974 gcc_assert (!is_gimple_reg_type (type));
975 if (type_contains_placeholder_p (type))
978 switch (TREE_CODE (type))
981 for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
982 if (TREE_CODE (fld) == FIELD_DECL)
984 tree ft = TREE_TYPE (fld);
986 if (DECL_BIT_FIELD (fld))
989 if (!is_gimple_reg_type (ft)
990 && !scalarizable_type_p (ft, const_decl))
998 HOST_WIDE_INT min_elem_size;
1002 min_elem_size = BITS_PER_UNIT;
1004 if (TYPE_DOMAIN (type) == NULL_TREE
1005 || !tree_fits_shwi_p (TYPE_SIZE (type))
1006 || !tree_fits_shwi_p (TYPE_SIZE (TREE_TYPE (type)))
1007 || (tree_to_shwi (TYPE_SIZE (TREE_TYPE (type))) <= min_elem_size)
1008 || !tree_fits_shwi_p (TYPE_MIN_VALUE (TYPE_DOMAIN (type))))
1010 if (tree_to_shwi (TYPE_SIZE (type)) == 0
1011 && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE)
1012 /* Zero-element array, should not prevent scalarization. */
1014 else if ((tree_to_shwi (TYPE_SIZE (type)) <= 0)
1015 || !tree_fits_shwi_p (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
1016 /* Variable-length array, do not allow scalarization. */
1019 tree elem = TREE_TYPE (type);
1020 if (!is_gimple_reg_type (elem)
1021 && !scalarizable_type_p (elem, const_decl))
1030 static void scalarize_elem (tree, HOST_WIDE_INT, HOST_WIDE_INT, bool, tree, tree);
1032 /* Create total_scalarization accesses for all scalar fields of a member
1033 of type DECL_TYPE conforming to scalarizable_type_p. BASE
1034 must be the top-most VAR_DECL representing the variable; within that,
1035 OFFSET locates the member and REF must be the memory reference expression for
1039 completely_scalarize (tree base, tree decl_type, HOST_WIDE_INT offset, tree ref)
1041 switch (TREE_CODE (decl_type))
1044 for (tree fld = TYPE_FIELDS (decl_type); fld; fld = DECL_CHAIN (fld))
1045 if (TREE_CODE (fld) == FIELD_DECL)
1047 HOST_WIDE_INT pos = offset + int_bit_position (fld);
1048 tree ft = TREE_TYPE (fld);
1049 tree nref = build3 (COMPONENT_REF, ft, ref, fld, NULL_TREE);
1051 scalarize_elem (base, pos, tree_to_uhwi (DECL_SIZE (fld)),
1052 TYPE_REVERSE_STORAGE_ORDER (decl_type),
1058 tree elemtype = TREE_TYPE (decl_type);
1059 tree elem_size = TYPE_SIZE (elemtype);
1060 gcc_assert (elem_size && tree_fits_shwi_p (elem_size));
1061 HOST_WIDE_INT el_size = tree_to_shwi (elem_size);
1062 gcc_assert (el_size > 0);
1064 tree minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (decl_type));
1065 gcc_assert (TREE_CODE (minidx) == INTEGER_CST);
1066 tree maxidx = TYPE_MAX_VALUE (TYPE_DOMAIN (decl_type));
1067 /* Skip (some) zero-length arrays; others have MAXIDX == MINIDX - 1. */
1070 gcc_assert (TREE_CODE (maxidx) == INTEGER_CST);
1071 tree domain = TYPE_DOMAIN (decl_type);
1072 /* MINIDX and MAXIDX are inclusive, and must be interpreted in
1073 DOMAIN (e.g. signed int, whereas min/max may be size_int). */
1074 offset_int idx = wi::to_offset (minidx);
1075 offset_int max = wi::to_offset (maxidx);
1076 if (!TYPE_UNSIGNED (domain))
1078 idx = wi::sext (idx, TYPE_PRECISION (domain));
1079 max = wi::sext (max, TYPE_PRECISION (domain));
1081 for (int el_off = offset; idx <= max; ++idx)
1083 tree nref = build4 (ARRAY_REF, elemtype,
1085 wide_int_to_tree (domain, idx),
1086 NULL_TREE, NULL_TREE);
1087 scalarize_elem (base, el_off, el_size,
1088 TYPE_REVERSE_STORAGE_ORDER (decl_type),
1100 /* Create total_scalarization accesses for a member of type TYPE, which must
1101 satisfy either is_gimple_reg_type or scalarizable_type_p. BASE must be the
1102 top-most VAR_DECL representing the variable; within that, POS and SIZE locate
1103 the member, REVERSE gives its torage order. and REF must be the reference
1104 expression for it. */
1107 scalarize_elem (tree base, HOST_WIDE_INT pos, HOST_WIDE_INT size, bool reverse,
1108 tree ref, tree type)
1110 if (is_gimple_reg_type (type))
1112 struct access *access = create_access_1 (base, pos, size);
1114 access->type = type;
1115 access->grp_total_scalarization = 1;
1116 access->reverse = reverse;
1117 /* Accesses for intraprocedural SRA can have their stmt NULL. */
1120 completely_scalarize (base, type, pos, ref);
1123 /* Create a total_scalarization access for VAR as a whole. VAR must be of a
1124 RECORD_TYPE or ARRAY_TYPE conforming to scalarizable_type_p. */
1127 create_total_scalarization_access (tree var)
1129 HOST_WIDE_INT size = tree_to_uhwi (DECL_SIZE (var));
1130 struct access *access;
1132 access = create_access_1 (var, 0, size);
1134 access->type = TREE_TYPE (var);
1135 access->grp_total_scalarization = 1;
1138 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1141 contains_view_convert_expr_p (const_tree ref)
1143 while (handled_component_p (ref))
1145 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
1147 ref = TREE_OPERAND (ref, 0);
1153 /* Return true if REF contains a VIEW_CONVERT_EXPR or a MEM_REF that performs
1154 type conversion or a COMPONENT_REF with a bit-field field declaration. */
1157 contains_vce_or_bfcref_p (const_tree ref)
1159 while (handled_component_p (ref))
1161 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
1162 || (TREE_CODE (ref) == COMPONENT_REF
1163 && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
1165 ref = TREE_OPERAND (ref, 0);
1168 if (TREE_CODE (ref) != MEM_REF
1169 || TREE_CODE (TREE_OPERAND (ref, 0)) != ADDR_EXPR)
1172 tree mem = TREE_OPERAND (TREE_OPERAND (ref, 0), 0);
1173 if (TYPE_MAIN_VARIANT (TREE_TYPE (ref))
1174 != TYPE_MAIN_VARIANT (TREE_TYPE (mem)))
1180 /* Search the given tree for a declaration by skipping handled components and
1181 exclude it from the candidates. */
1184 disqualify_base_of_expr (tree t, const char *reason)
1186 t = get_base_address (t);
1187 if (sra_mode == SRA_MODE_EARLY_IPA
1188 && TREE_CODE (t) == MEM_REF)
1189 t = get_ssa_base_param (TREE_OPERAND (t, 0));
1191 if (t && DECL_P (t))
1192 disqualify_candidate (t, reason);
1195 /* Scan expression EXPR and create access structures for all accesses to
1196 candidates for scalarization. Return the created access or NULL if none is
1199 static struct access *
1200 build_access_from_expr_1 (tree expr, gimple *stmt, bool write)
1202 struct access *ret = NULL;
1205 if (TREE_CODE (expr) == BIT_FIELD_REF
1206 || TREE_CODE (expr) == IMAGPART_EXPR
1207 || TREE_CODE (expr) == REALPART_EXPR)
1209 expr = TREE_OPERAND (expr, 0);
1213 partial_ref = false;
1215 if (storage_order_barrier_p (expr))
1217 disqualify_base_of_expr (expr, "storage order barrier.");
1221 /* We need to dive through V_C_Es in order to get the size of its parameter
1222 and not the result type. Ada produces such statements. We are also
1223 capable of handling the topmost V_C_E but not any of those buried in other
1224 handled components. */
1225 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
1226 expr = TREE_OPERAND (expr, 0);
1228 if (contains_view_convert_expr_p (expr))
1230 disqualify_base_of_expr (expr, "V_C_E under a different handled "
1234 if (TREE_THIS_VOLATILE (expr))
1236 disqualify_base_of_expr (expr, "part of a volatile reference.");
1240 switch (TREE_CODE (expr))
1243 if (TREE_CODE (TREE_OPERAND (expr, 0)) != ADDR_EXPR
1244 && sra_mode != SRA_MODE_EARLY_IPA)
1252 case ARRAY_RANGE_REF:
1253 ret = create_access (expr, stmt, write);
1260 if (write && partial_ref && ret)
1261 ret->grp_partial_lhs = 1;
1266 /* Scan expression EXPR and create access structures for all accesses to
1267 candidates for scalarization. Return true if any access has been inserted.
1268 STMT must be the statement from which the expression is taken, WRITE must be
1269 true if the expression is a store and false otherwise. */
1272 build_access_from_expr (tree expr, gimple *stmt, bool write)
1274 struct access *access;
1276 access = build_access_from_expr_1 (expr, stmt, write);
1279 /* This means the aggregate is accesses as a whole in a way other than an
1280 assign statement and thus cannot be removed even if we had a scalar
1281 replacement for everything. */
1282 if (cannot_scalarize_away_bitmap)
1283 bitmap_set_bit (cannot_scalarize_away_bitmap, DECL_UID (access->base));
1289 /* Return the single non-EH successor edge of BB or NULL if there is none or
1293 single_non_eh_succ (basic_block bb)
1298 FOR_EACH_EDGE (e, ei, bb->succs)
1299 if (!(e->flags & EDGE_EH))
1309 /* Disqualify LHS and RHS for scalarization if STMT has to terminate its BB and
1310 there is no alternative spot where to put statements SRA might need to
1311 generate after it. The spot we are looking for is an edge leading to a
1312 single non-EH successor, if it exists and is indeed single. RHS may be
1313 NULL, in that case ignore it. */
1316 disqualify_if_bad_bb_terminating_stmt (gimple *stmt, tree lhs, tree rhs)
1318 if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1319 && stmt_ends_bb_p (stmt))
1321 if (single_non_eh_succ (gimple_bb (stmt)))
1324 disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
1326 disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
1332 /* Return true if the nature of BASE is such that it contains data even if
1333 there is no write to it in the function. */
1336 comes_initialized_p (tree base)
1338 return TREE_CODE (base) == PARM_DECL || constant_decl_p (base);
1341 /* Scan expressions occurring in STMT, create access structures for all accesses
1342 to candidates for scalarization and remove those candidates which occur in
1343 statements or expressions that prevent them from being split apart. Return
1344 true if any access has been inserted. */
1347 build_accesses_from_assign (gimple *stmt)
1350 struct access *lacc, *racc;
1352 if (!gimple_assign_single_p (stmt)
1353 /* Scope clobbers don't influence scalarization. */
1354 || gimple_clobber_p (stmt))
1357 lhs = gimple_assign_lhs (stmt);
1358 rhs = gimple_assign_rhs1 (stmt);
1360 if (disqualify_if_bad_bb_terminating_stmt (stmt, lhs, rhs))
1363 racc = build_access_from_expr_1 (rhs, stmt, false);
1364 lacc = build_access_from_expr_1 (lhs, stmt, true);
1368 lacc->grp_assignment_write = 1;
1369 if (storage_order_barrier_p (rhs))
1370 lacc->grp_unscalarizable_region = 1;
1375 racc->grp_assignment_read = 1;
1376 if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
1377 && !is_gimple_reg_type (racc->type))
1379 if (contains_vce_or_bfcref_p (rhs))
1380 bitmap_set_bit (cannot_scalarize_away_bitmap,
1381 DECL_UID (racc->base));
1383 bitmap_set_bit (should_scalarize_away_bitmap,
1384 DECL_UID (racc->base));
1386 if (storage_order_barrier_p (lhs))
1387 racc->grp_unscalarizable_region = 1;
1391 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1392 && !lacc->grp_unscalarizable_region
1393 && !racc->grp_unscalarizable_region
1394 && AGGREGATE_TYPE_P (TREE_TYPE (lhs))
1395 && lacc->size == racc->size
1396 && useless_type_conversion_p (lacc->type, racc->type))
1398 struct assign_link *link;
1400 link = assign_link_pool.allocate ();
1401 memset (link, 0, sizeof (struct assign_link));
1405 add_link_to_rhs (racc, link);
1406 add_access_to_work_queue (racc);
1408 /* Let's delay marking the areas as written until propagation of accesses
1409 across link, unless the nature of rhs tells us that its data comes
1411 if (!comes_initialized_p (racc->base))
1412 lacc->write = false;
1415 return lacc || racc;
1418 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1419 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1422 asm_visit_addr (gimple *, tree op, tree, void *)
1424 op = get_base_address (op);
1427 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
1432 /* Return true iff callsite CALL has at least as many actual arguments as there
1433 are formal parameters of the function currently processed by IPA-SRA and
1434 that their types match. */
1437 callsite_arguments_match_p (gimple *call)
1439 if (gimple_call_num_args (call) < (unsigned) func_param_count)
1444 for (parm = DECL_ARGUMENTS (current_function_decl), i = 0;
1446 parm = DECL_CHAIN (parm), i++)
1448 tree arg = gimple_call_arg (call, i);
1449 if (!useless_type_conversion_p (TREE_TYPE (parm), TREE_TYPE (arg)))
1455 /* Scan function and look for interesting expressions and create access
1456 structures for them. Return true iff any access is created. */
1459 scan_function (void)
1464 FOR_EACH_BB_FN (bb, cfun)
1466 gimple_stmt_iterator gsi;
1467 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1469 gimple *stmt = gsi_stmt (gsi);
1473 if (final_bbs && stmt_can_throw_external (stmt))
1474 bitmap_set_bit (final_bbs, bb->index);
1475 switch (gimple_code (stmt))
1478 t = gimple_return_retval (as_a <greturn *> (stmt));
1480 ret |= build_access_from_expr (t, stmt, false);
1482 bitmap_set_bit (final_bbs, bb->index);
1486 ret |= build_accesses_from_assign (stmt);
1490 for (i = 0; i < gimple_call_num_args (stmt); i++)
1491 ret |= build_access_from_expr (gimple_call_arg (stmt, i),
1494 if (sra_mode == SRA_MODE_EARLY_IPA)
1496 tree dest = gimple_call_fndecl (stmt);
1497 int flags = gimple_call_flags (stmt);
1501 if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1502 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1503 encountered_apply_args = true;
1504 if (recursive_call_p (current_function_decl, dest))
1506 encountered_recursive_call = true;
1507 if (!callsite_arguments_match_p (stmt))
1508 encountered_unchangable_recursive_call = true;
1513 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1514 bitmap_set_bit (final_bbs, bb->index);
1517 t = gimple_call_lhs (stmt);
1518 if (t && !disqualify_if_bad_bb_terminating_stmt (stmt, t, NULL))
1519 ret |= build_access_from_expr (t, stmt, true);
1524 gasm *asm_stmt = as_a <gasm *> (stmt);
1525 walk_stmt_load_store_addr_ops (asm_stmt, NULL, NULL, NULL,
1528 bitmap_set_bit (final_bbs, bb->index);
1530 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
1532 t = TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
1533 ret |= build_access_from_expr (t, asm_stmt, false);
1535 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
1537 t = TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
1538 ret |= build_access_from_expr (t, asm_stmt, true);
1552 /* Helper of QSORT function. There are pointers to accesses in the array. An
1553 access is considered smaller than another if it has smaller offset or if the
1554 offsets are the same but is size is bigger. */
1557 compare_access_positions (const void *a, const void *b)
1559 const access_p *fp1 = (const access_p *) a;
1560 const access_p *fp2 = (const access_p *) b;
1561 const access_p f1 = *fp1;
1562 const access_p f2 = *fp2;
1564 if (f1->offset != f2->offset)
1565 return f1->offset < f2->offset ? -1 : 1;
1567 if (f1->size == f2->size)
1569 if (f1->type == f2->type)
1571 /* Put any non-aggregate type before any aggregate type. */
1572 else if (!is_gimple_reg_type (f1->type)
1573 && is_gimple_reg_type (f2->type))
1575 else if (is_gimple_reg_type (f1->type)
1576 && !is_gimple_reg_type (f2->type))
1578 /* Put any complex or vector type before any other scalar type. */
1579 else if (TREE_CODE (f1->type) != COMPLEX_TYPE
1580 && TREE_CODE (f1->type) != VECTOR_TYPE
1581 && (TREE_CODE (f2->type) == COMPLEX_TYPE
1582 || TREE_CODE (f2->type) == VECTOR_TYPE))
1584 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
1585 || TREE_CODE (f1->type) == VECTOR_TYPE)
1586 && TREE_CODE (f2->type) != COMPLEX_TYPE
1587 && TREE_CODE (f2->type) != VECTOR_TYPE)
1589 /* Put any integral type before any non-integral type. When splicing, we
1590 make sure that those with insufficient precision and occupying the
1591 same space are not scalarized. */
1592 else if (INTEGRAL_TYPE_P (f1->type)
1593 && !INTEGRAL_TYPE_P (f2->type))
1595 else if (!INTEGRAL_TYPE_P (f1->type)
1596 && INTEGRAL_TYPE_P (f2->type))
1598 /* Put the integral type with the bigger precision first. */
1599 else if (INTEGRAL_TYPE_P (f1->type)
1600 && INTEGRAL_TYPE_P (f2->type)
1601 && (TYPE_PRECISION (f2->type) != TYPE_PRECISION (f1->type)))
1602 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
1603 /* Stabilize the sort. */
1604 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1607 /* We want the bigger accesses first, thus the opposite operator in the next
1609 return f1->size > f2->size ? -1 : 1;
1613 /* Append a name of the declaration to the name obstack. A helper function for
1617 make_fancy_decl_name (tree decl)
1621 tree name = DECL_NAME (decl);
1623 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1624 IDENTIFIER_LENGTH (name));
1627 sprintf (buffer, "D%u", DECL_UID (decl));
1628 obstack_grow (&name_obstack, buffer, strlen (buffer));
1632 /* Helper for make_fancy_name. */
1635 make_fancy_name_1 (tree expr)
1642 make_fancy_decl_name (expr);
1646 switch (TREE_CODE (expr))
1649 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1650 obstack_1grow (&name_obstack, '$');
1651 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1655 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1656 obstack_1grow (&name_obstack, '$');
1657 /* Arrays with only one element may not have a constant as their
1659 index = TREE_OPERAND (expr, 1);
1660 if (TREE_CODE (index) != INTEGER_CST)
1662 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1663 obstack_grow (&name_obstack, buffer, strlen (buffer));
1667 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1671 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1672 if (!integer_zerop (TREE_OPERAND (expr, 1)))
1674 obstack_1grow (&name_obstack, '$');
1675 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC,
1676 TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)));
1677 obstack_grow (&name_obstack, buffer, strlen (buffer));
1684 gcc_unreachable (); /* we treat these as scalars. */
1691 /* Create a human readable name for replacement variable of ACCESS. */
1694 make_fancy_name (tree expr)
1696 make_fancy_name_1 (expr);
1697 obstack_1grow (&name_obstack, '\0');
1698 return XOBFINISH (&name_obstack, char *);
1701 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1702 EXP_TYPE at the given OFFSET and with storage order REVERSE. If BASE is
1703 something for which get_addr_base_and_unit_offset returns NULL, gsi must
1704 be non-NULL and is used to insert new statements either before or below
1705 the current one as specified by INSERT_AFTER. This function is not capable
1706 of handling bitfields. */
1709 build_ref_for_offset (location_t loc, tree base, poly_int64 offset,
1710 bool reverse, tree exp_type, gimple_stmt_iterator *gsi,
1713 tree prev_base = base;
1716 poly_int64 base_offset;
1717 unsigned HOST_WIDE_INT misalign;
1720 /* Preserve address-space information. */
1721 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (base));
1722 if (as != TYPE_ADDR_SPACE (exp_type))
1723 exp_type = build_qualified_type (exp_type,
1724 TYPE_QUALS (exp_type)
1725 | ENCODE_QUAL_ADDR_SPACE (as));
1727 poly_int64 byte_offset = exact_div (offset, BITS_PER_UNIT);
1728 get_object_alignment_1 (base, &align, &misalign);
1729 base = get_addr_base_and_unit_offset (base, &base_offset);
1731 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1732 offset such as array[var_index]. */
1738 gcc_checking_assert (gsi);
1739 tmp = make_ssa_name (build_pointer_type (TREE_TYPE (prev_base)));
1740 addr = build_fold_addr_expr (unshare_expr (prev_base));
1741 STRIP_USELESS_TYPE_CONVERSION (addr);
1742 stmt = gimple_build_assign (tmp, addr);
1743 gimple_set_location (stmt, loc);
1745 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
1747 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1749 off = build_int_cst (reference_alias_ptr_type (prev_base), byte_offset);
1752 else if (TREE_CODE (base) == MEM_REF)
1754 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1755 base_offset + byte_offset);
1756 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1757 base = unshare_expr (TREE_OPERAND (base, 0));
1761 off = build_int_cst (reference_alias_ptr_type (prev_base),
1762 base_offset + byte_offset);
1763 base = build_fold_addr_expr (unshare_expr (base));
1766 unsigned int align_bound = known_alignment (misalign + offset);
1767 if (align_bound != 0)
1768 align = MIN (align, align_bound);
1769 if (align != TYPE_ALIGN (exp_type))
1770 exp_type = build_aligned_type (exp_type, align);
1772 mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off);
1773 REF_REVERSE_STORAGE_ORDER (mem_ref) = reverse;
1774 if (TREE_THIS_VOLATILE (prev_base))
1775 TREE_THIS_VOLATILE (mem_ref) = 1;
1776 if (TREE_SIDE_EFFECTS (prev_base))
1777 TREE_SIDE_EFFECTS (mem_ref) = 1;
1781 /* Construct a memory reference to a part of an aggregate BASE at the given
1782 OFFSET and of the same type as MODEL. In case this is a reference to a
1783 bit-field, the function will replicate the last component_ref of model's
1784 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1785 build_ref_for_offset. */
1788 build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1789 struct access *model, gimple_stmt_iterator *gsi,
1792 if (TREE_CODE (model->expr) == COMPONENT_REF
1793 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1795 /* This access represents a bit-field. */
1796 tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
1798 offset -= int_bit_position (fld);
1799 exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
1800 t = build_ref_for_offset (loc, base, offset, model->reverse, exp_type,
1802 /* The flag will be set on the record type. */
1803 REF_REVERSE_STORAGE_ORDER (t) = 0;
1804 return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
1809 build_ref_for_offset (loc, base, offset, model->reverse, model->type,
1813 /* Attempt to build a memory reference that we could but into a gimple
1814 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1815 create statements and return s NULL instead. This function also ignores
1816 alignment issues and so its results should never end up in non-debug
1820 build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1821 struct access *model)
1823 poly_int64 base_offset;
1826 if (TREE_CODE (model->expr) == COMPONENT_REF
1827 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1830 base = get_addr_base_and_unit_offset (base, &base_offset);
1833 if (TREE_CODE (base) == MEM_REF)
1835 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1836 base_offset + offset / BITS_PER_UNIT);
1837 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1838 base = unshare_expr (TREE_OPERAND (base, 0));
1842 off = build_int_cst (reference_alias_ptr_type (base),
1843 base_offset + offset / BITS_PER_UNIT);
1844 base = build_fold_addr_expr (unshare_expr (base));
1847 return fold_build2_loc (loc, MEM_REF, model->type, base, off);
1850 /* Construct a memory reference consisting of component_refs and array_refs to
1851 a part of an aggregate *RES (which is of type TYPE). The requested part
1852 should have type EXP_TYPE at be the given OFFSET. This function might not
1853 succeed, it returns true when it does and only then *RES points to something
1854 meaningful. This function should be used only to build expressions that we
1855 might need to present to user (e.g. in warnings). In all other situations,
1856 build_ref_for_model or build_ref_for_offset should be used instead. */
1859 build_user_friendly_ref_for_offset (tree *res, tree type, HOST_WIDE_INT offset,
1865 tree tr_size, index, minidx;
1866 HOST_WIDE_INT el_size;
1868 if (offset == 0 && exp_type
1869 && types_compatible_p (exp_type, type))
1872 switch (TREE_CODE (type))
1875 case QUAL_UNION_TYPE:
1877 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
1879 HOST_WIDE_INT pos, size;
1880 tree tr_pos, expr, *expr_ptr;
1882 if (TREE_CODE (fld) != FIELD_DECL)
1885 tr_pos = bit_position (fld);
1886 if (!tr_pos || !tree_fits_uhwi_p (tr_pos))
1888 pos = tree_to_uhwi (tr_pos);
1889 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1890 tr_size = DECL_SIZE (fld);
1891 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1893 size = tree_to_uhwi (tr_size);
1899 else if (pos > offset || (pos + size) <= offset)
1902 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1905 if (build_user_friendly_ref_for_offset (expr_ptr, TREE_TYPE (fld),
1906 offset - pos, exp_type))
1915 tr_size = TYPE_SIZE (TREE_TYPE (type));
1916 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1918 el_size = tree_to_uhwi (tr_size);
1920 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1921 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
1923 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1924 if (!integer_zerop (minidx))
1925 index = int_const_binop (PLUS_EXPR, index, minidx);
1926 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1927 NULL_TREE, NULL_TREE);
1928 offset = offset % el_size;
1929 type = TREE_TYPE (type);
1944 /* Return true iff TYPE is stdarg va_list type. */
1947 is_va_list_type (tree type)
1949 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1952 /* Print message to dump file why a variable was rejected. */
1955 reject (tree var, const char *msg)
1957 if (dump_file && (dump_flags & TDF_DETAILS))
1959 fprintf (dump_file, "Rejected (%d): %s: ", DECL_UID (var), msg);
1960 print_generic_expr (dump_file, var);
1961 fprintf (dump_file, "\n");
1965 /* Return true if VAR is a candidate for SRA. */
1968 maybe_add_sra_candidate (tree var)
1970 tree type = TREE_TYPE (var);
1974 if (!AGGREGATE_TYPE_P (type))
1976 reject (var, "not aggregate");
1979 /* Allow constant-pool entries (that "need to live in memory")
1980 unless we are doing IPA SRA. */
1981 if (needs_to_live_in_memory (var)
1982 && (sra_mode == SRA_MODE_EARLY_IPA || !constant_decl_p (var)))
1984 reject (var, "needs to live in memory");
1987 if (TREE_THIS_VOLATILE (var))
1989 reject (var, "is volatile");
1992 if (!COMPLETE_TYPE_P (type))
1994 reject (var, "has incomplete type");
1997 if (!tree_fits_uhwi_p (TYPE_SIZE (type)))
1999 reject (var, "type size not fixed");
2002 if (tree_to_uhwi (TYPE_SIZE (type)) == 0)
2004 reject (var, "type size is zero");
2007 if (type_internals_preclude_sra_p (type, &msg))
2012 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
2013 we also want to schedule it rather late. Thus we ignore it in
2015 (sra_mode == SRA_MODE_EARLY_INTRA
2016 && is_va_list_type (type)))
2018 reject (var, "is va_list");
2022 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
2023 slot = candidates->find_slot_with_hash (var, DECL_UID (var), INSERT);
2026 if (dump_file && (dump_flags & TDF_DETAILS))
2028 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
2029 print_generic_expr (dump_file, var);
2030 fprintf (dump_file, "\n");
2036 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
2037 those with type which is suitable for scalarization. */
2040 find_var_candidates (void)
2046 for (parm = DECL_ARGUMENTS (current_function_decl);
2048 parm = DECL_CHAIN (parm))
2049 ret |= maybe_add_sra_candidate (parm);
2051 FOR_EACH_LOCAL_DECL (cfun, i, var)
2056 ret |= maybe_add_sra_candidate (var);
2062 /* Sort all accesses for the given variable, check for partial overlaps and
2063 return NULL if there are any. If there are none, pick a representative for
2064 each combination of offset and size and create a linked list out of them.
2065 Return the pointer to the first representative and make sure it is the first
2066 one in the vector of accesses. */
2068 static struct access *
2069 sort_and_splice_var_accesses (tree var)
2071 int i, j, access_count;
2072 struct access *res, **prev_acc_ptr = &res;
2073 vec<access_p> *access_vec;
2075 HOST_WIDE_INT low = -1, high = 0;
2077 access_vec = get_base_access_vector (var);
2080 access_count = access_vec->length ();
2082 /* Sort by <OFFSET, SIZE>. */
2083 access_vec->qsort (compare_access_positions);
2086 while (i < access_count)
2088 struct access *access = (*access_vec)[i];
2089 bool grp_write = access->write;
2090 bool grp_read = !access->write;
2091 bool grp_scalar_write = access->write
2092 && is_gimple_reg_type (access->type);
2093 bool grp_scalar_read = !access->write
2094 && is_gimple_reg_type (access->type);
2095 bool grp_assignment_read = access->grp_assignment_read;
2096 bool grp_assignment_write = access->grp_assignment_write;
2097 bool multiple_scalar_reads = false;
2098 bool total_scalarization = access->grp_total_scalarization;
2099 bool grp_partial_lhs = access->grp_partial_lhs;
2100 bool first_scalar = is_gimple_reg_type (access->type);
2101 bool unscalarizable_region = access->grp_unscalarizable_region;
2102 bool bf_non_full_precision
2103 = (INTEGRAL_TYPE_P (access->type)
2104 && TYPE_PRECISION (access->type) != access->size
2105 && TREE_CODE (access->expr) == COMPONENT_REF
2106 && DECL_BIT_FIELD (TREE_OPERAND (access->expr, 1)));
2108 if (first || access->offset >= high)
2111 low = access->offset;
2112 high = access->offset + access->size;
2114 else if (access->offset > low && access->offset + access->size > high)
2117 gcc_assert (access->offset >= low
2118 && access->offset + access->size <= high);
2121 while (j < access_count)
2123 struct access *ac2 = (*access_vec)[j];
2124 if (ac2->offset != access->offset || ac2->size != access->size)
2129 grp_scalar_write = (grp_scalar_write
2130 || is_gimple_reg_type (ac2->type));
2135 if (is_gimple_reg_type (ac2->type))
2137 if (grp_scalar_read)
2138 multiple_scalar_reads = true;
2140 grp_scalar_read = true;
2143 grp_assignment_read |= ac2->grp_assignment_read;
2144 grp_assignment_write |= ac2->grp_assignment_write;
2145 grp_partial_lhs |= ac2->grp_partial_lhs;
2146 unscalarizable_region |= ac2->grp_unscalarizable_region;
2147 total_scalarization |= ac2->grp_total_scalarization;
2148 relink_to_new_repr (access, ac2);
2150 /* If there are both aggregate-type and scalar-type accesses with
2151 this combination of size and offset, the comparison function
2152 should have put the scalars first. */
2153 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
2154 /* It also prefers integral types to non-integral. However, when the
2155 precision of the selected type does not span the entire area and
2156 should also be used for a non-integer (i.e. float), we must not
2157 let that happen. Normally analyze_access_subtree expands the type
2158 to cover the entire area but for bit-fields it doesn't. */
2159 if (bf_non_full_precision && !INTEGRAL_TYPE_P (ac2->type))
2161 if (dump_file && (dump_flags & TDF_DETAILS))
2163 fprintf (dump_file, "Cannot scalarize the following access "
2164 "because insufficient precision integer type was "
2166 dump_access (dump_file, access, false);
2168 unscalarizable_region = true;
2170 ac2->group_representative = access;
2176 access->group_representative = access;
2177 access->grp_write = grp_write;
2178 access->grp_read = grp_read;
2179 access->grp_scalar_read = grp_scalar_read;
2180 access->grp_scalar_write = grp_scalar_write;
2181 access->grp_assignment_read = grp_assignment_read;
2182 access->grp_assignment_write = grp_assignment_write;
2183 access->grp_hint = total_scalarization
2184 || (multiple_scalar_reads && !constant_decl_p (var));
2185 access->grp_total_scalarization = total_scalarization;
2186 access->grp_partial_lhs = grp_partial_lhs;
2187 access->grp_unscalarizable_region = unscalarizable_region;
2189 *prev_acc_ptr = access;
2190 prev_acc_ptr = &access->next_grp;
2193 gcc_assert (res == (*access_vec)[0]);
2197 /* Create a variable for the given ACCESS which determines the type, name and a
2198 few other properties. Return the variable declaration and store it also to
2199 ACCESS->replacement. */
2202 create_access_replacement (struct access *access)
2206 if (access->grp_to_be_debug_replaced)
2208 repl = create_tmp_var_raw (access->type);
2209 DECL_CONTEXT (repl) = current_function_decl;
2212 /* Drop any special alignment on the type if it's not on the main
2213 variant. This avoids issues with weirdo ABIs like AAPCS. */
2214 repl = create_tmp_var (build_qualified_type
2215 (TYPE_MAIN_VARIANT (access->type),
2216 TYPE_QUALS (access->type)), "SR");
2217 if (TREE_CODE (access->type) == COMPLEX_TYPE
2218 || TREE_CODE (access->type) == VECTOR_TYPE)
2220 if (!access->grp_partial_lhs)
2221 DECL_GIMPLE_REG_P (repl) = 1;
2223 else if (access->grp_partial_lhs
2224 && is_gimple_reg_type (access->type))
2225 TREE_ADDRESSABLE (repl) = 1;
2227 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
2228 DECL_ARTIFICIAL (repl) = 1;
2229 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
2231 if (DECL_NAME (access->base)
2232 && !DECL_IGNORED_P (access->base)
2233 && !DECL_ARTIFICIAL (access->base))
2235 char *pretty_name = make_fancy_name (access->expr);
2236 tree debug_expr = unshare_expr_without_location (access->expr), d;
2239 DECL_NAME (repl) = get_identifier (pretty_name);
2240 DECL_NAMELESS (repl) = 1;
2241 obstack_free (&name_obstack, pretty_name);
2243 /* Get rid of any SSA_NAMEs embedded in debug_expr,
2244 as DECL_DEBUG_EXPR isn't considered when looking for still
2245 used SSA_NAMEs and thus they could be freed. All debug info
2246 generation cares is whether something is constant or variable
2247 and that get_ref_base_and_extent works properly on the
2248 expression. It cannot handle accesses at a non-constant offset
2249 though, so just give up in those cases. */
2250 for (d = debug_expr;
2251 !fail && (handled_component_p (d) || TREE_CODE (d) == MEM_REF);
2252 d = TREE_OPERAND (d, 0))
2253 switch (TREE_CODE (d))
2256 case ARRAY_RANGE_REF:
2257 if (TREE_OPERAND (d, 1)
2258 && TREE_CODE (TREE_OPERAND (d, 1)) != INTEGER_CST)
2260 if (TREE_OPERAND (d, 3)
2261 && TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST)
2265 if (TREE_OPERAND (d, 2)
2266 && TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST)
2270 if (TREE_CODE (TREE_OPERAND (d, 0)) != ADDR_EXPR)
2273 d = TREE_OPERAND (d, 0);
2280 SET_DECL_DEBUG_EXPR (repl, debug_expr);
2281 DECL_HAS_DEBUG_EXPR_P (repl) = 1;
2283 if (access->grp_no_warning)
2284 TREE_NO_WARNING (repl) = 1;
2286 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
2289 TREE_NO_WARNING (repl) = 1;
2293 if (access->grp_to_be_debug_replaced)
2295 fprintf (dump_file, "Created a debug-only replacement for ");
2296 print_generic_expr (dump_file, access->base);
2297 fprintf (dump_file, " offset: %u, size: %u\n",
2298 (unsigned) access->offset, (unsigned) access->size);
2302 fprintf (dump_file, "Created a replacement for ");
2303 print_generic_expr (dump_file, access->base);
2304 fprintf (dump_file, " offset: %u, size: %u: ",
2305 (unsigned) access->offset, (unsigned) access->size);
2306 print_generic_expr (dump_file, repl);
2307 fprintf (dump_file, "\n");
2310 sra_stats.replacements++;
2315 /* Return ACCESS scalar replacement, which must exist. */
2318 get_access_replacement (struct access *access)
2320 gcc_checking_assert (access->replacement_decl);
2321 return access->replacement_decl;
2325 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2326 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2327 to it is not "within" the root. Return false iff some accesses partially
2331 build_access_subtree (struct access **access)
2333 struct access *root = *access, *last_child = NULL;
2334 HOST_WIDE_INT limit = root->offset + root->size;
2336 *access = (*access)->next_grp;
2337 while (*access && (*access)->offset + (*access)->size <= limit)
2340 root->first_child = *access;
2342 last_child->next_sibling = *access;
2343 last_child = *access;
2344 (*access)->parent = root;
2345 (*access)->grp_write |= root->grp_write;
2347 if (!build_access_subtree (access))
2351 if (*access && (*access)->offset < limit)
2357 /* Build a tree of access representatives, ACCESS is the pointer to the first
2358 one, others are linked in a list by the next_grp field. Return false iff
2359 some accesses partially overlap. */
2362 build_access_trees (struct access *access)
2366 struct access *root = access;
2368 if (!build_access_subtree (&access))
2370 root->next_grp = access;
2375 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2379 expr_with_var_bounded_array_refs_p (tree expr)
2381 while (handled_component_p (expr))
2383 if (TREE_CODE (expr) == ARRAY_REF
2384 && !tree_fits_shwi_p (array_ref_low_bound (expr)))
2386 expr = TREE_OPERAND (expr, 0);
2391 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2392 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2393 sorts of access flags appropriately along the way, notably always set
2394 grp_read and grp_assign_read according to MARK_READ and grp_write when
2397 Creating a replacement for a scalar access is considered beneficial if its
2398 grp_hint is set (this means we are either attempting total scalarization or
2399 there is more than one direct read access) or according to the following
2402 Access written to through a scalar type (once or more times)
2404 | Written to in an assignment statement
2406 | | Access read as scalar _once_
2408 | | | Read in an assignment statement
2410 | | | | Scalarize Comment
2411 -----------------------------------------------------------------------------
2412 0 0 0 0 No access for the scalar
2413 0 0 0 1 No access for the scalar
2414 0 0 1 0 No Single read - won't help
2415 0 0 1 1 No The same case
2416 0 1 0 0 No access for the scalar
2417 0 1 0 1 No access for the scalar
2418 0 1 1 0 Yes s = *g; return s.i;
2419 0 1 1 1 Yes The same case as above
2420 1 0 0 0 No Won't help
2421 1 0 0 1 Yes s.i = 1; *g = s;
2422 1 0 1 0 Yes s.i = 5; g = s.i;
2423 1 0 1 1 Yes The same case as above
2424 1 1 0 0 No Won't help.
2425 1 1 0 1 Yes s.i = 1; *g = s;
2426 1 1 1 0 Yes s = *g; return s.i;
2427 1 1 1 1 Yes Any of the above yeses */
2430 analyze_access_subtree (struct access *root, struct access *parent,
2431 bool allow_replacements)
2433 struct access *child;
2434 HOST_WIDE_INT limit = root->offset + root->size;
2435 HOST_WIDE_INT covered_to = root->offset;
2436 bool scalar = is_gimple_reg_type (root->type);
2437 bool hole = false, sth_created = false;
2441 if (parent->grp_read)
2443 if (parent->grp_assignment_read)
2444 root->grp_assignment_read = 1;
2445 if (parent->grp_write)
2446 root->grp_write = 1;
2447 if (parent->grp_assignment_write)
2448 root->grp_assignment_write = 1;
2449 if (parent->grp_total_scalarization)
2450 root->grp_total_scalarization = 1;
2453 if (root->grp_unscalarizable_region)
2454 allow_replacements = false;
2456 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
2457 allow_replacements = false;
2459 for (child = root->first_child; child; child = child->next_sibling)
2461 hole |= covered_to < child->offset;
2462 sth_created |= analyze_access_subtree (child, root,
2463 allow_replacements && !scalar);
2465 root->grp_unscalarized_data |= child->grp_unscalarized_data;
2466 root->grp_total_scalarization &= child->grp_total_scalarization;
2467 if (child->grp_covered)
2468 covered_to += child->size;
2473 if (allow_replacements && scalar && !root->first_child
2475 || ((root->grp_scalar_read || root->grp_assignment_read)
2476 && (root->grp_scalar_write || root->grp_assignment_write))))
2478 /* Always create access replacements that cover the whole access.
2479 For integral types this means the precision has to match.
2480 Avoid assumptions based on the integral type kind, too. */
2481 if (INTEGRAL_TYPE_P (root->type)
2482 && (TREE_CODE (root->type) != INTEGER_TYPE
2483 || TYPE_PRECISION (root->type) != root->size)
2484 /* But leave bitfield accesses alone. */
2485 && (TREE_CODE (root->expr) != COMPONENT_REF
2486 || !DECL_BIT_FIELD (TREE_OPERAND (root->expr, 1))))
2488 tree rt = root->type;
2489 gcc_assert ((root->offset % BITS_PER_UNIT) == 0
2490 && (root->size % BITS_PER_UNIT) == 0);
2491 root->type = build_nonstandard_integer_type (root->size,
2492 TYPE_UNSIGNED (rt));
2493 root->expr = build_ref_for_offset (UNKNOWN_LOCATION, root->base,
2494 root->offset, root->reverse,
2495 root->type, NULL, false);
2497 if (dump_file && (dump_flags & TDF_DETAILS))
2499 fprintf (dump_file, "Changing the type of a replacement for ");
2500 print_generic_expr (dump_file, root->base);
2501 fprintf (dump_file, " offset: %u, size: %u ",
2502 (unsigned) root->offset, (unsigned) root->size);
2503 fprintf (dump_file, " to an integer.\n");
2507 root->grp_to_be_replaced = 1;
2508 root->replacement_decl = create_access_replacement (root);
2514 if (allow_replacements
2515 && scalar && !root->first_child
2516 && (root->grp_scalar_write || root->grp_assignment_write)
2517 && !bitmap_bit_p (cannot_scalarize_away_bitmap,
2518 DECL_UID (root->base)))
2520 gcc_checking_assert (!root->grp_scalar_read
2521 && !root->grp_assignment_read);
2523 if (MAY_HAVE_DEBUG_BIND_STMTS)
2525 root->grp_to_be_debug_replaced = 1;
2526 root->replacement_decl = create_access_replacement (root);
2530 if (covered_to < limit)
2532 if (scalar || !allow_replacements)
2533 root->grp_total_scalarization = 0;
2536 if (!hole || root->grp_total_scalarization)
2537 root->grp_covered = 1;
2538 else if (root->grp_write || comes_initialized_p (root->base))
2539 root->grp_unscalarized_data = 1; /* not covered and written to */
2543 /* Analyze all access trees linked by next_grp by the means of
2544 analyze_access_subtree. */
2546 analyze_access_trees (struct access *access)
2552 if (analyze_access_subtree (access, NULL, true))
2554 access = access->next_grp;
2560 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2561 SIZE would conflict with an already existing one. If exactly such a child
2562 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2565 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
2566 HOST_WIDE_INT size, struct access **exact_match)
2568 struct access *child;
2570 for (child = lacc->first_child; child; child = child->next_sibling)
2572 if (child->offset == norm_offset && child->size == size)
2574 *exact_match = child;
2578 if (child->offset < norm_offset + size
2579 && child->offset + child->size > norm_offset)
2586 /* Create a new child access of PARENT, with all properties just like MODEL
2587 except for its offset and with its grp_write false and grp_read true.
2588 Return the new access or NULL if it cannot be created. Note that this
2589 access is created long after all splicing and sorting, it's not located in
2590 any access vector and is automatically a representative of its group. Set
2591 the gpr_write flag of the new accesss if SET_GRP_WRITE is true. */
2593 static struct access *
2594 create_artificial_child_access (struct access *parent, struct access *model,
2595 HOST_WIDE_INT new_offset,
2598 struct access **child;
2599 tree expr = parent->base;
2601 gcc_assert (!model->grp_unscalarizable_region);
2603 struct access *access = access_pool.allocate ();
2604 memset (access, 0, sizeof (struct access));
2605 if (!build_user_friendly_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
2608 access->grp_no_warning = true;
2609 expr = build_ref_for_model (EXPR_LOCATION (parent->base), parent->base,
2610 new_offset, model, NULL, false);
2613 access->base = parent->base;
2614 access->expr = expr;
2615 access->offset = new_offset;
2616 access->size = model->size;
2617 access->type = model->type;
2618 access->grp_write = set_grp_write;
2619 access->grp_read = false;
2620 access->reverse = model->reverse;
2622 child = &parent->first_child;
2623 while (*child && (*child)->offset < new_offset)
2624 child = &(*child)->next_sibling;
2626 access->next_sibling = *child;
2633 /* Beginning with ACCESS, traverse its whole access subtree and mark all
2634 sub-trees as written to. If any of them has not been marked so previously
2635 and has assignment links leading from it, re-enqueue it. */
2638 subtree_mark_written_and_enqueue (struct access *access)
2640 if (access->grp_write)
2642 access->grp_write = true;
2643 add_access_to_work_queue (access);
2645 struct access *child;
2646 for (child = access->first_child; child; child = child->next_sibling)
2647 subtree_mark_written_and_enqueue (child);
2650 /* Propagate subaccesses and grp_write flags of RACC across an assignment link
2651 to LACC. Enqueue sub-accesses as necessary so that the write flag is
2652 propagated transitively. Return true if anything changed. Additionally, if
2653 RACC is a scalar access but LACC is not, change the type of the latter, if
2657 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
2659 struct access *rchild;
2660 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
2663 /* IF the LHS is still not marked as being written to, we only need to do so
2664 if the RHS at this level actually was. */
2665 if (!lacc->grp_write)
2667 gcc_checking_assert (!comes_initialized_p (racc->base));
2668 if (racc->grp_write)
2670 subtree_mark_written_and_enqueue (lacc);
2675 if (is_gimple_reg_type (lacc->type)
2676 || lacc->grp_unscalarizable_region
2677 || racc->grp_unscalarizable_region)
2679 if (!lacc->grp_write)
2682 subtree_mark_written_and_enqueue (lacc);
2687 if (is_gimple_reg_type (racc->type))
2689 if (!lacc->grp_write)
2692 subtree_mark_written_and_enqueue (lacc);
2694 if (!lacc->first_child && !racc->first_child)
2696 tree t = lacc->base;
2698 lacc->type = racc->type;
2699 if (build_user_friendly_ref_for_offset (&t, TREE_TYPE (t),
2700 lacc->offset, racc->type))
2704 lacc->expr = build_ref_for_model (EXPR_LOCATION (lacc->base),
2705 lacc->base, lacc->offset,
2707 lacc->grp_no_warning = true;
2713 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
2715 struct access *new_acc = NULL;
2716 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
2718 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
2723 if (!new_acc->grp_write && rchild->grp_write)
2725 gcc_assert (!lacc->grp_write);
2726 subtree_mark_written_and_enqueue (new_acc);
2730 rchild->grp_hint = 1;
2731 new_acc->grp_hint |= new_acc->grp_read;
2732 if (rchild->first_child
2733 && propagate_subaccesses_across_link (new_acc, rchild))
2736 add_access_to_work_queue (new_acc);
2741 if (!lacc->grp_write)
2744 subtree_mark_written_and_enqueue (lacc);
2750 if (rchild->grp_unscalarizable_region)
2752 if (rchild->grp_write && !lacc->grp_write)
2755 subtree_mark_written_and_enqueue (lacc);
2760 rchild->grp_hint = 1;
2761 new_acc = create_artificial_child_access (lacc, rchild, norm_offset,
2763 || rchild->grp_write);
2764 gcc_checking_assert (new_acc);
2765 if (racc->first_child)
2766 propagate_subaccesses_across_link (new_acc, rchild);
2768 add_access_to_work_queue (lacc);
2775 /* Propagate all subaccesses across assignment links. */
2778 propagate_all_subaccesses (void)
2780 while (work_queue_head)
2782 struct access *racc = pop_access_from_work_queue ();
2783 struct assign_link *link;
2785 if (racc->group_representative)
2786 racc= racc->group_representative;
2787 gcc_assert (racc->first_link);
2789 for (link = racc->first_link; link; link = link->next)
2791 struct access *lacc = link->lacc;
2793 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
2795 lacc = lacc->group_representative;
2797 bool reque_parents = false;
2798 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (racc->base)))
2800 if (!lacc->grp_write)
2802 subtree_mark_written_and_enqueue (lacc);
2803 reque_parents = true;
2806 else if (propagate_subaccesses_across_link (lacc, racc))
2807 reque_parents = true;
2812 add_access_to_work_queue (lacc);
2813 lacc = lacc->parent;
2820 /* Go through all accesses collected throughout the (intraprocedural) analysis
2821 stage, exclude overlapping ones, identify representatives and build trees
2822 out of them, making decisions about scalarization on the way. Return true
2823 iff there are any to-be-scalarized variables after this stage. */
2826 analyze_all_variable_accesses (void)
2829 bitmap tmp = BITMAP_ALLOC (NULL);
2832 bool optimize_speed_p = !optimize_function_for_size_p (cfun);
2834 enum compiler_param param = optimize_speed_p
2835 ? PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED
2836 : PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE;
2838 /* If the user didn't set PARAM_SRA_MAX_SCALARIZATION_SIZE_<...>,
2839 fall back to a target default. */
2840 unsigned HOST_WIDE_INT max_scalarization_size
2841 = global_options_set.x_param_values[param]
2842 ? PARAM_VALUE (param)
2843 : get_move_ratio (optimize_speed_p) * UNITS_PER_WORD;
2845 max_scalarization_size *= BITS_PER_UNIT;
2847 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
2848 if (bitmap_bit_p (should_scalarize_away_bitmap, i)
2849 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
2851 tree var = candidate (i);
2853 if (VAR_P (var) && scalarizable_type_p (TREE_TYPE (var),
2854 constant_decl_p (var)))
2856 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var)))
2857 <= max_scalarization_size)
2859 create_total_scalarization_access (var);
2860 completely_scalarize (var, TREE_TYPE (var), 0, var);
2861 statistics_counter_event (cfun,
2862 "Totally-scalarized aggregates", 1);
2863 if (dump_file && (dump_flags & TDF_DETAILS))
2865 fprintf (dump_file, "Will attempt to totally scalarize ");
2866 print_generic_expr (dump_file, var);
2867 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2870 else if (dump_file && (dump_flags & TDF_DETAILS))
2872 fprintf (dump_file, "Too big to totally scalarize: ");
2873 print_generic_expr (dump_file, var);
2874 fprintf (dump_file, " (UID: %u)\n", DECL_UID (var));
2879 bitmap_copy (tmp, candidate_bitmap);
2880 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2882 tree var = candidate (i);
2883 struct access *access;
2885 access = sort_and_splice_var_accesses (var);
2886 if (!access || !build_access_trees (access))
2887 disqualify_candidate (var,
2888 "No or inhibitingly overlapping accesses.");
2891 propagate_all_subaccesses ();
2893 bitmap_copy (tmp, candidate_bitmap);
2894 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2896 tree var = candidate (i);
2897 struct access *access = get_first_repr_for_decl (var);
2899 if (analyze_access_trees (access))
2902 if (dump_file && (dump_flags & TDF_DETAILS))
2904 fprintf (dump_file, "\nAccess trees for ");
2905 print_generic_expr (dump_file, var);
2906 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2907 dump_access_tree (dump_file, access);
2908 fprintf (dump_file, "\n");
2912 disqualify_candidate (var, "No scalar replacements to be created.");
2919 statistics_counter_event (cfun, "Scalarized aggregates", res);
2926 /* Generate statements copying scalar replacements of accesses within a subtree
2927 into or out of AGG. ACCESS, all its children, siblings and their children
2928 are to be processed. AGG is an aggregate type expression (can be a
2929 declaration but does not have to be, it can for example also be a mem_ref or
2930 a series of handled components). TOP_OFFSET is the offset of the processed
2931 subtree which has to be subtracted from offsets of individual accesses to
2932 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2933 replacements in the interval <start_offset, start_offset + chunk_size>,
2934 otherwise copy all. GSI is a statement iterator used to place the new
2935 statements. WRITE should be true when the statements should write from AGG
2936 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2937 statements will be added after the current statement in GSI, they will be
2938 added before the statement otherwise. */
2941 generate_subtree_copies (struct access *access, tree agg,
2942 HOST_WIDE_INT top_offset,
2943 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
2944 gimple_stmt_iterator *gsi, bool write,
2945 bool insert_after, location_t loc)
2947 /* Never write anything into constant pool decls. See PR70602. */
2948 if (!write && constant_decl_p (agg))
2952 if (chunk_size && access->offset >= start_offset + chunk_size)
2955 if (access->grp_to_be_replaced
2957 || access->offset + access->size > start_offset))
2959 tree expr, repl = get_access_replacement (access);
2962 expr = build_ref_for_model (loc, agg, access->offset - top_offset,
2963 access, gsi, insert_after);
2967 if (access->grp_partial_lhs)
2968 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
2970 insert_after ? GSI_NEW_STMT
2972 stmt = gimple_build_assign (repl, expr);
2976 TREE_NO_WARNING (repl) = 1;
2977 if (access->grp_partial_lhs)
2978 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2980 insert_after ? GSI_NEW_STMT
2982 stmt = gimple_build_assign (expr, repl);
2984 gimple_set_location (stmt, loc);
2987 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2989 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2991 sra_stats.subtree_copies++;
2994 && access->grp_to_be_debug_replaced
2996 || access->offset + access->size > start_offset))
2999 tree drhs = build_debug_ref_for_model (loc, agg,
3000 access->offset - top_offset,
3002 ds = gimple_build_debug_bind (get_access_replacement (access),
3003 drhs, gsi_stmt (*gsi));
3005 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
3007 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3010 if (access->first_child)
3011 generate_subtree_copies (access->first_child, agg, top_offset,
3012 start_offset, chunk_size, gsi,
3013 write, insert_after, loc);
3015 access = access->next_sibling;
3020 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
3021 root of the subtree to be processed. GSI is the statement iterator used
3022 for inserting statements which are added after the current statement if
3023 INSERT_AFTER is true or before it otherwise. */
3026 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
3027 bool insert_after, location_t loc)
3030 struct access *child;
3032 if (access->grp_to_be_replaced)
3036 stmt = gimple_build_assign (get_access_replacement (access),
3037 build_zero_cst (access->type));
3039 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
3041 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
3043 gimple_set_location (stmt, loc);
3045 else if (access->grp_to_be_debug_replaced)
3048 = gimple_build_debug_bind (get_access_replacement (access),
3049 build_zero_cst (access->type),
3052 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
3054 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3057 for (child = access->first_child; child; child = child->next_sibling)
3058 init_subtree_with_zero (child, gsi, insert_after, loc);
3061 /* Clobber all scalar replacements in an access subtree. ACCESS is the
3062 root of the subtree to be processed. GSI is the statement iterator used
3063 for inserting statements which are added after the current statement if
3064 INSERT_AFTER is true or before it otherwise. */
3067 clobber_subtree (struct access *access, gimple_stmt_iterator *gsi,
3068 bool insert_after, location_t loc)
3071 struct access *child;
3073 if (access->grp_to_be_replaced)
3075 tree rep = get_access_replacement (access);
3076 tree clobber = build_constructor (access->type, NULL);
3077 TREE_THIS_VOLATILE (clobber) = 1;
3078 gimple *stmt = gimple_build_assign (rep, clobber);
3081 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
3083 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
3085 gimple_set_location (stmt, loc);
3088 for (child = access->first_child; child; child = child->next_sibling)
3089 clobber_subtree (child, gsi, insert_after, loc);
3092 /* Search for an access representative for the given expression EXPR and
3093 return it or NULL if it cannot be found. */
3095 static struct access *
3096 get_access_for_expr (tree expr)
3098 poly_int64 poffset, psize, pmax_size;
3099 HOST_WIDE_INT offset, max_size;
3103 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
3104 a different size than the size of its argument and we need the latter
3106 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
3107 expr = TREE_OPERAND (expr, 0);
3109 base = get_ref_base_and_extent (expr, &poffset, &psize, &pmax_size,
3111 if (!known_size_p (pmax_size)
3112 || !pmax_size.is_constant (&max_size)
3113 || !poffset.is_constant (&offset)
3117 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
3120 return get_var_base_offset_size_access (base, offset, max_size);
3123 /* Replace the expression EXPR with a scalar replacement if there is one and
3124 generate other statements to do type conversion or subtree copying if
3125 necessary. GSI is used to place newly created statements, WRITE is true if
3126 the expression is being written to (it is on a LHS of a statement or output
3127 in an assembly statement). */
3130 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
3133 struct access *access;
3134 tree type, bfr, orig_expr;
3136 if (TREE_CODE (*expr) == BIT_FIELD_REF)
3139 expr = &TREE_OPERAND (*expr, 0);
3144 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
3145 expr = &TREE_OPERAND (*expr, 0);
3146 access = get_access_for_expr (*expr);
3149 type = TREE_TYPE (*expr);
3152 loc = gimple_location (gsi_stmt (*gsi));
3153 gimple_stmt_iterator alt_gsi = gsi_none ();
3154 if (write && stmt_ends_bb_p (gsi_stmt (*gsi)))
3156 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
3160 if (access->grp_to_be_replaced)
3162 tree repl = get_access_replacement (access);
3163 /* If we replace a non-register typed access simply use the original
3164 access expression to extract the scalar component afterwards.
3165 This happens if scalarizing a function return value or parameter
3166 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
3167 gcc.c-torture/compile/20011217-1.c.
3169 We also want to use this when accessing a complex or vector which can
3170 be accessed as a different type too, potentially creating a need for
3171 type conversion (see PR42196) and when scalarized unions are involved
3172 in assembler statements (see PR42398). */
3173 if (!useless_type_conversion_p (type, access->type))
3177 ref = build_ref_for_model (loc, orig_expr, 0, access, gsi, false);
3183 if (access->grp_partial_lhs)
3184 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
3185 false, GSI_NEW_STMT);
3186 stmt = gimple_build_assign (repl, ref);
3187 gimple_set_location (stmt, loc);
3188 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
3194 if (access->grp_partial_lhs)
3195 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
3196 true, GSI_SAME_STMT);
3197 stmt = gimple_build_assign (ref, repl);
3198 gimple_set_location (stmt, loc);
3199 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
3206 else if (write && access->grp_to_be_debug_replaced)
3208 gdebug *ds = gimple_build_debug_bind (get_access_replacement (access),
3211 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
3214 if (access->first_child)
3216 HOST_WIDE_INT start_offset, chunk_size;
3218 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 1))
3219 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 2)))
3221 chunk_size = tree_to_uhwi (TREE_OPERAND (bfr, 1));
3222 start_offset = access->offset
3223 + tree_to_uhwi (TREE_OPERAND (bfr, 2));
3226 start_offset = chunk_size = 0;
3228 generate_subtree_copies (access->first_child, orig_expr, access->offset,
3229 start_offset, chunk_size, gsi, write, write,
3235 /* Where scalar replacements of the RHS have been written to when a replacement
3236 of a LHS of an assigments cannot be direclty loaded from a replacement of
3238 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
3239 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
3240 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
3242 struct subreplacement_assignment_data
3244 /* Offset of the access representing the lhs of the assignment. */
3245 HOST_WIDE_INT left_offset;
3247 /* LHS and RHS of the original assignment. */
3248 tree assignment_lhs, assignment_rhs;
3250 /* Access representing the rhs of the whole assignment. */
3251 struct access *top_racc;
3253 /* Stmt iterator used for statement insertions after the original assignment.
3254 It points to the main GSI used to traverse a BB during function body
3256 gimple_stmt_iterator *new_gsi;
3258 /* Stmt iterator used for statement insertions before the original
3259 assignment. Keeps on pointing to the original statement. */
3260 gimple_stmt_iterator old_gsi;
3262 /* Location of the assignment. */
3265 /* Keeps the information whether we have needed to refresh replacements of
3266 the LHS and from which side of the assignments this takes place. */
3267 enum unscalarized_data_handling refreshed;
3270 /* Store all replacements in the access tree rooted in TOP_RACC either to their
3271 base aggregate if there are unscalarized data or directly to LHS of the
3272 statement that is pointed to by GSI otherwise. */
3275 handle_unscalarized_data_in_subtree (struct subreplacement_assignment_data *sad)
3278 if (sad->top_racc->grp_unscalarized_data)
3280 src = sad->assignment_rhs;
3281 sad->refreshed = SRA_UDH_RIGHT;
3285 src = sad->assignment_lhs;
3286 sad->refreshed = SRA_UDH_LEFT;
3288 generate_subtree_copies (sad->top_racc->first_child, src,
3289 sad->top_racc->offset, 0, 0,
3290 &sad->old_gsi, false, false, sad->loc);
3293 /* Try to generate statements to load all sub-replacements in an access subtree
3294 formed by children of LACC from scalar replacements in the SAD->top_racc
3295 subtree. If that is not possible, refresh the SAD->top_racc base aggregate
3296 and load the accesses from it. */
3299 load_assign_lhs_subreplacements (struct access *lacc,
3300 struct subreplacement_assignment_data *sad)
3302 for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling)
3304 HOST_WIDE_INT offset;
3305 offset = lacc->offset - sad->left_offset + sad->top_racc->offset;
3307 if (lacc->grp_to_be_replaced)
3309 struct access *racc;
3313 racc = find_access_in_subtree (sad->top_racc, offset, lacc->size);
3314 if (racc && racc->grp_to_be_replaced)
3316 rhs = get_access_replacement (racc);
3317 if (!useless_type_conversion_p (lacc->type, racc->type))
3318 rhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
3321 if (racc->grp_partial_lhs && lacc->grp_partial_lhs)
3322 rhs = force_gimple_operand_gsi (&sad->old_gsi, rhs, true,
3323 NULL_TREE, true, GSI_SAME_STMT);
3327 /* No suitable access on the right hand side, need to load from
3328 the aggregate. See if we have to update it first... */
3329 if (sad->refreshed == SRA_UDH_NONE)
3330 handle_unscalarized_data_in_subtree (sad);
3332 if (sad->refreshed == SRA_UDH_LEFT)
3333 rhs = build_ref_for_model (sad->loc, sad->assignment_lhs,
3334 lacc->offset - sad->left_offset,
3335 lacc, sad->new_gsi, true);
3337 rhs = build_ref_for_model (sad->loc, sad->assignment_rhs,
3338 lacc->offset - sad->left_offset,
3339 lacc, sad->new_gsi, true);
3340 if (lacc->grp_partial_lhs)
3341 rhs = force_gimple_operand_gsi (sad->new_gsi,
3342 rhs, true, NULL_TREE,
3343 false, GSI_NEW_STMT);
3346 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
3347 gsi_insert_after (sad->new_gsi, stmt, GSI_NEW_STMT);
3348 gimple_set_location (stmt, sad->loc);
3350 sra_stats.subreplacements++;
3354 if (sad->refreshed == SRA_UDH_NONE
3355 && lacc->grp_read && !lacc->grp_covered)
3356 handle_unscalarized_data_in_subtree (sad);
3358 if (lacc && lacc->grp_to_be_debug_replaced)
3362 struct access *racc = find_access_in_subtree (sad->top_racc,
3366 if (racc && racc->grp_to_be_replaced)
3368 if (racc->grp_write || constant_decl_p (racc->base))
3369 drhs = get_access_replacement (racc);
3373 else if (sad->refreshed == SRA_UDH_LEFT)
3374 drhs = build_debug_ref_for_model (sad->loc, lacc->base,
3375 lacc->offset, lacc);
3376 else if (sad->refreshed == SRA_UDH_RIGHT)
3377 drhs = build_debug_ref_for_model (sad->loc, sad->top_racc->base,
3382 && !useless_type_conversion_p (lacc->type, TREE_TYPE (drhs)))
3383 drhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
3385 ds = gimple_build_debug_bind (get_access_replacement (lacc),
3386 drhs, gsi_stmt (sad->old_gsi));
3387 gsi_insert_after (sad->new_gsi, ds, GSI_NEW_STMT);
3391 if (lacc->first_child)
3392 load_assign_lhs_subreplacements (lacc, sad);
3396 /* Result code for SRA assignment modification. */
3397 enum assignment_mod_result { SRA_AM_NONE, /* nothing done for the stmt */
3398 SRA_AM_MODIFIED, /* stmt changed but not
3400 SRA_AM_REMOVED }; /* stmt eliminated */
3402 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
3403 to the assignment and GSI is the statement iterator pointing at it. Returns
3404 the same values as sra_modify_assign. */
3406 static enum assignment_mod_result
3407 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3409 tree lhs = gimple_assign_lhs (stmt);
3410 struct access *acc = get_access_for_expr (lhs);
3413 location_t loc = gimple_location (stmt);
3415 if (gimple_clobber_p (stmt))
3417 /* Clobber the replacement variable. */
3418 clobber_subtree (acc, gsi, !acc->grp_covered, loc);
3419 /* Remove clobbers of fully scalarized variables, they are dead. */
3420 if (acc->grp_covered)
3422 unlink_stmt_vdef (stmt);
3423 gsi_remove (gsi, true);
3424 release_defs (stmt);
3425 return SRA_AM_REMOVED;
3428 return SRA_AM_MODIFIED;
3431 if (CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt)) > 0)
3433 /* I have never seen this code path trigger but if it can happen the
3434 following should handle it gracefully. */
3435 if (access_has_children_p (acc))
3436 generate_subtree_copies (acc->first_child, lhs, acc->offset, 0, 0, gsi,
3438 return SRA_AM_MODIFIED;
3441 if (acc->grp_covered)
3443 init_subtree_with_zero (acc, gsi, false, loc);
3444 unlink_stmt_vdef (stmt);
3445 gsi_remove (gsi, true);
3446 release_defs (stmt);
3447 return SRA_AM_REMOVED;
3451 init_subtree_with_zero (acc, gsi, true, loc);
3452 return SRA_AM_MODIFIED;
3456 /* Create and return a new suitable default definition SSA_NAME for RACC which
3457 is an access describing an uninitialized part of an aggregate that is being
3461 get_repl_default_def_ssa_name (struct access *racc)
3463 gcc_checking_assert (!racc->grp_to_be_replaced
3464 && !racc->grp_to_be_debug_replaced);
3465 if (!racc->replacement_decl)
3466 racc->replacement_decl = create_access_replacement (racc);
3467 return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
3470 /* Examine both sides of the assignment statement pointed to by STMT, replace
3471 them with a scalare replacement if there is one and generate copying of
3472 replacements if scalarized aggregates have been used in the assignment. GSI
3473 is used to hold generated statements for type conversions and subtree
3476 static enum assignment_mod_result
3477 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3479 struct access *lacc, *racc;
3481 bool modify_this_stmt = false;
3482 bool force_gimple_rhs = false;
3484 gimple_stmt_iterator orig_gsi = *gsi;
3486 if (!gimple_assign_single_p (stmt))
3488 lhs = gimple_assign_lhs (stmt);
3489 rhs = gimple_assign_rhs1 (stmt);
3491 if (TREE_CODE (rhs) == CONSTRUCTOR)
3492 return sra_modify_constructor_assign (stmt, gsi);
3494 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
3495 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
3496 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
3498 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (stmt),
3500 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (stmt),
3502 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3505 lacc = get_access_for_expr (lhs);
3506 racc = get_access_for_expr (rhs);
3509 /* Avoid modifying initializations of constant-pool replacements. */
3510 if (racc && (racc->replacement_decl == lhs))
3513 loc = gimple_location (stmt);
3514 if (lacc && lacc->grp_to_be_replaced)
3516 lhs = get_access_replacement (lacc);
3517 gimple_assign_set_lhs (stmt, lhs);
3518 modify_this_stmt = true;
3519 if (lacc->grp_partial_lhs)
3520 force_gimple_rhs = true;
3524 if (racc && racc->grp_to_be_replaced)
3526 rhs = get_access_replacement (racc);
3527 modify_this_stmt = true;
3528 if (racc->grp_partial_lhs)
3529 force_gimple_rhs = true;
3533 && !racc->grp_unscalarized_data
3534 && !racc->grp_unscalarizable_region
3535 && TREE_CODE (lhs) == SSA_NAME
3536 && !access_has_replacements_p (racc))
3538 rhs = get_repl_default_def_ssa_name (racc);
3539 modify_this_stmt = true;
3543 if (modify_this_stmt)
3545 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3547 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3548 ??? This should move to fold_stmt which we simply should
3549 call after building a VIEW_CONVERT_EXPR here. */
3550 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
3551 && !contains_bitfld_component_ref_p (lhs))
3553 lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
3554 gimple_assign_set_lhs (stmt, lhs);
3556 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
3557 && !contains_vce_or_bfcref_p (rhs))
3558 rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
3560 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3562 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
3564 if (is_gimple_reg_type (TREE_TYPE (lhs))
3565 && TREE_CODE (lhs) != SSA_NAME)
3566 force_gimple_rhs = true;
3571 if (lacc && lacc->grp_to_be_debug_replaced)
3573 tree dlhs = get_access_replacement (lacc);
3574 tree drhs = unshare_expr (rhs);
3575 if (!useless_type_conversion_p (TREE_TYPE (dlhs), TREE_TYPE (drhs)))
3577 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs))
3578 && !contains_vce_or_bfcref_p (drhs))
3579 drhs = build_debug_ref_for_model (loc, drhs, 0, lacc);
3581 && !useless_type_conversion_p (TREE_TYPE (dlhs),
3583 drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
3584 TREE_TYPE (dlhs), drhs);
3586 gdebug *ds = gimple_build_debug_bind (dlhs, drhs, stmt);
3587 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3590 /* From this point on, the function deals with assignments in between
3591 aggregates when at least one has scalar reductions of some of its
3592 components. There are three possible scenarios: Both the LHS and RHS have
3593 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3595 In the first case, we would like to load the LHS components from RHS
3596 components whenever possible. If that is not possible, we would like to
3597 read it directly from the RHS (after updating it by storing in it its own
3598 components). If there are some necessary unscalarized data in the LHS,
3599 those will be loaded by the original assignment too. If neither of these
3600 cases happen, the original statement can be removed. Most of this is done
3601 by load_assign_lhs_subreplacements.
3603 In the second case, we would like to store all RHS scalarized components
3604 directly into LHS and if they cover the aggregate completely, remove the
3605 statement too. In the third case, we want the LHS components to be loaded
3606 directly from the RHS (DSE will remove the original statement if it
3609 This is a bit complex but manageable when types match and when unions do
3610 not cause confusion in a way that we cannot really load a component of LHS
3611 from the RHS or vice versa (the access representing this level can have
3612 subaccesses that are accessible only through a different union field at a
3613 higher level - different from the one used in the examined expression).
3616 Therefore, I specially handle a fourth case, happening when there is a
3617 specific type cast or it is impossible to locate a scalarized subaccess on
3618 the other side of the expression. If that happens, I simply "refresh" the
3619 RHS by storing in it is scalarized components leave the original statement
3620 there to do the copying and then load the scalar replacements of the LHS.
3621 This is what the first branch does. */
3623 if (modify_this_stmt
3624 || gimple_has_volatile_ops (stmt)
3625 || contains_vce_or_bfcref_p (rhs)
3626 || contains_vce_or_bfcref_p (lhs)
3627 || stmt_ends_bb_p (stmt))
3629 /* No need to copy into a constant-pool, it comes pre-initialized. */
3630 if (access_has_children_p (racc) && !constant_decl_p (racc->base))
3631 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3632 gsi, false, false, loc);
3633 if (access_has_children_p (lacc))
3635 gimple_stmt_iterator alt_gsi = gsi_none ();
3636 if (stmt_ends_bb_p (stmt))
3638 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
3641 generate_subtree_copies (lacc->first_child, lhs, lacc->offset, 0, 0,
3642 gsi, true, true, loc);
3644 sra_stats.separate_lhs_rhs_handling++;
3646 /* This gimplification must be done after generate_subtree_copies,
3647 lest we insert the subtree copies in the middle of the gimplified
3649 if (force_gimple_rhs)
3650 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
3651 true, GSI_SAME_STMT);
3652 if (gimple_assign_rhs1 (stmt) != rhs)
3654 modify_this_stmt = true;
3655 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
3656 gcc_assert (stmt == gsi_stmt (orig_gsi));
3659 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3663 if (access_has_children_p (lacc)
3664 && access_has_children_p (racc)
3665 /* When an access represents an unscalarizable region, it usually
3666 represents accesses with variable offset and thus must not be used
3667 to generate new memory accesses. */
3668 && !lacc->grp_unscalarizable_region
3669 && !racc->grp_unscalarizable_region)
3671 struct subreplacement_assignment_data sad;
3673 sad.left_offset = lacc->offset;
3674 sad.assignment_lhs = lhs;
3675 sad.assignment_rhs = rhs;
3676 sad.top_racc = racc;
3679 sad.loc = gimple_location (stmt);
3680 sad.refreshed = SRA_UDH_NONE;
3682 if (lacc->grp_read && !lacc->grp_covered)
3683 handle_unscalarized_data_in_subtree (&sad);
3685 load_assign_lhs_subreplacements (lacc, &sad);
3686 if (sad.refreshed != SRA_UDH_RIGHT)
3689 unlink_stmt_vdef (stmt);
3690 gsi_remove (&sad.old_gsi, true);
3691 release_defs (stmt);
3692 sra_stats.deleted++;
3693 return SRA_AM_REMOVED;
3698 if (access_has_children_p (racc)
3699 && !racc->grp_unscalarized_data
3700 && TREE_CODE (lhs) != SSA_NAME)
3704 fprintf (dump_file, "Removing load: ");
3705 print_gimple_stmt (dump_file, stmt, 0);
3707 generate_subtree_copies (racc->first_child, lhs,
3708 racc->offset, 0, 0, gsi,
3710 gcc_assert (stmt == gsi_stmt (*gsi));
3711 unlink_stmt_vdef (stmt);
3712 gsi_remove (gsi, true);
3713 release_defs (stmt);
3714 sra_stats.deleted++;
3715 return SRA_AM_REMOVED;
3717 /* Restore the aggregate RHS from its components so the
3718 prevailing aggregate copy does the right thing. */
3719 if (access_has_children_p (racc))
3720 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3721 gsi, false, false, loc);
3722 /* Re-load the components of the aggregate copy destination.
3723 But use the RHS aggregate to load from to expose more
3724 optimization opportunities. */
3725 if (access_has_children_p (lacc))
3726 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
3727 0, 0, gsi, true, true, loc);
3734 /* Set any scalar replacements of values in the constant pool to the initial
3735 value of the constant. (Constant-pool decls like *.LC0 have effectively
3736 been initialized before the program starts, we must do the same for their
3737 replacements.) Thus, we output statements like 'SR.1 = *.LC0[0];' into
3738 the function's entry block. */
3741 initialize_constant_pool_replacements (void)
3743 gimple_seq seq = NULL;
3744 gimple_stmt_iterator gsi = gsi_start (seq);
3748 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
3750 tree var = candidate (i);
3751 if (!constant_decl_p (var))
3753 vec<access_p> *access_vec = get_base_access_vector (var);
3756 for (unsigned i = 0; i < access_vec->length (); i++)
3758 struct access *access = (*access_vec)[i];
3759 if (!access->replacement_decl)
3762 = gimple_build_assign (get_access_replacement (access),
3763 unshare_expr (access->expr));
3764 if (dump_file && (dump_flags & TDF_DETAILS))
3766 fprintf (dump_file, "Generating constant initializer: ");
3767 print_gimple_stmt (dump_file, stmt, 0);
3768 fprintf (dump_file, "\n");
3770 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
3775 seq = gsi_seq (gsi);
3777 gsi_insert_seq_on_edge_immediate (
3778 single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3781 /* Traverse the function body and all modifications as decided in
3782 analyze_all_variable_accesses. Return true iff the CFG has been
3786 sra_modify_function_body (void)
3788 bool cfg_changed = false;
3791 initialize_constant_pool_replacements ();
3793 FOR_EACH_BB_FN (bb, cfun)
3795 gimple_stmt_iterator gsi = gsi_start_bb (bb);
3796 while (!gsi_end_p (gsi))
3798 gimple *stmt = gsi_stmt (gsi);
3799 enum assignment_mod_result assign_result;
3800 bool modified = false, deleted = false;
3804 switch (gimple_code (stmt))
3807 t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
3808 if (*t != NULL_TREE)
3809 modified |= sra_modify_expr (t, &gsi, false);
3813 assign_result = sra_modify_assign (stmt, &gsi);
3814 modified |= assign_result == SRA_AM_MODIFIED;
3815 deleted = assign_result == SRA_AM_REMOVED;
3819 /* Operands must be processed before the lhs. */
3820 for (i = 0; i < gimple_call_num_args (stmt); i++)
3822 t = gimple_call_arg_ptr (stmt, i);
3823 modified |= sra_modify_expr (t, &gsi, false);
3826 if (gimple_call_lhs (stmt))
3828 t = gimple_call_lhs_ptr (stmt);
3829 modified |= sra_modify_expr (t, &gsi, true);
3835 gasm *asm_stmt = as_a <gasm *> (stmt);
3836 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
3838 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
3839 modified |= sra_modify_expr (t, &gsi, false);
3841 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
3843 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
3844 modified |= sra_modify_expr (t, &gsi, true);
3856 if (maybe_clean_eh_stmt (stmt)
3857 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
3865 gsi_commit_edge_inserts ();
3869 /* Generate statements initializing scalar replacements of parts of function
3873 initialize_parameter_reductions (void)
3875 gimple_stmt_iterator gsi;
3876 gimple_seq seq = NULL;
3879 gsi = gsi_start (seq);
3880 for (parm = DECL_ARGUMENTS (current_function_decl);
3882 parm = DECL_CHAIN (parm))
3884 vec<access_p> *access_vec;
3885 struct access *access;
3887 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3889 access_vec = get_base_access_vector (parm);
3893 for (access = (*access_vec)[0];
3895 access = access->next_grp)
3896 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true,
3897 EXPR_LOCATION (parm));
3900 seq = gsi_seq (gsi);
3902 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3905 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3906 it reveals there are components of some aggregates to be scalarized, it runs
3907 the required transformations. */
3909 perform_intra_sra (void)
3914 if (!find_var_candidates ())
3917 if (!scan_function ())
3920 if (!analyze_all_variable_accesses ())
3923 if (sra_modify_function_body ())
3924 ret = TODO_update_ssa | TODO_cleanup_cfg;
3926 ret = TODO_update_ssa;
3927 initialize_parameter_reductions ();
3929 statistics_counter_event (cfun, "Scalar replacements created",
3930 sra_stats.replacements);
3931 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
3932 statistics_counter_event (cfun, "Subtree copy stmts",
3933 sra_stats.subtree_copies);
3934 statistics_counter_event (cfun, "Subreplacement stmts",
3935 sra_stats.subreplacements);
3936 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
3937 statistics_counter_event (cfun, "Separate LHS and RHS handling",
3938 sra_stats.separate_lhs_rhs_handling);
3941 sra_deinitialize ();
3945 /* Perform early intraprocedural SRA. */
3947 early_intra_sra (void)
3949 sra_mode = SRA_MODE_EARLY_INTRA;
3950 return perform_intra_sra ();
3953 /* Perform "late" intraprocedural SRA. */
3955 late_intra_sra (void)
3957 sra_mode = SRA_MODE_INTRA;
3958 return perform_intra_sra ();
3963 gate_intra_sra (void)
3965 return flag_tree_sra != 0 && dbg_cnt (tree_sra);
3971 const pass_data pass_data_sra_early =
3973 GIMPLE_PASS, /* type */
3975 OPTGROUP_NONE, /* optinfo_flags */
3976 TV_TREE_SRA, /* tv_id */
3977 ( PROP_cfg | PROP_ssa ), /* properties_required */
3978 0, /* properties_provided */
3979 0, /* properties_destroyed */
3980 0, /* todo_flags_start */
3981 TODO_update_ssa, /* todo_flags_finish */
3984 class pass_sra_early : public gimple_opt_pass
3987 pass_sra_early (gcc::context *ctxt)
3988 : gimple_opt_pass (pass_data_sra_early, ctxt)
3991 /* opt_pass methods: */
3992 virtual bool gate (function *) { return gate_intra_sra (); }
3993 virtual unsigned int execute (function *) { return early_intra_sra (); }
3995 }; // class pass_sra_early
4000 make_pass_sra_early (gcc::context *ctxt)
4002 return new pass_sra_early (ctxt);
4007 const pass_data pass_data_sra =
4009 GIMPLE_PASS, /* type */
4011 OPTGROUP_NONE, /* optinfo_flags */
4012 TV_TREE_SRA, /* tv_id */
4013 ( PROP_cfg | PROP_ssa ), /* properties_required */
4014 0, /* properties_provided */
4015 0, /* properties_destroyed */
4016 TODO_update_address_taken, /* todo_flags_start */
4017 TODO_update_ssa, /* todo_flags_finish */
4020 class pass_sra : public gimple_opt_pass
4023 pass_sra (gcc::context *ctxt)
4024 : gimple_opt_pass (pass_data_sra, ctxt)
4027 /* opt_pass methods: */
4028 virtual bool gate (function *) { return gate_intra_sra (); }
4029 virtual unsigned int execute (function *) { return late_intra_sra (); }
4031 }; // class pass_sra
4036 make_pass_sra (gcc::context *ctxt)
4038 return new pass_sra (ctxt);
4042 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
4046 is_unused_scalar_param (tree parm)
4049 return (is_gimple_reg (parm)
4050 && (!(name = ssa_default_def (cfun, parm))
4051 || has_zero_uses (name)));
4054 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
4055 examine whether there are any direct or otherwise infeasible ones. If so,
4056 return true, otherwise return false. PARM must be a gimple register with a
4057 non-NULL default definition. */
4060 ptr_parm_has_direct_uses (tree parm)
4062 imm_use_iterator ui;
4064 tree name = ssa_default_def (cfun, parm);
4067 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
4070 use_operand_p use_p;
4072 if (is_gimple_debug (stmt))
4075 /* Valid uses include dereferences on the lhs and the rhs. */
4076 if (gimple_has_lhs (stmt))
4078 tree lhs = gimple_get_lhs (stmt);
4079 while (handled_component_p (lhs))
4080 lhs = TREE_OPERAND (lhs, 0);
4081 if (TREE_CODE (lhs) == MEM_REF
4082 && TREE_OPERAND (lhs, 0) == name
4083 && integer_zerop (TREE_OPERAND (lhs, 1))
4084 && types_compatible_p (TREE_TYPE (lhs),
4085 TREE_TYPE (TREE_TYPE (name)))
4086 && !TREE_THIS_VOLATILE (lhs))
4089 if (gimple_assign_single_p (stmt))
4091 tree rhs = gimple_assign_rhs1 (stmt);
4092 while (handled_component_p (rhs))
4093 rhs = TREE_OPERAND (rhs, 0);
4094 if (TREE_CODE (rhs) == MEM_REF
4095 && TREE_OPERAND (rhs, 0) == name
4096 && integer_zerop (TREE_OPERAND (rhs, 1))
4097 && types_compatible_p (TREE_TYPE (rhs),
4098 TREE_TYPE (TREE_TYPE (name)))
4099 && !TREE_THIS_VOLATILE (rhs))
4102 else if (is_gimple_call (stmt))
4105 for (i = 0; i < gimple_call_num_args (stmt); ++i)
4107 tree arg = gimple_call_arg (stmt, i);
4108 while (handled_component_p (arg))
4109 arg = TREE_OPERAND (arg, 0);
4110 if (TREE_CODE (arg) == MEM_REF
4111 && TREE_OPERAND (arg, 0) == name
4112 && integer_zerop (TREE_OPERAND (arg, 1))
4113 && types_compatible_p (TREE_TYPE (arg),
4114 TREE_TYPE (TREE_TYPE (name)))
4115 && !TREE_THIS_VOLATILE (arg))
4120 /* If the number of valid uses does not match the number of
4121 uses in this stmt there is an unhandled use. */
4122 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
4129 BREAK_FROM_IMM_USE_STMT (ui);
4135 /* Identify candidates for reduction for IPA-SRA based on their type and mark
4136 them in candidate_bitmap. Note that these do not necessarily include
4137 parameter which are unused and thus can be removed. Return true iff any
4138 such candidate has been found. */
4141 find_param_candidates (void)
4148 for (parm = DECL_ARGUMENTS (current_function_decl);
4150 parm = DECL_CHAIN (parm))
4152 tree type = TREE_TYPE (parm);
4157 if (TREE_THIS_VOLATILE (parm)
4158 || TREE_ADDRESSABLE (parm)
4159 || (!is_gimple_reg_type (type) && is_va_list_type (type)))
4162 if (is_unused_scalar_param (parm))
4168 if (POINTER_TYPE_P (type))
4170 type = TREE_TYPE (type);
4172 if (TREE_CODE (type) == FUNCTION_TYPE
4173 || TYPE_VOLATILE (type)
4174 || (TREE_CODE (type) == ARRAY_TYPE
4175 && TYPE_NONALIASED_COMPONENT (type))
4176 || !is_gimple_reg (parm)
4177 || is_va_list_type (type)
4178 || ptr_parm_has_direct_uses (parm))
4181 else if (!AGGREGATE_TYPE_P (type))
4184 if (!COMPLETE_TYPE_P (type)
4185 || !tree_fits_uhwi_p (TYPE_SIZE (type))
4186 || tree_to_uhwi (TYPE_SIZE (type)) == 0
4187 || (AGGREGATE_TYPE_P (type)
4188 && type_internals_preclude_sra_p (type, &msg)))
4191 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
4192 slot = candidates->find_slot_with_hash (parm, DECL_UID (parm), INSERT);
4196 if (dump_file && (dump_flags & TDF_DETAILS))
4198 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
4199 print_generic_expr (dump_file, parm);
4200 fprintf (dump_file, "\n");
4204 func_param_count = count;
4208 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
4212 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
4215 struct access *repr = (struct access *) data;
4217 repr->grp_maybe_modified = 1;
4221 /* Analyze what representatives (in linked lists accessible from
4222 REPRESENTATIVES) can be modified by side effects of statements in the
4223 current function. */
4226 analyze_modified_params (vec<access_p> representatives)
4230 for (i = 0; i < func_param_count; i++)
4232 struct access *repr;
4234 for (repr = representatives[i];
4236 repr = repr->next_grp)
4238 struct access *access;
4242 if (no_accesses_p (repr))
4244 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
4245 || repr->grp_maybe_modified)
4248 ao_ref_init (&ar, repr->expr);
4249 visited = BITMAP_ALLOC (NULL);
4250 for (access = repr; access; access = access->next_sibling)
4252 /* All accesses are read ones, otherwise grp_maybe_modified would
4253 be trivially set. */
4254 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
4255 mark_maybe_modified, repr, &visited);
4256 if (repr->grp_maybe_modified)
4259 BITMAP_FREE (visited);
4264 /* Propagate distances in bb_dereferences in the opposite direction than the
4265 control flow edges, in each step storing the maximum of the current value
4266 and the minimum of all successors. These steps are repeated until the table
4267 stabilizes. Note that BBs which might terminate the functions (according to
4268 final_bbs bitmap) never updated in this way. */
4271 propagate_dereference_distances (void)
4275 auto_vec<basic_block> queue (last_basic_block_for_fn (cfun));
4276 queue.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun));
4277 FOR_EACH_BB_FN (bb, cfun)
4279 queue.quick_push (bb);
4283 while (!queue.is_empty ())
4287 bool change = false;
4293 if (bitmap_bit_p (final_bbs, bb->index))
4296 for (i = 0; i < func_param_count; i++)
4298 int idx = bb->index * func_param_count + i;
4300 HOST_WIDE_INT inh = 0;
4302 FOR_EACH_EDGE (e, ei, bb->succs)
4304 int succ_idx = e->dest->index * func_param_count + i;
4306 if (e->src == EXIT_BLOCK_PTR_FOR_FN (cfun))
4312 inh = bb_dereferences [succ_idx];
4314 else if (bb_dereferences [succ_idx] < inh)
4315 inh = bb_dereferences [succ_idx];
4318 if (!first && bb_dereferences[idx] < inh)
4320 bb_dereferences[idx] = inh;
4325 if (change && !bitmap_bit_p (final_bbs, bb->index))
4326 FOR_EACH_EDGE (e, ei, bb->preds)
4331 e->src->aux = e->src;
4332 queue.quick_push (e->src);
4337 /* Dump a dereferences TABLE with heading STR to file F. */
4340 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
4344 fprintf (dump_file, "%s", str);
4345 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
4346 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
4348 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
4349 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
4352 for (i = 0; i < func_param_count; i++)
4354 int idx = bb->index * func_param_count + i;
4355 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
4360 fprintf (dump_file, "\n");
4363 /* Determine what (parts of) parameters passed by reference that are not
4364 assigned to are not certainly dereferenced in this function and thus the
4365 dereferencing cannot be safely moved to the caller without potentially
4366 introducing a segfault. Mark such REPRESENTATIVES as
4367 grp_not_necessarilly_dereferenced.
4369 The dereferenced maximum "distance," i.e. the offset + size of the accessed
4370 part is calculated rather than simple booleans are calculated for each
4371 pointer parameter to handle cases when only a fraction of the whole
4372 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
4375 The maximum dereference distances for each pointer parameter and BB are
4376 already stored in bb_dereference. This routine simply propagates these
4377 values upwards by propagate_dereference_distances and then compares the
4378 distances of individual parameters in the ENTRY BB to the equivalent
4379 distances of each representative of a (fraction of a) parameter. */
4382 analyze_caller_dereference_legality (vec<access_p> representatives)
4386 if (dump_file && (dump_flags & TDF_DETAILS))
4387 dump_dereferences_table (dump_file,
4388 "Dereference table before propagation:\n",
4391 propagate_dereference_distances ();
4393 if (dump_file && (dump_flags & TDF_DETAILS))
4394 dump_dereferences_table (dump_file,
4395 "Dereference table after propagation:\n",
4398 for (i = 0; i < func_param_count; i++)
4400 struct access *repr = representatives[i];
4401 int idx = ENTRY_BLOCK_PTR_FOR_FN (cfun)->index * func_param_count + i;
4403 if (!repr || no_accesses_p (repr))
4408 if ((repr->offset + repr->size) > bb_dereferences[idx])
4409 repr->grp_not_necessarilly_dereferenced = 1;
4410 repr = repr->next_grp;
4416 /* Return the representative access for the parameter declaration PARM if it is
4417 a scalar passed by reference which is not written to and the pointer value
4418 is not used directly. Thus, if it is legal to dereference it in the caller
4419 and we can rule out modifications through aliases, such parameter should be
4420 turned into one passed by value. Return NULL otherwise. */
4422 static struct access *
4423 unmodified_by_ref_scalar_representative (tree parm)
4425 int i, access_count;
4426 struct access *repr;
4427 vec<access_p> *access_vec;
4429 access_vec = get_base_access_vector (parm);
4430 gcc_assert (access_vec);
4431 repr = (*access_vec)[0];
4434 repr->group_representative = repr;
4436 access_count = access_vec->length ();
4437 for (i = 1; i < access_count; i++)
4439 struct access *access = (*access_vec)[i];
4442 access->group_representative = repr;
4443 access->next_sibling = repr->next_sibling;
4444 repr->next_sibling = access;
4448 repr->grp_scalar_ptr = 1;
4452 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
4453 associated with. REQ_ALIGN is the minimum required alignment. */
4456 access_precludes_ipa_sra_p (struct access *access, unsigned int req_align)
4458 unsigned int exp_align;
4459 /* Avoid issues such as the second simple testcase in PR 42025. The problem
4460 is incompatible assign in a call statement (and possibly even in asm
4461 statements). This can be relaxed by using a new temporary but only for
4462 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
4463 intraprocedural SRA we deal with this by keeping the old aggregate around,
4464 something we cannot do in IPA-SRA.) */
4466 && (is_gimple_call (access->stmt)
4467 || gimple_code (access->stmt) == GIMPLE_ASM))
4470 exp_align = get_object_alignment (access->expr);
4471 if (exp_align < req_align)
4478 /* Sort collected accesses for parameter PARM, identify representatives for
4479 each accessed region and link them together. Return NULL if there are
4480 different but overlapping accesses, return the special ptr value meaning
4481 there are no accesses for this parameter if that is the case and return the
4482 first representative otherwise. Set *RO_GRP if there is a group of accesses
4483 with only read (i.e. no write) accesses. */
4485 static struct access *
4486 splice_param_accesses (tree parm, bool *ro_grp)
4488 int i, j, access_count, group_count;
4490 struct access *access, *res, **prev_acc_ptr = &res;
4491 vec<access_p> *access_vec;
4493 access_vec = get_base_access_vector (parm);
4495 return &no_accesses_representant;
4496 access_count = access_vec->length ();
4498 access_vec->qsort (compare_access_positions);
4503 while (i < access_count)
4507 access = (*access_vec)[i];
4508 modification = access->write;
4509 if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type)))
4511 a1_alias_type = reference_alias_ptr_type (access->expr);
4513 /* Access is about to become group representative unless we find some
4514 nasty overlap which would preclude us from breaking this parameter
4518 while (j < access_count)
4520 struct access *ac2 = (*access_vec)[j];
4521 if (ac2->offset != access->offset)
4523 /* All or nothing law for parameters. */
4524 if (access->offset + access->size > ac2->offset)
4529 else if (ac2->size != access->size)
4532 if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type))
4533 || (ac2->type != access->type
4534 && (TREE_ADDRESSABLE (ac2->type)
4535 || TREE_ADDRESSABLE (access->type)))
4536 || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
4539 modification |= ac2->write;
4540 ac2->group_representative = access;
4541 ac2->next_sibling = access->next_sibling;
4542 access->next_sibling = ac2;
4547 access->grp_maybe_modified = modification;
4550 *prev_acc_ptr = access;
4551 prev_acc_ptr = &access->next_grp;
4552 total_size += access->size;
4556 gcc_assert (group_count > 0);
4560 /* Decide whether parameters with representative accesses given by REPR should
4561 be reduced into components. */
4564 decide_one_param_reduction (struct access *repr)
4566 HOST_WIDE_INT total_size, cur_parm_size;
4571 cur_parm_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4572 gcc_assert (cur_parm_size > 0);
4574 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4582 fprintf (dump_file, "Evaluating PARAM group sizes for ");
4583 print_generic_expr (dump_file, parm);
4584 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
4585 for (acc = repr; acc; acc = acc->next_grp)
4586 dump_access (dump_file, acc, true);
4590 int new_param_count = 0;
4592 for (; repr; repr = repr->next_grp)
4594 gcc_assert (parm == repr->base);
4596 /* Taking the address of a non-addressable field is verboten. */
4597 if (by_ref && repr->non_addressable)
4600 /* Do not decompose a non-BLKmode param in a way that would
4601 create BLKmode params. Especially for by-reference passing
4602 (thus, pointer-type param) this is hardly worthwhile. */
4603 if (DECL_MODE (parm) != BLKmode
4604 && TYPE_MODE (repr->type) == BLKmode)
4607 if (!by_ref || (!repr->grp_maybe_modified
4608 && !repr->grp_not_necessarilly_dereferenced))
4609 total_size += repr->size;
4611 total_size += cur_parm_size;
4616 gcc_assert (new_param_count > 0);
4620 if (total_size >= cur_parm_size)
4626 if (optimize_function_for_size_p (cfun))
4629 parm_num_limit = PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR);
4631 if (new_param_count > parm_num_limit
4632 || total_size > (parm_num_limit * cur_parm_size))
4637 fprintf (dump_file, " ....will be split into %i components\n",
4639 return new_param_count;
4642 /* The order of the following enums is important, we need to do extra work for
4643 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4644 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
4645 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
4647 /* Identify representatives of all accesses to all candidate parameters for
4648 IPA-SRA. Return result based on what representatives have been found. */
4650 static enum ipa_splicing_result
4651 splice_all_param_accesses (vec<access_p> &representatives)
4653 enum ipa_splicing_result result = NO_GOOD_ACCESS;
4655 struct access *repr;
4657 representatives.create (func_param_count);
4659 for (parm = DECL_ARGUMENTS (current_function_decl);
4661 parm = DECL_CHAIN (parm))
4663 if (is_unused_scalar_param (parm))
4665 representatives.quick_push (&no_accesses_representant);
4666 if (result == NO_GOOD_ACCESS)
4667 result = UNUSED_PARAMS;
4669 else if (POINTER_TYPE_P (TREE_TYPE (parm))
4670 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
4671 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4673 repr = unmodified_by_ref_scalar_representative (parm);
4674 representatives.quick_push (repr);
4676 result = UNMODIF_BY_REF_ACCESSES;
4678 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4680 bool ro_grp = false;
4681 repr = splice_param_accesses (parm, &ro_grp);
4682 representatives.quick_push (repr);
4684 if (repr && !no_accesses_p (repr))
4686 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4689 result = UNMODIF_BY_REF_ACCESSES;
4690 else if (result < MODIF_BY_REF_ACCESSES)
4691 result = MODIF_BY_REF_ACCESSES;
4693 else if (result < BY_VAL_ACCESSES)
4694 result = BY_VAL_ACCESSES;
4696 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
4697 result = UNUSED_PARAMS;
4700 representatives.quick_push (NULL);
4703 if (result == NO_GOOD_ACCESS)
4705 representatives.release ();
4706 return NO_GOOD_ACCESS;
4712 /* Return the index of BASE in PARMS. Abort if it is not found. */
4715 get_param_index (tree base, vec<tree> parms)
4719 len = parms.length ();
4720 for (i = 0; i < len; i++)
4721 if (parms[i] == base)
4726 /* Convert the decisions made at the representative level into compact
4727 parameter adjustments. REPRESENTATIVES are pointers to first
4728 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4729 final number of adjustments. */
4731 static ipa_parm_adjustment_vec
4732 turn_representatives_into_adjustments (vec<access_p> representatives,
4733 int adjustments_count)
4736 ipa_parm_adjustment_vec adjustments;
4740 gcc_assert (adjustments_count > 0);
4741 parms = ipa_get_vector_of_formal_parms (current_function_decl);
4742 adjustments.create (adjustments_count);
4743 parm = DECL_ARGUMENTS (current_function_decl);
4744 for (i = 0; i < func_param_count; i++, parm = DECL_CHAIN (parm))
4746 struct access *repr = representatives[i];
4748 if (!repr || no_accesses_p (repr))
4750 struct ipa_parm_adjustment adj;
4752 memset (&adj, 0, sizeof (adj));
4753 adj.base_index = get_param_index (parm, parms);
4756 adj.op = IPA_PARM_OP_COPY;
4758 adj.op = IPA_PARM_OP_REMOVE;
4759 adj.arg_prefix = "ISRA";
4760 adjustments.quick_push (adj);
4764 struct ipa_parm_adjustment adj;
4765 int index = get_param_index (parm, parms);
4767 for (; repr; repr = repr->next_grp)
4769 memset (&adj, 0, sizeof (adj));
4770 gcc_assert (repr->base == parm);
4771 adj.base_index = index;
4772 adj.base = repr->base;
4773 adj.type = repr->type;
4774 adj.alias_ptr_type = reference_alias_ptr_type (repr->expr);
4775 adj.offset = repr->offset;
4776 adj.reverse = repr->reverse;
4777 adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
4778 && (repr->grp_maybe_modified
4779 || repr->grp_not_necessarilly_dereferenced));
4780 adj.arg_prefix = "ISRA";
4781 adjustments.quick_push (adj);
4789 /* Analyze the collected accesses and produce a plan what to do with the
4790 parameters in the form of adjustments, NULL meaning nothing. */
4792 static ipa_parm_adjustment_vec
4793 analyze_all_param_acesses (void)
4795 enum ipa_splicing_result repr_state;
4796 bool proceed = false;
4797 int i, adjustments_count = 0;
4798 vec<access_p> representatives;
4799 ipa_parm_adjustment_vec adjustments;
4801 repr_state = splice_all_param_accesses (representatives);
4802 if (repr_state == NO_GOOD_ACCESS)
4803 return ipa_parm_adjustment_vec ();
4805 /* If there are any parameters passed by reference which are not modified
4806 directly, we need to check whether they can be modified indirectly. */
4807 if (repr_state == UNMODIF_BY_REF_ACCESSES)
4809 analyze_caller_dereference_legality (representatives);
4810 analyze_modified_params (representatives);
4813 for (i = 0; i < func_param_count; i++)
4815 struct access *repr = representatives[i];
4817 if (repr && !no_accesses_p (repr))
4819 if (repr->grp_scalar_ptr)
4821 adjustments_count++;
4822 if (repr->grp_not_necessarilly_dereferenced
4823 || repr->grp_maybe_modified)
4824 representatives[i] = NULL;
4828 sra_stats.scalar_by_ref_to_by_val++;
4833 int new_components = decide_one_param_reduction (repr);
4835 if (new_components == 0)
4837 representatives[i] = NULL;
4838 adjustments_count++;
4842 adjustments_count += new_components;
4843 sra_stats.aggregate_params_reduced++;
4844 sra_stats.param_reductions_created += new_components;
4851 if (no_accesses_p (repr))
4854 sra_stats.deleted_unused_parameters++;
4856 adjustments_count++;
4860 if (!proceed && dump_file)
4861 fprintf (dump_file, "NOT proceeding to change params.\n");
4864 adjustments = turn_representatives_into_adjustments (representatives,
4867 adjustments = ipa_parm_adjustment_vec ();
4869 representatives.release ();
4873 /* If a parameter replacement identified by ADJ does not yet exist in the form
4874 of declaration, create it and record it, otherwise return the previously
4878 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
4881 if (!adj->new_ssa_base)
4883 char *pretty_name = make_fancy_name (adj->base);
4885 repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR");
4886 DECL_NAME (repl) = get_identifier (pretty_name);
4887 DECL_NAMELESS (repl) = 1;
4888 obstack_free (&name_obstack, pretty_name);
4890 adj->new_ssa_base = repl;
4893 repl = adj->new_ssa_base;
4897 /* Find the first adjustment for a particular parameter BASE in a vector of
4898 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4901 static struct ipa_parm_adjustment *
4902 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
4906 len = adjustments.length ();
4907 for (i = 0; i < len; i++)
4909 struct ipa_parm_adjustment *adj;
4911 adj = &adjustments[i];
4912 if (adj->op != IPA_PARM_OP_COPY && adj->base == base)
4919 /* If OLD_NAME, which is being defined by statement STMT, is an SSA_NAME of a
4920 parameter which is to be removed because its value is not used, create a new
4921 SSA_NAME relating to a replacement VAR_DECL, replace all uses of the
4922 original with it and return it. If there is no need to re-map, return NULL.
4923 ADJUSTMENTS is a pointer to a vector of IPA-SRA adjustments. */
4926 replace_removed_params_ssa_names (tree old_name, gimple *stmt,
4927 ipa_parm_adjustment_vec adjustments)
4929 struct ipa_parm_adjustment *adj;
4930 tree decl, repl, new_name;
4932 if (TREE_CODE (old_name) != SSA_NAME)
4935 decl = SSA_NAME_VAR (old_name);
4936 if (decl == NULL_TREE
4937 || TREE_CODE (decl) != PARM_DECL)
4940 adj = get_adjustment_for_base (adjustments, decl);
4944 repl = get_replaced_param_substitute (adj);
4945 new_name = make_ssa_name (repl, stmt);
4946 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name)
4947 = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name);
4951 fprintf (dump_file, "replacing an SSA name of a removed param ");
4952 print_generic_expr (dump_file, old_name);
4953 fprintf (dump_file, " with ");
4954 print_generic_expr (dump_file, new_name);
4955 fprintf (dump_file, "\n");
4958 replace_uses_by (old_name, new_name);
4962 /* If the statement STMT contains any expressions that need to replaced with a
4963 different one as noted by ADJUSTMENTS, do so. Handle any potential type
4964 incompatibilities (GSI is used to accommodate conversion statements and must
4965 point to the statement). Return true iff the statement was modified. */
4968 sra_ipa_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi,
4969 ipa_parm_adjustment_vec adjustments)
4971 tree *lhs_p, *rhs_p;
4974 if (!gimple_assign_single_p (stmt))
4977 rhs_p = gimple_assign_rhs1_ptr (stmt);
4978 lhs_p = gimple_assign_lhs_ptr (stmt);
4980 any = ipa_modify_expr (rhs_p, false, adjustments);
4981 any |= ipa_modify_expr (lhs_p, false, adjustments);
4984 tree new_rhs = NULL_TREE;
4986 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
4988 if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
4990 /* V_C_Es of constructors can cause trouble (PR 42714). */
4991 if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
4992 *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
4994 *rhs_p = build_constructor (TREE_TYPE (*lhs_p),
4998 new_rhs = fold_build1_loc (gimple_location (stmt),
4999 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
5002 else if (REFERENCE_CLASS_P (*rhs_p)
5003 && is_gimple_reg_type (TREE_TYPE (*lhs_p))
5004 && !is_gimple_reg (*lhs_p))
5005 /* This can happen when an assignment in between two single field
5006 structures is turned into an assignment in between two pointers to
5007 scalars (PR 42237). */
5012 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
5013 true, GSI_SAME_STMT);
5015 gimple_assign_set_rhs_from_tree (gsi, tmp);
5024 /* Traverse the function body and all modifications as described in
5025 ADJUSTMENTS. Return true iff the CFG has been changed. */
5028 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
5030 bool cfg_changed = false;
5033 FOR_EACH_BB_FN (bb, cfun)
5035 gimple_stmt_iterator gsi;
5037 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5039 gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
5040 tree new_lhs, old_lhs = gimple_phi_result (phi);
5041 new_lhs = replace_removed_params_ssa_names (old_lhs, phi, adjustments);
5044 gimple_phi_set_result (phi, new_lhs);
5045 release_ssa_name (old_lhs);
5049 gsi = gsi_start_bb (bb);
5050 while (!gsi_end_p (gsi))
5052 gimple *stmt = gsi_stmt (gsi);
5053 bool modified = false;
5057 switch (gimple_code (stmt))
5060 t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
5061 if (*t != NULL_TREE)
5062 modified |= ipa_modify_expr (t, true, adjustments);
5066 modified |= sra_ipa_modify_assign (stmt, &gsi, adjustments);
5070 /* Operands must be processed before the lhs. */
5071 for (i = 0; i < gimple_call_num_args (stmt); i++)
5073 t = gimple_call_arg_ptr (stmt, i);
5074 modified |= ipa_modify_expr (t, true, adjustments);
5077 if (gimple_call_lhs (stmt))
5079 t = gimple_call_lhs_ptr (stmt);
5080 modified |= ipa_modify_expr (t, false, adjustments);
5086 gasm *asm_stmt = as_a <gasm *> (stmt);
5087 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
5089 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
5090 modified |= ipa_modify_expr (t, true, adjustments);
5092 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
5094 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
5095 modified |= ipa_modify_expr (t, false, adjustments);
5106 FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF)
5108 tree old_def = DEF_FROM_PTR (defp);
5109 if (tree new_def = replace_removed_params_ssa_names (old_def, stmt,
5112 SET_DEF (defp, new_def);
5113 release_ssa_name (old_def);
5121 if (maybe_clean_eh_stmt (stmt)
5122 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
5132 /* Call gimple_debug_bind_reset_value on all debug statements describing
5133 gimple register parameters that are being removed or replaced. */
5136 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
5139 gimple_stmt_iterator *gsip = NULL, gsi;
5141 if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
5143 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
5146 len = adjustments.length ();
5147 for (i = 0; i < len; i++)
5149 struct ipa_parm_adjustment *adj;
5150 imm_use_iterator ui;
5153 tree name, vexpr, copy = NULL_TREE;
5154 use_operand_p use_p;
5156 adj = &adjustments[i];
5157 if (adj->op == IPA_PARM_OP_COPY || !is_gimple_reg (adj->base))
5159 name = ssa_default_def (cfun, adj->base);
5162 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
5164 if (gimple_clobber_p (stmt))
5166 gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
5167 unlink_stmt_vdef (stmt);
5168 gsi_remove (&cgsi, true);
5169 release_defs (stmt);
5172 /* All other users must have been removed by
5173 ipa_sra_modify_function_body. */
5174 gcc_assert (is_gimple_debug (stmt));
5175 if (vexpr == NULL && gsip != NULL)
5177 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
5178 vexpr = make_node (DEBUG_EXPR_DECL);
5179 def_temp = gimple_build_debug_source_bind (vexpr, adj->base,
5181 DECL_ARTIFICIAL (vexpr) = 1;
5182 TREE_TYPE (vexpr) = TREE_TYPE (name);
5183 SET_DECL_MODE (vexpr, DECL_MODE (adj->base));
5184 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
5188 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
5189 SET_USE (use_p, vexpr);
5192 gimple_debug_bind_reset_value (stmt);
5195 /* Create a VAR_DECL for debug info purposes. */
5196 if (!DECL_IGNORED_P (adj->base))
5198 copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
5199 VAR_DECL, DECL_NAME (adj->base),
5200 TREE_TYPE (adj->base));
5201 if (DECL_PT_UID_SET_P (adj->base))
5202 SET_DECL_PT_UID (copy, DECL_PT_UID (adj->base));
5203 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (adj->base);
5204 TREE_READONLY (copy) = TREE_READONLY (adj->base);
5205 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (adj->base);
5206 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (adj->base);
5207 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (adj->base);
5208 DECL_IGNORED_P (copy) = DECL_IGNORED_P (adj->base);
5209 DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (adj->base);
5210 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
5211 SET_DECL_RTL (copy, 0);
5212 TREE_USED (copy) = 1;
5213 DECL_CONTEXT (copy) = current_function_decl;
5214 add_local_decl (cfun, copy);
5216 BLOCK_VARS (DECL_INITIAL (current_function_decl));
5217 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
5219 if (gsip != NULL && copy && target_for_debug_bind (adj->base))
5221 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
5223 def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
5225 def_temp = gimple_build_debug_source_bind (copy, adj->base,
5227 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
5232 /* Return false if all callers have at least as many actual arguments as there
5233 are formal parameters in the current function and that their types
5237 some_callers_have_mismatched_arguments_p (struct cgraph_node *node,
5238 void *data ATTRIBUTE_UNUSED)
5240 struct cgraph_edge *cs;
5241 for (cs = node->callers; cs; cs = cs->next_caller)
5242 if (!cs->call_stmt || !callsite_arguments_match_p (cs->call_stmt))
5248 /* Return false if all callers have vuse attached to a call statement. */
5251 some_callers_have_no_vuse_p (struct cgraph_node *node,
5252 void *data ATTRIBUTE_UNUSED)
5254 struct cgraph_edge *cs;
5255 for (cs = node->callers; cs; cs = cs->next_caller)
5256 if (!cs->call_stmt || !gimple_vuse (cs->call_stmt))
5262 /* Convert all callers of NODE. */
5265 convert_callers_for_node (struct cgraph_node *node,
5268 ipa_parm_adjustment_vec *adjustments = (ipa_parm_adjustment_vec *) data;
5269 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
5270 struct cgraph_edge *cs;
5272 for (cs = node->callers; cs; cs = cs->next_caller)
5274 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
5277 fprintf (dump_file, "Adjusting call %s -> %s\n",
5278 cs->caller->dump_name (), cs->callee->dump_name ());
5280 ipa_modify_call_arguments (cs, cs->call_stmt, *adjustments);
5285 for (cs = node->callers; cs; cs = cs->next_caller)
5286 if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
5287 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
5288 compute_fn_summary (cs->caller, true);
5289 BITMAP_FREE (recomputed_callers);
5294 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
5297 convert_callers (struct cgraph_node *node, tree old_decl,
5298 ipa_parm_adjustment_vec adjustments)
5300 basic_block this_block;
5302 node->call_for_symbol_and_aliases (convert_callers_for_node,
5303 &adjustments, false);
5305 if (!encountered_recursive_call)
5308 FOR_EACH_BB_FN (this_block, cfun)
5310 gimple_stmt_iterator gsi;
5312 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
5316 stmt = dyn_cast <gcall *> (gsi_stmt (gsi));
5319 call_fndecl = gimple_call_fndecl (stmt);
5320 if (call_fndecl == old_decl)
5323 fprintf (dump_file, "Adjusting recursive call");
5324 gimple_call_set_fndecl (stmt, node->decl);
5325 ipa_modify_call_arguments (NULL, stmt, adjustments);
5333 /* Perform all the modification required in IPA-SRA for NODE to have parameters
5334 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
5337 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
5339 struct cgraph_node *new_node;
5342 cgraph_edge::rebuild_edges ();
5343 free_dominance_info (CDI_DOMINATORS);
5346 /* This must be done after rebuilding cgraph edges for node above.
5347 Otherwise any recursive calls to node that are recorded in
5348 redirect_callers will be corrupted. */
5349 vec<cgraph_edge *> redirect_callers = node->collect_callers ();
5350 new_node = node->create_version_clone_with_body (redirect_callers, NULL,
5351 NULL, false, NULL, NULL,
5353 redirect_callers.release ();
5355 push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
5356 ipa_modify_formal_parameters (current_function_decl, adjustments);
5357 cfg_changed = ipa_sra_modify_function_body (adjustments);
5358 sra_ipa_reset_debug_stmts (adjustments);
5359 convert_callers (new_node, node->decl, adjustments);
5360 new_node->make_local ();
5364 /* Means of communication between ipa_sra_check_caller and
5365 ipa_sra_preliminary_function_checks. */
5367 struct ipa_sra_check_caller_data
5370 bool bad_arg_alignment;
5374 /* If NODE has a caller, mark that fact in DATA which is pointer to
5375 ipa_sra_check_caller_data. Also check all aggregate arguments in all known
5376 calls if they are unit aligned and if not, set the appropriate flag in DATA
5380 ipa_sra_check_caller (struct cgraph_node *node, void *data)
5385 struct ipa_sra_check_caller_data *iscc;
5386 iscc = (struct ipa_sra_check_caller_data *) data;
5387 iscc->has_callers = true;
5389 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
5391 if (cs->caller->thunk.thunk_p)
5393 iscc->has_thunk = true;
5396 gimple *call_stmt = cs->call_stmt;
5397 unsigned count = gimple_call_num_args (call_stmt);
5398 for (unsigned i = 0; i < count; i++)
5400 tree arg = gimple_call_arg (call_stmt, i);
5401 if (is_gimple_reg (arg))
5405 poly_int64 bitsize, bitpos;
5407 int unsignedp, reversep, volatilep = 0;
5408 get_inner_reference (arg, &bitsize, &bitpos, &offset, &mode,
5409 &unsignedp, &reversep, &volatilep);
5410 if (!multiple_p (bitpos, BITS_PER_UNIT))
5412 iscc->bad_arg_alignment = true;
5421 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
5422 attributes, return true otherwise. NODE is the cgraph node of the current
5426 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
5428 if (!node->can_be_local_p ())
5431 fprintf (dump_file, "Function not local to this compilation unit.\n");
5435 if (!node->local.can_change_signature)
5438 fprintf (dump_file, "Function can not change signature.\n");
5442 if (!tree_versionable_function_p (node->decl))
5445 fprintf (dump_file, "Function is not versionable.\n");
5449 if (!opt_for_fn (node->decl, optimize)
5450 || !opt_for_fn (node->decl, flag_ipa_sra))
5453 fprintf (dump_file, "Function not optimized.\n");
5457 if (DECL_VIRTUAL_P (current_function_decl))
5460 fprintf (dump_file, "Function is a virtual method.\n");
5464 if ((DECL_ONE_ONLY (node->decl) || DECL_EXTERNAL (node->decl))
5465 && ipa_fn_summaries->get (node)->size >= MAX_INLINE_INSNS_AUTO)
5468 fprintf (dump_file, "Function too big to be made truly local.\n");
5475 fprintf (dump_file, "Function uses stdarg. \n");
5479 if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
5482 if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
5485 fprintf (dump_file, "Always inline function will be inlined "
5490 struct ipa_sra_check_caller_data iscc;
5491 memset (&iscc, 0, sizeof(iscc));
5492 node->call_for_symbol_and_aliases (ipa_sra_check_caller, &iscc, true);
5493 if (!iscc.has_callers)
5497 "Function has no callers in this compilation unit.\n");
5501 if (iscc.bad_arg_alignment)
5505 "A function call has an argument with non-unit alignment.\n");
5520 /* Perform early interprocedural SRA. */
5523 ipa_early_sra (void)
5525 struct cgraph_node *node = cgraph_node::get (current_function_decl);
5526 ipa_parm_adjustment_vec adjustments;
5529 if (!ipa_sra_preliminary_function_checks (node))
5533 sra_mode = SRA_MODE_EARLY_IPA;
5535 if (!find_param_candidates ())
5538 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
5542 if (node->call_for_symbol_and_aliases
5543 (some_callers_have_mismatched_arguments_p, NULL, true))
5546 fprintf (dump_file, "There are callers with insufficient number of "
5547 "arguments or arguments with type mismatches.\n");
5551 if (node->call_for_symbol_and_aliases
5552 (some_callers_have_no_vuse_p, NULL, true))
5555 fprintf (dump_file, "There are callers with no VUSE attached "
5556 "to a call stmt.\n");
5560 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
5562 * last_basic_block_for_fn (cfun));
5563 final_bbs = BITMAP_ALLOC (NULL);
5566 if (encountered_apply_args)
5569 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
5573 if (encountered_unchangable_recursive_call)
5576 fprintf (dump_file, "Function calls itself with insufficient "
5577 "number of arguments.\n");
5581 adjustments = analyze_all_param_acesses ();
5582 if (!adjustments.exists ())
5585 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
5587 if (modify_function (node, adjustments))
5588 ret = TODO_update_ssa | TODO_cleanup_cfg;
5590 ret = TODO_update_ssa;
5591 adjustments.release ();
5593 statistics_counter_event (cfun, "Unused parameters deleted",
5594 sra_stats.deleted_unused_parameters);
5595 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
5596 sra_stats.scalar_by_ref_to_by_val);
5597 statistics_counter_event (cfun, "Aggregate parameters broken up",
5598 sra_stats.aggregate_params_reduced);
5599 statistics_counter_event (cfun, "Aggregate parameter components created",
5600 sra_stats.param_reductions_created);
5603 BITMAP_FREE (final_bbs);
5604 free (bb_dereferences);
5606 sra_deinitialize ();
5612 const pass_data pass_data_early_ipa_sra =
5614 GIMPLE_PASS, /* type */
5615 "eipa_sra", /* name */
5616 OPTGROUP_NONE, /* optinfo_flags */
5617 TV_IPA_SRA, /* tv_id */
5618 0, /* properties_required */
5619 0, /* properties_provided */
5620 0, /* properties_destroyed */
5621 0, /* todo_flags_start */
5622 TODO_dump_symtab, /* todo_flags_finish */
5625 class pass_early_ipa_sra : public gimple_opt_pass
5628 pass_early_ipa_sra (gcc::context *ctxt)
5629 : gimple_opt_pass (pass_data_early_ipa_sra, ctxt)
5632 /* opt_pass methods: */
5633 virtual bool gate (function *) { return flag_ipa_sra && dbg_cnt (eipa_sra); }
5634 virtual unsigned int execute (function *) { return ipa_early_sra (); }
5636 }; // class pass_early_ipa_sra
5641 make_pass_early_ipa_sra (gcc::context *ctxt)
5643 return new pass_early_ipa_sra (ctxt);