OSDN Git Service

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