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 #ifdef USE_PCH
00057 #include "opt_pch.h"
00058 #endif // USE_PCH
00059 #pragma hdrstop
00060
00061
00062 #define opt_etable_CXX "opt_etable.cxx"
00063
00064 #include "id_map.h"
00065
00066 #include "defs.h"
00067 #include "cxx_memory.h"
00068 #include "glob.h"
00069
00070 #include "opt_base.h"
00071 #include "opt_bb.h"
00072 #include "opt_cfg.h"
00073 #include "opt_estr.h"
00074 #include "opt_etable.h"
00075 #include "opt_efinalize.h"
00076 #include "opt_mu_chi.h"
00077 #include "opt_htable.h"
00078 #include "opt_main.h"
00079 #include "opt_ssa.h"
00080 #include "opt_sys.h"
00081 #include "opt_util.h"
00082 #include "tracing.h"
00083 #include "opt_lftr2.h"
00084 #include "config_targ.h"
00085 #include "idx_32_set.h"
00086 #include "opt_verify.h"
00087 #include "opt_cvtl_rule.h"
00088 #include "opt_fold.h"
00089
00090 #include "data_layout.h"
00091
00092 #ifdef KEY
00093 #include "opt_alias_mgr.h"
00094 #endif
00095
00096
00097 const char *pre_kind_name(PRE_KIND kind)
00098 {
00099 switch (kind) {
00100 case PK_EPRE: return "epre";
00101 case PK_LPRE: return "lpre";
00102 case PK_SPRE: return "spre";
00103 case PK_VNFRE: return "vnfre";
00104 }
00105 return "unknown";
00106 }
00107
00108
00109
00110
00111
00112
00113
00114 class REHASH_CACHE_LIST : public SLIST_NODE {
00115 private:
00116 CODEREP *_cr;
00117 CODEREP *_rehash_cr;
00118
00119 REHASH_CACHE_LIST(const EXP_OCCURS_LIST&);
00120 REHASH_CACHE_LIST& operator = (const EXP_OCCURS_LIST&);
00121
00122 public:
00123 REHASH_CACHE_LIST(void) { }
00124 REHASH_CACHE_LIST(CODEREP *cr, CODEREP *rehash_cr)
00125 { _cr = cr; _rehash_cr = rehash_cr; }
00126 ~REHASH_CACHE_LIST(void) { }
00127
00128 DECLARE_SLIST_NODE_CLASS( REHASH_CACHE_LIST )
00129
00130 CODEREP *Cr(void) { return _cr; }
00131 CODEREP *Rehash_cr(void) { return _rehash_cr; }
00132 };
00133
00134
00135 CODEREP*
00136 CODEREP::Skip_opnd(INT16 i) const
00137 {
00138 Is_True(Kind() == CK_OP, ("CODEREP::Opnd, illegal kind %s", Print_kind()));
00139 if (Opr() == OPR_PARM)
00140 return Opnd(i)->Opnd(0);
00141
00142
00143
00144 if (Opr() == OPR_CVT) {
00145 INT cvt_kind;
00146 OPCODE opc;
00147
00148 cvt_kind = Need_type_conversion(Dsctyp(), Dtyp(), &opc);
00149 if (cvt_kind == NOT_AT_ALL)
00150 return Opnd(i)->Opnd(0);
00151 }
00152
00153
00154 return Opnd(i);
00155 }
00156
00157 void
00158 EXP_PHI::Init(EXP_ID e_num, INT opnd_count, BB_NODE *bb, MEM_POOL *pool)
00159 {
00160 _e_num = e_num; _opnd_count = opnd_count; _bb = bb;
00161 _cached_identity_assignment = NULL; _flags = 0;
00162 _result = NULL;
00163 Set_uses((USE_LIST_ENTRY *) NULL);
00164 _vec = (PHI_ELEM*) CXX_NEW_ARRAY(PHI_ELEM, opnd_count, pool);
00165 BZERO(_vec, sizeof(PHI_ELEM) * opnd_count);
00166 }
00167
00168 void
00169 EXP_PHI::Print(FILE *fp, BOOL show_preds_of_unavail) const
00170 {
00171 INT i;
00172 if (Not_down_safe())
00173 fprintf(fp, "!downsafe; ");
00174 if (Cant_be_avail())
00175 fprintf(fp, "Cant be available; ");
00176 if (Will_b_avail())
00177 fprintf(fp, "Will be available; ");
00178 if (Is_live())
00179 fprintf(fp, "Is live; ");
00180 if (Stops())
00181 fprintf(fp, "Stops; ");
00182 if (Partial_avail())
00183 fprintf(fp, "Partial avail; ");
00184 fprintf(fp, "phi_opnds: ");
00185 for (i = 0; i < Opnd_count(); i++) {
00186 if (Opnd(i) == NULL) {
00187 fprintf(fp, "nil");
00188 if (Has_real_occ(i))
00189 fprintf(fp, "<has-real-occ>");
00190 } else {
00191 fprintf(fp, "%d", Opnd(i)->E_version());
00192 switch (Opnd(i)->Occ_kind()) {
00193 case EXP_OCCURS::OCC_REAL_OCCUR:
00194 fprintf(fp, "<real>");
00195 break;
00196 case EXP_OCCURS::OCC_PHI_OCCUR:
00197 fprintf(fp, "<phi>");
00198 break;
00199 case EXP_OCCURS::OCC_PHI_PRED_OCCUR:
00200 fprintf(fp, "<phi pred>");
00201 break;
00202 default:
00203 fprintf(fp, "<bad>");
00204 break;
00205 }
00206 if (Has_real_occ(i))
00207 fprintf(fp, "<has-real-occ>");
00208 if (Delayed_rename(i))
00209 fprintf(fp, "<delayed>");
00210 if (Injured(i))
00211 fprintf(fp, "<injured>");
00212 if (Opnd_stops(i))
00213 fprintf(fp, "<stops>");
00214 }
00215 if (i < Opnd_count()-1)
00216 fprintf(fp, ",");
00217 }
00218 if (! Reverse_phi()) {
00219 if (show_preds_of_unavail || Will_b_avail()) {
00220 fprintf(fp, " phi_preds: ");
00221 for (i = 0; i < Opnd_count(); i++) {
00222 if (Pred(i) == NULL)
00223 fprintf(fp, "nil");
00224 else {
00225 switch (Pred(i)->Occ_kind()) {
00226 case EXP_OCCURS::OCC_PHI_PRED_OCCUR:
00227 fprintf(fp, "<phi_pred>%d", Pred(i)->Enclosed_in_bb()->Id());
00228 break;
00229 case EXP_OCCURS::OCC_REAL_OCCUR:
00230 fprintf(fp, "<real>%d", Pred(i)->Enclosed_in_bb()->Id());
00231 break;
00232 default:
00233 fprintf(fp, "<bad>");
00234 break;
00235 }
00236 }
00237 if (i < Opnd_count()-1)
00238 fprintf(fp, ",");
00239 }
00240 }
00241 }
00242 else {
00243 fprintf(fp, " iphi_succs: ");
00244 for (i = 0; i < Opnd_count(); i++) {
00245 if (Succ(i) == NULL)
00246 fprintf(fp, "nil");
00247 else {
00248 switch (Succ(i)->Occ_kind()) {
00249 case EXP_OCCURS::OCC_PHI_PRED_OCCUR:
00250 fprintf(fp, "<phi_succ>%d", Succ(i)->Enclosed_in_bb()->Id());
00251 break;
00252 case EXP_OCCURS::OCC_REAL_OCCUR:
00253 fprintf(fp, "<real>%d", Succ(i)->Enclosed_in_bb()->Id());
00254 break;
00255 default:
00256 fprintf(fp, "<bad>");
00257 break;
00258 }
00259 }
00260 if (i < Opnd_count()-1)
00261 fprintf(fp, ",");
00262 }
00263 }
00264 if (!Identity()) {
00265 fprintf(fp, " required");
00266 }
00267 else {
00268 if (Replacing_occur_known()) {
00269 fprintf(fp, " identical: ");
00270 if (Identical_to() != NULL) {
00271 fprintf(fp, "%d", Identical_to()->E_version());
00272 if (Identity_injured()) {
00273 fprintf(fp, "<inj>");
00274 }
00275 }
00276 else {
00277 fprintf(fp, "<NULL>");
00278 }
00279 }
00280 }
00281 fprintf(fp, "\n");
00282 }
00283
00284
00285
00286
00287
00288 BOOL
00289 EXP_PHI::Any_opnd_injured(void) const
00290 {
00291 for (INT i = 0; i < Opnd_count(); i++) {
00292 if (Injured(i)) {
00293 return TRUE;
00294 }
00295 }
00296 return FALSE;
00297 }
00298
00299
00300
00301 BOOL
00302 EXP_PHI::Identity_assignment(BOOL &seen_real_occur, EXP_PHI *orig_occur,
00303 BOOL forward_pre, STACK<EXP_PHI*> &phi_stack)
00304 {
00305 Is_True(!I_A_Seen(),("EXP_PHI::Identity_assignment: visited twice"));
00306
00307 Set_I_A_Seen();
00308 phi_stack.Push(this);
00309
00310 Is_True(Result() != NULL,
00311 ("EXP_PHI::Identity_assignment: NULL expr phi result"));
00312 Is_True(Result()->E_version() != EXP_OCCURS::ILLEGAL_E_VERSION,
00313 ("EXP_PHI::Identity_assignment: Illegal e-version for EXP_PHI result"));
00314
00315 if (Opnd_count() == 1) return FALSE;
00316
00317 BB_NODE *orig_bb = orig_occur->Bb();
00318 EXP_OCCURS *opnd;
00319 EXP_PHI *opnd_phi;
00320
00321 if (this == orig_occur) {
00322 BB_NODE *bb_pred;
00323 BB_LIST_ITER bb_iter;
00324 INT which_pred = 0;
00325
00326 FOR_ALL_ELEM( bb_pred, bb_iter,
00327 Init(forward_pre ? orig_bb->Pred() : orig_bb->Succ()) ) {
00328 opnd = Opnd(which_pred);
00329 ++which_pred;
00330
00331 if ( opnd == NULL ) {
00332 if ( forward_pre && orig_bb->Dominates( bb_pred ) ||
00333 !forward_pre && orig_bb->Postdominates( bb_pred ) ) {
00334 return FALSE;
00335 } else {
00336 continue;
00337 }
00338 }
00339
00340
00341 Is_True(opnd->E_version() != EXP_OCCURS::ILLEGAL_E_VERSION,
00342 ("EXP_PHI::Identity_assignment: Illegal e-version for EXP_PHI operand"));
00343 if ( forward_pre && orig_bb->Dominates( opnd->Bb() ) ||
00344 !forward_pre && orig_bb->Postdominates( opnd->Bb() ) ) {
00345 if (opnd->Occurs_as_lvalue()) {
00346 if (Has_real_occ(which_pred-1)) seen_real_occur = TRUE;
00347 continue;
00348 }
00349 if (opnd->Occ_kind() == EXP_OCCURS::OCC_PHI_OCCUR) {
00350 opnd_phi = opnd->Exp_phi();
00351 if (opnd_phi->I_A_Seen() ||
00352 opnd_phi->Identity_assignment(seen_real_occur, orig_occur,
00353 forward_pre, phi_stack)) {
00354 if (Has_real_occ(which_pred-1)) seen_real_occur = TRUE;
00355 continue;
00356 }
00357 }
00358 return FALSE;
00359 }
00360 }
00361
00362 return TRUE;
00363
00364 } else {
00365 for (INT32 i = 0; i < Opnd_count(); i++) {
00366 opnd = Opnd(i);
00367 if (opnd == NULL) return FALSE;
00368 Is_True(opnd->E_version() != EXP_OCCURS::ILLEGAL_E_VERSION,
00369 ("EXP_PHI::Identity_assignment: Illegal e-version for EXP_PHI operand"));
00370
00371 if ( forward_pre && orig_occur->Bb()->Dominates( opnd->Bb() ) ||
00372 !forward_pre && orig_occur->Bb()->Postdominates( opnd->Bb() ) ) {
00373 if (opnd->Occurs_as_lvalue()) {
00374 if (Has_real_occ(i)) seen_real_occur = TRUE;
00375 continue;
00376 }
00377 if (opnd->Occ_kind() == EXP_OCCURS::OCC_PHI_OCCUR) {
00378 EXP_PHI *opnd_phi = opnd->Exp_phi();
00379 if (opnd_phi->I_A_Seen() ||
00380 opnd_phi->Identity_assignment(seen_real_occur, orig_occur,
00381 forward_pre, phi_stack)) {
00382 if (Has_real_occ(i)) seen_real_occur = TRUE;
00383 continue;
00384 }
00385 }
00386 }
00387 return FALSE;
00388 }
00389 return TRUE;
00390 }
00391 }
00392
00393 BOOL
00394 EXP_OCCURS::Temp_eligible_as_owner(EXP_WORKLST *worklist) const
00395 {
00396 return (Occurs_as_lvalue() ||
00397 (worklist->Exp()->Is_integral_load_store() &&
00398 Occurrence()->Is_sign_extd() != worklist->Sign_extd()));
00399 }
00400
00401 void
00402 EXP_OCCURS::Init(void)
00403 {
00404 Set_kind(OCC_UNKNOWN_OCCUR);
00405 Reset_flag();
00406 Set_e_version(EXP_OCCURS::ILLEGAL_E_VERSION);
00407 _temp._temp_cr = NULL;
00408 Set_rehash_cost(0);
00409 Set_Next(NULL);
00410 }
00411
00412 STMTREP*
00413 EXP_OCCURS::Stmt(void) const
00414 {
00415 Is_True(Occ_kind() == OCC_REAL_OCCUR ||
00416 Occ_kind() == OCC_COMP_OCCUR ||
00417 (Occ_kind() == OCC_PHI_PRED_OCCUR &&
00418 (Inserted_computation() || Sunk_lvalue()) && Encl_stmt_set()),
00419 ("EXP_OCCURS::Stmt: Bad occurrence kind"));
00420 STMTREP *stmt = _enclosed_in._stmt;
00421
00422
00423 while (stmt->Is_RHS_saved()) {
00424 Is_True(stmt->Prev() && stmt->Prev()->Rhs(),
00425 ("EXP_OCCURS::stmt: cannot find the real statement"));
00426 Is_True(!Occurs_as_hoisted(),
00427 ("EXP_OCCURS::stmt: hoisted occur has no real stmt"));
00428 stmt = stmt->Prev();
00429 }
00430 return stmt;
00431 }
00432
00433 BB_NODE*
00434 EXP_OCCURS::Bb(void) const
00435 {
00436 switch (Occ_kind()) {
00437 case OCC_REAL_OCCUR:
00438 if (Is_flag_set(OCC_HOISTED))
00439 return _enclosed_in._bb;
00440 else
00441 return Stmt()->Bb();
00442
00443 case OCC_PHI_OCCUR:
00444 return Exp_phi()->Bb();
00445
00446 case OCC_PHI_PRED_OCCUR:
00447 if (Encl_stmt_set())
00448 return Stmt()->Bb();
00449 else
00450 return _enclosed_in._bb;
00451
00452 case OCC_COMP_OCCUR:
00453 return Stmt()->Bb();
00454
00455 case OCC_EXIT_OCCUR:
00456 return _enclosed_in._bb;
00457
00458 default:
00459 return NULL;
00460 }
00461 }
00462
00463
00464
00465
00466
00467 WN *
00468 CODEREP::Rvi_home_wn( OPT_STAB *opt_stab ) const
00469 {
00470 WN *home_wn = NULL;
00471
00472 switch (Kind()) {
00473 case CK_VAR:
00474 if ( ST_sclass(opt_stab->St(Aux_id())) != SCLASS_FORMAL_REF ) {
00475
00476
00477
00478 home_wn = WN_CreateLdid(OPR_LDID, Dtyp(), Dsctyp(),
00479 Offset(), opt_stab->St(Aux_id()), Lod_ty(),
00480 Field_id());
00481
00482 if (opt_stab->Bit_size (Aux_id()) > 0) {
00483 WN_set_operator (home_wn, OPR_LDBITS);
00484 WN_set_bit_offset_size (home_wn, Bit_offset (), Bit_size ());
00485 }
00486 }
00487 break;
00488 case CK_LDA:
00489 if ( ST_sclass(opt_stab->St(Lda_aux_id())) == SCLASS_FORMAL_REF ) {
00490 if (!ST_has_formal_preg_num(Lda_base_st())) {
00491
00492
00493
00494 home_wn = WN_CreateLdid(OPR_LDID, Pointer_type, Pointer_type,
00495 Offset(), Lda_base_st(),
00496 Lda_ty());
00497 }
00498 } else {
00499 home_wn = WN_CreateLda(OPR_LDA, Dtyp(), MTYPE_V, Offset(), Lda_ty(),
00500 Lda_base_st());
00501 }
00502 break;
00503 case CK_RCONST:
00504 home_wn = WN_CreateConst (OPR_CONST, Dtyp(), MTYPE_V,
00505 ST_st_idx (Const_id()));
00506 break;
00507 case CK_CONST:
00508 home_wn = WN_CreateIntconst (OPR_INTCONST, Dtyp(), MTYPE_V, Const_val());
00509 break;
00510 #ifdef TARG_NVISA // other targets don't know how to rematerialize these
00511 case CK_OP:
00512
00513
00514 switch (Opr()) {
00515 case OPR_ADD:
00516 case OPR_SUB:
00517 case OPR_MPY:
00518 {
00519 WN *kid0 = Opnd(0)->Rvi_home_wn(opt_stab);
00520 WN *kid1 = Opnd(1)->Rvi_home_wn(opt_stab);
00521 if (kid0 && kid1) {
00522 home_wn = WN_CreateExp2 (Opr(), Dtyp(), MTYPE_V, kid0, kid1);
00523 }
00524 }
00525 break;
00526 case OPR_CVT:
00527 {
00528 WN *kid = Opnd(0)->Rvi_home_wn(opt_stab);
00529 if (kid) {
00530 home_wn = WN_CreateExp1 (Opr(), Dtyp(), Dsctyp(), kid);
00531 }
00532 }
00533 break;
00534 }
00535 break;
00536 case CK_IVAR:
00537 if (Opr() == OPR_ILOAD && Ilod_base()) {
00538 WN *kid0 = Ilod_base()->Rvi_home_wn(opt_stab);
00539 if (kid0) {
00540 home_wn = WN_CreateIload (Opr(), Dtyp(), Dsctyp(),
00541 Offset(), Ilod_ty(), Ilod_base_ty(), kid0);
00542 }
00543 }
00544 break;
00545 #endif
00546 default:
00547 Is_True(FALSE, ("CODEREP::Rvi_home_wn: unexpected CR kind"));
00548 }
00549
00550 return home_wn;
00551 }
00552
00553
00554
00555
00556
00557
00558 CODEREP *
00559 EXP_OCCURS::Get_temp_cr(EXP_WORKLST *wk, CODEMAP *htable)
00560 {
00561 if (Temp_cr()) return Temp_cr();
00562
00563 CODEREP *exp = wk->Exp();
00564 MTYPE dtyp = exp->Dtyp();
00565 INT vsize = 0;
00566 INT signess = 0;
00567
00568 if (wk->Preg()) {
00569 vsize = htable->Sym()->Aux_stab_entry(wk->Preg())->Value_size();
00570 } else if ( WOPT_Enable_Min_Type ) {
00571
00572 vsize = Actual_data_size(exp, htable->Sym(), signess);
00573 if (wk->Pre_kind() == PK_VNFRE && vsize != MTYPE_size_min(dtyp))
00574 {
00575 vsize = MTYPE_size_min(dtyp);
00576 Is_True(vsize >= 32,
00577 ("Unexpected size of result type in EXP_OCCURS::Get_temp_cr"));
00578 }
00579
00580
00581 #if defined(TARG_IA32) || defined(TARG_X8664) || defined(TARG_NVISA)
00582 #if 0 // this can cause inconsistent sizes for the same symbol
00583 if (vsize <= 32 && dtyp == MTYPE_U8 && (signess & SIGN_0_EXTD))
00584 dtyp = MTYPE_U4;
00585 #endif
00586 #elif !defined(TARG_IA64)
00587
00588
00589 if (vsize <= 32 && dtyp == MTYPE_I8 && (signess & SIGN_1_EXTD))
00590 dtyp = MTYPE_I4;
00591 #endif
00592 }
00593
00594 if (wk->Preg() == 0) {
00595 WN *home_wn = NULL;
00596 #ifdef TARG_NVISA // only do for nvisa till other targets learn rematerialize
00597 home_wn = exp->Rvi_home_wn(htable->Sym());
00598 #endif
00599 switch (wk->Pre_kind()) {
00600 case PK_VNFRE:
00601 {
00602
00603
00604
00605 #ifndef TARG_NVISA
00606 AUX_ID id = htable->Sym()->Create_preg(dtyp);
00607 #else
00608 AUX_ID id = htable->Sym()->Create_preg(dtyp, "vnfre_cst", home_wn);
00609 #endif
00610 AUX_STAB_ENTRY *aux_preg = htable->Sym()->Aux_stab_entry(id);
00611 ADDRESSABILITY addressable =
00612 exp->Check_if_result_is_address(htable->Sym());
00613
00614 aux_preg->Set_LPRE_VNFRE_temp();
00615 wk->Set_preg(id);
00616 aux_preg->Set_value_size(vsize);
00617
00618
00619 if (addressable == ADDRESSABILITY_IS_ADDRESS)
00620 aux_preg->Set_is_address();
00621 else if (addressable == ADDRESSABILITY_NOT_ADDRESS)
00622 aux_preg->Set_not_address();
00623
00624 if (signess & SIGN_1_EXTD) aux_preg->Set_sign_extd();
00625 if (signess & SIGN_0_EXTD) aux_preg->Set_zero_extd();
00626 }
00627 break;
00628
00629 case PK_EPRE:
00630 {
00631 #ifndef TARG_NVISA
00632 AUX_ID id = htable->Sym()->Create_preg(dtyp);
00633 #else
00634 AUX_ID id = htable->Sym()->Create_preg(dtyp, "epre_cst", home_wn);
00635 #endif
00636 AUX_STAB_ENTRY *aux_preg = htable->Sym()->Aux_stab_entry(id);
00637 ADDRESSABILITY addressable = Occurrence()->Check_if_result_is_address(htable->Sym());
00638 wk->Set_preg(id);
00639 aux_preg->Set_EPRE_temp();
00640 aux_preg->Set_value_size(vsize);
00641
00642 if (addressable == ADDRESSABILITY_IS_ADDRESS)
00643 aux_preg->Set_is_address();
00644 else if (addressable == ADDRESSABILITY_NOT_ADDRESS)
00645 aux_preg->Set_not_address();
00646
00647
00648 if (exp->Is_integral_load_store()) {
00649 if (wk->Sign_extd())
00650 aux_preg->Set_sign_extd();
00651 else
00652 aux_preg->Set_zero_extd();
00653 } else {
00654 if (signess & SIGN_1_EXTD) aux_preg->Set_sign_extd();
00655 if (signess & SIGN_0_EXTD) aux_preg->Set_zero_extd();
00656 }
00657 break;
00658 }
00659 case PK_LPRE:
00660 {
00661 #ifndef TARG_NVISA // done above
00662 WN *home_wn = exp->Rvi_home_wn(htable->Sym());
00663 #endif
00664 if (inCODEKIND(exp->Kind(), CK_LDA|CK_RCONST|CK_CONST)) {
00665 wk->Set_preg(htable->Sym()->Create_preg(dtyp, "lpre_cst", home_wn));
00666 AUX_STAB_ENTRY *aux_preg = htable->Sym()->Aux_stab_entry(wk->Preg());
00667 aux_preg->Set_LPRE_VNFRE_temp();
00668 aux_preg->Set_value_size(vsize);
00669 if (signess & SIGN_1_EXTD) aux_preg->Set_sign_extd();
00670 if (signess & SIGN_0_EXTD) aux_preg->Set_zero_extd();
00671 } else {
00672 #ifdef KEY // Bug 9821: Set the alias map id.
00673 if (home_wn)
00674 htable->Sym()->Alias_Mgr()->Gen_alias_id (home_wn,
00675 exp->Points_to(htable->Sym()));
00676 #endif
00677
00678 AUX_ID aux_id = exp->Aux_id();
00679 const char *aux_name = htable->Sym()->Aux_stab_entry(aux_id)->St_name();
00680 wk->Set_preg(htable->Sym()->Create_preg(dtyp, aux_name, home_wn));
00681
00682
00683
00684
00685
00686 AUX_STAB_ENTRY *aux_entry = htable->Sym()->Aux_stab_entry(aux_id);
00687 AUX_STAB_ENTRY *aux_preg = htable->Sym()->Aux_stab_entry(wk->Preg());
00688
00689 Is_True(aux_entry->Home_sym() == 0,
00690 ("EXP_OCCURS::Get_temp_cr: variable already has home PREG"));
00691 aux_entry->Set_home_sym(wk->Preg());
00692
00693 aux_preg->Set_home_sym(aux_id);
00694 aux_preg->Set_LPRE_VNFRE_temp();
00695 aux_preg->Set_value_size(vsize);
00696 if (wk->Sign_extd())
00697 aux_preg->Set_sign_extd();
00698 else
00699 aux_preg->Set_zero_extd();
00700
00701 if (wk->Sign_extd())
00702 aux_preg->Set_LPRE_sign_extd();
00703 }
00704 break;
00705 }
00706 default:
00707 Is_True(FALSE, ("EXP_OCCURS::Get_temp_cr: wrong PRE_KIND."));
00708 }
00709 }
00710
00711
00712 Set_temp_cr(htable->Add_def(wk->Preg(), wk->Cur_e_version(), NULL,
00713 dtyp, dtyp, htable->Sym()->St_ofst(wk->Preg()),
00714 #ifdef KEY
00715 Occurrence()->Kind() == CK_VAR ? Occurrence()->Lod_ty() :
00716 #endif
00717 ST_type(MTYPE_To_PREG(dtyp)),
00718 0, TRUE));
00719 wk->New_e_version();
00720
00721 if (wk->Pre_kind() == PK_VNFRE)
00722 VNFRE::add_valnum(Temp_cr(), wk->E_num());
00723
00724 return Temp_cr();
00725 }
00726
00727
00728 CODEREP *
00729 ETABLE::New_temp_cr(MTYPE dtype, ADDRESSABILITY addressable, CODEREP *rhs)
00730 {
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754 const INT32 init_version = EXP_OCCURS::ILLEGAL_E_VERSION + 1;
00755 INT32 vsize = MTYPE_size_min(dtype);
00756
00757 Is_True(vsize >= 32,
00758 ("Unexpected size of result type in EXP_OCCURS::New_temp_cr"));
00759
00760 #ifdef TARG_NVISA
00761 WN *home_wn = rhs->Rvi_home_wn(Htable()->Sym());
00762 AUX_ID id = Htable()->Sym()->Create_preg(dtype, "new_cst", home_wn);
00763 #else
00764 AUX_ID id = Htable()->Sym()->Create_preg(dtype);
00765 #endif
00766 AUX_STAB_ENTRY *aux_preg = Htable()->Sym()->Aux_stab_entry(id);
00767
00768 if (Pre_kind() == PK_LPRE || Pre_kind() == PK_VNFRE)
00769 aux_preg->Set_LPRE_VNFRE_temp();
00770 else aux_preg->Set_EPRE_temp();
00771 aux_preg->Set_value_size(vsize);
00772
00773
00774
00775 if (addressable == ADDRESSABILITY_IS_ADDRESS)
00776 aux_preg->Set_is_address();
00777 else if (addressable == ADDRESSABILITY_NOT_ADDRESS)
00778 aux_preg->Set_not_address();
00779
00780 if (MTYPE_is_signed(dtype)) aux_preg->Set_sign_extd();
00781 if (MTYPE_is_unsigned(dtype)) aux_preg->Set_zero_extd();
00782
00783
00784
00785 return Htable()->Add_def(id, init_version, NULL,
00786 dtype, dtype, Htable()->Sym()->St_ofst(id),
00787 ST_type(MTYPE_To_PREG(dtype)), 0, TRUE);
00788 }
00789
00790
00791
00792
00793
00794
00795 BOOL
00796 EXP_OCCURS::Is_DT_descendant_of( EXP_OCCURS *anc )
00797 {
00798 Warn_todo("EXP_OCCURS::Is_DT_descendant_of: not implemented");
00799 return FALSE;
00800 }
00801
00802 BOOL
00803 STMTREP::Stmt_order_less_or_equal(const STMTREP *const x) const
00804 {
00805 Is_True(Stmt_id() != INVALID_STMT_ID,
00806 ("EXP_OCCURS::Stmt_order_less_or_equal: Stmt_id not set"));
00807 Is_True(x->Stmt_id() != INVALID_STMT_ID,
00808 ("EXP_OCCURS::Stmt_order_less_or_equal: Stmt_id not set"));
00809 if (Stmt_id() < x->Stmt_id())
00810 return TRUE;
00811 else if (Stmt_id() > x->Stmt_id())
00812 return FALSE;
00813 else {
00814
00815
00816
00817 const STMTREP *cur = this;
00818 if (cur == x) return TRUE;
00819
00820 INT32 stmt_id = cur->Stmt_id();
00821 for (cur = cur->Next();
00822 cur && cur->Stmt_id() == stmt_id;
00823 cur = cur->Next()){
00824 if (cur == x) return TRUE;
00825 }
00826 return FALSE;
00827 }
00828 }
00829
00830
00831
00832 BOOL
00833 EXP_OCCURS::Is_DPO_less_than(EXP_OCCURS *x)
00834 {
00835 if (For_spre()) {
00836
00837
00838 if (Bb()->Pdom_dfs_id() < x->Bb()->Pdom_dfs_id())
00839 return TRUE;
00840 if (Bb() == x->Bb()) {
00841 return Occ_kind() <= x->Occ_kind();
00842 }
00843 }
00844 else {
00845
00846
00847 if (Bb()->Dom_dfs_id() < x->Bb()->Dom_dfs_id())
00848 return TRUE;
00849
00850
00851
00852 if (Bb() == x->Bb()) {
00853 if ((Occ_kind() == OCC_COMP_OCCUR || Occ_kind() == OCC_REAL_OCCUR) &&
00854 x->Occurs_as_hoisted()) {
00855
00856 OPCODE opc = Stmt()->Op();
00857 if (opc == OPC_COMPGOTO ||
00858 opc == OPC_AGOTO ||
00859 opc == OPC_TRUEBR ||
00860 opc == OPC_FALSEBR)
00861 return FALSE;
00862 else
00863 return TRUE;
00864 }
00865 if ((x->Occ_kind() == OCC_COMP_OCCUR || x->Occ_kind() == OCC_REAL_OCCUR) &&
00866 Occurs_as_hoisted()) {
00867
00868 OPCODE opc = x->Stmt()->Op();
00869 if (opc == OPC_COMPGOTO ||
00870 opc == OPC_AGOTO ||
00871 opc == OPC_TRUEBR ||
00872 opc == OPC_FALSEBR)
00873 return TRUE;
00874 else
00875 return FALSE;
00876 }
00877
00878 if ((Occ_kind() == OCC_COMP_OCCUR || Occ_kind() == OCC_REAL_OCCUR) &&
00879 (x->Occ_kind() == OCC_COMP_OCCUR || x->Occ_kind() == OCC_REAL_OCCUR)){
00880
00881
00882 return Stmt_order_less_or_equal(x);
00883 }
00884 else
00885 return Occ_kind() <= x->Occ_kind();
00886 }
00887 }
00888
00889
00890 return FALSE;
00891 }
00892
00893 void
00894 EXP_OCCURS::Render_coderep_unownable(const ETABLE *const etable,
00895 ID_MAP<REHASH_INFO *, INT32> & id_map)
00896 {
00897 REHASH_INFO *rehash_info = id_map.Lookup(Occurrence()->Coderep_id());
00898
00899 if (Occurrence()->Is_flag_set(CF_OWNED_BY_TEMP)) {
00900 Is_True(rehash_info != NULL, ("EXP_OCCURS::Render_coderep_unownable: "
00901 "Owned coderep must occur in ID map"));
00902 rehash_info->Owning_t_ver()->Reset_t_ver_owns_coderep();
00903 Occurrence()->Reset_flag(CF_OWNED_BY_TEMP);
00904 }
00905
00906 if (rehash_info == NULL) {
00907 rehash_info = CXX_NEW(REHASH_INFO(Occurrence()),
00908 etable->Etable_local_pool());
00909 id_map.Insert(Occurrence()->Coderep_id(), rehash_info);
00910 }
00911 rehash_info->Set_coderep_unownable();
00912 }
00913
00914 void
00915 EXP_OCCURS::Bid_for_coderep(const ETABLE *const etable,
00916 ID_MAP<REHASH_INFO *, INT32> & id_map,
00917 const UINT32 rehash_cost)
00918 {
00919 REHASH_INFO *rehash_info = id_map.Lookup(Occurrence()->Coderep_id());
00920
00921 if (rehash_info == NULL) {
00922 rehash_info = CXX_NEW(REHASH_INFO(Occurrence()),
00923 etable->Etable_local_pool());
00924 id_map.Insert(Occurrence()->Coderep_id(), rehash_info);
00925 }
00926
00927 if (!rehash_info->Coderep_unownable() &&
00928 (rehash_info->Owning_t_ver() == NULL ||
00929 rehash_info->Max_rehash_cost() < rehash_cost)) {
00930 if (Occurrence()->Omitted()) {
00931
00932
00933
00934
00935
00936
00937
00938 rehash_info->Set_coderep_unownable();
00939 }
00940 else {
00941 rehash_info->Set_max_rehash_cost(rehash_cost);
00942 if (rehash_info->Owning_t_ver() != NULL) {
00943
00944
00945 rehash_info->Owning_t_ver()->Reset_t_ver_owns_coderep();
00946 }
00947 else {
00948 rehash_info->Coderep()->Set_flag(CF_OWNED_BY_TEMP);
00949 }
00950 rehash_info->Set_owning_t_ver(this);
00951 Set_t_ver_owns_coderep();
00952 }
00953 }
00954 }
00955
00956
00957
00958
00959
00960
00961 EXP_OCCURS *
00962 EXP_OCCURS::Occ_identical_to(void)
00963 {
00964 OCC_KIND kind = Occ_kind();
00965 EXP_OCCURS *identical_to = NULL;
00966
00967 if (kind == OCC_REAL_OCCUR) {
00968 Is_True(Save_to_temp(),
00969 ("EXP_OCCURS::Identical_to: real occurrence "
00970 "must be saved"));
00971 return this;
00972 }
00973 else if (kind == OCC_PHI_PRED_OCCUR) {
00974 Is_True(Inserted_computation() || Sunk_lvalue(),
00975 ("EXP_OCCURS::Identical_to: phi-pred occurrence "
00976 "must be inserted"));
00977 return this;
00978 }
00979 else if (kind == EXP_OCCURS::OCC_PHI_OCCUR) {
00980 if (Exp_phi()->Identity() &&
00981 Exp_phi()->Replacing_occur_known()) {
00982 Is_True(Exp_phi()->Identical_to() != NULL,
00983 ("EXP_OCCURS::Identical_to: known replacing occur "
00984 "must be non-NULL"));
00985 return Exp_phi()->Identical_to();
00986 }
00987 else if (!Exp_phi()->Identity()) {
00988 return this;
00989 }
00990 }
00991 return NULL;
00992 }
00993
00994 EXP_OCCURS::EXP_OCCURS(CODEREP *occurrence,
00995 STMTREP *enclose_stmt,
00996 EXP_PHI *exp_phi,
00997 BOOL is_real_occurrence)
00998 {
00999
01000
01001 Set_occurrence(occurrence);
01002 Clear_temp_cr();
01003 Set_e_version(EXP_OCCURS::ILLEGAL_E_VERSION);
01004 Clear_flags();
01005 if (is_real_occurrence) {
01006 Set_kind(OCC_REAL_OCCUR);
01007 Set_enclose_stmt(enclose_stmt);
01008 Set_rehash_cost(0);
01009 } else {
01010 Set_kind(OCC_PHI_OCCUR);
01011 Set_exp_phi(exp_phi);
01012 }
01013 }
01014
01015
01016 EXP_OCCURS*
01017 ETABLE::New_phi_occurrence(EXP_WORKLST *worklst,
01018 MEM_POOL *pool,
01019 BB_NODE *bb)
01020 {
01021 EXP_PHI *new_phi = CXX_NEW(EXP_PHI(worklst->E_num(),
01022 bb->Iphi_list()->Out_degree(),
01023 bb, pool), pool);
01024 EXP_OCCURS *occurs = Alloc_occurs_node();
01025 occurs->Set_occurrence(NULL);
01026 occurs->Set_kind(EXP_OCCURS::OCC_PHI_OCCUR);
01027 occurs->Set_exp_phi(new_phi);
01028 new_phi->Set_result(occurs);
01029 occurs->Set_spre_wk(worklst);
01030
01031 return occurs;
01032 }
01033
01034 void
01035 EXP_OCCURS_CONTAINER::Init(void)
01036 {
01037 Set_Head(NULL);
01038 Set_Tail(NULL);
01039 }
01040
01041 EXP_OCCURS *
01042 OCC_ITER_LIST::Get_cur(void) const
01043 {
01044 return (Is_occ_iter()) ? Occ_iter()->Cur() :
01045 All_real_iter()->Cur();
01046 }
01047
01048 EXP_OCCURS *
01049 OCC_ITER_LIST::Next_occ(void) const
01050 {
01051 return (Is_occ_iter()) ? Occ_iter()->Next() :
01052 All_real_iter()->Next();
01053 }
01054
01055 void
01056 OCC_CONTAINER::Insert_sort(OCC_ITER_LIST *l)
01057 {
01058 EXP_OCCURS *l_cur = l->Get_cur();
01059
01060 if (l_cur == NULL) return;
01061
01062
01063 OCC_ITER_LIST_ITER occ_iter_list_iter(this);
01064 OCC_ITER_LIST *tmp, *prev = NULL;
01065 FOR_ALL_NODE(tmp, occ_iter_list_iter, Init()) {
01066 EXP_OCCURS *exp_tmp = tmp->Get_cur();
01067 if (exp_tmp->Is_DPO_less_than(l_cur))
01068 prev = tmp;
01069 else
01070 break;
01071 }
01072 if (prev == NULL)
01073 Prepend(l);
01074 else if (prev == Tail())
01075 Append(l);
01076 else
01077 prev->Insert_After(l);
01078 }
01079
01080 EXP_ALL_REAL_ITER::EXP_ALL_REAL_ITER(EXP_OCCURS *real_occ,
01081 EXP_OCCURS_PAIR *comp_occ):
01082 _real(real_occ),
01083 _real_iter(&_real),
01084 _comp1_iter(&_comp1),
01085 _comp2_iter(&_comp2)
01086 {
01087 if (comp_occ) {
01088 _comp1.Init( comp_occ->Occ1() );
01089 _comp2.Init( comp_occ->Occ2() );
01090 }
01091 }
01092
01093 EXP_OCCURS*
01094 EXP_ALL_REAL_ITER::Get_cur(void) const
01095 {
01096 const OCC_ITER_LIST *first_iter = _all_iter.Head();
01097 if (first_iter == NULL) return NULL;
01098 return first_iter->Get_cur();
01099 }
01100
01101 EXP_OCCURS*
01102 EXP_ALL_REAL_ITER::First(void)
01103 {
01104 if (this == NULL)
01105 return NULL;
01106
01107
01108 _real.First();
01109 _comp1.First();
01110 _comp2.First();
01111
01112 _all_iter.Insert_sort(&_real_iter);
01113 _all_iter.Insert_sort(&_comp1_iter);
01114 _all_iter.Insert_sort(&_comp2_iter);
01115
01116 return Get_cur();
01117 }
01118
01119 EXP_OCCURS*
01120 EXP_ALL_REAL_ITER::Next(void)
01121 {
01122 OCC_ITER_LIST *first_iter = _all_iter.Head();
01123 if (first_iter == NULL) return NULL;
01124
01125 EXP_OCCURS *retval = first_iter->Get_cur();
01126 EXP_OCCURS *next = first_iter->Next_occ();
01127
01128 if (next == NULL) {
01129 _all_iter.Remove_Headnode();
01130 }
01131 else {
01132 _all_iter.Remove_Headnode();
01133 _all_iter.Insert_sort(first_iter);
01134 }
01135
01136 EXP_OCCURS *result = Get_cur();
01137
01138 Is_True((result==NULL) || retval->Is_DPO_less_than(result),
01139 ("EXP_ALL_OCCURS_ITER::Next(): Not dpo order"));
01140
01141 return result;
01142 }
01143
01144 BOOL
01145 EXP_ALL_REAL_ITER::Is_Empty(void) const
01146 {
01147 return Get_cur() == NULL;
01148 }
01149
01150 EXP_ALL_OCCURS_ITER::EXP_ALL_OCCURS_ITER(EXP_OCCURS *real,
01151 EXP_OCCURS_PAIR *comp,
01152 EXP_OCCURS *phi,
01153 EXP_OCCURS *phi_pred,
01154 EXP_OCCURS *exit):
01155 _real(real,comp),
01156 _phi(phi),
01157 _phi_pred(phi_pred),
01158 _exit(exit),
01159 _real_iter(&_real),
01160 _phi_iter(&_phi),
01161 _pred_iter(&_phi_pred),
01162 _exit_iter(&_exit)
01163 {
01164 _fast_array = NULL;
01165 }
01166
01167
01168 EXP_ALL_OCCURS_ITER::EXP_ALL_OCCURS_ITER(EXP_WORKLST *worklst,
01169 ETABLE *etable, LFTR *lftr):
01170 _real(worklst->Real_occurs().Head(), lftr->Exp_hash(worklst)),
01171 _phi(worklst->Phi_occurs().Head()),
01172 _phi_pred(worklst->Phi_pred_occurs().Head()),
01173 _exit(etable->Exit_occurs().Head()),
01174 _real_iter(&_real),
01175 _phi_iter(&_phi),
01176 _pred_iter(&_phi_pred),
01177 _exit_iter(&_exit)
01178 {
01179
01180 INT32 size = worklst->Real_occurs().Len() +
01181 worklst->Phi_occurs().Len() +
01182 worklst->Phi_pred_occurs().Len() +
01183 etable->Exit_occurs().Len();
01184 if (lftr->Lftr_on())
01185 size += lftr->Len();
01186
01187 if (lftr->Lftr_on()) {
01188 Is_Trace(lftr->Trace(),(TFile,"PPP LFTR size = %d\n",
01189 lftr->Len()));
01190 }
01191
01192 #ifdef XXX
01193
01194 _fast_array = (EXP_OCCURS **) CXX_NEW_ARRAY(EXP_OCCURS, size, mem_pool);
01195
01196 EXP_OCCURS *occur;
01197 EXP_ALL_OCCURS_ITER *exp_occ_iter = this;
01198 INT32 i = 0;
01199 FOR_ALL_NODE(occur, *exp_occ_iter, Init()) {
01200 _fast_array[i++] = occur;
01201 Is_True(i < size,("EXP_ALL_OCCURS_ITER::Fill_fast_array, array overflow"));
01202 }
01203 #endif
01204 }
01205
01206 EXP_OCCURS*
01207 EXP_ALL_OCCURS_ITER::Get_cur(void) const
01208 {
01209 const OCC_ITER_LIST *first_iter = _all_iter.Head();
01210 if (first_iter == NULL) return NULL;
01211 return first_iter->Get_cur();
01212 }
01213
01214 EXP_OCCURS*
01215 EXP_ALL_OCCURS_ITER::Next(void)
01216 {
01217 OCC_ITER_LIST *first_iter = _all_iter.Head();
01218 if (first_iter == NULL) return NULL;
01219
01220 EXP_OCCURS *retval = first_iter->Get_cur();
01221 EXP_OCCURS *next = first_iter->Next_occ();
01222
01223 if (next == NULL) {
01224 _all_iter.Remove_Headnode();
01225 }
01226 else if (retval->Bb() != next->Bb()) {
01227 _all_iter.Remove_Headnode();
01228 _all_iter.Insert_sort(first_iter);
01229 }
01230
01231 EXP_OCCURS *result = Get_cur();
01232
01233 Is_True((result==NULL) || retval->Is_DPO_less_than(result),
01234 ("EXP_ALL_OCCURS_ITER::Next(): Not dpo order"));
01235
01236 return result;
01237 }
01238
01239 EXP_OCCURS*
01240 EXP_ALL_OCCURS_ITER::First(void)
01241 {
01242 if (this == NULL)
01243 return NULL;
01244
01245
01246 _phi.First();
01247 _real.First();
01248 _phi_pred.First();
01249 _exit.First();
01250
01251 _all_iter.Insert_sort(&_phi_iter);
01252 _all_iter.Insert_sort(&_real_iter);
01253 _all_iter.Insert_sort(&_pred_iter);
01254 _all_iter.Insert_sort(&_exit_iter);
01255
01256 return Get_cur();
01257 }
01258
01259 BOOL
01260 EXP_ALL_OCCURS_ITER::Is_Empty(void) const
01261 {
01262 return Get_cur() == NULL;
01263 }
01264
01265 void
01266 EXP_ALL_OCCURS_ITER::Remove_iter(void)
01267 {
01268
01269 }
01270
01271 void
01272 EXP_WORKLST::Init(IDTYPE e_num, CODEREP *exp)
01273 {
01274 Set_Next(NULL);
01275 _e_num = e_num;
01276 _exp = exp;
01277 Set_preg(ILLEGAL_PREG);
01278 _u1._iphi_bbs = NULL;
01279 _real_occurs.Init();
01280 _phi_occurs.Init();
01281 _phi_pred_occurs.Init();
01282 Clear_flags();
01283 Reset_statistics();
01284 Init_e_version();
01285 }
01286
01287
01288
01289 void
01290 EXP_WORKLST::Exam_const(void)
01291 {
01292 if (Exp()->Kind() != CK_OP) return;
01293 for (INT i = 0; i < Exp()->Kid_count(); i++) {
01294 switch (Exp()->Get_opnd(i)->Kind()) {
01295 case CK_CONST:
01296 Set_has_const();
01297 break;
01298 case CK_RCONST:
01299 Set_has_rconst();
01300 break;
01301 case CK_LDA:
01302 Set_has_lda();
01303 break;
01304 }
01305 }
01306 }
01307
01308
01309 BOOL
01310 EXP_WORKLST::Verify_dpo_order(EXP_OCCURS_CONTAINER &worklist, EXP_OCCURS *occ)
01311 {
01312 EXP_OCCURS *tail = worklist.Tail();
01313 Is_True(!tail || tail->Is_DPO_less_than(occ),
01314 ("EXP_WORKLST::Verify_dpo_order: Not dpo order"));
01315 return TRUE;
01316 }
01317
01318 BOOL
01319 EXP_WORKLST::Verify_dpo_order(EXP_OCCURS_CONTAINER &worklist)
01320 {
01321 EXP_OCCURS *occ_pre = worklist.Head();
01322 EXP_OCCURS *occ_cur;
01323 EXP_OCCURS_ITER exp_occ_iter;
01324 FOR_ALL_NODE(occ_cur, exp_occ_iter, Init(worklist.Head()->Next())) {
01325 Is_True(occ_pre->Is_DPO_less_than(occ_cur),
01326 ("EXP_WORKLST::Verify_dpo_order: Not dpo order"));
01327 occ_pre = occ_cur;
01328 }
01329 return TRUE;
01330 }
01331
01332
01333
01334 void
01335 EXP_WORKLST::Append_occurrence(EXP_OCCURS *occ)
01336 {
01337 switch (occ->Occ_kind()) {
01338 case EXP_OCCURS::OCC_REAL_OCCUR:
01339 Is_True(Verify_dpo_order(Real_occurs(), occ),
01340 ("EXP_WORKLST::Append_occurrence: failed dpo_order test"));
01341 Real_occurs().Append(occ);
01342 break;
01343 case EXP_OCCURS::OCC_PHI_OCCUR:
01344 Is_True(Verify_dpo_order(Phi_occurs(), occ),
01345 ("EXP_WORKLST::Append_occurrence: failed dpo_order test"));
01346 Phi_occurs().Append(occ);
01347 break;
01348 case EXP_OCCURS::OCC_PHI_PRED_OCCUR:
01349 Is_True(Verify_dpo_order(Phi_pred_occurs(), occ),
01350 ("EXP_WORKLST::Append_occurrence: failed dpo_order test"));
01351 Phi_pred_occurs().Append(occ);
01352 break;
01353 default:
01354 Is_True(FALSE,("EXP_WORKLST::Append_occurrence: Illegal occurrence type"));
01355 break;
01356 }
01357 }
01358
01359
01360
01361
01362
01363
01364 void
01365 EXP_WORKLST::Insert_occurrence(EXP_OCCURS *occ, BB_NODE *bb)
01366 {
01367 Is_True(occ->Occ_kind() == EXP_OCCURS::OCC_REAL_OCCUR,
01368 ("EXP_WORKLST::Insert_occurrence: insert not implemented "
01369 "for non-real occ"));
01370
01371 EXP_OCCURS *real_occ;
01372 EXP_OCCURS_ITER real_occ_iter;
01373
01374 EXP_OCCURS *prev_occ = NULL;
01375 FOR_ALL_NODE(real_occ, real_occ_iter, Init(Real_occurs().Head())) {
01376 if (bb->Dom_dfs_id() < real_occ->Bb()->Dom_dfs_id()) {
01377
01378
01379 break;
01380 }
01381 prev_occ = real_occ;
01382 }
01383
01384
01385
01386
01387 if (real_occ != NULL) {
01388
01389
01390
01391
01392 OPCODE opc;
01393 if (prev_occ != NULL &&
01394 prev_occ->Bb() == bb &&
01395 ((opc = prev_occ->Stmt()->Op()) == OPC_COMPGOTO ||
01396 opc == OPC_AGOTO ||
01397 opc == OPC_TRUEBR ||
01398 opc == OPC_FALSEBR)) {
01399 BOOL success = Real_occurs().Prepend(occ, prev_occ);
01400 Is_True(success, ("EXP_WORKLST::Insert_occurrence failed!"));
01401 } else {
01402 BOOL success = Real_occurs().Prepend(occ, real_occ);
01403 Is_True(success, ("EXP_WORKLST::Insert_occurrence failed!"));
01404 }
01405 }
01406 else {
01407
01408
01409
01410 Real_occurs().Append(occ);
01411 }
01412 Is_True(Verify_dpo_order(Real_occurs()),
01413 ("EXP_WORKLST::Insert_occurrence: Not in DPO order after "
01414 "real_occurrence insertion"));
01415 }
01416
01417 void
01418 ETABLE::Add_to_occ_freelist(EXP_OCCURS *node)
01419 {
01420 if (node != NULL) {
01421 CODEREP *cr = (CODEREP*)node->Occurrence();
01422
01423
01424 if (Pre_kind() != PK_EPRE &&
01425 (cr && (node->Occ_kind() == EXP_OCCURS::OCC_REAL_OCCUR ||
01426 node->Occ_kind() == EXP_OCCURS::OCC_COMP_OCCUR)))
01427 cr->Set_Bitpos(ILLEGAL_BP);
01428 if (node->Occ_kind() == EXP_OCCURS::OCC_PHI_OCCUR) {
01429 node->Exp_phi()->Bb()->Set_exp_phi(NULL);
01430 }
01431 Occ_freelist()->Push(node);
01432 }
01433 }
01434
01435 void
01436 EXP_WORKLST::Insert_occurrence(EXP_OCCURS *occ, ETABLE *etable)
01437 {
01438 Is_True(occ->Occ_kind() == EXP_OCCURS::OCC_REAL_OCCUR,
01439 ("EXP_WORKLST::Insert_occurrence: insert not implemented "
01440 "for non-real occ"));
01441
01442 EXP_OCCURS *real_occ;
01443 EXP_OCCURS_ITER real_occ_iter;
01444 EXP_OCCURS *real_pred = NULL;
01445
01446 FOR_ALL_NODE(real_occ, real_occ_iter, Init(Real_occurs().Head())) {
01447 if (real_occ->Bb()->Dom_dfs_id() > occ->Bb()->Dom_dfs_id()) {
01448
01449
01450 break;
01451 }
01452 if (real_occ->Bb() == occ->Bb()) {
01453 if (!real_occ->Stmt_order_less_or_equal(occ))
01454 break;
01455 else if (real_occ->Stmt() == occ->Stmt()) {
01456 if (real_occ->Stmt_kid_num() > occ->Stmt_kid_num())
01457 break;
01458 }
01459 }
01460 real_pred = real_occ;
01461 }
01462 if (real_pred != NULL) {
01463 if (real_pred->Enclosed_in_stmt() == occ->Enclosed_in_stmt() &&
01464 real_pred->Stmt_kid_num() == occ->Stmt_kid_num()) {
01465 real_pred->Set_mult_real();
01466 etable->Add_to_occ_freelist(occ);
01467 }
01468 else {
01469 real_pred->Insert_After(occ);
01470 }
01471 }
01472 else if (real_occ == NULL)
01473 Real_occurs().Append(occ);
01474 else
01475 Real_occurs().Prepend(occ);
01476
01477 Is_True(Verify_dpo_order(Real_occurs()),
01478 ("EXP_WORKLST::Insert_occurrence: Not in DPO order after "
01479 "real_occurrence insertion"));
01480
01481 }
01482
01483
01484
01485
01486
01487
01488 static BOOL
01489 Are_different(CODEREP *cr1, CODEREP *cr2)
01490 {
01491 if (cr1 == cr2) return FALSE;
01492 if (cr1->Kind() != cr2->Kind()) return TRUE;
01493
01494 switch (cr1->Kind()) {
01495 case CK_VAR:
01496 return cr1->Aux_id() != cr2->Aux_id();
01497 case CK_IVAR:
01498 if (cr1->Opr() == OPR_PARM ) {
01499
01500 if ( cr1->Op() != cr2->Op() ) return TRUE;
01501
01502
01503 if (Are_different( cr1->Ilod_base(), cr2->Ilod_base()))
01504 return TRUE;
01505
01506 if ((cr1->Ivar_mu_node() == NULL) != (cr2->Ivar_mu_node() == NULL))
01507 return TRUE;
01508
01509 return FALSE;
01510 }
01511 Is_True(FALSE, ("EXP_WORKLST::Are_different: must not reach here."));
01512 case CK_OP:
01513 Is_True(FALSE, ("EXP_WORKLST::Are_different: must not reach here."));
01514 case CK_LDA:
01515 case CK_CONST:
01516 case CK_RCONST:
01517 default:
01518 return TRUE;
01519 }
01520 }
01521
01522
01523
01524
01525
01526
01527
01528 BOOL
01529 EXP_WORKLST::Is_the_same_as(const CODEREP *cr)
01530 {
01531
01532 #ifdef Is_True_On
01533 if (Pre_kind() == PK_LPRE) {
01534 Is_True(inCODEKIND(Exp()->Kind(), CK_CONST|CK_RCONST|CK_LDA|CK_VAR),
01535 ("EXP_WORKLST::Is_the_same_as(cr), not a leaf node, kind=0x%x",
01536 Exp()->Kind()));
01537 Is_True(inCODEKIND(Exp()->Kind(), CK_CONST|CK_RCONST|CK_LDA|CK_VAR),
01538 ("EXP_WORKLST::Is_the_same_as(cr), not a leaf node, kind=0x%x",
01539 cr->Kind()));
01540 }
01541 else if (Pre_kind() == PK_SPRE) {
01542 Is_True(Exp()->Kind() == CK_VAR,
01543 ("EXP_WORKLST::Is_the_same_as(cr), not a VAR, kind=0x%x",
01544 Exp()->Kind()));
01545 Is_True(cr->Kind() == CK_VAR,
01546 ("EXP_WORKLST::Is_the_same_as(cr), not a VAR, kind=0x%x",
01547 cr->Kind()));
01548 }
01549 else {
01550 Is_True(Exp()->Non_leaf(),
01551 ("EXP_WORKLST::Is_the_same_as(cr), not a OP or IVAR, kind=0x%x",
01552 Exp()->Kind()));
01553 Is_True(cr->Non_leaf(),
01554 ("EXP_WORKLST::Is_the_same_as(cr), not a OP or IVAR, kind=0x%x",
01555 cr->Kind()));
01556 }
01557 #endif
01558
01559 if (Exp() == cr) return TRUE;
01560
01561 if (Exp()->Kind() != cr->Kind()) return FALSE;
01562
01563
01564 if (inCODEKIND(cr->Kind(), CK_CONST|CK_RCONST|CK_LDA) ||
01565 inCODEKIND(Exp()->Kind(), CK_CONST|CK_RCONST|CK_LDA)) return FALSE;
01566
01567 if (Pre_kind() == PK_LPRE || Pre_kind() == PK_SPRE)
01568 return Exp()->Aux_id() == cr->Aux_id();
01569
01570 if (Exp()->Kind() == CK_IVAR && cr->Kind() == CK_IVAR) {
01571 if (Exp()->Opr() != cr->Opr())
01572 return FALSE;
01573
01574 CODEREP *gcr = Exp()->Ilod_base();
01575 CODEREP *lcr = cr->Ilod_base();
01576 if (gcr == NULL)
01577 gcr = Exp()->Istr_base();
01578 if (lcr == NULL)
01579 lcr = cr->Istr_base();
01580 if (Are_different(lcr, gcr))
01581 return FALSE;
01582
01583 if (cr->Opr() == OPR_ILOADX) {
01584 if (Are_different(cr->Index(), Exp()->Index()))
01585 return FALSE;
01586 }
01587 else {
01588 if (cr->Offset() != Exp()->Offset())
01589 return FALSE;
01590 }
01591 if (Get_mtype_class(cr->Dtyp()) != Get_mtype_class(Exp()->Dtyp()))
01592 return FALSE;
01593 if (MTYPE_size_min(cr->Dsctyp()) != MTYPE_size_min(Exp()->Dsctyp()))
01594 return FALSE;
01595
01596 if (cr->Ivar_occ()->Aux_id() != Exp()->Ivar_occ()->Aux_id())
01597 return FALSE;
01598
01599 if (cr->Opr() == OPR_MLOAD) {
01600 gcr = Exp()->Mload_size();
01601 if (gcr == NULL)
01602 gcr = Exp()->Mstore_size();
01603 lcr = cr->Mload_size();
01604 if (lcr == NULL)
01605 lcr = cr->Mstore_size();
01606 if (Are_different(lcr, gcr))
01607 return FALSE;
01608 }
01609 else if (OPERATOR_is_scalar_iload (cr->Opr())) {
01610
01611 const TY_IDX exp_addr_ty = Exp()->Ilod_base_ty();
01612 const TY_IDX cr_addr_ty = cr->Ilod_base_ty();
01613 if (exp_addr_ty != cr_addr_ty) {
01614 if (! exp_addr_ty || ! cr_addr_ty)
01615 return FALSE;
01616 if (TY_kind(exp_addr_ty) != KIND_POINTER)
01617 return FALSE;
01618 if (TY_kind(cr_addr_ty) != KIND_POINTER)
01619 return FALSE;
01620 if (TY_align_exp(TY_pointed(exp_addr_ty)) !=
01621 TY_align_exp(TY_pointed(cr_addr_ty)))
01622 return FALSE;
01623 }
01624 if (cr->Opr() == OPR_ILDBITS) {
01625 if (cr->I_bit_offset() != Exp()->I_bit_offset () ||
01626 cr->I_bit_size() != Exp()->I_bit_size ())
01627 return FALSE;
01628 }
01629 }
01630
01631
01632 if ((Exp()->Opr() == OPR_PARM) != (cr->Opr() == OPR_PARM))
01633 return FALSE;
01634
01635 return TRUE;
01636 }
01637 else {
01638 if (Exp()->Op() != cr->Op()) return FALSE;
01639
01640 if (Exp()->Kid_count() != cr->Kid_count())
01641 return FALSE;
01642
01643 #ifdef Is_True_On
01644 if (OPCODE_commutative_op(cr->Op()) == cr->Op()) {
01645
01646
01647
01648 if (!Are_different(cr->Opnd(0), Exp()->Opnd(1)) &&
01649 !Are_different(cr->Opnd(1), Exp()->Opnd(0)) &&
01650 Are_different(cr->Opnd(0), cr->Opnd(1))) {
01651 DevWarn("EXP_WORKLST::Is_the_same_as: expr not canonicalized.");
01652 return FALSE;
01653 }
01654 }
01655 #endif
01656
01657 for (IDX_32 i=0; i<Exp()->Kid_count(); i++) {
01658 if (Are_different(cr->Opnd(i),Exp()->Opnd(i)))
01659 return FALSE;
01660 }
01661
01662
01663 if (cr->Opr() == OPR_INTRINSIC_OP &&
01664 cr->Intrinsic() != Exp()->Intrinsic())
01665 return FALSE;
01666 #ifdef KEY
01667 else if (cr->Opr() == OPR_PURE_CALL_OP &&
01668 cr->Call_op_aux_id() != Exp()->Call_op_aux_id())
01669 return FALSE;
01670 #endif
01671 else if (cr->Opr() == OPR_CVTL && cr->Offset() != Exp()->Offset())
01672 return FALSE;
01673 else if ((cr->Opr() == OPR_EXTRACT_BITS || cr->Opr() == OPR_COMPOSE_BITS)
01674 && (cr->Op_bit_offset() != Exp()->Op_bit_offset() ||
01675 cr->Op_bit_size() != Exp()->Op_bit_size()))
01676 return FALSE;
01677 return TRUE;
01678 }
01679 }
01680
01681
01682
01683 EXP_OCCURS *
01684 EXP_WORKLST::Lookup_phi_occ(const BB_NODE *bb)
01685 {
01686
01687 EXP_OCCURS_ITER phi_occ_iter(Phi_occurs().Head());
01688 EXP_OCCURS *occur;
01689 FOR_ALL_NODE(occur, phi_occ_iter, Init()) {
01690 if (occur->Bb() == bb)
01691 return occur;
01692 }
01693 return NULL;
01694 }
01695
01696
01697 EXP_WORKLST_NODE *
01698 EXP_WORKLST_NODE_CONTAINER::Find_exp_worklst(const CODEREP *cr)
01699 {
01700 EXP_WORKLST_NODE *etmp, *result = NULL;
01701 EXP_WORKLST_NODE_ITER exp_worklst_iter;
01702 FOR_ALL_NODE(etmp, exp_worklst_iter, Init(this)) {
01703 Set_Tail(etmp);
01704 if (etmp->Node()->Is_the_same_as(cr))
01705 result = etmp;
01706 }
01707 return result;
01708 }
01709
01710
01711 void
01712 EXP_WORKLST_NODE_CONTAINER::Append(EXP_WORKLST_NODE *worklst,
01713 IDX_32 idx,
01714 ETABLE *etable)
01715 {
01716 SLIST::Append(worklst);
01717 etable->Set_exp_hash_bucket(idx,Head());
01718 }
01719
01720 EXP_WORKLST*
01721 EXP_WORKLST_ITER2::First(void)
01722 {
01723 if (_cur = _urgent_worklst->Head()) {
01724 _urgent_worklst->Remove_Headnode();
01725 }
01726 else if (_cur = _exp_worklst->Head()) {
01727 _exp_worklst->Remove_Headnode();
01728 }
01729 else
01730 _cur = NULL;
01731
01732 return _cur;
01733 }
01734
01735 EXP_WORKLST*
01736 EXP_WORKLST_ITER2::Next(void)
01737 {
01738 if (_cur) {
01739 if (_cur->Is_urgent())
01740 _cur->Reset_is_urgent();
01741 }
01742 return First();
01743 }
01744
01745
01746 void
01747 ETABLE::Add_rehash_expr(CODEREP *cr, CODEREP *rehash_cr)
01748 {
01749 REHASH_CACHE_LIST *p = CXX_NEW(REHASH_CACHE_LIST(cr, rehash_cr), Per_expr_pool());
01750 if (_rehash_cache == NULL)
01751 _rehash_cache = p;
01752 else {
01753 _rehash_cache->Insert_Before(p);
01754 _rehash_cache = p;
01755 }
01756 }
01757
01758
01759 void
01760 EXP_WORKLST::Remove_occurs(ETABLE *etable)
01761 {
01762 EXP_OCCURS *exp_occ, *prev_occ, *next_occ;
01763 EXP_OCCURS_ITER exp_occ_iter;
01764 prev_occ = NULL;
01765
01766
01767
01768
01769 exp_occ_iter.Init(Real_occurs().Head());
01770 for (exp_occ = exp_occ_iter.First();
01771 ! exp_occ_iter.Is_Empty();
01772 exp_occ = next_occ) {
01773
01774 next_occ = exp_occ_iter.Next();
01775 BOOL ok_to_remove;
01776 switch (Pre_kind()) {
01777 case PK_LPRE:
01778 case PK_SPRE:
01779 case PK_VNFRE:
01780 ok_to_remove = TRUE;
01781 break;
01782 case PK_EPRE:
01783 ok_to_remove = (!(exp_occ->Occurrence()->Non_leaf() &&
01784 Is_the_same_as(exp_occ->Occurrence())) ||
01785 exp_occ->Delete_comp());
01786 break;
01787 default:
01788 Is_True(FALSE, ("unexpected PRE_KIND."));
01789 }
01790 if (ok_to_remove) {
01791 etable->Add_to_occ_freelist(exp_occ);
01792 Real_occurs().Remove(prev_occ, exp_occ);
01793 }
01794 else {
01795 prev_occ = exp_occ;
01796 }
01797 }
01798
01799
01800 FOR_ALL_NODE(exp_occ, exp_occ_iter, Init(Phi_occurs().Head()))
01801 etable->Add_to_occ_freelist(exp_occ);
01802
01803 Phi_occurs().Clear();
01804
01805
01806
01807
01808
01809 prev_occ = NULL;
01810 exp_occ_iter.Init(Phi_pred_occurs().Head());
01811 for (exp_occ = exp_occ_iter.First();
01812 ! exp_occ_iter.Is_Empty();
01813 exp_occ = next_occ) {
01814 next_occ = exp_occ_iter.Next();
01815 if (Pre_kind() != PK_EPRE ||
01816 !exp_occ->Inserted_computation() || !exp_occ->Encl_stmt_set()) {
01817 etable->Add_to_occ_freelist(exp_occ);
01818 Phi_pred_occurs().Remove(prev_occ, exp_occ);
01819 }
01820 else {
01821 prev_occ = exp_occ;
01822 }
01823 }
01824
01825
01826
01827
01828 if (Pre_kind() == PK_EPRE) {
01829 EXP_ALL_OCCURS_ITER exp_all_occ_iter(Real_occurs().Head(),
01830 NULL,
01831 NULL,
01832 Phi_pred_occurs().Head(),
01833 NULL);
01834 prev_occ = NULL;
01835 exp_all_occ_iter.Init();
01836 for (exp_occ = exp_all_occ_iter.First();
01837 ! exp_all_occ_iter.Is_Empty();
01838 exp_occ = next_occ) {
01839 next_occ = exp_all_occ_iter.Next();
01840 BOOL is_multi_occ = FALSE;
01841 BOOL is_l_value;
01842 if (exp_occ->Occ_kind() == EXP_OCCURS::OCC_REAL_OCCUR) {
01843 is_l_value = exp_occ->Occurs_as_lvalue();
01844 prev_occ = exp_occ;
01845 if (exp_occ->Mult_real()) is_multi_occ = TRUE;
01846 if (exp_occ->Save_to_temp())
01847 exp_occ->Set_stmt_kid_num(0);
01848 }
01849 else {
01850 Is_True (exp_occ->Inserted_computation(),
01851 ("EXP_WORKLST::Remove_occurs: Not inserted computation"));
01852 Is_True (exp_occ->Encl_stmt_set(),
01853 ("EXP_WORKLST::Remove_occurs: Inclosed stmt not set"));
01854 Is_True(prev_occ == NULL || prev_occ->Is_DPO_less_than(exp_occ),
01855 ("EXP_WORKLST::Remove_occurs: Not dpo order"));
01856
01857 is_l_value = FALSE;
01858 exp_occ->Set_kind(EXP_OCCURS::OCC_REAL_OCCUR);
01859 exp_occ->Set_stmt_kid_num(0);
01860 Phi_pred_occurs().Remove(NULL, exp_occ);
01861 Real_occurs().SLIST::Append(exp_occ, prev_occ);
01862 prev_occ = exp_occ;
01863 }
01864 exp_occ->Set_rehash_cost(0);
01865
01866 exp_occ->Clear_temp_cr();
01867 exp_occ->Set_e_version(EXP_OCCURS::ILLEGAL_E_VERSION);
01868 exp_occ->Clear_flags();
01869 if (is_multi_occ) exp_occ->Set_mult_real();
01870 if (is_l_value) exp_occ->Set_occurs_as_lvalue();
01871 }
01872 }
01873 Set_is_processed();
01874 Set_preg(ILLEGAL_PREG);
01875 }
01876
01877 BOOL
01878 EXP_WORKLST::Remove_real_occurrence( STMTREP *stmt)
01879 {
01880 EXP_OCCURS *exp_occ, *prev_occ = NULL, *next_occ;
01881 EXP_OCCURS_ITER exp_occ_iter;
01882 exp_occ_iter.Init(Real_occurs().Head());
01883 for (exp_occ = exp_occ_iter.First();
01884 ! exp_occ_iter.Is_Empty();
01885 exp_occ = next_occ) {
01886 next_occ = exp_occ_iter.Next();
01887
01888 if (exp_occ->Stmt() == stmt) {
01889 Real_occurs().Remove(prev_occ, exp_occ);
01890 return TRUE;
01891 }
01892 else
01893 prev_occ = exp_occ;
01894 }
01895 return FALSE;
01896 }
01897
01898
01899 BOOL
01900 EXP_WORKLST::Weight_less_than(EXP_WORKLST *w)
01901 {
01902 if (this->Has_const()) return TRUE;
01903 if (w->Has_const()) return FALSE;
01904 if (this->Has_rconst()) return TRUE;
01905 if (w->Has_rconst()) return FALSE;
01906 if (this->Has_lda()) return TRUE;
01907 if (w->Has_lda()) return FALSE;
01908
01909
01910 return TRUE;
01911 }
01912
01913
01914 void
01915 EXP_WORKLST_CONTAINER::Insert_sorted(EXP_WORKLST *worklst)
01916 {
01917
01918
01919 EXP_WORKLST_ITER worklst_iter(this);
01920 EXP_WORKLST *tmp, *prev = NULL;
01921 FOR_ALL_NODE(tmp, worklst_iter, Init()) {
01922 if (worklst->Weight_less_than(tmp))
01923 break;
01924 else
01925 prev = tmp;
01926 }
01927 if (prev == NULL)
01928 this->Prepend(worklst);
01929 else if (prev == Tail())
01930 this->Append(worklst);
01931 else
01932 prev->Insert_After(worklst);
01933 }
01934
01935
01936
01937
01938
01939 CODEREP *
01940 ETABLE::Lookup_rehash_expr(CODEREP *cr)
01941 {
01942 REHASH_CACHE_LIST *p = _rehash_cache;
01943 while (p != NULL) {
01944 if (p->Cr() == cr)
01945 return p->Rehash_cr();
01946 p = p->Next();
01947 }
01948
01949
01950 return NULL;
01951 }
01952
01953
01954
01955
01956
01957 EXP_WORKLST*
01958 ETABLE::Get_worklst(CODEREP *cr, BOOL urgent, BOOL lookup_only)
01959 {
01960
01961 if (Pre_kind() == PK_VNFRE)
01962 return VNFRE::get_worklst(cr);
01963
01964 EXP_WORKLST_NODE_CONTAINER bucket;
01965 IDX_32 hash_idx = Hash_exp(cr);
01966 bucket.Init_Head(Exp_hash_bucket(hash_idx));
01967 EXP_WORKLST_NODE *worklist_node = bucket.Find_exp_worklst(cr);
01968 EXP_WORKLST *worklist = (worklist_node)? worklist_node->Node() : NULL;
01969
01970 if (lookup_only) return worklist;
01971
01972
01973
01974
01975 if (worklist == NULL) {
01976 worklist = (EXP_WORKLST *)CXX_NEW(EXP_WORKLST(Alloc_e_num(),cr,Pre_kind()),
01977 Etable_pool());
01978 worklist->Exp()->Set_e_num(worklist->E_num());
01979 if (Pre_kind() == PK_LPRE && WOPT_Enable_Shrink && cr->Kind() == CK_VAR &&
01980 Opt_stab()->Aux_stab_entry(cr->Aux_id())->Lr_shrink_cand())
01981 worklist->Set_LR_shrink_cand();
01982
01983 worklist_node = (EXP_WORKLST_NODE *)CXX_NEW(EXP_WORKLST_NODE(worklist),
01984 Etable_pool());
01985 bucket.Append(worklist_node, hash_idx, this);
01986 if (urgent) {
01987 worklist->Set_is_urgent();
01988
01989 _urgent_worklst.Insert_sorted(worklist);
01990 }
01991 else
01992 _exp_worklst.Append(worklist);
01993 }
01994 else if (worklist->Is_processed()) {
01995 if (!WOPT_Enable_Second_Order) return NULL;
01996 worklist->Clear_flags();
01997 worklist->Set_e_num(Alloc_e_num());
01998 worklist->Init_e_version();
01999
02000
02001 EXP_OCCURS *exp_occ;
02002 EXP_OCCURS_ITER occur_iter;
02003 FOR_ALL_NODE(exp_occ, occur_iter, Init(worklist->Real_occurs().Head()))
02004 exp_occ->Occurrence()->Set_e_num(worklist->E_num());
02005
02006 if (urgent) {
02007 worklist->Set_is_urgent();
02008
02009 _urgent_worklst.Insert_sorted(worklist);
02010 }
02011 else
02012 _exp_worklst.Append(worklist);
02013 }
02014
02015
02016
02017 return worklist;
02018 }
02019
02020
02021
02022 BOOL
02023 ETABLE::Remove_real_occurrence(EXP_WORKLST_CONTAINER *worklist,
02024 CODEREP *old_cr, STMTREP *stmt)
02025 {
02026
02027 EXP_WORKLST *worklst, *prev_worklst = NULL;
02028
02029 EXP_WORKLST_ITER worklst_iter(worklist->Head());
02030 FOR_ALL_NODE(worklst, worklst_iter, Init()) {
02031 if (worklst->Is_the_same_as(old_cr)) {
02032 if (worklst->Remove_real_occurrence(stmt)) {
02033 Is_Trace(Lftr()->Trace(),(TFile,
02034 "ETABLE::Remove_real_occurrence, after removed occurrence\n"));
02035 Is_Trace_cmd(Lftr()->Trace(),worklst->Print(TFile));
02036 }
02037
02038 if (worklst->Real_occurs().Head() == NULL) {
02039
02040
02041 worklist->Remove(prev_worklst, worklst);
02042 worklst->Set_is_processed();
02043 }
02044 return TRUE;
02045 }
02046 prev_worklst = worklst;
02047 }
02048 return FALSE;
02049 }
02050
02051
02052
02053 BOOL
02054 Subsumable_by_branch(CODEREP *cr)
02055 {
02056 #ifdef TARG_MIPS
02057
02058
02059
02060 if (cr->Kind() != CK_OP)
02061 return FALSE;
02062 const OPERATOR opr = cr->Opr();
02063 if ((opr == OPR_EQ || opr == OPR_NE || opr == OPR_LNOT) &&
02064 MTYPE_is_integral(cr->Dsctyp()))
02065 return TRUE;
02066 if ((opr == OPR_LT || opr == OPR_LE || opr == OPR_GT || opr == OPR_GE) &&
02067 MTYPE_is_integral(cr->Dsctyp())) {
02068 CODEREP *opnd = cr->Opnd(0);
02069 if (opnd->Kind() == CK_CONST && opnd->Const_val() == 0)
02070 return TRUE;
02071 opnd = cr->Opnd(1);
02072 if (opnd->Kind() == CK_CONST && opnd->Const_val() == 0)
02073 return TRUE;
02074 }
02075 #endif
02076 return FALSE;
02077 }
02078
02079
02080
02081
02082
02083
02084
02085 void
02086 ETABLE::Remove_real_occurrence(CODEREP *old_cr, STMTREP *stmt)
02087 {
02088 if (Remove_real_occurrence(Urgent_worklst(), old_cr, stmt)) return;
02089 if (Remove_real_occurrence(Exp_worklst(), old_cr, stmt)) return;
02090
02091
02092 EXP_WORKLST *worklist = Get_worklst(old_cr, FALSE, TRUE);
02093 if (worklist) {
02094 worklist->Remove_real_occurrence(stmt);
02095 return;
02096 }
02097
02098
02099 if ((stmt->Op() == OPC_TRUEBR || stmt->Op() == OPC_FALSEBR) &&
02100 Subsumable_by_branch(old_cr))
02101 return;
02102
02103 #if defined(TARG_IA32) || defined(TARG_X8664)
02104
02105 if ((stmt->Op() == OPC_TRUEBR || stmt->Op() == OPC_FALSEBR) &&
02106 old_cr->Kind() == CK_OP &&
02107 (old_cr->Opr() == OPR_EQ || old_cr->Opr() == OPR_NE ||
02108 old_cr->Opr() == OPR_LT || old_cr->Opr() == OPR_LE ||
02109 old_cr->Opr() == OPR_GT || old_cr->Opr() == OPR_GE))
02110 return;
02111 #endif
02112
02113
02114
02115 Is_True(FALSE, ("ETABLE::Remove_real_occurrences, logic error"));
02116 }
02117
02118 #ifdef KEY
02119 void
02120 ETABLE::Mark_phi_live(PHI_NODE *phi)
02121 {
02122 if ( phi->Live() )
02123 return;
02124
02125 phi->Set_live();
02126 for ( INT pkid = 0; pkid < phi->Size(); pkid++ ) {
02127 CODEREP *cr;
02128 cr = phi->OPND(pkid);
02129 if (cr->Is_flag_set(CF_DEF_BY_PHI))
02130 Mark_phi_live(cr->Defphi());
02131 }
02132 }
02133 #endif
02134
02135
02136
02137
02138 CODEREP *
02139 ETABLE::Generate_cur_expr(const BB_NODE *bb, INT opnd_num, CODEREP *newcr, BOOL fix_zero_ver)
02140 {
02141 switch (newcr->Kind()) {
02142 case CK_VAR:
02143 {
02144 PHI_NODE *var_phi = Lookup_var_phi(bb, newcr->Aux_id());
02145 if (var_phi != NULL) {
02146 Is_True(var_phi->Live(),
02147 ("ETABLE::Generate_cur_expr: encounter dead phi "
02148 "node bb:%d Aux:%d.", bb->Id(), newcr->Aux_id()));
02149 Is_True(var_phi->OPND(opnd_num) != NULL,
02150 ("ETABLE::Generate_cur_expr: encounter bad phi opnd"
02151 "node bb:%d Aux:%d.", bb->Id(), newcr->Aux_id()));
02152 if (fix_zero_ver && var_phi->OPND(opnd_num)->Is_flag_set(CF_IS_ZERO_VERSION))
02153 Htable()->Fix_zero_version(var_phi, opnd_num);
02154 #ifdef KEY // bug 7916
02155 if (var_phi->OPND(opnd_num)->Dsctyp() == MTYPE_UNKNOWN ||
02156 var_phi->OPND(opnd_num)->Is_flag_set(CF_MADEUP_TYPE)) {
02157 Is_True(newcr->Dsctyp() != MTYPE_UNKNOWN,
02158 ("ETABLE::Generate_cur_expr: cannot fix types for phi opnd "
02159 "%d at node bb:%d Aux:%d.", opnd_num, bb->Id(),
02160 newcr->Aux_id()));
02161 var_phi->OPND(opnd_num)->Set_dtyp(newcr->Dtyp());
02162 var_phi->OPND(opnd_num)->Set_dsctyp(newcr->Dsctyp());
02163 var_phi->OPND(opnd_num)->Set_lod_ty(newcr->Lod_ty());
02164 var_phi->OPND(opnd_num)->Set_field_id(newcr->Field_id());
02165 if (newcr->Bit_field_valid())
02166 var_phi->OPND(opnd_num)->Set_bit_field_valid();
02167 var_phi->OPND(opnd_num)->Set_sign_extension_flag();
02168 var_phi->OPND(opnd_num)->Reset_flag(CF_MADEUP_TYPE);
02169 }
02170 #endif
02171 newcr = var_phi->OPND(opnd_num);
02172 }
02173 }
02174 break;
02175 case CK_IVAR:
02176 {
02177 CODEREP *ilod_base = newcr->Ilod_base();
02178 CODEREP *istr_base = newcr->Istr_base();
02179 if (ilod_base == istr_base) {
02180 if (ilod_base->Kind() == CK_VAR) {
02181 PHI_NODE *var_phi = Lookup_var_phi(bb, ilod_base->Aux_id());
02182 if (var_phi != NULL) {
02183 Is_True(var_phi->Live(),
02184 ("ETABLE::Generate_cur_expr: encounter dead phi node."));
02185 Is_True(var_phi->OPND(opnd_num) != NULL,
02186 ("ETABLE::Generate_cur_expr: encounter bad phi opnd"
02187 "node bb:%d Aux:%d.", bb->Id(), ilod_base->Aux_id()));
02188 if (fix_zero_ver && var_phi->OPND(opnd_num)->Is_flag_set(CF_IS_ZERO_VERSION))
02189 Htable()->Fix_zero_version(var_phi, opnd_num);
02190 newcr->Set_ilod_base(var_phi->OPND(opnd_num));
02191 newcr->Set_istr_base(var_phi->OPND(opnd_num));
02192 }
02193 }
02194 } else {
02195 if (ilod_base && ilod_base->Kind() == CK_VAR) {
02196 PHI_NODE *var_phi = Lookup_var_phi(bb, ilod_base->Aux_id());
02197 if (var_phi != NULL) {
02198 Is_True(var_phi->Live(),
02199 ("ETABLE::Generate_cur_expr: encounter dead phi node."));
02200 Is_True(var_phi->OPND(opnd_num) != NULL,
02201 ("ETABLE::Generate_cur_expr: encounter bad phi opnd"
02202 "node bb:%d Aux:%d.", bb->Id(), ilod_base->Aux_id()));
02203 if (fix_zero_ver && var_phi->OPND(opnd_num)->Is_flag_set(CF_IS_ZERO_VERSION))
02204 Htable()->Fix_zero_version(var_phi, opnd_num);
02205 newcr->Set_ilod_base(var_phi->OPND(opnd_num));
02206 }
02207 }
02208 if (istr_base && istr_base->Kind() == CK_VAR) {
02209 PHI_NODE *var_phi = Lookup_var_phi(bb, istr_base->Aux_id());
02210 if (var_phi != NULL) {
02211 Is_True(var_phi->Live(),
02212 ("ETABLE::Generate_cur_expr: encounter dead phi node."));
02213 Is_True(var_phi->OPND(opnd_num) != NULL,
02214 ("ETABLE::Generate_cur_expr: encounter bad phi opnd"
02215 "node bb:%d Aux:%d.", bb->Id(), istr_base->Aux_id()));
02216 if (fix_zero_ver && var_phi->OPND(opnd_num)->Is_flag_set(CF_IS_ZERO_VERSION))
02217 Htable()->Fix_zero_version(var_phi, opnd_num);
02218 newcr->Set_istr_base(var_phi->OPND(opnd_num));
02219 }
02220 }
02221 }
02222 }
02223
02224 if (newcr->Ivar_mu_node() != NULL) {
02225 PHI_NODE *var_phi = Lookup_var_phi(bb, newcr->Ivar_occ()->Aux_id());
02226 if (var_phi != NULL) {
02227 #ifdef KEY
02228 if (!var_phi->Live())
02229 Mark_phi_live(var_phi);
02230 #endif
02231 Is_True(var_phi->Live(),
02232 ("ETABLE::Generate_cur_expr: encounter dead phi node."));
02233 Is_True(var_phi->OPND(opnd_num) != NULL,
02234 ("ETABLE::Generate_cur_expr: encounter bad phi opnd"
02235 "node bb:%d Aux:%d.", bb->Id(), newcr->Ivar_occ()->Aux_id()));
02236 if (fix_zero_ver && var_phi->OPND(opnd_num)->Is_flag_set(CF_IS_ZERO_VERSION))
02237 Htable()->Fix_zero_version(var_phi, opnd_num);
02238 newcr->Ivar_mu_node()->Set_OPND(var_phi->OPND(opnd_num));
02239 }
02240 }
02241 break;
02242 case CK_OP:
02243 {
02244 for (INT i = 0; i < newcr->Kid_count(); i++) {
02245 CODEREP *kid = newcr->Opnd(i);
02246 switch (kid->Kind()) {
02247 case CK_VAR:
02248 {
02249 PHI_NODE *var_phi = Lookup_var_phi(bb, kid->Aux_id());
02250 if (var_phi != NULL) {
02251 Is_True(var_phi->Live(),
02252 ("ETABLE::Generate_cur_expr: encounter dead phi "
02253 "node bb:%d Aux:%d.", bb->Id(), kid->Aux_id()));
02254 Is_True(var_phi->OPND(opnd_num) != NULL,
02255 ("ETABLE::Generate_cur_expr: encounter bad phi opnd"
02256 "node bb:%d Aux:%d.", bb->Id(), kid->Aux_id()));
02257 if (fix_zero_ver && var_phi->OPND(opnd_num)->Is_flag_set(CF_IS_ZERO_VERSION))
02258 Htable()->Fix_zero_version(var_phi, opnd_num);
02259 #ifdef KEY // bug 3070
02260 if (var_phi->OPND(opnd_num)->Dsctyp() == MTYPE_UNKNOWN ||
02261 var_phi->OPND(opnd_num)->Is_flag_set(CF_MADEUP_TYPE)) {
02262 var_phi->OPND(opnd_num)->Set_dtyp(kid->Dtyp());
02263 var_phi->OPND(opnd_num)->Set_dsctyp(kid->Dsctyp());
02264 var_phi->OPND(opnd_num)->Set_lod_ty(kid->Lod_ty());
02265 var_phi->OPND(opnd_num)->Set_field_id(kid->Field_id());
02266 if (kid->Bit_field_valid())
02267 var_phi->OPND(opnd_num)->Set_bit_field_valid();
02268 var_phi->OPND(opnd_num)->Set_sign_extension_flag();
02269 var_phi->OPND(opnd_num)->Reset_flag(CF_MADEUP_TYPE);
02270 }
02271 #endif
02272 newcr->Set_opnd(i, var_phi->OPND(opnd_num));
02273 }
02274 }
02275 break;
02276 case CK_CONST:
02277 case CK_RCONST:
02278 case CK_LDA:
02279 break;
02280 case CK_IVAR:
02281 {
02282 const CODEREP *ilod_base = kid->Ilod_base();
02283 if (ilod_base && ilod_base->Kind() == CK_VAR) {
02284 PHI_NODE *var_phi = Lookup_var_phi(bb, ilod_base->Aux_id());
02285 if (var_phi != NULL) {
02286 Is_True(var_phi->Live(),
02287 ("ETABLE::Generate_cur_expr: encounter dead phi node."));
02288 Is_True(var_phi->OPND(opnd_num) != NULL,
02289 ("ETABLE::Generate_cur_expr: encounter bad phi opnd"
02290 "node bb:%d Aux:%d.", bb->Id(), ilod_base->Aux_id()));
02291 if (fix_zero_ver && var_phi->OPND(opnd_num)->Is_flag_set(CF_IS_ZERO_VERSION))
02292 Htable()->Fix_zero_version(var_phi, opnd_num);
02293 kid->Set_ilod_base(var_phi->OPND(opnd_num));
02294 }
02295 }
02296 }
02297
02298
02299 Is_True(kid->Ivar_mu_node() != NULL || kid->Opr() == OPR_PARM,
02300 ("ETABLE::Generate_cur_expr: non PARM CK_IVAR must have a mu-node."));
02301
02302
02303 if (kid->Ivar_mu_node() != NULL) {
02304 const PHI_NODE *var_phi = Lookup_var_phi(bb, kid->Ivar_occ()->Aux_id());
02305 if (var_phi != NULL) {
02306 Is_True(var_phi->Live(),
02307 ("ETABLE::Generate_cur_expr: encounter dead phi node."));
02308 kid->Ivar_mu_node()->Set_OPND(var_phi->OPND(opnd_num));
02309 }
02310 }
02311 break;
02312 default:
02313 Is_True(FALSE, ("unexpected CK_KIND."));
02314 }
02315 }
02316 }
02317 break;
02318 default:
02319 Is_True(FALSE, ("unexpected CK_KIND."));
02320 }
02321
02322
02323 if (Tracing()) {
02324 fprintf(TFile, "ETABLE::Generate_cur_expr for phi opnd %d in BB%d\n",
02325 opnd_num, bb->Id());
02326 newcr->Print(10, TFile);
02327 }
02328
02329 if (newcr->Kind() != CK_VAR)
02330 newcr->Set_coderep_id(0);
02331 return newcr;
02332 }
02333
02334
02335 CODEREP *
02336 ETABLE::Get_cached_cur_expr(const BB_NODE *bb, INT opnd_num)
02337 {
02338 BB_NODE *nth_pred = bb->Nth_pred(opnd_num);
02339
02340 return Phi_pred_cr( nth_pred );
02341 }
02342
02343 void
02344 ETABLE::Update_cached_cur_expr(const BB_NODE *bb, INT opnd_num, CODEREP *newcr)
02345 {
02346 BB_NODE *nth_pred = bb->Nth_pred(opnd_num);
02347 Set_phi_pred_cr( nth_pred, newcr );
02348 }
02349
02350 CODEREP *
02351 ETABLE::Alloc_and_generate_cur_expr(const CODEREP *result_expr,
02352 const BB_NODE *bb, INT opnd_num,
02353 MEM_POOL *mpool,
02354 BOOL fix_zero_ver)
02355 {
02356 BB_NODE *nth_pred = bb->Nth_pred(opnd_num);
02357 CODEREP *newcr;
02358
02359
02360 CODEREP *cached_newcr = Phi_pred_cr( nth_pred );
02361 if (!fix_zero_ver && cached_newcr != NULL) {
02362 return cached_newcr;
02363 }
02364
02365
02366 if (cached_newcr == NULL) {
02367 if ( inCODEKIND(result_expr->Kind(), CK_VAR|CK_LDA|CK_RCONST|CK_CONST) ) {
02368 newcr = (CODEREP *) result_expr;
02369 } else {
02370 newcr = CXX_NEW_VARIANT(CODEREP(*result_expr),
02371 result_expr->Extra_space_used(), mpool);
02372 }
02373
02374 if (newcr->Kind() == CK_IVAR) {
02375
02376
02377
02378 newcr->Set_ivar_mu_node(CXX_NEW(MU_NODE(*result_expr->Ivar_mu_node()), mpool));
02379
02380 } else if (newcr->Kind() == CK_OP && (newcr->Opr() == OPR_INTRINSIC_OP
02381 #ifdef KEY
02382 || newcr->Opr() == OPR_PURE_CALL_OP
02383 #endif
02384 )) {
02385 for (INT i = 0; i < newcr->Kid_count(); i++) {
02386 CODEREP *kid = result_expr->Opnd(i);
02387 CODEREP *newkid = CXX_NEW_VARIANT(CODEREP(*kid), kid->Extra_space_used(), mpool);
02388 newcr->Set_opnd(i, newkid);
02389 if (kid->Ivar_mu_node() != NULL)
02390 newkid->Set_ivar_mu_node(CXX_NEW(MU_NODE(*kid->Ivar_mu_node()), mpool));
02391 else
02392 newkid->Set_ivar_mu_node(NULL);
02393 }
02394 }
02395 } else
02396 newcr = cached_newcr;
02397
02398 if (!inCODEKIND(newcr->Kind(), CK_LDA|CK_RCONST|CK_CONST))
02399 newcr = Generate_cur_expr(bb, opnd_num, newcr, fix_zero_ver);
02400
02401
02402 Set_phi_pred_cr( nth_pred, newcr );
02403
02404 Is_True(Def_before_use(newcr, nth_pred),
02405 ("ETABLE::Alloc_and_generate_cur_expr: Generated use before def"));
02406
02407 return newcr;
02408 }
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426 void
02427 ETABLE::Schedule_for_ocopy(EXP_OCCURS *const occ)
02428 {
02429 Is_True(occ != NULL, ("ETABLE::Schedule_for_ocopy: must not defer NULL"));
02430 Is_Trace(Tracing(), (TFile, "Deferring\n"));
02431 Is_Trace_cmd(Tracing(), occ->Print(TFile));
02432 Is_Trace_cmd(Tracing(), occ->Occurrence()->Print(3, TFile));
02433
02434 Deferred_ocopy_occurs()->Push(occ);
02435 }
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449 void
02450 ETABLE::Perform_deferred_ocopy_and_get_new_exprs(EXP_WORKLST *const worklist)
02451 {
02452 while (!Deferred_ocopy_occurs()->Is_Empty()) {
02453 EXP_OCCURS *occ = Deferred_ocopy_occurs()->Pop();
02454
02455 Is_True(occ != NULL, ("ETABLE::Perform_deferred_ocopy...: NULL was deferred"));
02456
02457 Is_Trace(Tracing(), (TFile, "\n<<<<<<<<< Retrieve deferred (2nd order effects): >>>>>>>>>\n"));
02458
02459 Is_Trace_cmd(Tracing(), occ->Print(TFile));
02460 Is_Trace_cmd(Tracing(), occ->Occurrence()->Print(3, TFile));
02461
02462 STMTREP *stmt;
02463
02464 if (occ->Occ_kind() == EXP_OCCURS::OCC_REAL_OCCUR) {
02465 stmt = occ->Stmt();
02466 }
02467 else {
02468 stmt = occ->Bb()->Last_stmtrep();
02469 if (! OPERATOR_is_scalar_store (stmt->Opr())) {
02470
02471 Is_True(stmt->Op() == OPC_GOTO ||
02472 stmt->Op() == OPC_COMPGOTO ||
02473 stmt->Op() == OPC_AGOTO ||
02474 stmt->Op() == OPC_TRUEBR ||
02475 stmt->Op() == OPC_FALSEBR ||
02476 stmt->Op() == OPC_REGION_EXIT,
02477 ("ETABLE::Perform_deferred_ocopy_and_get_new_exprs: "
02478 "BB with insertion ends anomalously"));
02479 stmt = stmt->Prev();
02480 Is_True(OPERATOR_is_scalar_store (stmt->Opr()),
02481 ("ETABLE::Perform_deferred_ocopy_and_get_new_exprs: "
02482 "Can't find inserted store"));
02483 }
02484 else {
02485
02486 }
02487 }
02488 Is_True((Opt_stab()->Aux_stab_entry(stmt->Lhs()->Aux_id())->EPRE_temp() &&
02489 worklist->Pre_kind() == PK_EPRE) ||
02490 worklist->Pre_kind() == PK_LPRE,
02491 ("ETABLE::Perform_deferred_ocopy_and_get_new_exprs: "
02492 "Found store, but store isn't inserted"));
02493 Is_True(worklist->Is_the_same_as(stmt->Rhs()) ||
02494 ((stmt->Rhs()->Opr() == OPR_CVT ||
02495 stmt->Rhs()->Opr() == OPR_CVTL) &&
02496 worklist->Is_the_same_as(stmt->Rhs()->Opnd(0))),
02497 ("ETABLE::Perform_deferred_ocopy_and_get_new_exprs: "
02498 "Store to temp must save current expression"));
02499 Is_True(occ->Occurrence() == stmt->Rhs() ||
02500 ((stmt->Rhs()->Opr() == OPR_CVT ||
02501 stmt->Rhs()->Opr() == OPR_CVTL) &&
02502 occ->Occurrence() == stmt->Rhs()->Opnd(0)),
02503 ("ETABLE::Perform_deferred_ocopy_and_get_new_exprs: "
02504 "Occurrence coderep must match RHS of statement"));
02505
02506
02507
02508 BOOL tree_changed = occ->Rehash_changed_expr();
02509 CODEREP *new_rhs = Htable()->Rehash_tree(stmt->Rhs(),
02510 WOPT_Enable_Output_Copy,
02511 &tree_changed, stmt->Bb());
02512
02513
02514 stmt->Rhs()->DecUsecnt();
02515 new_rhs->IncUsecnt();
02516
02517 Is_Trace(Tracing(), (TFile, "New RHS derived from deferred:\n"));
02518 Is_Trace_cmd(Tracing(), new_rhs->Print(3, TFile));
02519
02520 stmt->Set_rhs(new_rhs);
02521 if (tree_changed) {
02522 if (occ->Occ_kind() == EXP_OCCURS::OCC_PHI_PRED_OCCUR) {
02523 Is_True(occ->Inserted_computation(),
02524 ("ETABLE::Deferred_ocopy: Phi pred must be inserted\n"));
02525 occ->Set_enclose_bb(occ->Stmt()->Bb());
02526 occ->Reset_encl_stmt_set();
02527 }
02528 else {
02529 Is_True(occ->Occ_kind() == EXP_OCCURS::OCC_REAL_OCCUR,
02530 ("ETABLE::Deferred_ocopy: Non-phi-pred must "
02531 "be real occurrence\n"));
02532
02533
02534
02535
02536
02537
02538 occ->Set_delete_comp();
02539 }
02540 Bottom_up_cr(stmt, 0, new_rhs, FALSE, URGENT_INSERT,
02541 0, OPCODE_UNKNOWN, worklist->Exclude_sr_cand());
02542 }
02543 #ifdef KEY // bug 4674: restore original expression in occurrence node so later
02544
02545 if (occ->Occurrence()->Kind() != worklist->Exp()->Kind()) {
02546 Is_True(occ->Occurrence()->Opr() == OPR_CVT ||
02547 occ->Occurrence()->Opr() == OPR_CVTL,
02548 ("ETABLE::Deferred_ocopy: inconsistent expression operation\n"));
02549 occ->Set_occurrence(occ->Occurrence()->Opnd(0));
02550 }
02551 #endif
02552 }
02553 }
02554
02555
02556 void
02557 ETABLE::Perform_deferred_cfold()
02558 {
02559 while (!Deferred_cfold_stmts()->Is_Empty()) {
02560 STMTREP *sr = Deferred_cfold_stmts()->Pop();
02561 FOLD ftmp;
02562 CODEREP *expr = ftmp.Fold_Expr(sr->Rhs());
02563 if (expr != NULL)
02564 sr->Set_rhs(expr);
02565 }
02566 }
02567
02568
02569 ETABLE::ETABLE(CFG *cfg,
02570 OPT_STAB *opt_stab,
02571 CODEMAP *htable,
02572 ALIAS_RULE *ar,
02573 IDX_32 exp_hash_size,
02574 MEM_POOL *etable_pool,
02575 MEM_POOL *per_expr_pool,
02576 MEM_POOL *etable_local_pool,
02577 COMP_UNIT *comp_unit,
02578 PRE_KIND pre_kind):
02579 _phi_work_set(cfg->Total_bb_count(), cfg, etable_pool,
02580 BBNS_EMPTY),
02581 _var_phi_set(cfg->Total_bb_count(), cfg, etable_pool,
02582 BBNS_EMPTY),
02583 _exp_hash(exp_hash_size, etable_pool),
02584 _pre_kind(pre_kind),
02585 _nil_exp_phi_opnd(NULL, NULL, NULL, TRUE),
02586 _occ_freelist(etable_pool),
02587 _deferred_cfold_stmts(etable_pool),
02588 _deferred_ocopy_occurs(etable_pool)
02589 {
02590 _cfg = cfg;
02591 _opt_stab = opt_stab;
02592 _htable = htable;
02593 _ssu = NULL;
02594 _arule = ar;
02595 _etable_pool = etable_pool;
02596 _per_expr_pool = per_expr_pool;
02597 _etable_local_pool = etable_local_pool;
02598 _cur_e_num = ILLEGAL_E_NUMBER;
02599 _dpo_exp_phi = (EXP_OCCURS **)
02600 CXX_NEW_ARRAY(EXP_OCCURS*, Cfg()->Total_bb_count(), _etable_pool);
02601 _phi_pred_cr =
02602 CXX_NEW_ARRAY(CODEREP*, Cfg()->Total_bb_count(), _etable_pool);
02603 _nil_exp_phi_opnd.Init();
02604 if (pre_kind == PK_EPRE || pre_kind == PK_VNFRE)
02605 _tracing = Get_Trace( TP_GLOBOPT, EPRE_DUMP_FLAG );
02606 else if (pre_kind == PK_SPRE)
02607 _tracing = Get_Trace( TP_GLOBOPT, SPRE_DUMP_FLAG );
02608 else
02609 _tracing = Get_Trace( TP_GLOBOPT, LPRE_DUMP_FLAG );
02610 _comp_unit = comp_unit;
02611 _num_cse_reloads = _num_cse_saves = _num_inserted_saves = _num_temp_phis = _num_hoisted = _num_temp_owners = 0;
02612
02613 LPRE_set_do_loads(pre_kind == PK_LPRE);
02614 LPRE_set_do_consts(pre_kind == PK_LPRE);
02615 }
02616
02617 ETABLE::~ETABLE(void)
02618 {
02619 Perform_deferred_cfold();
02620
02621
02622
02623 }
02624
02625 EXP_PHI*
02626 ETABLE::Lookup_exp_phi(const BB_NODE *bb, const CODEREP *cr) const
02627 {
02628 EXP_PHI *exp_phi = bb->Exp_phi();
02629 if (exp_phi == NULL) return NULL;
02630 Is_True(exp_phi->Bb() == bb,
02631 ("ETABLE::Lookup_exp_phi: Inconsistent Exp_phi() on BB%d",
02632 bb->Id()));
02633 Is_True(( (Pre_kind() == PK_VNFRE &&
02634 (cr == NULL ||
02635 exp_phi->E_num() == VNFRE::get_valnum(cr))) ||
02636 exp_phi->E_num() == cr->E_num() ),
02637 ("ETABLE::Lookup_exp_phi: Inconsistent E_num() for EXP_PHI "
02638 "in BB%d", bb->Id()));
02639 return exp_phi;
02640 }
02641
02642
02643 IDX_32
02644 ETABLE::Exp_hashvalue(const CODEREP *cr)
02645 {
02646 if (inCODEKIND(cr->Kind(), CK_IVAR|CK_OP))
02647 return cr->Bitpos() << 6;
02648 if (cr->Kind() == CK_VAR)
02649 return cr->Aux_id() << 6;
02650 if (cr->Kind() == CK_CONST)
02651 return cr->Const_val() << 6;
02652 return cr->Coderep_id() << 6;
02653 }
02654
02655 IDX_32
02656 ETABLE::Hash_exp(const CODEREP *cr)
02657 {
02658 if (cr->Kind() == CK_IVAR) {
02659 CODEREP *bas = cr->Istr_base() ? cr->Istr_base() : cr->Ilod_base();
02660 return (Exp_hashvalue(bas) + cr->Offset()) % _exp_hash.Size();
02661 } else if (cr->Kind() == CK_VAR) {
02662 return (cr->Aux_id() % _exp_hash.Size());
02663 } else if (inCODEKIND(cr->Kind(), CK_LDA|CK_CONST|CK_RCONST)) {
02664 return (Exp_hashvalue(cr) % _exp_hash.Size());
02665 }
02666
02667 IDX_32 hvalue = 0;
02668 for (INT32 i = 0; i < cr->Kid_count(); i++)
02669 hvalue += Exp_hashvalue(cr->Opnd(i));
02670 return (cr->Op() + hvalue) % _exp_hash.Size();
02671 }
02672
02673 CODEREP *
02674 ETABLE::Rehash_exp(CODEREP *new_cr, UINT32 gvn, BOOL canon) const
02675 {
02676
02677
02678
02679
02680 CODEREP * const rehashed_cr = Htable()->Rehash(new_cr, canon);
02681
02682 if (Pre_kind() == PK_VNFRE && rehashed_cr != new_cr)
02683 {
02684 VNFRE::add_valnum(rehashed_cr, gvn);
02685 }
02686 return rehashed_cr;
02687 }
02688
02689 EXP_OCCURS*
02690 ETABLE::Alloc_occurs_node(void)
02691 {
02692 EXP_OCCURS *retval;
02693 if (Occ_freelist()->Is_Empty()) {
02694
02695 retval = CXX_NEW(EXP_OCCURS, Etable_pool());
02696 }
02697 else {
02698
02699 retval = Occ_freelist()->Pop();
02700 }
02701 retval->Init();
02702 return retval;
02703 }
02704
02705 EXP_OCCURS*
02706 ETABLE::Alloc_occurs_node(CODEREP *occurrence)
02707 {
02708 EXP_OCCURS *retval;
02709 if (Occ_freelist()->Is_Empty()) {
02710
02711 retval = CXX_NEW(EXP_OCCURS(occurrence,
02712 (STMTREP *) NULL,
02713 (EXP_PHI *) NULL,
02714 TRUE),
02715 Etable_pool());
02716 retval->Clear_temp_cr();
02717 retval->Set_rehash_cost(0);
02718 }
02719 else {
02720
02721 retval = Occ_freelist()->Pop();
02722 retval->Init();
02723 retval->Set_occurrence(occurrence);
02724 retval->Reset_enclosed_in();
02725
02726
02727 }
02728 return retval;
02729 }
02730
02731
02732
02733 void
02734 ETABLE::Check_lftr_non_candidate(STMTREP *stmt, CODEREP *cr, OPCODE opc)
02735 {
02736 if (cr->Kind() != CK_VAR)
02737 return;
02738 if (opc == OPCODE_UNKNOWN)
02739 return;
02740
02741
02742 switch (OPCODE_operator(opc)) {
02743 case OPR_ADD: case OPR_SUB: case OPR_MPY: case OPR_NEG:
02744 case OPR_LNOT: case OPR_EQ: case OPR_NE:
02745 case OPR_GT: case OPR_GE: case OPR_LT: case OPR_LE:
02746 return;
02747 case OPR_CVT:
02748 if (! (MTYPE_is_float(OPCODE_rtype(opc)) ||
02749 MTYPE_is_float(OPCODE_desc(opc))))
02750 return;
02751
02752 default: {
02753 BB_LOOP *loop = stmt->Bb()->Innermost();
02754 while (loop) {
02755 if (loop->Lftr_non_candidates() == NULL)
02756 loop->Set_lftr_non_candidates(
02757 CXX_NEW(IDX_32_SET(Opt_stab()->Lastidx()+1, Cfg()->Loc_pool(),
02758 OPTS_FALSE), Cfg()->Loc_pool()));
02759 loop->Lftr_non_candidates()->Union1D(cr->Aux_id());
02760 loop = loop->Parent();
02761 }
02762 return;
02763 }
02764 }
02765 }
02766
02767 #ifdef TARG_SL2
02768
02769
02770
02771
02772
02773
02774 static BOOL
02775 Is_Intrncall_Nth_Parm_Candidate(INTRINSIC id, INT nth_parm ) {
02776 switch(id) {
02777 case INTRN_C2_LD_C_IMM:
02778 case INTRN_C2_ST_C_IMM:
02779 if(nth_parm == 1) return TRUE;
02780 return FALSE;
02781 case INTRN_C2_LD_V2G_IMM:
02782 case INTRN_C2_ST_G2V_IMM:
02783 case INTRN_C2_LD_G_IMM:
02784 case INTRN_C2_ST_G_IMM:
02785 if(nth_parm == 2) return TRUE;
02786 return FALSE;
02787 case INTRN_C2_ST_V_IMM:
02788 if(nth_parm == 3) return TRUE;
02789 return FALSE;
02790 case INTRN_C2_LD_V_IMM:
02791 if(nth_parm == 4) return TRUE;
02792 return FALSE;
02793 default:
02794 return FALSE;
02795 }
02796 }
02797 #endif
02798
02799
02800
02801
02802
02803 void
02804 ETABLE::Bottom_up_stmt(STMTREP *stmt)
02805 {
02806 const OPERATOR stmt_opr = stmt->Opr();
02807
02808
02809
02810
02811
02812
02813 Is_Trace(Tracing(),
02814 (TFile, "----- stmt: %s -----\n", OPCODE_name(stmt->Op())));
02815 Is_Trace_cmd(Tracing(),stmt->Print(TFile));
02816
02817 #if 0
02818
02819 if (Lftr()->Lftr_on())
02820 Lftr()->Assign_stmt_no(stmt);
02821 #else
02822 stmt->Set_stmt_id(Cfg()->Get_stmt_id());
02823 #endif
02824
02825
02826
02827 CODEREP *rhs = stmt->Rhs();
02828 BOOL is_iv_update = FALSE;
02829 if (OPERATOR_is_scalar_istore (stmt_opr) ||
02830 OPERATOR_is_scalar_store (stmt_opr)) {
02831
02832
02833 if (WOPT_Enable_New_SR &&
02834 (is_iv_update = Str_red()->Determine_iv_update(stmt, NULL))) {
02835 Is_Trace(Tracing(),(TFile,"-Is iv update-\n"));
02836 }
02837 }
02838
02839 if (OPCODE_is_fake(stmt->Op())) {
02840 for (INT32 i = 0; i < rhs->Kid_count(); i++) {
02841 #ifdef TARG_SL2
02842 if(rhs->Opr()==OPR_INTRINSIC_CALL && Is_Intrncall_Nth_Parm_Candidate(rhs->Intrinsic(), i)) {
02843 continue;
02844 }
02845 #endif
02846 New_temp_id();
02847 Bottom_up_cr(stmt, i, rhs->Opnd(i), FALSE, NOT_URGENT, 0, rhs->Op(), FALSE);
02848 }
02849 } else if (rhs != NULL) {
02850 if (!is_iv_update) {
02851 New_temp_id();
02852 Bottom_up_cr(stmt, 0, rhs, FALSE, NOT_URGENT, 0, stmt->Op(), FALSE);
02853 }
02854 else {
02855 BOOL all_kids_are_terminal = TRUE;
02856 for (INT i = 0; i < rhs->Kid_count(); i++) {
02857 if (!rhs->Opnd(i)->Is_non_volatile_terminal(Opt_stab())) {
02858 all_kids_are_terminal = FALSE;
02859 break;
02860 }
02861 }
02862 if (all_kids_are_terminal) {
02863
02864
02865 Is_Trace(Tracing(), (TFile, " --- omitting rhs ---\n"));
02866 rhs->Set_omitted();
02867 } else {
02868
02869
02870
02871 Is_True(rhs->Kind() == CK_OP,
02872 ("ETABLE::Bottom_up_stmt: iv update must be CK_OP"));
02873 for (INT i = 0; i < rhs->Kid_count(); ++i) {
02874 New_temp_id();
02875 Bottom_up_cr(stmt, 0, rhs->Opnd(i), FALSE, NOT_URGENT,
02876 1 , rhs->Op(), FALSE);
02877 }
02878 }
02879 }
02880 }
02881 if (stmt->Lhs()) {
02882 Is_Trace(Tracing(),(TFile,"Lhs\n"));
02883 New_temp_id();
02884 Bottom_up_cr(stmt, 1, stmt->Lhs(), OPCODE_is_store(stmt->Op()), NOT_URGENT,
02885 0, OPCODE_UNKNOWN, FALSE);
02886 }
02887 }
02888
02889
02890
02891
02892 void
02893 ETABLE::Bottom_up_cr(STMTREP *stmt, INT stmt_kid_num, CODEREP *cr,
02894 BOOL is_istore, URGENCY urgent, UINT depth,
02895 OPCODE opc, BOOL no_estr)
02896 {
02897 Is_True(cr != NULL,("ETABLE::Bottom_up_cr, null CODEREP"));
02898
02899 Is_Trace(Tracing(),(TFile, "ETABLE::Bottom_up_cr called on ----- cr -----\n"));
02900 Is_Trace_cmd(Tracing(),cr->Print(2,TFile));
02901 switch (cr->Kind()) {
02902 case CK_CONST:
02903 case CK_RCONST:
02904 case CK_LDA:
02905 break;
02906 case CK_VAR:
02907 Check_lftr_non_candidate(stmt, cr, opc);
02908 break;
02909 case CK_IVAR:
02910 {
02911 BOOL same_base = TRUE;
02912 if (cr->Ilod_base() != NULL && cr->Istr_base() != NULL &&
02913 cr->Ilod_base() != cr->Istr_base()) {
02914 Warn_todo("CODEREP ilod_base != istr_base.");
02915 same_base = FALSE;
02916 }
02917 if (cr->Opr() == OPR_ILOADX)
02918 Warn_todo("ETABLE::Bottom_up_cr: Indexed load.");
02919 #ifdef TARG_SL
02920 if (cr->Dtyp() == MTYPE_I2 && cr->Dsctyp() == MTYPE_I2) {
02921 cr->Set_dtyp(MTYPE_I4);
02922 }
02923 #endif
02924 if (!is_istore) {
02925 CODEREP *ivar_vsym = cr->Get_ivar_vsym();
02926 if (cr->Ilod_base()->Is_non_volatile_terminal(Opt_stab()) &&
02927 ! cr->Is_ivar_volatile()) {
02928 Check_lftr_non_candidate(stmt, cr->Ilod_base(), cr->Op());
02929 if (same_base && WOPT_Enable_Ivar_PRE && cr->Ivar_has_e_num()) {
02930 #ifdef KEY
02931 if (WOPT_Enable_Preserve_Mem_Opnds && opc != OPCODE_UNKNOWN &&
02932 (OPCODE_operator(opc) == OPR_ADD ||
02933 OPCODE_operator(opc) == OPR_SUB ||
02934 MTYPE_is_float(OPCODE_rtype(opc)) &&
02935 OPCODE_operator(opc) == OPR_MPY)) {
02936 }
02937 else
02938 #endif
02939 if (urgent == NOT_URGENT) {
02940 Is_Trace(Tracing(),
02941 (TFile,"====== ETABLE::Bottom_up_cr, Append coderep:\n"));
02942 Is_Trace_cmd(Tracing(),cr->Print(2,TFile));
02943 Append_real_occurrence(cr, stmt, stmt_kid_num, depth);
02944 }
02945 else {
02946 Is_Trace(Tracing(),
02947 (TFile,"====== ETABLE::Bottom_up_cr, Insert coderep:\n"));
02948 Is_Trace_cmd(Tracing(),cr->Print(2,TFile));
02949 Insert_real_occurrence(cr, stmt, stmt_kid_num, depth, FALSE,
02950 urgent == URGENT_INSERT);
02951 }
02952 #if 0
02953
02954
02955 Lftr()->Insert_comp_occurrence(cr, stmt, stmt_kid_num);
02956 #endif
02957 }
02958 } else {
02959 Bottom_up_cr(stmt, stmt_kid_num, cr->Ilod_base(), FALSE, urgent,
02960 depth+1, cr->Op(), FALSE);
02961 }
02962 } else {
02963
02964
02965 CODEREP *ivar_vsym = cr->Get_ivar_vsym();
02966 if (cr->Istr_base()->Is_non_volatile_terminal(Opt_stab()) &&
02967 ! cr->Is_ivar_volatile()) {
02968 Check_lftr_non_candidate(stmt, cr->Istr_base(), cr->Op());
02969 if (same_base && WOPT_Enable_Ivar_PRE && cr->Ivar_has_e_num()) {
02970 if (!urgent) {
02971 Append_real_occurrence(cr, stmt, stmt_kid_num, depth, TRUE);
02972 Is_Trace(Tracing(),
02973 (TFile,"====== ETABLE::Bottom_up_cr, Append coderep:\n"));
02974 Is_Trace_cmd(Tracing(),cr->Print(2,TFile));
02975 } else {
02976 Is_Trace(Tracing(),
02977 (TFile,"====== ETABLE::Bottom_up_cr, Insert coderep:\n"));
02978 Is_Trace_cmd(Tracing(),cr->Print(2,TFile));
02979 Insert_real_occurrence(cr, stmt, stmt_kid_num, depth, FALSE, urgent);
02980 }
02981 #if 0
02982
02983
02984 Lftr()->Insert_comp_occurrence(cr, stmt, stmt_kid_num);
02985 #endif
02986 }
02987 } else {
02988 Bottom_up_cr(stmt, stmt_kid_num, cr->Istr_base(), FALSE, urgent,
02989 depth+1, cr->Op(), FALSE);
02990 }
02991 }
02992 }
02993 {
02994 const OPERATOR ivar_opr = cr->Opr();
02995 if ( ivar_opr == OPR_MLOAD) {
02996 if (cr->Mload_size())
02997 Bottom_up_cr(stmt, stmt_kid_num, cr->Mload_size(), FALSE, urgent,
02998 depth+1, cr->Op(), FALSE);
02999 else
03000 Bottom_up_cr(stmt, stmt_kid_num, cr->Mstore_size(), FALSE, urgent,
03001 depth+1, cr->Op(), FALSE);
03002 }
03003 if ( ivar_opr == OPR_ILOADX)
03004 Bottom_up_cr(stmt, stmt_kid_num, cr->Index(), FALSE, urgent,
03005 depth+1, cr->Op(), FALSE);
03006 }
03007 break;
03008 case CK_OP:
03009 {
03010 if (OPCODE_is_volatile(cr->Op())) {
03011 for (INT32 i=0; i<cr->Kid_count(); i++) {
03012 CODEREP *kid = cr->Opnd(i);
03013 if (!kid->Is_non_volatile_terminal(Opt_stab())) {
03014 Bottom_up_cr(stmt, stmt_kid_num, kid, FALSE, urgent,
03015 depth, cr->Op(), no_estr);
03016 }
03017 }
03018 } else {
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029 if (cr->Temp_id() == Cur_temp_id())
03030 if (cr->Is_lcse() && (cr->Max_depth() >= depth ||
03031 cr->Max_depth() == 255))
03032 return;
03033 else
03034 cr->Set_is_lcse();
03035 else {
03036 cr->Set_temp_id(Cur_temp_id());
03037 cr->Reset_is_lcse();
03038 cr->Set_max_depth(depth);
03039 }
03040
03041
03042 if (cr->Max_depth() < depth)
03043 if (depth > 255)
03044 cr->Set_max_depth(255);
03045 else cr->Set_max_depth(depth);
03046
03047 INT32 i;
03048 Is_True(cr->Opr() != OPR_ARRAY,
03049 ("ETABLE::Bottom_up_cr: reach an OPR_ARRAY node,"
03050 "this is a bug in lowering process"));
03051
03052 CODEREP *kid;
03053 BOOL all_kids_are_terminal = TRUE;
03054
03055 for (i=0; i<cr->Kid_count(); i++) {
03056 kid = cr->Opnd(i);
03057 if (!kid->Is_non_volatile_terminal(Opt_stab())) {
03058 all_kids_are_terminal = FALSE;
03059 Bottom_up_cr(stmt, stmt_kid_num, kid, FALSE, urgent,
03060 depth+1, cr->Op(), no_estr);
03061 }
03062 else Check_lftr_non_candidate(stmt, kid, cr->Op());
03063 }
03064 #ifdef TARG_NVISA
03065
03066 BOOL all_kids_are_const = TRUE;
03067 switch (cr->Opr()) {
03068 case OPR_ADD:
03069 case OPR_SUB:
03070 case OPR_MPY:
03071 case OPR_DIV:
03072 case OPR_MOD:
03073 case OPR_REM:
03074 case OPR_SHL:
03075 case OPR_LSHR:
03076 case OPR_ASHR:
03077 case OPR_BAND:
03078 case OPR_BIOR:
03079 case OPR_BXOR:
03080 case OPR_BNOR:
03081 case OPR_BNOT:
03082 case OPR_NEG:
03083 break;
03084 default:
03085 all_kids_are_const = FALSE;
03086 break;
03087 }
03088 for (i=0; i<cr->Kid_count(); i++) {
03089 kid = cr->Opnd(i);
03090 switch (kid->Kind()) {
03091 case CK_CONST:
03092 break;
03093 case CK_VAR:
03094 if ( ! ST_is_const_var( Opt_stab()->St(kid->Aux_id())))
03095 all_kids_are_const = FALSE;
03096 break;
03097 default:
03098
03099 all_kids_are_const = FALSE;
03100 break;
03101 }
03102 }
03103 #endif
03104
03105 if (cr->Exp_has_e_num()) {
03106 if (all_kids_are_terminal) {
03107 OPERATOR opr = cr->Opr();
03108 if ((stmt->Op() == OPC_TRUEBR || stmt->Op() == OPC_FALSEBR) &&
03109 (depth == 0 ||
03110 depth == 1 && stmt->Rhs()->Opr() == OPR_LNOT) &&
03111 Subsumable_by_branch(cr)) {
03112 cr->Set_omitted();
03113 } else if (!WOPT_Enable_CSE_FP_comparison &&
03114 (opr == OPR_EQ || opr == OPR_NE ||
03115 opr == OPR_LT || opr == OPR_LE ||
03116 opr == OPR_GT || opr == OPR_GE) &&
03117 MTYPE_is_float(cr->Dsctyp())) {
03118 cr->Set_omitted();
03119 #if defined(TARG_IA32) || defined(TARG_X8664)
03120 } else if ((opc == OPC_TRUEBR || opc == OPC_FALSEBR) &&
03121 (opr == OPR_EQ || opr == OPR_NE ||
03122 opr == OPR_LT || opr == OPR_LE ||
03123 opr == OPR_GT || opr == OPR_GE)) {
03124 cr->Set_omitted();
03125 #endif
03126 #ifdef TARG_NVISA
03127
03128 } else if (!WOPT_Enable_Const_Op_PRE && all_kids_are_const) {
03129 Is_Trace(Tracing(),
03130 (TFile,"omit from epre cause all kids are const\n"));
03131 cr->Set_omitted();
03132 #endif
03133 } else if (!urgent) {
03134 Is_Trace(Tracing(),
03135 (TFile,"====== ETABLE::Bottom_up_cr, Append coderep:\n"));
03136 Is_Trace_cmd(Tracing(),cr->Print(2,TFile));
03137 Append_real_occurrence(cr, stmt, stmt_kid_num, depth, FALSE);
03138 } else {
03139 Is_Trace(Tracing(),
03140 (TFile,"====== ETABLE::Bottom_up_cr, Insert coderep:\n"));
03141 Is_Trace_cmd(Tracing(),cr->Print(2,TFile));
03142 Insert_real_occurrence(cr, stmt, stmt_kid_num, depth, FALSE, urgent);
03143 }
03144 if (no_estr) {
03145 EXP_WORKLST *worklist = Get_worklst(cr, FALSE, TRUE);
03146 Is_True(worklist, ("ETABLE::Bottome_up_cr, cannot find worklist"));
03147 worklist->Set_exclude_sr_cand();
03148 }
03149 }
03150 if (all_kids_are_terminal || WOPT_Enable_Aggressive_Lftr)
03151 Lftr()->Insert_comp_occurrence(cr, stmt, stmt_kid_num);
03152 }
03153 }
03154 }
03155 break;
03156 case CK_DELETED:
03157 default:
03158 Is_True(0,("ETABLE::Bottom_up_cr(), unexpected kind 0x%x",cr->Kind()));
03159 break;
03160 }
03161 }
03162
03163
03164
03165
03166
03167
03168 CODEREP *
03169 EXP_OCCURS::Load_use_cr(ETABLE *etable, CODEREP * old_cr, CODEREP *cr)
03170 {
03171 EXP_WORKLST *worklist = etable->Get_worklst(old_cr, FALSE, TRUE);
03172 CODEREP * new_cr = Alloc_stack_cr(0);
03173
03174 Is_True(etable->Pre_kind() != PK_VNFRE,
03175 ("EXP_WORKLST::Load_use_cr: Unexpected call for VNFRE"));
03176 Is_True(old_cr->Is_integral_load_store(),("EXP_OCCUR::Load_use_cr: not an integral iload/ldid"));
03177 Is_True(cr!=NULL,("EXP_OCCUR::Load_use_cr: cr is NULL"));
03178 Is_True(worklist != NULL, ("EXP_OCCUR::Load_use_cr: Null worklist"));
03179
03180 if (MTYPE_size_min(old_cr->Dsctyp()) > MTYPE_size_min(MTYPE_I4))
03181 return cr;
03182
03183 OPCODE opc;
03184 INT load_need_cvt =
03185 Need_load_type_conversion(worklist->Sign_extd(),
03186 old_cr->Is_sign_extd(),
03187 old_cr->Dtyp(), old_cr->Dsctyp(), &opc);
03188 switch (load_need_cvt) {
03189 case NOT_AT_ALL:
03190 break;
03191 case NEED_CVT:
03192 cr->IncUsecnt();
03193 new_cr->Init_expr(opc, cr);
03194 cr = etable->Rehash_exp(new_cr, etable->Gvn(cr));
03195 break;
03196 case NEED_CVTL:
03197 cr->IncUsecnt();
03198 new_cr->Init_expr(opc, cr);
03199 new_cr->Set_offset(MTYPE_size_min(old_cr->Dsctyp()));
03200 cr = etable->Rehash_exp(new_cr, etable->Gvn(cr));
03201 break;
03202 }
03203
03204 #ifndef KEY
03205 if (Split_64_Bit_Int_Ops && MTYPE_size_min(cr->Dtyp()) == 32 &&
03206 MTYPE_size_min(old_cr->Dtyp()) == 64) {
03207 opc = MTYPE_signed(old_cr->Dtyp()) ? OPC_I8I4CVT : OPC_U8U4CVT;
03208 new_cr->Init_expr(opc, cr);
03209 return etable->Rehash_exp(new_cr, etable->Gvn(cr));
03210 }
03211 #else
03212 cr = cr->Fixup_type(old_cr->Dtyp(), etable->Htable());
03213 #endif
03214
03215 return cr;
03216 }
03217
03218
03219
03220
03221 CODEREP *
03222 EXP_WORKLST::Save_use_cr(const ETABLE *etable, CODEREP * old_cr)
03223 {
03224 Is_True(Pre_kind() != PK_VNFRE,
03225 ("EXP_WORKLST::Save_use_cr: Unexpected call for VNFRE"));
03226 Is_True(old_cr->Is_integral_load_store(),("EXP_WORKLST::Save_use_cr: not an integral iload/ldid"));
03227
03228 if (MTYPE_size_min(old_cr->Dsctyp()) > MTYPE_size_min(MTYPE_I4))
03229 return old_cr;
03230
03231 const UINT32 gvn = etable->Gvn(old_cr);
03232 CODEREP *new_cr = Alloc_stack_cr(0);
03233 OPCODE opc;
03234 INT load_need_cvt =
03235 Need_load_type_conversion(old_cr->Is_sign_extd(), Sign_extd(),
03236 old_cr->Dtyp(), old_cr->Dsctyp(), &opc);
03237 switch (load_need_cvt) {
03238 case NOT_AT_ALL:
03239 return old_cr;
03240 case NEED_CVT:
03241 if ( old_cr->Coderep_id() == 0 ||
03242 (old_cr->Kind() == CK_VAR && old_cr->Is_flag_set(CF_MADEUP_TYPE)) ) {
03243 old_cr->Reset_flag( CF_MADEUP_TYPE );
03244 if (opc == OPC_U8U4CVT) {
03245 old_cr->Set_dtyp(MTYPE_U8);
03246 old_cr->Set_dsctyp(MTYPE_U4);
03247 old_cr->Set_sign_extension_flag();
03248 #ifndef KEY
03249 } else if (opc == OPC_U4U8CVT) {
03250 old_cr->Set_dtyp(MTYPE_U4);
03251 #else
03252 } else if (opc == OPC_I8I4CVT) {
03253 old_cr->Set_dtyp(MTYPE_I8);
03254 old_cr->Set_dsctyp(MTYPE_I4);
03255 #endif
03256 old_cr->Set_sign_extension_flag();
03257 } else {
03258 Is_True(FALSE, ("EXP_WORKLST::Save_use_cr: wrong type conversion"));
03259 }
03260 return old_cr;
03261 } else {
03262 old_cr->IncUsecnt();
03263 new_cr->Init_expr(opc, old_cr);
03264 return etable->Rehash_exp(new_cr, gvn);
03265 }
03266 case NEED_CVTL:
03267 if ( old_cr->Coderep_id() == 0 ||
03268 (old_cr->Kind() == CK_VAR && old_cr->Is_flag_set(CF_MADEUP_TYPE)) ) {
03269 old_cr->Reset_flag( CF_MADEUP_TYPE );
03270 if (opc == OPC_U4CVTL || opc == OPC_U8CVTL) {
03271 old_cr->Set_dtyp(Mtype_TransferSign(MTYPE_U4,old_cr->Dtyp()));
03272 old_cr->Set_dsctyp(Mtype_TransferSign(MTYPE_U4,old_cr->Dsctyp()));
03273 old_cr->Set_sign_extension_flag();
03274 } else if (opc == OPC_I4CVTL || opc == OPC_I8CVTL) {
03275 old_cr->Set_dtyp(Mtype_TransferSign(MTYPE_I4,old_cr->Dtyp()));
03276 old_cr->Set_dsctyp(Mtype_TransferSign(MTYPE_I4,old_cr->Dsctyp()));
03277 old_cr->Set_sign_extension_flag();
03278 } else {
03279 Is_True(FALSE, ("EXP_WORKLST::Save_use_cr: wrong type conversion"));
03280 }
03281 return old_cr;
03282 } else {
03283 old_cr->IncUsecnt();
03284 new_cr->Init_expr(opc, old_cr);
03285 new_cr->Set_offset(MTYPE_size_min(old_cr->Dsctyp()));
03286 return etable->Rehash_exp(new_cr, gvn);
03287 }
03288 }
03289
03290 return old_cr;
03291 }
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309 class OCCUR_REPLACEMENT
03310 {
03311 private:
03312
03313 enum REPLACEMENT_KIND {REPL_BY_CR, REPL_BY_TYPED_CR, REPL_BY_CONST};
03314
03315 REPLACEMENT_KIND _kind;
03316 CODEREP *_cr;
03317 TCON _tcon;
03318
03319 CODEREP *_replace_by_cr(CODEREP *x)
03320 {
03321
03322
03323 x->DecUsecnt_rec();
03324 _cr->IncUsecnt();
03325 return _cr;
03326 }
03327
03328 CODEREP *_replace_by_typed_cr(ETABLE *etable,
03329 EXP_OCCURS *occur,
03330 CODEREP *x)
03331 {
03332
03333
03334 CODEREP *replacement = _replace_by_cr(x);
03335 if (x->Is_integral_load_store())
03336 {
03337
03338
03339 replacement = occur->Load_use_cr(etable, x, replacement);
03340 }
03341 return replacement;
03342 }
03343
03344 CODEREP *_replace_by_const(CODEMAP *htable, CODEREP *x)
03345 {
03346
03347
03348
03349 TCON_IDX tcon_idx;
03350
03351
03352
03353
03354
03355 if (x->Dtyp() != TCON_ty(_tcon) &&
03356 x->Dtyp() != MTYPE_M )
03357 tcon_idx = Enter_tcon(Targ_Conv(x->Dtyp(), _tcon));
03358 else
03359 tcon_idx = Enter_tcon(_tcon);
03360
03361 CODEREP *tcon_cr = htable->Add_tcon(tcon_idx);
03362
03363 x->DecUsecnt_rec();
03364 tcon_cr->IncUsecnt();
03365 return tcon_cr;
03366 }
03367
03368 public:
03369
03370 OCCUR_REPLACEMENT(CODEREP *replace_by_cr, BOOL type_conv = FALSE):
03371 _cr(replace_by_cr)
03372 {
03373 _kind = (type_conv? REPL_BY_TYPED_CR : REPL_BY_CR);
03374 }
03375
03376 OCCUR_REPLACEMENT(TCON replace_by_tcon):
03377 _tcon(replace_by_tcon),
03378 _kind(REPL_BY_CONST)
03379 {}
03380
03381 CODEREP *apply(CODEMAP *htable,
03382 ETABLE *etable,
03383 EXP_OCCURS *occur,
03384 CODEREP *x)
03385 {
03386
03387
03388 CODEREP *replacement = NULL;
03389
03390 switch (_kind)
03391 {
03392 case REPL_BY_CR:
03393 replacement = _replace_by_cr(x);
03394 break;
03395
03396 case REPL_BY_TYPED_CR:
03397 replacement = _replace_by_typed_cr(etable, occur, x);
03398 break;
03399
03400 case REPL_BY_CONST:
03401 replacement = _replace_by_const(htable, x);
03402
03403
03404
03405
03406 if (etable->Pre_kind() == PK_VNFRE)
03407 VNFRE::add_valnum(replacement, VNFRE::get_valnum(x));
03408 break;
03409
03410 default:
03411 FmtAssert(FALSE,("Unknown OCCUR_REPLACEMENT"));
03412 break;
03413 }
03414 return replacement;
03415 }
03416 };
03417
03418
03419 CODEREP *
03420 ETABLE::Recursive_rehash_and_replace(CODEREP *x,
03421 EXP_OCCURS *occur,
03422 OCCUR_REPLACEMENT *repl,
03423 const BOOL replacing_istr_base,
03424 UINT depth,
03425 OPCODE opc)
03426 {
03427
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437 BOOL need_rehash;
03438 BOOL all_kids_are_terminal;
03439 INT32 i;
03440 CODEREP *cr, *expr;
03441 CODEREP *original_cr = x;
03442
03443 Is_True(x != NULL, ("ETABLE::Recursive_rehash_and_replace, NULL CR"));
03444 Is_True(occur != NULL, ("ETABLE::Recursive_rehash_and_replace, NULL occur"));
03445
03446 if (Pre_kind() == PK_VNFRE)
03447 {
03448
03449
03450
03451
03452
03453
03454 Is_True(x->Coderep_id() != 0, ("Unexpected coderep id in "
03455 "ETABLE::Recursive_rehash_and_replace()"));
03456
03457 if (!replacing_istr_base &&
03458 VNFRE::get_valnum(x) == VNFRE::get_valnum(occur->Occurrence()) &&
03459 !(x->Non_leaf() && x->Opr() == OPR_PARM) &&
03460 x->Kind() != CK_CONST &&
03461 x->Kind() != CK_RCONST)
03462 {
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478 OPERATOR opr = OPCODE_operator(opc);
03479 TYPE_ID desc = OPCODE_desc(opc);
03480 if (opr == OPR_CVT && desc == MTYPE_B && x->Kind() == CK_VAR &&
03481 x->Dtyp() == MTYPE_B && x->Dsctyp() == MTYPE_B)
03482 {
03483 return x;
03484 }
03485
03486 return repl->apply(Htable(), this, occur, x);
03487 }
03488 }
03489 else if (x == occur->Occurrence())
03490 return repl->apply(Htable(), this, occur, x);
03491
03492 switch (x->Kind()) {
03493 case CK_LDA:
03494 case CK_VAR:
03495 case CK_CONST:
03496 case CK_RCONST:
03497 return NULL;
03498
03499 case CK_IVAR:
03500 cr = Alloc_stack_cr(x->Extra_ptrs_used());
03501 need_rehash = FALSE;
03502 cr->Copy(*x);
03503 cr->Set_usecnt(0);
03504
03505 if (replacing_istr_base) {
03506 expr = Recursive_rehash_and_replace(x->Istr_base(), occur, repl,
03507 FALSE, depth+1, x->Op());
03508 if (expr) {
03509 need_rehash = TRUE;
03510 cr->Set_istr_base(expr);
03511 cr->Set_ilod_base(NULL);
03512 }
03513 else cr->Set_istr_base(x->Istr_base());
03514 all_kids_are_terminal = cr->Istr_base()->Is_non_volatile_terminal(Opt_stab());
03515 }
03516 else {
03517 expr = Recursive_rehash_and_replace(x->Ilod_base(), occur, repl,
03518 FALSE, depth+1, x->Op());
03519 if (expr) {
03520 need_rehash = TRUE;
03521 cr->Set_ilod_base(expr);
03522 cr->Set_istr_base(NULL);
03523 }
03524 else cr->Set_ilod_base(x->Ilod_base());
03525 all_kids_are_terminal = cr->Ilod_base()->Is_non_volatile_terminal(Opt_stab());
03526 }
03527 if (x->Opr() == OPR_MLOAD) {
03528
03529 expr = Recursive_rehash_and_replace(x->Mload_size(), occur, repl,
03530 FALSE, depth+1, x->Op());
03531 if (expr) {
03532 need_rehash = TRUE;
03533 cr->Set_mload_size(expr);
03534 }
03535 else cr->Set_mload_size(x->Mload_size());
03536 }
03537 else if (x->Opr() == OPR_ILOADX) {
03538
03539 expr = Recursive_rehash_and_replace(x->Index(), occur, repl,
03540 FALSE, depth+1, x->Op());
03541 if (expr) {
03542 need_rehash = TRUE;
03543 cr->Set_index(expr);
03544 }
03545 else cr->Set_index(x->Index());
03546 }
03547 if (!need_rehash)
03548 return NULL;
03549 x->DecUsecnt();
03550 x = Rehash_exp(cr, Gvn(original_cr));
03551
03552 if (Pre_kind() == PK_VNFRE)
03553 VNFRE::replace_occurs(original_cr, x, occur->Stmt());
03554
03555 #ifdef KEY
03556 if (WOPT_Enable_Preserve_Mem_Opnds && opc != OPCODE_UNKNOWN &&
03557 MTYPE_is_float(OPCODE_rtype(opc)) &&
03558 (OPCODE_operator(opc) == OPR_ADD ||
03559 OPCODE_operator(opc) == OPR_MPY ||
03560 OPCODE_operator(opc) == OPR_SUB)) {
03561 }
03562 else
03563 #endif
03564 if (Pre_kind() == PK_EPRE &&
03565 all_kids_are_terminal &&
03566 OPERATOR_is_scalar_iload (x->Opr()) &&
03567 x->Dtyp() != MTYPE_M &&
03568 ! x->Is_ivar_volatile()) {
03569
03570 Is_Trace(Tracing(),
03571 (TFile, "ETABLE::Recursive_rehash_and_replace: "
03572 "New leaf expression for CK_IVAR case:\n"));
03573 Is_Trace_cmd(Tracing(), x->Print(4, TFile));
03574 Insert_real_occurrence(x, occur->Stmt(), occur->Stmt_kid_num(), depth,
03575 replacing_istr_base);
03576 }
03577 return x;
03578
03579 case CK_OP:
03580
03581
03582
03583
03584
03585
03586
03587
03588
03589 if (x->Temp_id() == Cur_temp_id() && x->Is_lcse()) {
03590
03591
03592
03593 Warn_todo("Recursive_rehash_and_replace: using unique CR id to "
03594 "lookup rehashed expr.");
03595 x = Lookup_rehash_expr(x);
03596 if (x == NULL)
03597 return NULL;
03598 all_kids_are_terminal = TRUE;
03599 for (INT32 i = 0; i < x->Kid_count(); i++) {
03600 if (! x->Opnd(i)->Is_non_volatile_terminal(Opt_stab()))
03601 all_kids_are_terminal = FALSE;
03602 }
03603 } else {
03604 if (!OPCODE_is_volatile(x->Op())) {
03605 if (x->Temp_id() != Cur_temp_id()) {
03606
03607 x->Set_temp_id(Cur_temp_id());
03608 x->Reset_is_lcse();
03609 }
03610 else x->Set_is_lcse();
03611 }
03612
03613 cr = Alloc_stack_cr(x->Extra_ptrs_used());
03614 need_rehash = FALSE;
03615 all_kids_are_terminal = TRUE;
03616 cr->Copy(*x);
03617 cr->Set_usecnt(0);
03618 for (INT32 i = 0; i < x->Kid_count(); i++) {
03619
03620 if (cr->Opr() == OPR_INTRINSIC_OP && cr->Intrinsic() == INTRN_EXPECT &&
03621 i == 1)
03622 continue;
03623 expr = Recursive_rehash_and_replace(x->Opnd(i), occur, repl,
03624 FALSE, depth+1, x->Op());
03625 if (expr) {
03626 need_rehash = TRUE;
03627 cr->Set_opnd(i, expr);
03628 } else
03629 cr->Set_opnd(i, x->Opnd(i));
03630 if (! cr->Opnd(i)->Is_non_volatile_terminal(Opt_stab()))
03631 all_kids_are_terminal = FALSE;
03632 }
03633 if (! need_rehash)
03634 return NULL;
03635 x->DecUsecnt();
03636
03637 CODEREP *rehash_x =
03638 Rehash_exp(cr, Gvn(original_cr), !OPCODE_is_compare(cr->Op()));
03639
03640
03641 if (x->Is_lcse())
03642 Add_rehash_expr(x, rehash_x);
03643 x = rehash_x;
03644 }
03645
03646 if (!OPCODE_is_volatile(x->Op())) {
03647 if (Pre_kind() == PK_VNFRE)
03648 VNFRE::replace_occurs(original_cr, x, occur->Stmt());
03649
03650 if (Pre_kind() == PK_EPRE) {
03651 if (all_kids_are_terminal) {
03652
03653 Is_Trace(Tracing(),
03654 (TFile, "ETABLE::Recursive_rehash_and_replace: "
03655 "New leaf expression for CK_OP case:\n"));
03656 Is_Trace_cmd(Tracing(), x->Print(4, TFile));
03657 OPERATOR opr = x->Opr();
03658 if (occur->Stmt()->Iv_update() ||
03659 (depth == 0 &&
03660 (occur->Stmt()->Op() == OPC_TRUEBR ||
03661 occur->Stmt()->Op() == OPC_FALSEBR) &&
03662 Subsumable_by_branch(x)) ||
03663 (depth == 1 &&
03664 (occur->Stmt()->Op() == OPC_TRUEBR ||
03665 occur->Stmt()->Op() == OPC_FALSEBR) &&
03666 occur->Stmt()->Rhs()->Opr() == OPR_LNOT &&
03667 Subsumable_by_branch(x))) {
03668 Is_Trace(Tracing(), (TFile, " -----> omitted\n"));
03669 x->Set_omitted();
03670 } else if (!WOPT_Enable_CSE_FP_comparison &&
03671 (opr == OPR_EQ || opr == OPR_NE ||
03672 opr == OPR_LT || opr == OPR_LE ||
03673 opr == OPR_GT || opr == OPR_GE) &&
03674 MTYPE_is_float(x->Dsctyp())) {
03675 x->Set_omitted();
03676 } else {
03677 Is_Trace(Tracing(), (TFile, " -----> inserting...\n"));
03678 Insert_real_occurrence(x, occur->Stmt(),
03679 occur->Stmt_kid_num(), depth);
03680 }
03681 }
03682 if (all_kids_are_terminal || WOPT_Enable_Aggressive_Lftr)
03683 Lftr()->Insert_comp_occurrence(x, occur->Stmt(), occur->Stmt_kid_num());
03684 }
03685 }
03686 return x;
03687 }
03688 Is_True(FALSE, ("ETABLE::Recursive_rehash_and_replace, unknown kind"));
03689 return NULL;
03690 }
03691
03692
03693 CODEREP *
03694 ETABLE::Rehash_and_replace(CODEREP *x,
03695 EXP_OCCURS *occur,
03696 OCCUR_REPLACEMENT *repl,
03697 const BOOL replacing_istr_base,
03698 OPCODE parent_opc)
03699 {
03700
03701
03702 CODEREP *new_cr = NULL;
03703
03704 if (Pre_kind() == PK_VNFRE)
03705 {
03706
03707
03708
03709
03710
03711
03712
03713
03714
03715
03716
03717 BOOL set_cr_id = (x->Coderep_id() == 0 && replacing_istr_base);
03718
03719 if (set_cr_id)
03720 x->Set_coderep_id(occur->Stmt()->Lhs()->Coderep_id());
03721
03722 VNFRE::delete_occurs(occur, x);
03723 new_cr =
03724 Recursive_rehash_and_replace(x, occur, repl, replacing_istr_base, 0, parent_opc);
03725
03726 if (set_cr_id)
03727 x->Set_coderep_id(0);
03728 }
03729 else
03730 {
03731 new_cr =
03732 Recursive_rehash_and_replace(x, occur, repl, replacing_istr_base, 0, parent_opc);
03733 }
03734 return new_cr;
03735
03736 }
03737
03738
03739 void
03740 ETABLE::Replace_occurs(EXP_OCCURS *occur, OCCUR_REPLACEMENT *repl)
03741 {
03742
03743
03744 Is_True(occur->Occ_kind() == EXP_OCCURS::OCC_REAL_OCCUR ||
03745 occur->Occ_kind() == EXP_OCCURS::OCC_COMP_OCCUR,
03746 ("ETABLE::Replace_occurs: can't handle occurrence kind"));
03747
03748 STMTREP *stmt = occur->Stmt();
03749 INT32 kid_num = occur->Stmt_kid_num();
03750
03751
03752
03753 if (occur->Occ_kind() == EXP_OCCURS::OCC_REAL_OCCUR &&
03754 Lftr()->Lftr_on() && Lftr()->Is_comparison(occur->Occurrence()))
03755 Lftr()->Remove_comp_occur(occur);
03756
03757 New_temp_id();
03758 Clear_rehash_cache();
03759
03760 Is_Trace(Tracing(), (TFile, "ETABLE::Replace_occurs: Replacing\n"));
03761 Is_Trace_cmd(Tracing(), occur->Occurrence()->Print(0, TFile));
03762 Is_Trace(Tracing(), (TFile, " in kid %d of\n", kid_num));
03763 Is_Trace_cmd(Tracing(), stmt->Print(TFile));
03764 Is_Trace(Tracing(), (TFile, " for occurrence\n"));
03765 Is_Trace_cmd(Tracing(), occur->Print(TFile));
03766 Is_Trace_cmd(Tracing(), fflush(TFile));
03767
03768 if (OPCODE_is_fake(stmt->Op()))
03769 {
03770 CODEREP *new_opnd =
03771 Rehash_and_replace(stmt->Rhs()->Opnd(kid_num), occur, repl, FALSE,
03772 stmt->Rhs()->Op());
03773
03774 Is_True(new_opnd != NULL,
03775 ("ETABLE::Replace_occurs: RHS opnd must rehash"));
03776
03777 stmt->Rhs()->Set_opnd(kid_num, new_opnd );
03778 }
03779 else if (OPCODE_is_store(stmt->Op()))
03780 {
03781 switch (kid_num) {
03782 case 0:
03783 if (Pre_kind() == PK_VNFRE ||
03784 !stmt->Iv_update() ||
03785 stmt->Rhs()->E_num() != occur->Occurrence()->E_num())
03786 {
03787 CODEREP *new_rhs = Rehash_and_replace(stmt->Rhs(), occur, repl, FALSE,
03788 stmt->Op());
03789
03790 #ifdef KEY // bug 5980: there can be duplicate real occur nodes inserted due
03791
03792 if (new_rhs == NULL) {
03793 #ifdef Is_True_On
03794 EXP_WORKLST *worklist = Get_worklst(occur->Occurrence());
03795 EXP_ALL_OCCURS_ITER exp_occ_iter(worklist->Real_occurs().Head(),
03796 NULL, NULL, NULL, NULL);
03797 EXP_OCCURS *oc;
03798 FOR_ALL_NODE(oc, exp_occ_iter, Init()) {
03799 if (oc == occur)
03800 FmtAssert(FALSE,("ETABLE::Replace_occurs: RHS must need rehash"));
03801 if (oc->Stmt() == occur->Stmt() &&
03802 oc->Stmt_kid_num() == occur->Stmt_kid_num())
03803 break;
03804 }
03805 #endif
03806 break;
03807 }
03808 #else
03809 Is_True(new_rhs != NULL,
03810 ("ETABLE::Replace_occurs: RHS must need rehash"));
03811 #endif
03812 stmt->Set_rhs(new_rhs);
03813
03814
03815
03816 stmt->Reset_iv_update();
03817 }
03818 else
03819 {
03820
03821
03822
03823 }
03824 break;
03825 case 1:
03826 {
03827 Is_True(stmt->Opr() == OPR_MSTORE ||
03828 OPERATOR_is_scalar_istore (stmt->Opr()) ||
03829 OPERATOR_is_scalar_store (stmt->Opr()),
03830 ("ETABLE::Replace_occurs: bad stmt_kid_num"));
03831 CODEREP *x = Alloc_stack_cr(stmt->Lhs()->Extra_ptrs_used());
03832 x->Copy(*stmt->Lhs());
03833 x->Set_usecnt(0);
03834 x = Rehash_and_replace(x, occur, repl, TRUE, stmt->Op());
03835
03836 Is_True(x == NULL || x->Istr_base() != NULL,
03837 ("ETABLE::Replace_occurs: Istr_base should not be NULL"));
03838
03839 if (x != NULL)
03840 stmt->Set_lhs(x);
03841 }
03842 break;
03843 case 2:
03844 {
03845 Is_True(stmt->Opr() == OPR_MSTORE,
03846 ("ETABLE::Replace_occurs: bad stmt_kid_num"));
03847 CODEREP *new_mstore_size =
03848 Rehash_and_replace(stmt->Lhs()->Mstore_size(), occur, repl, FALSE,
03849 stmt->Lhs()->Op());
03850 Is_True(new_mstore_size != NULL,
03851 ("ETABLE::Replace_occurs: Mstore_size() must not be NULL"));
03852
03853 stmt->Lhs()->Set_mstore_size(new_mstore_size);
03854 }
03855 break;
03856 default:
03857 Is_True(FALSE, ("ETABLE::Replace_occurs: bad stmt_kid_num"));
03858 break;
03859 }
03860 }
03861 else if (stmt->Opr() == OPR_PREFETCH)
03862 {
03863 Is_True(kid_num == 0, ("ETABLE::Replace_occurs: wrong stmt_kid_num"));
03864 CODEREP *new_ilod_base =
03865 Rehash_and_replace(stmt->Rhs()->Ilod_base(), occur, repl, FALSE,
03866 stmt->Rhs()->Op());
03867
03868 Is_True(new_ilod_base != NULL,
03869 ("ETABLE::Replace_occurs: new_ilod_base must not be NULL"));
03870 stmt->Rhs()->Set_ilod_base(new_ilod_base);
03871 }
03872 else
03873 {
03874 Is_True(kid_num == 0, ("ETABLE::Replace_occurs: wrong stmt_kid_num"));
03875 CODEREP *new_rhs = Rehash_and_replace(stmt->Rhs(), occur, repl, FALSE,
03876 stmt->Op());
03877 Is_True(new_rhs != NULL,
03878 ("ETABLE::Replace_occurs: new_rhs must not be NULL"));
03879 stmt->Set_rhs(new_rhs);
03880 }
03881 Is_Trace(Tracing(), (TFile, "ETABLE::Replace_occurs: Resulting stmt:\n"));
03882 Is_Trace_cmd(Tracing(), stmt->Print(TFile));
03883 }
03884
03885
03886
03887
03888
03889
03890 void
03891 ETABLE::Replace_by_temp(EXP_OCCURS *occur, CODEREP *tempcr)
03892 {
03893 OCCUR_REPLACEMENT repl(tempcr, (Pre_kind() != PK_VNFRE));
03894 Replace_occurs(occur, &repl);
03895 }
03896
03897
03898
03899
03900
03901
03902 void
03903 ETABLE::Replace_by_const(EXP_OCCURS *occur, TCON tcon)
03904 {
03905
03906
03907 OCCUR_REPLACEMENT repl(tcon);
03908 Replace_occurs(occur, &repl);
03909 }
03910
03911
03912
03913
03914
03915
03916
03917
03918 void
03919 ETABLE::No_replace(EXP_OCCURS *occur, BOOL dont_rehash)
03920 {
03921 Is_True(FALSE,
03922 ("ETABLE::No_replace: not yet correct "
03923 "(e.g. the assignment to original_occurs below)"));
03924
03925 Is_True(occur->Occurrence()->Is_flag_set(CF_OWNED_BY_TEMP),
03926 ("ETABLE::No_replace: called with wrong coderep node"));
03927
03928 EXP_OCCURS original_occur(occur->Occurrence(),
03929 occur->Stmt(), NULL, TRUE);
03930 CODEREP *x = occur->Occurrence();
03931
03932
03933
03934 if (occur->Occ_kind() == EXP_OCCURS::OCC_REAL_OCCUR &&
03935 Lftr()->Lftr_on() && Lftr()->Is_comparison(x))
03936 Lftr()->Remove_comp_occur(occur);
03937
03938
03939 if (x->Kind() == CK_IVAR) {
03940 x->Ilod_base()->IncUsecnt();
03941 if (x->Opr() == OPR_MLOAD)
03942 x->Mload_size()->IncUsecnt();
03943 else if (x->Opr() == OPR_ILOADX)
03944 x->Index()->IncUsecnt();
03945 }
03946 else {
03947 for (INT32 i = 0; i < x->Kid_count(); i++)
03948 x->Opnd(i)->IncUsecnt();
03949 }
03950 CODEREP *new_cr = Rehash_exp(x, Gvn(x));
03951 new_cr->Set_e_num(x->E_num());
03952 new_cr->DecUsecnt();
03953 occur->Set_occurrence(new_cr);
03954
03955 if (dont_rehash)
03956 return;
03957
03958 OCCUR_REPLACEMENT repl(occur->Occurrence(), FALSE);
03959 STMTREP *stmt = occur->Stmt();
03960 INT32 kid_num = occur->Stmt_kid_num();
03961 New_temp_id();
03962 Clear_rehash_cache();
03963
03964 Is_Trace(Tracing(), (TFile, "ETABLE::No_replace: called on\n"));
03965 Is_Trace_cmd(Tracing(), occur->Occurrence()->Print(0, TFile));
03966 Is_Trace(Tracing(), (TFile, " in kid %d of\n", kid_num));
03967 Is_Trace_cmd(Tracing(), stmt->Print(TFile));
03968
03969 if (OPCODE_is_fake(stmt->Op())) {
03970 CODEREP *new_opnd =
03971 Rehash_and_replace(stmt->Rhs()->Opnd(kid_num),
03972 &original_occur, &repl, FALSE, stmt->Rhs()->Op());
03973 Is_True(new_opnd != NULL,
03974 ("ETABLE::No_replace: RHS opnd must need rehash"));
03975 stmt->Rhs()->Set_opnd(kid_num, new_opnd );
03976 }
03977 else if (OPCODE_is_store(stmt->Op())) {
03978 switch (kid_num) {
03979 case 0: {
03980 CODEREP *new_rhs =
03981 Rehash_and_replace(stmt->Rhs(), &original_occur, &repl, FALSE,
03982 stmt->Rhs()->Op());
03983 Is_True(new_rhs != NULL,
03984 ("ETABLE::No_replace: RHS must need rehash"));
03985 stmt->Set_rhs(new_rhs);
03986 break;
03987 }
03988 case 1:
03989 {
03990 Is_True(stmt->Opr() == OPR_MSTORE ||
03991 OPERATOR_is_scalar_istore (stmt->Opr()),
03992 ("ETABLE::No_replace: bad stmt_kid_num"));
03993 CODEREP *x = Alloc_stack_cr(stmt->Lhs()->Extra_ptrs_used());
03994 x->Copy(*stmt->Lhs());
03995 x->Set_usecnt(0);
03996 x = Rehash_and_replace(x, &original_occur, &repl, TRUE, stmt->Op());
03997
03998 Is_True(x==NULL || x->Istr_base() != NULL,
03999 ("ETABLE::No_replace: Istr_base must not be NULL"));
04000
04001 if (x != NULL)
04002 stmt->Set_lhs(x);
04003 }
04004 break;
04005 case 2:
04006 {
04007 Is_True(stmt->Opr() == OPR_MSTORE,
04008 ("ETABLE::No_replace: bad stmt_kid_num"));
04009 CODEREP *new_mstore_size =
04010 Rehash_and_replace(stmt->Lhs()->Mstore_size(),
04011 &original_occur, &repl, TRUE, stmt->Lhs()->Op());
04012 Is_True(new_mstore_size != NULL,
04013 ("ETABLE::No_replace: Mstore_size() must not be NULL"));
04014 stmt->Lhs()->Set_mstore_size(new_mstore_size);
04015 }
04016 break;
04017 default:
04018 Is_True(FALSE, ("ETABLE::No_replace: bad stmt_kid_num"));
04019 break;
04020 }
04021 }
04022 else if (stmt->Opr() == OPR_PREFETCH) {
04023 Is_True(kid_num == 0, ("ETABLE::No_replace: wrong stmt_kid_num"));
04024 CODEREP *new_ilod_base =
04025 Rehash_and_replace(stmt->Rhs()->Ilod_base(),
04026 &original_occur, &repl, TRUE, stmt->Rhs()->Op());
04027
04028 Is_True(new_ilod_base != NULL,
04029 ("ETABLE::No_replace: new_ilod_base must not be NULL"));
04030 stmt->Rhs()->Set_ilod_base(new_ilod_base);
04031 }
04032 else {
04033 Is_True(kid_num == 0, ("ETABLE::No_replace: wrong stmt_kid_num"));
04034 CODEREP *new_rhs =
04035 Rehash_and_replace(stmt->Rhs(), &original_occur, &repl, TRUE, stmt->Op());
04036 Is_True(new_rhs != NULL,
04037 ("ETABLE::No_replace: new_rhs must not be NULL"));
04038 stmt->Set_rhs(new_rhs);
04039 }
04040 }
04041
04042
04043
04044
04045
04046
04047 void
04048 ETABLE::Find_1st_order_exprs_with_temp(STMTREP *stmt, INT stmt_kid_num,
04049 CODEREP *cr, CODEREP *tempcr,
04050 BOOL is_istore, UINT depth)
04051 {
04052 switch (cr->Kind()) {
04053 case CK_CONST:
04054 case CK_RCONST:
04055 case CK_LDA:
04056 case CK_VAR:
04057 break;
04058 case CK_IVAR:
04059 {
04060 BOOL same_base = TRUE;
04061 if (cr->Ilod_base() != NULL && cr->Istr_base() != NULL &&
04062 cr->Ilod_base() != cr->Istr_base()) {
04063 same_base = FALSE;
04064 }
04065
04066 if (!is_istore) {
04067 CODEREP *ivar_vsym = cr->Get_ivar_vsym();
04068 if (cr->Ilod_base() == tempcr && ! cr->Is_ivar_volatile()) {
04069 if (same_base && cr->Ivar_has_e_num()) {
04070 Append_real_occurrence(cr, stmt, stmt_kid_num, depth);
04071 }
04072 } else {
04073 Find_1st_order_exprs_with_temp(stmt, stmt_kid_num, cr->Ilod_base(),
04074 tempcr, FALSE, depth+1);
04075 }
04076 } else {
04077
04078
04079 CODEREP *ivar_vsym = cr->Get_ivar_vsym();
04080 if (cr->Istr_base() == tempcr && ! cr->Is_ivar_volatile()) {
04081 if (same_base && cr->Ivar_has_e_num()) {
04082 Append_real_occurrence(cr, stmt, stmt_kid_num, depth, TRUE);
04083 }
04084 } else {
04085 Find_1st_order_exprs_with_temp(stmt, stmt_kid_num, cr->Istr_base(),
04086 tempcr, FALSE, depth+1);
04087 }
04088 }
04089 }
04090 {
04091 const OPERATOR ivar_opr = cr->Opr();
04092 if ( ivar_opr == OPR_MLOAD) {
04093 if (cr->Mload_size())
04094 Find_1st_order_exprs_with_temp(stmt, stmt_kid_num, cr->Mload_size(),
04095 tempcr, FALSE, depth+1);
04096 else
04097 Find_1st_order_exprs_with_temp(stmt, stmt_kid_num, cr->Mstore_size(),
04098 tempcr, FALSE, depth+1);
04099 }
04100 else if ( ivar_opr == OPR_ILOADX) {
04101 Find_1st_order_exprs_with_temp(stmt, stmt_kid_num, cr->Index(),
04102 tempcr, FALSE, depth+1);
04103 }
04104 }
04105 break;
04106 case CK_OP:
04107 {
04108
04109
04110
04111
04112
04113
04114
04115
04116
04117
04118 if (cr->Temp_id() == Cur_temp_id())
04119 if (cr->Is_lcse() && (cr->Max_depth() >= depth ||
04120 cr->Max_depth() == 255))
04121 return;
04122 else
04123 cr->Set_is_lcse();
04124 else {
04125 cr->Set_temp_id(Cur_temp_id());
04126 cr->Reset_is_lcse();
04127 cr->Set_max_depth(depth);
04128 }
04129
04130
04131 if (cr->Max_depth() < depth)
04132 if (depth > 255)
04133 cr->Set_max_depth(255);
04134 else cr->Set_max_depth(depth);
04135
04136 INT32 i;
04137 CODEREP *kid;
04138 BOOL all_kids_are_terminal = TRUE;
04139 BOOL has_tempcr_as_opnd = FALSE;
04140
04141 for (i=0; i<cr->Kid_count(); i++) {
04142 kid = cr->Opnd(i);
04143 if (!kid->Is_non_volatile_terminal(Opt_stab())) {
04144 all_kids_are_terminal = FALSE;
04145 Find_1st_order_exprs_with_temp(stmt, stmt_kid_num, kid,
04146 tempcr, FALSE, depth+1);
04147 }
04148 else if (kid == tempcr)
04149 has_tempcr_as_opnd = TRUE;
04150 }
04151
04152 if (all_kids_are_terminal && has_tempcr_as_opnd && cr->Exp_has_e_num()) {
04153 Append_real_occurrence(cr, stmt, stmt_kid_num, depth, FALSE);
04154 }
04155 }
04156 break;
04157 case CK_DELETED:
04158 default:
04159 Is_True(0,("ETABLE::Find_1st_order_exprs_with_temp(), unexpected kind 0x%x",cr->Kind()));
04160 break;
04161 }
04162 }
04163
04164
04165
04166
04167
04168
04169
04170 void
04171 ETABLE::Find_new_1st_order_exprs(EXP_OCCURS *occur, CODEREP *tempcr)
04172 {
04173 Is_True(occur->Occ_kind() == EXP_OCCURS::OCC_REAL_OCCUR,
04174 ("ETABLE::Find_new_1st_order_exprs: can't handle occurrence kind"));
04175 STMTREP *stmt = occur->Stmt();
04176 INT32 kid_num = occur->Stmt_kid_num();
04177
04178 New_temp_id();
04179 CODEREP *tree;
04180 BOOL is_istr_base = FALSE;
04181
04182 if (OPCODE_is_fake(stmt->Op()))
04183 tree = stmt->Rhs()->Opnd(kid_num);
04184 else if (OPCODE_is_store(stmt->Op())) {
04185 switch (kid_num) {
04186 case 0: tree = stmt->Rhs(); break;
04187 case 1:
04188 Is_True(stmt->Opr() == OPR_MSTORE ||
04189 OPERATOR_is_scalar_istore (stmt->Opr()),
04190 ("ETABLE::Find_new_1st_order_exprs: bad stmt_kid_num"));
04191 if (OPERATOR_is_scalar_istore (stmt->Opr())) {
04192 is_istr_base = TRUE;
04193 tree = stmt->Lhs();
04194 }
04195 else tree = stmt->Lhs()->Istr_base();
04196 break;
04197 case 2: tree = stmt->Lhs()->Mstore_size(); break;
04198 default: Is_True(FALSE, ("ETABLE::Find_new_1st_order_exprs: bad stmt_kid_num")); break;
04199 }
04200 }
04201 else if (stmt->Opr() == OPR_PREFETCH)
04202 tree = stmt->Rhs()->Ilod_base();
04203 else tree = stmt->Rhs();
04204 Find_1st_order_exprs_with_temp(stmt, kid_num, tree, tempcr, is_istr_base, 0);
04205 }
04206
04207
04208
04209
04210
04211
04212
04213 void
04214 EXP_WORKLST::Adjust_combined_types(CODEREP *cr)
04215 {
04216 Is_True(Exp()->Is_integral_load_store(), ("EXP_WORKLST::Adjust_combined_types: wrong cr"));
04217 #if defined(TARG_NVISA)
04218 if ( (cr->Kind() == CK_VAR) &&
04219 (MTYPE_size_min(cr->Dsctyp()) != MTYPE_size_min(Exp()->Dsctyp())))
04220 Set_has_unequal_sizes();
04221 #endif
04222 Is_True(MTYPE_size_min(cr->Dsctyp()) == MTYPE_size_min(Exp()->Dsctyp()),
04223 ("EXP_WORKLST::Adjust_combined_types: mismatch Dsc types"));
04224
04225 #ifdef Is_True_On
04226 BOOL is_sign_extd = cr->Is_sign_extd();
04227 cr->Set_sign_extension_flag();
04228 Is_True(is_sign_extd==cr->Is_sign_extd(),
04229 ("EXP_WORKLST::Adjust_combined_types: cr's sign extension flag is inconsistent"));
04230 #endif
04231
04232 if (cr->Is_sign_extd()) Set_sign_extd();
04233
04234 }
04235
04236
04237
04238
04239 void
04240 ETABLE::Append_real_occurrence(CODEREP *cr, STMTREP *stmt, INT stmt_kid_num,
04241 UINT depth, BOOL is_istore)
04242 {
04243
04244 EXP_WORKLST *worklist = Get_worklst(cr);
04245
04246 if (worklist == NULL)
04247 return;
04248
04249 Is_True (cr->Kind() != CK_OP || !OPCODE_is_volatile(cr->Op()),
04250 ("ETABLE::Append_real_occurrence: entering volatile op."));
04251
04252
04253 if (worklist->Exp()->Is_integral_load_store())
04254 worklist->Adjust_combined_types(cr);
04255
04256
04257
04258
04259 EXP_OCCURS *tail_occ = worklist->Real_occurs().Tail();
04260
04261
04262 if (tail_occ && (tail_occ->Enclosed_in_stmt() == stmt) &&
04263 tail_occ->Stmt_kid_num() == stmt_kid_num) {
04264 tail_occ->Set_mult_real();
04265 if (tail_occ->Rehash_cost() < depth)
04266 tail_occ->Set_rehash_cost(depth);
04267 return;
04268 }
04269
04270
04271 EXP_OCCURS *occurs = Alloc_occurs_node();
04272 occurs->Set_occurrence(cr);
04273 occurs->Set_kind(EXP_OCCURS::OCC_REAL_OCCUR);
04274 occurs->Set_enclose_stmt(stmt);
04275 occurs->Set_stmt_kid_num(stmt_kid_num);
04276 occurs->Set_rehash_cost(depth);
04277 cr->Set_e_num(worklist->E_num());
04278 if (is_istore)
04279 occurs->Set_occurs_as_lvalue();
04280
04281 #if defined(TARG_SL) //PARA_EXTENSION
04282 if( stmt && stmt->Bb() && stmt->Bb()->SL2_para_region())
04283 occurs->Set_occ_in_para_region();
04284 #endif
04285
04286
04287 worklist->Append_occurrence(occurs);
04288 }
04289
04290
04291
04292
04293 void
04294 ETABLE::Insert_real_occurrence(CODEREP *cr, STMTREP *stmt, INT stmt_kid_num,
04295 UINT depth, BOOL is_istore, BOOL urgent)
04296 {
04297
04298 EXP_WORKLST *worklist = Get_worklst(cr, urgent);
04299
04300 Is_Trace(Tracing(), (TFile, "ETABLE::Insert_real_occurrence: "));
04301
04302 if (worklist == NULL) {
04303
04304 Is_Trace(Tracing(), (TFile, "2nd-order fx disabled; doing nothing\n"));
04305 return;
04306 }
04307
04308 Is_True (cr->Kind() != CK_OP || !OPCODE_is_volatile(cr->Op()),
04309 ("ETABLE::Insert_real_occurrence: entering volatile op."));
04310
04311
04312 if (worklist->Exp()->Is_integral_load_store())
04313 worklist->Adjust_combined_types(cr);
04314
04315
04316
04317
04318 EXP_OCCURS *tail_occ = worklist->Real_occurs().Tail();
04319
04320
04321 if (tail_occ && (tail_occ->Enclosed_in_stmt() == stmt) &&
04322 tail_occ->Stmt_kid_num() == stmt_kid_num) {
04323 Is_Trace(Tracing(), (TFile, "mult-real at tail\n"));
04324 tail_occ->Set_mult_real();
04325 if (tail_occ->Rehash_cost() < depth)
04326 tail_occ->Set_rehash_cost(depth);
04327 return;
04328 }
04329
04330 Is_Trace(Tracing(), (TFile, "building occ... "));
04331
04332
04333 EXP_OCCURS *occurs = Alloc_occurs_node();
04334 occurs->Set_occurrence(cr);
04335 occurs->Set_kind(EXP_OCCURS::OCC_REAL_OCCUR);
04336 occurs->Set_enclose_stmt(stmt);
04337 occurs->Set_stmt_kid_num(stmt_kid_num);
04338 occurs->Set_rehash_cost(depth);
04339
04340 #if defined(TARG_SL) //PARA_EXTENSION
04341 if( stmt && stmt->Bb() && stmt->Bb()->SL2_para_region())
04342 occurs->Set_occ_in_para_region();
04343 #endif
04344
04345 cr->Set_e_num(worklist->E_num());
04346 if (is_istore)
04347 occurs->Set_occurs_as_lvalue();
04348
04349
04350
04351 if ( tail_occ == NULL || tail_occ->Is_DPO_less_than(occurs) )
04352 worklist->Append_occurrence(occurs);
04353 else
04354 worklist->Insert_occurrence(occurs, this);
04355
04356 Is_Trace(Tracing(), (TFile, "placed in worklist\n"));
04357 }
04358
04359
04360 EXP_OCCURS*
04361 ETABLE::Append_phi_occurrence(CODEREP *cr, EXP_PHI *phi, EXP_WORKLST *worklist)
04362 {
04363
04364 EXP_OCCURS *occurs = Alloc_occurs_node();
04365 occurs->Set_occurrence(NULL);
04366 occurs->Set_kind(EXP_OCCURS::OCC_PHI_OCCUR);
04367 occurs->Set_exp_phi(phi);
04368 cr->Set_e_num(worklist->E_num());
04369 phi->Set_result(occurs);
04370
04371
04372 worklist->Append_occurrence(occurs);
04373
04374
04375
04376
04377 return occurs;
04378 }
04379
04380
04381 EXP_OCCURS *
04382 ETABLE::Append_phi_pred_occurrence(CODEREP *cr, BB_NODE *bb, EXP_WORKLST *worklist)
04383 {
04384
04385 EXP_OCCURS *occurs = Alloc_occurs_node();
04386 occurs->Set_occurrence(NULL);
04387 occurs->Set_kind(EXP_OCCURS::OCC_PHI_PRED_OCCUR);
04388 occurs->Set_enclose_bb(bb);
04389 cr->Set_e_num(worklist->E_num());
04390
04391
04392 worklist->Append_occurrence(occurs);
04393 return occurs;
04394 }
04395
04396
04397 void
04398 ETABLE::Append_exit_occurrence(BB_NODE *bb)
04399 {
04400
04401 EXP_OCCURS *occurs = Alloc_occurs_node();
04402 occurs->Set_occurrence(NULL);
04403 occurs->Set_kind(EXP_OCCURS::OCC_EXIT_OCCUR);
04404 occurs->Set_enclose_bb(bb);
04405
04406
04407 Exit_occurs().Append(occurs);
04408 }
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422
04423
04424
04425
04426
04427 void
04428 EXP_WORKLST::Prune_phi_phi_pred(ETABLE *etable)
04429 {
04430 EXP_OCCURS_CONTAINER *occurs_list = &Phi_occurs();
04431 EXP_OCCURS *current_occ;
04432
04433
04434
04435
04436
04437
04438 for (current_occ = occurs_list->Head();
04439 current_occ != NULL;
04440 current_occ = current_occ->Next()) {
04441 EXP_PHI *current_phi = current_occ->Exp_phi();
04442 if (current_phi->Will_b_avail()) {
04443 for (INT i = 0; i < current_phi->Opnd_count(); i++) {
04444 current_phi->Pred(i)->Set_required_pred();
04445 }
04446 }
04447 else {
04448
04449
04450
04451 for (INT i = 0; i < current_phi->Opnd_count(); i++) {
04452 current_phi->Set_pred(i, NULL);
04453 }
04454 }
04455 }
04456
04457
04458
04459
04460
04461 occurs_list = &Phi_pred_occurs();
04462
04463 while ((current_occ = occurs_list->Head()) != NULL &&
04464 !current_occ->Required_pred()) {
04465 etable->Add_to_occ_freelist(occurs_list->Remove_Headnode());
04466 }
04467
04468 while (current_occ != NULL) {
04469 EXP_OCCURS *next_occ = current_occ->Next();
04470 while (next_occ != NULL &&
04471 !next_occ->Required_pred()) {
04472 occurs_list->Remove(current_occ, next_occ);
04473 etable->Add_to_occ_freelist(next_occ);
04474 next_occ = current_occ->Next();
04475 }
04476 current_occ = next_occ;
04477 }
04478 Set_phi_preds_pruned();
04479 }
04480
04481
04482 void
04483 ETABLE::Perform_PRE_optimization(void)
04484 {
04485 if (Tracing()) {
04486 fprintf( TFile, "%sProgram before Expr PRE:\n%s",
04487 DBar, DBar );
04488 Cfg()->Print(TFile);
04489 }
04490
04491 _str_red = CXX_NEW(STR_RED(Cfg(), Htable(), _etable_pool, _tracing),
04492 _etable_pool);
04493 _lftr = CXX_NEW(LFTR(this, Htable(), Cfg(), LFTR_HASH_SIZE), _etable_pool);
04494
04495
04496 INT32 Exc_sr_cands_phase = 0;
04497 INT32 Phi_placement_phase = 0;
04498 INT32 Iterator_phase = 0;
04499 INT32 Exp_renaming_phase = 0;
04500 INT32 Downsafe_prop_phase = 0;
04501 INT32 Phi_liveness_phase = 0;
04502 INT32 Avail_insert_phase = 0;
04503 INT32 Worklst_prune_phase = 0;
04504 INT32 Hoist_phase = 0;
04505 INT32 Save_reload_phase = 0;
04506 INT32 Ssa_min_phase = 0;
04507 INT32 Finalize_phase = 0;
04508
04509
04510 Cfg()->Dpo_vec();
04511
04512 Cfg()->Reset_stmt_id();
04513 if (Lftr()->Lftr_on()) {
04514 Cfg()->Analyze_loops();
04515 }
04516
04517 if (WOPT_Enable_Hoisting)
04518 _exp_hoisting = New_EXP_HOISTING(this, _etable_pool);
04519
04520 SET_OPT_PHASE("New PRE: Build initial occurrence lists");
04521
04522
04523 if (Get_Trace(TKIND_ALLOC, TP_WOPT1)) {
04524 MEM_Tracing_Enable();
04525 }
04526
04527 Init_worklst();
04528 INT first_rank_e_num = _cur_e_num;
04529 INT bb_cnt = 0, edge_cnt = 0;
04530
04531 #ifdef Is_True_On
04532 CFG_ITER cfg_iter;
04533 BB_NODE *bb;
04534 FOR_ALL_ELEM(bb, cfg_iter, Init(Cfg())) {
04535 bb_cnt++;
04536 edge_cnt += bb->Succ()->Len();
04537 }
04538 #endif
04539
04540 Is_Trace(Tracing(),
04541 (TFile, "NEWPRE: initial worklist has %d candidates\n", _cur_e_num));
04542
04543 EXP_WORKLST *cur_worklst;
04544 EXP_WORKLST_ITER2 worklst_iter(Exp_worklst(), Urgent_worklst());
04545 Lftr()->Set_exp_iter(&worklst_iter);
04546 INT32 cur_worklst_idx = 0;
04547 INT total_phi_count = 0;
04548 INT total_opt_ssa_count = 0;
04549 INT total_dense_ssa_count = 0;
04550 INT orig_coderep_id_cnt = Htable()->Coderep_id_cnt();
04551 FOR_ALL_NODE(cur_worklst, worklst_iter, Init()) {
04552
04553 ++cur_worklst_idx;
04554 if (WOPT_Enable_Exp_PRE_Limit != -1 &&
04555 cur_worklst_idx > WOPT_Enable_Exp_PRE_Limit) {
04556 DevWarn("NEWPRE: skip PRE for expression with e_num > %d",
04557 WOPT_Enable_Exp_PRE_Limit);
04558 break;
04559 }
04560
04561 OPT_POOL_Push(Per_expr_pool(), -1);
04562
04563 Is_Trace(Tracing(),
04564 (TFile, "\nprocessing %dth expression b=%s\n", cur_worklst_idx,
04565 cur_worklst->Exp()->Print_bit()));
04566 Is_Trace_cmd(Tracing(),cur_worklst->Exp()->Print(0,TFile));
04567 Is_Trace_cmd(Tracing(),cur_worklst->Print(TFile, Lftr()->Exp_hash(cur_worklst)));
04568
04569
04570
04571 Per_worklst_cleanup(cur_worklst);
04572 _str_red->Perform_per_expr_cleanup();
04573
04574 if ( !WOPT_Enable_New_SR || !MTYPE_is_integral(cur_worklst->Exp()->Dtyp())) {
04575
04576
04577
04578 cur_worklst->Set_exclude_sr_cand();
04579 }
04580
04581 SET_OPT_REPEAT_PHASE(Phi_placement_phase, "New PRE: Expr phi placement");
04582
04583 if (cur_worklst->Insert_exp_phi(this)) {
04584
04585
04586 SET_OPT_REPEAT_PHASE(Iterator_phase, "New PRE: Iterator");
04587 EXP_ALL_OCCURS_ITER *exp_occ_iter = (EXP_ALL_OCCURS_ITER *)
04588 CXX_NEW(EXP_ALL_OCCURS_ITER(cur_worklst,this,Lftr()), Per_expr_pool());
04589 cur_worklst->Set_iterator(exp_occ_iter);
04590
04591 SET_OPT_REPEAT_PHASE(Exp_renaming_phase, "New PRE: Rename");
04592 cur_worklst->Rename_expression(this);
04593
04594 SET_OPT_REPEAT_PHASE(Downsafe_prop_phase, "New PRE: DownSafety");
04595
04596
04597 if (cur_worklst->Propagate_downsafe(this)) {
04598
04599
04600
04601 BOOL optimization_needed;
04602
04603 {
04604
04605
04606
04607
04608 SET_OPT_REPEAT_PHASE(Avail_insert_phase,
04609 "New PRE: WillBeAvail");
04610
04611
04612
04613 OPT_POOL_Push(Etable_local_pool(), -1);
04614
04615 cur_worklst->Compute_forward_attributes(this);
04616
04617 if (!WOPT_Enable_SSA_Minimization) {
04618
04619 OPT_POOL_Pop(Etable_local_pool(), -1);
04620 }
04621
04622 if (WOPT_Enable_Worklist_Pruning) {
04623 SET_OPT_REPEAT_PHASE(Worklst_prune_phase,
04624 "New PRE: Phi/phi-pred pruning");
04625 cur_worklst->Prune_phi_phi_pred(this);
04626 }
04627
04628 if (WOPT_Enable_Hoisting) {
04629 SET_OPT_REPEAT_PHASE(Hoist_phase,
04630 "New PRE: Expr hoisting.");
04631 cur_worklst->Hoist_expression(Exp_hoisting());
04632 }
04633
04634 SET_OPT_REPEAT_PHASE(Save_reload_phase,
04635 "New PRE: Expr save/reload");
04636
04637 optimization_needed =
04638 cur_worklst->
04639 Compute_save_delete(Htable(), this,
04640 Lftr()->Exp_hash(cur_worklst));
04641
04642 if (WOPT_Enable_SSA_Minimization && optimization_needed) {
04643 SET_OPT_REPEAT_PHASE(Ssa_min_phase, "New PRE: SSA minimization");
04644 cur_worklst->Minimize_temp_ssa(this, Tracing());
04645 }
04646
04647 if (WOPT_Enable_SSA_Minimization) {
04648
04649 OPT_POOL_Pop(Etable_local_pool(), -1);
04650 }
04651 }
04652
04653 if (optimization_needed) {
04654 SET_OPT_REPEAT_PHASE(Finalize_phase, "New PRE: CodeMotion");
04655 cur_worklst->Generate_save_reload(this);
04656 }
04657 else {
04658 Is_Trace(Tracing(), (TFile,
04659 "ETABLE::Perform_PRE_optimization: "
04660 "skipping CodeMotion for expr %d\n",
04661 cur_worklst_idx));
04662 }
04663
04664 #ifdef Is_True_On
04665 if (WOPT_Enable_Verbose && Tracing()) {
04666 fprintf(TFile, "%sCFG after expression %d\n%s", DBar,
04667 cur_worklst_idx, DBar);
04668 Cfg()->Print(TFile);
04669 }
04670 cur_worklst->Verify();
04671 #endif
04672
04673 }
04674
04675 Is_Trace(Tracing(),
04676 (TFile, "NEWPRE: entire worklist has %d candidates\n", _cur_e_num));
04677
04678 Opt_tlog("New_PRE", 0,
04679 "%d-th expression: Inserts=%d, Saves=%d, Reloads=%d, Temp phis=%d, Hoisted=%d",
04680 cur_worklst_idx,
04681 cur_worklst->Insert_count(),
04682 cur_worklst->Save_count(),
04683 cur_worklst->Reload_count(),
04684 cur_worklst->Temp_phi_count(),
04685 cur_worklst->Hoisted_count());
04686
04687 #ifdef Is_True_On
04688
04689
04690
04691 Opt_tlog( "New_PRE", 0,
04692 "%d-th expression: Phis=%d(%d%%), Realoccs=%d(%d%%), Optimistic_SSA=%d(%d%%), Dense_SSA=%d(%d%%)",
04693 cur_worklst_idx,
04694 cur_worklst->Phi_count(),
04695 cur_worklst->Phi_count() * 100 / bb_cnt,
04696 cur_worklst->Realocc_count(),
04697 cur_worklst->Realocc_count() * 100 / bb_cnt,
04698 cur_worklst->Optimistic_ssa_count(),
04699 cur_worklst->Optimistic_ssa_count() * 100 / (bb_cnt+edge_cnt),
04700 cur_worklst->Dense_ssa_count(),
04701 cur_worklst->Dense_ssa_count() * 100 / (bb_cnt+edge_cnt));
04702
04703 #if 0
04704
04705 fprintf(TFile, "journal statistics: (phis, realoccs, inserts, deletes, bb_cnt, ssa_edge_cnt, edge_cnt) %d %d %d %d %d %d %d\n",
04706 cur_worklst->Phi_count(), cur_worklst->Realocc_count(),
04707 cur_worklst->Insert_count(), cur_worklst->Reload_count(), bb_cnt,
04708 cur_worklst->Ssa_edge_count(), edge_cnt);
04709 #endif
04710
04711 total_phi_count += cur_worklst->Phi_count();
04712 total_opt_ssa_count += cur_worklst->Optimistic_ssa_count();
04713 total_dense_ssa_count += cur_worklst->Dense_ssa_count();
04714 #endif
04715
04716 exp_occ_iter->Remove_iter();
04717 cur_worklst->Set_iterator(NULL);
04718 }
04719
04720 cur_worklst->Remove_occurs(this);
04721 OPT_POOL_Pop(Per_expr_pool(), -1);
04722
04723 if (WOPT_Enable_Verify >= 4) {
04724 Is_True(_comp_unit->Verify_CODEMAP(), ("CODEMAP corrupted."));
04725 _comp_unit->Verify_version();
04726 }
04727 }
04728
04729 #ifdef Is_True_On
04730 Opt_tlog("New_PRE_PU_info", 0,
04731 "CFG nodes=%d, edges=%d, nodes+edges=%d, init_enum=%d, final_enum=%d",
04732 bb_cnt,
04733 edge_cnt,
04734 bb_cnt + edge_cnt,
04735 first_rank_e_num,
04736 _cur_e_num);
04737
04738 if (_cur_e_num > 0) {
04739 total_phi_count /= _cur_e_num;
04740 total_opt_ssa_count /= _cur_e_num;
04741 total_dense_ssa_count /= _cur_e_num;
04742 }
04743
04744 Opt_tlog("New_PRE_PU_info", 0,
04745 "PU Average: Phis=%d(%d%%), Optimistic_SSA=%d(%d%%), Dense_SSA=%d(%d%%)",
04746 total_phi_count,
04747 total_phi_count * 100 / bb_cnt,
04748 total_opt_ssa_count,
04749 total_opt_ssa_count * 100 / (bb_cnt+edge_cnt),
04750 total_dense_ssa_count,
04751 total_dense_ssa_count * 100 / (bb_cnt+edge_cnt));
04752 #endif
04753
04754 if (Tracing()) {
04755 fprintf(TFile, "%sAfter SSA PRE\n%s", DBar, DBar);
04756 fprintf(TFile, "Statistics (all expressions): Insert Count %d, "
04757 "Save Count %d, Reload Count %d, Temp Phi Count %d, Hoisted Count %d\n",
04758 _num_inserted_saves, _num_cse_saves, _num_cse_reloads,
04759 _num_temp_phis, _num_hoisted);
04760 fprintf(TFile, "Coderep Statistics (entire PU): previous count: %d new count: %d\n",
04761 orig_coderep_id_cnt, Htable()->Coderep_id_cnt());
04762 fprintf(TFile, " Expr nodes changed to temps without rehashing: %d\n",
04763 _num_temp_owners);
04764 Cfg()->Print(TFile);
04765 Lftr()->Print(TFile);
04766 if (Get_Trace(TKIND_ALLOC, TP_WOPT1)) {
04767 MEM_Trace();
04768 }
04769 }
04770
04771 CXX_DELETE(_str_red,_etable_pool);
04772 CXX_DELETE(_lftr,_etable_pool);
04773 if (WOPT_Enable_Hoisting)
04774 Delete_EXP_HOISTING(_exp_hoisting);
04775
04776 #ifdef Is_True_On
04777 #if 0 // uncomment following line for lexically identical expr statistics
04778 Count_lex_ident_exprs(cur_worklst_idx);
04779 #endif
04780 #endif
04781 }
04782
04783
04784 void
04785 ETABLE::Clear_dpo_exp_phi(void)
04786 {
04787 BZERO( _dpo_exp_phi, Cfg()->Total_bb_count()*sizeof(_dpo_exp_phi[0]));
04788 }
04789
04790 void
04791 ETABLE::Clear_dpo_exp_phi(EXP_OCCURS_CONTAINER &worklist)
04792 {
04793 #ifdef Is_True_On
04794 INT32 count = 0;
04795 #endif
04796 EXP_OCCURS *exp_phi;
04797 EXP_OCCURS_ITER exp_phi_iter;
04798
04799 FOR_ALL_NODE (exp_phi, exp_phi_iter, Init(worklist.Head())) {
04800 _dpo_exp_phi[exp_phi->Bb()->Dom_dfs_id()] = NULL;
04801 #ifdef Is_True_On
04802 count++;
04803 #endif
04804 }
04805 Is_True(count == worklist.Len(),
04806 ("ETABLE::Clear_dpo_exp_phi, list size is wrong"));
04807 }
04808
04809 EXP_OCCURS*
04810 ETABLE::Set_exp_phi_bb(const BB_NODE *bb, EXP_OCCURS *exp_phi)
04811 {
04812 return _dpo_exp_phi[bb->Dom_dfs_id()] = exp_phi;
04813 }
04814
04815 EXP_OCCURS*
04816 ETABLE::Get_exp_phi_bb(const BB_NODE *bb)
04817 {
04818 return _dpo_exp_phi[bb->Dom_dfs_id()];
04819 }
04820
04821 static void Cleanup_loop_flags(BB_LOOP *first_loop, BOOL trace)
04822 {
04823 if (first_loop != NULL) {
04824
04825 BB_LOOP_ITER loop_iter;
04826 BB_LOOP *loop;
04827
04828 FOR_ALL_NODE(loop, loop_iter, Init(first_loop)) {
04829 Is_Trace(trace, (TFile, "BB%d ", loop->Body()->Id()));
04830 loop->Clear_flag(LOOP_HAS_REAL_OCC);
04831 Cleanup_loop_flags(loop->Child(), trace);
04832 }
04833 }
04834 }
04835
04836
04837 void
04838 ETABLE::Per_worklst_cleanup(EXP_WORKLST *exp_worklst) const
04839 {
04840
04841 BZERO(_phi_pred_cr, Cfg()->Total_bb_count() * sizeof(_phi_pred_cr[0]));
04842
04843
04844 Lftr()->Clear_def_occurs(exp_worklst);
04845
04846 if (WOPT_Enable_New_SR &&
04847 Lftr()->Lftr_on() &&
04848 Str_red()->Candidate_opc(exp_worklst->Exp()->Op())) {
04849 Is_Trace(WOPT_Enable_Verbose && Tracing(),
04850 (TFile, "Clearing LOOP_HAS_REAL_OCC flags:\n "));
04851 Cleanup_loop_flags(Cfg()->Loops(),
04852 WOPT_Enable_Verbose && Tracing());
04853 Is_Trace(WOPT_Enable_Verbose && Tracing(),
04854 (TFile, "\n"));
04855 }
04856 }
04857
04858 void
04859 ETABLE::Insert_stmtrep_after(STMTREP *new_stmt,
04860 STMTREP *old_stmt)
04861 {
04862 STMTREP *stmt = old_stmt;
04863 if (stmt->Is_saved_RHS()) {
04864 Is_True(stmt->Next(),
04865 ("ETABLE::Insert_stmtrep: cannot find the real statement"));
04866 stmt = stmt->Next();
04867 }
04868 stmt->Bb()->Insert_stmtrep_after( new_stmt, stmt );
04869 new_stmt->Set_stmt_id(stmt->Stmt_id());
04870 }
04871
04872 void
04873 COMP_UNIT::Do_new_pre(void)
04874 {
04875 MEM_POOL etable_pool, phi_pool, etable_local_pool;
04876
04877 OPT_POOL_Initialize(&etable_pool, "etable pool", FALSE, -1);
04878 OPT_POOL_Initialize(&phi_pool, "phi pool", FALSE, -1);
04879 OPT_POOL_Initialize(&etable_local_pool, "etable local pool", FALSE, -1);
04880 OPT_POOL_Push(&etable_pool, -1);
04881 OPT_POOL_Push(&phi_pool, -1);
04882 OPT_POOL_Push(&etable_local_pool, -1);
04883
04884 {
04885 ETABLE etable(Cfg(), Opt_stab(), Htable(), Arule(), 10,
04886 &etable_pool, &phi_pool, &etable_local_pool, this, PK_EPRE);
04887 etable.Perform_PRE_optimization();
04888 }
04889
04890 OPT_POOL_Pop(&etable_local_pool, -1);
04891 OPT_POOL_Pop(&phi_pool, -1);
04892 OPT_POOL_Pop(&etable_pool, -1);
04893 OPT_POOL_Delete(&etable_local_pool, -1);
04894 OPT_POOL_Delete(&phi_pool, -1);
04895 OPT_POOL_Delete(&etable_pool, -1);
04896 }
04897
04898 void
04899 EXP_WORKLST::Verify(void)
04900 {
04901 Is_True(_real_occurs.Head() != NULL && _real_occurs.Tail() != NULL,
04902 ("EXP_WORKLST::Verify, null occurrence list"));
04903 Is_True(_exp != NULL,
04904 ("EXP_WORKLST::Verify, null exp"));
04905 Is_True(_iterator != NULL,
04906 ("EXP_WORKLST::Verify, null iterator"));
04907 }
04908
04909 void
04910 EXP_OCCURS::Print(FILE *fp, BOOL show_phi_preds) const
04911 {
04912 if (Occurrence() != NULL) {
04913 if (WOPT_Enable_Verbose)
04914 Occurrence()->Print(1, fp);
04915 else
04916 fprintf(fp, "cr%d", Occurrence()->Coderep_id());
04917 } else {
04918 fprintf(fp, "cr???");
04919 }
04920 if (Occ_kind() != OCC_PHI_PRED_OCCUR ||
04921 Inserted_computation())
04922 fprintf(fp, " Ver%02d ", E_version());
04923 else
04924 fprintf(fp, " ");
04925 switch (Occ_kind()) {
04926 case OCC_PHI_PRED_OCCUR:
04927 case OCC_REAL_OCCUR:
04928 if (Occ_kind() == OCC_PHI_PRED_OCCUR) {
04929 fprintf(fp, " (%s in BB%d)",
04930 (For_spre())? "iphi-succ" : "phi-pred",
04931 ((BB_NODE *) Bb())->Id());
04932 }
04933 if (Sunk_lvalue())
04934 fprintf(fp, " (sunk-lvalue)");
04935 if (Occ_kind() == OCC_REAL_OCCUR || Inserted_computation()) {
04936 if (Occ_kind() == OCC_PHI_PRED_OCCUR &&
04937 Inserted_computation()) {
04938 fprintf(fp, " (inserted real)");
04939 }
04940 else {
04941 if (Occ_kind() != OCC_REAL_OCCUR) {
04942 fprintf(fp, " (BAD KIND in BB%d Sid%d)",
04943 Enclosed_in_stmt()->Bb()->Id(),
04944 Enclosed_in_stmt()->Stmt_id());
04945 }
04946 else {
04947 fprintf(fp, " (real in BB%d Sid%d)",
04948 Bb()->Id(),
04949 Is_flag_set(OCC_HOISTED) ? 0 : Enclosed_in_stmt()->Stmt_id());
04950 if (WOPT_Enable_Verbose && !Is_flag_set(OCC_HOISTED) && !For_spre()) {
04951 fprintf(fp, "Enclosing statement:\n");
04952 Enclosed_in_stmt()->Print(fp);
04953 }
04954 }
04955 }
04956 if (! For_spre()) {
04957 if (Occ_kind() == OCC_REAL_OCCUR)
04958 fprintf(fp, " kid %d", Stmt_kid_num());
04959 if (Mult_real())
04960 fprintf(fp, " (multi-real)");
04961 if (Occ_kind() == OCC_PHI_PRED_OCCUR) {
04962 if (Is_flag_set(OCC_REQUIRED_PRED)) {
04963 fprintf(fp, " (required)");
04964 }
04965 }
04966 else {
04967 if (Is_flag_set(OCC_AS_L_VALUE))
04968 fprintf(fp, " (left-value)");
04969 }
04970 if (Is_flag_set(OCC_INJURED))
04971 fprintf(fp, " (injured)");
04972 if (Occ_kind() == OCC_REAL_OCCUR) {
04973 if (Delete_comp())
04974 fprintf(fp, " (reload)");
04975 if (Save_to_temp()) {
04976 fprintf(fp, " (compute and save)");
04977 if (T_ver_owns_coderep())
04978 fprintf(fp, " (owns coderep)");
04979 }
04980 fprintf(fp, " rehash_cost: %d", Rehash_cost());
04981 }
04982 }
04983 else {
04984 if (Occ_kind() == OCC_REAL_OCCUR) {
04985 if (Fake_store())
04986 fprintf(fp, " (fake-store)");
04987 if (Is_flag_set(OCC_AS_L_VALUE))
04988 fprintf(fp, " (left-value)");
04989 if (Delete_comp())
04990 fprintf(fp, " (deleted)");
04991 if (Save_to_temp())
04992 fprintf(fp, " (cause earlier deletions)");
04993 }
04994 }
04995 }
04996 fprintf(fp, "\n");
04997 break;
04998 case OCC_PHI_OCCUR:
04999 fprintf(fp, " (%s in BB%d) ", (For_spre()? "iphi" : "phi"), Bb()->Id());
05000 if (T_ver_owns_coderep())
05001 fprintf(fp, " (owns coderep)");
05002 Exp_phi()->Print(fp, show_phi_preds);
05003 break;
05004 case OCC_COMP_OCCUR:
05005 fprintf(fp, " (comp in BB%d Sid%d)%s\n",
05006 Enclosed_in_stmt()->Bb()->Id(),
05007 Enclosed_in_stmt()->Stmt_id(),
05008 (Obsolete_comparison() ? " (obsolete)" : ""));
05009 break;
05010 case OCC_EXIT_OCCUR:
05011 fprintf(fp, "(exit in BB%d)\n",((BB_NODE *) Enclosed_in_bb())->Id());
05012 break;
05013 default:
05014 FmtAssert(FALSE,("Is an undefined occurrence (Kind == %d).\n",Occ_kind()));
05015 break;
05016 }
05017 }
05018
05019 void
05020 EXP_WORKLST::Print(FILE *fp, EXP_OCCURS_PAIR *comp_occurs)
05021 {
05022 if (Pre_kind() != PK_SPRE)
05023 fprintf(fp,"<E_NUM=%d|PREG=%d", E_num(), Preg());
05024 else
05025 fprintf(fp,"<E_NUM=%d", E_num());
05026 if (Exp() != NULL) {
05027 Exp()->Print_node(1, fp);
05028 } else {
05029 fprintf(fp, "Has no expression coderep\n");
05030 }
05031 fprintf(fp," occurrences are:\n");
05032 EXP_OCCURS *exp_occ;
05033
05034 EXP_ALL_OCCURS_ITER exp_occ_iter(Real_occurs().Head(),
05035 comp_occurs,
05036 Phi_occurs().Head(),
05037 Phi_pred_occurs().Head(),
05038 NULL );
05039 FOR_ALL_NODE(exp_occ, exp_occ_iter, Init())
05040 exp_occ->Print(fp, !Phi_preds_pruned());
05041
05042 if (Pre_kind() != PK_SPRE) {
05043 fprintf(fp, "Statistics: %d insertions, "
05044 "%d saves, %d reloads, %d temp phis\n",
05045 _insert_cnt, _save_cnt, _reload_cnt, _temp_phi_cnt);
05046 fprintf(fp, "Statistics: %d expr nodes changed to temps without rehashing\n",
05047 _temp_owner_cnt);
05048 }
05049 else {
05050 fprintf(fp, "Statistics: %d deletions, %d insertions\n",
05051 _reload_cnt, _insert_cnt);
05052 }
05053 }
05054
05055 void
05056 EXP_OCCURS_CONTAINER::Print(FILE *fp)
05057 {
05058 INT32 count = 0;
05059 EXP_OCCURS *exp_occ;
05060 EXP_OCCURS_ITER exp_occ_iter;
05061 FOR_ALL_NODE (exp_occ, exp_occ_iter, Init(Head())) {
05062 exp_occ->Print(fp);
05063 count++;
05064 }
05065 Is_True(count == Len(),("EXP_OCCURS_CONTAINER::Print, list size is wrong"));
05066 }
05067
05068 #ifdef Is_True_On
05069
05070
05071 class EXPREP: public SLIST_NODE {
05072 friend class EXPREP_CONTAINER;
05073 friend class XTABLE;
05074 private:
05075 CODEREP *_cr;
05076 INT32 _exprep_id;
05077
05078 EXPREP(void);
05079 EXPREP(const EXPREP&);
05080 EXPREP& operator = (const EXPREP&);
05081
05082 EXPREP(CODEREP *cr, INT32 id): _cr(cr), _exprep_id(id) {}
05083 ~EXPREP(void) {}
05084 };
05085
05086 class EXPREP_CONTAINER: public SLIST {
05087 private:
05088 EXPREP_CONTAINER(const EXPREP_CONTAINER&);
05089 EXPREP_CONTAINER& operator = (const EXPREP_CONTAINER&);
05090
05091 DECLARE_SLIST_CLASS(EXPREP_CONTAINER,EXPREP)
05092 ~EXPREP_CONTAINER(void) {}
05093 };
05094
05095 class EXPREP_ITER: public SLIST_ITER {
05096 DECLARE_SLIST_ITER_CLASS(EXPREP_ITER, EXPREP, EXPREP_CONTAINER)
05097 };
05098
05099 class XTABLE {
05100 friend void ETABLE::Count_lex_ident_exprs(INT32);
05101 private:
05102 ARRAY<EXPREP *> _e_hash;
05103 ARRAY<EXPREP *> _cr_id_2_exprep;
05104 INT32 _expr_count;
05105 INT32 _compound_count;
05106 MEM_POOL *_local_pool;
05107 OPT_STAB *_opt_stab;
05108
05109 XTABLE(void);
05110 XTABLE(const XTABLE&);
05111 XTABLE& operator = (const XTABLE&);
05112
05113 XTABLE(MEM_POOL *lpool, OPT_STAB *opt_stab, CODEMAP *htable):
05114 _local_pool(lpool), _opt_stab(opt_stab), _expr_count(0),
05115 _compound_count(0), _e_hash(CODE_ITABLE_SIZE, lpool),
05116 _cr_id_2_exprep(htable->Coderep_id_cnt(), lpool) {}
05117 ~XTABLE(void) {}
05118
05119 BOOL Opnd_lex_identical(CODEREP *cr1, CODEREP *cr2) const;
05120 BOOL Lexically_identical(CODEREP *cr1, CODEREP *cr2) const;
05121 BOOL Is_compound(CODEREP *cr) const;
05122 IDX_32 Hashvalue(CODEREP *cr) const;
05123 IDX_32 Hash(CODEREP *cr) const;
05124 void Add_nonterm(CODEREP *cr);
05125 void Bottom_up_cr(CODEREP *cr);
05126 };
05127
05128
05129
05130 BOOL
05131 XTABLE::Opnd_lex_identical(CODEREP *cr1, CODEREP *cr2) const
05132 {
05133 if (cr1->Kind() != cr2->Kind())
05134 return FALSE;
05135 if (! cr1->Non_leaf() && cr1->Kind() != CK_VAR)
05136 return cr1 == cr2;
05137 if (cr1->Kind() == CK_VAR)
05138 return cr1->Aux_id() == cr2->Aux_id();
05139 if (cr1->Op() != cr2->Op())
05140 return FALSE;
05141 return _cr_id_2_exprep[cr1->Coderep_id()] ==
05142 _cr_id_2_exprep[cr2->Coderep_id()];
05143 }
05144
05145
05146
05147 BOOL
05148 XTABLE::Lexically_identical(CODEREP *cr1, CODEREP *cr2) const
05149 {
05150 if (cr1->Kind() != cr2->Kind()) return FALSE;
05151 if (cr1->Kind() == CK_IVAR) {
05152 if (cr1->Op() != cr1->Op()) return FALSE;
05153 if (cr1->Offset() != cr2->Offset()) return FALSE;
05154 if (Get_mtype_class(cr1->Dtyp()) != Get_mtype_class(cr2->Dtyp()))
05155 return FALSE;
05156 if (MTYPE_size_min(cr1->Dsctyp()) != MTYPE_size_min(cr2->Dsctyp()))
05157 return FALSE;
05158 CODEREP *base1 = cr1->Ilod_base() ? cr1->Ilod_base() : cr1->Istr_base();
05159 CODEREP *base2 = cr2->Ilod_base() ? cr2->Ilod_base() : cr2->Istr_base();
05160 if (! Opnd_lex_identical(base1, base2))
05161 return FALSE;
05162 if (cr1->Opr() == OPR_MLOAD) {
05163 if (! Opnd_lex_identical(cr1->Mload_size(), cr2->Mload_size()))
05164 return FALSE;
05165 }
05166 else if (cr1->Opr() == OPR_ILOADX) {
05167 if (! Opnd_lex_identical(cr1->Index(), cr2->Index()))
05168 return FALSE;
05169 }
05170 }
05171 else {
05172 if (cr1->Kid_count() != cr2->Kid_count()) return FALSE;
05173 if (OPCODE_commutative_op(cr1->Op()) == cr1->Op()) {
05174 if (! (Opnd_lex_identical(cr1->Opnd(0), cr2->Opnd(0)) &&
05175 Opnd_lex_identical(cr1->Opnd(1), cr2->Opnd(1))) &&
05176 ! (Opnd_lex_identical(cr1->Opnd(0), cr2->Opnd(1)) &&
05177 Opnd_lex_identical(cr1->Opnd(1), cr2->Opnd(0))))
05178 return FALSE;
05179 }
05180 else {
05181 for (INT32 i =0; i < cr1->Kid_count(); i++)
05182 if (! Opnd_lex_identical(cr1->Opnd(i), cr2->Opnd(i)))
05183 return FALSE;
05184 }
05185
05186 if (cr1->Opr() == OPR_INTRINSIC_OP)
05187 if (cr1->Intrinsic() != cr2->Intrinsic()) return FALSE;
05188 #ifdef KEY
05189 if (cr1->Opr() == OPR_PURE_CALL_OP)
05190 if (cr1->Call_op_aux_id() != cr2->Call_op_aux_id()) return FALSE;
05191 #endif
05192 if (cr1->Opr() == OPR_CVTL)
05193 if (cr1->Offset() != cr2->Offset()) return FALSE;
05194 }
05195 return TRUE;
05196 }
05197
05198 IDX_32
05199 XTABLE::Hashvalue(CODEREP *cr) const
05200 {
05201 if (inCODEKIND(cr->Kind(), CK_CONST|CK_RCONST|CK_LDA))
05202 return cr->Coderep_id() << 6;
05203 else if (cr->Kind() == CK_VAR)
05204 return cr->Aux_id() << 6;
05205 return _cr_id_2_exprep[cr->Coderep_id()]->_exprep_id << 6;
05206 }
05207
05208
05209 IDX_32
05210 XTABLE::Hash(CODEREP *cr) const
05211 {
05212 if (cr->Kind() == CK_IVAR) {
05213 CODEREP *base = cr->Ilod_base() ? cr->Ilod_base() : cr->Istr_base();
05214 return (Hashvalue(base) + cr->Offset()) % _e_hash.Size();
05215 }
05216
05217 IDX_32 hvalue = 0;
05218 if (cr->Opr() != OPR_INTRINSIC_OP
05219 #ifdef KEY
05220 && cr->Opr() != OPR_PURE_CALL_OP
05221 #endif
05222 ) {
05223 for (INT32 i = 0; i < cr->Kid_count(); i++)
05224 hvalue += Hashvalue(cr->Opnd(i));
05225 }
05226 else {
05227 for (INT32 i = 0; i < cr->Kid_count(); i++)
05228 hvalue += Hashvalue(cr->Opnd(i)->Ilod_base());
05229 }
05230 return (cr->Op() + hvalue) % _e_hash.Size();
05231 }
05232
05233 BOOL
05234 XTABLE::Is_compound(CODEREP *cr) const
05235 {
05236 if (cr->Kind() == CK_IVAR) {
05237 if (cr->Opr() == OPR_MLOAD)
05238 return TRUE;
05239 if (cr->Opr() == OPR_ILOADX)
05240 if (! cr->Index()->Is_non_volatile_terminal(_opt_stab))
05241 return TRUE;
05242 CODEREP *base = cr->Ilod_base() ? cr->Ilod_base() : cr->Istr_base();
05243 if (! base->Is_non_volatile_terminal(_opt_stab))
05244 return TRUE;
05245 return FALSE;
05246 }
05247
05248 if (cr->Is_isop_flag_set(ISOP_SSAPRE_OMITTED))
05249 return TRUE;
05250 if (cr->Opr() != OPR_INTRINSIC_OP
05251 #ifdef KEY
05252 && cr->Opr() != OPR_PURE_CALL_OP
05253 #endif
05254 ) {
05255 for (INT32 i = 0; i < cr->Kid_count(); i++)
05256 if (! cr->Opnd(i)->Is_non_volatile_terminal(_opt_stab))
05257 return TRUE;
05258 }
05259 else {
05260 for (INT32 i = 0; i < cr->Kid_count(); i++)
05261 if (! cr->Opnd(i)->Ilod_base()->Is_non_volatile_terminal(_opt_stab))
05262 return TRUE;
05263 }
05264 return FALSE;
05265 }
05266
05267
05268 void
05269 XTABLE::Add_nonterm(CODEREP *cr)
05270 {
05271 if (_cr_id_2_exprep[cr->Coderep_id()] != NULL)
05272 return;
05273 IDX_32 hash_idx = Hash(cr);
05274 EXPREP_CONTAINER bucket;
05275 bucket.Set_Head(_e_hash[hash_idx]);
05276 EXPREP_ITER exprep_iter;
05277 EXPREP *exp;
05278 BOOL found = FALSE;
05279 FOR_ALL_NODE(exp, exprep_iter, Init(&bucket))
05280 if (Lexically_identical(exp->_cr, cr)) {
05281 found = TRUE;
05282 break;
05283 }
05284 if (! found) {
05285 _expr_count++;
05286 exp = (EXPREP *) CXX_NEW(EXPREP(cr, _expr_count), _local_pool);
05287 if (Is_compound(cr))
05288 _compound_count++;
05289 bucket.Prepend(exp);
05290 _e_hash[hash_idx] = bucket.Head();
05291 }
05292 else if (cr->Kind() == CK_OP &&
05293 exp->_cr->Is_isop_flag_set(ISOP_SSAPRE_OMITTED)) {
05294
05295 if (! Is_compound(cr)) {
05296 exp->_cr = cr;
05297 _compound_count--;
05298 }
05299 }
05300 _cr_id_2_exprep[cr->Coderep_id()] = exp;
05301 }
05302
05303
05304
05305
05306 void
05307 XTABLE::Bottom_up_cr(CODEREP *cr)
05308 {
05309 switch(cr->Kind()) {
05310 case CK_CONST:
05311 case CK_RCONST:
05312 case CK_LDA:
05313 case CK_VAR:
05314 return;
05315 case CK_IVAR: {
05316 const OPERATOR ivar_opr = cr->Opr();
05317 if (cr->Ilod_base())
05318 Bottom_up_cr(cr->Ilod_base());
05319 else Bottom_up_cr(cr->Istr_base());
05320 if (ivar_opr == OPR_MLOAD)
05321 Bottom_up_cr(cr->Mload_size());
05322 else if (ivar_opr == OPR_ILOADX)
05323 Bottom_up_cr(cr->Index());
05324 Add_nonterm(cr);
05325 return;
05326 }
05327 case CK_OP: {
05328 if (cr->Opr() != OPR_INTRINSIC_OP
05329 #ifdef KEY
05330 && cr->Opr() != OPR_PURE_CALL_OP
05331 #endif
05332 ) {
05333 for (INT32 i=0; i < cr->Kid_count(); i++)
05334 Bottom_up_cr(cr->Opnd(i));
05335 Add_nonterm(cr);
05336 }
05337 else {
05338 for (INT32 i=0; i < cr->Kid_count(); i++)
05339 Bottom_up_cr(cr->Opnd(i)->Ilod_base());
05340 Add_nonterm(cr);
05341 }
05342 return;
05343 }
05344 default:
05345 Is_True(0, ("XTABLE::Bottom_up_cr: unexpected coderep kind"));
05346 return;
05347 }
05348 }
05349
05350
05351
05352
05353 void
05354 ETABLE::Count_lex_ident_exprs(INT32 simple_count)
05355 {
05356 MEM_POOL local_pool;
05357 OPT_POOL_Initialize(&local_pool, "Count_lex_ident_exprs local pool", FALSE, -1);
05358 OPT_POOL_Push(&local_pool, -1);
05359
05360 XTABLE xtable(&local_pool, Opt_stab(), Htable());
05361
05362
05363 BB_NODE *bb;
05364 CFG_ITER cfg_iter(Cfg());
05365 FOR_ALL_ELEM(bb, cfg_iter, Init()) {
05366 STMTREP_ITER stmt_iter(bb->Stmtlist());
05367 STMTREP *stmt;
05368 FOR_ALL_NODE(stmt, stmt_iter, Init()) {
05369 CODEREP *rhs = stmt->Rhs();
05370 if (OPCODE_is_fake(stmt->Op())) {
05371 for (INT32 i = 0; i < rhs->Kid_count(); i++)
05372 if (rhs->Opnd(i)->Kind() == CK_IVAR &&
05373 rhs->Opnd(i)->Opr() == OPR_PARM)
05374 xtable.Bottom_up_cr(rhs->Opnd(i)->Ilod_base());
05375 else xtable.Bottom_up_cr(rhs->Opnd(i));
05376 }
05377 else if (rhs != NULL) {
05378 xtable.Bottom_up_cr(rhs);
05379 }
05380 if (stmt->Lhs())
05381 xtable.Bottom_up_cr(stmt->Lhs());
05382 }
05383 }
05384
05385 fprintf(TFile, "%8d simple and %8d compound expressions seen by SSAPRE in PU %s\n",
05386 simple_count, xtable._compound_count, Cur_PU_Name);
05387 #if 0
05388
05389
05390 Is_True(simple_count + xtable._compound_count >= xtable._expr_count &&
05391 xtable._expr_count >= 0.98 * (simple_count + xtable._compound_count),
05392 ("Etable::Count_lex_ident_exprs: error in counting: total is %d",
05393 xtable._expr_count));
05394 #endif
05395
05396 OPT_POOL_Pop(&local_pool, -1);
05397 OPT_POOL_Delete(&local_pool, -1);
05398 }
05399 #endif