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