1 /* Scalar Replacement of Aggregates (SRA) converts some structure
2 references into scalar references, exposing them to the scalar
4 Copyright (C) 2008-2017 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"
83 #include "alloc-pool.h"
84 #include "tree-pass.h"
87 #include "gimple-pretty-print.h"
89 #include "fold-const.h"
91 #include "stor-layout.h"
93 #include "gimple-iterator.h"
94 #include "gimplify-me.h"
95 #include "gimple-walk.h"
99 #include "symbol-summary.h"
100 #include "ipa-prop.h"
103 #include "tree-inline.h"
104 #include "ipa-fnsummary.h"
105 #include "ipa-utils.h"
106 #include "builtins.h"
108 /* Enumeration of all aggregate reductions we can do. */
109 enum sra_mode
{ SRA_MODE_EARLY_IPA
, /* early call regularization */
110 SRA_MODE_EARLY_INTRA
, /* early intraprocedural SRA */
111 SRA_MODE_INTRA
}; /* late intraprocedural SRA */
113 /* Global variable describing which aggregate reduction we are performing at
115 static enum sra_mode sra_mode
;
119 /* ACCESS represents each access to an aggregate variable (as a whole or a
120 part). It can also represent a group of accesses that refer to exactly the
121 same fragment of an aggregate (i.e. those that have exactly the same offset
122 and size). Such representatives for a single aggregate, once determined,
123 are linked in a linked list and have the group fields set.
125 Moreover, when doing intraprocedural SRA, a tree is built from those
126 representatives (by the means of first_child and next_sibling pointers), in
127 which all items in a subtree are "within" the root, i.e. their offset is
128 greater or equal to offset of the root and offset+size is smaller or equal
129 to offset+size of the root. Children of an access are sorted by offset.
131 Note that accesses to parts of vector and complex number types always
132 represented by an access to the whole complex number or a vector. It is a
133 duty of the modifying functions to replace them appropriately. */
137 /* Values returned by `get_ref_base_and_extent' for each component reference
138 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
139 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
140 HOST_WIDE_INT offset
;
144 /* Expression. It is context dependent so do not use it to create new
145 expressions to access the original aggregate. See PR 42154 for a
151 /* The statement this access belongs to. */
154 /* Next group representative for this aggregate. */
155 struct access
*next_grp
;
157 /* Pointer to the group representative. Pointer to itself if the struct is
158 the representative. */
159 struct access
*group_representative
;
161 /* After access tree has been constructed, this points to the parent of the
162 current access, if there is one. NULL for roots. */
163 struct access
*parent
;
165 /* If this access has any children (in terms of the definition above), this
166 points to the first one. */
167 struct access
*first_child
;
169 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
170 described above. In IPA-SRA this is a pointer to the next access
171 belonging to the same group (having the same representative). */
172 struct access
*next_sibling
;
174 /* Pointers to the first and last element in the linked list of assign
176 struct assign_link
*first_link
, *last_link
;
178 /* Pointer to the next access in the work queue. */
179 struct access
*next_queued
;
181 /* Replacement variable for this access "region." Never to be accessed
182 directly, always only by the means of get_access_replacement() and only
183 when grp_to_be_replaced flag is set. */
184 tree replacement_decl
;
186 /* Is this access an access to a non-addressable field? */
187 unsigned non_addressable
: 1;
189 /* Is this access made in reverse storage order? */
190 unsigned reverse
: 1;
192 /* Is this particular access write access? */
195 /* Is this access currently in the work queue? */
196 unsigned grp_queued
: 1;
198 /* Does this group contain a write access? This flag is propagated down the
200 unsigned grp_write
: 1;
202 /* Does this group contain a read access? This flag is propagated down the
204 unsigned grp_read
: 1;
206 /* Does this group contain a read access that comes from an assignment
207 statement? This flag is propagated down the access tree. */
208 unsigned grp_assignment_read
: 1;
210 /* Does this group contain a write access that comes from an assignment
211 statement? This flag is propagated down the access tree. */
212 unsigned grp_assignment_write
: 1;
214 /* Does this group contain a read access through a scalar type? This flag is
215 not propagated in the access tree in any direction. */
216 unsigned grp_scalar_read
: 1;
218 /* Does this group contain a write access through a scalar type? This flag
219 is not propagated in the access tree in any direction. */
220 unsigned grp_scalar_write
: 1;
222 /* Is this access an artificial one created to scalarize some record
224 unsigned grp_total_scalarization
: 1;
226 /* Other passes of the analysis use this bit to make function
227 analyze_access_subtree create scalar replacements for this group if
229 unsigned grp_hint
: 1;
231 /* Is the subtree rooted in this access fully covered by scalar
233 unsigned grp_covered
: 1;
235 /* If set to true, this access and all below it in an access tree must not be
237 unsigned grp_unscalarizable_region
: 1;
239 /* Whether data have been written to parts of the aggregate covered by this
240 access which is not to be scalarized. This flag is propagated up in the
242 unsigned grp_unscalarized_data
: 1;
244 /* Does this access and/or group contain a write access through a
246 unsigned grp_partial_lhs
: 1;
248 /* Set when a scalar replacement should be created for this variable. */
249 unsigned grp_to_be_replaced
: 1;
251 /* Set when we want a replacement for the sole purpose of having it in
252 generated debug statements. */
253 unsigned grp_to_be_debug_replaced
: 1;
255 /* Should TREE_NO_WARNING of a replacement be set? */
256 unsigned grp_no_warning
: 1;
258 /* Is it possible that the group refers to data which might be (directly or
259 otherwise) modified? */
260 unsigned grp_maybe_modified
: 1;
262 /* Set when this is a representative of a pointer to scalar (i.e. by
263 reference) parameter which we consider for turning into a plain scalar
264 (i.e. a by value parameter). */
265 unsigned grp_scalar_ptr
: 1;
267 /* Set when we discover that this pointer is not safe to dereference in the
269 unsigned grp_not_necessarilly_dereferenced
: 1;
272 typedef struct access
*access_p
;
275 /* Alloc pool for allocating access structures. */
276 static object_allocator
<struct access
> access_pool ("SRA accesses");
278 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
279 are used to propagate subaccesses from rhs to lhs as long as they don't
280 conflict with what is already there. */
283 struct access
*lacc
, *racc
;
284 struct assign_link
*next
;
287 /* Alloc pool for allocating assign link structures. */
288 static object_allocator
<assign_link
> assign_link_pool ("SRA links");
290 /* Base (tree) -> Vector (vec<access_p> *) map. */
291 static hash_map
<tree
, auto_vec
<access_p
> > *base_access_vec
;
293 /* Candidate hash table helpers. */
295 struct uid_decl_hasher
: nofree_ptr_hash
<tree_node
>
297 static inline hashval_t
hash (const tree_node
*);
298 static inline bool equal (const tree_node
*, const tree_node
*);
301 /* Hash a tree in a uid_decl_map. */
304 uid_decl_hasher::hash (const tree_node
*item
)
306 return item
->decl_minimal
.uid
;
309 /* Return true if the DECL_UID in both trees are equal. */
312 uid_decl_hasher::equal (const tree_node
*a
, const tree_node
*b
)
314 return (a
->decl_minimal
.uid
== b
->decl_minimal
.uid
);
317 /* Set of candidates. */
318 static bitmap candidate_bitmap
;
319 static hash_table
<uid_decl_hasher
> *candidates
;
321 /* For a candidate UID return the candidates decl. */
324 candidate (unsigned uid
)
327 t
.decl_minimal
.uid
= uid
;
328 return candidates
->find_with_hash (&t
, static_cast <hashval_t
> (uid
));
331 /* Bitmap of candidates which we should try to entirely scalarize away and
332 those which cannot be (because they are and need be used as a whole). */
333 static bitmap should_scalarize_away_bitmap
, cannot_scalarize_away_bitmap
;
335 /* Bitmap of candidates in the constant pool, which cannot be scalarized
336 because this would produce non-constant expressions (e.g. Ada). */
337 static bitmap disqualified_constants
;
339 /* Obstack for creation of fancy names. */
340 static struct obstack name_obstack
;
342 /* Head of a linked list of accesses that need to have its subaccesses
343 propagated to their assignment counterparts. */
344 static struct access
*work_queue_head
;
346 /* Number of parameters of the analyzed function when doing early ipa SRA. */
347 static int func_param_count
;
349 /* scan_function sets the following to true if it encounters a call to
350 __builtin_apply_args. */
351 static bool encountered_apply_args
;
353 /* Set by scan_function when it finds a recursive call. */
354 static bool encountered_recursive_call
;
356 /* Set by scan_function when it finds a recursive call with less actual
357 arguments than formal parameters.. */
358 static bool encountered_unchangable_recursive_call
;
360 /* This is a table in which for each basic block and parameter there is a
361 distance (offset + size) in that parameter which is dereferenced and
362 accessed in that BB. */
363 static HOST_WIDE_INT
*bb_dereferences
;
364 /* Bitmap of BBs that can cause the function to "stop" progressing by
365 returning, throwing externally, looping infinitely or calling a function
366 which might abort etc.. */
367 static bitmap final_bbs
;
369 /* Representative of no accesses at all. */
370 static struct access no_accesses_representant
;
372 /* Predicate to test the special value. */
375 no_accesses_p (struct access
*access
)
377 return access
== &no_accesses_representant
;
380 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
381 representative fields are dumped, otherwise those which only describe the
382 individual access are. */
386 /* Number of processed aggregates is readily available in
387 analyze_all_variable_accesses and so is not stored here. */
389 /* Number of created scalar replacements. */
392 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
396 /* Number of statements created by generate_subtree_copies. */
399 /* Number of statements created by load_assign_lhs_subreplacements. */
402 /* Number of times sra_modify_assign has deleted a statement. */
405 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
406 RHS reparately due to type conversions or nonexistent matching
408 int separate_lhs_rhs_handling
;
410 /* Number of parameters that were removed because they were unused. */
411 int deleted_unused_parameters
;
413 /* Number of scalars passed as parameters by reference that have been
414 converted to be passed by value. */
415 int scalar_by_ref_to_by_val
;
417 /* Number of aggregate parameters that were replaced by one or more of their
419 int aggregate_params_reduced
;
421 /* Numbber of components created when splitting aggregate parameters. */
422 int param_reductions_created
;
426 dump_access (FILE *f
, struct access
*access
, bool grp
)
428 fprintf (f
, "access { ");
429 fprintf (f
, "base = (%d)'", DECL_UID (access
->base
));
430 print_generic_expr (f
, access
->base
);
431 fprintf (f
, "', offset = " HOST_WIDE_INT_PRINT_DEC
, access
->offset
);
432 fprintf (f
, ", size = " HOST_WIDE_INT_PRINT_DEC
, access
->size
);
433 fprintf (f
, ", expr = ");
434 print_generic_expr (f
, access
->expr
);
435 fprintf (f
, ", type = ");
436 print_generic_expr (f
, access
->type
);
437 fprintf (f
, ", non_addressable = %d, reverse = %d",
438 access
->non_addressable
, access
->reverse
);
440 fprintf (f
, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
441 "grp_assignment_write = %d, grp_scalar_read = %d, "
442 "grp_scalar_write = %d, grp_total_scalarization = %d, "
443 "grp_hint = %d, grp_covered = %d, "
444 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
445 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
446 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
447 "grp_not_necessarilly_dereferenced = %d\n",
448 access
->grp_read
, access
->grp_write
, access
->grp_assignment_read
,
449 access
->grp_assignment_write
, access
->grp_scalar_read
,
450 access
->grp_scalar_write
, access
->grp_total_scalarization
,
451 access
->grp_hint
, access
->grp_covered
,
452 access
->grp_unscalarizable_region
, access
->grp_unscalarized_data
,
453 access
->grp_partial_lhs
, access
->grp_to_be_replaced
,
454 access
->grp_to_be_debug_replaced
, access
->grp_maybe_modified
,
455 access
->grp_not_necessarilly_dereferenced
);
457 fprintf (f
, ", write = %d, grp_total_scalarization = %d, "
458 "grp_partial_lhs = %d\n",
459 access
->write
, access
->grp_total_scalarization
,
460 access
->grp_partial_lhs
);
463 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
466 dump_access_tree_1 (FILE *f
, struct access
*access
, int level
)
472 for (i
= 0; i
< level
; i
++)
475 dump_access (f
, access
, true);
477 if (access
->first_child
)
478 dump_access_tree_1 (f
, access
->first_child
, level
+ 1);
480 access
= access
->next_sibling
;
485 /* Dump all access trees for a variable, given the pointer to the first root in
489 dump_access_tree (FILE *f
, struct access
*access
)
491 for (; access
; access
= access
->next_grp
)
492 dump_access_tree_1 (f
, access
, 0);
495 /* Return true iff ACC is non-NULL and has subaccesses. */
498 access_has_children_p (struct access
*acc
)
500 return acc
&& acc
->first_child
;
503 /* Return true iff ACC is (partly) covered by at least one replacement. */
506 access_has_replacements_p (struct access
*acc
)
508 struct access
*child
;
509 if (acc
->grp_to_be_replaced
)
511 for (child
= acc
->first_child
; child
; child
= child
->next_sibling
)
512 if (access_has_replacements_p (child
))
517 /* Return a vector of pointers to accesses for the variable given in BASE or
518 NULL if there is none. */
520 static vec
<access_p
> *
521 get_base_access_vector (tree base
)
523 return base_access_vec
->get (base
);
526 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
527 in ACCESS. Return NULL if it cannot be found. */
529 static struct access
*
530 find_access_in_subtree (struct access
*access
, HOST_WIDE_INT offset
,
533 while (access
&& (access
->offset
!= offset
|| access
->size
!= size
))
535 struct access
*child
= access
->first_child
;
537 while (child
&& (child
->offset
+ child
->size
<= offset
))
538 child
= child
->next_sibling
;
545 /* Return the first group representative for DECL or NULL if none exists. */
547 static struct access
*
548 get_first_repr_for_decl (tree base
)
550 vec
<access_p
> *access_vec
;
552 access_vec
= get_base_access_vector (base
);
556 return (*access_vec
)[0];
559 /* Find an access representative for the variable BASE and given OFFSET and
560 SIZE. Requires that access trees have already been built. Return NULL if
561 it cannot be found. */
563 static struct access
*
564 get_var_base_offset_size_access (tree base
, HOST_WIDE_INT offset
,
567 struct access
*access
;
569 access
= get_first_repr_for_decl (base
);
570 while (access
&& (access
->offset
+ access
->size
<= offset
))
571 access
= access
->next_grp
;
575 return find_access_in_subtree (access
, offset
, size
);
578 /* Add LINK to the linked list of assign links of RACC. */
580 add_link_to_rhs (struct access
*racc
, struct assign_link
*link
)
582 gcc_assert (link
->racc
== racc
);
584 if (!racc
->first_link
)
586 gcc_assert (!racc
->last_link
);
587 racc
->first_link
= link
;
590 racc
->last_link
->next
= link
;
592 racc
->last_link
= link
;
596 /* Move all link structures in their linked list in OLD_RACC to the linked list
599 relink_to_new_repr (struct access
*new_racc
, struct access
*old_racc
)
601 if (!old_racc
->first_link
)
603 gcc_assert (!old_racc
->last_link
);
607 if (new_racc
->first_link
)
609 gcc_assert (!new_racc
->last_link
->next
);
610 gcc_assert (!old_racc
->last_link
|| !old_racc
->last_link
->next
);
612 new_racc
->last_link
->next
= old_racc
->first_link
;
613 new_racc
->last_link
= old_racc
->last_link
;
617 gcc_assert (!new_racc
->last_link
);
619 new_racc
->first_link
= old_racc
->first_link
;
620 new_racc
->last_link
= old_racc
->last_link
;
622 old_racc
->first_link
= old_racc
->last_link
= NULL
;
625 /* Add ACCESS to the work queue (which is actually a stack). */
628 add_access_to_work_queue (struct access
*access
)
630 if (access
->first_link
&& !access
->grp_queued
)
632 gcc_assert (!access
->next_queued
);
633 access
->next_queued
= work_queue_head
;
634 access
->grp_queued
= 1;
635 work_queue_head
= access
;
639 /* Pop an access from the work queue, and return it, assuming there is one. */
641 static struct access
*
642 pop_access_from_work_queue (void)
644 struct access
*access
= work_queue_head
;
646 work_queue_head
= access
->next_queued
;
647 access
->next_queued
= NULL
;
648 access
->grp_queued
= 0;
653 /* Allocate necessary structures. */
656 sra_initialize (void)
658 candidate_bitmap
= BITMAP_ALLOC (NULL
);
659 candidates
= new hash_table
<uid_decl_hasher
>
660 (vec_safe_length (cfun
->local_decls
) / 2);
661 should_scalarize_away_bitmap
= BITMAP_ALLOC (NULL
);
662 cannot_scalarize_away_bitmap
= BITMAP_ALLOC (NULL
);
663 disqualified_constants
= BITMAP_ALLOC (NULL
);
664 gcc_obstack_init (&name_obstack
);
665 base_access_vec
= new hash_map
<tree
, auto_vec
<access_p
> >;
666 memset (&sra_stats
, 0, sizeof (sra_stats
));
667 encountered_apply_args
= false;
668 encountered_recursive_call
= false;
669 encountered_unchangable_recursive_call
= false;
672 /* Deallocate all general structures. */
675 sra_deinitialize (void)
677 BITMAP_FREE (candidate_bitmap
);
680 BITMAP_FREE (should_scalarize_away_bitmap
);
681 BITMAP_FREE (cannot_scalarize_away_bitmap
);
682 BITMAP_FREE (disqualified_constants
);
683 access_pool
.release ();
684 assign_link_pool
.release ();
685 obstack_free (&name_obstack
, NULL
);
687 delete base_access_vec
;
690 /* Return true if DECL is a VAR_DECL in the constant pool, false otherwise. */
692 static bool constant_decl_p (tree decl
)
694 return VAR_P (decl
) && DECL_IN_CONSTANT_POOL (decl
);
697 /* Remove DECL from candidates for SRA and write REASON to the dump file if
701 disqualify_candidate (tree decl
, const char *reason
)
703 if (bitmap_clear_bit (candidate_bitmap
, DECL_UID (decl
)))
704 candidates
->remove_elt_with_hash (decl
, DECL_UID (decl
));
705 if (constant_decl_p (decl
))
706 bitmap_set_bit (disqualified_constants
, DECL_UID (decl
));
708 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
710 fprintf (dump_file
, "! Disqualifying ");
711 print_generic_expr (dump_file
, decl
);
712 fprintf (dump_file
, " - %s\n", reason
);
716 /* Return true iff the type contains a field or an element which does not allow
720 type_internals_preclude_sra_p (tree type
, const char **msg
)
725 switch (TREE_CODE (type
))
729 case QUAL_UNION_TYPE
:
730 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
731 if (TREE_CODE (fld
) == FIELD_DECL
)
733 tree ft
= TREE_TYPE (fld
);
735 if (TREE_THIS_VOLATILE (fld
))
737 *msg
= "volatile structure field";
740 if (!DECL_FIELD_OFFSET (fld
))
742 *msg
= "no structure field offset";
745 if (!DECL_SIZE (fld
))
747 *msg
= "zero structure field size";
750 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
752 *msg
= "structure field offset not fixed";
755 if (!tree_fits_uhwi_p (DECL_SIZE (fld
)))
757 *msg
= "structure field size not fixed";
760 if (!tree_fits_shwi_p (bit_position (fld
)))
762 *msg
= "structure field size too big";
765 if (AGGREGATE_TYPE_P (ft
)
766 && int_bit_position (fld
) % BITS_PER_UNIT
!= 0)
768 *msg
= "structure field is bit field";
772 if (AGGREGATE_TYPE_P (ft
) && type_internals_preclude_sra_p (ft
, msg
))
779 et
= TREE_TYPE (type
);
781 if (TYPE_VOLATILE (et
))
783 *msg
= "element type is volatile";
787 if (AGGREGATE_TYPE_P (et
) && type_internals_preclude_sra_p (et
, msg
))
797 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
798 base variable if it is. Return T if it is not an SSA_NAME. */
801 get_ssa_base_param (tree t
)
803 if (TREE_CODE (t
) == SSA_NAME
)
805 if (SSA_NAME_IS_DEFAULT_DEF (t
))
806 return SSA_NAME_VAR (t
);
813 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
814 belongs to, unless the BB has already been marked as a potentially
818 mark_parm_dereference (tree base
, HOST_WIDE_INT dist
, gimple
*stmt
)
820 basic_block bb
= gimple_bb (stmt
);
821 int idx
, parm_index
= 0;
824 if (bitmap_bit_p (final_bbs
, bb
->index
))
827 for (parm
= DECL_ARGUMENTS (current_function_decl
);
828 parm
&& parm
!= base
;
829 parm
= DECL_CHAIN (parm
))
832 gcc_assert (parm_index
< func_param_count
);
834 idx
= bb
->index
* func_param_count
+ parm_index
;
835 if (bb_dereferences
[idx
] < dist
)
836 bb_dereferences
[idx
] = dist
;
839 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
840 the three fields. Also add it to the vector of accesses corresponding to
841 the base. Finally, return the new access. */
843 static struct access
*
844 create_access_1 (tree base
, HOST_WIDE_INT offset
, HOST_WIDE_INT size
)
846 struct access
*access
= access_pool
.allocate ();
848 memset (access
, 0, sizeof (struct access
));
850 access
->offset
= offset
;
853 base_access_vec
->get_or_insert (base
).safe_push (access
);
858 static bool maybe_add_sra_candidate (tree
);
860 /* Create and insert access for EXPR. Return created access, or NULL if it is
861 not possible. Also scan for uses of constant pool as we go along and add
864 static struct access
*
865 create_access (tree expr
, gimple
*stmt
, bool write
)
867 struct access
*access
;
868 HOST_WIDE_INT offset
, size
, max_size
;
870 bool reverse
, ptr
, unscalarizable_region
= false;
872 base
= get_ref_base_and_extent (expr
, &offset
, &size
, &max_size
, &reverse
);
874 if (sra_mode
== SRA_MODE_EARLY_IPA
875 && TREE_CODE (base
) == MEM_REF
)
877 base
= get_ssa_base_param (TREE_OPERAND (base
, 0));
885 /* For constant-pool entries, check we can substitute the constant value. */
886 if (constant_decl_p (base
)
887 && (sra_mode
== SRA_MODE_EARLY_INTRA
|| sra_mode
== SRA_MODE_INTRA
))
889 gcc_assert (!bitmap_bit_p (disqualified_constants
, DECL_UID (base
)));
891 && !is_gimple_reg_type (TREE_TYPE (expr
))
892 && dump_file
&& (dump_flags
& TDF_DETAILS
))
894 /* This occurs in Ada with accesses to ARRAY_RANGE_REFs,
895 and elements of multidimensional arrays (which are
896 multi-element arrays in their own right). */
897 fprintf (dump_file
, "Allowing non-reg-type load of part"
898 " of constant-pool entry: ");
899 print_generic_expr (dump_file
, expr
);
901 maybe_add_sra_candidate (base
);
904 if (!DECL_P (base
) || !bitmap_bit_p (candidate_bitmap
, DECL_UID (base
)))
907 if (sra_mode
== SRA_MODE_EARLY_IPA
)
909 if (size
< 0 || size
!= max_size
)
911 disqualify_candidate (base
, "Encountered a variable sized access.");
914 if (TREE_CODE (expr
) == COMPONENT_REF
915 && DECL_BIT_FIELD (TREE_OPERAND (expr
, 1)))
917 disqualify_candidate (base
, "Encountered a bit-field access.");
920 gcc_checking_assert ((offset
% BITS_PER_UNIT
) == 0);
923 mark_parm_dereference (base
, offset
+ size
, stmt
);
927 if (size
!= max_size
)
930 unscalarizable_region
= true;
934 disqualify_candidate (base
, "Encountered an unconstrained access.");
939 access
= create_access_1 (base
, offset
, size
);
941 access
->type
= TREE_TYPE (expr
);
942 access
->write
= write
;
943 access
->grp_unscalarizable_region
= unscalarizable_region
;
945 access
->reverse
= reverse
;
947 if (TREE_CODE (expr
) == COMPONENT_REF
948 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr
, 1)))
949 access
->non_addressable
= 1;
955 /* Return true iff TYPE is scalarizable - i.e. a RECORD_TYPE or fixed-length
956 ARRAY_TYPE with fields that are either of gimple register types (excluding
957 bit-fields) or (recursively) scalarizable types. CONST_DECL must be true if
958 we are considering a decl from constant pool. If it is false, char arrays
962 scalarizable_type_p (tree type
, bool const_decl
)
964 gcc_assert (!is_gimple_reg_type (type
));
965 if (type_contains_placeholder_p (type
))
968 switch (TREE_CODE (type
))
971 for (tree fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
972 if (TREE_CODE (fld
) == FIELD_DECL
)
974 tree ft
= TREE_TYPE (fld
);
976 if (DECL_BIT_FIELD (fld
))
979 if (!is_gimple_reg_type (ft
)
980 && !scalarizable_type_p (ft
, const_decl
))
988 HOST_WIDE_INT min_elem_size
;
992 min_elem_size
= BITS_PER_UNIT
;
994 if (TYPE_DOMAIN (type
) == NULL_TREE
995 || !tree_fits_shwi_p (TYPE_SIZE (type
))
996 || !tree_fits_shwi_p (TYPE_SIZE (TREE_TYPE (type
)))
997 || (tree_to_shwi (TYPE_SIZE (TREE_TYPE (type
))) <= min_elem_size
)
998 || !tree_fits_shwi_p (TYPE_MIN_VALUE (TYPE_DOMAIN (type
))))
1000 if (tree_to_shwi (TYPE_SIZE (type
)) == 0
1001 && TYPE_MAX_VALUE (TYPE_DOMAIN (type
)) == NULL_TREE
)
1002 /* Zero-element array, should not prevent scalarization. */
1004 else if ((tree_to_shwi (TYPE_SIZE (type
)) <= 0)
1005 || !tree_fits_shwi_p (TYPE_MAX_VALUE (TYPE_DOMAIN (type
))))
1006 /* Variable-length array, do not allow scalarization. */
1009 tree elem
= TREE_TYPE (type
);
1010 if (!is_gimple_reg_type (elem
)
1011 && !scalarizable_type_p (elem
, const_decl
))
1020 static void scalarize_elem (tree
, HOST_WIDE_INT
, HOST_WIDE_INT
, bool, tree
, tree
);
1022 /* Create total_scalarization accesses for all scalar fields of a member
1023 of type DECL_TYPE conforming to scalarizable_type_p. BASE
1024 must be the top-most VAR_DECL representing the variable; within that,
1025 OFFSET locates the member and REF must be the memory reference expression for
1029 completely_scalarize (tree base
, tree decl_type
, HOST_WIDE_INT offset
, tree ref
)
1031 switch (TREE_CODE (decl_type
))
1034 for (tree fld
= TYPE_FIELDS (decl_type
); fld
; fld
= DECL_CHAIN (fld
))
1035 if (TREE_CODE (fld
) == FIELD_DECL
)
1037 HOST_WIDE_INT pos
= offset
+ int_bit_position (fld
);
1038 tree ft
= TREE_TYPE (fld
);
1039 tree nref
= build3 (COMPONENT_REF
, ft
, ref
, fld
, NULL_TREE
);
1041 scalarize_elem (base
, pos
, tree_to_uhwi (DECL_SIZE (fld
)),
1042 TYPE_REVERSE_STORAGE_ORDER (decl_type
),
1048 tree elemtype
= TREE_TYPE (decl_type
);
1049 tree elem_size
= TYPE_SIZE (elemtype
);
1050 gcc_assert (elem_size
&& tree_fits_shwi_p (elem_size
));
1051 HOST_WIDE_INT el_size
= tree_to_shwi (elem_size
);
1052 gcc_assert (el_size
> 0);
1054 tree minidx
= TYPE_MIN_VALUE (TYPE_DOMAIN (decl_type
));
1055 gcc_assert (TREE_CODE (minidx
) == INTEGER_CST
);
1056 tree maxidx
= TYPE_MAX_VALUE (TYPE_DOMAIN (decl_type
));
1057 /* Skip (some) zero-length arrays; others have MAXIDX == MINIDX - 1. */
1060 gcc_assert (TREE_CODE (maxidx
) == INTEGER_CST
);
1061 tree domain
= TYPE_DOMAIN (decl_type
);
1062 /* MINIDX and MAXIDX are inclusive, and must be interpreted in
1063 DOMAIN (e.g. signed int, whereas min/max may be size_int). */
1064 offset_int idx
= wi::to_offset (minidx
);
1065 offset_int max
= wi::to_offset (maxidx
);
1066 if (!TYPE_UNSIGNED (domain
))
1068 idx
= wi::sext (idx
, TYPE_PRECISION (domain
));
1069 max
= wi::sext (max
, TYPE_PRECISION (domain
));
1071 for (int el_off
= offset
; idx
<= max
; ++idx
)
1073 tree nref
= build4 (ARRAY_REF
, elemtype
,
1075 wide_int_to_tree (domain
, idx
),
1076 NULL_TREE
, NULL_TREE
);
1077 scalarize_elem (base
, el_off
, el_size
,
1078 TYPE_REVERSE_STORAGE_ORDER (decl_type
),
1090 /* Create total_scalarization accesses for a member of type TYPE, which must
1091 satisfy either is_gimple_reg_type or scalarizable_type_p. BASE must be the
1092 top-most VAR_DECL representing the variable; within that, POS and SIZE locate
1093 the member, REVERSE gives its torage order. and REF must be the reference
1094 expression for it. */
1097 scalarize_elem (tree base
, HOST_WIDE_INT pos
, HOST_WIDE_INT size
, bool reverse
,
1098 tree ref
, tree type
)
1100 if (is_gimple_reg_type (type
))
1102 struct access
*access
= create_access_1 (base
, pos
, size
);
1104 access
->type
= type
;
1105 access
->grp_total_scalarization
= 1;
1106 access
->reverse
= reverse
;
1107 /* Accesses for intraprocedural SRA can have their stmt NULL. */
1110 completely_scalarize (base
, type
, pos
, ref
);
1113 /* Create a total_scalarization access for VAR as a whole. VAR must be of a
1114 RECORD_TYPE or ARRAY_TYPE conforming to scalarizable_type_p. */
1117 create_total_scalarization_access (tree var
)
1119 HOST_WIDE_INT size
= tree_to_uhwi (DECL_SIZE (var
));
1120 struct access
*access
;
1122 access
= create_access_1 (var
, 0, size
);
1124 access
->type
= TREE_TYPE (var
);
1125 access
->grp_total_scalarization
= 1;
1128 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1131 contains_view_convert_expr_p (const_tree ref
)
1133 while (handled_component_p (ref
))
1135 if (TREE_CODE (ref
) == VIEW_CONVERT_EXPR
)
1137 ref
= TREE_OPERAND (ref
, 0);
1143 /* Search the given tree for a declaration by skipping handled components and
1144 exclude it from the candidates. */
1147 disqualify_base_of_expr (tree t
, const char *reason
)
1149 t
= get_base_address (t
);
1150 if (sra_mode
== SRA_MODE_EARLY_IPA
1151 && TREE_CODE (t
) == MEM_REF
)
1152 t
= get_ssa_base_param (TREE_OPERAND (t
, 0));
1154 if (t
&& DECL_P (t
))
1155 disqualify_candidate (t
, reason
);
1158 /* Scan expression EXPR and create access structures for all accesses to
1159 candidates for scalarization. Return the created access or NULL if none is
1162 static struct access
*
1163 build_access_from_expr_1 (tree expr
, gimple
*stmt
, bool write
)
1165 struct access
*ret
= NULL
;
1168 if (TREE_CODE (expr
) == BIT_FIELD_REF
1169 || TREE_CODE (expr
) == IMAGPART_EXPR
1170 || TREE_CODE (expr
) == REALPART_EXPR
)
1172 expr
= TREE_OPERAND (expr
, 0);
1176 partial_ref
= false;
1178 /* We need to dive through V_C_Es in order to get the size of its parameter
1179 and not the result type. Ada produces such statements. We are also
1180 capable of handling the topmost V_C_E but not any of those buried in other
1181 handled components. */
1182 if (TREE_CODE (expr
) == VIEW_CONVERT_EXPR
&& !storage_order_barrier_p (expr
))
1183 expr
= TREE_OPERAND (expr
, 0);
1185 if (contains_view_convert_expr_p (expr
))
1187 disqualify_base_of_expr (expr
, "V_C_E under a different handled "
1191 if (TREE_THIS_VOLATILE (expr
))
1193 disqualify_base_of_expr (expr
, "part of a volatile reference.");
1197 switch (TREE_CODE (expr
))
1200 if (TREE_CODE (TREE_OPERAND (expr
, 0)) != ADDR_EXPR
1201 && sra_mode
!= SRA_MODE_EARLY_IPA
)
1209 case ARRAY_RANGE_REF
:
1210 ret
= create_access (expr
, stmt
, write
);
1217 if (write
&& partial_ref
&& ret
)
1218 ret
->grp_partial_lhs
= 1;
1223 /* Scan expression EXPR and create access structures for all accesses to
1224 candidates for scalarization. Return true if any access has been inserted.
1225 STMT must be the statement from which the expression is taken, WRITE must be
1226 true if the expression is a store and false otherwise. */
1229 build_access_from_expr (tree expr
, gimple
*stmt
, bool write
)
1231 struct access
*access
;
1233 access
= build_access_from_expr_1 (expr
, stmt
, write
);
1236 /* This means the aggregate is accesses as a whole in a way other than an
1237 assign statement and thus cannot be removed even if we had a scalar
1238 replacement for everything. */
1239 if (cannot_scalarize_away_bitmap
)
1240 bitmap_set_bit (cannot_scalarize_away_bitmap
, DECL_UID (access
->base
));
1246 /* Return the single non-EH successor edge of BB or NULL if there is none or
1250 single_non_eh_succ (basic_block bb
)
1255 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1256 if (!(e
->flags
& EDGE_EH
))
1266 /* Disqualify LHS and RHS for scalarization if STMT has to terminate its BB and
1267 there is no alternative spot where to put statements SRA might need to
1268 generate after it. The spot we are looking for is an edge leading to a
1269 single non-EH successor, if it exists and is indeed single. RHS may be
1270 NULL, in that case ignore it. */
1273 disqualify_if_bad_bb_terminating_stmt (gimple
*stmt
, tree lhs
, tree rhs
)
1275 if ((sra_mode
== SRA_MODE_EARLY_INTRA
|| sra_mode
== SRA_MODE_INTRA
)
1276 && stmt_ends_bb_p (stmt
))
1278 if (single_non_eh_succ (gimple_bb (stmt
)))
1281 disqualify_base_of_expr (lhs
, "LHS of a throwing stmt.");
1283 disqualify_base_of_expr (rhs
, "RHS of a throwing stmt.");
1289 /* Return true if the nature of BASE is such that it contains data even if
1290 there is no write to it in the function. */
1293 comes_initialized_p (tree base
)
1295 return TREE_CODE (base
) == PARM_DECL
|| constant_decl_p (base
);
1298 /* Scan expressions occurring in STMT, create access structures for all accesses
1299 to candidates for scalarization and remove those candidates which occur in
1300 statements or expressions that prevent them from being split apart. Return
1301 true if any access has been inserted. */
1304 build_accesses_from_assign (gimple
*stmt
)
1307 struct access
*lacc
, *racc
;
1309 if (!gimple_assign_single_p (stmt
)
1310 /* Scope clobbers don't influence scalarization. */
1311 || gimple_clobber_p (stmt
))
1314 lhs
= gimple_assign_lhs (stmt
);
1315 rhs
= gimple_assign_rhs1 (stmt
);
1317 if (disqualify_if_bad_bb_terminating_stmt (stmt
, lhs
, rhs
))
1320 racc
= build_access_from_expr_1 (rhs
, stmt
, false);
1321 lacc
= build_access_from_expr_1 (lhs
, stmt
, true);
1325 lacc
->grp_assignment_write
= 1;
1326 if (storage_order_barrier_p (rhs
))
1327 lacc
->grp_unscalarizable_region
= 1;
1332 racc
->grp_assignment_read
= 1;
1333 if (should_scalarize_away_bitmap
&& !gimple_has_volatile_ops (stmt
)
1334 && !is_gimple_reg_type (racc
->type
))
1335 bitmap_set_bit (should_scalarize_away_bitmap
, DECL_UID (racc
->base
));
1336 if (storage_order_barrier_p (lhs
))
1337 racc
->grp_unscalarizable_region
= 1;
1341 && (sra_mode
== SRA_MODE_EARLY_INTRA
|| sra_mode
== SRA_MODE_INTRA
)
1342 && !lacc
->grp_unscalarizable_region
1343 && !racc
->grp_unscalarizable_region
1344 && AGGREGATE_TYPE_P (TREE_TYPE (lhs
))
1345 && lacc
->size
== racc
->size
1346 && useless_type_conversion_p (lacc
->type
, racc
->type
))
1348 struct assign_link
*link
;
1350 link
= assign_link_pool
.allocate ();
1351 memset (link
, 0, sizeof (struct assign_link
));
1355 add_link_to_rhs (racc
, link
);
1356 /* Let's delay marking the areas as written until propagation of accesses
1357 across link, unless the nature of rhs tells us that its data comes
1359 if (!comes_initialized_p (racc
->base
))
1360 lacc
->write
= false;
1363 return lacc
|| racc
;
1366 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1367 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1370 asm_visit_addr (gimple
*, tree op
, tree
, void *)
1372 op
= get_base_address (op
);
1375 disqualify_candidate (op
, "Non-scalarizable GIMPLE_ASM operand.");
1380 /* Return true iff callsite CALL has at least as many actual arguments as there
1381 are formal parameters of the function currently processed by IPA-SRA and
1382 that their types match. */
1385 callsite_arguments_match_p (gimple
*call
)
1387 if (gimple_call_num_args (call
) < (unsigned) func_param_count
)
1392 for (parm
= DECL_ARGUMENTS (current_function_decl
), i
= 0;
1394 parm
= DECL_CHAIN (parm
), i
++)
1396 tree arg
= gimple_call_arg (call
, i
);
1397 if (!useless_type_conversion_p (TREE_TYPE (parm
), TREE_TYPE (arg
)))
1403 /* Scan function and look for interesting expressions and create access
1404 structures for them. Return true iff any access is created. */
1407 scan_function (void)
1412 FOR_EACH_BB_FN (bb
, cfun
)
1414 gimple_stmt_iterator gsi
;
1415 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1417 gimple
*stmt
= gsi_stmt (gsi
);
1421 if (final_bbs
&& stmt_can_throw_external (stmt
))
1422 bitmap_set_bit (final_bbs
, bb
->index
);
1423 switch (gimple_code (stmt
))
1426 t
= gimple_return_retval (as_a
<greturn
*> (stmt
));
1428 ret
|= build_access_from_expr (t
, stmt
, false);
1430 bitmap_set_bit (final_bbs
, bb
->index
);
1434 ret
|= build_accesses_from_assign (stmt
);
1438 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1439 ret
|= build_access_from_expr (gimple_call_arg (stmt
, i
),
1442 if (sra_mode
== SRA_MODE_EARLY_IPA
)
1444 tree dest
= gimple_call_fndecl (stmt
);
1445 int flags
= gimple_call_flags (stmt
);
1449 if (DECL_BUILT_IN_CLASS (dest
) == BUILT_IN_NORMAL
1450 && DECL_FUNCTION_CODE (dest
) == BUILT_IN_APPLY_ARGS
)
1451 encountered_apply_args
= true;
1452 if (recursive_call_p (current_function_decl
, dest
))
1454 encountered_recursive_call
= true;
1455 if (!callsite_arguments_match_p (stmt
))
1456 encountered_unchangable_recursive_call
= true;
1461 && (flags
& (ECF_CONST
| ECF_PURE
)) == 0)
1462 bitmap_set_bit (final_bbs
, bb
->index
);
1465 t
= gimple_call_lhs (stmt
);
1466 if (t
&& !disqualify_if_bad_bb_terminating_stmt (stmt
, t
, NULL
))
1467 ret
|= build_access_from_expr (t
, stmt
, true);
1472 gasm
*asm_stmt
= as_a
<gasm
*> (stmt
);
1473 walk_stmt_load_store_addr_ops (asm_stmt
, NULL
, NULL
, NULL
,
1476 bitmap_set_bit (final_bbs
, bb
->index
);
1478 for (i
= 0; i
< gimple_asm_ninputs (asm_stmt
); i
++)
1480 t
= TREE_VALUE (gimple_asm_input_op (asm_stmt
, i
));
1481 ret
|= build_access_from_expr (t
, asm_stmt
, false);
1483 for (i
= 0; i
< gimple_asm_noutputs (asm_stmt
); i
++)
1485 t
= TREE_VALUE (gimple_asm_output_op (asm_stmt
, i
));
1486 ret
|= build_access_from_expr (t
, asm_stmt
, true);
1500 /* Helper of QSORT function. There are pointers to accesses in the array. An
1501 access is considered smaller than another if it has smaller offset or if the
1502 offsets are the same but is size is bigger. */
1505 compare_access_positions (const void *a
, const void *b
)
1507 const access_p
*fp1
= (const access_p
*) a
;
1508 const access_p
*fp2
= (const access_p
*) b
;
1509 const access_p f1
= *fp1
;
1510 const access_p f2
= *fp2
;
1512 if (f1
->offset
!= f2
->offset
)
1513 return f1
->offset
< f2
->offset
? -1 : 1;
1515 if (f1
->size
== f2
->size
)
1517 if (f1
->type
== f2
->type
)
1519 /* Put any non-aggregate type before any aggregate type. */
1520 else if (!is_gimple_reg_type (f1
->type
)
1521 && is_gimple_reg_type (f2
->type
))
1523 else if (is_gimple_reg_type (f1
->type
)
1524 && !is_gimple_reg_type (f2
->type
))
1526 /* Put any complex or vector type before any other scalar type. */
1527 else if (TREE_CODE (f1
->type
) != COMPLEX_TYPE
1528 && TREE_CODE (f1
->type
) != VECTOR_TYPE
1529 && (TREE_CODE (f2
->type
) == COMPLEX_TYPE
1530 || TREE_CODE (f2
->type
) == VECTOR_TYPE
))
1532 else if ((TREE_CODE (f1
->type
) == COMPLEX_TYPE
1533 || TREE_CODE (f1
->type
) == VECTOR_TYPE
)
1534 && TREE_CODE (f2
->type
) != COMPLEX_TYPE
1535 && TREE_CODE (f2
->type
) != VECTOR_TYPE
)
1537 /* Put the integral type with the bigger precision first. */
1538 else if (INTEGRAL_TYPE_P (f1
->type
)
1539 && INTEGRAL_TYPE_P (f2
->type
))
1540 return TYPE_PRECISION (f2
->type
) - TYPE_PRECISION (f1
->type
);
1541 /* Put any integral type with non-full precision last. */
1542 else if (INTEGRAL_TYPE_P (f1
->type
)
1543 && (TREE_INT_CST_LOW (TYPE_SIZE (f1
->type
))
1544 != TYPE_PRECISION (f1
->type
)))
1546 else if (INTEGRAL_TYPE_P (f2
->type
)
1547 && (TREE_INT_CST_LOW (TYPE_SIZE (f2
->type
))
1548 != TYPE_PRECISION (f2
->type
)))
1550 /* Stabilize the sort. */
1551 return TYPE_UID (f1
->type
) - TYPE_UID (f2
->type
);
1554 /* We want the bigger accesses first, thus the opposite operator in the next
1556 return f1
->size
> f2
->size
? -1 : 1;
1560 /* Append a name of the declaration to the name obstack. A helper function for
1564 make_fancy_decl_name (tree decl
)
1568 tree name
= DECL_NAME (decl
);
1570 obstack_grow (&name_obstack
, IDENTIFIER_POINTER (name
),
1571 IDENTIFIER_LENGTH (name
));
1574 sprintf (buffer
, "D%u", DECL_UID (decl
));
1575 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1579 /* Helper for make_fancy_name. */
1582 make_fancy_name_1 (tree expr
)
1589 make_fancy_decl_name (expr
);
1593 switch (TREE_CODE (expr
))
1596 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1597 obstack_1grow (&name_obstack
, '$');
1598 make_fancy_decl_name (TREE_OPERAND (expr
, 1));
1602 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1603 obstack_1grow (&name_obstack
, '$');
1604 /* Arrays with only one element may not have a constant as their
1606 index
= TREE_OPERAND (expr
, 1);
1607 if (TREE_CODE (index
) != INTEGER_CST
)
1609 sprintf (buffer
, HOST_WIDE_INT_PRINT_DEC
, TREE_INT_CST_LOW (index
));
1610 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1614 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1618 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1619 if (!integer_zerop (TREE_OPERAND (expr
, 1)))
1621 obstack_1grow (&name_obstack
, '$');
1622 sprintf (buffer
, HOST_WIDE_INT_PRINT_DEC
,
1623 TREE_INT_CST_LOW (TREE_OPERAND (expr
, 1)));
1624 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1631 gcc_unreachable (); /* we treat these as scalars. */
1638 /* Create a human readable name for replacement variable of ACCESS. */
1641 make_fancy_name (tree expr
)
1643 make_fancy_name_1 (expr
);
1644 obstack_1grow (&name_obstack
, '\0');
1645 return XOBFINISH (&name_obstack
, char *);
1648 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1649 EXP_TYPE at the given OFFSET and with storage order REVERSE. If BASE is
1650 something for which get_addr_base_and_unit_offset returns NULL, gsi must
1651 be non-NULL and is used to insert new statements either before or below
1652 the current one as specified by INSERT_AFTER. This function is not capable
1653 of handling bitfields. */
1656 build_ref_for_offset (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1657 bool reverse
, tree exp_type
, gimple_stmt_iterator
*gsi
,
1660 tree prev_base
= base
;
1663 HOST_WIDE_INT base_offset
;
1664 unsigned HOST_WIDE_INT misalign
;
1667 /* Preserve address-space information. */
1668 addr_space_t as
= TYPE_ADDR_SPACE (TREE_TYPE (base
));
1669 if (as
!= TYPE_ADDR_SPACE (exp_type
))
1670 exp_type
= build_qualified_type (exp_type
,
1671 TYPE_QUALS (exp_type
)
1672 | ENCODE_QUAL_ADDR_SPACE (as
));
1674 gcc_checking_assert (offset
% BITS_PER_UNIT
== 0);
1675 get_object_alignment_1 (base
, &align
, &misalign
);
1676 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
1678 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1679 offset such as array[var_index]. */
1685 gcc_checking_assert (gsi
);
1686 tmp
= make_ssa_name (build_pointer_type (TREE_TYPE (prev_base
)));
1687 addr
= build_fold_addr_expr (unshare_expr (prev_base
));
1688 STRIP_USELESS_TYPE_CONVERSION (addr
);
1689 stmt
= gimple_build_assign (tmp
, addr
);
1690 gimple_set_location (stmt
, loc
);
1692 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
1694 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
1696 off
= build_int_cst (reference_alias_ptr_type (prev_base
),
1697 offset
/ BITS_PER_UNIT
);
1700 else if (TREE_CODE (base
) == MEM_REF
)
1702 off
= build_int_cst (TREE_TYPE (TREE_OPERAND (base
, 1)),
1703 base_offset
+ offset
/ BITS_PER_UNIT
);
1704 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1), off
);
1705 base
= unshare_expr (TREE_OPERAND (base
, 0));
1709 off
= build_int_cst (reference_alias_ptr_type (prev_base
),
1710 base_offset
+ offset
/ BITS_PER_UNIT
);
1711 base
= build_fold_addr_expr (unshare_expr (base
));
1714 misalign
= (misalign
+ offset
) & (align
- 1);
1716 align
= least_bit_hwi (misalign
);
1717 if (align
!= TYPE_ALIGN (exp_type
))
1718 exp_type
= build_aligned_type (exp_type
, align
);
1720 mem_ref
= fold_build2_loc (loc
, MEM_REF
, exp_type
, base
, off
);
1721 REF_REVERSE_STORAGE_ORDER (mem_ref
) = reverse
;
1722 if (TREE_THIS_VOLATILE (prev_base
))
1723 TREE_THIS_VOLATILE (mem_ref
) = 1;
1724 if (TREE_SIDE_EFFECTS (prev_base
))
1725 TREE_SIDE_EFFECTS (mem_ref
) = 1;
1729 /* Construct a memory reference to a part of an aggregate BASE at the given
1730 OFFSET and of the same type as MODEL. In case this is a reference to a
1731 bit-field, the function will replicate the last component_ref of model's
1732 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1733 build_ref_for_offset. */
1736 build_ref_for_model (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1737 struct access
*model
, gimple_stmt_iterator
*gsi
,
1740 if (TREE_CODE (model
->expr
) == COMPONENT_REF
1741 && DECL_BIT_FIELD (TREE_OPERAND (model
->expr
, 1)))
1743 /* This access represents a bit-field. */
1744 tree t
, exp_type
, fld
= TREE_OPERAND (model
->expr
, 1);
1746 offset
-= int_bit_position (fld
);
1747 exp_type
= TREE_TYPE (TREE_OPERAND (model
->expr
, 0));
1748 t
= build_ref_for_offset (loc
, base
, offset
, model
->reverse
, exp_type
,
1750 /* The flag will be set on the record type. */
1751 REF_REVERSE_STORAGE_ORDER (t
) = 0;
1752 return fold_build3_loc (loc
, COMPONENT_REF
, TREE_TYPE (fld
), t
, fld
,
1757 build_ref_for_offset (loc
, base
, offset
, model
->reverse
, model
->type
,
1761 /* Attempt to build a memory reference that we could but into a gimple
1762 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1763 create statements and return s NULL instead. This function also ignores
1764 alignment issues and so its results should never end up in non-debug
1768 build_debug_ref_for_model (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1769 struct access
*model
)
1771 HOST_WIDE_INT base_offset
;
1774 if (TREE_CODE (model
->expr
) == COMPONENT_REF
1775 && DECL_BIT_FIELD (TREE_OPERAND (model
->expr
, 1)))
1778 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
1781 if (TREE_CODE (base
) == MEM_REF
)
1783 off
= build_int_cst (TREE_TYPE (TREE_OPERAND (base
, 1)),
1784 base_offset
+ offset
/ BITS_PER_UNIT
);
1785 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1), off
);
1786 base
= unshare_expr (TREE_OPERAND (base
, 0));
1790 off
= build_int_cst (reference_alias_ptr_type (base
),
1791 base_offset
+ offset
/ BITS_PER_UNIT
);
1792 base
= build_fold_addr_expr (unshare_expr (base
));
1795 return fold_build2_loc (loc
, MEM_REF
, model
->type
, base
, off
);
1798 /* Construct a memory reference consisting of component_refs and array_refs to
1799 a part of an aggregate *RES (which is of type TYPE). The requested part
1800 should have type EXP_TYPE at be the given OFFSET. This function might not
1801 succeed, it returns true when it does and only then *RES points to something
1802 meaningful. This function should be used only to build expressions that we
1803 might need to present to user (e.g. in warnings). In all other situations,
1804 build_ref_for_model or build_ref_for_offset should be used instead. */
1807 build_user_friendly_ref_for_offset (tree
*res
, tree type
, HOST_WIDE_INT offset
,
1813 tree tr_size
, index
, minidx
;
1814 HOST_WIDE_INT el_size
;
1816 if (offset
== 0 && exp_type
1817 && types_compatible_p (exp_type
, type
))
1820 switch (TREE_CODE (type
))
1823 case QUAL_UNION_TYPE
:
1825 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
1827 HOST_WIDE_INT pos
, size
;
1828 tree tr_pos
, expr
, *expr_ptr
;
1830 if (TREE_CODE (fld
) != FIELD_DECL
)
1833 tr_pos
= bit_position (fld
);
1834 if (!tr_pos
|| !tree_fits_uhwi_p (tr_pos
))
1836 pos
= tree_to_uhwi (tr_pos
);
1837 gcc_assert (TREE_CODE (type
) == RECORD_TYPE
|| pos
== 0);
1838 tr_size
= DECL_SIZE (fld
);
1839 if (!tr_size
|| !tree_fits_uhwi_p (tr_size
))
1841 size
= tree_to_uhwi (tr_size
);
1847 else if (pos
> offset
|| (pos
+ size
) <= offset
)
1850 expr
= build3 (COMPONENT_REF
, TREE_TYPE (fld
), *res
, fld
,
1853 if (build_user_friendly_ref_for_offset (expr_ptr
, TREE_TYPE (fld
),
1854 offset
- pos
, exp_type
))
1863 tr_size
= TYPE_SIZE (TREE_TYPE (type
));
1864 if (!tr_size
|| !tree_fits_uhwi_p (tr_size
))
1866 el_size
= tree_to_uhwi (tr_size
);
1868 minidx
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
1869 if (TREE_CODE (minidx
) != INTEGER_CST
|| el_size
== 0)
1871 index
= build_int_cst (TYPE_DOMAIN (type
), offset
/ el_size
);
1872 if (!integer_zerop (minidx
))
1873 index
= int_const_binop (PLUS_EXPR
, index
, minidx
);
1874 *res
= build4 (ARRAY_REF
, TREE_TYPE (type
), *res
, index
,
1875 NULL_TREE
, NULL_TREE
);
1876 offset
= offset
% el_size
;
1877 type
= TREE_TYPE (type
);
1892 /* Return true iff TYPE is stdarg va_list type. */
1895 is_va_list_type (tree type
)
1897 return TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (va_list_type_node
);
1900 /* Print message to dump file why a variable was rejected. */
1903 reject (tree var
, const char *msg
)
1905 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1907 fprintf (dump_file
, "Rejected (%d): %s: ", DECL_UID (var
), msg
);
1908 print_generic_expr (dump_file
, var
);
1909 fprintf (dump_file
, "\n");
1913 /* Return true if VAR is a candidate for SRA. */
1916 maybe_add_sra_candidate (tree var
)
1918 tree type
= TREE_TYPE (var
);
1922 if (!AGGREGATE_TYPE_P (type
))
1924 reject (var
, "not aggregate");
1927 /* Allow constant-pool entries (that "need to live in memory")
1928 unless we are doing IPA SRA. */
1929 if (needs_to_live_in_memory (var
)
1930 && (sra_mode
== SRA_MODE_EARLY_IPA
|| !constant_decl_p (var
)))
1932 reject (var
, "needs to live in memory");
1935 if (TREE_THIS_VOLATILE (var
))
1937 reject (var
, "is volatile");
1940 if (!COMPLETE_TYPE_P (type
))
1942 reject (var
, "has incomplete type");
1945 if (!tree_fits_uhwi_p (TYPE_SIZE (type
)))
1947 reject (var
, "type size not fixed");
1950 if (tree_to_uhwi (TYPE_SIZE (type
)) == 0)
1952 reject (var
, "type size is zero");
1955 if (type_internals_preclude_sra_p (type
, &msg
))
1960 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1961 we also want to schedule it rather late. Thus we ignore it in
1963 (sra_mode
== SRA_MODE_EARLY_INTRA
1964 && is_va_list_type (type
)))
1966 reject (var
, "is va_list");
1970 bitmap_set_bit (candidate_bitmap
, DECL_UID (var
));
1971 slot
= candidates
->find_slot_with_hash (var
, DECL_UID (var
), INSERT
);
1974 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1976 fprintf (dump_file
, "Candidate (%d): ", DECL_UID (var
));
1977 print_generic_expr (dump_file
, var
);
1978 fprintf (dump_file
, "\n");
1984 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1985 those with type which is suitable for scalarization. */
1988 find_var_candidates (void)
1994 for (parm
= DECL_ARGUMENTS (current_function_decl
);
1996 parm
= DECL_CHAIN (parm
))
1997 ret
|= maybe_add_sra_candidate (parm
);
1999 FOR_EACH_LOCAL_DECL (cfun
, i
, var
)
2004 ret
|= maybe_add_sra_candidate (var
);
2010 /* Sort all accesses for the given variable, check for partial overlaps and
2011 return NULL if there are any. If there are none, pick a representative for
2012 each combination of offset and size and create a linked list out of them.
2013 Return the pointer to the first representative and make sure it is the first
2014 one in the vector of accesses. */
2016 static struct access
*
2017 sort_and_splice_var_accesses (tree var
)
2019 int i
, j
, access_count
;
2020 struct access
*res
, **prev_acc_ptr
= &res
;
2021 vec
<access_p
> *access_vec
;
2023 HOST_WIDE_INT low
= -1, high
= 0;
2025 access_vec
= get_base_access_vector (var
);
2028 access_count
= access_vec
->length ();
2030 /* Sort by <OFFSET, SIZE>. */
2031 access_vec
->qsort (compare_access_positions
);
2034 while (i
< access_count
)
2036 struct access
*access
= (*access_vec
)[i
];
2037 bool grp_write
= access
->write
;
2038 bool grp_read
= !access
->write
;
2039 bool grp_scalar_write
= access
->write
2040 && is_gimple_reg_type (access
->type
);
2041 bool grp_scalar_read
= !access
->write
2042 && is_gimple_reg_type (access
->type
);
2043 bool grp_assignment_read
= access
->grp_assignment_read
;
2044 bool grp_assignment_write
= access
->grp_assignment_write
;
2045 bool multiple_scalar_reads
= false;
2046 bool total_scalarization
= access
->grp_total_scalarization
;
2047 bool grp_partial_lhs
= access
->grp_partial_lhs
;
2048 bool first_scalar
= is_gimple_reg_type (access
->type
);
2049 bool unscalarizable_region
= access
->grp_unscalarizable_region
;
2051 if (first
|| access
->offset
>= high
)
2054 low
= access
->offset
;
2055 high
= access
->offset
+ access
->size
;
2057 else if (access
->offset
> low
&& access
->offset
+ access
->size
> high
)
2060 gcc_assert (access
->offset
>= low
2061 && access
->offset
+ access
->size
<= high
);
2064 while (j
< access_count
)
2066 struct access
*ac2
= (*access_vec
)[j
];
2067 if (ac2
->offset
!= access
->offset
|| ac2
->size
!= access
->size
)
2072 grp_scalar_write
= (grp_scalar_write
2073 || is_gimple_reg_type (ac2
->type
));
2078 if (is_gimple_reg_type (ac2
->type
))
2080 if (grp_scalar_read
)
2081 multiple_scalar_reads
= true;
2083 grp_scalar_read
= true;
2086 grp_assignment_read
|= ac2
->grp_assignment_read
;
2087 grp_assignment_write
|= ac2
->grp_assignment_write
;
2088 grp_partial_lhs
|= ac2
->grp_partial_lhs
;
2089 unscalarizable_region
|= ac2
->grp_unscalarizable_region
;
2090 total_scalarization
|= ac2
->grp_total_scalarization
;
2091 relink_to_new_repr (access
, ac2
);
2093 /* If there are both aggregate-type and scalar-type accesses with
2094 this combination of size and offset, the comparison function
2095 should have put the scalars first. */
2096 gcc_assert (first_scalar
|| !is_gimple_reg_type (ac2
->type
));
2097 ac2
->group_representative
= access
;
2103 access
->group_representative
= access
;
2104 access
->grp_write
= grp_write
;
2105 access
->grp_read
= grp_read
;
2106 access
->grp_scalar_read
= grp_scalar_read
;
2107 access
->grp_scalar_write
= grp_scalar_write
;
2108 access
->grp_assignment_read
= grp_assignment_read
;
2109 access
->grp_assignment_write
= grp_assignment_write
;
2110 access
->grp_hint
= total_scalarization
2111 || (multiple_scalar_reads
&& !constant_decl_p (var
));
2112 access
->grp_total_scalarization
= total_scalarization
;
2113 access
->grp_partial_lhs
= grp_partial_lhs
;
2114 access
->grp_unscalarizable_region
= unscalarizable_region
;
2115 add_access_to_work_queue (access
);
2117 *prev_acc_ptr
= access
;
2118 prev_acc_ptr
= &access
->next_grp
;
2121 gcc_assert (res
== (*access_vec
)[0]);
2125 /* Create a variable for the given ACCESS which determines the type, name and a
2126 few other properties. Return the variable declaration and store it also to
2127 ACCESS->replacement. */
2130 create_access_replacement (struct access
*access
)
2134 if (access
->grp_to_be_debug_replaced
)
2136 repl
= create_tmp_var_raw (access
->type
);
2137 DECL_CONTEXT (repl
) = current_function_decl
;
2140 /* Drop any special alignment on the type if it's not on the main
2141 variant. This avoids issues with weirdo ABIs like AAPCS. */
2142 repl
= create_tmp_var (build_qualified_type
2143 (TYPE_MAIN_VARIANT (access
->type
),
2144 TYPE_QUALS (access
->type
)), "SR");
2145 if (TREE_CODE (access
->type
) == COMPLEX_TYPE
2146 || TREE_CODE (access
->type
) == VECTOR_TYPE
)
2148 if (!access
->grp_partial_lhs
)
2149 DECL_GIMPLE_REG_P (repl
) = 1;
2151 else if (access
->grp_partial_lhs
2152 && is_gimple_reg_type (access
->type
))
2153 TREE_ADDRESSABLE (repl
) = 1;
2155 DECL_SOURCE_LOCATION (repl
) = DECL_SOURCE_LOCATION (access
->base
);
2156 DECL_ARTIFICIAL (repl
) = 1;
2157 DECL_IGNORED_P (repl
) = DECL_IGNORED_P (access
->base
);
2159 if (DECL_NAME (access
->base
)
2160 && !DECL_IGNORED_P (access
->base
)
2161 && !DECL_ARTIFICIAL (access
->base
))
2163 char *pretty_name
= make_fancy_name (access
->expr
);
2164 tree debug_expr
= unshare_expr_without_location (access
->expr
), d
;
2167 DECL_NAME (repl
) = get_identifier (pretty_name
);
2168 DECL_NAMELESS (repl
) = 1;
2169 obstack_free (&name_obstack
, pretty_name
);
2171 /* Get rid of any SSA_NAMEs embedded in debug_expr,
2172 as DECL_DEBUG_EXPR isn't considered when looking for still
2173 used SSA_NAMEs and thus they could be freed. All debug info
2174 generation cares is whether something is constant or variable
2175 and that get_ref_base_and_extent works properly on the
2176 expression. It cannot handle accesses at a non-constant offset
2177 though, so just give up in those cases. */
2178 for (d
= debug_expr
;
2179 !fail
&& (handled_component_p (d
) || TREE_CODE (d
) == MEM_REF
);
2180 d
= TREE_OPERAND (d
, 0))
2181 switch (TREE_CODE (d
))
2184 case ARRAY_RANGE_REF
:
2185 if (TREE_OPERAND (d
, 1)
2186 && TREE_CODE (TREE_OPERAND (d
, 1)) != INTEGER_CST
)
2188 if (TREE_OPERAND (d
, 3)
2189 && TREE_CODE (TREE_OPERAND (d
, 3)) != INTEGER_CST
)
2193 if (TREE_OPERAND (d
, 2)
2194 && TREE_CODE (TREE_OPERAND (d
, 2)) != INTEGER_CST
)
2198 if (TREE_CODE (TREE_OPERAND (d
, 0)) != ADDR_EXPR
)
2201 d
= TREE_OPERAND (d
, 0);
2208 SET_DECL_DEBUG_EXPR (repl
, debug_expr
);
2209 DECL_HAS_DEBUG_EXPR_P (repl
) = 1;
2211 if (access
->grp_no_warning
)
2212 TREE_NO_WARNING (repl
) = 1;
2214 TREE_NO_WARNING (repl
) = TREE_NO_WARNING (access
->base
);
2217 TREE_NO_WARNING (repl
) = 1;
2221 if (access
->grp_to_be_debug_replaced
)
2223 fprintf (dump_file
, "Created a debug-only replacement for ");
2224 print_generic_expr (dump_file
, access
->base
);
2225 fprintf (dump_file
, " offset: %u, size: %u\n",
2226 (unsigned) access
->offset
, (unsigned) access
->size
);
2230 fprintf (dump_file
, "Created a replacement for ");
2231 print_generic_expr (dump_file
, access
->base
);
2232 fprintf (dump_file
, " offset: %u, size: %u: ",
2233 (unsigned) access
->offset
, (unsigned) access
->size
);
2234 print_generic_expr (dump_file
, repl
);
2235 fprintf (dump_file
, "\n");
2238 sra_stats
.replacements
++;
2243 /* Return ACCESS scalar replacement, which must exist. */
2246 get_access_replacement (struct access
*access
)
2248 gcc_checking_assert (access
->replacement_decl
);
2249 return access
->replacement_decl
;
2253 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2254 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2255 to it is not "within" the root. Return false iff some accesses partially
2259 build_access_subtree (struct access
**access
)
2261 struct access
*root
= *access
, *last_child
= NULL
;
2262 HOST_WIDE_INT limit
= root
->offset
+ root
->size
;
2264 *access
= (*access
)->next_grp
;
2265 while (*access
&& (*access
)->offset
+ (*access
)->size
<= limit
)
2268 root
->first_child
= *access
;
2270 last_child
->next_sibling
= *access
;
2271 last_child
= *access
;
2272 (*access
)->parent
= root
;
2273 (*access
)->grp_write
|= root
->grp_write
;
2275 if (!build_access_subtree (access
))
2279 if (*access
&& (*access
)->offset
< limit
)
2285 /* Build a tree of access representatives, ACCESS is the pointer to the first
2286 one, others are linked in a list by the next_grp field. Return false iff
2287 some accesses partially overlap. */
2290 build_access_trees (struct access
*access
)
2294 struct access
*root
= access
;
2296 if (!build_access_subtree (&access
))
2298 root
->next_grp
= access
;
2303 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2307 expr_with_var_bounded_array_refs_p (tree expr
)
2309 while (handled_component_p (expr
))
2311 if (TREE_CODE (expr
) == ARRAY_REF
2312 && !tree_fits_shwi_p (array_ref_low_bound (expr
)))
2314 expr
= TREE_OPERAND (expr
, 0);
2319 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2320 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2321 sorts of access flags appropriately along the way, notably always set
2322 grp_read and grp_assign_read according to MARK_READ and grp_write when
2325 Creating a replacement for a scalar access is considered beneficial if its
2326 grp_hint is set (this means we are either attempting total scalarization or
2327 there is more than one direct read access) or according to the following
2330 Access written to through a scalar type (once or more times)
2332 | Written to in an assignment statement
2334 | | Access read as scalar _once_
2336 | | | Read in an assignment statement
2338 | | | | Scalarize Comment
2339 -----------------------------------------------------------------------------
2340 0 0 0 0 No access for the scalar
2341 0 0 0 1 No access for the scalar
2342 0 0 1 0 No Single read - won't help
2343 0 0 1 1 No The same case
2344 0 1 0 0 No access for the scalar
2345 0 1 0 1 No access for the scalar
2346 0 1 1 0 Yes s = *g; return s.i;
2347 0 1 1 1 Yes The same case as above
2348 1 0 0 0 No Won't help
2349 1 0 0 1 Yes s.i = 1; *g = s;
2350 1 0 1 0 Yes s.i = 5; g = s.i;
2351 1 0 1 1 Yes The same case as above
2352 1 1 0 0 No Won't help.
2353 1 1 0 1 Yes s.i = 1; *g = s;
2354 1 1 1 0 Yes s = *g; return s.i;
2355 1 1 1 1 Yes Any of the above yeses */
2358 analyze_access_subtree (struct access
*root
, struct access
*parent
,
2359 bool allow_replacements
)
2361 struct access
*child
;
2362 HOST_WIDE_INT limit
= root
->offset
+ root
->size
;
2363 HOST_WIDE_INT covered_to
= root
->offset
;
2364 bool scalar
= is_gimple_reg_type (root
->type
);
2365 bool hole
= false, sth_created
= false;
2369 if (parent
->grp_read
)
2371 if (parent
->grp_assignment_read
)
2372 root
->grp_assignment_read
= 1;
2373 if (parent
->grp_write
)
2374 root
->grp_write
= 1;
2375 if (parent
->grp_assignment_write
)
2376 root
->grp_assignment_write
= 1;
2377 if (parent
->grp_total_scalarization
)
2378 root
->grp_total_scalarization
= 1;
2381 if (root
->grp_unscalarizable_region
)
2382 allow_replacements
= false;
2384 if (allow_replacements
&& expr_with_var_bounded_array_refs_p (root
->expr
))
2385 allow_replacements
= false;
2387 for (child
= root
->first_child
; child
; child
= child
->next_sibling
)
2389 hole
|= covered_to
< child
->offset
;
2390 sth_created
|= analyze_access_subtree (child
, root
,
2391 allow_replacements
&& !scalar
);
2393 root
->grp_unscalarized_data
|= child
->grp_unscalarized_data
;
2394 root
->grp_total_scalarization
&= child
->grp_total_scalarization
;
2395 if (child
->grp_covered
)
2396 covered_to
+= child
->size
;
2401 if (allow_replacements
&& scalar
&& !root
->first_child
2403 || ((root
->grp_scalar_read
|| root
->grp_assignment_read
)
2404 && (root
->grp_scalar_write
|| root
->grp_assignment_write
))))
2406 /* Always create access replacements that cover the whole access.
2407 For integral types this means the precision has to match.
2408 Avoid assumptions based on the integral type kind, too. */
2409 if (INTEGRAL_TYPE_P (root
->type
)
2410 && (TREE_CODE (root
->type
) != INTEGER_TYPE
2411 || TYPE_PRECISION (root
->type
) != root
->size
)
2412 /* But leave bitfield accesses alone. */
2413 && (TREE_CODE (root
->expr
) != COMPONENT_REF
2414 || !DECL_BIT_FIELD (TREE_OPERAND (root
->expr
, 1))))
2416 tree rt
= root
->type
;
2417 gcc_assert ((root
->offset
% BITS_PER_UNIT
) == 0
2418 && (root
->size
% BITS_PER_UNIT
) == 0);
2419 root
->type
= build_nonstandard_integer_type (root
->size
,
2420 TYPE_UNSIGNED (rt
));
2421 root
->expr
= build_ref_for_offset (UNKNOWN_LOCATION
, root
->base
,
2422 root
->offset
, root
->reverse
,
2423 root
->type
, NULL
, false);
2425 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2427 fprintf (dump_file
, "Changing the type of a replacement for ");
2428 print_generic_expr (dump_file
, root
->base
);
2429 fprintf (dump_file
, " offset: %u, size: %u ",
2430 (unsigned) root
->offset
, (unsigned) root
->size
);
2431 fprintf (dump_file
, " to an integer.\n");
2435 root
->grp_to_be_replaced
= 1;
2436 root
->replacement_decl
= create_access_replacement (root
);
2442 if (allow_replacements
2443 && scalar
&& !root
->first_child
2444 && (root
->grp_scalar_write
|| root
->grp_assignment_write
)
2445 && !bitmap_bit_p (cannot_scalarize_away_bitmap
,
2446 DECL_UID (root
->base
)))
2448 gcc_checking_assert (!root
->grp_scalar_read
2449 && !root
->grp_assignment_read
);
2451 if (MAY_HAVE_DEBUG_STMTS
)
2453 root
->grp_to_be_debug_replaced
= 1;
2454 root
->replacement_decl
= create_access_replacement (root
);
2458 if (covered_to
< limit
)
2460 if (scalar
|| !allow_replacements
)
2461 root
->grp_total_scalarization
= 0;
2464 if (!hole
|| root
->grp_total_scalarization
)
2465 root
->grp_covered
= 1;
2466 else if (root
->grp_write
|| comes_initialized_p (root
->base
))
2467 root
->grp_unscalarized_data
= 1; /* not covered and written to */
2471 /* Analyze all access trees linked by next_grp by the means of
2472 analyze_access_subtree. */
2474 analyze_access_trees (struct access
*access
)
2480 if (analyze_access_subtree (access
, NULL
, true))
2482 access
= access
->next_grp
;
2488 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2489 SIZE would conflict with an already existing one. If exactly such a child
2490 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2493 child_would_conflict_in_lacc (struct access
*lacc
, HOST_WIDE_INT norm_offset
,
2494 HOST_WIDE_INT size
, struct access
**exact_match
)
2496 struct access
*child
;
2498 for (child
= lacc
->first_child
; child
; child
= child
->next_sibling
)
2500 if (child
->offset
== norm_offset
&& child
->size
== size
)
2502 *exact_match
= child
;
2506 if (child
->offset
< norm_offset
+ size
2507 && child
->offset
+ child
->size
> norm_offset
)
2514 /* Create a new child access of PARENT, with all properties just like MODEL
2515 except for its offset and with its grp_write false and grp_read true.
2516 Return the new access or NULL if it cannot be created. Note that this
2517 access is created long after all splicing and sorting, it's not located in
2518 any access vector and is automatically a representative of its group. Set
2519 the gpr_write flag of the new accesss if SET_GRP_WRITE is true. */
2521 static struct access
*
2522 create_artificial_child_access (struct access
*parent
, struct access
*model
,
2523 HOST_WIDE_INT new_offset
,
2526 struct access
**child
;
2527 tree expr
= parent
->base
;
2529 gcc_assert (!model
->grp_unscalarizable_region
);
2531 struct access
*access
= access_pool
.allocate ();
2532 memset (access
, 0, sizeof (struct access
));
2533 if (!build_user_friendly_ref_for_offset (&expr
, TREE_TYPE (expr
), new_offset
,
2536 access
->grp_no_warning
= true;
2537 expr
= build_ref_for_model (EXPR_LOCATION (parent
->base
), parent
->base
,
2538 new_offset
, model
, NULL
, false);
2541 access
->base
= parent
->base
;
2542 access
->expr
= expr
;
2543 access
->offset
= new_offset
;
2544 access
->size
= model
->size
;
2545 access
->type
= model
->type
;
2546 access
->grp_write
= set_grp_write
;
2547 access
->grp_read
= false;
2548 access
->reverse
= model
->reverse
;
2550 child
= &parent
->first_child
;
2551 while (*child
&& (*child
)->offset
< new_offset
)
2552 child
= &(*child
)->next_sibling
;
2554 access
->next_sibling
= *child
;
2561 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
2562 true if any new subaccess was created. Additionally, if RACC is a scalar
2563 access but LACC is not, change the type of the latter, if possible. */
2566 propagate_subaccesses_across_link (struct access
*lacc
, struct access
*racc
)
2568 struct access
*rchild
;
2569 HOST_WIDE_INT norm_delta
= lacc
->offset
- racc
->offset
;
2572 /* IF the LHS is still not marked as being written to, we only need to do so
2573 if the RHS at this level actually was. */
2574 if (!lacc
->grp_write
)
2576 gcc_checking_assert (!comes_initialized_p (racc
->base
));
2577 if (racc
->grp_write
)
2579 lacc
->grp_write
= true;
2584 if (is_gimple_reg_type (lacc
->type
)
2585 || lacc
->grp_unscalarizable_region
2586 || racc
->grp_unscalarizable_region
)
2588 ret
|= !lacc
->grp_write
;
2589 lacc
->grp_write
= true;
2593 if (is_gimple_reg_type (racc
->type
))
2595 if (!lacc
->first_child
&& !racc
->first_child
)
2597 tree t
= lacc
->base
;
2599 lacc
->type
= racc
->type
;
2600 if (build_user_friendly_ref_for_offset (&t
, TREE_TYPE (t
),
2601 lacc
->offset
, racc
->type
))
2605 lacc
->expr
= build_ref_for_model (EXPR_LOCATION (lacc
->base
),
2606 lacc
->base
, lacc
->offset
,
2608 lacc
->grp_no_warning
= true;
2614 for (rchild
= racc
->first_child
; rchild
; rchild
= rchild
->next_sibling
)
2616 struct access
*new_acc
= NULL
;
2617 HOST_WIDE_INT norm_offset
= rchild
->offset
+ norm_delta
;
2619 if (rchild
->grp_unscalarizable_region
)
2621 lacc
->grp_write
= true;
2625 if (child_would_conflict_in_lacc (lacc
, norm_offset
, rchild
->size
,
2630 if (!new_acc
->grp_write
2631 && (lacc
->grp_write
|| rchild
->grp_write
))
2633 new_acc
->grp_write
= true;
2637 rchild
->grp_hint
= 1;
2638 new_acc
->grp_hint
|= new_acc
->grp_read
;
2639 if (rchild
->first_child
)
2640 ret
|= propagate_subaccesses_across_link (new_acc
, rchild
);
2643 lacc
->grp_write
= true;
2647 rchild
->grp_hint
= 1;
2648 new_acc
= create_artificial_child_access (lacc
, rchild
, norm_offset
,
2650 || rchild
->grp_write
);
2654 if (racc
->first_child
)
2655 propagate_subaccesses_across_link (new_acc
, rchild
);
2662 /* Beginning with ACCESS, traverse its whole access subtree and mark all
2663 sub-trees as written to. If any of them has not been marked so previously
2664 and has assignment links leading from it, re-enqueue it. */
2667 subtree_mark_written_and_enqueue (struct access
*access
)
2669 if (access
->grp_write
)
2671 access
->grp_write
= true;
2672 add_access_to_work_queue (access
);
2674 struct access
*child
;
2675 for (child
= access
->first_child
; child
; child
= child
->next_sibling
)
2676 subtree_mark_written_and_enqueue (child
);
2681 /* Propagate all subaccesses across assignment links. */
2684 propagate_all_subaccesses (void)
2686 while (work_queue_head
)
2688 struct access
*racc
= pop_access_from_work_queue ();
2689 struct assign_link
*link
;
2691 gcc_assert (racc
->first_link
);
2693 for (link
= racc
->first_link
; link
; link
= link
->next
)
2695 struct access
*lacc
= link
->lacc
;
2697 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (lacc
->base
)))
2699 lacc
= lacc
->group_representative
;
2701 bool reque_parents
= false;
2702 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (racc
->base
)))
2704 if (!lacc
->grp_write
)
2706 subtree_mark_written_and_enqueue (lacc
);
2707 reque_parents
= true;
2710 else if (propagate_subaccesses_across_link (lacc
, racc
))
2711 reque_parents
= true;
2716 add_access_to_work_queue (lacc
);
2717 lacc
= lacc
->parent
;
2724 /* Go through all accesses collected throughout the (intraprocedural) analysis
2725 stage, exclude overlapping ones, identify representatives and build trees
2726 out of them, making decisions about scalarization on the way. Return true
2727 iff there are any to-be-scalarized variables after this stage. */
2730 analyze_all_variable_accesses (void)
2733 bitmap tmp
= BITMAP_ALLOC (NULL
);
2736 bool optimize_speed_p
= !optimize_function_for_size_p (cfun
);
2738 enum compiler_param param
= optimize_speed_p
2739 ? PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED
2740 : PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE
;
2742 /* If the user didn't set PARAM_SRA_MAX_SCALARIZATION_SIZE_<...>,
2743 fall back to a target default. */
2744 unsigned HOST_WIDE_INT max_scalarization_size
2745 = global_options_set
.x_param_values
[param
]
2746 ? PARAM_VALUE (param
)
2747 : get_move_ratio (optimize_speed_p
) * UNITS_PER_WORD
;
2749 max_scalarization_size
*= BITS_PER_UNIT
;
2751 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap
, 0, i
, bi
)
2752 if (bitmap_bit_p (should_scalarize_away_bitmap
, i
)
2753 && !bitmap_bit_p (cannot_scalarize_away_bitmap
, i
))
2755 tree var
= candidate (i
);
2757 if (VAR_P (var
) && scalarizable_type_p (TREE_TYPE (var
),
2758 constant_decl_p (var
)))
2760 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var
)))
2761 <= max_scalarization_size
)
2763 create_total_scalarization_access (var
);
2764 completely_scalarize (var
, TREE_TYPE (var
), 0, var
);
2765 statistics_counter_event (cfun
,
2766 "Totally-scalarized aggregates", 1);
2767 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2769 fprintf (dump_file
, "Will attempt to totally scalarize ");
2770 print_generic_expr (dump_file
, var
);
2771 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (var
));
2774 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2776 fprintf (dump_file
, "Too big to totally scalarize: ");
2777 print_generic_expr (dump_file
, var
);
2778 fprintf (dump_file
, " (UID: %u)\n", DECL_UID (var
));
2783 bitmap_copy (tmp
, candidate_bitmap
);
2784 EXECUTE_IF_SET_IN_BITMAP (tmp
, 0, i
, bi
)
2786 tree var
= candidate (i
);
2787 struct access
*access
;
2789 access
= sort_and_splice_var_accesses (var
);
2790 if (!access
|| !build_access_trees (access
))
2791 disqualify_candidate (var
,
2792 "No or inhibitingly overlapping accesses.");
2795 propagate_all_subaccesses ();
2797 bitmap_copy (tmp
, candidate_bitmap
);
2798 EXECUTE_IF_SET_IN_BITMAP (tmp
, 0, i
, bi
)
2800 tree var
= candidate (i
);
2801 struct access
*access
= get_first_repr_for_decl (var
);
2803 if (analyze_access_trees (access
))
2806 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2808 fprintf (dump_file
, "\nAccess trees for ");
2809 print_generic_expr (dump_file
, var
);
2810 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (var
));
2811 dump_access_tree (dump_file
, access
);
2812 fprintf (dump_file
, "\n");
2816 disqualify_candidate (var
, "No scalar replacements to be created.");
2823 statistics_counter_event (cfun
, "Scalarized aggregates", res
);
2830 /* Generate statements copying scalar replacements of accesses within a subtree
2831 into or out of AGG. ACCESS, all its children, siblings and their children
2832 are to be processed. AGG is an aggregate type expression (can be a
2833 declaration but does not have to be, it can for example also be a mem_ref or
2834 a series of handled components). TOP_OFFSET is the offset of the processed
2835 subtree which has to be subtracted from offsets of individual accesses to
2836 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2837 replacements in the interval <start_offset, start_offset + chunk_size>,
2838 otherwise copy all. GSI is a statement iterator used to place the new
2839 statements. WRITE should be true when the statements should write from AGG
2840 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2841 statements will be added after the current statement in GSI, they will be
2842 added before the statement otherwise. */
2845 generate_subtree_copies (struct access
*access
, tree agg
,
2846 HOST_WIDE_INT top_offset
,
2847 HOST_WIDE_INT start_offset
, HOST_WIDE_INT chunk_size
,
2848 gimple_stmt_iterator
*gsi
, bool write
,
2849 bool insert_after
, location_t loc
)
2851 /* Never write anything into constant pool decls. See PR70602. */
2852 if (!write
&& constant_decl_p (agg
))
2856 if (chunk_size
&& access
->offset
>= start_offset
+ chunk_size
)
2859 if (access
->grp_to_be_replaced
2861 || access
->offset
+ access
->size
> start_offset
))
2863 tree expr
, repl
= get_access_replacement (access
);
2866 expr
= build_ref_for_model (loc
, agg
, access
->offset
- top_offset
,
2867 access
, gsi
, insert_after
);
2871 if (access
->grp_partial_lhs
)
2872 expr
= force_gimple_operand_gsi (gsi
, expr
, true, NULL_TREE
,
2874 insert_after
? GSI_NEW_STMT
2876 stmt
= gimple_build_assign (repl
, expr
);
2880 TREE_NO_WARNING (repl
) = 1;
2881 if (access
->grp_partial_lhs
)
2882 repl
= force_gimple_operand_gsi (gsi
, repl
, true, NULL_TREE
,
2884 insert_after
? GSI_NEW_STMT
2886 stmt
= gimple_build_assign (expr
, repl
);
2888 gimple_set_location (stmt
, loc
);
2891 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2893 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2895 sra_stats
.subtree_copies
++;
2898 && access
->grp_to_be_debug_replaced
2900 || access
->offset
+ access
->size
> start_offset
))
2903 tree drhs
= build_debug_ref_for_model (loc
, agg
,
2904 access
->offset
- top_offset
,
2906 ds
= gimple_build_debug_bind (get_access_replacement (access
),
2907 drhs
, gsi_stmt (*gsi
));
2909 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2911 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
2914 if (access
->first_child
)
2915 generate_subtree_copies (access
->first_child
, agg
, top_offset
,
2916 start_offset
, chunk_size
, gsi
,
2917 write
, insert_after
, loc
);
2919 access
= access
->next_sibling
;
2924 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2925 root of the subtree to be processed. GSI is the statement iterator used
2926 for inserting statements which are added after the current statement if
2927 INSERT_AFTER is true or before it otherwise. */
2930 init_subtree_with_zero (struct access
*access
, gimple_stmt_iterator
*gsi
,
2931 bool insert_after
, location_t loc
)
2934 struct access
*child
;
2936 if (access
->grp_to_be_replaced
)
2940 stmt
= gimple_build_assign (get_access_replacement (access
),
2941 build_zero_cst (access
->type
));
2943 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2945 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2947 gimple_set_location (stmt
, loc
);
2949 else if (access
->grp_to_be_debug_replaced
)
2952 = gimple_build_debug_bind (get_access_replacement (access
),
2953 build_zero_cst (access
->type
),
2956 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2958 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
2961 for (child
= access
->first_child
; child
; child
= child
->next_sibling
)
2962 init_subtree_with_zero (child
, gsi
, insert_after
, loc
);
2965 /* Clobber all scalar replacements in an access subtree. ACCESS is the
2966 root of the subtree to be processed. GSI is the statement iterator used
2967 for inserting statements which are added after the current statement if
2968 INSERT_AFTER is true or before it otherwise. */
2971 clobber_subtree (struct access
*access
, gimple_stmt_iterator
*gsi
,
2972 bool insert_after
, location_t loc
)
2975 struct access
*child
;
2977 if (access
->grp_to_be_replaced
)
2979 tree rep
= get_access_replacement (access
);
2980 tree clobber
= build_constructor (access
->type
, NULL
);
2981 TREE_THIS_VOLATILE (clobber
) = 1;
2982 gimple
*stmt
= gimple_build_assign (rep
, clobber
);
2985 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2987 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2989 gimple_set_location (stmt
, loc
);
2992 for (child
= access
->first_child
; child
; child
= child
->next_sibling
)
2993 clobber_subtree (child
, gsi
, insert_after
, loc
);
2996 /* Search for an access representative for the given expression EXPR and
2997 return it or NULL if it cannot be found. */
2999 static struct access
*
3000 get_access_for_expr (tree expr
)
3002 HOST_WIDE_INT offset
, size
, max_size
;
3006 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
3007 a different size than the size of its argument and we need the latter
3009 if (TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
3010 expr
= TREE_OPERAND (expr
, 0);
3012 base
= get_ref_base_and_extent (expr
, &offset
, &size
, &max_size
, &reverse
);
3013 if (max_size
== -1 || !DECL_P (base
))
3016 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (base
)))
3019 return get_var_base_offset_size_access (base
, offset
, max_size
);
3022 /* Replace the expression EXPR with a scalar replacement if there is one and
3023 generate other statements to do type conversion or subtree copying if
3024 necessary. GSI is used to place newly created statements, WRITE is true if
3025 the expression is being written to (it is on a LHS of a statement or output
3026 in an assembly statement). */
3029 sra_modify_expr (tree
*expr
, gimple_stmt_iterator
*gsi
, bool write
)
3032 struct access
*access
;
3033 tree type
, bfr
, orig_expr
;
3035 if (TREE_CODE (*expr
) == BIT_FIELD_REF
)
3038 expr
= &TREE_OPERAND (*expr
, 0);
3043 if (TREE_CODE (*expr
) == REALPART_EXPR
|| TREE_CODE (*expr
) == IMAGPART_EXPR
)
3044 expr
= &TREE_OPERAND (*expr
, 0);
3045 access
= get_access_for_expr (*expr
);
3048 type
= TREE_TYPE (*expr
);
3051 loc
= gimple_location (gsi_stmt (*gsi
));
3052 gimple_stmt_iterator alt_gsi
= gsi_none ();
3053 if (write
&& stmt_ends_bb_p (gsi_stmt (*gsi
)))
3055 alt_gsi
= gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi
)));
3059 if (access
->grp_to_be_replaced
)
3061 tree repl
= get_access_replacement (access
);
3062 /* If we replace a non-register typed access simply use the original
3063 access expression to extract the scalar component afterwards.
3064 This happens if scalarizing a function return value or parameter
3065 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
3066 gcc.c-torture/compile/20011217-1.c.
3068 We also want to use this when accessing a complex or vector which can
3069 be accessed as a different type too, potentially creating a need for
3070 type conversion (see PR42196) and when scalarized unions are involved
3071 in assembler statements (see PR42398). */
3072 if (!useless_type_conversion_p (type
, access
->type
))
3076 ref
= build_ref_for_model (loc
, orig_expr
, 0, access
, gsi
, false);
3082 if (access
->grp_partial_lhs
)
3083 ref
= force_gimple_operand_gsi (gsi
, ref
, true, NULL_TREE
,
3084 false, GSI_NEW_STMT
);
3085 stmt
= gimple_build_assign (repl
, ref
);
3086 gimple_set_location (stmt
, loc
);
3087 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
3093 if (access
->grp_partial_lhs
)
3094 repl
= force_gimple_operand_gsi (gsi
, repl
, true, NULL_TREE
,
3095 true, GSI_SAME_STMT
);
3096 stmt
= gimple_build_assign (ref
, repl
);
3097 gimple_set_location (stmt
, loc
);
3098 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
3105 else if (write
&& access
->grp_to_be_debug_replaced
)
3107 gdebug
*ds
= gimple_build_debug_bind (get_access_replacement (access
),
3110 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
3113 if (access
->first_child
)
3115 HOST_WIDE_INT start_offset
, chunk_size
;
3117 && tree_fits_uhwi_p (TREE_OPERAND (bfr
, 1))
3118 && tree_fits_uhwi_p (TREE_OPERAND (bfr
, 2)))
3120 chunk_size
= tree_to_uhwi (TREE_OPERAND (bfr
, 1));
3121 start_offset
= access
->offset
3122 + tree_to_uhwi (TREE_OPERAND (bfr
, 2));
3125 start_offset
= chunk_size
= 0;
3127 generate_subtree_copies (access
->first_child
, orig_expr
, access
->offset
,
3128 start_offset
, chunk_size
, gsi
, write
, write
,
3134 /* Where scalar replacements of the RHS have been written to when a replacement
3135 of a LHS of an assigments cannot be direclty loaded from a replacement of
3137 enum unscalarized_data_handling
{ SRA_UDH_NONE
, /* Nothing done so far. */
3138 SRA_UDH_RIGHT
, /* Data flushed to the RHS. */
3139 SRA_UDH_LEFT
}; /* Data flushed to the LHS. */
3141 struct subreplacement_assignment_data
3143 /* Offset of the access representing the lhs of the assignment. */
3144 HOST_WIDE_INT left_offset
;
3146 /* LHS and RHS of the original assignment. */
3147 tree assignment_lhs
, assignment_rhs
;
3149 /* Access representing the rhs of the whole assignment. */
3150 struct access
*top_racc
;
3152 /* Stmt iterator used for statement insertions after the original assignment.
3153 It points to the main GSI used to traverse a BB during function body
3155 gimple_stmt_iterator
*new_gsi
;
3157 /* Stmt iterator used for statement insertions before the original
3158 assignment. Keeps on pointing to the original statement. */
3159 gimple_stmt_iterator old_gsi
;
3161 /* Location of the assignment. */
3164 /* Keeps the information whether we have needed to refresh replacements of
3165 the LHS and from which side of the assignments this takes place. */
3166 enum unscalarized_data_handling refreshed
;
3169 /* Store all replacements in the access tree rooted in TOP_RACC either to their
3170 base aggregate if there are unscalarized data or directly to LHS of the
3171 statement that is pointed to by GSI otherwise. */
3174 handle_unscalarized_data_in_subtree (struct subreplacement_assignment_data
*sad
)
3177 if (sad
->top_racc
->grp_unscalarized_data
)
3179 src
= sad
->assignment_rhs
;
3180 sad
->refreshed
= SRA_UDH_RIGHT
;
3184 src
= sad
->assignment_lhs
;
3185 sad
->refreshed
= SRA_UDH_LEFT
;
3187 generate_subtree_copies (sad
->top_racc
->first_child
, src
,
3188 sad
->top_racc
->offset
, 0, 0,
3189 &sad
->old_gsi
, false, false, sad
->loc
);
3192 /* Try to generate statements to load all sub-replacements in an access subtree
3193 formed by children of LACC from scalar replacements in the SAD->top_racc
3194 subtree. If that is not possible, refresh the SAD->top_racc base aggregate
3195 and load the accesses from it. */
3198 load_assign_lhs_subreplacements (struct access
*lacc
,
3199 struct subreplacement_assignment_data
*sad
)
3201 for (lacc
= lacc
->first_child
; lacc
; lacc
= lacc
->next_sibling
)
3203 HOST_WIDE_INT offset
;
3204 offset
= lacc
->offset
- sad
->left_offset
+ sad
->top_racc
->offset
;
3206 if (lacc
->grp_to_be_replaced
)
3208 struct access
*racc
;
3212 racc
= find_access_in_subtree (sad
->top_racc
, offset
, lacc
->size
);
3213 if (racc
&& racc
->grp_to_be_replaced
)
3215 rhs
= get_access_replacement (racc
);
3216 if (!useless_type_conversion_p (lacc
->type
, racc
->type
))
3217 rhs
= fold_build1_loc (sad
->loc
, VIEW_CONVERT_EXPR
,
3220 if (racc
->grp_partial_lhs
&& lacc
->grp_partial_lhs
)
3221 rhs
= force_gimple_operand_gsi (&sad
->old_gsi
, rhs
, true,
3222 NULL_TREE
, true, GSI_SAME_STMT
);
3226 /* No suitable access on the right hand side, need to load from
3227 the aggregate. See if we have to update it first... */
3228 if (sad
->refreshed
== SRA_UDH_NONE
)
3229 handle_unscalarized_data_in_subtree (sad
);
3231 if (sad
->refreshed
== SRA_UDH_LEFT
)
3232 rhs
= build_ref_for_model (sad
->loc
, sad
->assignment_lhs
,
3233 lacc
->offset
- sad
->left_offset
,
3234 lacc
, sad
->new_gsi
, true);
3236 rhs
= build_ref_for_model (sad
->loc
, sad
->assignment_rhs
,
3237 lacc
->offset
- sad
->left_offset
,
3238 lacc
, sad
->new_gsi
, true);
3239 if (lacc
->grp_partial_lhs
)
3240 rhs
= force_gimple_operand_gsi (sad
->new_gsi
,
3241 rhs
, true, NULL_TREE
,
3242 false, GSI_NEW_STMT
);
3245 stmt
= gimple_build_assign (get_access_replacement (lacc
), rhs
);
3246 gsi_insert_after (sad
->new_gsi
, stmt
, GSI_NEW_STMT
);
3247 gimple_set_location (stmt
, sad
->loc
);
3249 sra_stats
.subreplacements
++;
3253 if (sad
->refreshed
== SRA_UDH_NONE
3254 && lacc
->grp_read
&& !lacc
->grp_covered
)
3255 handle_unscalarized_data_in_subtree (sad
);
3257 if (lacc
&& lacc
->grp_to_be_debug_replaced
)
3261 struct access
*racc
= find_access_in_subtree (sad
->top_racc
,
3265 if (racc
&& racc
->grp_to_be_replaced
)
3267 if (racc
->grp_write
|| constant_decl_p (racc
->base
))
3268 drhs
= get_access_replacement (racc
);
3272 else if (sad
->refreshed
== SRA_UDH_LEFT
)
3273 drhs
= build_debug_ref_for_model (sad
->loc
, lacc
->base
,
3274 lacc
->offset
, lacc
);
3275 else if (sad
->refreshed
== SRA_UDH_RIGHT
)
3276 drhs
= build_debug_ref_for_model (sad
->loc
, sad
->top_racc
->base
,
3281 && !useless_type_conversion_p (lacc
->type
, TREE_TYPE (drhs
)))
3282 drhs
= fold_build1_loc (sad
->loc
, VIEW_CONVERT_EXPR
,
3284 ds
= gimple_build_debug_bind (get_access_replacement (lacc
),
3285 drhs
, gsi_stmt (sad
->old_gsi
));
3286 gsi_insert_after (sad
->new_gsi
, ds
, GSI_NEW_STMT
);
3290 if (lacc
->first_child
)
3291 load_assign_lhs_subreplacements (lacc
, sad
);
3295 /* Result code for SRA assignment modification. */
3296 enum assignment_mod_result
{ SRA_AM_NONE
, /* nothing done for the stmt */
3297 SRA_AM_MODIFIED
, /* stmt changed but not
3299 SRA_AM_REMOVED
}; /* stmt eliminated */
3301 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
3302 to the assignment and GSI is the statement iterator pointing at it. Returns
3303 the same values as sra_modify_assign. */
3305 static enum assignment_mod_result
3306 sra_modify_constructor_assign (gimple
*stmt
, gimple_stmt_iterator
*gsi
)
3308 tree lhs
= gimple_assign_lhs (stmt
);
3309 struct access
*acc
= get_access_for_expr (lhs
);
3312 location_t loc
= gimple_location (stmt
);
3314 if (gimple_clobber_p (stmt
))
3316 /* Clobber the replacement variable. */
3317 clobber_subtree (acc
, gsi
, !acc
->grp_covered
, loc
);
3318 /* Remove clobbers of fully scalarized variables, they are dead. */
3319 if (acc
->grp_covered
)
3321 unlink_stmt_vdef (stmt
);
3322 gsi_remove (gsi
, true);
3323 release_defs (stmt
);
3324 return SRA_AM_REMOVED
;
3327 return SRA_AM_MODIFIED
;
3330 if (CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt
)) > 0)
3332 /* I have never seen this code path trigger but if it can happen the
3333 following should handle it gracefully. */
3334 if (access_has_children_p (acc
))
3335 generate_subtree_copies (acc
->first_child
, lhs
, acc
->offset
, 0, 0, gsi
,
3337 return SRA_AM_MODIFIED
;
3340 if (acc
->grp_covered
)
3342 init_subtree_with_zero (acc
, gsi
, false, loc
);
3343 unlink_stmt_vdef (stmt
);
3344 gsi_remove (gsi
, true);
3345 release_defs (stmt
);
3346 return SRA_AM_REMOVED
;
3350 init_subtree_with_zero (acc
, gsi
, true, loc
);
3351 return SRA_AM_MODIFIED
;
3355 /* Create and return a new suitable default definition SSA_NAME for RACC which
3356 is an access describing an uninitialized part of an aggregate that is being
3360 get_repl_default_def_ssa_name (struct access
*racc
)
3362 gcc_checking_assert (!racc
->grp_to_be_replaced
3363 && !racc
->grp_to_be_debug_replaced
);
3364 if (!racc
->replacement_decl
)
3365 racc
->replacement_decl
= create_access_replacement (racc
);
3366 return get_or_create_ssa_default_def (cfun
, racc
->replacement_decl
);
3369 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3370 bit-field field declaration somewhere in it. */
3373 contains_vce_or_bfcref_p (const_tree ref
)
3375 while (handled_component_p (ref
))
3377 if (TREE_CODE (ref
) == VIEW_CONVERT_EXPR
3378 || (TREE_CODE (ref
) == COMPONENT_REF
3379 && DECL_BIT_FIELD (TREE_OPERAND (ref
, 1))))
3381 ref
= TREE_OPERAND (ref
, 0);
3387 /* Examine both sides of the assignment statement pointed to by STMT, replace
3388 them with a scalare replacement if there is one and generate copying of
3389 replacements if scalarized aggregates have been used in the assignment. GSI
3390 is used to hold generated statements for type conversions and subtree
3393 static enum assignment_mod_result
3394 sra_modify_assign (gimple
*stmt
, gimple_stmt_iterator
*gsi
)
3396 struct access
*lacc
, *racc
;
3398 bool modify_this_stmt
= false;
3399 bool force_gimple_rhs
= false;
3401 gimple_stmt_iterator orig_gsi
= *gsi
;
3403 if (!gimple_assign_single_p (stmt
))
3405 lhs
= gimple_assign_lhs (stmt
);
3406 rhs
= gimple_assign_rhs1 (stmt
);
3408 if (TREE_CODE (rhs
) == CONSTRUCTOR
)
3409 return sra_modify_constructor_assign (stmt
, gsi
);
3411 if (TREE_CODE (rhs
) == REALPART_EXPR
|| TREE_CODE (lhs
) == REALPART_EXPR
3412 || TREE_CODE (rhs
) == IMAGPART_EXPR
|| TREE_CODE (lhs
) == IMAGPART_EXPR
3413 || TREE_CODE (rhs
) == BIT_FIELD_REF
|| TREE_CODE (lhs
) == BIT_FIELD_REF
)
3415 modify_this_stmt
= sra_modify_expr (gimple_assign_rhs1_ptr (stmt
),
3417 modify_this_stmt
|= sra_modify_expr (gimple_assign_lhs_ptr (stmt
),
3419 return modify_this_stmt
? SRA_AM_MODIFIED
: SRA_AM_NONE
;
3422 lacc
= get_access_for_expr (lhs
);
3423 racc
= get_access_for_expr (rhs
);
3426 /* Avoid modifying initializations of constant-pool replacements. */
3427 if (racc
&& (racc
->replacement_decl
== lhs
))
3430 loc
= gimple_location (stmt
);
3431 if (lacc
&& lacc
->grp_to_be_replaced
)
3433 lhs
= get_access_replacement (lacc
);
3434 gimple_assign_set_lhs (stmt
, lhs
);
3435 modify_this_stmt
= true;
3436 if (lacc
->grp_partial_lhs
)
3437 force_gimple_rhs
= true;
3441 if (racc
&& racc
->grp_to_be_replaced
)
3443 rhs
= get_access_replacement (racc
);
3444 modify_this_stmt
= true;
3445 if (racc
->grp_partial_lhs
)
3446 force_gimple_rhs
= true;
3450 && !racc
->grp_unscalarized_data
3451 && !racc
->grp_unscalarizable_region
3452 && TREE_CODE (lhs
) == SSA_NAME
3453 && !access_has_replacements_p (racc
))
3455 rhs
= get_repl_default_def_ssa_name (racc
);
3456 modify_this_stmt
= true;
3460 if (modify_this_stmt
)
3462 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
3464 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3465 ??? This should move to fold_stmt which we simply should
3466 call after building a VIEW_CONVERT_EXPR here. */
3467 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs
))
3468 && !contains_bitfld_component_ref_p (lhs
))
3470 lhs
= build_ref_for_model (loc
, lhs
, 0, racc
, gsi
, false);
3471 gimple_assign_set_lhs (stmt
, lhs
);
3473 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs
))
3474 && !contains_vce_or_bfcref_p (rhs
))
3475 rhs
= build_ref_for_model (loc
, rhs
, 0, lacc
, gsi
, false);
3477 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
3479 rhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, TREE_TYPE (lhs
),
3481 if (is_gimple_reg_type (TREE_TYPE (lhs
))
3482 && TREE_CODE (lhs
) != SSA_NAME
)
3483 force_gimple_rhs
= true;
3488 if (lacc
&& lacc
->grp_to_be_debug_replaced
)
3490 tree dlhs
= get_access_replacement (lacc
);
3491 tree drhs
= unshare_expr (rhs
);
3492 if (!useless_type_conversion_p (TREE_TYPE (dlhs
), TREE_TYPE (drhs
)))
3494 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs
))
3495 && !contains_vce_or_bfcref_p (drhs
))
3496 drhs
= build_debug_ref_for_model (loc
, drhs
, 0, lacc
);
3498 && !useless_type_conversion_p (TREE_TYPE (dlhs
),
3500 drhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
,
3501 TREE_TYPE (dlhs
), drhs
);
3503 gdebug
*ds
= gimple_build_debug_bind (dlhs
, drhs
, stmt
);
3504 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
3507 /* From this point on, the function deals with assignments in between
3508 aggregates when at least one has scalar reductions of some of its
3509 components. There are three possible scenarios: Both the LHS and RHS have
3510 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3512 In the first case, we would like to load the LHS components from RHS
3513 components whenever possible. If that is not possible, we would like to
3514 read it directly from the RHS (after updating it by storing in it its own
3515 components). If there are some necessary unscalarized data in the LHS,
3516 those will be loaded by the original assignment too. If neither of these
3517 cases happen, the original statement can be removed. Most of this is done
3518 by load_assign_lhs_subreplacements.
3520 In the second case, we would like to store all RHS scalarized components
3521 directly into LHS and if they cover the aggregate completely, remove the
3522 statement too. In the third case, we want the LHS components to be loaded
3523 directly from the RHS (DSE will remove the original statement if it
3526 This is a bit complex but manageable when types match and when unions do
3527 not cause confusion in a way that we cannot really load a component of LHS
3528 from the RHS or vice versa (the access representing this level can have
3529 subaccesses that are accessible only through a different union field at a
3530 higher level - different from the one used in the examined expression).
3533 Therefore, I specially handle a fourth case, happening when there is a
3534 specific type cast or it is impossible to locate a scalarized subaccess on
3535 the other side of the expression. If that happens, I simply "refresh" the
3536 RHS by storing in it is scalarized components leave the original statement
3537 there to do the copying and then load the scalar replacements of the LHS.
3538 This is what the first branch does. */
3540 if (modify_this_stmt
3541 || gimple_has_volatile_ops (stmt
)
3542 || contains_vce_or_bfcref_p (rhs
)
3543 || contains_vce_or_bfcref_p (lhs
)
3544 || stmt_ends_bb_p (stmt
))
3546 /* No need to copy into a constant-pool, it comes pre-initialized. */
3547 if (access_has_children_p (racc
) && !constant_decl_p (racc
->base
))
3548 generate_subtree_copies (racc
->first_child
, rhs
, racc
->offset
, 0, 0,
3549 gsi
, false, false, loc
);
3550 if (access_has_children_p (lacc
))
3552 gimple_stmt_iterator alt_gsi
= gsi_none ();
3553 if (stmt_ends_bb_p (stmt
))
3555 alt_gsi
= gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi
)));
3558 generate_subtree_copies (lacc
->first_child
, lhs
, lacc
->offset
, 0, 0,
3559 gsi
, true, true, loc
);
3561 sra_stats
.separate_lhs_rhs_handling
++;
3563 /* This gimplification must be done after generate_subtree_copies,
3564 lest we insert the subtree copies in the middle of the gimplified
3566 if (force_gimple_rhs
)
3567 rhs
= force_gimple_operand_gsi (&orig_gsi
, rhs
, true, NULL_TREE
,
3568 true, GSI_SAME_STMT
);
3569 if (gimple_assign_rhs1 (stmt
) != rhs
)
3571 modify_this_stmt
= true;
3572 gimple_assign_set_rhs_from_tree (&orig_gsi
, rhs
);
3573 gcc_assert (stmt
== gsi_stmt (orig_gsi
));
3576 return modify_this_stmt
? SRA_AM_MODIFIED
: SRA_AM_NONE
;
3580 if (access_has_children_p (lacc
)
3581 && access_has_children_p (racc
)
3582 /* When an access represents an unscalarizable region, it usually
3583 represents accesses with variable offset and thus must not be used
3584 to generate new memory accesses. */
3585 && !lacc
->grp_unscalarizable_region
3586 && !racc
->grp_unscalarizable_region
)
3588 struct subreplacement_assignment_data sad
;
3590 sad
.left_offset
= lacc
->offset
;
3591 sad
.assignment_lhs
= lhs
;
3592 sad
.assignment_rhs
= rhs
;
3593 sad
.top_racc
= racc
;
3596 sad
.loc
= gimple_location (stmt
);
3597 sad
.refreshed
= SRA_UDH_NONE
;
3599 if (lacc
->grp_read
&& !lacc
->grp_covered
)
3600 handle_unscalarized_data_in_subtree (&sad
);
3602 load_assign_lhs_subreplacements (lacc
, &sad
);
3603 if (sad
.refreshed
!= SRA_UDH_RIGHT
)
3606 unlink_stmt_vdef (stmt
);
3607 gsi_remove (&sad
.old_gsi
, true);
3608 release_defs (stmt
);
3609 sra_stats
.deleted
++;
3610 return SRA_AM_REMOVED
;
3615 if (access_has_children_p (racc
)
3616 && !racc
->grp_unscalarized_data
3617 && TREE_CODE (lhs
) != SSA_NAME
)
3621 fprintf (dump_file
, "Removing load: ");
3622 print_gimple_stmt (dump_file
, stmt
, 0);
3624 generate_subtree_copies (racc
->first_child
, lhs
,
3625 racc
->offset
, 0, 0, gsi
,
3627 gcc_assert (stmt
== gsi_stmt (*gsi
));
3628 unlink_stmt_vdef (stmt
);
3629 gsi_remove (gsi
, true);
3630 release_defs (stmt
);
3631 sra_stats
.deleted
++;
3632 return SRA_AM_REMOVED
;
3634 /* Restore the aggregate RHS from its components so the
3635 prevailing aggregate copy does the right thing. */
3636 if (access_has_children_p (racc
))
3637 generate_subtree_copies (racc
->first_child
, rhs
, racc
->offset
, 0, 0,
3638 gsi
, false, false, loc
);
3639 /* Re-load the components of the aggregate copy destination.
3640 But use the RHS aggregate to load from to expose more
3641 optimization opportunities. */
3642 if (access_has_children_p (lacc
))
3643 generate_subtree_copies (lacc
->first_child
, rhs
, lacc
->offset
,
3644 0, 0, gsi
, true, true, loc
);
3651 /* Set any scalar replacements of values in the constant pool to the initial
3652 value of the constant. (Constant-pool decls like *.LC0 have effectively
3653 been initialized before the program starts, we must do the same for their
3654 replacements.) Thus, we output statements like 'SR.1 = *.LC0[0];' into
3655 the function's entry block. */
3658 initialize_constant_pool_replacements (void)
3660 gimple_seq seq
= NULL
;
3661 gimple_stmt_iterator gsi
= gsi_start (seq
);
3665 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap
, 0, i
, bi
)
3667 tree var
= candidate (i
);
3668 if (!constant_decl_p (var
))
3670 vec
<access_p
> *access_vec
= get_base_access_vector (var
);
3673 for (unsigned i
= 0; i
< access_vec
->length (); i
++)
3675 struct access
*access
= (*access_vec
)[i
];
3676 if (!access
->replacement_decl
)
3679 = gimple_build_assign (get_access_replacement (access
),
3680 unshare_expr (access
->expr
));
3681 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3683 fprintf (dump_file
, "Generating constant initializer: ");
3684 print_gimple_stmt (dump_file
, stmt
, 0);
3685 fprintf (dump_file
, "\n");
3687 gsi_insert_after (&gsi
, stmt
, GSI_NEW_STMT
);
3692 seq
= gsi_seq (gsi
);
3694 gsi_insert_seq_on_edge_immediate (
3695 single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun
)), seq
);
3698 /* Traverse the function body and all modifications as decided in
3699 analyze_all_variable_accesses. Return true iff the CFG has been
3703 sra_modify_function_body (void)
3705 bool cfg_changed
= false;
3708 initialize_constant_pool_replacements ();
3710 FOR_EACH_BB_FN (bb
, cfun
)
3712 gimple_stmt_iterator gsi
= gsi_start_bb (bb
);
3713 while (!gsi_end_p (gsi
))
3715 gimple
*stmt
= gsi_stmt (gsi
);
3716 enum assignment_mod_result assign_result
;
3717 bool modified
= false, deleted
= false;
3721 switch (gimple_code (stmt
))
3724 t
= gimple_return_retval_ptr (as_a
<greturn
*> (stmt
));
3725 if (*t
!= NULL_TREE
)
3726 modified
|= sra_modify_expr (t
, &gsi
, false);
3730 assign_result
= sra_modify_assign (stmt
, &gsi
);
3731 modified
|= assign_result
== SRA_AM_MODIFIED
;
3732 deleted
= assign_result
== SRA_AM_REMOVED
;
3736 /* Operands must be processed before the lhs. */
3737 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
3739 t
= gimple_call_arg_ptr (stmt
, i
);
3740 modified
|= sra_modify_expr (t
, &gsi
, false);
3743 if (gimple_call_lhs (stmt
))
3745 t
= gimple_call_lhs_ptr (stmt
);
3746 modified
|= sra_modify_expr (t
, &gsi
, true);
3752 gasm
*asm_stmt
= as_a
<gasm
*> (stmt
);
3753 for (i
= 0; i
< gimple_asm_ninputs (asm_stmt
); i
++)
3755 t
= &TREE_VALUE (gimple_asm_input_op (asm_stmt
, i
));
3756 modified
|= sra_modify_expr (t
, &gsi
, false);
3758 for (i
= 0; i
< gimple_asm_noutputs (asm_stmt
); i
++)
3760 t
= &TREE_VALUE (gimple_asm_output_op (asm_stmt
, i
));
3761 modified
|= sra_modify_expr (t
, &gsi
, true);
3773 if (maybe_clean_eh_stmt (stmt
)
3774 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
3782 gsi_commit_edge_inserts ();
3786 /* Generate statements initializing scalar replacements of parts of function
3790 initialize_parameter_reductions (void)
3792 gimple_stmt_iterator gsi
;
3793 gimple_seq seq
= NULL
;
3796 gsi
= gsi_start (seq
);
3797 for (parm
= DECL_ARGUMENTS (current_function_decl
);
3799 parm
= DECL_CHAIN (parm
))
3801 vec
<access_p
> *access_vec
;
3802 struct access
*access
;
3804 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
3806 access_vec
= get_base_access_vector (parm
);
3810 for (access
= (*access_vec
)[0];
3812 access
= access
->next_grp
)
3813 generate_subtree_copies (access
, parm
, 0, 0, 0, &gsi
, true, true,
3814 EXPR_LOCATION (parm
));
3817 seq
= gsi_seq (gsi
);
3819 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun
)), seq
);
3822 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3823 it reveals there are components of some aggregates to be scalarized, it runs
3824 the required transformations. */
3826 perform_intra_sra (void)
3831 if (!find_var_candidates ())
3834 if (!scan_function ())
3837 if (!analyze_all_variable_accesses ())
3840 if (sra_modify_function_body ())
3841 ret
= TODO_update_ssa
| TODO_cleanup_cfg
;
3843 ret
= TODO_update_ssa
;
3844 initialize_parameter_reductions ();
3846 statistics_counter_event (cfun
, "Scalar replacements created",
3847 sra_stats
.replacements
);
3848 statistics_counter_event (cfun
, "Modified expressions", sra_stats
.exprs
);
3849 statistics_counter_event (cfun
, "Subtree copy stmts",
3850 sra_stats
.subtree_copies
);
3851 statistics_counter_event (cfun
, "Subreplacement stmts",
3852 sra_stats
.subreplacements
);
3853 statistics_counter_event (cfun
, "Deleted stmts", sra_stats
.deleted
);
3854 statistics_counter_event (cfun
, "Separate LHS and RHS handling",
3855 sra_stats
.separate_lhs_rhs_handling
);
3858 sra_deinitialize ();
3862 /* Perform early intraprocedural SRA. */
3864 early_intra_sra (void)
3866 sra_mode
= SRA_MODE_EARLY_INTRA
;
3867 return perform_intra_sra ();
3870 /* Perform "late" intraprocedural SRA. */
3872 late_intra_sra (void)
3874 sra_mode
= SRA_MODE_INTRA
;
3875 return perform_intra_sra ();
3880 gate_intra_sra (void)
3882 return flag_tree_sra
!= 0 && dbg_cnt (tree_sra
);
3888 const pass_data pass_data_sra_early
=
3890 GIMPLE_PASS
, /* type */
3892 OPTGROUP_NONE
, /* optinfo_flags */
3893 TV_TREE_SRA
, /* tv_id */
3894 ( PROP_cfg
| PROP_ssa
), /* properties_required */
3895 0, /* properties_provided */
3896 0, /* properties_destroyed */
3897 0, /* todo_flags_start */
3898 TODO_update_ssa
, /* todo_flags_finish */
3901 class pass_sra_early
: public gimple_opt_pass
3904 pass_sra_early (gcc::context
*ctxt
)
3905 : gimple_opt_pass (pass_data_sra_early
, ctxt
)
3908 /* opt_pass methods: */
3909 virtual bool gate (function
*) { return gate_intra_sra (); }
3910 virtual unsigned int execute (function
*) { return early_intra_sra (); }
3912 }; // class pass_sra_early
3917 make_pass_sra_early (gcc::context
*ctxt
)
3919 return new pass_sra_early (ctxt
);
3924 const pass_data pass_data_sra
=
3926 GIMPLE_PASS
, /* type */
3928 OPTGROUP_NONE
, /* optinfo_flags */
3929 TV_TREE_SRA
, /* tv_id */
3930 ( PROP_cfg
| PROP_ssa
), /* properties_required */
3931 0, /* properties_provided */
3932 0, /* properties_destroyed */
3933 TODO_update_address_taken
, /* todo_flags_start */
3934 TODO_update_ssa
, /* todo_flags_finish */
3937 class pass_sra
: public gimple_opt_pass
3940 pass_sra (gcc::context
*ctxt
)
3941 : gimple_opt_pass (pass_data_sra
, ctxt
)
3944 /* opt_pass methods: */
3945 virtual bool gate (function
*) { return gate_intra_sra (); }
3946 virtual unsigned int execute (function
*) { return late_intra_sra (); }
3948 }; // class pass_sra
3953 make_pass_sra (gcc::context
*ctxt
)
3955 return new pass_sra (ctxt
);
3959 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3963 is_unused_scalar_param (tree parm
)
3966 return (is_gimple_reg (parm
)
3967 && (!(name
= ssa_default_def (cfun
, parm
))
3968 || has_zero_uses (name
)));
3971 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3972 examine whether there are any direct or otherwise infeasible ones. If so,
3973 return true, otherwise return false. PARM must be a gimple register with a
3974 non-NULL default definition. */
3977 ptr_parm_has_direct_uses (tree parm
)
3979 imm_use_iterator ui
;
3981 tree name
= ssa_default_def (cfun
, parm
);
3984 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
3987 use_operand_p use_p
;
3989 if (is_gimple_debug (stmt
))
3992 /* Valid uses include dereferences on the lhs and the rhs. */
3993 if (gimple_has_lhs (stmt
))
3995 tree lhs
= gimple_get_lhs (stmt
);
3996 while (handled_component_p (lhs
))
3997 lhs
= TREE_OPERAND (lhs
, 0);
3998 if (TREE_CODE (lhs
) == MEM_REF
3999 && TREE_OPERAND (lhs
, 0) == name
4000 && integer_zerop (TREE_OPERAND (lhs
, 1))
4001 && types_compatible_p (TREE_TYPE (lhs
),
4002 TREE_TYPE (TREE_TYPE (name
)))
4003 && !TREE_THIS_VOLATILE (lhs
))
4006 if (gimple_assign_single_p (stmt
))
4008 tree rhs
= gimple_assign_rhs1 (stmt
);
4009 while (handled_component_p (rhs
))
4010 rhs
= TREE_OPERAND (rhs
, 0);
4011 if (TREE_CODE (rhs
) == MEM_REF
4012 && TREE_OPERAND (rhs
, 0) == name
4013 && integer_zerop (TREE_OPERAND (rhs
, 1))
4014 && types_compatible_p (TREE_TYPE (rhs
),
4015 TREE_TYPE (TREE_TYPE (name
)))
4016 && !TREE_THIS_VOLATILE (rhs
))
4019 else if (is_gimple_call (stmt
))
4022 for (i
= 0; i
< gimple_call_num_args (stmt
); ++i
)
4024 tree arg
= gimple_call_arg (stmt
, i
);
4025 while (handled_component_p (arg
))
4026 arg
= TREE_OPERAND (arg
, 0);
4027 if (TREE_CODE (arg
) == MEM_REF
4028 && TREE_OPERAND (arg
, 0) == name
4029 && integer_zerop (TREE_OPERAND (arg
, 1))
4030 && types_compatible_p (TREE_TYPE (arg
),
4031 TREE_TYPE (TREE_TYPE (name
)))
4032 && !TREE_THIS_VOLATILE (arg
))
4037 /* If the number of valid uses does not match the number of
4038 uses in this stmt there is an unhandled use. */
4039 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
4046 BREAK_FROM_IMM_USE_STMT (ui
);
4052 /* Identify candidates for reduction for IPA-SRA based on their type and mark
4053 them in candidate_bitmap. Note that these do not necessarily include
4054 parameter which are unused and thus can be removed. Return true iff any
4055 such candidate has been found. */
4058 find_param_candidates (void)
4065 for (parm
= DECL_ARGUMENTS (current_function_decl
);
4067 parm
= DECL_CHAIN (parm
))
4069 tree type
= TREE_TYPE (parm
);
4074 if (TREE_THIS_VOLATILE (parm
)
4075 || TREE_ADDRESSABLE (parm
)
4076 || (!is_gimple_reg_type (type
) && is_va_list_type (type
)))
4079 if (is_unused_scalar_param (parm
))
4085 if (POINTER_TYPE_P (type
))
4087 type
= TREE_TYPE (type
);
4089 if (TREE_CODE (type
) == FUNCTION_TYPE
4090 || TYPE_VOLATILE (type
)
4091 || (TREE_CODE (type
) == ARRAY_TYPE
4092 && TYPE_NONALIASED_COMPONENT (type
))
4093 || !is_gimple_reg (parm
)
4094 || is_va_list_type (type
)
4095 || ptr_parm_has_direct_uses (parm
))
4098 else if (!AGGREGATE_TYPE_P (type
))
4101 if (!COMPLETE_TYPE_P (type
)
4102 || !tree_fits_uhwi_p (TYPE_SIZE (type
))
4103 || tree_to_uhwi (TYPE_SIZE (type
)) == 0
4104 || (AGGREGATE_TYPE_P (type
)
4105 && type_internals_preclude_sra_p (type
, &msg
)))
4108 bitmap_set_bit (candidate_bitmap
, DECL_UID (parm
));
4109 slot
= candidates
->find_slot_with_hash (parm
, DECL_UID (parm
), INSERT
);
4113 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4115 fprintf (dump_file
, "Candidate (%d): ", DECL_UID (parm
));
4116 print_generic_expr (dump_file
, parm
);
4117 fprintf (dump_file
, "\n");
4121 func_param_count
= count
;
4125 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
4129 mark_maybe_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef ATTRIBUTE_UNUSED
,
4132 struct access
*repr
= (struct access
*) data
;
4134 repr
->grp_maybe_modified
= 1;
4138 /* Analyze what representatives (in linked lists accessible from
4139 REPRESENTATIVES) can be modified by side effects of statements in the
4140 current function. */
4143 analyze_modified_params (vec
<access_p
> representatives
)
4147 for (i
= 0; i
< func_param_count
; i
++)
4149 struct access
*repr
;
4151 for (repr
= representatives
[i
];
4153 repr
= repr
->next_grp
)
4155 struct access
*access
;
4159 if (no_accesses_p (repr
))
4161 if (!POINTER_TYPE_P (TREE_TYPE (repr
->base
))
4162 || repr
->grp_maybe_modified
)
4165 ao_ref_init (&ar
, repr
->expr
);
4166 visited
= BITMAP_ALLOC (NULL
);
4167 for (access
= repr
; access
; access
= access
->next_sibling
)
4169 /* All accesses are read ones, otherwise grp_maybe_modified would
4170 be trivially set. */
4171 walk_aliased_vdefs (&ar
, gimple_vuse (access
->stmt
),
4172 mark_maybe_modified
, repr
, &visited
);
4173 if (repr
->grp_maybe_modified
)
4176 BITMAP_FREE (visited
);
4181 /* Propagate distances in bb_dereferences in the opposite direction than the
4182 control flow edges, in each step storing the maximum of the current value
4183 and the minimum of all successors. These steps are repeated until the table
4184 stabilizes. Note that BBs which might terminate the functions (according to
4185 final_bbs bitmap) never updated in this way. */
4188 propagate_dereference_distances (void)
4192 auto_vec
<basic_block
> queue (last_basic_block_for_fn (cfun
));
4193 queue
.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
4194 FOR_EACH_BB_FN (bb
, cfun
)
4196 queue
.quick_push (bb
);
4200 while (!queue
.is_empty ())
4204 bool change
= false;
4210 if (bitmap_bit_p (final_bbs
, bb
->index
))
4213 for (i
= 0; i
< func_param_count
; i
++)
4215 int idx
= bb
->index
* func_param_count
+ i
;
4217 HOST_WIDE_INT inh
= 0;
4219 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
4221 int succ_idx
= e
->dest
->index
* func_param_count
+ i
;
4223 if (e
->src
== EXIT_BLOCK_PTR_FOR_FN (cfun
))
4229 inh
= bb_dereferences
[succ_idx
];
4231 else if (bb_dereferences
[succ_idx
] < inh
)
4232 inh
= bb_dereferences
[succ_idx
];
4235 if (!first
&& bb_dereferences
[idx
] < inh
)
4237 bb_dereferences
[idx
] = inh
;
4242 if (change
&& !bitmap_bit_p (final_bbs
, bb
->index
))
4243 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
4248 e
->src
->aux
= e
->src
;
4249 queue
.quick_push (e
->src
);
4254 /* Dump a dereferences TABLE with heading STR to file F. */
4257 dump_dereferences_table (FILE *f
, const char *str
, HOST_WIDE_INT
*table
)
4261 fprintf (dump_file
, "%s", str
);
4262 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR_FOR_FN (cfun
),
4263 EXIT_BLOCK_PTR_FOR_FN (cfun
), next_bb
)
4265 fprintf (f
, "%4i %i ", bb
->index
, bitmap_bit_p (final_bbs
, bb
->index
));
4266 if (bb
!= EXIT_BLOCK_PTR_FOR_FN (cfun
))
4269 for (i
= 0; i
< func_param_count
; i
++)
4271 int idx
= bb
->index
* func_param_count
+ i
;
4272 fprintf (f
, " %4" HOST_WIDE_INT_PRINT
"d", table
[idx
]);
4277 fprintf (dump_file
, "\n");
4280 /* Determine what (parts of) parameters passed by reference that are not
4281 assigned to are not certainly dereferenced in this function and thus the
4282 dereferencing cannot be safely moved to the caller without potentially
4283 introducing a segfault. Mark such REPRESENTATIVES as
4284 grp_not_necessarilly_dereferenced.
4286 The dereferenced maximum "distance," i.e. the offset + size of the accessed
4287 part is calculated rather than simple booleans are calculated for each
4288 pointer parameter to handle cases when only a fraction of the whole
4289 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
4292 The maximum dereference distances for each pointer parameter and BB are
4293 already stored in bb_dereference. This routine simply propagates these
4294 values upwards by propagate_dereference_distances and then compares the
4295 distances of individual parameters in the ENTRY BB to the equivalent
4296 distances of each representative of a (fraction of a) parameter. */
4299 analyze_caller_dereference_legality (vec
<access_p
> representatives
)
4303 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4304 dump_dereferences_table (dump_file
,
4305 "Dereference table before propagation:\n",
4308 propagate_dereference_distances ();
4310 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4311 dump_dereferences_table (dump_file
,
4312 "Dereference table after propagation:\n",
4315 for (i
= 0; i
< func_param_count
; i
++)
4317 struct access
*repr
= representatives
[i
];
4318 int idx
= ENTRY_BLOCK_PTR_FOR_FN (cfun
)->index
* func_param_count
+ i
;
4320 if (!repr
|| no_accesses_p (repr
))
4325 if ((repr
->offset
+ repr
->size
) > bb_dereferences
[idx
])
4326 repr
->grp_not_necessarilly_dereferenced
= 1;
4327 repr
= repr
->next_grp
;
4333 /* Return the representative access for the parameter declaration PARM if it is
4334 a scalar passed by reference which is not written to and the pointer value
4335 is not used directly. Thus, if it is legal to dereference it in the caller
4336 and we can rule out modifications through aliases, such parameter should be
4337 turned into one passed by value. Return NULL otherwise. */
4339 static struct access
*
4340 unmodified_by_ref_scalar_representative (tree parm
)
4342 int i
, access_count
;
4343 struct access
*repr
;
4344 vec
<access_p
> *access_vec
;
4346 access_vec
= get_base_access_vector (parm
);
4347 gcc_assert (access_vec
);
4348 repr
= (*access_vec
)[0];
4351 repr
->group_representative
= repr
;
4353 access_count
= access_vec
->length ();
4354 for (i
= 1; i
< access_count
; i
++)
4356 struct access
*access
= (*access_vec
)[i
];
4359 access
->group_representative
= repr
;
4360 access
->next_sibling
= repr
->next_sibling
;
4361 repr
->next_sibling
= access
;
4365 repr
->grp_scalar_ptr
= 1;
4369 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
4370 associated with. REQ_ALIGN is the minimum required alignment. */
4373 access_precludes_ipa_sra_p (struct access
*access
, unsigned int req_align
)
4375 unsigned int exp_align
;
4376 /* Avoid issues such as the second simple testcase in PR 42025. The problem
4377 is incompatible assign in a call statement (and possibly even in asm
4378 statements). This can be relaxed by using a new temporary but only for
4379 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
4380 intraprocedural SRA we deal with this by keeping the old aggregate around,
4381 something we cannot do in IPA-SRA.) */
4383 && (is_gimple_call (access
->stmt
)
4384 || gimple_code (access
->stmt
) == GIMPLE_ASM
))
4387 exp_align
= get_object_alignment (access
->expr
);
4388 if (exp_align
< req_align
)
4395 /* Sort collected accesses for parameter PARM, identify representatives for
4396 each accessed region and link them together. Return NULL if there are
4397 different but overlapping accesses, return the special ptr value meaning
4398 there are no accesses for this parameter if that is the case and return the
4399 first representative otherwise. Set *RO_GRP if there is a group of accesses
4400 with only read (i.e. no write) accesses. */
4402 static struct access
*
4403 splice_param_accesses (tree parm
, bool *ro_grp
)
4405 int i
, j
, access_count
, group_count
;
4406 int agg_size
, total_size
= 0;
4407 struct access
*access
, *res
, **prev_acc_ptr
= &res
;
4408 vec
<access_p
> *access_vec
;
4410 access_vec
= get_base_access_vector (parm
);
4412 return &no_accesses_representant
;
4413 access_count
= access_vec
->length ();
4415 access_vec
->qsort (compare_access_positions
);
4420 while (i
< access_count
)
4424 access
= (*access_vec
)[i
];
4425 modification
= access
->write
;
4426 if (access_precludes_ipa_sra_p (access
, TYPE_ALIGN (access
->type
)))
4428 a1_alias_type
= reference_alias_ptr_type (access
->expr
);
4430 /* Access is about to become group representative unless we find some
4431 nasty overlap which would preclude us from breaking this parameter
4435 while (j
< access_count
)
4437 struct access
*ac2
= (*access_vec
)[j
];
4438 if (ac2
->offset
!= access
->offset
)
4440 /* All or nothing law for parameters. */
4441 if (access
->offset
+ access
->size
> ac2
->offset
)
4446 else if (ac2
->size
!= access
->size
)
4449 if (access_precludes_ipa_sra_p (ac2
, TYPE_ALIGN (access
->type
))
4450 || (ac2
->type
!= access
->type
4451 && (TREE_ADDRESSABLE (ac2
->type
)
4452 || TREE_ADDRESSABLE (access
->type
)))
4453 || (reference_alias_ptr_type (ac2
->expr
) != a1_alias_type
))
4456 modification
|= ac2
->write
;
4457 ac2
->group_representative
= access
;
4458 ac2
->next_sibling
= access
->next_sibling
;
4459 access
->next_sibling
= ac2
;
4464 access
->grp_maybe_modified
= modification
;
4467 *prev_acc_ptr
= access
;
4468 prev_acc_ptr
= &access
->next_grp
;
4469 total_size
+= access
->size
;
4473 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4474 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm
))));
4476 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm
)));
4477 if (total_size
>= agg_size
)
4480 gcc_assert (group_count
> 0);
4484 /* Decide whether parameters with representative accesses given by REPR should
4485 be reduced into components. */
4488 decide_one_param_reduction (struct access
*repr
)
4490 int total_size
, cur_parm_size
, agg_size
, new_param_count
, parm_size_limit
;
4495 cur_parm_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm
)));
4496 gcc_assert (cur_parm_size
> 0);
4498 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4501 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm
))));
4506 agg_size
= cur_parm_size
;
4512 fprintf (dump_file
, "Evaluating PARAM group sizes for ");
4513 print_generic_expr (dump_file
, parm
);
4514 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (parm
));
4515 for (acc
= repr
; acc
; acc
= acc
->next_grp
)
4516 dump_access (dump_file
, acc
, true);
4520 new_param_count
= 0;
4522 for (; repr
; repr
= repr
->next_grp
)
4524 gcc_assert (parm
== repr
->base
);
4526 /* Taking the address of a non-addressable field is verboten. */
4527 if (by_ref
&& repr
->non_addressable
)
4530 /* Do not decompose a non-BLKmode param in a way that would
4531 create BLKmode params. Especially for by-reference passing
4532 (thus, pointer-type param) this is hardly worthwhile. */
4533 if (DECL_MODE (parm
) != BLKmode
4534 && TYPE_MODE (repr
->type
) == BLKmode
)
4537 if (!by_ref
|| (!repr
->grp_maybe_modified
4538 && !repr
->grp_not_necessarilly_dereferenced
))
4539 total_size
+= repr
->size
;
4541 total_size
+= cur_parm_size
;
4546 gcc_assert (new_param_count
> 0);
4548 if (optimize_function_for_size_p (cfun
))
4549 parm_size_limit
= cur_parm_size
;
4551 parm_size_limit
= (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR
)
4554 if (total_size
< agg_size
4555 && total_size
<= parm_size_limit
)
4558 fprintf (dump_file
, " ....will be split into %i components\n",
4560 return new_param_count
;
4566 /* The order of the following enums is important, we need to do extra work for
4567 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4568 enum ipa_splicing_result
{ NO_GOOD_ACCESS
, UNUSED_PARAMS
, BY_VAL_ACCESSES
,
4569 MODIF_BY_REF_ACCESSES
, UNMODIF_BY_REF_ACCESSES
};
4571 /* Identify representatives of all accesses to all candidate parameters for
4572 IPA-SRA. Return result based on what representatives have been found. */
4574 static enum ipa_splicing_result
4575 splice_all_param_accesses (vec
<access_p
> &representatives
)
4577 enum ipa_splicing_result result
= NO_GOOD_ACCESS
;
4579 struct access
*repr
;
4581 representatives
.create (func_param_count
);
4583 for (parm
= DECL_ARGUMENTS (current_function_decl
);
4585 parm
= DECL_CHAIN (parm
))
4587 if (is_unused_scalar_param (parm
))
4589 representatives
.quick_push (&no_accesses_representant
);
4590 if (result
== NO_GOOD_ACCESS
)
4591 result
= UNUSED_PARAMS
;
4593 else if (POINTER_TYPE_P (TREE_TYPE (parm
))
4594 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm
)))
4595 && bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
4597 repr
= unmodified_by_ref_scalar_representative (parm
);
4598 representatives
.quick_push (repr
);
4600 result
= UNMODIF_BY_REF_ACCESSES
;
4602 else if (bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
4604 bool ro_grp
= false;
4605 repr
= splice_param_accesses (parm
, &ro_grp
);
4606 representatives
.quick_push (repr
);
4608 if (repr
&& !no_accesses_p (repr
))
4610 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4613 result
= UNMODIF_BY_REF_ACCESSES
;
4614 else if (result
< MODIF_BY_REF_ACCESSES
)
4615 result
= MODIF_BY_REF_ACCESSES
;
4617 else if (result
< BY_VAL_ACCESSES
)
4618 result
= BY_VAL_ACCESSES
;
4620 else if (no_accesses_p (repr
) && (result
== NO_GOOD_ACCESS
))
4621 result
= UNUSED_PARAMS
;
4624 representatives
.quick_push (NULL
);
4627 if (result
== NO_GOOD_ACCESS
)
4629 representatives
.release ();
4630 return NO_GOOD_ACCESS
;
4636 /* Return the index of BASE in PARMS. Abort if it is not found. */
4639 get_param_index (tree base
, vec
<tree
> parms
)
4643 len
= parms
.length ();
4644 for (i
= 0; i
< len
; i
++)
4645 if (parms
[i
] == base
)
4650 /* Convert the decisions made at the representative level into compact
4651 parameter adjustments. REPRESENTATIVES are pointers to first
4652 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4653 final number of adjustments. */
4655 static ipa_parm_adjustment_vec
4656 turn_representatives_into_adjustments (vec
<access_p
> representatives
,
4657 int adjustments_count
)
4660 ipa_parm_adjustment_vec adjustments
;
4664 gcc_assert (adjustments_count
> 0);
4665 parms
= ipa_get_vector_of_formal_parms (current_function_decl
);
4666 adjustments
.create (adjustments_count
);
4667 parm
= DECL_ARGUMENTS (current_function_decl
);
4668 for (i
= 0; i
< func_param_count
; i
++, parm
= DECL_CHAIN (parm
))
4670 struct access
*repr
= representatives
[i
];
4672 if (!repr
|| no_accesses_p (repr
))
4674 struct ipa_parm_adjustment adj
;
4676 memset (&adj
, 0, sizeof (adj
));
4677 adj
.base_index
= get_param_index (parm
, parms
);
4680 adj
.op
= IPA_PARM_OP_COPY
;
4682 adj
.op
= IPA_PARM_OP_REMOVE
;
4683 adj
.arg_prefix
= "ISRA";
4684 adjustments
.quick_push (adj
);
4688 struct ipa_parm_adjustment adj
;
4689 int index
= get_param_index (parm
, parms
);
4691 for (; repr
; repr
= repr
->next_grp
)
4693 memset (&adj
, 0, sizeof (adj
));
4694 gcc_assert (repr
->base
== parm
);
4695 adj
.base_index
= index
;
4696 adj
.base
= repr
->base
;
4697 adj
.type
= repr
->type
;
4698 adj
.alias_ptr_type
= reference_alias_ptr_type (repr
->expr
);
4699 adj
.offset
= repr
->offset
;
4700 adj
.reverse
= repr
->reverse
;
4701 adj
.by_ref
= (POINTER_TYPE_P (TREE_TYPE (repr
->base
))
4702 && (repr
->grp_maybe_modified
4703 || repr
->grp_not_necessarilly_dereferenced
));
4704 adj
.arg_prefix
= "ISRA";
4705 adjustments
.quick_push (adj
);
4713 /* Analyze the collected accesses and produce a plan what to do with the
4714 parameters in the form of adjustments, NULL meaning nothing. */
4716 static ipa_parm_adjustment_vec
4717 analyze_all_param_acesses (void)
4719 enum ipa_splicing_result repr_state
;
4720 bool proceed
= false;
4721 int i
, adjustments_count
= 0;
4722 vec
<access_p
> representatives
;
4723 ipa_parm_adjustment_vec adjustments
;
4725 repr_state
= splice_all_param_accesses (representatives
);
4726 if (repr_state
== NO_GOOD_ACCESS
)
4727 return ipa_parm_adjustment_vec ();
4729 /* If there are any parameters passed by reference which are not modified
4730 directly, we need to check whether they can be modified indirectly. */
4731 if (repr_state
== UNMODIF_BY_REF_ACCESSES
)
4733 analyze_caller_dereference_legality (representatives
);
4734 analyze_modified_params (representatives
);
4737 for (i
= 0; i
< func_param_count
; i
++)
4739 struct access
*repr
= representatives
[i
];
4741 if (repr
&& !no_accesses_p (repr
))
4743 if (repr
->grp_scalar_ptr
)
4745 adjustments_count
++;
4746 if (repr
->grp_not_necessarilly_dereferenced
4747 || repr
->grp_maybe_modified
)
4748 representatives
[i
] = NULL
;
4752 sra_stats
.scalar_by_ref_to_by_val
++;
4757 int new_components
= decide_one_param_reduction (repr
);
4759 if (new_components
== 0)
4761 representatives
[i
] = NULL
;
4762 adjustments_count
++;
4766 adjustments_count
+= new_components
;
4767 sra_stats
.aggregate_params_reduced
++;
4768 sra_stats
.param_reductions_created
+= new_components
;
4775 if (no_accesses_p (repr
))
4778 sra_stats
.deleted_unused_parameters
++;
4780 adjustments_count
++;
4784 if (!proceed
&& dump_file
)
4785 fprintf (dump_file
, "NOT proceeding to change params.\n");
4788 adjustments
= turn_representatives_into_adjustments (representatives
,
4791 adjustments
= ipa_parm_adjustment_vec ();
4793 representatives
.release ();
4797 /* If a parameter replacement identified by ADJ does not yet exist in the form
4798 of declaration, create it and record it, otherwise return the previously
4802 get_replaced_param_substitute (struct ipa_parm_adjustment
*adj
)
4805 if (!adj
->new_ssa_base
)
4807 char *pretty_name
= make_fancy_name (adj
->base
);
4809 repl
= create_tmp_reg (TREE_TYPE (adj
->base
), "ISR");
4810 DECL_NAME (repl
) = get_identifier (pretty_name
);
4811 DECL_NAMELESS (repl
) = 1;
4812 obstack_free (&name_obstack
, pretty_name
);
4814 adj
->new_ssa_base
= repl
;
4817 repl
= adj
->new_ssa_base
;
4821 /* Find the first adjustment for a particular parameter BASE in a vector of
4822 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4825 static struct ipa_parm_adjustment
*
4826 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments
, tree base
)
4830 len
= adjustments
.length ();
4831 for (i
= 0; i
< len
; i
++)
4833 struct ipa_parm_adjustment
*adj
;
4835 adj
= &adjustments
[i
];
4836 if (adj
->op
!= IPA_PARM_OP_COPY
&& adj
->base
== base
)
4843 /* If OLD_NAME, which is being defined by statement STMT, is an SSA_NAME of a
4844 parameter which is to be removed because its value is not used, create a new
4845 SSA_NAME relating to a replacement VAR_DECL, replace all uses of the
4846 original with it and return it. If there is no need to re-map, return NULL.
4847 ADJUSTMENTS is a pointer to a vector of IPA-SRA adjustments. */
4850 replace_removed_params_ssa_names (tree old_name
, gimple
*stmt
,
4851 ipa_parm_adjustment_vec adjustments
)
4853 struct ipa_parm_adjustment
*adj
;
4854 tree decl
, repl
, new_name
;
4856 if (TREE_CODE (old_name
) != SSA_NAME
)
4859 decl
= SSA_NAME_VAR (old_name
);
4860 if (decl
== NULL_TREE
4861 || TREE_CODE (decl
) != PARM_DECL
)
4864 adj
= get_adjustment_for_base (adjustments
, decl
);
4868 repl
= get_replaced_param_substitute (adj
);
4869 new_name
= make_ssa_name (repl
, stmt
);
4870 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name
)
4871 = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name
);
4875 fprintf (dump_file
, "replacing an SSA name of a removed param ");
4876 print_generic_expr (dump_file
, old_name
);
4877 fprintf (dump_file
, " with ");
4878 print_generic_expr (dump_file
, new_name
);
4879 fprintf (dump_file
, "\n");
4882 replace_uses_by (old_name
, new_name
);
4886 /* If the statement STMT contains any expressions that need to replaced with a
4887 different one as noted by ADJUSTMENTS, do so. Handle any potential type
4888 incompatibilities (GSI is used to accommodate conversion statements and must
4889 point to the statement). Return true iff the statement was modified. */
4892 sra_ipa_modify_assign (gimple
*stmt
, gimple_stmt_iterator
*gsi
,
4893 ipa_parm_adjustment_vec adjustments
)
4895 tree
*lhs_p
, *rhs_p
;
4898 if (!gimple_assign_single_p (stmt
))
4901 rhs_p
= gimple_assign_rhs1_ptr (stmt
);
4902 lhs_p
= gimple_assign_lhs_ptr (stmt
);
4904 any
= ipa_modify_expr (rhs_p
, false, adjustments
);
4905 any
|= ipa_modify_expr (lhs_p
, false, adjustments
);
4908 tree new_rhs
= NULL_TREE
;
4910 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p
), TREE_TYPE (*rhs_p
)))
4912 if (TREE_CODE (*rhs_p
) == CONSTRUCTOR
)
4914 /* V_C_Es of constructors can cause trouble (PR 42714). */
4915 if (is_gimple_reg_type (TREE_TYPE (*lhs_p
)))
4916 *rhs_p
= build_zero_cst (TREE_TYPE (*lhs_p
));
4918 *rhs_p
= build_constructor (TREE_TYPE (*lhs_p
),
4922 new_rhs
= fold_build1_loc (gimple_location (stmt
),
4923 VIEW_CONVERT_EXPR
, TREE_TYPE (*lhs_p
),
4926 else if (REFERENCE_CLASS_P (*rhs_p
)
4927 && is_gimple_reg_type (TREE_TYPE (*lhs_p
))
4928 && !is_gimple_reg (*lhs_p
))
4929 /* This can happen when an assignment in between two single field
4930 structures is turned into an assignment in between two pointers to
4931 scalars (PR 42237). */
4936 tree tmp
= force_gimple_operand_gsi (gsi
, new_rhs
, true, NULL_TREE
,
4937 true, GSI_SAME_STMT
);
4939 gimple_assign_set_rhs_from_tree (gsi
, tmp
);
4948 /* Traverse the function body and all modifications as described in
4949 ADJUSTMENTS. Return true iff the CFG has been changed. */
4952 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments
)
4954 bool cfg_changed
= false;
4957 FOR_EACH_BB_FN (bb
, cfun
)
4959 gimple_stmt_iterator gsi
;
4961 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4963 gphi
*phi
= as_a
<gphi
*> (gsi_stmt (gsi
));
4964 tree new_lhs
, old_lhs
= gimple_phi_result (phi
);
4965 new_lhs
= replace_removed_params_ssa_names (old_lhs
, phi
, adjustments
);
4968 gimple_phi_set_result (phi
, new_lhs
);
4969 release_ssa_name (old_lhs
);
4973 gsi
= gsi_start_bb (bb
);
4974 while (!gsi_end_p (gsi
))
4976 gimple
*stmt
= gsi_stmt (gsi
);
4977 bool modified
= false;
4981 switch (gimple_code (stmt
))
4984 t
= gimple_return_retval_ptr (as_a
<greturn
*> (stmt
));
4985 if (*t
!= NULL_TREE
)
4986 modified
|= ipa_modify_expr (t
, true, adjustments
);
4990 modified
|= sra_ipa_modify_assign (stmt
, &gsi
, adjustments
);
4994 /* Operands must be processed before the lhs. */
4995 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
4997 t
= gimple_call_arg_ptr (stmt
, i
);
4998 modified
|= ipa_modify_expr (t
, true, adjustments
);
5001 if (gimple_call_lhs (stmt
))
5003 t
= gimple_call_lhs_ptr (stmt
);
5004 modified
|= ipa_modify_expr (t
, false, adjustments
);
5010 gasm
*asm_stmt
= as_a
<gasm
*> (stmt
);
5011 for (i
= 0; i
< gimple_asm_ninputs (asm_stmt
); i
++)
5013 t
= &TREE_VALUE (gimple_asm_input_op (asm_stmt
, i
));
5014 modified
|= ipa_modify_expr (t
, true, adjustments
);
5016 for (i
= 0; i
< gimple_asm_noutputs (asm_stmt
); i
++)
5018 t
= &TREE_VALUE (gimple_asm_output_op (asm_stmt
, i
));
5019 modified
|= ipa_modify_expr (t
, false, adjustments
);
5030 FOR_EACH_SSA_DEF_OPERAND (defp
, stmt
, iter
, SSA_OP_DEF
)
5032 tree old_def
= DEF_FROM_PTR (defp
);
5033 if (tree new_def
= replace_removed_params_ssa_names (old_def
, stmt
,
5036 SET_DEF (defp
, new_def
);
5037 release_ssa_name (old_def
);
5045 if (maybe_clean_eh_stmt (stmt
)
5046 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
5056 /* Call gimple_debug_bind_reset_value on all debug statements describing
5057 gimple register parameters that are being removed or replaced. */
5060 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments
)
5063 gimple_stmt_iterator
*gsip
= NULL
, gsi
;
5065 if (MAY_HAVE_DEBUG_STMTS
&& single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun
)))
5067 gsi
= gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun
)));
5070 len
= adjustments
.length ();
5071 for (i
= 0; i
< len
; i
++)
5073 struct ipa_parm_adjustment
*adj
;
5074 imm_use_iterator ui
;
5077 tree name
, vexpr
, copy
= NULL_TREE
;
5078 use_operand_p use_p
;
5080 adj
= &adjustments
[i
];
5081 if (adj
->op
== IPA_PARM_OP_COPY
|| !is_gimple_reg (adj
->base
))
5083 name
= ssa_default_def (cfun
, adj
->base
);
5086 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
5088 if (gimple_clobber_p (stmt
))
5090 gimple_stmt_iterator cgsi
= gsi_for_stmt (stmt
);
5091 unlink_stmt_vdef (stmt
);
5092 gsi_remove (&cgsi
, true);
5093 release_defs (stmt
);
5096 /* All other users must have been removed by
5097 ipa_sra_modify_function_body. */
5098 gcc_assert (is_gimple_debug (stmt
));
5099 if (vexpr
== NULL
&& gsip
!= NULL
)
5101 gcc_assert (TREE_CODE (adj
->base
) == PARM_DECL
);
5102 vexpr
= make_node (DEBUG_EXPR_DECL
);
5103 def_temp
= gimple_build_debug_source_bind (vexpr
, adj
->base
,
5105 DECL_ARTIFICIAL (vexpr
) = 1;
5106 TREE_TYPE (vexpr
) = TREE_TYPE (name
);
5107 SET_DECL_MODE (vexpr
, DECL_MODE (adj
->base
));
5108 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
5112 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
5113 SET_USE (use_p
, vexpr
);
5116 gimple_debug_bind_reset_value (stmt
);
5119 /* Create a VAR_DECL for debug info purposes. */
5120 if (!DECL_IGNORED_P (adj
->base
))
5122 copy
= build_decl (DECL_SOURCE_LOCATION (current_function_decl
),
5123 VAR_DECL
, DECL_NAME (adj
->base
),
5124 TREE_TYPE (adj
->base
));
5125 if (DECL_PT_UID_SET_P (adj
->base
))
5126 SET_DECL_PT_UID (copy
, DECL_PT_UID (adj
->base
));
5127 TREE_ADDRESSABLE (copy
) = TREE_ADDRESSABLE (adj
->base
);
5128 TREE_READONLY (copy
) = TREE_READONLY (adj
->base
);
5129 TREE_THIS_VOLATILE (copy
) = TREE_THIS_VOLATILE (adj
->base
);
5130 DECL_GIMPLE_REG_P (copy
) = DECL_GIMPLE_REG_P (adj
->base
);
5131 DECL_ARTIFICIAL (copy
) = DECL_ARTIFICIAL (adj
->base
);
5132 DECL_IGNORED_P (copy
) = DECL_IGNORED_P (adj
->base
);
5133 DECL_ABSTRACT_ORIGIN (copy
) = DECL_ORIGIN (adj
->base
);
5134 DECL_SEEN_IN_BIND_EXPR_P (copy
) = 1;
5135 SET_DECL_RTL (copy
, 0);
5136 TREE_USED (copy
) = 1;
5137 DECL_CONTEXT (copy
) = current_function_decl
;
5138 add_local_decl (cfun
, copy
);
5140 BLOCK_VARS (DECL_INITIAL (current_function_decl
));
5141 BLOCK_VARS (DECL_INITIAL (current_function_decl
)) = copy
;
5143 if (gsip
!= NULL
&& copy
&& target_for_debug_bind (adj
->base
))
5145 gcc_assert (TREE_CODE (adj
->base
) == PARM_DECL
);
5147 def_temp
= gimple_build_debug_bind (copy
, vexpr
, NULL
);
5149 def_temp
= gimple_build_debug_source_bind (copy
, adj
->base
,
5151 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
5156 /* Return false if all callers have at least as many actual arguments as there
5157 are formal parameters in the current function and that their types
5161 some_callers_have_mismatched_arguments_p (struct cgraph_node
*node
,
5162 void *data ATTRIBUTE_UNUSED
)
5164 struct cgraph_edge
*cs
;
5165 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
5166 if (!cs
->call_stmt
|| !callsite_arguments_match_p (cs
->call_stmt
))
5172 /* Return false if all callers have vuse attached to a call statement. */
5175 some_callers_have_no_vuse_p (struct cgraph_node
*node
,
5176 void *data ATTRIBUTE_UNUSED
)
5178 struct cgraph_edge
*cs
;
5179 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
5180 if (!cs
->call_stmt
|| !gimple_vuse (cs
->call_stmt
))
5186 /* Convert all callers of NODE. */
5189 convert_callers_for_node (struct cgraph_node
*node
,
5192 ipa_parm_adjustment_vec
*adjustments
= (ipa_parm_adjustment_vec
*) data
;
5193 bitmap recomputed_callers
= BITMAP_ALLOC (NULL
);
5194 struct cgraph_edge
*cs
;
5196 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
5198 push_cfun (DECL_STRUCT_FUNCTION (cs
->caller
->decl
));
5201 fprintf (dump_file
, "Adjusting call %s -> %s\n",
5202 cs
->caller
->dump_name (), cs
->callee
->dump_name ());
5204 ipa_modify_call_arguments (cs
, cs
->call_stmt
, *adjustments
);
5209 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
5210 if (bitmap_set_bit (recomputed_callers
, cs
->caller
->uid
)
5211 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs
->caller
->decl
)))
5212 compute_fn_summary (cs
->caller
, true);
5213 BITMAP_FREE (recomputed_callers
);
5218 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
5221 convert_callers (struct cgraph_node
*node
, tree old_decl
,
5222 ipa_parm_adjustment_vec adjustments
)
5224 basic_block this_block
;
5226 node
->call_for_symbol_and_aliases (convert_callers_for_node
,
5227 &adjustments
, false);
5229 if (!encountered_recursive_call
)
5232 FOR_EACH_BB_FN (this_block
, cfun
)
5234 gimple_stmt_iterator gsi
;
5236 for (gsi
= gsi_start_bb (this_block
); !gsi_end_p (gsi
); gsi_next (&gsi
))
5240 stmt
= dyn_cast
<gcall
*> (gsi_stmt (gsi
));
5243 call_fndecl
= gimple_call_fndecl (stmt
);
5244 if (call_fndecl
== old_decl
)
5247 fprintf (dump_file
, "Adjusting recursive call");
5248 gimple_call_set_fndecl (stmt
, node
->decl
);
5249 ipa_modify_call_arguments (NULL
, stmt
, adjustments
);
5257 /* Perform all the modification required in IPA-SRA for NODE to have parameters
5258 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
5261 modify_function (struct cgraph_node
*node
, ipa_parm_adjustment_vec adjustments
)
5263 struct cgraph_node
*new_node
;
5266 cgraph_edge::rebuild_edges ();
5267 free_dominance_info (CDI_DOMINATORS
);
5270 /* This must be done after rebuilding cgraph edges for node above.
5271 Otherwise any recursive calls to node that are recorded in
5272 redirect_callers will be corrupted. */
5273 vec
<cgraph_edge
*> redirect_callers
= node
->collect_callers ();
5274 new_node
= node
->create_version_clone_with_body (redirect_callers
, NULL
,
5275 NULL
, false, NULL
, NULL
,
5277 redirect_callers
.release ();
5279 push_cfun (DECL_STRUCT_FUNCTION (new_node
->decl
));
5280 ipa_modify_formal_parameters (current_function_decl
, adjustments
);
5281 cfg_changed
= ipa_sra_modify_function_body (adjustments
);
5282 sra_ipa_reset_debug_stmts (adjustments
);
5283 convert_callers (new_node
, node
->decl
, adjustments
);
5284 new_node
->make_local ();
5288 /* Means of communication between ipa_sra_check_caller and
5289 ipa_sra_preliminary_function_checks. */
5291 struct ipa_sra_check_caller_data
5294 bool bad_arg_alignment
;
5298 /* If NODE has a caller, mark that fact in DATA which is pointer to
5299 ipa_sra_check_caller_data. Also check all aggregate arguments in all known
5300 calls if they are unit aligned and if not, set the appropriate flag in DATA
5304 ipa_sra_check_caller (struct cgraph_node
*node
, void *data
)
5309 struct ipa_sra_check_caller_data
*iscc
;
5310 iscc
= (struct ipa_sra_check_caller_data
*) data
;
5311 iscc
->has_callers
= true;
5313 for (cgraph_edge
*cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
5315 if (cs
->caller
->thunk
.thunk_p
)
5317 iscc
->has_thunk
= true;
5320 gimple
*call_stmt
= cs
->call_stmt
;
5321 unsigned count
= gimple_call_num_args (call_stmt
);
5322 for (unsigned i
= 0; i
< count
; i
++)
5324 tree arg
= gimple_call_arg (call_stmt
, i
);
5325 if (is_gimple_reg (arg
))
5329 HOST_WIDE_INT bitsize
, bitpos
;
5331 int unsignedp
, reversep
, volatilep
= 0;
5332 get_inner_reference (arg
, &bitsize
, &bitpos
, &offset
, &mode
,
5333 &unsignedp
, &reversep
, &volatilep
);
5334 if (bitpos
% BITS_PER_UNIT
)
5336 iscc
->bad_arg_alignment
= true;
5345 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
5346 attributes, return true otherwise. NODE is the cgraph node of the current
5350 ipa_sra_preliminary_function_checks (struct cgraph_node
*node
)
5352 if (!node
->can_be_local_p ())
5355 fprintf (dump_file
, "Function not local to this compilation unit.\n");
5359 if (!node
->local
.can_change_signature
)
5362 fprintf (dump_file
, "Function can not change signature.\n");
5366 if (!tree_versionable_function_p (node
->decl
))
5369 fprintf (dump_file
, "Function is not versionable.\n");
5373 if (!opt_for_fn (node
->decl
, optimize
)
5374 || !opt_for_fn (node
->decl
, flag_ipa_sra
))
5377 fprintf (dump_file
, "Function not optimized.\n");
5381 if (DECL_VIRTUAL_P (current_function_decl
))
5384 fprintf (dump_file
, "Function is a virtual method.\n");
5388 if ((DECL_ONE_ONLY (node
->decl
) || DECL_EXTERNAL (node
->decl
))
5389 && ipa_fn_summaries
->get (node
)->size
>= MAX_INLINE_INSNS_AUTO
)
5392 fprintf (dump_file
, "Function too big to be made truly local.\n");
5399 fprintf (dump_file
, "Function uses stdarg. \n");
5403 if (TYPE_ATTRIBUTES (TREE_TYPE (node
->decl
)))
5406 if (DECL_DISREGARD_INLINE_LIMITS (node
->decl
))
5409 fprintf (dump_file
, "Always inline function will be inlined "
5414 struct ipa_sra_check_caller_data iscc
;
5415 memset (&iscc
, 0, sizeof(iscc
));
5416 node
->call_for_symbol_and_aliases (ipa_sra_check_caller
, &iscc
, true);
5417 if (!iscc
.has_callers
)
5421 "Function has no callers in this compilation unit.\n");
5425 if (iscc
.bad_arg_alignment
)
5429 "A function call has an argument with non-unit alignment.\n");
5444 /* Perform early interprocedural SRA. */
5447 ipa_early_sra (void)
5449 struct cgraph_node
*node
= cgraph_node::get (current_function_decl
);
5450 ipa_parm_adjustment_vec adjustments
;
5453 if (!ipa_sra_preliminary_function_checks (node
))
5457 sra_mode
= SRA_MODE_EARLY_IPA
;
5459 if (!find_param_candidates ())
5462 fprintf (dump_file
, "Function has no IPA-SRA candidates.\n");
5466 if (node
->call_for_symbol_and_aliases
5467 (some_callers_have_mismatched_arguments_p
, NULL
, true))
5470 fprintf (dump_file
, "There are callers with insufficient number of "
5471 "arguments or arguments with type mismatches.\n");
5475 if (node
->call_for_symbol_and_aliases
5476 (some_callers_have_no_vuse_p
, NULL
, true))
5479 fprintf (dump_file
, "There are callers with no VUSE attached "
5480 "to a call stmt.\n");
5484 bb_dereferences
= XCNEWVEC (HOST_WIDE_INT
,
5486 * last_basic_block_for_fn (cfun
));
5487 final_bbs
= BITMAP_ALLOC (NULL
);
5490 if (encountered_apply_args
)
5493 fprintf (dump_file
, "Function calls __builtin_apply_args().\n");
5497 if (encountered_unchangable_recursive_call
)
5500 fprintf (dump_file
, "Function calls itself with insufficient "
5501 "number of arguments.\n");
5505 adjustments
= analyze_all_param_acesses ();
5506 if (!adjustments
.exists ())
5509 ipa_dump_param_adjustments (dump_file
, adjustments
, current_function_decl
);
5511 if (modify_function (node
, adjustments
))
5512 ret
= TODO_update_ssa
| TODO_cleanup_cfg
;
5514 ret
= TODO_update_ssa
;
5515 adjustments
.release ();
5517 statistics_counter_event (cfun
, "Unused parameters deleted",
5518 sra_stats
.deleted_unused_parameters
);
5519 statistics_counter_event (cfun
, "Scalar parameters converted to by-value",
5520 sra_stats
.scalar_by_ref_to_by_val
);
5521 statistics_counter_event (cfun
, "Aggregate parameters broken up",
5522 sra_stats
.aggregate_params_reduced
);
5523 statistics_counter_event (cfun
, "Aggregate parameter components created",
5524 sra_stats
.param_reductions_created
);
5527 BITMAP_FREE (final_bbs
);
5528 free (bb_dereferences
);
5530 sra_deinitialize ();
5536 const pass_data pass_data_early_ipa_sra
=
5538 GIMPLE_PASS
, /* type */
5539 "eipa_sra", /* name */
5540 OPTGROUP_NONE
, /* optinfo_flags */
5541 TV_IPA_SRA
, /* tv_id */
5542 0, /* properties_required */
5543 0, /* properties_provided */
5544 0, /* properties_destroyed */
5545 0, /* todo_flags_start */
5546 TODO_dump_symtab
, /* todo_flags_finish */
5549 class pass_early_ipa_sra
: public gimple_opt_pass
5552 pass_early_ipa_sra (gcc::context
*ctxt
)
5553 : gimple_opt_pass (pass_data_early_ipa_sra
, ctxt
)
5556 /* opt_pass methods: */
5557 virtual bool gate (function
*) { return flag_ipa_sra
&& dbg_cnt (eipa_sra
); }
5558 virtual unsigned int execute (function
*) { return ipa_early_sra (); }
5560 }; // class pass_early_ipa_sra
5565 make_pass_early_ipa_sra (gcc::context
*ctxt
)
5567 return new pass_early_ipa_sra (ctxt
);