]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/tree-sra.c
gimple.h: Remove all includes.
[thirdparty/gcc.git] / gcc / tree-sra.c
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-2013 Free Software Foundation, Inc.
5 Contributed by Martin Jambor <mjambor@suse.cz>
6
7 This file is part of GCC.
8
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.
13
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.
18
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/>. */
22
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.
27
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.
32
33 Both passes operate in four stages:
34
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.
38
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.
46
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.
50
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.
55
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).
60
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.
64
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.
67
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. */
73
74 #include "config.h"
75 #include "system.h"
76 #include "coretypes.h"
77 #include "hash-table.h"
78 #include "alloc-pool.h"
79 #include "tm.h"
80 #include "tree.h"
81 #include "pointer-set.h"
82 #include "basic-block.h"
83 #include "tree-ssa-alias.h"
84 #include "internal-fn.h"
85 #include "tree-eh.h"
86 #include "gimple-expr.h"
87 #include "is-a.h"
88 #include "gimple.h"
89 #include "stor-layout.h"
90 #include "gimplify.h"
91 #include "gimple-iterator.h"
92 #include "gimplify-me.h"
93 #include "gimple-walk.h"
94 #include "bitmap.h"
95 #include "gimple-ssa.h"
96 #include "tree-cfg.h"
97 #include "tree-phinodes.h"
98 #include "ssa-iterators.h"
99 #include "stringpool.h"
100 #include "tree-ssanames.h"
101 #include "expr.h"
102 #include "tree-dfa.h"
103 #include "tree-ssa.h"
104 #include "tree-pass.h"
105 #include "ipa-prop.h"
106 #include "statistics.h"
107 #include "params.h"
108 #include "target.h"
109 #include "flags.h"
110 #include "dbgcnt.h"
111 #include "tree-inline.h"
112 #include "gimple-pretty-print.h"
113 #include "ipa-inline.h"
114 #include "ipa-utils.h"
115
116 /* Enumeration of all aggregate reductions we can do. */
117 enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
118 SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
119 SRA_MODE_INTRA }; /* late intraprocedural SRA */
120
121 /* Global variable describing which aggregate reduction we are performing at
122 the moment. */
123 static enum sra_mode sra_mode;
124
125 struct assign_link;
126
127 /* ACCESS represents each access to an aggregate variable (as a whole or a
128 part). It can also represent a group of accesses that refer to exactly the
129 same fragment of an aggregate (i.e. those that have exactly the same offset
130 and size). Such representatives for a single aggregate, once determined,
131 are linked in a linked list and have the group fields set.
132
133 Moreover, when doing intraprocedural SRA, a tree is built from those
134 representatives (by the means of first_child and next_sibling pointers), in
135 which all items in a subtree are "within" the root, i.e. their offset is
136 greater or equal to offset of the root and offset+size is smaller or equal
137 to offset+size of the root. Children of an access are sorted by offset.
138
139 Note that accesses to parts of vector and complex number types always
140 represented by an access to the whole complex number or a vector. It is a
141 duty of the modifying functions to replace them appropriately. */
142
143 struct access
144 {
145 /* Values returned by `get_ref_base_and_extent' for each component reference
146 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
147 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
148 HOST_WIDE_INT offset;
149 HOST_WIDE_INT size;
150 tree base;
151
152 /* Expression. It is context dependent so do not use it to create new
153 expressions to access the original aggregate. See PR 42154 for a
154 testcase. */
155 tree expr;
156 /* Type. */
157 tree type;
158
159 /* The statement this access belongs to. */
160 gimple stmt;
161
162 /* Next group representative for this aggregate. */
163 struct access *next_grp;
164
165 /* Pointer to the group representative. Pointer to itself if the struct is
166 the representative. */
167 struct access *group_representative;
168
169 /* If this access has any children (in terms of the definition above), this
170 points to the first one. */
171 struct access *first_child;
172
173 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
174 described above. In IPA-SRA this is a pointer to the next access
175 belonging to the same group (having the same representative). */
176 struct access *next_sibling;
177
178 /* Pointers to the first and last element in the linked list of assign
179 links. */
180 struct assign_link *first_link, *last_link;
181
182 /* Pointer to the next access in the work queue. */
183 struct access *next_queued;
184
185 /* Replacement variable for this access "region." Never to be accessed
186 directly, always only by the means of get_access_replacement() and only
187 when grp_to_be_replaced flag is set. */
188 tree replacement_decl;
189
190 /* Is this particular access write access? */
191 unsigned write : 1;
192
193 /* Is this access an access to a non-addressable field? */
194 unsigned non_addressable : 1;
195
196 /* Is this access currently in the work queue? */
197 unsigned grp_queued : 1;
198
199 /* Does this group contain a write access? This flag is propagated down the
200 access tree. */
201 unsigned grp_write : 1;
202
203 /* Does this group contain a read access? This flag is propagated down the
204 access tree. */
205 unsigned grp_read : 1;
206
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;
210
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;
214
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;
218
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;
222
223 /* Is this access an artificial one created to scalarize some record
224 entirely? */
225 unsigned grp_total_scalarization : 1;
226
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;
231
232 /* Is the subtree rooted in this access fully covered by scalar
233 replacements? */
234 unsigned grp_covered : 1;
235
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;
239
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;
244
245 /* Does this access and/or group contain a write access through a
246 BIT_FIELD_REF? */
247 unsigned grp_partial_lhs : 1;
248
249 /* Set when a scalar replacement should be created for this variable. */
250 unsigned grp_to_be_replaced : 1;
251
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;
255
256 /* Should TREE_NO_WARNING of a replacement be set? */
257 unsigned grp_no_warning : 1;
258
259 /* Is it possible that the group refers to data which might be (directly or
260 otherwise) modified? */
261 unsigned grp_maybe_modified : 1;
262
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;
267
268 /* Set when we discover that this pointer is not safe to dereference in the
269 caller. */
270 unsigned grp_not_necessarilly_dereferenced : 1;
271 };
272
273 typedef struct access *access_p;
274
275
276 /* Alloc pool for allocating access structures. */
277 static alloc_pool access_pool;
278
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
283 {
284 struct access *lacc, *racc;
285 struct assign_link *next;
286 };
287
288 /* Alloc pool for allocating assign link structures. */
289 static alloc_pool link_pool;
290
291 /* Base (tree) -> Vector (vec<access_p> *) map. */
292 static struct pointer_map_t *base_access_vec;
293
294 /* Candidate hash table helpers. */
295
296 struct uid_decl_hasher : typed_noop_remove <tree_node>
297 {
298 typedef tree_node value_type;
299 typedef tree_node compare_type;
300 static inline hashval_t hash (const value_type *);
301 static inline bool equal (const value_type *, const compare_type *);
302 };
303
304 /* Hash a tree in a uid_decl_map. */
305
306 inline hashval_t
307 uid_decl_hasher::hash (const value_type *item)
308 {
309 return item->decl_minimal.uid;
310 }
311
312 /* Return true if the DECL_UID in both trees are equal. */
313
314 inline bool
315 uid_decl_hasher::equal (const value_type *a, const compare_type *b)
316 {
317 return (a->decl_minimal.uid == b->decl_minimal.uid);
318 }
319
320 /* Set of candidates. */
321 static bitmap candidate_bitmap;
322 static hash_table <uid_decl_hasher> candidates;
323
324 /* For a candidate UID return the candidates decl. */
325
326 static inline tree
327 candidate (unsigned uid)
328 {
329 tree_node t;
330 t.decl_minimal.uid = uid;
331 return candidates.find_with_hash (&t, static_cast <hashval_t> (uid));
332 }
333
334 /* Bitmap of candidates which we should try to entirely scalarize away and
335 those which cannot be (because they are and need be used as a whole). */
336 static bitmap should_scalarize_away_bitmap, cannot_scalarize_away_bitmap;
337
338 /* Obstack for creation of fancy names. */
339 static struct obstack name_obstack;
340
341 /* Head of a linked list of accesses that need to have its subaccesses
342 propagated to their assignment counterparts. */
343 static struct access *work_queue_head;
344
345 /* Number of parameters of the analyzed function when doing early ipa SRA. */
346 static int func_param_count;
347
348 /* scan_function sets the following to true if it encounters a call to
349 __builtin_apply_args. */
350 static bool encountered_apply_args;
351
352 /* Set by scan_function when it finds a recursive call. */
353 static bool encountered_recursive_call;
354
355 /* Set by scan_function when it finds a recursive call with less actual
356 arguments than formal parameters.. */
357 static bool encountered_unchangable_recursive_call;
358
359 /* This is a table in which for each basic block and parameter there is a
360 distance (offset + size) in that parameter which is dereferenced and
361 accessed in that BB. */
362 static HOST_WIDE_INT *bb_dereferences;
363 /* Bitmap of BBs that can cause the function to "stop" progressing by
364 returning, throwing externally, looping infinitely or calling a function
365 which might abort etc.. */
366 static bitmap final_bbs;
367
368 /* Representative of no accesses at all. */
369 static struct access no_accesses_representant;
370
371 /* Predicate to test the special value. */
372
373 static inline bool
374 no_accesses_p (struct access *access)
375 {
376 return access == &no_accesses_representant;
377 }
378
379 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
380 representative fields are dumped, otherwise those which only describe the
381 individual access are. */
382
383 static struct
384 {
385 /* Number of processed aggregates is readily available in
386 analyze_all_variable_accesses and so is not stored here. */
387
388 /* Number of created scalar replacements. */
389 int replacements;
390
391 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
392 expression. */
393 int exprs;
394
395 /* Number of statements created by generate_subtree_copies. */
396 int subtree_copies;
397
398 /* Number of statements created by load_assign_lhs_subreplacements. */
399 int subreplacements;
400
401 /* Number of times sra_modify_assign has deleted a statement. */
402 int deleted;
403
404 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
405 RHS reparately due to type conversions or nonexistent matching
406 references. */
407 int separate_lhs_rhs_handling;
408
409 /* Number of parameters that were removed because they were unused. */
410 int deleted_unused_parameters;
411
412 /* Number of scalars passed as parameters by reference that have been
413 converted to be passed by value. */
414 int scalar_by_ref_to_by_val;
415
416 /* Number of aggregate parameters that were replaced by one or more of their
417 components. */
418 int aggregate_params_reduced;
419
420 /* Numbber of components created when splitting aggregate parameters. */
421 int param_reductions_created;
422 } sra_stats;
423
424 static void
425 dump_access (FILE *f, struct access *access, bool grp)
426 {
427 fprintf (f, "access { ");
428 fprintf (f, "base = (%d)'", DECL_UID (access->base));
429 print_generic_expr (f, access->base, 0);
430 fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
431 fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
432 fprintf (f, ", expr = ");
433 print_generic_expr (f, access->expr, 0);
434 fprintf (f, ", type = ");
435 print_generic_expr (f, access->type, 0);
436 if (grp)
437 fprintf (f, ", grp_read = %d, grp_write = %d, grp_assignment_read = %d, "
438 "grp_assignment_write = %d, grp_scalar_read = %d, "
439 "grp_scalar_write = %d, grp_total_scalarization = %d, "
440 "grp_hint = %d, grp_covered = %d, "
441 "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
442 "grp_partial_lhs = %d, grp_to_be_replaced = %d, "
443 "grp_to_be_debug_replaced = %d, grp_maybe_modified = %d, "
444 "grp_not_necessarilly_dereferenced = %d\n",
445 access->grp_read, access->grp_write, access->grp_assignment_read,
446 access->grp_assignment_write, access->grp_scalar_read,
447 access->grp_scalar_write, access->grp_total_scalarization,
448 access->grp_hint, access->grp_covered,
449 access->grp_unscalarizable_region, access->grp_unscalarized_data,
450 access->grp_partial_lhs, access->grp_to_be_replaced,
451 access->grp_to_be_debug_replaced, access->grp_maybe_modified,
452 access->grp_not_necessarilly_dereferenced);
453 else
454 fprintf (f, ", write = %d, grp_total_scalarization = %d, "
455 "grp_partial_lhs = %d\n",
456 access->write, access->grp_total_scalarization,
457 access->grp_partial_lhs);
458 }
459
460 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
461
462 static void
463 dump_access_tree_1 (FILE *f, struct access *access, int level)
464 {
465 do
466 {
467 int i;
468
469 for (i = 0; i < level; i++)
470 fputs ("* ", dump_file);
471
472 dump_access (f, access, true);
473
474 if (access->first_child)
475 dump_access_tree_1 (f, access->first_child, level + 1);
476
477 access = access->next_sibling;
478 }
479 while (access);
480 }
481
482 /* Dump all access trees for a variable, given the pointer to the first root in
483 ACCESS. */
484
485 static void
486 dump_access_tree (FILE *f, struct access *access)
487 {
488 for (; access; access = access->next_grp)
489 dump_access_tree_1 (f, access, 0);
490 }
491
492 /* Return true iff ACC is non-NULL and has subaccesses. */
493
494 static inline bool
495 access_has_children_p (struct access *acc)
496 {
497 return acc && acc->first_child;
498 }
499
500 /* Return true iff ACC is (partly) covered by at least one replacement. */
501
502 static bool
503 access_has_replacements_p (struct access *acc)
504 {
505 struct access *child;
506 if (acc->grp_to_be_replaced)
507 return true;
508 for (child = acc->first_child; child; child = child->next_sibling)
509 if (access_has_replacements_p (child))
510 return true;
511 return false;
512 }
513
514 /* Return a vector of pointers to accesses for the variable given in BASE or
515 NULL if there is none. */
516
517 static vec<access_p> *
518 get_base_access_vector (tree base)
519 {
520 void **slot;
521
522 slot = pointer_map_contains (base_access_vec, base);
523 if (!slot)
524 return NULL;
525 else
526 return *(vec<access_p> **) slot;
527 }
528
529 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
530 in ACCESS. Return NULL if it cannot be found. */
531
532 static struct access *
533 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
534 HOST_WIDE_INT size)
535 {
536 while (access && (access->offset != offset || access->size != size))
537 {
538 struct access *child = access->first_child;
539
540 while (child && (child->offset + child->size <= offset))
541 child = child->next_sibling;
542 access = child;
543 }
544
545 return access;
546 }
547
548 /* Return the first group representative for DECL or NULL if none exists. */
549
550 static struct access *
551 get_first_repr_for_decl (tree base)
552 {
553 vec<access_p> *access_vec;
554
555 access_vec = get_base_access_vector (base);
556 if (!access_vec)
557 return NULL;
558
559 return (*access_vec)[0];
560 }
561
562 /* Find an access representative for the variable BASE and given OFFSET and
563 SIZE. Requires that access trees have already been built. Return NULL if
564 it cannot be found. */
565
566 static struct access *
567 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
568 HOST_WIDE_INT size)
569 {
570 struct access *access;
571
572 access = get_first_repr_for_decl (base);
573 while (access && (access->offset + access->size <= offset))
574 access = access->next_grp;
575 if (!access)
576 return NULL;
577
578 return find_access_in_subtree (access, offset, size);
579 }
580
581 /* Add LINK to the linked list of assign links of RACC. */
582 static void
583 add_link_to_rhs (struct access *racc, struct assign_link *link)
584 {
585 gcc_assert (link->racc == racc);
586
587 if (!racc->first_link)
588 {
589 gcc_assert (!racc->last_link);
590 racc->first_link = link;
591 }
592 else
593 racc->last_link->next = link;
594
595 racc->last_link = link;
596 link->next = NULL;
597 }
598
599 /* Move all link structures in their linked list in OLD_RACC to the linked list
600 in NEW_RACC. */
601 static void
602 relink_to_new_repr (struct access *new_racc, struct access *old_racc)
603 {
604 if (!old_racc->first_link)
605 {
606 gcc_assert (!old_racc->last_link);
607 return;
608 }
609
610 if (new_racc->first_link)
611 {
612 gcc_assert (!new_racc->last_link->next);
613 gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
614
615 new_racc->last_link->next = old_racc->first_link;
616 new_racc->last_link = old_racc->last_link;
617 }
618 else
619 {
620 gcc_assert (!new_racc->last_link);
621
622 new_racc->first_link = old_racc->first_link;
623 new_racc->last_link = old_racc->last_link;
624 }
625 old_racc->first_link = old_racc->last_link = NULL;
626 }
627
628 /* Add ACCESS to the work queue (which is actually a stack). */
629
630 static void
631 add_access_to_work_queue (struct access *access)
632 {
633 if (!access->grp_queued)
634 {
635 gcc_assert (!access->next_queued);
636 access->next_queued = work_queue_head;
637 access->grp_queued = 1;
638 work_queue_head = access;
639 }
640 }
641
642 /* Pop an access from the work queue, and return it, assuming there is one. */
643
644 static struct access *
645 pop_access_from_work_queue (void)
646 {
647 struct access *access = work_queue_head;
648
649 work_queue_head = access->next_queued;
650 access->next_queued = NULL;
651 access->grp_queued = 0;
652 return access;
653 }
654
655
656 /* Allocate necessary structures. */
657
658 static void
659 sra_initialize (void)
660 {
661 candidate_bitmap = BITMAP_ALLOC (NULL);
662 candidates.create (vec_safe_length (cfun->local_decls) / 2);
663 should_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
664 cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
665 gcc_obstack_init (&name_obstack);
666 access_pool = create_alloc_pool ("SRA accesses", sizeof (struct access), 16);
667 link_pool = create_alloc_pool ("SRA links", sizeof (struct assign_link), 16);
668 base_access_vec = pointer_map_create ();
669 memset (&sra_stats, 0, sizeof (sra_stats));
670 encountered_apply_args = false;
671 encountered_recursive_call = false;
672 encountered_unchangable_recursive_call = false;
673 }
674
675 /* Hook fed to pointer_map_traverse, deallocate stored vectors. */
676
677 static bool
678 delete_base_accesses (const void *key ATTRIBUTE_UNUSED, void **value,
679 void *data ATTRIBUTE_UNUSED)
680 {
681 vec<access_p> *access_vec = (vec<access_p> *) *value;
682 vec_free (access_vec);
683 return true;
684 }
685
686 /* Deallocate all general structures. */
687
688 static void
689 sra_deinitialize (void)
690 {
691 BITMAP_FREE (candidate_bitmap);
692 candidates.dispose ();
693 BITMAP_FREE (should_scalarize_away_bitmap);
694 BITMAP_FREE (cannot_scalarize_away_bitmap);
695 free_alloc_pool (access_pool);
696 free_alloc_pool (link_pool);
697 obstack_free (&name_obstack, NULL);
698
699 pointer_map_traverse (base_access_vec, delete_base_accesses, NULL);
700 pointer_map_destroy (base_access_vec);
701 }
702
703 /* Remove DECL from candidates for SRA and write REASON to the dump file if
704 there is one. */
705 static void
706 disqualify_candidate (tree decl, const char *reason)
707 {
708 if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl)))
709 candidates.clear_slot (candidates.find_slot_with_hash (decl,
710 DECL_UID (decl),
711 NO_INSERT));
712
713 if (dump_file && (dump_flags & TDF_DETAILS))
714 {
715 fprintf (dump_file, "! Disqualifying ");
716 print_generic_expr (dump_file, decl, 0);
717 fprintf (dump_file, " - %s\n", reason);
718 }
719 }
720
721 /* Return true iff the type contains a field or an element which does not allow
722 scalarization. */
723
724 static bool
725 type_internals_preclude_sra_p (tree type, const char **msg)
726 {
727 tree fld;
728 tree et;
729
730 switch (TREE_CODE (type))
731 {
732 case RECORD_TYPE:
733 case UNION_TYPE:
734 case QUAL_UNION_TYPE:
735 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
736 if (TREE_CODE (fld) == FIELD_DECL)
737 {
738 tree ft = TREE_TYPE (fld);
739
740 if (TREE_THIS_VOLATILE (fld))
741 {
742 *msg = "volatile structure field";
743 return true;
744 }
745 if (!DECL_FIELD_OFFSET (fld))
746 {
747 *msg = "no structure field offset";
748 return true;
749 }
750 if (!DECL_SIZE (fld))
751 {
752 *msg = "zero structure field size";
753 return true;
754 }
755 if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
756 {
757 *msg = "structure field offset not fixed";
758 return true;
759 }
760 if (!tree_fits_uhwi_p (DECL_SIZE (fld)))
761 {
762 *msg = "structure field size not fixed";
763 return true;
764 }
765 if (!tree_fits_shwi_p (bit_position (fld)))
766 {
767 *msg = "structure field size too big";
768 return true;
769 }
770 if (AGGREGATE_TYPE_P (ft)
771 && int_bit_position (fld) % BITS_PER_UNIT != 0)
772 {
773 *msg = "structure field is bit field";
774 return true;
775 }
776
777 if (AGGREGATE_TYPE_P (ft) && type_internals_preclude_sra_p (ft, msg))
778 return true;
779 }
780
781 return false;
782
783 case ARRAY_TYPE:
784 et = TREE_TYPE (type);
785
786 if (TYPE_VOLATILE (et))
787 {
788 *msg = "element type is volatile";
789 return true;
790 }
791
792 if (AGGREGATE_TYPE_P (et) && type_internals_preclude_sra_p (et, msg))
793 return true;
794
795 return false;
796
797 default:
798 return false;
799 }
800 }
801
802 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
803 base variable if it is. Return T if it is not an SSA_NAME. */
804
805 static tree
806 get_ssa_base_param (tree t)
807 {
808 if (TREE_CODE (t) == SSA_NAME)
809 {
810 if (SSA_NAME_IS_DEFAULT_DEF (t))
811 return SSA_NAME_VAR (t);
812 else
813 return NULL_TREE;
814 }
815 return t;
816 }
817
818 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
819 belongs to, unless the BB has already been marked as a potentially
820 final. */
821
822 static void
823 mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple stmt)
824 {
825 basic_block bb = gimple_bb (stmt);
826 int idx, parm_index = 0;
827 tree parm;
828
829 if (bitmap_bit_p (final_bbs, bb->index))
830 return;
831
832 for (parm = DECL_ARGUMENTS (current_function_decl);
833 parm && parm != base;
834 parm = DECL_CHAIN (parm))
835 parm_index++;
836
837 gcc_assert (parm_index < func_param_count);
838
839 idx = bb->index * func_param_count + parm_index;
840 if (bb_dereferences[idx] < dist)
841 bb_dereferences[idx] = dist;
842 }
843
844 /* Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in
845 the three fields. Also add it to the vector of accesses corresponding to
846 the base. Finally, return the new access. */
847
848 static struct access *
849 create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
850 {
851 vec<access_p> *v;
852 struct access *access;
853 void **slot;
854
855 access = (struct access *) pool_alloc (access_pool);
856 memset (access, 0, sizeof (struct access));
857 access->base = base;
858 access->offset = offset;
859 access->size = size;
860
861 slot = pointer_map_contains (base_access_vec, base);
862 if (slot)
863 v = (vec<access_p> *) *slot;
864 else
865 vec_alloc (v, 32);
866
867 v->safe_push (access);
868
869 *((vec<access_p> **)
870 pointer_map_insert (base_access_vec, base)) = v;
871
872 return access;
873 }
874
875 /* Create and insert access for EXPR. Return created access, or NULL if it is
876 not possible. */
877
878 static struct access *
879 create_access (tree expr, gimple stmt, bool write)
880 {
881 struct access *access;
882 HOST_WIDE_INT offset, size, max_size;
883 tree base = expr;
884 bool ptr, unscalarizable_region = false;
885
886 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
887
888 if (sra_mode == SRA_MODE_EARLY_IPA
889 && TREE_CODE (base) == MEM_REF)
890 {
891 base = get_ssa_base_param (TREE_OPERAND (base, 0));
892 if (!base)
893 return NULL;
894 ptr = true;
895 }
896 else
897 ptr = false;
898
899 if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
900 return NULL;
901
902 if (sra_mode == SRA_MODE_EARLY_IPA)
903 {
904 if (size < 0 || size != max_size)
905 {
906 disqualify_candidate (base, "Encountered a variable sized access.");
907 return NULL;
908 }
909 if (TREE_CODE (expr) == COMPONENT_REF
910 && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))
911 {
912 disqualify_candidate (base, "Encountered a bit-field access.");
913 return NULL;
914 }
915 gcc_checking_assert ((offset % BITS_PER_UNIT) == 0);
916
917 if (ptr)
918 mark_parm_dereference (base, offset + size, stmt);
919 }
920 else
921 {
922 if (size != max_size)
923 {
924 size = max_size;
925 unscalarizable_region = true;
926 }
927 if (size < 0)
928 {
929 disqualify_candidate (base, "Encountered an unconstrained access.");
930 return NULL;
931 }
932 }
933
934 access = create_access_1 (base, offset, size);
935 access->expr = expr;
936 access->type = TREE_TYPE (expr);
937 access->write = write;
938 access->grp_unscalarizable_region = unscalarizable_region;
939 access->stmt = stmt;
940
941 if (TREE_CODE (expr) == COMPONENT_REF
942 && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1)))
943 access->non_addressable = 1;
944
945 return access;
946 }
947
948
949 /* Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple
950 register types or (recursively) records with only these two kinds of fields.
951 It also returns false if any of these records contains a bit-field. */
952
953 static bool
954 type_consists_of_records_p (tree type)
955 {
956 tree fld;
957
958 if (TREE_CODE (type) != RECORD_TYPE)
959 return false;
960
961 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
962 if (TREE_CODE (fld) == FIELD_DECL)
963 {
964 tree ft = TREE_TYPE (fld);
965
966 if (DECL_BIT_FIELD (fld))
967 return false;
968
969 if (!is_gimple_reg_type (ft)
970 && !type_consists_of_records_p (ft))
971 return false;
972 }
973
974 return true;
975 }
976
977 /* Create total_scalarization accesses for all scalar type fields in DECL that
978 must be of a RECORD_TYPE conforming to type_consists_of_records_p. BASE
979 must be the top-most VAR_DECL representing the variable, OFFSET must be the
980 offset of DECL within BASE. REF must be the memory reference expression for
981 the given decl. */
982
983 static void
984 completely_scalarize_record (tree base, tree decl, HOST_WIDE_INT offset,
985 tree ref)
986 {
987 tree fld, decl_type = TREE_TYPE (decl);
988
989 for (fld = TYPE_FIELDS (decl_type); fld; fld = DECL_CHAIN (fld))
990 if (TREE_CODE (fld) == FIELD_DECL)
991 {
992 HOST_WIDE_INT pos = offset + int_bit_position (fld);
993 tree ft = TREE_TYPE (fld);
994 tree nref = build3 (COMPONENT_REF, TREE_TYPE (fld), ref, fld,
995 NULL_TREE);
996
997 if (is_gimple_reg_type (ft))
998 {
999 struct access *access;
1000 HOST_WIDE_INT size;
1001
1002 size = tree_to_uhwi (DECL_SIZE (fld));
1003 access = create_access_1 (base, pos, size);
1004 access->expr = nref;
1005 access->type = ft;
1006 access->grp_total_scalarization = 1;
1007 /* Accesses for intraprocedural SRA can have their stmt NULL. */
1008 }
1009 else
1010 completely_scalarize_record (base, fld, pos, nref);
1011 }
1012 }
1013
1014 /* Create total_scalarization accesses for all scalar type fields in VAR and
1015 for VAR a a whole. VAR must be of a RECORD_TYPE conforming to
1016 type_consists_of_records_p. */
1017
1018 static void
1019 completely_scalarize_var (tree var)
1020 {
1021 HOST_WIDE_INT size = tree_to_uhwi (DECL_SIZE (var));
1022 struct access *access;
1023
1024 access = create_access_1 (var, 0, size);
1025 access->expr = var;
1026 access->type = TREE_TYPE (var);
1027 access->grp_total_scalarization = 1;
1028
1029 completely_scalarize_record (var, var, 0, var);
1030 }
1031
1032 /* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
1033
1034 static inline bool
1035 contains_view_convert_expr_p (const_tree ref)
1036 {
1037 while (handled_component_p (ref))
1038 {
1039 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
1040 return true;
1041 ref = TREE_OPERAND (ref, 0);
1042 }
1043
1044 return false;
1045 }
1046
1047 /* Search the given tree for a declaration by skipping handled components and
1048 exclude it from the candidates. */
1049
1050 static void
1051 disqualify_base_of_expr (tree t, const char *reason)
1052 {
1053 t = get_base_address (t);
1054 if (sra_mode == SRA_MODE_EARLY_IPA
1055 && TREE_CODE (t) == MEM_REF)
1056 t = get_ssa_base_param (TREE_OPERAND (t, 0));
1057
1058 if (t && DECL_P (t))
1059 disqualify_candidate (t, reason);
1060 }
1061
1062 /* Scan expression EXPR and create access structures for all accesses to
1063 candidates for scalarization. Return the created access or NULL if none is
1064 created. */
1065
1066 static struct access *
1067 build_access_from_expr_1 (tree expr, gimple stmt, bool write)
1068 {
1069 struct access *ret = NULL;
1070 bool partial_ref;
1071
1072 if (TREE_CODE (expr) == BIT_FIELD_REF
1073 || TREE_CODE (expr) == IMAGPART_EXPR
1074 || TREE_CODE (expr) == REALPART_EXPR)
1075 {
1076 expr = TREE_OPERAND (expr, 0);
1077 partial_ref = true;
1078 }
1079 else
1080 partial_ref = false;
1081
1082 /* We need to dive through V_C_Es in order to get the size of its parameter
1083 and not the result type. Ada produces such statements. We are also
1084 capable of handling the topmost V_C_E but not any of those buried in other
1085 handled components. */
1086 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
1087 expr = TREE_OPERAND (expr, 0);
1088
1089 if (contains_view_convert_expr_p (expr))
1090 {
1091 disqualify_base_of_expr (expr, "V_C_E under a different handled "
1092 "component.");
1093 return NULL;
1094 }
1095
1096 switch (TREE_CODE (expr))
1097 {
1098 case MEM_REF:
1099 if (TREE_CODE (TREE_OPERAND (expr, 0)) != ADDR_EXPR
1100 && sra_mode != SRA_MODE_EARLY_IPA)
1101 return NULL;
1102 /* fall through */
1103 case VAR_DECL:
1104 case PARM_DECL:
1105 case RESULT_DECL:
1106 case COMPONENT_REF:
1107 case ARRAY_REF:
1108 case ARRAY_RANGE_REF:
1109 ret = create_access (expr, stmt, write);
1110 break;
1111
1112 default:
1113 break;
1114 }
1115
1116 if (write && partial_ref && ret)
1117 ret->grp_partial_lhs = 1;
1118
1119 return ret;
1120 }
1121
1122 /* Scan expression EXPR and create access structures for all accesses to
1123 candidates for scalarization. Return true if any access has been inserted.
1124 STMT must be the statement from which the expression is taken, WRITE must be
1125 true if the expression is a store and false otherwise. */
1126
1127 static bool
1128 build_access_from_expr (tree expr, gimple stmt, bool write)
1129 {
1130 struct access *access;
1131
1132 access = build_access_from_expr_1 (expr, stmt, write);
1133 if (access)
1134 {
1135 /* This means the aggregate is accesses as a whole in a way other than an
1136 assign statement and thus cannot be removed even if we had a scalar
1137 replacement for everything. */
1138 if (cannot_scalarize_away_bitmap)
1139 bitmap_set_bit (cannot_scalarize_away_bitmap, DECL_UID (access->base));
1140 return true;
1141 }
1142 return false;
1143 }
1144
1145 /* Disqualify LHS and RHS for scalarization if STMT must end its basic block in
1146 modes in which it matters, return true iff they have been disqualified. RHS
1147 may be NULL, in that case ignore it. If we scalarize an aggregate in
1148 intra-SRA we may need to add statements after each statement. This is not
1149 possible if a statement unconditionally has to end the basic block. */
1150 static bool
1151 disqualify_ops_if_throwing_stmt (gimple stmt, tree lhs, tree rhs)
1152 {
1153 if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1154 && (stmt_can_throw_internal (stmt) || stmt_ends_bb_p (stmt)))
1155 {
1156 disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
1157 if (rhs)
1158 disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
1159 return true;
1160 }
1161 return false;
1162 }
1163
1164 /* Scan expressions occurring in STMT, create access structures for all accesses
1165 to candidates for scalarization and remove those candidates which occur in
1166 statements or expressions that prevent them from being split apart. Return
1167 true if any access has been inserted. */
1168
1169 static bool
1170 build_accesses_from_assign (gimple stmt)
1171 {
1172 tree lhs, rhs;
1173 struct access *lacc, *racc;
1174
1175 if (!gimple_assign_single_p (stmt)
1176 /* Scope clobbers don't influence scalarization. */
1177 || gimple_clobber_p (stmt))
1178 return false;
1179
1180 lhs = gimple_assign_lhs (stmt);
1181 rhs = gimple_assign_rhs1 (stmt);
1182
1183 if (disqualify_ops_if_throwing_stmt (stmt, lhs, rhs))
1184 return false;
1185
1186 racc = build_access_from_expr_1 (rhs, stmt, false);
1187 lacc = build_access_from_expr_1 (lhs, stmt, true);
1188
1189 if (lacc)
1190 lacc->grp_assignment_write = 1;
1191
1192 if (racc)
1193 {
1194 racc->grp_assignment_read = 1;
1195 if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
1196 && !is_gimple_reg_type (racc->type))
1197 bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
1198 }
1199
1200 if (lacc && racc
1201 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
1202 && !lacc->grp_unscalarizable_region
1203 && !racc->grp_unscalarizable_region
1204 && AGGREGATE_TYPE_P (TREE_TYPE (lhs))
1205 && lacc->size == racc->size
1206 && useless_type_conversion_p (lacc->type, racc->type))
1207 {
1208 struct assign_link *link;
1209
1210 link = (struct assign_link *) pool_alloc (link_pool);
1211 memset (link, 0, sizeof (struct assign_link));
1212
1213 link->lacc = lacc;
1214 link->racc = racc;
1215
1216 add_link_to_rhs (racc, link);
1217 }
1218
1219 return lacc || racc;
1220 }
1221
1222 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
1223 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
1224
1225 static bool
1226 asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED, tree op,
1227 void *data ATTRIBUTE_UNUSED)
1228 {
1229 op = get_base_address (op);
1230 if (op
1231 && DECL_P (op))
1232 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
1233
1234 return false;
1235 }
1236
1237 /* Return true iff callsite CALL has at least as many actual arguments as there
1238 are formal parameters of the function currently processed by IPA-SRA. */
1239
1240 static inline bool
1241 callsite_has_enough_arguments_p (gimple call)
1242 {
1243 return gimple_call_num_args (call) >= (unsigned) func_param_count;
1244 }
1245
1246 /* Scan function and look for interesting expressions and create access
1247 structures for them. Return true iff any access is created. */
1248
1249 static bool
1250 scan_function (void)
1251 {
1252 basic_block bb;
1253 bool ret = false;
1254
1255 FOR_EACH_BB (bb)
1256 {
1257 gimple_stmt_iterator gsi;
1258 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1259 {
1260 gimple stmt = gsi_stmt (gsi);
1261 tree t;
1262 unsigned i;
1263
1264 if (final_bbs && stmt_can_throw_external (stmt))
1265 bitmap_set_bit (final_bbs, bb->index);
1266 switch (gimple_code (stmt))
1267 {
1268 case GIMPLE_RETURN:
1269 t = gimple_return_retval (stmt);
1270 if (t != NULL_TREE)
1271 ret |= build_access_from_expr (t, stmt, false);
1272 if (final_bbs)
1273 bitmap_set_bit (final_bbs, bb->index);
1274 break;
1275
1276 case GIMPLE_ASSIGN:
1277 ret |= build_accesses_from_assign (stmt);
1278 break;
1279
1280 case GIMPLE_CALL:
1281 for (i = 0; i < gimple_call_num_args (stmt); i++)
1282 ret |= build_access_from_expr (gimple_call_arg (stmt, i),
1283 stmt, false);
1284
1285 if (sra_mode == SRA_MODE_EARLY_IPA)
1286 {
1287 tree dest = gimple_call_fndecl (stmt);
1288 int flags = gimple_call_flags (stmt);
1289
1290 if (dest)
1291 {
1292 if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1293 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1294 encountered_apply_args = true;
1295 if (recursive_call_p (current_function_decl, dest))
1296 {
1297 encountered_recursive_call = true;
1298 if (!callsite_has_enough_arguments_p (stmt))
1299 encountered_unchangable_recursive_call = true;
1300 }
1301 }
1302
1303 if (final_bbs
1304 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1305 bitmap_set_bit (final_bbs, bb->index);
1306 }
1307
1308 t = gimple_call_lhs (stmt);
1309 if (t && !disqualify_ops_if_throwing_stmt (stmt, t, NULL))
1310 ret |= build_access_from_expr (t, stmt, true);
1311 break;
1312
1313 case GIMPLE_ASM:
1314 walk_stmt_load_store_addr_ops (stmt, NULL, NULL, NULL,
1315 asm_visit_addr);
1316 if (final_bbs)
1317 bitmap_set_bit (final_bbs, bb->index);
1318
1319 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
1320 {
1321 t = TREE_VALUE (gimple_asm_input_op (stmt, i));
1322 ret |= build_access_from_expr (t, stmt, false);
1323 }
1324 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
1325 {
1326 t = TREE_VALUE (gimple_asm_output_op (stmt, i));
1327 ret |= build_access_from_expr (t, stmt, true);
1328 }
1329 break;
1330
1331 default:
1332 break;
1333 }
1334 }
1335 }
1336
1337 return ret;
1338 }
1339
1340 /* Helper of QSORT function. There are pointers to accesses in the array. An
1341 access is considered smaller than another if it has smaller offset or if the
1342 offsets are the same but is size is bigger. */
1343
1344 static int
1345 compare_access_positions (const void *a, const void *b)
1346 {
1347 const access_p *fp1 = (const access_p *) a;
1348 const access_p *fp2 = (const access_p *) b;
1349 const access_p f1 = *fp1;
1350 const access_p f2 = *fp2;
1351
1352 if (f1->offset != f2->offset)
1353 return f1->offset < f2->offset ? -1 : 1;
1354
1355 if (f1->size == f2->size)
1356 {
1357 if (f1->type == f2->type)
1358 return 0;
1359 /* Put any non-aggregate type before any aggregate type. */
1360 else if (!is_gimple_reg_type (f1->type)
1361 && is_gimple_reg_type (f2->type))
1362 return 1;
1363 else if (is_gimple_reg_type (f1->type)
1364 && !is_gimple_reg_type (f2->type))
1365 return -1;
1366 /* Put any complex or vector type before any other scalar type. */
1367 else if (TREE_CODE (f1->type) != COMPLEX_TYPE
1368 && TREE_CODE (f1->type) != VECTOR_TYPE
1369 && (TREE_CODE (f2->type) == COMPLEX_TYPE
1370 || TREE_CODE (f2->type) == VECTOR_TYPE))
1371 return 1;
1372 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
1373 || TREE_CODE (f1->type) == VECTOR_TYPE)
1374 && TREE_CODE (f2->type) != COMPLEX_TYPE
1375 && TREE_CODE (f2->type) != VECTOR_TYPE)
1376 return -1;
1377 /* Put the integral type with the bigger precision first. */
1378 else if (INTEGRAL_TYPE_P (f1->type)
1379 && INTEGRAL_TYPE_P (f2->type))
1380 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
1381 /* Put any integral type with non-full precision last. */
1382 else if (INTEGRAL_TYPE_P (f1->type)
1383 && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type))
1384 != TYPE_PRECISION (f1->type)))
1385 return 1;
1386 else if (INTEGRAL_TYPE_P (f2->type)
1387 && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type))
1388 != TYPE_PRECISION (f2->type)))
1389 return -1;
1390 /* Stabilize the sort. */
1391 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1392 }
1393
1394 /* We want the bigger accesses first, thus the opposite operator in the next
1395 line: */
1396 return f1->size > f2->size ? -1 : 1;
1397 }
1398
1399
1400 /* Append a name of the declaration to the name obstack. A helper function for
1401 make_fancy_name. */
1402
1403 static void
1404 make_fancy_decl_name (tree decl)
1405 {
1406 char buffer[32];
1407
1408 tree name = DECL_NAME (decl);
1409 if (name)
1410 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1411 IDENTIFIER_LENGTH (name));
1412 else
1413 {
1414 sprintf (buffer, "D%u", DECL_UID (decl));
1415 obstack_grow (&name_obstack, buffer, strlen (buffer));
1416 }
1417 }
1418
1419 /* Helper for make_fancy_name. */
1420
1421 static void
1422 make_fancy_name_1 (tree expr)
1423 {
1424 char buffer[32];
1425 tree index;
1426
1427 if (DECL_P (expr))
1428 {
1429 make_fancy_decl_name (expr);
1430 return;
1431 }
1432
1433 switch (TREE_CODE (expr))
1434 {
1435 case COMPONENT_REF:
1436 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1437 obstack_1grow (&name_obstack, '$');
1438 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1439 break;
1440
1441 case ARRAY_REF:
1442 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1443 obstack_1grow (&name_obstack, '$');
1444 /* Arrays with only one element may not have a constant as their
1445 index. */
1446 index = TREE_OPERAND (expr, 1);
1447 if (TREE_CODE (index) != INTEGER_CST)
1448 break;
1449 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1450 obstack_grow (&name_obstack, buffer, strlen (buffer));
1451 break;
1452
1453 case ADDR_EXPR:
1454 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1455 break;
1456
1457 case MEM_REF:
1458 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1459 if (!integer_zerop (TREE_OPERAND (expr, 1)))
1460 {
1461 obstack_1grow (&name_obstack, '$');
1462 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC,
1463 TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)));
1464 obstack_grow (&name_obstack, buffer, strlen (buffer));
1465 }
1466 break;
1467
1468 case BIT_FIELD_REF:
1469 case REALPART_EXPR:
1470 case IMAGPART_EXPR:
1471 gcc_unreachable (); /* we treat these as scalars. */
1472 break;
1473 default:
1474 break;
1475 }
1476 }
1477
1478 /* Create a human readable name for replacement variable of ACCESS. */
1479
1480 static char *
1481 make_fancy_name (tree expr)
1482 {
1483 make_fancy_name_1 (expr);
1484 obstack_1grow (&name_obstack, '\0');
1485 return XOBFINISH (&name_obstack, char *);
1486 }
1487
1488 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1489 EXP_TYPE at the given OFFSET. If BASE is something for which
1490 get_addr_base_and_unit_offset returns NULL, gsi must be non-NULL and is used
1491 to insert new statements either before or below the current one as specified
1492 by INSERT_AFTER. This function is not capable of handling bitfields.
1493
1494 BASE must be either a declaration or a memory reference that has correct
1495 alignment ifformation embeded in it (e.g. a pre-existing one in SRA). */
1496
1497 tree
1498 build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
1499 tree exp_type, gimple_stmt_iterator *gsi,
1500 bool insert_after)
1501 {
1502 tree prev_base = base;
1503 tree off;
1504 tree mem_ref;
1505 HOST_WIDE_INT base_offset;
1506 unsigned HOST_WIDE_INT misalign;
1507 unsigned int align;
1508
1509 gcc_checking_assert (offset % BITS_PER_UNIT == 0);
1510 get_object_alignment_1 (base, &align, &misalign);
1511 base = get_addr_base_and_unit_offset (base, &base_offset);
1512
1513 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1514 offset such as array[var_index]. */
1515 if (!base)
1516 {
1517 gimple stmt;
1518 tree tmp, addr;
1519
1520 gcc_checking_assert (gsi);
1521 tmp = make_ssa_name (build_pointer_type (TREE_TYPE (prev_base)), NULL);
1522 addr = build_fold_addr_expr (unshare_expr (prev_base));
1523 STRIP_USELESS_TYPE_CONVERSION (addr);
1524 stmt = gimple_build_assign (tmp, addr);
1525 gimple_set_location (stmt, loc);
1526 if (insert_after)
1527 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
1528 else
1529 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1530
1531 off = build_int_cst (reference_alias_ptr_type (prev_base),
1532 offset / BITS_PER_UNIT);
1533 base = tmp;
1534 }
1535 else if (TREE_CODE (base) == MEM_REF)
1536 {
1537 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1538 base_offset + offset / BITS_PER_UNIT);
1539 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1540 base = unshare_expr (TREE_OPERAND (base, 0));
1541 }
1542 else
1543 {
1544 off = build_int_cst (reference_alias_ptr_type (base),
1545 base_offset + offset / BITS_PER_UNIT);
1546 base = build_fold_addr_expr (unshare_expr (base));
1547 }
1548
1549 misalign = (misalign + offset) & (align - 1);
1550 if (misalign != 0)
1551 align = (misalign & -misalign);
1552 if (align < TYPE_ALIGN (exp_type))
1553 exp_type = build_aligned_type (exp_type, align);
1554
1555 mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off);
1556 if (TREE_THIS_VOLATILE (prev_base))
1557 TREE_THIS_VOLATILE (mem_ref) = 1;
1558 if (TREE_SIDE_EFFECTS (prev_base))
1559 TREE_SIDE_EFFECTS (mem_ref) = 1;
1560 return mem_ref;
1561 }
1562
1563 /* Construct a memory reference to a part of an aggregate BASE at the given
1564 OFFSET and of the same type as MODEL. In case this is a reference to a
1565 bit-field, the function will replicate the last component_ref of model's
1566 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1567 build_ref_for_offset. */
1568
1569 static tree
1570 build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1571 struct access *model, gimple_stmt_iterator *gsi,
1572 bool insert_after)
1573 {
1574 if (TREE_CODE (model->expr) == COMPONENT_REF
1575 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1576 {
1577 /* This access represents a bit-field. */
1578 tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
1579
1580 offset -= int_bit_position (fld);
1581 exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
1582 t = build_ref_for_offset (loc, base, offset, exp_type, gsi, insert_after);
1583 return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
1584 NULL_TREE);
1585 }
1586 else
1587 return build_ref_for_offset (loc, base, offset, model->type,
1588 gsi, insert_after);
1589 }
1590
1591 /* Attempt to build a memory reference that we could but into a gimple
1592 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1593 create statements and return s NULL instead. This function also ignores
1594 alignment issues and so its results should never end up in non-debug
1595 statements. */
1596
1597 static tree
1598 build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1599 struct access *model)
1600 {
1601 HOST_WIDE_INT base_offset;
1602 tree off;
1603
1604 if (TREE_CODE (model->expr) == COMPONENT_REF
1605 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1606 return NULL_TREE;
1607
1608 base = get_addr_base_and_unit_offset (base, &base_offset);
1609 if (!base)
1610 return NULL_TREE;
1611 if (TREE_CODE (base) == MEM_REF)
1612 {
1613 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1614 base_offset + offset / BITS_PER_UNIT);
1615 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1616 base = unshare_expr (TREE_OPERAND (base, 0));
1617 }
1618 else
1619 {
1620 off = build_int_cst (reference_alias_ptr_type (base),
1621 base_offset + offset / BITS_PER_UNIT);
1622 base = build_fold_addr_expr (unshare_expr (base));
1623 }
1624
1625 return fold_build2_loc (loc, MEM_REF, model->type, base, off);
1626 }
1627
1628 /* Construct a memory reference consisting of component_refs and array_refs to
1629 a part of an aggregate *RES (which is of type TYPE). The requested part
1630 should have type EXP_TYPE at be the given OFFSET. This function might not
1631 succeed, it returns true when it does and only then *RES points to something
1632 meaningful. This function should be used only to build expressions that we
1633 might need to present to user (e.g. in warnings). In all other situations,
1634 build_ref_for_model or build_ref_for_offset should be used instead. */
1635
1636 static bool
1637 build_user_friendly_ref_for_offset (tree *res, tree type, HOST_WIDE_INT offset,
1638 tree exp_type)
1639 {
1640 while (1)
1641 {
1642 tree fld;
1643 tree tr_size, index, minidx;
1644 HOST_WIDE_INT el_size;
1645
1646 if (offset == 0 && exp_type
1647 && types_compatible_p (exp_type, type))
1648 return true;
1649
1650 switch (TREE_CODE (type))
1651 {
1652 case UNION_TYPE:
1653 case QUAL_UNION_TYPE:
1654 case RECORD_TYPE:
1655 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
1656 {
1657 HOST_WIDE_INT pos, size;
1658 tree tr_pos, expr, *expr_ptr;
1659
1660 if (TREE_CODE (fld) != FIELD_DECL)
1661 continue;
1662
1663 tr_pos = bit_position (fld);
1664 if (!tr_pos || !tree_fits_uhwi_p (tr_pos))
1665 continue;
1666 pos = tree_to_uhwi (tr_pos);
1667 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1668 tr_size = DECL_SIZE (fld);
1669 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1670 continue;
1671 size = tree_to_uhwi (tr_size);
1672 if (size == 0)
1673 {
1674 if (pos != offset)
1675 continue;
1676 }
1677 else if (pos > offset || (pos + size) <= offset)
1678 continue;
1679
1680 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1681 NULL_TREE);
1682 expr_ptr = &expr;
1683 if (build_user_friendly_ref_for_offset (expr_ptr, TREE_TYPE (fld),
1684 offset - pos, exp_type))
1685 {
1686 *res = expr;
1687 return true;
1688 }
1689 }
1690 return false;
1691
1692 case ARRAY_TYPE:
1693 tr_size = TYPE_SIZE (TREE_TYPE (type));
1694 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1695 return false;
1696 el_size = tree_to_uhwi (tr_size);
1697
1698 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1699 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
1700 return false;
1701 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1702 if (!integer_zerop (minidx))
1703 index = int_const_binop (PLUS_EXPR, index, minidx);
1704 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1705 NULL_TREE, NULL_TREE);
1706 offset = offset % el_size;
1707 type = TREE_TYPE (type);
1708 break;
1709
1710 default:
1711 if (offset != 0)
1712 return false;
1713
1714 if (exp_type)
1715 return false;
1716 else
1717 return true;
1718 }
1719 }
1720 }
1721
1722 /* Return true iff TYPE is stdarg va_list type. */
1723
1724 static inline bool
1725 is_va_list_type (tree type)
1726 {
1727 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1728 }
1729
1730 /* Print message to dump file why a variable was rejected. */
1731
1732 static void
1733 reject (tree var, const char *msg)
1734 {
1735 if (dump_file && (dump_flags & TDF_DETAILS))
1736 {
1737 fprintf (dump_file, "Rejected (%d): %s: ", DECL_UID (var), msg);
1738 print_generic_expr (dump_file, var, 0);
1739 fprintf (dump_file, "\n");
1740 }
1741 }
1742
1743 /* Return true if VAR is a candidate for SRA. */
1744
1745 static bool
1746 maybe_add_sra_candidate (tree var)
1747 {
1748 tree type = TREE_TYPE (var);
1749 const char *msg;
1750 tree_node **slot;
1751
1752 if (!AGGREGATE_TYPE_P (type))
1753 {
1754 reject (var, "not aggregate");
1755 return false;
1756 }
1757 if (needs_to_live_in_memory (var))
1758 {
1759 reject (var, "needs to live in memory");
1760 return false;
1761 }
1762 if (TREE_THIS_VOLATILE (var))
1763 {
1764 reject (var, "is volatile");
1765 return false;
1766 }
1767 if (!COMPLETE_TYPE_P (type))
1768 {
1769 reject (var, "has incomplete type");
1770 return false;
1771 }
1772 if (!tree_fits_uhwi_p (TYPE_SIZE (type)))
1773 {
1774 reject (var, "type size not fixed");
1775 return false;
1776 }
1777 if (tree_to_uhwi (TYPE_SIZE (type)) == 0)
1778 {
1779 reject (var, "type size is zero");
1780 return false;
1781 }
1782 if (type_internals_preclude_sra_p (type, &msg))
1783 {
1784 reject (var, msg);
1785 return false;
1786 }
1787 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1788 we also want to schedule it rather late. Thus we ignore it in
1789 the early pass. */
1790 (sra_mode == SRA_MODE_EARLY_INTRA
1791 && is_va_list_type (type)))
1792 {
1793 reject (var, "is va_list");
1794 return false;
1795 }
1796
1797 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
1798 slot = candidates.find_slot_with_hash (var, DECL_UID (var), INSERT);
1799 *slot = var;
1800
1801 if (dump_file && (dump_flags & TDF_DETAILS))
1802 {
1803 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
1804 print_generic_expr (dump_file, var, 0);
1805 fprintf (dump_file, "\n");
1806 }
1807
1808 return true;
1809 }
1810
1811 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1812 those with type which is suitable for scalarization. */
1813
1814 static bool
1815 find_var_candidates (void)
1816 {
1817 tree var, parm;
1818 unsigned int i;
1819 bool ret = false;
1820
1821 for (parm = DECL_ARGUMENTS (current_function_decl);
1822 parm;
1823 parm = DECL_CHAIN (parm))
1824 ret |= maybe_add_sra_candidate (parm);
1825
1826 FOR_EACH_LOCAL_DECL (cfun, i, var)
1827 {
1828 if (TREE_CODE (var) != VAR_DECL)
1829 continue;
1830
1831 ret |= maybe_add_sra_candidate (var);
1832 }
1833
1834 return ret;
1835 }
1836
1837 /* Sort all accesses for the given variable, check for partial overlaps and
1838 return NULL if there are any. If there are none, pick a representative for
1839 each combination of offset and size and create a linked list out of them.
1840 Return the pointer to the first representative and make sure it is the first
1841 one in the vector of accesses. */
1842
1843 static struct access *
1844 sort_and_splice_var_accesses (tree var)
1845 {
1846 int i, j, access_count;
1847 struct access *res, **prev_acc_ptr = &res;
1848 vec<access_p> *access_vec;
1849 bool first = true;
1850 HOST_WIDE_INT low = -1, high = 0;
1851
1852 access_vec = get_base_access_vector (var);
1853 if (!access_vec)
1854 return NULL;
1855 access_count = access_vec->length ();
1856
1857 /* Sort by <OFFSET, SIZE>. */
1858 access_vec->qsort (compare_access_positions);
1859
1860 i = 0;
1861 while (i < access_count)
1862 {
1863 struct access *access = (*access_vec)[i];
1864 bool grp_write = access->write;
1865 bool grp_read = !access->write;
1866 bool grp_scalar_write = access->write
1867 && is_gimple_reg_type (access->type);
1868 bool grp_scalar_read = !access->write
1869 && is_gimple_reg_type (access->type);
1870 bool grp_assignment_read = access->grp_assignment_read;
1871 bool grp_assignment_write = access->grp_assignment_write;
1872 bool multiple_scalar_reads = false;
1873 bool total_scalarization = access->grp_total_scalarization;
1874 bool grp_partial_lhs = access->grp_partial_lhs;
1875 bool first_scalar = is_gimple_reg_type (access->type);
1876 bool unscalarizable_region = access->grp_unscalarizable_region;
1877
1878 if (first || access->offset >= high)
1879 {
1880 first = false;
1881 low = access->offset;
1882 high = access->offset + access->size;
1883 }
1884 else if (access->offset > low && access->offset + access->size > high)
1885 return NULL;
1886 else
1887 gcc_assert (access->offset >= low
1888 && access->offset + access->size <= high);
1889
1890 j = i + 1;
1891 while (j < access_count)
1892 {
1893 struct access *ac2 = (*access_vec)[j];
1894 if (ac2->offset != access->offset || ac2->size != access->size)
1895 break;
1896 if (ac2->write)
1897 {
1898 grp_write = true;
1899 grp_scalar_write = (grp_scalar_write
1900 || is_gimple_reg_type (ac2->type));
1901 }
1902 else
1903 {
1904 grp_read = true;
1905 if (is_gimple_reg_type (ac2->type))
1906 {
1907 if (grp_scalar_read)
1908 multiple_scalar_reads = true;
1909 else
1910 grp_scalar_read = true;
1911 }
1912 }
1913 grp_assignment_read |= ac2->grp_assignment_read;
1914 grp_assignment_write |= ac2->grp_assignment_write;
1915 grp_partial_lhs |= ac2->grp_partial_lhs;
1916 unscalarizable_region |= ac2->grp_unscalarizable_region;
1917 total_scalarization |= ac2->grp_total_scalarization;
1918 relink_to_new_repr (access, ac2);
1919
1920 /* If there are both aggregate-type and scalar-type accesses with
1921 this combination of size and offset, the comparison function
1922 should have put the scalars first. */
1923 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
1924 ac2->group_representative = access;
1925 j++;
1926 }
1927
1928 i = j;
1929
1930 access->group_representative = access;
1931 access->grp_write = grp_write;
1932 access->grp_read = grp_read;
1933 access->grp_scalar_read = grp_scalar_read;
1934 access->grp_scalar_write = grp_scalar_write;
1935 access->grp_assignment_read = grp_assignment_read;
1936 access->grp_assignment_write = grp_assignment_write;
1937 access->grp_hint = multiple_scalar_reads || total_scalarization;
1938 access->grp_total_scalarization = total_scalarization;
1939 access->grp_partial_lhs = grp_partial_lhs;
1940 access->grp_unscalarizable_region = unscalarizable_region;
1941 if (access->first_link)
1942 add_access_to_work_queue (access);
1943
1944 *prev_acc_ptr = access;
1945 prev_acc_ptr = &access->next_grp;
1946 }
1947
1948 gcc_assert (res == (*access_vec)[0]);
1949 return res;
1950 }
1951
1952 /* Create a variable for the given ACCESS which determines the type, name and a
1953 few other properties. Return the variable declaration and store it also to
1954 ACCESS->replacement. */
1955
1956 static tree
1957 create_access_replacement (struct access *access)
1958 {
1959 tree repl;
1960
1961 if (access->grp_to_be_debug_replaced)
1962 {
1963 repl = create_tmp_var_raw (access->type, NULL);
1964 DECL_CONTEXT (repl) = current_function_decl;
1965 }
1966 else
1967 repl = create_tmp_var (access->type, "SR");
1968 if (TREE_CODE (access->type) == COMPLEX_TYPE
1969 || TREE_CODE (access->type) == VECTOR_TYPE)
1970 {
1971 if (!access->grp_partial_lhs)
1972 DECL_GIMPLE_REG_P (repl) = 1;
1973 }
1974 else if (access->grp_partial_lhs
1975 && is_gimple_reg_type (access->type))
1976 TREE_ADDRESSABLE (repl) = 1;
1977
1978 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
1979 DECL_ARTIFICIAL (repl) = 1;
1980 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
1981
1982 if (DECL_NAME (access->base)
1983 && !DECL_IGNORED_P (access->base)
1984 && !DECL_ARTIFICIAL (access->base))
1985 {
1986 char *pretty_name = make_fancy_name (access->expr);
1987 tree debug_expr = unshare_expr_without_location (access->expr), d;
1988 bool fail = false;
1989
1990 DECL_NAME (repl) = get_identifier (pretty_name);
1991 obstack_free (&name_obstack, pretty_name);
1992
1993 /* Get rid of any SSA_NAMEs embedded in debug_expr,
1994 as DECL_DEBUG_EXPR isn't considered when looking for still
1995 used SSA_NAMEs and thus they could be freed. All debug info
1996 generation cares is whether something is constant or variable
1997 and that get_ref_base_and_extent works properly on the
1998 expression. It cannot handle accesses at a non-constant offset
1999 though, so just give up in those cases. */
2000 for (d = debug_expr;
2001 !fail && (handled_component_p (d) || TREE_CODE (d) == MEM_REF);
2002 d = TREE_OPERAND (d, 0))
2003 switch (TREE_CODE (d))
2004 {
2005 case ARRAY_REF:
2006 case ARRAY_RANGE_REF:
2007 if (TREE_OPERAND (d, 1)
2008 && TREE_CODE (TREE_OPERAND (d, 1)) != INTEGER_CST)
2009 fail = true;
2010 if (TREE_OPERAND (d, 3)
2011 && TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST)
2012 fail = true;
2013 /* FALLTHRU */
2014 case COMPONENT_REF:
2015 if (TREE_OPERAND (d, 2)
2016 && TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST)
2017 fail = true;
2018 break;
2019 case MEM_REF:
2020 if (TREE_CODE (TREE_OPERAND (d, 0)) != ADDR_EXPR)
2021 fail = true;
2022 else
2023 d = TREE_OPERAND (d, 0);
2024 break;
2025 default:
2026 break;
2027 }
2028 if (!fail)
2029 {
2030 SET_DECL_DEBUG_EXPR (repl, debug_expr);
2031 DECL_HAS_DEBUG_EXPR_P (repl) = 1;
2032 }
2033 if (access->grp_no_warning)
2034 TREE_NO_WARNING (repl) = 1;
2035 else
2036 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
2037 }
2038 else
2039 TREE_NO_WARNING (repl) = 1;
2040
2041 if (dump_file)
2042 {
2043 if (access->grp_to_be_debug_replaced)
2044 {
2045 fprintf (dump_file, "Created a debug-only replacement for ");
2046 print_generic_expr (dump_file, access->base, 0);
2047 fprintf (dump_file, " offset: %u, size: %u\n",
2048 (unsigned) access->offset, (unsigned) access->size);
2049 }
2050 else
2051 {
2052 fprintf (dump_file, "Created a replacement for ");
2053 print_generic_expr (dump_file, access->base, 0);
2054 fprintf (dump_file, " offset: %u, size: %u: ",
2055 (unsigned) access->offset, (unsigned) access->size);
2056 print_generic_expr (dump_file, repl, 0);
2057 fprintf (dump_file, "\n");
2058 }
2059 }
2060 sra_stats.replacements++;
2061
2062 return repl;
2063 }
2064
2065 /* Return ACCESS scalar replacement, create it if it does not exist yet. */
2066
2067 static inline tree
2068 get_access_replacement (struct access *access)
2069 {
2070 gcc_checking_assert (access->replacement_decl);
2071 return access->replacement_decl;
2072 }
2073
2074
2075 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2076 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2077 to it is not "within" the root. Return false iff some accesses partially
2078 overlap. */
2079
2080 static bool
2081 build_access_subtree (struct access **access)
2082 {
2083 struct access *root = *access, *last_child = NULL;
2084 HOST_WIDE_INT limit = root->offset + root->size;
2085
2086 *access = (*access)->next_grp;
2087 while (*access && (*access)->offset + (*access)->size <= limit)
2088 {
2089 if (!last_child)
2090 root->first_child = *access;
2091 else
2092 last_child->next_sibling = *access;
2093 last_child = *access;
2094
2095 if (!build_access_subtree (access))
2096 return false;
2097 }
2098
2099 if (*access && (*access)->offset < limit)
2100 return false;
2101
2102 return true;
2103 }
2104
2105 /* Build a tree of access representatives, ACCESS is the pointer to the first
2106 one, others are linked in a list by the next_grp field. Return false iff
2107 some accesses partially overlap. */
2108
2109 static bool
2110 build_access_trees (struct access *access)
2111 {
2112 while (access)
2113 {
2114 struct access *root = access;
2115
2116 if (!build_access_subtree (&access))
2117 return false;
2118 root->next_grp = access;
2119 }
2120 return true;
2121 }
2122
2123 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2124 array. */
2125
2126 static bool
2127 expr_with_var_bounded_array_refs_p (tree expr)
2128 {
2129 while (handled_component_p (expr))
2130 {
2131 if (TREE_CODE (expr) == ARRAY_REF
2132 && !tree_fits_shwi_p (array_ref_low_bound (expr)))
2133 return true;
2134 expr = TREE_OPERAND (expr, 0);
2135 }
2136 return false;
2137 }
2138
2139 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2140 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2141 sorts of access flags appropriately along the way, notably always set
2142 grp_read and grp_assign_read according to MARK_READ and grp_write when
2143 MARK_WRITE is true.
2144
2145 Creating a replacement for a scalar access is considered beneficial if its
2146 grp_hint is set (this means we are either attempting total scalarization or
2147 there is more than one direct read access) or according to the following
2148 table:
2149
2150 Access written to through a scalar type (once or more times)
2151 |
2152 | Written to in an assignment statement
2153 | |
2154 | | Access read as scalar _once_
2155 | | |
2156 | | | Read in an assignment statement
2157 | | | |
2158 | | | | Scalarize Comment
2159 -----------------------------------------------------------------------------
2160 0 0 0 0 No access for the scalar
2161 0 0 0 1 No access for the scalar
2162 0 0 1 0 No Single read - won't help
2163 0 0 1 1 No The same case
2164 0 1 0 0 No access for the scalar
2165 0 1 0 1 No access for the scalar
2166 0 1 1 0 Yes s = *g; return s.i;
2167 0 1 1 1 Yes The same case as above
2168 1 0 0 0 No Won't help
2169 1 0 0 1 Yes s.i = 1; *g = s;
2170 1 0 1 0 Yes s.i = 5; g = s.i;
2171 1 0 1 1 Yes The same case as above
2172 1 1 0 0 No Won't help.
2173 1 1 0 1 Yes s.i = 1; *g = s;
2174 1 1 1 0 Yes s = *g; return s.i;
2175 1 1 1 1 Yes Any of the above yeses */
2176
2177 static bool
2178 analyze_access_subtree (struct access *root, struct access *parent,
2179 bool allow_replacements)
2180 {
2181 struct access *child;
2182 HOST_WIDE_INT limit = root->offset + root->size;
2183 HOST_WIDE_INT covered_to = root->offset;
2184 bool scalar = is_gimple_reg_type (root->type);
2185 bool hole = false, sth_created = false;
2186
2187 if (parent)
2188 {
2189 if (parent->grp_read)
2190 root->grp_read = 1;
2191 if (parent->grp_assignment_read)
2192 root->grp_assignment_read = 1;
2193 if (parent->grp_write)
2194 root->grp_write = 1;
2195 if (parent->grp_assignment_write)
2196 root->grp_assignment_write = 1;
2197 if (parent->grp_total_scalarization)
2198 root->grp_total_scalarization = 1;
2199 }
2200
2201 if (root->grp_unscalarizable_region)
2202 allow_replacements = false;
2203
2204 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
2205 allow_replacements = false;
2206
2207 for (child = root->first_child; child; child = child->next_sibling)
2208 {
2209 hole |= covered_to < child->offset;
2210 sth_created |= analyze_access_subtree (child, root,
2211 allow_replacements && !scalar);
2212
2213 root->grp_unscalarized_data |= child->grp_unscalarized_data;
2214 root->grp_total_scalarization &= child->grp_total_scalarization;
2215 if (child->grp_covered)
2216 covered_to += child->size;
2217 else
2218 hole = true;
2219 }
2220
2221 if (allow_replacements && scalar && !root->first_child
2222 && (root->grp_hint
2223 || ((root->grp_scalar_read || root->grp_assignment_read)
2224 && (root->grp_scalar_write || root->grp_assignment_write))))
2225 {
2226 /* Always create access replacements that cover the whole access.
2227 For integral types this means the precision has to match.
2228 Avoid assumptions based on the integral type kind, too. */
2229 if (INTEGRAL_TYPE_P (root->type)
2230 && (TREE_CODE (root->type) != INTEGER_TYPE
2231 || TYPE_PRECISION (root->type) != root->size)
2232 /* But leave bitfield accesses alone. */
2233 && (TREE_CODE (root->expr) != COMPONENT_REF
2234 || !DECL_BIT_FIELD (TREE_OPERAND (root->expr, 1))))
2235 {
2236 tree rt = root->type;
2237 gcc_assert ((root->offset % BITS_PER_UNIT) == 0
2238 && (root->size % BITS_PER_UNIT) == 0);
2239 root->type = build_nonstandard_integer_type (root->size,
2240 TYPE_UNSIGNED (rt));
2241 root->expr = build_ref_for_offset (UNKNOWN_LOCATION,
2242 root->base, root->offset,
2243 root->type, NULL, false);
2244
2245 if (dump_file && (dump_flags & TDF_DETAILS))
2246 {
2247 fprintf (dump_file, "Changing the type of a replacement for ");
2248 print_generic_expr (dump_file, root->base, 0);
2249 fprintf (dump_file, " offset: %u, size: %u ",
2250 (unsigned) root->offset, (unsigned) root->size);
2251 fprintf (dump_file, " to an integer.\n");
2252 }
2253 }
2254
2255 root->grp_to_be_replaced = 1;
2256 root->replacement_decl = create_access_replacement (root);
2257 sth_created = true;
2258 hole = false;
2259 }
2260 else
2261 {
2262 if (allow_replacements
2263 && scalar && !root->first_child
2264 && (root->grp_scalar_write || root->grp_assignment_write)
2265 && !bitmap_bit_p (cannot_scalarize_away_bitmap,
2266 DECL_UID (root->base)))
2267 {
2268 gcc_checking_assert (!root->grp_scalar_read
2269 && !root->grp_assignment_read);
2270 sth_created = true;
2271 if (MAY_HAVE_DEBUG_STMTS)
2272 {
2273 root->grp_to_be_debug_replaced = 1;
2274 root->replacement_decl = create_access_replacement (root);
2275 }
2276 }
2277
2278 if (covered_to < limit)
2279 hole = true;
2280 if (scalar)
2281 root->grp_total_scalarization = 0;
2282 }
2283
2284 if (!hole || root->grp_total_scalarization)
2285 root->grp_covered = 1;
2286 else if (root->grp_write || TREE_CODE (root->base) == PARM_DECL)
2287 root->grp_unscalarized_data = 1; /* not covered and written to */
2288 return sth_created;
2289 }
2290
2291 /* Analyze all access trees linked by next_grp by the means of
2292 analyze_access_subtree. */
2293 static bool
2294 analyze_access_trees (struct access *access)
2295 {
2296 bool ret = false;
2297
2298 while (access)
2299 {
2300 if (analyze_access_subtree (access, NULL, true))
2301 ret = true;
2302 access = access->next_grp;
2303 }
2304
2305 return ret;
2306 }
2307
2308 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2309 SIZE would conflict with an already existing one. If exactly such a child
2310 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2311
2312 static bool
2313 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
2314 HOST_WIDE_INT size, struct access **exact_match)
2315 {
2316 struct access *child;
2317
2318 for (child = lacc->first_child; child; child = child->next_sibling)
2319 {
2320 if (child->offset == norm_offset && child->size == size)
2321 {
2322 *exact_match = child;
2323 return true;
2324 }
2325
2326 if (child->offset < norm_offset + size
2327 && child->offset + child->size > norm_offset)
2328 return true;
2329 }
2330
2331 return false;
2332 }
2333
2334 /* Create a new child access of PARENT, with all properties just like MODEL
2335 except for its offset and with its grp_write false and grp_read true.
2336 Return the new access or NULL if it cannot be created. Note that this access
2337 is created long after all splicing and sorting, it's not located in any
2338 access vector and is automatically a representative of its group. */
2339
2340 static struct access *
2341 create_artificial_child_access (struct access *parent, struct access *model,
2342 HOST_WIDE_INT new_offset)
2343 {
2344 struct access *access;
2345 struct access **child;
2346 tree expr = parent->base;
2347
2348 gcc_assert (!model->grp_unscalarizable_region);
2349
2350 access = (struct access *) pool_alloc (access_pool);
2351 memset (access, 0, sizeof (struct access));
2352 if (!build_user_friendly_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
2353 model->type))
2354 {
2355 access->grp_no_warning = true;
2356 expr = build_ref_for_model (EXPR_LOCATION (parent->base), parent->base,
2357 new_offset, model, NULL, false);
2358 }
2359
2360 access->base = parent->base;
2361 access->expr = expr;
2362 access->offset = new_offset;
2363 access->size = model->size;
2364 access->type = model->type;
2365 access->grp_write = true;
2366 access->grp_read = false;
2367
2368 child = &parent->first_child;
2369 while (*child && (*child)->offset < new_offset)
2370 child = &(*child)->next_sibling;
2371
2372 access->next_sibling = *child;
2373 *child = access;
2374
2375 return access;
2376 }
2377
2378
2379 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
2380 true if any new subaccess was created. Additionally, if RACC is a scalar
2381 access but LACC is not, change the type of the latter, if possible. */
2382
2383 static bool
2384 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
2385 {
2386 struct access *rchild;
2387 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
2388 bool ret = false;
2389
2390 if (is_gimple_reg_type (lacc->type)
2391 || lacc->grp_unscalarizable_region
2392 || racc->grp_unscalarizable_region)
2393 return false;
2394
2395 if (is_gimple_reg_type (racc->type))
2396 {
2397 if (!lacc->first_child && !racc->first_child)
2398 {
2399 tree t = lacc->base;
2400
2401 lacc->type = racc->type;
2402 if (build_user_friendly_ref_for_offset (&t, TREE_TYPE (t),
2403 lacc->offset, racc->type))
2404 lacc->expr = t;
2405 else
2406 {
2407 lacc->expr = build_ref_for_model (EXPR_LOCATION (lacc->base),
2408 lacc->base, lacc->offset,
2409 racc, NULL, false);
2410 lacc->grp_no_warning = true;
2411 }
2412 }
2413 return false;
2414 }
2415
2416 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
2417 {
2418 struct access *new_acc = NULL;
2419 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
2420
2421 if (rchild->grp_unscalarizable_region)
2422 continue;
2423
2424 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
2425 &new_acc))
2426 {
2427 if (new_acc)
2428 {
2429 rchild->grp_hint = 1;
2430 new_acc->grp_hint |= new_acc->grp_read;
2431 if (rchild->first_child)
2432 ret |= propagate_subaccesses_across_link (new_acc, rchild);
2433 }
2434 continue;
2435 }
2436
2437 rchild->grp_hint = 1;
2438 new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
2439 if (new_acc)
2440 {
2441 ret = true;
2442 if (racc->first_child)
2443 propagate_subaccesses_across_link (new_acc, rchild);
2444 }
2445 }
2446
2447 return ret;
2448 }
2449
2450 /* Propagate all subaccesses across assignment links. */
2451
2452 static void
2453 propagate_all_subaccesses (void)
2454 {
2455 while (work_queue_head)
2456 {
2457 struct access *racc = pop_access_from_work_queue ();
2458 struct assign_link *link;
2459
2460 gcc_assert (racc->first_link);
2461
2462 for (link = racc->first_link; link; link = link->next)
2463 {
2464 struct access *lacc = link->lacc;
2465
2466 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
2467 continue;
2468 lacc = lacc->group_representative;
2469 if (propagate_subaccesses_across_link (lacc, racc)
2470 && lacc->first_link)
2471 add_access_to_work_queue (lacc);
2472 }
2473 }
2474 }
2475
2476 /* Go through all accesses collected throughout the (intraprocedural) analysis
2477 stage, exclude overlapping ones, identify representatives and build trees
2478 out of them, making decisions about scalarization on the way. Return true
2479 iff there are any to-be-scalarized variables after this stage. */
2480
2481 static bool
2482 analyze_all_variable_accesses (void)
2483 {
2484 int res = 0;
2485 bitmap tmp = BITMAP_ALLOC (NULL);
2486 bitmap_iterator bi;
2487 unsigned i, max_total_scalarization_size;
2488
2489 max_total_scalarization_size = UNITS_PER_WORD * BITS_PER_UNIT
2490 * MOVE_RATIO (optimize_function_for_speed_p (cfun));
2491
2492 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
2493 if (bitmap_bit_p (should_scalarize_away_bitmap, i)
2494 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
2495 {
2496 tree var = candidate (i);
2497
2498 if (TREE_CODE (var) == VAR_DECL
2499 && type_consists_of_records_p (TREE_TYPE (var)))
2500 {
2501 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var)))
2502 <= max_total_scalarization_size)
2503 {
2504 completely_scalarize_var (var);
2505 if (dump_file && (dump_flags & TDF_DETAILS))
2506 {
2507 fprintf (dump_file, "Will attempt to totally scalarize ");
2508 print_generic_expr (dump_file, var, 0);
2509 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2510 }
2511 }
2512 else if (dump_file && (dump_flags & TDF_DETAILS))
2513 {
2514 fprintf (dump_file, "Too big to totally scalarize: ");
2515 print_generic_expr (dump_file, var, 0);
2516 fprintf (dump_file, " (UID: %u)\n", DECL_UID (var));
2517 }
2518 }
2519 }
2520
2521 bitmap_copy (tmp, candidate_bitmap);
2522 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2523 {
2524 tree var = candidate (i);
2525 struct access *access;
2526
2527 access = sort_and_splice_var_accesses (var);
2528 if (!access || !build_access_trees (access))
2529 disqualify_candidate (var,
2530 "No or inhibitingly overlapping accesses.");
2531 }
2532
2533 propagate_all_subaccesses ();
2534
2535 bitmap_copy (tmp, candidate_bitmap);
2536 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2537 {
2538 tree var = candidate (i);
2539 struct access *access = get_first_repr_for_decl (var);
2540
2541 if (analyze_access_trees (access))
2542 {
2543 res++;
2544 if (dump_file && (dump_flags & TDF_DETAILS))
2545 {
2546 fprintf (dump_file, "\nAccess trees for ");
2547 print_generic_expr (dump_file, var, 0);
2548 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2549 dump_access_tree (dump_file, access);
2550 fprintf (dump_file, "\n");
2551 }
2552 }
2553 else
2554 disqualify_candidate (var, "No scalar replacements to be created.");
2555 }
2556
2557 BITMAP_FREE (tmp);
2558
2559 if (res)
2560 {
2561 statistics_counter_event (cfun, "Scalarized aggregates", res);
2562 return true;
2563 }
2564 else
2565 return false;
2566 }
2567
2568 /* Generate statements copying scalar replacements of accesses within a subtree
2569 into or out of AGG. ACCESS, all its children, siblings and their children
2570 are to be processed. AGG is an aggregate type expression (can be a
2571 declaration but does not have to be, it can for example also be a mem_ref or
2572 a series of handled components). TOP_OFFSET is the offset of the processed
2573 subtree which has to be subtracted from offsets of individual accesses to
2574 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2575 replacements in the interval <start_offset, start_offset + chunk_size>,
2576 otherwise copy all. GSI is a statement iterator used to place the new
2577 statements. WRITE should be true when the statements should write from AGG
2578 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2579 statements will be added after the current statement in GSI, they will be
2580 added before the statement otherwise. */
2581
2582 static void
2583 generate_subtree_copies (struct access *access, tree agg,
2584 HOST_WIDE_INT top_offset,
2585 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
2586 gimple_stmt_iterator *gsi, bool write,
2587 bool insert_after, location_t loc)
2588 {
2589 do
2590 {
2591 if (chunk_size && access->offset >= start_offset + chunk_size)
2592 return;
2593
2594 if (access->grp_to_be_replaced
2595 && (chunk_size == 0
2596 || access->offset + access->size > start_offset))
2597 {
2598 tree expr, repl = get_access_replacement (access);
2599 gimple stmt;
2600
2601 expr = build_ref_for_model (loc, agg, access->offset - top_offset,
2602 access, gsi, insert_after);
2603
2604 if (write)
2605 {
2606 if (access->grp_partial_lhs)
2607 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
2608 !insert_after,
2609 insert_after ? GSI_NEW_STMT
2610 : GSI_SAME_STMT);
2611 stmt = gimple_build_assign (repl, expr);
2612 }
2613 else
2614 {
2615 TREE_NO_WARNING (repl) = 1;
2616 if (access->grp_partial_lhs)
2617 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2618 !insert_after,
2619 insert_after ? GSI_NEW_STMT
2620 : GSI_SAME_STMT);
2621 stmt = gimple_build_assign (expr, repl);
2622 }
2623 gimple_set_location (stmt, loc);
2624
2625 if (insert_after)
2626 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2627 else
2628 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2629 update_stmt (stmt);
2630 sra_stats.subtree_copies++;
2631 }
2632 else if (write
2633 && access->grp_to_be_debug_replaced
2634 && (chunk_size == 0
2635 || access->offset + access->size > start_offset))
2636 {
2637 gimple ds;
2638 tree drhs = build_debug_ref_for_model (loc, agg,
2639 access->offset - top_offset,
2640 access);
2641 ds = gimple_build_debug_bind (get_access_replacement (access),
2642 drhs, gsi_stmt (*gsi));
2643 if (insert_after)
2644 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2645 else
2646 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2647 }
2648
2649 if (access->first_child)
2650 generate_subtree_copies (access->first_child, agg, top_offset,
2651 start_offset, chunk_size, gsi,
2652 write, insert_after, loc);
2653
2654 access = access->next_sibling;
2655 }
2656 while (access);
2657 }
2658
2659 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2660 the root of the subtree to be processed. GSI is the statement iterator used
2661 for inserting statements which are added after the current statement if
2662 INSERT_AFTER is true or before it otherwise. */
2663
2664 static void
2665 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
2666 bool insert_after, location_t loc)
2667
2668 {
2669 struct access *child;
2670
2671 if (access->grp_to_be_replaced)
2672 {
2673 gimple stmt;
2674
2675 stmt = gimple_build_assign (get_access_replacement (access),
2676 build_zero_cst (access->type));
2677 if (insert_after)
2678 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2679 else
2680 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2681 update_stmt (stmt);
2682 gimple_set_location (stmt, loc);
2683 }
2684 else if (access->grp_to_be_debug_replaced)
2685 {
2686 gimple ds = gimple_build_debug_bind (get_access_replacement (access),
2687 build_zero_cst (access->type),
2688 gsi_stmt (*gsi));
2689 if (insert_after)
2690 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2691 else
2692 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
2693 }
2694
2695 for (child = access->first_child; child; child = child->next_sibling)
2696 init_subtree_with_zero (child, gsi, insert_after, loc);
2697 }
2698
2699 /* Search for an access representative for the given expression EXPR and
2700 return it or NULL if it cannot be found. */
2701
2702 static struct access *
2703 get_access_for_expr (tree expr)
2704 {
2705 HOST_WIDE_INT offset, size, max_size;
2706 tree base;
2707
2708 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2709 a different size than the size of its argument and we need the latter
2710 one. */
2711 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
2712 expr = TREE_OPERAND (expr, 0);
2713
2714 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
2715 if (max_size == -1 || !DECL_P (base))
2716 return NULL;
2717
2718 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
2719 return NULL;
2720
2721 return get_var_base_offset_size_access (base, offset, max_size);
2722 }
2723
2724 /* Replace the expression EXPR with a scalar replacement if there is one and
2725 generate other statements to do type conversion or subtree copying if
2726 necessary. GSI is used to place newly created statements, WRITE is true if
2727 the expression is being written to (it is on a LHS of a statement or output
2728 in an assembly statement). */
2729
2730 static bool
2731 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
2732 {
2733 location_t loc;
2734 struct access *access;
2735 tree type, bfr;
2736
2737 if (TREE_CODE (*expr) == BIT_FIELD_REF)
2738 {
2739 bfr = *expr;
2740 expr = &TREE_OPERAND (*expr, 0);
2741 }
2742 else
2743 bfr = NULL_TREE;
2744
2745 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
2746 expr = &TREE_OPERAND (*expr, 0);
2747 access = get_access_for_expr (*expr);
2748 if (!access)
2749 return false;
2750 type = TREE_TYPE (*expr);
2751
2752 loc = gimple_location (gsi_stmt (*gsi));
2753 if (access->grp_to_be_replaced)
2754 {
2755 tree repl = get_access_replacement (access);
2756 /* If we replace a non-register typed access simply use the original
2757 access expression to extract the scalar component afterwards.
2758 This happens if scalarizing a function return value or parameter
2759 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2760 gcc.c-torture/compile/20011217-1.c.
2761
2762 We also want to use this when accessing a complex or vector which can
2763 be accessed as a different type too, potentially creating a need for
2764 type conversion (see PR42196) and when scalarized unions are involved
2765 in assembler statements (see PR42398). */
2766 if (!useless_type_conversion_p (type, access->type))
2767 {
2768 tree ref;
2769
2770 ref = build_ref_for_model (loc, access->base, access->offset, access,
2771 NULL, false);
2772
2773 if (write)
2774 {
2775 gimple stmt;
2776
2777 if (access->grp_partial_lhs)
2778 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
2779 false, GSI_NEW_STMT);
2780 stmt = gimple_build_assign (repl, ref);
2781 gimple_set_location (stmt, loc);
2782 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2783 }
2784 else
2785 {
2786 gimple stmt;
2787
2788 if (access->grp_partial_lhs)
2789 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2790 true, GSI_SAME_STMT);
2791 stmt = gimple_build_assign (ref, repl);
2792 gimple_set_location (stmt, loc);
2793 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2794 }
2795 }
2796 else
2797 *expr = repl;
2798 sra_stats.exprs++;
2799 }
2800 else if (write && access->grp_to_be_debug_replaced)
2801 {
2802 gimple ds = gimple_build_debug_bind (get_access_replacement (access),
2803 NULL_TREE,
2804 gsi_stmt (*gsi));
2805 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
2806 }
2807
2808 if (access->first_child)
2809 {
2810 HOST_WIDE_INT start_offset, chunk_size;
2811 if (bfr
2812 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 1))
2813 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 2)))
2814 {
2815 chunk_size = tree_to_uhwi (TREE_OPERAND (bfr, 1));
2816 start_offset = access->offset
2817 + tree_to_uhwi (TREE_OPERAND (bfr, 2));
2818 }
2819 else
2820 start_offset = chunk_size = 0;
2821
2822 generate_subtree_copies (access->first_child, access->base, 0,
2823 start_offset, chunk_size, gsi, write, write,
2824 loc);
2825 }
2826 return true;
2827 }
2828
2829 /* Where scalar replacements of the RHS have been written to when a replacement
2830 of a LHS of an assigments cannot be direclty loaded from a replacement of
2831 the RHS. */
2832 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
2833 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
2834 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
2835
2836 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2837 base aggregate if there are unscalarized data or directly to LHS of the
2838 statement that is pointed to by GSI otherwise. */
2839
2840 static enum unscalarized_data_handling
2841 handle_unscalarized_data_in_subtree (struct access *top_racc,
2842 gimple_stmt_iterator *gsi)
2843 {
2844 if (top_racc->grp_unscalarized_data)
2845 {
2846 generate_subtree_copies (top_racc->first_child, top_racc->base, 0, 0, 0,
2847 gsi, false, false,
2848 gimple_location (gsi_stmt (*gsi)));
2849 return SRA_UDH_RIGHT;
2850 }
2851 else
2852 {
2853 tree lhs = gimple_assign_lhs (gsi_stmt (*gsi));
2854 generate_subtree_copies (top_racc->first_child, lhs, top_racc->offset,
2855 0, 0, gsi, false, false,
2856 gimple_location (gsi_stmt (*gsi)));
2857 return SRA_UDH_LEFT;
2858 }
2859 }
2860
2861
2862 /* Try to generate statements to load all sub-replacements in an access subtree
2863 formed by children of LACC from scalar replacements in the TOP_RACC subtree.
2864 If that is not possible, refresh the TOP_RACC base aggregate and load the
2865 accesses from it. LEFT_OFFSET is the offset of the left whole subtree being
2866 copied. NEW_GSI is stmt iterator used for statement insertions after the
2867 original assignment, OLD_GSI is used to insert statements before the
2868 assignment. *REFRESHED keeps the information whether we have needed to
2869 refresh replacements of the LHS and from which side of the assignments this
2870 takes place. */
2871
2872 static void
2873 load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
2874 HOST_WIDE_INT left_offset,
2875 gimple_stmt_iterator *old_gsi,
2876 gimple_stmt_iterator *new_gsi,
2877 enum unscalarized_data_handling *refreshed)
2878 {
2879 location_t loc = gimple_location (gsi_stmt (*old_gsi));
2880 for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling)
2881 {
2882 HOST_WIDE_INT offset = lacc->offset - left_offset + top_racc->offset;
2883
2884 if (lacc->grp_to_be_replaced)
2885 {
2886 struct access *racc;
2887 gimple stmt;
2888 tree rhs;
2889
2890 racc = find_access_in_subtree (top_racc, offset, lacc->size);
2891 if (racc && racc->grp_to_be_replaced)
2892 {
2893 rhs = get_access_replacement (racc);
2894 if (!useless_type_conversion_p (lacc->type, racc->type))
2895 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, lacc->type, rhs);
2896
2897 if (racc->grp_partial_lhs && lacc->grp_partial_lhs)
2898 rhs = force_gimple_operand_gsi (old_gsi, rhs, true, NULL_TREE,
2899 true, GSI_SAME_STMT);
2900 }
2901 else
2902 {
2903 /* No suitable access on the right hand side, need to load from
2904 the aggregate. See if we have to update it first... */
2905 if (*refreshed == SRA_UDH_NONE)
2906 *refreshed = handle_unscalarized_data_in_subtree (top_racc,
2907 old_gsi);
2908
2909 if (*refreshed == SRA_UDH_LEFT)
2910 rhs = build_ref_for_model (loc, lacc->base, lacc->offset, lacc,
2911 new_gsi, true);
2912 else
2913 rhs = build_ref_for_model (loc, top_racc->base, offset, lacc,
2914 new_gsi, true);
2915 if (lacc->grp_partial_lhs)
2916 rhs = force_gimple_operand_gsi (new_gsi, rhs, true, NULL_TREE,
2917 false, GSI_NEW_STMT);
2918 }
2919
2920 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
2921 gsi_insert_after (new_gsi, stmt, GSI_NEW_STMT);
2922 gimple_set_location (stmt, loc);
2923 update_stmt (stmt);
2924 sra_stats.subreplacements++;
2925 }
2926 else
2927 {
2928 if (*refreshed == SRA_UDH_NONE
2929 && lacc->grp_read && !lacc->grp_covered)
2930 *refreshed = handle_unscalarized_data_in_subtree (top_racc,
2931 old_gsi);
2932 if (lacc && lacc->grp_to_be_debug_replaced)
2933 {
2934 gimple ds;
2935 tree drhs;
2936 struct access *racc = find_access_in_subtree (top_racc, offset,
2937 lacc->size);
2938
2939 if (racc && racc->grp_to_be_replaced)
2940 {
2941 if (racc->grp_write)
2942 drhs = get_access_replacement (racc);
2943 else
2944 drhs = NULL;
2945 }
2946 else if (*refreshed == SRA_UDH_LEFT)
2947 drhs = build_debug_ref_for_model (loc, lacc->base, lacc->offset,
2948 lacc);
2949 else if (*refreshed == SRA_UDH_RIGHT)
2950 drhs = build_debug_ref_for_model (loc, top_racc->base, offset,
2951 lacc);
2952 else
2953 drhs = NULL_TREE;
2954 ds = gimple_build_debug_bind (get_access_replacement (lacc),
2955 drhs, gsi_stmt (*old_gsi));
2956 gsi_insert_after (new_gsi, ds, GSI_NEW_STMT);
2957 }
2958 }
2959
2960 if (lacc->first_child)
2961 load_assign_lhs_subreplacements (lacc, top_racc, left_offset,
2962 old_gsi, new_gsi, refreshed);
2963 }
2964 }
2965
2966 /* Result code for SRA assignment modification. */
2967 enum assignment_mod_result { SRA_AM_NONE, /* nothing done for the stmt */
2968 SRA_AM_MODIFIED, /* stmt changed but not
2969 removed */
2970 SRA_AM_REMOVED }; /* stmt eliminated */
2971
2972 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
2973 to the assignment and GSI is the statement iterator pointing at it. Returns
2974 the same values as sra_modify_assign. */
2975
2976 static enum assignment_mod_result
2977 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
2978 {
2979 tree lhs = gimple_assign_lhs (*stmt);
2980 struct access *acc;
2981 location_t loc;
2982
2983 acc = get_access_for_expr (lhs);
2984 if (!acc)
2985 return SRA_AM_NONE;
2986
2987 if (gimple_clobber_p (*stmt))
2988 {
2989 /* Remove clobbers of fully scalarized variables, otherwise
2990 do nothing. */
2991 if (acc->grp_covered)
2992 {
2993 unlink_stmt_vdef (*stmt);
2994 gsi_remove (gsi, true);
2995 release_defs (*stmt);
2996 return SRA_AM_REMOVED;
2997 }
2998 else
2999 return SRA_AM_NONE;
3000 }
3001
3002 loc = gimple_location (*stmt);
3003 if (vec_safe_length (CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt))) > 0)
3004 {
3005 /* I have never seen this code path trigger but if it can happen the
3006 following should handle it gracefully. */
3007 if (access_has_children_p (acc))
3008 generate_subtree_copies (acc->first_child, acc->base, 0, 0, 0, gsi,
3009 true, true, loc);
3010 return SRA_AM_MODIFIED;
3011 }
3012
3013 if (acc->grp_covered)
3014 {
3015 init_subtree_with_zero (acc, gsi, false, loc);
3016 unlink_stmt_vdef (*stmt);
3017 gsi_remove (gsi, true);
3018 release_defs (*stmt);
3019 return SRA_AM_REMOVED;
3020 }
3021 else
3022 {
3023 init_subtree_with_zero (acc, gsi, true, loc);
3024 return SRA_AM_MODIFIED;
3025 }
3026 }
3027
3028 /* Create and return a new suitable default definition SSA_NAME for RACC which
3029 is an access describing an uninitialized part of an aggregate that is being
3030 loaded. */
3031
3032 static tree
3033 get_repl_default_def_ssa_name (struct access *racc)
3034 {
3035 gcc_checking_assert (!racc->grp_to_be_replaced
3036 && !racc->grp_to_be_debug_replaced);
3037 if (!racc->replacement_decl)
3038 racc->replacement_decl = create_access_replacement (racc);
3039 return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
3040 }
3041
3042 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
3043 bit-field field declaration somewhere in it. */
3044
3045 static inline bool
3046 contains_vce_or_bfcref_p (const_tree ref)
3047 {
3048 while (handled_component_p (ref))
3049 {
3050 if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
3051 || (TREE_CODE (ref) == COMPONENT_REF
3052 && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
3053 return true;
3054 ref = TREE_OPERAND (ref, 0);
3055 }
3056
3057 return false;
3058 }
3059
3060 /* Examine both sides of the assignment statement pointed to by STMT, replace
3061 them with a scalare replacement if there is one and generate copying of
3062 replacements if scalarized aggregates have been used in the assignment. GSI
3063 is used to hold generated statements for type conversions and subtree
3064 copying. */
3065
3066 static enum assignment_mod_result
3067 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3068 {
3069 struct access *lacc, *racc;
3070 tree lhs, rhs;
3071 bool modify_this_stmt = false;
3072 bool force_gimple_rhs = false;
3073 location_t loc;
3074 gimple_stmt_iterator orig_gsi = *gsi;
3075
3076 if (!gimple_assign_single_p (*stmt))
3077 return SRA_AM_NONE;
3078 lhs = gimple_assign_lhs (*stmt);
3079 rhs = gimple_assign_rhs1 (*stmt);
3080
3081 if (TREE_CODE (rhs) == CONSTRUCTOR)
3082 return sra_modify_constructor_assign (stmt, gsi);
3083
3084 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
3085 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
3086 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
3087 {
3088 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (*stmt),
3089 gsi, false);
3090 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (*stmt),
3091 gsi, true);
3092 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3093 }
3094
3095 lacc = get_access_for_expr (lhs);
3096 racc = get_access_for_expr (rhs);
3097 if (!lacc && !racc)
3098 return SRA_AM_NONE;
3099
3100 loc = gimple_location (*stmt);
3101 if (lacc && lacc->grp_to_be_replaced)
3102 {
3103 lhs = get_access_replacement (lacc);
3104 gimple_assign_set_lhs (*stmt, lhs);
3105 modify_this_stmt = true;
3106 if (lacc->grp_partial_lhs)
3107 force_gimple_rhs = true;
3108 sra_stats.exprs++;
3109 }
3110
3111 if (racc && racc->grp_to_be_replaced)
3112 {
3113 rhs = get_access_replacement (racc);
3114 modify_this_stmt = true;
3115 if (racc->grp_partial_lhs)
3116 force_gimple_rhs = true;
3117 sra_stats.exprs++;
3118 }
3119 else if (racc
3120 && !racc->grp_unscalarized_data
3121 && TREE_CODE (lhs) == SSA_NAME
3122 && !access_has_replacements_p (racc))
3123 {
3124 rhs = get_repl_default_def_ssa_name (racc);
3125 modify_this_stmt = true;
3126 sra_stats.exprs++;
3127 }
3128
3129 if (modify_this_stmt)
3130 {
3131 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3132 {
3133 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3134 ??? This should move to fold_stmt which we simply should
3135 call after building a VIEW_CONVERT_EXPR here. */
3136 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
3137 && !contains_bitfld_component_ref_p (lhs))
3138 {
3139 lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
3140 gimple_assign_set_lhs (*stmt, lhs);
3141 }
3142 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
3143 && !contains_vce_or_bfcref_p (rhs))
3144 rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
3145
3146 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3147 {
3148 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
3149 rhs);
3150 if (is_gimple_reg_type (TREE_TYPE (lhs))
3151 && TREE_CODE (lhs) != SSA_NAME)
3152 force_gimple_rhs = true;
3153 }
3154 }
3155 }
3156
3157 if (lacc && lacc->grp_to_be_debug_replaced)
3158 {
3159 tree dlhs = get_access_replacement (lacc);
3160 tree drhs = unshare_expr (rhs);
3161 if (!useless_type_conversion_p (TREE_TYPE (dlhs), TREE_TYPE (drhs)))
3162 {
3163 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs))
3164 && !contains_vce_or_bfcref_p (drhs))
3165 drhs = build_debug_ref_for_model (loc, drhs, 0, lacc);
3166 if (drhs
3167 && !useless_type_conversion_p (TREE_TYPE (dlhs),
3168 TREE_TYPE (drhs)))
3169 drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
3170 TREE_TYPE (dlhs), drhs);
3171 }
3172 gimple ds = gimple_build_debug_bind (dlhs, drhs, *stmt);
3173 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3174 }
3175
3176 /* From this point on, the function deals with assignments in between
3177 aggregates when at least one has scalar reductions of some of its
3178 components. There are three possible scenarios: Both the LHS and RHS have
3179 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3180
3181 In the first case, we would like to load the LHS components from RHS
3182 components whenever possible. If that is not possible, we would like to
3183 read it directly from the RHS (after updating it by storing in it its own
3184 components). If there are some necessary unscalarized data in the LHS,
3185 those will be loaded by the original assignment too. If neither of these
3186 cases happen, the original statement can be removed. Most of this is done
3187 by load_assign_lhs_subreplacements.
3188
3189 In the second case, we would like to store all RHS scalarized components
3190 directly into LHS and if they cover the aggregate completely, remove the
3191 statement too. In the third case, we want the LHS components to be loaded
3192 directly from the RHS (DSE will remove the original statement if it
3193 becomes redundant).
3194
3195 This is a bit complex but manageable when types match and when unions do
3196 not cause confusion in a way that we cannot really load a component of LHS
3197 from the RHS or vice versa (the access representing this level can have
3198 subaccesses that are accessible only through a different union field at a
3199 higher level - different from the one used in the examined expression).
3200 Unions are fun.
3201
3202 Therefore, I specially handle a fourth case, happening when there is a
3203 specific type cast or it is impossible to locate a scalarized subaccess on
3204 the other side of the expression. If that happens, I simply "refresh" the
3205 RHS by storing in it is scalarized components leave the original statement
3206 there to do the copying and then load the scalar replacements of the LHS.
3207 This is what the first branch does. */
3208
3209 if (modify_this_stmt
3210 || gimple_has_volatile_ops (*stmt)
3211 || contains_vce_or_bfcref_p (rhs)
3212 || contains_vce_or_bfcref_p (lhs))
3213 {
3214 if (access_has_children_p (racc))
3215 generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
3216 gsi, false, false, loc);
3217 if (access_has_children_p (lacc))
3218 generate_subtree_copies (lacc->first_child, lacc->base, 0, 0, 0,
3219 gsi, true, true, loc);
3220 sra_stats.separate_lhs_rhs_handling++;
3221
3222 /* This gimplification must be done after generate_subtree_copies,
3223 lest we insert the subtree copies in the middle of the gimplified
3224 sequence. */
3225 if (force_gimple_rhs)
3226 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
3227 true, GSI_SAME_STMT);
3228 if (gimple_assign_rhs1 (*stmt) != rhs)
3229 {
3230 modify_this_stmt = true;
3231 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
3232 gcc_assert (*stmt == gsi_stmt (orig_gsi));
3233 }
3234
3235 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3236 }
3237 else
3238 {
3239 if (access_has_children_p (lacc)
3240 && access_has_children_p (racc)
3241 /* When an access represents an unscalarizable region, it usually
3242 represents accesses with variable offset and thus must not be used
3243 to generate new memory accesses. */
3244 && !lacc->grp_unscalarizable_region
3245 && !racc->grp_unscalarizable_region)
3246 {
3247 gimple_stmt_iterator orig_gsi = *gsi;
3248 enum unscalarized_data_handling refreshed;
3249
3250 if (lacc->grp_read && !lacc->grp_covered)
3251 refreshed = handle_unscalarized_data_in_subtree (racc, gsi);
3252 else
3253 refreshed = SRA_UDH_NONE;
3254
3255 load_assign_lhs_subreplacements (lacc, racc, lacc->offset,
3256 &orig_gsi, gsi, &refreshed);
3257 if (refreshed != SRA_UDH_RIGHT)
3258 {
3259 gsi_next (gsi);
3260 unlink_stmt_vdef (*stmt);
3261 gsi_remove (&orig_gsi, true);
3262 release_defs (*stmt);
3263 sra_stats.deleted++;
3264 return SRA_AM_REMOVED;
3265 }
3266 }
3267 else
3268 {
3269 if (access_has_children_p (racc)
3270 && !racc->grp_unscalarized_data)
3271 {
3272 if (dump_file)
3273 {
3274 fprintf (dump_file, "Removing load: ");
3275 print_gimple_stmt (dump_file, *stmt, 0, 0);
3276 }
3277 generate_subtree_copies (racc->first_child, lhs,
3278 racc->offset, 0, 0, gsi,
3279 false, false, loc);
3280 gcc_assert (*stmt == gsi_stmt (*gsi));
3281 unlink_stmt_vdef (*stmt);
3282 gsi_remove (gsi, true);
3283 release_defs (*stmt);
3284 sra_stats.deleted++;
3285 return SRA_AM_REMOVED;
3286 }
3287 /* Restore the aggregate RHS from its components so the
3288 prevailing aggregate copy does the right thing. */
3289 if (access_has_children_p (racc))
3290 generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
3291 gsi, false, false, loc);
3292 /* Re-load the components of the aggregate copy destination.
3293 But use the RHS aggregate to load from to expose more
3294 optimization opportunities. */
3295 if (access_has_children_p (lacc))
3296 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
3297 0, 0, gsi, true, true, loc);
3298 }
3299
3300 return SRA_AM_NONE;
3301 }
3302 }
3303
3304 /* Traverse the function body and all modifications as decided in
3305 analyze_all_variable_accesses. Return true iff the CFG has been
3306 changed. */
3307
3308 static bool
3309 sra_modify_function_body (void)
3310 {
3311 bool cfg_changed = false;
3312 basic_block bb;
3313
3314 FOR_EACH_BB (bb)
3315 {
3316 gimple_stmt_iterator gsi = gsi_start_bb (bb);
3317 while (!gsi_end_p (gsi))
3318 {
3319 gimple stmt = gsi_stmt (gsi);
3320 enum assignment_mod_result assign_result;
3321 bool modified = false, deleted = false;
3322 tree *t;
3323 unsigned i;
3324
3325 switch (gimple_code (stmt))
3326 {
3327 case GIMPLE_RETURN:
3328 t = gimple_return_retval_ptr (stmt);
3329 if (*t != NULL_TREE)
3330 modified |= sra_modify_expr (t, &gsi, false);
3331 break;
3332
3333 case GIMPLE_ASSIGN:
3334 assign_result = sra_modify_assign (&stmt, &gsi);
3335 modified |= assign_result == SRA_AM_MODIFIED;
3336 deleted = assign_result == SRA_AM_REMOVED;
3337 break;
3338
3339 case GIMPLE_CALL:
3340 /* Operands must be processed before the lhs. */
3341 for (i = 0; i < gimple_call_num_args (stmt); i++)
3342 {
3343 t = gimple_call_arg_ptr (stmt, i);
3344 modified |= sra_modify_expr (t, &gsi, false);
3345 }
3346
3347 if (gimple_call_lhs (stmt))
3348 {
3349 t = gimple_call_lhs_ptr (stmt);
3350 modified |= sra_modify_expr (t, &gsi, true);
3351 }
3352 break;
3353
3354 case GIMPLE_ASM:
3355 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
3356 {
3357 t = &TREE_VALUE (gimple_asm_input_op (stmt, i));
3358 modified |= sra_modify_expr (t, &gsi, false);
3359 }
3360 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
3361 {
3362 t = &TREE_VALUE (gimple_asm_output_op (stmt, i));
3363 modified |= sra_modify_expr (t, &gsi, true);
3364 }
3365 break;
3366
3367 default:
3368 break;
3369 }
3370
3371 if (modified)
3372 {
3373 update_stmt (stmt);
3374 if (maybe_clean_eh_stmt (stmt)
3375 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
3376 cfg_changed = true;
3377 }
3378 if (!deleted)
3379 gsi_next (&gsi);
3380 }
3381 }
3382
3383 return cfg_changed;
3384 }
3385
3386 /* Generate statements initializing scalar replacements of parts of function
3387 parameters. */
3388
3389 static void
3390 initialize_parameter_reductions (void)
3391 {
3392 gimple_stmt_iterator gsi;
3393 gimple_seq seq = NULL;
3394 tree parm;
3395
3396 gsi = gsi_start (seq);
3397 for (parm = DECL_ARGUMENTS (current_function_decl);
3398 parm;
3399 parm = DECL_CHAIN (parm))
3400 {
3401 vec<access_p> *access_vec;
3402 struct access *access;
3403
3404 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3405 continue;
3406 access_vec = get_base_access_vector (parm);
3407 if (!access_vec)
3408 continue;
3409
3410 for (access = (*access_vec)[0];
3411 access;
3412 access = access->next_grp)
3413 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true,
3414 EXPR_LOCATION (parm));
3415 }
3416
3417 seq = gsi_seq (gsi);
3418 if (seq)
3419 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3420 }
3421
3422 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3423 it reveals there are components of some aggregates to be scalarized, it runs
3424 the required transformations. */
3425 static unsigned int
3426 perform_intra_sra (void)
3427 {
3428 int ret = 0;
3429 sra_initialize ();
3430
3431 if (!find_var_candidates ())
3432 goto out;
3433
3434 if (!scan_function ())
3435 goto out;
3436
3437 if (!analyze_all_variable_accesses ())
3438 goto out;
3439
3440 if (sra_modify_function_body ())
3441 ret = TODO_update_ssa | TODO_cleanup_cfg;
3442 else
3443 ret = TODO_update_ssa;
3444 initialize_parameter_reductions ();
3445
3446 statistics_counter_event (cfun, "Scalar replacements created",
3447 sra_stats.replacements);
3448 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
3449 statistics_counter_event (cfun, "Subtree copy stmts",
3450 sra_stats.subtree_copies);
3451 statistics_counter_event (cfun, "Subreplacement stmts",
3452 sra_stats.subreplacements);
3453 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
3454 statistics_counter_event (cfun, "Separate LHS and RHS handling",
3455 sra_stats.separate_lhs_rhs_handling);
3456
3457 out:
3458 sra_deinitialize ();
3459 return ret;
3460 }
3461
3462 /* Perform early intraprocedural SRA. */
3463 static unsigned int
3464 early_intra_sra (void)
3465 {
3466 sra_mode = SRA_MODE_EARLY_INTRA;
3467 return perform_intra_sra ();
3468 }
3469
3470 /* Perform "late" intraprocedural SRA. */
3471 static unsigned int
3472 late_intra_sra (void)
3473 {
3474 sra_mode = SRA_MODE_INTRA;
3475 return perform_intra_sra ();
3476 }
3477
3478
3479 static bool
3480 gate_intra_sra (void)
3481 {
3482 return flag_tree_sra != 0 && dbg_cnt (tree_sra);
3483 }
3484
3485
3486 namespace {
3487
3488 const pass_data pass_data_sra_early =
3489 {
3490 GIMPLE_PASS, /* type */
3491 "esra", /* name */
3492 OPTGROUP_NONE, /* optinfo_flags */
3493 true, /* has_gate */
3494 true, /* has_execute */
3495 TV_TREE_SRA, /* tv_id */
3496 ( PROP_cfg | PROP_ssa ), /* properties_required */
3497 0, /* properties_provided */
3498 0, /* properties_destroyed */
3499 0, /* todo_flags_start */
3500 ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */
3501 };
3502
3503 class pass_sra_early : public gimple_opt_pass
3504 {
3505 public:
3506 pass_sra_early (gcc::context *ctxt)
3507 : gimple_opt_pass (pass_data_sra_early, ctxt)
3508 {}
3509
3510 /* opt_pass methods: */
3511 bool gate () { return gate_intra_sra (); }
3512 unsigned int execute () { return early_intra_sra (); }
3513
3514 }; // class pass_sra_early
3515
3516 } // anon namespace
3517
3518 gimple_opt_pass *
3519 make_pass_sra_early (gcc::context *ctxt)
3520 {
3521 return new pass_sra_early (ctxt);
3522 }
3523
3524 namespace {
3525
3526 const pass_data pass_data_sra =
3527 {
3528 GIMPLE_PASS, /* type */
3529 "sra", /* name */
3530 OPTGROUP_NONE, /* optinfo_flags */
3531 true, /* has_gate */
3532 true, /* has_execute */
3533 TV_TREE_SRA, /* tv_id */
3534 ( PROP_cfg | PROP_ssa ), /* properties_required */
3535 0, /* properties_provided */
3536 0, /* properties_destroyed */
3537 TODO_update_address_taken, /* todo_flags_start */
3538 ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */
3539 };
3540
3541 class pass_sra : public gimple_opt_pass
3542 {
3543 public:
3544 pass_sra (gcc::context *ctxt)
3545 : gimple_opt_pass (pass_data_sra, ctxt)
3546 {}
3547
3548 /* opt_pass methods: */
3549 bool gate () { return gate_intra_sra (); }
3550 unsigned int execute () { return late_intra_sra (); }
3551
3552 }; // class pass_sra
3553
3554 } // anon namespace
3555
3556 gimple_opt_pass *
3557 make_pass_sra (gcc::context *ctxt)
3558 {
3559 return new pass_sra (ctxt);
3560 }
3561
3562
3563 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
3564 parameter. */
3565
3566 static bool
3567 is_unused_scalar_param (tree parm)
3568 {
3569 tree name;
3570 return (is_gimple_reg (parm)
3571 && (!(name = ssa_default_def (cfun, parm))
3572 || has_zero_uses (name)));
3573 }
3574
3575 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
3576 examine whether there are any direct or otherwise infeasible ones. If so,
3577 return true, otherwise return false. PARM must be a gimple register with a
3578 non-NULL default definition. */
3579
3580 static bool
3581 ptr_parm_has_direct_uses (tree parm)
3582 {
3583 imm_use_iterator ui;
3584 gimple stmt;
3585 tree name = ssa_default_def (cfun, parm);
3586 bool ret = false;
3587
3588 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
3589 {
3590 int uses_ok = 0;
3591 use_operand_p use_p;
3592
3593 if (is_gimple_debug (stmt))
3594 continue;
3595
3596 /* Valid uses include dereferences on the lhs and the rhs. */
3597 if (gimple_has_lhs (stmt))
3598 {
3599 tree lhs = gimple_get_lhs (stmt);
3600 while (handled_component_p (lhs))
3601 lhs = TREE_OPERAND (lhs, 0);
3602 if (TREE_CODE (lhs) == MEM_REF
3603 && TREE_OPERAND (lhs, 0) == name
3604 && integer_zerop (TREE_OPERAND (lhs, 1))
3605 && types_compatible_p (TREE_TYPE (lhs),
3606 TREE_TYPE (TREE_TYPE (name)))
3607 && !TREE_THIS_VOLATILE (lhs))
3608 uses_ok++;
3609 }
3610 if (gimple_assign_single_p (stmt))
3611 {
3612 tree rhs = gimple_assign_rhs1 (stmt);
3613 while (handled_component_p (rhs))
3614 rhs = TREE_OPERAND (rhs, 0);
3615 if (TREE_CODE (rhs) == MEM_REF
3616 && TREE_OPERAND (rhs, 0) == name
3617 && integer_zerop (TREE_OPERAND (rhs, 1))
3618 && types_compatible_p (TREE_TYPE (rhs),
3619 TREE_TYPE (TREE_TYPE (name)))
3620 && !TREE_THIS_VOLATILE (rhs))
3621 uses_ok++;
3622 }
3623 else if (is_gimple_call (stmt))
3624 {
3625 unsigned i;
3626 for (i = 0; i < gimple_call_num_args (stmt); ++i)
3627 {
3628 tree arg = gimple_call_arg (stmt, i);
3629 while (handled_component_p (arg))
3630 arg = TREE_OPERAND (arg, 0);
3631 if (TREE_CODE (arg) == MEM_REF
3632 && TREE_OPERAND (arg, 0) == name
3633 && integer_zerop (TREE_OPERAND (arg, 1))
3634 && types_compatible_p (TREE_TYPE (arg),
3635 TREE_TYPE (TREE_TYPE (name)))
3636 && !TREE_THIS_VOLATILE (arg))
3637 uses_ok++;
3638 }
3639 }
3640
3641 /* If the number of valid uses does not match the number of
3642 uses in this stmt there is an unhandled use. */
3643 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
3644 --uses_ok;
3645
3646 if (uses_ok != 0)
3647 ret = true;
3648
3649 if (ret)
3650 BREAK_FROM_IMM_USE_STMT (ui);
3651 }
3652
3653 return ret;
3654 }
3655
3656 /* Identify candidates for reduction for IPA-SRA based on their type and mark
3657 them in candidate_bitmap. Note that these do not necessarily include
3658 parameter which are unused and thus can be removed. Return true iff any
3659 such candidate has been found. */
3660
3661 static bool
3662 find_param_candidates (void)
3663 {
3664 tree parm;
3665 int count = 0;
3666 bool ret = false;
3667 const char *msg;
3668
3669 for (parm = DECL_ARGUMENTS (current_function_decl);
3670 parm;
3671 parm = DECL_CHAIN (parm))
3672 {
3673 tree type = TREE_TYPE (parm);
3674 tree_node **slot;
3675
3676 count++;
3677
3678 if (TREE_THIS_VOLATILE (parm)
3679 || TREE_ADDRESSABLE (parm)
3680 || (!is_gimple_reg_type (type) && is_va_list_type (type)))
3681 continue;
3682
3683 if (is_unused_scalar_param (parm))
3684 {
3685 ret = true;
3686 continue;
3687 }
3688
3689 if (POINTER_TYPE_P (type))
3690 {
3691 type = TREE_TYPE (type);
3692
3693 if (TREE_CODE (type) == FUNCTION_TYPE
3694 || TYPE_VOLATILE (type)
3695 || (TREE_CODE (type) == ARRAY_TYPE
3696 && TYPE_NONALIASED_COMPONENT (type))
3697 || !is_gimple_reg (parm)
3698 || is_va_list_type (type)
3699 || ptr_parm_has_direct_uses (parm))
3700 continue;
3701 }
3702 else if (!AGGREGATE_TYPE_P (type))
3703 continue;
3704
3705 if (!COMPLETE_TYPE_P (type)
3706 || !tree_fits_uhwi_p (TYPE_SIZE (type))
3707 || tree_to_uhwi (TYPE_SIZE (type)) == 0
3708 || (AGGREGATE_TYPE_P (type)
3709 && type_internals_preclude_sra_p (type, &msg)))
3710 continue;
3711
3712 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
3713 slot = candidates.find_slot_with_hash (parm, DECL_UID (parm), INSERT);
3714 *slot = parm;
3715
3716 ret = true;
3717 if (dump_file && (dump_flags & TDF_DETAILS))
3718 {
3719 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
3720 print_generic_expr (dump_file, parm, 0);
3721 fprintf (dump_file, "\n");
3722 }
3723 }
3724
3725 func_param_count = count;
3726 return ret;
3727 }
3728
3729 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
3730 maybe_modified. */
3731
3732 static bool
3733 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
3734 void *data)
3735 {
3736 struct access *repr = (struct access *) data;
3737
3738 repr->grp_maybe_modified = 1;
3739 return true;
3740 }
3741
3742 /* Analyze what representatives (in linked lists accessible from
3743 REPRESENTATIVES) can be modified by side effects of statements in the
3744 current function. */
3745
3746 static void
3747 analyze_modified_params (vec<access_p> representatives)
3748 {
3749 int i;
3750
3751 for (i = 0; i < func_param_count; i++)
3752 {
3753 struct access *repr;
3754
3755 for (repr = representatives[i];
3756 repr;
3757 repr = repr->next_grp)
3758 {
3759 struct access *access;
3760 bitmap visited;
3761 ao_ref ar;
3762
3763 if (no_accesses_p (repr))
3764 continue;
3765 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
3766 || repr->grp_maybe_modified)
3767 continue;
3768
3769 ao_ref_init (&ar, repr->expr);
3770 visited = BITMAP_ALLOC (NULL);
3771 for (access = repr; access; access = access->next_sibling)
3772 {
3773 /* All accesses are read ones, otherwise grp_maybe_modified would
3774 be trivially set. */
3775 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
3776 mark_maybe_modified, repr, &visited);
3777 if (repr->grp_maybe_modified)
3778 break;
3779 }
3780 BITMAP_FREE (visited);
3781 }
3782 }
3783 }
3784
3785 /* Propagate distances in bb_dereferences in the opposite direction than the
3786 control flow edges, in each step storing the maximum of the current value
3787 and the minimum of all successors. These steps are repeated until the table
3788 stabilizes. Note that BBs which might terminate the functions (according to
3789 final_bbs bitmap) never updated in this way. */
3790
3791 static void
3792 propagate_dereference_distances (void)
3793 {
3794 basic_block bb;
3795
3796 auto_vec<basic_block> queue (last_basic_block_for_function (cfun));
3797 queue.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun));
3798 FOR_EACH_BB (bb)
3799 {
3800 queue.quick_push (bb);
3801 bb->aux = bb;
3802 }
3803
3804 while (!queue.is_empty ())
3805 {
3806 edge_iterator ei;
3807 edge e;
3808 bool change = false;
3809 int i;
3810
3811 bb = queue.pop ();
3812 bb->aux = NULL;
3813
3814 if (bitmap_bit_p (final_bbs, bb->index))
3815 continue;
3816
3817 for (i = 0; i < func_param_count; i++)
3818 {
3819 int idx = bb->index * func_param_count + i;
3820 bool first = true;
3821 HOST_WIDE_INT inh = 0;
3822
3823 FOR_EACH_EDGE (e, ei, bb->succs)
3824 {
3825 int succ_idx = e->dest->index * func_param_count + i;
3826
3827 if (e->src == EXIT_BLOCK_PTR_FOR_FN (cfun))
3828 continue;
3829
3830 if (first)
3831 {
3832 first = false;
3833 inh = bb_dereferences [succ_idx];
3834 }
3835 else if (bb_dereferences [succ_idx] < inh)
3836 inh = bb_dereferences [succ_idx];
3837 }
3838
3839 if (!first && bb_dereferences[idx] < inh)
3840 {
3841 bb_dereferences[idx] = inh;
3842 change = true;
3843 }
3844 }
3845
3846 if (change && !bitmap_bit_p (final_bbs, bb->index))
3847 FOR_EACH_EDGE (e, ei, bb->preds)
3848 {
3849 if (e->src->aux)
3850 continue;
3851
3852 e->src->aux = e->src;
3853 queue.quick_push (e->src);
3854 }
3855 }
3856 }
3857
3858 /* Dump a dereferences TABLE with heading STR to file F. */
3859
3860 static void
3861 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
3862 {
3863 basic_block bb;
3864
3865 fprintf (dump_file, str);
3866 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
3867 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
3868 {
3869 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
3870 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
3871 {
3872 int i;
3873 for (i = 0; i < func_param_count; i++)
3874 {
3875 int idx = bb->index * func_param_count + i;
3876 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
3877 }
3878 }
3879 fprintf (f, "\n");
3880 }
3881 fprintf (dump_file, "\n");
3882 }
3883
3884 /* Determine what (parts of) parameters passed by reference that are not
3885 assigned to are not certainly dereferenced in this function and thus the
3886 dereferencing cannot be safely moved to the caller without potentially
3887 introducing a segfault. Mark such REPRESENTATIVES as
3888 grp_not_necessarilly_dereferenced.
3889
3890 The dereferenced maximum "distance," i.e. the offset + size of the accessed
3891 part is calculated rather than simple booleans are calculated for each
3892 pointer parameter to handle cases when only a fraction of the whole
3893 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
3894 an example).
3895
3896 The maximum dereference distances for each pointer parameter and BB are
3897 already stored in bb_dereference. This routine simply propagates these
3898 values upwards by propagate_dereference_distances and then compares the
3899 distances of individual parameters in the ENTRY BB to the equivalent
3900 distances of each representative of a (fraction of a) parameter. */
3901
3902 static void
3903 analyze_caller_dereference_legality (vec<access_p> representatives)
3904 {
3905 int i;
3906
3907 if (dump_file && (dump_flags & TDF_DETAILS))
3908 dump_dereferences_table (dump_file,
3909 "Dereference table before propagation:\n",
3910 bb_dereferences);
3911
3912 propagate_dereference_distances ();
3913
3914 if (dump_file && (dump_flags & TDF_DETAILS))
3915 dump_dereferences_table (dump_file,
3916 "Dereference table after propagation:\n",
3917 bb_dereferences);
3918
3919 for (i = 0; i < func_param_count; i++)
3920 {
3921 struct access *repr = representatives[i];
3922 int idx = ENTRY_BLOCK_PTR_FOR_FN (cfun)->index * func_param_count + i;
3923
3924 if (!repr || no_accesses_p (repr))
3925 continue;
3926
3927 do
3928 {
3929 if ((repr->offset + repr->size) > bb_dereferences[idx])
3930 repr->grp_not_necessarilly_dereferenced = 1;
3931 repr = repr->next_grp;
3932 }
3933 while (repr);
3934 }
3935 }
3936
3937 /* Return the representative access for the parameter declaration PARM if it is
3938 a scalar passed by reference which is not written to and the pointer value
3939 is not used directly. Thus, if it is legal to dereference it in the caller
3940 and we can rule out modifications through aliases, such parameter should be
3941 turned into one passed by value. Return NULL otherwise. */
3942
3943 static struct access *
3944 unmodified_by_ref_scalar_representative (tree parm)
3945 {
3946 int i, access_count;
3947 struct access *repr;
3948 vec<access_p> *access_vec;
3949
3950 access_vec = get_base_access_vector (parm);
3951 gcc_assert (access_vec);
3952 repr = (*access_vec)[0];
3953 if (repr->write)
3954 return NULL;
3955 repr->group_representative = repr;
3956
3957 access_count = access_vec->length ();
3958 for (i = 1; i < access_count; i++)
3959 {
3960 struct access *access = (*access_vec)[i];
3961 if (access->write)
3962 return NULL;
3963 access->group_representative = repr;
3964 access->next_sibling = repr->next_sibling;
3965 repr->next_sibling = access;
3966 }
3967
3968 repr->grp_read = 1;
3969 repr->grp_scalar_ptr = 1;
3970 return repr;
3971 }
3972
3973 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
3974 associated with. REQ_ALIGN is the minimum required alignment. */
3975
3976 static bool
3977 access_precludes_ipa_sra_p (struct access *access, unsigned int req_align)
3978 {
3979 unsigned int exp_align;
3980 /* Avoid issues such as the second simple testcase in PR 42025. The problem
3981 is incompatible assign in a call statement (and possibly even in asm
3982 statements). This can be relaxed by using a new temporary but only for
3983 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
3984 intraprocedural SRA we deal with this by keeping the old aggregate around,
3985 something we cannot do in IPA-SRA.) */
3986 if (access->write
3987 && (is_gimple_call (access->stmt)
3988 || gimple_code (access->stmt) == GIMPLE_ASM))
3989 return true;
3990
3991 exp_align = get_object_alignment (access->expr);
3992 if (exp_align < req_align)
3993 return true;
3994
3995 return false;
3996 }
3997
3998
3999 /* Sort collected accesses for parameter PARM, identify representatives for
4000 each accessed region and link them together. Return NULL if there are
4001 different but overlapping accesses, return the special ptr value meaning
4002 there are no accesses for this parameter if that is the case and return the
4003 first representative otherwise. Set *RO_GRP if there is a group of accesses
4004 with only read (i.e. no write) accesses. */
4005
4006 static struct access *
4007 splice_param_accesses (tree parm, bool *ro_grp)
4008 {
4009 int i, j, access_count, group_count;
4010 int agg_size, total_size = 0;
4011 struct access *access, *res, **prev_acc_ptr = &res;
4012 vec<access_p> *access_vec;
4013
4014 access_vec = get_base_access_vector (parm);
4015 if (!access_vec)
4016 return &no_accesses_representant;
4017 access_count = access_vec->length ();
4018
4019 access_vec->qsort (compare_access_positions);
4020
4021 i = 0;
4022 total_size = 0;
4023 group_count = 0;
4024 while (i < access_count)
4025 {
4026 bool modification;
4027 tree a1_alias_type;
4028 access = (*access_vec)[i];
4029 modification = access->write;
4030 if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type)))
4031 return NULL;
4032 a1_alias_type = reference_alias_ptr_type (access->expr);
4033
4034 /* Access is about to become group representative unless we find some
4035 nasty overlap which would preclude us from breaking this parameter
4036 apart. */
4037
4038 j = i + 1;
4039 while (j < access_count)
4040 {
4041 struct access *ac2 = (*access_vec)[j];
4042 if (ac2->offset != access->offset)
4043 {
4044 /* All or nothing law for parameters. */
4045 if (access->offset + access->size > ac2->offset)
4046 return NULL;
4047 else
4048 break;
4049 }
4050 else if (ac2->size != access->size)
4051 return NULL;
4052
4053 if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type))
4054 || (ac2->type != access->type
4055 && (TREE_ADDRESSABLE (ac2->type)
4056 || TREE_ADDRESSABLE (access->type)))
4057 || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
4058 return NULL;
4059
4060 modification |= ac2->write;
4061 ac2->group_representative = access;
4062 ac2->next_sibling = access->next_sibling;
4063 access->next_sibling = ac2;
4064 j++;
4065 }
4066
4067 group_count++;
4068 access->grp_maybe_modified = modification;
4069 if (!modification)
4070 *ro_grp = true;
4071 *prev_acc_ptr = access;
4072 prev_acc_ptr = &access->next_grp;
4073 total_size += access->size;
4074 i = j;
4075 }
4076
4077 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4078 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4079 else
4080 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4081 if (total_size >= agg_size)
4082 return NULL;
4083
4084 gcc_assert (group_count > 0);
4085 return res;
4086 }
4087
4088 /* Decide whether parameters with representative accesses given by REPR should
4089 be reduced into components. */
4090
4091 static int
4092 decide_one_param_reduction (struct access *repr)
4093 {
4094 int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
4095 bool by_ref;
4096 tree parm;
4097
4098 parm = repr->base;
4099 cur_parm_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4100 gcc_assert (cur_parm_size > 0);
4101
4102 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4103 {
4104 by_ref = true;
4105 agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))));
4106 }
4107 else
4108 {
4109 by_ref = false;
4110 agg_size = cur_parm_size;
4111 }
4112
4113 if (dump_file)
4114 {
4115 struct access *acc;
4116 fprintf (dump_file, "Evaluating PARAM group sizes for ");
4117 print_generic_expr (dump_file, parm, 0);
4118 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
4119 for (acc = repr; acc; acc = acc->next_grp)
4120 dump_access (dump_file, acc, true);
4121 }
4122
4123 total_size = 0;
4124 new_param_count = 0;
4125
4126 for (; repr; repr = repr->next_grp)
4127 {
4128 gcc_assert (parm == repr->base);
4129
4130 /* Taking the address of a non-addressable field is verboten. */
4131 if (by_ref && repr->non_addressable)
4132 return 0;
4133
4134 /* Do not decompose a non-BLKmode param in a way that would
4135 create BLKmode params. Especially for by-reference passing
4136 (thus, pointer-type param) this is hardly worthwhile. */
4137 if (DECL_MODE (parm) != BLKmode
4138 && TYPE_MODE (repr->type) == BLKmode)
4139 return 0;
4140
4141 if (!by_ref || (!repr->grp_maybe_modified
4142 && !repr->grp_not_necessarilly_dereferenced))
4143 total_size += repr->size;
4144 else
4145 total_size += cur_parm_size;
4146
4147 new_param_count++;
4148 }
4149
4150 gcc_assert (new_param_count > 0);
4151
4152 if (optimize_function_for_size_p (cfun))
4153 parm_size_limit = cur_parm_size;
4154 else
4155 parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
4156 * cur_parm_size);
4157
4158 if (total_size < agg_size
4159 && total_size <= parm_size_limit)
4160 {
4161 if (dump_file)
4162 fprintf (dump_file, " ....will be split into %i components\n",
4163 new_param_count);
4164 return new_param_count;
4165 }
4166 else
4167 return 0;
4168 }
4169
4170 /* The order of the following enums is important, we need to do extra work for
4171 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4172 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
4173 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
4174
4175 /* Identify representatives of all accesses to all candidate parameters for
4176 IPA-SRA. Return result based on what representatives have been found. */
4177
4178 static enum ipa_splicing_result
4179 splice_all_param_accesses (vec<access_p> &representatives)
4180 {
4181 enum ipa_splicing_result result = NO_GOOD_ACCESS;
4182 tree parm;
4183 struct access *repr;
4184
4185 representatives.create (func_param_count);
4186
4187 for (parm = DECL_ARGUMENTS (current_function_decl);
4188 parm;
4189 parm = DECL_CHAIN (parm))
4190 {
4191 if (is_unused_scalar_param (parm))
4192 {
4193 representatives.quick_push (&no_accesses_representant);
4194 if (result == NO_GOOD_ACCESS)
4195 result = UNUSED_PARAMS;
4196 }
4197 else if (POINTER_TYPE_P (TREE_TYPE (parm))
4198 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
4199 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4200 {
4201 repr = unmodified_by_ref_scalar_representative (parm);
4202 representatives.quick_push (repr);
4203 if (repr)
4204 result = UNMODIF_BY_REF_ACCESSES;
4205 }
4206 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4207 {
4208 bool ro_grp = false;
4209 repr = splice_param_accesses (parm, &ro_grp);
4210 representatives.quick_push (repr);
4211
4212 if (repr && !no_accesses_p (repr))
4213 {
4214 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4215 {
4216 if (ro_grp)
4217 result = UNMODIF_BY_REF_ACCESSES;
4218 else if (result < MODIF_BY_REF_ACCESSES)
4219 result = MODIF_BY_REF_ACCESSES;
4220 }
4221 else if (result < BY_VAL_ACCESSES)
4222 result = BY_VAL_ACCESSES;
4223 }
4224 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
4225 result = UNUSED_PARAMS;
4226 }
4227 else
4228 representatives.quick_push (NULL);
4229 }
4230
4231 if (result == NO_GOOD_ACCESS)
4232 {
4233 representatives.release ();
4234 return NO_GOOD_ACCESS;
4235 }
4236
4237 return result;
4238 }
4239
4240 /* Return the index of BASE in PARMS. Abort if it is not found. */
4241
4242 static inline int
4243 get_param_index (tree base, vec<tree> parms)
4244 {
4245 int i, len;
4246
4247 len = parms.length ();
4248 for (i = 0; i < len; i++)
4249 if (parms[i] == base)
4250 return i;
4251 gcc_unreachable ();
4252 }
4253
4254 /* Convert the decisions made at the representative level into compact
4255 parameter adjustments. REPRESENTATIVES are pointers to first
4256 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4257 final number of adjustments. */
4258
4259 static ipa_parm_adjustment_vec
4260 turn_representatives_into_adjustments (vec<access_p> representatives,
4261 int adjustments_count)
4262 {
4263 vec<tree> parms;
4264 ipa_parm_adjustment_vec adjustments;
4265 tree parm;
4266 int i;
4267
4268 gcc_assert (adjustments_count > 0);
4269 parms = ipa_get_vector_of_formal_parms (current_function_decl);
4270 adjustments.create (adjustments_count);
4271 parm = DECL_ARGUMENTS (current_function_decl);
4272 for (i = 0; i < func_param_count; i++, parm = DECL_CHAIN (parm))
4273 {
4274 struct access *repr = representatives[i];
4275
4276 if (!repr || no_accesses_p (repr))
4277 {
4278 struct ipa_parm_adjustment adj;
4279
4280 memset (&adj, 0, sizeof (adj));
4281 adj.base_index = get_param_index (parm, parms);
4282 adj.base = parm;
4283 if (!repr)
4284 adj.copy_param = 1;
4285 else
4286 adj.remove_param = 1;
4287 adjustments.quick_push (adj);
4288 }
4289 else
4290 {
4291 struct ipa_parm_adjustment adj;
4292 int index = get_param_index (parm, parms);
4293
4294 for (; repr; repr = repr->next_grp)
4295 {
4296 memset (&adj, 0, sizeof (adj));
4297 gcc_assert (repr->base == parm);
4298 adj.base_index = index;
4299 adj.base = repr->base;
4300 adj.type = repr->type;
4301 adj.alias_ptr_type = reference_alias_ptr_type (repr->expr);
4302 adj.offset = repr->offset;
4303 adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
4304 && (repr->grp_maybe_modified
4305 || repr->grp_not_necessarilly_dereferenced));
4306 adjustments.quick_push (adj);
4307 }
4308 }
4309 }
4310 parms.release ();
4311 return adjustments;
4312 }
4313
4314 /* Analyze the collected accesses and produce a plan what to do with the
4315 parameters in the form of adjustments, NULL meaning nothing. */
4316
4317 static ipa_parm_adjustment_vec
4318 analyze_all_param_acesses (void)
4319 {
4320 enum ipa_splicing_result repr_state;
4321 bool proceed = false;
4322 int i, adjustments_count = 0;
4323 vec<access_p> representatives;
4324 ipa_parm_adjustment_vec adjustments;
4325
4326 repr_state = splice_all_param_accesses (representatives);
4327 if (repr_state == NO_GOOD_ACCESS)
4328 return ipa_parm_adjustment_vec ();
4329
4330 /* If there are any parameters passed by reference which are not modified
4331 directly, we need to check whether they can be modified indirectly. */
4332 if (repr_state == UNMODIF_BY_REF_ACCESSES)
4333 {
4334 analyze_caller_dereference_legality (representatives);
4335 analyze_modified_params (representatives);
4336 }
4337
4338 for (i = 0; i < func_param_count; i++)
4339 {
4340 struct access *repr = representatives[i];
4341
4342 if (repr && !no_accesses_p (repr))
4343 {
4344 if (repr->grp_scalar_ptr)
4345 {
4346 adjustments_count++;
4347 if (repr->grp_not_necessarilly_dereferenced
4348 || repr->grp_maybe_modified)
4349 representatives[i] = NULL;
4350 else
4351 {
4352 proceed = true;
4353 sra_stats.scalar_by_ref_to_by_val++;
4354 }
4355 }
4356 else
4357 {
4358 int new_components = decide_one_param_reduction (repr);
4359
4360 if (new_components == 0)
4361 {
4362 representatives[i] = NULL;
4363 adjustments_count++;
4364 }
4365 else
4366 {
4367 adjustments_count += new_components;
4368 sra_stats.aggregate_params_reduced++;
4369 sra_stats.param_reductions_created += new_components;
4370 proceed = true;
4371 }
4372 }
4373 }
4374 else
4375 {
4376 if (no_accesses_p (repr))
4377 {
4378 proceed = true;
4379 sra_stats.deleted_unused_parameters++;
4380 }
4381 adjustments_count++;
4382 }
4383 }
4384
4385 if (!proceed && dump_file)
4386 fprintf (dump_file, "NOT proceeding to change params.\n");
4387
4388 if (proceed)
4389 adjustments = turn_representatives_into_adjustments (representatives,
4390 adjustments_count);
4391 else
4392 adjustments = ipa_parm_adjustment_vec ();
4393
4394 representatives.release ();
4395 return adjustments;
4396 }
4397
4398 /* If a parameter replacement identified by ADJ does not yet exist in the form
4399 of declaration, create it and record it, otherwise return the previously
4400 created one. */
4401
4402 static tree
4403 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
4404 {
4405 tree repl;
4406 if (!adj->new_ssa_base)
4407 {
4408 char *pretty_name = make_fancy_name (adj->base);
4409
4410 repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR");
4411 DECL_NAME (repl) = get_identifier (pretty_name);
4412 obstack_free (&name_obstack, pretty_name);
4413
4414 adj->new_ssa_base = repl;
4415 }
4416 else
4417 repl = adj->new_ssa_base;
4418 return repl;
4419 }
4420
4421 /* Find the first adjustment for a particular parameter BASE in a vector of
4422 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4423 adjustment. */
4424
4425 static struct ipa_parm_adjustment *
4426 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
4427 {
4428 int i, len;
4429
4430 len = adjustments.length ();
4431 for (i = 0; i < len; i++)
4432 {
4433 struct ipa_parm_adjustment *adj;
4434
4435 adj = &adjustments[i];
4436 if (!adj->copy_param && adj->base == base)
4437 return adj;
4438 }
4439
4440 return NULL;
4441 }
4442
4443 /* If the statement STMT defines an SSA_NAME of a parameter which is to be
4444 removed because its value is not used, replace the SSA_NAME with a one
4445 relating to a created VAR_DECL together all of its uses and return true.
4446 ADJUSTMENTS is a pointer to an adjustments vector. */
4447
4448 static bool
4449 replace_removed_params_ssa_names (gimple stmt,
4450 ipa_parm_adjustment_vec adjustments)
4451 {
4452 struct ipa_parm_adjustment *adj;
4453 tree lhs, decl, repl, name;
4454
4455 if (gimple_code (stmt) == GIMPLE_PHI)
4456 lhs = gimple_phi_result (stmt);
4457 else if (is_gimple_assign (stmt))
4458 lhs = gimple_assign_lhs (stmt);
4459 else if (is_gimple_call (stmt))
4460 lhs = gimple_call_lhs (stmt);
4461 else
4462 gcc_unreachable ();
4463
4464 if (TREE_CODE (lhs) != SSA_NAME)
4465 return false;
4466
4467 decl = SSA_NAME_VAR (lhs);
4468 if (decl == NULL_TREE
4469 || TREE_CODE (decl) != PARM_DECL)
4470 return false;
4471
4472 adj = get_adjustment_for_base (adjustments, decl);
4473 if (!adj)
4474 return false;
4475
4476 repl = get_replaced_param_substitute (adj);
4477 name = make_ssa_name (repl, stmt);
4478
4479 if (dump_file)
4480 {
4481 fprintf (dump_file, "replacing an SSA name of a removed param ");
4482 print_generic_expr (dump_file, lhs, 0);
4483 fprintf (dump_file, " with ");
4484 print_generic_expr (dump_file, name, 0);
4485 fprintf (dump_file, "\n");
4486 }
4487
4488 if (is_gimple_assign (stmt))
4489 gimple_assign_set_lhs (stmt, name);
4490 else if (is_gimple_call (stmt))
4491 gimple_call_set_lhs (stmt, name);
4492 else
4493 gimple_phi_set_result (stmt, name);
4494
4495 replace_uses_by (lhs, name);
4496 release_ssa_name (lhs);
4497 return true;
4498 }
4499
4500 /* If the expression *EXPR should be replaced by a reduction of a parameter, do
4501 so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
4502 specifies whether the function should care about type incompatibility the
4503 current and new expressions. If it is false, the function will leave
4504 incompatibility issues to the caller. Return true iff the expression
4505 was modified. */
4506
4507 static bool
4508 sra_ipa_modify_expr (tree *expr, bool convert,
4509 ipa_parm_adjustment_vec adjustments)
4510 {
4511 int i, len;
4512 struct ipa_parm_adjustment *adj, *cand = NULL;
4513 HOST_WIDE_INT offset, size, max_size;
4514 tree base, src;
4515
4516 len = adjustments.length ();
4517
4518 if (TREE_CODE (*expr) == BIT_FIELD_REF
4519 || TREE_CODE (*expr) == IMAGPART_EXPR
4520 || TREE_CODE (*expr) == REALPART_EXPR)
4521 {
4522 expr = &TREE_OPERAND (*expr, 0);
4523 convert = true;
4524 }
4525
4526 base = get_ref_base_and_extent (*expr, &offset, &size, &max_size);
4527 if (!base || size == -1 || max_size == -1)
4528 return false;
4529
4530 if (TREE_CODE (base) == MEM_REF)
4531 {
4532 offset += mem_ref_offset (base).low * BITS_PER_UNIT;
4533 base = TREE_OPERAND (base, 0);
4534 }
4535
4536 base = get_ssa_base_param (base);
4537 if (!base || TREE_CODE (base) != PARM_DECL)
4538 return false;
4539
4540 for (i = 0; i < len; i++)
4541 {
4542 adj = &adjustments[i];
4543
4544 if (adj->base == base
4545 && (adj->offset == offset || adj->remove_param))
4546 {
4547 cand = adj;
4548 break;
4549 }
4550 }
4551 if (!cand || cand->copy_param || cand->remove_param)
4552 return false;
4553
4554 if (cand->by_ref)
4555 src = build_simple_mem_ref (cand->reduction);
4556 else
4557 src = cand->reduction;
4558
4559 if (dump_file && (dump_flags & TDF_DETAILS))
4560 {
4561 fprintf (dump_file, "About to replace expr ");
4562 print_generic_expr (dump_file, *expr, 0);
4563 fprintf (dump_file, " with ");
4564 print_generic_expr (dump_file, src, 0);
4565 fprintf (dump_file, "\n");
4566 }
4567
4568 if (convert && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
4569 {
4570 tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
4571 *expr = vce;
4572 }
4573 else
4574 *expr = src;
4575 return true;
4576 }
4577
4578 /* If the statement pointed to by STMT_PTR contains any expressions that need
4579 to replaced with a different one as noted by ADJUSTMENTS, do so. Handle any
4580 potential type incompatibilities (GSI is used to accommodate conversion
4581 statements and must point to the statement). Return true iff the statement
4582 was modified. */
4583
4584 static bool
4585 sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi,
4586 ipa_parm_adjustment_vec adjustments)
4587 {
4588 gimple stmt = *stmt_ptr;
4589 tree *lhs_p, *rhs_p;
4590 bool any;
4591
4592 if (!gimple_assign_single_p (stmt))
4593 return false;
4594
4595 rhs_p = gimple_assign_rhs1_ptr (stmt);
4596 lhs_p = gimple_assign_lhs_ptr (stmt);
4597
4598 any = sra_ipa_modify_expr (rhs_p, false, adjustments);
4599 any |= sra_ipa_modify_expr (lhs_p, false, adjustments);
4600 if (any)
4601 {
4602 tree new_rhs = NULL_TREE;
4603
4604 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
4605 {
4606 if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
4607 {
4608 /* V_C_Es of constructors can cause trouble (PR 42714). */
4609 if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
4610 *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
4611 else
4612 *rhs_p = build_constructor (TREE_TYPE (*lhs_p),
4613 NULL);
4614 }
4615 else
4616 new_rhs = fold_build1_loc (gimple_location (stmt),
4617 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
4618 *rhs_p);
4619 }
4620 else if (REFERENCE_CLASS_P (*rhs_p)
4621 && is_gimple_reg_type (TREE_TYPE (*lhs_p))
4622 && !is_gimple_reg (*lhs_p))
4623 /* This can happen when an assignment in between two single field
4624 structures is turned into an assignment in between two pointers to
4625 scalars (PR 42237). */
4626 new_rhs = *rhs_p;
4627
4628 if (new_rhs)
4629 {
4630 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
4631 true, GSI_SAME_STMT);
4632
4633 gimple_assign_set_rhs_from_tree (gsi, tmp);
4634 }
4635
4636 return true;
4637 }
4638
4639 return false;
4640 }
4641
4642 /* Traverse the function body and all modifications as described in
4643 ADJUSTMENTS. Return true iff the CFG has been changed. */
4644
4645 static bool
4646 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
4647 {
4648 bool cfg_changed = false;
4649 basic_block bb;
4650
4651 FOR_EACH_BB (bb)
4652 {
4653 gimple_stmt_iterator gsi;
4654
4655 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4656 replace_removed_params_ssa_names (gsi_stmt (gsi), adjustments);
4657
4658 gsi = gsi_start_bb (bb);
4659 while (!gsi_end_p (gsi))
4660 {
4661 gimple stmt = gsi_stmt (gsi);
4662 bool modified = false;
4663 tree *t;
4664 unsigned i;
4665
4666 switch (gimple_code (stmt))
4667 {
4668 case GIMPLE_RETURN:
4669 t = gimple_return_retval_ptr (stmt);
4670 if (*t != NULL_TREE)
4671 modified |= sra_ipa_modify_expr (t, true, adjustments);
4672 break;
4673
4674 case GIMPLE_ASSIGN:
4675 modified |= sra_ipa_modify_assign (&stmt, &gsi, adjustments);
4676 modified |= replace_removed_params_ssa_names (stmt, adjustments);
4677 break;
4678
4679 case GIMPLE_CALL:
4680 /* Operands must be processed before the lhs. */
4681 for (i = 0; i < gimple_call_num_args (stmt); i++)
4682 {
4683 t = gimple_call_arg_ptr (stmt, i);
4684 modified |= sra_ipa_modify_expr (t, true, adjustments);
4685 }
4686
4687 if (gimple_call_lhs (stmt))
4688 {
4689 t = gimple_call_lhs_ptr (stmt);
4690 modified |= sra_ipa_modify_expr (t, false, adjustments);
4691 modified |= replace_removed_params_ssa_names (stmt,
4692 adjustments);
4693 }
4694 break;
4695
4696 case GIMPLE_ASM:
4697 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
4698 {
4699 t = &TREE_VALUE (gimple_asm_input_op (stmt, i));
4700 modified |= sra_ipa_modify_expr (t, true, adjustments);
4701 }
4702 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
4703 {
4704 t = &TREE_VALUE (gimple_asm_output_op (stmt, i));
4705 modified |= sra_ipa_modify_expr (t, false, adjustments);
4706 }
4707 break;
4708
4709 default:
4710 break;
4711 }
4712
4713 if (modified)
4714 {
4715 update_stmt (stmt);
4716 if (maybe_clean_eh_stmt (stmt)
4717 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
4718 cfg_changed = true;
4719 }
4720 gsi_next (&gsi);
4721 }
4722 }
4723
4724 return cfg_changed;
4725 }
4726
4727 /* Call gimple_debug_bind_reset_value on all debug statements describing
4728 gimple register parameters that are being removed or replaced. */
4729
4730 static void
4731 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
4732 {
4733 int i, len;
4734 gimple_stmt_iterator *gsip = NULL, gsi;
4735
4736 if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
4737 {
4738 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
4739 gsip = &gsi;
4740 }
4741 len = adjustments.length ();
4742 for (i = 0; i < len; i++)
4743 {
4744 struct ipa_parm_adjustment *adj;
4745 imm_use_iterator ui;
4746 gimple stmt, def_temp;
4747 tree name, vexpr, copy = NULL_TREE;
4748 use_operand_p use_p;
4749
4750 adj = &adjustments[i];
4751 if (adj->copy_param || !is_gimple_reg (adj->base))
4752 continue;
4753 name = ssa_default_def (cfun, adj->base);
4754 vexpr = NULL;
4755 if (name)
4756 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
4757 {
4758 if (gimple_clobber_p (stmt))
4759 {
4760 gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
4761 unlink_stmt_vdef (stmt);
4762 gsi_remove (&cgsi, true);
4763 release_defs (stmt);
4764 continue;
4765 }
4766 /* All other users must have been removed by
4767 ipa_sra_modify_function_body. */
4768 gcc_assert (is_gimple_debug (stmt));
4769 if (vexpr == NULL && gsip != NULL)
4770 {
4771 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
4772 vexpr = make_node (DEBUG_EXPR_DECL);
4773 def_temp = gimple_build_debug_source_bind (vexpr, adj->base,
4774 NULL);
4775 DECL_ARTIFICIAL (vexpr) = 1;
4776 TREE_TYPE (vexpr) = TREE_TYPE (name);
4777 DECL_MODE (vexpr) = DECL_MODE (adj->base);
4778 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
4779 }
4780 if (vexpr)
4781 {
4782 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
4783 SET_USE (use_p, vexpr);
4784 }
4785 else
4786 gimple_debug_bind_reset_value (stmt);
4787 update_stmt (stmt);
4788 }
4789 /* Create a VAR_DECL for debug info purposes. */
4790 if (!DECL_IGNORED_P (adj->base))
4791 {
4792 copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
4793 VAR_DECL, DECL_NAME (adj->base),
4794 TREE_TYPE (adj->base));
4795 if (DECL_PT_UID_SET_P (adj->base))
4796 SET_DECL_PT_UID (copy, DECL_PT_UID (adj->base));
4797 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (adj->base);
4798 TREE_READONLY (copy) = TREE_READONLY (adj->base);
4799 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (adj->base);
4800 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (adj->base);
4801 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (adj->base);
4802 DECL_IGNORED_P (copy) = DECL_IGNORED_P (adj->base);
4803 DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (adj->base);
4804 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
4805 SET_DECL_RTL (copy, 0);
4806 TREE_USED (copy) = 1;
4807 DECL_CONTEXT (copy) = current_function_decl;
4808 add_local_decl (cfun, copy);
4809 DECL_CHAIN (copy) =
4810 BLOCK_VARS (DECL_INITIAL (current_function_decl));
4811 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
4812 }
4813 if (gsip != NULL && copy && target_for_debug_bind (adj->base))
4814 {
4815 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
4816 if (vexpr)
4817 def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
4818 else
4819 def_temp = gimple_build_debug_source_bind (copy, adj->base,
4820 NULL);
4821 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
4822 }
4823 }
4824 }
4825
4826 /* Return false iff all callers have at least as many actual arguments as there
4827 are formal parameters in the current function. */
4828
4829 static bool
4830 not_all_callers_have_enough_arguments_p (struct cgraph_node *node,
4831 void *data ATTRIBUTE_UNUSED)
4832 {
4833 struct cgraph_edge *cs;
4834 for (cs = node->callers; cs; cs = cs->next_caller)
4835 if (!callsite_has_enough_arguments_p (cs->call_stmt))
4836 return true;
4837
4838 return false;
4839 }
4840
4841 /* Convert all callers of NODE. */
4842
4843 static bool
4844 convert_callers_for_node (struct cgraph_node *node,
4845 void *data)
4846 {
4847 ipa_parm_adjustment_vec *adjustments = (ipa_parm_adjustment_vec *) data;
4848 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
4849 struct cgraph_edge *cs;
4850
4851 for (cs = node->callers; cs; cs = cs->next_caller)
4852 {
4853 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
4854
4855 if (dump_file)
4856 fprintf (dump_file, "Adjusting call %s/%i -> %s/%i\n",
4857 xstrdup (cs->caller->name ()),
4858 cs->caller->order,
4859 xstrdup (cs->callee->name ()),
4860 cs->callee->order);
4861
4862 ipa_modify_call_arguments (cs, cs->call_stmt, *adjustments);
4863
4864 pop_cfun ();
4865 }
4866
4867 for (cs = node->callers; cs; cs = cs->next_caller)
4868 if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
4869 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
4870 compute_inline_parameters (cs->caller, true);
4871 BITMAP_FREE (recomputed_callers);
4872
4873 return true;
4874 }
4875
4876 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
4877
4878 static void
4879 convert_callers (struct cgraph_node *node, tree old_decl,
4880 ipa_parm_adjustment_vec adjustments)
4881 {
4882 basic_block this_block;
4883
4884 cgraph_for_node_and_aliases (node, convert_callers_for_node,
4885 &adjustments, false);
4886
4887 if (!encountered_recursive_call)
4888 return;
4889
4890 FOR_EACH_BB (this_block)
4891 {
4892 gimple_stmt_iterator gsi;
4893
4894 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
4895 {
4896 gimple stmt = gsi_stmt (gsi);
4897 tree call_fndecl;
4898 if (gimple_code (stmt) != GIMPLE_CALL)
4899 continue;
4900 call_fndecl = gimple_call_fndecl (stmt);
4901 if (call_fndecl == old_decl)
4902 {
4903 if (dump_file)
4904 fprintf (dump_file, "Adjusting recursive call");
4905 gimple_call_set_fndecl (stmt, node->decl);
4906 ipa_modify_call_arguments (NULL, stmt, adjustments);
4907 }
4908 }
4909 }
4910
4911 return;
4912 }
4913
4914 /* Perform all the modification required in IPA-SRA for NODE to have parameters
4915 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
4916
4917 static bool
4918 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
4919 {
4920 struct cgraph_node *new_node;
4921 bool cfg_changed;
4922 vec<cgraph_edge_p> redirect_callers = collect_callers_of_node (node);
4923
4924 rebuild_cgraph_edges ();
4925 free_dominance_info (CDI_DOMINATORS);
4926 pop_cfun ();
4927
4928 new_node = cgraph_function_versioning (node, redirect_callers,
4929 NULL,
4930 NULL, false, NULL, NULL, "isra");
4931 redirect_callers.release ();
4932
4933 push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
4934 ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA");
4935 cfg_changed = ipa_sra_modify_function_body (adjustments);
4936 sra_ipa_reset_debug_stmts (adjustments);
4937 convert_callers (new_node, node->decl, adjustments);
4938 cgraph_make_node_local (new_node);
4939 return cfg_changed;
4940 }
4941
4942 /* If NODE has a caller, return true. */
4943
4944 static bool
4945 has_caller_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
4946 {
4947 if (node->callers)
4948 return true;
4949 return false;
4950 }
4951
4952 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
4953 attributes, return true otherwise. NODE is the cgraph node of the current
4954 function. */
4955
4956 static bool
4957 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
4958 {
4959 if (!cgraph_node_can_be_local_p (node))
4960 {
4961 if (dump_file)
4962 fprintf (dump_file, "Function not local to this compilation unit.\n");
4963 return false;
4964 }
4965
4966 if (!node->local.can_change_signature)
4967 {
4968 if (dump_file)
4969 fprintf (dump_file, "Function can not change signature.\n");
4970 return false;
4971 }
4972
4973 if (!tree_versionable_function_p (node->decl))
4974 {
4975 if (dump_file)
4976 fprintf (dump_file, "Function is not versionable.\n");
4977 return false;
4978 }
4979
4980 if (DECL_VIRTUAL_P (current_function_decl))
4981 {
4982 if (dump_file)
4983 fprintf (dump_file, "Function is a virtual method.\n");
4984 return false;
4985 }
4986
4987 if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
4988 && inline_summary (node)->size >= MAX_INLINE_INSNS_AUTO)
4989 {
4990 if (dump_file)
4991 fprintf (dump_file, "Function too big to be made truly local.\n");
4992 return false;
4993 }
4994
4995 if (!cgraph_for_node_and_aliases (node, has_caller_p, NULL, true))
4996 {
4997 if (dump_file)
4998 fprintf (dump_file,
4999 "Function has no callers in this compilation unit.\n");
5000 return false;
5001 }
5002
5003 if (cfun->stdarg)
5004 {
5005 if (dump_file)
5006 fprintf (dump_file, "Function uses stdarg. \n");
5007 return false;
5008 }
5009
5010 if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
5011 return false;
5012
5013 return true;
5014 }
5015
5016 /* Perform early interprocedural SRA. */
5017
5018 static unsigned int
5019 ipa_early_sra (void)
5020 {
5021 struct cgraph_node *node = cgraph_get_node (current_function_decl);
5022 ipa_parm_adjustment_vec adjustments;
5023 int ret = 0;
5024
5025 if (!ipa_sra_preliminary_function_checks (node))
5026 return 0;
5027
5028 sra_initialize ();
5029 sra_mode = SRA_MODE_EARLY_IPA;
5030
5031 if (!find_param_candidates ())
5032 {
5033 if (dump_file)
5034 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
5035 goto simple_out;
5036 }
5037
5038 if (cgraph_for_node_and_aliases (node, not_all_callers_have_enough_arguments_p,
5039 NULL, true))
5040 {
5041 if (dump_file)
5042 fprintf (dump_file, "There are callers with insufficient number of "
5043 "arguments.\n");
5044 goto simple_out;
5045 }
5046
5047 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
5048 func_param_count
5049 * last_basic_block_for_function (cfun));
5050 final_bbs = BITMAP_ALLOC (NULL);
5051
5052 scan_function ();
5053 if (encountered_apply_args)
5054 {
5055 if (dump_file)
5056 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
5057 goto out;
5058 }
5059
5060 if (encountered_unchangable_recursive_call)
5061 {
5062 if (dump_file)
5063 fprintf (dump_file, "Function calls itself with insufficient "
5064 "number of arguments.\n");
5065 goto out;
5066 }
5067
5068 adjustments = analyze_all_param_acesses ();
5069 if (!adjustments.exists ())
5070 goto out;
5071 if (dump_file)
5072 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
5073
5074 if (modify_function (node, adjustments))
5075 ret = TODO_update_ssa | TODO_cleanup_cfg;
5076 else
5077 ret = TODO_update_ssa;
5078 adjustments.release ();
5079
5080 statistics_counter_event (cfun, "Unused parameters deleted",
5081 sra_stats.deleted_unused_parameters);
5082 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
5083 sra_stats.scalar_by_ref_to_by_val);
5084 statistics_counter_event (cfun, "Aggregate parameters broken up",
5085 sra_stats.aggregate_params_reduced);
5086 statistics_counter_event (cfun, "Aggregate parameter components created",
5087 sra_stats.param_reductions_created);
5088
5089 out:
5090 BITMAP_FREE (final_bbs);
5091 free (bb_dereferences);
5092 simple_out:
5093 sra_deinitialize ();
5094 return ret;
5095 }
5096
5097 /* Return if early ipa sra shall be performed. */
5098 static bool
5099 ipa_early_sra_gate (void)
5100 {
5101 return flag_ipa_sra && dbg_cnt (eipa_sra);
5102 }
5103
5104 namespace {
5105
5106 const pass_data pass_data_early_ipa_sra =
5107 {
5108 GIMPLE_PASS, /* type */
5109 "eipa_sra", /* name */
5110 OPTGROUP_NONE, /* optinfo_flags */
5111 true, /* has_gate */
5112 true, /* has_execute */
5113 TV_IPA_SRA, /* tv_id */
5114 0, /* properties_required */
5115 0, /* properties_provided */
5116 0, /* properties_destroyed */
5117 0, /* todo_flags_start */
5118 TODO_dump_symtab, /* todo_flags_finish */
5119 };
5120
5121 class pass_early_ipa_sra : public gimple_opt_pass
5122 {
5123 public:
5124 pass_early_ipa_sra (gcc::context *ctxt)
5125 : gimple_opt_pass (pass_data_early_ipa_sra, ctxt)
5126 {}
5127
5128 /* opt_pass methods: */
5129 bool gate () { return ipa_early_sra_gate (); }
5130 unsigned int execute () { return ipa_early_sra (); }
5131
5132 }; // class pass_early_ipa_sra
5133
5134 } // anon namespace
5135
5136 gimple_opt_pass *
5137 make_pass_early_ipa_sra (gcc::context *ctxt)
5138 {
5139 return new pass_early_ipa_sra (ctxt);
5140 }