]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/tree-sra.c
36f7885cfcee9327f779e0666f138c020040c0e6
[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-2017 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 (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 (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1502 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1503 encountered_apply_args = true;
1504 if (recursive_call_p (current_function_decl, dest))
1505 {
1506 encountered_recursive_call = true;
1507 if (!callsite_arguments_match_p (stmt))
1508 encountered_unchangable_recursive_call = true;
1509 }
1510 }
1511
1512 if (final_bbs
1513 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1514 bitmap_set_bit (final_bbs, bb->index);
1515 }
1516
1517 t = gimple_call_lhs (stmt);
1518 if (t && !disqualify_if_bad_bb_terminating_stmt (stmt, t, NULL))
1519 ret |= build_access_from_expr (t, stmt, true);
1520 break;
1521
1522 case GIMPLE_ASM:
1523 {
1524 gasm *asm_stmt = as_a <gasm *> (stmt);
1525 walk_stmt_load_store_addr_ops (asm_stmt, NULL, NULL, NULL,
1526 asm_visit_addr);
1527 if (final_bbs)
1528 bitmap_set_bit (final_bbs, bb->index);
1529
1530 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
1531 {
1532 t = TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
1533 ret |= build_access_from_expr (t, asm_stmt, false);
1534 }
1535 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
1536 {
1537 t = TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
1538 ret |= build_access_from_expr (t, asm_stmt, true);
1539 }
1540 }
1541 break;
1542
1543 default:
1544 break;
1545 }
1546 }
1547 }
1548
1549 return ret;
1550 }
1551
1552 /* Helper of QSORT function. There are pointers to accesses in the array. An
1553 access is considered smaller than another if it has smaller offset or if the
1554 offsets are the same but is size is bigger. */
1555
1556 static int
1557 compare_access_positions (const void *a, const void *b)
1558 {
1559 const access_p *fp1 = (const access_p *) a;
1560 const access_p *fp2 = (const access_p *) b;
1561 const access_p f1 = *fp1;
1562 const access_p f2 = *fp2;
1563
1564 if (f1->offset != f2->offset)
1565 return f1->offset < f2->offset ? -1 : 1;
1566
1567 if (f1->size == f2->size)
1568 {
1569 if (f1->type == f2->type)
1570 return 0;
1571 /* Put any non-aggregate type before any aggregate type. */
1572 else if (!is_gimple_reg_type (f1->type)
1573 && is_gimple_reg_type (f2->type))
1574 return 1;
1575 else if (is_gimple_reg_type (f1->type)
1576 && !is_gimple_reg_type (f2->type))
1577 return -1;
1578 /* Put any complex or vector type before any other scalar type. */
1579 else if (TREE_CODE (f1->type) != COMPLEX_TYPE
1580 && TREE_CODE (f1->type) != VECTOR_TYPE
1581 && (TREE_CODE (f2->type) == COMPLEX_TYPE
1582 || TREE_CODE (f2->type) == VECTOR_TYPE))
1583 return 1;
1584 else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
1585 || TREE_CODE (f1->type) == VECTOR_TYPE)
1586 && TREE_CODE (f2->type) != COMPLEX_TYPE
1587 && TREE_CODE (f2->type) != VECTOR_TYPE)
1588 return -1;
1589 /* Put any integral type before any non-integral type. When splicing, we
1590 make sure that those with insufficient precision and occupying the
1591 same space are not scalarized. */
1592 else if (INTEGRAL_TYPE_P (f1->type)
1593 && !INTEGRAL_TYPE_P (f2->type))
1594 return -1;
1595 else if (!INTEGRAL_TYPE_P (f1->type)
1596 && INTEGRAL_TYPE_P (f2->type))
1597 return 1;
1598 /* Put the integral type with the bigger precision first. */
1599 else if (INTEGRAL_TYPE_P (f1->type)
1600 && INTEGRAL_TYPE_P (f2->type)
1601 && (TYPE_PRECISION (f2->type) != TYPE_PRECISION (f1->type)))
1602 return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type);
1603 /* Stabilize the sort. */
1604 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1605 }
1606
1607 /* We want the bigger accesses first, thus the opposite operator in the next
1608 line: */
1609 return f1->size > f2->size ? -1 : 1;
1610 }
1611
1612
1613 /* Append a name of the declaration to the name obstack. A helper function for
1614 make_fancy_name. */
1615
1616 static void
1617 make_fancy_decl_name (tree decl)
1618 {
1619 char buffer[32];
1620
1621 tree name = DECL_NAME (decl);
1622 if (name)
1623 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1624 IDENTIFIER_LENGTH (name));
1625 else
1626 {
1627 sprintf (buffer, "D%u", DECL_UID (decl));
1628 obstack_grow (&name_obstack, buffer, strlen (buffer));
1629 }
1630 }
1631
1632 /* Helper for make_fancy_name. */
1633
1634 static void
1635 make_fancy_name_1 (tree expr)
1636 {
1637 char buffer[32];
1638 tree index;
1639
1640 if (DECL_P (expr))
1641 {
1642 make_fancy_decl_name (expr);
1643 return;
1644 }
1645
1646 switch (TREE_CODE (expr))
1647 {
1648 case COMPONENT_REF:
1649 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1650 obstack_1grow (&name_obstack, '$');
1651 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1652 break;
1653
1654 case ARRAY_REF:
1655 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1656 obstack_1grow (&name_obstack, '$');
1657 /* Arrays with only one element may not have a constant as their
1658 index. */
1659 index = TREE_OPERAND (expr, 1);
1660 if (TREE_CODE (index) != INTEGER_CST)
1661 break;
1662 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1663 obstack_grow (&name_obstack, buffer, strlen (buffer));
1664 break;
1665
1666 case ADDR_EXPR:
1667 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1668 break;
1669
1670 case MEM_REF:
1671 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1672 if (!integer_zerop (TREE_OPERAND (expr, 1)))
1673 {
1674 obstack_1grow (&name_obstack, '$');
1675 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC,
1676 TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)));
1677 obstack_grow (&name_obstack, buffer, strlen (buffer));
1678 }
1679 break;
1680
1681 case BIT_FIELD_REF:
1682 case REALPART_EXPR:
1683 case IMAGPART_EXPR:
1684 gcc_unreachable (); /* we treat these as scalars. */
1685 break;
1686 default:
1687 break;
1688 }
1689 }
1690
1691 /* Create a human readable name for replacement variable of ACCESS. */
1692
1693 static char *
1694 make_fancy_name (tree expr)
1695 {
1696 make_fancy_name_1 (expr);
1697 obstack_1grow (&name_obstack, '\0');
1698 return XOBFINISH (&name_obstack, char *);
1699 }
1700
1701 /* Construct a MEM_REF that would reference a part of aggregate BASE of type
1702 EXP_TYPE at the given OFFSET and with storage order REVERSE. If BASE is
1703 something for which get_addr_base_and_unit_offset returns NULL, gsi must
1704 be non-NULL and is used to insert new statements either before or below
1705 the current one as specified by INSERT_AFTER. This function is not capable
1706 of handling bitfields. */
1707
1708 tree
1709 build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
1710 bool reverse, tree exp_type, gimple_stmt_iterator *gsi,
1711 bool insert_after)
1712 {
1713 tree prev_base = base;
1714 tree off;
1715 tree mem_ref;
1716 poly_int64 base_offset;
1717 unsigned HOST_WIDE_INT misalign;
1718 unsigned int align;
1719
1720 /* Preserve address-space information. */
1721 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (base));
1722 if (as != TYPE_ADDR_SPACE (exp_type))
1723 exp_type = build_qualified_type (exp_type,
1724 TYPE_QUALS (exp_type)
1725 | ENCODE_QUAL_ADDR_SPACE (as));
1726
1727 gcc_checking_assert (offset % BITS_PER_UNIT == 0);
1728 get_object_alignment_1 (base, &align, &misalign);
1729 base = get_addr_base_and_unit_offset (base, &base_offset);
1730
1731 /* get_addr_base_and_unit_offset returns NULL for references with a variable
1732 offset such as array[var_index]. */
1733 if (!base)
1734 {
1735 gassign *stmt;
1736 tree tmp, addr;
1737
1738 gcc_checking_assert (gsi);
1739 tmp = make_ssa_name (build_pointer_type (TREE_TYPE (prev_base)));
1740 addr = build_fold_addr_expr (unshare_expr (prev_base));
1741 STRIP_USELESS_TYPE_CONVERSION (addr);
1742 stmt = gimple_build_assign (tmp, addr);
1743 gimple_set_location (stmt, loc);
1744 if (insert_after)
1745 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
1746 else
1747 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1748
1749 off = build_int_cst (reference_alias_ptr_type (prev_base),
1750 offset / BITS_PER_UNIT);
1751 base = tmp;
1752 }
1753 else if (TREE_CODE (base) == MEM_REF)
1754 {
1755 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1756 base_offset + offset / BITS_PER_UNIT);
1757 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1758 base = unshare_expr (TREE_OPERAND (base, 0));
1759 }
1760 else
1761 {
1762 off = build_int_cst (reference_alias_ptr_type (prev_base),
1763 base_offset + offset / BITS_PER_UNIT);
1764 base = build_fold_addr_expr (unshare_expr (base));
1765 }
1766
1767 misalign = (misalign + offset) & (align - 1);
1768 if (misalign != 0)
1769 align = least_bit_hwi (misalign);
1770 if (align != TYPE_ALIGN (exp_type))
1771 exp_type = build_aligned_type (exp_type, align);
1772
1773 mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off);
1774 REF_REVERSE_STORAGE_ORDER (mem_ref) = reverse;
1775 if (TREE_THIS_VOLATILE (prev_base))
1776 TREE_THIS_VOLATILE (mem_ref) = 1;
1777 if (TREE_SIDE_EFFECTS (prev_base))
1778 TREE_SIDE_EFFECTS (mem_ref) = 1;
1779 return mem_ref;
1780 }
1781
1782 /* Construct a memory reference to a part of an aggregate BASE at the given
1783 OFFSET and of the same type as MODEL. In case this is a reference to a
1784 bit-field, the function will replicate the last component_ref of model's
1785 expr to access it. GSI and INSERT_AFTER have the same meaning as in
1786 build_ref_for_offset. */
1787
1788 static tree
1789 build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1790 struct access *model, gimple_stmt_iterator *gsi,
1791 bool insert_after)
1792 {
1793 if (TREE_CODE (model->expr) == COMPONENT_REF
1794 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1795 {
1796 /* This access represents a bit-field. */
1797 tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
1798
1799 offset -= int_bit_position (fld);
1800 exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
1801 t = build_ref_for_offset (loc, base, offset, model->reverse, exp_type,
1802 gsi, insert_after);
1803 /* The flag will be set on the record type. */
1804 REF_REVERSE_STORAGE_ORDER (t) = 0;
1805 return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
1806 NULL_TREE);
1807 }
1808 else
1809 return
1810 build_ref_for_offset (loc, base, offset, model->reverse, model->type,
1811 gsi, insert_after);
1812 }
1813
1814 /* Attempt to build a memory reference that we could but into a gimple
1815 debug_bind statement. Similar to build_ref_for_model but punts if it has to
1816 create statements and return s NULL instead. This function also ignores
1817 alignment issues and so its results should never end up in non-debug
1818 statements. */
1819
1820 static tree
1821 build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
1822 struct access *model)
1823 {
1824 poly_int64 base_offset;
1825 tree off;
1826
1827 if (TREE_CODE (model->expr) == COMPONENT_REF
1828 && DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
1829 return NULL_TREE;
1830
1831 base = get_addr_base_and_unit_offset (base, &base_offset);
1832 if (!base)
1833 return NULL_TREE;
1834 if (TREE_CODE (base) == MEM_REF)
1835 {
1836 off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
1837 base_offset + offset / BITS_PER_UNIT);
1838 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
1839 base = unshare_expr (TREE_OPERAND (base, 0));
1840 }
1841 else
1842 {
1843 off = build_int_cst (reference_alias_ptr_type (base),
1844 base_offset + offset / BITS_PER_UNIT);
1845 base = build_fold_addr_expr (unshare_expr (base));
1846 }
1847
1848 return fold_build2_loc (loc, MEM_REF, model->type, base, off);
1849 }
1850
1851 /* Construct a memory reference consisting of component_refs and array_refs to
1852 a part of an aggregate *RES (which is of type TYPE). The requested part
1853 should have type EXP_TYPE at be the given OFFSET. This function might not
1854 succeed, it returns true when it does and only then *RES points to something
1855 meaningful. This function should be used only to build expressions that we
1856 might need to present to user (e.g. in warnings). In all other situations,
1857 build_ref_for_model or build_ref_for_offset should be used instead. */
1858
1859 static bool
1860 build_user_friendly_ref_for_offset (tree *res, tree type, HOST_WIDE_INT offset,
1861 tree exp_type)
1862 {
1863 while (1)
1864 {
1865 tree fld;
1866 tree tr_size, index, minidx;
1867 HOST_WIDE_INT el_size;
1868
1869 if (offset == 0 && exp_type
1870 && types_compatible_p (exp_type, type))
1871 return true;
1872
1873 switch (TREE_CODE (type))
1874 {
1875 case UNION_TYPE:
1876 case QUAL_UNION_TYPE:
1877 case RECORD_TYPE:
1878 for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
1879 {
1880 HOST_WIDE_INT pos, size;
1881 tree tr_pos, expr, *expr_ptr;
1882
1883 if (TREE_CODE (fld) != FIELD_DECL)
1884 continue;
1885
1886 tr_pos = bit_position (fld);
1887 if (!tr_pos || !tree_fits_uhwi_p (tr_pos))
1888 continue;
1889 pos = tree_to_uhwi (tr_pos);
1890 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1891 tr_size = DECL_SIZE (fld);
1892 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1893 continue;
1894 size = tree_to_uhwi (tr_size);
1895 if (size == 0)
1896 {
1897 if (pos != offset)
1898 continue;
1899 }
1900 else if (pos > offset || (pos + size) <= offset)
1901 continue;
1902
1903 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1904 NULL_TREE);
1905 expr_ptr = &expr;
1906 if (build_user_friendly_ref_for_offset (expr_ptr, TREE_TYPE (fld),
1907 offset - pos, exp_type))
1908 {
1909 *res = expr;
1910 return true;
1911 }
1912 }
1913 return false;
1914
1915 case ARRAY_TYPE:
1916 tr_size = TYPE_SIZE (TREE_TYPE (type));
1917 if (!tr_size || !tree_fits_uhwi_p (tr_size))
1918 return false;
1919 el_size = tree_to_uhwi (tr_size);
1920
1921 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1922 if (TREE_CODE (minidx) != INTEGER_CST || el_size == 0)
1923 return false;
1924 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1925 if (!integer_zerop (minidx))
1926 index = int_const_binop (PLUS_EXPR, index, minidx);
1927 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1928 NULL_TREE, NULL_TREE);
1929 offset = offset % el_size;
1930 type = TREE_TYPE (type);
1931 break;
1932
1933 default:
1934 if (offset != 0)
1935 return false;
1936
1937 if (exp_type)
1938 return false;
1939 else
1940 return true;
1941 }
1942 }
1943 }
1944
1945 /* Return true iff TYPE is stdarg va_list type. */
1946
1947 static inline bool
1948 is_va_list_type (tree type)
1949 {
1950 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1951 }
1952
1953 /* Print message to dump file why a variable was rejected. */
1954
1955 static void
1956 reject (tree var, const char *msg)
1957 {
1958 if (dump_file && (dump_flags & TDF_DETAILS))
1959 {
1960 fprintf (dump_file, "Rejected (%d): %s: ", DECL_UID (var), msg);
1961 print_generic_expr (dump_file, var);
1962 fprintf (dump_file, "\n");
1963 }
1964 }
1965
1966 /* Return true if VAR is a candidate for SRA. */
1967
1968 static bool
1969 maybe_add_sra_candidate (tree var)
1970 {
1971 tree type = TREE_TYPE (var);
1972 const char *msg;
1973 tree_node **slot;
1974
1975 if (!AGGREGATE_TYPE_P (type))
1976 {
1977 reject (var, "not aggregate");
1978 return false;
1979 }
1980 /* Allow constant-pool entries (that "need to live in memory")
1981 unless we are doing IPA SRA. */
1982 if (needs_to_live_in_memory (var)
1983 && (sra_mode == SRA_MODE_EARLY_IPA || !constant_decl_p (var)))
1984 {
1985 reject (var, "needs to live in memory");
1986 return false;
1987 }
1988 if (TREE_THIS_VOLATILE (var))
1989 {
1990 reject (var, "is volatile");
1991 return false;
1992 }
1993 if (!COMPLETE_TYPE_P (type))
1994 {
1995 reject (var, "has incomplete type");
1996 return false;
1997 }
1998 if (!tree_fits_uhwi_p (TYPE_SIZE (type)))
1999 {
2000 reject (var, "type size not fixed");
2001 return false;
2002 }
2003 if (tree_to_uhwi (TYPE_SIZE (type)) == 0)
2004 {
2005 reject (var, "type size is zero");
2006 return false;
2007 }
2008 if (type_internals_preclude_sra_p (type, &msg))
2009 {
2010 reject (var, msg);
2011 return false;
2012 }
2013 if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
2014 we also want to schedule it rather late. Thus we ignore it in
2015 the early pass. */
2016 (sra_mode == SRA_MODE_EARLY_INTRA
2017 && is_va_list_type (type)))
2018 {
2019 reject (var, "is va_list");
2020 return false;
2021 }
2022
2023 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
2024 slot = candidates->find_slot_with_hash (var, DECL_UID (var), INSERT);
2025 *slot = var;
2026
2027 if (dump_file && (dump_flags & TDF_DETAILS))
2028 {
2029 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
2030 print_generic_expr (dump_file, var);
2031 fprintf (dump_file, "\n");
2032 }
2033
2034 return true;
2035 }
2036
2037 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
2038 those with type which is suitable for scalarization. */
2039
2040 static bool
2041 find_var_candidates (void)
2042 {
2043 tree var, parm;
2044 unsigned int i;
2045 bool ret = false;
2046
2047 for (parm = DECL_ARGUMENTS (current_function_decl);
2048 parm;
2049 parm = DECL_CHAIN (parm))
2050 ret |= maybe_add_sra_candidate (parm);
2051
2052 FOR_EACH_LOCAL_DECL (cfun, i, var)
2053 {
2054 if (!VAR_P (var))
2055 continue;
2056
2057 ret |= maybe_add_sra_candidate (var);
2058 }
2059
2060 return ret;
2061 }
2062
2063 /* Sort all accesses for the given variable, check for partial overlaps and
2064 return NULL if there are any. If there are none, pick a representative for
2065 each combination of offset and size and create a linked list out of them.
2066 Return the pointer to the first representative and make sure it is the first
2067 one in the vector of accesses. */
2068
2069 static struct access *
2070 sort_and_splice_var_accesses (tree var)
2071 {
2072 int i, j, access_count;
2073 struct access *res, **prev_acc_ptr = &res;
2074 vec<access_p> *access_vec;
2075 bool first = true;
2076 HOST_WIDE_INT low = -1, high = 0;
2077
2078 access_vec = get_base_access_vector (var);
2079 if (!access_vec)
2080 return NULL;
2081 access_count = access_vec->length ();
2082
2083 /* Sort by <OFFSET, SIZE>. */
2084 access_vec->qsort (compare_access_positions);
2085
2086 i = 0;
2087 while (i < access_count)
2088 {
2089 struct access *access = (*access_vec)[i];
2090 bool grp_write = access->write;
2091 bool grp_read = !access->write;
2092 bool grp_scalar_write = access->write
2093 && is_gimple_reg_type (access->type);
2094 bool grp_scalar_read = !access->write
2095 && is_gimple_reg_type (access->type);
2096 bool grp_assignment_read = access->grp_assignment_read;
2097 bool grp_assignment_write = access->grp_assignment_write;
2098 bool multiple_scalar_reads = false;
2099 bool total_scalarization = access->grp_total_scalarization;
2100 bool grp_partial_lhs = access->grp_partial_lhs;
2101 bool first_scalar = is_gimple_reg_type (access->type);
2102 bool unscalarizable_region = access->grp_unscalarizable_region;
2103 bool bf_non_full_precision
2104 = (INTEGRAL_TYPE_P (access->type)
2105 && TYPE_PRECISION (access->type) != access->size
2106 && TREE_CODE (access->expr) == COMPONENT_REF
2107 && DECL_BIT_FIELD (TREE_OPERAND (access->expr, 1)));
2108
2109 if (first || access->offset >= high)
2110 {
2111 first = false;
2112 low = access->offset;
2113 high = access->offset + access->size;
2114 }
2115 else if (access->offset > low && access->offset + access->size > high)
2116 return NULL;
2117 else
2118 gcc_assert (access->offset >= low
2119 && access->offset + access->size <= high);
2120
2121 j = i + 1;
2122 while (j < access_count)
2123 {
2124 struct access *ac2 = (*access_vec)[j];
2125 if (ac2->offset != access->offset || ac2->size != access->size)
2126 break;
2127 if (ac2->write)
2128 {
2129 grp_write = true;
2130 grp_scalar_write = (grp_scalar_write
2131 || is_gimple_reg_type (ac2->type));
2132 }
2133 else
2134 {
2135 grp_read = true;
2136 if (is_gimple_reg_type (ac2->type))
2137 {
2138 if (grp_scalar_read)
2139 multiple_scalar_reads = true;
2140 else
2141 grp_scalar_read = true;
2142 }
2143 }
2144 grp_assignment_read |= ac2->grp_assignment_read;
2145 grp_assignment_write |= ac2->grp_assignment_write;
2146 grp_partial_lhs |= ac2->grp_partial_lhs;
2147 unscalarizable_region |= ac2->grp_unscalarizable_region;
2148 total_scalarization |= ac2->grp_total_scalarization;
2149 relink_to_new_repr (access, ac2);
2150
2151 /* If there are both aggregate-type and scalar-type accesses with
2152 this combination of size and offset, the comparison function
2153 should have put the scalars first. */
2154 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
2155 /* It also prefers integral types to non-integral. However, when the
2156 precision of the selected type does not span the entire area and
2157 should also be used for a non-integer (i.e. float), we must not
2158 let that happen. Normally analyze_access_subtree expands the type
2159 to cover the entire area but for bit-fields it doesn't. */
2160 if (bf_non_full_precision && !INTEGRAL_TYPE_P (ac2->type))
2161 {
2162 if (dump_file && (dump_flags & TDF_DETAILS))
2163 {
2164 fprintf (dump_file, "Cannot scalarize the following access "
2165 "because insufficient precision integer type was "
2166 "selected.\n ");
2167 dump_access (dump_file, access, false);
2168 }
2169 unscalarizable_region = true;
2170 }
2171 ac2->group_representative = access;
2172 j++;
2173 }
2174
2175 i = j;
2176
2177 access->group_representative = access;
2178 access->grp_write = grp_write;
2179 access->grp_read = grp_read;
2180 access->grp_scalar_read = grp_scalar_read;
2181 access->grp_scalar_write = grp_scalar_write;
2182 access->grp_assignment_read = grp_assignment_read;
2183 access->grp_assignment_write = grp_assignment_write;
2184 access->grp_hint = total_scalarization
2185 || (multiple_scalar_reads && !constant_decl_p (var));
2186 access->grp_total_scalarization = total_scalarization;
2187 access->grp_partial_lhs = grp_partial_lhs;
2188 access->grp_unscalarizable_region = unscalarizable_region;
2189
2190 *prev_acc_ptr = access;
2191 prev_acc_ptr = &access->next_grp;
2192 }
2193
2194 gcc_assert (res == (*access_vec)[0]);
2195 return res;
2196 }
2197
2198 /* Create a variable for the given ACCESS which determines the type, name and a
2199 few other properties. Return the variable declaration and store it also to
2200 ACCESS->replacement. */
2201
2202 static tree
2203 create_access_replacement (struct access *access)
2204 {
2205 tree repl;
2206
2207 if (access->grp_to_be_debug_replaced)
2208 {
2209 repl = create_tmp_var_raw (access->type);
2210 DECL_CONTEXT (repl) = current_function_decl;
2211 }
2212 else
2213 /* Drop any special alignment on the type if it's not on the main
2214 variant. This avoids issues with weirdo ABIs like AAPCS. */
2215 repl = create_tmp_var (build_qualified_type
2216 (TYPE_MAIN_VARIANT (access->type),
2217 TYPE_QUALS (access->type)), "SR");
2218 if (TREE_CODE (access->type) == COMPLEX_TYPE
2219 || TREE_CODE (access->type) == VECTOR_TYPE)
2220 {
2221 if (!access->grp_partial_lhs)
2222 DECL_GIMPLE_REG_P (repl) = 1;
2223 }
2224 else if (access->grp_partial_lhs
2225 && is_gimple_reg_type (access->type))
2226 TREE_ADDRESSABLE (repl) = 1;
2227
2228 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
2229 DECL_ARTIFICIAL (repl) = 1;
2230 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
2231
2232 if (DECL_NAME (access->base)
2233 && !DECL_IGNORED_P (access->base)
2234 && !DECL_ARTIFICIAL (access->base))
2235 {
2236 char *pretty_name = make_fancy_name (access->expr);
2237 tree debug_expr = unshare_expr_without_location (access->expr), d;
2238 bool fail = false;
2239
2240 DECL_NAME (repl) = get_identifier (pretty_name);
2241 DECL_NAMELESS (repl) = 1;
2242 obstack_free (&name_obstack, pretty_name);
2243
2244 /* Get rid of any SSA_NAMEs embedded in debug_expr,
2245 as DECL_DEBUG_EXPR isn't considered when looking for still
2246 used SSA_NAMEs and thus they could be freed. All debug info
2247 generation cares is whether something is constant or variable
2248 and that get_ref_base_and_extent works properly on the
2249 expression. It cannot handle accesses at a non-constant offset
2250 though, so just give up in those cases. */
2251 for (d = debug_expr;
2252 !fail && (handled_component_p (d) || TREE_CODE (d) == MEM_REF);
2253 d = TREE_OPERAND (d, 0))
2254 switch (TREE_CODE (d))
2255 {
2256 case ARRAY_REF:
2257 case ARRAY_RANGE_REF:
2258 if (TREE_OPERAND (d, 1)
2259 && TREE_CODE (TREE_OPERAND (d, 1)) != INTEGER_CST)
2260 fail = true;
2261 if (TREE_OPERAND (d, 3)
2262 && TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST)
2263 fail = true;
2264 /* FALLTHRU */
2265 case COMPONENT_REF:
2266 if (TREE_OPERAND (d, 2)
2267 && TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST)
2268 fail = true;
2269 break;
2270 case MEM_REF:
2271 if (TREE_CODE (TREE_OPERAND (d, 0)) != ADDR_EXPR)
2272 fail = true;
2273 else
2274 d = TREE_OPERAND (d, 0);
2275 break;
2276 default:
2277 break;
2278 }
2279 if (!fail)
2280 {
2281 SET_DECL_DEBUG_EXPR (repl, debug_expr);
2282 DECL_HAS_DEBUG_EXPR_P (repl) = 1;
2283 }
2284 if (access->grp_no_warning)
2285 TREE_NO_WARNING (repl) = 1;
2286 else
2287 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
2288 }
2289 else
2290 TREE_NO_WARNING (repl) = 1;
2291
2292 if (dump_file)
2293 {
2294 if (access->grp_to_be_debug_replaced)
2295 {
2296 fprintf (dump_file, "Created a debug-only replacement for ");
2297 print_generic_expr (dump_file, access->base);
2298 fprintf (dump_file, " offset: %u, size: %u\n",
2299 (unsigned) access->offset, (unsigned) access->size);
2300 }
2301 else
2302 {
2303 fprintf (dump_file, "Created a replacement for ");
2304 print_generic_expr (dump_file, access->base);
2305 fprintf (dump_file, " offset: %u, size: %u: ",
2306 (unsigned) access->offset, (unsigned) access->size);
2307 print_generic_expr (dump_file, repl);
2308 fprintf (dump_file, "\n");
2309 }
2310 }
2311 sra_stats.replacements++;
2312
2313 return repl;
2314 }
2315
2316 /* Return ACCESS scalar replacement, which must exist. */
2317
2318 static inline tree
2319 get_access_replacement (struct access *access)
2320 {
2321 gcc_checking_assert (access->replacement_decl);
2322 return access->replacement_decl;
2323 }
2324
2325
2326 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
2327 linked list along the way. Stop when *ACCESS is NULL or the access pointed
2328 to it is not "within" the root. Return false iff some accesses partially
2329 overlap. */
2330
2331 static bool
2332 build_access_subtree (struct access **access)
2333 {
2334 struct access *root = *access, *last_child = NULL;
2335 HOST_WIDE_INT limit = root->offset + root->size;
2336
2337 *access = (*access)->next_grp;
2338 while (*access && (*access)->offset + (*access)->size <= limit)
2339 {
2340 if (!last_child)
2341 root->first_child = *access;
2342 else
2343 last_child->next_sibling = *access;
2344 last_child = *access;
2345 (*access)->parent = root;
2346 (*access)->grp_write |= root->grp_write;
2347
2348 if (!build_access_subtree (access))
2349 return false;
2350 }
2351
2352 if (*access && (*access)->offset < limit)
2353 return false;
2354
2355 return true;
2356 }
2357
2358 /* Build a tree of access representatives, ACCESS is the pointer to the first
2359 one, others are linked in a list by the next_grp field. Return false iff
2360 some accesses partially overlap. */
2361
2362 static bool
2363 build_access_trees (struct access *access)
2364 {
2365 while (access)
2366 {
2367 struct access *root = access;
2368
2369 if (!build_access_subtree (&access))
2370 return false;
2371 root->next_grp = access;
2372 }
2373 return true;
2374 }
2375
2376 /* Return true if expr contains some ARRAY_REFs into a variable bounded
2377 array. */
2378
2379 static bool
2380 expr_with_var_bounded_array_refs_p (tree expr)
2381 {
2382 while (handled_component_p (expr))
2383 {
2384 if (TREE_CODE (expr) == ARRAY_REF
2385 && !tree_fits_shwi_p (array_ref_low_bound (expr)))
2386 return true;
2387 expr = TREE_OPERAND (expr, 0);
2388 }
2389 return false;
2390 }
2391
2392 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
2393 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all
2394 sorts of access flags appropriately along the way, notably always set
2395 grp_read and grp_assign_read according to MARK_READ and grp_write when
2396 MARK_WRITE is true.
2397
2398 Creating a replacement for a scalar access is considered beneficial if its
2399 grp_hint is set (this means we are either attempting total scalarization or
2400 there is more than one direct read access) or according to the following
2401 table:
2402
2403 Access written to through a scalar type (once or more times)
2404 |
2405 | Written to in an assignment statement
2406 | |
2407 | | Access read as scalar _once_
2408 | | |
2409 | | | Read in an assignment statement
2410 | | | |
2411 | | | | Scalarize Comment
2412 -----------------------------------------------------------------------------
2413 0 0 0 0 No access for the scalar
2414 0 0 0 1 No access for the scalar
2415 0 0 1 0 No Single read - won't help
2416 0 0 1 1 No The same case
2417 0 1 0 0 No access for the scalar
2418 0 1 0 1 No access for the scalar
2419 0 1 1 0 Yes s = *g; return s.i;
2420 0 1 1 1 Yes The same case as above
2421 1 0 0 0 No Won't help
2422 1 0 0 1 Yes s.i = 1; *g = s;
2423 1 0 1 0 Yes s.i = 5; g = s.i;
2424 1 0 1 1 Yes The same case as above
2425 1 1 0 0 No Won't help.
2426 1 1 0 1 Yes s.i = 1; *g = s;
2427 1 1 1 0 Yes s = *g; return s.i;
2428 1 1 1 1 Yes Any of the above yeses */
2429
2430 static bool
2431 analyze_access_subtree (struct access *root, struct access *parent,
2432 bool allow_replacements)
2433 {
2434 struct access *child;
2435 HOST_WIDE_INT limit = root->offset + root->size;
2436 HOST_WIDE_INT covered_to = root->offset;
2437 bool scalar = is_gimple_reg_type (root->type);
2438 bool hole = false, sth_created = false;
2439
2440 if (parent)
2441 {
2442 if (parent->grp_read)
2443 root->grp_read = 1;
2444 if (parent->grp_assignment_read)
2445 root->grp_assignment_read = 1;
2446 if (parent->grp_write)
2447 root->grp_write = 1;
2448 if (parent->grp_assignment_write)
2449 root->grp_assignment_write = 1;
2450 if (parent->grp_total_scalarization)
2451 root->grp_total_scalarization = 1;
2452 }
2453
2454 if (root->grp_unscalarizable_region)
2455 allow_replacements = false;
2456
2457 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
2458 allow_replacements = false;
2459
2460 for (child = root->first_child; child; child = child->next_sibling)
2461 {
2462 hole |= covered_to < child->offset;
2463 sth_created |= analyze_access_subtree (child, root,
2464 allow_replacements && !scalar);
2465
2466 root->grp_unscalarized_data |= child->grp_unscalarized_data;
2467 root->grp_total_scalarization &= child->grp_total_scalarization;
2468 if (child->grp_covered)
2469 covered_to += child->size;
2470 else
2471 hole = true;
2472 }
2473
2474 if (allow_replacements && scalar && !root->first_child
2475 && (root->grp_hint
2476 || ((root->grp_scalar_read || root->grp_assignment_read)
2477 && (root->grp_scalar_write || root->grp_assignment_write))))
2478 {
2479 /* Always create access replacements that cover the whole access.
2480 For integral types this means the precision has to match.
2481 Avoid assumptions based on the integral type kind, too. */
2482 if (INTEGRAL_TYPE_P (root->type)
2483 && (TREE_CODE (root->type) != INTEGER_TYPE
2484 || TYPE_PRECISION (root->type) != root->size)
2485 /* But leave bitfield accesses alone. */
2486 && (TREE_CODE (root->expr) != COMPONENT_REF
2487 || !DECL_BIT_FIELD (TREE_OPERAND (root->expr, 1))))
2488 {
2489 tree rt = root->type;
2490 gcc_assert ((root->offset % BITS_PER_UNIT) == 0
2491 && (root->size % BITS_PER_UNIT) == 0);
2492 root->type = build_nonstandard_integer_type (root->size,
2493 TYPE_UNSIGNED (rt));
2494 root->expr = build_ref_for_offset (UNKNOWN_LOCATION, root->base,
2495 root->offset, root->reverse,
2496 root->type, NULL, false);
2497
2498 if (dump_file && (dump_flags & TDF_DETAILS))
2499 {
2500 fprintf (dump_file, "Changing the type of a replacement for ");
2501 print_generic_expr (dump_file, root->base);
2502 fprintf (dump_file, " offset: %u, size: %u ",
2503 (unsigned) root->offset, (unsigned) root->size);
2504 fprintf (dump_file, " to an integer.\n");
2505 }
2506 }
2507
2508 root->grp_to_be_replaced = 1;
2509 root->replacement_decl = create_access_replacement (root);
2510 sth_created = true;
2511 hole = false;
2512 }
2513 else
2514 {
2515 if (allow_replacements
2516 && scalar && !root->first_child
2517 && (root->grp_scalar_write || root->grp_assignment_write)
2518 && !bitmap_bit_p (cannot_scalarize_away_bitmap,
2519 DECL_UID (root->base)))
2520 {
2521 gcc_checking_assert (!root->grp_scalar_read
2522 && !root->grp_assignment_read);
2523 sth_created = true;
2524 if (MAY_HAVE_DEBUG_BIND_STMTS)
2525 {
2526 root->grp_to_be_debug_replaced = 1;
2527 root->replacement_decl = create_access_replacement (root);
2528 }
2529 }
2530
2531 if (covered_to < limit)
2532 hole = true;
2533 if (scalar || !allow_replacements)
2534 root->grp_total_scalarization = 0;
2535 }
2536
2537 if (!hole || root->grp_total_scalarization)
2538 root->grp_covered = 1;
2539 else if (root->grp_write || comes_initialized_p (root->base))
2540 root->grp_unscalarized_data = 1; /* not covered and written to */
2541 return sth_created;
2542 }
2543
2544 /* Analyze all access trees linked by next_grp by the means of
2545 analyze_access_subtree. */
2546 static bool
2547 analyze_access_trees (struct access *access)
2548 {
2549 bool ret = false;
2550
2551 while (access)
2552 {
2553 if (analyze_access_subtree (access, NULL, true))
2554 ret = true;
2555 access = access->next_grp;
2556 }
2557
2558 return ret;
2559 }
2560
2561 /* Return true iff a potential new child of LACC at offset OFFSET and with size
2562 SIZE would conflict with an already existing one. If exactly such a child
2563 already exists in LACC, store a pointer to it in EXACT_MATCH. */
2564
2565 static bool
2566 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
2567 HOST_WIDE_INT size, struct access **exact_match)
2568 {
2569 struct access *child;
2570
2571 for (child = lacc->first_child; child; child = child->next_sibling)
2572 {
2573 if (child->offset == norm_offset && child->size == size)
2574 {
2575 *exact_match = child;
2576 return true;
2577 }
2578
2579 if (child->offset < norm_offset + size
2580 && child->offset + child->size > norm_offset)
2581 return true;
2582 }
2583
2584 return false;
2585 }
2586
2587 /* Create a new child access of PARENT, with all properties just like MODEL
2588 except for its offset and with its grp_write false and grp_read true.
2589 Return the new access or NULL if it cannot be created. Note that this
2590 access is created long after all splicing and sorting, it's not located in
2591 any access vector and is automatically a representative of its group. Set
2592 the gpr_write flag of the new accesss if SET_GRP_WRITE is true. */
2593
2594 static struct access *
2595 create_artificial_child_access (struct access *parent, struct access *model,
2596 HOST_WIDE_INT new_offset,
2597 bool set_grp_write)
2598 {
2599 struct access **child;
2600 tree expr = parent->base;
2601
2602 gcc_assert (!model->grp_unscalarizable_region);
2603
2604 struct access *access = access_pool.allocate ();
2605 memset (access, 0, sizeof (struct access));
2606 if (!build_user_friendly_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
2607 model->type))
2608 {
2609 access->grp_no_warning = true;
2610 expr = build_ref_for_model (EXPR_LOCATION (parent->base), parent->base,
2611 new_offset, model, NULL, false);
2612 }
2613
2614 access->base = parent->base;
2615 access->expr = expr;
2616 access->offset = new_offset;
2617 access->size = model->size;
2618 access->type = model->type;
2619 access->grp_write = set_grp_write;
2620 access->grp_read = false;
2621 access->reverse = model->reverse;
2622
2623 child = &parent->first_child;
2624 while (*child && (*child)->offset < new_offset)
2625 child = &(*child)->next_sibling;
2626
2627 access->next_sibling = *child;
2628 *child = access;
2629
2630 return access;
2631 }
2632
2633
2634 /* Beginning with ACCESS, traverse its whole access subtree and mark all
2635 sub-trees as written to. If any of them has not been marked so previously
2636 and has assignment links leading from it, re-enqueue it. */
2637
2638 static void
2639 subtree_mark_written_and_enqueue (struct access *access)
2640 {
2641 if (access->grp_write)
2642 return;
2643 access->grp_write = true;
2644 add_access_to_work_queue (access);
2645
2646 struct access *child;
2647 for (child = access->first_child; child; child = child->next_sibling)
2648 subtree_mark_written_and_enqueue (child);
2649 }
2650
2651 /* Propagate subaccesses and grp_write flags of RACC across an assignment link
2652 to LACC. Enqueue sub-accesses as necessary so that the write flag is
2653 propagated transitively. Return true if anything changed. Additionally, if
2654 RACC is a scalar access but LACC is not, change the type of the latter, if
2655 possible. */
2656
2657 static bool
2658 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
2659 {
2660 struct access *rchild;
2661 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
2662 bool ret = false;
2663
2664 /* IF the LHS is still not marked as being written to, we only need to do so
2665 if the RHS at this level actually was. */
2666 if (!lacc->grp_write)
2667 {
2668 gcc_checking_assert (!comes_initialized_p (racc->base));
2669 if (racc->grp_write)
2670 {
2671 subtree_mark_written_and_enqueue (lacc);
2672 ret = true;
2673 }
2674 }
2675
2676 if (is_gimple_reg_type (lacc->type)
2677 || lacc->grp_unscalarizable_region
2678 || racc->grp_unscalarizable_region)
2679 {
2680 if (!lacc->grp_write)
2681 {
2682 ret = true;
2683 subtree_mark_written_and_enqueue (lacc);
2684 }
2685 return ret;
2686 }
2687
2688 if (is_gimple_reg_type (racc->type))
2689 {
2690 if (!lacc->grp_write)
2691 {
2692 ret = true;
2693 subtree_mark_written_and_enqueue (lacc);
2694 }
2695 if (!lacc->first_child && !racc->first_child)
2696 {
2697 tree t = lacc->base;
2698
2699 lacc->type = racc->type;
2700 if (build_user_friendly_ref_for_offset (&t, TREE_TYPE (t),
2701 lacc->offset, racc->type))
2702 lacc->expr = t;
2703 else
2704 {
2705 lacc->expr = build_ref_for_model (EXPR_LOCATION (lacc->base),
2706 lacc->base, lacc->offset,
2707 racc, NULL, false);
2708 lacc->grp_no_warning = true;
2709 }
2710 }
2711 return ret;
2712 }
2713
2714 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
2715 {
2716 struct access *new_acc = NULL;
2717 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
2718
2719 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
2720 &new_acc))
2721 {
2722 if (new_acc)
2723 {
2724 if (!new_acc->grp_write && rchild->grp_write)
2725 {
2726 gcc_assert (!lacc->grp_write);
2727 subtree_mark_written_and_enqueue (new_acc);
2728 ret = true;
2729 }
2730
2731 rchild->grp_hint = 1;
2732 new_acc->grp_hint |= new_acc->grp_read;
2733 if (rchild->first_child)
2734 ret |= propagate_subaccesses_across_link (new_acc, rchild);
2735 }
2736 else
2737 {
2738 if (!lacc->grp_write)
2739 {
2740 ret = true;
2741 subtree_mark_written_and_enqueue (lacc);
2742 }
2743 }
2744 continue;
2745 }
2746
2747 if (rchild->grp_unscalarizable_region)
2748 {
2749 if (rchild->grp_write && !lacc->grp_write)
2750 {
2751 ret = true;
2752 subtree_mark_written_and_enqueue (lacc);
2753 }
2754 continue;
2755 }
2756
2757 rchild->grp_hint = 1;
2758 new_acc = create_artificial_child_access (lacc, rchild, norm_offset,
2759 lacc->grp_write
2760 || rchild->grp_write);
2761 gcc_checking_assert (new_acc);
2762 if (racc->first_child)
2763 propagate_subaccesses_across_link (new_acc, rchild);
2764
2765 add_access_to_work_queue (lacc);
2766 ret = true;
2767 }
2768
2769 return ret;
2770 }
2771
2772 /* Propagate all subaccesses across assignment links. */
2773
2774 static void
2775 propagate_all_subaccesses (void)
2776 {
2777 while (work_queue_head)
2778 {
2779 struct access *racc = pop_access_from_work_queue ();
2780 struct assign_link *link;
2781
2782 if (racc->group_representative)
2783 racc= racc->group_representative;
2784 gcc_assert (racc->first_link);
2785
2786 for (link = racc->first_link; link; link = link->next)
2787 {
2788 struct access *lacc = link->lacc;
2789
2790 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
2791 continue;
2792 lacc = lacc->group_representative;
2793
2794 bool reque_parents = false;
2795 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (racc->base)))
2796 {
2797 if (!lacc->grp_write)
2798 {
2799 subtree_mark_written_and_enqueue (lacc);
2800 reque_parents = true;
2801 }
2802 }
2803 else if (propagate_subaccesses_across_link (lacc, racc))
2804 reque_parents = true;
2805
2806 if (reque_parents)
2807 do
2808 {
2809 add_access_to_work_queue (lacc);
2810 lacc = lacc->parent;
2811 }
2812 while (lacc);
2813 }
2814 }
2815 }
2816
2817 /* Go through all accesses collected throughout the (intraprocedural) analysis
2818 stage, exclude overlapping ones, identify representatives and build trees
2819 out of them, making decisions about scalarization on the way. Return true
2820 iff there are any to-be-scalarized variables after this stage. */
2821
2822 static bool
2823 analyze_all_variable_accesses (void)
2824 {
2825 int res = 0;
2826 bitmap tmp = BITMAP_ALLOC (NULL);
2827 bitmap_iterator bi;
2828 unsigned i;
2829 bool optimize_speed_p = !optimize_function_for_size_p (cfun);
2830
2831 enum compiler_param param = optimize_speed_p
2832 ? PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED
2833 : PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE;
2834
2835 /* If the user didn't set PARAM_SRA_MAX_SCALARIZATION_SIZE_<...>,
2836 fall back to a target default. */
2837 unsigned HOST_WIDE_INT max_scalarization_size
2838 = global_options_set.x_param_values[param]
2839 ? PARAM_VALUE (param)
2840 : get_move_ratio (optimize_speed_p) * UNITS_PER_WORD;
2841
2842 max_scalarization_size *= BITS_PER_UNIT;
2843
2844 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
2845 if (bitmap_bit_p (should_scalarize_away_bitmap, i)
2846 && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
2847 {
2848 tree var = candidate (i);
2849
2850 if (VAR_P (var) && scalarizable_type_p (TREE_TYPE (var),
2851 constant_decl_p (var)))
2852 {
2853 if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var)))
2854 <= max_scalarization_size)
2855 {
2856 create_total_scalarization_access (var);
2857 completely_scalarize (var, TREE_TYPE (var), 0, var);
2858 statistics_counter_event (cfun,
2859 "Totally-scalarized aggregates", 1);
2860 if (dump_file && (dump_flags & TDF_DETAILS))
2861 {
2862 fprintf (dump_file, "Will attempt to totally scalarize ");
2863 print_generic_expr (dump_file, var);
2864 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2865 }
2866 }
2867 else if (dump_file && (dump_flags & TDF_DETAILS))
2868 {
2869 fprintf (dump_file, "Too big to totally scalarize: ");
2870 print_generic_expr (dump_file, var);
2871 fprintf (dump_file, " (UID: %u)\n", DECL_UID (var));
2872 }
2873 }
2874 }
2875
2876 bitmap_copy (tmp, candidate_bitmap);
2877 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2878 {
2879 tree var = candidate (i);
2880 struct access *access;
2881
2882 access = sort_and_splice_var_accesses (var);
2883 if (!access || !build_access_trees (access))
2884 disqualify_candidate (var,
2885 "No or inhibitingly overlapping accesses.");
2886 }
2887
2888 propagate_all_subaccesses ();
2889
2890 bitmap_copy (tmp, candidate_bitmap);
2891 EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
2892 {
2893 tree var = candidate (i);
2894 struct access *access = get_first_repr_for_decl (var);
2895
2896 if (analyze_access_trees (access))
2897 {
2898 res++;
2899 if (dump_file && (dump_flags & TDF_DETAILS))
2900 {
2901 fprintf (dump_file, "\nAccess trees for ");
2902 print_generic_expr (dump_file, var);
2903 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
2904 dump_access_tree (dump_file, access);
2905 fprintf (dump_file, "\n");
2906 }
2907 }
2908 else
2909 disqualify_candidate (var, "No scalar replacements to be created.");
2910 }
2911
2912 BITMAP_FREE (tmp);
2913
2914 if (res)
2915 {
2916 statistics_counter_event (cfun, "Scalarized aggregates", res);
2917 return true;
2918 }
2919 else
2920 return false;
2921 }
2922
2923 /* Generate statements copying scalar replacements of accesses within a subtree
2924 into or out of AGG. ACCESS, all its children, siblings and their children
2925 are to be processed. AGG is an aggregate type expression (can be a
2926 declaration but does not have to be, it can for example also be a mem_ref or
2927 a series of handled components). TOP_OFFSET is the offset of the processed
2928 subtree which has to be subtracted from offsets of individual accesses to
2929 get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only
2930 replacements in the interval <start_offset, start_offset + chunk_size>,
2931 otherwise copy all. GSI is a statement iterator used to place the new
2932 statements. WRITE should be true when the statements should write from AGG
2933 to the replacement and false if vice versa. if INSERT_AFTER is true, new
2934 statements will be added after the current statement in GSI, they will be
2935 added before the statement otherwise. */
2936
2937 static void
2938 generate_subtree_copies (struct access *access, tree agg,
2939 HOST_WIDE_INT top_offset,
2940 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
2941 gimple_stmt_iterator *gsi, bool write,
2942 bool insert_after, location_t loc)
2943 {
2944 /* Never write anything into constant pool decls. See PR70602. */
2945 if (!write && constant_decl_p (agg))
2946 return;
2947 do
2948 {
2949 if (chunk_size && access->offset >= start_offset + chunk_size)
2950 return;
2951
2952 if (access->grp_to_be_replaced
2953 && (chunk_size == 0
2954 || access->offset + access->size > start_offset))
2955 {
2956 tree expr, repl = get_access_replacement (access);
2957 gassign *stmt;
2958
2959 expr = build_ref_for_model (loc, agg, access->offset - top_offset,
2960 access, gsi, insert_after);
2961
2962 if (write)
2963 {
2964 if (access->grp_partial_lhs)
2965 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
2966 !insert_after,
2967 insert_after ? GSI_NEW_STMT
2968 : GSI_SAME_STMT);
2969 stmt = gimple_build_assign (repl, expr);
2970 }
2971 else
2972 {
2973 TREE_NO_WARNING (repl) = 1;
2974 if (access->grp_partial_lhs)
2975 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2976 !insert_after,
2977 insert_after ? GSI_NEW_STMT
2978 : GSI_SAME_STMT);
2979 stmt = gimple_build_assign (expr, repl);
2980 }
2981 gimple_set_location (stmt, loc);
2982
2983 if (insert_after)
2984 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2985 else
2986 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2987 update_stmt (stmt);
2988 sra_stats.subtree_copies++;
2989 }
2990 else if (write
2991 && access->grp_to_be_debug_replaced
2992 && (chunk_size == 0
2993 || access->offset + access->size > start_offset))
2994 {
2995 gdebug *ds;
2996 tree drhs = build_debug_ref_for_model (loc, agg,
2997 access->offset - top_offset,
2998 access);
2999 ds = gimple_build_debug_bind (get_access_replacement (access),
3000 drhs, gsi_stmt (*gsi));
3001 if (insert_after)
3002 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
3003 else
3004 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3005 }
3006
3007 if (access->first_child)
3008 generate_subtree_copies (access->first_child, agg, top_offset,
3009 start_offset, chunk_size, gsi,
3010 write, insert_after, loc);
3011
3012 access = access->next_sibling;
3013 }
3014 while (access);
3015 }
3016
3017 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
3018 root of the subtree to be processed. GSI is the statement iterator used
3019 for inserting statements which are added after the current statement if
3020 INSERT_AFTER is true or before it otherwise. */
3021
3022 static void
3023 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
3024 bool insert_after, location_t loc)
3025
3026 {
3027 struct access *child;
3028
3029 if (access->grp_to_be_replaced)
3030 {
3031 gassign *stmt;
3032
3033 stmt = gimple_build_assign (get_access_replacement (access),
3034 build_zero_cst (access->type));
3035 if (insert_after)
3036 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
3037 else
3038 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
3039 update_stmt (stmt);
3040 gimple_set_location (stmt, loc);
3041 }
3042 else if (access->grp_to_be_debug_replaced)
3043 {
3044 gdebug *ds
3045 = gimple_build_debug_bind (get_access_replacement (access),
3046 build_zero_cst (access->type),
3047 gsi_stmt (*gsi));
3048 if (insert_after)
3049 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
3050 else
3051 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3052 }
3053
3054 for (child = access->first_child; child; child = child->next_sibling)
3055 init_subtree_with_zero (child, gsi, insert_after, loc);
3056 }
3057
3058 /* Clobber all scalar replacements in an access subtree. ACCESS is the
3059 root of the subtree to be processed. GSI is the statement iterator used
3060 for inserting statements which are added after the current statement if
3061 INSERT_AFTER is true or before it otherwise. */
3062
3063 static void
3064 clobber_subtree (struct access *access, gimple_stmt_iterator *gsi,
3065 bool insert_after, location_t loc)
3066
3067 {
3068 struct access *child;
3069
3070 if (access->grp_to_be_replaced)
3071 {
3072 tree rep = get_access_replacement (access);
3073 tree clobber = build_constructor (access->type, NULL);
3074 TREE_THIS_VOLATILE (clobber) = 1;
3075 gimple *stmt = gimple_build_assign (rep, clobber);
3076
3077 if (insert_after)
3078 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
3079 else
3080 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
3081 update_stmt (stmt);
3082 gimple_set_location (stmt, loc);
3083 }
3084
3085 for (child = access->first_child; child; child = child->next_sibling)
3086 clobber_subtree (child, gsi, insert_after, loc);
3087 }
3088
3089 /* Search for an access representative for the given expression EXPR and
3090 return it or NULL if it cannot be found. */
3091
3092 static struct access *
3093 get_access_for_expr (tree expr)
3094 {
3095 poly_int64 poffset, psize, pmax_size;
3096 HOST_WIDE_INT offset, max_size;
3097 tree base;
3098 bool reverse;
3099
3100 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
3101 a different size than the size of its argument and we need the latter
3102 one. */
3103 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
3104 expr = TREE_OPERAND (expr, 0);
3105
3106 base = get_ref_base_and_extent (expr, &poffset, &psize, &pmax_size,
3107 &reverse);
3108 if (!known_size_p (pmax_size)
3109 || !pmax_size.is_constant (&max_size)
3110 || !poffset.is_constant (&offset)
3111 || !DECL_P (base))
3112 return NULL;
3113
3114 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
3115 return NULL;
3116
3117 return get_var_base_offset_size_access (base, offset, max_size);
3118 }
3119
3120 /* Replace the expression EXPR with a scalar replacement if there is one and
3121 generate other statements to do type conversion or subtree copying if
3122 necessary. GSI is used to place newly created statements, WRITE is true if
3123 the expression is being written to (it is on a LHS of a statement or output
3124 in an assembly statement). */
3125
3126 static bool
3127 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
3128 {
3129 location_t loc;
3130 struct access *access;
3131 tree type, bfr, orig_expr;
3132
3133 if (TREE_CODE (*expr) == BIT_FIELD_REF)
3134 {
3135 bfr = *expr;
3136 expr = &TREE_OPERAND (*expr, 0);
3137 }
3138 else
3139 bfr = NULL_TREE;
3140
3141 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
3142 expr = &TREE_OPERAND (*expr, 0);
3143 access = get_access_for_expr (*expr);
3144 if (!access)
3145 return false;
3146 type = TREE_TYPE (*expr);
3147 orig_expr = *expr;
3148
3149 loc = gimple_location (gsi_stmt (*gsi));
3150 gimple_stmt_iterator alt_gsi = gsi_none ();
3151 if (write && stmt_ends_bb_p (gsi_stmt (*gsi)))
3152 {
3153 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
3154 gsi = &alt_gsi;
3155 }
3156
3157 if (access->grp_to_be_replaced)
3158 {
3159 tree repl = get_access_replacement (access);
3160 /* If we replace a non-register typed access simply use the original
3161 access expression to extract the scalar component afterwards.
3162 This happens if scalarizing a function return value or parameter
3163 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
3164 gcc.c-torture/compile/20011217-1.c.
3165
3166 We also want to use this when accessing a complex or vector which can
3167 be accessed as a different type too, potentially creating a need for
3168 type conversion (see PR42196) and when scalarized unions are involved
3169 in assembler statements (see PR42398). */
3170 if (!useless_type_conversion_p (type, access->type))
3171 {
3172 tree ref;
3173
3174 ref = build_ref_for_model (loc, orig_expr, 0, access, gsi, false);
3175
3176 if (write)
3177 {
3178 gassign *stmt;
3179
3180 if (access->grp_partial_lhs)
3181 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
3182 false, GSI_NEW_STMT);
3183 stmt = gimple_build_assign (repl, ref);
3184 gimple_set_location (stmt, loc);
3185 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
3186 }
3187 else
3188 {
3189 gassign *stmt;
3190
3191 if (access->grp_partial_lhs)
3192 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
3193 true, GSI_SAME_STMT);
3194 stmt = gimple_build_assign (ref, repl);
3195 gimple_set_location (stmt, loc);
3196 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
3197 }
3198 }
3199 else
3200 *expr = repl;
3201 sra_stats.exprs++;
3202 }
3203 else if (write && access->grp_to_be_debug_replaced)
3204 {
3205 gdebug *ds = gimple_build_debug_bind (get_access_replacement (access),
3206 NULL_TREE,
3207 gsi_stmt (*gsi));
3208 gsi_insert_after (gsi, ds, GSI_NEW_STMT);
3209 }
3210
3211 if (access->first_child)
3212 {
3213 HOST_WIDE_INT start_offset, chunk_size;
3214 if (bfr
3215 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 1))
3216 && tree_fits_uhwi_p (TREE_OPERAND (bfr, 2)))
3217 {
3218 chunk_size = tree_to_uhwi (TREE_OPERAND (bfr, 1));
3219 start_offset = access->offset
3220 + tree_to_uhwi (TREE_OPERAND (bfr, 2));
3221 }
3222 else
3223 start_offset = chunk_size = 0;
3224
3225 generate_subtree_copies (access->first_child, orig_expr, access->offset,
3226 start_offset, chunk_size, gsi, write, write,
3227 loc);
3228 }
3229 return true;
3230 }
3231
3232 /* Where scalar replacements of the RHS have been written to when a replacement
3233 of a LHS of an assigments cannot be direclty loaded from a replacement of
3234 the RHS. */
3235 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
3236 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
3237 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
3238
3239 struct subreplacement_assignment_data
3240 {
3241 /* Offset of the access representing the lhs of the assignment. */
3242 HOST_WIDE_INT left_offset;
3243
3244 /* LHS and RHS of the original assignment. */
3245 tree assignment_lhs, assignment_rhs;
3246
3247 /* Access representing the rhs of the whole assignment. */
3248 struct access *top_racc;
3249
3250 /* Stmt iterator used for statement insertions after the original assignment.
3251 It points to the main GSI used to traverse a BB during function body
3252 modification. */
3253 gimple_stmt_iterator *new_gsi;
3254
3255 /* Stmt iterator used for statement insertions before the original
3256 assignment. Keeps on pointing to the original statement. */
3257 gimple_stmt_iterator old_gsi;
3258
3259 /* Location of the assignment. */
3260 location_t loc;
3261
3262 /* Keeps the information whether we have needed to refresh replacements of
3263 the LHS and from which side of the assignments this takes place. */
3264 enum unscalarized_data_handling refreshed;
3265 };
3266
3267 /* Store all replacements in the access tree rooted in TOP_RACC either to their
3268 base aggregate if there are unscalarized data or directly to LHS of the
3269 statement that is pointed to by GSI otherwise. */
3270
3271 static void
3272 handle_unscalarized_data_in_subtree (struct subreplacement_assignment_data *sad)
3273 {
3274 tree src;
3275 if (sad->top_racc->grp_unscalarized_data)
3276 {
3277 src = sad->assignment_rhs;
3278 sad->refreshed = SRA_UDH_RIGHT;
3279 }
3280 else
3281 {
3282 src = sad->assignment_lhs;
3283 sad->refreshed = SRA_UDH_LEFT;
3284 }
3285 generate_subtree_copies (sad->top_racc->first_child, src,
3286 sad->top_racc->offset, 0, 0,
3287 &sad->old_gsi, false, false, sad->loc);
3288 }
3289
3290 /* Try to generate statements to load all sub-replacements in an access subtree
3291 formed by children of LACC from scalar replacements in the SAD->top_racc
3292 subtree. If that is not possible, refresh the SAD->top_racc base aggregate
3293 and load the accesses from it. */
3294
3295 static void
3296 load_assign_lhs_subreplacements (struct access *lacc,
3297 struct subreplacement_assignment_data *sad)
3298 {
3299 for (lacc = lacc->first_child; lacc; lacc = lacc->next_sibling)
3300 {
3301 HOST_WIDE_INT offset;
3302 offset = lacc->offset - sad->left_offset + sad->top_racc->offset;
3303
3304 if (lacc->grp_to_be_replaced)
3305 {
3306 struct access *racc;
3307 gassign *stmt;
3308 tree rhs;
3309
3310 racc = find_access_in_subtree (sad->top_racc, offset, lacc->size);
3311 if (racc && racc->grp_to_be_replaced)
3312 {
3313 rhs = get_access_replacement (racc);
3314 if (!useless_type_conversion_p (lacc->type, racc->type))
3315 rhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
3316 lacc->type, rhs);
3317
3318 if (racc->grp_partial_lhs && lacc->grp_partial_lhs)
3319 rhs = force_gimple_operand_gsi (&sad->old_gsi, rhs, true,
3320 NULL_TREE, true, GSI_SAME_STMT);
3321 }
3322 else
3323 {
3324 /* No suitable access on the right hand side, need to load from
3325 the aggregate. See if we have to update it first... */
3326 if (sad->refreshed == SRA_UDH_NONE)
3327 handle_unscalarized_data_in_subtree (sad);
3328
3329 if (sad->refreshed == SRA_UDH_LEFT)
3330 rhs = build_ref_for_model (sad->loc, sad->assignment_lhs,
3331 lacc->offset - sad->left_offset,
3332 lacc, sad->new_gsi, true);
3333 else
3334 rhs = build_ref_for_model (sad->loc, sad->assignment_rhs,
3335 lacc->offset - sad->left_offset,
3336 lacc, sad->new_gsi, true);
3337 if (lacc->grp_partial_lhs)
3338 rhs = force_gimple_operand_gsi (sad->new_gsi,
3339 rhs, true, NULL_TREE,
3340 false, GSI_NEW_STMT);
3341 }
3342
3343 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
3344 gsi_insert_after (sad->new_gsi, stmt, GSI_NEW_STMT);
3345 gimple_set_location (stmt, sad->loc);
3346 update_stmt (stmt);
3347 sra_stats.subreplacements++;
3348 }
3349 else
3350 {
3351 if (sad->refreshed == SRA_UDH_NONE
3352 && lacc->grp_read && !lacc->grp_covered)
3353 handle_unscalarized_data_in_subtree (sad);
3354
3355 if (lacc && lacc->grp_to_be_debug_replaced)
3356 {
3357 gdebug *ds;
3358 tree drhs;
3359 struct access *racc = find_access_in_subtree (sad->top_racc,
3360 offset,
3361 lacc->size);
3362
3363 if (racc && racc->grp_to_be_replaced)
3364 {
3365 if (racc->grp_write || constant_decl_p (racc->base))
3366 drhs = get_access_replacement (racc);
3367 else
3368 drhs = NULL;
3369 }
3370 else if (sad->refreshed == SRA_UDH_LEFT)
3371 drhs = build_debug_ref_for_model (sad->loc, lacc->base,
3372 lacc->offset, lacc);
3373 else if (sad->refreshed == SRA_UDH_RIGHT)
3374 drhs = build_debug_ref_for_model (sad->loc, sad->top_racc->base,
3375 offset, lacc);
3376 else
3377 drhs = NULL_TREE;
3378 if (drhs
3379 && !useless_type_conversion_p (lacc->type, TREE_TYPE (drhs)))
3380 drhs = fold_build1_loc (sad->loc, VIEW_CONVERT_EXPR,
3381 lacc->type, drhs);
3382 ds = gimple_build_debug_bind (get_access_replacement (lacc),
3383 drhs, gsi_stmt (sad->old_gsi));
3384 gsi_insert_after (sad->new_gsi, ds, GSI_NEW_STMT);
3385 }
3386 }
3387
3388 if (lacc->first_child)
3389 load_assign_lhs_subreplacements (lacc, sad);
3390 }
3391 }
3392
3393 /* Result code for SRA assignment modification. */
3394 enum assignment_mod_result { SRA_AM_NONE, /* nothing done for the stmt */
3395 SRA_AM_MODIFIED, /* stmt changed but not
3396 removed */
3397 SRA_AM_REMOVED }; /* stmt eliminated */
3398
3399 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
3400 to the assignment and GSI is the statement iterator pointing at it. Returns
3401 the same values as sra_modify_assign. */
3402
3403 static enum assignment_mod_result
3404 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3405 {
3406 tree lhs = gimple_assign_lhs (stmt);
3407 struct access *acc = get_access_for_expr (lhs);
3408 if (!acc)
3409 return SRA_AM_NONE;
3410 location_t loc = gimple_location (stmt);
3411
3412 if (gimple_clobber_p (stmt))
3413 {
3414 /* Clobber the replacement variable. */
3415 clobber_subtree (acc, gsi, !acc->grp_covered, loc);
3416 /* Remove clobbers of fully scalarized variables, they are dead. */
3417 if (acc->grp_covered)
3418 {
3419 unlink_stmt_vdef (stmt);
3420 gsi_remove (gsi, true);
3421 release_defs (stmt);
3422 return SRA_AM_REMOVED;
3423 }
3424 else
3425 return SRA_AM_MODIFIED;
3426 }
3427
3428 if (CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt)) > 0)
3429 {
3430 /* I have never seen this code path trigger but if it can happen the
3431 following should handle it gracefully. */
3432 if (access_has_children_p (acc))
3433 generate_subtree_copies (acc->first_child, lhs, acc->offset, 0, 0, gsi,
3434 true, true, loc);
3435 return SRA_AM_MODIFIED;
3436 }
3437
3438 if (acc->grp_covered)
3439 {
3440 init_subtree_with_zero (acc, gsi, false, loc);
3441 unlink_stmt_vdef (stmt);
3442 gsi_remove (gsi, true);
3443 release_defs (stmt);
3444 return SRA_AM_REMOVED;
3445 }
3446 else
3447 {
3448 init_subtree_with_zero (acc, gsi, true, loc);
3449 return SRA_AM_MODIFIED;
3450 }
3451 }
3452
3453 /* Create and return a new suitable default definition SSA_NAME for RACC which
3454 is an access describing an uninitialized part of an aggregate that is being
3455 loaded. */
3456
3457 static tree
3458 get_repl_default_def_ssa_name (struct access *racc)
3459 {
3460 gcc_checking_assert (!racc->grp_to_be_replaced
3461 && !racc->grp_to_be_debug_replaced);
3462 if (!racc->replacement_decl)
3463 racc->replacement_decl = create_access_replacement (racc);
3464 return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
3465 }
3466
3467 /* Examine both sides of the assignment statement pointed to by STMT, replace
3468 them with a scalare replacement if there is one and generate copying of
3469 replacements if scalarized aggregates have been used in the assignment. GSI
3470 is used to hold generated statements for type conversions and subtree
3471 copying. */
3472
3473 static enum assignment_mod_result
3474 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
3475 {
3476 struct access *lacc, *racc;
3477 tree lhs, rhs;
3478 bool modify_this_stmt = false;
3479 bool force_gimple_rhs = false;
3480 location_t loc;
3481 gimple_stmt_iterator orig_gsi = *gsi;
3482
3483 if (!gimple_assign_single_p (stmt))
3484 return SRA_AM_NONE;
3485 lhs = gimple_assign_lhs (stmt);
3486 rhs = gimple_assign_rhs1 (stmt);
3487
3488 if (TREE_CODE (rhs) == CONSTRUCTOR)
3489 return sra_modify_constructor_assign (stmt, gsi);
3490
3491 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
3492 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
3493 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
3494 {
3495 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (stmt),
3496 gsi, false);
3497 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (stmt),
3498 gsi, true);
3499 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3500 }
3501
3502 lacc = get_access_for_expr (lhs);
3503 racc = get_access_for_expr (rhs);
3504 if (!lacc && !racc)
3505 return SRA_AM_NONE;
3506 /* Avoid modifying initializations of constant-pool replacements. */
3507 if (racc && (racc->replacement_decl == lhs))
3508 return SRA_AM_NONE;
3509
3510 loc = gimple_location (stmt);
3511 if (lacc && lacc->grp_to_be_replaced)
3512 {
3513 lhs = get_access_replacement (lacc);
3514 gimple_assign_set_lhs (stmt, lhs);
3515 modify_this_stmt = true;
3516 if (lacc->grp_partial_lhs)
3517 force_gimple_rhs = true;
3518 sra_stats.exprs++;
3519 }
3520
3521 if (racc && racc->grp_to_be_replaced)
3522 {
3523 rhs = get_access_replacement (racc);
3524 modify_this_stmt = true;
3525 if (racc->grp_partial_lhs)
3526 force_gimple_rhs = true;
3527 sra_stats.exprs++;
3528 }
3529 else if (racc
3530 && !racc->grp_unscalarized_data
3531 && !racc->grp_unscalarizable_region
3532 && TREE_CODE (lhs) == SSA_NAME
3533 && !access_has_replacements_p (racc))
3534 {
3535 rhs = get_repl_default_def_ssa_name (racc);
3536 modify_this_stmt = true;
3537 sra_stats.exprs++;
3538 }
3539
3540 if (modify_this_stmt)
3541 {
3542 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3543 {
3544 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
3545 ??? This should move to fold_stmt which we simply should
3546 call after building a VIEW_CONVERT_EXPR here. */
3547 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
3548 && !contains_bitfld_component_ref_p (lhs))
3549 {
3550 lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
3551 gimple_assign_set_lhs (stmt, lhs);
3552 }
3553 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
3554 && !contains_vce_or_bfcref_p (rhs))
3555 rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
3556
3557 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
3558 {
3559 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
3560 rhs);
3561 if (is_gimple_reg_type (TREE_TYPE (lhs))
3562 && TREE_CODE (lhs) != SSA_NAME)
3563 force_gimple_rhs = true;
3564 }
3565 }
3566 }
3567
3568 if (lacc && lacc->grp_to_be_debug_replaced)
3569 {
3570 tree dlhs = get_access_replacement (lacc);
3571 tree drhs = unshare_expr (rhs);
3572 if (!useless_type_conversion_p (TREE_TYPE (dlhs), TREE_TYPE (drhs)))
3573 {
3574 if (AGGREGATE_TYPE_P (TREE_TYPE (drhs))
3575 && !contains_vce_or_bfcref_p (drhs))
3576 drhs = build_debug_ref_for_model (loc, drhs, 0, lacc);
3577 if (drhs
3578 && !useless_type_conversion_p (TREE_TYPE (dlhs),
3579 TREE_TYPE (drhs)))
3580 drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
3581 TREE_TYPE (dlhs), drhs);
3582 }
3583 gdebug *ds = gimple_build_debug_bind (dlhs, drhs, stmt);
3584 gsi_insert_before (gsi, ds, GSI_SAME_STMT);
3585 }
3586
3587 /* From this point on, the function deals with assignments in between
3588 aggregates when at least one has scalar reductions of some of its
3589 components. There are three possible scenarios: Both the LHS and RHS have
3590 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
3591
3592 In the first case, we would like to load the LHS components from RHS
3593 components whenever possible. If that is not possible, we would like to
3594 read it directly from the RHS (after updating it by storing in it its own
3595 components). If there are some necessary unscalarized data in the LHS,
3596 those will be loaded by the original assignment too. If neither of these
3597 cases happen, the original statement can be removed. Most of this is done
3598 by load_assign_lhs_subreplacements.
3599
3600 In the second case, we would like to store all RHS scalarized components
3601 directly into LHS and if they cover the aggregate completely, remove the
3602 statement too. In the third case, we want the LHS components to be loaded
3603 directly from the RHS (DSE will remove the original statement if it
3604 becomes redundant).
3605
3606 This is a bit complex but manageable when types match and when unions do
3607 not cause confusion in a way that we cannot really load a component of LHS
3608 from the RHS or vice versa (the access representing this level can have
3609 subaccesses that are accessible only through a different union field at a
3610 higher level - different from the one used in the examined expression).
3611 Unions are fun.
3612
3613 Therefore, I specially handle a fourth case, happening when there is a
3614 specific type cast or it is impossible to locate a scalarized subaccess on
3615 the other side of the expression. If that happens, I simply "refresh" the
3616 RHS by storing in it is scalarized components leave the original statement
3617 there to do the copying and then load the scalar replacements of the LHS.
3618 This is what the first branch does. */
3619
3620 if (modify_this_stmt
3621 || gimple_has_volatile_ops (stmt)
3622 || contains_vce_or_bfcref_p (rhs)
3623 || contains_vce_or_bfcref_p (lhs)
3624 || stmt_ends_bb_p (stmt))
3625 {
3626 /* No need to copy into a constant-pool, it comes pre-initialized. */
3627 if (access_has_children_p (racc) && !constant_decl_p (racc->base))
3628 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3629 gsi, false, false, loc);
3630 if (access_has_children_p (lacc))
3631 {
3632 gimple_stmt_iterator alt_gsi = gsi_none ();
3633 if (stmt_ends_bb_p (stmt))
3634 {
3635 alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
3636 gsi = &alt_gsi;
3637 }
3638 generate_subtree_copies (lacc->first_child, lhs, lacc->offset, 0, 0,
3639 gsi, true, true, loc);
3640 }
3641 sra_stats.separate_lhs_rhs_handling++;
3642
3643 /* This gimplification must be done after generate_subtree_copies,
3644 lest we insert the subtree copies in the middle of the gimplified
3645 sequence. */
3646 if (force_gimple_rhs)
3647 rhs = force_gimple_operand_gsi (&orig_gsi, rhs, true, NULL_TREE,
3648 true, GSI_SAME_STMT);
3649 if (gimple_assign_rhs1 (stmt) != rhs)
3650 {
3651 modify_this_stmt = true;
3652 gimple_assign_set_rhs_from_tree (&orig_gsi, rhs);
3653 gcc_assert (stmt == gsi_stmt (orig_gsi));
3654 }
3655
3656 return modify_this_stmt ? SRA_AM_MODIFIED : SRA_AM_NONE;
3657 }
3658 else
3659 {
3660 if (access_has_children_p (lacc)
3661 && access_has_children_p (racc)
3662 /* When an access represents an unscalarizable region, it usually
3663 represents accesses with variable offset and thus must not be used
3664 to generate new memory accesses. */
3665 && !lacc->grp_unscalarizable_region
3666 && !racc->grp_unscalarizable_region)
3667 {
3668 struct subreplacement_assignment_data sad;
3669
3670 sad.left_offset = lacc->offset;
3671 sad.assignment_lhs = lhs;
3672 sad.assignment_rhs = rhs;
3673 sad.top_racc = racc;
3674 sad.old_gsi = *gsi;
3675 sad.new_gsi = gsi;
3676 sad.loc = gimple_location (stmt);
3677 sad.refreshed = SRA_UDH_NONE;
3678
3679 if (lacc->grp_read && !lacc->grp_covered)
3680 handle_unscalarized_data_in_subtree (&sad);
3681
3682 load_assign_lhs_subreplacements (lacc, &sad);
3683 if (sad.refreshed != SRA_UDH_RIGHT)
3684 {
3685 gsi_next (gsi);
3686 unlink_stmt_vdef (stmt);
3687 gsi_remove (&sad.old_gsi, true);
3688 release_defs (stmt);
3689 sra_stats.deleted++;
3690 return SRA_AM_REMOVED;
3691 }
3692 }
3693 else
3694 {
3695 if (access_has_children_p (racc)
3696 && !racc->grp_unscalarized_data
3697 && TREE_CODE (lhs) != SSA_NAME)
3698 {
3699 if (dump_file)
3700 {
3701 fprintf (dump_file, "Removing load: ");
3702 print_gimple_stmt (dump_file, stmt, 0);
3703 }
3704 generate_subtree_copies (racc->first_child, lhs,
3705 racc->offset, 0, 0, gsi,
3706 false, false, loc);
3707 gcc_assert (stmt == gsi_stmt (*gsi));
3708 unlink_stmt_vdef (stmt);
3709 gsi_remove (gsi, true);
3710 release_defs (stmt);
3711 sra_stats.deleted++;
3712 return SRA_AM_REMOVED;
3713 }
3714 /* Restore the aggregate RHS from its components so the
3715 prevailing aggregate copy does the right thing. */
3716 if (access_has_children_p (racc))
3717 generate_subtree_copies (racc->first_child, rhs, racc->offset, 0, 0,
3718 gsi, false, false, loc);
3719 /* Re-load the components of the aggregate copy destination.
3720 But use the RHS aggregate to load from to expose more
3721 optimization opportunities. */
3722 if (access_has_children_p (lacc))
3723 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
3724 0, 0, gsi, true, true, loc);
3725 }
3726
3727 return SRA_AM_NONE;
3728 }
3729 }
3730
3731 /* Set any scalar replacements of values in the constant pool to the initial
3732 value of the constant. (Constant-pool decls like *.LC0 have effectively
3733 been initialized before the program starts, we must do the same for their
3734 replacements.) Thus, we output statements like 'SR.1 = *.LC0[0];' into
3735 the function's entry block. */
3736
3737 static void
3738 initialize_constant_pool_replacements (void)
3739 {
3740 gimple_seq seq = NULL;
3741 gimple_stmt_iterator gsi = gsi_start (seq);
3742 bitmap_iterator bi;
3743 unsigned i;
3744
3745 EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
3746 {
3747 tree var = candidate (i);
3748 if (!constant_decl_p (var))
3749 continue;
3750 vec<access_p> *access_vec = get_base_access_vector (var);
3751 if (!access_vec)
3752 continue;
3753 for (unsigned i = 0; i < access_vec->length (); i++)
3754 {
3755 struct access *access = (*access_vec)[i];
3756 if (!access->replacement_decl)
3757 continue;
3758 gassign *stmt
3759 = gimple_build_assign (get_access_replacement (access),
3760 unshare_expr (access->expr));
3761 if (dump_file && (dump_flags & TDF_DETAILS))
3762 {
3763 fprintf (dump_file, "Generating constant initializer: ");
3764 print_gimple_stmt (dump_file, stmt, 0);
3765 fprintf (dump_file, "\n");
3766 }
3767 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
3768 update_stmt (stmt);
3769 }
3770 }
3771
3772 seq = gsi_seq (gsi);
3773 if (seq)
3774 gsi_insert_seq_on_edge_immediate (
3775 single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3776 }
3777
3778 /* Traverse the function body and all modifications as decided in
3779 analyze_all_variable_accesses. Return true iff the CFG has been
3780 changed. */
3781
3782 static bool
3783 sra_modify_function_body (void)
3784 {
3785 bool cfg_changed = false;
3786 basic_block bb;
3787
3788 initialize_constant_pool_replacements ();
3789
3790 FOR_EACH_BB_FN (bb, cfun)
3791 {
3792 gimple_stmt_iterator gsi = gsi_start_bb (bb);
3793 while (!gsi_end_p (gsi))
3794 {
3795 gimple *stmt = gsi_stmt (gsi);
3796 enum assignment_mod_result assign_result;
3797 bool modified = false, deleted = false;
3798 tree *t;
3799 unsigned i;
3800
3801 switch (gimple_code (stmt))
3802 {
3803 case GIMPLE_RETURN:
3804 t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
3805 if (*t != NULL_TREE)
3806 modified |= sra_modify_expr (t, &gsi, false);
3807 break;
3808
3809 case GIMPLE_ASSIGN:
3810 assign_result = sra_modify_assign (stmt, &gsi);
3811 modified |= assign_result == SRA_AM_MODIFIED;
3812 deleted = assign_result == SRA_AM_REMOVED;
3813 break;
3814
3815 case GIMPLE_CALL:
3816 /* Operands must be processed before the lhs. */
3817 for (i = 0; i < gimple_call_num_args (stmt); i++)
3818 {
3819 t = gimple_call_arg_ptr (stmt, i);
3820 modified |= sra_modify_expr (t, &gsi, false);
3821 }
3822
3823 if (gimple_call_lhs (stmt))
3824 {
3825 t = gimple_call_lhs_ptr (stmt);
3826 modified |= sra_modify_expr (t, &gsi, true);
3827 }
3828 break;
3829
3830 case GIMPLE_ASM:
3831 {
3832 gasm *asm_stmt = as_a <gasm *> (stmt);
3833 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
3834 {
3835 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
3836 modified |= sra_modify_expr (t, &gsi, false);
3837 }
3838 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
3839 {
3840 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
3841 modified |= sra_modify_expr (t, &gsi, true);
3842 }
3843 }
3844 break;
3845
3846 default:
3847 break;
3848 }
3849
3850 if (modified)
3851 {
3852 update_stmt (stmt);
3853 if (maybe_clean_eh_stmt (stmt)
3854 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
3855 cfg_changed = true;
3856 }
3857 if (!deleted)
3858 gsi_next (&gsi);
3859 }
3860 }
3861
3862 gsi_commit_edge_inserts ();
3863 return cfg_changed;
3864 }
3865
3866 /* Generate statements initializing scalar replacements of parts of function
3867 parameters. */
3868
3869 static void
3870 initialize_parameter_reductions (void)
3871 {
3872 gimple_stmt_iterator gsi;
3873 gimple_seq seq = NULL;
3874 tree parm;
3875
3876 gsi = gsi_start (seq);
3877 for (parm = DECL_ARGUMENTS (current_function_decl);
3878 parm;
3879 parm = DECL_CHAIN (parm))
3880 {
3881 vec<access_p> *access_vec;
3882 struct access *access;
3883
3884 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3885 continue;
3886 access_vec = get_base_access_vector (parm);
3887 if (!access_vec)
3888 continue;
3889
3890 for (access = (*access_vec)[0];
3891 access;
3892 access = access->next_grp)
3893 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true,
3894 EXPR_LOCATION (parm));
3895 }
3896
3897 seq = gsi_seq (gsi);
3898 if (seq)
3899 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
3900 }
3901
3902 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
3903 it reveals there are components of some aggregates to be scalarized, it runs
3904 the required transformations. */
3905 static unsigned int
3906 perform_intra_sra (void)
3907 {
3908 int ret = 0;
3909 sra_initialize ();
3910
3911 if (!find_var_candidates ())
3912 goto out;
3913
3914 if (!scan_function ())
3915 goto out;
3916
3917 if (!analyze_all_variable_accesses ())
3918 goto out;
3919
3920 if (sra_modify_function_body ())
3921 ret = TODO_update_ssa | TODO_cleanup_cfg;
3922 else
3923 ret = TODO_update_ssa;
3924 initialize_parameter_reductions ();
3925
3926 statistics_counter_event (cfun, "Scalar replacements created",
3927 sra_stats.replacements);
3928 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
3929 statistics_counter_event (cfun, "Subtree copy stmts",
3930 sra_stats.subtree_copies);
3931 statistics_counter_event (cfun, "Subreplacement stmts",
3932 sra_stats.subreplacements);
3933 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
3934 statistics_counter_event (cfun, "Separate LHS and RHS handling",
3935 sra_stats.separate_lhs_rhs_handling);
3936
3937 out:
3938 sra_deinitialize ();
3939 return ret;
3940 }
3941
3942 /* Perform early intraprocedural SRA. */
3943 static unsigned int
3944 early_intra_sra (void)
3945 {
3946 sra_mode = SRA_MODE_EARLY_INTRA;
3947 return perform_intra_sra ();
3948 }
3949
3950 /* Perform "late" intraprocedural SRA. */
3951 static unsigned int
3952 late_intra_sra (void)
3953 {
3954 sra_mode = SRA_MODE_INTRA;
3955 return perform_intra_sra ();
3956 }
3957
3958
3959 static bool
3960 gate_intra_sra (void)
3961 {
3962 return flag_tree_sra != 0 && dbg_cnt (tree_sra);
3963 }
3964
3965
3966 namespace {
3967
3968 const pass_data pass_data_sra_early =
3969 {
3970 GIMPLE_PASS, /* type */
3971 "esra", /* name */
3972 OPTGROUP_NONE, /* optinfo_flags */
3973 TV_TREE_SRA, /* tv_id */
3974 ( PROP_cfg | PROP_ssa ), /* properties_required */
3975 0, /* properties_provided */
3976 0, /* properties_destroyed */
3977 0, /* todo_flags_start */
3978 TODO_update_ssa, /* todo_flags_finish */
3979 };
3980
3981 class pass_sra_early : public gimple_opt_pass
3982 {
3983 public:
3984 pass_sra_early (gcc::context *ctxt)
3985 : gimple_opt_pass (pass_data_sra_early, ctxt)
3986 {}
3987
3988 /* opt_pass methods: */
3989 virtual bool gate (function *) { return gate_intra_sra (); }
3990 virtual unsigned int execute (function *) { return early_intra_sra (); }
3991
3992 }; // class pass_sra_early
3993
3994 } // anon namespace
3995
3996 gimple_opt_pass *
3997 make_pass_sra_early (gcc::context *ctxt)
3998 {
3999 return new pass_sra_early (ctxt);
4000 }
4001
4002 namespace {
4003
4004 const pass_data pass_data_sra =
4005 {
4006 GIMPLE_PASS, /* type */
4007 "sra", /* name */
4008 OPTGROUP_NONE, /* optinfo_flags */
4009 TV_TREE_SRA, /* tv_id */
4010 ( PROP_cfg | PROP_ssa ), /* properties_required */
4011 0, /* properties_provided */
4012 0, /* properties_destroyed */
4013 TODO_update_address_taken, /* todo_flags_start */
4014 TODO_update_ssa, /* todo_flags_finish */
4015 };
4016
4017 class pass_sra : public gimple_opt_pass
4018 {
4019 public:
4020 pass_sra (gcc::context *ctxt)
4021 : gimple_opt_pass (pass_data_sra, ctxt)
4022 {}
4023
4024 /* opt_pass methods: */
4025 virtual bool gate (function *) { return gate_intra_sra (); }
4026 virtual unsigned int execute (function *) { return late_intra_sra (); }
4027
4028 }; // class pass_sra
4029
4030 } // anon namespace
4031
4032 gimple_opt_pass *
4033 make_pass_sra (gcc::context *ctxt)
4034 {
4035 return new pass_sra (ctxt);
4036 }
4037
4038
4039 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
4040 parameter. */
4041
4042 static bool
4043 is_unused_scalar_param (tree parm)
4044 {
4045 tree name;
4046 return (is_gimple_reg (parm)
4047 && (!(name = ssa_default_def (cfun, parm))
4048 || has_zero_uses (name)));
4049 }
4050
4051 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
4052 examine whether there are any direct or otherwise infeasible ones. If so,
4053 return true, otherwise return false. PARM must be a gimple register with a
4054 non-NULL default definition. */
4055
4056 static bool
4057 ptr_parm_has_direct_uses (tree parm)
4058 {
4059 imm_use_iterator ui;
4060 gimple *stmt;
4061 tree name = ssa_default_def (cfun, parm);
4062 bool ret = false;
4063
4064 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
4065 {
4066 int uses_ok = 0;
4067 use_operand_p use_p;
4068
4069 if (is_gimple_debug (stmt))
4070 continue;
4071
4072 /* Valid uses include dereferences on the lhs and the rhs. */
4073 if (gimple_has_lhs (stmt))
4074 {
4075 tree lhs = gimple_get_lhs (stmt);
4076 while (handled_component_p (lhs))
4077 lhs = TREE_OPERAND (lhs, 0);
4078 if (TREE_CODE (lhs) == MEM_REF
4079 && TREE_OPERAND (lhs, 0) == name
4080 && integer_zerop (TREE_OPERAND (lhs, 1))
4081 && types_compatible_p (TREE_TYPE (lhs),
4082 TREE_TYPE (TREE_TYPE (name)))
4083 && !TREE_THIS_VOLATILE (lhs))
4084 uses_ok++;
4085 }
4086 if (gimple_assign_single_p (stmt))
4087 {
4088 tree rhs = gimple_assign_rhs1 (stmt);
4089 while (handled_component_p (rhs))
4090 rhs = TREE_OPERAND (rhs, 0);
4091 if (TREE_CODE (rhs) == MEM_REF
4092 && TREE_OPERAND (rhs, 0) == name
4093 && integer_zerop (TREE_OPERAND (rhs, 1))
4094 && types_compatible_p (TREE_TYPE (rhs),
4095 TREE_TYPE (TREE_TYPE (name)))
4096 && !TREE_THIS_VOLATILE (rhs))
4097 uses_ok++;
4098 }
4099 else if (is_gimple_call (stmt))
4100 {
4101 unsigned i;
4102 for (i = 0; i < gimple_call_num_args (stmt); ++i)
4103 {
4104 tree arg = gimple_call_arg (stmt, i);
4105 while (handled_component_p (arg))
4106 arg = TREE_OPERAND (arg, 0);
4107 if (TREE_CODE (arg) == MEM_REF
4108 && TREE_OPERAND (arg, 0) == name
4109 && integer_zerop (TREE_OPERAND (arg, 1))
4110 && types_compatible_p (TREE_TYPE (arg),
4111 TREE_TYPE (TREE_TYPE (name)))
4112 && !TREE_THIS_VOLATILE (arg))
4113 uses_ok++;
4114 }
4115 }
4116
4117 /* If the number of valid uses does not match the number of
4118 uses in this stmt there is an unhandled use. */
4119 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
4120 --uses_ok;
4121
4122 if (uses_ok != 0)
4123 ret = true;
4124
4125 if (ret)
4126 BREAK_FROM_IMM_USE_STMT (ui);
4127 }
4128
4129 return ret;
4130 }
4131
4132 /* Identify candidates for reduction for IPA-SRA based on their type and mark
4133 them in candidate_bitmap. Note that these do not necessarily include
4134 parameter which are unused and thus can be removed. Return true iff any
4135 such candidate has been found. */
4136
4137 static bool
4138 find_param_candidates (void)
4139 {
4140 tree parm;
4141 int count = 0;
4142 bool ret = false;
4143 const char *msg;
4144
4145 for (parm = DECL_ARGUMENTS (current_function_decl);
4146 parm;
4147 parm = DECL_CHAIN (parm))
4148 {
4149 tree type = TREE_TYPE (parm);
4150 tree_node **slot;
4151
4152 count++;
4153
4154 if (TREE_THIS_VOLATILE (parm)
4155 || TREE_ADDRESSABLE (parm)
4156 || (!is_gimple_reg_type (type) && is_va_list_type (type)))
4157 continue;
4158
4159 if (is_unused_scalar_param (parm))
4160 {
4161 ret = true;
4162 continue;
4163 }
4164
4165 if (POINTER_TYPE_P (type))
4166 {
4167 type = TREE_TYPE (type);
4168
4169 if (TREE_CODE (type) == FUNCTION_TYPE
4170 || TYPE_VOLATILE (type)
4171 || (TREE_CODE (type) == ARRAY_TYPE
4172 && TYPE_NONALIASED_COMPONENT (type))
4173 || !is_gimple_reg (parm)
4174 || is_va_list_type (type)
4175 || ptr_parm_has_direct_uses (parm))
4176 continue;
4177 }
4178 else if (!AGGREGATE_TYPE_P (type))
4179 continue;
4180
4181 if (!COMPLETE_TYPE_P (type)
4182 || !tree_fits_uhwi_p (TYPE_SIZE (type))
4183 || tree_to_uhwi (TYPE_SIZE (type)) == 0
4184 || (AGGREGATE_TYPE_P (type)
4185 && type_internals_preclude_sra_p (type, &msg)))
4186 continue;
4187
4188 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
4189 slot = candidates->find_slot_with_hash (parm, DECL_UID (parm), INSERT);
4190 *slot = parm;
4191
4192 ret = true;
4193 if (dump_file && (dump_flags & TDF_DETAILS))
4194 {
4195 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
4196 print_generic_expr (dump_file, parm);
4197 fprintf (dump_file, "\n");
4198 }
4199 }
4200
4201 func_param_count = count;
4202 return ret;
4203 }
4204
4205 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
4206 maybe_modified. */
4207
4208 static bool
4209 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
4210 void *data)
4211 {
4212 struct access *repr = (struct access *) data;
4213
4214 repr->grp_maybe_modified = 1;
4215 return true;
4216 }
4217
4218 /* Analyze what representatives (in linked lists accessible from
4219 REPRESENTATIVES) can be modified by side effects of statements in the
4220 current function. */
4221
4222 static void
4223 analyze_modified_params (vec<access_p> representatives)
4224 {
4225 int i;
4226
4227 for (i = 0; i < func_param_count; i++)
4228 {
4229 struct access *repr;
4230
4231 for (repr = representatives[i];
4232 repr;
4233 repr = repr->next_grp)
4234 {
4235 struct access *access;
4236 bitmap visited;
4237 ao_ref ar;
4238
4239 if (no_accesses_p (repr))
4240 continue;
4241 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
4242 || repr->grp_maybe_modified)
4243 continue;
4244
4245 ao_ref_init (&ar, repr->expr);
4246 visited = BITMAP_ALLOC (NULL);
4247 for (access = repr; access; access = access->next_sibling)
4248 {
4249 /* All accesses are read ones, otherwise grp_maybe_modified would
4250 be trivially set. */
4251 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
4252 mark_maybe_modified, repr, &visited);
4253 if (repr->grp_maybe_modified)
4254 break;
4255 }
4256 BITMAP_FREE (visited);
4257 }
4258 }
4259 }
4260
4261 /* Propagate distances in bb_dereferences in the opposite direction than the
4262 control flow edges, in each step storing the maximum of the current value
4263 and the minimum of all successors. These steps are repeated until the table
4264 stabilizes. Note that BBs which might terminate the functions (according to
4265 final_bbs bitmap) never updated in this way. */
4266
4267 static void
4268 propagate_dereference_distances (void)
4269 {
4270 basic_block bb;
4271
4272 auto_vec<basic_block> queue (last_basic_block_for_fn (cfun));
4273 queue.quick_push (ENTRY_BLOCK_PTR_FOR_FN (cfun));
4274 FOR_EACH_BB_FN (bb, cfun)
4275 {
4276 queue.quick_push (bb);
4277 bb->aux = bb;
4278 }
4279
4280 while (!queue.is_empty ())
4281 {
4282 edge_iterator ei;
4283 edge e;
4284 bool change = false;
4285 int i;
4286
4287 bb = queue.pop ();
4288 bb->aux = NULL;
4289
4290 if (bitmap_bit_p (final_bbs, bb->index))
4291 continue;
4292
4293 for (i = 0; i < func_param_count; i++)
4294 {
4295 int idx = bb->index * func_param_count + i;
4296 bool first = true;
4297 HOST_WIDE_INT inh = 0;
4298
4299 FOR_EACH_EDGE (e, ei, bb->succs)
4300 {
4301 int succ_idx = e->dest->index * func_param_count + i;
4302
4303 if (e->src == EXIT_BLOCK_PTR_FOR_FN (cfun))
4304 continue;
4305
4306 if (first)
4307 {
4308 first = false;
4309 inh = bb_dereferences [succ_idx];
4310 }
4311 else if (bb_dereferences [succ_idx] < inh)
4312 inh = bb_dereferences [succ_idx];
4313 }
4314
4315 if (!first && bb_dereferences[idx] < inh)
4316 {
4317 bb_dereferences[idx] = inh;
4318 change = true;
4319 }
4320 }
4321
4322 if (change && !bitmap_bit_p (final_bbs, bb->index))
4323 FOR_EACH_EDGE (e, ei, bb->preds)
4324 {
4325 if (e->src->aux)
4326 continue;
4327
4328 e->src->aux = e->src;
4329 queue.quick_push (e->src);
4330 }
4331 }
4332 }
4333
4334 /* Dump a dereferences TABLE with heading STR to file F. */
4335
4336 static void
4337 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
4338 {
4339 basic_block bb;
4340
4341 fprintf (dump_file, "%s", str);
4342 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
4343 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
4344 {
4345 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
4346 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
4347 {
4348 int i;
4349 for (i = 0; i < func_param_count; i++)
4350 {
4351 int idx = bb->index * func_param_count + i;
4352 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
4353 }
4354 }
4355 fprintf (f, "\n");
4356 }
4357 fprintf (dump_file, "\n");
4358 }
4359
4360 /* Determine what (parts of) parameters passed by reference that are not
4361 assigned to are not certainly dereferenced in this function and thus the
4362 dereferencing cannot be safely moved to the caller without potentially
4363 introducing a segfault. Mark such REPRESENTATIVES as
4364 grp_not_necessarilly_dereferenced.
4365
4366 The dereferenced maximum "distance," i.e. the offset + size of the accessed
4367 part is calculated rather than simple booleans are calculated for each
4368 pointer parameter to handle cases when only a fraction of the whole
4369 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
4370 an example).
4371
4372 The maximum dereference distances for each pointer parameter and BB are
4373 already stored in bb_dereference. This routine simply propagates these
4374 values upwards by propagate_dereference_distances and then compares the
4375 distances of individual parameters in the ENTRY BB to the equivalent
4376 distances of each representative of a (fraction of a) parameter. */
4377
4378 static void
4379 analyze_caller_dereference_legality (vec<access_p> representatives)
4380 {
4381 int i;
4382
4383 if (dump_file && (dump_flags & TDF_DETAILS))
4384 dump_dereferences_table (dump_file,
4385 "Dereference table before propagation:\n",
4386 bb_dereferences);
4387
4388 propagate_dereference_distances ();
4389
4390 if (dump_file && (dump_flags & TDF_DETAILS))
4391 dump_dereferences_table (dump_file,
4392 "Dereference table after propagation:\n",
4393 bb_dereferences);
4394
4395 for (i = 0; i < func_param_count; i++)
4396 {
4397 struct access *repr = representatives[i];
4398 int idx = ENTRY_BLOCK_PTR_FOR_FN (cfun)->index * func_param_count + i;
4399
4400 if (!repr || no_accesses_p (repr))
4401 continue;
4402
4403 do
4404 {
4405 if ((repr->offset + repr->size) > bb_dereferences[idx])
4406 repr->grp_not_necessarilly_dereferenced = 1;
4407 repr = repr->next_grp;
4408 }
4409 while (repr);
4410 }
4411 }
4412
4413 /* Return the representative access for the parameter declaration PARM if it is
4414 a scalar passed by reference which is not written to and the pointer value
4415 is not used directly. Thus, if it is legal to dereference it in the caller
4416 and we can rule out modifications through aliases, such parameter should be
4417 turned into one passed by value. Return NULL otherwise. */
4418
4419 static struct access *
4420 unmodified_by_ref_scalar_representative (tree parm)
4421 {
4422 int i, access_count;
4423 struct access *repr;
4424 vec<access_p> *access_vec;
4425
4426 access_vec = get_base_access_vector (parm);
4427 gcc_assert (access_vec);
4428 repr = (*access_vec)[0];
4429 if (repr->write)
4430 return NULL;
4431 repr->group_representative = repr;
4432
4433 access_count = access_vec->length ();
4434 for (i = 1; i < access_count; i++)
4435 {
4436 struct access *access = (*access_vec)[i];
4437 if (access->write)
4438 return NULL;
4439 access->group_representative = repr;
4440 access->next_sibling = repr->next_sibling;
4441 repr->next_sibling = access;
4442 }
4443
4444 repr->grp_read = 1;
4445 repr->grp_scalar_ptr = 1;
4446 return repr;
4447 }
4448
4449 /* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
4450 associated with. REQ_ALIGN is the minimum required alignment. */
4451
4452 static bool
4453 access_precludes_ipa_sra_p (struct access *access, unsigned int req_align)
4454 {
4455 unsigned int exp_align;
4456 /* Avoid issues such as the second simple testcase in PR 42025. The problem
4457 is incompatible assign in a call statement (and possibly even in asm
4458 statements). This can be relaxed by using a new temporary but only for
4459 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
4460 intraprocedural SRA we deal with this by keeping the old aggregate around,
4461 something we cannot do in IPA-SRA.) */
4462 if (access->write
4463 && (is_gimple_call (access->stmt)
4464 || gimple_code (access->stmt) == GIMPLE_ASM))
4465 return true;
4466
4467 exp_align = get_object_alignment (access->expr);
4468 if (exp_align < req_align)
4469 return true;
4470
4471 return false;
4472 }
4473
4474
4475 /* Sort collected accesses for parameter PARM, identify representatives for
4476 each accessed region and link them together. Return NULL if there are
4477 different but overlapping accesses, return the special ptr value meaning
4478 there are no accesses for this parameter if that is the case and return the
4479 first representative otherwise. Set *RO_GRP if there is a group of accesses
4480 with only read (i.e. no write) accesses. */
4481
4482 static struct access *
4483 splice_param_accesses (tree parm, bool *ro_grp)
4484 {
4485 int i, j, access_count, group_count;
4486 int total_size = 0;
4487 struct access *access, *res, **prev_acc_ptr = &res;
4488 vec<access_p> *access_vec;
4489
4490 access_vec = get_base_access_vector (parm);
4491 if (!access_vec)
4492 return &no_accesses_representant;
4493 access_count = access_vec->length ();
4494
4495 access_vec->qsort (compare_access_positions);
4496
4497 i = 0;
4498 total_size = 0;
4499 group_count = 0;
4500 while (i < access_count)
4501 {
4502 bool modification;
4503 tree a1_alias_type;
4504 access = (*access_vec)[i];
4505 modification = access->write;
4506 if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type)))
4507 return NULL;
4508 a1_alias_type = reference_alias_ptr_type (access->expr);
4509
4510 /* Access is about to become group representative unless we find some
4511 nasty overlap which would preclude us from breaking this parameter
4512 apart. */
4513
4514 j = i + 1;
4515 while (j < access_count)
4516 {
4517 struct access *ac2 = (*access_vec)[j];
4518 if (ac2->offset != access->offset)
4519 {
4520 /* All or nothing law for parameters. */
4521 if (access->offset + access->size > ac2->offset)
4522 return NULL;
4523 else
4524 break;
4525 }
4526 else if (ac2->size != access->size)
4527 return NULL;
4528
4529 if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type))
4530 || (ac2->type != access->type
4531 && (TREE_ADDRESSABLE (ac2->type)
4532 || TREE_ADDRESSABLE (access->type)))
4533 || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
4534 return NULL;
4535
4536 modification |= ac2->write;
4537 ac2->group_representative = access;
4538 ac2->next_sibling = access->next_sibling;
4539 access->next_sibling = ac2;
4540 j++;
4541 }
4542
4543 group_count++;
4544 access->grp_maybe_modified = modification;
4545 if (!modification)
4546 *ro_grp = true;
4547 *prev_acc_ptr = access;
4548 prev_acc_ptr = &access->next_grp;
4549 total_size += access->size;
4550 i = j;
4551 }
4552
4553 gcc_assert (group_count > 0);
4554 return res;
4555 }
4556
4557 /* Decide whether parameters with representative accesses given by REPR should
4558 be reduced into components. */
4559
4560 static int
4561 decide_one_param_reduction (struct access *repr)
4562 {
4563 HOST_WIDE_INT total_size, cur_parm_size;
4564 bool by_ref;
4565 tree parm;
4566
4567 parm = repr->base;
4568 cur_parm_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
4569 gcc_assert (cur_parm_size > 0);
4570
4571 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4572 by_ref = true;
4573 else
4574 by_ref = false;
4575
4576 if (dump_file)
4577 {
4578 struct access *acc;
4579 fprintf (dump_file, "Evaluating PARAM group sizes for ");
4580 print_generic_expr (dump_file, parm);
4581 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
4582 for (acc = repr; acc; acc = acc->next_grp)
4583 dump_access (dump_file, acc, true);
4584 }
4585
4586 total_size = 0;
4587 int new_param_count = 0;
4588
4589 for (; repr; repr = repr->next_grp)
4590 {
4591 gcc_assert (parm == repr->base);
4592
4593 /* Taking the address of a non-addressable field is verboten. */
4594 if (by_ref && repr->non_addressable)
4595 return 0;
4596
4597 /* Do not decompose a non-BLKmode param in a way that would
4598 create BLKmode params. Especially for by-reference passing
4599 (thus, pointer-type param) this is hardly worthwhile. */
4600 if (DECL_MODE (parm) != BLKmode
4601 && TYPE_MODE (repr->type) == BLKmode)
4602 return 0;
4603
4604 if (!by_ref || (!repr->grp_maybe_modified
4605 && !repr->grp_not_necessarilly_dereferenced))
4606 total_size += repr->size;
4607 else
4608 total_size += cur_parm_size;
4609
4610 new_param_count++;
4611 }
4612
4613 gcc_assert (new_param_count > 0);
4614
4615 if (!by_ref)
4616 {
4617 if (total_size >= cur_parm_size)
4618 return 0;
4619 }
4620 else
4621 {
4622 int parm_num_limit;
4623 if (optimize_function_for_size_p (cfun))
4624 parm_num_limit = 1;
4625 else
4626 parm_num_limit = PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR);
4627
4628 if (new_param_count > parm_num_limit
4629 || total_size > (parm_num_limit * cur_parm_size))
4630 return 0;
4631 }
4632
4633 if (dump_file)
4634 fprintf (dump_file, " ....will be split into %i components\n",
4635 new_param_count);
4636 return new_param_count;
4637 }
4638
4639 /* The order of the following enums is important, we need to do extra work for
4640 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
4641 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
4642 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
4643
4644 /* Identify representatives of all accesses to all candidate parameters for
4645 IPA-SRA. Return result based on what representatives have been found. */
4646
4647 static enum ipa_splicing_result
4648 splice_all_param_accesses (vec<access_p> &representatives)
4649 {
4650 enum ipa_splicing_result result = NO_GOOD_ACCESS;
4651 tree parm;
4652 struct access *repr;
4653
4654 representatives.create (func_param_count);
4655
4656 for (parm = DECL_ARGUMENTS (current_function_decl);
4657 parm;
4658 parm = DECL_CHAIN (parm))
4659 {
4660 if (is_unused_scalar_param (parm))
4661 {
4662 representatives.quick_push (&no_accesses_representant);
4663 if (result == NO_GOOD_ACCESS)
4664 result = UNUSED_PARAMS;
4665 }
4666 else if (POINTER_TYPE_P (TREE_TYPE (parm))
4667 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
4668 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4669 {
4670 repr = unmodified_by_ref_scalar_representative (parm);
4671 representatives.quick_push (repr);
4672 if (repr)
4673 result = UNMODIF_BY_REF_ACCESSES;
4674 }
4675 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
4676 {
4677 bool ro_grp = false;
4678 repr = splice_param_accesses (parm, &ro_grp);
4679 representatives.quick_push (repr);
4680
4681 if (repr && !no_accesses_p (repr))
4682 {
4683 if (POINTER_TYPE_P (TREE_TYPE (parm)))
4684 {
4685 if (ro_grp)
4686 result = UNMODIF_BY_REF_ACCESSES;
4687 else if (result < MODIF_BY_REF_ACCESSES)
4688 result = MODIF_BY_REF_ACCESSES;
4689 }
4690 else if (result < BY_VAL_ACCESSES)
4691 result = BY_VAL_ACCESSES;
4692 }
4693 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
4694 result = UNUSED_PARAMS;
4695 }
4696 else
4697 representatives.quick_push (NULL);
4698 }
4699
4700 if (result == NO_GOOD_ACCESS)
4701 {
4702 representatives.release ();
4703 return NO_GOOD_ACCESS;
4704 }
4705
4706 return result;
4707 }
4708
4709 /* Return the index of BASE in PARMS. Abort if it is not found. */
4710
4711 static inline int
4712 get_param_index (tree base, vec<tree> parms)
4713 {
4714 int i, len;
4715
4716 len = parms.length ();
4717 for (i = 0; i < len; i++)
4718 if (parms[i] == base)
4719 return i;
4720 gcc_unreachable ();
4721 }
4722
4723 /* Convert the decisions made at the representative level into compact
4724 parameter adjustments. REPRESENTATIVES are pointers to first
4725 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
4726 final number of adjustments. */
4727
4728 static ipa_parm_adjustment_vec
4729 turn_representatives_into_adjustments (vec<access_p> representatives,
4730 int adjustments_count)
4731 {
4732 vec<tree> parms;
4733 ipa_parm_adjustment_vec adjustments;
4734 tree parm;
4735 int i;
4736
4737 gcc_assert (adjustments_count > 0);
4738 parms = ipa_get_vector_of_formal_parms (current_function_decl);
4739 adjustments.create (adjustments_count);
4740 parm = DECL_ARGUMENTS (current_function_decl);
4741 for (i = 0; i < func_param_count; i++, parm = DECL_CHAIN (parm))
4742 {
4743 struct access *repr = representatives[i];
4744
4745 if (!repr || no_accesses_p (repr))
4746 {
4747 struct ipa_parm_adjustment adj;
4748
4749 memset (&adj, 0, sizeof (adj));
4750 adj.base_index = get_param_index (parm, parms);
4751 adj.base = parm;
4752 if (!repr)
4753 adj.op = IPA_PARM_OP_COPY;
4754 else
4755 adj.op = IPA_PARM_OP_REMOVE;
4756 adj.arg_prefix = "ISRA";
4757 adjustments.quick_push (adj);
4758 }
4759 else
4760 {
4761 struct ipa_parm_adjustment adj;
4762 int index = get_param_index (parm, parms);
4763
4764 for (; repr; repr = repr->next_grp)
4765 {
4766 memset (&adj, 0, sizeof (adj));
4767 gcc_assert (repr->base == parm);
4768 adj.base_index = index;
4769 adj.base = repr->base;
4770 adj.type = repr->type;
4771 adj.alias_ptr_type = reference_alias_ptr_type (repr->expr);
4772 adj.offset = repr->offset;
4773 adj.reverse = repr->reverse;
4774 adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
4775 && (repr->grp_maybe_modified
4776 || repr->grp_not_necessarilly_dereferenced));
4777 adj.arg_prefix = "ISRA";
4778 adjustments.quick_push (adj);
4779 }
4780 }
4781 }
4782 parms.release ();
4783 return adjustments;
4784 }
4785
4786 /* Analyze the collected accesses and produce a plan what to do with the
4787 parameters in the form of adjustments, NULL meaning nothing. */
4788
4789 static ipa_parm_adjustment_vec
4790 analyze_all_param_acesses (void)
4791 {
4792 enum ipa_splicing_result repr_state;
4793 bool proceed = false;
4794 int i, adjustments_count = 0;
4795 vec<access_p> representatives;
4796 ipa_parm_adjustment_vec adjustments;
4797
4798 repr_state = splice_all_param_accesses (representatives);
4799 if (repr_state == NO_GOOD_ACCESS)
4800 return ipa_parm_adjustment_vec ();
4801
4802 /* If there are any parameters passed by reference which are not modified
4803 directly, we need to check whether they can be modified indirectly. */
4804 if (repr_state == UNMODIF_BY_REF_ACCESSES)
4805 {
4806 analyze_caller_dereference_legality (representatives);
4807 analyze_modified_params (representatives);
4808 }
4809
4810 for (i = 0; i < func_param_count; i++)
4811 {
4812 struct access *repr = representatives[i];
4813
4814 if (repr && !no_accesses_p (repr))
4815 {
4816 if (repr->grp_scalar_ptr)
4817 {
4818 adjustments_count++;
4819 if (repr->grp_not_necessarilly_dereferenced
4820 || repr->grp_maybe_modified)
4821 representatives[i] = NULL;
4822 else
4823 {
4824 proceed = true;
4825 sra_stats.scalar_by_ref_to_by_val++;
4826 }
4827 }
4828 else
4829 {
4830 int new_components = decide_one_param_reduction (repr);
4831
4832 if (new_components == 0)
4833 {
4834 representatives[i] = NULL;
4835 adjustments_count++;
4836 }
4837 else
4838 {
4839 adjustments_count += new_components;
4840 sra_stats.aggregate_params_reduced++;
4841 sra_stats.param_reductions_created += new_components;
4842 proceed = true;
4843 }
4844 }
4845 }
4846 else
4847 {
4848 if (no_accesses_p (repr))
4849 {
4850 proceed = true;
4851 sra_stats.deleted_unused_parameters++;
4852 }
4853 adjustments_count++;
4854 }
4855 }
4856
4857 if (!proceed && dump_file)
4858 fprintf (dump_file, "NOT proceeding to change params.\n");
4859
4860 if (proceed)
4861 adjustments = turn_representatives_into_adjustments (representatives,
4862 adjustments_count);
4863 else
4864 adjustments = ipa_parm_adjustment_vec ();
4865
4866 representatives.release ();
4867 return adjustments;
4868 }
4869
4870 /* If a parameter replacement identified by ADJ does not yet exist in the form
4871 of declaration, create it and record it, otherwise return the previously
4872 created one. */
4873
4874 static tree
4875 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
4876 {
4877 tree repl;
4878 if (!adj->new_ssa_base)
4879 {
4880 char *pretty_name = make_fancy_name (adj->base);
4881
4882 repl = create_tmp_reg (TREE_TYPE (adj->base), "ISR");
4883 DECL_NAME (repl) = get_identifier (pretty_name);
4884 DECL_NAMELESS (repl) = 1;
4885 obstack_free (&name_obstack, pretty_name);
4886
4887 adj->new_ssa_base = repl;
4888 }
4889 else
4890 repl = adj->new_ssa_base;
4891 return repl;
4892 }
4893
4894 /* Find the first adjustment for a particular parameter BASE in a vector of
4895 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
4896 adjustment. */
4897
4898 static struct ipa_parm_adjustment *
4899 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
4900 {
4901 int i, len;
4902
4903 len = adjustments.length ();
4904 for (i = 0; i < len; i++)
4905 {
4906 struct ipa_parm_adjustment *adj;
4907
4908 adj = &adjustments[i];
4909 if (adj->op != IPA_PARM_OP_COPY && adj->base == base)
4910 return adj;
4911 }
4912
4913 return NULL;
4914 }
4915
4916 /* If OLD_NAME, which is being defined by statement STMT, is an SSA_NAME of a
4917 parameter which is to be removed because its value is not used, create a new
4918 SSA_NAME relating to a replacement VAR_DECL, replace all uses of the
4919 original with it and return it. If there is no need to re-map, return NULL.
4920 ADJUSTMENTS is a pointer to a vector of IPA-SRA adjustments. */
4921
4922 static tree
4923 replace_removed_params_ssa_names (tree old_name, gimple *stmt,
4924 ipa_parm_adjustment_vec adjustments)
4925 {
4926 struct ipa_parm_adjustment *adj;
4927 tree decl, repl, new_name;
4928
4929 if (TREE_CODE (old_name) != SSA_NAME)
4930 return NULL;
4931
4932 decl = SSA_NAME_VAR (old_name);
4933 if (decl == NULL_TREE
4934 || TREE_CODE (decl) != PARM_DECL)
4935 return NULL;
4936
4937 adj = get_adjustment_for_base (adjustments, decl);
4938 if (!adj)
4939 return NULL;
4940
4941 repl = get_replaced_param_substitute (adj);
4942 new_name = make_ssa_name (repl, stmt);
4943 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name)
4944 = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name);
4945
4946 if (dump_file)
4947 {
4948 fprintf (dump_file, "replacing an SSA name of a removed param ");
4949 print_generic_expr (dump_file, old_name);
4950 fprintf (dump_file, " with ");
4951 print_generic_expr (dump_file, new_name);
4952 fprintf (dump_file, "\n");
4953 }
4954
4955 replace_uses_by (old_name, new_name);
4956 return new_name;
4957 }
4958
4959 /* If the statement STMT contains any expressions that need to replaced with a
4960 different one as noted by ADJUSTMENTS, do so. Handle any potential type
4961 incompatibilities (GSI is used to accommodate conversion statements and must
4962 point to the statement). Return true iff the statement was modified. */
4963
4964 static bool
4965 sra_ipa_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi,
4966 ipa_parm_adjustment_vec adjustments)
4967 {
4968 tree *lhs_p, *rhs_p;
4969 bool any;
4970
4971 if (!gimple_assign_single_p (stmt))
4972 return false;
4973
4974 rhs_p = gimple_assign_rhs1_ptr (stmt);
4975 lhs_p = gimple_assign_lhs_ptr (stmt);
4976
4977 any = ipa_modify_expr (rhs_p, false, adjustments);
4978 any |= ipa_modify_expr (lhs_p, false, adjustments);
4979 if (any)
4980 {
4981 tree new_rhs = NULL_TREE;
4982
4983 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
4984 {
4985 if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
4986 {
4987 /* V_C_Es of constructors can cause trouble (PR 42714). */
4988 if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
4989 *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
4990 else
4991 *rhs_p = build_constructor (TREE_TYPE (*lhs_p),
4992 NULL);
4993 }
4994 else
4995 new_rhs = fold_build1_loc (gimple_location (stmt),
4996 VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
4997 *rhs_p);
4998 }
4999 else if (REFERENCE_CLASS_P (*rhs_p)
5000 && is_gimple_reg_type (TREE_TYPE (*lhs_p))
5001 && !is_gimple_reg (*lhs_p))
5002 /* This can happen when an assignment in between two single field
5003 structures is turned into an assignment in between two pointers to
5004 scalars (PR 42237). */
5005 new_rhs = *rhs_p;
5006
5007 if (new_rhs)
5008 {
5009 tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
5010 true, GSI_SAME_STMT);
5011
5012 gimple_assign_set_rhs_from_tree (gsi, tmp);
5013 }
5014
5015 return true;
5016 }
5017
5018 return false;
5019 }
5020
5021 /* Traverse the function body and all modifications as described in
5022 ADJUSTMENTS. Return true iff the CFG has been changed. */
5023
5024 bool
5025 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
5026 {
5027 bool cfg_changed = false;
5028 basic_block bb;
5029
5030 FOR_EACH_BB_FN (bb, cfun)
5031 {
5032 gimple_stmt_iterator gsi;
5033
5034 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5035 {
5036 gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
5037 tree new_lhs, old_lhs = gimple_phi_result (phi);
5038 new_lhs = replace_removed_params_ssa_names (old_lhs, phi, adjustments);
5039 if (new_lhs)
5040 {
5041 gimple_phi_set_result (phi, new_lhs);
5042 release_ssa_name (old_lhs);
5043 }
5044 }
5045
5046 gsi = gsi_start_bb (bb);
5047 while (!gsi_end_p (gsi))
5048 {
5049 gimple *stmt = gsi_stmt (gsi);
5050 bool modified = false;
5051 tree *t;
5052 unsigned i;
5053
5054 switch (gimple_code (stmt))
5055 {
5056 case GIMPLE_RETURN:
5057 t = gimple_return_retval_ptr (as_a <greturn *> (stmt));
5058 if (*t != NULL_TREE)
5059 modified |= ipa_modify_expr (t, true, adjustments);
5060 break;
5061
5062 case GIMPLE_ASSIGN:
5063 modified |= sra_ipa_modify_assign (stmt, &gsi, adjustments);
5064 break;
5065
5066 case GIMPLE_CALL:
5067 /* Operands must be processed before the lhs. */
5068 for (i = 0; i < gimple_call_num_args (stmt); i++)
5069 {
5070 t = gimple_call_arg_ptr (stmt, i);
5071 modified |= ipa_modify_expr (t, true, adjustments);
5072 }
5073
5074 if (gimple_call_lhs (stmt))
5075 {
5076 t = gimple_call_lhs_ptr (stmt);
5077 modified |= ipa_modify_expr (t, false, adjustments);
5078 }
5079 break;
5080
5081 case GIMPLE_ASM:
5082 {
5083 gasm *asm_stmt = as_a <gasm *> (stmt);
5084 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
5085 {
5086 t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
5087 modified |= ipa_modify_expr (t, true, adjustments);
5088 }
5089 for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
5090 {
5091 t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
5092 modified |= ipa_modify_expr (t, false, adjustments);
5093 }
5094 }
5095 break;
5096
5097 default:
5098 break;
5099 }
5100
5101 def_operand_p defp;
5102 ssa_op_iter iter;
5103 FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF)
5104 {
5105 tree old_def = DEF_FROM_PTR (defp);
5106 if (tree new_def = replace_removed_params_ssa_names (old_def, stmt,
5107 adjustments))
5108 {
5109 SET_DEF (defp, new_def);
5110 release_ssa_name (old_def);
5111 modified = true;
5112 }
5113 }
5114
5115 if (modified)
5116 {
5117 update_stmt (stmt);
5118 if (maybe_clean_eh_stmt (stmt)
5119 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
5120 cfg_changed = true;
5121 }
5122 gsi_next (&gsi);
5123 }
5124 }
5125
5126 return cfg_changed;
5127 }
5128
5129 /* Call gimple_debug_bind_reset_value on all debug statements describing
5130 gimple register parameters that are being removed or replaced. */
5131
5132 static void
5133 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
5134 {
5135 int i, len;
5136 gimple_stmt_iterator *gsip = NULL, gsi;
5137
5138 if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
5139 {
5140 gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
5141 gsip = &gsi;
5142 }
5143 len = adjustments.length ();
5144 for (i = 0; i < len; i++)
5145 {
5146 struct ipa_parm_adjustment *adj;
5147 imm_use_iterator ui;
5148 gimple *stmt;
5149 gdebug *def_temp;
5150 tree name, vexpr, copy = NULL_TREE;
5151 use_operand_p use_p;
5152
5153 adj = &adjustments[i];
5154 if (adj->op == IPA_PARM_OP_COPY || !is_gimple_reg (adj->base))
5155 continue;
5156 name = ssa_default_def (cfun, adj->base);
5157 vexpr = NULL;
5158 if (name)
5159 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
5160 {
5161 if (gimple_clobber_p (stmt))
5162 {
5163 gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
5164 unlink_stmt_vdef (stmt);
5165 gsi_remove (&cgsi, true);
5166 release_defs (stmt);
5167 continue;
5168 }
5169 /* All other users must have been removed by
5170 ipa_sra_modify_function_body. */
5171 gcc_assert (is_gimple_debug (stmt));
5172 if (vexpr == NULL && gsip != NULL)
5173 {
5174 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
5175 vexpr = make_node (DEBUG_EXPR_DECL);
5176 def_temp = gimple_build_debug_source_bind (vexpr, adj->base,
5177 NULL);
5178 DECL_ARTIFICIAL (vexpr) = 1;
5179 TREE_TYPE (vexpr) = TREE_TYPE (name);
5180 SET_DECL_MODE (vexpr, DECL_MODE (adj->base));
5181 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
5182 }
5183 if (vexpr)
5184 {
5185 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
5186 SET_USE (use_p, vexpr);
5187 }
5188 else
5189 gimple_debug_bind_reset_value (stmt);
5190 update_stmt (stmt);
5191 }
5192 /* Create a VAR_DECL for debug info purposes. */
5193 if (!DECL_IGNORED_P (adj->base))
5194 {
5195 copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
5196 VAR_DECL, DECL_NAME (adj->base),
5197 TREE_TYPE (adj->base));
5198 if (DECL_PT_UID_SET_P (adj->base))
5199 SET_DECL_PT_UID (copy, DECL_PT_UID (adj->base));
5200 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (adj->base);
5201 TREE_READONLY (copy) = TREE_READONLY (adj->base);
5202 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (adj->base);
5203 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (adj->base);
5204 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (adj->base);
5205 DECL_IGNORED_P (copy) = DECL_IGNORED_P (adj->base);
5206 DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (adj->base);
5207 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
5208 SET_DECL_RTL (copy, 0);
5209 TREE_USED (copy) = 1;
5210 DECL_CONTEXT (copy) = current_function_decl;
5211 add_local_decl (cfun, copy);
5212 DECL_CHAIN (copy) =
5213 BLOCK_VARS (DECL_INITIAL (current_function_decl));
5214 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
5215 }
5216 if (gsip != NULL && copy && target_for_debug_bind (adj->base))
5217 {
5218 gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
5219 if (vexpr)
5220 def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
5221 else
5222 def_temp = gimple_build_debug_source_bind (copy, adj->base,
5223 NULL);
5224 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
5225 }
5226 }
5227 }
5228
5229 /* Return false if all callers have at least as many actual arguments as there
5230 are formal parameters in the current function and that their types
5231 match. */
5232
5233 static bool
5234 some_callers_have_mismatched_arguments_p (struct cgraph_node *node,
5235 void *data ATTRIBUTE_UNUSED)
5236 {
5237 struct cgraph_edge *cs;
5238 for (cs = node->callers; cs; cs = cs->next_caller)
5239 if (!cs->call_stmt || !callsite_arguments_match_p (cs->call_stmt))
5240 return true;
5241
5242 return false;
5243 }
5244
5245 /* Return false if all callers have vuse attached to a call statement. */
5246
5247 static bool
5248 some_callers_have_no_vuse_p (struct cgraph_node *node,
5249 void *data ATTRIBUTE_UNUSED)
5250 {
5251 struct cgraph_edge *cs;
5252 for (cs = node->callers; cs; cs = cs->next_caller)
5253 if (!cs->call_stmt || !gimple_vuse (cs->call_stmt))
5254 return true;
5255
5256 return false;
5257 }
5258
5259 /* Convert all callers of NODE. */
5260
5261 static bool
5262 convert_callers_for_node (struct cgraph_node *node,
5263 void *data)
5264 {
5265 ipa_parm_adjustment_vec *adjustments = (ipa_parm_adjustment_vec *) data;
5266 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
5267 struct cgraph_edge *cs;
5268
5269 for (cs = node->callers; cs; cs = cs->next_caller)
5270 {
5271 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
5272
5273 if (dump_file)
5274 fprintf (dump_file, "Adjusting call %s -> %s\n",
5275 cs->caller->dump_name (), cs->callee->dump_name ());
5276
5277 ipa_modify_call_arguments (cs, cs->call_stmt, *adjustments);
5278
5279 pop_cfun ();
5280 }
5281
5282 for (cs = node->callers; cs; cs = cs->next_caller)
5283 if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
5284 && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
5285 compute_fn_summary (cs->caller, true);
5286 BITMAP_FREE (recomputed_callers);
5287
5288 return true;
5289 }
5290
5291 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
5292
5293 static void
5294 convert_callers (struct cgraph_node *node, tree old_decl,
5295 ipa_parm_adjustment_vec adjustments)
5296 {
5297 basic_block this_block;
5298
5299 node->call_for_symbol_and_aliases (convert_callers_for_node,
5300 &adjustments, false);
5301
5302 if (!encountered_recursive_call)
5303 return;
5304
5305 FOR_EACH_BB_FN (this_block, cfun)
5306 {
5307 gimple_stmt_iterator gsi;
5308
5309 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
5310 {
5311 gcall *stmt;
5312 tree call_fndecl;
5313 stmt = dyn_cast <gcall *> (gsi_stmt (gsi));
5314 if (!stmt)
5315 continue;
5316 call_fndecl = gimple_call_fndecl (stmt);
5317 if (call_fndecl == old_decl)
5318 {
5319 if (dump_file)
5320 fprintf (dump_file, "Adjusting recursive call");
5321 gimple_call_set_fndecl (stmt, node->decl);
5322 ipa_modify_call_arguments (NULL, stmt, adjustments);
5323 }
5324 }
5325 }
5326
5327 return;
5328 }
5329
5330 /* Perform all the modification required in IPA-SRA for NODE to have parameters
5331 as given in ADJUSTMENTS. Return true iff the CFG has been changed. */
5332
5333 static bool
5334 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
5335 {
5336 struct cgraph_node *new_node;
5337 bool cfg_changed;
5338
5339 cgraph_edge::rebuild_edges ();
5340 free_dominance_info (CDI_DOMINATORS);
5341 pop_cfun ();
5342
5343 /* This must be done after rebuilding cgraph edges for node above.
5344 Otherwise any recursive calls to node that are recorded in
5345 redirect_callers will be corrupted. */
5346 vec<cgraph_edge *> redirect_callers = node->collect_callers ();
5347 new_node = node->create_version_clone_with_body (redirect_callers, NULL,
5348 NULL, false, NULL, NULL,
5349 "isra");
5350 redirect_callers.release ();
5351
5352 push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
5353 ipa_modify_formal_parameters (current_function_decl, adjustments);
5354 cfg_changed = ipa_sra_modify_function_body (adjustments);
5355 sra_ipa_reset_debug_stmts (adjustments);
5356 convert_callers (new_node, node->decl, adjustments);
5357 new_node->make_local ();
5358 return cfg_changed;
5359 }
5360
5361 /* Means of communication between ipa_sra_check_caller and
5362 ipa_sra_preliminary_function_checks. */
5363
5364 struct ipa_sra_check_caller_data
5365 {
5366 bool has_callers;
5367 bool bad_arg_alignment;
5368 bool has_thunk;
5369 };
5370
5371 /* If NODE has a caller, mark that fact in DATA which is pointer to
5372 ipa_sra_check_caller_data. Also check all aggregate arguments in all known
5373 calls if they are unit aligned and if not, set the appropriate flag in DATA
5374 too. */
5375
5376 static bool
5377 ipa_sra_check_caller (struct cgraph_node *node, void *data)
5378 {
5379 if (!node->callers)
5380 return false;
5381
5382 struct ipa_sra_check_caller_data *iscc;
5383 iscc = (struct ipa_sra_check_caller_data *) data;
5384 iscc->has_callers = true;
5385
5386 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
5387 {
5388 if (cs->caller->thunk.thunk_p)
5389 {
5390 iscc->has_thunk = true;
5391 return true;
5392 }
5393 gimple *call_stmt = cs->call_stmt;
5394 unsigned count = gimple_call_num_args (call_stmt);
5395 for (unsigned i = 0; i < count; i++)
5396 {
5397 tree arg = gimple_call_arg (call_stmt, i);
5398 if (is_gimple_reg (arg))
5399 continue;
5400
5401 tree offset;
5402 HOST_WIDE_INT bitsize, bitpos;
5403 machine_mode mode;
5404 int unsignedp, reversep, volatilep = 0;
5405 get_inner_reference (arg, &bitsize, &bitpos, &offset, &mode,
5406 &unsignedp, &reversep, &volatilep);
5407 if (bitpos % BITS_PER_UNIT)
5408 {
5409 iscc->bad_arg_alignment = true;
5410 return true;
5411 }
5412 }
5413 }
5414
5415 return false;
5416 }
5417
5418 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
5419 attributes, return true otherwise. NODE is the cgraph node of the current
5420 function. */
5421
5422 static bool
5423 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
5424 {
5425 if (!node->can_be_local_p ())
5426 {
5427 if (dump_file)
5428 fprintf (dump_file, "Function not local to this compilation unit.\n");
5429 return false;
5430 }
5431
5432 if (!node->local.can_change_signature)
5433 {
5434 if (dump_file)
5435 fprintf (dump_file, "Function can not change signature.\n");
5436 return false;
5437 }
5438
5439 if (!tree_versionable_function_p (node->decl))
5440 {
5441 if (dump_file)
5442 fprintf (dump_file, "Function is not versionable.\n");
5443 return false;
5444 }
5445
5446 if (!opt_for_fn (node->decl, optimize)
5447 || !opt_for_fn (node->decl, flag_ipa_sra))
5448 {
5449 if (dump_file)
5450 fprintf (dump_file, "Function not optimized.\n");
5451 return false;
5452 }
5453
5454 if (DECL_VIRTUAL_P (current_function_decl))
5455 {
5456 if (dump_file)
5457 fprintf (dump_file, "Function is a virtual method.\n");
5458 return false;
5459 }
5460
5461 if ((DECL_ONE_ONLY (node->decl) || DECL_EXTERNAL (node->decl))
5462 && ipa_fn_summaries->get (node)->size >= MAX_INLINE_INSNS_AUTO)
5463 {
5464 if (dump_file)
5465 fprintf (dump_file, "Function too big to be made truly local.\n");
5466 return false;
5467 }
5468
5469 if (cfun->stdarg)
5470 {
5471 if (dump_file)
5472 fprintf (dump_file, "Function uses stdarg. \n");
5473 return false;
5474 }
5475
5476 if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
5477 return false;
5478
5479 if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
5480 {
5481 if (dump_file)
5482 fprintf (dump_file, "Always inline function will be inlined "
5483 "anyway. \n");
5484 return false;
5485 }
5486
5487 struct ipa_sra_check_caller_data iscc;
5488 memset (&iscc, 0, sizeof(iscc));
5489 node->call_for_symbol_and_aliases (ipa_sra_check_caller, &iscc, true);
5490 if (!iscc.has_callers)
5491 {
5492 if (dump_file)
5493 fprintf (dump_file,
5494 "Function has no callers in this compilation unit.\n");
5495 return false;
5496 }
5497
5498 if (iscc.bad_arg_alignment)
5499 {
5500 if (dump_file)
5501 fprintf (dump_file,
5502 "A function call has an argument with non-unit alignment.\n");
5503 return false;
5504 }
5505
5506 if (iscc.has_thunk)
5507 {
5508 if (dump_file)
5509 fprintf (dump_file,
5510 "A has thunk.\n");
5511 return false;
5512 }
5513
5514 return true;
5515 }
5516
5517 /* Perform early interprocedural SRA. */
5518
5519 static unsigned int
5520 ipa_early_sra (void)
5521 {
5522 struct cgraph_node *node = cgraph_node::get (current_function_decl);
5523 ipa_parm_adjustment_vec adjustments;
5524 int ret = 0;
5525
5526 if (!ipa_sra_preliminary_function_checks (node))
5527 return 0;
5528
5529 sra_initialize ();
5530 sra_mode = SRA_MODE_EARLY_IPA;
5531
5532 if (!find_param_candidates ())
5533 {
5534 if (dump_file)
5535 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
5536 goto simple_out;
5537 }
5538
5539 if (node->call_for_symbol_and_aliases
5540 (some_callers_have_mismatched_arguments_p, NULL, true))
5541 {
5542 if (dump_file)
5543 fprintf (dump_file, "There are callers with insufficient number of "
5544 "arguments or arguments with type mismatches.\n");
5545 goto simple_out;
5546 }
5547
5548 if (node->call_for_symbol_and_aliases
5549 (some_callers_have_no_vuse_p, NULL, true))
5550 {
5551 if (dump_file)
5552 fprintf (dump_file, "There are callers with no VUSE attached "
5553 "to a call stmt.\n");
5554 goto simple_out;
5555 }
5556
5557 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
5558 func_param_count
5559 * last_basic_block_for_fn (cfun));
5560 final_bbs = BITMAP_ALLOC (NULL);
5561
5562 scan_function ();
5563 if (encountered_apply_args)
5564 {
5565 if (dump_file)
5566 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
5567 goto out;
5568 }
5569
5570 if (encountered_unchangable_recursive_call)
5571 {
5572 if (dump_file)
5573 fprintf (dump_file, "Function calls itself with insufficient "
5574 "number of arguments.\n");
5575 goto out;
5576 }
5577
5578 adjustments = analyze_all_param_acesses ();
5579 if (!adjustments.exists ())
5580 goto out;
5581 if (dump_file)
5582 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
5583
5584 if (modify_function (node, adjustments))
5585 ret = TODO_update_ssa | TODO_cleanup_cfg;
5586 else
5587 ret = TODO_update_ssa;
5588 adjustments.release ();
5589
5590 statistics_counter_event (cfun, "Unused parameters deleted",
5591 sra_stats.deleted_unused_parameters);
5592 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
5593 sra_stats.scalar_by_ref_to_by_val);
5594 statistics_counter_event (cfun, "Aggregate parameters broken up",
5595 sra_stats.aggregate_params_reduced);
5596 statistics_counter_event (cfun, "Aggregate parameter components created",
5597 sra_stats.param_reductions_created);
5598
5599 out:
5600 BITMAP_FREE (final_bbs);
5601 free (bb_dereferences);
5602 simple_out:
5603 sra_deinitialize ();
5604 return ret;
5605 }
5606
5607 namespace {
5608
5609 const pass_data pass_data_early_ipa_sra =
5610 {
5611 GIMPLE_PASS, /* type */
5612 "eipa_sra", /* name */
5613 OPTGROUP_NONE, /* optinfo_flags */
5614 TV_IPA_SRA, /* tv_id */
5615 0, /* properties_required */
5616 0, /* properties_provided */
5617 0, /* properties_destroyed */
5618 0, /* todo_flags_start */
5619 TODO_dump_symtab, /* todo_flags_finish */
5620 };
5621
5622 class pass_early_ipa_sra : public gimple_opt_pass
5623 {
5624 public:
5625 pass_early_ipa_sra (gcc::context *ctxt)
5626 : gimple_opt_pass (pass_data_early_ipa_sra, ctxt)
5627 {}
5628
5629 /* opt_pass methods: */
5630 virtual bool gate (function *) { return flag_ipa_sra && dbg_cnt (eipa_sra); }
5631 virtual unsigned int execute (function *) { return ipa_early_sra (); }
5632
5633 }; // class pass_early_ipa_sra
5634
5635 } // anon namespace
5636
5637 gimple_opt_pass *
5638 make_pass_early_ipa_sra (gcc::context *ctxt)
5639 {
5640 return new pass_early_ipa_sra (ctxt);
5641 }