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