00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "config.h"
00026 #include "system.h"
00027 #include "coretypes.h"
00028 #include "tm.h"
00029 #include "ggc.h"
00030 #include "tree.h"
00031
00032
00033 #include "rtl.h"
00034 #include "tm_p.h"
00035 #include "hard-reg-set.h"
00036 #include "basic-block.h"
00037 #include "diagnostic.h"
00038 #include "langhooks.h"
00039 #include "tree-inline.h"
00040 #include "tree-flow.h"
00041 #include "tree-gimple.h"
00042 #include "tree-dump.h"
00043 #include "tree-pass.h"
00044 #include "timevar.h"
00045 #include "flags.h"
00046 #include "bitmap.h"
00047 #include "obstack.h"
00048 #include "target.h"
00049
00050 #include "expr.h"
00051 #include "params.h"
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 static unsigned int todoflags;
00081
00082
00083 static bitmap sra_candidates;
00084
00085
00086
00087 static bitmap needs_copy_in;
00088
00089
00090 static bitmap sra_type_decomp_cache;
00091 static bitmap sra_type_inst_cache;
00092
00093
00094
00095 struct sra_elt
00096 {
00097
00098 struct sra_elt *parent;
00099 struct sra_elt *groups;
00100 struct sra_elt *children;
00101 struct sra_elt *sibling;
00102
00103
00104
00105
00106
00107
00108
00109 tree element;
00110
00111
00112 tree type;
00113
00114
00115 tree replacement;
00116
00117
00118
00119 unsigned int n_uses;
00120
00121
00122
00123 unsigned int n_copies;
00124
00125
00126 bool is_scalar;
00127
00128
00129 bool is_group;
00130
00131
00132
00133 bool cannot_scalarize;
00134
00135
00136
00137 bool use_block_copy;
00138
00139
00140 bool all_no_warning;
00141
00142
00143 bool visited;
00144 };
00145
00146 #define IS_ELEMENT_FOR_GROUP(ELEMENT) (TREE_CODE (ELEMENT) == RANGE_EXPR)
00147
00148 #define FOR_EACH_ACTUAL_CHILD(CHILD, ELT) \
00149 for ((CHILD) = (ELT)->is_group \
00150 ? next_child_for_group (NULL, (ELT)) \
00151 : (ELT)->children; \
00152 (CHILD); \
00153 (CHILD) = (ELT)->is_group \
00154 ? next_child_for_group ((CHILD), (ELT)) \
00155 : (CHILD)->sibling)
00156
00157
00158 static struct sra_elt *
00159 next_child_for_group (struct sra_elt *child, struct sra_elt *group)
00160 {
00161 gcc_assert (group->is_group);
00162
00163
00164 if (child)
00165 child = child->sibling;
00166 else
00167 child = group->parent->children;
00168
00169
00170 while (child)
00171 {
00172 tree g_elt = group->element;
00173 if (TREE_CODE (g_elt) == RANGE_EXPR)
00174 {
00175 if (!tree_int_cst_lt (child->element, TREE_OPERAND (g_elt, 0))
00176 && !tree_int_cst_lt (TREE_OPERAND (g_elt, 1), child->element))
00177 break;
00178 }
00179 else
00180 gcc_unreachable ();
00181
00182 child = child->sibling;
00183 }
00184
00185 return child;
00186 }
00187
00188
00189
00190
00191 static htab_t sra_map;
00192
00193
00194 static struct obstack sra_obstack;
00195
00196
00197 static void dump_sra_elt_name (FILE *, struct sra_elt *);
00198 extern void debug_sra_elt_name (struct sra_elt *);
00199
00200
00201 static tree generate_element_ref (struct sra_elt *);
00202
00203
00204
00205 static bool
00206 is_sra_candidate_decl (tree decl)
00207 {
00208 return DECL_P (decl) && bitmap_bit_p (sra_candidates, DECL_UID (decl));
00209 }
00210
00211
00212
00213 static bool
00214 is_sra_scalar_type (tree type)
00215 {
00216 enum tree_code code = TREE_CODE (type);
00217 return (code == INTEGER_TYPE || code == REAL_TYPE || code == VECTOR_TYPE
00218 || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE
00219 || code == POINTER_TYPE || code == OFFSET_TYPE
00220 || code == REFERENCE_TYPE);
00221 }
00222
00223
00224
00225
00226
00227
00228
00229 bool
00230 sra_type_can_be_decomposed_p (tree type)
00231 {
00232 unsigned int cache = TYPE_UID (TYPE_MAIN_VARIANT (type)) * 2;
00233 tree t;
00234
00235
00236 if (bitmap_bit_p (sra_type_decomp_cache, cache+0))
00237 return true;
00238 if (bitmap_bit_p (sra_type_decomp_cache, cache+1))
00239 return false;
00240
00241
00242 if (TYPE_SIZE (type) == NULL || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
00243 || integer_zerop (TYPE_SIZE (type)))
00244 goto fail;
00245
00246
00247 switch (TREE_CODE (type))
00248 {
00249 case RECORD_TYPE:
00250 {
00251 bool saw_one_field = false;
00252
00253 for (t = TYPE_FIELDS (type); t ; t = TREE_CHAIN (t))
00254 if (TREE_CODE (t) == FIELD_DECL)
00255 {
00256
00257 if (DECL_BIT_FIELD (t)
00258 && (tree_low_cst (DECL_SIZE (t), 1)
00259 != TYPE_PRECISION (TREE_TYPE (t))))
00260 goto fail;
00261
00262 saw_one_field = true;
00263 }
00264
00265
00266 if (!saw_one_field)
00267 goto fail;
00268 }
00269 break;
00270
00271 case ARRAY_TYPE:
00272
00273 t = TYPE_DOMAIN (type);
00274 if (t == NULL)
00275 goto fail;
00276 if (TYPE_MIN_VALUE (t) == NULL || !TREE_CONSTANT (TYPE_MIN_VALUE (t)))
00277 goto fail;
00278 if (TYPE_MAX_VALUE (t) == NULL || !TREE_CONSTANT (TYPE_MAX_VALUE (t)))
00279 goto fail;
00280 break;
00281
00282 case COMPLEX_TYPE:
00283 break;
00284
00285 default:
00286 goto fail;
00287 }
00288
00289 bitmap_set_bit (sra_type_decomp_cache, cache+0);
00290 return true;
00291
00292 fail:
00293 bitmap_set_bit (sra_type_decomp_cache, cache+1);
00294 return false;
00295 }
00296
00297
00298
00299
00300 static bool
00301 decl_can_be_decomposed_p (tree var)
00302 {
00303
00304 if (is_sra_scalar_type (TREE_TYPE (var)))
00305 return false;
00306
00307
00308 if (!is_gimple_non_addressable (var))
00309 {
00310 if (dump_file && (dump_flags & TDF_DETAILS))
00311 {
00312 fprintf (dump_file, "Cannot scalarize variable ");
00313 print_generic_expr (dump_file, var, dump_flags);
00314 fprintf (dump_file, " because it must live in memory\n");
00315 }
00316 return false;
00317 }
00318
00319
00320 if (TREE_THIS_VOLATILE (var))
00321 {
00322 if (dump_file && (dump_flags & TDF_DETAILS))
00323 {
00324 fprintf (dump_file, "Cannot scalarize variable ");
00325 print_generic_expr (dump_file, var, dump_flags);
00326 fprintf (dump_file, " because it is declared volatile\n");
00327 }
00328 return false;
00329 }
00330
00331
00332 if (!sra_type_can_be_decomposed_p (TREE_TYPE (var)))
00333 {
00334 if (dump_file && (dump_flags & TDF_DETAILS))
00335 {
00336 fprintf (dump_file, "Cannot scalarize variable ");
00337 print_generic_expr (dump_file, var, dump_flags);
00338 fprintf (dump_file, " because its type cannot be decomposed\n");
00339 }
00340 return false;
00341 }
00342
00343 return true;
00344 }
00345
00346
00347
00348 static bool
00349 type_can_instantiate_all_elements (tree type)
00350 {
00351 if (is_sra_scalar_type (type))
00352 return true;
00353 if (!sra_type_can_be_decomposed_p (type))
00354 return false;
00355
00356 switch (TREE_CODE (type))
00357 {
00358 case RECORD_TYPE:
00359 {
00360 unsigned int cache = TYPE_UID (TYPE_MAIN_VARIANT (type)) * 2;
00361 tree f;
00362
00363 if (bitmap_bit_p (sra_type_inst_cache, cache+0))
00364 return true;
00365 if (bitmap_bit_p (sra_type_inst_cache, cache+1))
00366 return false;
00367
00368 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
00369 if (TREE_CODE (f) == FIELD_DECL)
00370 {
00371 if (!type_can_instantiate_all_elements (TREE_TYPE (f)))
00372 {
00373 bitmap_set_bit (sra_type_inst_cache, cache+1);
00374 return false;
00375 }
00376 }
00377
00378 bitmap_set_bit (sra_type_inst_cache, cache+0);
00379 return true;
00380 }
00381
00382 case ARRAY_TYPE:
00383 return type_can_instantiate_all_elements (TREE_TYPE (type));
00384
00385 case COMPLEX_TYPE:
00386 return true;
00387
00388 default:
00389 gcc_unreachable ();
00390 }
00391 }
00392
00393
00394
00395 static bool
00396 can_completely_scalarize_p (struct sra_elt *elt)
00397 {
00398 struct sra_elt *c;
00399
00400 if (elt->cannot_scalarize)
00401 return false;
00402
00403 for (c = elt->children; c; c = c->sibling)
00404 if (!can_completely_scalarize_p (c))
00405 return false;
00406
00407 for (c = elt->groups; c; c = c->sibling)
00408 if (!can_completely_scalarize_p (c))
00409 return false;
00410
00411 return true;
00412 }
00413
00414
00415
00416
00417
00418 static hashval_t
00419 sra_hash_tree (tree t)
00420 {
00421 hashval_t h;
00422
00423 switch (TREE_CODE (t))
00424 {
00425 case VAR_DECL:
00426 case PARM_DECL:
00427 case RESULT_DECL:
00428 h = DECL_UID (t);
00429 break;
00430
00431 case INTEGER_CST:
00432 h = TREE_INT_CST_LOW (t) ^ TREE_INT_CST_HIGH (t);
00433 break;
00434
00435 case RANGE_EXPR:
00436 h = iterative_hash_expr (TREE_OPERAND (t, 0), 0);
00437 h = iterative_hash_expr (TREE_OPERAND (t, 1), h);
00438 break;
00439
00440 case FIELD_DECL:
00441
00442
00443 h = iterative_hash_expr (DECL_FIELD_OFFSET (t), 0);
00444 h = iterative_hash_expr (DECL_FIELD_BIT_OFFSET (t), h);
00445 break;
00446
00447 default:
00448 gcc_unreachable ();
00449 }
00450
00451 return h;
00452 }
00453
00454
00455
00456 static hashval_t
00457 sra_elt_hash (const void *x)
00458 {
00459 const struct sra_elt *e = x;
00460 const struct sra_elt *p;
00461 hashval_t h;
00462
00463 h = sra_hash_tree (e->element);
00464
00465
00466
00467
00468
00469 for (p = e->parent; p ; p = p->parent)
00470 h = (h * 65521) ^ sra_hash_tree (p->element);
00471
00472 return h;
00473 }
00474
00475
00476
00477 static int
00478 sra_elt_eq (const void *x, const void *y)
00479 {
00480 const struct sra_elt *a = x;
00481 const struct sra_elt *b = y;
00482 tree ae, be;
00483
00484 if (a->parent != b->parent)
00485 return false;
00486
00487 ae = a->element;
00488 be = b->element;
00489
00490 if (ae == be)
00491 return true;
00492 if (TREE_CODE (ae) != TREE_CODE (be))
00493 return false;
00494
00495 switch (TREE_CODE (ae))
00496 {
00497 case VAR_DECL:
00498 case PARM_DECL:
00499 case RESULT_DECL:
00500
00501 return false;
00502
00503 case INTEGER_CST:
00504
00505 return tree_int_cst_equal (ae, be);
00506
00507 case RANGE_EXPR:
00508 return
00509 tree_int_cst_equal (TREE_OPERAND (ae, 0), TREE_OPERAND (be, 0))
00510 && tree_int_cst_equal (TREE_OPERAND (ae, 1), TREE_OPERAND (be, 1));
00511
00512 case FIELD_DECL:
00513
00514
00515 if (DECL_FIELD_CONTEXT (ae) == DECL_FIELD_CONTEXT (be))
00516 return false;
00517 return fields_compatible_p (ae, be);
00518
00519 default:
00520 gcc_unreachable ();
00521 }
00522 }
00523
00524
00525
00526
00527 static struct sra_elt *
00528 lookup_element (struct sra_elt *parent, tree child, tree type,
00529 enum insert_option insert)
00530 {
00531 struct sra_elt dummy;
00532 struct sra_elt **slot;
00533 struct sra_elt *elt;
00534
00535 if (parent)
00536 dummy.parent = parent->is_group ? parent->parent : parent;
00537 else
00538 dummy.parent = NULL;
00539 dummy.element = child;
00540
00541 slot = (struct sra_elt **) htab_find_slot (sra_map, &dummy, insert);
00542 if (!slot && insert == NO_INSERT)
00543 return NULL;
00544
00545 elt = *slot;
00546 if (!elt && insert == INSERT)
00547 {
00548 *slot = elt = obstack_alloc (&sra_obstack, sizeof (*elt));
00549 memset (elt, 0, sizeof (*elt));
00550
00551 elt->parent = parent;
00552 elt->element = child;
00553 elt->type = type;
00554 elt->is_scalar = is_sra_scalar_type (type);
00555
00556 if (parent)
00557 {
00558 if (IS_ELEMENT_FOR_GROUP (elt->element))
00559 {
00560 elt->is_group = true;
00561 elt->sibling = parent->groups;
00562 parent->groups = elt;
00563 }
00564 else
00565 {
00566 elt->sibling = parent->children;
00567 parent->children = elt;
00568 }
00569 }
00570
00571
00572
00573 if (TREE_CODE (child) == PARM_DECL)
00574 {
00575 elt->n_copies = 1;
00576 bitmap_set_bit (needs_copy_in, DECL_UID (child));
00577 }
00578 }
00579
00580 return elt;
00581 }
00582
00583
00584
00585
00586 static struct sra_elt *
00587 maybe_lookup_element_for_expr (tree expr)
00588 {
00589 struct sra_elt *elt;
00590 tree child;
00591
00592 switch (TREE_CODE (expr))
00593 {
00594 case VAR_DECL:
00595 case PARM_DECL:
00596 case RESULT_DECL:
00597 if (is_sra_candidate_decl (expr))
00598 return lookup_element (NULL, expr, TREE_TYPE (expr), INSERT);
00599 return NULL;
00600
00601 case ARRAY_REF:
00602
00603 if (in_array_bounds_p (expr))
00604 child = TREE_OPERAND (expr, 1);
00605 else
00606 return NULL;
00607 break;
00608
00609 case ARRAY_RANGE_REF:
00610
00611 if (range_in_array_bounds_p (expr))
00612 {
00613 tree domain = TYPE_DOMAIN (TREE_TYPE (expr));
00614 child = build2 (RANGE_EXPR, integer_type_node,
00615 TYPE_MIN_VALUE (domain), TYPE_MAX_VALUE (domain));
00616 }
00617 else
00618 return NULL;
00619 break;
00620
00621 case COMPONENT_REF:
00622
00623 if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) != RECORD_TYPE)
00624 return NULL;
00625 child = TREE_OPERAND (expr, 1);
00626 break;
00627
00628 case REALPART_EXPR:
00629 child = integer_zero_node;
00630 break;
00631 case IMAGPART_EXPR:
00632 child = integer_one_node;
00633 break;
00634
00635 default:
00636 return NULL;
00637 }
00638
00639 elt = maybe_lookup_element_for_expr (TREE_OPERAND (expr, 0));
00640 if (elt)
00641 return lookup_element (elt, child, TREE_TYPE (expr), INSERT);
00642 return NULL;
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
00652 struct sra_walk_fns
00653 {
00654
00655
00656
00657
00658
00659 void (*use) (struct sra_elt *elt, tree *expr_p,
00660 block_stmt_iterator *bsi, bool is_output, bool use_all);
00661
00662
00663 void (*copy) (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
00664 block_stmt_iterator *bsi);
00665
00666
00667
00668 void (*init) (struct sra_elt *elt, tree value, block_stmt_iterator *bsi);
00669
00670
00671
00672
00673 void (*ldst) (struct sra_elt *elt, tree other,
00674 block_stmt_iterator *bsi, bool is_output);
00675
00676
00677
00678 bool initial_scan;
00679 };
00680
00681 #ifdef ENABLE_CHECKING
00682
00683
00684 static tree
00685 sra_find_candidate_decl (tree *tp, int *walk_subtrees,
00686 void *data ATTRIBUTE_UNUSED)
00687 {
00688 tree t = *tp;
00689 enum tree_code code = TREE_CODE (t);
00690
00691 if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
00692 {
00693 *walk_subtrees = 0;
00694 if (is_sra_candidate_decl (t))
00695 return t;
00696 }
00697 else if (TYPE_P (t))
00698 *walk_subtrees = 0;
00699
00700 return NULL;
00701 }
00702 #endif
00703
00704
00705
00706
00707 static void
00708 sra_walk_expr (tree *expr_p, block_stmt_iterator *bsi, bool is_output,
00709 const struct sra_walk_fns *fns)
00710 {
00711 tree expr = *expr_p;
00712 tree inner = expr;
00713 bool disable_scalarization = false;
00714 bool use_all_p = false;
00715
00716
00717
00718
00719
00720
00721
00722 while (1)
00723 switch (TREE_CODE (inner))
00724 {
00725 case VAR_DECL:
00726 case PARM_DECL:
00727 case RESULT_DECL:
00728
00729 if (is_sra_candidate_decl (inner))
00730 {
00731 struct sra_elt *elt = maybe_lookup_element_for_expr (expr);
00732 if (disable_scalarization)
00733 elt->cannot_scalarize = true;
00734 else
00735 fns->use (elt, expr_p, bsi, is_output, use_all_p);
00736 }
00737 return;
00738
00739 case ARRAY_REF:
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750 if (!in_array_bounds_p (inner))
00751 {
00752 disable_scalarization = true;
00753 goto use_all;
00754 }
00755
00756
00757 if (TREE_OPERAND (inner, 2) || TREE_OPERAND (inner, 3))
00758 goto use_all;
00759 inner = TREE_OPERAND (inner, 0);
00760 break;
00761
00762 case ARRAY_RANGE_REF:
00763 if (!range_in_array_bounds_p (inner))
00764 {
00765 disable_scalarization = true;
00766 goto use_all;
00767 }
00768
00769 if (TREE_OPERAND (inner, 2) || TREE_OPERAND (inner, 3))
00770 goto use_all;
00771 inner = TREE_OPERAND (inner, 0);
00772 break;
00773
00774 case COMPONENT_REF:
00775
00776
00777 if (TREE_CODE (TREE_TYPE (TREE_OPERAND (inner, 0))) != RECORD_TYPE)
00778 goto use_all;
00779
00780 if (TREE_OPERAND (inner, 2))
00781 goto use_all;
00782 inner = TREE_OPERAND (inner, 0);
00783 break;
00784
00785 case REALPART_EXPR:
00786 case IMAGPART_EXPR:
00787 inner = TREE_OPERAND (inner, 0);
00788 break;
00789
00790 case BIT_FIELD_REF:
00791
00792
00793
00794 goto use_all;
00795
00796 case VIEW_CONVERT_EXPR:
00797 case NOP_EXPR:
00798
00799
00800 goto use_all;
00801
00802 case WITH_SIZE_EXPR:
00803
00804
00805 goto use_all;
00806
00807 use_all:
00808 expr_p = &TREE_OPERAND (inner, 0);
00809 inner = expr = *expr_p;
00810 use_all_p = true;
00811 break;
00812
00813 default:
00814 #ifdef ENABLE_CHECKING
00815
00816 gcc_assert (!walk_tree (&inner, sra_find_candidate_decl, NULL, NULL));
00817 #endif
00818 return;
00819 }
00820 }
00821
00822
00823
00824
00825 static void
00826 sra_walk_tree_list (tree list, block_stmt_iterator *bsi, bool is_output,
00827 const struct sra_walk_fns *fns)
00828 {
00829 tree op;
00830 for (op = list; op ; op = TREE_CHAIN (op))
00831 sra_walk_expr (&TREE_VALUE (op), bsi, is_output, fns);
00832 }
00833
00834
00835
00836
00837 static void
00838 sra_walk_call_expr (tree expr, block_stmt_iterator *bsi,
00839 const struct sra_walk_fns *fns)
00840 {
00841 sra_walk_tree_list (TREE_OPERAND (expr, 1), bsi, false, fns);
00842 }
00843
00844
00845
00846
00847 static void
00848 sra_walk_asm_expr (tree expr, block_stmt_iterator *bsi,
00849 const struct sra_walk_fns *fns)
00850 {
00851 sra_walk_tree_list (ASM_INPUTS (expr), bsi, false, fns);
00852 sra_walk_tree_list (ASM_OUTPUTS (expr), bsi, true, fns);
00853 }
00854
00855
00856
00857 static void
00858 sra_walk_modify_expr (tree expr, block_stmt_iterator *bsi,
00859 const struct sra_walk_fns *fns)
00860 {
00861 struct sra_elt *lhs_elt, *rhs_elt;
00862 tree lhs, rhs;
00863
00864 lhs = TREE_OPERAND (expr, 0);
00865 rhs = TREE_OPERAND (expr, 1);
00866 lhs_elt = maybe_lookup_element_for_expr (lhs);
00867 rhs_elt = maybe_lookup_element_for_expr (rhs);
00868
00869
00870 if (lhs_elt && rhs_elt)
00871 {
00872 fns->copy (lhs_elt, rhs_elt, bsi);
00873 return;
00874 }
00875
00876
00877 if (rhs_elt)
00878 {
00879 if (!rhs_elt->is_scalar && !TREE_SIDE_EFFECTS (lhs))
00880 fns->ldst (rhs_elt, lhs, bsi, false);
00881 else
00882 fns->use (rhs_elt, &TREE_OPERAND (expr, 1), bsi, false, false);
00883 }
00884
00885
00886
00887
00888
00889
00890 else
00891 {
00892 tree call = get_call_expr_in (rhs);
00893 if (call)
00894 sra_walk_call_expr (call, bsi, fns);
00895 else
00896 sra_walk_expr (&TREE_OPERAND (expr, 1), bsi, false, fns);
00897 }
00898
00899
00900
00901 if (lhs_elt)
00902 {
00903
00904
00905 if (TREE_CODE (rhs) == COMPLEX_EXPR
00906 || TREE_CODE (rhs) == COMPLEX_CST
00907 || TREE_CODE (rhs) == CONSTRUCTOR)
00908 fns->init (lhs_elt, rhs, bsi);
00909
00910
00911
00912 else if (TREE_CODE (rhs) == VAR_DECL
00913 && TREE_STATIC (rhs)
00914 && TREE_READONLY (rhs)
00915 && targetm.binds_local_p (rhs))
00916 fns->init (lhs_elt, DECL_INITIAL (rhs), bsi);
00917
00918
00919
00920
00921
00922 else if (!lhs_elt->is_scalar
00923 && !TREE_SIDE_EFFECTS (rhs) && is_gimple_addressable (rhs))
00924 fns->ldst (lhs_elt, rhs, bsi, true);
00925
00926
00927
00928 else
00929 fns->use (lhs_elt, &TREE_OPERAND (expr, 0), bsi, true, false);
00930 }
00931
00932
00933
00934
00935 else
00936 sra_walk_expr (&TREE_OPERAND (expr, 0), bsi, true, fns);
00937 }
00938
00939
00940
00941
00942
00943 static void
00944 sra_walk_function (const struct sra_walk_fns *fns)
00945 {
00946 basic_block bb;
00947 block_stmt_iterator si, ni;
00948
00949
00950
00951
00952 FOR_EACH_BB (bb)
00953 for (si = bsi_start (bb); !bsi_end_p (si); si = ni)
00954 {
00955 tree stmt, t;
00956 stmt_ann_t ann;
00957
00958 stmt = bsi_stmt (si);
00959 ann = stmt_ann (stmt);
00960
00961 ni = si;
00962 bsi_next (&ni);
00963
00964
00965
00966 if (ZERO_SSA_OPERANDS (stmt, (SSA_OP_VIRTUAL_DEFS | SSA_OP_VUSE)))
00967 continue;
00968
00969 switch (TREE_CODE (stmt))
00970 {
00971 case RETURN_EXPR:
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981 t = TREE_OPERAND (stmt, 0);
00982 if (TREE_CODE (t) == MODIFY_EXPR)
00983 sra_walk_expr (&TREE_OPERAND (t, 1), &si, false, fns);
00984 else
00985 sra_walk_expr (&TREE_OPERAND (stmt, 0), &si, false, fns);
00986 break;
00987
00988 case MODIFY_EXPR:
00989 sra_walk_modify_expr (stmt, &si, fns);
00990 break;
00991 case CALL_EXPR:
00992 sra_walk_call_expr (stmt, &si, fns);
00993 break;
00994 case ASM_EXPR:
00995 sra_walk_asm_expr (stmt, &si, fns);
00996 break;
00997
00998 default:
00999 break;
01000 }
01001 }
01002 }
01003
01004
01005
01006
01007 static bool
01008 find_candidates_for_sra (void)
01009 {
01010 bool any_set = false;
01011 tree var;
01012 referenced_var_iterator rvi;
01013
01014 FOR_EACH_REFERENCED_VAR (var, rvi)
01015 {
01016 if (decl_can_be_decomposed_p (var))
01017 {
01018 bitmap_set_bit (sra_candidates, DECL_UID (var));
01019 any_set = true;
01020 }
01021 }
01022
01023 return any_set;
01024 }
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034 static void
01035 scan_use (struct sra_elt *elt, tree *expr_p ATTRIBUTE_UNUSED,
01036 block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
01037 bool is_output ATTRIBUTE_UNUSED, bool use_all ATTRIBUTE_UNUSED)
01038 {
01039 elt->n_uses += 1;
01040 }
01041
01042 static void
01043 scan_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
01044 block_stmt_iterator *bsi ATTRIBUTE_UNUSED)
01045 {
01046 lhs_elt->n_copies += 1;
01047 rhs_elt->n_copies += 1;
01048 }
01049
01050 static void
01051 scan_init (struct sra_elt *lhs_elt, tree rhs ATTRIBUTE_UNUSED,
01052 block_stmt_iterator *bsi ATTRIBUTE_UNUSED)
01053 {
01054 lhs_elt->n_copies += 1;
01055 }
01056
01057 static void
01058 scan_ldst (struct sra_elt *elt, tree other ATTRIBUTE_UNUSED,
01059 block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
01060 bool is_output ATTRIBUTE_UNUSED)
01061 {
01062 elt->n_copies += 1;
01063 }
01064
01065
01066
01067 static void
01068 scan_dump (struct sra_elt *elt)
01069 {
01070 struct sra_elt *c;
01071
01072 dump_sra_elt_name (dump_file, elt);
01073 fprintf (dump_file, ": n_uses=%u n_copies=%u\n", elt->n_uses, elt->n_copies);
01074
01075 for (c = elt->children; c ; c = c->sibling)
01076 scan_dump (c);
01077
01078 for (c = elt->groups; c ; c = c->sibling)
01079 scan_dump (c);
01080 }
01081
01082
01083
01084
01085 static void
01086 scan_function (void)
01087 {
01088 static const struct sra_walk_fns fns = {
01089 scan_use, scan_copy, scan_init, scan_ldst, true
01090 };
01091 bitmap_iterator bi;
01092
01093 sra_walk_function (&fns);
01094
01095 if (dump_file && (dump_flags & TDF_DETAILS))
01096 {
01097 unsigned i;
01098
01099 fputs ("\nScan results:\n", dump_file);
01100 EXECUTE_IF_SET_IN_BITMAP (sra_candidates, 0, i, bi)
01101 {
01102 tree var = referenced_var (i);
01103 struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT);
01104 if (elt)
01105 scan_dump (elt);
01106 }
01107 fputc ('\n', dump_file);
01108 }
01109 }
01110
01111
01112
01113
01114
01115
01116
01117 static void
01118 build_element_name_1 (struct sra_elt *elt)
01119 {
01120 tree t;
01121 char buffer[32];
01122
01123 if (elt->parent)
01124 {
01125 build_element_name_1 (elt->parent);
01126 obstack_1grow (&sra_obstack, '$');
01127
01128 if (TREE_CODE (elt->parent->type) == COMPLEX_TYPE)
01129 {
01130 if (elt->element == integer_zero_node)
01131 obstack_grow (&sra_obstack, "real", 4);
01132 else
01133 obstack_grow (&sra_obstack, "imag", 4);
01134 return;
01135 }
01136 }
01137
01138 t = elt->element;
01139 if (TREE_CODE (t) == INTEGER_CST)
01140 {
01141
01142 sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (t));
01143 obstack_grow (&sra_obstack, buffer, strlen (buffer));
01144 }
01145 else
01146 {
01147 tree name = DECL_NAME (t);
01148 if (name)
01149 obstack_grow (&sra_obstack, IDENTIFIER_POINTER (name),
01150 IDENTIFIER_LENGTH (name));
01151 else
01152 {
01153 sprintf (buffer, "D%u", DECL_UID (t));
01154 obstack_grow (&sra_obstack, buffer, strlen (buffer));
01155 }
01156 }
01157 }
01158
01159
01160
01161
01162 static char *
01163 build_element_name (struct sra_elt *elt)
01164 {
01165 build_element_name_1 (elt);
01166 obstack_1grow (&sra_obstack, '\0');
01167 return XOBFINISH (&sra_obstack, char *);
01168 }
01169
01170
01171
01172 static void
01173 instantiate_element (struct sra_elt *elt)
01174 {
01175 struct sra_elt *base_elt;
01176 tree var, base;
01177
01178 for (base_elt = elt; base_elt->parent; base_elt = base_elt->parent)
01179 continue;
01180 base = base_elt->element;
01181
01182 elt->replacement = var = make_rename_temp (elt->type, "SR");
01183 DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (base);
01184 DECL_ARTIFICIAL (var) = 1;
01185
01186 if (TREE_THIS_VOLATILE (elt->type))
01187 {
01188 TREE_THIS_VOLATILE (var) = 1;
01189 TREE_SIDE_EFFECTS (var) = 1;
01190 }
01191
01192 if (DECL_NAME (base) && !DECL_IGNORED_P (base))
01193 {
01194 char *pretty_name = build_element_name (elt);
01195 DECL_NAME (var) = get_identifier (pretty_name);
01196 obstack_free (&sra_obstack, pretty_name);
01197
01198 SET_DECL_DEBUG_EXPR (var, generate_element_ref (elt));
01199 DECL_DEBUG_EXPR_IS_FROM (var) = 1;
01200
01201 DECL_IGNORED_P (var) = 0;
01202 TREE_NO_WARNING (var) = TREE_NO_WARNING (base);
01203 }
01204 else
01205 {
01206 DECL_IGNORED_P (var) = 1;
01207
01208 TREE_NO_WARNING (var) = 1;
01209 }
01210
01211 if (dump_file)
01212 {
01213 fputs (" ", dump_file);
01214 dump_sra_elt_name (dump_file, elt);
01215 fputs (" -> ", dump_file);
01216 print_generic_expr (dump_file, var, dump_flags);
01217 fputc ('\n', dump_file);
01218 }
01219 }
01220
01221
01222
01223
01224
01225
01226
01227 static void
01228 decide_instantiation_1 (struct sra_elt *elt, unsigned int parent_uses,
01229 unsigned int parent_copies)
01230 {
01231 if (dump_file && !elt->parent)
01232 {
01233 fputs ("Initial instantiation for ", dump_file);
01234 dump_sra_elt_name (dump_file, elt);
01235 fputc ('\n', dump_file);
01236 }
01237
01238 if (elt->cannot_scalarize)
01239 return;
01240
01241 if (elt->is_scalar)
01242 {
01243
01244
01245 if (elt->n_uses + elt->n_copies + parent_copies > parent_uses)
01246 instantiate_element (elt);
01247 }
01248 else
01249 {
01250 struct sra_elt *c, *group;
01251 unsigned int this_uses = elt->n_uses + parent_uses;
01252 unsigned int this_copies = elt->n_copies + parent_copies;
01253
01254
01255
01256 for (group = elt->groups; group ; group = group->sibling)
01257 FOR_EACH_ACTUAL_CHILD (c, group)
01258 {
01259 c->n_uses += group->n_uses;
01260 c->n_copies += group->n_copies;
01261 }
01262
01263 for (c = elt->children; c ; c = c->sibling)
01264 decide_instantiation_1 (c, this_uses, this_copies);
01265 }
01266 }
01267
01268
01269
01270
01271
01272 static unsigned int
01273 sum_instantiated_sizes (struct sra_elt *elt, unsigned HOST_WIDE_INT *sizep)
01274 {
01275 if (elt->replacement)
01276 {
01277 *sizep += TREE_INT_CST_LOW (TYPE_SIZE_UNIT (elt->type));
01278 return 1;
01279 }
01280 else
01281 {
01282 struct sra_elt *c;
01283 unsigned int count = 0;
01284
01285 for (c = elt->children; c ; c = c->sibling)
01286 count += sum_instantiated_sizes (c, sizep);
01287
01288 return count;
01289 }
01290 }
01291
01292
01293
01294
01295 static void instantiate_missing_elements (struct sra_elt *elt);
01296
01297 static void
01298 instantiate_missing_elements_1 (struct sra_elt *elt, tree child, tree type)
01299 {
01300 struct sra_elt *sub = lookup_element (elt, child, type, INSERT);
01301 if (sub->is_scalar)
01302 {
01303 if (sub->replacement == NULL)
01304 instantiate_element (sub);
01305 }
01306 else
01307 instantiate_missing_elements (sub);
01308 }
01309
01310 static void
01311 instantiate_missing_elements (struct sra_elt *elt)
01312 {
01313 tree type = elt->type;
01314
01315 switch (TREE_CODE (type))
01316 {
01317 case RECORD_TYPE:
01318 {
01319 tree f;
01320 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
01321 if (TREE_CODE (f) == FIELD_DECL)
01322 {
01323 tree field_type = TREE_TYPE (f);
01324
01325
01326
01327
01328
01329 if (INTEGRAL_TYPE_P (field_type)
01330 && DECL_MODE (f) != TYPE_MODE (field_type))
01331 field_type = TREE_TYPE (get_unwidened (build3 (COMPONENT_REF,
01332 field_type,
01333 elt->element,
01334 f, NULL_TREE),
01335 NULL_TREE));
01336
01337 instantiate_missing_elements_1 (elt, f, field_type);
01338 }
01339 break;
01340 }
01341
01342 case ARRAY_TYPE:
01343 {
01344 tree i, max, subtype;
01345
01346 i = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
01347 max = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
01348 subtype = TREE_TYPE (type);
01349
01350 while (1)
01351 {
01352 instantiate_missing_elements_1 (elt, i, subtype);
01353 if (tree_int_cst_equal (i, max))
01354 break;
01355 i = int_const_binop (PLUS_EXPR, i, integer_one_node, true);
01356 }
01357
01358 break;
01359 }
01360
01361 case COMPLEX_TYPE:
01362 type = TREE_TYPE (type);
01363 instantiate_missing_elements_1 (elt, integer_zero_node, type);
01364 instantiate_missing_elements_1 (elt, integer_one_node, type);
01365 break;
01366
01367 default:
01368 gcc_unreachable ();
01369 }
01370 }
01371
01372
01373
01374
01375
01376 static bool
01377 decide_block_copy (struct sra_elt *elt)
01378 {
01379 struct sra_elt *c;
01380 bool any_inst;
01381
01382
01383
01384 gcc_assert (!elt->is_group);
01385
01386
01387 if (elt->cannot_scalarize)
01388 {
01389 elt->use_block_copy = 1;
01390
01391 if (dump_file)
01392 {
01393 fputs ("Scalarization disabled for ", dump_file);
01394 dump_sra_elt_name (dump_file, elt);
01395 fputc ('\n', dump_file);
01396 }
01397
01398
01399 for (c = elt->children; c; c = c->sibling)
01400 {
01401 c->cannot_scalarize = 1;
01402 decide_block_copy (c);
01403 }
01404
01405
01406 for (c = elt->groups; c; c = c->sibling)
01407 {
01408 c->cannot_scalarize = 1;
01409 c->use_block_copy = 1;
01410 }
01411
01412 return false;
01413 }
01414
01415
01416 if (elt->n_uses == 0 && elt->n_copies == 0)
01417 ;
01418
01419 else if (!elt->is_scalar)
01420 {
01421 tree size_tree = TYPE_SIZE_UNIT (elt->type);
01422 bool use_block_copy = true;
01423
01424
01425
01426 if (TREE_CODE (elt->type) == COMPLEX_TYPE)
01427 use_block_copy = false;
01428
01429
01430
01431
01432 else if (host_integerp (size_tree, 1))
01433 {
01434 unsigned HOST_WIDE_INT full_size, inst_size = 0;
01435 unsigned int max_size, max_count, inst_count, full_count;
01436
01437
01438
01439
01440 max_size = SRA_MAX_STRUCTURE_SIZE
01441 ? SRA_MAX_STRUCTURE_SIZE
01442 : MOVE_RATIO * UNITS_PER_WORD;
01443 max_count = SRA_MAX_STRUCTURE_COUNT
01444 ? SRA_MAX_STRUCTURE_COUNT
01445 : MOVE_RATIO;
01446
01447 full_size = tree_low_cst (size_tree, 1);
01448 full_count = count_type_elements (elt->type, false);
01449 inst_count = sum_instantiated_sizes (elt, &inst_size);
01450
01451
01452
01453
01454
01455
01456
01457
01458 if (full_size <= max_size
01459 && (full_count - inst_count) <= max_count
01460 && elt->n_copies > elt->n_uses)
01461 use_block_copy = false;
01462 else if (inst_count * 100 >= full_count * SRA_FIELD_STRUCTURE_RATIO
01463 && inst_size * 100 >= full_size * SRA_FIELD_STRUCTURE_RATIO)
01464 use_block_copy = false;
01465
01466
01467
01468 if (!use_block_copy
01469 && (!can_completely_scalarize_p (elt)
01470 || !type_can_instantiate_all_elements (elt->type)))
01471 use_block_copy = true;
01472 }
01473
01474 elt->use_block_copy = use_block_copy;
01475
01476
01477 for (c = elt->groups; c; c = c->sibling)
01478 c->use_block_copy = use_block_copy;
01479
01480 if (dump_file)
01481 {
01482 fprintf (dump_file, "Using %s for ",
01483 use_block_copy ? "block-copy" : "element-copy");
01484 dump_sra_elt_name (dump_file, elt);
01485 fputc ('\n', dump_file);
01486 }
01487
01488 if (!use_block_copy)
01489 {
01490 instantiate_missing_elements (elt);
01491 return true;
01492 }
01493 }
01494
01495 any_inst = elt->replacement != NULL;
01496
01497 for (c = elt->children; c ; c = c->sibling)
01498 any_inst |= decide_block_copy (c);
01499
01500 return any_inst;
01501 }
01502
01503
01504
01505 static void
01506 decide_instantiations (void)
01507 {
01508 unsigned int i;
01509 bool cleared_any;
01510 bitmap_head done_head;
01511 bitmap_iterator bi;
01512
01513
01514
01515 bitmap_initialize (&done_head, &bitmap_default_obstack);
01516 cleared_any = false;
01517
01518 EXECUTE_IF_SET_IN_BITMAP (sra_candidates, 0, i, bi)
01519 {
01520 tree var = referenced_var (i);
01521 struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT);
01522 if (elt)
01523 {
01524 decide_instantiation_1 (elt, 0, 0);
01525 if (!decide_block_copy (elt))
01526 elt = NULL;
01527 }
01528 if (!elt)
01529 {
01530 bitmap_set_bit (&done_head, i);
01531 cleared_any = true;
01532 }
01533 }
01534
01535 if (cleared_any)
01536 {
01537 bitmap_and_compl_into (sra_candidates, &done_head);
01538 bitmap_and_compl_into (needs_copy_in, &done_head);
01539 }
01540 bitmap_clear (&done_head);
01541
01542 if (!bitmap_empty_p (sra_candidates))
01543 todoflags |= TODO_update_smt_usage;
01544
01545 mark_set_for_renaming (sra_candidates);
01546
01547 if (dump_file)
01548 fputc ('\n', dump_file);
01549 }
01550
01551
01552
01553
01554
01555
01556
01557 static void
01558 mark_all_v_defs_1 (tree stmt)
01559 {
01560 tree sym;
01561 ssa_op_iter iter;
01562
01563 update_stmt_if_modified (stmt);
01564
01565 FOR_EACH_SSA_TREE_OPERAND (sym, stmt, iter, SSA_OP_ALL_VIRTUALS)
01566 {
01567 if (TREE_CODE (sym) == SSA_NAME)
01568 sym = SSA_NAME_VAR (sym);
01569 mark_sym_for_renaming (sym);
01570 }
01571 }
01572
01573
01574
01575
01576
01577 static void
01578 mark_all_v_defs (tree list)
01579 {
01580 if (TREE_CODE (list) != STATEMENT_LIST)
01581 mark_all_v_defs_1 (list);
01582 else
01583 {
01584 tree_stmt_iterator i;
01585 for (i = tsi_start (list); !tsi_end_p (i); tsi_next (&i))
01586 mark_all_v_defs_1 (tsi_stmt (i));
01587 }
01588 }
01589
01590
01591
01592 static void
01593 mark_no_warning (struct sra_elt *elt)
01594 {
01595 if (!elt->all_no_warning)
01596 {
01597 if (elt->replacement)
01598 TREE_NO_WARNING (elt->replacement) = 1;
01599 else
01600 {
01601 struct sra_elt *c;
01602 FOR_EACH_ACTUAL_CHILD (c, elt)
01603 mark_no_warning (c);
01604 }
01605 elt->all_no_warning = true;
01606 }
01607 }
01608
01609
01610
01611 static tree
01612 generate_one_element_ref (struct sra_elt *elt, tree base)
01613 {
01614 switch (TREE_CODE (TREE_TYPE (base)))
01615 {
01616 case RECORD_TYPE:
01617 {
01618 tree field = elt->element;
01619
01620
01621 if (DECL_FIELD_CONTEXT (field) != TYPE_MAIN_VARIANT (TREE_TYPE (base)))
01622 field = find_compatible_field (TREE_TYPE (base), field);
01623
01624 return build3 (COMPONENT_REF, elt->type, base, field, NULL);
01625 }
01626
01627 case ARRAY_TYPE:
01628 todoflags |= TODO_update_smt_usage;
01629 if (TREE_CODE (elt->element) == RANGE_EXPR)
01630 return build4 (ARRAY_RANGE_REF, elt->type, base,
01631 TREE_OPERAND (elt->element, 0), NULL, NULL);
01632 else
01633 return build4 (ARRAY_REF, elt->type, base, elt->element, NULL, NULL);
01634
01635 case COMPLEX_TYPE:
01636 if (elt->element == integer_zero_node)
01637 return build1 (REALPART_EXPR, elt->type, base);
01638 else
01639 return build1 (IMAGPART_EXPR, elt->type, base);
01640
01641 default:
01642 gcc_unreachable ();
01643 }
01644 }
01645
01646
01647
01648 static tree
01649 generate_element_ref (struct sra_elt *elt)
01650 {
01651 if (elt->parent)
01652 return generate_one_element_ref (elt, generate_element_ref (elt->parent));
01653 else
01654 return elt->element;
01655 }
01656
01657 static tree
01658 sra_build_assignment (tree dst, tree src)
01659 {
01660
01661
01662 return build2 (MODIFY_EXPR, void_type_node, dst, src);
01663 }
01664
01665
01666
01667
01668
01669
01670 static void
01671 generate_copy_inout (struct sra_elt *elt, bool copy_out, tree expr,
01672 tree *list_p)
01673 {
01674 struct sra_elt *c;
01675 tree t;
01676
01677 if (!copy_out && TREE_CODE (expr) == SSA_NAME
01678 && TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
01679 {
01680 tree r, i;
01681
01682 c = lookup_element (elt, integer_zero_node, NULL, NO_INSERT);
01683 r = c->replacement;
01684 c = lookup_element (elt, integer_one_node, NULL, NO_INSERT);
01685 i = c->replacement;
01686
01687 t = build2 (COMPLEX_EXPR, elt->type, r, i);
01688 t = sra_build_assignment (expr, t);
01689 SSA_NAME_DEF_STMT (expr) = t;
01690 append_to_statement_list (t, list_p);
01691 }
01692 else if (elt->replacement)
01693 {
01694 if (copy_out)
01695 t = sra_build_assignment (elt->replacement, expr);
01696 else
01697 t = sra_build_assignment (expr, elt->replacement);
01698 append_to_statement_list (t, list_p);
01699 }
01700 else
01701 {
01702 FOR_EACH_ACTUAL_CHILD (c, elt)
01703 {
01704 t = generate_one_element_ref (c, unshare_expr (expr));
01705 generate_copy_inout (c, copy_out, t, list_p);
01706 }
01707 }
01708 }
01709
01710
01711
01712
01713
01714 static void
01715 generate_element_copy (struct sra_elt *dst, struct sra_elt *src, tree *list_p)
01716 {
01717 struct sra_elt *dc, *sc;
01718
01719 FOR_EACH_ACTUAL_CHILD (dc, dst)
01720 {
01721 sc = lookup_element (src, dc->element, NULL, NO_INSERT);
01722 gcc_assert (sc);
01723 generate_element_copy (dc, sc, list_p);
01724 }
01725
01726 if (dst->replacement)
01727 {
01728 tree t;
01729
01730 gcc_assert (src->replacement);
01731
01732 t = sra_build_assignment (dst->replacement, src->replacement);
01733 append_to_statement_list (t, list_p);
01734 }
01735 }
01736
01737
01738
01739
01740
01741
01742 static void
01743 generate_element_zero (struct sra_elt *elt, tree *list_p)
01744 {
01745 struct sra_elt *c;
01746
01747 if (elt->visited)
01748 {
01749 elt->visited = false;
01750 return;
01751 }
01752
01753 FOR_EACH_ACTUAL_CHILD (c, elt)
01754 generate_element_zero (c, list_p);
01755
01756 if (elt->replacement)
01757 {
01758 tree t;
01759
01760 gcc_assert (elt->is_scalar);
01761 t = fold_convert (elt->type, integer_zero_node);
01762
01763 t = sra_build_assignment (elt->replacement, t);
01764 append_to_statement_list (t, list_p);
01765 }
01766 }
01767
01768
01769
01770
01771 static void
01772 generate_one_element_init (tree var, tree init, tree *list_p)
01773 {
01774
01775 tree stmt = sra_build_assignment (var, init);
01776 gimplify_and_add (stmt, list_p);
01777 }
01778
01779
01780
01781
01782
01783
01784
01785 static bool
01786 generate_element_init_1 (struct sra_elt *elt, tree init, tree *list_p)
01787 {
01788 bool result = true;
01789 enum tree_code init_code;
01790 struct sra_elt *sub;
01791 tree t;
01792 unsigned HOST_WIDE_INT idx;
01793 tree value, purpose;
01794
01795
01796
01797 STRIP_USELESS_TYPE_CONVERSION (init);
01798 init_code = TREE_CODE (init);
01799
01800 if (elt->is_scalar)
01801 {
01802 if (elt->replacement)
01803 {
01804 generate_one_element_init (elt->replacement, init, list_p);
01805 elt->visited = true;
01806 }
01807 return result;
01808 }
01809
01810 switch (init_code)
01811 {
01812 case COMPLEX_CST:
01813 case COMPLEX_EXPR:
01814 FOR_EACH_ACTUAL_CHILD (sub, elt)
01815 {
01816 if (sub->element == integer_zero_node)
01817 t = (init_code == COMPLEX_EXPR
01818 ? TREE_OPERAND (init, 0) : TREE_REALPART (init));
01819 else
01820 t = (init_code == COMPLEX_EXPR
01821 ? TREE_OPERAND (init, 1) : TREE_IMAGPART (init));
01822 result &= generate_element_init_1 (sub, t, list_p);
01823 }
01824 break;
01825
01826 case CONSTRUCTOR:
01827 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, purpose, value)
01828 {
01829 if (TREE_CODE (purpose) == RANGE_EXPR)
01830 {
01831 tree lower = TREE_OPERAND (purpose, 0);
01832 tree upper = TREE_OPERAND (purpose, 1);
01833
01834 while (1)
01835 {
01836 sub = lookup_element (elt, lower, NULL, NO_INSERT);
01837 if (sub != NULL)
01838 result &= generate_element_init_1 (sub, value, list_p);
01839 if (tree_int_cst_equal (lower, upper))
01840 break;
01841 lower = int_const_binop (PLUS_EXPR, lower,
01842 integer_one_node, true);
01843 }
01844 }
01845 else
01846 {
01847 sub = lookup_element (elt, purpose, NULL, NO_INSERT);
01848 if (sub != NULL)
01849 result &= generate_element_init_1 (sub, value, list_p);
01850 }
01851 }
01852 break;
01853
01854 default:
01855 elt->visited = true;
01856 result = false;
01857 }
01858
01859 return result;
01860 }
01861
01862
01863
01864
01865 static bool
01866 generate_element_init (struct sra_elt *elt, tree init, tree *list_p)
01867 {
01868 bool ret;
01869
01870 push_gimplify_context ();
01871 ret = generate_element_init_1 (elt, init, list_p);
01872 pop_gimplify_context (NULL);
01873
01874
01875 if (ret && *list_p)
01876 {
01877 tree_stmt_iterator i;
01878
01879 for (i = tsi_start (*list_p); !tsi_end_p (i); tsi_next (&i))
01880 find_new_referenced_vars (tsi_stmt_ptr (i));
01881 }
01882
01883 return ret;
01884 }
01885
01886
01887
01888
01889
01890 void
01891 insert_edge_copies (tree stmt, basic_block bb)
01892 {
01893 edge e;
01894 edge_iterator ei;
01895 bool first_copy;
01896
01897 first_copy = true;
01898 FOR_EACH_EDGE (e, ei, bb->succs)
01899 {
01900
01901
01902
01903 if (!(e->flags & EDGE_ABNORMAL))
01904 {
01905 if (first_copy)
01906 {
01907 bsi_insert_on_edge (e, stmt);
01908 first_copy = false;
01909 }
01910 else
01911 bsi_insert_on_edge (e, unsave_expr_now (stmt));
01912 }
01913 }
01914 }
01915
01916
01917
01918 void
01919 sra_insert_before (block_stmt_iterator *bsi, tree list)
01920 {
01921 tree stmt = bsi_stmt (*bsi);
01922
01923 if (EXPR_HAS_LOCATION (stmt))
01924 annotate_all_with_locus (&list, EXPR_LOCATION (stmt));
01925 bsi_insert_before (bsi, list, BSI_SAME_STMT);
01926 }
01927
01928
01929
01930 void
01931 sra_insert_after (block_stmt_iterator *bsi, tree list)
01932 {
01933 tree stmt = bsi_stmt (*bsi);
01934
01935 if (EXPR_HAS_LOCATION (stmt))
01936 annotate_all_with_locus (&list, EXPR_LOCATION (stmt));
01937
01938 if (stmt_ends_bb_p (stmt))
01939 insert_edge_copies (list, bsi->bb);
01940 else
01941 bsi_insert_after (bsi, list, BSI_SAME_STMT);
01942 }
01943
01944
01945
01946 static void
01947 sra_replace (block_stmt_iterator *bsi, tree list)
01948 {
01949 sra_insert_before (bsi, list);
01950 bsi_remove (bsi, false);
01951 if (bsi_end_p (*bsi))
01952 *bsi = bsi_last (bsi->bb);
01953 else
01954 bsi_prev (bsi);
01955 }
01956
01957
01958
01959
01960
01961 static void
01962 scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi,
01963 bool is_output, bool use_all)
01964 {
01965 tree list = NULL, stmt = bsi_stmt (*bsi);
01966
01967 if (elt->replacement)
01968 {
01969
01970
01971 if (is_output)
01972 mark_all_v_defs (stmt);
01973 *expr_p = elt->replacement;
01974 update_stmt (stmt);
01975 }
01976 else
01977 {
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991 generate_copy_inout (elt, is_output, generate_element_ref (elt), &list);
01992 if (list == NULL)
01993 return;
01994 mark_all_v_defs (list);
01995 if (is_output)
01996 sra_insert_after (bsi, list);
01997 else
01998 {
01999 sra_insert_before (bsi, list);
02000 if (use_all)
02001 mark_no_warning (elt);
02002 }
02003 }
02004 }
02005
02006
02007
02008
02009 static void
02010 scalarize_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
02011 block_stmt_iterator *bsi)
02012 {
02013 tree list, stmt;
02014
02015 if (lhs_elt->replacement && rhs_elt->replacement)
02016 {
02017
02018 stmt = bsi_stmt (*bsi);
02019
02020
02021
02022 gcc_assert (TREE_CODE (stmt) == MODIFY_EXPR);
02023
02024 TREE_OPERAND (stmt, 0) = lhs_elt->replacement;
02025 TREE_OPERAND (stmt, 1) = rhs_elt->replacement;
02026 update_stmt (stmt);
02027 }
02028 else if (lhs_elt->use_block_copy || rhs_elt->use_block_copy)
02029 {
02030
02031
02032
02033
02034
02035
02036
02037
02038 list = NULL;
02039 generate_copy_inout (rhs_elt, false,
02040 generate_element_ref (rhs_elt), &list);
02041 if (list)
02042 {
02043 mark_all_v_defs (list);
02044 sra_insert_before (bsi, list);
02045 }
02046
02047 list = NULL;
02048 generate_copy_inout (lhs_elt, true,
02049 generate_element_ref (lhs_elt), &list);
02050 if (list)
02051 {
02052 mark_all_v_defs (list);
02053 sra_insert_after (bsi, list);
02054 }
02055 }
02056 else
02057 {
02058
02059
02060
02061
02062 stmt = bsi_stmt (*bsi);
02063 mark_all_v_defs (stmt);
02064
02065 list = NULL;
02066 generate_element_copy (lhs_elt, rhs_elt, &list);
02067 gcc_assert (list);
02068 mark_all_v_defs (list);
02069 sra_replace (bsi, list);
02070 }
02071 }
02072
02073
02074
02075
02076
02077
02078 static void
02079 scalarize_init (struct sra_elt *lhs_elt, tree rhs, block_stmt_iterator *bsi)
02080 {
02081 bool result = true;
02082 tree list = NULL;
02083
02084
02085 if (rhs)
02086 {
02087
02088 rhs = unshare_expr (rhs);
02089 result = generate_element_init (lhs_elt, rhs, &list);
02090 }
02091
02092
02093
02094 generate_element_zero (lhs_elt, &list);
02095
02096 if (!result)
02097 {
02098
02099
02100
02101
02102
02103
02104 tree list0 = NULL;
02105 generate_copy_inout (lhs_elt, true, generate_element_ref (lhs_elt),
02106 &list0);
02107 append_to_statement_list (list, &list0);
02108 list = list0;
02109 }
02110
02111 if (lhs_elt->use_block_copy || !result)
02112 {
02113
02114
02115
02116 if (list)
02117 {
02118 mark_all_v_defs (list);
02119 sra_insert_after (bsi, list);
02120 }
02121 }
02122 else
02123 {
02124
02125
02126 gcc_assert (list);
02127 mark_all_v_defs (bsi_stmt (*bsi));
02128 mark_all_v_defs (list);
02129 sra_replace (bsi, list);
02130 }
02131 }
02132
02133
02134
02135
02136 static tree
02137 mark_notrap (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
02138 {
02139 tree t = *tp;
02140
02141 if (TREE_CODE (t) == INDIRECT_REF)
02142 {
02143 TREE_THIS_NOTRAP (t) = 1;
02144 *walk_subtrees = 0;
02145 }
02146 else if (IS_TYPE_OR_DECL_P (t))
02147 *walk_subtrees = 0;
02148
02149 return NULL;
02150 }
02151
02152
02153
02154
02155
02156 static void
02157 scalarize_ldst (struct sra_elt *elt, tree other,
02158 block_stmt_iterator *bsi, bool is_output)
02159 {
02160
02161 gcc_assert (!elt->replacement);
02162
02163 if (elt->use_block_copy)
02164 {
02165
02166
02167 scalarize_use (elt, NULL, bsi, is_output, false);
02168 }
02169 else
02170 {
02171
02172
02173
02174
02175 tree list = NULL, stmt = bsi_stmt (*bsi);
02176
02177 mark_all_v_defs (stmt);
02178 generate_copy_inout (elt, is_output, other, &list);
02179 mark_all_v_defs (list);
02180 gcc_assert (list);
02181
02182
02183 if (stmt_ends_bb_p (stmt))
02184 {
02185 tree_stmt_iterator tsi;
02186 tree first;
02187
02188
02189 tsi = tsi_start (list);
02190 first = tsi_stmt (tsi);
02191 tsi_delink (&tsi);
02192
02193
02194 bsi_replace (bsi, first, true);
02195
02196 if (!tsi_end_p (tsi))
02197 {
02198
02199
02200
02201
02202
02203 do
02204 {
02205 walk_tree (tsi_stmt_ptr (tsi), mark_notrap, NULL, NULL);
02206 tsi_next (&tsi);
02207 }
02208 while (!tsi_end_p (tsi));
02209
02210 insert_edge_copies (list, bsi->bb);
02211 }
02212 }
02213 else
02214 sra_replace (bsi, list);
02215 }
02216 }
02217
02218
02219
02220 static void
02221 scalarize_parms (void)
02222 {
02223 tree list = NULL;
02224 unsigned i;
02225 bitmap_iterator bi;
02226
02227 EXECUTE_IF_SET_IN_BITMAP (needs_copy_in, 0, i, bi)
02228 {
02229 tree var = referenced_var (i);
02230 struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT);
02231 generate_copy_inout (elt, true, var, &list);
02232 }
02233
02234 if (list)
02235 {
02236 insert_edge_copies (list, ENTRY_BLOCK_PTR);
02237 mark_all_v_defs (list);
02238 }
02239 }
02240
02241
02242
02243 static void
02244 scalarize_function (void)
02245 {
02246 static const struct sra_walk_fns fns = {
02247 scalarize_use, scalarize_copy, scalarize_init, scalarize_ldst, false
02248 };
02249
02250 sra_walk_function (&fns);
02251 scalarize_parms ();
02252 bsi_commit_edge_inserts ();
02253 }
02254
02255
02256
02257
02258 static void
02259 dump_sra_elt_name (FILE *f, struct sra_elt *elt)
02260 {
02261 if (elt->parent && TREE_CODE (elt->parent->type) == COMPLEX_TYPE)
02262 {
02263 fputs (elt->element == integer_zero_node ? "__real__ " : "__imag__ ", f);
02264 dump_sra_elt_name (f, elt->parent);
02265 }
02266 else
02267 {
02268 if (elt->parent)
02269 dump_sra_elt_name (f, elt->parent);
02270 if (DECL_P (elt->element))
02271 {
02272 if (TREE_CODE (elt->element) == FIELD_DECL)
02273 fputc ('.', f);
02274 print_generic_expr (f, elt->element, dump_flags);
02275 }
02276 else if (TREE_CODE (elt->element) == RANGE_EXPR)
02277 fprintf (f, "["HOST_WIDE_INT_PRINT_DEC".."HOST_WIDE_INT_PRINT_DEC"]",
02278 TREE_INT_CST_LOW (TREE_OPERAND (elt->element, 0)),
02279 TREE_INT_CST_LOW (TREE_OPERAND (elt->element, 1)));
02280 else
02281 fprintf (f, "[" HOST_WIDE_INT_PRINT_DEC "]",
02282 TREE_INT_CST_LOW (elt->element));
02283 }
02284 }
02285
02286
02287
02288 void
02289 debug_sra_elt_name (struct sra_elt *elt)
02290 {
02291 dump_sra_elt_name (stderr, elt);
02292 fputc ('\n', stderr);
02293 }
02294
02295 void
02296 sra_init_cache (void)
02297 {
02298 if (sra_type_decomp_cache)
02299 return;
02300
02301 sra_type_decomp_cache = BITMAP_ALLOC (NULL);
02302 sra_type_inst_cache = BITMAP_ALLOC (NULL);
02303 }
02304
02305
02306
02307 static unsigned int
02308 tree_sra (void)
02309 {
02310
02311 todoflags = 0;
02312 gcc_obstack_init (&sra_obstack);
02313 sra_candidates = BITMAP_ALLOC (NULL);
02314 needs_copy_in = BITMAP_ALLOC (NULL);
02315 sra_init_cache ();
02316 sra_map = htab_create (101, sra_elt_hash, sra_elt_eq, NULL);
02317
02318
02319 if (find_candidates_for_sra ())
02320 {
02321 scan_function ();
02322 decide_instantiations ();
02323 scalarize_function ();
02324 }
02325
02326
02327 htab_delete (sra_map);
02328 sra_map = NULL;
02329 BITMAP_FREE (sra_candidates);
02330 BITMAP_FREE (needs_copy_in);
02331 BITMAP_FREE (sra_type_decomp_cache);
02332 BITMAP_FREE (sra_type_inst_cache);
02333 obstack_free (&sra_obstack, NULL);
02334 return todoflags;
02335 }
02336
02337 static bool
02338 gate_sra (void)
02339 {
02340 return flag_tree_sra != 0;
02341 }
02342
02343 struct tree_opt_pass pass_sra =
02344 {
02345 "sra",
02346 gate_sra,
02347 tree_sra,
02348 NULL,
02349 NULL,
02350 0,
02351 TV_TREE_SRA,
02352 PROP_cfg | PROP_ssa | PROP_alias,
02353 0,
02354 PROP_smt_usage,
02355 0,
02356 TODO_dump_func
02357 | TODO_update_ssa
02358 | TODO_ggc_collect | TODO_verify_ssa,
02359 0
02360 };