OSDN Git Service

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