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