1 /* Scalar Replacement of Aggregates (SRA) converts some structure
2 references into scalar references, exposing them to the scalar
4 Copyright (C) 2008-2013 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"
116 /* Enumeration of all aggregate reductions we can do. */
117 enum sra_mode
{ SRA_MODE_EARLY_IPA
, /* early call regularization */
118 SRA_MODE_EARLY_INTRA
, /* early intraprocedural SRA */
119 SRA_MODE_INTRA
}; /* late intraprocedural SRA */
121 /* Global variable describing which aggregate reduction we are performing at
123 static enum sra_mode sra_mode
;
127 /* ACCESS represents each access to an aggregate variable (as a whole or a
128 part). It can also represent a group of accesses that refer to exactly the
129 same fragment of an aggregate (i.e. those that have exactly the same offset
130 and size). Such representatives for a single aggregate, once determined,
131 are linked in a linked list and have the group fields set.
133 Moreover, when doing intraprocedural SRA, a tree is built from those
134 representatives (by the means of first_child and next_sibling pointers), in
135 which all items in a subtree are "within" the root, i.e. their offset is
136 greater or equal to offset of the root and offset+size is smaller or equal
137 to offset+size of the root. Children of an access are sorted by offset.
139 Note that accesses to parts of vector and complex number types always
140 represented by an access to the whole complex number or a vector. It is a
141 duty of the modifying functions to replace them appropriately. */
145 /* Values returned by `get_ref_base_and_extent' for each component reference
146 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
147 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
148 HOST_WIDE_INT offset
;
152 /* Expression. It is context dependent so do not use it to create new
153 expressions to access the original aggregate. See PR 42154 for a
159 /* The statement this access belongs to. */
162 /* Next group representative for this aggregate. */
163 struct access
*next_grp
;
165 /* Pointer to the group representative. Pointer to itself if the struct is
166 the representative. */
167 struct access
*group_representative
;
169 /* If this access has any children (in terms of the definition above), this
170 points to the first one. */
171 struct access
*first_child
;
173 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
174 described above. In IPA-SRA this is a pointer to the next access
175 belonging to the same group (having the same representative). */
176 struct access
*next_sibling
;
178 /* Pointers to the first and last element in the linked list of assign
180 struct assign_link
*first_link
, *last_link
;
182 /* Pointer to the next access in the work queue. */
183 struct access
*next_queued
;
185 /* Replacement variable for this access "region." Never to be accessed
186 directly, always only by the means of get_access_replacement() and only
187 when grp_to_be_replaced flag is set. */
188 tree replacement_decl
;
190 /* Is this particular access write access? */
193 /* Is this access an access to a non-addressable field? */
194 unsigned non_addressable
: 1;
196 /* Is this access currently in the work queue? */
197 unsigned grp_queued
: 1;
199 /* Does this group contain a write access? This flag is propagated down the
201 unsigned grp_write
: 1;
203 /* Does this group contain a read access? This flag is propagated down the
205 unsigned grp_read
: 1;
207 /* Does this group contain a read access that comes from an assignment
208 statement? This flag is propagated down the access tree. */
209 unsigned grp_assignment_read
: 1;
211 /* Does this group contain a write access that comes from an assignment
212 statement? This flag is propagated down the access tree. */
213 unsigned grp_assignment_write
: 1;
215 /* Does this group contain a read access through a scalar type? This flag is
216 not propagated in the access tree in any direction. */
217 unsigned grp_scalar_read
: 1;
219 /* Does this group contain a write access through a scalar type? This flag
220 is not propagated in the access tree in any direction. */
221 unsigned grp_scalar_write
: 1;
223 /* Is this access an artificial one created to scalarize some record
225 unsigned grp_total_scalarization
: 1;
227 /* Other passes of the analysis use this bit to make function
228 analyze_access_subtree create scalar replacements for this group if
230 unsigned grp_hint
: 1;
232 /* Is the subtree rooted in this access fully covered by scalar
234 unsigned grp_covered
: 1;
236 /* If set to true, this access and all below it in an access tree must not be
238 unsigned grp_unscalarizable_region
: 1;
240 /* Whether data have been written to parts of the aggregate covered by this
241 access which is not to be scalarized. This flag is propagated up in the
243 unsigned grp_unscalarized_data
: 1;
245 /* Does this access and/or group contain a write access through a
247 unsigned grp_partial_lhs
: 1;
249 /* Set when a scalar replacement should be created for this variable. */
250 unsigned grp_to_be_replaced
: 1;
252 /* Set when we want a replacement for the sole purpose of having it in
253 generated debug statements. */
254 unsigned grp_to_be_debug_replaced
: 1;
256 /* Should TREE_NO_WARNING of a replacement be set? */
257 unsigned grp_no_warning
: 1;
259 /* Is it possible that the group refers to data which might be (directly or
260 otherwise) modified? */
261 unsigned grp_maybe_modified
: 1;
263 /* Set when this is a representative of a pointer to scalar (i.e. by
264 reference) parameter which we consider for turning into a plain scalar
265 (i.e. a by value parameter). */
266 unsigned grp_scalar_ptr
: 1;
268 /* Set when we discover that this pointer is not safe to dereference in the
270 unsigned grp_not_necessarilly_dereferenced
: 1;
273 typedef struct access
*access_p
;
276 /* Alloc pool for allocating access structures. */
277 static alloc_pool access_pool
;
279 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
280 are used to propagate subaccesses from rhs to lhs as long as they don't
281 conflict with what is already there. */
284 struct access
*lacc
, *racc
;
285 struct assign_link
*next
;
288 /* Alloc pool for allocating assign link structures. */
289 static alloc_pool link_pool
;
291 /* Base (tree) -> Vector (vec<access_p> *) map. */
292 static struct pointer_map_t
*base_access_vec
;
294 /* Candidate hash table helpers. */
296 struct uid_decl_hasher
: typed_noop_remove
<tree_node
>
298 typedef tree_node value_type
;
299 typedef tree_node compare_type
;
300 static inline hashval_t
hash (const value_type
*);
301 static inline bool equal (const value_type
*, const compare_type
*);
304 /* Hash a tree in a uid_decl_map. */
307 uid_decl_hasher::hash (const value_type
*item
)
309 return item
->decl_minimal
.uid
;
312 /* Return true if the DECL_UID in both trees are equal. */
315 uid_decl_hasher::equal (const value_type
*a
, const compare_type
*b
)
317 return (a
->decl_minimal
.uid
== b
->decl_minimal
.uid
);
320 /* Set of candidates. */
321 static bitmap candidate_bitmap
;
322 static hash_table
<uid_decl_hasher
> candidates
;
324 /* For a candidate UID return the candidates decl. */
327 candidate (unsigned uid
)
330 t
.decl_minimal
.uid
= uid
;
331 return candidates
.find_with_hash (&t
, static_cast <hashval_t
> (uid
));
334 /* Bitmap of candidates which we should try to entirely scalarize away and
335 those which cannot be (because they are and need be used as a whole). */
336 static bitmap should_scalarize_away_bitmap
, cannot_scalarize_away_bitmap
;
338 /* Obstack for creation of fancy names. */
339 static struct obstack name_obstack
;
341 /* Head of a linked list of accesses that need to have its subaccesses
342 propagated to their assignment counterparts. */
343 static struct access
*work_queue_head
;
345 /* Number of parameters of the analyzed function when doing early ipa SRA. */
346 static int func_param_count
;
348 /* scan_function sets the following to true if it encounters a call to
349 __builtin_apply_args. */
350 static bool encountered_apply_args
;
352 /* Set by scan_function when it finds a recursive call. */
353 static bool encountered_recursive_call
;
355 /* Set by scan_function when it finds a recursive call with less actual
356 arguments than formal parameters.. */
357 static bool encountered_unchangable_recursive_call
;
359 /* This is a table in which for each basic block and parameter there is a
360 distance (offset + size) in that parameter which is dereferenced and
361 accessed in that BB. */
362 static HOST_WIDE_INT
*bb_dereferences
;
363 /* Bitmap of BBs that can cause the function to "stop" progressing by
364 returning, throwing externally, looping infinitely or calling a function
365 which might abort etc.. */
366 static bitmap final_bbs
;
368 /* Representative of no accesses at all. */
369 static struct access no_accesses_representant
;
371 /* Predicate to test the special value. */
374 no_accesses_p (struct access
*access
)
376 return access
== &no_accesses_representant
;
379 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
380 representative fields are dumped, otherwise those which only describe the
381 individual access are. */
385 /* Number of processed aggregates is readily available in
386 analyze_all_variable_accesses and so is not stored here. */
388 /* Number of created scalar replacements. */
391 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
395 /* Number of statements created by generate_subtree_copies. */
398 /* Number of statements created by load_assign_lhs_subreplacements. */
401 /* Number of times sra_modify_assign has deleted a statement. */
404 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
405 RHS reparately due to type conversions or nonexistent matching
407 int separate_lhs_rhs_handling
;
409 /* Number of parameters that were removed because they were unused. */
410 int deleted_unused_parameters
;
412 /* Number of scalars passed as parameters by reference that have been
413 converted to be passed by value. */
414 int scalar_by_ref_to_by_val
;
416 /* Number of aggregate parameters that were replaced by one or more of their
418 int aggregate_params_reduced
;
420 /* Numbber of components created when splitting aggregate parameters. */
421 int param_reductions_created
;
425 dump_access (FILE *f
, struct access
*access
, bool grp
)
427 fprintf (f
, "access { ");
428 fprintf (f
, "base = (%d)'", DECL_UID (access
->base
));
429 print_generic_expr (f
, access
->base
, 0);
430 fprintf (f
, "', offset = " HOST_WIDE_INT_PRINT_DEC
, access
->offset
);
431 fprintf (f
, ", size = " HOST_WIDE_INT_PRINT_DEC
, access
->size
);
432 fprintf (f
, ", expr = ");
433 print_generic_expr (f
, access
->expr
, 0);
434 fprintf (f
, ", type = ");
435 print_generic_expr (f
, access
->type
, 0);
437 fprintf (f
, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
438 "grp_assignment_write = %d, grp_scalar_read = %d, "
439 "grp_scalar_write = %d, grp_total_scalarization = %d, "
440 "grp_hint = %d, grp_covered = %d, "
441 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
442 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
443 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
444 "grp_not_necessarilly_dereferenced = %d\n",
445 access
->grp_read
, access
->grp_write
, access
->grp_assignment_read
,
446 access
->grp_assignment_write
, access
->grp_scalar_read
,
447 access
->grp_scalar_write
, access
->grp_total_scalarization
,
448 access
->grp_hint
, access
->grp_covered
,
449 access
->grp_unscalarizable_region
, access
->grp_unscalarized_data
,
450 access
->grp_partial_lhs
, access
->grp_to_be_replaced
,
451 access
->grp_to_be_debug_replaced
, access
->grp_maybe_modified
,
452 access
->grp_not_necessarilly_dereferenced
);
454 fprintf (f
, ", write = %d, grp_total_scalarization = %d, "
455 "grp_partial_lhs = %d\n",
456 access
->write
, access
->grp_total_scalarization
,
457 access
->grp_partial_lhs
);
460 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
463 dump_access_tree_1 (FILE *f
, struct access
*access
, int level
)
469 for (i
= 0; i
< level
; i
++)
470 fputs ("* ", dump_file
);
472 dump_access (f
, access
, true);
474 if (access
->first_child
)
475 dump_access_tree_1 (f
, access
->first_child
, level
+ 1);
477 access
= access
->next_sibling
;
482 /* Dump all access trees for a variable, given the pointer to the first root in
486 dump_access_tree (FILE *f
, struct access
*access
)
488 for (; access
; access
= access
->next_grp
)
489 dump_access_tree_1 (f
, access
, 0);
492 /* Return true iff ACC is non-NULL and has subaccesses. */
495 access_has_children_p (struct access
*acc
)
497 return acc
&& acc
->first_child
;
500 /* Return true iff ACC is (partly) covered by at least one replacement. */
503 access_has_replacements_p (struct access
*acc
)
505 struct access
*child
;
506 if (acc
->grp_to_be_replaced
)
508 for (child
= acc
->first_child
; child
; child
= child
->next_sibling
)
509 if (access_has_replacements_p (child
))
514 /* Return a vector of pointers to accesses for the variable given in BASE or
515 NULL if there is none. */
517 static vec
<access_p
> *
518 get_base_access_vector (tree base
)
522 slot
= pointer_map_contains (base_access_vec
, base
);
526 return *(vec
<access_p
> **) slot
;
529 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
530 in ACCESS. Return NULL if it cannot be found. */
532 static struct access
*
533 find_access_in_subtree (struct access
*access
, HOST_WIDE_INT offset
,
536 while (access
&& (access
->offset
!= offset
|| access
->size
!= size
))
538 struct access
*child
= access
->first_child
;
540 while (child
&& (child
->offset
+ child
->size
<= offset
))
541 child
= child
->next_sibling
;
548 /* Return the first group representative for DECL or NULL if none exists. */
550 static struct access
*
551 get_first_repr_for_decl (tree base
)
553 vec
<access_p
> *access_vec
;
555 access_vec
= get_base_access_vector (base
);
559 return (*access_vec
)[0];
562 /* Find an access representative for the variable BASE and given OFFSET and
563 SIZE. Requires that access trees have already been built. Return NULL if
564 it cannot be found. */
566 static struct access
*
567 get_var_base_offset_size_access (tree base
, HOST_WIDE_INT offset
,
570 struct access
*access
;
572 access
= get_first_repr_for_decl (base
);
573 while (access
&& (access
->offset
+ access
->size
<= offset
))
574 access
= access
->next_grp
;
578 return find_access_in_subtree (access
, offset
, size
);
581 /* Add LINK to the linked list of assign links of RACC. */
583 add_link_to_rhs (struct access
*racc
, struct assign_link
*link
)
585 gcc_assert (link
->racc
== racc
);
587 if (!racc
->first_link
)
589 gcc_assert (!racc
->last_link
);
590 racc
->first_link
= link
;
593 racc
->last_link
->next
= link
;
595 racc
->last_link
= link
;
599 /* Move all link structures in their linked list in OLD_RACC to the linked list
602 relink_to_new_repr (struct access
*new_racc
, struct access
*old_racc
)
604 if (!old_racc
->first_link
)
606 gcc_assert (!old_racc
->last_link
);
610 if (new_racc
->first_link
)
612 gcc_assert (!new_racc
->last_link
->next
);
613 gcc_assert (!old_racc
->last_link
|| !old_racc
->last_link
->next
);
615 new_racc
->last_link
->next
= old_racc
->first_link
;
616 new_racc
->last_link
= old_racc
->last_link
;
620 gcc_assert (!new_racc
->last_link
);
622 new_racc
->first_link
= old_racc
->first_link
;
623 new_racc
->last_link
= old_racc
->last_link
;
625 old_racc
->first_link
= old_racc
->last_link
= NULL
;
628 /* Add ACCESS to the work queue (which is actually a stack). */
631 add_access_to_work_queue (struct access
*access
)
633 if (!access
->grp_queued
)
635 gcc_assert (!access
->next_queued
);
636 access
->next_queued
= work_queue_head
;
637 access
->grp_queued
= 1;
638 work_queue_head
= access
;
642 /* Pop an access from the work queue, and return it, assuming there is one. */
644 static struct access
*
645 pop_access_from_work_queue (void)
647 struct access
*access
= work_queue_head
;
649 work_queue_head
= access
->next_queued
;
650 access
->next_queued
= NULL
;
651 access
->grp_queued
= 0;
656 /* Allocate necessary structures. */
659 sra_initialize (void)
661 candidate_bitmap
= BITMAP_ALLOC (NULL
);
662 candidates
.create (vec_safe_length (cfun
->local_decls
) / 2);
663 should_scalarize_away_bitmap
= BITMAP_ALLOC (NULL
);
664 cannot_scalarize_away_bitmap
= BITMAP_ALLOC (NULL
);
665 gcc_obstack_init (&name_obstack
);
666 access_pool
= create_alloc_pool ("SRA accesses", sizeof (struct access
), 16);
667 link_pool
= create_alloc_pool ("SRA links", sizeof (struct assign_link
), 16);
668 base_access_vec
= pointer_map_create ();
669 memset (&sra_stats
, 0, sizeof (sra_stats
));
670 encountered_apply_args
= false;
671 encountered_recursive_call
= false;
672 encountered_unchangable_recursive_call
= false;
675 /* Hook fed to pointer_map_traverse, deallocate stored vectors. */
678 delete_base_accesses (const void *key ATTRIBUTE_UNUSED
, void **value
,
679 void *data ATTRIBUTE_UNUSED
)
681 vec
<access_p
> *access_vec
= (vec
<access_p
> *) *value
;
682 vec_free (access_vec
);
686 /* Deallocate all general structures. */
689 sra_deinitialize (void)
691 BITMAP_FREE (candidate_bitmap
);
692 candidates
.dispose ();
693 BITMAP_FREE (should_scalarize_away_bitmap
);
694 BITMAP_FREE (cannot_scalarize_away_bitmap
);
695 free_alloc_pool (access_pool
);
696 free_alloc_pool (link_pool
);
697 obstack_free (&name_obstack
, NULL
);
699 pointer_map_traverse (base_access_vec
, delete_base_accesses
, NULL
);
700 pointer_map_destroy (base_access_vec
);
703 /* Remove DECL from candidates for SRA and write REASON to the dump file if
706 disqualify_candidate (tree decl
, const char *reason
)
708 if (bitmap_clear_bit (candidate_bitmap
, DECL_UID (decl
)))
709 candidates
.clear_slot (candidates
.find_slot_with_hash (decl
,
713 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
715 fprintf (dump_file
, "! Disqualifying ");
716 print_generic_expr (dump_file
, decl
, 0);
717 fprintf (dump_file
, " - %s\n", reason
);
721 /* Return true iff the type contains a field or an element which does not allow
725 type_internals_preclude_sra_p (tree type
, const char **msg
)
730 switch (TREE_CODE (type
))
734 case QUAL_UNION_TYPE
:
735 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
736 if (TREE_CODE (fld
) == FIELD_DECL
)
738 tree ft
= TREE_TYPE (fld
);
740 if (TREE_THIS_VOLATILE (fld
))
742 *msg
= "volatile structure field";
745 if (!DECL_FIELD_OFFSET (fld
))
747 *msg
= "no structure field offset";
750 if (!DECL_SIZE (fld
))
752 *msg
= "zero structure field size";
755 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
757 *msg
= "structure field offset not fixed";
760 if (!tree_fits_uhwi_p (DECL_SIZE (fld
)))
762 *msg
= "structure field size not fixed";
765 if (!tree_fits_shwi_p (bit_position (fld
)))
767 *msg
= "structure field size too big";
770 if (AGGREGATE_TYPE_P (ft
)
771 && int_bit_position (fld
) % BITS_PER_UNIT
!= 0)
773 *msg
= "structure field is bit field";
777 if (AGGREGATE_TYPE_P (ft
) && type_internals_preclude_sra_p (ft
, msg
))
784 et
= TREE_TYPE (type
);
786 if (TYPE_VOLATILE (et
))
788 *msg
= "element type is volatile";
792 if (AGGREGATE_TYPE_P (et
) && type_internals_preclude_sra_p (et
, msg
))
802 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
803 base variable if it is. Return T if it is not an SSA_NAME. */
806 get_ssa_base_param (tree t
)
808 if (TREE_CODE (t
) == SSA_NAME
)
810 if (SSA_NAME_IS_DEFAULT_DEF (t
))
811 return SSA_NAME_VAR (t
);
818 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
819 belongs to, unless the BB has already been marked as a potentially
823 mark_parm_dereference (tree base
, HOST_WIDE_INT dist
, gimple stmt
)
825 basic_block bb
= gimple_bb (stmt
);
826 int idx
, parm_index
= 0;
829 if (bitmap_bit_p (final_bbs
, bb
->index
))
832 for (parm
= DECL_ARGUMENTS (current_function_decl
);
833 parm
&& parm
!= base
;
834 parm
= DECL_CHAIN (parm
))
837 gcc_assert (parm_index
< func_param_count
);
839 idx
= bb
->index
* func_param_count
+ parm_index
;
840 if (bb_dereferences
[idx
] < dist
)
841 bb_dereferences
[idx
] = dist
;
844 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
845 the three fields. Also add it to the vector of accesses corresponding to
846 the base. Finally, return the new access. */
848 static struct access
*
849 create_access_1 (tree base
, HOST_WIDE_INT offset
, HOST_WIDE_INT size
)
852 struct access
*access
;
855 access
= (struct access
*) pool_alloc (access_pool
);
856 memset (access
, 0, sizeof (struct access
));
858 access
->offset
= offset
;
861 slot
= pointer_map_contains (base_access_vec
, base
);
863 v
= (vec
<access_p
> *) *slot
;
867 v
->safe_push (access
);
870 pointer_map_insert (base_access_vec
, base
)) = v
;
875 /* Create and insert access for EXPR. Return created access, or NULL if it is
878 static struct access
*
879 create_access (tree expr
, gimple stmt
, bool write
)
881 struct access
*access
;
882 HOST_WIDE_INT offset
, size
, max_size
;
884 bool ptr
, unscalarizable_region
= false;
886 base
= get_ref_base_and_extent (expr
, &offset
, &size
, &max_size
);
888 if (sra_mode
== SRA_MODE_EARLY_IPA
889 && TREE_CODE (base
) == MEM_REF
)
891 base
= get_ssa_base_param (TREE_OPERAND (base
, 0));
899 if (!DECL_P (base
) || !bitmap_bit_p (candidate_bitmap
, DECL_UID (base
)))
902 if (sra_mode
== SRA_MODE_EARLY_IPA
)
904 if (size
< 0 || size
!= max_size
)
906 disqualify_candidate (base
, "Encountered a variable sized access.");
909 if (TREE_CODE (expr
) == COMPONENT_REF
910 && DECL_BIT_FIELD (TREE_OPERAND (expr
, 1)))
912 disqualify_candidate (base
, "Encountered a bit-field access.");
915 gcc_checking_assert ((offset
% BITS_PER_UNIT
) == 0);
918 mark_parm_dereference (base
, offset
+ size
, stmt
);
922 if (size
!= max_size
)
925 unscalarizable_region
= true;
929 disqualify_candidate (base
, "Encountered an unconstrained access.");
934 access
= create_access_1 (base
, offset
, size
);
936 access
->type
= TREE_TYPE (expr
);
937 access
->write
= write
;
938 access
->grp_unscalarizable_region
= unscalarizable_region
;
941 if (TREE_CODE (expr
) == COMPONENT_REF
942 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr
, 1)))
943 access
->non_addressable
= 1;
949 /* Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple
950 register types or (recursively) records with only these two kinds of fields.
951 It also returns false if any of these records contains a bit-field. */
954 type_consists_of_records_p (tree type
)
958 if (TREE_CODE (type
) != RECORD_TYPE
)
961 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
962 if (TREE_CODE (fld
) == FIELD_DECL
)
964 tree ft
= TREE_TYPE (fld
);
966 if (DECL_BIT_FIELD (fld
))
969 if (!is_gimple_reg_type (ft
)
970 && !type_consists_of_records_p (ft
))
977 /* Create total_scalarization accesses for all scalar type fields in DECL that
978 must be of a RECORD_TYPE conforming to type_consists_of_records_p. BASE
979 must be the top-most VAR_DECL representing the variable, OFFSET must be the
980 offset of DECL within BASE. REF must be the memory reference expression for
984 completely_scalarize_record (tree base
, tree decl
, HOST_WIDE_INT offset
,
987 tree fld
, decl_type
= TREE_TYPE (decl
);
989 for (fld
= TYPE_FIELDS (decl_type
); fld
; fld
= DECL_CHAIN (fld
))
990 if (TREE_CODE (fld
) == FIELD_DECL
)
992 HOST_WIDE_INT pos
= offset
+ int_bit_position (fld
);
993 tree ft
= TREE_TYPE (fld
);
994 tree nref
= build3 (COMPONENT_REF
, TREE_TYPE (fld
), ref
, fld
,
997 if (is_gimple_reg_type (ft
))
999 struct access
*access
;
1002 size
= tree_to_uhwi (DECL_SIZE (fld
));
1003 access
= create_access_1 (base
, pos
, size
);
1004 access
->expr
= nref
;
1006 access
->grp_total_scalarization
= 1;
1007 /* Accesses for intraprocedural SRA can have their stmt NULL. */
1010 completely_scalarize_record (base
, fld
, pos
, nref
);
1014 /* Create total_scalarization accesses for all scalar type fields in VAR and
1015 for VAR a a whole. VAR must be of a RECORD_TYPE conforming to
1016 type_consists_of_records_p. */
1019 completely_scalarize_var (tree var
)
1021 HOST_WIDE_INT size
= tree_to_uhwi (DECL_SIZE (var
));
1022 struct access
*access
;
1024 access
= create_access_1 (var
, 0, size
);
1026 access
->type
= TREE_TYPE (var
);
1027 access
->grp_total_scalarization
= 1;
1029 completely_scalarize_record (var
, var
, 0, var
);
1032 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1035 contains_view_convert_expr_p (const_tree ref
)
1037 while (handled_component_p (ref
))
1039 if (TREE_CODE (ref
) == VIEW_CONVERT_EXPR
)
1041 ref
= TREE_OPERAND (ref
, 0);
1047 /* Search the given tree for a declaration by skipping handled components and
1048 exclude it from the candidates. */
1051 disqualify_base_of_expr (tree t
, const char *reason
)
1053 t
= get_base_address (t
);
1054 if (sra_mode
== SRA_MODE_EARLY_IPA
1055 && TREE_CODE (t
) == MEM_REF
)
1056 t
= get_ssa_base_param (TREE_OPERAND (t
, 0));
1058 if (t
&& DECL_P (t
))
1059 disqualify_candidate (t
, reason
);
1062 /* Scan expression EXPR and create access structures for all accesses to
1063 candidates for scalarization. Return the created access or NULL if none is
1066 static struct access
*
1067 build_access_from_expr_1 (tree expr
, gimple stmt
, bool write
)
1069 struct access
*ret
= NULL
;
1072 if (TREE_CODE (expr
) == BIT_FIELD_REF
1073 || TREE_CODE (expr
) == IMAGPART_EXPR
1074 || TREE_CODE (expr
) == REALPART_EXPR
)
1076 expr
= TREE_OPERAND (expr
, 0);
1080 partial_ref
= false;
1082 /* We need to dive through V_C_Es in order to get the size of its parameter
1083 and not the result type. Ada produces such statements. We are also
1084 capable of handling the topmost V_C_E but not any of those buried in other
1085 handled components. */
1086 if (TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
1087 expr
= TREE_OPERAND (expr
, 0);
1089 if (contains_view_convert_expr_p (expr
))
1091 disqualify_base_of_expr (expr
, "V_C_E under a different handled "
1096 switch (TREE_CODE (expr
))
1099 if (TREE_CODE (TREE_OPERAND (expr
, 0)) != ADDR_EXPR
1100 && sra_mode
!= SRA_MODE_EARLY_IPA
)
1108 case ARRAY_RANGE_REF
:
1109 ret
= create_access (expr
, stmt
, write
);
1116 if (write
&& partial_ref
&& ret
)
1117 ret
->grp_partial_lhs
= 1;
1122 /* Scan expression EXPR and create access structures for all accesses to
1123 candidates for scalarization. Return true if any access has been inserted.
1124 STMT must be the statement from which the expression is taken, WRITE must be
1125 true if the expression is a store and false otherwise. */
1128 build_access_from_expr (tree expr
, gimple stmt
, bool write
)
1130 struct access
*access
;
1132 access
= build_access_from_expr_1 (expr
, stmt
, write
);
1135 /* This means the aggregate is accesses as a whole in a way other than an
1136 assign statement and thus cannot be removed even if we had a scalar
1137 replacement for everything. */
1138 if (cannot_scalarize_away_bitmap
)
1139 bitmap_set_bit (cannot_scalarize_away_bitmap
, DECL_UID (access
->base
));
1145 /* Disqualify LHS and RHS for scalarization if STMT must end its basic block in
1146 modes in which it matters, return true iff they have been disqualified. RHS
1147 may be NULL, in that case ignore it. If we scalarize an aggregate in
1148 intra-SRA we may need to add statements after each statement. This is not
1149 possible if a statement unconditionally has to end the basic block. */
1151 disqualify_ops_if_throwing_stmt (gimple stmt
, tree lhs
, tree rhs
)
1153 if ((sra_mode
== SRA_MODE_EARLY_INTRA
|| sra_mode
== SRA_MODE_INTRA
)
1154 && (stmt_can_throw_internal (stmt
) || stmt_ends_bb_p (stmt
)))
1156 disqualify_base_of_expr (lhs
, "LHS of a throwing stmt.");
1158 disqualify_base_of_expr (rhs
, "RHS of a throwing stmt.");
1164 /* Scan expressions occurring in STMT, create access structures for all accesses
1165 to candidates for scalarization and remove those candidates which occur in
1166 statements or expressions that prevent them from being split apart. Return
1167 true if any access has been inserted. */
1170 build_accesses_from_assign (gimple stmt
)
1173 struct access
*lacc
, *racc
;
1175 if (!gimple_assign_single_p (stmt
)
1176 /* Scope clobbers don't influence scalarization. */
1177 || gimple_clobber_p (stmt
))
1180 lhs
= gimple_assign_lhs (stmt
);
1181 rhs
= gimple_assign_rhs1 (stmt
);
1183 if (disqualify_ops_if_throwing_stmt (stmt
, lhs
, rhs
))
1186 racc
= build_access_from_expr_1 (rhs
, stmt
, false);
1187 lacc
= build_access_from_expr_1 (lhs
, stmt
, true);
1190 lacc
->grp_assignment_write
= 1;
1194 racc
->grp_assignment_read
= 1;
1195 if (should_scalarize_away_bitmap
&& !gimple_has_volatile_ops (stmt
)
1196 && !is_gimple_reg_type (racc
->type
))
1197 bitmap_set_bit (should_scalarize_away_bitmap
, DECL_UID (racc
->base
));
1201 && (sra_mode
== SRA_MODE_EARLY_INTRA
|| sra_mode
== SRA_MODE_INTRA
)
1202 && !lacc
->grp_unscalarizable_region
1203 && !racc
->grp_unscalarizable_region
1204 && AGGREGATE_TYPE_P (TREE_TYPE (lhs
))
1205 && lacc
->size
== racc
->size
1206 && useless_type_conversion_p (lacc
->type
, racc
->type
))
1208 struct assign_link
*link
;
1210 link
= (struct assign_link
*) pool_alloc (link_pool
);
1211 memset (link
, 0, sizeof (struct assign_link
));
1216 add_link_to_rhs (racc
, link
);
1219 return lacc
|| racc
;
1222 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1223 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1226 asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED
, tree op
,
1227 void *data ATTRIBUTE_UNUSED
)
1229 op
= get_base_address (op
);
1232 disqualify_candidate (op
, "Non-scalarizable GIMPLE_ASM operand.");
1237 /* Return true iff callsite CALL has at least as many actual arguments as there
1238 are formal parameters of the function currently processed by IPA-SRA. */
1241 callsite_has_enough_arguments_p (gimple call
)
1243 return gimple_call_num_args (call
) >= (unsigned) func_param_count
;
1246 /* Scan function and look for interesting expressions and create access
1247 structures for them. Return true iff any access is created. */
1250 scan_function (void)
1257 gimple_stmt_iterator gsi
;
1258 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1260 gimple stmt
= gsi_stmt (gsi
);
1264 if (final_bbs
&& stmt_can_throw_external (stmt
))
1265 bitmap_set_bit (final_bbs
, bb
->index
);
1266 switch (gimple_code (stmt
))
1269 t
= gimple_return_retval (stmt
);
1271 ret
|= build_access_from_expr (t
, stmt
, false);
1273 bitmap_set_bit (final_bbs
, bb
->index
);
1277 ret
|= build_accesses_from_assign (stmt
);
1281 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1282 ret
|= build_access_from_expr (gimple_call_arg (stmt
, i
),
1285 if (sra_mode
== SRA_MODE_EARLY_IPA
)
1287 tree dest
= gimple_call_fndecl (stmt
);
1288 int flags
= gimple_call_flags (stmt
);
1292 if (DECL_BUILT_IN_CLASS (dest
) == BUILT_IN_NORMAL
1293 && DECL_FUNCTION_CODE (dest
) == BUILT_IN_APPLY_ARGS
)
1294 encountered_apply_args
= true;
1295 if (recursive_call_p (current_function_decl
, dest
))
1297 encountered_recursive_call
= true;
1298 if (!callsite_has_enough_arguments_p (stmt
))
1299 encountered_unchangable_recursive_call
= true;
1304 && (flags
& (ECF_CONST
| ECF_PURE
)) == 0)
1305 bitmap_set_bit (final_bbs
, bb
->index
);
1308 t
= gimple_call_lhs (stmt
);
1309 if (t
&& !disqualify_ops_if_throwing_stmt (stmt
, t
, NULL
))
1310 ret
|= build_access_from_expr (t
, stmt
, true);
1314 walk_stmt_load_store_addr_ops (stmt
, NULL
, NULL
, NULL
,
1317 bitmap_set_bit (final_bbs
, bb
->index
);
1319 for (i
= 0; i
< gimple_asm_ninputs (stmt
); i
++)
1321 t
= TREE_VALUE (gimple_asm_input_op (stmt
, i
));
1322 ret
|= build_access_from_expr (t
, stmt
, false);
1324 for (i
= 0; i
< gimple_asm_noutputs (stmt
); i
++)
1326 t
= TREE_VALUE (gimple_asm_output_op (stmt
, i
));
1327 ret
|= build_access_from_expr (t
, stmt
, true);
1340 /* Helper of QSORT function. There are pointers to accesses in the array. An
1341 access is considered smaller than another if it has smaller offset or if the
1342 offsets are the same but is size is bigger. */
1345 compare_access_positions (const void *a
, const void *b
)
1347 const access_p
*fp1
= (const access_p
*) a
;
1348 const access_p
*fp2
= (const access_p
*) b
;
1349 const access_p f1
= *fp1
;
1350 const access_p f2
= *fp2
;
1352 if (f1
->offset
!= f2
->offset
)
1353 return f1
->offset
< f2
->offset
? -1 : 1;
1355 if (f1
->size
== f2
->size
)
1357 if (f1
->type
== f2
->type
)
1359 /* Put any non-aggregate type before any aggregate type. */
1360 else if (!is_gimple_reg_type (f1
->type
)
1361 && is_gimple_reg_type (f2
->type
))
1363 else if (is_gimple_reg_type (f1
->type
)
1364 && !is_gimple_reg_type (f2
->type
))
1366 /* Put any complex or vector type before any other scalar type. */
1367 else if (TREE_CODE (f1
->type
) != COMPLEX_TYPE
1368 && TREE_CODE (f1
->type
) != VECTOR_TYPE
1369 && (TREE_CODE (f2
->type
) == COMPLEX_TYPE
1370 || TREE_CODE (f2
->type
) == VECTOR_TYPE
))
1372 else if ((TREE_CODE (f1
->type
) == COMPLEX_TYPE
1373 || TREE_CODE (f1
->type
) == VECTOR_TYPE
)
1374 && TREE_CODE (f2
->type
) != COMPLEX_TYPE
1375 && TREE_CODE (f2
->type
) != VECTOR_TYPE
)
1377 /* Put the integral type with the bigger precision first. */
1378 else if (INTEGRAL_TYPE_P (f1
->type
)
1379 && INTEGRAL_TYPE_P (f2
->type
))
1380 return TYPE_PRECISION (f2
->type
) - TYPE_PRECISION (f1
->type
);
1381 /* Put any integral type with non-full precision last. */
1382 else if (INTEGRAL_TYPE_P (f1
->type
)
1383 && (TREE_INT_CST_LOW (TYPE_SIZE (f1
->type
))
1384 != TYPE_PRECISION (f1
->type
)))
1386 else if (INTEGRAL_TYPE_P (f2
->type
)
1387 && (TREE_INT_CST_LOW (TYPE_SIZE (f2
->type
))
1388 != TYPE_PRECISION (f2
->type
)))
1390 /* Stabilize the sort. */
1391 return TYPE_UID (f1
->type
) - TYPE_UID (f2
->type
);
1394 /* We want the bigger accesses first, thus the opposite operator in the next
1396 return f1
->size
> f2
->size
? -1 : 1;
1400 /* Append a name of the declaration to the name obstack. A helper function for
1404 make_fancy_decl_name (tree decl
)
1408 tree name
= DECL_NAME (decl
);
1410 obstack_grow (&name_obstack
, IDENTIFIER_POINTER (name
),
1411 IDENTIFIER_LENGTH (name
));
1414 sprintf (buffer
, "D%u", DECL_UID (decl
));
1415 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1419 /* Helper for make_fancy_name. */
1422 make_fancy_name_1 (tree expr
)
1429 make_fancy_decl_name (expr
);
1433 switch (TREE_CODE (expr
))
1436 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1437 obstack_1grow (&name_obstack
, '$');
1438 make_fancy_decl_name (TREE_OPERAND (expr
, 1));
1442 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1443 obstack_1grow (&name_obstack
, '$');
1444 /* Arrays with only one element may not have a constant as their
1446 index
= TREE_OPERAND (expr
, 1);
1447 if (TREE_CODE (index
) != INTEGER_CST
)
1449 sprintf (buffer
, HOST_WIDE_INT_PRINT_DEC
, TREE_INT_CST_LOW (index
));
1450 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1454 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1458 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1459 if (!integer_zerop (TREE_OPERAND (expr
, 1)))
1461 obstack_1grow (&name_obstack
, '$');
1462 sprintf (buffer
, HOST_WIDE_INT_PRINT_DEC
,
1463 TREE_INT_CST_LOW (TREE_OPERAND (expr
, 1)));
1464 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1471 gcc_unreachable (); /* we treat these as scalars. */
1478 /* Create a human readable name for replacement variable of ACCESS. */
1481 make_fancy_name (tree expr
)
1483 make_fancy_name_1 (expr
);
1484 obstack_1grow (&name_obstack
, '\0');
1485 return XOBFINISH (&name_obstack
, char *);
1488 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1489 EXP_TYPE at the given OFFSET. If BASE is something for which
1490 get_addr_base_and_unit_offset returns NULL, gsi must be non-NULL and is used
1491 to insert new statements either before or below the current one as specified
1492 by INSERT_AFTER. This function is not capable of handling bitfields.
1494 BASE must be either a declaration or a memory reference that has correct
1495 alignment ifformation embeded in it (e.g. a pre-existing one in SRA). */
1498 build_ref_for_offset (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1499 tree exp_type
, gimple_stmt_iterator
*gsi
,
1502 tree prev_base
= base
;
1505 HOST_WIDE_INT base_offset
;
1506 unsigned HOST_WIDE_INT misalign
;
1509 gcc_checking_assert (offset
% BITS_PER_UNIT
== 0);
1510 get_object_alignment_1 (base
, &align
, &misalign
);
1511 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
1513 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1514 offset such as array[var_index]. */
1520 gcc_checking_assert (gsi
);
1521 tmp
= make_ssa_name (build_pointer_type (TREE_TYPE (prev_base
)), NULL
);
1522 addr
= build_fold_addr_expr (unshare_expr (prev_base
));
1523 STRIP_USELESS_TYPE_CONVERSION (addr
);
1524 stmt
= gimple_build_assign (tmp
, addr
);
1525 gimple_set_location (stmt
, loc
);
1527 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
1529 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
1531 off
= build_int_cst (reference_alias_ptr_type (prev_base
),
1532 offset
/ BITS_PER_UNIT
);
1535 else if (TREE_CODE (base
) == MEM_REF
)
1537 off
= build_int_cst (TREE_TYPE (TREE_OPERAND (base
, 1)),
1538 base_offset
+ offset
/ BITS_PER_UNIT
);
1539 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1), off
);
1540 base
= unshare_expr (TREE_OPERAND (base
, 0));
1544 off
= build_int_cst (reference_alias_ptr_type (base
),
1545 base_offset
+ offset
/ BITS_PER_UNIT
);
1546 base
= build_fold_addr_expr (unshare_expr (base
));
1549 misalign
= (misalign
+ offset
) & (align
- 1);
1551 align
= (misalign
& -misalign
);
1552 if (align
< TYPE_ALIGN (exp_type
))
1553 exp_type
= build_aligned_type (exp_type
, align
);
1555 mem_ref
= fold_build2_loc (loc
, MEM_REF
, exp_type
, base
, off
);
1556 if (TREE_THIS_VOLATILE (prev_base
))
1557 TREE_THIS_VOLATILE (mem_ref
) = 1;
1558 if (TREE_SIDE_EFFECTS (prev_base
))
1559 TREE_SIDE_EFFECTS (mem_ref
) = 1;
1563 /* Construct a memory reference to a part of an aggregate BASE at the given
1564 OFFSET and of the same type as MODEL. In case this is a reference to a
1565 bit-field, the function will replicate the last component_ref of model's
1566 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1567 build_ref_for_offset. */
1570 build_ref_for_model (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1571 struct access
*model
, gimple_stmt_iterator
*gsi
,
1574 if (TREE_CODE (model
->expr
) == COMPONENT_REF
1575 && DECL_BIT_FIELD (TREE_OPERAND (model
->expr
, 1)))
1577 /* This access represents a bit-field. */
1578 tree t
, exp_type
, fld
= TREE_OPERAND (model
->expr
, 1);
1580 offset
-= int_bit_position (fld
);
1581 exp_type
= TREE_TYPE (TREE_OPERAND (model
->expr
, 0));
1582 t
= build_ref_for_offset (loc
, base
, offset
, exp_type
, gsi
, insert_after
);
1583 return fold_build3_loc (loc
, COMPONENT_REF
, TREE_TYPE (fld
), t
, fld
,
1587 return build_ref_for_offset (loc
, base
, offset
, model
->type
,
1591 /* Attempt to build a memory reference that we could but into a gimple
1592 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1593 create statements and return s NULL instead. This function also ignores
1594 alignment issues and so its results should never end up in non-debug
1598 build_debug_ref_for_model (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1599 struct access
*model
)
1601 HOST_WIDE_INT base_offset
;
1604 if (TREE_CODE (model
->expr
) == COMPONENT_REF
1605 && DECL_BIT_FIELD (TREE_OPERAND (model
->expr
, 1)))
1608 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
1611 if (TREE_CODE (base
) == MEM_REF
)
1613 off
= build_int_cst (TREE_TYPE (TREE_OPERAND (base
, 1)),
1614 base_offset
+ offset
/ BITS_PER_UNIT
);
1615 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1), off
);
1616 base
= unshare_expr (TREE_OPERAND (base
, 0));
1620 off
= build_int_cst (reference_alias_ptr_type (base
),
1621 base_offset
+ offset
/ BITS_PER_UNIT
);
1622 base
= build_fold_addr_expr (unshare_expr (base
));
1625 return fold_build2_loc (loc
, MEM_REF
, model
->type
, base
, off
);
1628 /* Construct a memory reference consisting of component_refs and array_refs to
1629 a part of an aggregate *RES (which is of type TYPE). The requested part
1630 should have type EXP_TYPE at be the given OFFSET. This function might not
1631 succeed, it returns true when it does and only then *RES points to something
1632 meaningful. This function should be used only to build expressions that we
1633 might need to present to user (e.g. in warnings). In all other situations,
1634 build_ref_for_model or build_ref_for_offset should be used instead. */
1637 build_user_friendly_ref_for_offset (tree
*res
, tree type
, HOST_WIDE_INT offset
,
1643 tree tr_size
, index
, minidx
;
1644 HOST_WIDE_INT el_size
;
1646 if (offset
== 0 && exp_type
1647 && types_compatible_p (exp_type
, type
))
1650 switch (TREE_CODE (type
))
1653 case QUAL_UNION_TYPE
:
1655 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
1657 HOST_WIDE_INT pos
, size
;
1658 tree tr_pos
, expr
, *expr_ptr
;
1660 if (TREE_CODE (fld
) != FIELD_DECL
)
1663 tr_pos
= bit_position (fld
);
1664 if (!tr_pos
|| !tree_fits_uhwi_p (tr_pos
))
1666 pos
= tree_to_uhwi (tr_pos
);
1667 gcc_assert (TREE_CODE (type
) == RECORD_TYPE
|| pos
== 0);
1668 tr_size
= DECL_SIZE (fld
);
1669 if (!tr_size
|| !tree_fits_uhwi_p (tr_size
))
1671 size
= tree_to_uhwi (tr_size
);
1677 else if (pos
> offset
|| (pos
+ size
) <= offset
)
1680 expr
= build3 (COMPONENT_REF
, TREE_TYPE (fld
), *res
, fld
,
1683 if (build_user_friendly_ref_for_offset (expr_ptr
, TREE_TYPE (fld
),
1684 offset
- pos
, exp_type
))
1693 tr_size
= TYPE_SIZE (TREE_TYPE (type
));
1694 if (!tr_size
|| !tree_fits_uhwi_p (tr_size
))
1696 el_size
= tree_to_uhwi (tr_size
);
1698 minidx
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
1699 if (TREE_CODE (minidx
) != INTEGER_CST
|| el_size
== 0)
1701 index
= build_int_cst (TYPE_DOMAIN (type
), offset
/ el_size
);
1702 if (!integer_zerop (minidx
))
1703 index
= int_const_binop (PLUS_EXPR
, index
, minidx
);
1704 *res
= build4 (ARRAY_REF
, TREE_TYPE (type
), *res
, index
,
1705 NULL_TREE
, NULL_TREE
);
1706 offset
= offset
% el_size
;
1707 type
= TREE_TYPE (type
);
1722 /* Return true iff TYPE is stdarg va_list type. */
1725 is_va_list_type (tree type
)
1727 return TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (va_list_type_node
);
1730 /* Print message to dump file why a variable was rejected. */
1733 reject (tree var
, const char *msg
)
1735 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1737 fprintf (dump_file
, "Rejected (%d): %s: ", DECL_UID (var
), msg
);
1738 print_generic_expr (dump_file
, var
, 0);
1739 fprintf (dump_file
, "\n");
1743 /* Return true if VAR is a candidate for SRA. */
1746 maybe_add_sra_candidate (tree var
)
1748 tree type
= TREE_TYPE (var
);
1752 if (!AGGREGATE_TYPE_P (type
))
1754 reject (var
, "not aggregate");
1757 if (needs_to_live_in_memory (var
))
1759 reject (var
, "needs to live in memory");
1762 if (TREE_THIS_VOLATILE (var
))
1764 reject (var
, "is volatile");
1767 if (!COMPLETE_TYPE_P (type
))
1769 reject (var
, "has incomplete type");
1772 if (!tree_fits_uhwi_p (TYPE_SIZE (type
)))
1774 reject (var
, "type size not fixed");
1777 if (tree_to_uhwi (TYPE_SIZE (type
)) == 0)
1779 reject (var
, "type size is zero");
1782 if (type_internals_preclude_sra_p (type
, &msg
))
1787 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1788 we also want to schedule it rather late. Thus we ignore it in
1790 (sra_mode
== SRA_MODE_EARLY_INTRA
1791 && is_va_list_type (type
)))
1793 reject (var
, "is va_list");
1797 bitmap_set_bit (candidate_bitmap
, DECL_UID (var
));
1798 slot
= candidates
.find_slot_with_hash (var
, DECL_UID (var
), INSERT
);
1801 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1803 fprintf (dump_file
, "Candidate (%d): ", DECL_UID (var
));
1804 print_generic_expr (dump_file
, var
, 0);
1805 fprintf (dump_file
, "\n");
1811 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1812 those with type which is suitable for scalarization. */
1815 find_var_candidates (void)
1821 for (parm
= DECL_ARGUMENTS (current_function_decl
);
1823 parm
= DECL_CHAIN (parm
))
1824 ret
|= maybe_add_sra_candidate (parm
);
1826 FOR_EACH_LOCAL_DECL (cfun
, i
, var
)
1828 if (TREE_CODE (var
) != VAR_DECL
)
1831 ret
|= maybe_add_sra_candidate (var
);
1837 /* Sort all accesses for the given variable, check for partial overlaps and
1838 return NULL if there are any. If there are none, pick a representative for
1839 each combination of offset and size and create a linked list out of them.
1840 Return the pointer to the first representative and make sure it is the first
1841 one in the vector of accesses. */
1843 static struct access
*
1844 sort_and_splice_var_accesses (tree var
)
1846 int i
, j
, access_count
;
1847 struct access
*res
, **prev_acc_ptr
= &res
;
1848 vec
<access_p
> *access_vec
;
1850 HOST_WIDE_INT low
= -1, high
= 0;
1852 access_vec
= get_base_access_vector (var
);
1855 access_count
= access_vec
->length ();
1857 /* Sort by <OFFSET, SIZE>. */
1858 access_vec
->qsort (compare_access_positions
);
1861 while (i
< access_count
)
1863 struct access
*access
= (*access_vec
)[i
];
1864 bool grp_write
= access
->write
;
1865 bool grp_read
= !access
->write
;
1866 bool grp_scalar_write
= access
->write
1867 && is_gimple_reg_type (access
->type
);
1868 bool grp_scalar_read
= !access
->write
1869 && is_gimple_reg_type (access
->type
);
1870 bool grp_assignment_read
= access
->grp_assignment_read
;
1871 bool grp_assignment_write
= access
->grp_assignment_write
;
1872 bool multiple_scalar_reads
= false;
1873 bool total_scalarization
= access
->grp_total_scalarization
;
1874 bool grp_partial_lhs
= access
->grp_partial_lhs
;
1875 bool first_scalar
= is_gimple_reg_type (access
->type
);
1876 bool unscalarizable_region
= access
->grp_unscalarizable_region
;
1878 if (first
|| access
->offset
>= high
)
1881 low
= access
->offset
;
1882 high
= access
->offset
+ access
->size
;
1884 else if (access
->offset
> low
&& access
->offset
+ access
->size
> high
)
1887 gcc_assert (access
->offset
>= low
1888 && access
->offset
+ access
->size
<= high
);
1891 while (j
< access_count
)
1893 struct access
*ac2
= (*access_vec
)[j
];
1894 if (ac2
->offset
!= access
->offset
|| ac2
->size
!= access
->size
)
1899 grp_scalar_write
= (grp_scalar_write
1900 || is_gimple_reg_type (ac2
->type
));
1905 if (is_gimple_reg_type (ac2
->type
))
1907 if (grp_scalar_read
)
1908 multiple_scalar_reads
= true;
1910 grp_scalar_read
= true;
1913 grp_assignment_read
|= ac2
->grp_assignment_read
;
1914 grp_assignment_write
|= ac2
->grp_assignment_write
;
1915 grp_partial_lhs
|= ac2
->grp_partial_lhs
;
1916 unscalarizable_region
|= ac2
->grp_unscalarizable_region
;
1917 total_scalarization
|= ac2
->grp_total_scalarization
;
1918 relink_to_new_repr (access
, ac2
);
1920 /* If there are both aggregate-type and scalar-type accesses with
1921 this combination of size and offset, the comparison function
1922 should have put the scalars first. */
1923 gcc_assert (first_scalar
|| !is_gimple_reg_type (ac2
->type
));
1924 ac2
->group_representative
= access
;
1930 access
->group_representative
= access
;
1931 access
->grp_write
= grp_write
;
1932 access
->grp_read
= grp_read
;
1933 access
->grp_scalar_read
= grp_scalar_read
;
1934 access
->grp_scalar_write
= grp_scalar_write
;
1935 access
->grp_assignment_read
= grp_assignment_read
;
1936 access
->grp_assignment_write
= grp_assignment_write
;
1937 access
->grp_hint
= multiple_scalar_reads
|| total_scalarization
;
1938 access
->grp_total_scalarization
= total_scalarization
;
1939 access
->grp_partial_lhs
= grp_partial_lhs
;
1940 access
->grp_unscalarizable_region
= unscalarizable_region
;
1941 if (access
->first_link
)
1942 add_access_to_work_queue (access
);
1944 *prev_acc_ptr
= access
;
1945 prev_acc_ptr
= &access
->next_grp
;
1948 gcc_assert (res
== (*access_vec
)[0]);
1952 /* Create a variable for the given ACCESS which determines the type, name and a
1953 few other properties. Return the variable declaration and store it also to
1954 ACCESS->replacement. */
1957 create_access_replacement (struct access
*access
)
1961 if (access
->grp_to_be_debug_replaced
)
1963 repl
= create_tmp_var_raw (access
->type
, NULL
);
1964 DECL_CONTEXT (repl
) = current_function_decl
;
1967 repl
= create_tmp_var (access
->type
, "SR");
1968 if (TREE_CODE (access
->type
) == COMPLEX_TYPE
1969 || TREE_CODE (access
->type
) == VECTOR_TYPE
)
1971 if (!access
->grp_partial_lhs
)
1972 DECL_GIMPLE_REG_P (repl
) = 1;
1974 else if (access
->grp_partial_lhs
1975 && is_gimple_reg_type (access
->type
))
1976 TREE_ADDRESSABLE (repl
) = 1;
1978 DECL_SOURCE_LOCATION (repl
) = DECL_SOURCE_LOCATION (access
->base
);
1979 DECL_ARTIFICIAL (repl
) = 1;
1980 DECL_IGNORED_P (repl
) = DECL_IGNORED_P (access
->base
);
1982 if (DECL_NAME (access
->base
)
1983 && !DECL_IGNORED_P (access
->base
)
1984 && !DECL_ARTIFICIAL (access
->base
))
1986 char *pretty_name
= make_fancy_name (access
->expr
);
1987 tree debug_expr
= unshare_expr_without_location (access
->expr
), d
;
1990 DECL_NAME (repl
) = get_identifier (pretty_name
);
1991 obstack_free (&name_obstack
, pretty_name
);
1993 /* Get rid of any SSA_NAMEs embedded in debug_expr,
1994 as DECL_DEBUG_EXPR isn't considered when looking for still
1995 used SSA_NAMEs and thus they could be freed. All debug info
1996 generation cares is whether something is constant or variable
1997 and that get_ref_base_and_extent works properly on the
1998 expression. It cannot handle accesses at a non-constant offset
1999 though, so just give up in those cases. */
2000 for (d
= debug_expr
;
2001 !fail
&& (handled_component_p (d
) || TREE_CODE (d
) == MEM_REF
);
2002 d
= TREE_OPERAND (d
, 0))
2003 switch (TREE_CODE (d
))
2006 case ARRAY_RANGE_REF
:
2007 if (TREE_OPERAND (d
, 1)
2008 && TREE_CODE (TREE_OPERAND (d
, 1)) != INTEGER_CST
)
2010 if (TREE_OPERAND (d
, 3)
2011 && TREE_CODE (TREE_OPERAND (d
, 3)) != INTEGER_CST
)
2015 if (TREE_OPERAND (d
, 2)
2016 && TREE_CODE (TREE_OPERAND (d
, 2)) != INTEGER_CST
)
2020 if (TREE_CODE (TREE_OPERAND (d
, 0)) != ADDR_EXPR
)
2023 d
= TREE_OPERAND (d
, 0);
2030 SET_DECL_DEBUG_EXPR (repl
, debug_expr
);
2031 DECL_HAS_DEBUG_EXPR_P (repl
) = 1;
2033 if (access
->grp_no_warning
)
2034 TREE_NO_WARNING (repl
) = 1;
2036 TREE_NO_WARNING (repl
) = TREE_NO_WARNING (access
->base
);
2039 TREE_NO_WARNING (repl
) = 1;
2043 if (access
->grp_to_be_debug_replaced
)
2045 fprintf (dump_file
, "Created a debug-only replacement for ");
2046 print_generic_expr (dump_file
, access
->base
, 0);
2047 fprintf (dump_file
, " offset: %u, size: %u\n",
2048 (unsigned) access
->offset
, (unsigned) access
->size
);
2052 fprintf (dump_file
, "Created a replacement for ");
2053 print_generic_expr (dump_file
, access
->base
, 0);
2054 fprintf (dump_file
, " offset: %u, size: %u: ",
2055 (unsigned) access
->offset
, (unsigned) access
->size
);
2056 print_generic_expr (dump_file
, repl
, 0);
2057 fprintf (dump_file
, "\n");
2060 sra_stats
.replacements
++;
2065 /* Return ACCESS scalar replacement, create it if it does not exist yet. */
2068 get_access_replacement (struct access
*access
)
2070 gcc_checking_assert (access
->replacement_decl
);
2071 return access
->replacement_decl
;
2075 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2076 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2077 to it is not "within" the root. Return false iff some accesses partially
2081 build_access_subtree (struct access
**access
)
2083 struct access
*root
= *access
, *last_child
= NULL
;
2084 HOST_WIDE_INT limit
= root
->offset
+ root
->size
;
2086 *access
= (*access
)->next_grp
;
2087 while (*access
&& (*access
)->offset
+ (*access
)->size
<= limit
)
2090 root
->first_child
= *access
;
2092 last_child
->next_sibling
= *access
;
2093 last_child
= *access
;
2095 if (!build_access_subtree (access
))
2099 if (*access
&& (*access
)->offset
< limit
)
2105 /* Build a tree of access representatives, ACCESS is the pointer to the first
2106 one, others are linked in a list by the next_grp field. Return false iff
2107 some accesses partially overlap. */
2110 build_access_trees (struct access
*access
)
2114 struct access
*root
= access
;
2116 if (!build_access_subtree (&access
))
2118 root
->next_grp
= access
;
2123 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2127 expr_with_var_bounded_array_refs_p (tree expr
)
2129 while (handled_component_p (expr
))
2131 if (TREE_CODE (expr
) == ARRAY_REF
2132 && !tree_fits_shwi_p (array_ref_low_bound (expr
)))
2134 expr
= TREE_OPERAND (expr
, 0);
2139 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2140 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2141 sorts of access flags appropriately along the way, notably always set
2142 grp_read and grp_assign_read according to MARK_READ and grp_write when
2145 Creating a replacement for a scalar access is considered beneficial if its
2146 grp_hint is set (this means we are either attempting total scalarization or
2147 there is more than one direct read access) or according to the following
2150 Access written to through a scalar type (once or more times)
2152 | Written to in an assignment statement
2154 | | Access read as scalar _once_
2156 | | | Read in an assignment statement
2158 | | | | Scalarize Comment
2159 -----------------------------------------------------------------------------
2160 0 0 0 0 No access for the scalar
2161 0 0 0 1 No access for the scalar
2162 0 0 1 0 No Single read - won't help
2163 0 0 1 1 No The same case
2164 0 1 0 0 No access for the scalar
2165 0 1 0 1 No access for the scalar
2166 0 1 1 0 Yes s = *g; return s.i;
2167 0 1 1 1 Yes The same case as above
2168 1 0 0 0 No Won't help
2169 1 0 0 1 Yes s.i = 1; *g = s;
2170 1 0 1 0 Yes s.i = 5; g = s.i;
2171 1 0 1 1 Yes The same case as above
2172 1 1 0 0 No Won't help.
2173 1 1 0 1 Yes s.i = 1; *g = s;
2174 1 1 1 0 Yes s = *g; return s.i;
2175 1 1 1 1 Yes Any of the above yeses */
2178 analyze_access_subtree (struct access
*root
, struct access
*parent
,
2179 bool allow_replacements
)
2181 struct access
*child
;
2182 HOST_WIDE_INT limit
= root
->offset
+ root
->size
;
2183 HOST_WIDE_INT covered_to
= root
->offset
;
2184 bool scalar
= is_gimple_reg_type (root
->type
);
2185 bool hole
= false, sth_created
= false;
2189 if (parent
->grp_read
)
2191 if (parent
->grp_assignment_read
)
2192 root
->grp_assignment_read
= 1;
2193 if (parent
->grp_write
)
2194 root
->grp_write
= 1;
2195 if (parent
->grp_assignment_write
)
2196 root
->grp_assignment_write
= 1;
2197 if (parent
->grp_total_scalarization
)
2198 root
->grp_total_scalarization
= 1;
2201 if (root
->grp_unscalarizable_region
)
2202 allow_replacements
= false;
2204 if (allow_replacements
&& expr_with_var_bounded_array_refs_p (root
->expr
))
2205 allow_replacements
= false;
2207 for (child
= root
->first_child
; child
; child
= child
->next_sibling
)
2209 hole
|= covered_to
< child
->offset
;
2210 sth_created
|= analyze_access_subtree (child
, root
,
2211 allow_replacements
&& !scalar
);
2213 root
->grp_unscalarized_data
|= child
->grp_unscalarized_data
;
2214 root
->grp_total_scalarization
&= child
->grp_total_scalarization
;
2215 if (child
->grp_covered
)
2216 covered_to
+= child
->size
;
2221 if (allow_replacements
&& scalar
&& !root
->first_child
2223 || ((root
->grp_scalar_read
|| root
->grp_assignment_read
)
2224 && (root
->grp_scalar_write
|| root
->grp_assignment_write
))))
2226 /* Always create access replacements that cover the whole access.
2227 For integral types this means the precision has to match.
2228 Avoid assumptions based on the integral type kind, too. */
2229 if (INTEGRAL_TYPE_P (root
->type
)
2230 && (TREE_CODE (root
->type
) != INTEGER_TYPE
2231 || TYPE_PRECISION (root
->type
) != root
->size
)
2232 /* But leave bitfield accesses alone. */
2233 && (TREE_CODE (root
->expr
) != COMPONENT_REF
2234 || !DECL_BIT_FIELD (TREE_OPERAND (root
->expr
, 1))))
2236 tree rt
= root
->type
;
2237 gcc_assert ((root
->offset
% BITS_PER_UNIT
) == 0
2238 && (root
->size
% BITS_PER_UNIT
) == 0);
2239 root
->type
= build_nonstandard_integer_type (root
->size
,
2240 TYPE_UNSIGNED (rt
));
2241 root
->expr
= build_ref_for_offset (UNKNOWN_LOCATION
,
2242 root
->base
, root
->offset
,
2243 root
->type
, NULL
, false);
2245 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2247 fprintf (dump_file
, "Changing the type of a replacement for ");
2248 print_generic_expr (dump_file
, root
->base
, 0);
2249 fprintf (dump_file
, " offset: %u, size: %u ",
2250 (unsigned) root
->offset
, (unsigned) root
->size
);
2251 fprintf (dump_file
, " to an integer.\n");
2255 root
->grp_to_be_replaced
= 1;
2256 root
->replacement_decl
= create_access_replacement (root
);
2262 if (allow_replacements
2263 && scalar
&& !root
->first_child
2264 && (root
->grp_scalar_write
|| root
->grp_assignment_write
)
2265 && !bitmap_bit_p (cannot_scalarize_away_bitmap
,
2266 DECL_UID (root
->base
)))
2268 gcc_checking_assert (!root
->grp_scalar_read
2269 && !root
->grp_assignment_read
);
2271 if (MAY_HAVE_DEBUG_STMTS
)
2273 root
->grp_to_be_debug_replaced
= 1;
2274 root
->replacement_decl
= create_access_replacement (root
);
2278 if (covered_to
< limit
)
2281 root
->grp_total_scalarization
= 0;
2284 if (!hole
|| root
->grp_total_scalarization
)
2285 root
->grp_covered
= 1;
2286 else if (root
->grp_write
|| TREE_CODE (root
->base
) == PARM_DECL
)
2287 root
->grp_unscalarized_data
= 1; /* not covered and written to */
2291 /* Analyze all access trees linked by next_grp by the means of
2292 analyze_access_subtree. */
2294 analyze_access_trees (struct access
*access
)
2300 if (analyze_access_subtree (access
, NULL
, true))
2302 access
= access
->next_grp
;
2308 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2309 SIZE would conflict with an already existing one. If exactly such a child
2310 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2313 child_would_conflict_in_lacc (struct access
*lacc
, HOST_WIDE_INT norm_offset
,
2314 HOST_WIDE_INT size
, struct access
**exact_match
)
2316 struct access
*child
;
2318 for (child
= lacc
->first_child
; child
; child
= child
->next_sibling
)
2320 if (child
->offset
== norm_offset
&& child
->size
== size
)
2322 *exact_match
= child
;
2326 if (child
->offset
< norm_offset
+ size
2327 && child
->offset
+ child
->size
> norm_offset
)
2334 /* Create a new child access of PARENT, with all properties just like MODEL
2335 except for its offset and with its grp_write false and grp_read true.
2336 Return the new access or NULL if it cannot be created. Note that this access
2337 is created long after all splicing and sorting, it's not located in any
2338 access vector and is automatically a representative of its group. */
2340 static struct access
*
2341 create_artificial_child_access (struct access
*parent
, struct access
*model
,
2342 HOST_WIDE_INT new_offset
)
2344 struct access
*access
;
2345 struct access
**child
;
2346 tree expr
= parent
->base
;
2348 gcc_assert (!model
->grp_unscalarizable_region
);
2350 access
= (struct access
*) pool_alloc (access_pool
);
2351 memset (access
, 0, sizeof (struct access
));
2352 if (!build_user_friendly_ref_for_offset (&expr
, TREE_TYPE (expr
), new_offset
,
2355 access
->grp_no_warning
= true;
2356 expr
= build_ref_for_model (EXPR_LOCATION (parent
->base
), parent
->base
,
2357 new_offset
, model
, NULL
, false);
2360 access
->base
= parent
->base
;
2361 access
->expr
= expr
;
2362 access
->offset
= new_offset
;
2363 access
->size
= model
->size
;
2364 access
->type
= model
->type
;
2365 access
->grp_write
= true;
2366 access
->grp_read
= false;
2368 child
= &parent
->first_child
;
2369 while (*child
&& (*child
)->offset
< new_offset
)
2370 child
= &(*child
)->next_sibling
;
2372 access
->next_sibling
= *child
;
2379 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
2380 true if any new subaccess was created. Additionally, if RACC is a scalar
2381 access but LACC is not, change the type of the latter, if possible. */
2384 propagate_subaccesses_across_link (struct access
*lacc
, struct access
*racc
)
2386 struct access
*rchild
;
2387 HOST_WIDE_INT norm_delta
= lacc
->offset
- racc
->offset
;
2390 if (is_gimple_reg_type (lacc
->type
)
2391 || lacc
->grp_unscalarizable_region
2392 || racc
->grp_unscalarizable_region
)
2395 if (is_gimple_reg_type (racc
->type
))
2397 if (!lacc
->first_child
&& !racc
->first_child
)
2399 tree t
= lacc
->base
;
2401 lacc
->type
= racc
->type
;
2402 if (build_user_friendly_ref_for_offset (&t
, TREE_TYPE (t
),
2403 lacc
->offset
, racc
->type
))
2407 lacc
->expr
= build_ref_for_model (EXPR_LOCATION (lacc
->base
),
2408 lacc
->base
, lacc
->offset
,
2410 lacc
->grp_no_warning
= true;
2416 for (rchild
= racc
->first_child
; rchild
; rchild
= rchild
->next_sibling
)
2418 struct access
*new_acc
= NULL
;
2419 HOST_WIDE_INT norm_offset
= rchild
->offset
+ norm_delta
;
2421 if (rchild
->grp_unscalarizable_region
)
2424 if (child_would_conflict_in_lacc (lacc
, norm_offset
, rchild
->size
,
2429 rchild
->grp_hint
= 1;
2430 new_acc
->grp_hint
|= new_acc
->grp_read
;
2431 if (rchild
->first_child
)
2432 ret
|= propagate_subaccesses_across_link (new_acc
, rchild
);
2437 rchild
->grp_hint
= 1;
2438 new_acc
= create_artificial_child_access (lacc
, rchild
, norm_offset
);
2442 if (racc
->first_child
)
2443 propagate_subaccesses_across_link (new_acc
, rchild
);
2450 /* Propagate all subaccesses across assignment links. */
2453 propagate_all_subaccesses (void)
2455 while (work_queue_head
)
2457 struct access
*racc
= pop_access_from_work_queue ();
2458 struct assign_link
*link
;
2460 gcc_assert (racc
->first_link
);
2462 for (link
= racc
->first_link
; link
; link
= link
->next
)
2464 struct access
*lacc
= link
->lacc
;
2466 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (lacc
->base
)))
2468 lacc
= lacc
->group_representative
;
2469 if (propagate_subaccesses_across_link (lacc
, racc
)
2470 && lacc
->first_link
)
2471 add_access_to_work_queue (lacc
);
2476 /* Go through all accesses collected throughout the (intraprocedural) analysis
2477 stage, exclude overlapping ones, identify representatives and build trees
2478 out of them, making decisions about scalarization on the way. Return true
2479 iff there are any to-be-scalarized variables after this stage. */
2482 analyze_all_variable_accesses (void)
2485 bitmap tmp
= BITMAP_ALLOC (NULL
);
2487 unsigned i
, max_total_scalarization_size
;
2489 max_total_scalarization_size
= UNITS_PER_WORD
* BITS_PER_UNIT
2490 * MOVE_RATIO (optimize_function_for_speed_p (cfun
));
2492 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap
, 0, i
, bi
)
2493 if (bitmap_bit_p (should_scalarize_away_bitmap
, i
)
2494 && !bitmap_bit_p (cannot_scalarize_away_bitmap
, i
))
2496 tree var
= candidate (i
);
2498 if (TREE_CODE (var
) == VAR_DECL
2499 && type_consists_of_records_p (TREE_TYPE (var
)))
2501 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var
)))
2502 <= max_total_scalarization_size
)
2504 completely_scalarize_var (var
);
2505 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2507 fprintf (dump_file
, "Will attempt to totally scalarize ");
2508 print_generic_expr (dump_file
, var
, 0);
2509 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (var
));
2512 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2514 fprintf (dump_file
, "Too big to totally scalarize: ");
2515 print_generic_expr (dump_file
, var
, 0);
2516 fprintf (dump_file
, " (UID: %u)\n", DECL_UID (var
));
2521 bitmap_copy (tmp
, candidate_bitmap
);
2522 EXECUTE_IF_SET_IN_BITMAP (tmp
, 0, i
, bi
)
2524 tree var
= candidate (i
);
2525 struct access
*access
;
2527 access
= sort_and_splice_var_accesses (var
);
2528 if (!access
|| !build_access_trees (access
))
2529 disqualify_candidate (var
,
2530 "No or inhibitingly overlapping accesses.");
2533 propagate_all_subaccesses ();
2535 bitmap_copy (tmp
, candidate_bitmap
);
2536 EXECUTE_IF_SET_IN_BITMAP (tmp
, 0, i
, bi
)
2538 tree var
= candidate (i
);
2539 struct access
*access
= get_first_repr_for_decl (var
);
2541 if (analyze_access_trees (access
))
2544 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2546 fprintf (dump_file
, "\nAccess trees for ");
2547 print_generic_expr (dump_file
, var
, 0);
2548 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (var
));
2549 dump_access_tree (dump_file
, access
);
2550 fprintf (dump_file
, "\n");
2554 disqualify_candidate (var
, "No scalar replacements to be created.");
2561 statistics_counter_event (cfun
, "Scalarized aggregates", res
);
2568 /* Generate statements copying scalar replacements of accesses within a subtree
2569 into or out of AGG. ACCESS, all its children, siblings and their children
2570 are to be processed. AGG is an aggregate type expression (can be a
2571 declaration but does not have to be, it can for example also be a mem_ref or
2572 a series of handled components). TOP_OFFSET is the offset of the processed
2573 subtree which has to be subtracted from offsets of individual accesses to
2574 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2575 replacements in the interval <start_offset, start_offset + chunk_size>,
2576 otherwise copy all. GSI is a statement iterator used to place the new
2577 statements. WRITE should be true when the statements should write from AGG
2578 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2579 statements will be added after the current statement in GSI, they will be
2580 added before the statement otherwise. */
2583 generate_subtree_copies (struct access
*access
, tree agg
,
2584 HOST_WIDE_INT top_offset
,
2585 HOST_WIDE_INT start_offset
, HOST_WIDE_INT chunk_size
,
2586 gimple_stmt_iterator
*gsi
, bool write
,
2587 bool insert_after
, location_t loc
)
2591 if (chunk_size
&& access
->offset
>= start_offset
+ chunk_size
)
2594 if (access
->grp_to_be_replaced
2596 || access
->offset
+ access
->size
> start_offset
))
2598 tree expr
, repl
= get_access_replacement (access
);
2601 expr
= build_ref_for_model (loc
, agg
, access
->offset
- top_offset
,
2602 access
, gsi
, insert_after
);
2606 if (access
->grp_partial_lhs
)
2607 expr
= force_gimple_operand_gsi (gsi
, expr
, true, NULL_TREE
,
2609 insert_after
? GSI_NEW_STMT
2611 stmt
= gimple_build_assign (repl
, expr
);
2615 TREE_NO_WARNING (repl
) = 1;
2616 if (access
->grp_partial_lhs
)
2617 repl
= force_gimple_operand_gsi (gsi
, repl
, true, NULL_TREE
,
2619 insert_after
? GSI_NEW_STMT
2621 stmt
= gimple_build_assign (expr
, repl
);
2623 gimple_set_location (stmt
, loc
);
2626 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2628 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2630 sra_stats
.subtree_copies
++;
2633 && access
->grp_to_be_debug_replaced
2635 || access
->offset
+ access
->size
> start_offset
))
2638 tree drhs
= build_debug_ref_for_model (loc
, agg
,
2639 access
->offset
- top_offset
,
2641 ds
= gimple_build_debug_bind (get_access_replacement (access
),
2642 drhs
, gsi_stmt (*gsi
));
2644 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2646 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
2649 if (access
->first_child
)
2650 generate_subtree_copies (access
->first_child
, agg
, top_offset
,
2651 start_offset
, chunk_size
, gsi
,
2652 write
, insert_after
, loc
);
2654 access
= access
->next_sibling
;
2659 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2660 the root of the subtree to be processed. GSI is the statement iterator used
2661 for inserting statements which are added after the current statement if
2662 INSERT_AFTER is true or before it otherwise. */
2665 init_subtree_with_zero (struct access
*access
, gimple_stmt_iterator
*gsi
,
2666 bool insert_after
, location_t loc
)
2669 struct access
*child
;
2671 if (access
->grp_to_be_replaced
)
2675 stmt
= gimple_build_assign (get_access_replacement (access
),
2676 build_zero_cst (access
->type
));
2678 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2680 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2682 gimple_set_location (stmt
, loc
);
2684 else if (access
->grp_to_be_debug_replaced
)
2686 gimple ds
= gimple_build_debug_bind (get_access_replacement (access
),
2687 build_zero_cst (access
->type
),
2690 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2692 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
2695 for (child
= access
->first_child
; child
; child
= child
->next_sibling
)
2696 init_subtree_with_zero (child
, gsi
, insert_after
, loc
);
2699 /* Search for an access representative for the given expression EXPR and
2700 return it or NULL if it cannot be found. */
2702 static struct access
*
2703 get_access_for_expr (tree expr
)
2705 HOST_WIDE_INT offset
, size
, max_size
;
2708 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2709 a different size than the size of its argument and we need the latter
2711 if (TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
2712 expr
= TREE_OPERAND (expr
, 0);
2714 base
= get_ref_base_and_extent (expr
, &offset
, &size
, &max_size
);
2715 if (max_size
== -1 || !DECL_P (base
))
2718 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (base
)))
2721 return get_var_base_offset_size_access (base
, offset
, max_size
);
2724 /* Replace the expression EXPR with a scalar replacement if there is one and
2725 generate other statements to do type conversion or subtree copying if
2726 necessary. GSI is used to place newly created statements, WRITE is true if
2727 the expression is being written to (it is on a LHS of a statement or output
2728 in an assembly statement). */
2731 sra_modify_expr (tree
*expr
, gimple_stmt_iterator
*gsi
, bool write
)
2734 struct access
*access
;
2737 if (TREE_CODE (*expr
) == BIT_FIELD_REF
)
2740 expr
= &TREE_OPERAND (*expr
, 0);
2745 if (TREE_CODE (*expr
) == REALPART_EXPR
|| TREE_CODE (*expr
) == IMAGPART_EXPR
)
2746 expr
= &TREE_OPERAND (*expr
, 0);
2747 access
= get_access_for_expr (*expr
);
2750 type
= TREE_TYPE (*expr
);
2752 loc
= gimple_location (gsi_stmt (*gsi
));
2753 if (access
->grp_to_be_replaced
)
2755 tree repl
= get_access_replacement (access
);
2756 /* If we replace a non-register typed access simply use the original
2757 access expression to extract the scalar component afterwards.
2758 This happens if scalarizing a function return value or parameter
2759 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2760 gcc.c-torture/compile/20011217-1.c.
2762 We also want to use this when accessing a complex or vector which can
2763 be accessed as a different type too, potentially creating a need for
2764 type conversion (see PR42196) and when scalarized unions are involved
2765 in assembler statements (see PR42398). */
2766 if (!useless_type_conversion_p (type
, access
->type
))
2770 ref
= build_ref_for_model (loc
, access
->base
, access
->offset
, access
,
2777 if (access
->grp_partial_lhs
)
2778 ref
= force_gimple_operand_gsi (gsi
, ref
, true, NULL_TREE
,
2779 false, GSI_NEW_STMT
);
2780 stmt
= gimple_build_assign (repl
, ref
);
2781 gimple_set_location (stmt
, loc
);
2782 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2788 if (access
->grp_partial_lhs
)
2789 repl
= force_gimple_operand_gsi (gsi
, repl
, true, NULL_TREE
,
2790 true, GSI_SAME_STMT
);
2791 stmt
= gimple_build_assign (ref
, repl
);
2792 gimple_set_location (stmt
, loc
);
2793 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2800 else if (write
&& access
->grp_to_be_debug_replaced
)
2802 gimple ds
= gimple_build_debug_bind (get_access_replacement (access
),
2805 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2808 if (access
->first_child
)
2810 HOST_WIDE_INT start_offset
, chunk_size
;
2812 && tree_fits_uhwi_p (TREE_OPERAND (bfr
, 1))
2813 && tree_fits_uhwi_p (TREE_OPERAND (bfr
, 2)))
2815 chunk_size
= tree_to_uhwi (TREE_OPERAND (bfr
, 1));
2816 start_offset
= access
->offset
2817 + tree_to_uhwi (TREE_OPERAND (bfr
, 2));
2820 start_offset
= chunk_size
= 0;
2822 generate_subtree_copies (access
->first_child
, access
->base
, 0,
2823 start_offset
, chunk_size
, gsi
, write
, write
,
2829 /* Where scalar replacements of the RHS have been written to when a replacement
2830 of a LHS of an assigments cannot be direclty loaded from a replacement of
2832 enum unscalarized_data_handling
{ SRA_UDH_NONE
, /* Nothing done so far. */
2833 SRA_UDH_RIGHT
, /* Data flushed to the RHS. */
2834 SRA_UDH_LEFT
}; /* Data flushed to the LHS. */
2836 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2837 base aggregate if there are unscalarized data or directly to LHS of the
2838 statement that is pointed to by GSI otherwise. */
2840 static enum unscalarized_data_handling
2841 handle_unscalarized_data_in_subtree (struct access
*top_racc
,
2842 gimple_stmt_iterator
*gsi
)
2844 if (top_racc
->grp_unscalarized_data
)
2846 generate_subtree_copies (top_racc
->first_child
, top_racc
->base
, 0, 0, 0,
2848 gimple_location (gsi_stmt (*gsi
)));
2849 return SRA_UDH_RIGHT
;
2853 tree lhs
= gimple_assign_lhs (gsi_stmt (*gsi
));
2854 generate_subtree_copies (top_racc
->first_child
, lhs
, top_racc
->offset
,
2855 0, 0, gsi
, false, false,
2856 gimple_location (gsi_stmt (*gsi
)));
2857 return SRA_UDH_LEFT
;
2862 /* Try to generate statements to load all sub-replacements in an access subtree
2863 formed by children of LACC from scalar replacements in the TOP_RACC subtree.
2864 If that is not possible, refresh the TOP_RACC base aggregate and load the
2865 accesses from it. LEFT_OFFSET is the offset of the left whole subtree being
2866 copied. NEW_GSI is stmt iterator used for statement insertions after the
2867 original assignment, OLD_GSI is used to insert statements before the
2868 assignment. *REFRESHED keeps the information whether we have needed to
2869 refresh replacements of the LHS and from which side of the assignments this
2873 load_assign_lhs_subreplacements (struct access
*lacc
, struct access
*top_racc
,
2874 HOST_WIDE_INT left_offset
,
2875 gimple_stmt_iterator
*old_gsi
,
2876 gimple_stmt_iterator
*new_gsi
,
2877 enum unscalarized_data_handling
*refreshed
)
2879 location_t loc
= gimple_location (gsi_stmt (*old_gsi
));
2880 for (lacc
= lacc
->first_child
; lacc
; lacc
= lacc
->next_sibling
)
2882 HOST_WIDE_INT offset
= lacc
->offset
- left_offset
+ top_racc
->offset
;
2884 if (lacc
->grp_to_be_replaced
)
2886 struct access
*racc
;
2890 racc
= find_access_in_subtree (top_racc
, offset
, lacc
->size
);
2891 if (racc
&& racc
->grp_to_be_replaced
)
2893 rhs
= get_access_replacement (racc
);
2894 if (!useless_type_conversion_p (lacc
->type
, racc
->type
))
2895 rhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, lacc
->type
, rhs
);
2897 if (racc
->grp_partial_lhs
&& lacc
->grp_partial_lhs
)
2898 rhs
= force_gimple_operand_gsi (old_gsi
, rhs
, true, NULL_TREE
,
2899 true, GSI_SAME_STMT
);
2903 /* No suitable access on the right hand side, need to load from
2904 the aggregate. See if we have to update it first... */
2905 if (*refreshed
== SRA_UDH_NONE
)
2906 *refreshed
= handle_unscalarized_data_in_subtree (top_racc
,
2909 if (*refreshed
== SRA_UDH_LEFT
)
2910 rhs
= build_ref_for_model (loc
, lacc
->base
, lacc
->offset
, lacc
,
2913 rhs
= build_ref_for_model (loc
, top_racc
->base
, offset
, lacc
,
2915 if (lacc
->grp_partial_lhs
)
2916 rhs
= force_gimple_operand_gsi (new_gsi
, rhs
, true, NULL_TREE
,
2917 false, GSI_NEW_STMT
);
2920 stmt
= gimple_build_assign (get_access_replacement (lacc
), rhs
);
2921 gsi_insert_after (new_gsi
, stmt
, GSI_NEW_STMT
);
2922 gimple_set_location (stmt
, loc
);
2924 sra_stats
.subreplacements
++;
2928 if (*refreshed
== SRA_UDH_NONE
2929 && lacc
->grp_read
&& !lacc
->grp_covered
)
2930 *refreshed
= handle_unscalarized_data_in_subtree (top_racc
,
2932 if (lacc
&& lacc
->grp_to_be_debug_replaced
)
2936 struct access
*racc
= find_access_in_subtree (top_racc
, offset
,
2939 if (racc
&& racc
->grp_to_be_replaced
)
2941 if (racc
->grp_write
)
2942 drhs
= get_access_replacement (racc
);
2946 else if (*refreshed
== SRA_UDH_LEFT
)
2947 drhs
= build_debug_ref_for_model (loc
, lacc
->base
, lacc
->offset
,
2949 else if (*refreshed
== SRA_UDH_RIGHT
)
2950 drhs
= build_debug_ref_for_model (loc
, top_racc
->base
, offset
,
2954 ds
= gimple_build_debug_bind (get_access_replacement (lacc
),
2955 drhs
, gsi_stmt (*old_gsi
));
2956 gsi_insert_after (new_gsi
, ds
, GSI_NEW_STMT
);
2960 if (lacc
->first_child
)
2961 load_assign_lhs_subreplacements (lacc
, top_racc
, left_offset
,
2962 old_gsi
, new_gsi
, refreshed
);
2966 /* Result code for SRA assignment modification. */
2967 enum assignment_mod_result
{ SRA_AM_NONE
, /* nothing done for the stmt */
2968 SRA_AM_MODIFIED
, /* stmt changed but not
2970 SRA_AM_REMOVED
}; /* stmt eliminated */
2972 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
2973 to the assignment and GSI is the statement iterator pointing at it. Returns
2974 the same values as sra_modify_assign. */
2976 static enum assignment_mod_result
2977 sra_modify_constructor_assign (gimple
*stmt
, gimple_stmt_iterator
*gsi
)
2979 tree lhs
= gimple_assign_lhs (*stmt
);
2983 acc
= get_access_for_expr (lhs
);
2987 if (gimple_clobber_p (*stmt
))
2989 /* Remove clobbers of fully scalarized variables, otherwise
2991 if (acc
->grp_covered
)
2993 unlink_stmt_vdef (*stmt
);
2994 gsi_remove (gsi
, true);
2995 release_defs (*stmt
);
2996 return SRA_AM_REMOVED
;
3002 loc
= gimple_location (*stmt
);
3003 if (vec_safe_length (CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt
))) > 0)
3005 /* I have never seen this code path trigger but if it can happen the
3006 following should handle it gracefully. */
3007 if (access_has_children_p (acc
))
3008 generate_subtree_copies (acc
->first_child
, acc
->base
, 0, 0, 0, gsi
,
3010 return SRA_AM_MODIFIED
;
3013 if (acc
->grp_covered
)
3015 init_subtree_with_zero (acc
, gsi
, false, loc
);
3016 unlink_stmt_vdef (*stmt
);
3017 gsi_remove (gsi
, true);
3018 release_defs (*stmt
);
3019 return SRA_AM_REMOVED
;
3023 init_subtree_with_zero (acc
, gsi
, true, loc
);
3024 return SRA_AM_MODIFIED
;
3028 /* Create and return a new suitable default definition SSA_NAME for RACC which
3029 is an access describing an uninitialized part of an aggregate that is being
3033 get_repl_default_def_ssa_name (struct access
*racc
)
3035 gcc_checking_assert (!racc
->grp_to_be_replaced
3036 && !racc
->grp_to_be_debug_replaced
);
3037 if (!racc
->replacement_decl
)
3038 racc
->replacement_decl
= create_access_replacement (racc
);
3039 return get_or_create_ssa_default_def (cfun
, racc
->replacement_decl
);
3042 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3043 bit-field field declaration somewhere in it. */
3046 contains_vce_or_bfcref_p (const_tree ref
)
3048 while (handled_component_p (ref
))
3050 if (TREE_CODE (ref
) == VIEW_CONVERT_EXPR
3051 || (TREE_CODE (ref
) == COMPONENT_REF
3052 && DECL_BIT_FIELD (TREE_OPERAND (ref
, 1))))
3054 ref
= TREE_OPERAND (ref
, 0);
3060 /* Examine both sides of the assignment statement pointed to by STMT, replace
3061 them with a scalare replacement if there is one and generate copying of
3062 replacements if scalarized aggregates have been used in the assignment. GSI
3063 is used to hold generated statements for type conversions and subtree
3066 static enum assignment_mod_result
3067 sra_modify_assign (gimple
*stmt
, gimple_stmt_iterator
*gsi
)
3069 struct access
*lacc
, *racc
;
3071 bool modify_this_stmt
= false;
3072 bool force_gimple_rhs
= false;
3074 gimple_stmt_iterator orig_gsi
= *gsi
;
3076 if (!gimple_assign_single_p (*stmt
))
3078 lhs
= gimple_assign_lhs (*stmt
);
3079 rhs
= gimple_assign_rhs1 (*stmt
);
3081 if (TREE_CODE (rhs
) == CONSTRUCTOR
)
3082 return sra_modify_constructor_assign (stmt
, gsi
);
3084 if (TREE_CODE (rhs
) == REALPART_EXPR
|| TREE_CODE (lhs
) == REALPART_EXPR
3085 || TREE_CODE (rhs
) == IMAGPART_EXPR
|| TREE_CODE (lhs
) == IMAGPART_EXPR
3086 || TREE_CODE (rhs
) == BIT_FIELD_REF
|| TREE_CODE (lhs
) == BIT_FIELD_REF
)
3088 modify_this_stmt
= sra_modify_expr (gimple_assign_rhs1_ptr (*stmt
),
3090 modify_this_stmt
|= sra_modify_expr (gimple_assign_lhs_ptr (*stmt
),
3092 return modify_this_stmt
? SRA_AM_MODIFIED
: SRA_AM_NONE
;
3095 lacc
= get_access_for_expr (lhs
);
3096 racc
= get_access_for_expr (rhs
);
3100 loc
= gimple_location (*stmt
);
3101 if (lacc
&& lacc
->grp_to_be_replaced
)
3103 lhs
= get_access_replacement (lacc
);
3104 gimple_assign_set_lhs (*stmt
, lhs
);
3105 modify_this_stmt
= true;
3106 if (lacc
->grp_partial_lhs
)
3107 force_gimple_rhs
= true;
3111 if (racc
&& racc
->grp_to_be_replaced
)
3113 rhs
= get_access_replacement (racc
);
3114 modify_this_stmt
= true;
3115 if (racc
->grp_partial_lhs
)
3116 force_gimple_rhs
= true;
3120 && !racc
->grp_unscalarized_data
3121 && TREE_CODE (lhs
) == SSA_NAME
3122 && !access_has_replacements_p (racc
))
3124 rhs
= get_repl_default_def_ssa_name (racc
);
3125 modify_this_stmt
= true;
3129 if (modify_this_stmt
)
3131 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
3133 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3134 ??? This should move to fold_stmt which we simply should
3135 call after building a VIEW_CONVERT_EXPR here. */
3136 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs
))
3137 && !contains_bitfld_component_ref_p (lhs
))
3139 lhs
= build_ref_for_model (loc
, lhs
, 0, racc
, gsi
, false);
3140 gimple_assign_set_lhs (*stmt
, lhs
);
3142 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs
))
3143 && !contains_vce_or_bfcref_p (rhs
))
3144 rhs
= build_ref_for_model (loc
, rhs
, 0, lacc
, gsi
, false);
3146 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
3148 rhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, TREE_TYPE (lhs
),
3150 if (is_gimple_reg_type (TREE_TYPE (lhs
))
3151 && TREE_CODE (lhs
) != SSA_NAME
)
3152 force_gimple_rhs
= true;
3157 if (lacc
&& lacc
->grp_to_be_debug_replaced
)
3159 tree dlhs
= get_access_replacement (lacc
);
3160 tree drhs
= unshare_expr (rhs
);
3161 if (!useless_type_conversion_p (TREE_TYPE (dlhs
), TREE_TYPE (drhs
)))
3163 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs
))
3164 && !contains_vce_or_bfcref_p (drhs
))
3165 drhs
= build_debug_ref_for_model (loc
, drhs
, 0, lacc
);
3167 && !useless_type_conversion_p (TREE_TYPE (dlhs
),
3169 drhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
,
3170 TREE_TYPE (dlhs
), drhs
);
3172 gimple ds
= gimple_build_debug_bind (dlhs
, drhs
, *stmt
);
3173 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
3176 /* From this point on, the function deals with assignments in between
3177 aggregates when at least one has scalar reductions of some of its
3178 components. There are three possible scenarios: Both the LHS and RHS have
3179 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3181 In the first case, we would like to load the LHS components from RHS
3182 components whenever possible. If that is not possible, we would like to
3183 read it directly from the RHS (after updating it by storing in it its own
3184 components). If there are some necessary unscalarized data in the LHS,
3185 those will be loaded by the original assignment too. If neither of these
3186 cases happen, the original statement can be removed. Most of this is done
3187 by load_assign_lhs_subreplacements.
3189 In the second case, we would like to store all RHS scalarized components
3190 directly into LHS and if they cover the aggregate completely, remove the
3191 statement too. In the third case, we want the LHS components to be loaded
3192 directly from the RHS (DSE will remove the original statement if it
3195 This is a bit complex but manageable when types match and when unions do
3196 not cause confusion in a way that we cannot really load a component of LHS
3197 from the RHS or vice versa (the access representing this level can have
3198 subaccesses that are accessible only through a different union field at a
3199 higher level - different from the one used in the examined expression).
3202 Therefore, I specially handle a fourth case, happening when there is a
3203 specific type cast or it is impossible to locate a scalarized subaccess on
3204 the other side of the expression. If that happens, I simply "refresh" the
3205 RHS by storing in it is scalarized components leave the original statement
3206 there to do the copying and then load the scalar replacements of the LHS.
3207 This is what the first branch does. */
3209 if (modify_this_stmt
3210 || gimple_has_volatile_ops (*stmt
)
3211 || contains_vce_or_bfcref_p (rhs
)
3212 || contains_vce_or_bfcref_p (lhs
))
3214 if (access_has_children_p (racc
))
3215 generate_subtree_copies (racc
->first_child
, racc
->base
, 0, 0, 0,
3216 gsi
, false, false, loc
);
3217 if (access_has_children_p (lacc
))
3218 generate_subtree_copies (lacc
->first_child
, lacc
->base
, 0, 0, 0,
3219 gsi
, true, true, loc
);
3220 sra_stats
.separate_lhs_rhs_handling
++;
3222 /* This gimplification must be done after generate_subtree_copies,
3223 lest we insert the subtree copies in the middle of the gimplified
3225 if (force_gimple_rhs
)
3226 rhs
= force_gimple_operand_gsi (&orig_gsi
, rhs
, true, NULL_TREE
,
3227 true, GSI_SAME_STMT
);
3228 if (gimple_assign_rhs1 (*stmt
) != rhs
)
3230 modify_this_stmt
= true;
3231 gimple_assign_set_rhs_from_tree (&orig_gsi
, rhs
);
3232 gcc_assert (*stmt
== gsi_stmt (orig_gsi
));
3235 return modify_this_stmt
? SRA_AM_MODIFIED
: SRA_AM_NONE
;
3239 if (access_has_children_p (lacc
)
3240 && access_has_children_p (racc
)
3241 /* When an access represents an unscalarizable region, it usually
3242 represents accesses with variable offset and thus must not be used
3243 to generate new memory accesses. */
3244 && !lacc
->grp_unscalarizable_region
3245 && !racc
->grp_unscalarizable_region
)
3247 gimple_stmt_iterator orig_gsi
= *gsi
;
3248 enum unscalarized_data_handling refreshed
;
3250 if (lacc
->grp_read
&& !lacc
->grp_covered
)
3251 refreshed
= handle_unscalarized_data_in_subtree (racc
, gsi
);
3253 refreshed
= SRA_UDH_NONE
;
3255 load_assign_lhs_subreplacements (lacc
, racc
, lacc
->offset
,
3256 &orig_gsi
, gsi
, &refreshed
);
3257 if (refreshed
!= SRA_UDH_RIGHT
)
3260 unlink_stmt_vdef (*stmt
);
3261 gsi_remove (&orig_gsi
, true);
3262 release_defs (*stmt
);
3263 sra_stats
.deleted
++;
3264 return SRA_AM_REMOVED
;
3269 if (access_has_children_p (racc
)
3270 && !racc
->grp_unscalarized_data
)
3274 fprintf (dump_file
, "Removing load: ");
3275 print_gimple_stmt (dump_file
, *stmt
, 0, 0);
3277 generate_subtree_copies (racc
->first_child
, lhs
,
3278 racc
->offset
, 0, 0, gsi
,
3280 gcc_assert (*stmt
== gsi_stmt (*gsi
));
3281 unlink_stmt_vdef (*stmt
);
3282 gsi_remove (gsi
, true);
3283 release_defs (*stmt
);
3284 sra_stats
.deleted
++;
3285 return SRA_AM_REMOVED
;
3287 /* Restore the aggregate RHS from its components so the
3288 prevailing aggregate copy does the right thing. */
3289 if (access_has_children_p (racc
))
3290 generate_subtree_copies (racc
->first_child
, racc
->base
, 0, 0, 0,
3291 gsi
, false, false, loc
);
3292 /* Re-load the components of the aggregate copy destination.
3293 But use the RHS aggregate to load from to expose more
3294 optimization opportunities. */
3295 if (access_has_children_p (lacc
))
3296 generate_subtree_copies (lacc
->first_child
, rhs
, lacc
->offset
,
3297 0, 0, gsi
, true, true, loc
);
3304 /* Traverse the function body and all modifications as decided in
3305 analyze_all_variable_accesses. Return true iff the CFG has been
3309 sra_modify_function_body (void)
3311 bool cfg_changed
= false;
3316 gimple_stmt_iterator gsi
= gsi_start_bb (bb
);
3317 while (!gsi_end_p (gsi
))
3319 gimple stmt
= gsi_stmt (gsi
);
3320 enum assignment_mod_result assign_result
;
3321 bool modified
= false, deleted
= false;
3325 switch (gimple_code (stmt
))
3328 t
= gimple_return_retval_ptr (stmt
);
3329 if (*t
!= NULL_TREE
)
3330 modified
|= sra_modify_expr (t
, &gsi
, false);
3334 assign_result
= sra_modify_assign (&stmt
, &gsi
);
3335 modified
|= assign_result
== SRA_AM_MODIFIED
;
3336 deleted
= assign_result
== SRA_AM_REMOVED
;
3340 /* Operands must be processed before the lhs. */
3341 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
3343 t
= gimple_call_arg_ptr (stmt
, i
);
3344 modified
|= sra_modify_expr (t
, &gsi
, false);
3347 if (gimple_call_lhs (stmt
))
3349 t
= gimple_call_lhs_ptr (stmt
);
3350 modified
|= sra_modify_expr (t
, &gsi
, true);
3355 for (i
= 0; i
< gimple_asm_ninputs (stmt
); i
++)
3357 t
= &TREE_VALUE (gimple_asm_input_op (stmt
, i
));
3358 modified
|= sra_modify_expr (t
, &gsi
, false);
3360 for (i
= 0; i
< gimple_asm_noutputs (stmt
); i
++)
3362 t
= &TREE_VALUE (gimple_asm_output_op (stmt
, i
));
3363 modified
|= sra_modify_expr (t
, &gsi
, true);
3374 if (maybe_clean_eh_stmt (stmt
)
3375 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
3386 /* Generate statements initializing scalar replacements of parts of function
3390 initialize_parameter_reductions (void)
3392 gimple_stmt_iterator gsi
;
3393 gimple_seq seq
= NULL
;
3396 gsi
= gsi_start (seq
);
3397 for (parm
= DECL_ARGUMENTS (current_function_decl
);
3399 parm
= DECL_CHAIN (parm
))
3401 vec
<access_p
> *access_vec
;
3402 struct access
*access
;
3404 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
3406 access_vec
= get_base_access_vector (parm
);
3410 for (access
= (*access_vec
)[0];
3412 access
= access
->next_grp
)
3413 generate_subtree_copies (access
, parm
, 0, 0, 0, &gsi
, true, true,
3414 EXPR_LOCATION (parm
));
3417 seq
= gsi_seq (gsi
);
3419 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun
)), seq
);
3422 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3423 it reveals there are components of some aggregates to be scalarized, it runs
3424 the required transformations. */
3426 perform_intra_sra (void)
3431 if (!find_var_candidates ())
3434 if (!scan_function ())
3437 if (!analyze_all_variable_accesses ())
3440 if (sra_modify_function_body ())
3441 ret
= TODO_update_ssa
| TODO_cleanup_cfg
;
3443 ret
= TODO_update_ssa
;
3444 initialize_parameter_reductions ();
3446 statistics_counter_event (cfun
, "Scalar replacements created",
3447 sra_stats
.replacements
);
3448 statistics_counter_event (cfun
, "Modified expressions", sra_stats
.exprs
);
3449 statistics_counter_event (cfun
, "Subtree copy stmts",
3450 sra_stats
.subtree_copies
);
3451 statistics_counter_event (cfun
, "Subreplacement stmts",
3452 sra_stats
.subreplacements
);
3453 statistics_counter_event (cfun
, "Deleted stmts", sra_stats
.deleted
);
3454 statistics_counter_event (cfun
, "Separate LHS and RHS handling",
3455 sra_stats
.separate_lhs_rhs_handling
);
3458 sra_deinitialize ();
3462 /* Perform early intraprocedural SRA. */
3464 early_intra_sra (void)
3466 sra_mode
= SRA_MODE_EARLY_INTRA
;
3467 return perform_intra_sra ();
3470 /* Perform "late" intraprocedural SRA. */
3472 late_intra_sra (void)
3474 sra_mode
= SRA_MODE_INTRA
;
3475 return perform_intra_sra ();
3480 gate_intra_sra (void)
3482 return flag_tree_sra
!= 0 && dbg_cnt (tree_sra
);
3488 const pass_data pass_data_sra_early
=
3490 GIMPLE_PASS
, /* type */
3492 OPTGROUP_NONE
, /* optinfo_flags */
3493 true, /* has_gate */
3494 true, /* has_execute */
3495 TV_TREE_SRA
, /* tv_id */
3496 ( PROP_cfg
| PROP_ssa
), /* properties_required */
3497 0, /* properties_provided */
3498 0, /* properties_destroyed */
3499 0, /* todo_flags_start */
3500 ( TODO_update_ssa
| TODO_verify_ssa
), /* todo_flags_finish */
3503 class pass_sra_early
: public gimple_opt_pass
3506 pass_sra_early (gcc::context
*ctxt
)
3507 : gimple_opt_pass (pass_data_sra_early
, ctxt
)
3510 /* opt_pass methods: */
3511 bool gate () { return gate_intra_sra (); }
3512 unsigned int execute () { return early_intra_sra (); }
3514 }; // class pass_sra_early
3519 make_pass_sra_early (gcc::context
*ctxt
)
3521 return new pass_sra_early (ctxt
);
3526 const pass_data pass_data_sra
=
3528 GIMPLE_PASS
, /* type */
3530 OPTGROUP_NONE
, /* optinfo_flags */
3531 true, /* has_gate */
3532 true, /* has_execute */
3533 TV_TREE_SRA
, /* tv_id */
3534 ( PROP_cfg
| PROP_ssa
), /* properties_required */
3535 0, /* properties_provided */
3536 0, /* properties_destroyed */
3537 TODO_update_address_taken
, /* todo_flags_start */
3538 ( TODO_update_ssa
| TODO_verify_ssa
), /* todo_flags_finish */
3541 class pass_sra
: public gimple_opt_pass
3544 pass_sra (gcc::context
*ctxt
)
3545 : gimple_opt_pass (pass_data_sra
, ctxt
)
3548 /* opt_pass methods: */
3549 bool gate () { return gate_intra_sra (); }
3550 unsigned int execute () { return late_intra_sra (); }
3552 }; // class pass_sra
3557 make_pass_sra (gcc::context
*ctxt
)
3559 return new pass_sra (ctxt
);
3563 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3567 is_unused_scalar_param (tree parm
)
3570 return (is_gimple_reg (parm
)
3571 && (!(name
= ssa_default_def (cfun
, parm
))
3572 || has_zero_uses (name
)));
3575 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3576 examine whether there are any direct or otherwise infeasible ones. If so,
3577 return true, otherwise return false. PARM must be a gimple register with a
3578 non-NULL default definition. */
3581 ptr_parm_has_direct_uses (tree parm
)
3583 imm_use_iterator ui
;
3585 tree name
= ssa_default_def (cfun
, parm
);
3588 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
3591 use_operand_p use_p
;
3593 if (is_gimple_debug (stmt
))
3596 /* Valid uses include dereferences on the lhs and the rhs. */
3597 if (gimple_has_lhs (stmt
))
3599 tree lhs
= gimple_get_lhs (stmt
);
3600 while (handled_component_p (lhs
))
3601 lhs
= TREE_OPERAND (lhs
, 0);
3602 if (TREE_CODE (lhs
) == MEM_REF
3603 && TREE_OPERAND (lhs
, 0) == name
3604 && integer_zerop (TREE_OPERAND (lhs
, 1))
3605 && types_compatible_p (TREE_TYPE (lhs
),
3606 TREE_TYPE (TREE_TYPE (name
)))
3607 && !TREE_THIS_VOLATILE (lhs
))
3610 if (gimple_assign_single_p (stmt
))
3612 tree rhs
= gimple_assign_rhs1 (stmt
);
3613 while (handled_component_p (rhs
))
3614 rhs
= TREE_OPERAND (rhs
, 0);
3615 if (TREE_CODE (rhs
) == MEM_REF
3616 && TREE_OPERAND (rhs
, 0) == name
3617 && integer_zerop (TREE_OPERAND (rhs
, 1))
3618 && types_compatible_p (TREE_TYPE (rhs
),
3619 TREE_TYPE (TREE_TYPE (name
)))
3620 && !TREE_THIS_VOLATILE (rhs
))
3623 else if (is_gimple_call (stmt
))
3626 for (i
= 0; i
< gimple_call_num_args (stmt
); ++i
)
3628 tree arg
= gimple_call_arg (stmt
, i
);
3629 while (handled_component_p (arg
))
3630 arg
= TREE_OPERAND (arg
, 0);
3631 if (TREE_CODE (arg
) == MEM_REF
3632 && TREE_OPERAND (arg
, 0) == name
3633 && integer_zerop (TREE_OPERAND (arg
, 1))
3634 && types_compatible_p (TREE_TYPE (arg
),
3635 TREE_TYPE (TREE_TYPE (name
)))
3636 && !TREE_THIS_VOLATILE (arg
))
3641 /* If the number of valid uses does not match the number of
3642 uses in this stmt there is an unhandled use. */
3643 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
3650 BREAK_FROM_IMM_USE_STMT (ui
);
3656 /* Identify candidates for reduction for IPA-SRA based on their type and mark
3657 them in candidate_bitmap. Note that these do not necessarily include
3658 parameter which are unused and thus can be removed. Return true iff any
3659 such candidate has been found. */
3662 find_param_candidates (void)
3669 for (parm
= DECL_ARGUMENTS (current_function_decl
);
3671 parm
= DECL_CHAIN (parm
))
3673 tree type
= TREE_TYPE (parm
);
3678 if (TREE_THIS_VOLATILE (parm
)
3679 || TREE_ADDRESSABLE (parm
)
3680 || (!is_gimple_reg_type (type
) && is_va_list_type (type
)))
3683 if (is_unused_scalar_param (parm
))
3689 if (POINTER_TYPE_P (type
))
3691 type
= TREE_TYPE (type
);
3693 if (TREE_CODE (type
) == FUNCTION_TYPE
3694 || TYPE_VOLATILE (type
)
3695 || (TREE_CODE (type
) == ARRAY_TYPE
3696 && TYPE_NONALIASED_COMPONENT (type
))
3697 || !is_gimple_reg (parm
)
3698 || is_va_list_type (type
)
3699 || ptr_parm_has_direct_uses (parm
))
3702 else if (!AGGREGATE_TYPE_P (type
))
3705 if (!COMPLETE_TYPE_P (type
)
3706 || !tree_fits_uhwi_p (TYPE_SIZE (type
))
3707 || tree_to_uhwi (TYPE_SIZE (type
)) == 0
3708 || (AGGREGATE_TYPE_P (type
)
3709 && type_internals_preclude_sra_p (type
, &msg
)))
3712 bitmap_set_bit (candidate_bitmap
, DECL_UID (parm
));
3713 slot
= candidates
.find_slot_with_hash (parm
, DECL_UID (parm
), INSERT
);
3717 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3719 fprintf (dump_file
, "Candidate (%d): ", DECL_UID (parm
));
3720 print_generic_expr (dump_file
, parm
, 0);
3721 fprintf (dump_file
, "\n");
3725 func_param_count
= count
;
3729 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
3733 mark_maybe_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef ATTRIBUTE_UNUSED
,
3736 struct access
*repr
= (struct access
*) data
;
3738 repr
->grp_maybe_modified
= 1;
3742 /* Analyze what representatives (in linked lists accessible from
3743 REPRESENTATIVES) can be modified by side effects of statements in the
3744 current function. */
3747 analyze_modified_params (vec
<access_p
> representatives
)
3751 for (i
= 0; i
< func_param_count
; i
++)
3753 struct access
*repr
;
3755 for (repr
= representatives
[i
];
3757 repr
= repr
->next_grp
)
3759 struct access
*access
;
3763 if (no_accesses_p (repr
))
3765 if (!POINTER_TYPE_P (TREE_TYPE (repr
->base
))
3766 || repr
->grp_maybe_modified
)
3769 ao_ref_init (&ar
, repr
->expr
);
3770 visited
= BITMAP_ALLOC (NULL
);
3771 for (access
= repr
; access
; access
= access
->next_sibling
)
3773 /* All accesses are read ones, otherwise grp_maybe_modified would
3774 be trivially set. */
3775 walk_aliased_vdefs (&ar
, gimple_vuse (access
->stmt
),
3776 mark_maybe_modified
, repr
, &visited
);
3777 if (repr
->grp_maybe_modified
)
3780 BITMAP_FREE (visited
);
3785 /* Propagate distances in bb_dereferences in the opposite direction than the
3786 control flow edges, in each step storing the maximum of the current value
3787 and the minimum of all successors. These steps are repeated until the table
3788 stabilizes. Note that BBs which might terminate the functions (according to
3789 final_bbs bitmap) never updated in this way. */
3792 propagate_dereference_distances (void)
3796 auto_vec
<basic_block
> queue (last_basic_block_for_function (cfun
));
3797 queue
.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
3800 queue
.quick_push (bb
);
3804 while (!queue
.is_empty ())
3808 bool change
= false;
3814 if (bitmap_bit_p (final_bbs
, bb
->index
))
3817 for (i
= 0; i
< func_param_count
; i
++)
3819 int idx
= bb
->index
* func_param_count
+ i
;
3821 HOST_WIDE_INT inh
= 0;
3823 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
3825 int succ_idx
= e
->dest
->index
* func_param_count
+ i
;
3827 if (e
->src
== EXIT_BLOCK_PTR_FOR_FN (cfun
))
3833 inh
= bb_dereferences
[succ_idx
];
3835 else if (bb_dereferences
[succ_idx
] < inh
)
3836 inh
= bb_dereferences
[succ_idx
];
3839 if (!first
&& bb_dereferences
[idx
] < inh
)
3841 bb_dereferences
[idx
] = inh
;
3846 if (change
&& !bitmap_bit_p (final_bbs
, bb
->index
))
3847 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
3852 e
->src
->aux
= e
->src
;
3853 queue
.quick_push (e
->src
);
3858 /* Dump a dereferences TABLE with heading STR to file F. */
3861 dump_dereferences_table (FILE *f
, const char *str
, HOST_WIDE_INT
*table
)
3865 fprintf (dump_file
, str
);
3866 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR_FOR_FN (cfun
),
3867 EXIT_BLOCK_PTR_FOR_FN (cfun
), next_bb
)
3869 fprintf (f
, "%4i %i ", bb
->index
, bitmap_bit_p (final_bbs
, bb
->index
));
3870 if (bb
!= EXIT_BLOCK_PTR_FOR_FN (cfun
))
3873 for (i
= 0; i
< func_param_count
; i
++)
3875 int idx
= bb
->index
* func_param_count
+ i
;
3876 fprintf (f
, " %4" HOST_WIDE_INT_PRINT
"d", table
[idx
]);
3881 fprintf (dump_file
, "\n");
3884 /* Determine what (parts of) parameters passed by reference that are not
3885 assigned to are not certainly dereferenced in this function and thus the
3886 dereferencing cannot be safely moved to the caller without potentially
3887 introducing a segfault. Mark such REPRESENTATIVES as
3888 grp_not_necessarilly_dereferenced.
3890 The dereferenced maximum "distance," i.e. the offset + size of the accessed
3891 part is calculated rather than simple booleans are calculated for each
3892 pointer parameter to handle cases when only a fraction of the whole
3893 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
3896 The maximum dereference distances for each pointer parameter and BB are
3897 already stored in bb_dereference. This routine simply propagates these
3898 values upwards by propagate_dereference_distances and then compares the
3899 distances of individual parameters in the ENTRY BB to the equivalent
3900 distances of each representative of a (fraction of a) parameter. */
3903 analyze_caller_dereference_legality (vec
<access_p
> representatives
)
3907 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3908 dump_dereferences_table (dump_file
,
3909 "Dereference table before propagation:\n",
3912 propagate_dereference_distances ();
3914 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3915 dump_dereferences_table (dump_file
,
3916 "Dereference table after propagation:\n",
3919 for (i
= 0; i
< func_param_count
; i
++)
3921 struct access
*repr
= representatives
[i
];
3922 int idx
= ENTRY_BLOCK_PTR_FOR_FN (cfun
)->index
* func_param_count
+ i
;
3924 if (!repr
|| no_accesses_p (repr
))
3929 if ((repr
->offset
+ repr
->size
) > bb_dereferences
[idx
])
3930 repr
->grp_not_necessarilly_dereferenced
= 1;
3931 repr
= repr
->next_grp
;
3937 /* Return the representative access for the parameter declaration PARM if it is
3938 a scalar passed by reference which is not written to and the pointer value
3939 is not used directly. Thus, if it is legal to dereference it in the caller
3940 and we can rule out modifications through aliases, such parameter should be
3941 turned into one passed by value. Return NULL otherwise. */
3943 static struct access
*
3944 unmodified_by_ref_scalar_representative (tree parm
)
3946 int i
, access_count
;
3947 struct access
*repr
;
3948 vec
<access_p
> *access_vec
;
3950 access_vec
= get_base_access_vector (parm
);
3951 gcc_assert (access_vec
);
3952 repr
= (*access_vec
)[0];
3955 repr
->group_representative
= repr
;
3957 access_count
= access_vec
->length ();
3958 for (i
= 1; i
< access_count
; i
++)
3960 struct access
*access
= (*access_vec
)[i
];
3963 access
->group_representative
= repr
;
3964 access
->next_sibling
= repr
->next_sibling
;
3965 repr
->next_sibling
= access
;
3969 repr
->grp_scalar_ptr
= 1;
3973 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
3974 associated with. REQ_ALIGN is the minimum required alignment. */
3977 access_precludes_ipa_sra_p (struct access
*access
, unsigned int req_align
)
3979 unsigned int exp_align
;
3980 /* Avoid issues such as the second simple testcase in PR 42025. The problem
3981 is incompatible assign in a call statement (and possibly even in asm
3982 statements). This can be relaxed by using a new temporary but only for
3983 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
3984 intraprocedural SRA we deal with this by keeping the old aggregate around,
3985 something we cannot do in IPA-SRA.) */
3987 && (is_gimple_call (access
->stmt
)
3988 || gimple_code (access
->stmt
) == GIMPLE_ASM
))
3991 exp_align
= get_object_alignment (access
->expr
);
3992 if (exp_align
< req_align
)
3999 /* Sort collected accesses for parameter PARM, identify representatives for
4000 each accessed region and link them together. Return NULL if there are
4001 different but overlapping accesses, return the special ptr value meaning
4002 there are no accesses for this parameter if that is the case and return the
4003 first representative otherwise. Set *RO_GRP if there is a group of accesses
4004 with only read (i.e. no write) accesses. */
4006 static struct access
*
4007 splice_param_accesses (tree parm
, bool *ro_grp
)
4009 int i
, j
, access_count
, group_count
;
4010 int agg_size
, total_size
= 0;
4011 struct access
*access
, *res
, **prev_acc_ptr
= &res
;
4012 vec
<access_p
> *access_vec
;
4014 access_vec
= get_base_access_vector (parm
);
4016 return &no_accesses_representant
;
4017 access_count
= access_vec
->length ();
4019 access_vec
->qsort (compare_access_positions
);
4024 while (i
< access_count
)
4028 access
= (*access_vec
)[i
];
4029 modification
= access
->write
;
4030 if (access_precludes_ipa_sra_p (access
, TYPE_ALIGN (access
->type
)))
4032 a1_alias_type
= reference_alias_ptr_type (access
->expr
);
4034 /* Access is about to become group representative unless we find some
4035 nasty overlap which would preclude us from breaking this parameter
4039 while (j
< access_count
)
4041 struct access
*ac2
= (*access_vec
)[j
];
4042 if (ac2
->offset
!= access
->offset
)
4044 /* All or nothing law for parameters. */
4045 if (access
->offset
+ access
->size
> ac2
->offset
)
4050 else if (ac2
->size
!= access
->size
)
4053 if (access_precludes_ipa_sra_p (ac2
, TYPE_ALIGN (access
->type
))
4054 || (ac2
->type
!= access
->type
4055 && (TREE_ADDRESSABLE (ac2
->type
)
4056 || TREE_ADDRESSABLE (access
->type
)))
4057 || (reference_alias_ptr_type (ac2
->expr
) != a1_alias_type
))
4060 modification
|= ac2
->write
;
4061 ac2
->group_representative
= access
;
4062 ac2
->next_sibling
= access
->next_sibling
;
4063 access
->next_sibling
= ac2
;
4068 access
->grp_maybe_modified
= modification
;
4071 *prev_acc_ptr
= access
;
4072 prev_acc_ptr
= &access
->next_grp
;
4073 total_size
+= access
->size
;
4077 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4078 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm
))));
4080 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm
)));
4081 if (total_size
>= agg_size
)
4084 gcc_assert (group_count
> 0);
4088 /* Decide whether parameters with representative accesses given by REPR should
4089 be reduced into components. */
4092 decide_one_param_reduction (struct access
*repr
)
4094 int total_size
, cur_parm_size
, agg_size
, new_param_count
, parm_size_limit
;
4099 cur_parm_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm
)));
4100 gcc_assert (cur_parm_size
> 0);
4102 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4105 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm
))));
4110 agg_size
= cur_parm_size
;
4116 fprintf (dump_file
, "Evaluating PARAM group sizes for ");
4117 print_generic_expr (dump_file
, parm
, 0);
4118 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (parm
));
4119 for (acc
= repr
; acc
; acc
= acc
->next_grp
)
4120 dump_access (dump_file
, acc
, true);
4124 new_param_count
= 0;
4126 for (; repr
; repr
= repr
->next_grp
)
4128 gcc_assert (parm
== repr
->base
);
4130 /* Taking the address of a non-addressable field is verboten. */
4131 if (by_ref
&& repr
->non_addressable
)
4134 /* Do not decompose a non-BLKmode param in a way that would
4135 create BLKmode params. Especially for by-reference passing
4136 (thus, pointer-type param) this is hardly worthwhile. */
4137 if (DECL_MODE (parm
) != BLKmode
4138 && TYPE_MODE (repr
->type
) == BLKmode
)
4141 if (!by_ref
|| (!repr
->grp_maybe_modified
4142 && !repr
->grp_not_necessarilly_dereferenced
))
4143 total_size
+= repr
->size
;
4145 total_size
+= cur_parm_size
;
4150 gcc_assert (new_param_count
> 0);
4152 if (optimize_function_for_size_p (cfun
))
4153 parm_size_limit
= cur_parm_size
;
4155 parm_size_limit
= (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR
)
4158 if (total_size
< agg_size
4159 && total_size
<= parm_size_limit
)
4162 fprintf (dump_file
, " ....will be split into %i components\n",
4164 return new_param_count
;
4170 /* The order of the following enums is important, we need to do extra work for
4171 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4172 enum ipa_splicing_result
{ NO_GOOD_ACCESS
, UNUSED_PARAMS
, BY_VAL_ACCESSES
,
4173 MODIF_BY_REF_ACCESSES
, UNMODIF_BY_REF_ACCESSES
};
4175 /* Identify representatives of all accesses to all candidate parameters for
4176 IPA-SRA. Return result based on what representatives have been found. */
4178 static enum ipa_splicing_result
4179 splice_all_param_accesses (vec
<access_p
> &representatives
)
4181 enum ipa_splicing_result result
= NO_GOOD_ACCESS
;
4183 struct access
*repr
;
4185 representatives
.create (func_param_count
);
4187 for (parm
= DECL_ARGUMENTS (current_function_decl
);
4189 parm
= DECL_CHAIN (parm
))
4191 if (is_unused_scalar_param (parm
))
4193 representatives
.quick_push (&no_accesses_representant
);
4194 if (result
== NO_GOOD_ACCESS
)
4195 result
= UNUSED_PARAMS
;
4197 else if (POINTER_TYPE_P (TREE_TYPE (parm
))
4198 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm
)))
4199 && bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
4201 repr
= unmodified_by_ref_scalar_representative (parm
);
4202 representatives
.quick_push (repr
);
4204 result
= UNMODIF_BY_REF_ACCESSES
;
4206 else if (bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
4208 bool ro_grp
= false;
4209 repr
= splice_param_accesses (parm
, &ro_grp
);
4210 representatives
.quick_push (repr
);
4212 if (repr
&& !no_accesses_p (repr
))
4214 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4217 result
= UNMODIF_BY_REF_ACCESSES
;
4218 else if (result
< MODIF_BY_REF_ACCESSES
)
4219 result
= MODIF_BY_REF_ACCESSES
;
4221 else if (result
< BY_VAL_ACCESSES
)
4222 result
= BY_VAL_ACCESSES
;
4224 else if (no_accesses_p (repr
) && (result
== NO_GOOD_ACCESS
))
4225 result
= UNUSED_PARAMS
;
4228 representatives
.quick_push (NULL
);
4231 if (result
== NO_GOOD_ACCESS
)
4233 representatives
.release ();
4234 return NO_GOOD_ACCESS
;
4240 /* Return the index of BASE in PARMS. Abort if it is not found. */
4243 get_param_index (tree base
, vec
<tree
> parms
)
4247 len
= parms
.length ();
4248 for (i
= 0; i
< len
; i
++)
4249 if (parms
[i
] == base
)
4254 /* Convert the decisions made at the representative level into compact
4255 parameter adjustments. REPRESENTATIVES are pointers to first
4256 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4257 final number of adjustments. */
4259 static ipa_parm_adjustment_vec
4260 turn_representatives_into_adjustments (vec
<access_p
> representatives
,
4261 int adjustments_count
)
4264 ipa_parm_adjustment_vec adjustments
;
4268 gcc_assert (adjustments_count
> 0);
4269 parms
= ipa_get_vector_of_formal_parms (current_function_decl
);
4270 adjustments
.create (adjustments_count
);
4271 parm
= DECL_ARGUMENTS (current_function_decl
);
4272 for (i
= 0; i
< func_param_count
; i
++, parm
= DECL_CHAIN (parm
))
4274 struct access
*repr
= representatives
[i
];
4276 if (!repr
|| no_accesses_p (repr
))
4278 struct ipa_parm_adjustment adj
;
4280 memset (&adj
, 0, sizeof (adj
));
4281 adj
.base_index
= get_param_index (parm
, parms
);
4284 adj
.op
= IPA_PARM_OP_COPY
;
4286 adj
.op
= IPA_PARM_OP_REMOVE
;
4287 adj
.arg_prefix
= "ISRA";
4288 adjustments
.quick_push (adj
);
4292 struct ipa_parm_adjustment adj
;
4293 int index
= get_param_index (parm
, parms
);
4295 for (; repr
; repr
= repr
->next_grp
)
4297 memset (&adj
, 0, sizeof (adj
));
4298 gcc_assert (repr
->base
== parm
);
4299 adj
.base_index
= index
;
4300 adj
.base
= repr
->base
;
4301 adj
.type
= repr
->type
;
4302 adj
.alias_ptr_type
= reference_alias_ptr_type (repr
->expr
);
4303 adj
.offset
= repr
->offset
;
4304 adj
.by_ref
= (POINTER_TYPE_P (TREE_TYPE (repr
->base
))
4305 && (repr
->grp_maybe_modified
4306 || repr
->grp_not_necessarilly_dereferenced
));
4307 adj
.arg_prefix
= "ISRA";
4308 adjustments
.quick_push (adj
);
4316 /* Analyze the collected accesses and produce a plan what to do with the
4317 parameters in the form of adjustments, NULL meaning nothing. */
4319 static ipa_parm_adjustment_vec
4320 analyze_all_param_acesses (void)
4322 enum ipa_splicing_result repr_state
;
4323 bool proceed
= false;
4324 int i
, adjustments_count
= 0;
4325 vec
<access_p
> representatives
;
4326 ipa_parm_adjustment_vec adjustments
;
4328 repr_state
= splice_all_param_accesses (representatives
);
4329 if (repr_state
== NO_GOOD_ACCESS
)
4330 return ipa_parm_adjustment_vec ();
4332 /* If there are any parameters passed by reference which are not modified
4333 directly, we need to check whether they can be modified indirectly. */
4334 if (repr_state
== UNMODIF_BY_REF_ACCESSES
)
4336 analyze_caller_dereference_legality (representatives
);
4337 analyze_modified_params (representatives
);
4340 for (i
= 0; i
< func_param_count
; i
++)
4342 struct access
*repr
= representatives
[i
];
4344 if (repr
&& !no_accesses_p (repr
))
4346 if (repr
->grp_scalar_ptr
)
4348 adjustments_count
++;
4349 if (repr
->grp_not_necessarilly_dereferenced
4350 || repr
->grp_maybe_modified
)
4351 representatives
[i
] = NULL
;
4355 sra_stats
.scalar_by_ref_to_by_val
++;
4360 int new_components
= decide_one_param_reduction (repr
);
4362 if (new_components
== 0)
4364 representatives
[i
] = NULL
;
4365 adjustments_count
++;
4369 adjustments_count
+= new_components
;
4370 sra_stats
.aggregate_params_reduced
++;
4371 sra_stats
.param_reductions_created
+= new_components
;
4378 if (no_accesses_p (repr
))
4381 sra_stats
.deleted_unused_parameters
++;
4383 adjustments_count
++;
4387 if (!proceed
&& dump_file
)
4388 fprintf (dump_file
, "NOT proceeding to change params.\n");
4391 adjustments
= turn_representatives_into_adjustments (representatives
,
4394 adjustments
= ipa_parm_adjustment_vec ();
4396 representatives
.release ();
4400 /* If a parameter replacement identified by ADJ does not yet exist in the form
4401 of declaration, create it and record it, otherwise return the previously
4405 get_replaced_param_substitute (struct ipa_parm_adjustment
*adj
)
4408 if (!adj
->new_ssa_base
)
4410 char *pretty_name
= make_fancy_name (adj
->base
);
4412 repl
= create_tmp_reg (TREE_TYPE (adj
->base
), "ISR");
4413 DECL_NAME (repl
) = get_identifier (pretty_name
);
4414 obstack_free (&name_obstack
, pretty_name
);
4416 adj
->new_ssa_base
= repl
;
4419 repl
= adj
->new_ssa_base
;
4423 /* Find the first adjustment for a particular parameter BASE in a vector of
4424 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4427 static struct ipa_parm_adjustment
*
4428 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments
, tree base
)
4432 len
= adjustments
.length ();
4433 for (i
= 0; i
< len
; i
++)
4435 struct ipa_parm_adjustment
*adj
;
4437 adj
= &adjustments
[i
];
4438 if (adj
->op
!= IPA_PARM_OP_COPY
&& adj
->base
== base
)
4445 /* If the statement STMT defines an SSA_NAME of a parameter which is to be
4446 removed because its value is not used, replace the SSA_NAME with a one
4447 relating to a created VAR_DECL together all of its uses and return true.
4448 ADJUSTMENTS is a pointer to an adjustments vector. */
4451 replace_removed_params_ssa_names (gimple stmt
,
4452 ipa_parm_adjustment_vec adjustments
)
4454 struct ipa_parm_adjustment
*adj
;
4455 tree lhs
, decl
, repl
, name
;
4457 if (gimple_code (stmt
) == GIMPLE_PHI
)
4458 lhs
= gimple_phi_result (stmt
);
4459 else if (is_gimple_assign (stmt
))
4460 lhs
= gimple_assign_lhs (stmt
);
4461 else if (is_gimple_call (stmt
))
4462 lhs
= gimple_call_lhs (stmt
);
4466 if (TREE_CODE (lhs
) != SSA_NAME
)
4469 decl
= SSA_NAME_VAR (lhs
);
4470 if (decl
== NULL_TREE
4471 || TREE_CODE (decl
) != PARM_DECL
)
4474 adj
= get_adjustment_for_base (adjustments
, decl
);
4478 repl
= get_replaced_param_substitute (adj
);
4479 name
= make_ssa_name (repl
, stmt
);
4483 fprintf (dump_file
, "replacing an SSA name of a removed param ");
4484 print_generic_expr (dump_file
, lhs
, 0);
4485 fprintf (dump_file
, " with ");
4486 print_generic_expr (dump_file
, name
, 0);
4487 fprintf (dump_file
, "\n");
4490 if (is_gimple_assign (stmt
))
4491 gimple_assign_set_lhs (stmt
, name
);
4492 else if (is_gimple_call (stmt
))
4493 gimple_call_set_lhs (stmt
, name
);
4495 gimple_phi_set_result (stmt
, name
);
4497 replace_uses_by (lhs
, name
);
4498 release_ssa_name (lhs
);
4502 /* If the statement pointed to by STMT_PTR contains any expressions that need
4503 to replaced with a different one as noted by ADJUSTMENTS, do so. Handle any
4504 potential type incompatibilities (GSI is used to accommodate conversion
4505 statements and must point to the statement). Return true iff the statement
4509 sra_ipa_modify_assign (gimple
*stmt_ptr
, gimple_stmt_iterator
*gsi
,
4510 ipa_parm_adjustment_vec adjustments
)
4512 gimple stmt
= *stmt_ptr
;
4513 tree
*lhs_p
, *rhs_p
;
4516 if (!gimple_assign_single_p (stmt
))
4519 rhs_p
= gimple_assign_rhs1_ptr (stmt
);
4520 lhs_p
= gimple_assign_lhs_ptr (stmt
);
4522 any
= ipa_modify_expr (rhs_p
, false, adjustments
);
4523 any
|= ipa_modify_expr (lhs_p
, false, adjustments
);
4526 tree new_rhs
= NULL_TREE
;
4528 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p
), TREE_TYPE (*rhs_p
)))
4530 if (TREE_CODE (*rhs_p
) == CONSTRUCTOR
)
4532 /* V_C_Es of constructors can cause trouble (PR 42714). */
4533 if (is_gimple_reg_type (TREE_TYPE (*lhs_p
)))
4534 *rhs_p
= build_zero_cst (TREE_TYPE (*lhs_p
));
4536 *rhs_p
= build_constructor (TREE_TYPE (*lhs_p
),
4540 new_rhs
= fold_build1_loc (gimple_location (stmt
),
4541 VIEW_CONVERT_EXPR
, TREE_TYPE (*lhs_p
),
4544 else if (REFERENCE_CLASS_P (*rhs_p
)
4545 && is_gimple_reg_type (TREE_TYPE (*lhs_p
))
4546 && !is_gimple_reg (*lhs_p
))
4547 /* This can happen when an assignment in between two single field
4548 structures is turned into an assignment in between two pointers to
4549 scalars (PR 42237). */
4554 tree tmp
= force_gimple_operand_gsi (gsi
, new_rhs
, true, NULL_TREE
,
4555 true, GSI_SAME_STMT
);
4557 gimple_assign_set_rhs_from_tree (gsi
, tmp
);
4566 /* Traverse the function body and all modifications as described in
4567 ADJUSTMENTS. Return true iff the CFG has been changed. */
4570 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments
)
4572 bool cfg_changed
= false;
4577 gimple_stmt_iterator gsi
;
4579 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4580 replace_removed_params_ssa_names (gsi_stmt (gsi
), adjustments
);
4582 gsi
= gsi_start_bb (bb
);
4583 while (!gsi_end_p (gsi
))
4585 gimple stmt
= gsi_stmt (gsi
);
4586 bool modified
= false;
4590 switch (gimple_code (stmt
))
4593 t
= gimple_return_retval_ptr (stmt
);
4594 if (*t
!= NULL_TREE
)
4595 modified
|= ipa_modify_expr (t
, true, adjustments
);
4599 modified
|= sra_ipa_modify_assign (&stmt
, &gsi
, adjustments
);
4600 modified
|= replace_removed_params_ssa_names (stmt
, adjustments
);
4604 /* Operands must be processed before the lhs. */
4605 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
4607 t
= gimple_call_arg_ptr (stmt
, i
);
4608 modified
|= ipa_modify_expr (t
, true, adjustments
);
4611 if (gimple_call_lhs (stmt
))
4613 t
= gimple_call_lhs_ptr (stmt
);
4614 modified
|= ipa_modify_expr (t
, false, adjustments
);
4615 modified
|= replace_removed_params_ssa_names (stmt
,
4621 for (i
= 0; i
< gimple_asm_ninputs (stmt
); i
++)
4623 t
= &TREE_VALUE (gimple_asm_input_op (stmt
, i
));
4624 modified
|= ipa_modify_expr (t
, true, adjustments
);
4626 for (i
= 0; i
< gimple_asm_noutputs (stmt
); i
++)
4628 t
= &TREE_VALUE (gimple_asm_output_op (stmt
, i
));
4629 modified
|= ipa_modify_expr (t
, false, adjustments
);
4640 if (maybe_clean_eh_stmt (stmt
)
4641 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
4651 /* Call gimple_debug_bind_reset_value on all debug statements describing
4652 gimple register parameters that are being removed or replaced. */
4655 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments
)
4658 gimple_stmt_iterator
*gsip
= NULL
, gsi
;
4660 if (MAY_HAVE_DEBUG_STMTS
&& single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun
)))
4662 gsi
= gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun
)));
4665 len
= adjustments
.length ();
4666 for (i
= 0; i
< len
; i
++)
4668 struct ipa_parm_adjustment
*adj
;
4669 imm_use_iterator ui
;
4670 gimple stmt
, def_temp
;
4671 tree name
, vexpr
, copy
= NULL_TREE
;
4672 use_operand_p use_p
;
4674 adj
= &adjustments
[i
];
4675 if (adj
->op
== IPA_PARM_OP_COPY
|| !is_gimple_reg (adj
->base
))
4677 name
= ssa_default_def (cfun
, adj
->base
);
4680 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
4682 if (gimple_clobber_p (stmt
))
4684 gimple_stmt_iterator cgsi
= gsi_for_stmt (stmt
);
4685 unlink_stmt_vdef (stmt
);
4686 gsi_remove (&cgsi
, true);
4687 release_defs (stmt
);
4690 /* All other users must have been removed by
4691 ipa_sra_modify_function_body. */
4692 gcc_assert (is_gimple_debug (stmt
));
4693 if (vexpr
== NULL
&& gsip
!= NULL
)
4695 gcc_assert (TREE_CODE (adj
->base
) == PARM_DECL
);
4696 vexpr
= make_node (DEBUG_EXPR_DECL
);
4697 def_temp
= gimple_build_debug_source_bind (vexpr
, adj
->base
,
4699 DECL_ARTIFICIAL (vexpr
) = 1;
4700 TREE_TYPE (vexpr
) = TREE_TYPE (name
);
4701 DECL_MODE (vexpr
) = DECL_MODE (adj
->base
);
4702 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
4706 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
4707 SET_USE (use_p
, vexpr
);
4710 gimple_debug_bind_reset_value (stmt
);
4713 /* Create a VAR_DECL for debug info purposes. */
4714 if (!DECL_IGNORED_P (adj
->base
))
4716 copy
= build_decl (DECL_SOURCE_LOCATION (current_function_decl
),
4717 VAR_DECL
, DECL_NAME (adj
->base
),
4718 TREE_TYPE (adj
->base
));
4719 if (DECL_PT_UID_SET_P (adj
->base
))
4720 SET_DECL_PT_UID (copy
, DECL_PT_UID (adj
->base
));
4721 TREE_ADDRESSABLE (copy
) = TREE_ADDRESSABLE (adj
->base
);
4722 TREE_READONLY (copy
) = TREE_READONLY (adj
->base
);
4723 TREE_THIS_VOLATILE (copy
) = TREE_THIS_VOLATILE (adj
->base
);
4724 DECL_GIMPLE_REG_P (copy
) = DECL_GIMPLE_REG_P (adj
->base
);
4725 DECL_ARTIFICIAL (copy
) = DECL_ARTIFICIAL (adj
->base
);
4726 DECL_IGNORED_P (copy
) = DECL_IGNORED_P (adj
->base
);
4727 DECL_ABSTRACT_ORIGIN (copy
) = DECL_ORIGIN (adj
->base
);
4728 DECL_SEEN_IN_BIND_EXPR_P (copy
) = 1;
4729 SET_DECL_RTL (copy
, 0);
4730 TREE_USED (copy
) = 1;
4731 DECL_CONTEXT (copy
) = current_function_decl
;
4732 add_local_decl (cfun
, copy
);
4734 BLOCK_VARS (DECL_INITIAL (current_function_decl
));
4735 BLOCK_VARS (DECL_INITIAL (current_function_decl
)) = copy
;
4737 if (gsip
!= NULL
&& copy
&& target_for_debug_bind (adj
->base
))
4739 gcc_assert (TREE_CODE (adj
->base
) == PARM_DECL
);
4741 def_temp
= gimple_build_debug_bind (copy
, vexpr
, NULL
);
4743 def_temp
= gimple_build_debug_source_bind (copy
, adj
->base
,
4745 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
4750 /* Return false iff all callers have at least as many actual arguments as there
4751 are formal parameters in the current function. */
4754 not_all_callers_have_enough_arguments_p (struct cgraph_node
*node
,
4755 void *data ATTRIBUTE_UNUSED
)
4757 struct cgraph_edge
*cs
;
4758 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4759 if (!callsite_has_enough_arguments_p (cs
->call_stmt
))
4765 /* Convert all callers of NODE. */
4768 convert_callers_for_node (struct cgraph_node
*node
,
4771 ipa_parm_adjustment_vec
*adjustments
= (ipa_parm_adjustment_vec
*) data
;
4772 bitmap recomputed_callers
= BITMAP_ALLOC (NULL
);
4773 struct cgraph_edge
*cs
;
4775 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4777 push_cfun (DECL_STRUCT_FUNCTION (cs
->caller
->decl
));
4780 fprintf (dump_file
, "Adjusting call %s/%i -> %s/%i\n",
4781 xstrdup (cs
->caller
->name ()),
4783 xstrdup (cs
->callee
->name ()),
4786 ipa_modify_call_arguments (cs
, cs
->call_stmt
, *adjustments
);
4791 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4792 if (bitmap_set_bit (recomputed_callers
, cs
->caller
->uid
)
4793 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs
->caller
->decl
)))
4794 compute_inline_parameters (cs
->caller
, true);
4795 BITMAP_FREE (recomputed_callers
);
4800 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
4803 convert_callers (struct cgraph_node
*node
, tree old_decl
,
4804 ipa_parm_adjustment_vec adjustments
)
4806 basic_block this_block
;
4808 cgraph_for_node_and_aliases (node
, convert_callers_for_node
,
4809 &adjustments
, false);
4811 if (!encountered_recursive_call
)
4814 FOR_EACH_BB (this_block
)
4816 gimple_stmt_iterator gsi
;
4818 for (gsi
= gsi_start_bb (this_block
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4820 gimple stmt
= gsi_stmt (gsi
);
4822 if (gimple_code (stmt
) != GIMPLE_CALL
)
4824 call_fndecl
= gimple_call_fndecl (stmt
);
4825 if (call_fndecl
== old_decl
)
4828 fprintf (dump_file
, "Adjusting recursive call");
4829 gimple_call_set_fndecl (stmt
, node
->decl
);
4830 ipa_modify_call_arguments (NULL
, stmt
, adjustments
);
4838 /* Perform all the modification required in IPA-SRA for NODE to have parameters
4839 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
4842 modify_function (struct cgraph_node
*node
, ipa_parm_adjustment_vec adjustments
)
4844 struct cgraph_node
*new_node
;
4846 vec
<cgraph_edge_p
> redirect_callers
= collect_callers_of_node (node
);
4848 rebuild_cgraph_edges ();
4849 free_dominance_info (CDI_DOMINATORS
);
4852 new_node
= cgraph_function_versioning (node
, redirect_callers
,
4854 NULL
, false, NULL
, NULL
, "isra");
4855 redirect_callers
.release ();
4857 push_cfun (DECL_STRUCT_FUNCTION (new_node
->decl
));
4858 ipa_modify_formal_parameters (current_function_decl
, adjustments
);
4859 cfg_changed
= ipa_sra_modify_function_body (adjustments
);
4860 sra_ipa_reset_debug_stmts (adjustments
);
4861 convert_callers (new_node
, node
->decl
, adjustments
);
4862 cgraph_make_node_local (new_node
);
4866 /* If NODE has a caller, return true. */
4869 has_caller_p (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
4876 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
4877 attributes, return true otherwise. NODE is the cgraph node of the current
4881 ipa_sra_preliminary_function_checks (struct cgraph_node
*node
)
4883 if (!cgraph_node_can_be_local_p (node
))
4886 fprintf (dump_file
, "Function not local to this compilation unit.\n");
4890 if (!node
->local
.can_change_signature
)
4893 fprintf (dump_file
, "Function can not change signature.\n");
4897 if (!tree_versionable_function_p (node
->decl
))
4900 fprintf (dump_file
, "Function is not versionable.\n");
4904 if (DECL_VIRTUAL_P (current_function_decl
))
4907 fprintf (dump_file
, "Function is a virtual method.\n");
4911 if ((DECL_COMDAT (node
->decl
) || DECL_EXTERNAL (node
->decl
))
4912 && inline_summary (node
)->size
>= MAX_INLINE_INSNS_AUTO
)
4915 fprintf (dump_file
, "Function too big to be made truly local.\n");
4919 if (!cgraph_for_node_and_aliases (node
, has_caller_p
, NULL
, true))
4923 "Function has no callers in this compilation unit.\n");
4930 fprintf (dump_file
, "Function uses stdarg. \n");
4934 if (TYPE_ATTRIBUTES (TREE_TYPE (node
->decl
)))
4940 /* Perform early interprocedural SRA. */
4943 ipa_early_sra (void)
4945 struct cgraph_node
*node
= cgraph_get_node (current_function_decl
);
4946 ipa_parm_adjustment_vec adjustments
;
4949 if (!ipa_sra_preliminary_function_checks (node
))
4953 sra_mode
= SRA_MODE_EARLY_IPA
;
4955 if (!find_param_candidates ())
4958 fprintf (dump_file
, "Function has no IPA-SRA candidates.\n");
4962 if (cgraph_for_node_and_aliases (node
, not_all_callers_have_enough_arguments_p
,
4966 fprintf (dump_file
, "There are callers with insufficient number of "
4971 bb_dereferences
= XCNEWVEC (HOST_WIDE_INT
,
4973 * last_basic_block_for_function (cfun
));
4974 final_bbs
= BITMAP_ALLOC (NULL
);
4977 if (encountered_apply_args
)
4980 fprintf (dump_file
, "Function calls __builtin_apply_args().\n");
4984 if (encountered_unchangable_recursive_call
)
4987 fprintf (dump_file
, "Function calls itself with insufficient "
4988 "number of arguments.\n");
4992 adjustments
= analyze_all_param_acesses ();
4993 if (!adjustments
.exists ())
4996 ipa_dump_param_adjustments (dump_file
, adjustments
, current_function_decl
);
4998 if (modify_function (node
, adjustments
))
4999 ret
= TODO_update_ssa
| TODO_cleanup_cfg
;
5001 ret
= TODO_update_ssa
;
5002 adjustments
.release ();
5004 statistics_counter_event (cfun
, "Unused parameters deleted",
5005 sra_stats
.deleted_unused_parameters
);
5006 statistics_counter_event (cfun
, "Scalar parameters converted to by-value",
5007 sra_stats
.scalar_by_ref_to_by_val
);
5008 statistics_counter_event (cfun
, "Aggregate parameters broken up",
5009 sra_stats
.aggregate_params_reduced
);
5010 statistics_counter_event (cfun
, "Aggregate parameter components created",
5011 sra_stats
.param_reductions_created
);
5014 BITMAP_FREE (final_bbs
);
5015 free (bb_dereferences
);
5017 sra_deinitialize ();
5021 /* Return if early ipa sra shall be performed. */
5023 ipa_early_sra_gate (void)
5025 return flag_ipa_sra
&& dbg_cnt (eipa_sra
);
5030 const pass_data pass_data_early_ipa_sra
=
5032 GIMPLE_PASS
, /* type */
5033 "eipa_sra", /* name */
5034 OPTGROUP_NONE
, /* optinfo_flags */
5035 true, /* has_gate */
5036 true, /* has_execute */
5037 TV_IPA_SRA
, /* tv_id */
5038 0, /* properties_required */
5039 0, /* properties_provided */
5040 0, /* properties_destroyed */
5041 0, /* todo_flags_start */
5042 TODO_dump_symtab
, /* todo_flags_finish */
5045 class pass_early_ipa_sra
: public gimple_opt_pass
5048 pass_early_ipa_sra (gcc::context
*ctxt
)
5049 : gimple_opt_pass (pass_data_early_ipa_sra
, ctxt
)
5052 /* opt_pass methods: */
5053 bool gate () { return ipa_early_sra_gate (); }
5054 unsigned int execute () { return ipa_early_sra (); }
5056 }; // class pass_early_ipa_sra
5061 make_pass_early_ipa_sra (gcc::context
*ctxt
)
5063 return new pass_early_ipa_sra (ctxt
);