OSDN Git Service

* ipa.c (function_and_variable_visibility): Fix my accidentail commit and
[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   /* In intraprocedural SRA, pointer to the next sibling in the access tree as
148      described above.  In IPA-SRA this is a pointer to the next access
149      belonging to the same group (having the same representative).  */
150   struct access *next_sibling;
151
152   /* Pointers to the first and last element in the linked list of assign
153      links.  */
154   struct assign_link *first_link, *last_link;
155
156   /* Pointer to the next access in the work queue.  */
157   struct access *next_queued;
158
159   /* Replacement variable for this access "region."  Never to be accessed
160      directly, always only by the means of get_access_replacement() and only
161      when grp_to_be_replaced flag is set.  */
162   tree replacement_decl;
163
164   /* Is this particular access write access? */
165   unsigned write : 1;
166
167   /* Is this access currently in the work queue?  */
168   unsigned grp_queued : 1;
169
170   /* Does this group contain a write access?  This flag is propagated down the
171      access tree.  */
172   unsigned grp_write : 1;
173
174   /* Does this group contain a read access?  This flag is propagated down the
175      access tree.  */
176   unsigned grp_read : 1;
177
178   /* Other passes of the analysis use this bit to make function
179      analyze_access_subtree create scalar replacements for this group if
180      possible.  */
181   unsigned grp_hint : 1;
182
183   /* Is the subtree rooted in this access fully covered by scalar
184      replacements?  */
185   unsigned grp_covered : 1;
186
187   /* If set to true, this access and all below it in an access tree must not be
188      scalarized.  */
189   unsigned grp_unscalarizable_region : 1;
190
191   /* Whether data have been written to parts of the aggregate covered by this
192      access which is not to be scalarized.  This flag is propagated up in the
193      access tree.  */
194   unsigned grp_unscalarized_data : 1;
195
196   /* Does this access and/or group contain a write access through a
197      BIT_FIELD_REF?  */
198   unsigned grp_partial_lhs : 1;
199
200   /* Set when a scalar replacement should be created for this variable.  We do
201      the decision and creation at different places because create_tmp_var
202      cannot be called from within FOR_EACH_REFERENCED_VAR. */
203   unsigned grp_to_be_replaced : 1;
204
205   /* Is it possible that the group refers to data which might be (directly or
206      otherwise) modified?  */
207   unsigned grp_maybe_modified : 1;
208
209   /* Set when this is a representative of a pointer to scalar (i.e. by
210      reference) parameter which we consider for turning into a plain scalar
211      (i.e. a by value parameter).  */
212   unsigned grp_scalar_ptr : 1;
213
214   /* Set when we discover that this pointer is not safe to dereference in the
215      caller.  */
216   unsigned grp_not_necessarilly_dereferenced : 1;
217 };
218
219 typedef struct access *access_p;
220
221 DEF_VEC_P (access_p);
222 DEF_VEC_ALLOC_P (access_p, heap);
223
224 /* Alloc pool for allocating access structures.  */
225 static alloc_pool access_pool;
226
227 /* A structure linking lhs and rhs accesses from an aggregate assignment.  They
228    are used to propagate subaccesses from rhs to lhs as long as they don't
229    conflict with what is already there.  */
230 struct assign_link
231 {
232   struct access *lacc, *racc;
233   struct assign_link *next;
234 };
235
236 /* Alloc pool for allocating assign link structures.  */
237 static alloc_pool link_pool;
238
239 /* Base (tree) -> Vector (VEC(access_p,heap) *) map.  */
240 static struct pointer_map_t *base_access_vec;
241
242 /* Bitmap of candidates.  */
243 static bitmap candidate_bitmap;
244
245 /* Obstack for creation of fancy names.  */
246 static struct obstack name_obstack;
247
248 /* Head of a linked list of accesses that need to have its subaccesses
249    propagated to their assignment counterparts. */
250 static struct access *work_queue_head;
251
252 /* Number of parameters of the analyzed function when doing early ipa SRA.  */
253 static int func_param_count;
254
255 /* scan_function sets the following to true if it encounters a call to
256    __builtin_apply_args.  */
257 static bool encountered_apply_args;
258
259 /* This is a table in which for each basic block and parameter there is a
260    distance (offset + size) in that parameter which is dereferenced and
261    accessed in that BB.  */
262 static HOST_WIDE_INT *bb_dereferences;
263 /* Bitmap of BBs that can cause the function to "stop" progressing by
264    returning, throwing externally, looping infinitely or calling a function
265    which might abort etc.. */
266 static bitmap final_bbs;
267
268 /* Representative of no accesses at all. */
269 static struct access  no_accesses_representant;
270
271 /* Predicate to test the special value.  */
272
273 static inline bool
274 no_accesses_p (struct access *access)
275 {
276   return access == &no_accesses_representant;
277 }
278
279 /* Dump contents of ACCESS to file F in a human friendly way.  If GRP is true,
280    representative fields are dumped, otherwise those which only describe the
281    individual access are.  */
282
283 static struct
284 {
285   /* Number of processed aggregates is readily available in
286      analyze_all_variable_accesses and so is not stored here.  */
287
288   /* Number of created scalar replacements.  */
289   int replacements;
290
291   /* Number of times sra_modify_expr or sra_modify_assign themselves changed an
292      expression.  */
293   int exprs;
294
295   /* Number of statements created by generate_subtree_copies.  */
296   int subtree_copies;
297
298   /* Number of statements created by load_assign_lhs_subreplacements.  */
299   int subreplacements;
300
301   /* Number of times sra_modify_assign has deleted a statement.  */
302   int deleted;
303
304   /* Number of times sra_modify_assign has to deal with subaccesses of LHS and
305      RHS reparately due to type conversions or nonexistent matching
306      references.  */
307   int separate_lhs_rhs_handling;
308
309   /* Number of parameters that were removed because they were unused.  */
310   int deleted_unused_parameters;
311
312   /* Number of scalars passed as parameters by reference that have been
313      converted to be passed by value.  */
314   int scalar_by_ref_to_by_val;
315
316   /* Number of aggregate parameters that were replaced by one or more of their
317      components.  */
318   int aggregate_params_reduced;
319
320   /* Numbber of components created when splitting aggregate parameters.  */
321   int param_reductions_created;
322 } sra_stats;
323
324 static void
325 dump_access (FILE *f, struct access *access, bool grp)
326 {
327   fprintf (f, "access { ");
328   fprintf (f, "base = (%d)'", DECL_UID (access->base));
329   print_generic_expr (f, access->base, 0);
330   fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
331   fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
332   fprintf (f, ", expr = ");
333   print_generic_expr (f, access->expr, 0);
334   fprintf (f, ", type = ");
335   print_generic_expr (f, access->type, 0);
336   if (grp)
337     fprintf (f, ", grp_write = %d, grp_read = %d, grp_hint = %d, "
338              "grp_covered = %d, grp_unscalarizable_region = %d, "
339              "grp_unscalarized_data = %d, grp_partial_lhs = %d, "
340              "grp_to_be_replaced = %d\n grp_maybe_modified = %d, "
341              "grp_not_necessarilly_dereferenced = %d\n",
342              access->grp_write, access->grp_read, access->grp_hint,
343              access->grp_covered, access->grp_unscalarizable_region,
344              access->grp_unscalarized_data, access->grp_partial_lhs,
345              access->grp_to_be_replaced, access->grp_maybe_modified,
346              access->grp_not_necessarilly_dereferenced);
347   else
348     fprintf (f, ", write = %d, grp_partial_lhs = %d\n", access->write,
349              access->grp_partial_lhs);
350 }
351
352 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL.  */
353
354 static void
355 dump_access_tree_1 (FILE *f, struct access *access, int level)
356 {
357   do
358     {
359       int i;
360
361       for (i = 0; i < level; i++)
362         fputs ("* ", dump_file);
363
364       dump_access (f, access, true);
365
366       if (access->first_child)
367         dump_access_tree_1 (f, access->first_child, level + 1);
368
369       access = access->next_sibling;
370     }
371   while (access);
372 }
373
374 /* Dump all access trees for a variable, given the pointer to the first root in
375    ACCESS.  */
376
377 static void
378 dump_access_tree (FILE *f, struct access *access)
379 {
380   for (; access; access = access->next_grp)
381     dump_access_tree_1 (f, access, 0);
382 }
383
384 /* Return true iff ACC is non-NULL and has subaccesses.  */
385
386 static inline bool
387 access_has_children_p (struct access *acc)
388 {
389   return acc && acc->first_child;
390 }
391
392 /* Return a vector of pointers to accesses for the variable given in BASE or
393    NULL if there is none.  */
394
395 static VEC (access_p, heap) *
396 get_base_access_vector (tree base)
397 {
398   void **slot;
399
400   slot = pointer_map_contains (base_access_vec, base);
401   if (!slot)
402     return NULL;
403   else
404     return *(VEC (access_p, heap) **) slot;
405 }
406
407 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
408    in ACCESS.  Return NULL if it cannot be found.  */
409
410 static struct access *
411 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
412                         HOST_WIDE_INT size)
413 {
414   while (access && (access->offset != offset || access->size != size))
415     {
416       struct access *child = access->first_child;
417
418       while (child && (child->offset + child->size <= offset))
419         child = child->next_sibling;
420       access = child;
421     }
422
423   return access;
424 }
425
426 /* Return the first group representative for DECL or NULL if none exists.  */
427
428 static struct access *
429 get_first_repr_for_decl (tree base)
430 {
431   VEC (access_p, heap) *access_vec;
432
433   access_vec = get_base_access_vector (base);
434   if (!access_vec)
435     return NULL;
436
437   return VEC_index (access_p, access_vec, 0);
438 }
439
440 /* Find an access representative for the variable BASE and given OFFSET and
441    SIZE.  Requires that access trees have already been built.  Return NULL if
442    it cannot be found.  */
443
444 static struct access *
445 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
446                                  HOST_WIDE_INT size)
447 {
448   struct access *access;
449
450   access = get_first_repr_for_decl (base);
451   while (access && (access->offset + access->size <= offset))
452     access = access->next_grp;
453   if (!access)
454     return NULL;
455
456   return find_access_in_subtree (access, offset, size);
457 }
458
459 /* Add LINK to the linked list of assign links of RACC.  */
460 static void
461 add_link_to_rhs (struct access *racc, struct assign_link *link)
462 {
463   gcc_assert (link->racc == racc);
464
465   if (!racc->first_link)
466     {
467       gcc_assert (!racc->last_link);
468       racc->first_link = link;
469     }
470   else
471     racc->last_link->next = link;
472
473   racc->last_link = link;
474   link->next = NULL;
475 }
476
477 /* Move all link structures in their linked list in OLD_RACC to the linked list
478    in NEW_RACC.  */
479 static void
480 relink_to_new_repr (struct access *new_racc, struct access *old_racc)
481 {
482   if (!old_racc->first_link)
483     {
484       gcc_assert (!old_racc->last_link);
485       return;
486     }
487
488   if (new_racc->first_link)
489     {
490       gcc_assert (!new_racc->last_link->next);
491       gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
492
493       new_racc->last_link->next = old_racc->first_link;
494       new_racc->last_link = old_racc->last_link;
495     }
496   else
497     {
498       gcc_assert (!new_racc->last_link);
499
500       new_racc->first_link = old_racc->first_link;
501       new_racc->last_link = old_racc->last_link;
502     }
503   old_racc->first_link = old_racc->last_link = NULL;
504 }
505
506 /* Add ACCESS to the work queue (which is actually a stack).  */
507
508 static void
509 add_access_to_work_queue (struct access *access)
510 {
511   if (!access->grp_queued)
512     {
513       gcc_assert (!access->next_queued);
514       access->next_queued = work_queue_head;
515       access->grp_queued = 1;
516       work_queue_head = access;
517     }
518 }
519
520 /* Pop an access from the work queue, and return it, assuming there is one.  */
521
522 static struct access *
523 pop_access_from_work_queue (void)
524 {
525   struct access *access = work_queue_head;
526
527   work_queue_head = access->next_queued;
528   access->next_queued = NULL;
529   access->grp_queued = 0;
530   return access;
531 }
532
533
534 /* Allocate necessary structures.  */
535
536 static void
537 sra_initialize (void)
538 {
539   candidate_bitmap = BITMAP_ALLOC (NULL);
540   gcc_obstack_init (&name_obstack);
541   access_pool = create_alloc_pool ("SRA accesses", sizeof (struct access), 16);
542   link_pool = create_alloc_pool ("SRA links", sizeof (struct assign_link), 16);
543   base_access_vec = pointer_map_create ();
544   memset (&sra_stats, 0, sizeof (sra_stats));
545   encountered_apply_args = false;
546 }
547
548 /* Hook fed to pointer_map_traverse, deallocate stored vectors.  */
549
550 static bool
551 delete_base_accesses (const void *key ATTRIBUTE_UNUSED, void **value,
552                      void *data ATTRIBUTE_UNUSED)
553 {
554   VEC (access_p, heap) *access_vec;
555   access_vec = (VEC (access_p, heap) *) *value;
556   VEC_free (access_p, heap, access_vec);
557
558   return true;
559 }
560
561 /* Deallocate all general structures.  */
562
563 static void
564 sra_deinitialize (void)
565 {
566   BITMAP_FREE (candidate_bitmap);
567   free_alloc_pool (access_pool);
568   free_alloc_pool (link_pool);
569   obstack_free (&name_obstack, NULL);
570
571   pointer_map_traverse (base_access_vec, delete_base_accesses, NULL);
572   pointer_map_destroy (base_access_vec);
573 }
574
575 /* Remove DECL from candidates for SRA and write REASON to the dump file if
576    there is one.  */
577 static void
578 disqualify_candidate (tree decl, const char *reason)
579 {
580   bitmap_clear_bit (candidate_bitmap, DECL_UID (decl));
581
582   if (dump_file && (dump_flags & TDF_DETAILS))
583     {
584       fprintf (dump_file, "! Disqualifying ");
585       print_generic_expr (dump_file, decl, 0);
586       fprintf (dump_file, " - %s\n", reason);
587     }
588 }
589
590 /* Return true iff the type contains a field or an element which does not allow
591    scalarization.  */
592
593 static bool
594 type_internals_preclude_sra_p (tree type)
595 {
596   tree fld;
597   tree et;
598
599   switch (TREE_CODE (type))
600     {
601     case RECORD_TYPE:
602     case UNION_TYPE:
603     case QUAL_UNION_TYPE:
604       for (fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
605         if (TREE_CODE (fld) == FIELD_DECL)
606           {
607             tree ft = TREE_TYPE (fld);
608
609             if (TREE_THIS_VOLATILE (fld)
610                 || !DECL_FIELD_OFFSET (fld) || !DECL_SIZE (fld)
611                 || !host_integerp (DECL_FIELD_OFFSET (fld), 1)
612                 || !host_integerp (DECL_SIZE (fld), 1))
613               return true;
614
615             if (AGGREGATE_TYPE_P (ft)
616                 && type_internals_preclude_sra_p (ft))
617               return true;
618           }
619
620       return false;
621
622     case ARRAY_TYPE:
623       et = TREE_TYPE (type);
624
625       if (AGGREGATE_TYPE_P (et))
626         return type_internals_preclude_sra_p (et);
627       else
628         return false;
629
630     default:
631       return false;
632     }
633 }
634
635 /* If T is an SSA_NAME, return NULL if it is not a default def or return its
636    base variable if it is.  Return T if it is not an SSA_NAME.  */
637
638 static tree
639 get_ssa_base_param (tree t)
640 {
641   if (TREE_CODE (t) == SSA_NAME)
642     {
643       if (SSA_NAME_IS_DEFAULT_DEF (t))
644         return SSA_NAME_VAR (t);
645       else
646         return NULL_TREE;
647     }
648   return t;
649 }
650
651 /* Mark a dereference of BASE of distance DIST in a basic block tht STMT
652    belongs to, unless the BB has already been marked as a potentially
653    final.  */
654
655 static void
656 mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple stmt)
657 {
658   basic_block bb = gimple_bb (stmt);
659   int idx, parm_index = 0;
660   tree parm;
661
662   if (bitmap_bit_p (final_bbs, bb->index))
663     return;
664
665   for (parm = DECL_ARGUMENTS (current_function_decl);
666        parm && parm != base;
667        parm = TREE_CHAIN (parm))
668     parm_index++;
669
670   gcc_assert (parm_index < func_param_count);
671
672   idx = bb->index * func_param_count + parm_index;
673   if (bb_dereferences[idx] < dist)
674     bb_dereferences[idx] = dist;
675 }
676
677 /* Create and insert access for EXPR. Return created access, or NULL if it is
678    not possible.  */
679
680 static struct access *
681 create_access (tree expr, gimple stmt, bool write)
682 {
683   struct access *access;
684   void **slot;
685   VEC (access_p,heap) *vec;
686   HOST_WIDE_INT offset, size, max_size;
687   tree base = expr;
688   bool ptr, unscalarizable_region = false;
689
690   base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
691
692   if (sra_mode == SRA_MODE_EARLY_IPA && INDIRECT_REF_P (base))
693     {
694       base = get_ssa_base_param (TREE_OPERAND (base, 0));
695       if (!base)
696         return NULL;
697       ptr = true;
698     }
699   else
700     ptr = false;
701
702   if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
703     return NULL;
704
705   if (sra_mode == SRA_MODE_EARLY_IPA)
706     {
707       if (size < 0 || size != max_size)
708         {
709           disqualify_candidate (base, "Encountered a variable sized access.");
710           return NULL;
711         }
712       if ((offset % BITS_PER_UNIT) != 0 || (size % BITS_PER_UNIT) != 0)
713         {
714           disqualify_candidate (base,
715                                 "Encountered an acces not aligned to a byte.");
716           return NULL;
717         }
718
719       if (ptr)
720         mark_parm_dereference (base, offset + size, stmt);
721     }
722   else
723     {
724       if (size != max_size)
725         {
726           size = max_size;
727           unscalarizable_region = true;
728         }
729       if (size < 0)
730         {
731           disqualify_candidate (base, "Encountered an unconstrained access.");
732           return NULL;
733         }
734     }
735
736   access = (struct access *) pool_alloc (access_pool);
737   memset (access, 0, sizeof (struct access));
738
739   access->base = base;
740   access->offset = offset;
741   access->size = size;
742   access->expr = expr;
743   access->type = TREE_TYPE (expr);
744   access->write = write;
745   access->grp_unscalarizable_region = unscalarizable_region;
746   access->stmt = stmt;
747
748   slot = pointer_map_contains (base_access_vec, base);
749   if (slot)
750     vec = (VEC (access_p, heap) *) *slot;
751   else
752     vec = VEC_alloc (access_p, heap, 32);
753
754   VEC_safe_push (access_p, heap, vec, access);
755
756   *((struct VEC (access_p,heap) **)
757         pointer_map_insert (base_access_vec, base)) = vec;
758
759   return access;
760 }
761
762
763 /* Search the given tree for a declaration by skipping handled components and
764    exclude it from the candidates.  */
765
766 static void
767 disqualify_base_of_expr (tree t, const char *reason)
768 {
769   while (handled_component_p (t))
770     t = TREE_OPERAND (t, 0);
771
772   if (sra_mode == SRA_MODE_EARLY_IPA)
773     {
774       if (INDIRECT_REF_P (t))
775         t = TREE_OPERAND (t, 0);
776       t = get_ssa_base_param (t);
777     }
778
779   if (t && DECL_P (t))
780     disqualify_candidate (t, reason);
781 }
782
783 /* Scan expression EXPR and create access structures for all accesses to
784    candidates for scalarization.  Return the created access or NULL if none is
785    created.  */
786
787 static struct access *
788 build_access_from_expr_1 (tree *expr_ptr, gimple stmt, bool write)
789 {
790   struct access *ret = NULL;
791   tree expr = *expr_ptr;
792   bool partial_ref;
793
794   if (TREE_CODE (expr) == BIT_FIELD_REF
795       || TREE_CODE (expr) == IMAGPART_EXPR
796       || TREE_CODE (expr) == REALPART_EXPR)
797     {
798       expr = TREE_OPERAND (expr, 0);
799       partial_ref = true;
800     }
801   else
802     partial_ref = false;
803
804   /* We need to dive through V_C_Es in order to get the size of its parameter
805      and not the result type.  Ada produces such statements.  We are also
806      capable of handling the topmost V_C_E but not any of those buried in other
807      handled components.  */
808   if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
809     expr = TREE_OPERAND (expr, 0);
810
811   if (contains_view_convert_expr_p (expr))
812     {
813       disqualify_base_of_expr (expr, "V_C_E under a different handled "
814                                "component.");
815       return NULL;
816     }
817
818   switch (TREE_CODE (expr))
819     {
820     case INDIRECT_REF:
821       if (sra_mode != SRA_MODE_EARLY_IPA)
822         return NULL;
823       /* fall through */
824     case VAR_DECL:
825     case PARM_DECL:
826     case RESULT_DECL:
827     case COMPONENT_REF:
828     case ARRAY_REF:
829     case ARRAY_RANGE_REF:
830       ret = create_access (expr, stmt, write);
831       break;
832
833     default:
834       break;
835     }
836
837   if (write && partial_ref && ret)
838     ret->grp_partial_lhs = 1;
839
840   return ret;
841 }
842
843 /* Callback of scan_function.  Scan expression EXPR and create access
844    structures for all accesses to candidates for scalarization.  Return true if
845    any access has been inserted.  */
846
847 static bool
848 build_access_from_expr (tree *expr_ptr,
849                         gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED, bool write,
850                         void *data ATTRIBUTE_UNUSED)
851 {
852   return build_access_from_expr_1 (expr_ptr, gsi_stmt (*gsi), write) != NULL;
853 }
854
855 /* Disqualify LHS and RHS for scalarization if STMT must end its basic block in
856    modes in which it matters, return true iff they have been disqualified.  RHS
857    may be NULL, in that case ignore it.  If we scalarize an aggregate in
858    intra-SRA we may need to add statements after each statement.  This is not
859    possible if a statement unconditionally has to end the basic block.  */
860 static bool
861 disqualify_ops_if_throwing_stmt (gimple stmt, tree lhs, tree rhs)
862 {
863   if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
864       && (stmt_can_throw_internal (stmt) || stmt_ends_bb_p (stmt)))
865     {
866       disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
867       if (rhs)
868         disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
869       return true;
870     }
871   return false;
872 }
873
874
875 /* Result code for scan_assign callback for scan_function.  */
876 enum scan_assign_result { SRA_SA_NONE,       /* nothing done for the stmt */
877                           SRA_SA_PROCESSED,  /* stmt analyzed/changed */
878                           SRA_SA_REMOVED };  /* stmt redundant and eliminated */
879
880
881 /* Callback of scan_function.  Scan expressions occuring in the statement
882    pointed to by STMT_EXPR, create access structures for all accesses to
883    candidates for scalarization and remove those candidates which occur in
884    statements or expressions that prevent them from being split apart.  Return
885    true if any access has been inserted.  */
886
887 static enum scan_assign_result
888 build_accesses_from_assign (gimple *stmt_ptr,
889                             gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
890                             void *data ATTRIBUTE_UNUSED)
891 {
892   gimple stmt = *stmt_ptr;
893   tree *lhs_ptr, *rhs_ptr;
894   struct access *lacc, *racc;
895
896   if (!gimple_assign_single_p (stmt))
897     return SRA_SA_NONE;
898
899   lhs_ptr = gimple_assign_lhs_ptr (stmt);
900   rhs_ptr = gimple_assign_rhs1_ptr (stmt);
901
902   if (disqualify_ops_if_throwing_stmt (stmt, *lhs_ptr, *rhs_ptr))
903     return SRA_SA_NONE;
904
905   racc = build_access_from_expr_1 (rhs_ptr, stmt, false);
906   lacc = build_access_from_expr_1 (lhs_ptr, stmt, true);
907
908   if (lacc && racc
909       && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
910       && !lacc->grp_unscalarizable_region
911       && !racc->grp_unscalarizable_region
912       && AGGREGATE_TYPE_P (TREE_TYPE (*lhs_ptr))
913       /* FIXME: Turn the following line into an assert after PR 40058 is
914          fixed.  */
915       && lacc->size == racc->size
916       && useless_type_conversion_p (lacc->type, racc->type))
917     {
918       struct assign_link *link;
919
920       link = (struct assign_link *) pool_alloc (link_pool);
921       memset (link, 0, sizeof (struct assign_link));
922
923       link->lacc = lacc;
924       link->racc = racc;
925
926       add_link_to_rhs (racc, link);
927     }
928
929   return (lacc || racc) ? SRA_SA_PROCESSED : SRA_SA_NONE;
930 }
931
932 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
933    GIMPLE_ASM operands with memory constrains which cannot be scalarized.  */
934
935 static bool
936 asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED, tree op,
937                 void *data ATTRIBUTE_UNUSED)
938 {
939   if (DECL_P (op))
940     disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
941
942   return false;
943 }
944
945
946 /* Scan function and look for interesting statements. Return true if any has
947    been found or processed, as indicated by callbacks.  SCAN_EXPR is a callback
948    called on all expressions within statements except assign statements and
949    those deemed entirely unsuitable for some reason (all operands in such
950    statements and expression are removed from candidate_bitmap).  SCAN_ASSIGN
951    is a callback called on all assign statements, HANDLE_SSA_DEFS is a callback
952    called on assign statements and those call statements which have a lhs, it
953    can be NULL.  ANALYSIS_STAGE is true when running in the analysis stage of a
954    pass and thus no statement is being modified.  DATA is a pointer passed to
955    all callbacks.  If any single callback returns true, this function also
956    returns true, otherwise it returns false.  */
957
958 static bool
959 scan_function (bool (*scan_expr) (tree *, gimple_stmt_iterator *, bool, void *),
960                enum scan_assign_result (*scan_assign) (gimple *,
961                                                        gimple_stmt_iterator *,
962                                                        void *),
963                bool (*handle_ssa_defs)(gimple, void *),
964                bool analysis_stage, void *data)
965 {
966   gimple_stmt_iterator gsi;
967   basic_block bb;
968   unsigned i;
969   tree *t;
970   bool ret = false;
971
972   FOR_EACH_BB (bb)
973     {
974       bool bb_changed = false;
975
976       if (handle_ssa_defs)
977         for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
978           ret |= handle_ssa_defs (gsi_stmt (gsi), data);
979
980       gsi = gsi_start_bb (bb);
981       while (!gsi_end_p (gsi))
982         {
983           gimple stmt = gsi_stmt (gsi);
984           enum scan_assign_result assign_result;
985           bool any = false, deleted = false;
986
987           if (analysis_stage && final_bbs && stmt_can_throw_external (stmt))
988             bitmap_set_bit (final_bbs, bb->index);
989           switch (gimple_code (stmt))
990             {
991             case GIMPLE_RETURN:
992               t = gimple_return_retval_ptr (stmt);
993               if (*t != NULL_TREE)
994                 any |= scan_expr (t, &gsi, false, data);
995               if (analysis_stage && final_bbs)
996                 bitmap_set_bit (final_bbs, bb->index);
997               break;
998
999             case GIMPLE_ASSIGN:
1000               assign_result = scan_assign (&stmt, &gsi, data);
1001               any |= assign_result == SRA_SA_PROCESSED;
1002               deleted = assign_result == SRA_SA_REMOVED;
1003               if (handle_ssa_defs && assign_result != SRA_SA_REMOVED)
1004                 any |= handle_ssa_defs (stmt, data);
1005               break;
1006
1007             case GIMPLE_CALL:
1008               /* Operands must be processed before the lhs.  */
1009               for (i = 0; i < gimple_call_num_args (stmt); i++)
1010                 {
1011                   tree *argp = gimple_call_arg_ptr (stmt, i);
1012                   any |= scan_expr (argp, &gsi, false, data);
1013                 }
1014
1015               if (analysis_stage)
1016                 {
1017                   tree dest = gimple_call_fndecl (stmt);
1018                   int flags = gimple_call_flags (stmt);
1019
1020                   if (dest
1021                       && DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
1022                       && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
1023                     encountered_apply_args = true;
1024
1025                   if (final_bbs
1026                       && (flags & (ECF_CONST | ECF_PURE)) == 0)
1027                     bitmap_set_bit (final_bbs, bb->index);
1028                 }
1029
1030               if (gimple_call_lhs (stmt))
1031                 {
1032                   tree *lhs_ptr = gimple_call_lhs_ptr (stmt);
1033                   if (!analysis_stage
1034                       || !disqualify_ops_if_throwing_stmt (stmt,
1035                                                            *lhs_ptr, NULL))
1036                     {
1037                       any |= scan_expr (lhs_ptr, &gsi, true, data);
1038                       if (handle_ssa_defs)
1039                         any |= handle_ssa_defs (stmt, data);
1040                     }
1041                 }
1042               break;
1043
1044             case GIMPLE_ASM:
1045               if (analysis_stage)
1046                 {
1047                   walk_stmt_load_store_addr_ops (stmt, NULL, NULL, NULL,
1048                                                  asm_visit_addr);
1049                   if (final_bbs)
1050                     bitmap_set_bit (final_bbs, bb->index);
1051                 }
1052               for (i = 0; i < gimple_asm_ninputs (stmt); i++)
1053                 {
1054                   tree *op = &TREE_VALUE (gimple_asm_input_op (stmt, i));
1055                   any |= scan_expr (op, &gsi, false, data);
1056                 }
1057               for (i = 0; i < gimple_asm_noutputs (stmt); i++)
1058                 {
1059                   tree *op = &TREE_VALUE (gimple_asm_output_op (stmt, i));
1060                   any |= scan_expr (op, &gsi, true, data);
1061                 }
1062               break;
1063
1064             default:
1065               break;
1066             }
1067
1068           if (any)
1069             {
1070               ret = true;
1071
1072               if (!analysis_stage)
1073                 {
1074                   bb_changed = true;
1075                   update_stmt (stmt);
1076                   maybe_clean_eh_stmt (stmt);
1077                 }
1078             }
1079           if (deleted)
1080             bb_changed = true;
1081           else
1082             {
1083               gsi_next (&gsi);
1084               ret = true;
1085             }
1086         }
1087       if (!analysis_stage && bb_changed && sra_mode == SRA_MODE_EARLY_IPA)
1088         gimple_purge_dead_eh_edges (bb);
1089     }
1090
1091   return ret;
1092 }
1093
1094 /* Helper of QSORT function. There are pointers to accesses in the array.  An
1095    access is considered smaller than another if it has smaller offset or if the
1096    offsets are the same but is size is bigger. */
1097
1098 static int
1099 compare_access_positions (const void *a, const void *b)
1100 {
1101   const access_p *fp1 = (const access_p *) a;
1102   const access_p *fp2 = (const access_p *) b;
1103   const access_p f1 = *fp1;
1104   const access_p f2 = *fp2;
1105
1106   if (f1->offset != f2->offset)
1107     return f1->offset < f2->offset ? -1 : 1;
1108
1109   if (f1->size == f2->size)
1110     {
1111       /* Put any non-aggregate type before any aggregate type.  */
1112       if (!is_gimple_reg_type (f1->type)
1113                && is_gimple_reg_type (f2->type))
1114         return 1;
1115       else if (is_gimple_reg_type (f1->type)
1116                && !is_gimple_reg_type (f2->type))
1117         return -1;
1118       /* Put the integral type with the bigger precision first.  */
1119       else if (INTEGRAL_TYPE_P (f1->type)
1120           && INTEGRAL_TYPE_P (f2->type))
1121         return TYPE_PRECISION (f1->type) > TYPE_PRECISION (f2->type) ? -1 : 1;
1122       /* Put any integral type with non-full precision last.  */
1123       else if (INTEGRAL_TYPE_P (f1->type)
1124                && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type))
1125                    != TYPE_PRECISION (f1->type)))
1126         return 1;
1127       else if (INTEGRAL_TYPE_P (f2->type)
1128                && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type))
1129                    != TYPE_PRECISION (f2->type)))
1130         return -1;
1131       /* Stabilize the sort.  */
1132       return TYPE_UID (f1->type) - TYPE_UID (f2->type);
1133     }
1134
1135   /* We want the bigger accesses first, thus the opposite operator in the next
1136      line: */
1137   return f1->size > f2->size ? -1 : 1;
1138 }
1139
1140
1141 /* Append a name of the declaration to the name obstack.  A helper function for
1142    make_fancy_name.  */
1143
1144 static void
1145 make_fancy_decl_name (tree decl)
1146 {
1147   char buffer[32];
1148
1149   tree name = DECL_NAME (decl);
1150   if (name)
1151     obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
1152                   IDENTIFIER_LENGTH (name));
1153   else
1154     {
1155       sprintf (buffer, "D%u", DECL_UID (decl));
1156       obstack_grow (&name_obstack, buffer, strlen (buffer));
1157     }
1158 }
1159
1160 /* Helper for make_fancy_name.  */
1161
1162 static void
1163 make_fancy_name_1 (tree expr)
1164 {
1165   char buffer[32];
1166   tree index;
1167
1168   if (DECL_P (expr))
1169     {
1170       make_fancy_decl_name (expr);
1171       return;
1172     }
1173
1174   switch (TREE_CODE (expr))
1175     {
1176     case COMPONENT_REF:
1177       make_fancy_name_1 (TREE_OPERAND (expr, 0));
1178       obstack_1grow (&name_obstack, '$');
1179       make_fancy_decl_name (TREE_OPERAND (expr, 1));
1180       break;
1181
1182     case ARRAY_REF:
1183       make_fancy_name_1 (TREE_OPERAND (expr, 0));
1184       obstack_1grow (&name_obstack, '$');
1185       /* Arrays with only one element may not have a constant as their
1186          index. */
1187       index = TREE_OPERAND (expr, 1);
1188       if (TREE_CODE (index) != INTEGER_CST)
1189         break;
1190       sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
1191       obstack_grow (&name_obstack, buffer, strlen (buffer));
1192
1193       break;
1194
1195     case BIT_FIELD_REF:
1196     case REALPART_EXPR:
1197     case IMAGPART_EXPR:
1198       gcc_unreachable ();       /* we treat these as scalars.  */
1199       break;
1200     default:
1201       break;
1202     }
1203 }
1204
1205 /* Create a human readable name for replacement variable of ACCESS.  */
1206
1207 static char *
1208 make_fancy_name (tree expr)
1209 {
1210   make_fancy_name_1 (expr);
1211   obstack_1grow (&name_obstack, '\0');
1212   return XOBFINISH (&name_obstack, char *);
1213 }
1214
1215 /* Helper function for build_ref_for_offset.  */
1216
1217 static bool
1218 build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset,
1219                         tree exp_type)
1220 {
1221   while (1)
1222     {
1223       tree fld;
1224       tree tr_size, index, minidx;
1225       HOST_WIDE_INT el_size;
1226
1227       if (offset == 0 && exp_type
1228           && types_compatible_p (exp_type, type))
1229         return true;
1230
1231       switch (TREE_CODE (type))
1232         {
1233         case UNION_TYPE:
1234         case QUAL_UNION_TYPE:
1235         case RECORD_TYPE:
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;
2824
2825       for (repr = VEC_index (access_p, representatives, i);
2826            repr;
2827            repr = repr->next_grp)
2828         {
2829           struct access *access;
2830           bitmap visited;
2831           ao_ref ar;
2832
2833           if (no_accesses_p (repr))
2834             continue;
2835           if (!POINTER_TYPE_P (TREE_TYPE (repr->base))
2836               || repr->grp_maybe_modified)
2837             continue;
2838
2839           ao_ref_init (&ar, repr->expr);
2840           visited = BITMAP_ALLOC (NULL);
2841           for (access = repr; access; access = access->next_sibling)
2842             {
2843               /* All accesses are read ones, otherwise grp_maybe_modified would
2844                  be trivially set.  */
2845               walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
2846                                   mark_maybe_modified, repr, &visited);
2847               if (repr->grp_maybe_modified)
2848                 break;
2849             }
2850           BITMAP_FREE (visited);
2851         }
2852     }
2853 }
2854
2855 /* Propagate distances in bb_dereferences in the opposite direction than the
2856    control flow edges, in each step storing the maximum of the current value
2857    and the minimum of all successors.  These steps are repeated until the table
2858    stabilizes.  Note that BBs which might terminate the functions (according to
2859    final_bbs bitmap) never updated in this way.  */
2860
2861 static void
2862 propagate_dereference_distances (void)
2863 {
2864   VEC (basic_block, heap) *queue;
2865   basic_block bb;
2866
2867   queue = VEC_alloc (basic_block, heap, last_basic_block_for_function (cfun));
2868   VEC_quick_push (basic_block, queue, ENTRY_BLOCK_PTR);
2869   FOR_EACH_BB (bb)
2870     {
2871       VEC_quick_push (basic_block, queue, bb);
2872       bb->aux = bb;
2873     }
2874
2875   while (!VEC_empty (basic_block, queue))
2876     {
2877       edge_iterator ei;
2878       edge e;
2879       bool change = false;
2880       int i;
2881
2882       bb = VEC_pop (basic_block, queue);
2883       bb->aux = NULL;
2884
2885       if (bitmap_bit_p (final_bbs, bb->index))
2886         continue;
2887
2888       for (i = 0; i < func_param_count; i++)
2889         {
2890           int idx = bb->index * func_param_count + i;
2891           bool first = true;
2892           HOST_WIDE_INT inh = 0;
2893
2894           FOR_EACH_EDGE (e, ei, bb->succs)
2895           {
2896             int succ_idx = e->dest->index * func_param_count + i;
2897
2898             if (e->src == EXIT_BLOCK_PTR)
2899               continue;
2900
2901             if (first)
2902               {
2903                 first = false;
2904                 inh = bb_dereferences [succ_idx];
2905               }
2906             else if (bb_dereferences [succ_idx] < inh)
2907               inh = bb_dereferences [succ_idx];
2908           }
2909
2910           if (!first && bb_dereferences[idx] < inh)
2911             {
2912               bb_dereferences[idx] = inh;
2913               change = true;
2914             }
2915         }
2916
2917       if (change && !bitmap_bit_p (final_bbs, bb->index))
2918         FOR_EACH_EDGE (e, ei, bb->preds)
2919           {
2920             if (e->src->aux)
2921               continue;
2922
2923             e->src->aux = e->src;
2924             VEC_quick_push (basic_block, queue, e->src);
2925           }
2926     }
2927
2928   VEC_free (basic_block, heap, queue);
2929 }
2930
2931 /* Dump a dereferences TABLE with heading STR to file F.  */
2932
2933 static void
2934 dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
2935 {
2936   basic_block bb;
2937
2938   fprintf (dump_file, str);
2939   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
2940     {
2941       fprintf (f, "%4i  %i   ", bb->index, bitmap_bit_p (final_bbs, bb->index));
2942       if (bb != EXIT_BLOCK_PTR)
2943         {
2944           int i;
2945           for (i = 0; i < func_param_count; i++)
2946             {
2947               int idx = bb->index * func_param_count + i;
2948               fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
2949             }
2950         }
2951       fprintf (f, "\n");
2952     }
2953   fprintf (dump_file, "\n");
2954 }
2955
2956 /* Determine what (parts of) parameters passed by reference that are not
2957    assigned to are not certainly dereferenced in this function and thus the
2958    dereferencing cannot be safely moved to the caller without potentially
2959    introducing a segfault.  Mark such REPRESENTATIVES as
2960    grp_not_necessarilly_dereferenced.
2961
2962    The dereferenced maximum "distance," i.e. the offset + size of the accessed
2963    part is calculated rather than simple booleans are calculated for each
2964    pointer parameter to handle cases when only a fraction of the whole
2965    aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
2966    an example).
2967
2968    The maximum dereference distances for each pointer parameter and BB are
2969    already stored in bb_dereference.  This routine simply propagates these
2970    values upwards by propagate_dereference_distances and then compares the
2971    distances of individual parameters in the ENTRY BB to the equivalent
2972    distances of each representative of a (fraction of a) parameter.  */
2973
2974 static void
2975 analyze_caller_dereference_legality (VEC (access_p, heap) *representatives)
2976 {
2977   int i;
2978
2979   if (dump_file && (dump_flags & TDF_DETAILS))
2980     dump_dereferences_table (dump_file,
2981                              "Dereference table before propagation:\n",
2982                              bb_dereferences);
2983
2984   propagate_dereference_distances ();
2985
2986   if (dump_file && (dump_flags & TDF_DETAILS))
2987     dump_dereferences_table (dump_file,
2988                              "Dereference table after propagation:\n",
2989                              bb_dereferences);
2990
2991   for (i = 0; i < func_param_count; i++)
2992     {
2993       struct access *repr = VEC_index (access_p, representatives, i);
2994       int idx = ENTRY_BLOCK_PTR->index * func_param_count + i;
2995
2996       if (!repr || no_accesses_p (repr))
2997         continue;
2998
2999       do
3000         {
3001           if ((repr->offset + repr->size) > bb_dereferences[idx])
3002             repr->grp_not_necessarilly_dereferenced = 1;
3003           repr = repr->next_grp;
3004         }
3005       while (repr);
3006     }
3007 }
3008
3009 /* Return the representative access for the parameter declaration PARM if it is
3010    a scalar passed by reference which is not written to and the pointer value
3011    is not used directly.  Thus, if it is legal to dereference it in the caller
3012    and we can rule out modifications through aliases, such parameter should be
3013    turned into one passed by value.  Return NULL otherwise.  */
3014
3015 static struct access *
3016 unmodified_by_ref_scalar_representative (tree parm)
3017 {
3018   int i, access_count;
3019   struct access *repr;
3020   VEC (access_p, heap) *access_vec;
3021
3022   access_vec = get_base_access_vector (parm);
3023   gcc_assert (access_vec);
3024   repr = VEC_index (access_p, access_vec, 0);
3025   if (repr->write)
3026     return NULL;
3027   repr->group_representative = repr;
3028
3029   access_count = VEC_length (access_p, access_vec);
3030   for (i = 1; i < access_count; i++)
3031     {
3032       struct access *access = VEC_index (access_p, access_vec, i);
3033       if (access->write)
3034         return NULL;
3035       access->group_representative = repr;
3036       access->next_sibling = repr->next_sibling;
3037       repr->next_sibling = access;
3038     }
3039
3040   repr->grp_read = 1;
3041   repr->grp_scalar_ptr = 1;
3042   return repr;
3043 }
3044
3045 /* Sort collected accesses for parameter PARM, identify representatives for
3046    each accessed region and link them together.  Return NULL if there are
3047    different but overlapping accesses, return the special ptr value meaning
3048    there are no accesses for this parameter if that is the case and return the
3049    first representative otherwise.  Set *RO_GRP if there is a group of accesses
3050    with only read (i.e. no write) accesses.  */
3051
3052 static struct access *
3053 splice_param_accesses (tree parm, bool *ro_grp)
3054 {
3055   int i, j, access_count, group_count;
3056   int agg_size, total_size = 0;
3057   struct access *access, *res, **prev_acc_ptr = &res;
3058   VEC (access_p, heap) *access_vec;
3059
3060   access_vec = get_base_access_vector (parm);
3061   if (!access_vec)
3062     return &no_accesses_representant;
3063   access_count = VEC_length (access_p, access_vec);
3064
3065   qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
3066          compare_access_positions);
3067
3068   i = 0;
3069   total_size = 0;
3070   group_count = 0;
3071   while (i < access_count)
3072     {
3073       bool modification;
3074       access = VEC_index (access_p, access_vec, i);
3075       modification = access->write;
3076
3077       /* Access is about to become group representative unless we find some
3078          nasty overlap which would preclude us from breaking this parameter
3079          apart. */
3080
3081       j = i + 1;
3082       while (j < access_count)
3083         {
3084           struct access *ac2 = VEC_index (access_p, access_vec, j);
3085           if (ac2->offset != access->offset)
3086             {
3087               /* All or nothing law for parameters. */
3088               if (access->offset + access->size > ac2->offset)
3089                 return NULL;
3090               else
3091                 break;
3092             }
3093           else if (ac2->size != access->size)
3094             return NULL;
3095
3096           modification |= ac2->write;
3097           ac2->group_representative = access;
3098           ac2->next_sibling = access->next_sibling;
3099           access->next_sibling = ac2;
3100           j++;
3101         }
3102
3103       group_count++;
3104       access->grp_maybe_modified = modification;
3105       if (!modification)
3106         *ro_grp = true;
3107       *prev_acc_ptr = access;
3108       prev_acc_ptr = &access->next_grp;
3109       total_size += access->size;
3110       i = j;
3111     }
3112
3113   if (POINTER_TYPE_P (TREE_TYPE (parm)))
3114     agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))), 1);
3115   else
3116     agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (parm)), 1);
3117   if (total_size >= agg_size)
3118     return NULL;
3119
3120   gcc_assert (group_count > 0);
3121   return res;
3122 }
3123
3124 /* Decide whether parameters with representative accesses given by REPR should
3125    be reduced into components.  */
3126
3127 static int
3128 decide_one_param_reduction (struct access *repr)
3129 {
3130   int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
3131   bool by_ref;
3132   tree parm;
3133
3134   parm = repr->base;
3135   cur_parm_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (parm)), 1);
3136   gcc_assert (cur_parm_size > 0);
3137
3138   if (POINTER_TYPE_P (TREE_TYPE (parm)))
3139     {
3140       by_ref = true;
3141       agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))), 1);
3142     }
3143   else
3144     {
3145       by_ref = false;
3146       agg_size = cur_parm_size;
3147     }
3148
3149   if (dump_file)
3150     {
3151       struct access *acc;
3152       fprintf (dump_file, "Evaluating PARAM group sizes for ");
3153       print_generic_expr (dump_file, parm, 0);
3154       fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
3155       for (acc = repr; acc; acc = acc->next_grp)
3156         dump_access (dump_file, acc, true);
3157     }
3158
3159   total_size = 0;
3160   new_param_count = 0;
3161
3162   for (; repr; repr = repr->next_grp)
3163     {
3164       gcc_assert (parm == repr->base);
3165       new_param_count++;
3166
3167       if (!by_ref || (!repr->grp_maybe_modified
3168                       && !repr->grp_not_necessarilly_dereferenced))
3169         total_size += repr->size;
3170       else
3171         total_size += cur_parm_size;
3172     }
3173
3174   gcc_assert (new_param_count > 0);
3175
3176   if (optimize_function_for_size_p (cfun))
3177     parm_size_limit = cur_parm_size;
3178   else
3179     parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
3180                        * cur_parm_size);
3181
3182   if (total_size < agg_size
3183       && total_size <= parm_size_limit)
3184     {
3185       if (dump_file)
3186         fprintf (dump_file, "    ....will be split into %i components\n",
3187                  new_param_count);
3188       return new_param_count;
3189     }
3190   else
3191     return 0;
3192 }
3193
3194 /* The order of the following enums is important, we need to do extra work for
3195    UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES.  */
3196 enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
3197                           MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
3198
3199 /* Identify representatives of all accesses to all candidate parameters for
3200    IPA-SRA.  Return result based on what representatives have been found. */
3201
3202 static enum ipa_splicing_result
3203 splice_all_param_accesses (VEC (access_p, heap) **representatives)
3204 {
3205   enum ipa_splicing_result result = NO_GOOD_ACCESS;
3206   tree parm;
3207   struct access *repr;
3208
3209   *representatives = VEC_alloc (access_p, heap, func_param_count);
3210
3211   for (parm = DECL_ARGUMENTS (current_function_decl);
3212        parm;
3213        parm = TREE_CHAIN (parm))
3214     {
3215       if (is_unused_scalar_param (parm))
3216         {
3217           VEC_quick_push (access_p, *representatives,
3218                           &no_accesses_representant);
3219           if (result == NO_GOOD_ACCESS)
3220             result = UNUSED_PARAMS;
3221         }
3222       else if (POINTER_TYPE_P (TREE_TYPE (parm))
3223                && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
3224                && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3225         {
3226           repr = unmodified_by_ref_scalar_representative (parm);
3227           VEC_quick_push (access_p, *representatives, repr);
3228           if (repr)
3229             result = UNMODIF_BY_REF_ACCESSES;
3230         }
3231       else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
3232         {
3233           bool ro_grp = false;
3234           repr = splice_param_accesses (parm, &ro_grp);
3235           VEC_quick_push (access_p, *representatives, repr);
3236
3237           if (repr && !no_accesses_p (repr))
3238             {
3239               if (POINTER_TYPE_P (TREE_TYPE (parm)))
3240                 {
3241                   if (ro_grp)
3242                     result = UNMODIF_BY_REF_ACCESSES;
3243                   else if (result < MODIF_BY_REF_ACCESSES)
3244                     result = MODIF_BY_REF_ACCESSES;
3245                 }
3246               else if (result < BY_VAL_ACCESSES)
3247                 result = BY_VAL_ACCESSES;
3248             }
3249           else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
3250             result = UNUSED_PARAMS;
3251         }
3252       else
3253         VEC_quick_push (access_p, *representatives, NULL);
3254     }
3255
3256   if (result == NO_GOOD_ACCESS)
3257     {
3258       VEC_free (access_p, heap, *representatives);
3259       *representatives = NULL;
3260       return NO_GOOD_ACCESS;
3261     }
3262
3263   return result;
3264 }
3265
3266 /* Return the index of BASE in PARMS.  Abort if it is not found.  */
3267
3268 static inline int
3269 get_param_index (tree base, VEC(tree, heap) *parms)
3270 {
3271   int i, len;
3272
3273   len = VEC_length (tree, parms);
3274   for (i = 0; i < len; i++)
3275     if (VEC_index (tree, parms, i) == base)
3276       return i;
3277   gcc_unreachable ();
3278 }
3279
3280 /* Convert the decisions made at the representative level into compact
3281    parameter adjustments.  REPRESENTATIVES are pointers to first
3282    representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
3283    final number of adjustments.  */
3284
3285 static ipa_parm_adjustment_vec
3286 turn_representatives_into_adjustments (VEC (access_p, heap) *representatives,
3287                                        int adjustments_count)
3288 {
3289   VEC (tree, heap) *parms;
3290   ipa_parm_adjustment_vec adjustments;
3291   tree parm;
3292   int i;
3293
3294   gcc_assert (adjustments_count > 0);
3295   parms = ipa_get_vector_of_formal_parms (current_function_decl);
3296   adjustments = VEC_alloc (ipa_parm_adjustment_t, heap, adjustments_count);
3297   parm = DECL_ARGUMENTS (current_function_decl);
3298   for (i = 0; i < func_param_count; i++, parm = TREE_CHAIN (parm))
3299     {
3300       struct access *repr = VEC_index (access_p, representatives, i);
3301
3302       if (!repr || no_accesses_p (repr))
3303         {
3304           struct ipa_parm_adjustment *adj;
3305
3306           adj = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
3307           memset (adj, 0, sizeof (*adj));
3308           adj->base_index = get_param_index (parm, parms);
3309           adj->base = parm;
3310           if (!repr)
3311             adj->copy_param = 1;
3312           else
3313             adj->remove_param = 1;
3314         }
3315       else
3316         {
3317           struct ipa_parm_adjustment *adj;
3318           int index = get_param_index (parm, parms);
3319
3320           for (; repr; repr = repr->next_grp)
3321             {
3322               adj = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
3323               memset (adj, 0, sizeof (*adj));
3324               gcc_assert (repr->base == parm);
3325               adj->base_index = index;
3326               adj->base = repr->base;
3327               adj->type = repr->type;
3328               adj->offset = repr->offset;
3329               adj->by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
3330                              && (repr->grp_maybe_modified
3331                                  || repr->grp_not_necessarilly_dereferenced));
3332
3333             }
3334         }
3335     }
3336   VEC_free (tree, heap, parms);
3337   return adjustments;
3338 }
3339
3340 /* Analyze the collected accesses and produce a plan what to do with the
3341    parameters in the form of adjustments, NULL meaning nothing.  */
3342
3343 static ipa_parm_adjustment_vec
3344 analyze_all_param_acesses (void)
3345 {
3346   enum ipa_splicing_result repr_state;
3347   bool proceed = false;
3348   int i, adjustments_count = 0;
3349   VEC (access_p, heap) *representatives;
3350   ipa_parm_adjustment_vec adjustments;
3351
3352   repr_state = splice_all_param_accesses (&representatives);
3353   if (repr_state == NO_GOOD_ACCESS)
3354     return NULL;
3355
3356   /* If there are any parameters passed by reference which are not modified
3357      directly, we need to check whether they can be modified indirectly.  */
3358   if (repr_state == UNMODIF_BY_REF_ACCESSES)
3359     {
3360       analyze_caller_dereference_legality (representatives);
3361       analyze_modified_params (representatives);
3362     }
3363
3364   for (i = 0; i < func_param_count; i++)
3365     {
3366       struct access *repr = VEC_index (access_p, representatives, i);
3367
3368       if (repr && !no_accesses_p (repr))
3369         {
3370           if (repr->grp_scalar_ptr)
3371             {
3372               adjustments_count++;
3373               if (repr->grp_not_necessarilly_dereferenced
3374                   || repr->grp_maybe_modified)
3375                 VEC_replace (access_p, representatives, i, NULL);
3376               else
3377                 {
3378                   proceed = true;
3379                   sra_stats.scalar_by_ref_to_by_val++;
3380                 }
3381             }
3382           else
3383             {
3384               int new_components = decide_one_param_reduction (repr);
3385
3386               if (new_components == 0)
3387                 {
3388                   VEC_replace (access_p, representatives, i, NULL);
3389                   adjustments_count++;
3390                 }
3391               else
3392                 {
3393                   adjustments_count += new_components;
3394                   sra_stats.aggregate_params_reduced++;
3395                   sra_stats.param_reductions_created += new_components;
3396                   proceed = true;
3397                 }
3398             }
3399         }
3400       else
3401         {
3402           if (no_accesses_p (repr))
3403             {
3404               proceed = true;
3405               sra_stats.deleted_unused_parameters++;
3406             }
3407           adjustments_count++;
3408         }
3409     }
3410
3411   if (!proceed && dump_file)
3412     fprintf (dump_file, "NOT proceeding to change params.\n");
3413
3414   if (proceed)
3415     adjustments = turn_representatives_into_adjustments (representatives,
3416                                                          adjustments_count);
3417   else
3418     adjustments = NULL;
3419
3420   VEC_free (access_p, heap, representatives);
3421   return adjustments;
3422 }
3423
3424 /* If a parameter replacement identified by ADJ does not yet exist in the form
3425    of declaration, create it and record it, otherwise return the previously
3426    created one.  */
3427
3428 static tree
3429 get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
3430 {
3431   tree repl;
3432   if (!adj->new_ssa_base)
3433     {
3434       char *pretty_name = make_fancy_name (adj->base);
3435
3436       repl = make_rename_temp (TREE_TYPE (adj->base), "ISR");
3437       DECL_NAME (repl) = get_identifier (pretty_name);
3438       obstack_free (&name_obstack, pretty_name);
3439
3440       get_var_ann (repl);
3441       add_referenced_var (repl);
3442       adj->new_ssa_base = repl;
3443     }
3444   else
3445     repl = adj->new_ssa_base;
3446   return repl;
3447 }
3448
3449 /* Find the first adjustment for a particular parameter BASE in a vector of
3450    ADJUSTMENTS which is not a copy_param.  Return NULL if there is no such
3451    adjustment. */
3452
3453 static struct ipa_parm_adjustment *
3454 get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
3455 {
3456   int i, len;
3457
3458   len = VEC_length (ipa_parm_adjustment_t, adjustments);
3459   for (i = 0; i < len; i++)
3460     {
3461       struct ipa_parm_adjustment *adj;
3462
3463       adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3464       if (!adj->copy_param && adj->base == base)
3465         return adj;
3466     }
3467
3468   return NULL;
3469 }
3470
3471 /* Callback for scan_function.  If the statement STMT defines an SSA_NAME of a
3472    parameter which is to be removed because its value is not used, replace the
3473    SSA_NAME with a one relating to a created VAR_DECL and replace all of its
3474    uses too.  DATA is a pointer to an adjustments vector.  */
3475
3476 static bool
3477 replace_removed_params_ssa_names (gimple stmt, void *data)
3478 {
3479   VEC (ipa_parm_adjustment_t, heap) *adjustments;
3480   struct ipa_parm_adjustment *adj;
3481   tree lhs, decl, repl, name;
3482
3483   adjustments = (VEC (ipa_parm_adjustment_t, heap) *) data;
3484   if (gimple_code (stmt) == GIMPLE_PHI)
3485     lhs = gimple_phi_result (stmt);
3486   else if (is_gimple_assign (stmt))
3487     lhs = gimple_assign_lhs (stmt);
3488   else if (is_gimple_call (stmt))
3489     lhs = gimple_call_lhs (stmt);
3490   else
3491     gcc_unreachable ();
3492
3493   if (TREE_CODE (lhs) != SSA_NAME)
3494     return false;
3495   decl = SSA_NAME_VAR (lhs);
3496   if (TREE_CODE (decl) != PARM_DECL)
3497     return false;
3498
3499   adj = get_adjustment_for_base (adjustments, decl);
3500   if (!adj)
3501     return false;
3502
3503   repl = get_replaced_param_substitute (adj);
3504   name = make_ssa_name (repl, stmt);
3505
3506   if (dump_file)
3507     {
3508       fprintf (dump_file, "replacing an SSA name of a removed param ");
3509       print_generic_expr (dump_file, lhs, 0);
3510       fprintf (dump_file, " with ");
3511       print_generic_expr (dump_file, name, 0);
3512       fprintf (dump_file, "\n");
3513     }
3514
3515   if (is_gimple_assign (stmt))
3516     gimple_assign_set_lhs (stmt, name);
3517   else if (is_gimple_call (stmt))
3518     gimple_call_set_lhs (stmt, name);
3519   else
3520     gimple_phi_set_result (stmt, name);
3521
3522   replace_uses_by (lhs, name);
3523   return true;
3524 }
3525
3526 /* Callback for scan_function.  If the expression *EXPR should be replaced by a
3527    reduction of a parameter, do so.  DATA is a pointer to a vector of
3528    adjustments.  */
3529
3530 static bool
3531 sra_ipa_modify_expr (tree *expr, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
3532                      bool write ATTRIBUTE_UNUSED, void *data)
3533 {
3534   ipa_parm_adjustment_vec adjustments;
3535   int i, len;
3536   struct ipa_parm_adjustment *adj, *cand = NULL;
3537   HOST_WIDE_INT offset, size, max_size;
3538   tree base, src;
3539
3540   adjustments = (VEC (ipa_parm_adjustment_t, heap) *) data;
3541   len = VEC_length (ipa_parm_adjustment_t, adjustments);
3542
3543   if (TREE_CODE (*expr) == BIT_FIELD_REF
3544       || TREE_CODE (*expr) == IMAGPART_EXPR
3545       || TREE_CODE (*expr) == REALPART_EXPR)
3546     expr = &TREE_OPERAND (*expr, 0);
3547   while (TREE_CODE (*expr) == NOP_EXPR
3548          || TREE_CODE (*expr) == VIEW_CONVERT_EXPR)
3549     expr = &TREE_OPERAND (*expr, 0);
3550
3551   base = get_ref_base_and_extent (*expr, &offset, &size, &max_size);
3552   if (!base || size == -1 || max_size == -1)
3553     return false;
3554
3555   if (INDIRECT_REF_P (base))
3556     base = TREE_OPERAND (base, 0);
3557
3558   base = get_ssa_base_param (base);
3559   if (!base || TREE_CODE (base) != PARM_DECL)
3560     return false;
3561
3562   for (i = 0; i < len; i++)
3563     {
3564       adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3565
3566       if (adj->base == base &&
3567           (adj->offset == offset || adj->remove_param))
3568         {
3569           cand = adj;
3570           break;
3571         }
3572     }
3573   if (!cand || cand->copy_param || cand->remove_param)
3574     return false;
3575
3576   if (cand->by_ref)
3577     {
3578       tree folded;
3579       src = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (cand->reduction)),
3580                     cand->reduction);
3581       folded = gimple_fold_indirect_ref (src);
3582       if (folded)
3583         src = folded;
3584     }
3585   else
3586     src = cand->reduction;
3587
3588   if (dump_file && (dump_flags & TDF_DETAILS))
3589     {
3590       fprintf (dump_file, "About to replace expr ");
3591       print_generic_expr (dump_file, *expr, 0);
3592       fprintf (dump_file, " with ");
3593       print_generic_expr (dump_file, src, 0);
3594       fprintf (dump_file, "\n");
3595     }
3596
3597   if (!useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
3598     {
3599       tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
3600       *expr = vce;
3601     }
3602     else
3603       *expr = src;
3604   return true;
3605 }
3606
3607 /* Callback for scan_function to process assign statements.  Performs
3608    essentially the same function like sra_ipa_modify_expr.  */
3609
3610 static enum scan_assign_result
3611 sra_ipa_modify_assign (gimple *stmt_ptr,
3612                        gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED, void *data)
3613 {
3614   gimple stmt = *stmt_ptr;
3615   bool any = false;
3616
3617   if (!gimple_assign_single_p (stmt))
3618     return SRA_SA_NONE;
3619
3620   any |= sra_ipa_modify_expr (gimple_assign_rhs1_ptr (stmt), gsi, false,
3621                               data);
3622   any |= sra_ipa_modify_expr (gimple_assign_lhs_ptr (stmt), gsi, true, data);
3623
3624   return any ? SRA_SA_PROCESSED : SRA_SA_NONE;
3625 }
3626
3627 /* Call gimple_debug_bind_reset_value on all debug statements describing
3628    gimple register parameters that are being removed or replaced.  */
3629
3630 static void
3631 sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
3632 {
3633   int i, len;
3634
3635   len = VEC_length (ipa_parm_adjustment_t, adjustments);
3636   for (i = 0; i < len; i++)
3637     {
3638       struct ipa_parm_adjustment *adj;
3639       imm_use_iterator ui;
3640       gimple stmt;
3641       tree name;
3642
3643       adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
3644       if (adj->copy_param || !is_gimple_reg (adj->base))
3645         continue;
3646       name = gimple_default_def (cfun, adj->base);
3647       if (!name)
3648         continue;
3649       FOR_EACH_IMM_USE_STMT (stmt, ui, name)
3650         {
3651           /* All other users must have been removed by scan_function.  */
3652           gcc_assert (is_gimple_debug (stmt));
3653           gimple_debug_bind_reset_value (stmt);
3654           update_stmt (stmt);
3655         }
3656     }
3657 }
3658
3659 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS.  */
3660
3661 static void
3662 convert_callers (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
3663 {
3664   tree old_cur_fndecl = current_function_decl;
3665   struct cgraph_edge *cs;
3666   basic_block this_block;
3667   bitmap recomputed_callers = BITMAP_ALLOC (NULL);
3668
3669   for (cs = node->callers; cs; cs = cs->next_caller)
3670     {
3671       current_function_decl = cs->caller->decl;
3672       push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
3673
3674       if (dump_file)
3675         fprintf (dump_file, "Adjusting call (%i -> %i) %s -> %s\n",
3676                  cs->caller->uid, cs->callee->uid,
3677                  cgraph_node_name (cs->caller),
3678                  cgraph_node_name (cs->callee));
3679
3680       ipa_modify_call_arguments (cs, cs->call_stmt, adjustments);
3681
3682       pop_cfun ();
3683     }
3684
3685   for (cs = node->callers; cs; cs = cs->next_caller)
3686     if (!bitmap_bit_p (recomputed_callers, cs->caller->uid))
3687       {
3688         compute_inline_parameters (cs->caller);
3689         bitmap_set_bit (recomputed_callers, cs->caller->uid);
3690       }
3691   BITMAP_FREE (recomputed_callers);
3692
3693   current_function_decl = old_cur_fndecl;
3694   FOR_EACH_BB (this_block)
3695     {
3696       gimple_stmt_iterator gsi;
3697
3698       for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
3699         {
3700           gimple stmt = gsi_stmt (gsi);
3701           if (gimple_code (stmt) == GIMPLE_CALL
3702               && gimple_call_fndecl (stmt) == node->decl)
3703             {
3704               if (dump_file)
3705                 fprintf (dump_file, "Adjusting recursive call");
3706               ipa_modify_call_arguments (NULL, stmt, adjustments);
3707             }
3708         }
3709     }
3710
3711   return;
3712 }
3713
3714 /* Perform all the modification required in IPA-SRA for NODE to have parameters
3715    as given in ADJUSTMENTS.  */
3716
3717 static void
3718 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
3719 {
3720   ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA");
3721   scan_function (sra_ipa_modify_expr, sra_ipa_modify_assign,
3722                  replace_removed_params_ssa_names, false, adjustments);
3723   sra_ipa_reset_debug_stmts (adjustments);
3724   convert_callers (node, adjustments);
3725   cgraph_make_node_local (node);
3726   return;
3727 }
3728
3729 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
3730    attributes, return true otherwise.  NODE is the cgraph node of the current
3731    function.  */
3732
3733 static bool
3734 ipa_sra_preliminary_function_checks (struct cgraph_node *node)
3735 {
3736   if (!cgraph_node_can_be_local_p (node))
3737     {
3738       if (dump_file)
3739         fprintf (dump_file, "Function not local to this compilation unit.\n");
3740       return false;
3741     }
3742
3743   if (DECL_VIRTUAL_P (current_function_decl))
3744     {
3745       if (dump_file)
3746         fprintf (dump_file, "Function is a virtual method.\n");
3747       return false;
3748     }
3749
3750   if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
3751       && node->global.size >= MAX_INLINE_INSNS_AUTO)
3752     {
3753       if (dump_file)
3754         fprintf (dump_file, "Function too big to be made truly local.\n");
3755       return false;
3756     }
3757
3758   if (!node->callers)
3759     {
3760       if (dump_file)
3761         fprintf (dump_file,
3762                  "Function has no callers in this compilation unit.\n");
3763       return false;
3764     }
3765
3766   if (cfun->stdarg)
3767     {
3768       if (dump_file)
3769         fprintf (dump_file, "Function uses stdarg. \n");
3770       return false;
3771     }
3772
3773   return true;
3774 }
3775
3776 /* Perform early interprocedural SRA.  */
3777
3778 static unsigned int
3779 ipa_early_sra (void)
3780 {
3781   struct cgraph_node *node = cgraph_node (current_function_decl);
3782   ipa_parm_adjustment_vec adjustments;
3783   int ret = 0;
3784
3785   if (!ipa_sra_preliminary_function_checks (node))
3786     return 0;
3787
3788   sra_initialize ();
3789   sra_mode = SRA_MODE_EARLY_IPA;
3790
3791   if (!find_param_candidates ())
3792     {
3793       if (dump_file)
3794         fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
3795       goto simple_out;
3796     }
3797
3798   bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
3799                                  func_param_count
3800                                  * last_basic_block_for_function (cfun));
3801   final_bbs = BITMAP_ALLOC (NULL);
3802
3803   scan_function (build_access_from_expr, build_accesses_from_assign,
3804                  NULL, true, NULL);
3805   if (encountered_apply_args)
3806     {
3807       if (dump_file)
3808         fprintf (dump_file, "Function calls  __builtin_apply_args().\n");
3809       goto out;
3810     }
3811
3812   adjustments = analyze_all_param_acesses ();
3813   if (!adjustments)
3814     goto out;
3815   if (dump_file)
3816     ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
3817
3818   modify_function (node, adjustments);
3819   VEC_free (ipa_parm_adjustment_t, heap, adjustments);
3820   ret = TODO_update_ssa;
3821
3822   statistics_counter_event (cfun, "Unused parameters deleted",
3823                             sra_stats.deleted_unused_parameters);
3824   statistics_counter_event (cfun, "Scalar parameters converted to by-value",
3825                             sra_stats.scalar_by_ref_to_by_val);
3826   statistics_counter_event (cfun, "Aggregate parameters broken up",
3827                             sra_stats.aggregate_params_reduced);
3828   statistics_counter_event (cfun, "Aggregate parameter components created",
3829                             sra_stats.param_reductions_created);
3830
3831  out:
3832   BITMAP_FREE (final_bbs);
3833   free (bb_dereferences);
3834  simple_out:
3835   sra_deinitialize ();
3836   return ret;
3837 }
3838
3839 /* Return if early ipa sra shall be performed.  */
3840 static bool
3841 ipa_early_sra_gate (void)
3842 {
3843   return flag_ipa_sra;
3844 }
3845
3846 struct gimple_opt_pass pass_early_ipa_sra =
3847 {
3848  {
3849   GIMPLE_PASS,
3850   "eipa_sra",                           /* name */
3851   ipa_early_sra_gate,                   /* gate */
3852   ipa_early_sra,                        /* execute */
3853   NULL,                                 /* sub */
3854   NULL,                                 /* next */
3855   0,                                    /* static_pass_number */
3856   TV_IPA_SRA,                           /* tv_id */
3857   0,                                    /* properties_required */
3858   0,                                    /* properties_provided */
3859   0,                                    /* properties_destroyed */
3860   0,                                    /* todo_flags_start */
3861   TODO_dump_func | TODO_dump_cgraph     /* todo_flags_finish */
3862  }
3863 };
3864
3865