OSDN Git Service

PR c++/40373
[pf3gnuchains/gcc-fork.git] / gcc / tree-sra.c
1 /* Scalar Replacement of Aggregates (SRA) converts some structure
2    references into scalar references, exposing them to the scalar
3    optimizers.
4    Copyright (C) 2008, 2009 Free Software Foundation, Inc.
5    Contributed by Martin Jambor <mjambor@suse.cz>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23 /* This file implements Scalar Reduction of Aggregates (SRA).  SRA is run
24    twice, once in the early stages of compilation (early SRA) and once in the
25    late stages (late SRA).  The aim of both is to turn references to scalar
26    parts of aggregates into uses of independent scalar variables.
27
28    The two passes are nearly identical, the only difference is that early SRA
29    does not scalarize unions which are used as the result in a GIMPLE_RETURN
30    statement because together with inlining this can lead to weird type
31    conversions.
32
33    Both passes operate in four stages:
34
35    1. The declarations that have properties which make them candidates for
36       scalarization are identified in function find_var_candidates().  The
37       candidates are stored in candidate_bitmap.
38
39    2. The function body is scanned.  In the process, declarations which are
40       used in a manner that prevent their scalarization are removed from the
41       candidate bitmap.  More importantly, for every access into an aggregate,
42       an access structure (struct access) is created by create_access() and
43       stored in a vector associated with the aggregate.  Among other
44       information, the aggregate declaration, the offset and size of the access
45       and its type are stored in the structure.
46
47       On a related note, assign_link structures are created for every assign
48       statement between candidate aggregates and attached to the related
49       accesses.
50
51    3. The vectors of accesses are analyzed.  They are first sorted according to
52       their offset and size and then scanned for partially overlapping accesses
53       (i.e. those which overlap but one is not entirely within another).  Such
54       an access disqualifies the whole aggregate from being scalarized.
55
56       If there is no such inhibiting overlap, a representative access structure
57       is chosen for every unique combination of offset and size.  Afterwards,
58       the pass builds a set of trees from these structures, in which children
59       of an access are within their parent (in terms of offset and size).
60
61       Then accesses  are propagated  whenever possible (i.e.  in cases  when it
62       does not create a partially overlapping access) across assign_links from
63       the right hand side to the left hand side.
64
65       Then the set of trees for each declaration is traversed again and those
66       accesses which should be replaced by a scalar are identified.
67
68    4. The function is traversed again, and for every reference into an
69       aggregate that has some component which is about to be scalarized,
70       statements are amended and new statements are created as necessary.
71       Finally, if a parameter got scalarized, the scalar replacements are
72       initialized with values from respective parameter aggregates.  */
73
74 #include "config.h"
75 #include "system.h"
76 #include "coretypes.h"
77 #include "alloc-pool.h"
78 #include "tm.h"
79 #include "tree.h"
80 #include "gimple.h"
81 #include "tree-flow.h"
82 #include "diagnostic.h"
83 #include "tree-dump.h"
84 #include "timevar.h"
85 #include "params.h"
86 #include "target.h"
87 #include "flags.h"
88
89 /* Enumeration of all aggregate reductions we can do.  */
90 enum sra_mode { SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
91                 SRA_MODE_INTRA };            /* late intraprocedural SRA */
92
93 /* Global variable describing which aggregate reduction we are performing at
94    the moment.  */
95 static enum sra_mode sra_mode;
96
97 struct assign_link;
98
99 /* ACCESS represents each access to an aggregate variable (as a whole or a
100    part).  It can also represent a group of accesses that refer to exactly the
101    same fragment of an aggregate (i.e. those that have exactly the same offset
102    and size).  Such representatives for a single aggregate, once determined,
103    are linked in a linked list and have the group fields set.
104
105    Moreover, when doing intraprocedural SRA, a tree is built from those
106    representatives (by the means of first_child and next_sibling pointers), in
107    which all items in a subtree are "within" the root, i.e. their offset is
108    greater or equal to offset of the root and offset+size is smaller or equal
109    to offset+size of the root.  Children of an access are sorted by offset.
110
111    Note that accesses to parts of vector and complex number types always
112    represented by an access to the whole complex number or a vector.  It is a
113    duty of the modifying functions to replace them appropriately.  */
114
115 struct access
116 {
117   /* Values returned by  `get_ref_base_and_extent' for each component reference
118      If EXPR isn't a component reference  just set `BASE = EXPR', `OFFSET = 0',
119      `SIZE = TREE_SIZE (TREE_TYPE (expr))'.  */
120   HOST_WIDE_INT offset;
121   HOST_WIDE_INT size;
122   tree base;
123
124   /* Expression.  */
125   tree expr;
126   /* Type.  */
127   tree type;
128
129   /* Next group representative for this aggregate. */
130   struct access *next_grp;
131
132   /* Pointer to the group representative.  Pointer to itself if the struct is
133      the representative.  */
134   struct access *group_representative;
135
136   /* If this access has any children (in terms of the definition above), this
137      points to the first one.  */
138   struct access *first_child;
139
140   /* Pointer to the next sibling in the access tree as described above.  */
141   struct access *next_sibling;
142
143   /* Pointers to the first and last element in the linked list of assign
144      links.  */
145   struct assign_link *first_link, *last_link;
146
147   /* Pointer to the next access in the work queue.  */
148   struct access *next_queued;
149
150   /* Replacement variable for this access "region."  Never to be accessed
151      directly, always only by the means of get_access_replacement() and only
152      when grp_to_be_replaced flag is set.  */
153   tree replacement_decl;
154
155   /* Is this particular access write access? */
156   unsigned write : 1;
157
158   /* Is this access currently in the work queue?  */
159   unsigned grp_queued : 1;
160   /* Does this group contain a write access?  This flag is propagated down the
161      access tree.  */
162   unsigned grp_write : 1;
163   /* Does this group contain a read access?  This flag is propagated down the
164      access tree.  */
165   unsigned grp_read : 1;
166   /* Is the subtree rooted in this access fully covered by scalar
167      replacements?  */
168   unsigned grp_covered : 1;
169   /* If set to true, this access and all below it in an access tree must not be
170      scalarized.  */
171   unsigned grp_unscalarizable_region : 1;
172   /* Whether data have been written to parts of the aggregate covered by this
173      access which is not to be scalarized.  This flag is propagated up in the
174      access tree.  */
175   unsigned grp_unscalarized_data : 1;
176   /* Does this access and/or group contain a write access through a
177      BIT_FIELD_REF?  */
178   unsigned grp_partial_lhs : 1;
179
180   /* Set when a scalar replacement should be created for this variable.  We do
181      the decision and creation at different places because create_tmp_var
182      cannot be called from within FOR_EACH_REFERENCED_VAR. */
183   unsigned grp_to_be_replaced : 1;
184 };
185
186 typedef struct access *access_p;
187
188 DEF_VEC_P (access_p);
189 DEF_VEC_ALLOC_P (access_p, heap);
190
191 /* Alloc pool for allocating access structures.  */
192 static alloc_pool access_pool;
193
194 /* A structure linking lhs and rhs accesses from an aggregate assignment.  They
195    are used to propagate subaccesses from rhs to lhs as long as they don't
196    conflict with what is already there.  */
197 struct assign_link
198 {
199   struct access *lacc, *racc;
200   struct assign_link *next;
201 };
202
203 /* Alloc pool for allocating assign link structures.  */
204 static alloc_pool link_pool;
205
206 /* Base (tree) -> Vector (VEC(access_p,heap) *) map.  */
207 static struct pointer_map_t *base_access_vec;
208
209 /* Bitmap of bases (candidates).  */
210 static bitmap candidate_bitmap;
211 /* Obstack for creation of fancy names.  */
212 static struct obstack name_obstack;
213
214 /* Head of a linked list of accesses that need to have its subaccesses
215    propagated to their assignment counterparts. */
216 static struct access *work_queue_head;
217
218 /* Dump contents of ACCESS to file F in a human friendly way.  If GRP is true,
219    representative fields are dumped, otherwise those which only describe the
220    individual access are.  */
221
222 static void
223 dump_access (FILE *f, struct access *access, bool grp)
224 {
225   fprintf (f, "access { ");
226   fprintf (f, "base = (%d)'", DECL_UID (access->base));
227   print_generic_expr (f, access->base, 0);
228   fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
229   fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
230   fprintf (f, ", expr = ");
231   print_generic_expr (f, access->expr, 0);
232   fprintf (f, ", type = ");
233   print_generic_expr (f, access->type, 0);
234   if (grp)
235     fprintf (f, ", grp_write = %d, grp_read = %d, grp_covered = %d, "
236              "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
237              "grp_partial_lhs = %d, grp_to_be_replaced = %d\n",
238              access->grp_write, access->grp_read, access->grp_covered,
239              access->grp_unscalarizable_region, access->grp_unscalarized_data,
240              access->grp_partial_lhs, access->grp_to_be_replaced);
241   else
242     fprintf (f, ", write = %d, grp_partial_lhs = %d\n", access->write,
243              access->grp_partial_lhs);
244 }
245
246 /* Dump a subtree rooted in ACCESS to file F, indent by LEVEL.  */
247
248 static void
249 dump_access_tree_1 (FILE *f, struct access *access, int level)
250 {
251   do
252     {
253       int i;
254
255       for (i = 0; i < level; i++)
256         fputs ("* ", dump_file);
257
258       dump_access (f, access, true);
259
260       if (access->first_child)
261         dump_access_tree_1 (f, access->first_child, level + 1);
262
263       access = access->next_sibling;
264     }
265   while (access);
266 }
267
268 /* Dump all access trees for a variable, given the pointer to the first root in
269    ACCESS.  */
270
271 static void
272 dump_access_tree (FILE *f, struct access *access)
273 {
274   for (; access; access = access->next_grp)
275     dump_access_tree_1 (f, access, 0);
276 }
277
278 /* Return true iff ACC is non-NULL and has subaccesses.  */
279
280 static inline bool
281 access_has_children_p (struct access *acc)
282 {
283   return acc && acc->first_child;
284 }
285
286 /* Return a vector of pointers to accesses for the variable given in BASE or
287    NULL if there is none.  */
288
289 static VEC (access_p, heap) *
290 get_base_access_vector (tree base)
291 {
292   void **slot;
293
294   slot = pointer_map_contains (base_access_vec, base);
295   if (!slot)
296     return NULL;
297   else
298     return *(VEC (access_p, heap) **) slot;
299 }
300
301 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
302    in ACCESS.  Return NULL if it cannot be found.  */
303
304 static struct access *
305 find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
306                         HOST_WIDE_INT size)
307 {
308   while (access && (access->offset != offset || access->size != size))
309     {
310       struct access *child = access->first_child;
311
312       while (child && (child->offset + child->size <= offset))
313         child = child->next_sibling;
314       access = child;
315     }
316
317   return access;
318 }
319
320 /* Return the first group representative for DECL or NULL if none exists.  */
321
322 static struct access *
323 get_first_repr_for_decl (tree base)
324 {
325   VEC (access_p, heap) *access_vec;
326
327   access_vec = get_base_access_vector (base);
328   if (!access_vec)
329     return NULL;
330
331   return VEC_index (access_p, access_vec, 0);
332 }
333
334 /* Find an access representative for the variable BASE and given OFFSET and
335    SIZE.  Requires that access trees have already been built.  Return NULL if
336    it cannot be found.  */
337
338 static struct access *
339 get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
340                                  HOST_WIDE_INT size)
341 {
342   struct access *access;
343
344   access = get_first_repr_for_decl (base);
345   while (access && (access->offset + access->size <= offset))
346     access = access->next_grp;
347   if (!access)
348     return NULL;
349
350   return find_access_in_subtree (access, offset, size);
351 }
352
353 /* Add LINK to the linked list of assign links of RACC.  */
354 static void
355 add_link_to_rhs (struct access *racc, struct assign_link *link)
356 {
357   gcc_assert (link->racc == racc);
358
359   if (!racc->first_link)
360     {
361       gcc_assert (!racc->last_link);
362       racc->first_link = link;
363     }
364   else
365     racc->last_link->next = link;
366
367   racc->last_link = link;
368   link->next = NULL;
369 }
370
371 /* Move all link structures in their linked list in OLD_RACC to the linked list
372    in NEW_RACC.  */
373 static void
374 relink_to_new_repr (struct access *new_racc, struct access *old_racc)
375 {
376   if (!old_racc->first_link)
377     {
378       gcc_assert (!old_racc->last_link);
379       return;
380     }
381
382   if (new_racc->first_link)
383     {
384       gcc_assert (!new_racc->last_link->next);
385       gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
386
387       new_racc->last_link->next = old_racc->first_link;
388       new_racc->last_link = old_racc->last_link;
389     }
390   else
391     {
392       gcc_assert (!new_racc->last_link);
393
394       new_racc->first_link = old_racc->first_link;
395       new_racc->last_link = old_racc->last_link;
396     }
397   old_racc->first_link = old_racc->last_link = NULL;
398 }
399
400 /* Add ACCESS to the work queue (which is actually a stack).  */
401
402 static void
403 add_access_to_work_queue (struct access *access)
404 {
405   if (!access->grp_queued)
406     {
407       gcc_assert (!access->next_queued);
408       access->next_queued = work_queue_head;
409       access->grp_queued = 1;
410       work_queue_head = access;
411     }
412 }
413
414 /* Pop an access from the work queue, and return it, assuming there is one.  */
415
416 static struct access *
417 pop_access_from_work_queue (void)
418 {
419   struct access *access = work_queue_head;
420
421   work_queue_head = access->next_queued;
422   access->next_queued = NULL;
423   access->grp_queued = 0;
424   return access;
425 }
426
427
428 /* Allocate necessary structures.  */
429
430 static void
431 sra_initialize (void)
432 {
433   candidate_bitmap = BITMAP_ALLOC (NULL);
434   gcc_obstack_init (&name_obstack);
435   access_pool = create_alloc_pool ("SRA accesses", sizeof (struct access), 16);
436   link_pool = create_alloc_pool ("SRA links", sizeof (struct assign_link), 16);
437   base_access_vec = pointer_map_create ();
438 }
439
440 /* Hook fed to pointer_map_traverse, deallocate stored vectors.  */
441
442 static bool
443 delete_base_accesses (const void *key ATTRIBUTE_UNUSED, void **value,
444                      void *data ATTRIBUTE_UNUSED)
445 {
446   VEC (access_p, heap) *access_vec;
447   access_vec = (VEC (access_p, heap) *) *value;
448   VEC_free (access_p, heap, access_vec);
449
450   return true;
451 }
452
453 /* Deallocate all general structures.  */
454
455 static void
456 sra_deinitialize (void)
457 {
458   BITMAP_FREE (candidate_bitmap);
459   free_alloc_pool (access_pool);
460   free_alloc_pool (link_pool);
461   obstack_free (&name_obstack, NULL);
462
463   pointer_map_traverse (base_access_vec, delete_base_accesses, NULL);
464   pointer_map_destroy (base_access_vec);
465 }
466
467 /* Remove DECL from candidates for SRA and write REASON to the dump file if
468    there is one.  */
469 static void
470 disqualify_candidate (tree decl, const char *reason)
471 {
472   bitmap_clear_bit (candidate_bitmap, DECL_UID (decl));
473
474   if (dump_file && (dump_flags & TDF_DETAILS))
475     {
476       fprintf (dump_file, "! Disqualifying ");
477       print_generic_expr (dump_file, decl, 0);
478       fprintf (dump_file, " - %s\n", reason);
479     }
480 }
481
482 /* Return true iff the type contains a field or an element which does not allow
483    scalarization.  */
484
485 static bool
486 type_internals_preclude_sra_p (tree type)
487 {
488   tree fld;
489   tree et;
490
491   switch (TREE_CODE (type))
492     {
493     case RECORD_TYPE:
494     case UNION_TYPE:
495     case QUAL_UNION_TYPE:
496       for (fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
497         if (TREE_CODE (fld) == FIELD_DECL)
498           {
499             tree ft = TREE_TYPE (fld);
500
501             if (TREE_THIS_VOLATILE (fld)
502                 || !DECL_FIELD_OFFSET (fld) || !DECL_SIZE (fld)
503                 || !host_integerp (DECL_FIELD_OFFSET (fld), 1)
504                 || !host_integerp (DECL_SIZE (fld), 1))
505               return true;
506
507             if (AGGREGATE_TYPE_P (ft)
508                 && type_internals_preclude_sra_p (ft))
509               return true;
510           }
511
512       return false;
513
514     case ARRAY_TYPE:
515       et = TREE_TYPE (type);
516
517       if (AGGREGATE_TYPE_P (et))
518         return type_internals_preclude_sra_p (et);
519       else
520         return false;
521
522     default:
523       return false;
524     }
525 }
526
527 /* Create and insert access for EXPR. Return created access, or NULL if it is
528    not possible.  */
529
530 static struct access *
531 create_access (tree expr, bool write)
532 {
533   struct access *access;
534   void **slot;
535   VEC (access_p,heap) *vec;
536   HOST_WIDE_INT offset, size, max_size;
537   tree base = expr;
538   bool unscalarizable_region = false;
539
540   base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
541
542   if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
543     return NULL;
544
545   if (size != max_size)
546     {
547       size = max_size;
548       unscalarizable_region = true;
549     }
550
551   if (size < 0)
552     {
553       disqualify_candidate (base, "Encountered an unconstrained access.");
554       return NULL;
555     }
556
557   access = (struct access *) pool_alloc (access_pool);
558   memset (access, 0, sizeof (struct access));
559
560   access->base = base;
561   access->offset = offset;
562   access->size = size;
563   access->expr = expr;
564   access->type = TREE_TYPE (expr);
565   access->write = write;
566   access->grp_unscalarizable_region = unscalarizable_region;
567
568   slot = pointer_map_contains (base_access_vec, base);
569   if (slot)
570     vec = (VEC (access_p, heap) *) *slot;
571   else
572     vec = VEC_alloc (access_p, heap, 32);
573
574   VEC_safe_push (access_p, heap, vec, access);
575
576   *((struct VEC (access_p,heap) **)
577         pointer_map_insert (base_access_vec, base)) = vec;
578
579   return access;
580 }
581
582
583 /* Search the given tree for a declaration by skipping handled components and
584    exclude it from the candidates.  */
585
586 static void
587 disqualify_base_of_expr (tree t, const char *reason)
588 {
589   while (handled_component_p (t))
590     t = TREE_OPERAND (t, 0);
591
592   if (DECL_P (t))
593     disqualify_candidate (t, reason);
594 }
595
596 /* Scan expression EXPR and create access structures for all accesses to
597    candidates for scalarization.  Return the created access or NULL if none is
598    created.  */
599
600 static struct access *
601 build_access_from_expr_1 (tree *expr_ptr, bool write)
602 {
603   struct access *ret = NULL;
604   tree expr = *expr_ptr;
605   bool partial_ref;
606
607   if (TREE_CODE (expr) == BIT_FIELD_REF
608       || TREE_CODE (expr) == IMAGPART_EXPR
609       || TREE_CODE (expr) == REALPART_EXPR)
610     {
611       expr = TREE_OPERAND (expr, 0);
612       partial_ref = true;
613     }
614   else
615     partial_ref = false;
616
617   /* We need to dive through V_C_Es in order to get the size of its parameter
618      and not the result type.  Ada produces such statements.  We are also
619      capable of handling the topmost V_C_E but not any of those buried in other
620      handled components.  */
621   if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
622     expr = TREE_OPERAND (expr, 0);
623
624   if (contains_view_convert_expr_p (expr))
625     {
626       disqualify_base_of_expr (expr, "V_C_E under a different handled "
627                                "component.");
628       return NULL;
629     }
630
631   switch (TREE_CODE (expr))
632     {
633     case VAR_DECL:
634     case PARM_DECL:
635     case RESULT_DECL:
636     case COMPONENT_REF:
637     case ARRAY_REF:
638     case ARRAY_RANGE_REF:
639       ret = create_access (expr, write);
640       break;
641
642     default:
643       break;
644     }
645
646   if (write && partial_ref && ret)
647     ret->grp_partial_lhs = 1;
648
649   return ret;
650 }
651
652 /* Callback of scan_function.  Scan expression EXPR and create access
653    structures for all accesses to candidates for scalarization.  Return true if
654    any access has been inserted.  */
655
656 static bool
657 build_access_from_expr (tree *expr_ptr,
658                         gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED, bool write,
659                         void *data ATTRIBUTE_UNUSED)
660 {
661   return build_access_from_expr_1 (expr_ptr, write) != NULL;
662 }
663
664 /* Disqualify LHS and RHS for scalarization if STMT must end its basic block in
665    modes in which it matters, return true iff they have been disqualified.  RHS
666    may be NULL, in that case ignore it.  If we scalarize an aggregate in
667    intra-SRA we may need to add statements after each statement.  This is not
668    possible if a statement unconditionally has to end the basic block.  */
669 static bool
670 disqualify_ops_if_throwing_stmt (gimple stmt, tree lhs, tree rhs)
671 {
672   if (stmt_can_throw_internal (stmt) || stmt_ends_bb_p (stmt))
673     {
674       disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
675       if (rhs)
676         disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
677       return true;
678     }
679   return false;
680 }
681
682
683 /* Result code for scan_assign callback for scan_function.  */
684 enum scan_assign_result { SRA_SA_NONE,       /* nothing done for the stmt */
685                           SRA_SA_PROCESSED,  /* stmt analyzed/changed */
686                           SRA_SA_REMOVED };  /* stmt redundant and eliminated */
687
688
689 /* Callback of scan_function.  Scan expressions occuring in the statement
690    pointed to by STMT_EXPR, create access structures for all accesses to
691    candidates for scalarization and remove those candidates which occur in
692    statements or expressions that prevent them from being split apart.  Return
693    true if any access has been inserted.  */
694
695 static enum scan_assign_result
696 build_accesses_from_assign (gimple *stmt_ptr,
697                             gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
698                             void *data ATTRIBUTE_UNUSED)
699 {
700   gimple stmt = *stmt_ptr;
701   tree *lhs_ptr, *rhs_ptr;
702   struct access *lacc, *racc;
703
704   if (!gimple_assign_single_p (stmt))
705     return SRA_SA_NONE;
706
707   lhs_ptr = gimple_assign_lhs_ptr (stmt);
708   rhs_ptr = gimple_assign_rhs1_ptr (stmt);
709
710   if (disqualify_ops_if_throwing_stmt (stmt, *lhs_ptr, *rhs_ptr))
711     return SRA_SA_NONE;
712
713   racc = build_access_from_expr_1 (rhs_ptr, false);
714   lacc = build_access_from_expr_1 (lhs_ptr, true);
715
716   if (lacc && racc
717       && !lacc->grp_unscalarizable_region
718       && !racc->grp_unscalarizable_region
719       && AGGREGATE_TYPE_P (TREE_TYPE (*lhs_ptr))
720       /* FIXME: Turn the following line into an assert after PR 40058 is
721          fixed.  */
722       && lacc->size == racc->size
723       && useless_type_conversion_p (lacc->type, racc->type))
724     {
725       struct assign_link *link;
726
727       link = (struct assign_link *) pool_alloc (link_pool);
728       memset (link, 0, sizeof (struct assign_link));
729
730       link->lacc = lacc;
731       link->racc = racc;
732
733       add_link_to_rhs (racc, link);
734     }
735
736   return (lacc || racc) ? SRA_SA_PROCESSED : SRA_SA_NONE;
737 }
738
739 /* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
740    GIMPLE_ASM operands with memory constrains which cannot be scalarized.  */
741
742 static bool
743 asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED, tree op,
744                 void *data ATTRIBUTE_UNUSED)
745 {
746   if (DECL_P (op))
747     disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
748
749   return false;
750 }
751
752
753 /* Scan function and look for interesting statements. Return true if any has
754    been found or processed, as indicated by callbacks.  SCAN_EXPR is a callback
755    called on all expressions within statements except assign statements and
756    those deemed entirely unsuitable for some reason (all operands in such
757    statements and expression are removed from candidate_bitmap).  SCAN_ASSIGN
758    is a callback called on all assign statements, HANDLE_SSA_DEFS is a callback
759    called on assign statements and those call statements which have a lhs and
760    it is the only callback which can be NULL. ANALYSIS_STAGE is true when
761    running in the analysis stage of a pass and thus no statement is being
762    modified.  DATA is a pointer passed to all callbacks.  If any single
763    callback returns true, this function also returns true, otherwise it returns
764    false.  */
765
766 static bool
767 scan_function (bool (*scan_expr) (tree *, gimple_stmt_iterator *, bool, void *),
768                enum scan_assign_result (*scan_assign) (gimple *,
769                                                        gimple_stmt_iterator *,
770                                                        void *),
771                bool (*handle_ssa_defs)(gimple, void *),
772                bool analysis_stage, void *data)
773 {
774   gimple_stmt_iterator gsi;
775   basic_block bb;
776   unsigned i;
777   tree *t;
778   bool ret = false;
779
780   FOR_EACH_BB (bb)
781     {
782       bool bb_changed = false;
783
784       gsi = gsi_start_bb (bb);
785       while (!gsi_end_p (gsi))
786         {
787           gimple stmt = gsi_stmt (gsi);
788           enum scan_assign_result assign_result;
789           bool any = false, deleted = false;
790
791           switch (gimple_code (stmt))
792             {
793             case GIMPLE_RETURN:
794               t = gimple_return_retval_ptr (stmt);
795               if (*t != NULL_TREE)
796                 any |= scan_expr (t, &gsi, false, data);
797               break;
798
799             case GIMPLE_ASSIGN:
800               assign_result = scan_assign (&stmt, &gsi, data);
801               any |= assign_result == SRA_SA_PROCESSED;
802               deleted = assign_result == SRA_SA_REMOVED;
803               if (handle_ssa_defs && assign_result != SRA_SA_REMOVED)
804                 any |= handle_ssa_defs (stmt, data);
805               break;
806
807             case GIMPLE_CALL:
808               /* Operands must be processed before the lhs.  */
809               for (i = 0; i < gimple_call_num_args (stmt); i++)
810                 {
811                   tree *argp = gimple_call_arg_ptr (stmt, i);
812                   any |= scan_expr (argp, &gsi, false, data);
813                 }
814
815               if (gimple_call_lhs (stmt))
816                 {
817                   tree *lhs_ptr = gimple_call_lhs_ptr (stmt);
818                   if (!analysis_stage
819                       || !disqualify_ops_if_throwing_stmt (stmt,
820                                                            *lhs_ptr, NULL))
821                     {
822                       any |= scan_expr (lhs_ptr, &gsi, true, data);
823                       if (handle_ssa_defs)
824                         any |= handle_ssa_defs (stmt, data);
825                     }
826                 }
827               break;
828
829             case GIMPLE_ASM:
830
831               if (analysis_stage)
832                 walk_stmt_load_store_addr_ops (stmt, NULL, NULL, NULL,
833                                                asm_visit_addr);
834               for (i = 0; i < gimple_asm_ninputs (stmt); i++)
835                 {
836                   tree *op = &TREE_VALUE (gimple_asm_input_op (stmt, i));
837                   any |= scan_expr (op, &gsi, false, data);
838                 }
839               for (i = 0; i < gimple_asm_noutputs (stmt); i++)
840                 {
841                   tree *op = &TREE_VALUE (gimple_asm_output_op (stmt, i));
842                   any |= scan_expr (op, &gsi, true, data);
843                 }
844
845             default:
846               break;
847             }
848
849           if (any)
850             {
851               ret = true;
852               bb_changed = true;
853
854               if (!analysis_stage)
855                 {
856                   update_stmt (stmt);
857                   if (!stmt_could_throw_p (stmt))
858                     remove_stmt_from_eh_region (stmt);
859                 }
860             }
861           if (deleted)
862             bb_changed = true;
863           else
864             {
865               gsi_next (&gsi);
866               ret = true;
867             }
868         }
869       if (!analysis_stage && bb_changed)
870         gimple_purge_dead_eh_edges (bb);
871     }
872
873   return ret;
874 }
875
876 /* Helper of QSORT function. There are pointers to accesses in the array.  An
877    access is considered smaller than another if it has smaller offset or if the
878    offsets are the same but is size is bigger. */
879
880 static int
881 compare_access_positions (const void *a, const void *b)
882 {
883   const access_p *fp1 = (const access_p *) a;
884   const access_p *fp2 = (const access_p *) b;
885   const access_p f1 = *fp1;
886   const access_p f2 = *fp2;
887
888   if (f1->offset != f2->offset)
889     return f1->offset < f2->offset ? -1 : 1;
890
891   if (f1->size == f2->size)
892     {
893       /* Put any non-aggregate type before any aggregate type.  */
894       if (!is_gimple_reg_type (f1->type)
895                && is_gimple_reg_type (f2->type))
896         return 1;
897       else if (is_gimple_reg_type (f1->type)
898                && !is_gimple_reg_type (f2->type))
899         return -1;
900       /* Put the integral type with the bigger precision first.  */
901       else if (INTEGRAL_TYPE_P (f1->type)
902           && INTEGRAL_TYPE_P (f2->type))
903         return TYPE_PRECISION (f1->type) > TYPE_PRECISION (f2->type) ? -1 : 1;
904       /* Put any integral type with non-full precision last.  */
905       else if (INTEGRAL_TYPE_P (f1->type)
906                && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type))
907                    != TYPE_PRECISION (f1->type)))
908         return 1;
909       else if (INTEGRAL_TYPE_P (f2->type)
910                && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type))
911                    != TYPE_PRECISION (f2->type)))
912         return -1;
913       /* Stabilize the sort.  */
914       return TYPE_UID (f1->type) - TYPE_UID (f2->type);
915     }
916
917   /* We want the bigger accesses first, thus the opposite operator in the next
918      line: */
919   return f1->size > f2->size ? -1 : 1;
920 }
921
922
923 /* Append a name of the declaration to the name obstack.  A helper function for
924    make_fancy_name.  */
925
926 static void
927 make_fancy_decl_name (tree decl)
928 {
929   char buffer[32];
930
931   tree name = DECL_NAME (decl);
932   if (name)
933     obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
934                   IDENTIFIER_LENGTH (name));
935   else
936     {
937       sprintf (buffer, "D%u", DECL_UID (decl));
938       obstack_grow (&name_obstack, buffer, strlen (buffer));
939     }
940 }
941
942 /* Helper for make_fancy_name.  */
943
944 static void
945 make_fancy_name_1 (tree expr)
946 {
947   char buffer[32];
948   tree index;
949
950   if (DECL_P (expr))
951     {
952       make_fancy_decl_name (expr);
953       return;
954     }
955
956   switch (TREE_CODE (expr))
957     {
958     case COMPONENT_REF:
959       make_fancy_name_1 (TREE_OPERAND (expr, 0));
960       obstack_1grow (&name_obstack, '$');
961       make_fancy_decl_name (TREE_OPERAND (expr, 1));
962       break;
963
964     case ARRAY_REF:
965       make_fancy_name_1 (TREE_OPERAND (expr, 0));
966       obstack_1grow (&name_obstack, '$');
967       /* Arrays with only one element may not have a constant as their
968          index. */
969       index = TREE_OPERAND (expr, 1);
970       if (TREE_CODE (index) != INTEGER_CST)
971         break;
972       sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
973       obstack_grow (&name_obstack, buffer, strlen (buffer));
974
975       break;
976
977     case BIT_FIELD_REF:
978     case REALPART_EXPR:
979     case IMAGPART_EXPR:
980       gcc_unreachable ();       /* we treat these as scalars.  */
981       break;
982     default:
983       break;
984     }
985 }
986
987 /* Create a human readable name for replacement variable of ACCESS.  */
988
989 static char *
990 make_fancy_name (tree expr)
991 {
992   make_fancy_name_1 (expr);
993   obstack_1grow (&name_obstack, '\0');
994   return XOBFINISH (&name_obstack, char *);
995 }
996
997 /* Helper function for build_ref_for_offset.  */
998
999 static bool
1000 build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset,
1001                         tree exp_type)
1002 {
1003   while (1)
1004     {
1005       tree fld;
1006       tree tr_size, index;
1007       HOST_WIDE_INT el_size;
1008
1009       if (offset == 0 && exp_type
1010           && useless_type_conversion_p (exp_type, type))
1011         return true;
1012
1013       switch (TREE_CODE (type))
1014         {
1015         case UNION_TYPE:
1016         case QUAL_UNION_TYPE:
1017         case RECORD_TYPE:
1018           /* Some ADA records are half-unions, treat all of them the same.  */
1019           for (fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
1020             {
1021               HOST_WIDE_INT pos, size;
1022               tree expr, *expr_ptr;
1023
1024               if (TREE_CODE (fld) != FIELD_DECL)
1025                 continue;
1026
1027               pos = int_bit_position (fld);
1028               gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
1029               size = tree_low_cst (DECL_SIZE (fld), 1);
1030               if (pos > offset || (pos + size) <= offset)
1031                 continue;
1032
1033               if (res)
1034                 {
1035                   expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
1036                                  NULL_TREE);
1037                   expr_ptr = &expr;
1038                 }
1039               else
1040                 expr_ptr = NULL;
1041               if (build_ref_for_offset_1 (expr_ptr, TREE_TYPE (fld),
1042                                           offset - pos, exp_type))
1043                 {
1044                   if (res)
1045                     *res = expr;
1046                   return true;
1047                 }
1048             }
1049           return false;
1050
1051         case ARRAY_TYPE:
1052           tr_size = TYPE_SIZE (TREE_TYPE (type));
1053           if (!tr_size || !host_integerp (tr_size, 1))
1054             return false;
1055           el_size = tree_low_cst (tr_size, 1);
1056
1057           if (res)
1058             {
1059               index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
1060               if (!integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (type))))
1061                 index = int_const_binop (PLUS_EXPR, index,
1062                                          TYPE_MIN_VALUE (TYPE_DOMAIN (type)),
1063                                          0);
1064               *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
1065                              NULL_TREE, NULL_TREE);
1066             }
1067           offset = offset % el_size;
1068           type = TREE_TYPE (type);
1069           break;
1070
1071         default:
1072           if (offset != 0)
1073             return false;
1074
1075           if (exp_type)
1076             return false;
1077           else
1078             return true;
1079         }
1080     }
1081 }
1082
1083 /* Construct an expression that would reference a part of aggregate *EXPR of
1084    type TYPE at the given OFFSET of the type EXP_TYPE.  If EXPR is NULL, the
1085    function only determines whether it can build such a reference without
1086    actually doing it.
1087
1088    FIXME: Eventually this should be replaced with
1089    maybe_fold_offset_to_reference() from tree-ssa-ccp.c but that requires a
1090    minor rewrite of fold_stmt.
1091  */
1092
1093 static bool
1094 build_ref_for_offset (tree *expr, tree type, HOST_WIDE_INT offset,
1095                       tree exp_type, bool allow_ptr)
1096 {
1097   if (allow_ptr && POINTER_TYPE_P (type))
1098     {
1099       type = TREE_TYPE (type);
1100       if (expr)
1101         *expr = fold_build1 (INDIRECT_REF, type, *expr);
1102     }
1103
1104   return build_ref_for_offset_1 (expr, type, offset, exp_type);
1105 }
1106
1107 /* The very first phase of intraprocedural SRA.  It marks in candidate_bitmap
1108    those with type which is suitable for scalarization.  */
1109
1110 static bool
1111 find_var_candidates (void)
1112 {
1113   tree var, type;
1114   referenced_var_iterator rvi;
1115   bool ret = false;
1116
1117   FOR_EACH_REFERENCED_VAR (var, rvi)
1118     {
1119       if (TREE_CODE (var) != VAR_DECL && TREE_CODE (var) != PARM_DECL)
1120         continue;
1121       type = TREE_TYPE (var);
1122
1123       if (!AGGREGATE_TYPE_P (type)
1124           || needs_to_live_in_memory (var)
1125           || TREE_THIS_VOLATILE (var)
1126           || !COMPLETE_TYPE_P (type)
1127           || !host_integerp (TYPE_SIZE (type), 1)
1128           || tree_low_cst (TYPE_SIZE (type), 1) == 0
1129           || type_internals_preclude_sra_p (type))
1130         continue;
1131
1132       bitmap_set_bit (candidate_bitmap, DECL_UID (var));
1133
1134       if (dump_file && (dump_flags & TDF_DETAILS))
1135         {
1136           fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
1137           print_generic_expr (dump_file, var, 0);
1138           fprintf (dump_file, "\n");
1139         }
1140       ret = true;
1141     }
1142
1143   return ret;
1144 }
1145
1146 /* Sort all accesses for the given variable, check for partial overlaps and
1147    return NULL if there are any.  If there are none, pick a representative for
1148    each combination of offset and size and create a linked list out of them.
1149    Return the pointer to the first representative and make sure it is the first
1150    one in the vector of accesses.  */
1151
1152 static struct access *
1153 sort_and_splice_var_accesses (tree var)
1154 {
1155   int i, j, access_count;
1156   struct access *res, **prev_acc_ptr = &res;
1157   VEC (access_p, heap) *access_vec;
1158   bool first = true;
1159   HOST_WIDE_INT low = -1, high = 0;
1160
1161   access_vec = get_base_access_vector (var);
1162   if (!access_vec)
1163     return NULL;
1164   access_count = VEC_length (access_p, access_vec);
1165
1166   /* Sort by <OFFSET, SIZE>.  */
1167   qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
1168          compare_access_positions);
1169
1170   i = 0;
1171   while (i < access_count)
1172     {
1173       struct access *access = VEC_index (access_p, access_vec, i);
1174       bool modification = access->write;
1175       bool grp_read = !access->write;
1176       bool grp_partial_lhs = access->grp_partial_lhs;
1177       bool first_scalar = is_gimple_reg_type (access->type);
1178       bool unscalarizable_region = access->grp_unscalarizable_region;
1179
1180       if (first || access->offset >= high)
1181         {
1182           first = false;
1183           low = access->offset;
1184           high = access->offset + access->size;
1185         }
1186       else if (access->offset > low && access->offset + access->size > high)
1187         return NULL;
1188       else
1189         gcc_assert (access->offset >= low
1190                     && access->offset + access->size <= high);
1191
1192       j = i + 1;
1193       while (j < access_count)
1194         {
1195           struct access *ac2 = VEC_index (access_p, access_vec, j);
1196           if (ac2->offset != access->offset || ac2->size != access->size)
1197             break;
1198           modification |= ac2->write;
1199           grp_read |= !ac2->write;
1200           grp_partial_lhs |= ac2->grp_partial_lhs;
1201           unscalarizable_region |= ac2->grp_unscalarizable_region;
1202           relink_to_new_repr (access, ac2);
1203
1204           /* If there are both aggregate-type and scalar-type accesses with
1205              this combination of size and offset, the comparison function
1206              should have put the scalars first.  */
1207           gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
1208           ac2->group_representative = access;
1209           j++;
1210         }
1211
1212       i = j;
1213
1214       access->group_representative = access;
1215       access->grp_write = modification;
1216       access->grp_read = grp_read;
1217       access->grp_partial_lhs = grp_partial_lhs;
1218       access->grp_unscalarizable_region = unscalarizable_region;
1219       if (access->first_link)
1220         add_access_to_work_queue (access);
1221
1222       *prev_acc_ptr = access;
1223       prev_acc_ptr = &access->next_grp;
1224     }
1225
1226   gcc_assert (res == VEC_index (access_p, access_vec, 0));
1227   return res;
1228 }
1229
1230 /* Create a variable for the given ACCESS which determines the type, name and a
1231    few other properties.  Return the variable declaration and store it also to
1232    ACCESS->replacement.  */
1233
1234 static tree
1235 create_access_replacement (struct access *access)
1236 {
1237   tree repl;
1238
1239   repl = create_tmp_var (access->type, "SR");
1240   get_var_ann (repl);
1241   add_referenced_var (repl);
1242   mark_sym_for_renaming (repl);
1243
1244   if (!access->grp_partial_lhs
1245       && (TREE_CODE (access->type) == COMPLEX_TYPE
1246           || TREE_CODE (access->type) == VECTOR_TYPE))
1247     DECL_GIMPLE_REG_P (repl) = 1;
1248
1249   DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
1250   DECL_ARTIFICIAL (repl) = 1;
1251
1252   if (DECL_NAME (access->base)
1253       && !DECL_IGNORED_P (access->base)
1254       && !DECL_ARTIFICIAL (access->base))
1255     {
1256       char *pretty_name = make_fancy_name (access->expr);
1257
1258       DECL_NAME (repl) = get_identifier (pretty_name);
1259       obstack_free (&name_obstack, pretty_name);
1260
1261       SET_DECL_DEBUG_EXPR (repl, access->expr);
1262       DECL_DEBUG_EXPR_IS_FROM (repl) = 1;
1263       DECL_IGNORED_P (repl) = 0;
1264     }
1265
1266   DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
1267   TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
1268
1269   if (dump_file)
1270     {
1271       fprintf (dump_file, "Created a replacement for ");
1272       print_generic_expr (dump_file, access->base, 0);
1273       fprintf (dump_file, " offset: %u, size: %u: ",
1274                (unsigned) access->offset, (unsigned) access->size);
1275       print_generic_expr (dump_file, repl, 0);
1276       fprintf (dump_file, "\n");
1277     }
1278
1279   return repl;
1280 }
1281
1282 /* Return ACCESS scalar replacement, create it if it does not exist yet.  */
1283
1284 static inline tree
1285 get_access_replacement (struct access *access)
1286 {
1287   gcc_assert (access->grp_to_be_replaced);
1288
1289   if (access->replacement_decl)
1290     return access->replacement_decl;
1291
1292   access->replacement_decl = create_access_replacement (access);
1293   return access->replacement_decl;
1294 }
1295
1296 /* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
1297    linked list along the way.  Stop when *ACCESS is NULL or the access pointed
1298    to it is not "within" the root.  */
1299
1300 static void
1301 build_access_subtree (struct access **access)
1302 {
1303   struct access *root = *access, *last_child = NULL;
1304   HOST_WIDE_INT limit = root->offset + root->size;
1305
1306   *access = (*access)->next_grp;
1307   while  (*access && (*access)->offset + (*access)->size <= limit)
1308     {
1309       if (!last_child)
1310         root->first_child = *access;
1311       else
1312         last_child->next_sibling = *access;
1313       last_child = *access;
1314
1315       build_access_subtree (access);
1316     }
1317 }
1318
1319 /* Build a tree of access representatives, ACCESS is the pointer to the first
1320    one, others are linked in a list by the next_grp field.  Decide about scalar
1321    replacements on the way, return true iff any are to be created.  */
1322
1323 static void
1324 build_access_trees (struct access *access)
1325 {
1326   while (access)
1327     {
1328       struct access *root = access;
1329
1330       build_access_subtree (&access);
1331       root->next_grp = access;
1332     }
1333 }
1334
1335 /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
1336    both seeming beneficial and when ALLOW_REPLACEMENTS allows it.  Also set
1337    all sorts of access flags appropriately along the way, notably always ser
1338    grp_read when MARK_READ is true and grp_write when MARK_WRITE is true.  */
1339
1340 static bool
1341 analyze_access_subtree (struct access *root, bool allow_replacements,
1342                         bool mark_read, bool mark_write)
1343 {
1344   struct access *child;
1345   HOST_WIDE_INT limit = root->offset + root->size;
1346   HOST_WIDE_INT covered_to = root->offset;
1347   bool scalar = is_gimple_reg_type (root->type);
1348   bool hole = false, sth_created = false;
1349
1350   if (mark_read)
1351     root->grp_read = true;
1352   else if (root->grp_read)
1353     mark_read = true;
1354
1355   if (mark_write)
1356     root->grp_write = true;
1357   else if (root->grp_write)
1358     mark_write = true;
1359
1360   if (root->grp_unscalarizable_region)
1361     allow_replacements = false;
1362
1363   for (child = root->first_child; child; child = child->next_sibling)
1364     {
1365       if (!hole && child->offset < covered_to)
1366         hole = true;
1367       else
1368         covered_to += child->size;
1369
1370       sth_created |= analyze_access_subtree (child, allow_replacements,
1371                                              mark_read, mark_write);
1372
1373       root->grp_unscalarized_data |= child->grp_unscalarized_data;
1374       hole |= !child->grp_covered;
1375     }
1376
1377   if (allow_replacements && scalar && !root->first_child)
1378     {
1379       if (dump_file && (dump_flags & TDF_DETAILS))
1380         {
1381           fprintf (dump_file, "Marking ");
1382           print_generic_expr (dump_file, root->base, 0);
1383           fprintf (dump_file, " offset: %u, size: %u: ",
1384                    (unsigned) root->offset, (unsigned) root->size);
1385           fprintf (dump_file, " to be replaced.\n");
1386         }
1387
1388       root->grp_to_be_replaced = 1;
1389       sth_created = true;
1390       hole = false;
1391     }
1392   else if (covered_to < limit)
1393     hole = true;
1394
1395   if (sth_created && !hole)
1396     {
1397       root->grp_covered = 1;
1398       return true;
1399     }
1400   if (root->grp_write || TREE_CODE (root->base) == PARM_DECL)
1401     root->grp_unscalarized_data = 1; /* not covered and written to */
1402   if (sth_created)
1403     return true;
1404   return false;
1405 }
1406
1407 /* Analyze all access trees linked by next_grp by the means of
1408    analyze_access_subtree.  */
1409 static bool
1410 analyze_access_trees (struct access *access)
1411 {
1412   bool ret = false;
1413
1414   while (access)
1415     {
1416       if (analyze_access_subtree (access, true, false, false))
1417         ret = true;
1418       access = access->next_grp;
1419     }
1420
1421   return ret;
1422 }
1423
1424 /* Return true iff a potential new child of LACC at offset OFFSET and with size
1425    SIZE would conflict with an already existing one.  If exactly such a child
1426    already exists in LACC, store a pointer to it in EXACT_MATCH.  */
1427
1428 static bool
1429 child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
1430                               HOST_WIDE_INT size, struct access **exact_match)
1431 {
1432   struct access *child;
1433
1434   for (child = lacc->first_child; child; child = child->next_sibling)
1435     {
1436       if (child->offset == norm_offset && child->size == size)
1437         {
1438           *exact_match = child;
1439           return true;
1440         }
1441
1442       if (child->offset < norm_offset + size
1443           && child->offset + child->size > norm_offset)
1444         return true;
1445     }
1446
1447   return false;
1448 }
1449
1450 /* Set the expr of TARGET to one just like MODEL but with is own base at the
1451    bottom of the handled components.  */
1452
1453 static void
1454 duplicate_expr_for_different_base (struct access *target,
1455                                    struct access *model)
1456 {
1457   tree t, expr = unshare_expr (model->expr);
1458
1459   gcc_assert (handled_component_p (expr));
1460   t = expr;
1461   while (handled_component_p (TREE_OPERAND (t, 0)))
1462     t = TREE_OPERAND (t, 0);
1463   gcc_assert (TREE_OPERAND (t, 0) == model->base);
1464   TREE_OPERAND (t, 0) = target->base;
1465
1466   target->expr = expr;
1467 }
1468
1469
1470 /* Create a new child access of PARENT, with all properties just like MODEL
1471    except for its offset and with its grp_write false and grp_read true.
1472    Return the new access. Note that this access is created long after all
1473    splicing and sorting, it's not located in any access vector and is
1474    automatically a representative of its group.  */
1475
1476 static struct access *
1477 create_artificial_child_access (struct access *parent, struct access *model,
1478                                 HOST_WIDE_INT new_offset)
1479 {
1480   struct access *access;
1481   struct access **child;
1482
1483   gcc_assert (!model->grp_unscalarizable_region);
1484
1485   access = (struct access *) pool_alloc (access_pool);
1486   memset (access, 0, sizeof (struct access));
1487   access->base = parent->base;
1488   access->offset = new_offset;
1489   access->size = model->size;
1490   duplicate_expr_for_different_base (access, model);
1491   access->type = model->type;
1492   access->grp_write = true;
1493   access->grp_read = false;
1494
1495   child = &parent->first_child;
1496   while (*child && (*child)->offset < new_offset)
1497     child = &(*child)->next_sibling;
1498
1499   access->next_sibling = *child;
1500   *child = access;
1501
1502   return access;
1503 }
1504
1505
1506 /* Propagate all subaccesses of RACC across an assignment link to LACC. Return
1507    true if any new subaccess was created.  Additionally, if RACC is a scalar
1508    access but LACC is not, change the type of the latter.  */
1509
1510 static bool
1511 propagate_subacesses_accross_link (struct access *lacc, struct access *racc)
1512 {
1513   struct access *rchild;
1514   HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
1515
1516   bool ret = false;
1517
1518   if (is_gimple_reg_type (lacc->type)
1519       || lacc->grp_unscalarizable_region
1520       || racc->grp_unscalarizable_region)
1521     return false;
1522
1523   if (!lacc->first_child && !racc->first_child
1524       && is_gimple_reg_type (racc->type))
1525     {
1526       duplicate_expr_for_different_base (lacc, racc);
1527       lacc->type = racc->type;
1528       return false;
1529     }
1530
1531   for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
1532     {
1533       struct access *new_acc = NULL;
1534       HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
1535
1536       if (rchild->grp_unscalarizable_region)
1537         continue;
1538
1539       if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
1540                                         &new_acc))
1541         {
1542           if (new_acc && rchild->first_child)
1543             ret |= propagate_subacesses_accross_link (new_acc, rchild);
1544           continue;
1545         }
1546
1547       new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
1548       if (racc->first_child)
1549         propagate_subacesses_accross_link (new_acc, rchild);
1550
1551       ret = true;
1552     }
1553
1554   return ret;
1555 }
1556
1557 /* Propagate all subaccesses across assignment links.  */
1558
1559 static void
1560 propagate_all_subaccesses (void)
1561 {
1562   while (work_queue_head)
1563     {
1564       struct access *racc = pop_access_from_work_queue ();
1565       struct assign_link *link;
1566
1567       gcc_assert (racc->first_link);
1568
1569       for (link = racc->first_link; link; link = link->next)
1570         {
1571           struct access *lacc = link->lacc;
1572
1573           if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
1574             continue;
1575           lacc = lacc->group_representative;
1576           if (propagate_subacesses_accross_link (lacc, racc)
1577               && lacc->first_link)
1578             add_access_to_work_queue (lacc);
1579         }
1580     }
1581 }
1582
1583 /* Go through all accesses collected throughout the (intraprocedural) analysis
1584    stage, exclude overlapping ones, identify representatives and build trees
1585    out of them, making decisions about scalarization on the way.  Return true
1586    iff there are any to-be-scalarized variables after this stage. */
1587
1588 static bool
1589 analyze_all_variable_accesses (void)
1590 {
1591   tree var;
1592   referenced_var_iterator rvi;
1593   bool res = false;
1594
1595   FOR_EACH_REFERENCED_VAR (var, rvi)
1596     if (bitmap_bit_p (candidate_bitmap, DECL_UID (var)))
1597       {
1598         struct access *access;
1599
1600         access = sort_and_splice_var_accesses (var);
1601         if (access)
1602           build_access_trees (access);
1603         else
1604           disqualify_candidate (var,
1605                                 "No or inhibitingly overlapping accesses.");
1606       }
1607
1608   propagate_all_subaccesses ();
1609
1610   FOR_EACH_REFERENCED_VAR (var, rvi)
1611     if (bitmap_bit_p (candidate_bitmap, DECL_UID (var)))
1612       {
1613         struct access *access = get_first_repr_for_decl (var);
1614
1615         if (analyze_access_trees (access))
1616           {
1617             res = true;
1618             if (dump_file && (dump_flags & TDF_DETAILS))
1619               {
1620                 fprintf (dump_file, "\nAccess trees for ");
1621                 print_generic_expr (dump_file, var, 0);
1622                 fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
1623                 dump_access_tree (dump_file, access);
1624                 fprintf (dump_file, "\n");
1625               }
1626           }
1627         else
1628           disqualify_candidate (var, "No scalar replacements to be created.");
1629       }
1630
1631   return res;
1632 }
1633
1634 /* Return true iff a reference statement into aggregate AGG can be built for
1635    every single to-be-replaced accesses that is a child of ACCESS, its sibling
1636    or a child of its sibling. TOP_OFFSET is the offset from the processed
1637    access subtree that has to be subtracted from offset of each access.  */
1638
1639 static bool
1640 ref_expr_for_all_replacements_p (struct access *access, tree agg,
1641                                  HOST_WIDE_INT top_offset)
1642 {
1643   do
1644     {
1645       if (access->grp_to_be_replaced
1646           && !build_ref_for_offset (NULL, TREE_TYPE (agg),
1647                                     access->offset - top_offset,
1648                                     access->type, false))
1649         return false;
1650
1651       if (access->first_child
1652           && !ref_expr_for_all_replacements_p (access->first_child, agg,
1653                                                top_offset))
1654         return false;
1655
1656       access = access->next_sibling;
1657     }
1658   while (access);
1659
1660   return true;
1661 }
1662
1663 /* Generate statements copying scalar replacements of accesses within a subtree
1664    into or out of AGG.  ACCESS is the first child of the root of the subtree to
1665    be processed.  AGG is an aggregate type expression (can be a declaration but
1666    does not have to be, it can for example also be an indirect_ref).
1667    TOP_OFFSET is the offset of the processed subtree which has to be subtracted
1668    from offsets of individual accesses to get corresponding offsets for AGG.
1669    If CHUNK_SIZE is non-null, copy only replacements in the interval
1670    <start_offset, start_offset + chunk_size>, otherwise copy all.  GSI is a
1671    statement iterator used to place the new statements.  WRITE should be true
1672    when the statements should write from AGG to the replacement and false if
1673    vice versa.  if INSERT_AFTER is true, new statements will be added after the
1674    current statement in GSI, they will be added before the statement
1675    otherwise.  */
1676
1677 static void
1678 generate_subtree_copies (struct access *access, tree agg,
1679                          HOST_WIDE_INT top_offset,
1680                          HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
1681                          gimple_stmt_iterator *gsi, bool write,
1682                          bool insert_after)
1683 {
1684   do
1685     {
1686       tree expr = unshare_expr (agg);
1687
1688       if (chunk_size && access->offset >= start_offset + chunk_size)
1689         return;
1690
1691       if (access->grp_to_be_replaced
1692           && (chunk_size == 0
1693               || access->offset + access->size > start_offset))
1694         {
1695           tree repl = get_access_replacement (access);
1696           bool ref_found;
1697           gimple stmt;
1698
1699           ref_found = build_ref_for_offset (&expr, TREE_TYPE (agg),
1700                                              access->offset - top_offset,
1701                                              access->type, false);
1702           gcc_assert (ref_found);
1703
1704           if (write)
1705             {
1706               if (access->grp_partial_lhs)
1707                 expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
1708                                                  !insert_after,
1709                                                  insert_after ? GSI_NEW_STMT
1710                                                  : GSI_SAME_STMT);
1711               stmt = gimple_build_assign (repl, expr);
1712             }
1713           else
1714             {
1715               TREE_NO_WARNING (repl) = 1;
1716               if (access->grp_partial_lhs)
1717                 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
1718                                                  !insert_after,
1719                                                  insert_after ? GSI_NEW_STMT
1720                                                  : GSI_SAME_STMT);
1721               stmt = gimple_build_assign (expr, repl);
1722             }
1723
1724           if (insert_after)
1725             gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
1726           else
1727             gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1728           update_stmt (stmt);
1729         }
1730
1731       if (access->first_child)
1732         generate_subtree_copies (access->first_child, agg, top_offset,
1733                                  start_offset, chunk_size, gsi,
1734                                  write, insert_after);
1735
1736       access = access->next_sibling;
1737     }
1738   while (access);
1739 }
1740
1741 /* Assign zero to all scalar replacements in an access subtree.  ACCESS is the
1742    the root of the subtree to be processed.  GSI is the statement iterator used
1743    for inserting statements which are added after the current statement if
1744    INSERT_AFTER is true or before it otherwise.  */
1745
1746 static void
1747 init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
1748                         bool insert_after)
1749
1750 {
1751   struct access *child;
1752
1753   if (access->grp_to_be_replaced)
1754     {
1755       gimple stmt;
1756
1757       stmt = gimple_build_assign (get_access_replacement (access),
1758                                   fold_convert (access->type,
1759                                                 integer_zero_node));
1760       if (insert_after)
1761         gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
1762       else
1763         gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1764       update_stmt (stmt);
1765     }
1766
1767   for (child = access->first_child; child; child = child->next_sibling)
1768     init_subtree_with_zero (child, gsi, insert_after);
1769 }
1770
1771 /* Search for an access representative for the given expression EXPR and
1772    return it or NULL if it cannot be found.  */
1773
1774 static struct access *
1775 get_access_for_expr (tree expr)
1776 {
1777   HOST_WIDE_INT offset, size, max_size;
1778   tree base;
1779
1780   /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
1781      a different size than the size of its argument and we need the latter
1782      one.  */
1783   if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
1784     expr = TREE_OPERAND (expr, 0);
1785
1786   base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
1787   if (max_size == -1 || !DECL_P (base))
1788     return NULL;
1789
1790   if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
1791     return NULL;
1792
1793   return get_var_base_offset_size_access (base, offset, max_size);
1794 }
1795
1796 /* Callback for scan_function.  Replace the expression EXPR with a scalar
1797    replacement if there is one and generate other statements to do type
1798    conversion or subtree copying if necessary.  GSI is used to place newly
1799    created statements, WRITE is true if the expression is being written to (it
1800    is on a LHS of a statement or output in an assembly statement).  */
1801
1802 static bool
1803 sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write,
1804                  void *data ATTRIBUTE_UNUSED)
1805 {
1806   struct access *access;
1807   tree type, bfr;
1808
1809   if (TREE_CODE (*expr) == BIT_FIELD_REF)
1810     {
1811       bfr = *expr;
1812       expr = &TREE_OPERAND (*expr, 0);
1813     }
1814   else
1815     bfr = NULL_TREE;
1816
1817   if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
1818     expr = &TREE_OPERAND (*expr, 0);
1819   access = get_access_for_expr (*expr);
1820   if (!access)
1821     return false;
1822   type = TREE_TYPE (*expr);
1823
1824   if (access->grp_to_be_replaced)
1825     {
1826       tree repl = get_access_replacement (access);
1827       /* If we replace a non-register typed access simply use the original
1828          access expression to extract the scalar component afterwards.
1829          This happens if scalarizing a function return value or parameter
1830          like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
1831          gcc.c-torture/compile/20011217-1.c.  */
1832       if (!is_gimple_reg_type (type))
1833         {
1834           gimple stmt;
1835           if (write)
1836             {
1837               tree ref = unshare_expr (access->expr);
1838               if (access->grp_partial_lhs)
1839                 ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
1840                                                  false, GSI_NEW_STMT);
1841               stmt = gimple_build_assign (repl, ref);
1842               gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
1843             }
1844           else
1845             {
1846               if (access->grp_partial_lhs)
1847                 repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
1848                                                  true, GSI_SAME_STMT);
1849               stmt = gimple_build_assign (unshare_expr (access->expr), repl);
1850               gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1851             }
1852         }
1853       else
1854         {
1855           gcc_assert (useless_type_conversion_p (type, access->type));
1856           *expr = repl;
1857         }
1858     }
1859
1860   if (access->first_child)
1861     {
1862       HOST_WIDE_INT start_offset, chunk_size;
1863       if (bfr
1864           && host_integerp (TREE_OPERAND (bfr, 1), 1)
1865           && host_integerp (TREE_OPERAND (bfr, 2), 1))
1866         {
1867           start_offset = tree_low_cst (TREE_OPERAND (bfr, 1), 1);
1868           chunk_size = tree_low_cst (TREE_OPERAND (bfr, 2), 1);
1869         }
1870       else
1871         start_offset = chunk_size = 0;
1872
1873       generate_subtree_copies (access->first_child, access->base, 0,
1874                                start_offset, chunk_size, gsi, write, write);
1875     }
1876   return true;
1877 }
1878
1879 /* Store all replacements in the access tree rooted in TOP_RACC either to their
1880    base aggregate if there are unscalarized data or directly to LHS
1881    otherwise.  */
1882
1883 static void
1884 handle_unscalarized_data_in_subtree (struct access *top_racc, tree lhs,
1885                                      gimple_stmt_iterator *gsi)
1886 {
1887   if (top_racc->grp_unscalarized_data)
1888     generate_subtree_copies (top_racc->first_child, top_racc->base, 0, 0, 0,
1889                              gsi, false, false);
1890   else
1891     generate_subtree_copies (top_racc->first_child, lhs, top_racc->offset,
1892                              0, 0, gsi, false, false);
1893 }
1894
1895
1896 /* Try to generate statements to load all sub-replacements in an access
1897    (sub)tree (LACC is the first child) from scalar replacements in the TOP_RACC
1898    (sub)tree.  If that is not possible, refresh the TOP_RACC base aggregate and
1899    load the accesses from it.  LEFT_OFFSET is the offset of the left whole
1900    subtree being copied, RIGHT_OFFSET is the same thing for the right subtree.
1901    GSI is stmt iterator used for statement insertions.  *REFRESHED is true iff
1902    the rhs top aggregate has already been refreshed by contents of its scalar
1903    reductions and is set to true if this function has to do it.  */
1904
1905 static void
1906 load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
1907                                  HOST_WIDE_INT left_offset,
1908                                  HOST_WIDE_INT right_offset,
1909                                  gimple_stmt_iterator *old_gsi,
1910                                  gimple_stmt_iterator *new_gsi,
1911                                  bool *refreshed, tree lhs)
1912 {
1913   do
1914     {
1915       if (lacc->grp_to_be_replaced)
1916         {
1917           struct access *racc;
1918           HOST_WIDE_INT offset = lacc->offset - left_offset + right_offset;
1919           gimple stmt;
1920           tree rhs;
1921
1922           racc = find_access_in_subtree (top_racc, offset, lacc->size);
1923           if (racc && racc->grp_to_be_replaced)
1924             {
1925               rhs = get_access_replacement (racc);
1926               if (!useless_type_conversion_p (lacc->type, racc->type))
1927                 rhs = fold_build1 (VIEW_CONVERT_EXPR, lacc->type, rhs);
1928             }
1929           else
1930             {
1931               bool repl_found;
1932
1933               /* No suitable access on the right hand side, need to load from
1934                  the aggregate.  See if we have to update it first... */
1935               if (!*refreshed)
1936                 {
1937                   gcc_assert (top_racc->first_child);
1938                   handle_unscalarized_data_in_subtree (top_racc, lhs, old_gsi);
1939                   *refreshed = true;
1940                 }
1941
1942               rhs = unshare_expr (top_racc->base);
1943               repl_found = build_ref_for_offset (&rhs,
1944                                                  TREE_TYPE (top_racc->base),
1945                                                  lacc->offset - left_offset,
1946                                                  lacc->type, false);
1947               gcc_assert (repl_found);
1948             }
1949
1950           stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
1951           gsi_insert_after (new_gsi, stmt, GSI_NEW_STMT);
1952           update_stmt (stmt);
1953         }
1954       else if (lacc->grp_read && !lacc->grp_covered && !*refreshed)
1955         {
1956           handle_unscalarized_data_in_subtree (top_racc, lhs, old_gsi);
1957           *refreshed = true;
1958         }
1959
1960       if (lacc->first_child)
1961         load_assign_lhs_subreplacements (lacc->first_child, top_racc,
1962                                          left_offset, right_offset,
1963                                          old_gsi, new_gsi, refreshed, lhs);
1964       lacc = lacc->next_sibling;
1965     }
1966   while (lacc);
1967 }
1968
1969 /* Modify assignments with a CONSTRUCTOR on their RHS.  STMT contains a pointer
1970    to the assignment and GSI is the statement iterator pointing at it.  Returns
1971    the same values as sra_modify_assign.  */
1972
1973 static enum scan_assign_result
1974 sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
1975 {
1976   tree lhs = gimple_assign_lhs (*stmt);
1977   struct access *acc;
1978
1979   acc = get_access_for_expr (lhs);
1980   if (!acc)
1981     return SRA_SA_NONE;
1982
1983   if (VEC_length (constructor_elt,
1984                   CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt))) > 0)
1985     {
1986       /* I have never seen this code path trigger but if it can happen the
1987          following should handle it gracefully.  */
1988       if (access_has_children_p (acc))
1989         generate_subtree_copies (acc->first_child, acc->base, 0, 0, 0, gsi,
1990                                  true, true);
1991       return SRA_SA_PROCESSED;
1992     }
1993
1994   if (acc->grp_covered)
1995     {
1996       init_subtree_with_zero (acc, gsi, false);
1997       unlink_stmt_vdef (*stmt);
1998       gsi_remove (gsi, true);
1999       return SRA_SA_REMOVED;
2000     }
2001   else
2002     {
2003       init_subtree_with_zero (acc, gsi, true);
2004       return SRA_SA_PROCESSED;
2005     }
2006 }
2007
2008
2009 /* Callback of scan_function to process assign statements.  It examines both
2010    sides of the statement, replaces them with a scalare replacement if there is
2011    one and generating copying of replacements if scalarized aggregates have been
2012    used in the assignment.  STMT is a pointer to the assign statement, GSI is
2013    used to hold generated statements for type conversions and subtree
2014    copying.  */
2015
2016 static enum scan_assign_result
2017 sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi,
2018                    void *data ATTRIBUTE_UNUSED)
2019 {
2020   struct access *lacc, *racc;
2021   tree lhs, rhs;
2022   bool modify_this_stmt = false;
2023   bool force_gimple_rhs = false;
2024
2025   if (!gimple_assign_single_p (*stmt))
2026     return SRA_SA_NONE;
2027   lhs = gimple_assign_lhs (*stmt);
2028   rhs = gimple_assign_rhs1 (*stmt);
2029
2030   if (TREE_CODE (rhs) == CONSTRUCTOR)
2031     return sra_modify_constructor_assign (stmt, gsi);
2032
2033   if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
2034       || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
2035       || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
2036     {
2037       modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (*stmt),
2038                                           gsi, false, data);
2039       modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (*stmt),
2040                                            gsi, true, data);
2041       return modify_this_stmt ? SRA_SA_PROCESSED : SRA_SA_NONE;
2042     }
2043
2044   lacc = get_access_for_expr (lhs);
2045   racc = get_access_for_expr (rhs);
2046   if (!lacc && !racc)
2047     return SRA_SA_NONE;
2048
2049   if (lacc && lacc->grp_to_be_replaced)
2050     {
2051       lhs = get_access_replacement (lacc);
2052       gimple_assign_set_lhs (*stmt, lhs);
2053       modify_this_stmt = true;
2054       if (lacc->grp_partial_lhs)
2055         force_gimple_rhs = true;
2056     }
2057
2058   if (racc && racc->grp_to_be_replaced)
2059     {
2060       rhs = get_access_replacement (racc);
2061       modify_this_stmt = true;
2062       if (racc->grp_partial_lhs)
2063         force_gimple_rhs = true;
2064     }
2065
2066   if (modify_this_stmt)
2067     {
2068       if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
2069         {
2070           /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
2071              ???  This should move to fold_stmt which we simply should
2072              call after building a VIEW_CONVERT_EXPR here.  */
2073           if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
2074               && !access_has_children_p (lacc))
2075             {
2076               tree expr = unshare_expr (lhs);
2077               if (build_ref_for_offset (&expr, TREE_TYPE (lhs), racc->offset,
2078                                         TREE_TYPE (rhs), false))
2079                 {
2080                   lhs = expr;
2081                   gimple_assign_set_lhs (*stmt, expr);
2082                 }
2083             }
2084           else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
2085                    && !access_has_children_p (racc))
2086             {
2087               tree expr = unshare_expr (rhs);
2088               if (build_ref_for_offset (&expr, TREE_TYPE (rhs), lacc->offset,
2089                                         TREE_TYPE (lhs), false))
2090                 rhs = expr;
2091             }
2092           if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
2093             rhs = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs);
2094         }
2095
2096       if (force_gimple_rhs)
2097         rhs = force_gimple_operand_gsi (gsi, rhs, true, NULL_TREE,
2098                                         true, GSI_SAME_STMT);
2099       if (gimple_assign_rhs1 (*stmt) != rhs)
2100         {
2101           gimple_assign_set_rhs_from_tree (gsi, rhs);
2102           gcc_assert (*stmt == gsi_stmt (*gsi));
2103         }
2104     }
2105
2106   /* From this point on, the function deals with assignments in between
2107      aggregates when at least one has scalar reductions of some of its
2108      components.  There are three possible scenarios: Both the LHS and RHS have
2109      to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
2110
2111      In the first case, we would like to load the LHS components from RHS
2112      components whenever possible.  If that is not possible, we would like to
2113      read it directly from the RHS (after updating it by storing in it its own
2114      components).  If there are some necessary unscalarized data in the LHS,
2115      those will be loaded by the original assignment too.  If neither of these
2116      cases happen, the original statement can be removed.  Most of this is done
2117      by load_assign_lhs_subreplacements.
2118
2119      In the second case, we would like to store all RHS scalarized components
2120      directly into LHS and if they cover the aggregate completely, remove the
2121      statement too.  In the third case, we want the LHS components to be loaded
2122      directly from the RHS (DSE will remove the original statement if it
2123      becomes redundant).
2124
2125      This is a bit complex but manageable when types match and when unions do
2126      not cause confusion in a way that we cannot really load a component of LHS
2127      from the RHS or vice versa (the access representing this level can have
2128      subaccesses that are accessible only through a different union field at a
2129      higher level - different from the one used in the examined expression).
2130      Unions are fun.
2131
2132      Therefore, I specially handle a fourth case, happening when there is a
2133      specific type cast or it is impossible to locate a scalarized subaccess on
2134      the other side of the expression.  If that happens, I simply "refresh" the
2135      RHS by storing in it is scalarized components leave the original statement
2136      there to do the copying and then load the scalar replacements of the LHS.
2137      This is what the first branch does.  */
2138
2139   if (contains_view_convert_expr_p (rhs) || contains_view_convert_expr_p (lhs)
2140       || (access_has_children_p (racc)
2141           && !ref_expr_for_all_replacements_p (racc, lhs, racc->offset))
2142       || (access_has_children_p (lacc)
2143           && !ref_expr_for_all_replacements_p (lacc, rhs, lacc->offset)))
2144     {
2145       if (access_has_children_p (racc))
2146         generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
2147                                  gsi, false, false);
2148       if (access_has_children_p (lacc))
2149         generate_subtree_copies (lacc->first_child, lacc->base, 0, 0, 0,
2150                                  gsi, true, true);
2151     }
2152   else
2153     {
2154       if (access_has_children_p (lacc) && access_has_children_p (racc))
2155         {
2156           gimple_stmt_iterator orig_gsi = *gsi;
2157           bool refreshed;
2158
2159           if (lacc->grp_read && !lacc->grp_covered)
2160             {
2161               handle_unscalarized_data_in_subtree (racc, lhs, gsi);
2162               refreshed = true;
2163             }
2164           else
2165             refreshed = false;
2166
2167           load_assign_lhs_subreplacements (lacc->first_child, racc,
2168                                            lacc->offset, racc->offset,
2169                                            &orig_gsi, gsi, &refreshed, lhs);
2170           if (!refreshed || !racc->grp_unscalarized_data)
2171             {
2172               if (*stmt == gsi_stmt (*gsi))
2173                 gsi_next (gsi);
2174
2175               unlink_stmt_vdef (*stmt);
2176               gsi_remove (&orig_gsi, true);
2177               return SRA_SA_REMOVED;
2178             }
2179         }
2180       else
2181         {
2182           if (access_has_children_p (racc))
2183             {
2184               if (!racc->grp_unscalarized_data)
2185                 {
2186                   generate_subtree_copies (racc->first_child, lhs,
2187                                            racc->offset, 0, 0, gsi,
2188                                            false, false);
2189                   gcc_assert (*stmt == gsi_stmt (*gsi));
2190                   unlink_stmt_vdef (*stmt);
2191                   gsi_remove (gsi, true);
2192                   return SRA_SA_REMOVED;
2193                 }
2194               else
2195                 generate_subtree_copies (racc->first_child, lhs,
2196                                          racc->offset, 0, 0, gsi, false, true);
2197             }
2198           else if (access_has_children_p (lacc))
2199             generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
2200                                      0, 0, gsi, true, true);
2201         }
2202     }
2203   return modify_this_stmt ? SRA_SA_PROCESSED : SRA_SA_NONE;
2204 }
2205
2206 /* Generate statements initializing scalar replacements of parts of function
2207    parameters.  */
2208
2209 static void
2210 initialize_parameter_reductions (void)
2211 {
2212   gimple_stmt_iterator gsi;
2213   gimple_seq seq = NULL;
2214   tree parm;
2215
2216   for (parm = DECL_ARGUMENTS (current_function_decl);
2217        parm;
2218        parm = TREE_CHAIN (parm))
2219     {
2220       VEC (access_p, heap) *access_vec;
2221       struct access *access;
2222
2223       if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
2224         continue;
2225       access_vec = get_base_access_vector (parm);
2226       if (!access_vec)
2227         continue;
2228
2229       if (!seq)
2230         {
2231           seq = gimple_seq_alloc ();
2232           gsi = gsi_start (seq);
2233         }
2234
2235       for (access = VEC_index (access_p, access_vec, 0);
2236            access;
2237            access = access->next_grp)
2238         generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true);
2239     }
2240
2241   if (seq)
2242     gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR), seq);
2243 }
2244
2245 /* The "main" function of intraprocedural SRA passes.  Runs the analysis and if
2246    it reveals there are components of some aggregates to be scalarized, it runs
2247    the required transformations.  */
2248 static unsigned int
2249 perform_intra_sra (void)
2250 {
2251   int ret = 0;
2252   sra_initialize ();
2253
2254   if (!find_var_candidates ())
2255     goto out;
2256
2257   if (!scan_function (build_access_from_expr, build_accesses_from_assign, NULL,
2258                       true, NULL))
2259     goto out;
2260
2261   if (!analyze_all_variable_accesses ())
2262     goto out;
2263
2264   scan_function (sra_modify_expr, sra_modify_assign, NULL,
2265                  false, NULL);
2266   initialize_parameter_reductions ();
2267   ret = TODO_update_ssa;
2268
2269  out:
2270   sra_deinitialize ();
2271   return ret;
2272 }
2273
2274 /* Perform early intraprocedural SRA.  */
2275 static unsigned int
2276 early_intra_sra (void)
2277 {
2278   sra_mode = SRA_MODE_EARLY_INTRA;
2279   return perform_intra_sra ();
2280 }
2281
2282 /* Perform "late" intraprocedural SRA.  */
2283 static unsigned int
2284 late_intra_sra (void)
2285 {
2286   sra_mode = SRA_MODE_INTRA;
2287   return perform_intra_sra ();
2288 }
2289
2290
2291 static bool
2292 gate_intra_sra (void)
2293 {
2294   return flag_tree_sra != 0;
2295 }
2296
2297
2298 struct gimple_opt_pass pass_sra_early =
2299 {
2300  {
2301   GIMPLE_PASS,
2302   "esra",                               /* name */
2303   gate_intra_sra,                       /* gate */
2304   early_intra_sra,                      /* execute */
2305   NULL,                                 /* sub */
2306   NULL,                                 /* next */
2307   0,                                    /* static_pass_number */
2308   TV_TREE_SRA,                          /* tv_id */
2309   PROP_cfg | PROP_ssa,                  /* properties_required */
2310   0,                                    /* properties_provided */
2311   0,                                    /* properties_destroyed */
2312   0,                                    /* todo_flags_start */
2313   TODO_dump_func
2314   | TODO_update_ssa
2315   | TODO_ggc_collect
2316   | TODO_verify_ssa                     /* todo_flags_finish */
2317  }
2318 };
2319
2320
2321 struct gimple_opt_pass pass_sra =
2322 {
2323  {
2324   GIMPLE_PASS,
2325   "sra",                                /* name */
2326   gate_intra_sra,                       /* gate */
2327   late_intra_sra,                       /* execute */
2328   NULL,                                 /* sub */
2329   NULL,                                 /* next */
2330   0,                                    /* static_pass_number */
2331   TV_TREE_SRA,                          /* tv_id */
2332   PROP_cfg | PROP_ssa,                  /* properties_required */
2333   0,                                    /* properties_provided */
2334   0,                                    /* properties_destroyed */
2335   TODO_update_address_taken,            /* todo_flags_start */
2336   TODO_dump_func
2337   | TODO_update_ssa
2338   | TODO_ggc_collect
2339   | TODO_verify_ssa                     /* todo_flags_finish */
2340  }
2341 };