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 "errors.h"
00035 #include "expr.h"
00036 #include "function.h"
00037 #include "diagnostic.h"
00038 #include "bitmap.h"
00039 #include "tree-flow.h"
00040 #include "tree-gimple.h"
00041 #include "tree-inline.h"
00042 #include "varray.h"
00043 #include "timevar.h"
00044 #include "hashtab.h"
00045 #include "tree-dump.h"
00046 #include "tree-pass.h"
00047 #include "cfgloop.h"
00048 #include "domwalk.h"
00049 #include "ggc.h"
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 struct def_blocks_d
00060 {
00061
00062 tree var;
00063
00064
00065
00066 bitmap def_blocks;
00067
00068
00069 bitmap phi_blocks;
00070
00071
00072
00073 bitmap livein_blocks;
00074 };
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 static htab_t def_blocks;
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 static VEC(tree_on_heap) *block_defs_stack;
00112
00113
00114 DEF_VEC_MALLOC_P(basic_block);
00115
00116
00117 struct mark_def_sites_global_data
00118 {
00119
00120
00121
00122
00123 bitmap kills;
00124
00125
00126 sbitmap names_to_rename;
00127 };
00128
00129
00130
00131 struct ssa_name_info
00132 {
00133
00134
00135
00136 ENUM_BITFIELD (need_phi_state) need_phi_state : 2;
00137
00138
00139 tree current_def;
00140 };
00141
00142
00143
00144
00145
00146 #define REWRITE_THIS_STMT(T) TREE_VISITED (T)
00147
00148
00149
00150
00151 static inline struct ssa_name_info *
00152 get_ssa_name_ann (tree name)
00153 {
00154 if (!SSA_NAME_AUX (name))
00155 SSA_NAME_AUX (name) = xcalloc (1, sizeof (struct ssa_name_info));
00156
00157 return SSA_NAME_AUX (name);
00158 }
00159
00160
00161
00162
00163 static inline enum need_phi_state
00164 get_phi_state (tree var)
00165 {
00166 if (TREE_CODE (var) == SSA_NAME)
00167 return get_ssa_name_ann (var)->need_phi_state;
00168 else
00169 return var_ann (var)->need_phi_state;
00170 }
00171
00172
00173
00174
00175 static inline void
00176 set_phi_state (tree var, enum need_phi_state state)
00177 {
00178 if (TREE_CODE (var) == SSA_NAME)
00179 get_ssa_name_ann (var)->need_phi_state = state;
00180 else
00181 var_ann (var)->need_phi_state = state;
00182 }
00183
00184
00185
00186
00187 static inline tree
00188 get_current_def (tree var)
00189 {
00190 if (TREE_CODE (var) == SSA_NAME)
00191 return get_ssa_name_ann (var)->current_def;
00192 else
00193 return var_ann (var)->current_def;
00194 }
00195
00196
00197
00198
00199 static inline void
00200 set_current_def (tree var, tree def)
00201 {
00202 if (TREE_CODE (var) == SSA_NAME)
00203 get_ssa_name_ann (var)->current_def = def;
00204 else
00205 var_ann (var)->current_def = def;
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 void
00218 compute_global_livein (bitmap livein, bitmap def_blocks)
00219 {
00220 basic_block bb, *worklist, *tos;
00221 unsigned i;
00222 bitmap_iterator bi;
00223
00224 tos = worklist
00225 = (basic_block *) xmalloc (sizeof (basic_block) * (n_basic_blocks + 1));
00226
00227 EXECUTE_IF_SET_IN_BITMAP (livein, 0, i, bi)
00228 {
00229 *tos++ = BASIC_BLOCK (i);
00230 }
00231
00232
00233 while (tos != worklist)
00234 {
00235 edge e;
00236 edge_iterator ei;
00237
00238
00239 bb = *--tos;
00240
00241
00242 FOR_EACH_EDGE (e, ei, bb->preds)
00243 {
00244 basic_block pred = e->src;
00245 int pred_index = pred->index;
00246
00247
00248 if (pred != ENTRY_BLOCK_PTR
00249 && ! bitmap_bit_p (livein, pred_index)
00250 && ! bitmap_bit_p (def_blocks, pred_index))
00251 {
00252 *tos++ = pred;
00253 bitmap_set_bit (livein, pred_index);
00254 }
00255 }
00256 }
00257
00258 free (worklist);
00259 }
00260
00261
00262
00263
00264
00265
00266 static inline struct def_blocks_d *
00267 get_def_blocks_for (tree var)
00268 {
00269 struct def_blocks_d db, *db_p;
00270 void **slot;
00271
00272 db.var = var;
00273 slot = htab_find_slot (def_blocks, (void *) &db, INSERT);
00274 if (*slot == NULL)
00275 {
00276 db_p = xmalloc (sizeof (*db_p));
00277 db_p->var = var;
00278 db_p->def_blocks = BITMAP_ALLOC (NULL);
00279 db_p->phi_blocks = BITMAP_ALLOC (NULL);
00280 db_p->livein_blocks = BITMAP_ALLOC (NULL);
00281 *slot = (void *) db_p;
00282 }
00283 else
00284 db_p = (struct def_blocks_d *) *slot;
00285
00286 return db_p;
00287 }
00288
00289
00290
00291
00292
00293
00294 static void
00295 set_def_block (tree var, basic_block bb, bool phi_p, bool is_update)
00296 {
00297 struct def_blocks_d *db_p;
00298 enum need_phi_state state;
00299
00300 if (!is_update && TREE_CODE (var) == SSA_NAME)
00301 var = SSA_NAME_VAR (var);
00302
00303 state = get_phi_state (var);
00304 db_p = get_def_blocks_for (var);
00305
00306
00307 bitmap_set_bit (db_p->def_blocks, bb->index);
00308 if (phi_p)
00309 bitmap_set_bit (db_p->phi_blocks, bb->index);
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 if (state == NEED_PHI_STATE_UNKNOWN)
00324 set_phi_state (var, NEED_PHI_STATE_NO);
00325 else
00326 set_phi_state (var, NEED_PHI_STATE_MAYBE);
00327 }
00328
00329
00330
00331
00332 static void
00333 set_livein_block (tree var, basic_block bb)
00334 {
00335 struct def_blocks_d *db_p;
00336 enum need_phi_state state = get_phi_state (var);
00337
00338 db_p = get_def_blocks_for (var);
00339
00340
00341 bitmap_set_bit (db_p->livein_blocks, bb->index);
00342
00343
00344
00345
00346
00347
00348
00349 if (state == NEED_PHI_STATE_NO)
00350 {
00351 int def_block_index = bitmap_first_set_bit (db_p->def_blocks);
00352
00353 if (def_block_index == -1
00354 || ! dominated_by_p (CDI_DOMINATORS, bb,
00355 BASIC_BLOCK (def_block_index)))
00356 set_phi_state (var, NEED_PHI_STATE_MAYBE);
00357 }
00358 else
00359 set_phi_state (var, NEED_PHI_STATE_MAYBE);
00360 }
00361
00362
00363
00364
00365
00366
00367
00368 static bool
00369 prepare_use_operand_for_rename (use_operand_p op_p, size_t *uid_p)
00370 {
00371 tree use = USE_FROM_PTR (op_p);
00372 tree var = (TREE_CODE (use) != SSA_NAME) ? use : SSA_NAME_VAR (use);
00373 *uid_p = var_ann (var)->uid;
00374
00375
00376 if (vars_to_rename && !bitmap_bit_p (vars_to_rename, *uid_p))
00377 return false;
00378
00379
00380
00381
00382
00383
00384
00385 if (TREE_CODE (use) == SSA_NAME)
00386 SET_USE (op_p, var);
00387
00388 return true;
00389 }
00390
00391
00392
00393
00394
00395
00396 static bool
00397 prepare_def_operand_for_rename (tree def, size_t *uid_p)
00398 {
00399 tree var = (TREE_CODE (def) != SSA_NAME) ? def : SSA_NAME_VAR (def);
00400 *uid_p = var_ann (var)->uid;
00401
00402
00403 if (vars_to_rename && !bitmap_bit_p (vars_to_rename, *uid_p))
00404 return false;
00405
00406 return true;
00407 }
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 static void
00426 mark_def_sites (struct dom_walk_data *walk_data,
00427 basic_block bb,
00428 block_stmt_iterator bsi)
00429 {
00430 struct mark_def_sites_global_data *gd = walk_data->global_data;
00431 bitmap kills = gd->kills;
00432 size_t uid;
00433 tree stmt, def;
00434 use_operand_p use_p;
00435 def_operand_p def_p;
00436 ssa_op_iter iter;
00437
00438
00439
00440 stmt = bsi_stmt (bsi);
00441 get_stmt_operands (stmt);
00442
00443 REWRITE_THIS_STMT (stmt) = 0;
00444
00445
00446
00447
00448 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
00449 SSA_OP_USE | SSA_OP_VUSE | SSA_OP_VMUSTDEFKILL)
00450 {
00451 if (prepare_use_operand_for_rename (use_p, &uid))
00452 {
00453 REWRITE_THIS_STMT (stmt) = 1;
00454 if (!bitmap_bit_p (kills, uid))
00455 set_livein_block (USE_FROM_PTR (use_p), bb);
00456 }
00457 }
00458
00459
00460
00461
00462
00463
00464 FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
00465 {
00466 if (prepare_use_operand_for_rename (use_p, &uid))
00467 {
00468
00469
00470 if (TREE_CODE (DEF_FROM_PTR (def_p)) != SSA_NAME)
00471 SET_DEF (def_p, USE_FROM_PTR (use_p));
00472
00473 set_livein_block (USE_FROM_PTR (use_p), bb);
00474 set_def_block (DEF_FROM_PTR (def_p), bb, false, false);
00475 REWRITE_THIS_STMT (stmt) = 1;
00476 }
00477 }
00478
00479
00480 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF | SSA_OP_VMUSTDEF)
00481 {
00482 if (prepare_def_operand_for_rename (def, &uid))
00483 {
00484 set_def_block (def, bb, false, false);
00485 bitmap_set_bit (kills, uid);
00486 REWRITE_THIS_STMT (stmt) = 1;
00487 }
00488 }
00489 }
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 static bitmap
00502 find_idf (bitmap def_blocks, bitmap *dfs)
00503 {
00504 bitmap_iterator bi;
00505 unsigned bb_index;
00506 VEC(basic_block) *work_stack;
00507 bitmap phi_insertion_points;
00508
00509 work_stack = VEC_alloc (basic_block, n_basic_blocks);
00510 phi_insertion_points = BITMAP_ALLOC (NULL);
00511
00512
00513 EXECUTE_IF_SET_IN_BITMAP (def_blocks, 0, bb_index, bi)
00514 VEC_safe_push (basic_block, work_stack, BASIC_BLOCK (bb_index));
00515
00516
00517
00518
00519
00520
00521 while (VEC_length (basic_block, work_stack) > 0)
00522 {
00523 basic_block bb = VEC_pop (basic_block, work_stack);
00524 bb_index = bb->index;
00525
00526 EXECUTE_IF_AND_COMPL_IN_BITMAP (dfs[bb_index], phi_insertion_points,
00527 0, bb_index, bi)
00528 {
00529 bb = BASIC_BLOCK (bb_index);
00530
00531
00532
00533
00534 VEC_safe_push (basic_block, work_stack, bb);
00535 bitmap_set_bit (phi_insertion_points, bb_index);
00536 }
00537 }
00538
00539 VEC_free (basic_block, work_stack);
00540
00541 return phi_insertion_points;
00542 }
00543
00544
00545
00546
00547
00548
00549 static inline struct def_blocks_d *
00550 find_def_blocks_for (tree var)
00551 {
00552 struct def_blocks_d dm;
00553 dm.var = var;
00554 return (struct def_blocks_d *) htab_find (def_blocks, &dm);
00555 }
00556
00557
00558
00559
00560
00561 static void
00562 insert_phi_nodes_for (tree var, bitmap phi_insertion_points)
00563 {
00564 unsigned bb_index;
00565 edge e;
00566 tree phi;
00567 basic_block bb;
00568 bitmap_iterator bi;
00569 struct def_blocks_d *def_map;
00570
00571 def_map = find_def_blocks_for (var);
00572
00573
00574 bitmap_and_compl_into (phi_insertion_points, def_map->phi_blocks);
00575
00576
00577
00578 compute_global_livein (def_map->livein_blocks, def_map->def_blocks);
00579
00580
00581 EXECUTE_IF_AND_IN_BITMAP (phi_insertion_points, def_map->livein_blocks,
00582 0, bb_index, bi)
00583 {
00584 bb = BASIC_BLOCK (bb_index);
00585 phi = create_phi_node (var, bb);
00586
00587
00588 if (TREE_CODE (var) == SSA_NAME)
00589 {
00590 edge_iterator ei;
00591 FOR_EACH_EDGE (e, ei, bb->preds)
00592 add_phi_arg (phi, var, e);
00593 }
00594 }
00595 }
00596
00597
00598
00599
00600
00601 static inline void
00602 insert_phi_nodes_1 (tree var, bitmap *dfs)
00603 {
00604 struct def_blocks_d *def_map;
00605 bitmap idf;
00606
00607 def_map = find_def_blocks_for (var);
00608 if (def_map == NULL)
00609 return;
00610
00611 idf = find_idf (def_map->def_blocks, dfs);
00612
00613 if (get_phi_state (var) != NEED_PHI_STATE_NO)
00614 insert_phi_nodes_for (var, idf);
00615
00616 BITMAP_FREE (idf);
00617 }
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628 static void
00629 insert_phi_nodes (bitmap *dfs, bitmap names_to_rename)
00630 {
00631 unsigned i;
00632 bitmap_iterator bi;
00633
00634 timevar_push (TV_TREE_INSERT_PHI_NODES);
00635
00636
00637
00638
00639
00640 if (names_to_rename)
00641 {
00642 EXECUTE_IF_SET_IN_BITMAP (names_to_rename, 0, i, bi)
00643 if (ssa_name (i))
00644 insert_phi_nodes_1 (ssa_name (i), dfs);
00645 }
00646 else if (vars_to_rename)
00647 {
00648 EXECUTE_IF_SET_IN_BITMAP (vars_to_rename, 0, i, bi)
00649 insert_phi_nodes_1 (referenced_var (i), dfs);
00650 }
00651 else
00652 {
00653 for (i = 0; i < num_referenced_vars; i++)
00654 insert_phi_nodes_1 (referenced_var (i), dfs);
00655 }
00656
00657 timevar_pop (TV_TREE_INSERT_PHI_NODES);
00658 }
00659
00660
00661
00662
00663
00664
00665 void
00666 register_new_def (tree def, VEC (tree_on_heap) **block_defs_p)
00667 {
00668 tree var = SSA_NAME_VAR (def);
00669 tree currdef;
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679 if (get_phi_state (var) == NEED_PHI_STATE_NO)
00680 {
00681 set_current_def (var, def);
00682 return;
00683 }
00684
00685 currdef = get_current_def (var);
00686
00687
00688
00689
00690
00691
00692 VEC_safe_push (tree_on_heap, *block_defs_p, currdef ? currdef : var);
00693
00694
00695 set_current_def (var, def);
00696 }
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727 static void
00728 rewrite_initialize_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
00729 basic_block bb)
00730 {
00731 tree phi;
00732
00733 if (dump_file && (dump_flags & TDF_DETAILS))
00734 fprintf (dump_file, "\n\nRenaming block #%d\n\n", bb->index);
00735
00736
00737 VEC_safe_push (tree_on_heap, block_defs_stack, NULL_TREE);
00738
00739
00740
00741
00742 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
00743 {
00744 tree result = PHI_RESULT (phi);
00745 register_new_def (result, &block_defs_stack);
00746 }
00747 }
00748
00749
00750
00751
00752
00753
00754
00755
00756 static tree
00757 get_reaching_def (tree var)
00758 {
00759 tree default_d, currdef_var, avar;
00760
00761
00762 default_d = NULL_TREE;
00763 currdef_var = get_current_def (var);
00764
00765
00766
00767 if (currdef_var == NULL_TREE)
00768 {
00769 if (TREE_CODE (var) == SSA_NAME)
00770 avar = SSA_NAME_VAR (var);
00771 else
00772 avar = var;
00773
00774 default_d = default_def (avar);
00775 if (default_d == NULL_TREE)
00776 {
00777 default_d = make_ssa_name (avar, build_empty_stmt ());
00778 set_default_def (avar, default_d);
00779 }
00780 set_current_def (var, default_d);
00781 }
00782
00783
00784
00785 return (currdef_var) ? currdef_var : default_d;
00786 }
00787
00788
00789
00790
00791
00792 static inline void
00793 rewrite_operand (use_operand_p op_p)
00794 {
00795 tree var = USE_FROM_PTR (op_p);
00796 if (TREE_CODE (var) != SSA_NAME)
00797 SET_USE (op_p, get_reaching_def (var));
00798 else
00799 {
00800 #if defined ENABLE_CHECKING
00801
00802
00803
00804
00805 tree sym = SSA_NAME_VAR (var);
00806 if (bitmap_bit_p (vars_to_rename, var_ann (sym)->uid))
00807 gcc_assert (var == get_reaching_def (SSA_NAME_VAR (var)));
00808 #endif
00809 }
00810 }
00811
00812
00813
00814
00815
00816
00817 static void
00818 rewrite_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
00819 basic_block bb ATTRIBUTE_UNUSED,
00820 block_stmt_iterator si)
00821 {
00822 stmt_ann_t ann;
00823 tree stmt;
00824 use_operand_p use_p;
00825 def_operand_p def_p;
00826 ssa_op_iter iter;
00827
00828 stmt = bsi_stmt (si);
00829 ann = stmt_ann (stmt);
00830
00831
00832
00833 if (!REWRITE_THIS_STMT (stmt))
00834 return;
00835
00836 if (dump_file && (dump_flags & TDF_DETAILS))
00837 {
00838 fprintf (dump_file, "Renaming statement ");
00839 print_generic_stmt (dump_file, stmt, TDF_SLIM);
00840 fprintf (dump_file, "\n");
00841 }
00842
00843 get_stmt_operands (stmt);
00844
00845
00846 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES | SSA_OP_ALL_KILLS)
00847 rewrite_operand (use_p);
00848
00849
00850 FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_ALL_DEFS)
00851 {
00852 if (TREE_CODE (DEF_FROM_PTR (def_p)) != SSA_NAME)
00853 SET_DEF (def_p, make_ssa_name (DEF_FROM_PTR (def_p), stmt));
00854
00855
00856
00857 register_new_def (DEF_FROM_PTR (def_p), &block_defs_stack);
00858 }
00859 }
00860
00861
00862
00863
00864
00865
00866
00867 static void
00868 rewrite_add_phi_arguments (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
00869 basic_block bb)
00870 {
00871 edge e;
00872 edge_iterator ei;
00873
00874 FOR_EACH_EDGE (e, ei, bb->succs)
00875 {
00876 tree phi;
00877
00878 for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
00879 {
00880 tree currdef;
00881
00882
00883
00884
00885 if (PHI_REWRITTEN (phi))
00886 break;
00887
00888 currdef = get_reaching_def (SSA_NAME_VAR (PHI_RESULT (phi)));
00889 add_phi_arg (phi, currdef, e);
00890 }
00891 }
00892 }
00893
00894
00895
00896
00897
00898
00899 static void
00900 rewrite_virtual_phi_arguments (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
00901 basic_block bb)
00902 {
00903 edge e;
00904 use_operand_p op;
00905 edge_iterator ei;
00906
00907 FOR_EACH_EDGE (e, ei, bb->succs)
00908 {
00909 tree phi;
00910
00911 if (e->dest == EXIT_BLOCK_PTR)
00912 continue;
00913
00914 for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
00915 {
00916 tree result = PHI_RESULT (phi);
00917 op = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
00918
00919 if (is_gimple_reg (result)
00920 || !bitmap_bit_p (vars_to_rename,
00921 var_ann (SSA_NAME_VAR (result))->uid))
00922 continue;
00923
00924 SET_USE (op, get_reaching_def (SSA_NAME_VAR (result)));
00925 if (e->flags & EDGE_ABNORMAL)
00926 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (op)) = 1;
00927 }
00928 }
00929 }
00930
00931
00932
00933
00934
00935 static void
00936 rewrite_finalize_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
00937 basic_block bb ATTRIBUTE_UNUSED)
00938 {
00939
00940 while (VEC_length (tree_on_heap, block_defs_stack) > 0)
00941 {
00942 tree tmp = VEC_pop (tree_on_heap, block_defs_stack);
00943 tree saved_def, var;
00944
00945 if (tmp == NULL_TREE)
00946 break;
00947
00948
00949
00950
00951
00952 if (TREE_CODE (tmp) == SSA_NAME)
00953 {
00954 saved_def = tmp;
00955 var = SSA_NAME_VAR (saved_def);
00956 }
00957 else
00958 {
00959 saved_def = NULL;
00960 var = tmp;
00961 }
00962
00963 set_current_def (var, saved_def);
00964 }
00965 }
00966
00967
00968
00969
00970 void
00971 dump_tree_ssa (FILE *file)
00972 {
00973 basic_block bb;
00974 const char *funcname
00975 = lang_hooks.decl_printable_name (current_function_decl, 2);
00976
00977 fprintf (file, "SSA information for %s\n\n", funcname);
00978
00979 FOR_EACH_BB (bb)
00980 {
00981 dump_bb (bb, file, 0);
00982 fputs (" ", file);
00983 print_generic_stmt (file, phi_nodes (bb), dump_flags);
00984 fputs ("\n\n", file);
00985 }
00986 }
00987
00988
00989
00990
00991 void
00992 debug_tree_ssa (void)
00993 {
00994 dump_tree_ssa (stderr);
00995 }
00996
00997
00998
00999
01000 static void
01001 htab_statistics (FILE *file, htab_t htab)
01002 {
01003 fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
01004 (long) htab_size (htab),
01005 (long) htab_elements (htab),
01006 htab_collisions (htab));
01007 }
01008
01009
01010
01011
01012 void
01013 dump_tree_ssa_stats (FILE *file)
01014 {
01015 fprintf (file, "\nHash table statistics:\n");
01016
01017 fprintf (file, " def_blocks: ");
01018 htab_statistics (file, def_blocks);
01019
01020 fprintf (file, "\n");
01021 }
01022
01023
01024
01025
01026 void
01027 debug_tree_ssa_stats (void)
01028 {
01029 dump_tree_ssa_stats (stderr);
01030 }
01031
01032
01033
01034
01035 static hashval_t
01036 def_blocks_hash (const void *p)
01037 {
01038 return htab_hash_pointer
01039 ((const void *)((const struct def_blocks_d *)p)->var);
01040 }
01041
01042 static int
01043 def_blocks_eq (const void *p1, const void *p2)
01044 {
01045 return ((const struct def_blocks_d *)p1)->var
01046 == ((const struct def_blocks_d *)p2)->var;
01047 }
01048
01049
01050
01051
01052 static void
01053 def_blocks_free (void *p)
01054 {
01055 struct def_blocks_d *entry = p;
01056 BITMAP_FREE (entry->def_blocks);
01057 BITMAP_FREE (entry->phi_blocks);
01058 BITMAP_FREE (entry->livein_blocks);
01059 free (entry);
01060 }
01061
01062
01063
01064
01065 static int
01066 debug_def_blocks_r (void **slot, void *data ATTRIBUTE_UNUSED)
01067 {
01068 struct def_blocks_d *db_p = (struct def_blocks_d *) *slot;
01069
01070 fprintf (stderr, "VAR: ");
01071 print_generic_expr (stderr, db_p->var, dump_flags);
01072 bitmap_print (stderr, db_p->def_blocks, ", DEF_BLOCKS: { ", "}");
01073 bitmap_print (stderr, db_p->livein_blocks, ", LIVEIN_BLOCKS: { ", "}\n");
01074
01075 return 1;
01076 }
01077
01078
01079
01080
01081 void
01082 debug_def_blocks (void)
01083 {
01084 htab_traverse (def_blocks, debug_def_blocks_r, NULL);
01085 }
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101 static void
01102 invalidate_name_tags (bitmap vars_to_rename)
01103 {
01104 unsigned i;
01105 bool rename_name_tags_p;
01106 bitmap_iterator bi;
01107
01108 rename_name_tags_p = false;
01109 EXECUTE_IF_SET_IN_BITMAP (vars_to_rename, 0, i, bi)
01110 {
01111 if (POINTER_TYPE_P (TREE_TYPE (referenced_var (i))))
01112 {
01113 rename_name_tags_p = true;
01114 break;
01115 }
01116 }
01117
01118 if (rename_name_tags_p)
01119 for (i = 0; i < num_referenced_vars; i++)
01120 {
01121 var_ann_t ann = var_ann (referenced_var (i));
01122
01123 if (ann->mem_tag_kind == NAME_TAG)
01124 {
01125 size_t j;
01126 varray_type may_aliases = ann->may_aliases;
01127
01128 bitmap_set_bit (vars_to_rename, ann->uid);
01129 if (ann->may_aliases)
01130 for (j = 0; j < VARRAY_ACTIVE_SIZE (may_aliases); j++)
01131 {
01132 tree var = VARRAY_TREE (may_aliases, j);
01133 bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
01134 }
01135 }
01136 }
01137 }
01138
01139
01140
01141
01142
01143
01144
01145 static void
01146 rewrite_blocks (bool fix_virtual_phis)
01147 {
01148 struct dom_walk_data walk_data;
01149
01150
01151 timevar_push (TV_TREE_SSA_REWRITE_BLOCKS);
01152
01153
01154 walk_data.walk_stmts_backward = false;
01155 walk_data.dom_direction = CDI_DOMINATORS;
01156 walk_data.initialize_block_local_data = NULL;
01157 walk_data.before_dom_children_before_stmts = rewrite_initialize_block;
01158 walk_data.before_dom_children_walk_stmts = rewrite_stmt;
01159 walk_data.before_dom_children_after_stmts = NULL;
01160 if (!fix_virtual_phis)
01161 walk_data.before_dom_children_after_stmts = rewrite_add_phi_arguments;
01162 else
01163 walk_data.before_dom_children_after_stmts = rewrite_virtual_phi_arguments;
01164
01165 walk_data.after_dom_children_before_stmts = NULL;
01166 walk_data.after_dom_children_walk_stmts = NULL;
01167 walk_data.after_dom_children_after_stmts = rewrite_finalize_block;
01168 walk_data.global_data = NULL;
01169 walk_data.block_local_data_size = 0;
01170
01171 block_defs_stack = VEC_alloc (tree_on_heap, 10);
01172
01173
01174 init_walk_dominator_tree (&walk_data);
01175
01176
01177
01178 walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
01179
01180
01181 fini_walk_dominator_tree (&walk_data);
01182
01183
01184 if (dump_file && (dump_flags & TDF_STATS))
01185 {
01186 dump_dfa_stats (dump_file);
01187 dump_tree_ssa_stats (dump_file);
01188 }
01189
01190 htab_delete (def_blocks);
01191 def_blocks = NULL;
01192
01193 VEC_free (tree_on_heap, block_defs_stack);
01194 block_defs_stack = NULL;
01195
01196 timevar_pop (TV_TREE_SSA_REWRITE_BLOCKS);
01197 }
01198
01199
01200
01201
01202
01203 static void
01204 mark_def_sites_initialize_block (struct dom_walk_data *walk_data,
01205 basic_block bb ATTRIBUTE_UNUSED)
01206 {
01207 struct mark_def_sites_global_data *gd = walk_data->global_data;
01208 bitmap kills = gd->kills;
01209 bitmap_clear (kills);
01210 }
01211
01212
01213
01214
01215
01216 static void
01217 mark_def_site_blocks (void)
01218 {
01219 size_t i;
01220 struct dom_walk_data walk_data;
01221 struct mark_def_sites_global_data mark_def_sites_global_data;
01222
01223
01224 def_blocks = htab_create (VARRAY_ACTIVE_SIZE (referenced_vars),
01225 def_blocks_hash, def_blocks_eq, def_blocks_free);
01226
01227 for (i = 0; i < num_referenced_vars; i++)
01228 set_current_def (referenced_var (i), NULL_TREE);
01229
01230
01231 calculate_dominance_info (CDI_DOMINATORS);
01232
01233
01234
01235 walk_data.walk_stmts_backward = false;
01236 walk_data.dom_direction = CDI_DOMINATORS;
01237 walk_data.initialize_block_local_data = NULL;
01238 walk_data.before_dom_children_before_stmts = mark_def_sites_initialize_block;
01239 walk_data.before_dom_children_walk_stmts = mark_def_sites;
01240 walk_data.before_dom_children_after_stmts = NULL;
01241 walk_data.after_dom_children_before_stmts = NULL;
01242 walk_data.after_dom_children_walk_stmts = NULL;
01243 walk_data.after_dom_children_after_stmts = NULL;
01244
01245
01246
01247
01248 mark_def_sites_global_data.kills = BITMAP_ALLOC (NULL);
01249 walk_data.global_data = &mark_def_sites_global_data;
01250
01251
01252 walk_data.block_local_data_size = 0;
01253
01254
01255 init_walk_dominator_tree (&walk_data);
01256
01257
01258 walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
01259
01260
01261 fini_walk_dominator_tree (&walk_data);
01262
01263
01264 BITMAP_FREE (mark_def_sites_global_data.kills);
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 void
01293 rewrite_into_ssa (bool all)
01294 {
01295 bitmap *dfs;
01296 basic_block bb;
01297 bitmap old_vars_to_rename = vars_to_rename;
01298
01299 timevar_push (TV_TREE_SSA_OTHER);
01300
01301 if (all)
01302 vars_to_rename = NULL;
01303 else
01304 {
01305
01306 gcc_assert (vars_to_rename);
01307
01308 if (bitmap_empty_p (vars_to_rename))
01309 {
01310 timevar_pop (TV_TREE_SSA_OTHER);
01311 return;
01312 }
01313
01314 invalidate_name_tags (vars_to_rename);
01315
01316
01317
01318 remove_all_phi_nodes_for (vars_to_rename);
01319 }
01320
01321 mark_def_site_blocks ();
01322
01323
01324
01325
01326 dfs = (bitmap *) xmalloc (last_basic_block * sizeof (bitmap *));
01327 FOR_EACH_BB (bb)
01328 dfs[bb->index] = BITMAP_ALLOC (NULL);
01329
01330
01331 compute_dominance_frontiers (dfs);
01332
01333
01334 insert_phi_nodes (dfs, NULL);
01335
01336 rewrite_blocks (false);
01337
01338
01339 FOR_EACH_BB (bb)
01340 BITMAP_FREE (dfs[bb->index]);
01341 free (dfs);
01342
01343 vars_to_rename = old_vars_to_rename;
01344 timevar_pop (TV_TREE_SSA_OTHER);
01345 }
01346
01347
01348
01349
01350 static void
01351 rewrite_all_into_ssa (void)
01352 {
01353 rewrite_into_ssa (true);
01354 }
01355
01356 struct tree_opt_pass pass_build_ssa =
01357 {
01358 "ssa",
01359 NULL,
01360 rewrite_all_into_ssa,
01361 NULL,
01362 NULL,
01363 0,
01364 0,
01365 PROP_cfg | PROP_referenced_vars,
01366 PROP_ssa,
01367 0,
01368 0,
01369 TODO_dump_func | TODO_verify_ssa,
01370 0
01371 };
01372
01373
01374
01375
01376
01377 void
01378 rewrite_def_def_chains (void)
01379 {
01380
01381 calculate_dominance_info (CDI_DOMINATORS);
01382 mark_def_site_blocks ();
01383 rewrite_blocks (true);
01384 }
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396 static void
01397 ssa_rewrite_finalize_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
01398 basic_block bb ATTRIBUTE_UNUSED)
01399 {
01400
01401
01402
01403 while (VEC_length (tree_on_heap, block_defs_stack) > 0)
01404 {
01405 tree var = VEC_pop (tree_on_heap, block_defs_stack);
01406 tree saved_def;
01407
01408 if (var == NULL)
01409 break;
01410
01411 saved_def = VEC_pop (tree_on_heap, block_defs_stack);
01412 set_current_def (var, saved_def);
01413 }
01414 }
01415
01416
01417
01418
01419
01420
01421 static void
01422 ssa_register_new_def (tree var, tree def)
01423 {
01424 tree currdef;
01425
01426
01427
01428
01429
01430 if (get_phi_state (var) == NEED_PHI_STATE_NO)
01431 {
01432 set_current_def (var, def);
01433 return;
01434 }
01435
01436 currdef = get_current_def (var);
01437
01438
01439
01440
01441
01442 VEC_safe_push (tree_on_heap, block_defs_stack, currdef);
01443 VEC_safe_push (tree_on_heap, block_defs_stack, var);
01444
01445
01446 set_current_def (var, def);
01447 }
01448
01449
01450
01451
01452 static void
01453 ssa_rewrite_stmt (struct dom_walk_data *walk_data,
01454 basic_block bb ATTRIBUTE_UNUSED,
01455 block_stmt_iterator si)
01456 {
01457 stmt_ann_t ann;
01458 tree stmt, var;
01459 ssa_op_iter iter;
01460 use_operand_p use_p;
01461 def_operand_p def_p;
01462 sbitmap names_to_rename = walk_data->global_data;
01463
01464 stmt = bsi_stmt (si);
01465 ann = stmt_ann (stmt);
01466
01467 if (dump_file && (dump_flags & TDF_DETAILS))
01468 {
01469 fprintf (dump_file, "Renaming statement ");
01470 print_generic_stmt (dump_file, stmt, TDF_SLIM);
01471 fprintf (dump_file, "\n");
01472 }
01473
01474
01475
01476 gcc_assert (!ann->modified);
01477
01478
01479 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES | SSA_OP_ALL_KILLS)
01480 {
01481 if (TEST_BIT (names_to_rename, SSA_NAME_VERSION (USE_FROM_PTR (use_p))))
01482 SET_USE (use_p, get_reaching_def (USE_FROM_PTR (use_p)));
01483 }
01484
01485
01486 FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_ALL_DEFS)
01487 {
01488 var = DEF_FROM_PTR (def_p);
01489
01490 if (!TEST_BIT (names_to_rename, SSA_NAME_VERSION (var)))
01491 continue;
01492
01493 SET_DEF (def_p, duplicate_ssa_name (var, stmt));
01494 ssa_register_new_def (var, DEF_FROM_PTR (def_p));
01495 }
01496 }
01497
01498
01499
01500
01501 static void
01502 ssa_rewrite_phi_arguments (struct dom_walk_data *walk_data, basic_block bb)
01503 {
01504 edge e;
01505 sbitmap names_to_rename = walk_data->global_data;
01506 use_operand_p op;
01507 edge_iterator ei;
01508
01509 FOR_EACH_EDGE (e, ei, bb->succs)
01510 {
01511 tree phi;
01512
01513 if (e->dest == EXIT_BLOCK_PTR)
01514 continue;
01515
01516 for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
01517 {
01518 op = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
01519 if (TREE_CODE (USE_FROM_PTR (op)) != SSA_NAME)
01520 continue;
01521
01522 if (!TEST_BIT (names_to_rename, SSA_NAME_VERSION (USE_FROM_PTR (op))))
01523 continue;
01524
01525 SET_USE (op, get_reaching_def (USE_FROM_PTR (op)));
01526 if (e->flags & EDGE_ABNORMAL)
01527 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (op)) = 1;
01528 }
01529 }
01530 }
01531
01532
01533
01534 static void
01535 ssa_rewrite_initialize_block (struct dom_walk_data *walk_data, basic_block bb)
01536 {
01537 tree phi, new_name;
01538 sbitmap names_to_rename = walk_data->global_data;
01539 edge e;
01540 bool abnormal_phi;
01541 edge_iterator ei;
01542
01543 if (dump_file && (dump_flags & TDF_DETAILS))
01544 fprintf (dump_file, "\n\nRenaming block #%d\n\n", bb->index);
01545
01546
01547 VEC_safe_push (tree_on_heap, block_defs_stack, NULL_TREE);
01548
01549 FOR_EACH_EDGE (e, ei, bb->preds)
01550 if (e->flags & EDGE_ABNORMAL)
01551 break;
01552 abnormal_phi = (e != NULL);
01553
01554
01555
01556
01557 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
01558 {
01559 tree result = PHI_RESULT (phi);
01560
01561 if (TEST_BIT (names_to_rename, SSA_NAME_VERSION (result)))
01562 {
01563 new_name = duplicate_ssa_name (result, phi);
01564 SET_PHI_RESULT (phi, new_name);
01565
01566 if (abnormal_phi)
01567 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name) = 1;
01568 ssa_register_new_def (result, new_name);
01569 }
01570 }
01571 }
01572
01573
01574
01575
01576 static void
01577 ssa_mark_def_sites (struct dom_walk_data *walk_data,
01578 basic_block bb,
01579 block_stmt_iterator bsi)
01580 {
01581 struct mark_def_sites_global_data *gd = walk_data->global_data;
01582 bitmap kills = gd->kills;
01583 size_t uid, def_uid;
01584 tree stmt, use, def;
01585 ssa_op_iter iter;
01586
01587
01588
01589 stmt = bsi_stmt (bsi);
01590 get_stmt_operands (stmt);
01591
01592
01593
01594 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_USES | SSA_OP_ALL_KILLS)
01595 {
01596 uid = SSA_NAME_VERSION (use);
01597
01598 if (TEST_BIT (gd->names_to_rename, uid)
01599 && !bitmap_bit_p (kills, uid))
01600 set_livein_block (use, bb);
01601 }
01602
01603
01604
01605 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
01606 {
01607 def_uid = SSA_NAME_VERSION (def);
01608
01609 if (TEST_BIT (gd->names_to_rename, def_uid))
01610 {
01611 set_def_block (def, bb, false, true);
01612 bitmap_set_bit (kills, def_uid);
01613 }
01614 }
01615 }
01616
01617
01618
01619
01620
01621 static void
01622 ssa_mark_def_sites_initialize_block (struct dom_walk_data *walk_data,
01623 basic_block bb)
01624 {
01625 struct mark_def_sites_global_data *gd = walk_data->global_data;
01626 bitmap kills = gd->kills;
01627 tree phi, def;
01628 unsigned def_uid;
01629
01630 bitmap_clear (kills);
01631
01632 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
01633 {
01634 def = PHI_RESULT (phi);
01635 def_uid = SSA_NAME_VERSION (def);
01636
01637 if (!TEST_BIT (gd->names_to_rename, def_uid))
01638 continue;
01639
01640 set_def_block (def, bb, true, true);
01641 bitmap_set_bit (kills, def_uid);
01642 }
01643 }
01644
01645
01646
01647 static void
01648 ssa_mark_phi_uses (struct dom_walk_data *walk_data, basic_block bb)
01649 {
01650 struct mark_def_sites_global_data *gd = walk_data->global_data;
01651 bitmap kills = gd->kills;
01652 edge e;
01653 tree phi, use;
01654 unsigned uid;
01655 edge_iterator ei;
01656
01657 FOR_EACH_EDGE (e, ei, bb->succs)
01658 {
01659 if (e->dest == EXIT_BLOCK_PTR)
01660 continue;
01661
01662 for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
01663 {
01664 use = PHI_ARG_DEF_FROM_EDGE (phi, e);
01665 if (TREE_CODE (use) != SSA_NAME)
01666 continue;
01667
01668 uid = SSA_NAME_VERSION (use);
01669
01670 if (TEST_BIT (gd->names_to_rename, uid)
01671 && !bitmap_bit_p (kills, uid))
01672 set_livein_block (use, bb);
01673 }
01674 }
01675 }
01676
01677
01678
01679
01680
01681 void
01682 rewrite_ssa_into_ssa (void)
01683 {
01684 bitmap *dfs;
01685 basic_block bb;
01686 struct dom_walk_data walk_data;
01687 struct mark_def_sites_global_data mark_def_sites_global_data;
01688 unsigned i;
01689 sbitmap snames_to_rename;
01690 bitmap to_rename;
01691 bitmap_iterator bi;
01692
01693 if (!any_marked_for_rewrite_p ())
01694 return;
01695 to_rename = marked_ssa_names ();
01696
01697 timevar_push (TV_TREE_SSA_OTHER);
01698
01699
01700 def_blocks = htab_create (num_ssa_names,
01701 def_blocks_hash, def_blocks_eq, def_blocks_free);
01702
01703
01704
01705
01706 dfs = (bitmap *) xmalloc (last_basic_block * sizeof (bitmap *));
01707 FOR_EACH_BB (bb)
01708 dfs[bb->index] = BITMAP_ALLOC (NULL);
01709
01710
01711 calculate_dominance_info (CDI_DOMINATORS);
01712
01713
01714 compute_dominance_frontiers (dfs);
01715
01716
01717
01718 walk_data.walk_stmts_backward = false;
01719 walk_data.dom_direction = CDI_DOMINATORS;
01720 walk_data.initialize_block_local_data = NULL;
01721 walk_data.before_dom_children_before_stmts
01722 = ssa_mark_def_sites_initialize_block;
01723 walk_data.before_dom_children_walk_stmts = ssa_mark_def_sites;
01724 walk_data.before_dom_children_after_stmts = ssa_mark_phi_uses;
01725 walk_data.after_dom_children_before_stmts = NULL;
01726 walk_data.after_dom_children_walk_stmts = NULL;
01727 walk_data.after_dom_children_after_stmts = NULL;
01728
01729 snames_to_rename = sbitmap_alloc (num_ssa_names);
01730 sbitmap_zero (snames_to_rename);
01731 EXECUTE_IF_SET_IN_BITMAP (to_rename, 0, i, bi)
01732 {
01733 SET_BIT (snames_to_rename, i);
01734 set_current_def (ssa_name (i), NULL_TREE);
01735 }
01736
01737 mark_def_sites_global_data.kills = BITMAP_ALLOC (NULL);
01738 mark_def_sites_global_data.names_to_rename = snames_to_rename;
01739 walk_data.global_data = &mark_def_sites_global_data;
01740
01741 block_defs_stack = VEC_alloc (tree_on_heap, 10);
01742
01743
01744 walk_data.block_local_data_size = 0;
01745
01746
01747 init_walk_dominator_tree (&walk_data);
01748
01749
01750 walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
01751
01752
01753 fini_walk_dominator_tree (&walk_data);
01754
01755
01756 BITMAP_FREE (mark_def_sites_global_data.kills);
01757
01758
01759 insert_phi_nodes (dfs, to_rename);
01760
01761
01762 timevar_push (TV_TREE_SSA_REWRITE_BLOCKS);
01763
01764
01765 walk_data.walk_stmts_backward = false;
01766 walk_data.dom_direction = CDI_DOMINATORS;
01767 walk_data.initialize_block_local_data = NULL;
01768 walk_data.before_dom_children_before_stmts = ssa_rewrite_initialize_block;
01769 walk_data.before_dom_children_walk_stmts = ssa_rewrite_stmt;
01770 walk_data.before_dom_children_after_stmts = ssa_rewrite_phi_arguments;
01771 walk_data.after_dom_children_before_stmts = NULL;
01772 walk_data.after_dom_children_walk_stmts = NULL;
01773 walk_data.after_dom_children_after_stmts = ssa_rewrite_finalize_block;
01774 walk_data.global_data = snames_to_rename;
01775 walk_data.block_local_data_size = 0;
01776
01777
01778 init_walk_dominator_tree (&walk_data);
01779
01780
01781
01782 walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
01783
01784
01785 fini_walk_dominator_tree (&walk_data);
01786
01787 unmark_all_for_rewrite ();
01788
01789 EXECUTE_IF_SET_IN_BITMAP (to_rename, 0, i, bi)
01790 {
01791
01792
01793 if (SSA_NAME_AUX (ssa_name (i)))
01794 free (SSA_NAME_AUX (ssa_name (i)));
01795
01796 release_ssa_name (ssa_name (i));
01797 }
01798
01799 sbitmap_free (snames_to_rename);
01800
01801 timevar_pop (TV_TREE_SSA_REWRITE_BLOCKS);
01802
01803
01804 if (dump_file && (dump_flags & TDF_STATS))
01805 {
01806 dump_dfa_stats (dump_file);
01807 dump_tree_ssa_stats (dump_file);
01808 }
01809
01810
01811 FOR_EACH_BB (bb)
01812 BITMAP_FREE (dfs[bb->index]);
01813 free (dfs);
01814
01815 htab_delete (def_blocks);
01816
01817 #ifdef ENABLE_CHECKING
01818 for (i = 1; i < num_ssa_names; i++)
01819 {
01820 tree name = ssa_name (i);
01821 if (!name)
01822 continue;
01823
01824 gcc_assert (SSA_NAME_AUX (name) == NULL);
01825 }
01826 #endif
01827
01828 BITMAP_FREE (to_rename);
01829
01830 VEC_free (tree_on_heap, block_defs_stack);
01831 block_defs_stack = NULL;
01832 timevar_pop (TV_TREE_SSA_OTHER);
01833 }