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 #ifdef USE_PCH
00059 #include "opt_pch.h"
00060 #endif // USE_PCH
00061 #pragma hdrstop
00062
00063
00064 #ifdef _KEEP_RCS_ID
00065 #define opt_du_CXX "opt_du.cxx"
00066 static char *rcs_id = opt_du_CXX"$Revision$";
00067 #endif
00068
00069 #include "defs.h"
00070 #include "tracing.h"
00071 #include "errors.h"
00072 #include "erglob.h"
00073 #include "wn_util.h"
00074 #include "ir_reader.h"
00075
00076 #include "opt_base.h"
00077 #include "opt_config.h"
00078 #include "cxx_memory.h"
00079 #include "opt_du.h"
00080 #include "opt_emit.h"
00081 #include "opt_htable.h"
00082 #include "opt_ssa.h"
00083 #include "opt_mu_chi.h"
00084 #include "opt_util.h"
00085 #include "opt_cfg.h"
00086 #include "bb_node_set.h"
00087
00088 #ifdef Is_True_On
00089
00090 #include "optimizer.h"
00091 #endif
00092
00093
00094
00095 static mINT16 DU_Phi_Ctr = 0;
00096
00097
00098
00099
00100
00101 void
00102 DU_NODE::Print(FILE *fp) const
00103 {
00104
00105 fprintf(fp, "<%d:%d> ", OPCODE_mapcat(WN_opcode(_wn)), WN_map_id(_wn));
00106 }
00107
00108 void
00109 DEF_LIST::Print(FILE *fp)
00110 {
00111 if ( Incomplete() )
00112 fprintf( fp, "(Incomplete) " );
00113
00114
00115 DEF_LIST_ITER def_lst_iter;
00116 const DU_NODE *tmp;
00117 FOR_ALL_NODE(tmp, def_lst_iter, Init(this))
00118 tmp->Print(fp);
00119 }
00120
00121 void
00122 USE_LIST::Print(FILE *fp)
00123 {
00124 if ( Incomplete() )
00125 fprintf( fp, "(Incomplete) " );
00126
00127
00128 USE_LIST_ITER use_lst_iter;
00129 const DU_NODE *tmp;
00130 FOR_ALL_NODE(tmp, use_lst_iter, Init(this))
00131 tmp->Print(fp);
00132 }
00133
00134 void
00135 DU_MANAGER::Print_Du(WN *def, FILE *fp)
00136 {
00137 fprintf(fp, "D-U <%d:%d> -> ",
00138 OPCODE_mapcat(WN_opcode(def)), WN_map_id(def));
00139 USE_LIST *use_list = Du_Get_Use(def);
00140 if ( use_list != NULL ) {
00141 use_list->Print(fp);
00142 }
00143 fprintf( fp, "def:" );
00144 fdump_wn(fp, def);
00145 }
00146
00147 void
00148 DU_MANAGER::Print_Ud(WN *use, FILE *fp)
00149 {
00150 fprintf(fp, "U-D <%d:%d> -> ",
00151 OPCODE_mapcat(WN_opcode(use)), WN_map_id(use));
00152 DEF_LIST *def_list = Ud_Get_Def(use);
00153 if ( def_list != NULL )
00154 def_list->Print(fp);
00155 if (! OPERATOR_is_scalar_iload (WN_operator(use))) {
00156 if ( def_list != NULL && def_list->Loop_stmt() ) {
00157 fprintf(fp," Loop_stmt:");
00158
00159 }
00160 }
00161 fprintf(fp, "\n");
00162 }
00163
00164 #ifdef Is_True_On
00165 void
00166 DU_MANAGER::Print_Du_Info(FILE *fp)
00167 {
00168 BOOL save_IR_dmi = IR_dump_map_info;
00169 IR_dump_map_info = TRUE;
00170
00171
00172
00173
00174
00175 for (WN_ITER* wni = WN_WALK_TreeIter(Entry_Wn());
00176 wni != NULL;
00177 wni = WN_WALK_TreeNext(wni)) {
00178 USE_LIST *use_list = Du_Get_Use(WN_ITER_wn(wni));
00179
00180 if (use_list != NULL) {
00181 use_list->Print(fp);
00182 fflush(fp);
00183 fprintf(fp, "def: ");
00184 fdump_wn(fp, WN_ITER_wn(wni));
00185 fflush(fp);
00186 }
00187 }
00188
00189 IR_dump_map_info = save_IR_dmi;
00190 }
00191 #endif
00192
00193
00194
00195
00196
00197 BOOL
00198 USE_LIST::Contains( const WN *wn )
00199 {
00200 USE_LIST_ITER use_lst_iter;
00201 const DU_NODE *tmp;
00202 FOR_ALL_NODE( tmp, use_lst_iter, Init(this) ) {
00203 if ( tmp->Wn() == wn )
00204 return TRUE;
00205 }
00206
00207 return FALSE;
00208 }
00209
00210 BOOL
00211 DEF_LIST::Contains( const WN *wn )
00212 {
00213 DEF_LIST_ITER def_lst_iter;
00214 const DU_NODE *tmp;
00215 FOR_ALL_NODE( tmp, def_lst_iter, Init(this) ) {
00216 if ( tmp->Wn() == wn )
00217 return TRUE;
00218 }
00219
00220 return FALSE;
00221 }
00222
00223
00224
00225
00226
00227 void
00228 EMITTER::Connect_cr_wn( CODEREP *cr, WN *wn )
00229 {
00230
00231 WN_MAP_Set( _wn_to_cr_map, wn, cr );
00232 }
00233
00234 void
00235 EMITTER::Connect_sr_wn( STMTREP *sr, WN *wn )
00236 {
00237
00238 WN_MAP_Set( _wn_to_cr_map, wn, sr );
00239
00240
00241 if ( sr->Wn() == NULL ) {
00242 Is_True ( ! sr->Is_use_list(),
00243 ("EMITTER::Connect_sr_wn: null Wn() but Is_use_list") );
00244
00245 sr->Set_wn( wn );
00246 }
00247 else {
00248
00249
00250 if ( ! sr->Is_use_list() ) {
00251
00252 DU_NODE *old_use = CXX_NEW( DU_NODE(sr->Wn()), Mem_pool() );
00253
00254
00255 USE_LIST *use_list = CXX_NEW( USE_LIST(old_use,0), Mem_pool() );
00256 sr->Set_use_list(use_list);
00257 }
00258
00259
00260 DU_NODE *new_use = CXX_NEW( DU_NODE(wn), Mem_pool() );
00261 sr->Use_list()->Prepend(new_use);
00262 }
00263 }
00264
00265 void
00266 EMITTER::Duplicate_sr_cr_connections( WN *old_wn, WN *new_wn )
00267 {
00268 const OPCODE opc = WN_opcode(old_wn);
00269
00270 Is_True( opc == WN_opcode(new_wn),
00271 ("EMITTER::Duplicate_sr_cr_connections: trees don't match") );
00272
00273 void *vp = WN_MAP_Get( _wn_to_cr_map, old_wn );
00274 if ( vp != NULL ) {
00275 if ( OPCODE_is_stmt(opc) || OPCODE_is_scf(opc) ) {
00276
00277 Connect_sr_wn( (STMTREP*)vp, new_wn );
00278 }
00279 else {
00280
00281 Connect_cr_wn( (CODEREP*)vp, new_wn );
00282 }
00283 }
00284
00285 if ( opc == OPC_BLOCK ) {
00286 WN *old_bwn, *new_bwn;
00287 for ( old_bwn = WN_first(old_wn), new_bwn = WN_first(new_wn);
00288 old_bwn != NULL;
00289 old_bwn = WN_next(old_bwn), new_bwn = WN_next(new_bwn) )
00290 {
00291 Duplicate_sr_cr_connections( old_bwn, new_bwn );
00292 }
00293 }
00294 else {
00295 for ( INT ikid = 0; ikid < WN_kid_count(old_wn); ikid++ ) {
00296 Duplicate_sr_cr_connections( WN_kid(old_wn,ikid),
00297 WN_kid(new_wn,ikid) );
00298 }
00299 }
00300 }
00301
00302
00303
00304 void DU_MANAGER::Set_value_restored(WN *def)
00305 {
00306 if (_val_restored_map == WN_MAP_UNDEFINED)
00307 _val_restored_map = WN_MAP32_Create(&_mem_pool);
00308 Is_True(OPERATOR_is_scalar_store (WN_operator(def)),
00309 ("DU_MANAGER::Set_value_restored: not an assignment."));
00310 WN_MAP32_Set(_val_restored_map, def, TRUE);
00311 }
00312
00313
00314
00315
00316
00317 void
00318 DU_MANAGER::Set_alias_mgr(ALIAS_MANAGER *am)
00319 {
00320 _alias_mgr = am;
00321 }
00322
00323
00324 void
00325 DU_MANAGER::Ud_Add_Def(WN *use, WN *def)
00326 {
00327
00328 DEF_LIST *deflst = Ud_Get_Def(use);
00329
00330
00331 if ( deflst != NULL && deflst->Contains(def) )
00332 return;
00333
00334 DU_NODE *defnod = CXX_NEW(DU_NODE(def), &_mem_pool);
00335 if (deflst == NULL) {
00336 deflst = CXX_NEW( DEF_LIST(defnod,0), &_mem_pool);
00337 deflst->Set_loop_stmt(NULL);
00338 Ud_Put_Def(use, deflst);
00339 }
00340 else {
00341 deflst->Append(defnod);
00342 }
00343
00344 if ( Tracing() )
00345 Print_Ud(use, TFile);
00346
00347 #ifdef Is_True_On
00348
00349
00350 const OPCODE def_opc = WN_opcode(def);
00351 const OPCODE use_opc = WN_opcode(use);
00352 if ( (OPCODE_is_load(use_opc) || OPCODE_is_store(use_opc)) &&
00353 (OPCODE_is_load(def_opc) || OPCODE_is_store(def_opc)) )
00354 {
00355
00356
00357
00358 if (! OPERATOR_is_scalar_iload (WN_operator(use)) &&
00359 ! OPERATOR_is_scalar_istore (WN_operator(def)) &&
00360 WN_operator(use) != OPR_MLOAD && WN_operator(use) != OPR_MSTORE &&
00361 !OPCODE_is_stmt(WN_opcode(use)))
00362 {
00363 if (!Aliased(_alias_mgr, use, def)) {
00364 ErrMsg(EC_Development_Warning, "DU_MANAGER::Ud_Add_Def",
00365 "Use and Def are not aliased");
00366 dump_wn(def);
00367 dump_wn(use);
00368 }
00369 }
00370 }
00371 #endif // Is_True_On
00372
00373 }
00374
00375 void
00376 DU_MANAGER::Du_Add_Use(WN *def, WN *use)
00377 {
00378
00379 USE_LIST *uselst = Du_Get_Use(def);
00380
00381
00382 if ( uselst != NULL && uselst->Contains(use) )
00383 return;
00384
00385 DU_NODE *usenod = CXX_NEW(DU_NODE(use), &_mem_pool);
00386 if (uselst == NULL) {
00387 uselst = CXX_NEW(USE_LIST(usenod,0), &_mem_pool);
00388 Du_Put_Use(def, uselst);
00389 }
00390 else {
00391 uselst->Append(usenod);
00392 }
00393
00394 if ( Tracing() )
00395 Print_Du(def, TFile);
00396 }
00397
00398 void
00399 DU_MANAGER::Add_Def_Use( WN *def, WN *use )
00400 {
00401 if ((_opt_phase == PREOPT_PHASE || _opt_phase == PREOPT_LNO_PHASE ||
00402 _opt_phase == PREOPT_DUONLY_PHASE) &&
00403 OPERATOR_is_scalar_iload (WN_operator(use)) &&
00404 !OPERATOR_is_scalar_store (WN_operator(def)))
00405 return;
00406
00407
00408 Du_Add_Use( def, use );
00409 Ud_Add_Def( use, def );
00410 }
00411
00412 void
00413 DU_MANAGER::Ud_Delete_Def(WN *use, WN *def)
00414 {
00415
00416 DEF_LIST *deflist = Ud_Get_Def(use);
00417 DEF_LIST_ITER d_iter(deflist);
00418 DU_NODE *du_ptr=(DU_NODE *)d_iter.First();
00419 DU_NODE *du_ptr1=du_ptr;
00420 for (; !d_iter.Is_Empty(); du_ptr1=du_ptr,du_ptr=(DU_NODE *)d_iter.Next()) {
00421 if (du_ptr->Wn()==def)
00422 break;
00423 }
00424 if (d_iter.Is_Empty())
00425 return;
00426 else if (deflist->Head()->Wn()==def)
00427 deflist->Remove_Headnode();
00428 else
00429 deflist->Remove(du_ptr1,du_ptr);
00430 if ( Tracing() )
00431 Print_Ud(use, TFile);
00432 }
00433
00434 void
00435 DU_MANAGER::Du_Delete_Use(WN *def, WN *use)
00436 {
00437
00438 USE_LIST *uselist = Du_Get_Use(def);
00439 USE_LIST_ITER u_iter(uselist);
00440 DU_NODE *du_ptr=(DU_NODE *)u_iter.First();
00441 DU_NODE *du_ptr1=du_ptr;
00442 for (; !u_iter.Is_Empty(); du_ptr1=du_ptr,du_ptr=(DU_NODE *)u_iter.Next()) {
00443 if (du_ptr->Wn()==use)
00444 break;
00445 }
00446 if (u_iter.Is_Empty())
00447 return;
00448 else if (uselist->Head()->Wn()==use)
00449 uselist->Remove_Headnode();
00450 else
00451 uselist->Remove(du_ptr1,du_ptr);
00452 if ( Tracing() )
00453 Print_Du(def, TFile);
00454 }
00455
00456 void
00457 DU_MANAGER::Delete_Def_Use( WN *def, WN *use )
00458 {
00459
00460 Du_Delete_Use( def, use );
00461 Ud_Delete_Def( use, def );
00462 }
00463
00464
00465
00466 void DU_MANAGER::Remove_Use_From_System(WN *use)
00467 {
00468 DEF_LIST *defs = Ud_Get_Def(use);
00469 if (defs) {
00470 while (!defs->Is_Empty()) {
00471 DU_NODE *def_node = defs->Remove_Headnode();
00472 WN *def = def_node->Wn();
00473
00474
00475 USE_LIST *uses = Du_Get_Use(def);
00476 BOOL found = FALSE;
00477 if (uses) {
00478 USE_LIST_ITER uli(uses);
00479 DU_NODE *prev = NULL;
00480 for ( DU_NODE *use_node=uli.First(); !uli.Is_Empty();
00481 use_node = uli.Next())
00482 {
00483 if (use_node->Wn() == use) {
00484 CXX_DELETE(uses->Remove(prev,use_node),&_mem_pool);
00485 found = TRUE;
00486 break;
00487 }
00488 prev = use_node;
00489 }
00490 }
00491 Is_True(found,("Must be a backedge in Remove_Use_From_System\n"));
00492 }
00493 CXX_DELETE(defs,&_mem_pool);
00494 }
00495 WN_MAP_Set(_ud_map, use, NULL);
00496 }
00497
00498
00499 void DU_MANAGER::Remove_Def_From_System(WN *def)
00500 {
00501 USE_LIST *uses = Du_Get_Use(def);
00502 if (uses) {
00503 while (!uses->Is_Empty()) {
00504 DU_NODE *use_node = uses->Remove_Headnode();
00505 WN *use = use_node->Wn();
00506
00507
00508 BOOL found = FALSE;
00509 DEF_LIST *defs = Ud_Get_Def(use);
00510 if (defs) {
00511 DEF_LIST_ITER dli(defs);
00512 DU_NODE *prev = NULL;
00513 for (DU_NODE *def_node=dli.First(); !dli.Is_Empty();
00514 def_node = dli.Next()) {
00515 if (def_node->Wn() == def) {
00516 found = TRUE;
00517 CXX_DELETE(defs->Remove(prev,def_node),&_mem_pool);
00518 break;
00519 }
00520 prev = def_node;
00521 }
00522 }
00523 Is_True(found,("Must be a backedge in Remove_Def_From_System\n"));
00524 }
00525 CXX_DELETE(uses,&_mem_pool);
00526 }
00527 WN_MAP_Set(_du_map, def, NULL);
00528 }
00529
00530
00531
00532
00533
00534 void
00535 DU_MANAGER::Create_Def_List(WN *use)
00536 {
00537 if ( Ud_Get_Def(use) == NULL ) {
00538 DEF_LIST *def_list = CXX_NEW( DEF_LIST(NULL,0), &_mem_pool);
00539 Ud_Put_Def(use, def_list);
00540 }
00541 }
00542
00543 void
00544 DU_MANAGER::Create_Use_List(WN *def)
00545 {
00546 if ( Du_Get_Use(def) == NULL ) {
00547 USE_LIST *use_list = CXX_NEW( USE_LIST(NULL,0), &_mem_pool);
00548 Du_Put_Use(def, use_list);
00549 }
00550 }
00551
00552
00553
00554
00555
00556 void
00557 EMITTER::Add_defs_use( DU_MANAGER *du_mgr, STMTREP *defstmt, WN *use )
00558 {
00559 FmtAssert( defstmt->Wn() != NULL,
00560 ("EMITTER::Du_Add_Uses: no Wn for stmtrep") );
00561
00562
00563 if ( ! defstmt->Is_use_list() ) {
00564 du_mgr->Add_Def_Use( defstmt->Wn(), use );
00565 }
00566 else {
00567
00568 USE_LIST_ITER def_lst_iter;
00569 DU_NODE *du;
00570 FOR_ALL_NODE(du, def_lst_iter, Init(defstmt->Use_list())) {
00571 du_mgr->Add_Def_Use( du->Wn(), use );
00572 }
00573 }
00574 }
00575
00576
00577
00578
00579
00580
00581
00582 void
00583 DU_MANAGER::Du_Set_Incomplete( WN *def )
00584 {
00585
00586 USE_LIST *uselst = Du_Get_Use(def);
00587 if (uselst == NULL) {
00588
00589 uselst = CXX_NEW(USE_LIST(), &_mem_pool);
00590 uselst->Init();
00591 Du_Put_Use(def, uselst);
00592 }
00593 uselst->Set_Incomplete();
00594
00595 if ( Tracing() )
00596 Print_Du(def, TFile);
00597 }
00598
00599
00600
00601
00602
00603
00604 static void
00605 Set_Incomplete_Uses( DU_MANAGER *du_mgr, STMTREP *defstmt )
00606 {
00607 FmtAssert( defstmt->Wn() != NULL,
00608 ("Set_Incomplete_Uses: no Wn for stmtrep") );
00609
00610
00611 if ( ! defstmt->Is_use_list() ) {
00612 du_mgr->Du_Set_Incomplete( defstmt->Wn() );
00613 }
00614 else {
00615
00616 USE_LIST_ITER def_lst_iter;
00617 DU_NODE *du;
00618 FOR_ALL_NODE(du, def_lst_iter, Init(defstmt->Use_list())) {
00619 du_mgr->Du_Set_Incomplete( du->Wn() );
00620 }
00621 }
00622 }
00623
00624
00625
00626
00627
00628 static
00629 void Update_loop_info( DU_MANAGER *du_mgr, WN *wn, BB_NODE *wn_bb )
00630 {
00631
00632
00633 DEF_LIST *deflist = du_mgr->Ud_Get_Def(wn);
00634 if (deflist && deflist->Loop_info() != NULL) {
00635 if (deflist->Loop_info()->Contains( wn_bb->Innermost())) {
00636 deflist->Set_loop_stmt(deflist->Loop_info()->Loopstmt());
00637 if ( du_mgr->Tracing() && deflist->Loop_stmt() != NULL ) {
00638 fprintf( TFile, "Use WN:<%d:%d> has Loop_stmt WN:<%d:%d> %s\n",
00639 OPCODE_mapcat(WN_opcode(wn)),
00640 WN_map_id(wn),
00641 OPCODE_mapcat(WN_opcode(deflist->Loop_stmt())),
00642 WN_map_id(deflist->Loop_stmt()),
00643 OPCODE_name(WN_opcode(deflist->Loop_stmt())) );
00644 }
00645 }
00646 else
00647 deflist->Set_loop_stmt(NULL);
00648 }
00649 }
00650
00651
00652
00653
00654
00655
00656 void
00657 EMITTER::Compute_incomplete_defs( DU_MANAGER *du_mgr, CODEREP *cr )
00658 {
00659 if (cr->Kind() != CK_VAR)
00660 return;
00661
00662
00663
00664 BOOL is_real_var = du_mgr->Opt_Stab()->Is_real_var(cr->Aux_id());
00665 FmtAssert( is_real_var,
00666 ("Compute_incomplete_defs: should not see virtual variable") );
00667
00668 if (!cr->Is_var_nodef()) {
00669 if (cr->Is_flag_set(CF_DEF_BY_PHI)) {
00670
00671 PHI_NODE *phi = cr->Defphi();
00672
00673
00674 if ( phi->Live() && phi->Count() != DU_Phi_Ctr) {
00675
00676 phi->Set_count(DU_Phi_Ctr);
00677
00678 PHI_OPND_ITER phi_opnd_iter(phi);
00679 CODEREP *opnd;
00680 BOOL ignore_pregs = Opt_stab()->Is_virtual(phi->RESULT()->Aux_id());
00681 FOR_ALL_ELEM(opnd, phi_opnd_iter, Init()) {
00682 Is_True(opnd != NULL,
00683 ("EMITTER::Compute_incomplete_defs: null phi-opnd"));
00684
00685
00686
00687 if ( ! opnd->Is_flag_set(CF_IS_ZERO_VERSION) ) {
00688 Compute_incomplete_defs( du_mgr, opnd );
00689 }
00690 }
00691 }
00692 } else if (cr->Is_flag_set(CF_DEF_BY_CHI)) {
00693
00694
00695 } else {
00696
00697 STMTREP *defstmt = cr->Defstmt();
00698 if ( defstmt->Live_stmt() ) {
00699 if (OPERATOR_is_scalar_store (defstmt->Opr())) {
00700
00701
00702 Set_Incomplete_Uses( du_mgr, defstmt );
00703 }
00704 }
00705 }
00706 }
00707 }
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717 void
00718 EMITTER::Compute_use_def_zero_version_var( DU_MANAGER *du_mgr,
00719 CODEREP *cr, WN *wn, BB_NODE *bb, BB_NODE *wn_bb )
00720 {
00721 for ( ; bb != NULL; bb = bb->Idom() ) {
00722 STMTREP *stmt;
00723 STMTREP_ITER stmt_iter(bb->Stmtlist());
00724 FOR_ALL_NODE_REVERSE(stmt,stmt_iter,Init()) {
00725 const OPERATOR stmt_opr = stmt->Opr();
00726
00727 if (OPERATOR_is_scalar_store (stmt_opr)) {
00728 if ( stmt->Lhs()->Aux_id() == cr->Aux_id() ) {
00729
00730 Add_defs_use( du_mgr, stmt, wn );
00731 return;
00732 }
00733 }
00734
00735 if ( stmt->Has_chi() ) {
00736 CHI_LIST_ITER chi_iter;
00737 CHI_NODE *chi;
00738 FOR_ALL_NODE( chi, chi_iter, Init(stmt->Chi_list()) ) {
00739 if ( chi->Live() && chi->RESULT()->Aux_id() == cr->Aux_id() ) {
00740
00741
00742 Add_defs_use( du_mgr, stmt, wn );
00743
00744
00745 DEF_LIST *deflist = du_mgr->Ud_Get_Def(wn);
00746 deflist->Set_Incomplete();
00747
00748
00749
00750 Set_Incomplete_Uses( du_mgr, stmt );
00751
00752 if ( du_mgr->Tracing() ) {
00753 fprintf( TFile, "Compute_use_def_zero_version_var: "
00754 "found defstmt in BB:%d\n", bb->Id() );
00755 }
00756
00757 return;
00758 }
00759 }
00760 }
00761 }
00762
00763
00764 PHI_LIST_ITER phi_iter;
00765 PHI_NODE *phi;
00766 FOR_ALL_ELEM ( phi, phi_iter, Init(bb->Phi_list()) ) {
00767 if (!phi->Res_is_cr()) continue;
00768 if ( phi->Count() != DU_Phi_Ctr ) {
00769
00770
00771 phi->Set_count(DU_Phi_Ctr);
00772
00773 if ( phi->Live() && phi->RESULT()->Aux_id() == cr->Aux_id() ) {
00774
00775
00776
00777 PHI_OPND_ITER phi_opnd_iter(phi);
00778 CODEREP *opnd;
00779 BOOL ignore_pregs = Opt_stab()->Is_virtual(phi->RESULT()->Aux_id());
00780 FOR_ALL_ELEM(opnd, phi_opnd_iter, Init()) {
00781 if ( ! opnd->Is_flag_set(CF_IS_ZERO_VERSION) ) {
00782
00783
00784 Compute_use_def_var( du_mgr, opnd, wn, wn_bb );
00785 }
00786 else {
00787
00788 Compute_use_def_zero_version_var( du_mgr, opnd, wn,
00789 phi->Bb()->Nth_pred(phi_opnd_iter.Curidx()), wn_bb );
00790 }
00791 }
00792
00793
00794
00795 return;
00796 }
00797 }
00798 }
00799 }
00800
00801
00802
00803 if (OPERATOR_is_scalar_load (WN_operator(wn))) {
00804 du_mgr->Add_Def_Use( du_mgr->Entry_Wn(), wn );
00805
00806 DEF_LIST *deflist = du_mgr->Ud_Get_Def(wn);
00807 deflist->Set_Incomplete();
00808 }
00809 }
00810
00811
00812
00813
00814
00815
00816 void
00817 EMITTER::Compute_use_def_var( DU_MANAGER *du_mgr, CODEREP *cr, WN *wn,
00818 BB_NODE *wn_bb)
00819 {
00820 if (cr->Kind() != CK_VAR)
00821 return;
00822
00823
00824
00825
00826
00827 BOOL is_real_var = du_mgr->Opt_Stab()->Is_real_var(cr->Aux_id());
00828
00829 if ( !is_real_var && !Opt_stab()->Unique_vsym(cr->Aux_id())) {
00830
00831
00832 if (OPERATOR_is_scalar_load (WN_operator(wn))) {
00833 DEF_LIST *deflist = du_mgr->Ud_Get_Def(wn);
00834
00835
00836 Is_True( deflist != NULL,
00837 ("Compute_use_def_var: null deflist") );
00838 deflist->Set_Incomplete();
00839 }
00840 }
00841 else if ( cr->Is_flag_set(CF_IS_ZERO_VERSION) ) {
00842
00843
00844 FmtAssert( FALSE,
00845 ("EMITTER::Compute_use_def_var: cr is zero-version") );
00846 }
00847 else if (!cr->Is_var_nodef()) {
00848 if (cr->Is_flag_set(CF_DEF_BY_PHI)) {
00849
00850 PHI_NODE *phi = cr->Defphi();
00851
00852 if (! phi->Live())
00853 return;
00854
00855
00856 if (phi->Count() != DU_Phi_Ctr) {
00857
00858
00859 phi->Set_count(DU_Phi_Ctr);
00860
00861 PHI_OPND_ITER phi_opnd_iter(phi);
00862 CODEREP *opnd;
00863 BOOL ignore_pregs = Opt_stab()->Is_virtual(phi->RESULT()->Aux_id());
00864 FOR_ALL_ELEM(opnd, phi_opnd_iter, Init()) {
00865 Is_True(opnd != NULL,
00866 ("EMITTER::Compute_use_def_var: null phi-opnd"));
00867 FmtAssert(opnd->Kind() == CK_VAR,
00868 ("CODEREP::Compute_use_def: phi operand not a VAR"));
00869
00870 if ( ! opnd->Is_flag_set(CF_IS_ZERO_VERSION) ) {
00871 Compute_use_def_var( du_mgr, opnd, wn, wn_bb );
00872 }
00873 else {
00874
00875
00876 Compute_use_def_zero_version_var( du_mgr, opnd, wn,
00877 phi->Bb()->Nth_pred(phi_opnd_iter.Curidx()), wn_bb );
00878 }
00879
00880 }
00881
00882 BB_NODE *bb = phi->Bb();
00883 if ( (bb->Kind() == BB_DOEND || bb->Kind() == BB_WHILEEND)
00884 && bb->Loop() != NULL ) {
00885 DEF_LIST *deflst = du_mgr->Ud_Get_Def(wn);
00886
00887 if (deflst) {
00888 if (deflst->Loop_info() == NULL) {
00889 if (wn_bb && bb->Loop()->Contains( wn_bb->Innermost()))
00890 deflst->Set_loop_info(bb->Loop());
00891 }
00892 else {
00893 BB_LOOP *prev_loop = deflst->Loop_info();
00894 if ( bb->Loop()->Step()->Loopdepth() <
00895 prev_loop->Step()->Loopdepth() )
00896 {
00897 deflst->Set_loop_info(bb->Loop());
00898 }
00899 }
00900 }
00901 }
00902 }
00903 } else if (cr->Is_flag_set(CF_DEF_BY_CHI)) {
00904 STMTREP *defstmt = cr->Defstmt();
00905 CHI_NODE *chi = cr->Defchi();
00906
00907
00908 Add_defs_use( du_mgr, defstmt, wn );
00909
00910
00911 if ( defstmt->Opr() == OPR_OPT_CHI ) {
00912 Add_defs_use( du_mgr, defstmt, wn );
00913 }
00914
00915
00916
00917 else if ( WOPT_Enable_Zero_Version || ! WOPT_Enable_DU_Full ) {
00918
00919
00920 DEF_LIST *deflist = du_mgr->Ud_Get_Def(wn);
00921 deflist->Set_Incomplete();
00922 }
00923 else {
00924 if ( chi->Live() ) {
00925 Compute_use_def_var( du_mgr, chi->OPND(), wn, wn_bb );
00926 }
00927 }
00928 } else {
00929
00930 STMTREP *defstmt = cr->Defstmt();
00931 if (OPERATOR_is_scalar_load (WN_operator(wn)) ||
00932 OPERATOR_is_scalar_store (defstmt->Opr()))
00933 {
00934 Add_defs_use( du_mgr, defstmt, wn );
00935 }
00936 }
00937 }
00938 else {
00939
00940 if (OPERATOR_is_scalar_load (WN_operator (wn))) {
00941 du_mgr->Add_Def_Use( du_mgr->Entry_Wn(), wn );
00942 }
00943 }
00944 }
00945
00946
00947
00948
00949
00950 void
00951 EMITTER::Compute_use_def_expr( DU_MANAGER *du_mgr, WN *wn,
00952 BB_NODE *wn_bb )
00953 {
00954 const OPERATOR opr = WN_operator(wn);
00955 CODEREP *cr = (CODEREP*)WN_MAP_Get( _wn_to_cr_map, wn );
00956
00957 switch ( opr ) {
00958
00959 case OPR_LDID:
00960 case OPR_LDBITS:
00961 DU_Phi_Ctr++;
00962 Compute_use_def_var( du_mgr, cr, wn, wn_bb );
00963
00964
00965
00966 Update_loop_info( du_mgr, wn, wn_bb );
00967 break;
00968
00969 default:
00970 for ( INT ikid = 0; ikid < WN_kid_count(wn); ikid++ ) {
00971 Compute_use_def_expr( du_mgr, WN_kid(wn,ikid), wn_bb );
00972 }
00973 break;
00974 }
00975
00976
00977 if ( cr && cr->Kind() == CK_IVAR ) {
00978 MU_NODE *mnode = cr->Ivar_mu_node();
00979 if ( mnode && mnode->Is_Valid() ) {
00980 CODEREP *mu_cr = mnode->OPND();
00981
00982 if ( ! mu_cr->Is_flag_set(CF_IS_ZERO_VERSION) ) {
00983 DU_Phi_Ctr++;
00984 Compute_use_def_var( du_mgr, mu_cr, wn, wn_bb );
00985
00986
00987
00988 Update_loop_info( du_mgr, wn, wn_bb );
00989 }
00990 }
00991 }
00992 }
00993
00994 void
00995 EMITTER::Compute_use_def_stmt( DU_MANAGER *du_mgr, WN *wn, BB_NODE *wn_bb )
00996 {
00997 const OPERATOR opr = WN_operator(wn);
00998
00999 Is_True( OPERATOR_is_stmt(opr) || OPERATOR_is_scf(opr),
01000 ("EMITTER::Compute_use_def_stmt: non-stmt: %s", OPERATOR_name(opr)) );
01001
01002
01003 if ( WN_has_mu(wn, Cfg()->Rgn_level()) ) {
01004 STMTREP *stmt = (STMTREP*)WN_MAP_Get( _wn_to_cr_map, wn );
01005 Is_True( stmt != NULL,
01006 ("Compute_use_def_stmt: no stmtrep for wn:<%d:%d>\n",
01007 OPERATOR_mapcat(opr), WN_map_id(wn)) );
01008
01009 MU_LIST_ITER mu_iter;
01010 MU_NODE *mnode;
01011 FOR_ALL_NODE( mnode, mu_iter, Init(stmt->Mu_list())) {
01012 if ( mnode->Is_Valid() ) {
01013 CODEREP *mu_cr = mnode->OPND();
01014
01015 if ( ! mu_cr->Is_flag_set(CF_IS_ZERO_VERSION) ) {
01016 DU_Phi_Ctr++;
01017 Compute_use_def_var( du_mgr, mu_cr, wn, wn_bb );
01018
01019
01020
01021 Update_loop_info( du_mgr, wn, stmt->Bb() );
01022 }
01023 }
01024 }
01025 }
01026
01027
01028
01029 if ( WN_has_chi(wn, Cfg()->Rgn_level()) ) {
01030 STMTREP *stmt = (STMTREP*)WN_MAP_Get( _wn_to_cr_map, wn );
01031 Is_True( stmt != NULL,
01032 ("Compute_use_def_stmt: no stmtrep for wn:<%d:%d>\n",
01033 OPERATOR_mapcat(WN_operator(wn)), WN_map_id(wn)) );
01034
01035 CHI_LIST_ITER chi_iter;
01036 CHI_NODE *chi;
01037 FOR_ALL_NODE( chi, chi_iter, Init(stmt->Chi_list()) ) {
01038 if ( chi->Live() ) {
01039 BOOL real_var_chi_opnd =
01040 du_mgr->Opt_Stab()->Is_real_var(chi->OPND()->Aux_id());
01041
01042
01043
01044 if (WOPT_Enable_DU_Union && OPERATOR_is_scalar_store (opr) &&
01045 chi->Aux_id() != du_mgr->Opt_Stab()->Default_vsym()) {
01046 du_mgr->Du_Set_Incomplete( wn );
01047 }
01048
01049 if ( !real_var_chi_opnd ) {
01050
01051
01052
01053
01054
01055
01056
01057 if ( OPERATOR_is_scalar_store (opr) ) {
01058 du_mgr->Du_Set_Incomplete( wn );
01059 }
01060 }
01061 else if ( WOPT_Enable_Zero_Version || ! WOPT_Enable_DU_Full ) {
01062 if ( ! chi->OPND()->Is_flag_set(CF_IS_ZERO_VERSION) ) {
01063 DU_Phi_Ctr++;
01064 Compute_incomplete_defs( du_mgr, chi->OPND() );
01065 }
01066 }
01067 }
01068 }
01069 }
01070
01071
01072 if ( opr == OPR_BLOCK ) {
01073 for ( WN *bwn = WN_first(wn); bwn != NULL; bwn = WN_next(bwn) ) {
01074 Compute_use_def_stmt( du_mgr, bwn, wn_bb );
01075 }
01076 } else if ( opr == OPR_IO ) {
01077
01078 } else if (opr == OPR_REGION) {
01079 RID *rid = REGION_get_rid(wn);
01080 Is_True(rid != NULL, ("EMITTER::Compute_use_def_stmt, NULL RID"));
01081
01082 #if defined(TARG_SL2)
01083 if (RID_TYPE_mp(rid) || RID_TYPE_eh(rid) || RID_TYPE_olimit(rid) ||
01084 RID_TYPE_major(rid) || RID_TYPE_minor(rid) ||
01085 RID_TYPE_pragma(rid) ||
01086 RID_level(rid) < Cfg()->Rgn_level()) {
01087 #else
01088 if (RID_TYPE_mp(rid) || RID_TYPE_eh(rid) || RID_TYPE_olimit(rid) ||
01089 RID_TYPE_pragma(rid) ||
01090 RID_level(rid) < Cfg()->Rgn_level()) {
01091 #endif
01092 Compute_use_def_stmt(du_mgr, WN_region_body(wn), wn_bb);
01093
01094 if (RID_TYPE_mp(rid))
01095 Compute_use_def_stmt(du_mgr, WN_region_pragmas(wn), wn_bb);
01096 }
01097 } else {
01098
01099
01100 STMTREP *stmt = (STMTREP*)WN_MAP_Get( _wn_to_cr_map, wn );
01101
01102
01103 if ( OPERATOR_is_scalar_store (opr) ) {
01104 if ( stmt->Has_zver() ) {
01105 du_mgr->Du_Set_Incomplete( wn );
01106 }
01107 }
01108
01109 for ( INT ikid = 0; ikid < WN_kid_count(wn); ikid++ ) {
01110 WN *kid = WN_kid(wn,ikid);
01111 const OPERATOR kid_opr = WN_operator(kid);
01112 if ( OPERATOR_is_stmt(kid_opr) || OPERATOR_is_scf(kid_opr) )
01113 Compute_use_def_stmt( du_mgr, kid, wn_bb );
01114 else
01115 Compute_use_def_expr( du_mgr, kid, (stmt?stmt->Bb():NULL) );
01116 }
01117 }
01118 }
01119
01120
01121
01122
01123
01124
01125
01126 void
01127 EMITTER::Compute_use_def_zero_ver( DU_MANAGER *du_mgr )
01128 {
01129 CFG_ITER cfg_iter(Cfg());
01130 BB_NODE *bb;
01131 FOR_ALL_NODE( bb, cfg_iter, Init() ) {
01132 PHI_LIST_ITER phi_iter;
01133 PHI_NODE *phi;
01134 FOR_ALL_ELEM ( phi, phi_iter, Init(bb->Phi_list()) ) {
01135 if (!phi->Res_is_cr()) continue;
01136 CODEREP *res = phi->RESULT();
01137 if ( res != NULL && res->Kind() == CK_VAR &&
01138 res->Is_flag_set(CF_IS_ZERO_VERSION) )
01139 {
01140
01141 PHI_OPND_ITER phi_opnd_iter(phi);
01142 CODEREP *opnd;
01143 BOOL ignore_pregs = Opt_stab()->Is_virtual(phi->RESULT()->Aux_id());
01144 DU_Phi_Ctr++;
01145 FOR_ALL_ELEM(opnd, phi_opnd_iter, Init()) {
01146
01147
01148 if ( ! opnd->Is_flag_set(CF_IS_ZERO_VERSION) &&
01149 du_mgr->Opt_Stab()->Is_real_var(opnd->Aux_id()) )
01150 {
01151
01152
01153 Compute_incomplete_defs( du_mgr, opnd );
01154 }
01155 }
01156 }
01157 }
01158 }
01159 }
01160
01161
01162
01163
01164
01165
01166
01167 static void
01168 Clear_phi_counts( CFG *cfg )
01169 {
01170 CFG_ITER cfg_iter(cfg);
01171 BB_NODE *bb;
01172 FOR_ALL_NODE( bb, cfg_iter, Init() ) {
01173 PHI_LIST_ITER phi_iter;
01174 PHI_NODE *phi;
01175 FOR_ALL_ELEM ( phi, phi_iter, Init(bb->Phi_list()) ) {
01176 phi->Set_count(0);
01177 }
01178 }
01179
01180
01181 DU_Phi_Ctr = 0;
01182 }
01183
01184
01185 void
01186 EMITTER::Compute_use_def(DU_MANAGER *du_mgr)
01187 {
01188 BOOL gen_du = WOPT_Enable_Generate_DU;
01189 BOOL collect_ipa = TRUE;
01190
01191 du_mgr->Set_Entry_Wn(_opt_func);
01192 du_mgr->Set_Opt_Stab(_opt_stab);
01193 du_mgr->Set_opt_phase(_opt_phase);
01194 du_mgr->Set_Tracing( Get_Trace(TP_GLOBOPT, DU_DUMP_FLAG) );
01195 if ( du_mgr->Tracing() ) {
01196 fprintf( TFile, "%s EMITTER::Compute_use_def\n%s",SBar,SBar );
01197 }
01198
01199
01200 if (du_mgr->Opt_phase() == PREOPT_LNO_PHASE &&
01201 !Has_do_loop() &&
01202 !PU_mp_needs_lno(Get_Current_PU())
01203 )
01204 {
01205 gen_du = FALSE;
01206 collect_ipa = FALSE;
01207 }
01208
01209 if ( gen_du ) {
01210
01211 Clear_phi_counts(_cfg);
01212
01213 Compute_use_def_stmt(du_mgr, du_mgr->Entry_Wn(), NULL);
01214
01215 Compute_use_def_zero_ver( du_mgr );
01216 du_mgr->Set_du_built();
01217 }
01218
01219 if ( collect_ipa ) {
01220
01221 Collect_IPA_summary( du_mgr, du_mgr->Entry_Wn() );
01222 }
01223
01224 #ifdef Is_True_On
01225 if ( du_mgr->Du_built() && !du_mgr->Verify() ) {
01226 DevWarn( "DU_MANAGER::Verify() returned FALSE" );
01227 }
01228 #endif // is_true_on
01229
01230 }
01231
01232
01233
01234
01235
01236 DU_MANAGER* Create_Du_Manager(MEM_POOL *pu_pool)
01237 {
01238 return CXX_NEW(DU_MANAGER, pu_pool);
01239 }
01240
01241 void Delete_Du_Manager(DU_MANAGER *du, MEM_POOL *pu_pool)
01242 {
01243 CXX_DELETE(du, pu_pool);
01244 }
01245
01246
01247
01248
01249
01250 extern BOOL
01251 Du_Built( DU_MANAGER *du )
01252 {
01253 return du->Du_built();
01254 }
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266 BOOL
01267 DU_MANAGER::Verify_add_wn_to_map( WN *wn, WN_MAP *wn_in_tree_map ) const
01268 {
01269 BOOL verified = TRUE;
01270 #ifdef Is_True_On
01271 if ( WOPT_Enable_Verify <= 0 )
01272 return TRUE;
01273
01274 if ( WN_MAP32_Get( *wn_in_tree_map, wn ) != 0 ) {
01275 verified = FALSE;
01276
01277 if ( Tracing() ) {
01278 fprintf( TFile, "Verify_add_wn_to_map: WN:<%d:%d> in DAG?\n",
01279 OPCODE_mapcat(WN_opcode(wn)), WN_map_id(wn) );
01280 }
01281 }
01282 else {
01283 WN_MAP32_Set( *wn_in_tree_map, wn, 1 );
01284 }
01285
01286 if ( WN_opcode(wn) == OPC_BLOCK ) {
01287 for ( WN *stmt = WN_first(wn); stmt; stmt = WN_next(stmt) )
01288 if ( ! Verify_add_wn_to_map( stmt, wn_in_tree_map ) )
01289 verified = FALSE;
01290 }
01291 else {
01292 for ( INT kidnum = 0; kidnum < WN_kid_count(wn); kidnum++ )
01293 if ( ! Verify_add_wn_to_map( WN_kid(wn,kidnum), wn_in_tree_map ) )
01294 verified = FALSE;
01295 }
01296
01297 #endif
01298 return verified;
01299 }
01300
01301 BOOL
01302 DU_MANAGER::Verify_du_chains_in_tree( WN *wn, WN_MAP *wn_in_tree_map ) const
01303 {
01304 BOOL verified = TRUE;
01305 #ifdef Is_True_On
01306 if ( WOPT_Enable_Verify <= 0 )
01307 return TRUE;
01308
01309
01310 if ( WN_MAP32_Get( *wn_in_tree_map, wn ) == 0 ) {
01311 verified = FALSE;
01312
01313 if ( Tracing() ) {
01314 fprintf( TFile, "Verify_du_chains_in_tree: WN:<%d:%d> not in tree\n",
01315 OPCODE_mapcat(WN_opcode(wn)), WN_map_id(wn) );
01316 }
01317 }
01318 else {
01319
01320
01321 DEF_LIST *ud_list = Ud_Get_Def(wn);
01322 if ( ud_list != NULL ) {
01323 DEF_LIST_ITER def_lst_iter;
01324 DU_NODE *ud_node;
01325 FOR_ALL_NODE(ud_node, def_lst_iter, Init(ud_list)) {
01326 WN *ud_wn = ud_node->Wn();
01327 if ( ud_wn != NULL ) {
01328 if ( WN_MAP32_Get( *wn_in_tree_map, ud_wn ) == 0 ) {
01329 verified = FALSE;
01330
01331 if ( Tracing() ) {
01332 fprintf( TFile,
01333 "Verify_du_chains_in_tree: def WN:<%d:%d> from use WN:<%d:%d> not in tree\n",
01334 OPCODE_mapcat(WN_opcode(ud_wn)), WN_map_id(ud_wn),
01335 OPCODE_mapcat(WN_opcode(wn)), WN_map_id(wn) );
01336 fdump_tree( TFile, ud_wn );
01337 }
01338 }
01339 }
01340 }
01341
01342
01343 if ( ud_list->Loop_stmt() != NULL ) {
01344 if ( WN_MAP32_Get(*wn_in_tree_map, ud_list->Loop_stmt()) == 0 ){
01345 verified = FALSE;
01346
01347 if ( Tracing() ) {
01348 fprintf( TFile,
01349 "Verify_du_chains_in_tree: Loop_stmt WN:<%d:%d> from use WN:<%d:%d> not in tree\n",
01350 OPCODE_mapcat(WN_opcode(ud_list->Loop_stmt())),
01351 WN_map_id(ud_list->Loop_stmt()),
01352 OPCODE_mapcat(WN_opcode(wn)), WN_map_id(wn) );
01353 }
01354 }
01355 }
01356 }
01357
01358
01359 USE_LIST *du_list = Du_Get_Use(wn);
01360 if ( du_list != NULL ) {
01361 USE_LIST_ITER use_lst_iter;
01362 DU_NODE *du_node;
01363 FOR_ALL_NODE(du_node, use_lst_iter, Init(du_list)) {
01364 WN *du_wn = du_node->Wn();
01365 if ( du_wn != NULL ) {
01366 if ( WN_MAP32_Get( *wn_in_tree_map, du_wn ) == 0 ) {
01367 verified = FALSE;
01368
01369 if ( Tracing() ) {
01370 fprintf( TFile,
01371 "Verify_du_chains_in_tree: use WN:<%d:%d> from def WN:<%d:%d> not in tree\n",
01372 OPCODE_mapcat(WN_opcode(du_wn)), WN_map_id(du_wn),
01373 OPCODE_mapcat(WN_opcode(wn)), WN_map_id(wn) );
01374 fdump_tree( TFile, du_wn );
01375 }
01376 }
01377 }
01378 }
01379 }
01380
01381
01382 if ( WN_opcode(wn) == OPC_BLOCK ) {
01383 for ( WN *stmt = WN_first(wn); stmt; stmt = WN_next(stmt) )
01384 if ( ! Verify_du_chains_in_tree( stmt, wn_in_tree_map ) )
01385 verified = FALSE;
01386 }
01387 else {
01388 for ( INT kidnum = 0; kidnum < WN_kid_count(wn); kidnum++ )
01389 if (! Verify_du_chains_in_tree( WN_kid(wn,kidnum), wn_in_tree_map ))
01390 verified = FALSE;
01391 }
01392 }
01393 #endif
01394 return verified;
01395 }
01396
01397 BOOL
01398 DU_MANAGER::Verify_wn_in_tree( void ) const
01399 {
01400 BOOL verified = TRUE;
01401 #ifdef Is_True_On
01402 if ( WOPT_Enable_Verify <= 0 )
01403 return TRUE;
01404
01405 if ( Entry_Wn() == NULL )
01406 return verified;
01407
01408 OPT_POOL_Push( &MEM_local_pool, DU_DUMP_FLAG );
01409
01410
01411 WN_MAP wn_in_tree_map = WN_MAP32_Create(&MEM_local_pool);
01412 if ( ! Verify_add_wn_to_map( Entry_Wn(), &wn_in_tree_map ) )
01413 verified = FALSE;
01414
01415
01416
01417 if ( ! Verify_du_chains_in_tree( Entry_Wn(), &wn_in_tree_map ) )
01418 verified = FALSE;
01419
01420
01421 WN_MAP_Delete(wn_in_tree_map);
01422
01423 OPT_POOL_Pop( &MEM_local_pool, DU_DUMP_FLAG );
01424
01425 #endif
01426 return verified;
01427 }
01428
01429 BOOL
01430 DU_MANAGER::Verify_scalar_usage( WN *wn ) const
01431 {
01432 BOOL verified = TRUE;
01433 #ifdef Is_True_On
01434 if ( WOPT_Enable_Verify <= 0 )
01435 return TRUE;
01436
01437 const OPCODE opc = WN_opcode(wn);
01438 const OPERATOR opr = OPCODE_operator(opc);
01439
01440 switch ( opr ) {
01441 case OPR_LDID:
01442 case OPR_LDBITS:
01443 {
01444 DEF_LIST *ud_list = Ud_Get_Def(wn);
01445 if ( ud_list == NULL ) {
01446 verified = FALSE;
01447 if ( Tracing() ) {
01448 fprintf( TFile, "Verify_scalar_usage: no def for WN:<%d:%d>:",
01449 OPCODE_mapcat(WN_opcode(wn)), WN_map_id(wn) );
01450 fdump_wn( TFile, wn );
01451 }
01452 }
01453 else {
01454 WN *loop = ud_list->Loop_stmt();
01455 if ( loop ) {
01456 if ( WN_opcode(loop) != OPC_DO_LOOP ) {
01457 verified = FALSE;
01458 if ( Tracing() ) {
01459 fprintf( TFile,
01460 "Verify_scalar_usage: non-loop node for WN:<%d:%d>\n",
01461 OPCODE_mapcat(WN_opcode(wn)), WN_map_id(wn) );
01462 fprintf( TFile, " is %s\n", OPCODE_name(WN_opcode(loop)) );
01463 }
01464 }
01465 }
01466 }
01467 }
01468 break;
01469
01470 case OPR_STID:
01471 case OPR_STBITS:
01472 {
01473 USE_LIST *du_list = Du_Get_Use(wn);
01474 if ( du_list == NULL ) {
01475
01476 if ( TY_is_volatile( WN_ty(wn) ) ||
01477 ( ST_class(WN_st(wn)) == CLASS_PREG &&
01478 Preg_Is_Dedicated(WN_offset(wn)) ) ) {
01479
01480 goto stid_visit_kids;
01481 }
01482
01483 verified = FALSE;
01484 if ( Tracing() ) {
01485 fprintf( TFile, "Verify_scalar_usage: no use for WN:<%d:%d>: ",
01486 OPCODE_mapcat(WN_opcode(wn)), WN_map_id(wn) );
01487 fdump_wn( TFile, wn );
01488 }
01489 }
01490
01491 stid_visit_kids:
01492 for ( INT kidnum = 0; kidnum < WN_kid_count(wn); kidnum++ )
01493 if ( ! Verify_scalar_usage( WN_kid(wn,kidnum) ) )
01494 verified = FALSE;
01495 }
01496 break;
01497
01498 case OPR_FORWARD_BARRIER:
01499 case OPR_BACKWARD_BARRIER:
01500 case OPR_IO:
01501
01502 break;
01503
01504 case OPR_BLOCK:
01505 {
01506 for ( WN *stmt = WN_first(wn); stmt; stmt = WN_next(stmt) )
01507 if ( ! Verify_scalar_usage( stmt ) )
01508 verified = FALSE;
01509 }
01510 break;
01511
01512 default:
01513 {
01514 for ( INT kidnum = 0; kidnum < WN_kid_count(wn); kidnum++ )
01515 if ( ! Verify_scalar_usage( WN_kid(wn,kidnum) ) )
01516 verified = FALSE;
01517 }
01518 break;
01519 }
01520
01521 #endif
01522 return verified;
01523 }
01524
01525
01526
01527
01528
01529 BOOL
01530 DU_MANAGER::Verify(void)
01531 {
01532 BOOL verified = TRUE;
01533
01534 #ifdef Is_True_On
01535 if ( WOPT_Enable_Verify <= 0 )
01536 return TRUE;
01537
01538 BOOL old_tracing = Tracing();
01539 Set_Tracing( Get_Trace(TP_GLOBOPT, DU_DUMP_FLAG) );
01540
01541 if ( Tracing() ) {
01542 fprintf( TFile, "DU_MANAGER::Verify\n" );
01543 }
01544
01545
01546 if ( ! Verify_wn_in_tree() )
01547 verified = FALSE;
01548
01549
01550 if ( ! Verify_scalar_usage( Entry_Wn() ) )
01551 verified = FALSE;
01552
01553 if ( Tracing() ) {
01554 fprintf( TFile, "DU_MANAGER::Verify: %s\n",
01555 (verified ? "TRUE":"FALSE") );
01556 }
01557
01558 Set_Tracing(old_tracing);
01559 #endif
01560
01561 return verified;
01562 }
01563
01564
01565
01566
01567
01568
01569 class BB_SUMMARY_INFO {
01570 public:
01571 enum {
01572 BR_FALL_THRU = 0,
01573 BR_TAKEN = 1,
01574 BR_UNKNOWN = 2
01575 };
01576
01577 IDTYPE *succ;
01578 IDTYPE cd;
01579 INT which_edge;
01580 INT dom_dfs_id;
01581 INT dom_kid_cnt;
01582 WN *first_stmt;
01583 WN *last_stmt;
01584 };
01585
01586
01587
01588 IDTYPE *
01589 DU_MANAGER::Get_succ_vec(IDTYPE bb_id)
01590 {
01591 Check_bb_id(bb_id);
01592 return _bb_summary[bb_id].succ;
01593 }
01594
01595 IDTYPE
01596 DU_MANAGER::Get_cd(IDTYPE bb_id)
01597 {
01598 Check_bb_id(bb_id);
01599 return _bb_summary[bb_id].cd;
01600 }
01601
01602
01603 WN *
01604 DU_MANAGER::Get_first_stmt(IDTYPE bb_id)
01605 {
01606 Check_bb_id(bb_id);
01607 return _bb_summary[bb_id].first_stmt;
01608 }
01609
01610 WN *
01611 DU_MANAGER::Get_last_stmt(IDTYPE bb_id)
01612 {
01613 Check_bb_id(bb_id);
01614 return _bb_summary[bb_id].last_stmt;
01615 }
01616
01617
01618 BOOL
01619 DU_MANAGER::CD_is_fall_thru(IDTYPE bb_id)
01620 {
01621 Check_bb_id(bb_id);
01622 return _bb_summary[bb_id].which_edge == BB_SUMMARY_INFO::BR_FALL_THRU;
01623 }
01624
01625 BOOL
01626 DU_MANAGER::CD_is_br_taken(IDTYPE bb_id)
01627 {
01628 Check_bb_id(bb_id);
01629 return _bb_summary[bb_id].which_edge == BB_SUMMARY_INFO::BR_TAKEN;
01630 }
01631
01632
01633 BOOL
01634 DU_MANAGER::Dominate(IDTYPE bb1, IDTYPE bb2)
01635 {
01636 Check_bb_id(bb1);
01637 Check_bb_id(bb2);
01638 BB_SUMMARY_INFO *bs1 = &_bb_summary[bb1];
01639 BB_SUMMARY_INFO *bs2 = &_bb_summary[bb2];
01640 return (bs1->dom_dfs_id <= bs2->dom_dfs_id &&
01641 bs2->dom_dfs_id <= (bs1->dom_dfs_id + bs1->dom_kid_cnt));
01642 }
01643
01644
01645 void
01646 DU_MANAGER::Collect_BB_id(WN_MAP wn_to_cr_map, WN *wn)
01647 {
01648 const OPERATOR opr = WN_operator(wn);
01649 const STMTREP *stmt = (STMTREP*)WN_MAP_Get( wn_to_cr_map, wn );
01650
01651 if (stmt && (WN_operator(wn) != OPR_FUNC_ENTRY ||
01652 WN_operator(wn) != OPR_ALTENTRY)) {
01653 BB_NODE *bb = stmt->Bb();
01654 BB_SUMMARY_INFO *bs = &_bb_summary[bb->Id()];
01655 Set_bb_id(wn, bb->Id());
01656 if (bs->first_stmt == NULL)
01657 bs->first_stmt = wn;
01658 bs->last_stmt = wn;
01659 if (Tracing())
01660 fprintf(TFile, "stmt (map_id %d) in BB%d\n", WN_map_id(wn), Get_bb_id(wn));
01661 }
01662
01663 if ( opr == OPR_BLOCK ) {
01664 for ( WN *bwn = WN_first(wn); bwn != NULL; bwn = WN_next(bwn) ) {
01665 Collect_BB_id(wn_to_cr_map, bwn);
01666 }
01667 } else if ( opr == OPR_IO ) {
01668
01669 } else if (opr == OPR_REGION) {
01670 Collect_BB_id(wn_to_cr_map, WN_region_body(wn));
01671 } else {
01672 for ( INT ikid = 0; ikid < WN_kid_count(wn); ikid++ ) {
01673 WN *kid = WN_kid(wn,ikid);
01674 const OPERATOR kid_opr = WN_operator(kid);
01675 if ( OPERATOR_is_stmt(kid_opr) || OPERATOR_is_scf(kid_opr) )
01676 Collect_BB_id( wn_to_cr_map, kid);
01677 }
01678 }
01679 }
01680
01681
01682 void
01683 DU_MANAGER::Collect_CFG(CFG *cfg)
01684 {
01685 CFG_ITER cfg_iter;
01686 BB_NODE *bb;
01687 FOR_ALL_ELEM (bb, cfg_iter, Init(cfg)) {
01688 IDTYPE *succ = (IDTYPE *) CXX_NEW_ARRAY(IDTYPE *, bb->Succ()->Len()+1, &_mem_pool);
01689 BB_LIST_ITER bb_iter;
01690 BB_NODE *bb_succ;
01691 INT i = 0;
01692 FOR_ALL_ELEM( bb_succ, bb_iter, Init(bb->Succ()) ) {
01693 succ[i++] = bb_succ->Id();
01694 }
01695 succ[i] = 0;
01696 _bb_summary[bb->Id()].succ = succ;
01697 _bb_summary[bb->Id()].dom_dfs_id = bb->Dom_dfs_id();
01698 _bb_summary[bb->Id()].dom_kid_cnt = bb->Dom_descendant_cnt();
01699
01700
01701 if (bb == cfg->Fake_entry_bb() || bb == cfg->Fake_exit_bb())
01702 continue;
01703
01704
01705 BB_NODE *cd_bb = NULL;
01706 BB_NODE *temp_bb;
01707 BB_NODE_SET_ITER rcfg_iter;
01708 FOR_ALL_ELEM( temp_bb, rcfg_iter, Init( bb->Rcfg_dom_frontier() ) ) {
01709 if (temp_bb == bb) continue;
01710 if (cd_bb != NULL) {
01711 cd_bb = NULL;
01712 break;
01713 }
01714 cd_bb = temp_bb;
01715 }
01716 if (cd_bb == NULL && bb->Postdominates_strictly(cfg->Entry_bb())) {
01717 cd_bb = cfg->Entry_bb();
01718 }
01719 if (cd_bb != NULL) {
01720 if (cd_bb == bb || ! cd_bb->Dominates_strictly(bb)) {
01721 cd_bb = NULL;
01722 }
01723 }
01724
01725 if (cd_bb != NULL) {
01726 BB_LIST_ITER bb_iter;
01727 BB_NODE *succ;
01728 BB_NODE *which_edge = NULL;
01729 FOR_ALL_ELEM( succ, bb_iter, Init(cd_bb->Succ()) ) {
01730 if (bb->Postdominates(succ)) {
01731 which_edge = succ;
01732 break;
01733 }
01734 }
01735 if (which_edge != NULL) {
01736 BB_SUMMARY_INFO *bs = &_bb_summary[bb->Id()];
01737 bs->cd = cd_bb->Id();
01738 bs->which_edge = BB_SUMMARY_INFO::BR_UNKNOWN;
01739 STMTREP *bb_branch = cd_bb->Branch_stmtrep();
01740 if (bb_branch != NULL) {
01741 OPERATOR opr = bb_branch->Opr();
01742 if (opr == OPR_TRUEBR || opr == OPR_FALSEBR) {
01743 if (which_edge == cd_bb->Next())
01744 bs->which_edge = BB_SUMMARY_INFO::BR_FALL_THRU;
01745 else
01746 bs->which_edge = BB_SUMMARY_INFO::BR_TAKEN;
01747 }
01748 }
01749 }
01750 }
01751 }
01752
01753
01754 _entry_bb = cfg->Entry_bb()->Id();
01755 _exit_bb = cfg->Exit_bb()->Id();
01756 if (cfg->Exit_bb() == cfg->Fake_exit_bb()) {
01757 BB_NODE *bb = cfg->Exit_bb();
01758 IDTYPE *pred = (IDTYPE *) CXX_NEW_ARRAY(IDTYPE *, bb->Pred()->Len()+1, &_mem_pool);
01759 BB_LIST_ITER bb_iter;
01760 BB_NODE *bb_pred;
01761 INT i = 0;
01762 FOR_ALL_ELEM( bb_pred, bb_iter, Init(bb->Pred()) ) {
01763 pred[i++] = bb_pred->Id();
01764 }
01765 pred[i] = 0;
01766 _bb_summary[bb->Id()].succ = pred;
01767 }
01768
01769 if (Tracing()) {
01770 INT i;
01771 for (i = 1; i < cfg->Total_bb_count(); i++) {
01772 fprintf(TFile, "%3d ", i);
01773 if (_bb_summary[i].first_stmt)
01774 fprintf(TFile, "\t\tfirst_stmt %d last_stmt %d",
01775 WN_map_id(_bb_summary[i].first_stmt),
01776 WN_map_id(_bb_summary[i].last_stmt));
01777 fprintf(TFile, "\n");
01778 }
01779
01780 fprintf(TFile, "entry bb is %d. exit bb is %d\n", _entry_bb, _exit_bb);
01781 for (i = 1; i < cfg->Total_bb_count(); i++) {
01782 fprintf(TFile, "%3d -> ", i);
01783 if (_bb_summary[i].succ) {
01784 for (IDTYPE *p = _bb_summary[i].succ; *p != 0; p++)
01785 fprintf(TFile, "%d ", *p);
01786 }
01787 if (_bb_summary[i].cd)
01788 fprintf(TFile, "\t\tCD%d:%d ", _bb_summary[i].cd, _bb_summary[i].which_edge);
01789 fprintf(TFile, "\t\tdom_dfs: %d dom_kid: %d", _bb_summary[i].dom_dfs_id, _bb_summary[i].dom_kid_cnt);
01790 fprintf(TFile, "\n");
01791 }
01792 }
01793 }
01794
01795
01796 void
01797 DU_MANAGER::Alloc_IPA_summary(CFG *cfg)
01798 {
01799 _bb_cnt = cfg->Total_bb_count();
01800 _bb_summary = (BB_SUMMARY_INFO *) CXX_NEW_ARRAY(BB_SUMMARY_INFO, _bb_cnt, &_mem_pool);
01801 BZERO (_bb_summary, sizeof(BB_SUMMARY_INFO) * _bb_cnt);
01802 }
01803
01804
01805 void
01806 EMITTER::Collect_IPA_summary(DU_MANAGER *du_mgr, WN *wn)
01807 {
01808 du_mgr->Alloc_IPA_summary(Cfg());
01809 du_mgr->Collect_BB_id(_wn_to_cr_map, wn);
01810 du_mgr->Collect_CFG(Cfg());
01811 }
01812
01813
01814
01815
01816
01817 DU_MANAGER::DU_MANAGER(void)
01818 {
01819 OPT_POOL_Initialize(&_mem_pool, "DU_pool", FALSE, DU_DUMP_FLAG);
01820 OPT_POOL_Push(&_mem_pool, DU_DUMP_FLAG);
01821 _du_map = WN_MAP_Create(&_mem_pool);
01822 _ud_map = WN_MAP_Create(&_mem_pool);
01823 _bb_map = WN_MAP32_Create(&_mem_pool);
01824 _val_restored_map = WN_MAP_UNDEFINED;
01825 _opt_stab = NULL;
01826 _entry_wn = NULL;
01827 _opt_phase = PREOPT_PHASE;
01828 _du_built = FALSE;
01829 _tracing = FALSE;
01830 }
01831
01832