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"
83 #include "gimple-iterator.h"
84 #include "gimplify-me.h"
85 #include "gimple-walk.h"
87 #include "gimple-ssa.h"
89 #include "tree-phinodes.h"
90 #include "ssa-iterators.h"
91 #include "tree-ssanames.h"
94 #include "tree-pass.h"
96 #include "statistics.h"
101 #include "tree-inline.h"
102 #include "gimple-pretty-print.h"
103 #include "ipa-inline.h"
104 #include "ipa-utils.h"
106 /* Enumeration of all aggregate reductions we can do. */
107 enum sra_mode
{ SRA_MODE_EARLY_IPA
, /* early call regularization */
108 SRA_MODE_EARLY_INTRA
, /* early intraprocedural SRA */
109 SRA_MODE_INTRA
}; /* late intraprocedural SRA */
111 /* Global variable describing which aggregate reduction we are performing at
113 static enum sra_mode sra_mode
;
117 /* ACCESS represents each access to an aggregate variable (as a whole or a
118 part). It can also represent a group of accesses that refer to exactly the
119 same fragment of an aggregate (i.e. those that have exactly the same offset
120 and size). Such representatives for a single aggregate, once determined,
121 are linked in a linked list and have the group fields set.
123 Moreover, when doing intraprocedural SRA, a tree is built from those
124 representatives (by the means of first_child and next_sibling pointers), in
125 which all items in a subtree are "within" the root, i.e. their offset is
126 greater or equal to offset of the root and offset+size is smaller or equal
127 to offset+size of the root. Children of an access are sorted by offset.
129 Note that accesses to parts of vector and complex number types always
130 represented by an access to the whole complex number or a vector. It is a
131 duty of the modifying functions to replace them appropriately. */
135 /* Values returned by `get_ref_base_and_extent' for each component reference
136 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
137 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
138 HOST_WIDE_INT offset
;
142 /* Expression. It is context dependent so do not use it to create new
143 expressions to access the original aggregate. See PR 42154 for a
149 /* The statement this access belongs to. */
152 /* Next group representative for this aggregate. */
153 struct access
*next_grp
;
155 /* Pointer to the group representative. Pointer to itself if the struct is
156 the representative. */
157 struct access
*group_representative
;
159 /* If this access has any children (in terms of the definition above), this
160 points to the first one. */
161 struct access
*first_child
;
163 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
164 described above. In IPA-SRA this is a pointer to the next access
165 belonging to the same group (having the same representative). */
166 struct access
*next_sibling
;
168 /* Pointers to the first and last element in the linked list of assign
170 struct assign_link
*first_link
, *last_link
;
172 /* Pointer to the next access in the work queue. */
173 struct access
*next_queued
;
175 /* Replacement variable for this access "region." Never to be accessed
176 directly, always only by the means of get_access_replacement() and only
177 when grp_to_be_replaced flag is set. */
178 tree replacement_decl
;
180 /* Is this particular access write access? */
183 /* Is this access an access to a non-addressable field? */
184 unsigned non_addressable
: 1;
186 /* Is this access currently in the work queue? */
187 unsigned grp_queued
: 1;
189 /* Does this group contain a write access? This flag is propagated down the
191 unsigned grp_write
: 1;
193 /* Does this group contain a read access? This flag is propagated down the
195 unsigned grp_read
: 1;
197 /* Does this group contain a read access that comes from an assignment
198 statement? This flag is propagated down the access tree. */
199 unsigned grp_assignment_read
: 1;
201 /* Does this group contain a write access that comes from an assignment
202 statement? This flag is propagated down the access tree. */
203 unsigned grp_assignment_write
: 1;
205 /* Does this group contain a read access through a scalar type? This flag is
206 not propagated in the access tree in any direction. */
207 unsigned grp_scalar_read
: 1;
209 /* Does this group contain a write access through a scalar type? This flag
210 is not propagated in the access tree in any direction. */
211 unsigned grp_scalar_write
: 1;
213 /* Is this access an artificial one created to scalarize some record
215 unsigned grp_total_scalarization
: 1;
217 /* Other passes of the analysis use this bit to make function
218 analyze_access_subtree create scalar replacements for this group if
220 unsigned grp_hint
: 1;
222 /* Is the subtree rooted in this access fully covered by scalar
224 unsigned grp_covered
: 1;
226 /* If set to true, this access and all below it in an access tree must not be
228 unsigned grp_unscalarizable_region
: 1;
230 /* Whether data have been written to parts of the aggregate covered by this
231 access which is not to be scalarized. This flag is propagated up in the
233 unsigned grp_unscalarized_data
: 1;
235 /* Does this access and/or group contain a write access through a
237 unsigned grp_partial_lhs
: 1;
239 /* Set when a scalar replacement should be created for this variable. */
240 unsigned grp_to_be_replaced
: 1;
242 /* Set when we want a replacement for the sole purpose of having it in
243 generated debug statements. */
244 unsigned grp_to_be_debug_replaced
: 1;
246 /* Should TREE_NO_WARNING of a replacement be set? */
247 unsigned grp_no_warning
: 1;
249 /* Is it possible that the group refers to data which might be (directly or
250 otherwise) modified? */
251 unsigned grp_maybe_modified
: 1;
253 /* Set when this is a representative of a pointer to scalar (i.e. by
254 reference) parameter which we consider for turning into a plain scalar
255 (i.e. a by value parameter). */
256 unsigned grp_scalar_ptr
: 1;
258 /* Set when we discover that this pointer is not safe to dereference in the
260 unsigned grp_not_necessarilly_dereferenced
: 1;
263 typedef struct access
*access_p
;
266 /* Alloc pool for allocating access structures. */
267 static alloc_pool access_pool
;
269 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
270 are used to propagate subaccesses from rhs to lhs as long as they don't
271 conflict with what is already there. */
274 struct access
*lacc
, *racc
;
275 struct assign_link
*next
;
278 /* Alloc pool for allocating assign link structures. */
279 static alloc_pool link_pool
;
281 /* Base (tree) -> Vector (vec<access_p> *) map. */
282 static struct pointer_map_t
*base_access_vec
;
284 /* Candidate hash table helpers. */
286 struct uid_decl_hasher
: typed_noop_remove
<tree_node
>
288 typedef tree_node value_type
;
289 typedef tree_node compare_type
;
290 static inline hashval_t
hash (const value_type
*);
291 static inline bool equal (const value_type
*, const compare_type
*);
294 /* Hash a tree in a uid_decl_map. */
297 uid_decl_hasher::hash (const value_type
*item
)
299 return item
->decl_minimal
.uid
;
302 /* Return true if the DECL_UID in both trees are equal. */
305 uid_decl_hasher::equal (const value_type
*a
, const compare_type
*b
)
307 return (a
->decl_minimal
.uid
== b
->decl_minimal
.uid
);
310 /* Set of candidates. */
311 static bitmap candidate_bitmap
;
312 static hash_table
<uid_decl_hasher
> candidates
;
314 /* For a candidate UID return the candidates decl. */
317 candidate (unsigned uid
)
320 t
.decl_minimal
.uid
= uid
;
321 return candidates
.find_with_hash (&t
, static_cast <hashval_t
> (uid
));
324 /* Bitmap of candidates which we should try to entirely scalarize away and
325 those which cannot be (because they are and need be used as a whole). */
326 static bitmap should_scalarize_away_bitmap
, cannot_scalarize_away_bitmap
;
328 /* Obstack for creation of fancy names. */
329 static struct obstack name_obstack
;
331 /* Head of a linked list of accesses that need to have its subaccesses
332 propagated to their assignment counterparts. */
333 static struct access
*work_queue_head
;
335 /* Number of parameters of the analyzed function when doing early ipa SRA. */
336 static int func_param_count
;
338 /* scan_function sets the following to true if it encounters a call to
339 __builtin_apply_args. */
340 static bool encountered_apply_args
;
342 /* Set by scan_function when it finds a recursive call. */
343 static bool encountered_recursive_call
;
345 /* Set by scan_function when it finds a recursive call with less actual
346 arguments than formal parameters.. */
347 static bool encountered_unchangable_recursive_call
;
349 /* This is a table in which for each basic block and parameter there is a
350 distance (offset + size) in that parameter which is dereferenced and
351 accessed in that BB. */
352 static HOST_WIDE_INT
*bb_dereferences
;
353 /* Bitmap of BBs that can cause the function to "stop" progressing by
354 returning, throwing externally, looping infinitely or calling a function
355 which might abort etc.. */
356 static bitmap final_bbs
;
358 /* Representative of no accesses at all. */
359 static struct access no_accesses_representant
;
361 /* Predicate to test the special value. */
364 no_accesses_p (struct access
*access
)
366 return access
== &no_accesses_representant
;
369 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
370 representative fields are dumped, otherwise those which only describe the
371 individual access are. */
375 /* Number of processed aggregates is readily available in
376 analyze_all_variable_accesses and so is not stored here. */
378 /* Number of created scalar replacements. */
381 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
385 /* Number of statements created by generate_subtree_copies. */
388 /* Number of statements created by load_assign_lhs_subreplacements. */
391 /* Number of times sra_modify_assign has deleted a statement. */
394 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
395 RHS reparately due to type conversions or nonexistent matching
397 int separate_lhs_rhs_handling
;
399 /* Number of parameters that were removed because they were unused. */
400 int deleted_unused_parameters
;
402 /* Number of scalars passed as parameters by reference that have been
403 converted to be passed by value. */
404 int scalar_by_ref_to_by_val
;
406 /* Number of aggregate parameters that were replaced by one or more of their
408 int aggregate_params_reduced
;
410 /* Numbber of components created when splitting aggregate parameters. */
411 int param_reductions_created
;
415 dump_access (FILE *f
, struct access
*access
, bool grp
)
417 fprintf (f
, "access { ");
418 fprintf (f
, "base = (%d)'", DECL_UID (access
->base
));
419 print_generic_expr (f
, access
->base
, 0);
420 fprintf (f
, "', offset = " HOST_WIDE_INT_PRINT_DEC
, access
->offset
);
421 fprintf (f
, ", size = " HOST_WIDE_INT_PRINT_DEC
, access
->size
);
422 fprintf (f
, ", expr = ");
423 print_generic_expr (f
, access
->expr
, 0);
424 fprintf (f
, ", type = ");
425 print_generic_expr (f
, access
->type
, 0);
427 fprintf (f
, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
428 "grp_assignment_write = %d, grp_scalar_read = %d, "
429 "grp_scalar_write = %d, grp_total_scalarization = %d, "
430 "grp_hint = %d, grp_covered = %d, "
431 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
432 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
433 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
434 "grp_not_necessarilly_dereferenced = %d\n",
435 access
->grp_read
, access
->grp_write
, access
->grp_assignment_read
,
436 access
->grp_assignment_write
, access
->grp_scalar_read
,
437 access
->grp_scalar_write
, access
->grp_total_scalarization
,
438 access
->grp_hint
, access
->grp_covered
,
439 access
->grp_unscalarizable_region
, access
->grp_unscalarized_data
,
440 access
->grp_partial_lhs
, access
->grp_to_be_replaced
,
441 access
->grp_to_be_debug_replaced
, access
->grp_maybe_modified
,
442 access
->grp_not_necessarilly_dereferenced
);
444 fprintf (f
, ", write = %d, grp_total_scalarization = %d, "
445 "grp_partial_lhs = %d\n",
446 access
->write
, access
->grp_total_scalarization
,
447 access
->grp_partial_lhs
);
450 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
453 dump_access_tree_1 (FILE *f
, struct access
*access
, int level
)
459 for (i
= 0; i
< level
; i
++)
460 fputs ("* ", dump_file
);
462 dump_access (f
, access
, true);
464 if (access
->first_child
)
465 dump_access_tree_1 (f
, access
->first_child
, level
+ 1);
467 access
= access
->next_sibling
;
472 /* Dump all access trees for a variable, given the pointer to the first root in
476 dump_access_tree (FILE *f
, struct access
*access
)
478 for (; access
; access
= access
->next_grp
)
479 dump_access_tree_1 (f
, access
, 0);
482 /* Return true iff ACC is non-NULL and has subaccesses. */
485 access_has_children_p (struct access
*acc
)
487 return acc
&& acc
->first_child
;
490 /* Return true iff ACC is (partly) covered by at least one replacement. */
493 access_has_replacements_p (struct access
*acc
)
495 struct access
*child
;
496 if (acc
->grp_to_be_replaced
)
498 for (child
= acc
->first_child
; child
; child
= child
->next_sibling
)
499 if (access_has_replacements_p (child
))
504 /* Return a vector of pointers to accesses for the variable given in BASE or
505 NULL if there is none. */
507 static vec
<access_p
> *
508 get_base_access_vector (tree base
)
512 slot
= pointer_map_contains (base_access_vec
, base
);
516 return *(vec
<access_p
> **) slot
;
519 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
520 in ACCESS. Return NULL if it cannot be found. */
522 static struct access
*
523 find_access_in_subtree (struct access
*access
, HOST_WIDE_INT offset
,
526 while (access
&& (access
->offset
!= offset
|| access
->size
!= size
))
528 struct access
*child
= access
->first_child
;
530 while (child
&& (child
->offset
+ child
->size
<= offset
))
531 child
= child
->next_sibling
;
538 /* Return the first group representative for DECL or NULL if none exists. */
540 static struct access
*
541 get_first_repr_for_decl (tree base
)
543 vec
<access_p
> *access_vec
;
545 access_vec
= get_base_access_vector (base
);
549 return (*access_vec
)[0];
552 /* Find an access representative for the variable BASE and given OFFSET and
553 SIZE. Requires that access trees have already been built. Return NULL if
554 it cannot be found. */
556 static struct access
*
557 get_var_base_offset_size_access (tree base
, HOST_WIDE_INT offset
,
560 struct access
*access
;
562 access
= get_first_repr_for_decl (base
);
563 while (access
&& (access
->offset
+ access
->size
<= offset
))
564 access
= access
->next_grp
;
568 return find_access_in_subtree (access
, offset
, size
);
571 /* Add LINK to the linked list of assign links of RACC. */
573 add_link_to_rhs (struct access
*racc
, struct assign_link
*link
)
575 gcc_assert (link
->racc
== racc
);
577 if (!racc
->first_link
)
579 gcc_assert (!racc
->last_link
);
580 racc
->first_link
= link
;
583 racc
->last_link
->next
= link
;
585 racc
->last_link
= link
;
589 /* Move all link structures in their linked list in OLD_RACC to the linked list
592 relink_to_new_repr (struct access
*new_racc
, struct access
*old_racc
)
594 if (!old_racc
->first_link
)
596 gcc_assert (!old_racc
->last_link
);
600 if (new_racc
->first_link
)
602 gcc_assert (!new_racc
->last_link
->next
);
603 gcc_assert (!old_racc
->last_link
|| !old_racc
->last_link
->next
);
605 new_racc
->last_link
->next
= old_racc
->first_link
;
606 new_racc
->last_link
= old_racc
->last_link
;
610 gcc_assert (!new_racc
->last_link
);
612 new_racc
->first_link
= old_racc
->first_link
;
613 new_racc
->last_link
= old_racc
->last_link
;
615 old_racc
->first_link
= old_racc
->last_link
= NULL
;
618 /* Add ACCESS to the work queue (which is actually a stack). */
621 add_access_to_work_queue (struct access
*access
)
623 if (!access
->grp_queued
)
625 gcc_assert (!access
->next_queued
);
626 access
->next_queued
= work_queue_head
;
627 access
->grp_queued
= 1;
628 work_queue_head
= access
;
632 /* Pop an access from the work queue, and return it, assuming there is one. */
634 static struct access
*
635 pop_access_from_work_queue (void)
637 struct access
*access
= work_queue_head
;
639 work_queue_head
= access
->next_queued
;
640 access
->next_queued
= NULL
;
641 access
->grp_queued
= 0;
646 /* Allocate necessary structures. */
649 sra_initialize (void)
651 candidate_bitmap
= BITMAP_ALLOC (NULL
);
652 candidates
.create (vec_safe_length (cfun
->local_decls
) / 2);
653 should_scalarize_away_bitmap
= BITMAP_ALLOC (NULL
);
654 cannot_scalarize_away_bitmap
= BITMAP_ALLOC (NULL
);
655 gcc_obstack_init (&name_obstack
);
656 access_pool
= create_alloc_pool ("SRA accesses", sizeof (struct access
), 16);
657 link_pool
= create_alloc_pool ("SRA links", sizeof (struct assign_link
), 16);
658 base_access_vec
= pointer_map_create ();
659 memset (&sra_stats
, 0, sizeof (sra_stats
));
660 encountered_apply_args
= false;
661 encountered_recursive_call
= false;
662 encountered_unchangable_recursive_call
= false;
665 /* Hook fed to pointer_map_traverse, deallocate stored vectors. */
668 delete_base_accesses (const void *key ATTRIBUTE_UNUSED
, void **value
,
669 void *data ATTRIBUTE_UNUSED
)
671 vec
<access_p
> *access_vec
= (vec
<access_p
> *) *value
;
672 vec_free (access_vec
);
676 /* Deallocate all general structures. */
679 sra_deinitialize (void)
681 BITMAP_FREE (candidate_bitmap
);
682 candidates
.dispose ();
683 BITMAP_FREE (should_scalarize_away_bitmap
);
684 BITMAP_FREE (cannot_scalarize_away_bitmap
);
685 free_alloc_pool (access_pool
);
686 free_alloc_pool (link_pool
);
687 obstack_free (&name_obstack
, NULL
);
689 pointer_map_traverse (base_access_vec
, delete_base_accesses
, NULL
);
690 pointer_map_destroy (base_access_vec
);
693 /* Remove DECL from candidates for SRA and write REASON to the dump file if
696 disqualify_candidate (tree decl
, const char *reason
)
698 if (bitmap_clear_bit (candidate_bitmap
, DECL_UID (decl
)))
699 candidates
.clear_slot (candidates
.find_slot_with_hash (decl
,
703 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
705 fprintf (dump_file
, "! Disqualifying ");
706 print_generic_expr (dump_file
, decl
, 0);
707 fprintf (dump_file
, " - %s\n", reason
);
711 /* Return true iff the type contains a field or an element which does not allow
715 type_internals_preclude_sra_p (tree type
, const char **msg
)
720 switch (TREE_CODE (type
))
724 case QUAL_UNION_TYPE
:
725 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
726 if (TREE_CODE (fld
) == FIELD_DECL
)
728 tree ft
= TREE_TYPE (fld
);
730 if (TREE_THIS_VOLATILE (fld
))
732 *msg
= "volatile structure field";
735 if (!DECL_FIELD_OFFSET (fld
))
737 *msg
= "no structure field offset";
740 if (!DECL_SIZE (fld
))
742 *msg
= "zero structure field size";
745 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
747 *msg
= "structure field offset not fixed";
750 if (!tree_fits_uhwi_p (DECL_SIZE (fld
)))
752 *msg
= "structure field size not fixed";
755 if (!tree_fits_shwi_p (bit_position (fld
)))
757 *msg
= "structure field size too big";
760 if (AGGREGATE_TYPE_P (ft
)
761 && int_bit_position (fld
) % BITS_PER_UNIT
!= 0)
763 *msg
= "structure field is bit field";
767 if (AGGREGATE_TYPE_P (ft
) && type_internals_preclude_sra_p (ft
, msg
))
774 et
= TREE_TYPE (type
);
776 if (TYPE_VOLATILE (et
))
778 *msg
= "element type is volatile";
782 if (AGGREGATE_TYPE_P (et
) && type_internals_preclude_sra_p (et
, msg
))
792 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
793 base variable if it is. Return T if it is not an SSA_NAME. */
796 get_ssa_base_param (tree t
)
798 if (TREE_CODE (t
) == SSA_NAME
)
800 if (SSA_NAME_IS_DEFAULT_DEF (t
))
801 return SSA_NAME_VAR (t
);
808 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
809 belongs to, unless the BB has already been marked as a potentially
813 mark_parm_dereference (tree base
, HOST_WIDE_INT dist
, gimple stmt
)
815 basic_block bb
= gimple_bb (stmt
);
816 int idx
, parm_index
= 0;
819 if (bitmap_bit_p (final_bbs
, bb
->index
))
822 for (parm
= DECL_ARGUMENTS (current_function_decl
);
823 parm
&& parm
!= base
;
824 parm
= DECL_CHAIN (parm
))
827 gcc_assert (parm_index
< func_param_count
);
829 idx
= bb
->index
* func_param_count
+ parm_index
;
830 if (bb_dereferences
[idx
] < dist
)
831 bb_dereferences
[idx
] = dist
;
834 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
835 the three fields. Also add it to the vector of accesses corresponding to
836 the base. Finally, return the new access. */
838 static struct access
*
839 create_access_1 (tree base
, HOST_WIDE_INT offset
, HOST_WIDE_INT size
)
842 struct access
*access
;
845 access
= (struct access
*) pool_alloc (access_pool
);
846 memset (access
, 0, sizeof (struct access
));
848 access
->offset
= offset
;
851 slot
= pointer_map_contains (base_access_vec
, base
);
853 v
= (vec
<access_p
> *) *slot
;
857 v
->safe_push (access
);
860 pointer_map_insert (base_access_vec
, base
)) = v
;
865 /* Create and insert access for EXPR. Return created access, or NULL if it is
868 static struct access
*
869 create_access (tree expr
, gimple stmt
, bool write
)
871 struct access
*access
;
872 HOST_WIDE_INT offset
, size
, max_size
;
874 bool ptr
, unscalarizable_region
= false;
876 base
= get_ref_base_and_extent (expr
, &offset
, &size
, &max_size
);
878 if (sra_mode
== SRA_MODE_EARLY_IPA
879 && TREE_CODE (base
) == MEM_REF
)
881 base
= get_ssa_base_param (TREE_OPERAND (base
, 0));
889 if (!DECL_P (base
) || !bitmap_bit_p (candidate_bitmap
, DECL_UID (base
)))
892 if (sra_mode
== SRA_MODE_EARLY_IPA
)
894 if (size
< 0 || size
!= max_size
)
896 disqualify_candidate (base
, "Encountered a variable sized access.");
899 if (TREE_CODE (expr
) == COMPONENT_REF
900 && DECL_BIT_FIELD (TREE_OPERAND (expr
, 1)))
902 disqualify_candidate (base
, "Encountered a bit-field access.");
905 gcc_checking_assert ((offset
% BITS_PER_UNIT
) == 0);
908 mark_parm_dereference (base
, offset
+ size
, stmt
);
912 if (size
!= max_size
)
915 unscalarizable_region
= true;
919 disqualify_candidate (base
, "Encountered an unconstrained access.");
924 access
= create_access_1 (base
, offset
, size
);
926 access
->type
= TREE_TYPE (expr
);
927 access
->write
= write
;
928 access
->grp_unscalarizable_region
= unscalarizable_region
;
931 if (TREE_CODE (expr
) == COMPONENT_REF
932 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr
, 1)))
933 access
->non_addressable
= 1;
939 /* Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple
940 register types or (recursively) records with only these two kinds of fields.
941 It also returns false if any of these records contains a bit-field. */
944 type_consists_of_records_p (tree type
)
948 if (TREE_CODE (type
) != RECORD_TYPE
)
951 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
952 if (TREE_CODE (fld
) == FIELD_DECL
)
954 tree ft
= TREE_TYPE (fld
);
956 if (DECL_BIT_FIELD (fld
))
959 if (!is_gimple_reg_type (ft
)
960 && !type_consists_of_records_p (ft
))
967 /* Create total_scalarization accesses for all scalar type fields in DECL that
968 must be of a RECORD_TYPE conforming to type_consists_of_records_p. BASE
969 must be the top-most VAR_DECL representing the variable, OFFSET must be the
970 offset of DECL within BASE. REF must be the memory reference expression for
974 completely_scalarize_record (tree base
, tree decl
, HOST_WIDE_INT offset
,
977 tree fld
, decl_type
= TREE_TYPE (decl
);
979 for (fld
= TYPE_FIELDS (decl_type
); fld
; fld
= DECL_CHAIN (fld
))
980 if (TREE_CODE (fld
) == FIELD_DECL
)
982 HOST_WIDE_INT pos
= offset
+ int_bit_position (fld
);
983 tree ft
= TREE_TYPE (fld
);
984 tree nref
= build3 (COMPONENT_REF
, TREE_TYPE (fld
), ref
, fld
,
987 if (is_gimple_reg_type (ft
))
989 struct access
*access
;
992 size
= tree_to_uhwi (DECL_SIZE (fld
));
993 access
= create_access_1 (base
, pos
, size
);
996 access
->grp_total_scalarization
= 1;
997 /* Accesses for intraprocedural SRA can have their stmt NULL. */
1000 completely_scalarize_record (base
, fld
, pos
, nref
);
1004 /* Create total_scalarization accesses for all scalar type fields in VAR and
1005 for VAR a a whole. VAR must be of a RECORD_TYPE conforming to
1006 type_consists_of_records_p. */
1009 completely_scalarize_var (tree var
)
1011 HOST_WIDE_INT size
= tree_to_uhwi (DECL_SIZE (var
));
1012 struct access
*access
;
1014 access
= create_access_1 (var
, 0, size
);
1016 access
->type
= TREE_TYPE (var
);
1017 access
->grp_total_scalarization
= 1;
1019 completely_scalarize_record (var
, var
, 0, var
);
1022 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1025 contains_view_convert_expr_p (const_tree ref
)
1027 while (handled_component_p (ref
))
1029 if (TREE_CODE (ref
) == VIEW_CONVERT_EXPR
)
1031 ref
= TREE_OPERAND (ref
, 0);
1037 /* Search the given tree for a declaration by skipping handled components and
1038 exclude it from the candidates. */
1041 disqualify_base_of_expr (tree t
, const char *reason
)
1043 t
= get_base_address (t
);
1044 if (sra_mode
== SRA_MODE_EARLY_IPA
1045 && TREE_CODE (t
) == MEM_REF
)
1046 t
= get_ssa_base_param (TREE_OPERAND (t
, 0));
1048 if (t
&& DECL_P (t
))
1049 disqualify_candidate (t
, reason
);
1052 /* Scan expression EXPR and create access structures for all accesses to
1053 candidates for scalarization. Return the created access or NULL if none is
1056 static struct access
*
1057 build_access_from_expr_1 (tree expr
, gimple stmt
, bool write
)
1059 struct access
*ret
= NULL
;
1062 if (TREE_CODE (expr
) == BIT_FIELD_REF
1063 || TREE_CODE (expr
) == IMAGPART_EXPR
1064 || TREE_CODE (expr
) == REALPART_EXPR
)
1066 expr
= TREE_OPERAND (expr
, 0);
1070 partial_ref
= false;
1072 /* We need to dive through V_C_Es in order to get the size of its parameter
1073 and not the result type. Ada produces such statements. We are also
1074 capable of handling the topmost V_C_E but not any of those buried in other
1075 handled components. */
1076 if (TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
1077 expr
= TREE_OPERAND (expr
, 0);
1079 if (contains_view_convert_expr_p (expr
))
1081 disqualify_base_of_expr (expr
, "V_C_E under a different handled "
1086 switch (TREE_CODE (expr
))
1089 if (TREE_CODE (TREE_OPERAND (expr
, 0)) != ADDR_EXPR
1090 && sra_mode
!= SRA_MODE_EARLY_IPA
)
1098 case ARRAY_RANGE_REF
:
1099 ret
= create_access (expr
, stmt
, write
);
1106 if (write
&& partial_ref
&& ret
)
1107 ret
->grp_partial_lhs
= 1;
1112 /* Scan expression EXPR and create access structures for all accesses to
1113 candidates for scalarization. Return true if any access has been inserted.
1114 STMT must be the statement from which the expression is taken, WRITE must be
1115 true if the expression is a store and false otherwise. */
1118 build_access_from_expr (tree expr
, gimple stmt
, bool write
)
1120 struct access
*access
;
1122 access
= build_access_from_expr_1 (expr
, stmt
, write
);
1125 /* This means the aggregate is accesses as a whole in a way other than an
1126 assign statement and thus cannot be removed even if we had a scalar
1127 replacement for everything. */
1128 if (cannot_scalarize_away_bitmap
)
1129 bitmap_set_bit (cannot_scalarize_away_bitmap
, DECL_UID (access
->base
));
1135 /* Disqualify LHS and RHS for scalarization if STMT must end its basic block in
1136 modes in which it matters, return true iff they have been disqualified. RHS
1137 may be NULL, in that case ignore it. If we scalarize an aggregate in
1138 intra-SRA we may need to add statements after each statement. This is not
1139 possible if a statement unconditionally has to end the basic block. */
1141 disqualify_ops_if_throwing_stmt (gimple stmt
, tree lhs
, tree rhs
)
1143 if ((sra_mode
== SRA_MODE_EARLY_INTRA
|| sra_mode
== SRA_MODE_INTRA
)
1144 && (stmt_can_throw_internal (stmt
) || stmt_ends_bb_p (stmt
)))
1146 disqualify_base_of_expr (lhs
, "LHS of a throwing stmt.");
1148 disqualify_base_of_expr (rhs
, "RHS of a throwing stmt.");
1154 /* Scan expressions occurring in STMT, create access structures for all accesses
1155 to candidates for scalarization and remove those candidates which occur in
1156 statements or expressions that prevent them from being split apart. Return
1157 true if any access has been inserted. */
1160 build_accesses_from_assign (gimple stmt
)
1163 struct access
*lacc
, *racc
;
1165 if (!gimple_assign_single_p (stmt
)
1166 /* Scope clobbers don't influence scalarization. */
1167 || gimple_clobber_p (stmt
))
1170 lhs
= gimple_assign_lhs (stmt
);
1171 rhs
= gimple_assign_rhs1 (stmt
);
1173 if (disqualify_ops_if_throwing_stmt (stmt
, lhs
, rhs
))
1176 racc
= build_access_from_expr_1 (rhs
, stmt
, false);
1177 lacc
= build_access_from_expr_1 (lhs
, stmt
, true);
1180 lacc
->grp_assignment_write
= 1;
1184 racc
->grp_assignment_read
= 1;
1185 if (should_scalarize_away_bitmap
&& !gimple_has_volatile_ops (stmt
)
1186 && !is_gimple_reg_type (racc
->type
))
1187 bitmap_set_bit (should_scalarize_away_bitmap
, DECL_UID (racc
->base
));
1191 && (sra_mode
== SRA_MODE_EARLY_INTRA
|| sra_mode
== SRA_MODE_INTRA
)
1192 && !lacc
->grp_unscalarizable_region
1193 && !racc
->grp_unscalarizable_region
1194 && AGGREGATE_TYPE_P (TREE_TYPE (lhs
))
1195 && lacc
->size
== racc
->size
1196 && useless_type_conversion_p (lacc
->type
, racc
->type
))
1198 struct assign_link
*link
;
1200 link
= (struct assign_link
*) pool_alloc (link_pool
);
1201 memset (link
, 0, sizeof (struct assign_link
));
1206 add_link_to_rhs (racc
, link
);
1209 return lacc
|| racc
;
1212 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1213 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1216 asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED
, tree op
,
1217 void *data ATTRIBUTE_UNUSED
)
1219 op
= get_base_address (op
);
1222 disqualify_candidate (op
, "Non-scalarizable GIMPLE_ASM operand.");
1227 /* Return true iff callsite CALL has at least as many actual arguments as there
1228 are formal parameters of the function currently processed by IPA-SRA. */
1231 callsite_has_enough_arguments_p (gimple call
)
1233 return gimple_call_num_args (call
) >= (unsigned) func_param_count
;
1236 /* Scan function and look for interesting expressions and create access
1237 structures for them. Return true iff any access is created. */
1240 scan_function (void)
1247 gimple_stmt_iterator gsi
;
1248 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1250 gimple stmt
= gsi_stmt (gsi
);
1254 if (final_bbs
&& stmt_can_throw_external (stmt
))
1255 bitmap_set_bit (final_bbs
, bb
->index
);
1256 switch (gimple_code (stmt
))
1259 t
= gimple_return_retval (stmt
);
1261 ret
|= build_access_from_expr (t
, stmt
, false);
1263 bitmap_set_bit (final_bbs
, bb
->index
);
1267 ret
|= build_accesses_from_assign (stmt
);
1271 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1272 ret
|= build_access_from_expr (gimple_call_arg (stmt
, i
),
1275 if (sra_mode
== SRA_MODE_EARLY_IPA
)
1277 tree dest
= gimple_call_fndecl (stmt
);
1278 int flags
= gimple_call_flags (stmt
);
1282 if (DECL_BUILT_IN_CLASS (dest
) == BUILT_IN_NORMAL
1283 && DECL_FUNCTION_CODE (dest
) == BUILT_IN_APPLY_ARGS
)
1284 encountered_apply_args
= true;
1285 if (recursive_call_p (current_function_decl
, dest
))
1287 encountered_recursive_call
= true;
1288 if (!callsite_has_enough_arguments_p (stmt
))
1289 encountered_unchangable_recursive_call
= true;
1294 && (flags
& (ECF_CONST
| ECF_PURE
)) == 0)
1295 bitmap_set_bit (final_bbs
, bb
->index
);
1298 t
= gimple_call_lhs (stmt
);
1299 if (t
&& !disqualify_ops_if_throwing_stmt (stmt
, t
, NULL
))
1300 ret
|= build_access_from_expr (t
, stmt
, true);
1304 walk_stmt_load_store_addr_ops (stmt
, NULL
, NULL
, NULL
,
1307 bitmap_set_bit (final_bbs
, bb
->index
);
1309 for (i
= 0; i
< gimple_asm_ninputs (stmt
); i
++)
1311 t
= TREE_VALUE (gimple_asm_input_op (stmt
, i
));
1312 ret
|= build_access_from_expr (t
, stmt
, false);
1314 for (i
= 0; i
< gimple_asm_noutputs (stmt
); i
++)
1316 t
= TREE_VALUE (gimple_asm_output_op (stmt
, i
));
1317 ret
|= build_access_from_expr (t
, stmt
, true);
1330 /* Helper of QSORT function. There are pointers to accesses in the array. An
1331 access is considered smaller than another if it has smaller offset or if the
1332 offsets are the same but is size is bigger. */
1335 compare_access_positions (const void *a
, const void *b
)
1337 const access_p
*fp1
= (const access_p
*) a
;
1338 const access_p
*fp2
= (const access_p
*) b
;
1339 const access_p f1
= *fp1
;
1340 const access_p f2
= *fp2
;
1342 if (f1
->offset
!= f2
->offset
)
1343 return f1
->offset
< f2
->offset
? -1 : 1;
1345 if (f1
->size
== f2
->size
)
1347 if (f1
->type
== f2
->type
)
1349 /* Put any non-aggregate type before any aggregate type. */
1350 else if (!is_gimple_reg_type (f1
->type
)
1351 && is_gimple_reg_type (f2
->type
))
1353 else if (is_gimple_reg_type (f1
->type
)
1354 && !is_gimple_reg_type (f2
->type
))
1356 /* Put any complex or vector type before any other scalar type. */
1357 else if (TREE_CODE (f1
->type
) != COMPLEX_TYPE
1358 && TREE_CODE (f1
->type
) != VECTOR_TYPE
1359 && (TREE_CODE (f2
->type
) == COMPLEX_TYPE
1360 || TREE_CODE (f2
->type
) == VECTOR_TYPE
))
1362 else if ((TREE_CODE (f1
->type
) == COMPLEX_TYPE
1363 || TREE_CODE (f1
->type
) == VECTOR_TYPE
)
1364 && TREE_CODE (f2
->type
) != COMPLEX_TYPE
1365 && TREE_CODE (f2
->type
) != VECTOR_TYPE
)
1367 /* Put the integral type with the bigger precision first. */
1368 else if (INTEGRAL_TYPE_P (f1
->type
)
1369 && INTEGRAL_TYPE_P (f2
->type
))
1370 return TYPE_PRECISION (f2
->type
) - TYPE_PRECISION (f1
->type
);
1371 /* Put any integral type with non-full precision last. */
1372 else if (INTEGRAL_TYPE_P (f1
->type
)
1373 && (TREE_INT_CST_LOW (TYPE_SIZE (f1
->type
))
1374 != TYPE_PRECISION (f1
->type
)))
1376 else if (INTEGRAL_TYPE_P (f2
->type
)
1377 && (TREE_INT_CST_LOW (TYPE_SIZE (f2
->type
))
1378 != TYPE_PRECISION (f2
->type
)))
1380 /* Stabilize the sort. */
1381 return TYPE_UID (f1
->type
) - TYPE_UID (f2
->type
);
1384 /* We want the bigger accesses first, thus the opposite operator in the next
1386 return f1
->size
> f2
->size
? -1 : 1;
1390 /* Append a name of the declaration to the name obstack. A helper function for
1394 make_fancy_decl_name (tree decl
)
1398 tree name
= DECL_NAME (decl
);
1400 obstack_grow (&name_obstack
, IDENTIFIER_POINTER (name
),
1401 IDENTIFIER_LENGTH (name
));
1404 sprintf (buffer
, "D%u", DECL_UID (decl
));
1405 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1409 /* Helper for make_fancy_name. */
1412 make_fancy_name_1 (tree expr
)
1419 make_fancy_decl_name (expr
);
1423 switch (TREE_CODE (expr
))
1426 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1427 obstack_1grow (&name_obstack
, '$');
1428 make_fancy_decl_name (TREE_OPERAND (expr
, 1));
1432 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1433 obstack_1grow (&name_obstack
, '$');
1434 /* Arrays with only one element may not have a constant as their
1436 index
= TREE_OPERAND (expr
, 1);
1437 if (TREE_CODE (index
) != INTEGER_CST
)
1439 sprintf (buffer
, HOST_WIDE_INT_PRINT_DEC
, TREE_INT_CST_LOW (index
));
1440 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1444 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1448 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1449 if (!integer_zerop (TREE_OPERAND (expr
, 1)))
1451 obstack_1grow (&name_obstack
, '$');
1452 sprintf (buffer
, HOST_WIDE_INT_PRINT_DEC
,
1453 TREE_INT_CST_LOW (TREE_OPERAND (expr
, 1)));
1454 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1461 gcc_unreachable (); /* we treat these as scalars. */
1468 /* Create a human readable name for replacement variable of ACCESS. */
1471 make_fancy_name (tree expr
)
1473 make_fancy_name_1 (expr
);
1474 obstack_1grow (&name_obstack
, '\0');
1475 return XOBFINISH (&name_obstack
, char *);
1478 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1479 EXP_TYPE at the given OFFSET. If BASE is something for which
1480 get_addr_base_and_unit_offset returns NULL, gsi must be non-NULL and is used
1481 to insert new statements either before or below the current one as specified
1482 by INSERT_AFTER. This function is not capable of handling bitfields.
1484 BASE must be either a declaration or a memory reference that has correct
1485 alignment ifformation embeded in it (e.g. a pre-existing one in SRA). */
1488 build_ref_for_offset (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1489 tree exp_type
, gimple_stmt_iterator
*gsi
,
1492 tree prev_base
= base
;
1495 HOST_WIDE_INT base_offset
;
1496 unsigned HOST_WIDE_INT misalign
;
1499 gcc_checking_assert (offset
% BITS_PER_UNIT
== 0);
1500 get_object_alignment_1 (base
, &align
, &misalign
);
1501 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
1503 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1504 offset such as array[var_index]. */
1510 gcc_checking_assert (gsi
);
1511 tmp
= make_ssa_name (build_pointer_type (TREE_TYPE (prev_base
)), NULL
);
1512 addr
= build_fold_addr_expr (unshare_expr (prev_base
));
1513 STRIP_USELESS_TYPE_CONVERSION (addr
);
1514 stmt
= gimple_build_assign (tmp
, addr
);
1515 gimple_set_location (stmt
, loc
);
1517 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
1519 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
1521 off
= build_int_cst (reference_alias_ptr_type (prev_base
),
1522 offset
/ BITS_PER_UNIT
);
1525 else if (TREE_CODE (base
) == MEM_REF
)
1527 off
= build_int_cst (TREE_TYPE (TREE_OPERAND (base
, 1)),
1528 base_offset
+ offset
/ BITS_PER_UNIT
);
1529 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1), off
);
1530 base
= unshare_expr (TREE_OPERAND (base
, 0));
1534 off
= build_int_cst (reference_alias_ptr_type (base
),
1535 base_offset
+ offset
/ BITS_PER_UNIT
);
1536 base
= build_fold_addr_expr (unshare_expr (base
));
1539 misalign
= (misalign
+ offset
) & (align
- 1);
1541 align
= (misalign
& -misalign
);
1542 if (align
< TYPE_ALIGN (exp_type
))
1543 exp_type
= build_aligned_type (exp_type
, align
);
1545 mem_ref
= fold_build2_loc (loc
, MEM_REF
, exp_type
, base
, off
);
1546 if (TREE_THIS_VOLATILE (prev_base
))
1547 TREE_THIS_VOLATILE (mem_ref
) = 1;
1548 if (TREE_SIDE_EFFECTS (prev_base
))
1549 TREE_SIDE_EFFECTS (mem_ref
) = 1;
1553 /* Construct a memory reference to a part of an aggregate BASE at the given
1554 OFFSET and of the same type as MODEL. In case this is a reference to a
1555 bit-field, the function will replicate the last component_ref of model's
1556 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1557 build_ref_for_offset. */
1560 build_ref_for_model (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1561 struct access
*model
, gimple_stmt_iterator
*gsi
,
1564 if (TREE_CODE (model
->expr
) == COMPONENT_REF
1565 && DECL_BIT_FIELD (TREE_OPERAND (model
->expr
, 1)))
1567 /* This access represents a bit-field. */
1568 tree t
, exp_type
, fld
= TREE_OPERAND (model
->expr
, 1);
1570 offset
-= int_bit_position (fld
);
1571 exp_type
= TREE_TYPE (TREE_OPERAND (model
->expr
, 0));
1572 t
= build_ref_for_offset (loc
, base
, offset
, exp_type
, gsi
, insert_after
);
1573 return fold_build3_loc (loc
, COMPONENT_REF
, TREE_TYPE (fld
), t
, fld
,
1577 return build_ref_for_offset (loc
, base
, offset
, model
->type
,
1581 /* Attempt to build a memory reference that we could but into a gimple
1582 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1583 create statements and return s NULL instead. This function also ignores
1584 alignment issues and so its results should never end up in non-debug
1588 build_debug_ref_for_model (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1589 struct access
*model
)
1591 HOST_WIDE_INT base_offset
;
1594 if (TREE_CODE (model
->expr
) == COMPONENT_REF
1595 && DECL_BIT_FIELD (TREE_OPERAND (model
->expr
, 1)))
1598 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
1601 if (TREE_CODE (base
) == MEM_REF
)
1603 off
= build_int_cst (TREE_TYPE (TREE_OPERAND (base
, 1)),
1604 base_offset
+ offset
/ BITS_PER_UNIT
);
1605 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1), off
);
1606 base
= unshare_expr (TREE_OPERAND (base
, 0));
1610 off
= build_int_cst (reference_alias_ptr_type (base
),
1611 base_offset
+ offset
/ BITS_PER_UNIT
);
1612 base
= build_fold_addr_expr (unshare_expr (base
));
1615 return fold_build2_loc (loc
, MEM_REF
, model
->type
, base
, off
);
1618 /* Construct a memory reference consisting of component_refs and array_refs to
1619 a part of an aggregate *RES (which is of type TYPE). The requested part
1620 should have type EXP_TYPE at be the given OFFSET. This function might not
1621 succeed, it returns true when it does and only then *RES points to something
1622 meaningful. This function should be used only to build expressions that we
1623 might need to present to user (e.g. in warnings). In all other situations,
1624 build_ref_for_model or build_ref_for_offset should be used instead. */
1627 build_user_friendly_ref_for_offset (tree
*res
, tree type
, HOST_WIDE_INT offset
,
1633 tree tr_size
, index
, minidx
;
1634 HOST_WIDE_INT el_size
;
1636 if (offset
== 0 && exp_type
1637 && types_compatible_p (exp_type
, type
))
1640 switch (TREE_CODE (type
))
1643 case QUAL_UNION_TYPE
:
1645 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
1647 HOST_WIDE_INT pos
, size
;
1648 tree tr_pos
, expr
, *expr_ptr
;
1650 if (TREE_CODE (fld
) != FIELD_DECL
)
1653 tr_pos
= bit_position (fld
);
1654 if (!tr_pos
|| !tree_fits_uhwi_p (tr_pos
))
1656 pos
= TREE_INT_CST_LOW (tr_pos
);
1657 gcc_assert (TREE_CODE (type
) == RECORD_TYPE
|| pos
== 0);
1658 tr_size
= DECL_SIZE (fld
);
1659 if (!tr_size
|| !tree_fits_uhwi_p (tr_size
))
1661 size
= TREE_INT_CST_LOW (tr_size
);
1667 else if (pos
> offset
|| (pos
+ size
) <= offset
)
1670 expr
= build3 (COMPONENT_REF
, TREE_TYPE (fld
), *res
, fld
,
1673 if (build_user_friendly_ref_for_offset (expr_ptr
, TREE_TYPE (fld
),
1674 offset
- pos
, exp_type
))
1683 tr_size
= TYPE_SIZE (TREE_TYPE (type
));
1684 if (!tr_size
|| !tree_fits_uhwi_p (tr_size
))
1686 el_size
= tree_to_uhwi (tr_size
);
1688 minidx
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
1689 if (TREE_CODE (minidx
) != INTEGER_CST
|| el_size
== 0)
1691 index
= build_int_cst (TYPE_DOMAIN (type
), offset
/ el_size
);
1692 if (!integer_zerop (minidx
))
1693 index
= int_const_binop (PLUS_EXPR
, index
, minidx
);
1694 *res
= build4 (ARRAY_REF
, TREE_TYPE (type
), *res
, index
,
1695 NULL_TREE
, NULL_TREE
);
1696 offset
= offset
% el_size
;
1697 type
= TREE_TYPE (type
);
1712 /* Return true iff TYPE is stdarg va_list type. */
1715 is_va_list_type (tree type
)
1717 return TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (va_list_type_node
);
1720 /* Print message to dump file why a variable was rejected. */
1723 reject (tree var
, const char *msg
)
1725 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1727 fprintf (dump_file
, "Rejected (%d): %s: ", DECL_UID (var
), msg
);
1728 print_generic_expr (dump_file
, var
, 0);
1729 fprintf (dump_file
, "\n");
1733 /* Return true if VAR is a candidate for SRA. */
1736 maybe_add_sra_candidate (tree var
)
1738 tree type
= TREE_TYPE (var
);
1742 if (!AGGREGATE_TYPE_P (type
))
1744 reject (var
, "not aggregate");
1747 if (needs_to_live_in_memory (var
))
1749 reject (var
, "needs to live in memory");
1752 if (TREE_THIS_VOLATILE (var
))
1754 reject (var
, "is volatile");
1757 if (!COMPLETE_TYPE_P (type
))
1759 reject (var
, "has incomplete type");
1762 if (!tree_fits_uhwi_p (TYPE_SIZE (type
)))
1764 reject (var
, "type size not fixed");
1767 if (tree_to_uhwi (TYPE_SIZE (type
)) == 0)
1769 reject (var
, "type size is zero");
1772 if (type_internals_preclude_sra_p (type
, &msg
))
1777 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1778 we also want to schedule it rather late. Thus we ignore it in
1780 (sra_mode
== SRA_MODE_EARLY_INTRA
1781 && is_va_list_type (type
)))
1783 reject (var
, "is va_list");
1787 bitmap_set_bit (candidate_bitmap
, DECL_UID (var
));
1788 slot
= candidates
.find_slot_with_hash (var
, DECL_UID (var
), INSERT
);
1791 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1793 fprintf (dump_file
, "Candidate (%d): ", DECL_UID (var
));
1794 print_generic_expr (dump_file
, var
, 0);
1795 fprintf (dump_file
, "\n");
1801 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1802 those with type which is suitable for scalarization. */
1805 find_var_candidates (void)
1811 for (parm
= DECL_ARGUMENTS (current_function_decl
);
1813 parm
= DECL_CHAIN (parm
))
1814 ret
|= maybe_add_sra_candidate (parm
);
1816 FOR_EACH_LOCAL_DECL (cfun
, i
, var
)
1818 if (TREE_CODE (var
) != VAR_DECL
)
1821 ret
|= maybe_add_sra_candidate (var
);
1827 /* Sort all accesses for the given variable, check for partial overlaps and
1828 return NULL if there are any. If there are none, pick a representative for
1829 each combination of offset and size and create a linked list out of them.
1830 Return the pointer to the first representative and make sure it is the first
1831 one in the vector of accesses. */
1833 static struct access
*
1834 sort_and_splice_var_accesses (tree var
)
1836 int i
, j
, access_count
;
1837 struct access
*res
, **prev_acc_ptr
= &res
;
1838 vec
<access_p
> *access_vec
;
1840 HOST_WIDE_INT low
= -1, high
= 0;
1842 access_vec
= get_base_access_vector (var
);
1845 access_count
= access_vec
->length ();
1847 /* Sort by <OFFSET, SIZE>. */
1848 access_vec
->qsort (compare_access_positions
);
1851 while (i
< access_count
)
1853 struct access
*access
= (*access_vec
)[i
];
1854 bool grp_write
= access
->write
;
1855 bool grp_read
= !access
->write
;
1856 bool grp_scalar_write
= access
->write
1857 && is_gimple_reg_type (access
->type
);
1858 bool grp_scalar_read
= !access
->write
1859 && is_gimple_reg_type (access
->type
);
1860 bool grp_assignment_read
= access
->grp_assignment_read
;
1861 bool grp_assignment_write
= access
->grp_assignment_write
;
1862 bool multiple_scalar_reads
= false;
1863 bool total_scalarization
= access
->grp_total_scalarization
;
1864 bool grp_partial_lhs
= access
->grp_partial_lhs
;
1865 bool first_scalar
= is_gimple_reg_type (access
->type
);
1866 bool unscalarizable_region
= access
->grp_unscalarizable_region
;
1868 if (first
|| access
->offset
>= high
)
1871 low
= access
->offset
;
1872 high
= access
->offset
+ access
->size
;
1874 else if (access
->offset
> low
&& access
->offset
+ access
->size
> high
)
1877 gcc_assert (access
->offset
>= low
1878 && access
->offset
+ access
->size
<= high
);
1881 while (j
< access_count
)
1883 struct access
*ac2
= (*access_vec
)[j
];
1884 if (ac2
->offset
!= access
->offset
|| ac2
->size
!= access
->size
)
1889 grp_scalar_write
= (grp_scalar_write
1890 || is_gimple_reg_type (ac2
->type
));
1895 if (is_gimple_reg_type (ac2
->type
))
1897 if (grp_scalar_read
)
1898 multiple_scalar_reads
= true;
1900 grp_scalar_read
= true;
1903 grp_assignment_read
|= ac2
->grp_assignment_read
;
1904 grp_assignment_write
|= ac2
->grp_assignment_write
;
1905 grp_partial_lhs
|= ac2
->grp_partial_lhs
;
1906 unscalarizable_region
|= ac2
->grp_unscalarizable_region
;
1907 total_scalarization
|= ac2
->grp_total_scalarization
;
1908 relink_to_new_repr (access
, ac2
);
1910 /* If there are both aggregate-type and scalar-type accesses with
1911 this combination of size and offset, the comparison function
1912 should have put the scalars first. */
1913 gcc_assert (first_scalar
|| !is_gimple_reg_type (ac2
->type
));
1914 ac2
->group_representative
= access
;
1920 access
->group_representative
= access
;
1921 access
->grp_write
= grp_write
;
1922 access
->grp_read
= grp_read
;
1923 access
->grp_scalar_read
= grp_scalar_read
;
1924 access
->grp_scalar_write
= grp_scalar_write
;
1925 access
->grp_assignment_read
= grp_assignment_read
;
1926 access
->grp_assignment_write
= grp_assignment_write
;
1927 access
->grp_hint
= multiple_scalar_reads
|| total_scalarization
;
1928 access
->grp_total_scalarization
= total_scalarization
;
1929 access
->grp_partial_lhs
= grp_partial_lhs
;
1930 access
->grp_unscalarizable_region
= unscalarizable_region
;
1931 if (access
->first_link
)
1932 add_access_to_work_queue (access
);
1934 *prev_acc_ptr
= access
;
1935 prev_acc_ptr
= &access
->next_grp
;
1938 gcc_assert (res
== (*access_vec
)[0]);
1942 /* Create a variable for the given ACCESS which determines the type, name and a
1943 few other properties. Return the variable declaration and store it also to
1944 ACCESS->replacement. */
1947 create_access_replacement (struct access
*access
)
1951 if (access
->grp_to_be_debug_replaced
)
1953 repl
= create_tmp_var_raw (access
->type
, NULL
);
1954 DECL_CONTEXT (repl
) = current_function_decl
;
1957 repl
= create_tmp_var (access
->type
, "SR");
1958 if (TREE_CODE (access
->type
) == COMPLEX_TYPE
1959 || TREE_CODE (access
->type
) == VECTOR_TYPE
)
1961 if (!access
->grp_partial_lhs
)
1962 DECL_GIMPLE_REG_P (repl
) = 1;
1964 else if (access
->grp_partial_lhs
1965 && is_gimple_reg_type (access
->type
))
1966 TREE_ADDRESSABLE (repl
) = 1;
1968 DECL_SOURCE_LOCATION (repl
) = DECL_SOURCE_LOCATION (access
->base
);
1969 DECL_ARTIFICIAL (repl
) = 1;
1970 DECL_IGNORED_P (repl
) = DECL_IGNORED_P (access
->base
);
1972 if (DECL_NAME (access
->base
)
1973 && !DECL_IGNORED_P (access
->base
)
1974 && !DECL_ARTIFICIAL (access
->base
))
1976 char *pretty_name
= make_fancy_name (access
->expr
);
1977 tree debug_expr
= unshare_expr_without_location (access
->expr
), d
;
1980 DECL_NAME (repl
) = get_identifier (pretty_name
);
1981 obstack_free (&name_obstack
, pretty_name
);
1983 /* Get rid of any SSA_NAMEs embedded in debug_expr,
1984 as DECL_DEBUG_EXPR isn't considered when looking for still
1985 used SSA_NAMEs and thus they could be freed. All debug info
1986 generation cares is whether something is constant or variable
1987 and that get_ref_base_and_extent works properly on the
1988 expression. It cannot handle accesses at a non-constant offset
1989 though, so just give up in those cases. */
1990 for (d
= debug_expr
;
1991 !fail
&& (handled_component_p (d
) || TREE_CODE (d
) == MEM_REF
);
1992 d
= TREE_OPERAND (d
, 0))
1993 switch (TREE_CODE (d
))
1996 case ARRAY_RANGE_REF
:
1997 if (TREE_OPERAND (d
, 1)
1998 && TREE_CODE (TREE_OPERAND (d
, 1)) != INTEGER_CST
)
2000 if (TREE_OPERAND (d
, 3)
2001 && TREE_CODE (TREE_OPERAND (d
, 3)) != INTEGER_CST
)
2005 if (TREE_OPERAND (d
, 2)
2006 && TREE_CODE (TREE_OPERAND (d
, 2)) != INTEGER_CST
)
2010 if (TREE_CODE (TREE_OPERAND (d
, 0)) != ADDR_EXPR
)
2013 d
= TREE_OPERAND (d
, 0);
2020 SET_DECL_DEBUG_EXPR (repl
, debug_expr
);
2021 DECL_HAS_DEBUG_EXPR_P (repl
) = 1;
2023 if (access
->grp_no_warning
)
2024 TREE_NO_WARNING (repl
) = 1;
2026 TREE_NO_WARNING (repl
) = TREE_NO_WARNING (access
->base
);
2029 TREE_NO_WARNING (repl
) = 1;
2033 if (access
->grp_to_be_debug_replaced
)
2035 fprintf (dump_file
, "Created a debug-only replacement for ");
2036 print_generic_expr (dump_file
, access
->base
, 0);
2037 fprintf (dump_file
, " offset: %u, size: %u\n",
2038 (unsigned) access
->offset
, (unsigned) access
->size
);
2042 fprintf (dump_file
, "Created a replacement for ");
2043 print_generic_expr (dump_file
, access
->base
, 0);
2044 fprintf (dump_file
, " offset: %u, size: %u: ",
2045 (unsigned) access
->offset
, (unsigned) access
->size
);
2046 print_generic_expr (dump_file
, repl
, 0);
2047 fprintf (dump_file
, "\n");
2050 sra_stats
.replacements
++;
2055 /* Return ACCESS scalar replacement, create it if it does not exist yet. */
2058 get_access_replacement (struct access
*access
)
2060 gcc_checking_assert (access
->replacement_decl
);
2061 return access
->replacement_decl
;
2065 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2066 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2067 to it is not "within" the root. Return false iff some accesses partially
2071 build_access_subtree (struct access
**access
)
2073 struct access
*root
= *access
, *last_child
= NULL
;
2074 HOST_WIDE_INT limit
= root
->offset
+ root
->size
;
2076 *access
= (*access
)->next_grp
;
2077 while (*access
&& (*access
)->offset
+ (*access
)->size
<= limit
)
2080 root
->first_child
= *access
;
2082 last_child
->next_sibling
= *access
;
2083 last_child
= *access
;
2085 if (!build_access_subtree (access
))
2089 if (*access
&& (*access
)->offset
< limit
)
2095 /* Build a tree of access representatives, ACCESS is the pointer to the first
2096 one, others are linked in a list by the next_grp field. Return false iff
2097 some accesses partially overlap. */
2100 build_access_trees (struct access
*access
)
2104 struct access
*root
= access
;
2106 if (!build_access_subtree (&access
))
2108 root
->next_grp
= access
;
2113 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2117 expr_with_var_bounded_array_refs_p (tree expr
)
2119 while (handled_component_p (expr
))
2121 if (TREE_CODE (expr
) == ARRAY_REF
2122 && !tree_fits_shwi_p (array_ref_low_bound (expr
)))
2124 expr
= TREE_OPERAND (expr
, 0);
2129 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2130 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2131 sorts of access flags appropriately along the way, notably always set
2132 grp_read and grp_assign_read according to MARK_READ and grp_write when
2135 Creating a replacement for a scalar access is considered beneficial if its
2136 grp_hint is set (this means we are either attempting total scalarization or
2137 there is more than one direct read access) or according to the following
2140 Access written to through a scalar type (once or more times)
2142 | Written to in an assignment statement
2144 | | Access read as scalar _once_
2146 | | | Read in an assignment statement
2148 | | | | Scalarize Comment
2149 -----------------------------------------------------------------------------
2150 0 0 0 0 No access for the scalar
2151 0 0 0 1 No access for the scalar
2152 0 0 1 0 No Single read - won't help
2153 0 0 1 1 No The same case
2154 0 1 0 0 No access for the scalar
2155 0 1 0 1 No access for the scalar
2156 0 1 1 0 Yes s = *g; return s.i;
2157 0 1 1 1 Yes The same case as above
2158 1 0 0 0 No Won't help
2159 1 0 0 1 Yes s.i = 1; *g = s;
2160 1 0 1 0 Yes s.i = 5; g = s.i;
2161 1 0 1 1 Yes The same case as above
2162 1 1 0 0 No Won't help.
2163 1 1 0 1 Yes s.i = 1; *g = s;
2164 1 1 1 0 Yes s = *g; return s.i;
2165 1 1 1 1 Yes Any of the above yeses */
2168 analyze_access_subtree (struct access
*root
, struct access
*parent
,
2169 bool allow_replacements
)
2171 struct access
*child
;
2172 HOST_WIDE_INT limit
= root
->offset
+ root
->size
;
2173 HOST_WIDE_INT covered_to
= root
->offset
;
2174 bool scalar
= is_gimple_reg_type (root
->type
);
2175 bool hole
= false, sth_created
= false;
2179 if (parent
->grp_read
)
2181 if (parent
->grp_assignment_read
)
2182 root
->grp_assignment_read
= 1;
2183 if (parent
->grp_write
)
2184 root
->grp_write
= 1;
2185 if (parent
->grp_assignment_write
)
2186 root
->grp_assignment_write
= 1;
2187 if (parent
->grp_total_scalarization
)
2188 root
->grp_total_scalarization
= 1;
2191 if (root
->grp_unscalarizable_region
)
2192 allow_replacements
= false;
2194 if (allow_replacements
&& expr_with_var_bounded_array_refs_p (root
->expr
))
2195 allow_replacements
= false;
2197 for (child
= root
->first_child
; child
; child
= child
->next_sibling
)
2199 hole
|= covered_to
< child
->offset
;
2200 sth_created
|= analyze_access_subtree (child
, root
,
2201 allow_replacements
&& !scalar
);
2203 root
->grp_unscalarized_data
|= child
->grp_unscalarized_data
;
2204 root
->grp_total_scalarization
&= child
->grp_total_scalarization
;
2205 if (child
->grp_covered
)
2206 covered_to
+= child
->size
;
2211 if (allow_replacements
&& scalar
&& !root
->first_child
2213 || ((root
->grp_scalar_read
|| root
->grp_assignment_read
)
2214 && (root
->grp_scalar_write
|| root
->grp_assignment_write
))))
2216 /* Always create access replacements that cover the whole access.
2217 For integral types this means the precision has to match.
2218 Avoid assumptions based on the integral type kind, too. */
2219 if (INTEGRAL_TYPE_P (root
->type
)
2220 && (TREE_CODE (root
->type
) != INTEGER_TYPE
2221 || TYPE_PRECISION (root
->type
) != root
->size
)
2222 /* But leave bitfield accesses alone. */
2223 && (TREE_CODE (root
->expr
) != COMPONENT_REF
2224 || !DECL_BIT_FIELD (TREE_OPERAND (root
->expr
, 1))))
2226 tree rt
= root
->type
;
2227 gcc_assert ((root
->offset
% BITS_PER_UNIT
) == 0
2228 && (root
->size
% BITS_PER_UNIT
) == 0);
2229 root
->type
= build_nonstandard_integer_type (root
->size
,
2230 TYPE_UNSIGNED (rt
));
2231 root
->expr
= build_ref_for_offset (UNKNOWN_LOCATION
,
2232 root
->base
, root
->offset
,
2233 root
->type
, NULL
, false);
2235 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2237 fprintf (dump_file
, "Changing the type of a replacement for ");
2238 print_generic_expr (dump_file
, root
->base
, 0);
2239 fprintf (dump_file
, " offset: %u, size: %u ",
2240 (unsigned) root
->offset
, (unsigned) root
->size
);
2241 fprintf (dump_file
, " to an integer.\n");
2245 root
->grp_to_be_replaced
= 1;
2246 root
->replacement_decl
= create_access_replacement (root
);
2252 if (allow_replacements
2253 && scalar
&& !root
->first_child
2254 && (root
->grp_scalar_write
|| root
->grp_assignment_write
)
2255 && !bitmap_bit_p (cannot_scalarize_away_bitmap
,
2256 DECL_UID (root
->base
)))
2258 gcc_checking_assert (!root
->grp_scalar_read
2259 && !root
->grp_assignment_read
);
2261 if (MAY_HAVE_DEBUG_STMTS
)
2263 root
->grp_to_be_debug_replaced
= 1;
2264 root
->replacement_decl
= create_access_replacement (root
);
2268 if (covered_to
< limit
)
2271 root
->grp_total_scalarization
= 0;
2274 if (!hole
|| root
->grp_total_scalarization
)
2275 root
->grp_covered
= 1;
2276 else if (root
->grp_write
|| TREE_CODE (root
->base
) == PARM_DECL
)
2277 root
->grp_unscalarized_data
= 1; /* not covered and written to */
2281 /* Analyze all access trees linked by next_grp by the means of
2282 analyze_access_subtree. */
2284 analyze_access_trees (struct access
*access
)
2290 if (analyze_access_subtree (access
, NULL
, true))
2292 access
= access
->next_grp
;
2298 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2299 SIZE would conflict with an already existing one. If exactly such a child
2300 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2303 child_would_conflict_in_lacc (struct access
*lacc
, HOST_WIDE_INT norm_offset
,
2304 HOST_WIDE_INT size
, struct access
**exact_match
)
2306 struct access
*child
;
2308 for (child
= lacc
->first_child
; child
; child
= child
->next_sibling
)
2310 if (child
->offset
== norm_offset
&& child
->size
== size
)
2312 *exact_match
= child
;
2316 if (child
->offset
< norm_offset
+ size
2317 && child
->offset
+ child
->size
> norm_offset
)
2324 /* Create a new child access of PARENT, with all properties just like MODEL
2325 except for its offset and with its grp_write false and grp_read true.
2326 Return the new access or NULL if it cannot be created. Note that this access
2327 is created long after all splicing and sorting, it's not located in any
2328 access vector and is automatically a representative of its group. */
2330 static struct access
*
2331 create_artificial_child_access (struct access
*parent
, struct access
*model
,
2332 HOST_WIDE_INT new_offset
)
2334 struct access
*access
;
2335 struct access
**child
;
2336 tree expr
= parent
->base
;
2338 gcc_assert (!model
->grp_unscalarizable_region
);
2340 access
= (struct access
*) pool_alloc (access_pool
);
2341 memset (access
, 0, sizeof (struct access
));
2342 if (!build_user_friendly_ref_for_offset (&expr
, TREE_TYPE (expr
), new_offset
,
2345 access
->grp_no_warning
= true;
2346 expr
= build_ref_for_model (EXPR_LOCATION (parent
->base
), parent
->base
,
2347 new_offset
, model
, NULL
, false);
2350 access
->base
= parent
->base
;
2351 access
->expr
= expr
;
2352 access
->offset
= new_offset
;
2353 access
->size
= model
->size
;
2354 access
->type
= model
->type
;
2355 access
->grp_write
= true;
2356 access
->grp_read
= false;
2358 child
= &parent
->first_child
;
2359 while (*child
&& (*child
)->offset
< new_offset
)
2360 child
= &(*child
)->next_sibling
;
2362 access
->next_sibling
= *child
;
2369 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
2370 true if any new subaccess was created. Additionally, if RACC is a scalar
2371 access but LACC is not, change the type of the latter, if possible. */
2374 propagate_subaccesses_across_link (struct access
*lacc
, struct access
*racc
)
2376 struct access
*rchild
;
2377 HOST_WIDE_INT norm_delta
= lacc
->offset
- racc
->offset
;
2380 if (is_gimple_reg_type (lacc
->type
)
2381 || lacc
->grp_unscalarizable_region
2382 || racc
->grp_unscalarizable_region
)
2385 if (is_gimple_reg_type (racc
->type
))
2387 if (!lacc
->first_child
&& !racc
->first_child
)
2389 tree t
= lacc
->base
;
2391 lacc
->type
= racc
->type
;
2392 if (build_user_friendly_ref_for_offset (&t
, TREE_TYPE (t
),
2393 lacc
->offset
, racc
->type
))
2397 lacc
->expr
= build_ref_for_model (EXPR_LOCATION (lacc
->base
),
2398 lacc
->base
, lacc
->offset
,
2400 lacc
->grp_no_warning
= true;
2406 for (rchild
= racc
->first_child
; rchild
; rchild
= rchild
->next_sibling
)
2408 struct access
*new_acc
= NULL
;
2409 HOST_WIDE_INT norm_offset
= rchild
->offset
+ norm_delta
;
2411 if (rchild
->grp_unscalarizable_region
)
2414 if (child_would_conflict_in_lacc (lacc
, norm_offset
, rchild
->size
,
2419 rchild
->grp_hint
= 1;
2420 new_acc
->grp_hint
|= new_acc
->grp_read
;
2421 if (rchild
->first_child
)
2422 ret
|= propagate_subaccesses_across_link (new_acc
, rchild
);
2427 rchild
->grp_hint
= 1;
2428 new_acc
= create_artificial_child_access (lacc
, rchild
, norm_offset
);
2432 if (racc
->first_child
)
2433 propagate_subaccesses_across_link (new_acc
, rchild
);
2440 /* Propagate all subaccesses across assignment links. */
2443 propagate_all_subaccesses (void)
2445 while (work_queue_head
)
2447 struct access
*racc
= pop_access_from_work_queue ();
2448 struct assign_link
*link
;
2450 gcc_assert (racc
->first_link
);
2452 for (link
= racc
->first_link
; link
; link
= link
->next
)
2454 struct access
*lacc
= link
->lacc
;
2456 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (lacc
->base
)))
2458 lacc
= lacc
->group_representative
;
2459 if (propagate_subaccesses_across_link (lacc
, racc
)
2460 && lacc
->first_link
)
2461 add_access_to_work_queue (lacc
);
2466 /* Go through all accesses collected throughout the (intraprocedural) analysis
2467 stage, exclude overlapping ones, identify representatives and build trees
2468 out of them, making decisions about scalarization on the way. Return true
2469 iff there are any to-be-scalarized variables after this stage. */
2472 analyze_all_variable_accesses (void)
2475 bitmap tmp
= BITMAP_ALLOC (NULL
);
2477 unsigned i
, max_total_scalarization_size
;
2479 max_total_scalarization_size
= UNITS_PER_WORD
* BITS_PER_UNIT
2480 * MOVE_RATIO (optimize_function_for_speed_p (cfun
));
2482 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap
, 0, i
, bi
)
2483 if (bitmap_bit_p (should_scalarize_away_bitmap
, i
)
2484 && !bitmap_bit_p (cannot_scalarize_away_bitmap
, i
))
2486 tree var
= candidate (i
);
2488 if (TREE_CODE (var
) == VAR_DECL
2489 && type_consists_of_records_p (TREE_TYPE (var
)))
2491 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var
)))
2492 <= max_total_scalarization_size
)
2494 completely_scalarize_var (var
);
2495 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2497 fprintf (dump_file
, "Will attempt to totally scalarize ");
2498 print_generic_expr (dump_file
, var
, 0);
2499 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (var
));
2502 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2504 fprintf (dump_file
, "Too big to totally scalarize: ");
2505 print_generic_expr (dump_file
, var
, 0);
2506 fprintf (dump_file
, " (UID: %u)\n", DECL_UID (var
));
2511 bitmap_copy (tmp
, candidate_bitmap
);
2512 EXECUTE_IF_SET_IN_BITMAP (tmp
, 0, i
, bi
)
2514 tree var
= candidate (i
);
2515 struct access
*access
;
2517 access
= sort_and_splice_var_accesses (var
);
2518 if (!access
|| !build_access_trees (access
))
2519 disqualify_candidate (var
,
2520 "No or inhibitingly overlapping accesses.");
2523 propagate_all_subaccesses ();
2525 bitmap_copy (tmp
, candidate_bitmap
);
2526 EXECUTE_IF_SET_IN_BITMAP (tmp
, 0, i
, bi
)
2528 tree var
= candidate (i
);
2529 struct access
*access
= get_first_repr_for_decl (var
);
2531 if (analyze_access_trees (access
))
2534 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2536 fprintf (dump_file
, "\nAccess trees for ");
2537 print_generic_expr (dump_file
, var
, 0);
2538 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (var
));
2539 dump_access_tree (dump_file
, access
);
2540 fprintf (dump_file
, "\n");
2544 disqualify_candidate (var
, "No scalar replacements to be created.");
2551 statistics_counter_event (cfun
, "Scalarized aggregates", res
);
2558 /* Generate statements copying scalar replacements of accesses within a subtree
2559 into or out of AGG. ACCESS, all its children, siblings and their children
2560 are to be processed. AGG is an aggregate type expression (can be a
2561 declaration but does not have to be, it can for example also be a mem_ref or
2562 a series of handled components). TOP_OFFSET is the offset of the processed
2563 subtree which has to be subtracted from offsets of individual accesses to
2564 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2565 replacements in the interval <start_offset, start_offset + chunk_size>,
2566 otherwise copy all. GSI is a statement iterator used to place the new
2567 statements. WRITE should be true when the statements should write from AGG
2568 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2569 statements will be added after the current statement in GSI, they will be
2570 added before the statement otherwise. */
2573 generate_subtree_copies (struct access
*access
, tree agg
,
2574 HOST_WIDE_INT top_offset
,
2575 HOST_WIDE_INT start_offset
, HOST_WIDE_INT chunk_size
,
2576 gimple_stmt_iterator
*gsi
, bool write
,
2577 bool insert_after
, location_t loc
)
2581 if (chunk_size
&& access
->offset
>= start_offset
+ chunk_size
)
2584 if (access
->grp_to_be_replaced
2586 || access
->offset
+ access
->size
> start_offset
))
2588 tree expr
, repl
= get_access_replacement (access
);
2591 expr
= build_ref_for_model (loc
, agg
, access
->offset
- top_offset
,
2592 access
, gsi
, insert_after
);
2596 if (access
->grp_partial_lhs
)
2597 expr
= force_gimple_operand_gsi (gsi
, expr
, true, NULL_TREE
,
2599 insert_after
? GSI_NEW_STMT
2601 stmt
= gimple_build_assign (repl
, expr
);
2605 TREE_NO_WARNING (repl
) = 1;
2606 if (access
->grp_partial_lhs
)
2607 repl
= force_gimple_operand_gsi (gsi
, repl
, true, NULL_TREE
,
2609 insert_after
? GSI_NEW_STMT
2611 stmt
= gimple_build_assign (expr
, repl
);
2613 gimple_set_location (stmt
, loc
);
2616 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2618 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2620 sra_stats
.subtree_copies
++;
2623 && access
->grp_to_be_debug_replaced
2625 || access
->offset
+ access
->size
> start_offset
))
2628 tree drhs
= build_debug_ref_for_model (loc
, agg
,
2629 access
->offset
- top_offset
,
2631 ds
= gimple_build_debug_bind (get_access_replacement (access
),
2632 drhs
, gsi_stmt (*gsi
));
2634 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2636 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
2639 if (access
->first_child
)
2640 generate_subtree_copies (access
->first_child
, agg
, top_offset
,
2641 start_offset
, chunk_size
, gsi
,
2642 write
, insert_after
, loc
);
2644 access
= access
->next_sibling
;
2649 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2650 the root of the subtree to be processed. GSI is the statement iterator used
2651 for inserting statements which are added after the current statement if
2652 INSERT_AFTER is true or before it otherwise. */
2655 init_subtree_with_zero (struct access
*access
, gimple_stmt_iterator
*gsi
,
2656 bool insert_after
, location_t loc
)
2659 struct access
*child
;
2661 if (access
->grp_to_be_replaced
)
2665 stmt
= gimple_build_assign (get_access_replacement (access
),
2666 build_zero_cst (access
->type
));
2668 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2670 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2672 gimple_set_location (stmt
, loc
);
2674 else if (access
->grp_to_be_debug_replaced
)
2676 gimple ds
= gimple_build_debug_bind (get_access_replacement (access
),
2677 build_zero_cst (access
->type
),
2680 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2682 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
2685 for (child
= access
->first_child
; child
; child
= child
->next_sibling
)
2686 init_subtree_with_zero (child
, gsi
, insert_after
, loc
);
2689 /* Search for an access representative for the given expression EXPR and
2690 return it or NULL if it cannot be found. */
2692 static struct access
*
2693 get_access_for_expr (tree expr
)
2695 HOST_WIDE_INT offset
, size
, max_size
;
2698 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2699 a different size than the size of its argument and we need the latter
2701 if (TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
2702 expr
= TREE_OPERAND (expr
, 0);
2704 base
= get_ref_base_and_extent (expr
, &offset
, &size
, &max_size
);
2705 if (max_size
== -1 || !DECL_P (base
))
2708 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (base
)))
2711 return get_var_base_offset_size_access (base
, offset
, max_size
);
2714 /* Replace the expression EXPR with a scalar replacement if there is one and
2715 generate other statements to do type conversion or subtree copying if
2716 necessary. GSI is used to place newly created statements, WRITE is true if
2717 the expression is being written to (it is on a LHS of a statement or output
2718 in an assembly statement). */
2721 sra_modify_expr (tree
*expr
, gimple_stmt_iterator
*gsi
, bool write
)
2724 struct access
*access
;
2727 if (TREE_CODE (*expr
) == BIT_FIELD_REF
)
2730 expr
= &TREE_OPERAND (*expr
, 0);
2735 if (TREE_CODE (*expr
) == REALPART_EXPR
|| TREE_CODE (*expr
) == IMAGPART_EXPR
)
2736 expr
= &TREE_OPERAND (*expr
, 0);
2737 access
= get_access_for_expr (*expr
);
2740 type
= TREE_TYPE (*expr
);
2742 loc
= gimple_location (gsi_stmt (*gsi
));
2743 if (access
->grp_to_be_replaced
)
2745 tree repl
= get_access_replacement (access
);
2746 /* If we replace a non-register typed access simply use the original
2747 access expression to extract the scalar component afterwards.
2748 This happens if scalarizing a function return value or parameter
2749 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2750 gcc.c-torture/compile/20011217-1.c.
2752 We also want to use this when accessing a complex or vector which can
2753 be accessed as a different type too, potentially creating a need for
2754 type conversion (see PR42196) and when scalarized unions are involved
2755 in assembler statements (see PR42398). */
2756 if (!useless_type_conversion_p (type
, access
->type
))
2760 ref
= build_ref_for_model (loc
, access
->base
, access
->offset
, access
,
2767 if (access
->grp_partial_lhs
)
2768 ref
= force_gimple_operand_gsi (gsi
, ref
, true, NULL_TREE
,
2769 false, GSI_NEW_STMT
);
2770 stmt
= gimple_build_assign (repl
, ref
);
2771 gimple_set_location (stmt
, loc
);
2772 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2778 if (access
->grp_partial_lhs
)
2779 repl
= force_gimple_operand_gsi (gsi
, repl
, true, NULL_TREE
,
2780 true, GSI_SAME_STMT
);
2781 stmt
= gimple_build_assign (ref
, repl
);
2782 gimple_set_location (stmt
, loc
);
2783 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2790 else if (write
&& access
->grp_to_be_debug_replaced
)
2792 gimple ds
= gimple_build_debug_bind (get_access_replacement (access
),
2795 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2798 if (access
->first_child
)
2800 HOST_WIDE_INT start_offset
, chunk_size
;
2802 && tree_fits_uhwi_p (TREE_OPERAND (bfr
, 1))
2803 && tree_fits_uhwi_p (TREE_OPERAND (bfr
, 2)))
2805 chunk_size
= tree_to_uhwi (TREE_OPERAND (bfr
, 1));
2806 start_offset
= access
->offset
2807 + tree_to_uhwi (TREE_OPERAND (bfr
, 2));
2810 start_offset
= chunk_size
= 0;
2812 generate_subtree_copies (access
->first_child
, access
->base
, 0,
2813 start_offset
, chunk_size
, gsi
, write
, write
,
2819 /* Where scalar replacements of the RHS have been written to when a replacement
2820 of a LHS of an assigments cannot be direclty loaded from a replacement of
2822 enum unscalarized_data_handling
{ SRA_UDH_NONE
, /* Nothing done so far. */
2823 SRA_UDH_RIGHT
, /* Data flushed to the RHS. */
2824 SRA_UDH_LEFT
}; /* Data flushed to the LHS. */
2826 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2827 base aggregate if there are unscalarized data or directly to LHS of the
2828 statement that is pointed to by GSI otherwise. */
2830 static enum unscalarized_data_handling
2831 handle_unscalarized_data_in_subtree (struct access
*top_racc
,
2832 gimple_stmt_iterator
*gsi
)
2834 if (top_racc
->grp_unscalarized_data
)
2836 generate_subtree_copies (top_racc
->first_child
, top_racc
->base
, 0, 0, 0,
2838 gimple_location (gsi_stmt (*gsi
)));
2839 return SRA_UDH_RIGHT
;
2843 tree lhs
= gimple_assign_lhs (gsi_stmt (*gsi
));
2844 generate_subtree_copies (top_racc
->first_child
, lhs
, top_racc
->offset
,
2845 0, 0, gsi
, false, false,
2846 gimple_location (gsi_stmt (*gsi
)));
2847 return SRA_UDH_LEFT
;
2852 /* Try to generate statements to load all sub-replacements in an access subtree
2853 formed by children of LACC from scalar replacements in the TOP_RACC subtree.
2854 If that is not possible, refresh the TOP_RACC base aggregate and load the
2855 accesses from it. LEFT_OFFSET is the offset of the left whole subtree being
2856 copied. NEW_GSI is stmt iterator used for statement insertions after the
2857 original assignment, OLD_GSI is used to insert statements before the
2858 assignment. *REFRESHED keeps the information whether we have needed to
2859 refresh replacements of the LHS and from which side of the assignments this
2863 load_assign_lhs_subreplacements (struct access
*lacc
, struct access
*top_racc
,
2864 HOST_WIDE_INT left_offset
,
2865 gimple_stmt_iterator
*old_gsi
,
2866 gimple_stmt_iterator
*new_gsi
,
2867 enum unscalarized_data_handling
*refreshed
)
2869 location_t loc
= gimple_location (gsi_stmt (*old_gsi
));
2870 for (lacc
= lacc
->first_child
; lacc
; lacc
= lacc
->next_sibling
)
2872 HOST_WIDE_INT offset
= lacc
->offset
- left_offset
+ top_racc
->offset
;
2874 if (lacc
->grp_to_be_replaced
)
2876 struct access
*racc
;
2880 racc
= find_access_in_subtree (top_racc
, offset
, lacc
->size
);
2881 if (racc
&& racc
->grp_to_be_replaced
)
2883 rhs
= get_access_replacement (racc
);
2884 if (!useless_type_conversion_p (lacc
->type
, racc
->type
))
2885 rhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, lacc
->type
, rhs
);
2887 if (racc
->grp_partial_lhs
&& lacc
->grp_partial_lhs
)
2888 rhs
= force_gimple_operand_gsi (old_gsi
, rhs
, true, NULL_TREE
,
2889 true, GSI_SAME_STMT
);
2893 /* No suitable access on the right hand side, need to load from
2894 the aggregate. See if we have to update it first... */
2895 if (*refreshed
== SRA_UDH_NONE
)
2896 *refreshed
= handle_unscalarized_data_in_subtree (top_racc
,
2899 if (*refreshed
== SRA_UDH_LEFT
)
2900 rhs
= build_ref_for_model (loc
, lacc
->base
, lacc
->offset
, lacc
,
2903 rhs
= build_ref_for_model (loc
, top_racc
->base
, offset
, lacc
,
2905 if (lacc
->grp_partial_lhs
)
2906 rhs
= force_gimple_operand_gsi (new_gsi
, rhs
, true, NULL_TREE
,
2907 false, GSI_NEW_STMT
);
2910 stmt
= gimple_build_assign (get_access_replacement (lacc
), rhs
);
2911 gsi_insert_after (new_gsi
, stmt
, GSI_NEW_STMT
);
2912 gimple_set_location (stmt
, loc
);
2914 sra_stats
.subreplacements
++;
2918 if (*refreshed
== SRA_UDH_NONE
2919 && lacc
->grp_read
&& !lacc
->grp_covered
)
2920 *refreshed
= handle_unscalarized_data_in_subtree (top_racc
,
2922 if (lacc
&& lacc
->grp_to_be_debug_replaced
)
2926 struct access
*racc
= find_access_in_subtree (top_racc
, offset
,
2929 if (racc
&& racc
->grp_to_be_replaced
)
2931 if (racc
->grp_write
)
2932 drhs
= get_access_replacement (racc
);
2936 else if (*refreshed
== SRA_UDH_LEFT
)
2937 drhs
= build_debug_ref_for_model (loc
, lacc
->base
, lacc
->offset
,
2939 else if (*refreshed
== SRA_UDH_RIGHT
)
2940 drhs
= build_debug_ref_for_model (loc
, top_racc
->base
, offset
,
2944 ds
= gimple_build_debug_bind (get_access_replacement (lacc
),
2945 drhs
, gsi_stmt (*old_gsi
));
2946 gsi_insert_after (new_gsi
, ds
, GSI_NEW_STMT
);
2950 if (lacc
->first_child
)
2951 load_assign_lhs_subreplacements (lacc
, top_racc
, left_offset
,
2952 old_gsi
, new_gsi
, refreshed
);
2956 /* Result code for SRA assignment modification. */
2957 enum assignment_mod_result
{ SRA_AM_NONE
, /* nothing done for the stmt */
2958 SRA_AM_MODIFIED
, /* stmt changed but not
2960 SRA_AM_REMOVED
}; /* stmt eliminated */
2962 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
2963 to the assignment and GSI is the statement iterator pointing at it. Returns
2964 the same values as sra_modify_assign. */
2966 static enum assignment_mod_result
2967 sra_modify_constructor_assign (gimple
*stmt
, gimple_stmt_iterator
*gsi
)
2969 tree lhs
= gimple_assign_lhs (*stmt
);
2973 acc
= get_access_for_expr (lhs
);
2977 if (gimple_clobber_p (*stmt
))
2979 /* Remove clobbers of fully scalarized variables, otherwise
2981 if (acc
->grp_covered
)
2983 unlink_stmt_vdef (*stmt
);
2984 gsi_remove (gsi
, true);
2985 release_defs (*stmt
);
2986 return SRA_AM_REMOVED
;
2992 loc
= gimple_location (*stmt
);
2993 if (vec_safe_length (CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt
))) > 0)
2995 /* I have never seen this code path trigger but if it can happen the
2996 following should handle it gracefully. */
2997 if (access_has_children_p (acc
))
2998 generate_subtree_copies (acc
->first_child
, acc
->base
, 0, 0, 0, gsi
,
3000 return SRA_AM_MODIFIED
;
3003 if (acc
->grp_covered
)
3005 init_subtree_with_zero (acc
, gsi
, false, loc
);
3006 unlink_stmt_vdef (*stmt
);
3007 gsi_remove (gsi
, true);
3008 release_defs (*stmt
);
3009 return SRA_AM_REMOVED
;
3013 init_subtree_with_zero (acc
, gsi
, true, loc
);
3014 return SRA_AM_MODIFIED
;
3018 /* Create and return a new suitable default definition SSA_NAME for RACC which
3019 is an access describing an uninitialized part of an aggregate that is being
3023 get_repl_default_def_ssa_name (struct access
*racc
)
3025 gcc_checking_assert (!racc
->grp_to_be_replaced
3026 && !racc
->grp_to_be_debug_replaced
);
3027 if (!racc
->replacement_decl
)
3028 racc
->replacement_decl
= create_access_replacement (racc
);
3029 return get_or_create_ssa_default_def (cfun
, racc
->replacement_decl
);
3032 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3033 bit-field field declaration somewhere in it. */
3036 contains_vce_or_bfcref_p (const_tree ref
)
3038 while (handled_component_p (ref
))
3040 if (TREE_CODE (ref
) == VIEW_CONVERT_EXPR
3041 || (TREE_CODE (ref
) == COMPONENT_REF
3042 && DECL_BIT_FIELD (TREE_OPERAND (ref
, 1))))
3044 ref
= TREE_OPERAND (ref
, 0);
3050 /* Examine both sides of the assignment statement pointed to by STMT, replace
3051 them with a scalare replacement if there is one and generate copying of
3052 replacements if scalarized aggregates have been used in the assignment. GSI
3053 is used to hold generated statements for type conversions and subtree
3056 static enum assignment_mod_result
3057 sra_modify_assign (gimple
*stmt
, gimple_stmt_iterator
*gsi
)
3059 struct access
*lacc
, *racc
;
3061 bool modify_this_stmt
= false;
3062 bool force_gimple_rhs
= false;
3064 gimple_stmt_iterator orig_gsi
= *gsi
;
3066 if (!gimple_assign_single_p (*stmt
))
3068 lhs
= gimple_assign_lhs (*stmt
);
3069 rhs
= gimple_assign_rhs1 (*stmt
);
3071 if (TREE_CODE (rhs
) == CONSTRUCTOR
)
3072 return sra_modify_constructor_assign (stmt
, gsi
);
3074 if (TREE_CODE (rhs
) == REALPART_EXPR
|| TREE_CODE (lhs
) == REALPART_EXPR
3075 || TREE_CODE (rhs
) == IMAGPART_EXPR
|| TREE_CODE (lhs
) == IMAGPART_EXPR
3076 || TREE_CODE (rhs
) == BIT_FIELD_REF
|| TREE_CODE (lhs
) == BIT_FIELD_REF
)
3078 modify_this_stmt
= sra_modify_expr (gimple_assign_rhs1_ptr (*stmt
),
3080 modify_this_stmt
|= sra_modify_expr (gimple_assign_lhs_ptr (*stmt
),
3082 return modify_this_stmt
? SRA_AM_MODIFIED
: SRA_AM_NONE
;
3085 lacc
= get_access_for_expr (lhs
);
3086 racc
= get_access_for_expr (rhs
);
3090 loc
= gimple_location (*stmt
);
3091 if (lacc
&& lacc
->grp_to_be_replaced
)
3093 lhs
= get_access_replacement (lacc
);
3094 gimple_assign_set_lhs (*stmt
, lhs
);
3095 modify_this_stmt
= true;
3096 if (lacc
->grp_partial_lhs
)
3097 force_gimple_rhs
= true;
3101 if (racc
&& racc
->grp_to_be_replaced
)
3103 rhs
= get_access_replacement (racc
);
3104 modify_this_stmt
= true;
3105 if (racc
->grp_partial_lhs
)
3106 force_gimple_rhs
= true;
3110 && !racc
->grp_unscalarized_data
3111 && TREE_CODE (lhs
) == SSA_NAME
3112 && !access_has_replacements_p (racc
))
3114 rhs
= get_repl_default_def_ssa_name (racc
);
3115 modify_this_stmt
= true;
3119 if (modify_this_stmt
)
3121 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
3123 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3124 ??? This should move to fold_stmt which we simply should
3125 call after building a VIEW_CONVERT_EXPR here. */
3126 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs
))
3127 && !contains_bitfld_component_ref_p (lhs
))
3129 lhs
= build_ref_for_model (loc
, lhs
, 0, racc
, gsi
, false);
3130 gimple_assign_set_lhs (*stmt
, lhs
);
3132 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs
))
3133 && !contains_vce_or_bfcref_p (rhs
))
3134 rhs
= build_ref_for_model (loc
, rhs
, 0, lacc
, gsi
, false);
3136 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
3138 rhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, TREE_TYPE (lhs
),
3140 if (is_gimple_reg_type (TREE_TYPE (lhs
))
3141 && TREE_CODE (lhs
) != SSA_NAME
)
3142 force_gimple_rhs
= true;
3147 if (lacc
&& lacc
->grp_to_be_debug_replaced
)
3149 tree dlhs
= get_access_replacement (lacc
);
3150 tree drhs
= unshare_expr (rhs
);
3151 if (!useless_type_conversion_p (TREE_TYPE (dlhs
), TREE_TYPE (drhs
)))
3153 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs
))
3154 && !contains_vce_or_bfcref_p (drhs
))
3155 drhs
= build_debug_ref_for_model (loc
, drhs
, 0, lacc
);
3157 && !useless_type_conversion_p (TREE_TYPE (dlhs
),
3159 drhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
,
3160 TREE_TYPE (dlhs
), drhs
);
3162 gimple ds
= gimple_build_debug_bind (dlhs
, drhs
, *stmt
);
3163 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
3166 /* From this point on, the function deals with assignments in between
3167 aggregates when at least one has scalar reductions of some of its
3168 components. There are three possible scenarios: Both the LHS and RHS have
3169 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3171 In the first case, we would like to load the LHS components from RHS
3172 components whenever possible. If that is not possible, we would like to
3173 read it directly from the RHS (after updating it by storing in it its own
3174 components). If there are some necessary unscalarized data in the LHS,
3175 those will be loaded by the original assignment too. If neither of these
3176 cases happen, the original statement can be removed. Most of this is done
3177 by load_assign_lhs_subreplacements.
3179 In the second case, we would like to store all RHS scalarized components
3180 directly into LHS and if they cover the aggregate completely, remove the
3181 statement too. In the third case, we want the LHS components to be loaded
3182 directly from the RHS (DSE will remove the original statement if it
3185 This is a bit complex but manageable when types match and when unions do
3186 not cause confusion in a way that we cannot really load a component of LHS
3187 from the RHS or vice versa (the access representing this level can have
3188 subaccesses that are accessible only through a different union field at a
3189 higher level - different from the one used in the examined expression).
3192 Therefore, I specially handle a fourth case, happening when there is a
3193 specific type cast or it is impossible to locate a scalarized subaccess on
3194 the other side of the expression. If that happens, I simply "refresh" the
3195 RHS by storing in it is scalarized components leave the original statement
3196 there to do the copying and then load the scalar replacements of the LHS.
3197 This is what the first branch does. */
3199 if (modify_this_stmt
3200 || gimple_has_volatile_ops (*stmt
)
3201 || contains_vce_or_bfcref_p (rhs
)
3202 || contains_vce_or_bfcref_p (lhs
))
3204 if (access_has_children_p (racc
))
3205 generate_subtree_copies (racc
->first_child
, racc
->base
, 0, 0, 0,
3206 gsi
, false, false, loc
);
3207 if (access_has_children_p (lacc
))
3208 generate_subtree_copies (lacc
->first_child
, lacc
->base
, 0, 0, 0,
3209 gsi
, true, true, loc
);
3210 sra_stats
.separate_lhs_rhs_handling
++;
3212 /* This gimplification must be done after generate_subtree_copies,
3213 lest we insert the subtree copies in the middle of the gimplified
3215 if (force_gimple_rhs
)
3216 rhs
= force_gimple_operand_gsi (&orig_gsi
, rhs
, true, NULL_TREE
,
3217 true, GSI_SAME_STMT
);
3218 if (gimple_assign_rhs1 (*stmt
) != rhs
)
3220 modify_this_stmt
= true;
3221 gimple_assign_set_rhs_from_tree (&orig_gsi
, rhs
);
3222 gcc_assert (*stmt
== gsi_stmt (orig_gsi
));
3225 return modify_this_stmt
? SRA_AM_MODIFIED
: SRA_AM_NONE
;
3229 if (access_has_children_p (lacc
)
3230 && access_has_children_p (racc
)
3231 /* When an access represents an unscalarizable region, it usually
3232 represents accesses with variable offset and thus must not be used
3233 to generate new memory accesses. */
3234 && !lacc
->grp_unscalarizable_region
3235 && !racc
->grp_unscalarizable_region
)
3237 gimple_stmt_iterator orig_gsi
= *gsi
;
3238 enum unscalarized_data_handling refreshed
;
3240 if (lacc
->grp_read
&& !lacc
->grp_covered
)
3241 refreshed
= handle_unscalarized_data_in_subtree (racc
, gsi
);
3243 refreshed
= SRA_UDH_NONE
;
3245 load_assign_lhs_subreplacements (lacc
, racc
, lacc
->offset
,
3246 &orig_gsi
, gsi
, &refreshed
);
3247 if (refreshed
!= SRA_UDH_RIGHT
)
3250 unlink_stmt_vdef (*stmt
);
3251 gsi_remove (&orig_gsi
, true);
3252 release_defs (*stmt
);
3253 sra_stats
.deleted
++;
3254 return SRA_AM_REMOVED
;
3259 if (access_has_children_p (racc
)
3260 && !racc
->grp_unscalarized_data
)
3264 fprintf (dump_file
, "Removing load: ");
3265 print_gimple_stmt (dump_file
, *stmt
, 0, 0);
3267 generate_subtree_copies (racc
->first_child
, lhs
,
3268 racc
->offset
, 0, 0, gsi
,
3270 gcc_assert (*stmt
== gsi_stmt (*gsi
));
3271 unlink_stmt_vdef (*stmt
);
3272 gsi_remove (gsi
, true);
3273 release_defs (*stmt
);
3274 sra_stats
.deleted
++;
3275 return SRA_AM_REMOVED
;
3277 /* Restore the aggregate RHS from its components so the
3278 prevailing aggregate copy does the right thing. */
3279 if (access_has_children_p (racc
))
3280 generate_subtree_copies (racc
->first_child
, racc
->base
, 0, 0, 0,
3281 gsi
, false, false, loc
);
3282 /* Re-load the components of the aggregate copy destination.
3283 But use the RHS aggregate to load from to expose more
3284 optimization opportunities. */
3285 if (access_has_children_p (lacc
))
3286 generate_subtree_copies (lacc
->first_child
, rhs
, lacc
->offset
,
3287 0, 0, gsi
, true, true, loc
);
3294 /* Traverse the function body and all modifications as decided in
3295 analyze_all_variable_accesses. Return true iff the CFG has been
3299 sra_modify_function_body (void)
3301 bool cfg_changed
= false;
3306 gimple_stmt_iterator gsi
= gsi_start_bb (bb
);
3307 while (!gsi_end_p (gsi
))
3309 gimple stmt
= gsi_stmt (gsi
);
3310 enum assignment_mod_result assign_result
;
3311 bool modified
= false, deleted
= false;
3315 switch (gimple_code (stmt
))
3318 t
= gimple_return_retval_ptr (stmt
);
3319 if (*t
!= NULL_TREE
)
3320 modified
|= sra_modify_expr (t
, &gsi
, false);
3324 assign_result
= sra_modify_assign (&stmt
, &gsi
);
3325 modified
|= assign_result
== SRA_AM_MODIFIED
;
3326 deleted
= assign_result
== SRA_AM_REMOVED
;
3330 /* Operands must be processed before the lhs. */
3331 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
3333 t
= gimple_call_arg_ptr (stmt
, i
);
3334 modified
|= sra_modify_expr (t
, &gsi
, false);
3337 if (gimple_call_lhs (stmt
))
3339 t
= gimple_call_lhs_ptr (stmt
);
3340 modified
|= sra_modify_expr (t
, &gsi
, true);
3345 for (i
= 0; i
< gimple_asm_ninputs (stmt
); i
++)
3347 t
= &TREE_VALUE (gimple_asm_input_op (stmt
, i
));
3348 modified
|= sra_modify_expr (t
, &gsi
, false);
3350 for (i
= 0; i
< gimple_asm_noutputs (stmt
); i
++)
3352 t
= &TREE_VALUE (gimple_asm_output_op (stmt
, i
));
3353 modified
|= sra_modify_expr (t
, &gsi
, true);
3364 if (maybe_clean_eh_stmt (stmt
)
3365 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
3376 /* Generate statements initializing scalar replacements of parts of function
3380 initialize_parameter_reductions (void)
3382 gimple_stmt_iterator gsi
;
3383 gimple_seq seq
= NULL
;
3386 gsi
= gsi_start (seq
);
3387 for (parm
= DECL_ARGUMENTS (current_function_decl
);
3389 parm
= DECL_CHAIN (parm
))
3391 vec
<access_p
> *access_vec
;
3392 struct access
*access
;
3394 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
3396 access_vec
= get_base_access_vector (parm
);
3400 for (access
= (*access_vec
)[0];
3402 access
= access
->next_grp
)
3403 generate_subtree_copies (access
, parm
, 0, 0, 0, &gsi
, true, true,
3404 EXPR_LOCATION (parm
));
3407 seq
= gsi_seq (gsi
);
3409 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR
), seq
);
3412 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3413 it reveals there are components of some aggregates to be scalarized, it runs
3414 the required transformations. */
3416 perform_intra_sra (void)
3421 if (!find_var_candidates ())
3424 if (!scan_function ())
3427 if (!analyze_all_variable_accesses ())
3430 if (sra_modify_function_body ())
3431 ret
= TODO_update_ssa
| TODO_cleanup_cfg
;
3433 ret
= TODO_update_ssa
;
3434 initialize_parameter_reductions ();
3436 statistics_counter_event (cfun
, "Scalar replacements created",
3437 sra_stats
.replacements
);
3438 statistics_counter_event (cfun
, "Modified expressions", sra_stats
.exprs
);
3439 statistics_counter_event (cfun
, "Subtree copy stmts",
3440 sra_stats
.subtree_copies
);
3441 statistics_counter_event (cfun
, "Subreplacement stmts",
3442 sra_stats
.subreplacements
);
3443 statistics_counter_event (cfun
, "Deleted stmts", sra_stats
.deleted
);
3444 statistics_counter_event (cfun
, "Separate LHS and RHS handling",
3445 sra_stats
.separate_lhs_rhs_handling
);
3448 sra_deinitialize ();
3452 /* Perform early intraprocedural SRA. */
3454 early_intra_sra (void)
3456 sra_mode
= SRA_MODE_EARLY_INTRA
;
3457 return perform_intra_sra ();
3460 /* Perform "late" intraprocedural SRA. */
3462 late_intra_sra (void)
3464 sra_mode
= SRA_MODE_INTRA
;
3465 return perform_intra_sra ();
3470 gate_intra_sra (void)
3472 return flag_tree_sra
!= 0 && dbg_cnt (tree_sra
);
3478 const pass_data pass_data_sra_early
=
3480 GIMPLE_PASS
, /* type */
3482 OPTGROUP_NONE
, /* optinfo_flags */
3483 true, /* has_gate */
3484 true, /* has_execute */
3485 TV_TREE_SRA
, /* tv_id */
3486 ( PROP_cfg
| PROP_ssa
), /* properties_required */
3487 0, /* properties_provided */
3488 0, /* properties_destroyed */
3489 0, /* todo_flags_start */
3490 ( TODO_update_ssa
| TODO_verify_ssa
), /* todo_flags_finish */
3493 class pass_sra_early
: public gimple_opt_pass
3496 pass_sra_early (gcc::context
*ctxt
)
3497 : gimple_opt_pass (pass_data_sra_early
, ctxt
)
3500 /* opt_pass methods: */
3501 bool gate () { return gate_intra_sra (); }
3502 unsigned int execute () { return early_intra_sra (); }
3504 }; // class pass_sra_early
3509 make_pass_sra_early (gcc::context
*ctxt
)
3511 return new pass_sra_early (ctxt
);
3516 const pass_data pass_data_sra
=
3518 GIMPLE_PASS
, /* type */
3520 OPTGROUP_NONE
, /* optinfo_flags */
3521 true, /* has_gate */
3522 true, /* has_execute */
3523 TV_TREE_SRA
, /* tv_id */
3524 ( PROP_cfg
| PROP_ssa
), /* properties_required */
3525 0, /* properties_provided */
3526 0, /* properties_destroyed */
3527 TODO_update_address_taken
, /* todo_flags_start */
3528 ( TODO_update_ssa
| TODO_verify_ssa
), /* todo_flags_finish */
3531 class pass_sra
: public gimple_opt_pass
3534 pass_sra (gcc::context
*ctxt
)
3535 : gimple_opt_pass (pass_data_sra
, ctxt
)
3538 /* opt_pass methods: */
3539 bool gate () { return gate_intra_sra (); }
3540 unsigned int execute () { return late_intra_sra (); }
3542 }; // class pass_sra
3547 make_pass_sra (gcc::context
*ctxt
)
3549 return new pass_sra (ctxt
);
3553 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3557 is_unused_scalar_param (tree parm
)
3560 return (is_gimple_reg (parm
)
3561 && (!(name
= ssa_default_def (cfun
, parm
))
3562 || has_zero_uses (name
)));
3565 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3566 examine whether there are any direct or otherwise infeasible ones. If so,
3567 return true, otherwise return false. PARM must be a gimple register with a
3568 non-NULL default definition. */
3571 ptr_parm_has_direct_uses (tree parm
)
3573 imm_use_iterator ui
;
3575 tree name
= ssa_default_def (cfun
, parm
);
3578 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
3581 use_operand_p use_p
;
3583 if (is_gimple_debug (stmt
))
3586 /* Valid uses include dereferences on the lhs and the rhs. */
3587 if (gimple_has_lhs (stmt
))
3589 tree lhs
= gimple_get_lhs (stmt
);
3590 while (handled_component_p (lhs
))
3591 lhs
= TREE_OPERAND (lhs
, 0);
3592 if (TREE_CODE (lhs
) == MEM_REF
3593 && TREE_OPERAND (lhs
, 0) == name
3594 && integer_zerop (TREE_OPERAND (lhs
, 1))
3595 && types_compatible_p (TREE_TYPE (lhs
),
3596 TREE_TYPE (TREE_TYPE (name
)))
3597 && !TREE_THIS_VOLATILE (lhs
))
3600 if (gimple_assign_single_p (stmt
))
3602 tree rhs
= gimple_assign_rhs1 (stmt
);
3603 while (handled_component_p (rhs
))
3604 rhs
= TREE_OPERAND (rhs
, 0);
3605 if (TREE_CODE (rhs
) == MEM_REF
3606 && TREE_OPERAND (rhs
, 0) == name
3607 && integer_zerop (TREE_OPERAND (rhs
, 1))
3608 && types_compatible_p (TREE_TYPE (rhs
),
3609 TREE_TYPE (TREE_TYPE (name
)))
3610 && !TREE_THIS_VOLATILE (rhs
))
3613 else if (is_gimple_call (stmt
))
3616 for (i
= 0; i
< gimple_call_num_args (stmt
); ++i
)
3618 tree arg
= gimple_call_arg (stmt
, i
);
3619 while (handled_component_p (arg
))
3620 arg
= TREE_OPERAND (arg
, 0);
3621 if (TREE_CODE (arg
) == MEM_REF
3622 && TREE_OPERAND (arg
, 0) == name
3623 && integer_zerop (TREE_OPERAND (arg
, 1))
3624 && types_compatible_p (TREE_TYPE (arg
),
3625 TREE_TYPE (TREE_TYPE (name
)))
3626 && !TREE_THIS_VOLATILE (arg
))
3631 /* If the number of valid uses does not match the number of
3632 uses in this stmt there is an unhandled use. */
3633 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
3640 BREAK_FROM_IMM_USE_STMT (ui
);
3646 /* Identify candidates for reduction for IPA-SRA based on their type and mark
3647 them in candidate_bitmap. Note that these do not necessarily include
3648 parameter which are unused and thus can be removed. Return true iff any
3649 such candidate has been found. */
3652 find_param_candidates (void)
3659 for (parm
= DECL_ARGUMENTS (current_function_decl
);
3661 parm
= DECL_CHAIN (parm
))
3663 tree type
= TREE_TYPE (parm
);
3668 if (TREE_THIS_VOLATILE (parm
)
3669 || TREE_ADDRESSABLE (parm
)
3670 || (!is_gimple_reg_type (type
) && is_va_list_type (type
)))
3673 if (is_unused_scalar_param (parm
))
3679 if (POINTER_TYPE_P (type
))
3681 type
= TREE_TYPE (type
);
3683 if (TREE_CODE (type
) == FUNCTION_TYPE
3684 || TYPE_VOLATILE (type
)
3685 || (TREE_CODE (type
) == ARRAY_TYPE
3686 && TYPE_NONALIASED_COMPONENT (type
))
3687 || !is_gimple_reg (parm
)
3688 || is_va_list_type (type
)
3689 || ptr_parm_has_direct_uses (parm
))
3692 else if (!AGGREGATE_TYPE_P (type
))
3695 if (!COMPLETE_TYPE_P (type
)
3696 || !tree_fits_uhwi_p (TYPE_SIZE (type
))
3697 || tree_to_uhwi (TYPE_SIZE (type
)) == 0
3698 || (AGGREGATE_TYPE_P (type
)
3699 && type_internals_preclude_sra_p (type
, &msg
)))
3702 bitmap_set_bit (candidate_bitmap
, DECL_UID (parm
));
3703 slot
= candidates
.find_slot_with_hash (parm
, DECL_UID (parm
), INSERT
);
3707 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3709 fprintf (dump_file
, "Candidate (%d): ", DECL_UID (parm
));
3710 print_generic_expr (dump_file
, parm
, 0);
3711 fprintf (dump_file
, "\n");
3715 func_param_count
= count
;
3719 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
3723 mark_maybe_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef ATTRIBUTE_UNUSED
,
3726 struct access
*repr
= (struct access
*) data
;
3728 repr
->grp_maybe_modified
= 1;
3732 /* Analyze what representatives (in linked lists accessible from
3733 REPRESENTATIVES) can be modified by side effects of statements in the
3734 current function. */
3737 analyze_modified_params (vec
<access_p
> representatives
)
3741 for (i
= 0; i
< func_param_count
; i
++)
3743 struct access
*repr
;
3745 for (repr
= representatives
[i
];
3747 repr
= repr
->next_grp
)
3749 struct access
*access
;
3753 if (no_accesses_p (repr
))
3755 if (!POINTER_TYPE_P (TREE_TYPE (repr
->base
))
3756 || repr
->grp_maybe_modified
)
3759 ao_ref_init (&ar
, repr
->expr
);
3760 visited
= BITMAP_ALLOC (NULL
);
3761 for (access
= repr
; access
; access
= access
->next_sibling
)
3763 /* All accesses are read ones, otherwise grp_maybe_modified would
3764 be trivially set. */
3765 walk_aliased_vdefs (&ar
, gimple_vuse (access
->stmt
),
3766 mark_maybe_modified
, repr
, &visited
);
3767 if (repr
->grp_maybe_modified
)
3770 BITMAP_FREE (visited
);
3775 /* Propagate distances in bb_dereferences in the opposite direction than the
3776 control flow edges, in each step storing the maximum of the current value
3777 and the minimum of all successors. These steps are repeated until the table
3778 stabilizes. Note that BBs which might terminate the functions (according to
3779 final_bbs bitmap) never updated in this way. */
3782 propagate_dereference_distances (void)
3784 vec
<basic_block
> queue
;
3787 queue
.create (last_basic_block_for_function (cfun
));
3788 queue
.quick_push (ENTRY_BLOCK_PTR
);
3791 queue
.quick_push (bb
);
3795 while (!queue
.is_empty ())
3799 bool change
= false;
3805 if (bitmap_bit_p (final_bbs
, bb
->index
))
3808 for (i
= 0; i
< func_param_count
; i
++)
3810 int idx
= bb
->index
* func_param_count
+ i
;
3812 HOST_WIDE_INT inh
= 0;
3814 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
3816 int succ_idx
= e
->dest
->index
* func_param_count
+ i
;
3818 if (e
->src
== EXIT_BLOCK_PTR
)
3824 inh
= bb_dereferences
[succ_idx
];
3826 else if (bb_dereferences
[succ_idx
] < inh
)
3827 inh
= bb_dereferences
[succ_idx
];
3830 if (!first
&& bb_dereferences
[idx
] < inh
)
3832 bb_dereferences
[idx
] = inh
;
3837 if (change
&& !bitmap_bit_p (final_bbs
, bb
->index
))
3838 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
3843 e
->src
->aux
= e
->src
;
3844 queue
.quick_push (e
->src
);
3851 /* Dump a dereferences TABLE with heading STR to file F. */
3854 dump_dereferences_table (FILE *f
, const char *str
, HOST_WIDE_INT
*table
)
3858 fprintf (dump_file
, str
);
3859 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR
, EXIT_BLOCK_PTR
, next_bb
)
3861 fprintf (f
, "%4i %i ", bb
->index
, bitmap_bit_p (final_bbs
, bb
->index
));
3862 if (bb
!= EXIT_BLOCK_PTR
)
3865 for (i
= 0; i
< func_param_count
; i
++)
3867 int idx
= bb
->index
* func_param_count
+ i
;
3868 fprintf (f
, " %4" HOST_WIDE_INT_PRINT
"d", table
[idx
]);
3873 fprintf (dump_file
, "\n");
3876 /* Determine what (parts of) parameters passed by reference that are not
3877 assigned to are not certainly dereferenced in this function and thus the
3878 dereferencing cannot be safely moved to the caller without potentially
3879 introducing a segfault. Mark such REPRESENTATIVES as
3880 grp_not_necessarilly_dereferenced.
3882 The dereferenced maximum "distance," i.e. the offset + size of the accessed
3883 part is calculated rather than simple booleans are calculated for each
3884 pointer parameter to handle cases when only a fraction of the whole
3885 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
3888 The maximum dereference distances for each pointer parameter and BB are
3889 already stored in bb_dereference. This routine simply propagates these
3890 values upwards by propagate_dereference_distances and then compares the
3891 distances of individual parameters in the ENTRY BB to the equivalent
3892 distances of each representative of a (fraction of a) parameter. */
3895 analyze_caller_dereference_legality (vec
<access_p
> representatives
)
3899 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3900 dump_dereferences_table (dump_file
,
3901 "Dereference table before propagation:\n",
3904 propagate_dereference_distances ();
3906 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3907 dump_dereferences_table (dump_file
,
3908 "Dereference table after propagation:\n",
3911 for (i
= 0; i
< func_param_count
; i
++)
3913 struct access
*repr
= representatives
[i
];
3914 int idx
= ENTRY_BLOCK_PTR
->index
* func_param_count
+ i
;
3916 if (!repr
|| no_accesses_p (repr
))
3921 if ((repr
->offset
+ repr
->size
) > bb_dereferences
[idx
])
3922 repr
->grp_not_necessarilly_dereferenced
= 1;
3923 repr
= repr
->next_grp
;
3929 /* Return the representative access for the parameter declaration PARM if it is
3930 a scalar passed by reference which is not written to and the pointer value
3931 is not used directly. Thus, if it is legal to dereference it in the caller
3932 and we can rule out modifications through aliases, such parameter should be
3933 turned into one passed by value. Return NULL otherwise. */
3935 static struct access
*
3936 unmodified_by_ref_scalar_representative (tree parm
)
3938 int i
, access_count
;
3939 struct access
*repr
;
3940 vec
<access_p
> *access_vec
;
3942 access_vec
= get_base_access_vector (parm
);
3943 gcc_assert (access_vec
);
3944 repr
= (*access_vec
)[0];
3947 repr
->group_representative
= repr
;
3949 access_count
= access_vec
->length ();
3950 for (i
= 1; i
< access_count
; i
++)
3952 struct access
*access
= (*access_vec
)[i
];
3955 access
->group_representative
= repr
;
3956 access
->next_sibling
= repr
->next_sibling
;
3957 repr
->next_sibling
= access
;
3961 repr
->grp_scalar_ptr
= 1;
3965 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
3966 associated with. REQ_ALIGN is the minimum required alignment. */
3969 access_precludes_ipa_sra_p (struct access
*access
, unsigned int req_align
)
3971 unsigned int exp_align
;
3972 /* Avoid issues such as the second simple testcase in PR 42025. The problem
3973 is incompatible assign in a call statement (and possibly even in asm
3974 statements). This can be relaxed by using a new temporary but only for
3975 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
3976 intraprocedural SRA we deal with this by keeping the old aggregate around,
3977 something we cannot do in IPA-SRA.) */
3979 && (is_gimple_call (access
->stmt
)
3980 || gimple_code (access
->stmt
) == GIMPLE_ASM
))
3983 exp_align
= get_object_alignment (access
->expr
);
3984 if (exp_align
< req_align
)
3991 /* Sort collected accesses for parameter PARM, identify representatives for
3992 each accessed region and link them together. Return NULL if there are
3993 different but overlapping accesses, return the special ptr value meaning
3994 there are no accesses for this parameter if that is the case and return the
3995 first representative otherwise. Set *RO_GRP if there is a group of accesses
3996 with only read (i.e. no write) accesses. */
3998 static struct access
*
3999 splice_param_accesses (tree parm
, bool *ro_grp
)
4001 int i
, j
, access_count
, group_count
;
4002 int agg_size
, total_size
= 0;
4003 struct access
*access
, *res
, **prev_acc_ptr
= &res
;
4004 vec
<access_p
> *access_vec
;
4006 access_vec
= get_base_access_vector (parm
);
4008 return &no_accesses_representant
;
4009 access_count
= access_vec
->length ();
4011 access_vec
->qsort (compare_access_positions
);
4016 while (i
< access_count
)
4020 access
= (*access_vec
)[i
];
4021 modification
= access
->write
;
4022 if (access_precludes_ipa_sra_p (access
, TYPE_ALIGN (access
->type
)))
4024 a1_alias_type
= reference_alias_ptr_type (access
->expr
);
4026 /* Access is about to become group representative unless we find some
4027 nasty overlap which would preclude us from breaking this parameter
4031 while (j
< access_count
)
4033 struct access
*ac2
= (*access_vec
)[j
];
4034 if (ac2
->offset
!= access
->offset
)
4036 /* All or nothing law for parameters. */
4037 if (access
->offset
+ access
->size
> ac2
->offset
)
4042 else if (ac2
->size
!= access
->size
)
4045 if (access_precludes_ipa_sra_p (ac2
, TYPE_ALIGN (access
->type
))
4046 || (ac2
->type
!= access
->type
4047 && (TREE_ADDRESSABLE (ac2
->type
)
4048 || TREE_ADDRESSABLE (access
->type
)))
4049 || (reference_alias_ptr_type (ac2
->expr
) != a1_alias_type
))
4052 modification
|= ac2
->write
;
4053 ac2
->group_representative
= access
;
4054 ac2
->next_sibling
= access
->next_sibling
;
4055 access
->next_sibling
= ac2
;
4060 access
->grp_maybe_modified
= modification
;
4063 *prev_acc_ptr
= access
;
4064 prev_acc_ptr
= &access
->next_grp
;
4065 total_size
+= access
->size
;
4069 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4070 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm
))));
4072 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm
)));
4073 if (total_size
>= agg_size
)
4076 gcc_assert (group_count
> 0);
4080 /* Decide whether parameters with representative accesses given by REPR should
4081 be reduced into components. */
4084 decide_one_param_reduction (struct access
*repr
)
4086 int total_size
, cur_parm_size
, agg_size
, new_param_count
, parm_size_limit
;
4091 cur_parm_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm
)));
4092 gcc_assert (cur_parm_size
> 0);
4094 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4097 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm
))));
4102 agg_size
= cur_parm_size
;
4108 fprintf (dump_file
, "Evaluating PARAM group sizes for ");
4109 print_generic_expr (dump_file
, parm
, 0);
4110 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (parm
));
4111 for (acc
= repr
; acc
; acc
= acc
->next_grp
)
4112 dump_access (dump_file
, acc
, true);
4116 new_param_count
= 0;
4118 for (; repr
; repr
= repr
->next_grp
)
4120 gcc_assert (parm
== repr
->base
);
4122 /* Taking the address of a non-addressable field is verboten. */
4123 if (by_ref
&& repr
->non_addressable
)
4126 /* Do not decompose a non-BLKmode param in a way that would
4127 create BLKmode params. Especially for by-reference passing
4128 (thus, pointer-type param) this is hardly worthwhile. */
4129 if (DECL_MODE (parm
) != BLKmode
4130 && TYPE_MODE (repr
->type
) == BLKmode
)
4133 if (!by_ref
|| (!repr
->grp_maybe_modified
4134 && !repr
->grp_not_necessarilly_dereferenced
))
4135 total_size
+= repr
->size
;
4137 total_size
+= cur_parm_size
;
4142 gcc_assert (new_param_count
> 0);
4144 if (optimize_function_for_size_p (cfun
))
4145 parm_size_limit
= cur_parm_size
;
4147 parm_size_limit
= (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR
)
4150 if (total_size
< agg_size
4151 && total_size
<= parm_size_limit
)
4154 fprintf (dump_file
, " ....will be split into %i components\n",
4156 return new_param_count
;
4162 /* The order of the following enums is important, we need to do extra work for
4163 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4164 enum ipa_splicing_result
{ NO_GOOD_ACCESS
, UNUSED_PARAMS
, BY_VAL_ACCESSES
,
4165 MODIF_BY_REF_ACCESSES
, UNMODIF_BY_REF_ACCESSES
};
4167 /* Identify representatives of all accesses to all candidate parameters for
4168 IPA-SRA. Return result based on what representatives have been found. */
4170 static enum ipa_splicing_result
4171 splice_all_param_accesses (vec
<access_p
> &representatives
)
4173 enum ipa_splicing_result result
= NO_GOOD_ACCESS
;
4175 struct access
*repr
;
4177 representatives
.create (func_param_count
);
4179 for (parm
= DECL_ARGUMENTS (current_function_decl
);
4181 parm
= DECL_CHAIN (parm
))
4183 if (is_unused_scalar_param (parm
))
4185 representatives
.quick_push (&no_accesses_representant
);
4186 if (result
== NO_GOOD_ACCESS
)
4187 result
= UNUSED_PARAMS
;
4189 else if (POINTER_TYPE_P (TREE_TYPE (parm
))
4190 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm
)))
4191 && bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
4193 repr
= unmodified_by_ref_scalar_representative (parm
);
4194 representatives
.quick_push (repr
);
4196 result
= UNMODIF_BY_REF_ACCESSES
;
4198 else if (bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
4200 bool ro_grp
= false;
4201 repr
= splice_param_accesses (parm
, &ro_grp
);
4202 representatives
.quick_push (repr
);
4204 if (repr
&& !no_accesses_p (repr
))
4206 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4209 result
= UNMODIF_BY_REF_ACCESSES
;
4210 else if (result
< MODIF_BY_REF_ACCESSES
)
4211 result
= MODIF_BY_REF_ACCESSES
;
4213 else if (result
< BY_VAL_ACCESSES
)
4214 result
= BY_VAL_ACCESSES
;
4216 else if (no_accesses_p (repr
) && (result
== NO_GOOD_ACCESS
))
4217 result
= UNUSED_PARAMS
;
4220 representatives
.quick_push (NULL
);
4223 if (result
== NO_GOOD_ACCESS
)
4225 representatives
.release ();
4226 return NO_GOOD_ACCESS
;
4232 /* Return the index of BASE in PARMS. Abort if it is not found. */
4235 get_param_index (tree base
, vec
<tree
> parms
)
4239 len
= parms
.length ();
4240 for (i
= 0; i
< len
; i
++)
4241 if (parms
[i
] == base
)
4246 /* Convert the decisions made at the representative level into compact
4247 parameter adjustments. REPRESENTATIVES are pointers to first
4248 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4249 final number of adjustments. */
4251 static ipa_parm_adjustment_vec
4252 turn_representatives_into_adjustments (vec
<access_p
> representatives
,
4253 int adjustments_count
)
4256 ipa_parm_adjustment_vec adjustments
;
4260 gcc_assert (adjustments_count
> 0);
4261 parms
= ipa_get_vector_of_formal_parms (current_function_decl
);
4262 adjustments
.create (adjustments_count
);
4263 parm
= DECL_ARGUMENTS (current_function_decl
);
4264 for (i
= 0; i
< func_param_count
; i
++, parm
= DECL_CHAIN (parm
))
4266 struct access
*repr
= representatives
[i
];
4268 if (!repr
|| no_accesses_p (repr
))
4270 struct ipa_parm_adjustment adj
;
4272 memset (&adj
, 0, sizeof (adj
));
4273 adj
.base_index
= get_param_index (parm
, parms
);
4278 adj
.remove_param
= 1;
4279 adjustments
.quick_push (adj
);
4283 struct ipa_parm_adjustment adj
;
4284 int index
= get_param_index (parm
, parms
);
4286 for (; repr
; repr
= repr
->next_grp
)
4288 memset (&adj
, 0, sizeof (adj
));
4289 gcc_assert (repr
->base
== parm
);
4290 adj
.base_index
= index
;
4291 adj
.base
= repr
->base
;
4292 adj
.type
= repr
->type
;
4293 adj
.alias_ptr_type
= reference_alias_ptr_type (repr
->expr
);
4294 adj
.offset
= repr
->offset
;
4295 adj
.by_ref
= (POINTER_TYPE_P (TREE_TYPE (repr
->base
))
4296 && (repr
->grp_maybe_modified
4297 || repr
->grp_not_necessarilly_dereferenced
));
4298 adjustments
.quick_push (adj
);
4306 /* Analyze the collected accesses and produce a plan what to do with the
4307 parameters in the form of adjustments, NULL meaning nothing. */
4309 static ipa_parm_adjustment_vec
4310 analyze_all_param_acesses (void)
4312 enum ipa_splicing_result repr_state
;
4313 bool proceed
= false;
4314 int i
, adjustments_count
= 0;
4315 vec
<access_p
> representatives
;
4316 ipa_parm_adjustment_vec adjustments
;
4318 repr_state
= splice_all_param_accesses (representatives
);
4319 if (repr_state
== NO_GOOD_ACCESS
)
4320 return ipa_parm_adjustment_vec ();
4322 /* If there are any parameters passed by reference which are not modified
4323 directly, we need to check whether they can be modified indirectly. */
4324 if (repr_state
== UNMODIF_BY_REF_ACCESSES
)
4326 analyze_caller_dereference_legality (representatives
);
4327 analyze_modified_params (representatives
);
4330 for (i
= 0; i
< func_param_count
; i
++)
4332 struct access
*repr
= representatives
[i
];
4334 if (repr
&& !no_accesses_p (repr
))
4336 if (repr
->grp_scalar_ptr
)
4338 adjustments_count
++;
4339 if (repr
->grp_not_necessarilly_dereferenced
4340 || repr
->grp_maybe_modified
)
4341 representatives
[i
] = NULL
;
4345 sra_stats
.scalar_by_ref_to_by_val
++;
4350 int new_components
= decide_one_param_reduction (repr
);
4352 if (new_components
== 0)
4354 representatives
[i
] = NULL
;
4355 adjustments_count
++;
4359 adjustments_count
+= new_components
;
4360 sra_stats
.aggregate_params_reduced
++;
4361 sra_stats
.param_reductions_created
+= new_components
;
4368 if (no_accesses_p (repr
))
4371 sra_stats
.deleted_unused_parameters
++;
4373 adjustments_count
++;
4377 if (!proceed
&& dump_file
)
4378 fprintf (dump_file
, "NOT proceeding to change params.\n");
4381 adjustments
= turn_representatives_into_adjustments (representatives
,
4384 adjustments
= ipa_parm_adjustment_vec ();
4386 representatives
.release ();
4390 /* If a parameter replacement identified by ADJ does not yet exist in the form
4391 of declaration, create it and record it, otherwise return the previously
4395 get_replaced_param_substitute (struct ipa_parm_adjustment
*adj
)
4398 if (!adj
->new_ssa_base
)
4400 char *pretty_name
= make_fancy_name (adj
->base
);
4402 repl
= create_tmp_reg (TREE_TYPE (adj
->base
), "ISR");
4403 DECL_NAME (repl
) = get_identifier (pretty_name
);
4404 obstack_free (&name_obstack
, pretty_name
);
4406 adj
->new_ssa_base
= repl
;
4409 repl
= adj
->new_ssa_base
;
4413 /* Find the first adjustment for a particular parameter BASE in a vector of
4414 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4417 static struct ipa_parm_adjustment
*
4418 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments
, tree base
)
4422 len
= adjustments
.length ();
4423 for (i
= 0; i
< len
; i
++)
4425 struct ipa_parm_adjustment
*adj
;
4427 adj
= &adjustments
[i
];
4428 if (!adj
->copy_param
&& adj
->base
== base
)
4435 /* If the statement STMT defines an SSA_NAME of a parameter which is to be
4436 removed because its value is not used, replace the SSA_NAME with a one
4437 relating to a created VAR_DECL together all of its uses and return true.
4438 ADJUSTMENTS is a pointer to an adjustments vector. */
4441 replace_removed_params_ssa_names (gimple stmt
,
4442 ipa_parm_adjustment_vec adjustments
)
4444 struct ipa_parm_adjustment
*adj
;
4445 tree lhs
, decl
, repl
, name
;
4447 if (gimple_code (stmt
) == GIMPLE_PHI
)
4448 lhs
= gimple_phi_result (stmt
);
4449 else if (is_gimple_assign (stmt
))
4450 lhs
= gimple_assign_lhs (stmt
);
4451 else if (is_gimple_call (stmt
))
4452 lhs
= gimple_call_lhs (stmt
);
4456 if (TREE_CODE (lhs
) != SSA_NAME
)
4459 decl
= SSA_NAME_VAR (lhs
);
4460 if (decl
== NULL_TREE
4461 || TREE_CODE (decl
) != PARM_DECL
)
4464 adj
= get_adjustment_for_base (adjustments
, decl
);
4468 repl
= get_replaced_param_substitute (adj
);
4469 name
= make_ssa_name (repl
, stmt
);
4473 fprintf (dump_file
, "replacing an SSA name of a removed param ");
4474 print_generic_expr (dump_file
, lhs
, 0);
4475 fprintf (dump_file
, " with ");
4476 print_generic_expr (dump_file
, name
, 0);
4477 fprintf (dump_file
, "\n");
4480 if (is_gimple_assign (stmt
))
4481 gimple_assign_set_lhs (stmt
, name
);
4482 else if (is_gimple_call (stmt
))
4483 gimple_call_set_lhs (stmt
, name
);
4485 gimple_phi_set_result (stmt
, name
);
4487 replace_uses_by (lhs
, name
);
4488 release_ssa_name (lhs
);
4492 /* If the expression *EXPR should be replaced by a reduction of a parameter, do
4493 so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
4494 specifies whether the function should care about type incompatibility the
4495 current and new expressions. If it is false, the function will leave
4496 incompatibility issues to the caller. Return true iff the expression
4500 sra_ipa_modify_expr (tree
*expr
, bool convert
,
4501 ipa_parm_adjustment_vec adjustments
)
4504 struct ipa_parm_adjustment
*adj
, *cand
= NULL
;
4505 HOST_WIDE_INT offset
, size
, max_size
;
4508 len
= adjustments
.length ();
4510 if (TREE_CODE (*expr
) == BIT_FIELD_REF
4511 || TREE_CODE (*expr
) == IMAGPART_EXPR
4512 || TREE_CODE (*expr
) == REALPART_EXPR
)
4514 expr
= &TREE_OPERAND (*expr
, 0);
4518 base
= get_ref_base_and_extent (*expr
, &offset
, &size
, &max_size
);
4519 if (!base
|| size
== -1 || max_size
== -1)
4522 if (TREE_CODE (base
) == MEM_REF
)
4524 offset
+= mem_ref_offset (base
).low
* BITS_PER_UNIT
;
4525 base
= TREE_OPERAND (base
, 0);
4528 base
= get_ssa_base_param (base
);
4529 if (!base
|| TREE_CODE (base
) != PARM_DECL
)
4532 for (i
= 0; i
< len
; i
++)
4534 adj
= &adjustments
[i
];
4536 if (adj
->base
== base
4537 && (adj
->offset
== offset
|| adj
->remove_param
))
4543 if (!cand
|| cand
->copy_param
|| cand
->remove_param
)
4547 src
= build_simple_mem_ref (cand
->reduction
);
4549 src
= cand
->reduction
;
4551 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4553 fprintf (dump_file
, "About to replace expr ");
4554 print_generic_expr (dump_file
, *expr
, 0);
4555 fprintf (dump_file
, " with ");
4556 print_generic_expr (dump_file
, src
, 0);
4557 fprintf (dump_file
, "\n");
4560 if (convert
&& !useless_type_conversion_p (TREE_TYPE (*expr
), cand
->type
))
4562 tree vce
= build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (*expr
), src
);
4570 /* If the statement pointed to by STMT_PTR contains any expressions that need
4571 to replaced with a different one as noted by ADJUSTMENTS, do so. Handle any
4572 potential type incompatibilities (GSI is used to accommodate conversion
4573 statements and must point to the statement). Return true iff the statement
4577 sra_ipa_modify_assign (gimple
*stmt_ptr
, gimple_stmt_iterator
*gsi
,
4578 ipa_parm_adjustment_vec adjustments
)
4580 gimple stmt
= *stmt_ptr
;
4581 tree
*lhs_p
, *rhs_p
;
4584 if (!gimple_assign_single_p (stmt
))
4587 rhs_p
= gimple_assign_rhs1_ptr (stmt
);
4588 lhs_p
= gimple_assign_lhs_ptr (stmt
);
4590 any
= sra_ipa_modify_expr (rhs_p
, false, adjustments
);
4591 any
|= sra_ipa_modify_expr (lhs_p
, false, adjustments
);
4594 tree new_rhs
= NULL_TREE
;
4596 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p
), TREE_TYPE (*rhs_p
)))
4598 if (TREE_CODE (*rhs_p
) == CONSTRUCTOR
)
4600 /* V_C_Es of constructors can cause trouble (PR 42714). */
4601 if (is_gimple_reg_type (TREE_TYPE (*lhs_p
)))
4602 *rhs_p
= build_zero_cst (TREE_TYPE (*lhs_p
));
4604 *rhs_p
= build_constructor (TREE_TYPE (*lhs_p
),
4608 new_rhs
= fold_build1_loc (gimple_location (stmt
),
4609 VIEW_CONVERT_EXPR
, TREE_TYPE (*lhs_p
),
4612 else if (REFERENCE_CLASS_P (*rhs_p
)
4613 && is_gimple_reg_type (TREE_TYPE (*lhs_p
))
4614 && !is_gimple_reg (*lhs_p
))
4615 /* This can happen when an assignment in between two single field
4616 structures is turned into an assignment in between two pointers to
4617 scalars (PR 42237). */
4622 tree tmp
= force_gimple_operand_gsi (gsi
, new_rhs
, true, NULL_TREE
,
4623 true, GSI_SAME_STMT
);
4625 gimple_assign_set_rhs_from_tree (gsi
, tmp
);
4634 /* Traverse the function body and all modifications as described in
4635 ADJUSTMENTS. Return true iff the CFG has been changed. */
4638 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments
)
4640 bool cfg_changed
= false;
4645 gimple_stmt_iterator gsi
;
4647 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4648 replace_removed_params_ssa_names (gsi_stmt (gsi
), adjustments
);
4650 gsi
= gsi_start_bb (bb
);
4651 while (!gsi_end_p (gsi
))
4653 gimple stmt
= gsi_stmt (gsi
);
4654 bool modified
= false;
4658 switch (gimple_code (stmt
))
4661 t
= gimple_return_retval_ptr (stmt
);
4662 if (*t
!= NULL_TREE
)
4663 modified
|= sra_ipa_modify_expr (t
, true, adjustments
);
4667 modified
|= sra_ipa_modify_assign (&stmt
, &gsi
, adjustments
);
4668 modified
|= replace_removed_params_ssa_names (stmt
, adjustments
);
4672 /* Operands must be processed before the lhs. */
4673 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
4675 t
= gimple_call_arg_ptr (stmt
, i
);
4676 modified
|= sra_ipa_modify_expr (t
, true, adjustments
);
4679 if (gimple_call_lhs (stmt
))
4681 t
= gimple_call_lhs_ptr (stmt
);
4682 modified
|= sra_ipa_modify_expr (t
, false, adjustments
);
4683 modified
|= replace_removed_params_ssa_names (stmt
,
4689 for (i
= 0; i
< gimple_asm_ninputs (stmt
); i
++)
4691 t
= &TREE_VALUE (gimple_asm_input_op (stmt
, i
));
4692 modified
|= sra_ipa_modify_expr (t
, true, adjustments
);
4694 for (i
= 0; i
< gimple_asm_noutputs (stmt
); i
++)
4696 t
= &TREE_VALUE (gimple_asm_output_op (stmt
, i
));
4697 modified
|= sra_ipa_modify_expr (t
, false, adjustments
);
4708 if (maybe_clean_eh_stmt (stmt
)
4709 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
4719 /* Call gimple_debug_bind_reset_value on all debug statements describing
4720 gimple register parameters that are being removed or replaced. */
4723 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments
)
4726 gimple_stmt_iterator
*gsip
= NULL
, gsi
;
4728 if (MAY_HAVE_DEBUG_STMTS
&& single_succ_p (ENTRY_BLOCK_PTR
))
4730 gsi
= gsi_after_labels (single_succ (ENTRY_BLOCK_PTR
));
4733 len
= adjustments
.length ();
4734 for (i
= 0; i
< len
; i
++)
4736 struct ipa_parm_adjustment
*adj
;
4737 imm_use_iterator ui
;
4738 gimple stmt
, def_temp
;
4739 tree name
, vexpr
, copy
= NULL_TREE
;
4740 use_operand_p use_p
;
4742 adj
= &adjustments
[i
];
4743 if (adj
->copy_param
|| !is_gimple_reg (adj
->base
))
4745 name
= ssa_default_def (cfun
, adj
->base
);
4748 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
4750 if (gimple_clobber_p (stmt
))
4752 gimple_stmt_iterator cgsi
= gsi_for_stmt (stmt
);
4753 unlink_stmt_vdef (stmt
);
4754 gsi_remove (&cgsi
, true);
4755 release_defs (stmt
);
4758 /* All other users must have been removed by
4759 ipa_sra_modify_function_body. */
4760 gcc_assert (is_gimple_debug (stmt
));
4761 if (vexpr
== NULL
&& gsip
!= NULL
)
4763 gcc_assert (TREE_CODE (adj
->base
) == PARM_DECL
);
4764 vexpr
= make_node (DEBUG_EXPR_DECL
);
4765 def_temp
= gimple_build_debug_source_bind (vexpr
, adj
->base
,
4767 DECL_ARTIFICIAL (vexpr
) = 1;
4768 TREE_TYPE (vexpr
) = TREE_TYPE (name
);
4769 DECL_MODE (vexpr
) = DECL_MODE (adj
->base
);
4770 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
4774 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
4775 SET_USE (use_p
, vexpr
);
4778 gimple_debug_bind_reset_value (stmt
);
4781 /* Create a VAR_DECL for debug info purposes. */
4782 if (!DECL_IGNORED_P (adj
->base
))
4784 copy
= build_decl (DECL_SOURCE_LOCATION (current_function_decl
),
4785 VAR_DECL
, DECL_NAME (adj
->base
),
4786 TREE_TYPE (adj
->base
));
4787 if (DECL_PT_UID_SET_P (adj
->base
))
4788 SET_DECL_PT_UID (copy
, DECL_PT_UID (adj
->base
));
4789 TREE_ADDRESSABLE (copy
) = TREE_ADDRESSABLE (adj
->base
);
4790 TREE_READONLY (copy
) = TREE_READONLY (adj
->base
);
4791 TREE_THIS_VOLATILE (copy
) = TREE_THIS_VOLATILE (adj
->base
);
4792 DECL_GIMPLE_REG_P (copy
) = DECL_GIMPLE_REG_P (adj
->base
);
4793 DECL_ARTIFICIAL (copy
) = DECL_ARTIFICIAL (adj
->base
);
4794 DECL_IGNORED_P (copy
) = DECL_IGNORED_P (adj
->base
);
4795 DECL_ABSTRACT_ORIGIN (copy
) = DECL_ORIGIN (adj
->base
);
4796 DECL_SEEN_IN_BIND_EXPR_P (copy
) = 1;
4797 SET_DECL_RTL (copy
, 0);
4798 TREE_USED (copy
) = 1;
4799 DECL_CONTEXT (copy
) = current_function_decl
;
4800 add_local_decl (cfun
, copy
);
4802 BLOCK_VARS (DECL_INITIAL (current_function_decl
));
4803 BLOCK_VARS (DECL_INITIAL (current_function_decl
)) = copy
;
4805 if (gsip
!= NULL
&& copy
&& target_for_debug_bind (adj
->base
))
4807 gcc_assert (TREE_CODE (adj
->base
) == PARM_DECL
);
4809 def_temp
= gimple_build_debug_bind (copy
, vexpr
, NULL
);
4811 def_temp
= gimple_build_debug_source_bind (copy
, adj
->base
,
4813 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
4818 /* Return false iff all callers have at least as many actual arguments as there
4819 are formal parameters in the current function. */
4822 not_all_callers_have_enough_arguments_p (struct cgraph_node
*node
,
4823 void *data ATTRIBUTE_UNUSED
)
4825 struct cgraph_edge
*cs
;
4826 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4827 if (!callsite_has_enough_arguments_p (cs
->call_stmt
))
4833 /* Convert all callers of NODE. */
4836 convert_callers_for_node (struct cgraph_node
*node
,
4839 ipa_parm_adjustment_vec
*adjustments
= (ipa_parm_adjustment_vec
*) data
;
4840 bitmap recomputed_callers
= BITMAP_ALLOC (NULL
);
4841 struct cgraph_edge
*cs
;
4843 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4845 push_cfun (DECL_STRUCT_FUNCTION (cs
->caller
->decl
));
4848 fprintf (dump_file
, "Adjusting call %s/%i -> %s/%i\n",
4849 xstrdup (cs
->caller
->name ()),
4851 xstrdup (cs
->callee
->name ()),
4854 ipa_modify_call_arguments (cs
, cs
->call_stmt
, *adjustments
);
4859 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4860 if (bitmap_set_bit (recomputed_callers
, cs
->caller
->uid
)
4861 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs
->caller
->decl
)))
4862 compute_inline_parameters (cs
->caller
, true);
4863 BITMAP_FREE (recomputed_callers
);
4868 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
4871 convert_callers (struct cgraph_node
*node
, tree old_decl
,
4872 ipa_parm_adjustment_vec adjustments
)
4874 basic_block this_block
;
4876 cgraph_for_node_and_aliases (node
, convert_callers_for_node
,
4877 &adjustments
, false);
4879 if (!encountered_recursive_call
)
4882 FOR_EACH_BB (this_block
)
4884 gimple_stmt_iterator gsi
;
4886 for (gsi
= gsi_start_bb (this_block
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4888 gimple stmt
= gsi_stmt (gsi
);
4890 if (gimple_code (stmt
) != GIMPLE_CALL
)
4892 call_fndecl
= gimple_call_fndecl (stmt
);
4893 if (call_fndecl
== old_decl
)
4896 fprintf (dump_file
, "Adjusting recursive call");
4897 gimple_call_set_fndecl (stmt
, node
->decl
);
4898 ipa_modify_call_arguments (NULL
, stmt
, adjustments
);
4906 /* Perform all the modification required in IPA-SRA for NODE to have parameters
4907 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
4910 modify_function (struct cgraph_node
*node
, ipa_parm_adjustment_vec adjustments
)
4912 struct cgraph_node
*new_node
;
4914 vec
<cgraph_edge_p
> redirect_callers
= collect_callers_of_node (node
);
4916 rebuild_cgraph_edges ();
4917 free_dominance_info (CDI_DOMINATORS
);
4920 new_node
= cgraph_function_versioning (node
, redirect_callers
,
4922 NULL
, false, NULL
, NULL
, "isra");
4923 redirect_callers
.release ();
4925 push_cfun (DECL_STRUCT_FUNCTION (new_node
->decl
));
4926 ipa_modify_formal_parameters (current_function_decl
, adjustments
, "ISRA");
4927 cfg_changed
= ipa_sra_modify_function_body (adjustments
);
4928 sra_ipa_reset_debug_stmts (adjustments
);
4929 convert_callers (new_node
, node
->decl
, adjustments
);
4930 cgraph_make_node_local (new_node
);
4934 /* If NODE has a caller, return true. */
4937 has_caller_p (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
4944 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
4945 attributes, return true otherwise. NODE is the cgraph node of the current
4949 ipa_sra_preliminary_function_checks (struct cgraph_node
*node
)
4951 if (!cgraph_node_can_be_local_p (node
))
4954 fprintf (dump_file
, "Function not local to this compilation unit.\n");
4958 if (!node
->local
.can_change_signature
)
4961 fprintf (dump_file
, "Function can not change signature.\n");
4965 if (!tree_versionable_function_p (node
->decl
))
4968 fprintf (dump_file
, "Function is not versionable.\n");
4972 if (DECL_VIRTUAL_P (current_function_decl
))
4975 fprintf (dump_file
, "Function is a virtual method.\n");
4979 if ((DECL_COMDAT (node
->decl
) || DECL_EXTERNAL (node
->decl
))
4980 && inline_summary (node
)->size
>= MAX_INLINE_INSNS_AUTO
)
4983 fprintf (dump_file
, "Function too big to be made truly local.\n");
4987 if (!cgraph_for_node_and_aliases (node
, has_caller_p
, NULL
, true))
4991 "Function has no callers in this compilation unit.\n");
4998 fprintf (dump_file
, "Function uses stdarg. \n");
5002 if (TYPE_ATTRIBUTES (TREE_TYPE (node
->decl
)))
5008 /* Perform early interprocedural SRA. */
5011 ipa_early_sra (void)
5013 struct cgraph_node
*node
= cgraph_get_node (current_function_decl
);
5014 ipa_parm_adjustment_vec adjustments
;
5017 if (!ipa_sra_preliminary_function_checks (node
))
5021 sra_mode
= SRA_MODE_EARLY_IPA
;
5023 if (!find_param_candidates ())
5026 fprintf (dump_file
, "Function has no IPA-SRA candidates.\n");
5030 if (cgraph_for_node_and_aliases (node
, not_all_callers_have_enough_arguments_p
,
5034 fprintf (dump_file
, "There are callers with insufficient number of "
5039 bb_dereferences
= XCNEWVEC (HOST_WIDE_INT
,
5041 * last_basic_block_for_function (cfun
));
5042 final_bbs
= BITMAP_ALLOC (NULL
);
5045 if (encountered_apply_args
)
5048 fprintf (dump_file
, "Function calls __builtin_apply_args().\n");
5052 if (encountered_unchangable_recursive_call
)
5055 fprintf (dump_file
, "Function calls itself with insufficient "
5056 "number of arguments.\n");
5060 adjustments
= analyze_all_param_acesses ();
5061 if (!adjustments
.exists ())
5064 ipa_dump_param_adjustments (dump_file
, adjustments
, current_function_decl
);
5066 if (modify_function (node
, adjustments
))
5067 ret
= TODO_update_ssa
| TODO_cleanup_cfg
;
5069 ret
= TODO_update_ssa
;
5070 adjustments
.release ();
5072 statistics_counter_event (cfun
, "Unused parameters deleted",
5073 sra_stats
.deleted_unused_parameters
);
5074 statistics_counter_event (cfun
, "Scalar parameters converted to by-value",
5075 sra_stats
.scalar_by_ref_to_by_val
);
5076 statistics_counter_event (cfun
, "Aggregate parameters broken up",
5077 sra_stats
.aggregate_params_reduced
);
5078 statistics_counter_event (cfun
, "Aggregate parameter components created",
5079 sra_stats
.param_reductions_created
);
5082 BITMAP_FREE (final_bbs
);
5083 free (bb_dereferences
);
5085 sra_deinitialize ();
5089 /* Return if early ipa sra shall be performed. */
5091 ipa_early_sra_gate (void)
5093 return flag_ipa_sra
&& dbg_cnt (eipa_sra
);
5098 const pass_data pass_data_early_ipa_sra
=
5100 GIMPLE_PASS
, /* type */
5101 "eipa_sra", /* name */
5102 OPTGROUP_NONE
, /* optinfo_flags */
5103 true, /* has_gate */
5104 true, /* has_execute */
5105 TV_IPA_SRA
, /* tv_id */
5106 0, /* properties_required */
5107 0, /* properties_provided */
5108 0, /* properties_destroyed */
5109 0, /* todo_flags_start */
5110 TODO_dump_symtab
, /* todo_flags_finish */
5113 class pass_early_ipa_sra
: public gimple_opt_pass
5116 pass_early_ipa_sra (gcc::context
*ctxt
)
5117 : gimple_opt_pass (pass_data_early_ipa_sra
, ctxt
)
5120 /* opt_pass methods: */
5121 bool gate () { return ipa_early_sra_gate (); }
5122 unsigned int execute () { return ipa_early_sra (); }
5124 }; // class pass_early_ipa_sra
5129 make_pass_early_ipa_sra (gcc::context
*ctxt
)
5131 return new pass_early_ipa_sra (ctxt
);