00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #ifdef USE_PCH
00063 #include "opt_pch.h"
00064 #endif // USE_PCH
00065 #pragma hdrstop
00066
00067
00068 #ifdef _KEEP_RCS_ID
00069 #define opt_dse_CXX "opt_dse.cxx"
00070 static char *rcs_id = opt_dse_CXX"$Revision: 1.17 $";
00071 #endif
00072
00073 #include "defs.h"
00074 #include "opt_config.h"
00075 #include "errors.h"
00076 #include "erglob.h"
00077 #include "tracing.h"
00078
00079 #include "opt_base.h"
00080 #include "opt_cfg.h"
00081 #include "opt_exc.h"
00082 #include "opt_mu_chi.h"
00083 #include "opt_ssa.h"
00084 #include "opt_mu_chi.h"
00085 #include "opt_util.h"
00086 #include <vector>
00087 using std::vector;
00088 #include "opt_alias_rule.h"
00089 #include "idx_32_set.h"
00090
00091
00092
00093
00094 class DSE {
00095 private:
00096
00097 CFG *_cfg;
00098 OPT_STAB *_opt_stab;
00099 EXC *_exc;
00100 MEM_POOL *_loc_pool;
00101 WN_MAP _live_wns;
00102
00103 BOOL _tracing;
00104 #ifdef TARG_SL
00105 vector <WN *> *_injury_aux_intrnop;
00106 #endif
00107 vector <WN *> *_last_store_vec;
00108 vector <IDX_32_SET *> * _alias_aux_vec;
00109
00110
00111
00112
00113 CFG *Cfg( void ) const
00114 { return _cfg; }
00115 OPT_STAB *Opt_stab( void ) const
00116 { return _opt_stab; }
00117 MEM_POOL *Loc_pool( void ) const
00118 { return _loc_pool; }
00119 BOOL Tracing( void ) const
00120 { return _tracing; }
00121
00122
00123
00124
00125 BOOL Required_call( const WN *wn ) const;
00126 BOOL Required_istore( const WN *wn ) const;
00127 BOOL Required_stid( const WN *wn ) const;
00128 BOOL Required_load( const WN *wn ) const;
00129 BOOL Required_stmt( const WN *wn ) const;
00130 BOOL Check_Required_Expr( WN *wn ) const;
00131 BOOL Is_deleted_statement( WN *stmt ) const;
00132
00133 void Set_Required_VSE( VER_STAB_ENTRY *, BOOL , WN * ) const;
00134 void Set_Required_PHI( VER_STAB_ENTRY *vse, WN *ref_wn ) const;
00135 void Set_Required_MU( MU_NODE *mu, BOOL real_use ) const;
00136 void Set_Required_CHI( CHI_NODE *chi, BOOL *chi_is_live ) const;
00137 void Set_Required_WN( WN *wn ) const;
00138 void Add_EH_exposed_use(WN *call) const;
00139 #ifdef KEY
00140 void Add_entry_exposed_uses(WN *call) const;
00141 #endif
00142 void Update_MU_list_for_call(BB_NODE *bb) const;
00143
00144 BOOL Live_wn( WN *wn ) const
00145 { return WN_MAP32_Get( _live_wns, wn ); }
00146 void Set_live_wn( WN *wn ) const
00147 { WN_MAP32_Set( _live_wns, wn, 1 ); }
00148
00149 #if defined(TARG_SL)
00150 void Repair_Injured_AuxIntrnOP(void) const ;
00151 void Append_Injured_AuxIntrnOp(WN *wn) const { _injury_aux_intrnop->insert(_injury_aux_intrnop->begin(), wn);};
00152 #endif
00153 WN* Last_store(AUX_ID aid) const
00154 { return (*_last_store_vec)[aid]; }
00155 void Set_last_store( AUX_ID aid, WN *store) const
00156 { (*_last_store_vec)[aid] = store; }
00157 BOOL Aliased_aux( AUX_ID id1, AUX_ID id2) const
00158 {
00159 if((*_alias_aux_vec)[id1]->MemberP(id2))
00160 return TRUE;
00161 else
00162 return FALSE;
00163 }
00164
00165
00166 BOOL Mem_WN_equiv_rec(WN *wn1, WN *wn2) const;
00167 BOOL Mem_WN_equiv(WN *wn1, WN* wn2) const;
00168 BOOL Same_memloc( WN* store1, WN* store2) const;
00169 VER_ID Prop_vsym_new_result( VER_ID vid ) const;
00170 void Propagate_vsym_wn( WN *wn ) const;
00171 void Propagate_vsym_bb( BB_NODE *bb ) const;
00172
00173 public:
00174
00175 DSE( CFG *cfg, OPT_STAB *opt_stab, MEM_POOL *pool, EXC *exc, BOOL tracing )
00176 : _cfg(cfg), _opt_stab(opt_stab), _loc_pool(pool), _exc(exc),
00177 _tracing(tracing)
00178 {
00179
00180 _live_wns = WN_MAP32_Create(Loc_pool());
00181 #ifdef TARG_SL
00182 _injury_aux_intrnop = CXX_NEW(vector<WN *>, pool);
00183 #endif
00184
00185
00186 INT asym_count = Opt_stab()->Lastidx() + 1;
00187 _last_store_vec = CXX_NEW(vector<WN *>, pool);
00188 _last_store_vec->insert(_last_store_vec->end(), asym_count, (WN*)NULL);
00189
00190
00191 _alias_aux_vec = CXX_NEW(vector<IDX_32_SET*>, pool);
00192 for( INT aid = 0; aid < asym_count; aid++) {
00193 IDX_32_SET *alias_set = CXX_NEW( IDX_32_SET(asym_count, pool, OPTS_FALSE), pool);
00194 _alias_aux_vec->push_back(alias_set);
00195 }
00196 for(INT aid = 1; aid<asym_count; aid++) {
00197 (*_alias_aux_vec)[aid]->Union1D(aid);
00198 POINTS_TO *apt = Opt_stab()->Points_to(aid);
00199 for(INT nid = aid +1; nid<asym_count; nid++) {
00200 if(Opt_stab()->Rule()->Aliased_Memop( Opt_stab()->Points_to(nid), apt)) {
00201 (*_alias_aux_vec)[aid]->Union1D(nid);
00202 (*_alias_aux_vec)[nid]->Union1D(aid);
00203 }
00204 }
00205 }
00206 }
00207
00208 ~DSE( void )
00209 {
00210
00211 WN_MAP_Delete( _live_wns );
00212 }
00213
00214 void Dead_store_elim( void ) const;
00215 void Add_MU_list_for_calls( void ) const;
00216
00217 };
00218
00219
00220
00221
00222
00223
00224 BOOL
00225 DSE::Required_call( const WN *wn ) const
00226 {
00227
00228
00229 Warn_todo("DSE::Required_call see if the callee has side-effects");
00230 return ( TRUE );
00231 }
00232
00233
00234
00235
00236
00237
00238 BOOL
00239 DSE::Required_istore(const WN *wn) const
00240 {
00241 TY_IDX ty = WN_ty(wn);
00242
00243 if (Ilod_TY_is_volatile(ty))
00244 return TRUE;
00245
00246
00247 OCC_TAB_ENTRY *occ = Opt_stab()->Get_occ(wn);
00248 if (occ->Points_to()->Unique_pt() ||
00249 occ->Points_to()->Restricted())
00250 return TRUE;
00251
00252 #ifdef KEY // deleting fetch of MTYPE_M return value can cause lowerer to omit
00253
00254 if (Opt_stab()->Phase() == PREOPT_IPA0_PHASE && WN_desc(wn) == MTYPE_M &&
00255 WN_opcode(WN_kid0(wn)) == OPC_MMLDID) {
00256 ST *s = Opt_stab()->St(Opt_stab()->Du_aux_id(WN_ver(WN_kid0(wn))));
00257 if (ST_class(s) == CLASS_PREG && Preg_Is_Dedicated(WN_offset(wn)))
00258 return TRUE;
00259 }
00260 #endif
00261
00262 return FALSE;
00263 }
00264
00265
00266
00267
00268
00269
00270
00271 BOOL
00272 DSE::Required_stid( const WN *wn ) const
00273 {
00274 TY_IDX ty = WN_ty(wn);
00275
00276
00277 if ( Lod_TY_is_volatile(ty) )
00278 return TRUE;
00279
00280
00281 IDTYPE du = WN_ver(wn);
00282 if ( Opt_stab()->Du_is_volatile(du) )
00283 return TRUE;
00284
00285
00286 ST *s = Opt_stab()->St(Opt_stab()->Du_aux_id(du));
00287 if (ST_class(s) == CLASS_PREG && Preg_Is_Dedicated(WN_offset(wn)))
00288 return TRUE;
00289
00290 if (ST_sclass(s) == SCLASS_FORMAL)
00291 return TRUE;
00292
00293 #ifdef KEY // bugs 5401 and 5267
00294 if (Opt_stab()->Aux_stab_entry(Opt_stab()->Du_aux_id(du))->Mp_no_dse())
00295 return TRUE;
00296 #endif
00297
00298 #ifdef KEY // deleting fetch of MTYPE_M return value can cause lowerer to omit
00299
00300 if (Opt_stab()->Phase() == PREOPT_IPA0_PHASE && WN_desc(wn) == MTYPE_M &&
00301 WN_opcode(WN_kid0(wn)) == OPC_MMLDID) {
00302 s = Opt_stab()->St(Opt_stab()->Du_aux_id(WN_ver(WN_kid0(wn))));
00303 if (ST_class(s) == CLASS_PREG && Preg_Is_Dedicated(WN_offset(wn)))
00304 return TRUE;
00305 }
00306 #endif
00307 #ifdef TARG_SL
00308 if (WN_Intrinsic_OP_Slave(WN_kid0(wn))) {
00309 Append_Injured_AuxIntrnOp((WN *)wn);
00310 }
00311 #endif
00312
00313 return FALSE;
00314 }
00315
00316
00317
00318
00319
00320
00321 BOOL
00322 DSE::Required_load( const WN *wn ) const
00323 {
00324 TY_IDX ty = WN_ty(wn);
00325 if ( Lod_TY_is_volatile(ty) )
00326 return TRUE;
00327
00328 const OPERATOR opr = WN_operator(wn);
00329 switch ( opr ) {
00330 case OPR_LDID:
00331 case OPR_LDBITS:
00332 {
00333
00334 IDTYPE du = WN_ver(wn);
00335 if ( Opt_stab()->Du_is_volatile(du) )
00336 return TRUE;
00337 }
00338 break;
00339
00340 case OPR_MLOAD:
00341 {
00342
00343 Is_True( TY_kind(ty) == KIND_POINTER,
00344 ("Required_load: ty in MLOAD not pointer") );
00345
00346 if (Ilod_TY_is_volatile(ty))
00347 return TRUE;
00348 }
00349 break;
00350
00351 case OPR_ILOAD:
00352 case OPR_ILOADX:
00353 case OPR_ILDBITS:
00354 {
00355 TY_IDX load_addr_ty = WN_load_addr_ty(wn);
00356
00357 Is_True( TY_kind(load_addr_ty) == KIND_POINTER,
00358 ("Required_load: load_addr_ty in ILOAD not pointer") );
00359
00360 if ( Ilod_TY_is_volatile(load_addr_ty) )
00361 return TRUE;
00362 }
00363 break;
00364
00365 default:
00366 Is_True( FALSE,
00367 ("Required_load: unknown load: %s",
00368 OPCODE_name(WN_opcode(wn))) );
00369 break;
00370 }
00371
00372 return FALSE;
00373 }
00374
00375
00376
00377
00378
00379
00380
00381 BOOL
00382 DSE::Required_stmt( const WN *wn ) const
00383 {
00384 if ( ! WOPT_Enable_Dse_Aggressive )
00385 return TRUE;
00386 OPERATOR oper = WN_operator(wn);
00387
00388
00389 switch ( oper ) {
00390 case OPR_AGOTO:
00391 case OPR_ASSERT:
00392 case OPR_BACKWARD_BARRIER:
00393 case OPR_TRUEBR:
00394 case OPR_FALSEBR:
00395 case OPR_COMPGOTO:
00396 case OPR_FORWARD_BARRIER:
00397 case OPR_GOTO:
00398 case OPR_IO:
00399 case OPR_LABEL:
00400 case OPR_PRAGMA:
00401 case OPR_REGION:
00402 case OPR_RETURN:
00403 case OPR_RETURN_VAL:
00404 case OPR_PREFETCH:
00405 case OPR_PREFETCHX:
00406 return TRUE;
00407
00408 case OPR_CALL:
00409 case OPR_ICALL:
00410 case OPR_INTRINSIC_CALL:
00411 return Required_call( wn );
00412
00413 case OPR_MSTORE:
00414 case OPR_ISTORE:
00415 case OPR_ISTBITS:
00416 case OPR_ISTOREX:
00417 return Required_istore( wn );
00418
00419 case OPR_STID:
00420 case OPR_STBITS:
00421 return Required_stid( wn );
00422
00423 default:
00424 return TRUE;
00425 }
00426 }
00427
00428
00429
00430
00431
00432
00433 void
00434 DSE::Set_Required_VSE( VER_STAB_ENTRY *vse, BOOL real_use, WN *ref_wn ) const
00435 {
00436
00437
00438
00439 if (real_use)
00440 vse->Set_Real_use();
00441
00442
00443
00444 if ( vse->Any_use() ) return;
00445
00446 BOOL vse_live=TRUE;
00447
00448 switch ( vse->Type() ) {
00449 case WHIRL_STMT:
00450 vse->Set_Any_use();
00451 Set_Required_WN( vse->Wn() );
00452 break;
00453 case PHI_STMT:
00454 vse->Set_Any_use();
00455 if (ref_wn != NULL)
00456 vse->Set_ref_wn(ref_wn);
00457 Set_Required_PHI( vse, ref_wn );
00458 break;
00459 case CHI_STMT:
00460 Set_Required_CHI( vse->Chi(), &vse_live );
00461 break;
00462 case ENTRY_STMT:
00463
00464 break;
00465
00466 case MU_STMT:
00467 case NO_STMT:
00468 default:
00469 ErrMsg( EC_Misc_Int, "Set_Required_VSE invalid type",
00470 vse->Type() );
00471 break;
00472 }
00473
00474 if ( Tracing() ) {
00475 if(vse_live)
00476 fprintf( TFile, "<dse> Required VSE: var:%d version:%d\n",
00477 vse->Aux_id(), vse->Version() );
00478 else
00479 fprintf( TFile, "<dse> Not Required VSE: var:%d version:%d\n",
00480 vse->Aux_id(), vse->Version() );
00481 }
00482 }
00483
00484
00485
00486
00487
00488
00489 void
00490 DSE::Set_Required_PHI( VER_STAB_ENTRY *vse, WN *ref_wn ) const
00491 {
00492 PHI_NODE *phi = vse->Phi();
00493 if ( phi->Live() ) {
00494
00495 if ( vse->Ref_wn() != NULL || ref_wn == NULL ) {
00496
00497 return;
00498 }
00499 }
00500
00501 phi->Set_live();
00502 for ( INT32 opndnum = 0; opndnum < phi->Size(); opndnum++ ) {
00503 VER_ID phi_opnd = phi->Opnd(opndnum);
00504 VER_STAB_ENTRY *sym = Opt_stab()->Ver_stab_entry(phi_opnd);
00505 Set_last_store( sym->Aux_id(), NULL);
00506 Set_Required_VSE( sym, FALSE, ref_wn );
00507 }
00508 }
00509
00510
00511
00512
00513
00514
00515 void
00516 DSE::Set_Required_MU( MU_NODE *mu, BOOL real_use ) const
00517 {
00518 VER_STAB_ENTRY *ver = Opt_stab()->Ver_stab_entry(mu->Opnd());
00519 Set_last_store(ver->Aux_id(), NULL);
00520 Set_Required_VSE( ver, real_use, NULL );
00521 }
00522
00523
00524 #if 0 // OSP_468, remove Set_Required_Imp_VSE()
00525 void
00526 DSE::Set_Required_Imp_VSE( VER_ID vid, BOOL real_use) const
00527 {
00528 VER_STAB_ENTRY *vse = Opt_stab()->Ver_stab_entry(vid);
00529 AUX_ID vaid = vse->Aux_id();
00530
00531 STMT_TYPE vtype = vse->Type();
00532 switch ( vtype ) {
00533 case WHIRL_STMT:
00534 case CHI_STMT:
00535 {
00536 WN *wn;
00537 if (vtype == WHIRL_STMT)
00538 wn = vse->Wn();
00539 else
00540 wn = vse->Chi_wn();
00541
00542 CHI_LIST *chi_list = Opt_stab()->Get_generic_chi_list(wn);
00543 FmtAssert(OPERATOR_is_scalar_store ( WN_operator(wn) ) || chi_list,
00544 ("DSE::Set_Required_Implicit_Use: chi list is null."));
00545 if(chi_list == NULL)
00546 break;
00547 CHI_LIST_ITER chi_iter;
00548 CHI_NODE *cnode;
00549 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
00550 AUX_ID caid = cnode->Aux_id();
00551 if(caid != vaid && Aliased_aux(caid, vaid)) {
00552 FmtAssert( vid != cnode->Result(), ("DSE::Set_Required_Imp_VSE: confused version"));
00553 VER_STAB_ENTRY *cvse = Opt_stab()->Ver_stab_entry(cnode->Result());
00554 Set_last_store(caid, NULL);
00555 Set_Required_VSE(cvse, real_use, NULL);
00556 }
00557 }
00558 }
00559 break;
00560
00561 case PHI_STMT:
00562 {
00563 BB_NODE *bb = Opt_stab()->Ver_stab_entry(vid)->Bb();
00564 PHI_LIST_ITER phi_iter;
00565 PHI_NODE *phi;
00566 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
00567 AUX_ID paid = phi->Aux_id();
00568 if( paid != vaid && Aliased_aux(paid, vaid)) {
00569 FmtAssert( vid != phi->Result(), ("DSE::Set_Required_Imp_VSE: confused version"));
00570 VER_STAB_ENTRY *pvse = Opt_stab()->Ver_stab_entry(phi->Result());
00571 Set_last_store(paid, NULL);
00572 Set_Required_VSE(pvse, real_use, NULL);
00573 }
00574 }
00575 }
00576 break;
00577
00578 case ENTRY_STMT:
00579
00580 break;
00581
00582 case MU_STMT:
00583 case NO_STMT:
00584 default:
00585 ErrMsg( EC_Misc_Int, "DSE::Set_Required_Implicit_Use invalid type", vse->Type() );
00586 break;
00587 }
00588 return;
00589
00590 }
00591 #endif
00592
00593 static bool Is_identity_asgn(WN *wn, OPT_STAB *opt_stab)
00594 {
00595 OPERATOR opr = WN_operator(wn);
00596 if (! OPERATOR_is_scalar_store(opr)) return FALSE;
00597 WN *rhs = WN_kid(wn,0);
00598 if ((opr == OPR_STID && WN_operator(rhs) != OPR_LDID) ||
00599 (opr == OPR_STBITS && WN_operator(rhs) != OPR_LDBITS))
00600 return FALSE;
00601
00602 return (opt_stab->Ver_stab_entry(WN_ver(wn))->Aux_id() ==
00603 opt_stab->Ver_stab_entry(WN_ver(rhs))->Aux_id());
00604 }
00605
00606 BOOL
00607 DSE::Mem_WN_equiv_rec(WN *wn1, WN *wn2) const
00608 {
00609 if (!wn1 || !wn2) return FALSE;
00610 if (!Mem_WN_equiv(wn1,wn2)) {
00611 return FALSE;
00612 }
00613 for (INT i=0; i<WN_kid_count(wn1); i++) {
00614 if (!Mem_WN_equiv_rec(WN_kid(wn1,i),WN_kid(wn2,i))) {
00615 return FALSE;
00616 }
00617 }
00618 return TRUE;
00619 }
00620
00621 BOOL
00622 DSE::Mem_WN_equiv(WN *wn1, WN *wn2) const
00623 {
00624 if (!WN_Equiv(wn1, wn2))
00625 return FALSE;
00626
00627 OPERATOR opr = WN_operator(wn1);
00628 if(OPERATOR_has_field_id(opr)) {
00629 if(WN_field_id(wn1) != WN_field_id(wn2))
00630 return FALSE;
00631 }
00632
00633 if(opr == OPR_STBITS || opr == OPR_ISTBITS || opr == OPR_LDBITS || opr == OPR_ILDBITS) {
00634 if( WN_bit_offset(wn1) != WN_bit_offset(wn2))
00635 return FALSE;
00636 if( WN_bit_size(wn1) != WN_bit_size(wn2))
00637 return FALSE;
00638 }
00639
00640 if (WN_has_mu(wn1, Cfg()->Rgn_level())) {
00641 MU_NODE *mu1 = Opt_stab()->Get_occ(wn1)->Mem_mu_node();
00642 MU_NODE *mu2 = Opt_stab()->Get_occ(wn2)->Mem_mu_node();
00643 if(mu1 != NULL && mu2 != NULL && mu1->Opnd() != mu2->Opnd() )
00644 return FALSE;
00645 if((mu1==NULL) != (mu2 == NULL))
00646 return FALSE;
00647 }
00648
00649 return TRUE;
00650 }
00651
00652 BOOL
00653 DSE::Same_memloc( WN* store1, WN* store2) const
00654 {
00655 FmtAssert(OPERATOR_is_scalar_istore(WN_operator(store1)) ||
00656 OPERATOR_is_scalar_store (WN_operator(store1)) ||
00657 WN_operator(store1) == OPR_MSTORE,
00658 ("DSE::Same_memloc: store1 is not istore"));
00659 FmtAssert(OPERATOR_is_scalar_istore(WN_operator(store2)) ||
00660 OPERATOR_is_scalar_store (WN_operator(store2)) ||
00661 WN_operator(store2) == OPR_MSTORE,
00662 ("DSE::Same_memloc: store2 is not istore"));
00663
00664 OCC_TAB_ENTRY *occ1 = Opt_stab()->Get_occ(store1);
00665 OCC_TAB_ENTRY *occ2 = Opt_stab()->Get_occ(store2);
00666 FmtAssert(occ1 != NULL && occ2 != NULL, ("DSE::Same_memloc: occ == NULL"));
00667 POINTS_TO *pt1 = occ1->Points_to();
00668 POINTS_TO *pt2 = occ2->Points_to();
00669 FmtAssert(pt1 != NULL && pt2 != NULL, ("DSE::Same_memloc: points_to == NULL"));
00670
00671 if (Opt_stab()->Rule()->Same_location(store1, store2, pt1, pt2)) {
00672 #if defined(TARG_NVISA)
00673
00674 INT i;
00675 TY_IDX ty;
00676 ty = ST_type(pt1->Base());
00677 if (TY_kind(ty) == KIND_ARRAY) {
00678 for (i = 0; i < TY_AR_ndims(ty); i++) {
00679 if ( !TY_AR_const_lbnd(ty, i) ||
00680 !TY_AR_const_ubnd(ty, i) )
00681 return FALSE;
00682 }
00683 }
00684
00685 ty = ST_type(pt2->Base());
00686 if (TY_kind(ty) == KIND_ARRAY) {
00687 for (i = 0; i < TY_AR_ndims(ty); i++) {
00688 if ( !TY_AR_const_lbnd(ty, i) ||
00689 !TY_AR_const_ubnd(ty, i) )
00690 return FALSE;
00691 }
00692 }
00693 #endif
00694 return TRUE;
00695 }
00696 else if (Mem_WN_equiv(store1, store2)) {
00697 if (WN_kid_count(store1)>1 && Mem_WN_equiv_rec(WN_kid1(store1), WN_kid1(store2)))
00698 return TRUE;
00699 }
00700 return FALSE;
00701 }
00702
00703
00704
00705
00706
00707
00708 void
00709 DSE::Set_Required_CHI( CHI_NODE *chi, BOOL *chi_is_live ) const
00710 {
00711 AUX_ID vaux = chi->Aux_id();
00712 BOOL real_use = FALSE;
00713 WN *chiwn = Opt_stab()->Ver_stab_entry(chi->Result())->Chi_wn();
00714 if (OPERATOR_is_scalar_istore (WN_operator(chiwn))) {
00715 real_use = (Opt_stab()->Is_virtual(vaux) &&
00716 ! Opt_stab()->Special_vsym(vaux) &&
00717 Opt_stab()->Get_occ(chiwn)->Aux_id() == vaux);
00718
00719 if (real_use)
00720 Opt_stab()->Ver_stab_entry(chi->Result())->Set_Real_use();
00721 }
00722 else if (!WOPT_Enable_Call_Zero_Version && WN_operator(chiwn) == OPR_CALL) {
00723 real_use = ! Opt_stab()->Special_vsym(vaux);
00724 if (real_use)
00725 Opt_stab()->Ver_stab_entry(chi->Result())->Set_Real_use();
00726 } else if (Is_identity_asgn(chiwn, Opt_stab())) {
00727
00728
00729
00730 Opt_stab()->Ver_stab_entry(chi->Result())->Set_Real_use();
00731 }
00732
00733 *chi_is_live = TRUE;
00734 if (OPERATOR_is_scalar_istore(WN_operator(chiwn)) ||
00735 OPERATOR_is_scalar_store(WN_operator(chiwn)) ||
00736 WN_operator(chiwn) == OPR_MSTORE) {
00737 WN *last_st = Last_store(vaux);
00738 if( last_st != NULL && chiwn != last_st ) {
00739 if( Same_memloc(chiwn, last_st) ) {
00740 *chi_is_live = FALSE;
00741 if ( Tracing() ) {
00742 fprintf ( TFile, "DSE::Set_Required_CHI, current chiwn is not set live:\n" );
00743 fdump_tree_no_st(TFile, chiwn);
00744 }
00745 }
00746 }
00747 if(*chi_is_live)
00748 Set_last_store(vaux, chiwn);
00749 }
00750
00751 if(*chi_is_live) {
00752 VER_STAB_ENTRY *vsym = Opt_stab()->Ver_stab_entry(chi->Result());
00753 vsym->Set_Any_use();
00754 Set_Required_WN(chiwn);
00755 }
00756
00757 if (OPERATOR_is_scalar_istore(WN_operator(chiwn)) ||
00758 OPERATOR_is_scalar_store(WN_operator(chiwn)) ||
00759 WN_operator(chiwn) == OPR_MSTORE) {
00760 if(*chi_is_live)
00761 Set_last_store(vaux, chiwn);
00762 }
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 VER_STAB_ENTRY *opnd_ver = Opt_stab()->Ver_stab_entry(chi->Opnd());
00775 Set_Required_VSE( opnd_ver, real_use, NULL );
00776 }
00777
00778
00779
00780
00781
00782
00783 void
00784 DSE::Set_Required_WN( WN *wn ) const
00785 {
00786
00787 if ( Live_wn( wn ) ) {
00788 return;
00789 }
00790
00791
00792 Set_live_wn( wn );
00793
00794 const OPERATOR opr = WN_operator(wn);
00795
00796 if ( Tracing() ) {
00797 fprintf( TFile, "<dse> required WN_map_id:%d (%s)\n",
00798 WN_map_id(wn), OPERATOR_name(opr) );
00799 }
00800
00801
00802
00803
00804
00805 if (OPERATOR_is_scalar_istore (opr)) {
00806 AUX_ID vaux = Opt_stab()->Get_occ(wn)->Aux_id();
00807 if (! Opt_stab()->Is_virtual(vaux) || Opt_stab()->Special_vsym(vaux))
00808 ;
00809 else {
00810 CHI_LIST_ITER chi_iter;
00811 CHI_NODE *cnode;
00812 FOR_ALL_NODE( cnode, chi_iter, Init(Opt_stab()->Get_generic_chi_list(wn))) {
00813 if (cnode->Aux_id() != vaux) continue;
00814 VER_STAB_ENTRY *vsym = Opt_stab()->Ver_stab_entry(cnode->Result());
00815 Set_Required_VSE( vsym, TRUE, NULL );
00816 break;
00817 }
00818 }
00819 }
00820
00821 if ( WN_has_ver(wn) ) {
00822 VER_STAB_ENTRY *sym = Opt_stab()->Ver_stab_entry(WN_ver(wn));
00823 if(OPERATOR_is_scalar_load( WN_operator(wn) )) {
00824
00825
00826 Set_last_store(sym->Aux_id(), NULL);
00827 }
00828 Set_Required_VSE( sym, TRUE, wn );
00829 }
00830
00831
00832
00833 if (opr != OPR_BLOCK && ! OPERATOR_is_black_box(opr) && opr != OPR_REGION) {
00834
00835
00836 for ( INT32 kidnum = 0; kidnum < WN_kid_count(wn); kidnum++ ) {
00837 Set_Required_WN( WN_kid(wn,kidnum) );
00838 }
00839 }
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853 if ( WN_has_mu(wn, Cfg()->Rgn_level()) ) {
00854
00855 MU_LIST_ITER mu_iter;
00856 MU_NODE *mu;
00857 BOOL mu_reqd = (OPERATOR_is_scalar_iload (opr) ||
00858 opr == OPR_RETURN || opr == OPR_RETURN_VAL ||
00859 opr == OPR_MLOAD || opr == OPR_REGION ||
00860 !WOPT_Enable_Call_Zero_Version && opr == OPR_CALL);
00861 BOOL mu_of_parm = opr == OPR_PARM;
00862
00863
00864
00865 OCC_TAB_ENTRY *occ = Opt_stab()->Get_occ(wn);
00866 if (occ->Is_stmt()) {
00867 MU_LIST *mu_list = occ->Stmt_mu_list();
00868 FOR_ALL_NODE( mu, mu_iter, Init(mu_list)) {
00869 Set_Required_MU( mu, mu_reqd || mu_of_parm);
00870 }
00871 } else {
00872 Set_Required_MU( occ->Mem_mu_node(), mu_reqd || mu_of_parm);
00873
00874
00875 }
00876 }
00877 }
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887 BOOL
00888 DSE::Check_Required_Expr( WN *wn ) const
00889 {
00890 OPERATOR expr_oper = WN_operator(wn);
00891
00892 switch ( expr_oper ) {
00893 case OPR_LDID:
00894 case OPR_LDBITS:
00895 case OPR_ILOAD:
00896 case OPR_ILDBITS:
00897 case OPR_ILOADX:
00898 case OPR_MLOAD:
00899 if ( Required_load( wn ) ) {
00900 return TRUE;
00901 }
00902 break;
00903
00904 case OPR_BLOCK:
00905
00906 break;
00907
00908 default:
00909 for ( INT32 kidnum = 0; kidnum < WN_kid_count(wn); kidnum++ ) {
00910 if ( Check_Required_Expr( WN_kid(wn,kidnum) ) ) {
00911 return TRUE;
00912 }
00913 }
00914 break;
00915 }
00916
00917 return FALSE;
00918 }
00919
00920
00921
00922
00923
00924
00925 BOOL
00926 DSE::Is_deleted_statement( WN *stmt ) const
00927 {
00928 const OPCODE opc = WN_opcode(stmt);
00929 const OPERATOR opr = OPCODE_operator(opc);
00930
00931 if (OPERATOR_is_scalar_store (opr) &&
00932 ! Opt_stab()->Du_any_use(WN_ver(stmt))) {
00933 return TRUE;
00934 }
00935 else if ( (OPERATOR_is_scalar_istore (opr) || opr == OPR_MSTORE) &&
00936 WOPT_Enable_Dse_Aggressive && WN_has_chi(stmt, Cfg()->Rgn_level()) )
00937 {
00938
00939 if ( Required_istore( stmt ) )
00940 return FALSE;
00941 else {
00942
00943
00944 OCC_TAB_ENTRY *occ = Opt_stab()->Get_occ(stmt);
00945 if (occ->Points_to()->Unique_pt()) {
00946 Warn_todo("Handle unique pts.");
00947 return TRUE;
00948 }
00949
00950 CHI_LIST_ITER chi_iter;
00951 CHI_NODE *cnode;
00952 CHI_LIST *chi_list = Opt_stab()->Get_generic_chi_list(stmt);
00953 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list) ) {
00954 if (cnode->Live()) {
00955
00956 return FALSE;
00957 }
00958 }
00959
00960
00961 return TRUE;
00962 }
00963 }
00964
00965 return FALSE;
00966 }
00967
00968
00969 VER_ID
00970 DSE::Prop_vsym_new_result( VER_ID vid ) const
00971 {
00972 VER_STAB_ENTRY *vse = Opt_stab()->Ver_stab_entry(vid);
00973 if ( vse->Type() == PHI_STMT ) {
00974
00975 return vse->Phi()->Result();
00976 }
00977 else if ( vse->Type() == CHI_STMT ) {
00978
00979 if (vse->Chi()->Live()) {
00980 return vse->Chi()->Result();
00981 }
00982 else {
00983 return Prop_vsym_new_result(vse->Chi()->Opnd());
00984 }
00985 }
00986 else {
00987 return vid;
00988 }
00989 }
00990
00991 void
00992 DSE::Propagate_vsym_wn( WN *wn ) const
00993 {
00994 if ( WN_has_ver(wn) ) {
00995 WN_set_ver(wn, Prop_vsym_new_result(WN_ver(wn)));
00996 }
00997
00998 if ( WN_has_mu(wn, Cfg()->Rgn_level()) ) {
00999
01000 OCC_TAB_ENTRY *occ = Opt_stab()->Get_occ(wn);
01001 MU_NODE *mu = occ->Mem_mu_node();
01002 mu->Set_opnd( Prop_vsym_new_result(mu->Opnd()) );
01003 }
01004 return;
01005 }
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021 void
01022 DSE::Propagate_vsym_bb( BB_NODE *bb ) const
01023 {
01024
01025 PHI_LIST_ITER phi_iter;
01026 PHI_NODE *phi;
01027 FOR_ALL_ELEM ( phi, phi_iter, Init(bb->Phi_list()) ) {
01028 if (phi->Live() ) {
01029 for ( INT pkid = 0; pkid < phi->Size(); pkid++ ) {
01030 phi->Set_opnd(pkid, Prop_vsym_new_result(phi->Opnd(pkid)));
01031 }
01032 }
01033 }
01034
01035
01036 STMT_ITER stmt_iter;
01037 WN *stmt;
01038 FOR_ALL_ELEM(stmt, stmt_iter, Init(bb->Firststmt(),bb->Laststmt())) {
01039
01040 if ( !Is_deleted_statement(stmt) ) {
01041
01042 if ( WN_has_mu(stmt, Cfg()->Rgn_level()) ) {
01043 MU_LIST *mu_list = _opt_stab->Get_stmt_mu_list(stmt);
01044 if (mu_list) {
01045 MU_LIST_ITER mu_iter;
01046 MU_NODE *mu;
01047 FOR_ALL_NODE( mu, mu_iter, Init(mu_list)) {
01048 mu->Set_opnd( Prop_vsym_new_result(mu->Opnd()) );
01049 }
01050 }
01051 }
01052
01053 for ( INT32 kidnum = 0; kidnum < WN_kid_count(stmt); kidnum++ ) {
01054 Propagate_vsym_wn( WN_kid(stmt, kidnum) );
01055 }
01056
01057
01058
01059 if ( WN_has_chi(stmt, Cfg()->Rgn_level())) {
01060 CHI_LIST *chi_list = _opt_stab->Get_generic_chi_list(stmt);
01061 if (chi_list) {
01062 CHI_LIST_ITER chi_iter;
01063 CHI_NODE *chi;
01064 FOR_ALL_NODE( chi, chi_iter, Init(chi_list)) {
01065
01066 chi->Set_opnd( Prop_vsym_new_result( chi->Opnd() ));
01067 }
01068 }
01069 }
01070 }
01071 }
01072
01073
01074 BB_NODE *dom_bb;
01075 BB_LIST_ITER dom_bb_iter;
01076 FOR_ALL_ELEM(dom_bb, dom_bb_iter, Init(bb->Dom_bbs())) {
01077 Propagate_vsym_bb(dom_bb);
01078 }
01079 }
01080
01081
01082 #if defined(TARG_SL)
01083
01084
01085
01086
01087 void
01088 DSE::Repair_Injured_AuxIntrnOP (void) const{
01089 for (INT32 i = 0; i < _injury_aux_intrnop->size(); i++) {
01090 WN *wn = (*_injury_aux_intrnop)[i];
01091 if (WN_operator(wn) == OPR_STID) {
01092 WN *rhs = WN_kid0(wn);
01093 if (WN_Intrinsic_OP_Slave(rhs)) {
01094 WN *op1 = WN_kid0(WN_kid0(rhs));
01095 if (WN_has_ver(op1)) {
01096 VER_STAB_ENTRY *sym = Opt_stab()->Ver_stab_entry(WN_ver(op1));
01097 if (sym->Real_use()) {
01098
01099 Set_Required_WN(wn);
01100 }
01101 }
01102 }
01103 }
01104
01105 }
01106
01107 }
01108
01109 #endif
01110
01111
01112
01113
01114
01115 void
01116 DSE::Dead_store_elim( void ) const
01117 {
01118 if ( Tracing() ) {
01119 fprintf ( TFile, "DSE::Dead_store_elim (before dse)\n" );
01120 }
01121
01122 VER_STAB_ITER ver_stab_iter(Opt_stab()->Ver_stab());
01123 VER_ID ssa_id;
01124
01125
01126 FOR_ALL_NODE( ssa_id, ver_stab_iter, Init() ) {
01127 VER_STAB_ENTRY *vse = Opt_stab()->Ver_stab_entry(ssa_id);
01128 Assert( vse != NULL,
01129 (EC_Misc_Int, "Dead_store_elim null version entry", ssa_id) );
01130 vse->Reset_Real_use();
01131 vse->Reset_Any_use();
01132 if (vse->Type() == PHI_STMT) {
01133 vse->Phi()->Reset_live();
01134 }
01135 else if (vse->Type() == CHI_STMT) {
01136 vse->Chi()->Set_live(FALSE);
01137 }
01138
01139 if ( Tracing() ) {
01140 vse->Print(TFile, ssa_id);
01141 }
01142 }
01143
01144
01145
01146
01147 CFG_ITER cfg_iter(Cfg());
01148 BB_NODE *bb;
01149 FOR_ALL_NODE_REVERSE( bb, cfg_iter, Init() ) {
01150 STMT_ITER stmt_iter;
01151 WN *wn;
01152
01153 if ( Tracing() ) {
01154 fprintf( TFile, "<dse> block: %d\n", bb->Id() );
01155 }
01156
01157
01158
01159 if (WOPT_Enable_IVR) {
01160 if (bb->Kind() == BB_DOSTEP) {
01161 FOR_ALL_ELEM(wn, stmt_iter, Init(bb->Firststmt(),bb->Laststmt())) {
01162 Set_Required_WN( wn );
01163 }
01164 } else if (bb->Kind() == BB_WHILEEND || bb->Kind() == BB_DOEND || bb->Kind() == BB_REPEATEND) {
01165 if (bb->Laststmt() != NULL && WN_prev(bb->Laststmt()) != NULL)
01166 Set_Required_WN( WN_prev(bb->Laststmt()) );
01167 }
01168 }
01169
01170
01171
01172
01173
01174 FOR_ALL_ELEM_REVERSE(wn, stmt_iter, Init(bb->Firststmt(),bb->Laststmt())) {
01175 if ( Live_wn( wn ) ) {
01176
01177 continue;
01178 }
01179 else if ( Required_stmt( wn ) ) {
01180 Set_Required_WN( wn );
01181 }
01182 else if ( Check_Required_Expr(wn) ) {
01183 Set_Required_WN( wn );
01184 }
01185 }
01186 }
01187
01188 #if defined(TARG_SL)
01189 Repair_Injured_AuxIntrnOP();
01190 #endif
01191
01192
01193
01194
01195 FOR_ALL_NODE( ssa_id, ver_stab_iter, Init() ) {
01196 VER_STAB_ENTRY *vse = Opt_stab()->Ver_stab_entry(ssa_id);
01197
01198 if (vse->Type() == PHI_STMT) {
01199 if (vse->Any_use()) {
01200 vse->Phi()->Set_live();
01201 vse->Phi()->Reset_dse_dead();
01202 }
01203 else {
01204 vse->Phi()->Reset_live();
01205 vse->Phi()->Set_dse_dead();
01206 }
01207 }
01208 else if (vse->Type() == CHI_STMT) {
01209 vse->Chi()->Set_live(vse->Any_use());
01210 vse->Chi()->Set_dse_dead(! vse->Any_use());
01211 }
01212 }
01213
01214 if (Opt_stab()->Has_exc_handler()
01215 #ifdef KEY
01216 || Opt_stab()->Has_nonlocal_goto_target()
01217 #endif
01218 ) {
01219 Add_MU_list_for_calls();
01220
01221
01222
01223 FOR_ALL_NODE( ssa_id, ver_stab_iter, Init() ) {
01224 VER_STAB_ENTRY *vse = Opt_stab()->Ver_stab_entry(ssa_id);
01225
01226 if (vse->Type() == PHI_STMT) {
01227 if (vse->Any_use()) {
01228 vse->Phi()->Set_live();
01229 vse->Phi()->Reset_dse_dead();
01230 }
01231 else {
01232 vse->Phi()->Reset_live();
01233 vse->Phi()->Set_dse_dead();
01234 }
01235 }
01236 else if (vse->Type() == CHI_STMT) {
01237 vse->Chi()->Set_live(vse->Any_use());
01238 vse->Chi()->Set_dse_dead(! vse->Any_use());
01239 }
01240 }
01241 }
01242
01243 FOR_ALL_NODE( ssa_id, ver_stab_iter, Init() ) {
01244 VER_STAB_ENTRY *vse = Opt_stab()->Ver_stab_entry(ssa_id);
01245
01246 if (vse->Type() == ENTRY_STMT) {
01247 vse->Set_Real_use();
01248 vse->Set_Any_use();
01249 }
01250 }
01251
01252
01253
01254
01255
01256
01257
01258 PHI_NODE *phi;
01259 PHI_LIST_ITER phi_iter;
01260 FOR_ALL_NODE(bb, cfg_iter, Init()) {
01261 if (bb->Loop() && bb->Loop()->Well_formed() && bb->Loop()->Header() == bb) {
01262 INT32 pos = bb->Loop()->Header()->Pred()->Pos(bb);
01263 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Loop()->Header()->Phi_list())) {
01264 if (phi->Live()) {
01265 VER_STAB_ENTRY *vse = Opt_stab()->Ver_stab_entry(phi->Opnd(pos));
01266 vse->Set_Real_use();
01267 vse->Set_Any_use();
01268 }
01269 }
01270 }
01271 }
01272
01273 Propagate_vsym_bb( Cfg()->Entry_bb() );
01274
01275 if ( Tracing() ) {
01276 fprintf ( TFile, "SSA::Dead_store_elim (after dse)\n" );
01277 FOR_ALL_NODE( ssa_id, ver_stab_iter, Init() ) {
01278 VER_STAB_ENTRY *vse = Opt_stab()->Ver_stab_entry(ssa_id);
01279 fprintf(TFile, " [%3d]", ssa_id);
01280 vse->Print(TFile, ssa_id);
01281 }
01282 FOR_ALL_NODE( bb, cfg_iter, Init() ) {
01283 bb->Print_head(TFile);
01284 STMT_ITER stmt_iter;
01285 WN *wn;
01286 bb->Phi_list()->PRINT(TFile);
01287 FOR_ALL_ELEM(wn, stmt_iter, Init(bb->Firststmt(),bb->Laststmt())){
01288 if ( Is_deleted_statement( wn ) ) {
01289 fprintf(TFile, "*** the following stmt is deleted. ***\n");
01290 }
01291
01292 if ( WN_has_mu(wn, Cfg()->Rgn_level()) ) {
01293 MU_LIST *mu_list = _opt_stab->Get_stmt_mu_list(wn);
01294 if (mu_list) {
01295 MU_LIST_ITER mu_iter;
01296 fprintf(TFile, " mu<");
01297 MU_NODE *mnode;
01298 FOR_ALL_NODE( mnode, mu_iter, Init(mu_list)) {
01299 fprintf(TFile, "%d/%d ", mnode->Aux_id(), mnode->Opnd());
01300 }
01301 fprintf(TFile, ">\n");
01302 }
01303 }
01304
01305 fdump_tree_no_st(TFile, wn);
01306
01307 if ( WN_has_chi(wn, Cfg()->Rgn_level()) ) {
01308 CHI_LIST *chi_list = _opt_stab->Get_generic_chi_list(wn);
01309 if (chi_list) {
01310 CHI_LIST_ITER chi_iter;
01311 fprintf(TFile, " chi<");
01312 CHI_NODE *cnode;
01313 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
01314 fprintf(TFile, "%d/%d/%d ",
01315 cnode->Aux_id(), cnode->Result(), cnode->Opnd());
01316 }
01317 fprintf(TFile, ">\n");
01318 }
01319 }
01320 }
01321 }
01322 }
01323 }
01324
01325
01326
01327
01328
01329
01330 MU_NODE*
01331 MU_LIST::New_mu_node_w_cur_vse(AUX_ID var,
01332 VER_ID vse,
01333 MEM_POOL *pool)
01334 {
01335
01336 if (Contains(var)) return NULL;
01337
01338
01339 MU_NODE *mnode = New_mu_node(var, pool);
01340 mnode->Set_opnd(vse);
01341 return mnode;
01342 }
01343
01344
01345
01346
01347
01348
01349 void
01350 DSE::Add_EH_exposed_use(WN *call) const
01351 {
01352 if (_exc == NULL || _exc->Get_es_link(call) == NULL)
01353 return;
01354
01355
01356
01357 Is_True(_exc != NULL, ("DSE::Add_EH_exposed_use, NULL exception scope (1)"));
01358 EXC_SCOPE *es = _exc->Get_es_link(call);
01359 Is_True(es != NULL, ("DSE::Add_EH_exposed_use, NULL exception scope (2)"));
01360
01361 MU_LIST *mu_list = _opt_stab->Get_stmt_mu_list(call);
01362 MU_NODE *mu;
01363 AUX_ID var;
01364 VER_ID vse;
01365 EXC_SCOPE *exc_scope, *exc_scope2;
01366
01367 for (exc_scope = es; exc_scope != NULL; exc_scope = exc_scope->Parent()) {
01368 EXC_SCOPE_TRY_ITER try_iter(exc_scope);
01369 FOR_ALL_ELEM(var, try_iter, Init()) {
01370 if (var != 0) {
01371 vse = _opt_stab->Stack(var)->Top();
01372 mu = mu_list->New_mu_node_w_cur_vse(var, vse, _cfg->Mem_pool());
01373 if (mu) {
01374 Set_Required_MU( mu, FALSE );
01375 if ( Tracing() )
01376 fprintf( TFile, "<dse> Required EH_MU: var:%d\n", var );
01377 }
01378 }
01379 }
01380 }
01381 }
01382
01383
01384 #ifdef KEY
01385 void
01386 DSE::Add_entry_exposed_uses(WN *call) const
01387 {
01388
01389
01390
01391 MU_LIST *mu_list = _opt_stab->Get_stmt_mu_list(call);
01392 MU_NODE *mu;
01393 AUX_ID var;
01394 VER_ID vse;
01395 WN *optchi;
01396 CHI_LIST *chi;
01397 CHI_LIST_ITER chi_iter;
01398 CHI_NODE *cnode;
01399 BB_LIST_ITER entry_iter(_cfg->Fake_entry_bb()->Succ());
01400 FOR_ALL_ITEM(entry_iter, Init()) {
01401 BB_NODE *bb = entry_iter.Cur_bb();
01402 optchi = bb->Firststmt();
01403 if (optchi == NULL)
01404 continue;
01405 Is_True(WN_operator(optchi) == OPR_OPT_CHI,
01406 ("DSE::Add_entry_exposed_uses: cannot find chi-list"));
01407 chi = _opt_stab->Get_stmt_chi_list(optchi);
01408 Is_True(chi != NULL,
01409 ("DSE::Add_entry_exposed_uses: NULL chi"));
01410 FOR_ALL_NODE(cnode, chi_iter, Init(chi)) {
01411 var = cnode->Aux_id();
01412 vse = _opt_stab->Stack(var)->Top();
01413 mu = mu_list->New_mu_node_w_cur_vse(var, vse, _cfg->Mem_pool());
01414 if (mu)
01415 Set_Required_MU( mu, FALSE );
01416 }
01417 }
01418 }
01419 #endif
01420
01421
01422
01423
01424
01425
01426 void DSE::Update_MU_list_for_call(BB_NODE *bb) const
01427 {
01428 PHI_LIST_ITER phi_iter;
01429 PHI_NODE *phi;
01430 BB_LIST_ITER bb_iter;
01431 STMT_ITER stmt_iter;
01432 BB_NODE *dom_bb;
01433 BB_LIST_ITER dom_bb_iter;
01434 WN *wn;
01435 AUX_ID var;
01436
01437
01438 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
01439 var = phi->Aux_id();
01440 _opt_stab->Stack(var)->Push(phi->Result());
01441 }
01442
01443
01444 FOR_ALL_ELEM (wn, stmt_iter, Init(bb->Firststmt(), bb->Laststmt())) {
01445
01446 OPCODE opc = WN_opcode(wn);
01447 OPERATOR opr = OPCODE_operator(opc);
01448
01449
01450 if ( opr == OPR_CALL || opr == OPR_ICALL ) {
01451 #ifdef KEY
01452 if (_opt_stab->Has_exc_handler())
01453 #endif
01454 Add_EH_exposed_use(wn);
01455 #ifdef KEY
01456 else if (_opt_stab->Has_nonlocal_goto_target())
01457 Add_entry_exposed_uses(wn);
01458 #endif
01459 }
01460
01461
01462 if (OPERATOR_is_scalar_store (opr)) {
01463 var = _opt_stab->Du_aux_id(WN_ver(wn));
01464 _opt_stab->Stack(var)->Push(WN_ver(wn));
01465 }
01466
01467
01468 if ( WN_has_chi(wn, Cfg()->Rgn_level()) ) {
01469 CHI_LIST *chi_list = _opt_stab->Get_generic_chi_list(wn);
01470 if (chi_list) {
01471 CHI_LIST_ITER chi_iter;
01472 CHI_NODE *cnode;
01473 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
01474 var = cnode->Aux_id();
01475 _opt_stab->Stack(var)->Push(cnode->Result());
01476 }
01477 }
01478 }
01479 }
01480
01481 FOR_ALL_ELEM (dom_bb, dom_bb_iter, Init(bb->Dom_bbs())) {
01482 Update_MU_list_for_call(dom_bb);
01483 }
01484
01485
01486
01487
01488 FOR_ALL_ELEM_REVERSE (wn, stmt_iter, Init(bb->Firststmt(), bb->Laststmt())) {
01489
01490 OPERATOR opr = WN_operator(wn);
01491
01492
01493 if ( WN_has_chi(wn, Cfg()->Rgn_level()) ) {
01494 CHI_LIST *chi_list = _opt_stab->Get_generic_chi_list(wn);
01495 if (chi_list) {
01496 CHI_LIST_ITER chi_iter;
01497 CHI_NODE *cnode;
01498 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
01499 var = cnode->Aux_id();
01500 _opt_stab->Stack(var)->Pop();
01501 }
01502 }
01503 }
01504
01505
01506 if (OPERATOR_is_scalar_store (opr)) {
01507 var = _opt_stab->Du_aux_id(WN_ver(wn));
01508 _opt_stab->Stack(var)->Pop();
01509 }
01510 }
01511
01512 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
01513 var = phi->Aux_id();
01514 _opt_stab->Stack(var)->Pop();
01515 }
01516 }
01517
01518
01519
01520
01521
01522 void
01523 DSE::Add_MU_list_for_calls( void ) const
01524 {
01525 AUX_ID var;
01526 MEM_POOL stack_pool;
01527 OPT_POOL_Initialize(&stack_pool, "DSE stack pool", FALSE, DSE_DUMP_FLAG);
01528 OPT_POOL_Push(&stack_pool, DSE_DUMP_FLAG);
01529
01530 AUX_STAB_ITER opt_stab_iter(_opt_stab);
01531
01532
01533 FOR_ALL_NODE(var, opt_stab_iter, Init()) {
01534 AUX_STAB_ENTRY *psym = _opt_stab->Aux_stab_entry(var);
01535 if (psym->Is_real_var() || psym->Is_virtual()) {
01536 psym->Set_stack(CXX_NEW(STACK<AUX_ID>(&stack_pool), &stack_pool));
01537 }
01538 }
01539
01540 Update_MU_list_for_call(_cfg->Entry_bb());
01541
01542 OPT_POOL_Pop(&stack_pool, DSE_DUMP_FLAG);
01543 OPT_POOL_Delete(&stack_pool, DSE_DUMP_FLAG);
01544 }
01545
01546
01547
01548
01549
01550
01551
01552
01553 void
01554 SSA::Dead_store_elim( CFG *cfg, OPT_STAB *opt_stab, EXC *exc )
01555 {
01556
01557 OPT_POOL_Push( cfg->Loc_pool(), DSE_DUMP_FLAG );
01558
01559 {
01560 DSE dse( cfg, opt_stab, cfg->Loc_pool(), exc,
01561 Get_Trace( TP_GLOBOPT, DSE_DUMP_FLAG ) );
01562
01563
01564 dse.Dead_store_elim();
01565
01566 }
01567
01568
01569 OPT_POOL_Pop( cfg->Loc_pool(), DSE_DUMP_FLAG );
01570 }