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