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_rvi_CXX "opt_rvi.cxx"
00070 static char *rcs_id = opt_rvi_CXX"$Revision: 1.5 $";
00071 #endif
00072
00073 #include "defs.h"
00074 #include "errors.h"
00075 #include "erglob.h"
00076 #include "config.h"
00077 #include "tracing.h"
00078 #include "wn.h"
00079 #include "wn_lower.h"
00080
00081 #include "opt_defs.h"
00082 #include "opt_base.h"
00083 #include "opt_config.h"
00084 #include "opt_bb.h"
00085 #include "opt_cfg.h"
00086 #include "opt_htable.h"
00087 #include "opt_mu_chi.h"
00088 #include "bb_node_set.h"
00089 #include "idx_32_set.h"
00090 #include "opt_alias_mgr.h"
00091 #include "opt_rvi.h"
00092 #include "opt_rvilr.h"
00093 #include "opt_rvitab.h"
00094 #include "opt_rvi_emit.h"
00095 #include "opt_sym.h"
00096 #include "opt_util.h"
00097 #include "opt_alias_interface.h"
00098
00099
00100
00101
00102
00103 RVI::RVI( BOOL do_rvi, OPT_STAB *opt_stab, IDX_32 max_varbit, ALIAS_MANAGER *alias_mgr ) :
00104 _do_rvi(do_rvi),
00105 _opt_stab(opt_stab)
00106 {
00107
00108 if ( do_rvi ) {
00109 AUX_ID var;
00110 AUX_STAB_ITER aux_stab_iter(opt_stab);
00111
00112 _tracing = Get_Trace( TP_GLOBOPT, RVI_TRACE_FLAG );
00113 _alias_mgr = alias_mgr;
00114
00115 _rvi_gpoolp = &_rvi_gpool;
00116 OPT_POOL_Initialize( &_rvi_gpool, "Rvi_gpool", FALSE, RVI_TRACE_FLAG+1);
00117 OPT_POOL_Push( Rvi_gpool(), RVI_TRACE_FLAG+1);
00118
00119 _rvi_ppoolp = &_rvi_ppool;
00120 OPT_POOL_Initialize( &_rvi_ppool, "Rvi_ppool", FALSE, RVI_TRACE_FLAG+2);
00121 OPT_POOL_Push( Rvi_ppool() , RVI_TRACE_FLAG+2);
00122
00123 _rvi_lpoolp = &_rvi_lpool;
00124 OPT_POOL_Initialize( &_rvi_lpool, "Rvi_lpool", FALSE, RVI_TRACE_FLAG+3);
00125 OPT_POOL_Push( Rvi_lpool() , RVI_TRACE_FLAG+3);
00126
00127 WN_MAP_Status();
00128
00129 _mu_map = WN_MAP_Create( Rvi_gpool() );
00130 _chi_map = WN_MAP_Create( Rvi_gpool() );
00131 _bp_map = WN_MAP32_Create( Rvi_gpool() );
00132
00133
00134 _do_base_lda = FALSE;
00135
00136 _unique_pregs = TRUE;
00137
00138 _max_bitpos = max_varbit;
00139
00140 _last_varbit = max_varbit;
00141
00142
00143 _init_set_size = 0;
00144
00145 _rvi_ctab = NULL;
00146
00147 _cfg = NULL;
00148
00149 _dfs_vec = NULL; _dfs_vec_size = 0;
00150
00151
00152 _redundant._load_top = NULL;
00153 _redundant._load_bot = NULL;
00154 _redundant._store_top = NULL;
00155 _redundant._store_iref = NULL;
00156
00157 _volatile_set = CXX_NEW( IDX_32_SET(Initial_set_size(), Rvi_gpool(),
00158 OPTS_FALSE), Rvi_gpool() );
00159
00160 FOR_ALL_NODE(var, aux_stab_iter, Init()) {
00161 AUX_STAB_ENTRY *psym = opt_stab->Aux_stab_entry( var );
00162 if ( psym->Is_real_var() && psym->Is_volatile()) {
00163 _volatile_set->Union1D((IDX_32)psym->Itab_bitpos() + 1);
00164 }
00165 }
00166 }
00167 else {
00168
00169 }
00170 }
00171
00172
00173
00174
00175
00176 RVI::~RVI( void )
00177 {
00178
00179 if ( _do_rvi ) {
00180
00181 WN_MAP_Delete( Mu_map() );
00182 WN_MAP_Delete( Chi_map() );
00183 WN_MAP_Delete( Bp_map() );
00184
00185
00186 OPT_POOL_Pop( Rvi_lpool(), RVI_TRACE_FLAG+3);
00187 OPT_POOL_Pop( Rvi_ppool(), RVI_TRACE_FLAG+2);
00188 OPT_POOL_Pop( Rvi_gpool(), RVI_TRACE_FLAG+1);
00189 OPT_POOL_Delete( Rvi_lpool(), RVI_TRACE_FLAG+3);
00190 OPT_POOL_Delete( Rvi_ppool(), RVI_TRACE_FLAG+2);
00191 OPT_POOL_Delete( Rvi_gpool(), RVI_TRACE_FLAG+1);
00192 }
00193 else {
00194
00195 }
00196 }
00197
00198
00199
00200
00201
00202 void
00203 RVI::Map_mu_list ( WN *wn, MU_LIST *mu_list )
00204 {
00205 if ( mu_list->Is_Empty() ) {
00206 return;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216 if ( WN_operator(wn) == OPR_LDID &&
00217 ST_class(WN_st(wn)) == CLASS_PREG )
00218 {
00219 return;
00220 }
00221
00222 Warn_todo( "RVI::Map_mu_list: do not adjust bitpos by 1" );
00223
00224 MU_LIST_ITER mu_iter;
00225 MU_NODE *mu;
00226 IDX_32_SET *mu_set = NULL;
00227
00228
00229 FOR_ALL_NODE( mu, mu_iter, Init(mu_list) ) {
00230 CODEREP *mu_opnd = mu->OPND();
00231 if ( mu_opnd != NULL ) {
00232 if ( mu_opnd->Bitpos() != ILLEGAL_BP ) {
00233 if ( mu_set == NULL )
00234 mu_set = CXX_NEW( IDX_32_SET(Initial_set_size(), Rvi_gpool(),
00235 OPTS_FALSE), Rvi_gpool() );
00236 mu_set->Union1D( mu_opnd->Bitpos()+1 );
00237 }
00238 else if ( mu_opnd->Kind() == CK_VAR ) {
00239 AUX_STAB_ENTRY *sym = Opt_stab()->Aux_stab_entry(mu_opnd->Aux_id());
00240 if ( sym->Is_real_var() ) {
00241
00242 if ( sym->Itab_bitpos() != ILLEGAL_BP ) {
00243 if ( mu_set == NULL )
00244 mu_set = CXX_NEW( IDX_32_SET(Initial_set_size(), Rvi_gpool(),
00245 OPTS_FALSE), Rvi_gpool() );
00246 mu_set->Union1D( sym->Itab_bitpos()+1 );
00247 }
00248 }
00249 else {
00250
00251 if ( sym->Aux_id_list() != NULL ) {
00252 AUX_ID_LIST_ITER id_list_iter;
00253 AUX_ID_NODE *id_node;
00254 FOR_ALL_ELEM( id_node, id_list_iter, Init(sym->Aux_id_list()) ) {
00255 if ( (IDX_32)(id_node->Aux_id()) != ILLEGAL_BP ) {
00256 if ( mu_set == NULL )
00257 mu_set = CXX_NEW(IDX_32_SET(Initial_set_size(),Rvi_gpool(),
00258 OPTS_FALSE), Rvi_gpool() );
00259 mu_set->Union1D( (IDX_32)(id_node->Aux_id()+1) );
00260 }
00261 }
00262 }
00263 }
00264 }
00265 }
00266 }
00267
00268 if ( mu_set != NULL ) {
00269 WN_MAP_Set( Mu_map(), wn, (void*)mu_set );
00270 }
00271 }
00272
00273
00274
00275
00276
00277 void
00278 RVI::Map_mu_node ( WN *wn, MU_NODE *mu_node )
00279 {
00280
00281
00282
00283
00284
00285
00286
00287 if ( WN_operator(wn) == OPR_LDID &&
00288 ST_class(WN_st(wn)) == CLASS_PREG )
00289 {
00290 return;
00291 }
00292
00293 Warn_todo( "RVI::Map_mu_node: do not adjust bitpos by 1" );
00294
00295 IDX_32_SET *mu_set = NULL;
00296
00297 CODEREP *mu_opnd = mu_node->OPND();
00298 if ( mu_opnd != NULL ) {
00299 if ( mu_opnd->Bitpos() != ILLEGAL_BP ) {
00300 if ( mu_set == NULL )
00301 mu_set = CXX_NEW( IDX_32_SET(Initial_set_size(), Rvi_gpool(),
00302 OPTS_FALSE), Rvi_gpool() );
00303 mu_set->Union1D( mu_opnd->Bitpos()+1 );
00304 }
00305 else if ( mu_opnd->Kind() == CK_VAR ) {
00306 AUX_STAB_ENTRY *sym = Opt_stab()->Aux_stab_entry(mu_opnd->Aux_id());
00307 if ( sym->Is_real_var() ) {
00308
00309 if ( sym->Itab_bitpos() != ILLEGAL_BP ) {
00310 if ( mu_set == NULL )
00311 mu_set = CXX_NEW( IDX_32_SET(Initial_set_size(), Rvi_gpool(),
00312 OPTS_FALSE), Rvi_gpool() );
00313 mu_set->Union1D( sym->Itab_bitpos()+1 );
00314 }
00315 }
00316 else {
00317
00318 if ( sym->Aux_id_list() != NULL ) {
00319 AUX_ID_LIST_ITER id_list_iter;
00320 AUX_ID_NODE *id_node;
00321 FOR_ALL_ELEM( id_node, id_list_iter, Init(sym->Aux_id_list()) ) {
00322 if ( (IDX_32)(id_node->Aux_id()) != ILLEGAL_BP ) {
00323 if ( mu_set == NULL )
00324 mu_set = CXX_NEW(IDX_32_SET(Initial_set_size(),Rvi_gpool(),
00325 OPTS_FALSE), Rvi_gpool() );
00326 mu_set->Union1D( (IDX_32)(id_node->Aux_id()+1) );
00327 }
00328 }
00329 }
00330 }
00331 }
00332 }
00333
00334 if ( mu_set != NULL ) {
00335 WN_MAP_Set( Mu_map(), wn, (void*)mu_set );
00336 }
00337 }
00338
00339
00340
00341
00342
00343 void
00344 RVI::Map_chi_list ( WN *wn, CHI_LIST *chi_list )
00345 {
00346 if ( chi_list->Is_Empty() ) {
00347 return;
00348 }
00349
00350 Warn_todo( "RVI::Map_chi_list: do not adjust bitpos by 1" );
00351
00352 CHI_LIST_ITER chi_iter;
00353 CHI_NODE *chi;
00354 IDX_32_SET *chi_set = NULL;
00355
00356 const OPERATOR opr = WN_operator(wn);
00357 const BOOL is_scalar = (opr == OPR_STID);
00358 const BOOL is_istore = (opr == OPR_ISTORE);
00359
00360 #ifdef DEBUGGING
00361 if ( Tracing() ) {
00362 fprintf( TFile, "RVI::Map_chi_list: WN <%d:%d>\n",
00363 OPCODE_mapcat(WN_opcode(wn)), WN_map_id(wn) );
00364 }
00365 #endif
00366
00367
00368 FOR_ALL_NODE( chi, chi_iter, Init(chi_list) ) {
00369 CODEREP *chi_res = chi->RESULT();
00370 if ( chi_res != NULL ) {
00371
00372 #ifdef DEBUGGING
00373 if ( Tracing() ) {
00374 fprintf( TFile, "..chi=" );
00375 chi->Print(TFile);
00376 }
00377 #endif
00378 if ( chi_res->Bitpos() != ILLEGAL_BP ) {
00379 if ( chi_set == NULL )
00380 chi_set = CXX_NEW( IDX_32_SET(Initial_set_size(), Rvi_gpool(),
00381 OPTS_FALSE), Rvi_gpool() );
00382 chi_set->Union1D( chi_res->Bitpos()+1 );
00383 #ifdef DEBUGGING
00384 if ( Tracing() ) {
00385 fprintf( TFile, " chi_res->Bitpos() != ILLEGAL_BP\n" );
00386 }
00387 #endif
00388 }
00389 else if ( chi_res->Kind() == CK_VAR ) {
00390 AUX_STAB_ENTRY *sym = Opt_stab()->Aux_stab_entry(chi_res->Aux_id());
00391 if ( sym->Is_real_var() ) {
00392
00393 #ifdef DEBUGGING
00394 if ( Tracing() ) {
00395 fprintf( TFile, " regular variable\n" );
00396 }
00397 #endif
00398 if ( sym->Itab_bitpos() != ILLEGAL_BP ) {
00399 if ( chi_set == NULL )
00400 chi_set = CXX_NEW( IDX_32_SET(Initial_set_size(), Rvi_gpool(),
00401 OPTS_FALSE), Rvi_gpool() );
00402 chi_set->Union1D( sym->Itab_bitpos()+1 );
00403 #ifdef DEBUGGING
00404 if ( Tracing() ) {
00405 fprintf( TFile, " sym->Itab_bitpos() != ILLEGAL_BP\n" );
00406 }
00407 #endif
00408 }
00409 }
00410 else {
00411
00412 #ifdef DEBUGGING
00413 if ( Tracing() ) {
00414 fprintf( TFile, " virtual variable\n" );
00415 }
00416 #endif
00417 if ( WOPT_Enable_Rvivsym ) {
00418 #ifdef DEBUGGING
00419 if ( Tracing() ) {
00420 fprintf( TFile, " skipping vsym\n" );
00421 }
00422 #endif
00423 continue;
00424 }
00425
00426 if ( is_istore && WOPT_Enable_Rviistore ) {
00427
00428
00429
00430 #ifdef DEBUGGING
00431 if ( Tracing() ) {
00432 fprintf( TFile, " is_istore, so skip virtual variable\n" );
00433 }
00434 #endif
00435 continue;
00436 }
00437 if ( sym->Aux_id_list() != NULL ) {
00438 #ifdef DEBUGGING
00439 if ( Tracing() ) {
00440 fprintf( TFile, " Aux_id_list() != NULL\n" );
00441 }
00442 #endif
00443 AUX_ID_LIST_ITER id_list_iter;
00444 AUX_ID_NODE *id_node;
00445 FOR_ALL_ELEM( id_node, id_list_iter, Init(sym->Aux_id_list()) ) {
00446 #ifdef DEBUGGING
00447 if ( Tracing() ) {
00448 fprintf( TFile, " Inside Aux_id_list() iter\n" );
00449 }
00450 #endif
00451 if ( (IDX_32)(id_node->Aux_id()) != ILLEGAL_BP ) {
00452 if ( chi_set == NULL )
00453 chi_set = CXX_NEW(IDX_32_SET(Initial_set_size(),Rvi_gpool(),
00454 OPTS_FALSE), Rvi_gpool() );
00455
00456
00457
00458
00459
00460
00461 if ( ! is_scalar ) {
00462 chi_set->Union1D( (IDX_32)(id_node->Aux_id()+1) );
00463 }
00464 #ifdef DEBUGGING
00465 if ( Tracing() ) {
00466 fprintf( TFile, " id_node->Aux_id() != ILLEGAL_BP\n" );
00467 }
00468 #endif
00469 }
00470 }
00471 }
00472 }
00473 }
00474 }
00475 }
00476
00477 if ( chi_set != NULL ) {
00478 WN_MAP_Set( Chi_map(), wn, (void*)chi_set );
00479 }
00480 }
00481
00482
00483
00484
00485
00486
00487 IDX_32_SET *
00488 RVI::Bb_end_mu_list( const BB_NODE *bb ) const
00489 {
00490 return bb->Loc_mu_ref();
00491 }
00492
00493
00494
00495
00496
00497
00498 IDX_32_SET *
00499 RVI::Bb_end_chi_list( const BB_NODE *bb ) const
00500 {
00501 return bb->Loc_chi_def();
00502 }
00503
00504
00505
00506
00507
00508 BOOL
00509 RVI::Is_exit_block( const BB_NODE *bb ) const
00510 {
00511 if ( bb->Kind() == BB_EXIT || bb->Kind() == BB_REGIONEXIT ) {
00512 return TRUE;
00513 }
00514
00515 return FALSE;
00516 }
00517
00518
00519
00520
00521
00522
00523 const IDX_32_SET *
00524 RVI::Global_vars( const BB_NODE *bb ) const
00525 {
00526 WN *last = bb->Laststmt();
00527 if ( last != NULL ) {
00528 if ( WN_has_mu(last, Cfg()->Rgn_level()) ) {
00529 return Get_mu_list( last );
00530 }
00531 }
00532
00533 return NULL;
00534 }
00535
00536
00537
00538
00539
00540 void
00541 RVI::Resize_sets( BB_NODE *bb, INT32 new_size ) const
00542 {
00543 if ( bb->Loc_appear() )
00544 bb->Loc_appear()->ResizeD( new_size );
00545 if ( bb->Loc_def() )
00546 bb->Loc_def()->ResizeD( new_size );
00547 if ( bb->Loc_upwd() )
00548 bb->Loc_upwd()->ResizeD( new_size );
00549 if ( bb->Loc_mu_ref() )
00550 bb->Loc_mu_ref()->ResizeD( new_size );
00551
00552
00553 if ( Has_end_chi_list(bb) ) {
00554 IDX_32_SET *chi_set = Bb_end_chi_list( bb );
00555 if ( chi_set != NULL ) {
00556 chi_set->ResizeD( new_size );
00557 }
00558 }
00559 }
00560
00561
00562
00563
00564
00565 void
00566 RVI::Init_redundant( MEM_POOL *pool )
00567 {
00568 _redundant._load_top = CXX_NEW(BB_NODE_SET(Cfg()->Total_bb_count(),
00569 Cfg(), pool, BBNS_EMPTY), pool);
00570 _redundant._load_bot = CXX_NEW(BB_NODE_SET(Cfg()->Total_bb_count(),
00571 Cfg(), pool, BBNS_EMPTY), pool);
00572 _redundant._store_top = CXX_NEW(BB_NODE_SET(Cfg()->Total_bb_count(),
00573 Cfg(), pool, BBNS_EMPTY), pool);
00574 _redundant._store_iref = CXX_NEW(BB_NODE_SET(Cfg()->Total_bb_count(),
00575 Cfg(), pool, BBNS_EMPTY), pool);
00576 }
00577
00578
00579
00580
00581
00582 void
00583 RVI::Clear_redundant( void ) const
00584 {
00585 _redundant._load_top->ClearD();
00586 _redundant._load_bot->ClearD();
00587 _redundant._store_top->ClearD();
00588 _redundant._store_iref->ClearD();
00589 }
00590
00591
00592
00593
00594
00595
00596
00597
00598 void
00599 RVI::Find_loops( void ) const
00600 {
00601 Warn_todo( "RVI::Find_loops: get valid loops" );
00602
00603 CFG_ITER cfg_iter(Cfg());
00604 BB_NODE *bb;
00605 FOR_ALL_NODE( bb, cfg_iter, Init() ) {
00606
00607 if ( bb->Succ() != NULL && bb->Succ()->Contains(bb) ) {
00608 bb->Set_loopdepth( 1 );
00609 }
00610 }
00611 }
00612
00613
00614
00615
00616
00617
00618 WN *
00619 RVI::Perform_phase1( WN *entry_wn )
00620 {
00621 WN *return_wn;
00622 OPT_POOL_Push( Rvi_ppool(), RVI_TRACE_FLAG+4 );
00623
00624 {
00625 CFG cfg( Rvi_ppool(), Rvi_lpool() );
00626 _cfg = &cfg;
00627
00628
00629 RVI_CTAB ctab( Rvi_ppool() );
00630 _rvi_ctab = &ctab;
00631
00632
00633 RVI_VTAB vtab( Last_varbit(), Rvi_ppool() );
00634 _rvi_vtab = &vtab;
00635
00636
00637 Warn_todo( "RVI::Perform_phase1: get rid of Set_rvi_break_stmt" );
00638 cfg.Set_rvi_break_stmt(WOPT_Enable_Rvisplit);
00639 cfg.Create(entry_wn, TRUE, TRUE,
00640 RL_RVI1, NULL,
00641 FALSE );
00642
00643 cfg.Remove_fake_entryexit_arcs();
00644
00645 Find_loops();
00646
00647
00648
00649 Copy_dedicated_regs_to_pregs();
00650
00651 if ( Tracing() ) {
00652 fprintf( TFile, "%sBefore Perform_phase1 RVI\n%s", DBar, DBar );
00653 cfg.Print( TFile );
00654 fprintf( TFile, "%sPerform_phase1\n%s", SBar, SBar );
00655 }
00656
00657
00658 Get_local_attributes( FALSE );
00659
00660
00661
00662 _dfs_vec = cfg.Dfs_vec();
00663 _dfs_vec_size = cfg.Dfs_vec_sz();
00664
00665
00666
00667 Init_redundant( Rvi_ppool() );
00668
00669 if ( Tracing() ) {
00670 Rvi_vtab()->Print( TFile );
00671 Rvi_ctab()->Print( TFile );
00672 }
00673
00674
00675 Get_dataflow_equations();
00676
00677
00678 Perform_variable_rvi();
00679
00680
00681 Perform_constant_rvi();
00682
00683 if ( Tracing() ) {
00684 fprintf( TFile, "%sAfter Perform_phase1 RVI\n%s", DBar, DBar );
00685 cfg.Print( TFile );
00686 }
00687
00688
00689 RVI_EMIT emitter( this, FALSE, Alias_Mgr(), RL_RVI1 );
00690 return_wn = emitter.Entry_wn();
00691
00692 if ( Tracing() ) {
00693 fprintf( TFile, "%sPerform_phase1 return_wn\n%s", SBar, SBar );
00694 fdump_tree( TFile, return_wn );
00695 }
00696 }
00697
00698 OPT_POOL_Pop( Rvi_ppool(), RVI_TRACE_FLAG+4 );
00699
00700 return return_wn;
00701 }
00702
00703
00704
00705
00706
00707 WN *
00708 RVI::Perform_phase2( WN *entry_wn )
00709 {
00710 WN *return_wn;
00711 OPT_POOL_Push( Rvi_ppool(), RVI_TRACE_FLAG+5 );
00712
00713 {
00714
00715
00716
00717
00718 WN_MAP_Delete( Mu_map() );
00719 WN_MAP_Delete( Chi_map() );
00720 WN_MAP_Delete( Bp_map() );
00721 _mu_map = WN_MAP_Create( Rvi_gpool() );
00722 _chi_map = WN_MAP_Create( Rvi_gpool() );
00723 _bp_map = WN_MAP32_Create( Rvi_gpool() );
00724
00725
00726
00727 _max_bitpos = 0;
00728
00729
00730 _init_set_size = 0;
00731
00732 CFG cfg( Rvi_ppool(), Rvi_lpool() );
00733 _cfg = &cfg;
00734
00735
00736 RVI_CTAB ctab( Rvi_ppool() );
00737 _rvi_ctab = &ctab;
00738
00739
00740 _rvi_vtab = NULL;
00741
00742
00743 cfg.Set_rvi_break_stmt(FALSE);
00744 cfg.Create(entry_wn, TRUE, TRUE,
00745 RL_RVI2, NULL,
00746 FALSE );
00747
00748
00749 cfg.Remove_fake_entryexit_arcs();
00750
00751 _dfs_vec = cfg.Dfs_vec();
00752 _dfs_vec_size = cfg.Dfs_vec_sz();
00753
00754
00755 Find_loops();
00756
00757
00758
00759
00760
00761 Set_callrel();
00762
00763 if ( Tracing() ) {
00764 fprintf( TFile, "%sBefore RVI::Perform_phase2\n%s", DBar, DBar );
00765 cfg.Print( TFile );
00766
00767 fprintf( TFile, "%sRVI::Perform_phase2\n%s", SBar, SBar );
00768 }
00769
00770
00771 Get_local_attributes( TRUE );
00772
00773
00774
00775 Init_redundant( Rvi_ppool() );
00776
00777 if ( Tracing() ) {
00778 Rvi_ctab()->Print( TFile );
00779 }
00780
00781
00782 Get_lda_dataflow_equations();
00783
00784
00785 Perform_constant_rvi();
00786
00787 if ( Tracing() ) {
00788 fprintf( TFile, "%sAfter RVI::Perform_phase2\n%s", DBar, DBar );
00789 cfg.Print( TFile );
00790 }
00791
00792
00793 RVI_EMIT emitter( this, TRUE, Alias_Mgr(), RL_RVI2 );
00794 return_wn = emitter.Entry_wn();
00795 if ( Tracing() ) {
00796 fprintf( TFile, "%sPerform_phase2 return_wn\n%s", SBar, SBar );
00797 fdump_tree( TFile, return_wn );
00798 }
00799 }
00800
00801 OPT_POOL_Pop( Rvi_ppool(), RVI_TRACE_FLAG+5 );
00802
00803 return return_wn;
00804 }
00805
00806
00807
00808
00809
00810 static void
00811 PRINT_HOMING_INFO( WN *wn, ALIAS_MANAGER *am, BOOL first_time )
00812 {
00813 if ( first_time ) {
00814 fprintf( TFile, "%sPRINT_HOMING_INFO\n%s", DBar, DBar );
00815 }
00816
00817 const OPCODE opc = WN_opcode(wn);
00818
00819 if ( opc == OPC_FUNC_ENTRY ) {
00820 PRINT_HOMING_INFO( WN_func_body(wn), am, FALSE );
00821 }
00822 else if ( opc == OPC_BLOCK ) {
00823 for ( WN *stmt = WN_first(wn); stmt; stmt = WN_next(stmt) ) {
00824 PRINT_HOMING_INFO( stmt, am, FALSE );
00825 }
00826 }
00827 else {
00828
00829
00830 if ( am->Homing_load(wn) ) {
00831 fprintf( TFile, "Homing: " );
00832 fdump_wn( TFile, wn );
00833 }
00834
00835 for ( INT i = 0; i < WN_kid_count(wn); i++ ) {
00836 PRINT_HOMING_INFO( WN_kid(wn,i), am, FALSE );
00837 }
00838 }
00839 }
00840
00841
00842
00843
00844
00845
00846
00847 WN *
00848 RVI::Perform_RVI( WN *entry_wn, ALIAS_MANAGER *alias_mgr )
00849 {
00850 Is_True(REGION_consistency_check(entry_wn),
00851 ("RVI::Perform_RVI, inconsistent region in RVI"));
00852 Set_Error_Phase("RVI1");
00853 WN *phase1_wn = WOPT_Enable_RVI1 ?
00854 Perform_phase1( entry_wn ) :
00855 entry_wn;
00856 Is_True(phase1_wn && REGION_consistency_check(phase1_wn),
00857 ("RVI::Perform_RVI, inconsistent region from RVI phase 1"));
00858 Verify_alias(alias_mgr,phase1_wn);
00859
00860 LOWER_ACTIONS actions =
00861 LOWER_SPLIT_CONST_OFFSETS |
00862 LOWER_SPLIT_SYM_ADDRS |
00863 LOWER_PICCALL |
00864 LOWER_MLDID_MSTID |
00865 LOWER_ALL_MAPS;
00866
00867 WN *lda_wn = WN_Lower( phase1_wn,
00868 actions,
00869 alias_mgr, "RVI" );
00870
00871 REGION_new_wn(lda_wn, phase1_wn);
00872
00873 if ( Tracing() ) {
00874 fprintf( TFile, "%sAfter LDA Lowering\n%s", SBar, SBar );
00875 fdump_tree( TFile, lda_wn );
00876 }
00877
00878 Set_Error_Phase("RVI2");
00879 WN *phase2_wn = WOPT_Enable_RVI2 ?
00880 Perform_phase2( lda_wn ) :
00881 lda_wn;
00882 Is_True(REGION_consistency_check(phase2_wn),
00883 ("RVI::Perform_RVI, inconsistent region from RVI phase 2"));
00884 Verify_alias(alias_mgr,phase2_wn);
00885
00886 return phase2_wn;
00887 }
00888
00889
00890
00891
00892
00893
00894 RVI_NODE *
00895 RVI::Add_to_const_table( WN *wn )
00896 {
00897 IDX_32 hash_val = Rvi_ctab()->Hash( wn );
00898 RVI_NODE *cnode = Rvi_ctab()->Find( wn, hash_val );
00899
00900 if ( cnode == NULL ) {
00901
00902 IDX_32 bitpos = Next_bitpos();
00903 Map_bitpos( wn, bitpos );
00904
00905 cnode = Rvi_ctab()->Add_unique( wn, bitpos, hash_val );
00906 }
00907 else {
00908
00909 Map_bitpos( wn, cnode->Bitpos() );
00910 }
00911
00912 return cnode;
00913 }
00914
00915
00916
00917
00918
00919 BOOL
00920 RVI::Is_base_lda( const WN *wn ) const
00921 {
00922 Is_True( WN_operator(wn) == OPR_LDA,
00923 ("RVI::Is_base_lda (not): %s", OPERATOR_name(WN_operator(wn))) );
00924
00925 return ( WN_lda_offset(wn) == 0 );
00926 }
00927
00928
00929
00930
00931
00932 BOOL
00933 RVI::Is_ldid_candidate( const WN *ldidwn ) const
00934 {
00935 Warn_todo( "RVI::Is_ldid_candidate: returns true" );
00936 return TRUE;
00937 }
00938
00939
00940
00941
00942
00943 BOOL
00944 RVI::Is_stid_candidate( const WN *stidwn ) const
00945 {
00946 Warn_todo( "RVI::Is_stid_candidate: returns true" );
00947 return TRUE;
00948 }
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958 void
00959 RVI::Get_wn_local_attributes( BB_NODE *bb, WN *wn, BOOL *check_const )
00960 {
00961 IDX_32 bitpos = ILLEGAL_BP;
00962 RVI_NODE *rvi_node;
00963
00964 const OPCODE opc = WN_opcode(wn);
00965 const OPERATOR opr = OPCODE_operator(opc);
00966
00967
00968 *check_const = FALSE;
00969
00970
00971
00972
00973
00974 if ( WN_has_mu(wn, Cfg()->Rgn_level()) ) {
00975 IDX_32_SET *mu_set = Get_mu_list( wn );
00976 if ( mu_set != NULL ) {
00977
00978
00979 if ( bb->Loc_mu_ref() == NULL ) {
00980
00981 bb->Set_loc_mu_ref(mu_set);
00982 }
00983 else {
00984
00985 bb->Loc_mu_ref()->UnionD( mu_set );
00986 }
00987
00988 if ( Tracing() ) {
00989 fprintf( TFile, "<wn_local_attr> Mu refs: " );
00990 mu_set->Print(TFile);
00991 fprintf( TFile, "\n" );
00992 fdump_wn( TFile, wn );
00993 }
00994 }
00995 }
00996
00997
00998
00999
01000 if ( ! Black_box(opc) ) {
01001
01002 for ( INT ikid = 0; ikid < WN_kid_count(wn); ikid++ ) {
01003 WN *kid = WN_kid(wn,ikid);
01004 BOOL is_const;
01005 #ifdef KEY // bug 12471: __builtin_expect's first kid must be constant
01006 if (WN_operator(wn) == OPR_INTRINSIC_OP &&
01007 ((INTRINSIC) WN_intrinsic(wn)) == INTRN_EXPECT &&
01008 ikid == 1)
01009 continue;
01010 #endif
01011 Get_wn_local_attributes( bb, kid, &is_const );
01012
01013
01014 if ( is_const ) {
01015 if ( WN_operator(kid) == OPR_INTCONST ) {
01016 if ( Is_const_candidate( wn, kid, ikid ) ) {
01017 rvi_node = Add_to_const_table( kid );
01018 rvi_node->Add_reference( bb, TRUE, Rvi_ppool() );
01019 bitpos = rvi_node->Bitpos();
01020 bb->Loc_appear()->Union1D( bitpos );
01021 bb->Loc_upwd()->Union1D( bitpos );
01022 }
01023 }
01024 else if ( WN_operator(kid) == OPR_LDA ) {
01025
01026 if ( Is_lda_candidate( wn, kid, ikid ) ) {
01027 rvi_node = Add_to_const_table( kid );
01028 rvi_node->Add_reference( bb, TRUE, Rvi_ppool() );
01029 bitpos = rvi_node->Bitpos();
01030 bb->Loc_appear()->Union1D( bitpos );
01031 bb->Loc_upwd()->Union1D( bitpos );
01032 }
01033 }
01034 else {
01035 FmtAssert( FALSE,
01036 ("Unknown is_const operator: %s",
01037 OPCODE_name(WN_opcode(kid))) );
01038 }
01039 }
01040 }
01041 }
01042
01043 switch ( opr ) {
01044 case OPR_CONST:
01045
01046 rvi_node = Add_to_const_table( wn );
01047 rvi_node->Add_reference( bb, TRUE, Rvi_ppool() );
01048 bitpos = rvi_node->Bitpos();
01049 bb->Loc_appear()->Union1D( bitpos );
01050 bb->Loc_upwd()->Union1D( bitpos );
01051 break;
01052
01053 case OPR_INTCONST:
01054
01055
01056
01057 *check_const = TRUE;
01058 break;
01059
01060 case OPR_LDA:
01061
01062 if ( ! Is_base_lda( wn ) ) {
01063 *check_const = TRUE;
01064 }
01065 break;
01066
01067 case OPR_LDID:
01068 if ( ST_class(WN_st(wn)) == CLASS_PREG ) {
01069
01070 break;
01071 }
01072 bitpos = Get_bitpos( wn );
01073 if ( bitpos == ILLEGAL_BP ) {
01074
01075 FmtAssert( FALSE,
01076 ("RVI::Get_wn_local_attributes: ldid has no bitpos") );
01077 break;
01078 }
01079 if ( ! Is_ldid_candidate( wn ) ) {
01080
01081
01082 Warn_todo( "RVI::Get_wn_local_attributes: not candidate ldid" );
01083
01084 Map_bitpos( wn, ILLEGAL_BP );
01085 break;
01086 }
01087
01088 FmtAssert( bitpos != ILLEGAL_BP && bitpos <= Last_varbit(),
01089 ("RVI::Get_wn_local_attributes: LDID bitpos invalid %d",
01090 bitpos) );
01091
01092 rvi_node = Rvi_vtab()->Add_load( wn, bitpos );
01093 rvi_node->Add_reference( bb, TRUE, Rvi_ppool() );
01094
01095 bb->Loc_appear()->Union1D( bitpos );
01096
01097
01098
01099 if ( ! bb->Loc_def()->MemberP( bitpos ) ) {
01100 bb->Loc_upwd()->Union1D( bitpos );
01101 }
01102 break;
01103
01104 case OPR_STID:
01105 if ( ST_class(WN_st(wn)) == CLASS_PREG ) {
01106
01107 break;
01108 }
01109 bitpos = Get_bitpos( wn );
01110 if ( bitpos == ILLEGAL_BP ) {
01111
01112 FmtAssert( FALSE,
01113 ("RVI::Get_wn_local_attributes: stid has no bitpos") );
01114 break;
01115 }
01116
01117 if ( ! Is_stid_candidate( wn ) ) {
01118
01119
01120 Warn_todo( "RVI::Get_wn_local_attributes: not candidate stid" );
01121
01122 Map_bitpos( wn, ILLEGAL_BP );
01123 break;
01124 }
01125
01126 FmtAssert( bitpos != ILLEGAL_BP && bitpos <= Last_varbit(),
01127 ("RVI::Get_wn_local_attributes: STID bitpos invalid %d",
01128 bitpos) );
01129
01130 rvi_node = Rvi_vtab()->Add_store( wn, bitpos );
01131 rvi_node->Add_reference( bb, FALSE, Rvi_ppool() );
01132 bb->Loc_appear()->Union1D( bitpos );
01133 bb->Loc_def()->Union1D( bitpos );
01134
01135 break;
01136
01137 default:
01138 break;
01139 }
01140
01141
01142 if ( WN_has_chi(wn, Cfg()->Rgn_level()) ) {
01143 IDX_32_SET *chi_set = Get_chi_list( wn );
01144 if ( chi_set != NULL ) {
01145
01146
01147 if ( opr == OPR_STID && bitpos != ILLEGAL_BP ) {
01148 chi_set->Difference1D( bitpos );
01149
01150
01151
01152
01153 bb->Set_last_stid_has_chi( TRUE );
01154 }
01155
01156 Is_True( bb->Loc_chi_def() == NULL,
01157 ("RVI::Get_wn_local_attributes: Loc_chi_def already set") );
01158 bb->Set_loc_chi_def( chi_set );
01159
01160 if ( Tracing() ) {
01161 fprintf( TFile, "<wn_local_attr>: " );
01162 fdump_wn( TFile, wn );
01163 fprintf( TFile, " Chi defs: " );
01164 chi_set->Print(TFile);
01165 fprintf( TFile, "\n" );
01166 }
01167 }
01168 }
01169
01170
01171 if ( opr == OPR_STID && bitpos != ILLEGAL_BP ) {
01172
01173
01174 if ( wn == bb->Laststmt() ||
01175 bb->Loc_mu_ref() != NULL ||
01176 bb->Loc_chi_def() != NULL )
01177 {
01178 bb->Set_last_stid_bitpos( bitpos );
01179 }
01180 else {
01181
01182
01183 if ( Get_chi_list( wn ) == NULL ) {
01184 bb->Unstored_defs()->Union1D( bitpos );
01185 }
01186 }
01187 }
01188
01189 }
01190
01191
01192
01193
01194
01195 void
01196 RVI::Get_bb_local_attributes( BB_NODE *bb )
01197 {
01198
01199 bb->Set_loc_appear( CXX_NEW(IDX_32_SET(Initial_set_size(),
01200 Rvi_ppool(), OPTS_FALSE), Rvi_ppool()));
01201 bb->Set_loc_def( CXX_NEW(IDX_32_SET(Initial_set_size(),
01202 Rvi_ppool(), OPTS_FALSE), Rvi_ppool()));
01203 bb->Set_loc_upwd( CXX_NEW(IDX_32_SET(Initial_set_size(),
01204 Rvi_ppool(), OPTS_FALSE), Rvi_ppool()));
01205 bb->Set_unstored_defs( CXX_NEW(IDX_32_SET(Initial_set_size(),
01206 Rvi_ppool(), OPTS_FALSE), Rvi_ppool()));
01207
01208
01209 bb->Set_loc_chi_def( NULL );
01210 bb->Set_loc_mu_ref( NULL );
01211 bb->Set_loc_mu_wn( NULL );
01212 bb->Set_last_stid_bitpos( ILLEGAL_BP );
01213 bb->Set_last_stid_has_chi( FALSE );
01214
01215
01216 bb->Set_rvi_anns( NULL );
01217
01218 WN *first = bb->Firststmt();
01219
01220 if ( first == NULL ) {
01221
01222 }
01223 else {
01224 STMT_ITER stmt_iter;
01225 WN *wn;
01226 FOR_ALL_ELEM( wn, stmt_iter, Init(bb->Firststmt(),bb->Laststmt()) ){
01227 BOOL is_const;
01228 BOOL need_to_split = FALSE;
01229 Get_wn_local_attributes( bb, wn, &is_const );
01230 Is_True( !is_const,
01231 ("RVI::Get_bb_local_attributes: statement can't be constant") );
01232
01233 if ( bb->Loc_mu_ref() != NULL ) {
01234
01235
01236 Is_True( bb->Loc_mu_wn() == NULL,
01237 ("RVI::Get_bb_local_attributes: Loc_mu_wn set") );
01238 bb->Set_loc_mu_wn( wn );
01239 need_to_split = TRUE;
01240 }
01241
01242 if ( bb->Loc_chi_def() != NULL ) {
01243
01244 bb->Set_loc_mu_wn( wn );
01245 need_to_split = TRUE;
01246 }
01247
01248 if ( need_to_split && wn != bb->Laststmt() ) {
01249 Is_True( !WOPT_Enable_Rvisplit,
01250 ("RVI::Get_bb_local_attributes: need to split") );
01251
01252 BB_NODE *newbb = Cfg()->Split_bb_with_wns( bb, wn );
01253
01254 if ( ! OPCODE_is_call(WN_opcode(wn)) )
01255 newbb->Pred()->Node()->Reset_hascall();
01256
01257 if ( Tracing() ) {
01258 fprintf( TFile,
01259 "Get_bb_local_attributes: split BB:%d into BB:%d/BB:%d\n",
01260 bb->Id(), bb->Id(), newbb->Id() );
01261 }
01262
01263
01264 break;
01265 }
01266 }
01267
01268
01269 if ( bb->Hascall() && bb->Loc_mu_wn() == NULL ) {
01270 bb->Set_loc_mu_wn( bb->Laststmt() );
01271 }
01272
01273 }
01274
01275 #ifdef Is_True_On
01276 if ( Tracing() ) {
01277 fprintf( TFile, "BB:%d Loc_appear: ", bb->Id() );
01278 bb->Loc_appear()->Print(TFile);
01279 fprintf( TFile, "\n" );
01280 fprintf( TFile, "BB:%d Loc_def: ", bb->Id() );
01281 bb->Loc_def()->Print(TFile);
01282 fprintf( TFile, "\n" );
01283 fprintf( TFile, "BB:%d Loc_upwd: ", bb->Id() );
01284 bb->Loc_upwd()->Print(TFile);
01285 fprintf( TFile, "\n" );
01286 fprintf( TFile, "BB:%d Unstored_defs: ", bb->Id() );
01287 bb->Unstored_defs()->Print(TFile);
01288 fprintf( TFile, "\n" );
01289 fprintf( TFile, "BB:%d Loc_mu_ref: ", bb->Id() );
01290 if ( bb->Loc_mu_ref() )
01291 bb->Loc_mu_ref()->Print(TFile);
01292 else
01293 fprintf( TFile, "NULL" );
01294 fprintf( TFile, "\n" );
01295 fprintf( TFile, "BB:%d Loc_chi_def: ", bb->Id() );
01296 if ( bb->Loc_chi_def() )
01297 bb->Loc_chi_def()->Print(TFile);
01298 else
01299 fprintf( TFile, "NULL" );
01300 fprintf( TFile, "\n" );
01301 if ( bb->Last_stid_bitpos() != ILLEGAL_BP ) {
01302 fprintf( TFile, "BB:%d Last_stid_bitpos: %d %s\n",
01303 bb->Id(), bb->Last_stid_bitpos(),
01304 (bb->Last_stid_has_chi() ? "(has chi)" : "") );
01305 }
01306 }
01307 #endif
01308
01309 }
01310
01311
01312
01313
01314
01315
01316
01317 #if defined(TARG_SL)
01318 BOOL
01319 RVI::Is_Intrncall_Nth_Parm_Need_RVI(INTRINSIC id, INT nth_parm ) {
01320 switch(id) {
01321 case INTRN_C2_LD_C_IMM:
01322 case INTRN_C2_ST_C_IMM:
01323 if(nth_parm == 1) return TRUE;
01324 return FALSE;
01325 case INTRN_C2_LD_V2G_IMM:
01326 case INTRN_C2_ST_G2V_IMM:
01327 case INTRN_C2_LD_G_IMM:
01328 case INTRN_C2_ST_G_IMM:
01329 if(nth_parm == 2) return TRUE;
01330 return FALSE;
01331 case INTRN_C2_ST_V_IMM:
01332 if(nth_parm == 3) return TRUE;
01333 return FALSE;
01334 case INTRN_C2_LD_V_IMM:
01335 if(nth_parm == 4) return TRUE;
01336 return FALSE;
01337 default:
01338 return FALSE;
01339 }
01340 return FALSE;
01341 }
01342 #endif
01343
01344
01345
01346
01347
01348
01349
01350
01351 void
01352 RVI::Get_wn_local_lda_attributes( BB_NODE *bb, WN *wn, BOOL *check_lda )
01353 {
01354 IDX_32 bitpos;
01355 RVI_NODE *rvi_node;
01356
01357
01358 *check_lda = FALSE;
01359
01360 const OPCODE opc = WN_opcode(wn);
01361 const OPERATOR opr = OPCODE_operator(opc);
01362
01363
01364
01365
01366 if ( ! Black_box(opc) ) {
01367
01368 for ( INT ikid = 0; ikid < WN_kid_count(wn); ikid++ ) {
01369 BOOL is_lda;
01370
01371 #ifdef TARG_SL
01372
01373
01374
01375 if( (opr==OPR_INTRINSIC_CALL || opr == OPR_INTRINSIC_OP) &&
01376 Is_Intrncall_Nth_Parm_Need_RVI(WN_intrinsic(wn), ikid))
01377 continue;
01378 #endif
01379 Get_wn_local_lda_attributes( bb, WN_kid(wn,ikid), &is_lda );
01380
01381
01382 if ( is_lda ) {
01383 if ( Is_lda_candidate( wn, WN_kid(wn,ikid), ikid ) ) {
01384 rvi_node = Add_to_const_table( WN_kid(wn,ikid) );
01385 rvi_node->Add_reference( bb, TRUE, Rvi_ppool() );
01386 bitpos = rvi_node->Bitpos();
01387 bb->Loc_appear()->Union1D( bitpos );
01388 }
01389 }
01390 }
01391 }
01392
01393 if ( opr == OPR_LDA ) {
01394
01395 if ( Is_base_lda( wn ) ) {
01396 *check_lda = TRUE;
01397 }
01398 }
01399
01400 }
01401
01402
01403
01404
01405
01406 void
01407 RVI::Get_bb_local_lda_attributes( BB_NODE *bb )
01408 {
01409
01410 bb->Set_loc_appear( CXX_NEW(IDX_32_SET(Initial_set_size(),
01411 Rvi_ppool(), OPTS_FALSE), Rvi_ppool()));
01412 bb->Set_loc_def( NULL );
01413 bb->Set_loc_upwd( NULL );
01414 bb->Set_unstored_defs( NULL );
01415
01416 bb->Set_loc_chi_def( NULL );
01417 bb->Set_loc_mu_ref( NULL );
01418 bb->Set_loc_mu_wn( NULL );
01419 bb->Set_last_stid_bitpos( ILLEGAL_BP );
01420 bb->Set_last_stid_has_chi( FALSE );
01421
01422
01423 bb->Set_rvi_anns( NULL );
01424
01425 WN *first = bb->Firststmt();
01426
01427 if ( first == NULL ) {
01428
01429 }
01430 else {
01431 STMT_ITER stmt_iter;
01432 WN *wn;
01433 FOR_ALL_ELEM( wn, stmt_iter, Init(bb->Firststmt(),bb->Laststmt()) ){
01434 BOOL is_lda;
01435 Get_wn_local_lda_attributes( bb, wn, &is_lda );
01436 Is_True( !is_lda,
01437 ("RVI::Get_bb_local_lda_attributes: statement can't be LDA") );
01438 }
01439
01440
01441 if ( bb->Hascall() && bb->Loc_mu_wn() == NULL ) {
01442 bb->Set_loc_mu_wn( bb->Laststmt() );
01443 }
01444 }
01445
01446
01447 if ( Tracing() ) {
01448 fprintf( TFile, "BB:%d Loc_appear: ", bb->Id() );
01449 bb->Loc_appear()->Print(TFile);
01450 fprintf( TFile, "\n" );
01451 }
01452 }
01453
01454
01455
01456
01457
01458 void
01459 RVI::Get_local_attributes( BOOL just_lda )
01460 {
01461 CFG_ITER cfg_iter(Cfg());
01462
01463 if ( ! just_lda ) {
01464 BB_NODE *bb;
01465 FOR_ALL_NODE( bb, cfg_iter, Init() ) {
01466 Get_bb_local_attributes( bb );
01467 }
01468 }
01469 else {
01470
01471 BB_NODE *bb;
01472 FOR_ALL_NODE( bb, cfg_iter, Init() ) {
01473 Get_bb_local_lda_attributes( bb );
01474 }
01475 }
01476 }
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487 void
01488 RVI::Get_forward_dataflow( void )
01489 {
01490 IDX_32_SET save_set(Initial_set_size(), Rvi_lpool(), OPTS_FALSE);
01491
01492 BOOL changed;
01493 do {
01494 changed = FALSE;
01495
01496 for ( INT bbi = 0; bbi < Dfs_vec_size(); bbi++ ) {
01497 BB_NODE *bb = Dfs_vec(bbi);
01498 BB_LIST_ITER bb_pred_iter;
01499 BB_NODE *pred;
01500
01501 if ( ! changed )
01502 save_set.CopyD( bb->Defreach() );
01503
01504 FOR_ALL_ELEM( pred, bb_pred_iter, Init(bb->Pred()) ) {
01505 IDX_32_SET *chi_set = Has_end_chi_list(pred) ?
01506 Bb_end_chi_list(pred) : NULL;
01507 if ( chi_set != NULL ) {
01508
01509 bb->Defreach()->Bs_2_3_Minus_1_Or_D( pred->Defreach(), chi_set );
01510 }
01511 else {
01512
01513 bb->Defreach()->UnionD( pred->Defreach() );
01514 }
01515 }
01516
01517 if ( ! changed )
01518 changed = ! save_set.EqualP( bb->Defreach() );
01519 }
01520 } while ( changed );
01521
01522
01523
01524
01525
01526
01527 IDX_32_SET temp_set(Initial_set_size(), Rvi_lpool(), OPTS_FALSE);
01528 do {
01529 changed = FALSE;
01530
01531 for ( INT bbi = 0; bbi < Dfs_vec_size(); bbi++ ) {
01532 BB_NODE *bb = Dfs_vec(bbi);
01533 BB_LIST_ITER bb_pred_iter;
01534 BB_NODE *pred;
01535
01536 if ( ! changed )
01537 save_set.CopyD( bb->Unstored_defs() );
01538
01539
01540
01541 FOR_ALL_ELEM( pred, bb_pred_iter, Init(bb->Pred()) ) {
01542 temp_set.CopyD( pred->Unstored_defs() );
01543
01544 IDX_32_SET *pred_mu = Bb_end_mu_list(pred);
01545 if ( pred_mu != NULL )
01546 temp_set.DifferenceD( pred_mu );
01547
01548 IDX_32_SET *pred_chi = Bb_end_chi_list(pred);
01549 if ( pred_chi != NULL )
01550 temp_set.DifferenceD( pred_chi );
01551
01552 if ( pred->Last_stid_bitpos() != ILLEGAL_BP &&
01553 ! pred->Last_stid_has_chi() )
01554 temp_set.Union1D( pred->Last_stid_bitpos() );
01555
01556 bb->Unstored_defs()->UnionD( &temp_set );
01557 }
01558
01559 if ( ! changed )
01560 changed = ! save_set.EqualP( bb->Unstored_defs() );
01561 }
01562 } while ( changed );
01563 }
01564
01565
01566
01567
01568
01569
01570
01571
01572 void
01573 RVI::Get_backward_dataflow( void )
01574 {
01575 IDX_32_SET save_set(Initial_set_size(), Rvi_lpool(), OPTS_FALSE);
01576 BB_NODE_SET bb_set(Cfg()->Total_bb_count(), Cfg(), Rvi_lpool(), BBNS_EMPTY);
01577
01578
01579
01580
01581 INT bbi;
01582 for (bbi = 0; bbi < Dfs_vec_size(); bbi++ ) {
01583 BB_NODE *bb = Dfs_vec(bbi);
01584 BB_LIST_ITER bb_succ_iter;
01585 BB_NODE *succ;
01586
01587
01588 IDX_32_SET *chi_set = Has_end_chi_list(bb) ?
01589 Bb_end_chi_list(bb) : NULL;
01590
01591 IDX_32_SET *mu_set = Has_end_mu_list(bb) ?
01592 Bb_end_mu_list(bb) : NULL;
01593
01594 if ( mu_set != NULL ) {
01595 FOR_ALL_ELEM( succ, bb_succ_iter, Init(bb->Succ()) ) {
01596
01597
01598 if ( chi_set != NULL ) {
01599 bb->Live_at_exit()->Bs_2_3_Minus_1_Or_D( succ->Loc_upwd(),
01600 chi_set );
01601 }
01602 else {
01603 bb->Live_at_exit()->UnionD( succ->Loc_upwd() );
01604 }
01605
01606 IDX_32_SET *succ_mu_set = Has_end_mu_list(succ) ?
01607 Bb_end_mu_list(succ) : NULL;
01608 if ( succ_mu_set != NULL ) {
01609
01610
01611 bb->Live_out()->Bs_3_2_Minus_4_Or_5_Or_1_Or_D(succ->Loc_def(),
01612 succ_mu_set, mu_set, succ->Loc_upwd() );
01613 }
01614 else {
01615
01616
01617 bb->Live_out()->Bs_2_3_Or_1_Or_D(succ->Loc_upwd(),mu_set);
01618 }
01619 }
01620 }
01621 else {
01622
01623
01624 FOR_ALL_ELEM( succ, bb_succ_iter, Init(bb->Succ()) ) {
01625 bb->Live_at_exit()->UnionD( succ->Loc_upwd() );
01626
01627 IDX_32_SET *succ_mu_set = Has_end_mu_list(succ) ?
01628 Bb_end_mu_list(succ) : NULL;
01629 if ( succ_mu_set != NULL ) {
01630
01631
01632 bb->Live_out()->Bs_3_2_Minus_4_Or_1_Or_D( succ->Loc_def(),
01633 succ_mu_set, succ->Loc_upwd() );
01634 }
01635 else {
01636
01637
01638 bb->Live_out()->UnionD( succ->Loc_upwd() );
01639 }
01640 }
01641 }
01642
01643
01644
01645 if ( Is_exit_block(bb) ) {
01646 const IDX_32_SET *global_vars = Global_vars(bb);
01647 if ( global_vars != NULL ) {
01648 bb->Live_out()->UnionD( global_vars );
01649 }
01650 }
01651 }
01652
01653 if ( Tracing() ) {
01654 for ( INT bbi = 0; bbi < Dfs_vec_size(); bbi++ ) {
01655 BB_NODE *bb = Dfs_vec(bbi);
01656 fprintf( TFile, "<RVI::Get_backward_dataflow: bb:%d init l-a-e: ",
01657 bb->Id() );
01658 bb->Live_at_exit()->Print( TFile );
01659 fprintf( TFile, "\n" );
01660 fprintf( TFile, "<RVI::Get_backward_dataflow: bb:%d init live-out:",
01661 bb->Id() );
01662 bb->Live_out()->Print( TFile );
01663 fprintf( TFile, "\n" );
01664 }
01665 }
01666
01667
01668
01669
01670 BOOL changed;
01671 do {
01672 changed = FALSE;
01673
01674 for ( bbi = Dfs_vec_size()-1; bbi >= 0; bbi-- ) {
01675 BB_NODE *bb = Dfs_vec(bbi);
01676 BB_LIST_ITER bb_succ_iter;
01677 BB_NODE *succ;
01678
01679 if ( ! changed )
01680 save_set.CopyD( bb->Live_at_exit() );
01681
01682
01683 IDX_32_SET *chi_set = Has_end_chi_list(bb) ?
01684 Bb_end_chi_list(bb) : NULL;
01685
01686 if ( chi_set == NULL ) {
01687 FOR_ALL_ELEM( succ, bb_succ_iter, Init(bb->Succ()) ) {
01688
01689 bb->Live_at_exit()->Bs_2_3_Minus_1_Or_D( succ->Live_at_exit(),
01690 succ->Loc_def() );
01691 }
01692 }
01693 else {
01694 FOR_ALL_ELEM( succ, bb_succ_iter, Init(bb->Succ()) ) {
01695
01696
01697 bb->Live_at_exit()->Bs_2_3_Minus_4_Minus_1_Or_D(
01698 succ->Live_at_exit(),
01699 succ->Loc_def(), chi_set );
01700 }
01701 }
01702
01703 if ( ! changed )
01704 changed = ! save_set.EqualP( bb->Live_at_exit() );
01705 }
01706 } while ( changed );
01707
01708
01709
01710
01711 do {
01712 changed = FALSE;
01713
01714 for ( bbi = Dfs_vec_size()-1; bbi >= 0; bbi-- ) {
01715 BB_NODE *bb = Dfs_vec(bbi);
01716 BB_LIST_ITER bb_succ_iter;
01717 BB_NODE *succ;
01718
01719 if ( ! changed )
01720 save_set.CopyD( bb->Live_out() );
01721
01722 FOR_ALL_ELEM( succ, bb_succ_iter, Init(bb->Succ()) ) {
01723
01724 bb->Live_out()->Bs_2_3_Minus_1_Or_D( succ->Live_out(),
01725 succ->Loc_def() );
01726 }
01727
01728 if ( ! changed )
01729 changed = ! save_set.EqualP( bb->Live_out() );
01730 }
01731 } while ( changed );
01732
01733 }
01734
01735
01736
01737
01738
01739 void
01740 RVI::Get_dataflow_equations( void )
01741 {
01742 INT bbi;
01743 for ( bbi = 0; bbi < Dfs_vec_size(); bbi++ ) {
01744 BB_NODE *bb = Dfs_vec(bbi);
01745
01746
01747
01748 Resize_sets( bb, Initial_set_size() );
01749
01750
01751
01752
01753
01754 bb->Set_defreach( CXX_NEW(IDX_32_SET(Initial_set_size(),
01755 Rvi_ppool(), OPTS_DONT_CARE), Rvi_ppool()));
01756 bb->Defreach()->CopyD( bb->Loc_appear() );
01757
01758
01759 bb->Set_live_at_exit( CXX_NEW(IDX_32_SET(Initial_set_size(),
01760 Rvi_ppool(), OPTS_DONT_CARE), Rvi_ppool()));
01761 bb->Live_at_exit()->CopyD( bb->Loc_appear() );
01762
01763
01764 bb->Set_live_out( CXX_NEW(IDX_32_SET(Initial_set_size(),
01765 Rvi_ppool(), OPTS_FALSE), Rvi_ppool()));
01766 }
01767
01768 Get_forward_dataflow();
01769 Get_backward_dataflow();
01770
01771 if ( Tracing() ) {
01772 for ( INT bbi = 0; bbi < Dfs_vec_size(); bbi++ ) {
01773 BB_NODE *bb = Dfs_vec(bbi);
01774
01775 fprintf ( TFile, "BB:%d Defreach: ", bb->Id() );
01776 bb->Defreach()->Print(TFile);
01777 fprintf ( TFile, "\n" );
01778 fprintf ( TFile, "BB:%d Live_at_exit: ", bb->Id() );
01779 bb->Live_at_exit()->Print(TFile);
01780 fprintf ( TFile, "\n" );
01781 fprintf ( TFile, "BB:%d Live_out: ", bb->Id() );
01782 bb->Live_out()->Print(TFile);
01783 fprintf ( TFile, "\n" );
01784 fprintf ( TFile, "BB:%d Unstored_defs: ", bb->Id() );
01785 bb->Unstored_defs()->Print(TFile);
01786 fprintf ( TFile, "\n" );
01787 }
01788 }
01789
01790
01791
01792 for ( bbi = 0; bbi < Dfs_vec_size(); bbi++ ) {
01793 BB_NODE *bb = Dfs_vec(bbi);
01794 bb->Defreach()->IntersectionD( bb->Live_at_exit() );
01795
01796 if ( Tracing() ) {
01797 fprintf ( TFile, "BB:%d Live-range (defreach): ", bb->Id() );
01798 bb->Defreach()->Print(TFile);
01799 fprintf ( TFile, "\n" );
01800 }
01801 }
01802
01803 }
01804
01805
01806
01807
01808
01809
01810
01811
01812 void
01813 RVI::Get_forward_lda_dataflow( void )
01814 {
01815 IDX_32_SET save_set(Initial_set_size(), Rvi_lpool(), OPTS_FALSE);
01816
01817 BOOL changed;
01818 do {
01819 changed = FALSE;
01820
01821 for ( INT bbi = 0; bbi < Dfs_vec_size(); bbi++ ) {
01822 BB_NODE *bb = Dfs_vec(bbi);
01823 BB_LIST_ITER bb_pred_iter;
01824 BB_NODE *pred;
01825
01826 if ( ! changed )
01827 save_set.CopyD( bb->Defreach() );
01828
01829 FOR_ALL_ELEM( pred, bb_pred_iter, Init(bb->Pred()) ) {
01830
01831 bb->Defreach()->UnionD( pred->Defreach() );
01832 }
01833
01834 if ( ! changed )
01835 changed = ! save_set.EqualP( bb->Defreach() );
01836 }
01837 } while ( changed );
01838 }
01839
01840
01841
01842
01843
01844
01845
01846 void
01847 RVI::Get_backward_lda_dataflow( void )
01848 {
01849 IDX_32_SET save_set(Initial_set_size(), Rvi_lpool(), OPTS_FALSE);
01850
01851
01852 INT bbi;
01853 for ( bbi = 0; bbi < Dfs_vec_size(); bbi++ ) {
01854 BB_NODE *bb = Dfs_vec(bbi);
01855 BB_LIST_ITER bb_succ_iter;
01856 BB_NODE *succ;
01857
01858 FOR_ALL_ELEM( succ, bb_succ_iter, Init(bb->Succ()) ) {
01859 bb->Live_at_exit()->UnionD( succ->Loc_appear() );
01860 }
01861 }
01862
01863 if ( Tracing() ) {
01864 for ( INT bbi = 0; bbi < Dfs_vec_size(); bbi++ ) {
01865 BB_NODE *bb = Dfs_vec(bbi);
01866 fprintf( TFile, "<RVI::Get_backward_dataflow: init l-a-e:bb:%d:",
01867 bb->Id() );
01868 bb->Live_at_exit()->Print( TFile );
01869 fprintf( TFile, "\n" );
01870 }
01871 }
01872
01873
01874 BOOL changed;
01875 do {
01876 changed = FALSE;
01877
01878 for ( bbi = Dfs_vec_size()-1; bbi >= 0; bbi-- ) {
01879 BB_NODE *bb = Dfs_vec(bbi);
01880 BB_LIST_ITER bb_succ_iter;
01881 BB_NODE *succ;
01882
01883 if ( ! changed )
01884 save_set.CopyD( bb->Live_at_exit() );
01885
01886 FOR_ALL_ELEM( succ, bb_succ_iter, Init(bb->Succ()) ) {
01887
01888 bb->Live_at_exit()->UnionD( succ->Live_at_exit() );
01889 }
01890
01891 if ( ! changed )
01892 changed = ! save_set.EqualP( bb->Live_at_exit() );
01893 }
01894 } while ( changed );
01895
01896 }
01897
01898
01899
01900
01901
01902 void
01903 RVI::Get_lda_dataflow_equations( void )
01904 {
01905 INT bbi;
01906 for ( bbi = 0; bbi < Dfs_vec_size(); bbi++ ) {
01907 BB_NODE *bb = Dfs_vec(bbi);
01908
01909
01910
01911
01912
01913 bb->Set_defreach( CXX_NEW(IDX_32_SET(Initial_set_size(),
01914 Rvi_ppool(), OPTS_DONT_CARE), Rvi_ppool()));
01915 bb->Defreach()->CopyD( bb->Loc_appear() );
01916
01917
01918 bb->Set_live_at_exit( CXX_NEW(IDX_32_SET(Initial_set_size(),
01919 Rvi_ppool(), OPTS_DONT_CARE), Rvi_ppool()));
01920 bb->Live_at_exit()->CopyD( bb->Loc_appear() );
01921
01922 bb->Set_live_out( NULL );
01923 }
01924
01925 Get_forward_lda_dataflow();
01926 Get_backward_lda_dataflow();
01927
01928 if ( Tracing() ) {
01929 for ( INT bbi = 0; bbi < Dfs_vec_size(); bbi++ ) {
01930 BB_NODE *bb = Dfs_vec(bbi);
01931
01932 fprintf ( TFile, "BB:%d Defreach: ", bb->Id() );
01933 bb->Defreach()->Print(TFile);
01934 fprintf ( TFile, "\n" );
01935 fprintf ( TFile, "BB:%d Live_at_exit: ", bb->Id() );
01936 bb->Live_at_exit()->Print(TFile);
01937 fprintf ( TFile, "\n" );
01938 }
01939 }
01940
01941
01942
01943 for ( bbi = 0; bbi < Dfs_vec_size(); bbi++ ) {
01944 BB_NODE *bb = Dfs_vec(bbi);
01945 bb->Defreach()->IntersectionD( bb->Live_at_exit() );
01946
01947 if ( Tracing() ) {
01948 fprintf ( TFile, "BB:%d Live-range (defreach): ", bb->Id() );
01949 bb->Defreach()->Print(TFile);
01950 fprintf ( TFile, "\n" );
01951 }
01952 }
01953
01954 }
01955
01956
01957
01958
01959
01960
01961 void
01962 RVI::Perform_variable_constant_rvi( RVI_NODE *rvi_node )
01963 {
01964 OPT_POOL_Push( Rvi_lpool(), RVI_TRACE_FLAG+6 );
01965 Build_live_ranges( rvi_node, Rvi_lpool() );
01966
01967 INT32 home_preg = 0;
01968
01969 RVI_LR_ITER lr_iter;
01970 RVI_LR *lr;
01971 FOR_ALL_NODE( lr, lr_iter, Init( rvi_node->Live_ranges() ) ) {
01972 Analyze_live_range( lr );
01973
01974 if ( Tracing() ) {
01975 fprintf( TFile, "After Analyze_live_range for rvi_node\n" );
01976 lr->Print( TFile );
01977 }
01978
01979
01980 if ( lr->Replace_anything() ) {
01981
01982
01983 if ( lr->Need_home() || !Unique_pregs() ) {
01984
01985 if ( home_preg == 0 ) {
01986 home_preg = Create_Preg(rvi_node->Mtype(), rvi_node->Name(),
01987 rvi_node->New_home_wn( Alias_Mgr() ) );
01988 }
01989
01990 lr->Set_preg( home_preg );
01991 }
01992 else {
01993
01994 lr->Set_preg( Create_Preg(rvi_node->Mtype(), rvi_node->Name(),
01995 rvi_node->New_home_wn( Alias_Mgr() ) ) );
01996 }
01997
01998 Insert_loads_stores( lr, rvi_node );
01999
02000 if ( Tracing() ) {
02001 fprintf( TFile, "After Insert_loads_stores for rvi_node\n" );
02002 lr->Print( TFile );
02003 }
02004 }
02005
02006 }
02007
02008 OPT_POOL_Pop( Rvi_lpool(), RVI_TRACE_FLAG+6 );
02009 }
02010
02011
02012
02013
02014
02015 void
02016 RVI::Perform_variable_rvi( void )
02017 {
02018 RVI_VTAB_ITER vtab_iter;
02019 RVI_NODE *rvi_node;
02020 FOR_ALL_NODE( rvi_node, vtab_iter, Init( Rvi_vtab() ) ) {
02021 if ( Tracing() ) {
02022 fprintf( TFile, "Perform_variable_rvi: " );
02023 rvi_node->Print( TFile );
02024 }
02025
02026
02027 if ( WOPT_Enable_Rviskip != NULL ) {
02028 char *name = NULL;
02029 if ( rvi_node->Loadwn() ) {
02030 name = ST_name(WN_st(rvi_node->Loadwn()));
02031 }
02032 else if ( rvi_node->Storewn() ) {
02033 name = ST_name(WN_st(rvi_node->Storewn()));
02034 }
02035
02036 if ( name && strcmp(WOPT_Enable_Rviskip,name) == 0 ) {
02037 DevWarn( "RVI skip variable %s", name );
02038 if ( Tracing() ) {
02039 fprintf( TFile, " SKIP: rvskip'd variable\n" );
02040 }
02041 continue;
02042 }
02043 }
02044
02045
02046 if ( Volatile_set()->MemberP(rvi_node->Bitpos()) ) {
02047 if ( Tracing() ) {
02048 fprintf( TFile, " SKIP: Is_volatile\n" );
02049 }
02050 continue;
02051 }
02052
02053
02054 if (Cfg()->Fake_entry_bb()) {
02055 if (ST_sclass(rvi_node->St()) == SCLASS_FORMAL_REF) {
02056 if ( Tracing() ) {
02057 fprintf( TFile, " SKIP: multi-entry point parameter %s\n", rvi_node->Name() );
02058 }
02059 continue;
02060 }
02061 }
02062
02063 Is_True(!rvi_node->Is_volatile(), ("RVI::Perform_variable_rvi: Find volatile rvi_node."));
02064
02065 Perform_variable_constant_rvi( rvi_node );
02066 }
02067 }
02068
02069
02070
02071
02072
02073 void
02074 RVI::Perform_constant_rvi( void )
02075 {
02076 RVI_CTAB_ITER ctab_iter;
02077 RVI_NODE *rvi_node;
02078
02079 FOR_ALL_NODE( rvi_node, ctab_iter, Init(Rvi_ctab()) ) {
02080
02081 if ( Tracing() ) {
02082 fprintf( TFile, "Perform_constant_rvi: " );
02083 rvi_node->Print( TFile );
02084 }
02085
02086 Perform_variable_constant_rvi( rvi_node );
02087 }
02088 }
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100 void
02101 PRE_RVI_HOOKS::Setup_bitpos(OPT_STAB *opt_stab,
02102 CODEREP *cr)
02103 {
02104 if (opt_stab->Aux_stab_entry(cr->Aux_id())->Itab_bitpos() ==
02105 ILLEGAL_BP) {
02106 Is_Trace(Tracing(), (TFile, "Setup_bitpos: assigning bitpos %d "
02107 "to aux_id %d\n", Nbits(),
02108 cr->Aux_id()));
02109
02110 opt_stab->Set_itab_bitpos(cr->Aux_id(), Nbits());
02111 Inc_nbits();
02112 }
02113 else {
02114 Is_Trace(Tracing(),
02115 (TFile, "Setup_bitpos: Aux id %d already has bitpos %d\n",
02116 cr->Aux_id(),
02117 opt_stab->Aux_stab_entry(cr->Aux_id())->Itab_bitpos()));
02118 }
02119 Is_Trace_cmd(Tracing(), cr->Print(1, TFile));
02120 Is_Trace(Tracing(),
02121 (TFile, " ^^^ coderep assigned bitpos %d\n",
02122 opt_stab->Aux_stab_entry(cr->Aux_id())->Itab_bitpos()));
02123
02124 cr->Set_Bitpos(opt_stab->Aux_stab_entry(cr->Aux_id())->Itab_bitpos());
02125 }
02126
02127
02128
02129
02130 PRE_RVI_HOOKS::PRE_RVI_HOOKS(OPT_STAB *opt_stab,
02131 CFG *cfg,
02132 MEM_POOL *pool,
02133 BOOL tracing) : _tracing(tracing)
02134 {
02135 CFG_ITER bb_iter;
02136 BB_NODE *bb;
02137
02138 opt_stab->Clear_itab_bitpos();
02139
02140 _nbits = 0;
02141
02142 OPT_POOL_Push(pool, RVI_TRACE_FLAG+7);
02143
02144 FOR_ALL_ELEM(bb, bb_iter, Init(cfg)) {
02145 STMTREP_ITER stmt_iter(bb->Stmtlist());
02146 STMTREP *stmt;
02147
02148 FOR_ALL_NODE(stmt, stmt_iter, Init()) {
02149 LEAF_ITER<CODEREP> leaf_iter(pool, Tracing());
02150 CODEREP *leaf;
02151
02152 if (stmt->Lhs() != NULL) {
02153 FOR_ALL_NODE(leaf, leaf_iter, Init(stmt->Lhs())) {
02154 if (leaf->Kind() == CK_VAR) {
02155
02156 Setup_bitpos(opt_stab, leaf);
02157 }
02158 }
02159 }
02160 if (stmt->Rhs() != NULL) {
02161 FOR_ALL_NODE(leaf, leaf_iter, Init(stmt->Rhs())) {
02162 if (leaf->Kind() == CK_VAR) {
02163
02164 Setup_bitpos(opt_stab, leaf);
02165 }
02166 }
02167 }
02168 }
02169 }
02170
02171 OPT_POOL_Pop(pool, RVI_TRACE_FLAG+7);
02172
02173 opt_stab->Rename_aux_id_list_to_bitpos();
02174 }