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 "tree.h"
00027 #include "flags.h"
00028 #include "rtl.h"
00029 #include "tm_p.h"
00030 #include "langhooks.h"
00031 #include "hard-reg-set.h"
00032 #include "basic-block.h"
00033 #include "output.h"
00034 #include "expr.h"
00035 #include "function.h"
00036 #include "diagnostic.h"
00037 #include "bitmap.h"
00038 #include "tree-flow.h"
00039 #include "tree-gimple.h"
00040 #include "tree-inline.h"
00041 #include "varray.h"
00042 #include "timevar.h"
00043 #include "hashtab.h"
00044 #include "tree-dump.h"
00045 #include "tree-pass.h"
00046 #include "cfgloop.h"
00047 #include "domwalk.h"
00048 #include "ggc.h"
00049 #include "params.h"
00050 #include "vecprim.h"
00051
00052
00053
00054
00055
00056
00057
00058
00059 bool in_ssa_p;
00060
00061
00062
00063 struct def_blocks_d
00064 {
00065
00066 tree var;
00067
00068
00069
00070 bitmap def_blocks;
00071
00072
00073 bitmap phi_blocks;
00074
00075
00076
00077 bitmap livein_blocks;
00078 };
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 static htab_t def_blocks;
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 static VEC(tree,heap) *block_defs_stack;
00106
00107
00108 static sbitmap old_ssa_names;
00109
00110
00111
00112
00113 static sbitmap new_ssa_names;
00114
00115
00116
00117 static bitmap syms_to_rename;
00118
00119
00120
00121
00122 static bitmap names_to_release;
00123
00124
00125
00126
00127 typedef VEC(tree, heap) *tree_vec;
00128 DEF_VEC_P (tree_vec);
00129 DEF_VEC_ALLOC_P (tree_vec, heap);
00130
00131 static VEC(tree_vec, heap) *phis_to_rewrite;
00132
00133
00134
00135 static bitmap blocks_with_phis_to_rewrite;
00136
00137
00138
00139
00140
00141
00142 #define NAME_SETS_GROWTH_FACTOR (MAX (3, num_ssa_names / 3))
00143
00144
00145 struct repl_map_d
00146 {
00147 tree name;
00148 bitmap set;
00149 };
00150
00151
00152
00153
00154 static htab_t repl_tbl;
00155
00156
00157
00158 static bool need_to_initialize_update_ssa_p = true;
00159
00160
00161 static bool need_to_update_vops_p = false;
00162
00163
00164
00165
00166
00167
00168
00169 struct update_ssa_stats_d
00170 {
00171 unsigned num_virtual_mappings;
00172 unsigned num_total_mappings;
00173 bitmap virtual_symbols;
00174 unsigned num_virtual_symbols;
00175 };
00176 static struct update_ssa_stats_d update_ssa_stats;
00177
00178
00179 struct mark_def_sites_global_data
00180 {
00181
00182
00183 bitmap kills;
00184
00185
00186 sbitmap names_to_rename;
00187
00188
00189
00190 sbitmap interesting_blocks;
00191 };
00192
00193
00194
00195 struct ssa_name_info
00196 {
00197
00198 tree current_def;
00199
00200
00201
00202
00203 ENUM_BITFIELD (need_phi_state) need_phi_state : 2;
00204
00205
00206
00207
00208 unsigned age;
00209 };
00210
00211
00212 typedef struct ssa_name_info *ssa_name_info_p;
00213 DEF_VEC_P (ssa_name_info_p);
00214 DEF_VEC_ALLOC_P (ssa_name_info_p, heap);
00215
00216 static VEC(ssa_name_info_p, heap) *info_for_ssa_name;
00217 static unsigned current_info_for_ssa_name_age;
00218
00219
00220
00221 static bitmap blocks_to_update;
00222
00223
00224
00225
00226
00227
00228
00229 enum rewrite_mode {
00230
00231 REWRITE_ALL,
00232
00233
00234
00235 REWRITE_UPDATE
00236 };
00237
00238
00239
00240
00241
00242 #define REWRITE_THIS_STMT(T) TREE_VISITED (T)
00243
00244
00245
00246
00247
00248
00249
00250
00251 #define REGISTER_DEFS_IN_THIS_STMT(T) (T)->common.unsigned_flag
00252
00253
00254
00255 extern void dump_tree_ssa (FILE *);
00256 extern void debug_tree_ssa (void);
00257 extern void debug_def_blocks (void);
00258 extern void dump_tree_ssa_stats (FILE *);
00259 extern void debug_tree_ssa_stats (void);
00260 void dump_update_ssa (FILE *);
00261 void debug_update_ssa (void);
00262 void dump_names_replaced_by (FILE *, tree);
00263 void debug_names_replaced_by (tree);
00264
00265
00266
00267 static inline struct ssa_name_info *
00268 get_ssa_name_ann (tree name)
00269 {
00270 unsigned ver = SSA_NAME_VERSION (name);
00271 unsigned len = VEC_length (ssa_name_info_p, info_for_ssa_name);
00272 struct ssa_name_info *info;
00273
00274 if (ver >= len)
00275 {
00276 unsigned new_len = num_ssa_names;
00277
00278 VEC_reserve (ssa_name_info_p, heap, info_for_ssa_name, new_len);
00279 while (len++ < new_len)
00280 {
00281 struct ssa_name_info *info = XCNEW (struct ssa_name_info);
00282 info->age = current_info_for_ssa_name_age;
00283 VEC_quick_push (ssa_name_info_p, info_for_ssa_name, info);
00284 }
00285 }
00286
00287 info = VEC_index (ssa_name_info_p, info_for_ssa_name, ver);
00288 if (info->age < current_info_for_ssa_name_age)
00289 {
00290 info->need_phi_state = 0;
00291 info->current_def = NULL_TREE;
00292 info->age = current_info_for_ssa_name_age;
00293 }
00294
00295 return info;
00296 }
00297
00298
00299
00300 static void
00301 clear_ssa_name_info (void)
00302 {
00303 current_info_for_ssa_name_age++;
00304 }
00305
00306
00307
00308 static inline enum need_phi_state
00309 get_phi_state (tree var)
00310 {
00311 if (TREE_CODE (var) == SSA_NAME)
00312 return get_ssa_name_ann (var)->need_phi_state;
00313 else
00314 return var_ann (var)->need_phi_state;
00315 }
00316
00317
00318
00319
00320 static inline void
00321 set_phi_state (tree var, enum need_phi_state state)
00322 {
00323 if (TREE_CODE (var) == SSA_NAME)
00324 get_ssa_name_ann (var)->need_phi_state = state;
00325 else
00326 var_ann (var)->need_phi_state = state;
00327 }
00328
00329
00330
00331
00332 tree
00333 get_current_def (tree var)
00334 {
00335 if (TREE_CODE (var) == SSA_NAME)
00336 return get_ssa_name_ann (var)->current_def;
00337 else
00338 return var_ann (var)->current_def;
00339 }
00340
00341
00342
00343
00344 void
00345 set_current_def (tree var, tree def)
00346 {
00347 if (TREE_CODE (var) == SSA_NAME)
00348 get_ssa_name_ann (var)->current_def = def;
00349 else
00350 var_ann (var)->current_def = def;
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 void
00363 compute_global_livein (bitmap livein, bitmap def_blocks)
00364 {
00365 basic_block bb, *worklist, *tos;
00366 unsigned i;
00367 bitmap_iterator bi;
00368
00369 tos = worklist
00370 = (basic_block *) xmalloc (sizeof (basic_block) * (last_basic_block + 1));
00371
00372 EXECUTE_IF_SET_IN_BITMAP (livein, 0, i, bi)
00373 {
00374 *tos++ = BASIC_BLOCK (i);
00375 }
00376
00377
00378 while (tos != worklist)
00379 {
00380 edge e;
00381 edge_iterator ei;
00382
00383
00384 bb = *--tos;
00385
00386
00387 FOR_EACH_EDGE (e, ei, bb->preds)
00388 {
00389 basic_block pred = e->src;
00390 int pred_index = pred->index;
00391
00392
00393 if (pred != ENTRY_BLOCK_PTR
00394 && ! bitmap_bit_p (livein, pred_index)
00395 && ! bitmap_bit_p (def_blocks, pred_index))
00396 {
00397 *tos++ = pred;
00398 bitmap_set_bit (livein, pred_index);
00399 }
00400 }
00401 }
00402
00403 free (worklist);
00404 }
00405
00406
00407
00408
00409
00410 static void
00411 initialize_flags_in_bb (basic_block bb)
00412 {
00413 tree phi, stmt;
00414 block_stmt_iterator bsi;
00415
00416 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
00417 {
00418 REWRITE_THIS_STMT (phi) = 0;
00419 REGISTER_DEFS_IN_THIS_STMT (phi) = 0;
00420 }
00421
00422 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
00423 {
00424 stmt = bsi_stmt (bsi);
00425
00426
00427
00428 gcc_assert (!stmt_modified_p (stmt));
00429 REWRITE_THIS_STMT (stmt) = 0;
00430 REGISTER_DEFS_IN_THIS_STMT (stmt) = 0;
00431 }
00432 }
00433
00434
00435
00436 static void
00437 mark_block_for_update (basic_block bb)
00438 {
00439 gcc_assert (blocks_to_update != NULL);
00440 if (bitmap_bit_p (blocks_to_update, bb->index))
00441 return;
00442 bitmap_set_bit (blocks_to_update, bb->index);
00443 initialize_flags_in_bb (bb);
00444 }
00445
00446
00447
00448
00449
00450 static inline struct def_blocks_d *
00451 get_def_blocks_for (tree var)
00452 {
00453 struct def_blocks_d db, *db_p;
00454 void **slot;
00455
00456 db.var = var;
00457 slot = htab_find_slot (def_blocks, (void *) &db, INSERT);
00458 if (*slot == NULL)
00459 {
00460 db_p = XNEW (struct def_blocks_d);
00461 db_p->var = var;
00462 db_p->def_blocks = BITMAP_ALLOC (NULL);
00463 db_p->phi_blocks = BITMAP_ALLOC (NULL);
00464 db_p->livein_blocks = BITMAP_ALLOC (NULL);
00465 *slot = (void *) db_p;
00466 }
00467 else
00468 db_p = (struct def_blocks_d *) *slot;
00469
00470 return db_p;
00471 }
00472
00473
00474
00475
00476
00477 static void
00478 set_def_block (tree var, basic_block bb, bool phi_p)
00479 {
00480 struct def_blocks_d *db_p;
00481 enum need_phi_state state;
00482
00483 state = get_phi_state (var);
00484 db_p = get_def_blocks_for (var);
00485
00486
00487 bitmap_set_bit (db_p->def_blocks, bb->index);
00488 if (phi_p)
00489 bitmap_set_bit (db_p->phi_blocks, bb->index);
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 if (state == NEED_PHI_STATE_UNKNOWN)
00504 set_phi_state (var, NEED_PHI_STATE_NO);
00505 else
00506 set_phi_state (var, NEED_PHI_STATE_MAYBE);
00507 }
00508
00509
00510
00511
00512 static void
00513 set_livein_block (tree var, basic_block bb)
00514 {
00515 struct def_blocks_d *db_p;
00516 enum need_phi_state state = get_phi_state (var);
00517
00518 db_p = get_def_blocks_for (var);
00519
00520
00521 bitmap_set_bit (db_p->livein_blocks, bb->index);
00522
00523
00524
00525
00526
00527
00528
00529 if (state == NEED_PHI_STATE_NO)
00530 {
00531 int def_block_index = bitmap_first_set_bit (db_p->def_blocks);
00532
00533 if (def_block_index == -1
00534 || ! dominated_by_p (CDI_DOMINATORS, bb,
00535 BASIC_BLOCK (def_block_index)))
00536 set_phi_state (var, NEED_PHI_STATE_MAYBE);
00537 }
00538 else
00539 set_phi_state (var, NEED_PHI_STATE_MAYBE);
00540 }
00541
00542
00543
00544
00545 static inline bool
00546 symbol_marked_for_renaming (tree sym)
00547 {
00548 gcc_assert (DECL_P (sym));
00549 return bitmap_bit_p (syms_to_rename, DECL_UID (sym));
00550 }
00551
00552
00553
00554
00555 static inline bool
00556 is_old_name (tree name)
00557 {
00558 unsigned ver = SSA_NAME_VERSION (name);
00559 return ver < new_ssa_names->n_bits && TEST_BIT (old_ssa_names, ver);
00560 }
00561
00562
00563
00564
00565 static inline bool
00566 is_new_name (tree name)
00567 {
00568 unsigned ver = SSA_NAME_VERSION (name);
00569 return ver < new_ssa_names->n_bits && TEST_BIT (new_ssa_names, ver);
00570 }
00571
00572
00573
00574
00575 static hashval_t
00576 repl_map_hash (const void *p)
00577 {
00578 return htab_hash_pointer ((const void *)((const struct repl_map_d *)p)->name);
00579 }
00580
00581 static int
00582 repl_map_eq (const void *p1, const void *p2)
00583 {
00584 return ((const struct repl_map_d *)p1)->name
00585 == ((const struct repl_map_d *)p2)->name;
00586 }
00587
00588 static void
00589 repl_map_free (void *p)
00590 {
00591 BITMAP_FREE (((struct repl_map_d *)p)->set);
00592 free (p);
00593 }
00594
00595
00596
00597
00598 static inline bitmap
00599 names_replaced_by (tree new)
00600 {
00601 struct repl_map_d m;
00602 void **slot;
00603
00604 m.name = new;
00605 slot = htab_find_slot (repl_tbl, (void *) &m, NO_INSERT);
00606
00607
00608 if (slot == NULL || *slot == NULL)
00609 return NULL;
00610
00611 return ((struct repl_map_d *) *slot)->set;
00612 }
00613
00614
00615
00616
00617 static inline void
00618 add_to_repl_tbl (tree new, tree old)
00619 {
00620 struct repl_map_d m, *mp;
00621 void **slot;
00622
00623 m.name = new;
00624 slot = htab_find_slot (repl_tbl, (void *) &m, INSERT);
00625 if (*slot == NULL)
00626 {
00627 mp = XNEW (struct repl_map_d);
00628 mp->name = new;
00629 mp->set = BITMAP_ALLOC (NULL);
00630 *slot = (void *) mp;
00631 }
00632 else
00633 mp = (struct repl_map_d *) *slot;
00634
00635 bitmap_set_bit (mp->set, SSA_NAME_VERSION (old));
00636 }
00637
00638
00639
00640
00641
00642
00643
00644 static void
00645 add_new_name_mapping (tree new, tree old)
00646 {
00647 timevar_push (TV_TREE_SSA_INCREMENTAL);
00648
00649
00650 gcc_assert (new != old && SSA_NAME_VAR (new) == SSA_NAME_VAR (old));
00651
00652
00653
00654 if (new_ssa_names->n_bits <= num_ssa_names - 1)
00655 {
00656 unsigned int new_sz = num_ssa_names + NAME_SETS_GROWTH_FACTOR;
00657 new_ssa_names = sbitmap_resize (new_ssa_names, new_sz, 0);
00658 old_ssa_names = sbitmap_resize (old_ssa_names, new_sz, 0);
00659 }
00660
00661
00662
00663 if (!is_gimple_reg (new))
00664 {
00665 tree sym;
00666 size_t uid;
00667
00668 need_to_update_vops_p = true;
00669
00670
00671
00672
00673
00674
00675
00676 sym = SSA_NAME_VAR (new);
00677 uid = DECL_UID (sym);
00678 update_ssa_stats.num_virtual_mappings++;
00679 if (!bitmap_bit_p (update_ssa_stats.virtual_symbols, uid))
00680 {
00681 bitmap_set_bit (update_ssa_stats.virtual_symbols, uid);
00682 update_ssa_stats.num_virtual_symbols++;
00683 }
00684 }
00685
00686
00687 add_to_repl_tbl (new, old);
00688
00689
00690
00691 if (is_new_name (old))
00692 bitmap_ior_into (names_replaced_by (new), names_replaced_by (old));
00693
00694
00695
00696 SET_BIT (new_ssa_names, SSA_NAME_VERSION (new));
00697 SET_BIT (old_ssa_names, SSA_NAME_VERSION (old));
00698
00699
00700 update_ssa_stats.num_total_mappings++;
00701
00702 timevar_pop (TV_TREE_SSA_INCREMENTAL);
00703 }
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 static void
00721 mark_def_sites (struct dom_walk_data *walk_data,
00722 basic_block bb,
00723 block_stmt_iterator bsi)
00724 {
00725 struct mark_def_sites_global_data *gd =
00726 (struct mark_def_sites_global_data *) walk_data->global_data;
00727 bitmap kills = gd->kills;
00728 tree stmt, def;
00729 use_operand_p use_p;
00730 def_operand_p def_p;
00731 ssa_op_iter iter;
00732
00733 stmt = bsi_stmt (bsi);
00734 update_stmt_if_modified (stmt);
00735
00736 gcc_assert (blocks_to_update == NULL);
00737 REGISTER_DEFS_IN_THIS_STMT (stmt) = 0;
00738 REWRITE_THIS_STMT (stmt) = 0;
00739
00740
00741
00742 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
00743 SSA_OP_USE | SSA_OP_VUSE | SSA_OP_VMUSTKILL)
00744 {
00745 tree sym = USE_FROM_PTR (use_p);
00746 gcc_assert (DECL_P (sym));
00747 if (!bitmap_bit_p (kills, DECL_UID (sym)))
00748 set_livein_block (sym, bb);
00749 REWRITE_THIS_STMT (stmt) = 1;
00750 }
00751
00752
00753
00754
00755
00756
00757 FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
00758 {
00759 tree sym = USE_FROM_PTR (use_p);
00760 gcc_assert (DECL_P (sym));
00761 set_livein_block (sym, bb);
00762 set_def_block (sym, bb, false);
00763 REGISTER_DEFS_IN_THIS_STMT (stmt) = 1;
00764 REWRITE_THIS_STMT (stmt) = 1;
00765 }
00766
00767
00768 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF | SSA_OP_VMUSTDEF)
00769 {
00770 gcc_assert (DECL_P (def));
00771 set_def_block (def, bb, false);
00772 bitmap_set_bit (kills, DECL_UID (def));
00773 REGISTER_DEFS_IN_THIS_STMT (stmt) = 1;
00774 }
00775
00776
00777
00778 if (REWRITE_THIS_STMT (stmt) || REGISTER_DEFS_IN_THIS_STMT (stmt))
00779 SET_BIT (gd->interesting_blocks, bb->index);
00780 }
00781
00782
00783
00784
00785 struct dom_dfsnum
00786 {
00787
00788 unsigned bb_index;
00789
00790
00791 unsigned dfs_num;
00792 };
00793
00794
00795
00796
00797 static int
00798 cmp_dfsnum (const void *a, const void *b)
00799 {
00800 const struct dom_dfsnum *da = a;
00801 const struct dom_dfsnum *db = b;
00802
00803 return (int) da->dfs_num - (int) db->dfs_num;
00804 }
00805
00806
00807
00808
00809 static unsigned
00810 find_dfsnum_interval (struct dom_dfsnum *defs, unsigned n, unsigned s)
00811 {
00812 unsigned f = 0, t = n, m;
00813
00814 while (t > f + 1)
00815 {
00816 m = (f + t) / 2;
00817 if (defs[m].dfs_num <= s)
00818 f = m;
00819 else
00820 t = m;
00821 }
00822
00823 return defs[f].bb_index;
00824 }
00825
00826
00827
00828
00829 static void
00830 prune_unused_phi_nodes (bitmap phis, bitmap kills, bitmap uses)
00831 {
00832 VEC(int, heap) *worklist;
00833 bitmap_iterator bi;
00834 unsigned i, b, p, u, top;
00835 bitmap live_phis;
00836 basic_block def_bb, use_bb;
00837 edge e;
00838 edge_iterator ei;
00839 bitmap to_remove;
00840 struct dom_dfsnum *defs;
00841 unsigned n_defs, adef;
00842
00843 if (bitmap_empty_p (uses))
00844 {
00845 bitmap_clear (phis);
00846 return;
00847 }
00848
00849
00850
00851 to_remove = BITMAP_ALLOC (NULL);
00852 bitmap_and_compl (to_remove, kills, uses);
00853 bitmap_and_compl_into (phis, to_remove);
00854 if (bitmap_empty_p (phis))
00855 {
00856 BITMAP_FREE (to_remove);
00857 return;
00858 }
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878 bitmap_ior (to_remove, kills, phis);
00879 n_defs = bitmap_count_bits (to_remove);
00880 defs = XNEWVEC (struct dom_dfsnum, 2 * n_defs + 1);
00881 defs[0].bb_index = 1;
00882 defs[0].dfs_num = 0;
00883 adef = 1;
00884 EXECUTE_IF_SET_IN_BITMAP (to_remove, 0, i, bi)
00885 {
00886 def_bb = BASIC_BLOCK (i);
00887 defs[adef].bb_index = i;
00888 defs[adef].dfs_num = bb_dom_dfs_in (CDI_DOMINATORS, def_bb);
00889 defs[adef + 1].bb_index = i;
00890 defs[adef + 1].dfs_num = bb_dom_dfs_out (CDI_DOMINATORS, def_bb);
00891 adef += 2;
00892 }
00893 BITMAP_FREE (to_remove);
00894 gcc_assert (adef == 2 * n_defs + 1);
00895 qsort (defs, adef, sizeof (struct dom_dfsnum), cmp_dfsnum);
00896 gcc_assert (defs[0].bb_index == 1);
00897
00898
00899
00900
00901
00902
00903
00904 worklist = VEC_alloc (int, heap, n_defs + 1);
00905 VEC_quick_push (int, worklist, 1);
00906 top = 1;
00907 n_defs = 1;
00908 for (i = 1; i < adef; i++)
00909 {
00910 b = defs[i].bb_index;
00911 if (b == top)
00912 {
00913
00914
00915 VEC_pop (int, worklist);
00916 top = VEC_index (int, worklist, VEC_length (int, worklist) - 1);
00917 defs[n_defs].bb_index = top;
00918 defs[n_defs].dfs_num = defs[i].dfs_num + 1;
00919 }
00920 else
00921 {
00922
00923
00924 defs[n_defs].bb_index = defs[i].bb_index;
00925 defs[n_defs].dfs_num = defs[i].dfs_num;
00926 VEC_quick_push (int, worklist, b);
00927 top = b;
00928 }
00929
00930
00931
00932 if (defs[n_defs].dfs_num == defs[n_defs - 1].dfs_num)
00933 defs[n_defs - 1].bb_index = defs[n_defs].bb_index;
00934 else
00935 n_defs++;
00936 }
00937 VEC_pop (int, worklist);
00938 gcc_assert (VEC_empty (int, worklist));
00939
00940
00941 live_phis = BITMAP_ALLOC (NULL);
00942 EXECUTE_IF_SET_IN_BITMAP (uses, 0, i, bi)
00943 {
00944 VEC_safe_push (int, heap, worklist, i);
00945 }
00946
00947 while (!VEC_empty (int, worklist))
00948 {
00949 b = VEC_pop (int, worklist);
00950 if (b == ENTRY_BLOCK)
00951 continue;
00952
00953
00954
00955
00956 if (bitmap_bit_p (phis, b))
00957 p = b;
00958 else
00959 {
00960 use_bb = get_immediate_dominator (CDI_DOMINATORS, BASIC_BLOCK (b));
00961 p = find_dfsnum_interval (defs, n_defs,
00962 bb_dom_dfs_in (CDI_DOMINATORS, use_bb));
00963 if (!bitmap_bit_p (phis, p))
00964 continue;
00965 }
00966
00967
00968 if (bitmap_bit_p (live_phis, p))
00969 continue;
00970
00971
00972 bitmap_set_bit (live_phis, p);
00973 def_bb = BASIC_BLOCK (p);
00974 FOR_EACH_EDGE (e, ei, def_bb->preds)
00975 {
00976 u = e->src->index;
00977 if (bitmap_bit_p (uses, u))
00978 continue;
00979
00980
00981
00982
00983
00984 if (bitmap_bit_p (kills, u))
00985 continue;
00986
00987 bitmap_set_bit (uses, u);
00988 VEC_safe_push (int, heap, worklist, u);
00989 }
00990 }
00991
00992 VEC_free (int, heap, worklist);
00993 bitmap_copy (phis, live_phis);
00994 BITMAP_FREE (live_phis);
00995 free (defs);
00996 }
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007 static bitmap
01008 find_idf (bitmap def_blocks, bitmap *dfs)
01009 {
01010 bitmap_iterator bi;
01011 unsigned bb_index;
01012 VEC(int,heap) *work_stack;
01013 bitmap phi_insertion_points;
01014
01015 work_stack = VEC_alloc (int, heap, n_basic_blocks);
01016 phi_insertion_points = BITMAP_ALLOC (NULL);
01017
01018
01019 EXECUTE_IF_SET_IN_BITMAP (def_blocks, 0, bb_index, bi)
01020
01021
01022
01023
01024 VEC_quick_push (int, work_stack, bb_index);
01025
01026
01027
01028
01029
01030
01031 while (VEC_length (int, work_stack) > 0)
01032 {
01033 bb_index = VEC_pop (int, work_stack);
01034
01035
01036
01037
01038
01039
01040 gcc_assert (bb_index < (unsigned) last_basic_block);
01041
01042 EXECUTE_IF_AND_COMPL_IN_BITMAP (dfs[bb_index], phi_insertion_points,
01043 0, bb_index, bi)
01044 {
01045
01046
01047
01048 VEC_safe_push (int, heap, work_stack, bb_index);
01049 bitmap_set_bit (phi_insertion_points, bb_index);
01050 }
01051 }
01052
01053 VEC_free (int, heap, work_stack);
01054
01055 return phi_insertion_points;
01056 }
01057
01058
01059
01060
01061
01062
01063 static inline struct def_blocks_d *
01064 find_def_blocks_for (tree var)
01065 {
01066 struct def_blocks_d dm;
01067 dm.var = var;
01068 return (struct def_blocks_d *) htab_find (def_blocks, &dm);
01069 }
01070
01071
01072
01073
01074 static inline tree
01075 get_default_def_for (tree sym)
01076 {
01077 tree ddef = default_def (sym);
01078
01079 if (ddef == NULL_TREE)
01080 {
01081 ddef = make_ssa_name (sym, build_empty_stmt ());
01082 set_default_def (sym, ddef);
01083 }
01084
01085 return ddef;
01086 }
01087
01088
01089
01090
01091 static void
01092 mark_phi_for_rewrite (basic_block bb, tree phi)
01093 {
01094 tree_vec phis;
01095 unsigned i, idx = bb->index;
01096
01097 if (REWRITE_THIS_STMT (phi))
01098 return;
01099 REWRITE_THIS_STMT (phi) = 1;
01100
01101 if (!blocks_with_phis_to_rewrite)
01102 return;
01103
01104 bitmap_set_bit (blocks_with_phis_to_rewrite, idx);
01105 VEC_reserve (tree_vec, heap, phis_to_rewrite, last_basic_block + 1);
01106 for (i = VEC_length (tree_vec, phis_to_rewrite); i <= idx; i++)
01107 VEC_quick_push (tree_vec, phis_to_rewrite, NULL);
01108
01109 phis = VEC_index (tree_vec, phis_to_rewrite, idx);
01110 if (!phis)
01111 phis = VEC_alloc (tree, heap, 10);
01112
01113 VEC_safe_push (tree, heap, phis, phi);
01114 VEC_replace (tree_vec, phis_to_rewrite, idx, phis);
01115 }
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128 static void
01129 insert_phi_nodes_for (tree var, bitmap phi_insertion_points, bool update_p)
01130 {
01131 unsigned bb_index;
01132 edge e;
01133 tree phi;
01134 basic_block bb;
01135 bitmap_iterator bi;
01136 struct def_blocks_d *def_map;
01137
01138 def_map = find_def_blocks_for (var);
01139 gcc_assert (def_map);
01140
01141
01142 bitmap_and_compl_into (phi_insertion_points, def_map->phi_blocks);
01143
01144
01145 prune_unused_phi_nodes (phi_insertion_points, def_map->def_blocks,
01146 def_map->livein_blocks);
01147
01148
01149 EXECUTE_IF_SET_IN_BITMAP (phi_insertion_points, 0, bb_index, bi)
01150 {
01151 bb = BASIC_BLOCK (bb_index);
01152 if (update_p)
01153 mark_block_for_update (bb);
01154
01155 if (update_p && TREE_CODE (var) == SSA_NAME)
01156 {
01157
01158
01159
01160
01161 edge_iterator ei;
01162 tree new_lhs;
01163
01164 phi = create_phi_node (var, bb);
01165 new_lhs = duplicate_ssa_name (var, phi);
01166 SET_PHI_RESULT (phi, new_lhs);
01167 add_new_name_mapping (new_lhs, var);
01168
01169
01170
01171
01172
01173
01174
01175 FOR_EACH_EDGE (e, ei, bb->preds)
01176 add_phi_arg (phi, var, e);
01177 }
01178 else
01179 {
01180 tree sym = DECL_P (var) ? var : SSA_NAME_VAR (var);
01181 phi = create_phi_node (sym, bb);
01182 }
01183
01184
01185 REGISTER_DEFS_IN_THIS_STMT (phi) = 1;
01186 mark_phi_for_rewrite (bb, phi);
01187 }
01188 }
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198 static void
01199 insert_phi_nodes (bitmap *dfs)
01200 {
01201 referenced_var_iterator rvi;
01202 tree var;
01203
01204 timevar_push (TV_TREE_INSERT_PHI_NODES);
01205
01206 FOR_EACH_REFERENCED_VAR (var, rvi)
01207 {
01208 struct def_blocks_d *def_map;
01209 bitmap idf;
01210
01211 def_map = find_def_blocks_for (var);
01212 if (def_map == NULL)
01213 continue;
01214
01215 if (get_phi_state (var) != NEED_PHI_STATE_NO)
01216 {
01217 idf = find_idf (def_map->def_blocks, dfs);
01218 insert_phi_nodes_for (var, idf, false);
01219 BITMAP_FREE (idf);
01220 }
01221 }
01222
01223 timevar_pop (TV_TREE_INSERT_PHI_NODES);
01224 }
01225
01226
01227
01228
01229
01230
01231 void
01232 register_new_def (tree def, VEC(tree,heap) **block_defs_p)
01233 {
01234 tree var = SSA_NAME_VAR (def);
01235 tree currdef;
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245 if (get_phi_state (var) == NEED_PHI_STATE_NO)
01246 {
01247 set_current_def (var, def);
01248 return;
01249 }
01250
01251 currdef = get_current_def (var);
01252
01253
01254
01255
01256
01257
01258 VEC_safe_push (tree, heap, *block_defs_p, currdef ? currdef : var);
01259
01260
01261 set_current_def (var, def);
01262 }
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293 static void
01294 rewrite_initialize_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
01295 basic_block bb)
01296 {
01297 tree phi;
01298
01299 if (dump_file && (dump_flags & TDF_DETAILS))
01300 fprintf (dump_file, "\n\nRenaming block #%d\n\n", bb->index);
01301
01302
01303 VEC_safe_push (tree, heap, block_defs_stack, NULL_TREE);
01304
01305
01306
01307
01308 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
01309 {
01310 tree result = PHI_RESULT (phi);
01311 register_new_def (result, &block_defs_stack);
01312 }
01313 }
01314
01315
01316
01317
01318
01319
01320
01321
01322 static tree
01323 get_reaching_def (tree var)
01324 {
01325 tree currdef_var, avar;
01326
01327
01328 currdef_var = get_current_def (var);
01329
01330
01331
01332 if (currdef_var == NULL_TREE)
01333 {
01334 avar = DECL_P (var) ? var : SSA_NAME_VAR (var);
01335 currdef_var = get_default_def_for (avar);
01336 set_current_def (var, currdef_var);
01337 }
01338
01339
01340
01341 return currdef_var;
01342 }
01343
01344
01345
01346
01347
01348
01349 static void
01350 rewrite_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
01351 basic_block bb ATTRIBUTE_UNUSED,
01352 block_stmt_iterator si)
01353 {
01354 tree stmt;
01355 use_operand_p use_p;
01356 def_operand_p def_p;
01357 ssa_op_iter iter;
01358
01359 stmt = bsi_stmt (si);
01360
01361
01362
01363 gcc_assert (blocks_to_update == NULL);
01364 if (!REWRITE_THIS_STMT (stmt) && !REGISTER_DEFS_IN_THIS_STMT (stmt))
01365 return;
01366
01367 if (dump_file && (dump_flags & TDF_DETAILS))
01368 {
01369 fprintf (dump_file, "Renaming statement ");
01370 print_generic_stmt (dump_file, stmt, TDF_SLIM);
01371 fprintf (dump_file, "\n");
01372 }
01373
01374
01375 if (REWRITE_THIS_STMT (stmt))
01376 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
01377 SSA_OP_ALL_USES|SSA_OP_ALL_KILLS)
01378 {
01379 tree var = USE_FROM_PTR (use_p);
01380 gcc_assert (DECL_P (var));
01381 SET_USE (use_p, get_reaching_def (var));
01382 }
01383
01384
01385 if (REGISTER_DEFS_IN_THIS_STMT (stmt))
01386 FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_ALL_DEFS)
01387 {
01388 tree var = DEF_FROM_PTR (def_p);
01389 gcc_assert (DECL_P (var));
01390 SET_DEF (def_p, make_ssa_name (var, stmt));
01391 register_new_def (DEF_FROM_PTR (def_p), &block_defs_stack);
01392 }
01393 }
01394
01395
01396
01397
01398
01399
01400
01401 static void
01402 rewrite_add_phi_arguments (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
01403 basic_block bb)
01404 {
01405 edge e;
01406 edge_iterator ei;
01407
01408 FOR_EACH_EDGE (e, ei, bb->succs)
01409 {
01410 tree phi;
01411
01412 for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
01413 {
01414 tree currdef;
01415 currdef = get_reaching_def (SSA_NAME_VAR (PHI_RESULT (phi)));
01416 add_phi_arg (phi, currdef, e);
01417 }
01418 }
01419 }
01420
01421
01422
01423
01424
01425 static void
01426 rewrite_finalize_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
01427 basic_block bb ATTRIBUTE_UNUSED)
01428 {
01429
01430 while (VEC_length (tree, block_defs_stack) > 0)
01431 {
01432 tree tmp = VEC_pop (tree, block_defs_stack);
01433 tree saved_def, var;
01434
01435 if (tmp == NULL_TREE)
01436 break;
01437
01438
01439
01440
01441
01442 if (TREE_CODE (tmp) == SSA_NAME)
01443 {
01444 saved_def = tmp;
01445 var = SSA_NAME_VAR (saved_def);
01446 }
01447 else
01448 {
01449 saved_def = NULL;
01450 var = tmp;
01451 }
01452
01453 set_current_def (var, saved_def);
01454 }
01455 }
01456
01457
01458
01459
01460 void
01461 dump_tree_ssa (FILE *file)
01462 {
01463 basic_block bb;
01464 const char *funcname
01465 = lang_hooks.decl_printable_name (current_function_decl, 2);
01466
01467 fprintf (file, "SSA information for %s\n\n", funcname);
01468
01469 FOR_EACH_BB (bb)
01470 {
01471 dump_bb (bb, file, 0);
01472 fputs (" ", file);
01473 print_generic_stmt (file, phi_nodes (bb), dump_flags);
01474 fputs ("\n\n", file);
01475 }
01476 }
01477
01478
01479
01480
01481 void
01482 debug_tree_ssa (void)
01483 {
01484 dump_tree_ssa (stderr);
01485 }
01486
01487
01488
01489
01490 static void
01491 htab_statistics (FILE *file, htab_t htab)
01492 {
01493 fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
01494 (long) htab_size (htab),
01495 (long) htab_elements (htab),
01496 htab_collisions (htab));
01497 }
01498
01499
01500
01501
01502 void
01503 dump_tree_ssa_stats (FILE *file)
01504 {
01505 fprintf (file, "\nHash table statistics:\n");
01506
01507 fprintf (file, " def_blocks: ");
01508 htab_statistics (file, def_blocks);
01509
01510 fprintf (file, "\n");
01511 }
01512
01513
01514
01515
01516 void
01517 debug_tree_ssa_stats (void)
01518 {
01519 dump_tree_ssa_stats (stderr);
01520 }
01521
01522
01523
01524
01525 static hashval_t
01526 def_blocks_hash (const void *p)
01527 {
01528 return htab_hash_pointer
01529 ((const void *)((const struct def_blocks_d *)p)->var);
01530 }
01531
01532 static int
01533 def_blocks_eq (const void *p1, const void *p2)
01534 {
01535 return ((const struct def_blocks_d *)p1)->var
01536 == ((const struct def_blocks_d *)p2)->var;
01537 }
01538
01539
01540
01541
01542 static void
01543 def_blocks_free (void *p)
01544 {
01545 struct def_blocks_d *entry = (struct def_blocks_d *) p;
01546 BITMAP_FREE (entry->def_blocks);
01547 BITMAP_FREE (entry->phi_blocks);
01548 BITMAP_FREE (entry->livein_blocks);
01549 free (entry);
01550 }
01551
01552
01553
01554
01555 static int
01556 debug_def_blocks_r (void **slot, void *data ATTRIBUTE_UNUSED)
01557 {
01558 struct def_blocks_d *db_p = (struct def_blocks_d *) *slot;
01559
01560 fprintf (stderr, "VAR: ");
01561 print_generic_expr (stderr, db_p->var, dump_flags);
01562 bitmap_print (stderr, db_p->def_blocks, ", DEF_BLOCKS: { ", "}");
01563 bitmap_print (stderr, db_p->livein_blocks, ", LIVEIN_BLOCKS: { ", "}\n");
01564
01565 return 1;
01566 }
01567
01568
01569
01570
01571 void
01572 debug_def_blocks (void)
01573 {
01574 htab_traverse (def_blocks, debug_def_blocks_r, NULL);
01575 }
01576
01577
01578
01579
01580 static inline void
01581 register_new_update_single (tree new_name, tree old_name)
01582 {
01583 tree currdef = get_current_def (old_name);
01584
01585
01586
01587
01588
01589
01590 VEC_reserve (tree, heap, block_defs_stack, 2);
01591 VEC_quick_push (tree, block_defs_stack, currdef);
01592 VEC_quick_push (tree, block_defs_stack, old_name);
01593
01594
01595
01596 set_current_def (old_name, new_name);
01597 }
01598
01599
01600
01601
01602
01603
01604 static inline void
01605 register_new_update_set (tree new_name, bitmap old_names)
01606 {
01607 bitmap_iterator bi;
01608 unsigned i;
01609
01610 EXECUTE_IF_SET_IN_BITMAP (old_names, 0, i, bi)
01611 register_new_update_single (new_name, ssa_name (i));
01612 }
01613
01614
01615
01616
01617
01618
01619
01620 static void
01621 rewrite_update_init_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
01622 basic_block bb)
01623 {
01624 edge e;
01625 edge_iterator ei;
01626 tree phi;
01627 bool is_abnormal_phi;
01628
01629 if (dump_file && (dump_flags & TDF_DETAILS))
01630 fprintf (dump_file, "\n\nRegistering new PHI nodes in block #%d\n\n",
01631 bb->index);
01632
01633
01634 VEC_safe_push (tree, heap, block_defs_stack, NULL_TREE);
01635
01636 if (!bitmap_bit_p (blocks_to_update, bb->index))
01637 return;
01638
01639
01640
01641 is_abnormal_phi = false;
01642 FOR_EACH_EDGE (e, ei, bb->preds)
01643 if (e->flags & EDGE_ABNORMAL)
01644 {
01645 is_abnormal_phi = true;
01646 break;
01647 }
01648
01649
01650
01651
01652
01653
01654
01655 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
01656 {
01657 tree lhs, lhs_sym;
01658
01659 if (!REGISTER_DEFS_IN_THIS_STMT (phi))
01660 continue;
01661
01662 lhs = PHI_RESULT (phi);
01663 lhs_sym = SSA_NAME_VAR (lhs);
01664
01665 if (symbol_marked_for_renaming (lhs_sym))
01666 register_new_update_single (lhs, lhs_sym);
01667 else
01668 {
01669
01670
01671 if (is_new_name (lhs))
01672 register_new_update_set (lhs, names_replaced_by (lhs));
01673
01674
01675
01676 if (is_old_name (lhs))
01677 register_new_update_single (lhs, lhs);
01678 }
01679
01680 if (is_abnormal_phi)
01681 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs) = 1;
01682 }
01683 }
01684
01685
01686
01687
01688
01689
01690
01691
01692 static void
01693 rewrite_update_fini_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
01694 basic_block bb ATTRIBUTE_UNUSED)
01695 {
01696 while (VEC_length (tree, block_defs_stack) > 0)
01697 {
01698 tree var = VEC_pop (tree, block_defs_stack);
01699 tree saved_def;
01700
01701
01702
01703 if (var == NULL)
01704 return;
01705
01706 saved_def = VEC_pop (tree, block_defs_stack);
01707 set_current_def (var, saved_def);
01708 }
01709 }
01710
01711
01712
01713
01714
01715
01716 static inline void
01717 maybe_replace_use (use_operand_p use_p)
01718 {
01719 tree rdef = NULL_TREE;
01720 tree use = USE_FROM_PTR (use_p);
01721 tree sym = DECL_P (use) ? use : SSA_NAME_VAR (use);
01722
01723 if (symbol_marked_for_renaming (sym))
01724 rdef = get_reaching_def (sym);
01725 else if (is_old_name (use))
01726 rdef = get_reaching_def (use);
01727
01728 if (rdef && rdef != use)
01729 SET_USE (use_p, rdef);
01730 }
01731
01732
01733
01734
01735
01736
01737
01738 static inline void
01739 maybe_register_def (def_operand_p def_p, tree stmt)
01740 {
01741 tree def = DEF_FROM_PTR (def_p);
01742 tree sym = DECL_P (def) ? def : SSA_NAME_VAR (def);
01743
01744
01745
01746 if (symbol_marked_for_renaming (sym))
01747 {
01748 if (DECL_P (def))
01749 {
01750 def = make_ssa_name (def, stmt);
01751 SET_DEF (def_p, def);
01752 }
01753
01754 register_new_update_single (def, sym);
01755 }
01756 else
01757 {
01758
01759
01760 if (is_new_name (def))
01761 register_new_update_set (def, names_replaced_by (def));
01762
01763
01764
01765 if (is_old_name (def))
01766 register_new_update_single (def, def);
01767 }
01768 }
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778 static void
01779 rewrite_update_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
01780 basic_block bb ATTRIBUTE_UNUSED,
01781 block_stmt_iterator si)
01782 {
01783 stmt_ann_t ann;
01784 tree stmt;
01785 use_operand_p use_p;
01786 def_operand_p def_p;
01787 ssa_op_iter iter;
01788
01789 stmt = bsi_stmt (si);
01790 ann = stmt_ann (stmt);
01791
01792 gcc_assert (bitmap_bit_p (blocks_to_update, bb->index));
01793
01794
01795 if (!REWRITE_THIS_STMT (stmt) && !REGISTER_DEFS_IN_THIS_STMT (stmt))
01796 return;
01797
01798 if (dump_file && (dump_flags & TDF_DETAILS))
01799 {
01800 fprintf (dump_file, "Updating SSA information for statement ");
01801 print_generic_stmt (dump_file, stmt, TDF_SLIM);
01802 fprintf (dump_file, "\n");
01803 }
01804
01805
01806
01807 if (REWRITE_THIS_STMT (stmt))
01808 {
01809 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
01810 maybe_replace_use (use_p);
01811
01812 if (need_to_update_vops_p)
01813 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
01814 SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS)
01815 maybe_replace_use (use_p);
01816 }
01817
01818
01819
01820
01821 if (REGISTER_DEFS_IN_THIS_STMT (stmt))
01822 {
01823 FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF)
01824 maybe_register_def (def_p, stmt);
01825
01826 if (need_to_update_vops_p)
01827 FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_VIRTUAL_DEFS)
01828 maybe_register_def (def_p, stmt);
01829 }
01830 }
01831
01832
01833
01834
01835
01836 static inline void
01837 replace_use (use_operand_p use_p, tree use)
01838 {
01839 tree rdef = get_reaching_def (use);
01840 if (rdef != use)
01841 SET_USE (use_p, rdef);
01842 }
01843
01844
01845
01846
01847
01848
01849
01850 static void
01851 rewrite_update_phi_arguments (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
01852 basic_block bb)
01853 {
01854 edge e;
01855 edge_iterator ei;
01856 unsigned i;
01857
01858 FOR_EACH_EDGE (e, ei, bb->succs)
01859 {
01860 tree phi;
01861 tree_vec phis;
01862
01863 if (!bitmap_bit_p (blocks_with_phis_to_rewrite, e->dest->index))
01864 continue;
01865
01866 phis = VEC_index (tree_vec, phis_to_rewrite, e->dest->index);
01867 for (i = 0; VEC_iterate (tree, phis, i, phi); i++)
01868 {
01869 tree arg;
01870 use_operand_p arg_p;
01871
01872 gcc_assert (REWRITE_THIS_STMT (phi));
01873
01874 arg_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
01875 arg = USE_FROM_PTR (arg_p);
01876
01877 if (arg && !DECL_P (arg) && TREE_CODE (arg) != SSA_NAME)
01878 continue;
01879
01880 if (arg == NULL_TREE)
01881 {
01882
01883
01884
01885 replace_use (arg_p, SSA_NAME_VAR (PHI_RESULT (phi)));
01886 }
01887 else
01888 {
01889 tree sym = DECL_P (arg) ? arg : SSA_NAME_VAR (arg);
01890
01891 if (symbol_marked_for_renaming (sym))
01892 replace_use (arg_p, sym);
01893 else if (is_old_name (arg))
01894 replace_use (arg_p, arg);
01895 }
01896
01897 if (e->flags & EDGE_ABNORMAL)
01898 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (arg_p)) = 1;
01899 }
01900 }
01901 }
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918 static void
01919 rewrite_blocks (basic_block entry, enum rewrite_mode what, sbitmap blocks)
01920 {
01921 struct dom_walk_data walk_data;
01922
01923
01924 timevar_push (TV_TREE_SSA_REWRITE_BLOCKS);
01925
01926
01927 memset (&walk_data, 0, sizeof (walk_data));
01928
01929 walk_data.dom_direction = CDI_DOMINATORS;
01930 walk_data.interesting_blocks = blocks;
01931
01932 if (what == REWRITE_UPDATE)
01933 walk_data.before_dom_children_before_stmts = rewrite_update_init_block;
01934 else
01935 walk_data.before_dom_children_before_stmts = rewrite_initialize_block;
01936
01937 if (what == REWRITE_ALL)
01938 walk_data.before_dom_children_walk_stmts = rewrite_stmt;
01939 else if (what == REWRITE_UPDATE)
01940 walk_data.before_dom_children_walk_stmts = rewrite_update_stmt;
01941 else
01942 gcc_unreachable ();
01943
01944 if (what == REWRITE_ALL)
01945 walk_data.before_dom_children_after_stmts = rewrite_add_phi_arguments;
01946 else if (what == REWRITE_UPDATE)
01947 walk_data.before_dom_children_after_stmts = rewrite_update_phi_arguments;
01948 else
01949 gcc_unreachable ();
01950
01951 if (what == REWRITE_ALL)
01952 walk_data.after_dom_children_after_stmts = rewrite_finalize_block;
01953 else if (what == REWRITE_UPDATE)
01954 walk_data.after_dom_children_after_stmts = rewrite_update_fini_block;
01955 else
01956 gcc_unreachable ();
01957
01958 block_defs_stack = VEC_alloc (tree, heap, 10);
01959
01960
01961 init_walk_dominator_tree (&walk_data);
01962
01963
01964
01965 walk_dominator_tree (&walk_data, entry);
01966
01967
01968 fini_walk_dominator_tree (&walk_data);
01969
01970
01971 if (dump_file && (dump_flags & TDF_STATS))
01972 {
01973 dump_dfa_stats (dump_file);
01974 if (def_blocks)
01975 dump_tree_ssa_stats (dump_file);
01976 }
01977
01978 if (def_blocks)
01979 {
01980 htab_delete (def_blocks);
01981 def_blocks = NULL;
01982 }
01983
01984 VEC_free (tree, heap, block_defs_stack);
01985
01986 timevar_pop (TV_TREE_SSA_REWRITE_BLOCKS);
01987 }
01988
01989
01990
01991
01992
01993 static void
01994 mark_def_sites_initialize_block (struct dom_walk_data *walk_data,
01995 basic_block bb ATTRIBUTE_UNUSED)
01996 {
01997 struct mark_def_sites_global_data *gd =
01998 (struct mark_def_sites_global_data *) walk_data->global_data;
01999 bitmap kills = gd->kills;
02000 bitmap_clear (kills);
02001 }
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011 static void
02012 mark_def_site_blocks (sbitmap interesting_blocks)
02013 {
02014 struct dom_walk_data walk_data;
02015 struct mark_def_sites_global_data mark_def_sites_global_data;
02016 referenced_var_iterator rvi;
02017 tree var;
02018
02019
02020 def_blocks = htab_create (num_referenced_vars,
02021 def_blocks_hash, def_blocks_eq, def_blocks_free);
02022 FOR_EACH_REFERENCED_VAR(var, rvi)
02023 set_current_def (var, NULL_TREE);
02024
02025
02026
02027 walk_data.walk_stmts_backward = false;
02028 walk_data.dom_direction = CDI_DOMINATORS;
02029 walk_data.initialize_block_local_data = NULL;
02030 walk_data.before_dom_children_before_stmts = mark_def_sites_initialize_block;
02031 walk_data.before_dom_children_walk_stmts = mark_def_sites;
02032 walk_data.before_dom_children_after_stmts = NULL;
02033 walk_data.after_dom_children_before_stmts = NULL;
02034 walk_data.after_dom_children_walk_stmts = NULL;
02035 walk_data.after_dom_children_after_stmts = NULL;
02036 walk_data.interesting_blocks = NULL;
02037
02038
02039
02040
02041 mark_def_sites_global_data.kills = BITMAP_ALLOC (NULL);
02042
02043
02044
02045 mark_def_sites_global_data.interesting_blocks = interesting_blocks;
02046 walk_data.global_data = &mark_def_sites_global_data;
02047
02048
02049 walk_data.block_local_data_size = 0;
02050
02051
02052 init_walk_dominator_tree (&walk_data);
02053
02054
02055 walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
02056
02057
02058 fini_walk_dominator_tree (&walk_data);
02059
02060
02061 BITMAP_FREE (mark_def_sites_global_data.kills);
02062 }
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082 static unsigned int
02083 rewrite_into_ssa (void)
02084 {
02085 bitmap *dfs;
02086 basic_block bb;
02087 sbitmap interesting_blocks;
02088
02089 timevar_push (TV_TREE_SSA_OTHER);
02090
02091
02092 init_ssa_operands ();
02093
02094
02095
02096
02097 interesting_blocks = sbitmap_alloc (last_basic_block);
02098 sbitmap_zero (interesting_blocks);
02099
02100
02101 dfs = (bitmap *) xmalloc (last_basic_block * sizeof (bitmap));
02102 FOR_EACH_BB (bb)
02103 dfs[bb->index] = BITMAP_ALLOC (NULL);
02104
02105
02106 calculate_dominance_info (CDI_DOMINATORS);
02107 compute_dominance_frontiers (dfs);
02108
02109
02110 mark_def_site_blocks (interesting_blocks);
02111
02112
02113 insert_phi_nodes (dfs);
02114
02115
02116 rewrite_blocks (ENTRY_BLOCK_PTR, REWRITE_ALL, interesting_blocks);
02117
02118
02119 FOR_EACH_BB (bb)
02120 BITMAP_FREE (dfs[bb->index]);
02121 free (dfs);
02122 sbitmap_free (interesting_blocks);
02123
02124 timevar_pop (TV_TREE_SSA_OTHER);
02125 in_ssa_p = true;
02126 return 0;
02127 }
02128
02129
02130 struct tree_opt_pass pass_build_ssa =
02131 {
02132 "ssa",
02133 NULL,
02134 rewrite_into_ssa,
02135 NULL,
02136 NULL,
02137 0,
02138 0,
02139 PROP_cfg | PROP_referenced_vars,
02140 PROP_ssa,
02141 0,
02142 0,
02143 TODO_dump_func
02144 | TODO_verify_ssa
02145 | TODO_remove_unused_locals,
02146 0
02147 };
02148
02149
02150
02151
02152
02153 static void
02154 mark_def_interesting (tree var, tree stmt, basic_block bb, bool insert_phi_p)
02155 {
02156 gcc_assert (bitmap_bit_p (blocks_to_update, bb->index));
02157 REGISTER_DEFS_IN_THIS_STMT (stmt) = 1;
02158
02159 if (insert_phi_p)
02160 {
02161 bool is_phi_p = TREE_CODE (stmt) == PHI_NODE;
02162
02163 set_def_block (var, bb, is_phi_p);
02164
02165
02166
02167 if (TREE_CODE (var) == SSA_NAME && is_new_name (var))
02168 {
02169 bitmap_iterator bi;
02170 unsigned i;
02171 bitmap set = names_replaced_by (var);
02172 if (set)
02173 EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi)
02174 set_def_block (ssa_name (i), bb, is_phi_p);
02175 }
02176 }
02177 }
02178
02179
02180
02181
02182
02183
02184 static inline void
02185 mark_use_interesting (tree var, tree stmt, basic_block bb, bool insert_phi_p)
02186 {
02187 basic_block def_bb = bb_for_stmt (stmt);
02188
02189 mark_block_for_update (def_bb);
02190 mark_block_for_update (bb);
02191
02192 if (TREE_CODE (stmt) == PHI_NODE)
02193 mark_phi_for_rewrite (def_bb, stmt);
02194 else
02195 REWRITE_THIS_STMT (stmt) = 1;
02196
02197
02198
02199
02200
02201
02202 if (insert_phi_p)
02203 {
02204 struct def_blocks_d *db_p = get_def_blocks_for (var);
02205 if (!bitmap_bit_p (db_p->def_blocks, bb->index))
02206 set_livein_block (var, bb);
02207 }
02208 }
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220 static void
02221 prepare_block_for_update (basic_block bb, bool insert_phi_p)
02222 {
02223 basic_block son;
02224 block_stmt_iterator si;
02225 tree phi;
02226 edge e;
02227 edge_iterator ei;
02228
02229 mark_block_for_update (bb);
02230
02231
02232
02233 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
02234 {
02235 tree lhs_sym, lhs = PHI_RESULT (phi);
02236
02237 lhs_sym = DECL_P (lhs) ? lhs : SSA_NAME_VAR (lhs);
02238
02239 if (!symbol_marked_for_renaming (lhs_sym))
02240 continue;
02241 mark_def_interesting (lhs_sym, phi, bb, insert_phi_p);
02242
02243
02244
02245
02246
02247
02248
02249
02250 FOR_EACH_EDGE (e, ei, bb->preds)
02251 {
02252 mark_use_interesting (lhs_sym, phi, e->src, insert_phi_p);
02253 }
02254 }
02255
02256
02257 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
02258 {
02259 tree stmt;
02260 ssa_op_iter i;
02261 use_operand_p use_p;
02262 def_operand_p def_p;
02263
02264 stmt = bsi_stmt (si);
02265
02266 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, i, SSA_OP_USE)
02267 {
02268 tree use = USE_FROM_PTR (use_p);
02269 tree sym = DECL_P (use) ? use : SSA_NAME_VAR (use);
02270 if (symbol_marked_for_renaming (sym))
02271 mark_use_interesting (use, stmt, bb, insert_phi_p);
02272 }
02273
02274 FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, i, SSA_OP_DEF)
02275 {
02276 tree def = DEF_FROM_PTR (def_p);
02277 tree sym = DECL_P (def) ? def : SSA_NAME_VAR (def);
02278
02279 if (symbol_marked_for_renaming (sym))
02280 mark_def_interesting (def, stmt, bb, insert_phi_p);
02281 }
02282
02283 FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, i, SSA_OP_VIRTUAL_DEFS)
02284 {
02285 tree def = DEF_FROM_PTR (def_p);
02286 tree sym = DECL_P (def) ? def : SSA_NAME_VAR (def);
02287
02288 if (symbol_marked_for_renaming (sym))
02289 {
02290 mark_use_interesting (sym, stmt, bb, insert_phi_p);
02291 mark_def_interesting (sym, stmt, bb, insert_phi_p);
02292 }
02293 }
02294
02295 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, i, SSA_OP_VUSE)
02296 {
02297 tree use = USE_FROM_PTR (use_p);
02298 tree sym = DECL_P (use) ? use : SSA_NAME_VAR (use);
02299
02300 if (symbol_marked_for_renaming (sym))
02301 mark_use_interesting (sym, stmt, bb, insert_phi_p);
02302 }
02303 }
02304
02305
02306 for (son = first_dom_son (CDI_DOMINATORS, bb);
02307 son;
02308 son = next_dom_son (CDI_DOMINATORS, son))
02309 prepare_block_for_update (son, insert_phi_p);
02310 }
02311
02312
02313
02314
02315
02316
02317 static void
02318 prepare_use_sites_for (tree name, bool insert_phi_p)
02319 {
02320 use_operand_p use_p;
02321 imm_use_iterator iter;
02322
02323 FOR_EACH_IMM_USE_FAST (use_p, iter, name)
02324 {
02325 tree stmt = USE_STMT (use_p);
02326 basic_block bb = bb_for_stmt (stmt);
02327
02328 if (TREE_CODE (stmt) == PHI_NODE)
02329 {
02330 int ix = PHI_ARG_INDEX_FROM_USE (use_p);
02331 edge e = PHI_ARG_EDGE (stmt, ix);
02332 mark_use_interesting (name, stmt, e->src, insert_phi_p);
02333 }
02334 else
02335 {
02336
02337
02338 mark_use_interesting (name, stmt, bb, insert_phi_p);
02339 }
02340 }
02341 }
02342
02343
02344
02345
02346
02347
02348 static void
02349 prepare_def_site_for (tree name, bool insert_phi_p)
02350 {
02351 tree stmt;
02352 basic_block bb;
02353
02354 gcc_assert (names_to_release == NULL
02355 || !bitmap_bit_p (names_to_release, SSA_NAME_VERSION (name)));
02356
02357 stmt = SSA_NAME_DEF_STMT (name);
02358 bb = bb_for_stmt (stmt);
02359 if (bb)
02360 {
02361 gcc_assert (bb->index < last_basic_block);
02362 mark_block_for_update (bb);
02363 mark_def_interesting (name, stmt, bb, insert_phi_p);
02364 }
02365 }
02366
02367
02368
02369
02370
02371
02372 static void
02373 prepare_names_to_update (bool insert_phi_p)
02374 {
02375 unsigned i = 0;
02376 bitmap_iterator bi;
02377 sbitmap_iterator sbi;
02378
02379
02380
02381
02382
02383
02384 if (names_to_release)
02385 EXECUTE_IF_SET_IN_BITMAP (names_to_release, 0, i, bi)
02386 RESET_BIT (new_ssa_names, i);
02387
02388
02389
02390
02391 EXECUTE_IF_SET_IN_SBITMAP (new_ssa_names, 0, i, sbi)
02392 prepare_def_site_for (ssa_name (i), insert_phi_p);
02393
02394
02395
02396 EXECUTE_IF_SET_IN_SBITMAP (old_ssa_names, 0, i, sbi)
02397 {
02398 if (names_to_release == NULL || !bitmap_bit_p (names_to_release, i))
02399 prepare_def_site_for (ssa_name (i), insert_phi_p);
02400 prepare_use_sites_for (ssa_name (i), insert_phi_p);
02401 }
02402 }
02403
02404
02405
02406
02407 void
02408 dump_names_replaced_by (FILE *file, tree name)
02409 {
02410 unsigned i;
02411 bitmap old_set;
02412 bitmap_iterator bi;
02413
02414 print_generic_expr (file, name, 0);
02415 fprintf (file, " -> { ");
02416
02417 old_set = names_replaced_by (name);
02418 EXECUTE_IF_SET_IN_BITMAP (old_set, 0, i, bi)
02419 {
02420 print_generic_expr (file, ssa_name (i), 0);
02421 fprintf (file, " ");
02422 }
02423
02424 fprintf (file, "}\n");
02425 }
02426
02427
02428
02429
02430 void
02431 debug_names_replaced_by (tree name)
02432 {
02433 dump_names_replaced_by (stderr, name);
02434 }
02435
02436
02437
02438
02439 void
02440 dump_update_ssa (FILE *file)
02441 {
02442 unsigned i = 0;
02443 bitmap_iterator bi;
02444
02445 if (!need_ssa_update_p ())
02446 return;
02447
02448 if (new_ssa_names && sbitmap_first_set_bit (new_ssa_names) >= 0)
02449 {
02450 sbitmap_iterator sbi;
02451
02452 fprintf (file, "\nSSA replacement table\n");
02453 fprintf (file, "N_i -> { O_1 ... O_j } means that N_i replaces "
02454 "O_1, ..., O_j\n\n");
02455
02456 EXECUTE_IF_SET_IN_SBITMAP (new_ssa_names, 0, i, sbi)
02457 dump_names_replaced_by (file, ssa_name (i));
02458
02459 fprintf (file, "\n");
02460 fprintf (file, "Number of virtual NEW -> OLD mappings: %7u\n",
02461 update_ssa_stats.num_virtual_mappings);
02462 fprintf (file, "Number of real NEW -> OLD mappings: %7u\n",
02463 update_ssa_stats.num_total_mappings
02464 - update_ssa_stats.num_virtual_mappings);
02465 fprintf (file, "Number of total NEW -> OLD mappings: %7u\n",
02466 update_ssa_stats.num_total_mappings);
02467
02468 fprintf (file, "\nNumber of virtual symbols: %u\n",
02469 update_ssa_stats.num_virtual_symbols);
02470 }
02471
02472 if (syms_to_rename && !bitmap_empty_p (syms_to_rename))
02473 {
02474 fprintf (file, "\n\nSymbols to be put in SSA form\n\n");
02475 EXECUTE_IF_SET_IN_BITMAP (syms_to_rename, 0, i, bi)
02476 {
02477 print_generic_expr (file, referenced_var (i), 0);
02478 fprintf (file, " ");
02479 }
02480 }
02481
02482 if (names_to_release && !bitmap_empty_p (names_to_release))
02483 {
02484 fprintf (file, "\n\nSSA names to release after updating the SSA web\n\n");
02485 EXECUTE_IF_SET_IN_BITMAP (names_to_release, 0, i, bi)
02486 {
02487 print_generic_expr (file, ssa_name (i), 0);
02488 fprintf (file, " ");
02489 }
02490 }
02491
02492 fprintf (file, "\n\n");
02493 }
02494
02495
02496
02497
02498 void
02499 debug_update_ssa (void)
02500 {
02501 dump_update_ssa (stderr);
02502 }
02503
02504
02505
02506
02507 static void
02508 init_update_ssa (void)
02509 {
02510
02511
02512
02513 old_ssa_names = sbitmap_alloc (num_ssa_names + NAME_SETS_GROWTH_FACTOR);
02514 sbitmap_zero (old_ssa_names);
02515
02516 new_ssa_names = sbitmap_alloc (num_ssa_names + NAME_SETS_GROWTH_FACTOR);
02517 sbitmap_zero (new_ssa_names);
02518
02519 repl_tbl = htab_create (20, repl_map_hash, repl_map_eq, repl_map_free);
02520 need_to_initialize_update_ssa_p = false;
02521 need_to_update_vops_p = false;
02522 syms_to_rename = BITMAP_ALLOC (NULL);
02523 names_to_release = NULL;
02524 memset (&update_ssa_stats, 0, sizeof (update_ssa_stats));
02525 update_ssa_stats.virtual_symbols = BITMAP_ALLOC (NULL);
02526 }
02527
02528
02529
02530
02531 void
02532 delete_update_ssa (void)
02533 {
02534 unsigned i;
02535 bitmap_iterator bi;
02536
02537 sbitmap_free (old_ssa_names);
02538 old_ssa_names = NULL;
02539
02540 sbitmap_free (new_ssa_names);
02541 new_ssa_names = NULL;
02542
02543 htab_delete (repl_tbl);
02544 repl_tbl = NULL;
02545
02546 need_to_initialize_update_ssa_p = true;
02547 need_to_update_vops_p = false;
02548 BITMAP_FREE (syms_to_rename);
02549 BITMAP_FREE (update_ssa_stats.virtual_symbols);
02550
02551 if (names_to_release)
02552 {
02553 EXECUTE_IF_SET_IN_BITMAP (names_to_release, 0, i, bi)
02554 release_ssa_name (ssa_name (i));
02555 BITMAP_FREE (names_to_release);
02556 }
02557
02558 clear_ssa_name_info ();
02559 }
02560
02561
02562
02563
02564
02565
02566
02567 tree
02568 create_new_def_for (tree old_name, tree stmt, def_operand_p def)
02569 {
02570 tree new_name = duplicate_ssa_name (old_name, stmt);
02571
02572 SET_DEF (def, new_name);
02573
02574 if (TREE_CODE (stmt) == PHI_NODE)
02575 {
02576 edge e;
02577 edge_iterator ei;
02578 basic_block bb = bb_for_stmt (stmt);
02579
02580
02581 FOR_EACH_EDGE (e, ei, bb->preds)
02582 if (e->flags & EDGE_ABNORMAL)
02583 {
02584 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name) = 1;
02585 break;
02586 }
02587 }
02588
02589 register_new_name_mapping (new_name, old_name);
02590
02591
02592
02593
02594 set_current_def (old_name, new_name);
02595
02596 return new_name;
02597 }
02598
02599
02600
02601
02602
02603
02604 void
02605 register_new_name_mapping (tree new, tree old)
02606 {
02607 if (need_to_initialize_update_ssa_p)
02608 init_update_ssa ();
02609
02610 add_new_name_mapping (new, old);
02611 }
02612
02613
02614
02615
02616 void
02617 mark_sym_for_renaming (tree sym)
02618 {
02619 if (need_to_initialize_update_ssa_p)
02620 init_update_ssa ();
02621
02622 bitmap_set_bit (syms_to_rename, DECL_UID (sym));
02623
02624 if (!is_gimple_reg (sym))
02625 need_to_update_vops_p = true;
02626 }
02627
02628
02629
02630
02631 void
02632 mark_set_for_renaming (bitmap set)
02633 {
02634 bitmap_iterator bi;
02635 unsigned i;
02636
02637 if (bitmap_empty_p (set))
02638 return;
02639
02640 if (need_to_initialize_update_ssa_p)
02641 init_update_ssa ();
02642
02643 bitmap_ior_into (syms_to_rename, set);
02644
02645 EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi)
02646 if (!is_gimple_reg (referenced_var (i)))
02647 {
02648 need_to_update_vops_p = true;
02649 break;
02650 }
02651 }
02652
02653
02654
02655
02656 bool
02657 need_ssa_update_p (void)
02658 {
02659 return syms_to_rename || old_ssa_names || new_ssa_names;
02660 }
02661
02662
02663
02664
02665 bool
02666 name_registered_for_update_p (tree n)
02667 {
02668 if (!need_ssa_update_p ())
02669 return false;
02670
02671 return is_new_name (n)
02672 || is_old_name (n)
02673 || symbol_marked_for_renaming (SSA_NAME_VAR (n));
02674 }
02675
02676
02677
02678
02679 bitmap
02680 ssa_names_to_replace (void)
02681 {
02682 unsigned i = 0;
02683 bitmap ret;
02684 sbitmap_iterator sbi;
02685
02686 ret = BITMAP_ALLOC (NULL);
02687 EXECUTE_IF_SET_IN_SBITMAP (old_ssa_names, 0, i, sbi)
02688 bitmap_set_bit (ret, i);
02689
02690 return ret;
02691 }
02692
02693
02694
02695
02696 void
02697 release_ssa_name_after_update_ssa (tree name)
02698 {
02699 gcc_assert (!need_to_initialize_update_ssa_p);
02700
02701 if (names_to_release == NULL)
02702 names_to_release = BITMAP_ALLOC (NULL);
02703
02704 bitmap_set_bit (names_to_release, SSA_NAME_VERSION (name));
02705 }
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731 static void
02732 insert_updated_phi_nodes_for (tree var, bitmap *dfs, bitmap blocks,
02733 unsigned update_flags)
02734 {
02735 basic_block entry;
02736 struct def_blocks_d *db;
02737 bitmap idf, pruned_idf;
02738 bitmap_iterator bi;
02739 unsigned i;
02740
02741 #if defined ENABLE_CHECKING
02742 if (TREE_CODE (var) == SSA_NAME)
02743 gcc_assert (is_old_name (var));
02744 else
02745 gcc_assert (symbol_marked_for_renaming (var));
02746 #endif
02747
02748
02749 db = find_def_blocks_for (var);
02750
02751
02752 if (db == NULL || bitmap_empty_p (db->def_blocks))
02753 return;
02754
02755
02756 idf = find_idf (db->def_blocks, dfs);
02757 pruned_idf = BITMAP_ALLOC (NULL);
02758
02759 if (TREE_CODE (var) == SSA_NAME)
02760 {
02761 if (update_flags == TODO_update_ssa)
02762 {
02763
02764
02765
02766 entry = nearest_common_dominator_for_set (CDI_DOMINATORS,
02767 db->def_blocks);
02768
02769 if (entry != ENTRY_BLOCK_PTR)
02770 EXECUTE_IF_SET_IN_BITMAP (idf, 0, i, bi)
02771 if (BASIC_BLOCK (i) != entry
02772 && dominated_by_p (CDI_DOMINATORS, BASIC_BLOCK (i), entry))
02773 bitmap_set_bit (pruned_idf, i);
02774 }
02775 else
02776 {
02777
02778 gcc_assert (update_flags == TODO_update_ssa_full_phi);
02779 bitmap_copy (pruned_idf, idf);
02780 }
02781 }
02782 else
02783 {
02784
02785
02786
02787 bitmap_copy (pruned_idf, idf);
02788 }
02789
02790 if (!bitmap_empty_p (pruned_idf))
02791 {
02792
02793
02794
02795
02796 bitmap_ior_into (blocks, pruned_idf);
02797 EXECUTE_IF_SET_IN_BITMAP (pruned_idf, 0, i, bi)
02798 {
02799 edge e;
02800 edge_iterator ei;
02801 basic_block bb = BASIC_BLOCK (i);
02802
02803 FOR_EACH_EDGE (e, ei, bb->preds)
02804 if (e->src->index >= 0)
02805 bitmap_set_bit (blocks, e->src->index);
02806 }
02807
02808 insert_phi_nodes_for (var, pruned_idf, true);
02809 }
02810
02811 BITMAP_FREE (pruned_idf);
02812 BITMAP_FREE (idf);
02813 }
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833 static bool
02834 switch_virtuals_to_full_rewrite_p (void)
02835 {
02836 if (update_ssa_stats.num_virtual_mappings < (unsigned) MIN_VIRTUAL_MAPPINGS)
02837 return false;
02838
02839 if (update_ssa_stats.num_virtual_mappings
02840 > (unsigned) VIRTUAL_MAPPINGS_TO_SYMS_RATIO
02841 * update_ssa_stats.num_virtual_symbols)
02842 return true;
02843
02844 return false;
02845 }
02846
02847
02848
02849
02850
02851 static void
02852 switch_virtuals_to_full_rewrite (void)
02853 {
02854 unsigned i = 0;
02855 sbitmap_iterator sbi;
02856
02857 if (dump_file)
02858 {
02859 fprintf (dump_file, "\nEnabled virtual name mapping heuristic.\n");
02860 fprintf (dump_file, "\tNumber of virtual mappings: %7u\n",
02861 update_ssa_stats.num_virtual_mappings);
02862 fprintf (dump_file, "\tNumber of unique virtual symbols: %7u\n",
02863 update_ssa_stats.num_virtual_symbols);
02864 fprintf (dump_file, "Updating FUD-chains from top of CFG will be "
02865 "faster than processing\nthe name mappings.\n\n");
02866 }
02867
02868
02869
02870
02871 EXECUTE_IF_SET_IN_SBITMAP (new_ssa_names, 0, i, sbi)
02872 if (!is_gimple_reg (ssa_name (i)))
02873 RESET_BIT (new_ssa_names, i);
02874
02875 EXECUTE_IF_SET_IN_SBITMAP (old_ssa_names, 0, i, sbi)
02876 if (!is_gimple_reg (ssa_name (i)))
02877 RESET_BIT (old_ssa_names, i);
02878
02879 bitmap_ior_into (syms_to_rename, update_ssa_stats.virtual_symbols);
02880 }
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947 void
02948 update_ssa (unsigned update_flags)
02949 {
02950 basic_block bb, start_bb;
02951 bitmap_iterator bi;
02952 unsigned i = 0;
02953 sbitmap tmp;
02954 bool insert_phi_p;
02955 sbitmap_iterator sbi;
02956
02957 if (!need_ssa_update_p ())
02958 return;
02959
02960 timevar_push (TV_TREE_SSA_INCREMENTAL);
02961
02962 blocks_with_phis_to_rewrite = BITMAP_ALLOC (NULL);
02963 if (!phis_to_rewrite)
02964 phis_to_rewrite = VEC_alloc (tree_vec, heap, last_basic_block);
02965 blocks_to_update = BITMAP_ALLOC (NULL);
02966
02967
02968 calculate_dominance_info (CDI_DOMINATORS);
02969
02970
02971 gcc_assert (update_flags == TODO_update_ssa
02972 || update_flags == TODO_update_ssa_no_phi
02973 || update_flags == TODO_update_ssa_full_phi
02974 || update_flags == TODO_update_ssa_only_virtuals);
02975
02976
02977
02978
02979 if (update_flags == TODO_update_ssa_only_virtuals)
02980 {
02981 sbitmap_zero (old_ssa_names);
02982 sbitmap_zero (new_ssa_names);
02983 htab_empty (repl_tbl);
02984 }
02985
02986 insert_phi_p = (update_flags != TODO_update_ssa_no_phi);
02987
02988 if (insert_phi_p)
02989 {
02990
02991
02992
02993
02994
02995
02996
02997 def_blocks = htab_create (num_ssa_names, def_blocks_hash,
02998 def_blocks_eq, def_blocks_free);
02999 }
03000 else
03001 {
03002 def_blocks = NULL;
03003 }
03004
03005
03006
03007 if (insert_phi_p && switch_virtuals_to_full_rewrite_p ())
03008 switch_virtuals_to_full_rewrite ();
03009
03010
03011
03012
03013 if (sbitmap_first_set_bit (new_ssa_names) >= 0)
03014 {
03015 prepare_names_to_update (insert_phi_p);
03016
03017
03018
03019
03020 if (sbitmap_first_set_bit (new_ssa_names) < 0
03021 && bitmap_empty_p (syms_to_rename))
03022 goto done;
03023 }
03024
03025
03026 if (!bitmap_empty_p (syms_to_rename))
03027 {
03028
03029
03030
03031
03032
03033 start_bb = ENTRY_BLOCK_PTR;
03034
03035
03036
03037
03038
03039 prepare_block_for_update (start_bb, insert_phi_p);
03040 }
03041 else
03042 {
03043
03044
03045 start_bb = nearest_common_dominator_for_set (CDI_DOMINATORS,
03046 blocks_to_update);
03047 }
03048
03049
03050
03051
03052 if (insert_phi_p)
03053 {
03054 bitmap *dfs;
03055
03056
03057
03058 dfs = XNEWVEC (bitmap, last_basic_block);
03059 FOR_EACH_BB (bb)
03060 dfs[bb->index] = BITMAP_ALLOC (NULL);
03061 compute_dominance_frontiers (dfs);
03062
03063 if (sbitmap_first_set_bit (old_ssa_names) >= 0)
03064 {
03065 sbitmap_iterator sbi;
03066
03067
03068
03069
03070
03071
03072 sbitmap tmp = sbitmap_alloc (old_ssa_names->n_bits);
03073 sbitmap_copy (tmp, old_ssa_names);
03074 EXECUTE_IF_SET_IN_SBITMAP (tmp, 0, i, sbi)
03075 insert_updated_phi_nodes_for (ssa_name (i), dfs, blocks_to_update,
03076 update_flags);
03077 sbitmap_free (tmp);
03078 }
03079
03080 EXECUTE_IF_SET_IN_BITMAP (syms_to_rename, 0, i, bi)
03081 insert_updated_phi_nodes_for (referenced_var (i), dfs,
03082 blocks_to_update, update_flags);
03083
03084 FOR_EACH_BB (bb)
03085 BITMAP_FREE (dfs[bb->index]);
03086 free (dfs);
03087
03088
03089
03090
03091 if (start_bb != ENTRY_BLOCK_PTR)
03092 start_bb = nearest_common_dominator_for_set (CDI_DOMINATORS,
03093 blocks_to_update);
03094 }
03095
03096
03097
03098 EXECUTE_IF_SET_IN_SBITMAP (old_ssa_names, 0, i, sbi)
03099 set_current_def (ssa_name (i), NULL_TREE);
03100
03101 EXECUTE_IF_SET_IN_BITMAP (syms_to_rename, 0, i, bi)
03102 set_current_def (referenced_var (i), NULL_TREE);
03103
03104
03105 tmp = sbitmap_alloc (last_basic_block);
03106 sbitmap_zero (tmp);
03107 EXECUTE_IF_SET_IN_BITMAP (blocks_to_update, 0, i, bi)
03108 SET_BIT (tmp, i);
03109
03110 rewrite_blocks (start_bb, REWRITE_UPDATE, tmp);
03111
03112 sbitmap_free (tmp);
03113
03114
03115 if (dump_file)
03116 {
03117 int c;
03118 unsigned i;
03119
03120 dump_update_ssa (dump_file);
03121
03122 fprintf (dump_file, "Incremental SSA update started at block: %d\n\n",
03123 start_bb->index);
03124
03125 c = 0;
03126 EXECUTE_IF_SET_IN_BITMAP (blocks_to_update, 0, i, bi)
03127 c++;
03128 fprintf (dump_file, "Number of blocks in CFG: %d\n", last_basic_block);
03129 fprintf (dump_file, "Number of blocks to update: %d (%3.0f%%)\n\n",
03130 c, PERCENT (c, last_basic_block));
03131
03132 if (dump_flags & TDF_DETAILS)
03133 {
03134 fprintf (dump_file, "Affected blocks: ");
03135 EXECUTE_IF_SET_IN_BITMAP (blocks_to_update, 0, i, bi)
03136 fprintf (dump_file, "%u ", i);
03137 fprintf (dump_file, "\n");
03138 }
03139
03140 fprintf (dump_file, "\n\n");
03141 }
03142
03143
03144 done:
03145 EXECUTE_IF_SET_IN_BITMAP (blocks_with_phis_to_rewrite, 0, i, bi)
03146 {
03147 tree_vec phis = VEC_index (tree_vec, phis_to_rewrite, i);
03148
03149 VEC_free (tree, heap, phis);
03150 VEC_replace (tree_vec, phis_to_rewrite, i, NULL);
03151 }
03152 BITMAP_FREE (blocks_with_phis_to_rewrite);
03153 BITMAP_FREE (blocks_to_update);
03154 delete_update_ssa ();
03155
03156 timevar_pop (TV_TREE_SSA_INCREMENTAL);
03157 }