1 /* Scalar Replacement of Aggregates (SRA) converts some structure
2 references into scalar references, exposing them to the scalar
4 Copyright (C) 2008-2014 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"
77 #include "hash-table.h"
78 #include "alloc-pool.h"
81 #include "pointer-set.h"
82 #include "basic-block.h"
83 #include "tree-ssa-alias.h"
84 #include "internal-fn.h"
86 #include "gimple-expr.h"
89 #include "stor-layout.h"
91 #include "gimple-iterator.h"
92 #include "gimplify-me.h"
93 #include "gimple-walk.h"
95 #include "gimple-ssa.h"
97 #include "tree-phinodes.h"
98 #include "ssa-iterators.h"
99 #include "stringpool.h"
100 #include "tree-ssanames.h"
102 #include "tree-dfa.h"
103 #include "tree-ssa.h"
104 #include "tree-pass.h"
105 #include "ipa-prop.h"
106 #include "statistics.h"
111 #include "tree-inline.h"
112 #include "gimple-pretty-print.h"
113 #include "ipa-inline.h"
114 #include "ipa-utils.h"
115 #include "builtins.h"
117 /* Enumeration of all aggregate reductions we can do. */
118 enum sra_mode
{ SRA_MODE_EARLY_IPA
, /* early call regularization */
119 SRA_MODE_EARLY_INTRA
, /* early intraprocedural SRA */
120 SRA_MODE_INTRA
}; /* late intraprocedural SRA */
122 /* Global variable describing which aggregate reduction we are performing at
124 static enum sra_mode sra_mode
;
128 /* ACCESS represents each access to an aggregate variable (as a whole or a
129 part). It can also represent a group of accesses that refer to exactly the
130 same fragment of an aggregate (i.e. those that have exactly the same offset
131 and size). Such representatives for a single aggregate, once determined,
132 are linked in a linked list and have the group fields set.
134 Moreover, when doing intraprocedural SRA, a tree is built from those
135 representatives (by the means of first_child and next_sibling pointers), in
136 which all items in a subtree are "within" the root, i.e. their offset is
137 greater or equal to offset of the root and offset+size is smaller or equal
138 to offset+size of the root. Children of an access are sorted by offset.
140 Note that accesses to parts of vector and complex number types always
141 represented by an access to the whole complex number or a vector. It is a
142 duty of the modifying functions to replace them appropriately. */
146 /* Values returned by `get_ref_base_and_extent' for each component reference
147 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
148 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
149 HOST_WIDE_INT offset
;
153 /* Expression. It is context dependent so do not use it to create new
154 expressions to access the original aggregate. See PR 42154 for a
160 /* The statement this access belongs to. */
163 /* Next group representative for this aggregate. */
164 struct access
*next_grp
;
166 /* Pointer to the group representative. Pointer to itself if the struct is
167 the representative. */
168 struct access
*group_representative
;
170 /* If this access has any children (in terms of the definition above), this
171 points to the first one. */
172 struct access
*first_child
;
174 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
175 described above. In IPA-SRA this is a pointer to the next access
176 belonging to the same group (having the same representative). */
177 struct access
*next_sibling
;
179 /* Pointers to the first and last element in the linked list of assign
181 struct assign_link
*first_link
, *last_link
;
183 /* Pointer to the next access in the work queue. */
184 struct access
*next_queued
;
186 /* Replacement variable for this access "region." Never to be accessed
187 directly, always only by the means of get_access_replacement() and only
188 when grp_to_be_replaced flag is set. */
189 tree replacement_decl
;
191 /* Is this particular access write access? */
194 /* Is this access an access to a non-addressable field? */
195 unsigned non_addressable
: 1;
197 /* Is this access currently in the work queue? */
198 unsigned grp_queued
: 1;
200 /* Does this group contain a write access? This flag is propagated down the
202 unsigned grp_write
: 1;
204 /* Does this group contain a read access? This flag is propagated down the
206 unsigned grp_read
: 1;
208 /* Does this group contain a read access that comes from an assignment
209 statement? This flag is propagated down the access tree. */
210 unsigned grp_assignment_read
: 1;
212 /* Does this group contain a write access that comes from an assignment
213 statement? This flag is propagated down the access tree. */
214 unsigned grp_assignment_write
: 1;
216 /* Does this group contain a read access through a scalar type? This flag is
217 not propagated in the access tree in any direction. */
218 unsigned grp_scalar_read
: 1;
220 /* Does this group contain a write access through a scalar type? This flag
221 is not propagated in the access tree in any direction. */
222 unsigned grp_scalar_write
: 1;
224 /* Is this access an artificial one created to scalarize some record
226 unsigned grp_total_scalarization
: 1;
228 /* Other passes of the analysis use this bit to make function
229 analyze_access_subtree create scalar replacements for this group if
231 unsigned grp_hint
: 1;
233 /* Is the subtree rooted in this access fully covered by scalar
235 unsigned grp_covered
: 1;
237 /* If set to true, this access and all below it in an access tree must not be
239 unsigned grp_unscalarizable_region
: 1;
241 /* Whether data have been written to parts of the aggregate covered by this
242 access which is not to be scalarized. This flag is propagated up in the
244 unsigned grp_unscalarized_data
: 1;
246 /* Does this access and/or group contain a write access through a
248 unsigned grp_partial_lhs
: 1;
250 /* Set when a scalar replacement should be created for this variable. */
251 unsigned grp_to_be_replaced
: 1;
253 /* Set when we want a replacement for the sole purpose of having it in
254 generated debug statements. */
255 unsigned grp_to_be_debug_replaced
: 1;
257 /* Should TREE_NO_WARNING of a replacement be set? */
258 unsigned grp_no_warning
: 1;
260 /* Is it possible that the group refers to data which might be (directly or
261 otherwise) modified? */
262 unsigned grp_maybe_modified
: 1;
264 /* Set when this is a representative of a pointer to scalar (i.e. by
265 reference) parameter which we consider for turning into a plain scalar
266 (i.e. a by value parameter). */
267 unsigned grp_scalar_ptr
: 1;
269 /* Set when we discover that this pointer is not safe to dereference in the
271 unsigned grp_not_necessarilly_dereferenced
: 1;
274 typedef struct access
*access_p
;
277 /* Alloc pool for allocating access structures. */
278 static alloc_pool access_pool
;
280 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
281 are used to propagate subaccesses from rhs to lhs as long as they don't
282 conflict with what is already there. */
285 struct access
*lacc
, *racc
;
286 struct assign_link
*next
;
289 /* Alloc pool for allocating assign link structures. */
290 static alloc_pool link_pool
;
292 /* Base (tree) -> Vector (vec<access_p> *) map. */
293 static struct pointer_map_t
*base_access_vec
;
295 /* Candidate hash table helpers. */
297 struct uid_decl_hasher
: typed_noop_remove
<tree_node
>
299 typedef tree_node value_type
;
300 typedef tree_node compare_type
;
301 static inline hashval_t
hash (const value_type
*);
302 static inline bool equal (const value_type
*, const compare_type
*);
305 /* Hash a tree in a uid_decl_map. */
308 uid_decl_hasher::hash (const value_type
*item
)
310 return item
->decl_minimal
.uid
;
313 /* Return true if the DECL_UID in both trees are equal. */
316 uid_decl_hasher::equal (const value_type
*a
, const compare_type
*b
)
318 return (a
->decl_minimal
.uid
== b
->decl_minimal
.uid
);
321 /* Set of candidates. */
322 static bitmap candidate_bitmap
;
323 static hash_table
<uid_decl_hasher
> *candidates
;
325 /* For a candidate UID return the candidates decl. */
328 candidate (unsigned uid
)
331 t
.decl_minimal
.uid
= uid
;
332 return candidates
->find_with_hash (&t
, static_cast <hashval_t
> (uid
));
335 /* Bitmap of candidates which we should try to entirely scalarize away and
336 those which cannot be (because they are and need be used as a whole). */
337 static bitmap should_scalarize_away_bitmap
, cannot_scalarize_away_bitmap
;
339 /* Obstack for creation of fancy names. */
340 static struct obstack name_obstack
;
342 /* Head of a linked list of accesses that need to have its subaccesses
343 propagated to their assignment counterparts. */
344 static struct access
*work_queue_head
;
346 /* Number of parameters of the analyzed function when doing early ipa SRA. */
347 static int func_param_count
;
349 /* scan_function sets the following to true if it encounters a call to
350 __builtin_apply_args. */
351 static bool encountered_apply_args
;
353 /* Set by scan_function when it finds a recursive call. */
354 static bool encountered_recursive_call
;
356 /* Set by scan_function when it finds a recursive call with less actual
357 arguments than formal parameters.. */
358 static bool encountered_unchangable_recursive_call
;
360 /* This is a table in which for each basic block and parameter there is a
361 distance (offset + size) in that parameter which is dereferenced and
362 accessed in that BB. */
363 static HOST_WIDE_INT
*bb_dereferences
;
364 /* Bitmap of BBs that can cause the function to "stop" progressing by
365 returning, throwing externally, looping infinitely or calling a function
366 which might abort etc.. */
367 static bitmap final_bbs
;
369 /* Representative of no accesses at all. */
370 static struct access no_accesses_representant
;
372 /* Predicate to test the special value. */
375 no_accesses_p (struct access
*access
)
377 return access
== &no_accesses_representant
;
380 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
381 representative fields are dumped, otherwise those which only describe the
382 individual access are. */
386 /* Number of processed aggregates is readily available in
387 analyze_all_variable_accesses and so is not stored here. */
389 /* Number of created scalar replacements. */
392 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
396 /* Number of statements created by generate_subtree_copies. */
399 /* Number of statements created by load_assign_lhs_subreplacements. */
402 /* Number of times sra_modify_assign has deleted a statement. */
405 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
406 RHS reparately due to type conversions or nonexistent matching
408 int separate_lhs_rhs_handling
;
410 /* Number of parameters that were removed because they were unused. */
411 int deleted_unused_parameters
;
413 /* Number of scalars passed as parameters by reference that have been
414 converted to be passed by value. */
415 int scalar_by_ref_to_by_val
;
417 /* Number of aggregate parameters that were replaced by one or more of their
419 int aggregate_params_reduced
;
421 /* Numbber of components created when splitting aggregate parameters. */
422 int param_reductions_created
;
426 dump_access (FILE *f
, struct access
*access
, bool grp
)
428 fprintf (f
, "access { ");
429 fprintf (f
, "base = (%d)'", DECL_UID (access
->base
));
430 print_generic_expr (f
, access
->base
, 0);
431 fprintf (f
, "', offset = " HOST_WIDE_INT_PRINT_DEC
, access
->offset
);
432 fprintf (f
, ", size = " HOST_WIDE_INT_PRINT_DEC
, access
->size
);
433 fprintf (f
, ", expr = ");
434 print_generic_expr (f
, access
->expr
, 0);
435 fprintf (f
, ", type = ");
436 print_generic_expr (f
, access
->type
, 0);
438 fprintf (f
, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
439 "grp_assignment_write = %d, grp_scalar_read = %d, "
440 "grp_scalar_write = %d, grp_total_scalarization = %d, "
441 "grp_hint = %d, grp_covered = %d, "
442 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
443 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
444 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
445 "grp_not_necessarilly_dereferenced = %d\n",
446 access
->grp_read
, access
->grp_write
, access
->grp_assignment_read
,
447 access
->grp_assignment_write
, access
->grp_scalar_read
,
448 access
->grp_scalar_write
, access
->grp_total_scalarization
,
449 access
->grp_hint
, access
->grp_covered
,
450 access
->grp_unscalarizable_region
, access
->grp_unscalarized_data
,
451 access
->grp_partial_lhs
, access
->grp_to_be_replaced
,
452 access
->grp_to_be_debug_replaced
, access
->grp_maybe_modified
,
453 access
->grp_not_necessarilly_dereferenced
);
455 fprintf (f
, ", write = %d, grp_total_scalarization = %d, "
456 "grp_partial_lhs = %d\n",
457 access
->write
, access
->grp_total_scalarization
,
458 access
->grp_partial_lhs
);
461 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
464 dump_access_tree_1 (FILE *f
, struct access
*access
, int level
)
470 for (i
= 0; i
< level
; i
++)
471 fputs ("* ", dump_file
);
473 dump_access (f
, access
, true);
475 if (access
->first_child
)
476 dump_access_tree_1 (f
, access
->first_child
, level
+ 1);
478 access
= access
->next_sibling
;
483 /* Dump all access trees for a variable, given the pointer to the first root in
487 dump_access_tree (FILE *f
, struct access
*access
)
489 for (; access
; access
= access
->next_grp
)
490 dump_access_tree_1 (f
, access
, 0);
493 /* Return true iff ACC is non-NULL and has subaccesses. */
496 access_has_children_p (struct access
*acc
)
498 return acc
&& acc
->first_child
;
501 /* Return true iff ACC is (partly) covered by at least one replacement. */
504 access_has_replacements_p (struct access
*acc
)
506 struct access
*child
;
507 if (acc
->grp_to_be_replaced
)
509 for (child
= acc
->first_child
; child
; child
= child
->next_sibling
)
510 if (access_has_replacements_p (child
))
515 /* Return a vector of pointers to accesses for the variable given in BASE or
516 NULL if there is none. */
518 static vec
<access_p
> *
519 get_base_access_vector (tree base
)
523 slot
= pointer_map_contains (base_access_vec
, base
);
527 return *(vec
<access_p
> **) slot
;
530 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
531 in ACCESS. Return NULL if it cannot be found. */
533 static struct access
*
534 find_access_in_subtree (struct access
*access
, HOST_WIDE_INT offset
,
537 while (access
&& (access
->offset
!= offset
|| access
->size
!= size
))
539 struct access
*child
= access
->first_child
;
541 while (child
&& (child
->offset
+ child
->size
<= offset
))
542 child
= child
->next_sibling
;
549 /* Return the first group representative for DECL or NULL if none exists. */
551 static struct access
*
552 get_first_repr_for_decl (tree base
)
554 vec
<access_p
> *access_vec
;
556 access_vec
= get_base_access_vector (base
);
560 return (*access_vec
)[0];
563 /* Find an access representative for the variable BASE and given OFFSET and
564 SIZE. Requires that access trees have already been built. Return NULL if
565 it cannot be found. */
567 static struct access
*
568 get_var_base_offset_size_access (tree base
, HOST_WIDE_INT offset
,
571 struct access
*access
;
573 access
= get_first_repr_for_decl (base
);
574 while (access
&& (access
->offset
+ access
->size
<= offset
))
575 access
= access
->next_grp
;
579 return find_access_in_subtree (access
, offset
, size
);
582 /* Add LINK to the linked list of assign links of RACC. */
584 add_link_to_rhs (struct access
*racc
, struct assign_link
*link
)
586 gcc_assert (link
->racc
== racc
);
588 if (!racc
->first_link
)
590 gcc_assert (!racc
->last_link
);
591 racc
->first_link
= link
;
594 racc
->last_link
->next
= link
;
596 racc
->last_link
= link
;
600 /* Move all link structures in their linked list in OLD_RACC to the linked list
603 relink_to_new_repr (struct access
*new_racc
, struct access
*old_racc
)
605 if (!old_racc
->first_link
)
607 gcc_assert (!old_racc
->last_link
);
611 if (new_racc
->first_link
)
613 gcc_assert (!new_racc
->last_link
->next
);
614 gcc_assert (!old_racc
->last_link
|| !old_racc
->last_link
->next
);
616 new_racc
->last_link
->next
= old_racc
->first_link
;
617 new_racc
->last_link
= old_racc
->last_link
;
621 gcc_assert (!new_racc
->last_link
);
623 new_racc
->first_link
= old_racc
->first_link
;
624 new_racc
->last_link
= old_racc
->last_link
;
626 old_racc
->first_link
= old_racc
->last_link
= NULL
;
629 /* Add ACCESS to the work queue (which is actually a stack). */
632 add_access_to_work_queue (struct access
*access
)
634 if (!access
->grp_queued
)
636 gcc_assert (!access
->next_queued
);
637 access
->next_queued
= work_queue_head
;
638 access
->grp_queued
= 1;
639 work_queue_head
= access
;
643 /* Pop an access from the work queue, and return it, assuming there is one. */
645 static struct access
*
646 pop_access_from_work_queue (void)
648 struct access
*access
= work_queue_head
;
650 work_queue_head
= access
->next_queued
;
651 access
->next_queued
= NULL
;
652 access
->grp_queued
= 0;
657 /* Allocate necessary structures. */
660 sra_initialize (void)
662 candidate_bitmap
= BITMAP_ALLOC (NULL
);
663 candidates
= new hash_table
<uid_decl_hasher
>
664 (vec_safe_length (cfun
->local_decls
) / 2);
665 should_scalarize_away_bitmap
= BITMAP_ALLOC (NULL
);
666 cannot_scalarize_away_bitmap
= BITMAP_ALLOC (NULL
);
667 gcc_obstack_init (&name_obstack
);
668 access_pool
= create_alloc_pool ("SRA accesses", sizeof (struct access
), 16);
669 link_pool
= create_alloc_pool ("SRA links", sizeof (struct assign_link
), 16);
670 base_access_vec
= pointer_map_create ();
671 memset (&sra_stats
, 0, sizeof (sra_stats
));
672 encountered_apply_args
= false;
673 encountered_recursive_call
= false;
674 encountered_unchangable_recursive_call
= false;
677 /* Hook fed to pointer_map_traverse, deallocate stored vectors. */
680 delete_base_accesses (const void *key ATTRIBUTE_UNUSED
, void **value
,
681 void *data ATTRIBUTE_UNUSED
)
683 vec
<access_p
> *access_vec
= (vec
<access_p
> *) *value
;
684 vec_free (access_vec
);
688 /* Deallocate all general structures. */
691 sra_deinitialize (void)
693 BITMAP_FREE (candidate_bitmap
);
696 BITMAP_FREE (should_scalarize_away_bitmap
);
697 BITMAP_FREE (cannot_scalarize_away_bitmap
);
698 free_alloc_pool (access_pool
);
699 free_alloc_pool (link_pool
);
700 obstack_free (&name_obstack
, NULL
);
702 pointer_map_traverse (base_access_vec
, delete_base_accesses
, NULL
);
703 pointer_map_destroy (base_access_vec
);
706 /* Remove DECL from candidates for SRA and write REASON to the dump file if
709 disqualify_candidate (tree decl
, const char *reason
)
711 if (bitmap_clear_bit (candidate_bitmap
, DECL_UID (decl
)))
712 candidates
->remove_elt_with_hash (decl
, DECL_UID (decl
));
714 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
716 fprintf (dump_file
, "! Disqualifying ");
717 print_generic_expr (dump_file
, decl
, 0);
718 fprintf (dump_file
, " - %s\n", reason
);
722 /* Return true iff the type contains a field or an element which does not allow
726 type_internals_preclude_sra_p (tree type
, const char **msg
)
731 switch (TREE_CODE (type
))
735 case QUAL_UNION_TYPE
:
736 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
737 if (TREE_CODE (fld
) == FIELD_DECL
)
739 tree ft
= TREE_TYPE (fld
);
741 if (TREE_THIS_VOLATILE (fld
))
743 *msg
= "volatile structure field";
746 if (!DECL_FIELD_OFFSET (fld
))
748 *msg
= "no structure field offset";
751 if (!DECL_SIZE (fld
))
753 *msg
= "zero structure field size";
756 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
758 *msg
= "structure field offset not fixed";
761 if (!tree_fits_uhwi_p (DECL_SIZE (fld
)))
763 *msg
= "structure field size not fixed";
766 if (!tree_fits_shwi_p (bit_position (fld
)))
768 *msg
= "structure field size too big";
771 if (AGGREGATE_TYPE_P (ft
)
772 && int_bit_position (fld
) % BITS_PER_UNIT
!= 0)
774 *msg
= "structure field is bit field";
778 if (AGGREGATE_TYPE_P (ft
) && type_internals_preclude_sra_p (ft
, msg
))
785 et
= TREE_TYPE (type
);
787 if (TYPE_VOLATILE (et
))
789 *msg
= "element type is volatile";
793 if (AGGREGATE_TYPE_P (et
) && type_internals_preclude_sra_p (et
, msg
))
803 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
804 base variable if it is. Return T if it is not an SSA_NAME. */
807 get_ssa_base_param (tree t
)
809 if (TREE_CODE (t
) == SSA_NAME
)
811 if (SSA_NAME_IS_DEFAULT_DEF (t
))
812 return SSA_NAME_VAR (t
);
819 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
820 belongs to, unless the BB has already been marked as a potentially
824 mark_parm_dereference (tree base
, HOST_WIDE_INT dist
, gimple stmt
)
826 basic_block bb
= gimple_bb (stmt
);
827 int idx
, parm_index
= 0;
830 if (bitmap_bit_p (final_bbs
, bb
->index
))
833 for (parm
= DECL_ARGUMENTS (current_function_decl
);
834 parm
&& parm
!= base
;
835 parm
= DECL_CHAIN (parm
))
838 gcc_assert (parm_index
< func_param_count
);
840 idx
= bb
->index
* func_param_count
+ parm_index
;
841 if (bb_dereferences
[idx
] < dist
)
842 bb_dereferences
[idx
] = dist
;
845 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
846 the three fields. Also add it to the vector of accesses corresponding to
847 the base. Finally, return the new access. */
849 static struct access
*
850 create_access_1 (tree base
, HOST_WIDE_INT offset
, HOST_WIDE_INT size
)
853 struct access
*access
;
856 access
= (struct access
*) pool_alloc (access_pool
);
857 memset (access
, 0, sizeof (struct access
));
859 access
->offset
= offset
;
862 slot
= pointer_map_contains (base_access_vec
, base
);
864 v
= (vec
<access_p
> *) *slot
;
868 v
->safe_push (access
);
871 pointer_map_insert (base_access_vec
, base
)) = v
;
876 /* Create and insert access for EXPR. Return created access, or NULL if it is
879 static struct access
*
880 create_access (tree expr
, gimple stmt
, bool write
)
882 struct access
*access
;
883 HOST_WIDE_INT offset
, size
, max_size
;
885 bool ptr
, unscalarizable_region
= false;
887 base
= get_ref_base_and_extent (expr
, &offset
, &size
, &max_size
);
889 if (sra_mode
== SRA_MODE_EARLY_IPA
890 && TREE_CODE (base
) == MEM_REF
)
892 base
= get_ssa_base_param (TREE_OPERAND (base
, 0));
900 if (!DECL_P (base
) || !bitmap_bit_p (candidate_bitmap
, DECL_UID (base
)))
903 if (sra_mode
== SRA_MODE_EARLY_IPA
)
905 if (size
< 0 || size
!= max_size
)
907 disqualify_candidate (base
, "Encountered a variable sized access.");
910 if (TREE_CODE (expr
) == COMPONENT_REF
911 && DECL_BIT_FIELD (TREE_OPERAND (expr
, 1)))
913 disqualify_candidate (base
, "Encountered a bit-field access.");
916 gcc_checking_assert ((offset
% BITS_PER_UNIT
) == 0);
919 mark_parm_dereference (base
, offset
+ size
, stmt
);
923 if (size
!= max_size
)
926 unscalarizable_region
= true;
930 disqualify_candidate (base
, "Encountered an unconstrained access.");
935 access
= create_access_1 (base
, offset
, size
);
937 access
->type
= TREE_TYPE (expr
);
938 access
->write
= write
;
939 access
->grp_unscalarizable_region
= unscalarizable_region
;
942 if (TREE_CODE (expr
) == COMPONENT_REF
943 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr
, 1)))
944 access
->non_addressable
= 1;
950 /* Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple
951 register types or (recursively) records with only these two kinds of fields.
952 It also returns false if any of these records contains a bit-field. */
955 type_consists_of_records_p (tree type
)
959 if (TREE_CODE (type
) != RECORD_TYPE
)
962 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
963 if (TREE_CODE (fld
) == FIELD_DECL
)
965 tree ft
= TREE_TYPE (fld
);
967 if (DECL_BIT_FIELD (fld
))
970 if (!is_gimple_reg_type (ft
)
971 && !type_consists_of_records_p (ft
))
978 /* Create total_scalarization accesses for all scalar type fields in DECL that
979 must be of a RECORD_TYPE conforming to type_consists_of_records_p. BASE
980 must be the top-most VAR_DECL representing the variable, OFFSET must be the
981 offset of DECL within BASE. REF must be the memory reference expression for
985 completely_scalarize_record (tree base
, tree decl
, HOST_WIDE_INT offset
,
988 tree fld
, decl_type
= TREE_TYPE (decl
);
990 for (fld
= TYPE_FIELDS (decl_type
); fld
; fld
= DECL_CHAIN (fld
))
991 if (TREE_CODE (fld
) == FIELD_DECL
)
993 HOST_WIDE_INT pos
= offset
+ int_bit_position (fld
);
994 tree ft
= TREE_TYPE (fld
);
995 tree nref
= build3 (COMPONENT_REF
, TREE_TYPE (fld
), ref
, fld
,
998 if (is_gimple_reg_type (ft
))
1000 struct access
*access
;
1003 size
= tree_to_uhwi (DECL_SIZE (fld
));
1004 access
= create_access_1 (base
, pos
, size
);
1005 access
->expr
= nref
;
1007 access
->grp_total_scalarization
= 1;
1008 /* Accesses for intraprocedural SRA can have their stmt NULL. */
1011 completely_scalarize_record (base
, fld
, pos
, nref
);
1015 /* Create total_scalarization accesses for all scalar type fields in VAR and
1016 for VAR a a whole. VAR must be of a RECORD_TYPE conforming to
1017 type_consists_of_records_p. */
1020 completely_scalarize_var (tree var
)
1022 HOST_WIDE_INT size
= tree_to_uhwi (DECL_SIZE (var
));
1023 struct access
*access
;
1025 access
= create_access_1 (var
, 0, size
);
1027 access
->type
= TREE_TYPE (var
);
1028 access
->grp_total_scalarization
= 1;
1030 completely_scalarize_record (var
, var
, 0, var
);
1033 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1036 contains_view_convert_expr_p (const_tree ref
)
1038 while (handled_component_p (ref
))
1040 if (TREE_CODE (ref
) == VIEW_CONVERT_EXPR
)
1042 ref
= TREE_OPERAND (ref
, 0);
1048 /* Search the given tree for a declaration by skipping handled components and
1049 exclude it from the candidates. */
1052 disqualify_base_of_expr (tree t
, const char *reason
)
1054 t
= get_base_address (t
);
1055 if (sra_mode
== SRA_MODE_EARLY_IPA
1056 && TREE_CODE (t
) == MEM_REF
)
1057 t
= get_ssa_base_param (TREE_OPERAND (t
, 0));
1059 if (t
&& DECL_P (t
))
1060 disqualify_candidate (t
, reason
);
1063 /* Scan expression EXPR and create access structures for all accesses to
1064 candidates for scalarization. Return the created access or NULL if none is
1067 static struct access
*
1068 build_access_from_expr_1 (tree expr
, gimple stmt
, bool write
)
1070 struct access
*ret
= NULL
;
1073 if (TREE_CODE (expr
) == BIT_FIELD_REF
1074 || TREE_CODE (expr
) == IMAGPART_EXPR
1075 || TREE_CODE (expr
) == REALPART_EXPR
)
1077 expr
= TREE_OPERAND (expr
, 0);
1081 partial_ref
= false;
1083 /* We need to dive through V_C_Es in order to get the size of its parameter
1084 and not the result type. Ada produces such statements. We are also
1085 capable of handling the topmost V_C_E but not any of those buried in other
1086 handled components. */
1087 if (TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
1088 expr
= TREE_OPERAND (expr
, 0);
1090 if (contains_view_convert_expr_p (expr
))
1092 disqualify_base_of_expr (expr
, "V_C_E under a different handled "
1097 switch (TREE_CODE (expr
))
1100 if (TREE_CODE (TREE_OPERAND (expr
, 0)) != ADDR_EXPR
1101 && sra_mode
!= SRA_MODE_EARLY_IPA
)
1109 case ARRAY_RANGE_REF
:
1110 ret
= create_access (expr
, stmt
, write
);
1117 if (write
&& partial_ref
&& ret
)
1118 ret
->grp_partial_lhs
= 1;
1123 /* Scan expression EXPR and create access structures for all accesses to
1124 candidates for scalarization. Return true if any access has been inserted.
1125 STMT must be the statement from which the expression is taken, WRITE must be
1126 true if the expression is a store and false otherwise. */
1129 build_access_from_expr (tree expr
, gimple stmt
, bool write
)
1131 struct access
*access
;
1133 access
= build_access_from_expr_1 (expr
, stmt
, write
);
1136 /* This means the aggregate is accesses as a whole in a way other than an
1137 assign statement and thus cannot be removed even if we had a scalar
1138 replacement for everything. */
1139 if (cannot_scalarize_away_bitmap
)
1140 bitmap_set_bit (cannot_scalarize_away_bitmap
, DECL_UID (access
->base
));
1146 /* Return the single non-EH successor edge of BB or NULL if there is none or
1150 single_non_eh_succ (basic_block bb
)
1155 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1156 if (!(e
->flags
& EDGE_EH
))
1166 /* Disqualify LHS and RHS for scalarization if STMT has to terminate its BB and
1167 there is no alternative spot where to put statements SRA might need to
1168 generate after it. The spot we are looking for is an edge leading to a
1169 single non-EH successor, if it exists and is indeed single. RHS may be
1170 NULL, in that case ignore it. */
1173 disqualify_if_bad_bb_terminating_stmt (gimple stmt
, tree lhs
, tree rhs
)
1175 if ((sra_mode
== SRA_MODE_EARLY_INTRA
|| sra_mode
== SRA_MODE_INTRA
)
1176 && stmt_ends_bb_p (stmt
))
1178 if (single_non_eh_succ (gimple_bb (stmt
)))
1181 disqualify_base_of_expr (lhs
, "LHS of a throwing stmt.");
1183 disqualify_base_of_expr (rhs
, "RHS of a throwing stmt.");
1189 /* Scan expressions occurring in STMT, create access structures for all accesses
1190 to candidates for scalarization and remove those candidates which occur in
1191 statements or expressions that prevent them from being split apart. Return
1192 true if any access has been inserted. */
1195 build_accesses_from_assign (gimple stmt
)
1198 struct access
*lacc
, *racc
;
1200 if (!gimple_assign_single_p (stmt
)
1201 /* Scope clobbers don't influence scalarization. */
1202 || gimple_clobber_p (stmt
))
1205 lhs
= gimple_assign_lhs (stmt
);
1206 rhs
= gimple_assign_rhs1 (stmt
);
1208 if (disqualify_if_bad_bb_terminating_stmt (stmt
, lhs
, rhs
))
1211 racc
= build_access_from_expr_1 (rhs
, stmt
, false);
1212 lacc
= build_access_from_expr_1 (lhs
, stmt
, true);
1215 lacc
->grp_assignment_write
= 1;
1219 racc
->grp_assignment_read
= 1;
1220 if (should_scalarize_away_bitmap
&& !gimple_has_volatile_ops (stmt
)
1221 && !is_gimple_reg_type (racc
->type
))
1222 bitmap_set_bit (should_scalarize_away_bitmap
, DECL_UID (racc
->base
));
1226 && (sra_mode
== SRA_MODE_EARLY_INTRA
|| sra_mode
== SRA_MODE_INTRA
)
1227 && !lacc
->grp_unscalarizable_region
1228 && !racc
->grp_unscalarizable_region
1229 && AGGREGATE_TYPE_P (TREE_TYPE (lhs
))
1230 && lacc
->size
== racc
->size
1231 && useless_type_conversion_p (lacc
->type
, racc
->type
))
1233 struct assign_link
*link
;
1235 link
= (struct assign_link
*) pool_alloc (link_pool
);
1236 memset (link
, 0, sizeof (struct assign_link
));
1241 add_link_to_rhs (racc
, link
);
1244 return lacc
|| racc
;
1247 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1248 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1251 asm_visit_addr (gimple
, tree op
, tree
, void *)
1253 op
= get_base_address (op
);
1256 disqualify_candidate (op
, "Non-scalarizable GIMPLE_ASM operand.");
1261 /* Return true iff callsite CALL has at least as many actual arguments as there
1262 are formal parameters of the function currently processed by IPA-SRA and
1263 that their types match. */
1266 callsite_arguments_match_p (gimple call
)
1268 if (gimple_call_num_args (call
) < (unsigned) func_param_count
)
1273 for (parm
= DECL_ARGUMENTS (current_function_decl
), i
= 0;
1275 parm
= DECL_CHAIN (parm
), i
++)
1277 tree arg
= gimple_call_arg (call
, i
);
1278 if (!useless_type_conversion_p (TREE_TYPE (parm
), TREE_TYPE (arg
)))
1284 /* Scan function and look for interesting expressions and create access
1285 structures for them. Return true iff any access is created. */
1288 scan_function (void)
1293 FOR_EACH_BB_FN (bb
, cfun
)
1295 gimple_stmt_iterator gsi
;
1296 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1298 gimple stmt
= gsi_stmt (gsi
);
1302 if (final_bbs
&& stmt_can_throw_external (stmt
))
1303 bitmap_set_bit (final_bbs
, bb
->index
);
1304 switch (gimple_code (stmt
))
1307 t
= gimple_return_retval (stmt
);
1309 ret
|= build_access_from_expr (t
, stmt
, false);
1311 bitmap_set_bit (final_bbs
, bb
->index
);
1315 ret
|= build_accesses_from_assign (stmt
);
1319 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1320 ret
|= build_access_from_expr (gimple_call_arg (stmt
, i
),
1323 if (sra_mode
== SRA_MODE_EARLY_IPA
)
1325 tree dest
= gimple_call_fndecl (stmt
);
1326 int flags
= gimple_call_flags (stmt
);
1330 if (DECL_BUILT_IN_CLASS (dest
) == BUILT_IN_NORMAL
1331 && DECL_FUNCTION_CODE (dest
) == BUILT_IN_APPLY_ARGS
)
1332 encountered_apply_args
= true;
1333 if (recursive_call_p (current_function_decl
, dest
))
1335 encountered_recursive_call
= true;
1336 if (!callsite_arguments_match_p (stmt
))
1337 encountered_unchangable_recursive_call
= true;
1342 && (flags
& (ECF_CONST
| ECF_PURE
)) == 0)
1343 bitmap_set_bit (final_bbs
, bb
->index
);
1346 t
= gimple_call_lhs (stmt
);
1347 if (t
&& !disqualify_if_bad_bb_terminating_stmt (stmt
, t
, NULL
))
1348 ret
|= build_access_from_expr (t
, stmt
, true);
1352 walk_stmt_load_store_addr_ops (stmt
, NULL
, NULL
, NULL
,
1355 bitmap_set_bit (final_bbs
, bb
->index
);
1357 for (i
= 0; i
< gimple_asm_ninputs (stmt
); i
++)
1359 t
= TREE_VALUE (gimple_asm_input_op (stmt
, i
));
1360 ret
|= build_access_from_expr (t
, stmt
, false);
1362 for (i
= 0; i
< gimple_asm_noutputs (stmt
); i
++)
1364 t
= TREE_VALUE (gimple_asm_output_op (stmt
, i
));
1365 ret
|= build_access_from_expr (t
, stmt
, true);
1378 /* Helper of QSORT function. There are pointers to accesses in the array. An
1379 access is considered smaller than another if it has smaller offset or if the
1380 offsets are the same but is size is bigger. */
1383 compare_access_positions (const void *a
, const void *b
)
1385 const access_p
*fp1
= (const access_p
*) a
;
1386 const access_p
*fp2
= (const access_p
*) b
;
1387 const access_p f1
= *fp1
;
1388 const access_p f2
= *fp2
;
1390 if (f1
->offset
!= f2
->offset
)
1391 return f1
->offset
< f2
->offset
? -1 : 1;
1393 if (f1
->size
== f2
->size
)
1395 if (f1
->type
== f2
->type
)
1397 /* Put any non-aggregate type before any aggregate type. */
1398 else if (!is_gimple_reg_type (f1
->type
)
1399 && is_gimple_reg_type (f2
->type
))
1401 else if (is_gimple_reg_type (f1
->type
)
1402 && !is_gimple_reg_type (f2
->type
))
1404 /* Put any complex or vector type before any other scalar type. */
1405 else if (TREE_CODE (f1
->type
) != COMPLEX_TYPE
1406 && TREE_CODE (f1
->type
) != VECTOR_TYPE
1407 && (TREE_CODE (f2
->type
) == COMPLEX_TYPE
1408 || TREE_CODE (f2
->type
) == VECTOR_TYPE
))
1410 else if ((TREE_CODE (f1
->type
) == COMPLEX_TYPE
1411 || TREE_CODE (f1
->type
) == VECTOR_TYPE
)
1412 && TREE_CODE (f2
->type
) != COMPLEX_TYPE
1413 && TREE_CODE (f2
->type
) != VECTOR_TYPE
)
1415 /* Put the integral type with the bigger precision first. */
1416 else if (INTEGRAL_TYPE_P (f1
->type
)
1417 && INTEGRAL_TYPE_P (f2
->type
))
1418 return TYPE_PRECISION (f2
->type
) - TYPE_PRECISION (f1
->type
);
1419 /* Put any integral type with non-full precision last. */
1420 else if (INTEGRAL_TYPE_P (f1
->type
)
1421 && (TREE_INT_CST_LOW (TYPE_SIZE (f1
->type
))
1422 != TYPE_PRECISION (f1
->type
)))
1424 else if (INTEGRAL_TYPE_P (f2
->type
)
1425 && (TREE_INT_CST_LOW (TYPE_SIZE (f2
->type
))
1426 != TYPE_PRECISION (f2
->type
)))
1428 /* Stabilize the sort. */
1429 return TYPE_UID (f1
->type
) - TYPE_UID (f2
->type
);
1432 /* We want the bigger accesses first, thus the opposite operator in the next
1434 return f1
->size
> f2
->size
? -1 : 1;
1438 /* Append a name of the declaration to the name obstack. A helper function for
1442 make_fancy_decl_name (tree decl
)
1446 tree name
= DECL_NAME (decl
);
1448 obstack_grow (&name_obstack
, IDENTIFIER_POINTER (name
),
1449 IDENTIFIER_LENGTH (name
));
1452 sprintf (buffer
, "D%u", DECL_UID (decl
));
1453 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1457 /* Helper for make_fancy_name. */
1460 make_fancy_name_1 (tree expr
)
1467 make_fancy_decl_name (expr
);
1471 switch (TREE_CODE (expr
))
1474 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1475 obstack_1grow (&name_obstack
, '$');
1476 make_fancy_decl_name (TREE_OPERAND (expr
, 1));
1480 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1481 obstack_1grow (&name_obstack
, '$');
1482 /* Arrays with only one element may not have a constant as their
1484 index
= TREE_OPERAND (expr
, 1);
1485 if (TREE_CODE (index
) != INTEGER_CST
)
1487 sprintf (buffer
, HOST_WIDE_INT_PRINT_DEC
, TREE_INT_CST_LOW (index
));
1488 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1492 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1496 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1497 if (!integer_zerop (TREE_OPERAND (expr
, 1)))
1499 obstack_1grow (&name_obstack
, '$');
1500 sprintf (buffer
, HOST_WIDE_INT_PRINT_DEC
,
1501 TREE_INT_CST_LOW (TREE_OPERAND (expr
, 1)));
1502 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1509 gcc_unreachable (); /* we treat these as scalars. */
1516 /* Create a human readable name for replacement variable of ACCESS. */
1519 make_fancy_name (tree expr
)
1521 make_fancy_name_1 (expr
);
1522 obstack_1grow (&name_obstack
, '\0');
1523 return XOBFINISH (&name_obstack
, char *);
1526 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1527 EXP_TYPE at the given OFFSET. If BASE is something for which
1528 get_addr_base_and_unit_offset returns NULL, gsi must be non-NULL and is used
1529 to insert new statements either before or below the current one as specified
1530 by INSERT_AFTER. This function is not capable of handling bitfields.
1532 BASE must be either a declaration or a memory reference that has correct
1533 alignment ifformation embeded in it (e.g. a pre-existing one in SRA). */
1536 build_ref_for_offset (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1537 tree exp_type
, gimple_stmt_iterator
*gsi
,
1540 tree prev_base
= base
;
1543 HOST_WIDE_INT base_offset
;
1544 unsigned HOST_WIDE_INT misalign
;
1547 gcc_checking_assert (offset
% BITS_PER_UNIT
== 0);
1548 get_object_alignment_1 (base
, &align
, &misalign
);
1549 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
1551 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1552 offset such as array[var_index]. */
1558 gcc_checking_assert (gsi
);
1559 tmp
= make_ssa_name (build_pointer_type (TREE_TYPE (prev_base
)), NULL
);
1560 addr
= build_fold_addr_expr (unshare_expr (prev_base
));
1561 STRIP_USELESS_TYPE_CONVERSION (addr
);
1562 stmt
= gimple_build_assign (tmp
, addr
);
1563 gimple_set_location (stmt
, loc
);
1565 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
1567 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
1569 off
= build_int_cst (reference_alias_ptr_type (prev_base
),
1570 offset
/ BITS_PER_UNIT
);
1573 else if (TREE_CODE (base
) == MEM_REF
)
1575 off
= build_int_cst (TREE_TYPE (TREE_OPERAND (base
, 1)),
1576 base_offset
+ offset
/ BITS_PER_UNIT
);
1577 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1), off
);
1578 base
= unshare_expr (TREE_OPERAND (base
, 0));
1582 off
= build_int_cst (reference_alias_ptr_type (base
),
1583 base_offset
+ offset
/ BITS_PER_UNIT
);
1584 base
= build_fold_addr_expr (unshare_expr (base
));
1587 misalign
= (misalign
+ offset
) & (align
- 1);
1589 align
= (misalign
& -misalign
);
1590 if (align
< TYPE_ALIGN (exp_type
))
1591 exp_type
= build_aligned_type (exp_type
, align
);
1593 mem_ref
= fold_build2_loc (loc
, MEM_REF
, exp_type
, base
, off
);
1594 if (TREE_THIS_VOLATILE (prev_base
))
1595 TREE_THIS_VOLATILE (mem_ref
) = 1;
1596 if (TREE_SIDE_EFFECTS (prev_base
))
1597 TREE_SIDE_EFFECTS (mem_ref
) = 1;
1601 /* Construct a memory reference to a part of an aggregate BASE at the given
1602 OFFSET and of the same type as MODEL. In case this is a reference to a
1603 bit-field, the function will replicate the last component_ref of model's
1604 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1605 build_ref_for_offset. */
1608 build_ref_for_model (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1609 struct access
*model
, gimple_stmt_iterator
*gsi
,
1612 if (TREE_CODE (model
->expr
) == COMPONENT_REF
1613 && DECL_BIT_FIELD (TREE_OPERAND (model
->expr
, 1)))
1615 /* This access represents a bit-field. */
1616 tree t
, exp_type
, fld
= TREE_OPERAND (model
->expr
, 1);
1618 offset
-= int_bit_position (fld
);
1619 exp_type
= TREE_TYPE (TREE_OPERAND (model
->expr
, 0));
1620 t
= build_ref_for_offset (loc
, base
, offset
, exp_type
, gsi
, insert_after
);
1621 return fold_build3_loc (loc
, COMPONENT_REF
, TREE_TYPE (fld
), t
, fld
,
1625 return build_ref_for_offset (loc
, base
, offset
, model
->type
,
1629 /* Attempt to build a memory reference that we could but into a gimple
1630 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1631 create statements and return s NULL instead. This function also ignores
1632 alignment issues and so its results should never end up in non-debug
1636 build_debug_ref_for_model (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1637 struct access
*model
)
1639 HOST_WIDE_INT base_offset
;
1642 if (TREE_CODE (model
->expr
) == COMPONENT_REF
1643 && DECL_BIT_FIELD (TREE_OPERAND (model
->expr
, 1)))
1646 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
1649 if (TREE_CODE (base
) == MEM_REF
)
1651 off
= build_int_cst (TREE_TYPE (TREE_OPERAND (base
, 1)),
1652 base_offset
+ offset
/ BITS_PER_UNIT
);
1653 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1), off
);
1654 base
= unshare_expr (TREE_OPERAND (base
, 0));
1658 off
= build_int_cst (reference_alias_ptr_type (base
),
1659 base_offset
+ offset
/ BITS_PER_UNIT
);
1660 base
= build_fold_addr_expr (unshare_expr (base
));
1663 return fold_build2_loc (loc
, MEM_REF
, model
->type
, base
, off
);
1666 /* Construct a memory reference consisting of component_refs and array_refs to
1667 a part of an aggregate *RES (which is of type TYPE). The requested part
1668 should have type EXP_TYPE at be the given OFFSET. This function might not
1669 succeed, it returns true when it does and only then *RES points to something
1670 meaningful. This function should be used only to build expressions that we
1671 might need to present to user (e.g. in warnings). In all other situations,
1672 build_ref_for_model or build_ref_for_offset should be used instead. */
1675 build_user_friendly_ref_for_offset (tree
*res
, tree type
, HOST_WIDE_INT offset
,
1681 tree tr_size
, index
, minidx
;
1682 HOST_WIDE_INT el_size
;
1684 if (offset
== 0 && exp_type
1685 && types_compatible_p (exp_type
, type
))
1688 switch (TREE_CODE (type
))
1691 case QUAL_UNION_TYPE
:
1693 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
1695 HOST_WIDE_INT pos
, size
;
1696 tree tr_pos
, expr
, *expr_ptr
;
1698 if (TREE_CODE (fld
) != FIELD_DECL
)
1701 tr_pos
= bit_position (fld
);
1702 if (!tr_pos
|| !tree_fits_uhwi_p (tr_pos
))
1704 pos
= tree_to_uhwi (tr_pos
);
1705 gcc_assert (TREE_CODE (type
) == RECORD_TYPE
|| pos
== 0);
1706 tr_size
= DECL_SIZE (fld
);
1707 if (!tr_size
|| !tree_fits_uhwi_p (tr_size
))
1709 size
= tree_to_uhwi (tr_size
);
1715 else if (pos
> offset
|| (pos
+ size
) <= offset
)
1718 expr
= build3 (COMPONENT_REF
, TREE_TYPE (fld
), *res
, fld
,
1721 if (build_user_friendly_ref_for_offset (expr_ptr
, TREE_TYPE (fld
),
1722 offset
- pos
, exp_type
))
1731 tr_size
= TYPE_SIZE (TREE_TYPE (type
));
1732 if (!tr_size
|| !tree_fits_uhwi_p (tr_size
))
1734 el_size
= tree_to_uhwi (tr_size
);
1736 minidx
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
1737 if (TREE_CODE (minidx
) != INTEGER_CST
|| el_size
== 0)
1739 index
= build_int_cst (TYPE_DOMAIN (type
), offset
/ el_size
);
1740 if (!integer_zerop (minidx
))
1741 index
= int_const_binop (PLUS_EXPR
, index
, minidx
);
1742 *res
= build4 (ARRAY_REF
, TREE_TYPE (type
), *res
, index
,
1743 NULL_TREE
, NULL_TREE
);
1744 offset
= offset
% el_size
;
1745 type
= TREE_TYPE (type
);
1760 /* Return true iff TYPE is stdarg va_list type. */
1763 is_va_list_type (tree type
)
1765 return TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (va_list_type_node
);
1768 /* Print message to dump file why a variable was rejected. */
1771 reject (tree var
, const char *msg
)
1773 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1775 fprintf (dump_file
, "Rejected (%d): %s: ", DECL_UID (var
), msg
);
1776 print_generic_expr (dump_file
, var
, 0);
1777 fprintf (dump_file
, "\n");
1781 /* Return true if VAR is a candidate for SRA. */
1784 maybe_add_sra_candidate (tree var
)
1786 tree type
= TREE_TYPE (var
);
1790 if (!AGGREGATE_TYPE_P (type
))
1792 reject (var
, "not aggregate");
1795 if (needs_to_live_in_memory (var
))
1797 reject (var
, "needs to live in memory");
1800 if (TREE_THIS_VOLATILE (var
))
1802 reject (var
, "is volatile");
1805 if (!COMPLETE_TYPE_P (type
))
1807 reject (var
, "has incomplete type");
1810 if (!tree_fits_uhwi_p (TYPE_SIZE (type
)))
1812 reject (var
, "type size not fixed");
1815 if (tree_to_uhwi (TYPE_SIZE (type
)) == 0)
1817 reject (var
, "type size is zero");
1820 if (type_internals_preclude_sra_p (type
, &msg
))
1825 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1826 we also want to schedule it rather late. Thus we ignore it in
1828 (sra_mode
== SRA_MODE_EARLY_INTRA
1829 && is_va_list_type (type
)))
1831 reject (var
, "is va_list");
1835 bitmap_set_bit (candidate_bitmap
, DECL_UID (var
));
1836 slot
= candidates
->find_slot_with_hash (var
, DECL_UID (var
), INSERT
);
1839 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1841 fprintf (dump_file
, "Candidate (%d): ", DECL_UID (var
));
1842 print_generic_expr (dump_file
, var
, 0);
1843 fprintf (dump_file
, "\n");
1849 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1850 those with type which is suitable for scalarization. */
1853 find_var_candidates (void)
1859 for (parm
= DECL_ARGUMENTS (current_function_decl
);
1861 parm
= DECL_CHAIN (parm
))
1862 ret
|= maybe_add_sra_candidate (parm
);
1864 FOR_EACH_LOCAL_DECL (cfun
, i
, var
)
1866 if (TREE_CODE (var
) != VAR_DECL
)
1869 ret
|= maybe_add_sra_candidate (var
);
1875 /* Sort all accesses for the given variable, check for partial overlaps and
1876 return NULL if there are any. If there are none, pick a representative for
1877 each combination of offset and size and create a linked list out of them.
1878 Return the pointer to the first representative and make sure it is the first
1879 one in the vector of accesses. */
1881 static struct access
*
1882 sort_and_splice_var_accesses (tree var
)
1884 int i
, j
, access_count
;
1885 struct access
*res
, **prev_acc_ptr
= &res
;
1886 vec
<access_p
> *access_vec
;
1888 HOST_WIDE_INT low
= -1, high
= 0;
1890 access_vec
= get_base_access_vector (var
);
1893 access_count
= access_vec
->length ();
1895 /* Sort by <OFFSET, SIZE>. */
1896 access_vec
->qsort (compare_access_positions
);
1899 while (i
< access_count
)
1901 struct access
*access
= (*access_vec
)[i
];
1902 bool grp_write
= access
->write
;
1903 bool grp_read
= !access
->write
;
1904 bool grp_scalar_write
= access
->write
1905 && is_gimple_reg_type (access
->type
);
1906 bool grp_scalar_read
= !access
->write
1907 && is_gimple_reg_type (access
->type
);
1908 bool grp_assignment_read
= access
->grp_assignment_read
;
1909 bool grp_assignment_write
= access
->grp_assignment_write
;
1910 bool multiple_scalar_reads
= false;
1911 bool total_scalarization
= access
->grp_total_scalarization
;
1912 bool grp_partial_lhs
= access
->grp_partial_lhs
;
1913 bool first_scalar
= is_gimple_reg_type (access
->type
);
1914 bool unscalarizable_region
= access
->grp_unscalarizable_region
;
1916 if (first
|| access
->offset
>= high
)
1919 low
= access
->offset
;
1920 high
= access
->offset
+ access
->size
;
1922 else if (access
->offset
> low
&& access
->offset
+ access
->size
> high
)
1925 gcc_assert (access
->offset
>= low
1926 && access
->offset
+ access
->size
<= high
);
1929 while (j
< access_count
)
1931 struct access
*ac2
= (*access_vec
)[j
];
1932 if (ac2
->offset
!= access
->offset
|| ac2
->size
!= access
->size
)
1937 grp_scalar_write
= (grp_scalar_write
1938 || is_gimple_reg_type (ac2
->type
));
1943 if (is_gimple_reg_type (ac2
->type
))
1945 if (grp_scalar_read
)
1946 multiple_scalar_reads
= true;
1948 grp_scalar_read
= true;
1951 grp_assignment_read
|= ac2
->grp_assignment_read
;
1952 grp_assignment_write
|= ac2
->grp_assignment_write
;
1953 grp_partial_lhs
|= ac2
->grp_partial_lhs
;
1954 unscalarizable_region
|= ac2
->grp_unscalarizable_region
;
1955 total_scalarization
|= ac2
->grp_total_scalarization
;
1956 relink_to_new_repr (access
, ac2
);
1958 /* If there are both aggregate-type and scalar-type accesses with
1959 this combination of size and offset, the comparison function
1960 should have put the scalars first. */
1961 gcc_assert (first_scalar
|| !is_gimple_reg_type (ac2
->type
));
1962 ac2
->group_representative
= access
;
1968 access
->group_representative
= access
;
1969 access
->grp_write
= grp_write
;
1970 access
->grp_read
= grp_read
;
1971 access
->grp_scalar_read
= grp_scalar_read
;
1972 access
->grp_scalar_write
= grp_scalar_write
;
1973 access
->grp_assignment_read
= grp_assignment_read
;
1974 access
->grp_assignment_write
= grp_assignment_write
;
1975 access
->grp_hint
= multiple_scalar_reads
|| total_scalarization
;
1976 access
->grp_total_scalarization
= total_scalarization
;
1977 access
->grp_partial_lhs
= grp_partial_lhs
;
1978 access
->grp_unscalarizable_region
= unscalarizable_region
;
1979 if (access
->first_link
)
1980 add_access_to_work_queue (access
);
1982 *prev_acc_ptr
= access
;
1983 prev_acc_ptr
= &access
->next_grp
;
1986 gcc_assert (res
== (*access_vec
)[0]);
1990 /* Create a variable for the given ACCESS which determines the type, name and a
1991 few other properties. Return the variable declaration and store it also to
1992 ACCESS->replacement. */
1995 create_access_replacement (struct access
*access
)
1999 if (access
->grp_to_be_debug_replaced
)
2001 repl
= create_tmp_var_raw (access
->type
, NULL
);
2002 DECL_CONTEXT (repl
) = current_function_decl
;
2005 repl
= create_tmp_var (access
->type
, "SR");
2006 if (TREE_CODE (access
->type
) == COMPLEX_TYPE
2007 || TREE_CODE (access
->type
) == VECTOR_TYPE
)
2009 if (!access
->grp_partial_lhs
)
2010 DECL_GIMPLE_REG_P (repl
) = 1;
2012 else if (access
->grp_partial_lhs
2013 && is_gimple_reg_type (access
->type
))
2014 TREE_ADDRESSABLE (repl
) = 1;
2016 DECL_SOURCE_LOCATION (repl
) = DECL_SOURCE_LOCATION (access
->base
);
2017 DECL_ARTIFICIAL (repl
) = 1;
2018 DECL_IGNORED_P (repl
) = DECL_IGNORED_P (access
->base
);
2020 if (DECL_NAME (access
->base
)
2021 && !DECL_IGNORED_P (access
->base
)
2022 && !DECL_ARTIFICIAL (access
->base
))
2024 char *pretty_name
= make_fancy_name (access
->expr
);
2025 tree debug_expr
= unshare_expr_without_location (access
->expr
), d
;
2028 DECL_NAME (repl
) = get_identifier (pretty_name
);
2029 obstack_free (&name_obstack
, pretty_name
);
2031 /* Get rid of any SSA_NAMEs embedded in debug_expr,
2032 as DECL_DEBUG_EXPR isn't considered when looking for still
2033 used SSA_NAMEs and thus they could be freed. All debug info
2034 generation cares is whether something is constant or variable
2035 and that get_ref_base_and_extent works properly on the
2036 expression. It cannot handle accesses at a non-constant offset
2037 though, so just give up in those cases. */
2038 for (d
= debug_expr
;
2039 !fail
&& (handled_component_p (d
) || TREE_CODE (d
) == MEM_REF
);
2040 d
= TREE_OPERAND (d
, 0))
2041 switch (TREE_CODE (d
))
2044 case ARRAY_RANGE_REF
:
2045 if (TREE_OPERAND (d
, 1)
2046 && TREE_CODE (TREE_OPERAND (d
, 1)) != INTEGER_CST
)
2048 if (TREE_OPERAND (d
, 3)
2049 && TREE_CODE (TREE_OPERAND (d
, 3)) != INTEGER_CST
)
2053 if (TREE_OPERAND (d
, 2)
2054 && TREE_CODE (TREE_OPERAND (d
, 2)) != INTEGER_CST
)
2058 if (TREE_CODE (TREE_OPERAND (d
, 0)) != ADDR_EXPR
)
2061 d
= TREE_OPERAND (d
, 0);
2068 SET_DECL_DEBUG_EXPR (repl
, debug_expr
);
2069 DECL_HAS_DEBUG_EXPR_P (repl
) = 1;
2071 if (access
->grp_no_warning
)
2072 TREE_NO_WARNING (repl
) = 1;
2074 TREE_NO_WARNING (repl
) = TREE_NO_WARNING (access
->base
);
2077 TREE_NO_WARNING (repl
) = 1;
2081 if (access
->grp_to_be_debug_replaced
)
2083 fprintf (dump_file
, "Created a debug-only replacement for ");
2084 print_generic_expr (dump_file
, access
->base
, 0);
2085 fprintf (dump_file
, " offset: %u, size: %u\n",
2086 (unsigned) access
->offset
, (unsigned) access
->size
);
2090 fprintf (dump_file
, "Created a replacement for ");
2091 print_generic_expr (dump_file
, access
->base
, 0);
2092 fprintf (dump_file
, " offset: %u, size: %u: ",
2093 (unsigned) access
->offset
, (unsigned) access
->size
);
2094 print_generic_expr (dump_file
, repl
, 0);
2095 fprintf (dump_file
, "\n");
2098 sra_stats
.replacements
++;
2103 /* Return ACCESS scalar replacement, create it if it does not exist yet. */
2106 get_access_replacement (struct access
*access
)
2108 gcc_checking_assert (access
->replacement_decl
);
2109 return access
->replacement_decl
;
2113 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2114 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2115 to it is not "within" the root. Return false iff some accesses partially
2119 build_access_subtree (struct access
**access
)
2121 struct access
*root
= *access
, *last_child
= NULL
;
2122 HOST_WIDE_INT limit
= root
->offset
+ root
->size
;
2124 *access
= (*access
)->next_grp
;
2125 while (*access
&& (*access
)->offset
+ (*access
)->size
<= limit
)
2128 root
->first_child
= *access
;
2130 last_child
->next_sibling
= *access
;
2131 last_child
= *access
;
2133 if (!build_access_subtree (access
))
2137 if (*access
&& (*access
)->offset
< limit
)
2143 /* Build a tree of access representatives, ACCESS is the pointer to the first
2144 one, others are linked in a list by the next_grp field. Return false iff
2145 some accesses partially overlap. */
2148 build_access_trees (struct access
*access
)
2152 struct access
*root
= access
;
2154 if (!build_access_subtree (&access
))
2156 root
->next_grp
= access
;
2161 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2165 expr_with_var_bounded_array_refs_p (tree expr
)
2167 while (handled_component_p (expr
))
2169 if (TREE_CODE (expr
) == ARRAY_REF
2170 && !tree_fits_shwi_p (array_ref_low_bound (expr
)))
2172 expr
= TREE_OPERAND (expr
, 0);
2177 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2178 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2179 sorts of access flags appropriately along the way, notably always set
2180 grp_read and grp_assign_read according to MARK_READ and grp_write when
2183 Creating a replacement for a scalar access is considered beneficial if its
2184 grp_hint is set (this means we are either attempting total scalarization or
2185 there is more than one direct read access) or according to the following
2188 Access written to through a scalar type (once or more times)
2190 | Written to in an assignment statement
2192 | | Access read as scalar _once_
2194 | | | Read in an assignment statement
2196 | | | | Scalarize Comment
2197 -----------------------------------------------------------------------------
2198 0 0 0 0 No access for the scalar
2199 0 0 0 1 No access for the scalar
2200 0 0 1 0 No Single read - won't help
2201 0 0 1 1 No The same case
2202 0 1 0 0 No access for the scalar
2203 0 1 0 1 No access for the scalar
2204 0 1 1 0 Yes s = *g; return s.i;
2205 0 1 1 1 Yes The same case as above
2206 1 0 0 0 No Won't help
2207 1 0 0 1 Yes s.i = 1; *g = s;
2208 1 0 1 0 Yes s.i = 5; g = s.i;
2209 1 0 1 1 Yes The same case as above
2210 1 1 0 0 No Won't help.
2211 1 1 0 1 Yes s.i = 1; *g = s;
2212 1 1 1 0 Yes s = *g; return s.i;
2213 1 1 1 1 Yes Any of the above yeses */
2216 analyze_access_subtree (struct access
*root
, struct access
*parent
,
2217 bool allow_replacements
)
2219 struct access
*child
;
2220 HOST_WIDE_INT limit
= root
->offset
+ root
->size
;
2221 HOST_WIDE_INT covered_to
= root
->offset
;
2222 bool scalar
= is_gimple_reg_type (root
->type
);
2223 bool hole
= false, sth_created
= false;
2227 if (parent
->grp_read
)
2229 if (parent
->grp_assignment_read
)
2230 root
->grp_assignment_read
= 1;
2231 if (parent
->grp_write
)
2232 root
->grp_write
= 1;
2233 if (parent
->grp_assignment_write
)
2234 root
->grp_assignment_write
= 1;
2235 if (parent
->grp_total_scalarization
)
2236 root
->grp_total_scalarization
= 1;
2239 if (root
->grp_unscalarizable_region
)
2240 allow_replacements
= false;
2242 if (allow_replacements
&& expr_with_var_bounded_array_refs_p (root
->expr
))
2243 allow_replacements
= false;
2245 for (child
= root
->first_child
; child
; child
= child
->next_sibling
)
2247 hole
|= covered_to
< child
->offset
;
2248 sth_created
|= analyze_access_subtree (child
, root
,
2249 allow_replacements
&& !scalar
);
2251 root
->grp_unscalarized_data
|= child
->grp_unscalarized_data
;
2252 root
->grp_total_scalarization
&= child
->grp_total_scalarization
;
2253 if (child
->grp_covered
)
2254 covered_to
+= child
->size
;
2259 if (allow_replacements
&& scalar
&& !root
->first_child
2261 || ((root
->grp_scalar_read
|| root
->grp_assignment_read
)
2262 && (root
->grp_scalar_write
|| root
->grp_assignment_write
))))
2264 /* Always create access replacements that cover the whole access.
2265 For integral types this means the precision has to match.
2266 Avoid assumptions based on the integral type kind, too. */
2267 if (INTEGRAL_TYPE_P (root
->type
)
2268 && (TREE_CODE (root
->type
) != INTEGER_TYPE
2269 || TYPE_PRECISION (root
->type
) != root
->size
)
2270 /* But leave bitfield accesses alone. */
2271 && (TREE_CODE (root
->expr
) != COMPONENT_REF
2272 || !DECL_BIT_FIELD (TREE_OPERAND (root
->expr
, 1))))
2274 tree rt
= root
->type
;
2275 gcc_assert ((root
->offset
% BITS_PER_UNIT
) == 0
2276 && (root
->size
% BITS_PER_UNIT
) == 0);
2277 root
->type
= build_nonstandard_integer_type (root
->size
,
2278 TYPE_UNSIGNED (rt
));
2279 root
->expr
= build_ref_for_offset (UNKNOWN_LOCATION
,
2280 root
->base
, root
->offset
,
2281 root
->type
, NULL
, false);
2283 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2285 fprintf (dump_file
, "Changing the type of a replacement for ");
2286 print_generic_expr (dump_file
, root
->base
, 0);
2287 fprintf (dump_file
, " offset: %u, size: %u ",
2288 (unsigned) root
->offset
, (unsigned) root
->size
);
2289 fprintf (dump_file
, " to an integer.\n");
2293 root
->grp_to_be_replaced
= 1;
2294 root
->replacement_decl
= create_access_replacement (root
);
2300 if (allow_replacements
2301 && scalar
&& !root
->first_child
2302 && (root
->grp_scalar_write
|| root
->grp_assignment_write
)
2303 && !bitmap_bit_p (cannot_scalarize_away_bitmap
,
2304 DECL_UID (root
->base
)))
2306 gcc_checking_assert (!root
->grp_scalar_read
2307 && !root
->grp_assignment_read
);
2309 if (MAY_HAVE_DEBUG_STMTS
)
2311 root
->grp_to_be_debug_replaced
= 1;
2312 root
->replacement_decl
= create_access_replacement (root
);
2316 if (covered_to
< limit
)
2319 root
->grp_total_scalarization
= 0;
2322 if (!hole
|| root
->grp_total_scalarization
)
2323 root
->grp_covered
= 1;
2324 else if (root
->grp_write
|| TREE_CODE (root
->base
) == PARM_DECL
)
2325 root
->grp_unscalarized_data
= 1; /* not covered and written to */
2329 /* Analyze all access trees linked by next_grp by the means of
2330 analyze_access_subtree. */
2332 analyze_access_trees (struct access
*access
)
2338 if (analyze_access_subtree (access
, NULL
, true))
2340 access
= access
->next_grp
;
2346 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2347 SIZE would conflict with an already existing one. If exactly such a child
2348 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2351 child_would_conflict_in_lacc (struct access
*lacc
, HOST_WIDE_INT norm_offset
,
2352 HOST_WIDE_INT size
, struct access
**exact_match
)
2354 struct access
*child
;
2356 for (child
= lacc
->first_child
; child
; child
= child
->next_sibling
)
2358 if (child
->offset
== norm_offset
&& child
->size
== size
)
2360 *exact_match
= child
;
2364 if (child
->offset
< norm_offset
+ size
2365 && child
->offset
+ child
->size
> norm_offset
)
2372 /* Create a new child access of PARENT, with all properties just like MODEL
2373 except for its offset and with its grp_write false and grp_read true.
2374 Return the new access or NULL if it cannot be created. Note that this access
2375 is created long after all splicing and sorting, it's not located in any
2376 access vector and is automatically a representative of its group. */
2378 static struct access
*
2379 create_artificial_child_access (struct access
*parent
, struct access
*model
,
2380 HOST_WIDE_INT new_offset
)
2382 struct access
*access
;
2383 struct access
**child
;
2384 tree expr
= parent
->base
;
2386 gcc_assert (!model
->grp_unscalarizable_region
);
2388 access
= (struct access
*) pool_alloc (access_pool
);
2389 memset (access
, 0, sizeof (struct access
));
2390 if (!build_user_friendly_ref_for_offset (&expr
, TREE_TYPE (expr
), new_offset
,
2393 access
->grp_no_warning
= true;
2394 expr
= build_ref_for_model (EXPR_LOCATION (parent
->base
), parent
->base
,
2395 new_offset
, model
, NULL
, false);
2398 access
->base
= parent
->base
;
2399 access
->expr
= expr
;
2400 access
->offset
= new_offset
;
2401 access
->size
= model
->size
;
2402 access
->type
= model
->type
;
2403 access
->grp_write
= true;
2404 access
->grp_read
= false;
2406 child
= &parent
->first_child
;
2407 while (*child
&& (*child
)->offset
< new_offset
)
2408 child
= &(*child
)->next_sibling
;
2410 access
->next_sibling
= *child
;
2417 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
2418 true if any new subaccess was created. Additionally, if RACC is a scalar
2419 access but LACC is not, change the type of the latter, if possible. */
2422 propagate_subaccesses_across_link (struct access
*lacc
, struct access
*racc
)
2424 struct access
*rchild
;
2425 HOST_WIDE_INT norm_delta
= lacc
->offset
- racc
->offset
;
2428 if (is_gimple_reg_type (lacc
->type
)
2429 || lacc
->grp_unscalarizable_region
2430 || racc
->grp_unscalarizable_region
)
2433 if (is_gimple_reg_type (racc
->type
))
2435 if (!lacc
->first_child
&& !racc
->first_child
)
2437 tree t
= lacc
->base
;
2439 lacc
->type
= racc
->type
;
2440 if (build_user_friendly_ref_for_offset (&t
, TREE_TYPE (t
),
2441 lacc
->offset
, racc
->type
))
2445 lacc
->expr
= build_ref_for_model (EXPR_LOCATION (lacc
->base
),
2446 lacc
->base
, lacc
->offset
,
2448 lacc
->grp_no_warning
= true;
2454 for (rchild
= racc
->first_child
; rchild
; rchild
= rchild
->next_sibling
)
2456 struct access
*new_acc
= NULL
;
2457 HOST_WIDE_INT norm_offset
= rchild
->offset
+ norm_delta
;
2459 if (rchild
->grp_unscalarizable_region
)
2462 if (child_would_conflict_in_lacc (lacc
, norm_offset
, rchild
->size
,
2467 rchild
->grp_hint
= 1;
2468 new_acc
->grp_hint
|= new_acc
->grp_read
;
2469 if (rchild
->first_child
)
2470 ret
|= propagate_subaccesses_across_link (new_acc
, rchild
);
2475 rchild
->grp_hint
= 1;
2476 new_acc
= create_artificial_child_access (lacc
, rchild
, norm_offset
);
2480 if (racc
->first_child
)
2481 propagate_subaccesses_across_link (new_acc
, rchild
);
2488 /* Propagate all subaccesses across assignment links. */
2491 propagate_all_subaccesses (void)
2493 while (work_queue_head
)
2495 struct access
*racc
= pop_access_from_work_queue ();
2496 struct assign_link
*link
;
2498 gcc_assert (racc
->first_link
);
2500 for (link
= racc
->first_link
; link
; link
= link
->next
)
2502 struct access
*lacc
= link
->lacc
;
2504 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (lacc
->base
)))
2506 lacc
= lacc
->group_representative
;
2507 if (propagate_subaccesses_across_link (lacc
, racc
)
2508 && lacc
->first_link
)
2509 add_access_to_work_queue (lacc
);
2514 /* Go through all accesses collected throughout the (intraprocedural) analysis
2515 stage, exclude overlapping ones, identify representatives and build trees
2516 out of them, making decisions about scalarization on the way. Return true
2517 iff there are any to-be-scalarized variables after this stage. */
2520 analyze_all_variable_accesses (void)
2523 bitmap tmp
= BITMAP_ALLOC (NULL
);
2525 unsigned i
, max_total_scalarization_size
;
2527 max_total_scalarization_size
= UNITS_PER_WORD
* BITS_PER_UNIT
2528 * MOVE_RATIO (optimize_function_for_speed_p (cfun
));
2530 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap
, 0, i
, bi
)
2531 if (bitmap_bit_p (should_scalarize_away_bitmap
, i
)
2532 && !bitmap_bit_p (cannot_scalarize_away_bitmap
, i
))
2534 tree var
= candidate (i
);
2536 if (TREE_CODE (var
) == VAR_DECL
2537 && type_consists_of_records_p (TREE_TYPE (var
)))
2539 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var
)))
2540 <= max_total_scalarization_size
)
2542 completely_scalarize_var (var
);
2543 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2545 fprintf (dump_file
, "Will attempt to totally scalarize ");
2546 print_generic_expr (dump_file
, var
, 0);
2547 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (var
));
2550 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2552 fprintf (dump_file
, "Too big to totally scalarize: ");
2553 print_generic_expr (dump_file
, var
, 0);
2554 fprintf (dump_file
, " (UID: %u)\n", DECL_UID (var
));
2559 bitmap_copy (tmp
, candidate_bitmap
);
2560 EXECUTE_IF_SET_IN_BITMAP (tmp
, 0, i
, bi
)
2562 tree var
= candidate (i
);
2563 struct access
*access
;
2565 access
= sort_and_splice_var_accesses (var
);
2566 if (!access
|| !build_access_trees (access
))
2567 disqualify_candidate (var
,
2568 "No or inhibitingly overlapping accesses.");
2571 propagate_all_subaccesses ();
2573 bitmap_copy (tmp
, candidate_bitmap
);
2574 EXECUTE_IF_SET_IN_BITMAP (tmp
, 0, i
, bi
)
2576 tree var
= candidate (i
);
2577 struct access
*access
= get_first_repr_for_decl (var
);
2579 if (analyze_access_trees (access
))
2582 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2584 fprintf (dump_file
, "\nAccess trees for ");
2585 print_generic_expr (dump_file
, var
, 0);
2586 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (var
));
2587 dump_access_tree (dump_file
, access
);
2588 fprintf (dump_file
, "\n");
2592 disqualify_candidate (var
, "No scalar replacements to be created.");
2599 statistics_counter_event (cfun
, "Scalarized aggregates", res
);
2606 /* Generate statements copying scalar replacements of accesses within a subtree
2607 into or out of AGG. ACCESS, all its children, siblings and their children
2608 are to be processed. AGG is an aggregate type expression (can be a
2609 declaration but does not have to be, it can for example also be a mem_ref or
2610 a series of handled components). TOP_OFFSET is the offset of the processed
2611 subtree which has to be subtracted from offsets of individual accesses to
2612 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2613 replacements in the interval <start_offset, start_offset + chunk_size>,
2614 otherwise copy all. GSI is a statement iterator used to place the new
2615 statements. WRITE should be true when the statements should write from AGG
2616 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2617 statements will be added after the current statement in GSI, they will be
2618 added before the statement otherwise. */
2621 generate_subtree_copies (struct access
*access
, tree agg
,
2622 HOST_WIDE_INT top_offset
,
2623 HOST_WIDE_INT start_offset
, HOST_WIDE_INT chunk_size
,
2624 gimple_stmt_iterator
*gsi
, bool write
,
2625 bool insert_after
, location_t loc
)
2629 if (chunk_size
&& access
->offset
>= start_offset
+ chunk_size
)
2632 if (access
->grp_to_be_replaced
2634 || access
->offset
+ access
->size
> start_offset
))
2636 tree expr
, repl
= get_access_replacement (access
);
2639 expr
= build_ref_for_model (loc
, agg
, access
->offset
- top_offset
,
2640 access
, gsi
, insert_after
);
2644 if (access
->grp_partial_lhs
)
2645 expr
= force_gimple_operand_gsi (gsi
, expr
, true, NULL_TREE
,
2647 insert_after
? GSI_NEW_STMT
2649 stmt
= gimple_build_assign (repl
, expr
);
2653 TREE_NO_WARNING (repl
) = 1;
2654 if (access
->grp_partial_lhs
)
2655 repl
= force_gimple_operand_gsi (gsi
, repl
, true, NULL_TREE
,
2657 insert_after
? GSI_NEW_STMT
2659 stmt
= gimple_build_assign (expr
, repl
);
2661 gimple_set_location (stmt
, loc
);
2664 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2666 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2668 sra_stats
.subtree_copies
++;
2671 && access
->grp_to_be_debug_replaced
2673 || access
->offset
+ access
->size
> start_offset
))
2676 tree drhs
= build_debug_ref_for_model (loc
, agg
,
2677 access
->offset
- top_offset
,
2679 ds
= gimple_build_debug_bind (get_access_replacement (access
),
2680 drhs
, gsi_stmt (*gsi
));
2682 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2684 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
2687 if (access
->first_child
)
2688 generate_subtree_copies (access
->first_child
, agg
, top_offset
,
2689 start_offset
, chunk_size
, gsi
,
2690 write
, insert_after
, loc
);
2692 access
= access
->next_sibling
;
2697 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2698 the root of the subtree to be processed. GSI is the statement iterator used
2699 for inserting statements which are added after the current statement if
2700 INSERT_AFTER is true or before it otherwise. */
2703 init_subtree_with_zero (struct access
*access
, gimple_stmt_iterator
*gsi
,
2704 bool insert_after
, location_t loc
)
2707 struct access
*child
;
2709 if (access
->grp_to_be_replaced
)
2713 stmt
= gimple_build_assign (get_access_replacement (access
),
2714 build_zero_cst (access
->type
));
2716 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2718 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2720 gimple_set_location (stmt
, loc
);
2722 else if (access
->grp_to_be_debug_replaced
)
2724 gimple ds
= gimple_build_debug_bind (get_access_replacement (access
),
2725 build_zero_cst (access
->type
),
2728 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2730 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
2733 for (child
= access
->first_child
; child
; child
= child
->next_sibling
)
2734 init_subtree_with_zero (child
, gsi
, insert_after
, loc
);
2737 /* Search for an access representative for the given expression EXPR and
2738 return it or NULL if it cannot be found. */
2740 static struct access
*
2741 get_access_for_expr (tree expr
)
2743 HOST_WIDE_INT offset
, size
, max_size
;
2746 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2747 a different size than the size of its argument and we need the latter
2749 if (TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
2750 expr
= TREE_OPERAND (expr
, 0);
2752 base
= get_ref_base_and_extent (expr
, &offset
, &size
, &max_size
);
2753 if (max_size
== -1 || !DECL_P (base
))
2756 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (base
)))
2759 return get_var_base_offset_size_access (base
, offset
, max_size
);
2762 /* Replace the expression EXPR with a scalar replacement if there is one and
2763 generate other statements to do type conversion or subtree copying if
2764 necessary. GSI is used to place newly created statements, WRITE is true if
2765 the expression is being written to (it is on a LHS of a statement or output
2766 in an assembly statement). */
2769 sra_modify_expr (tree
*expr
, gimple_stmt_iterator
*gsi
, bool write
)
2772 struct access
*access
;
2773 tree type
, bfr
, orig_expr
;
2775 if (TREE_CODE (*expr
) == BIT_FIELD_REF
)
2778 expr
= &TREE_OPERAND (*expr
, 0);
2783 if (TREE_CODE (*expr
) == REALPART_EXPR
|| TREE_CODE (*expr
) == IMAGPART_EXPR
)
2784 expr
= &TREE_OPERAND (*expr
, 0);
2785 access
= get_access_for_expr (*expr
);
2788 type
= TREE_TYPE (*expr
);
2791 loc
= gimple_location (gsi_stmt (*gsi
));
2792 gimple_stmt_iterator alt_gsi
= gsi_none ();
2793 if (write
&& stmt_ends_bb_p (gsi_stmt (*gsi
)))
2795 alt_gsi
= gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi
)));
2799 if (access
->grp_to_be_replaced
)
2801 tree repl
= get_access_replacement (access
);
2802 /* If we replace a non-register typed access simply use the original
2803 access expression to extract the scalar component afterwards.
2804 This happens if scalarizing a function return value or parameter
2805 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2806 gcc.c-torture/compile/20011217-1.c.
2808 We also want to use this when accessing a complex or vector which can
2809 be accessed as a different type too, potentially creating a need for
2810 type conversion (see PR42196) and when scalarized unions are involved
2811 in assembler statements (see PR42398). */
2812 if (!useless_type_conversion_p (type
, access
->type
))
2816 ref
= build_ref_for_model (loc
, orig_expr
, 0, access
, gsi
, false);
2822 if (access
->grp_partial_lhs
)
2823 ref
= force_gimple_operand_gsi (gsi
, ref
, true, NULL_TREE
,
2824 false, GSI_NEW_STMT
);
2825 stmt
= gimple_build_assign (repl
, ref
);
2826 gimple_set_location (stmt
, loc
);
2827 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2833 if (access
->grp_partial_lhs
)
2834 repl
= force_gimple_operand_gsi (gsi
, repl
, true, NULL_TREE
,
2835 true, GSI_SAME_STMT
);
2836 stmt
= gimple_build_assign (ref
, repl
);
2837 gimple_set_location (stmt
, loc
);
2838 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2845 else if (write
&& access
->grp_to_be_debug_replaced
)
2847 gimple ds
= gimple_build_debug_bind (get_access_replacement (access
),
2850 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2853 if (access
->first_child
)
2855 HOST_WIDE_INT start_offset
, chunk_size
;
2857 && tree_fits_uhwi_p (TREE_OPERAND (bfr
, 1))
2858 && tree_fits_uhwi_p (TREE_OPERAND (bfr
, 2)))
2860 chunk_size
= tree_to_uhwi (TREE_OPERAND (bfr
, 1));
2861 start_offset
= access
->offset
2862 + tree_to_uhwi (TREE_OPERAND (bfr
, 2));
2865 start_offset
= chunk_size
= 0;
2867 generate_subtree_copies (access
->first_child
, orig_expr
, access
->offset
,
2868 start_offset
, chunk_size
, gsi
, write
, write
,
2874 /* Where scalar replacements of the RHS have been written to when a replacement
2875 of a LHS of an assigments cannot be direclty loaded from a replacement of
2877 enum unscalarized_data_handling
{ SRA_UDH_NONE
, /* Nothing done so far. */
2878 SRA_UDH_RIGHT
, /* Data flushed to the RHS. */
2879 SRA_UDH_LEFT
}; /* Data flushed to the LHS. */
2881 struct subreplacement_assignment_data
2883 /* Offset of the access representing the lhs of the assignment. */
2884 HOST_WIDE_INT left_offset
;
2886 /* LHS and RHS of the original assignment. */
2887 tree assignment_lhs
, assignment_rhs
;
2889 /* Access representing the rhs of the whole assignment. */
2890 struct access
*top_racc
;
2892 /* Stmt iterator used for statement insertions after the original assignment.
2893 It points to the main GSI used to traverse a BB during function body
2895 gimple_stmt_iterator
*new_gsi
;
2897 /* Stmt iterator used for statement insertions before the original
2898 assignment. Keeps on pointing to the original statement. */
2899 gimple_stmt_iterator old_gsi
;
2901 /* Location of the assignment. */
2904 /* Keeps the information whether we have needed to refresh replacements of
2905 the LHS and from which side of the assignments this takes place. */
2906 enum unscalarized_data_handling refreshed
;
2909 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2910 base aggregate if there are unscalarized data or directly to LHS of the
2911 statement that is pointed to by GSI otherwise. */
2914 handle_unscalarized_data_in_subtree (struct subreplacement_assignment_data
*sad
)
2917 if (sad
->top_racc
->grp_unscalarized_data
)
2919 src
= sad
->assignment_rhs
;
2920 sad
->refreshed
= SRA_UDH_RIGHT
;
2924 src
= sad
->assignment_lhs
;
2925 sad
->refreshed
= SRA_UDH_LEFT
;
2927 generate_subtree_copies (sad
->top_racc
->first_child
, src
,
2928 sad
->top_racc
->offset
, 0, 0,
2929 &sad
->old_gsi
, false, false, sad
->loc
);
2932 /* Try to generate statements to load all sub-replacements in an access subtree
2933 formed by children of LACC from scalar replacements in the SAD->top_racc
2934 subtree. If that is not possible, refresh the SAD->top_racc base aggregate
2935 and load the accesses from it. */
2938 load_assign_lhs_subreplacements (struct access
*lacc
,
2939 struct subreplacement_assignment_data
*sad
)
2941 for (lacc
= lacc
->first_child
; lacc
; lacc
= lacc
->next_sibling
)
2943 HOST_WIDE_INT offset
;
2944 offset
= lacc
->offset
- sad
->left_offset
+ sad
->top_racc
->offset
;
2946 if (lacc
->grp_to_be_replaced
)
2948 struct access
*racc
;
2952 racc
= find_access_in_subtree (sad
->top_racc
, offset
, lacc
->size
);
2953 if (racc
&& racc
->grp_to_be_replaced
)
2955 rhs
= get_access_replacement (racc
);
2956 if (!useless_type_conversion_p (lacc
->type
, racc
->type
))
2957 rhs
= fold_build1_loc (sad
->loc
, VIEW_CONVERT_EXPR
,
2960 if (racc
->grp_partial_lhs
&& lacc
->grp_partial_lhs
)
2961 rhs
= force_gimple_operand_gsi (&sad
->old_gsi
, rhs
, true,
2962 NULL_TREE
, true, GSI_SAME_STMT
);
2966 /* No suitable access on the right hand side, need to load from
2967 the aggregate. See if we have to update it first... */
2968 if (sad
->refreshed
== SRA_UDH_NONE
)
2969 handle_unscalarized_data_in_subtree (sad
);
2971 if (sad
->refreshed
== SRA_UDH_LEFT
)
2972 rhs
= build_ref_for_model (sad
->loc
, sad
->assignment_lhs
,
2973 lacc
->offset
- sad
->left_offset
,
2974 lacc
, sad
->new_gsi
, true);
2976 rhs
= build_ref_for_model (sad
->loc
, sad
->assignment_rhs
,
2977 lacc
->offset
- sad
->left_offset
,
2978 lacc
, sad
->new_gsi
, true);
2979 if (lacc
->grp_partial_lhs
)
2980 rhs
= force_gimple_operand_gsi (sad
->new_gsi
,
2981 rhs
, true, NULL_TREE
,
2982 false, GSI_NEW_STMT
);
2985 stmt
= gimple_build_assign (get_access_replacement (lacc
), rhs
);
2986 gsi_insert_after (sad
->new_gsi
, stmt
, GSI_NEW_STMT
);
2987 gimple_set_location (stmt
, sad
->loc
);
2989 sra_stats
.subreplacements
++;
2993 if (sad
->refreshed
== SRA_UDH_NONE
2994 && lacc
->grp_read
&& !lacc
->grp_covered
)
2995 handle_unscalarized_data_in_subtree (sad
);
2997 if (lacc
&& lacc
->grp_to_be_debug_replaced
)
3001 struct access
*racc
= find_access_in_subtree (sad
->top_racc
,
3005 if (racc
&& racc
->grp_to_be_replaced
)
3007 if (racc
->grp_write
)
3008 drhs
= get_access_replacement (racc
);
3012 else if (sad
->refreshed
== SRA_UDH_LEFT
)
3013 drhs
= build_debug_ref_for_model (sad
->loc
, lacc
->base
,
3014 lacc
->offset
, lacc
);
3015 else if (sad
->refreshed
== SRA_UDH_RIGHT
)
3016 drhs
= build_debug_ref_for_model (sad
->loc
, sad
->top_racc
->base
,
3021 && !useless_type_conversion_p (lacc
->type
, TREE_TYPE (drhs
)))
3022 drhs
= fold_build1_loc (sad
->loc
, VIEW_CONVERT_EXPR
,
3024 ds
= gimple_build_debug_bind (get_access_replacement (lacc
),
3025 drhs
, gsi_stmt (sad
->old_gsi
));
3026 gsi_insert_after (sad
->new_gsi
, ds
, GSI_NEW_STMT
);
3030 if (lacc
->first_child
)
3031 load_assign_lhs_subreplacements (lacc
, sad
);
3035 /* Result code for SRA assignment modification. */
3036 enum assignment_mod_result
{ SRA_AM_NONE
, /* nothing done for the stmt */
3037 SRA_AM_MODIFIED
, /* stmt changed but not
3039 SRA_AM_REMOVED
}; /* stmt eliminated */
3041 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
3042 to the assignment and GSI is the statement iterator pointing at it. Returns
3043 the same values as sra_modify_assign. */
3045 static enum assignment_mod_result
3046 sra_modify_constructor_assign (gimple
*stmt
, gimple_stmt_iterator
*gsi
)
3048 tree lhs
= gimple_assign_lhs (*stmt
);
3052 acc
= get_access_for_expr (lhs
);
3056 if (gimple_clobber_p (*stmt
))
3058 /* Remove clobbers of fully scalarized variables, otherwise
3060 if (acc
->grp_covered
)
3062 unlink_stmt_vdef (*stmt
);
3063 gsi_remove (gsi
, true);
3064 release_defs (*stmt
);
3065 return SRA_AM_REMOVED
;
3071 loc
= gimple_location (*stmt
);
3072 if (vec_safe_length (CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt
))) > 0)
3074 /* I have never seen this code path trigger but if it can happen the
3075 following should handle it gracefully. */
3076 if (access_has_children_p (acc
))
3077 generate_subtree_copies (acc
->first_child
, lhs
, acc
->offset
, 0, 0, gsi
,
3079 return SRA_AM_MODIFIED
;
3082 if (acc
->grp_covered
)
3084 init_subtree_with_zero (acc
, gsi
, false, loc
);
3085 unlink_stmt_vdef (*stmt
);
3086 gsi_remove (gsi
, true);
3087 release_defs (*stmt
);
3088 return SRA_AM_REMOVED
;
3092 init_subtree_with_zero (acc
, gsi
, true, loc
);
3093 return SRA_AM_MODIFIED
;
3097 /* Create and return a new suitable default definition SSA_NAME for RACC which
3098 is an access describing an uninitialized part of an aggregate that is being
3102 get_repl_default_def_ssa_name (struct access
*racc
)
3104 gcc_checking_assert (!racc
->grp_to_be_replaced
3105 && !racc
->grp_to_be_debug_replaced
);
3106 if (!racc
->replacement_decl
)
3107 racc
->replacement_decl
= create_access_replacement (racc
);
3108 return get_or_create_ssa_default_def (cfun
, racc
->replacement_decl
);
3111 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3112 bit-field field declaration somewhere in it. */
3115 contains_vce_or_bfcref_p (const_tree ref
)
3117 while (handled_component_p (ref
))
3119 if (TREE_CODE (ref
) == VIEW_CONVERT_EXPR
3120 || (TREE_CODE (ref
) == COMPONENT_REF
3121 && DECL_BIT_FIELD (TREE_OPERAND (ref
, 1))))
3123 ref
= TREE_OPERAND (ref
, 0);
3129 /* Examine both sides of the assignment statement pointed to by STMT, replace
3130 them with a scalare replacement if there is one and generate copying of
3131 replacements if scalarized aggregates have been used in the assignment. GSI
3132 is used to hold generated statements for type conversions and subtree
3135 static enum assignment_mod_result
3136 sra_modify_assign (gimple
*stmt
, gimple_stmt_iterator
*gsi
)
3138 struct access
*lacc
, *racc
;
3140 bool modify_this_stmt
= false;
3141 bool force_gimple_rhs
= false;
3143 gimple_stmt_iterator orig_gsi
= *gsi
;
3145 if (!gimple_assign_single_p (*stmt
))
3147 lhs
= gimple_assign_lhs (*stmt
);
3148 rhs
= gimple_assign_rhs1 (*stmt
);
3150 if (TREE_CODE (rhs
) == CONSTRUCTOR
)
3151 return sra_modify_constructor_assign (stmt
, gsi
);
3153 if (TREE_CODE (rhs
) == REALPART_EXPR
|| TREE_CODE (lhs
) == REALPART_EXPR
3154 || TREE_CODE (rhs
) == IMAGPART_EXPR
|| TREE_CODE (lhs
) == IMAGPART_EXPR
3155 || TREE_CODE (rhs
) == BIT_FIELD_REF
|| TREE_CODE (lhs
) == BIT_FIELD_REF
)
3157 modify_this_stmt
= sra_modify_expr (gimple_assign_rhs1_ptr (*stmt
),
3159 modify_this_stmt
|= sra_modify_expr (gimple_assign_lhs_ptr (*stmt
),
3161 return modify_this_stmt
? SRA_AM_MODIFIED
: SRA_AM_NONE
;
3164 lacc
= get_access_for_expr (lhs
);
3165 racc
= get_access_for_expr (rhs
);
3169 loc
= gimple_location (*stmt
);
3170 if (lacc
&& lacc
->grp_to_be_replaced
)
3172 lhs
= get_access_replacement (lacc
);
3173 gimple_assign_set_lhs (*stmt
, lhs
);
3174 modify_this_stmt
= true;
3175 if (lacc
->grp_partial_lhs
)
3176 force_gimple_rhs
= true;
3180 if (racc
&& racc
->grp_to_be_replaced
)
3182 rhs
= get_access_replacement (racc
);
3183 modify_this_stmt
= true;
3184 if (racc
->grp_partial_lhs
)
3185 force_gimple_rhs
= true;
3189 && !racc
->grp_unscalarized_data
3190 && TREE_CODE (lhs
) == SSA_NAME
3191 && !access_has_replacements_p (racc
))
3193 rhs
= get_repl_default_def_ssa_name (racc
);
3194 modify_this_stmt
= true;
3198 if (modify_this_stmt
)
3200 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
3202 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3203 ??? This should move to fold_stmt which we simply should
3204 call after building a VIEW_CONVERT_EXPR here. */
3205 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs
))
3206 && !contains_bitfld_component_ref_p (lhs
))
3208 lhs
= build_ref_for_model (loc
, lhs
, 0, racc
, gsi
, false);
3209 gimple_assign_set_lhs (*stmt
, lhs
);
3211 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs
))
3212 && !contains_vce_or_bfcref_p (rhs
))
3213 rhs
= build_ref_for_model (loc
, rhs
, 0, lacc
, gsi
, false);
3215 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
3217 rhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, TREE_TYPE (lhs
),
3219 if (is_gimple_reg_type (TREE_TYPE (lhs
))
3220 && TREE_CODE (lhs
) != SSA_NAME
)
3221 force_gimple_rhs
= true;
3226 if (lacc
&& lacc
->grp_to_be_debug_replaced
)
3228 tree dlhs
= get_access_replacement (lacc
);
3229 tree drhs
= unshare_expr (rhs
);
3230 if (!useless_type_conversion_p (TREE_TYPE (dlhs
), TREE_TYPE (drhs
)))
3232 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs
))
3233 && !contains_vce_or_bfcref_p (drhs
))
3234 drhs
= build_debug_ref_for_model (loc
, drhs
, 0, lacc
);
3236 && !useless_type_conversion_p (TREE_TYPE (dlhs
),
3238 drhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
,
3239 TREE_TYPE (dlhs
), drhs
);
3241 gimple ds
= gimple_build_debug_bind (dlhs
, drhs
, *stmt
);
3242 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
3245 /* From this point on, the function deals with assignments in between
3246 aggregates when at least one has scalar reductions of some of its
3247 components. There are three possible scenarios: Both the LHS and RHS have
3248 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3250 In the first case, we would like to load the LHS components from RHS
3251 components whenever possible. If that is not possible, we would like to
3252 read it directly from the RHS (after updating it by storing in it its own
3253 components). If there are some necessary unscalarized data in the LHS,
3254 those will be loaded by the original assignment too. If neither of these
3255 cases happen, the original statement can be removed. Most of this is done
3256 by load_assign_lhs_subreplacements.
3258 In the second case, we would like to store all RHS scalarized components
3259 directly into LHS and if they cover the aggregate completely, remove the
3260 statement too. In the third case, we want the LHS components to be loaded
3261 directly from the RHS (DSE will remove the original statement if it
3264 This is a bit complex but manageable when types match and when unions do
3265 not cause confusion in a way that we cannot really load a component of LHS
3266 from the RHS or vice versa (the access representing this level can have
3267 subaccesses that are accessible only through a different union field at a
3268 higher level - different from the one used in the examined expression).
3271 Therefore, I specially handle a fourth case, happening when there is a
3272 specific type cast or it is impossible to locate a scalarized subaccess on
3273 the other side of the expression. If that happens, I simply "refresh" the
3274 RHS by storing in it is scalarized components leave the original statement
3275 there to do the copying and then load the scalar replacements of the LHS.
3276 This is what the first branch does. */
3278 if (modify_this_stmt
3279 || gimple_has_volatile_ops (*stmt
)
3280 || contains_vce_or_bfcref_p (rhs
)
3281 || contains_vce_or_bfcref_p (lhs
)
3282 || stmt_ends_bb_p (*stmt
))
3284 if (access_has_children_p (racc
))
3285 generate_subtree_copies (racc
->first_child
, rhs
, racc
->offset
, 0, 0,
3286 gsi
, false, false, loc
);
3287 if (access_has_children_p (lacc
))
3289 gimple_stmt_iterator alt_gsi
= gsi_none ();
3290 if (stmt_ends_bb_p (*stmt
))
3292 alt_gsi
= gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi
)));
3295 generate_subtree_copies (lacc
->first_child
, lhs
, lacc
->offset
, 0, 0,
3296 gsi
, true, true, loc
);
3298 sra_stats
.separate_lhs_rhs_handling
++;
3300 /* This gimplification must be done after generate_subtree_copies,
3301 lest we insert the subtree copies in the middle of the gimplified
3303 if (force_gimple_rhs
)
3304 rhs
= force_gimple_operand_gsi (&orig_gsi
, rhs
, true, NULL_TREE
,
3305 true, GSI_SAME_STMT
);
3306 if (gimple_assign_rhs1 (*stmt
) != rhs
)
3308 modify_this_stmt
= true;
3309 gimple_assign_set_rhs_from_tree (&orig_gsi
, rhs
);
3310 gcc_assert (*stmt
== gsi_stmt (orig_gsi
));
3313 return modify_this_stmt
? SRA_AM_MODIFIED
: SRA_AM_NONE
;
3317 if (access_has_children_p (lacc
)
3318 && access_has_children_p (racc
)
3319 /* When an access represents an unscalarizable region, it usually
3320 represents accesses with variable offset and thus must not be used
3321 to generate new memory accesses. */
3322 && !lacc
->grp_unscalarizable_region
3323 && !racc
->grp_unscalarizable_region
)
3325 struct subreplacement_assignment_data sad
;
3327 sad
.left_offset
= lacc
->offset
;
3328 sad
.assignment_lhs
= lhs
;
3329 sad
.assignment_rhs
= rhs
;
3330 sad
.top_racc
= racc
;
3333 sad
.loc
= gimple_location (*stmt
);
3334 sad
.refreshed
= SRA_UDH_NONE
;
3336 if (lacc
->grp_read
&& !lacc
->grp_covered
)
3337 handle_unscalarized_data_in_subtree (&sad
);
3339 load_assign_lhs_subreplacements (lacc
, &sad
);
3340 if (sad
.refreshed
!= SRA_UDH_RIGHT
)
3343 unlink_stmt_vdef (*stmt
);
3344 gsi_remove (&sad
.old_gsi
, true);
3345 release_defs (*stmt
);
3346 sra_stats
.deleted
++;
3347 return SRA_AM_REMOVED
;
3352 if (access_has_children_p (racc
)
3353 && !racc
->grp_unscalarized_data
)
3357 fprintf (dump_file
, "Removing load: ");
3358 print_gimple_stmt (dump_file
, *stmt
, 0, 0);
3360 generate_subtree_copies (racc
->first_child
, lhs
,
3361 racc
->offset
, 0, 0, gsi
,
3363 gcc_assert (*stmt
== gsi_stmt (*gsi
));
3364 unlink_stmt_vdef (*stmt
);
3365 gsi_remove (gsi
, true);
3366 release_defs (*stmt
);
3367 sra_stats
.deleted
++;
3368 return SRA_AM_REMOVED
;
3370 /* Restore the aggregate RHS from its components so the
3371 prevailing aggregate copy does the right thing. */
3372 if (access_has_children_p (racc
))
3373 generate_subtree_copies (racc
->first_child
, rhs
, racc
->offset
, 0, 0,
3374 gsi
, false, false, loc
);
3375 /* Re-load the components of the aggregate copy destination.
3376 But use the RHS aggregate to load from to expose more
3377 optimization opportunities. */
3378 if (access_has_children_p (lacc
))
3379 generate_subtree_copies (lacc
->first_child
, rhs
, lacc
->offset
,
3380 0, 0, gsi
, true, true, loc
);
3387 /* Traverse the function body and all modifications as decided in
3388 analyze_all_variable_accesses. Return true iff the CFG has been
3392 sra_modify_function_body (void)
3394 bool cfg_changed
= false;
3397 FOR_EACH_BB_FN (bb
, cfun
)
3399 gimple_stmt_iterator gsi
= gsi_start_bb (bb
);
3400 while (!gsi_end_p (gsi
))
3402 gimple stmt
= gsi_stmt (gsi
);
3403 enum assignment_mod_result assign_result
;
3404 bool modified
= false, deleted
= false;
3408 switch (gimple_code (stmt
))
3411 t
= gimple_return_retval_ptr (stmt
);
3412 if (*t
!= NULL_TREE
)
3413 modified
|= sra_modify_expr (t
, &gsi
, false);
3417 assign_result
= sra_modify_assign (&stmt
, &gsi
);
3418 modified
|= assign_result
== SRA_AM_MODIFIED
;
3419 deleted
= assign_result
== SRA_AM_REMOVED
;
3423 /* Operands must be processed before the lhs. */
3424 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
3426 t
= gimple_call_arg_ptr (stmt
, i
);
3427 modified
|= sra_modify_expr (t
, &gsi
, false);
3430 if (gimple_call_lhs (stmt
))
3432 t
= gimple_call_lhs_ptr (stmt
);
3433 modified
|= sra_modify_expr (t
, &gsi
, true);
3438 for (i
= 0; i
< gimple_asm_ninputs (stmt
); i
++)
3440 t
= &TREE_VALUE (gimple_asm_input_op (stmt
, i
));
3441 modified
|= sra_modify_expr (t
, &gsi
, false);
3443 for (i
= 0; i
< gimple_asm_noutputs (stmt
); i
++)
3445 t
= &TREE_VALUE (gimple_asm_output_op (stmt
, i
));
3446 modified
|= sra_modify_expr (t
, &gsi
, true);
3457 if (maybe_clean_eh_stmt (stmt
)
3458 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
3466 gsi_commit_edge_inserts ();
3470 /* Generate statements initializing scalar replacements of parts of function
3474 initialize_parameter_reductions (void)
3476 gimple_stmt_iterator gsi
;
3477 gimple_seq seq
= NULL
;
3480 gsi
= gsi_start (seq
);
3481 for (parm
= DECL_ARGUMENTS (current_function_decl
);
3483 parm
= DECL_CHAIN (parm
))
3485 vec
<access_p
> *access_vec
;
3486 struct access
*access
;
3488 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
3490 access_vec
= get_base_access_vector (parm
);
3494 for (access
= (*access_vec
)[0];
3496 access
= access
->next_grp
)
3497 generate_subtree_copies (access
, parm
, 0, 0, 0, &gsi
, true, true,
3498 EXPR_LOCATION (parm
));
3501 seq
= gsi_seq (gsi
);
3503 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun
)), seq
);
3506 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3507 it reveals there are components of some aggregates to be scalarized, it runs
3508 the required transformations. */
3510 perform_intra_sra (void)
3515 if (!find_var_candidates ())
3518 if (!scan_function ())
3521 if (!analyze_all_variable_accesses ())
3524 if (sra_modify_function_body ())
3525 ret
= TODO_update_ssa
| TODO_cleanup_cfg
;
3527 ret
= TODO_update_ssa
;
3528 initialize_parameter_reductions ();
3530 statistics_counter_event (cfun
, "Scalar replacements created",
3531 sra_stats
.replacements
);
3532 statistics_counter_event (cfun
, "Modified expressions", sra_stats
.exprs
);
3533 statistics_counter_event (cfun
, "Subtree copy stmts",
3534 sra_stats
.subtree_copies
);
3535 statistics_counter_event (cfun
, "Subreplacement stmts",
3536 sra_stats
.subreplacements
);
3537 statistics_counter_event (cfun
, "Deleted stmts", sra_stats
.deleted
);
3538 statistics_counter_event (cfun
, "Separate LHS and RHS handling",
3539 sra_stats
.separate_lhs_rhs_handling
);
3542 sra_deinitialize ();
3546 /* Perform early intraprocedural SRA. */
3548 early_intra_sra (void)
3550 sra_mode
= SRA_MODE_EARLY_INTRA
;
3551 return perform_intra_sra ();
3554 /* Perform "late" intraprocedural SRA. */
3556 late_intra_sra (void)
3558 sra_mode
= SRA_MODE_INTRA
;
3559 return perform_intra_sra ();
3564 gate_intra_sra (void)
3566 return flag_tree_sra
!= 0 && dbg_cnt (tree_sra
);
3572 const pass_data pass_data_sra_early
=
3574 GIMPLE_PASS
, /* type */
3576 OPTGROUP_NONE
, /* optinfo_flags */
3577 TV_TREE_SRA
, /* tv_id */
3578 ( PROP_cfg
| PROP_ssa
), /* properties_required */
3579 0, /* properties_provided */
3580 0, /* properties_destroyed */
3581 0, /* todo_flags_start */
3582 TODO_update_ssa
, /* todo_flags_finish */
3585 class pass_sra_early
: public gimple_opt_pass
3588 pass_sra_early (gcc::context
*ctxt
)
3589 : gimple_opt_pass (pass_data_sra_early
, ctxt
)
3592 /* opt_pass methods: */
3593 virtual bool gate (function
*) { return gate_intra_sra (); }
3594 virtual unsigned int execute (function
*) { return early_intra_sra (); }
3596 }; // class pass_sra_early
3601 make_pass_sra_early (gcc::context
*ctxt
)
3603 return new pass_sra_early (ctxt
);
3608 const pass_data pass_data_sra
=
3610 GIMPLE_PASS
, /* type */
3612 OPTGROUP_NONE
, /* optinfo_flags */
3613 TV_TREE_SRA
, /* tv_id */
3614 ( PROP_cfg
| PROP_ssa
), /* properties_required */
3615 0, /* properties_provided */
3616 0, /* properties_destroyed */
3617 TODO_update_address_taken
, /* todo_flags_start */
3618 TODO_update_ssa
, /* todo_flags_finish */
3621 class pass_sra
: public gimple_opt_pass
3624 pass_sra (gcc::context
*ctxt
)
3625 : gimple_opt_pass (pass_data_sra
, ctxt
)
3628 /* opt_pass methods: */
3629 virtual bool gate (function
*) { return gate_intra_sra (); }
3630 virtual unsigned int execute (function
*) { return late_intra_sra (); }
3632 }; // class pass_sra
3637 make_pass_sra (gcc::context
*ctxt
)
3639 return new pass_sra (ctxt
);
3643 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3647 is_unused_scalar_param (tree parm
)
3650 return (is_gimple_reg (parm
)
3651 && (!(name
= ssa_default_def (cfun
, parm
))
3652 || has_zero_uses (name
)));
3655 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3656 examine whether there are any direct or otherwise infeasible ones. If so,
3657 return true, otherwise return false. PARM must be a gimple register with a
3658 non-NULL default definition. */
3661 ptr_parm_has_direct_uses (tree parm
)
3663 imm_use_iterator ui
;
3665 tree name
= ssa_default_def (cfun
, parm
);
3668 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
3671 use_operand_p use_p
;
3673 if (is_gimple_debug (stmt
))
3676 /* Valid uses include dereferences on the lhs and the rhs. */
3677 if (gimple_has_lhs (stmt
))
3679 tree lhs
= gimple_get_lhs (stmt
);
3680 while (handled_component_p (lhs
))
3681 lhs
= TREE_OPERAND (lhs
, 0);
3682 if (TREE_CODE (lhs
) == MEM_REF
3683 && TREE_OPERAND (lhs
, 0) == name
3684 && integer_zerop (TREE_OPERAND (lhs
, 1))
3685 && types_compatible_p (TREE_TYPE (lhs
),
3686 TREE_TYPE (TREE_TYPE (name
)))
3687 && !TREE_THIS_VOLATILE (lhs
))
3690 if (gimple_assign_single_p (stmt
))
3692 tree rhs
= gimple_assign_rhs1 (stmt
);
3693 while (handled_component_p (rhs
))
3694 rhs
= TREE_OPERAND (rhs
, 0);
3695 if (TREE_CODE (rhs
) == MEM_REF
3696 && TREE_OPERAND (rhs
, 0) == name
3697 && integer_zerop (TREE_OPERAND (rhs
, 1))
3698 && types_compatible_p (TREE_TYPE (rhs
),
3699 TREE_TYPE (TREE_TYPE (name
)))
3700 && !TREE_THIS_VOLATILE (rhs
))
3703 else if (is_gimple_call (stmt
))
3706 for (i
= 0; i
< gimple_call_num_args (stmt
); ++i
)
3708 tree arg
= gimple_call_arg (stmt
, i
);
3709 while (handled_component_p (arg
))
3710 arg
= TREE_OPERAND (arg
, 0);
3711 if (TREE_CODE (arg
) == MEM_REF
3712 && TREE_OPERAND (arg
, 0) == name
3713 && integer_zerop (TREE_OPERAND (arg
, 1))
3714 && types_compatible_p (TREE_TYPE (arg
),
3715 TREE_TYPE (TREE_TYPE (name
)))
3716 && !TREE_THIS_VOLATILE (arg
))
3721 /* If the number of valid uses does not match the number of
3722 uses in this stmt there is an unhandled use. */
3723 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
3730 BREAK_FROM_IMM_USE_STMT (ui
);
3736 /* Identify candidates for reduction for IPA-SRA based on their type and mark
3737 them in candidate_bitmap. Note that these do not necessarily include
3738 parameter which are unused and thus can be removed. Return true iff any
3739 such candidate has been found. */
3742 find_param_candidates (void)
3749 for (parm
= DECL_ARGUMENTS (current_function_decl
);
3751 parm
= DECL_CHAIN (parm
))
3753 tree type
= TREE_TYPE (parm
);
3758 if (TREE_THIS_VOLATILE (parm
)
3759 || TREE_ADDRESSABLE (parm
)
3760 || (!is_gimple_reg_type (type
) && is_va_list_type (type
)))
3763 if (is_unused_scalar_param (parm
))
3769 if (POINTER_TYPE_P (type
))
3771 type
= TREE_TYPE (type
);
3773 if (TREE_CODE (type
) == FUNCTION_TYPE
3774 || TYPE_VOLATILE (type
)
3775 || (TREE_CODE (type
) == ARRAY_TYPE
3776 && TYPE_NONALIASED_COMPONENT (type
))
3777 || !is_gimple_reg (parm
)
3778 || is_va_list_type (type
)
3779 || ptr_parm_has_direct_uses (parm
))
3782 else if (!AGGREGATE_TYPE_P (type
))
3785 if (!COMPLETE_TYPE_P (type
)
3786 || !tree_fits_uhwi_p (TYPE_SIZE (type
))
3787 || tree_to_uhwi (TYPE_SIZE (type
)) == 0
3788 || (AGGREGATE_TYPE_P (type
)
3789 && type_internals_preclude_sra_p (type
, &msg
)))
3792 bitmap_set_bit (candidate_bitmap
, DECL_UID (parm
));
3793 slot
= candidates
->find_slot_with_hash (parm
, DECL_UID (parm
), INSERT
);
3797 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3799 fprintf (dump_file
, "Candidate (%d): ", DECL_UID (parm
));
3800 print_generic_expr (dump_file
, parm
, 0);
3801 fprintf (dump_file
, "\n");
3805 func_param_count
= count
;
3809 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
3813 mark_maybe_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef ATTRIBUTE_UNUSED
,
3816 struct access
*repr
= (struct access
*) data
;
3818 repr
->grp_maybe_modified
= 1;
3822 /* Analyze what representatives (in linked lists accessible from
3823 REPRESENTATIVES) can be modified by side effects of statements in the
3824 current function. */
3827 analyze_modified_params (vec
<access_p
> representatives
)
3831 for (i
= 0; i
< func_param_count
; i
++)
3833 struct access
*repr
;
3835 for (repr
= representatives
[i
];
3837 repr
= repr
->next_grp
)
3839 struct access
*access
;
3843 if (no_accesses_p (repr
))
3845 if (!POINTER_TYPE_P (TREE_TYPE (repr
->base
))
3846 || repr
->grp_maybe_modified
)
3849 ao_ref_init (&ar
, repr
->expr
);
3850 visited
= BITMAP_ALLOC (NULL
);
3851 for (access
= repr
; access
; access
= access
->next_sibling
)
3853 /* All accesses are read ones, otherwise grp_maybe_modified would
3854 be trivially set. */
3855 walk_aliased_vdefs (&ar
, gimple_vuse (access
->stmt
),
3856 mark_maybe_modified
, repr
, &visited
);
3857 if (repr
->grp_maybe_modified
)
3860 BITMAP_FREE (visited
);
3865 /* Propagate distances in bb_dereferences in the opposite direction than the
3866 control flow edges, in each step storing the maximum of the current value
3867 and the minimum of all successors. These steps are repeated until the table
3868 stabilizes. Note that BBs which might terminate the functions (according to
3869 final_bbs bitmap) never updated in this way. */
3872 propagate_dereference_distances (void)
3876 auto_vec
<basic_block
> queue (last_basic_block_for_fn (cfun
));
3877 queue
.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
3878 FOR_EACH_BB_FN (bb
, cfun
)
3880 queue
.quick_push (bb
);
3884 while (!queue
.is_empty ())
3888 bool change
= false;
3894 if (bitmap_bit_p (final_bbs
, bb
->index
))
3897 for (i
= 0; i
< func_param_count
; i
++)
3899 int idx
= bb
->index
* func_param_count
+ i
;
3901 HOST_WIDE_INT inh
= 0;
3903 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
3905 int succ_idx
= e
->dest
->index
* func_param_count
+ i
;
3907 if (e
->src
== EXIT_BLOCK_PTR_FOR_FN (cfun
))
3913 inh
= bb_dereferences
[succ_idx
];
3915 else if (bb_dereferences
[succ_idx
] < inh
)
3916 inh
= bb_dereferences
[succ_idx
];
3919 if (!first
&& bb_dereferences
[idx
] < inh
)
3921 bb_dereferences
[idx
] = inh
;
3926 if (change
&& !bitmap_bit_p (final_bbs
, bb
->index
))
3927 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
3932 e
->src
->aux
= e
->src
;
3933 queue
.quick_push (e
->src
);
3938 /* Dump a dereferences TABLE with heading STR to file F. */
3941 dump_dereferences_table (FILE *f
, const char *str
, HOST_WIDE_INT
*table
)
3945 fprintf (dump_file
, str
);
3946 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR_FOR_FN (cfun
),
3947 EXIT_BLOCK_PTR_FOR_FN (cfun
), next_bb
)
3949 fprintf (f
, "%4i %i ", bb
->index
, bitmap_bit_p (final_bbs
, bb
->index
));
3950 if (bb
!= EXIT_BLOCK_PTR_FOR_FN (cfun
))
3953 for (i
= 0; i
< func_param_count
; i
++)
3955 int idx
= bb
->index
* func_param_count
+ i
;
3956 fprintf (f
, " %4" HOST_WIDE_INT_PRINT
"d", table
[idx
]);
3961 fprintf (dump_file
, "\n");
3964 /* Determine what (parts of) parameters passed by reference that are not
3965 assigned to are not certainly dereferenced in this function and thus the
3966 dereferencing cannot be safely moved to the caller without potentially
3967 introducing a segfault. Mark such REPRESENTATIVES as
3968 grp_not_necessarilly_dereferenced.
3970 The dereferenced maximum "distance," i.e. the offset + size of the accessed
3971 part is calculated rather than simple booleans are calculated for each
3972 pointer parameter to handle cases when only a fraction of the whole
3973 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
3976 The maximum dereference distances for each pointer parameter and BB are
3977 already stored in bb_dereference. This routine simply propagates these
3978 values upwards by propagate_dereference_distances and then compares the
3979 distances of individual parameters in the ENTRY BB to the equivalent
3980 distances of each representative of a (fraction of a) parameter. */
3983 analyze_caller_dereference_legality (vec
<access_p
> representatives
)
3987 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3988 dump_dereferences_table (dump_file
,
3989 "Dereference table before propagation:\n",
3992 propagate_dereference_distances ();
3994 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3995 dump_dereferences_table (dump_file
,
3996 "Dereference table after propagation:\n",
3999 for (i
= 0; i
< func_param_count
; i
++)
4001 struct access
*repr
= representatives
[i
];
4002 int idx
= ENTRY_BLOCK_PTR_FOR_FN (cfun
)->index
* func_param_count
+ i
;
4004 if (!repr
|| no_accesses_p (repr
))
4009 if ((repr
->offset
+ repr
->size
) > bb_dereferences
[idx
])
4010 repr
->grp_not_necessarilly_dereferenced
= 1;
4011 repr
= repr
->next_grp
;
4017 /* Return the representative access for the parameter declaration PARM if it is
4018 a scalar passed by reference which is not written to and the pointer value
4019 is not used directly. Thus, if it is legal to dereference it in the caller
4020 and we can rule out modifications through aliases, such parameter should be
4021 turned into one passed by value. Return NULL otherwise. */
4023 static struct access
*
4024 unmodified_by_ref_scalar_representative (tree parm
)
4026 int i
, access_count
;
4027 struct access
*repr
;
4028 vec
<access_p
> *access_vec
;
4030 access_vec
= get_base_access_vector (parm
);
4031 gcc_assert (access_vec
);
4032 repr
= (*access_vec
)[0];
4035 repr
->group_representative
= repr
;
4037 access_count
= access_vec
->length ();
4038 for (i
= 1; i
< access_count
; i
++)
4040 struct access
*access
= (*access_vec
)[i
];
4043 access
->group_representative
= repr
;
4044 access
->next_sibling
= repr
->next_sibling
;
4045 repr
->next_sibling
= access
;
4049 repr
->grp_scalar_ptr
= 1;
4053 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
4054 associated with. REQ_ALIGN is the minimum required alignment. */
4057 access_precludes_ipa_sra_p (struct access
*access
, unsigned int req_align
)
4059 unsigned int exp_align
;
4060 /* Avoid issues such as the second simple testcase in PR 42025. The problem
4061 is incompatible assign in a call statement (and possibly even in asm
4062 statements). This can be relaxed by using a new temporary but only for
4063 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
4064 intraprocedural SRA we deal with this by keeping the old aggregate around,
4065 something we cannot do in IPA-SRA.) */
4067 && (is_gimple_call (access
->stmt
)
4068 || gimple_code (access
->stmt
) == GIMPLE_ASM
))
4071 exp_align
= get_object_alignment (access
->expr
);
4072 if (exp_align
< req_align
)
4079 /* Sort collected accesses for parameter PARM, identify representatives for
4080 each accessed region and link them together. Return NULL if there are
4081 different but overlapping accesses, return the special ptr value meaning
4082 there are no accesses for this parameter if that is the case and return the
4083 first representative otherwise. Set *RO_GRP if there is a group of accesses
4084 with only read (i.e. no write) accesses. */
4086 static struct access
*
4087 splice_param_accesses (tree parm
, bool *ro_grp
)
4089 int i
, j
, access_count
, group_count
;
4090 int agg_size
, total_size
= 0;
4091 struct access
*access
, *res
, **prev_acc_ptr
= &res
;
4092 vec
<access_p
> *access_vec
;
4094 access_vec
= get_base_access_vector (parm
);
4096 return &no_accesses_representant
;
4097 access_count
= access_vec
->length ();
4099 access_vec
->qsort (compare_access_positions
);
4104 while (i
< access_count
)
4108 access
= (*access_vec
)[i
];
4109 modification
= access
->write
;
4110 if (access_precludes_ipa_sra_p (access
, TYPE_ALIGN (access
->type
)))
4112 a1_alias_type
= reference_alias_ptr_type (access
->expr
);
4114 /* Access is about to become group representative unless we find some
4115 nasty overlap which would preclude us from breaking this parameter
4119 while (j
< access_count
)
4121 struct access
*ac2
= (*access_vec
)[j
];
4122 if (ac2
->offset
!= access
->offset
)
4124 /* All or nothing law for parameters. */
4125 if (access
->offset
+ access
->size
> ac2
->offset
)
4130 else if (ac2
->size
!= access
->size
)
4133 if (access_precludes_ipa_sra_p (ac2
, TYPE_ALIGN (access
->type
))
4134 || (ac2
->type
!= access
->type
4135 && (TREE_ADDRESSABLE (ac2
->type
)
4136 || TREE_ADDRESSABLE (access
->type
)))
4137 || (reference_alias_ptr_type (ac2
->expr
) != a1_alias_type
))
4140 modification
|= ac2
->write
;
4141 ac2
->group_representative
= access
;
4142 ac2
->next_sibling
= access
->next_sibling
;
4143 access
->next_sibling
= ac2
;
4148 access
->grp_maybe_modified
= modification
;
4151 *prev_acc_ptr
= access
;
4152 prev_acc_ptr
= &access
->next_grp
;
4153 total_size
+= access
->size
;
4157 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4158 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm
))));
4160 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm
)));
4161 if (total_size
>= agg_size
)
4164 gcc_assert (group_count
> 0);
4168 /* Decide whether parameters with representative accesses given by REPR should
4169 be reduced into components. */
4172 decide_one_param_reduction (struct access
*repr
)
4174 int total_size
, cur_parm_size
, agg_size
, new_param_count
, parm_size_limit
;
4179 cur_parm_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm
)));
4180 gcc_assert (cur_parm_size
> 0);
4182 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4185 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm
))));
4190 agg_size
= cur_parm_size
;
4196 fprintf (dump_file
, "Evaluating PARAM group sizes for ");
4197 print_generic_expr (dump_file
, parm
, 0);
4198 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (parm
));
4199 for (acc
= repr
; acc
; acc
= acc
->next_grp
)
4200 dump_access (dump_file
, acc
, true);
4204 new_param_count
= 0;
4206 for (; repr
; repr
= repr
->next_grp
)
4208 gcc_assert (parm
== repr
->base
);
4210 /* Taking the address of a non-addressable field is verboten. */
4211 if (by_ref
&& repr
->non_addressable
)
4214 /* Do not decompose a non-BLKmode param in a way that would
4215 create BLKmode params. Especially for by-reference passing
4216 (thus, pointer-type param) this is hardly worthwhile. */
4217 if (DECL_MODE (parm
) != BLKmode
4218 && TYPE_MODE (repr
->type
) == BLKmode
)
4221 if (!by_ref
|| (!repr
->grp_maybe_modified
4222 && !repr
->grp_not_necessarilly_dereferenced
))
4223 total_size
+= repr
->size
;
4225 total_size
+= cur_parm_size
;
4230 gcc_assert (new_param_count
> 0);
4232 if (optimize_function_for_size_p (cfun
))
4233 parm_size_limit
= cur_parm_size
;
4235 parm_size_limit
= (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR
)
4238 if (total_size
< agg_size
4239 && total_size
<= parm_size_limit
)
4242 fprintf (dump_file
, " ....will be split into %i components\n",
4244 return new_param_count
;
4250 /* The order of the following enums is important, we need to do extra work for
4251 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4252 enum ipa_splicing_result
{ NO_GOOD_ACCESS
, UNUSED_PARAMS
, BY_VAL_ACCESSES
,
4253 MODIF_BY_REF_ACCESSES
, UNMODIF_BY_REF_ACCESSES
};
4255 /* Identify representatives of all accesses to all candidate parameters for
4256 IPA-SRA. Return result based on what representatives have been found. */
4258 static enum ipa_splicing_result
4259 splice_all_param_accesses (vec
<access_p
> &representatives
)
4261 enum ipa_splicing_result result
= NO_GOOD_ACCESS
;
4263 struct access
*repr
;
4265 representatives
.create (func_param_count
);
4267 for (parm
= DECL_ARGUMENTS (current_function_decl
);
4269 parm
= DECL_CHAIN (parm
))
4271 if (is_unused_scalar_param (parm
))
4273 representatives
.quick_push (&no_accesses_representant
);
4274 if (result
== NO_GOOD_ACCESS
)
4275 result
= UNUSED_PARAMS
;
4277 else if (POINTER_TYPE_P (TREE_TYPE (parm
))
4278 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm
)))
4279 && bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
4281 repr
= unmodified_by_ref_scalar_representative (parm
);
4282 representatives
.quick_push (repr
);
4284 result
= UNMODIF_BY_REF_ACCESSES
;
4286 else if (bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
4288 bool ro_grp
= false;
4289 repr
= splice_param_accesses (parm
, &ro_grp
);
4290 representatives
.quick_push (repr
);
4292 if (repr
&& !no_accesses_p (repr
))
4294 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4297 result
= UNMODIF_BY_REF_ACCESSES
;
4298 else if (result
< MODIF_BY_REF_ACCESSES
)
4299 result
= MODIF_BY_REF_ACCESSES
;
4301 else if (result
< BY_VAL_ACCESSES
)
4302 result
= BY_VAL_ACCESSES
;
4304 else if (no_accesses_p (repr
) && (result
== NO_GOOD_ACCESS
))
4305 result
= UNUSED_PARAMS
;
4308 representatives
.quick_push (NULL
);
4311 if (result
== NO_GOOD_ACCESS
)
4313 representatives
.release ();
4314 return NO_GOOD_ACCESS
;
4320 /* Return the index of BASE in PARMS. Abort if it is not found. */
4323 get_param_index (tree base
, vec
<tree
> parms
)
4327 len
= parms
.length ();
4328 for (i
= 0; i
< len
; i
++)
4329 if (parms
[i
] == base
)
4334 /* Convert the decisions made at the representative level into compact
4335 parameter adjustments. REPRESENTATIVES are pointers to first
4336 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4337 final number of adjustments. */
4339 static ipa_parm_adjustment_vec
4340 turn_representatives_into_adjustments (vec
<access_p
> representatives
,
4341 int adjustments_count
)
4344 ipa_parm_adjustment_vec adjustments
;
4348 gcc_assert (adjustments_count
> 0);
4349 parms
= ipa_get_vector_of_formal_parms (current_function_decl
);
4350 adjustments
.create (adjustments_count
);
4351 parm
= DECL_ARGUMENTS (current_function_decl
);
4352 for (i
= 0; i
< func_param_count
; i
++, parm
= DECL_CHAIN (parm
))
4354 struct access
*repr
= representatives
[i
];
4356 if (!repr
|| no_accesses_p (repr
))
4358 struct ipa_parm_adjustment adj
;
4360 memset (&adj
, 0, sizeof (adj
));
4361 adj
.base_index
= get_param_index (parm
, parms
);
4364 adj
.op
= IPA_PARM_OP_COPY
;
4366 adj
.op
= IPA_PARM_OP_REMOVE
;
4367 adj
.arg_prefix
= "ISRA";
4368 adjustments
.quick_push (adj
);
4372 struct ipa_parm_adjustment adj
;
4373 int index
= get_param_index (parm
, parms
);
4375 for (; repr
; repr
= repr
->next_grp
)
4377 memset (&adj
, 0, sizeof (adj
));
4378 gcc_assert (repr
->base
== parm
);
4379 adj
.base_index
= index
;
4380 adj
.base
= repr
->base
;
4381 adj
.type
= repr
->type
;
4382 adj
.alias_ptr_type
= reference_alias_ptr_type (repr
->expr
);
4383 adj
.offset
= repr
->offset
;
4384 adj
.by_ref
= (POINTER_TYPE_P (TREE_TYPE (repr
->base
))
4385 && (repr
->grp_maybe_modified
4386 || repr
->grp_not_necessarilly_dereferenced
));
4387 adj
.arg_prefix
= "ISRA";
4388 adjustments
.quick_push (adj
);
4396 /* Analyze the collected accesses and produce a plan what to do with the
4397 parameters in the form of adjustments, NULL meaning nothing. */
4399 static ipa_parm_adjustment_vec
4400 analyze_all_param_acesses (void)
4402 enum ipa_splicing_result repr_state
;
4403 bool proceed
= false;
4404 int i
, adjustments_count
= 0;
4405 vec
<access_p
> representatives
;
4406 ipa_parm_adjustment_vec adjustments
;
4408 repr_state
= splice_all_param_accesses (representatives
);
4409 if (repr_state
== NO_GOOD_ACCESS
)
4410 return ipa_parm_adjustment_vec ();
4412 /* If there are any parameters passed by reference which are not modified
4413 directly, we need to check whether they can be modified indirectly. */
4414 if (repr_state
== UNMODIF_BY_REF_ACCESSES
)
4416 analyze_caller_dereference_legality (representatives
);
4417 analyze_modified_params (representatives
);
4420 for (i
= 0; i
< func_param_count
; i
++)
4422 struct access
*repr
= representatives
[i
];
4424 if (repr
&& !no_accesses_p (repr
))
4426 if (repr
->grp_scalar_ptr
)
4428 adjustments_count
++;
4429 if (repr
->grp_not_necessarilly_dereferenced
4430 || repr
->grp_maybe_modified
)
4431 representatives
[i
] = NULL
;
4435 sra_stats
.scalar_by_ref_to_by_val
++;
4440 int new_components
= decide_one_param_reduction (repr
);
4442 if (new_components
== 0)
4444 representatives
[i
] = NULL
;
4445 adjustments_count
++;
4449 adjustments_count
+= new_components
;
4450 sra_stats
.aggregate_params_reduced
++;
4451 sra_stats
.param_reductions_created
+= new_components
;
4458 if (no_accesses_p (repr
))
4461 sra_stats
.deleted_unused_parameters
++;
4463 adjustments_count
++;
4467 if (!proceed
&& dump_file
)
4468 fprintf (dump_file
, "NOT proceeding to change params.\n");
4471 adjustments
= turn_representatives_into_adjustments (representatives
,
4474 adjustments
= ipa_parm_adjustment_vec ();
4476 representatives
.release ();
4480 /* If a parameter replacement identified by ADJ does not yet exist in the form
4481 of declaration, create it and record it, otherwise return the previously
4485 get_replaced_param_substitute (struct ipa_parm_adjustment
*adj
)
4488 if (!adj
->new_ssa_base
)
4490 char *pretty_name
= make_fancy_name (adj
->base
);
4492 repl
= create_tmp_reg (TREE_TYPE (adj
->base
), "ISR");
4493 DECL_NAME (repl
) = get_identifier (pretty_name
);
4494 obstack_free (&name_obstack
, pretty_name
);
4496 adj
->new_ssa_base
= repl
;
4499 repl
= adj
->new_ssa_base
;
4503 /* Find the first adjustment for a particular parameter BASE in a vector of
4504 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4507 static struct ipa_parm_adjustment
*
4508 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments
, tree base
)
4512 len
= adjustments
.length ();
4513 for (i
= 0; i
< len
; i
++)
4515 struct ipa_parm_adjustment
*adj
;
4517 adj
= &adjustments
[i
];
4518 if (adj
->op
!= IPA_PARM_OP_COPY
&& adj
->base
== base
)
4525 /* If the statement STMT defines an SSA_NAME of a parameter which is to be
4526 removed because its value is not used, replace the SSA_NAME with a one
4527 relating to a created VAR_DECL together all of its uses and return true.
4528 ADJUSTMENTS is a pointer to an adjustments vector. */
4531 replace_removed_params_ssa_names (gimple stmt
,
4532 ipa_parm_adjustment_vec adjustments
)
4534 struct ipa_parm_adjustment
*adj
;
4535 tree lhs
, decl
, repl
, name
;
4537 if (gimple_code (stmt
) == GIMPLE_PHI
)
4538 lhs
= gimple_phi_result (stmt
);
4539 else if (is_gimple_assign (stmt
))
4540 lhs
= gimple_assign_lhs (stmt
);
4541 else if (is_gimple_call (stmt
))
4542 lhs
= gimple_call_lhs (stmt
);
4546 if (TREE_CODE (lhs
) != SSA_NAME
)
4549 decl
= SSA_NAME_VAR (lhs
);
4550 if (decl
== NULL_TREE
4551 || TREE_CODE (decl
) != PARM_DECL
)
4554 adj
= get_adjustment_for_base (adjustments
, decl
);
4558 repl
= get_replaced_param_substitute (adj
);
4559 name
= make_ssa_name (repl
, stmt
);
4563 fprintf (dump_file
, "replacing an SSA name of a removed param ");
4564 print_generic_expr (dump_file
, lhs
, 0);
4565 fprintf (dump_file
, " with ");
4566 print_generic_expr (dump_file
, name
, 0);
4567 fprintf (dump_file
, "\n");
4570 if (is_gimple_assign (stmt
))
4571 gimple_assign_set_lhs (stmt
, name
);
4572 else if (is_gimple_call (stmt
))
4573 gimple_call_set_lhs (stmt
, name
);
4575 gimple_phi_set_result (stmt
, name
);
4577 replace_uses_by (lhs
, name
);
4578 release_ssa_name (lhs
);
4582 /* If the statement pointed to by STMT_PTR contains any expressions that need
4583 to replaced with a different one as noted by ADJUSTMENTS, do so. Handle any
4584 potential type incompatibilities (GSI is used to accommodate conversion
4585 statements and must point to the statement). Return true iff the statement
4589 sra_ipa_modify_assign (gimple
*stmt_ptr
, gimple_stmt_iterator
*gsi
,
4590 ipa_parm_adjustment_vec adjustments
)
4592 gimple stmt
= *stmt_ptr
;
4593 tree
*lhs_p
, *rhs_p
;
4596 if (!gimple_assign_single_p (stmt
))
4599 rhs_p
= gimple_assign_rhs1_ptr (stmt
);
4600 lhs_p
= gimple_assign_lhs_ptr (stmt
);
4602 any
= ipa_modify_expr (rhs_p
, false, adjustments
);
4603 any
|= ipa_modify_expr (lhs_p
, false, adjustments
);
4606 tree new_rhs
= NULL_TREE
;
4608 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p
), TREE_TYPE (*rhs_p
)))
4610 if (TREE_CODE (*rhs_p
) == CONSTRUCTOR
)
4612 /* V_C_Es of constructors can cause trouble (PR 42714). */
4613 if (is_gimple_reg_type (TREE_TYPE (*lhs_p
)))
4614 *rhs_p
= build_zero_cst (TREE_TYPE (*lhs_p
));
4616 *rhs_p
= build_constructor (TREE_TYPE (*lhs_p
),
4620 new_rhs
= fold_build1_loc (gimple_location (stmt
),
4621 VIEW_CONVERT_EXPR
, TREE_TYPE (*lhs_p
),
4624 else if (REFERENCE_CLASS_P (*rhs_p
)
4625 && is_gimple_reg_type (TREE_TYPE (*lhs_p
))
4626 && !is_gimple_reg (*lhs_p
))
4627 /* This can happen when an assignment in between two single field
4628 structures is turned into an assignment in between two pointers to
4629 scalars (PR 42237). */
4634 tree tmp
= force_gimple_operand_gsi (gsi
, new_rhs
, true, NULL_TREE
,
4635 true, GSI_SAME_STMT
);
4637 gimple_assign_set_rhs_from_tree (gsi
, tmp
);
4646 /* Traverse the function body and all modifications as described in
4647 ADJUSTMENTS. Return true iff the CFG has been changed. */
4650 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments
)
4652 bool cfg_changed
= false;
4655 FOR_EACH_BB_FN (bb
, cfun
)
4657 gimple_stmt_iterator gsi
;
4659 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4660 replace_removed_params_ssa_names (gsi_stmt (gsi
), adjustments
);
4662 gsi
= gsi_start_bb (bb
);
4663 while (!gsi_end_p (gsi
))
4665 gimple stmt
= gsi_stmt (gsi
);
4666 bool modified
= false;
4670 switch (gimple_code (stmt
))
4673 t
= gimple_return_retval_ptr (stmt
);
4674 if (*t
!= NULL_TREE
)
4675 modified
|= ipa_modify_expr (t
, true, adjustments
);
4679 modified
|= sra_ipa_modify_assign (&stmt
, &gsi
, adjustments
);
4680 modified
|= replace_removed_params_ssa_names (stmt
, adjustments
);
4684 /* Operands must be processed before the lhs. */
4685 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
4687 t
= gimple_call_arg_ptr (stmt
, i
);
4688 modified
|= ipa_modify_expr (t
, true, adjustments
);
4691 if (gimple_call_lhs (stmt
))
4693 t
= gimple_call_lhs_ptr (stmt
);
4694 modified
|= ipa_modify_expr (t
, false, adjustments
);
4695 modified
|= replace_removed_params_ssa_names (stmt
,
4701 for (i
= 0; i
< gimple_asm_ninputs (stmt
); i
++)
4703 t
= &TREE_VALUE (gimple_asm_input_op (stmt
, i
));
4704 modified
|= ipa_modify_expr (t
, true, adjustments
);
4706 for (i
= 0; i
< gimple_asm_noutputs (stmt
); i
++)
4708 t
= &TREE_VALUE (gimple_asm_output_op (stmt
, i
));
4709 modified
|= ipa_modify_expr (t
, false, adjustments
);
4720 if (maybe_clean_eh_stmt (stmt
)
4721 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
4731 /* Call gimple_debug_bind_reset_value on all debug statements describing
4732 gimple register parameters that are being removed or replaced. */
4735 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments
)
4738 gimple_stmt_iterator
*gsip
= NULL
, gsi
;
4740 if (MAY_HAVE_DEBUG_STMTS
&& single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun
)))
4742 gsi
= gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun
)));
4745 len
= adjustments
.length ();
4746 for (i
= 0; i
< len
; i
++)
4748 struct ipa_parm_adjustment
*adj
;
4749 imm_use_iterator ui
;
4750 gimple stmt
, def_temp
;
4751 tree name
, vexpr
, copy
= NULL_TREE
;
4752 use_operand_p use_p
;
4754 adj
= &adjustments
[i
];
4755 if (adj
->op
== IPA_PARM_OP_COPY
|| !is_gimple_reg (adj
->base
))
4757 name
= ssa_default_def (cfun
, adj
->base
);
4760 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
4762 if (gimple_clobber_p (stmt
))
4764 gimple_stmt_iterator cgsi
= gsi_for_stmt (stmt
);
4765 unlink_stmt_vdef (stmt
);
4766 gsi_remove (&cgsi
, true);
4767 release_defs (stmt
);
4770 /* All other users must have been removed by
4771 ipa_sra_modify_function_body. */
4772 gcc_assert (is_gimple_debug (stmt
));
4773 if (vexpr
== NULL
&& gsip
!= NULL
)
4775 gcc_assert (TREE_CODE (adj
->base
) == PARM_DECL
);
4776 vexpr
= make_node (DEBUG_EXPR_DECL
);
4777 def_temp
= gimple_build_debug_source_bind (vexpr
, adj
->base
,
4779 DECL_ARTIFICIAL (vexpr
) = 1;
4780 TREE_TYPE (vexpr
) = TREE_TYPE (name
);
4781 DECL_MODE (vexpr
) = DECL_MODE (adj
->base
);
4782 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
4786 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
4787 SET_USE (use_p
, vexpr
);
4790 gimple_debug_bind_reset_value (stmt
);
4793 /* Create a VAR_DECL for debug info purposes. */
4794 if (!DECL_IGNORED_P (adj
->base
))
4796 copy
= build_decl (DECL_SOURCE_LOCATION (current_function_decl
),
4797 VAR_DECL
, DECL_NAME (adj
->base
),
4798 TREE_TYPE (adj
->base
));
4799 if (DECL_PT_UID_SET_P (adj
->base
))
4800 SET_DECL_PT_UID (copy
, DECL_PT_UID (adj
->base
));
4801 TREE_ADDRESSABLE (copy
) = TREE_ADDRESSABLE (adj
->base
);
4802 TREE_READONLY (copy
) = TREE_READONLY (adj
->base
);
4803 TREE_THIS_VOLATILE (copy
) = TREE_THIS_VOLATILE (adj
->base
);
4804 DECL_GIMPLE_REG_P (copy
) = DECL_GIMPLE_REG_P (adj
->base
);
4805 DECL_ARTIFICIAL (copy
) = DECL_ARTIFICIAL (adj
->base
);
4806 DECL_IGNORED_P (copy
) = DECL_IGNORED_P (adj
->base
);
4807 DECL_ABSTRACT_ORIGIN (copy
) = DECL_ORIGIN (adj
->base
);
4808 DECL_SEEN_IN_BIND_EXPR_P (copy
) = 1;
4809 SET_DECL_RTL (copy
, 0);
4810 TREE_USED (copy
) = 1;
4811 DECL_CONTEXT (copy
) = current_function_decl
;
4812 add_local_decl (cfun
, copy
);
4814 BLOCK_VARS (DECL_INITIAL (current_function_decl
));
4815 BLOCK_VARS (DECL_INITIAL (current_function_decl
)) = copy
;
4817 if (gsip
!= NULL
&& copy
&& target_for_debug_bind (adj
->base
))
4819 gcc_assert (TREE_CODE (adj
->base
) == PARM_DECL
);
4821 def_temp
= gimple_build_debug_bind (copy
, vexpr
, NULL
);
4823 def_temp
= gimple_build_debug_source_bind (copy
, adj
->base
,
4825 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
4830 /* Return false if all callers have at least as many actual arguments as there
4831 are formal parameters in the current function and that their types
4835 some_callers_have_mismatched_arguments_p (struct cgraph_node
*node
,
4836 void *data ATTRIBUTE_UNUSED
)
4838 struct cgraph_edge
*cs
;
4839 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4840 if (!callsite_arguments_match_p (cs
->call_stmt
))
4846 /* Convert all callers of NODE. */
4849 convert_callers_for_node (struct cgraph_node
*node
,
4852 ipa_parm_adjustment_vec
*adjustments
= (ipa_parm_adjustment_vec
*) data
;
4853 bitmap recomputed_callers
= BITMAP_ALLOC (NULL
);
4854 struct cgraph_edge
*cs
;
4856 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4858 push_cfun (DECL_STRUCT_FUNCTION (cs
->caller
->decl
));
4861 fprintf (dump_file
, "Adjusting call %s/%i -> %s/%i\n",
4862 xstrdup (cs
->caller
->name ()),
4864 xstrdup (cs
->callee
->name ()),
4867 ipa_modify_call_arguments (cs
, cs
->call_stmt
, *adjustments
);
4872 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4873 if (bitmap_set_bit (recomputed_callers
, cs
->caller
->uid
)
4874 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs
->caller
->decl
)))
4875 compute_inline_parameters (cs
->caller
, true);
4876 BITMAP_FREE (recomputed_callers
);
4881 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
4884 convert_callers (struct cgraph_node
*node
, tree old_decl
,
4885 ipa_parm_adjustment_vec adjustments
)
4887 basic_block this_block
;
4889 node
->call_for_symbol_thunks_and_aliases (convert_callers_for_node
,
4890 &adjustments
, false);
4892 if (!encountered_recursive_call
)
4895 FOR_EACH_BB_FN (this_block
, cfun
)
4897 gimple_stmt_iterator gsi
;
4899 for (gsi
= gsi_start_bb (this_block
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4901 gimple stmt
= gsi_stmt (gsi
);
4903 if (gimple_code (stmt
) != GIMPLE_CALL
)
4905 call_fndecl
= gimple_call_fndecl (stmt
);
4906 if (call_fndecl
== old_decl
)
4909 fprintf (dump_file
, "Adjusting recursive call");
4910 gimple_call_set_fndecl (stmt
, node
->decl
);
4911 ipa_modify_call_arguments (NULL
, stmt
, adjustments
);
4919 /* Perform all the modification required in IPA-SRA for NODE to have parameters
4920 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
4923 modify_function (struct cgraph_node
*node
, ipa_parm_adjustment_vec adjustments
)
4925 struct cgraph_node
*new_node
;
4928 rebuild_cgraph_edges ();
4929 free_dominance_info (CDI_DOMINATORS
);
4932 /* This must be done after rebuilding cgraph edges for node above.
4933 Otherwise any recursive calls to node that are recorded in
4934 redirect_callers will be corrupted. */
4935 vec
<cgraph_edge
*> redirect_callers
= node
->collect_callers ();
4936 new_node
= node
->create_version_clone_with_body (redirect_callers
, NULL
,
4937 NULL
, false, NULL
, NULL
,
4939 redirect_callers
.release ();
4941 push_cfun (DECL_STRUCT_FUNCTION (new_node
->decl
));
4942 ipa_modify_formal_parameters (current_function_decl
, adjustments
);
4943 cfg_changed
= ipa_sra_modify_function_body (adjustments
);
4944 sra_ipa_reset_debug_stmts (adjustments
);
4945 convert_callers (new_node
, node
->decl
, adjustments
);
4946 new_node
->make_local ();
4950 /* If NODE has a caller, return true. */
4953 has_caller_p (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
4960 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
4961 attributes, return true otherwise. NODE is the cgraph node of the current
4965 ipa_sra_preliminary_function_checks (struct cgraph_node
*node
)
4967 if (!node
->can_be_local_p ())
4970 fprintf (dump_file
, "Function not local to this compilation unit.\n");
4974 if (!node
->local
.can_change_signature
)
4977 fprintf (dump_file
, "Function can not change signature.\n");
4981 if (!tree_versionable_function_p (node
->decl
))
4984 fprintf (dump_file
, "Function is not versionable.\n");
4988 if (!opt_for_fn (node
->decl
, optimize
)
4989 || !opt_for_fn (node
->decl
, flag_ipa_sra
))
4992 fprintf (dump_file
, "Function not optimized.\n");
4996 if (DECL_VIRTUAL_P (current_function_decl
))
4999 fprintf (dump_file
, "Function is a virtual method.\n");
5003 if ((DECL_COMDAT (node
->decl
) || DECL_EXTERNAL (node
->decl
))
5004 && inline_summary (node
)->size
>= MAX_INLINE_INSNS_AUTO
)
5007 fprintf (dump_file
, "Function too big to be made truly local.\n");
5011 if (!node
->call_for_symbol_thunks_and_aliases (has_caller_p
, NULL
, true))
5015 "Function has no callers in this compilation unit.\n");
5022 fprintf (dump_file
, "Function uses stdarg. \n");
5026 if (TYPE_ATTRIBUTES (TREE_TYPE (node
->decl
)))
5029 if (DECL_DISREGARD_INLINE_LIMITS (node
->decl
))
5032 fprintf (dump_file
, "Always inline function will be inlined "
5040 /* Perform early interprocedural SRA. */
5043 ipa_early_sra (void)
5045 struct cgraph_node
*node
= cgraph_node::get (current_function_decl
);
5046 ipa_parm_adjustment_vec adjustments
;
5049 if (!ipa_sra_preliminary_function_checks (node
))
5053 sra_mode
= SRA_MODE_EARLY_IPA
;
5055 if (!find_param_candidates ())
5058 fprintf (dump_file
, "Function has no IPA-SRA candidates.\n");
5062 if (node
->call_for_symbol_thunks_and_aliases
5063 (some_callers_have_mismatched_arguments_p
, NULL
, true))
5066 fprintf (dump_file
, "There are callers with insufficient number of "
5067 "arguments or arguments with type mismatches.\n");
5071 bb_dereferences
= XCNEWVEC (HOST_WIDE_INT
,
5073 * last_basic_block_for_fn (cfun
));
5074 final_bbs
= BITMAP_ALLOC (NULL
);
5077 if (encountered_apply_args
)
5080 fprintf (dump_file
, "Function calls __builtin_apply_args().\n");
5084 if (encountered_unchangable_recursive_call
)
5087 fprintf (dump_file
, "Function calls itself with insufficient "
5088 "number of arguments.\n");
5092 adjustments
= analyze_all_param_acesses ();
5093 if (!adjustments
.exists ())
5096 ipa_dump_param_adjustments (dump_file
, adjustments
, current_function_decl
);
5098 if (modify_function (node
, adjustments
))
5099 ret
= TODO_update_ssa
| TODO_cleanup_cfg
;
5101 ret
= TODO_update_ssa
;
5102 adjustments
.release ();
5104 statistics_counter_event (cfun
, "Unused parameters deleted",
5105 sra_stats
.deleted_unused_parameters
);
5106 statistics_counter_event (cfun
, "Scalar parameters converted to by-value",
5107 sra_stats
.scalar_by_ref_to_by_val
);
5108 statistics_counter_event (cfun
, "Aggregate parameters broken up",
5109 sra_stats
.aggregate_params_reduced
);
5110 statistics_counter_event (cfun
, "Aggregate parameter components created",
5111 sra_stats
.param_reductions_created
);
5114 BITMAP_FREE (final_bbs
);
5115 free (bb_dereferences
);
5117 sra_deinitialize ();
5123 const pass_data pass_data_early_ipa_sra
=
5125 GIMPLE_PASS
, /* type */
5126 "eipa_sra", /* name */
5127 OPTGROUP_NONE
, /* optinfo_flags */
5128 TV_IPA_SRA
, /* tv_id */
5129 0, /* properties_required */
5130 0, /* properties_provided */
5131 0, /* properties_destroyed */
5132 0, /* todo_flags_start */
5133 TODO_dump_symtab
, /* todo_flags_finish */
5136 class pass_early_ipa_sra
: public gimple_opt_pass
5139 pass_early_ipa_sra (gcc::context
*ctxt
)
5140 : gimple_opt_pass (pass_data_early_ipa_sra
, ctxt
)
5143 /* opt_pass methods: */
5144 virtual bool gate (function
*) { return flag_ipa_sra
&& dbg_cnt (eipa_sra
); }
5145 virtual unsigned int execute (function
*) { return ipa_early_sra (); }
5147 }; // class pass_early_ipa_sra
5152 make_pass_early_ipa_sra (gcc::context
*ctxt
)
5154 return new pass_early_ipa_sra (ctxt
);