00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "system.h"
00023 #include "coretypes.h"
00024 #include "tm.h"
00025 #include "tree.h"
00026 #include "flags.h"
00027 #include "rtl.h"
00028 #include "tm_p.h"
00029 #include "ggc.h"
00030 #include "basic-block.h"
00031 #include "output.h"
00032 #include "expr.h"
00033 #include "function.h"
00034 #include "diagnostic.h"
00035 #include "timevar.h"
00036 #include "tree-dump.h"
00037 #include "tree-flow.h"
00038 #include "tree-pass.h"
00039 #include "tree-ssa-propagate.h"
00040 #include "langhooks.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 bool
00061 may_propagate_copy (tree dest, tree orig)
00062 {
00063 tree type_d = TREE_TYPE (dest);
00064 tree type_o = TREE_TYPE (orig);
00065
00066
00067 if (!tree_ssa_useless_type_conversion_1 (type_d, type_o))
00068 return false;
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 if (TREE_CODE (dest) == SSA_NAME
00107 && TREE_CODE (orig) == SSA_NAME
00108 && POINTER_TYPE_P (type_d)
00109 && POINTER_TYPE_P (type_o))
00110 {
00111 tree mt_dest = var_ann (SSA_NAME_VAR (dest))->symbol_mem_tag;
00112 tree mt_orig = var_ann (SSA_NAME_VAR (orig))->symbol_mem_tag;
00113 if (mt_dest && mt_orig && mt_dest != mt_orig)
00114 return false;
00115 else if (!lang_hooks.types_compatible_p (type_d, type_o))
00116 return false;
00117 else if (get_alias_set (TREE_TYPE (type_d)) !=
00118 get_alias_set (TREE_TYPE (type_o)))
00119 return false;
00120
00121
00122 if (SSA_NAME_PTR_INFO (orig) && SSA_NAME_PTR_INFO (dest))
00123 {
00124 struct ptr_info_def *orig_ptr_info = SSA_NAME_PTR_INFO (orig);
00125 struct ptr_info_def *dest_ptr_info = SSA_NAME_PTR_INFO (dest);
00126
00127 if (orig_ptr_info->name_mem_tag
00128 && dest_ptr_info->name_mem_tag
00129 && orig_ptr_info->pt_vars
00130 && dest_ptr_info->pt_vars
00131 && !bitmap_intersect_p (dest_ptr_info->pt_vars,
00132 orig_ptr_info->pt_vars))
00133 return false;
00134 }
00135 }
00136
00137
00138
00139 if (TREE_CODE (dest) == SSA_NAME && !is_gimple_reg (dest))
00140 {
00141
00142
00143 if (TREE_CODE (orig) == SSA_NAME
00144 && !is_gimple_reg (orig))
00145 return true;
00146
00147
00148
00149 return false;
00150 }
00151
00152
00153 if (TREE_CODE (orig) == SSA_NAME
00154 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
00155 return false;
00156
00157
00158
00159 if (TREE_CODE (dest) == SSA_NAME
00160 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest))
00161 return false;
00162
00163
00164 return true;
00165 }
00166
00167
00168
00169 bool
00170 may_propagate_copy_into_asm (tree dest)
00171 {
00172
00173 return !(TREE_CODE (dest) == SSA_NAME
00174 && TREE_CODE (SSA_NAME_VAR (dest)) == VAR_DECL
00175 && DECL_HARD_REGISTER (SSA_NAME_VAR (dest)));
00176 }
00177
00178
00179
00180
00181
00182
00183 void
00184 merge_alias_info (tree orig, tree new)
00185 {
00186 tree new_sym = SSA_NAME_VAR (new);
00187 tree orig_sym = SSA_NAME_VAR (orig);
00188 var_ann_t new_ann = var_ann (new_sym);
00189 var_ann_t orig_ann = var_ann (orig_sym);
00190
00191 gcc_assert (POINTER_TYPE_P (TREE_TYPE (orig)));
00192 gcc_assert (POINTER_TYPE_P (TREE_TYPE (new)));
00193
00194 #if defined ENABLE_CHECKING
00195 gcc_assert (lang_hooks.types_compatible_p (TREE_TYPE (orig),
00196 TREE_TYPE (new)));
00197
00198
00199
00200
00201 gcc_assert (get_alias_set (TREE_TYPE (TREE_TYPE (new_sym)))
00202 == get_alias_set (TREE_TYPE (TREE_TYPE (orig_sym))));
00203 #endif
00204
00205
00206
00207
00208
00209 if (new_ann->symbol_mem_tag == NULL_TREE)
00210 new_ann->symbol_mem_tag = orig_ann->symbol_mem_tag;
00211 else if (orig_ann->symbol_mem_tag == NULL_TREE)
00212 orig_ann->symbol_mem_tag = new_ann->symbol_mem_tag;
00213 else
00214 gcc_assert (new_ann->symbol_mem_tag == orig_ann->symbol_mem_tag);
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 if (SSA_NAME_PTR_INFO (orig) && SSA_NAME_PTR_INFO (new))
00233 {
00234 struct ptr_info_def *orig_ptr_info = SSA_NAME_PTR_INFO (orig);
00235 struct ptr_info_def *new_ptr_info = SSA_NAME_PTR_INFO (new);
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 if (orig_ptr_info->name_mem_tag
00246 && new_ptr_info->name_mem_tag
00247 && orig_ptr_info->pt_vars
00248 && new_ptr_info->pt_vars)
00249 gcc_assert (bitmap_intersect_p (new_ptr_info->pt_vars,
00250 orig_ptr_info->pt_vars));
00251 }
00252 }
00253
00254
00255
00256
00257
00258
00259
00260 static void
00261 replace_exp_1 (use_operand_p op_p, tree val,
00262 bool for_propagation ATTRIBUTE_UNUSED)
00263 {
00264 tree op = USE_FROM_PTR (op_p);
00265
00266 #if defined ENABLE_CHECKING
00267 gcc_assert (!(for_propagation
00268 && TREE_CODE (op) == SSA_NAME
00269 && TREE_CODE (val) == SSA_NAME
00270 && !may_propagate_copy (op, val)));
00271 #endif
00272
00273 if (TREE_CODE (val) == SSA_NAME)
00274 {
00275 if (TREE_CODE (op) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (op)))
00276 merge_alias_info (op, val);
00277 SET_USE (op_p, val);
00278 }
00279 else
00280 SET_USE (op_p, unsave_expr_now (val));
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290 void
00291 propagate_value (use_operand_p op_p, tree val)
00292 {
00293 replace_exp_1 (op_p, val, true);
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 void
00306 propagate_tree_value (tree *op_p, tree val)
00307 {
00308 #if defined ENABLE_CHECKING
00309 gcc_assert (!(TREE_CODE (val) == SSA_NAME
00310 && TREE_CODE (*op_p) == SSA_NAME
00311 && !may_propagate_copy (*op_p, val)));
00312 #endif
00313
00314 if (TREE_CODE (val) == SSA_NAME)
00315 {
00316 if (TREE_CODE (*op_p) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (*op_p)))
00317 merge_alias_info (*op_p, val);
00318 *op_p = val;
00319 }
00320 else
00321 *op_p = unsave_expr_now (val);
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331 void
00332 replace_exp (use_operand_p op_p, tree val)
00333 {
00334 replace_exp_1 (op_p, val, false);
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 static prop_value_t *copy_of;
00353
00354
00355
00356 static tree *cached_last_copy_of;
00357
00358
00359 static bool do_store_copy_prop;
00360
00361
00362
00363
00364 static bool
00365 stmt_may_generate_copy (tree stmt)
00366 {
00367 tree lhs, rhs;
00368 stmt_ann_t ann;
00369
00370 if (TREE_CODE (stmt) == PHI_NODE)
00371 return !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (stmt));
00372
00373 if (TREE_CODE (stmt) != MODIFY_EXPR)
00374 return false;
00375
00376 lhs = TREE_OPERAND (stmt, 0);
00377 rhs = TREE_OPERAND (stmt, 1);
00378 ann = stmt_ann (stmt);
00379
00380
00381
00382 if (ann->has_volatile_ops)
00383 return false;
00384
00385
00386
00387 if (!do_store_copy_prop
00388 && !ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
00389 return false;
00390
00391
00392
00393
00394 return (do_store_copy_prop
00395 && TREE_CODE (lhs) == SSA_NAME)
00396 || (TREE_CODE (rhs) == SSA_NAME
00397 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs));
00398 }
00399
00400
00401
00402
00403 static inline prop_value_t *
00404 get_copy_of_val (tree var)
00405 {
00406 prop_value_t *val = ©_of[SSA_NAME_VERSION (var)];
00407
00408 if (val->value == NULL_TREE
00409 && !stmt_may_generate_copy (SSA_NAME_DEF_STMT (var)))
00410 {
00411
00412
00413 val->value = var;
00414 val->mem_ref = NULL_TREE;
00415 }
00416
00417 return val;
00418 }
00419
00420
00421
00422
00423 static tree
00424 get_last_copy_of (tree var)
00425 {
00426 tree last;
00427 int i;
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 #define LIMIT 5
00441
00442 last = var;
00443 for (i = 0; i < LIMIT; i++)
00444 {
00445 tree copy = copy_of[SSA_NAME_VERSION (last)].value;
00446 if (copy == NULL_TREE || copy == last)
00447 break;
00448 last = copy;
00449 }
00450
00451
00452
00453
00454 return (i < LIMIT ? last : var);
00455 }
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 static inline bool
00467 set_copy_of_val (tree dest, tree first, tree mem_ref)
00468 {
00469 unsigned int dest_ver = SSA_NAME_VERSION (dest);
00470 tree old_first, old_last, new_last;
00471
00472
00473
00474 old_first = copy_of[dest_ver].value;
00475 copy_of[dest_ver].value = first;
00476 copy_of[dest_ver].mem_ref = mem_ref;
00477
00478 if (old_first != first)
00479 return true;
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 old_last = cached_last_copy_of[dest_ver];
00493 new_last = get_last_copy_of (dest);
00494 cached_last_copy_of[dest_ver] = new_last;
00495
00496 return (old_last != new_last);
00497 }
00498
00499
00500
00501
00502 static void
00503 dump_copy_of (FILE *file, tree var)
00504 {
00505 tree val;
00506 sbitmap visited;
00507
00508 print_generic_expr (file, var, dump_flags);
00509
00510 if (TREE_CODE (var) != SSA_NAME)
00511 return;
00512
00513 visited = sbitmap_alloc (num_ssa_names);
00514 sbitmap_zero (visited);
00515 SET_BIT (visited, SSA_NAME_VERSION (var));
00516
00517 fprintf (file, " copy-of chain: ");
00518
00519 val = var;
00520 print_generic_expr (file, val, 0);
00521 fprintf (file, " ");
00522 while (copy_of[SSA_NAME_VERSION (val)].value)
00523 {
00524 fprintf (file, "-> ");
00525 val = copy_of[SSA_NAME_VERSION (val)].value;
00526 print_generic_expr (file, val, 0);
00527 fprintf (file, " ");
00528 if (TEST_BIT (visited, SSA_NAME_VERSION (val)))
00529 break;
00530 SET_BIT (visited, SSA_NAME_VERSION (val));
00531 }
00532
00533 val = get_copy_of_val (var)->value;
00534 if (val == NULL_TREE)
00535 fprintf (file, "[UNDEFINED]");
00536 else if (val != var)
00537 fprintf (file, "[COPY]");
00538 else
00539 fprintf (file, "[NOT A COPY]");
00540
00541 sbitmap_free (visited);
00542 }
00543
00544
00545
00546
00547
00548
00549
00550
00551 static enum ssa_prop_result
00552 copy_prop_visit_assignment (tree stmt, tree *result_p)
00553 {
00554 tree lhs, rhs;
00555 prop_value_t *rhs_val;
00556
00557 lhs = TREE_OPERAND (stmt, 0);
00558 rhs = TREE_OPERAND (stmt, 1);
00559
00560 gcc_assert (TREE_CODE (rhs) == SSA_NAME);
00561
00562 rhs_val = get_copy_of_val (rhs);
00563
00564 if (TREE_CODE (lhs) == SSA_NAME)
00565 {
00566
00567
00568 if (!may_propagate_copy (lhs, rhs))
00569 return SSA_PROP_VARYING;
00570
00571
00572
00573
00574
00575
00576
00577 *result_p = lhs;
00578 if (set_copy_of_val (*result_p, rhs_val->value, rhs_val->mem_ref))
00579 return SSA_PROP_INTERESTING;
00580 else
00581 return SSA_PROP_NOT_INTERESTING;
00582 }
00583 else if (stmt_makes_single_store (stmt))
00584 {
00585
00586
00587 ssa_op_iter i;
00588 tree vdef;
00589 bool changed;
00590
00591
00592 gcc_assert (do_store_copy_prop);
00593
00594
00595 changed = false;
00596 FOR_EACH_SSA_TREE_OPERAND (vdef, stmt, i, SSA_OP_VIRTUAL_DEFS)
00597 changed |= set_copy_of_val (vdef, rhs_val->value, lhs);
00598
00599
00600
00601
00602
00603
00604 *result_p = first_vdef (stmt);
00605
00606 if (changed)
00607 return SSA_PROP_INTERESTING;
00608 else
00609 return SSA_PROP_NOT_INTERESTING;
00610 }
00611
00612
00613 return SSA_PROP_VARYING;
00614 }
00615
00616
00617
00618
00619
00620
00621 static enum ssa_prop_result
00622 copy_prop_visit_cond_stmt (tree stmt, edge *taken_edge_p)
00623 {
00624 enum ssa_prop_result retval;
00625 tree cond;
00626
00627 cond = COND_EXPR_COND (stmt);
00628 retval = SSA_PROP_VARYING;
00629
00630
00631
00632 if (COMPARISON_CLASS_P (cond)
00633 && TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
00634 && TREE_CODE (TREE_OPERAND (cond, 1)) == SSA_NAME)
00635 {
00636 tree op0 = get_last_copy_of (TREE_OPERAND (cond, 0));
00637 tree op1 = get_last_copy_of (TREE_OPERAND (cond, 1));
00638
00639
00640 if (dump_file && (dump_flags & TDF_DETAILS))
00641 {
00642 fprintf (dump_file, "Trying to determine truth value of ");
00643 fprintf (dump_file, "predicate ");
00644 print_generic_stmt (dump_file, cond, 0);
00645 }
00646
00647
00648
00649 if (op0 == op1)
00650 {
00651 tree folded_cond = fold_binary (TREE_CODE (cond), boolean_type_node,
00652 op0, op1);
00653 if (folded_cond)
00654 {
00655 basic_block bb = bb_for_stmt (stmt);
00656 *taken_edge_p = find_taken_edge (bb, folded_cond);
00657 if (*taken_edge_p)
00658 retval = SSA_PROP_INTERESTING;
00659 }
00660 }
00661 }
00662
00663 if (dump_file && (dump_flags & TDF_DETAILS) && *taken_edge_p)
00664 fprintf (dump_file, "\nConditional will always take edge %d->%d\n",
00665 (*taken_edge_p)->src->index, (*taken_edge_p)->dest->index);
00666
00667 return retval;
00668 }
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681 static enum ssa_prop_result
00682 copy_prop_visit_stmt (tree stmt, edge *taken_edge_p, tree *result_p)
00683 {
00684 enum ssa_prop_result retval;
00685
00686 if (dump_file && (dump_flags & TDF_DETAILS))
00687 {
00688 fprintf (dump_file, "\nVisiting statement:\n");
00689 print_generic_stmt (dump_file, stmt, dump_flags);
00690 fprintf (dump_file, "\n");
00691 }
00692
00693 if (TREE_CODE (stmt) == MODIFY_EXPR
00694 && TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME
00695 && (do_store_copy_prop
00696 || TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME))
00697 {
00698
00699
00700 retval = copy_prop_visit_assignment (stmt, result_p);
00701 }
00702 else if (TREE_CODE (stmt) == MODIFY_EXPR
00703 && TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME
00704 && do_store_copy_prop
00705 && stmt_makes_single_load (stmt))
00706 {
00707
00708
00709
00710 prop_value_t *val = get_value_loaded_by (stmt, copy_of);
00711 if (val
00712 && val->mem_ref
00713 && is_gimple_reg (val->value)
00714 && operand_equal_p (val->mem_ref, TREE_OPERAND (stmt, 1), 0))
00715 {
00716 bool changed;
00717 changed = set_copy_of_val (TREE_OPERAND (stmt, 0),
00718 val->value, val->mem_ref);
00719 if (changed)
00720 {
00721 *result_p = TREE_OPERAND (stmt, 0);
00722 retval = SSA_PROP_INTERESTING;
00723 }
00724 else
00725 retval = SSA_PROP_NOT_INTERESTING;
00726 }
00727 else
00728 retval = SSA_PROP_VARYING;
00729 }
00730 else if (TREE_CODE (stmt) == COND_EXPR)
00731 {
00732
00733
00734 retval = copy_prop_visit_cond_stmt (stmt, taken_edge_p);
00735 }
00736 else
00737 retval = SSA_PROP_VARYING;
00738
00739 if (retval == SSA_PROP_VARYING)
00740 {
00741 tree def;
00742 ssa_op_iter i;
00743
00744
00745
00746 if (dump_file && (dump_flags & TDF_DETAILS))
00747 fprintf (dump_file, "No interesting values produced.\n");
00748
00749
00750
00751
00752 FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_ALL_DEFS)
00753 set_copy_of_val (def, def, NULL_TREE);
00754 }
00755
00756 return retval;
00757 }
00758
00759
00760
00761
00762
00763 static enum ssa_prop_result
00764 copy_prop_visit_phi_node (tree phi)
00765 {
00766 enum ssa_prop_result retval;
00767 int i;
00768 tree lhs;
00769 prop_value_t phi_val = { 0, NULL_TREE, NULL_TREE };
00770
00771 lhs = PHI_RESULT (phi);
00772
00773 if (dump_file && (dump_flags & TDF_DETAILS))
00774 {
00775 fprintf (dump_file, "\nVisiting PHI node: ");
00776 print_generic_expr (dump_file, phi, dump_flags);
00777 fprintf (dump_file, "\n\n");
00778 }
00779
00780 for (i = 0; i < PHI_NUM_ARGS (phi); i++)
00781 {
00782 prop_value_t *arg_val;
00783 tree arg = PHI_ARG_DEF (phi, i);
00784 edge e = PHI_ARG_EDGE (phi, i);
00785
00786
00787
00788 if (!(e->flags & EDGE_EXECUTABLE))
00789 continue;
00790
00791
00792
00793
00794 if (TREE_CODE (arg) != SSA_NAME || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg))
00795 {
00796 phi_val.value = lhs;
00797 break;
00798 }
00799
00800
00801
00802
00803
00804
00805 if (loop_depth_of_name (arg) > loop_depth_of_name (lhs))
00806 {
00807 phi_val.value = lhs;
00808 break;
00809 }
00810
00811
00812
00813 if (arg == lhs || get_last_copy_of (arg) == lhs)
00814 continue;
00815
00816 if (dump_file && (dump_flags & TDF_DETAILS))
00817 {
00818 fprintf (dump_file, "\tArgument #%d: ", i);
00819 dump_copy_of (dump_file, arg);
00820 fprintf (dump_file, "\n");
00821 }
00822
00823 arg_val = get_copy_of_val (arg);
00824
00825
00826
00827
00828
00829
00830 if (phi_val.value == NULL_TREE)
00831 {
00832 phi_val.value = arg;
00833 phi_val.mem_ref = arg_val->mem_ref;
00834 continue;
00835 }
00836
00837
00838
00839
00840
00841
00842 if (get_last_copy_of (phi_val.value) != get_last_copy_of (arg)
00843 || (do_store_copy_prop
00844 && phi_val.mem_ref
00845 && arg_val->mem_ref
00846 && simple_cst_equal (phi_val.mem_ref, arg_val->mem_ref) != 1))
00847 {
00848 phi_val.value = lhs;
00849 break;
00850 }
00851 }
00852
00853 if (phi_val.value && set_copy_of_val (lhs, phi_val.value, phi_val.mem_ref))
00854 retval = (phi_val.value != lhs) ? SSA_PROP_INTERESTING : SSA_PROP_VARYING;
00855 else
00856 retval = SSA_PROP_NOT_INTERESTING;
00857
00858 if (dump_file && (dump_flags & TDF_DETAILS))
00859 {
00860 fprintf (dump_file, "\nPHI node ");
00861 dump_copy_of (dump_file, lhs);
00862 fprintf (dump_file, "\nTelling the propagator to ");
00863 if (retval == SSA_PROP_INTERESTING)
00864 fprintf (dump_file, "add SSA edges out of this PHI and continue.");
00865 else if (retval == SSA_PROP_VARYING)
00866 fprintf (dump_file, "add SSA edges out of this PHI and never visit again.");
00867 else
00868 fprintf (dump_file, "do nothing with SSA edges and keep iterating.");
00869 fprintf (dump_file, "\n\n");
00870 }
00871
00872 return retval;
00873 }
00874
00875
00876
00877
00878
00879
00880 static void
00881 init_copy_prop (void)
00882 {
00883 basic_block bb;
00884
00885 copy_of = XNEWVEC (prop_value_t, num_ssa_names);
00886 memset (copy_of, 0, num_ssa_names * sizeof (*copy_of));
00887
00888 cached_last_copy_of = XNEWVEC (tree, num_ssa_names);
00889 memset (cached_last_copy_of, 0, num_ssa_names * sizeof (*cached_last_copy_of));
00890
00891 FOR_EACH_BB (bb)
00892 {
00893 block_stmt_iterator si;
00894 tree phi, def;
00895 int depth = bb->loop_depth;
00896
00897 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
00898 {
00899 tree stmt = bsi_stmt (si);
00900 ssa_op_iter iter;
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912 if (stmt_ends_bb_p (stmt))
00913 DONT_SIMULATE_AGAIN (stmt) = false;
00914 else if (stmt_may_generate_copy (stmt)
00915 && loop_depth_of_name (TREE_OPERAND (stmt, 1)) <= depth)
00916 DONT_SIMULATE_AGAIN (stmt) = false;
00917 else
00918 DONT_SIMULATE_AGAIN (stmt) = true;
00919
00920
00921
00922 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
00923 if (DONT_SIMULATE_AGAIN (stmt))
00924 set_copy_of_val (def, def, NULL_TREE);
00925 else
00926 cached_last_copy_of[SSA_NAME_VERSION (def)] = def;
00927 }
00928
00929 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
00930 {
00931 def = PHI_RESULT (phi);
00932 if (!do_store_copy_prop && !is_gimple_reg (def))
00933 DONT_SIMULATE_AGAIN (phi) = true;
00934 else
00935 DONT_SIMULATE_AGAIN (phi) = false;
00936
00937 if (DONT_SIMULATE_AGAIN (phi))
00938 set_copy_of_val (def, def, NULL_TREE);
00939 else
00940 cached_last_copy_of[SSA_NAME_VERSION (def)] = def;
00941 }
00942 }
00943 }
00944
00945
00946
00947
00948
00949 static void
00950 fini_copy_prop (void)
00951 {
00952 size_t i;
00953 prop_value_t *tmp;
00954
00955
00956
00957 tmp = XNEWVEC (prop_value_t, num_ssa_names);
00958 memset (tmp, 0, num_ssa_names * sizeof (*tmp));
00959 for (i = 1; i < num_ssa_names; i++)
00960 {
00961 tree var = ssa_name (i);
00962 if (var && copy_of[i].value && copy_of[i].value != var)
00963 tmp[i].value = get_last_copy_of (var);
00964 }
00965
00966 substitute_and_fold (tmp, false);
00967
00968 free (cached_last_copy_of);
00969 free (copy_of);
00970 free (tmp);
00971 }
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081 static void
01082 execute_copy_prop (bool store_copy_prop)
01083 {
01084 do_store_copy_prop = store_copy_prop;
01085 init_copy_prop ();
01086 ssa_propagate (copy_prop_visit_stmt, copy_prop_visit_phi_node);
01087 fini_copy_prop ();
01088 }
01089
01090
01091 static bool
01092 gate_copy_prop (void)
01093 {
01094 return flag_tree_copy_prop != 0;
01095 }
01096
01097 static unsigned int
01098 do_copy_prop (void)
01099 {
01100 execute_copy_prop (false);
01101 return 0;
01102 }
01103
01104 struct tree_opt_pass pass_copy_prop =
01105 {
01106 "copyprop",
01107 gate_copy_prop,
01108 do_copy_prop,
01109 NULL,
01110 NULL,
01111 0,
01112 TV_TREE_COPY_PROP,
01113 PROP_ssa | PROP_alias | PROP_cfg,
01114 0,
01115 0,
01116 0,
01117 TODO_cleanup_cfg
01118 | TODO_dump_func
01119 | TODO_ggc_collect
01120 | TODO_verify_ssa
01121 | TODO_update_ssa,
01122 0
01123 };
01124
01125 static bool
01126 gate_store_copy_prop (void)
01127 {
01128
01129
01130
01131
01132 return flag_tree_store_copy_prop != 0 || flag_tree_copy_prop != 0;
01133 }
01134
01135 static unsigned int
01136 store_copy_prop (void)
01137 {
01138
01139 execute_copy_prop (flag_tree_store_copy_prop != 0);
01140 return 0;
01141 }
01142
01143 struct tree_opt_pass pass_store_copy_prop =
01144 {
01145 "store_copyprop",
01146 gate_store_copy_prop,
01147 store_copy_prop,
01148 NULL,
01149 NULL,
01150 0,
01151 TV_TREE_STORE_COPY_PROP,
01152 PROP_ssa | PROP_alias | PROP_cfg,
01153 0,
01154 0,
01155 0,
01156 TODO_dump_func
01157 | TODO_cleanup_cfg
01158 | TODO_ggc_collect
01159 | TODO_verify_ssa
01160 | TODO_update_ssa,
01161 0
01162 };