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 #ifdef USE_PCH
00062 #include "opt_pch.h"
00063 #endif // USE_PCH
00064 #pragma hdrstop
00065
00066
00067 #define opt_bb_CXX "opt_bb.cxx"
00068 #ifdef _KEEP_RCS_ID
00069 static char *rcs_id = opt_bb_CXX"$Revision: 1.1.1.1 $";
00070 #endif
00071
00072 #include "defs.h"
00073 #include "wn.h"
00074 #include "errors.h"
00075 #include "erglob.h"
00076 #include "cxx_memory.h"
00077 #include "region_util.h"
00078 #include "fb_whirl.h"
00079
00080 #include "stblock.h"
00081
00082 #include "bb_node_set.h"
00083
00084 #include "opt_bb.h"
00085 #include "opt_config.h"
00086 #include "opt_htable.h"
00087 #include "opt_util.h"
00088 #include "opt_wn.h"
00089 #include "opt_ssa.h"
00090 #include "opt_base.h"
00091 #include "bb_node_set.h"
00092 #include "idx_32_set.h"
00093
00094 BB_LOOP*
00095 BB_LOOP::Append (BB_LOOP *loop)
00096 {
00097 BB_LOOP_CONTAINER bb_loop_container(this);
00098 bb_loop_container.Append(loop);
00099 return (BB_LOOP*)bb_loop_container.Head();
00100 }
00101
00102 BB_LOOP*
00103 BB_LOOP::Append_list (BB_LOOP *loop)
00104 {
00105 BB_LOOP_CONTAINER bb_loop_container(this);
00106 BB_LOOP_CONTAINER tmp(loop);
00107 bb_loop_container.Append_List(&tmp);
00108 return (BB_LOOP*)bb_loop_container.Head();
00109 }
00110
00111 BOOL
00112 BB_LOOP::Contains(const BB_LOOP* l) const
00113 {
00114
00115 for (const BB_LOOP *p = l; p != NULL; p = p->Parent())
00116 if (p == this) return TRUE;
00117 return FALSE;
00118 }
00119
00120 BB_LIST*
00121 BB_LIST::Append (BB_NODE *bb, MEM_POOL *pool)
00122 {
00123 SLIST bb_list_container(this);
00124 BB_LIST *new_bblst = (BB_LIST*)CXX_NEW( BB_LIST(bb), pool );
00125 if ( new_bblst == NULL ) ErrMsg ( EC_No_Mem, "BB_LIST::Append" );
00126 bb_list_container.Append(new_bblst);
00127 return (BB_LIST*)bb_list_container.Head();
00128 }
00129
00130 BB_LIST *
00131 BB_LIST::Remove (BB_NODE *bb, MEM_POOL *pool)
00132 {
00133 Warn_todo("BB_LIST::Remove: remove this call");
00134 BB_LIST *prev, *cur, *retval = this;
00135
00136 if (bb == NULL) return this;
00137
00138 for (prev=NULL,cur=this; cur && cur->node != bb; cur = cur->Next())
00139 prev = cur;
00140
00141 if ( cur == NULL )
00142 return this;
00143
00144 if (cur == this)
00145 retval = Next();
00146
00147 cur->SLIST_NODE::Remove(prev);
00148 CXX_DELETE(cur, pool);
00149 return retval;
00150 }
00151
00152 BOOL
00153 BB_LIST::Contains(BB_NODE *bb) const
00154 {
00155 BB_LIST_ITER bb_list_iter(this);
00156 BB_NODE *tmp;
00157 FOR_ALL_ELEM(tmp, bb_list_iter, Init()) {
00158 if (tmp == bb)
00159 return TRUE;
00160 }
00161 return FALSE;
00162 }
00163
00164 INT32
00165 BB_LIST::Pos(BB_NODE *nd)
00166 {
00167 BB_LIST *cur = this;
00168 INT32 pos = 0;
00169 while (cur) {
00170 if (nd == cur->node) {
00171 Is_True( cur->Next()->Pos(nd) == -1,
00172 ( "BB_LIST::Pos(): Node BB%d must not "
00173 "appear more than once", nd ) );
00174 return pos;
00175 }
00176 cur = cur->Next();
00177 pos++;
00178 }
00179 return -1;
00180 }
00181
00182 void
00183 BB_LIST_CONTAINER::Append (BB_NODE *bb, MEM_POOL *pool)
00184 {
00185 BB_LIST *new_bblst = (BB_LIST*)CXX_NEW( BB_LIST(bb), pool );
00186 if ( new_bblst == NULL ) ErrMsg ( EC_No_Mem, "BB_LIST::Append" );
00187 Append(new_bblst);
00188 }
00189
00190 void
00191 BB_LIST_CONTAINER::Prepend(BB_NODE *bb, MEM_POOL *pool)
00192 {
00193 BB_LIST *new_bblst = (BB_LIST*)CXX_NEW( BB_LIST(bb), pool );
00194 if ( new_bblst == NULL ) ErrMsg ( EC_No_Mem, "BB_LIST::Prepend" );
00195 Prepend(new_bblst);
00196 }
00197
00198 void
00199 BB_LIST_CONTAINER::Remove (BB_NODE *bb, MEM_POOL *pool)
00200 {
00201 Warn_todo("BB_LIST_CONTAINER::Remove: remove this call");
00202 BB_LIST *prev, *cur;
00203
00204 if (bb == NULL) return;
00205 for (prev=NULL,cur=Head(); cur && cur->Node() != bb; cur = cur->Next())
00206 prev = cur;
00207
00208 CXX_DELETE(cur->Remove(prev), pool);
00209 }
00210
00211 BB_NODE *
00212 BB_LIST_CONTAINER::Remove_head(MEM_POOL *pool)
00213 {
00214 Warn_todo("BB_LIST_CONTAINER::Remove_head: remove this call");
00215 BB_NODE *bb;
00216 BB_LIST *head;
00217
00218 head = Head();
00219 if (head == NULL)
00220 return NULL;
00221 bb = head->Node();
00222 CXX_DELETE(Remove_Headnode(), pool);
00223 return bb;
00224 }
00225
00226 BOOL
00227 BB_LIST_CONTAINER::Contains(BB_NODE *bb) const
00228 {
00229 BB_LIST_ITER bb_list_iter(this);
00230 BB_NODE* tmp;
00231 FOR_ALL_ELEM(tmp, bb_list_iter, Init()) {
00232 if (tmp == bb)
00233 return TRUE;
00234 }
00235 return FALSE;
00236 }
00237
00238 void
00239 BB_LIST_ITER::Validate_unique(FILE *fp)
00240 {
00241 for (First(); !Is_Empty(); Next()) {
00242 BB_NODE *tmp = Cur()->Node();
00243 if (tmp == NULL) {
00244 fprintf(fp, "Empty Node in the bb_list!!!\n");
00245 break;
00246 }
00247 if (Peek_Next()) {
00248 if (Peek_Next()->Contains(tmp)) {
00249 fprintf(fp, "The bb_list has redundant bb_node");
00250 this->Head()->Print(fp);
00251 }
00252 }
00253 }
00254 }
00255
00256
00257
00258 static inline BOOL
00259 Can_fallthru(OPCODE opc)
00260 {
00261 if (OPCODE_is_non_scf(opc)) {
00262 if (opc == OPC_TRUEBR ||
00263 opc == OPC_FALSEBR ||
00264 opc == OPC_LABEL) {
00265 return TRUE;
00266 }
00267 else {
00268 return FALSE;
00269 }
00270 }
00271
00272
00273 return TRUE;
00274 }
00275
00276 const BB_NODE *
00277 BB_NODE::Falls_thru_to(void) const
00278 {
00279 if (Firststmt() == NULL) {
00280
00281 if (Last_stmtrep() != NULL) {
00282 if (!Can_fallthru(Last_stmtrep()->Op())) {
00283 return NULL;
00284 }
00285 }
00286 }
00287 else {
00288 if (!Can_fallthru(WN_opcode(Laststmt()))) {
00289 return NULL;
00290 }
00291 }
00292
00293 return Next();
00294 }
00295
00296
00297
00298
00299
00300 void
00301 BB_NODE::Replace_succ( BB_NODE *old_succ, BB_NODE *new_succ )
00302 {
00303 for ( BB_LIST *succs = Succ(); succs != NULL; succs = succs->Next()) {
00304 if ( succs->Node() == old_succ ) {
00305 succs->Set_node(new_succ);
00306 break;
00307 }
00308 }
00309 }
00310
00311 void
00312 BB_NODE::Replace_pred( BB_NODE *old_pred, BB_NODE *new_pred )
00313 {
00314 for ( BB_LIST *preds = Pred(); preds != NULL; preds = preds->Next()) {
00315 if ( preds->Node() == old_pred ) {
00316 preds->Set_node(new_pred);
00317 break;
00318 }
00319 }
00320 }
00321
00322 BB_NODE *
00323 BB_NODE::Nth_pred( INT32 n ) const
00324 {
00325 INT counter = 0;
00326 for ( BB_LIST *preds = Pred(); preds != NULL; preds = preds->Next()) {
00327 if ( counter == n )
00328 return preds->Node();
00329 counter++;
00330 }
00331
00332 FmtAssert( FALSE,
00333 ("BB_NODE::Nth_pred: BB:%d does not have a %dth pred",
00334 Id(), n) );
00335
00336 return NULL;
00337 }
00338
00339
00340 BB_NODE *
00341 BB_NODE::Nth_succ( INT32 n ) const
00342 {
00343 INT counter = 0;
00344 for ( BB_LIST *succs = Succ(); succs != NULL; succs = succs->Next()) {
00345 if ( counter == n )
00346 return succs->Node();
00347 counter++;
00348 }
00349
00350 FmtAssert( FALSE,
00351 ("BB_NODE::Nth_succ: BB:%d does not have a %dth succ",
00352 Id(), n) );
00353
00354 return NULL;
00355 }
00356
00357
00358
00359
00360
00361
00362
00363 void
00364 BB_NODE::Remove_phi_reference( INT32 whichpred )
00365 {
00366 if (Phi_list() != NULL)
00367 Phi_list()->Remove_opnd( whichpred );
00368 }
00369
00370
00371
00372
00373
00374 void
00375 BB_NODE::Clear()
00376 {
00377 _id = 0;
00378 Set_rpo_id((unsigned) -1);
00379 _loopdepth = 0;
00380 _rid_id = 0;
00381 _flags = (BB_FLAG)0;
00382 _kind = BB_UNKNOWN;
00383 _pred = NULL;
00384 _succ = NULL;
00385 _idom = NULL;
00386 _ipdom = NULL;
00387 _dom_bbs = NULL;
00388 _pdom_bbs = NULL;
00389 _dom_dfs_id = 0;
00390 _dom_dfs_last = 0;
00391 _pdom_dfs_id = 0;
00392 _pdom_dfs_last = 0;
00393 _dom_frontier = NULL;
00394 _rcfg_dom_frontier = NULL;
00395 Set_labnam(0);
00396 Set_label_loop_info(NULL);
00397 _firststmt = NULL;
00398 _laststmt = NULL;
00399 _innermost = NULL;
00400 _phi_list = NULL;
00401 _iphi_list = NULL;
00402 _linenum = (SRCPOS)0;
00403 _loop = NULL;
00404 _hi._ifinfo = NULL;
00405 Set_exp_phi(NULL);
00406 }
00407
00408
00409
00410
00411
00412
00413
00414
00415 BB_NODE::BB_NODE(const BB_NODE& old)
00416 {
00417 Clear();
00418 _id = old._id;
00419 _loopdepth = old._loopdepth;
00420 _rid_id = old._rid_id;
00421 _flags = old._flags;
00422 _kind = old._kind;
00423 _pred = old._pred;
00424 _succ = old._succ;
00425 _idom = old._idom;
00426 _ipdom = old._ipdom;
00427 _dom_bbs = old._dom_bbs;
00428 _pdom_bbs = old._pdom_bbs;
00429 _dom_dfs_id = old._dom_dfs_id;
00430 _dom_dfs_last = old._dom_dfs_last;
00431 _pdom_dfs_id = old._pdom_dfs_id;
00432 _pdom_dfs_last = old._pdom_dfs_last;
00433 _dom_frontier = old._dom_frontier;
00434 _rcfg_dom_frontier = old._rcfg_dom_frontier;
00435 _labels = old._labels;
00436 _firststmt = old._firststmt;
00437 _laststmt = old._laststmt;
00438
00439 _innermost = old._innermost;
00440 _hi = old._hi;
00441 _phi_list = old._phi_list;
00442 _iphi_list = old._iphi_list;
00443 _linenum = old._linenum;
00444 _u0 = old._u0;
00445 _u1 = old._u1;
00446 _u2 = old._u2;
00447 _u3 = old._u3;
00448 _u4 = old._u4;
00449 _u5 = old._u5;
00450 _u6 = old._u6;
00451 _u7 = old._u7;
00452 _u8 = old._u8;
00453 _u9 = old._u9;
00454 _u10 = old._u10;
00455 _u11 = old._u11;
00456 _u12 = old._u12;
00457 _u13 = old._u13;
00458 Set_exp_phi(NULL);
00459 }
00460
00461
00462 const char *
00463 BB_NODE::Kind_name( void ) const
00464 {
00465 switch ( Kind() ) {
00466 case BB_UNKNOWN:
00467 case BB_GOTO:
00468 case BB_LOGIF:
00469 case BB_VARGOTO:
00470 case BB_ENTRY:
00471 case BB_EXIT:
00472 case BB_DOSTART:
00473 case BB_DOEND:
00474 case BB_DOSTEP:
00475 case BB_DOHEAD:
00476 case BB_DOTAIL:
00477 case BB_IO:
00478 case BB_WHILEEND:
00479 case BB_REGIONSTART:
00480 case BB_REGIONEXIT:
00481 case BB_REPEATBODY:
00482 case BB_REPEATEND:
00483 case BB_SUMMARY:
00484 return BB_kind_name[Kind()];
00485 default:
00486 Warn_todo( "BB_NODE::Kind_name: unknown kind" );
00487 return "BAD BB_KIND";
00488 }
00489 }
00490
00491 void
00492 BB_NODE::Validate (FILE *fp) const
00493 {
00494
00495 Print_head(fp);
00496 if (Kind() != BB_ENTRY && Kind() != BB_REGIONSTART && Pred() == NULL)
00497 fprintf(fp, "Validate BB%d: has no predecessor (%s)\n", Id(),Kind_name());
00498 BB_LIST_ITER pred_iter(Pred());
00499 pred_iter.Validate_unique(fp);
00500 if (Kind() != BB_EXIT && Kind() != BB_REGIONEXIT && Succ() == NULL)
00501 fprintf(fp, "Validate BB%d: has no successor (%s)\n", Id(),Kind_name());
00502 BB_LIST_ITER succ_iter(Succ());
00503 succ_iter.Validate_unique(fp);
00504 }
00505
00506 WN *
00507 BB_NODE::Get_do_start() const
00508 {
00509
00510 FmtAssert(Kind() == BB_DOSTART, ("BB_NODE::Get_do_start, must be BB_DOSTART"));
00511
00512 return WN_start(Firststmt());
00513 }
00514 WN *
00515 BB_NODE::Get_do_end() const
00516 {
00517
00518 FmtAssert(Kind() == BB_DOEND, ("BB_NODE::Get_do_end, must be BB_DOEND"));
00519
00520 return WN_end(Firststmt());
00521 }
00522
00523 WN *
00524 BB_NODE::Get_do_step() const
00525 {
00526
00527 FmtAssert(Kind() == BB_DOSTEP, ("BB_NODE::Get_do_step, must be BB_DOSTEP"));
00528
00529 return WN_step(Firststmt());
00530 }
00531
00532
00533
00534 STMTREP *
00535 BB_NODE::Add_stmtnode(WN *wn, MEM_POOL *pool)
00536 {
00537 STMTREP *stmt = CXX_NEW(STMTREP(WN_opcode(wn)), pool);
00538 stmt->Set_wn(wn);
00539
00540
00541
00542
00543 if (_stmtlist.Head() == NULL)
00544 Set_linenum(WN_Get_Linenum(wn));
00545 else if (Linenum() == 0)
00546 Set_linenum(WN_Get_Linenum(wn));
00547 stmt->Set_bb(this);
00548 _stmtlist.Append(stmt);
00549
00550 return stmt;
00551 }
00552
00553
00554
00555 void
00556 BB_NODE::Append_stmtrep(STMTREP *stmt)
00557 {
00558 Is_True((Kind() != BB_REGIONSTART && Kind() != BB_ENTRY) ||
00559 (Kind() == BB_REGIONSTART &&
00560 (stmt->Op() == OPC_PRAGMA || stmt->Op() == OPC_XPRAGMA)),
00561 ("BB_NODE::Append_stmtrep(), inserting into a %s",Kind_name()));
00562 Warn_todo(
00563 "BB_NODE::Append_stmtrep: Guarantee it is added before the branch, if any");
00564 stmt->Set_bb(this);
00565 _stmtlist.Append(stmt);
00566 }
00567
00568
00569
00570 void
00571 BB_NODE::Prepend_stmtrep(STMTREP *stmt)
00572 {
00573 Is_True(Kind() != BB_REGIONSTART && Kind() != BB_ENTRY,
00574 ("BB_NODE::Prepend_stmtrep(), inserting into a %s (bb:%d)",
00575 Kind_name(), Id()));
00576
00577 STMTREP_ITER stmtrep_iter(&_stmtlist);
00578 STMTREP *tmp, *last_label = NULL;
00579 FOR_ALL_NODE(tmp, stmtrep_iter, Init())
00580 if (OPCODE_operator(tmp->Op()) == OPR_LABEL)
00581 last_label = tmp;
00582 else
00583 break;
00584 stmt->Set_bb(this);
00585 if (last_label == NULL)
00586 _stmtlist.Prepend(stmt);
00587 else
00588 _stmtlist.Insert_After(stmt, last_label);
00589 }
00590
00591
00592
00593 void
00594 BB_NODE::Insert_stmtrep_before(STMTREP *stmt, STMTREP *before_stmt)
00595 {
00596 Is_True(Kind() != BB_REGIONSTART && Kind() != BB_ENTRY,
00597 ("BB_NODE::Insert_stmtrep(), inserting into a %s",Kind_name()));
00598
00599 STMTREP_ITER stmtrep_iter(&_stmtlist);
00600 stmt->Set_bb(this);
00601 if (before_stmt == NULL)
00602 _stmtlist.Prepend(stmt);
00603 else
00604 _stmtlist.Insert_Before(stmt, before_stmt);
00605 }
00606
00607
00608 void
00609 BB_NODE::Insert_stmtrep_after(STMTREP *stmt, STMTREP *after_stmt)
00610 {
00611 STMTREP_ITER stmtrep_iter(&_stmtlist);
00612 stmt->Set_bb(this);
00613 if (after_stmt == NULL)
00614 _stmtlist.Append(stmt);
00615 else
00616 _stmtlist.Insert_After(stmt, after_stmt);
00617 }
00618
00619
00620
00621 void
00622 BB_NODE::Remove_stmtrep( STMTREP *stmt )
00623 {
00624 if ( stmt->Lhs() != NULL ) {
00625
00626
00627
00628 stmt->Lhs()->DecKidsUsecnt_rec();
00629 }
00630
00631 if ( stmt->Rhs() != NULL ) {
00632 stmt->Rhs()->DecUsecnt_rec();
00633 }
00634
00635 _stmtlist.Remove(stmt);
00636 }
00637
00638
00639
00640
00641
00642 void
00643 BB_NODE::Append_stmt_before_branch(STMTREP *stmt)
00644 {
00645 STMTREP *last_stmt = Last_stmtrep();
00646
00647 Is_True(Kind() != BB_REGIONSTART,
00648 ("BB_NODE::Append_stmt_before_branch, illegal insertion into BB_REGIONSTART"));
00649
00650 stmt->Set_linenum(last_stmt != NULL ? last_stmt->Linenum() : Linenum());
00651 if (last_stmt == NULL ||
00652 ! OPCODE_is_endsbb(last_stmt->Op()) ||
00653 OPCODE_is_call(last_stmt->Op())) {
00654 Stmtlist()->Append(stmt);
00655 stmt->Set_bb(this);
00656 }
00657 else {
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 if (last_stmt->Op() == OPC_GOTO ||
00672 last_stmt->Op() == OPC_TRUEBR ||
00673 last_stmt->Op() == OPC_FALSEBR ||
00674
00675
00676 Succ()->Next() != NULL) {
00677 Stmtlist()->Insert_Before(stmt, last_stmt);
00678 }
00679 else {
00680 Stmtlist()->Append(stmt);
00681 }
00682 stmt->Set_bb(this);
00683 }
00684 }
00685
00686
00687
00688
00689
00690
00691 STMTREP *
00692 BB_NODE::Branch_stmtrep(void)
00693 {
00694 STMTREP *branchstmt = Last_stmtrep();
00695 if ( branchstmt != NULL ) {
00696 if ( OPCODE_is_endsbb(branchstmt->Op()) )
00697 return ( branchstmt );
00698 if ( branchstmt->Op() == OPC_IO && Kind() == BB_IO )
00699 return ( branchstmt );
00700 if ( branchstmt->Op() == OPC_REGION && Kind() == BB_GOTO )
00701 return ( branchstmt );
00702 }
00703
00704 return ( NULL );
00705 }
00706
00707
00708
00709
00710
00711
00712
00713 STMTREP *
00714 BB_NODE::Label_stmtrep(void)
00715 {
00716 STMTREP *labelstmt = First_stmtrep();
00717 if ( labelstmt != NULL && labelstmt->Op() == OPC_LABEL ) {
00718 return ( labelstmt );
00719 }
00720
00721 return ( NULL );
00722 }
00723
00724
00725
00726
00727
00728
00729 void
00730 BB_NODE::Remove_label_stmtrep()
00731 {
00732 STMTREP *stmt;
00733 while ((stmt = Label_stmtrep()) != NULL)
00734 Remove_stmtrep(stmt);
00735 }
00736
00737
00738
00739
00740
00741 void
00742 BB_NODE::Add_label_stmtrep(MEM_POOL *pool)
00743 {
00744 Is_True( Label_stmtrep() == NULL,
00745 ("BB_NODE::Add_label_stmtrep: BB:%d has label statement", Id()) );
00746
00747 Is_True( Labnam() != 0, ("BB_NODE::Add_label_stmtrep: BB:%d has no label.", Id()));
00748
00749 STMTREP *new_label = CXX_NEW( STMTREP(OPC_LABEL), pool );
00750 new_label->Set_live_stmt();
00751 new_label->Init_Label( NULL, Labnam(), Linenum() );
00752 new_label->Set_bb(this);
00753 Prepend_stmtrep(new_label);
00754 }
00755
00756
00757 void
00758 BB_NODE::Add_label(CFG *cfg)
00759 {
00760 Is_True( Labnam() == 0, ("BB_NODE::Add_label: BB:%d has a label.", Id()));
00761 cfg->Append_label_map( cfg->Alloc_label(), this );
00762 }
00763
00764
00765
00766
00767
00768
00769
00770 WN *
00771 BB_NODE::Branch_wn(void) const
00772 {
00773 WN *branchwn = Laststmt();
00774 if ( branchwn != NULL ) {
00775 const OPCODE opc = WN_opcode(branchwn);
00776 if ( OPCODE_is_endsbb(opc) ) {
00777 return ( branchwn );
00778 }
00779 }
00780
00781 return ( NULL );
00782 }
00783
00784
00785
00786
00787
00788
00789
00790
00791 WN *
00792 BB_NODE::Label_wn(void) const
00793 {
00794 WN *labelwn = Firststmt();
00795 if ( labelwn != NULL && WN_opcode(labelwn) == OPC_LABEL ) {
00796 return ( labelwn );
00797 }
00798
00799 return ( NULL );
00800 }
00801
00802
00803
00804
00805
00806
00807 void
00808 BB_NODE::Insert_wn_after( WN *wn, WN *after_this )
00809 {
00810 Is_True(Kind() != BB_REGIONSTART && Kind() != BB_ENTRY,
00811 ("BB_NODE::Insert_wn_after(), inserting into a %s",Kind_name()));
00812
00813 if (Firststmt() == NULL) {
00814 Is_True( after_this == NULL,
00815 ("BB_NODE::Insert_wn_after: empty block, non-null after_this") );
00816
00817 Init_stmt(wn);
00818 }
00819 else {
00820 if ( after_this == NULL ) {
00821 WN_prev(Firststmt()) = wn;
00822 WN_prev(wn) = NULL;
00823 WN_next(wn) = Firststmt();
00824 Set_firststmt(wn);
00825 }
00826 else {
00827 WN_prev(wn) = after_this;
00828 if ( WN_next(after_this) != NULL ) {
00829 WN_next(wn) = WN_next(after_this);
00830 WN_prev(WN_next(wn)) = wn;
00831 }
00832 else {
00833 WN_next(wn) = NULL;
00834 Set_laststmt( wn );
00835 }
00836 WN_next(after_this) = wn;
00837 }
00838 }
00839 }
00840
00841
00842
00843
00844
00845
00846 void
00847 BB_NODE::Insert_wn_before( WN *wn, WN *before_this )
00848 {
00849 Is_True(Kind() != BB_REGIONSTART && Kind() != BB_ENTRY,
00850 ("BB_NODE::Insert_wn_before(), inserting into a %s",Kind_name()));
00851
00852 if (Firststmt() == NULL) {
00853 Is_True( before_this == NULL,
00854 ("BB_NODE::Insert_wn_before: empty block, non-null before_this"));
00855
00856 Init_stmt(wn);
00857 }
00858 else if ( before_this == NULL ) {
00859 WN_next(Laststmt()) = wn;
00860 WN_prev(wn) = Laststmt();
00861 WN_next(wn) = NULL;
00862 Set_laststmt(wn);
00863 }
00864 else {
00865 WN_next(wn) = before_this;
00866 if ( WN_prev(before_this) != NULL ) {
00867 WN_prev(wn) = WN_prev(before_this);
00868 WN_next(WN_prev(wn)) = wn;
00869 }
00870 else {
00871 WN_prev(wn) = NULL;
00872 Set_firststmt( wn );
00873 }
00874 WN_prev(before_this) = wn;
00875 }
00876 }
00877
00878
00879
00880
00881
00882 void
00883 BB_NODE::Append_wn_before_branch( WN *wn )
00884 {
00885 Insert_wn_before( wn, Branch_wn() );
00886 }
00887
00888
00889
00890
00891
00892
00893 static BOOL
00894 WN_is_call_related( const WN *wn )
00895 {
00896 const OPERATOR opr = WN_operator(wn);
00897
00898
00899 if ( opr == OPR_STID || opr == OPR_ISTORE || opr == OPR_ISTOREX ||
00900 opr == OPR_ISTBITS )
00901 {
00902 WN *val = WN_kid0(wn);
00903 const OPERATOR val_opr = WN_operator(val);
00904 if ( val_opr == OPR_LDID ) {
00905 ST *val_st = WN_st(val);
00906 if ( ST_class(val_st) == CLASS_PREG &&
00907 Preg_Is_Dedicated(WN_offset(val)) )
00908 {
00909 return TRUE;
00910 }
00911 else if (opr == OPR_STID) {
00912 Warn_todo("WN_is_call_related: Find_Slink_Symbol performance issue");
00913 if (WN_st(wn) == Find_Slink_Symbol(CURRENT_SYMTAB))
00914 {
00915
00916 return TRUE;
00917 }
00918 }
00919 }
00920 }
00921
00922
00923 return FALSE;
00924 }
00925
00926
00927
00928
00929
00930
00931 void
00932 BB_NODE::Prepend_wn_after_labels( WN *wn )
00933 {
00934 if (Firststmt() == NULL) {
00935 Init_stmt(wn);
00936 }
00937 else {
00938 WN *prev = NULL;
00939 WN *labwn;
00940
00941 for ( labwn = Firststmt(); labwn != NULL; labwn = WN_next(labwn) ) {
00942 const OPERATOR labopr = WN_operator(labwn);
00943 if ( labopr == OPR_LABEL ||
00944 labopr == OPR_PRAGMA ||
00945 labopr == OPR_COMMENT ||
00946 ( Callrel() && WN_is_call_related(labwn) )) {
00947 prev = labwn;
00948 }
00949 else {
00950 break;
00951 }
00952 }
00953
00954 Insert_wn_after( wn, prev );
00955 }
00956 }
00957
00958 void
00959 BB_NODE::Add_pragma(WN *wn, STMTREP *stmt, MEM_POOL *pool)
00960 {
00961 STMTREP *sr = CXX_NEW(STMTREP(OPC_PRAGMA), pool);
00962 sr->Set_orig_wn(wn);
00963 if (stmt) {
00964 sr->Set_bb(this);
00965 Stmtlist()->Insert_Before(sr, stmt);
00966 }
00967 else
00968 Append_stmtrep(sr);
00969 }
00970
00971
00972
00973 void
00974 BB_NODE::Compute_rcfg_itrdom_frontier( BB_NODE_SET *itrcd ) const
00975 {
00976 Is_True(itrcd!=NULL,("BB_NODE::Compute_rcfg_itrdom_frontier: NULL pointer"));
00977 BB_NODE *cdbb;
00978 BB_NODE_SET_ITER rcfg_iter;
00979 FOR_ALL_ELEM( cdbb, rcfg_iter, Init( Rcfg_dom_frontier() ) ) {
00980 if ( ! itrcd->MemberP( cdbb ) ) {
00981 itrcd->Union1D( cdbb );
00982 cdbb->Compute_rcfg_itrdom_frontier( itrcd );
00983 }
00984 }
00985 }
00986
00987
00988
00989
00990 BOOL
00991 BB_NODE::Is_empty()
00992 {
00993 if (First_stmtrep() == NULL) return TRUE;
00994 STMTREP *bb_branch = Branch_stmtrep();
00995 STMTREP *bb_label = Label_stmtrep();
00996 if (bb_branch == NULL) {
00997 return (bb_label == Last_stmtrep());
00998 } else {
00999 if (OPC_GOTO == bb_branch->Op()) {
01000 if (bb_label == NULL)
01001 return (bb_branch == First_stmtrep());
01002 else
01003 return (bb_label->Next() == bb_branch);
01004 } else
01005 return FALSE;
01006 }
01007 }
01008
01009 BOOL
01010 BB_NODE::Clonable(BOOL allow_loop_cloning, const BVECTOR *cr_vol_map)
01011 {
01012
01013
01014
01015 switch (Kind()) {
01016 case BB_ENTRY:
01017 case BB_REGIONSTART:
01018 case BB_REGIONEXIT:
01019 case BB_EXIT:
01020 case BB_VARGOTO:
01021 return FALSE;
01022
01023 case BB_DOSTART:
01024 case BB_DOEND:
01025 case BB_DOSTEP:
01026 case BB_DOHEAD:
01027 case BB_DOTAIL:
01028 case BB_WHILEEND:
01029 case BB_REPEATBODY:
01030 case BB_REPEATEND:
01031 if (!allow_loop_cloning) return FALSE;
01032 }
01033 if (Loop() && Loop()->Header()==this)
01034 if (!allow_loop_cloning) return FALSE;
01035
01036
01037 BB_LIST_ITER bb_pred_iter;
01038 BB_NODE *pred;
01039 FOR_ALL_ELEM( pred, bb_pred_iter, Init(Pred()) ) {
01040 if (!allow_loop_cloning) {
01041 if (pred->Kind() == BB_DOHEAD ||
01042 pred->Kind() == BB_DOSTART)
01043 return FALSE;
01044 }
01045 if (pred->Kind() == BB_VARGOTO)
01046 return FALSE;
01047 }
01048
01049
01050 if ( Labnam() > 0 && LABEL_addr_saved( Labnam() ) )
01051 return FALSE;
01052
01053
01054 STMTREP_ITER stmt_iter(Stmtlist());
01055 STMTREP *stmt;
01056 FOR_ALL_NODE(stmt, stmt_iter, Init()) {
01057 OPERATOR opr = OPCODE_operator(stmt->Op());
01058 if (opr == OPR_PREFETCH) return FALSE;
01059 if (opr == OPR_REGION) return FALSE;
01060 if (OPERATOR_is_volatile(opr)) return FALSE;
01061 if (cr_vol_map != NULL &&
01062 stmt->Contains_volatile_ref(*cr_vol_map)) return FALSE;
01063
01064
01065
01066
01067
01068
01069
01070 }
01071
01072 return TRUE;
01073 }
01074
01075 #if defined(TARG_SL)
01076 BOOL
01077 BB_NODE::Preds_or_succs_from_different_region(BOOL pred)
01078 {
01079 BB_LIST_ITER bb_iter;
01080 BB_LIST* bb_list;
01081 BB_NODE *bb;
01082 vector <mUINT16 >rid_stack;
01083
01084 rid_stack.clear();
01085
01086 bb_list = (pred) ? this->Pred() : this->Succ();
01087
01088 FOR_ALL_ELEM(bb, bb_iter, Init(bb_list)) {
01089 if(find(rid_stack.begin(), rid_stack.end(), bb->Rid_id()) == rid_stack.end())
01090 rid_stack.push_back(bb->Rid_id());
01091 }
01092
01093 if(rid_stack.size() > 1)
01094 return TRUE;
01095 else
01096 return FALSE;
01097
01098 }
01099 #endif
01100
01101
01102
01103
01104
01105
01106
01107 void
01108 BB_LOOP::Print(FILE *fp) const
01109 {
01110 if (Well_formed()) {
01111 fprintf(fp, "LOOP header BB%d\n", Header()->Id());
01112 fprintf(fp, "Natural loop: preheader %d, loopback %d, ",
01113 Preheader()->Id(),
01114 Loopback()->Id());
01115 if (Tail())
01116 fprintf(fp, "tail %d\n", Tail()->Id());
01117 else
01118 fprintf(fp, " no tail\n");
01119 fprintf(fp, "%s", Test_at_entry() ? "test-at-entry, " : "not test-at-entry, ");
01120 fprintf(fp, "%s", Test_at_exit() ? "test-at-exit, " : "not test-at-exit, ");
01121 fprintf(fp, "%s", Exit_early() ? "exit-early\n" : "not exit-early\n");
01122 fprintf(fp, "depth=%d, max_depth=%d\n", Depth(), Max_depth());
01123 } else
01124 fprintf(fp, "not a well-formed loop\n");
01125 if (End() != NULL) {
01126 fprintf(fp, "SCF: START %d, END %d, BODY %d, MERGE %d\n",
01127 Start()->Id(), End()->Id(), Body()->Id(), Merge()->Id());
01128 }
01129
01130 BOOL in_mainopt = Start() && Start()->Kind() == BB_DOHEAD;
01131 INT depth, i;
01132
01133 switch (_flags & LOOP_TYPES) {
01134 case LOOP_DO:
01135 depth = Body()->Loopdepth();
01136 for (i = 0; i < depth; i++) fprintf(fp, ".");
01137 fprintf(fp, "DO: body:%d depth:%d ", _body->Id(), depth);
01138 break;
01139 case LOOP_PRE_DO:
01140 depth = _end->Loopdepth();
01141 for ( i = 0; i < depth; i++) fprintf(fp, ".");
01142 fprintf(fp, "DO: cond:%d depth:%d ", _end->Id(), depth);
01143 break;
01144 case LOOP_WHILE:
01145 case LOOP_PRE_WHILE:
01146 depth = _body->Loopdepth();
01147 for ( i = 0; i < depth; i++) fprintf(fp, ".");
01148 fprintf(fp, "WHILE: body:%d depth:%d ", _body->Id(), depth);
01149 break;
01150 case LOOP_REPEAT:
01151 case LOOP_PRE_REPEAT:
01152 depth = _body->Loopdepth();
01153 for ( i = 0; i < depth; i++) fprintf(fp, ".");
01154 fprintf(fp, "REPEAT: body:%d depth:%d ", _body->Id(), depth);
01155 break;
01156 }
01157 fprintf(fp, "loop body set: ");
01158 if (Body_set())
01159 Body_set()->Print(fp);
01160 else
01161 fprintf(fp," null\n");
01162 fprintf(fp, "true loop body set: ");
01163 True_body_set()->Print(fp);
01164 fprintf(fp, "\n");
01165 fprintf(fp, "size estimate: %d\n", _size_estimate);
01166 }
01167
01168
01169 void
01170 BB_LIST::Print(FILE *fp) const
01171 {
01172 BB_LIST_ITER bb_list_iter(this);
01173 BB_NODE *tmp;
01174 FOR_ALL_ELEM(tmp, bb_list_iter, Init()) {
01175 if (tmp)
01176 fprintf(fp, "%d ",tmp->Id());
01177 }
01178 }
01179
01180 void
01181 BB_NODE::Print_head (FILE *fp) const
01182 {
01183
01184 fprintf(fp, "---- BB%d (RPO %d)", Id(),Rpo_id());
01185 if (Labnam())
01186 fprintf(fp, " (Lab%d)", Labnam());
01187 if (Kind() == BB_REGIONSTART || Kind() == BB_REGIONEXIT) {
01188 if (Regioninfo()) {
01189 Is_True(Regioninfo()->Rid() != NULL, ("BB_NODE::Print_head, NULL Rid"));
01190 fprintf(fp, " (%s %d)", Kind_name(), RID_id(Regioninfo()->Rid()) );
01191 } else
01192 fprintf(fp, " (%s***)", Kind_name() );
01193 } else
01194 fprintf(fp, " (%s)", Kind_name() );
01195 fprintf(fp, " %s", (Willexit())?"(e)":"(ne)");
01196 fprintf(fp, " LINE %d", Srcpos_To_Line(Linenum()));
01197 if (Haspragma())
01198 fprintf(fp, " (pragmas)" );
01199 if (Hascall())
01200 fprintf(fp, " (call)" );
01201 if ( Loopdepth() > 0 )
01202 fprintf(fp, " (nest:%d)", Loopdepth() );
01203 fprintf(fp, " (rid_id:%d)", Rid_id() );
01204 fprintf(fp, " (flag:%x)", Flag() );
01205
01206 fprintf(fp, "\n");
01207
01208 fprintf(fp, "Preds:");
01209 Pred()->Print(fp);
01210 fprintf(fp, "\n");
01211
01212 fprintf(fp, "Succs:");
01213 Succ()->Print(fp);
01214 fprintf(fp, "\n");
01215
01216 if (Falls_thru_to() != NULL) {
01217 fprintf(fp, "Fallthrough: %d\n", Falls_thru_to()->Id());
01218 }
01219
01220 if (Idom())
01221 fprintf(fp, "Idom : BB%d\n", Idom()->Id() );
01222 if (Ipdom())
01223 fprintf(fp, "Ipdom : BB%d\n", Ipdom()->Id() );
01224
01225 fprintf(fp, "dom_dfs_id(%u), dom_dfs_last(%u)\n",
01226 Dom_dfs_id(), Dom_dfs_last());
01227 fprintf(fp, "pdom_dfs_id(%u), pdom_dfs_last(%u)\n",
01228 Pdom_dfs_id(), Pdom_dfs_last());
01229
01230 if (Dom_bbs())
01231 {
01232 if (WOPT_Enable_SSA_PRE) {
01233 Dom_bbs()->Print(fp);
01234 fprintf(fp, "\n");
01235 }
01236 else {
01237 fprintf(fp, "Dom :");
01238 Dom_bbs()->Print(fp);
01239 fprintf(fp, "\n");
01240 }
01241 }
01242 if (Pdom_bbs())
01243 {
01244 fprintf(fp, "Pdom :");
01245 Pdom_bbs()->Print(fp);
01246 fprintf(fp, "\n");
01247 }
01248 if (Dom_frontier())
01249 {
01250 fprintf(fp, "Dom Frontier :");
01251 Dom_frontier()->Print(fp);
01252 fprintf(fp, "\n");
01253 }
01254 if (Rcfg_dom_frontier())
01255 {
01256 fprintf(fp, "RCFG Dom Frontier :");
01257 Rcfg_dom_frontier()->Print(fp);
01258 fprintf(fp, "\n");
01259 }
01260 }
01261
01262 void
01263 BB_NODE::Print_wn (FILE *fp) const
01264 {
01265 STMT_ITER wn_iter(_firststmt, _laststmt);
01266 wn_iter.Print(fp);
01267 }
01268
01269 void
01270 BB_NODE::Print (FILE *fp) const
01271 {
01272 Print_head(fp);
01273
01274 Print_wn(fp);
01275 if (Phi_list())
01276 Phi_list()->Print(fp);
01277
01278
01279 _stmtlist.Print(fp);
01280 }
01281
01282 void
01283 BB_NODE::PrintVis (void) const
01284 {
01285 BB_LIST_ITER bb_succ_iter(Succ());
01286 BB_NODE *succ;
01287 WN * wn;
01288
01289 #ifdef TARG_NVISA
01290
01291 STMT_ITER stmt_iter;
01292 FOR_ALL_ELEM(wn, stmt_iter, Init(Firststmt(), Laststmt())) {
01293 INTRINSIC id;
01294 if (WN_operator(wn) == OPR_INTRINSIC_CALL) {
01295 id = WN_intrinsic(wn);
01296 if (id == INTRN_SYNCHRONIZE) {
01297 fprintf(stdout, "BB%d[color=red]\n", Id());
01298 break;
01299 }
01300 }
01301 }
01302 #endif
01303 FOR_ALL_ELEM(succ, bb_succ_iter, Init()) {
01304 fprintf(stdout, " BB%d -> BB%d\n", Id(), succ->Id());
01305 }
01306 }
01307
01308 void
01309 BB_NODE::Print_ssa (FILE *fp) const
01310 {
01311
01312 Print_head(fp);
01313
01314 if (Phi_list())
01315 Phi_list()->Print(fp);
01316 _stmtlist.Print(fp);
01317 }
01318
01319 INT32 BB_NODE::Code_size_est(void) const
01320 {
01321 STMTREP_CONST_ITER stmt_iter(&_stmtlist);
01322 const STMTREP *stmt;
01323 INT32 size = 0;
01324 FOR_ALL_NODE(stmt, stmt_iter, Init()) {
01325 size++;
01326 if (OPERATOR_is_call(stmt->Opr()))
01327 size += 10;
01328 else if (stmt->Opr() == OPR_ISTORE) {
01329 if (stmt->Rhs()->Kind() == CK_OP && stmt->Rhs()->Opr() == OPR_SELECT)
01330 size += 19;
01331 }
01332 }
01333 return size;
01334 }
01335