00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #ifdef USE_PCH
00054 #include "opt_pch.h"
00055 #endif // USE_PCH
00056 #pragma hdrstop
00057
00058
00059 #ifdef _KEEP_RCS_ID
00060 #define opt_rvitab_CXX "opt_rvitab.cxx"
00061 static char *rcs_id = opt_rvitab_CXX"$Revision$";
00062 #endif
00063
00064 #include "defs.h"
00065 #include "errors.h"
00066 #include "erglob.h"
00067 #include "tracing.h"
00068 #include "stab.h"
00069 #include "wn.h"
00070 #include "wn_util.h"
00071 #include "cxx_memory.h"
00072 #include "data_layout.h"
00073
00074 #include "opt_defs.h"
00075 #include "opt_config.h"
00076 #include "opt_base.h"
00077 #include "opt_rvilr.h"
00078 #include "opt_rvitab.h"
00079 #include "opt_util.h"
00080 #include "opt_wn.h"
00081 #include "opt_alias_interface.h"
00082
00083
00084
00085
00086
00087
00088
00089 RVI_CTAB::RVI_CTAB( MEM_POOL *mem_pool ) :
00090 _mem_pool(mem_pool),
00091 _ctab(RVI_CTAB_SIZE, mem_pool)
00092 {
00093
00094 _ctab.Bzero_array();
00095 }
00096
00097 RVI_CTAB::~RVI_CTAB( void )
00098 {
00099 }
00100
00101
00102
00103
00104
00105 RVI_NODE *
00106 RVI_CTAB::Find( const WN *wn, IDX_32 hash_val ) const
00107 {
00108 RVI_NODE_ITER node_iter;
00109 RVI_NODE *cnode;
00110
00111 FOR_ALL_NODE( cnode, node_iter, Init(_ctab[hash_val]) ) {
00112 if ( cnode->Match_constant( wn ) ) {
00113 return cnode;
00114 }
00115 }
00116
00117 return NULL;
00118 }
00119
00120
00121
00122
00123
00124 RVI_NODE *
00125 RVI_CTAB::Add_unique( WN *wn, IDX_32 bitpos, IDX_32 hash_val ) const
00126 {
00127 RVI_NODE *cnode = CXX_NEW(RVI_NODE(bitpos,wn,NULL), _mem_pool);
00128
00129 if ( _ctab[hash_val] == NULL ) {
00130 _ctab[hash_val] = CXX_NEW(RVI_NODE_LIST(), _mem_pool);
00131 }
00132
00133 _ctab[hash_val]->Prepend( cnode );
00134
00135 return cnode;
00136 }
00137
00138
00139
00140
00141
00142 IDX_32
00143 RVI_CTAB::Hash( const WN *wn ) const
00144 {
00145 const OPCODE opc = WN_opcode(wn);
00146 const OPERATOR opr = OPCODE_operator(opc);
00147
00148 if ( opr == OPR_INTCONST ) {
00149
00150 return ( ((UINT32)opc+(UINT64)WN_const_val(wn)) % RVI_CTAB_SIZE );
00151 }
00152 else if (opr == OPR_CONST || opr == OPR_LDA) {
00153 UINT32 val;
00154
00155 switch (ST_class(WN_st(wn))) {
00156 case CLASS_CONST:
00157
00158
00159 Warn_todo("RVI_CTAB::Hash: use better initial value for CLASS_CONST");
00160 val = WN_st_idx(wn);
00161 break;
00162 default:
00163 Warn_todo("RVI_CTAB::Hash: use better initial value for non-CONST classes");
00164 val = WN_st_idx(wn);
00165 break;
00166 }
00167
00168
00169 if ( opr == OPR_CONST ) {
00170 return (((UINT32)opc+val) % RVI_CTAB_SIZE);
00171 }
00172 else {
00173
00174
00175 #ifdef TARG_SL
00176 return (((UINT32)opc+val+(UINT32)WN_lda_offset(wn) + (UINT32)WN_is_internal_mem_ofst(wn)) % RVI_CTAB_SIZE);
00177 #else
00178 return (((UINT32)opc+val+(UINT32)WN_lda_offset(wn)) % RVI_CTAB_SIZE);
00179 #endif
00180 }
00181 }
00182 else {
00183 Warn_todo( "RVI_CTAB::Hash: unknown operator" );
00184 return (((UINT32)opc) % RVI_CTAB_SIZE);
00185 }
00186 }
00187
00188
00189
00190
00191
00192 MTYPE
00193 RVI_NODE::Mtype( void ) const
00194 {
00195 MTYPE mtype;
00196 if ( Storewn() != NULL ) {
00197 const OPCODE opc = WN_opcode(Storewn());
00198 mtype = OPCODE_desc(opc);
00199 }
00200 else if ( Loadwn() != NULL ) {
00201 const OPCODE opc = WN_opcode(Loadwn());
00202 const OPERATOR opr = OPCODE_operator(opc);
00203
00204 if ( opr == OPR_LDID )
00205 mtype = OPCODE_desc(opc);
00206 else
00207 mtype = OPCODE_rtype(opc);
00208 }
00209 else {
00210 FmtAssert( FALSE, ("RVI_NODE::Mtype: No way to determine type") );
00211 return MTYPE_V;
00212 }
00213
00214
00215 if ( MTYPE_size_best(mtype) >= 32 )
00216 return mtype;
00217 else
00218 return Mtype_from_class_size( mtype, MTYPE_I4 );
00219 }
00220
00221
00222
00223
00224
00225 BOOL
00226 RVI_NODE::Match_constant( const WN *wn ) const
00227 {
00228 const OPCODE opc = WN_opcode(wn);
00229
00230 if ( WN_opcode(Loadwn()) != opc )
00231 return FALSE;
00232
00233
00234 switch ( OPCODE_operator(opc) ) {
00235 case OPR_CONST:
00236 return WN_st(Loadwn()) == WN_st(wn);
00237
00238 case OPR_INTCONST:
00239 return WN_const_val(Loadwn()) == WN_const_val(wn);
00240
00241 case OPR_LDA:
00242 return (WN_st(Loadwn()) == WN_st(wn)) &&
00243 (WN_lda_offset(Loadwn()) == WN_lda_offset(wn));
00244 }
00245
00246 return FALSE;
00247 }
00248
00249
00250
00251
00252
00253 void
00254 RVI_CTAB::Print( FILE *fp ) const
00255 {
00256 fprintf( fp, "%sRVI_CTAB::Print\n%s", SBar, SBar );
00257 RVI_CTAB_ITER ctab_iter;
00258 RVI_NODE *cnode;
00259 FOR_ALL_NODE( cnode, ctab_iter, Init( this ) ) {
00260 cnode->Print( fp );
00261 }
00262 }
00263
00264
00265
00266
00267
00268 RVI_NODE *
00269 RVI_CTAB_ITER::First( void )
00270 {
00271 _did_first = TRUE;
00272 _cnode = NULL;
00273 for ( _ctab_index = 0; _ctab_index < RVI_CTAB_SIZE; _ctab_index++ ) {
00274 RVI_NODE_LIST *clist = _ctab->_ctab[_ctab_index];
00275 if ( clist != NULL ) {
00276 FOR_ALL_NODE( _cnode, _cnode_iter, Init(clist) ) {
00277 return _cnode;
00278 }
00279 }
00280 }
00281
00282 return NULL;
00283 }
00284
00285 RVI_NODE *
00286 RVI_CTAB_ITER::Next( void )
00287 {
00288 if ( ! _did_first ) {
00289 return First();
00290 }
00291
00292 _cnode = _cnode_iter.Next();
00293 if ( _cnode != NULL ) {
00294 return _cnode;
00295 }
00296
00297
00298 for ( _ctab_index += 1; _ctab_index < RVI_CTAB_SIZE; _ctab_index++ ) {
00299 RVI_NODE_LIST *clist = _ctab->_ctab[_ctab_index];
00300 if ( clist != NULL ) {
00301 FOR_ALL_NODE( _cnode, _cnode_iter, Init(clist) ) {
00302 return _cnode;
00303 }
00304 }
00305 }
00306
00307 return NULL;
00308 }
00309
00310 BOOL
00311 RVI_CTAB_ITER::Is_Empty( void )
00312 {
00313 if ( ! _did_first ) {
00314 (void)First();
00315 }
00316
00317 return _cnode == NULL;
00318 }
00319
00320
00321
00322
00323
00324
00325
00326 RVI_VTAB::RVI_VTAB( INT num_vars, MEM_POOL *mem_pool ) :
00327 _size(num_vars+1),
00328 _mem_pool(mem_pool),
00329 _vtab(num_vars+1, mem_pool)
00330 {
00331
00332 _vtab.Bzero_array();
00333 }
00334
00335 RVI_VTAB::~RVI_VTAB( void )
00336 {
00337 }
00338
00339
00340
00341
00342
00343 RVI_NODE *
00344 RVI_VTAB_ITER::First( void )
00345 {
00346 _did_first = TRUE;
00347 _vnode = NULL;
00348 for ( _vtab_index = 0; _vtab_index < _vtab->Size(); _vtab_index++ ) {
00349 _vnode = _vtab->Find(_vtab_index);
00350 if ( _vnode != NULL ) {
00351 return _vnode;
00352 }
00353 }
00354
00355 return NULL;
00356 }
00357
00358 RVI_NODE *
00359 RVI_VTAB_ITER::Next( void )
00360 {
00361 if ( ! _did_first ) {
00362 return First();
00363 }
00364
00365
00366 _vnode = NULL;
00367 for ( _vtab_index += 1; _vtab_index < _vtab->Size(); _vtab_index++ ) {
00368 _vnode = _vtab->Find(_vtab_index);
00369 if ( _vnode != NULL ) {
00370 return _vnode;
00371 }
00372 }
00373
00374 return NULL;
00375 }
00376
00377 BOOL
00378 RVI_VTAB_ITER::Is_Empty( void )
00379 {
00380 if ( ! _did_first ) {
00381 (void)First();
00382 }
00383
00384 return _vnode == NULL;
00385 }
00386
00387
00388
00389
00390
00391 RVI_NODE *
00392 RVI_VTAB::Add_load( WN *loadwn, IDX_32 bitpos ) const
00393 {
00394 RVI_NODE *vnode = _vtab[bitpos];
00395
00396 if ( vnode == NULL ) {
00397 vnode = CXX_NEW(RVI_NODE(bitpos,loadwn,NULL),_mem_pool);
00398 _vtab[bitpos] = vnode;
00399 }
00400 else if ( vnode->Loadwn() == NULL ) {
00401 vnode->Set_loadwn(loadwn);
00402 }
00403 else {
00404
00405
00406
00407 const MTYPE cur_rtype = WN_rtype(vnode->Loadwn());
00408 const MTYPE new_rtype = WN_rtype(loadwn);
00409
00410 if ( MTYPE_size_min(new_rtype) > MTYPE_size_min(cur_rtype) ) {
00411 vnode->Set_loadwn(loadwn);
00412 }
00413 }
00414
00415 return vnode;
00416 }
00417
00418
00419
00420
00421
00422 RVI_NODE *
00423 RVI_VTAB::Add_store( WN *storewn, IDX_32 bitpos ) const
00424 {
00425 RVI_NODE *vnode = _vtab[bitpos];
00426
00427 if ( vnode == NULL ) {
00428 vnode = CXX_NEW(RVI_NODE(bitpos,NULL,storewn),_mem_pool);
00429 _vtab[bitpos] = vnode;
00430 }
00431 else if ( vnode->Storewn() == NULL ) {
00432 vnode->Set_storewn(storewn);
00433 }
00434
00435 return vnode;
00436 }
00437
00438
00439
00440
00441
00442
00443 RVI_NODE *
00444 RVI_VTAB::Find_match( const WN *wn ) const
00445 {
00446 const OPCODE wnopc = WN_opcode(wn);
00447 const OPERATOR wnopr = OPCODE_operator(wnopc);
00448 Is_True( wnopr == OPR_STID || wnopr == OPR_LDID,
00449 ("RVI_VTAB::Find_match: neither stid nor ldid") );
00450 const ST *wnst = WN_st(wn);
00451 const WN_OFFSET wnoff = (wnopr == OPR_STID ? WN_store_offset(wn) :
00452 WN_load_offset(wn));
00453 const MTYPE wnmtype = TY_mtype(ST_type(wnst));
00454
00455 RVI_VTAB_ITER vtab_iter;
00456 RVI_NODE *vnode;
00457 FOR_ALL_NODE( vnode, vtab_iter, Init(this) ) {
00458 ST *vst;
00459 WN_OFFSET voff;
00460 MTYPE vmtype;
00461
00462 if ( vnode->Loadwn() != NULL ) {
00463 vst = WN_st(vnode->Loadwn());
00464 voff = WN_load_offset(vnode->Loadwn());
00465 vmtype = TY_mtype(ST_type(vst));
00466 }
00467 else if ( vnode->Storewn() != NULL ) {
00468 vst = WN_st(vnode->Storewn());
00469 voff = WN_store_offset(vnode->Storewn());
00470 vmtype = TY_mtype(ST_type(vst));
00471 }
00472 else {
00473 FmtAssert( FALSE,
00474 ("RVI_VTAB::Find_match: bitpos %d", vnode->Bitpos()) );
00475 }
00476
00477 if ( wnst == vst && wnoff == voff && wnmtype == vmtype ) {
00478 return vnode;
00479 }
00480 }
00481
00482 return NULL;
00483 }
00484
00485
00486
00487
00488
00489
00490 ST *
00491 RVI_NODE::St( void ) const
00492 {
00493 if ( Loadwn() != NULL ) {
00494 const OPCODE opc = WN_opcode(Loadwn());
00495 const OPERATOR opr = OPCODE_operator(opc);
00496
00497 if ( opr == OPR_LDID )
00498 return WN_st(Loadwn());
00499 else {
00500
00501 return NULL;
00502 }
00503 }
00504 else if ( Storewn() != NULL ) {
00505 return WN_st(Storewn());
00506 }
00507 else {
00508 FmtAssert( FALSE, ("RVI_NODE::Name: No way to determine ST") );
00509 return NULL;
00510 }
00511 }
00512
00513
00514
00515
00516
00517 const char *
00518 RVI_NODE::Name( void ) const
00519 {
00520 ST *st = NULL;
00521
00522 if ( Loadwn() != NULL ) {
00523 const OPCODE opc = WN_opcode(Loadwn());
00524 const OPERATOR opr = OPCODE_operator(opc);
00525
00526 if ( opr == OPR_LDID )
00527 st = WN_st(Loadwn());
00528 else {
00529
00530 return NULL;
00531 }
00532 }
00533 else if ( Storewn() != NULL ) {
00534 st = WN_st(Storewn());
00535 }
00536 else {
00537 FmtAssert( FALSE, ("RVI_NODE::Name: No way to determine name") );
00538 return "RVI-unknown";
00539 }
00540
00541 return ST_name(st);
00542 }
00543
00544
00545
00546
00547
00548
00549 WN *
00550 RVI_NODE::New_home_wn(ALIAS_MANAGER *alias_mgr) const
00551 {
00552 WN *home_wn = NULL;
00553
00554 if ( Loadwn() != NULL )
00555 {
00556 WN *wn = Loadwn();
00557
00558
00559 if ( WN_has_sym(wn) && WN_sclass(wn) == SCLASS_FORMAL_REF )
00560 {
00561 if ( WN_operator_is(wn, OPR_LDA))
00562 {
00563 ST *base = Get_ST_formal_ref_base(WN_st(wn));
00564
00565 if (!ST_has_formal_preg_num(base))
00566 {
00567
00568
00569 TY_IDX ty = WN_ty(wn);
00570 home_wn = WN_CreateLdid(OPR_LDID, Pointer_type, Pointer_type,
00571 WN_lda_offset(wn), base,
00572 WN_ty(wn));
00573 }
00574 }
00575 }
00576 else if ( WN_operator_is(wn, OPR_LDID ))
00577 {
00578 home_wn = WN_CreateIdname( WN_load_offset(wn), WN_st(wn) );
00579 Copy_alias_info(alias_mgr, wn, home_wn);
00580 }
00581 else
00582 {
00583
00584 home_wn = WN_COPY_Tree( wn );
00585 }
00586 }
00587 else if ( Storewn() != NULL )
00588 {
00589 WN *wn = Storewn();
00590
00591 if (WN_sclass(wn) != SCLASS_FORMAL_REF)
00592 {
00593 home_wn = WN_CreateIdname(WN_store_offset(wn), WN_st(wn) );
00594 Copy_alias_info(alias_mgr, wn, home_wn);
00595 }
00596 }
00597 else
00598 {
00599 FmtAssert( FALSE,
00600 ("RVI_NODE::New_home_wn: No way to determine home") );
00601 }
00602
00603 return home_wn;
00604 }
00605
00606
00607
00608
00609
00610
00611
00612
00613 void
00614 RVI_NODE::Add_reference( BB_NODE *bb, BOOL is_load, MEM_POOL *pool )
00615 {
00616 if ( Appearances() == NULL ) {
00617 Set_appearances( CXX_NEW(RVI_LRBB_LIST(), pool) );
00618 }
00619
00620 RVI_LRBB *lrbb = Appearances()->Find( bb );
00621 if ( lrbb == NULL ) {
00622 lrbb = CXX_NEW(RVI_LRBB(bb),pool);
00623 Appearances()->Prepend( lrbb );
00624
00625
00626 if ( !is_load ) {
00627 lrbb->Set_first_is_store();
00628 }
00629 }
00630
00631 if ( is_load ) {
00632 lrbb->Set_load_cnt( lrbb->Load_cnt() + 1 );
00633 }
00634 else {
00635 lrbb->Set_store_cnt( lrbb->Store_cnt() + 1 );
00636 }
00637 }
00638
00639
00640
00641
00642
00643
00644
00645
00646 BOOL
00647 RVI_NODE::Is_volatile( void ) const
00648 {
00649 TY_IDX ty = (TY_IDX) 0;
00650 ST *st = NULL;
00651 if ( Loadwn() != NULL ) {
00652 ty = WN_ty(Loadwn());
00653 st = WN_st(Loadwn());
00654 }
00655 else if ( Storewn() != NULL ) {
00656 ty = WN_ty(Storewn());
00657 st = WN_st(Storewn());
00658 }
00659
00660 Is_True( ty != 0, ("RVI_NODE::Is_volatile: no ty [%d]", Bitpos()) );
00661
00662 if (TY_is_volatile(ty))
00663 return TRUE;
00664
00665
00666
00667
00668 Is_True(st != NULL,
00669 ("RVI_NODE::Is_volatile: no st [%d]", Bitpos()));
00670 TY_IDX st_ty = ST_type(st);
00671 if (TY_is_volatile(st_ty))
00672 return TRUE;
00673
00674 return FALSE;
00675 }
00676
00677
00678
00679
00680
00681 void
00682 RVI_NODE::Print( FILE *fp ) const
00683 {
00684 fprintf( fp, "Bitpos: %d", Bitpos() );
00685 if ( Loadwn() != NULL ) {
00686 const OPCODE opc = WN_opcode(Loadwn());
00687 const OPERATOR opr = OPCODE_operator(opc);
00688
00689 if ( opr == OPR_LDID ) {
00690 fprintf( fp, ", Loadwn: %s %s %d",
00691 OPCODE_name(WN_opcode(Loadwn())), ST_name(WN_st(Loadwn())),
00692 WN_load_offset(Loadwn()) );
00693 }
00694 else {
00695 fprintf( fp, ", Loadwn: " );
00696 fdump_tree( fp, Loadwn() );
00697 }
00698 }
00699 if ( Storewn() != NULL ) {
00700 fprintf( fp, ", Storewn: %s %s %d",
00701 OPCODE_name(WN_opcode(Storewn())), ST_name(WN_st(Storewn())),
00702 WN_store_offset(Storewn()) );
00703 }
00704
00705 fprintf( fp, "\n" );
00706 }
00707
00708
00709
00710
00711
00712 void
00713 RVI_VTAB::Print( FILE *fp ) const
00714 {
00715 fprintf( fp, "%sRVI_VTAB::Print\n%s", SBar, SBar );
00716 RVI_VTAB_ITER vtab_iter;
00717 RVI_NODE *vnode;
00718 FOR_ALL_NODE( vnode, vtab_iter, Init(this) ) {
00719 vnode->Print( fp );
00720 }
00721
00722 }
00723