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 #ifdef USE_PCH
00054 #include "opt_pch.h"
00055 #endif // USE_PCH
00056 #pragma hdrstop
00057
00058
00059 #define opt_stable_CXX "opt_stable.cxx"
00060
00061
00062 #include "defs.h"
00063 #include "cxx_memory.h"
00064 #include "opt_bb.h"
00065 #include "opt_main.h"
00066 #include "opt_etable.h"
00067 #include "idx_32_set.h"
00068 #include "opt_ssu.h"
00069 #include "opt_ssa.h"
00070 #include "opt_mu_chi.h"
00071 #include "opt_cvtl_rule.h"
00072
00073
00074
00075
00076
00077 EXP_OCCURS *
00078 ETABLE::Append_spre_real_occurrence(STMTREP *stmt,
00079 EXP_WORKLST *worklist)
00080 {
00081 Is_True(worklist != NULL, ("ETABLE::Append_spre_real_occurrence: null work list node"));
00082
00083 EXP_OCCURS *occur = Alloc_occurs_node();
00084 occur->Set_occurrence(stmt->Lhs());
00085 occur->Set_kind(EXP_OCCURS::OCC_REAL_OCCUR);
00086 occur->Set_enclose_stmt(stmt);
00087
00088
00089 worklist->SPRE_append_occurrence(occur);
00090
00091 return occur;
00092 }
00093
00094
00095
00096
00097
00098 EXP_OCCURS *
00099 ETABLE::Append_iphi_succ_occurrence(BB_NODE *bb,
00100 EXP_WORKLST *worklist)
00101 {
00102 Is_True(worklist != NULL, ("ETABLE::Append_iphi_succ_occurrence: null work list node"));
00103
00104 EXP_OCCURS *occur = Alloc_occurs_node();
00105 occur->Set_occurrence(NULL);
00106 occur->Set_kind(EXP_OCCURS::OCC_PHI_PRED_OCCUR);
00107 occur->Set_enclose_bb(bb);
00108
00109
00110 worklist->SPRE_append_occurrence(occur);
00111 return occur;
00112 }
00113
00114 void
00115 EXP_WORKLST::SPRE_create_iphi_succ(ETABLE *etable)
00116 {
00117 BB_NODE_SET &iphi_succs = etable->Phi_work_set();
00118 BB_NODE_SET_ITER bb_iter;
00119 IDTYPE pdo_id;
00120 EXP_OCCURS *iphi_occ;
00121 EXP_OCCURS_ITER iphi_occ_iter;
00122 BB_NODE *bb_iphi;
00123 BB_NODE *bb_orig;
00124 BB_LIST_ITER bb_list_iter;
00125
00126 Is_Trace(etable->Tracing(),
00127 (TFile, "====== EXP_WORKLST::SPRE_create_iphi_succ ======\n"));
00128
00129 Is_Trace(etable->Tracing(),
00130 (TFile, "The real occurrence list is:\n"));
00131 Is_Trace_cmd(etable->Tracing(), Real_occurs().Print(TFile));
00132 Is_Trace(etable->Tracing(),
00133 (TFile, "The iphi occurrence list is:\n"));
00134 Is_Trace_cmd(etable->Tracing(), Phi_occurs().Print(TFile));
00135
00136 iphi_succs.ClearD();
00137
00138 FOR_ALL_NODE ( iphi_occ, iphi_occ_iter, Init( Phi_occurs().Head()) ) {
00139 FOR_ALL_ELEM ( bb_iphi, bb_list_iter, Init( iphi_occ->Bb()->Succ() ) ) {
00140 iphi_succs.Union1D( bb_iphi->Pdom_dfs_id() );
00141 }
00142 iphi_occ->Bb()->Set_exp_phi(iphi_occ->Exp_phi());
00143 }
00144
00145 FOR_ALL_NODE ( pdo_id, bb_iter, Init(&iphi_succs) ) {
00146 bb_orig = etable->Cfg()->Pdo_Bb( pdo_id );
00147 Is_Trace(etable->Tracing(),
00148 (TFile,"------ Generate Iphi-succ occurrence %d ------\n",
00149 bb_orig->Id()));
00150 EXP_OCCURS *iphi_succ = etable->Append_iphi_succ_occurrence(bb_orig, this);
00151 FOR_ALL_ELEM ( bb_iphi, bb_list_iter, Init( bb_orig->Pred() ) ) {
00152 EXP_PHI *iphi = etable->Lookup_exp_phi( bb_iphi, Exp() );
00153 if ( iphi != NULL ) {
00154 INT32 opnd_num = bb_iphi->Succ()->Pos( bb_orig );
00155 iphi->Set_pred(opnd_num, iphi_succ);
00156 }
00157 }
00158 }
00159 }
00160
00161 inline void
00162 EXP_WORKLST::SPRE_compute_backward_attributes(
00163
00164 ETABLE *etable)
00165 {
00166 Compute_forward_attributes(etable);
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 static void
00178 SPRE_force_rhs_to_preg(STMTREP *stmt, IDTYPE preg, ETABLE *etable)
00179 {
00180 CODEREP *rhs = stmt->Rhs();
00181 if (rhs->Kind() == CK_VAR && rhs->Aux_id() == preg) {
00182 etable->Htable()->Insert_var_phi(rhs, rhs->Defbb());
00183 return;
00184 }
00185
00186 CODEREP *pregcr =
00187 etable->Htable()->Add_def(preg, -1, NULL ,
00188 stmt->Lhs()->Dtyp(), stmt->Lhs()->Dtyp(),
00189 etable->Htable()->Sym()->St_ofst(preg),
00190 stmt->Lhs()->Lod_ty(), 0, TRUE);
00191 STMTREP *newstmt = etable->Save_replace_rhs_by_preg(stmt, pregcr, NULL);
00192 etable->Add_stmt(newstmt, stmt->Bb());
00193 }
00194
00195
00196
00197
00198
00199 static void
00200 SPRE_insert_load_to_preg(CODEREP *v, IDTYPE preg, BOOL sign_extd, BB_NODE *bb, ETABLE *etable)
00201 {
00202 CODEREP *rhs;
00203 Is_True(! v->Is_flag_set(CF_IS_ZERO_VERSION),
00204 ("SPRE_insert_load_to_preg: variable cannot be zero version"));
00205 v->IncUsecnt();
00206
00207 CODEREP *pregcr =
00208 etable->Htable()->Add_def(preg, -1, NULL ,
00209 v->Dtyp(), v->Dtyp(),
00210 etable->Htable()->Sym()->St_ofst(preg),
00211 v->Lod_ty(), v->Field_id(), TRUE);
00212 rhs = v;
00213
00214 if (v->Is_integral_load_store() &&
00215 MTYPE_size_min(v->Dsctyp()) <= MTYPE_size_min(MTYPE_I4)) {
00216 OPCODE opc;
00217 CODEREP *new_cr = Alloc_stack_cr(0);
00218 INT load_need_cvt = Need_load_type_conversion(v->Is_sign_extd(), sign_extd,
00219 v->Dtyp(), v->Dsctyp(), &opc);
00220 switch (load_need_cvt) {
00221 case NOT_AT_ALL:
00222 break;
00223 case NEED_CVT:
00224 if (v->Is_flag_set(CF_MADEUP_TYPE)) {
00225 v->Reset_flag(CF_MADEUP_TYPE);
00226 if (opc == OPC_U8U4CVT) {
00227 v->Set_dtyp(MTYPE_U8);
00228 v->Set_dsctyp(MTYPE_U4);
00229 v->Set_sign_extension_flag();
00230 #ifndef KEY
00231 } else if (opc == OPC_U4U8CVT) {
00232 v->Set_dtyp(MTYPE_U4);
00233 v->Set_sign_extension_flag();
00234 #else
00235 } else if (opc == OPC_I8I4CVT) {
00236 v->Set_dtyp(MTYPE_I8);
00237 v->Set_dsctyp(MTYPE_I4);
00238 v->Set_sign_extension_flag();
00239 #endif
00240 } else Is_True(FALSE, ("SPRE_isnert_load_to_preg: wrong type conversion"));
00241 }
00242 else {
00243 new_cr->Init_expr(opc, v);
00244 rhs = etable->Htable()->Rehash(new_cr);
00245 }
00246 break;
00247 case NEED_CVTL:
00248 if (v->Is_flag_set(CF_MADEUP_TYPE)) {
00249 v->Reset_flag(CF_MADEUP_TYPE);
00250 if (opc == OPC_U4CVTL || opc == OPC_U8CVTL) {
00251 v->Set_dtyp(Mtype_TransferSign(MTYPE_U4,v->Dtyp()));
00252 v->Set_dsctyp(Mtype_TransferSign(MTYPE_U4,v->Dsctyp()));
00253 v->Set_sign_extension_flag();
00254 } else if (opc == OPC_I4CVTL || opc == OPC_I8CVTL) {
00255 v->Set_dtyp(Mtype_TransferSign(MTYPE_I4,v->Dtyp()));
00256 v->Set_dsctyp(Mtype_TransferSign(MTYPE_I4,v->Dsctyp()));
00257 v->Set_sign_extension_flag();
00258 } else Is_True(FALSE, ("SPRE_insert_load_to_preg: wrong type conversion"));
00259 }
00260 else {
00261 new_cr->Init_expr(opc, v);
00262 new_cr->Set_offset(MTYPE_size_min(v->Dsctyp()));
00263 rhs = etable->Htable()->Rehash(new_cr);
00264 }
00265 break;
00266 }
00267 }
00268
00269
00270 STMTREP *newstmt = etable->Generate_stid_to_preg(pregcr, rhs, rhs->Dtyp(), bb,
00271 0 );
00272 bb->Append_stmt_before_branch(newstmt);
00273 newstmt->Set_stmt_id(etable->Cfg()->Get_stmt_id());
00274 etable->Add_stmt(newstmt, bb);
00275 }
00276
00277 static CHI_LIST *
00278 Pick_less_live_chi_list(CHI_LIST *chi_list1, CHI_LIST *chi_list2)
00279 {
00280 CHI_LIST_ITER chi_iter;
00281 CHI_NODE *chi;
00282 INT32 live_nodes1 = 0;
00283 INT32 live_nodes2 = 0;
00284 FOR_ALL_NODE(chi, chi_iter, Init(chi_list1)) {
00285 if (chi->Live())
00286 live_nodes1++;
00287 }
00288 FOR_ALL_NODE(chi, chi_iter, Init(chi_list2)) {
00289 if (chi->Live())
00290 live_nodes2++;
00291 }
00292 if (live_nodes1 <= live_nodes2)
00293 return chi_list1;
00294 return chi_list2;
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304 static CHI_LIST *
00305 SPRE_find_def_from_phi(PHI_NODE *phi, IDTYPE preg, BOOL sign_extd, ETABLE *etable)
00306 {
00307 CODEREP *opnd;
00308 CHI_LIST *chi_list = NULL;
00309 BB_LIST_ITER bb_pred_iter;
00310 BB_NODE *bbpred;
00311 INT32 pos = 0;
00312 FOR_ALL_ELEM(bbpred, bb_pred_iter, Init(phi->Bb()->Pred())) {
00313 opnd = phi->OPND(pos);
00314 if (opnd->Is_flag_set((CR_FLAG)(CF_DEF_BY_CHI|CF_IS_ZERO_VERSION))) {
00315
00316 Is_True(WOPT_Enable_Aggressive_Code_Motion,
00317 ("SPRE_find_def_from_phi: must not see a def by chi or zero ver"));
00318 Is_Trace(etable->Tracing(),
00319 (TFile, "SPRE aggcm: load to preg inserted at BB%d\n",
00320 bbpred->Id()));
00321 if (opnd->Is_flag_set(CF_IS_ZERO_VERSION)) {
00322 etable->Htable()->Fix_zero_version(phi, pos);
00323 opnd = phi->OPND(pos);
00324 }
00325 SPRE_insert_load_to_preg(opnd, preg, sign_extd, bbpred, etable);
00326 }
00327 else if (! opnd->Is_flag_set(CF_DEF_BY_PHI)) {
00328 STMTREP *stmt = opnd->Defstmt();
00329 Is_True(stmt != NULL,
00330 ("SPRE_find_def_from_phi: defstmt is NULL for cr%d", opnd->Coderep_id()));
00331 SPRE_force_rhs_to_preg(stmt, preg, etable);
00332 if (chi_list == NULL)
00333 chi_list = stmt->Chi_list();
00334 else chi_list = Pick_less_live_chi_list(chi_list, stmt->Chi_list());
00335 }
00336 else {
00337 PHI_NODE *defphi = opnd->Defphi();
00338 if (defphi->Find_def_processed()) {
00339 pos++;
00340 continue;
00341 }
00342 defphi->Set_find_def_processed();
00343 CHI_LIST *tmp_chi_list = SPRE_find_def_from_phi(defphi, preg, sign_extd, etable);
00344 if (tmp_chi_list != NULL) {
00345 if (chi_list == NULL)
00346 chi_list = tmp_chi_list;
00347 else chi_list = Pick_less_live_chi_list(chi_list, tmp_chi_list);
00348 }
00349 }
00350 pos++;
00351 }
00352 return chi_list;
00353 }
00354
00355
00356
00357
00358
00359
00360
00361 static CODEREP *
00362 SPRE_find_corresponding_preg_cr(CODEREP *x, IDTYPE preg, ETABLE *etable)
00363 {
00364 if (x->Defphi()->Find_corr_processed())
00365 return NULL;
00366 x->Defphi()->Set_find_corr_processed();
00367
00368 BB_NODE *bb = x->Defphi()->Bb();
00369 PHI_NODE *pregphi = etable->Lookup_var_phi(bb, preg);
00370 if (pregphi != NULL)
00371 return pregphi->RESULT();
00372 CODEREP *opnd = x->Defphi()->OPND(0);
00373
00374 if (opnd->Is_flag_set(CF_DEF_BY_PHI))
00375 return SPRE_find_corresponding_preg_cr(opnd, preg, etable);
00376 if (opnd->Is_flag_set((CR_FLAG)(CF_DEF_BY_CHI|CF_IS_ZERO_VERSION))) {
00377 Is_True(WOPT_Enable_Aggressive_Code_Motion,
00378 ("SPRE_find_corresponding_preg_cr: must not see a def by chi"));
00379 return NULL;
00380 }
00381
00382 SPRE_force_rhs_to_preg(opnd->Defstmt(), preg, etable);
00383 CODEREP *rhs = opnd->Defstmt()->Rhs();
00384 Is_True(rhs->Kind() == CK_VAR && rhs->Aux_id() == preg,
00385 ("SPRE_find_corresponding_preg_cr: store of current version has bad rhs"));
00386
00387 return rhs;
00388 }
00389
00390
00391
00392
00393
00394
00395 static CHI_LIST *
00396 SPRE_clone_chi_list(CHI_LIST *old_chi_list,
00397 BOOL chi_opnd_not_current,
00398 STMTREP *stmt,
00399 ETABLE *etable)
00400 {
00401 CHI_LIST_ITER chi_iter;
00402 CHI_NODE *chi, *newchi;
00403 CHI_LIST *new_chi_list = CXX_NEW(CHI_LIST, etable->Htable()->Mem_pool());
00404 FOR_ALL_NODE(chi, chi_iter, Init(old_chi_list)) {
00405 newchi = new_chi_list->New_chi_node(chi->Aux_id(), etable->Htable()->Mem_pool());
00406 newchi->Clone(chi);
00407
00408 if (!chi->Dse_dead()) {
00409
00410 CODEREP *new_lhs = etable->Htable()->Add_def(chi->Aux_id(), -1,
00411 NULL ,
00412 chi->RESULT()->Dtyp(),
00413 chi->RESULT()->Dsctyp(),
00414 chi->RESULT()->Offset(),
00415 chi->RESULT()->Lod_ty(),
00416 chi->RESULT()->Field_id(),
00417 TRUE);
00418 new_lhs->Set_flag(CF_DEF_BY_CHI);
00419 new_lhs->Set_defstmt(stmt);
00420 new_lhs->Set_defchi(newchi);
00421 newchi->Set_RESULT(new_lhs);
00422 if (chi_opnd_not_current)
00423 newchi->Set_OPND(etable->Htable()->Ssa()->Get_zero_version_CR(
00424 chi->Aux_id(), etable->Opt_stab(), 0));
00425 else newchi->Set_OPND(chi->OPND());
00426 }
00427 }
00428 return new_chi_list;
00429 }
00430
00431
00432
00433
00434
00435
00436 void
00437 EXP_WORKLST::SPRE_perform_insert_delete(ETABLE *etable)
00438 {
00439 EXP_OCCURS *occur;
00440 STMTREP *stmt;
00441 BB_NODE *bb;
00442 EXP_PHI *iphi;
00443 BB_NODE *iphi_bb;
00444 BB_LIST_ITER bb_iter;
00445 CHI_LIST_ITER chi_iter;
00446 CHI_NODE *chi;
00447 EXP_OCCURS_ITER occ_iter;
00448
00449 #if 0
00450 BB_NODE *succ_bb;
00451
00452 FOR_ALL_NODE(occur, occ_iter, Init(Phi_occurs().Head())) {
00453 bb = occur->Bb();
00454 iphi = occur->Exp_phi();
00455 INT32 pos = 0;
00456 BB_NODE *bb_succ;
00457 FOR_ALL_ELEM(bb_succ, bb_iter, Init(bb->Succ())) {
00458 if (iphi->Opnd(pos) == NULL)
00459 Is_True(iphi->Null_ssu_version(pos),
00460 ("EXP_WORKST::SPRE_perform_insert_delete: a NULL iphi operand does not have NULL_SSU_VERSION flag set"));
00461 pos++;
00462 }
00463 }
00464 #endif
00465
00466
00467 FOR_ALL_NODE(occur, occ_iter, Init(Phi_pred_occurs().Head())) {
00468 CODEREP *old_lhs;
00469
00470 if (! occur->Inserted_computation())
00471 continue;
00472 bb = occur->Bb();
00473
00474
00475
00476 PHI_NODE *varphi = NULL;
00477 if (bb->Pred()->Multiple_bbs())
00478 varphi = etable->Lookup_var_phi(bb, Exp()->Aux_id());
00479 if (varphi != NULL)
00480 old_lhs = varphi->RESULT();
00481 else {
00482
00483 FOR_ALL_ELEM(iphi_bb, bb_iter, Init(bb->Pred())) {
00484 iphi = etable->Lookup_exp_phi(iphi_bb, Exp());
00485 if (iphi != NULL) break;
00486 }
00487 Is_True(iphi != NULL,
00488 ("EXP_WORKLST::SPRE_perform_insert_delete: at iphi succ, cannot find iphi"));
00489
00490 old_lhs = iphi->Result()->Occurrence();
00491 Is_True(old_lhs != NULL,
00492 ("EXP_WORKLST::SPRE_perform_insert_delete: occurrence of iphi not set at BB%d",
00493 iphi_bb->Id()));
00494 }
00495
00496 Is_True(! old_lhs->Is_flag_set(CF_IS_ZERO_VERSION),
00497 ("EXP_WORKLST::SPRE_perform_insert_delete: at insertion, current version is 0 version"));
00498
00499
00500 Is_True(! old_lhs->Is_flag_set(CF_DEF_BY_CHI),
00501 ("EXP_WORKLST::SPRE_perform_insert_delete: at insertion, current version cannot be defined by chi"));
00502 BOOL chi_opnd_not_current;
00503 CHI_LIST *old_chi_list;
00504 CODEREP *rhs;
00505
00506 if (old_lhs->Is_flag_set(CF_DEF_BY_PHI)) {
00507 Is_True(old_lhs->Defphi()->Live(),
00508 ("EXP_WORKLST::SPRE_perform_insert_delete: at insertion, current version cannot be defined by dead phi"));
00509
00510 BB_NODE *defbb = old_lhs->Defphi()->Bb();
00511 old_lhs->Defphi()->Set_find_def_processed();
00512 old_chi_list = SPRE_find_def_from_phi(old_lhs->Defphi(), Preg(), Sign_extd(), etable);
00513 chi_opnd_not_current = TRUE;
00514 rhs = SPRE_find_corresponding_preg_cr(old_lhs, Preg(), etable);
00515 if (rhs == NULL) {
00516 rhs = etable->Htable()->Ssa()->Get_zero_version_CR(
00517 Preg(), etable->Opt_stab(), 0);
00518
00519
00520
00521
00522
00523 }
00524 }
00525 else {
00526 SPRE_force_rhs_to_preg(old_lhs->Defstmt(), Preg(), etable);
00527 rhs = old_lhs->Defstmt()->Rhs();
00528 Is_True(rhs->Kind() == CK_VAR && rhs->Aux_id() == Preg(),
00529 ("EXP_WORKLST::SPRE_perform_insert_delete: at insertion, store of current version has bad rhs"));
00530 old_chi_list = old_lhs->Defstmt()->Chi_list();
00531 chi_opnd_not_current = FALSE;
00532 }
00533 rhs->IncUsecnt();
00534
00535
00536 #ifdef KEY // bug 5798
00537 if (old_lhs->Dtyp() == MTYPE_UNKNOWN) {
00538 old_lhs->Set_dsctyp(Exp()->Dsctyp());
00539 old_lhs->Set_dtyp(Exp()->Dtyp());
00540 }
00541 #endif
00542 CODEREP *new_lhs = etable->Htable()->Add_def(old_lhs->Aux_id(), -1,
00543 NULL , old_lhs->Dtyp(), old_lhs->Dsctyp(),
00544 old_lhs->Offset(), old_lhs->Lod_ty(), old_lhs->Field_id(), TRUE);
00545
00546
00547 stmt = CXX_NEW(STMTREP, etable->Htable()->Mem_pool());
00548 stmt->Init(new_lhs, rhs, OPCODE_make_op(OPR_STID, MTYPE_V, new_lhs->Dsctyp()));
00549 stmt->Set_chi_list(SPRE_clone_chi_list(old_chi_list,
00550 chi_opnd_not_current, stmt, etable));
00551
00552 new_lhs->Set_defstmt(stmt);
00553 stmt->Set_bb(bb);
00554 if (bb->First_stmtrep() == NULL)
00555 stmt->Set_linenum(bb->Linenum());
00556 else stmt->Set_linenum(bb->First_stmtrep()->Linenum());
00557 stmt->Set_live_stmt();
00558 stmt->Set_stmt_id(etable->Cfg()->Get_stmt_id());
00559
00560
00561 bb->Prepend_stmtrep(stmt);
00562 etable->Add_stmt(stmt, bb);
00563 Inc_insert_count();
00564
00565
00566 etable->Opt_stab()->Aux_stab_entry(Preg())->Set_SPRE_temp();
00567 }
00568
00569
00570 FOR_ALL_NODE(occur, occ_iter, Init(Real_occurs().Head())) {
00571 if (occur->Delete_comp()) {
00572 stmt = occur->Enclosed_in_stmt();
00573 if (stmt->Volatile_stmt())
00574 continue;
00575 bb = stmt->Bb();
00576
00577
00578 FOR_ALL_NODE(chi, chi_iter, Init(stmt->Chi_list())) {
00579 if (chi->Dse_dead() ||
00580 !chi->Live() ||
00581 chi->RESULT()->Is_flag_set(CF_IS_ZERO_VERSION))
00582 continue;
00583 chi->RESULT()->Set_flag(CF_SPRE_REMOVED);
00584 }
00585
00586
00587 if (stmt->Rhs()->Kind() == CK_VAR)
00588 etable->Htable()->Insert_var_phi(stmt->Rhs(), stmt->Rhs()->Defbb());
00589
00590 stmt->Lhs()->Set_flag(CF_SPRE_REMOVED);
00591 bb->Remove_stmtrep(stmt);
00592 Inc_reload_count();
00593
00594 }
00595 }
00596
00597 Is_Trace(etable->Tracing(),
00598 (TFile, "==== After EXP_WORKLST::SPRE_perform_insert_delete\n"));
00599 Is_Trace_cmd(etable->Tracing(), Print(TFile, NULL));
00600
00601
00602 etable->Inc_cse_reloads(Reload_count());
00603 etable->Inc_inserted_saves(Insert_count());
00604 }
00605
00606
00607 void
00608 ETABLE::Add_stmt(STMTREP *stmt, BB_NODE *bb)
00609 {
00610
00611 CODEREP *new_lhs = stmt->Lhs();
00612 Htable()->Insert_var_phi(new_lhs, bb);
00613 CHI_LIST_ITER chi_iter;
00614 CHI_NODE *chi;
00615 FOR_ALL_NODE(chi, chi_iter, Init(stmt->Chi_list())) {
00616 if (chi->Live())
00617 Htable()->Insert_var_phi(chi->RESULT(), bb);
00618 }
00619 }
00620
00621
00622 void
00623 ETABLE::Perform_SPRE_optimization(void)
00624 {
00625 if (Tracing()) {
00626 if (Get_Trace(TKIND_ALLOC, TP_WOPT1)) {
00627 MEM_Tracing_Enable();
00628 }
00629 fprintf( TFile, "%sProgram before SPRE:\n%s",
00630 DBar, DBar );
00631 Cfg()->Print(TFile);
00632 }
00633
00634 Cfg()->Pdo_vec();
00635
00636 OPT_POOL_Push(Etable_local_pool(), SPRE_DUMP_FLAG);
00637 {
00638 _ssu = CXX_NEW(SSU(Htable(), Cfg(), Opt_stab(), this,
00639 Etable_pool(), Etable_local_pool(),
00640 Get_Trace(TP_GLOBOPT, SPRE_DUMP_FLAG)),
00641 Etable_local_pool());
00642
00643
00644
00645
00646
00647 Ssu()->Construct();
00648 }
00649 OPT_POOL_Pop(Etable_local_pool(), SPRE_DUMP_FLAG);
00650
00651
00652 INT32 Downsafe_prop_phase = 0;
00653 INT32 Avail_insert_phase = 0;
00654 INT32 Save_reload_phase = 0;
00655 INT32 Finalize_phase = 0;
00656
00657 INT32 cur_worklst_idx = 0;
00658 EXP_WORKLST *cur_worklst;
00659 EXP_WORKLST_ITER worklst_iter(Exp_worklst());
00660 FOR_ALL_NODE(cur_worklst, worklst_iter, Init()) {
00661
00662 cur_worklst_idx++;
00663 if (WOPT_Enable_Store_PRE_Limit != -1 &&
00664 cur_worklst_idx > WOPT_Enable_Store_PRE_Limit) {
00665 DevWarn("SPRE: skip SPRE for variable with v_num > %d\n",
00666 WOPT_Enable_Store_PRE_Limit);
00667 break;
00668 }
00669
00670 OPT_POOL_Push(Per_expr_pool(), SPRE_DUMP_FLAG);
00671 Is_Trace(Tracing(),
00672 (TFile, "\n||||||||||||| processing %dth store\n", cur_worklst_idx));
00673 Is_Trace_cmd(Tracing(),cur_worklst->Print(TFile, NULL));
00674
00675 Is_Trace_cmd(Tracing(),cur_worklst->Exp()->Print(0,TFile));
00676
00677 #ifdef Is_True_On
00678 {
00679 EXP_OCCURS *iphi_occ;
00680 EXP_OCCURS_ITER iphi_occ_iter;
00681 FOR_ALL_NODE ( iphi_occ, iphi_occ_iter, Init( cur_worklst->Phi_occurs().Head()) ) {
00682 Is_True(iphi_occ->Exp_phi()->Result() == iphi_occ,
00683 ("ETABLE::Perform_SPRE_optimization: Inconsistent Phi-occur."));
00684 Is_True(iphi_occ->For_spre(),
00685 ("ETABLE::Perform_SPRE_optimization: for_spre not set in EXP_OCCUR."));
00686 }
00687 }
00688 #endif
00689
00690
00691 {
00692
00693 cur_worklst->SPRE_create_iphi_succ(this);
00694
00695
00696 SET_OPT_REPEAT_PHASE(Downsafe_prop_phase, "SPRE: Up Safety");
00697 cur_worklst->Propagate_downsafe(this);
00698
00699 SET_OPT_REPEAT_PHASE(Avail_insert_phase, "SPRE: Backward attributes");
00700 cur_worklst->SPRE_compute_backward_attributes(this);
00701
00702 SET_OPT_REPEAT_PHASE(Save_reload_phase, "SPRE: Compute insert/delete");
00703 cur_worklst->SPRE_compute_insert_delete(Htable(), this);
00704
00705 SET_OPT_REPEAT_PHASE(Finalize_phase, "SPRE: Perform insert/delete");
00706 cur_worklst->SPRE_perform_insert_delete(this);
00707
00708 Opt_tlog( "SPRE", 0,
00709 "%d-th variable: Inserts=%d, Deletes=%d",
00710 cur_worklst_idx,
00711 cur_worklst->Insert_count(),
00712 cur_worklst->Reload_count());
00713
00714
00715 EXP_OCCURS *iphi_occ;
00716 EXP_OCCURS_ITER iphi_occ_iter;
00717 FOR_ALL_NODE ( iphi_occ, iphi_occ_iter, Init( cur_worklst->Phi_occurs().Head()) ) {
00718 iphi_occ->Bb()->Set_exp_phi(NULL);
00719 }
00720 }
00721
00722 OPT_POOL_Pop(Per_expr_pool(), SPRE_DUMP_FLAG);
00723
00724 }
00725
00726 if (Tracing()) {
00727 fprintf(TFile, "%sBefore SPRE rename\n%s", DBar, DBar);
00728 Cfg()->Print(TFile);
00729 }
00730
00731 SET_OPT_PHASE("SPRE: Update SSA");
00732 SPRE_update_ssa();
00733
00734 if (Tracing()) {
00735 fprintf(TFile, "%sAfter SPRE\n%s", DBar, DBar);
00736 fprintf(TFile, "Statistics (all expressions): Insert Count %d, "
00737 "Delete Count %d\n", _num_inserted_saves, _num_cse_reloads);
00738 Cfg()->Print(TFile);
00739 if (Get_Trace(TKIND_ALLOC, TP_WOPT1)) {
00740 MEM_Trace();
00741 }
00742 }
00743 }
00744
00745 void
00746 COMP_UNIT::Do_store_pre(void)
00747 {
00748 MEM_POOL stable_pool, per_str_pool, stable_local_pool;
00749
00750 OPT_POOL_Initialize(&stable_pool, "stable pool", FALSE, SPRE_DUMP_FLAG);
00751 OPT_POOL_Initialize(&per_str_pool, "per str pool", FALSE, SPRE_DUMP_FLAG);
00752 OPT_POOL_Initialize(&stable_local_pool, "stable local pool", FALSE, SPRE_DUMP_FLAG);
00753 OPT_POOL_Push(&stable_pool, SPRE_DUMP_FLAG);
00754 OPT_POOL_Push(&per_str_pool, SPRE_DUMP_FLAG);
00755 OPT_POOL_Push(&stable_local_pool, SPRE_DUMP_FLAG);
00756
00757 {
00758 ETABLE etable(Cfg(), Opt_stab(), Htable(), Arule(), 10, &stable_pool,
00759 &per_str_pool, &stable_local_pool, this, PK_SPRE);
00760 etable.Perform_SPRE_optimization();
00761 }
00762
00763 OPT_POOL_Pop(&stable_local_pool, SPRE_DUMP_FLAG);
00764 OPT_POOL_Pop(&per_str_pool, SPRE_DUMP_FLAG);
00765 OPT_POOL_Pop(&stable_pool, SPRE_DUMP_FLAG);
00766 OPT_POOL_Delete(&stable_local_pool, SPRE_DUMP_FLAG);
00767 OPT_POOL_Delete(&per_str_pool, SPRE_DUMP_FLAG);
00768 OPT_POOL_Delete(&stable_pool, SPRE_DUMP_FLAG);
00769 }