OSDN Git Service

2005-06-28 Thomas Koenig <Thomas.Koenig@online.de>
[pf3gnuchains/gcc-fork.git] / gcc / tree-sra.c
1 /* Scalar Replacement of Aggregates (SRA) converts some structure
2    references into scalar references, exposing them to the scalar
3    optimizers.
4    Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
5    Contributed by Diego Novillo <dnovillo@redhat.com>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
12 later version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY 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 COPYING.  If not, write to the Free
21 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22 02110-1301, USA.  */
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "ggc.h"
29 #include "tree.h"
30
31 /* These RTL headers are needed for basic-block.h.  */
32 #include "rtl.h"
33 #include "tm_p.h"
34 #include "hard-reg-set.h"
35 #include "basic-block.h"
36 #include "diagnostic.h"
37 #include "langhooks.h"
38 #include "tree-inline.h"
39 #include "tree-flow.h"
40 #include "tree-gimple.h"
41 #include "tree-dump.h"
42 #include "tree-pass.h"
43 #include "timevar.h"
44 #include "flags.h"
45 #include "bitmap.h"
46 #include "obstack.h"
47 #include "target.h"
48 /* expr.h is needed for MOVE_RATIO.  */
49 #include "expr.h"
50 #include "params.h"
51
52
53 /* This object of this pass is to replace a non-addressable aggregate with a
54    set of independent variables.  Most of the time, all of these variables
55    will be scalars.  But a secondary objective is to break up larger
56    aggregates into smaller aggregates.  In the process we may find that some
57    bits of the larger aggregate can be deleted as unreferenced.
58
59    This substitution is done globally.  More localized substitutions would
60    be the purvey of a load-store motion pass.
61
62    The optimization proceeds in phases:
63
64      (1) Identify variables that have types that are candidates for
65          decomposition.
66
67      (2) Scan the function looking for the ways these variables are used.
68          In particular we're interested in the number of times a variable
69          (or member) is needed as a complete unit, and the number of times
70          a variable (or member) is copied.
71
72      (3) Based on the usage profile, instantiate substitution variables.
73
74      (4) Scan the function making replacements.
75 */
76
77
78 /* The set of aggregate variables that are candidates for scalarization.  */
79 static bitmap sra_candidates;
80
81 /* Set of scalarizable PARM_DECLs that need copy-in operations at the
82    beginning of the function.  */
83 static bitmap needs_copy_in;
84
85 /* Sets of bit pairs that cache type decomposition and instantiation.  */
86 static bitmap sra_type_decomp_cache;
87 static bitmap sra_type_inst_cache;
88
89 /* One of these structures is created for each candidate aggregate
90    and each (accessed) member of such an aggregate.  */
91 struct sra_elt
92 {
93   /* A tree of the elements.  Used when we want to traverse everything.  */
94   struct sra_elt *parent;
95   struct sra_elt *children;
96   struct sra_elt *sibling;
97
98   /* If this element is a root, then this is the VAR_DECL.  If this is
99      a sub-element, this is some token used to identify the reference.
100      In the case of COMPONENT_REF, this is the FIELD_DECL.  In the case
101      of an ARRAY_REF, this is the (constant) index.  In the case of a
102      complex number, this is a zero or one.  */
103   tree element;
104
105   /* The type of the element.  */
106   tree type;
107
108   /* A VAR_DECL, for any sub-element we've decided to replace.  */
109   tree replacement;
110
111   /* The number of times the element is referenced as a whole.  I.e.
112      given "a.b.c", this would be incremented for C, but not for A or B.  */
113   unsigned int n_uses;
114
115   /* The number of times the element is copied to or from another
116      scalarizable element.  */
117   unsigned int n_copies;
118
119   /* True if TYPE is scalar.  */
120   bool is_scalar;
121
122   /* True if we saw something about this element that prevents scalarization,
123      such as non-constant indexing.  */
124   bool cannot_scalarize;
125
126   /* True if we've decided that structure-to-structure assignment
127      should happen via memcpy and not per-element.  */
128   bool use_block_copy;
129
130   /* A flag for use with/after random access traversals.  */
131   bool visited;
132 };
133
134 /* Random access to the child of a parent is performed by hashing.
135    This prevents quadratic behavior, and allows SRA to function
136    reasonably on larger records.  */
137 static htab_t sra_map;
138
139 /* All structures are allocated out of the following obstack.  */
140 static struct obstack sra_obstack;
141
142 /* Debugging functions.  */
143 static void dump_sra_elt_name (FILE *, struct sra_elt *);
144 extern void debug_sra_elt_name (struct sra_elt *);
145
146 /* Forward declarations.  */
147 static tree generate_element_ref (struct sra_elt *);
148 \f
149 /* Return true if DECL is an SRA candidate.  */
150
151 static bool
152 is_sra_candidate_decl (tree decl)
153 {
154   return DECL_P (decl) && bitmap_bit_p (sra_candidates, var_ann (decl)->uid);
155 }
156
157 /* Return true if TYPE is a scalar type.  */
158
159 static bool
160 is_sra_scalar_type (tree type)
161 {
162   enum tree_code code = TREE_CODE (type);
163   return (code == INTEGER_TYPE || code == REAL_TYPE || code == VECTOR_TYPE
164           || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE
165           || code == CHAR_TYPE || code == POINTER_TYPE || code == OFFSET_TYPE
166           || code == REFERENCE_TYPE);
167 }
168
169 /* Return true if TYPE can be decomposed into a set of independent variables.
170
171    Note that this doesn't imply that all elements of TYPE can be
172    instantiated, just that if we decide to break up the type into
173    separate pieces that it can be done.  */
174
175 static bool
176 type_can_be_decomposed_p (tree type)
177 {
178   unsigned int cache = TYPE_UID (TYPE_MAIN_VARIANT (type)) * 2;
179   tree t;
180
181   /* Avoid searching the same type twice.  */
182   if (bitmap_bit_p (sra_type_decomp_cache, cache+0))
183     return true;
184   if (bitmap_bit_p (sra_type_decomp_cache, cache+1))
185     return false;
186
187   /* The type must have a definite nonzero size.  */
188   if (TYPE_SIZE (type) == NULL || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
189       || integer_zerop (TYPE_SIZE (type)))
190     goto fail;
191
192   /* The type must be a non-union aggregate.  */
193   switch (TREE_CODE (type))
194     {
195     case RECORD_TYPE:
196       {
197         bool saw_one_field = false;
198
199         for (t = TYPE_FIELDS (type); t ; t = TREE_CHAIN (t))
200           if (TREE_CODE (t) == FIELD_DECL)
201             {
202               /* Reject incorrectly represented bit fields.  */
203               if (DECL_BIT_FIELD (t)
204                   && (tree_low_cst (DECL_SIZE (t), 1)
205                       != TYPE_PRECISION (TREE_TYPE (t))))
206                 goto fail;
207
208               saw_one_field = true;
209             }
210
211         /* Record types must have at least one field.  */
212         if (!saw_one_field)
213           goto fail;
214       }
215       break;
216
217     case ARRAY_TYPE:
218       /* Array types must have a fixed lower and upper bound.  */
219       t = TYPE_DOMAIN (type);
220       if (t == NULL)
221         goto fail;
222       if (TYPE_MIN_VALUE (t) == NULL || !TREE_CONSTANT (TYPE_MIN_VALUE (t)))
223         goto fail;
224       if (TYPE_MAX_VALUE (t) == NULL || !TREE_CONSTANT (TYPE_MAX_VALUE (t)))
225         goto fail;
226       break;
227
228     case COMPLEX_TYPE:
229       break;
230
231     default:
232       goto fail;
233     }
234
235   bitmap_set_bit (sra_type_decomp_cache, cache+0);
236   return true;
237
238  fail:
239   bitmap_set_bit (sra_type_decomp_cache, cache+1);
240   return false;
241 }
242
243 /* Return true if DECL can be decomposed into a set of independent
244    (though not necessarily scalar) variables.  */
245
246 static bool
247 decl_can_be_decomposed_p (tree var)
248 {
249   /* Early out for scalars.  */
250   if (is_sra_scalar_type (TREE_TYPE (var)))
251     return false;
252
253   /* The variable must not be aliased.  */
254   if (!is_gimple_non_addressable (var))
255     {
256       if (dump_file && (dump_flags & TDF_DETAILS))
257         {
258           fprintf (dump_file, "Cannot scalarize variable ");
259           print_generic_expr (dump_file, var, dump_flags);
260           fprintf (dump_file, " because it must live in memory\n");
261         }
262       return false;
263     }
264
265   /* The variable must not be volatile.  */
266   if (TREE_THIS_VOLATILE (var))
267     {
268       if (dump_file && (dump_flags & TDF_DETAILS))
269         {
270           fprintf (dump_file, "Cannot scalarize variable ");
271           print_generic_expr (dump_file, var, dump_flags);
272           fprintf (dump_file, " because it is declared volatile\n");
273         }
274       return false;
275     }
276
277   /* We must be able to decompose the variable's type.  */
278   if (!type_can_be_decomposed_p (TREE_TYPE (var)))
279     {
280       if (dump_file && (dump_flags & TDF_DETAILS))
281         {
282           fprintf (dump_file, "Cannot scalarize variable ");
283           print_generic_expr (dump_file, var, dump_flags);
284           fprintf (dump_file, " because its type cannot be decomposed\n");
285         }
286       return false;
287     }
288
289   return true;
290 }
291
292 /* Return true if TYPE can be *completely* decomposed into scalars.  */
293
294 static bool
295 type_can_instantiate_all_elements (tree type)
296 {
297   if (is_sra_scalar_type (type))
298     return true;
299   if (!type_can_be_decomposed_p (type))
300     return false;
301
302   switch (TREE_CODE (type))
303     {
304     case RECORD_TYPE:
305       {
306         unsigned int cache = TYPE_UID (TYPE_MAIN_VARIANT (type)) * 2;
307         tree f;
308
309         if (bitmap_bit_p (sra_type_inst_cache, cache+0))
310           return true;
311         if (bitmap_bit_p (sra_type_inst_cache, cache+1))
312           return false;
313
314         for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
315           if (TREE_CODE (f) == FIELD_DECL)
316             {
317               if (!type_can_instantiate_all_elements (TREE_TYPE (f)))
318                 {
319                   bitmap_set_bit (sra_type_inst_cache, cache+1);
320                   return false;
321                 }
322             }
323
324         bitmap_set_bit (sra_type_inst_cache, cache+0);
325         return true;
326       }
327
328     case ARRAY_TYPE:
329       return type_can_instantiate_all_elements (TREE_TYPE (type));
330
331     case COMPLEX_TYPE:
332       return true;
333
334     default:
335       gcc_unreachable ();
336     }
337 }
338
339 /* Test whether ELT or some sub-element cannot be scalarized.  */
340
341 static bool
342 can_completely_scalarize_p (struct sra_elt *elt)
343 {
344   struct sra_elt *c;
345
346   if (elt->cannot_scalarize)
347     return false;
348
349   for (c = elt->children; c ; c = c->sibling)
350     if (!can_completely_scalarize_p (c))
351       return false;
352
353   return true;
354 }
355
356 \f
357 /* A simplified tree hashing algorithm that only handles the types of
358    trees we expect to find in sra_elt->element.  */
359
360 static hashval_t
361 sra_hash_tree (tree t)
362 {
363   hashval_t h;
364
365   switch (TREE_CODE (t))
366     {
367     case VAR_DECL:
368     case PARM_DECL:
369     case RESULT_DECL:
370       h = DECL_UID (t);
371       break;
372
373     case INTEGER_CST:
374       h = TREE_INT_CST_LOW (t) ^ TREE_INT_CST_HIGH (t);
375       break;
376
377     case FIELD_DECL:
378       /* We can have types that are compatible, but have different member
379          lists, so we can't hash fields by ID.  Use offsets instead.  */
380       h = iterative_hash_expr (DECL_FIELD_OFFSET (t), 0);
381       h = iterative_hash_expr (DECL_FIELD_BIT_OFFSET (t), h);
382       break;
383
384     default:
385       gcc_unreachable ();
386     }
387
388   return h;
389 }
390
391 /* Hash function for type SRA_PAIR.  */
392
393 static hashval_t
394 sra_elt_hash (const void *x)
395 {
396   const struct sra_elt *e = x;
397   const struct sra_elt *p;
398   hashval_t h;
399
400   h = sra_hash_tree (e->element);
401
402   /* Take into account everything back up the chain.  Given that chain
403      lengths are rarely very long, this should be acceptable.  If we
404      truly identify this as a performance problem, it should work to
405      hash the pointer value "e->parent".  */
406   for (p = e->parent; p ; p = p->parent)
407     h = (h * 65521) ^ sra_hash_tree (p->element);
408
409   return h;
410 }
411
412 /* Equality function for type SRA_PAIR.  */
413
414 static int
415 sra_elt_eq (const void *x, const void *y)
416 {
417   const struct sra_elt *a = x;
418   const struct sra_elt *b = y;
419   tree ae, be;
420
421   if (a->parent != b->parent)
422     return false;
423
424   ae = a->element;
425   be = b->element;
426
427   if (ae == be)
428     return true;
429   if (TREE_CODE (ae) != TREE_CODE (be))
430     return false;
431
432   switch (TREE_CODE (ae))
433     {
434     case VAR_DECL:
435     case PARM_DECL:
436     case RESULT_DECL:
437       /* These are all pointer unique.  */
438       return false;
439
440     case INTEGER_CST:
441       /* Integers are not pointer unique, so compare their values.  */
442       return tree_int_cst_equal (ae, be);
443
444     case FIELD_DECL:
445       /* Fields are unique within a record, but not between
446          compatible records.  */
447       if (DECL_FIELD_CONTEXT (ae) == DECL_FIELD_CONTEXT (be))
448         return false;
449       return fields_compatible_p (ae, be);
450
451     default:
452       gcc_unreachable ();
453     }
454 }
455
456 /* Create or return the SRA_ELT structure for CHILD in PARENT.  PARENT
457    may be null, in which case CHILD must be a DECL.  */
458
459 static struct sra_elt *
460 lookup_element (struct sra_elt *parent, tree child, tree type,
461                 enum insert_option insert)
462 {
463   struct sra_elt dummy;
464   struct sra_elt **slot;
465   struct sra_elt *elt;
466
467   dummy.parent = parent;
468   dummy.element = child;
469
470   slot = (struct sra_elt **) htab_find_slot (sra_map, &dummy, insert);
471   if (!slot && insert == NO_INSERT)
472     return NULL;
473
474   elt = *slot;
475   if (!elt && insert == INSERT)
476     {
477       *slot = elt = obstack_alloc (&sra_obstack, sizeof (*elt));
478       memset (elt, 0, sizeof (*elt));
479
480       elt->parent = parent;
481       elt->element = child;
482       elt->type = type;
483       elt->is_scalar = is_sra_scalar_type (type);
484
485       if (parent)
486         {
487           elt->sibling = parent->children;
488           parent->children = elt;
489         }
490
491       /* If this is a parameter, then if we want to scalarize, we have
492          one copy from the true function parameter.  Count it now.  */
493       if (TREE_CODE (child) == PARM_DECL)
494         {
495           elt->n_copies = 1;
496           bitmap_set_bit (needs_copy_in, var_ann (child)->uid);
497         }
498     }
499
500   return elt;
501 }
502
503 /* Return true if the ARRAY_REF in EXPR is a constant, in bounds access.  */
504
505 static bool
506 is_valid_const_index (tree expr)
507 {
508   tree dom, t, index = TREE_OPERAND (expr, 1);
509
510   if (TREE_CODE (index) != INTEGER_CST)
511     return false;
512
513   /* Watch out for stupid user tricks, indexing outside the array.
514
515      Careful, we're not called only on scalarizable types, so do not
516      assume constant array bounds.  We needn't do anything with such
517      cases, since they'll be referring to objects that we should have
518      already rejected for scalarization, so returning false is fine.  */
519
520   dom = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (expr, 0)));
521   if (dom == NULL)
522     return false;
523
524   t = TYPE_MIN_VALUE (dom);
525   if (!t || TREE_CODE (t) != INTEGER_CST)
526     return false;
527   if (tree_int_cst_lt (index, t))
528     return false;
529
530   t = TYPE_MAX_VALUE (dom);
531   if (!t || TREE_CODE (t) != INTEGER_CST)
532     return false;
533   if (tree_int_cst_lt (t, index))
534     return false;
535
536   return true;
537 }
538
539 /* Create or return the SRA_ELT structure for EXPR if the expression
540    refers to a scalarizable variable.  */
541
542 static struct sra_elt *
543 maybe_lookup_element_for_expr (tree expr)
544 {
545   struct sra_elt *elt;
546   tree child;
547
548   switch (TREE_CODE (expr))
549     {
550     case VAR_DECL:
551     case PARM_DECL:
552     case RESULT_DECL:
553       if (is_sra_candidate_decl (expr))
554         return lookup_element (NULL, expr, TREE_TYPE (expr), INSERT);
555       return NULL;
556
557     case ARRAY_REF:
558       /* We can't scalarize variable array indicies.  */
559       if (is_valid_const_index (expr))
560         child = TREE_OPERAND (expr, 1);
561       else
562         return NULL;
563       break;
564
565     case COMPONENT_REF:
566       /* Don't look through unions.  */
567       if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) != RECORD_TYPE)
568         return NULL;
569       child = TREE_OPERAND (expr, 1);
570       break;
571
572     case REALPART_EXPR:
573       child = integer_zero_node;
574       break;
575     case IMAGPART_EXPR:
576       child = integer_one_node;
577       break;
578
579     default:
580       return NULL;
581     }
582
583   elt = maybe_lookup_element_for_expr (TREE_OPERAND (expr, 0));
584   if (elt)
585     return lookup_element (elt, child, TREE_TYPE (expr), INSERT);
586   return NULL;
587 }
588
589 \f
590 /* Functions to walk just enough of the tree to see all scalarizable
591    references, and categorize them.  */
592
593 /* A set of callbacks for phases 2 and 4.  They'll be invoked for the
594    various kinds of references seen.  In all cases, *BSI is an iterator
595    pointing to the statement being processed.  */
596 struct sra_walk_fns
597 {
598   /* Invoked when ELT is required as a unit.  Note that ELT might refer to
599      a leaf node, in which case this is a simple scalar reference.  *EXPR_P
600      points to the location of the expression.  IS_OUTPUT is true if this
601      is a left-hand-side reference.  */
602   void (*use) (struct sra_elt *elt, tree *expr_p,
603                block_stmt_iterator *bsi, bool is_output);
604
605   /* Invoked when we have a copy between two scalarizable references.  */
606   void (*copy) (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
607                 block_stmt_iterator *bsi);
608
609   /* Invoked when ELT is initialized from a constant.  VALUE may be NULL,
610      in which case it should be treated as an empty CONSTRUCTOR.  */
611   void (*init) (struct sra_elt *elt, tree value, block_stmt_iterator *bsi);
612
613   /* Invoked when we have a copy between one scalarizable reference ELT
614      and one non-scalarizable reference OTHER.  IS_OUTPUT is true if ELT
615      is on the left-hand side.  */
616   void (*ldst) (struct sra_elt *elt, tree other,
617                 block_stmt_iterator *bsi, bool is_output);
618
619   /* True during phase 2, false during phase 4.  */
620   /* ??? This is a hack.  */
621   bool initial_scan;
622 };
623
624 #ifdef ENABLE_CHECKING
625 /* Invoked via walk_tree, if *TP contains a candidate decl, return it.  */
626
627 static tree
628 sra_find_candidate_decl (tree *tp, int *walk_subtrees,
629                          void *data ATTRIBUTE_UNUSED)
630 {
631   tree t = *tp;
632   enum tree_code code = TREE_CODE (t);
633
634   if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
635     {
636       *walk_subtrees = 0;
637       if (is_sra_candidate_decl (t))
638         return t;
639     }
640   else if (TYPE_P (t))
641     *walk_subtrees = 0;
642
643   return NULL;
644 }
645 #endif
646
647 /* Walk most expressions looking for a scalarizable aggregate.
648    If we find one, invoke FNS->USE.  */
649
650 static void
651 sra_walk_expr (tree *expr_p, block_stmt_iterator *bsi, bool is_output,
652                const struct sra_walk_fns *fns)
653 {
654   tree expr = *expr_p;
655   tree inner = expr;
656   bool disable_scalarization = false;
657
658   /* We're looking to collect a reference expression between EXPR and INNER,
659      such that INNER is a scalarizable decl and all other nodes through EXPR
660      are references that we can scalarize.  If we come across something that
661      we can't scalarize, we reset EXPR.  This has the effect of making it
662      appear that we're referring to the larger expression as a whole.  */
663
664   while (1)
665     switch (TREE_CODE (inner))
666       {
667       case VAR_DECL:
668       case PARM_DECL:
669       case RESULT_DECL:
670         /* If there is a scalarizable decl at the bottom, then process it.  */
671         if (is_sra_candidate_decl (inner))
672           {
673             struct sra_elt *elt = maybe_lookup_element_for_expr (expr);
674             if (disable_scalarization)
675               elt->cannot_scalarize = true;
676             else
677               fns->use (elt, expr_p, bsi, is_output);
678           }
679         return;
680
681       case ARRAY_REF:
682         /* Non-constant index means any member may be accessed.  Prevent the
683            expression from being scalarized.  If we were to treat this as a
684            reference to the whole array, we can wind up with a single dynamic
685            index reference inside a loop being overridden by several constant
686            index references during loop setup.  It's possible that this could
687            be avoided by using dynamic usage counts based on BB trip counts
688            (based on loop analysis or profiling), but that hardly seems worth
689            the effort.  */
690         /* ??? Hack.  Figure out how to push this into the scan routines
691            without duplicating too much code.  */
692         if (!is_valid_const_index (inner))
693           {
694             disable_scalarization = true;
695             goto use_all;
696           }
697         /* ??? Are we assured that non-constant bounds and stride will have
698            the same value everywhere?  I don't think Fortran will...  */
699         if (TREE_OPERAND (inner, 2) || TREE_OPERAND (inner, 3))
700           goto use_all;
701         inner = TREE_OPERAND (inner, 0);
702         break;
703
704       case COMPONENT_REF:
705         /* A reference to a union member constitutes a reference to the
706            entire union.  */
707         if (TREE_CODE (TREE_TYPE (TREE_OPERAND (inner, 0))) != RECORD_TYPE)
708           goto use_all;
709         /* ??? See above re non-constant stride.  */
710         if (TREE_OPERAND (inner, 2))
711           goto use_all;
712         inner = TREE_OPERAND (inner, 0);
713         break;
714
715       case REALPART_EXPR:
716       case IMAGPART_EXPR:
717         inner = TREE_OPERAND (inner, 0);
718         break;
719
720       case BIT_FIELD_REF:
721         /* A bit field reference (access to *multiple* fields simultaneously)
722            is not currently scalarized.  Consider this an access to the
723            complete outer element, to which walk_tree will bring us next.  */
724         goto use_all;
725
726       case ARRAY_RANGE_REF:
727         /* Similarly, an subrange reference is used to modify indexing.  Which
728            means that the canonical element names that we have won't work.  */
729         goto use_all;
730
731       case VIEW_CONVERT_EXPR:
732       case NOP_EXPR:
733         /* Similarly, a view/nop explicitly wants to look at an object in a
734            type other than the one we've scalarized.  */
735         goto use_all;
736
737       case WITH_SIZE_EXPR:
738         /* This is a transparent wrapper.  The entire inner expression really
739            is being used.  */
740         goto use_all;
741
742       use_all:
743         expr_p = &TREE_OPERAND (inner, 0);
744         inner = expr = *expr_p;
745         break;
746
747       default:
748 #ifdef ENABLE_CHECKING
749         /* Validate that we're not missing any references.  */
750         gcc_assert (!walk_tree (&inner, sra_find_candidate_decl, NULL, NULL));
751 #endif
752         return;
753       }
754 }
755
756 /* Walk a TREE_LIST of values looking for scalarizable aggregates.
757    If we find one, invoke FNS->USE.  */
758
759 static void
760 sra_walk_tree_list (tree list, block_stmt_iterator *bsi, bool is_output,
761                     const struct sra_walk_fns *fns)
762 {
763   tree op;
764   for (op = list; op ; op = TREE_CHAIN (op))
765     sra_walk_expr (&TREE_VALUE (op), bsi, is_output, fns);
766 }
767
768 /* Walk the arguments of a CALL_EXPR looking for scalarizable aggregates.
769    If we find one, invoke FNS->USE.  */
770
771 static void
772 sra_walk_call_expr (tree expr, block_stmt_iterator *bsi,
773                     const struct sra_walk_fns *fns)
774 {
775   sra_walk_tree_list (TREE_OPERAND (expr, 1), bsi, false, fns);
776 }
777
778 /* Walk the inputs and outputs of an ASM_EXPR looking for scalarizable
779    aggregates.  If we find one, invoke FNS->USE.  */
780
781 static void
782 sra_walk_asm_expr (tree expr, block_stmt_iterator *bsi,
783                    const struct sra_walk_fns *fns)
784 {
785   sra_walk_tree_list (ASM_INPUTS (expr), bsi, false, fns);
786   sra_walk_tree_list (ASM_OUTPUTS (expr), bsi, true, fns);
787 }
788
789 /* Walk a MODIFY_EXPR and categorize the assignment appropriately.  */
790
791 static void
792 sra_walk_modify_expr (tree expr, block_stmt_iterator *bsi,
793                       const struct sra_walk_fns *fns)
794 {
795   struct sra_elt *lhs_elt, *rhs_elt;
796   tree lhs, rhs;
797
798   lhs = TREE_OPERAND (expr, 0);
799   rhs = TREE_OPERAND (expr, 1);
800   lhs_elt = maybe_lookup_element_for_expr (lhs);
801   rhs_elt = maybe_lookup_element_for_expr (rhs);
802
803   /* If both sides are scalarizable, this is a COPY operation.  */
804   if (lhs_elt && rhs_elt)
805     {
806       fns->copy (lhs_elt, rhs_elt, bsi);
807       return;
808     }
809
810   /* If the RHS is scalarizable, handle it.  There are only two cases.  */
811   if (rhs_elt)
812     {
813       if (!rhs_elt->is_scalar)
814         fns->ldst (rhs_elt, lhs, bsi, false);
815       else
816         fns->use (rhs_elt, &TREE_OPERAND (expr, 1), bsi, false);
817     }
818
819   /* If it isn't scalarizable, there may be scalarizable variables within, so
820      check for a call or else walk the RHS to see if we need to do any
821      copy-in operations.  We need to do it before the LHS is scalarized so
822      that the statements get inserted in the proper place, before any
823      copy-out operations.  */
824   else
825     {
826       tree call = get_call_expr_in (rhs);
827       if (call)
828         sra_walk_call_expr (call, bsi, fns);
829       else
830         sra_walk_expr (&TREE_OPERAND (expr, 1), bsi, false, fns);
831     }
832
833   /* Likewise, handle the LHS being scalarizable.  We have cases similar
834      to those above, but also want to handle RHS being constant.  */
835   if (lhs_elt)
836     {
837       /* If this is an assignment from a constant, or constructor, then
838          we have access to all of the elements individually.  Invoke INIT.  */
839       if (TREE_CODE (rhs) == COMPLEX_EXPR
840           || TREE_CODE (rhs) == COMPLEX_CST
841           || TREE_CODE (rhs) == CONSTRUCTOR)
842         fns->init (lhs_elt, rhs, bsi);
843
844       /* If this is an assignment from read-only memory, treat this as if
845          we'd been passed the constructor directly.  Invoke INIT.  */
846       else if (TREE_CODE (rhs) == VAR_DECL
847                && TREE_STATIC (rhs)
848                && TREE_READONLY (rhs)
849                && targetm.binds_local_p (rhs))
850         fns->init (lhs_elt, DECL_INITIAL (rhs), bsi);
851
852       /* If this is a copy from a non-scalarizable lvalue, invoke LDST.
853          The lvalue requirement prevents us from trying to directly scalarize
854          the result of a function call.  Which would result in trying to call
855          the function multiple times, and other evil things.  */
856       else if (!lhs_elt->is_scalar && is_gimple_addressable (rhs))
857         fns->ldst (lhs_elt, rhs, bsi, true);
858
859       /* Otherwise we're being used in some context that requires the
860          aggregate to be seen as a whole.  Invoke USE.  */
861       else
862         fns->use (lhs_elt, &TREE_OPERAND (expr, 0), bsi, true);
863     }
864
865   /* Similarly to above, LHS_ELT being null only means that the LHS as a
866      whole is not a scalarizable reference.  There may be occurrences of
867      scalarizable variables within, which implies a USE.  */
868   else
869     sra_walk_expr (&TREE_OPERAND (expr, 0), bsi, true, fns);
870 }
871
872 /* Entry point to the walk functions.  Search the entire function,
873    invoking the callbacks in FNS on each of the references to
874    scalarizable variables.  */
875
876 static void
877 sra_walk_function (const struct sra_walk_fns *fns)
878 {
879   basic_block bb;
880   block_stmt_iterator si, ni;
881
882   /* ??? Phase 4 could derive some benefit to walking the function in
883      dominator tree order.  */
884
885   FOR_EACH_BB (bb)
886     for (si = bsi_start (bb); !bsi_end_p (si); si = ni)
887       {
888         tree stmt, t;
889         stmt_ann_t ann;
890
891         stmt = bsi_stmt (si);
892         ann = stmt_ann (stmt);
893
894         ni = si;
895         bsi_next (&ni);
896
897         /* If the statement has no virtual operands, then it doesn't
898            make any structure references that we care about.  */
899         if (ZERO_SSA_OPERANDS (stmt, (SSA_OP_VIRTUAL_DEFS | SSA_OP_VUSE)))
900           continue;
901
902         switch (TREE_CODE (stmt))
903           {
904           case RETURN_EXPR:
905             /* If we have "return <retval>" then the return value is
906                already exposed for our pleasure.  Walk it as a USE to
907                force all the components back in place for the return.
908
909                If we have an embedded assignment, then <retval> is of
910                a type that gets returned in registers in this ABI, and
911                we do not wish to extend their lifetimes.  Treat this
912                as a USE of the variable on the RHS of this assignment.  */
913
914             t = TREE_OPERAND (stmt, 0);
915             if (TREE_CODE (t) == MODIFY_EXPR)
916               sra_walk_expr (&TREE_OPERAND (t, 1), &si, false, fns);
917             else
918               sra_walk_expr (&TREE_OPERAND (stmt, 0), &si, false, fns);
919             break;
920
921           case MODIFY_EXPR:
922             sra_walk_modify_expr (stmt, &si, fns);
923             break;
924           case CALL_EXPR:
925             sra_walk_call_expr (stmt, &si, fns);
926             break;
927           case ASM_EXPR:
928             sra_walk_asm_expr (stmt, &si, fns);
929             break;
930
931           default:
932             break;
933           }
934       }
935 }
936 \f
937 /* Phase One: Scan all referenced variables in the program looking for
938    structures that could be decomposed.  */
939
940 static bool
941 find_candidates_for_sra (void)
942 {
943   size_t i;
944   bool any_set = false;
945
946   for (i = 0; i < num_referenced_vars; i++)
947     {
948       tree var = referenced_var (i);
949       if (decl_can_be_decomposed_p (var))
950         {
951           bitmap_set_bit (sra_candidates, var_ann (var)->uid);
952           any_set = true;
953         }
954     }
955
956   return any_set;
957 }
958
959 \f
960 /* Phase Two: Scan all references to scalarizable variables.  Count the
961    number of times they are used or copied respectively.  */
962
963 /* Callbacks to fill in SRA_WALK_FNS.  Everything but USE is
964    considered a copy, because we can decompose the reference such that
965    the sub-elements needn't be contiguous.  */
966
967 static void
968 scan_use (struct sra_elt *elt, tree *expr_p ATTRIBUTE_UNUSED,
969           block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
970           bool is_output ATTRIBUTE_UNUSED)
971 {
972   elt->n_uses += 1;
973 }
974
975 static void
976 scan_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
977            block_stmt_iterator *bsi ATTRIBUTE_UNUSED)
978 {
979   lhs_elt->n_copies += 1;
980   rhs_elt->n_copies += 1;
981 }
982
983 static void
984 scan_init (struct sra_elt *lhs_elt, tree rhs ATTRIBUTE_UNUSED,
985            block_stmt_iterator *bsi ATTRIBUTE_UNUSED)
986 {
987   lhs_elt->n_copies += 1;
988 }
989
990 static void
991 scan_ldst (struct sra_elt *elt, tree other ATTRIBUTE_UNUSED,
992            block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
993            bool is_output ATTRIBUTE_UNUSED)
994 {
995   elt->n_copies += 1;
996 }
997
998 /* Dump the values we collected during the scanning phase.  */
999
1000 static void
1001 scan_dump (struct sra_elt *elt)
1002 {
1003   struct sra_elt *c;
1004
1005   dump_sra_elt_name (dump_file, elt);
1006   fprintf (dump_file, ": n_uses=%u n_copies=%u\n", elt->n_uses, elt->n_copies);
1007
1008   for (c = elt->children; c ; c = c->sibling)
1009     scan_dump (c);
1010 }
1011
1012 /* Entry point to phase 2.  Scan the entire function, building up
1013    scalarization data structures, recording copies and uses.  */
1014
1015 static void
1016 scan_function (void)
1017 {
1018   static const struct sra_walk_fns fns = {
1019     scan_use, scan_copy, scan_init, scan_ldst, true
1020   };
1021   bitmap_iterator bi;
1022
1023   sra_walk_function (&fns);
1024
1025   if (dump_file && (dump_flags & TDF_DETAILS))
1026     {
1027       unsigned i;
1028
1029       fputs ("\nScan results:\n", dump_file);
1030       EXECUTE_IF_SET_IN_BITMAP (sra_candidates, 0, i, bi)
1031         {
1032           tree var = referenced_var (i);
1033           struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT);
1034           if (elt)
1035             scan_dump (elt);
1036         }
1037       fputc ('\n', dump_file);
1038     }
1039 }
1040 \f
1041 /* Phase Three: Make decisions about which variables to scalarize, if any.
1042    All elements to be scalarized have replacement variables made for them.  */
1043
1044 /* A subroutine of build_element_name.  Recursively build the element
1045    name on the obstack.  */
1046
1047 static void
1048 build_element_name_1 (struct sra_elt *elt)
1049 {
1050   tree t;
1051   char buffer[32];
1052
1053   if (elt->parent)
1054     {
1055       build_element_name_1 (elt->parent);
1056       obstack_1grow (&sra_obstack, '$');
1057
1058       if (TREE_CODE (elt->parent->type) == COMPLEX_TYPE)
1059         {
1060           if (elt->element == integer_zero_node)
1061             obstack_grow (&sra_obstack, "real", 4);
1062           else
1063             obstack_grow (&sra_obstack, "imag", 4);
1064           return;
1065         }
1066     }
1067
1068   t = elt->element;
1069   if (TREE_CODE (t) == INTEGER_CST)
1070     {
1071       /* ??? Eh.  Don't bother doing double-wide printing.  */
1072       sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (t));
1073       obstack_grow (&sra_obstack, buffer, strlen (buffer));
1074     }
1075   else
1076     {
1077       tree name = DECL_NAME (t);
1078       if (name)
1079         obstack_grow (&sra_obstack, IDENTIFIER_POINTER (name),
1080                       IDENTIFIER_LENGTH (name));
1081       else
1082         {
1083           sprintf (buffer, "D%u", DECL_UID (t));
1084           obstack_grow (&sra_obstack, buffer, strlen (buffer));
1085         }
1086     }
1087 }
1088
1089 /* Construct a pretty variable name for an element's replacement variable.
1090    The name is built on the obstack.  */
1091
1092 static char *
1093 build_element_name (struct sra_elt *elt)
1094 {
1095   build_element_name_1 (elt);
1096   obstack_1grow (&sra_obstack, '\0');
1097   return XOBFINISH (&sra_obstack, char *);
1098 }
1099
1100 /* Instantiate an element as an independent variable.  */
1101
1102 static void
1103 instantiate_element (struct sra_elt *elt)
1104 {
1105   struct sra_elt *base_elt;
1106   tree var, base;
1107
1108   for (base_elt = elt; base_elt->parent; base_elt = base_elt->parent)
1109     continue;
1110   base = base_elt->element;
1111
1112   elt->replacement = var = make_rename_temp (elt->type, "SR");
1113   DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (base);
1114   DECL_ARTIFICIAL (var) = 1;
1115
1116   if (TREE_THIS_VOLATILE (elt->type))
1117     {
1118       TREE_THIS_VOLATILE (var) = 1;
1119       TREE_SIDE_EFFECTS (var) = 1;
1120     }
1121
1122   if (DECL_NAME (base) && !DECL_IGNORED_P (base))
1123     {
1124       char *pretty_name = build_element_name (elt);
1125       DECL_NAME (var) = get_identifier (pretty_name);
1126       obstack_free (&sra_obstack, pretty_name);
1127
1128       SET_DECL_DEBUG_EXPR (var, generate_element_ref (elt));
1129       DECL_DEBUG_EXPR_IS_FROM (var) = 1;
1130       
1131       DECL_IGNORED_P (var) = 0;
1132       TREE_NO_WARNING (var) = TREE_NO_WARNING (base);
1133     }
1134   else
1135     {
1136       DECL_IGNORED_P (var) = 1;
1137       /* ??? We can't generate any warning that would be meaningful.  */
1138       TREE_NO_WARNING (var) = 1;
1139     }
1140
1141   if (dump_file)
1142     {
1143       fputs ("  ", dump_file);
1144       dump_sra_elt_name (dump_file, elt);
1145       fputs (" -> ", dump_file);
1146       print_generic_expr (dump_file, var, dump_flags);
1147       fputc ('\n', dump_file);
1148     }
1149 }
1150
1151 /* Make one pass across an element tree deciding whether or not it's
1152    profitable to instantiate individual leaf scalars.
1153
1154    PARENT_USES and PARENT_COPIES are the sum of the N_USES and N_COPIES
1155    fields all the way up the tree.  */
1156
1157 static void
1158 decide_instantiation_1 (struct sra_elt *elt, unsigned int parent_uses,
1159                         unsigned int parent_copies)
1160 {
1161   if (dump_file && !elt->parent)
1162     {
1163       fputs ("Initial instantiation for ", dump_file);
1164       dump_sra_elt_name (dump_file, elt);
1165       fputc ('\n', dump_file);
1166     }
1167
1168   if (elt->cannot_scalarize)
1169     return;
1170
1171   if (elt->is_scalar)
1172     {
1173       /* The decision is simple: instantiate if we're used more frequently
1174          than the parent needs to be seen as a complete unit.  */
1175       if (elt->n_uses + elt->n_copies + parent_copies > parent_uses)
1176         instantiate_element (elt);
1177     }
1178   else
1179     {
1180       struct sra_elt *c;
1181       unsigned int this_uses = elt->n_uses + parent_uses;
1182       unsigned int this_copies = elt->n_copies + parent_copies;
1183
1184       for (c = elt->children; c ; c = c->sibling)
1185         decide_instantiation_1 (c, this_uses, this_copies);
1186     }
1187 }
1188
1189 /* Compute the size and number of all instantiated elements below ELT.
1190    We will only care about this if the size of the complete structure
1191    fits in a HOST_WIDE_INT, so we don't have to worry about overflow.  */
1192
1193 static unsigned int
1194 sum_instantiated_sizes (struct sra_elt *elt, unsigned HOST_WIDE_INT *sizep)
1195 {
1196   if (elt->replacement)
1197     {
1198       *sizep += TREE_INT_CST_LOW (TYPE_SIZE_UNIT (elt->type));
1199       return 1;
1200     }
1201   else
1202     {
1203       struct sra_elt *c;
1204       unsigned int count = 0;
1205
1206       for (c = elt->children; c ; c = c->sibling)
1207         count += sum_instantiated_sizes (c, sizep);
1208
1209       return count;
1210     }
1211 }
1212
1213 /* Instantiate fields in ELT->TYPE that are not currently present as
1214    children of ELT.  */
1215
1216 static void instantiate_missing_elements (struct sra_elt *elt);
1217
1218 static void
1219 instantiate_missing_elements_1 (struct sra_elt *elt, tree child, tree type)
1220 {
1221   struct sra_elt *sub = lookup_element (elt, child, type, INSERT);
1222   if (sub->is_scalar)
1223     {
1224       if (sub->replacement == NULL)
1225         instantiate_element (sub);
1226     }
1227   else
1228     instantiate_missing_elements (sub);
1229 }
1230
1231 static void
1232 instantiate_missing_elements (struct sra_elt *elt)
1233 {
1234   tree type = elt->type;
1235
1236   switch (TREE_CODE (type))
1237     {
1238     case RECORD_TYPE:
1239       {
1240         tree f;
1241         for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
1242           if (TREE_CODE (f) == FIELD_DECL)
1243             instantiate_missing_elements_1 (elt, f, TREE_TYPE (f));
1244         break;
1245       }
1246
1247     case ARRAY_TYPE:
1248       {
1249         tree i, max, subtype;
1250
1251         i = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
1252         max = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
1253         subtype = TREE_TYPE (type);
1254
1255         while (1)
1256           {
1257             instantiate_missing_elements_1 (elt, i, subtype);
1258             if (tree_int_cst_equal (i, max))
1259               break;
1260             i = int_const_binop (PLUS_EXPR, i, integer_one_node, true);
1261           }
1262
1263         break;
1264       }
1265
1266     case COMPLEX_TYPE:
1267       type = TREE_TYPE (type);
1268       instantiate_missing_elements_1 (elt, integer_zero_node, type);
1269       instantiate_missing_elements_1 (elt, integer_one_node, type);
1270       break;
1271
1272     default:
1273       gcc_unreachable ();
1274     }
1275 }
1276
1277 /* Make one pass across an element tree deciding whether to perform block
1278    or element copies.  If we decide on element copies, instantiate all
1279    elements.  Return true if there are any instantiated sub-elements.  */
1280
1281 static bool
1282 decide_block_copy (struct sra_elt *elt)
1283 {
1284   struct sra_elt *c;
1285   bool any_inst;
1286
1287   /* If scalarization is disabled, respect it.  */
1288   if (elt->cannot_scalarize)
1289     {
1290       elt->use_block_copy = 1;
1291
1292       if (dump_file)
1293         {
1294           fputs ("Scalarization disabled for ", dump_file);
1295           dump_sra_elt_name (dump_file, elt);
1296           fputc ('\n', dump_file);
1297         }
1298
1299       /* Disable scalarization of sub-elements */
1300       for (c = elt->children; c; c = c->sibling)
1301         {
1302           c->cannot_scalarize = 1;
1303           decide_block_copy (c);
1304         }
1305       return false;
1306     }
1307
1308   /* Don't decide if we've no uses.  */
1309   if (elt->n_uses == 0 && elt->n_copies == 0)
1310     ;
1311
1312   else if (!elt->is_scalar)
1313     {
1314       tree size_tree = TYPE_SIZE_UNIT (elt->type);
1315       bool use_block_copy = true;
1316
1317       /* Tradeoffs for COMPLEX types pretty much always make it better
1318          to go ahead and split the components.  */
1319       if (TREE_CODE (elt->type) == COMPLEX_TYPE)
1320         use_block_copy = false;
1321
1322       /* Don't bother trying to figure out the rest if the structure is
1323          so large we can't do easy arithmetic.  This also forces block
1324          copies for variable sized structures.  */
1325       else if (host_integerp (size_tree, 1))
1326         {
1327           unsigned HOST_WIDE_INT full_size, inst_size = 0;
1328           unsigned int max_size;
1329
1330           /* If the sra-max-structure-size parameter is 0, then the
1331              user has not overridden the parameter and we can choose a
1332              sensible default.  */
1333           max_size = SRA_MAX_STRUCTURE_SIZE
1334             ? SRA_MAX_STRUCTURE_SIZE
1335             : MOVE_RATIO * UNITS_PER_WORD;
1336
1337           full_size = tree_low_cst (size_tree, 1);
1338
1339           /* ??? What to do here.  If there are two fields, and we've only
1340              instantiated one, then instantiating the other is clearly a win.
1341              If there are a large number of fields then the size of the copy
1342              is much more of a factor.  */
1343
1344           /* If the structure is small, and we've made copies, go ahead
1345              and instantiate, hoping that the copies will go away.  */
1346           if (full_size <= max_size
1347               && elt->n_copies > elt->n_uses)
1348             use_block_copy = false;
1349           else
1350             {
1351               sum_instantiated_sizes (elt, &inst_size);
1352
1353               if (inst_size * 100 >= full_size * SRA_FIELD_STRUCTURE_RATIO)
1354                 use_block_copy = false;
1355             }
1356
1357           /* In order to avoid block copy, we have to be able to instantiate
1358              all elements of the type.  See if this is possible.  */
1359           if (!use_block_copy
1360               && (!can_completely_scalarize_p (elt)
1361                   || !type_can_instantiate_all_elements (elt->type)))
1362             use_block_copy = true;
1363         }
1364       elt->use_block_copy = use_block_copy;
1365
1366       if (dump_file)
1367         {
1368           fprintf (dump_file, "Using %s for ",
1369                    use_block_copy ? "block-copy" : "element-copy");
1370           dump_sra_elt_name (dump_file, elt);
1371           fputc ('\n', dump_file);
1372         }
1373
1374       if (!use_block_copy)
1375         {
1376           instantiate_missing_elements (elt);
1377           return true;
1378         }
1379     }
1380
1381   any_inst = elt->replacement != NULL;
1382
1383   for (c = elt->children; c ; c = c->sibling)
1384     any_inst |= decide_block_copy (c);
1385
1386   return any_inst;
1387 }
1388
1389 /* Entry point to phase 3.  Instantiate scalar replacement variables.  */
1390
1391 static void
1392 decide_instantiations (void)
1393 {
1394   unsigned int i;
1395   bool cleared_any;
1396   bitmap_head done_head;
1397   bitmap_iterator bi;
1398
1399   /* We cannot clear bits from a bitmap we're iterating over,
1400      so save up all the bits to clear until the end.  */
1401   bitmap_initialize (&done_head, &bitmap_default_obstack);
1402   cleared_any = false;
1403
1404   EXECUTE_IF_SET_IN_BITMAP (sra_candidates, 0, i, bi)
1405     {
1406       tree var = referenced_var (i);
1407       struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT);
1408       if (elt)
1409         {
1410           decide_instantiation_1 (elt, 0, 0);
1411           if (!decide_block_copy (elt))
1412             elt = NULL;
1413         }
1414       if (!elt)
1415         {
1416           bitmap_set_bit (&done_head, i);
1417           cleared_any = true;
1418         }
1419     }
1420
1421   if (cleared_any)
1422     {
1423       bitmap_and_compl_into (sra_candidates, &done_head);
1424       bitmap_and_compl_into (needs_copy_in, &done_head);
1425     }
1426   bitmap_clear (&done_head);
1427
1428   mark_set_for_renaming (sra_candidates);
1429
1430   if (dump_file)
1431     fputc ('\n', dump_file);
1432 }
1433
1434 \f
1435 /* Phase Four: Update the function to match the replacements created.  */
1436
1437 /* Mark all the variables in V_MAY_DEF or V_MUST_DEF operands for STMT for
1438    renaming. This becomes necessary when we modify all of a non-scalar.  */
1439
1440 static void
1441 mark_all_v_defs_1 (tree stmt)
1442 {
1443   tree sym;
1444   ssa_op_iter iter;
1445
1446   update_stmt_if_modified (stmt);
1447
1448   FOR_EACH_SSA_TREE_OPERAND (sym, stmt, iter, SSA_OP_ALL_VIRTUALS)
1449     {
1450       if (TREE_CODE (sym) == SSA_NAME)
1451         sym = SSA_NAME_VAR (sym);
1452       mark_sym_for_renaming (sym);
1453     }
1454 }
1455
1456
1457 /* Mark all the variables in virtual operands in all the statements in
1458    LIST for renaming.  */
1459
1460 static void
1461 mark_all_v_defs (tree list)
1462 {
1463   if (TREE_CODE (list) != STATEMENT_LIST)
1464     mark_all_v_defs_1 (list);
1465   else
1466     {
1467       tree_stmt_iterator i;
1468       for (i = tsi_start (list); !tsi_end_p (i); tsi_next (&i))
1469         mark_all_v_defs_1 (tsi_stmt (i));
1470     }
1471 }
1472
1473
1474 /* Build a single level component reference to ELT rooted at BASE.  */
1475
1476 static tree
1477 generate_one_element_ref (struct sra_elt *elt, tree base)
1478 {
1479   switch (TREE_CODE (TREE_TYPE (base)))
1480     {
1481     case RECORD_TYPE:
1482       {
1483         tree field = elt->element;
1484
1485         /* Watch out for compatible records with differing field lists.  */
1486         if (DECL_FIELD_CONTEXT (field) != TYPE_MAIN_VARIANT (TREE_TYPE (base)))
1487           field = find_compatible_field (TREE_TYPE (base), field);
1488
1489         return build (COMPONENT_REF, elt->type, base, field, NULL);
1490       }
1491
1492     case ARRAY_TYPE:
1493       return build (ARRAY_REF, elt->type, base, elt->element, NULL, NULL);
1494
1495     case COMPLEX_TYPE:
1496       if (elt->element == integer_zero_node)
1497         return build (REALPART_EXPR, elt->type, base);
1498       else
1499         return build (IMAGPART_EXPR, elt->type, base);
1500
1501     default:
1502       gcc_unreachable ();
1503     }
1504 }
1505
1506 /* Build a full component reference to ELT rooted at its native variable.  */
1507
1508 static tree
1509 generate_element_ref (struct sra_elt *elt)
1510 {
1511   if (elt->parent)
1512     return generate_one_element_ref (elt, generate_element_ref (elt->parent));
1513   else
1514     return elt->element;
1515 }
1516
1517 /* Generate a set of assignment statements in *LIST_P to copy all
1518    instantiated elements under ELT to or from the equivalent structure
1519    rooted at EXPR.  COPY_OUT controls the direction of the copy, with
1520    true meaning to copy out of EXPR into ELT.  */
1521
1522 static void
1523 generate_copy_inout (struct sra_elt *elt, bool copy_out, tree expr,
1524                      tree *list_p)
1525 {
1526   struct sra_elt *c;
1527   tree t;
1528
1529   if (!copy_out && TREE_CODE (expr) == SSA_NAME
1530       && TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
1531     {
1532       tree r, i;
1533
1534       c = lookup_element (elt, integer_zero_node, NULL, NO_INSERT);
1535       r = c->replacement;
1536       c = lookup_element (elt, integer_one_node, NULL, NO_INSERT);
1537       i = c->replacement;
1538
1539       t = build (COMPLEX_EXPR, elt->type, r, i);
1540       t = build (MODIFY_EXPR, void_type_node, expr, t);
1541       SSA_NAME_DEF_STMT (expr) = t;
1542       append_to_statement_list (t, list_p);
1543     }
1544   else if (elt->replacement)
1545     {
1546       if (copy_out)
1547         t = build (MODIFY_EXPR, void_type_node, elt->replacement, expr);
1548       else
1549         t = build (MODIFY_EXPR, void_type_node, expr, elt->replacement);
1550       append_to_statement_list (t, list_p);
1551     }
1552   else
1553     {
1554       for (c = elt->children; c ; c = c->sibling)
1555         {
1556           t = generate_one_element_ref (c, unshare_expr (expr));
1557           generate_copy_inout (c, copy_out, t, list_p);
1558         }
1559     }
1560 }
1561
1562 /* Generate a set of assignment statements in *LIST_P to copy all instantiated
1563    elements under SRC to their counterparts under DST.  There must be a 1-1
1564    correspondence of instantiated elements.  */
1565
1566 static void
1567 generate_element_copy (struct sra_elt *dst, struct sra_elt *src, tree *list_p)
1568 {
1569   struct sra_elt *dc, *sc;
1570
1571   for (dc = dst->children; dc ; dc = dc->sibling)
1572     {
1573       sc = lookup_element (src, dc->element, NULL, NO_INSERT);
1574       gcc_assert (sc);
1575       generate_element_copy (dc, sc, list_p);
1576     }
1577
1578   if (dst->replacement)
1579     {
1580       tree t;
1581
1582       gcc_assert (src->replacement);
1583
1584       t = build (MODIFY_EXPR, void_type_node, dst->replacement,
1585                  src->replacement);
1586       append_to_statement_list (t, list_p);
1587     }
1588 }
1589
1590 /* Generate a set of assignment statements in *LIST_P to zero all instantiated
1591    elements under ELT.  In addition, do not assign to elements that have been
1592    marked VISITED but do reset the visited flag; this allows easy coordination
1593    with generate_element_init.  */
1594
1595 static void
1596 generate_element_zero (struct sra_elt *elt, tree *list_p)
1597 {
1598   struct sra_elt *c;
1599
1600   if (elt->visited)
1601     {
1602       elt->visited = false;
1603       return;
1604     }
1605
1606   for (c = elt->children; c ; c = c->sibling)
1607     generate_element_zero (c, list_p);
1608
1609   if (elt->replacement)
1610     {
1611       tree t;
1612
1613       gcc_assert (elt->is_scalar);
1614       t = fold_convert (elt->type, integer_zero_node);
1615
1616       t = build (MODIFY_EXPR, void_type_node, elt->replacement, t);
1617       append_to_statement_list (t, list_p);
1618     }
1619 }
1620
1621 /* Generate an assignment VAR = INIT, where INIT may need gimplification.
1622    Add the result to *LIST_P.  */
1623
1624 static void
1625 generate_one_element_init (tree var, tree init, tree *list_p)
1626 {
1627   /* The replacement can be almost arbitrarily complex.  Gimplify.  */
1628   tree stmt = build (MODIFY_EXPR, void_type_node, var, init);
1629   gimplify_and_add (stmt, list_p);
1630 }
1631
1632 /* Generate a set of assignment statements in *LIST_P to set all instantiated
1633    elements under ELT with the contents of the initializer INIT.  In addition,
1634    mark all assigned elements VISITED; this allows easy coordination with
1635    generate_element_zero.  Return false if we found a case we couldn't
1636    handle.  */
1637
1638 static bool
1639 generate_element_init_1 (struct sra_elt *elt, tree init, tree *list_p)
1640 {
1641   bool result = true;
1642   enum tree_code init_code;
1643   struct sra_elt *sub;
1644   tree t;
1645
1646   /* We can be passed DECL_INITIAL of a static variable.  It might have a
1647      conversion, which we strip off here.  */
1648   STRIP_USELESS_TYPE_CONVERSION (init);
1649   init_code = TREE_CODE (init);
1650
1651   if (elt->is_scalar)
1652     {
1653       if (elt->replacement)
1654         {
1655           generate_one_element_init (elt->replacement, init, list_p);
1656           elt->visited = true;
1657         }
1658       return result;
1659     }
1660
1661   switch (init_code)
1662     {
1663     case COMPLEX_CST:
1664     case COMPLEX_EXPR:
1665       for (sub = elt->children; sub ; sub = sub->sibling)
1666         {
1667           if (sub->element == integer_zero_node)
1668             t = (init_code == COMPLEX_EXPR
1669                  ? TREE_OPERAND (init, 0) : TREE_REALPART (init));
1670           else
1671             t = (init_code == COMPLEX_EXPR
1672                  ? TREE_OPERAND (init, 1) : TREE_IMAGPART (init));
1673           result &= generate_element_init_1 (sub, t, list_p);
1674         }
1675       break;
1676
1677     case CONSTRUCTOR:
1678       for (t = CONSTRUCTOR_ELTS (init); t ; t = TREE_CHAIN (t))
1679         {
1680           tree purpose = TREE_PURPOSE (t);
1681           tree value = TREE_VALUE (t);
1682
1683           if (TREE_CODE (purpose) == RANGE_EXPR)
1684             {
1685               tree lower = TREE_OPERAND (purpose, 0);
1686               tree upper = TREE_OPERAND (purpose, 1);
1687
1688               while (1)
1689                 {
1690                   sub = lookup_element (elt, lower, NULL, NO_INSERT);
1691                   if (sub != NULL)
1692                     result &= generate_element_init_1 (sub, value, list_p);
1693                   if (tree_int_cst_equal (lower, upper))
1694                     break;
1695                   lower = int_const_binop (PLUS_EXPR, lower,
1696                                            integer_one_node, true);
1697                 }
1698             }
1699           else
1700             {
1701               sub = lookup_element (elt, purpose, NULL, NO_INSERT);
1702               if (sub != NULL)
1703                 result &= generate_element_init_1 (sub, value, list_p);
1704             }
1705         }
1706       break;
1707
1708     default:
1709       elt->visited = true;
1710       result = false;
1711     }
1712
1713   return result;
1714 }
1715
1716 /* A wrapper function for generate_element_init_1 that handles cleanup after
1717    gimplification.  */
1718
1719 static bool
1720 generate_element_init (struct sra_elt *elt, tree init, tree *list_p)
1721 {
1722   bool ret;
1723
1724   push_gimplify_context ();
1725   ret = generate_element_init_1 (elt, init, list_p);
1726   pop_gimplify_context (NULL);
1727
1728   /* The replacement can expose previously unreferenced variables.  */
1729   if (ret && *list_p)
1730     {
1731       tree_stmt_iterator i;
1732       size_t old, new, j;
1733
1734       old = num_referenced_vars;
1735
1736       for (i = tsi_start (*list_p); !tsi_end_p (i); tsi_next (&i))
1737         find_new_referenced_vars (tsi_stmt_ptr (i));
1738
1739       new = num_referenced_vars;
1740       for (j = old; j < new; ++j)
1741         mark_sym_for_renaming (referenced_var (j));
1742     }
1743
1744   return ret;
1745 }
1746
1747 /* Insert STMT on all the outgoing edges out of BB.  Note that if BB
1748    has more than one edge, STMT will be replicated for each edge.  Also,
1749    abnormal edges will be ignored.  */
1750
1751 void
1752 insert_edge_copies (tree stmt, basic_block bb)
1753 {
1754   edge e;
1755   edge_iterator ei;
1756   bool first_copy;
1757
1758   first_copy = true;
1759   FOR_EACH_EDGE (e, ei, bb->succs)
1760     {
1761       /* We don't need to insert copies on abnormal edges.  The
1762          value of the scalar replacement is not guaranteed to
1763          be valid through an abnormal edge.  */
1764       if (!(e->flags & EDGE_ABNORMAL))
1765         {
1766           if (first_copy)
1767             {
1768               bsi_insert_on_edge (e, stmt);
1769               first_copy = false;
1770             }
1771           else
1772             bsi_insert_on_edge (e, unsave_expr_now (stmt));
1773         }
1774     }
1775 }
1776
1777 /* Helper function to insert LIST before BSI, and set up line number info.  */
1778
1779 static void
1780 sra_insert_before (block_stmt_iterator *bsi, tree list)
1781 {
1782   tree stmt = bsi_stmt (*bsi);
1783
1784   if (EXPR_HAS_LOCATION (stmt))
1785     annotate_all_with_locus (&list, EXPR_LOCATION (stmt));
1786   bsi_insert_before (bsi, list, BSI_SAME_STMT);
1787 }
1788
1789 /* Similarly, but insert after BSI.  Handles insertion onto edges as well.  */
1790
1791 static void
1792 sra_insert_after (block_stmt_iterator *bsi, tree list)
1793 {
1794   tree stmt = bsi_stmt (*bsi);
1795
1796   if (EXPR_HAS_LOCATION (stmt))
1797     annotate_all_with_locus (&list, EXPR_LOCATION (stmt));
1798
1799   if (stmt_ends_bb_p (stmt))
1800     insert_edge_copies (list, bsi->bb);
1801   else
1802     bsi_insert_after (bsi, list, BSI_SAME_STMT);
1803 }
1804
1805 /* Similarly, but replace the statement at BSI.  */
1806
1807 static void
1808 sra_replace (block_stmt_iterator *bsi, tree list)
1809 {
1810   sra_insert_before (bsi, list);
1811   bsi_remove (bsi);
1812   if (bsi_end_p (*bsi))
1813     *bsi = bsi_last (bsi->bb);
1814   else
1815     bsi_prev (bsi);
1816 }
1817
1818 /* Scalarize a USE.  To recap, this is either a simple reference to ELT,
1819    if elt is scalar, or some occurrence of ELT that requires a complete
1820    aggregate.  IS_OUTPUT is true if ELT is being modified.  */
1821
1822 static void
1823 scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi,
1824                bool is_output)
1825 {
1826   tree list = NULL, stmt = bsi_stmt (*bsi);
1827
1828   if (elt->replacement)
1829     {
1830       /* If we have a replacement, then updating the reference is as
1831          simple as modifying the existing statement in place.  */
1832       if (is_output)
1833         mark_all_v_defs (stmt);
1834       *expr_p = elt->replacement;
1835       update_stmt (stmt);
1836     }
1837   else
1838     {
1839       /* Otherwise we need some copies.  If ELT is being read, then we want
1840          to store all (modified) sub-elements back into the structure before
1841          the reference takes place.  If ELT is being written, then we want to
1842          load the changed values back into our shadow variables.  */
1843       /* ??? We don't check modified for reads, we just always write all of
1844          the values.  We should be able to record the SSA number of the VOP
1845          for which the values were last read.  If that number matches the
1846          SSA number of the VOP in the current statement, then we needn't
1847          emit an assignment.  This would also eliminate double writes when
1848          a structure is passed as more than one argument to a function call.
1849          This optimization would be most effective if sra_walk_function
1850          processed the blocks in dominator order.  */
1851
1852       generate_copy_inout (elt, is_output, generate_element_ref (elt), &list);
1853       if (list == NULL)
1854         return;
1855       mark_all_v_defs (list);
1856       if (is_output)
1857         sra_insert_after (bsi, list);
1858       else
1859         sra_insert_before (bsi, list);
1860     }
1861 }
1862
1863 /* Scalarize a COPY.  To recap, this is an assignment statement between
1864    two scalarizable references, LHS_ELT and RHS_ELT.  */
1865
1866 static void
1867 scalarize_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
1868                 block_stmt_iterator *bsi)
1869 {
1870   tree list, stmt;
1871
1872   if (lhs_elt->replacement && rhs_elt->replacement)
1873     {
1874       /* If we have two scalar operands, modify the existing statement.  */
1875       stmt = bsi_stmt (*bsi);
1876
1877       /* See the commentary in sra_walk_function concerning
1878          RETURN_EXPR, and why we should never see one here.  */
1879       gcc_assert (TREE_CODE (stmt) == MODIFY_EXPR);
1880
1881       TREE_OPERAND (stmt, 0) = lhs_elt->replacement;
1882       TREE_OPERAND (stmt, 1) = rhs_elt->replacement;
1883       update_stmt (stmt);
1884     }
1885   else if (lhs_elt->use_block_copy || rhs_elt->use_block_copy)
1886     {
1887       /* If either side requires a block copy, then sync the RHS back
1888          to the original structure, leave the original assignment
1889          statement (which will perform the block copy), then load the
1890          LHS values out of its now-updated original structure.  */
1891       /* ??? Could perform a modified pair-wise element copy.  That
1892          would at least allow those elements that are instantiated in
1893          both structures to be optimized well.  */
1894
1895       list = NULL;
1896       generate_copy_inout (rhs_elt, false,
1897                            generate_element_ref (rhs_elt), &list);
1898       if (list)
1899         {
1900           mark_all_v_defs (list);
1901           sra_insert_before (bsi, list);
1902         }
1903
1904       list = NULL;
1905       generate_copy_inout (lhs_elt, true,
1906                            generate_element_ref (lhs_elt), &list);
1907       if (list)
1908         {
1909           mark_all_v_defs (list);
1910           sra_insert_after (bsi, list);
1911         }
1912     }
1913   else
1914     {
1915       /* Otherwise both sides must be fully instantiated.  In which
1916          case perform pair-wise element assignments and replace the
1917          original block copy statement.  */
1918
1919       stmt = bsi_stmt (*bsi);
1920       mark_all_v_defs (stmt);
1921
1922       list = NULL;
1923       generate_element_copy (lhs_elt, rhs_elt, &list);
1924       gcc_assert (list);
1925       mark_all_v_defs (list);
1926       sra_replace (bsi, list);
1927     }
1928 }
1929
1930 /* Scalarize an INIT.  To recap, this is an assignment to a scalarizable
1931    reference from some form of constructor: CONSTRUCTOR, COMPLEX_CST or
1932    COMPLEX_EXPR.  If RHS is NULL, it should be treated as an empty
1933    CONSTRUCTOR.  */
1934
1935 static void
1936 scalarize_init (struct sra_elt *lhs_elt, tree rhs, block_stmt_iterator *bsi)
1937 {
1938   bool result = true;
1939   tree list = NULL;
1940
1941   /* Generate initialization statements for all members extant in the RHS.  */
1942   if (rhs)
1943     {
1944       /* Unshare the expression just in case this is from a decl's initial.  */
1945       rhs = unshare_expr (rhs);
1946       result = generate_element_init (lhs_elt, rhs, &list);
1947     }
1948
1949   /* CONSTRUCTOR is defined such that any member not mentioned is assigned
1950      a zero value.  Initialize the rest of the instantiated elements.  */
1951   generate_element_zero (lhs_elt, &list);
1952
1953   if (!result)
1954     {
1955       /* If we failed to convert the entire initializer, then we must
1956          leave the structure assignment in place and must load values
1957          from the structure into the slots for which we did not find
1958          constants.  The easiest way to do this is to generate a complete
1959          copy-out, and then follow that with the constant assignments
1960          that we were able to build.  DCE will clean things up.  */
1961       tree list0 = NULL;
1962       generate_copy_inout (lhs_elt, true, generate_element_ref (lhs_elt),
1963                            &list0);
1964       append_to_statement_list (list, &list0);
1965       list = list0;
1966     }
1967
1968   if (lhs_elt->use_block_copy || !result)
1969     {
1970       /* Since LHS is not fully instantiated, we must leave the structure
1971          assignment in place.  Treating this case differently from a USE
1972          exposes constants to later optimizations.  */
1973       if (list)
1974         {
1975           mark_all_v_defs (list);
1976           sra_insert_after (bsi, list);
1977         }
1978     }
1979   else
1980     {
1981       /* The LHS is fully instantiated.  The list of initializations
1982          replaces the original structure assignment.  */
1983       gcc_assert (list);
1984       mark_all_v_defs (bsi_stmt (*bsi));
1985       mark_all_v_defs (list);
1986       sra_replace (bsi, list);
1987     }
1988 }
1989
1990 /* A subroutine of scalarize_ldst called via walk_tree.  Set TREE_NO_TRAP
1991    on all INDIRECT_REFs.  */
1992
1993 static tree
1994 mark_notrap (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1995 {
1996   tree t = *tp;
1997
1998   if (TREE_CODE (t) == INDIRECT_REF)
1999     {
2000       TREE_THIS_NOTRAP (t) = 1;
2001       *walk_subtrees = 0;
2002     }
2003   else if (IS_TYPE_OR_DECL_P (t))
2004     *walk_subtrees = 0;
2005
2006   return NULL;
2007 }
2008
2009 /* Scalarize a LDST.  To recap, this is an assignment between one scalarizable
2010    reference ELT and one non-scalarizable reference OTHER.  IS_OUTPUT is true
2011    if ELT is on the left-hand side.  */
2012
2013 static void
2014 scalarize_ldst (struct sra_elt *elt, tree other,
2015                 block_stmt_iterator *bsi, bool is_output)
2016 {
2017   /* Shouldn't have gotten called for a scalar.  */
2018   gcc_assert (!elt->replacement);
2019
2020   if (elt->use_block_copy)
2021     {
2022       /* Since ELT is not fully instantiated, we have to leave the
2023          block copy in place.  Treat this as a USE.  */
2024       scalarize_use (elt, NULL, bsi, is_output);
2025     }
2026   else
2027     {
2028       /* The interesting case is when ELT is fully instantiated.  In this
2029          case we can have each element stored/loaded directly to/from the
2030          corresponding slot in OTHER.  This avoids a block copy.  */
2031
2032       tree list = NULL, stmt = bsi_stmt (*bsi);
2033
2034       mark_all_v_defs (stmt);
2035       generate_copy_inout (elt, is_output, other, &list);
2036       mark_all_v_defs (list);
2037       gcc_assert (list);
2038
2039       /* Preserve EH semantics.  */
2040       if (stmt_ends_bb_p (stmt))
2041         {
2042           tree_stmt_iterator tsi;
2043           tree first;
2044
2045           /* Extract the first statement from LIST.  */
2046           tsi = tsi_start (list);
2047           first = tsi_stmt (tsi);
2048           tsi_delink (&tsi);
2049
2050           /* Replace the old statement with this new representative.  */
2051           bsi_replace (bsi, first, true);
2052
2053           if (!tsi_end_p (tsi))
2054             {
2055               /* If any reference would trap, then they all would.  And more
2056                  to the point, the first would.  Therefore none of the rest
2057                  will trap since the first didn't.  Indicate this by
2058                  iterating over the remaining statements and set
2059                  TREE_THIS_NOTRAP in all INDIRECT_REFs.  */
2060               do
2061                 {
2062                   walk_tree (tsi_stmt_ptr (tsi), mark_notrap, NULL, NULL);
2063                   tsi_next (&tsi);
2064                 }
2065               while (!tsi_end_p (tsi));
2066
2067               insert_edge_copies (list, bsi->bb);
2068             }
2069         }
2070       else
2071         sra_replace (bsi, list);
2072     }
2073 }
2074
2075 /* Generate initializations for all scalarizable parameters.  */
2076
2077 static void
2078 scalarize_parms (void)
2079 {
2080   tree list = NULL;
2081   unsigned i;
2082   bitmap_iterator bi;
2083
2084   EXECUTE_IF_SET_IN_BITMAP (needs_copy_in, 0, i, bi)
2085     {
2086       tree var = referenced_var (i);
2087       struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT);
2088       generate_copy_inout (elt, true, var, &list);
2089     }
2090
2091   if (list)
2092     {
2093       insert_edge_copies (list, ENTRY_BLOCK_PTR);
2094       mark_all_v_defs (list);
2095     }
2096 }
2097
2098 /* Entry point to phase 4.  Update the function to match replacements.  */
2099
2100 static void
2101 scalarize_function (void)
2102 {
2103   static const struct sra_walk_fns fns = {
2104     scalarize_use, scalarize_copy, scalarize_init, scalarize_ldst, false
2105   };
2106
2107   sra_walk_function (&fns);
2108   scalarize_parms ();
2109   bsi_commit_edge_inserts ();
2110 }
2111
2112 \f
2113 /* Debug helper function.  Print ELT in a nice human-readable format.  */
2114
2115 static void
2116 dump_sra_elt_name (FILE *f, struct sra_elt *elt)
2117 {
2118   if (elt->parent && TREE_CODE (elt->parent->type) == COMPLEX_TYPE)
2119     {
2120       fputs (elt->element == integer_zero_node ? "__real__ " : "__imag__ ", f);
2121       dump_sra_elt_name (f, elt->parent);
2122     }
2123   else
2124     {
2125       if (elt->parent)
2126         dump_sra_elt_name (f, elt->parent);
2127       if (DECL_P (elt->element))
2128         {
2129           if (TREE_CODE (elt->element) == FIELD_DECL)
2130             fputc ('.', f);
2131           print_generic_expr (f, elt->element, dump_flags);
2132         }
2133       else
2134         fprintf (f, "[" HOST_WIDE_INT_PRINT_DEC "]",
2135                  TREE_INT_CST_LOW (elt->element));
2136     }
2137 }
2138
2139 /* Likewise, but callable from the debugger.  */
2140
2141 void
2142 debug_sra_elt_name (struct sra_elt *elt)
2143 {
2144   dump_sra_elt_name (stderr, elt);
2145   fputc ('\n', stderr);
2146 }
2147
2148 /* Main entry point.  */
2149
2150 static void
2151 tree_sra (void)
2152 {
2153   /* Initialize local variables.  */
2154   gcc_obstack_init (&sra_obstack);
2155   sra_candidates = BITMAP_ALLOC (NULL);
2156   needs_copy_in = BITMAP_ALLOC (NULL);
2157   sra_type_decomp_cache = BITMAP_ALLOC (NULL);
2158   sra_type_inst_cache = BITMAP_ALLOC (NULL);
2159   sra_map = htab_create (101, sra_elt_hash, sra_elt_eq, NULL);
2160
2161   /* Scan.  If we find anything, instantiate and scalarize.  */
2162   if (find_candidates_for_sra ())
2163     {
2164       scan_function ();
2165       decide_instantiations ();
2166       scalarize_function ();
2167     }
2168
2169   /* Free allocated memory.  */
2170   htab_delete (sra_map);
2171   sra_map = NULL;
2172   BITMAP_FREE (sra_candidates);
2173   BITMAP_FREE (needs_copy_in);
2174   BITMAP_FREE (sra_type_decomp_cache);
2175   BITMAP_FREE (sra_type_inst_cache);
2176   obstack_free (&sra_obstack, NULL);
2177 }
2178
2179 static bool
2180 gate_sra (void)
2181 {
2182   return flag_tree_sra != 0;
2183 }
2184
2185 struct tree_opt_pass pass_sra =
2186 {
2187   "sra",                                /* name */
2188   gate_sra,                             /* gate */
2189   tree_sra,                             /* execute */
2190   NULL,                                 /* sub */
2191   NULL,                                 /* next */
2192   0,                                    /* static_pass_number */
2193   TV_TREE_SRA,                          /* tv_id */
2194   PROP_cfg | PROP_ssa | PROP_alias,     /* properties_required */
2195   0,                                    /* properties_provided */
2196   0,                                    /* properties_destroyed */
2197   0,                                    /* todo_flags_start */
2198   TODO_dump_func | TODO_update_ssa
2199     | TODO_ggc_collect | TODO_verify_ssa,  /* todo_flags_finish */
2200   0                                     /* letter */
2201 };