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