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