00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #ifdef USE_PCH
00066 #include "opt_pch.h"
00067 #endif // USE_PCH
00068 #pragma hdrstop
00069
00070
00071 #ifdef _KEEP_RCS_ID
00072 #define opt_ssa_CXX "opt_ssa.cxx"
00073 static char *rcs_id = opt_ssa_CXX"$Revision: 1.24 $";
00074 #endif
00075
00076 #include "defs.h"
00077 #include "config.h"
00078 #include "errors.h"
00079 #include "erglob.h"
00080 #include "glob.h"
00081 #include "bb_node_set.h"
00082 #include "tracing.h"
00083
00084 #include "opt_defs.h"
00085 #include "opt_config.h"
00086 #include "opt_htable.h"
00087 #include "opt_util.h"
00088 #include "opt_ssa.h"
00089 #include "opt_mu_chi.h"
00090 #include "opt_wn.h"
00091 #include "opt_prop.h"
00092 #include "wn.h"
00093
00094
00095 #ifdef Is_True_On
00096 static BOOL verify_defs_bb(OPT_STAB *opt_stab)
00097 {
00098 AUX_ID idx;
00099 AUX_STAB_ITER aux_stab_iter(opt_stab);
00100
00101 FOR_ALL_NODE (idx, aux_stab_iter, Init()) {
00102 if (opt_stab->Aux_stab_entry(idx)->Def_bbs() != NULL)
00103 return FALSE;
00104 }
00105 return TRUE;
00106 }
00107 #endif
00108
00109
00110
00111 void SSA::Collect_defs_bb(MEM_POOL *pool)
00112 {
00113 WN *wn;
00114 BB_NODE *bb;
00115 CFG_ITER cfg_iter;
00116 STMT_ITER stmt_iter;
00117
00118 Is_True(verify_defs_bb(Opt_stab()), ("defs_bb not initialized."));
00119
00120 FOR_ALL_ELEM (bb, cfg_iter, Init(_cfg)) {
00121 FOR_ALL_ELEM (wn, stmt_iter, Init(bb->Firststmt(), bb->Laststmt())) {
00122
00123 if (WN_has_chi(wn, Cfg()->Rgn_level()) ||
00124 OPERATOR_is_scalar_store (WN_operator(wn))) {
00125 CHI_LIST_ITER chi_iter;
00126 CHI_NODE *cnode;
00127 CHI_LIST *chi_list = Opt_stab()->Get_generic_chi_list(wn);
00128 if (chi_list) {
00129 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
00130 Opt_stab()->Aux_stab_entry(cnode->Aux_id())->Prepend_def_bbs(bb, pool);
00131 }
00132 }
00133 }
00134
00135 if (OPERATOR_is_scalar_store (WN_operator(wn)))
00136 Opt_stab()->Aux_stab_entry(WN_aux(wn))->Prepend_def_bbs(bb, pool);
00137 }
00138 }
00139 }
00140
00141
00142
00143
00144
00145
00146 void SSA::Place_phi_node(MEM_POOL *def_bb_pool)
00147 {
00148 AUX_STAB_ITER opt_stab_iter(Opt_stab());
00149 BB_LIST_ITER bb_list_iter;
00150 BB_LIST_CONTAINER worklist;
00151 BB_NODE_SET_ITER bns_iter;
00152 BB_NODE *bbx, *bby, *mergebb;
00153 INT32 var;
00154 BS_ELT bbs = Cfg()->Last_bb_id()+1;
00155 MEM_POOL bbset_pool;
00156
00157 OPT_POOL_Initialize(&bbset_pool, "SSA bb set pool", FALSE, SSA_DUMP_FLAG);
00158 OPT_POOL_Push(&bbset_pool, SSA_DUMP_FLAG);
00159
00160 BB_NODE_SET inserted(bbs, Cfg(), &bbset_pool, BBNS_EMPTY);
00161 BB_NODE_SET everonlist(bbs, Cfg(), &bbset_pool, BBNS_EMPTY);
00162 BB_NODE_SET loopstart(bbs, Cfg(), &bbset_pool, BBNS_EMPTY);
00163 BB_NODE_SET do_not_insert_ident(bbs, Cfg(), &bbset_pool, BBNS_EMPTY);
00164
00165
00166 BB_NODE *bb;
00167 CFG_ITER cfg_iter;
00168 FOR_ALL_ELEM(bb, cfg_iter, Init(Cfg())) {
00169 if (bb->Loop() &&
00170 bb->Loop()->Well_formed() &&
00171 bb->Loop()->Header() == bb &&
00172 bb->Loop()->Merge() != NULL) {
00173 BB_NODE *startbb = bb;
00174 loopstart.Union1D(startbb);
00175
00176
00177
00178 if ( !WOPT_Enable_IVR_Outermost_Loop_Parallel_Region ) {
00179 BB_LOOP *loop = bb->Loop();
00180 if ( loop != NULL &&
00181 Cfg()->Is_outermost_loop_in_parallel_region(loop,WN_PRAGMA_PDO_BEGIN) )
00182 {
00183 do_not_insert_ident.Union1D(startbb);
00184 }
00185 }
00186 }
00187 }
00188
00189 AUX_ID default_vsym = Opt_stab()->Default_vsym();
00190
00191
00192 FOR_ALL_NODE(var, opt_stab_iter, Init()) {
00193
00194 if (var == default_vsym) continue;
00195
00196 AUX_STAB_ENTRY *psym = Opt_stab()->Aux_stab_entry(var);
00197
00198
00199 if (psym->Is_volatile()) continue;
00200
00201 inserted.ClearD();
00202 everonlist.ClearD();
00203 worklist.Clear();
00204
00205
00206 FOR_ALL_ELEM (bbx, bb_list_iter, Init(psym->Def_bbs())) {
00207 if (everonlist.MemberP(bbx) == FALSE) {
00208 everonlist.Union1D(bbx);
00209 worklist.Append(bbx, &bbset_pool);
00210 }
00211 }
00212
00213
00214 while (bbx = worklist.Remove_head(&bbset_pool)) {
00215
00216 FOR_ALL_ELEM (bby, bns_iter, Init(bbx->Dom_frontier())) {
00217 if (inserted.MemberP(bby) == FALSE) {
00218 bby->Phi_list()->New_phi_node(var, mem_pool, bby);
00219 inserted.Union1D(bby);
00220 if (everonlist.MemberP(bby) == FALSE) {
00221 everonlist.Union1D(bby);
00222 worklist.Append(bby, &bbset_pool);
00223 }
00224
00225 if (loopstart.MemberP(bby) &&
00226 !do_not_insert_ident.MemberP(bby) ) {
00227
00228
00229
00230
00231
00232
00233
00234
00235 if (bby->Loop()->Exit_early()) {
00236 mergebb = bby->Loop()->Merge();
00237 if (everonlist.MemberP(mergebb) == FALSE) {
00238 everonlist.Union1D(mergebb);
00239 worklist.Append(mergebb, &bbset_pool);
00240 }
00241 }
00242
00243 mergebb = Insert_identity_assignment_4_loopexit(bby, var, def_bb_pool);
00244 if ( mergebb != NULL ) {
00245 if (everonlist.MemberP(mergebb) == FALSE) {
00246 everonlist.Union1D(mergebb);
00247 worklist.Append(mergebb, &bbset_pool);
00248 }
00249 }
00250 }
00251 }
00252 }
00253 }
00254 }
00255
00256
00257 {
00258 AUX_STAB_ENTRY *psym = Opt_stab()->Aux_stab_entry(default_vsym);
00259 inserted.ClearD();
00260 everonlist.ClearD();
00261 worklist.Clear();
00262
00263
00264 FOR_ALL_ELEM (bbx, bb_list_iter, Init(psym->Def_bbs())) {
00265 if (everonlist.MemberP(bbx) == FALSE) {
00266 everonlist.Union1D(bbx);
00267 worklist.Append(bbx, &bbset_pool);
00268 }
00269 }
00270
00271
00272 while (bbx = worklist.Remove_head(&bbset_pool)) {
00273
00274 FOR_ALL_ELEM (bby, bns_iter, Init(bbx->Dom_frontier())) {
00275 if (inserted.MemberP(bby) == FALSE) {
00276 bby->Phi_list()->New_phi_node(default_vsym, mem_pool, bby);
00277 inserted.Union1D(bby);
00278 if (everonlist.MemberP(bby) == FALSE) {
00279 everonlist.Union1D(bby);
00280 worklist.Append(bby, &bbset_pool);
00281 }
00282 if (loopstart.MemberP(bby) &&
00283 !do_not_insert_ident.MemberP(bby) ) {
00284 if (bby->Loop()->Exit_early()) {
00285 mergebb = bby->Loop()->Merge();
00286 if (everonlist.MemberP(mergebb) == FALSE) {
00287 everonlist.Union1D(mergebb);
00288 worklist.Append(mergebb, &bbset_pool);
00289 }
00290 }
00291 }
00292 }
00293 }
00294 }
00295 }
00296
00297 OPT_POOL_Pop(&bbset_pool, SSA_DUMP_FLAG);
00298 OPT_POOL_Delete(&bbset_pool, SSA_DUMP_FLAG);
00299 }
00300
00301
00302
00303
00304
00305
00306 BB_NODE *
00307 SSA::Insert_identity_assignment_4_loopexit(BB_NODE *start, AUX_ID aux_id, MEM_POOL *def_bb_pool)
00308 {
00309 if (!WOPT_Enable_IVR) return NULL;
00310
00311 AUX_STAB_ENTRY *sym = Opt_stab()->Aux_stab_entry(aux_id);
00312 ST *st = sym->St();
00313 INT32 mtype_class = sym->Mclass();
00314
00315
00316 if (sym->Is_real_var() &&
00317 mtype_class != MTYPE_UNKNOWN &&
00318 mtype_class != MTYPE_V &&
00319 !Opt_stab()->Dedicated(aux_id) &&
00320 !sym->Is_flag_const_init())
00321 {
00322 INT32 size = sym->Byte_size();
00323
00324
00325
00326 if ((mtype_class == MTYPE_CLASS_INTEGER) && size <= 2) {
00327 sym->Set_dont_replace_iv();
00328 return NULL;
00329 }
00330
00331
00332 if ( MTYPE_is_float(mtype_class) &&
00333 WOPT_Enable_LNO_Copy_Propagate ) {
00334 sym->Set_dont_replace_iv();
00335 return NULL;
00336 }
00337
00338
00339
00340 TY_IDX ty = Identity_assignment_type( sym, Htable()->Phase());
00341 if ( ty == TY_IDX_ZERO ) {
00342 sym->Set_dont_replace_iv();
00343 return NULL;
00344 }
00345
00346 BB_NODE *merge_bb = start->Loop()->Merge();
00347
00348 WN *copy = Create_identity_assignment(sym, aux_id, ty);
00349
00350 if (!sym->Points_to()->No_alias())
00351 Opt_stab()->Compute_FFA_for_copy( copy, merge_bb, TRUE );
00352
00353 merge_bb->Prepend_wn_after_labels(copy);
00354 return merge_bb;
00355 }
00356
00357 sym->Set_dont_replace_iv();
00358 return NULL;
00359 }
00360
00361
00362
00363 void
00364 SSA::Rename_rhs(OPT_STAB *opt_stab, WN *wn)
00365 {
00366 OPCODE opc = WN_opcode(wn);
00367 OPERATOR opr = OPCODE_operator(opc);
00368 VER_ID du;
00369
00370 if (OPCODE_has_aux(opc)) {
00371 if (OPERATOR_is_scalar_load (opr)) {
00372 if ( opt_stab->Is_volatile(WN_aux(wn)) ) {
00373
00374 opt_stab->Gen_name(WN_aux(wn));
00375
00376 du = opt_stab->Stack(WN_aux(wn))->Pop();
00377
00378
00379 opt_stab->Ver_stab_entry(du)->Set_type(ENTRY_STMT);
00380 }
00381 else {
00382 du = opt_stab->Get_name(WN_aux(wn));
00383 }
00384 WN_set_ver(wn, du);
00385 }
00386 else if (OPERATOR_is_scalar_store (opr)) {
00387 du = opt_stab->Get_name(WN_aux(wn));
00388 WN_set_ver(wn, du);
00389 }
00390 }
00391
00392 if (WN_has_mu(wn, Cfg()->Rgn_level())) {
00393 OCC_TAB_ENTRY *occ = opt_stab->Get_occ(wn);
00394 if (occ->Is_stmt()) {
00395 MU_LIST *mu_list = occ->Stmt_mu_list();
00396 if (mu_list) {
00397 MU_LIST_ITER mu_iter;
00398 MU_NODE *mnode;
00399 FOR_ALL_NODE( mnode, mu_iter, Init(mu_list)) {
00400 VER_ID ver = opt_stab->Get_name(mnode->Aux_id());
00401 mnode->Set_opnd(ver);
00402 }
00403 }
00404 } else {
00405 MU_NODE *mnode = occ->Mem_mu_node();
00406 VER_ID ver = opt_stab->Get_name(mnode->Aux_id());
00407 mnode->Set_opnd(ver);
00408 }
00409 }
00410
00411 for (INT32 i = 0; i < WN_kid_count(wn); i++)
00412 Rename_rhs(opt_stab, WN_kid(wn,i));
00413 }
00414
00415
00416
00417 void SSA::Rename(CFG *cfg, OPT_STAB *opt_stab, BB_NODE *bb)
00418 {
00419 PHI_LIST_ITER phi_iter;
00420 PHI_NODE *phi;
00421 BB_LIST_ITER bb_iter;
00422 STMT_ITER stmt_iter;
00423 INT32 pos;
00424 AUX_ID v;
00425 BB_NODE *succ, *dom_bb;
00426 BB_LIST_ITER dom_bb_iter;
00427 WN *wn;
00428 AUX_ID var;
00429 VER_ID du;
00430
00431
00432 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
00433 opt_stab->Gen_name_phi(phi);
00434 }
00435
00436
00437 FOR_ALL_ELEM (wn, stmt_iter, Init(bb->Firststmt(), bb->Laststmt())) {
00438
00439 OPCODE opc = WN_opcode(wn);
00440 OPERATOR opr = OPCODE_operator(opc);
00441 BOOL process_only_mu_chi = FALSE;
00442
00443 Is_True( opr != OPR_BLOCK, ("cannot rename a block of statements."));
00444
00445
00446 if (opc == OPC_REGION) {
00447 RID *rid = REGION_get_rid(wn);
00448 Is_True(rid != NULL,("SSA::Rename, NULL rid"));
00449 if (RID_level(rid) >= opt_stab->Rgn_level())
00450 process_only_mu_chi = TRUE;
00451 }
00452
00453 if (!process_only_mu_chi) {
00454
00455 if ( opr == OPR_COMPGOTO ) {
00456
00457 Rename_rhs(opt_stab, WN_kid0(wn));
00458 }
00459
00460 else if ( ! OPCODE_is_black_box( opc ) ) {
00461 for (INT32 i = 0; i < WN_kid_count(wn); i++)
00462 Rename_rhs(opt_stab, WN_kid(wn,i));
00463 }
00464 }
00465
00466
00467 if (WN_has_mu(wn, Cfg()->Rgn_level())) {
00468 MU_LIST *mu_list = opt_stab->Get_stmt_mu_list(wn);
00469 if (mu_list) {
00470 MU_LIST_ITER mu_iter;
00471 MU_NODE *mnode;
00472 FOR_ALL_NODE( mnode, mu_iter, Init(mu_list)) {
00473 VER_ID ver = opt_stab->Get_name(mnode->Aux_id());
00474 mnode->Set_opnd(ver);
00475 }
00476 }
00477 }
00478
00479
00480 if (WN_has_chi(wn, Cfg()->Rgn_level())) {
00481 CHI_LIST *chi_list = opt_stab->Get_generic_chi_list(wn);
00482 if (chi_list) {
00483 CHI_LIST_ITER chi_iter;
00484 CHI_NODE *cnode;
00485 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
00486 VER_ID ver = opt_stab->Get_name(cnode->Aux_id());
00487 cnode->Set_opnd(ver);
00488 opt_stab->Gen_name_chi(cnode, wn);
00489 }
00490 }
00491 }
00492
00493
00494 if (!process_only_mu_chi && OPERATOR_is_scalar_store (opr)) {
00495 opt_stab->Gen_name(WN_aux(wn));
00496 }
00497
00498 }
00499
00500 FOR_ALL_ELEM (succ, bb_iter, Init(bb->Succ())) {
00501 pos = succ->Pred()->Pos(bb);
00502 FOR_ALL_ELEM (phi, phi_iter, Init(succ->Phi_list())) {
00503 v = phi->Aux_id();
00504 phi->Set_opnd(pos, opt_stab->Stack(v)->Top());
00505 }
00506 }
00507
00508 FOR_ALL_ELEM (dom_bb, dom_bb_iter, Init(bb->Dom_bbs())) {
00509 Rename(cfg, opt_stab, dom_bb);
00510 }
00511
00512
00513
00514
00515 FOR_ALL_ELEM_REVERSE (wn, stmt_iter, Init(bb->Firststmt(), bb->Laststmt())) {
00516
00517 OPERATOR opr = WN_operator(wn);
00518
00519
00520 if (WN_has_chi(wn, Cfg()->Rgn_level())) {
00521 CHI_LIST *chi_list = opt_stab->Get_generic_chi_list(wn);
00522 if (chi_list) {
00523 CHI_LIST_ITER chi_iter;
00524 CHI_NODE *cnode;
00525 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
00526 var = cnode->Aux_id();
00527 du = opt_stab->Stack(var)->Pop();
00528 opt_stab->Enter_du(du, cnode, bb);
00529 }
00530 }
00531 }
00532
00533
00534 if (OPERATOR_is_scalar_store (opr)) {
00535 var = WN_aux(wn);
00536 du = opt_stab->Stack(var)->Pop();
00537 opt_stab->Enter_du(du, wn, bb);
00538 WN_set_ver(wn, du);
00539 }
00540 }
00541
00542 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
00543 du = opt_stab->Stack(phi->Aux_id())->Pop();
00544 opt_stab->Enter_du(du, phi, bb);
00545 }
00546 }
00547
00548
00549 #ifdef Is_True_On
00550
00551 static BOOL verify_stack(OPT_STAB *opt_stab)
00552 {
00553 AUX_ID idx, v;
00554 AUX_STAB_ITER aux_stab_iter(opt_stab);
00555
00556 FOR_ALL_NODE (idx, aux_stab_iter, Init()) {
00557 AUX_STAB_ENTRY *psym = opt_stab->Aux_stab_entry(idx);
00558 if (psym->Is_real_var() || psym->Is_virtual()) {
00559 v = opt_stab->Ver_stab_entry(opt_stab->Get_name(idx))->Version();
00560 FmtAssert(v == 1, ("Verify_stack: stack for var%d is not empty %d\n",
00561 idx, v));
00562 }
00563 }
00564 return TRUE;
00565 }
00566 #endif
00567
00568
00569
00570 void SSA::Construct(CODEMAP *htable, CFG *cfg, OPT_STAB *opt_stab)
00571 {
00572 BB_NODE *bb;
00573 CFG_ITER cfg_iter;
00574 AUX_ID var;
00575 VER_ID du;
00576 AUX_STAB_ITER opt_stab_iter(opt_stab);
00577
00578 OPT_POOL_Push(loc_pool, SSA_DUMP_FLAG);
00579
00580 _cfg = cfg;
00581 _opt_stab = opt_stab;
00582 _htable = htable;
00583
00584 MEM_POOL defs_bb_pool;
00585 OPT_POOL_Initialize(&defs_bb_pool, "SSA defs bb pool", FALSE, SSA_DUMP_FLAG);
00586 OPT_POOL_Push(&defs_bb_pool, SSA_DUMP_FLAG);
00587
00588 Opt_stab()->Create_entry_chi();
00589
00590
00591 Collect_defs_bb(&defs_bb_pool);
00592
00593 if ( Get_Trace(TP_GLOBOPT, SSA_DUMP_FLAG)) {
00594 opt_stab->Print(TFile);
00595 }
00596
00597
00598 FOR_ALL_ELEM (bb, cfg_iter, Init(cfg))
00599 bb->Set_phi_list(CXX_NEW(PHI_LIST(bb), mem_pool));
00600
00601
00602 Place_phi_node(&defs_bb_pool);
00603
00604 OPT_POOL_Pop(&defs_bb_pool, SSA_DUMP_FLAG);
00605 OPT_POOL_Delete(&defs_bb_pool, SSA_DUMP_FLAG);
00606
00607 MEM_POOL rename_pool;
00608 OPT_POOL_Initialize(&rename_pool, "SSA rename pool", FALSE, SSA_DUMP_FLAG);
00609 OPT_POOL_Push(&rename_pool, SSA_DUMP_FLAG);
00610
00611
00612
00613
00614 FOR_ALL_NODE(var, opt_stab_iter, Init()) {
00615 AUX_STAB_ENTRY *psym = opt_stab->Aux_stab_entry(var);
00616 if (psym->Is_real_var() || psym->Is_virtual()) {
00617 psym->Clear_version();
00618 psym->Set_stack(CXX_NEW(STACK<AUX_ID>(&rename_pool), &rename_pool));
00619 du = opt_stab->Gen_name(var);
00620 opt_stab->Enter_du(du);
00621 }
00622 }
00623
00624
00625 Rename(cfg, opt_stab, cfg->Entry_bb());
00626
00627
00628 Is_True(verify_stack(Opt_stab()), ("ssa: stack is non-empty"));
00629
00630 OPT_POOL_Pop(&rename_pool, SSA_DUMP_FLAG);
00631 OPT_POOL_Delete(&rename_pool, SSA_DUMP_FLAG);
00632
00633 if ( Get_Trace(TP_GLOBOPT, SSA_DUMP_FLAG)) {
00634
00635 fprintf(TFile, "PHI INSERTION: \n");
00636 FOR_ALL_ELEM (bb, cfg_iter, Init(cfg))
00637 if (bb->Phi_list()->Len() > 0) {
00638 fprintf(TFile, "BB%d: \n", bb->Id());
00639 bb->Phi_list()->PRINT(TFile);
00640 }
00641 }
00642 }
00643
00644
00645
00646 void
00647 SSA::Pointer_Alias_Analysis(void)
00648 {
00649 if (WOPT_Enable_FSA) {
00650 BB_NODE *bb;
00651 STMT_ITER stmt_iter;
00652 WN *wn;
00653 CFG_ITER cfg_iter;
00654
00655 Opt_stab()->Compute_FSA();
00656
00657
00658
00659 FOR_ALL_ELEM (bb, cfg_iter, Init(Cfg())) {
00660 PHI_NODE *phi;
00661 PHI_LIST_ITER phi_iter;
00662 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
00663 for (INT i = 0; i < phi->Size(); i++) {
00664 VER_ID idx = phi->Opnd(i);
00665 if (Opt_stab()->Ver_stab_entry(idx)->Synonym()) {
00666 VER_ID s = idx;
00667 while (s != 0 && Opt_stab()->Ver_stab_entry(s)->Synonym())
00668 s = Opt_stab()->Ver_stab_entry(s)->Synonym();
00669 phi->Set_opnd(i,s);
00670 }
00671 }
00672 }
00673 FOR_ALL_ELEM (wn, stmt_iter, Init(bb->Firststmt(), bb->Laststmt()))
00674 Opt_stab()->Remap_ver_synonym(wn);
00675 }
00676 if ( Get_Trace(TP_GLOBOPT, ALIAS_DUMP_FLAG)) {
00677 fprintf( TFile, "%sPOINTS_TO after pointer analysis\n%s", DBar, DBar );
00678 _opt_stab->Print_alias_info(TFile);
00679
00680 fprintf( TFile, "%sOcc table after flow sensitive alias analysis\n%s", DBar, DBar );
00681 #ifdef KEY
00682 FOR_ALL_ELEM (bb, cfg_iter, Init(Cfg())) {
00683 FOR_ALL_ELEM (wn, stmt_iter, Init(bb->Firststmt(), bb->Laststmt()))
00684 _opt_stab->Print_occ_tab(TFile,wn);
00685 }
00686 #endif
00687
00688 }
00689 }
00690 }
00691
00692
00693
00694
00695
00696 void
00697 SSA::Find_zero_versions(void)
00698 {
00699 VER_STAB_ENTRY *vse;
00700 BB_LIST_ITER bb_list_iter;
00701 BB_NODE *bbpred;
00702 INT32 pos;
00703 PHI_NODE *ph;
00704 VER_STAB_ENTRY *opnd;
00705 BOOL phi_opnds_all_real_use;
00706
00707 OPT_POOL_Push(loc_pool, SSA_DUMP_FLAG);
00708
00709
00710 VER_STAB_ITER ver_stab_iter(Opt_stab()->Ver_stab());
00711 AUX_ID vid;
00712 FOR_ALL_NODE(vid, ver_stab_iter, Init()) {
00713 vse = Opt_stab()->Ver_stab_entry(vid);
00714 if (! vse->Any_use()) {
00715 vse->Set_Zero_vers();
00716 continue;
00717 }
00718 if (vse->Real_use()) continue;
00719
00720
00721 if (Opt_stab()->Special_vsym(vse->Aux_id()))
00722 continue;
00723 if (vse->Type() == CHI_STMT) {
00724 if (WN_operator(vse->Chi_wn()) != OPR_OPT_CHI)
00725 vse->Set_Zero_vers();
00726 continue;
00727 }
00728
00729 Is_True(vse->Type() == PHI_STMT,
00730 ("SSA::Find_zero_versions: version not defined by phi"));
00731
00732 phi_opnds_all_real_use = TRUE;
00733 pos = 0;
00734 ph = vse->Phi();
00735 FOR_ALL_ELEM(bbpred, bb_list_iter, Init(ph->Bb()->Pred())) {
00736 opnd = Opt_stab()->Ver_stab_entry(ph->Opnd(pos));
00737 if (opnd->Zero_vers()) {
00738 vse->Set_Zero_vers();
00739 break;
00740 }
00741 if (! opnd->Real_use())
00742 phi_opnds_all_real_use = FALSE;
00743 pos++;
00744 }
00745 if (vse->Zero_vers()) continue;
00746 if (phi_opnds_all_real_use)
00747 vse->Set_Real_use();
00748 else {
00749 VER_STAB_LIST_NODE *nz = CXX_NEW(VER_STAB_LIST_NODE(vse), loc_pool);
00750 AUX_STAB_ENTRY *sym = Opt_stab()->Aux_stab_entry(vse->Aux_id());
00751 sym->Set_nonzerophis(sym->Nonzerophis()->Prepend(nz));
00752 }
00753 }
00754
00755
00756 AUX_ID i;
00757 AUX_STAB_ITER aux_stab_iter(Opt_stab());
00758 FOR_ALL_NODE(i, aux_stab_iter, Init()) {
00759 AUX_STAB_ENTRY *v = Opt_stab()->Aux_stab_entry(i);
00760
00761 BOOL changed;
00762 do {
00763 VER_STAB_LIST_NODE *prev = NULL;
00764 VER_STAB_LIST_NODE *cur = v->Nonzerophis();
00765 changed = FALSE;
00766
00767 while (cur != NULL) {
00768 vse = cur->Vers();
00769
00770
00771 phi_opnds_all_real_use = TRUE;
00772 pos = 0;
00773 ph = vse->Phi();
00774 FOR_ALL_ELEM(bbpred, bb_list_iter, Init(ph->Bb()->Pred())) {
00775 opnd = Opt_stab()->Ver_stab_entry(ph->Opnd(pos));
00776 if (opnd->Zero_vers()) {
00777 vse->Set_Zero_vers();
00778
00779 if (prev != NULL)
00780 prev->Set_Next(cur->Next());
00781 else v->Set_nonzerophis(cur->Next());
00782 cur = cur->Next();
00783 changed = TRUE;
00784 break;
00785 }
00786 if (! opnd->Real_use())
00787 phi_opnds_all_real_use = FALSE;
00788 pos++;
00789 }
00790 if (vse->Zero_vers()) continue;
00791 if (phi_opnds_all_real_use) {
00792 vse->Set_Real_use();
00793
00794 if (prev != NULL)
00795 prev->Set_Next(cur->Next());
00796 else v->Set_nonzerophis(cur->Next());
00797 cur = cur->Next();
00798 changed = TRUE;
00799 break;
00800 }
00801
00802 prev = cur;
00803 cur = cur->Next();
00804 }
00805 } while (changed);
00806
00807 v->Set_cr_list(NULL);
00808 }
00809 #ifdef KEY
00810 if ( Get_Trace(TP_GLOBOPT, SSA_DUMP_FLAG)) {
00811 CFG_ITER cfg_iter;
00812 BB_NODE *bb;
00813 fprintf(TFile, "ZERO VERSIONING: \n");
00814 FOR_ALL_ELEM (bb, cfg_iter, Init(_cfg)){
00815 if (bb->Phi_list()->Len() > 0) {
00816 fprintf(TFile, "BB%d: \n", bb->Id());
00817 bb->Phi_list()->PRINT(TFile);
00818 }
00819 WN *wn;
00820 STMT_ITER stmt_iter;
00821 FOR_ALL_ELEM (wn, stmt_iter, Init(bb->Firststmt(), bb->Laststmt())) {
00822 fdump_tree_no_st(TFile, wn);
00823 Print_ssa_ver_for_wn(wn);
00824 if (WN_has_mu(wn, _cfg->Rgn_level())) {
00825 MU_LIST *mu_list = Opt_stab()->Get_stmt_mu_list(wn);
00826 if (mu_list)
00827 mu_list->Print(TFile);
00828 }
00829 if (WN_has_chi(wn, _cfg->Rgn_level())) {
00830 CHI_LIST *chi_list = Opt_stab()->Get_generic_chi_list(wn);
00831 if (chi_list)
00832 chi_list->Print(TFile);
00833 }
00834 }
00835 }
00836 }
00837 #endif
00838 OPT_POOL_Pop(loc_pool, SSA_DUMP_FLAG);
00839 }
00840 #ifdef KEY
00841 void SSA::Print_ssa_ver_for_wn(WN* wn)
00842 {
00843 OPCODE opc = WN_opcode(wn);
00844 OPERATOR opr = OPCODE_operator(opc);
00845 if (WN_has_mu(wn, Cfg()->Rgn_level())) {
00846 OCC_TAB_ENTRY *occ = Opt_stab()->Get_occ(wn);
00847 if (occ && !occ->Is_stmt()) {
00848 fdump_tree_no_st(TFile,wn);
00849 MU_NODE *mnode = occ -> Mem_mu_node();
00850 mnode->Print(TFile);
00851 }
00852 }
00853 for (INT32 i = 0; i < WN_kid_count(wn); i++)
00854 Print_ssa_ver_for_wn(WN_kid(wn,i));
00855 }
00856 #endif
00857 void
00858 SSA::Create_CODEMAP(void)
00859 {
00860 _opt_stab->New_coderep(loc_pool);
00861 _cfg->Set_htable(Htable());
00862
00863 {
00864 extern BOOL Simp_Canonicalize;
00865 BOOL save_simp_canon = Simp_Canonicalize;
00866 COPYPROP copyprop(_htable, _opt_stab, _cfg, loc_pool);
00867 #ifdef TARG_NVISA
00868
00869
00870
00871
00872 if (Htable()->Phase() == PREOPT_PHASE)
00873 copyprop.Set_disabled();
00874 #endif
00875
00876
00877 Value_number(_htable, _opt_stab, _cfg->Entry_bb(), ©prop, _cfg->Exc());
00878 #ifdef Is_True_On
00879 _opt_stab->Check_stack();
00880 #endif
00881
00882 if ( Get_Trace(TP_GLOBOPT, CR_DUMP_FLAG)) {
00883 fprintf( TFile, "%sAfter SSA::Create_CODEMAP\n%s",
00884 DBar, DBar );
00885 _htable->Print(TFile);
00886 _cfg->Print(TFile);
00887 if (_opt_stab->Cr_sr_annot_mgr ())
00888 _opt_stab->Cr_sr_annot_mgr()->Print (TFile);
00889 }
00890
00891 Opt_tlog( "CODEMAP", 0, "%d iloadfolds, %d istorefolds",
00892 _htable->Num_iloadfolds(), _htable->Num_istorefolds() );
00893 Opt_tlog( "INPUTPROP", 0, "%d copy propagations",
00894 Htable()->Num_inputprops() );
00895 #ifdef TARG_NVISA
00896 if (Htable()->Phase() == PREOPT_PHASE)
00897 copyprop.Reset_disabled();
00898 #endif
00899 Simp_Canonicalize = save_simp_canon;
00900 }
00901
00902 Opt_stab()->Delete_ver_pool();
00903 OPT_POOL_Pop(loc_pool, SSA_DUMP_FLAG);
00904
00905 _htable->Init_var_phi_hash();
00906
00907
00908 if (WN_MEMOP_ANNOT_MGR::WN_mem_annot_mgr())
00909 WN_MEMOP_ANNOT_MGR::WN_mem_annot_mgr()->Invalidate ();
00910 }
00911
00912
00913
00914
00915
00916
00917 void
00918 PHI_NODE::Remove_opnd( INT32 i )
00919 {
00920 if ( size > 0 ) {
00921 Reset_OPND(i);
00922
00923 for ( INT32 n = i+1; n < size; n++ ) {
00924 Set_opnd( n-1, OPND(n) );
00925 }
00926 size -= 1;
00927 }
00928 }
00929
00930
00931
00932
00933 PHI_LIST::PHI_LIST(BB_NODE *bb)
00934 {
00935 in_degree = bb->Pred()->Len();
00936 }
00937
00938 PHI_LIST *
00939 PHI_LIST::Dup_phi_node(MEM_POOL *pool, BB_NODE *bb)
00940 {
00941 PHI_LIST *newp;
00942 PHI_NODE *phi, *p;
00943 PHI_LIST_ITER phi_iter;
00944
00945 newp = (CXX_NEW(PHI_LIST(bb), pool));
00946 FOR_ALL_ELEM ( phi, phi_iter, Init(bb->Phi_list()) ) {
00947 p = CXX_NEW(PHI_NODE(newp->In_degree(), pool, bb), pool);
00948 p->Set_aux_id(phi->Aux_id());
00949 p->Set_count(phi->Count());
00950 p->Set_result(phi->RESULT());
00951 p->Set_flags(phi->Flags());
00952 if (phi->Live())
00953 phi->RESULT()->Set_defphi(p);
00954 for (INT i = 0; i < newp->In_degree(); i++) {
00955 p->Set_opnd(i, phi->OPND(i));
00956 }
00957 newp->Append(p);
00958 }
00959 return newp;
00960 }
00961
00962
00963 PHI_LIST *
00964 PHI_LIST::Dup_phi_node(MEM_POOL *pool, BB_NODE *bb, INT pos)
00965 {
00966 PHI_LIST *newp;
00967 PHI_NODE *phi, *p;
00968 PHI_LIST_ITER phi_iter;
00969
00970 newp = (CXX_NEW(PHI_LIST(bb), pool));
00971 FOR_ALL_ELEM ( phi, phi_iter, Init(bb->Phi_list()) ) {
00972 p = CXX_NEW(PHI_NODE(newp->In_degree(), pool, bb), pool);
00973 p->Set_aux_id(phi->Aux_id());
00974 p->Set_count(phi->Count());
00975 p->Set_result(phi->RESULT());
00976 p->Set_flags(phi->Flags());
00977 if (phi->Live())
00978 phi->RESULT()->Set_defphi(p);
00979 for (INT i = 0; i < newp->In_degree()-1; i++) {
00980 p->Set_opnd(i, phi->OPND(i));
00981 }
00982 if (pos >= 0)
00983 p->Set_opnd(newp->In_degree()-1, phi->OPND(pos));
00984 newp->Append(p);
00985 }
00986 return newp;
00987 }
00988
00989
00990
00991
00992
00993 void
00994 PHI_LIST::Remove_opnd( INT32 i )
00995 {
00996 PHI_LIST_ITER phi_iter;
00997 PHI_NODE *phi;
00998
00999 FOR_ALL_ELEM ( phi, phi_iter, Init(this) ) {
01000 phi->Remove_opnd(i);
01001 }
01002
01003
01004 Set_in_degree( In_degree() - 1 );
01005 }
01006
01007
01008
01009
01010 CODEREP *
01011 SSA::Get_zero_version_CR(AUX_ID aux_id, OPT_STAB *opt_stab, VER_ID du)
01012 {
01013 CODEREP *retv;
01014
01015 if (du != 0) {
01016 retv = opt_stab->Du_coderep(du);
01017 if (retv) return retv;
01018 }
01019
01020 ST *st = opt_stab->St(aux_id);
01021 TY_IDX ty = TY_IDX_ZERO;
01022 if (opt_stab->Zero_cr(aux_id) == NULL) {
01023 if (st != NULL) ty = ST_type(st);
01024 MTYPE dtype, rtype;
01025 AUX_STAB_ENTRY *sym = opt_stab->Aux_stab_entry(aux_id);
01026
01027 if (sym->Mtype()==MTYPE_M || MTYPE_is_vector(sym->Mtype())
01028 #ifdef KEY
01029 || (sym->Mclass() & MTYPE_CLASS_VECTOR)
01030 #endif
01031 )
01032 rtype = sym->Mtype();
01033 else {
01034 rtype = Mtype_from_mtype_class_and_size(sym->Mclass(),
01035 sym->Byte_size());
01036 #ifdef KEY // bug 8186
01037 if (MTYPE_is_unsigned(sym->Mtype()))
01038 rtype = Mtype_TransferSign(MTYPE_U4, rtype);
01039 #endif
01040 }
01041
01042 dtype = rtype;
01043 if (rtype != MTYPE_UNKNOWN && rtype != MTYPE_M) {
01044 if (MTYPE_is_integral(rtype) &&
01045 sym->Byte_size() < (MTYPE_size_min(MTYPE_I4)/8)) {
01046 rtype = Mtype_from_mtype_class_and_size(sym->Mclass(),
01047 MTYPE_size_min(MTYPE_I4)/8);
01048 #ifdef KEY // bug 8186
01049 if (MTYPE_is_unsigned(sym->Mtype()))
01050 rtype = Mtype_TransferSign(MTYPE_U4, rtype);
01051 #endif
01052 }
01053 ty = MTYPE_To_TY(rtype);
01054 }
01055 CODEREP *cr = _htable->Add_def(aux_id, 0, NULL, rtype, dtype,
01056 opt_stab->St_ofst(aux_id), ty, 0, TRUE);
01057 cr->Set_flag(CF_MADEUP_TYPE);
01058 cr->Set_flag(CF_IS_ZERO_VERSION);
01059
01060 if( opt_stab->Is_volatile(aux_id) )
01061 cr->Set_var_volatile();
01062
01063 opt_stab->Set_zero_cr(aux_id, cr);
01064 }
01065
01066 retv = opt_stab->Zero_cr(aux_id);
01067
01068 if ( du != 0 ) {
01069 if ( opt_stab->Du_is_volatile(du) ) {
01070 retv->Set_var_volatile();
01071 }
01072 else {
01073
01074 opt_stab->Du_set_coderep(du, retv);
01075 }
01076 }
01077
01078 return retv;
01079 }
01080
01081
01082 CODEREP *
01083 SSA::Du2cr( CODEMAP *htable, OPT_STAB *opt_stab, VER_ID du,
01084 STMTREP *stmt)
01085 {
01086 VER_STAB_ENTRY *vse = opt_stab->Ver_stab_entry(du);
01087 CODEREP *cr = vse->Coderep();
01088 if (cr == NULL) {
01089 WN *ref_wn;
01090 MTYPE dtype, rtype;
01091 TY_IDX ty;
01092 if (vse->Type() == PHI_STMT && (ref_wn = vse->Ref_wn()) != NULL) {
01093 OPCODE opc = WN_opcode(ref_wn);
01094 rtype = OPCODE_rtype(opc);
01095 dtype = OPCODE_desc(opc);
01096 Is_True(!(dtype==MTYPE_I2 && rtype== MTYPE_I2), ("Create illegal coderep i2i2"));
01097
01098 #ifndef TARG_X8664
01099
01100
01101
01102
01103 if (dtype == MTYPE_I4 && rtype == MTYPE_I8)
01104 rtype = MTYPE_I4;
01105 #else
01106 if (dtype == MTYPE_U4 && rtype == MTYPE_U8)
01107 rtype = MTYPE_U4;
01108 #endif
01109
01110 ty = WN_object_ty(ref_wn);
01111 cr = htable->Add_def(opt_stab->Du_aux_id(du),
01112 opt_stab->Du_version(du),
01113 stmt,
01114 rtype,
01115 dtype,
01116 opt_stab->Du_st_ofst(du),
01117 ty,
01118 0,
01119
01120 TRUE);
01121 } else {
01122 AUX_STAB_ENTRY *sym = opt_stab->Aux_stab_entry(vse->Aux_id());
01123
01124 ty = TY_IDX_ZERO;
01125 ST *st = opt_stab->St(vse->Aux_id());
01126 if (st != NULL) ty = ST_type(st);
01127
01128 if (sym->Mtype()==MTYPE_M || MTYPE_is_vector(sym->Mtype()))
01129 rtype = sym->Mtype();
01130 else {
01131 rtype = Mtype_from_mtype_class_and_size(sym->Mclass(),
01132 sym->Byte_size());
01133 #ifdef KEY // bug 8186
01134 if (MTYPE_is_unsigned(sym->Mtype()))
01135 rtype = Mtype_TransferSign(MTYPE_U4, rtype);
01136 #endif
01137 }
01138
01139 dtype = rtype;
01140
01141 if (rtype != MTYPE_UNKNOWN && rtype != MTYPE_M) {
01142 if (MTYPE_is_integral(rtype) &&
01143 sym->Byte_size() < (MTYPE_size_min(MTYPE_I4)/8)) {
01144 rtype = Mtype_from_mtype_class_and_size(sym->Mclass(),
01145 MTYPE_size_min(MTYPE_I4)/8);
01146 #ifdef KEY // bug 8186
01147 if (MTYPE_is_unsigned(sym->Mtype()))
01148 rtype = Mtype_TransferSign(MTYPE_U4, rtype);
01149 #endif
01150 }
01151 ty = MTYPE_To_TY(rtype);
01152 }
01153
01154 cr = htable->Add_def(opt_stab->Du_aux_id(du),
01155 opt_stab->Du_version(du),
01156 stmt,
01157 rtype,
01158 dtype,
01159 opt_stab->Du_st_ofst(du),
01160 ty,
01161 0,
01162 TRUE);
01163 cr->Set_flag(CF_MADEUP_TYPE);
01164 }
01165
01166
01167 if ( opt_stab->Du_is_volatile(du) ) {
01168 cr->Set_var_volatile();
01169 }
01170 else {
01171
01172 opt_stab->Du_set_coderep(du, cr);
01173 }
01174 }
01175
01176 return cr;
01177 }
01178
01179
01180
01181 void SSA::Value_number(CODEMAP *htable, OPT_STAB *opt_stab, BB_NODE *bb,
01182 COPYPROP *copyprop, EXC *exc)
01183 {
01184 PHI_LIST_ITER phi_iter;
01185 PHI_NODE *phi;
01186 STMT_ITER stmt_iter;
01187 WN *wn;
01188 VER_ID du;
01189 CODEREP *cr;
01190
01191
01192 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
01193 if (phi->Live()) {
01194 du = phi->Result();
01195 FmtAssert(du != 0,
01196 ("SSA::Value_number: Phi result wasn't set correctly"));
01197 if (opt_stab->Du_zero_vers(du) ) {
01198 cr = Get_zero_version_CR(phi->Aux_id(), opt_stab, du);
01199 phi->Set_result(cr);
01200 } else {
01201 cr = Du2cr( htable, opt_stab, du, NULL);
01202 Is_True(cr != NULL, ("SSA::Value_number: Du2cr cannot return NULL"));
01203 cr->Set_flag(CF_DEF_BY_PHI);
01204 cr->Set_defphi(phi);
01205 phi->Set_result(cr);
01206 }
01207 phi->Set_res_is_cr();
01208 } else cr = NULL;
01209 opt_stab->Push_coderep(phi->Aux_id(), cr);
01210 }
01211
01212 copyprop->Unvisit_nodes();
01213
01214 Is_True(! copyprop->Past_ret_reg_def(),
01215 ("SSA::Value_number: _past_ret_reg_def flag set incorrectly"));
01216
01217 STMTREP *stmt = NULL;
01218
01219 FOR_ALL_ELEM (wn, stmt_iter, Init(bb->Firststmt(), bb->Laststmt())) {
01220 if (OPERATOR_is_scalar_store (WN_operator(wn)) &&
01221 ! opt_stab->Du_any_use(WN_ver(wn)))
01222 continue;
01223 #ifndef KEY // move deletion to emit phase because htable.cxx needs to mark
01224
01225 else if (Htable()->Phase() == MAINOPT_PHASE &&
01226 WN_operator(wn) == OPR_XPRAGMA &&
01227 WN_pragma(wn) == WN_PRAGMA_COPYIN_BOUND)
01228 continue;
01229
01230
01231 #endif
01232 else if ((OPERATOR_is_scalar_istore (WN_operator(wn)) ||
01233 WN_operator(wn) == OPR_MSTORE) &&
01234 WOPT_Enable_Dse_Aggressive &&
01235 WN_has_chi(wn, Cfg()->Rgn_level())) {
01236 CHI_LIST_ITER chi_iter;
01237 CHI_NODE *cnode;
01238 CHI_LIST *chi_list = opt_stab->Get_generic_chi_list(wn);
01239 BOOL istore_live = FALSE;
01240 TY_IDX ty = WN_ty(wn);
01241
01242
01243
01244
01245 if (TY_is_volatile(ty))
01246 istore_live = TRUE;
01247 else if (TY_kind(ty) == KIND_POINTER && Ilod_TY_is_volatile(ty))
01248 istore_live = TRUE;
01249 #ifdef KEY
01250 else if ((WN_operator(WN_kid1(wn)) == OPR_LDA || WN_operator(WN_kid1(wn)) ==OPR_ILDA) &&
01251 TY_kind(WN_ty(WN_kid1(wn))) == KIND_POINTER && Ilod_TY_is_volatile(WN_ty(WN_kid1(wn))))
01252 istore_live = TRUE;
01253 #endif
01254 else {
01255 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list) ) {
01256 if (cnode->Live()) {
01257 istore_live = TRUE;
01258 break;
01259 }
01260 }
01261 }
01262
01263
01264
01265
01266
01267
01268
01269
01270 if (! istore_live && !opt_stab->Get_occ(wn)->Points_to()->Unique_pt())
01271 continue;
01272 }
01273
01274
01275 stmt = bb->Add_stmtnode(wn, mem_pool);
01276
01277 #ifdef TARG_SL //fork_joint
01278 if(WN_is_compgoto_para(wn))
01279 stmt->Set_fork_stmt_flags(TRUE);
01280 else if(WN_is_compgoto_for_minor(wn))
01281 stmt -> Set_minor_fork_stmt_flags(TRUE);
01282
01283 if (WN_operator(wn) == OPR_ISTORE && WN_is_internal_mem_ofst(wn))
01284 stmt->Set_SL2_internal_mem_ofst(TRUE);
01285 #endif
01286
01287 stmt->Enter_rhs(htable, opt_stab, copyprop, exc);
01288 stmt->Enter_lhs(htable, opt_stab, copyprop);
01289
01290 #ifdef KEY // bug 3130
01291
01292
01293
01294
01295 OPERATOR stmt_opr = stmt->Opr();
01296 if (stmt_opr == OPR_STID &&
01297 ST_class(opt_stab->St(stmt->Lhs()->Aux_id())) != CLASS_PREG) {
01298 CODEREP *rhs_cr = stmt->Rhs();
01299 CODEREP *lhs = stmt->Lhs();
01300 if (rhs_cr->Kind() == CK_OP && rhs_cr->Opr() == OPR_CVT &&
01301 rhs_cr->Opnd(0)->Kind() == CK_VAR &&
01302 lhs->Aux_id() == rhs_cr->Opnd(0)->Aux_id() &&
01303 MTYPE_is_integral(rhs_cr->Dsctyp()) &&
01304 MTYPE_is_integral(rhs_cr->Dtyp()) &&
01305 MTYPE_is_integral(lhs->Dsctyp()) &&
01306 MTYPE_byte_size(rhs_cr->Dtyp()) == MTYPE_byte_size(lhs->Dsctyp())) {
01307 stmt->Set_rhs(rhs_cr->Opnd(0));
01308 rhs_cr->DecUsecnt();
01309 }
01310 }
01311 #endif
01312
01313 #if 0
01314
01315 OPERATOR stmt_opr = stmt->Opr();
01316 if (stmt_opr == OPR_STID &&
01317 ST_class(opt_stab->St(stmt->Lhs()->Aux_id())) != CLASS_PREG ||
01318 stmt_opr == OPR_ISTORE ||
01319 stmt_opr == OPR_ISTOREX) {
01320 CODEREP *rhs_cr = stmt->Rhs();
01321 CODEREP *lhs = stmt->Lhs();
01322 if (WOPT_Enable_Cvt_Folding &&
01323 rhs_cr->Kind() == CK_OP &&
01324 (rhs_cr->Opr() == OPR_CVT && MTYPE_is_integral(rhs_cr->Dsctyp())
01325 || rhs_cr->Opr() == OPR_CVTL) &&
01326 MTYPE_is_integral(rhs_cr->Dtyp()) &&
01327 MTYPE_is_integral(lhs->Dsctyp())
01328 ) {
01329 MTYPE actual_type = (rhs_cr->Opr() == OPR_CVT) ?
01330 rhs_cr->Dsctyp() : Actual_cvtl_type(rhs_cr->Op(),rhs_cr->Offset());
01331 if (MTYPE_size_min(lhs->Dsctyp()) <= MTYPE_size_min(actual_type)) {
01332 stmt->Set_rhs(rhs_cr->Get_opnd(0));
01333 }
01334 }
01335 }
01336 #endif
01337
01338 INT32 linenum = Srcpos_To_Line(stmt->Linenum());
01339
01340
01341 stmt->Set_wn(NULL);
01342
01343 BOOL set_dont_prop = TRUE;
01344 if (WN_operator(wn) == OPR_CALL && WN_Call_Does_Mem_Free(wn)) {
01345 set_dont_prop = FALSE;
01346 WOPT_Enable_Itself_Prop = FALSE;
01347 }
01348
01349
01350 if (WN_has_mu(wn, Cfg()->Rgn_level())) {
01351 MU_LIST_ITER mu_iter;
01352 MU_NODE *mnode;
01353
01354 stmt->Set_mu_list( opt_stab->Get_stmt_mu_list(wn) );
01355 if (stmt->Opr() == OPR_RETURN || stmt->Opr() == OPR_RETURN_VAL
01356 #ifdef KEY
01357 || stmt->Opr() == OPR_GOTO_OUTER_BLOCK
01358 #endif
01359 )
01360 stmt->Mu_list()->Delete_def_at_entry_mus(opt_stab);
01361 FOR_ALL_NODE( mnode, mu_iter, Init(stmt->Mu_list()) ) {
01362 if (mnode->Opnd() != 0) {
01363
01364
01365
01366 if (opt_stab->Du_zero_vers(mnode->Opnd()) ||
01367 ! opt_stab->Du_any_use(mnode->Opnd())) {
01368 cr = Get_zero_version_CR(mnode->Aux_id(), opt_stab, mnode->Opnd());
01369 } else {
01370 cr = Du2cr( htable, opt_stab, mnode->Opnd(),
01371 NULL);
01372 }
01373 mnode->Set_OPND(cr, set_dont_prop);
01374 if (opt_stab->NULL_coderep(cr->Aux_id()))
01375 opt_stab->Push_coderep(cr->Aux_id(), cr);
01376 }
01377 }
01378 }
01379
01380 if (WN_has_chi(wn, Cfg()->Rgn_level())) {
01381 CHI_LIST_ITER chi_iter;
01382 CHI_NODE *cnode;
01383
01384 stmt->Set_chi_list( opt_stab->Get_generic_chi_list(wn) );
01385 FOR_ALL_NODE( cnode, chi_iter, Init( stmt->Chi_list()) ) {
01386
01387
01388
01389
01390
01391 if (cnode->Live()) {
01392 if (opt_stab->Du_zero_vers(cnode->Result())) {
01393
01394
01395 stmt->Set_has_zver();
01396 CODEREP *tmpcr = Get_zero_version_CR(cnode->Aux_id(), opt_stab,
01397 cnode->Result());
01398 cnode->Set_RESULT(tmpcr);
01399 opt_stab->Push_coderep(tmpcr->Aux_id(), tmpcr);
01400
01401 if (opt_stab->Du_zero_vers(cnode->Opnd()) ||
01402 stmt->Op() == OPC_OPT_CHI)
01403 tmpcr = Get_zero_version_CR(cnode->Aux_id(), opt_stab,
01404 cnode->Opnd());
01405 else
01406 tmpcr = Du2cr( htable, opt_stab, cnode->Opnd(), NULL);
01407 cnode->Set_OPND(tmpcr, set_dont_prop);
01408
01409 } else {
01410
01411 cr = Du2cr(htable, opt_stab, cnode->Result(), stmt);
01412 if ( cr != NULL ) {
01413 cr->Set_flag(CF_DEF_BY_CHI);
01414 cr->Set_defchi(cnode);
01415 opt_stab->Push_coderep(cr->Aux_id(), cr);
01416 }
01417
01418 cnode->Set_RESULT(cr);
01419
01420
01421
01422
01423 if (opt_stab->Du_zero_vers(cnode->Opnd()) ||
01424 stmt->Op() == OPC_OPT_CHI) {
01425
01426 Is_True(opt_stab->Du_any_use(cnode->Opnd()),
01427 ("Du_any_use if chi for aux %d is not true.",cnode->Aux_id()));
01428
01429 cr = Get_zero_version_CR(cnode->Aux_id(), opt_stab,
01430 cnode->Opnd());
01431 } else
01432 cr = Du2cr( htable, opt_stab, cnode->Opnd(), NULL);
01433
01434 cnode->Set_OPND(cr, set_dont_prop);
01435 }
01436 }
01437 else opt_stab->Push_coderep(cnode->Aux_id(), NULL);
01438 }
01439 }
01440
01441 if (OPERATOR_is_scalar_store (stmt->Opr()) &&
01442 opt_stab->Aux_stab_entry(stmt->Lhs()->Aux_id())->Is_dedicated_preg())
01443 copyprop->Set_past_ret_reg_def();
01444 else if (stmt->Opr() == OPR_RETURN ||
01445 stmt->Opr() == OPR_RETURN_VAL ||
01446 #ifdef KEY
01447 stmt->Opr() == OPR_GOTO_OUTER_BLOCK ||
01448 #endif
01449 stmt->Opr() == OPR_REGION)
01450 copyprop->Reset_past_ret_reg_def();
01451
01452 if (WN_has_chi(wn, Cfg()->Rgn_level()) || OPCODE_is_store(WN_opcode(wn)))
01453 copyprop->Unvisit_nodes();
01454 }
01455
01456
01457 if (stmt != NULL && stmt->Opr() == OPR_IO &&
01458 bb->Kind() == BB_IO) {
01459 stmt->Set_has_ctrl_flow();
01460 }
01461
01462
01463 BB_NODE *succ; BB_LIST_ITER bb_iter;
01464 FOR_ALL_ELEM (succ, bb_iter, Init(bb->Succ())) {
01465 INT32 pos = succ->Pred()->Pos(bb);
01466 Is_True(pos >= 0 || succ->Pred() == NULL,
01467 ("SSA:Value_number: cannot find BB in predecessor list of successor"));
01468 FOR_ALL_ELEM (phi, phi_iter, Init(succ->Phi_list())) {
01469 if (phi->Live()) {
01470 if (opt_stab->Du_zero_vers(phi->Opnd(pos)))
01471 cr = Get_zero_version_CR(phi->Aux_id(), opt_stab, phi->Opnd(pos));
01472 else {
01473 cr = Du2cr( htable, opt_stab, phi->Opnd(pos), NULL);
01474 }
01475 phi->Set_opnd(pos, cr);
01476 cr->Set_flag(CF_DONT_PROP);
01477 }
01478 }
01479 }
01480
01481 bb->Set_vn_processed();
01482
01483
01484 BB_NODE *dom_bb; BB_LIST_ITER dom_bb_iter;
01485 FOR_ALL_ELEM (dom_bb, dom_bb_iter, Init(bb->Dom_bbs())) {
01486 Value_number(htable, opt_stab, dom_bb, copyprop, exc);
01487 }
01488
01489 STMTREP_ITER stmtrep_iter(bb->Stmtlist());
01490 FOR_ALL_NODE_REVERSE (stmt, stmtrep_iter, Init()) {
01491
01492 OPERATOR opr = stmt->Opr();
01493
01494 if (stmt->Has_chi()) {
01495 CHI_LIST_ITER chi_iter;
01496 CHI_NODE *cnode;
01497 CHI_LIST *chi_list = stmt->Chi_list();
01498 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
01499 opt_stab->Pop_coderep(cnode->Aux_id());
01500 }
01501 }
01502
01503
01504 if (OPERATOR_is_scalar_store (opr))
01505 opt_stab->Pop_coderep(stmt->Lhs()->Aux_id());
01506 }
01507
01508 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
01509 opt_stab->Pop_coderep(phi->Aux_id());
01510 }
01511
01512 bb->Init_stmt( NULL );
01513 }
01514
01515
01516 void SSA::Value_number_mu_node(MU_NODE *mnode)
01517 {
01518 if (mnode && mnode->Opnd() != 0) {
01519 CODEREP *cr = Du2cr( _htable, _opt_stab, mnode->Opnd(), NULL);
01520 mnode->Set_OPND(cr);
01521 if (_opt_stab->NULL_coderep(cr->Aux_id()))
01522 _opt_stab->Push_coderep(cr->Aux_id(), cr);
01523 }
01524 }
01525
01526 void SSA::Value_number_mu_list(MU_LIST *mu_list)
01527 {
01528 MU_NODE *mnode;
01529 MU_LIST_ITER mu_iter;
01530 FOR_ALL_NODE( mnode, mu_iter, Init(mu_list)) {
01531 Value_number_mu_node(mnode);
01532 }
01533 }
01534
01535
01536
01537
01538
01539
01540 static STMTREP *
01541 Find_stmt_containing_chi(CHI_NODE *chi, BB_NODE *bb)
01542 {
01543
01544 STMTREP_ITER stmt_iter(bb->Stmtlist());
01545 STMTREP *stmt;
01546 FOR_ALL_NODE(stmt, stmt_iter, Init()) {
01547 if (! stmt->Has_chi())
01548 continue;
01549 CHI_LIST_ITER chi_iter;
01550 CHI_NODE *cnode;
01551 CHI_LIST *chi_list = stmt->Chi_list();
01552 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
01553 if (cnode == chi)
01554 return stmt;
01555 }
01556 }
01557 return NULL;
01558 }
01559
01560
01561
01562
01563
01564
01565
01566
01567 void
01568 SSA::Resurrect_phi(PHI_NODE *phi)
01569 {
01570 VER_ID du;
01571 CODEREP *cr;
01572
01573 du = phi->Result();
01574 if (_opt_stab->Du_zero_vers(du) ) {
01575 cr = Get_zero_version_CR(phi->Aux_id(), _opt_stab, du);
01576 } else {
01577 cr = Du2cr(_htable, _opt_stab, du, NULL);
01578 cr->Set_flag(CF_DEF_BY_PHI);
01579 cr->Set_defphi(phi);
01580 }
01581 phi->Set_result(cr);
01582 phi->Set_live();
01583 phi->Set_res_is_cr();
01584
01585
01586 BB_LIST_ITER bb_list_iter;
01587 BB_NODE *bbpred;
01588 INT32 pos = 0;
01589 FOR_ALL_ELEM(bbpred, bb_list_iter, Init(phi->Bb()->Pred())) {
01590 if (bbpred->VN_processed()) {
01591 phi->Set_opnd(pos, Revive_phi_chi_opnd(phi->Opnd(pos)));
01592 phi->OPND(pos)->Set_flag(CF_DONT_PROP);
01593 }
01594 else Make_live_phi_chi_opnd(phi->Opnd(pos));
01595 pos++;
01596 }
01597 }
01598
01599
01600
01601
01602
01603
01604 void
01605 SSA::Resurrect_chi(CHI_NODE *chi)
01606 {
01607 VER_ID du;
01608 CODEREP *cr;
01609
01610 du = chi->Result();
01611 STMTREP *sr = Find_stmt_containing_chi(chi, _opt_stab->Ver_stab_entry(du)->Bb());
01612 if (_opt_stab->Du_zero_vers(du) ) {
01613 cr = Get_zero_version_CR(chi->Aux_id(), _opt_stab, du);
01614 sr->Set_has_zver();
01615 } else {
01616 cr = Du2cr(_htable, _opt_stab, du, sr);
01617 cr->Set_flag(CF_DEF_BY_CHI);
01618 cr->Set_defchi(chi);
01619 }
01620 chi->Set_RESULT(cr);
01621 chi->Set_live(TRUE);
01622 chi->Set_dse_dead(FALSE);
01623
01624 if (sr->Op() == OPC_OPT_CHI)
01625 chi->Set_OPND( Get_zero_version_CR(chi->Aux_id(), _opt_stab, du));
01626 else {
01627 chi->Set_OPND(Revive_phi_chi_opnd(chi->Opnd()));
01628 chi->OPND()->Set_flag(CF_DONT_PROP);
01629 }
01630 }
01631
01632
01633
01634
01635
01636
01637
01638 CODEREP *
01639 SSA::Revive_phi_chi_opnd(VER_ID du)
01640 {
01641 VER_STAB_ENTRY *vse = _opt_stab->Ver_stab_entry(du);
01642
01643
01644
01645
01646 if (vse->Type() == PHI_STMT) {
01647 PHI_NODE *phi = _opt_stab->Ver_stab_entry(du)->Phi();
01648 if (! phi->Live())
01649 Resurrect_phi(phi);
01650 return phi->RESULT();
01651 }
01652 else if (vse->Type() == CHI_STMT) {
01653 CHI_NODE *chi = _opt_stab->Ver_stab_entry(du)->Chi();
01654 if (! chi->Live()) {
01655 Resurrect_chi(chi);
01656 }
01657 return chi->RESULT();
01658 }
01659 else return Du2cr(_htable, _opt_stab, du, NULL);
01660 }
01661
01662
01663
01664
01665
01666
01667
01668
01669 void
01670 SSA::Make_live_phi_chi_opnd(VER_ID du)
01671 {
01672 VER_STAB_ENTRY *vse = _opt_stab->Ver_stab_entry(du);
01673
01674
01675
01676
01677
01678
01679
01680 BB_NODE *defbb = _opt_stab->Ver_stab_entry(du)->Bb();
01681
01682
01683 if (defbb == NULL)
01684 return;
01685
01686 if (defbb->VN_processed())
01687 Revive_phi_chi_opnd(du);
01688 else {
01689 if (vse->Type() == PHI_STMT) {
01690 PHI_NODE *phi = _opt_stab->Ver_stab_entry(du)->Phi();
01691 if (! phi->Live()) {
01692 phi->Set_live();
01693
01694 BB_LIST_ITER bb_list_iter;
01695 BB_NODE *bbpred;
01696 INT32 pos = 0;
01697
01698 FOR_ALL_ELEM(bbpred, bb_list_iter, Init(phi->Bb()->Pred())) {
01699 if (bbpred->VN_processed()) {
01700 phi->Set_opnd(pos, Revive_phi_chi_opnd(phi->Opnd(pos)));
01701 phi->OPND(pos)->Set_flag(CF_DONT_PROP);
01702 }
01703 else Make_live_phi_chi_opnd(phi->Opnd(pos));
01704 pos++;
01705 }
01706 }
01707 }
01708 else if (vse->Type() == CHI_STMT) {
01709 CHI_NODE *chi = _opt_stab->Ver_stab_entry(du)->Chi();
01710 if (! chi->Live()) {
01711 chi->Set_live(TRUE);
01712 chi->Set_dse_dead(FALSE);
01713 Make_live_phi_chi_opnd(chi->Opnd());
01714 }
01715 }
01716 }
01717 }
01718
01719 void
01720 PHI_NODE::Print(FILE *fp) const
01721 {
01722 Print(size, fp);
01723 }
01724
01725
01726
01727 void
01728 PHI_NODE::Print(INT32 in_degree, FILE *fp) const
01729 {
01730 if (! Live())
01731 PRINT(in_degree, fp);
01732 else {
01733 CODEREP *cr = RESULT();
01734 fprintf(fp, " sym%dv%d<cr%d> <- phi(", cr->Aux_id(),
01735 cr->Version(), cr->Coderep_id());
01736 for (INT32 i = 0; i < Size(); i++) {
01737 cr = OPND(i);
01738 if (cr != NULL) {
01739 fprintf(fp, "sym%dv%d<cr%d>", cr->Aux_id(), cr->Version(),
01740 cr->Coderep_id());
01741 }
01742 else {
01743 fprintf(fp, "<null>");
01744 }
01745
01746 if ( i == in_degree-1 )
01747 fprintf(fp, ")\n" );
01748 else
01749 fprintf(fp, "," );
01750 }
01751 }
01752 }
01753
01754
01755
01756
01757 void
01758 PHI_NODE::PRINT(INT32 in_degree, FILE *fp) const
01759 {
01760 if (! Live())
01761 fprintf(fp, "(not live)");
01762 if (Dse_dead())
01763 fprintf(fp, "(dse-dead)");
01764 if (Dce_dead())
01765 fprintf(fp, "(dce-dead)");
01766 fprintf(fp, " sym%dv%d <- phi(", Aux_id(), Result());
01767 for (INT32 i = 0; i < in_degree; i++) {
01768 fprintf(fp, "sym%dv%d", Aux_id(), Opnd(i));
01769 if ( i == in_degree-1 )
01770 fprintf(fp, ")\n" );
01771 else
01772 fprintf(fp, "," );
01773 }
01774 }
01775
01776
01777
01778
01779 void
01780 PHI_LIST::Print(FILE *fp)
01781 {
01782 PHI_LIST_ITER phi_iter;
01783 PHI_NODE *pnode;
01784
01785 FOR_ALL_NODE(pnode, phi_iter, Init(this))
01786 pnode->Print(in_degree, fp);
01787 }
01788
01789
01790
01791 void
01792 PHI_LIST::PRINT(FILE *fp)
01793 {
01794 PHI_LIST_ITER phi_iter;
01795 PHI_NODE *pnode;
01796
01797 FOR_ALL_NODE(pnode, phi_iter, Init(this))
01798 pnode->PRINT(in_degree, fp);
01799 }
01800