00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "tracing.h"
00014 #include "error.h"
00015
00016 #include "mempool_allocator.h"
00017 #include "cxx_memory.h"
00018
00019 #include "op.h"
00020 #include "bb.h"
00021 #include "bb_set.h"
00022
00023 #include "gtn_universe.h"
00024 #include "gtn_set.h"
00025 #include "register.h"
00026 #include "gra_live.h"
00027
00028 #include "dominate.h"
00029 #include "cgtarget.h"
00030 #include "cg_dep_graph.h"
00031 #include "cg_loop.h"
00032
00033 #include "gcm_licm.h"
00034 #include "gcm.h"
00035 #include "loop_dce.h"
00036 #include "tag.h"
00037
00038 #include <list>
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 typedef enum{
00095 TOPO,
00096 REV_TOPO
00097 }DIRECTION;
00098
00099 class TOPO_ITER {
00100 private:
00101 MEM_POOL* _mp;
00102 DIRECTION _dir;
00103
00104 BB_SET* _visited;
00105
00106 LOOP_DESCR* _loop;
00107 BB* _head;
00108 BB* _tail;
00109 BB* _prolog;
00110 BB* _epilog;
00111
00112 BB* _cur;
00113 std::list<BB*> _seq;
00114 BB* _begin;
00115
00116 BOOL _well_formed;
00117 BOOL _sequential;
00118 public:
00119 TOPO_ITER (LOOP_DESCR* l, DIRECTION dir, MEM_POOL* mp);
00120 ~TOPO_ITER (void) {};
00121
00122 void topo_sort();
00123 void rev_topo_sort();
00124
00125 void set_begin() { _cur = _begin; }
00126 BB* begin() const { return _begin; }
00127 BB* end() const { return NULL; }
00128
00129 BB* operator*(void) const { return _cur; }
00130 TOPO_ITER& operator++ (void);
00131
00132
00133 BOOL well_formed(){ return _well_formed; }
00134 BOOL sequential(){ return _sequential; }
00135 };
00136
00137 TOPO_ITER :: TOPO_ITER (LOOP_DESCR* l, DIRECTION dir, MEM_POOL* mp)
00138 {
00139 _mp = mp;
00140 _dir = dir;
00141 _loop = l;
00142
00143 _cur = NULL;
00144 _seq.clear();
00145
00146 _visited = BB_SET_Create_Empty (252, _mp);
00147 _well_formed = TRUE;
00148 _sequential = TRUE;
00149
00150 if( _dir == TOPO )
00151 topo_sort();
00152 else
00153 rev_topo_sort();
00154
00155 }
00156
00157 void TOPO_ITER::topo_sort()
00158 {
00159
00160
00161 BB_SET *body = LOOP_DESCR_bbset(_loop);
00162 BB *epilog = NULL;
00163 BB *tail;
00164 BB *bb;
00165 FOR_ALL_BB_SET_members(body, bb) {
00166 BBLIST *succs;
00167 FOR_ALL_BB_SUCCS(bb, succs){
00168 BB *succ = BBLIST_item(succs);
00169 if( !BB_SET_MemberP(body, succ) ){
00170 if( epilog && succ != epilog ){
00171 _well_formed = FALSE;
00172 return;
00173 }else{
00174 epilog = succ;
00175 tail = bb;
00176 }
00177 }
00178 }
00179 }
00180
00181 BB* head = LOOP_DESCR_loophead(_loop);
00182
00183 std::list<BB*> working_list;
00184 working_list.push_back(head);
00185 _seq.push_back(head);
00186 _visited = BB_SET_Union1D (_visited, head, _mp);
00187
00188 while( !working_list.empty() ){
00189 _cur = working_list.front();
00190 working_list.pop_front();
00191
00192 BBLIST *s,*p;
00193 FOR_ALL_BB_SUCCS(_cur, s){
00194 if( (BBlist_Len(s) > 1) && (_cur != tail) )
00195 _sequential = FALSE;
00196
00197 BB* succ = BBLIST_item(s);
00198 if(!BB_SET_MemberP (body,succ))
00199 continue;
00200 if(BB_SET_MemberP(_visited,succ))
00201 continue;
00202
00203 BOOL all_pred_visited = TRUE;
00204 if(succ != head){
00205 FOR_ALL_BB_PREDS (succ, p) {
00206 BB* pred = BBLIST_item (p);
00207 if( (pred != _cur) && !BB_SET_MemberP(_visited, pred) ) {
00208 all_pred_visited = FALSE;
00209 break;
00210 }
00211 }
00212 }
00213
00214 if(all_pred_visited){
00215 _visited = BB_SET_Union1D (_visited, succ, _mp);
00216 _seq.push_back(succ);
00217 working_list.push_back(succ);
00218 }
00219 }
00220 }
00221
00222 _well_formed = ( _seq.size() == BB_SET_Size(LOOP_DESCR_bbset(_loop)) );
00223
00224 _cur = *_seq.begin();
00225 _begin = *_seq.begin();
00226
00227 return;
00228 }
00229
00230
00231 void TOPO_ITER::rev_topo_sort()
00232 {
00233
00234 BB *head = LOOP_DESCR_loophead(_loop);
00235 BB_SET *body = LOOP_DESCR_bbset(_loop);
00236 BB *epilog = NULL;
00237 BB *tail;
00238 BB *bb;
00239 FOR_ALL_BB_SET_members(body, bb) {
00240 BBLIST *succs;
00241 FOR_ALL_BB_SUCCS(bb, succs){
00242 BB *succ = BBLIST_item(succs);
00243 if( !BB_SET_MemberP(body, succ) ){
00244 if( epilog && succ != epilog ){
00245 epilog = NULL;
00246 _well_formed = FALSE;
00247 return;
00248 }
00249 epilog = succ;
00250 tail = bb;
00251 }
00252 }
00253 }
00254
00255
00256 _seq.push_back(tail);
00257
00258
00259 std::list<BB*> working_list;
00260 working_list.push_back(tail);
00261 _visited = BB_SET_Union1D (_visited, tail, _mp);
00262
00263 while( !working_list.empty() ){
00264 _cur = working_list.front();
00265 working_list.pop_front();
00266
00267 BBLIST *s,*p;
00268 FOR_ALL_BB_PREDS(_cur, s){
00269 if( (BBlist_Len(s) > 1) && (_cur != head) )
00270 _sequential = FALSE;
00271
00272 BB* pred = BBLIST_item(s);
00273 if(!BB_SET_MemberP (body,pred))
00274 continue;
00275 if(BB_SET_MemberP(_visited,pred))
00276 continue;
00277
00278
00279 BOOL all_succ_visited = TRUE;
00280 if( pred != tail ){
00281 FOR_ALL_BB_SUCCS (pred, p) {
00282 BB* succ = BBLIST_item (p);
00283 if( (succ != _cur) && !BB_SET_MemberP(_visited, succ)) {
00284 all_succ_visited = FALSE;
00285 break;
00286 }
00287 }
00288 }
00289
00290 if(all_succ_visited){
00291 _seq.push_back(pred);
00292 _visited = BB_SET_Union1D (_visited, pred, _mp);
00293 working_list.push_back(pred);
00294 }
00295 }
00296 }
00297
00298 _well_formed = (_seq.size() == BB_SET_Size(body));
00299
00300
00301 _cur = *_seq.begin ();
00302 _begin = *_seq.begin ();
00303
00304 return;
00305 }
00306
00307 TOPO_ITER &
00308 TOPO_ITER::operator++()
00309 {
00310 std::list< BB* >::const_iterator cit = _seq.begin();
00311 for( ; cit != _seq.end(); cit++ )
00312 if( _cur == *cit )
00313 break;
00314
00315 if( cit == _seq.end() )
00316 Is_True( 0, ("no post++ allowed for end()") );
00317
00318 cit++;
00319 if( cit == _seq.end() ){
00320 _cur = NULL;
00321 }else{
00322 _cur = *cit;
00323 }
00324
00325 return *this;
00326 }
00327
00328
00329
00330
00331
00332
00333 typedef struct {
00334 TN *dest;
00335 TN *src;
00336 OP *op;
00337 BOOL up_copy;
00338 }CopyRec;
00339
00340 class LOOP_RCE
00341 {
00342 private:
00343 MEM_POOL *_pool;
00344 LOOP_DESCR *_loop;
00345
00346 BB *_epilog;
00347 BB *_prolog;
00348 BB *_head;
00349 BB *_tail;
00350 BB_SET *_loop_bbs;
00351
00352 BOOL _well_formed;
00353 BOOL _trace;
00354
00355 std::list< OP* > _up_copies;
00356 std::list< OP* > _down_copies;
00357
00358 INT32 _chain_num;
00359 std::vector< std::vector<CopyRec> > _chains;
00360 std::vector<BOOL> _circular_chains;
00361
00362 INT32 _del_num;
00363 private:
00364 void Find_Epilog();
00365 void Find_Prolog();
00366
00367 void Find_Chain();
00368
00369 void Move_To_Prolog(INT32);
00370 void Move_To_Epilog(INT32);
00371
00372 public:
00373 LOOP_RCE( LOOP_DESCR *, MEM_POOL * );
00374 ~LOOP_RCE();
00375
00376 void Redundant_Copy_Elimination();
00377 };
00378
00379 LOOP_RCE::LOOP_RCE( LOOP_DESCR *l, MEM_POOL *p) :
00380 _loop(l), _pool(p),
00381 _well_formed(TRUE),
00382 _epilog(NULL),
00383 _prolog(NULL),
00384 _head(NULL),
00385 _tail(NULL),
00386 _chain_num(0),
00387 _del_num(0)
00388 {
00389 _head = LOOP_DESCR_loophead(_loop);
00390 _loop_bbs = LOOP_DESCR_bbset(_loop);
00391
00392 _trace = Get_Trace (TP_GCM, GCM_TRACE_RCE );
00393
00394 Find_Prolog();
00395 Find_Epilog();
00396 }
00397
00398 LOOP_RCE::~LOOP_RCE()
00399 {
00400 }
00401
00402
00403
00404
00405
00406
00407 void LOOP_RCE::Find_Prolog()
00408 {
00409 _prolog = Loop_Is_Zdl( _loop );
00410 if( _prolog ){
00411 if( _trace )
00412 fprintf( TFile, "this is zero delay loop\n" );
00413 return;
00414 }else{
00415 if( _trace )
00416 fprintf( TFile, "this is NOT zero delay loop\n" );
00417 }
00418
00419
00420 BBLIST* p;
00421 FOR_ALL_BB_PREDS( _head, p ){
00422 BB* pred = BBLIST_item (p);
00423 if( BB_SET_MemberP( _loop_bbs, pred ) )
00424 continue;
00425 if( _prolog ){
00426 _prolog = NULL;
00427 break;
00428 }else{
00429 _prolog = pred;
00430 }
00431 }
00432
00433 if( _prolog )
00434 Set_BB_gra_spill(_prolog);
00435
00436 if( _prolog && (BB_prev(_head) != _prolog) ){
00437 DevWarn( "prolog BB:%d not fall through to BB:%d. Ugly due to cflow",
00438 BB_id(_prolog), BB_id(_head) );
00439 DevWarn( "I don't do RCE for it" );
00440 _well_formed = FALSE;
00441 return;
00442 }else{
00443 if( !_prolog ){
00444 if( _trace )
00445 fprintf( TFile, "Create a new :\n" );
00446 _prolog = CG_LOOP_Gen_And_Prepend_To_Prolog( _head,_loop );
00447
00448 Set_BB_dom_set( _prolog, BS_Create_Empty( 2+PU_BB_Count+1, _pool ) );
00449 BS_UnionD( BB_dom_set(_prolog), BB_dom_set(_head), _pool );
00450 BS_Union1D( BB_dom_set(_prolog), BB_id(_prolog), _pool );
00451 BS_Difference1D( BB_dom_set(_prolog), BB_id(_head) );
00452
00453 Set_BB_pdom_set( _prolog, BS_Create_Empty( 2+PU_BB_Count+1, _pool ) );
00454 BS_UnionD( BB_pdom_set(_prolog), BB_pdom_set(_head), _pool );
00455 BS_Union1D( BB_pdom_set(_prolog), BB_id(_prolog), _pool );
00456 }
00457 if( _trace ){
00458 fprintf( TFile, "Prolog is :\n" );
00459 Print_BB_No_Srclines( _prolog );
00460 }
00461
00462 return;
00463 }
00464 }
00465
00466
00467
00468
00469
00470 void LOOP_RCE::Find_Epilog()
00471 {
00472
00473 BB *bb;
00474 FOR_ALL_BB_SET_members(_loop_bbs, bb) {
00475 BBLIST *succs;
00476 FOR_ALL_BB_SUCCS(bb, succs){
00477 BB *succ = BBLIST_item(succs);
00478 if( !BB_SET_MemberP(_loop_bbs, succ) ){
00479 if( _epilog && succ != _epilog ){
00480 _epilog = NULL;
00481 if( _trace )
00482 fprintf(TFile, "There are more than one epilogs");
00483 break;
00484 }
00485 _epilog = succ;
00486 _tail = bb;
00487 }
00488 }
00489 }
00490
00491 if( _epilog == NULL ){
00492 if( _trace )
00493 fprintf( TFile, "cannot find epilog" );
00494 _well_formed = FALSE;
00495 }else{
00496 if( _trace )
00497 fprintf( TFile, "epilog is BB:%i\n", BB_id(_epilog) );
00498 }
00499
00500 return;
00501 }
00502
00503
00504
00505
00506
00507
00508 static inline BOOL OP_not_in_list( OP *op, std::list<OP*> live_ops )
00509 {
00510 std::list<OP*>::const_iterator cit = live_ops.begin();
00511 for( ; cit != live_ops.end(); cit++ ){
00512 if( op == *cit )
00513 return FALSE;
00514 }
00515 return TRUE;
00516 }
00517
00518
00519
00520
00521
00522 static inline BOOL OP_is_copy( OP *op )
00523 {
00524 BOOL ret = OP_copy(op);
00525 #ifdef TARG_SL
00526 if( (OP_code(op)==TOP_c3_mvfacc) || (OP_code(op)==TOP_c3_mvtacc) ||
00527 (OP_code(op)==TOP_c3_mvfadd) || (OP_code(op)==TOP_c3_mvtadd) ){
00528 Is_True( OP_opnds(op)==2, ("opnd number is not 2, incorrect") );
00529 TN *shift_tn = OP_opnd(op, 1);
00530 if( TN_is_constant(shift_tn) && TN_value(shift_tn)==0 )
00531 ret |= TRUE;
00532 }
00533 #endif
00534 return ret;
00535 }
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562 static void Do_Non_Copy( OP *op, std::list<OP*> *copies )
00563 {
00564
00565
00566
00567
00568
00569 INT32 last_trip = 0;
00570
00571 BOOL removed = TRUE;
00572 while( removed ){
00573 removed = FALSE;
00574 std::list<OP*>::iterator it = copies->begin();
00575 for(INT32 i=0; i<last_trip; i++)
00576 it++;
00577 for( ; (it != copies->end()) ; it++ ){
00578 INT16 i=0;
00579 OP *copy = *it;
00580 for( i=0; i < OP_opnds(copy); i++ ){
00581 TN *tn = OP_opnd(copy, i);
00582 if( (tn != Zero_TN) &&
00583 !TN_is_constant(tn) &&
00584 (OP_Refs_TN(op, tn) || OP_Defs_TN(op,tn)) ){
00585 copies->remove(copy);
00586 removed = TRUE;
00587 break;
00588 }
00589 }
00590 for( i=0; !removed && (i < OP_results(copy)); i++ ){
00591 TN *tn = OP_result(copy, i);
00592 if( (tn != Zero_TN) &&
00593 !TN_is_constant(tn) &&
00594 ( OP_Refs_TN(op, tn) || OP_Defs_TN(op,tn) ) ){
00595 copies->remove(copy);
00596 removed = TRUE;
00597 break;
00598 }
00599 }
00600 if( removed )
00601 break;
00602 last_trip++;
00603 }
00604 }
00605 return;
00606 }
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617 static BOOL OP_Before_OP( OP *op_a, OP *op_b )
00618 {
00619 OP *op = OP_prev(op_b);
00620 while( op ){
00621 if( op == op_a )
00622 return TRUE;
00623 op = OP_prev(op);
00624 }
00625 return FALSE;
00626 }
00627
00628
00629
00630
00631
00632
00633 void LOOP_RCE::Find_Chain()
00634 {
00635 if( _trace ){
00636 fprintf(TFile, " the up exposed copies are (bottom up): \n" );
00637 }
00638
00639
00640 std::list<OP*>::const_iterator cit = _up_copies.begin();
00641 for( ; cit != _up_copies.end(); cit++ ){
00642 if( _trace )
00643 Print_OP_No_SrcLine(*cit);
00644
00645 CopyRec rec;
00646 rec.dest = OP_result(*cit, 0);
00647 rec.src = OP_opnd(*cit, 0);
00648 rec.op = *cit;
00649 rec.up_copy = TRUE;
00650
00651 INT chain_id = 0;
00652 BOOL appended = FALSE;
00653 for( ; chain_id < _chain_num; chain_id++ ){
00654 INT size = _chains[chain_id].size();
00655 if( size == 0 )
00656 continue;
00657 Is_True( !TN_is_constant(rec.dest) && !TN_is_constant(rec.src) &&
00658 !TN_is_constant(_chains[chain_id][size-1].dest) &&
00659 !TN_is_constant(_chains[chain_id][size-1].src),
00660 ("TN is constant in a copy OP") );
00661 if( TN_number(rec.dest) == TN_number(_chains[chain_id][size-1].src) ){
00662 _chains[chain_id].push_back(rec);
00663 appended = TRUE;
00664 }
00665 }
00666
00667 if( !appended ){
00668 _chain_num++;
00669 _chains.resize(_chain_num);
00670 _chains[_chain_num-1].push_back(rec);
00671 }
00672 }
00673
00674
00675
00676 if( _trace ){
00677 fprintf(TFile, " the down exposed copies are (bottom up): \n" );
00678 }
00679
00680 std::list<OP*>::const_reverse_iterator rcit;
00681 rcit = _down_copies.rbegin();
00682 INT32 i = _down_copies.size();
00683
00684 for( ; i > 0; i--, rcit++ ){
00685 if( _trace )
00686 Print_OP_No_SrcLine(*rcit);
00687
00688 CopyRec rec;
00689 rec.dest = OP_result(*rcit, 0);
00690 rec.src = OP_opnd(*rcit, 0);
00691 rec.op = *rcit;
00692 rec.up_copy = FALSE;
00693
00694 INT chain_id = 0;
00695 BOOL appended = FALSE;
00696 for( ; chain_id < _chain_num; chain_id++ ){
00697 INT size = _chains[chain_id].size();
00698 if( size == 0 )
00699 continue;
00700 Is_True( !TN_is_constant(rec.dest) && !TN_is_constant(rec.src) &&
00701 !TN_is_constant(_chains[chain_id][size-1].dest) &&
00702 !TN_is_constant(_chains[chain_id][size-1].src),
00703 ("TN is constant in a copy OP") );
00704 if( TN_number(rec.dest) == TN_number(_chains[chain_id][size-1].src) ){
00705 _chains[chain_id].push_back(rec);
00706 appended = TRUE;
00707 }
00708 }
00709
00710 if( !appended ){
00711 _chain_num++;
00712 _chains.resize(_chain_num);
00713 _chains[_chain_num-1].push_back(rec);
00714 }
00715 }
00716
00717
00718 INT32 j = 0;
00719
00720 for( i=0; i < _chain_num; i++ ){
00721 j = _chains[i].size();
00722 Is_True( j>0, ("chain size == 0") );
00723 OP *first_op = _chains[i][0].op;
00724 OP *last_op = _chains[i][j-1].op;
00725 TN *dest_tn = OP_result(first_op, 0);
00726 TN *src_tn = OP_opnd(last_op, 0);
00727
00728
00729 if( TN_number(dest_tn) == TN_number(src_tn) &&
00730 OP_Before_OP(first_op, last_op) ){
00731 _circular_chains.push_back(TRUE);
00732 }else
00733 _circular_chains.push_back(FALSE);
00734 }
00735
00736 if( _trace ){
00737 fprintf( TFile, " --- The Chains are : --- \n" );
00738 for( i=0 ; i < _chain_num; i++ ){
00739 fprintf( TFile, " the %ith chain : \n", i );
00740 for(j=0 ; j < _chains[i].size(); j++ ){
00741 fprintf( TFile, "%s,",
00742 _chains[i][j].up_copy ? "up exposed" : "down exposed" );
00743 Print_OP_No_SrcLine( _chains[i][j].op );
00744 }
00745 if( _circular_chains[i] )
00746 fprintf(TFile, " is circular \n" );
00747 else
00748 fprintf(TFile, " is NOT circular \n" );
00749 }
00750 }
00751 }
00752
00753
00754
00755
00756
00757
00758 static void Update_Liveness( BB *src_bb, BB *tgt_bb, OP *op, BOOL upward )
00759 {
00760 INT32 i;
00761 for( i=0; i < OP_opnds(op); i++ ){
00762 TN *tn = OP_opnd(op,i);
00763 if( TN_is_constant(tn) )
00764 continue;
00765 if( !TN_is_global_reg(tn) )
00766 GTN_UNIVERSE_Add_TN(tn);
00767
00768 if( upward ){
00769 GRA_LIVE_Add_Live_Use_GTN(tgt_bb, tn);
00770 GRA_LIVE_Add_Live_Out_GTN(tgt_bb, tn);
00771 }else{
00772 GRA_LIVE_Add_Live_In_GTN(tgt_bb, tn);
00773 GRA_LIVE_Add_Live_Use_GTN(tgt_bb, tn);
00774 GRA_LIVE_Add_Defreach_In_GTN(tgt_bb, tn);
00775
00776 GRA_LIVE_Add_Live_Out_GTN(src_bb, tn);
00777 GRA_LIVE_Add_Defreach_Out_GTN(src_bb, tn);
00778 }
00779 }
00780
00781 for( i=0; i < OP_results(op); i++ ){
00782 TN *tn = OP_result(op,i);
00783 if( TN_is_constant(tn) )
00784 continue;
00785 if( !TN_is_global_reg(tn) )
00786 GTN_UNIVERSE_Add_TN(tn);
00787
00788 if( upward ){
00789 GRA_LIVE_Add_Defreach_Out_GTN(tgt_bb, tn);
00790 GRA_LIVE_Add_Defreach_In_GTN(src_bb, tn);
00791 }else{
00792 }
00793 }
00794 }
00795
00796
00797
00798
00799 void LOOP_RCE::Move_To_Prolog(INT32 chain_id)
00800 {
00801 INT32 size = _chains[chain_id].size();
00802 INT32 i = size-1;
00803 for( ; i >= 0; i-- ){
00804 OP *op = _chains[chain_id][i].op;
00805 if( _chains[chain_id][i].up_copy ){
00806 Is_True( !BB_zdl_body(_prolog), ("prolog is tail BB of a ZDL") );
00807 BB *src_bb = OP_bb(op);
00808 BB_Remove_Op( src_bb, op );
00809
00810
00811 OP *loop_op = BB_loop_op(_prolog);
00812 if( loop_op )
00813 BB_Insert_Op_Before( _prolog, loop_op, op );
00814 else
00815 BB_Append_Op( _prolog, op );
00816
00817 Update_Liveness( src_bb, _prolog, op, TRUE );
00818 _del_num++;
00819 if( _trace ){
00820 fprintf( TFile, "move following OP to prolog:\n" );
00821 Print_OP_No_SrcLine(op);
00822 }
00823 }
00824 }
00825 }
00826
00827
00828
00829
00830 void LOOP_RCE::Move_To_Epilog(INT32 chain_id)
00831 {
00832 INT32 size = _chains[chain_id].size();
00833 INT32 i = 0;
00834 for( ; i < size; i++ ){
00835 OP *op = _chains[chain_id][i].op;
00836 if( !_chains[chain_id][i].up_copy ){
00837 BB *src_bb = OP_bb(op);
00838 BB_Remove_Op( src_bb, op );
00839 BB_Prepend_Op( _epilog, op );
00840 Update_Liveness( src_bb, _epilog, op, FALSE );
00841 _del_num++;
00842 if( _trace ){
00843 fprintf( TFile, "move following OP to epilog:\n" );
00844 Print_OP_No_SrcLine(op);
00845 }
00846 }
00847 }
00848 }
00849
00850
00851
00852
00853 void LOOP_RCE::Redundant_Copy_Elimination()
00854 {
00855 if( !_well_formed )
00856 return;
00857
00858 TOPO_ITER topo_it(_loop, TOPO, _pool);
00859 TOPO_ITER r_topo_it(_loop, REV_TOPO, _pool);
00860
00861 if( !topo_it.well_formed() || !topo_it.sequential() )
00862 return;
00863
00864 if( _trace )
00865 fprintf( TFile, "==== begin LOOP Redundant Copy Elimination ====\n" );
00866
00867
00868
00869
00870 TN_SET *live_tns;
00871 GTN_SET *epilog_live_in = BB_live_in(_epilog);
00872 live_tns = TN_SET_Create_Empty( Last_TN + 1, _pool );
00873 for( TN *tn = GTN_SET_Choose(epilog_live_in);
00874 tn != GTN_SET_CHOOSE_FAILURE;
00875 tn = GTN_SET_Choose_Next(epilog_live_in,tn))
00876 {
00877 FmtAssert(TN_is_global_reg(tn),("TN%d is not global",TN_number(tn)));
00878 live_tns = TN_SET_Union1D(live_tns, tn, _pool);
00879 }
00880
00881 if( _trace ){
00882 fprintf( TFile, "the bbs in loop are:" );
00883 BB_SET_Print( _loop_bbs, TFile );
00884
00885 fprintf( TFile, "\nthe live in TNs of epilog:" );
00886 TN_SET_Print( live_tns, TFile );
00887 fprintf( TFile, "\n" );
00888 }
00889
00890
00891
00892
00893
00894
00895
00896 BB *bb = topo_it.begin();
00897 topo_it.set_begin();
00898 for( ; *topo_it != topo_it.end(); ++topo_it ){
00899 bb = *topo_it;
00900 OP *op;
00901 FOR_ALL_BB_OPs(bb, op){
00902 if( OP_is_copy(op) ){
00903 _down_copies.push_back(op);
00904 }else
00905 Do_Non_Copy(op, &_down_copies);
00906 }
00907 }
00908
00909
00910 bb = r_topo_it.begin();
00911 r_topo_it.set_begin();
00912 for( ; *r_topo_it != r_topo_it.end(); ++r_topo_it ){
00913
00914 bb = *r_topo_it;
00915 OP *op;
00916 FOR_ALL_BB_OPs_REV(bb, op){
00917 if( OP_is_copy(op) )
00918 _up_copies.push_back(op);
00919 else
00920 Do_Non_Copy(op, &_up_copies);
00921 }
00922 }
00923
00924
00925 Find_Chain();
00926
00927
00928
00929
00930 INT32 chain_id = 0;
00931 for( ; chain_id < _chain_num; chain_id++ ){
00932 if( !_circular_chains[chain_id] )
00933 continue;
00934
00935
00936
00937
00938 Move_To_Prolog( chain_id );
00939
00940
00941 Move_To_Epilog( chain_id );
00942 }
00943
00944 if( _trace ){
00945 fprintf( TFile, " Total delete OPs: %i\n", _del_num );
00946 fprintf( TFile, "==== end LOOP Redundant Copy Elimination ====\n" );
00947 }
00948 }
00949
00950
00951
00952
00953 void LOOP_Redundant_Copy_Elimination( LOOP_DESCR *loop, MEM_POOL *pool )
00954 {
00955 LOOP_RCE loop_rce(loop, pool);
00956 loop_rce.Redundant_Copy_Elimination();
00957 }