OSDN Git Service

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