1 /* Scalar Replacement of Aggregates (SRA) converts some structure
2 references into scalar references, exposing them to the scalar
4 Copyright (C) 2008-2014 Free Software Foundation, Inc.
5 Contributed by Martin Jambor <mjambor@suse.cz>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* This file implements Scalar Reduction of Aggregates (SRA). SRA is run
24 twice, once in the early stages of compilation (early SRA) and once in the
25 late stages (late SRA). The aim of both is to turn references to scalar
26 parts of aggregates into uses of independent scalar variables.
28 The two passes are nearly identical, the only difference is that early SRA
29 does not scalarize unions which are used as the result in a GIMPLE_RETURN
30 statement because together with inlining this can lead to weird type
33 Both passes operate in four stages:
35 1. The declarations that have properties which make them candidates for
36 scalarization are identified in function find_var_candidates(). The
37 candidates are stored in candidate_bitmap.
39 2. The function body is scanned. In the process, declarations which are
40 used in a manner that prevent their scalarization are removed from the
41 candidate bitmap. More importantly, for every access into an aggregate,
42 an access structure (struct access) is created by create_access() and
43 stored in a vector associated with the aggregate. Among other
44 information, the aggregate declaration, the offset and size of the access
45 and its type are stored in the structure.
47 On a related note, assign_link structures are created for every assign
48 statement between candidate aggregates and attached to the related
51 3. The vectors of accesses are analyzed. They are first sorted according to
52 their offset and size and then scanned for partially overlapping accesses
53 (i.e. those which overlap but one is not entirely within another). Such
54 an access disqualifies the whole aggregate from being scalarized.
56 If there is no such inhibiting overlap, a representative access structure
57 is chosen for every unique combination of offset and size. Afterwards,
58 the pass builds a set of trees from these structures, in which children
59 of an access are within their parent (in terms of offset and size).
61 Then accesses are propagated whenever possible (i.e. in cases when it
62 does not create a partially overlapping access) across assign_links from
63 the right hand side to the left hand side.
65 Then the set of trees for each declaration is traversed again and those
66 accesses which should be replaced by a scalar are identified.
68 4. The function is traversed again, and for every reference into an
69 aggregate that has some component which is about to be scalarized,
70 statements are amended and new statements are created as necessary.
71 Finally, if a parameter got scalarized, the scalar replacements are
72 initialized with values from respective parameter aggregates. */
76 #include "coretypes.h"
77 #include "hash-table.h"
78 #include "alloc-pool.h"
81 #include "pointer-set.h"
82 #include "basic-block.h"
83 #include "tree-ssa-alias.h"
84 #include "internal-fn.h"
86 #include "gimple-expr.h"
89 #include "stor-layout.h"
91 #include "gimple-iterator.h"
92 #include "gimplify-me.h"
93 #include "gimple-walk.h"
95 #include "gimple-ssa.h"
97 #include "tree-phinodes.h"
98 #include "ssa-iterators.h"
99 #include "stringpool.h"
100 #include "tree-ssanames.h"
102 #include "tree-dfa.h"
103 #include "tree-ssa.h"
104 #include "tree-pass.h"
105 #include "ipa-prop.h"
106 #include "statistics.h"
112 #include "tree-inline.h"
113 #include "gimple-pretty-print.h"
115 #include "ipa-inline.h"
116 #include "ipa-utils.h"
118 /* Enumeration of all aggregate reductions we can do. */
119 enum sra_mode
{ SRA_MODE_EARLY_IPA
, /* early call regularization */
120 SRA_MODE_EARLY_INTRA
, /* early intraprocedural SRA */
121 SRA_MODE_INTRA
}; /* late intraprocedural SRA */
123 /* Global variable describing which aggregate reduction we are performing at
125 static enum sra_mode sra_mode
;
129 /* ACCESS represents each access to an aggregate variable (as a whole or a
130 part). It can also represent a group of accesses that refer to exactly the
131 same fragment of an aggregate (i.e. those that have exactly the same offset
132 and size). Such representatives for a single aggregate, once determined,
133 are linked in a linked list and have the group fields set.
135 Moreover, when doing intraprocedural SRA, a tree is built from those
136 representatives (by the means of first_child and next_sibling pointers), in
137 which all items in a subtree are "within" the root, i.e. their offset is
138 greater or equal to offset of the root and offset+size is smaller or equal
139 to offset+size of the root. Children of an access are sorted by offset.
141 Note that accesses to parts of vector and complex number types always
142 represented by an access to the whole complex number or a vector. It is a
143 duty of the modifying functions to replace them appropriately. */
147 /* Values returned by `get_ref_base_and_extent' for each component reference
148 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
149 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
150 HOST_WIDE_INT offset
;
154 /* Expression. It is context dependent so do not use it to create new
155 expressions to access the original aggregate. See PR 42154 for a
161 /* The statement this access belongs to. */
164 /* Next group representative for this aggregate. */
165 struct access
*next_grp
;
167 /* Pointer to the group representative. Pointer to itself if the struct is
168 the representative. */
169 struct access
*group_representative
;
171 /* If this access has any children (in terms of the definition above), this
172 points to the first one. */
173 struct access
*first_child
;
175 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
176 described above. In IPA-SRA this is a pointer to the next access
177 belonging to the same group (having the same representative). */
178 struct access
*next_sibling
;
180 /* Pointers to the first and last element in the linked list of assign
182 struct assign_link
*first_link
, *last_link
;
184 /* Pointer to the next access in the work queue. */
185 struct access
*next_queued
;
187 /* Replacement variable for this access "region." Never to be accessed
188 directly, always only by the means of get_access_replacement() and only
189 when grp_to_be_replaced flag is set. */
190 tree replacement_decl
;
192 /* Is this particular access write access? */
195 /* Is this access an access to a non-addressable field? */
196 unsigned non_addressable
: 1;
198 /* Is this access currently in the work queue? */
199 unsigned grp_queued
: 1;
201 /* Does this group contain a write access? This flag is propagated down the
203 unsigned grp_write
: 1;
205 /* Does this group contain a read access? This flag is propagated down the
207 unsigned grp_read
: 1;
209 /* Does this group contain a read access that comes from an assignment
210 statement? This flag is propagated down the access tree. */
211 unsigned grp_assignment_read
: 1;
213 /* Does this group contain a write access that comes from an assignment
214 statement? This flag is propagated down the access tree. */
215 unsigned grp_assignment_write
: 1;
217 /* Does this group contain a read access through a scalar type? This flag is
218 not propagated in the access tree in any direction. */
219 unsigned grp_scalar_read
: 1;
221 /* Does this group contain a write access through a scalar type? This flag
222 is not propagated in the access tree in any direction. */
223 unsigned grp_scalar_write
: 1;
225 /* Is this access an artificial one created to scalarize some record
227 unsigned grp_total_scalarization
: 1;
229 /* Other passes of the analysis use this bit to make function
230 analyze_access_subtree create scalar replacements for this group if
232 unsigned grp_hint
: 1;
234 /* Is the subtree rooted in this access fully covered by scalar
236 unsigned grp_covered
: 1;
238 /* If set to true, this access and all below it in an access tree must not be
240 unsigned grp_unscalarizable_region
: 1;
242 /* Whether data have been written to parts of the aggregate covered by this
243 access which is not to be scalarized. This flag is propagated up in the
245 unsigned grp_unscalarized_data
: 1;
247 /* Does this access and/or group contain a write access through a
249 unsigned grp_partial_lhs
: 1;
251 /* Set when a scalar replacement should be created for this variable. */
252 unsigned grp_to_be_replaced
: 1;
254 /* Set when we want a replacement for the sole purpose of having it in
255 generated debug statements. */
256 unsigned grp_to_be_debug_replaced
: 1;
258 /* Should TREE_NO_WARNING of a replacement be set? */
259 unsigned grp_no_warning
: 1;
261 /* Is it possible that the group refers to data which might be (directly or
262 otherwise) modified? */
263 unsigned grp_maybe_modified
: 1;
265 /* Set when this is a representative of a pointer to scalar (i.e. by
266 reference) parameter which we consider for turning into a plain scalar
267 (i.e. a by value parameter). */
268 unsigned grp_scalar_ptr
: 1;
270 /* Set when we discover that this pointer is not safe to dereference in the
272 unsigned grp_not_necessarilly_dereferenced
: 1;
275 typedef struct access
*access_p
;
278 /* Alloc pool for allocating access structures. */
279 static alloc_pool access_pool
;
281 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
282 are used to propagate subaccesses from rhs to lhs as long as they don't
283 conflict with what is already there. */
286 struct access
*lacc
, *racc
;
287 struct assign_link
*next
;
290 /* Alloc pool for allocating assign link structures. */
291 static alloc_pool link_pool
;
293 /* Base (tree) -> Vector (vec<access_p> *) map. */
294 static struct pointer_map_t
*base_access_vec
;
296 /* Candidate hash table helpers. */
298 struct uid_decl_hasher
: typed_noop_remove
<tree_node
>
300 typedef tree_node value_type
;
301 typedef tree_node compare_type
;
302 static inline hashval_t
hash (const value_type
*);
303 static inline bool equal (const value_type
*, const compare_type
*);
306 /* Hash a tree in a uid_decl_map. */
309 uid_decl_hasher::hash (const value_type
*item
)
311 return item
->decl_minimal
.uid
;
314 /* Return true if the DECL_UID in both trees are equal. */
317 uid_decl_hasher::equal (const value_type
*a
, const compare_type
*b
)
319 return (a
->decl_minimal
.uid
== b
->decl_minimal
.uid
);
322 /* Set of candidates. */
323 static bitmap candidate_bitmap
;
324 static hash_table
<uid_decl_hasher
> candidates
;
326 /* For a candidate UID return the candidates decl. */
329 candidate (unsigned uid
)
332 t
.decl_minimal
.uid
= uid
;
333 return candidates
.find_with_hash (&t
, static_cast <hashval_t
> (uid
));
336 /* Bitmap of candidates which we should try to entirely scalarize away and
337 those which cannot be (because they are and need be used as a whole). */
338 static bitmap should_scalarize_away_bitmap
, cannot_scalarize_away_bitmap
;
340 /* Obstack for creation of fancy names. */
341 static struct obstack name_obstack
;
343 /* Head of a linked list of accesses that need to have its subaccesses
344 propagated to their assignment counterparts. */
345 static struct access
*work_queue_head
;
347 /* Number of parameters of the analyzed function when doing early ipa SRA. */
348 static int func_param_count
;
350 /* scan_function sets the following to true if it encounters a call to
351 __builtin_apply_args. */
352 static bool encountered_apply_args
;
354 /* Set by scan_function when it finds a recursive call. */
355 static bool encountered_recursive_call
;
357 /* Set by scan_function when it finds a recursive call with less actual
358 arguments than formal parameters.. */
359 static bool encountered_unchangable_recursive_call
;
361 /* This is a table in which for each basic block and parameter there is a
362 distance (offset + size) in that parameter which is dereferenced and
363 accessed in that BB. */
364 static HOST_WIDE_INT
*bb_dereferences
;
365 /* Bitmap of BBs that can cause the function to "stop" progressing by
366 returning, throwing externally, looping infinitely or calling a function
367 which might abort etc.. */
368 static bitmap final_bbs
;
370 /* Representative of no accesses at all. */
371 static struct access no_accesses_representant
;
373 /* Predicate to test the special value. */
376 no_accesses_p (struct access
*access
)
378 return access
== &no_accesses_representant
;
381 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
382 representative fields are dumped, otherwise those which only describe the
383 individual access are. */
387 /* Number of processed aggregates is readily available in
388 analyze_all_variable_accesses and so is not stored here. */
390 /* Number of created scalar replacements. */
393 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
397 /* Number of statements created by generate_subtree_copies. */
400 /* Number of statements created by load_assign_lhs_subreplacements. */
403 /* Number of times sra_modify_assign has deleted a statement. */
406 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
407 RHS reparately due to type conversions or nonexistent matching
409 int separate_lhs_rhs_handling
;
411 /* Number of parameters that were removed because they were unused. */
412 int deleted_unused_parameters
;
414 /* Number of scalars passed as parameters by reference that have been
415 converted to be passed by value. */
416 int scalar_by_ref_to_by_val
;
418 /* Number of aggregate parameters that were replaced by one or more of their
420 int aggregate_params_reduced
;
422 /* Numbber of components created when splitting aggregate parameters. */
423 int param_reductions_created
;
427 dump_access (FILE *f
, struct access
*access
, bool grp
)
429 fprintf (f
, "access { ");
430 fprintf (f
, "base = (%d)'", DECL_UID (access
->base
));
431 print_generic_expr (f
, access
->base
, 0);
432 fprintf (f
, "', offset = " HOST_WIDE_INT_PRINT_DEC
, access
->offset
);
433 fprintf (f
, ", size = " HOST_WIDE_INT_PRINT_DEC
, access
->size
);
434 fprintf (f
, ", expr = ");
435 print_generic_expr (f
, access
->expr
, 0);
436 fprintf (f
, ", type = ");
437 print_generic_expr (f
, access
->type
, 0);
439 fprintf (f
, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
440 "grp_assignment_write = %d, grp_scalar_read = %d, "
441 "grp_scalar_write = %d, grp_total_scalarization = %d, "
442 "grp_hint = %d, grp_covered = %d, "
443 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
444 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
445 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
446 "grp_not_necessarilly_dereferenced = %d\n",
447 access
->grp_read
, access
->grp_write
, access
->grp_assignment_read
,
448 access
->grp_assignment_write
, access
->grp_scalar_read
,
449 access
->grp_scalar_write
, access
->grp_total_scalarization
,
450 access
->grp_hint
, access
->grp_covered
,
451 access
->grp_unscalarizable_region
, access
->grp_unscalarized_data
,
452 access
->grp_partial_lhs
, access
->grp_to_be_replaced
,
453 access
->grp_to_be_debug_replaced
, access
->grp_maybe_modified
,
454 access
->grp_not_necessarilly_dereferenced
);
456 fprintf (f
, ", write = %d, grp_total_scalarization = %d, "
457 "grp_partial_lhs = %d\n",
458 access
->write
, access
->grp_total_scalarization
,
459 access
->grp_partial_lhs
);
462 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
465 dump_access_tree_1 (FILE *f
, struct access
*access
, int level
)
471 for (i
= 0; i
< level
; i
++)
472 fputs ("* ", dump_file
);
474 dump_access (f
, access
, true);
476 if (access
->first_child
)
477 dump_access_tree_1 (f
, access
->first_child
, level
+ 1);
479 access
= access
->next_sibling
;
484 /* Dump all access trees for a variable, given the pointer to the first root in
488 dump_access_tree (FILE *f
, struct access
*access
)
490 for (; access
; access
= access
->next_grp
)
491 dump_access_tree_1 (f
, access
, 0);
494 /* Return true iff ACC is non-NULL and has subaccesses. */
497 access_has_children_p (struct access
*acc
)
499 return acc
&& acc
->first_child
;
502 /* Return true iff ACC is (partly) covered by at least one replacement. */
505 access_has_replacements_p (struct access
*acc
)
507 struct access
*child
;
508 if (acc
->grp_to_be_replaced
)
510 for (child
= acc
->first_child
; child
; child
= child
->next_sibling
)
511 if (access_has_replacements_p (child
))
516 /* Return a vector of pointers to accesses for the variable given in BASE or
517 NULL if there is none. */
519 static vec
<access_p
> *
520 get_base_access_vector (tree base
)
524 slot
= pointer_map_contains (base_access_vec
, base
);
528 return *(vec
<access_p
> **) slot
;
531 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
532 in ACCESS. Return NULL if it cannot be found. */
534 static struct access
*
535 find_access_in_subtree (struct access
*access
, HOST_WIDE_INT offset
,
538 while (access
&& (access
->offset
!= offset
|| access
->size
!= size
))
540 struct access
*child
= access
->first_child
;
542 while (child
&& (child
->offset
+ child
->size
<= offset
))
543 child
= child
->next_sibling
;
550 /* Return the first group representative for DECL or NULL if none exists. */
552 static struct access
*
553 get_first_repr_for_decl (tree base
)
555 vec
<access_p
> *access_vec
;
557 access_vec
= get_base_access_vector (base
);
561 return (*access_vec
)[0];
564 /* Find an access representative for the variable BASE and given OFFSET and
565 SIZE. Requires that access trees have already been built. Return NULL if
566 it cannot be found. */
568 static struct access
*
569 get_var_base_offset_size_access (tree base
, HOST_WIDE_INT offset
,
572 struct access
*access
;
574 access
= get_first_repr_for_decl (base
);
575 while (access
&& (access
->offset
+ access
->size
<= offset
))
576 access
= access
->next_grp
;
580 return find_access_in_subtree (access
, offset
, size
);
583 /* Add LINK to the linked list of assign links of RACC. */
585 add_link_to_rhs (struct access
*racc
, struct assign_link
*link
)
587 gcc_assert (link
->racc
== racc
);
589 if (!racc
->first_link
)
591 gcc_assert (!racc
->last_link
);
592 racc
->first_link
= link
;
595 racc
->last_link
->next
= link
;
597 racc
->last_link
= link
;
601 /* Move all link structures in their linked list in OLD_RACC to the linked list
604 relink_to_new_repr (struct access
*new_racc
, struct access
*old_racc
)
606 if (!old_racc
->first_link
)
608 gcc_assert (!old_racc
->last_link
);
612 if (new_racc
->first_link
)
614 gcc_assert (!new_racc
->last_link
->next
);
615 gcc_assert (!old_racc
->last_link
|| !old_racc
->last_link
->next
);
617 new_racc
->last_link
->next
= old_racc
->first_link
;
618 new_racc
->last_link
= old_racc
->last_link
;
622 gcc_assert (!new_racc
->last_link
);
624 new_racc
->first_link
= old_racc
->first_link
;
625 new_racc
->last_link
= old_racc
->last_link
;
627 old_racc
->first_link
= old_racc
->last_link
= NULL
;
630 /* Add ACCESS to the work queue (which is actually a stack). */
633 add_access_to_work_queue (struct access
*access
)
635 if (!access
->grp_queued
)
637 gcc_assert (!access
->next_queued
);
638 access
->next_queued
= work_queue_head
;
639 access
->grp_queued
= 1;
640 work_queue_head
= access
;
644 /* Pop an access from the work queue, and return it, assuming there is one. */
646 static struct access
*
647 pop_access_from_work_queue (void)
649 struct access
*access
= work_queue_head
;
651 work_queue_head
= access
->next_queued
;
652 access
->next_queued
= NULL
;
653 access
->grp_queued
= 0;
658 /* Allocate necessary structures. */
661 sra_initialize (void)
663 candidate_bitmap
= BITMAP_ALLOC (NULL
);
664 candidates
.create (vec_safe_length (cfun
->local_decls
) / 2);
665 should_scalarize_away_bitmap
= BITMAP_ALLOC (NULL
);
666 cannot_scalarize_away_bitmap
= BITMAP_ALLOC (NULL
);
667 gcc_obstack_init (&name_obstack
);
668 access_pool
= create_alloc_pool ("SRA accesses", sizeof (struct access
), 16);
669 link_pool
= create_alloc_pool ("SRA links", sizeof (struct assign_link
), 16);
670 base_access_vec
= pointer_map_create ();
671 memset (&sra_stats
, 0, sizeof (sra_stats
));
672 encountered_apply_args
= false;
673 encountered_recursive_call
= false;
674 encountered_unchangable_recursive_call
= false;
677 /* Hook fed to pointer_map_traverse, deallocate stored vectors. */
680 delete_base_accesses (const void *key ATTRIBUTE_UNUSED
, void **value
,
681 void *data ATTRIBUTE_UNUSED
)
683 vec
<access_p
> *access_vec
= (vec
<access_p
> *) *value
;
684 vec_free (access_vec
);
688 /* Deallocate all general structures. */
691 sra_deinitialize (void)
693 BITMAP_FREE (candidate_bitmap
);
694 candidates
.dispose ();
695 BITMAP_FREE (should_scalarize_away_bitmap
);
696 BITMAP_FREE (cannot_scalarize_away_bitmap
);
697 free_alloc_pool (access_pool
);
698 free_alloc_pool (link_pool
);
699 obstack_free (&name_obstack
, NULL
);
701 pointer_map_traverse (base_access_vec
, delete_base_accesses
, NULL
);
702 pointer_map_destroy (base_access_vec
);
705 /* Remove DECL from candidates for SRA and write REASON to the dump file if
708 disqualify_candidate (tree decl
, const char *reason
)
710 if (bitmap_clear_bit (candidate_bitmap
, DECL_UID (decl
)))
711 candidates
.clear_slot (candidates
.find_slot_with_hash (decl
,
715 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
717 fprintf (dump_file
, "! Disqualifying ");
718 print_generic_expr (dump_file
, decl
, 0);
719 fprintf (dump_file
, " - %s\n", reason
);
723 /* Return true iff the type contains a field or an element which does not allow
727 type_internals_preclude_sra_p (tree type
, const char **msg
)
732 switch (TREE_CODE (type
))
736 case QUAL_UNION_TYPE
:
737 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
738 if (TREE_CODE (fld
) == FIELD_DECL
)
740 tree ft
= TREE_TYPE (fld
);
742 if (TREE_THIS_VOLATILE (fld
))
744 *msg
= "volatile structure field";
747 if (!DECL_FIELD_OFFSET (fld
))
749 *msg
= "no structure field offset";
752 if (!DECL_SIZE (fld
))
754 *msg
= "zero structure field size";
757 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
759 *msg
= "structure field offset not fixed";
762 if (!tree_fits_uhwi_p (DECL_SIZE (fld
)))
764 *msg
= "structure field size not fixed";
767 if (!tree_fits_shwi_p (bit_position (fld
)))
769 *msg
= "structure field size too big";
772 if (AGGREGATE_TYPE_P (ft
)
773 && int_bit_position (fld
) % BITS_PER_UNIT
!= 0)
775 *msg
= "structure field is bit field";
779 if (AGGREGATE_TYPE_P (ft
) && type_internals_preclude_sra_p (ft
, msg
))
786 et
= TREE_TYPE (type
);
788 if (TYPE_VOLATILE (et
))
790 *msg
= "element type is volatile";
794 if (AGGREGATE_TYPE_P (et
) && type_internals_preclude_sra_p (et
, msg
))
804 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
805 base variable if it is. Return T if it is not an SSA_NAME. */
808 get_ssa_base_param (tree t
)
810 if (TREE_CODE (t
) == SSA_NAME
)
812 if (SSA_NAME_IS_DEFAULT_DEF (t
))
813 return SSA_NAME_VAR (t
);
820 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
821 belongs to, unless the BB has already been marked as a potentially
825 mark_parm_dereference (tree base
, HOST_WIDE_INT dist
, gimple stmt
)
827 basic_block bb
= gimple_bb (stmt
);
828 int idx
, parm_index
= 0;
831 if (bitmap_bit_p (final_bbs
, bb
->index
))
834 for (parm
= DECL_ARGUMENTS (current_function_decl
);
835 parm
&& parm
!= base
;
836 parm
= DECL_CHAIN (parm
))
839 gcc_assert (parm_index
< func_param_count
);
841 idx
= bb
->index
* func_param_count
+ parm_index
;
842 if (bb_dereferences
[idx
] < dist
)
843 bb_dereferences
[idx
] = dist
;
846 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
847 the three fields. Also add it to the vector of accesses corresponding to
848 the base. Finally, return the new access. */
850 static struct access
*
851 create_access_1 (tree base
, HOST_WIDE_INT offset
, HOST_WIDE_INT size
)
854 struct access
*access
;
857 access
= (struct access
*) pool_alloc (access_pool
);
858 memset (access
, 0, sizeof (struct access
));
860 access
->offset
= offset
;
863 slot
= pointer_map_contains (base_access_vec
, base
);
865 v
= (vec
<access_p
> *) *slot
;
869 v
->safe_push (access
);
872 pointer_map_insert (base_access_vec
, base
)) = v
;
877 /* Create and insert access for EXPR. Return created access, or NULL if it is
880 static struct access
*
881 create_access (tree expr
, gimple stmt
, bool write
)
883 struct access
*access
;
884 HOST_WIDE_INT offset
, size
, max_size
;
886 bool ptr
, unscalarizable_region
= false;
888 base
= get_ref_base_and_extent (expr
, &offset
, &size
, &max_size
);
890 if (sra_mode
== SRA_MODE_EARLY_IPA
891 && TREE_CODE (base
) == MEM_REF
)
893 base
= get_ssa_base_param (TREE_OPERAND (base
, 0));
901 if (!DECL_P (base
) || !bitmap_bit_p (candidate_bitmap
, DECL_UID (base
)))
904 if (sra_mode
== SRA_MODE_EARLY_IPA
)
906 if (size
< 0 || size
!= max_size
)
908 disqualify_candidate (base
, "Encountered a variable sized access.");
911 if (TREE_CODE (expr
) == COMPONENT_REF
912 && DECL_BIT_FIELD (TREE_OPERAND (expr
, 1)))
914 disqualify_candidate (base
, "Encountered a bit-field access.");
917 gcc_checking_assert ((offset
% BITS_PER_UNIT
) == 0);
920 mark_parm_dereference (base
, offset
+ size
, stmt
);
924 if (size
!= max_size
)
927 unscalarizable_region
= true;
931 disqualify_candidate (base
, "Encountered an unconstrained access.");
936 access
= create_access_1 (base
, offset
, size
);
938 access
->type
= TREE_TYPE (expr
);
939 access
->write
= write
;
940 access
->grp_unscalarizable_region
= unscalarizable_region
;
943 if (TREE_CODE (expr
) == COMPONENT_REF
944 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr
, 1)))
945 access
->non_addressable
= 1;
951 /* Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple
952 register types or (recursively) records with only these two kinds of fields.
953 It also returns false if any of these records contains a bit-field. */
956 type_consists_of_records_p (tree type
)
960 if (TREE_CODE (type
) != RECORD_TYPE
)
963 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
964 if (TREE_CODE (fld
) == FIELD_DECL
)
966 tree ft
= TREE_TYPE (fld
);
968 if (DECL_BIT_FIELD (fld
))
971 if (!is_gimple_reg_type (ft
)
972 && !type_consists_of_records_p (ft
))
979 /* Create total_scalarization accesses for all scalar type fields in DECL that
980 must be of a RECORD_TYPE conforming to type_consists_of_records_p. BASE
981 must be the top-most VAR_DECL representing the variable, OFFSET must be the
982 offset of DECL within BASE. REF must be the memory reference expression for
986 completely_scalarize_record (tree base
, tree decl
, HOST_WIDE_INT offset
,
989 tree fld
, decl_type
= TREE_TYPE (decl
);
991 for (fld
= TYPE_FIELDS (decl_type
); fld
; fld
= DECL_CHAIN (fld
))
992 if (TREE_CODE (fld
) == FIELD_DECL
)
994 HOST_WIDE_INT pos
= offset
+ int_bit_position (fld
);
995 tree ft
= TREE_TYPE (fld
);
996 tree nref
= build3 (COMPONENT_REF
, TREE_TYPE (fld
), ref
, fld
,
999 if (is_gimple_reg_type (ft
))
1001 struct access
*access
;
1004 size
= tree_to_uhwi (DECL_SIZE (fld
));
1005 access
= create_access_1 (base
, pos
, size
);
1006 access
->expr
= nref
;
1008 access
->grp_total_scalarization
= 1;
1009 /* Accesses for intraprocedural SRA can have their stmt NULL. */
1012 completely_scalarize_record (base
, fld
, pos
, nref
);
1016 /* Create total_scalarization accesses for all scalar type fields in VAR and
1017 for VAR a a whole. VAR must be of a RECORD_TYPE conforming to
1018 type_consists_of_records_p. */
1021 completely_scalarize_var (tree var
)
1023 HOST_WIDE_INT size
= tree_to_uhwi (DECL_SIZE (var
));
1024 struct access
*access
;
1026 access
= create_access_1 (var
, 0, size
);
1028 access
->type
= TREE_TYPE (var
);
1029 access
->grp_total_scalarization
= 1;
1031 completely_scalarize_record (var
, var
, 0, var
);
1034 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1037 contains_view_convert_expr_p (const_tree ref
)
1039 while (handled_component_p (ref
))
1041 if (TREE_CODE (ref
) == VIEW_CONVERT_EXPR
)
1043 ref
= TREE_OPERAND (ref
, 0);
1049 /* Search the given tree for a declaration by skipping handled components and
1050 exclude it from the candidates. */
1053 disqualify_base_of_expr (tree t
, const char *reason
)
1055 t
= get_base_address (t
);
1056 if (sra_mode
== SRA_MODE_EARLY_IPA
1057 && TREE_CODE (t
) == MEM_REF
)
1058 t
= get_ssa_base_param (TREE_OPERAND (t
, 0));
1060 if (t
&& DECL_P (t
))
1061 disqualify_candidate (t
, reason
);
1064 /* Scan expression EXPR and create access structures for all accesses to
1065 candidates for scalarization. Return the created access or NULL if none is
1068 static struct access
*
1069 build_access_from_expr_1 (tree expr
, gimple stmt
, bool write
)
1071 struct access
*ret
= NULL
;
1074 if (TREE_CODE (expr
) == BIT_FIELD_REF
1075 || TREE_CODE (expr
) == IMAGPART_EXPR
1076 || TREE_CODE (expr
) == REALPART_EXPR
)
1078 expr
= TREE_OPERAND (expr
, 0);
1082 partial_ref
= false;
1084 /* We need to dive through V_C_Es in order to get the size of its parameter
1085 and not the result type. Ada produces such statements. We are also
1086 capable of handling the topmost V_C_E but not any of those buried in other
1087 handled components. */
1088 if (TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
1089 expr
= TREE_OPERAND (expr
, 0);
1091 if (contains_view_convert_expr_p (expr
))
1093 disqualify_base_of_expr (expr
, "V_C_E under a different handled "
1097 if (TREE_THIS_VOLATILE (expr
))
1099 disqualify_base_of_expr (expr
, "part of a volatile reference.");
1103 switch (TREE_CODE (expr
))
1106 if (TREE_CODE (TREE_OPERAND (expr
, 0)) != ADDR_EXPR
1107 && sra_mode
!= SRA_MODE_EARLY_IPA
)
1115 case ARRAY_RANGE_REF
:
1116 ret
= create_access (expr
, stmt
, write
);
1123 if (write
&& partial_ref
&& ret
)
1124 ret
->grp_partial_lhs
= 1;
1129 /* Scan expression EXPR and create access structures for all accesses to
1130 candidates for scalarization. Return true if any access has been inserted.
1131 STMT must be the statement from which the expression is taken, WRITE must be
1132 true if the expression is a store and false otherwise. */
1135 build_access_from_expr (tree expr
, gimple stmt
, bool write
)
1137 struct access
*access
;
1139 access
= build_access_from_expr_1 (expr
, stmt
, write
);
1142 /* This means the aggregate is accesses as a whole in a way other than an
1143 assign statement and thus cannot be removed even if we had a scalar
1144 replacement for everything. */
1145 if (cannot_scalarize_away_bitmap
)
1146 bitmap_set_bit (cannot_scalarize_away_bitmap
, DECL_UID (access
->base
));
1152 /* Disqualify LHS and RHS for scalarization if STMT must end its basic block in
1153 modes in which it matters, return true iff they have been disqualified. RHS
1154 may be NULL, in that case ignore it. If we scalarize an aggregate in
1155 intra-SRA we may need to add statements after each statement. This is not
1156 possible if a statement unconditionally has to end the basic block. */
1158 disqualify_ops_if_throwing_stmt (gimple stmt
, tree lhs
, tree rhs
)
1160 if ((sra_mode
== SRA_MODE_EARLY_INTRA
|| sra_mode
== SRA_MODE_INTRA
)
1161 && (stmt_can_throw_internal (stmt
) || stmt_ends_bb_p (stmt
)))
1163 disqualify_base_of_expr (lhs
, "LHS of a throwing stmt.");
1165 disqualify_base_of_expr (rhs
, "RHS of a throwing stmt.");
1171 /* Scan expressions occurring in STMT, create access structures for all accesses
1172 to candidates for scalarization and remove those candidates which occur in
1173 statements or expressions that prevent them from being split apart. Return
1174 true if any access has been inserted. */
1177 build_accesses_from_assign (gimple stmt
)
1180 struct access
*lacc
, *racc
;
1182 if (!gimple_assign_single_p (stmt
)
1183 /* Scope clobbers don't influence scalarization. */
1184 || gimple_clobber_p (stmt
))
1187 lhs
= gimple_assign_lhs (stmt
);
1188 rhs
= gimple_assign_rhs1 (stmt
);
1190 if (disqualify_ops_if_throwing_stmt (stmt
, lhs
, rhs
))
1193 racc
= build_access_from_expr_1 (rhs
, stmt
, false);
1194 lacc
= build_access_from_expr_1 (lhs
, stmt
, true);
1197 lacc
->grp_assignment_write
= 1;
1201 racc
->grp_assignment_read
= 1;
1202 if (should_scalarize_away_bitmap
&& !gimple_has_volatile_ops (stmt
)
1203 && !is_gimple_reg_type (racc
->type
))
1204 bitmap_set_bit (should_scalarize_away_bitmap
, DECL_UID (racc
->base
));
1208 && (sra_mode
== SRA_MODE_EARLY_INTRA
|| sra_mode
== SRA_MODE_INTRA
)
1209 && !lacc
->grp_unscalarizable_region
1210 && !racc
->grp_unscalarizable_region
1211 && AGGREGATE_TYPE_P (TREE_TYPE (lhs
))
1212 && lacc
->size
== racc
->size
1213 && useless_type_conversion_p (lacc
->type
, racc
->type
))
1215 struct assign_link
*link
;
1217 link
= (struct assign_link
*) pool_alloc (link_pool
);
1218 memset (link
, 0, sizeof (struct assign_link
));
1223 add_link_to_rhs (racc
, link
);
1226 return lacc
|| racc
;
1229 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1230 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1233 asm_visit_addr (gimple
, tree op
, tree
, void *)
1235 op
= get_base_address (op
);
1238 disqualify_candidate (op
, "Non-scalarizable GIMPLE_ASM operand.");
1243 /* Return true iff callsite CALL has at least as many actual arguments as there
1244 are formal parameters of the function currently processed by IPA-SRA and
1245 that their types match. */
1248 callsite_arguments_match_p (gimple call
)
1250 if (gimple_call_num_args (call
) < (unsigned) func_param_count
)
1255 for (parm
= DECL_ARGUMENTS (current_function_decl
), i
= 0;
1257 parm
= DECL_CHAIN (parm
), i
++)
1259 tree arg
= gimple_call_arg (call
, i
);
1260 if (!useless_type_conversion_p (TREE_TYPE (parm
), TREE_TYPE (arg
)))
1266 /* Scan function and look for interesting expressions and create access
1267 structures for them. Return true iff any access is created. */
1270 scan_function (void)
1275 FOR_EACH_BB_FN (bb
, cfun
)
1277 gimple_stmt_iterator gsi
;
1278 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1280 gimple stmt
= gsi_stmt (gsi
);
1284 if (final_bbs
&& stmt_can_throw_external (stmt
))
1285 bitmap_set_bit (final_bbs
, bb
->index
);
1286 switch (gimple_code (stmt
))
1289 t
= gimple_return_retval (stmt
);
1291 ret
|= build_access_from_expr (t
, stmt
, false);
1293 bitmap_set_bit (final_bbs
, bb
->index
);
1297 ret
|= build_accesses_from_assign (stmt
);
1301 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1302 ret
|= build_access_from_expr (gimple_call_arg (stmt
, i
),
1305 if (sra_mode
== SRA_MODE_EARLY_IPA
)
1307 tree dest
= gimple_call_fndecl (stmt
);
1308 int flags
= gimple_call_flags (stmt
);
1312 if (DECL_BUILT_IN_CLASS (dest
) == BUILT_IN_NORMAL
1313 && DECL_FUNCTION_CODE (dest
) == BUILT_IN_APPLY_ARGS
)
1314 encountered_apply_args
= true;
1315 if (recursive_call_p (current_function_decl
, dest
))
1317 encountered_recursive_call
= true;
1318 if (!callsite_arguments_match_p (stmt
))
1319 encountered_unchangable_recursive_call
= true;
1324 && (flags
& (ECF_CONST
| ECF_PURE
)) == 0)
1325 bitmap_set_bit (final_bbs
, bb
->index
);
1328 t
= gimple_call_lhs (stmt
);
1329 if (t
&& !disqualify_ops_if_throwing_stmt (stmt
, t
, NULL
))
1330 ret
|= build_access_from_expr (t
, stmt
, true);
1334 walk_stmt_load_store_addr_ops (stmt
, NULL
, NULL
, NULL
,
1337 bitmap_set_bit (final_bbs
, bb
->index
);
1339 for (i
= 0; i
< gimple_asm_ninputs (stmt
); i
++)
1341 t
= TREE_VALUE (gimple_asm_input_op (stmt
, i
));
1342 ret
|= build_access_from_expr (t
, stmt
, false);
1344 for (i
= 0; i
< gimple_asm_noutputs (stmt
); i
++)
1346 t
= TREE_VALUE (gimple_asm_output_op (stmt
, i
));
1347 ret
|= build_access_from_expr (t
, stmt
, true);
1360 /* Helper of QSORT function. There are pointers to accesses in the array. An
1361 access is considered smaller than another if it has smaller offset or if the
1362 offsets are the same but is size is bigger. */
1365 compare_access_positions (const void *a
, const void *b
)
1367 const access_p
*fp1
= (const access_p
*) a
;
1368 const access_p
*fp2
= (const access_p
*) b
;
1369 const access_p f1
= *fp1
;
1370 const access_p f2
= *fp2
;
1372 if (f1
->offset
!= f2
->offset
)
1373 return f1
->offset
< f2
->offset
? -1 : 1;
1375 if (f1
->size
== f2
->size
)
1377 if (f1
->type
== f2
->type
)
1379 /* Put any non-aggregate type before any aggregate type. */
1380 else if (!is_gimple_reg_type (f1
->type
)
1381 && is_gimple_reg_type (f2
->type
))
1383 else if (is_gimple_reg_type (f1
->type
)
1384 && !is_gimple_reg_type (f2
->type
))
1386 /* Put any complex or vector type before any other scalar type. */
1387 else if (TREE_CODE (f1
->type
) != COMPLEX_TYPE
1388 && TREE_CODE (f1
->type
) != VECTOR_TYPE
1389 && (TREE_CODE (f2
->type
) == COMPLEX_TYPE
1390 || TREE_CODE (f2
->type
) == VECTOR_TYPE
))
1392 else if ((TREE_CODE (f1
->type
) == COMPLEX_TYPE
1393 || TREE_CODE (f1
->type
) == VECTOR_TYPE
)
1394 && TREE_CODE (f2
->type
) != COMPLEX_TYPE
1395 && TREE_CODE (f2
->type
) != VECTOR_TYPE
)
1397 /* Put the integral type with the bigger precision first. */
1398 else if (INTEGRAL_TYPE_P (f1
->type
)
1399 && INTEGRAL_TYPE_P (f2
->type
))
1400 return TYPE_PRECISION (f2
->type
) - TYPE_PRECISION (f1
->type
);
1401 /* Put any integral type with non-full precision last. */
1402 else if (INTEGRAL_TYPE_P (f1
->type
)
1403 && (TREE_INT_CST_LOW (TYPE_SIZE (f1
->type
))
1404 != TYPE_PRECISION (f1
->type
)))
1406 else if (INTEGRAL_TYPE_P (f2
->type
)
1407 && (TREE_INT_CST_LOW (TYPE_SIZE (f2
->type
))
1408 != TYPE_PRECISION (f2
->type
)))
1410 /* Stabilize the sort. */
1411 return TYPE_UID (f1
->type
) - TYPE_UID (f2
->type
);
1414 /* We want the bigger accesses first, thus the opposite operator in the next
1416 return f1
->size
> f2
->size
? -1 : 1;
1420 /* Append a name of the declaration to the name obstack. A helper function for
1424 make_fancy_decl_name (tree decl
)
1428 tree name
= DECL_NAME (decl
);
1430 obstack_grow (&name_obstack
, IDENTIFIER_POINTER (name
),
1431 IDENTIFIER_LENGTH (name
));
1434 sprintf (buffer
, "D%u", DECL_UID (decl
));
1435 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1439 /* Helper for make_fancy_name. */
1442 make_fancy_name_1 (tree expr
)
1449 make_fancy_decl_name (expr
);
1453 switch (TREE_CODE (expr
))
1456 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1457 obstack_1grow (&name_obstack
, '$');
1458 make_fancy_decl_name (TREE_OPERAND (expr
, 1));
1462 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1463 obstack_1grow (&name_obstack
, '$');
1464 /* Arrays with only one element may not have a constant as their
1466 index
= TREE_OPERAND (expr
, 1);
1467 if (TREE_CODE (index
) != INTEGER_CST
)
1469 sprintf (buffer
, HOST_WIDE_INT_PRINT_DEC
, TREE_INT_CST_LOW (index
));
1470 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1474 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1478 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1479 if (!integer_zerop (TREE_OPERAND (expr
, 1)))
1481 obstack_1grow (&name_obstack
, '$');
1482 sprintf (buffer
, HOST_WIDE_INT_PRINT_DEC
,
1483 TREE_INT_CST_LOW (TREE_OPERAND (expr
, 1)));
1484 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1491 gcc_unreachable (); /* we treat these as scalars. */
1498 /* Create a human readable name for replacement variable of ACCESS. */
1501 make_fancy_name (tree expr
)
1503 make_fancy_name_1 (expr
);
1504 obstack_1grow (&name_obstack
, '\0');
1505 return XOBFINISH (&name_obstack
, char *);
1508 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1509 EXP_TYPE at the given OFFSET. If BASE is something for which
1510 get_addr_base_and_unit_offset returns NULL, gsi must be non-NULL and is used
1511 to insert new statements either before or below the current one as specified
1512 by INSERT_AFTER. This function is not capable of handling bitfields.
1514 BASE must be either a declaration or a memory reference that has correct
1515 alignment ifformation embeded in it (e.g. a pre-existing one in SRA). */
1518 build_ref_for_offset (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1519 tree exp_type
, gimple_stmt_iterator
*gsi
,
1522 tree prev_base
= base
;
1525 HOST_WIDE_INT base_offset
;
1526 unsigned HOST_WIDE_INT misalign
;
1529 gcc_checking_assert (offset
% BITS_PER_UNIT
== 0);
1530 get_object_alignment_1 (base
, &align
, &misalign
);
1531 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
1533 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1534 offset such as array[var_index]. */
1540 gcc_checking_assert (gsi
);
1541 tmp
= make_ssa_name (build_pointer_type (TREE_TYPE (prev_base
)), NULL
);
1542 addr
= build_fold_addr_expr (unshare_expr (prev_base
));
1543 STRIP_USELESS_TYPE_CONVERSION (addr
);
1544 stmt
= gimple_build_assign (tmp
, addr
);
1545 gimple_set_location (stmt
, loc
);
1547 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
1549 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
1551 off
= build_int_cst (reference_alias_ptr_type (prev_base
),
1552 offset
/ BITS_PER_UNIT
);
1555 else if (TREE_CODE (base
) == MEM_REF
)
1557 off
= build_int_cst (TREE_TYPE (TREE_OPERAND (base
, 1)),
1558 base_offset
+ offset
/ BITS_PER_UNIT
);
1559 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1), off
);
1560 base
= unshare_expr (TREE_OPERAND (base
, 0));
1564 off
= build_int_cst (reference_alias_ptr_type (base
),
1565 base_offset
+ offset
/ BITS_PER_UNIT
);
1566 base
= build_fold_addr_expr (unshare_expr (base
));
1569 misalign
= (misalign
+ offset
) & (align
- 1);
1571 align
= (misalign
& -misalign
);
1572 if (align
< TYPE_ALIGN (exp_type
))
1573 exp_type
= build_aligned_type (exp_type
, align
);
1575 mem_ref
= fold_build2_loc (loc
, MEM_REF
, exp_type
, base
, off
);
1576 if (TREE_THIS_VOLATILE (prev_base
))
1577 TREE_THIS_VOLATILE (mem_ref
) = 1;
1578 if (TREE_SIDE_EFFECTS (prev_base
))
1579 TREE_SIDE_EFFECTS (mem_ref
) = 1;
1583 /* Construct a memory reference to a part of an aggregate BASE at the given
1584 OFFSET and of the same type as MODEL. In case this is a reference to a
1585 bit-field, the function will replicate the last component_ref of model's
1586 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1587 build_ref_for_offset. */
1590 build_ref_for_model (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1591 struct access
*model
, gimple_stmt_iterator
*gsi
,
1594 if (TREE_CODE (model
->expr
) == COMPONENT_REF
1595 && DECL_BIT_FIELD (TREE_OPERAND (model
->expr
, 1)))
1597 /* This access represents a bit-field. */
1598 tree t
, exp_type
, fld
= TREE_OPERAND (model
->expr
, 1);
1600 offset
-= int_bit_position (fld
);
1601 exp_type
= TREE_TYPE (TREE_OPERAND (model
->expr
, 0));
1602 t
= build_ref_for_offset (loc
, base
, offset
, exp_type
, gsi
, insert_after
);
1603 return fold_build3_loc (loc
, COMPONENT_REF
, TREE_TYPE (fld
), t
, fld
,
1607 return build_ref_for_offset (loc
, base
, offset
, model
->type
,
1611 /* Attempt to build a memory reference that we could but into a gimple
1612 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1613 create statements and return s NULL instead. This function also ignores
1614 alignment issues and so its results should never end up in non-debug
1618 build_debug_ref_for_model (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1619 struct access
*model
)
1621 HOST_WIDE_INT base_offset
;
1624 if (TREE_CODE (model
->expr
) == COMPONENT_REF
1625 && DECL_BIT_FIELD (TREE_OPERAND (model
->expr
, 1)))
1628 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
1631 if (TREE_CODE (base
) == MEM_REF
)
1633 off
= build_int_cst (TREE_TYPE (TREE_OPERAND (base
, 1)),
1634 base_offset
+ offset
/ BITS_PER_UNIT
);
1635 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1), off
);
1636 base
= unshare_expr (TREE_OPERAND (base
, 0));
1640 off
= build_int_cst (reference_alias_ptr_type (base
),
1641 base_offset
+ offset
/ BITS_PER_UNIT
);
1642 base
= build_fold_addr_expr (unshare_expr (base
));
1645 return fold_build2_loc (loc
, MEM_REF
, model
->type
, base
, off
);
1648 /* Construct a memory reference consisting of component_refs and array_refs to
1649 a part of an aggregate *RES (which is of type TYPE). The requested part
1650 should have type EXP_TYPE at be the given OFFSET. This function might not
1651 succeed, it returns true when it does and only then *RES points to something
1652 meaningful. This function should be used only to build expressions that we
1653 might need to present to user (e.g. in warnings). In all other situations,
1654 build_ref_for_model or build_ref_for_offset should be used instead. */
1657 build_user_friendly_ref_for_offset (tree
*res
, tree type
, HOST_WIDE_INT offset
,
1663 tree tr_size
, index
, minidx
;
1664 HOST_WIDE_INT el_size
;
1666 if (offset
== 0 && exp_type
1667 && types_compatible_p (exp_type
, type
))
1670 switch (TREE_CODE (type
))
1673 case QUAL_UNION_TYPE
:
1675 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
1677 HOST_WIDE_INT pos
, size
;
1678 tree tr_pos
, expr
, *expr_ptr
;
1680 if (TREE_CODE (fld
) != FIELD_DECL
)
1683 tr_pos
= bit_position (fld
);
1684 if (!tr_pos
|| !tree_fits_uhwi_p (tr_pos
))
1686 pos
= tree_to_uhwi (tr_pos
);
1687 gcc_assert (TREE_CODE (type
) == RECORD_TYPE
|| pos
== 0);
1688 tr_size
= DECL_SIZE (fld
);
1689 if (!tr_size
|| !tree_fits_uhwi_p (tr_size
))
1691 size
= tree_to_uhwi (tr_size
);
1697 else if (pos
> offset
|| (pos
+ size
) <= offset
)
1700 expr
= build3 (COMPONENT_REF
, TREE_TYPE (fld
), *res
, fld
,
1703 if (build_user_friendly_ref_for_offset (expr_ptr
, TREE_TYPE (fld
),
1704 offset
- pos
, exp_type
))
1713 tr_size
= TYPE_SIZE (TREE_TYPE (type
));
1714 if (!tr_size
|| !tree_fits_uhwi_p (tr_size
))
1716 el_size
= tree_to_uhwi (tr_size
);
1718 minidx
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
1719 if (TREE_CODE (minidx
) != INTEGER_CST
|| el_size
== 0)
1721 index
= build_int_cst (TYPE_DOMAIN (type
), offset
/ el_size
);
1722 if (!integer_zerop (minidx
))
1723 index
= int_const_binop (PLUS_EXPR
, index
, minidx
);
1724 *res
= build4 (ARRAY_REF
, TREE_TYPE (type
), *res
, index
,
1725 NULL_TREE
, NULL_TREE
);
1726 offset
= offset
% el_size
;
1727 type
= TREE_TYPE (type
);
1742 /* Return true iff TYPE is stdarg va_list type. */
1745 is_va_list_type (tree type
)
1747 return TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (va_list_type_node
);
1750 /* Print message to dump file why a variable was rejected. */
1753 reject (tree var
, const char *msg
)
1755 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1757 fprintf (dump_file
, "Rejected (%d): %s: ", DECL_UID (var
), msg
);
1758 print_generic_expr (dump_file
, var
, 0);
1759 fprintf (dump_file
, "\n");
1763 /* Return true if VAR is a candidate for SRA. */
1766 maybe_add_sra_candidate (tree var
)
1768 tree type
= TREE_TYPE (var
);
1772 if (!AGGREGATE_TYPE_P (type
))
1774 reject (var
, "not aggregate");
1777 if (needs_to_live_in_memory (var
))
1779 reject (var
, "needs to live in memory");
1782 if (TREE_THIS_VOLATILE (var
))
1784 reject (var
, "is volatile");
1787 if (!COMPLETE_TYPE_P (type
))
1789 reject (var
, "has incomplete type");
1792 if (!tree_fits_uhwi_p (TYPE_SIZE (type
)))
1794 reject (var
, "type size not fixed");
1797 if (tree_to_uhwi (TYPE_SIZE (type
)) == 0)
1799 reject (var
, "type size is zero");
1802 if (type_internals_preclude_sra_p (type
, &msg
))
1807 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1808 we also want to schedule it rather late. Thus we ignore it in
1810 (sra_mode
== SRA_MODE_EARLY_INTRA
1811 && is_va_list_type (type
)))
1813 reject (var
, "is va_list");
1817 bitmap_set_bit (candidate_bitmap
, DECL_UID (var
));
1818 slot
= candidates
.find_slot_with_hash (var
, DECL_UID (var
), INSERT
);
1821 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1823 fprintf (dump_file
, "Candidate (%d): ", DECL_UID (var
));
1824 print_generic_expr (dump_file
, var
, 0);
1825 fprintf (dump_file
, "\n");
1831 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1832 those with type which is suitable for scalarization. */
1835 find_var_candidates (void)
1841 for (parm
= DECL_ARGUMENTS (current_function_decl
);
1843 parm
= DECL_CHAIN (parm
))
1844 ret
|= maybe_add_sra_candidate (parm
);
1846 FOR_EACH_LOCAL_DECL (cfun
, i
, var
)
1848 if (TREE_CODE (var
) != VAR_DECL
)
1851 ret
|= maybe_add_sra_candidate (var
);
1857 /* Sort all accesses for the given variable, check for partial overlaps and
1858 return NULL if there are any. If there are none, pick a representative for
1859 each combination of offset and size and create a linked list out of them.
1860 Return the pointer to the first representative and make sure it is the first
1861 one in the vector of accesses. */
1863 static struct access
*
1864 sort_and_splice_var_accesses (tree var
)
1866 int i
, j
, access_count
;
1867 struct access
*res
, **prev_acc_ptr
= &res
;
1868 vec
<access_p
> *access_vec
;
1870 HOST_WIDE_INT low
= -1, high
= 0;
1872 access_vec
= get_base_access_vector (var
);
1875 access_count
= access_vec
->length ();
1877 /* Sort by <OFFSET, SIZE>. */
1878 access_vec
->qsort (compare_access_positions
);
1881 while (i
< access_count
)
1883 struct access
*access
= (*access_vec
)[i
];
1884 bool grp_write
= access
->write
;
1885 bool grp_read
= !access
->write
;
1886 bool grp_scalar_write
= access
->write
1887 && is_gimple_reg_type (access
->type
);
1888 bool grp_scalar_read
= !access
->write
1889 && is_gimple_reg_type (access
->type
);
1890 bool grp_assignment_read
= access
->grp_assignment_read
;
1891 bool grp_assignment_write
= access
->grp_assignment_write
;
1892 bool multiple_scalar_reads
= false;
1893 bool total_scalarization
= access
->grp_total_scalarization
;
1894 bool grp_partial_lhs
= access
->grp_partial_lhs
;
1895 bool first_scalar
= is_gimple_reg_type (access
->type
);
1896 bool unscalarizable_region
= access
->grp_unscalarizable_region
;
1898 if (first
|| access
->offset
>= high
)
1901 low
= access
->offset
;
1902 high
= access
->offset
+ access
->size
;
1904 else if (access
->offset
> low
&& access
->offset
+ access
->size
> high
)
1907 gcc_assert (access
->offset
>= low
1908 && access
->offset
+ access
->size
<= high
);
1911 while (j
< access_count
)
1913 struct access
*ac2
= (*access_vec
)[j
];
1914 if (ac2
->offset
!= access
->offset
|| ac2
->size
!= access
->size
)
1919 grp_scalar_write
= (grp_scalar_write
1920 || is_gimple_reg_type (ac2
->type
));
1925 if (is_gimple_reg_type (ac2
->type
))
1927 if (grp_scalar_read
)
1928 multiple_scalar_reads
= true;
1930 grp_scalar_read
= true;
1933 grp_assignment_read
|= ac2
->grp_assignment_read
;
1934 grp_assignment_write
|= ac2
->grp_assignment_write
;
1935 grp_partial_lhs
|= ac2
->grp_partial_lhs
;
1936 unscalarizable_region
|= ac2
->grp_unscalarizable_region
;
1937 total_scalarization
|= ac2
->grp_total_scalarization
;
1938 relink_to_new_repr (access
, ac2
);
1940 /* If there are both aggregate-type and scalar-type accesses with
1941 this combination of size and offset, the comparison function
1942 should have put the scalars first. */
1943 gcc_assert (first_scalar
|| !is_gimple_reg_type (ac2
->type
));
1944 ac2
->group_representative
= access
;
1950 access
->group_representative
= access
;
1951 access
->grp_write
= grp_write
;
1952 access
->grp_read
= grp_read
;
1953 access
->grp_scalar_read
= grp_scalar_read
;
1954 access
->grp_scalar_write
= grp_scalar_write
;
1955 access
->grp_assignment_read
= grp_assignment_read
;
1956 access
->grp_assignment_write
= grp_assignment_write
;
1957 access
->grp_hint
= multiple_scalar_reads
|| total_scalarization
;
1958 access
->grp_total_scalarization
= total_scalarization
;
1959 access
->grp_partial_lhs
= grp_partial_lhs
;
1960 access
->grp_unscalarizable_region
= unscalarizable_region
;
1961 if (access
->first_link
)
1962 add_access_to_work_queue (access
);
1964 *prev_acc_ptr
= access
;
1965 prev_acc_ptr
= &access
->next_grp
;
1968 gcc_assert (res
== (*access_vec
)[0]);
1972 /* Create a variable for the given ACCESS which determines the type, name and a
1973 few other properties. Return the variable declaration and store it also to
1974 ACCESS->replacement. */
1977 create_access_replacement (struct access
*access
)
1981 if (access
->grp_to_be_debug_replaced
)
1983 repl
= create_tmp_var_raw (access
->type
, NULL
);
1984 DECL_CONTEXT (repl
) = current_function_decl
;
1987 repl
= create_tmp_var (access
->type
, "SR");
1988 if (TREE_CODE (access
->type
) == COMPLEX_TYPE
1989 || TREE_CODE (access
->type
) == VECTOR_TYPE
)
1991 if (!access
->grp_partial_lhs
)
1992 DECL_GIMPLE_REG_P (repl
) = 1;
1994 else if (access
->grp_partial_lhs
1995 && is_gimple_reg_type (access
->type
))
1996 TREE_ADDRESSABLE (repl
) = 1;
1998 DECL_SOURCE_LOCATION (repl
) = DECL_SOURCE_LOCATION (access
->base
);
1999 DECL_ARTIFICIAL (repl
) = 1;
2000 DECL_IGNORED_P (repl
) = DECL_IGNORED_P (access
->base
);
2002 if (DECL_NAME (access
->base
)
2003 && !DECL_IGNORED_P (access
->base
)
2004 && !DECL_ARTIFICIAL (access
->base
))
2006 char *pretty_name
= make_fancy_name (access
->expr
);
2007 tree debug_expr
= unshare_expr_without_location (access
->expr
), d
;
2010 DECL_NAME (repl
) = get_identifier (pretty_name
);
2011 obstack_free (&name_obstack
, pretty_name
);
2013 /* Get rid of any SSA_NAMEs embedded in debug_expr,
2014 as DECL_DEBUG_EXPR isn't considered when looking for still
2015 used SSA_NAMEs and thus they could be freed. All debug info
2016 generation cares is whether something is constant or variable
2017 and that get_ref_base_and_extent works properly on the
2018 expression. It cannot handle accesses at a non-constant offset
2019 though, so just give up in those cases. */
2020 for (d
= debug_expr
;
2021 !fail
&& (handled_component_p (d
) || TREE_CODE (d
) == MEM_REF
);
2022 d
= TREE_OPERAND (d
, 0))
2023 switch (TREE_CODE (d
))
2026 case ARRAY_RANGE_REF
:
2027 if (TREE_OPERAND (d
, 1)
2028 && TREE_CODE (TREE_OPERAND (d
, 1)) != INTEGER_CST
)
2030 if (TREE_OPERAND (d
, 3)
2031 && TREE_CODE (TREE_OPERAND (d
, 3)) != INTEGER_CST
)
2035 if (TREE_OPERAND (d
, 2)
2036 && TREE_CODE (TREE_OPERAND (d
, 2)) != INTEGER_CST
)
2040 if (TREE_CODE (TREE_OPERAND (d
, 0)) != ADDR_EXPR
)
2043 d
= TREE_OPERAND (d
, 0);
2050 SET_DECL_DEBUG_EXPR (repl
, debug_expr
);
2051 DECL_HAS_DEBUG_EXPR_P (repl
) = 1;
2053 if (access
->grp_no_warning
)
2054 TREE_NO_WARNING (repl
) = 1;
2056 TREE_NO_WARNING (repl
) = TREE_NO_WARNING (access
->base
);
2059 TREE_NO_WARNING (repl
) = 1;
2063 if (access
->grp_to_be_debug_replaced
)
2065 fprintf (dump_file
, "Created a debug-only replacement for ");
2066 print_generic_expr (dump_file
, access
->base
, 0);
2067 fprintf (dump_file
, " offset: %u, size: %u\n",
2068 (unsigned) access
->offset
, (unsigned) access
->size
);
2072 fprintf (dump_file
, "Created a replacement for ");
2073 print_generic_expr (dump_file
, access
->base
, 0);
2074 fprintf (dump_file
, " offset: %u, size: %u: ",
2075 (unsigned) access
->offset
, (unsigned) access
->size
);
2076 print_generic_expr (dump_file
, repl
, 0);
2077 fprintf (dump_file
, "\n");
2080 sra_stats
.replacements
++;
2085 /* Return ACCESS scalar replacement, create it if it does not exist yet. */
2088 get_access_replacement (struct access
*access
)
2090 gcc_checking_assert (access
->replacement_decl
);
2091 return access
->replacement_decl
;
2095 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2096 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2097 to it is not "within" the root. Return false iff some accesses partially
2101 build_access_subtree (struct access
**access
)
2103 struct access
*root
= *access
, *last_child
= NULL
;
2104 HOST_WIDE_INT limit
= root
->offset
+ root
->size
;
2106 *access
= (*access
)->next_grp
;
2107 while (*access
&& (*access
)->offset
+ (*access
)->size
<= limit
)
2110 root
->first_child
= *access
;
2112 last_child
->next_sibling
= *access
;
2113 last_child
= *access
;
2115 if (!build_access_subtree (access
))
2119 if (*access
&& (*access
)->offset
< limit
)
2125 /* Build a tree of access representatives, ACCESS is the pointer to the first
2126 one, others are linked in a list by the next_grp field. Return false iff
2127 some accesses partially overlap. */
2130 build_access_trees (struct access
*access
)
2134 struct access
*root
= access
;
2136 if (!build_access_subtree (&access
))
2138 root
->next_grp
= access
;
2143 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2147 expr_with_var_bounded_array_refs_p (tree expr
)
2149 while (handled_component_p (expr
))
2151 if (TREE_CODE (expr
) == ARRAY_REF
2152 && !tree_fits_shwi_p (array_ref_low_bound (expr
)))
2154 expr
= TREE_OPERAND (expr
, 0);
2159 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2160 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2161 sorts of access flags appropriately along the way, notably always set
2162 grp_read and grp_assign_read according to MARK_READ and grp_write when
2165 Creating a replacement for a scalar access is considered beneficial if its
2166 grp_hint is set (this means we are either attempting total scalarization or
2167 there is more than one direct read access) or according to the following
2170 Access written to through a scalar type (once or more times)
2172 | Written to in an assignment statement
2174 | | Access read as scalar _once_
2176 | | | Read in an assignment statement
2178 | | | | Scalarize Comment
2179 -----------------------------------------------------------------------------
2180 0 0 0 0 No access for the scalar
2181 0 0 0 1 No access for the scalar
2182 0 0 1 0 No Single read - won't help
2183 0 0 1 1 No The same case
2184 0 1 0 0 No access for the scalar
2185 0 1 0 1 No access for the scalar
2186 0 1 1 0 Yes s = *g; return s.i;
2187 0 1 1 1 Yes The same case as above
2188 1 0 0 0 No Won't help
2189 1 0 0 1 Yes s.i = 1; *g = s;
2190 1 0 1 0 Yes s.i = 5; g = s.i;
2191 1 0 1 1 Yes The same case as above
2192 1 1 0 0 No Won't help.
2193 1 1 0 1 Yes s.i = 1; *g = s;
2194 1 1 1 0 Yes s = *g; return s.i;
2195 1 1 1 1 Yes Any of the above yeses */
2198 analyze_access_subtree (struct access
*root
, struct access
*parent
,
2199 bool allow_replacements
)
2201 struct access
*child
;
2202 HOST_WIDE_INT limit
= root
->offset
+ root
->size
;
2203 HOST_WIDE_INT covered_to
= root
->offset
;
2204 bool scalar
= is_gimple_reg_type (root
->type
);
2205 bool hole
= false, sth_created
= false;
2209 if (parent
->grp_read
)
2211 if (parent
->grp_assignment_read
)
2212 root
->grp_assignment_read
= 1;
2213 if (parent
->grp_write
)
2214 root
->grp_write
= 1;
2215 if (parent
->grp_assignment_write
)
2216 root
->grp_assignment_write
= 1;
2217 if (parent
->grp_total_scalarization
)
2218 root
->grp_total_scalarization
= 1;
2221 if (root
->grp_unscalarizable_region
)
2222 allow_replacements
= false;
2224 if (allow_replacements
&& expr_with_var_bounded_array_refs_p (root
->expr
))
2225 allow_replacements
= false;
2227 for (child
= root
->first_child
; child
; child
= child
->next_sibling
)
2229 hole
|= covered_to
< child
->offset
;
2230 sth_created
|= analyze_access_subtree (child
, root
,
2231 allow_replacements
&& !scalar
);
2233 root
->grp_unscalarized_data
|= child
->grp_unscalarized_data
;
2234 root
->grp_total_scalarization
&= child
->grp_total_scalarization
;
2235 if (child
->grp_covered
)
2236 covered_to
+= child
->size
;
2241 if (allow_replacements
&& scalar
&& !root
->first_child
2243 || ((root
->grp_scalar_read
|| root
->grp_assignment_read
)
2244 && (root
->grp_scalar_write
|| root
->grp_assignment_write
))))
2246 /* Always create access replacements that cover the whole access.
2247 For integral types this means the precision has to match.
2248 Avoid assumptions based on the integral type kind, too. */
2249 if (INTEGRAL_TYPE_P (root
->type
)
2250 && (TREE_CODE (root
->type
) != INTEGER_TYPE
2251 || TYPE_PRECISION (root
->type
) != root
->size
)
2252 /* But leave bitfield accesses alone. */
2253 && (TREE_CODE (root
->expr
) != COMPONENT_REF
2254 || !DECL_BIT_FIELD (TREE_OPERAND (root
->expr
, 1))))
2256 tree rt
= root
->type
;
2257 gcc_assert ((root
->offset
% BITS_PER_UNIT
) == 0
2258 && (root
->size
% BITS_PER_UNIT
) == 0);
2259 root
->type
= build_nonstandard_integer_type (root
->size
,
2260 TYPE_UNSIGNED (rt
));
2261 root
->expr
= build_ref_for_offset (UNKNOWN_LOCATION
,
2262 root
->base
, root
->offset
,
2263 root
->type
, NULL
, false);
2265 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2267 fprintf (dump_file
, "Changing the type of a replacement for ");
2268 print_generic_expr (dump_file
, root
->base
, 0);
2269 fprintf (dump_file
, " offset: %u, size: %u ",
2270 (unsigned) root
->offset
, (unsigned) root
->size
);
2271 fprintf (dump_file
, " to an integer.\n");
2275 root
->grp_to_be_replaced
= 1;
2276 root
->replacement_decl
= create_access_replacement (root
);
2282 if (allow_replacements
2283 && scalar
&& !root
->first_child
2284 && (root
->grp_scalar_write
|| root
->grp_assignment_write
)
2285 && !bitmap_bit_p (cannot_scalarize_away_bitmap
,
2286 DECL_UID (root
->base
)))
2288 gcc_checking_assert (!root
->grp_scalar_read
2289 && !root
->grp_assignment_read
);
2291 if (MAY_HAVE_DEBUG_STMTS
)
2293 root
->grp_to_be_debug_replaced
= 1;
2294 root
->replacement_decl
= create_access_replacement (root
);
2298 if (covered_to
< limit
)
2301 root
->grp_total_scalarization
= 0;
2304 if (!hole
|| root
->grp_total_scalarization
)
2305 root
->grp_covered
= 1;
2306 else if (root
->grp_write
|| TREE_CODE (root
->base
) == PARM_DECL
)
2307 root
->grp_unscalarized_data
= 1; /* not covered and written to */
2311 /* Analyze all access trees linked by next_grp by the means of
2312 analyze_access_subtree. */
2314 analyze_access_trees (struct access
*access
)
2320 if (analyze_access_subtree (access
, NULL
, true))
2322 access
= access
->next_grp
;
2328 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2329 SIZE would conflict with an already existing one. If exactly such a child
2330 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2333 child_would_conflict_in_lacc (struct access
*lacc
, HOST_WIDE_INT norm_offset
,
2334 HOST_WIDE_INT size
, struct access
**exact_match
)
2336 struct access
*child
;
2338 for (child
= lacc
->first_child
; child
; child
= child
->next_sibling
)
2340 if (child
->offset
== norm_offset
&& child
->size
== size
)
2342 *exact_match
= child
;
2346 if (child
->offset
< norm_offset
+ size
2347 && child
->offset
+ child
->size
> norm_offset
)
2354 /* Create a new child access of PARENT, with all properties just like MODEL
2355 except for its offset and with its grp_write false and grp_read true.
2356 Return the new access or NULL if it cannot be created. Note that this access
2357 is created long after all splicing and sorting, it's not located in any
2358 access vector and is automatically a representative of its group. */
2360 static struct access
*
2361 create_artificial_child_access (struct access
*parent
, struct access
*model
,
2362 HOST_WIDE_INT new_offset
)
2364 struct access
*access
;
2365 struct access
**child
;
2366 tree expr
= parent
->base
;
2368 gcc_assert (!model
->grp_unscalarizable_region
);
2370 access
= (struct access
*) pool_alloc (access_pool
);
2371 memset (access
, 0, sizeof (struct access
));
2372 if (!build_user_friendly_ref_for_offset (&expr
, TREE_TYPE (expr
), new_offset
,
2375 access
->grp_no_warning
= true;
2376 expr
= build_ref_for_model (EXPR_LOCATION (parent
->base
), parent
->base
,
2377 new_offset
, model
, NULL
, false);
2380 access
->base
= parent
->base
;
2381 access
->expr
= expr
;
2382 access
->offset
= new_offset
;
2383 access
->size
= model
->size
;
2384 access
->type
= model
->type
;
2385 access
->grp_write
= true;
2386 access
->grp_read
= false;
2388 child
= &parent
->first_child
;
2389 while (*child
&& (*child
)->offset
< new_offset
)
2390 child
= &(*child
)->next_sibling
;
2392 access
->next_sibling
= *child
;
2399 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
2400 true if any new subaccess was created. Additionally, if RACC is a scalar
2401 access but LACC is not, change the type of the latter, if possible. */
2404 propagate_subaccesses_across_link (struct access
*lacc
, struct access
*racc
)
2406 struct access
*rchild
;
2407 HOST_WIDE_INT norm_delta
= lacc
->offset
- racc
->offset
;
2410 if (is_gimple_reg_type (lacc
->type
)
2411 || lacc
->grp_unscalarizable_region
2412 || racc
->grp_unscalarizable_region
)
2415 if (is_gimple_reg_type (racc
->type
))
2417 if (!lacc
->first_child
&& !racc
->first_child
)
2419 tree t
= lacc
->base
;
2421 lacc
->type
= racc
->type
;
2422 if (build_user_friendly_ref_for_offset (&t
, TREE_TYPE (t
),
2423 lacc
->offset
, racc
->type
))
2427 lacc
->expr
= build_ref_for_model (EXPR_LOCATION (lacc
->base
),
2428 lacc
->base
, lacc
->offset
,
2430 lacc
->grp_no_warning
= true;
2436 for (rchild
= racc
->first_child
; rchild
; rchild
= rchild
->next_sibling
)
2438 struct access
*new_acc
= NULL
;
2439 HOST_WIDE_INT norm_offset
= rchild
->offset
+ norm_delta
;
2441 if (rchild
->grp_unscalarizable_region
)
2444 if (child_would_conflict_in_lacc (lacc
, norm_offset
, rchild
->size
,
2449 rchild
->grp_hint
= 1;
2450 new_acc
->grp_hint
|= new_acc
->grp_read
;
2451 if (rchild
->first_child
)
2452 ret
|= propagate_subaccesses_across_link (new_acc
, rchild
);
2457 rchild
->grp_hint
= 1;
2458 new_acc
= create_artificial_child_access (lacc
, rchild
, norm_offset
);
2462 if (racc
->first_child
)
2463 propagate_subaccesses_across_link (new_acc
, rchild
);
2470 /* Propagate all subaccesses across assignment links. */
2473 propagate_all_subaccesses (void)
2475 while (work_queue_head
)
2477 struct access
*racc
= pop_access_from_work_queue ();
2478 struct assign_link
*link
;
2480 gcc_assert (racc
->first_link
);
2482 for (link
= racc
->first_link
; link
; link
= link
->next
)
2484 struct access
*lacc
= link
->lacc
;
2486 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (lacc
->base
)))
2488 lacc
= lacc
->group_representative
;
2489 if (propagate_subaccesses_across_link (lacc
, racc
)
2490 && lacc
->first_link
)
2491 add_access_to_work_queue (lacc
);
2496 /* Go through all accesses collected throughout the (intraprocedural) analysis
2497 stage, exclude overlapping ones, identify representatives and build trees
2498 out of them, making decisions about scalarization on the way. Return true
2499 iff there are any to-be-scalarized variables after this stage. */
2502 analyze_all_variable_accesses (void)
2505 bitmap tmp
= BITMAP_ALLOC (NULL
);
2507 unsigned i
, max_total_scalarization_size
;
2509 max_total_scalarization_size
= UNITS_PER_WORD
* BITS_PER_UNIT
2510 * MOVE_RATIO (optimize_function_for_speed_p (cfun
));
2512 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap
, 0, i
, bi
)
2513 if (bitmap_bit_p (should_scalarize_away_bitmap
, i
)
2514 && !bitmap_bit_p (cannot_scalarize_away_bitmap
, i
))
2516 tree var
= candidate (i
);
2518 if (TREE_CODE (var
) == VAR_DECL
2519 && type_consists_of_records_p (TREE_TYPE (var
)))
2521 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var
)))
2522 <= max_total_scalarization_size
)
2524 completely_scalarize_var (var
);
2525 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2527 fprintf (dump_file
, "Will attempt to totally scalarize ");
2528 print_generic_expr (dump_file
, var
, 0);
2529 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (var
));
2532 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2534 fprintf (dump_file
, "Too big to totally scalarize: ");
2535 print_generic_expr (dump_file
, var
, 0);
2536 fprintf (dump_file
, " (UID: %u)\n", DECL_UID (var
));
2541 bitmap_copy (tmp
, candidate_bitmap
);
2542 EXECUTE_IF_SET_IN_BITMAP (tmp
, 0, i
, bi
)
2544 tree var
= candidate (i
);
2545 struct access
*access
;
2547 access
= sort_and_splice_var_accesses (var
);
2548 if (!access
|| !build_access_trees (access
))
2549 disqualify_candidate (var
,
2550 "No or inhibitingly overlapping accesses.");
2553 propagate_all_subaccesses ();
2555 bitmap_copy (tmp
, candidate_bitmap
);
2556 EXECUTE_IF_SET_IN_BITMAP (tmp
, 0, i
, bi
)
2558 tree var
= candidate (i
);
2559 struct access
*access
= get_first_repr_for_decl (var
);
2561 if (analyze_access_trees (access
))
2564 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2566 fprintf (dump_file
, "\nAccess trees for ");
2567 print_generic_expr (dump_file
, var
, 0);
2568 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (var
));
2569 dump_access_tree (dump_file
, access
);
2570 fprintf (dump_file
, "\n");
2574 disqualify_candidate (var
, "No scalar replacements to be created.");
2581 statistics_counter_event (cfun
, "Scalarized aggregates", res
);
2588 /* Generate statements copying scalar replacements of accesses within a subtree
2589 into or out of AGG. ACCESS, all its children, siblings and their children
2590 are to be processed. AGG is an aggregate type expression (can be a
2591 declaration but does not have to be, it can for example also be a mem_ref or
2592 a series of handled components). TOP_OFFSET is the offset of the processed
2593 subtree which has to be subtracted from offsets of individual accesses to
2594 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2595 replacements in the interval <start_offset, start_offset + chunk_size>,
2596 otherwise copy all. GSI is a statement iterator used to place the new
2597 statements. WRITE should be true when the statements should write from AGG
2598 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2599 statements will be added after the current statement in GSI, they will be
2600 added before the statement otherwise. */
2603 generate_subtree_copies (struct access
*access
, tree agg
,
2604 HOST_WIDE_INT top_offset
,
2605 HOST_WIDE_INT start_offset
, HOST_WIDE_INT chunk_size
,
2606 gimple_stmt_iterator
*gsi
, bool write
,
2607 bool insert_after
, location_t loc
)
2611 if (chunk_size
&& access
->offset
>= start_offset
+ chunk_size
)
2614 if (access
->grp_to_be_replaced
2616 || access
->offset
+ access
->size
> start_offset
))
2618 tree expr
, repl
= get_access_replacement (access
);
2621 expr
= build_ref_for_model (loc
, agg
, access
->offset
- top_offset
,
2622 access
, gsi
, insert_after
);
2626 if (access
->grp_partial_lhs
)
2627 expr
= force_gimple_operand_gsi (gsi
, expr
, true, NULL_TREE
,
2629 insert_after
? GSI_NEW_STMT
2631 stmt
= gimple_build_assign (repl
, expr
);
2635 TREE_NO_WARNING (repl
) = 1;
2636 if (access
->grp_partial_lhs
)
2637 repl
= force_gimple_operand_gsi (gsi
, repl
, true, NULL_TREE
,
2639 insert_after
? GSI_NEW_STMT
2641 stmt
= gimple_build_assign (expr
, repl
);
2643 gimple_set_location (stmt
, loc
);
2646 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2648 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2650 sra_stats
.subtree_copies
++;
2653 && access
->grp_to_be_debug_replaced
2655 || access
->offset
+ access
->size
> start_offset
))
2658 tree drhs
= build_debug_ref_for_model (loc
, agg
,
2659 access
->offset
- top_offset
,
2661 ds
= gimple_build_debug_bind (get_access_replacement (access
),
2662 drhs
, gsi_stmt (*gsi
));
2664 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2666 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
2669 if (access
->first_child
)
2670 generate_subtree_copies (access
->first_child
, agg
, top_offset
,
2671 start_offset
, chunk_size
, gsi
,
2672 write
, insert_after
, loc
);
2674 access
= access
->next_sibling
;
2679 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2680 the root of the subtree to be processed. GSI is the statement iterator used
2681 for inserting statements which are added after the current statement if
2682 INSERT_AFTER is true or before it otherwise. */
2685 init_subtree_with_zero (struct access
*access
, gimple_stmt_iterator
*gsi
,
2686 bool insert_after
, location_t loc
)
2689 struct access
*child
;
2691 if (access
->grp_to_be_replaced
)
2695 stmt
= gimple_build_assign (get_access_replacement (access
),
2696 build_zero_cst (access
->type
));
2698 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2700 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2702 gimple_set_location (stmt
, loc
);
2704 else if (access
->grp_to_be_debug_replaced
)
2706 gimple ds
= gimple_build_debug_bind (get_access_replacement (access
),
2707 build_zero_cst (access
->type
),
2710 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2712 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
2715 for (child
= access
->first_child
; child
; child
= child
->next_sibling
)
2716 init_subtree_with_zero (child
, gsi
, insert_after
, loc
);
2719 /* Search for an access representative for the given expression EXPR and
2720 return it or NULL if it cannot be found. */
2722 static struct access
*
2723 get_access_for_expr (tree expr
)
2725 HOST_WIDE_INT offset
, size
, max_size
;
2728 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2729 a different size than the size of its argument and we need the latter
2731 if (TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
2732 expr
= TREE_OPERAND (expr
, 0);
2734 base
= get_ref_base_and_extent (expr
, &offset
, &size
, &max_size
);
2735 if (max_size
== -1 || !DECL_P (base
))
2738 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (base
)))
2741 return get_var_base_offset_size_access (base
, offset
, max_size
);
2744 /* Replace the expression EXPR with a scalar replacement if there is one and
2745 generate other statements to do type conversion or subtree copying if
2746 necessary. GSI is used to place newly created statements, WRITE is true if
2747 the expression is being written to (it is on a LHS of a statement or output
2748 in an assembly statement). */
2751 sra_modify_expr (tree
*expr
, gimple_stmt_iterator
*gsi
, bool write
)
2754 struct access
*access
;
2757 if (TREE_CODE (*expr
) == BIT_FIELD_REF
)
2760 expr
= &TREE_OPERAND (*expr
, 0);
2765 if (TREE_CODE (*expr
) == REALPART_EXPR
|| TREE_CODE (*expr
) == IMAGPART_EXPR
)
2766 expr
= &TREE_OPERAND (*expr
, 0);
2767 access
= get_access_for_expr (*expr
);
2770 type
= TREE_TYPE (*expr
);
2772 loc
= gimple_location (gsi_stmt (*gsi
));
2773 if (access
->grp_to_be_replaced
)
2775 tree repl
= get_access_replacement (access
);
2776 /* If we replace a non-register typed access simply use the original
2777 access expression to extract the scalar component afterwards.
2778 This happens if scalarizing a function return value or parameter
2779 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2780 gcc.c-torture/compile/20011217-1.c.
2782 We also want to use this when accessing a complex or vector which can
2783 be accessed as a different type too, potentially creating a need for
2784 type conversion (see PR42196) and when scalarized unions are involved
2785 in assembler statements (see PR42398). */
2786 if (!useless_type_conversion_p (type
, access
->type
))
2790 ref
= build_ref_for_model (loc
, access
->base
, access
->offset
, access
,
2797 if (access
->grp_partial_lhs
)
2798 ref
= force_gimple_operand_gsi (gsi
, ref
, true, NULL_TREE
,
2799 false, GSI_NEW_STMT
);
2800 stmt
= gimple_build_assign (repl
, ref
);
2801 gimple_set_location (stmt
, loc
);
2802 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2808 if (access
->grp_partial_lhs
)
2809 repl
= force_gimple_operand_gsi (gsi
, repl
, true, NULL_TREE
,
2810 true, GSI_SAME_STMT
);
2811 stmt
= gimple_build_assign (ref
, repl
);
2812 gimple_set_location (stmt
, loc
);
2813 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2820 else if (write
&& access
->grp_to_be_debug_replaced
)
2822 gimple ds
= gimple_build_debug_bind (get_access_replacement (access
),
2825 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2828 if (access
->first_child
)
2830 HOST_WIDE_INT start_offset
, chunk_size
;
2832 && tree_fits_uhwi_p (TREE_OPERAND (bfr
, 1))
2833 && tree_fits_uhwi_p (TREE_OPERAND (bfr
, 2)))
2835 chunk_size
= tree_to_uhwi (TREE_OPERAND (bfr
, 1));
2836 start_offset
= access
->offset
2837 + tree_to_uhwi (TREE_OPERAND (bfr
, 2));
2840 start_offset
= chunk_size
= 0;
2842 generate_subtree_copies (access
->first_child
, access
->base
, 0,
2843 start_offset
, chunk_size
, gsi
, write
, write
,
2849 /* Where scalar replacements of the RHS have been written to when a replacement
2850 of a LHS of an assigments cannot be direclty loaded from a replacement of
2852 enum unscalarized_data_handling
{ SRA_UDH_NONE
, /* Nothing done so far. */
2853 SRA_UDH_RIGHT
, /* Data flushed to the RHS. */
2854 SRA_UDH_LEFT
}; /* Data flushed to the LHS. */
2856 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2857 base aggregate if there are unscalarized data or directly to LHS of the
2858 statement that is pointed to by GSI otherwise. */
2860 static enum unscalarized_data_handling
2861 handle_unscalarized_data_in_subtree (struct access
*top_racc
,
2862 gimple_stmt_iterator
*gsi
)
2864 if (top_racc
->grp_unscalarized_data
)
2866 generate_subtree_copies (top_racc
->first_child
, top_racc
->base
, 0, 0, 0,
2868 gimple_location (gsi_stmt (*gsi
)));
2869 return SRA_UDH_RIGHT
;
2873 tree lhs
= gimple_assign_lhs (gsi_stmt (*gsi
));
2874 generate_subtree_copies (top_racc
->first_child
, lhs
, top_racc
->offset
,
2875 0, 0, gsi
, false, false,
2876 gimple_location (gsi_stmt (*gsi
)));
2877 return SRA_UDH_LEFT
;
2882 /* Try to generate statements to load all sub-replacements in an access subtree
2883 formed by children of LACC from scalar replacements in the TOP_RACC subtree.
2884 If that is not possible, refresh the TOP_RACC base aggregate and load the
2885 accesses from it. LEFT_OFFSET is the offset of the left whole subtree being
2886 copied. NEW_GSI is stmt iterator used for statement insertions after the
2887 original assignment, OLD_GSI is used to insert statements before the
2888 assignment. *REFRESHED keeps the information whether we have needed to
2889 refresh replacements of the LHS and from which side of the assignments this
2893 load_assign_lhs_subreplacements (struct access
*lacc
, struct access
*top_racc
,
2894 HOST_WIDE_INT left_offset
,
2895 gimple_stmt_iterator
*old_gsi
,
2896 gimple_stmt_iterator
*new_gsi
,
2897 enum unscalarized_data_handling
*refreshed
)
2899 location_t loc
= gimple_location (gsi_stmt (*old_gsi
));
2900 for (lacc
= lacc
->first_child
; lacc
; lacc
= lacc
->next_sibling
)
2902 HOST_WIDE_INT offset
= lacc
->offset
- left_offset
+ top_racc
->offset
;
2904 if (lacc
->grp_to_be_replaced
)
2906 struct access
*racc
;
2910 racc
= find_access_in_subtree (top_racc
, offset
, lacc
->size
);
2911 if (racc
&& racc
->grp_to_be_replaced
)
2913 rhs
= get_access_replacement (racc
);
2914 if (!useless_type_conversion_p (lacc
->type
, racc
->type
))
2915 rhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, lacc
->type
, rhs
);
2917 if (racc
->grp_partial_lhs
&& lacc
->grp_partial_lhs
)
2918 rhs
= force_gimple_operand_gsi (old_gsi
, rhs
, true, NULL_TREE
,
2919 true, GSI_SAME_STMT
);
2923 /* No suitable access on the right hand side, need to load from
2924 the aggregate. See if we have to update it first... */
2925 if (*refreshed
== SRA_UDH_NONE
)
2926 *refreshed
= handle_unscalarized_data_in_subtree (top_racc
,
2929 if (*refreshed
== SRA_UDH_LEFT
)
2930 rhs
= build_ref_for_model (loc
, lacc
->base
, lacc
->offset
, lacc
,
2933 rhs
= build_ref_for_model (loc
, top_racc
->base
, offset
, lacc
,
2935 if (lacc
->grp_partial_lhs
)
2936 rhs
= force_gimple_operand_gsi (new_gsi
, rhs
, true, NULL_TREE
,
2937 false, GSI_NEW_STMT
);
2940 stmt
= gimple_build_assign (get_access_replacement (lacc
), rhs
);
2941 gsi_insert_after (new_gsi
, stmt
, GSI_NEW_STMT
);
2942 gimple_set_location (stmt
, loc
);
2944 sra_stats
.subreplacements
++;
2948 if (*refreshed
== SRA_UDH_NONE
2949 && lacc
->grp_read
&& !lacc
->grp_covered
)
2950 *refreshed
= handle_unscalarized_data_in_subtree (top_racc
,
2952 if (lacc
&& lacc
->grp_to_be_debug_replaced
)
2956 struct access
*racc
= find_access_in_subtree (top_racc
, offset
,
2959 if (racc
&& racc
->grp_to_be_replaced
)
2961 if (racc
->grp_write
)
2962 drhs
= get_access_replacement (racc
);
2966 else if (*refreshed
== SRA_UDH_LEFT
)
2967 drhs
= build_debug_ref_for_model (loc
, lacc
->base
, lacc
->offset
,
2969 else if (*refreshed
== SRA_UDH_RIGHT
)
2970 drhs
= build_debug_ref_for_model (loc
, top_racc
->base
, offset
,
2975 && !useless_type_conversion_p (lacc
->type
, TREE_TYPE (drhs
)))
2976 drhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
,
2978 ds
= gimple_build_debug_bind (get_access_replacement (lacc
),
2979 drhs
, gsi_stmt (*old_gsi
));
2980 gsi_insert_after (new_gsi
, ds
, GSI_NEW_STMT
);
2984 if (lacc
->first_child
)
2985 load_assign_lhs_subreplacements (lacc
, top_racc
, left_offset
,
2986 old_gsi
, new_gsi
, refreshed
);
2990 /* Result code for SRA assignment modification. */
2991 enum assignment_mod_result
{ SRA_AM_NONE
, /* nothing done for the stmt */
2992 SRA_AM_MODIFIED
, /* stmt changed but not
2994 SRA_AM_REMOVED
}; /* stmt eliminated */
2996 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
2997 to the assignment and GSI is the statement iterator pointing at it. Returns
2998 the same values as sra_modify_assign. */
3000 static enum assignment_mod_result
3001 sra_modify_constructor_assign (gimple
*stmt
, gimple_stmt_iterator
*gsi
)
3003 tree lhs
= gimple_assign_lhs (*stmt
);
3007 acc
= get_access_for_expr (lhs
);
3011 if (gimple_clobber_p (*stmt
))
3013 /* Remove clobbers of fully scalarized variables, otherwise
3015 if (acc
->grp_covered
)
3017 unlink_stmt_vdef (*stmt
);
3018 gsi_remove (gsi
, true);
3019 release_defs (*stmt
);
3020 return SRA_AM_REMOVED
;
3026 loc
= gimple_location (*stmt
);
3027 if (vec_safe_length (CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt
))) > 0)
3029 /* I have never seen this code path trigger but if it can happen the
3030 following should handle it gracefully. */
3031 if (access_has_children_p (acc
))
3032 generate_subtree_copies (acc
->first_child
, acc
->base
, 0, 0, 0, gsi
,
3034 return SRA_AM_MODIFIED
;
3037 if (acc
->grp_covered
)
3039 init_subtree_with_zero (acc
, gsi
, false, loc
);
3040 unlink_stmt_vdef (*stmt
);
3041 gsi_remove (gsi
, true);
3042 release_defs (*stmt
);
3043 return SRA_AM_REMOVED
;
3047 init_subtree_with_zero (acc
, gsi
, true, loc
);
3048 return SRA_AM_MODIFIED
;
3052 /* Create and return a new suitable default definition SSA_NAME for RACC which
3053 is an access describing an uninitialized part of an aggregate that is being
3057 get_repl_default_def_ssa_name (struct access
*racc
)
3059 gcc_checking_assert (!racc
->grp_to_be_replaced
3060 && !racc
->grp_to_be_debug_replaced
);
3061 if (!racc
->replacement_decl
)
3062 racc
->replacement_decl
= create_access_replacement (racc
);
3063 return get_or_create_ssa_default_def (cfun
, racc
->replacement_decl
);
3066 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3067 bit-field field declaration somewhere in it. */
3070 contains_vce_or_bfcref_p (const_tree ref
)
3072 while (handled_component_p (ref
))
3074 if (TREE_CODE (ref
) == VIEW_CONVERT_EXPR
3075 || (TREE_CODE (ref
) == COMPONENT_REF
3076 && DECL_BIT_FIELD (TREE_OPERAND (ref
, 1))))
3078 ref
= TREE_OPERAND (ref
, 0);
3084 /* Examine both sides of the assignment statement pointed to by STMT, replace
3085 them with a scalare replacement if there is one and generate copying of
3086 replacements if scalarized aggregates have been used in the assignment. GSI
3087 is used to hold generated statements for type conversions and subtree
3090 static enum assignment_mod_result
3091 sra_modify_assign (gimple
*stmt
, gimple_stmt_iterator
*gsi
)
3093 struct access
*lacc
, *racc
;
3095 bool modify_this_stmt
= false;
3096 bool force_gimple_rhs
= false;
3098 gimple_stmt_iterator orig_gsi
= *gsi
;
3100 if (!gimple_assign_single_p (*stmt
))
3102 lhs
= gimple_assign_lhs (*stmt
);
3103 rhs
= gimple_assign_rhs1 (*stmt
);
3105 if (TREE_CODE (rhs
) == CONSTRUCTOR
)
3106 return sra_modify_constructor_assign (stmt
, gsi
);
3108 if (TREE_CODE (rhs
) == REALPART_EXPR
|| TREE_CODE (lhs
) == REALPART_EXPR
3109 || TREE_CODE (rhs
) == IMAGPART_EXPR
|| TREE_CODE (lhs
) == IMAGPART_EXPR
3110 || TREE_CODE (rhs
) == BIT_FIELD_REF
|| TREE_CODE (lhs
) == BIT_FIELD_REF
)
3112 modify_this_stmt
= sra_modify_expr (gimple_assign_rhs1_ptr (*stmt
),
3114 modify_this_stmt
|= sra_modify_expr (gimple_assign_lhs_ptr (*stmt
),
3116 return modify_this_stmt
? SRA_AM_MODIFIED
: SRA_AM_NONE
;
3119 lacc
= get_access_for_expr (lhs
);
3120 racc
= get_access_for_expr (rhs
);
3124 loc
= gimple_location (*stmt
);
3125 if (lacc
&& lacc
->grp_to_be_replaced
)
3127 lhs
= get_access_replacement (lacc
);
3128 gimple_assign_set_lhs (*stmt
, lhs
);
3129 modify_this_stmt
= true;
3130 if (lacc
->grp_partial_lhs
)
3131 force_gimple_rhs
= true;
3135 if (racc
&& racc
->grp_to_be_replaced
)
3137 rhs
= get_access_replacement (racc
);
3138 modify_this_stmt
= true;
3139 if (racc
->grp_partial_lhs
)
3140 force_gimple_rhs
= true;
3144 && !racc
->grp_unscalarized_data
3145 && TREE_CODE (lhs
) == SSA_NAME
3146 && !access_has_replacements_p (racc
))
3148 rhs
= get_repl_default_def_ssa_name (racc
);
3149 modify_this_stmt
= true;
3153 if (modify_this_stmt
)
3155 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
3157 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3158 ??? This should move to fold_stmt which we simply should
3159 call after building a VIEW_CONVERT_EXPR here. */
3160 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs
))
3161 && !contains_bitfld_component_ref_p (lhs
))
3163 lhs
= build_ref_for_model (loc
, lhs
, 0, racc
, gsi
, false);
3164 gimple_assign_set_lhs (*stmt
, lhs
);
3166 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs
))
3167 && !contains_vce_or_bfcref_p (rhs
))
3168 rhs
= build_ref_for_model (loc
, rhs
, 0, lacc
, gsi
, false);
3170 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
3172 rhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, TREE_TYPE (lhs
),
3174 if (is_gimple_reg_type (TREE_TYPE (lhs
))
3175 && TREE_CODE (lhs
) != SSA_NAME
)
3176 force_gimple_rhs
= true;
3181 if (lacc
&& lacc
->grp_to_be_debug_replaced
)
3183 tree dlhs
= get_access_replacement (lacc
);
3184 tree drhs
= unshare_expr (rhs
);
3185 if (!useless_type_conversion_p (TREE_TYPE (dlhs
), TREE_TYPE (drhs
)))
3187 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs
))
3188 && !contains_vce_or_bfcref_p (drhs
))
3189 drhs
= build_debug_ref_for_model (loc
, drhs
, 0, lacc
);
3191 && !useless_type_conversion_p (TREE_TYPE (dlhs
),
3193 drhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
,
3194 TREE_TYPE (dlhs
), drhs
);
3196 gimple ds
= gimple_build_debug_bind (dlhs
, drhs
, *stmt
);
3197 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
3200 /* From this point on, the function deals with assignments in between
3201 aggregates when at least one has scalar reductions of some of its
3202 components. There are three possible scenarios: Both the LHS and RHS have
3203 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3205 In the first case, we would like to load the LHS components from RHS
3206 components whenever possible. If that is not possible, we would like to
3207 read it directly from the RHS (after updating it by storing in it its own
3208 components). If there are some necessary unscalarized data in the LHS,
3209 those will be loaded by the original assignment too. If neither of these
3210 cases happen, the original statement can be removed. Most of this is done
3211 by load_assign_lhs_subreplacements.
3213 In the second case, we would like to store all RHS scalarized components
3214 directly into LHS and if they cover the aggregate completely, remove the
3215 statement too. In the third case, we want the LHS components to be loaded
3216 directly from the RHS (DSE will remove the original statement if it
3219 This is a bit complex but manageable when types match and when unions do
3220 not cause confusion in a way that we cannot really load a component of LHS
3221 from the RHS or vice versa (the access representing this level can have
3222 subaccesses that are accessible only through a different union field at a
3223 higher level - different from the one used in the examined expression).
3226 Therefore, I specially handle a fourth case, happening when there is a
3227 specific type cast or it is impossible to locate a scalarized subaccess on
3228 the other side of the expression. If that happens, I simply "refresh" the
3229 RHS by storing in it is scalarized components leave the original statement
3230 there to do the copying and then load the scalar replacements of the LHS.
3231 This is what the first branch does. */
3233 if (modify_this_stmt
3234 || gimple_has_volatile_ops (*stmt
)
3235 || contains_vce_or_bfcref_p (rhs
)
3236 || contains_vce_or_bfcref_p (lhs
))
3238 if (access_has_children_p (racc
))
3239 generate_subtree_copies (racc
->first_child
, racc
->base
, 0, 0, 0,
3240 gsi
, false, false, loc
);
3241 if (access_has_children_p (lacc
))
3242 generate_subtree_copies (lacc
->first_child
, lacc
->base
, 0, 0, 0,
3243 gsi
, true, true, loc
);
3244 sra_stats
.separate_lhs_rhs_handling
++;
3246 /* This gimplification must be done after generate_subtree_copies,
3247 lest we insert the subtree copies in the middle of the gimplified
3249 if (force_gimple_rhs
)
3250 rhs
= force_gimple_operand_gsi (&orig_gsi
, rhs
, true, NULL_TREE
,
3251 true, GSI_SAME_STMT
);
3252 if (gimple_assign_rhs1 (*stmt
) != rhs
)
3254 modify_this_stmt
= true;
3255 gimple_assign_set_rhs_from_tree (&orig_gsi
, rhs
);
3256 gcc_assert (*stmt
== gsi_stmt (orig_gsi
));
3259 return modify_this_stmt
? SRA_AM_MODIFIED
: SRA_AM_NONE
;
3263 if (access_has_children_p (lacc
)
3264 && access_has_children_p (racc
)
3265 /* When an access represents an unscalarizable region, it usually
3266 represents accesses with variable offset and thus must not be used
3267 to generate new memory accesses. */
3268 && !lacc
->grp_unscalarizable_region
3269 && !racc
->grp_unscalarizable_region
)
3271 gimple_stmt_iterator orig_gsi
= *gsi
;
3272 enum unscalarized_data_handling refreshed
;
3274 if (lacc
->grp_read
&& !lacc
->grp_covered
)
3275 refreshed
= handle_unscalarized_data_in_subtree (racc
, gsi
);
3277 refreshed
= SRA_UDH_NONE
;
3279 load_assign_lhs_subreplacements (lacc
, racc
, lacc
->offset
,
3280 &orig_gsi
, gsi
, &refreshed
);
3281 if (refreshed
!= SRA_UDH_RIGHT
)
3284 unlink_stmt_vdef (*stmt
);
3285 gsi_remove (&orig_gsi
, true);
3286 release_defs (*stmt
);
3287 sra_stats
.deleted
++;
3288 return SRA_AM_REMOVED
;
3293 if (access_has_children_p (racc
)
3294 && !racc
->grp_unscalarized_data
)
3298 fprintf (dump_file
, "Removing load: ");
3299 print_gimple_stmt (dump_file
, *stmt
, 0, 0);
3301 generate_subtree_copies (racc
->first_child
, lhs
,
3302 racc
->offset
, 0, 0, gsi
,
3304 gcc_assert (*stmt
== gsi_stmt (*gsi
));
3305 unlink_stmt_vdef (*stmt
);
3306 gsi_remove (gsi
, true);
3307 release_defs (*stmt
);
3308 sra_stats
.deleted
++;
3309 return SRA_AM_REMOVED
;
3311 /* Restore the aggregate RHS from its components so the
3312 prevailing aggregate copy does the right thing. */
3313 if (access_has_children_p (racc
))
3314 generate_subtree_copies (racc
->first_child
, racc
->base
, 0, 0, 0,
3315 gsi
, false, false, loc
);
3316 /* Re-load the components of the aggregate copy destination.
3317 But use the RHS aggregate to load from to expose more
3318 optimization opportunities. */
3319 if (access_has_children_p (lacc
))
3320 generate_subtree_copies (lacc
->first_child
, rhs
, lacc
->offset
,
3321 0, 0, gsi
, true, true, loc
);
3328 /* Traverse the function body and all modifications as decided in
3329 analyze_all_variable_accesses. Return true iff the CFG has been
3333 sra_modify_function_body (void)
3335 bool cfg_changed
= false;
3338 FOR_EACH_BB_FN (bb
, cfun
)
3340 gimple_stmt_iterator gsi
= gsi_start_bb (bb
);
3341 while (!gsi_end_p (gsi
))
3343 gimple stmt
= gsi_stmt (gsi
);
3344 enum assignment_mod_result assign_result
;
3345 bool modified
= false, deleted
= false;
3349 switch (gimple_code (stmt
))
3352 t
= gimple_return_retval_ptr (stmt
);
3353 if (*t
!= NULL_TREE
)
3354 modified
|= sra_modify_expr (t
, &gsi
, false);
3358 assign_result
= sra_modify_assign (&stmt
, &gsi
);
3359 modified
|= assign_result
== SRA_AM_MODIFIED
;
3360 deleted
= assign_result
== SRA_AM_REMOVED
;
3364 /* Operands must be processed before the lhs. */
3365 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
3367 t
= gimple_call_arg_ptr (stmt
, i
);
3368 modified
|= sra_modify_expr (t
, &gsi
, false);
3371 if (gimple_call_lhs (stmt
))
3373 t
= gimple_call_lhs_ptr (stmt
);
3374 modified
|= sra_modify_expr (t
, &gsi
, true);
3379 for (i
= 0; i
< gimple_asm_ninputs (stmt
); i
++)
3381 t
= &TREE_VALUE (gimple_asm_input_op (stmt
, i
));
3382 modified
|= sra_modify_expr (t
, &gsi
, false);
3384 for (i
= 0; i
< gimple_asm_noutputs (stmt
); i
++)
3386 t
= &TREE_VALUE (gimple_asm_output_op (stmt
, i
));
3387 modified
|= sra_modify_expr (t
, &gsi
, true);
3398 if (maybe_clean_eh_stmt (stmt
)
3399 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
3410 /* Generate statements initializing scalar replacements of parts of function
3414 initialize_parameter_reductions (void)
3416 gimple_stmt_iterator gsi
;
3417 gimple_seq seq
= NULL
;
3420 gsi
= gsi_start (seq
);
3421 for (parm
= DECL_ARGUMENTS (current_function_decl
);
3423 parm
= DECL_CHAIN (parm
))
3425 vec
<access_p
> *access_vec
;
3426 struct access
*access
;
3428 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
3430 access_vec
= get_base_access_vector (parm
);
3434 for (access
= (*access_vec
)[0];
3436 access
= access
->next_grp
)
3437 generate_subtree_copies (access
, parm
, 0, 0, 0, &gsi
, true, true,
3438 EXPR_LOCATION (parm
));
3441 seq
= gsi_seq (gsi
);
3443 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun
)), seq
);
3446 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3447 it reveals there are components of some aggregates to be scalarized, it runs
3448 the required transformations. */
3450 perform_intra_sra (void)
3455 if (!find_var_candidates ())
3458 if (!scan_function ())
3461 if (!analyze_all_variable_accesses ())
3464 if (sra_modify_function_body ())
3465 ret
= TODO_update_ssa
| TODO_cleanup_cfg
;
3467 ret
= TODO_update_ssa
;
3468 initialize_parameter_reductions ();
3470 statistics_counter_event (cfun
, "Scalar replacements created",
3471 sra_stats
.replacements
);
3472 statistics_counter_event (cfun
, "Modified expressions", sra_stats
.exprs
);
3473 statistics_counter_event (cfun
, "Subtree copy stmts",
3474 sra_stats
.subtree_copies
);
3475 statistics_counter_event (cfun
, "Subreplacement stmts",
3476 sra_stats
.subreplacements
);
3477 statistics_counter_event (cfun
, "Deleted stmts", sra_stats
.deleted
);
3478 statistics_counter_event (cfun
, "Separate LHS and RHS handling",
3479 sra_stats
.separate_lhs_rhs_handling
);
3482 sra_deinitialize ();
3486 /* Perform early intraprocedural SRA. */
3488 early_intra_sra (void)
3490 sra_mode
= SRA_MODE_EARLY_INTRA
;
3491 return perform_intra_sra ();
3494 /* Perform "late" intraprocedural SRA. */
3496 late_intra_sra (void)
3498 sra_mode
= SRA_MODE_INTRA
;
3499 return perform_intra_sra ();
3504 gate_intra_sra (void)
3506 return flag_tree_sra
!= 0 && dbg_cnt (tree_sra
);
3512 const pass_data pass_data_sra_early
=
3514 GIMPLE_PASS
, /* type */
3516 OPTGROUP_NONE
, /* optinfo_flags */
3517 true, /* has_gate */
3518 true, /* has_execute */
3519 TV_TREE_SRA
, /* tv_id */
3520 ( PROP_cfg
| PROP_ssa
), /* properties_required */
3521 0, /* properties_provided */
3522 0, /* properties_destroyed */
3523 0, /* todo_flags_start */
3524 ( TODO_update_ssa
| TODO_verify_ssa
), /* todo_flags_finish */
3527 class pass_sra_early
: public gimple_opt_pass
3530 pass_sra_early (gcc::context
*ctxt
)
3531 : gimple_opt_pass (pass_data_sra_early
, ctxt
)
3534 /* opt_pass methods: */
3535 bool gate () { return gate_intra_sra (); }
3536 unsigned int execute () { return early_intra_sra (); }
3538 }; // class pass_sra_early
3543 make_pass_sra_early (gcc::context
*ctxt
)
3545 return new pass_sra_early (ctxt
);
3550 const pass_data pass_data_sra
=
3552 GIMPLE_PASS
, /* type */
3554 OPTGROUP_NONE
, /* optinfo_flags */
3555 true, /* has_gate */
3556 true, /* has_execute */
3557 TV_TREE_SRA
, /* tv_id */
3558 ( PROP_cfg
| PROP_ssa
), /* properties_required */
3559 0, /* properties_provided */
3560 0, /* properties_destroyed */
3561 TODO_update_address_taken
, /* todo_flags_start */
3562 ( TODO_update_ssa
| TODO_verify_ssa
), /* todo_flags_finish */
3565 class pass_sra
: public gimple_opt_pass
3568 pass_sra (gcc::context
*ctxt
)
3569 : gimple_opt_pass (pass_data_sra
, ctxt
)
3572 /* opt_pass methods: */
3573 bool gate () { return gate_intra_sra (); }
3574 unsigned int execute () { return late_intra_sra (); }
3576 }; // class pass_sra
3581 make_pass_sra (gcc::context
*ctxt
)
3583 return new pass_sra (ctxt
);
3587 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3591 is_unused_scalar_param (tree parm
)
3594 return (is_gimple_reg (parm
)
3595 && (!(name
= ssa_default_def (cfun
, parm
))
3596 || has_zero_uses (name
)));
3599 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3600 examine whether there are any direct or otherwise infeasible ones. If so,
3601 return true, otherwise return false. PARM must be a gimple register with a
3602 non-NULL default definition. */
3605 ptr_parm_has_direct_uses (tree parm
)
3607 imm_use_iterator ui
;
3609 tree name
= ssa_default_def (cfun
, parm
);
3612 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
3615 use_operand_p use_p
;
3617 if (is_gimple_debug (stmt
))
3620 /* Valid uses include dereferences on the lhs and the rhs. */
3621 if (gimple_has_lhs (stmt
))
3623 tree lhs
= gimple_get_lhs (stmt
);
3624 while (handled_component_p (lhs
))
3625 lhs
= TREE_OPERAND (lhs
, 0);
3626 if (TREE_CODE (lhs
) == MEM_REF
3627 && TREE_OPERAND (lhs
, 0) == name
3628 && integer_zerop (TREE_OPERAND (lhs
, 1))
3629 && types_compatible_p (TREE_TYPE (lhs
),
3630 TREE_TYPE (TREE_TYPE (name
)))
3631 && !TREE_THIS_VOLATILE (lhs
))
3634 if (gimple_assign_single_p (stmt
))
3636 tree rhs
= gimple_assign_rhs1 (stmt
);
3637 while (handled_component_p (rhs
))
3638 rhs
= TREE_OPERAND (rhs
, 0);
3639 if (TREE_CODE (rhs
) == MEM_REF
3640 && TREE_OPERAND (rhs
, 0) == name
3641 && integer_zerop (TREE_OPERAND (rhs
, 1))
3642 && types_compatible_p (TREE_TYPE (rhs
),
3643 TREE_TYPE (TREE_TYPE (name
)))
3644 && !TREE_THIS_VOLATILE (rhs
))
3647 else if (is_gimple_call (stmt
))
3650 for (i
= 0; i
< gimple_call_num_args (stmt
); ++i
)
3652 tree arg
= gimple_call_arg (stmt
, i
);
3653 while (handled_component_p (arg
))
3654 arg
= TREE_OPERAND (arg
, 0);
3655 if (TREE_CODE (arg
) == MEM_REF
3656 && TREE_OPERAND (arg
, 0) == name
3657 && integer_zerop (TREE_OPERAND (arg
, 1))
3658 && types_compatible_p (TREE_TYPE (arg
),
3659 TREE_TYPE (TREE_TYPE (name
)))
3660 && !TREE_THIS_VOLATILE (arg
))
3665 /* If the number of valid uses does not match the number of
3666 uses in this stmt there is an unhandled use. */
3667 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
3674 BREAK_FROM_IMM_USE_STMT (ui
);
3680 /* Identify candidates for reduction for IPA-SRA based on their type and mark
3681 them in candidate_bitmap. Note that these do not necessarily include
3682 parameter which are unused and thus can be removed. Return true iff any
3683 such candidate has been found. */
3686 find_param_candidates (void)
3693 for (parm
= DECL_ARGUMENTS (current_function_decl
);
3695 parm
= DECL_CHAIN (parm
))
3697 tree type
= TREE_TYPE (parm
);
3702 if (TREE_THIS_VOLATILE (parm
)
3703 || TREE_ADDRESSABLE (parm
)
3704 || (!is_gimple_reg_type (type
) && is_va_list_type (type
)))
3707 if (is_unused_scalar_param (parm
))
3713 if (POINTER_TYPE_P (type
))
3715 type
= TREE_TYPE (type
);
3717 if (TREE_CODE (type
) == FUNCTION_TYPE
3718 || TYPE_VOLATILE (type
)
3719 || (TREE_CODE (type
) == ARRAY_TYPE
3720 && TYPE_NONALIASED_COMPONENT (type
))
3721 || !is_gimple_reg (parm
)
3722 || is_va_list_type (type
)
3723 || ptr_parm_has_direct_uses (parm
))
3726 else if (!AGGREGATE_TYPE_P (type
))
3729 if (!COMPLETE_TYPE_P (type
)
3730 || !tree_fits_uhwi_p (TYPE_SIZE (type
))
3731 || tree_to_uhwi (TYPE_SIZE (type
)) == 0
3732 || (AGGREGATE_TYPE_P (type
)
3733 && type_internals_preclude_sra_p (type
, &msg
)))
3736 bitmap_set_bit (candidate_bitmap
, DECL_UID (parm
));
3737 slot
= candidates
.find_slot_with_hash (parm
, DECL_UID (parm
), INSERT
);
3741 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3743 fprintf (dump_file
, "Candidate (%d): ", DECL_UID (parm
));
3744 print_generic_expr (dump_file
, parm
, 0);
3745 fprintf (dump_file
, "\n");
3749 func_param_count
= count
;
3753 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
3757 mark_maybe_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef ATTRIBUTE_UNUSED
,
3760 struct access
*repr
= (struct access
*) data
;
3762 repr
->grp_maybe_modified
= 1;
3766 /* Analyze what representatives (in linked lists accessible from
3767 REPRESENTATIVES) can be modified by side effects of statements in the
3768 current function. */
3771 analyze_modified_params (vec
<access_p
> representatives
)
3775 for (i
= 0; i
< func_param_count
; i
++)
3777 struct access
*repr
;
3779 for (repr
= representatives
[i
];
3781 repr
= repr
->next_grp
)
3783 struct access
*access
;
3787 if (no_accesses_p (repr
))
3789 if (!POINTER_TYPE_P (TREE_TYPE (repr
->base
))
3790 || repr
->grp_maybe_modified
)
3793 ao_ref_init (&ar
, repr
->expr
);
3794 visited
= BITMAP_ALLOC (NULL
);
3795 for (access
= repr
; access
; access
= access
->next_sibling
)
3797 /* All accesses are read ones, otherwise grp_maybe_modified would
3798 be trivially set. */
3799 walk_aliased_vdefs (&ar
, gimple_vuse (access
->stmt
),
3800 mark_maybe_modified
, repr
, &visited
);
3801 if (repr
->grp_maybe_modified
)
3804 BITMAP_FREE (visited
);
3809 /* Propagate distances in bb_dereferences in the opposite direction than the
3810 control flow edges, in each step storing the maximum of the current value
3811 and the minimum of all successors. These steps are repeated until the table
3812 stabilizes. Note that BBs which might terminate the functions (according to
3813 final_bbs bitmap) never updated in this way. */
3816 propagate_dereference_distances (void)
3820 auto_vec
<basic_block
> queue (last_basic_block_for_fn (cfun
));
3821 queue
.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
3822 FOR_EACH_BB_FN (bb
, cfun
)
3824 queue
.quick_push (bb
);
3828 while (!queue
.is_empty ())
3832 bool change
= false;
3838 if (bitmap_bit_p (final_bbs
, bb
->index
))
3841 for (i
= 0; i
< func_param_count
; i
++)
3843 int idx
= bb
->index
* func_param_count
+ i
;
3845 HOST_WIDE_INT inh
= 0;
3847 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
3849 int succ_idx
= e
->dest
->index
* func_param_count
+ i
;
3851 if (e
->src
== EXIT_BLOCK_PTR_FOR_FN (cfun
))
3857 inh
= bb_dereferences
[succ_idx
];
3859 else if (bb_dereferences
[succ_idx
] < inh
)
3860 inh
= bb_dereferences
[succ_idx
];
3863 if (!first
&& bb_dereferences
[idx
] < inh
)
3865 bb_dereferences
[idx
] = inh
;
3870 if (change
&& !bitmap_bit_p (final_bbs
, bb
->index
))
3871 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
3876 e
->src
->aux
= e
->src
;
3877 queue
.quick_push (e
->src
);
3882 /* Dump a dereferences TABLE with heading STR to file F. */
3885 dump_dereferences_table (FILE *f
, const char *str
, HOST_WIDE_INT
*table
)
3889 fprintf (dump_file
, str
);
3890 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR_FOR_FN (cfun
),
3891 EXIT_BLOCK_PTR_FOR_FN (cfun
), next_bb
)
3893 fprintf (f
, "%4i %i ", bb
->index
, bitmap_bit_p (final_bbs
, bb
->index
));
3894 if (bb
!= EXIT_BLOCK_PTR_FOR_FN (cfun
))
3897 for (i
= 0; i
< func_param_count
; i
++)
3899 int idx
= bb
->index
* func_param_count
+ i
;
3900 fprintf (f
, " %4" HOST_WIDE_INT_PRINT
"d", table
[idx
]);
3905 fprintf (dump_file
, "\n");
3908 /* Determine what (parts of) parameters passed by reference that are not
3909 assigned to are not certainly dereferenced in this function and thus the
3910 dereferencing cannot be safely moved to the caller without potentially
3911 introducing a segfault. Mark such REPRESENTATIVES as
3912 grp_not_necessarilly_dereferenced.
3914 The dereferenced maximum "distance," i.e. the offset + size of the accessed
3915 part is calculated rather than simple booleans are calculated for each
3916 pointer parameter to handle cases when only a fraction of the whole
3917 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
3920 The maximum dereference distances for each pointer parameter and BB are
3921 already stored in bb_dereference. This routine simply propagates these
3922 values upwards by propagate_dereference_distances and then compares the
3923 distances of individual parameters in the ENTRY BB to the equivalent
3924 distances of each representative of a (fraction of a) parameter. */
3927 analyze_caller_dereference_legality (vec
<access_p
> representatives
)
3931 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3932 dump_dereferences_table (dump_file
,
3933 "Dereference table before propagation:\n",
3936 propagate_dereference_distances ();
3938 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3939 dump_dereferences_table (dump_file
,
3940 "Dereference table after propagation:\n",
3943 for (i
= 0; i
< func_param_count
; i
++)
3945 struct access
*repr
= representatives
[i
];
3946 int idx
= ENTRY_BLOCK_PTR_FOR_FN (cfun
)->index
* func_param_count
+ i
;
3948 if (!repr
|| no_accesses_p (repr
))
3953 if ((repr
->offset
+ repr
->size
) > bb_dereferences
[idx
])
3954 repr
->grp_not_necessarilly_dereferenced
= 1;
3955 repr
= repr
->next_grp
;
3961 /* Return the representative access for the parameter declaration PARM if it is
3962 a scalar passed by reference which is not written to and the pointer value
3963 is not used directly. Thus, if it is legal to dereference it in the caller
3964 and we can rule out modifications through aliases, such parameter should be
3965 turned into one passed by value. Return NULL otherwise. */
3967 static struct access
*
3968 unmodified_by_ref_scalar_representative (tree parm
)
3970 int i
, access_count
;
3971 struct access
*repr
;
3972 vec
<access_p
> *access_vec
;
3974 access_vec
= get_base_access_vector (parm
);
3975 gcc_assert (access_vec
);
3976 repr
= (*access_vec
)[0];
3979 repr
->group_representative
= repr
;
3981 access_count
= access_vec
->length ();
3982 for (i
= 1; i
< access_count
; i
++)
3984 struct access
*access
= (*access_vec
)[i
];
3987 access
->group_representative
= repr
;
3988 access
->next_sibling
= repr
->next_sibling
;
3989 repr
->next_sibling
= access
;
3993 repr
->grp_scalar_ptr
= 1;
3997 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
3998 associated with. REQ_ALIGN is the minimum required alignment. */
4001 access_precludes_ipa_sra_p (struct access
*access
, unsigned int req_align
)
4003 unsigned int exp_align
;
4004 /* Avoid issues such as the second simple testcase in PR 42025. The problem
4005 is incompatible assign in a call statement (and possibly even in asm
4006 statements). This can be relaxed by using a new temporary but only for
4007 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
4008 intraprocedural SRA we deal with this by keeping the old aggregate around,
4009 something we cannot do in IPA-SRA.) */
4011 && (is_gimple_call (access
->stmt
)
4012 || gimple_code (access
->stmt
) == GIMPLE_ASM
))
4015 exp_align
= get_object_alignment (access
->expr
);
4016 if (exp_align
< req_align
)
4023 /* Sort collected accesses for parameter PARM, identify representatives for
4024 each accessed region and link them together. Return NULL if there are
4025 different but overlapping accesses, return the special ptr value meaning
4026 there are no accesses for this parameter if that is the case and return the
4027 first representative otherwise. Set *RO_GRP if there is a group of accesses
4028 with only read (i.e. no write) accesses. */
4030 static struct access
*
4031 splice_param_accesses (tree parm
, bool *ro_grp
)
4033 int i
, j
, access_count
, group_count
;
4034 int agg_size
, total_size
= 0;
4035 struct access
*access
, *res
, **prev_acc_ptr
= &res
;
4036 vec
<access_p
> *access_vec
;
4038 access_vec
= get_base_access_vector (parm
);
4040 return &no_accesses_representant
;
4041 access_count
= access_vec
->length ();
4043 access_vec
->qsort (compare_access_positions
);
4048 while (i
< access_count
)
4052 access
= (*access_vec
)[i
];
4053 modification
= access
->write
;
4054 if (access_precludes_ipa_sra_p (access
, TYPE_ALIGN (access
->type
)))
4056 a1_alias_type
= reference_alias_ptr_type (access
->expr
);
4058 /* Access is about to become group representative unless we find some
4059 nasty overlap which would preclude us from breaking this parameter
4063 while (j
< access_count
)
4065 struct access
*ac2
= (*access_vec
)[j
];
4066 if (ac2
->offset
!= access
->offset
)
4068 /* All or nothing law for parameters. */
4069 if (access
->offset
+ access
->size
> ac2
->offset
)
4074 else if (ac2
->size
!= access
->size
)
4077 if (access_precludes_ipa_sra_p (ac2
, TYPE_ALIGN (access
->type
))
4078 || (ac2
->type
!= access
->type
4079 && (TREE_ADDRESSABLE (ac2
->type
)
4080 || TREE_ADDRESSABLE (access
->type
)))
4081 || (reference_alias_ptr_type (ac2
->expr
) != a1_alias_type
))
4084 modification
|= ac2
->write
;
4085 ac2
->group_representative
= access
;
4086 ac2
->next_sibling
= access
->next_sibling
;
4087 access
->next_sibling
= ac2
;
4092 access
->grp_maybe_modified
= modification
;
4095 *prev_acc_ptr
= access
;
4096 prev_acc_ptr
= &access
->next_grp
;
4097 total_size
+= access
->size
;
4101 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4102 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm
))));
4104 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm
)));
4105 if (total_size
>= agg_size
)
4108 gcc_assert (group_count
> 0);
4112 /* Decide whether parameters with representative accesses given by REPR should
4113 be reduced into components. */
4116 decide_one_param_reduction (struct access
*repr
)
4118 int total_size
, cur_parm_size
, agg_size
, new_param_count
, parm_size_limit
;
4123 cur_parm_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm
)));
4124 gcc_assert (cur_parm_size
> 0);
4126 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4129 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm
))));
4134 agg_size
= cur_parm_size
;
4140 fprintf (dump_file
, "Evaluating PARAM group sizes for ");
4141 print_generic_expr (dump_file
, parm
, 0);
4142 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (parm
));
4143 for (acc
= repr
; acc
; acc
= acc
->next_grp
)
4144 dump_access (dump_file
, acc
, true);
4148 new_param_count
= 0;
4150 for (; repr
; repr
= repr
->next_grp
)
4152 gcc_assert (parm
== repr
->base
);
4154 /* Taking the address of a non-addressable field is verboten. */
4155 if (by_ref
&& repr
->non_addressable
)
4158 /* Do not decompose a non-BLKmode param in a way that would
4159 create BLKmode params. Especially for by-reference passing
4160 (thus, pointer-type param) this is hardly worthwhile. */
4161 if (DECL_MODE (parm
) != BLKmode
4162 && TYPE_MODE (repr
->type
) == BLKmode
)
4165 if (!by_ref
|| (!repr
->grp_maybe_modified
4166 && !repr
->grp_not_necessarilly_dereferenced
))
4167 total_size
+= repr
->size
;
4169 total_size
+= cur_parm_size
;
4174 gcc_assert (new_param_count
> 0);
4176 if (optimize_function_for_size_p (cfun
))
4177 parm_size_limit
= cur_parm_size
;
4179 parm_size_limit
= (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR
)
4182 if (total_size
< agg_size
4183 && total_size
<= parm_size_limit
)
4186 fprintf (dump_file
, " ....will be split into %i components\n",
4188 return new_param_count
;
4194 /* The order of the following enums is important, we need to do extra work for
4195 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4196 enum ipa_splicing_result
{ NO_GOOD_ACCESS
, UNUSED_PARAMS
, BY_VAL_ACCESSES
,
4197 MODIF_BY_REF_ACCESSES
, UNMODIF_BY_REF_ACCESSES
};
4199 /* Identify representatives of all accesses to all candidate parameters for
4200 IPA-SRA. Return result based on what representatives have been found. */
4202 static enum ipa_splicing_result
4203 splice_all_param_accesses (vec
<access_p
> &representatives
)
4205 enum ipa_splicing_result result
= NO_GOOD_ACCESS
;
4207 struct access
*repr
;
4209 representatives
.create (func_param_count
);
4211 for (parm
= DECL_ARGUMENTS (current_function_decl
);
4213 parm
= DECL_CHAIN (parm
))
4215 if (is_unused_scalar_param (parm
))
4217 representatives
.quick_push (&no_accesses_representant
);
4218 if (result
== NO_GOOD_ACCESS
)
4219 result
= UNUSED_PARAMS
;
4221 else if (POINTER_TYPE_P (TREE_TYPE (parm
))
4222 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm
)))
4223 && bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
4225 repr
= unmodified_by_ref_scalar_representative (parm
);
4226 representatives
.quick_push (repr
);
4228 result
= UNMODIF_BY_REF_ACCESSES
;
4230 else if (bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
4232 bool ro_grp
= false;
4233 repr
= splice_param_accesses (parm
, &ro_grp
);
4234 representatives
.quick_push (repr
);
4236 if (repr
&& !no_accesses_p (repr
))
4238 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4241 result
= UNMODIF_BY_REF_ACCESSES
;
4242 else if (result
< MODIF_BY_REF_ACCESSES
)
4243 result
= MODIF_BY_REF_ACCESSES
;
4245 else if (result
< BY_VAL_ACCESSES
)
4246 result
= BY_VAL_ACCESSES
;
4248 else if (no_accesses_p (repr
) && (result
== NO_GOOD_ACCESS
))
4249 result
= UNUSED_PARAMS
;
4252 representatives
.quick_push (NULL
);
4255 if (result
== NO_GOOD_ACCESS
)
4257 representatives
.release ();
4258 return NO_GOOD_ACCESS
;
4264 /* Return the index of BASE in PARMS. Abort if it is not found. */
4267 get_param_index (tree base
, vec
<tree
> parms
)
4271 len
= parms
.length ();
4272 for (i
= 0; i
< len
; i
++)
4273 if (parms
[i
] == base
)
4278 /* Convert the decisions made at the representative level into compact
4279 parameter adjustments. REPRESENTATIVES are pointers to first
4280 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4281 final number of adjustments. */
4283 static ipa_parm_adjustment_vec
4284 turn_representatives_into_adjustments (vec
<access_p
> representatives
,
4285 int adjustments_count
)
4288 ipa_parm_adjustment_vec adjustments
;
4292 gcc_assert (adjustments_count
> 0);
4293 parms
= ipa_get_vector_of_formal_parms (current_function_decl
);
4294 adjustments
.create (adjustments_count
);
4295 parm
= DECL_ARGUMENTS (current_function_decl
);
4296 for (i
= 0; i
< func_param_count
; i
++, parm
= DECL_CHAIN (parm
))
4298 struct access
*repr
= representatives
[i
];
4300 if (!repr
|| no_accesses_p (repr
))
4302 struct ipa_parm_adjustment adj
;
4304 memset (&adj
, 0, sizeof (adj
));
4305 adj
.base_index
= get_param_index (parm
, parms
);
4308 adj
.op
= IPA_PARM_OP_COPY
;
4310 adj
.op
= IPA_PARM_OP_REMOVE
;
4311 adj
.arg_prefix
= "ISRA";
4312 adjustments
.quick_push (adj
);
4316 struct ipa_parm_adjustment adj
;
4317 int index
= get_param_index (parm
, parms
);
4319 for (; repr
; repr
= repr
->next_grp
)
4321 memset (&adj
, 0, sizeof (adj
));
4322 gcc_assert (repr
->base
== parm
);
4323 adj
.base_index
= index
;
4324 adj
.base
= repr
->base
;
4325 adj
.type
= repr
->type
;
4326 adj
.alias_ptr_type
= reference_alias_ptr_type (repr
->expr
);
4327 adj
.offset
= repr
->offset
;
4328 adj
.by_ref
= (POINTER_TYPE_P (TREE_TYPE (repr
->base
))
4329 && (repr
->grp_maybe_modified
4330 || repr
->grp_not_necessarilly_dereferenced
));
4331 adj
.arg_prefix
= "ISRA";
4332 adjustments
.quick_push (adj
);
4340 /* Analyze the collected accesses and produce a plan what to do with the
4341 parameters in the form of adjustments, NULL meaning nothing. */
4343 static ipa_parm_adjustment_vec
4344 analyze_all_param_acesses (void)
4346 enum ipa_splicing_result repr_state
;
4347 bool proceed
= false;
4348 int i
, adjustments_count
= 0;
4349 vec
<access_p
> representatives
;
4350 ipa_parm_adjustment_vec adjustments
;
4352 repr_state
= splice_all_param_accesses (representatives
);
4353 if (repr_state
== NO_GOOD_ACCESS
)
4354 return ipa_parm_adjustment_vec ();
4356 /* If there are any parameters passed by reference which are not modified
4357 directly, we need to check whether they can be modified indirectly. */
4358 if (repr_state
== UNMODIF_BY_REF_ACCESSES
)
4360 analyze_caller_dereference_legality (representatives
);
4361 analyze_modified_params (representatives
);
4364 for (i
= 0; i
< func_param_count
; i
++)
4366 struct access
*repr
= representatives
[i
];
4368 if (repr
&& !no_accesses_p (repr
))
4370 if (repr
->grp_scalar_ptr
)
4372 adjustments_count
++;
4373 if (repr
->grp_not_necessarilly_dereferenced
4374 || repr
->grp_maybe_modified
)
4375 representatives
[i
] = NULL
;
4379 sra_stats
.scalar_by_ref_to_by_val
++;
4384 int new_components
= decide_one_param_reduction (repr
);
4386 if (new_components
== 0)
4388 representatives
[i
] = NULL
;
4389 adjustments_count
++;
4393 adjustments_count
+= new_components
;
4394 sra_stats
.aggregate_params_reduced
++;
4395 sra_stats
.param_reductions_created
+= new_components
;
4402 if (no_accesses_p (repr
))
4405 sra_stats
.deleted_unused_parameters
++;
4407 adjustments_count
++;
4411 if (!proceed
&& dump_file
)
4412 fprintf (dump_file
, "NOT proceeding to change params.\n");
4415 adjustments
= turn_representatives_into_adjustments (representatives
,
4418 adjustments
= ipa_parm_adjustment_vec ();
4420 representatives
.release ();
4424 /* If a parameter replacement identified by ADJ does not yet exist in the form
4425 of declaration, create it and record it, otherwise return the previously
4429 get_replaced_param_substitute (struct ipa_parm_adjustment
*adj
)
4432 if (!adj
->new_ssa_base
)
4434 char *pretty_name
= make_fancy_name (adj
->base
);
4436 repl
= create_tmp_reg (TREE_TYPE (adj
->base
), "ISR");
4437 DECL_NAME (repl
) = get_identifier (pretty_name
);
4438 obstack_free (&name_obstack
, pretty_name
);
4440 adj
->new_ssa_base
= repl
;
4443 repl
= adj
->new_ssa_base
;
4447 /* Find the first adjustment for a particular parameter BASE in a vector of
4448 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4451 static struct ipa_parm_adjustment
*
4452 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments
, tree base
)
4456 len
= adjustments
.length ();
4457 for (i
= 0; i
< len
; i
++)
4459 struct ipa_parm_adjustment
*adj
;
4461 adj
= &adjustments
[i
];
4462 if (adj
->op
!= IPA_PARM_OP_COPY
&& adj
->base
== base
)
4469 /* If the statement STMT defines an SSA_NAME of a parameter which is to be
4470 removed because its value is not used, replace the SSA_NAME with a one
4471 relating to a created VAR_DECL together all of its uses and return true.
4472 ADJUSTMENTS is a pointer to an adjustments vector. */
4475 replace_removed_params_ssa_names (gimple stmt
,
4476 ipa_parm_adjustment_vec adjustments
)
4478 struct ipa_parm_adjustment
*adj
;
4479 tree lhs
, decl
, repl
, name
;
4481 if (gimple_code (stmt
) == GIMPLE_PHI
)
4482 lhs
= gimple_phi_result (stmt
);
4483 else if (is_gimple_assign (stmt
))
4484 lhs
= gimple_assign_lhs (stmt
);
4485 else if (is_gimple_call (stmt
))
4486 lhs
= gimple_call_lhs (stmt
);
4490 if (TREE_CODE (lhs
) != SSA_NAME
)
4493 decl
= SSA_NAME_VAR (lhs
);
4494 if (decl
== NULL_TREE
4495 || TREE_CODE (decl
) != PARM_DECL
)
4498 adj
= get_adjustment_for_base (adjustments
, decl
);
4502 repl
= get_replaced_param_substitute (adj
);
4503 name
= make_ssa_name (repl
, stmt
);
4507 fprintf (dump_file
, "replacing an SSA name of a removed param ");
4508 print_generic_expr (dump_file
, lhs
, 0);
4509 fprintf (dump_file
, " with ");
4510 print_generic_expr (dump_file
, name
, 0);
4511 fprintf (dump_file
, "\n");
4514 if (is_gimple_assign (stmt
))
4515 gimple_assign_set_lhs (stmt
, name
);
4516 else if (is_gimple_call (stmt
))
4517 gimple_call_set_lhs (stmt
, name
);
4519 gimple_phi_set_result (stmt
, name
);
4521 replace_uses_by (lhs
, name
);
4522 release_ssa_name (lhs
);
4526 /* If the statement pointed to by STMT_PTR contains any expressions that need
4527 to replaced with a different one as noted by ADJUSTMENTS, do so. Handle any
4528 potential type incompatibilities (GSI is used to accommodate conversion
4529 statements and must point to the statement). Return true iff the statement
4533 sra_ipa_modify_assign (gimple
*stmt_ptr
, gimple_stmt_iterator
*gsi
,
4534 ipa_parm_adjustment_vec adjustments
)
4536 gimple stmt
= *stmt_ptr
;
4537 tree
*lhs_p
, *rhs_p
;
4540 if (!gimple_assign_single_p (stmt
))
4543 rhs_p
= gimple_assign_rhs1_ptr (stmt
);
4544 lhs_p
= gimple_assign_lhs_ptr (stmt
);
4546 any
= ipa_modify_expr (rhs_p
, false, adjustments
);
4547 any
|= ipa_modify_expr (lhs_p
, false, adjustments
);
4550 tree new_rhs
= NULL_TREE
;
4552 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p
), TREE_TYPE (*rhs_p
)))
4554 if (TREE_CODE (*rhs_p
) == CONSTRUCTOR
)
4556 /* V_C_Es of constructors can cause trouble (PR 42714). */
4557 if (is_gimple_reg_type (TREE_TYPE (*lhs_p
)))
4558 *rhs_p
= build_zero_cst (TREE_TYPE (*lhs_p
));
4560 *rhs_p
= build_constructor (TREE_TYPE (*lhs_p
),
4564 new_rhs
= fold_build1_loc (gimple_location (stmt
),
4565 VIEW_CONVERT_EXPR
, TREE_TYPE (*lhs_p
),
4568 else if (REFERENCE_CLASS_P (*rhs_p
)
4569 && is_gimple_reg_type (TREE_TYPE (*lhs_p
))
4570 && !is_gimple_reg (*lhs_p
))
4571 /* This can happen when an assignment in between two single field
4572 structures is turned into an assignment in between two pointers to
4573 scalars (PR 42237). */
4578 tree tmp
= force_gimple_operand_gsi (gsi
, new_rhs
, true, NULL_TREE
,
4579 true, GSI_SAME_STMT
);
4581 gimple_assign_set_rhs_from_tree (gsi
, tmp
);
4590 /* Traverse the function body and all modifications as described in
4591 ADJUSTMENTS. Return true iff the CFG has been changed. */
4594 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments
)
4596 bool cfg_changed
= false;
4599 FOR_EACH_BB_FN (bb
, cfun
)
4601 gimple_stmt_iterator gsi
;
4603 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4604 replace_removed_params_ssa_names (gsi_stmt (gsi
), adjustments
);
4606 gsi
= gsi_start_bb (bb
);
4607 while (!gsi_end_p (gsi
))
4609 gimple stmt
= gsi_stmt (gsi
);
4610 bool modified
= false;
4614 switch (gimple_code (stmt
))
4617 t
= gimple_return_retval_ptr (stmt
);
4618 if (*t
!= NULL_TREE
)
4619 modified
|= ipa_modify_expr (t
, true, adjustments
);
4623 modified
|= sra_ipa_modify_assign (&stmt
, &gsi
, adjustments
);
4624 modified
|= replace_removed_params_ssa_names (stmt
, adjustments
);
4628 /* Operands must be processed before the lhs. */
4629 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
4631 t
= gimple_call_arg_ptr (stmt
, i
);
4632 modified
|= ipa_modify_expr (t
, true, adjustments
);
4635 if (gimple_call_lhs (stmt
))
4637 t
= gimple_call_lhs_ptr (stmt
);
4638 modified
|= ipa_modify_expr (t
, false, adjustments
);
4639 modified
|= replace_removed_params_ssa_names (stmt
,
4645 for (i
= 0; i
< gimple_asm_ninputs (stmt
); i
++)
4647 t
= &TREE_VALUE (gimple_asm_input_op (stmt
, i
));
4648 modified
|= ipa_modify_expr (t
, true, adjustments
);
4650 for (i
= 0; i
< gimple_asm_noutputs (stmt
); i
++)
4652 t
= &TREE_VALUE (gimple_asm_output_op (stmt
, i
));
4653 modified
|= ipa_modify_expr (t
, false, adjustments
);
4664 if (maybe_clean_eh_stmt (stmt
)
4665 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
4675 /* Call gimple_debug_bind_reset_value on all debug statements describing
4676 gimple register parameters that are being removed or replaced. */
4679 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments
)
4682 gimple_stmt_iterator
*gsip
= NULL
, gsi
;
4684 if (MAY_HAVE_DEBUG_STMTS
&& single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun
)))
4686 gsi
= gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun
)));
4689 len
= adjustments
.length ();
4690 for (i
= 0; i
< len
; i
++)
4692 struct ipa_parm_adjustment
*adj
;
4693 imm_use_iterator ui
;
4694 gimple stmt
, def_temp
;
4695 tree name
, vexpr
, copy
= NULL_TREE
;
4696 use_operand_p use_p
;
4698 adj
= &adjustments
[i
];
4699 if (adj
->op
== IPA_PARM_OP_COPY
|| !is_gimple_reg (adj
->base
))
4701 name
= ssa_default_def (cfun
, adj
->base
);
4704 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
4706 if (gimple_clobber_p (stmt
))
4708 gimple_stmt_iterator cgsi
= gsi_for_stmt (stmt
);
4709 unlink_stmt_vdef (stmt
);
4710 gsi_remove (&cgsi
, true);
4711 release_defs (stmt
);
4714 /* All other users must have been removed by
4715 ipa_sra_modify_function_body. */
4716 gcc_assert (is_gimple_debug (stmt
));
4717 if (vexpr
== NULL
&& gsip
!= NULL
)
4719 gcc_assert (TREE_CODE (adj
->base
) == PARM_DECL
);
4720 vexpr
= make_node (DEBUG_EXPR_DECL
);
4721 def_temp
= gimple_build_debug_source_bind (vexpr
, adj
->base
,
4723 DECL_ARTIFICIAL (vexpr
) = 1;
4724 TREE_TYPE (vexpr
) = TREE_TYPE (name
);
4725 DECL_MODE (vexpr
) = DECL_MODE (adj
->base
);
4726 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
4730 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
4731 SET_USE (use_p
, vexpr
);
4734 gimple_debug_bind_reset_value (stmt
);
4737 /* Create a VAR_DECL for debug info purposes. */
4738 if (!DECL_IGNORED_P (adj
->base
))
4740 copy
= build_decl (DECL_SOURCE_LOCATION (current_function_decl
),
4741 VAR_DECL
, DECL_NAME (adj
->base
),
4742 TREE_TYPE (adj
->base
));
4743 if (DECL_PT_UID_SET_P (adj
->base
))
4744 SET_DECL_PT_UID (copy
, DECL_PT_UID (adj
->base
));
4745 TREE_ADDRESSABLE (copy
) = TREE_ADDRESSABLE (adj
->base
);
4746 TREE_READONLY (copy
) = TREE_READONLY (adj
->base
);
4747 TREE_THIS_VOLATILE (copy
) = TREE_THIS_VOLATILE (adj
->base
);
4748 DECL_GIMPLE_REG_P (copy
) = DECL_GIMPLE_REG_P (adj
->base
);
4749 DECL_ARTIFICIAL (copy
) = DECL_ARTIFICIAL (adj
->base
);
4750 DECL_IGNORED_P (copy
) = DECL_IGNORED_P (adj
->base
);
4751 DECL_ABSTRACT_ORIGIN (copy
) = DECL_ORIGIN (adj
->base
);
4752 DECL_SEEN_IN_BIND_EXPR_P (copy
) = 1;
4753 SET_DECL_RTL (copy
, 0);
4754 TREE_USED (copy
) = 1;
4755 DECL_CONTEXT (copy
) = current_function_decl
;
4756 add_local_decl (cfun
, copy
);
4758 BLOCK_VARS (DECL_INITIAL (current_function_decl
));
4759 BLOCK_VARS (DECL_INITIAL (current_function_decl
)) = copy
;
4761 if (gsip
!= NULL
&& copy
&& target_for_debug_bind (adj
->base
))
4763 gcc_assert (TREE_CODE (adj
->base
) == PARM_DECL
);
4765 def_temp
= gimple_build_debug_bind (copy
, vexpr
, NULL
);
4767 def_temp
= gimple_build_debug_source_bind (copy
, adj
->base
,
4769 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
4774 /* Return false if all callers have at least as many actual arguments as there
4775 are formal parameters in the current function and that their types
4779 some_callers_have_mismatched_arguments_p (struct cgraph_node
*node
,
4780 void *data ATTRIBUTE_UNUSED
)
4782 struct cgraph_edge
*cs
;
4783 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4784 if (!callsite_arguments_match_p (cs
->call_stmt
))
4790 /* Convert all callers of NODE. */
4793 convert_callers_for_node (struct cgraph_node
*node
,
4796 ipa_parm_adjustment_vec
*adjustments
= (ipa_parm_adjustment_vec
*) data
;
4797 bitmap recomputed_callers
= BITMAP_ALLOC (NULL
);
4798 struct cgraph_edge
*cs
;
4800 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4802 push_cfun (DECL_STRUCT_FUNCTION (cs
->caller
->decl
));
4805 fprintf (dump_file
, "Adjusting call %s/%i -> %s/%i\n",
4806 xstrdup (cs
->caller
->name ()),
4808 xstrdup (cs
->callee
->name ()),
4812 ipa_modify_call_arguments (cs
, cs
->call_stmt
, *adjustments
);
4817 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4818 if (bitmap_set_bit (recomputed_callers
, cs
->caller
->uid
)
4819 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs
->caller
->decl
)))
4820 compute_inline_parameters (cs
->caller
, true);
4821 BITMAP_FREE (recomputed_callers
);
4826 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
4829 convert_callers (struct cgraph_node
*node
, tree old_decl
,
4830 ipa_parm_adjustment_vec adjustments
)
4832 basic_block this_block
;
4834 cgraph_for_node_and_aliases (node
, convert_callers_for_node
,
4835 &adjustments
, false);
4837 if (!encountered_recursive_call
)
4840 FOR_EACH_BB_FN (this_block
, cfun
)
4842 gimple_stmt_iterator gsi
;
4844 for (gsi
= gsi_start_bb (this_block
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4846 gimple stmt
= gsi_stmt (gsi
);
4848 if (gimple_code (stmt
) != GIMPLE_CALL
)
4850 call_fndecl
= gimple_call_fndecl (stmt
);
4851 if (call_fndecl
== old_decl
)
4854 fprintf (dump_file
, "Adjusting recursive call");
4855 gimple_call_set_fndecl (stmt
, node
->decl
);
4856 ipa_modify_call_arguments (NULL
, stmt
, adjustments
);
4864 /* Perform all the modification required in IPA-SRA for NODE to have parameters
4865 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
4868 modify_function (struct cgraph_node
*node
, ipa_parm_adjustment_vec adjustments
)
4870 struct cgraph_node
*new_node
;
4873 rebuild_cgraph_edges ();
4874 free_dominance_info (CDI_DOMINATORS
);
4877 /* This must be done after rebuilding cgraph edges for node above.
4878 Otherwise any recursive calls to node that are recorded in
4879 redirect_callers will be corrupted. */
4880 vec
<cgraph_edge_p
> redirect_callers
= collect_callers_of_node (node
);
4881 new_node
= cgraph_function_versioning (node
, redirect_callers
,
4883 NULL
, false, NULL
, NULL
, "isra");
4884 redirect_callers
.release ();
4886 push_cfun (DECL_STRUCT_FUNCTION (new_node
->decl
));
4887 ipa_modify_formal_parameters (current_function_decl
, adjustments
);
4888 cfg_changed
= ipa_sra_modify_function_body (adjustments
);
4889 sra_ipa_reset_debug_stmts (adjustments
);
4890 convert_callers (new_node
, node
->decl
, adjustments
);
4891 cgraph_make_node_local (new_node
);
4896 /* If NODE has a caller, return true. */
4899 has_caller_p (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
4906 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
4907 attributes, return true otherwise. NODE is the cgraph node of the current
4911 ipa_sra_preliminary_function_checks (struct cgraph_node
*node
)
4913 if (!cgraph_node_can_be_local_p (node
))
4916 fprintf (dump_file
, "Function not local to this compilation unit.\n");
4920 if (!node
->local
.can_change_signature
)
4923 fprintf (dump_file
, "Function can not change signature.\n");
4927 if (!tree_versionable_function_p (node
->decl
))
4930 fprintf (dump_file
, "Function is not versionable.\n");
4934 if (!opt_for_fn (node
->decl
, optimize
)
4935 || !opt_for_fn (node
->decl
, flag_ipa_sra
))
4938 fprintf (dump_file
, "Function not optimized.\n");
4942 if (DECL_VIRTUAL_P (current_function_decl
))
4945 fprintf (dump_file
, "Function is a virtual method.\n");
4949 if ((DECL_COMDAT (node
->decl
) || DECL_EXTERNAL (node
->decl
))
4950 && inline_summary (node
)->size
>= MAX_INLINE_INSNS_AUTO
)
4953 fprintf (dump_file
, "Function too big to be made truly local.\n");
4957 if (!cgraph_for_node_and_aliases (node
, has_caller_p
, NULL
, true))
4961 "Function has no callers in this compilation unit.\n");
4968 fprintf (dump_file
, "Function uses stdarg. \n");
4972 if (TYPE_ATTRIBUTES (TREE_TYPE (node
->decl
)))
4978 /* Perform early interprocedural SRA. */
4981 ipa_early_sra (void)
4983 struct cgraph_node
*node
= cgraph_get_node (current_function_decl
);
4984 ipa_parm_adjustment_vec adjustments
;
4987 if (!ipa_sra_preliminary_function_checks (node
))
4991 sra_mode
= SRA_MODE_EARLY_IPA
;
4993 if (!find_param_candidates ())
4996 fprintf (dump_file
, "Function has no IPA-SRA candidates.\n");
5000 if (cgraph_for_node_and_aliases (node
,
5001 some_callers_have_mismatched_arguments_p
,
5005 fprintf (dump_file
, "There are callers with insufficient number of "
5006 "arguments or arguments with type mismatches.\n");
5010 bb_dereferences
= XCNEWVEC (HOST_WIDE_INT
,
5012 * last_basic_block_for_fn (cfun
));
5013 final_bbs
= BITMAP_ALLOC (NULL
);
5016 if (encountered_apply_args
)
5019 fprintf (dump_file
, "Function calls __builtin_apply_args().\n");
5023 if (encountered_unchangable_recursive_call
)
5026 fprintf (dump_file
, "Function calls itself with insufficient "
5027 "number of arguments.\n");
5031 adjustments
= analyze_all_param_acesses ();
5032 if (!adjustments
.exists ())
5035 ipa_dump_param_adjustments (dump_file
, adjustments
, current_function_decl
);
5037 if (modify_function (node
, adjustments
))
5038 ret
= TODO_update_ssa
| TODO_cleanup_cfg
;
5040 ret
= TODO_update_ssa
;
5041 adjustments
.release ();
5043 statistics_counter_event (cfun
, "Unused parameters deleted",
5044 sra_stats
.deleted_unused_parameters
);
5045 statistics_counter_event (cfun
, "Scalar parameters converted to by-value",
5046 sra_stats
.scalar_by_ref_to_by_val
);
5047 statistics_counter_event (cfun
, "Aggregate parameters broken up",
5048 sra_stats
.aggregate_params_reduced
);
5049 statistics_counter_event (cfun
, "Aggregate parameter components created",
5050 sra_stats
.param_reductions_created
);
5053 BITMAP_FREE (final_bbs
);
5054 free (bb_dereferences
);
5056 sra_deinitialize ();
5060 /* Return if early ipa sra shall be performed. */
5062 ipa_early_sra_gate (void)
5064 return flag_ipa_sra
&& !flag_dyn_ipa
&& dbg_cnt (eipa_sra
);
5069 const pass_data pass_data_early_ipa_sra
=
5071 GIMPLE_PASS
, /* type */
5072 "eipa_sra", /* name */
5073 OPTGROUP_NONE
, /* optinfo_flags */
5074 true, /* has_gate */
5075 true, /* has_execute */
5076 TV_IPA_SRA
, /* tv_id */
5077 0, /* properties_required */
5078 0, /* properties_provided */
5079 0, /* properties_destroyed */
5080 0, /* todo_flags_start */
5081 TODO_dump_symtab
, /* todo_flags_finish */
5084 class pass_early_ipa_sra
: public gimple_opt_pass
5087 pass_early_ipa_sra (gcc::context
*ctxt
)
5088 : gimple_opt_pass (pass_data_early_ipa_sra
, ctxt
)
5091 /* opt_pass methods: */
5092 bool gate () { return ipa_early_sra_gate (); }
5093 unsigned int execute () { return ipa_early_sra (); }
5095 }; // class pass_early_ipa_sra
5100 make_pass_early_ipa_sra (gcc::context
*ctxt
)
5102 return new pass_early_ipa_sra (ctxt
);