OSDN Git Service

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