00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tm.h"
00026 #include "hashtab.h"
00027 #include "pointer-set.h"
00028 #include "tree.h"
00029 #include "rtl.h"
00030 #include "tm_p.h"
00031 #include "hard-reg-set.h"
00032 #include "basic-block.h"
00033 #include "output.h"
00034 #include "errors.h"
00035 #include "timevar.h"
00036 #include "expr.h"
00037 #include "ggc.h"
00038 #include "langhooks.h"
00039 #include "flags.h"
00040 #include "function.h"
00041 #include "diagnostic.h"
00042 #include "tree-dump.h"
00043 #include "tree-gimple.h"
00044 #include "tree-flow.h"
00045 #include "tree-inline.h"
00046 #include "tree-pass.h"
00047 #include "convert.h"
00048 #include "params.h"
00049 #include "cgraph.h"
00050
00051
00052
00053
00054 struct dfa_stats_d
00055 {
00056 long num_stmt_anns;
00057 long num_var_anns;
00058 long num_defs;
00059 long num_uses;
00060 long num_phis;
00061 long num_phi_args;
00062 int max_num_phi_args;
00063 long num_v_may_defs;
00064 long num_vuses;
00065 long num_v_must_defs;
00066 };
00067
00068
00069
00070 struct walk_state
00071 {
00072
00073 htab_t vars_found;
00074 };
00075
00076
00077
00078 static void collect_dfa_stats (struct dfa_stats_d *);
00079 static tree collect_dfa_stats_r (tree *, int *, void *);
00080 static void add_immediate_use (tree, tree);
00081 static tree find_vars_r (tree *, int *, void *);
00082 static void add_referenced_var (tree, struct walk_state *);
00083 static void compute_immediate_uses_for_phi (tree, bool (*)(tree));
00084 static void compute_immediate_uses_for_stmt (tree, int, bool (*)(tree));
00085
00086
00087
00088
00089
00090 varray_type referenced_vars;
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 static void
00105 find_referenced_vars (void)
00106 {
00107 htab_t vars_found;
00108 basic_block bb;
00109 block_stmt_iterator si;
00110 struct walk_state walk_state;
00111
00112 vars_found = htab_create (50, htab_hash_pointer, htab_eq_pointer, NULL);
00113 memset (&walk_state, 0, sizeof (walk_state));
00114 walk_state.vars_found = vars_found;
00115
00116 FOR_EACH_BB (bb)
00117 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
00118 {
00119 tree *stmt_p = bsi_stmt_ptr (si);
00120 walk_tree (stmt_p, find_vars_r, &walk_state, NULL);
00121 }
00122
00123 htab_delete (vars_found);
00124 }
00125
00126 struct tree_opt_pass pass_referenced_vars =
00127 {
00128 NULL,
00129 NULL,
00130 find_referenced_vars,
00131 NULL,
00132 NULL,
00133 0,
00134 TV_FIND_REFERENCED_VARS,
00135 PROP_gimple_leh | PROP_cfg,
00136 PROP_referenced_vars,
00137 0,
00138 0,
00139 0,
00140 0
00141 };
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 void
00156 compute_immediate_uses (int flags, bool (*calc_for)(tree))
00157 {
00158 basic_block bb;
00159 block_stmt_iterator si;
00160
00161 FOR_EACH_BB (bb)
00162 {
00163 tree phi;
00164
00165 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
00166 {
00167 if (is_gimple_reg (PHI_RESULT (phi)))
00168 {
00169 if (!(flags & TDFA_USE_OPS))
00170 continue;
00171 }
00172 else
00173 {
00174 if (!(flags & TDFA_USE_VOPS))
00175 continue;
00176 }
00177
00178 compute_immediate_uses_for_phi (phi, calc_for);
00179 }
00180
00181 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
00182 {
00183 tree stmt = bsi_stmt (si);
00184 get_stmt_operands (stmt);
00185 compute_immediate_uses_for_stmt (stmt, flags, calc_for);
00186 }
00187 }
00188 }
00189
00190
00191
00192
00193 void
00194 free_df_for_stmt (tree stmt)
00195 {
00196 dataflow_t *df;
00197
00198 if (TREE_CODE (stmt) == PHI_NODE)
00199 df = &PHI_DF (stmt);
00200 else
00201 {
00202 stmt_ann_t ann = stmt_ann (stmt);
00203
00204 if (!ann)
00205 return;
00206
00207 df = &ann->df;
00208 }
00209
00210 if (!*df)
00211 return;
00212
00213
00214
00215 if ((*df)->immediate_uses)
00216 ggc_free ((*df)->immediate_uses);
00217
00218
00219 ggc_free (*df);
00220 *df = NULL;
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 void
00233 free_df (void)
00234 {
00235 basic_block bb;
00236 block_stmt_iterator si;
00237
00238 FOR_EACH_BB (bb)
00239 {
00240 tree phi;
00241
00242 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
00243 free_df_for_stmt (phi);
00244
00245 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
00246 {
00247 tree stmt = bsi_stmt (si);
00248 free_df_for_stmt (stmt);
00249 }
00250 }
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 static void
00262 compute_immediate_uses_for_phi (tree phi, bool (*calc_for)(tree))
00263 {
00264 int i;
00265
00266 gcc_assert (TREE_CODE (phi) == PHI_NODE);
00267
00268 for (i = 0; i < PHI_NUM_ARGS (phi); i++)
00269 {
00270 tree arg = PHI_ARG_DEF (phi, i);
00271
00272 if (TREE_CODE (arg) == SSA_NAME && (!calc_for || calc_for (arg)))
00273 {
00274 tree imm_rdef_stmt = SSA_NAME_DEF_STMT (PHI_ARG_DEF (phi, i));
00275 if (!IS_EMPTY_STMT (imm_rdef_stmt))
00276 add_immediate_use (imm_rdef_stmt, phi);
00277 }
00278 }
00279 }
00280
00281
00282
00283
00284
00285
00286
00287 static void
00288 compute_immediate_uses_for_stmt (tree stmt, int flags, bool (*calc_for)(tree))
00289 {
00290 tree use;
00291 ssa_op_iter iter;
00292
00293
00294 gcc_assert (TREE_CODE (stmt) != PHI_NODE);
00295
00296
00297 if (flags & TDFA_USE_OPS)
00298 {
00299 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
00300 {
00301 tree imm_stmt = SSA_NAME_DEF_STMT (use);
00302 if (!IS_EMPTY_STMT (imm_stmt) && (!calc_for || calc_for (use)))
00303 add_immediate_use (imm_stmt, stmt);
00304 }
00305 }
00306
00307 if (flags & TDFA_USE_VOPS)
00308 {
00309 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VIRTUAL_USES)
00310 {
00311 tree imm_rdef_stmt = SSA_NAME_DEF_STMT (use);
00312 if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (use)))
00313 add_immediate_use (imm_rdef_stmt, stmt);
00314 }
00315
00316 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_KILLS)
00317 {
00318 tree imm_rdef_stmt = SSA_NAME_DEF_STMT (use);
00319 if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (use)))
00320 add_immediate_use (imm_rdef_stmt, stmt);
00321 }
00322 }
00323 }
00324
00325
00326
00327
00328
00329 static void
00330 add_immediate_use (tree stmt, tree use_stmt)
00331 {
00332 struct dataflow_d **df;
00333
00334 if (TREE_CODE (stmt) == PHI_NODE)
00335 df = &PHI_DF (stmt);
00336 else
00337 {
00338 stmt_ann_t ann = get_stmt_ann (stmt);
00339 df = &ann->df;
00340 }
00341
00342 if (*df == NULL)
00343 {
00344 *df = ggc_alloc (sizeof (struct dataflow_d));
00345 memset ((void *) *df, 0, sizeof (struct dataflow_d));
00346 (*df)->uses[0] = use_stmt;
00347 return;
00348 }
00349
00350 if (!(*df)->uses[1])
00351 {
00352 (*df)->uses[1] = use_stmt;
00353 return;
00354 }
00355
00356 if ((*df)->immediate_uses == NULL)
00357 VARRAY_TREE_INIT ((*df)->immediate_uses, 4, "immediate_uses");
00358
00359 VARRAY_PUSH_TREE ((*df)->immediate_uses, use_stmt);
00360 }
00361
00362
00363
00364
00365 static void
00366 redirect_immediate_use (tree use, tree old, tree new)
00367 {
00368 tree imm_stmt = SSA_NAME_DEF_STMT (use);
00369 struct dataflow_d *df = get_immediate_uses (imm_stmt);
00370 unsigned int num_uses = num_immediate_uses (df);
00371 unsigned int i;
00372
00373 for (i = 0; i < num_uses; i++)
00374 {
00375 if (immediate_use (df, i) == old)
00376 {
00377 if (i == 0 || i == 1)
00378 df->uses[i] = new;
00379 else
00380 VARRAY_TREE (df->immediate_uses, i - 2) = new;
00381 }
00382 }
00383 }
00384
00385
00386
00387
00388
00389
00390 void
00391 redirect_immediate_uses (tree old, tree new)
00392 {
00393 ssa_op_iter iter;
00394 tree val;
00395
00396 FOR_EACH_SSA_TREE_OPERAND (val, old, iter, SSA_OP_ALL_USES)
00397 redirect_immediate_use (val, old, new);
00398 }
00399
00400
00401
00402
00403
00404
00405
00406 var_ann_t
00407 create_var_ann (tree t)
00408 {
00409 var_ann_t ann;
00410
00411 gcc_assert (t);
00412 gcc_assert (DECL_P (t));
00413 gcc_assert (!t->common.ann || t->common.ann->common.type == VAR_ANN);
00414
00415 ann = ggc_alloc (sizeof (*ann));
00416 memset ((void *) ann, 0, sizeof (*ann));
00417
00418 ann->common.type = VAR_ANN;
00419
00420 t->common.ann = (tree_ann_t) ann;
00421
00422 return ann;
00423 }
00424
00425
00426
00427
00428 stmt_ann_t
00429 create_stmt_ann (tree t)
00430 {
00431 stmt_ann_t ann;
00432
00433 gcc_assert (is_gimple_stmt (t));
00434 gcc_assert (!t->common.ann || t->common.ann->common.type == STMT_ANN);
00435
00436 ann = ggc_alloc (sizeof (*ann));
00437 memset ((void *) ann, 0, sizeof (*ann));
00438
00439 ann->common.type = STMT_ANN;
00440
00441
00442 ann->modified = true;
00443
00444 t->common.ann = (tree_ann_t) ann;
00445
00446 return ann;
00447 }
00448
00449
00450
00451
00452 tree_ann_t
00453 create_tree_ann (tree t)
00454 {
00455 tree_ann_t ann;
00456
00457 gcc_assert (t);
00458 gcc_assert (!t->common.ann || t->common.ann->common.type == TREE_ANN_COMMON);
00459
00460 ann = ggc_alloc (sizeof (*ann));
00461 memset ((void *) ann, 0, sizeof (*ann));
00462
00463 ann->common.type = TREE_ANN_COMMON;
00464 t->common.ann = ann;
00465
00466 return ann;
00467 }
00468
00469
00470
00471 tree
00472 make_rename_temp (tree type, const char *prefix)
00473 {
00474 tree t = create_tmp_var (type, prefix);
00475 if (referenced_vars)
00476 {
00477 add_referenced_tmp_var (t);
00478 bitmap_set_bit (vars_to_rename, var_ann (t)->uid);
00479 }
00480 return t;
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 void
00492 dump_referenced_vars (FILE *file)
00493 {
00494 size_t i;
00495
00496 fprintf (file, "\nReferenced variables in %s: %u\n\n",
00497 get_name (current_function_decl), (unsigned) num_referenced_vars);
00498
00499 for (i = 0; i < num_referenced_vars; i++)
00500 {
00501 tree var = referenced_var (i);
00502 fprintf (file, "Variable: ");
00503 dump_variable (file, var);
00504 fprintf (file, "\n");
00505 }
00506 }
00507
00508
00509
00510
00511 void
00512 debug_referenced_vars (void)
00513 {
00514 dump_referenced_vars (stderr);
00515 }
00516
00517
00518
00519
00520 void
00521 dump_variable (FILE *file, tree var)
00522 {
00523 var_ann_t ann;
00524
00525 if (TREE_CODE (var) == SSA_NAME)
00526 {
00527 if (POINTER_TYPE_P (TREE_TYPE (var)))
00528 dump_points_to_info_for (file, var);
00529 var = SSA_NAME_VAR (var);
00530 }
00531
00532 if (var == NULL_TREE)
00533 {
00534 fprintf (file, "<nil>");
00535 return;
00536 }
00537
00538 print_generic_expr (file, var, dump_flags);
00539
00540 ann = var_ann (var);
00541
00542 fprintf (file, ", UID %u", (unsigned) ann->uid);
00543
00544 fprintf (file, ", ");
00545 print_generic_expr (file, TREE_TYPE (var), dump_flags);
00546
00547 if (ann->type_mem_tag)
00548 {
00549 fprintf (file, ", type memory tag: ");
00550 print_generic_expr (file, ann->type_mem_tag, dump_flags);
00551 }
00552
00553 if (ann->is_alias_tag)
00554 fprintf (file, ", is an alias tag");
00555
00556 if (TREE_ADDRESSABLE (var))
00557 fprintf (file, ", is addressable");
00558
00559 if (is_global_var (var))
00560 fprintf (file, ", is global");
00561
00562 if (TREE_THIS_VOLATILE (var))
00563 fprintf (file, ", is volatile");
00564
00565 if (is_call_clobbered (var))
00566 fprintf (file, ", call clobbered");
00567
00568 if (ann->default_def)
00569 {
00570 fprintf (file, ", default def: ");
00571 print_generic_expr (file, ann->default_def, dump_flags);
00572 }
00573
00574 if (ann->may_aliases)
00575 {
00576 fprintf (file, ", may aliases: ");
00577 dump_may_aliases_for (file, var);
00578 }
00579
00580 fprintf (file, "\n");
00581 }
00582
00583
00584
00585
00586 void
00587 debug_variable (tree var)
00588 {
00589 dump_variable (stderr, var);
00590 }
00591
00592
00593
00594
00595 void
00596 dump_immediate_uses (FILE *file)
00597 {
00598 basic_block bb;
00599 block_stmt_iterator si;
00600 const char *funcname
00601 = lang_hooks.decl_printable_name (current_function_decl, 2);
00602
00603 fprintf (file, "\nDef-use edges for function %s\n", funcname);
00604
00605 FOR_EACH_BB (bb)
00606 {
00607 tree phi;
00608
00609 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
00610 dump_immediate_uses_for (file, phi);
00611
00612 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
00613 dump_immediate_uses_for (file, bsi_stmt (si));
00614 }
00615
00616 fprintf (file, "\n");
00617 }
00618
00619
00620
00621
00622 void
00623 debug_immediate_uses (void)
00624 {
00625 dump_immediate_uses (stderr);
00626 }
00627
00628
00629
00630
00631 void
00632 dump_immediate_uses_for (FILE *file, tree stmt)
00633 {
00634 dataflow_t df = get_immediate_uses (stmt);
00635 int num_imm_uses = num_immediate_uses (df);
00636
00637 if (num_imm_uses > 0)
00638 {
00639 int i;
00640
00641 fprintf (file, "-> ");
00642 print_generic_stmt (file, stmt, TDF_SLIM);
00643 fprintf (file, "\n");
00644
00645 for (i = 0; i < num_imm_uses; i++)
00646 {
00647 fprintf (file, "\t");
00648 print_generic_stmt (file, immediate_use (df, i), TDF_SLIM);
00649 fprintf (file, "\n");
00650 }
00651
00652 fprintf (file, "\n");
00653 }
00654 }
00655
00656
00657
00658
00659 void
00660 debug_immediate_uses_for (tree stmt)
00661 {
00662 dump_immediate_uses_for (stderr, stmt);
00663 }
00664
00665
00666
00667
00668 void
00669 dump_dfa_stats (FILE *file)
00670 {
00671 struct dfa_stats_d dfa_stats;
00672
00673 unsigned long size, total = 0;
00674 const char * const fmt_str = "%-30s%-13s%12s\n";
00675 const char * const fmt_str_1 = "%-30s%13lu%11lu%c\n";
00676 const char * const fmt_str_3 = "%-43s%11lu%c\n";
00677 const char *funcname
00678 = lang_hooks.decl_printable_name (current_function_decl, 2);
00679
00680 collect_dfa_stats (&dfa_stats);
00681
00682 fprintf (file, "\nDFA Statistics for %s\n\n", funcname);
00683
00684 fprintf (file, "---------------------------------------------------------\n");
00685 fprintf (file, fmt_str, "", " Number of ", "Memory");
00686 fprintf (file, fmt_str, "", " instances ", "used ");
00687 fprintf (file, "---------------------------------------------------------\n");
00688
00689 size = num_referenced_vars * sizeof (tree);
00690 total += size;
00691 fprintf (file, fmt_str_1, "Referenced variables", (unsigned long)num_referenced_vars,
00692 SCALE (size), LABEL (size));
00693
00694 size = dfa_stats.num_stmt_anns * sizeof (struct stmt_ann_d);
00695 total += size;
00696 fprintf (file, fmt_str_1, "Statements annotated", dfa_stats.num_stmt_anns,
00697 SCALE (size), LABEL (size));
00698
00699 size = dfa_stats.num_var_anns * sizeof (struct var_ann_d);
00700 total += size;
00701 fprintf (file, fmt_str_1, "Variables annotated", dfa_stats.num_var_anns,
00702 SCALE (size), LABEL (size));
00703
00704 size = dfa_stats.num_uses * sizeof (tree *);
00705 total += size;
00706 fprintf (file, fmt_str_1, "USE operands", dfa_stats.num_uses,
00707 SCALE (size), LABEL (size));
00708
00709 size = dfa_stats.num_defs * sizeof (tree *);
00710 total += size;
00711 fprintf (file, fmt_str_1, "DEF operands", dfa_stats.num_defs,
00712 SCALE (size), LABEL (size));
00713
00714 size = dfa_stats.num_vuses * sizeof (tree *);
00715 total += size;
00716 fprintf (file, fmt_str_1, "VUSE operands", dfa_stats.num_vuses,
00717 SCALE (size), LABEL (size));
00718
00719 size = dfa_stats.num_v_may_defs * sizeof (tree *);
00720 total += size;
00721 fprintf (file, fmt_str_1, "V_MAY_DEF operands", dfa_stats.num_v_may_defs,
00722 SCALE (size), LABEL (size));
00723
00724 size = dfa_stats.num_v_must_defs * sizeof (tree *);
00725 total += size;
00726 fprintf (file, fmt_str_1, "V_MUST_DEF operands", dfa_stats.num_v_must_defs,
00727 SCALE (size), LABEL (size));
00728
00729 size = dfa_stats.num_phis * sizeof (struct tree_phi_node);
00730 total += size;
00731 fprintf (file, fmt_str_1, "PHI nodes", dfa_stats.num_phis,
00732 SCALE (size), LABEL (size));
00733
00734 size = dfa_stats.num_phi_args * sizeof (struct phi_arg_d);
00735 total += size;
00736 fprintf (file, fmt_str_1, "PHI arguments", dfa_stats.num_phi_args,
00737 SCALE (size), LABEL (size));
00738
00739 fprintf (file, "---------------------------------------------------------\n");
00740 fprintf (file, fmt_str_3, "Total memory used by DFA/SSA data", SCALE (total),
00741 LABEL (total));
00742 fprintf (file, "---------------------------------------------------------\n");
00743 fprintf (file, "\n");
00744
00745 if (dfa_stats.num_phis)
00746 fprintf (file, "Average number of arguments per PHI node: %.1f (max: %d)\n",
00747 (float) dfa_stats.num_phi_args / (float) dfa_stats.num_phis,
00748 dfa_stats.max_num_phi_args);
00749
00750 fprintf (file, "\n");
00751 }
00752
00753
00754
00755
00756 void
00757 debug_dfa_stats (void)
00758 {
00759 dump_dfa_stats (stderr);
00760 }
00761
00762
00763
00764
00765
00766 static void
00767 collect_dfa_stats (struct dfa_stats_d *dfa_stats_p)
00768 {
00769 struct pointer_set_t *pset;
00770 basic_block bb;
00771 block_stmt_iterator i;
00772
00773 gcc_assert (dfa_stats_p);
00774
00775 memset ((void *)dfa_stats_p, 0, sizeof (struct dfa_stats_d));
00776
00777
00778
00779 pset = pointer_set_create ();
00780
00781 for (i = bsi_start (BASIC_BLOCK (0)); !bsi_end_p (i); bsi_next (&i))
00782 walk_tree (bsi_stmt_ptr (i), collect_dfa_stats_r, (void *) dfa_stats_p,
00783 pset);
00784
00785 pointer_set_destroy (pset);
00786
00787 FOR_EACH_BB (bb)
00788 {
00789 tree phi;
00790 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
00791 {
00792 dfa_stats_p->num_phis++;
00793 dfa_stats_p->num_phi_args += PHI_NUM_ARGS (phi);
00794 if (PHI_NUM_ARGS (phi) > dfa_stats_p->max_num_phi_args)
00795 dfa_stats_p->max_num_phi_args = PHI_NUM_ARGS (phi);
00796 }
00797 }
00798 }
00799
00800
00801
00802
00803
00804 static tree
00805 collect_dfa_stats_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
00806 void *data)
00807 {
00808 tree t = *tp;
00809 struct dfa_stats_d *dfa_stats_p = (struct dfa_stats_d *)data;
00810
00811 if (t->common.ann)
00812 {
00813 switch (ann_type (t->common.ann))
00814 {
00815 case STMT_ANN:
00816 {
00817 stmt_ann_t ann = (stmt_ann_t) t->common.ann;
00818 dfa_stats_p->num_stmt_anns++;
00819 dfa_stats_p->num_defs += NUM_DEFS (DEF_OPS (ann));
00820 dfa_stats_p->num_uses += NUM_USES (USE_OPS (ann));
00821 dfa_stats_p->num_v_may_defs +=
00822 NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann));
00823 dfa_stats_p->num_vuses += NUM_VUSES (VUSE_OPS (ann));
00824 dfa_stats_p->num_v_must_defs +=
00825 NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann));
00826 break;
00827 }
00828
00829 case VAR_ANN:
00830 dfa_stats_p->num_var_anns++;
00831 break;
00832
00833 default:
00834 break;
00835 }
00836 }
00837
00838 return NULL;
00839 }
00840
00841
00842
00843
00844
00845
00846
00847
00848 static tree
00849 find_vars_r (tree *tp, int *walk_subtrees, void *data)
00850 {
00851 struct walk_state *walk_state = (struct walk_state *) data;
00852
00853
00854
00855 if (SSA_VAR_P (*tp))
00856 add_referenced_var (*tp, walk_state);
00857
00858
00859
00860 else if (IS_TYPE_OR_DECL_P (*tp) || CONSTANT_CLASS_P (*tp))
00861 *walk_subtrees = 0;
00862
00863 return NULL_TREE;
00864 }
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874 static void
00875 add_referenced_var (tree var, struct walk_state *walk_state)
00876 {
00877 void **slot;
00878 var_ann_t v_ann;
00879
00880 v_ann = get_var_ann (var);
00881
00882 if (walk_state)
00883 slot = htab_find_slot (walk_state->vars_found, (void *) var, INSERT);
00884 else
00885 slot = NULL;
00886
00887 if (slot == NULL || *slot == NULL)
00888 {
00889
00890
00891
00892 if (slot)
00893 *slot = (void *) var;
00894 v_ann->uid = num_referenced_vars;
00895 VARRAY_PUSH_TREE (referenced_vars, var);
00896
00897
00898 if (is_global_var (var))
00899 mark_call_clobbered (var);
00900
00901
00902
00903
00904 if (DECL_INITIAL (var))
00905 walk_tree (&DECL_INITIAL (var), find_vars_r, walk_state, 0);
00906 }
00907 }
00908
00909
00910
00911
00912 tree
00913 get_virtual_var (tree var)
00914 {
00915 STRIP_NOPS (var);
00916
00917 if (TREE_CODE (var) == SSA_NAME)
00918 var = SSA_NAME_VAR (var);
00919
00920 while (TREE_CODE (var) == REALPART_EXPR || TREE_CODE (var) == IMAGPART_EXPR
00921 || handled_component_p (var))
00922 var = TREE_OPERAND (var, 0);
00923
00924
00925
00926
00927 gcc_assert (SSA_VAR_P (var));
00928 gcc_assert (!is_gimple_reg (var));
00929
00930 return var;
00931 }
00932
00933
00934
00935
00936
00937
00938
00939 void
00940 add_referenced_tmp_var (tree var)
00941 {
00942 add_referenced_var (var, NULL);
00943 }
00944
00945
00946
00947
00948
00949 void
00950 mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename)
00951 {
00952 ssa_op_iter iter;
00953 tree val;
00954 bitmap vars_in_vops_to_rename;
00955 bool found_exposed_symbol = false;
00956 int v_may_defs_before, v_may_defs_after;
00957 int v_must_defs_before, v_must_defs_after;
00958
00959 vars_in_vops_to_rename = BITMAP_ALLOC (NULL);
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970 v_may_defs_before = NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt));
00971 v_must_defs_before = NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt));
00972
00973 FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter,
00974 SSA_OP_VMAYDEF | SSA_OP_VUSE | SSA_OP_VMUSTDEF)
00975 {
00976 if (!DECL_P (val))
00977 val = SSA_NAME_VAR (val);
00978 bitmap_set_bit (vars_in_vops_to_rename, var_ann (val)->uid);
00979 }
00980
00981
00982
00983 modify_stmt (stmt);
00984 get_stmt_operands (stmt);
00985
00986 v_may_defs_after = NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt));
00987 v_must_defs_after = NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt));
00988
00989 FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_ALL_OPERANDS)
00990 {
00991 if (DECL_P (val))
00992 {
00993 found_exposed_symbol = true;
00994 bitmap_set_bit (vars_to_rename, var_ann (val)->uid);
00995 }
00996 }
00997
00998
00999
01000
01001
01002
01003 if (found_exposed_symbol
01004 || v_may_defs_before > v_may_defs_after
01005 || v_must_defs_before > v_must_defs_after)
01006 bitmap_ior_into (vars_to_rename, vars_in_vops_to_rename);
01007
01008 BITMAP_FREE (vars_in_vops_to_rename);
01009 }
01010
01011
01012
01013
01014 static tree
01015 find_new_referenced_vars_1 (tree *tp, int *walk_subtrees,
01016 void *data ATTRIBUTE_UNUSED)
01017 {
01018 tree t = *tp;
01019
01020 if (TREE_CODE (t) == VAR_DECL && !var_ann (t))
01021 add_referenced_tmp_var (t);
01022
01023 if (IS_TYPE_OR_DECL_P (t))
01024 *walk_subtrees = 0;
01025
01026 return NULL;
01027 }
01028
01029 void
01030 find_new_referenced_vars (tree *stmt_p)
01031 {
01032 walk_tree (stmt_p, find_new_referenced_vars_1, NULL, NULL);
01033 }
01034
01035
01036
01037
01038 void
01039 mark_call_clobbered_vars_to_rename (void)
01040 {
01041 unsigned i;
01042 bitmap_iterator bi;
01043 EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
01044 {
01045 tree var = referenced_var (i);
01046 bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
01047 }
01048 }