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