1 /* Scalar Replacement of Aggregates (SRA) converts some structure
2 references into scalar references, exposing them to the scalar
4 Copyright (C) 2008-2015 Free Software Foundation, Inc.
5 Contributed by Martin Jambor <mjambor@suse.cz>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* This file implements Scalar Reduction of Aggregates (SRA). SRA is run
24 twice, once in the early stages of compilation (early SRA) and once in the
25 late stages (late SRA). The aim of both is to turn references to scalar
26 parts of aggregates into uses of independent scalar variables.
28 The two passes are nearly identical, the only difference is that early SRA
29 does not scalarize unions which are used as the result in a GIMPLE_RETURN
30 statement because together with inlining this can lead to weird type
33 Both passes operate in four stages:
35 1. The declarations that have properties which make them candidates for
36 scalarization are identified in function find_var_candidates(). The
37 candidates are stored in candidate_bitmap.
39 2. The function body is scanned. In the process, declarations which are
40 used in a manner that prevent their scalarization are removed from the
41 candidate bitmap. More importantly, for every access into an aggregate,
42 an access structure (struct access) is created by create_access() and
43 stored in a vector associated with the aggregate. Among other
44 information, the aggregate declaration, the offset and size of the access
45 and its type are stored in the structure.
47 On a related note, assign_link structures are created for every assign
48 statement between candidate aggregates and attached to the related
51 3. The vectors of accesses are analyzed. They are first sorted according to
52 their offset and size and then scanned for partially overlapping accesses
53 (i.e. those which overlap but one is not entirely within another). Such
54 an access disqualifies the whole aggregate from being scalarized.
56 If there is no such inhibiting overlap, a representative access structure
57 is chosen for every unique combination of offset and size. Afterwards,
58 the pass builds a set of trees from these structures, in which children
59 of an access are within their parent (in terms of offset and size).
61 Then accesses are propagated whenever possible (i.e. in cases when it
62 does not create a partially overlapping access) across assign_links from
63 the right hand side to the left hand side.
65 Then the set of trees for each declaration is traversed again and those
66 accesses which should be replaced by a scalar are identified.
68 4. The function is traversed again, and for every reference into an
69 aggregate that has some component which is about to be scalarized,
70 statements are amended and new statements are created as necessary.
71 Finally, if a parameter got scalarized, the scalar replacements are
72 initialized with values from respective parameter aggregates. */
76 #include "coretypes.h"
77 #include "mem-stats.h"
79 #include "hash-table.h"
80 #include "alloc-pool.h"
85 #include "double-int.h"
92 #include "fold-const.h"
94 #include "hard-reg-set.h"
96 #include "dominance.h"
98 #include "basic-block.h"
99 #include "tree-ssa-alias.h"
100 #include "internal-fn.h"
102 #include "gimple-expr.h"
105 #include "stor-layout.h"
106 #include "gimplify.h"
107 #include "gimple-iterator.h"
108 #include "gimplify-me.h"
109 #include "gimple-walk.h"
111 #include "gimple-ssa.h"
112 #include "tree-cfg.h"
113 #include "tree-phinodes.h"
114 #include "ssa-iterators.h"
115 #include "stringpool.h"
116 #include "tree-ssanames.h"
120 #include "statistics.h"
122 #include "fixed-value.h"
123 #include "insn-config.h"
128 #include "emit-rtl.h"
132 #include "tree-dfa.h"
133 #include "tree-ssa.h"
134 #include "tree-pass.h"
135 #include "plugin-api.h"
138 #include "symbol-summary.h"
139 #include "ipa-prop.h"
143 #include "tree-inline.h"
144 #include "gimple-pretty-print.h"
145 #include "ipa-inline.h"
146 #include "ipa-utils.h"
147 #include "builtins.h"
149 /* Enumeration of all aggregate reductions we can do. */
150 enum sra_mode
{ SRA_MODE_EARLY_IPA
, /* early call regularization */
151 SRA_MODE_EARLY_INTRA
, /* early intraprocedural SRA */
152 SRA_MODE_INTRA
}; /* late intraprocedural SRA */
154 /* Global variable describing which aggregate reduction we are performing at
156 static enum sra_mode sra_mode
;
160 /* ACCESS represents each access to an aggregate variable (as a whole or a
161 part). It can also represent a group of accesses that refer to exactly the
162 same fragment of an aggregate (i.e. those that have exactly the same offset
163 and size). Such representatives for a single aggregate, once determined,
164 are linked in a linked list and have the group fields set.
166 Moreover, when doing intraprocedural SRA, a tree is built from those
167 representatives (by the means of first_child and next_sibling pointers), in
168 which all items in a subtree are "within" the root, i.e. their offset is
169 greater or equal to offset of the root and offset+size is smaller or equal
170 to offset+size of the root. Children of an access are sorted by offset.
172 Note that accesses to parts of vector and complex number types always
173 represented by an access to the whole complex number or a vector. It is a
174 duty of the modifying functions to replace them appropriately. */
178 /* Values returned by `get_ref_base_and_extent' for each component reference
179 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
180 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
181 HOST_WIDE_INT offset
;
185 /* Expression. It is context dependent so do not use it to create new
186 expressions to access the original aggregate. See PR 42154 for a
192 /* The statement this access belongs to. */
195 /* Next group representative for this aggregate. */
196 struct access
*next_grp
;
198 /* Pointer to the group representative. Pointer to itself if the struct is
199 the representative. */
200 struct access
*group_representative
;
202 /* If this access has any children (in terms of the definition above), this
203 points to the first one. */
204 struct access
*first_child
;
206 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
207 described above. In IPA-SRA this is a pointer to the next access
208 belonging to the same group (having the same representative). */
209 struct access
*next_sibling
;
211 /* Pointers to the first and last element in the linked list of assign
213 struct assign_link
*first_link
, *last_link
;
215 /* Pointer to the next access in the work queue. */
216 struct access
*next_queued
;
218 /* Replacement variable for this access "region." Never to be accessed
219 directly, always only by the means of get_access_replacement() and only
220 when grp_to_be_replaced flag is set. */
221 tree replacement_decl
;
223 /* Is this particular access write access? */
226 /* Is this access an access to a non-addressable field? */
227 unsigned non_addressable
: 1;
229 /* Is this access currently in the work queue? */
230 unsigned grp_queued
: 1;
232 /* Does this group contain a write access? This flag is propagated down the
234 unsigned grp_write
: 1;
236 /* Does this group contain a read access? This flag is propagated down the
238 unsigned grp_read
: 1;
240 /* Does this group contain a read access that comes from an assignment
241 statement? This flag is propagated down the access tree. */
242 unsigned grp_assignment_read
: 1;
244 /* Does this group contain a write access that comes from an assignment
245 statement? This flag is propagated down the access tree. */
246 unsigned grp_assignment_write
: 1;
248 /* Does this group contain a read access through a scalar type? This flag is
249 not propagated in the access tree in any direction. */
250 unsigned grp_scalar_read
: 1;
252 /* Does this group contain a write access through a scalar type? This flag
253 is not propagated in the access tree in any direction. */
254 unsigned grp_scalar_write
: 1;
256 /* Is this access an artificial one created to scalarize some record
258 unsigned grp_total_scalarization
: 1;
260 /* Other passes of the analysis use this bit to make function
261 analyze_access_subtree create scalar replacements for this group if
263 unsigned grp_hint
: 1;
265 /* Is the subtree rooted in this access fully covered by scalar
267 unsigned grp_covered
: 1;
269 /* If set to true, this access and all below it in an access tree must not be
271 unsigned grp_unscalarizable_region
: 1;
273 /* Whether data have been written to parts of the aggregate covered by this
274 access which is not to be scalarized. This flag is propagated up in the
276 unsigned grp_unscalarized_data
: 1;
278 /* Does this access and/or group contain a write access through a
280 unsigned grp_partial_lhs
: 1;
282 /* Set when a scalar replacement should be created for this variable. */
283 unsigned grp_to_be_replaced
: 1;
285 /* Set when we want a replacement for the sole purpose of having it in
286 generated debug statements. */
287 unsigned grp_to_be_debug_replaced
: 1;
289 /* Should TREE_NO_WARNING of a replacement be set? */
290 unsigned grp_no_warning
: 1;
292 /* Is it possible that the group refers to data which might be (directly or
293 otherwise) modified? */
294 unsigned grp_maybe_modified
: 1;
296 /* Set when this is a representative of a pointer to scalar (i.e. by
297 reference) parameter which we consider for turning into a plain scalar
298 (i.e. a by value parameter). */
299 unsigned grp_scalar_ptr
: 1;
301 /* Set when we discover that this pointer is not safe to dereference in the
303 unsigned grp_not_necessarilly_dereferenced
: 1;
306 typedef struct access
*access_p
;
309 /* Alloc pool for allocating access structures. */
310 static alloc_pool access_pool
;
312 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
313 are used to propagate subaccesses from rhs to lhs as long as they don't
314 conflict with what is already there. */
317 struct access
*lacc
, *racc
;
318 struct assign_link
*next
;
321 /* Alloc pool for allocating assign link structures. */
322 static alloc_pool link_pool
;
324 /* Base (tree) -> Vector (vec<access_p> *) map. */
325 static hash_map
<tree
, auto_vec
<access_p
> > *base_access_vec
;
327 /* Candidate hash table helpers. */
329 struct uid_decl_hasher
: typed_noop_remove
<tree_node
>
331 typedef tree_node
*value_type
;
332 typedef tree_node
*compare_type
;
333 static inline hashval_t
hash (const tree_node
*);
334 static inline bool equal (const tree_node
*, const tree_node
*);
337 /* Hash a tree in a uid_decl_map. */
340 uid_decl_hasher::hash (const tree_node
*item
)
342 return item
->decl_minimal
.uid
;
345 /* Return true if the DECL_UID in both trees are equal. */
348 uid_decl_hasher::equal (const tree_node
*a
, const tree_node
*b
)
350 return (a
->decl_minimal
.uid
== b
->decl_minimal
.uid
);
353 /* Set of candidates. */
354 static bitmap candidate_bitmap
;
355 static hash_table
<uid_decl_hasher
> *candidates
;
357 /* For a candidate UID return the candidates decl. */
360 candidate (unsigned uid
)
363 t
.decl_minimal
.uid
= uid
;
364 return candidates
->find_with_hash (&t
, static_cast <hashval_t
> (uid
));
367 /* Bitmap of candidates which we should try to entirely scalarize away and
368 those which cannot be (because they are and need be used as a whole). */
369 static bitmap should_scalarize_away_bitmap
, cannot_scalarize_away_bitmap
;
371 /* Obstack for creation of fancy names. */
372 static struct obstack name_obstack
;
374 /* Head of a linked list of accesses that need to have its subaccesses
375 propagated to their assignment counterparts. */
376 static struct access
*work_queue_head
;
378 /* Number of parameters of the analyzed function when doing early ipa SRA. */
379 static int func_param_count
;
381 /* scan_function sets the following to true if it encounters a call to
382 __builtin_apply_args. */
383 static bool encountered_apply_args
;
385 /* Set by scan_function when it finds a recursive call. */
386 static bool encountered_recursive_call
;
388 /* Set by scan_function when it finds a recursive call with less actual
389 arguments than formal parameters.. */
390 static bool encountered_unchangable_recursive_call
;
392 /* This is a table in which for each basic block and parameter there is a
393 distance (offset + size) in that parameter which is dereferenced and
394 accessed in that BB. */
395 static HOST_WIDE_INT
*bb_dereferences
;
396 /* Bitmap of BBs that can cause the function to "stop" progressing by
397 returning, throwing externally, looping infinitely or calling a function
398 which might abort etc.. */
399 static bitmap final_bbs
;
401 /* Representative of no accesses at all. */
402 static struct access no_accesses_representant
;
404 /* Predicate to test the special value. */
407 no_accesses_p (struct access
*access
)
409 return access
== &no_accesses_representant
;
412 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
413 representative fields are dumped, otherwise those which only describe the
414 individual access are. */
418 /* Number of processed aggregates is readily available in
419 analyze_all_variable_accesses and so is not stored here. */
421 /* Number of created scalar replacements. */
424 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
428 /* Number of statements created by generate_subtree_copies. */
431 /* Number of statements created by load_assign_lhs_subreplacements. */
434 /* Number of times sra_modify_assign has deleted a statement. */
437 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
438 RHS reparately due to type conversions or nonexistent matching
440 int separate_lhs_rhs_handling
;
442 /* Number of parameters that were removed because they were unused. */
443 int deleted_unused_parameters
;
445 /* Number of scalars passed as parameters by reference that have been
446 converted to be passed by value. */
447 int scalar_by_ref_to_by_val
;
449 /* Number of aggregate parameters that were replaced by one or more of their
451 int aggregate_params_reduced
;
453 /* Numbber of components created when splitting aggregate parameters. */
454 int param_reductions_created
;
458 dump_access (FILE *f
, struct access
*access
, bool grp
)
460 fprintf (f
, "access { ");
461 fprintf (f
, "base = (%d)'", DECL_UID (access
->base
));
462 print_generic_expr (f
, access
->base
, 0);
463 fprintf (f
, "', offset = " HOST_WIDE_INT_PRINT_DEC
, access
->offset
);
464 fprintf (f
, ", size = " HOST_WIDE_INT_PRINT_DEC
, access
->size
);
465 fprintf (f
, ", expr = ");
466 print_generic_expr (f
, access
->expr
, 0);
467 fprintf (f
, ", type = ");
468 print_generic_expr (f
, access
->type
, 0);
470 fprintf (f
, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
471 "grp_assignment_write = %d, grp_scalar_read = %d, "
472 "grp_scalar_write = %d, grp_total_scalarization = %d, "
473 "grp_hint = %d, grp_covered = %d, "
474 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
475 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
476 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
477 "grp_not_necessarilly_dereferenced = %d\n",
478 access
->grp_read
, access
->grp_write
, access
->grp_assignment_read
,
479 access
->grp_assignment_write
, access
->grp_scalar_read
,
480 access
->grp_scalar_write
, access
->grp_total_scalarization
,
481 access
->grp_hint
, access
->grp_covered
,
482 access
->grp_unscalarizable_region
, access
->grp_unscalarized_data
,
483 access
->grp_partial_lhs
, access
->grp_to_be_replaced
,
484 access
->grp_to_be_debug_replaced
, access
->grp_maybe_modified
,
485 access
->grp_not_necessarilly_dereferenced
);
487 fprintf (f
, ", write = %d, grp_total_scalarization = %d, "
488 "grp_partial_lhs = %d\n",
489 access
->write
, access
->grp_total_scalarization
,
490 access
->grp_partial_lhs
);
493 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
496 dump_access_tree_1 (FILE *f
, struct access
*access
, int level
)
502 for (i
= 0; i
< level
; i
++)
503 fputs ("* ", dump_file
);
505 dump_access (f
, access
, true);
507 if (access
->first_child
)
508 dump_access_tree_1 (f
, access
->first_child
, level
+ 1);
510 access
= access
->next_sibling
;
515 /* Dump all access trees for a variable, given the pointer to the first root in
519 dump_access_tree (FILE *f
, struct access
*access
)
521 for (; access
; access
= access
->next_grp
)
522 dump_access_tree_1 (f
, access
, 0);
525 /* Return true iff ACC is non-NULL and has subaccesses. */
528 access_has_children_p (struct access
*acc
)
530 return acc
&& acc
->first_child
;
533 /* Return true iff ACC is (partly) covered by at least one replacement. */
536 access_has_replacements_p (struct access
*acc
)
538 struct access
*child
;
539 if (acc
->grp_to_be_replaced
)
541 for (child
= acc
->first_child
; child
; child
= child
->next_sibling
)
542 if (access_has_replacements_p (child
))
547 /* Return a vector of pointers to accesses for the variable given in BASE or
548 NULL if there is none. */
550 static vec
<access_p
> *
551 get_base_access_vector (tree base
)
553 return base_access_vec
->get (base
);
556 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
557 in ACCESS. Return NULL if it cannot be found. */
559 static struct access
*
560 find_access_in_subtree (struct access
*access
, HOST_WIDE_INT offset
,
563 while (access
&& (access
->offset
!= offset
|| access
->size
!= size
))
565 struct access
*child
= access
->first_child
;
567 while (child
&& (child
->offset
+ child
->size
<= offset
))
568 child
= child
->next_sibling
;
575 /* Return the first group representative for DECL or NULL if none exists. */
577 static struct access
*
578 get_first_repr_for_decl (tree base
)
580 vec
<access_p
> *access_vec
;
582 access_vec
= get_base_access_vector (base
);
586 return (*access_vec
)[0];
589 /* Find an access representative for the variable BASE and given OFFSET and
590 SIZE. Requires that access trees have already been built. Return NULL if
591 it cannot be found. */
593 static struct access
*
594 get_var_base_offset_size_access (tree base
, HOST_WIDE_INT offset
,
597 struct access
*access
;
599 access
= get_first_repr_for_decl (base
);
600 while (access
&& (access
->offset
+ access
->size
<= offset
))
601 access
= access
->next_grp
;
605 return find_access_in_subtree (access
, offset
, size
);
608 /* Add LINK to the linked list of assign links of RACC. */
610 add_link_to_rhs (struct access
*racc
, struct assign_link
*link
)
612 gcc_assert (link
->racc
== racc
);
614 if (!racc
->first_link
)
616 gcc_assert (!racc
->last_link
);
617 racc
->first_link
= link
;
620 racc
->last_link
->next
= link
;
622 racc
->last_link
= link
;
626 /* Move all link structures in their linked list in OLD_RACC to the linked list
629 relink_to_new_repr (struct access
*new_racc
, struct access
*old_racc
)
631 if (!old_racc
->first_link
)
633 gcc_assert (!old_racc
->last_link
);
637 if (new_racc
->first_link
)
639 gcc_assert (!new_racc
->last_link
->next
);
640 gcc_assert (!old_racc
->last_link
|| !old_racc
->last_link
->next
);
642 new_racc
->last_link
->next
= old_racc
->first_link
;
643 new_racc
->last_link
= old_racc
->last_link
;
647 gcc_assert (!new_racc
->last_link
);
649 new_racc
->first_link
= old_racc
->first_link
;
650 new_racc
->last_link
= old_racc
->last_link
;
652 old_racc
->first_link
= old_racc
->last_link
= NULL
;
655 /* Add ACCESS to the work queue (which is actually a stack). */
658 add_access_to_work_queue (struct access
*access
)
660 if (!access
->grp_queued
)
662 gcc_assert (!access
->next_queued
);
663 access
->next_queued
= work_queue_head
;
664 access
->grp_queued
= 1;
665 work_queue_head
= access
;
669 /* Pop an access from the work queue, and return it, assuming there is one. */
671 static struct access
*
672 pop_access_from_work_queue (void)
674 struct access
*access
= work_queue_head
;
676 work_queue_head
= access
->next_queued
;
677 access
->next_queued
= NULL
;
678 access
->grp_queued
= 0;
683 /* Allocate necessary structures. */
686 sra_initialize (void)
688 candidate_bitmap
= BITMAP_ALLOC (NULL
);
689 candidates
= new hash_table
<uid_decl_hasher
>
690 (vec_safe_length (cfun
->local_decls
) / 2);
691 should_scalarize_away_bitmap
= BITMAP_ALLOC (NULL
);
692 cannot_scalarize_away_bitmap
= BITMAP_ALLOC (NULL
);
693 gcc_obstack_init (&name_obstack
);
694 access_pool
= create_alloc_pool ("SRA accesses", sizeof (struct access
), 16);
695 link_pool
= create_alloc_pool ("SRA links", sizeof (struct assign_link
), 16);
696 base_access_vec
= new hash_map
<tree
, auto_vec
<access_p
> >;
697 memset (&sra_stats
, 0, sizeof (sra_stats
));
698 encountered_apply_args
= false;
699 encountered_recursive_call
= false;
700 encountered_unchangable_recursive_call
= false;
703 /* Deallocate all general structures. */
706 sra_deinitialize (void)
708 BITMAP_FREE (candidate_bitmap
);
711 BITMAP_FREE (should_scalarize_away_bitmap
);
712 BITMAP_FREE (cannot_scalarize_away_bitmap
);
713 free_alloc_pool (access_pool
);
714 free_alloc_pool (link_pool
);
715 obstack_free (&name_obstack
, NULL
);
717 delete base_access_vec
;
720 /* Remove DECL from candidates for SRA and write REASON to the dump file if
723 disqualify_candidate (tree decl
, const char *reason
)
725 if (bitmap_clear_bit (candidate_bitmap
, DECL_UID (decl
)))
726 candidates
->remove_elt_with_hash (decl
, DECL_UID (decl
));
728 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
730 fprintf (dump_file
, "! Disqualifying ");
731 print_generic_expr (dump_file
, decl
, 0);
732 fprintf (dump_file
, " - %s\n", reason
);
736 /* Return true iff the type contains a field or an element which does not allow
740 type_internals_preclude_sra_p (tree type
, const char **msg
)
745 switch (TREE_CODE (type
))
749 case QUAL_UNION_TYPE
:
750 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
751 if (TREE_CODE (fld
) == FIELD_DECL
)
753 tree ft
= TREE_TYPE (fld
);
755 if (TREE_THIS_VOLATILE (fld
))
757 *msg
= "volatile structure field";
760 if (!DECL_FIELD_OFFSET (fld
))
762 *msg
= "no structure field offset";
765 if (!DECL_SIZE (fld
))
767 *msg
= "zero structure field size";
770 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
772 *msg
= "structure field offset not fixed";
775 if (!tree_fits_uhwi_p (DECL_SIZE (fld
)))
777 *msg
= "structure field size not fixed";
780 if (!tree_fits_shwi_p (bit_position (fld
)))
782 *msg
= "structure field size too big";
785 if (AGGREGATE_TYPE_P (ft
)
786 && int_bit_position (fld
) % BITS_PER_UNIT
!= 0)
788 *msg
= "structure field is bit field";
792 if (AGGREGATE_TYPE_P (ft
) && type_internals_preclude_sra_p (ft
, msg
))
799 et
= TREE_TYPE (type
);
801 if (TYPE_VOLATILE (et
))
803 *msg
= "element type is volatile";
807 if (AGGREGATE_TYPE_P (et
) && type_internals_preclude_sra_p (et
, msg
))
817 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
818 base variable if it is. Return T if it is not an SSA_NAME. */
821 get_ssa_base_param (tree t
)
823 if (TREE_CODE (t
) == SSA_NAME
)
825 if (SSA_NAME_IS_DEFAULT_DEF (t
))
826 return SSA_NAME_VAR (t
);
833 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
834 belongs to, unless the BB has already been marked as a potentially
838 mark_parm_dereference (tree base
, HOST_WIDE_INT dist
, gimple stmt
)
840 basic_block bb
= gimple_bb (stmt
);
841 int idx
, parm_index
= 0;
844 if (bitmap_bit_p (final_bbs
, bb
->index
))
847 for (parm
= DECL_ARGUMENTS (current_function_decl
);
848 parm
&& parm
!= base
;
849 parm
= DECL_CHAIN (parm
))
852 gcc_assert (parm_index
< func_param_count
);
854 idx
= bb
->index
* func_param_count
+ parm_index
;
855 if (bb_dereferences
[idx
] < dist
)
856 bb_dereferences
[idx
] = dist
;
859 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
860 the three fields. Also add it to the vector of accesses corresponding to
861 the base. Finally, return the new access. */
863 static struct access
*
864 create_access_1 (tree base
, HOST_WIDE_INT offset
, HOST_WIDE_INT size
)
866 struct access
*access
;
868 access
= (struct access
*) pool_alloc (access_pool
);
869 memset (access
, 0, sizeof (struct access
));
871 access
->offset
= offset
;
874 base_access_vec
->get_or_insert (base
).safe_push (access
);
879 /* Create and insert access for EXPR. Return created access, or NULL if it is
882 static struct access
*
883 create_access (tree expr
, gimple stmt
, bool write
)
885 struct access
*access
;
886 HOST_WIDE_INT offset
, size
, max_size
;
888 bool ptr
, unscalarizable_region
= false;
890 base
= get_ref_base_and_extent (expr
, &offset
, &size
, &max_size
);
892 if (sra_mode
== SRA_MODE_EARLY_IPA
893 && TREE_CODE (base
) == MEM_REF
)
895 base
= get_ssa_base_param (TREE_OPERAND (base
, 0));
903 if (!DECL_P (base
) || !bitmap_bit_p (candidate_bitmap
, DECL_UID (base
)))
906 if (sra_mode
== SRA_MODE_EARLY_IPA
)
908 if (size
< 0 || size
!= max_size
)
910 disqualify_candidate (base
, "Encountered a variable sized access.");
913 if (TREE_CODE (expr
) == COMPONENT_REF
914 && DECL_BIT_FIELD (TREE_OPERAND (expr
, 1)))
916 disqualify_candidate (base
, "Encountered a bit-field access.");
919 gcc_checking_assert ((offset
% BITS_PER_UNIT
) == 0);
922 mark_parm_dereference (base
, offset
+ size
, stmt
);
926 if (size
!= max_size
)
929 unscalarizable_region
= true;
933 disqualify_candidate (base
, "Encountered an unconstrained access.");
938 access
= create_access_1 (base
, offset
, size
);
940 access
->type
= TREE_TYPE (expr
);
941 access
->write
= write
;
942 access
->grp_unscalarizable_region
= unscalarizable_region
;
945 if (TREE_CODE (expr
) == COMPONENT_REF
946 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr
, 1)))
947 access
->non_addressable
= 1;
953 /* Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple
954 register types or (recursively) records with only these two kinds of fields.
955 It also returns false if any of these records contains a bit-field. */
958 type_consists_of_records_p (tree type
)
962 if (TREE_CODE (type
) != RECORD_TYPE
)
965 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
966 if (TREE_CODE (fld
) == FIELD_DECL
)
968 tree ft
= TREE_TYPE (fld
);
970 if (DECL_BIT_FIELD (fld
))
973 if (!is_gimple_reg_type (ft
)
974 && !type_consists_of_records_p (ft
))
981 /* Create total_scalarization accesses for all scalar type fields in DECL that
982 must be of a RECORD_TYPE conforming to type_consists_of_records_p. BASE
983 must be the top-most VAR_DECL representing the variable, OFFSET must be the
984 offset of DECL within BASE. REF must be the memory reference expression for
988 completely_scalarize_record (tree base
, tree decl
, HOST_WIDE_INT offset
,
991 tree fld
, decl_type
= TREE_TYPE (decl
);
993 for (fld
= TYPE_FIELDS (decl_type
); fld
; fld
= DECL_CHAIN (fld
))
994 if (TREE_CODE (fld
) == FIELD_DECL
)
996 HOST_WIDE_INT pos
= offset
+ int_bit_position (fld
);
997 tree ft
= TREE_TYPE (fld
);
998 tree nref
= build3 (COMPONENT_REF
, TREE_TYPE (fld
), ref
, fld
,
1001 if (is_gimple_reg_type (ft
))
1003 struct access
*access
;
1006 size
= tree_to_uhwi (DECL_SIZE (fld
));
1007 access
= create_access_1 (base
, pos
, size
);
1008 access
->expr
= nref
;
1010 access
->grp_total_scalarization
= 1;
1011 /* Accesses for intraprocedural SRA can have their stmt NULL. */
1014 completely_scalarize_record (base
, fld
, pos
, nref
);
1018 /* Create total_scalarization accesses for all scalar type fields in VAR and
1019 for VAR a a whole. VAR must be of a RECORD_TYPE conforming to
1020 type_consists_of_records_p. */
1023 completely_scalarize_var (tree var
)
1025 HOST_WIDE_INT size
= tree_to_uhwi (DECL_SIZE (var
));
1026 struct access
*access
;
1028 access
= create_access_1 (var
, 0, size
);
1030 access
->type
= TREE_TYPE (var
);
1031 access
->grp_total_scalarization
= 1;
1033 completely_scalarize_record (var
, var
, 0, var
);
1036 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1039 contains_view_convert_expr_p (const_tree ref
)
1041 while (handled_component_p (ref
))
1043 if (TREE_CODE (ref
) == VIEW_CONVERT_EXPR
)
1045 ref
= TREE_OPERAND (ref
, 0);
1051 /* Search the given tree for a declaration by skipping handled components and
1052 exclude it from the candidates. */
1055 disqualify_base_of_expr (tree t
, const char *reason
)
1057 t
= get_base_address (t
);
1058 if (sra_mode
== SRA_MODE_EARLY_IPA
1059 && TREE_CODE (t
) == MEM_REF
)
1060 t
= get_ssa_base_param (TREE_OPERAND (t
, 0));
1062 if (t
&& DECL_P (t
))
1063 disqualify_candidate (t
, reason
);
1066 /* Scan expression EXPR and create access structures for all accesses to
1067 candidates for scalarization. Return the created access or NULL if none is
1070 static struct access
*
1071 build_access_from_expr_1 (tree expr
, gimple stmt
, bool write
)
1073 struct access
*ret
= NULL
;
1076 if (TREE_CODE (expr
) == BIT_FIELD_REF
1077 || TREE_CODE (expr
) == IMAGPART_EXPR
1078 || TREE_CODE (expr
) == REALPART_EXPR
)
1080 expr
= TREE_OPERAND (expr
, 0);
1084 partial_ref
= false;
1086 /* We need to dive through V_C_Es in order to get the size of its parameter
1087 and not the result type. Ada produces such statements. We are also
1088 capable of handling the topmost V_C_E but not any of those buried in other
1089 handled components. */
1090 if (TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
1091 expr
= TREE_OPERAND (expr
, 0);
1093 if (contains_view_convert_expr_p (expr
))
1095 disqualify_base_of_expr (expr
, "V_C_E under a different handled "
1099 if (TREE_THIS_VOLATILE (expr
))
1101 disqualify_base_of_expr (expr
, "part of a volatile reference.");
1105 switch (TREE_CODE (expr
))
1108 if (TREE_CODE (TREE_OPERAND (expr
, 0)) != ADDR_EXPR
1109 && sra_mode
!= SRA_MODE_EARLY_IPA
)
1117 case ARRAY_RANGE_REF
:
1118 ret
= create_access (expr
, stmt
, write
);
1125 if (write
&& partial_ref
&& ret
)
1126 ret
->grp_partial_lhs
= 1;
1131 /* Scan expression EXPR and create access structures for all accesses to
1132 candidates for scalarization. Return true if any access has been inserted.
1133 STMT must be the statement from which the expression is taken, WRITE must be
1134 true if the expression is a store and false otherwise. */
1137 build_access_from_expr (tree expr
, gimple stmt
, bool write
)
1139 struct access
*access
;
1141 access
= build_access_from_expr_1 (expr
, stmt
, write
);
1144 /* This means the aggregate is accesses as a whole in a way other than an
1145 assign statement and thus cannot be removed even if we had a scalar
1146 replacement for everything. */
1147 if (cannot_scalarize_away_bitmap
)
1148 bitmap_set_bit (cannot_scalarize_away_bitmap
, DECL_UID (access
->base
));
1154 /* Return the single non-EH successor edge of BB or NULL if there is none or
1158 single_non_eh_succ (basic_block bb
)
1163 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1164 if (!(e
->flags
& EDGE_EH
))
1174 /* Disqualify LHS and RHS for scalarization if STMT has to terminate its BB and
1175 there is no alternative spot where to put statements SRA might need to
1176 generate after it. The spot we are looking for is an edge leading to a
1177 single non-EH successor, if it exists and is indeed single. RHS may be
1178 NULL, in that case ignore it. */
1181 disqualify_if_bad_bb_terminating_stmt (gimple stmt
, tree lhs
, tree rhs
)
1183 if ((sra_mode
== SRA_MODE_EARLY_INTRA
|| sra_mode
== SRA_MODE_INTRA
)
1184 && stmt_ends_bb_p (stmt
))
1186 if (single_non_eh_succ (gimple_bb (stmt
)))
1189 disqualify_base_of_expr (lhs
, "LHS of a throwing stmt.");
1191 disqualify_base_of_expr (rhs
, "RHS of a throwing stmt.");
1197 /* Scan expressions occurring in STMT, create access structures for all accesses
1198 to candidates for scalarization and remove those candidates which occur in
1199 statements or expressions that prevent them from being split apart. Return
1200 true if any access has been inserted. */
1203 build_accesses_from_assign (gimple stmt
)
1206 struct access
*lacc
, *racc
;
1208 if (!gimple_assign_single_p (stmt
)
1209 /* Scope clobbers don't influence scalarization. */
1210 || gimple_clobber_p (stmt
))
1213 lhs
= gimple_assign_lhs (stmt
);
1214 rhs
= gimple_assign_rhs1 (stmt
);
1216 if (disqualify_if_bad_bb_terminating_stmt (stmt
, lhs
, rhs
))
1219 racc
= build_access_from_expr_1 (rhs
, stmt
, false);
1220 lacc
= build_access_from_expr_1 (lhs
, stmt
, true);
1223 lacc
->grp_assignment_write
= 1;
1227 racc
->grp_assignment_read
= 1;
1228 if (should_scalarize_away_bitmap
&& !gimple_has_volatile_ops (stmt
)
1229 && !is_gimple_reg_type (racc
->type
))
1230 bitmap_set_bit (should_scalarize_away_bitmap
, DECL_UID (racc
->base
));
1234 && (sra_mode
== SRA_MODE_EARLY_INTRA
|| sra_mode
== SRA_MODE_INTRA
)
1235 && !lacc
->grp_unscalarizable_region
1236 && !racc
->grp_unscalarizable_region
1237 && AGGREGATE_TYPE_P (TREE_TYPE (lhs
))
1238 && lacc
->size
== racc
->size
1239 && useless_type_conversion_p (lacc
->type
, racc
->type
))
1241 struct assign_link
*link
;
1243 link
= (struct assign_link
*) pool_alloc (link_pool
);
1244 memset (link
, 0, sizeof (struct assign_link
));
1249 add_link_to_rhs (racc
, link
);
1252 return lacc
|| racc
;
1255 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1256 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1259 asm_visit_addr (gimple
, tree op
, tree
, void *)
1261 op
= get_base_address (op
);
1264 disqualify_candidate (op
, "Non-scalarizable GIMPLE_ASM operand.");
1269 /* Return true iff callsite CALL has at least as many actual arguments as there
1270 are formal parameters of the function currently processed by IPA-SRA and
1271 that their types match. */
1274 callsite_arguments_match_p (gimple call
)
1276 if (gimple_call_num_args (call
) < (unsigned) func_param_count
)
1281 for (parm
= DECL_ARGUMENTS (current_function_decl
), i
= 0;
1283 parm
= DECL_CHAIN (parm
), i
++)
1285 tree arg
= gimple_call_arg (call
, i
);
1286 if (!useless_type_conversion_p (TREE_TYPE (parm
), TREE_TYPE (arg
)))
1292 /* Scan function and look for interesting expressions and create access
1293 structures for them. Return true iff any access is created. */
1296 scan_function (void)
1301 FOR_EACH_BB_FN (bb
, cfun
)
1303 gimple_stmt_iterator gsi
;
1304 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1306 gimple stmt
= gsi_stmt (gsi
);
1310 if (final_bbs
&& stmt_can_throw_external (stmt
))
1311 bitmap_set_bit (final_bbs
, bb
->index
);
1312 switch (gimple_code (stmt
))
1315 t
= gimple_return_retval (as_a
<greturn
*> (stmt
));
1317 ret
|= build_access_from_expr (t
, stmt
, false);
1319 bitmap_set_bit (final_bbs
, bb
->index
);
1323 ret
|= build_accesses_from_assign (stmt
);
1327 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1328 ret
|= build_access_from_expr (gimple_call_arg (stmt
, i
),
1331 if (sra_mode
== SRA_MODE_EARLY_IPA
)
1333 tree dest
= gimple_call_fndecl (stmt
);
1334 int flags
= gimple_call_flags (stmt
);
1338 if (DECL_BUILT_IN_CLASS (dest
) == BUILT_IN_NORMAL
1339 && DECL_FUNCTION_CODE (dest
) == BUILT_IN_APPLY_ARGS
)
1340 encountered_apply_args
= true;
1341 if (recursive_call_p (current_function_decl
, dest
))
1343 encountered_recursive_call
= true;
1344 if (!callsite_arguments_match_p (stmt
))
1345 encountered_unchangable_recursive_call
= true;
1350 && (flags
& (ECF_CONST
| ECF_PURE
)) == 0)
1351 bitmap_set_bit (final_bbs
, bb
->index
);
1354 t
= gimple_call_lhs (stmt
);
1355 if (t
&& !disqualify_if_bad_bb_terminating_stmt (stmt
, t
, NULL
))
1356 ret
|= build_access_from_expr (t
, stmt
, true);
1361 gasm
*asm_stmt
= as_a
<gasm
*> (stmt
);
1362 walk_stmt_load_store_addr_ops (asm_stmt
, NULL
, NULL
, NULL
,
1365 bitmap_set_bit (final_bbs
, bb
->index
);
1367 for (i
= 0; i
< gimple_asm_ninputs (asm_stmt
); i
++)
1369 t
= TREE_VALUE (gimple_asm_input_op (asm_stmt
, i
));
1370 ret
|= build_access_from_expr (t
, asm_stmt
, false);
1372 for (i
= 0; i
< gimple_asm_noutputs (asm_stmt
); i
++)
1374 t
= TREE_VALUE (gimple_asm_output_op (asm_stmt
, i
));
1375 ret
|= build_access_from_expr (t
, asm_stmt
, true);
1389 /* Helper of QSORT function. There are pointers to accesses in the array. An
1390 access is considered smaller than another if it has smaller offset or if the
1391 offsets are the same but is size is bigger. */
1394 compare_access_positions (const void *a
, const void *b
)
1396 const access_p
*fp1
= (const access_p
*) a
;
1397 const access_p
*fp2
= (const access_p
*) b
;
1398 const access_p f1
= *fp1
;
1399 const access_p f2
= *fp2
;
1401 if (f1
->offset
!= f2
->offset
)
1402 return f1
->offset
< f2
->offset
? -1 : 1;
1404 if (f1
->size
== f2
->size
)
1406 if (f1
->type
== f2
->type
)
1408 /* Put any non-aggregate type before any aggregate type. */
1409 else if (!is_gimple_reg_type (f1
->type
)
1410 && is_gimple_reg_type (f2
->type
))
1412 else if (is_gimple_reg_type (f1
->type
)
1413 && !is_gimple_reg_type (f2
->type
))
1415 /* Put any complex or vector type before any other scalar type. */
1416 else if (TREE_CODE (f1
->type
) != COMPLEX_TYPE
1417 && TREE_CODE (f1
->type
) != VECTOR_TYPE
1418 && (TREE_CODE (f2
->type
) == COMPLEX_TYPE
1419 || TREE_CODE (f2
->type
) == VECTOR_TYPE
))
1421 else if ((TREE_CODE (f1
->type
) == COMPLEX_TYPE
1422 || TREE_CODE (f1
->type
) == VECTOR_TYPE
)
1423 && TREE_CODE (f2
->type
) != COMPLEX_TYPE
1424 && TREE_CODE (f2
->type
) != VECTOR_TYPE
)
1426 /* Put the integral type with the bigger precision first. */
1427 else if (INTEGRAL_TYPE_P (f1
->type
)
1428 && INTEGRAL_TYPE_P (f2
->type
))
1429 return TYPE_PRECISION (f2
->type
) - TYPE_PRECISION (f1
->type
);
1430 /* Put any integral type with non-full precision last. */
1431 else if (INTEGRAL_TYPE_P (f1
->type
)
1432 && (TREE_INT_CST_LOW (TYPE_SIZE (f1
->type
))
1433 != TYPE_PRECISION (f1
->type
)))
1435 else if (INTEGRAL_TYPE_P (f2
->type
)
1436 && (TREE_INT_CST_LOW (TYPE_SIZE (f2
->type
))
1437 != TYPE_PRECISION (f2
->type
)))
1439 /* Stabilize the sort. */
1440 return TYPE_UID (f1
->type
) - TYPE_UID (f2
->type
);
1443 /* We want the bigger accesses first, thus the opposite operator in the next
1445 return f1
->size
> f2
->size
? -1 : 1;
1449 /* Append a name of the declaration to the name obstack. A helper function for
1453 make_fancy_decl_name (tree decl
)
1457 tree name
= DECL_NAME (decl
);
1459 obstack_grow (&name_obstack
, IDENTIFIER_POINTER (name
),
1460 IDENTIFIER_LENGTH (name
));
1463 sprintf (buffer
, "D%u", DECL_UID (decl
));
1464 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1468 /* Helper for make_fancy_name. */
1471 make_fancy_name_1 (tree expr
)
1478 make_fancy_decl_name (expr
);
1482 switch (TREE_CODE (expr
))
1485 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1486 obstack_1grow (&name_obstack
, '$');
1487 make_fancy_decl_name (TREE_OPERAND (expr
, 1));
1491 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1492 obstack_1grow (&name_obstack
, '$');
1493 /* Arrays with only one element may not have a constant as their
1495 index
= TREE_OPERAND (expr
, 1);
1496 if (TREE_CODE (index
) != INTEGER_CST
)
1498 sprintf (buffer
, HOST_WIDE_INT_PRINT_DEC
, TREE_INT_CST_LOW (index
));
1499 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1503 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1507 make_fancy_name_1 (TREE_OPERAND (expr
, 0));
1508 if (!integer_zerop (TREE_OPERAND (expr
, 1)))
1510 obstack_1grow (&name_obstack
, '$');
1511 sprintf (buffer
, HOST_WIDE_INT_PRINT_DEC
,
1512 TREE_INT_CST_LOW (TREE_OPERAND (expr
, 1)));
1513 obstack_grow (&name_obstack
, buffer
, strlen (buffer
));
1520 gcc_unreachable (); /* we treat these as scalars. */
1527 /* Create a human readable name for replacement variable of ACCESS. */
1530 make_fancy_name (tree expr
)
1532 make_fancy_name_1 (expr
);
1533 obstack_1grow (&name_obstack
, '\0');
1534 return XOBFINISH (&name_obstack
, char *);
1537 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1538 EXP_TYPE at the given OFFSET. If BASE is something for which
1539 get_addr_base_and_unit_offset returns NULL, gsi must be non-NULL and is used
1540 to insert new statements either before or below the current one as specified
1541 by INSERT_AFTER. This function is not capable of handling bitfields.
1543 BASE must be either a declaration or a memory reference that has correct
1544 alignment ifformation embeded in it (e.g. a pre-existing one in SRA). */
1547 build_ref_for_offset (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1548 tree exp_type
, gimple_stmt_iterator
*gsi
,
1551 tree prev_base
= base
;
1554 HOST_WIDE_INT base_offset
;
1555 unsigned HOST_WIDE_INT misalign
;
1558 gcc_checking_assert (offset
% BITS_PER_UNIT
== 0);
1559 get_object_alignment_1 (base
, &align
, &misalign
);
1560 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
1562 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1563 offset such as array[var_index]. */
1569 gcc_checking_assert (gsi
);
1570 tmp
= make_ssa_name (build_pointer_type (TREE_TYPE (prev_base
)));
1571 addr
= build_fold_addr_expr (unshare_expr (prev_base
));
1572 STRIP_USELESS_TYPE_CONVERSION (addr
);
1573 stmt
= gimple_build_assign (tmp
, addr
);
1574 gimple_set_location (stmt
, loc
);
1576 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
1578 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
1580 off
= build_int_cst (reference_alias_ptr_type (prev_base
),
1581 offset
/ BITS_PER_UNIT
);
1584 else if (TREE_CODE (base
) == MEM_REF
)
1586 off
= build_int_cst (TREE_TYPE (TREE_OPERAND (base
, 1)),
1587 base_offset
+ offset
/ BITS_PER_UNIT
);
1588 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1), off
);
1589 base
= unshare_expr (TREE_OPERAND (base
, 0));
1593 off
= build_int_cst (reference_alias_ptr_type (base
),
1594 base_offset
+ offset
/ BITS_PER_UNIT
);
1595 base
= build_fold_addr_expr (unshare_expr (base
));
1598 misalign
= (misalign
+ offset
) & (align
- 1);
1600 align
= (misalign
& -misalign
);
1601 if (align
!= TYPE_ALIGN (exp_type
))
1602 exp_type
= build_aligned_type (exp_type
, align
);
1604 mem_ref
= fold_build2_loc (loc
, MEM_REF
, exp_type
, base
, off
);
1605 if (TREE_THIS_VOLATILE (prev_base
))
1606 TREE_THIS_VOLATILE (mem_ref
) = 1;
1607 if (TREE_SIDE_EFFECTS (prev_base
))
1608 TREE_SIDE_EFFECTS (mem_ref
) = 1;
1612 /* Construct a memory reference to a part of an aggregate BASE at the given
1613 OFFSET and of the same type as MODEL. In case this is a reference to a
1614 bit-field, the function will replicate the last component_ref of model's
1615 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1616 build_ref_for_offset. */
1619 build_ref_for_model (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1620 struct access
*model
, gimple_stmt_iterator
*gsi
,
1623 if (TREE_CODE (model
->expr
) == COMPONENT_REF
1624 && DECL_BIT_FIELD (TREE_OPERAND (model
->expr
, 1)))
1626 /* This access represents a bit-field. */
1627 tree t
, exp_type
, fld
= TREE_OPERAND (model
->expr
, 1);
1629 offset
-= int_bit_position (fld
);
1630 exp_type
= TREE_TYPE (TREE_OPERAND (model
->expr
, 0));
1631 t
= build_ref_for_offset (loc
, base
, offset
, exp_type
, gsi
, insert_after
);
1632 return fold_build3_loc (loc
, COMPONENT_REF
, TREE_TYPE (fld
), t
, fld
,
1636 return build_ref_for_offset (loc
, base
, offset
, model
->type
,
1640 /* Attempt to build a memory reference that we could but into a gimple
1641 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1642 create statements and return s NULL instead. This function also ignores
1643 alignment issues and so its results should never end up in non-debug
1647 build_debug_ref_for_model (location_t loc
, tree base
, HOST_WIDE_INT offset
,
1648 struct access
*model
)
1650 HOST_WIDE_INT base_offset
;
1653 if (TREE_CODE (model
->expr
) == COMPONENT_REF
1654 && DECL_BIT_FIELD (TREE_OPERAND (model
->expr
, 1)))
1657 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
1660 if (TREE_CODE (base
) == MEM_REF
)
1662 off
= build_int_cst (TREE_TYPE (TREE_OPERAND (base
, 1)),
1663 base_offset
+ offset
/ BITS_PER_UNIT
);
1664 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1), off
);
1665 base
= unshare_expr (TREE_OPERAND (base
, 0));
1669 off
= build_int_cst (reference_alias_ptr_type (base
),
1670 base_offset
+ offset
/ BITS_PER_UNIT
);
1671 base
= build_fold_addr_expr (unshare_expr (base
));
1674 return fold_build2_loc (loc
, MEM_REF
, model
->type
, base
, off
);
1677 /* Construct a memory reference consisting of component_refs and array_refs to
1678 a part of an aggregate *RES (which is of type TYPE). The requested part
1679 should have type EXP_TYPE at be the given OFFSET. This function might not
1680 succeed, it returns true when it does and only then *RES points to something
1681 meaningful. This function should be used only to build expressions that we
1682 might need to present to user (e.g. in warnings). In all other situations,
1683 build_ref_for_model or build_ref_for_offset should be used instead. */
1686 build_user_friendly_ref_for_offset (tree
*res
, tree type
, HOST_WIDE_INT offset
,
1692 tree tr_size
, index
, minidx
;
1693 HOST_WIDE_INT el_size
;
1695 if (offset
== 0 && exp_type
1696 && types_compatible_p (exp_type
, type
))
1699 switch (TREE_CODE (type
))
1702 case QUAL_UNION_TYPE
:
1704 for (fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
1706 HOST_WIDE_INT pos
, size
;
1707 tree tr_pos
, expr
, *expr_ptr
;
1709 if (TREE_CODE (fld
) != FIELD_DECL
)
1712 tr_pos
= bit_position (fld
);
1713 if (!tr_pos
|| !tree_fits_uhwi_p (tr_pos
))
1715 pos
= tree_to_uhwi (tr_pos
);
1716 gcc_assert (TREE_CODE (type
) == RECORD_TYPE
|| pos
== 0);
1717 tr_size
= DECL_SIZE (fld
);
1718 if (!tr_size
|| !tree_fits_uhwi_p (tr_size
))
1720 size
= tree_to_uhwi (tr_size
);
1726 else if (pos
> offset
|| (pos
+ size
) <= offset
)
1729 expr
= build3 (COMPONENT_REF
, TREE_TYPE (fld
), *res
, fld
,
1732 if (build_user_friendly_ref_for_offset (expr_ptr
, TREE_TYPE (fld
),
1733 offset
- pos
, exp_type
))
1742 tr_size
= TYPE_SIZE (TREE_TYPE (type
));
1743 if (!tr_size
|| !tree_fits_uhwi_p (tr_size
))
1745 el_size
= tree_to_uhwi (tr_size
);
1747 minidx
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
1748 if (TREE_CODE (minidx
) != INTEGER_CST
|| el_size
== 0)
1750 index
= build_int_cst (TYPE_DOMAIN (type
), offset
/ el_size
);
1751 if (!integer_zerop (minidx
))
1752 index
= int_const_binop (PLUS_EXPR
, index
, minidx
);
1753 *res
= build4 (ARRAY_REF
, TREE_TYPE (type
), *res
, index
,
1754 NULL_TREE
, NULL_TREE
);
1755 offset
= offset
% el_size
;
1756 type
= TREE_TYPE (type
);
1771 /* Return true iff TYPE is stdarg va_list type. */
1774 is_va_list_type (tree type
)
1776 return TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (va_list_type_node
);
1779 /* Print message to dump file why a variable was rejected. */
1782 reject (tree var
, const char *msg
)
1784 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1786 fprintf (dump_file
, "Rejected (%d): %s: ", DECL_UID (var
), msg
);
1787 print_generic_expr (dump_file
, var
, 0);
1788 fprintf (dump_file
, "\n");
1792 /* Return true if VAR is a candidate for SRA. */
1795 maybe_add_sra_candidate (tree var
)
1797 tree type
= TREE_TYPE (var
);
1801 if (!AGGREGATE_TYPE_P (type
))
1803 reject (var
, "not aggregate");
1806 if (needs_to_live_in_memory (var
))
1808 reject (var
, "needs to live in memory");
1811 if (TREE_THIS_VOLATILE (var
))
1813 reject (var
, "is volatile");
1816 if (!COMPLETE_TYPE_P (type
))
1818 reject (var
, "has incomplete type");
1821 if (!tree_fits_uhwi_p (TYPE_SIZE (type
)))
1823 reject (var
, "type size not fixed");
1826 if (tree_to_uhwi (TYPE_SIZE (type
)) == 0)
1828 reject (var
, "type size is zero");
1831 if (type_internals_preclude_sra_p (type
, &msg
))
1836 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1837 we also want to schedule it rather late. Thus we ignore it in
1839 (sra_mode
== SRA_MODE_EARLY_INTRA
1840 && is_va_list_type (type
)))
1842 reject (var
, "is va_list");
1846 bitmap_set_bit (candidate_bitmap
, DECL_UID (var
));
1847 slot
= candidates
->find_slot_with_hash (var
, DECL_UID (var
), INSERT
);
1850 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1852 fprintf (dump_file
, "Candidate (%d): ", DECL_UID (var
));
1853 print_generic_expr (dump_file
, var
, 0);
1854 fprintf (dump_file
, "\n");
1860 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1861 those with type which is suitable for scalarization. */
1864 find_var_candidates (void)
1870 for (parm
= DECL_ARGUMENTS (current_function_decl
);
1872 parm
= DECL_CHAIN (parm
))
1873 ret
|= maybe_add_sra_candidate (parm
);
1875 FOR_EACH_LOCAL_DECL (cfun
, i
, var
)
1877 if (TREE_CODE (var
) != VAR_DECL
)
1880 ret
|= maybe_add_sra_candidate (var
);
1886 /* Sort all accesses for the given variable, check for partial overlaps and
1887 return NULL if there are any. If there are none, pick a representative for
1888 each combination of offset and size and create a linked list out of them.
1889 Return the pointer to the first representative and make sure it is the first
1890 one in the vector of accesses. */
1892 static struct access
*
1893 sort_and_splice_var_accesses (tree var
)
1895 int i
, j
, access_count
;
1896 struct access
*res
, **prev_acc_ptr
= &res
;
1897 vec
<access_p
> *access_vec
;
1899 HOST_WIDE_INT low
= -1, high
= 0;
1901 access_vec
= get_base_access_vector (var
);
1904 access_count
= access_vec
->length ();
1906 /* Sort by <OFFSET, SIZE>. */
1907 access_vec
->qsort (compare_access_positions
);
1910 while (i
< access_count
)
1912 struct access
*access
= (*access_vec
)[i
];
1913 bool grp_write
= access
->write
;
1914 bool grp_read
= !access
->write
;
1915 bool grp_scalar_write
= access
->write
1916 && is_gimple_reg_type (access
->type
);
1917 bool grp_scalar_read
= !access
->write
1918 && is_gimple_reg_type (access
->type
);
1919 bool grp_assignment_read
= access
->grp_assignment_read
;
1920 bool grp_assignment_write
= access
->grp_assignment_write
;
1921 bool multiple_scalar_reads
= false;
1922 bool total_scalarization
= access
->grp_total_scalarization
;
1923 bool grp_partial_lhs
= access
->grp_partial_lhs
;
1924 bool first_scalar
= is_gimple_reg_type (access
->type
);
1925 bool unscalarizable_region
= access
->grp_unscalarizable_region
;
1927 if (first
|| access
->offset
>= high
)
1930 low
= access
->offset
;
1931 high
= access
->offset
+ access
->size
;
1933 else if (access
->offset
> low
&& access
->offset
+ access
->size
> high
)
1936 gcc_assert (access
->offset
>= low
1937 && access
->offset
+ access
->size
<= high
);
1940 while (j
< access_count
)
1942 struct access
*ac2
= (*access_vec
)[j
];
1943 if (ac2
->offset
!= access
->offset
|| ac2
->size
!= access
->size
)
1948 grp_scalar_write
= (grp_scalar_write
1949 || is_gimple_reg_type (ac2
->type
));
1954 if (is_gimple_reg_type (ac2
->type
))
1956 if (grp_scalar_read
)
1957 multiple_scalar_reads
= true;
1959 grp_scalar_read
= true;
1962 grp_assignment_read
|= ac2
->grp_assignment_read
;
1963 grp_assignment_write
|= ac2
->grp_assignment_write
;
1964 grp_partial_lhs
|= ac2
->grp_partial_lhs
;
1965 unscalarizable_region
|= ac2
->grp_unscalarizable_region
;
1966 total_scalarization
|= ac2
->grp_total_scalarization
;
1967 relink_to_new_repr (access
, ac2
);
1969 /* If there are both aggregate-type and scalar-type accesses with
1970 this combination of size and offset, the comparison function
1971 should have put the scalars first. */
1972 gcc_assert (first_scalar
|| !is_gimple_reg_type (ac2
->type
));
1973 ac2
->group_representative
= access
;
1979 access
->group_representative
= access
;
1980 access
->grp_write
= grp_write
;
1981 access
->grp_read
= grp_read
;
1982 access
->grp_scalar_read
= grp_scalar_read
;
1983 access
->grp_scalar_write
= grp_scalar_write
;
1984 access
->grp_assignment_read
= grp_assignment_read
;
1985 access
->grp_assignment_write
= grp_assignment_write
;
1986 access
->grp_hint
= multiple_scalar_reads
|| total_scalarization
;
1987 access
->grp_total_scalarization
= total_scalarization
;
1988 access
->grp_partial_lhs
= grp_partial_lhs
;
1989 access
->grp_unscalarizable_region
= unscalarizable_region
;
1990 if (access
->first_link
)
1991 add_access_to_work_queue (access
);
1993 *prev_acc_ptr
= access
;
1994 prev_acc_ptr
= &access
->next_grp
;
1997 gcc_assert (res
== (*access_vec
)[0]);
2001 /* Create a variable for the given ACCESS which determines the type, name and a
2002 few other properties. Return the variable declaration and store it also to
2003 ACCESS->replacement. */
2006 create_access_replacement (struct access
*access
)
2010 if (access
->grp_to_be_debug_replaced
)
2012 repl
= create_tmp_var_raw (access
->type
);
2013 DECL_CONTEXT (repl
) = current_function_decl
;
2016 /* Drop any special alignment on the type if it's not on the main
2017 variant. This avoids issues with weirdo ABIs like AAPCS. */
2018 repl
= create_tmp_var (build_qualified_type
2019 (TYPE_MAIN_VARIANT (access
->type
),
2020 TYPE_QUALS (access
->type
)), "SR");
2021 if (TREE_CODE (access
->type
) == COMPLEX_TYPE
2022 || TREE_CODE (access
->type
) == VECTOR_TYPE
)
2024 if (!access
->grp_partial_lhs
)
2025 DECL_GIMPLE_REG_P (repl
) = 1;
2027 else if (access
->grp_partial_lhs
2028 && is_gimple_reg_type (access
->type
))
2029 TREE_ADDRESSABLE (repl
) = 1;
2031 DECL_SOURCE_LOCATION (repl
) = DECL_SOURCE_LOCATION (access
->base
);
2032 DECL_ARTIFICIAL (repl
) = 1;
2033 DECL_IGNORED_P (repl
) = DECL_IGNORED_P (access
->base
);
2035 if (DECL_NAME (access
->base
)
2036 && !DECL_IGNORED_P (access
->base
)
2037 && !DECL_ARTIFICIAL (access
->base
))
2039 char *pretty_name
= make_fancy_name (access
->expr
);
2040 tree debug_expr
= unshare_expr_without_location (access
->expr
), d
;
2043 DECL_NAME (repl
) = get_identifier (pretty_name
);
2044 obstack_free (&name_obstack
, pretty_name
);
2046 /* Get rid of any SSA_NAMEs embedded in debug_expr,
2047 as DECL_DEBUG_EXPR isn't considered when looking for still
2048 used SSA_NAMEs and thus they could be freed. All debug info
2049 generation cares is whether something is constant or variable
2050 and that get_ref_base_and_extent works properly on the
2051 expression. It cannot handle accesses at a non-constant offset
2052 though, so just give up in those cases. */
2053 for (d
= debug_expr
;
2054 !fail
&& (handled_component_p (d
) || TREE_CODE (d
) == MEM_REF
);
2055 d
= TREE_OPERAND (d
, 0))
2056 switch (TREE_CODE (d
))
2059 case ARRAY_RANGE_REF
:
2060 if (TREE_OPERAND (d
, 1)
2061 && TREE_CODE (TREE_OPERAND (d
, 1)) != INTEGER_CST
)
2063 if (TREE_OPERAND (d
, 3)
2064 && TREE_CODE (TREE_OPERAND (d
, 3)) != INTEGER_CST
)
2068 if (TREE_OPERAND (d
, 2)
2069 && TREE_CODE (TREE_OPERAND (d
, 2)) != INTEGER_CST
)
2073 if (TREE_CODE (TREE_OPERAND (d
, 0)) != ADDR_EXPR
)
2076 d
= TREE_OPERAND (d
, 0);
2083 SET_DECL_DEBUG_EXPR (repl
, debug_expr
);
2084 DECL_HAS_DEBUG_EXPR_P (repl
) = 1;
2086 if (access
->grp_no_warning
)
2087 TREE_NO_WARNING (repl
) = 1;
2089 TREE_NO_WARNING (repl
) = TREE_NO_WARNING (access
->base
);
2092 TREE_NO_WARNING (repl
) = 1;
2096 if (access
->grp_to_be_debug_replaced
)
2098 fprintf (dump_file
, "Created a debug-only replacement for ");
2099 print_generic_expr (dump_file
, access
->base
, 0);
2100 fprintf (dump_file
, " offset: %u, size: %u\n",
2101 (unsigned) access
->offset
, (unsigned) access
->size
);
2105 fprintf (dump_file
, "Created a replacement for ");
2106 print_generic_expr (dump_file
, access
->base
, 0);
2107 fprintf (dump_file
, " offset: %u, size: %u: ",
2108 (unsigned) access
->offset
, (unsigned) access
->size
);
2109 print_generic_expr (dump_file
, repl
, 0);
2110 fprintf (dump_file
, "\n");
2113 sra_stats
.replacements
++;
2118 /* Return ACCESS scalar replacement, create it if it does not exist yet. */
2121 get_access_replacement (struct access
*access
)
2123 gcc_checking_assert (access
->replacement_decl
);
2124 return access
->replacement_decl
;
2128 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2129 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2130 to it is not "within" the root. Return false iff some accesses partially
2134 build_access_subtree (struct access
**access
)
2136 struct access
*root
= *access
, *last_child
= NULL
;
2137 HOST_WIDE_INT limit
= root
->offset
+ root
->size
;
2139 *access
= (*access
)->next_grp
;
2140 while (*access
&& (*access
)->offset
+ (*access
)->size
<= limit
)
2143 root
->first_child
= *access
;
2145 last_child
->next_sibling
= *access
;
2146 last_child
= *access
;
2148 if (!build_access_subtree (access
))
2152 if (*access
&& (*access
)->offset
< limit
)
2158 /* Build a tree of access representatives, ACCESS is the pointer to the first
2159 one, others are linked in a list by the next_grp field. Return false iff
2160 some accesses partially overlap. */
2163 build_access_trees (struct access
*access
)
2167 struct access
*root
= access
;
2169 if (!build_access_subtree (&access
))
2171 root
->next_grp
= access
;
2176 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2180 expr_with_var_bounded_array_refs_p (tree expr
)
2182 while (handled_component_p (expr
))
2184 if (TREE_CODE (expr
) == ARRAY_REF
2185 && !tree_fits_shwi_p (array_ref_low_bound (expr
)))
2187 expr
= TREE_OPERAND (expr
, 0);
2192 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2193 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2194 sorts of access flags appropriately along the way, notably always set
2195 grp_read and grp_assign_read according to MARK_READ and grp_write when
2198 Creating a replacement for a scalar access is considered beneficial if its
2199 grp_hint is set (this means we are either attempting total scalarization or
2200 there is more than one direct read access) or according to the following
2203 Access written to through a scalar type (once or more times)
2205 | Written to in an assignment statement
2207 | | Access read as scalar _once_
2209 | | | Read in an assignment statement
2211 | | | | Scalarize Comment
2212 -----------------------------------------------------------------------------
2213 0 0 0 0 No access for the scalar
2214 0 0 0 1 No access for the scalar
2215 0 0 1 0 No Single read - won't help
2216 0 0 1 1 No The same case
2217 0 1 0 0 No access for the scalar
2218 0 1 0 1 No access for the scalar
2219 0 1 1 0 Yes s = *g; return s.i;
2220 0 1 1 1 Yes The same case as above
2221 1 0 0 0 No Won't help
2222 1 0 0 1 Yes s.i = 1; *g = s;
2223 1 0 1 0 Yes s.i = 5; g = s.i;
2224 1 0 1 1 Yes The same case as above
2225 1 1 0 0 No Won't help.
2226 1 1 0 1 Yes s.i = 1; *g = s;
2227 1 1 1 0 Yes s = *g; return s.i;
2228 1 1 1 1 Yes Any of the above yeses */
2231 analyze_access_subtree (struct access
*root
, struct access
*parent
,
2232 bool allow_replacements
)
2234 struct access
*child
;
2235 HOST_WIDE_INT limit
= root
->offset
+ root
->size
;
2236 HOST_WIDE_INT covered_to
= root
->offset
;
2237 bool scalar
= is_gimple_reg_type (root
->type
);
2238 bool hole
= false, sth_created
= false;
2242 if (parent
->grp_read
)
2244 if (parent
->grp_assignment_read
)
2245 root
->grp_assignment_read
= 1;
2246 if (parent
->grp_write
)
2247 root
->grp_write
= 1;
2248 if (parent
->grp_assignment_write
)
2249 root
->grp_assignment_write
= 1;
2250 if (parent
->grp_total_scalarization
)
2251 root
->grp_total_scalarization
= 1;
2254 if (root
->grp_unscalarizable_region
)
2255 allow_replacements
= false;
2257 if (allow_replacements
&& expr_with_var_bounded_array_refs_p (root
->expr
))
2258 allow_replacements
= false;
2260 for (child
= root
->first_child
; child
; child
= child
->next_sibling
)
2262 hole
|= covered_to
< child
->offset
;
2263 sth_created
|= analyze_access_subtree (child
, root
,
2264 allow_replacements
&& !scalar
);
2266 root
->grp_unscalarized_data
|= child
->grp_unscalarized_data
;
2267 root
->grp_total_scalarization
&= child
->grp_total_scalarization
;
2268 if (child
->grp_covered
)
2269 covered_to
+= child
->size
;
2274 if (allow_replacements
&& scalar
&& !root
->first_child
2276 || ((root
->grp_scalar_read
|| root
->grp_assignment_read
)
2277 && (root
->grp_scalar_write
|| root
->grp_assignment_write
))))
2279 /* Always create access replacements that cover the whole access.
2280 For integral types this means the precision has to match.
2281 Avoid assumptions based on the integral type kind, too. */
2282 if (INTEGRAL_TYPE_P (root
->type
)
2283 && (TREE_CODE (root
->type
) != INTEGER_TYPE
2284 || TYPE_PRECISION (root
->type
) != root
->size
)
2285 /* But leave bitfield accesses alone. */
2286 && (TREE_CODE (root
->expr
) != COMPONENT_REF
2287 || !DECL_BIT_FIELD (TREE_OPERAND (root
->expr
, 1))))
2289 tree rt
= root
->type
;
2290 gcc_assert ((root
->offset
% BITS_PER_UNIT
) == 0
2291 && (root
->size
% BITS_PER_UNIT
) == 0);
2292 root
->type
= build_nonstandard_integer_type (root
->size
,
2293 TYPE_UNSIGNED (rt
));
2294 root
->expr
= build_ref_for_offset (UNKNOWN_LOCATION
,
2295 root
->base
, root
->offset
,
2296 root
->type
, NULL
, false);
2298 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2300 fprintf (dump_file
, "Changing the type of a replacement for ");
2301 print_generic_expr (dump_file
, root
->base
, 0);
2302 fprintf (dump_file
, " offset: %u, size: %u ",
2303 (unsigned) root
->offset
, (unsigned) root
->size
);
2304 fprintf (dump_file
, " to an integer.\n");
2308 root
->grp_to_be_replaced
= 1;
2309 root
->replacement_decl
= create_access_replacement (root
);
2315 if (allow_replacements
2316 && scalar
&& !root
->first_child
2317 && (root
->grp_scalar_write
|| root
->grp_assignment_write
)
2318 && !bitmap_bit_p (cannot_scalarize_away_bitmap
,
2319 DECL_UID (root
->base
)))
2321 gcc_checking_assert (!root
->grp_scalar_read
2322 && !root
->grp_assignment_read
);
2324 if (MAY_HAVE_DEBUG_STMTS
)
2326 root
->grp_to_be_debug_replaced
= 1;
2327 root
->replacement_decl
= create_access_replacement (root
);
2331 if (covered_to
< limit
)
2334 root
->grp_total_scalarization
= 0;
2337 if (!hole
|| root
->grp_total_scalarization
)
2338 root
->grp_covered
= 1;
2339 else if (root
->grp_write
|| TREE_CODE (root
->base
) == PARM_DECL
)
2340 root
->grp_unscalarized_data
= 1; /* not covered and written to */
2344 /* Analyze all access trees linked by next_grp by the means of
2345 analyze_access_subtree. */
2347 analyze_access_trees (struct access
*access
)
2353 if (analyze_access_subtree (access
, NULL
, true))
2355 access
= access
->next_grp
;
2361 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2362 SIZE would conflict with an already existing one. If exactly such a child
2363 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2366 child_would_conflict_in_lacc (struct access
*lacc
, HOST_WIDE_INT norm_offset
,
2367 HOST_WIDE_INT size
, struct access
**exact_match
)
2369 struct access
*child
;
2371 for (child
= lacc
->first_child
; child
; child
= child
->next_sibling
)
2373 if (child
->offset
== norm_offset
&& child
->size
== size
)
2375 *exact_match
= child
;
2379 if (child
->offset
< norm_offset
+ size
2380 && child
->offset
+ child
->size
> norm_offset
)
2387 /* Create a new child access of PARENT, with all properties just like MODEL
2388 except for its offset and with its grp_write false and grp_read true.
2389 Return the new access or NULL if it cannot be created. Note that this access
2390 is created long after all splicing and sorting, it's not located in any
2391 access vector and is automatically a representative of its group. */
2393 static struct access
*
2394 create_artificial_child_access (struct access
*parent
, struct access
*model
,
2395 HOST_WIDE_INT new_offset
)
2397 struct access
*access
;
2398 struct access
**child
;
2399 tree expr
= parent
->base
;
2401 gcc_assert (!model
->grp_unscalarizable_region
);
2403 access
= (struct access
*) pool_alloc (access_pool
);
2404 memset (access
, 0, sizeof (struct access
));
2405 if (!build_user_friendly_ref_for_offset (&expr
, TREE_TYPE (expr
), new_offset
,
2408 access
->grp_no_warning
= true;
2409 expr
= build_ref_for_model (EXPR_LOCATION (parent
->base
), parent
->base
,
2410 new_offset
, model
, NULL
, false);
2413 access
->base
= parent
->base
;
2414 access
->expr
= expr
;
2415 access
->offset
= new_offset
;
2416 access
->size
= model
->size
;
2417 access
->type
= model
->type
;
2418 access
->grp_write
= true;
2419 access
->grp_read
= false;
2421 child
= &parent
->first_child
;
2422 while (*child
&& (*child
)->offset
< new_offset
)
2423 child
= &(*child
)->next_sibling
;
2425 access
->next_sibling
= *child
;
2432 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
2433 true if any new subaccess was created. Additionally, if RACC is a scalar
2434 access but LACC is not, change the type of the latter, if possible. */
2437 propagate_subaccesses_across_link (struct access
*lacc
, struct access
*racc
)
2439 struct access
*rchild
;
2440 HOST_WIDE_INT norm_delta
= lacc
->offset
- racc
->offset
;
2443 if (is_gimple_reg_type (lacc
->type
)
2444 || lacc
->grp_unscalarizable_region
2445 || racc
->grp_unscalarizable_region
)
2448 if (is_gimple_reg_type (racc
->type
))
2450 if (!lacc
->first_child
&& !racc
->first_child
)
2452 tree t
= lacc
->base
;
2454 lacc
->type
= racc
->type
;
2455 if (build_user_friendly_ref_for_offset (&t
, TREE_TYPE (t
),
2456 lacc
->offset
, racc
->type
))
2460 lacc
->expr
= build_ref_for_model (EXPR_LOCATION (lacc
->base
),
2461 lacc
->base
, lacc
->offset
,
2463 lacc
->grp_no_warning
= true;
2469 for (rchild
= racc
->first_child
; rchild
; rchild
= rchild
->next_sibling
)
2471 struct access
*new_acc
= NULL
;
2472 HOST_WIDE_INT norm_offset
= rchild
->offset
+ norm_delta
;
2474 if (rchild
->grp_unscalarizable_region
)
2477 if (child_would_conflict_in_lacc (lacc
, norm_offset
, rchild
->size
,
2482 rchild
->grp_hint
= 1;
2483 new_acc
->grp_hint
|= new_acc
->grp_read
;
2484 if (rchild
->first_child
)
2485 ret
|= propagate_subaccesses_across_link (new_acc
, rchild
);
2490 rchild
->grp_hint
= 1;
2491 new_acc
= create_artificial_child_access (lacc
, rchild
, norm_offset
);
2495 if (racc
->first_child
)
2496 propagate_subaccesses_across_link (new_acc
, rchild
);
2503 /* Propagate all subaccesses across assignment links. */
2506 propagate_all_subaccesses (void)
2508 while (work_queue_head
)
2510 struct access
*racc
= pop_access_from_work_queue ();
2511 struct assign_link
*link
;
2513 gcc_assert (racc
->first_link
);
2515 for (link
= racc
->first_link
; link
; link
= link
->next
)
2517 struct access
*lacc
= link
->lacc
;
2519 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (lacc
->base
)))
2521 lacc
= lacc
->group_representative
;
2522 if (propagate_subaccesses_across_link (lacc
, racc
)
2523 && lacc
->first_link
)
2524 add_access_to_work_queue (lacc
);
2529 /* Go through all accesses collected throughout the (intraprocedural) analysis
2530 stage, exclude overlapping ones, identify representatives and build trees
2531 out of them, making decisions about scalarization on the way. Return true
2532 iff there are any to-be-scalarized variables after this stage. */
2535 analyze_all_variable_accesses (void)
2538 bitmap tmp
= BITMAP_ALLOC (NULL
);
2541 unsigned max_scalarization_size
2542 = (optimize_function_for_size_p (cfun
)
2543 ? PARAM_VALUE (PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE
)
2544 : PARAM_VALUE (PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED
))
2547 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap
, 0, i
, bi
)
2548 if (bitmap_bit_p (should_scalarize_away_bitmap
, i
)
2549 && !bitmap_bit_p (cannot_scalarize_away_bitmap
, i
))
2551 tree var
= candidate (i
);
2553 if (TREE_CODE (var
) == VAR_DECL
2554 && type_consists_of_records_p (TREE_TYPE (var
)))
2556 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var
)))
2557 <= max_scalarization_size
)
2559 completely_scalarize_var (var
);
2560 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2562 fprintf (dump_file
, "Will attempt to totally scalarize ");
2563 print_generic_expr (dump_file
, var
, 0);
2564 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (var
));
2567 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2569 fprintf (dump_file
, "Too big to totally scalarize: ");
2570 print_generic_expr (dump_file
, var
, 0);
2571 fprintf (dump_file
, " (UID: %u)\n", DECL_UID (var
));
2576 bitmap_copy (tmp
, candidate_bitmap
);
2577 EXECUTE_IF_SET_IN_BITMAP (tmp
, 0, i
, bi
)
2579 tree var
= candidate (i
);
2580 struct access
*access
;
2582 access
= sort_and_splice_var_accesses (var
);
2583 if (!access
|| !build_access_trees (access
))
2584 disqualify_candidate (var
,
2585 "No or inhibitingly overlapping accesses.");
2588 propagate_all_subaccesses ();
2590 bitmap_copy (tmp
, candidate_bitmap
);
2591 EXECUTE_IF_SET_IN_BITMAP (tmp
, 0, i
, bi
)
2593 tree var
= candidate (i
);
2594 struct access
*access
= get_first_repr_for_decl (var
);
2596 if (analyze_access_trees (access
))
2599 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2601 fprintf (dump_file
, "\nAccess trees for ");
2602 print_generic_expr (dump_file
, var
, 0);
2603 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (var
));
2604 dump_access_tree (dump_file
, access
);
2605 fprintf (dump_file
, "\n");
2609 disqualify_candidate (var
, "No scalar replacements to be created.");
2616 statistics_counter_event (cfun
, "Scalarized aggregates", res
);
2623 /* Generate statements copying scalar replacements of accesses within a subtree
2624 into or out of AGG. ACCESS, all its children, siblings and their children
2625 are to be processed. AGG is an aggregate type expression (can be a
2626 declaration but does not have to be, it can for example also be a mem_ref or
2627 a series of handled components). TOP_OFFSET is the offset of the processed
2628 subtree which has to be subtracted from offsets of individual accesses to
2629 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2630 replacements in the interval <start_offset, start_offset + chunk_size>,
2631 otherwise copy all. GSI is a statement iterator used to place the new
2632 statements. WRITE should be true when the statements should write from AGG
2633 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2634 statements will be added after the current statement in GSI, they will be
2635 added before the statement otherwise. */
2638 generate_subtree_copies (struct access
*access
, tree agg
,
2639 HOST_WIDE_INT top_offset
,
2640 HOST_WIDE_INT start_offset
, HOST_WIDE_INT chunk_size
,
2641 gimple_stmt_iterator
*gsi
, bool write
,
2642 bool insert_after
, location_t loc
)
2646 if (chunk_size
&& access
->offset
>= start_offset
+ chunk_size
)
2649 if (access
->grp_to_be_replaced
2651 || access
->offset
+ access
->size
> start_offset
))
2653 tree expr
, repl
= get_access_replacement (access
);
2656 expr
= build_ref_for_model (loc
, agg
, access
->offset
- top_offset
,
2657 access
, gsi
, insert_after
);
2661 if (access
->grp_partial_lhs
)
2662 expr
= force_gimple_operand_gsi (gsi
, expr
, true, NULL_TREE
,
2664 insert_after
? GSI_NEW_STMT
2666 stmt
= gimple_build_assign (repl
, expr
);
2670 TREE_NO_WARNING (repl
) = 1;
2671 if (access
->grp_partial_lhs
)
2672 repl
= force_gimple_operand_gsi (gsi
, repl
, true, NULL_TREE
,
2674 insert_after
? GSI_NEW_STMT
2676 stmt
= gimple_build_assign (expr
, repl
);
2678 gimple_set_location (stmt
, loc
);
2681 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2683 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2685 sra_stats
.subtree_copies
++;
2688 && access
->grp_to_be_debug_replaced
2690 || access
->offset
+ access
->size
> start_offset
))
2693 tree drhs
= build_debug_ref_for_model (loc
, agg
,
2694 access
->offset
- top_offset
,
2696 ds
= gimple_build_debug_bind (get_access_replacement (access
),
2697 drhs
, gsi_stmt (*gsi
));
2699 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2701 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
2704 if (access
->first_child
)
2705 generate_subtree_copies (access
->first_child
, agg
, top_offset
,
2706 start_offset
, chunk_size
, gsi
,
2707 write
, insert_after
, loc
);
2709 access
= access
->next_sibling
;
2714 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2715 the root of the subtree to be processed. GSI is the statement iterator used
2716 for inserting statements which are added after the current statement if
2717 INSERT_AFTER is true or before it otherwise. */
2720 init_subtree_with_zero (struct access
*access
, gimple_stmt_iterator
*gsi
,
2721 bool insert_after
, location_t loc
)
2724 struct access
*child
;
2726 if (access
->grp_to_be_replaced
)
2730 stmt
= gimple_build_assign (get_access_replacement (access
),
2731 build_zero_cst (access
->type
));
2733 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2735 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2737 gimple_set_location (stmt
, loc
);
2739 else if (access
->grp_to_be_debug_replaced
)
2742 = gimple_build_debug_bind (get_access_replacement (access
),
2743 build_zero_cst (access
->type
),
2746 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2748 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
2751 for (child
= access
->first_child
; child
; child
= child
->next_sibling
)
2752 init_subtree_with_zero (child
, gsi
, insert_after
, loc
);
2755 /* Clobber all scalar replacements in an access subtree. ACCESS is the the
2756 root of the subtree to be processed. GSI is the statement iterator used
2757 for inserting statements which are added after the current statement if
2758 INSERT_AFTER is true or before it otherwise. */
2761 clobber_subtree (struct access
*access
, gimple_stmt_iterator
*gsi
,
2762 bool insert_after
, location_t loc
)
2765 struct access
*child
;
2767 if (access
->grp_to_be_replaced
)
2769 tree rep
= get_access_replacement (access
);
2770 tree clobber
= build_constructor (access
->type
, NULL
);
2771 TREE_THIS_VOLATILE (clobber
) = 1;
2772 gimple stmt
= gimple_build_assign (rep
, clobber
);
2775 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2777 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2779 gimple_set_location (stmt
, loc
);
2782 for (child
= access
->first_child
; child
; child
= child
->next_sibling
)
2783 clobber_subtree (child
, gsi
, insert_after
, loc
);
2786 /* Search for an access representative for the given expression EXPR and
2787 return it or NULL if it cannot be found. */
2789 static struct access
*
2790 get_access_for_expr (tree expr
)
2792 HOST_WIDE_INT offset
, size
, max_size
;
2795 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2796 a different size than the size of its argument and we need the latter
2798 if (TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
2799 expr
= TREE_OPERAND (expr
, 0);
2801 base
= get_ref_base_and_extent (expr
, &offset
, &size
, &max_size
);
2802 if (max_size
== -1 || !DECL_P (base
))
2805 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (base
)))
2808 return get_var_base_offset_size_access (base
, offset
, max_size
);
2811 /* Replace the expression EXPR with a scalar replacement if there is one and
2812 generate other statements to do type conversion or subtree copying if
2813 necessary. GSI is used to place newly created statements, WRITE is true if
2814 the expression is being written to (it is on a LHS of a statement or output
2815 in an assembly statement). */
2818 sra_modify_expr (tree
*expr
, gimple_stmt_iterator
*gsi
, bool write
)
2821 struct access
*access
;
2822 tree type
, bfr
, orig_expr
;
2824 if (TREE_CODE (*expr
) == BIT_FIELD_REF
)
2827 expr
= &TREE_OPERAND (*expr
, 0);
2832 if (TREE_CODE (*expr
) == REALPART_EXPR
|| TREE_CODE (*expr
) == IMAGPART_EXPR
)
2833 expr
= &TREE_OPERAND (*expr
, 0);
2834 access
= get_access_for_expr (*expr
);
2837 type
= TREE_TYPE (*expr
);
2840 loc
= gimple_location (gsi_stmt (*gsi
));
2841 gimple_stmt_iterator alt_gsi
= gsi_none ();
2842 if (write
&& stmt_ends_bb_p (gsi_stmt (*gsi
)))
2844 alt_gsi
= gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi
)));
2848 if (access
->grp_to_be_replaced
)
2850 tree repl
= get_access_replacement (access
);
2851 /* If we replace a non-register typed access simply use the original
2852 access expression to extract the scalar component afterwards.
2853 This happens if scalarizing a function return value or parameter
2854 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2855 gcc.c-torture/compile/20011217-1.c.
2857 We also want to use this when accessing a complex or vector which can
2858 be accessed as a different type too, potentially creating a need for
2859 type conversion (see PR42196) and when scalarized unions are involved
2860 in assembler statements (see PR42398). */
2861 if (!useless_type_conversion_p (type
, access
->type
))
2865 ref
= build_ref_for_model (loc
, orig_expr
, 0, access
, gsi
, false);
2871 if (access
->grp_partial_lhs
)
2872 ref
= force_gimple_operand_gsi (gsi
, ref
, true, NULL_TREE
,
2873 false, GSI_NEW_STMT
);
2874 stmt
= gimple_build_assign (repl
, ref
);
2875 gimple_set_location (stmt
, loc
);
2876 gsi_insert_after (gsi
, stmt
, GSI_NEW_STMT
);
2882 if (access
->grp_partial_lhs
)
2883 repl
= force_gimple_operand_gsi (gsi
, repl
, true, NULL_TREE
,
2884 true, GSI_SAME_STMT
);
2885 stmt
= gimple_build_assign (ref
, repl
);
2886 gimple_set_location (stmt
, loc
);
2887 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
2894 else if (write
&& access
->grp_to_be_debug_replaced
)
2896 gdebug
*ds
= gimple_build_debug_bind (get_access_replacement (access
),
2899 gsi_insert_after (gsi
, ds
, GSI_NEW_STMT
);
2902 if (access
->first_child
)
2904 HOST_WIDE_INT start_offset
, chunk_size
;
2906 && tree_fits_uhwi_p (TREE_OPERAND (bfr
, 1))
2907 && tree_fits_uhwi_p (TREE_OPERAND (bfr
, 2)))
2909 chunk_size
= tree_to_uhwi (TREE_OPERAND (bfr
, 1));
2910 start_offset
= access
->offset
2911 + tree_to_uhwi (TREE_OPERAND (bfr
, 2));
2914 start_offset
= chunk_size
= 0;
2916 generate_subtree_copies (access
->first_child
, orig_expr
, access
->offset
,
2917 start_offset
, chunk_size
, gsi
, write
, write
,
2923 /* Where scalar replacements of the RHS have been written to when a replacement
2924 of a LHS of an assigments cannot be direclty loaded from a replacement of
2926 enum unscalarized_data_handling
{ SRA_UDH_NONE
, /* Nothing done so far. */
2927 SRA_UDH_RIGHT
, /* Data flushed to the RHS. */
2928 SRA_UDH_LEFT
}; /* Data flushed to the LHS. */
2930 struct subreplacement_assignment_data
2932 /* Offset of the access representing the lhs of the assignment. */
2933 HOST_WIDE_INT left_offset
;
2935 /* LHS and RHS of the original assignment. */
2936 tree assignment_lhs
, assignment_rhs
;
2938 /* Access representing the rhs of the whole assignment. */
2939 struct access
*top_racc
;
2941 /* Stmt iterator used for statement insertions after the original assignment.
2942 It points to the main GSI used to traverse a BB during function body
2944 gimple_stmt_iterator
*new_gsi
;
2946 /* Stmt iterator used for statement insertions before the original
2947 assignment. Keeps on pointing to the original statement. */
2948 gimple_stmt_iterator old_gsi
;
2950 /* Location of the assignment. */
2953 /* Keeps the information whether we have needed to refresh replacements of
2954 the LHS and from which side of the assignments this takes place. */
2955 enum unscalarized_data_handling refreshed
;
2958 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2959 base aggregate if there are unscalarized data or directly to LHS of the
2960 statement that is pointed to by GSI otherwise. */
2963 handle_unscalarized_data_in_subtree (struct subreplacement_assignment_data
*sad
)
2966 if (sad
->top_racc
->grp_unscalarized_data
)
2968 src
= sad
->assignment_rhs
;
2969 sad
->refreshed
= SRA_UDH_RIGHT
;
2973 src
= sad
->assignment_lhs
;
2974 sad
->refreshed
= SRA_UDH_LEFT
;
2976 generate_subtree_copies (sad
->top_racc
->first_child
, src
,
2977 sad
->top_racc
->offset
, 0, 0,
2978 &sad
->old_gsi
, false, false, sad
->loc
);
2981 /* Try to generate statements to load all sub-replacements in an access subtree
2982 formed by children of LACC from scalar replacements in the SAD->top_racc
2983 subtree. If that is not possible, refresh the SAD->top_racc base aggregate
2984 and load the accesses from it. */
2987 load_assign_lhs_subreplacements (struct access
*lacc
,
2988 struct subreplacement_assignment_data
*sad
)
2990 for (lacc
= lacc
->first_child
; lacc
; lacc
= lacc
->next_sibling
)
2992 HOST_WIDE_INT offset
;
2993 offset
= lacc
->offset
- sad
->left_offset
+ sad
->top_racc
->offset
;
2995 if (lacc
->grp_to_be_replaced
)
2997 struct access
*racc
;
3001 racc
= find_access_in_subtree (sad
->top_racc
, offset
, lacc
->size
);
3002 if (racc
&& racc
->grp_to_be_replaced
)
3004 rhs
= get_access_replacement (racc
);
3005 if (!useless_type_conversion_p (lacc
->type
, racc
->type
))
3006 rhs
= fold_build1_loc (sad
->loc
, VIEW_CONVERT_EXPR
,
3009 if (racc
->grp_partial_lhs
&& lacc
->grp_partial_lhs
)
3010 rhs
= force_gimple_operand_gsi (&sad
->old_gsi
, rhs
, true,
3011 NULL_TREE
, true, GSI_SAME_STMT
);
3015 /* No suitable access on the right hand side, need to load from
3016 the aggregate. See if we have to update it first... */
3017 if (sad
->refreshed
== SRA_UDH_NONE
)
3018 handle_unscalarized_data_in_subtree (sad
);
3020 if (sad
->refreshed
== SRA_UDH_LEFT
)
3021 rhs
= build_ref_for_model (sad
->loc
, sad
->assignment_lhs
,
3022 lacc
->offset
- sad
->left_offset
,
3023 lacc
, sad
->new_gsi
, true);
3025 rhs
= build_ref_for_model (sad
->loc
, sad
->assignment_rhs
,
3026 lacc
->offset
- sad
->left_offset
,
3027 lacc
, sad
->new_gsi
, true);
3028 if (lacc
->grp_partial_lhs
)
3029 rhs
= force_gimple_operand_gsi (sad
->new_gsi
,
3030 rhs
, true, NULL_TREE
,
3031 false, GSI_NEW_STMT
);
3034 stmt
= gimple_build_assign (get_access_replacement (lacc
), rhs
);
3035 gsi_insert_after (sad
->new_gsi
, stmt
, GSI_NEW_STMT
);
3036 gimple_set_location (stmt
, sad
->loc
);
3038 sra_stats
.subreplacements
++;
3042 if (sad
->refreshed
== SRA_UDH_NONE
3043 && lacc
->grp_read
&& !lacc
->grp_covered
)
3044 handle_unscalarized_data_in_subtree (sad
);
3046 if (lacc
&& lacc
->grp_to_be_debug_replaced
)
3050 struct access
*racc
= find_access_in_subtree (sad
->top_racc
,
3054 if (racc
&& racc
->grp_to_be_replaced
)
3056 if (racc
->grp_write
)
3057 drhs
= get_access_replacement (racc
);
3061 else if (sad
->refreshed
== SRA_UDH_LEFT
)
3062 drhs
= build_debug_ref_for_model (sad
->loc
, lacc
->base
,
3063 lacc
->offset
, lacc
);
3064 else if (sad
->refreshed
== SRA_UDH_RIGHT
)
3065 drhs
= build_debug_ref_for_model (sad
->loc
, sad
->top_racc
->base
,
3070 && !useless_type_conversion_p (lacc
->type
, TREE_TYPE (drhs
)))
3071 drhs
= fold_build1_loc (sad
->loc
, VIEW_CONVERT_EXPR
,
3073 ds
= gimple_build_debug_bind (get_access_replacement (lacc
),
3074 drhs
, gsi_stmt (sad
->old_gsi
));
3075 gsi_insert_after (sad
->new_gsi
, ds
, GSI_NEW_STMT
);
3079 if (lacc
->first_child
)
3080 load_assign_lhs_subreplacements (lacc
, sad
);
3084 /* Result code for SRA assignment modification. */
3085 enum assignment_mod_result
{ SRA_AM_NONE
, /* nothing done for the stmt */
3086 SRA_AM_MODIFIED
, /* stmt changed but not
3088 SRA_AM_REMOVED
}; /* stmt eliminated */
3090 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
3091 to the assignment and GSI is the statement iterator pointing at it. Returns
3092 the same values as sra_modify_assign. */
3094 static enum assignment_mod_result
3095 sra_modify_constructor_assign (gimple stmt
, gimple_stmt_iterator
*gsi
)
3097 tree lhs
= gimple_assign_lhs (stmt
);
3098 struct access
*acc
= get_access_for_expr (lhs
);
3101 location_t loc
= gimple_location (stmt
);
3103 if (gimple_clobber_p (stmt
))
3105 /* Clobber the replacement variable. */
3106 clobber_subtree (acc
, gsi
, !acc
->grp_covered
, loc
);
3107 /* Remove clobbers of fully scalarized variables, they are dead. */
3108 if (acc
->grp_covered
)
3110 unlink_stmt_vdef (stmt
);
3111 gsi_remove (gsi
, true);
3112 release_defs (stmt
);
3113 return SRA_AM_REMOVED
;
3116 return SRA_AM_MODIFIED
;
3119 if (vec_safe_length (CONSTRUCTOR_ELTS (gimple_assign_rhs1 (stmt
))) > 0)
3121 /* I have never seen this code path trigger but if it can happen the
3122 following should handle it gracefully. */
3123 if (access_has_children_p (acc
))
3124 generate_subtree_copies (acc
->first_child
, lhs
, acc
->offset
, 0, 0, gsi
,
3126 return SRA_AM_MODIFIED
;
3129 if (acc
->grp_covered
)
3131 init_subtree_with_zero (acc
, gsi
, false, loc
);
3132 unlink_stmt_vdef (stmt
);
3133 gsi_remove (gsi
, true);
3134 release_defs (stmt
);
3135 return SRA_AM_REMOVED
;
3139 init_subtree_with_zero (acc
, gsi
, true, loc
);
3140 return SRA_AM_MODIFIED
;
3144 /* Create and return a new suitable default definition SSA_NAME for RACC which
3145 is an access describing an uninitialized part of an aggregate that is being
3149 get_repl_default_def_ssa_name (struct access
*racc
)
3151 gcc_checking_assert (!racc
->grp_to_be_replaced
3152 && !racc
->grp_to_be_debug_replaced
);
3153 if (!racc
->replacement_decl
)
3154 racc
->replacement_decl
= create_access_replacement (racc
);
3155 return get_or_create_ssa_default_def (cfun
, racc
->replacement_decl
);
3158 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3159 bit-field field declaration somewhere in it. */
3162 contains_vce_or_bfcref_p (const_tree ref
)
3164 while (handled_component_p (ref
))
3166 if (TREE_CODE (ref
) == VIEW_CONVERT_EXPR
3167 || (TREE_CODE (ref
) == COMPONENT_REF
3168 && DECL_BIT_FIELD (TREE_OPERAND (ref
, 1))))
3170 ref
= TREE_OPERAND (ref
, 0);
3176 /* Examine both sides of the assignment statement pointed to by STMT, replace
3177 them with a scalare replacement if there is one and generate copying of
3178 replacements if scalarized aggregates have been used in the assignment. GSI
3179 is used to hold generated statements for type conversions and subtree
3182 static enum assignment_mod_result
3183 sra_modify_assign (gimple stmt
, gimple_stmt_iterator
*gsi
)
3185 struct access
*lacc
, *racc
;
3187 bool modify_this_stmt
= false;
3188 bool force_gimple_rhs
= false;
3190 gimple_stmt_iterator orig_gsi
= *gsi
;
3192 if (!gimple_assign_single_p (stmt
))
3194 lhs
= gimple_assign_lhs (stmt
);
3195 rhs
= gimple_assign_rhs1 (stmt
);
3197 if (TREE_CODE (rhs
) == CONSTRUCTOR
)
3198 return sra_modify_constructor_assign (stmt
, gsi
);
3200 if (TREE_CODE (rhs
) == REALPART_EXPR
|| TREE_CODE (lhs
) == REALPART_EXPR
3201 || TREE_CODE (rhs
) == IMAGPART_EXPR
|| TREE_CODE (lhs
) == IMAGPART_EXPR
3202 || TREE_CODE (rhs
) == BIT_FIELD_REF
|| TREE_CODE (lhs
) == BIT_FIELD_REF
)
3204 modify_this_stmt
= sra_modify_expr (gimple_assign_rhs1_ptr (stmt
),
3206 modify_this_stmt
|= sra_modify_expr (gimple_assign_lhs_ptr (stmt
),
3208 return modify_this_stmt
? SRA_AM_MODIFIED
: SRA_AM_NONE
;
3211 lacc
= get_access_for_expr (lhs
);
3212 racc
= get_access_for_expr (rhs
);
3216 loc
= gimple_location (stmt
);
3217 if (lacc
&& lacc
->grp_to_be_replaced
)
3219 lhs
= get_access_replacement (lacc
);
3220 gimple_assign_set_lhs (stmt
, lhs
);
3221 modify_this_stmt
= true;
3222 if (lacc
->grp_partial_lhs
)
3223 force_gimple_rhs
= true;
3227 if (racc
&& racc
->grp_to_be_replaced
)
3229 rhs
= get_access_replacement (racc
);
3230 modify_this_stmt
= true;
3231 if (racc
->grp_partial_lhs
)
3232 force_gimple_rhs
= true;
3236 && !racc
->grp_unscalarized_data
3237 && TREE_CODE (lhs
) == SSA_NAME
3238 && !access_has_replacements_p (racc
))
3240 rhs
= get_repl_default_def_ssa_name (racc
);
3241 modify_this_stmt
= true;
3245 if (modify_this_stmt
)
3247 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
3249 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3250 ??? This should move to fold_stmt which we simply should
3251 call after building a VIEW_CONVERT_EXPR here. */
3252 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs
))
3253 && !contains_bitfld_component_ref_p (lhs
))
3255 lhs
= build_ref_for_model (loc
, lhs
, 0, racc
, gsi
, false);
3256 gimple_assign_set_lhs (stmt
, lhs
);
3258 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs
))
3259 && !contains_vce_or_bfcref_p (rhs
))
3260 rhs
= build_ref_for_model (loc
, rhs
, 0, lacc
, gsi
, false);
3262 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
3264 rhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, TREE_TYPE (lhs
),
3266 if (is_gimple_reg_type (TREE_TYPE (lhs
))
3267 && TREE_CODE (lhs
) != SSA_NAME
)
3268 force_gimple_rhs
= true;
3273 if (lacc
&& lacc
->grp_to_be_debug_replaced
)
3275 tree dlhs
= get_access_replacement (lacc
);
3276 tree drhs
= unshare_expr (rhs
);
3277 if (!useless_type_conversion_p (TREE_TYPE (dlhs
), TREE_TYPE (drhs
)))
3279 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs
))
3280 && !contains_vce_or_bfcref_p (drhs
))
3281 drhs
= build_debug_ref_for_model (loc
, drhs
, 0, lacc
);
3283 && !useless_type_conversion_p (TREE_TYPE (dlhs
),
3285 drhs
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
,
3286 TREE_TYPE (dlhs
), drhs
);
3288 gdebug
*ds
= gimple_build_debug_bind (dlhs
, drhs
, stmt
);
3289 gsi_insert_before (gsi
, ds
, GSI_SAME_STMT
);
3292 /* From this point on, the function deals with assignments in between
3293 aggregates when at least one has scalar reductions of some of its
3294 components. There are three possible scenarios: Both the LHS and RHS have
3295 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3297 In the first case, we would like to load the LHS components from RHS
3298 components whenever possible. If that is not possible, we would like to
3299 read it directly from the RHS (after updating it by storing in it its own
3300 components). If there are some necessary unscalarized data in the LHS,
3301 those will be loaded by the original assignment too. If neither of these
3302 cases happen, the original statement can be removed. Most of this is done
3303 by load_assign_lhs_subreplacements.
3305 In the second case, we would like to store all RHS scalarized components
3306 directly into LHS and if they cover the aggregate completely, remove the
3307 statement too. In the third case, we want the LHS components to be loaded
3308 directly from the RHS (DSE will remove the original statement if it
3311 This is a bit complex but manageable when types match and when unions do
3312 not cause confusion in a way that we cannot really load a component of LHS
3313 from the RHS or vice versa (the access representing this level can have
3314 subaccesses that are accessible only through a different union field at a
3315 higher level - different from the one used in the examined expression).
3318 Therefore, I specially handle a fourth case, happening when there is a
3319 specific type cast or it is impossible to locate a scalarized subaccess on
3320 the other side of the expression. If that happens, I simply "refresh" the
3321 RHS by storing in it is scalarized components leave the original statement
3322 there to do the copying and then load the scalar replacements of the LHS.
3323 This is what the first branch does. */
3325 if (modify_this_stmt
3326 || gimple_has_volatile_ops (stmt
)
3327 || contains_vce_or_bfcref_p (rhs
)
3328 || contains_vce_or_bfcref_p (lhs
)
3329 || stmt_ends_bb_p (stmt
))
3331 if (access_has_children_p (racc
))
3332 generate_subtree_copies (racc
->first_child
, rhs
, racc
->offset
, 0, 0,
3333 gsi
, false, false, loc
);
3334 if (access_has_children_p (lacc
))
3336 gimple_stmt_iterator alt_gsi
= gsi_none ();
3337 if (stmt_ends_bb_p (stmt
))
3339 alt_gsi
= gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi
)));
3342 generate_subtree_copies (lacc
->first_child
, lhs
, lacc
->offset
, 0, 0,
3343 gsi
, true, true, loc
);
3345 sra_stats
.separate_lhs_rhs_handling
++;
3347 /* This gimplification must be done after generate_subtree_copies,
3348 lest we insert the subtree copies in the middle of the gimplified
3350 if (force_gimple_rhs
)
3351 rhs
= force_gimple_operand_gsi (&orig_gsi
, rhs
, true, NULL_TREE
,
3352 true, GSI_SAME_STMT
);
3353 if (gimple_assign_rhs1 (stmt
) != rhs
)
3355 modify_this_stmt
= true;
3356 gimple_assign_set_rhs_from_tree (&orig_gsi
, rhs
);
3357 gcc_assert (stmt
== gsi_stmt (orig_gsi
));
3360 return modify_this_stmt
? SRA_AM_MODIFIED
: SRA_AM_NONE
;
3364 if (access_has_children_p (lacc
)
3365 && access_has_children_p (racc
)
3366 /* When an access represents an unscalarizable region, it usually
3367 represents accesses with variable offset and thus must not be used
3368 to generate new memory accesses. */
3369 && !lacc
->grp_unscalarizable_region
3370 && !racc
->grp_unscalarizable_region
)
3372 struct subreplacement_assignment_data sad
;
3374 sad
.left_offset
= lacc
->offset
;
3375 sad
.assignment_lhs
= lhs
;
3376 sad
.assignment_rhs
= rhs
;
3377 sad
.top_racc
= racc
;
3380 sad
.loc
= gimple_location (stmt
);
3381 sad
.refreshed
= SRA_UDH_NONE
;
3383 if (lacc
->grp_read
&& !lacc
->grp_covered
)
3384 handle_unscalarized_data_in_subtree (&sad
);
3386 load_assign_lhs_subreplacements (lacc
, &sad
);
3387 if (sad
.refreshed
!= SRA_UDH_RIGHT
)
3390 unlink_stmt_vdef (stmt
);
3391 gsi_remove (&sad
.old_gsi
, true);
3392 release_defs (stmt
);
3393 sra_stats
.deleted
++;
3394 return SRA_AM_REMOVED
;
3399 if (access_has_children_p (racc
)
3400 && !racc
->grp_unscalarized_data
)
3404 fprintf (dump_file
, "Removing load: ");
3405 print_gimple_stmt (dump_file
, stmt
, 0, 0);
3407 generate_subtree_copies (racc
->first_child
, lhs
,
3408 racc
->offset
, 0, 0, gsi
,
3410 gcc_assert (stmt
== gsi_stmt (*gsi
));
3411 unlink_stmt_vdef (stmt
);
3412 gsi_remove (gsi
, true);
3413 release_defs (stmt
);
3414 sra_stats
.deleted
++;
3415 return SRA_AM_REMOVED
;
3417 /* Restore the aggregate RHS from its components so the
3418 prevailing aggregate copy does the right thing. */
3419 if (access_has_children_p (racc
))
3420 generate_subtree_copies (racc
->first_child
, rhs
, racc
->offset
, 0, 0,
3421 gsi
, false, false, loc
);
3422 /* Re-load the components of the aggregate copy destination.
3423 But use the RHS aggregate to load from to expose more
3424 optimization opportunities. */
3425 if (access_has_children_p (lacc
))
3426 generate_subtree_copies (lacc
->first_child
, rhs
, lacc
->offset
,
3427 0, 0, gsi
, true, true, loc
);
3434 /* Traverse the function body and all modifications as decided in
3435 analyze_all_variable_accesses. Return true iff the CFG has been
3439 sra_modify_function_body (void)
3441 bool cfg_changed
= false;
3444 FOR_EACH_BB_FN (bb
, cfun
)
3446 gimple_stmt_iterator gsi
= gsi_start_bb (bb
);
3447 while (!gsi_end_p (gsi
))
3449 gimple stmt
= gsi_stmt (gsi
);
3450 enum assignment_mod_result assign_result
;
3451 bool modified
= false, deleted
= false;
3455 switch (gimple_code (stmt
))
3458 t
= gimple_return_retval_ptr (as_a
<greturn
*> (stmt
));
3459 if (*t
!= NULL_TREE
)
3460 modified
|= sra_modify_expr (t
, &gsi
, false);
3464 assign_result
= sra_modify_assign (stmt
, &gsi
);
3465 modified
|= assign_result
== SRA_AM_MODIFIED
;
3466 deleted
= assign_result
== SRA_AM_REMOVED
;
3470 /* Operands must be processed before the lhs. */
3471 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
3473 t
= gimple_call_arg_ptr (stmt
, i
);
3474 modified
|= sra_modify_expr (t
, &gsi
, false);
3477 if (gimple_call_lhs (stmt
))
3479 t
= gimple_call_lhs_ptr (stmt
);
3480 modified
|= sra_modify_expr (t
, &gsi
, true);
3486 gasm
*asm_stmt
= as_a
<gasm
*> (stmt
);
3487 for (i
= 0; i
< gimple_asm_ninputs (asm_stmt
); i
++)
3489 t
= &TREE_VALUE (gimple_asm_input_op (asm_stmt
, i
));
3490 modified
|= sra_modify_expr (t
, &gsi
, false);
3492 for (i
= 0; i
< gimple_asm_noutputs (asm_stmt
); i
++)
3494 t
= &TREE_VALUE (gimple_asm_output_op (asm_stmt
, i
));
3495 modified
|= sra_modify_expr (t
, &gsi
, true);
3507 if (maybe_clean_eh_stmt (stmt
)
3508 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
3516 gsi_commit_edge_inserts ();
3520 /* Generate statements initializing scalar replacements of parts of function
3524 initialize_parameter_reductions (void)
3526 gimple_stmt_iterator gsi
;
3527 gimple_seq seq
= NULL
;
3530 gsi
= gsi_start (seq
);
3531 for (parm
= DECL_ARGUMENTS (current_function_decl
);
3533 parm
= DECL_CHAIN (parm
))
3535 vec
<access_p
> *access_vec
;
3536 struct access
*access
;
3538 if (!bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
3540 access_vec
= get_base_access_vector (parm
);
3544 for (access
= (*access_vec
)[0];
3546 access
= access
->next_grp
)
3547 generate_subtree_copies (access
, parm
, 0, 0, 0, &gsi
, true, true,
3548 EXPR_LOCATION (parm
));
3551 seq
= gsi_seq (gsi
);
3553 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun
)), seq
);
3556 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3557 it reveals there are components of some aggregates to be scalarized, it runs
3558 the required transformations. */
3560 perform_intra_sra (void)
3565 if (!find_var_candidates ())
3568 if (!scan_function ())
3571 if (!analyze_all_variable_accesses ())
3574 if (sra_modify_function_body ())
3575 ret
= TODO_update_ssa
| TODO_cleanup_cfg
;
3577 ret
= TODO_update_ssa
;
3578 initialize_parameter_reductions ();
3580 statistics_counter_event (cfun
, "Scalar replacements created",
3581 sra_stats
.replacements
);
3582 statistics_counter_event (cfun
, "Modified expressions", sra_stats
.exprs
);
3583 statistics_counter_event (cfun
, "Subtree copy stmts",
3584 sra_stats
.subtree_copies
);
3585 statistics_counter_event (cfun
, "Subreplacement stmts",
3586 sra_stats
.subreplacements
);
3587 statistics_counter_event (cfun
, "Deleted stmts", sra_stats
.deleted
);
3588 statistics_counter_event (cfun
, "Separate LHS and RHS handling",
3589 sra_stats
.separate_lhs_rhs_handling
);
3592 sra_deinitialize ();
3596 /* Perform early intraprocedural SRA. */
3598 early_intra_sra (void)
3600 sra_mode
= SRA_MODE_EARLY_INTRA
;
3601 return perform_intra_sra ();
3604 /* Perform "late" intraprocedural SRA. */
3606 late_intra_sra (void)
3608 sra_mode
= SRA_MODE_INTRA
;
3609 return perform_intra_sra ();
3614 gate_intra_sra (void)
3616 return flag_tree_sra
!= 0 && dbg_cnt (tree_sra
);
3622 const pass_data pass_data_sra_early
=
3624 GIMPLE_PASS
, /* type */
3626 OPTGROUP_NONE
, /* optinfo_flags */
3627 TV_TREE_SRA
, /* tv_id */
3628 ( PROP_cfg
| PROP_ssa
), /* properties_required */
3629 0, /* properties_provided */
3630 0, /* properties_destroyed */
3631 0, /* todo_flags_start */
3632 TODO_update_ssa
, /* todo_flags_finish */
3635 class pass_sra_early
: public gimple_opt_pass
3638 pass_sra_early (gcc::context
*ctxt
)
3639 : gimple_opt_pass (pass_data_sra_early
, ctxt
)
3642 /* opt_pass methods: */
3643 virtual bool gate (function
*) { return gate_intra_sra (); }
3644 virtual unsigned int execute (function
*) { return early_intra_sra (); }
3646 }; // class pass_sra_early
3651 make_pass_sra_early (gcc::context
*ctxt
)
3653 return new pass_sra_early (ctxt
);
3658 const pass_data pass_data_sra
=
3660 GIMPLE_PASS
, /* type */
3662 OPTGROUP_NONE
, /* optinfo_flags */
3663 TV_TREE_SRA
, /* tv_id */
3664 ( PROP_cfg
| PROP_ssa
), /* properties_required */
3665 0, /* properties_provided */
3666 0, /* properties_destroyed */
3667 TODO_update_address_taken
, /* todo_flags_start */
3668 TODO_update_ssa
, /* todo_flags_finish */
3671 class pass_sra
: public gimple_opt_pass
3674 pass_sra (gcc::context
*ctxt
)
3675 : gimple_opt_pass (pass_data_sra
, ctxt
)
3678 /* opt_pass methods: */
3679 virtual bool gate (function
*) { return gate_intra_sra (); }
3680 virtual unsigned int execute (function
*) { return late_intra_sra (); }
3682 }; // class pass_sra
3687 make_pass_sra (gcc::context
*ctxt
)
3689 return new pass_sra (ctxt
);
3693 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3697 is_unused_scalar_param (tree parm
)
3700 return (is_gimple_reg (parm
)
3701 && (!(name
= ssa_default_def (cfun
, parm
))
3702 || has_zero_uses (name
)));
3705 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3706 examine whether there are any direct or otherwise infeasible ones. If so,
3707 return true, otherwise return false. PARM must be a gimple register with a
3708 non-NULL default definition. */
3711 ptr_parm_has_direct_uses (tree parm
)
3713 imm_use_iterator ui
;
3715 tree name
= ssa_default_def (cfun
, parm
);
3718 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
3721 use_operand_p use_p
;
3723 if (is_gimple_debug (stmt
))
3726 /* Valid uses include dereferences on the lhs and the rhs. */
3727 if (gimple_has_lhs (stmt
))
3729 tree lhs
= gimple_get_lhs (stmt
);
3730 while (handled_component_p (lhs
))
3731 lhs
= TREE_OPERAND (lhs
, 0);
3732 if (TREE_CODE (lhs
) == MEM_REF
3733 && TREE_OPERAND (lhs
, 0) == name
3734 && integer_zerop (TREE_OPERAND (lhs
, 1))
3735 && types_compatible_p (TREE_TYPE (lhs
),
3736 TREE_TYPE (TREE_TYPE (name
)))
3737 && !TREE_THIS_VOLATILE (lhs
))
3740 if (gimple_assign_single_p (stmt
))
3742 tree rhs
= gimple_assign_rhs1 (stmt
);
3743 while (handled_component_p (rhs
))
3744 rhs
= TREE_OPERAND (rhs
, 0);
3745 if (TREE_CODE (rhs
) == MEM_REF
3746 && TREE_OPERAND (rhs
, 0) == name
3747 && integer_zerop (TREE_OPERAND (rhs
, 1))
3748 && types_compatible_p (TREE_TYPE (rhs
),
3749 TREE_TYPE (TREE_TYPE (name
)))
3750 && !TREE_THIS_VOLATILE (rhs
))
3753 else if (is_gimple_call (stmt
))
3756 for (i
= 0; i
< gimple_call_num_args (stmt
); ++i
)
3758 tree arg
= gimple_call_arg (stmt
, i
);
3759 while (handled_component_p (arg
))
3760 arg
= TREE_OPERAND (arg
, 0);
3761 if (TREE_CODE (arg
) == MEM_REF
3762 && TREE_OPERAND (arg
, 0) == name
3763 && integer_zerop (TREE_OPERAND (arg
, 1))
3764 && types_compatible_p (TREE_TYPE (arg
),
3765 TREE_TYPE (TREE_TYPE (name
)))
3766 && !TREE_THIS_VOLATILE (arg
))
3771 /* If the number of valid uses does not match the number of
3772 uses in this stmt there is an unhandled use. */
3773 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
3780 BREAK_FROM_IMM_USE_STMT (ui
);
3786 /* Identify candidates for reduction for IPA-SRA based on their type and mark
3787 them in candidate_bitmap. Note that these do not necessarily include
3788 parameter which are unused and thus can be removed. Return true iff any
3789 such candidate has been found. */
3792 find_param_candidates (void)
3799 for (parm
= DECL_ARGUMENTS (current_function_decl
);
3801 parm
= DECL_CHAIN (parm
))
3803 tree type
= TREE_TYPE (parm
);
3808 if (TREE_THIS_VOLATILE (parm
)
3809 || TREE_ADDRESSABLE (parm
)
3810 || (!is_gimple_reg_type (type
) && is_va_list_type (type
)))
3813 if (is_unused_scalar_param (parm
))
3819 if (POINTER_TYPE_P (type
))
3821 type
= TREE_TYPE (type
);
3823 if (TREE_CODE (type
) == FUNCTION_TYPE
3824 || TYPE_VOLATILE (type
)
3825 || (TREE_CODE (type
) == ARRAY_TYPE
3826 && TYPE_NONALIASED_COMPONENT (type
))
3827 || !is_gimple_reg (parm
)
3828 || is_va_list_type (type
)
3829 || ptr_parm_has_direct_uses (parm
))
3832 else if (!AGGREGATE_TYPE_P (type
))
3835 if (!COMPLETE_TYPE_P (type
)
3836 || !tree_fits_uhwi_p (TYPE_SIZE (type
))
3837 || tree_to_uhwi (TYPE_SIZE (type
)) == 0
3838 || (AGGREGATE_TYPE_P (type
)
3839 && type_internals_preclude_sra_p (type
, &msg
)))
3842 bitmap_set_bit (candidate_bitmap
, DECL_UID (parm
));
3843 slot
= candidates
->find_slot_with_hash (parm
, DECL_UID (parm
), INSERT
);
3847 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3849 fprintf (dump_file
, "Candidate (%d): ", DECL_UID (parm
));
3850 print_generic_expr (dump_file
, parm
, 0);
3851 fprintf (dump_file
, "\n");
3855 func_param_count
= count
;
3859 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
3863 mark_maybe_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef ATTRIBUTE_UNUSED
,
3866 struct access
*repr
= (struct access
*) data
;
3868 repr
->grp_maybe_modified
= 1;
3872 /* Analyze what representatives (in linked lists accessible from
3873 REPRESENTATIVES) can be modified by side effects of statements in the
3874 current function. */
3877 analyze_modified_params (vec
<access_p
> representatives
)
3881 for (i
= 0; i
< func_param_count
; i
++)
3883 struct access
*repr
;
3885 for (repr
= representatives
[i
];
3887 repr
= repr
->next_grp
)
3889 struct access
*access
;
3893 if (no_accesses_p (repr
))
3895 if (!POINTER_TYPE_P (TREE_TYPE (repr
->base
))
3896 || repr
->grp_maybe_modified
)
3899 ao_ref_init (&ar
, repr
->expr
);
3900 visited
= BITMAP_ALLOC (NULL
);
3901 for (access
= repr
; access
; access
= access
->next_sibling
)
3903 /* All accesses are read ones, otherwise grp_maybe_modified would
3904 be trivially set. */
3905 walk_aliased_vdefs (&ar
, gimple_vuse (access
->stmt
),
3906 mark_maybe_modified
, repr
, &visited
);
3907 if (repr
->grp_maybe_modified
)
3910 BITMAP_FREE (visited
);
3915 /* Propagate distances in bb_dereferences in the opposite direction than the
3916 control flow edges, in each step storing the maximum of the current value
3917 and the minimum of all successors. These steps are repeated until the table
3918 stabilizes. Note that BBs which might terminate the functions (according to
3919 final_bbs bitmap) never updated in this way. */
3922 propagate_dereference_distances (void)
3926 auto_vec
<basic_block
> queue (last_basic_block_for_fn (cfun
));
3927 queue
.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
3928 FOR_EACH_BB_FN (bb
, cfun
)
3930 queue
.quick_push (bb
);
3934 while (!queue
.is_empty ())
3938 bool change
= false;
3944 if (bitmap_bit_p (final_bbs
, bb
->index
))
3947 for (i
= 0; i
< func_param_count
; i
++)
3949 int idx
= bb
->index
* func_param_count
+ i
;
3951 HOST_WIDE_INT inh
= 0;
3953 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
3955 int succ_idx
= e
->dest
->index
* func_param_count
+ i
;
3957 if (e
->src
== EXIT_BLOCK_PTR_FOR_FN (cfun
))
3963 inh
= bb_dereferences
[succ_idx
];
3965 else if (bb_dereferences
[succ_idx
] < inh
)
3966 inh
= bb_dereferences
[succ_idx
];
3969 if (!first
&& bb_dereferences
[idx
] < inh
)
3971 bb_dereferences
[idx
] = inh
;
3976 if (change
&& !bitmap_bit_p (final_bbs
, bb
->index
))
3977 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
3982 e
->src
->aux
= e
->src
;
3983 queue
.quick_push (e
->src
);
3988 /* Dump a dereferences TABLE with heading STR to file F. */
3991 dump_dereferences_table (FILE *f
, const char *str
, HOST_WIDE_INT
*table
)
3995 fprintf (dump_file
, "%s", str
);
3996 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR_FOR_FN (cfun
),
3997 EXIT_BLOCK_PTR_FOR_FN (cfun
), next_bb
)
3999 fprintf (f
, "%4i %i ", bb
->index
, bitmap_bit_p (final_bbs
, bb
->index
));
4000 if (bb
!= EXIT_BLOCK_PTR_FOR_FN (cfun
))
4003 for (i
= 0; i
< func_param_count
; i
++)
4005 int idx
= bb
->index
* func_param_count
+ i
;
4006 fprintf (f
, " %4" HOST_WIDE_INT_PRINT
"d", table
[idx
]);
4011 fprintf (dump_file
, "\n");
4014 /* Determine what (parts of) parameters passed by reference that are not
4015 assigned to are not certainly dereferenced in this function and thus the
4016 dereferencing cannot be safely moved to the caller without potentially
4017 introducing a segfault. Mark such REPRESENTATIVES as
4018 grp_not_necessarilly_dereferenced.
4020 The dereferenced maximum "distance," i.e. the offset + size of the accessed
4021 part is calculated rather than simple booleans are calculated for each
4022 pointer parameter to handle cases when only a fraction of the whole
4023 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
4026 The maximum dereference distances for each pointer parameter and BB are
4027 already stored in bb_dereference. This routine simply propagates these
4028 values upwards by propagate_dereference_distances and then compares the
4029 distances of individual parameters in the ENTRY BB to the equivalent
4030 distances of each representative of a (fraction of a) parameter. */
4033 analyze_caller_dereference_legality (vec
<access_p
> representatives
)
4037 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4038 dump_dereferences_table (dump_file
,
4039 "Dereference table before propagation:\n",
4042 propagate_dereference_distances ();
4044 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4045 dump_dereferences_table (dump_file
,
4046 "Dereference table after propagation:\n",
4049 for (i
= 0; i
< func_param_count
; i
++)
4051 struct access
*repr
= representatives
[i
];
4052 int idx
= ENTRY_BLOCK_PTR_FOR_FN (cfun
)->index
* func_param_count
+ i
;
4054 if (!repr
|| no_accesses_p (repr
))
4059 if ((repr
->offset
+ repr
->size
) > bb_dereferences
[idx
])
4060 repr
->grp_not_necessarilly_dereferenced
= 1;
4061 repr
= repr
->next_grp
;
4067 /* Return the representative access for the parameter declaration PARM if it is
4068 a scalar passed by reference which is not written to and the pointer value
4069 is not used directly. Thus, if it is legal to dereference it in the caller
4070 and we can rule out modifications through aliases, such parameter should be
4071 turned into one passed by value. Return NULL otherwise. */
4073 static struct access
*
4074 unmodified_by_ref_scalar_representative (tree parm
)
4076 int i
, access_count
;
4077 struct access
*repr
;
4078 vec
<access_p
> *access_vec
;
4080 access_vec
= get_base_access_vector (parm
);
4081 gcc_assert (access_vec
);
4082 repr
= (*access_vec
)[0];
4085 repr
->group_representative
= repr
;
4087 access_count
= access_vec
->length ();
4088 for (i
= 1; i
< access_count
; i
++)
4090 struct access
*access
= (*access_vec
)[i
];
4093 access
->group_representative
= repr
;
4094 access
->next_sibling
= repr
->next_sibling
;
4095 repr
->next_sibling
= access
;
4099 repr
->grp_scalar_ptr
= 1;
4103 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
4104 associated with. REQ_ALIGN is the minimum required alignment. */
4107 access_precludes_ipa_sra_p (struct access
*access
, unsigned int req_align
)
4109 unsigned int exp_align
;
4110 /* Avoid issues such as the second simple testcase in PR 42025. The problem
4111 is incompatible assign in a call statement (and possibly even in asm
4112 statements). This can be relaxed by using a new temporary but only for
4113 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
4114 intraprocedural SRA we deal with this by keeping the old aggregate around,
4115 something we cannot do in IPA-SRA.) */
4117 && (is_gimple_call (access
->stmt
)
4118 || gimple_code (access
->stmt
) == GIMPLE_ASM
))
4121 exp_align
= get_object_alignment (access
->expr
);
4122 if (exp_align
< req_align
)
4129 /* Sort collected accesses for parameter PARM, identify representatives for
4130 each accessed region and link them together. Return NULL if there are
4131 different but overlapping accesses, return the special ptr value meaning
4132 there are no accesses for this parameter if that is the case and return the
4133 first representative otherwise. Set *RO_GRP if there is a group of accesses
4134 with only read (i.e. no write) accesses. */
4136 static struct access
*
4137 splice_param_accesses (tree parm
, bool *ro_grp
)
4139 int i
, j
, access_count
, group_count
;
4140 int agg_size
, total_size
= 0;
4141 struct access
*access
, *res
, **prev_acc_ptr
= &res
;
4142 vec
<access_p
> *access_vec
;
4144 access_vec
= get_base_access_vector (parm
);
4146 return &no_accesses_representant
;
4147 access_count
= access_vec
->length ();
4149 access_vec
->qsort (compare_access_positions
);
4154 while (i
< access_count
)
4158 access
= (*access_vec
)[i
];
4159 modification
= access
->write
;
4160 if (access_precludes_ipa_sra_p (access
, TYPE_ALIGN (access
->type
)))
4162 a1_alias_type
= reference_alias_ptr_type (access
->expr
);
4164 /* Access is about to become group representative unless we find some
4165 nasty overlap which would preclude us from breaking this parameter
4169 while (j
< access_count
)
4171 struct access
*ac2
= (*access_vec
)[j
];
4172 if (ac2
->offset
!= access
->offset
)
4174 /* All or nothing law for parameters. */
4175 if (access
->offset
+ access
->size
> ac2
->offset
)
4180 else if (ac2
->size
!= access
->size
)
4183 if (access_precludes_ipa_sra_p (ac2
, TYPE_ALIGN (access
->type
))
4184 || (ac2
->type
!= access
->type
4185 && (TREE_ADDRESSABLE (ac2
->type
)
4186 || TREE_ADDRESSABLE (access
->type
)))
4187 || (reference_alias_ptr_type (ac2
->expr
) != a1_alias_type
))
4190 modification
|= ac2
->write
;
4191 ac2
->group_representative
= access
;
4192 ac2
->next_sibling
= access
->next_sibling
;
4193 access
->next_sibling
= ac2
;
4198 access
->grp_maybe_modified
= modification
;
4201 *prev_acc_ptr
= access
;
4202 prev_acc_ptr
= &access
->next_grp
;
4203 total_size
+= access
->size
;
4207 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4208 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm
))));
4210 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm
)));
4211 if (total_size
>= agg_size
)
4214 gcc_assert (group_count
> 0);
4218 /* Decide whether parameters with representative accesses given by REPR should
4219 be reduced into components. */
4222 decide_one_param_reduction (struct access
*repr
)
4224 int total_size
, cur_parm_size
, agg_size
, new_param_count
, parm_size_limit
;
4229 cur_parm_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm
)));
4230 gcc_assert (cur_parm_size
> 0);
4232 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4235 agg_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm
))));
4240 agg_size
= cur_parm_size
;
4246 fprintf (dump_file
, "Evaluating PARAM group sizes for ");
4247 print_generic_expr (dump_file
, parm
, 0);
4248 fprintf (dump_file
, " (UID: %u): \n", DECL_UID (parm
));
4249 for (acc
= repr
; acc
; acc
= acc
->next_grp
)
4250 dump_access (dump_file
, acc
, true);
4254 new_param_count
= 0;
4256 for (; repr
; repr
= repr
->next_grp
)
4258 gcc_assert (parm
== repr
->base
);
4260 /* Taking the address of a non-addressable field is verboten. */
4261 if (by_ref
&& repr
->non_addressable
)
4264 /* Do not decompose a non-BLKmode param in a way that would
4265 create BLKmode params. Especially for by-reference passing
4266 (thus, pointer-type param) this is hardly worthwhile. */
4267 if (DECL_MODE (parm
) != BLKmode
4268 && TYPE_MODE (repr
->type
) == BLKmode
)
4271 if (!by_ref
|| (!repr
->grp_maybe_modified
4272 && !repr
->grp_not_necessarilly_dereferenced
))
4273 total_size
+= repr
->size
;
4275 total_size
+= cur_parm_size
;
4280 gcc_assert (new_param_count
> 0);
4282 if (optimize_function_for_size_p (cfun
))
4283 parm_size_limit
= cur_parm_size
;
4285 parm_size_limit
= (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR
)
4288 if (total_size
< agg_size
4289 && total_size
<= parm_size_limit
)
4292 fprintf (dump_file
, " ....will be split into %i components\n",
4294 return new_param_count
;
4300 /* The order of the following enums is important, we need to do extra work for
4301 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4302 enum ipa_splicing_result
{ NO_GOOD_ACCESS
, UNUSED_PARAMS
, BY_VAL_ACCESSES
,
4303 MODIF_BY_REF_ACCESSES
, UNMODIF_BY_REF_ACCESSES
};
4305 /* Identify representatives of all accesses to all candidate parameters for
4306 IPA-SRA. Return result based on what representatives have been found. */
4308 static enum ipa_splicing_result
4309 splice_all_param_accesses (vec
<access_p
> &representatives
)
4311 enum ipa_splicing_result result
= NO_GOOD_ACCESS
;
4313 struct access
*repr
;
4315 representatives
.create (func_param_count
);
4317 for (parm
= DECL_ARGUMENTS (current_function_decl
);
4319 parm
= DECL_CHAIN (parm
))
4321 if (is_unused_scalar_param (parm
))
4323 representatives
.quick_push (&no_accesses_representant
);
4324 if (result
== NO_GOOD_ACCESS
)
4325 result
= UNUSED_PARAMS
;
4327 else if (POINTER_TYPE_P (TREE_TYPE (parm
))
4328 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm
)))
4329 && bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
4331 repr
= unmodified_by_ref_scalar_representative (parm
);
4332 representatives
.quick_push (repr
);
4334 result
= UNMODIF_BY_REF_ACCESSES
;
4336 else if (bitmap_bit_p (candidate_bitmap
, DECL_UID (parm
)))
4338 bool ro_grp
= false;
4339 repr
= splice_param_accesses (parm
, &ro_grp
);
4340 representatives
.quick_push (repr
);
4342 if (repr
&& !no_accesses_p (repr
))
4344 if (POINTER_TYPE_P (TREE_TYPE (parm
)))
4347 result
= UNMODIF_BY_REF_ACCESSES
;
4348 else if (result
< MODIF_BY_REF_ACCESSES
)
4349 result
= MODIF_BY_REF_ACCESSES
;
4351 else if (result
< BY_VAL_ACCESSES
)
4352 result
= BY_VAL_ACCESSES
;
4354 else if (no_accesses_p (repr
) && (result
== NO_GOOD_ACCESS
))
4355 result
= UNUSED_PARAMS
;
4358 representatives
.quick_push (NULL
);
4361 if (result
== NO_GOOD_ACCESS
)
4363 representatives
.release ();
4364 return NO_GOOD_ACCESS
;
4370 /* Return the index of BASE in PARMS. Abort if it is not found. */
4373 get_param_index (tree base
, vec
<tree
> parms
)
4377 len
= parms
.length ();
4378 for (i
= 0; i
< len
; i
++)
4379 if (parms
[i
] == base
)
4384 /* Convert the decisions made at the representative level into compact
4385 parameter adjustments. REPRESENTATIVES are pointers to first
4386 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4387 final number of adjustments. */
4389 static ipa_parm_adjustment_vec
4390 turn_representatives_into_adjustments (vec
<access_p
> representatives
,
4391 int adjustments_count
)
4394 ipa_parm_adjustment_vec adjustments
;
4398 gcc_assert (adjustments_count
> 0);
4399 parms
= ipa_get_vector_of_formal_parms (current_function_decl
);
4400 adjustments
.create (adjustments_count
);
4401 parm
= DECL_ARGUMENTS (current_function_decl
);
4402 for (i
= 0; i
< func_param_count
; i
++, parm
= DECL_CHAIN (parm
))
4404 struct access
*repr
= representatives
[i
];
4406 if (!repr
|| no_accesses_p (repr
))
4408 struct ipa_parm_adjustment adj
;
4410 memset (&adj
, 0, sizeof (adj
));
4411 adj
.base_index
= get_param_index (parm
, parms
);
4414 adj
.op
= IPA_PARM_OP_COPY
;
4416 adj
.op
= IPA_PARM_OP_REMOVE
;
4417 adj
.arg_prefix
= "ISRA";
4418 adjustments
.quick_push (adj
);
4422 struct ipa_parm_adjustment adj
;
4423 int index
= get_param_index (parm
, parms
);
4425 for (; repr
; repr
= repr
->next_grp
)
4427 memset (&adj
, 0, sizeof (adj
));
4428 gcc_assert (repr
->base
== parm
);
4429 adj
.base_index
= index
;
4430 adj
.base
= repr
->base
;
4431 adj
.type
= repr
->type
;
4432 adj
.alias_ptr_type
= reference_alias_ptr_type (repr
->expr
);
4433 adj
.offset
= repr
->offset
;
4434 adj
.by_ref
= (POINTER_TYPE_P (TREE_TYPE (repr
->base
))
4435 && (repr
->grp_maybe_modified
4436 || repr
->grp_not_necessarilly_dereferenced
));
4437 adj
.arg_prefix
= "ISRA";
4438 adjustments
.quick_push (adj
);
4446 /* Analyze the collected accesses and produce a plan what to do with the
4447 parameters in the form of adjustments, NULL meaning nothing. */
4449 static ipa_parm_adjustment_vec
4450 analyze_all_param_acesses (void)
4452 enum ipa_splicing_result repr_state
;
4453 bool proceed
= false;
4454 int i
, adjustments_count
= 0;
4455 vec
<access_p
> representatives
;
4456 ipa_parm_adjustment_vec adjustments
;
4458 repr_state
= splice_all_param_accesses (representatives
);
4459 if (repr_state
== NO_GOOD_ACCESS
)
4460 return ipa_parm_adjustment_vec ();
4462 /* If there are any parameters passed by reference which are not modified
4463 directly, we need to check whether they can be modified indirectly. */
4464 if (repr_state
== UNMODIF_BY_REF_ACCESSES
)
4466 analyze_caller_dereference_legality (representatives
);
4467 analyze_modified_params (representatives
);
4470 for (i
= 0; i
< func_param_count
; i
++)
4472 struct access
*repr
= representatives
[i
];
4474 if (repr
&& !no_accesses_p (repr
))
4476 if (repr
->grp_scalar_ptr
)
4478 adjustments_count
++;
4479 if (repr
->grp_not_necessarilly_dereferenced
4480 || repr
->grp_maybe_modified
)
4481 representatives
[i
] = NULL
;
4485 sra_stats
.scalar_by_ref_to_by_val
++;
4490 int new_components
= decide_one_param_reduction (repr
);
4492 if (new_components
== 0)
4494 representatives
[i
] = NULL
;
4495 adjustments_count
++;
4499 adjustments_count
+= new_components
;
4500 sra_stats
.aggregate_params_reduced
++;
4501 sra_stats
.param_reductions_created
+= new_components
;
4508 if (no_accesses_p (repr
))
4511 sra_stats
.deleted_unused_parameters
++;
4513 adjustments_count
++;
4517 if (!proceed
&& dump_file
)
4518 fprintf (dump_file
, "NOT proceeding to change params.\n");
4521 adjustments
= turn_representatives_into_adjustments (representatives
,
4524 adjustments
= ipa_parm_adjustment_vec ();
4526 representatives
.release ();
4530 /* If a parameter replacement identified by ADJ does not yet exist in the form
4531 of declaration, create it and record it, otherwise return the previously
4535 get_replaced_param_substitute (struct ipa_parm_adjustment
*adj
)
4538 if (!adj
->new_ssa_base
)
4540 char *pretty_name
= make_fancy_name (adj
->base
);
4542 repl
= create_tmp_reg (TREE_TYPE (adj
->base
), "ISR");
4543 DECL_NAME (repl
) = get_identifier (pretty_name
);
4544 obstack_free (&name_obstack
, pretty_name
);
4546 adj
->new_ssa_base
= repl
;
4549 repl
= adj
->new_ssa_base
;
4553 /* Find the first adjustment for a particular parameter BASE in a vector of
4554 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4557 static struct ipa_parm_adjustment
*
4558 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments
, tree base
)
4562 len
= adjustments
.length ();
4563 for (i
= 0; i
< len
; i
++)
4565 struct ipa_parm_adjustment
*adj
;
4567 adj
= &adjustments
[i
];
4568 if (adj
->op
!= IPA_PARM_OP_COPY
&& adj
->base
== base
)
4575 /* If the statement STMT defines an SSA_NAME of a parameter which is to be
4576 removed because its value is not used, replace the SSA_NAME with a one
4577 relating to a created VAR_DECL together all of its uses and return true.
4578 ADJUSTMENTS is a pointer to an adjustments vector. */
4581 replace_removed_params_ssa_names (gimple stmt
,
4582 ipa_parm_adjustment_vec adjustments
)
4584 struct ipa_parm_adjustment
*adj
;
4585 tree lhs
, decl
, repl
, name
;
4587 if (gimple_code (stmt
) == GIMPLE_PHI
)
4588 lhs
= gimple_phi_result (stmt
);
4589 else if (is_gimple_assign (stmt
))
4590 lhs
= gimple_assign_lhs (stmt
);
4591 else if (is_gimple_call (stmt
))
4592 lhs
= gimple_call_lhs (stmt
);
4596 if (TREE_CODE (lhs
) != SSA_NAME
)
4599 decl
= SSA_NAME_VAR (lhs
);
4600 if (decl
== NULL_TREE
4601 || TREE_CODE (decl
) != PARM_DECL
)
4604 adj
= get_adjustment_for_base (adjustments
, decl
);
4608 repl
= get_replaced_param_substitute (adj
);
4609 name
= make_ssa_name (repl
, stmt
);
4613 fprintf (dump_file
, "replacing an SSA name of a removed param ");
4614 print_generic_expr (dump_file
, lhs
, 0);
4615 fprintf (dump_file
, " with ");
4616 print_generic_expr (dump_file
, name
, 0);
4617 fprintf (dump_file
, "\n");
4620 if (is_gimple_assign (stmt
))
4621 gimple_assign_set_lhs (stmt
, name
);
4622 else if (is_gimple_call (stmt
))
4623 gimple_call_set_lhs (stmt
, name
);
4625 gimple_phi_set_result (as_a
<gphi
*> (stmt
), name
);
4627 replace_uses_by (lhs
, name
);
4628 release_ssa_name (lhs
);
4632 /* If the statement STMT contains any expressions that need to replaced with a
4633 different one as noted by ADJUSTMENTS, do so. Handle any potential type
4634 incompatibilities (GSI is used to accommodate conversion statements and must
4635 point to the statement). Return true iff the statement was modified. */
4638 sra_ipa_modify_assign (gimple stmt
, gimple_stmt_iterator
*gsi
,
4639 ipa_parm_adjustment_vec adjustments
)
4641 tree
*lhs_p
, *rhs_p
;
4644 if (!gimple_assign_single_p (stmt
))
4647 rhs_p
= gimple_assign_rhs1_ptr (stmt
);
4648 lhs_p
= gimple_assign_lhs_ptr (stmt
);
4650 any
= ipa_modify_expr (rhs_p
, false, adjustments
);
4651 any
|= ipa_modify_expr (lhs_p
, false, adjustments
);
4654 tree new_rhs
= NULL_TREE
;
4656 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p
), TREE_TYPE (*rhs_p
)))
4658 if (TREE_CODE (*rhs_p
) == CONSTRUCTOR
)
4660 /* V_C_Es of constructors can cause trouble (PR 42714). */
4661 if (is_gimple_reg_type (TREE_TYPE (*lhs_p
)))
4662 *rhs_p
= build_zero_cst (TREE_TYPE (*lhs_p
));
4664 *rhs_p
= build_constructor (TREE_TYPE (*lhs_p
),
4668 new_rhs
= fold_build1_loc (gimple_location (stmt
),
4669 VIEW_CONVERT_EXPR
, TREE_TYPE (*lhs_p
),
4672 else if (REFERENCE_CLASS_P (*rhs_p
)
4673 && is_gimple_reg_type (TREE_TYPE (*lhs_p
))
4674 && !is_gimple_reg (*lhs_p
))
4675 /* This can happen when an assignment in between two single field
4676 structures is turned into an assignment in between two pointers to
4677 scalars (PR 42237). */
4682 tree tmp
= force_gimple_operand_gsi (gsi
, new_rhs
, true, NULL_TREE
,
4683 true, GSI_SAME_STMT
);
4685 gimple_assign_set_rhs_from_tree (gsi
, tmp
);
4694 /* Traverse the function body and all modifications as described in
4695 ADJUSTMENTS. Return true iff the CFG has been changed. */
4698 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments
)
4700 bool cfg_changed
= false;
4703 FOR_EACH_BB_FN (bb
, cfun
)
4705 gimple_stmt_iterator gsi
;
4707 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4708 replace_removed_params_ssa_names (gsi_stmt (gsi
), adjustments
);
4710 gsi
= gsi_start_bb (bb
);
4711 while (!gsi_end_p (gsi
))
4713 gimple stmt
= gsi_stmt (gsi
);
4714 bool modified
= false;
4718 switch (gimple_code (stmt
))
4721 t
= gimple_return_retval_ptr (as_a
<greturn
*> (stmt
));
4722 if (*t
!= NULL_TREE
)
4723 modified
|= ipa_modify_expr (t
, true, adjustments
);
4727 modified
|= sra_ipa_modify_assign (stmt
, &gsi
, adjustments
);
4728 modified
|= replace_removed_params_ssa_names (stmt
, adjustments
);
4732 /* Operands must be processed before the lhs. */
4733 for (i
= 0; i
< gimple_call_num_args (stmt
); i
++)
4735 t
= gimple_call_arg_ptr (stmt
, i
);
4736 modified
|= ipa_modify_expr (t
, true, adjustments
);
4739 if (gimple_call_lhs (stmt
))
4741 t
= gimple_call_lhs_ptr (stmt
);
4742 modified
|= ipa_modify_expr (t
, false, adjustments
);
4743 modified
|= replace_removed_params_ssa_names (stmt
,
4750 gasm
*asm_stmt
= as_a
<gasm
*> (stmt
);
4751 for (i
= 0; i
< gimple_asm_ninputs (asm_stmt
); i
++)
4753 t
= &TREE_VALUE (gimple_asm_input_op (asm_stmt
, i
));
4754 modified
|= ipa_modify_expr (t
, true, adjustments
);
4756 for (i
= 0; i
< gimple_asm_noutputs (asm_stmt
); i
++)
4758 t
= &TREE_VALUE (gimple_asm_output_op (asm_stmt
, i
));
4759 modified
|= ipa_modify_expr (t
, false, adjustments
);
4771 if (maybe_clean_eh_stmt (stmt
)
4772 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
4782 /* Call gimple_debug_bind_reset_value on all debug statements describing
4783 gimple register parameters that are being removed or replaced. */
4786 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments
)
4789 gimple_stmt_iterator
*gsip
= NULL
, gsi
;
4791 if (MAY_HAVE_DEBUG_STMTS
&& single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun
)))
4793 gsi
= gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun
)));
4796 len
= adjustments
.length ();
4797 for (i
= 0; i
< len
; i
++)
4799 struct ipa_parm_adjustment
*adj
;
4800 imm_use_iterator ui
;
4803 tree name
, vexpr
, copy
= NULL_TREE
;
4804 use_operand_p use_p
;
4806 adj
= &adjustments
[i
];
4807 if (adj
->op
== IPA_PARM_OP_COPY
|| !is_gimple_reg (adj
->base
))
4809 name
= ssa_default_def (cfun
, adj
->base
);
4812 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
4814 if (gimple_clobber_p (stmt
))
4816 gimple_stmt_iterator cgsi
= gsi_for_stmt (stmt
);
4817 unlink_stmt_vdef (stmt
);
4818 gsi_remove (&cgsi
, true);
4819 release_defs (stmt
);
4822 /* All other users must have been removed by
4823 ipa_sra_modify_function_body. */
4824 gcc_assert (is_gimple_debug (stmt
));
4825 if (vexpr
== NULL
&& gsip
!= NULL
)
4827 gcc_assert (TREE_CODE (adj
->base
) == PARM_DECL
);
4828 vexpr
= make_node (DEBUG_EXPR_DECL
);
4829 def_temp
= gimple_build_debug_source_bind (vexpr
, adj
->base
,
4831 DECL_ARTIFICIAL (vexpr
) = 1;
4832 TREE_TYPE (vexpr
) = TREE_TYPE (name
);
4833 DECL_MODE (vexpr
) = DECL_MODE (adj
->base
);
4834 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
4838 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
4839 SET_USE (use_p
, vexpr
);
4842 gimple_debug_bind_reset_value (stmt
);
4845 /* Create a VAR_DECL for debug info purposes. */
4846 if (!DECL_IGNORED_P (adj
->base
))
4848 copy
= build_decl (DECL_SOURCE_LOCATION (current_function_decl
),
4849 VAR_DECL
, DECL_NAME (adj
->base
),
4850 TREE_TYPE (adj
->base
));
4851 if (DECL_PT_UID_SET_P (adj
->base
))
4852 SET_DECL_PT_UID (copy
, DECL_PT_UID (adj
->base
));
4853 TREE_ADDRESSABLE (copy
) = TREE_ADDRESSABLE (adj
->base
);
4854 TREE_READONLY (copy
) = TREE_READONLY (adj
->base
);
4855 TREE_THIS_VOLATILE (copy
) = TREE_THIS_VOLATILE (adj
->base
);
4856 DECL_GIMPLE_REG_P (copy
) = DECL_GIMPLE_REG_P (adj
->base
);
4857 DECL_ARTIFICIAL (copy
) = DECL_ARTIFICIAL (adj
->base
);
4858 DECL_IGNORED_P (copy
) = DECL_IGNORED_P (adj
->base
);
4859 DECL_ABSTRACT_ORIGIN (copy
) = DECL_ORIGIN (adj
->base
);
4860 DECL_SEEN_IN_BIND_EXPR_P (copy
) = 1;
4861 SET_DECL_RTL (copy
, 0);
4862 TREE_USED (copy
) = 1;
4863 DECL_CONTEXT (copy
) = current_function_decl
;
4864 add_local_decl (cfun
, copy
);
4866 BLOCK_VARS (DECL_INITIAL (current_function_decl
));
4867 BLOCK_VARS (DECL_INITIAL (current_function_decl
)) = copy
;
4869 if (gsip
!= NULL
&& copy
&& target_for_debug_bind (adj
->base
))
4871 gcc_assert (TREE_CODE (adj
->base
) == PARM_DECL
);
4873 def_temp
= gimple_build_debug_bind (copy
, vexpr
, NULL
);
4875 def_temp
= gimple_build_debug_source_bind (copy
, adj
->base
,
4877 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
4882 /* Return false if all callers have at least as many actual arguments as there
4883 are formal parameters in the current function and that their types
4887 some_callers_have_mismatched_arguments_p (struct cgraph_node
*node
,
4888 void *data ATTRIBUTE_UNUSED
)
4890 struct cgraph_edge
*cs
;
4891 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4892 if (!cs
->call_stmt
|| !callsite_arguments_match_p (cs
->call_stmt
))
4898 /* Return false if all callers have vuse attached to a call statement. */
4901 some_callers_have_no_vuse_p (struct cgraph_node
*node
,
4902 void *data ATTRIBUTE_UNUSED
)
4904 struct cgraph_edge
*cs
;
4905 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4906 if (!cs
->call_stmt
|| !gimple_vuse (cs
->call_stmt
))
4912 /* Convert all callers of NODE. */
4915 convert_callers_for_node (struct cgraph_node
*node
,
4918 ipa_parm_adjustment_vec
*adjustments
= (ipa_parm_adjustment_vec
*) data
;
4919 bitmap recomputed_callers
= BITMAP_ALLOC (NULL
);
4920 struct cgraph_edge
*cs
;
4922 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4924 push_cfun (DECL_STRUCT_FUNCTION (cs
->caller
->decl
));
4927 fprintf (dump_file
, "Adjusting call %s/%i -> %s/%i\n",
4928 xstrdup (cs
->caller
->name ()),
4930 xstrdup (cs
->callee
->name ()),
4933 ipa_modify_call_arguments (cs
, cs
->call_stmt
, *adjustments
);
4938 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4939 if (bitmap_set_bit (recomputed_callers
, cs
->caller
->uid
)
4940 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs
->caller
->decl
)))
4941 compute_inline_parameters (cs
->caller
, true);
4942 BITMAP_FREE (recomputed_callers
);
4947 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
4950 convert_callers (struct cgraph_node
*node
, tree old_decl
,
4951 ipa_parm_adjustment_vec adjustments
)
4953 basic_block this_block
;
4955 node
->call_for_symbol_and_aliases (convert_callers_for_node
,
4956 &adjustments
, false);
4958 if (!encountered_recursive_call
)
4961 FOR_EACH_BB_FN (this_block
, cfun
)
4963 gimple_stmt_iterator gsi
;
4965 for (gsi
= gsi_start_bb (this_block
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4969 stmt
= dyn_cast
<gcall
*> (gsi_stmt (gsi
));
4972 call_fndecl
= gimple_call_fndecl (stmt
);
4973 if (call_fndecl
== old_decl
)
4976 fprintf (dump_file
, "Adjusting recursive call");
4977 gimple_call_set_fndecl (stmt
, node
->decl
);
4978 ipa_modify_call_arguments (NULL
, stmt
, adjustments
);
4986 /* Perform all the modification required in IPA-SRA for NODE to have parameters
4987 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
4990 modify_function (struct cgraph_node
*node
, ipa_parm_adjustment_vec adjustments
)
4992 struct cgraph_node
*new_node
;
4995 cgraph_edge::rebuild_edges ();
4996 free_dominance_info (CDI_DOMINATORS
);
4999 /* This must be done after rebuilding cgraph edges for node above.
5000 Otherwise any recursive calls to node that are recorded in
5001 redirect_callers will be corrupted. */
5002 vec
<cgraph_edge
*> redirect_callers
= node
->collect_callers ();
5003 new_node
= node
->create_version_clone_with_body (redirect_callers
, NULL
,
5004 NULL
, false, NULL
, NULL
,
5006 redirect_callers
.release ();
5008 push_cfun (DECL_STRUCT_FUNCTION (new_node
->decl
));
5009 ipa_modify_formal_parameters (current_function_decl
, adjustments
);
5010 cfg_changed
= ipa_sra_modify_function_body (adjustments
);
5011 sra_ipa_reset_debug_stmts (adjustments
);
5012 convert_callers (new_node
, node
->decl
, adjustments
);
5013 new_node
->make_local ();
5017 /* Means of communication between ipa_sra_check_caller and
5018 ipa_sra_preliminary_function_checks. */
5020 struct ipa_sra_check_caller_data
5023 bool bad_arg_alignment
;
5027 /* If NODE has a caller, mark that fact in DATA which is pointer to
5028 ipa_sra_check_caller_data. Also check all aggregate arguments in all known
5029 calls if they are unit aligned and if not, set the appropriate flag in DATA
5033 ipa_sra_check_caller (struct cgraph_node
*node
, void *data
)
5038 struct ipa_sra_check_caller_data
*iscc
;
5039 iscc
= (struct ipa_sra_check_caller_data
*) data
;
5040 iscc
->has_callers
= true;
5042 for (cgraph_edge
*cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
5044 if (cs
->caller
->thunk
.thunk_p
)
5046 iscc
->has_thunk
= true;
5049 gimple call_stmt
= cs
->call_stmt
;
5050 unsigned count
= gimple_call_num_args (call_stmt
);
5051 for (unsigned i
= 0; i
< count
; i
++)
5053 tree arg
= gimple_call_arg (call_stmt
, i
);
5054 if (is_gimple_reg (arg
))
5058 HOST_WIDE_INT bitsize
, bitpos
;
5060 int unsignedp
, volatilep
= 0;
5061 get_inner_reference (arg
, &bitsize
, &bitpos
, &offset
, &mode
,
5062 &unsignedp
, &volatilep
, false);
5063 if (bitpos
% BITS_PER_UNIT
)
5065 iscc
->bad_arg_alignment
= true;
5074 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
5075 attributes, return true otherwise. NODE is the cgraph node of the current
5079 ipa_sra_preliminary_function_checks (struct cgraph_node
*node
)
5081 if (!node
->can_be_local_p ())
5084 fprintf (dump_file
, "Function not local to this compilation unit.\n");
5088 if (!node
->local
.can_change_signature
)
5091 fprintf (dump_file
, "Function can not change signature.\n");
5095 if (!tree_versionable_function_p (node
->decl
))
5098 fprintf (dump_file
, "Function is not versionable.\n");
5102 if (!opt_for_fn (node
->decl
, optimize
)
5103 || !opt_for_fn (node
->decl
, flag_ipa_sra
))
5106 fprintf (dump_file
, "Function not optimized.\n");
5110 if (DECL_VIRTUAL_P (current_function_decl
))
5113 fprintf (dump_file
, "Function is a virtual method.\n");
5117 if ((DECL_ONE_ONLY (node
->decl
) || DECL_EXTERNAL (node
->decl
))
5118 && inline_summaries
->get (node
)->size
>= MAX_INLINE_INSNS_AUTO
)
5121 fprintf (dump_file
, "Function too big to be made truly local.\n");
5128 fprintf (dump_file
, "Function uses stdarg. \n");
5132 if (TYPE_ATTRIBUTES (TREE_TYPE (node
->decl
)))
5135 if (DECL_DISREGARD_INLINE_LIMITS (node
->decl
))
5138 fprintf (dump_file
, "Always inline function will be inlined "
5143 struct ipa_sra_check_caller_data iscc
;
5144 memset (&iscc
, 0, sizeof(iscc
));
5145 node
->call_for_symbol_and_aliases (ipa_sra_check_caller
, &iscc
, true);
5146 if (!iscc
.has_callers
)
5150 "Function has no callers in this compilation unit.\n");
5154 if (iscc
.bad_arg_alignment
)
5158 "A function call has an argument with non-unit alignment.\n");
5173 /* Perform early interprocedural SRA. */
5176 ipa_early_sra (void)
5178 struct cgraph_node
*node
= cgraph_node::get (current_function_decl
);
5179 ipa_parm_adjustment_vec adjustments
;
5182 if (!ipa_sra_preliminary_function_checks (node
))
5186 sra_mode
= SRA_MODE_EARLY_IPA
;
5188 if (!find_param_candidates ())
5191 fprintf (dump_file
, "Function has no IPA-SRA candidates.\n");
5195 if (node
->call_for_symbol_and_aliases
5196 (some_callers_have_mismatched_arguments_p
, NULL
, true))
5199 fprintf (dump_file
, "There are callers with insufficient number of "
5200 "arguments or arguments with type mismatches.\n");
5204 if (node
->call_for_symbol_and_aliases
5205 (some_callers_have_no_vuse_p
, NULL
, true))
5208 fprintf (dump_file
, "There are callers with no VUSE attached "
5209 "to a call stmt.\n");
5213 bb_dereferences
= XCNEWVEC (HOST_WIDE_INT
,
5215 * last_basic_block_for_fn (cfun
));
5216 final_bbs
= BITMAP_ALLOC (NULL
);
5219 if (encountered_apply_args
)
5222 fprintf (dump_file
, "Function calls __builtin_apply_args().\n");
5226 if (encountered_unchangable_recursive_call
)
5229 fprintf (dump_file
, "Function calls itself with insufficient "
5230 "number of arguments.\n");
5234 adjustments
= analyze_all_param_acesses ();
5235 if (!adjustments
.exists ())
5238 ipa_dump_param_adjustments (dump_file
, adjustments
, current_function_decl
);
5240 if (modify_function (node
, adjustments
))
5241 ret
= TODO_update_ssa
| TODO_cleanup_cfg
;
5243 ret
= TODO_update_ssa
;
5244 adjustments
.release ();
5246 statistics_counter_event (cfun
, "Unused parameters deleted",
5247 sra_stats
.deleted_unused_parameters
);
5248 statistics_counter_event (cfun
, "Scalar parameters converted to by-value",
5249 sra_stats
.scalar_by_ref_to_by_val
);
5250 statistics_counter_event (cfun
, "Aggregate parameters broken up",
5251 sra_stats
.aggregate_params_reduced
);
5252 statistics_counter_event (cfun
, "Aggregate parameter components created",
5253 sra_stats
.param_reductions_created
);
5256 BITMAP_FREE (final_bbs
);
5257 free (bb_dereferences
);
5259 sra_deinitialize ();
5265 const pass_data pass_data_early_ipa_sra
=
5267 GIMPLE_PASS
, /* type */
5268 "eipa_sra", /* name */
5269 OPTGROUP_NONE
, /* optinfo_flags */
5270 TV_IPA_SRA
, /* tv_id */
5271 0, /* properties_required */
5272 0, /* properties_provided */
5273 0, /* properties_destroyed */
5274 0, /* todo_flags_start */
5275 TODO_dump_symtab
, /* todo_flags_finish */
5278 class pass_early_ipa_sra
: public gimple_opt_pass
5281 pass_early_ipa_sra (gcc::context
*ctxt
)
5282 : gimple_opt_pass (pass_data_early_ipa_sra
, ctxt
)
5285 /* opt_pass methods: */
5286 virtual bool gate (function
*) { return flag_ipa_sra
&& dbg_cnt (eipa_sra
); }
5287 virtual unsigned int execute (function
*) { return ipa_early_sra (); }
5289 }; // class pass_early_ipa_sra
5294 make_pass_early_ipa_sra (gcc::context
*ctxt
)
5296 return new pass_early_ipa_sra (ctxt
);