OSDN Git Service

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