1 /* Scalar Replacement of Aggregates (SRA) converts some structure
2 references into scalar references, exposing them to the scalar
4 Copyright (C) 2008-2013 Free Software Foundation, Inc.
5 Contributed by Martin Jambor <mjambor@suse.cz>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* This file implements Scalar Reduction of Aggregates (SRA). SRA is run
24 twice, once in the early stages of compilation (early SRA) and once in the
25 late stages (late SRA). The aim of both is to turn references to scalar
26 parts of aggregates into uses of independent scalar variables.
28 The two passes are nearly identical, the only difference is that early SRA
29 does not scalarize unions which are used as the result in a GIMPLE_RETURN
30 statement because together with inlining this can lead to weird type
33 Both passes operate in four stages:
35 1. The declarations that have properties which make them candidates for
36 scalarization are identified in function find_var_candidates(). The
37 candidates are stored in candidate_bitmap.
39 2. The function body is scanned. In the process, declarations which are
40 used in a manner that prevent their scalarization are removed from the
41 candidate bitmap. More importantly, for every access into an aggregate,
42 an access structure (struct access) is created by create_access() and
43 stored in a vector associated with the aggregate. Among other
44 information, the aggregate declaration, the offset and size of the access
45 and its type are stored in the structure.
47 On a related note, assign_link structures are created for every assign
48 statement between candidate aggregates and attached to the related
51 3. The vectors of accesses are analyzed. They are first sorted according to
52 their offset and size and then scanned for partially overlapping accesses
53 (i.e. those which overlap but one is not entirely within another). Such
54 an access disqualifies the whole aggregate from being scalarized.
56 If there is no such inhibiting overlap, a representative access structure
57 is chosen for every unique combination of offset and size. Afterwards,
58 the pass builds a set of trees from these structures, in which children
59 of an access are within their parent (in terms of offset and size).
61 Then accesses are propagated whenever possible (i.e. in cases when it
62 does not create a partially overlapping access) across assign_links from
63 the right hand side to the left hand side.
65 Then the set of trees for each declaration is traversed again and those
66 accesses which should be replaced by a scalar are identified.
68 4. The function is traversed again, and for every reference into an
69 aggregate that has some component which is about to be scalarized,
70 statements are amended and new statements are created as necessary.
71 Finally, if a parameter got scalarized, the scalar replacements are
72 initialized with values from respective parameter aggregates. */
76 #include "coretypes.h"
77 #include "hash-table.h"
78 #include "alloc-pool.h"
82 #include "gimple-iterator.h"
83 #include "gimple-walk.h"
85 #include "gimple-ssa.h"
87 #include "tree-phinodes.h"
88 #include "ssa-iterators.h"
89 #include "tree-ssanames.h"
92 #include "tree-pass.h"
94 #include "statistics.h"
99 #include "tree-inline.h"
100 #include "gimple-pretty-print.h"
101 #include "ipa-inline.h"
102 #include "ipa-utils.h"
104 /* Enumeration of all aggregate reductions we can do. */
105 enum sra_mode
{ SRA_MODE_EARLY_IPA
, /* early call regularization */
106 SRA_MODE_EARLY_INTRA
, /* early intraprocedural SRA */
107 SRA_MODE_INTRA
}; /* late intraprocedural SRA */
109 /* Global variable describing which aggregate reduction we are performing at
111 static enum sra_mode sra_mode
;
115 /* ACCESS represents each access to an aggregate variable (as a whole or a
116 part). It can also represent a group of accesses that refer to exactly the
117 same fragment of an aggregate (i.e. those that have exactly the same offset
118 and size). Such representatives for a single aggregate, once determined,
119 are linked in a linked list and have the group fields set.
121 Moreover, when doing intraprocedural SRA, a tree is built from those
122 representatives (by the means of first_child and next_sibling pointers), in
123 which all items in a subtree are "within" the root, i.e. their offset is
124 greater or equal to offset of the root and offset+size is smaller or equal
125 to offset+size of the root. Children of an access are sorted by offset.
127 Note that accesses to parts of vector and complex number types always
128 represented by an access to the whole complex number or a vector. It is a
129 duty of the modifying functions to replace them appropriately. */
133 /* Values returned by `get_ref_base_and_extent' for each component reference
134 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
135 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
136 HOST_WIDE_INT offset
;
140 /* Expression. It is context dependent so do not use it to create new
141 expressions to access the original aggregate. See PR 42154 for a
147 /* The statement this access belongs to. */
150 /* Next group representative for this aggregate. */
151 struct access
*next_grp
;
153 /* Pointer to the group representative. Pointer to itself if the struct is
154 the representative. */
155 struct access
*group_representative
;
157 /* If this access has any children (in terms of the definition above), this
158 points to the first one. */
159 struct access
*first_child
;
161 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
162 described above. In IPA-SRA this is a pointer to the next access
163 belonging to the same group (having the same representative). */
164 struct access
*next_sibling
;
166 /* Pointers to the first and last element in the linked list of assign
168 struct assign_link
*first_link
, *last_link
;
170 /* Pointer to the next access in the work queue. */
171 struct access
*next_queued
;
173 /* Replacement variable for this access "region." Never to be accessed
174 directly, always only by the means of get_access_replacement() and only
175 when grp_to_be_replaced flag is set. */
176 tree replacement_decl
;
178 /* Is this particular access write access? */
181 /* Is this access an access to a non-addressable field? */
182 unsigned non_addressable
: 1;
184 /* Is this access currently in the work queue? */
185 unsigned grp_queued
: 1;
187 /* Does this group contain a write access? This flag is propagated down the
189 unsigned grp_write
: 1;
191 /* Does this group contain a read access? This flag is propagated down the
193 unsigned grp_read
: 1;
195 /* Does this group contain a read access that comes from an assignment
196 statement? This flag is propagated down the access tree. */
197 unsigned grp_assignment_read
: 1;
199 /* Does this group contain a write access that comes from an assignment
200 statement? This flag is propagated down the access tree. */
201 unsigned grp_assignment_write
: 1;
203 /* Does this group contain a read access through a scalar type? This flag is
204 not propagated in the access tree in any direction. */
205 unsigned grp_scalar_read
: 1;
207 /* Does this group contain a write access through a scalar type? This flag
208 is not propagated in the access tree in any direction. */
209 unsigned grp_scalar_write
: 1;
211 /* Is this access an artificial one created to scalarize some record
213 unsigned grp_total_scalarization
: 1;
215 /* Other passes of the analysis use this bit to make function
216 analyze_access_subtree create scalar replacements for this group if
218 unsigned grp_hint
: 1;
220 /* Is the subtree rooted in this access fully covered by scalar
222 unsigned grp_covered
: 1;
224 /* If set to true, this access and all below it in an access tree must not be
226 unsigned grp_unscalarizable_region
: 1;
228 /* Whether data have been written to parts of the aggregate covered by this
229 access which is not to be scalarized. This flag is propagated up in the
231 unsigned grp_unscalarized_data
: 1;
233 /* Does this access and/or group contain a write access through a
235 unsigned grp_partial_lhs
: 1;
237 /* Set when a scalar replacement should be created for this variable. */
238 unsigned grp_to_be_replaced
: 1;
240 /* Set when we want a replacement for the sole purpose of having it in
241 generated debug statements. */
242 unsigned grp_to_be_debug_replaced
: 1;
244 /* Should TREE_NO_WARNING of a replacement be set? */
245 unsigned grp_no_warning
: 1;
247 /* Is it possible that the group refers to data which might be (directly or
248 otherwise) modified? */
249 unsigned grp_maybe_modified
: 1;
251 /* Set when this is a representative of a pointer to scalar (i.e. by
252 reference) parameter which we consider for turning into a plain scalar
253 (i.e. a by value parameter). */
254 unsigned grp_scalar_ptr
: 1;
256 /* Set when we discover that this pointer is not safe to dereference in the
258 unsigned grp_not_necessarilly_dereferenced
: 1;
261 typedef struct access
*access_p
;
264 /* Alloc pool for allocating access structures. */
265 static alloc_pool access_pool
;
267 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
268 are used to propagate subaccesses from rhs to lhs as long as they don't
269 conflict with what is already there. */
272 struct access
*lacc
, *racc
;
273 struct assign_link
*next
;
276 /* Alloc pool for allocating assign link structures. */
277 static alloc_pool link_pool
;
279 /* Base (tree) -> Vector (vec<access_p> *) map. */
280 static struct pointer_map_t
*base_access_vec
;
282 /* Candidate hash table helpers. */
284 struct uid_decl_hasher
: typed_noop_remove
<tree_node
>
286 typedef tree_node value_type
;
287 typedef tree_node compare_type
;
288 static inline hashval_t
hash (const value_type
*);
289 static inline bool equal (const value_type
*, const compare_type
*);
292 /* Hash a tree in a uid_decl_map. */
295 uid_decl_hasher::hash (const value_type
*item
)
297 return item
->decl_minimal
.uid
;
300 /* Return true if the DECL_UID in both trees are equal. */
303 uid_decl_hasher::equal (const value_type
*a
, const compare_type
*b
)
305 return (a
->decl_minimal
.uid
== b
->decl_minimal
.uid
);
308 /* Set of candidates. */
309 static bitmap candidate_bitmap
;
310 static hash_table
<uid_decl_hasher
> candidates
;
312 /* For a candidate UID return the candidates decl. */
315 candidate (unsigned uid
)
318 t
.decl_minimal
.uid
= uid
;
319 return candidates
.find_with_hash (&t
, static_cast <hashval_t
> (uid
));
322 /* Bitmap of candidates which we should try to entirely scalarize away and
323 those which cannot be (because they are and need be used as a whole). */
324 static bitmap should_scalarize_away_bitmap
, cannot_scalarize_away_bitmap
;
326 /* Obstack for creation of fancy names. */
327 static struct obstack name_obstack
;
329 /* Head of a linked list of accesses that need to have its subaccesses
330 propagated to their assignment counterparts. */
331 static struct access
*work_queue_head
;
333 /* Number of parameters of the analyzed function when doing early ipa SRA. */
334 static int func_param_count
;
336 /* scan_function sets the following to true if it encounters a call to
337 __builtin_apply_args. */
338 static bool encountered_apply_args
;
340 /* Set by scan_function when it finds a recursive call. */
341 static bool encountered_recursive_call
;
343 /* Set by scan_function when it finds a recursive call with less actual
344 arguments than formal parameters.. */
345 static bool encountered_unchangable_recursive_call
;
347 /* This is a table in which for each basic block and parameter there is a
348 distance (offset + size) in that parameter which is dereferenced and
349 accessed in that BB. */
350 static HOST_WIDE_INT
*bb_dereferences
;
351 /* Bitmap of BBs that can cause the function to "stop" progressing by
352 returning, throwing externally, looping infinitely or calling a function
353 which might abort etc.. */
354 static bitmap final_bbs
;
356 /* Representative of no accesses at all. */
357 static struct access no_accesses_representant
;
359 /* Predicate to test the special value. */
362 no_accesses_p (struct access
*access
)
364 return access
== &no_accesses_representant
;
367 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
368 representative fields are dumped, otherwise those which only describe the
369 individual access are. */
373 /* Number of processed aggregates is readily available in
374 analyze_all_variable_accesses and so is not stored here. */
376 /* Number of created scalar replacements. */
379 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
383 /* Number of statements created by generate_subtree_copies. */
386 /* Number of statements created by load_assign_lhs_subreplacements. */
389 /* Number of times sra_modify_assign has deleted a statement. */
392 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
393 RHS reparately due to type conversions or nonexistent matching
395 int separate_lhs_rhs_handling
;
397 /* Number of parameters that were removed because they were unused. */
398 int deleted_unused_parameters
;
400 /* Number of scalars passed as parameters by reference that have been
401 converted to be passed by value. */
402 int scalar_by_ref_to_by_val
;
404 /* Number of aggregate parameters that were replaced by one or more of their
406 int aggregate_params_reduced
;
408 /* Numbber of components created when splitting aggregate parameters. */
409 int param_reductions_created
;
413 dump_access (FILE *f
, struct access
*access
, bool grp
)
415 fprintf (f
, "access { ");
416 fprintf (f
, "base = (%d)'", DECL_UID (access
->base
));
417 print_generic_expr (f
, access
->base
, 0);
418 fprintf (f
, "', offset = " HOST_WIDE_INT_PRINT_DEC
, access
->offset
);
419 fprintf (f
, ", size = " HOST_WIDE_INT_PRINT_DEC
, access
->size
);
420 fprintf (f
, ", expr = ");
421 print_generic_expr (f
, access
->expr
, 0);
422 fprintf (f
, ", type = ");
423 print_generic_expr (f
, access
->type
, 0);
425 fprintf (f
, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
426 "grp_assignment_write = %d, grp_scalar_read = %d, "
427 "grp_scalar_write = %d, grp_total_scalarization = %d, "
428 "grp_hint = %d, grp_covered = %d, "
429 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
430 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
431 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
432 "grp_not_necessarilly_dereferenced = %d\n",
433 access
->grp_read
, access
->grp_write
, access
->grp_assignment_read
,
434 access
->grp_assignment_write
, access
->grp_scalar_read
,
435 access
->grp_scalar_write
, access
->grp_total_scalarization
,
436 access
->grp_hint
, access
->grp_covered
,
437 access
->grp_unscalarizable_region
, access
->grp_unscalarized_data
,
438 access
->grp_partial_lhs
, access
->grp_to_be_replaced
,
439 access
->grp_to_be_debug_replaced
, access
->grp_maybe_modified
,
440 access
->grp_not_necessarilly_dereferenced
);
442 fprintf (f
, ", write = %d, grp_total_scalarization = %d, "
443 "grp_partial_lhs = %d\n",
444 access
->write
, access
->grp_total_scalarization
,
445 access
->grp_partial_lhs
);
448 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
451 dump_access_tree_1 (FILE *f
, struct access
*access
, int level
)
457 for (i
= 0; i
< level
; i
++)
458 fputs ("* ", dump_file
);
460 dump_access (f
, access
, true);
462 if (access
->first_child
)
463 dump_access_tree_1 (f
, access
->first_child
, level
+ 1);
465 access
= access
->next_sibling
;
470 /* Dump all access trees for a variable, given the pointer to the first root in
474 dump_access_tree (FILE *f
, struct access
*access
)
476 for (; access
; access
= access
->next_grp
)
477 dump_access_tree_1 (f
, access
, 0);
480 /* Return true iff ACC is non-NULL and has subaccesses. */
483 access_has_children_p (struct access
*acc
)
485 return acc
&& acc
->first_child
;
488 /* Return true iff ACC is (partly) covered by at least one replacement. */
491 access_has_replacements_p (struct access
*acc
)
493 struct access
*child
;
494 if (acc
->grp_to_be_replaced
)
496 for (child
= acc
->first_child
; child
; child
= child
->next_sibling
)
497 if (access_has_replacements_p (child
))
502 /* Return a vector of pointers to accesses for the variable given in BASE or
503 NULL if there is none. */
505 static vec
<access_p
> *
506 get_base_access_vector (tree base
)
510 slot
= pointer_map_contains (base_access_vec
, base
);
514 return *(vec
<access_p
> **) slot
;
517 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
518 in ACCESS. Return NULL if it cannot be found. */
520 static struct access
*
521 find_access_in_subtree (struct access
*access
, HOST_WIDE_INT offset
,
524 while (access
&& (access
->offset
!= offset
|| access
->size
!= size
))
526 struct access
*child
= access
->first_child
;
528 while (child
&& (child
->offset
+ child
->size
<= offset
))
529 child
= child
->next_sibling
;
536 /* Return the first group representative for DECL or NULL if none exists. */
538 static struct access
*
539 get_first_repr_for_decl (tree base
)
541 vec
<access_p
> *access_vec
;
543 access_vec
= get_base_access_vector (base
);
547 return (*access_vec
)[0];
550 /* Find an access representative for the variable BASE and given OFFSET and
551 SIZE. Requires that access trees have already been built. Return NULL if
552 it cannot be found. */
554 static struct access
*
555 get_var_base_offset_size_access (tree base
, HOST_WIDE_INT offset
,
558 struct access
*access
;
560 access
= get_first_repr_for_decl (base
);
561 while (access
&& (access
->offset
+ access
->size
<= offset
))
562 access
= access
->next_grp
;
566 return find_access_in_subtree (access
, offset
, size
);
569 /* Add LINK to the linked list of assign links of RACC. */
571 add_link_to_rhs (struct access
*racc
, struct assign_link
*link
)
573 gcc_assert (link
->racc
== racc
);
575 if (!racc
->first_link
)
577 gcc_assert (!racc
->last_link
);
578 racc
->first_link
= link
;
581 racc
->last_link
->next
= link
;
583 racc
->last_link
= link
;
587 /* Move all link structures in their linked list in OLD_RACC to the linked list
590 relink_to_new_repr (struct access
*new_racc
, struct access
*old_racc
)
592 if (!old_racc
->first_link
)
594 gcc_assert (!old_racc
->last_link
);
598 if (new_racc
->first_link
)
600 gcc_assert (!new_racc
->last_link
->next
);
601 gcc_assert (!old_racc
->last_link
|| !old_racc
->last_link
->next
);
603 new_racc
->last_link
->next
= old_racc
->first_link
;
604 new_racc
->last_link
= old_racc
->last_link
;
608 gcc_assert (!new_racc
->last_link
);
610 new_racc
->first_link
= old_racc
->first_link
;
611 new_racc
->last_link
= old_racc
->last_link
;
613 old_racc
->first_link
= old_racc
->last_link
= NULL
;
616 /* Add ACCESS to the work queue (which is actually a stack). */
619 add_access_to_work_queue (struct access
*access
)
621 if (!access
->grp_queued
)
623 gcc_assert (!access
->next_queued
);
624 access
->next_queued
= work_queue_head
;
625 access
->grp_queued
= 1;
626 work_queue_head
= access
;
630 /* Pop an access from the work queue, and return it, assuming there is one. */
632 static struct access
*
633 pop_access_from_work_queue (void)
635 struct access
*access
= work_queue_head
;
637 work_queue_head
= access
->next_queued
;
638 access
->next_queued
= NULL
;
639 access
->grp_queued
= 0;
644 /* Allocate necessary structures. */
647 sra_initialize (void)
649 candidate_bitmap
= BITMAP_ALLOC (NULL
);
650 candidates
.create (vec_safe_length (cfun
->local_decls
) / 2);
651 should_scalarize_away_bitmap
= BITMAP_ALLOC (NULL
);
652 cannot_scalarize_away_bitmap
= BITMAP_ALLOC (NULL
);
653 gcc_obstack_init (&name_obstack
);
654 access_pool
= create_alloc_pool ("SRA accesses", sizeof (struct access
), 16);
655 link_pool
= create_alloc_pool ("SRA links", sizeof (struct assign_link
), 16);
656 base_access_vec
= pointer_map_create ();
657 memset (&sra_stats
, 0, sizeof (sra_stats
));
658 encountered_apply_args
= false;
659 encountered_recursive_call
= false;
660 encountered_unchangable_recursive_call
= false;
663 /* Hook fed to pointer_map_traverse, deallocate stored vectors. */
666 delete_base_accesses (const void *key ATTRIBUTE_UNUSED
, void **value
,
667 void *data ATTRIBUTE_UNUSED
)
669 vec
<access_p
> *access_vec
= (vec
<access_p
> *) *value
;
670 vec_free (access_vec
);
674 /* Deallocate all general structures. */
677 sra_deinitialize (void)
679 BITMAP_FREE (candidate_bitmap
);
680 candidates
.dispose ();
681 BITMAP_FREE (should_scalarize_away_bitmap
);
682 BITMAP_FREE (cannot_scalarize_away_bitmap
);
683 free_alloc_pool (access_pool
);
684 free_alloc_pool (link_pool
);
685 obstack_free (&name_obstack
, NULL
);
687 pointer_map_traverse (base_access_vec
, delete_base_accesses
, NULL
);
688 pointer_map_destroy (base_access_vec
);
691 /* Remove DECL from candidates for SRA and write REASON to the dump file if
694 disqualify_candidate (tree decl
, const char *reason
)
696 if (bitmap_clear_bit (candidate_bitmap
, DECL_UID (decl
)))
697 candidates
.clear_slot (candidates
.find_slot_with_hash (decl
,
701 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
703 fprintf (dump_file
, "! Disqualifying ");
704 print_generic_expr (dump_file
, decl
, 0);
705 fprintf (dump_file
, " - %s\n", reason
);
709 /* Return true iff the type contains a field or an element which does not allow
713 type_internals_preclude_sra_p (tree type
, const char **msg
)
718 switch (TREE_CODE (type
))
722 case QUAL_UNION_TYPE
:
723 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
724 if (TREE_CODE (fld
) == FIELD_DECL
)
726 tree ft
= TREE_TYPE (fld
);
728 if (TREE_THIS_VOLATILE (fld
))
730 *msg
= "volatile structure field";
733 if (!DECL_FIELD_OFFSET (fld
))
735 *msg
= "no structure field offset";
738 if (!DECL_SIZE (fld
))
740 *msg
= "zero structure field size";
743 if (!host_integerp (DECL_FIELD_OFFSET (fld
), 1))
745 *msg
= "structure field offset not fixed";
748 if (!host_integerp (DECL_SIZE (fld
), 1))
750 *msg
= "structure field size not fixed";
753 if (!host_integerp (bit_position (fld
), 0))
755 *msg
= "structure field size too big";
758 if (AGGREGATE_TYPE_P (ft
)
759 && int_bit_position (fld
) % BITS_PER_UNIT
!= 0)
761 *msg
= "structure field is bit field";
765 if (AGGREGATE_TYPE_P (ft
) && type_internals_preclude_sra_p (ft
, msg
))
772 et
= TREE_TYPE (type
);
774 if (TYPE_VOLATILE (et
))
776 *msg
= "element type is volatile";
780 if (AGGREGATE_TYPE_P (et
) && type_internals_preclude_sra_p (et
, msg
))
790 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
791 base variable if it is. Return T if it is not an SSA_NAME. */
794 get_ssa_base_param (tree t
)
796 if (TREE_CODE (t
) == SSA_NAME
)
798 if (SSA_NAME_IS_DEFAULT_DEF (t
))
799 return SSA_NAME_VAR (t
);
806 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
807 belongs to, unless the BB has already been marked as a potentially
811 mark_parm_dereference (tree base
, HOST_WIDE_INT dist
, gimple stmt
)
813 basic_block bb
= gimple_bb (stmt
);
814 int idx
, parm_index
= 0;
817 if (bitmap_bit_p (final_bbs
, bb
->index
))
820 for (parm
= DECL_ARGUMENTS (current_function_decl
);
821 parm
&& parm
!= base
;
822 parm
= DECL_CHAIN (parm
))
825 gcc_assert (parm_index
< func_param_count
);
827 idx
= bb
->index
* func_param_count
+ parm_index
;
828 if (bb_dereferences
[idx
] < dist
)
829 bb_dereferences
[idx
] = dist
;
832 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
833 the three fields. Also add it to the vector of accesses corresponding to
834 the base. Finally, return the new access. */
836 static struct access
*
837 create_access_1 (tree base
, HOST_WIDE_INT offset
, HOST_WIDE_INT size
)
840 struct access
*access
;
843 access
= (struct access
*) pool_alloc (access_pool
);
844 memset (access
, 0, sizeof (struct access
));
846 access
->offset
= offset
;
849 slot
= pointer_map_contains (base_access_vec
, base
);
851 v
= (vec
<access_p
> *) *slot
;
855 v
->safe_push (access
);
858 pointer_map_insert (base_access_vec
, base
)) = v
;
863 /* Create and insert access for EXPR. Return created access, or NULL if it is
866 static struct access
*
867 create_access (tree expr
, gimple stmt
, bool write
)
869 struct access
*access
;
870 HOST_WIDE_INT offset
, size
, max_size
;
872 bool ptr
, unscalarizable_region
= false;
874 base
= get_ref_base_and_extent (expr
, &offset
, &size
, &max_size
);
876 if (sra_mode
== SRA_MODE_EARLY_IPA
877 && TREE_CODE (base
) == MEM_REF
)
879 base
= get_ssa_base_param (TREE_OPERAND (base
, 0));
887 if (!DECL_P (base
) || !bitmap_bit_p (candidate_bitmap
, DECL_UID (base
)))
890 if (sra_mode
== SRA_MODE_EARLY_IPA
)
892 if (size
< 0 || size
!= max_size
)
894 disqualify_candidate (base
, "Encountered a variable sized access.");
897 if (TREE_CODE (expr
) == COMPONENT_REF
898 && DECL_BIT_FIELD (TREE_OPERAND (expr
, 1)))
900 disqualify_candidate (base
, "Encountered a bit-field access.");
903 gcc_checking_assert ((offset
% BITS_PER_UNIT
) == 0);
906 mark_parm_dereference (base
, offset
+ size
, stmt
);
910 if (size
!= max_size
)
913 unscalarizable_region
= true;
917 disqualify_candidate (base
, "Encountered an unconstrained access.");
922 access
= create_access_1 (base
, offset
, size
);
924 access
->type
= TREE_TYPE (expr
);
925 access
->write
= write
;
926 access
->grp_unscalarizable_region
= unscalarizable_region
;
929 if (TREE_CODE (expr
) == COMPONENT_REF
930 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr
, 1)))
931 access
->non_addressable
= 1;
937 /* Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple
938 register types or (recursively) records with only these two kinds of fields.
939 It also returns false if any of these records contains a bit-field. */
942 type_consists_of_records_p (tree type
)
946 if (TREE_CODE (type
) != RECORD_TYPE
)
949 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
950 if (TREE_CODE (fld
) == FIELD_DECL
)
952 tree ft
= TREE_TYPE (fld
);
954 if (DECL_BIT_FIELD (fld
))
957 if (!is_gimple_reg_type (ft
)
958 && !type_consists_of_records_p (ft
))
965 /* Create total_scalarization accesses for all scalar type fields in DECL that
966 must be of a RECORD_TYPE conforming to type_consists_of_records_p. BASE
967 must be the top-most VAR_DECL representing the variable, OFFSET must be the
968 offset of DECL within BASE. REF must be the memory reference expression for
972 completely_scalarize_record (tree base
, tree decl
, HOST_WIDE_INT offset
,
975 tree fld
, decl_type
= TREE_TYPE (decl
);
977 for (fld
= TYPE_FIELDS (decl_type
); fld
; fld
= DECL_CHAIN (fld
))
978 if (TREE_CODE (fld
) == FIELD_DECL
)
980 HOST_WIDE_INT pos
= offset
+ int_bit_position (fld
);
981 tree ft
= TREE_TYPE (fld
);
982 tree nref
= build3 (COMPONENT_REF
, TREE_TYPE (fld
), ref
, fld
,
985 if (is_gimple_reg_type (ft
))
987 struct access
*access
;
990 size
= tree_low_cst (DECL_SIZE (fld
), 1);
991 access
= create_access_1 (base
, pos
, size
);
994 access
->grp_total_scalarization
= 1;
995 /* Accesses for intraprocedural SRA can have their stmt NULL. */
998 completely_scalarize_record (base
, fld
, pos
, nref
);
1002 /* Create total_scalarization accesses for all scalar type fields in VAR and
1003 for VAR a a whole. VAR must be of a RECORD_TYPE conforming to
1004 type_consists_of_records_p. */
1007 completely_scalarize_var (tree var
)
1009 HOST_WIDE_INT size
= tree_low_cst (DECL_SIZE (var
), 1);
1010 struct access
*access
;
1012 access
= create_access_1 (var
, 0, size
);
1014 access
->type
= TREE_TYPE (var
);
1015 access
->grp_total_scalarization
= 1;
1017 completely_scalarize_record (var
, var
, 0, var
);
1020 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1023 contains_view_convert_expr_p (const_tree ref
)
1025 while (handled_component_p (ref
))
1027 if (TREE_CODE (ref
) == VIEW_CONVERT_EXPR
)
1029 ref
= TREE_OPERAND (ref
, 0);
1035 /* Search the given tree for a declaration by skipping handled components and
1036 exclude it from the candidates. */
1039 disqualify_base_of_expr (tree t
, const char *reason
)
1041 t
= get_base_address (t
);
1042 if (sra_mode
== SRA_MODE_EARLY_IPA
1043 && TREE_CODE (t
) == MEM_REF
)
1044 t
= get_ssa_base_param (TREE_OPERAND (t
, 0));
1046 if (t
&& DECL_P (t
))
1047 disqualify_candidate (t
, reason
);
1050 /* Scan expression EXPR and create access structures for all accesses to
1051 candidates for scalarization. Return the created access or NULL if none is
1054 static struct access
*
1055 build_access_from_expr_1 (tree expr
, gimple stmt
, bool write
)
1057 struct access
*ret
= NULL
;
1060 if (TREE_CODE (expr
) == BIT_FIELD_REF
1061 || TREE_CODE (expr
) == IMAGPART_EXPR
1062 || TREE_CODE (expr
) == REALPART_EXPR
)
1064 expr
= TREE_OPERAND (expr
, 0);
1068 partial_ref
= false;
1070 /* We need to dive through V_C_Es in order to get the size of its parameter
1071 and not the result type. Ada produces such statements. We are also
1072 capable of handling the topmost V_C_E but not any of those buried in other
1073 handled components. */
1074 if (TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
1075 expr
= TREE_OPERAND (expr
, 0);
1077 if (contains_view_convert_expr_p (expr
))
1079 disqualify_base_of_expr (expr
, "V_C_E under a different handled "
1084 switch (TREE_CODE (expr
))
1087 if (TREE_CODE (TREE_OPERAND (expr
, 0)) != ADDR_EXPR
1088 && sra_mode
!= SRA_MODE_EARLY_IPA
)
1096 case ARRAY_RANGE_REF
:
1097 ret
= create_access (expr
, stmt
, write
);
1104 if (write
&& partial_ref
&& ret
)
1105 ret
->grp_partial_lhs
= 1;
1110 /* Scan expression EXPR and create access structures for all accesses to
1111 candidates for scalarization. Return true if any access has been inserted.
1112 STMT must be the statement from which the expression is taken, WRITE must be
1113 true if the expression is a store and false otherwise. */
1116 build_access_from_expr (tree expr
, gimple stmt
, bool write
)
1118 struct access
*access
;
1120 access
= build_access_from_expr_1 (expr
, stmt
, write
);
1123 /* This means the aggregate is accesses as a whole in a way other than an
1124 assign statement and thus cannot be removed even if we had a scalar
1125 replacement for everything. */
1126 if (cannot_scalarize_away_bitmap
)
1127 bitmap_set_bit (cannot_scalarize_away_bitmap
, DECL_UID (access
->base
));
1133 /* Disqualify LHS and RHS for scalarization if STMT must end its basic block in
1134 modes in which it matters, return true iff they have been disqualified. RHS
1135 may be NULL, in that case ignore it. If we scalarize an aggregate in
1136 intra-SRA we may need to add statements after each statement. This is not
1137 possible if a statement unconditionally has to end the basic block. */
1139 disqualify_ops_if_throwing_stmt (gimple stmt
, tree lhs
, tree rhs
)
1141 if ((sra_mode
== SRA_MODE_EARLY_INTRA
|| sra_mode
== SRA_MODE_INTRA
)
1142 && (stmt_can_throw_internal (stmt
) || stmt_ends_bb_p (stmt
)))
1144 disqualify_base_of_expr (lhs
, "LHS of a throwing stmt.");
1146 disqualify_base_of_expr (rhs
, "RHS of a throwing stmt.");
1152 /* Scan expressions occurring in STMT, create access structures for all accesses
1153 to candidates for scalarization and remove those candidates which occur in
1154 statements or expressions that prevent them from being split apart. Return
1155 true if any access has been inserted. */
1158 build_accesses_from_assign (gimple stmt
)
1161 struct access
*lacc
, *racc
;
1163 if (!gimple_assign_single_p (stmt
)
1164 /* Scope clobbers don't influence scalarization. */
1165 || gimple_clobber_p (stmt
))
1168 lhs
= gimple_assign_lhs (stmt
);
1169 rhs
= gimple_assign_rhs1 (stmt
);
1171 if (disqualify_ops_if_throwing_stmt (stmt
, lhs
, rhs
))
1174 racc
= build_access_from_expr_1 (rhs
, stmt
, false);
1175 lacc
= build_access_from_expr_1 (lhs
, stmt
, true);
1178 lacc
->grp_assignment_write
= 1;
1182 racc
->grp_assignment_read
= 1;
1183 if (should_scalarize_away_bitmap
&& !gimple_has_volatile_ops (stmt
)
1184 && !is_gimple_reg_type (racc
->type
))
1185 bitmap_set_bit (should_scalarize_away_bitmap
, DECL_UID (racc
->base
));
1189 && (sra_mode
== SRA_MODE_EARLY_INTRA
|| sra_mode
== SRA_MODE_INTRA
)
1190 && !lacc
->grp_unscalarizable_region
1191 && !racc
->grp_unscalarizable_region
1192 && AGGREGATE_TYPE_P (TREE_TYPE (lhs
))
1193 && lacc
->size
== racc
->size
1194 && useless_type_conversion_p (lacc
->type
, racc
->type
))
1196 struct assign_link
*link
;
1198 link
= (struct assign_link
*) pool_alloc (link_pool
);
1199 memset (link
, 0, sizeof (struct assign_link
));
1204 add_link_to_rhs (racc
, link
);
1207 return lacc
|| racc
;
1210 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1211 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1214 asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED
, tree op
,
1215 void *data ATTRIBUTE_UNUSED
)
1217 op
= get_base_address (op
);
1220 disqualify_candidate (op
, "Non-scalarizable GIMPLE_ASM operand.");
1225 /* Return true iff callsite CALL has at least as many actual arguments as there
1226 are formal parameters of the function currently processed by IPA-SRA. */
1229 callsite_has_enough_arguments_p (gimple call
)
1231 return gimple_call_num_args (call
) >= (unsigned) func_param_count
;
1234 /* Scan function and look for interesting expressions and create access
1235 structures for them. Return true iff any access is created. */
1238 scan_function (void)
1245 gimple_stmt_iterator gsi
;
1246 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1248 gimple stmt
= gsi_stmt (gsi
);
1252 if (final_bbs
&& stmt_can_throw_external (stmt
))
1253 bitmap_set_bit (final_bbs
, bb
->index
);
1254 switch (gimple_code (stmt
))
1257 t
= gimple_return_retval (stmt
);
1259 ret
|= build_access_from_expr (t
, stmt
, false);
1261 bitmap_set_bit (final_bbs
, bb
->index
);
1265 ret
|= build_accesses_from_assign (stmt
);
1269 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1270 ret
|= build_access_from_expr (gimple_call_arg (stmt
, i
),
1273 if (sra_mode
== SRA_MODE_EARLY_IPA
)
1275 tree dest
= gimple_call_fndecl (stmt
);
1276 int flags
= gimple_call_flags (stmt
);
1280 if (DECL_BUILT_IN_CLASS (dest
) == BUILT_IN_NORMAL
1281 && DECL_FUNCTION_CODE (dest
) == BUILT_IN_APPLY_ARGS
)
1282 encountered_apply_args
= true;
1283 if (recursive_call_p (current_function_decl
, dest
))
1285 encountered_recursive_call
= true;
1286 if (!callsite_has_enough_arguments_p (stmt
))
1287 encountered_unchangable_recursive_call
= true;
1292 && (flags
& (ECF_CONST
| ECF_PURE
)) == 0)
1293 bitmap_set_bit (final_bbs
, bb
->index
);
1296 t
= gimple_call_lhs (stmt
);
1297 if (t
&& !disqualify_ops_if_throwing_stmt (stmt
, t
, NULL
))
1298 ret
|= build_access_from_expr (t
, stmt
, true);
1302 walk_stmt_load_store_addr_ops (stmt
, NULL
, NULL
, NULL
,
1305 bitmap_set_bit (final_bbs
, bb
->index
);
1307 for (i
= 0; i
< gimple_asm_ninputs (stmt
); i
++)
1309 t
= TREE_VALUE (gimple_asm_input_op (stmt
, i
));
1310 ret
|= build_access_from_expr (t
, stmt
, false);
1312 for (i
= 0; i
< gimple_asm_noutputs (stmt
); i
++)
1314 t
= TREE_VALUE (gimple_asm_output_op (stmt
, i
));
1315 ret
|= build_access_from_expr (t
, stmt
, true);
1328 /* Helper of QSORT function. There are pointers to accesses in the array. An
1329 access is considered smaller than another if it has smaller offset or if the
1330 offsets are the same but is size is bigger. */
1333 compare_access_positions (const void *a
, const void *b
)
1335 const access_p
*fp1
= (const access_p
*) a
;
1336 const access_p
*fp2
= (const access_p
*) b
;
1337 const access_p f1
= *fp1
;
1338 const access_p f2
= *fp2
;
1340 if (f1
->offset
!= f2
->offset
)
1341 return f1
->offset
< f2
->offset
? -1 : 1;
1343 if (f1
->size
== f2
->size
)
1345 if (f1
->type
== f2
->type
)
1347 /* Put any non-aggregate type before any aggregate type. */
1348 else if (!is_gimple_reg_type (f1
->type
)
1349 && is_gimple_reg_type (f2
->type
))
1351 else if (is_gimple_reg_type (f1
->type
)
1352 && !is_gimple_reg_type (f2
->type
))
1354 /* Put any complex or vector type before any other scalar type. */
1355 else if (TREE_CODE (f1
->type
) != COMPLEX_TYPE
1356 && TREE_CODE (f1
->type
) != VECTOR_TYPE
1357 && (TREE_CODE (f2
->type
) == COMPLEX_TYPE
1358 || TREE_CODE (f2
->type
) == VECTOR_TYPE
))
1360 else if ((TREE_CODE (f1
->type
) == COMPLEX_TYPE
1361 || TREE_CODE (f1
->type
) == VECTOR_TYPE
)
1362 && TREE_CODE (f2
->type
) != COMPLEX_TYPE
1363 && TREE_CODE (f2
->type
) != VECTOR_TYPE
)
1365 /* Put the integral type with the bigger precision first. */
1366 else if (INTEGRAL_TYPE_P (f1
->type
)
1367 && INTEGRAL_TYPE_P (f2
->type
))
1368 return TYPE_PRECISION (f2
->type
) - TYPE_PRECISION (f1
->type
);
1369 /* Put any integral type with non-full precision last. */
1370 else if (INTEGRAL_TYPE_P (f1
->type
)
1371 && (TREE_INT_CST_LOW (TYPE_SIZE (f1
->type
))
1372 != TYPE_PRECISION (f1
->type
)))
1374 else if (INTEGRAL_TYPE_P (f2
->type
)
1375 && (TREE_INT_CST_LOW (TYPE_SIZE (f2
->type
))
1376 != TYPE_PRECISION (f2
->type
)))
1378 /* Stabilize the sort. */
1379 return TYPE_UID (f1
->type
) - TYPE_UID (f2
->type
);
1382 /* We want the bigger accesses first, thus the opposite operator in the next
1384 return f1
->size
> f2
->size
? -1 : 1;
1388 /* Append a name of the declaration to the name obstack. A helper function for
1392 make_fancy_decl_name (tree decl
)
1396 tree name
= DECL_NAME (decl
);
1398 obstack_grow (&name_obstack
, IDENTIFIER_POINTER (name
),
1399 IDENTIFIER_LENGTH (name
));
1402 sprintf (buffer
, "D%u", DECL_UID (decl
));
1403 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1407 /* Helper for make_fancy_name. */
1410 make_fancy_name_1 (tree expr
)
1417 make_fancy_decl_name (expr
);
1421 switch (TREE_CODE (expr
))
1424 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1425 obstack_1grow (&name_obstack
, '$');
1426 make_fancy_decl_name (TREE_OPERAND (expr
, 1));
1430 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1431 obstack_1grow (&name_obstack
, '$');
1432 /* Arrays with only one element may not have a constant as their
1434 index
= TREE_OPERAND (expr
, 1);
1435 if (TREE_CODE (index
) != INTEGER_CST
)
1437 sprintf (buffer
, HOST_WIDE_INT_PRINT_DEC
, TREE_INT_CST_LOW (index
));
1438 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1442 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1446 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1447 if (!integer_zerop (TREE_OPERAND (expr
, 1)))
1449 obstack_1grow (&name_obstack
, '$');
1450 sprintf (buffer
, HOST_WIDE_INT_PRINT_DEC
,
1451 TREE_INT_CST_LOW (TREE_OPERAND (expr
, 1)));
1452 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1459 gcc_unreachable (); /* we treat these as scalars. */
1466 /* Create a human readable name for replacement variable of ACCESS. */
1469 make_fancy_name (tree expr
)
1471 make_fancy_name_1 (expr
);
1472 obstack_1grow (&name_obstack
, '\0');
1473 return XOBFINISH (&name_obstack
, char *);
1476 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1477 EXP_TYPE at the given OFFSET. If BASE is something for which
1478 get_addr_base_and_unit_offset returns NULL, gsi must be non-NULL and is used
1479 to insert new statements either before or below the current one as specified
1480 by INSERT_AFTER. This function is not capable of handling bitfields.
1482 BASE must be either a declaration or a memory reference that has correct
1483 alignment ifformation embeded in it (e.g. a pre-existing one in SRA). */
1486 build_ref_for_offset (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1487 tree exp_type
, gimple_stmt_iterator
*gsi
,
1490 tree prev_base
= base
;
1493 HOST_WIDE_INT base_offset
;
1494 unsigned HOST_WIDE_INT misalign
;
1497 gcc_checking_assert (offset
% BITS_PER_UNIT
== 0);
1498 get_object_alignment_1 (base
, &align
, &misalign
);
1499 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
1501 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1502 offset such as array[var_index]. */
1508 gcc_checking_assert (gsi
);
1509 tmp
= make_ssa_name (build_pointer_type (TREE_TYPE (prev_base
)), NULL
);
1510 addr
= build_fold_addr_expr (unshare_expr (prev_base
));
1511 STRIP_USELESS_TYPE_CONVERSION (addr
);
1512 stmt
= gimple_build_assign (tmp
, addr
);
1513 gimple_set_location (stmt
, loc
);
1515 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
1517 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
1519 off
= build_int_cst (reference_alias_ptr_type (prev_base
),
1520 offset
/ BITS_PER_UNIT
);
1523 else if (TREE_CODE (base
) == MEM_REF
)
1525 off
= build_int_cst (TREE_TYPE (TREE_OPERAND (base
, 1)),
1526 base_offset
+ offset
/ BITS_PER_UNIT
);
1527 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1), off
);
1528 base
= unshare_expr (TREE_OPERAND (base
, 0));
1532 off
= build_int_cst (reference_alias_ptr_type (base
),
1533 base_offset
+ offset
/ BITS_PER_UNIT
);
1534 base
= build_fold_addr_expr (unshare_expr (base
));
1537 misalign
= (misalign
+ offset
) & (align
- 1);
1539 align
= (misalign
& -misalign
);
1540 if (align
< TYPE_ALIGN (exp_type
))
1541 exp_type
= build_aligned_type (exp_type
, align
);
1543 mem_ref
= fold_build2_loc (loc
, MEM_REF
, exp_type
, base
, off
);
1544 if (TREE_THIS_VOLATILE (prev_base
))
1545 TREE_THIS_VOLATILE (mem_ref
) = 1;
1546 if (TREE_SIDE_EFFECTS (prev_base
))
1547 TREE_SIDE_EFFECTS (mem_ref
) = 1;
1551 /* Construct a memory reference to a part of an aggregate BASE at the given
1552 OFFSET and of the same type as MODEL. In case this is a reference to a
1553 bit-field, the function will replicate the last component_ref of model's
1554 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1555 build_ref_for_offset. */
1558 build_ref_for_model (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1559 struct access
*model
, gimple_stmt_iterator
*gsi
,
1562 if (TREE_CODE (model
->expr
) == COMPONENT_REF
1563 && DECL_BIT_FIELD (TREE_OPERAND (model
->expr
, 1)))
1565 /* This access represents a bit-field. */
1566 tree t
, exp_type
, fld
= TREE_OPERAND (model
->expr
, 1);
1568 offset
-= int_bit_position (fld
);
1569 exp_type
= TREE_TYPE (TREE_OPERAND (model
->expr
, 0));
1570 t
= build_ref_for_offset (loc
, base
, offset
, exp_type
, gsi
, insert_after
);
1571 return fold_build3_loc (loc
, COMPONENT_REF
, TREE_TYPE (fld
), t
, fld
,
1575 return build_ref_for_offset (loc
, base
, offset
, model
->type
,
1579 /* Attempt to build a memory reference that we could but into a gimple
1580 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1581 create statements and return s NULL instead. This function also ignores
1582 alignment issues and so its results should never end up in non-debug
1586 build_debug_ref_for_model (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1587 struct access
*model
)
1589 HOST_WIDE_INT base_offset
;
1592 if (TREE_CODE (model
->expr
) == COMPONENT_REF
1593 && DECL_BIT_FIELD (TREE_OPERAND (model
->expr
, 1)))
1596 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
1599 if (TREE_CODE (base
) == MEM_REF
)
1601 off
= build_int_cst (TREE_TYPE (TREE_OPERAND (base
, 1)),
1602 base_offset
+ offset
/ BITS_PER_UNIT
);
1603 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1), off
);
1604 base
= unshare_expr (TREE_OPERAND (base
, 0));
1608 off
= build_int_cst (reference_alias_ptr_type (base
),
1609 base_offset
+ offset
/ BITS_PER_UNIT
);
1610 base
= build_fold_addr_expr (unshare_expr (base
));
1613 return fold_build2_loc (loc
, MEM_REF
, model
->type
, base
, off
);
1616 /* Construct a memory reference consisting of component_refs and array_refs to
1617 a part of an aggregate *RES (which is of type TYPE). The requested part
1618 should have type EXP_TYPE at be the given OFFSET. This function might not
1619 succeed, it returns true when it does and only then *RES points to something
1620 meaningful. This function should be used only to build expressions that we
1621 might need to present to user (e.g. in warnings). In all other situations,
1622 build_ref_for_model or build_ref_for_offset should be used instead. */
1625 build_user_friendly_ref_for_offset (tree
*res
, tree type
, HOST_WIDE_INT offset
,
1631 tree tr_size
, index
, minidx
;
1632 HOST_WIDE_INT el_size
;
1634 if (offset
== 0 && exp_type
1635 && types_compatible_p (exp_type
, type
))
1638 switch (TREE_CODE (type
))
1641 case QUAL_UNION_TYPE
:
1643 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
1645 HOST_WIDE_INT pos
, size
;
1646 tree tr_pos
, expr
, *expr_ptr
;
1648 if (TREE_CODE (fld
) != FIELD_DECL
)
1651 tr_pos
= bit_position (fld
);
1652 if (!tr_pos
|| !host_integerp (tr_pos
, 1))
1654 pos
= TREE_INT_CST_LOW (tr_pos
);
1655 gcc_assert (TREE_CODE (type
) == RECORD_TYPE
|| pos
== 0);
1656 tr_size
= DECL_SIZE (fld
);
1657 if (!tr_size
|| !host_integerp (tr_size
, 1))
1659 size
= TREE_INT_CST_LOW (tr_size
);
1665 else if (pos
> offset
|| (pos
+ size
) <= offset
)
1668 expr
= build3 (COMPONENT_REF
, TREE_TYPE (fld
), *res
, fld
,
1671 if (build_user_friendly_ref_for_offset (expr_ptr
, TREE_TYPE (fld
),
1672 offset
- pos
, exp_type
))
1681 tr_size
= TYPE_SIZE (TREE_TYPE (type
));
1682 if (!tr_size
|| !host_integerp (tr_size
, 1))
1684 el_size
= tree_low_cst (tr_size
, 1);
1686 minidx
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
1687 if (TREE_CODE (minidx
) != INTEGER_CST
|| el_size
== 0)
1689 index
= build_int_cst (TYPE_DOMAIN (type
), offset
/ el_size
);
1690 if (!integer_zerop (minidx
))
1691 index
= int_const_binop (PLUS_EXPR
, index
, minidx
);
1692 *res
= build4 (ARRAY_REF
, TREE_TYPE (type
), *res
, index
,
1693 NULL_TREE
, NULL_TREE
);
1694 offset
= offset
% el_size
;
1695 type
= TREE_TYPE (type
);
1710 /* Return true iff TYPE is stdarg va_list type. */
1713 is_va_list_type (tree type
)
1715 return TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (va_list_type_node
);
1718 /* Print message to dump file why a variable was rejected. */
1721 reject (tree var
, const char *msg
)
1723 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1725 fprintf (dump_file
, "Rejected (%d): %s: ", DECL_UID (var
), msg
);
1726 print_generic_expr (dump_file
, var
, 0);
1727 fprintf (dump_file
, "\n");
1731 /* Return true if VAR is a candidate for SRA. */
1734 maybe_add_sra_candidate (tree var
)
1736 tree type
= TREE_TYPE (var
);
1740 if (!AGGREGATE_TYPE_P (type
))
1742 reject (var
, "not aggregate");
1745 if (needs_to_live_in_memory (var
))
1747 reject (var
, "needs to live in memory");
1750 if (TREE_THIS_VOLATILE (var
))
1752 reject (var
, "is volatile");
1755 if (!COMPLETE_TYPE_P (type
))
1757 reject (var
, "has incomplete type");
1760 if (!host_integerp (TYPE_SIZE (type
), 1))
1762 reject (var
, "type size not fixed");
1765 if (tree_low_cst (TYPE_SIZE (type
), 1) == 0)
1767 reject (var
, "type size is zero");
1770 if (type_internals_preclude_sra_p (type
, &msg
))
1775 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1776 we also want to schedule it rather late. Thus we ignore it in
1778 (sra_mode
== SRA_MODE_EARLY_INTRA
1779 && is_va_list_type (type
)))
1781 reject (var
, "is va_list");
1785 bitmap_set_bit (candidate_bitmap
, DECL_UID (var
));
1786 slot
= candidates
.find_slot_with_hash (var
, DECL_UID (var
), INSERT
);
1789 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1791 fprintf (dump_file
, "Candidate (%d): ", DECL_UID (var
));
1792 print_generic_expr (dump_file
, var
, 0);
1793 fprintf (dump_file
, "\n");
1799 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1800 those with type which is suitable for scalarization. */
1803 find_var_candidates (void)
1809 for (parm
= DECL_ARGUMENTS (current_function_decl
);
1811 parm
= DECL_CHAIN (parm
))
1812 ret
|= maybe_add_sra_candidate (parm
);
1814 FOR_EACH_LOCAL_DECL (cfun
, i
, var
)
1816 if (TREE_CODE (var
) != VAR_DECL
)
1819 ret
|= maybe_add_sra_candidate (var
);
1825 /* Sort all accesses for the given variable, check for partial overlaps and
1826 return NULL if there are any. If there are none, pick a representative for
1827 each combination of offset and size and create a linked list out of them.
1828 Return the pointer to the first representative and make sure it is the first
1829 one in the vector of accesses. */
1831 static struct access
*
1832 sort_and_splice_var_accesses (tree var
)
1834 int i
, j
, access_count
;
1835 struct access
*res
, **prev_acc_ptr
= &res
;
1836 vec
<access_p
> *access_vec
;
1838 HOST_WIDE_INT low
= -1, high
= 0;
1840 access_vec
= get_base_access_vector (var
);
1843 access_count
= access_vec
->length ();
1845 /* Sort by <OFFSET, SIZE>. */
1846 access_vec
->qsort (compare_access_positions
);
1849 while (i
< access_count
)
1851 struct access
*access
= (*access_vec
)[i
];
1852 bool grp_write
= access
->write
;
1853 bool grp_read
= !access
->write
;
1854 bool grp_scalar_write
= access
->write
1855 && is_gimple_reg_type (access
->type
);
1856 bool grp_scalar_read
= !access
->write
1857 && is_gimple_reg_type (access
->type
);
1858 bool grp_assignment_read
= access
->grp_assignment_read
;
1859 bool grp_assignment_write
= access
->grp_assignment_write
;
1860 bool multiple_scalar_reads
= false;
1861 bool total_scalarization
= access
->grp_total_scalarization
;
1862 bool grp_partial_lhs
= access
->grp_partial_lhs
;
1863 bool first_scalar
= is_gimple_reg_type (access
->type
);
1864 bool unscalarizable_region
= access
->grp_unscalarizable_region
;
1866 if (first
|| access
->offset
>= high
)
1869 low
= access
->offset
;
1870 high
= access
->offset
+ access
->size
;
1872 else if (access
->offset
> low
&& access
->offset
+ access
->size
> high
)
1875 gcc_assert (access
->offset
>= low
1876 && access
->offset
+ access
->size
<= high
);
1879 while (j
< access_count
)
1881 struct access
*ac2
= (*access_vec
)[j
];
1882 if (ac2
->offset
!= access
->offset
|| ac2
->size
!= access
->size
)
1887 grp_scalar_write
= (grp_scalar_write
1888 || is_gimple_reg_type (ac2
->type
));
1893 if (is_gimple_reg_type (ac2
->type
))
1895 if (grp_scalar_read
)
1896 multiple_scalar_reads
= true;
1898 grp_scalar_read
= true;
1901 grp_assignment_read
|= ac2
->grp_assignment_read
;
1902 grp_assignment_write
|= ac2
->grp_assignment_write
;
1903 grp_partial_lhs
|= ac2
->grp_partial_lhs
;
1904 unscalarizable_region
|= ac2
->grp_unscalarizable_region
;
1905 total_scalarization
|= ac2
->grp_total_scalarization
;
1906 relink_to_new_repr (access
, ac2
);
1908 /* If there are both aggregate-type and scalar-type accesses with
1909 this combination of size and offset, the comparison function
1910 should have put the scalars first. */
1911 gcc_assert (first_scalar
|| !is_gimple_reg_type (ac2
->type
));
1912 ac2
->group_representative
= access
;
1918 access
->group_representative
= access
;
1919 access
->grp_write
= grp_write
;
1920 access
->grp_read
= grp_read
;
1921 access
->grp_scalar_read
= grp_scalar_read
;
1922 access
->grp_scalar_write
= grp_scalar_write
;
1923 access
->grp_assignment_read
= grp_assignment_read
;
1924 access
->grp_assignment_write
= grp_assignment_write
;
1925 access
->grp_hint
= multiple_scalar_reads
|| total_scalarization
;
1926 access
->grp_total_scalarization
= total_scalarization
;
1927 access
->grp_partial_lhs
= grp_partial_lhs
;
1928 access
->grp_unscalarizable_region
= unscalarizable_region
;
1929 if (access
->first_link
)
1930 add_access_to_work_queue (access
);
1932 *prev_acc_ptr
= access
;
1933 prev_acc_ptr
= &access
->next_grp
;
1936 gcc_assert (res
== (*access_vec
)[0]);
1940 /* Create a variable for the given ACCESS which determines the type, name and a
1941 few other properties. Return the variable declaration and store it also to
1942 ACCESS->replacement. */
1945 create_access_replacement (struct access
*access
)
1949 if (access
->grp_to_be_debug_replaced
)
1951 repl
= create_tmp_var_raw (access
->type
, NULL
);
1952 DECL_CONTEXT (repl
) = current_function_decl
;
1955 repl
= create_tmp_var (access
->type
, "SR");
1956 if (TREE_CODE (access
->type
) == COMPLEX_TYPE
1957 || TREE_CODE (access
->type
) == VECTOR_TYPE
)
1959 if (!access
->grp_partial_lhs
)
1960 DECL_GIMPLE_REG_P (repl
) = 1;
1962 else if (access
->grp_partial_lhs
1963 && is_gimple_reg_type (access
->type
))
1964 TREE_ADDRESSABLE (repl
) = 1;
1966 DECL_SOURCE_LOCATION (repl
) = DECL_SOURCE_LOCATION (access
->base
);
1967 DECL_ARTIFICIAL (repl
) = 1;
1968 DECL_IGNORED_P (repl
) = DECL_IGNORED_P (access
->base
);
1970 if (DECL_NAME (access
->base
)
1971 && !DECL_IGNORED_P (access
->base
)
1972 && !DECL_ARTIFICIAL (access
->base
))
1974 char *pretty_name
= make_fancy_name (access
->expr
);
1975 tree debug_expr
= unshare_expr_without_location (access
->expr
), d
;
1978 DECL_NAME (repl
) = get_identifier (pretty_name
);
1979 obstack_free (&name_obstack
, pretty_name
);
1981 /* Get rid of any SSA_NAMEs embedded in debug_expr,
1982 as DECL_DEBUG_EXPR isn't considered when looking for still
1983 used SSA_NAMEs and thus they could be freed. All debug info
1984 generation cares is whether something is constant or variable
1985 and that get_ref_base_and_extent works properly on the
1986 expression. It cannot handle accesses at a non-constant offset
1987 though, so just give up in those cases. */
1988 for (d
= debug_expr
;
1989 !fail
&& (handled_component_p (d
) || TREE_CODE (d
) == MEM_REF
);
1990 d
= TREE_OPERAND (d
, 0))
1991 switch (TREE_CODE (d
))
1994 case ARRAY_RANGE_REF
:
1995 if (TREE_OPERAND (d
, 1)
1996 && TREE_CODE (TREE_OPERAND (d
, 1)) != INTEGER_CST
)
1998 if (TREE_OPERAND (d
, 3)
1999 && TREE_CODE (TREE_OPERAND (d
, 3)) != INTEGER_CST
)
2003 if (TREE_OPERAND (d
, 2)
2004 && TREE_CODE (TREE_OPERAND (d
, 2)) != INTEGER_CST
)
2008 if (TREE_CODE (TREE_OPERAND (d
, 0)) != ADDR_EXPR
)
2011 d
= TREE_OPERAND (d
, 0);
2018 SET_DECL_DEBUG_EXPR (repl
, debug_expr
);
2019 DECL_HAS_DEBUG_EXPR_P (repl
) = 1;
2021 if (access
->grp_no_warning
)
2022 TREE_NO_WARNING (repl
) = 1;
2024 TREE_NO_WARNING (repl
) = TREE_NO_WARNING (access
->base
);
2027 TREE_NO_WARNING (repl
) = 1;
2031 if (access
->grp_to_be_debug_replaced
)
2033 fprintf (dump_file
, "Created a debug-only replacement for ");
2034 print_generic_expr (dump_file
, access
->base
, 0);
2035 fprintf (dump_file
, " offset: %u, size: %u\n",
2036 (unsigned) access
->offset
, (unsigned) access
->size
);
2040 fprintf (dump_file
, "Created a replacement for ");
2041 print_generic_expr (dump_file
, access
->base
, 0);
2042 fprintf (dump_file
, " offset: %u, size: %u: ",
2043 (unsigned) access
->offset
, (unsigned) access
->size
);
2044 print_generic_expr (dump_file
, repl
, 0);
2045 fprintf (dump_file
, "\n");
2048 sra_stats
.replacements
++;
2053 /* Return ACCESS scalar replacement, create it if it does not exist yet. */
2056 get_access_replacement (struct access
*access
)
2058 gcc_checking_assert (access
->replacement_decl
);
2059 return access
->replacement_decl
;
2063 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2064 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2065 to it is not "within" the root. Return false iff some accesses partially
2069 build_access_subtree (struct access
**access
)
2071 struct access
*root
= *access
, *last_child
= NULL
;
2072 HOST_WIDE_INT limit
= root
->offset
+ root
->size
;
2074 *access
= (*access
)->next_grp
;
2075 while (*access
&& (*access
)->offset
+ (*access
)->size
<= limit
)
2078 root
->first_child
= *access
;
2080 last_child
->next_sibling
= *access
;
2081 last_child
= *access
;
2083 if (!build_access_subtree (access
))
2087 if (*access
&& (*access
)->offset
< limit
)
2093 /* Build a tree of access representatives, ACCESS is the pointer to the first
2094 one, others are linked in a list by the next_grp field. Return false iff
2095 some accesses partially overlap. */
2098 build_access_trees (struct access
*access
)
2102 struct access
*root
= access
;
2104 if (!build_access_subtree (&access
))
2106 root
->next_grp
= access
;
2111 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2115 expr_with_var_bounded_array_refs_p (tree expr
)
2117 while (handled_component_p (expr
))
2119 if (TREE_CODE (expr
) == ARRAY_REF
2120 && !host_integerp (array_ref_low_bound (expr
), 0))
2122 expr
= TREE_OPERAND (expr
, 0);
2127 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2128 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2129 sorts of access flags appropriately along the way, notably always set
2130 grp_read and grp_assign_read according to MARK_READ and grp_write when
2133 Creating a replacement for a scalar access is considered beneficial if its
2134 grp_hint is set (this means we are either attempting total scalarization or
2135 there is more than one direct read access) or according to the following
2138 Access written to through a scalar type (once or more times)
2140 | Written to in an assignment statement
2142 | | Access read as scalar _once_
2144 | | | Read in an assignment statement
2146 | | | | Scalarize Comment
2147 -----------------------------------------------------------------------------
2148 0 0 0 0 No access for the scalar
2149 0 0 0 1 No access for the scalar
2150 0 0 1 0 No Single read - won't help
2151 0 0 1 1 No The same case
2152 0 1 0 0 No access for the scalar
2153 0 1 0 1 No access for the scalar
2154 0 1 1 0 Yes s = *g; return s.i;
2155 0 1 1 1 Yes The same case as above
2156 1 0 0 0 No Won't help
2157 1 0 0 1 Yes s.i = 1; *g = s;
2158 1 0 1 0 Yes s.i = 5; g = s.i;
2159 1 0 1 1 Yes The same case as above
2160 1 1 0 0 No Won't help.
2161 1 1 0 1 Yes s.i = 1; *g = s;
2162 1 1 1 0 Yes s = *g; return s.i;
2163 1 1 1 1 Yes Any of the above yeses */
2166 analyze_access_subtree (struct access
*root
, struct access
*parent
,
2167 bool allow_replacements
)
2169 struct access
*child
;
2170 HOST_WIDE_INT limit
= root
->offset
+ root
->size
;
2171 HOST_WIDE_INT covered_to
= root
->offset
;
2172 bool scalar
= is_gimple_reg_type (root
->type
);
2173 bool hole
= false, sth_created
= false;
2177 if (parent
->grp_read
)
2179 if (parent
->grp_assignment_read
)
2180 root
->grp_assignment_read
= 1;
2181 if (parent
->grp_write
)
2182 root
->grp_write
= 1;
2183 if (parent
->grp_assignment_write
)
2184 root
->grp_assignment_write
= 1;
2185 if (parent
->grp_total_scalarization
)
2186 root
->grp_total_scalarization
= 1;
2189 if (root
->grp_unscalarizable_region
)
2190 allow_replacements
= false;
2192 if (allow_replacements
&& expr_with_var_bounded_array_refs_p (root
->expr
))
2193 allow_replacements
= false;
2195 for (child
= root
->first_child
; child
; child
= child
->next_sibling
)
2197 hole
|= covered_to
< child
->offset
;
2198 sth_created
|= analyze_access_subtree (child
, root
,
2199 allow_replacements
&& !scalar
);
2201 root
->grp_unscalarized_data
|= child
->grp_unscalarized_data
;
2202 root
->grp_total_scalarization
&= child
->grp_total_scalarization
;
2203 if (child
->grp_covered
)
2204 covered_to
+= child
->size
;
2209 if (allow_replacements
&& scalar
&& !root
->first_child
2211 || ((root
->grp_scalar_read
|| root
->grp_assignment_read
)
2212 && (root
->grp_scalar_write
|| root
->grp_assignment_write
))))
2214 /* Always create access replacements that cover the whole access.
2215 For integral types this means the precision has to match.
2216 Avoid assumptions based on the integral type kind, too. */
2217 if (INTEGRAL_TYPE_P (root
->type
)
2218 && (TREE_CODE (root
->type
) != INTEGER_TYPE
2219 || TYPE_PRECISION (root
->type
) != root
->size
)
2220 /* But leave bitfield accesses alone. */
2221 && (TREE_CODE (root
->expr
) != COMPONENT_REF
2222 || !DECL_BIT_FIELD (TREE_OPERAND (root
->expr
, 1))))
2224 tree rt
= root
->type
;
2225 gcc_assert ((root
->offset
% BITS_PER_UNIT
) == 0
2226 && (root
->size
% BITS_PER_UNIT
) == 0);
2227 root
->type
= build_nonstandard_integer_type (root
->size
,
2228 TYPE_UNSIGNED (rt
));
2229 root
->expr
= build_ref_for_offset (UNKNOWN_LOCATION
,
2230 root
->base
, root
->offset
,
2231 root
->type
, NULL
, false);
2233 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2235 fprintf (dump_file
, "Changing the type of a replacement for ");
2236 print_generic_expr (dump_file
, root
->base
, 0);
2237 fprintf (dump_file
, " offset: %u, size: %u ",
2238 (unsigned) root
->offset
, (unsigned) root
->size
);
2239 fprintf (dump_file
, " to an integer.\n");
2243 root
->grp_to_be_replaced
= 1;
2244 root
->replacement_decl
= create_access_replacement (root
);
2250 if (allow_replacements
2251 && scalar
&& !root
->first_child
2252 && (root
->grp_scalar_write
|| root
->grp_assignment_write
)
2253 && !bitmap_bit_p (cannot_scalarize_away_bitmap
,
2254 DECL_UID (root
->base
)))
2256 gcc_checking_assert (!root
->grp_scalar_read
2257 && !root
->grp_assignment_read
);
2259 if (MAY_HAVE_DEBUG_STMTS
)
2261 root
->grp_to_be_debug_replaced
= 1;
2262 root
->replacement_decl
= create_access_replacement (root
);
2266 if (covered_to
< limit
)
2269 root
->grp_total_scalarization
= 0;
2272 if (!hole
|| root
->grp_total_scalarization
)
2273 root
->grp_covered
= 1;
2274 else if (root
->grp_write
|| TREE_CODE (root
->base
) == PARM_DECL
)
2275 root
->grp_unscalarized_data
= 1; /* not covered and written to */
2279 /* Analyze all access trees linked by next_grp by the means of
2280 analyze_access_subtree. */
2282 analyze_access_trees (struct access
*access
)
2288 if (analyze_access_subtree (access
, NULL
, true))
2290 access
= access
->next_grp
;
2296 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2297 SIZE would conflict with an already existing one. If exactly such a child
2298 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2301 child_would_conflict_in_lacc (struct access
*lacc
, HOST_WIDE_INT norm_offset
,
2302 HOST_WIDE_INT size
, struct access
**exact_match
)
2304 struct access
*child
;
2306 for (child
= lacc
->first_child
; child
; child
= child
->next_sibling
)
2308 if (child
->offset
== norm_offset
&& child
->size
== size
)
2310 *exact_match
= child
;
2314 if (child
->offset
< norm_offset
+ size
2315 && child
->offset
+ child
->size
> norm_offset
)
2322 /* Create a new child access of PARENT, with all properties just like MODEL
2323 except for its offset and with its grp_write false and grp_read true.
2324 Return the new access or NULL if it cannot be created. Note that this access
2325 is created long after all splicing and sorting, it's not located in any
2326 access vector and is automatically a representative of its group. */
2328 static struct access
*
2329 create_artificial_child_access (struct access
*parent
, struct access
*model
,
2330 HOST_WIDE_INT new_offset
)
2332 struct access
*access
;
2333 struct access
**child
;
2334 tree expr
= parent
->base
;
2336 gcc_assert (!model
->grp_unscalarizable_region
);
2338 access
= (struct access
*) pool_alloc (access_pool
);
2339 memset (access
, 0, sizeof (struct access
));
2340 if (!build_user_friendly_ref_for_offset (&expr
, TREE_TYPE (expr
), new_offset
,
2343 access
->grp_no_warning
= true;
2344 expr
= build_ref_for_model (EXPR_LOCATION (parent
->base
), parent
->base
,
2345 new_offset
, model
, NULL
, false);
2348 access
->base
= parent
->base
;
2349 access
->expr
= expr
;
2350 access
->offset
= new_offset
;
2351 access
->size
= model
->size
;
2352 access
->type
= model
->type
;
2353 access
->grp_write
= true;
2354 access
->grp_read
= false;
2356 child
= &parent
->first_child
;
2357 while (*child
&& (*child
)->offset
< new_offset
)
2358 child
= &(*child
)->next_sibling
;
2360 access
->next_sibling
= *child
;
2367 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
2368 true if any new subaccess was created. Additionally, if RACC is a scalar
2369 access but LACC is not, change the type of the latter, if possible. */
2372 propagate_subaccesses_across_link (struct access
*lacc
, struct access
*racc
)
2374 struct access
*rchild
;
2375 HOST_WIDE_INT norm_delta
= lacc
->offset
- racc
->offset
;
2378 if (is_gimple_reg_type (lacc
->type
)
2379 || lacc
->grp_unscalarizable_region
2380 || racc
->grp_unscalarizable_region
)
2383 if (is_gimple_reg_type (racc
->type
))
2385 if (!lacc
->first_child
&& !racc
->first_child
)
2387 tree t
= lacc
->base
;
2389 lacc
->type
= racc
->type
;
2390 if (build_user_friendly_ref_for_offset (&t
, TREE_TYPE (t
),
2391 lacc
->offset
, racc
->type
))
2395 lacc
->expr
= build_ref_for_model (EXPR_LOCATION (lacc
->base
),
2396 lacc
->base
, lacc
->offset
,
2398 lacc
->grp_no_warning
= true;
2404 for (rchild
= racc
->first_child
; rchild
; rchild
= rchild
->next_sibling
)
2406 struct access
*new_acc
= NULL
;
2407 HOST_WIDE_INT norm_offset
= rchild
->offset
+ norm_delta
;
2409 if (rchild
->grp_unscalarizable_region
)
2412 if (child_would_conflict_in_lacc (lacc
, norm_offset
, rchild
->size
,
2417 rchild
->grp_hint
= 1;
2418 new_acc
->grp_hint
|= new_acc
->grp_read
;
2419 if (rchild
->first_child
)
2420 ret
|= propagate_subaccesses_across_link (new_acc
, rchild
);
2425 rchild
->grp_hint
= 1;
2426 new_acc
= create_artificial_child_access (lacc
, rchild
, norm_offset
);
2430 if (racc
->first_child
)
2431 propagate_subaccesses_across_link (new_acc
, rchild
);
2438 /* Propagate all subaccesses across assignment links. */
2441 propagate_all_subaccesses (void)
2443 while (work_queue_head
)
2445 struct access
*racc
= pop_access_from_work_queue ();
2446 struct assign_link
*link
;
2448 gcc_assert (racc
->first_link
);
2450 for (link
= racc
->first_link
; link
; link
= link
->next
)
2452 struct access
*lacc
= link
->lacc
;
2454 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (lacc
->base
)))
2456 lacc
= lacc
->group_representative
;
2457 if (propagate_subaccesses_across_link (lacc
, racc
)
2458 && lacc
->first_link
)
2459 add_access_to_work_queue (lacc
);
2464 /* Go through all accesses collected throughout the (intraprocedural) analysis
2465 stage, exclude overlapping ones, identify representatives and build trees
2466 out of them, making decisions about scalarization on the way. Return true
2467 iff there are any to-be-scalarized variables after this stage. */
2470 analyze_all_variable_accesses (void)
2473 bitmap tmp
= BITMAP_ALLOC (NULL
);
2475 unsigned i
, max_total_scalarization_size
;
2477 max_total_scalarization_size
= UNITS_PER_WORD
* BITS_PER_UNIT
2478 * MOVE_RATIO (optimize_function_for_speed_p (cfun
));
2480 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap
, 0, i
, bi
)
2481 if (bitmap_bit_p (should_scalarize_away_bitmap
, i
)
2482 && !bitmap_bit_p (cannot_scalarize_away_bitmap
, i
))
2484 tree var
= candidate (i
);
2486 if (TREE_CODE (var
) == VAR_DECL
2487 && type_consists_of_records_p (TREE_TYPE (var
)))
2489 if ((unsigned) tree_low_cst (TYPE_SIZE (TREE_TYPE (var
)), 1)
2490 <= max_total_scalarization_size
)
2492 completely_scalarize_var (var
);
2493 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2495 fprintf (dump_file
, "Will attempt to totally scalarize ");
2496 print_generic_expr (dump_file
, var
, 0);
2497 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (var
));
2500 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2502 fprintf (dump_file
, "Too big to totally scalarize: ");
2503 print_generic_expr (dump_file
, var
, 0);
2504 fprintf (dump_file
, " (UID: %u)\n", DECL_UID (var
));
2509 bitmap_copy (tmp
, candidate_bitmap
);
2510 EXECUTE_IF_SET_IN_BITMAP (tmp
, 0, i
, bi
)
2512 tree var
= candidate (i
);
2513 struct access
*access
;
2515 access
= sort_and_splice_var_accesses (var
);
2516 if (!access
|| !build_access_trees (access
))
2517 disqualify_candidate (var
,
2518 "No or inhibitingly overlapping accesses.");
2521 propagate_all_subaccesses ();
2523 bitmap_copy (tmp
, candidate_bitmap
);
2524 EXECUTE_IF_SET_IN_BITMAP (tmp
, 0, i
, bi
)
2526 tree var
= candidate (i
);
2527 struct access
*access
= get_first_repr_for_decl (var
);
2529 if (analyze_access_trees (access
))
2532 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2534 fprintf (dump_file
, "\nAccess trees for ");
2535 print_generic_expr (dump_file
, var
, 0);
2536 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (var
));
2537 dump_access_tree (dump_file
, access
);
2538 fprintf (dump_file
, "\n");
2542 disqualify_candidate (var
, "No scalar replacements to be created.");
2549 statistics_counter_event (cfun
, "Scalarized aggregates", res
);
2556 /* Generate statements copying scalar replacements of accesses within a subtree
2557 into or out of AGG. ACCESS, all its children, siblings and their children
2558 are to be processed. AGG is an aggregate type expression (can be a
2559 declaration but does not have to be, it can for example also be a mem_ref or
2560 a series of handled components). TOP_OFFSET is the offset of the processed
2561 subtree which has to be subtracted from offsets of individual accesses to
2562 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2563 replacements in the interval <start_offset, start_offset + chunk_size>,
2564 otherwise copy all. GSI is a statement iterator used to place the new
2565 statements. WRITE should be true when the statements should write from AGG
2566 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2567 statements will be added after the current statement in GSI, they will be
2568 added before the statement otherwise. */
2571 generate_subtree_copies (struct access
*access
, tree agg
,
2572 HOST_WIDE_INT top_offset
,
2573 HOST_WIDE_INT start_offset
, HOST_WIDE_INT chunk_size
,
2574 gimple_stmt_iterator
*gsi
, bool write
,
2575 bool insert_after
, location_t loc
)
2579 if (chunk_size
&& access
->offset
>= start_offset
+ chunk_size
)
2582 if (access
->grp_to_be_replaced
2584 || access
->offset
+ access
->size
> start_offset
))
2586 tree expr
, repl
= get_access_replacement (access
);
2589 expr
= build_ref_for_model (loc
, agg
, access
->offset
- top_offset
,
2590 access
, gsi
, insert_after
);
2594 if (access
->grp_partial_lhs
)
2595 expr
= force_gimple_operand_gsi (gsi
, expr
, true, NULL_TREE
,
2597 insert_after
? GSI_NEW_STMT
2599 stmt
= gimple_build_assign (repl
, expr
);
2603 TREE_NO_WARNING (repl
) = 1;
2604 if (access
->grp_partial_lhs
)
2605 repl
= force_gimple_operand_gsi (gsi
, repl
, true, NULL_TREE
,
2607 insert_after
? GSI_NEW_STMT
2609 stmt
= gimple_build_assign (expr
, repl
);
2611 gimple_set_location (stmt
, loc
);
2614 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2616 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2618 sra_stats
.subtree_copies
++;
2621 && access
->grp_to_be_debug_replaced
2623 || access
->offset
+ access
->size
> start_offset
))
2626 tree drhs
= build_debug_ref_for_model (loc
, agg
,
2627 access
->offset
- top_offset
,
2629 ds
= gimple_build_debug_bind (get_access_replacement (access
),
2630 drhs
, gsi_stmt (*gsi
));
2632 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2634 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
2637 if (access
->first_child
)
2638 generate_subtree_copies (access
->first_child
, agg
, top_offset
,
2639 start_offset
, chunk_size
, gsi
,
2640 write
, insert_after
, loc
);
2642 access
= access
->next_sibling
;
2647 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2648 the root of the subtree to be processed. GSI is the statement iterator used
2649 for inserting statements which are added after the current statement if
2650 INSERT_AFTER is true or before it otherwise. */
2653 init_subtree_with_zero (struct access
*access
, gimple_stmt_iterator
*gsi
,
2654 bool insert_after
, location_t loc
)
2657 struct access
*child
;
2659 if (access
->grp_to_be_replaced
)
2663 stmt
= gimple_build_assign (get_access_replacement (access
),
2664 build_zero_cst (access
->type
));
2666 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2668 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2670 gimple_set_location (stmt
, loc
);
2672 else if (access
->grp_to_be_debug_replaced
)
2674 gimple ds
= gimple_build_debug_bind (get_access_replacement (access
),
2675 build_zero_cst (access
->type
),
2678 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2680 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
2683 for (child
= access
->first_child
; child
; child
= child
->next_sibling
)
2684 init_subtree_with_zero (child
, gsi
, insert_after
, loc
);
2687 /* Search for an access representative for the given expression EXPR and
2688 return it or NULL if it cannot be found. */
2690 static struct access
*
2691 get_access_for_expr (tree expr
)
2693 HOST_WIDE_INT offset
, size
, max_size
;
2696 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2697 a different size than the size of its argument and we need the latter
2699 if (TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
2700 expr
= TREE_OPERAND (expr
, 0);
2702 base
= get_ref_base_and_extent (expr
, &offset
, &size
, &max_size
);
2703 if (max_size
== -1 || !DECL_P (base
))
2706 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (base
)))
2709 return get_var_base_offset_size_access (base
, offset
, max_size
);
2712 /* Replace the expression EXPR with a scalar replacement if there is one and
2713 generate other statements to do type conversion or subtree copying if
2714 necessary. GSI is used to place newly created statements, WRITE is true if
2715 the expression is being written to (it is on a LHS of a statement or output
2716 in an assembly statement). */
2719 sra_modify_expr (tree
*expr
, gimple_stmt_iterator
*gsi
, bool write
)
2722 struct access
*access
;
2725 if (TREE_CODE (*expr
) == BIT_FIELD_REF
)
2728 expr
= &TREE_OPERAND (*expr
, 0);
2733 if (TREE_CODE (*expr
) == REALPART_EXPR
|| TREE_CODE (*expr
) == IMAGPART_EXPR
)
2734 expr
= &TREE_OPERAND (*expr
, 0);
2735 access
= get_access_for_expr (*expr
);
2738 type
= TREE_TYPE (*expr
);
2740 loc
= gimple_location (gsi_stmt (*gsi
));
2741 if (access
->grp_to_be_replaced
)
2743 tree repl
= get_access_replacement (access
);
2744 /* If we replace a non-register typed access simply use the original
2745 access expression to extract the scalar component afterwards.
2746 This happens if scalarizing a function return value or parameter
2747 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2748 gcc.c-torture/compile/20011217-1.c.
2750 We also want to use this when accessing a complex or vector which can
2751 be accessed as a different type too, potentially creating a need for
2752 type conversion (see PR42196) and when scalarized unions are involved
2753 in assembler statements (see PR42398). */
2754 if (!useless_type_conversion_p (type
, access
->type
))
2758 ref
= build_ref_for_model (loc
, access
->base
, access
->offset
, access
,
2765 if (access
->grp_partial_lhs
)
2766 ref
= force_gimple_operand_gsi (gsi
, ref
, true, NULL_TREE
,
2767 false, GSI_NEW_STMT
);
2768 stmt
= gimple_build_assign (repl
, ref
);
2769 gimple_set_location (stmt
, loc
);
2770 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2776 if (access
->grp_partial_lhs
)
2777 repl
= force_gimple_operand_gsi (gsi
, repl
, true, NULL_TREE
,
2778 true, GSI_SAME_STMT
);
2779 stmt
= gimple_build_assign (ref
, repl
);
2780 gimple_set_location (stmt
, loc
);
2781 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2788 else if (write
&& access
->grp_to_be_debug_replaced
)
2790 gimple ds
= gimple_build_debug_bind (get_access_replacement (access
),
2793 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2796 if (access
->first_child
)
2798 HOST_WIDE_INT start_offset
, chunk_size
;
2800 && host_integerp (TREE_OPERAND (bfr
, 1), 1)
2801 && host_integerp (TREE_OPERAND (bfr
, 2), 1))
2803 chunk_size
= tree_low_cst (TREE_OPERAND (bfr
, 1), 1);
2804 start_offset
= access
->offset
2805 + tree_low_cst (TREE_OPERAND (bfr
, 2), 1);
2808 start_offset
= chunk_size
= 0;
2810 generate_subtree_copies (access
->first_child
, access
->base
, 0,
2811 start_offset
, chunk_size
, gsi
, write
, write
,
2817 /* Where scalar replacements of the RHS have been written to when a replacement
2818 of a LHS of an assigments cannot be direclty loaded from a replacement of
2820 enum unscalarized_data_handling
{ SRA_UDH_NONE
, /* Nothing done so far. */
2821 SRA_UDH_RIGHT
, /* Data flushed to the RHS. */
2822 SRA_UDH_LEFT
}; /* Data flushed to the LHS. */
2824 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2825 base aggregate if there are unscalarized data or directly to LHS of the
2826 statement that is pointed to by GSI otherwise. */
2828 static enum unscalarized_data_handling
2829 handle_unscalarized_data_in_subtree (struct access
*top_racc
,
2830 gimple_stmt_iterator
*gsi
)
2832 if (top_racc
->grp_unscalarized_data
)
2834 generate_subtree_copies (top_racc
->first_child
, top_racc
->base
, 0, 0, 0,
2836 gimple_location (gsi_stmt (*gsi
)));
2837 return SRA_UDH_RIGHT
;
2841 tree lhs
= gimple_assign_lhs (gsi_stmt (*gsi
));
2842 generate_subtree_copies (top_racc
->first_child
, lhs
, top_racc
->offset
,
2843 0, 0, gsi
, false, false,
2844 gimple_location (gsi_stmt (*gsi
)));
2845 return SRA_UDH_LEFT
;
2850 /* Try to generate statements to load all sub-replacements in an access subtree
2851 formed by children of LACC from scalar replacements in the TOP_RACC subtree.
2852 If that is not possible, refresh the TOP_RACC base aggregate and load the
2853 accesses from it. LEFT_OFFSET is the offset of the left whole subtree being
2854 copied. NEW_GSI is stmt iterator used for statement insertions after the
2855 original assignment, OLD_GSI is used to insert statements before the
2856 assignment. *REFRESHED keeps the information whether we have needed to
2857 refresh replacements of the LHS and from which side of the assignments this
2861 load_assign_lhs_subreplacements (struct access
*lacc
, struct access
*top_racc
,
2862 HOST_WIDE_INT left_offset
,
2863 gimple_stmt_iterator
*old_gsi
,
2864 gimple_stmt_iterator
*new_gsi
,
2865 enum unscalarized_data_handling
*refreshed
)
2867 location_t loc
= gimple_location (gsi_stmt (*old_gsi
));
2868 for (lacc
= lacc
->first_child
; lacc
; lacc
= lacc
->next_sibling
)
2870 HOST_WIDE_INT offset
= lacc
->offset
- left_offset
+ top_racc
->offset
;
2872 if (lacc
->grp_to_be_replaced
)
2874 struct access
*racc
;
2878 racc
= find_access_in_subtree (top_racc
, offset
, lacc
->size
);
2879 if (racc
&& racc
->grp_to_be_replaced
)
2881 rhs
= get_access_replacement (racc
);
2882 if (!useless_type_conversion_p (lacc
->type
, racc
->type
))
2883 rhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, lacc
->type
, rhs
);
2885 if (racc
->grp_partial_lhs
&& lacc
->grp_partial_lhs
)
2886 rhs
= force_gimple_operand_gsi (old_gsi
, rhs
, true, NULL_TREE
,
2887 true, GSI_SAME_STMT
);
2891 /* No suitable access on the right hand side, need to load from
2892 the aggregate. See if we have to update it first... */
2893 if (*refreshed
== SRA_UDH_NONE
)
2894 *refreshed
= handle_unscalarized_data_in_subtree (top_racc
,
2897 if (*refreshed
== SRA_UDH_LEFT
)
2898 rhs
= build_ref_for_model (loc
, lacc
->base
, lacc
->offset
, lacc
,
2901 rhs
= build_ref_for_model (loc
, top_racc
->base
, offset
, lacc
,
2903 if (lacc
->grp_partial_lhs
)
2904 rhs
= force_gimple_operand_gsi (new_gsi
, rhs
, true, NULL_TREE
,
2905 false, GSI_NEW_STMT
);
2908 stmt
= gimple_build_assign (get_access_replacement (lacc
), rhs
);
2909 gsi_insert_after (new_gsi
, stmt
, GSI_NEW_STMT
);
2910 gimple_set_location (stmt
, loc
);
2912 sra_stats
.subreplacements
++;
2916 if (*refreshed
== SRA_UDH_NONE
2917 && lacc
->grp_read
&& !lacc
->grp_covered
)
2918 *refreshed
= handle_unscalarized_data_in_subtree (top_racc
,
2920 if (lacc
&& lacc
->grp_to_be_debug_replaced
)
2924 struct access
*racc
= find_access_in_subtree (top_racc
, offset
,
2927 if (racc
&& racc
->grp_to_be_replaced
)
2929 if (racc
->grp_write
)
2930 drhs
= get_access_replacement (racc
);
2934 else if (*refreshed
== SRA_UDH_LEFT
)
2935 drhs
= build_debug_ref_for_model (loc
, lacc
->base
, lacc
->offset
,
2937 else if (*refreshed
== SRA_UDH_RIGHT
)
2938 drhs
= build_debug_ref_for_model (loc
, top_racc
->base
, offset
,
2942 ds
= gimple_build_debug_bind (get_access_replacement (lacc
),
2943 drhs
, gsi_stmt (*old_gsi
));
2944 gsi_insert_after (new_gsi
, ds
, GSI_NEW_STMT
);
2948 if (lacc
->first_child
)
2949 load_assign_lhs_subreplacements (lacc
, top_racc
, left_offset
,
2950 old_gsi
, new_gsi
, refreshed
);
2954 /* Result code for SRA assignment modification. */
2955 enum assignment_mod_result
{ SRA_AM_NONE
, /* nothing done for the stmt */
2956 SRA_AM_MODIFIED
, /* stmt changed but not
2958 SRA_AM_REMOVED
}; /* stmt eliminated */
2960 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
2961 to the assignment and GSI is the statement iterator pointing at it. Returns
2962 the same values as sra_modify_assign. */
2964 static enum assignment_mod_result
2965 sra_modify_constructor_assign (gimple
*stmt
, gimple_stmt_iterator
*gsi
)
2967 tree lhs
= gimple_assign_lhs (*stmt
);
2971 acc
= get_access_for_expr (lhs
);
2975 if (gimple_clobber_p (*stmt
))
2977 /* Remove clobbers of fully scalarized variables, otherwise
2979 if (acc
->grp_covered
)
2981 unlink_stmt_vdef (*stmt
);
2982 gsi_remove (gsi
, true);
2983 release_defs (*stmt
);
2984 return SRA_AM_REMOVED
;
2990 loc
= gimple_location (*stmt
);
2991 if (vec_safe_length (CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt
))) > 0)
2993 /* I have never seen this code path trigger but if it can happen the
2994 following should handle it gracefully. */
2995 if (access_has_children_p (acc
))
2996 generate_subtree_copies (acc
->first_child
, acc
->base
, 0, 0, 0, gsi
,
2998 return SRA_AM_MODIFIED
;
3001 if (acc
->grp_covered
)
3003 init_subtree_with_zero (acc
, gsi
, false, loc
);
3004 unlink_stmt_vdef (*stmt
);
3005 gsi_remove (gsi
, true);
3006 release_defs (*stmt
);
3007 return SRA_AM_REMOVED
;
3011 init_subtree_with_zero (acc
, gsi
, true, loc
);
3012 return SRA_AM_MODIFIED
;
3016 /* Create and return a new suitable default definition SSA_NAME for RACC which
3017 is an access describing an uninitialized part of an aggregate that is being
3021 get_repl_default_def_ssa_name (struct access
*racc
)
3023 gcc_checking_assert (!racc
->grp_to_be_replaced
3024 && !racc
->grp_to_be_debug_replaced
);
3025 if (!racc
->replacement_decl
)
3026 racc
->replacement_decl
= create_access_replacement (racc
);
3027 return get_or_create_ssa_default_def (cfun
, racc
->replacement_decl
);
3030 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3031 bit-field field declaration somewhere in it. */
3034 contains_vce_or_bfcref_p (const_tree ref
)
3036 while (handled_component_p (ref
))
3038 if (TREE_CODE (ref
) == VIEW_CONVERT_EXPR
3039 || (TREE_CODE (ref
) == COMPONENT_REF
3040 && DECL_BIT_FIELD (TREE_OPERAND (ref
, 1))))
3042 ref
= TREE_OPERAND (ref
, 0);
3048 /* Examine both sides of the assignment statement pointed to by STMT, replace
3049 them with a scalare replacement if there is one and generate copying of
3050 replacements if scalarized aggregates have been used in the assignment. GSI
3051 is used to hold generated statements for type conversions and subtree
3054 static enum assignment_mod_result
3055 sra_modify_assign (gimple
*stmt
, gimple_stmt_iterator
*gsi
)
3057 struct access
*lacc
, *racc
;
3059 bool modify_this_stmt
= false;
3060 bool force_gimple_rhs
= false;
3062 gimple_stmt_iterator orig_gsi
= *gsi
;
3064 if (!gimple_assign_single_p (*stmt
))
3066 lhs
= gimple_assign_lhs (*stmt
);
3067 rhs
= gimple_assign_rhs1 (*stmt
);
3069 if (TREE_CODE (rhs
) == CONSTRUCTOR
)
3070 return sra_modify_constructor_assign (stmt
, gsi
);
3072 if (TREE_CODE (rhs
) == REALPART_EXPR
|| TREE_CODE (lhs
) == REALPART_EXPR
3073 || TREE_CODE (rhs
) == IMAGPART_EXPR
|| TREE_CODE (lhs
) == IMAGPART_EXPR
3074 || TREE_CODE (rhs
) == BIT_FIELD_REF
|| TREE_CODE (lhs
) == BIT_FIELD_REF
)
3076 modify_this_stmt
= sra_modify_expr (gimple_assign_rhs1_ptr (*stmt
),
3078 modify_this_stmt
|= sra_modify_expr (gimple_assign_lhs_ptr (*stmt
),
3080 return modify_this_stmt
? SRA_AM_MODIFIED
: SRA_AM_NONE
;
3083 lacc
= get_access_for_expr (lhs
);
3084 racc
= get_access_for_expr (rhs
);
3088 loc
= gimple_location (*stmt
);
3089 if (lacc
&& lacc
->grp_to_be_replaced
)
3091 lhs
= get_access_replacement (lacc
);
3092 gimple_assign_set_lhs (*stmt
, lhs
);
3093 modify_this_stmt
= true;
3094 if (lacc
->grp_partial_lhs
)
3095 force_gimple_rhs
= true;
3099 if (racc
&& racc
->grp_to_be_replaced
)
3101 rhs
= get_access_replacement (racc
);
3102 modify_this_stmt
= true;
3103 if (racc
->grp_partial_lhs
)
3104 force_gimple_rhs
= true;
3108 && !racc
->grp_unscalarized_data
3109 && TREE_CODE (lhs
) == SSA_NAME
3110 && !access_has_replacements_p (racc
))
3112 rhs
= get_repl_default_def_ssa_name (racc
);
3113 modify_this_stmt
= true;
3117 if (modify_this_stmt
)
3119 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
3121 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3122 ??? This should move to fold_stmt which we simply should
3123 call after building a VIEW_CONVERT_EXPR here. */
3124 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs
))
3125 && !contains_bitfld_component_ref_p (lhs
))
3127 lhs
= build_ref_for_model (loc
, lhs
, 0, racc
, gsi
, false);
3128 gimple_assign_set_lhs (*stmt
, lhs
);
3130 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs
))
3131 && !contains_vce_or_bfcref_p (rhs
))
3132 rhs
= build_ref_for_model (loc
, rhs
, 0, lacc
, gsi
, false);
3134 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
3136 rhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, TREE_TYPE (lhs
),
3138 if (is_gimple_reg_type (TREE_TYPE (lhs
))
3139 && TREE_CODE (lhs
) != SSA_NAME
)
3140 force_gimple_rhs
= true;
3145 if (lacc
&& lacc
->grp_to_be_debug_replaced
)
3147 tree dlhs
= get_access_replacement (lacc
);
3148 tree drhs
= unshare_expr (rhs
);
3149 if (!useless_type_conversion_p (TREE_TYPE (dlhs
), TREE_TYPE (drhs
)))
3151 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs
))
3152 && !contains_vce_or_bfcref_p (drhs
))
3153 drhs
= build_debug_ref_for_model (loc
, drhs
, 0, lacc
);
3155 && !useless_type_conversion_p (TREE_TYPE (dlhs
),
3157 drhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
,
3158 TREE_TYPE (dlhs
), drhs
);
3160 gimple ds
= gimple_build_debug_bind (dlhs
, drhs
, *stmt
);
3161 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
3164 /* From this point on, the function deals with assignments in between
3165 aggregates when at least one has scalar reductions of some of its
3166 components. There are three possible scenarios: Both the LHS and RHS have
3167 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3169 In the first case, we would like to load the LHS components from RHS
3170 components whenever possible. If that is not possible, we would like to
3171 read it directly from the RHS (after updating it by storing in it its own
3172 components). If there are some necessary unscalarized data in the LHS,
3173 those will be loaded by the original assignment too. If neither of these
3174 cases happen, the original statement can be removed. Most of this is done
3175 by load_assign_lhs_subreplacements.
3177 In the second case, we would like to store all RHS scalarized components
3178 directly into LHS and if they cover the aggregate completely, remove the
3179 statement too. In the third case, we want the LHS components to be loaded
3180 directly from the RHS (DSE will remove the original statement if it
3183 This is a bit complex but manageable when types match and when unions do
3184 not cause confusion in a way that we cannot really load a component of LHS
3185 from the RHS or vice versa (the access representing this level can have
3186 subaccesses that are accessible only through a different union field at a
3187 higher level - different from the one used in the examined expression).
3190 Therefore, I specially handle a fourth case, happening when there is a
3191 specific type cast or it is impossible to locate a scalarized subaccess on
3192 the other side of the expression. If that happens, I simply "refresh" the
3193 RHS by storing in it is scalarized components leave the original statement
3194 there to do the copying and then load the scalar replacements of the LHS.
3195 This is what the first branch does. */
3197 if (modify_this_stmt
3198 || gimple_has_volatile_ops (*stmt
)
3199 || contains_vce_or_bfcref_p (rhs
)
3200 || contains_vce_or_bfcref_p (lhs
))
3202 if (access_has_children_p (racc
))
3203 generate_subtree_copies (racc
->first_child
, racc
->base
, 0, 0, 0,
3204 gsi
, false, false, loc
);
3205 if (access_has_children_p (lacc
))
3206 generate_subtree_copies (lacc
->first_child
, lacc
->base
, 0, 0, 0,
3207 gsi
, true, true, loc
);
3208 sra_stats
.separate_lhs_rhs_handling
++;
3210 /* This gimplification must be done after generate_subtree_copies,
3211 lest we insert the subtree copies in the middle of the gimplified
3213 if (force_gimple_rhs
)
3214 rhs
= force_gimple_operand_gsi (&orig_gsi
, rhs
, true, NULL_TREE
,
3215 true, GSI_SAME_STMT
);
3216 if (gimple_assign_rhs1 (*stmt
) != rhs
)
3218 modify_this_stmt
= true;
3219 gimple_assign_set_rhs_from_tree (&orig_gsi
, rhs
);
3220 gcc_assert (*stmt
== gsi_stmt (orig_gsi
));
3223 return modify_this_stmt
? SRA_AM_MODIFIED
: SRA_AM_NONE
;
3227 if (access_has_children_p (lacc
)
3228 && access_has_children_p (racc
)
3229 /* When an access represents an unscalarizable region, it usually
3230 represents accesses with variable offset and thus must not be used
3231 to generate new memory accesses. */
3232 && !lacc
->grp_unscalarizable_region
3233 && !racc
->grp_unscalarizable_region
)
3235 gimple_stmt_iterator orig_gsi
= *gsi
;
3236 enum unscalarized_data_handling refreshed
;
3238 if (lacc
->grp_read
&& !lacc
->grp_covered
)
3239 refreshed
= handle_unscalarized_data_in_subtree (racc
, gsi
);
3241 refreshed
= SRA_UDH_NONE
;
3243 load_assign_lhs_subreplacements (lacc
, racc
, lacc
->offset
,
3244 &orig_gsi
, gsi
, &refreshed
);
3245 if (refreshed
!= SRA_UDH_RIGHT
)
3248 unlink_stmt_vdef (*stmt
);
3249 gsi_remove (&orig_gsi
, true);
3250 release_defs (*stmt
);
3251 sra_stats
.deleted
++;
3252 return SRA_AM_REMOVED
;
3257 if (access_has_children_p (racc
)
3258 && !racc
->grp_unscalarized_data
)
3262 fprintf (dump_file
, "Removing load: ");
3263 print_gimple_stmt (dump_file
, *stmt
, 0, 0);
3265 generate_subtree_copies (racc
->first_child
, lhs
,
3266 racc
->offset
, 0, 0, gsi
,
3268 gcc_assert (*stmt
== gsi_stmt (*gsi
));
3269 unlink_stmt_vdef (*stmt
);
3270 gsi_remove (gsi
, true);
3271 release_defs (*stmt
);
3272 sra_stats
.deleted
++;
3273 return SRA_AM_REMOVED
;
3275 /* Restore the aggregate RHS from its components so the
3276 prevailing aggregate copy does the right thing. */
3277 if (access_has_children_p (racc
))
3278 generate_subtree_copies (racc
->first_child
, racc
->base
, 0, 0, 0,
3279 gsi
, false, false, loc
);
3280 /* Re-load the components of the aggregate copy destination.
3281 But use the RHS aggregate to load from to expose more
3282 optimization opportunities. */
3283 if (access_has_children_p (lacc
))
3284 generate_subtree_copies (lacc
->first_child
, rhs
, lacc
->offset
,
3285 0, 0, gsi
, true, true, loc
);
3292 /* Traverse the function body and all modifications as decided in
3293 analyze_all_variable_accesses. Return true iff the CFG has been
3297 sra_modify_function_body (void)
3299 bool cfg_changed
= false;
3304 gimple_stmt_iterator gsi
= gsi_start_bb (bb
);
3305 while (!gsi_end_p (gsi
))
3307 gimple stmt
= gsi_stmt (gsi
);
3308 enum assignment_mod_result assign_result
;
3309 bool modified
= false, deleted
= false;
3313 switch (gimple_code (stmt
))
3316 t
= gimple_return_retval_ptr (stmt
);
3317 if (*t
!= NULL_TREE
)
3318 modified
|= sra_modify_expr (t
, &gsi
, false);
3322 assign_result
= sra_modify_assign (&stmt
, &gsi
);
3323 modified
|= assign_result
== SRA_AM_MODIFIED
;
3324 deleted
= assign_result
== SRA_AM_REMOVED
;
3328 /* Operands must be processed before the lhs. */
3329 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
3331 t
= gimple_call_arg_ptr (stmt
, i
);
3332 modified
|= sra_modify_expr (t
, &gsi
, false);
3335 if (gimple_call_lhs (stmt
))
3337 t
= gimple_call_lhs_ptr (stmt
);
3338 modified
|= sra_modify_expr (t
, &gsi
, true);
3343 for (i
= 0; i
< gimple_asm_ninputs (stmt
); i
++)
3345 t
= &TREE_VALUE (gimple_asm_input_op (stmt
, i
));
3346 modified
|= sra_modify_expr (t
, &gsi
, false);
3348 for (i
= 0; i
< gimple_asm_noutputs (stmt
); i
++)
3350 t
= &TREE_VALUE (gimple_asm_output_op (stmt
, i
));
3351 modified
|= sra_modify_expr (t
, &gsi
, true);
3362 if (maybe_clean_eh_stmt (stmt
)
3363 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
3374 /* Generate statements initializing scalar replacements of parts of function
3378 initialize_parameter_reductions (void)
3380 gimple_stmt_iterator gsi
;
3381 gimple_seq seq
= NULL
;
3384 gsi
= gsi_start (seq
);
3385 for (parm
= DECL_ARGUMENTS (current_function_decl
);
3387 parm
= DECL_CHAIN (parm
))
3389 vec
<access_p
> *access_vec
;
3390 struct access
*access
;
3392 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
3394 access_vec
= get_base_access_vector (parm
);
3398 for (access
= (*access_vec
)[0];
3400 access
= access
->next_grp
)
3401 generate_subtree_copies (access
, parm
, 0, 0, 0, &gsi
, true, true,
3402 EXPR_LOCATION (parm
));
3405 seq
= gsi_seq (gsi
);
3407 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR
), seq
);
3410 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3411 it reveals there are components of some aggregates to be scalarized, it runs
3412 the required transformations. */
3414 perform_intra_sra (void)
3419 if (!find_var_candidates ())
3422 if (!scan_function ())
3425 if (!analyze_all_variable_accesses ())
3428 if (sra_modify_function_body ())
3429 ret
= TODO_update_ssa
| TODO_cleanup_cfg
;
3431 ret
= TODO_update_ssa
;
3432 initialize_parameter_reductions ();
3434 statistics_counter_event (cfun
, "Scalar replacements created",
3435 sra_stats
.replacements
);
3436 statistics_counter_event (cfun
, "Modified expressions", sra_stats
.exprs
);
3437 statistics_counter_event (cfun
, "Subtree copy stmts",
3438 sra_stats
.subtree_copies
);
3439 statistics_counter_event (cfun
, "Subreplacement stmts",
3440 sra_stats
.subreplacements
);
3441 statistics_counter_event (cfun
, "Deleted stmts", sra_stats
.deleted
);
3442 statistics_counter_event (cfun
, "Separate LHS and RHS handling",
3443 sra_stats
.separate_lhs_rhs_handling
);
3446 sra_deinitialize ();
3450 /* Perform early intraprocedural SRA. */
3452 early_intra_sra (void)
3454 sra_mode
= SRA_MODE_EARLY_INTRA
;
3455 return perform_intra_sra ();
3458 /* Perform "late" intraprocedural SRA. */
3460 late_intra_sra (void)
3462 sra_mode
= SRA_MODE_INTRA
;
3463 return perform_intra_sra ();
3468 gate_intra_sra (void)
3470 return flag_tree_sra
!= 0 && dbg_cnt (tree_sra
);
3476 const pass_data pass_data_sra_early
=
3478 GIMPLE_PASS
, /* type */
3480 OPTGROUP_NONE
, /* optinfo_flags */
3481 true, /* has_gate */
3482 true, /* has_execute */
3483 TV_TREE_SRA
, /* tv_id */
3484 ( PROP_cfg
| PROP_ssa
), /* properties_required */
3485 0, /* properties_provided */
3486 0, /* properties_destroyed */
3487 0, /* todo_flags_start */
3488 ( TODO_update_ssa
| TODO_verify_ssa
), /* todo_flags_finish */
3491 class pass_sra_early
: public gimple_opt_pass
3494 pass_sra_early (gcc::context
*ctxt
)
3495 : gimple_opt_pass (pass_data_sra_early
, ctxt
)
3498 /* opt_pass methods: */
3499 bool gate () { return gate_intra_sra (); }
3500 unsigned int execute () { return early_intra_sra (); }
3502 }; // class pass_sra_early
3507 make_pass_sra_early (gcc::context
*ctxt
)
3509 return new pass_sra_early (ctxt
);
3514 const pass_data pass_data_sra
=
3516 GIMPLE_PASS
, /* type */
3518 OPTGROUP_NONE
, /* optinfo_flags */
3519 true, /* has_gate */
3520 true, /* has_execute */
3521 TV_TREE_SRA
, /* tv_id */
3522 ( PROP_cfg
| PROP_ssa
), /* properties_required */
3523 0, /* properties_provided */
3524 0, /* properties_destroyed */
3525 TODO_update_address_taken
, /* todo_flags_start */
3526 ( TODO_update_ssa
| TODO_verify_ssa
), /* todo_flags_finish */
3529 class pass_sra
: public gimple_opt_pass
3532 pass_sra (gcc::context
*ctxt
)
3533 : gimple_opt_pass (pass_data_sra
, ctxt
)
3536 /* opt_pass methods: */
3537 bool gate () { return gate_intra_sra (); }
3538 unsigned int execute () { return late_intra_sra (); }
3540 }; // class pass_sra
3545 make_pass_sra (gcc::context
*ctxt
)
3547 return new pass_sra (ctxt
);
3551 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3555 is_unused_scalar_param (tree parm
)
3558 return (is_gimple_reg (parm
)
3559 && (!(name
= ssa_default_def (cfun
, parm
))
3560 || has_zero_uses (name
)));
3563 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3564 examine whether there are any direct or otherwise infeasible ones. If so,
3565 return true, otherwise return false. PARM must be a gimple register with a
3566 non-NULL default definition. */
3569 ptr_parm_has_direct_uses (tree parm
)
3571 imm_use_iterator ui
;
3573 tree name
= ssa_default_def (cfun
, parm
);
3576 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
3579 use_operand_p use_p
;
3581 if (is_gimple_debug (stmt
))
3584 /* Valid uses include dereferences on the lhs and the rhs. */
3585 if (gimple_has_lhs (stmt
))
3587 tree lhs
= gimple_get_lhs (stmt
);
3588 while (handled_component_p (lhs
))
3589 lhs
= TREE_OPERAND (lhs
, 0);
3590 if (TREE_CODE (lhs
) == MEM_REF
3591 && TREE_OPERAND (lhs
, 0) == name
3592 && integer_zerop (TREE_OPERAND (lhs
, 1))
3593 && types_compatible_p (TREE_TYPE (lhs
),
3594 TREE_TYPE (TREE_TYPE (name
)))
3595 && !TREE_THIS_VOLATILE (lhs
))
3598 if (gimple_assign_single_p (stmt
))
3600 tree rhs
= gimple_assign_rhs1 (stmt
);
3601 while (handled_component_p (rhs
))
3602 rhs
= TREE_OPERAND (rhs
, 0);
3603 if (TREE_CODE (rhs
) == MEM_REF
3604 && TREE_OPERAND (rhs
, 0) == name
3605 && integer_zerop (TREE_OPERAND (rhs
, 1))
3606 && types_compatible_p (TREE_TYPE (rhs
),
3607 TREE_TYPE (TREE_TYPE (name
)))
3608 && !TREE_THIS_VOLATILE (rhs
))
3611 else if (is_gimple_call (stmt
))
3614 for (i
= 0; i
< gimple_call_num_args (stmt
); ++i
)
3616 tree arg
= gimple_call_arg (stmt
, i
);
3617 while (handled_component_p (arg
))
3618 arg
= TREE_OPERAND (arg
, 0);
3619 if (TREE_CODE (arg
) == MEM_REF
3620 && TREE_OPERAND (arg
, 0) == name
3621 && integer_zerop (TREE_OPERAND (arg
, 1))
3622 && types_compatible_p (TREE_TYPE (arg
),
3623 TREE_TYPE (TREE_TYPE (name
)))
3624 && !TREE_THIS_VOLATILE (arg
))
3629 /* If the number of valid uses does not match the number of
3630 uses in this stmt there is an unhandled use. */
3631 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
3638 BREAK_FROM_IMM_USE_STMT (ui
);
3644 /* Identify candidates for reduction for IPA-SRA based on their type and mark
3645 them in candidate_bitmap. Note that these do not necessarily include
3646 parameter which are unused and thus can be removed. Return true iff any
3647 such candidate has been found. */
3650 find_param_candidates (void)
3657 for (parm
= DECL_ARGUMENTS (current_function_decl
);
3659 parm
= DECL_CHAIN (parm
))
3661 tree type
= TREE_TYPE (parm
);
3666 if (TREE_THIS_VOLATILE (parm
)
3667 || TREE_ADDRESSABLE (parm
)
3668 || (!is_gimple_reg_type (type
) && is_va_list_type (type
)))
3671 if (is_unused_scalar_param (parm
))
3677 if (POINTER_TYPE_P (type
))
3679 type
= TREE_TYPE (type
);
3681 if (TREE_CODE (type
) == FUNCTION_TYPE
3682 || TYPE_VOLATILE (type
)
3683 || (TREE_CODE (type
) == ARRAY_TYPE
3684 && TYPE_NONALIASED_COMPONENT (type
))
3685 || !is_gimple_reg (parm
)
3686 || is_va_list_type (type
)
3687 || ptr_parm_has_direct_uses (parm
))
3690 else if (!AGGREGATE_TYPE_P (type
))
3693 if (!COMPLETE_TYPE_P (type
)
3694 || !host_integerp (TYPE_SIZE (type
), 1)
3695 || tree_low_cst (TYPE_SIZE (type
), 1) == 0
3696 || (AGGREGATE_TYPE_P (type
)
3697 && type_internals_preclude_sra_p (type
, &msg
)))
3700 bitmap_set_bit (candidate_bitmap
, DECL_UID (parm
));
3701 slot
= candidates
.find_slot_with_hash (parm
, DECL_UID (parm
), INSERT
);
3705 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3707 fprintf (dump_file
, "Candidate (%d): ", DECL_UID (parm
));
3708 print_generic_expr (dump_file
, parm
, 0);
3709 fprintf (dump_file
, "\n");
3713 func_param_count
= count
;
3717 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
3721 mark_maybe_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef ATTRIBUTE_UNUSED
,
3724 struct access
*repr
= (struct access
*) data
;
3726 repr
->grp_maybe_modified
= 1;
3730 /* Analyze what representatives (in linked lists accessible from
3731 REPRESENTATIVES) can be modified by side effects of statements in the
3732 current function. */
3735 analyze_modified_params (vec
<access_p
> representatives
)
3739 for (i
= 0; i
< func_param_count
; i
++)
3741 struct access
*repr
;
3743 for (repr
= representatives
[i
];
3745 repr
= repr
->next_grp
)
3747 struct access
*access
;
3751 if (no_accesses_p (repr
))
3753 if (!POINTER_TYPE_P (TREE_TYPE (repr
->base
))
3754 || repr
->grp_maybe_modified
)
3757 ao_ref_init (&ar
, repr
->expr
);
3758 visited
= BITMAP_ALLOC (NULL
);
3759 for (access
= repr
; access
; access
= access
->next_sibling
)
3761 /* All accesses are read ones, otherwise grp_maybe_modified would
3762 be trivially set. */
3763 walk_aliased_vdefs (&ar
, gimple_vuse (access
->stmt
),
3764 mark_maybe_modified
, repr
, &visited
);
3765 if (repr
->grp_maybe_modified
)
3768 BITMAP_FREE (visited
);
3773 /* Propagate distances in bb_dereferences in the opposite direction than the
3774 control flow edges, in each step storing the maximum of the current value
3775 and the minimum of all successors. These steps are repeated until the table
3776 stabilizes. Note that BBs which might terminate the functions (according to
3777 final_bbs bitmap) never updated in this way. */
3780 propagate_dereference_distances (void)
3782 vec
<basic_block
> queue
;
3785 queue
.create (last_basic_block_for_function (cfun
));
3786 queue
.quick_push (ENTRY_BLOCK_PTR
);
3789 queue
.quick_push (bb
);
3793 while (!queue
.is_empty ())
3797 bool change
= false;
3803 if (bitmap_bit_p (final_bbs
, bb
->index
))
3806 for (i
= 0; i
< func_param_count
; i
++)
3808 int idx
= bb
->index
* func_param_count
+ i
;
3810 HOST_WIDE_INT inh
= 0;
3812 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
3814 int succ_idx
= e
->dest
->index
* func_param_count
+ i
;
3816 if (e
->src
== EXIT_BLOCK_PTR
)
3822 inh
= bb_dereferences
[succ_idx
];
3824 else if (bb_dereferences
[succ_idx
] < inh
)
3825 inh
= bb_dereferences
[succ_idx
];
3828 if (!first
&& bb_dereferences
[idx
] < inh
)
3830 bb_dereferences
[idx
] = inh
;
3835 if (change
&& !bitmap_bit_p (final_bbs
, bb
->index
))
3836 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
3841 e
->src
->aux
= e
->src
;
3842 queue
.quick_push (e
->src
);
3849 /* Dump a dereferences TABLE with heading STR to file F. */
3852 dump_dereferences_table (FILE *f
, const char *str
, HOST_WIDE_INT
*table
)
3856 fprintf (dump_file
, str
);
3857 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR
, EXIT_BLOCK_PTR
, next_bb
)
3859 fprintf (f
, "%4i %i ", bb
->index
, bitmap_bit_p (final_bbs
, bb
->index
));
3860 if (bb
!= EXIT_BLOCK_PTR
)
3863 for (i
= 0; i
< func_param_count
; i
++)
3865 int idx
= bb
->index
* func_param_count
+ i
;
3866 fprintf (f
, " %4" HOST_WIDE_INT_PRINT
"d", table
[idx
]);
3871 fprintf (dump_file
, "\n");
3874 /* Determine what (parts of) parameters passed by reference that are not
3875 assigned to are not certainly dereferenced in this function and thus the
3876 dereferencing cannot be safely moved to the caller without potentially
3877 introducing a segfault. Mark such REPRESENTATIVES as
3878 grp_not_necessarilly_dereferenced.
3880 The dereferenced maximum "distance," i.e. the offset + size of the accessed
3881 part is calculated rather than simple booleans are calculated for each
3882 pointer parameter to handle cases when only a fraction of the whole
3883 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
3886 The maximum dereference distances for each pointer parameter and BB are
3887 already stored in bb_dereference. This routine simply propagates these
3888 values upwards by propagate_dereference_distances and then compares the
3889 distances of individual parameters in the ENTRY BB to the equivalent
3890 distances of each representative of a (fraction of a) parameter. */
3893 analyze_caller_dereference_legality (vec
<access_p
> representatives
)
3897 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3898 dump_dereferences_table (dump_file
,
3899 "Dereference table before propagation:\n",
3902 propagate_dereference_distances ();
3904 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3905 dump_dereferences_table (dump_file
,
3906 "Dereference table after propagation:\n",
3909 for (i
= 0; i
< func_param_count
; i
++)
3911 struct access
*repr
= representatives
[i
];
3912 int idx
= ENTRY_BLOCK_PTR
->index
* func_param_count
+ i
;
3914 if (!repr
|| no_accesses_p (repr
))
3919 if ((repr
->offset
+ repr
->size
) > bb_dereferences
[idx
])
3920 repr
->grp_not_necessarilly_dereferenced
= 1;
3921 repr
= repr
->next_grp
;
3927 /* Return the representative access for the parameter declaration PARM if it is
3928 a scalar passed by reference which is not written to and the pointer value
3929 is not used directly. Thus, if it is legal to dereference it in the caller
3930 and we can rule out modifications through aliases, such parameter should be
3931 turned into one passed by value. Return NULL otherwise. */
3933 static struct access
*
3934 unmodified_by_ref_scalar_representative (tree parm
)
3936 int i
, access_count
;
3937 struct access
*repr
;
3938 vec
<access_p
> *access_vec
;
3940 access_vec
= get_base_access_vector (parm
);
3941 gcc_assert (access_vec
);
3942 repr
= (*access_vec
)[0];
3945 repr
->group_representative
= repr
;
3947 access_count
= access_vec
->length ();
3948 for (i
= 1; i
< access_count
; i
++)
3950 struct access
*access
= (*access_vec
)[i
];
3953 access
->group_representative
= repr
;
3954 access
->next_sibling
= repr
->next_sibling
;
3955 repr
->next_sibling
= access
;
3959 repr
->grp_scalar_ptr
= 1;
3963 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
3964 associated with. REQ_ALIGN is the minimum required alignment. */
3967 access_precludes_ipa_sra_p (struct access
*access
, unsigned int req_align
)
3969 unsigned int exp_align
;
3970 /* Avoid issues such as the second simple testcase in PR 42025. The problem
3971 is incompatible assign in a call statement (and possibly even in asm
3972 statements). This can be relaxed by using a new temporary but only for
3973 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
3974 intraprocedural SRA we deal with this by keeping the old aggregate around,
3975 something we cannot do in IPA-SRA.) */
3977 && (is_gimple_call (access
->stmt
)
3978 || gimple_code (access
->stmt
) == GIMPLE_ASM
))
3981 exp_align
= get_object_alignment (access
->expr
);
3982 if (exp_align
< req_align
)
3989 /* Sort collected accesses for parameter PARM, identify representatives for
3990 each accessed region and link them together. Return NULL if there are
3991 different but overlapping accesses, return the special ptr value meaning
3992 there are no accesses for this parameter if that is the case and return the
3993 first representative otherwise. Set *RO_GRP if there is a group of accesses
3994 with only read (i.e. no write) accesses. */
3996 static struct access
*
3997 splice_param_accesses (tree parm
, bool *ro_grp
)
3999 int i
, j
, access_count
, group_count
;
4000 int agg_size
, total_size
= 0;
4001 struct access
*access
, *res
, **prev_acc_ptr
= &res
;
4002 vec
<access_p
> *access_vec
;
4004 access_vec
= get_base_access_vector (parm
);
4006 return &no_accesses_representant
;
4007 access_count
= access_vec
->length ();
4009 access_vec
->qsort (compare_access_positions
);
4014 while (i
< access_count
)
4018 access
= (*access_vec
)[i
];
4019 modification
= access
->write
;
4020 if (access_precludes_ipa_sra_p (access
, TYPE_ALIGN (access
->type
)))
4022 a1_alias_type
= reference_alias_ptr_type (access
->expr
);
4024 /* Access is about to become group representative unless we find some
4025 nasty overlap which would preclude us from breaking this parameter
4029 while (j
< access_count
)
4031 struct access
*ac2
= (*access_vec
)[j
];
4032 if (ac2
->offset
!= access
->offset
)
4034 /* All or nothing law for parameters. */
4035 if (access
->offset
+ access
->size
> ac2
->offset
)
4040 else if (ac2
->size
!= access
->size
)
4043 if (access_precludes_ipa_sra_p (ac2
, TYPE_ALIGN (access
->type
))
4044 || (ac2
->type
!= access
->type
4045 && (TREE_ADDRESSABLE (ac2
->type
)
4046 || TREE_ADDRESSABLE (access
->type
)))
4047 || (reference_alias_ptr_type (ac2
->expr
) != a1_alias_type
))
4050 modification
|= ac2
->write
;
4051 ac2
->group_representative
= access
;
4052 ac2
->next_sibling
= access
->next_sibling
;
4053 access
->next_sibling
= ac2
;
4058 access
->grp_maybe_modified
= modification
;
4061 *prev_acc_ptr
= access
;
4062 prev_acc_ptr
= &access
->next_grp
;
4063 total_size
+= access
->size
;
4067 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4068 agg_size
= tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm
))), 1);
4070 agg_size
= tree_low_cst (TYPE_SIZE (TREE_TYPE (parm
)), 1);
4071 if (total_size
>= agg_size
)
4074 gcc_assert (group_count
> 0);
4078 /* Decide whether parameters with representative accesses given by REPR should
4079 be reduced into components. */
4082 decide_one_param_reduction (struct access
*repr
)
4084 int total_size
, cur_parm_size
, agg_size
, new_param_count
, parm_size_limit
;
4089 cur_parm_size
= tree_low_cst (TYPE_SIZE (TREE_TYPE (parm
)), 1);
4090 gcc_assert (cur_parm_size
> 0);
4092 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4095 agg_size
= tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm
))), 1);
4100 agg_size
= cur_parm_size
;
4106 fprintf (dump_file
, "Evaluating PARAM group sizes for ");
4107 print_generic_expr (dump_file
, parm
, 0);
4108 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (parm
));
4109 for (acc
= repr
; acc
; acc
= acc
->next_grp
)
4110 dump_access (dump_file
, acc
, true);
4114 new_param_count
= 0;
4116 for (; repr
; repr
= repr
->next_grp
)
4118 gcc_assert (parm
== repr
->base
);
4120 /* Taking the address of a non-addressable field is verboten. */
4121 if (by_ref
&& repr
->non_addressable
)
4124 /* Do not decompose a non-BLKmode param in a way that would
4125 create BLKmode params. Especially for by-reference passing
4126 (thus, pointer-type param) this is hardly worthwhile. */
4127 if (DECL_MODE (parm
) != BLKmode
4128 && TYPE_MODE (repr
->type
) == BLKmode
)
4131 if (!by_ref
|| (!repr
->grp_maybe_modified
4132 && !repr
->grp_not_necessarilly_dereferenced
))
4133 total_size
+= repr
->size
;
4135 total_size
+= cur_parm_size
;
4140 gcc_assert (new_param_count
> 0);
4142 if (optimize_function_for_size_p (cfun
))
4143 parm_size_limit
= cur_parm_size
;
4145 parm_size_limit
= (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR
)
4148 if (total_size
< agg_size
4149 && total_size
<= parm_size_limit
)
4152 fprintf (dump_file
, " ....will be split into %i components\n",
4154 return new_param_count
;
4160 /* The order of the following enums is important, we need to do extra work for
4161 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4162 enum ipa_splicing_result
{ NO_GOOD_ACCESS
, UNUSED_PARAMS
, BY_VAL_ACCESSES
,
4163 MODIF_BY_REF_ACCESSES
, UNMODIF_BY_REF_ACCESSES
};
4165 /* Identify representatives of all accesses to all candidate parameters for
4166 IPA-SRA. Return result based on what representatives have been found. */
4168 static enum ipa_splicing_result
4169 splice_all_param_accesses (vec
<access_p
> &representatives
)
4171 enum ipa_splicing_result result
= NO_GOOD_ACCESS
;
4173 struct access
*repr
;
4175 representatives
.create (func_param_count
);
4177 for (parm
= DECL_ARGUMENTS (current_function_decl
);
4179 parm
= DECL_CHAIN (parm
))
4181 if (is_unused_scalar_param (parm
))
4183 representatives
.quick_push (&no_accesses_representant
);
4184 if (result
== NO_GOOD_ACCESS
)
4185 result
= UNUSED_PARAMS
;
4187 else if (POINTER_TYPE_P (TREE_TYPE (parm
))
4188 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm
)))
4189 && bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
4191 repr
= unmodified_by_ref_scalar_representative (parm
);
4192 representatives
.quick_push (repr
);
4194 result
= UNMODIF_BY_REF_ACCESSES
;
4196 else if (bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
4198 bool ro_grp
= false;
4199 repr
= splice_param_accesses (parm
, &ro_grp
);
4200 representatives
.quick_push (repr
);
4202 if (repr
&& !no_accesses_p (repr
))
4204 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4207 result
= UNMODIF_BY_REF_ACCESSES
;
4208 else if (result
< MODIF_BY_REF_ACCESSES
)
4209 result
= MODIF_BY_REF_ACCESSES
;
4211 else if (result
< BY_VAL_ACCESSES
)
4212 result
= BY_VAL_ACCESSES
;
4214 else if (no_accesses_p (repr
) && (result
== NO_GOOD_ACCESS
))
4215 result
= UNUSED_PARAMS
;
4218 representatives
.quick_push (NULL
);
4221 if (result
== NO_GOOD_ACCESS
)
4223 representatives
.release ();
4224 return NO_GOOD_ACCESS
;
4230 /* Return the index of BASE in PARMS. Abort if it is not found. */
4233 get_param_index (tree base
, vec
<tree
> parms
)
4237 len
= parms
.length ();
4238 for (i
= 0; i
< len
; i
++)
4239 if (parms
[i
] == base
)
4244 /* Convert the decisions made at the representative level into compact
4245 parameter adjustments. REPRESENTATIVES are pointers to first
4246 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4247 final number of adjustments. */
4249 static ipa_parm_adjustment_vec
4250 turn_representatives_into_adjustments (vec
<access_p
> representatives
,
4251 int adjustments_count
)
4254 ipa_parm_adjustment_vec adjustments
;
4258 gcc_assert (adjustments_count
> 0);
4259 parms
= ipa_get_vector_of_formal_parms (current_function_decl
);
4260 adjustments
.create (adjustments_count
);
4261 parm
= DECL_ARGUMENTS (current_function_decl
);
4262 for (i
= 0; i
< func_param_count
; i
++, parm
= DECL_CHAIN (parm
))
4264 struct access
*repr
= representatives
[i
];
4266 if (!repr
|| no_accesses_p (repr
))
4268 struct ipa_parm_adjustment adj
;
4270 memset (&adj
, 0, sizeof (adj
));
4271 adj
.base_index
= get_param_index (parm
, parms
);
4276 adj
.remove_param
= 1;
4277 adjustments
.quick_push (adj
);
4281 struct ipa_parm_adjustment adj
;
4282 int index
= get_param_index (parm
, parms
);
4284 for (; repr
; repr
= repr
->next_grp
)
4286 memset (&adj
, 0, sizeof (adj
));
4287 gcc_assert (repr
->base
== parm
);
4288 adj
.base_index
= index
;
4289 adj
.base
= repr
->base
;
4290 adj
.type
= repr
->type
;
4291 adj
.alias_ptr_type
= reference_alias_ptr_type (repr
->expr
);
4292 adj
.offset
= repr
->offset
;
4293 adj
.by_ref
= (POINTER_TYPE_P (TREE_TYPE (repr
->base
))
4294 && (repr
->grp_maybe_modified
4295 || repr
->grp_not_necessarilly_dereferenced
));
4296 adjustments
.quick_push (adj
);
4304 /* Analyze the collected accesses and produce a plan what to do with the
4305 parameters in the form of adjustments, NULL meaning nothing. */
4307 static ipa_parm_adjustment_vec
4308 analyze_all_param_acesses (void)
4310 enum ipa_splicing_result repr_state
;
4311 bool proceed
= false;
4312 int i
, adjustments_count
= 0;
4313 vec
<access_p
> representatives
;
4314 ipa_parm_adjustment_vec adjustments
;
4316 repr_state
= splice_all_param_accesses (representatives
);
4317 if (repr_state
== NO_GOOD_ACCESS
)
4318 return ipa_parm_adjustment_vec ();
4320 /* If there are any parameters passed by reference which are not modified
4321 directly, we need to check whether they can be modified indirectly. */
4322 if (repr_state
== UNMODIF_BY_REF_ACCESSES
)
4324 analyze_caller_dereference_legality (representatives
);
4325 analyze_modified_params (representatives
);
4328 for (i
= 0; i
< func_param_count
; i
++)
4330 struct access
*repr
= representatives
[i
];
4332 if (repr
&& !no_accesses_p (repr
))
4334 if (repr
->grp_scalar_ptr
)
4336 adjustments_count
++;
4337 if (repr
->grp_not_necessarilly_dereferenced
4338 || repr
->grp_maybe_modified
)
4339 representatives
[i
] = NULL
;
4343 sra_stats
.scalar_by_ref_to_by_val
++;
4348 int new_components
= decide_one_param_reduction (repr
);
4350 if (new_components
== 0)
4352 representatives
[i
] = NULL
;
4353 adjustments_count
++;
4357 adjustments_count
+= new_components
;
4358 sra_stats
.aggregate_params_reduced
++;
4359 sra_stats
.param_reductions_created
+= new_components
;
4366 if (no_accesses_p (repr
))
4369 sra_stats
.deleted_unused_parameters
++;
4371 adjustments_count
++;
4375 if (!proceed
&& dump_file
)
4376 fprintf (dump_file
, "NOT proceeding to change params.\n");
4379 adjustments
= turn_representatives_into_adjustments (representatives
,
4382 adjustments
= ipa_parm_adjustment_vec ();
4384 representatives
.release ();
4388 /* If a parameter replacement identified by ADJ does not yet exist in the form
4389 of declaration, create it and record it, otherwise return the previously
4393 get_replaced_param_substitute (struct ipa_parm_adjustment
*adj
)
4396 if (!adj
->new_ssa_base
)
4398 char *pretty_name
= make_fancy_name (adj
->base
);
4400 repl
= create_tmp_reg (TREE_TYPE (adj
->base
), "ISR");
4401 DECL_NAME (repl
) = get_identifier (pretty_name
);
4402 obstack_free (&name_obstack
, pretty_name
);
4404 adj
->new_ssa_base
= repl
;
4407 repl
= adj
->new_ssa_base
;
4411 /* Find the first adjustment for a particular parameter BASE in a vector of
4412 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4415 static struct ipa_parm_adjustment
*
4416 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments
, tree base
)
4420 len
= adjustments
.length ();
4421 for (i
= 0; i
< len
; i
++)
4423 struct ipa_parm_adjustment
*adj
;
4425 adj
= &adjustments
[i
];
4426 if (!adj
->copy_param
&& adj
->base
== base
)
4433 /* If the statement STMT defines an SSA_NAME of a parameter which is to be
4434 removed because its value is not used, replace the SSA_NAME with a one
4435 relating to a created VAR_DECL together all of its uses and return true.
4436 ADJUSTMENTS is a pointer to an adjustments vector. */
4439 replace_removed_params_ssa_names (gimple stmt
,
4440 ipa_parm_adjustment_vec adjustments
)
4442 struct ipa_parm_adjustment
*adj
;
4443 tree lhs
, decl
, repl
, name
;
4445 if (gimple_code (stmt
) == GIMPLE_PHI
)
4446 lhs
= gimple_phi_result (stmt
);
4447 else if (is_gimple_assign (stmt
))
4448 lhs
= gimple_assign_lhs (stmt
);
4449 else if (is_gimple_call (stmt
))
4450 lhs
= gimple_call_lhs (stmt
);
4454 if (TREE_CODE (lhs
) != SSA_NAME
)
4457 decl
= SSA_NAME_VAR (lhs
);
4458 if (decl
== NULL_TREE
4459 || TREE_CODE (decl
) != PARM_DECL
)
4462 adj
= get_adjustment_for_base (adjustments
, decl
);
4466 repl
= get_replaced_param_substitute (adj
);
4467 name
= make_ssa_name (repl
, stmt
);
4471 fprintf (dump_file
, "replacing an SSA name of a removed param ");
4472 print_generic_expr (dump_file
, lhs
, 0);
4473 fprintf (dump_file
, " with ");
4474 print_generic_expr (dump_file
, name
, 0);
4475 fprintf (dump_file
, "\n");
4478 if (is_gimple_assign (stmt
))
4479 gimple_assign_set_lhs (stmt
, name
);
4480 else if (is_gimple_call (stmt
))
4481 gimple_call_set_lhs (stmt
, name
);
4483 gimple_phi_set_result (stmt
, name
);
4485 replace_uses_by (lhs
, name
);
4486 release_ssa_name (lhs
);
4490 /* If the expression *EXPR should be replaced by a reduction of a parameter, do
4491 so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
4492 specifies whether the function should care about type incompatibility the
4493 current and new expressions. If it is false, the function will leave
4494 incompatibility issues to the caller. Return true iff the expression
4498 sra_ipa_modify_expr (tree
*expr
, bool convert
,
4499 ipa_parm_adjustment_vec adjustments
)
4502 struct ipa_parm_adjustment
*adj
, *cand
= NULL
;
4503 HOST_WIDE_INT offset
, size
, max_size
;
4506 len
= adjustments
.length ();
4508 if (TREE_CODE (*expr
) == BIT_FIELD_REF
4509 || TREE_CODE (*expr
) == IMAGPART_EXPR
4510 || TREE_CODE (*expr
) == REALPART_EXPR
)
4512 expr
= &TREE_OPERAND (*expr
, 0);
4516 base
= get_ref_base_and_extent (*expr
, &offset
, &size
, &max_size
);
4517 if (!base
|| size
== -1 || max_size
== -1)
4520 if (TREE_CODE (base
) == MEM_REF
)
4522 offset
+= mem_ref_offset (base
).low
* BITS_PER_UNIT
;
4523 base
= TREE_OPERAND (base
, 0);
4526 base
= get_ssa_base_param (base
);
4527 if (!base
|| TREE_CODE (base
) != PARM_DECL
)
4530 for (i
= 0; i
< len
; i
++)
4532 adj
= &adjustments
[i
];
4534 if (adj
->base
== base
4535 && (adj
->offset
== offset
|| adj
->remove_param
))
4541 if (!cand
|| cand
->copy_param
|| cand
->remove_param
)
4545 src
= build_simple_mem_ref (cand
->reduction
);
4547 src
= cand
->reduction
;
4549 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4551 fprintf (dump_file
, "About to replace expr ");
4552 print_generic_expr (dump_file
, *expr
, 0);
4553 fprintf (dump_file
, " with ");
4554 print_generic_expr (dump_file
, src
, 0);
4555 fprintf (dump_file
, "\n");
4558 if (convert
&& !useless_type_conversion_p (TREE_TYPE (*expr
), cand
->type
))
4560 tree vce
= build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (*expr
), src
);
4568 /* If the statement pointed to by STMT_PTR contains any expressions that need
4569 to replaced with a different one as noted by ADJUSTMENTS, do so. Handle any
4570 potential type incompatibilities (GSI is used to accommodate conversion
4571 statements and must point to the statement). Return true iff the statement
4575 sra_ipa_modify_assign (gimple
*stmt_ptr
, gimple_stmt_iterator
*gsi
,
4576 ipa_parm_adjustment_vec adjustments
)
4578 gimple stmt
= *stmt_ptr
;
4579 tree
*lhs_p
, *rhs_p
;
4582 if (!gimple_assign_single_p (stmt
))
4585 rhs_p
= gimple_assign_rhs1_ptr (stmt
);
4586 lhs_p
= gimple_assign_lhs_ptr (stmt
);
4588 any
= sra_ipa_modify_expr (rhs_p
, false, adjustments
);
4589 any
|= sra_ipa_modify_expr (lhs_p
, false, adjustments
);
4592 tree new_rhs
= NULL_TREE
;
4594 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p
), TREE_TYPE (*rhs_p
)))
4596 if (TREE_CODE (*rhs_p
) == CONSTRUCTOR
)
4598 /* V_C_Es of constructors can cause trouble (PR 42714). */
4599 if (is_gimple_reg_type (TREE_TYPE (*lhs_p
)))
4600 *rhs_p
= build_zero_cst (TREE_TYPE (*lhs_p
));
4602 *rhs_p
= build_constructor (TREE_TYPE (*lhs_p
),
4606 new_rhs
= fold_build1_loc (gimple_location (stmt
),
4607 VIEW_CONVERT_EXPR
, TREE_TYPE (*lhs_p
),
4610 else if (REFERENCE_CLASS_P (*rhs_p
)
4611 && is_gimple_reg_type (TREE_TYPE (*lhs_p
))
4612 && !is_gimple_reg (*lhs_p
))
4613 /* This can happen when an assignment in between two single field
4614 structures is turned into an assignment in between two pointers to
4615 scalars (PR 42237). */
4620 tree tmp
= force_gimple_operand_gsi (gsi
, new_rhs
, true, NULL_TREE
,
4621 true, GSI_SAME_STMT
);
4623 gimple_assign_set_rhs_from_tree (gsi
, tmp
);
4632 /* Traverse the function body and all modifications as described in
4633 ADJUSTMENTS. Return true iff the CFG has been changed. */
4636 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments
)
4638 bool cfg_changed
= false;
4643 gimple_stmt_iterator gsi
;
4645 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4646 replace_removed_params_ssa_names (gsi_stmt (gsi
), adjustments
);
4648 gsi
= gsi_start_bb (bb
);
4649 while (!gsi_end_p (gsi
))
4651 gimple stmt
= gsi_stmt (gsi
);
4652 bool modified
= false;
4656 switch (gimple_code (stmt
))
4659 t
= gimple_return_retval_ptr (stmt
);
4660 if (*t
!= NULL_TREE
)
4661 modified
|= sra_ipa_modify_expr (t
, true, adjustments
);
4665 modified
|= sra_ipa_modify_assign (&stmt
, &gsi
, adjustments
);
4666 modified
|= replace_removed_params_ssa_names (stmt
, adjustments
);
4670 /* Operands must be processed before the lhs. */
4671 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
4673 t
= gimple_call_arg_ptr (stmt
, i
);
4674 modified
|= sra_ipa_modify_expr (t
, true, adjustments
);
4677 if (gimple_call_lhs (stmt
))
4679 t
= gimple_call_lhs_ptr (stmt
);
4680 modified
|= sra_ipa_modify_expr (t
, false, adjustments
);
4681 modified
|= replace_removed_params_ssa_names (stmt
,
4687 for (i
= 0; i
< gimple_asm_ninputs (stmt
); i
++)
4689 t
= &TREE_VALUE (gimple_asm_input_op (stmt
, i
));
4690 modified
|= sra_ipa_modify_expr (t
, true, adjustments
);
4692 for (i
= 0; i
< gimple_asm_noutputs (stmt
); i
++)
4694 t
= &TREE_VALUE (gimple_asm_output_op (stmt
, i
));
4695 modified
|= sra_ipa_modify_expr (t
, false, adjustments
);
4706 if (maybe_clean_eh_stmt (stmt
)
4707 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
4717 /* Call gimple_debug_bind_reset_value on all debug statements describing
4718 gimple register parameters that are being removed or replaced. */
4721 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments
)
4724 gimple_stmt_iterator
*gsip
= NULL
, gsi
;
4726 if (MAY_HAVE_DEBUG_STMTS
&& single_succ_p (ENTRY_BLOCK_PTR
))
4728 gsi
= gsi_after_labels (single_succ (ENTRY_BLOCK_PTR
));
4731 len
= adjustments
.length ();
4732 for (i
= 0; i
< len
; i
++)
4734 struct ipa_parm_adjustment
*adj
;
4735 imm_use_iterator ui
;
4736 gimple stmt
, def_temp
;
4737 tree name
, vexpr
, copy
= NULL_TREE
;
4738 use_operand_p use_p
;
4740 adj
= &adjustments
[i
];
4741 if (adj
->copy_param
|| !is_gimple_reg (adj
->base
))
4743 name
= ssa_default_def (cfun
, adj
->base
);
4746 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
4748 if (gimple_clobber_p (stmt
))
4750 gimple_stmt_iterator cgsi
= gsi_for_stmt (stmt
);
4751 unlink_stmt_vdef (stmt
);
4752 gsi_remove (&cgsi
, true);
4753 release_defs (stmt
);
4756 /* All other users must have been removed by
4757 ipa_sra_modify_function_body. */
4758 gcc_assert (is_gimple_debug (stmt
));
4759 if (vexpr
== NULL
&& gsip
!= NULL
)
4761 gcc_assert (TREE_CODE (adj
->base
) == PARM_DECL
);
4762 vexpr
= make_node (DEBUG_EXPR_DECL
);
4763 def_temp
= gimple_build_debug_source_bind (vexpr
, adj
->base
,
4765 DECL_ARTIFICIAL (vexpr
) = 1;
4766 TREE_TYPE (vexpr
) = TREE_TYPE (name
);
4767 DECL_MODE (vexpr
) = DECL_MODE (adj
->base
);
4768 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
4772 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
4773 SET_USE (use_p
, vexpr
);
4776 gimple_debug_bind_reset_value (stmt
);
4779 /* Create a VAR_DECL for debug info purposes. */
4780 if (!DECL_IGNORED_P (adj
->base
))
4782 copy
= build_decl (DECL_SOURCE_LOCATION (current_function_decl
),
4783 VAR_DECL
, DECL_NAME (adj
->base
),
4784 TREE_TYPE (adj
->base
));
4785 if (DECL_PT_UID_SET_P (adj
->base
))
4786 SET_DECL_PT_UID (copy
, DECL_PT_UID (adj
->base
));
4787 TREE_ADDRESSABLE (copy
) = TREE_ADDRESSABLE (adj
->base
);
4788 TREE_READONLY (copy
) = TREE_READONLY (adj
->base
);
4789 TREE_THIS_VOLATILE (copy
) = TREE_THIS_VOLATILE (adj
->base
);
4790 DECL_GIMPLE_REG_P (copy
) = DECL_GIMPLE_REG_P (adj
->base
);
4791 DECL_ARTIFICIAL (copy
) = DECL_ARTIFICIAL (adj
->base
);
4792 DECL_IGNORED_P (copy
) = DECL_IGNORED_P (adj
->base
);
4793 DECL_ABSTRACT_ORIGIN (copy
) = DECL_ORIGIN (adj
->base
);
4794 DECL_SEEN_IN_BIND_EXPR_P (copy
) = 1;
4795 SET_DECL_RTL (copy
, 0);
4796 TREE_USED (copy
) = 1;
4797 DECL_CONTEXT (copy
) = current_function_decl
;
4798 add_local_decl (cfun
, copy
);
4800 BLOCK_VARS (DECL_INITIAL (current_function_decl
));
4801 BLOCK_VARS (DECL_INITIAL (current_function_decl
)) = copy
;
4803 if (gsip
!= NULL
&& copy
&& target_for_debug_bind (adj
->base
))
4805 gcc_assert (TREE_CODE (adj
->base
) == PARM_DECL
);
4807 def_temp
= gimple_build_debug_bind (copy
, vexpr
, NULL
);
4809 def_temp
= gimple_build_debug_source_bind (copy
, adj
->base
,
4811 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
4816 /* Return false iff all callers have at least as many actual arguments as there
4817 are formal parameters in the current function. */
4820 not_all_callers_have_enough_arguments_p (struct cgraph_node
*node
,
4821 void *data ATTRIBUTE_UNUSED
)
4823 struct cgraph_edge
*cs
;
4824 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4825 if (!callsite_has_enough_arguments_p (cs
->call_stmt
))
4831 /* Convert all callers of NODE. */
4834 convert_callers_for_node (struct cgraph_node
*node
,
4837 ipa_parm_adjustment_vec
*adjustments
= (ipa_parm_adjustment_vec
*) data
;
4838 bitmap recomputed_callers
= BITMAP_ALLOC (NULL
);
4839 struct cgraph_edge
*cs
;
4841 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4843 push_cfun (DECL_STRUCT_FUNCTION (cs
->caller
->decl
));
4846 fprintf (dump_file
, "Adjusting call %s/%i -> %s/%i\n",
4847 xstrdup (cgraph_node_name (cs
->caller
)),
4849 xstrdup (cgraph_node_name (cs
->callee
)),
4852 ipa_modify_call_arguments (cs
, cs
->call_stmt
, *adjustments
);
4857 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4858 if (bitmap_set_bit (recomputed_callers
, cs
->caller
->uid
)
4859 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs
->caller
->decl
)))
4860 compute_inline_parameters (cs
->caller
, true);
4861 BITMAP_FREE (recomputed_callers
);
4866 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
4869 convert_callers (struct cgraph_node
*node
, tree old_decl
,
4870 ipa_parm_adjustment_vec adjustments
)
4872 basic_block this_block
;
4874 cgraph_for_node_and_aliases (node
, convert_callers_for_node
,
4875 &adjustments
, false);
4877 if (!encountered_recursive_call
)
4880 FOR_EACH_BB (this_block
)
4882 gimple_stmt_iterator gsi
;
4884 for (gsi
= gsi_start_bb (this_block
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4886 gimple stmt
= gsi_stmt (gsi
);
4888 if (gimple_code (stmt
) != GIMPLE_CALL
)
4890 call_fndecl
= gimple_call_fndecl (stmt
);
4891 if (call_fndecl
== old_decl
)
4894 fprintf (dump_file
, "Adjusting recursive call");
4895 gimple_call_set_fndecl (stmt
, node
->decl
);
4896 ipa_modify_call_arguments (NULL
, stmt
, adjustments
);
4904 /* Perform all the modification required in IPA-SRA for NODE to have parameters
4905 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
4908 modify_function (struct cgraph_node
*node
, ipa_parm_adjustment_vec adjustments
)
4910 struct cgraph_node
*new_node
;
4912 vec
<cgraph_edge_p
> redirect_callers
= collect_callers_of_node (node
);
4914 rebuild_cgraph_edges ();
4915 free_dominance_info (CDI_DOMINATORS
);
4918 new_node
= cgraph_function_versioning (node
, redirect_callers
,
4920 NULL
, false, NULL
, NULL
, "isra");
4921 redirect_callers
.release ();
4923 push_cfun (DECL_STRUCT_FUNCTION (new_node
->decl
));
4924 ipa_modify_formal_parameters (current_function_decl
, adjustments
, "ISRA");
4925 cfg_changed
= ipa_sra_modify_function_body (adjustments
);
4926 sra_ipa_reset_debug_stmts (adjustments
);
4927 convert_callers (new_node
, node
->decl
, adjustments
);
4928 cgraph_make_node_local (new_node
);
4932 /* If NODE has a caller, return true. */
4935 has_caller_p (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
4942 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
4943 attributes, return true otherwise. NODE is the cgraph node of the current
4947 ipa_sra_preliminary_function_checks (struct cgraph_node
*node
)
4949 if (!cgraph_node_can_be_local_p (node
))
4952 fprintf (dump_file
, "Function not local to this compilation unit.\n");
4956 if (!node
->local
.can_change_signature
)
4959 fprintf (dump_file
, "Function can not change signature.\n");
4963 if (!tree_versionable_function_p (node
->decl
))
4966 fprintf (dump_file
, "Function is not versionable.\n");
4970 if (DECL_VIRTUAL_P (current_function_decl
))
4973 fprintf (dump_file
, "Function is a virtual method.\n");
4977 if ((DECL_COMDAT (node
->decl
) || DECL_EXTERNAL (node
->decl
))
4978 && inline_summary (node
)->size
>= MAX_INLINE_INSNS_AUTO
)
4981 fprintf (dump_file
, "Function too big to be made truly local.\n");
4985 if (!cgraph_for_node_and_aliases (node
, has_caller_p
, NULL
, true))
4989 "Function has no callers in this compilation unit.\n");
4996 fprintf (dump_file
, "Function uses stdarg. \n");
5000 if (TYPE_ATTRIBUTES (TREE_TYPE (node
->decl
)))
5006 /* Perform early interprocedural SRA. */
5009 ipa_early_sra (void)
5011 struct cgraph_node
*node
= cgraph_get_node (current_function_decl
);
5012 ipa_parm_adjustment_vec adjustments
;
5015 if (!ipa_sra_preliminary_function_checks (node
))
5019 sra_mode
= SRA_MODE_EARLY_IPA
;
5021 if (!find_param_candidates ())
5024 fprintf (dump_file
, "Function has no IPA-SRA candidates.\n");
5028 if (cgraph_for_node_and_aliases (node
, not_all_callers_have_enough_arguments_p
,
5032 fprintf (dump_file
, "There are callers with insufficient number of "
5037 bb_dereferences
= XCNEWVEC (HOST_WIDE_INT
,
5039 * last_basic_block_for_function (cfun
));
5040 final_bbs
= BITMAP_ALLOC (NULL
);
5043 if (encountered_apply_args
)
5046 fprintf (dump_file
, "Function calls __builtin_apply_args().\n");
5050 if (encountered_unchangable_recursive_call
)
5053 fprintf (dump_file
, "Function calls itself with insufficient "
5054 "number of arguments.\n");
5058 adjustments
= analyze_all_param_acesses ();
5059 if (!adjustments
.exists ())
5062 ipa_dump_param_adjustments (dump_file
, adjustments
, current_function_decl
);
5064 if (modify_function (node
, adjustments
))
5065 ret
= TODO_update_ssa
| TODO_cleanup_cfg
;
5067 ret
= TODO_update_ssa
;
5068 adjustments
.release ();
5070 statistics_counter_event (cfun
, "Unused parameters deleted",
5071 sra_stats
.deleted_unused_parameters
);
5072 statistics_counter_event (cfun
, "Scalar parameters converted to by-value",
5073 sra_stats
.scalar_by_ref_to_by_val
);
5074 statistics_counter_event (cfun
, "Aggregate parameters broken up",
5075 sra_stats
.aggregate_params_reduced
);
5076 statistics_counter_event (cfun
, "Aggregate parameter components created",
5077 sra_stats
.param_reductions_created
);
5080 BITMAP_FREE (final_bbs
);
5081 free (bb_dereferences
);
5083 sra_deinitialize ();
5087 /* Return if early ipa sra shall be performed. */
5089 ipa_early_sra_gate (void)
5091 return flag_ipa_sra
&& dbg_cnt (eipa_sra
);
5096 const pass_data pass_data_early_ipa_sra
=
5098 GIMPLE_PASS
, /* type */
5099 "eipa_sra", /* name */
5100 OPTGROUP_NONE
, /* optinfo_flags */
5101 true, /* has_gate */
5102 true, /* has_execute */
5103 TV_IPA_SRA
, /* tv_id */
5104 0, /* properties_required */
5105 0, /* properties_provided */
5106 0, /* properties_destroyed */
5107 0, /* todo_flags_start */
5108 TODO_dump_symtab
, /* todo_flags_finish */
5111 class pass_early_ipa_sra
: public gimple_opt_pass
5114 pass_early_ipa_sra (gcc::context
*ctxt
)
5115 : gimple_opt_pass (pass_data_early_ipa_sra
, ctxt
)
5118 /* opt_pass methods: */
5119 bool gate () { return ipa_early_sra_gate (); }
5120 unsigned int execute () { return ipa_early_sra (); }
5122 }; // class pass_early_ipa_sra
5127 make_pass_early_ipa_sra (gcc::context
*ctxt
)
5129 return new pass_early_ipa_sra (ctxt
);