OSDN Git Service

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