OSDN Git Service

2009-10-29 Martin Jambor <mjambor@suse.cz>
[pf3gnuchains/gcc-fork.git] / gcc / tree-sra.c
1 /* Scalar Replacement of Aggregates (SRA) converts some structure
2    references into scalar references, exposing them to the scalar
3    optimizers.
4    Copyright (C) 2008, 2009 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 records used to be half-unions in Ada so the code treats
1235              the 3 container types the same.  This has been fixed in Ada.  */
1236           for (fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
1237             {
1238               HOST_WIDE_INT pos, size;
1239               tree expr, *expr_ptr;
1240
1241               if (TREE_CODE (fld) != FIELD_DECL)
1242                 continue;
1243
1244               pos = int_bit_position (fld);
1245               gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1246               tr_size = DECL_SIZE (fld);
1247               if (!tr_size || !host_integerp (tr_size, 1))
1248                 continue;
1249               size = tree_low_cst (tr_size, 1);
1250               if (pos > offset || (pos + size) <= offset)
1251                 continue;
1252
1253               if (res)
1254                 {
1255                   expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1256                                  NULL_TREE);
1257                   expr_ptr = &expr;
1258                 }
1259               else
1260                 expr_ptr = NULL;
1261               if (build_ref_for_offset_1 (expr_ptr, TREE_TYPE (fld),
1262                                           offset - pos, exp_type))
1263                 {
1264                   if (res)
1265                     *res = expr;
1266                   return true;
1267                 }
1268             }
1269           return false;
1270
1271         case ARRAY_TYPE:
1272           tr_size = TYPE_SIZE (TREE_TYPE (type));
1273           if (!tr_size || !host_integerp (tr_size, 1))
1274             return false;
1275           el_size = tree_low_cst (tr_size, 1);
1276
1277           minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1278           if (TREE_CODE (minidx) != INTEGER_CST)
1279             return false;
1280           if (res)
1281             {
1282               index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1283               if (!integer_zerop (minidx))
1284                 index = int_const_binop (PLUS_EXPR, index, minidx, 0);
1285               *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1286                              NULL_TREE, NULL_TREE);
1287             }
1288           offset = offset % el_size;
1289           type = TREE_TYPE (type);
1290           break;
1291
1292         default:
1293           if (offset != 0)
1294             return false;
1295
1296           if (exp_type)
1297             return false;
1298           else
1299             return true;
1300         }
1301     }
1302 }
1303
1304 /* Construct an expression that would reference a part of aggregate *EXPR of
1305    type TYPE at the given OFFSET of the type EXP_TYPE.  If EXPR is NULL, the
1306    function only determines whether it can build such a reference without
1307    actually doing it, otherwise, the tree it points to is unshared first and
1308    then used as a base for furhter sub-references.
1309
1310    FIXME: Eventually this should be replaced with
1311    maybe_fold_offset_to_reference() from tree-ssa-ccp.c but that requires a
1312    minor rewrite of fold_stmt.
1313  */
1314
1315 bool
1316 build_ref_for_offset (tree *expr, tree type, HOST_WIDE_INT offset,
1317                       tree exp_type, bool allow_ptr)
1318 {
1319   location_t loc = expr ? EXPR_LOCATION (*expr) : UNKNOWN_LOCATION;
1320
1321   if (expr)
1322     *expr = unshare_expr (*expr);
1323
1324   if (allow_ptr && POINTER_TYPE_P (type))
1325     {
1326       type = TREE_TYPE (type);
1327       if (expr)
1328         *expr = fold_build1_loc (loc, INDIRECT_REF, type, *expr);
1329     }
1330
1331   return build_ref_for_offset_1 (expr, type, offset, exp_type);
1332 }
1333
1334 /* Return true iff TYPE is stdarg va_list type.  */
1335
1336 static inline bool
1337 is_va_list_type (tree type)
1338 {
1339   return TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node);
1340 }
1341
1342 /* The very first phase of intraprocedural SRA.  It marks in candidate_bitmap
1343    those with type which is suitable for scalarization.  */
1344
1345 static bool
1346 find_var_candidates (void)
1347 {
1348   tree var, type;
1349   referenced_var_iterator rvi;
1350   bool ret = false;
1351
1352   FOR_EACH_REFERENCED_VAR (var, rvi)
1353     {
1354       if (TREE_CODE (var) != VAR_DECL && TREE_CODE (var) != PARM_DECL)
1355         continue;
1356       type = TREE_TYPE (var);
1357
1358       if (!AGGREGATE_TYPE_P (type)
1359           || needs_to_live_in_memory (var)
1360           || TREE_THIS_VOLATILE (var)
1361           || !COMPLETE_TYPE_P (type)
1362           || !host_integerp (TYPE_SIZE (type), 1)
1363           || tree_low_cst (TYPE_SIZE (type), 1) == 0
1364           || type_internals_preclude_sra_p (type)
1365           /* Fix for PR 41089.  tree-stdarg.c needs to have va_lists intact but
1366               we also want to schedule it rather late.  Thus we ignore it in
1367               the early pass. */
1368           || (sra_mode == SRA_MODE_EARLY_INTRA
1369               && is_va_list_type (type)))
1370         continue;
1371
1372       bitmap_set_bit (candidate_bitmap, DECL_UID (var));
1373
1374       if (dump_file && (dump_flags & TDF_DETAILS))
1375         {
1376           fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
1377           print_generic_expr (dump_file, var, 0);
1378           fprintf (dump_file, "\n");
1379         }
1380       ret = true;
1381     }
1382
1383   return ret;
1384 }
1385
1386 /* Sort all accesses for the given variable, check for partial overlaps and
1387    return NULL if there are any.  If there are none, pick a representative for
1388    each combination of offset and size and create a linked list out of them.
1389    Return the pointer to the first representative and make sure it is the first
1390    one in the vector of accesses.  */
1391
1392 static struct access *
1393 sort_and_splice_var_accesses (tree var)
1394 {
1395   int i, j, access_count;
1396   struct access *res, **prev_acc_ptr = &res;
1397   VEC (access_p, heap) *access_vec;
1398   bool first = true;
1399   HOST_WIDE_INT low = -1, high = 0;
1400
1401   access_vec = get_base_access_vector (var);
1402   if (!access_vec)
1403     return NULL;
1404   access_count = VEC_length (access_p, access_vec);
1405
1406   /* Sort by <OFFSET, SIZE>.  */
1407   qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
1408          compare_access_positions);
1409
1410   i = 0;
1411   while (i < access_count)
1412     {
1413       struct access *access = VEC_index (access_p, access_vec, i);
1414       bool grp_write = access->write;
1415       bool grp_read = !access->write;
1416       bool multiple_reads = false;
1417       bool grp_partial_lhs = access->grp_partial_lhs;
1418       bool first_scalar = is_gimple_reg_type (access->type);
1419       bool unscalarizable_region = access->grp_unscalarizable_region;
1420
1421       if (first || access->offset >= high)
1422         {
1423           first = false;
1424           low = access->offset;
1425           high = access->offset + access->size;
1426         }
1427       else if (access->offset > low && access->offset + access->size > high)
1428         return NULL;
1429       else
1430         gcc_assert (access->offset >= low
1431                     && access->offset + access->size <= high);
1432
1433       j = i + 1;
1434       while (j < access_count)
1435         {
1436           struct access *ac2 = VEC_index (access_p, access_vec, j);
1437           if (ac2->offset != access->offset || ac2->size != access->size)
1438             break;
1439           if (ac2->write)
1440             grp_write = true;
1441           else
1442             {
1443               if (grp_read)
1444                 multiple_reads = true;
1445               else
1446                 grp_read = true;
1447             }
1448           grp_partial_lhs |= ac2->grp_partial_lhs;
1449           unscalarizable_region |= ac2->grp_unscalarizable_region;
1450           relink_to_new_repr (access, ac2);
1451
1452           /* If there are both aggregate-type and scalar-type accesses with
1453              this combination of size and offset, the comparison function
1454              should have put the scalars first.  */
1455           gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
1456           ac2->group_representative = access;
1457           j++;
1458         }
1459
1460       i = j;
1461
1462       access->group_representative = access;
1463       access->grp_write = grp_write;
1464       access->grp_read = grp_read;
1465       access->grp_hint = multiple_reads;
1466       access->grp_partial_lhs = grp_partial_lhs;
1467       access->grp_unscalarizable_region = unscalarizable_region;
1468       if (access->first_link)
1469         add_access_to_work_queue (access);
1470
1471       *prev_acc_ptr = access;
1472       prev_acc_ptr = &access->next_grp;
1473     }
1474
1475   gcc_assert (res == VEC_index (access_p, access_vec, 0));
1476   return res;
1477 }
1478
1479 /* Create a variable for the given ACCESS which determines the type, name and a
1480    few other properties.  Return the variable declaration and store it also to
1481    ACCESS->replacement.  */
1482
1483 static tree
1484 create_access_replacement (struct access *access)
1485 {
1486   tree repl;
1487
1488   repl = create_tmp_var (access->type, "SR");
1489   get_var_ann (repl);
1490   add_referenced_var (repl);
1491   mark_sym_for_renaming (repl);
1492
1493   if (!access->grp_partial_lhs
1494       && (TREE_CODE (access->type) == COMPLEX_TYPE
1495           || TREE_CODE (access->type) == VECTOR_TYPE))
1496     DECL_GIMPLE_REG_P (repl) = 1;
1497
1498   DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
1499   DECL_ARTIFICIAL (repl) = 1;
1500
1501   if (DECL_NAME (access->base)
1502       && !DECL_IGNORED_P (access->base)
1503       && !DECL_ARTIFICIAL (access->base))
1504     {
1505       char *pretty_name = make_fancy_name (access->expr);
1506
1507       DECL_NAME (repl) = get_identifier (pretty_name);
1508       obstack_free (&name_obstack, pretty_name);
1509
1510       SET_DECL_DEBUG_EXPR (repl, access->expr);
1511       DECL_DEBUG_EXPR_IS_FROM (repl) = 1;
1512       DECL_IGNORED_P (repl) = 0;
1513     }
1514
1515   DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
1516   TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
1517
1518   if (dump_file)
1519     {
1520       fprintf (dump_file, "Created a replacement for ");
1521       print_generic_expr (dump_file, access->base, 0);
1522       fprintf (dump_file, " offset: %u, size: %u: ",
1523                (unsigned) access->offset, (unsigned) access->size);
1524       print_generic_expr (dump_file, repl, 0);
1525       fprintf (dump_file, "\n");
1526     }
1527   sra_stats.replacements++;
1528
1529   return repl;
1530 }
1531
1532 /* Return ACCESS scalar replacement, create it if it does not exist yet.  */
1533
1534 static inline tree
1535 get_access_replacement (struct access *access)
1536 {
1537   gcc_assert (access->grp_to_be_replaced);
1538
1539   if (!access->replacement_decl)
1540     access->replacement_decl = create_access_replacement (access);
1541   return access->replacement_decl;
1542 }
1543
1544 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
1545    linked list along the way.  Stop when *ACCESS is NULL or the access pointed
1546    to it is not "within" the root.  */
1547
1548 static void
1549 build_access_subtree (struct access **access)
1550 {
1551   struct access *root = *access, *last_child = NULL;
1552   HOST_WIDE_INT limit = root->offset + root->size;
1553
1554   *access = (*access)->next_grp;
1555   while  (*access && (*access)->offset + (*access)->size <= limit)
1556     {
1557       if (!last_child)
1558         root->first_child = *access;
1559       else
1560         last_child->next_sibling = *access;
1561       last_child = *access;
1562
1563       build_access_subtree (access);
1564     }
1565 }
1566
1567 /* Build a tree of access representatives, ACCESS is the pointer to the first
1568    one, others are linked in a list by the next_grp field.  Decide about scalar
1569    replacements on the way, return true iff any are to be created.  */
1570
1571 static void
1572 build_access_trees (struct access *access)
1573 {
1574   while (access)
1575     {
1576       struct access *root = access;
1577
1578       build_access_subtree (&access);
1579       root->next_grp = access;
1580     }
1581 }
1582
1583 /* Return true if expr contains some ARRAY_REFs into a variable bounded
1584    array.  */
1585
1586 static bool
1587 expr_with_var_bounded_array_refs_p (tree expr)
1588 {
1589   while (handled_component_p (expr))
1590     {
1591       if (TREE_CODE (expr) == ARRAY_REF
1592           && !host_integerp (array_ref_low_bound (expr), 0))
1593         return true;
1594       expr = TREE_OPERAND (expr, 0);
1595     }
1596   return false;
1597 }
1598
1599 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
1600    both seeming beneficial and when ALLOW_REPLACEMENTS allows it.  Also set
1601    all sorts of access flags appropriately along the way, notably always ser
1602    grp_read when MARK_READ is true and grp_write when MARK_WRITE is true.  */
1603
1604 static bool
1605 analyze_access_subtree (struct access *root, bool allow_replacements,
1606                         bool mark_read, bool mark_write)
1607 {
1608   struct access *child;
1609   HOST_WIDE_INT limit = root->offset + root->size;
1610   HOST_WIDE_INT covered_to = root->offset;
1611   bool scalar = is_gimple_reg_type (root->type);
1612   bool hole = false, sth_created = false;
1613   bool direct_read = root->grp_read;
1614
1615   if (mark_read)
1616     root->grp_read = true;
1617   else if (root->grp_read)
1618     mark_read = true;
1619
1620   if (mark_write)
1621     root->grp_write = true;
1622   else if (root->grp_write)
1623     mark_write = true;
1624
1625   if (root->grp_unscalarizable_region)
1626     allow_replacements = false;
1627
1628   if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
1629     allow_replacements = false;
1630
1631   for (child = root->first_child; child; child = child->next_sibling)
1632     {
1633       if (!hole && child->offset < covered_to)
1634         hole = true;
1635       else
1636         covered_to += child->size;
1637
1638       sth_created |= analyze_access_subtree (child, allow_replacements,
1639                                              mark_read, mark_write);
1640
1641       root->grp_unscalarized_data |= child->grp_unscalarized_data;
1642       hole |= !child->grp_covered;
1643     }
1644
1645   if (allow_replacements && scalar && !root->first_child
1646       && (root->grp_hint
1647           || (direct_read && root->grp_write)))
1648     {
1649       if (dump_file && (dump_flags & TDF_DETAILS))
1650         {
1651           fprintf (dump_file, "Marking ");
1652           print_generic_expr (dump_file, root->base, 0);
1653           fprintf (dump_file, " offset: %u, size: %u: ",
1654                    (unsigned) root->offset, (unsigned) root->size);
1655           fprintf (dump_file, " to be replaced.\n");
1656         }
1657
1658       root->grp_to_be_replaced = 1;
1659       sth_created = true;
1660       hole = false;
1661     }
1662   else if (covered_to < limit)
1663     hole = true;
1664
1665   if (sth_created && !hole)
1666     {
1667       root->grp_covered = 1;
1668       return true;
1669     }
1670   if (root->grp_write || TREE_CODE (root->base) == PARM_DECL)
1671     root->grp_unscalarized_data = 1; /* not covered and written to */
1672   if (sth_created)
1673     return true;
1674   return false;
1675 }
1676
1677 /* Analyze all access trees linked by next_grp by the means of
1678    analyze_access_subtree.  */
1679 static bool
1680 analyze_access_trees (struct access *access)
1681 {
1682   bool ret = false;
1683
1684   while (access)
1685     {
1686       if (analyze_access_subtree (access, true, false, false))
1687         ret = true;
1688       access = access->next_grp;
1689     }
1690
1691   return ret;
1692 }
1693
1694 /* Return true iff a potential new child of LACC at offset OFFSET and with size
1695    SIZE would conflict with an already existing one.  If exactly such a child
1696    already exists in LACC, store a pointer to it in EXACT_MATCH.  */
1697
1698 static bool
1699 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
1700                               HOST_WIDE_INT size, struct access **exact_match)
1701 {
1702   struct access *child;
1703
1704   for (child = lacc->first_child; child; child = child->next_sibling)
1705     {
1706       if (child->offset == norm_offset && child->size == size)
1707         {
1708           *exact_match = child;
1709           return true;
1710         }
1711
1712       if (child->offset < norm_offset + size
1713           && child->offset + child->size > norm_offset)
1714         return true;
1715     }
1716
1717   return false;
1718 }
1719
1720 /* Create a new child access of PARENT, with all properties just like MODEL
1721    except for its offset and with its grp_write false and grp_read true.
1722    Return the new access or NULL if it cannot be created.  Note that this access
1723    is created long after all splicing and sorting, it's not located in any
1724    access vector and is automatically a representative of its group.  */
1725
1726 static struct access *
1727 create_artificial_child_access (struct access *parent, struct access *model,
1728                                 HOST_WIDE_INT new_offset)
1729 {
1730   struct access *access;
1731   struct access **child;
1732   tree expr = parent->base;;
1733
1734   gcc_assert (!model->grp_unscalarizable_region);
1735
1736   if (!build_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
1737                              model->type, false))
1738     return NULL;
1739
1740   access = (struct access *) pool_alloc (access_pool);
1741   memset (access, 0, sizeof (struct access));
1742   access->base = parent->base;
1743   access->expr = expr;
1744   access->offset = new_offset;
1745   access->size = model->size;
1746   access->type = model->type;
1747   access->grp_write = true;
1748   access->grp_read = false;
1749
1750   child = &parent->first_child;
1751   while (*child && (*child)->offset < new_offset)
1752     child = &(*child)->next_sibling;
1753
1754   access->next_sibling = *child;
1755   *child = access;
1756
1757   return access;
1758 }
1759
1760
1761 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
1762    true if any new subaccess was created.  Additionally, if RACC is a scalar
1763    access but LACC is not, change the type of the latter, if possible.  */
1764
1765 static bool
1766 propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
1767 {
1768   struct access *rchild;
1769   HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
1770   bool ret = false;
1771
1772   if (is_gimple_reg_type (lacc->type)
1773       || lacc->grp_unscalarizable_region
1774       || racc->grp_unscalarizable_region)
1775     return false;
1776
1777   if (!lacc->first_child && !racc->first_child
1778       && is_gimple_reg_type (racc->type))
1779     {
1780       tree t = lacc->base;
1781
1782       if (build_ref_for_offset (&t, TREE_TYPE (t), lacc->offset, racc->type,
1783                                 false))
1784         {
1785           lacc->expr = t;
1786           lacc->type = racc->type;
1787         }
1788       return false;
1789     }
1790
1791   for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
1792     {
1793       struct access *new_acc = NULL;
1794       HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
1795
1796       if (rchild->grp_unscalarizable_region)
1797         continue;
1798
1799       if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
1800                                         &new_acc))
1801         {
1802           if (new_acc)
1803             {
1804               rchild->grp_hint = 1;
1805               new_acc->grp_hint |= new_acc->grp_read;
1806               if (rchild->first_child)
1807                 ret |= propagate_subaccesses_across_link (new_acc, rchild);
1808             }
1809           continue;
1810         }
1811
1812       /* If a (part of) a union field is on the RHS of an assignment, it can
1813          have sub-accesses which do not make sense on the LHS (PR 40351).
1814          Check that this is not the case.  */
1815       if (!build_ref_for_offset (NULL, TREE_TYPE (lacc->base), norm_offset,
1816                                  rchild->type, false))
1817         continue;
1818
1819       rchild->grp_hint = 1;
1820       new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
1821       if (new_acc)
1822         {
1823           ret = true;
1824           if (racc->first_child)
1825             propagate_subaccesses_across_link (new_acc, rchild);
1826         }
1827     }
1828
1829   return ret;
1830 }
1831
1832 /* Propagate all subaccesses across assignment links.  */
1833
1834 static void
1835 propagate_all_subaccesses (void)
1836 {
1837   while (work_queue_head)
1838     {
1839       struct access *racc = pop_access_from_work_queue ();
1840       struct assign_link *link;
1841
1842       gcc_assert (racc->first_link);
1843
1844       for (link = racc->first_link; link; link = link->next)
1845         {
1846           struct access *lacc = link->lacc;
1847
1848           if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
1849             continue;
1850           lacc = lacc->group_representative;
1851           if (propagate_subaccesses_across_link (lacc, racc)
1852               && lacc->first_link)
1853             add_access_to_work_queue (lacc);
1854         }
1855     }
1856 }
1857
1858 /* Go through all accesses collected throughout the (intraprocedural) analysis
1859    stage, exclude overlapping ones, identify representatives and build trees
1860    out of them, making decisions about scalarization on the way.  Return true
1861    iff there are any to-be-scalarized variables after this stage. */
1862
1863 static bool
1864 analyze_all_variable_accesses (void)
1865 {
1866   tree var;
1867   referenced_var_iterator rvi;
1868   int res = 0;
1869
1870   FOR_EACH_REFERENCED_VAR (var, rvi)
1871     if (bitmap_bit_p (candidate_bitmap, DECL_UID (var)))
1872       {
1873         struct access *access;
1874
1875         access = sort_and_splice_var_accesses (var);
1876         if (access)
1877           build_access_trees (access);
1878         else
1879           disqualify_candidate (var,
1880                                 "No or inhibitingly overlapping accesses.");
1881       }
1882
1883   propagate_all_subaccesses ();
1884
1885   FOR_EACH_REFERENCED_VAR (var, rvi)
1886     if (bitmap_bit_p (candidate_bitmap, DECL_UID (var)))
1887       {
1888         struct access *access = get_first_repr_for_decl (var);
1889
1890         if (analyze_access_trees (access))
1891           {
1892             res++;
1893             if (dump_file && (dump_flags & TDF_DETAILS))
1894               {
1895                 fprintf (dump_file, "\nAccess trees for ");
1896                 print_generic_expr (dump_file, var, 0);
1897                 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
1898                 dump_access_tree (dump_file, access);
1899                 fprintf (dump_file, "\n");
1900               }
1901           }
1902         else
1903           disqualify_candidate (var, "No scalar replacements to be created.");
1904       }
1905
1906   if (res)
1907     {
1908       statistics_counter_event (cfun, "Scalarized aggregates", res);
1909       return true;
1910     }
1911   else
1912     return false;
1913 }
1914
1915 /* Return true iff a reference statement into aggregate AGG can be built for
1916    every single to-be-replaced accesses that is a child of ACCESS, its sibling
1917    or a child of its sibling. TOP_OFFSET is the offset from the processed
1918    access subtree that has to be subtracted from offset of each access.  */
1919
1920 static bool
1921 ref_expr_for_all_replacements_p (struct access *access, tree agg,
1922                                  HOST_WIDE_INT top_offset)
1923 {
1924   do
1925     {
1926       if (access->grp_to_be_replaced
1927           && !build_ref_for_offset (NULL, TREE_TYPE (agg),
1928                                     access->offset - top_offset,
1929                                     access->type, false))
1930         return false;
1931
1932       if (access->first_child
1933           && !ref_expr_for_all_replacements_p (access->first_child, agg,
1934                                                top_offset))
1935         return false;
1936
1937       access = access->next_sibling;
1938     }
1939   while (access);
1940
1941   return true;
1942 }
1943
1944 /* Generate statements copying scalar replacements of accesses within a subtree
1945    into or out of AGG.  ACCESS is the first child of the root of the subtree to
1946    be processed.  AGG is an aggregate type expression (can be a declaration but
1947    does not have to be, it can for example also be an indirect_ref).
1948    TOP_OFFSET is the offset of the processed subtree which has to be subtracted
1949    from offsets of individual accesses to get corresponding offsets for AGG.
1950    If CHUNK_SIZE is non-null, copy only replacements in the interval
1951    <start_offset, start_offset + chunk_size>, otherwise copy all.  GSI is a
1952    statement iterator used to place the new statements.  WRITE should be true
1953    when the statements should write from AGG to the replacement and false if
1954    vice versa.  if INSERT_AFTER is true, new statements will be added after the
1955    current statement in GSI, they will be added before the statement
1956    otherwise.  */
1957
1958 static void
1959 generate_subtree_copies (struct access *access, tree agg,
1960                          HOST_WIDE_INT top_offset,
1961                          HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
1962                          gimple_stmt_iterator *gsi, bool write,
1963                          bool insert_after)
1964 {
1965   do
1966     {
1967       tree expr = agg;
1968
1969       if (chunk_size && access->offset >= start_offset + chunk_size)
1970         return;
1971
1972       if (access->grp_to_be_replaced
1973           && (chunk_size == 0
1974               || access->offset + access->size > start_offset))
1975         {
1976           tree repl = get_access_replacement (access);
1977           bool ref_found;
1978           gimple stmt;
1979
1980           ref_found = build_ref_for_offset (&expr, TREE_TYPE (agg),
1981                                              access->offset - top_offset,
1982                                              access->type, false);
1983           gcc_assert (ref_found);
1984
1985           if (write)
1986             {
1987               if (access->grp_partial_lhs)
1988                 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
1989                                                  !insert_after,
1990                                                  insert_after ? GSI_NEW_STMT
1991                                                  : GSI_SAME_STMT);
1992               stmt = gimple_build_assign (repl, expr);
1993             }
1994           else
1995             {
1996               TREE_NO_WARNING (repl) = 1;
1997               if (access->grp_partial_lhs)
1998                 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
1999                                                  !insert_after,
2000                                                  insert_after ? GSI_NEW_STMT
2001                                                  : GSI_SAME_STMT);
2002               stmt = gimple_build_assign (expr, repl);
2003             }
2004
2005           if (insert_after)
2006             gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2007           else
2008             gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2009           update_stmt (stmt);
2010           sra_stats.subtree_copies++;
2011         }
2012
2013       if (access->first_child)
2014         generate_subtree_copies (access->first_child, agg, top_offset,
2015                                  start_offset, chunk_size, gsi,
2016                                  write, insert_after);
2017
2018       access = access->next_sibling;
2019     }
2020   while (access);
2021 }
2022
2023 /* Assign zero to all scalar replacements in an access subtree.  ACCESS is the
2024    the root of the subtree to be processed.  GSI is the statement iterator used
2025    for inserting statements which are added after the current statement if
2026    INSERT_AFTER is true or before it otherwise.  */
2027
2028 static void
2029 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
2030                         bool insert_after)
2031
2032 {
2033   struct access *child;
2034
2035   if (access->grp_to_be_replaced)
2036     {
2037       gimple stmt;
2038
2039       stmt = gimple_build_assign (get_access_replacement (access),
2040                                   fold_convert (access->type,
2041                                                 integer_zero_node));
2042       if (insert_after)
2043         gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2044       else
2045         gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2046       update_stmt (stmt);
2047     }
2048
2049   for (child = access->first_child; child; child = child->next_sibling)
2050     init_subtree_with_zero (child, gsi, insert_after);
2051 }
2052
2053 /* Search for an access representative for the given expression EXPR and
2054    return it or NULL if it cannot be found.  */
2055
2056 static struct access *
2057 get_access_for_expr (tree expr)
2058 {
2059   HOST_WIDE_INT offset, size, max_size;
2060   tree base;
2061
2062   /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
2063      a different size than the size of its argument and we need the latter
2064      one.  */
2065   if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
2066     expr = TREE_OPERAND (expr, 0);
2067
2068   base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
2069   if (max_size == -1 || !DECL_P (base))
2070     return NULL;
2071
2072   if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
2073     return NULL;
2074
2075   return get_var_base_offset_size_access (base, offset, max_size);
2076 }
2077
2078 /* Callback for scan_function.  Replace the expression EXPR with a scalar
2079    replacement if there is one and generate other statements to do type
2080    conversion or subtree copying if necessary.  GSI is used to place newly
2081    created statements, WRITE is true if the expression is being written to (it
2082    is on a LHS of a statement or output in an assembly statement).  */
2083
2084 static bool
2085 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write,
2086                  void *data ATTRIBUTE_UNUSED)
2087 {
2088   struct access *access;
2089   tree type, bfr;
2090
2091   if (TREE_CODE (*expr) == BIT_FIELD_REF)
2092     {
2093       bfr = *expr;
2094       expr = &TREE_OPERAND (*expr, 0);
2095     }
2096   else
2097     bfr = NULL_TREE;
2098
2099   if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
2100     expr = &TREE_OPERAND (*expr, 0);
2101   access = get_access_for_expr (*expr);
2102   if (!access)
2103     return false;
2104   type = TREE_TYPE (*expr);
2105
2106   if (access->grp_to_be_replaced)
2107     {
2108       tree repl = get_access_replacement (access);
2109       /* If we replace a non-register typed access simply use the original
2110          access expression to extract the scalar component afterwards.
2111          This happens if scalarizing a function return value or parameter
2112          like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
2113          gcc.c-torture/compile/20011217-1.c.  */
2114       if (!is_gimple_reg_type (type))
2115         {
2116           gimple stmt;
2117           if (write)
2118             {
2119               tree ref = unshare_expr (access->expr);
2120               if (access->grp_partial_lhs)
2121                 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
2122                                                  false, GSI_NEW_STMT);
2123               stmt = gimple_build_assign (repl, ref);
2124               gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
2125             }
2126           else
2127             {
2128               if (access->grp_partial_lhs)
2129                 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
2130                                                  true, GSI_SAME_STMT);
2131               stmt = gimple_build_assign (unshare_expr (access->expr), repl);
2132               gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
2133             }
2134         }
2135       else
2136         {
2137           gcc_assert (useless_type_conversion_p (type, access->type));
2138           *expr = repl;
2139         }
2140       sra_stats.exprs++;
2141     }
2142
2143   if (access->first_child)
2144     {
2145       HOST_WIDE_INT start_offset, chunk_size;
2146       if (bfr
2147           && host_integerp (TREE_OPERAND (bfr, 1), 1)
2148           && host_integerp (TREE_OPERAND (bfr, 2), 1))
2149         {
2150           chunk_size = tree_low_cst (TREE_OPERAND (bfr, 1), 1);
2151           start_offset = access->offset
2152             + tree_low_cst (TREE_OPERAND (bfr, 2), 1);
2153         }
2154       else
2155         start_offset = chunk_size = 0;
2156
2157       generate_subtree_copies (access->first_child, access->base, 0,
2158                                start_offset, chunk_size, gsi, write, write);
2159     }
2160   return true;
2161 }
2162
2163 /* Where scalar replacements of the RHS have been written to when a replacement
2164    of a LHS of an assigments cannot be direclty loaded from a replacement of
2165    the RHS. */
2166 enum unscalarized_data_handling { SRA_UDH_NONE,  /* Nothing done so far. */
2167                                   SRA_UDH_RIGHT, /* Data flushed to the RHS. */
2168                                   SRA_UDH_LEFT }; /* Data flushed to the LHS. */
2169
2170 /* Store all replacements in the access tree rooted in TOP_RACC either to their
2171    base aggregate if there are unscalarized data or directly to LHS
2172    otherwise.  */
2173
2174 static enum unscalarized_data_handling
2175 handle_unscalarized_data_in_subtree (struct access *top_racc, tree lhs,
2176                                      gimple_stmt_iterator *gsi)
2177 {
2178   if (top_racc->grp_unscalarized_data)
2179     {
2180       generate_subtree_copies (top_racc->first_child, top_racc->base, 0, 0, 0,
2181                                gsi, false, false);
2182       return SRA_UDH_RIGHT;
2183     }
2184   else
2185     {
2186       generate_subtree_copies (top_racc->first_child, lhs, top_racc->offset,
2187                                0, 0, gsi, false, false);
2188       return SRA_UDH_LEFT;
2189     }
2190 }
2191
2192
2193 /* Try to generate statements to load all sub-replacements in an access
2194    (sub)tree (LACC is the first child) from scalar replacements in the TOP_RACC
2195    (sub)tree.  If that is not possible, refresh the TOP_RACC base aggregate and
2196    load the accesses from it.  LEFT_OFFSET is the offset of the left whole
2197    subtree being copied, RIGHT_OFFSET is the same thing for the right subtree.
2198    GSI is stmt iterator used for statement insertions.  *REFRESHED is true iff
2199    the rhs top aggregate has already been refreshed by contents of its scalar
2200    reductions and is set to true if this function has to do it.  */
2201
2202 static void
2203 load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
2204                                  HOST_WIDE_INT left_offset,
2205                                  HOST_WIDE_INT right_offset,
2206                                  gimple_stmt_iterator *old_gsi,
2207                                  gimple_stmt_iterator *new_gsi,
2208                                  enum unscalarized_data_handling *refreshed,
2209                                  tree lhs)
2210 {
2211   location_t loc = EXPR_LOCATION (lacc->expr);
2212   do
2213     {
2214       if (lacc->grp_to_be_replaced)
2215         {
2216           struct access *racc;
2217           HOST_WIDE_INT offset = lacc->offset - left_offset + right_offset;
2218           gimple stmt;
2219           tree rhs;
2220
2221           racc = find_access_in_subtree (top_racc, offset, lacc->size);
2222           if (racc && racc->grp_to_be_replaced)
2223             {
2224               rhs = get_access_replacement (racc);
2225               if (!useless_type_conversion_p (lacc->type, racc->type))
2226                 rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, lacc->type, rhs);
2227             }
2228           else
2229             {
2230               bool repl_found;
2231
2232               /* No suitable access on the right hand side, need to load from
2233                  the aggregate.  See if we have to update it first... */
2234               if (*refreshed == SRA_UDH_NONE)
2235                 *refreshed = handle_unscalarized_data_in_subtree (top_racc,
2236                                                                   lhs, old_gsi);
2237
2238               if (*refreshed == SRA_UDH_LEFT)
2239                 rhs = unshare_expr (lacc->expr);
2240               else
2241                 {
2242                   rhs = top_racc->base;
2243                   repl_found = build_ref_for_offset (&rhs,
2244                                                      TREE_TYPE (top_racc->base),
2245                                                      offset, lacc->type, false);
2246                   gcc_assert (repl_found);
2247                 }
2248             }
2249
2250           stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
2251           gsi_insert_after (new_gsi, stmt, GSI_NEW_STMT);
2252           update_stmt (stmt);
2253           sra_stats.subreplacements++;
2254         }
2255       else if (*refreshed == SRA_UDH_NONE
2256                && lacc->grp_read && !lacc->grp_covered)
2257         *refreshed = handle_unscalarized_data_in_subtree (top_racc, lhs,
2258                                                           old_gsi);
2259
2260       if (lacc->first_child)
2261         load_assign_lhs_subreplacements (lacc->first_child, top_racc,
2262                                          left_offset, right_offset,
2263                                          old_gsi, new_gsi, refreshed, lhs);
2264       lacc = lacc->next_sibling;
2265     }
2266   while (lacc);
2267 }
2268
2269 /* Modify assignments with a CONSTRUCTOR on their RHS.  STMT contains a pointer
2270    to the assignment and GSI is the statement iterator pointing at it.  Returns
2271    the same values as sra_modify_assign.  */
2272
2273 static enum scan_assign_result
2274 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
2275 {
2276   tree lhs = gimple_assign_lhs (*stmt);
2277   struct access *acc;
2278
2279   acc = get_access_for_expr (lhs);
2280   if (!acc)
2281     return SRA_SA_NONE;
2282
2283   if (VEC_length (constructor_elt,
2284                   CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt))) > 0)
2285     {
2286       /* I have never seen this code path trigger but if it can happen the
2287          following should handle it gracefully.  */
2288       if (access_has_children_p (acc))
2289         generate_subtree_copies (acc->first_child, acc->base, 0, 0, 0, gsi,
2290                                  true, true);
2291       return SRA_SA_PROCESSED;
2292     }
2293
2294   if (acc->grp_covered)
2295     {
2296       init_subtree_with_zero (acc, gsi, false);
2297       unlink_stmt_vdef (*stmt);
2298       gsi_remove (gsi, true);
2299       return SRA_SA_REMOVED;
2300     }
2301   else
2302     {
2303       init_subtree_with_zero (acc, gsi, true);
2304       return SRA_SA_PROCESSED;
2305     }
2306 }
2307
2308
2309 /* Callback of scan_function to process assign statements.  It examines both
2310    sides of the statement, replaces them with a scalare replacement if there is
2311    one and generating copying of replacements if scalarized aggregates have been
2312    used in the assignment.  STMT is a pointer to the assign statement, GSI is
2313    used to hold generated statements for type conversions and subtree
2314    copying.  */
2315
2316 static enum scan_assign_result
2317 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi,
2318                    void *data ATTRIBUTE_UNUSED)
2319 {
2320   struct access *lacc, *racc;
2321   tree lhs, rhs;
2322   bool modify_this_stmt = false;
2323   bool force_gimple_rhs = false;
2324   location_t loc = gimple_location (*stmt);
2325
2326   if (!gimple_assign_single_p (*stmt))
2327     return SRA_SA_NONE;
2328   lhs = gimple_assign_lhs (*stmt);
2329   rhs = gimple_assign_rhs1 (*stmt);
2330
2331   if (TREE_CODE (rhs) == CONSTRUCTOR)
2332     return sra_modify_constructor_assign (stmt, gsi);
2333
2334   if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
2335       || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
2336       || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
2337     {
2338       modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (*stmt),
2339                                           gsi, false, data);
2340       modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (*stmt),
2341                                            gsi, true, data);
2342       return modify_this_stmt ? SRA_SA_PROCESSED : SRA_SA_NONE;
2343     }
2344
2345   lacc = get_access_for_expr (lhs);
2346   racc = get_access_for_expr (rhs);
2347   if (!lacc && !racc)
2348     return SRA_SA_NONE;
2349
2350   if (lacc && lacc->grp_to_be_replaced)
2351     {
2352       lhs = get_access_replacement (lacc);
2353       gimple_assign_set_lhs (*stmt, lhs);
2354       modify_this_stmt = true;
2355       if (lacc->grp_partial_lhs)
2356         force_gimple_rhs = true;
2357       sra_stats.exprs++;
2358     }
2359
2360   if (racc && racc->grp_to_be_replaced)
2361     {
2362       rhs = get_access_replacement (racc);
2363       modify_this_stmt = true;
2364       if (racc->grp_partial_lhs)
2365         force_gimple_rhs = true;
2366       sra_stats.exprs++;
2367     }
2368
2369   if (modify_this_stmt)
2370     {
2371       if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
2372         {
2373           /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
2374              ???  This should move to fold_stmt which we simply should
2375              call after building a VIEW_CONVERT_EXPR here.  */
2376           if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
2377               && !access_has_children_p (lacc))
2378             {
2379               tree expr = lhs;
2380               if (build_ref_for_offset (&expr, TREE_TYPE (lhs), 0,
2381                                         TREE_TYPE (rhs), false))
2382                 {
2383                   lhs = expr;
2384                   gimple_assign_set_lhs (*stmt, expr);
2385                 }
2386             }
2387           else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
2388                    && !access_has_children_p (racc))
2389             {
2390               tree expr = rhs;
2391               if (build_ref_for_offset (&expr, TREE_TYPE (rhs), 0,
2392                                         TREE_TYPE (lhs), false))
2393                 rhs = expr;
2394             }
2395           if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
2396             {
2397               rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs);
2398               if (!is_gimple_reg (lhs))
2399                 force_gimple_rhs = true;
2400             }
2401         }
2402
2403       if (force_gimple_rhs)
2404         rhs = force_gimple_operand_gsi (gsi, rhs, true, NULL_TREE,
2405                                         true, GSI_SAME_STMT);
2406       if (gimple_assign_rhs1 (*stmt) != rhs)
2407         {
2408           gimple_assign_set_rhs_from_tree (gsi, rhs);
2409           gcc_assert (*stmt == gsi_stmt (*gsi));
2410         }
2411     }
2412
2413   /* From this point on, the function deals with assignments in between
2414      aggregates when at least one has scalar reductions of some of its
2415      components.  There are three possible scenarios: Both the LHS and RHS have
2416      to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
2417
2418      In the first case, we would like to load the LHS components from RHS
2419      components whenever possible.  If that is not possible, we would like to
2420      read it directly from the RHS (after updating it by storing in it its own
2421      components).  If there are some necessary unscalarized data in the LHS,
2422      those will be loaded by the original assignment too.  If neither of these
2423      cases happen, the original statement can be removed.  Most of this is done
2424      by load_assign_lhs_subreplacements.
2425
2426      In the second case, we would like to store all RHS scalarized components
2427      directly into LHS and if they cover the aggregate completely, remove the
2428      statement too.  In the third case, we want the LHS components to be loaded
2429      directly from the RHS (DSE will remove the original statement if it
2430      becomes redundant).
2431
2432      This is a bit complex but manageable when types match and when unions do
2433      not cause confusion in a way that we cannot really load a component of LHS
2434      from the RHS or vice versa (the access representing this level can have
2435      subaccesses that are accessible only through a different union field at a
2436      higher level - different from the one used in the examined expression).
2437      Unions are fun.
2438
2439      Therefore, I specially handle a fourth case, happening when there is a
2440      specific type cast or it is impossible to locate a scalarized subaccess on
2441      the other side of the expression.  If that happens, I simply "refresh" the
2442      RHS by storing in it is scalarized components leave the original statement
2443      there to do the copying and then load the scalar replacements of the LHS.
2444      This is what the first branch does.  */
2445
2446   if (contains_view_convert_expr_p (rhs) || contains_view_convert_expr_p (lhs)
2447       || (access_has_children_p (racc)
2448           && !ref_expr_for_all_replacements_p (racc, lhs, racc->offset))
2449       || (access_has_children_p (lacc)
2450           && !ref_expr_for_all_replacements_p (lacc, rhs, lacc->offset)))
2451     {
2452       if (access_has_children_p (racc))
2453         generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
2454                                  gsi, false, false);
2455       if (access_has_children_p (lacc))
2456         generate_subtree_copies (lacc->first_child, lacc->base, 0, 0, 0,
2457                                  gsi, true, true);
2458       sra_stats.separate_lhs_rhs_handling++;
2459     }
2460   else
2461     {
2462       if (access_has_children_p (lacc) && access_has_children_p (racc))
2463         {
2464           gimple_stmt_iterator orig_gsi = *gsi;
2465           enum unscalarized_data_handling refreshed;
2466
2467           if (lacc->grp_read && !lacc->grp_covered)
2468             refreshed = handle_unscalarized_data_in_subtree (racc, lhs, gsi);
2469           else
2470             refreshed = SRA_UDH_NONE;
2471
2472           load_assign_lhs_subreplacements (lacc->first_child, racc,
2473                                            lacc->offset, racc->offset,
2474                                            &orig_gsi, gsi, &refreshed, lhs);
2475           if (refreshed != SRA_UDH_RIGHT)
2476             {
2477               if (*stmt == gsi_stmt (*gsi))
2478                 gsi_next (gsi);
2479
2480               unlink_stmt_vdef (*stmt);
2481               gsi_remove (&orig_gsi, true);
2482               sra_stats.deleted++;
2483               return SRA_SA_REMOVED;
2484             }
2485         }
2486       else
2487         {
2488           if (access_has_children_p (racc))
2489             {
2490               if (!racc->grp_unscalarized_data)
2491                 {
2492                   generate_subtree_copies (racc->first_child, lhs,
2493                                            racc->offset, 0, 0, gsi,
2494                                            false, false);
2495                   gcc_assert (*stmt == gsi_stmt (*gsi));
2496                   unlink_stmt_vdef (*stmt);
2497                   gsi_remove (gsi, true);
2498                   sra_stats.deleted++;
2499                   return SRA_SA_REMOVED;
2500                 }
2501               else
2502                 generate_subtree_copies (racc->first_child, lhs,
2503                                          racc->offset, 0, 0, gsi, false, true);
2504             }
2505           else if (access_has_children_p (lacc))
2506             generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
2507                                      0, 0, gsi, true, true);
2508         }
2509     }
2510   return modify_this_stmt ? SRA_SA_PROCESSED : SRA_SA_NONE;
2511 }
2512
2513 /* Generate statements initializing scalar replacements of parts of function
2514    parameters.  */
2515
2516 static void
2517 initialize_parameter_reductions (void)
2518 {
2519   gimple_stmt_iterator gsi;
2520   gimple_seq seq = NULL;
2521   tree parm;
2522
2523   for (parm = DECL_ARGUMENTS (current_function_decl);
2524        parm;
2525        parm = TREE_CHAIN (parm))
2526     {
2527       VEC (access_p, heap) *access_vec;
2528       struct access *access;
2529
2530       if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
2531         continue;
2532       access_vec = get_base_access_vector (parm);
2533       if (!access_vec)
2534         continue;
2535
2536       if (!seq)
2537         {
2538           seq = gimple_seq_alloc ();
2539           gsi = gsi_start (seq);
2540         }
2541
2542       for (access = VEC_index (access_p, access_vec, 0);
2543            access;
2544            access = access->next_grp)
2545         generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true);
2546     }
2547
2548   if (seq)
2549     gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR), seq);
2550 }
2551
2552 /* The "main" function of intraprocedural SRA passes.  Runs the analysis and if
2553    it reveals there are components of some aggregates to be scalarized, it runs
2554    the required transformations.  */
2555 static unsigned int
2556 perform_intra_sra (void)
2557 {
2558   int ret = 0;
2559   sra_initialize ();
2560
2561   if (!find_var_candidates ())
2562     goto out;
2563
2564   if (!scan_function (build_access_from_expr, build_accesses_from_assign, NULL,
2565                       true, NULL))
2566     goto out;
2567
2568   if (!analyze_all_variable_accesses ())
2569     goto out;
2570
2571   scan_function (sra_modify_expr, sra_modify_assign, NULL, false, NULL);
2572   initialize_parameter_reductions ();
2573
2574   statistics_counter_event (cfun, "Scalar replacements created",
2575                             sra_stats.replacements);
2576   statistics_counter_event (cfun, "Modified expressions", sra_stats.exprs);
2577   statistics_counter_event (cfun, "Subtree copy stmts",
2578                             sra_stats.subtree_copies);
2579   statistics_counter_event (cfun, "Subreplacement stmts",
2580                             sra_stats.subreplacements);
2581   statistics_counter_event (cfun, "Deleted stmts", sra_stats.deleted);
2582   statistics_counter_event (cfun, "Separate LHS and RHS handling",
2583                             sra_stats.separate_lhs_rhs_handling);
2584
2585   ret = TODO_update_ssa;
2586
2587  out:
2588   sra_deinitialize ();
2589   return ret;
2590 }
2591
2592 /* Perform early intraprocedural SRA.  */
2593 static unsigned int
2594 early_intra_sra (void)
2595 {
2596   sra_mode = SRA_MODE_EARLY_INTRA;
2597   return perform_intra_sra ();
2598 }
2599
2600 /* Perform "late" intraprocedural SRA.  */
2601 static unsigned int
2602 late_intra_sra (void)
2603 {
2604   sra_mode = SRA_MODE_INTRA;
2605   return perform_intra_sra ();
2606 }
2607
2608
2609 static bool
2610 gate_intra_sra (void)
2611 {
2612   return flag_tree_sra != 0;
2613 }
2614
2615
2616 struct gimple_opt_pass pass_sra_early =
2617 {
2618  {
2619   GIMPLE_PASS,
2620   "esra",                               /* name */
2621   gate_intra_sra,                       /* gate */
2622   early_intra_sra,                      /* execute */
2623   NULL,                                 /* sub */
2624   NULL,                                 /* next */
2625   0,                                    /* static_pass_number */
2626   TV_TREE_SRA,                          /* tv_id */
2627   PROP_cfg | PROP_ssa,                  /* properties_required */
2628   0,                                    /* properties_provided */
2629   0,                                    /* properties_destroyed */
2630   0,                                    /* todo_flags_start */
2631   TODO_dump_func
2632   | TODO_update_ssa
2633   | TODO_ggc_collect
2634   | TODO_verify_ssa                     /* todo_flags_finish */
2635  }
2636 };
2637
2638 struct gimple_opt_pass pass_sra =
2639 {
2640  {
2641   GIMPLE_PASS,
2642   "sra",                                /* name */
2643   gate_intra_sra,                       /* gate */
2644   late_intra_sra,                       /* execute */
2645   NULL,                                 /* sub */
2646   NULL,                                 /* next */
2647   0,                                    /* static_pass_number */
2648   TV_TREE_SRA,                          /* tv_id */
2649   PROP_cfg | PROP_ssa,                  /* properties_required */
2650   0,                                    /* properties_provided */
2651   0,                                    /* properties_destroyed */
2652   TODO_update_address_taken,            /* todo_flags_start */
2653   TODO_dump_func
2654   | TODO_update_ssa
2655   | TODO_ggc_collect
2656   | TODO_verify_ssa                     /* todo_flags_finish */
2657  }
2658 };
2659
2660
2661 /* Return true iff PARM (which must be a parm_decl) is an unused scalar
2662    parameter.  */
2663
2664 static bool
2665 is_unused_scalar_param (tree parm)
2666 {
2667   tree name;
2668   return (is_gimple_reg (parm)
2669           && (!(name = gimple_default_def (cfun, parm))
2670               || has_zero_uses (name)));
2671 }
2672
2673 /* Scan immediate uses of a default definition SSA name of a parameter PARM and
2674    examine whether there are any direct or otherwise infeasible ones.  If so,
2675    return true, otherwise return false.  PARM must be a gimple register with a
2676    non-NULL default definition.  */
2677
2678 static bool
2679 ptr_parm_has_direct_uses (tree parm)
2680 {
2681   imm_use_iterator ui;
2682   gimple stmt;
2683   tree name = gimple_default_def (cfun, parm);
2684   bool ret = false;
2685
2686   FOR_EACH_IMM_USE_STMT (stmt, ui, name)
2687     {
2688       if (gimple_assign_single_p (stmt))
2689         {
2690           tree rhs = gimple_assign_rhs1 (stmt);
2691           if (rhs == name)
2692             ret = true;
2693           else if (TREE_CODE (rhs) == ADDR_EXPR)
2694             {
2695               do
2696                 {
2697                   rhs = TREE_OPERAND (rhs, 0);
2698                 }
2699               while (handled_component_p (rhs));
2700               if (INDIRECT_REF_P (rhs) && TREE_OPERAND (rhs, 0) == name)
2701                 ret = true;
2702             }
2703         }
2704       else if (gimple_code (stmt) == GIMPLE_RETURN)
2705         {
2706           tree t = gimple_return_retval (stmt);
2707           if (t == name)
2708             ret = true;
2709         }
2710       else if (is_gimple_call (stmt))
2711         {
2712           unsigned i;
2713           for (i = 0; i < gimple_call_num_args (stmt); i++)
2714             {
2715               tree arg = gimple_call_arg (stmt, i);
2716               if (arg == name)
2717                 {
2718                   ret = true;
2719                   break;
2720                 }
2721             }
2722         }
2723       else if (!is_gimple_debug (stmt))
2724         ret = true;
2725
2726       if (ret)
2727         BREAK_FROM_IMM_USE_STMT (ui);
2728     }
2729
2730   return ret;
2731 }
2732
2733 /* Identify candidates for reduction for IPA-SRA based on their type and mark
2734    them in candidate_bitmap.  Note that these do not necessarily include
2735    parameter which are unused and thus can be removed.  Return true iff any
2736    such candidate has been found.  */
2737
2738 static bool
2739 find_param_candidates (void)
2740 {
2741   tree parm;
2742   int count = 0;
2743   bool ret = false;
2744
2745   for (parm = DECL_ARGUMENTS (current_function_decl);
2746        parm;
2747        parm = TREE_CHAIN (parm))
2748     {
2749       tree type = TREE_TYPE (parm);
2750
2751       count++;
2752
2753       if (TREE_THIS_VOLATILE (parm)
2754           || TREE_ADDRESSABLE (parm)
2755           || is_va_list_type (type))
2756         continue;
2757
2758       if (is_unused_scalar_param (parm))
2759         {
2760           ret = true;
2761           continue;
2762         }
2763
2764       if (POINTER_TYPE_P (type))
2765         {
2766           type = TREE_TYPE (type);
2767
2768           if (TREE_CODE (type) == FUNCTION_TYPE
2769               || TYPE_VOLATILE (type)
2770               || !is_gimple_reg (parm)
2771               || is_va_list_type (type)
2772               || ptr_parm_has_direct_uses (parm))
2773             continue;
2774         }
2775       else if (!AGGREGATE_TYPE_P (type))
2776         continue;
2777
2778       if (!COMPLETE_TYPE_P (type)
2779           || !host_integerp (TYPE_SIZE (type), 1)
2780           || tree_low_cst (TYPE_SIZE (type), 1) == 0
2781           || (AGGREGATE_TYPE_P (type)
2782               && type_internals_preclude_sra_p (type)))
2783         continue;
2784
2785       bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
2786       ret = true;
2787       if (dump_file && (dump_flags & TDF_DETAILS))
2788         {
2789           fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
2790           print_generic_expr (dump_file, parm, 0);
2791           fprintf (dump_file, "\n");
2792         }
2793     }
2794
2795   func_param_count = count;
2796   return ret;
2797 }
2798
2799 /* Callback of walk_aliased_vdefs, marks the access passed as DATA as
2800    maybe_modified. */
2801
2802 static bool
2803 mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
2804                      void *data)
2805 {
2806   struct access *repr = (struct access *) data;
2807
2808   repr->grp_maybe_modified = 1;
2809   return true;
2810 }
2811
2812 /* Analyze what representatives (in linked lists accessible from
2813    REPRESENTATIVES) can be modified by side effects of statements in the
2814    current function.  */
2815
2816 static void
2817 analyze_modified_params (VEC (access_p, heap) *representatives)
2818 {
2819   int i;
2820
2821   for (i = 0; i < func_param_count; i++)
2822     {
2823       struct access *repr = VEC_index (access_p, representatives, i);
2824       VEC (access_p, heap) *access_vec;
2825       int j, access_count;
2826       tree parm;
2827
2828       if (!repr || no_accesses_p (repr))
2829         continue;
2830       parm = repr->base;
2831       if (!POINTER_TYPE_P (TREE_TYPE (parm))
2832           || repr->grp_maybe_modified)
2833         continue;
2834
2835       access_vec = get_base_access_vector (parm);
2836       access_count = VEC_length (access_p, access_vec);
2837       for (j = 0; j < access_count; j++)
2838         {
2839           struct access *access;
2840           ao_ref ar;
2841
2842           /* All accesses are read ones, otherwise grp_maybe_modified would be
2843              trivially set.  */
2844           access = VEC_index (access_p, access_vec, j);
2845           ao_ref_init (&ar, access->expr);
2846           walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
2847                               mark_maybe_modified, repr, NULL);
2848           if (repr->grp_maybe_modified)
2849             break;
2850         }
2851     }
2852 }
2853
2854 /* Propagate distances in bb_dereferences in the opposite direction than the
2855    control flow edges, in each step storing the maximum of the current value
2856    and the minimum of all successors.  These steps are repeated until the table
2857    stabilizes.  Note that BBs which might terminate the functions (according to
2858    final_bbs bitmap) never updated in this way.  */
2859
2860 static void
2861 propagate_dereference_distances (void)
2862 {
2863   VEC (basic_block, heap) *queue;
2864   basic_block bb;
2865
2866   queue = VEC_alloc (basic_block, heap, last_basic_block_for_function (cfun));
2867   VEC_quick_push (basic_block, queue, ENTRY_BLOCK_PTR);
2868   FOR_EACH_BB (bb)
2869     {
2870       VEC_quick_push (basic_block, queue, bb);
2871       bb->aux = bb;
2872     }
2873
2874   while (!VEC_empty (basic_block, queue))
2875     {
2876       edge_iterator ei;
2877       edge e;
2878       bool change = false;
2879       int i;
2880
2881       bb = VEC_pop (basic_block, queue);
2882       bb->aux = NULL;
2883
2884       if (bitmap_bit_p (final_bbs, bb->index))
2885         continue;
2886
2887       for (i = 0; i < func_param_count; i++)
2888         {
2889           int idx = bb->index * func_param_count + i;
2890           bool first = true;
2891           HOST_WIDE_INT inh = 0;
2892
2893           FOR_EACH_EDGE (e, ei, bb->succs)
2894           {
2895             int succ_idx = e->dest->index * func_param_count + i;
2896
2897             if (e->src == EXIT_BLOCK_PTR)
2898               continue;
2899
2900             if (first)
2901               {
2902                 first = false;
2903                 inh = bb_dereferences [succ_idx];
2904               }
2905             else if (bb_dereferences [succ_idx] < inh)
2906               inh = bb_dereferences [succ_idx];
2907           }
2908
2909           if (!first && bb_dereferences[idx] < inh)
2910             {
2911               bb_dereferences[idx] = inh;
2912               change = true;
2913             }
2914         }
2915
2916       if (change && !bitmap_bit_p (final_bbs, bb->index))
2917         FOR_EACH_EDGE (e, ei, bb->preds)
2918           {
2919             if (e->src->aux)
2920               continue;
2921
2922             e->src->aux = e->src;
2923             VEC_quick_push (basic_block, queue, e->src);
2924           }
2925     }
2926
2927   VEC_free (basic_block, heap, queue);
2928 }
2929
2930 /* Dump a dereferences TABLE with heading STR to file F.  */
2931
2932 static void
2933 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
2934 {
2935   basic_block bb;
2936
2937   fprintf (dump_file, str);
2938   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
2939     {
2940       fprintf (f, "%4i  %i   ", bb->index, bitmap_bit_p (final_bbs, bb->index));
2941       if (bb != EXIT_BLOCK_PTR)
2942         {
2943           int i;
2944           for (i = 0; i < func_param_count; i++)
2945             {
2946               int idx = bb->index * func_param_count + i;
2947               fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
2948             }
2949         }
2950       fprintf (f, "\n");
2951     }
2952   fprintf (dump_file, "\n");
2953 }
2954
2955 /* Determine what (parts of) parameters passed by reference that are not
2956    assigned to are not certainly dereferenced in this function and thus the
2957    dereferencing cannot be safely moved to the caller without potentially
2958    introducing a segfault.  Mark such REPRESENTATIVES as
2959    grp_not_necessarilly_dereferenced.
2960
2961    The dereferenced maximum "distance," i.e. the offset + size of the accessed
2962    part is calculated rather than simple booleans are calculated for each
2963    pointer parameter to handle cases when only a fraction of the whole
2964    aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
2965    an example).
2966
2967    The maximum dereference distances for each pointer parameter and BB are
2968    already stored in bb_dereference.  This routine simply propagates these
2969    values upwards by propagate_dereference_distances and then compares the
2970    distances of individual parameters in the ENTRY BB to the equivalent
2971    distances of each representative of a (fraction of a) parameter.  */
2972
2973 static void
2974 analyze_caller_dereference_legality (VEC (access_p, heap) *representatives)
2975 {
2976   int i;
2977
2978   if (dump_file && (dump_flags & TDF_DETAILS))
2979     dump_dereferences_table (dump_file,
2980                              "Dereference table before propagation:\n",
2981                              bb_dereferences);
2982
2983   propagate_dereference_distances ();
2984
2985   if (dump_file && (dump_flags & TDF_DETAILS))
2986     dump_dereferences_table (dump_file,
2987                              "Dereference table after propagation:\n",
2988                              bb_dereferences);
2989
2990   for (i = 0; i < func_param_count; i++)
2991     {
2992       struct access *repr = VEC_index (access_p, representatives, i);
2993       int idx = ENTRY_BLOCK_PTR->index * func_param_count + i;
2994
2995       if (!repr || no_accesses_p (repr))
2996         continue;
2997
2998       do
2999         {
3000           if ((repr->offset + repr->size) > bb_dereferences[idx])
3001             repr->grp_not_necessarilly_dereferenced = 1;
3002           repr = repr->next_grp;
3003         }
3004       while (repr);
3005     }
3006 }
3007
3008 /* Return the representative access for the parameter declaration PARM if it is
3009    a scalar passed by reference which is not written to and the pointer value
3010    is not used directly.  Thus, if it is legal to dereference it in the caller
3011    and we can rule out modifications through aliases, such parameter should be
3012    turned into one passed by value.  Return NULL otherwise.  */
3013
3014 static struct access *
3015 unmodified_by_ref_scalar_representative (tree parm)
3016 {
3017   int i, access_count;
3018   struct access *access;
3019   VEC (access_p, heap) *access_vec;
3020
3021   access_vec = get_base_access_vector (parm);
3022   gcc_assert (access_vec);
3023   access_count = VEC_length (access_p, access_vec);
3024
3025   for (i = 0; i < access_count; i++)
3026     {
3027       access = VEC_index (access_p, access_vec, i);
3028       if (access->write)
3029         return NULL;
3030     }
3031
3032   access = VEC_index (access_p, access_vec, 0);
3033   access->grp_read = 1;
3034   access->grp_scalar_ptr = 1;
3035   return access;
3036 }
3037
3038 /* Sort collected accesses for parameter PARM, identify representatives for
3039    each accessed region and link them together.  Return NULL if there are
3040    different but overlapping accesses, return the special ptr value meaning
3041    there are no accesses for this parameter if that is the case and return the
3042    first representative otherwise.  Set *RO_GRP if there is a group of accesses
3043    with only read (i.e. no write) accesses.  */
3044
3045 static struct access *
3046 splice_param_accesses (tree parm, bool *ro_grp)
3047 {
3048   int i, j, access_count, group_count;
3049   int agg_size, total_size = 0;
3050   struct access *access, *res, **prev_acc_ptr = &res;
3051   VEC (access_p, heap) *access_vec;
3052
3053   access_vec = get_base_access_vector (parm);
3054   if (!access_vec)
3055     return &no_accesses_representant;
3056   access_count = VEC_length (access_p, access_vec);
3057
3058   qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
3059          compare_access_positions);
3060
3061   i = 0;
3062   total_size = 0;
3063   group_count = 0;
3064   while (i < access_count)
3065     {
3066       bool modification;
3067       access = VEC_index (access_p, access_vec, i);
3068       modification = access->write;
3069
3070       /* Access is about to become group representative unless we find some
3071          nasty overlap which would preclude us from breaking this parameter
3072          apart. */
3073
3074       j = i + 1;
3075       while (j < access_count)
3076         {
3077           struct access *ac2 = VEC_index (access_p, access_vec, j);
3078           if (ac2->offset != access->offset)
3079             {
3080               /* All or nothing law for parameters. */
3081               if (access->offset + access->size > ac2->offset)
3082                 return NULL;
3083               else
3084                 break;
3085             }
3086           else if (ac2->size != access->size)
3087             return NULL;
3088
3089           modification |= ac2->write;
3090           j++;
3091         }
3092
3093       group_count++;
3094       access->grp_maybe_modified = modification;
3095       if (!modification)
3096         *ro_grp = true;
3097       *prev_acc_ptr = access;
3098       prev_acc_ptr = &access->next_grp;
3099       total_size += access->size;
3100       i = j;
3101     }
3102
3103   if (POINTER_TYPE_P (TREE_TYPE (parm)))
3104     agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))), 1);
3105   else
3106     agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (parm)), 1);
3107   if (total_size >= agg_size)
3108     return NULL;
3109
3110   gcc_assert (group_count > 0);
3111   return res;
3112 }
3113
3114 /* Decide whether parameters with representative accesses given by REPR should
3115    be reduced into components.  */
3116
3117 static int
3118 decide_one_param_reduction (struct access *repr)
3119 {
3120   int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
3121   bool by_ref;
3122   tree parm;
3123
3124   parm = repr->base;
3125   cur_parm_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (parm)), 1);
3126   gcc_assert (cur_parm_size > 0);
3127
3128   if (POINTER_TYPE_P (TREE_TYPE (parm)))
3129     {
3130       by_ref = true;
3131       agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))), 1);
3132     }
3133   else
3134     {
3135       by_ref = false;
3136       agg_size = cur_parm_size;
3137     }
3138
3139   if (dump_file)
3140     {
3141       struct access *acc;
3142       fprintf (dump_file, "Evaluating PARAM group sizes for ");
3143       print_generic_expr (dump_file, parm, 0);
3144       fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
3145       for (acc = repr; acc; acc = acc->next_grp)
3146         dump_access (dump_file, acc, true);
3147     }
3148
3149   total_size = 0;
3150   new_param_count = 0;
3151
3152   for (; repr; repr = repr->next_grp)
3153     {
3154       gcc_assert (parm == repr->base);
3155       new_param_count++;
3156
3157       if (!by_ref || (!repr->grp_maybe_modified
3158                       && !repr->grp_not_necessarilly_dereferenced))
3159         total_size += repr->size;
3160       else
3161         total_size += cur_parm_size;
3162     }
3163
3164   gcc_assert (new_param_count > 0);
3165
3166   if (optimize_function_for_size_p (cfun))
3167     parm_size_limit = cur_parm_size;
3168   else
3169     parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
3170                        * cur_parm_size);
3171
3172   if (total_size < agg_size
3173       && total_size <= parm_size_limit)
3174     {
3175       if (dump_file)
3176         fprintf (dump_file, "    ....will be split into %i components\n",
3177                  new_param_count);
3178       return new_param_count;
3179     }
3180   else
3181     return 0;
3182 }
3183
3184 /* The order of the following enums is important, we need to do extra work for
3185    UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES.  */
3186 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
3187                           MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
3188
3189 /* Identify representatives of all accesses to all candidate parameters for
3190    IPA-SRA.  Return result based on what representatives have been found. */
3191
3192 static enum ipa_splicing_result
3193 splice_all_param_accesses (VEC (access_p, heap) **representatives)
3194 {
3195   enum ipa_splicing_result result = NO_GOOD_ACCESS;
3196   tree parm;
3197   struct access *repr;
3198
3199   *representatives = VEC_alloc (access_p, heap, func_param_count);
3200
3201   for (parm = DECL_ARGUMENTS (current_function_decl);
3202        parm;
3203        parm = TREE_CHAIN (parm))
3204     {
3205       if (is_unused_scalar_param (parm))
3206         {
3207           VEC_quick_push (access_p, *representatives,
3208                           &no_accesses_representant);
3209           if (result == NO_GOOD_ACCESS)
3210             result = UNUSED_PARAMS;
3211         }
3212       else if (POINTER_TYPE_P (TREE_TYPE (parm))
3213                && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
3214                && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3215         {
3216           repr = unmodified_by_ref_scalar_representative (parm);
3217           VEC_quick_push (access_p, *representatives, repr);
3218           if (repr)
3219             result = UNMODIF_BY_REF_ACCESSES;
3220         }
3221       else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3222         {
3223           bool ro_grp = false;
3224           repr = splice_param_accesses (parm, &ro_grp);
3225           VEC_quick_push (access_p, *representatives, repr);
3226
3227           if (repr && !no_accesses_p (repr))
3228             {
3229               if (POINTER_TYPE_P (TREE_TYPE (parm)))
3230                 {
3231                   if (ro_grp)
3232                     result = UNMODIF_BY_REF_ACCESSES;
3233                   else if (result < MODIF_BY_REF_ACCESSES)
3234                     result = MODIF_BY_REF_ACCESSES;
3235                 }
3236               else if (result < BY_VAL_ACCESSES)
3237                 result = BY_VAL_ACCESSES;
3238             }
3239           else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
3240             result = UNUSED_PARAMS;
3241         }
3242       else
3243         VEC_quick_push (access_p, *representatives, NULL);
3244     }
3245
3246   if (result == NO_GOOD_ACCESS)
3247     {
3248       VEC_free (access_p, heap, *representatives);
3249       *representatives = NULL;
3250       return NO_GOOD_ACCESS;
3251     }
3252
3253   return result;
3254 }
3255
3256 /* Return the index of BASE in PARMS.  Abort if it is not found.  */
3257
3258 static inline int
3259 get_param_index (tree base, VEC(tree, heap) *parms)
3260 {
3261   int i, len;
3262
3263   len = VEC_length (tree, parms);
3264   for (i = 0; i < len; i++)
3265     if (VEC_index (tree, parms, i) == base)
3266       return i;
3267   gcc_unreachable ();
3268 }
3269
3270 /* Convert the decisions made at the representative level into compact
3271    parameter adjustments.  REPRESENTATIVES are pointers to first
3272    representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
3273    final number of adjustments.  */
3274
3275 static ipa_parm_adjustment_vec
3276 turn_representatives_into_adjustments (VEC (access_p, heap) *representatives,
3277                                        int adjustments_count)
3278 {
3279   VEC (tree, heap) *parms;
3280   ipa_parm_adjustment_vec adjustments;
3281   tree parm;
3282   int i;
3283
3284   gcc_assert (adjustments_count > 0);
3285   parms = ipa_get_vector_of_formal_parms (current_function_decl);
3286   adjustments = VEC_alloc (ipa_parm_adjustment_t, heap, adjustments_count);
3287   parm = DECL_ARGUMENTS (current_function_decl);
3288   for (i = 0; i < func_param_count; i++, parm = TREE_CHAIN (parm))
3289     {
3290       struct access *repr = VEC_index (access_p, representatives, i);
3291
3292       if (!repr || no_accesses_p (repr))
3293         {
3294           struct ipa_parm_adjustment *adj;
3295
3296           adj = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
3297           memset (adj, 0, sizeof (*adj));
3298           adj->base_index = get_param_index (parm, parms);
3299           adj->base = parm;
3300           if (!repr)
3301             adj->copy_param = 1;
3302           else
3303             adj->remove_param = 1;
3304         }
3305       else
3306         {
3307           struct ipa_parm_adjustment *adj;
3308           int index = get_param_index (parm, parms);
3309
3310           for (; repr; repr = repr->next_grp)
3311             {
3312               adj = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
3313               memset (adj, 0, sizeof (*adj));
3314               gcc_assert (repr->base == parm);
3315               adj->base_index = index;
3316               adj->base = repr->base;
3317               adj->type = repr->type;
3318               adj->offset = repr->offset;
3319               adj->by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
3320                              && (repr->grp_maybe_modified
3321                                  || repr->grp_not_necessarilly_dereferenced));
3322
3323             }
3324         }
3325     }
3326   VEC_free (tree, heap, parms);
3327   return adjustments;
3328 }
3329
3330 /* Analyze the collected accesses and produce a plan what to do with the
3331    parameters in the form of adjustments, NULL meaning nothing.  */
3332
3333 static ipa_parm_adjustment_vec
3334 analyze_all_param_acesses (void)
3335 {
3336   enum ipa_splicing_result repr_state;
3337   bool proceed = false;
3338   int i, adjustments_count = 0;
3339   VEC (access_p, heap) *representatives;
3340   ipa_parm_adjustment_vec adjustments;
3341
3342   repr_state = splice_all_param_accesses (&representatives);
3343   if (repr_state == NO_GOOD_ACCESS)
3344     return NULL;
3345
3346   /* If there are any parameters passed by reference which are not modified
3347      directly, we need to check whether they can be modified indirectly.  */
3348   if (repr_state == UNMODIF_BY_REF_ACCESSES)
3349     {
3350       analyze_caller_dereference_legality (representatives);
3351       analyze_modified_params (representatives);
3352     }
3353
3354   for (i = 0; i < func_param_count; i++)
3355     {
3356       struct access *repr = VEC_index (access_p, representatives, i);
3357
3358       if (repr && !no_accesses_p (repr))
3359         {
3360           if (repr->grp_scalar_ptr)
3361             {
3362               adjustments_count++;
3363               if (repr->grp_not_necessarilly_dereferenced
3364                   || repr->grp_maybe_modified)
3365                 VEC_replace (access_p, representatives, i, NULL);
3366               else
3367                 {
3368                   proceed = true;
3369                   sra_stats.scalar_by_ref_to_by_val++;
3370                 }
3371             }
3372           else
3373             {
3374               int new_components = decide_one_param_reduction (repr);
3375
3376               if (new_components == 0)
3377                 {
3378                   VEC_replace (access_p, representatives, i, NULL);
3379                   adjustments_count++;
3380                 }
3381               else
3382                 {
3383                   adjustments_count += new_components;
3384                   sra_stats.aggregate_params_reduced++;
3385                   sra_stats.param_reductions_created += new_components;
3386                   proceed = true;
3387                 }
3388             }
3389         }
3390       else
3391         {
3392           if (no_accesses_p (repr))
3393             {
3394               proceed = true;
3395               sra_stats.deleted_unused_parameters++;
3396             }
3397           adjustments_count++;
3398         }
3399     }
3400
3401   if (!proceed && dump_file)
3402     fprintf (dump_file, "NOT proceeding to change params.\n");
3403
3404   if (proceed)
3405     adjustments = turn_representatives_into_adjustments (representatives,
3406                                                          adjustments_count);
3407   else
3408     adjustments = NULL;
3409
3410   VEC_free (access_p, heap, representatives);
3411   return adjustments;
3412 }
3413
3414 /* If a parameter replacement identified by ADJ does not yet exist in the form
3415    of declaration, create it and record it, otherwise return the previously
3416    created one.  */
3417
3418 static tree
3419 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
3420 {
3421   tree repl;
3422   if (!adj->new_ssa_base)
3423     {
3424       char *pretty_name = make_fancy_name (adj->base);
3425
3426       repl = make_rename_temp (TREE_TYPE (adj->base), "ISR");
3427       DECL_NAME (repl) = get_identifier (pretty_name);
3428       obstack_free (&name_obstack, pretty_name);
3429
3430       get_var_ann (repl);
3431       add_referenced_var (repl);
3432       adj->new_ssa_base = repl;
3433     }
3434   else
3435     repl = adj->new_ssa_base;
3436   return repl;
3437 }
3438
3439 /* Find the first adjustment for a particular parameter BASE in a vector of
3440    ADJUSTMENTS which is not a copy_param.  Return NULL if there is no such
3441    adjustment. */
3442
3443 static struct ipa_parm_adjustment *
3444 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
3445 {
3446   int i, len;
3447
3448   len = VEC_length (ipa_parm_adjustment_t, adjustments);
3449   for (i = 0; i < len; i++)
3450     {
3451       struct ipa_parm_adjustment *adj;
3452
3453       adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3454       if (!adj->copy_param && adj->base == base)
3455         return adj;
3456     }
3457
3458   return NULL;
3459 }
3460
3461 /* Callback for scan_function.  If the statement STMT defines an SSA_NAME of a
3462    parameter which is to be removed because its value is not used, replace the
3463    SSA_NAME with a one relating to a created VAR_DECL and replace all of its
3464    uses too.  DATA is a pointer to an adjustments vector.  */
3465
3466 static bool
3467 replace_removed_params_ssa_names (gimple stmt, void *data)
3468 {
3469   VEC (ipa_parm_adjustment_t, heap) *adjustments;
3470   struct ipa_parm_adjustment *adj;
3471   tree lhs, decl, repl, name;
3472
3473   adjustments = (VEC (ipa_parm_adjustment_t, heap) *) data;
3474   if (gimple_code (stmt) == GIMPLE_PHI)
3475     lhs = gimple_phi_result (stmt);
3476   else if (is_gimple_assign (stmt))
3477     lhs = gimple_assign_lhs (stmt);
3478   else if (is_gimple_call (stmt))
3479     lhs = gimple_call_lhs (stmt);
3480   else
3481     gcc_unreachable ();
3482
3483   if (TREE_CODE (lhs) != SSA_NAME)
3484     return false;
3485   decl = SSA_NAME_VAR (lhs);
3486   if (TREE_CODE (decl) != PARM_DECL)
3487     return false;
3488
3489   adj = get_adjustment_for_base (adjustments, decl);
3490   if (!adj)
3491     return false;
3492
3493   repl = get_replaced_param_substitute (adj);
3494   name = make_ssa_name (repl, stmt);
3495
3496   if (dump_file)
3497     {
3498       fprintf (dump_file, "replacing an SSA name of a removed param ");
3499       print_generic_expr (dump_file, lhs, 0);
3500       fprintf (dump_file, " with ");
3501       print_generic_expr (dump_file, name, 0);
3502       fprintf (dump_file, "\n");
3503     }
3504
3505   if (is_gimple_assign (stmt))
3506     gimple_assign_set_lhs (stmt, name);
3507   else if (is_gimple_call (stmt))
3508     gimple_call_set_lhs (stmt, name);
3509   else
3510     gimple_phi_set_result (stmt, name);
3511
3512   replace_uses_by (lhs, name);
3513   return true;
3514 }
3515
3516 /* Callback for scan_function.  If the expression *EXPR should be replaced by a
3517    reduction of a parameter, do so.  DATA is a pointer to a vector of
3518    adjustments.  */
3519
3520 static bool
3521 sra_ipa_modify_expr (tree *expr, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
3522                      bool write ATTRIBUTE_UNUSED, void *data)
3523 {
3524   ipa_parm_adjustment_vec adjustments;
3525   int i, len;
3526   struct ipa_parm_adjustment *adj, *cand = NULL;
3527   HOST_WIDE_INT offset, size, max_size;
3528   tree base, src;
3529
3530   adjustments = (VEC (ipa_parm_adjustment_t, heap) *) data;
3531   len = VEC_length (ipa_parm_adjustment_t, adjustments);
3532
3533   if (TREE_CODE (*expr) == BIT_FIELD_REF
3534       || TREE_CODE (*expr) == IMAGPART_EXPR
3535       || TREE_CODE (*expr) == REALPART_EXPR)
3536     expr = &TREE_OPERAND (*expr, 0);
3537   while (TREE_CODE (*expr) == NOP_EXPR
3538          || TREE_CODE (*expr) == VIEW_CONVERT_EXPR)
3539     expr = &TREE_OPERAND (*expr, 0);
3540
3541   base = get_ref_base_and_extent (*expr, &offset, &size, &max_size);
3542   if (!base || size == -1 || max_size == -1)
3543     return false;
3544
3545   if (INDIRECT_REF_P (base))
3546     base = TREE_OPERAND (base, 0);
3547
3548   base = get_ssa_base_param (base);
3549   if (!base || TREE_CODE (base) != PARM_DECL)
3550     return false;
3551
3552   for (i = 0; i < len; i++)
3553     {
3554       adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3555
3556       if (adj->base == base &&
3557           (adj->offset == offset || adj->remove_param))
3558         {
3559           cand = adj;
3560           break;
3561         }
3562     }
3563   if (!cand || cand->copy_param || cand->remove_param)
3564     return false;
3565
3566   if (cand->by_ref)
3567     {
3568       tree folded;
3569       src = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (cand->reduction)),
3570                     cand->reduction);
3571       folded = gimple_fold_indirect_ref (src);
3572       if (folded)
3573         src = folded;
3574     }
3575   else
3576     src = cand->reduction;
3577
3578   if (dump_file && (dump_flags & TDF_DETAILS))
3579     {
3580       fprintf (dump_file, "About to replace expr ");
3581       print_generic_expr (dump_file, *expr, 0);
3582       fprintf (dump_file, " with ");
3583       print_generic_expr (dump_file, src, 0);
3584       fprintf (dump_file, "\n");
3585     }
3586
3587   if (!useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
3588     {
3589       tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
3590       *expr = vce;
3591     }
3592     else
3593       *expr = src;
3594   return true;
3595 }
3596
3597 /* Callback for scan_function to process assign statements.  Performs
3598    essentially the same function like sra_ipa_modify_expr.  */
3599
3600 static enum scan_assign_result
3601 sra_ipa_modify_assign (gimple *stmt_ptr,
3602                        gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED, void *data)
3603 {
3604   gimple stmt = *stmt_ptr;
3605   bool any = false;
3606
3607   if (!gimple_assign_single_p (stmt))
3608     return SRA_SA_NONE;
3609
3610   any |= sra_ipa_modify_expr (gimple_assign_rhs1_ptr (stmt), gsi, false,
3611                               data);
3612   any |= sra_ipa_modify_expr (gimple_assign_lhs_ptr (stmt), gsi, true, data);
3613
3614   return any ? SRA_SA_PROCESSED : SRA_SA_NONE;
3615 }
3616
3617 /* Call gimple_debug_bind_reset_value on all debug statements describing
3618    gimple register parameters that are being removed or replaced.  */
3619
3620 static void
3621 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
3622 {
3623   int i, len;
3624
3625   len = VEC_length (ipa_parm_adjustment_t, adjustments);
3626   for (i = 0; i < len; i++)
3627     {
3628       struct ipa_parm_adjustment *adj;
3629       imm_use_iterator ui;
3630       gimple stmt;
3631       tree name;
3632
3633       adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3634       if (adj->copy_param || !is_gimple_reg (adj->base))
3635         continue;
3636       name = gimple_default_def (cfun, adj->base);
3637       if (!name)
3638         continue;
3639       FOR_EACH_IMM_USE_STMT (stmt, ui, name)
3640         {
3641           /* All other users must have been removed by scan_function.  */
3642           gcc_assert (is_gimple_debug (stmt));
3643           gimple_debug_bind_reset_value (stmt);
3644           update_stmt (stmt);
3645         }
3646     }
3647 }
3648
3649 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS.  */
3650
3651 static void
3652 convert_callers (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
3653 {
3654   tree old_cur_fndecl = current_function_decl;
3655   struct cgraph_edge *cs;
3656   basic_block this_block;
3657   bitmap recomputed_callers = BITMAP_ALLOC (NULL);
3658
3659   for (cs = node->callers; cs; cs = cs->next_caller)
3660     {
3661       current_function_decl = cs->caller->decl;
3662       push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
3663
3664       if (dump_file)
3665         fprintf (dump_file, "Adjusting call (%i -> %i) %s -> %s\n",
3666                  cs->caller->uid, cs->callee->uid,
3667                  cgraph_node_name (cs->caller),
3668                  cgraph_node_name (cs->callee));
3669
3670       ipa_modify_call_arguments (cs, cs->call_stmt, adjustments);
3671
3672       pop_cfun ();
3673     }
3674
3675   for (cs = node->callers; cs; cs = cs->next_caller)
3676     if (!bitmap_bit_p (recomputed_callers, cs->caller->uid))
3677       {
3678         compute_inline_parameters (cs->caller);
3679         bitmap_set_bit (recomputed_callers, cs->caller->uid);
3680       }
3681   BITMAP_FREE (recomputed_callers);
3682
3683   current_function_decl = old_cur_fndecl;
3684   FOR_EACH_BB (this_block)
3685     {
3686       gimple_stmt_iterator gsi;
3687
3688       for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
3689         {
3690           gimple stmt = gsi_stmt (gsi);
3691           if (gimple_code (stmt) == GIMPLE_CALL
3692               && gimple_call_fndecl (stmt) == node->decl)
3693             {
3694               if (dump_file)
3695                 fprintf (dump_file, "Adjusting recursive call");
3696               ipa_modify_call_arguments (NULL, stmt, adjustments);
3697             }
3698         }
3699     }
3700
3701   return;
3702 }
3703
3704 /* Perform all the modification required in IPA-SRA for NODE to have parameters
3705    as given in ADJUSTMENTS.  */
3706
3707 static void
3708 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
3709 {
3710   ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA");
3711   scan_function (sra_ipa_modify_expr, sra_ipa_modify_assign,
3712                  replace_removed_params_ssa_names, false, adjustments);
3713   sra_ipa_reset_debug_stmts (adjustments);
3714   convert_callers (node, adjustments);
3715   cgraph_make_node_local (node);
3716   return;
3717 }
3718
3719 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
3720    attributes, return true otherwise.  NODE is the cgraph node of the current
3721    function.  */
3722
3723 static bool
3724 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
3725 {
3726   if (!cgraph_node_can_be_local_p (node))
3727     {
3728       if (dump_file)
3729         fprintf (dump_file, "Function not local to this compilation unit.\n");
3730       return false;
3731     }
3732
3733   if (DECL_VIRTUAL_P (current_function_decl))
3734     {
3735       if (dump_file)
3736         fprintf (dump_file, "Function is a virtual method.\n");
3737       return false;
3738     }
3739
3740   if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
3741       && node->global.size >= MAX_INLINE_INSNS_AUTO)
3742     {
3743       if (dump_file)
3744         fprintf (dump_file, "Function too big to be made truly local.\n");
3745       return false;
3746     }
3747
3748   if (!node->callers)
3749     {
3750       if (dump_file)
3751         fprintf (dump_file,
3752                  "Function has no callers in this compilation unit.\n");
3753       return false;
3754     }
3755
3756   if (cfun->stdarg)
3757     {
3758       if (dump_file)
3759         fprintf (dump_file, "Function uses stdarg. \n");
3760       return false;
3761     }
3762
3763   return true;
3764 }
3765
3766 /* Perform early interprocedural SRA.  */
3767
3768 static unsigned int
3769 ipa_early_sra (void)
3770 {
3771   struct cgraph_node *node = cgraph_node (current_function_decl);
3772   ipa_parm_adjustment_vec adjustments;
3773   int ret = 0;
3774
3775   if (!ipa_sra_preliminary_function_checks (node))
3776     return 0;
3777
3778   sra_initialize ();
3779   sra_mode = SRA_MODE_EARLY_IPA;
3780
3781   if (!find_param_candidates ())
3782     {
3783       if (dump_file)
3784         fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
3785       goto simple_out;
3786     }
3787
3788   bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
3789                                  func_param_count
3790                                  * last_basic_block_for_function (cfun));
3791   final_bbs = BITMAP_ALLOC (NULL);
3792
3793   scan_function (build_access_from_expr, build_accesses_from_assign,
3794                  NULL, true, NULL);
3795   if (encountered_apply_args)
3796     {
3797       if (dump_file)
3798         fprintf (dump_file, "Function calls  __builtin_apply_args().\n");
3799       goto out;
3800     }
3801
3802   adjustments = analyze_all_param_acesses ();
3803   if (!adjustments)
3804     goto out;
3805   if (dump_file)
3806     ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
3807
3808   modify_function (node, adjustments);
3809   VEC_free (ipa_parm_adjustment_t, heap, adjustments);
3810   ret = TODO_update_ssa;
3811
3812   statistics_counter_event (cfun, "Unused parameters deleted",
3813                             sra_stats.deleted_unused_parameters);
3814   statistics_counter_event (cfun, "Scalar parameters converted to by-value",
3815                             sra_stats.scalar_by_ref_to_by_val);
3816   statistics_counter_event (cfun, "Aggregate parameters broken up",
3817                             sra_stats.aggregate_params_reduced);
3818   statistics_counter_event (cfun, "Aggregate parameter components created",
3819                             sra_stats.param_reductions_created);
3820
3821  out:
3822   BITMAP_FREE (final_bbs);
3823   free (bb_dereferences);
3824  simple_out:
3825   sra_deinitialize ();
3826   return ret;
3827 }
3828
3829 /* Return if early ipa sra shall be performed.  */
3830 static bool
3831 ipa_early_sra_gate (void)
3832 {
3833   return flag_ipa_sra;
3834 }
3835
3836 struct gimple_opt_pass pass_early_ipa_sra =
3837 {
3838  {
3839   GIMPLE_PASS,
3840   "eipa_sra",                           /* name */
3841   ipa_early_sra_gate,                   /* gate */
3842   ipa_early_sra,                        /* execute */
3843   NULL,                                 /* sub */
3844   NULL,                                 /* next */
3845   0,                                    /* static_pass_number */
3846   TV_IPA_SRA,                           /* tv_id */
3847   0,                                    /* properties_required */
3848   0,                                    /* properties_provided */
3849   0,                                    /* properties_destroyed */
3850   0,                                    /* todo_flags_start */
3851   TODO_dump_func | TODO_dump_cgraph     /* todo_flags_finish */
3852  }
3853 };
3854
3855