OSDN Git Service

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