re PR c++/10690 ([DR 115] Even when used within typeid(), a template-id generating...
[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, 2009 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 "alloc-pool.h"
78 #include "tm.h"
79 #include "tree.h"
80 #include "gimple.h"
81 #include "cgraph.h"
82 #include "tree-flow.h"
83 #include "ipa-prop.h"
84 #include "diagnostic.h"
85 #include "statistics.h"
86 #include "tree-dump.h"
87 #include "timevar.h"
88 #include "params.h"
89 #include "target.h"
90 #include "flags.h"
91
92 /* Enumeration of all aggregate reductions we can do. */
93 enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
94 SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
95 SRA_MODE_INTRA }; /* late intraprocedural SRA */
96
97 /* Global variable describing which aggregate reduction we are performing at
98 the moment. */
99 static enum sra_mode sra_mode;
100
101 struct assign_link;
102
103 /* ACCESS represents each access to an aggregate variable (as a whole or a
104 part). It can also represent a group of accesses that refer to exactly the
105 same fragment of an aggregate (i.e. those that have exactly the same offset
106 and size). Such representatives for a single aggregate, once determined,
107 are linked in a linked list and have the group fields set.
108
109 Moreover, when doing intraprocedural SRA, a tree is built from those
110 representatives (by the means of first_child and next_sibling pointers), in
111 which all items in a subtree are "within" the root, i.e. their offset is
112 greater or equal to offset of the root and offset+size is smaller or equal
113 to offset+size of the root. Children of an access are sorted by offset.
114
115 Note that accesses to parts of vector and complex number types always
116 represented by an access to the whole complex number or a vector. It is a
117 duty of the modifying functions to replace them appropriately. */
118
119 struct access
120 {
121 /* Values returned by `get_ref_base_and_extent' for each component reference
122 If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
123 `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
124 HOST_WIDE_INT offset;
125 HOST_WIDE_INT size;
126 tree base;
127
128 /* Expression. It is context dependent so do not use it to create new
129 expressions to access the original aggregate. See PR 42154 for a
130 testcase. */
131 tree expr;
132 /* Type. */
133 tree type;
134
135 /* The statement this access belongs to. */
136 gimple stmt;
137
138 /* Next group representative for this aggregate. */
139 struct access *next_grp;
140
141 /* Pointer to the group representative. Pointer to itself if the struct is
142 the representative. */
143 struct access *group_representative;
144
145 /* If this access has any children (in terms of the definition above), this
146 points to the first one. */
147 struct access *first_child;
148
149 /* In intraprocedural SRA, pointer to the next sibling in the access tree as
150 described above. In IPA-SRA this is a pointer to the next access
151 belonging to the same group (having the same representative). */
152 struct access *next_sibling;
153
154 /* Pointers to the first and last element in the linked list of assign
155 links. */
156 struct assign_link *first_link, *last_link;
157
158 /* Pointer to the next access in the work queue. */
159 struct access *next_queued;
160
161 /* Replacement variable for this access "region." Never to be accessed
162 directly, always only by the means of get_access_replacement() and only
163 when grp_to_be_replaced flag is set. */
164 tree replacement_decl;
165
166 /* Is this particular access write access? */
167 unsigned write : 1;
168
169 /* Is this access currently in the work queue? */
170 unsigned grp_queued : 1;
171
172 /* Does this group contain a write access? This flag is propagated down the
173 access tree. */
174 unsigned grp_write : 1;
175
176 /* Does this group contain a read access? This flag is propagated down the
177 access tree. */
178 unsigned grp_read : 1;
179
180 /* Other passes of the analysis use this bit to make function
181 analyze_access_subtree create scalar replacements for this group if
182 possible. */
183 unsigned grp_hint : 1;
184
185 /* Is the subtree rooted in this access fully covered by scalar
186 replacements? */
187 unsigned grp_covered : 1;
188
189 /* If set to true, this access and all below it in an access tree must not be
190 scalarized. */
191 unsigned grp_unscalarizable_region : 1;
192
193 /* Whether data have been written to parts of the aggregate covered by this
194 access which is not to be scalarized. This flag is propagated up in the
195 access tree. */
196 unsigned grp_unscalarized_data : 1;
197
198 /* Does this access and/or group contain a write access through a
199 BIT_FIELD_REF? */
200 unsigned grp_partial_lhs : 1;
201
202 /* Set when a scalar replacement should be created for this variable. We do
203 the decision and creation at different places because create_tmp_var
204 cannot be called from within FOR_EACH_REFERENCED_VAR. */
205 unsigned grp_to_be_replaced : 1;
206
207 /* Is it possible that the group refers to data which might be (directly or
208 otherwise) modified? */
209 unsigned grp_maybe_modified : 1;
210
211 /* Set when this is a representative of a pointer to scalar (i.e. by
212 reference) parameter which we consider for turning into a plain scalar
213 (i.e. a by value parameter). */
214 unsigned grp_scalar_ptr : 1;
215
216 /* Set when we discover that this pointer is not safe to dereference in the
217 caller. */
218 unsigned grp_not_necessarilly_dereferenced : 1;
219 };
220
221 typedef struct access *access_p;
222
223 DEF_VEC_P (access_p);
224 DEF_VEC_ALLOC_P (access_p, heap);
225
226 /* Alloc pool for allocating access structures. */
227 static alloc_pool access_pool;
228
229 /* A structure linking lhs and rhs accesses from an aggregate assignment. They
230 are used to propagate subaccesses from rhs to lhs as long as they don't
231 conflict with what is already there. */
232 struct assign_link
233 {
234 struct access *lacc, *racc;
235 struct assign_link *next;
236 };
237
238 /* Alloc pool for allocating assign link structures. */
239 static alloc_pool link_pool;
240
241 /* Base (tree) -> Vector (VEC(access_p,heap) *) map. */
242 static struct pointer_map_t *base_access_vec;
243
244 /* Bitmap of candidates. */
245 static bitmap candidate_bitmap;
246
247 /* Obstack for creation of fancy names. */
248 static struct obstack name_obstack;
249
250 /* Head of a linked list of accesses that need to have its subaccesses
251 propagated to their assignment counterparts. */
252 static struct access *work_queue_head;
253
254 /* Number of parameters of the analyzed function when doing early ipa SRA. */
255 static int func_param_count;
256
257 /* scan_function sets the following to true if it encounters a call to
258 __builtin_apply_args. */
259 static bool encountered_apply_args;
260
261 /* This is a table in which for each basic block and parameter there is a
262 distance (offset + size) in that parameter which is dereferenced and
263 accessed in that BB. */
264 static HOST_WIDE_INT *bb_dereferences;
265 /* Bitmap of BBs that can cause the function to "stop" progressing by
266 returning, throwing externally, looping infinitely or calling a function
267 which might abort etc.. */
268 static bitmap final_bbs;
269
270 /* Representative of no accesses at all. */
271 static struct access no_accesses_representant;
272
273 /* Predicate to test the special value. */
274
275 static inline bool
276 no_accesses_p (struct access *access)
277 {
278 return access == &no_accesses_representant;
279 }
280
281 /* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
282 representative fields are dumped, otherwise those which only describe the
283 individual access are. */
284
285 static struct
286 {
287 /* Number of processed aggregates is readily available in
288 analyze_all_variable_accesses and so is not stored here. */
289
290 /* Number of created scalar replacements. */
291 int replacements;
292
293 /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
294 expression. */
295 int exprs;
296
297 /* Number of statements created by generate_subtree_copies. */
298 int subtree_copies;
299
300 /* Number of statements created by load_assign_lhs_subreplacements. */
301 int subreplacements;
302
303 /* Number of times sra_modify_assign has deleted a statement. */
304 int deleted;
305
306 /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
307 RHS reparately due to type conversions or nonexistent matching
308 references. */
309 int separate_lhs_rhs_handling;
310
311 /* Number of parameters that were removed because they were unused. */
312 int deleted_unused_parameters;
313
314 /* Number of scalars passed as parameters by reference that have been
315 converted to be passed by value. */
316 int scalar_by_ref_to_by_val;
317
318 /* Number of aggregate parameters that were replaced by one or more of their
319 components. */
320 int aggregate_params_reduced;
321
322 /* Numbber of components created when splitting aggregate parameters. */
323 int param_reductions_created;
324 } sra_stats;
325
326 static void
327 dump_access (FILE *f, struct access *access, bool grp)
328 {
329 fprintf (f, "access { ");
330 fprintf (f, "base = (%d)'", DECL_UID (access->base));
331 print_generic_expr (f, access->base, 0);
332 fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
333 fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
334 fprintf (f, ", expr = ");
335 print_generic_expr (f, access->expr, 0);
336 fprintf (f, ", type = ");
337 print_generic_expr (f, access->type, 0);
338 if (grp)
339 fprintf (f, ", grp_write = %d, grp_read = %d, grp_hint = %d, "
340 "grp_covered = %d, grp_unscalarizable_region = %d, "
341 "grp_unscalarized_data = %d, grp_partial_lhs = %d, "
342 "grp_to_be_replaced = %d\n grp_maybe_modified = %d, "
343 "grp_not_necessarilly_dereferenced = %d\n",
344 access->grp_write, access->grp_read, access->grp_hint,
345 access->grp_covered, access->grp_unscalarizable_region,
346 access->grp_unscalarized_data, access->grp_partial_lhs,
347 access->grp_to_be_replaced, access->grp_maybe_modified,
348 access->grp_not_necessarilly_dereferenced);
349 else
350 fprintf (f, ", write = %d, grp_partial_lhs = %d\n", access->write,
351 access->grp_partial_lhs);
352 }
353
354 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
355
356 static void
357 dump_access_tree_1 (FILE *f, struct access *access, int level)
358 {
359 do
360 {
361 int i;
362
363 for (i = 0; i < level; i++)
364 fputs ("* ", dump_file);
365
366 dump_access (f, access, true);
367
368 if (access->first_child)
369 dump_access_tree_1 (f, access->first_child, level + 1);
370
371 access = access->next_sibling;
372 }
373 while (access);
374 }
375
376 /* Dump all access trees for a variable, given the pointer to the first root in
377 ACCESS. */
378
379 static void
380 dump_access_tree (FILE *f, struct access *access)
381 {
382 for (; access; access = access->next_grp)
383 dump_access_tree_1 (f, access, 0);
384 }
385
386 /* Return true iff ACC is non-NULL and has subaccesses. */
387
388 static inline bool
389 access_has_children_p (struct access *acc)
390 {
391 return acc && acc->first_child;
392 }
393
394 /* Return a vector of pointers to accesses for the variable given in BASE or
395 NULL if there is none. */
396
397 static VEC (access_p, heap) *
398 get_base_access_vector (tree base)
399 {
400 void **slot;
401
402 slot = pointer_map_contains (base_access_vec, base);
403 if (!slot)
404 return NULL;
405 else
406 return *(VEC (access_p, heap) **) slot;
407 }
408
409 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
410 in ACCESS. Return NULL if it cannot be found. */
411
412 static struct access *
413 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
414 HOST_WIDE_INT size)
415 {
416 while (access && (access->offset != offset || access->size != size))
417 {
418 struct access *child = access->first_child;
419
420 while (child && (child->offset + child->size <= offset))
421 child = child->next_sibling;
422 access = child;
423 }
424
425 return access;
426 }
427
428 /* Return the first group representative for DECL or NULL if none exists. */
429
430 static struct access *
431 get_first_repr_for_decl (tree base)
432 {
433 VEC (access_p, heap) *access_vec;
434
435 access_vec = get_base_access_vector (base);
436 if (!access_vec)
437 return NULL;
438
439 return VEC_index (access_p, access_vec, 0);
440 }
441
442 /* Find an access representative for the variable BASE and given OFFSET and
443 SIZE. Requires that access trees have already been built. Return NULL if
444 it cannot be found. */
445
446 static struct access *
447 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
448 HOST_WIDE_INT size)
449 {
450 struct access *access;
451
452 access = get_first_repr_for_decl (base);
453 while (access && (access->offset + access->size <= offset))
454 access = access->next_grp;
455 if (!access)
456 return NULL;
457
458 return find_access_in_subtree (access, offset, size);
459 }
460
461 /* Add LINK to the linked list of assign links of RACC. */
462 static void
463 add_link_to_rhs (struct access *racc, struct assign_link *link)
464 {
465 gcc_assert (link->racc == racc);
466
467 if (!racc->first_link)
468 {
469 gcc_assert (!racc->last_link);
470 racc->first_link = link;
471 }
472 else
473 racc->last_link->next = link;
474
475 racc->last_link = link;
476 link->next = NULL;
477 }
478
479 /* Move all link structures in their linked list in OLD_RACC to the linked list
480 in NEW_RACC. */
481 static void
482 relink_to_new_repr (struct access *new_racc, struct access *old_racc)
483 {
484 if (!old_racc->first_link)
485 {
486 gcc_assert (!old_racc->last_link);
487 return;
488 }
489
490 if (new_racc->first_link)
491 {
492 gcc_assert (!new_racc->last_link->next);
493 gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
494
495 new_racc->last_link->next = old_racc->first_link;
496 new_racc->last_link = old_racc->last_link;
497 }
498 else
499 {
500 gcc_assert (!new_racc->last_link);
501
502 new_racc->first_link = old_racc->first_link;
503 new_racc->last_link = old_racc->last_link;
504 }
505 old_racc->first_link = old_racc->last_link = NULL;
506 }
507
508 /* Add ACCESS to the work queue (which is actually a stack). */
509
510 static void
511 add_access_to_work_queue (struct access *access)
512 {
513 if (!access->grp_queued)
514 {
515 gcc_assert (!access->next_queued);
516 access->next_queued = work_queue_head;
517 access->grp_queued = 1;
518 work_queue_head = access;
519 }
520 }
521
522 /* Pop an access from the work queue, and return it, assuming there is one. */
523
524 static struct access *
525 pop_access_from_work_queue (void)
526 {
527 struct access *access = work_queue_head;
528
529 work_queue_head = access->next_queued;
530 access->next_queued = NULL;
531 access->grp_queued = 0;
532 return access;
533 }
534
535
536 /* Allocate necessary structures. */
537
538 static void
539 sra_initialize (void)
540 {
541 candidate_bitmap = BITMAP_ALLOC (NULL);
542 gcc_obstack_init (&name_obstack);
543 access_pool = create_alloc_pool ("SRA accesses", sizeof (struct access), 16);
544 link_pool = create_alloc_pool ("SRA links", sizeof (struct assign_link), 16);
545 base_access_vec = pointer_map_create ();
546 memset (&sra_stats, 0, sizeof (sra_stats));
547 encountered_apply_args = false;
548 }
549
550 /* Hook fed to pointer_map_traverse, deallocate stored vectors. */
551
552 static bool
553 delete_base_accesses (const void *key ATTRIBUTE_UNUSED, void **value,
554 void *data ATTRIBUTE_UNUSED)
555 {
556 VEC (access_p, heap) *access_vec;
557 access_vec = (VEC (access_p, heap) *) *value;
558 VEC_free (access_p, heap, access_vec);
559
560 return true;
561 }
562
563 /* Deallocate all general structures. */
564
565 static void
566 sra_deinitialize (void)
567 {
568 BITMAP_FREE (candidate_bitmap);
569 free_alloc_pool (access_pool);
570 free_alloc_pool (link_pool);
571 obstack_free (&name_obstack, NULL);
572
573 pointer_map_traverse (base_access_vec, delete_base_accesses, NULL);
574 pointer_map_destroy (base_access_vec);
575 }
576
577 /* Remove DECL from candidates for SRA and write REASON to the dump file if
578 there is one. */
579 static void
580 disqualify_candidate (tree decl, const char *reason)
581 {
582 bitmap_clear_bit (candidate_bitmap, DECL_UID (decl));
583
584 if (dump_file && (dump_flags & TDF_DETAILS))
585 {
586 fprintf (dump_file, "! Disqualifying ");
587 print_generic_expr (dump_file, decl, 0);
588 fprintf (dump_file, " - %s\n", reason);
589 }
590 }
591
592 /* Return true iff the type contains a field or an element which does not allow
593 scalarization. */
594
595 static bool
596 type_internals_preclude_sra_p (tree type)
597 {
598 tree fld;
599 tree et;
600
601 switch (TREE_CODE (type))
602 {
603 case RECORD_TYPE:
604 case UNION_TYPE:
605 case QUAL_UNION_TYPE:
606 for (fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
607 if (TREE_CODE (fld) == FIELD_DECL)
608 {
609 tree ft = TREE_TYPE (fld);
610
611 if (TREE_THIS_VOLATILE (fld)
612 || !DECL_FIELD_OFFSET (fld) || !DECL_SIZE (fld)
613 || !host_integerp (DECL_FIELD_OFFSET (fld), 1)
614 || !host_integerp (DECL_SIZE (fld), 1))
615 return true;
616
617 if (AGGREGATE_TYPE_P (ft)
618 && type_internals_preclude_sra_p (ft))
619 return true;
620 }
621
622 return false;
623
624 case ARRAY_TYPE:
625 et = TREE_TYPE (type);
626
627 if (AGGREGATE_TYPE_P (et))
628 return type_internals_preclude_sra_p (et);
629 else
630 return false;
631
632 default:
633 return false;
634 }
635 }
636
637 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
638 base variable if it is. Return T if it is not an SSA_NAME. */
639
640 static tree
641 get_ssa_base_param (tree t)
642 {
643 if (TREE_CODE (t) == SSA_NAME)
644 {
645 if (SSA_NAME_IS_DEFAULT_DEF (t))
646 return SSA_NAME_VAR (t);
647 else
648 return NULL_TREE;
649 }
650 return t;
651 }
652
653 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
654 belongs to, unless the BB has already been marked as a potentially
655 final. */
656
657 static void
658 mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple stmt)
659 {
660 basic_block bb = gimple_bb (stmt);
661 int idx, parm_index = 0;
662 tree parm;
663
664 if (bitmap_bit_p (final_bbs, bb->index))
665 return;
666
667 for (parm = DECL_ARGUMENTS (current_function_decl);
668 parm && parm != base;
669 parm = TREE_CHAIN (parm))
670 parm_index++;
671
672 gcc_assert (parm_index < func_param_count);
673
674 idx = bb->index * func_param_count + parm_index;
675 if (bb_dereferences[idx] < dist)
676 bb_dereferences[idx] = dist;
677 }
678
679 /* Create and insert access for EXPR. Return created access, or NULL if it is
680 not possible. */
681
682 static struct access *
683 create_access (tree expr, gimple stmt, bool write)
684 {
685 struct access *access;
686 void **slot;
687 VEC (access_p,heap) *vec;
688 HOST_WIDE_INT offset, size, max_size;
689 tree base = expr;
690 bool ptr, unscalarizable_region = false;
691
692 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
693
694 if (sra_mode == SRA_MODE_EARLY_IPA && INDIRECT_REF_P (base))
695 {
696 base = get_ssa_base_param (TREE_OPERAND (base, 0));
697 if (!base)
698 return NULL;
699 ptr = true;
700 }
701 else
702 ptr = false;
703
704 if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
705 return NULL;
706
707 if (sra_mode == SRA_MODE_EARLY_IPA)
708 {
709 if (size < 0 || size != max_size)
710 {
711 disqualify_candidate (base, "Encountered a variable sized access.");
712 return NULL;
713 }
714 if ((offset % BITS_PER_UNIT) != 0 || (size % BITS_PER_UNIT) != 0)
715 {
716 disqualify_candidate (base,
717 "Encountered an acces not aligned to a byte.");
718 return NULL;
719 }
720
721 if (ptr)
722 mark_parm_dereference (base, offset + size, stmt);
723 }
724 else
725 {
726 if (size != max_size)
727 {
728 size = max_size;
729 unscalarizable_region = true;
730 }
731 if (size < 0)
732 {
733 disqualify_candidate (base, "Encountered an unconstrained access.");
734 return NULL;
735 }
736 }
737
738 access = (struct access *) pool_alloc (access_pool);
739 memset (access, 0, sizeof (struct access));
740
741 access->base = base;
742 access->offset = offset;
743 access->size = size;
744 access->expr = expr;
745 access->type = TREE_TYPE (expr);
746 access->write = write;
747 access->grp_unscalarizable_region = unscalarizable_region;
748 access->stmt = stmt;
749
750 slot = pointer_map_contains (base_access_vec, base);
751 if (slot)
752 vec = (VEC (access_p, heap) *) *slot;
753 else
754 vec = VEC_alloc (access_p, heap, 32);
755
756 VEC_safe_push (access_p, heap, vec, access);
757
758 *((struct VEC (access_p,heap) **)
759 pointer_map_insert (base_access_vec, base)) = vec;
760
761 return access;
762 }
763
764
765 /* Search the given tree for a declaration by skipping handled components and
766 exclude it from the candidates. */
767
768 static void
769 disqualify_base_of_expr (tree t, const char *reason)
770 {
771 while (handled_component_p (t))
772 t = TREE_OPERAND (t, 0);
773
774 if (sra_mode == SRA_MODE_EARLY_IPA)
775 {
776 if (INDIRECT_REF_P (t))
777 t = TREE_OPERAND (t, 0);
778 t = get_ssa_base_param (t);
779 }
780
781 if (t && DECL_P (t))
782 disqualify_candidate (t, reason);
783 }
784
785 /* Scan expression EXPR and create access structures for all accesses to
786 candidates for scalarization. Return the created access or NULL if none is
787 created. */
788
789 static struct access *
790 build_access_from_expr_1 (tree *expr_ptr, gimple stmt, bool write)
791 {
792 struct access *ret = NULL;
793 tree expr = *expr_ptr;
794 bool partial_ref;
795
796 if (TREE_CODE (expr) == BIT_FIELD_REF
797 || TREE_CODE (expr) == IMAGPART_EXPR
798 || TREE_CODE (expr) == REALPART_EXPR)
799 {
800 expr = TREE_OPERAND (expr, 0);
801 partial_ref = true;
802 }
803 else
804 partial_ref = false;
805
806 /* We need to dive through V_C_Es in order to get the size of its parameter
807 and not the result type. Ada produces such statements. We are also
808 capable of handling the topmost V_C_E but not any of those buried in other
809 handled components. */
810 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
811 expr = TREE_OPERAND (expr, 0);
812
813 if (contains_view_convert_expr_p (expr))
814 {
815 disqualify_base_of_expr (expr, "V_C_E under a different handled "
816 "component.");
817 return NULL;
818 }
819
820 switch (TREE_CODE (expr))
821 {
822 case INDIRECT_REF:
823 if (sra_mode != SRA_MODE_EARLY_IPA)
824 return NULL;
825 /* fall through */
826 case VAR_DECL:
827 case PARM_DECL:
828 case RESULT_DECL:
829 case COMPONENT_REF:
830 case ARRAY_REF:
831 case ARRAY_RANGE_REF:
832 ret = create_access (expr, stmt, write);
833 break;
834
835 default:
836 break;
837 }
838
839 if (write && partial_ref && ret)
840 ret->grp_partial_lhs = 1;
841
842 return ret;
843 }
844
845 /* Callback of scan_function. Scan expression EXPR and create access
846 structures for all accesses to candidates for scalarization. Return true if
847 any access has been inserted. */
848
849 static bool
850 build_access_from_expr (tree *expr_ptr,
851 gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED, bool write,
852 void *data ATTRIBUTE_UNUSED)
853 {
854 return build_access_from_expr_1 (expr_ptr, gsi_stmt (*gsi), write) != NULL;
855 }
856
857 /* Disqualify LHS and RHS for scalarization if STMT must end its basic block in
858 modes in which it matters, return true iff they have been disqualified. RHS
859 may be NULL, in that case ignore it. If we scalarize an aggregate in
860 intra-SRA we may need to add statements after each statement. This is not
861 possible if a statement unconditionally has to end the basic block. */
862 static bool
863 disqualify_ops_if_throwing_stmt (gimple stmt, tree lhs, tree rhs)
864 {
865 if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
866 && (stmt_can_throw_internal (stmt) || stmt_ends_bb_p (stmt)))
867 {
868 disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
869 if (rhs)
870 disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
871 return true;
872 }
873 return false;
874 }
875
876
877 /* Result code for scan_assign callback for scan_function. */
878 enum scan_assign_result { SRA_SA_NONE, /* nothing done for the stmt */
879 SRA_SA_PROCESSED, /* stmt analyzed/changed */
880 SRA_SA_REMOVED }; /* stmt redundant and eliminated */
881
882
883 /* Callback of scan_function. Scan expressions occuring in the statement
884 pointed to by STMT_EXPR, create access structures for all accesses to
885 candidates for scalarization and remove those candidates which occur in
886 statements or expressions that prevent them from being split apart. Return
887 true if any access has been inserted. */
888
889 static enum scan_assign_result
890 build_accesses_from_assign (gimple *stmt_ptr,
891 gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
892 void *data ATTRIBUTE_UNUSED)
893 {
894 gimple stmt = *stmt_ptr;
895 tree *lhs_ptr, *rhs_ptr;
896 struct access *lacc, *racc;
897
898 if (!gimple_assign_single_p (stmt))
899 return SRA_SA_NONE;
900
901 lhs_ptr = gimple_assign_lhs_ptr (stmt);
902 rhs_ptr = gimple_assign_rhs1_ptr (stmt);
903
904 if (disqualify_ops_if_throwing_stmt (stmt, *lhs_ptr, *rhs_ptr))
905 return SRA_SA_NONE;
906
907 racc = build_access_from_expr_1 (rhs_ptr, stmt, false);
908 lacc = build_access_from_expr_1 (lhs_ptr, stmt, true);
909
910 if (lacc && racc
911 && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
912 && !lacc->grp_unscalarizable_region
913 && !racc->grp_unscalarizable_region
914 && AGGREGATE_TYPE_P (TREE_TYPE (*lhs_ptr))
915 /* FIXME: Turn the following line into an assert after PR 40058 is
916 fixed. */
917 && lacc->size == racc->size
918 && useless_type_conversion_p (lacc->type, racc->type))
919 {
920 struct assign_link *link;
921
922 link = (struct assign_link *) pool_alloc (link_pool);
923 memset (link, 0, sizeof (struct assign_link));
924
925 link->lacc = lacc;
926 link->racc = racc;
927
928 add_link_to_rhs (racc, link);
929 }
930
931 return (lacc || racc) ? SRA_SA_PROCESSED : SRA_SA_NONE;
932 }
933
934 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
935 GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
936
937 static bool
938 asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED, tree op,
939 void *data ATTRIBUTE_UNUSED)
940 {
941 if (DECL_P (op))
942 disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
943
944 return false;
945 }
946
947
948 /* Scan function and look for interesting statements. Return true if any has
949 been found or processed, as indicated by callbacks. SCAN_EXPR is a callback
950 called on all expressions within statements except assign statements and
951 those deemed entirely unsuitable for some reason (all operands in such
952 statements and expression are removed from candidate_bitmap). SCAN_ASSIGN
953 is a callback called on all assign statements, HANDLE_SSA_DEFS is a callback
954 called on assign statements and those call statements which have a lhs, it
955 can be NULL. ANALYSIS_STAGE is true when running in the analysis stage of a
956 pass and thus no statement is being modified. DATA is a pointer passed to
957 all callbacks. If any single callback returns true, this function also
958 returns true, otherwise it returns false. */
959
960 static bool
961 scan_function (bool (*scan_expr) (tree *, gimple_stmt_iterator *, bool, void *),
962 enum scan_assign_result (*scan_assign) (gimple *,
963 gimple_stmt_iterator *,
964 void *),
965 bool (*handle_ssa_defs)(gimple, void *),
966 bool analysis_stage, void *data)
967 {
968 gimple_stmt_iterator gsi;
969 basic_block bb;
970 unsigned i;
971 tree *t;
972 bool ret = false;
973
974 FOR_EACH_BB (bb)
975 {
976 bool bb_changed = false;
977
978 if (handle_ssa_defs)
979 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
980 ret |= handle_ssa_defs (gsi_stmt (gsi), data);
981
982 gsi = gsi_start_bb (bb);
983 while (!gsi_end_p (gsi))
984 {
985 gimple stmt = gsi_stmt (gsi);
986 enum scan_assign_result assign_result;
987 bool any = false, deleted = false;
988
989 if (analysis_stage && final_bbs && stmt_can_throw_external (stmt))
990 bitmap_set_bit (final_bbs, bb->index);
991 switch (gimple_code (stmt))
992 {
993 case GIMPLE_RETURN:
994 t = gimple_return_retval_ptr (stmt);
995 if (*t != NULL_TREE)
996 any |= scan_expr (t, &gsi, false, data);
997 if (analysis_stage && final_bbs)
998 bitmap_set_bit (final_bbs, bb->index);
999 break;
1000
1001 case GIMPLE_ASSIGN:
1002 assign_result = scan_assign (&stmt, &gsi, data);
1003 any |= assign_result == SRA_SA_PROCESSED;
1004 deleted = assign_result == SRA_SA_REMOVED;
1005 if (handle_ssa_defs && assign_result != SRA_SA_REMOVED)
1006 any |= handle_ssa_defs (stmt, data);
1007 break;
1008
1009 case GIMPLE_CALL:
1010 /* Operands must be processed before the lhs. */
1011 for (i = 0; i < gimple_call_num_args (stmt); i++)
1012 {
1013 tree *argp = gimple_call_arg_ptr (stmt, i);
1014 any |= scan_expr (argp, &gsi, false, data);
1015 }
1016
1017 if (analysis_stage)
1018 {
1019 tree dest = gimple_call_fndecl (stmt);
1020 int flags = gimple_call_flags (stmt);
1021
1022 if (dest
1023 && DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1024 && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1025 encountered_apply_args = true;
1026
1027 if (final_bbs
1028 && (flags & (ECF_CONST | ECF_PURE)) == 0)
1029 bitmap_set_bit (final_bbs, bb->index);
1030 }
1031
1032 if (gimple_call_lhs (stmt))
1033 {
1034 tree *lhs_ptr = gimple_call_lhs_ptr (stmt);
1035 if (!analysis_stage
1036 || !disqualify_ops_if_throwing_stmt (stmt,
1037 *lhs_ptr, NULL))
1038 {
1039 any |= scan_expr (lhs_ptr, &gsi, true, data);
1040 if (handle_ssa_defs)
1041 any |= handle_ssa_defs (stmt, data);
1042 }
1043 }
1044 break;
1045
1046 case GIMPLE_ASM:
1047 if (analysis_stage)
1048 {
1049 walk_stmt_load_store_addr_ops (stmt, NULL, NULL, NULL,
1050 asm_visit_addr);
1051 if (final_bbs)
1052 bitmap_set_bit (final_bbs, bb->index);
1053 }
1054 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
1055 {
1056 tree *op = &TREE_VALUE (gimple_asm_input_op (stmt, i));
1057 any |= scan_expr (op, &gsi, false, data);
1058 }
1059 for (i = 0; i < gimple_asm_noutputs (stmt); i++)
1060 {
1061 tree *op = &TREE_VALUE (gimple_asm_output_op (stmt, i));
1062 any |= scan_expr (op, &gsi, true, data);
1063 }
1064 break;
1065
1066 default:
1067 break;
1068 }
1069
1070 if (any)
1071 {
1072 ret = true;
1073
1074 if (!analysis_stage)
1075 {
1076 bb_changed = true;
1077 update_stmt (stmt);
1078 maybe_clean_eh_stmt (stmt);
1079 }
1080 }
1081 if (deleted)
1082 bb_changed = true;
1083 else
1084 {
1085 gsi_next (&gsi);
1086 ret = true;
1087 }
1088 }
1089 if (!analysis_stage && bb_changed && sra_mode == SRA_MODE_EARLY_IPA)
1090 gimple_purge_dead_eh_edges (bb);
1091 }
1092
1093 return ret;
1094 }
1095
1096 /* Helper of QSORT function. There are pointers to accesses in the array. An
1097 access is considered smaller than another if it has smaller offset or if the
1098 offsets are the same but is size is bigger. */
1099
1100 static int
1101 compare_access_positions (const void *a, const void *b)
1102 {
1103 const access_p *fp1 = (const access_p *) a;
1104 const access_p *fp2 = (const access_p *) b;
1105 const access_p f1 = *fp1;
1106 const access_p f2 = *fp2;
1107
1108 if (f1->offset != f2->offset)
1109 return f1->offset < f2->offset ? -1 : 1;
1110
1111 if (f1->size == f2->size)
1112 {
1113 /* Put any non-aggregate type before any aggregate type. */
1114 if (!is_gimple_reg_type (f1->type)
1115 && is_gimple_reg_type (f2->type))
1116 return 1;
1117 else if (is_gimple_reg_type (f1->type)
1118 && !is_gimple_reg_type (f2->type))
1119 return -1;
1120 /* Put the integral type with the bigger precision first. */
1121 else if (INTEGRAL_TYPE_P (f1->type)
1122 && INTEGRAL_TYPE_P (f2->type))
1123 return TYPE_PRECISION (f1->type) > TYPE_PRECISION (f2->type) ? -1 : 1;
1124 /* Put any integral type with non-full precision last. */
1125 else if (INTEGRAL_TYPE_P (f1->type)
1126 && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type))
1127 != TYPE_PRECISION (f1->type)))
1128 return 1;
1129 else if (INTEGRAL_TYPE_P (f2->type)
1130 && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type))
1131 != TYPE_PRECISION (f2->type)))
1132 return -1;
1133 /* Stabilize the sort. */
1134 return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1135 }
1136
1137 /* We want the bigger accesses first, thus the opposite operator in the next
1138 line: */
1139 return f1->size > f2->size ? -1 : 1;
1140 }
1141
1142
1143 /* Append a name of the declaration to the name obstack. A helper function for
1144 make_fancy_name. */
1145
1146 static void
1147 make_fancy_decl_name (tree decl)
1148 {
1149 char buffer[32];
1150
1151 tree name = DECL_NAME (decl);
1152 if (name)
1153 obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1154 IDENTIFIER_LENGTH (name));
1155 else
1156 {
1157 sprintf (buffer, "D%u", DECL_UID (decl));
1158 obstack_grow (&name_obstack, buffer, strlen (buffer));
1159 }
1160 }
1161
1162 /* Helper for make_fancy_name. */
1163
1164 static void
1165 make_fancy_name_1 (tree expr)
1166 {
1167 char buffer[32];
1168 tree index;
1169
1170 if (DECL_P (expr))
1171 {
1172 make_fancy_decl_name (expr);
1173 return;
1174 }
1175
1176 switch (TREE_CODE (expr))
1177 {
1178 case COMPONENT_REF:
1179 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1180 obstack_1grow (&name_obstack, '$');
1181 make_fancy_decl_name (TREE_OPERAND (expr, 1));
1182 break;
1183
1184 case ARRAY_REF:
1185 make_fancy_name_1 (TREE_OPERAND (expr, 0));
1186 obstack_1grow (&name_obstack, '$');
1187 /* Arrays with only one element may not have a constant as their
1188 index. */
1189 index = TREE_OPERAND (expr, 1);
1190 if (TREE_CODE (index) != INTEGER_CST)
1191 break;
1192 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1193 obstack_grow (&name_obstack, buffer, strlen (buffer));
1194
1195 break;
1196
1197 case BIT_FIELD_REF:
1198 case REALPART_EXPR:
1199 case IMAGPART_EXPR:
1200 gcc_unreachable (); /* we treat these as scalars. */
1201 break;
1202 default:
1203 break;
1204 }
1205 }
1206
1207 /* Create a human readable name for replacement variable of ACCESS. */
1208
1209 static char *
1210 make_fancy_name (tree expr)
1211 {
1212 make_fancy_name_1 (expr);
1213 obstack_1grow (&name_obstack, '\0');
1214 return XOBFINISH (&name_obstack, char *);
1215 }
1216
1217 /* Helper function for build_ref_for_offset. */
1218
1219 static bool
1220 build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset,
1221 tree exp_type)
1222 {
1223 while (1)
1224 {
1225 tree fld;
1226 tree tr_size, index, minidx;
1227 HOST_WIDE_INT el_size;
1228
1229 if (offset == 0 && exp_type
1230 && types_compatible_p (exp_type, type))
1231 return true;
1232
1233 switch (TREE_CODE (type))
1234 {
1235 case UNION_TYPE:
1236 case QUAL_UNION_TYPE:
1237 case RECORD_TYPE:
1238 for (fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
1239 {
1240 HOST_WIDE_INT pos, size;
1241 tree expr, *expr_ptr;
1242
1243 if (TREE_CODE (fld) != FIELD_DECL)
1244 continue;
1245
1246 pos = int_bit_position (fld);
1247 gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1248 tr_size = DECL_SIZE (fld);
1249 if (!tr_size || !host_integerp (tr_size, 1))
1250 continue;
1251 size = tree_low_cst (tr_size, 1);
1252 if (pos > offset || (pos + size) <= offset)
1253 continue;
1254
1255 if (res)
1256 {
1257 expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1258 NULL_TREE);
1259 expr_ptr = &expr;
1260 }
1261 else
1262 expr_ptr = NULL;
1263 if (build_ref_for_offset_1 (expr_ptr, TREE_TYPE (fld),
1264 offset - pos, exp_type))
1265 {
1266 if (res)
1267 *res = expr;
1268 return true;
1269 }
1270 }
1271 return false;
1272
1273 case ARRAY_TYPE:
1274 tr_size = TYPE_SIZE (TREE_TYPE (type));
1275 if (!tr_size || !host_integerp (tr_size, 1))
1276 return false;
1277 el_size = tree_low_cst (tr_size, 1);
1278
1279 minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1280 if (TREE_CODE (minidx) != INTEGER_CST)
1281 return false;
1282 if (res)
1283 {
1284 index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1285 if (!integer_zerop (minidx))
1286 index = int_const_binop (PLUS_EXPR, index, minidx, 0);
1287 *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1288 NULL_TREE, NULL_TREE);
1289 }
1290 offset = offset % el_size;
1291 type = TREE_TYPE (type);
1292 break;
1293
1294 default:
1295 if (offset != 0)
1296 return false;
1297
1298 if (exp_type)
1299 return false;
1300 else
1301 return true;
1302 }
1303 }
1304 }
1305
1306 /* Construct an expression that would reference a part of aggregate *EXPR of
1307 type TYPE at the given OFFSET of the type EXP_TYPE. If EXPR is NULL, the
1308 function only determines whether it can build such a reference without
1309 actually doing it, otherwise, the tree it points to is unshared first and
1310 then used as a base for furhter sub-references.
1311
1312 FIXME: Eventually this should be replaced with
1313 maybe_fold_offset_to_reference() from tree-ssa-ccp.c but that requires a
1314 minor rewrite of fold_stmt.
1315 */
1316
1317 bool
1318 build_ref_for_offset (tree *expr, tree type, HOST_WIDE_INT offset,
1319 tree exp_type, bool allow_ptr)
1320 {
1321 location_t loc = expr ? EXPR_LOCATION (*expr) : UNKNOWN_LOCATION;
1322
1323 if (expr)
1324 *expr = unshare_expr (*expr);
1325
1326 if (allow_ptr && POINTER_TYPE_P (type))
1327 {
1328 type = TREE_TYPE (type);
1329 if (expr)
1330 *expr = fold_build1_loc (loc, INDIRECT_REF, type, *expr);
1331 }
1332
1333 return build_ref_for_offset_1 (expr, type, offset, exp_type);
1334 }
1335
1336 /* Return true iff TYPE is stdarg va_list type. */
1337
1338 static inline bool
1339 is_va_list_type (tree type)
1340 {
1341 return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1342 }
1343
1344 /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
1345 those with type which is suitable for scalarization. */
1346
1347 static bool
1348 find_var_candidates (void)
1349 {
1350 tree var, type;
1351 referenced_var_iterator rvi;
1352 bool ret = false;
1353
1354 FOR_EACH_REFERENCED_VAR (var, rvi)
1355 {
1356 if (TREE_CODE (var) != VAR_DECL && TREE_CODE (var) != PARM_DECL)
1357 continue;
1358 type = TREE_TYPE (var);
1359
1360 if (!AGGREGATE_TYPE_P (type)
1361 || needs_to_live_in_memory (var)
1362 || TREE_THIS_VOLATILE (var)
1363 || !COMPLETE_TYPE_P (type)
1364 || !host_integerp (TYPE_SIZE (type), 1)
1365 || tree_low_cst (TYPE_SIZE (type), 1) == 0
1366 || type_internals_preclude_sra_p (type)
1367 /* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
1368 we also want to schedule it rather late. Thus we ignore it in
1369 the early pass. */
1370 || (sra_mode == SRA_MODE_EARLY_INTRA
1371 && is_va_list_type (type)))
1372 continue;
1373
1374 bitmap_set_bit (candidate_bitmap, DECL_UID (var));
1375
1376 if (dump_file && (dump_flags & TDF_DETAILS))
1377 {
1378 fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
1379 print_generic_expr (dump_file, var, 0);
1380 fprintf (dump_file, "\n");
1381 }
1382 ret = true;
1383 }
1384
1385 return ret;
1386 }
1387
1388 /* Sort all accesses for the given variable, check for partial overlaps and
1389 return NULL if there are any. If there are none, pick a representative for
1390 each combination of offset and size and create a linked list out of them.
1391 Return the pointer to the first representative and make sure it is the first
1392 one in the vector of accesses. */
1393
1394 static struct access *
1395 sort_and_splice_var_accesses (tree var)
1396 {
1397 int i, j, access_count;
1398 struct access *res, **prev_acc_ptr = &res;
1399 VEC (access_p, heap) *access_vec;
1400 bool first = true;
1401 HOST_WIDE_INT low = -1, high = 0;
1402
1403 access_vec = get_base_access_vector (var);
1404 if (!access_vec)
1405 return NULL;
1406 access_count = VEC_length (access_p, access_vec);
1407
1408 /* Sort by <OFFSET, SIZE>. */
1409 qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
1410 compare_access_positions);
1411
1412 i = 0;
1413 while (i < access_count)
1414 {
1415 struct access *access = VEC_index (access_p, access_vec, i);
1416 bool grp_write = access->write;
1417 bool grp_read = !access->write;
1418 bool multiple_reads = false;
1419 bool grp_partial_lhs = access->grp_partial_lhs;
1420 bool first_scalar = is_gimple_reg_type (access->type);
1421 bool unscalarizable_region = access->grp_unscalarizable_region;
1422
1423 if (first || access->offset >= high)
1424 {
1425 first = false;
1426 low = access->offset;
1427 high = access->offset + access->size;
1428 }
1429 else if (access->offset > low && access->offset + access->size > high)
1430 return NULL;
1431 else
1432 gcc_assert (access->offset >= low
1433 && access->offset + access->size <= high);
1434
1435 j = i + 1;
1436 while (j < access_count)
1437 {
1438 struct access *ac2 = VEC_index (access_p, access_vec, j);
1439 if (ac2->offset != access->offset || ac2->size != access->size)
1440 break;
1441 if (ac2->write)
1442 grp_write = true;
1443 else
1444 {
1445 if (grp_read)
1446 multiple_reads = true;
1447 else
1448 grp_read = true;
1449 }
1450 grp_partial_lhs |= ac2->grp_partial_lhs;
1451 unscalarizable_region |= ac2->grp_unscalarizable_region;
1452 relink_to_new_repr (access, ac2);
1453
1454 /* If there are both aggregate-type and scalar-type accesses with
1455 this combination of size and offset, the comparison function
1456 should have put the scalars first. */
1457 gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
1458 ac2->group_representative = access;
1459 j++;
1460 }
1461
1462 i = j;
1463
1464 access->group_representative = access;
1465 access->grp_write = grp_write;
1466 access->grp_read = grp_read;
1467 access->grp_hint = multiple_reads;
1468 access->grp_partial_lhs = grp_partial_lhs;
1469 access->grp_unscalarizable_region = unscalarizable_region;
1470 if (access->first_link)
1471 add_access_to_work_queue (access);
1472
1473 *prev_acc_ptr = access;
1474 prev_acc_ptr = &access->next_grp;
1475 }
1476
1477 gcc_assert (res == VEC_index (access_p, access_vec, 0));
1478 return res;
1479 }
1480
1481 /* Create a variable for the given ACCESS which determines the type, name and a
1482 few other properties. Return the variable declaration and store it also to
1483 ACCESS->replacement. */
1484
1485 static tree
1486 create_access_replacement (struct access *access)
1487 {
1488 tree repl;
1489
1490 repl = create_tmp_var (access->type, "SR");
1491 get_var_ann (repl);
1492 add_referenced_var (repl);
1493 mark_sym_for_renaming (repl);
1494
1495 if (!access->grp_partial_lhs
1496 && (TREE_CODE (access->type) == COMPLEX_TYPE
1497 || TREE_CODE (access->type) == VECTOR_TYPE))
1498 DECL_GIMPLE_REG_P (repl) = 1;
1499
1500 DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
1501 DECL_ARTIFICIAL (repl) = 1;
1502
1503 if (DECL_NAME (access->base)
1504 && !DECL_IGNORED_P (access->base)
1505 && !DECL_ARTIFICIAL (access->base))
1506 {
1507 char *pretty_name = make_fancy_name (access->expr);
1508
1509 DECL_NAME (repl) = get_identifier (pretty_name);
1510 obstack_free (&name_obstack, pretty_name);
1511
1512 SET_DECL_DEBUG_EXPR (repl, access->expr);
1513 DECL_DEBUG_EXPR_IS_FROM (repl) = 1;
1514 DECL_IGNORED_P (repl) = 0;
1515 }
1516
1517 DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
1518 TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
1519
1520 if (dump_file)
1521 {
1522 fprintf (dump_file, "Created a replacement for ");
1523 print_generic_expr (dump_file, access->base, 0);
1524 fprintf (dump_file, " offset: %u, size: %u: ",
1525 (unsigned) access->offset, (unsigned) access->size);
1526 print_generic_expr (dump_file, repl, 0);
1527 fprintf (dump_file, "\n");
1528 }
1529 sra_stats.replacements++;
1530
1531 return repl;
1532 }
1533
1534 /* Return ACCESS scalar replacement, create it if it does not exist yet. */
1535
1536 static inline tree
1537 get_access_replacement (struct access *access)
1538 {
1539 gcc_assert (access->grp_to_be_replaced);
1540
1541 if (!access->replacement_decl)
1542 access->replacement_decl = create_access_replacement (access);
1543 return access->replacement_decl;
1544 }
1545
1546 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
1547 linked list along the way. Stop when *ACCESS is NULL or the access pointed
1548 to it is not "within" the root. */
1549
1550 static void
1551 build_access_subtree (struct access **access)
1552 {
1553 struct access *root = *access, *last_child = NULL;
1554 HOST_WIDE_INT limit = root->offset + root->size;
1555
1556 *access = (*access)->next_grp;
1557 while (*access && (*access)->offset + (*access)->size <= limit)
1558 {
1559 if (!last_child)
1560 root->first_child = *access;
1561 else
1562 last_child->next_sibling = *access;
1563 last_child = *access;
1564
1565 build_access_subtree (access);
1566 }
1567 }
1568
1569 /* Build a tree of access representatives, ACCESS is the pointer to the first
1570 one, others are linked in a list by the next_grp field. Decide about scalar
1571 replacements on the way, return true iff any are to be created. */
1572
1573 static void
1574 build_access_trees (struct access *access)
1575 {
1576 while (access)
1577 {
1578 struct access *root = access;
1579
1580 build_access_subtree (&access);
1581 root->next_grp = access;
1582 }
1583 }
1584
1585 /* Return true if expr contains some ARRAY_REFs into a variable bounded
1586 array. */
1587
1588 static bool
1589 expr_with_var_bounded_array_refs_p (tree expr)
1590 {
1591 while (handled_component_p (expr))
1592 {
1593 if (TREE_CODE (expr) == ARRAY_REF
1594 && !host_integerp (array_ref_low_bound (expr), 0))
1595 return true;
1596 expr = TREE_OPERAND (expr, 0);
1597 }
1598 return false;
1599 }
1600
1601 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
1602 both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set
1603 all sorts of access flags appropriately along the way, notably always ser
1604 grp_read when MARK_READ is true and grp_write when MARK_WRITE is true. */
1605
1606 static bool
1607 analyze_access_subtree (struct access *root, bool allow_replacements,
1608 bool mark_read, bool mark_write)
1609 {
1610 struct access *child;
1611 HOST_WIDE_INT limit = root->offset + root->size;
1612 HOST_WIDE_INT covered_to = root->offset;
1613 bool scalar = is_gimple_reg_type (root->type);
1614 bool hole = false, sth_created = false;
1615 bool direct_read = root->grp_read;
1616
1617 if (mark_read)
1618 root->grp_read = true;
1619 else if (root->grp_read)
1620 mark_read = true;
1621
1622 if (mark_write)
1623 root->grp_write = true;
1624 else if (root->grp_write)
1625 mark_write = true;
1626
1627 if (root->grp_unscalarizable_region)
1628 allow_replacements = false;
1629
1630 if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
1631 allow_replacements = false;
1632
1633 for (child = root->first_child; child; child = child->next_sibling)
1634 {
1635 if (!hole && child->offset < covered_to)
1636 hole = true;
1637 else
1638 covered_to += child->size;
1639
1640 sth_created |= analyze_access_subtree (child, allow_replacements,
1641 mark_read, mark_write);
1642
1643 root->grp_unscalarized_data |= child->grp_unscalarized_data;
1644 hole |= !child->grp_covered;
1645 }
1646
1647 if (allow_replacements && scalar && !root->first_child
1648 && (root->grp_hint
1649 || (direct_read && root->grp_write)))
1650 {
1651 if (dump_file && (dump_flags & TDF_DETAILS))
1652 {
1653 fprintf (dump_file, "Marking ");
1654 print_generic_expr (dump_file, root->base, 0);
1655 fprintf (dump_file, " offset: %u, size: %u: ",
1656 (unsigned) root->offset, (unsigned) root->size);
1657 fprintf (dump_file, " to be replaced.\n");
1658 }
1659
1660 root->grp_to_be_replaced = 1;
1661 sth_created = true;
1662 hole = false;
1663 }
1664 else if (covered_to < limit)
1665 hole = true;
1666
1667 if (sth_created && !hole)
1668 {
1669 root->grp_covered = 1;
1670 return true;
1671 }
1672 if (root->grp_write || TREE_CODE (root->base) == PARM_DECL)
1673 root->grp_unscalarized_data = 1; /* not covered and written to */
1674 if (sth_created)
1675 return true;
1676 return false;
1677 }
1678
1679 /* Analyze all access trees linked by next_grp by the means of
1680 analyze_access_subtree. */
1681 static bool
1682 analyze_access_trees (struct access *access)
1683 {
1684 bool ret = false;
1685
1686 while (access)
1687 {
1688 if (analyze_access_subtree (access, true, false, false))
1689 ret = true;
1690 access = access->next_grp;
1691 }
1692
1693 return ret;
1694 }
1695
1696 /* Return true iff a potential new child of LACC at offset OFFSET and with size
1697 SIZE would conflict with an already existing one. If exactly such a child
1698 already exists in LACC, store a pointer to it in EXACT_MATCH. */
1699
1700 static bool
1701 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
1702 HOST_WIDE_INT size, struct access **exact_match)
1703 {
1704 struct access *child;
1705
1706 for (child = lacc->first_child; child; child = child->next_sibling)
1707 {
1708 if (child->offset == norm_offset && child->size == size)
1709 {
1710 *exact_match = child;
1711 return true;
1712 }
1713
1714 if (child->offset < norm_offset + size
1715 && child->offset + child->size > norm_offset)
1716 return true;
1717 }
1718
1719 return false;
1720 }
1721
1722 /* Create a new child access of PARENT, with all properties just like MODEL
1723 except for its offset and with its grp_write false and grp_read true.
1724 Return the new access or NULL if it cannot be created. Note that this access
1725 is created long after all splicing and sorting, it's not located in any
1726 access vector and is automatically a representative of its group. */
1727
1728 static struct access *
1729 create_artificial_child_access (struct access *parent, struct access *model,
1730 HOST_WIDE_INT new_offset)
1731 {
1732 struct access *access;
1733 struct access **child;
1734 tree expr = parent->base;;
1735
1736 gcc_assert (!model->grp_unscalarizable_region);
1737
1738 if (!build_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
1739 model->type, false))
1740 return NULL;
1741
1742 access = (struct access *) pool_alloc (access_pool);
1743 memset (access, 0, sizeof (struct access));
1744 access->base = parent->base;
1745 access->expr = expr;
1746 access->offset = new_offset;
1747 access->size = model->size;
1748 access->type = model->type;
1749 access->grp_write = true;
1750 access->grp_read = false;
1751
1752 child = &parent->first_child;
1753 while (*child && (*child)->offset < new_offset)
1754 child = &(*child)->next_sibling;
1755
1756 access->next_sibling = *child;
1757 *child = access;
1758
1759 return access;
1760 }
1761
1762
1763 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
1764 true if any new subaccess was created. Additionally, if RACC is a scalar
1765 access but LACC is not, change the type of the latter, if possible. */
1766
1767 static bool
1768 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
1769 {
1770 struct access *rchild;
1771 HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
1772 bool ret = false;
1773
1774 if (is_gimple_reg_type (lacc->type)
1775 || lacc->grp_unscalarizable_region
1776 || racc->grp_unscalarizable_region)
1777 return false;
1778
1779 if (!lacc->first_child && !racc->first_child
1780 && is_gimple_reg_type (racc->type))
1781 {
1782 tree t = lacc->base;
1783
1784 if (build_ref_for_offset (&t, TREE_TYPE (t), lacc->offset, racc->type,
1785 false))
1786 {
1787 lacc->expr = t;
1788 lacc->type = racc->type;
1789 }
1790 return false;
1791 }
1792
1793 for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
1794 {
1795 struct access *new_acc = NULL;
1796 HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
1797
1798 if (rchild->grp_unscalarizable_region)
1799 continue;
1800
1801 if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
1802 &new_acc))
1803 {
1804 if (new_acc)
1805 {
1806 rchild->grp_hint = 1;
1807 new_acc->grp_hint |= new_acc->grp_read;
1808 if (rchild->first_child)
1809 ret |= propagate_subaccesses_across_link (new_acc, rchild);
1810 }
1811 continue;
1812 }
1813
1814 /* If a (part of) a union field is on the RHS of an assignment, it can
1815 have sub-accesses which do not make sense on the LHS (PR 40351).
1816 Check that this is not the case. */
1817 if (!build_ref_for_offset (NULL, TREE_TYPE (lacc->base), norm_offset,
1818 rchild->type, false))
1819 continue;
1820
1821 rchild->grp_hint = 1;
1822 new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
1823 if (new_acc)
1824 {
1825 ret = true;
1826 if (racc->first_child)
1827 propagate_subaccesses_across_link (new_acc, rchild);
1828 }
1829 }
1830
1831 return ret;
1832 }
1833
1834 /* Propagate all subaccesses across assignment links. */
1835
1836 static void
1837 propagate_all_subaccesses (void)
1838 {
1839 while (work_queue_head)
1840 {
1841 struct access *racc = pop_access_from_work_queue ();
1842 struct assign_link *link;
1843
1844 gcc_assert (racc->first_link);
1845
1846 for (link = racc->first_link; link; link = link->next)
1847 {
1848 struct access *lacc = link->lacc;
1849
1850 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
1851 continue;
1852 lacc = lacc->group_representative;
1853 if (propagate_subaccesses_across_link (lacc, racc)
1854 && lacc->first_link)
1855 add_access_to_work_queue (lacc);
1856 }
1857 }
1858 }
1859
1860 /* Go through all accesses collected throughout the (intraprocedural) analysis
1861 stage, exclude overlapping ones, identify representatives and build trees
1862 out of them, making decisions about scalarization on the way. Return true
1863 iff there are any to-be-scalarized variables after this stage. */
1864
1865 static bool
1866 analyze_all_variable_accesses (void)
1867 {
1868 tree var;
1869 referenced_var_iterator rvi;
1870 int res = 0;
1871
1872 FOR_EACH_REFERENCED_VAR (var, rvi)
1873 if (bitmap_bit_p (candidate_bitmap, DECL_UID (var)))
1874 {
1875 struct access *access;
1876
1877 access = sort_and_splice_var_accesses (var);
1878 if (access)
1879 build_access_trees (access);
1880 else
1881 disqualify_candidate (var,
1882 "No or inhibitingly overlapping accesses.");
1883 }
1884
1885 propagate_all_subaccesses ();
1886
1887 FOR_EACH_REFERENCED_VAR (var, rvi)
1888 if (bitmap_bit_p (candidate_bitmap, DECL_UID (var)))
1889 {
1890 struct access *access = get_first_repr_for_decl (var);
1891
1892 if (analyze_access_trees (access))
1893 {
1894 res++;
1895 if (dump_file && (dump_flags & TDF_DETAILS))
1896 {
1897 fprintf (dump_file, "\nAccess trees for ");
1898 print_generic_expr (dump_file, var, 0);
1899 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
1900 dump_access_tree (dump_file, access);
1901 fprintf (dump_file, "\n");
1902 }
1903 }
1904 else
1905 disqualify_candidate (var, "No scalar replacements to be created.");
1906 }
1907
1908 if (res)
1909 {
1910 statistics_counter_event (cfun, "Scalarized aggregates", res);
1911 return true;
1912 }
1913 else
1914 return false;
1915 }
1916
1917 /* Return true iff a reference statement into aggregate AGG can be built for
1918 every single to-be-replaced accesses that is a child of ACCESS, its sibling
1919 or a child of its sibling. TOP_OFFSET is the offset from the processed
1920 access subtree that has to be subtracted from offset of each access. */
1921
1922 static bool
1923 ref_expr_for_all_replacements_p (struct access *access, tree agg,
1924 HOST_WIDE_INT top_offset)
1925 {
1926 do
1927 {
1928 if (access->grp_to_be_replaced
1929 && !build_ref_for_offset (NULL, TREE_TYPE (agg),
1930 access->offset - top_offset,
1931 access->type, false))
1932 return false;
1933
1934 if (access->first_child
1935 && !ref_expr_for_all_replacements_p (access->first_child, agg,
1936 top_offset))
1937 return false;
1938
1939 access = access->next_sibling;
1940 }
1941 while (access);
1942
1943 return true;
1944 }
1945
1946 /* Generate statements copying scalar replacements of accesses within a subtree
1947 into or out of AGG. ACCESS is the first child of the root of the subtree to
1948 be processed. AGG is an aggregate type expression (can be a declaration but
1949 does not have to be, it can for example also be an indirect_ref).
1950 TOP_OFFSET is the offset of the processed subtree which has to be subtracted
1951 from offsets of individual accesses to get corresponding offsets for AGG.
1952 If CHUNK_SIZE is non-null, copy only replacements in the interval
1953 <start_offset, start_offset + chunk_size>, otherwise copy all. GSI is a
1954 statement iterator used to place the new statements. WRITE should be true
1955 when the statements should write from AGG to the replacement and false if
1956 vice versa. if INSERT_AFTER is true, new statements will be added after the
1957 current statement in GSI, they will be added before the statement
1958 otherwise. */
1959
1960 static void
1961 generate_subtree_copies (struct access *access, tree agg,
1962 HOST_WIDE_INT top_offset,
1963 HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
1964 gimple_stmt_iterator *gsi, bool write,
1965 bool insert_after)
1966 {
1967 do
1968 {
1969 tree expr = agg;
1970
1971 if (chunk_size && access->offset >= start_offset + chunk_size)
1972 return;
1973
1974 if (access->grp_to_be_replaced
1975 && (chunk_size == 0
1976 || access->offset + access->size > start_offset))
1977 {
1978 tree repl = get_access_replacement (access);
1979 bool ref_found;
1980 gimple stmt;
1981
1982 ref_found = build_ref_for_offset (&expr, TREE_TYPE (agg),
1983 access->offset - top_offset,
1984 access->type, false);
1985 gcc_assert (ref_found);
1986
1987 if (write)
1988 {
1989 if (access->grp_partial_lhs)
1990 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
1991 !insert_after,
1992 insert_after ? GSI_NEW_STMT
1993 : GSI_SAME_STMT);
1994 stmt = gimple_build_assign (repl, expr);
1995 }
1996 else
1997 {
1998 TREE_NO_WARNING (repl) = 1;
1999 if (access->grp_partial_lhs)
2000 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2001 !insert_after,
2002 insert_after ? GSI_NEW_STMT
2003 : GSI_SAME_STMT);
2004 stmt = gimple_build_assign (expr, repl);
2005 }
2006
2007 if (insert_after)
2008 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2009 else
2010 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2011 update_stmt (stmt);
2012 sra_stats.subtree_copies++;
2013 }
2014
2015 if (access->first_child)
2016 generate_subtree_copies (access->first_child, agg, top_offset,
2017 start_offset, chunk_size, gsi,
2018 write, insert_after);
2019
2020 access = access->next_sibling;
2021 }
2022 while (access);
2023 }
2024
2025 /* Assign zero to all scalar replacements in an access subtree. ACCESS is the
2026 the root of the subtree to be processed. GSI is the statement iterator used
2027 for inserting statements which are added after the current statement if
2028 INSERT_AFTER is true or before it otherwise. */
2029
2030 static void
2031 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
2032 bool insert_after)
2033
2034 {
2035 struct access *child;
2036
2037 if (access->grp_to_be_replaced)
2038 {
2039 gimple stmt;
2040
2041 stmt = gimple_build_assign (get_access_replacement (access),
2042 fold_convert (access->type,
2043 integer_zero_node));
2044 if (insert_after)
2045 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2046 else
2047 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2048 update_stmt (stmt);
2049 }
2050
2051 for (child = access->first_child; child; child = child->next_sibling)
2052 init_subtree_with_zero (child, gsi, insert_after);
2053 }
2054
2055 /* Search for an access representative for the given expression EXPR and
2056 return it or NULL if it cannot be found. */
2057
2058 static struct access *
2059 get_access_for_expr (tree expr)
2060 {
2061 HOST_WIDE_INT offset, size, max_size;
2062 tree base;
2063
2064 /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2065 a different size than the size of its argument and we need the latter
2066 one. */
2067 if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
2068 expr = TREE_OPERAND (expr, 0);
2069
2070 base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
2071 if (max_size == -1 || !DECL_P (base))
2072 return NULL;
2073
2074 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
2075 return NULL;
2076
2077 return get_var_base_offset_size_access (base, offset, max_size);
2078 }
2079
2080 /* Callback for scan_function. Replace the expression EXPR with a scalar
2081 replacement if there is one and generate other statements to do type
2082 conversion or subtree copying if necessary. GSI is used to place newly
2083 created statements, WRITE is true if the expression is being written to (it
2084 is on a LHS of a statement or output in an assembly statement). */
2085
2086 static bool
2087 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write,
2088 void *data ATTRIBUTE_UNUSED)
2089 {
2090 struct access *access;
2091 tree type, bfr;
2092
2093 if (TREE_CODE (*expr) == BIT_FIELD_REF)
2094 {
2095 bfr = *expr;
2096 expr = &TREE_OPERAND (*expr, 0);
2097 }
2098 else
2099 bfr = NULL_TREE;
2100
2101 if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
2102 expr = &TREE_OPERAND (*expr, 0);
2103 access = get_access_for_expr (*expr);
2104 if (!access)
2105 return false;
2106 type = TREE_TYPE (*expr);
2107
2108 if (access->grp_to_be_replaced)
2109 {
2110 tree repl = get_access_replacement (access);
2111 /* If we replace a non-register typed access simply use the original
2112 access expression to extract the scalar component afterwards.
2113 This happens if scalarizing a function return value or parameter
2114 like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2115 gcc.c-torture/compile/20011217-1.c. */
2116 if (!is_gimple_reg_type (type))
2117 {
2118 tree ref = access->base;
2119 bool ok;
2120
2121 ok = build_ref_for_offset (&ref, TREE_TYPE (ref),
2122 access->offset, access->type, false);
2123 gcc_assert (ok);
2124
2125 if (write)
2126 {
2127 gimple stmt;
2128
2129 if (access->grp_partial_lhs)
2130 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
2131 false, GSI_NEW_STMT);
2132 stmt = gimple_build_assign (repl, ref);
2133 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2134 }
2135 else
2136 {
2137 gimple stmt;
2138
2139 if (access->grp_partial_lhs)
2140 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2141 true, GSI_SAME_STMT);
2142 stmt = gimple_build_assign (ref, repl);
2143 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2144 }
2145 }
2146 else
2147 {
2148 gcc_assert (useless_type_conversion_p (type, access->type));
2149 *expr = repl;
2150 }
2151 sra_stats.exprs++;
2152 }
2153
2154 if (access->first_child)
2155 {
2156 HOST_WIDE_INT start_offset, chunk_size;
2157 if (bfr
2158 && host_integerp (TREE_OPERAND (bfr, 1), 1)
2159 && host_integerp (TREE_OPERAND (bfr, 2), 1))
2160 {
2161 chunk_size = tree_low_cst (TREE_OPERAND (bfr, 1), 1);
2162 start_offset = access->offset
2163 + tree_low_cst (TREE_OPERAND (bfr, 2), 1);
2164 }
2165 else
2166 start_offset = chunk_size = 0;
2167
2168 generate_subtree_copies (access->first_child, access->base, 0,
2169 start_offset, chunk_size, gsi, write, write);
2170 }
2171 return true;
2172 }
2173
2174 /* Where scalar replacements of the RHS have been written to when a replacement
2175 of a LHS of an assigments cannot be direclty loaded from a replacement of
2176 the RHS. */
2177 enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
2178 SRA_UDH_RIGHT, /* Data flushed to the RHS. */
2179 SRA_UDH_LEFT }; /* Data flushed to the LHS. */
2180
2181 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2182 base aggregate if there are unscalarized data or directly to LHS
2183 otherwise. */
2184
2185 static enum unscalarized_data_handling
2186 handle_unscalarized_data_in_subtree (struct access *top_racc, tree lhs,
2187 gimple_stmt_iterator *gsi)
2188 {
2189 if (top_racc->grp_unscalarized_data)
2190 {
2191 generate_subtree_copies (top_racc->first_child, top_racc->base, 0, 0, 0,
2192 gsi, false, false);
2193 return SRA_UDH_RIGHT;
2194 }
2195 else
2196 {
2197 generate_subtree_copies (top_racc->first_child, lhs, top_racc->offset,
2198 0, 0, gsi, false, false);
2199 return SRA_UDH_LEFT;
2200 }
2201 }
2202
2203
2204 /* Try to generate statements to load all sub-replacements in an access
2205 (sub)tree (LACC is the first child) from scalar replacements in the TOP_RACC
2206 (sub)tree. If that is not possible, refresh the TOP_RACC base aggregate and
2207 load the accesses from it. LEFT_OFFSET is the offset of the left whole
2208 subtree being copied, RIGHT_OFFSET is the same thing for the right subtree.
2209 GSI is stmt iterator used for statement insertions. *REFRESHED is true iff
2210 the rhs top aggregate has already been refreshed by contents of its scalar
2211 reductions and is set to true if this function has to do it. */
2212
2213 static void
2214 load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
2215 HOST_WIDE_INT left_offset,
2216 HOST_WIDE_INT right_offset,
2217 gimple_stmt_iterator *old_gsi,
2218 gimple_stmt_iterator *new_gsi,
2219 enum unscalarized_data_handling *refreshed,
2220 tree lhs)
2221 {
2222 location_t loc = EXPR_LOCATION (lacc->expr);
2223 do
2224 {
2225 if (lacc->grp_to_be_replaced)
2226 {
2227 struct access *racc;
2228 HOST_WIDE_INT offset = lacc->offset - left_offset + right_offset;
2229 gimple stmt;
2230 tree rhs;
2231
2232 racc = find_access_in_subtree (top_racc, offset, lacc->size);
2233 if (racc && racc->grp_to_be_replaced)
2234 {
2235 rhs = get_access_replacement (racc);
2236 if (!useless_type_conversion_p (lacc->type, racc->type))
2237 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, lacc->type, rhs);
2238 }
2239 else
2240 {
2241 /* No suitable access on the right hand side, need to load from
2242 the aggregate. See if we have to update it first... */
2243 if (*refreshed == SRA_UDH_NONE)
2244 *refreshed = handle_unscalarized_data_in_subtree (top_racc,
2245 lhs, old_gsi);
2246
2247 if (*refreshed == SRA_UDH_LEFT)
2248 {
2249 bool repl_found;
2250
2251 rhs = lacc->base;
2252 repl_found = build_ref_for_offset (&rhs, TREE_TYPE (rhs),
2253 lacc->offset, lacc->type,
2254 false);
2255 gcc_assert (repl_found);
2256 }
2257 else
2258 {
2259 bool repl_found;
2260
2261 rhs = top_racc->base;
2262 repl_found = build_ref_for_offset (&rhs,
2263 TREE_TYPE (top_racc->base),
2264 offset, lacc->type, false);
2265 gcc_assert (repl_found);
2266 }
2267 }
2268
2269 stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
2270 gsi_insert_after (new_gsi, stmt, GSI_NEW_STMT);
2271 update_stmt (stmt);
2272 sra_stats.subreplacements++;
2273 }
2274 else if (*refreshed == SRA_UDH_NONE
2275 && lacc->grp_read && !lacc->grp_covered)
2276 *refreshed = handle_unscalarized_data_in_subtree (top_racc, lhs,
2277 old_gsi);
2278
2279 if (lacc->first_child)
2280 load_assign_lhs_subreplacements (lacc->first_child, top_racc,
2281 left_offset, right_offset,
2282 old_gsi, new_gsi, refreshed, lhs);
2283 lacc = lacc->next_sibling;
2284 }
2285 while (lacc);
2286 }
2287
2288 /* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
2289 to the assignment and GSI is the statement iterator pointing at it. Returns
2290 the same values as sra_modify_assign. */
2291
2292 static enum scan_assign_result
2293 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
2294 {
2295 tree lhs = gimple_assign_lhs (*stmt);
2296 struct access *acc;
2297
2298 acc = get_access_for_expr (lhs);
2299 if (!acc)
2300 return SRA_SA_NONE;
2301
2302 if (VEC_length (constructor_elt,
2303 CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt))) > 0)
2304 {
2305 /* I have never seen this code path trigger but if it can happen the
2306 following should handle it gracefully. */
2307 if (access_has_children_p (acc))
2308 generate_subtree_copies (acc->first_child, acc->base, 0, 0, 0, gsi,
2309 true, true);
2310 return SRA_SA_PROCESSED;
2311 }
2312
2313 if (acc->grp_covered)
2314 {
2315 init_subtree_with_zero (acc, gsi, false);
2316 unlink_stmt_vdef (*stmt);
2317 gsi_remove (gsi, true);
2318 return SRA_SA_REMOVED;
2319 }
2320 else
2321 {
2322 init_subtree_with_zero (acc, gsi, true);
2323 return SRA_SA_PROCESSED;
2324 }
2325 }
2326
2327
2328 /* Callback of scan_function to process assign statements. It examines both
2329 sides of the statement, replaces them with a scalare replacement if there is
2330 one and generating copying of replacements if scalarized aggregates have been
2331 used in the assignment. STMT is a pointer to the assign statement, GSI is
2332 used to hold generated statements for type conversions and subtree
2333 copying. */
2334
2335 static enum scan_assign_result
2336 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi,
2337 void *data ATTRIBUTE_UNUSED)
2338 {
2339 struct access *lacc, *racc;
2340 tree lhs, rhs;
2341 bool modify_this_stmt = false;
2342 bool force_gimple_rhs = false;
2343 location_t loc = gimple_location (*stmt);
2344
2345 if (!gimple_assign_single_p (*stmt))
2346 return SRA_SA_NONE;
2347 lhs = gimple_assign_lhs (*stmt);
2348 rhs = gimple_assign_rhs1 (*stmt);
2349
2350 if (TREE_CODE (rhs) == CONSTRUCTOR)
2351 return sra_modify_constructor_assign (stmt, gsi);
2352
2353 if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
2354 || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
2355 || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
2356 {
2357 modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (*stmt),
2358 gsi, false, data);
2359 modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (*stmt),
2360 gsi, true, data);
2361 return modify_this_stmt ? SRA_SA_PROCESSED : SRA_SA_NONE;
2362 }
2363
2364 lacc = get_access_for_expr (lhs);
2365 racc = get_access_for_expr (rhs);
2366 if (!lacc && !racc)
2367 return SRA_SA_NONE;
2368
2369 if (lacc && lacc->grp_to_be_replaced)
2370 {
2371 lhs = get_access_replacement (lacc);
2372 gimple_assign_set_lhs (*stmt, lhs);
2373 modify_this_stmt = true;
2374 if (lacc->grp_partial_lhs)
2375 force_gimple_rhs = true;
2376 sra_stats.exprs++;
2377 }
2378
2379 if (racc && racc->grp_to_be_replaced)
2380 {
2381 rhs = get_access_replacement (racc);
2382 modify_this_stmt = true;
2383 if (racc->grp_partial_lhs)
2384 force_gimple_rhs = true;
2385 sra_stats.exprs++;
2386 }
2387
2388 if (modify_this_stmt)
2389 {
2390 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
2391 {
2392 /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
2393 ??? This should move to fold_stmt which we simply should
2394 call after building a VIEW_CONVERT_EXPR here. */
2395 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
2396 && !access_has_children_p (lacc))
2397 {
2398 tree expr = lhs;
2399 if (build_ref_for_offset (&expr, TREE_TYPE (lhs), 0,
2400 TREE_TYPE (rhs), false))
2401 {
2402 lhs = expr;
2403 gimple_assign_set_lhs (*stmt, expr);
2404 }
2405 }
2406 else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
2407 && !access_has_children_p (racc))
2408 {
2409 tree expr = rhs;
2410 if (build_ref_for_offset (&expr, TREE_TYPE (rhs), 0,
2411 TREE_TYPE (lhs), false))
2412 rhs = expr;
2413 }
2414 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
2415 {
2416 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs);
2417 if (!is_gimple_reg (lhs))
2418 force_gimple_rhs = true;
2419 }
2420 }
2421
2422 if (force_gimple_rhs)
2423 rhs = force_gimple_operand_gsi (gsi, rhs, true, NULL_TREE,
2424 true, GSI_SAME_STMT);
2425 if (gimple_assign_rhs1 (*stmt) != rhs)
2426 {
2427 gimple_assign_set_rhs_from_tree (gsi, rhs);
2428 gcc_assert (*stmt == gsi_stmt (*gsi));
2429 }
2430 }
2431
2432 /* From this point on, the function deals with assignments in between
2433 aggregates when at least one has scalar reductions of some of its
2434 components. There are three possible scenarios: Both the LHS and RHS have
2435 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
2436
2437 In the first case, we would like to load the LHS components from RHS
2438 components whenever possible. If that is not possible, we would like to
2439 read it directly from the RHS (after updating it by storing in it its own
2440 components). If there are some necessary unscalarized data in the LHS,
2441 those will be loaded by the original assignment too. If neither of these
2442 cases happen, the original statement can be removed. Most of this is done
2443 by load_assign_lhs_subreplacements.
2444
2445 In the second case, we would like to store all RHS scalarized components
2446 directly into LHS and if they cover the aggregate completely, remove the
2447 statement too. In the third case, we want the LHS components to be loaded
2448 directly from the RHS (DSE will remove the original statement if it
2449 becomes redundant).
2450
2451 This is a bit complex but manageable when types match and when unions do
2452 not cause confusion in a way that we cannot really load a component of LHS
2453 from the RHS or vice versa (the access representing this level can have
2454 subaccesses that are accessible only through a different union field at a
2455 higher level - different from the one used in the examined expression).
2456 Unions are fun.
2457
2458 Therefore, I specially handle a fourth case, happening when there is a
2459 specific type cast or it is impossible to locate a scalarized subaccess on
2460 the other side of the expression. If that happens, I simply "refresh" the
2461 RHS by storing in it is scalarized components leave the original statement
2462 there to do the copying and then load the scalar replacements of the LHS.
2463 This is what the first branch does. */
2464
2465 if (contains_view_convert_expr_p (rhs) || contains_view_convert_expr_p (lhs)
2466 || (access_has_children_p (racc)
2467 && !ref_expr_for_all_replacements_p (racc, lhs, racc->offset))
2468 || (access_has_children_p (lacc)
2469 && !ref_expr_for_all_replacements_p (lacc, rhs, lacc->offset)))
2470 {
2471 if (access_has_children_p (racc))
2472 generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
2473 gsi, false, false);
2474 if (access_has_children_p (lacc))
2475 generate_subtree_copies (lacc->first_child, lacc->base, 0, 0, 0,
2476 gsi, true, true);
2477 sra_stats.separate_lhs_rhs_handling++;
2478 }
2479 else
2480 {
2481 if (access_has_children_p (lacc) && access_has_children_p (racc))
2482 {
2483 gimple_stmt_iterator orig_gsi = *gsi;
2484 enum unscalarized_data_handling refreshed;
2485
2486 if (lacc->grp_read && !lacc->grp_covered)
2487 refreshed = handle_unscalarized_data_in_subtree (racc, lhs, gsi);
2488 else
2489 refreshed = SRA_UDH_NONE;
2490
2491 load_assign_lhs_subreplacements (lacc->first_child, racc,
2492 lacc->offset, racc->offset,
2493 &orig_gsi, gsi, &refreshed, lhs);
2494 if (refreshed != SRA_UDH_RIGHT)
2495 {
2496 if (*stmt == gsi_stmt (*gsi))
2497 gsi_next (gsi);
2498
2499 unlink_stmt_vdef (*stmt);
2500 gsi_remove (&orig_gsi, true);
2501 sra_stats.deleted++;
2502 return SRA_SA_REMOVED;
2503 }
2504 }
2505 else
2506 {
2507 if (access_has_children_p (racc))
2508 {
2509 if (!racc->grp_unscalarized_data)
2510 {
2511 generate_subtree_copies (racc->first_child, lhs,
2512 racc->offset, 0, 0, gsi,
2513 false, false);
2514 gcc_assert (*stmt == gsi_stmt (*gsi));
2515 unlink_stmt_vdef (*stmt);
2516 gsi_remove (gsi, true);
2517 sra_stats.deleted++;
2518 return SRA_SA_REMOVED;
2519 }
2520 else
2521 generate_subtree_copies (racc->first_child, lhs,
2522 racc->offset, 0, 0, gsi, false, true);
2523 }
2524 else if (access_has_children_p (lacc))
2525 generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
2526 0, 0, gsi, true, true);
2527 }
2528 }
2529 return modify_this_stmt ? SRA_SA_PROCESSED : SRA_SA_NONE;
2530 }
2531
2532 /* Generate statements initializing scalar replacements of parts of function
2533 parameters. */
2534
2535 static void
2536 initialize_parameter_reductions (void)
2537 {
2538 gimple_stmt_iterator gsi;
2539 gimple_seq seq = NULL;
2540 tree parm;
2541
2542 for (parm = DECL_ARGUMENTS (current_function_decl);
2543 parm;
2544 parm = TREE_CHAIN (parm))
2545 {
2546 VEC (access_p, heap) *access_vec;
2547 struct access *access;
2548
2549 if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
2550 continue;
2551 access_vec = get_base_access_vector (parm);
2552 if (!access_vec)
2553 continue;
2554
2555 if (!seq)
2556 {
2557 seq = gimple_seq_alloc ();
2558 gsi = gsi_start (seq);
2559 }
2560
2561 for (access = VEC_index (access_p, access_vec, 0);
2562 access;
2563 access = access->next_grp)
2564 generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true);
2565 }
2566
2567 if (seq)
2568 gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR), seq);
2569 }
2570
2571 /* The "main" function of intraprocedural SRA passes. Runs the analysis and if
2572 it reveals there are components of some aggregates to be scalarized, it runs
2573 the required transformations. */
2574 static unsigned int
2575 perform_intra_sra (void)
2576 {
2577 int ret = 0;
2578 sra_initialize ();
2579
2580 if (!find_var_candidates ())
2581 goto out;
2582
2583 if (!scan_function (build_access_from_expr, build_accesses_from_assign, NULL,
2584 true, NULL))
2585 goto out;
2586
2587 if (!analyze_all_variable_accesses ())
2588 goto out;
2589
2590 scan_function (sra_modify_expr, sra_modify_assign, NULL, false, NULL);
2591 initialize_parameter_reductions ();
2592
2593 statistics_counter_event (cfun, "Scalar replacements created",
2594 sra_stats.replacements);
2595 statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
2596 statistics_counter_event (cfun, "Subtree copy stmts",
2597 sra_stats.subtree_copies);
2598 statistics_counter_event (cfun, "Subreplacement stmts",
2599 sra_stats.subreplacements);
2600 statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
2601 statistics_counter_event (cfun, "Separate LHS and RHS handling",
2602 sra_stats.separate_lhs_rhs_handling);
2603
2604 ret = TODO_update_ssa;
2605
2606 out:
2607 sra_deinitialize ();
2608 return ret;
2609 }
2610
2611 /* Perform early intraprocedural SRA. */
2612 static unsigned int
2613 early_intra_sra (void)
2614 {
2615 sra_mode = SRA_MODE_EARLY_INTRA;
2616 return perform_intra_sra ();
2617 }
2618
2619 /* Perform "late" intraprocedural SRA. */
2620 static unsigned int
2621 late_intra_sra (void)
2622 {
2623 sra_mode = SRA_MODE_INTRA;
2624 return perform_intra_sra ();
2625 }
2626
2627
2628 static bool
2629 gate_intra_sra (void)
2630 {
2631 return flag_tree_sra != 0;
2632 }
2633
2634
2635 struct gimple_opt_pass pass_sra_early =
2636 {
2637 {
2638 GIMPLE_PASS,
2639 "esra", /* name */
2640 gate_intra_sra, /* gate */
2641 early_intra_sra, /* execute */
2642 NULL, /* sub */
2643 NULL, /* next */
2644 0, /* static_pass_number */
2645 TV_TREE_SRA, /* tv_id */
2646 PROP_cfg | PROP_ssa, /* properties_required */
2647 0, /* properties_provided */
2648 0, /* properties_destroyed */
2649 0, /* todo_flags_start */
2650 TODO_dump_func
2651 | TODO_update_ssa
2652 | TODO_ggc_collect
2653 | TODO_verify_ssa /* todo_flags_finish */
2654 }
2655 };
2656
2657 struct gimple_opt_pass pass_sra =
2658 {
2659 {
2660 GIMPLE_PASS,
2661 "sra", /* name */
2662 gate_intra_sra, /* gate */
2663 late_intra_sra, /* execute */
2664 NULL, /* sub */
2665 NULL, /* next */
2666 0, /* static_pass_number */
2667 TV_TREE_SRA, /* tv_id */
2668 PROP_cfg | PROP_ssa, /* properties_required */
2669 0, /* properties_provided */
2670 0, /* properties_destroyed */
2671 TODO_update_address_taken, /* todo_flags_start */
2672 TODO_dump_func
2673 | TODO_update_ssa
2674 | TODO_ggc_collect
2675 | TODO_verify_ssa /* todo_flags_finish */
2676 }
2677 };
2678
2679
2680 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
2681 parameter. */
2682
2683 static bool
2684 is_unused_scalar_param (tree parm)
2685 {
2686 tree name;
2687 return (is_gimple_reg (parm)
2688 && (!(name = gimple_default_def (cfun, parm))
2689 || has_zero_uses (name)));
2690 }
2691
2692 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
2693 examine whether there are any direct or otherwise infeasible ones. If so,
2694 return true, otherwise return false. PARM must be a gimple register with a
2695 non-NULL default definition. */
2696
2697 static bool
2698 ptr_parm_has_direct_uses (tree parm)
2699 {
2700 imm_use_iterator ui;
2701 gimple stmt;
2702 tree name = gimple_default_def (cfun, parm);
2703 bool ret = false;
2704
2705 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
2706 {
2707 if (gimple_assign_single_p (stmt))
2708 {
2709 tree rhs = gimple_assign_rhs1 (stmt);
2710 if (rhs == name)
2711 ret = true;
2712 else if (TREE_CODE (rhs) == ADDR_EXPR)
2713 {
2714 do
2715 {
2716 rhs = TREE_OPERAND (rhs, 0);
2717 }
2718 while (handled_component_p (rhs));
2719 if (INDIRECT_REF_P (rhs) && TREE_OPERAND (rhs, 0) == name)
2720 ret = true;
2721 }
2722 }
2723 else if (gimple_code (stmt) == GIMPLE_RETURN)
2724 {
2725 tree t = gimple_return_retval (stmt);
2726 if (t == name)
2727 ret = true;
2728 }
2729 else if (is_gimple_call (stmt))
2730 {
2731 unsigned i;
2732 for (i = 0; i < gimple_call_num_args (stmt); i++)
2733 {
2734 tree arg = gimple_call_arg (stmt, i);
2735 if (arg == name)
2736 {
2737 ret = true;
2738 break;
2739 }
2740 }
2741 }
2742 else if (!is_gimple_debug (stmt))
2743 ret = true;
2744
2745 if (ret)
2746 BREAK_FROM_IMM_USE_STMT (ui);
2747 }
2748
2749 return ret;
2750 }
2751
2752 /* Identify candidates for reduction for IPA-SRA based on their type and mark
2753 them in candidate_bitmap. Note that these do not necessarily include
2754 parameter which are unused and thus can be removed. Return true iff any
2755 such candidate has been found. */
2756
2757 static bool
2758 find_param_candidates (void)
2759 {
2760 tree parm;
2761 int count = 0;
2762 bool ret = false;
2763
2764 for (parm = DECL_ARGUMENTS (current_function_decl);
2765 parm;
2766 parm = TREE_CHAIN (parm))
2767 {
2768 tree type = TREE_TYPE (parm);
2769
2770 count++;
2771
2772 if (TREE_THIS_VOLATILE (parm)
2773 || TREE_ADDRESSABLE (parm)
2774 || is_va_list_type (type))
2775 continue;
2776
2777 if (is_unused_scalar_param (parm))
2778 {
2779 ret = true;
2780 continue;
2781 }
2782
2783 if (POINTER_TYPE_P (type))
2784 {
2785 type = TREE_TYPE (type);
2786
2787 if (TREE_CODE (type) == FUNCTION_TYPE
2788 || TYPE_VOLATILE (type)
2789 || !is_gimple_reg (parm)
2790 || is_va_list_type (type)
2791 || ptr_parm_has_direct_uses (parm))
2792 continue;
2793 }
2794 else if (!AGGREGATE_TYPE_P (type))
2795 continue;
2796
2797 if (!COMPLETE_TYPE_P (type)
2798 || !host_integerp (TYPE_SIZE (type), 1)
2799 || tree_low_cst (TYPE_SIZE (type), 1) == 0
2800 || (AGGREGATE_TYPE_P (type)
2801 && type_internals_preclude_sra_p (type)))
2802 continue;
2803
2804 bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
2805 ret = true;
2806 if (dump_file && (dump_flags & TDF_DETAILS))
2807 {
2808 fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
2809 print_generic_expr (dump_file, parm, 0);
2810 fprintf (dump_file, "\n");
2811 }
2812 }
2813
2814 func_param_count = count;
2815 return ret;
2816 }
2817
2818 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
2819 maybe_modified. */
2820
2821 static bool
2822 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
2823 void *data)
2824 {
2825 struct access *repr = (struct access *) data;
2826
2827 repr->grp_maybe_modified = 1;
2828 return true;
2829 }
2830
2831 /* Analyze what representatives (in linked lists accessible from
2832 REPRESENTATIVES) can be modified by side effects of statements in the
2833 current function. */
2834
2835 static void
2836 analyze_modified_params (VEC (access_p, heap) *representatives)
2837 {
2838 int i;
2839
2840 for (i = 0; i < func_param_count; i++)
2841 {
2842 struct access *repr;
2843
2844 for (repr = VEC_index (access_p, representatives, i);
2845 repr;
2846 repr = repr->next_grp)
2847 {
2848 struct access *access;
2849 bitmap visited;
2850 ao_ref ar;
2851
2852 if (no_accesses_p (repr))
2853 continue;
2854 if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
2855 || repr->grp_maybe_modified)
2856 continue;
2857
2858 ao_ref_init (&ar, repr->expr);
2859 visited = BITMAP_ALLOC (NULL);
2860 for (access = repr; access; access = access->next_sibling)
2861 {
2862 /* All accesses are read ones, otherwise grp_maybe_modified would
2863 be trivially set. */
2864 walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
2865 mark_maybe_modified, repr, &visited);
2866 if (repr->grp_maybe_modified)
2867 break;
2868 }
2869 BITMAP_FREE (visited);
2870 }
2871 }
2872 }
2873
2874 /* Propagate distances in bb_dereferences in the opposite direction than the
2875 control flow edges, in each step storing the maximum of the current value
2876 and the minimum of all successors. These steps are repeated until the table
2877 stabilizes. Note that BBs which might terminate the functions (according to
2878 final_bbs bitmap) never updated in this way. */
2879
2880 static void
2881 propagate_dereference_distances (void)
2882 {
2883 VEC (basic_block, heap) *queue;
2884 basic_block bb;
2885
2886 queue = VEC_alloc (basic_block, heap, last_basic_block_for_function (cfun));
2887 VEC_quick_push (basic_block, queue, ENTRY_BLOCK_PTR);
2888 FOR_EACH_BB (bb)
2889 {
2890 VEC_quick_push (basic_block, queue, bb);
2891 bb->aux = bb;
2892 }
2893
2894 while (!VEC_empty (basic_block, queue))
2895 {
2896 edge_iterator ei;
2897 edge e;
2898 bool change = false;
2899 int i;
2900
2901 bb = VEC_pop (basic_block, queue);
2902 bb->aux = NULL;
2903
2904 if (bitmap_bit_p (final_bbs, bb->index))
2905 continue;
2906
2907 for (i = 0; i < func_param_count; i++)
2908 {
2909 int idx = bb->index * func_param_count + i;
2910 bool first = true;
2911 HOST_WIDE_INT inh = 0;
2912
2913 FOR_EACH_EDGE (e, ei, bb->succs)
2914 {
2915 int succ_idx = e->dest->index * func_param_count + i;
2916
2917 if (e->src == EXIT_BLOCK_PTR)
2918 continue;
2919
2920 if (first)
2921 {
2922 first = false;
2923 inh = bb_dereferences [succ_idx];
2924 }
2925 else if (bb_dereferences [succ_idx] < inh)
2926 inh = bb_dereferences [succ_idx];
2927 }
2928
2929 if (!first && bb_dereferences[idx] < inh)
2930 {
2931 bb_dereferences[idx] = inh;
2932 change = true;
2933 }
2934 }
2935
2936 if (change && !bitmap_bit_p (final_bbs, bb->index))
2937 FOR_EACH_EDGE (e, ei, bb->preds)
2938 {
2939 if (e->src->aux)
2940 continue;
2941
2942 e->src->aux = e->src;
2943 VEC_quick_push (basic_block, queue, e->src);
2944 }
2945 }
2946
2947 VEC_free (basic_block, heap, queue);
2948 }
2949
2950 /* Dump a dereferences TABLE with heading STR to file F. */
2951
2952 static void
2953 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
2954 {
2955 basic_block bb;
2956
2957 fprintf (dump_file, str);
2958 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
2959 {
2960 fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
2961 if (bb != EXIT_BLOCK_PTR)
2962 {
2963 int i;
2964 for (i = 0; i < func_param_count; i++)
2965 {
2966 int idx = bb->index * func_param_count + i;
2967 fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
2968 }
2969 }
2970 fprintf (f, "\n");
2971 }
2972 fprintf (dump_file, "\n");
2973 }
2974
2975 /* Determine what (parts of) parameters passed by reference that are not
2976 assigned to are not certainly dereferenced in this function and thus the
2977 dereferencing cannot be safely moved to the caller without potentially
2978 introducing a segfault. Mark such REPRESENTATIVES as
2979 grp_not_necessarilly_dereferenced.
2980
2981 The dereferenced maximum "distance," i.e. the offset + size of the accessed
2982 part is calculated rather than simple booleans are calculated for each
2983 pointer parameter to handle cases when only a fraction of the whole
2984 aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
2985 an example).
2986
2987 The maximum dereference distances for each pointer parameter and BB are
2988 already stored in bb_dereference. This routine simply propagates these
2989 values upwards by propagate_dereference_distances and then compares the
2990 distances of individual parameters in the ENTRY BB to the equivalent
2991 distances of each representative of a (fraction of a) parameter. */
2992
2993 static void
2994 analyze_caller_dereference_legality (VEC (access_p, heap) *representatives)
2995 {
2996 int i;
2997
2998 if (dump_file && (dump_flags & TDF_DETAILS))
2999 dump_dereferences_table (dump_file,
3000 "Dereference table before propagation:\n",
3001 bb_dereferences);
3002
3003 propagate_dereference_distances ();
3004
3005 if (dump_file && (dump_flags & TDF_DETAILS))
3006 dump_dereferences_table (dump_file,
3007 "Dereference table after propagation:\n",
3008 bb_dereferences);
3009
3010 for (i = 0; i < func_param_count; i++)
3011 {
3012 struct access *repr = VEC_index (access_p, representatives, i);
3013 int idx = ENTRY_BLOCK_PTR->index * func_param_count + i;
3014
3015 if (!repr || no_accesses_p (repr))
3016 continue;
3017
3018 do
3019 {
3020 if ((repr->offset + repr->size) > bb_dereferences[idx])
3021 repr->grp_not_necessarilly_dereferenced = 1;
3022 repr = repr->next_grp;
3023 }
3024 while (repr);
3025 }
3026 }
3027
3028 /* Return the representative access for the parameter declaration PARM if it is
3029 a scalar passed by reference which is not written to and the pointer value
3030 is not used directly. Thus, if it is legal to dereference it in the caller
3031 and we can rule out modifications through aliases, such parameter should be
3032 turned into one passed by value. Return NULL otherwise. */
3033
3034 static struct access *
3035 unmodified_by_ref_scalar_representative (tree parm)
3036 {
3037 int i, access_count;
3038 struct access *repr;
3039 VEC (access_p, heap) *access_vec;
3040
3041 access_vec = get_base_access_vector (parm);
3042 gcc_assert (access_vec);
3043 repr = VEC_index (access_p, access_vec, 0);
3044 if (repr->write)
3045 return NULL;
3046 repr->group_representative = repr;
3047
3048 access_count = VEC_length (access_p, access_vec);
3049 for (i = 1; i < access_count; i++)
3050 {
3051 struct access *access = VEC_index (access_p, access_vec, i);
3052 if (access->write)
3053 return NULL;
3054 access->group_representative = repr;
3055 access->next_sibling = repr->next_sibling;
3056 repr->next_sibling = access;
3057 }
3058
3059 repr->grp_read = 1;
3060 repr->grp_scalar_ptr = 1;
3061 return repr;
3062 }
3063
3064 /* Return true iff this access precludes IPA-SRA of the parameter it is
3065 associated with. */
3066
3067 static bool
3068 access_precludes_ipa_sra_p (struct access *access)
3069 {
3070 /* Avoid issues such as the second simple testcase in PR 42025. The problem
3071 is incompatible assign in a call statement (and possibly even in asm
3072 statements). This can be relaxed by using a new temporary but only for
3073 non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
3074 intraprocedural SRA we deal with this by keeping the old aggregate around,
3075 something we cannot do in IPA-SRA.) */
3076 if (access->write
3077 && (is_gimple_call (access->stmt)
3078 || gimple_code (access->stmt) == GIMPLE_ASM))
3079 return true;
3080
3081 return false;
3082 }
3083
3084
3085 /* Sort collected accesses for parameter PARM, identify representatives for
3086 each accessed region and link them together. Return NULL if there are
3087 different but overlapping accesses, return the special ptr value meaning
3088 there are no accesses for this parameter if that is the case and return the
3089 first representative otherwise. Set *RO_GRP if there is a group of accesses
3090 with only read (i.e. no write) accesses. */
3091
3092 static struct access *
3093 splice_param_accesses (tree parm, bool *ro_grp)
3094 {
3095 int i, j, access_count, group_count;
3096 int agg_size, total_size = 0;
3097 struct access *access, *res, **prev_acc_ptr = &res;
3098 VEC (access_p, heap) *access_vec;
3099
3100 access_vec = get_base_access_vector (parm);
3101 if (!access_vec)
3102 return &no_accesses_representant;
3103 access_count = VEC_length (access_p, access_vec);
3104
3105 qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
3106 compare_access_positions);
3107
3108 i = 0;
3109 total_size = 0;
3110 group_count = 0;
3111 while (i < access_count)
3112 {
3113 bool modification;
3114 access = VEC_index (access_p, access_vec, i);
3115 modification = access->write;
3116 if (access_precludes_ipa_sra_p (access))
3117 return NULL;
3118
3119 /* Access is about to become group representative unless we find some
3120 nasty overlap which would preclude us from breaking this parameter
3121 apart. */
3122
3123 j = i + 1;
3124 while (j < access_count)
3125 {
3126 struct access *ac2 = VEC_index (access_p, access_vec, j);
3127 if (ac2->offset != access->offset)
3128 {
3129 /* All or nothing law for parameters. */
3130 if (access->offset + access->size > ac2->offset)
3131 return NULL;
3132 else
3133 break;
3134 }
3135 else if (ac2->size != access->size)
3136 return NULL;
3137
3138 if (access_precludes_ipa_sra_p (ac2))
3139 return NULL;
3140
3141 modification |= ac2->write;
3142 ac2->group_representative = access;
3143 ac2->next_sibling = access->next_sibling;
3144 access->next_sibling = ac2;
3145 j++;
3146 }
3147
3148 group_count++;
3149 access->grp_maybe_modified = modification;
3150 if (!modification)
3151 *ro_grp = true;
3152 *prev_acc_ptr = access;
3153 prev_acc_ptr = &access->next_grp;
3154 total_size += access->size;
3155 i = j;
3156 }
3157
3158 if (POINTER_TYPE_P (TREE_TYPE (parm)))
3159 agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))), 1);
3160 else
3161 agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (parm)), 1);
3162 if (total_size >= agg_size)
3163 return NULL;
3164
3165 gcc_assert (group_count > 0);
3166 return res;
3167 }
3168
3169 /* Decide whether parameters with representative accesses given by REPR should
3170 be reduced into components. */
3171
3172 static int
3173 decide_one_param_reduction (struct access *repr)
3174 {
3175 int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
3176 bool by_ref;
3177 tree parm;
3178
3179 parm = repr->base;
3180 cur_parm_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (parm)), 1);
3181 gcc_assert (cur_parm_size > 0);
3182
3183 if (POINTER_TYPE_P (TREE_TYPE (parm)))
3184 {
3185 by_ref = true;
3186 agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))), 1);
3187 }
3188 else
3189 {
3190 by_ref = false;
3191 agg_size = cur_parm_size;
3192 }
3193
3194 if (dump_file)
3195 {
3196 struct access *acc;
3197 fprintf (dump_file, "Evaluating PARAM group sizes for ");
3198 print_generic_expr (dump_file, parm, 0);
3199 fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
3200 for (acc = repr; acc; acc = acc->next_grp)
3201 dump_access (dump_file, acc, true);
3202 }
3203
3204 total_size = 0;
3205 new_param_count = 0;
3206
3207 for (; repr; repr = repr->next_grp)
3208 {
3209 gcc_assert (parm == repr->base);
3210 new_param_count++;
3211
3212 if (!by_ref || (!repr->grp_maybe_modified
3213 && !repr->grp_not_necessarilly_dereferenced))
3214 total_size += repr->size;
3215 else
3216 total_size += cur_parm_size;
3217 }
3218
3219 gcc_assert (new_param_count > 0);
3220
3221 if (optimize_function_for_size_p (cfun))
3222 parm_size_limit = cur_parm_size;
3223 else
3224 parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
3225 * cur_parm_size);
3226
3227 if (total_size < agg_size
3228 && total_size <= parm_size_limit)
3229 {
3230 if (dump_file)
3231 fprintf (dump_file, " ....will be split into %i components\n",
3232 new_param_count);
3233 return new_param_count;
3234 }
3235 else
3236 return 0;
3237 }
3238
3239 /* The order of the following enums is important, we need to do extra work for
3240 UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
3241 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
3242 MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
3243
3244 /* Identify representatives of all accesses to all candidate parameters for
3245 IPA-SRA. Return result based on what representatives have been found. */
3246
3247 static enum ipa_splicing_result
3248 splice_all_param_accesses (VEC (access_p, heap) **representatives)
3249 {
3250 enum ipa_splicing_result result = NO_GOOD_ACCESS;
3251 tree parm;
3252 struct access *repr;
3253
3254 *representatives = VEC_alloc (access_p, heap, func_param_count);
3255
3256 for (parm = DECL_ARGUMENTS (current_function_decl);
3257 parm;
3258 parm = TREE_CHAIN (parm))
3259 {
3260 if (is_unused_scalar_param (parm))
3261 {
3262 VEC_quick_push (access_p, *representatives,
3263 &no_accesses_representant);
3264 if (result == NO_GOOD_ACCESS)
3265 result = UNUSED_PARAMS;
3266 }
3267 else if (POINTER_TYPE_P (TREE_TYPE (parm))
3268 && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
3269 && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3270 {
3271 repr = unmodified_by_ref_scalar_representative (parm);
3272 VEC_quick_push (access_p, *representatives, repr);
3273 if (repr)
3274 result = UNMODIF_BY_REF_ACCESSES;
3275 }
3276 else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3277 {
3278 bool ro_grp = false;
3279 repr = splice_param_accesses (parm, &ro_grp);
3280 VEC_quick_push (access_p, *representatives, repr);
3281
3282 if (repr && !no_accesses_p (repr))
3283 {
3284 if (POINTER_TYPE_P (TREE_TYPE (parm)))
3285 {
3286 if (ro_grp)
3287 result = UNMODIF_BY_REF_ACCESSES;
3288 else if (result < MODIF_BY_REF_ACCESSES)
3289 result = MODIF_BY_REF_ACCESSES;
3290 }
3291 else if (result < BY_VAL_ACCESSES)
3292 result = BY_VAL_ACCESSES;
3293 }
3294 else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
3295 result = UNUSED_PARAMS;
3296 }
3297 else
3298 VEC_quick_push (access_p, *representatives, NULL);
3299 }
3300
3301 if (result == NO_GOOD_ACCESS)
3302 {
3303 VEC_free (access_p, heap, *representatives);
3304 *representatives = NULL;
3305 return NO_GOOD_ACCESS;
3306 }
3307
3308 return result;
3309 }
3310
3311 /* Return the index of BASE in PARMS. Abort if it is not found. */
3312
3313 static inline int
3314 get_param_index (tree base, VEC(tree, heap) *parms)
3315 {
3316 int i, len;
3317
3318 len = VEC_length (tree, parms);
3319 for (i = 0; i < len; i++)
3320 if (VEC_index (tree, parms, i) == base)
3321 return i;
3322 gcc_unreachable ();
3323 }
3324
3325 /* Convert the decisions made at the representative level into compact
3326 parameter adjustments. REPRESENTATIVES are pointers to first
3327 representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
3328 final number of adjustments. */
3329
3330 static ipa_parm_adjustment_vec
3331 turn_representatives_into_adjustments (VEC (access_p, heap) *representatives,
3332 int adjustments_count)
3333 {
3334 VEC (tree, heap) *parms;
3335 ipa_parm_adjustment_vec adjustments;
3336 tree parm;
3337 int i;
3338
3339 gcc_assert (adjustments_count > 0);
3340 parms = ipa_get_vector_of_formal_parms (current_function_decl);
3341 adjustments = VEC_alloc (ipa_parm_adjustment_t, heap, adjustments_count);
3342 parm = DECL_ARGUMENTS (current_function_decl);
3343 for (i = 0; i < func_param_count; i++, parm = TREE_CHAIN (parm))
3344 {
3345 struct access *repr = VEC_index (access_p, representatives, i);
3346
3347 if (!repr || no_accesses_p (repr))
3348 {
3349 struct ipa_parm_adjustment *adj;
3350
3351 adj = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
3352 memset (adj, 0, sizeof (*adj));
3353 adj->base_index = get_param_index (parm, parms);
3354 adj->base = parm;
3355 if (!repr)
3356 adj->copy_param = 1;
3357 else
3358 adj->remove_param = 1;
3359 }
3360 else
3361 {
3362 struct ipa_parm_adjustment *adj;
3363 int index = get_param_index (parm, parms);
3364
3365 for (; repr; repr = repr->next_grp)
3366 {
3367 adj = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
3368 memset (adj, 0, sizeof (*adj));
3369 gcc_assert (repr->base == parm);
3370 adj->base_index = index;
3371 adj->base = repr->base;
3372 adj->type = repr->type;
3373 adj->offset = repr->offset;
3374 adj->by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
3375 && (repr->grp_maybe_modified
3376 || repr->grp_not_necessarilly_dereferenced));
3377
3378 }
3379 }
3380 }
3381 VEC_free (tree, heap, parms);
3382 return adjustments;
3383 }
3384
3385 /* Analyze the collected accesses and produce a plan what to do with the
3386 parameters in the form of adjustments, NULL meaning nothing. */
3387
3388 static ipa_parm_adjustment_vec
3389 analyze_all_param_acesses (void)
3390 {
3391 enum ipa_splicing_result repr_state;
3392 bool proceed = false;
3393 int i, adjustments_count = 0;
3394 VEC (access_p, heap) *representatives;
3395 ipa_parm_adjustment_vec adjustments;
3396
3397 repr_state = splice_all_param_accesses (&representatives);
3398 if (repr_state == NO_GOOD_ACCESS)
3399 return NULL;
3400
3401 /* If there are any parameters passed by reference which are not modified
3402 directly, we need to check whether they can be modified indirectly. */
3403 if (repr_state == UNMODIF_BY_REF_ACCESSES)
3404 {
3405 analyze_caller_dereference_legality (representatives);
3406 analyze_modified_params (representatives);
3407 }
3408
3409 for (i = 0; i < func_param_count; i++)
3410 {
3411 struct access *repr = VEC_index (access_p, representatives, i);
3412
3413 if (repr && !no_accesses_p (repr))
3414 {
3415 if (repr->grp_scalar_ptr)
3416 {
3417 adjustments_count++;
3418 if (repr->grp_not_necessarilly_dereferenced
3419 || repr->grp_maybe_modified)
3420 VEC_replace (access_p, representatives, i, NULL);
3421 else
3422 {
3423 proceed = true;
3424 sra_stats.scalar_by_ref_to_by_val++;
3425 }
3426 }
3427 else
3428 {
3429 int new_components = decide_one_param_reduction (repr);
3430
3431 if (new_components == 0)
3432 {
3433 VEC_replace (access_p, representatives, i, NULL);
3434 adjustments_count++;
3435 }
3436 else
3437 {
3438 adjustments_count += new_components;
3439 sra_stats.aggregate_params_reduced++;
3440 sra_stats.param_reductions_created += new_components;
3441 proceed = true;
3442 }
3443 }
3444 }
3445 else
3446 {
3447 if (no_accesses_p (repr))
3448 {
3449 proceed = true;
3450 sra_stats.deleted_unused_parameters++;
3451 }
3452 adjustments_count++;
3453 }
3454 }
3455
3456 if (!proceed && dump_file)
3457 fprintf (dump_file, "NOT proceeding to change params.\n");
3458
3459 if (proceed)
3460 adjustments = turn_representatives_into_adjustments (representatives,
3461 adjustments_count);
3462 else
3463 adjustments = NULL;
3464
3465 VEC_free (access_p, heap, representatives);
3466 return adjustments;
3467 }
3468
3469 /* If a parameter replacement identified by ADJ does not yet exist in the form
3470 of declaration, create it and record it, otherwise return the previously
3471 created one. */
3472
3473 static tree
3474 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
3475 {
3476 tree repl;
3477 if (!adj->new_ssa_base)
3478 {
3479 char *pretty_name = make_fancy_name (adj->base);
3480
3481 repl = make_rename_temp (TREE_TYPE (adj->base), "ISR");
3482 DECL_NAME (repl) = get_identifier (pretty_name);
3483 obstack_free (&name_obstack, pretty_name);
3484
3485 get_var_ann (repl);
3486 add_referenced_var (repl);
3487 adj->new_ssa_base = repl;
3488 }
3489 else
3490 repl = adj->new_ssa_base;
3491 return repl;
3492 }
3493
3494 /* Find the first adjustment for a particular parameter BASE in a vector of
3495 ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
3496 adjustment. */
3497
3498 static struct ipa_parm_adjustment *
3499 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
3500 {
3501 int i, len;
3502
3503 len = VEC_length (ipa_parm_adjustment_t, adjustments);
3504 for (i = 0; i < len; i++)
3505 {
3506 struct ipa_parm_adjustment *adj;
3507
3508 adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3509 if (!adj->copy_param && adj->base == base)
3510 return adj;
3511 }
3512
3513 return NULL;
3514 }
3515
3516 /* Callback for scan_function. If the statement STMT defines an SSA_NAME of a
3517 parameter which is to be removed because its value is not used, replace the
3518 SSA_NAME with a one relating to a created VAR_DECL and replace all of its
3519 uses too. DATA is a pointer to an adjustments vector. */
3520
3521 static bool
3522 replace_removed_params_ssa_names (gimple stmt, void *data)
3523 {
3524 VEC (ipa_parm_adjustment_t, heap) *adjustments;
3525 struct ipa_parm_adjustment *adj;
3526 tree lhs, decl, repl, name;
3527
3528 adjustments = (VEC (ipa_parm_adjustment_t, heap) *) data;
3529 if (gimple_code (stmt) == GIMPLE_PHI)
3530 lhs = gimple_phi_result (stmt);
3531 else if (is_gimple_assign (stmt))
3532 lhs = gimple_assign_lhs (stmt);
3533 else if (is_gimple_call (stmt))
3534 lhs = gimple_call_lhs (stmt);
3535 else
3536 gcc_unreachable ();
3537
3538 if (TREE_CODE (lhs) != SSA_NAME)
3539 return false;
3540 decl = SSA_NAME_VAR (lhs);
3541 if (TREE_CODE (decl) != PARM_DECL)
3542 return false;
3543
3544 adj = get_adjustment_for_base (adjustments, decl);
3545 if (!adj)
3546 return false;
3547
3548 repl = get_replaced_param_substitute (adj);
3549 name = make_ssa_name (repl, stmt);
3550
3551 if (dump_file)
3552 {
3553 fprintf (dump_file, "replacing an SSA name of a removed param ");
3554 print_generic_expr (dump_file, lhs, 0);
3555 fprintf (dump_file, " with ");
3556 print_generic_expr (dump_file, name, 0);
3557 fprintf (dump_file, "\n");
3558 }
3559
3560 if (is_gimple_assign (stmt))
3561 gimple_assign_set_lhs (stmt, name);
3562 else if (is_gimple_call (stmt))
3563 gimple_call_set_lhs (stmt, name);
3564 else
3565 gimple_phi_set_result (stmt, name);
3566
3567 replace_uses_by (lhs, name);
3568 return true;
3569 }
3570
3571 /* Callback for scan_function and helper to sra_ipa_modify_assign. If the
3572 expression *EXPR should be replaced by a reduction of a parameter, do so.
3573 DATA is a pointer to a vector of adjustments. DONT_CONVERT specifies
3574 whether the function should care about type incompatibility the current and
3575 new expressions. If it is true, the function will leave incompatibility
3576 issues to the caller.
3577
3578 When called directly by scan_function, DONT_CONVERT is true when the EXPR is
3579 a write (LHS) expression. */
3580
3581 static bool
3582 sra_ipa_modify_expr (tree *expr, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
3583 bool dont_convert, void *data)
3584 {
3585 ipa_parm_adjustment_vec adjustments;
3586 int i, len;
3587 struct ipa_parm_adjustment *adj, *cand = NULL;
3588 HOST_WIDE_INT offset, size, max_size;
3589 tree base, src;
3590
3591 adjustments = (VEC (ipa_parm_adjustment_t, heap) *) data;
3592 len = VEC_length (ipa_parm_adjustment_t, adjustments);
3593
3594 if (TREE_CODE (*expr) == BIT_FIELD_REF
3595 || TREE_CODE (*expr) == IMAGPART_EXPR
3596 || TREE_CODE (*expr) == REALPART_EXPR)
3597 {
3598 expr = &TREE_OPERAND (*expr, 0);
3599 dont_convert = false;
3600 }
3601
3602 base = get_ref_base_and_extent (*expr, &offset, &size, &max_size);
3603 if (!base || size == -1 || max_size == -1)
3604 return false;
3605
3606 if (INDIRECT_REF_P (base))
3607 base = TREE_OPERAND (base, 0);
3608
3609 base = get_ssa_base_param (base);
3610 if (!base || TREE_CODE (base) != PARM_DECL)
3611 return false;
3612
3613 for (i = 0; i < len; i++)
3614 {
3615 adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3616
3617 if (adj->base == base &&
3618 (adj->offset == offset || adj->remove_param))
3619 {
3620 cand = adj;
3621 break;
3622 }
3623 }
3624 if (!cand || cand->copy_param || cand->remove_param)
3625 return false;
3626
3627 if (cand->by_ref)
3628 {
3629 tree folded;
3630 src = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (cand->reduction)),
3631 cand->reduction);
3632 folded = gimple_fold_indirect_ref (src);
3633 if (folded)
3634 src = folded;
3635 }
3636 else
3637 src = cand->reduction;
3638
3639 if (dump_file && (dump_flags & TDF_DETAILS))
3640 {
3641 fprintf (dump_file, "About to replace expr ");
3642 print_generic_expr (dump_file, *expr, 0);
3643 fprintf (dump_file, " with ");
3644 print_generic_expr (dump_file, src, 0);
3645 fprintf (dump_file, "\n");
3646 }
3647
3648 if (!dont_convert
3649 && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
3650 {
3651 tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
3652 *expr = vce;
3653 }
3654 else
3655 *expr = src;
3656 return true;
3657 }
3658
3659 /* Callback for scan_function to process assign statements. Performs
3660 essentially the same function like sra_ipa_modify_expr. */
3661
3662 static enum scan_assign_result
3663 sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi, void *data)
3664 {
3665 gimple stmt = *stmt_ptr;
3666 tree *lhs_p, *rhs_p;
3667 bool any;
3668
3669 if (!gimple_assign_single_p (stmt))
3670 return SRA_SA_NONE;
3671
3672 rhs_p = gimple_assign_rhs1_ptr (stmt);
3673 lhs_p = gimple_assign_lhs_ptr (stmt);
3674
3675 any = sra_ipa_modify_expr (rhs_p, gsi, true, data);
3676 any |= sra_ipa_modify_expr (lhs_p, gsi, true, data);
3677 if (any)
3678 {
3679 if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
3680 {
3681 location_t loc = gimple_location (stmt);
3682 tree vce = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
3683 TREE_TYPE (*lhs_p), *rhs_p);
3684 tree tmp = force_gimple_operand_gsi (gsi, vce, true, NULL_TREE,
3685 true, GSI_SAME_STMT);
3686
3687 gimple_assign_set_rhs_from_tree (gsi, tmp);
3688 }
3689
3690 return SRA_SA_PROCESSED;
3691 }
3692
3693 return SRA_SA_NONE;
3694 }
3695
3696 /* Call gimple_debug_bind_reset_value on all debug statements describing
3697 gimple register parameters that are being removed or replaced. */
3698
3699 static void
3700 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
3701 {
3702 int i, len;
3703
3704 len = VEC_length (ipa_parm_adjustment_t, adjustments);
3705 for (i = 0; i < len; i++)
3706 {
3707 struct ipa_parm_adjustment *adj;
3708 imm_use_iterator ui;
3709 gimple stmt;
3710 tree name;
3711
3712 adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3713 if (adj->copy_param || !is_gimple_reg (adj->base))
3714 continue;
3715 name = gimple_default_def (cfun, adj->base);
3716 if (!name)
3717 continue;
3718 FOR_EACH_IMM_USE_STMT (stmt, ui, name)
3719 {
3720 /* All other users must have been removed by scan_function. */
3721 gcc_assert (is_gimple_debug (stmt));
3722 gimple_debug_bind_reset_value (stmt);
3723 update_stmt (stmt);
3724 }
3725 }
3726 }
3727
3728 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
3729
3730 static void
3731 convert_callers (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
3732 {
3733 tree old_cur_fndecl = current_function_decl;
3734 struct cgraph_edge *cs;
3735 basic_block this_block;
3736 bitmap recomputed_callers = BITMAP_ALLOC (NULL);
3737
3738 for (cs = node->callers; cs; cs = cs->next_caller)
3739 {
3740 current_function_decl = cs->caller->decl;
3741 push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
3742
3743 if (dump_file)
3744 fprintf (dump_file, "Adjusting call (%i -> %i) %s -> %s\n",
3745 cs->caller->uid, cs->callee->uid,
3746 cgraph_node_name (cs->caller),
3747 cgraph_node_name (cs->callee));
3748
3749 ipa_modify_call_arguments (cs, cs->call_stmt, adjustments);
3750
3751 pop_cfun ();
3752 }
3753
3754 for (cs = node->callers; cs; cs = cs->next_caller)
3755 if (!bitmap_bit_p (recomputed_callers, cs->caller->uid))
3756 {
3757 compute_inline_parameters (cs->caller);
3758 bitmap_set_bit (recomputed_callers, cs->caller->uid);
3759 }
3760 BITMAP_FREE (recomputed_callers);
3761
3762 current_function_decl = old_cur_fndecl;
3763 FOR_EACH_BB (this_block)
3764 {
3765 gimple_stmt_iterator gsi;
3766
3767 for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
3768 {
3769 gimple stmt = gsi_stmt (gsi);
3770 if (gimple_code (stmt) == GIMPLE_CALL
3771 && gimple_call_fndecl (stmt) == node->decl)
3772 {
3773 if (dump_file)
3774 fprintf (dump_file, "Adjusting recursive call");
3775 ipa_modify_call_arguments (NULL, stmt, adjustments);
3776 }
3777 }
3778 }
3779
3780 return;
3781 }
3782
3783 /* Perform all the modification required in IPA-SRA for NODE to have parameters
3784 as given in ADJUSTMENTS. */
3785
3786 static void
3787 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
3788 {
3789 ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA");
3790 scan_function (sra_ipa_modify_expr, sra_ipa_modify_assign,
3791 replace_removed_params_ssa_names, false, adjustments);
3792 sra_ipa_reset_debug_stmts (adjustments);
3793 convert_callers (node, adjustments);
3794 cgraph_make_node_local (node);
3795 return;
3796 }
3797
3798 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
3799 attributes, return true otherwise. NODE is the cgraph node of the current
3800 function. */
3801
3802 static bool
3803 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
3804 {
3805 if (!cgraph_node_can_be_local_p (node))
3806 {
3807 if (dump_file)
3808 fprintf (dump_file, "Function not local to this compilation unit.\n");
3809 return false;
3810 }
3811
3812 if (DECL_VIRTUAL_P (current_function_decl))
3813 {
3814 if (dump_file)
3815 fprintf (dump_file, "Function is a virtual method.\n");
3816 return false;
3817 }
3818
3819 if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
3820 && node->global.size >= MAX_INLINE_INSNS_AUTO)
3821 {
3822 if (dump_file)
3823 fprintf (dump_file, "Function too big to be made truly local.\n");
3824 return false;
3825 }
3826
3827 if (!node->callers)
3828 {
3829 if (dump_file)
3830 fprintf (dump_file,
3831 "Function has no callers in this compilation unit.\n");
3832 return false;
3833 }
3834
3835 if (cfun->stdarg)
3836 {
3837 if (dump_file)
3838 fprintf (dump_file, "Function uses stdarg. \n");
3839 return false;
3840 }
3841
3842 return true;
3843 }
3844
3845 /* Perform early interprocedural SRA. */
3846
3847 static unsigned int
3848 ipa_early_sra (void)
3849 {
3850 struct cgraph_node *node = cgraph_node (current_function_decl);
3851 ipa_parm_adjustment_vec adjustments;
3852 int ret = 0;
3853
3854 if (!ipa_sra_preliminary_function_checks (node))
3855 return 0;
3856
3857 sra_initialize ();
3858 sra_mode = SRA_MODE_EARLY_IPA;
3859
3860 if (!find_param_candidates ())
3861 {
3862 if (dump_file)
3863 fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
3864 goto simple_out;
3865 }
3866
3867 bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
3868 func_param_count
3869 * last_basic_block_for_function (cfun));
3870 final_bbs = BITMAP_ALLOC (NULL);
3871
3872 scan_function (build_access_from_expr, build_accesses_from_assign,
3873 NULL, true, NULL);
3874 if (encountered_apply_args)
3875 {
3876 if (dump_file)
3877 fprintf (dump_file, "Function calls __builtin_apply_args().\n");
3878 goto out;
3879 }
3880
3881 adjustments = analyze_all_param_acesses ();
3882 if (!adjustments)
3883 goto out;
3884 if (dump_file)
3885 ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
3886
3887 modify_function (node, adjustments);
3888 VEC_free (ipa_parm_adjustment_t, heap, adjustments);
3889 ret = TODO_update_ssa;
3890
3891 statistics_counter_event (cfun, "Unused parameters deleted",
3892 sra_stats.deleted_unused_parameters);
3893 statistics_counter_event (cfun, "Scalar parameters converted to by-value",
3894 sra_stats.scalar_by_ref_to_by_val);
3895 statistics_counter_event (cfun, "Aggregate parameters broken up",
3896 sra_stats.aggregate_params_reduced);
3897 statistics_counter_event (cfun, "Aggregate parameter components created",
3898 sra_stats.param_reductions_created);
3899
3900 out:
3901 BITMAP_FREE (final_bbs);
3902 free (bb_dereferences);
3903 simple_out:
3904 sra_deinitialize ();
3905 return ret;
3906 }
3907
3908 /* Return if early ipa sra shall be performed. */
3909 static bool
3910 ipa_early_sra_gate (void)
3911 {
3912 return flag_ipa_sra;
3913 }
3914
3915 struct gimple_opt_pass pass_early_ipa_sra =
3916 {
3917 {
3918 GIMPLE_PASS,
3919 "eipa_sra", /* name */
3920 ipa_early_sra_gate, /* gate */
3921 ipa_early_sra, /* execute */
3922 NULL, /* sub */
3923 NULL, /* next */
3924 0, /* static_pass_number */
3925 TV_IPA_SRA, /* tv_id */
3926 0, /* properties_required */
3927 0, /* properties_provided */
3928 0, /* properties_destroyed */
3929 0, /* todo_flags_start */
3930 TODO_dump_func | TODO_dump_cgraph /* todo_flags_finish */
3931 }
3932 };
3933
3934