* gcc-interface/trans.c (Subprogram_Body_to_gnu): Initialize locus.
[official-gcc.git] / gcc / tree-sra.c
blobdaef8d72cd0e05684cd0326413125ec23901374d
1 /* Scalar Replacement of Aggregates (SRA) converts some structure
2 references into scalar references, exposing them to the scalar
3 optimizers.
4 Copyright (C) 2008-2017 Free Software Foundation, Inc.
5 Contributed by Martin Jambor <mjambor@suse.cz>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
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
17 for more details.
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
31 conversions.
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
49 accesses.
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. */
74 #include "config.h"
75 #include "system.h"
76 #include "coretypes.h"
77 #include "backend.h"
78 #include "target.h"
79 #include "rtl.h"
80 #include "tree.h"
81 #include "gimple.h"
82 #include "predict.h"
83 #include "alloc-pool.h"
84 #include "tree-pass.h"
85 #include "ssa.h"
86 #include "cgraph.h"
87 #include "gimple-pretty-print.h"
88 #include "alias.h"
89 #include "fold-const.h"
90 #include "tree-eh.h"
91 #include "stor-layout.h"
92 #include "gimplify.h"
93 #include "gimple-iterator.h"
94 #include "gimplify-me.h"
95 #include "gimple-walk.h"
96 #include "tree-cfg.h"
97 #include "tree-dfa.h"
98 #include "tree-ssa.h"
99 #include "symbol-summary.h"
100 #include "ipa-param-manipulation.h"
101 #include "ipa-prop.h"
102 #include "params.h"
103 #include "dbgcnt.h"
104 #include "tree-inline.h"
105 #include "ipa-fnsummary.h"
106 #include "ipa-utils.h"
107 #include "builtins.h"
109 /* Enumeration of all aggregate reductions we can do. */
110 enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
111 SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
112 SRA_MODE_INTRA }; /* late intraprocedural SRA */
114 /* Global variable describing which aggregate reduction we are performing at
115 the moment. */
116 static enum sra_mode sra_mode;
118 struct assign_link;
120 /* ACCESS represents each access to an aggregate variable (as a whole or a
121 part). It can also represent a group of accesses that refer to exactly the
122 same fragment of an aggregate (i.e. those that have exactly the same offset
123 and size). Such representatives for a single aggregate, once determined,
124 are linked in a linked list and have the group fields set.
126 Moreover, when doing intraprocedural SRA, a tree is built from those
127 representatives (by the means of first_child and next_sibling pointers), in
128 which all items in a subtree are "within" the root, i.e. their offset is
129 greater or equal to offset of the root and offset+size is smaller or equal
130 to offset+size of the root. Children of an access are sorted by offset.
132 Note that accesses to parts of vector and complex number types always
133 represented by an access to the whole complex number or a vector. It is a
134 duty of the modifying functions to replace them appropriately. */
136 struct access
138 /* Values returned by `get_ref_base_and_extent' for each component reference
139 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
140 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
141 HOST_WIDE_INT offset;
142 HOST_WIDE_INT size;
143 tree base;
145 /* Expression. It is context dependent so do not use it to create new
146 expressions to access the original aggregate. See PR 42154 for a
147 testcase. */
148 tree expr;
149 /* Type. */
150 tree type;
152 /* The statement this access belongs to. */
153 gimple *stmt;
155 /* Next group representative for this aggregate. */
156 struct access *next_grp;
158 /* Pointer to the group representative. Pointer to itself if the struct is
159 the representative. */
160 struct access *group_representative;
162 /* After access tree has been constructed, this points to the parent of the
163 current access, if there is one. NULL for roots. */
164 struct access *parent;
166 /* If this access has any children (in terms of the definition above), this
167 points to the first one. */
168 struct access *first_child;
170 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
171 described above. In IPA-SRA this is a pointer to the next access
172 belonging to the same group (having the same representative). */
173 struct access *next_sibling;
175 /* Pointers to the first and last element in the linked list of assign
176 links. */
177 struct assign_link *first_link, *last_link;
179 /* Pointer to the next access in the work queue. */
180 struct access *next_queued;
182 /* Replacement variable for this access "region." Never to be accessed
183 directly, always only by the means of get_access_replacement() and only
184 when grp_to_be_replaced flag is set. */
185 tree replacement_decl;
187 /* Is this access an access to a non-addressable field? */
188 unsigned non_addressable : 1;
190 /* Is this access made in reverse storage order? */
191 unsigned reverse : 1;
193 /* Is this particular access write access? */
194 unsigned write : 1;
196 /* Is this access currently in the work queue? */
197 unsigned grp_queued : 1;
199 /* Does this group contain a write access? This flag is propagated down the
200 access tree. */
201 unsigned grp_write : 1;
203 /* Does this group contain a read access? This flag is propagated down the
204 access tree. */
205 unsigned grp_read : 1;
207 /* Does this group contain a read access that comes from an assignment
208 statement? This flag is propagated down the access tree. */
209 unsigned grp_assignment_read : 1;
211 /* Does this group contain a write access that comes from an assignment
212 statement? This flag is propagated down the access tree. */
213 unsigned grp_assignment_write : 1;
215 /* Does this group contain a read access through a scalar type? This flag is
216 not propagated in the access tree in any direction. */
217 unsigned grp_scalar_read : 1;
219 /* Does this group contain a write access through a scalar type? This flag
220 is not propagated in the access tree in any direction. */
221 unsigned grp_scalar_write : 1;
223 /* Is this access an artificial one created to scalarize some record
224 entirely? */
225 unsigned grp_total_scalarization : 1;
227 /* Other passes of the analysis use this bit to make function
228 analyze_access_subtree create scalar replacements for this group if
229 possible. */
230 unsigned grp_hint : 1;
232 /* Is the subtree rooted in this access fully covered by scalar
233 replacements? */
234 unsigned grp_covered : 1;
236 /* If set to true, this access and all below it in an access tree must not be
237 scalarized. */
238 unsigned grp_unscalarizable_region : 1;
240 /* Whether data have been written to parts of the aggregate covered by this
241 access which is not to be scalarized. This flag is propagated up in the
242 access tree. */
243 unsigned grp_unscalarized_data : 1;
245 /* Does this access and/or group contain a write access through a
246 BIT_FIELD_REF? */
247 unsigned grp_partial_lhs : 1;
249 /* Set when a scalar replacement should be created for this variable. */
250 unsigned grp_to_be_replaced : 1;
252 /* Set when we want a replacement for the sole purpose of having it in
253 generated debug statements. */
254 unsigned grp_to_be_debug_replaced : 1;
256 /* Should TREE_NO_WARNING of a replacement be set? */
257 unsigned grp_no_warning : 1;
259 /* Is it possible that the group refers to data which might be (directly or
260 otherwise) modified? */
261 unsigned grp_maybe_modified : 1;
263 /* Set when this is a representative of a pointer to scalar (i.e. by
264 reference) parameter which we consider for turning into a plain scalar
265 (i.e. a by value parameter). */
266 unsigned grp_scalar_ptr : 1;
268 /* Set when we discover that this pointer is not safe to dereference in the
269 caller. */
270 unsigned grp_not_necessarilly_dereferenced : 1;
273 typedef struct access *access_p;
276 /* Alloc pool for allocating access structures. */
277 static object_allocator<struct access> access_pool ("SRA accesses");
279 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
280 are used to propagate subaccesses from rhs to lhs as long as they don't
281 conflict with what is already there. */
282 struct assign_link
284 struct access *lacc, *racc;
285 struct assign_link *next;
288 /* Alloc pool for allocating assign link structures. */
289 static object_allocator<assign_link> assign_link_pool ("SRA links");
291 /* Base (tree) -> Vector (vec<access_p> *) map. */
292 static hash_map<tree, auto_vec<access_p> > *base_access_vec;
294 /* Candidate hash table helpers. */
296 struct uid_decl_hasher : nofree_ptr_hash <tree_node>
298 static inline hashval_t hash (const tree_node *);
299 static inline bool equal (const tree_node *, const tree_node *);
302 /* Hash a tree in a uid_decl_map. */
304 inline hashval_t
305 uid_decl_hasher::hash (const tree_node *item)
307 return item->decl_minimal.uid;
310 /* Return true if the DECL_UID in both trees are equal. */
312 inline bool
313 uid_decl_hasher::equal (const tree_node *a, const tree_node *b)
315 return (a->decl_minimal.uid == b->decl_minimal.uid);
318 /* Set of candidates. */
319 static bitmap candidate_bitmap;
320 static hash_table<uid_decl_hasher> *candidates;
322 /* For a candidate UID return the candidates decl. */
324 static inline tree
325 candidate (unsigned uid)
327 tree_node t;
328 t.decl_minimal.uid = uid;
329 return candidates->find_with_hash (&t, static_cast <hashval_t> (uid));
332 /* Bitmap of candidates which we should try to entirely scalarize away and
333 those which cannot be (because they are and need be used as a whole). */
334 static bitmap should_scalarize_away_bitmap, cannot_scalarize_away_bitmap;
336 /* Bitmap of candidates in the constant pool, which cannot be scalarized
337 because this would produce non-constant expressions (e.g. Ada). */
338 static bitmap disqualified_constants;
340 /* Obstack for creation of fancy names. */
341 static struct obstack name_obstack;
343 /* Head of a linked list of accesses that need to have its subaccesses
344 propagated to their assignment counterparts. */
345 static struct access *work_queue_head;
347 /* Number of parameters of the analyzed function when doing early ipa SRA. */
348 static int func_param_count;
350 /* scan_function sets the following to true if it encounters a call to
351 __builtin_apply_args. */
352 static bool encountered_apply_args;
354 /* Set by scan_function when it finds a recursive call. */
355 static bool encountered_recursive_call;
357 /* Set by scan_function when it finds a recursive call with less actual
358 arguments than formal parameters.. */
359 static bool encountered_unchangable_recursive_call;
361 /* This is a table in which for each basic block and parameter there is a
362 distance (offset + size) in that parameter which is dereferenced and
363 accessed in that BB. */
364 static HOST_WIDE_INT *bb_dereferences;
365 /* Bitmap of BBs that can cause the function to "stop" progressing by
366 returning, throwing externally, looping infinitely or calling a function
367 which might abort etc.. */
368 static bitmap final_bbs;
370 /* Representative of no accesses at all. */
371 static struct access no_accesses_representant;
373 /* Predicate to test the special value. */
375 static inline bool
376 no_accesses_p (struct access *access)
378 return access == &no_accesses_representant;
381 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
382 representative fields are dumped, otherwise those which only describe the
383 individual access are. */
385 static struct
387 /* Number of processed aggregates is readily available in
388 analyze_all_variable_accesses and so is not stored here. */
390 /* Number of created scalar replacements. */
391 int replacements;
393 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
394 expression. */
395 int exprs;
397 /* Number of statements created by generate_subtree_copies. */
398 int subtree_copies;
400 /* Number of statements created by load_assign_lhs_subreplacements. */
401 int subreplacements;
403 /* Number of times sra_modify_assign has deleted a statement. */
404 int deleted;
406 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
407 RHS reparately due to type conversions or nonexistent matching
408 references. */
409 int separate_lhs_rhs_handling;
411 /* Number of parameters that were removed because they were unused. */
412 int deleted_unused_parameters;
414 /* Number of scalars passed as parameters by reference that have been
415 converted to be passed by value. */
416 int scalar_by_ref_to_by_val;
418 /* Number of aggregate parameters that were replaced by one or more of their
419 components. */
420 int aggregate_params_reduced;
422 /* Numbber of components created when splitting aggregate parameters. */
423 int param_reductions_created;
424 } sra_stats;
426 static void
427 dump_access (FILE *f, struct access *access, bool grp)
429 fprintf (f, "access { ");
430 fprintf (f, "base = (%d)'", DECL_UID (access->base));
431 print_generic_expr (f, access->base);
432 fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
433 fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
434 fprintf (f, ", expr = ");
435 print_generic_expr (f, access->expr);
436 fprintf (f, ", type = ");
437 print_generic_expr (f, access->type);
438 fprintf (f, ", non_addressable = %d, reverse = %d",
439 access->non_addressable, access->reverse);
440 if (grp)
441 fprintf (f, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
442 "grp_assignment_write = %d, grp_scalar_read = %d, "
443 "grp_scalar_write = %d, grp_total_scalarization = %d, "
444 "grp_hint = %d, grp_covered = %d, "
445 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
446 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
447 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
448 "grp_not_necessarilly_dereferenced = %d\n",
449 access->grp_read, access->grp_write, access->grp_assignment_read,
450 access->grp_assignment_write, access->grp_scalar_read,
451 access->grp_scalar_write, access->grp_total_scalarization,
452 access->grp_hint, access->grp_covered,
453 access->grp_unscalarizable_region, access->grp_unscalarized_data,
454 access->grp_partial_lhs, access->grp_to_be_replaced,
455 access->grp_to_be_debug_replaced, access->grp_maybe_modified,
456 access->grp_not_necessarilly_dereferenced);
457 else
458 fprintf (f, ", write = %d, grp_total_scalarization = %d, "
459 "grp_partial_lhs = %d\n",
460 access->write, access->grp_total_scalarization,
461 access->grp_partial_lhs);
464 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
466 static void
467 dump_access_tree_1 (FILE *f, struct access *access, int level)
471 int i;
473 for (i = 0; i < level; i++)
474 fputs ("* ", f);
476 dump_access (f, access, true);
478 if (access->first_child)
479 dump_access_tree_1 (f, access->first_child, level + 1);
481 access = access->next_sibling;
483 while (access);
486 /* Dump all access trees for a variable, given the pointer to the first root in
487 ACCESS. */
489 static void
490 dump_access_tree (FILE *f, struct access *access)
492 for (; access; access = access->next_grp)
493 dump_access_tree_1 (f, access, 0);
496 /* Return true iff ACC is non-NULL and has subaccesses. */
498 static inline bool
499 access_has_children_p (struct access *acc)
501 return acc && acc->first_child;
504 /* Return true iff ACC is (partly) covered by at least one replacement. */
506 static bool
507 access_has_replacements_p (struct access *acc)
509 struct access *child;
510 if (acc->grp_to_be_replaced)
511 return true;
512 for (child = acc->first_child; child; child = child->next_sibling)
513 if (access_has_replacements_p (child))
514 return true;
515 return false;
518 /* Return a vector of pointers to accesses for the variable given in BASE or
519 NULL if there is none. */
521 static vec<access_p> *
522 get_base_access_vector (tree base)
524 return base_access_vec->get (base);
527 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
528 in ACCESS. Return NULL if it cannot be found. */
530 static struct access *
531 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
532 HOST_WIDE_INT size)
534 while (access && (access->offset != offset || access->size != size))
536 struct access *child = access->first_child;
538 while (child && (child->offset + child->size <= offset))
539 child = child->next_sibling;
540 access = child;
543 return access;
546 /* Return the first group representative for DECL or NULL if none exists. */
548 static struct access *
549 get_first_repr_for_decl (tree base)
551 vec<access_p> *access_vec;
553 access_vec = get_base_access_vector (base);
554 if (!access_vec)
555 return NULL;
557 return (*access_vec)[0];
560 /* Find an access representative for the variable BASE and given OFFSET and
561 SIZE. Requires that access trees have already been built. Return NULL if
562 it cannot be found. */
564 static struct access *
565 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
566 HOST_WIDE_INT size)
568 struct access *access;
570 access = get_first_repr_for_decl (base);
571 while (access && (access->offset + access->size <= offset))
572 access = access->next_grp;
573 if (!access)
574 return NULL;
576 return find_access_in_subtree (access, offset, size);
579 /* Add LINK to the linked list of assign links of RACC. */
580 static void
581 add_link_to_rhs (struct access *racc, struct assign_link *link)
583 gcc_assert (link->racc == racc);
585 if (!racc->first_link)
587 gcc_assert (!racc->last_link);
588 racc->first_link = link;
590 else
591 racc->last_link->next = link;
593 racc->last_link = link;
594 link->next = NULL;
597 /* Move all link structures in their linked list in OLD_RACC to the linked list
598 in NEW_RACC. */
599 static void
600 relink_to_new_repr (struct access *new_racc, struct access *old_racc)
602 if (!old_racc->first_link)
604 gcc_assert (!old_racc->last_link);
605 return;
608 if (new_racc->first_link)
610 gcc_assert (!new_racc->last_link->next);
611 gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
613 new_racc->last_link->next = old_racc->first_link;
614 new_racc->last_link = old_racc->last_link;
616 else
618 gcc_assert (!new_racc->last_link);
620 new_racc->first_link = old_racc->first_link;
621 new_racc->last_link = old_racc->last_link;
623 old_racc->first_link = old_racc->last_link = NULL;
626 /* Add ACCESS to the work queue (which is actually a stack). */
628 static void
629 add_access_to_work_queue (struct access *access)
631 if (access->first_link && !access->grp_queued)
633 gcc_assert (!access->next_queued);
634 access->next_queued = work_queue_head;
635 access->grp_queued = 1;
636 work_queue_head = access;
640 /* Pop an access from the work queue, and return it, assuming there is one. */
642 static struct access *
643 pop_access_from_work_queue (void)
645 struct access *access = work_queue_head;
647 work_queue_head = access->next_queued;
648 access->next_queued = NULL;
649 access->grp_queued = 0;
650 return access;
654 /* Allocate necessary structures. */
656 static void
657 sra_initialize (void)
659 candidate_bitmap = BITMAP_ALLOC (NULL);
660 candidates = new hash_table<uid_decl_hasher>
661 (vec_safe_length (cfun->local_decls) / 2);
662 should_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
663 cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
664 disqualified_constants = BITMAP_ALLOC (NULL);
665 gcc_obstack_init (&name_obstack);
666 base_access_vec = new hash_map<tree, auto_vec<access_p> >;
667 memset (&sra_stats, 0, sizeof (sra_stats));
668 encountered_apply_args = false;
669 encountered_recursive_call = false;
670 encountered_unchangable_recursive_call = false;
673 /* Deallocate all general structures. */
675 static void
676 sra_deinitialize (void)
678 BITMAP_FREE (candidate_bitmap);
679 delete candidates;
680 candidates = NULL;
681 BITMAP_FREE (should_scalarize_away_bitmap);
682 BITMAP_FREE (cannot_scalarize_away_bitmap);
683 BITMAP_FREE (disqualified_constants);
684 access_pool.release ();
685 assign_link_pool.release ();
686 obstack_free (&name_obstack, NULL);
688 delete base_access_vec;
691 /* Return true if DECL is a VAR_DECL in the constant pool, false otherwise. */
693 static bool constant_decl_p (tree decl)
695 return VAR_P (decl) && DECL_IN_CONSTANT_POOL (decl);
698 /* Remove DECL from candidates for SRA and write REASON to the dump file if
699 there is one. */
701 static void
702 disqualify_candidate (tree decl, const char *reason)
704 if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl)))
705 candidates->remove_elt_with_hash (decl, DECL_UID (decl));
706 if (constant_decl_p (decl))
707 bitmap_set_bit (disqualified_constants, DECL_UID (decl));
709 if (dump_file && (dump_flags & TDF_DETAILS))
711 fprintf (dump_file, "! Disqualifying ");
712 print_generic_expr (dump_file, decl);
713 fprintf (dump_file, " - %s\n", reason);
717 /* Return true iff the type contains a field or an element which does not allow
718 scalarization. */
720 static bool
721 type_internals_preclude_sra_p (tree type, const char **msg)
723 tree fld;
724 tree et;
726 switch (TREE_CODE (type))
728 case RECORD_TYPE:
729 case UNION_TYPE:
730 case QUAL_UNION_TYPE:
731 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
732 if (TREE_CODE (fld) == FIELD_DECL)
734 tree ft = TREE_TYPE (fld);
736 if (TREE_THIS_VOLATILE (fld))
738 *msg = "volatile structure field";
739 return true;
741 if (!DECL_FIELD_OFFSET (fld))
743 *msg = "no structure field offset";
744 return true;
746 if (!DECL_SIZE (fld))
748 *msg = "zero structure field size";
749 return true;
751 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
753 *msg = "structure field offset not fixed";
754 return true;
756 if (!tree_fits_uhwi_p (DECL_SIZE (fld)))
758 *msg = "structure field size not fixed";
759 return true;
761 if (!tree_fits_shwi_p (bit_position (fld)))
763 *msg = "structure field size too big";
764 return true;
766 if (AGGREGATE_TYPE_P (ft)
767 && int_bit_position (fld) % BITS_PER_UNIT != 0)
769 *msg = "structure field is bit field";
770 return true;
773 if (AGGREGATE_TYPE_P (ft) && type_internals_preclude_sra_p (ft, msg))
774 return true;
777 return false;
779 case ARRAY_TYPE:
780 et = TREE_TYPE (type);
782 if (TYPE_VOLATILE (et))
784 *msg = "element type is volatile";
785 return true;
788 if (AGGREGATE_TYPE_P (et) && type_internals_preclude_sra_p (et, msg))
789 return true;
791 return false;
793 default:
794 return false;
798 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
799 base variable if it is. Return T if it is not an SSA_NAME. */
801 static tree
802 get_ssa_base_param (tree t)
804 if (TREE_CODE (t) == SSA_NAME)
806 if (SSA_NAME_IS_DEFAULT_DEF (t))
807 return SSA_NAME_VAR (t);
808 else
809 return NULL_TREE;
811 return t;
814 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
815 belongs to, unless the BB has already been marked as a potentially
816 final. */
818 static void
819 mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple *stmt)
821 basic_block bb = gimple_bb (stmt);
822 int idx, parm_index = 0;
823 tree parm;
825 if (bitmap_bit_p (final_bbs, bb->index))
826 return;
828 for (parm = DECL_ARGUMENTS (current_function_decl);
829 parm && parm != base;
830 parm = DECL_CHAIN (parm))
831 parm_index++;
833 gcc_assert (parm_index < func_param_count);
835 idx = bb->index * func_param_count + parm_index;
836 if (bb_dereferences[idx] < dist)
837 bb_dereferences[idx] = dist;
840 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
841 the three fields. Also add it to the vector of accesses corresponding to
842 the base. Finally, return the new access. */
844 static struct access *
845 create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
847 struct access *access = access_pool.allocate ();
849 memset (access, 0, sizeof (struct access));
850 access->base = base;
851 access->offset = offset;
852 access->size = size;
854 base_access_vec->get_or_insert (base).safe_push (access);
856 return access;
859 static bool maybe_add_sra_candidate (tree);
861 /* Create and insert access for EXPR. Return created access, or NULL if it is
862 not possible. Also scan for uses of constant pool as we go along and add
863 to candidates. */
865 static struct access *
866 create_access (tree expr, gimple *stmt, bool write)
868 struct access *access;
869 HOST_WIDE_INT offset, size, max_size;
870 tree base = expr;
871 bool reverse, ptr, unscalarizable_region = false;
873 base = get_ref_base_and_extent (expr, &offset, &size, &max_size, &reverse);
875 if (sra_mode == SRA_MODE_EARLY_IPA
876 && TREE_CODE (base) == MEM_REF)
878 base = get_ssa_base_param (TREE_OPERAND (base, 0));
879 if (!base)
880 return NULL;
881 ptr = true;
883 else
884 ptr = false;
886 /* For constant-pool entries, check we can substitute the constant value. */
887 if (constant_decl_p (base)
888 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA))
890 gcc_assert (!bitmap_bit_p (disqualified_constants, DECL_UID (base)));
891 if (expr != base
892 && !is_gimple_reg_type (TREE_TYPE (expr))
893 && dump_file && (dump_flags & TDF_DETAILS))
895 /* This occurs in Ada with accesses to ARRAY_RANGE_REFs,
896 and elements of multidimensional arrays (which are
897 multi-element arrays in their own right). */
898 fprintf (dump_file, "Allowing non-reg-type load of part"
899 " of constant-pool entry: ");
900 print_generic_expr (dump_file, expr);
902 maybe_add_sra_candidate (base);
905 if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
906 return NULL;
908 if (sra_mode == SRA_MODE_EARLY_IPA)
910 if (size < 0 || size != max_size)
912 disqualify_candidate (base, "Encountered a variable sized access.");
913 return NULL;
915 if (TREE_CODE (expr) == COMPONENT_REF
916 && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))
918 disqualify_candidate (base, "Encountered a bit-field access.");
919 return NULL;
921 gcc_checking_assert ((offset % BITS_PER_UNIT) == 0);
923 if (ptr)
924 mark_parm_dereference (base, offset + size, stmt);
926 else
928 if (size != max_size)
930 size = max_size;
931 unscalarizable_region = true;
933 if (size < 0)
935 disqualify_candidate (base, "Encountered an unconstrained access.");
936 return NULL;
940 access = create_access_1 (base, offset, size);
941 access->expr = expr;
942 access->type = TREE_TYPE (expr);
943 access->write = write;
944 access->grp_unscalarizable_region = unscalarizable_region;
945 access->stmt = stmt;
946 access->reverse = reverse;
948 if (TREE_CODE (expr) == COMPONENT_REF
949 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1)))
950 access->non_addressable = 1;
952 return access;
956 /* Return true iff TYPE is scalarizable - i.e. a RECORD_TYPE or fixed-length
957 ARRAY_TYPE with fields that are either of gimple register types (excluding
958 bit-fields) or (recursively) scalarizable types. CONST_DECL must be true if
959 we are considering a decl from constant pool. If it is false, char arrays
960 will be refused. */
962 static bool
963 scalarizable_type_p (tree type, bool const_decl)
965 gcc_assert (!is_gimple_reg_type (type));
966 if (type_contains_placeholder_p (type))
967 return false;
969 switch (TREE_CODE (type))
971 case RECORD_TYPE:
972 for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
973 if (TREE_CODE (fld) == FIELD_DECL)
975 tree ft = TREE_TYPE (fld);
977 if (DECL_BIT_FIELD (fld))
978 return false;
980 if (!is_gimple_reg_type (ft)
981 && !scalarizable_type_p (ft, const_decl))
982 return false;
985 return true;
987 case ARRAY_TYPE:
989 HOST_WIDE_INT min_elem_size;
990 if (const_decl)
991 min_elem_size = 0;
992 else
993 min_elem_size = BITS_PER_UNIT;
995 if (TYPE_DOMAIN (type) == NULL_TREE
996 || !tree_fits_shwi_p (TYPE_SIZE (type))
997 || !tree_fits_shwi_p (TYPE_SIZE (TREE_TYPE (type)))
998 || (tree_to_shwi (TYPE_SIZE (TREE_TYPE (type))) <= min_elem_size)
999 || !tree_fits_shwi_p (TYPE_MIN_VALUE (TYPE_DOMAIN (type))))
1000 return false;
1001 if (tree_to_shwi (TYPE_SIZE (type)) == 0
1002 && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE)
1003 /* Zero-element array, should not prevent scalarization. */
1005 else if ((tree_to_shwi (TYPE_SIZE (type)) <= 0)
1006 || !tree_fits_shwi_p (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
1007 /* Variable-length array, do not allow scalarization. */
1008 return false;
1010 tree elem = TREE_TYPE (type);
1011 if (!is_gimple_reg_type (elem)
1012 && !scalarizable_type_p (elem, const_decl))
1013 return false;
1014 return true;
1016 default:
1017 return false;
1021 static void scalarize_elem (tree, HOST_WIDE_INT, HOST_WIDE_INT, bool, tree, tree);
1023 /* Create total_scalarization accesses for all scalar fields of a member
1024 of type DECL_TYPE conforming to scalarizable_type_p. BASE
1025 must be the top-most VAR_DECL representing the variable; within that,
1026 OFFSET locates the member and REF must be the memory reference expression for
1027 the member. */
1029 static void
1030 completely_scalarize (tree base, tree decl_type, HOST_WIDE_INT offset, tree ref)
1032 switch (TREE_CODE (decl_type))
1034 case RECORD_TYPE:
1035 for (tree fld = TYPE_FIELDS (decl_type); fld; fld = DECL_CHAIN (fld))
1036 if (TREE_CODE (fld) == FIELD_DECL)
1038 HOST_WIDE_INT pos = offset + int_bit_position (fld);
1039 tree ft = TREE_TYPE (fld);
1040 tree nref = build3 (COMPONENT_REF, ft, ref, fld, NULL_TREE);
1042 scalarize_elem (base, pos, tree_to_uhwi (DECL_SIZE (fld)),
1043 TYPE_REVERSE_STORAGE_ORDER (decl_type),
1044 nref, ft);
1046 break;
1047 case ARRAY_TYPE:
1049 tree elemtype = TREE_TYPE (decl_type);
1050 tree elem_size = TYPE_SIZE (elemtype);
1051 gcc_assert (elem_size && tree_fits_shwi_p (elem_size));
1052 HOST_WIDE_INT el_size = tree_to_shwi (elem_size);
1053 gcc_assert (el_size > 0);
1055 tree minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (decl_type));
1056 gcc_assert (TREE_CODE (minidx) == INTEGER_CST);
1057 tree maxidx = TYPE_MAX_VALUE (TYPE_DOMAIN (decl_type));
1058 /* Skip (some) zero-length arrays; others have MAXIDX == MINIDX - 1. */
1059 if (maxidx)
1061 gcc_assert (TREE_CODE (maxidx) == INTEGER_CST);
1062 tree domain = TYPE_DOMAIN (decl_type);
1063 /* MINIDX and MAXIDX are inclusive, and must be interpreted in
1064 DOMAIN (e.g. signed int, whereas min/max may be size_int). */
1065 offset_int idx = wi::to_offset (minidx);
1066 offset_int max = wi::to_offset (maxidx);
1067 if (!TYPE_UNSIGNED (domain))
1069 idx = wi::sext (idx, TYPE_PRECISION (domain));
1070 max = wi::sext (max, TYPE_PRECISION (domain));
1072 for (int el_off = offset; idx <= max; ++idx)
1074 tree nref = build4 (ARRAY_REF, elemtype,
1075 ref,
1076 wide_int_to_tree (domain, idx),
1077 NULL_TREE, NULL_TREE);
1078 scalarize_elem (base, el_off, el_size,
1079 TYPE_REVERSE_STORAGE_ORDER (decl_type),
1080 nref, elemtype);
1081 el_off += el_size;
1085 break;
1086 default:
1087 gcc_unreachable ();
1091 /* Create total_scalarization accesses for a member of type TYPE, which must
1092 satisfy either is_gimple_reg_type or scalarizable_type_p. BASE must be the
1093 top-most VAR_DECL representing the variable; within that, POS and SIZE locate
1094 the member, REVERSE gives its torage order. and REF must be the reference
1095 expression for it. */
1097 static void
1098 scalarize_elem (tree base, HOST_WIDE_INT pos, HOST_WIDE_INT size, bool reverse,
1099 tree ref, tree type)
1101 if (is_gimple_reg_type (type))
1103 struct access *access = create_access_1 (base, pos, size);
1104 access->expr = ref;
1105 access->type = type;
1106 access->grp_total_scalarization = 1;
1107 access->reverse = reverse;
1108 /* Accesses for intraprocedural SRA can have their stmt NULL. */
1110 else
1111 completely_scalarize (base, type, pos, ref);
1114 /* Create a total_scalarization access for VAR as a whole. VAR must be of a
1115 RECORD_TYPE or ARRAY_TYPE conforming to scalarizable_type_p. */
1117 static void
1118 create_total_scalarization_access (tree var)
1120 HOST_WIDE_INT size = tree_to_uhwi (DECL_SIZE (var));
1121 struct access *access;
1123 access = create_access_1 (var, 0, size);
1124 access->expr = var;
1125 access->type = TREE_TYPE (var);
1126 access->grp_total_scalarization = 1;
1129 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1131 static inline bool
1132 contains_view_convert_expr_p (const_tree ref)
1134 while (handled_component_p (ref))
1136 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
1137 return true;
1138 ref = TREE_OPERAND (ref, 0);
1141 return false;
1144 /* Return true if REF contains a VIEW_CONVERT_EXPR or a MEM_REF that performs
1145 type conversion or a COMPONENT_REF with a bit-field field declaration. */
1147 static bool
1148 contains_vce_or_bfcref_p (const_tree ref)
1150 while (handled_component_p (ref))
1152 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
1153 || (TREE_CODE (ref) == COMPONENT_REF
1154 && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
1155 return true;
1156 ref = TREE_OPERAND (ref, 0);
1159 if (TREE_CODE (ref) != MEM_REF
1160 || TREE_CODE (TREE_OPERAND (ref, 0)) != ADDR_EXPR)
1161 return false;
1163 tree mem = TREE_OPERAND (TREE_OPERAND (ref, 0), 0);
1164 if (TYPE_MAIN_VARIANT (TREE_TYPE (ref))
1165 != TYPE_MAIN_VARIANT (TREE_TYPE (mem)))
1166 return true;
1168 return false;
1171 /* Search the given tree for a declaration by skipping handled components and
1172 exclude it from the candidates. */
1174 static void
1175 disqualify_base_of_expr (tree t, const char *reason)
1177 t = get_base_address (t);
1178 if (sra_mode == SRA_MODE_EARLY_IPA
1179 && TREE_CODE (t) == MEM_REF)
1180 t = get_ssa_base_param (TREE_OPERAND (t, 0));
1182 if (t && DECL_P (t))
1183 disqualify_candidate (t, reason);
1186 /* Scan expression EXPR and create access structures for all accesses to
1187 candidates for scalarization. Return the created access or NULL if none is
1188 created. */
1190 static struct access *
1191 build_access_from_expr_1 (tree expr, gimple *stmt, bool write)
1193 struct access *ret = NULL;
1194 bool partial_ref;
1196 if (TREE_CODE (expr) == BIT_FIELD_REF
1197 || TREE_CODE (expr) == IMAGPART_EXPR
1198 || TREE_CODE (expr) == REALPART_EXPR)
1200 expr = TREE_OPERAND (expr, 0);
1201 partial_ref = true;
1203 else
1204 partial_ref = false;
1206 if (storage_order_barrier_p (expr))
1208 disqualify_base_of_expr (expr, "storage order barrier.");
1209 return NULL;
1212 /* We need to dive through V_C_Es in order to get the size of its parameter
1213 and not the result type. Ada produces such statements. We are also
1214 capable of handling the topmost V_C_E but not any of those buried in other
1215 handled components. */
1216 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
1217 expr = TREE_OPERAND (expr, 0);
1219 if (contains_view_convert_expr_p (expr))
1221 disqualify_base_of_expr (expr, "V_C_E under a different handled "
1222 "component.");
1223 return NULL;
1225 if (TREE_THIS_VOLATILE (expr))
1227 disqualify_base_of_expr (expr, "part of a volatile reference.");
1228 return NULL;
1231 switch (TREE_CODE (expr))
1233 case MEM_REF:
1234 if (TREE_CODE (TREE_OPERAND (expr, 0)) != ADDR_EXPR
1235 && sra_mode != SRA_MODE_EARLY_IPA)
1236 return NULL;
1237 /* fall through */
1238 case VAR_DECL:
1239 case PARM_DECL:
1240 case RESULT_DECL:
1241 case COMPONENT_REF:
1242 case ARRAY_REF:
1243 case ARRAY_RANGE_REF:
1244 ret = create_access (expr, stmt, write);
1245 break;
1247 default:
1248 break;
1251 if (write && partial_ref && ret)
1252 ret->grp_partial_lhs = 1;
1254 return ret;
1257 /* Scan expression EXPR and create access structures for all accesses to
1258 candidates for scalarization. Return true if any access has been inserted.
1259 STMT must be the statement from which the expression is taken, WRITE must be
1260 true if the expression is a store and false otherwise. */
1262 static bool
1263 build_access_from_expr (tree expr, gimple *stmt, bool write)
1265 struct access *access;
1267 access = build_access_from_expr_1 (expr, stmt, write);
1268 if (access)
1270 /* This means the aggregate is accesses as a whole in a way other than an
1271 assign statement and thus cannot be removed even if we had a scalar
1272 replacement for everything. */
1273 if (cannot_scalarize_away_bitmap)
1274 bitmap_set_bit (cannot_scalarize_away_bitmap, DECL_UID (access->base));
1275 return true;
1277 return false;
1280 /* Return the single non-EH successor edge of BB or NULL if there is none or
1281 more than one. */
1283 static edge
1284 single_non_eh_succ (basic_block bb)
1286 edge e, res = NULL;
1287 edge_iterator ei;
1289 FOR_EACH_EDGE (e, ei, bb->succs)
1290 if (!(e->flags & EDGE_EH))
1292 if (res)
1293 return NULL;
1294 res = e;
1297 return res;
1300 /* Disqualify LHS and RHS for scalarization if STMT has to terminate its BB and
1301 there is no alternative spot where to put statements SRA might need to
1302 generate after it. The spot we are looking for is an edge leading to a
1303 single non-EH successor, if it exists and is indeed single. RHS may be
1304 NULL, in that case ignore it. */
1306 static bool
1307 disqualify_if_bad_bb_terminating_stmt (gimple *stmt, tree lhs, tree rhs)
1309 if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1310 && stmt_ends_bb_p (stmt))
1312 if (single_non_eh_succ (gimple_bb (stmt)))
1313 return false;
1315 disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
1316 if (rhs)
1317 disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
1318 return true;
1320 return false;
1323 /* Return true if the nature of BASE is such that it contains data even if
1324 there is no write to it in the function. */
1326 static bool
1327 comes_initialized_p (tree base)
1329 return TREE_CODE (base) == PARM_DECL || constant_decl_p (base);
1332 /* Scan expressions occurring in STMT, create access structures for all accesses
1333 to candidates for scalarization and remove those candidates which occur in
1334 statements or expressions that prevent them from being split apart. Return
1335 true if any access has been inserted. */
1337 static bool
1338 build_accesses_from_assign (gimple *stmt)
1340 tree lhs, rhs;
1341 struct access *lacc, *racc;
1343 if (!gimple_assign_single_p (stmt)
1344 /* Scope clobbers don't influence scalarization. */
1345 || gimple_clobber_p (stmt))
1346 return false;
1348 lhs = gimple_assign_lhs (stmt);
1349 rhs = gimple_assign_rhs1 (stmt);
1351 if (disqualify_if_bad_bb_terminating_stmt (stmt, lhs, rhs))
1352 return false;
1354 racc = build_access_from_expr_1 (rhs, stmt, false);
1355 lacc = build_access_from_expr_1 (lhs, stmt, true);
1357 if (lacc)
1359 lacc->grp_assignment_write = 1;
1360 if (storage_order_barrier_p (rhs))
1361 lacc->grp_unscalarizable_region = 1;
1364 if (racc)
1366 racc->grp_assignment_read = 1;
1367 if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
1368 && !is_gimple_reg_type (racc->type))
1370 if (contains_vce_or_bfcref_p (rhs))
1371 bitmap_set_bit (cannot_scalarize_away_bitmap,
1372 DECL_UID (racc->base));
1373 else
1374 bitmap_set_bit (should_scalarize_away_bitmap,
1375 DECL_UID (racc->base));
1377 if (storage_order_barrier_p (lhs))
1378 racc->grp_unscalarizable_region = 1;
1381 if (lacc && racc
1382 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1383 && !lacc->grp_unscalarizable_region
1384 && !racc->grp_unscalarizable_region
1385 && AGGREGATE_TYPE_P (TREE_TYPE (lhs))
1386 && lacc->size == racc->size
1387 && useless_type_conversion_p (lacc->type, racc->type))
1389 struct assign_link *link;
1391 link = assign_link_pool.allocate ();
1392 memset (link, 0, sizeof (struct assign_link));
1394 link->lacc = lacc;
1395 link->racc = racc;
1396 add_link_to_rhs (racc, link);
1397 add_access_to_work_queue (racc);
1399 /* Let's delay marking the areas as written until propagation of accesses
1400 across link, unless the nature of rhs tells us that its data comes
1401 from elsewhere. */
1402 if (!comes_initialized_p (racc->base))
1403 lacc->write = false;
1406 return lacc || racc;
1409 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1410 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1412 static bool
1413 asm_visit_addr (gimple *, tree op, tree, void *)
1415 op = get_base_address (op);
1416 if (op
1417 && DECL_P (op))
1418 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
1420 return false;
1423 /* Return true iff callsite CALL has at least as many actual arguments as there
1424 are formal parameters of the function currently processed by IPA-SRA and
1425 that their types match. */
1427 static inline bool
1428 callsite_arguments_match_p (gimple *call)
1430 if (gimple_call_num_args (call) < (unsigned) func_param_count)
1431 return false;
1433 tree parm;
1434 int i;
1435 for (parm = DECL_ARGUMENTS (current_function_decl), i = 0;
1436 parm;
1437 parm = DECL_CHAIN (parm), i++)
1439 tree arg = gimple_call_arg (call, i);
1440 if (!useless_type_conversion_p (TREE_TYPE (parm), TREE_TYPE (arg)))
1441 return false;
1443 return true;
1446 /* Scan function and look for interesting expressions and create access
1447 structures for them. Return true iff any access is created. */
1449 static bool
1450 scan_function (void)
1452 basic_block bb;
1453 bool ret = false;
1455 FOR_EACH_BB_FN (bb, cfun)
1457 gimple_stmt_iterator gsi;
1458 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1460 gimple *stmt = gsi_stmt (gsi);
1461 tree t;
1462 unsigned i;
1464 if (final_bbs && stmt_can_throw_external (stmt))
1465 bitmap_set_bit (final_bbs, bb->index);
1466 switch (gimple_code (stmt))
1468 case GIMPLE_RETURN:
1469 t = gimple_return_retval (as_a <greturn *> (stmt));
1470 if (t != NULL_TREE)
1471 ret |= build_access_from_expr (t, stmt, false);
1472 if (final_bbs)
1473 bitmap_set_bit (final_bbs, bb->index);
1474 break;
1476 case GIMPLE_ASSIGN:
1477 ret |= build_accesses_from_assign (stmt);
1478 break;
1480 case GIMPLE_CALL:
1481 for (i = 0; i < gimple_call_num_args (stmt); i++)
1482 ret |= build_access_from_expr (gimple_call_arg (stmt, i),
1483 stmt, false);
1485 if (sra_mode == SRA_MODE_EARLY_IPA)
1487 tree dest = gimple_call_fndecl (stmt);
1488 int flags = gimple_call_flags (stmt);
1490 if (dest)
1492 if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1493 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1494 encountered_apply_args = true;
1495 if (recursive_call_p (current_function_decl, dest))
1497 encountered_recursive_call = true;
1498 if (!callsite_arguments_match_p (stmt))
1499 encountered_unchangable_recursive_call = true;
1503 if (final_bbs
1504 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1505 bitmap_set_bit (final_bbs, bb->index);
1508 t = gimple_call_lhs (stmt);
1509 if (t && !disqualify_if_bad_bb_terminating_stmt (stmt, t, NULL))
1510 ret |= build_access_from_expr (t, stmt, true);
1511 break;
1513 case GIMPLE_ASM:
1515 gasm *asm_stmt = as_a <gasm *> (stmt);
1516 walk_stmt_load_store_addr_ops (asm_stmt, NULL, NULL, NULL,
1517 asm_visit_addr);
1518 if (final_bbs)
1519 bitmap_set_bit (final_bbs, bb->index);
1521 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
1523 t = TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
1524 ret |= build_access_from_expr (t, asm_stmt, false);
1526 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
1528 t = TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
1529 ret |= build_access_from_expr (t, asm_stmt, true);
1532 break;
1534 default:
1535 break;
1540 return ret;
1543 /* Helper of QSORT function. There are pointers to accesses in the array. An
1544 access is considered smaller than another if it has smaller offset or if the
1545 offsets are the same but is size is bigger. */
1547 static int
1548 compare_access_positions (const void *a, const void *b)
1550 const access_p *fp1 = (const access_p *) a;
1551 const access_p *fp2 = (const access_p *) b;
1552 const access_p f1 = *fp1;
1553 const access_p f2 = *fp2;
1555 if (f1->offset != f2->offset)
1556 return f1->offset < f2->offset ? -1 : 1;
1558 if (f1->size == f2->size)
1560 if (f1->type == f2->type)
1561 return 0;
1562 /* Put any non-aggregate type before any aggregate type. */
1563 else if (!is_gimple_reg_type (f1->type)
1564 && is_gimple_reg_type (f2->type))
1565 return 1;
1566 else if (is_gimple_reg_type (f1->type)
1567 && !is_gimple_reg_type (f2->type))
1568 return -1;
1569 /* Put any complex or vector type before any other scalar type. */
1570 else if (TREE_CODE (f1->type) != COMPLEX_TYPE
1571 && TREE_CODE (f1->type) != VECTOR_TYPE
1572 && (TREE_CODE (f2->type) == COMPLEX_TYPE
1573 || TREE_CODE (f2->type) == VECTOR_TYPE))
1574 return 1;
1575 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
1576 || TREE_CODE (f1->type) == VECTOR_TYPE)
1577 && TREE_CODE (f2->type) != COMPLEX_TYPE
1578 && TREE_CODE (f2->type) != VECTOR_TYPE)
1579 return -1;
1580 /* Put any integral type before any non-integral type. When splicing, we
1581 make sure that those with insufficient precision and occupying the
1582 same space are not scalarized. */
1583 else if (INTEGRAL_TYPE_P (f1->type)
1584 && !INTEGRAL_TYPE_P (f2->type))
1585 return -1;
1586 else if (!INTEGRAL_TYPE_P (f1->type)
1587 && INTEGRAL_TYPE_P (f2->type))
1588 return 1;
1589 /* Put the integral type with the bigger precision first. */
1590 else if (INTEGRAL_TYPE_P (f1->type)
1591 && INTEGRAL_TYPE_P (f2->type)
1592 && (TYPE_PRECISION (f2->type) != TYPE_PRECISION (f1->type)))
1593 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
1594 /* Stabilize the sort. */
1595 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1598 /* We want the bigger accesses first, thus the opposite operator in the next
1599 line: */
1600 return f1->size > f2->size ? -1 : 1;
1604 /* Append a name of the declaration to the name obstack. A helper function for
1605 make_fancy_name. */
1607 static void
1608 make_fancy_decl_name (tree decl)
1610 char buffer[32];
1612 tree name = DECL_NAME (decl);
1613 if (name)
1614 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1615 IDENTIFIER_LENGTH (name));
1616 else
1618 sprintf (buffer, "D%u", DECL_UID (decl));
1619 obstack_grow (&name_obstack, buffer, strlen (buffer));
1623 /* Helper for make_fancy_name. */
1625 static void
1626 make_fancy_name_1 (tree expr)
1628 char buffer[32];
1629 tree index;
1631 if (DECL_P (expr))
1633 make_fancy_decl_name (expr);
1634 return;
1637 switch (TREE_CODE (expr))
1639 case COMPONENT_REF:
1640 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1641 obstack_1grow (&name_obstack, '$');
1642 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1643 break;
1645 case ARRAY_REF:
1646 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1647 obstack_1grow (&name_obstack, '$');
1648 /* Arrays with only one element may not have a constant as their
1649 index. */
1650 index = TREE_OPERAND (expr, 1);
1651 if (TREE_CODE (index) != INTEGER_CST)
1652 break;
1653 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1654 obstack_grow (&name_obstack, buffer, strlen (buffer));
1655 break;
1657 case ADDR_EXPR:
1658 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1659 break;
1661 case MEM_REF:
1662 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1663 if (!integer_zerop (TREE_OPERAND (expr, 1)))
1665 obstack_1grow (&name_obstack, '$');
1666 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC,
1667 TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)));
1668 obstack_grow (&name_obstack, buffer, strlen (buffer));
1670 break;
1672 case BIT_FIELD_REF:
1673 case REALPART_EXPR:
1674 case IMAGPART_EXPR:
1675 gcc_unreachable (); /* we treat these as scalars. */
1676 break;
1677 default:
1678 break;
1682 /* Create a human readable name for replacement variable of ACCESS. */
1684 static char *
1685 make_fancy_name (tree expr)
1687 make_fancy_name_1 (expr);
1688 obstack_1grow (&name_obstack, '\0');
1689 return XOBFINISH (&name_obstack, char *);
1692 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1693 EXP_TYPE at the given OFFSET and with storage order REVERSE. If BASE is
1694 something for which get_addr_base_and_unit_offset returns NULL, gsi must
1695 be non-NULL and is used to insert new statements either before or below
1696 the current one as specified by INSERT_AFTER. This function is not capable
1697 of handling bitfields. */
1699 tree
1700 build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
1701 bool reverse, tree exp_type, gimple_stmt_iterator *gsi,
1702 bool insert_after)
1704 tree prev_base = base;
1705 tree off;
1706 tree mem_ref;
1707 HOST_WIDE_INT base_offset;
1708 unsigned HOST_WIDE_INT misalign;
1709 unsigned int align;
1711 /* Preserve address-space information. */
1712 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (base));
1713 if (as != TYPE_ADDR_SPACE (exp_type))
1714 exp_type = build_qualified_type (exp_type,
1715 TYPE_QUALS (exp_type)
1716 | ENCODE_QUAL_ADDR_SPACE (as));
1718 gcc_checking_assert (offset % BITS_PER_UNIT == 0);
1719 get_object_alignment_1 (base, &align, &misalign);
1720 base = get_addr_base_and_unit_offset (base, &base_offset);
1722 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1723 offset such as array[var_index]. */
1724 if (!base)
1726 gassign *stmt;
1727 tree tmp, addr;
1729 gcc_checking_assert (gsi);
1730 tmp = make_ssa_name (build_pointer_type (TREE_TYPE (prev_base)));
1731 addr = build_fold_addr_expr (unshare_expr (prev_base));
1732 STRIP_USELESS_TYPE_CONVERSION (addr);
1733 stmt = gimple_build_assign (tmp, addr);
1734 gimple_set_location (stmt, loc);
1735 if (insert_after)
1736 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
1737 else
1738 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1740 off = build_int_cst (reference_alias_ptr_type (prev_base),
1741 offset / BITS_PER_UNIT);
1742 base = tmp;
1744 else if (TREE_CODE (base) == MEM_REF)
1746 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1747 base_offset + offset / BITS_PER_UNIT);
1748 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1749 base = unshare_expr (TREE_OPERAND (base, 0));
1751 else
1753 off = build_int_cst (reference_alias_ptr_type (prev_base),
1754 base_offset + offset / BITS_PER_UNIT);
1755 base = build_fold_addr_expr (unshare_expr (base));
1758 misalign = (misalign + offset) & (align - 1);
1759 if (misalign != 0)
1760 align = least_bit_hwi (misalign);
1761 if (align != TYPE_ALIGN (exp_type))
1762 exp_type = build_aligned_type (exp_type, align);
1764 mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off);
1765 REF_REVERSE_STORAGE_ORDER (mem_ref) = reverse;
1766 if (TREE_THIS_VOLATILE (prev_base))
1767 TREE_THIS_VOLATILE (mem_ref) = 1;
1768 if (TREE_SIDE_EFFECTS (prev_base))
1769 TREE_SIDE_EFFECTS (mem_ref) = 1;
1770 return mem_ref;
1773 /* Construct a memory reference to a part of an aggregate BASE at the given
1774 OFFSET and of the same type as MODEL. In case this is a reference to a
1775 bit-field, the function will replicate the last component_ref of model's
1776 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1777 build_ref_for_offset. */
1779 static tree
1780 build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1781 struct access *model, gimple_stmt_iterator *gsi,
1782 bool insert_after)
1784 if (TREE_CODE (model->expr) == COMPONENT_REF
1785 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1787 /* This access represents a bit-field. */
1788 tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
1790 offset -= int_bit_position (fld);
1791 exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
1792 t = build_ref_for_offset (loc, base, offset, model->reverse, exp_type,
1793 gsi, insert_after);
1794 /* The flag will be set on the record type. */
1795 REF_REVERSE_STORAGE_ORDER (t) = 0;
1796 return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
1797 NULL_TREE);
1799 else
1800 return
1801 build_ref_for_offset (loc, base, offset, model->reverse, model->type,
1802 gsi, insert_after);
1805 /* Attempt to build a memory reference that we could but into a gimple
1806 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1807 create statements and return s NULL instead. This function also ignores
1808 alignment issues and so its results should never end up in non-debug
1809 statements. */
1811 static tree
1812 build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1813 struct access *model)
1815 HOST_WIDE_INT base_offset;
1816 tree off;
1818 if (TREE_CODE (model->expr) == COMPONENT_REF
1819 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1820 return NULL_TREE;
1822 base = get_addr_base_and_unit_offset (base, &base_offset);
1823 if (!base)
1824 return NULL_TREE;
1825 if (TREE_CODE (base) == MEM_REF)
1827 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1828 base_offset + offset / BITS_PER_UNIT);
1829 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1830 base = unshare_expr (TREE_OPERAND (base, 0));
1832 else
1834 off = build_int_cst (reference_alias_ptr_type (base),
1835 base_offset + offset / BITS_PER_UNIT);
1836 base = build_fold_addr_expr (unshare_expr (base));
1839 return fold_build2_loc (loc, MEM_REF, model->type, base, off);
1842 /* Construct a memory reference consisting of component_refs and array_refs to
1843 a part of an aggregate *RES (which is of type TYPE). The requested part
1844 should have type EXP_TYPE at be the given OFFSET. This function might not
1845 succeed, it returns true when it does and only then *RES points to something
1846 meaningful. This function should be used only to build expressions that we
1847 might need to present to user (e.g. in warnings). In all other situations,
1848 build_ref_for_model or build_ref_for_offset should be used instead. */
1850 static bool
1851 build_user_friendly_ref_for_offset (tree *res, tree type, HOST_WIDE_INT offset,
1852 tree exp_type)
1854 while (1)
1856 tree fld;
1857 tree tr_size, index, minidx;
1858 HOST_WIDE_INT el_size;
1860 if (offset == 0 && exp_type
1861 && types_compatible_p (exp_type, type))
1862 return true;
1864 switch (TREE_CODE (type))
1866 case UNION_TYPE:
1867 case QUAL_UNION_TYPE:
1868 case RECORD_TYPE:
1869 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
1871 HOST_WIDE_INT pos, size;
1872 tree tr_pos, expr, *expr_ptr;
1874 if (TREE_CODE (fld) != FIELD_DECL)
1875 continue;
1877 tr_pos = bit_position (fld);
1878 if (!tr_pos || !tree_fits_uhwi_p (tr_pos))
1879 continue;
1880 pos = tree_to_uhwi (tr_pos);
1881 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1882 tr_size = DECL_SIZE (fld);
1883 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1884 continue;
1885 size = tree_to_uhwi (tr_size);
1886 if (size == 0)
1888 if (pos != offset)
1889 continue;
1891 else if (pos > offset || (pos + size) <= offset)
1892 continue;
1894 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1895 NULL_TREE);
1896 expr_ptr = &expr;
1897 if (build_user_friendly_ref_for_offset (expr_ptr, TREE_TYPE (fld),
1898 offset - pos, exp_type))
1900 *res = expr;
1901 return true;
1904 return false;
1906 case ARRAY_TYPE:
1907 tr_size = TYPE_SIZE (TREE_TYPE (type));
1908 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1909 return false;
1910 el_size = tree_to_uhwi (tr_size);
1912 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1913 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
1914 return false;
1915 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1916 if (!integer_zerop (minidx))
1917 index = int_const_binop (PLUS_EXPR, index, minidx);
1918 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1919 NULL_TREE, NULL_TREE);
1920 offset = offset % el_size;
1921 type = TREE_TYPE (type);
1922 break;
1924 default:
1925 if (offset != 0)
1926 return false;
1928 if (exp_type)
1929 return false;
1930 else
1931 return true;
1936 /* Return true iff TYPE is stdarg va_list type. */
1938 static inline bool
1939 is_va_list_type (tree type)
1941 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1944 /* Print message to dump file why a variable was rejected. */
1946 static void
1947 reject (tree var, const char *msg)
1949 if (dump_file && (dump_flags & TDF_DETAILS))
1951 fprintf (dump_file, "Rejected (%d): %s: ", DECL_UID (var), msg);
1952 print_generic_expr (dump_file, var);
1953 fprintf (dump_file, "\n");
1957 /* Return true if VAR is a candidate for SRA. */
1959 static bool
1960 maybe_add_sra_candidate (tree var)
1962 tree type = TREE_TYPE (var);
1963 const char *msg;
1964 tree_node **slot;
1966 if (!AGGREGATE_TYPE_P (type))
1968 reject (var, "not aggregate");
1969 return false;
1971 /* Allow constant-pool entries (that "need to live in memory")
1972 unless we are doing IPA SRA. */
1973 if (needs_to_live_in_memory (var)
1974 && (sra_mode == SRA_MODE_EARLY_IPA || !constant_decl_p (var)))
1976 reject (var, "needs to live in memory");
1977 return false;
1979 if (TREE_THIS_VOLATILE (var))
1981 reject (var, "is volatile");
1982 return false;
1984 if (!COMPLETE_TYPE_P (type))
1986 reject (var, "has incomplete type");
1987 return false;
1989 if (!tree_fits_uhwi_p (TYPE_SIZE (type)))
1991 reject (var, "type size not fixed");
1992 return false;
1994 if (tree_to_uhwi (TYPE_SIZE (type)) == 0)
1996 reject (var, "type size is zero");
1997 return false;
1999 if (type_internals_preclude_sra_p (type, &msg))
2001 reject (var, msg);
2002 return false;
2004 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
2005 we also want to schedule it rather late. Thus we ignore it in
2006 the early pass. */
2007 (sra_mode == SRA_MODE_EARLY_INTRA
2008 && is_va_list_type (type)))
2010 reject (var, "is va_list");
2011 return false;
2014 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
2015 slot = candidates->find_slot_with_hash (var, DECL_UID (var), INSERT);
2016 *slot = var;
2018 if (dump_file && (dump_flags & TDF_DETAILS))
2020 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
2021 print_generic_expr (dump_file, var);
2022 fprintf (dump_file, "\n");
2025 return true;
2028 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
2029 those with type which is suitable for scalarization. */
2031 static bool
2032 find_var_candidates (void)
2034 tree var, parm;
2035 unsigned int i;
2036 bool ret = false;
2038 for (parm = DECL_ARGUMENTS (current_function_decl);
2039 parm;
2040 parm = DECL_CHAIN (parm))
2041 ret |= maybe_add_sra_candidate (parm);
2043 FOR_EACH_LOCAL_DECL (cfun, i, var)
2045 if (!VAR_P (var))
2046 continue;
2048 ret |= maybe_add_sra_candidate (var);
2051 return ret;
2054 /* Sort all accesses for the given variable, check for partial overlaps and
2055 return NULL if there are any. If there are none, pick a representative for
2056 each combination of offset and size and create a linked list out of them.
2057 Return the pointer to the first representative and make sure it is the first
2058 one in the vector of accesses. */
2060 static struct access *
2061 sort_and_splice_var_accesses (tree var)
2063 int i, j, access_count;
2064 struct access *res, **prev_acc_ptr = &res;
2065 vec<access_p> *access_vec;
2066 bool first = true;
2067 HOST_WIDE_INT low = -1, high = 0;
2069 access_vec = get_base_access_vector (var);
2070 if (!access_vec)
2071 return NULL;
2072 access_count = access_vec->length ();
2074 /* Sort by <OFFSET, SIZE>. */
2075 access_vec->qsort (compare_access_positions);
2077 i = 0;
2078 while (i < access_count)
2080 struct access *access = (*access_vec)[i];
2081 bool grp_write = access->write;
2082 bool grp_read = !access->write;
2083 bool grp_scalar_write = access->write
2084 && is_gimple_reg_type (access->type);
2085 bool grp_scalar_read = !access->write
2086 && is_gimple_reg_type (access->type);
2087 bool grp_assignment_read = access->grp_assignment_read;
2088 bool grp_assignment_write = access->grp_assignment_write;
2089 bool multiple_scalar_reads = false;
2090 bool total_scalarization = access->grp_total_scalarization;
2091 bool grp_partial_lhs = access->grp_partial_lhs;
2092 bool first_scalar = is_gimple_reg_type (access->type);
2093 bool unscalarizable_region = access->grp_unscalarizable_region;
2094 bool bf_non_full_precision
2095 = (INTEGRAL_TYPE_P (access->type)
2096 && TYPE_PRECISION (access->type) != access->size
2097 && TREE_CODE (access->expr) == COMPONENT_REF
2098 && DECL_BIT_FIELD (TREE_OPERAND (access->expr, 1)));
2100 if (first || access->offset >= high)
2102 first = false;
2103 low = access->offset;
2104 high = access->offset + access->size;
2106 else if (access->offset > low && access->offset + access->size > high)
2107 return NULL;
2108 else
2109 gcc_assert (access->offset >= low
2110 && access->offset + access->size <= high);
2112 j = i + 1;
2113 while (j < access_count)
2115 struct access *ac2 = (*access_vec)[j];
2116 if (ac2->offset != access->offset || ac2->size != access->size)
2117 break;
2118 if (ac2->write)
2120 grp_write = true;
2121 grp_scalar_write = (grp_scalar_write
2122 || is_gimple_reg_type (ac2->type));
2124 else
2126 grp_read = true;
2127 if (is_gimple_reg_type (ac2->type))
2129 if (grp_scalar_read)
2130 multiple_scalar_reads = true;
2131 else
2132 grp_scalar_read = true;
2135 grp_assignment_read |= ac2->grp_assignment_read;
2136 grp_assignment_write |= ac2->grp_assignment_write;
2137 grp_partial_lhs |= ac2->grp_partial_lhs;
2138 unscalarizable_region |= ac2->grp_unscalarizable_region;
2139 total_scalarization |= ac2->grp_total_scalarization;
2140 relink_to_new_repr (access, ac2);
2142 /* If there are both aggregate-type and scalar-type accesses with
2143 this combination of size and offset, the comparison function
2144 should have put the scalars first. */
2145 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
2146 /* It also prefers integral types to non-integral. However, when the
2147 precision of the selected type does not span the entire area and
2148 should also be used for a non-integer (i.e. float), we must not
2149 let that happen. Normally analyze_access_subtree expands the type
2150 to cover the entire area but for bit-fields it doesn't. */
2151 if (bf_non_full_precision && !INTEGRAL_TYPE_P (ac2->type))
2153 if (dump_file && (dump_flags & TDF_DETAILS))
2155 fprintf (dump_file, "Cannot scalarize the following access "
2156 "because insufficient precision integer type was "
2157 "selected.\n ");
2158 dump_access (dump_file, access, false);
2160 unscalarizable_region = true;
2162 ac2->group_representative = access;
2163 j++;
2166 i = j;
2168 access->group_representative = access;
2169 access->grp_write = grp_write;
2170 access->grp_read = grp_read;
2171 access->grp_scalar_read = grp_scalar_read;
2172 access->grp_scalar_write = grp_scalar_write;
2173 access->grp_assignment_read = grp_assignment_read;
2174 access->grp_assignment_write = grp_assignment_write;
2175 access->grp_hint = total_scalarization
2176 || (multiple_scalar_reads && !constant_decl_p (var));
2177 access->grp_total_scalarization = total_scalarization;
2178 access->grp_partial_lhs = grp_partial_lhs;
2179 access->grp_unscalarizable_region = unscalarizable_region;
2181 *prev_acc_ptr = access;
2182 prev_acc_ptr = &access->next_grp;
2185 gcc_assert (res == (*access_vec)[0]);
2186 return res;
2189 /* Create a variable for the given ACCESS which determines the type, name and a
2190 few other properties. Return the variable declaration and store it also to
2191 ACCESS->replacement. */
2193 static tree
2194 create_access_replacement (struct access *access)
2196 tree repl;
2198 if (access->grp_to_be_debug_replaced)
2200 repl = create_tmp_var_raw (access->type);
2201 DECL_CONTEXT (repl) = current_function_decl;
2203 else
2204 /* Drop any special alignment on the type if it's not on the main
2205 variant. This avoids issues with weirdo ABIs like AAPCS. */
2206 repl = create_tmp_var (build_qualified_type
2207 (TYPE_MAIN_VARIANT (access->type),
2208 TYPE_QUALS (access->type)), "SR");
2209 if (TREE_CODE (access->type) == COMPLEX_TYPE
2210 || TREE_CODE (access->type) == VECTOR_TYPE)
2212 if (!access->grp_partial_lhs)
2213 DECL_GIMPLE_REG_P (repl) = 1;
2215 else if (access->grp_partial_lhs
2216 && is_gimple_reg_type (access->type))
2217 TREE_ADDRESSABLE (repl) = 1;
2219 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
2220 DECL_ARTIFICIAL (repl) = 1;
2221 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
2223 if (DECL_NAME (access->base)
2224 && !DECL_IGNORED_P (access->base)
2225 && !DECL_ARTIFICIAL (access->base))
2227 char *pretty_name = make_fancy_name (access->expr);
2228 tree debug_expr = unshare_expr_without_location (access->expr), d;
2229 bool fail = false;
2231 DECL_NAME (repl) = get_identifier (pretty_name);
2232 DECL_NAMELESS (repl) = 1;
2233 obstack_free (&name_obstack, pretty_name);
2235 /* Get rid of any SSA_NAMEs embedded in debug_expr,
2236 as DECL_DEBUG_EXPR isn't considered when looking for still
2237 used SSA_NAMEs and thus they could be freed. All debug info
2238 generation cares is whether something is constant or variable
2239 and that get_ref_base_and_extent works properly on the
2240 expression. It cannot handle accesses at a non-constant offset
2241 though, so just give up in those cases. */
2242 for (d = debug_expr;
2243 !fail && (handled_component_p (d) || TREE_CODE (d) == MEM_REF);
2244 d = TREE_OPERAND (d, 0))
2245 switch (TREE_CODE (d))
2247 case ARRAY_REF:
2248 case ARRAY_RANGE_REF:
2249 if (TREE_OPERAND (d, 1)
2250 && TREE_CODE (TREE_OPERAND (d, 1)) != INTEGER_CST)
2251 fail = true;
2252 if (TREE_OPERAND (d, 3)
2253 && TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST)
2254 fail = true;
2255 /* FALLTHRU */
2256 case COMPONENT_REF:
2257 if (TREE_OPERAND (d, 2)
2258 && TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST)
2259 fail = true;
2260 break;
2261 case MEM_REF:
2262 if (TREE_CODE (TREE_OPERAND (d, 0)) != ADDR_EXPR)
2263 fail = true;
2264 else
2265 d = TREE_OPERAND (d, 0);
2266 break;
2267 default:
2268 break;
2270 if (!fail)
2272 SET_DECL_DEBUG_EXPR (repl, debug_expr);
2273 DECL_HAS_DEBUG_EXPR_P (repl) = 1;
2275 if (access->grp_no_warning)
2276 TREE_NO_WARNING (repl) = 1;
2277 else
2278 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
2280 else
2281 TREE_NO_WARNING (repl) = 1;
2283 if (dump_file)
2285 if (access->grp_to_be_debug_replaced)
2287 fprintf (dump_file, "Created a debug-only replacement for ");
2288 print_generic_expr (dump_file, access->base);
2289 fprintf (dump_file, " offset: %u, size: %u\n",
2290 (unsigned) access->offset, (unsigned) access->size);
2292 else
2294 fprintf (dump_file, "Created a replacement for ");
2295 print_generic_expr (dump_file, access->base);
2296 fprintf (dump_file, " offset: %u, size: %u: ",
2297 (unsigned) access->offset, (unsigned) access->size);
2298 print_generic_expr (dump_file, repl);
2299 fprintf (dump_file, "\n");
2302 sra_stats.replacements++;
2304 return repl;
2307 /* Return ACCESS scalar replacement, which must exist. */
2309 static inline tree
2310 get_access_replacement (struct access *access)
2312 gcc_checking_assert (access->replacement_decl);
2313 return access->replacement_decl;
2317 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2318 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2319 to it is not "within" the root. Return false iff some accesses partially
2320 overlap. */
2322 static bool
2323 build_access_subtree (struct access **access)
2325 struct access *root = *access, *last_child = NULL;
2326 HOST_WIDE_INT limit = root->offset + root->size;
2328 *access = (*access)->next_grp;
2329 while (*access && (*access)->offset + (*access)->size <= limit)
2331 if (!last_child)
2332 root->first_child = *access;
2333 else
2334 last_child->next_sibling = *access;
2335 last_child = *access;
2336 (*access)->parent = root;
2337 (*access)->grp_write |= root->grp_write;
2339 if (!build_access_subtree (access))
2340 return false;
2343 if (*access && (*access)->offset < limit)
2344 return false;
2346 return true;
2349 /* Build a tree of access representatives, ACCESS is the pointer to the first
2350 one, others are linked in a list by the next_grp field. Return false iff
2351 some accesses partially overlap. */
2353 static bool
2354 build_access_trees (struct access *access)
2356 while (access)
2358 struct access *root = access;
2360 if (!build_access_subtree (&access))
2361 return false;
2362 root->next_grp = access;
2364 return true;
2367 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2368 array. */
2370 static bool
2371 expr_with_var_bounded_array_refs_p (tree expr)
2373 while (handled_component_p (expr))
2375 if (TREE_CODE (expr) == ARRAY_REF
2376 && !tree_fits_shwi_p (array_ref_low_bound (expr)))
2377 return true;
2378 expr = TREE_OPERAND (expr, 0);
2380 return false;
2383 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2384 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2385 sorts of access flags appropriately along the way, notably always set
2386 grp_read and grp_assign_read according to MARK_READ and grp_write when
2387 MARK_WRITE is true.
2389 Creating a replacement for a scalar access is considered beneficial if its
2390 grp_hint is set (this means we are either attempting total scalarization or
2391 there is more than one direct read access) or according to the following
2392 table:
2394 Access written to through a scalar type (once or more times)
2396 | Written to in an assignment statement
2398 | | Access read as scalar _once_
2399 | | |
2400 | | | Read in an assignment statement
2401 | | | |
2402 | | | | Scalarize Comment
2403 -----------------------------------------------------------------------------
2404 0 0 0 0 No access for the scalar
2405 0 0 0 1 No access for the scalar
2406 0 0 1 0 No Single read - won't help
2407 0 0 1 1 No The same case
2408 0 1 0 0 No access for the scalar
2409 0 1 0 1 No access for the scalar
2410 0 1 1 0 Yes s = *g; return s.i;
2411 0 1 1 1 Yes The same case as above
2412 1 0 0 0 No Won't help
2413 1 0 0 1 Yes s.i = 1; *g = s;
2414 1 0 1 0 Yes s.i = 5; g = s.i;
2415 1 0 1 1 Yes The same case as above
2416 1 1 0 0 No Won't help.
2417 1 1 0 1 Yes s.i = 1; *g = s;
2418 1 1 1 0 Yes s = *g; return s.i;
2419 1 1 1 1 Yes Any of the above yeses */
2421 static bool
2422 analyze_access_subtree (struct access *root, struct access *parent,
2423 bool allow_replacements)
2425 struct access *child;
2426 HOST_WIDE_INT limit = root->offset + root->size;
2427 HOST_WIDE_INT covered_to = root->offset;
2428 bool scalar = is_gimple_reg_type (root->type);
2429 bool hole = false, sth_created = false;
2431 if (parent)
2433 if (parent->grp_read)
2434 root->grp_read = 1;
2435 if (parent->grp_assignment_read)
2436 root->grp_assignment_read = 1;
2437 if (parent->grp_write)
2438 root->grp_write = 1;
2439 if (parent->grp_assignment_write)
2440 root->grp_assignment_write = 1;
2441 if (parent->grp_total_scalarization)
2442 root->grp_total_scalarization = 1;
2445 if (root->grp_unscalarizable_region)
2446 allow_replacements = false;
2448 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
2449 allow_replacements = false;
2451 for (child = root->first_child; child; child = child->next_sibling)
2453 hole |= covered_to < child->offset;
2454 sth_created |= analyze_access_subtree (child, root,
2455 allow_replacements && !scalar);
2457 root->grp_unscalarized_data |= child->grp_unscalarized_data;
2458 root->grp_total_scalarization &= child->grp_total_scalarization;
2459 if (child->grp_covered)
2460 covered_to += child->size;
2461 else
2462 hole = true;
2465 if (allow_replacements && scalar && !root->first_child
2466 && (root->grp_hint
2467 || ((root->grp_scalar_read || root->grp_assignment_read)
2468 && (root->grp_scalar_write || root->grp_assignment_write))))
2470 /* Always create access replacements that cover the whole access.
2471 For integral types this means the precision has to match.
2472 Avoid assumptions based on the integral type kind, too. */
2473 if (INTEGRAL_TYPE_P (root->type)
2474 && (TREE_CODE (root->type) != INTEGER_TYPE
2475 || TYPE_PRECISION (root->type) != root->size)
2476 /* But leave bitfield accesses alone. */
2477 && (TREE_CODE (root->expr) != COMPONENT_REF
2478 || !DECL_BIT_FIELD (TREE_OPERAND (root->expr, 1))))
2480 tree rt = root->type;
2481 gcc_assert ((root->offset % BITS_PER_UNIT) == 0
2482 && (root->size % BITS_PER_UNIT) == 0);
2483 root->type = build_nonstandard_integer_type (root->size,
2484 TYPE_UNSIGNED (rt));
2485 root->expr = build_ref_for_offset (UNKNOWN_LOCATION, root->base,
2486 root->offset, root->reverse,
2487 root->type, NULL, false);
2489 if (dump_file && (dump_flags & TDF_DETAILS))
2491 fprintf (dump_file, "Changing the type of a replacement for ");
2492 print_generic_expr (dump_file, root->base);
2493 fprintf (dump_file, " offset: %u, size: %u ",
2494 (unsigned) root->offset, (unsigned) root->size);
2495 fprintf (dump_file, " to an integer.\n");
2499 root->grp_to_be_replaced = 1;
2500 root->replacement_decl = create_access_replacement (root);
2501 sth_created = true;
2502 hole = false;
2504 else
2506 if (allow_replacements
2507 && scalar && !root->first_child
2508 && (root->grp_scalar_write || root->grp_assignment_write)
2509 && !bitmap_bit_p (cannot_scalarize_away_bitmap,
2510 DECL_UID (root->base)))
2512 gcc_checking_assert (!root->grp_scalar_read
2513 && !root->grp_assignment_read);
2514 sth_created = true;
2515 if (MAY_HAVE_DEBUG_BIND_STMTS)
2517 root->grp_to_be_debug_replaced = 1;
2518 root->replacement_decl = create_access_replacement (root);
2522 if (covered_to < limit)
2523 hole = true;
2524 if (scalar || !allow_replacements)
2525 root->grp_total_scalarization = 0;
2528 if (!hole || root->grp_total_scalarization)
2529 root->grp_covered = 1;
2530 else if (root->grp_write || comes_initialized_p (root->base))
2531 root->grp_unscalarized_data = 1; /* not covered and written to */
2532 return sth_created;
2535 /* Analyze all access trees linked by next_grp by the means of
2536 analyze_access_subtree. */
2537 static bool
2538 analyze_access_trees (struct access *access)
2540 bool ret = false;
2542 while (access)
2544 if (analyze_access_subtree (access, NULL, true))
2545 ret = true;
2546 access = access->next_grp;
2549 return ret;
2552 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2553 SIZE would conflict with an already existing one. If exactly such a child
2554 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2556 static bool
2557 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
2558 HOST_WIDE_INT size, struct access **exact_match)
2560 struct access *child;
2562 for (child = lacc->first_child; child; child = child->next_sibling)
2564 if (child->offset == norm_offset && child->size == size)
2566 *exact_match = child;
2567 return true;
2570 if (child->offset < norm_offset + size
2571 && child->offset + child->size > norm_offset)
2572 return true;
2575 return false;
2578 /* Create a new child access of PARENT, with all properties just like MODEL
2579 except for its offset and with its grp_write false and grp_read true.
2580 Return the new access or NULL if it cannot be created. Note that this
2581 access is created long after all splicing and sorting, it's not located in
2582 any access vector and is automatically a representative of its group. Set
2583 the gpr_write flag of the new accesss if SET_GRP_WRITE is true. */
2585 static struct access *
2586 create_artificial_child_access (struct access *parent, struct access *model,
2587 HOST_WIDE_INT new_offset,
2588 bool set_grp_write)
2590 struct access **child;
2591 tree expr = parent->base;
2593 gcc_assert (!model->grp_unscalarizable_region);
2595 struct access *access = access_pool.allocate ();
2596 memset (access, 0, sizeof (struct access));
2597 if (!build_user_friendly_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
2598 model->type))
2600 access->grp_no_warning = true;
2601 expr = build_ref_for_model (EXPR_LOCATION (parent->base), parent->base,
2602 new_offset, model, NULL, false);
2605 access->base = parent->base;
2606 access->expr = expr;
2607 access->offset = new_offset;
2608 access->size = model->size;
2609 access->type = model->type;
2610 access->grp_write = set_grp_write;
2611 access->grp_read = false;
2612 access->reverse = model->reverse;
2614 child = &parent->first_child;
2615 while (*child && (*child)->offset < new_offset)
2616 child = &(*child)->next_sibling;
2618 access->next_sibling = *child;
2619 *child = access;
2621 return access;
2625 /* Beginning with ACCESS, traverse its whole access subtree and mark all
2626 sub-trees as written to. If any of them has not been marked so previously
2627 and has assignment links leading from it, re-enqueue it. */
2629 static void
2630 subtree_mark_written_and_enqueue (struct access *access)
2632 if (access->grp_write)
2633 return;
2634 access->grp_write = true;
2635 add_access_to_work_queue (access);
2637 struct access *child;
2638 for (child = access->first_child; child; child = child->next_sibling)
2639 subtree_mark_written_and_enqueue (child);
2642 /* Propagate subaccesses and grp_write flags of RACC across an assignment link
2643 to LACC. Enqueue sub-accesses as necessary so that the write flag is
2644 propagated transitively. Return true if anything changed. Additionally, if
2645 RACC is a scalar access but LACC is not, change the type of the latter, if
2646 possible. */
2648 static bool
2649 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
2651 struct access *rchild;
2652 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
2653 bool ret = false;
2655 /* IF the LHS is still not marked as being written to, we only need to do so
2656 if the RHS at this level actually was. */
2657 if (!lacc->grp_write)
2659 gcc_checking_assert (!comes_initialized_p (racc->base));
2660 if (racc->grp_write)
2662 subtree_mark_written_and_enqueue (lacc);
2663 ret = true;
2667 if (is_gimple_reg_type (lacc->type)
2668 || lacc->grp_unscalarizable_region
2669 || racc->grp_unscalarizable_region)
2671 if (!lacc->grp_write)
2673 ret = true;
2674 subtree_mark_written_and_enqueue (lacc);
2676 return ret;
2679 if (is_gimple_reg_type (racc->type))
2681 if (!lacc->grp_write)
2683 ret = true;
2684 subtree_mark_written_and_enqueue (lacc);
2686 if (!lacc->first_child && !racc->first_child)
2688 tree t = lacc->base;
2690 lacc->type = racc->type;
2691 if (build_user_friendly_ref_for_offset (&t, TREE_TYPE (t),
2692 lacc->offset, racc->type))
2693 lacc->expr = t;
2694 else
2696 lacc->expr = build_ref_for_model (EXPR_LOCATION (lacc->base),
2697 lacc->base, lacc->offset,
2698 racc, NULL, false);
2699 lacc->grp_no_warning = true;
2702 return ret;
2705 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
2707 struct access *new_acc = NULL;
2708 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
2710 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
2711 &new_acc))
2713 if (new_acc)
2715 if (!new_acc->grp_write && rchild->grp_write)
2717 gcc_assert (!lacc->grp_write);
2718 subtree_mark_written_and_enqueue (new_acc);
2719 ret = true;
2722 rchild->grp_hint = 1;
2723 new_acc->grp_hint |= new_acc->grp_read;
2724 if (rchild->first_child)
2725 ret |= propagate_subaccesses_across_link (new_acc, rchild);
2727 else
2729 if (!lacc->grp_write)
2731 ret = true;
2732 subtree_mark_written_and_enqueue (lacc);
2735 continue;
2738 if (rchild->grp_unscalarizable_region)
2740 if (rchild->grp_write && !lacc->grp_write)
2742 ret = true;
2743 subtree_mark_written_and_enqueue (lacc);
2745 continue;
2748 rchild->grp_hint = 1;
2749 new_acc = create_artificial_child_access (lacc, rchild, norm_offset,
2750 lacc->grp_write
2751 || rchild->grp_write);
2752 gcc_checking_assert (new_acc);
2753 if (racc->first_child)
2754 propagate_subaccesses_across_link (new_acc, rchild);
2756 add_access_to_work_queue (lacc);
2757 ret = true;
2760 return ret;
2763 /* Propagate all subaccesses across assignment links. */
2765 static void
2766 propagate_all_subaccesses (void)
2768 while (work_queue_head)
2770 struct access *racc = pop_access_from_work_queue ();
2771 struct assign_link *link;
2773 if (racc->group_representative)
2774 racc= racc->group_representative;
2775 gcc_assert (racc->first_link);
2777 for (link = racc->first_link; link; link = link->next)
2779 struct access *lacc = link->lacc;
2781 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
2782 continue;
2783 lacc = lacc->group_representative;
2785 bool reque_parents = false;
2786 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (racc->base)))
2788 if (!lacc->grp_write)
2790 subtree_mark_written_and_enqueue (lacc);
2791 reque_parents = true;
2794 else if (propagate_subaccesses_across_link (lacc, racc))
2795 reque_parents = true;
2797 if (reque_parents)
2800 add_access_to_work_queue (lacc);
2801 lacc = lacc->parent;
2803 while (lacc);
2808 /* Go through all accesses collected throughout the (intraprocedural) analysis
2809 stage, exclude overlapping ones, identify representatives and build trees
2810 out of them, making decisions about scalarization on the way. Return true
2811 iff there are any to-be-scalarized variables after this stage. */
2813 static bool
2814 analyze_all_variable_accesses (void)
2816 int res = 0;
2817 bitmap tmp = BITMAP_ALLOC (NULL);
2818 bitmap_iterator bi;
2819 unsigned i;
2820 bool optimize_speed_p = !optimize_function_for_size_p (cfun);
2822 enum compiler_param param = optimize_speed_p
2823 ? PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED
2824 : PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE;
2826 /* If the user didn't set PARAM_SRA_MAX_SCALARIZATION_SIZE_<...>,
2827 fall back to a target default. */
2828 unsigned HOST_WIDE_INT max_scalarization_size
2829 = global_options_set.x_param_values[param]
2830 ? PARAM_VALUE (param)
2831 : get_move_ratio (optimize_speed_p) * UNITS_PER_WORD;
2833 max_scalarization_size *= BITS_PER_UNIT;
2835 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
2836 if (bitmap_bit_p (should_scalarize_away_bitmap, i)
2837 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
2839 tree var = candidate (i);
2841 if (VAR_P (var) && scalarizable_type_p (TREE_TYPE (var),
2842 constant_decl_p (var)))
2844 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var)))
2845 <= max_scalarization_size)
2847 create_total_scalarization_access (var);
2848 completely_scalarize (var, TREE_TYPE (var), 0, var);
2849 statistics_counter_event (cfun,
2850 "Totally-scalarized aggregates", 1);
2851 if (dump_file && (dump_flags & TDF_DETAILS))
2853 fprintf (dump_file, "Will attempt to totally scalarize ");
2854 print_generic_expr (dump_file, var);
2855 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2858 else if (dump_file && (dump_flags & TDF_DETAILS))
2860 fprintf (dump_file, "Too big to totally scalarize: ");
2861 print_generic_expr (dump_file, var);
2862 fprintf (dump_file, " (UID: %u)\n", DECL_UID (var));
2867 bitmap_copy (tmp, candidate_bitmap);
2868 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2870 tree var = candidate (i);
2871 struct access *access;
2873 access = sort_and_splice_var_accesses (var);
2874 if (!access || !build_access_trees (access))
2875 disqualify_candidate (var,
2876 "No or inhibitingly overlapping accesses.");
2879 propagate_all_subaccesses ();
2881 bitmap_copy (tmp, candidate_bitmap);
2882 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2884 tree var = candidate (i);
2885 struct access *access = get_first_repr_for_decl (var);
2887 if (analyze_access_trees (access))
2889 res++;
2890 if (dump_file && (dump_flags & TDF_DETAILS))
2892 fprintf (dump_file, "\nAccess trees for ");
2893 print_generic_expr (dump_file, var);
2894 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2895 dump_access_tree (dump_file, access);
2896 fprintf (dump_file, "\n");
2899 else
2900 disqualify_candidate (var, "No scalar replacements to be created.");
2903 BITMAP_FREE (tmp);
2905 if (res)
2907 statistics_counter_event (cfun, "Scalarized aggregates", res);
2908 return true;
2910 else
2911 return false;
2914 /* Generate statements copying scalar replacements of accesses within a subtree
2915 into or out of AGG. ACCESS, all its children, siblings and their children
2916 are to be processed. AGG is an aggregate type expression (can be a
2917 declaration but does not have to be, it can for example also be a mem_ref or
2918 a series of handled components). TOP_OFFSET is the offset of the processed
2919 subtree which has to be subtracted from offsets of individual accesses to
2920 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2921 replacements in the interval <start_offset, start_offset + chunk_size>,
2922 otherwise copy all. GSI is a statement iterator used to place the new
2923 statements. WRITE should be true when the statements should write from AGG
2924 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2925 statements will be added after the current statement in GSI, they will be
2926 added before the statement otherwise. */
2928 static void
2929 generate_subtree_copies (struct access *access, tree agg,
2930 HOST_WIDE_INT top_offset,
2931 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
2932 gimple_stmt_iterator *gsi, bool write,
2933 bool insert_after, location_t loc)
2935 /* Never write anything into constant pool decls. See PR70602. */
2936 if (!write && constant_decl_p (agg))
2937 return;
2940 if (chunk_size && access->offset >= start_offset + chunk_size)
2941 return;
2943 if (access->grp_to_be_replaced
2944 && (chunk_size == 0
2945 || access->offset + access->size > start_offset))
2947 tree expr, repl = get_access_replacement (access);
2948 gassign *stmt;
2950 expr = build_ref_for_model (loc, agg, access->offset - top_offset,
2951 access, gsi, insert_after);
2953 if (write)
2955 if (access->grp_partial_lhs)
2956 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
2957 !insert_after,
2958 insert_after ? GSI_NEW_STMT
2959 : GSI_SAME_STMT);
2960 stmt = gimple_build_assign (repl, expr);
2962 else
2964 TREE_NO_WARNING (repl) = 1;
2965 if (access->grp_partial_lhs)
2966 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2967 !insert_after,
2968 insert_after ? GSI_NEW_STMT
2969 : GSI_SAME_STMT);
2970 stmt = gimple_build_assign (expr, repl);
2972 gimple_set_location (stmt, loc);
2974 if (insert_after)
2975 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2976 else
2977 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2978 update_stmt (stmt);
2979 sra_stats.subtree_copies++;
2981 else if (write
2982 && access->grp_to_be_debug_replaced
2983 && (chunk_size == 0
2984 || access->offset + access->size > start_offset))
2986 gdebug *ds;
2987 tree drhs = build_debug_ref_for_model (loc, agg,
2988 access->offset - top_offset,
2989 access);
2990 ds = gimple_build_debug_bind (get_access_replacement (access),
2991 drhs, gsi_stmt (*gsi));
2992 if (insert_after)
2993 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2994 else
2995 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2998 if (access->first_child)
2999 generate_subtree_copies (access->first_child, agg, top_offset,
3000 start_offset, chunk_size, gsi,
3001 write, insert_after, loc);
3003 access = access->next_sibling;
3005 while (access);
3008 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
3009 root of the subtree to be processed. GSI is the statement iterator used
3010 for inserting statements which are added after the current statement if
3011 INSERT_AFTER is true or before it otherwise. */
3013 static void
3014 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
3015 bool insert_after, location_t loc)
3018 struct access *child;
3020 if (access->grp_to_be_replaced)
3022 gassign *stmt;
3024 stmt = gimple_build_assign (get_access_replacement (access),
3025 build_zero_cst (access->type));
3026 if (insert_after)
3027 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
3028 else
3029 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
3030 update_stmt (stmt);
3031 gimple_set_location (stmt, loc);
3033 else if (access->grp_to_be_debug_replaced)
3035 gdebug *ds
3036 = gimple_build_debug_bind (get_access_replacement (access),
3037 build_zero_cst (access->type),
3038 gsi_stmt (*gsi));
3039 if (insert_after)
3040 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
3041 else
3042 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3045 for (child = access->first_child; child; child = child->next_sibling)
3046 init_subtree_with_zero (child, gsi, insert_after, loc);
3049 /* Clobber all scalar replacements in an access subtree. ACCESS is the
3050 root of the subtree to be processed. GSI is the statement iterator used
3051 for inserting statements which are added after the current statement if
3052 INSERT_AFTER is true or before it otherwise. */
3054 static void
3055 clobber_subtree (struct access *access, gimple_stmt_iterator *gsi,
3056 bool insert_after, location_t loc)
3059 struct access *child;
3061 if (access->grp_to_be_replaced)
3063 tree rep = get_access_replacement (access);
3064 tree clobber = build_constructor (access->type, NULL);
3065 TREE_THIS_VOLATILE (clobber) = 1;
3066 gimple *stmt = gimple_build_assign (rep, clobber);
3068 if (insert_after)
3069 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
3070 else
3071 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
3072 update_stmt (stmt);
3073 gimple_set_location (stmt, loc);
3076 for (child = access->first_child; child; child = child->next_sibling)
3077 clobber_subtree (child, gsi, insert_after, loc);
3080 /* Search for an access representative for the given expression EXPR and
3081 return it or NULL if it cannot be found. */
3083 static struct access *
3084 get_access_for_expr (tree expr)
3086 HOST_WIDE_INT offset, size, max_size;
3087 tree base;
3088 bool reverse;
3090 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
3091 a different size than the size of its argument and we need the latter
3092 one. */
3093 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
3094 expr = TREE_OPERAND (expr, 0);
3096 base = get_ref_base_and_extent (expr, &offset, &size, &max_size, &reverse);
3097 if (max_size == -1 || !DECL_P (base))
3098 return NULL;
3100 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
3101 return NULL;
3103 return get_var_base_offset_size_access (base, offset, max_size);
3106 /* Replace the expression EXPR with a scalar replacement if there is one and
3107 generate other statements to do type conversion or subtree copying if
3108 necessary. GSI is used to place newly created statements, WRITE is true if
3109 the expression is being written to (it is on a LHS of a statement or output
3110 in an assembly statement). */
3112 static bool
3113 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
3115 location_t loc;
3116 struct access *access;
3117 tree type, bfr, orig_expr;
3119 if (TREE_CODE (*expr) == BIT_FIELD_REF)
3121 bfr = *expr;
3122 expr = &TREE_OPERAND (*expr, 0);
3124 else
3125 bfr = NULL_TREE;
3127 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
3128 expr = &TREE_OPERAND (*expr, 0);
3129 access = get_access_for_expr (*expr);
3130 if (!access)
3131 return false;
3132 type = TREE_TYPE (*expr);
3133 orig_expr = *expr;
3135 loc = gimple_location (gsi_stmt (*gsi));
3136 gimple_stmt_iterator alt_gsi = gsi_none ();
3137 if (write && stmt_ends_bb_p (gsi_stmt (*gsi)))
3139 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
3140 gsi = &alt_gsi;
3143 if (access->grp_to_be_replaced)
3145 tree repl = get_access_replacement (access);
3146 /* If we replace a non-register typed access simply use the original
3147 access expression to extract the scalar component afterwards.
3148 This happens if scalarizing a function return value or parameter
3149 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
3150 gcc.c-torture/compile/20011217-1.c.
3152 We also want to use this when accessing a complex or vector which can
3153 be accessed as a different type too, potentially creating a need for
3154 type conversion (see PR42196) and when scalarized unions are involved
3155 in assembler statements (see PR42398). */
3156 if (!useless_type_conversion_p (type, access->type))
3158 tree ref;
3160 ref = build_ref_for_model (loc, orig_expr, 0, access, gsi, false);
3162 if (write)
3164 gassign *stmt;
3166 if (access->grp_partial_lhs)
3167 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
3168 false, GSI_NEW_STMT);
3169 stmt = gimple_build_assign (repl, ref);
3170 gimple_set_location (stmt, loc);
3171 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
3173 else
3175 gassign *stmt;
3177 if (access->grp_partial_lhs)
3178 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
3179 true, GSI_SAME_STMT);
3180 stmt = gimple_build_assign (ref, repl);
3181 gimple_set_location (stmt, loc);
3182 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
3185 else
3186 *expr = repl;
3187 sra_stats.exprs++;
3189 else if (write && access->grp_to_be_debug_replaced)
3191 gdebug *ds = gimple_build_debug_bind (get_access_replacement (access),
3192 NULL_TREE,
3193 gsi_stmt (*gsi));
3194 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
3197 if (access->first_child)
3199 HOST_WIDE_INT start_offset, chunk_size;
3200 if (bfr
3201 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 1))
3202 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 2)))
3204 chunk_size = tree_to_uhwi (TREE_OPERAND (bfr, 1));
3205 start_offset = access->offset
3206 + tree_to_uhwi (TREE_OPERAND (bfr, 2));
3208 else
3209 start_offset = chunk_size = 0;
3211 generate_subtree_copies (access->first_child, orig_expr, access->offset,
3212 start_offset, chunk_size, gsi, write, write,
3213 loc);
3215 return true;
3218 /* Where scalar replacements of the RHS have been written to when a replacement
3219 of a LHS of an assigments cannot be direclty loaded from a replacement of
3220 the RHS. */
3221 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
3222 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
3223 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
3225 struct subreplacement_assignment_data
3227 /* Offset of the access representing the lhs of the assignment. */
3228 HOST_WIDE_INT left_offset;
3230 /* LHS and RHS of the original assignment. */
3231 tree assignment_lhs, assignment_rhs;
3233 /* Access representing the rhs of the whole assignment. */
3234 struct access *top_racc;
3236 /* Stmt iterator used for statement insertions after the original assignment.
3237 It points to the main GSI used to traverse a BB during function body
3238 modification. */
3239 gimple_stmt_iterator *new_gsi;
3241 /* Stmt iterator used for statement insertions before the original
3242 assignment. Keeps on pointing to the original statement. */
3243 gimple_stmt_iterator old_gsi;
3245 /* Location of the assignment. */
3246 location_t loc;
3248 /* Keeps the information whether we have needed to refresh replacements of
3249 the LHS and from which side of the assignments this takes place. */
3250 enum unscalarized_data_handling refreshed;
3253 /* Store all replacements in the access tree rooted in TOP_RACC either to their
3254 base aggregate if there are unscalarized data or directly to LHS of the
3255 statement that is pointed to by GSI otherwise. */
3257 static void
3258 handle_unscalarized_data_in_subtree (struct subreplacement_assignment_data *sad)
3260 tree src;
3261 if (sad->top_racc->grp_unscalarized_data)
3263 src = sad->assignment_rhs;
3264 sad->refreshed = SRA_UDH_RIGHT;
3266 else
3268 src = sad->assignment_lhs;
3269 sad->refreshed = SRA_UDH_LEFT;
3271 generate_subtree_copies (sad->top_racc->first_child, src,
3272 sad->top_racc->offset, 0, 0,
3273 &sad->old_gsi, false, false, sad->loc);
3276 /* Try to generate statements to load all sub-replacements in an access subtree
3277 formed by children of LACC from scalar replacements in the SAD->top_racc
3278 subtree. If that is not possible, refresh the SAD->top_racc base aggregate
3279 and load the accesses from it. */
3281 static void
3282 load_assign_lhs_subreplacements (struct access *lacc,
3283 struct subreplacement_assignment_data *sad)
3285 for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling)
3287 HOST_WIDE_INT offset;
3288 offset = lacc->offset - sad->left_offset + sad->top_racc->offset;
3290 if (lacc->grp_to_be_replaced)
3292 struct access *racc;
3293 gassign *stmt;
3294 tree rhs;
3296 racc = find_access_in_subtree (sad->top_racc, offset, lacc->size);
3297 if (racc && racc->grp_to_be_replaced)
3299 rhs = get_access_replacement (racc);
3300 if (!useless_type_conversion_p (lacc->type, racc->type))
3301 rhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
3302 lacc->type, rhs);
3304 if (racc->grp_partial_lhs && lacc->grp_partial_lhs)
3305 rhs = force_gimple_operand_gsi (&sad->old_gsi, rhs, true,
3306 NULL_TREE, true, GSI_SAME_STMT);
3308 else
3310 /* No suitable access on the right hand side, need to load from
3311 the aggregate. See if we have to update it first... */
3312 if (sad->refreshed == SRA_UDH_NONE)
3313 handle_unscalarized_data_in_subtree (sad);
3315 if (sad->refreshed == SRA_UDH_LEFT)
3316 rhs = build_ref_for_model (sad->loc, sad->assignment_lhs,
3317 lacc->offset - sad->left_offset,
3318 lacc, sad->new_gsi, true);
3319 else
3320 rhs = build_ref_for_model (sad->loc, sad->assignment_rhs,
3321 lacc->offset - sad->left_offset,
3322 lacc, sad->new_gsi, true);
3323 if (lacc->grp_partial_lhs)
3324 rhs = force_gimple_operand_gsi (sad->new_gsi,
3325 rhs, true, NULL_TREE,
3326 false, GSI_NEW_STMT);
3329 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
3330 gsi_insert_after (sad->new_gsi, stmt, GSI_NEW_STMT);
3331 gimple_set_location (stmt, sad->loc);
3332 update_stmt (stmt);
3333 sra_stats.subreplacements++;
3335 else
3337 if (sad->refreshed == SRA_UDH_NONE
3338 && lacc->grp_read && !lacc->grp_covered)
3339 handle_unscalarized_data_in_subtree (sad);
3341 if (lacc && lacc->grp_to_be_debug_replaced)
3343 gdebug *ds;
3344 tree drhs;
3345 struct access *racc = find_access_in_subtree (sad->top_racc,
3346 offset,
3347 lacc->size);
3349 if (racc && racc->grp_to_be_replaced)
3351 if (racc->grp_write || constant_decl_p (racc->base))
3352 drhs = get_access_replacement (racc);
3353 else
3354 drhs = NULL;
3356 else if (sad->refreshed == SRA_UDH_LEFT)
3357 drhs = build_debug_ref_for_model (sad->loc, lacc->base,
3358 lacc->offset, lacc);
3359 else if (sad->refreshed == SRA_UDH_RIGHT)
3360 drhs = build_debug_ref_for_model (sad->loc, sad->top_racc->base,
3361 offset, lacc);
3362 else
3363 drhs = NULL_TREE;
3364 if (drhs
3365 && !useless_type_conversion_p (lacc->type, TREE_TYPE (drhs)))
3366 drhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
3367 lacc->type, drhs);
3368 ds = gimple_build_debug_bind (get_access_replacement (lacc),
3369 drhs, gsi_stmt (sad->old_gsi));
3370 gsi_insert_after (sad->new_gsi, ds, GSI_NEW_STMT);
3374 if (lacc->first_child)
3375 load_assign_lhs_subreplacements (lacc, sad);
3379 /* Result code for SRA assignment modification. */
3380 enum assignment_mod_result { SRA_AM_NONE, /* nothing done for the stmt */
3381 SRA_AM_MODIFIED, /* stmt changed but not
3382 removed */
3383 SRA_AM_REMOVED }; /* stmt eliminated */
3385 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
3386 to the assignment and GSI is the statement iterator pointing at it. Returns
3387 the same values as sra_modify_assign. */
3389 static enum assignment_mod_result
3390 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3392 tree lhs = gimple_assign_lhs (stmt);
3393 struct access *acc = get_access_for_expr (lhs);
3394 if (!acc)
3395 return SRA_AM_NONE;
3396 location_t loc = gimple_location (stmt);
3398 if (gimple_clobber_p (stmt))
3400 /* Clobber the replacement variable. */
3401 clobber_subtree (acc, gsi, !acc->grp_covered, loc);
3402 /* Remove clobbers of fully scalarized variables, they are dead. */
3403 if (acc->grp_covered)
3405 unlink_stmt_vdef (stmt);
3406 gsi_remove (gsi, true);
3407 release_defs (stmt);
3408 return SRA_AM_REMOVED;
3410 else
3411 return SRA_AM_MODIFIED;
3414 if (CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt)) > 0)
3416 /* I have never seen this code path trigger but if it can happen the
3417 following should handle it gracefully. */
3418 if (access_has_children_p (acc))
3419 generate_subtree_copies (acc->first_child, lhs, acc->offset, 0, 0, gsi,
3420 true, true, loc);
3421 return SRA_AM_MODIFIED;
3424 if (acc->grp_covered)
3426 init_subtree_with_zero (acc, gsi, false, loc);
3427 unlink_stmt_vdef (stmt);
3428 gsi_remove (gsi, true);
3429 release_defs (stmt);
3430 return SRA_AM_REMOVED;
3432 else
3434 init_subtree_with_zero (acc, gsi, true, loc);
3435 return SRA_AM_MODIFIED;
3439 /* Create and return a new suitable default definition SSA_NAME for RACC which
3440 is an access describing an uninitialized part of an aggregate that is being
3441 loaded. */
3443 static tree
3444 get_repl_default_def_ssa_name (struct access *racc)
3446 gcc_checking_assert (!racc->grp_to_be_replaced
3447 && !racc->grp_to_be_debug_replaced);
3448 if (!racc->replacement_decl)
3449 racc->replacement_decl = create_access_replacement (racc);
3450 return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
3453 /* Examine both sides of the assignment statement pointed to by STMT, replace
3454 them with a scalare replacement if there is one and generate copying of
3455 replacements if scalarized aggregates have been used in the assignment. GSI
3456 is used to hold generated statements for type conversions and subtree
3457 copying. */
3459 static enum assignment_mod_result
3460 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3462 struct access *lacc, *racc;
3463 tree lhs, rhs;
3464 bool modify_this_stmt = false;
3465 bool force_gimple_rhs = false;
3466 location_t loc;
3467 gimple_stmt_iterator orig_gsi = *gsi;
3469 if (!gimple_assign_single_p (stmt))
3470 return SRA_AM_NONE;
3471 lhs = gimple_assign_lhs (stmt);
3472 rhs = gimple_assign_rhs1 (stmt);
3474 if (TREE_CODE (rhs) == CONSTRUCTOR)
3475 return sra_modify_constructor_assign (stmt, gsi);
3477 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
3478 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
3479 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
3481 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (stmt),
3482 gsi, false);
3483 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (stmt),
3484 gsi, true);
3485 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3488 lacc = get_access_for_expr (lhs);
3489 racc = get_access_for_expr (rhs);
3490 if (!lacc && !racc)
3491 return SRA_AM_NONE;
3492 /* Avoid modifying initializations of constant-pool replacements. */
3493 if (racc && (racc->replacement_decl == lhs))
3494 return SRA_AM_NONE;
3496 loc = gimple_location (stmt);
3497 if (lacc && lacc->grp_to_be_replaced)
3499 lhs = get_access_replacement (lacc);
3500 gimple_assign_set_lhs (stmt, lhs);
3501 modify_this_stmt = true;
3502 if (lacc->grp_partial_lhs)
3503 force_gimple_rhs = true;
3504 sra_stats.exprs++;
3507 if (racc && racc->grp_to_be_replaced)
3509 rhs = get_access_replacement (racc);
3510 modify_this_stmt = true;
3511 if (racc->grp_partial_lhs)
3512 force_gimple_rhs = true;
3513 sra_stats.exprs++;
3515 else if (racc
3516 && !racc->grp_unscalarized_data
3517 && !racc->grp_unscalarizable_region
3518 && TREE_CODE (lhs) == SSA_NAME
3519 && !access_has_replacements_p (racc))
3521 rhs = get_repl_default_def_ssa_name (racc);
3522 modify_this_stmt = true;
3523 sra_stats.exprs++;
3526 if (modify_this_stmt)
3528 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3530 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3531 ??? This should move to fold_stmt which we simply should
3532 call after building a VIEW_CONVERT_EXPR here. */
3533 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
3534 && !contains_bitfld_component_ref_p (lhs))
3536 lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
3537 gimple_assign_set_lhs (stmt, lhs);
3539 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
3540 && !contains_vce_or_bfcref_p (rhs))
3541 rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
3543 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3545 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
3546 rhs);
3547 if (is_gimple_reg_type (TREE_TYPE (lhs))
3548 && TREE_CODE (lhs) != SSA_NAME)
3549 force_gimple_rhs = true;
3554 if (lacc && lacc->grp_to_be_debug_replaced)
3556 tree dlhs = get_access_replacement (lacc);
3557 tree drhs = unshare_expr (rhs);
3558 if (!useless_type_conversion_p (TREE_TYPE (dlhs), TREE_TYPE (drhs)))
3560 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs))
3561 && !contains_vce_or_bfcref_p (drhs))
3562 drhs = build_debug_ref_for_model (loc, drhs, 0, lacc);
3563 if (drhs
3564 && !useless_type_conversion_p (TREE_TYPE (dlhs),
3565 TREE_TYPE (drhs)))
3566 drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
3567 TREE_TYPE (dlhs), drhs);
3569 gdebug *ds = gimple_build_debug_bind (dlhs, drhs, stmt);
3570 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3573 /* From this point on, the function deals with assignments in between
3574 aggregates when at least one has scalar reductions of some of its
3575 components. There are three possible scenarios: Both the LHS and RHS have
3576 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3578 In the first case, we would like to load the LHS components from RHS
3579 components whenever possible. If that is not possible, we would like to
3580 read it directly from the RHS (after updating it by storing in it its own
3581 components). If there are some necessary unscalarized data in the LHS,
3582 those will be loaded by the original assignment too. If neither of these
3583 cases happen, the original statement can be removed. Most of this is done
3584 by load_assign_lhs_subreplacements.
3586 In the second case, we would like to store all RHS scalarized components
3587 directly into LHS and if they cover the aggregate completely, remove the
3588 statement too. In the third case, we want the LHS components to be loaded
3589 directly from the RHS (DSE will remove the original statement if it
3590 becomes redundant).
3592 This is a bit complex but manageable when types match and when unions do
3593 not cause confusion in a way that we cannot really load a component of LHS
3594 from the RHS or vice versa (the access representing this level can have
3595 subaccesses that are accessible only through a different union field at a
3596 higher level - different from the one used in the examined expression).
3597 Unions are fun.
3599 Therefore, I specially handle a fourth case, happening when there is a
3600 specific type cast or it is impossible to locate a scalarized subaccess on
3601 the other side of the expression. If that happens, I simply "refresh" the
3602 RHS by storing in it is scalarized components leave the original statement
3603 there to do the copying and then load the scalar replacements of the LHS.
3604 This is what the first branch does. */
3606 if (modify_this_stmt
3607 || gimple_has_volatile_ops (stmt)
3608 || contains_vce_or_bfcref_p (rhs)
3609 || contains_vce_or_bfcref_p (lhs)
3610 || stmt_ends_bb_p (stmt))
3612 /* No need to copy into a constant-pool, it comes pre-initialized. */
3613 if (access_has_children_p (racc) && !constant_decl_p (racc->base))
3614 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3615 gsi, false, false, loc);
3616 if (access_has_children_p (lacc))
3618 gimple_stmt_iterator alt_gsi = gsi_none ();
3619 if (stmt_ends_bb_p (stmt))
3621 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
3622 gsi = &alt_gsi;
3624 generate_subtree_copies (lacc->first_child, lhs, lacc->offset, 0, 0,
3625 gsi, true, true, loc);
3627 sra_stats.separate_lhs_rhs_handling++;
3629 /* This gimplification must be done after generate_subtree_copies,
3630 lest we insert the subtree copies in the middle of the gimplified
3631 sequence. */
3632 if (force_gimple_rhs)
3633 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
3634 true, GSI_SAME_STMT);
3635 if (gimple_assign_rhs1 (stmt) != rhs)
3637 modify_this_stmt = true;
3638 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
3639 gcc_assert (stmt == gsi_stmt (orig_gsi));
3642 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3644 else
3646 if (access_has_children_p (lacc)
3647 && access_has_children_p (racc)
3648 /* When an access represents an unscalarizable region, it usually
3649 represents accesses with variable offset and thus must not be used
3650 to generate new memory accesses. */
3651 && !lacc->grp_unscalarizable_region
3652 && !racc->grp_unscalarizable_region)
3654 struct subreplacement_assignment_data sad;
3656 sad.left_offset = lacc->offset;
3657 sad.assignment_lhs = lhs;
3658 sad.assignment_rhs = rhs;
3659 sad.top_racc = racc;
3660 sad.old_gsi = *gsi;
3661 sad.new_gsi = gsi;
3662 sad.loc = gimple_location (stmt);
3663 sad.refreshed = SRA_UDH_NONE;
3665 if (lacc->grp_read && !lacc->grp_covered)
3666 handle_unscalarized_data_in_subtree (&sad);
3668 load_assign_lhs_subreplacements (lacc, &sad);
3669 if (sad.refreshed != SRA_UDH_RIGHT)
3671 gsi_next (gsi);
3672 unlink_stmt_vdef (stmt);
3673 gsi_remove (&sad.old_gsi, true);
3674 release_defs (stmt);
3675 sra_stats.deleted++;
3676 return SRA_AM_REMOVED;
3679 else
3681 if (access_has_children_p (racc)
3682 && !racc->grp_unscalarized_data
3683 && TREE_CODE (lhs) != SSA_NAME)
3685 if (dump_file)
3687 fprintf (dump_file, "Removing load: ");
3688 print_gimple_stmt (dump_file, stmt, 0);
3690 generate_subtree_copies (racc->first_child, lhs,
3691 racc->offset, 0, 0, gsi,
3692 false, false, loc);
3693 gcc_assert (stmt == gsi_stmt (*gsi));
3694 unlink_stmt_vdef (stmt);
3695 gsi_remove (gsi, true);
3696 release_defs (stmt);
3697 sra_stats.deleted++;
3698 return SRA_AM_REMOVED;
3700 /* Restore the aggregate RHS from its components so the
3701 prevailing aggregate copy does the right thing. */
3702 if (access_has_children_p (racc))
3703 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3704 gsi, false, false, loc);
3705 /* Re-load the components of the aggregate copy destination.
3706 But use the RHS aggregate to load from to expose more
3707 optimization opportunities. */
3708 if (access_has_children_p (lacc))
3709 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
3710 0, 0, gsi, true, true, loc);
3713 return SRA_AM_NONE;
3717 /* Set any scalar replacements of values in the constant pool to the initial
3718 value of the constant. (Constant-pool decls like *.LC0 have effectively
3719 been initialized before the program starts, we must do the same for their
3720 replacements.) Thus, we output statements like 'SR.1 = *.LC0[0];' into
3721 the function's entry block. */
3723 static void
3724 initialize_constant_pool_replacements (void)
3726 gimple_seq seq = NULL;
3727 gimple_stmt_iterator gsi = gsi_start (seq);
3728 bitmap_iterator bi;
3729 unsigned i;
3731 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
3733 tree var = candidate (i);
3734 if (!constant_decl_p (var))
3735 continue;
3736 vec<access_p> *access_vec = get_base_access_vector (var);
3737 if (!access_vec)
3738 continue;
3739 for (unsigned i = 0; i < access_vec->length (); i++)
3741 struct access *access = (*access_vec)[i];
3742 if (!access->replacement_decl)
3743 continue;
3744 gassign *stmt
3745 = gimple_build_assign (get_access_replacement (access),
3746 unshare_expr (access->expr));
3747 if (dump_file && (dump_flags & TDF_DETAILS))
3749 fprintf (dump_file, "Generating constant initializer: ");
3750 print_gimple_stmt (dump_file, stmt, 0);
3751 fprintf (dump_file, "\n");
3753 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
3754 update_stmt (stmt);
3758 seq = gsi_seq (gsi);
3759 if (seq)
3760 gsi_insert_seq_on_edge_immediate (
3761 single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3764 /* Traverse the function body and all modifications as decided in
3765 analyze_all_variable_accesses. Return true iff the CFG has been
3766 changed. */
3768 static bool
3769 sra_modify_function_body (void)
3771 bool cfg_changed = false;
3772 basic_block bb;
3774 initialize_constant_pool_replacements ();
3776 FOR_EACH_BB_FN (bb, cfun)
3778 gimple_stmt_iterator gsi = gsi_start_bb (bb);
3779 while (!gsi_end_p (gsi))
3781 gimple *stmt = gsi_stmt (gsi);
3782 enum assignment_mod_result assign_result;
3783 bool modified = false, deleted = false;
3784 tree *t;
3785 unsigned i;
3787 switch (gimple_code (stmt))
3789 case GIMPLE_RETURN:
3790 t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
3791 if (*t != NULL_TREE)
3792 modified |= sra_modify_expr (t, &gsi, false);
3793 break;
3795 case GIMPLE_ASSIGN:
3796 assign_result = sra_modify_assign (stmt, &gsi);
3797 modified |= assign_result == SRA_AM_MODIFIED;
3798 deleted = assign_result == SRA_AM_REMOVED;
3799 break;
3801 case GIMPLE_CALL:
3802 /* Operands must be processed before the lhs. */
3803 for (i = 0; i < gimple_call_num_args (stmt); i++)
3805 t = gimple_call_arg_ptr (stmt, i);
3806 modified |= sra_modify_expr (t, &gsi, false);
3809 if (gimple_call_lhs (stmt))
3811 t = gimple_call_lhs_ptr (stmt);
3812 modified |= sra_modify_expr (t, &gsi, true);
3814 break;
3816 case GIMPLE_ASM:
3818 gasm *asm_stmt = as_a <gasm *> (stmt);
3819 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
3821 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
3822 modified |= sra_modify_expr (t, &gsi, false);
3824 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
3826 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
3827 modified |= sra_modify_expr (t, &gsi, true);
3830 break;
3832 default:
3833 break;
3836 if (modified)
3838 update_stmt (stmt);
3839 if (maybe_clean_eh_stmt (stmt)
3840 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
3841 cfg_changed = true;
3843 if (!deleted)
3844 gsi_next (&gsi);
3848 gsi_commit_edge_inserts ();
3849 return cfg_changed;
3852 /* Generate statements initializing scalar replacements of parts of function
3853 parameters. */
3855 static void
3856 initialize_parameter_reductions (void)
3858 gimple_stmt_iterator gsi;
3859 gimple_seq seq = NULL;
3860 tree parm;
3862 gsi = gsi_start (seq);
3863 for (parm = DECL_ARGUMENTS (current_function_decl);
3864 parm;
3865 parm = DECL_CHAIN (parm))
3867 vec<access_p> *access_vec;
3868 struct access *access;
3870 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3871 continue;
3872 access_vec = get_base_access_vector (parm);
3873 if (!access_vec)
3874 continue;
3876 for (access = (*access_vec)[0];
3877 access;
3878 access = access->next_grp)
3879 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true,
3880 EXPR_LOCATION (parm));
3883 seq = gsi_seq (gsi);
3884 if (seq)
3885 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3888 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3889 it reveals there are components of some aggregates to be scalarized, it runs
3890 the required transformations. */
3891 static unsigned int
3892 perform_intra_sra (void)
3894 int ret = 0;
3895 sra_initialize ();
3897 if (!find_var_candidates ())
3898 goto out;
3900 if (!scan_function ())
3901 goto out;
3903 if (!analyze_all_variable_accesses ())
3904 goto out;
3906 if (sra_modify_function_body ())
3907 ret = TODO_update_ssa | TODO_cleanup_cfg;
3908 else
3909 ret = TODO_update_ssa;
3910 initialize_parameter_reductions ();
3912 statistics_counter_event (cfun, "Scalar replacements created",
3913 sra_stats.replacements);
3914 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
3915 statistics_counter_event (cfun, "Subtree copy stmts",
3916 sra_stats.subtree_copies);
3917 statistics_counter_event (cfun, "Subreplacement stmts",
3918 sra_stats.subreplacements);
3919 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
3920 statistics_counter_event (cfun, "Separate LHS and RHS handling",
3921 sra_stats.separate_lhs_rhs_handling);
3923 out:
3924 sra_deinitialize ();
3925 return ret;
3928 /* Perform early intraprocedural SRA. */
3929 static unsigned int
3930 early_intra_sra (void)
3932 sra_mode = SRA_MODE_EARLY_INTRA;
3933 return perform_intra_sra ();
3936 /* Perform "late" intraprocedural SRA. */
3937 static unsigned int
3938 late_intra_sra (void)
3940 sra_mode = SRA_MODE_INTRA;
3941 return perform_intra_sra ();
3945 static bool
3946 gate_intra_sra (void)
3948 return flag_tree_sra != 0 && dbg_cnt (tree_sra);
3952 namespace {
3954 const pass_data pass_data_sra_early =
3956 GIMPLE_PASS, /* type */
3957 "esra", /* name */
3958 OPTGROUP_NONE, /* optinfo_flags */
3959 TV_TREE_SRA, /* tv_id */
3960 ( PROP_cfg | PROP_ssa ), /* properties_required */
3961 0, /* properties_provided */
3962 0, /* properties_destroyed */
3963 0, /* todo_flags_start */
3964 TODO_update_ssa, /* todo_flags_finish */
3967 class pass_sra_early : public gimple_opt_pass
3969 public:
3970 pass_sra_early (gcc::context *ctxt)
3971 : gimple_opt_pass (pass_data_sra_early, ctxt)
3974 /* opt_pass methods: */
3975 virtual bool gate (function *) { return gate_intra_sra (); }
3976 virtual unsigned int execute (function *) { return early_intra_sra (); }
3978 }; // class pass_sra_early
3980 } // anon namespace
3982 gimple_opt_pass *
3983 make_pass_sra_early (gcc::context *ctxt)
3985 return new pass_sra_early (ctxt);
3988 namespace {
3990 const pass_data pass_data_sra =
3992 GIMPLE_PASS, /* type */
3993 "sra", /* name */
3994 OPTGROUP_NONE, /* optinfo_flags */
3995 TV_TREE_SRA, /* tv_id */
3996 ( PROP_cfg | PROP_ssa ), /* properties_required */
3997 0, /* properties_provided */
3998 0, /* properties_destroyed */
3999 TODO_update_address_taken, /* todo_flags_start */
4000 TODO_update_ssa, /* todo_flags_finish */
4003 class pass_sra : public gimple_opt_pass
4005 public:
4006 pass_sra (gcc::context *ctxt)
4007 : gimple_opt_pass (pass_data_sra, ctxt)
4010 /* opt_pass methods: */
4011 virtual bool gate (function *) { return gate_intra_sra (); }
4012 virtual unsigned int execute (function *) { return late_intra_sra (); }
4014 }; // class pass_sra
4016 } // anon namespace
4018 gimple_opt_pass *
4019 make_pass_sra (gcc::context *ctxt)
4021 return new pass_sra (ctxt);
4025 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
4026 parameter. */
4028 static bool
4029 is_unused_scalar_param (tree parm)
4031 tree name;
4032 return (is_gimple_reg (parm)
4033 && (!(name = ssa_default_def (cfun, parm))
4034 || has_zero_uses (name)));
4037 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
4038 examine whether there are any direct or otherwise infeasible ones. If so,
4039 return true, otherwise return false. PARM must be a gimple register with a
4040 non-NULL default definition. */
4042 static bool
4043 ptr_parm_has_direct_uses (tree parm)
4045 imm_use_iterator ui;
4046 gimple *stmt;
4047 tree name = ssa_default_def (cfun, parm);
4048 bool ret = false;
4050 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
4052 int uses_ok = 0;
4053 use_operand_p use_p;
4055 if (is_gimple_debug (stmt))
4056 continue;
4058 /* Valid uses include dereferences on the lhs and the rhs. */
4059 if (gimple_has_lhs (stmt))
4061 tree lhs = gimple_get_lhs (stmt);
4062 while (handled_component_p (lhs))
4063 lhs = TREE_OPERAND (lhs, 0);
4064 if (TREE_CODE (lhs) == MEM_REF
4065 && TREE_OPERAND (lhs, 0) == name
4066 && integer_zerop (TREE_OPERAND (lhs, 1))
4067 && types_compatible_p (TREE_TYPE (lhs),
4068 TREE_TYPE (TREE_TYPE (name)))
4069 && !TREE_THIS_VOLATILE (lhs))
4070 uses_ok++;
4072 if (gimple_assign_single_p (stmt))
4074 tree rhs = gimple_assign_rhs1 (stmt);
4075 while (handled_component_p (rhs))
4076 rhs = TREE_OPERAND (rhs, 0);
4077 if (TREE_CODE (rhs) == MEM_REF
4078 && TREE_OPERAND (rhs, 0) == name
4079 && integer_zerop (TREE_OPERAND (rhs, 1))
4080 && types_compatible_p (TREE_TYPE (rhs),
4081 TREE_TYPE (TREE_TYPE (name)))
4082 && !TREE_THIS_VOLATILE (rhs))
4083 uses_ok++;
4085 else if (is_gimple_call (stmt))
4087 unsigned i;
4088 for (i = 0; i < gimple_call_num_args (stmt); ++i)
4090 tree arg = gimple_call_arg (stmt, i);
4091 while (handled_component_p (arg))
4092 arg = TREE_OPERAND (arg, 0);
4093 if (TREE_CODE (arg) == MEM_REF
4094 && TREE_OPERAND (arg, 0) == name
4095 && integer_zerop (TREE_OPERAND (arg, 1))
4096 && types_compatible_p (TREE_TYPE (arg),
4097 TREE_TYPE (TREE_TYPE (name)))
4098 && !TREE_THIS_VOLATILE (arg))
4099 uses_ok++;
4103 /* If the number of valid uses does not match the number of
4104 uses in this stmt there is an unhandled use. */
4105 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
4106 --uses_ok;
4108 if (uses_ok != 0)
4109 ret = true;
4111 if (ret)
4112 BREAK_FROM_IMM_USE_STMT (ui);
4115 return ret;
4118 /* Identify candidates for reduction for IPA-SRA based on their type and mark
4119 them in candidate_bitmap. Note that these do not necessarily include
4120 parameter which are unused and thus can be removed. Return true iff any
4121 such candidate has been found. */
4123 static bool
4124 find_param_candidates (void)
4126 tree parm;
4127 int count = 0;
4128 bool ret = false;
4129 const char *msg;
4131 for (parm = DECL_ARGUMENTS (current_function_decl);
4132 parm;
4133 parm = DECL_CHAIN (parm))
4135 tree type = TREE_TYPE (parm);
4136 tree_node **slot;
4138 count++;
4140 if (TREE_THIS_VOLATILE (parm)
4141 || TREE_ADDRESSABLE (parm)
4142 || (!is_gimple_reg_type (type) && is_va_list_type (type)))
4143 continue;
4145 if (is_unused_scalar_param (parm))
4147 ret = true;
4148 continue;
4151 if (POINTER_TYPE_P (type))
4153 type = TREE_TYPE (type);
4155 if (TREE_CODE (type) == FUNCTION_TYPE
4156 || TYPE_VOLATILE (type)
4157 || (TREE_CODE (type) == ARRAY_TYPE
4158 && TYPE_NONALIASED_COMPONENT (type))
4159 || !is_gimple_reg (parm)
4160 || is_va_list_type (type)
4161 || ptr_parm_has_direct_uses (parm))
4162 continue;
4164 else if (!AGGREGATE_TYPE_P (type))
4165 continue;
4167 if (!COMPLETE_TYPE_P (type)
4168 || !tree_fits_uhwi_p (TYPE_SIZE (type))
4169 || tree_to_uhwi (TYPE_SIZE (type)) == 0
4170 || (AGGREGATE_TYPE_P (type)
4171 && type_internals_preclude_sra_p (type, &msg)))
4172 continue;
4174 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
4175 slot = candidates->find_slot_with_hash (parm, DECL_UID (parm), INSERT);
4176 *slot = parm;
4178 ret = true;
4179 if (dump_file && (dump_flags & TDF_DETAILS))
4181 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
4182 print_generic_expr (dump_file, parm);
4183 fprintf (dump_file, "\n");
4187 func_param_count = count;
4188 return ret;
4191 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
4192 maybe_modified. */
4194 static bool
4195 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
4196 void *data)
4198 struct access *repr = (struct access *) data;
4200 repr->grp_maybe_modified = 1;
4201 return true;
4204 /* Analyze what representatives (in linked lists accessible from
4205 REPRESENTATIVES) can be modified by side effects of statements in the
4206 current function. */
4208 static void
4209 analyze_modified_params (vec<access_p> representatives)
4211 int i;
4213 for (i = 0; i < func_param_count; i++)
4215 struct access *repr;
4217 for (repr = representatives[i];
4218 repr;
4219 repr = repr->next_grp)
4221 struct access *access;
4222 bitmap visited;
4223 ao_ref ar;
4225 if (no_accesses_p (repr))
4226 continue;
4227 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
4228 || repr->grp_maybe_modified)
4229 continue;
4231 ao_ref_init (&ar, repr->expr);
4232 visited = BITMAP_ALLOC (NULL);
4233 for (access = repr; access; access = access->next_sibling)
4235 /* All accesses are read ones, otherwise grp_maybe_modified would
4236 be trivially set. */
4237 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
4238 mark_maybe_modified, repr, &visited);
4239 if (repr->grp_maybe_modified)
4240 break;
4242 BITMAP_FREE (visited);
4247 /* Propagate distances in bb_dereferences in the opposite direction than the
4248 control flow edges, in each step storing the maximum of the current value
4249 and the minimum of all successors. These steps are repeated until the table
4250 stabilizes. Note that BBs which might terminate the functions (according to
4251 final_bbs bitmap) never updated in this way. */
4253 static void
4254 propagate_dereference_distances (void)
4256 basic_block bb;
4258 auto_vec<basic_block> queue (last_basic_block_for_fn (cfun));
4259 queue.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun));
4260 FOR_EACH_BB_FN (bb, cfun)
4262 queue.quick_push (bb);
4263 bb->aux = bb;
4266 while (!queue.is_empty ())
4268 edge_iterator ei;
4269 edge e;
4270 bool change = false;
4271 int i;
4273 bb = queue.pop ();
4274 bb->aux = NULL;
4276 if (bitmap_bit_p (final_bbs, bb->index))
4277 continue;
4279 for (i = 0; i < func_param_count; i++)
4281 int idx = bb->index * func_param_count + i;
4282 bool first = true;
4283 HOST_WIDE_INT inh = 0;
4285 FOR_EACH_EDGE (e, ei, bb->succs)
4287 int succ_idx = e->dest->index * func_param_count + i;
4289 if (e->src == EXIT_BLOCK_PTR_FOR_FN (cfun))
4290 continue;
4292 if (first)
4294 first = false;
4295 inh = bb_dereferences [succ_idx];
4297 else if (bb_dereferences [succ_idx] < inh)
4298 inh = bb_dereferences [succ_idx];
4301 if (!first && bb_dereferences[idx] < inh)
4303 bb_dereferences[idx] = inh;
4304 change = true;
4308 if (change && !bitmap_bit_p (final_bbs, bb->index))
4309 FOR_EACH_EDGE (e, ei, bb->preds)
4311 if (e->src->aux)
4312 continue;
4314 e->src->aux = e->src;
4315 queue.quick_push (e->src);
4320 /* Dump a dereferences TABLE with heading STR to file F. */
4322 static void
4323 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
4325 basic_block bb;
4327 fprintf (dump_file, "%s", str);
4328 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
4329 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
4331 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
4332 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
4334 int i;
4335 for (i = 0; i < func_param_count; i++)
4337 int idx = bb->index * func_param_count + i;
4338 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
4341 fprintf (f, "\n");
4343 fprintf (dump_file, "\n");
4346 /* Determine what (parts of) parameters passed by reference that are not
4347 assigned to are not certainly dereferenced in this function and thus the
4348 dereferencing cannot be safely moved to the caller without potentially
4349 introducing a segfault. Mark such REPRESENTATIVES as
4350 grp_not_necessarilly_dereferenced.
4352 The dereferenced maximum "distance," i.e. the offset + size of the accessed
4353 part is calculated rather than simple booleans are calculated for each
4354 pointer parameter to handle cases when only a fraction of the whole
4355 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
4356 an example).
4358 The maximum dereference distances for each pointer parameter and BB are
4359 already stored in bb_dereference. This routine simply propagates these
4360 values upwards by propagate_dereference_distances and then compares the
4361 distances of individual parameters in the ENTRY BB to the equivalent
4362 distances of each representative of a (fraction of a) parameter. */
4364 static void
4365 analyze_caller_dereference_legality (vec<access_p> representatives)
4367 int i;
4369 if (dump_file && (dump_flags & TDF_DETAILS))
4370 dump_dereferences_table (dump_file,
4371 "Dereference table before propagation:\n",
4372 bb_dereferences);
4374 propagate_dereference_distances ();
4376 if (dump_file && (dump_flags & TDF_DETAILS))
4377 dump_dereferences_table (dump_file,
4378 "Dereference table after propagation:\n",
4379 bb_dereferences);
4381 for (i = 0; i < func_param_count; i++)
4383 struct access *repr = representatives[i];
4384 int idx = ENTRY_BLOCK_PTR_FOR_FN (cfun)->index * func_param_count + i;
4386 if (!repr || no_accesses_p (repr))
4387 continue;
4391 if ((repr->offset + repr->size) > bb_dereferences[idx])
4392 repr->grp_not_necessarilly_dereferenced = 1;
4393 repr = repr->next_grp;
4395 while (repr);
4399 /* Return the representative access for the parameter declaration PARM if it is
4400 a scalar passed by reference which is not written to and the pointer value
4401 is not used directly. Thus, if it is legal to dereference it in the caller
4402 and we can rule out modifications through aliases, such parameter should be
4403 turned into one passed by value. Return NULL otherwise. */
4405 static struct access *
4406 unmodified_by_ref_scalar_representative (tree parm)
4408 int i, access_count;
4409 struct access *repr;
4410 vec<access_p> *access_vec;
4412 access_vec = get_base_access_vector (parm);
4413 gcc_assert (access_vec);
4414 repr = (*access_vec)[0];
4415 if (repr->write)
4416 return NULL;
4417 repr->group_representative = repr;
4419 access_count = access_vec->length ();
4420 for (i = 1; i < access_count; i++)
4422 struct access *access = (*access_vec)[i];
4423 if (access->write)
4424 return NULL;
4425 access->group_representative = repr;
4426 access->next_sibling = repr->next_sibling;
4427 repr->next_sibling = access;
4430 repr->grp_read = 1;
4431 repr->grp_scalar_ptr = 1;
4432 return repr;
4435 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
4436 associated with. REQ_ALIGN is the minimum required alignment. */
4438 static bool
4439 access_precludes_ipa_sra_p (struct access *access, unsigned int req_align)
4441 unsigned int exp_align;
4442 /* Avoid issues such as the second simple testcase in PR 42025. The problem
4443 is incompatible assign in a call statement (and possibly even in asm
4444 statements). This can be relaxed by using a new temporary but only for
4445 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
4446 intraprocedural SRA we deal with this by keeping the old aggregate around,
4447 something we cannot do in IPA-SRA.) */
4448 if (access->write
4449 && (is_gimple_call (access->stmt)
4450 || gimple_code (access->stmt) == GIMPLE_ASM))
4451 return true;
4453 exp_align = get_object_alignment (access->expr);
4454 if (exp_align < req_align)
4455 return true;
4457 return false;
4461 /* Sort collected accesses for parameter PARM, identify representatives for
4462 each accessed region and link them together. Return NULL if there are
4463 different but overlapping accesses, return the special ptr value meaning
4464 there are no accesses for this parameter if that is the case and return the
4465 first representative otherwise. Set *RO_GRP if there is a group of accesses
4466 with only read (i.e. no write) accesses. */
4468 static struct access *
4469 splice_param_accesses (tree parm, bool *ro_grp)
4471 int i, j, access_count, group_count;
4472 int total_size = 0;
4473 struct access *access, *res, **prev_acc_ptr = &res;
4474 vec<access_p> *access_vec;
4476 access_vec = get_base_access_vector (parm);
4477 if (!access_vec)
4478 return &no_accesses_representant;
4479 access_count = access_vec->length ();
4481 access_vec->qsort (compare_access_positions);
4483 i = 0;
4484 total_size = 0;
4485 group_count = 0;
4486 while (i < access_count)
4488 bool modification;
4489 tree a1_alias_type;
4490 access = (*access_vec)[i];
4491 modification = access->write;
4492 if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type)))
4493 return NULL;
4494 a1_alias_type = reference_alias_ptr_type (access->expr);
4496 /* Access is about to become group representative unless we find some
4497 nasty overlap which would preclude us from breaking this parameter
4498 apart. */
4500 j = i + 1;
4501 while (j < access_count)
4503 struct access *ac2 = (*access_vec)[j];
4504 if (ac2->offset != access->offset)
4506 /* All or nothing law for parameters. */
4507 if (access->offset + access->size > ac2->offset)
4508 return NULL;
4509 else
4510 break;
4512 else if (ac2->size != access->size)
4513 return NULL;
4515 if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type))
4516 || (ac2->type != access->type
4517 && (TREE_ADDRESSABLE (ac2->type)
4518 || TREE_ADDRESSABLE (access->type)))
4519 || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
4520 return NULL;
4522 modification |= ac2->write;
4523 ac2->group_representative = access;
4524 ac2->next_sibling = access->next_sibling;
4525 access->next_sibling = ac2;
4526 j++;
4529 group_count++;
4530 access->grp_maybe_modified = modification;
4531 if (!modification)
4532 *ro_grp = true;
4533 *prev_acc_ptr = access;
4534 prev_acc_ptr = &access->next_grp;
4535 total_size += access->size;
4536 i = j;
4539 gcc_assert (group_count > 0);
4540 return res;
4543 /* Decide whether parameters with representative accesses given by REPR should
4544 be reduced into components. */
4546 static int
4547 decide_one_param_reduction (struct access *repr)
4549 HOST_WIDE_INT total_size, cur_parm_size;
4550 bool by_ref;
4551 tree parm;
4553 parm = repr->base;
4554 cur_parm_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4555 gcc_assert (cur_parm_size > 0);
4557 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4558 by_ref = true;
4559 else
4560 by_ref = false;
4562 if (dump_file)
4564 struct access *acc;
4565 fprintf (dump_file, "Evaluating PARAM group sizes for ");
4566 print_generic_expr (dump_file, parm);
4567 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
4568 for (acc = repr; acc; acc = acc->next_grp)
4569 dump_access (dump_file, acc, true);
4572 total_size = 0;
4573 int new_param_count = 0;
4575 for (; repr; repr = repr->next_grp)
4577 gcc_assert (parm == repr->base);
4579 /* Taking the address of a non-addressable field is verboten. */
4580 if (by_ref && repr->non_addressable)
4581 return 0;
4583 /* Do not decompose a non-BLKmode param in a way that would
4584 create BLKmode params. Especially for by-reference passing
4585 (thus, pointer-type param) this is hardly worthwhile. */
4586 if (DECL_MODE (parm) != BLKmode
4587 && TYPE_MODE (repr->type) == BLKmode)
4588 return 0;
4590 if (!by_ref || (!repr->grp_maybe_modified
4591 && !repr->grp_not_necessarilly_dereferenced))
4592 total_size += repr->size;
4593 else
4594 total_size += cur_parm_size;
4596 new_param_count++;
4599 gcc_assert (new_param_count > 0);
4601 if (!by_ref)
4603 if (total_size >= cur_parm_size)
4604 return 0;
4606 else
4608 int parm_num_limit;
4609 if (optimize_function_for_size_p (cfun))
4610 parm_num_limit = 1;
4611 else
4612 parm_num_limit = PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR);
4614 if (new_param_count > parm_num_limit
4615 || total_size > (parm_num_limit * cur_parm_size))
4616 return 0;
4619 if (dump_file)
4620 fprintf (dump_file, " ....will be split into %i components\n",
4621 new_param_count);
4622 return new_param_count;
4625 /* The order of the following enums is important, we need to do extra work for
4626 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4627 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
4628 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
4630 /* Identify representatives of all accesses to all candidate parameters for
4631 IPA-SRA. Return result based on what representatives have been found. */
4633 static enum ipa_splicing_result
4634 splice_all_param_accesses (vec<access_p> &representatives)
4636 enum ipa_splicing_result result = NO_GOOD_ACCESS;
4637 tree parm;
4638 struct access *repr;
4640 representatives.create (func_param_count);
4642 for (parm = DECL_ARGUMENTS (current_function_decl);
4643 parm;
4644 parm = DECL_CHAIN (parm))
4646 if (is_unused_scalar_param (parm))
4648 representatives.quick_push (&no_accesses_representant);
4649 if (result == NO_GOOD_ACCESS)
4650 result = UNUSED_PARAMS;
4652 else if (POINTER_TYPE_P (TREE_TYPE (parm))
4653 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
4654 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4656 repr = unmodified_by_ref_scalar_representative (parm);
4657 representatives.quick_push (repr);
4658 if (repr)
4659 result = UNMODIF_BY_REF_ACCESSES;
4661 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4663 bool ro_grp = false;
4664 repr = splice_param_accesses (parm, &ro_grp);
4665 representatives.quick_push (repr);
4667 if (repr && !no_accesses_p (repr))
4669 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4671 if (ro_grp)
4672 result = UNMODIF_BY_REF_ACCESSES;
4673 else if (result < MODIF_BY_REF_ACCESSES)
4674 result = MODIF_BY_REF_ACCESSES;
4676 else if (result < BY_VAL_ACCESSES)
4677 result = BY_VAL_ACCESSES;
4679 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
4680 result = UNUSED_PARAMS;
4682 else
4683 representatives.quick_push (NULL);
4686 if (result == NO_GOOD_ACCESS)
4688 representatives.release ();
4689 return NO_GOOD_ACCESS;
4692 return result;
4695 /* Return the index of BASE in PARMS. Abort if it is not found. */
4697 static inline int
4698 get_param_index (tree base, vec<tree> parms)
4700 int i, len;
4702 len = parms.length ();
4703 for (i = 0; i < len; i++)
4704 if (parms[i] == base)
4705 return i;
4706 gcc_unreachable ();
4709 /* Convert the decisions made at the representative level into compact
4710 parameter adjustments. REPRESENTATIVES are pointers to first
4711 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4712 final number of adjustments. */
4714 static ipa_parm_adjustment_vec
4715 turn_representatives_into_adjustments (vec<access_p> representatives,
4716 int adjustments_count)
4718 vec<tree> parms;
4719 ipa_parm_adjustment_vec adjustments;
4720 tree parm;
4721 int i;
4723 gcc_assert (adjustments_count > 0);
4724 parms = ipa_get_vector_of_formal_parms (current_function_decl);
4725 adjustments.create (adjustments_count);
4726 parm = DECL_ARGUMENTS (current_function_decl);
4727 for (i = 0; i < func_param_count; i++, parm = DECL_CHAIN (parm))
4729 struct access *repr = representatives[i];
4731 if (!repr || no_accesses_p (repr))
4733 struct ipa_parm_adjustment adj;
4735 memset (&adj, 0, sizeof (adj));
4736 adj.base_index = get_param_index (parm, parms);
4737 adj.base = parm;
4738 if (!repr)
4739 adj.op = IPA_PARM_OP_COPY;
4740 else
4741 adj.op = IPA_PARM_OP_REMOVE;
4742 adj.arg_prefix = "ISRA";
4743 adjustments.quick_push (adj);
4745 else
4747 struct ipa_parm_adjustment adj;
4748 int index = get_param_index (parm, parms);
4750 for (; repr; repr = repr->next_grp)
4752 memset (&adj, 0, sizeof (adj));
4753 gcc_assert (repr->base == parm);
4754 adj.base_index = index;
4755 adj.base = repr->base;
4756 adj.type = repr->type;
4757 adj.alias_ptr_type = reference_alias_ptr_type (repr->expr);
4758 adj.offset = repr->offset;
4759 adj.reverse = repr->reverse;
4760 adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
4761 && (repr->grp_maybe_modified
4762 || repr->grp_not_necessarilly_dereferenced));
4763 adj.arg_prefix = "ISRA";
4764 adjustments.quick_push (adj);
4768 parms.release ();
4769 return adjustments;
4772 /* Analyze the collected accesses and produce a plan what to do with the
4773 parameters in the form of adjustments, NULL meaning nothing. */
4775 static ipa_parm_adjustment_vec
4776 analyze_all_param_acesses (void)
4778 enum ipa_splicing_result repr_state;
4779 bool proceed = false;
4780 int i, adjustments_count = 0;
4781 vec<access_p> representatives;
4782 ipa_parm_adjustment_vec adjustments;
4784 repr_state = splice_all_param_accesses (representatives);
4785 if (repr_state == NO_GOOD_ACCESS)
4786 return ipa_parm_adjustment_vec ();
4788 /* If there are any parameters passed by reference which are not modified
4789 directly, we need to check whether they can be modified indirectly. */
4790 if (repr_state == UNMODIF_BY_REF_ACCESSES)
4792 analyze_caller_dereference_legality (representatives);
4793 analyze_modified_params (representatives);
4796 for (i = 0; i < func_param_count; i++)
4798 struct access *repr = representatives[i];
4800 if (repr && !no_accesses_p (repr))
4802 if (repr->grp_scalar_ptr)
4804 adjustments_count++;
4805 if (repr->grp_not_necessarilly_dereferenced
4806 || repr->grp_maybe_modified)
4807 representatives[i] = NULL;
4808 else
4810 proceed = true;
4811 sra_stats.scalar_by_ref_to_by_val++;
4814 else
4816 int new_components = decide_one_param_reduction (repr);
4818 if (new_components == 0)
4820 representatives[i] = NULL;
4821 adjustments_count++;
4823 else
4825 adjustments_count += new_components;
4826 sra_stats.aggregate_params_reduced++;
4827 sra_stats.param_reductions_created += new_components;
4828 proceed = true;
4832 else
4834 if (no_accesses_p (repr))
4836 proceed = true;
4837 sra_stats.deleted_unused_parameters++;
4839 adjustments_count++;
4843 if (!proceed && dump_file)
4844 fprintf (dump_file, "NOT proceeding to change params.\n");
4846 if (proceed)
4847 adjustments = turn_representatives_into_adjustments (representatives,
4848 adjustments_count);
4849 else
4850 adjustments = ipa_parm_adjustment_vec ();
4852 representatives.release ();
4853 return adjustments;
4856 /* If a parameter replacement identified by ADJ does not yet exist in the form
4857 of declaration, create it and record it, otherwise return the previously
4858 created one. */
4860 static tree
4861 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
4863 tree repl;
4864 if (!adj->new_ssa_base)
4866 char *pretty_name = make_fancy_name (adj->base);
4868 repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR");
4869 DECL_NAME (repl) = get_identifier (pretty_name);
4870 DECL_NAMELESS (repl) = 1;
4871 obstack_free (&name_obstack, pretty_name);
4873 adj->new_ssa_base = repl;
4875 else
4876 repl = adj->new_ssa_base;
4877 return repl;
4880 /* Find the first adjustment for a particular parameter BASE in a vector of
4881 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4882 adjustment. */
4884 static struct ipa_parm_adjustment *
4885 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
4887 int i, len;
4889 len = adjustments.length ();
4890 for (i = 0; i < len; i++)
4892 struct ipa_parm_adjustment *adj;
4894 adj = &adjustments[i];
4895 if (adj->op != IPA_PARM_OP_COPY && adj->base == base)
4896 return adj;
4899 return NULL;
4902 /* If OLD_NAME, which is being defined by statement STMT, is an SSA_NAME of a
4903 parameter which is to be removed because its value is not used, create a new
4904 SSA_NAME relating to a replacement VAR_DECL, replace all uses of the
4905 original with it and return it. If there is no need to re-map, return NULL.
4906 ADJUSTMENTS is a pointer to a vector of IPA-SRA adjustments. */
4908 static tree
4909 replace_removed_params_ssa_names (tree old_name, gimple *stmt,
4910 ipa_parm_adjustment_vec adjustments)
4912 struct ipa_parm_adjustment *adj;
4913 tree decl, repl, new_name;
4915 if (TREE_CODE (old_name) != SSA_NAME)
4916 return NULL;
4918 decl = SSA_NAME_VAR (old_name);
4919 if (decl == NULL_TREE
4920 || TREE_CODE (decl) != PARM_DECL)
4921 return NULL;
4923 adj = get_adjustment_for_base (adjustments, decl);
4924 if (!adj)
4925 return NULL;
4927 repl = get_replaced_param_substitute (adj);
4928 new_name = make_ssa_name (repl, stmt);
4929 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name)
4930 = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name);
4932 if (dump_file)
4934 fprintf (dump_file, "replacing an SSA name of a removed param ");
4935 print_generic_expr (dump_file, old_name);
4936 fprintf (dump_file, " with ");
4937 print_generic_expr (dump_file, new_name);
4938 fprintf (dump_file, "\n");
4941 replace_uses_by (old_name, new_name);
4942 return new_name;
4945 /* If the statement STMT contains any expressions that need to replaced with a
4946 different one as noted by ADJUSTMENTS, do so. Handle any potential type
4947 incompatibilities (GSI is used to accommodate conversion statements and must
4948 point to the statement). Return true iff the statement was modified. */
4950 static bool
4951 sra_ipa_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi,
4952 ipa_parm_adjustment_vec adjustments)
4954 tree *lhs_p, *rhs_p;
4955 bool any;
4957 if (!gimple_assign_single_p (stmt))
4958 return false;
4960 rhs_p = gimple_assign_rhs1_ptr (stmt);
4961 lhs_p = gimple_assign_lhs_ptr (stmt);
4963 any = ipa_modify_expr (rhs_p, false, adjustments);
4964 any |= ipa_modify_expr (lhs_p, false, adjustments);
4965 if (any)
4967 tree new_rhs = NULL_TREE;
4969 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
4971 if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
4973 /* V_C_Es of constructors can cause trouble (PR 42714). */
4974 if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
4975 *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
4976 else
4977 *rhs_p = build_constructor (TREE_TYPE (*lhs_p),
4978 NULL);
4980 else
4981 new_rhs = fold_build1_loc (gimple_location (stmt),
4982 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
4983 *rhs_p);
4985 else if (REFERENCE_CLASS_P (*rhs_p)
4986 && is_gimple_reg_type (TREE_TYPE (*lhs_p))
4987 && !is_gimple_reg (*lhs_p))
4988 /* This can happen when an assignment in between two single field
4989 structures is turned into an assignment in between two pointers to
4990 scalars (PR 42237). */
4991 new_rhs = *rhs_p;
4993 if (new_rhs)
4995 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
4996 true, GSI_SAME_STMT);
4998 gimple_assign_set_rhs_from_tree (gsi, tmp);
5001 return true;
5004 return false;
5007 /* Traverse the function body and all modifications as described in
5008 ADJUSTMENTS. Return true iff the CFG has been changed. */
5010 bool
5011 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
5013 bool cfg_changed = false;
5014 basic_block bb;
5016 FOR_EACH_BB_FN (bb, cfun)
5018 gimple_stmt_iterator gsi;
5020 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5022 gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
5023 tree new_lhs, old_lhs = gimple_phi_result (phi);
5024 new_lhs = replace_removed_params_ssa_names (old_lhs, phi, adjustments);
5025 if (new_lhs)
5027 gimple_phi_set_result (phi, new_lhs);
5028 release_ssa_name (old_lhs);
5032 gsi = gsi_start_bb (bb);
5033 while (!gsi_end_p (gsi))
5035 gimple *stmt = gsi_stmt (gsi);
5036 bool modified = false;
5037 tree *t;
5038 unsigned i;
5040 switch (gimple_code (stmt))
5042 case GIMPLE_RETURN:
5043 t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
5044 if (*t != NULL_TREE)
5045 modified |= ipa_modify_expr (t, true, adjustments);
5046 break;
5048 case GIMPLE_ASSIGN:
5049 modified |= sra_ipa_modify_assign (stmt, &gsi, adjustments);
5050 break;
5052 case GIMPLE_CALL:
5053 /* Operands must be processed before the lhs. */
5054 for (i = 0; i < gimple_call_num_args (stmt); i++)
5056 t = gimple_call_arg_ptr (stmt, i);
5057 modified |= ipa_modify_expr (t, true, adjustments);
5060 if (gimple_call_lhs (stmt))
5062 t = gimple_call_lhs_ptr (stmt);
5063 modified |= ipa_modify_expr (t, false, adjustments);
5065 break;
5067 case GIMPLE_ASM:
5069 gasm *asm_stmt = as_a <gasm *> (stmt);
5070 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
5072 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
5073 modified |= ipa_modify_expr (t, true, adjustments);
5075 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
5077 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
5078 modified |= ipa_modify_expr (t, false, adjustments);
5081 break;
5083 default:
5084 break;
5087 def_operand_p defp;
5088 ssa_op_iter iter;
5089 FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF)
5091 tree old_def = DEF_FROM_PTR (defp);
5092 if (tree new_def = replace_removed_params_ssa_names (old_def, stmt,
5093 adjustments))
5095 SET_DEF (defp, new_def);
5096 release_ssa_name (old_def);
5097 modified = true;
5101 if (modified)
5103 update_stmt (stmt);
5104 if (maybe_clean_eh_stmt (stmt)
5105 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
5106 cfg_changed = true;
5108 gsi_next (&gsi);
5112 return cfg_changed;
5115 /* Call gimple_debug_bind_reset_value on all debug statements describing
5116 gimple register parameters that are being removed or replaced. */
5118 static void
5119 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
5121 int i, len;
5122 gimple_stmt_iterator *gsip = NULL, gsi;
5124 if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
5126 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
5127 gsip = &gsi;
5129 len = adjustments.length ();
5130 for (i = 0; i < len; i++)
5132 struct ipa_parm_adjustment *adj;
5133 imm_use_iterator ui;
5134 gimple *stmt;
5135 gdebug *def_temp;
5136 tree name, vexpr, copy = NULL_TREE;
5137 use_operand_p use_p;
5139 adj = &adjustments[i];
5140 if (adj->op == IPA_PARM_OP_COPY || !is_gimple_reg (adj->base))
5141 continue;
5142 name = ssa_default_def (cfun, adj->base);
5143 vexpr = NULL;
5144 if (name)
5145 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
5147 if (gimple_clobber_p (stmt))
5149 gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
5150 unlink_stmt_vdef (stmt);
5151 gsi_remove (&cgsi, true);
5152 release_defs (stmt);
5153 continue;
5155 /* All other users must have been removed by
5156 ipa_sra_modify_function_body. */
5157 gcc_assert (is_gimple_debug (stmt));
5158 if (vexpr == NULL && gsip != NULL)
5160 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
5161 vexpr = make_node (DEBUG_EXPR_DECL);
5162 def_temp = gimple_build_debug_source_bind (vexpr, adj->base,
5163 NULL);
5164 DECL_ARTIFICIAL (vexpr) = 1;
5165 TREE_TYPE (vexpr) = TREE_TYPE (name);
5166 SET_DECL_MODE (vexpr, DECL_MODE (adj->base));
5167 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
5169 if (vexpr)
5171 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
5172 SET_USE (use_p, vexpr);
5174 else
5175 gimple_debug_bind_reset_value (stmt);
5176 update_stmt (stmt);
5178 /* Create a VAR_DECL for debug info purposes. */
5179 if (!DECL_IGNORED_P (adj->base))
5181 copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
5182 VAR_DECL, DECL_NAME (adj->base),
5183 TREE_TYPE (adj->base));
5184 if (DECL_PT_UID_SET_P (adj->base))
5185 SET_DECL_PT_UID (copy, DECL_PT_UID (adj->base));
5186 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (adj->base);
5187 TREE_READONLY (copy) = TREE_READONLY (adj->base);
5188 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (adj->base);
5189 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (adj->base);
5190 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (adj->base);
5191 DECL_IGNORED_P (copy) = DECL_IGNORED_P (adj->base);
5192 DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (adj->base);
5193 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
5194 SET_DECL_RTL (copy, 0);
5195 TREE_USED (copy) = 1;
5196 DECL_CONTEXT (copy) = current_function_decl;
5197 add_local_decl (cfun, copy);
5198 DECL_CHAIN (copy) =
5199 BLOCK_VARS (DECL_INITIAL (current_function_decl));
5200 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
5202 if (gsip != NULL && copy && target_for_debug_bind (adj->base))
5204 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
5205 if (vexpr)
5206 def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
5207 else
5208 def_temp = gimple_build_debug_source_bind (copy, adj->base,
5209 NULL);
5210 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
5215 /* Return false if all callers have at least as many actual arguments as there
5216 are formal parameters in the current function and that their types
5217 match. */
5219 static bool
5220 some_callers_have_mismatched_arguments_p (struct cgraph_node *node,
5221 void *data ATTRIBUTE_UNUSED)
5223 struct cgraph_edge *cs;
5224 for (cs = node->callers; cs; cs = cs->next_caller)
5225 if (!cs->call_stmt || !callsite_arguments_match_p (cs->call_stmt))
5226 return true;
5228 return false;
5231 /* Return false if all callers have vuse attached to a call statement. */
5233 static bool
5234 some_callers_have_no_vuse_p (struct cgraph_node *node,
5235 void *data ATTRIBUTE_UNUSED)
5237 struct cgraph_edge *cs;
5238 for (cs = node->callers; cs; cs = cs->next_caller)
5239 if (!cs->call_stmt || !gimple_vuse (cs->call_stmt))
5240 return true;
5242 return false;
5245 /* Convert all callers of NODE. */
5247 static bool
5248 convert_callers_for_node (struct cgraph_node *node,
5249 void *data)
5251 ipa_parm_adjustment_vec *adjustments = (ipa_parm_adjustment_vec *) data;
5252 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
5253 struct cgraph_edge *cs;
5255 for (cs = node->callers; cs; cs = cs->next_caller)
5257 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
5259 if (dump_file)
5260 fprintf (dump_file, "Adjusting call %s -> %s\n",
5261 cs->caller->dump_name (), cs->callee->dump_name ());
5263 ipa_modify_call_arguments (cs, cs->call_stmt, *adjustments);
5265 pop_cfun ();
5268 for (cs = node->callers; cs; cs = cs->next_caller)
5269 if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
5270 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
5271 compute_fn_summary (cs->caller, true);
5272 BITMAP_FREE (recomputed_callers);
5274 return true;
5277 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
5279 static void
5280 convert_callers (struct cgraph_node *node, tree old_decl,
5281 ipa_parm_adjustment_vec adjustments)
5283 basic_block this_block;
5285 node->call_for_symbol_and_aliases (convert_callers_for_node,
5286 &adjustments, false);
5288 if (!encountered_recursive_call)
5289 return;
5291 FOR_EACH_BB_FN (this_block, cfun)
5293 gimple_stmt_iterator gsi;
5295 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
5297 gcall *stmt;
5298 tree call_fndecl;
5299 stmt = dyn_cast <gcall *> (gsi_stmt (gsi));
5300 if (!stmt)
5301 continue;
5302 call_fndecl = gimple_call_fndecl (stmt);
5303 if (call_fndecl == old_decl)
5305 if (dump_file)
5306 fprintf (dump_file, "Adjusting recursive call");
5307 gimple_call_set_fndecl (stmt, node->decl);
5308 ipa_modify_call_arguments (NULL, stmt, adjustments);
5313 return;
5316 /* Perform all the modification required in IPA-SRA for NODE to have parameters
5317 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
5319 static bool
5320 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
5322 struct cgraph_node *new_node;
5323 bool cfg_changed;
5325 cgraph_edge::rebuild_edges ();
5326 free_dominance_info (CDI_DOMINATORS);
5327 pop_cfun ();
5329 /* This must be done after rebuilding cgraph edges for node above.
5330 Otherwise any recursive calls to node that are recorded in
5331 redirect_callers will be corrupted. */
5332 vec<cgraph_edge *> redirect_callers = node->collect_callers ();
5333 new_node = node->create_version_clone_with_body (redirect_callers, NULL,
5334 NULL, false, NULL, NULL,
5335 "isra");
5336 redirect_callers.release ();
5338 push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
5339 ipa_modify_formal_parameters (current_function_decl, adjustments);
5340 cfg_changed = ipa_sra_modify_function_body (adjustments);
5341 sra_ipa_reset_debug_stmts (adjustments);
5342 convert_callers (new_node, node->decl, adjustments);
5343 new_node->make_local ();
5344 return cfg_changed;
5347 /* Means of communication between ipa_sra_check_caller and
5348 ipa_sra_preliminary_function_checks. */
5350 struct ipa_sra_check_caller_data
5352 bool has_callers;
5353 bool bad_arg_alignment;
5354 bool has_thunk;
5357 /* If NODE has a caller, mark that fact in DATA which is pointer to
5358 ipa_sra_check_caller_data. Also check all aggregate arguments in all known
5359 calls if they are unit aligned and if not, set the appropriate flag in DATA
5360 too. */
5362 static bool
5363 ipa_sra_check_caller (struct cgraph_node *node, void *data)
5365 if (!node->callers)
5366 return false;
5368 struct ipa_sra_check_caller_data *iscc;
5369 iscc = (struct ipa_sra_check_caller_data *) data;
5370 iscc->has_callers = true;
5372 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
5374 if (cs->caller->thunk.thunk_p)
5376 iscc->has_thunk = true;
5377 return true;
5379 gimple *call_stmt = cs->call_stmt;
5380 unsigned count = gimple_call_num_args (call_stmt);
5381 for (unsigned i = 0; i < count; i++)
5383 tree arg = gimple_call_arg (call_stmt, i);
5384 if (is_gimple_reg (arg))
5385 continue;
5387 tree offset;
5388 HOST_WIDE_INT bitsize, bitpos;
5389 machine_mode mode;
5390 int unsignedp, reversep, volatilep = 0;
5391 get_inner_reference (arg, &bitsize, &bitpos, &offset, &mode,
5392 &unsignedp, &reversep, &volatilep);
5393 if (bitpos % BITS_PER_UNIT)
5395 iscc->bad_arg_alignment = true;
5396 return true;
5401 return false;
5404 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
5405 attributes, return true otherwise. NODE is the cgraph node of the current
5406 function. */
5408 static bool
5409 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
5411 if (!node->can_be_local_p ())
5413 if (dump_file)
5414 fprintf (dump_file, "Function not local to this compilation unit.\n");
5415 return false;
5418 if (!node->local.can_change_signature)
5420 if (dump_file)
5421 fprintf (dump_file, "Function can not change signature.\n");
5422 return false;
5425 if (!tree_versionable_function_p (node->decl))
5427 if (dump_file)
5428 fprintf (dump_file, "Function is not versionable.\n");
5429 return false;
5432 if (!opt_for_fn (node->decl, optimize)
5433 || !opt_for_fn (node->decl, flag_ipa_sra))
5435 if (dump_file)
5436 fprintf (dump_file, "Function not optimized.\n");
5437 return false;
5440 if (DECL_VIRTUAL_P (current_function_decl))
5442 if (dump_file)
5443 fprintf (dump_file, "Function is a virtual method.\n");
5444 return false;
5447 if ((DECL_ONE_ONLY (node->decl) || DECL_EXTERNAL (node->decl))
5448 && ipa_fn_summaries->get (node)->size >= MAX_INLINE_INSNS_AUTO)
5450 if (dump_file)
5451 fprintf (dump_file, "Function too big to be made truly local.\n");
5452 return false;
5455 if (cfun->stdarg)
5457 if (dump_file)
5458 fprintf (dump_file, "Function uses stdarg. \n");
5459 return false;
5462 if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
5463 return false;
5465 if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
5467 if (dump_file)
5468 fprintf (dump_file, "Always inline function will be inlined "
5469 "anyway. \n");
5470 return false;
5473 struct ipa_sra_check_caller_data iscc;
5474 memset (&iscc, 0, sizeof(iscc));
5475 node->call_for_symbol_and_aliases (ipa_sra_check_caller, &iscc, true);
5476 if (!iscc.has_callers)
5478 if (dump_file)
5479 fprintf (dump_file,
5480 "Function has no callers in this compilation unit.\n");
5481 return false;
5484 if (iscc.bad_arg_alignment)
5486 if (dump_file)
5487 fprintf (dump_file,
5488 "A function call has an argument with non-unit alignment.\n");
5489 return false;
5492 if (iscc.has_thunk)
5494 if (dump_file)
5495 fprintf (dump_file,
5496 "A has thunk.\n");
5497 return false;
5500 return true;
5503 /* Perform early interprocedural SRA. */
5505 static unsigned int
5506 ipa_early_sra (void)
5508 struct cgraph_node *node = cgraph_node::get (current_function_decl);
5509 ipa_parm_adjustment_vec adjustments;
5510 int ret = 0;
5512 if (!ipa_sra_preliminary_function_checks (node))
5513 return 0;
5515 sra_initialize ();
5516 sra_mode = SRA_MODE_EARLY_IPA;
5518 if (!find_param_candidates ())
5520 if (dump_file)
5521 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
5522 goto simple_out;
5525 if (node->call_for_symbol_and_aliases
5526 (some_callers_have_mismatched_arguments_p, NULL, true))
5528 if (dump_file)
5529 fprintf (dump_file, "There are callers with insufficient number of "
5530 "arguments or arguments with type mismatches.\n");
5531 goto simple_out;
5534 if (node->call_for_symbol_and_aliases
5535 (some_callers_have_no_vuse_p, NULL, true))
5537 if (dump_file)
5538 fprintf (dump_file, "There are callers with no VUSE attached "
5539 "to a call stmt.\n");
5540 goto simple_out;
5543 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
5544 func_param_count
5545 * last_basic_block_for_fn (cfun));
5546 final_bbs = BITMAP_ALLOC (NULL);
5548 scan_function ();
5549 if (encountered_apply_args)
5551 if (dump_file)
5552 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
5553 goto out;
5556 if (encountered_unchangable_recursive_call)
5558 if (dump_file)
5559 fprintf (dump_file, "Function calls itself with insufficient "
5560 "number of arguments.\n");
5561 goto out;
5564 adjustments = analyze_all_param_acesses ();
5565 if (!adjustments.exists ())
5566 goto out;
5567 if (dump_file)
5568 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
5570 if (modify_function (node, adjustments))
5571 ret = TODO_update_ssa | TODO_cleanup_cfg;
5572 else
5573 ret = TODO_update_ssa;
5574 adjustments.release ();
5576 statistics_counter_event (cfun, "Unused parameters deleted",
5577 sra_stats.deleted_unused_parameters);
5578 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
5579 sra_stats.scalar_by_ref_to_by_val);
5580 statistics_counter_event (cfun, "Aggregate parameters broken up",
5581 sra_stats.aggregate_params_reduced);
5582 statistics_counter_event (cfun, "Aggregate parameter components created",
5583 sra_stats.param_reductions_created);
5585 out:
5586 BITMAP_FREE (final_bbs);
5587 free (bb_dereferences);
5588 simple_out:
5589 sra_deinitialize ();
5590 return ret;
5593 namespace {
5595 const pass_data pass_data_early_ipa_sra =
5597 GIMPLE_PASS, /* type */
5598 "eipa_sra", /* name */
5599 OPTGROUP_NONE, /* optinfo_flags */
5600 TV_IPA_SRA, /* tv_id */
5601 0, /* properties_required */
5602 0, /* properties_provided */
5603 0, /* properties_destroyed */
5604 0, /* todo_flags_start */
5605 TODO_dump_symtab, /* todo_flags_finish */
5608 class pass_early_ipa_sra : public gimple_opt_pass
5610 public:
5611 pass_early_ipa_sra (gcc::context *ctxt)
5612 : gimple_opt_pass (pass_data_early_ipa_sra, ctxt)
5615 /* opt_pass methods: */
5616 virtual bool gate (function *) { return flag_ipa_sra && dbg_cnt (eipa_sra); }
5617 virtual unsigned int execute (function *) { return ipa_early_sra (); }
5619 }; // class pass_early_ipa_sra
5621 } // anon namespace
5623 gimple_opt_pass *
5624 make_pass_early_ipa_sra (gcc::context *ctxt)
5626 return new pass_early_ipa_sra (ctxt);