OSDN Git Service

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