Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

list_scheduler.C

Go to the documentation of this file.
00001 #include <iostream.h>
00002 #include <fstream.h>
00003 #include <time.h>
00004 #include <stl.h>
00005 #include "lego.H"
00006 #include "legoUtil.H"
00007 #include "legoAn.H"
00008 #include "scheduling_utilities.H"
00009 #include "list_scheduler.H"
00010 #include "lmdes.h"
00011 #include "RU_manager.h"
00012 #include "l_alloc_new.h"
00013 
00014 
00015 /* Debugging support, courtesy of Sumedh */ 
00016 //   #define temperr(_s_)  cerr << _s_ 
00017    #define temperr(_s_) 
00018 //   #define dperr(_s_)  cerr << _s_ 
00019    #define dperr(_s_) 
00020 //   #define ddderr(_s_)  cerr << _s_ 
00021    #define ddderr(_s_) 
00022 //#define _LIST_SCHEDULER_DEBUG_ 
00023 #if defined (_LIST_SCHEDULER_DEBUG_) 
00024    #define derr(_s_)  cerr << _s_ 
00025    #define dderr(_s_)  cerr << _s_ 
00026 #else 
00027    #define derr(_s_) 
00028    #define dderr(_s_) 
00029 #endif 
00030 
00031 
00032 #define       YES     1
00033 #define       NO      0
00034 
00035 extern L_Alloc_Pool    *Operand_ready_pool;
00036 chains* Chains;
00037 int MaxRegNum;
00038 int MaxOpId;
00039 int ReDoLiveVarsNextTreegion = FALSE;
00040 int live_call_number = 1;
00041 int rdef_call_number = 1;
00042 time_t now, then;
00043 double elapsed, elapsed_c;
00044 int *operand_ready_times;
00045 int *true_operand_ready_times;
00046 int *true_dsld_operand_ready_times; 
00047 int *dsld_operand_ready_times; 
00048 int ReDoLiveVarsAfterGlobal = FALSE;
00049 int MergeProblemDuringGlobal = FALSE;
00050 extern int dom_parallel_ops, copy_ops_added, speculated_ops;
00051 extern int liveness_renamed_ops, falsedep_renamed_ops, combine_renamed_ops;
00052 extern int liveness_calls, rdef_calls; 
00053 extern int downward_motion_ops, unspeculated_ops, unspeculated_pbr_ops, dead_ops;
00054 extern double downward_dynamic_op_reduction, combine_dynamic_op_reduction;
00055 extern double speculative_dynamic_op_increase, multiway_dynamic_op_reduction;
00056 extern double copy_dynamic_op_increase;
00057 extern int total_branch_multiops, total_branch_ops, blocks_removed; 
00058 int temp_dom_op_count=0;
00059 
00060 //HZ: for debug 
00061 legoOp *debug_op;
00062 
00063 
00064 
00065 // DescendantofBlock: Returns YES if this operation 
00066 // belongs to a block which is a descendant of the 
00067 // block identified by a pointer of value input_block_int. 
00068 int list_scheduler::DescendantofBlock( int input_block_int, legoOp *op )
00069 {
00070   
00071   legoRegion *block_ptr, *root_block_ptr;
00072   regionList *region_list;
00073   int block_int;
00074 
00075   derr( ">> DescendantofBlock\n" );
00076 
00077   block_ptr = (legoRegion *) op->GetParentBlockPtr();
00078   block_int = (int) block_ptr;
00079   
00080   root_block_ptr = ((legoTreegion*) Region)->GetRoot();
00081   while ( (block_int != input_block_int) && (block_ptr != NULL) ) {
00082     if (block_ptr == root_block_ptr)
00083       break;
00084     region_list = block_ptr->GetParents();
00085     // blocks in a treegion have one and only one parent, except root block 
00086     // which has no parents. 
00087     if (region_list != NULL) {
00088       block_ptr = region_list->GetRegionPtr();
00089       block_int = (int) block_ptr;
00090     }
00091     else {
00092       block_ptr = NULL;
00093       block_int = 0;
00094     }
00095   }
00096   
00097   if (block_int == input_block_int) {
00098     derr( "... op is a descendant of input block pointer\n" );
00099     return TRUE;
00100   }
00101   else {
00102     derr( "... op is NOT a descendant of input block pointer\n" );
00103     return FALSE;
00104   }
00105 }
00106 
00107 
00108 // DescendantofCurBlockPtr: Returns YES if this operation 
00109 // belongs to a block which is a descendant of the 
00110 // block identified by the current_block_int attribute. 
00111 int list_scheduler::DescendantofCurBlockPtr( vector < BigListElement >::iterator Node )
00112 {
00113   
00114   legoRegion *block_ptr, *root_block_ptr;
00115   regionList *region_list;
00116   int block_int;
00117 
00118   derr( ">> DescendantofCurBlockPtr\n" );
00119 
00120   block_ptr = (legoRegion *) (*Node).GetOp()->GetParentBlockPtr();
00121   block_int = (int) block_ptr;
00122   
00123   //HZ: update to handle the case when the Reion is a BB instead of a Treegion
00124   if(Region->GetRegionType() != RT_BB)
00125       root_block_ptr = ((legoTreegion*) Region)->GetRoot();
00126   else
00127       root_block_ptr = Region;
00128   while ( (block_int != current_block_int) && (block_ptr != NULL) ) {
00129     if (block_ptr == root_block_ptr)
00130       break;
00131     region_list = block_ptr->GetParents();
00132     // blocks in a treegion have one and only one parent, except root block 
00133     // which has no parents. 
00134     if (region_list != NULL) {
00135       block_ptr = region_list->GetRegionPtr();
00136       block_int = (int) block_ptr;
00137     }
00138     else {
00139       block_ptr = NULL;
00140       block_int = 0;
00141     }
00142   }
00143   
00144   if (block_int == current_block_int) {
00145     derr( "... op is a descendant of current block pointer\n" );
00146     return TRUE;
00147   }
00148   else {
00149     derr( "... op is NOT a descendant of current block pointer\n" );
00150     return FALSE;
00151   }
00152 }
00153 
00154 
00155 // TruePredecessorsScheduled: Returns YES if all predecessors of an 
00156 // operation have been scheduled, returns NO otherwise
00157 // TruePredecessorsScheduled: Same as PredecessorsScheduled except that it 
00158 // ignores anti/output-deps
00159 int list_scheduler::TruePredecessorsScheduled( vector < BigListElement >::iterator Node )
00160 {
00161   vector < SmallListElement >::iterator Front, Back;
00162   int PredecessorId,
00163   PredecessorIssueTime;
00164   enum edgeTypes DepType;
00165   
00166   derr( ">> CheckDeps\n" );
00167   if ( (*Node).NumPredecessors() == 0 ) {
00168     derr( "   Entry Node <<\n" );
00169     return YES;
00170   }
00171   
00172   // If predecessors exist check to see if they are scheduled yet
00173   for ( Front = (*Node).Predecessors->begin(),
00174        Back = (*Node).Predecessors->end(); Front != Back; Front++ ) {
00175      
00176     DepType = (*Front).GetDependencyType();
00177     if ((DepType != ET_REGOUT) && (DepType != ET_REGANTI)) {
00178       // Get the Op id of the current predecessor, so we can search for it
00179       PredecessorId = (*Front).GetOp()->GetOpId();
00180       derr( "   checking if Predecessor op " << PredecessorId << " has been scheduled...\n" );
00181       
00182       // Ok to consider unscheduled ET_MEM predecessors to load ops (unless 
00183       // already flagged as "load_verify")
00184       if (!((DepType == ET_MEM) && 
00185             IsLoadOp((*Node).GetOp()) && 
00186             (FindLcAttribute( "load_verify", (*Node).GetOp() ) == NULL))) {
00187         // If the dominating Op is unscheduled, dependencies should
00188         // be enforced.
00189         if ( (PredecessorIssueTime=(*Front).GetOp()->GetSchedTime())
00190             == UNSCHEDULED ) {
00191           derr( "... a Predecessor op is unscheduled\n" );
00192           return NO;
00193         }
00194       }
00195     }
00196   }
00197   derr( "... all Predecessor ops are scheduled\n" );
00198   return YES;
00199   
00200 }
00201 
00202 
00203 // PredecessorsScheduled: Returns YES if all predecessors of an 
00204 // operation have been scheduled, returns NO otherwise
00205 int list_scheduler::PredecessorsScheduled( vector < BigListElement >::iterator Node )
00206 {
00207   vector < SmallListElement >::iterator Front, Back;
00208   int PredecessorId,
00209   PredecessorIssueTime;
00210   
00211   
00212   derr( ">> CheckDeps\n" );
00213   if ( (*Node).NumPredecessors() == 0 ) {
00214     derr( "   Entry Node <<\n" );
00215     return YES;
00216   }
00217   
00218   // If predecessors exist check to see if they are scheduled yet
00219   for ( Front = (*Node).Predecessors->begin(),
00220        Back = (*Node).Predecessors->end(); Front != Back; Front++ ) {
00221     
00222     // Get the Op id of the current predecessor, so we can search for it
00223     PredecessorId = (*Front).GetOp()->GetOpId();
00224     derr( "   checking if Predecessor op " << PredecessorId << " has been scheduled...\n" );
00225     
00226     // In the dominating Op is unscheduled, dependencies should
00227     // be enforced.
00228     if ( (PredecessorIssueTime=(*Front).GetOp()->GetSchedTime())
00229         == UNSCHEDULED ) {
00230       derr( "... a Predecessor op is unscheduled\n" );
00231       return NO;
00232     }
00233   }
00234   derr( "... all Predecessor ops are scheduled\n" );
00235   return YES;
00236   
00237 }
00238 
00239 
00240 // BuildReadyTimes: Finds the ReadyTimes for each operand of an unscheduled
00241 // operation that will now be a Candidate for scheduling
00242 void list_scheduler::BuildReadyTimes( vector < BigListElement >::iterator Node,
00243                                      int IssueCycle )
00244 {
00245   vector < SmallListElement >::iterator Front, Back;
00246   int i, indexi, j, indexj, ready_time, op_latency, latency_count, operand_found;
00247   int PredecessorIssueTime;
00248   enum edgeTypes Dependency;
00249   legoOprd *destoprd, *srcoprd, *predoprd, *destoprd2;
00250   RU_Info* ru_info;
00251   
00252   operand_ready_times = (int *) L_alloc(Operand_ready_pool);
00253   true_operand_ready_times = (int *) L_alloc(Operand_ready_pool);
00254   true_dsld_operand_ready_times = (int *) L_alloc(Operand_ready_pool);
00255   dsld_operand_ready_times = (int *) L_alloc(Operand_ready_pool);
00256   
00257   // initialize operand_ready_times to zero
00258   latency_count = mdes_latency_count();
00259   for (i = 0; i < latency_count; i++) {
00260     operand_ready_times[i] = 0;
00261     true_operand_ready_times[i] = 0;
00262     true_dsld_operand_ready_times[i] = 0;
00263     dsld_operand_ready_times[i] = 0;
00264   }
00265   
00266   for ( Front = (*Node).Predecessors->begin(),
00267        Back = (*Node).Predecessors->end(); Front != Back; Front++ ) {
00268     switch (Dependency=(*Front).GetDependencyType()) {
00269     case (ET_CNTL): 
00270       ru_info = (*Front).GetOp()->GetRUInfoPtr();
00271       indexi = operand_index (MDES_SYNC_OUT, 1);
00272       op_latency = mdes_operand_latency(ru_info->proc_opc, ru_info->selected_alt->id, 
00273                                         indexi);
00274       // Branch latency now zero to enable Mulit-Way branching, but C_MERGE 
00275       // ops still require a latency of one for branches. 
00276       if ((*Node).GetOp()->GetOpcode() == C_MERGE)
00277         ready_time = (*Front).GetOp()->GetSchedTime() + op_latency + 1; 
00278       else
00279         ready_time = (*Front).GetOp()->GetSchedTime() + op_latency; 
00280       indexj = operand_index (MDES_SYNC_IN, 1);      
00281       derr( "** Control Dependency Found:   from Op" << (*Front).GetOp()->GetOpId() << " to Op" 
00282            << (*Node).GetOp()->GetOpId() << " with ready_time = " << ready_time << "\n");
00283       if ( ready_time > operand_ready_times[indexj])
00284         operand_ready_times[indexj] = ready_time;
00285       if ( ready_time > true_operand_ready_times[indexj])
00286         true_operand_ready_times[indexj] = ready_time;
00287       if ( ready_time > true_dsld_operand_ready_times[indexj])
00288         true_dsld_operand_ready_times[indexj] = ready_time;
00289       if ( ready_time > dsld_operand_ready_times[indexj])
00290         dsld_operand_ready_times[indexj] = ready_time;
00291       break;
00292     case (ET_MEM): 
00293       // Check MEM deps. If a PlayDoh architecture is used, allow issue
00294       // of dependent Ops. Otherwise treat as a flow dep.
00295       if ( PlayDoh == 1 ) {
00296         derr( "...PlayDoh arch being used" );
00297         PredecessorIssueTime=(*Front).GetOp()->GetSchedTime();
00298         if ( ! ( Machine->isStoreOp( (*Node).GetOp() )
00299                 // mdj 10/13/98 DagEntries appear to change when copy ops are 
00300                 // added to the priority list use the op directly here to 
00301                 // avoid this problem. 
00302                 //&& Machine->isBranchOp( (*Front).GetDagEntry()->GetOp() )
00303                 && Machine->isBranchOp( (*Front).GetOp() )
00304                 && (PredecessorIssueTime == UNSCHEDULED || PredecessorIssueTime == IssueCycle) ) ) {
00305           derr( ", no mem-dep\n" );
00306           break;
00307         }
00308         derr( ", store speculation disallowed\n" );
00309       } // if - PlayDoh arch
00310       if ((*Front).GetOp()->GetSchedTime() == UNSCHEDULED) { 
00311         indexj = operand_index (MDES_SYNC_IN, 0);
00312         operand_ready_times[indexj] = 9999;
00313         true_operand_ready_times[indexj] = 9999;
00314         if (!IsLoadOp((*Node).GetOp()) || 
00315             (FindLcAttribute( "load_verify", (*Node).GetOp() ) != NULL)) {
00316           true_dsld_operand_ready_times[indexj] = 9999;
00317           dsld_operand_ready_times[indexj] = 9999;
00318         }
00319       }
00320       else {
00321         ru_info = (*Front).GetOp()->GetRUInfoPtr();
00322         indexi = operand_index (MDES_SYNC_OUT, 0);
00323         op_latency = mdes_operand_latency(ru_info->proc_opc, ru_info->selected_alt->id, indexi);
00324         if ( Machine->isRealOp( (*Front).GetOp() ) )
00325           ready_time = (*Front).GetOp()->GetSchedTime() + op_latency + BypassLatency; 
00326         else 
00327           ready_time = (*Front).GetOp()->GetSchedTime() + op_latency; 
00328         indexj = operand_index (MDES_SYNC_IN, 0);      
00329         derr( "** Memory Dependency Found:   from Op" << (*Front).GetOp()->GetOpId() << " to Op" 
00330              << (*Node).GetOp()->GetOpId() << " with ready_time = " << ready_time << "\n");
00331         if ( ready_time > operand_ready_times[indexj])
00332           operand_ready_times[indexj] = ready_time;
00333         if ( ready_time > true_operand_ready_times[indexj])
00334           true_operand_ready_times[indexj] = ready_time;
00335         if (!IsLoadOp((*Node).GetOp()) || 
00336             (FindLcAttribute( "load_verify", (*Node).GetOp() ) != NULL)) {
00337           if ( ready_time > true_dsld_operand_ready_times[indexj])
00338             true_dsld_operand_ready_times[indexj] = ready_time;
00339           if ( ready_time > dsld_operand_ready_times[indexj])
00340             dsld_operand_ready_times[indexj] = ready_time;
00341         }
00342       }
00343       break;
00344     case (ET_REGFLOW):
00345       operand_found = FALSE;
00346       // determine operand_ready_times for the src operands (flow dependencies)
00347       for (j = 0, destoprd = (*Front).GetOp()->GetDestOprdPtr(); destoprd != NULL; 
00348            destoprd = destoprd->GetNextOprdPtr(), j++) {
00349         for (i = 0, srcoprd = (*Node).GetOp()->GetSrcOprdPtr(); srcoprd != NULL; 
00350              srcoprd = srcoprd->GetNextOprdPtr(), i++) {
00351           if (((destoprd->GetOprdType() == OT_MACRO) &&
00352                (srcoprd->GetOprdType() == OT_MACRO) &&
00353                (destoprd->GetOprdRegNum() == srcoprd->GetOprdRegNum())) ||
00354               
00355               ((destoprd->GetOprdType() == OT_REG) &&
00356                (srcoprd->GetOprdType() == OT_REG) &&
00357                (destoprd->GetOprdRegType() == srcoprd->GetOprdRegType()) &&
00358                (destoprd->GetOprdRegNum() == srcoprd->GetOprdRegNum()) &&
00359                (destoprd->GetOprdFileType() == srcoprd->GetOprdFileType()))) {
00360             operand_found = TRUE;
00361             ru_info = (*Front).GetOp()->GetRUInfoPtr();
00362             indexj = operand_index (MDES_DEST, j);
00363             if (IsLoadOp((*Front).GetOp()) && 
00364                 (FindLcAttribute( "load_verify", (*Front).GetOp() ) != NULL)) {
00365                 
00366                 //HZ: Here Matt assumed that load verify will take 1 cycle.
00367                 // However this "load_verify" attribute is not set and cleared correctly, so
00368                 // there would be situation like
00369                 //  r1 <- ld(r10) and r11 <- r1 in one multiop after scheduling, 
00370                 // which is wrong
00371                 // Quick fix: as we currently not generating the recovery code.
00372                 //  let's change all ld's latency back to 2 cycles.
00373               //op_latency = 1;
00374                 op_latency = 2;
00375             }
00376             else {
00377               op_latency = mdes_operand_latency(ru_info->proc_opc, ru_info->selected_alt->id, indexj);
00378             }
00379             if ( Machine->isRealOp( (*Front).GetOp() ) )
00380               ready_time = (*Front).GetOp()->GetSchedTime() + op_latency + BypassLatency; 
00381             else 
00382               ready_time = (*Front).GetOp()->GetSchedTime() + op_latency; 
00383             indexi = operand_index (MDES_SRC, i);
00384             derr( "** Flow Dependency Found:   from Op" << (*Front).GetOp()->GetOpId() << " to Op" 
00385                  << (*Node).GetOp()->GetOpId() << " with ready_time = " << ready_time << "\n");
00386             if ( ready_time > operand_ready_times[indexi])
00387               operand_ready_times[indexi] = ready_time;
00388             if ( ready_time > true_operand_ready_times[indexi])
00389               true_operand_ready_times[indexi] = ready_time;
00390             if ( ready_time > true_dsld_operand_ready_times[indexi])
00391               true_dsld_operand_ready_times[indexi] = ready_time;
00392             if ( ready_time > dsld_operand_ready_times[indexi])
00393               dsld_operand_ready_times[indexi] = ready_time;
00394           }
00395         }
00396         
00397         // determine operand_ready_times for the pred oprds (flow dependencies)
00398         for (i = 0, predoprd = (*Node).GetOp()->GetPredOprdPtr(); predoprd != NULL; 
00399              predoprd = predoprd->GetNextOprdPtr(), i++) {
00400           // probably do not need the macro comparisons for pred registers, include for now
00401           if (((destoprd->GetOprdType() == OT_MACRO) &&
00402                (predoprd->GetOprdType() == OT_MACRO) &&
00403                (destoprd->GetOprdRegNum() == predoprd->GetOprdRegNum())) ||
00404               
00405               ((destoprd->GetOprdType() == OT_REG) &&
00406                (predoprd->GetOprdType() == OT_REG) &&
00407                (destoprd->GetOprdRegType() == predoprd->GetOprdRegType()) &&
00408                (destoprd->GetOprdRegNum() == predoprd->GetOprdRegNum()) &&
00409                (destoprd->GetOprdFileType() == predoprd->GetOprdFileType()))) {
00410             operand_found = TRUE;
00411             ru_info = (*Front).GetOp()->GetRUInfoPtr();
00412             indexj = operand_index (MDES_DEST, j);
00413             if (IsLoadOp((*Front).GetOp()) && 
00414                 (FindLcAttribute( "load_verify", (*Front).GetOp() ) != NULL)) {
00415                 
00416                 //HZ: same reason as before to change latency back to 2 cycles
00417               //op_latency = 1;
00418                 op_latency = 2;
00419             }
00420             else {
00421               op_latency = mdes_operand_latency(ru_info->proc_opc, ru_info->selected_alt->id, indexj);
00422             }
00423             if ( Machine->isRealOp( (*Front).GetOp() ) )
00424               ready_time = (*Front).GetOp()->GetSchedTime() + op_latency + BypassLatency; 
00425             else 
00426               ready_time = (*Front).GetOp()->GetSchedTime() + op_latency; 
00427             indexi = operand_index (MDES_PRED, i);
00428             derr( "** Flow Dependency Found:   from Op" << (*Front).GetOp()->GetOpId() << " to Op" 
00429                  << (*Node).GetOp()->GetOpId() << " with ready_time = " << ready_time << "\n");
00430             if ( ready_time > operand_ready_times[indexi])
00431               operand_ready_times[indexi] = ready_time;
00432             if ( ready_time > true_operand_ready_times[indexi])
00433               true_operand_ready_times[indexi] = ready_time;
00434             if ( ready_time > true_dsld_operand_ready_times[indexi])
00435               true_dsld_operand_ready_times[indexi] = ready_time;
00436             if ( ready_time > dsld_operand_ready_times[indexi])
00437               dsld_operand_ready_times[indexi] = ready_time;
00438           }
00439         }
00440       }
00441       if (!operand_found) {
00442         ru_info = (*Front).GetOp()->GetRUInfoPtr();
00443         indexi = operand_index (MDES_DEST, 0);
00444         if (IsLoadOp((*Front).GetOp()) && 
00445             (FindLcAttribute( "load_verify", (*Front).GetOp() ) != NULL)) {
00446                 //HZ: same reason as before to change latency back to 2 cycles
00447               //op_latency = 1;
00448                 op_latency = 2;
00449         }
00450         else {
00451           op_latency = mdes_operand_latency(ru_info->proc_opc, ru_info->selected_alt->id, indexi);
00452         }
00453         if ( Machine->isRealOp( (*Front).GetOp() ) ) {
00454           if ( (*Node).GetOp()->GetOpcode() == BRL ) {
00455             ready_time = (*Front).GetOp()->GetSchedTime() + op_latency + BypassLatency - 1; 
00456           }
00457           else {
00458             ready_time = (*Front).GetOp()->GetSchedTime() + op_latency + BypassLatency; 
00459           }
00460         }
00461         else { 
00462           if ( (*Node).GetOp()->GetOpcode() == BRL ) {
00463             ready_time = (*Front).GetOp()->GetSchedTime() + op_latency - 1; 
00464           }
00465           else {
00466             ready_time = (*Front).GetOp()->GetSchedTime() + op_latency; 
00467           }
00468         }
00469         indexj = operand_index (MDES_SRC, 0); 
00470         derr( "** Flow Dependency Found:   from Op" << (*Front).GetOp()->GetOpId() << " to Op" 
00471              << (*Node).GetOp()->GetOpId() << " with ready_time = " << ready_time << "\n");
00472         derr( "** this Flow Dependency results from a BRL return value, mdes treats as a control sync");
00473         if ( ready_time > operand_ready_times[indexj])
00474           operand_ready_times[indexj] = ready_time;
00475         if ( ready_time > true_operand_ready_times[indexj])
00476           true_operand_ready_times[indexj] = ready_time;
00477         if ( ready_time > true_dsld_operand_ready_times[indexj])
00478           true_dsld_operand_ready_times[indexj] = ready_time;
00479         if ( ready_time > dsld_operand_ready_times[indexj])
00480           dsld_operand_ready_times[indexj] = ready_time;
00481       }
00482       break;
00483     case (ET_REGOUT):
00484       if ((*Front).GetOp()->GetSchedTime() == UNSCHEDULED) { 
00485         indexj = operand_index (MDES_DEST, 0);
00486         operand_ready_times[indexj] = 9999;
00487         dsld_operand_ready_times[indexj] = 9999;
00488       }
00489       else {
00490         operand_found = FALSE;
00491         // determine operand_ready_times for the destination operands (output dependencies)
00492         for (i = 0, destoprd = (*Node).GetOp()->GetDestOprdPtr(); destoprd != NULL; 
00493              destoprd = destoprd->GetNextOprdPtr(), i++) {
00494           for (j = 0, destoprd2 = (*Front).GetOp()->GetDestOprdPtr(); destoprd2 != NULL; 
00495                destoprd2 = destoprd2->GetNextOprdPtr(), j++) {
00496             if (((destoprd2->GetOprdType() == OT_MACRO) &&
00497                  (destoprd->GetOprdType() == OT_MACRO) &&
00498                  (destoprd2->GetOprdRegNum() == destoprd->GetOprdRegNum())) ||
00499                 
00500                 ((destoprd2->GetOprdType() == OT_REG) &&
00501                  (destoprd->GetOprdType() == OT_REG) &&
00502                  (destoprd2->GetOprdRegType() == destoprd->GetOprdRegType()) &&
00503                  (destoprd2->GetOprdRegNum() == destoprd->GetOprdRegNum()) &&
00504                  (destoprd2->GetOprdFileType() == destoprd->GetOprdFileType()))) {
00505               operand_found = TRUE;
00506               ru_info = (*Front).GetOp()->GetRUInfoPtr();
00507               indexj = operand_index (MDES_DEST, j);
00508               if (IsLoadOp((*Front).GetOp()) && 
00509                   (FindLcAttribute( "load_verify", (*Front).GetOp() ) != NULL)) {
00510                 //HZ: same reason as before to change latency back to 2 cycles
00511                 //op_latency = 1;
00512                 op_latency = 2;
00513               }
00514               else {
00515                 op_latency = mdes_operand_latency(ru_info->proc_opc, ru_info->selected_alt->id, indexj);
00516               }
00517               // add one to ready time here so that op with an output dependency does not try to 
00518               // write register in same cycle as op it is dependent on, but ok in following cycle
00519               // Don't add 1 to DEFINEs to agree with Sanjeev's scheduler
00520               if ((*Node).GetOp()->GetOpcode() == DEFINE)
00521                 ready_time = (*Front).GetOp()->GetSchedTime() + op_latency; 
00522               else
00523                 // BRLs define RET_ADDR macro on procedure entrance, not 
00524                 // on procedure exit 
00525                 if (((*Front).GetOp()->GetOpcode() == BRL) && 
00526                     (destoprd2->GetOprdRegNum() == RET_ADDR)) {
00527                   ready_time = (*Front).GetOp()->GetSchedTime() + op_latency; 
00528                 }
00529                 else {
00530                   ready_time = (*Front).GetOp()->GetSchedTime() + op_latency + 1; 
00531                 }
00532               indexi = operand_index (MDES_DEST, i);
00533               derr( "** Output Dependency Found:   from Op" << (*Front).GetOp()->GetOpId() << " to Op" 
00534                    << (*Node).GetOp()->GetOpId() << " with ready_time = " << ready_time << "\n");
00535               if ( ready_time > operand_ready_times[indexi])
00536                 operand_ready_times[indexi] = ready_time;
00537               if ( ready_time > dsld_operand_ready_times[indexi])
00538                 dsld_operand_ready_times[indexi] = ready_time;
00539             }
00540           }
00541         }
00542         if (!operand_found) {
00543           ru_info = (*Front).GetOp()->GetRUInfoPtr();
00544           indexi = operand_index (MDES_DEST, 0);
00545           if (IsLoadOp((*Front).GetOp()) && 
00546               (FindLcAttribute( "load_verify", (*Front).GetOp() ) != NULL)) {
00547                 //HZ: same reason as before to change latency back to 2 cycles
00548                 //op_latency = 1;
00549                 op_latency = 2;
00550           }
00551           else {
00552             op_latency = mdes_operand_latency(ru_info->proc_opc, ru_info->selected_alt->id, indexi);
00553           }
00554           // add one to ready time here so that op with an output dependency does not try to 
00555           // write register in same cycle as op it is dependent on, but ok in following cycle
00556           // Don't add 1 to DEFINEs to agree with Sanjeev's scheduler
00557           if ((*Node).GetOp()->GetOpcode() == DEFINE) {
00558             if ( (*Node).GetOp()->GetOpcode() == BRL ) {
00559               ready_time = (*Front).GetOp()->GetSchedTime() + op_latency - 1; 
00560             }
00561             else {
00562               ready_time = (*Front).GetOp()->GetSchedTime() + op_latency; 
00563             }
00564           }
00565           else {
00566             if ( (*Node).GetOp()->GetOpcode() == BRL ) {
00567               ready_time = (*Front).GetOp()->GetSchedTime() + op_latency; 
00568             }
00569             else {
00570               ready_time = (*Front).GetOp()->GetSchedTime() + op_latency + 1; 
00571             }
00572           }
00573           indexj = operand_index (MDES_DEST, 0); 
00574           derr( "** Output Dependency Found:   from Op" << (*Front).GetOp()->GetOpId() << " to Op" 
00575                << (*Node).GetOp()->GetOpId() << " with ready_time = " << ready_time << "\n");
00576           derr( "** this Output Dependency results from a BRL return value, mdes treats as a control sync" 
00577                << "\n");
00578           if ( ready_time > operand_ready_times[indexj])
00579             operand_ready_times[indexj] = ready_time;
00580           if ( ready_time > dsld_operand_ready_times[indexj])
00581             dsld_operand_ready_times[indexj] = ready_time;
00582         }
00583       }
00584         break;
00585     case (ET_REGANTI):
00586       if ((*Front).GetOp()->GetSchedTime() == UNSCHEDULED) { 
00587         indexj = operand_index (MDES_DEST, 0);
00588         operand_ready_times[indexj] = 9999;
00589         dsld_operand_ready_times[indexj] = 9999;
00590       }
00591       else {
00592         for (i = 0, destoprd = (*Node).GetOp()->GetDestOprdPtr(); destoprd != NULL; 
00593              destoprd = destoprd->GetNextOprdPtr(), i++) {
00594           for (j = 0, srcoprd = (*Front).GetOp()->GetSrcOprdPtr(); srcoprd != NULL; 
00595                srcoprd = srcoprd->GetNextOprdPtr(), j++) {
00596             if (((srcoprd->GetOprdType() == OT_MACRO) &&
00597                  (destoprd->GetOprdType() == OT_MACRO) &&
00598                  (srcoprd->GetOprdRegNum() == destoprd->GetOprdRegNum())) ||
00599                 
00600                 ((srcoprd->GetOprdType() == OT_REG) &&
00601                  (destoprd->GetOprdType() == OT_REG) &&
00602                  (srcoprd->GetOprdRegType() == destoprd->GetOprdRegType()) &&
00603                  (srcoprd->GetOprdRegNum() == destoprd->GetOprdRegNum()) &&
00604                  (srcoprd->GetOprdFileType() == destoprd->GetOprdFileType()))) {
00605               ru_info = (*Front).GetOp()->GetRUInfoPtr();
00606               indexj = operand_index (MDES_SRC, j);
00607               op_latency = mdes_operand_latency(ru_info->proc_opc, ru_info->selected_alt->id, 
00608                                                 indexj);
00609               if ( Machine->isRealOp( (*Front).GetOp() ) )
00610                 ready_time = (*Front).GetOp()->GetSchedTime() + op_latency - BypassLatency; 
00611               else 
00612                 ready_time = (*Front).GetOp()->GetSchedTime() + op_latency; 
00613               indexi = operand_index (MDES_DEST, i);
00614               derr( "** Anti Dependency Found:   from Op" << (*Front).GetOp()->GetOpId() << " to Op" 
00615                    << (*Node).GetOp()->GetOpId() << " with ready_time = " << ready_time << "\n");
00616               if ( ready_time > operand_ready_times[indexi])
00617                 operand_ready_times[indexi] = ready_time;
00618               if ( ready_time > dsld_operand_ready_times[indexi])
00619                 dsld_operand_ready_times[indexi] = ready_time;
00620             }
00621           }
00622         }
00623       }
00624       break;
00625     }
00626   }
00627 }
00628 
00629 
00630 // GetCandidateNodeTree: Tree-Traversal version of this function. scans 
00631 // the list of Ops to try and find one which is unscheduled, has all TRUE 
00632 // predecessors scheduled (excluding anti/output-deps) and meets requirements 
00633 // of tree-traversal scheduling (is dominated by cur_block_ptr)  Creates 
00634 // "int *operand_ready_times" for the op to be used during scheduling
00635 vector < BigListElement >::iterator
00636    list_scheduler::GetCandidateNodeTree(int IssueCycle, knobs *Knobs,
00637                                         legoRegion *proc_ptr, int Final_Pass)
00638 {
00639   ListIterator Ptr;
00640   int sched_time, descendant, predecessors_scheduled, mdes_slot, i; 
00641   legoOp *dummy_br_op; 
00642   int rn_conflict, ready_time, true_ready_time, true_dsld_ready_time, dsld_ready_time;
00643   int latency_count, alt_id, operand_latency; 
00644   RU_Info* ru_info;
00645   Mdes_Info* mdes_info;
00646   Mdes_Compatable_Alt *compatable_alt;
00647   attrs *liveattr;
00648   opEdges *edge;
00649   int orig_ptr_id; 
00650   legoOprd *def, *use, *oprd; 
00651   oprdList *uses; 
00652   char *regiontype, fully_if_convert;
00653   int FullyIfConverted;
00654   
00655   derr( ">> GetCandidateNodeTree\n" );
00656   
00657   
00658   if (current_before_op->GetOpcode() == BRL && 
00659       current_before_op->GetNextLink()->GetOpcode() == DUMMY_BR && 
00660       current_before_op->GetNextLink()->GetSchedTime() == UNSCHEDULED ) {
00661     for (Ptr = List->begin(), dummy_br_op = current_before_op->GetNextLink();
00662          (*Ptr).GetOp() != dummy_br_op;
00663          Ptr++)
00664       ;// do nothing
00665     derr( ">> GetCandidateNodeTree: Linking DUMMY_BR to previous BRL\n" );
00666     //BuildReadyTimes( Ptr, IssueCycle );
00667     // or maybe don't worry about ready-times when linking DUMMY_BR
00668     for (i = 0; i < mdes_latency_count(); i++)
00669       operand_ready_times[i] = 0;
00670     mdes_slot = RU_can_schedule_op ((*Ptr).GetOp()->GetRUInfoPtr(), 
00671                                     (*Ptr).GetOp()->GetMdesInfoPtr(),
00672                                     operand_ready_times, IssueCycle, 0, 
00673                                     mdes_total_slots(), 0);
00674     if (mdes_slot == -1) {
00675       derr( "<< GetCandidateNodeTree: candidate not found, DUMMY_BR can not be scheduled in CurrentCycle.\n" );
00676       return List->end();
00677     }
00678     else
00679       return Ptr;
00680   }
00681 
00682   Ptr = ListPtr;
00683   ListTail = List->end();
00684   while ( Ptr != ListTail ) {
00685     derr( "   candidate Op " << (*Ptr).GetOp()->GetOpId() << "\n" );
00686 
00687     sched_time = (*Ptr).GetOp()->GetSchedTime();
00688     if ( sched_time == UNSCHEDULED ) {
00689       descendant = DescendantofCurBlockPtr( Ptr );
00690       
00691       //HZ: temp output info for debug
00692       //derr("  descendant: " << descendant << "\n");
00693       
00694       if ( descendant == YES ) {
00695           
00696         Knobs->SetDefaultPanel ("ccom");
00697         Knobs->Read ("region", regiontype);
00698         Knobs->Read ("fully-if-convert", fully_if_convert);
00699         FullyIfConverted = FALSE;
00700         if ((strcmp (regiontype, "FICT") == 0) || 
00701             (fully_if_convert && Final_Pass)) {
00702           FullyIfConverted = TRUE;
00703         }
00704         if (FullyIfConverted == TRUE) {
00705           predecessors_scheduled = PredecessorsScheduled( Ptr );
00706           if ( predecessors_scheduled == YES ) {
00707             BuildReadyTimes( Ptr, IssueCycle );
00708             ListPtr = Ptr + 1;
00709             
00710             derr( ">> GetCandidateNodeTree: candidate found\n" );
00711             // Update output to ListFile for accepted candidate
00712             if ( CreateSchedVizFiles ) {
00713               fprintf (ListFile, "%d\n", (*Ptr).GetOp()->GetOpId());
00714             }
00715             return Ptr;
00716           }
00717           else {
00718             derr( "   candidate rejected, has unscheduled predecessor(s)\n" );
00719             // Update output to ListFile for rejected candidate
00720             if ( CreateSchedVizFiles ) {
00721               fprintf (ListFile, "%d\n", (*Ptr).GetOp()->GetOpId());
00722               fprintf (ListFile, "n\n");
00723               fprintf (ListFile, "unscheduled predecessor(s)\n");
00724             }
00725             Ptr++;
00726           }
00727         }
00728         else { 
00729           predecessors_scheduled = TruePredecessorsScheduled( Ptr );
00730 
00731           if ( predecessors_scheduled == YES ) {
00732               
00733             //HZ: Debug:
00734             //if(IssueCycle == 2 && Ptr->GetOp()->GetOpId() == 804)
00735             //{
00736                 //int temp_iiii = 1;
00737             //}
00738               
00739             
00740             BuildReadyTimes( Ptr, IssueCycle );
00741             
00742             // Allow renaming to try and improve operand_ready_times for trees
00743             latency_count = mdes_latency_count();
00744             ru_info = (*Ptr).GetOp()->GetRUInfoPtr();
00745             mdes_info = (*Ptr).GetOp()->GetMdesInfoPtr();
00746             compatable_alt = mdes_info->compatable_alts; 
00747             alt_id = compatable_alt->alt->id;
00748             ready_time = 0; 
00749             true_ready_time = 0; 
00750             true_dsld_ready_time = 0; 
00751             dsld_ready_time = 0; 
00752             for (i = 0; i < latency_count; i++) {
00753               operand_latency = mdes_operand_latency(ru_info->proc_opc, alt_id, i);
00754               if ( (operand_ready_times[i] - operand_latency) > ready_time )
00755                 ready_time = operand_ready_times[i] - operand_latency;
00756               if ( (true_operand_ready_times[i] - operand_latency) >  true_ready_time )
00757                 true_ready_time = true_operand_ready_times[i] - operand_latency;
00758               if ( (true_dsld_operand_ready_times[i] - operand_latency) >  true_dsld_ready_time )
00759                 true_dsld_ready_time = true_dsld_operand_ready_times[i] - operand_latency;
00760               if ( (dsld_operand_ready_times[i] - operand_latency) >  dsld_ready_time )
00761                 dsld_ready_time = dsld_operand_ready_times[i] - operand_latency;
00762             }
00763             
00764             if (true_dsld_ready_time < dsld_ready_time) {
00765               
00766               //cerr << "\nBefore Renaming:\n";
00767               //cerr << "\nOpId = " << (*Ptr).GetOp()->GetOpId() << "\n";
00768               //cerr << "  true_dsld_ready_time = " << true_dsld_ready_time << "\n";
00769               //cerr << "  dsld_ready_time = " << dsld_ready_time << "\n\n";
00770               
00771               if ( true_dsld_ready_time <= IssueCycle ) {
00772                 
00773                 // Rename may change Ptr
00774                 orig_ptr_id = (*Ptr).GetOp()->GetOpId(); 
00775                 ReDoLiveVarsAfterGlobal = FALSE; 
00776                 rn_conflict = Rename((*Ptr).GetOp(), NO, Knobs, 
00777                                      (legoProc *) proc_ptr, Final_Pass, 
00778                                      YES, NO);
00779                 
00780                 // Now reset ListTail and Ptr to the original Id
00781                 ListTail = List->end();
00782                 Ptr = List->begin();
00783                 while ((*Ptr).GetOp()->GetOpId() != orig_ptr_id) Ptr++; 
00784                 
00785                 if (rn_conflict == NO_RENAMING_CONFLICT) {
00786                   
00787                   //cerr << "Renaming Successfull !!!\n\n";
00788                   
00789                   if (!((*Ptr).GetOp()->IsDummy())) {
00790                     falsedep_renamed_ops++;
00791                   }
00792                   
00793                   // Op may not actually get scheduled this cycle. Make 
00794                   // sure that LiveVars get updated in this tree so 
00795                   // that op won't disappear (Due to DoTheMessyStuff())
00796                   for (def = (*Ptr).GetOp()->GetDestOprdPtr(); 
00797                        def != NULL; 
00798                        def = def->GetNextOprdPtr()) {
00799                     if (def->GetOprdType() != OT_UNDEFINED) {
00800                       for (uses = Chains->GetDUChains()->Lookup (def);
00801                            (uses != NULL) && (Chains->GetDUChains()->NotFound() == FALSE);
00802                            uses = uses->GetNextListPtr()) {
00803                         use = uses->GetOprdPtr();
00804                         if (((legoRegion *) use->GetParentOpPtr()
00805                              ->GetParentBlockPtr())->GetParentPtr() == Region) {
00806                           FixLiveVarsFromUses(use, (*Ptr).GetOp(), 
00807                                               (legoProc*) proc_ptr);
00808                         }
00809                         else {
00810                           ReDoLiveVarsAfterGlobal = TRUE; 
00811                           break;
00812                         }
00813                       }
00814                     }
00815                   }
00816                   
00817                   if (ReDoLiveVarsAfterGlobal) {
00818                     // Clean-up previous live attrs generated by earlier call
00819                     for ( edge = ((legoProc*) proc_ptr)->GetEdgeDictionary(); edge != NULL;
00820                          edge = edge->GetNextOpEdgePtr() ) {
00821                       liveattr = FindLiveAttribute (edge);
00822                       if (liveattr != NULL) RemoveLiveAttribute (edge, ((legoProc *) proc_ptr));
00823                     }
00824                     
00825                     then = time(NULL);
00826                     start_live = clock();
00827                     LiveVariables ((legoProc*) proc_ptr);
00828                     liveness_calls++;
00829                     now = time(NULL);
00830                     finish_live = clock();
00831                     dderr ("LiveVariables() call number " << live_call_number++ << " ended\n");
00832                     elapsed = difftime(now, then);
00833                     elapsed_c = ((finish_live - start_live) / clocks_per_sec);
00834                     dderr ("---Elapsed time is " << elapsed << " seconds\n");
00835                     dderr ("---Elapsed time is " << elapsed_c << " ticks\n"); 
00836                     //total_live += elapsed_c;
00837                     total_live += elapsed;
00838                     
00839                     ReDoLiveVarsAfterGlobal = FALSE; 
00840                     ReDoLiveVarsNextTreegion = FALSE; 
00841                   }
00842                   
00843                   // Re-Do operand_ready_times[] so change is transparent to 
00844                   // the scheduler (Output/Anti-Deps incrementally removed 
00845                   // during renaming). 
00846                   BuildReadyTimes( Ptr, IssueCycle );
00847                   
00848                   ready_time = 0; 
00849                   true_ready_time = 0; 
00850                   true_dsld_ready_time = 0; 
00851                   dsld_ready_time = 0; 
00852                   for (i = 0; i < latency_count; i++) {
00853                     operand_latency = mdes_operand_latency(ru_info->proc_opc, alt_id, i);
00854                     if ( (operand_ready_times[i] - operand_latency) > ready_time )
00855                       ready_time = operand_ready_times[i] - operand_latency;
00856                     if ( (true_operand_ready_times[i] - operand_latency) >  true_ready_time )
00857                       true_ready_time = true_operand_ready_times[i] - operand_latency;
00858                     if ( (true_dsld_operand_ready_times[i] - operand_latency) >  true_dsld_ready_time )
00859                       true_dsld_ready_time = true_dsld_operand_ready_times[i] - operand_latency;
00860                     if ( (dsld_operand_ready_times[i] - operand_latency) >  dsld_ready_time )
00861                       dsld_ready_time = dsld_operand_ready_times[i] - operand_latency;
00862                   }
00863                   
00864                   //cerr << "After Renaming:\n";
00865                   //cerr << "  true_dsld_ready_time = " << true_dsld_ready_time << "\n";
00866                   //cerr << "  dsld_ready_time = " << dsld_ready_time << "\n\n";
00867                   
00868                 }
00869                 else {
00870                   
00871                   if (ReDoLiveVarsAfterGlobal) {
00872                     // Clean-up previous live attrs generated by earlier call
00873                     for ( edge = ((legoProc*) proc_ptr)->GetEdgeDictionary(); edge != NULL;
00874                          edge = edge->GetNextOpEdgePtr() ) {
00875                       liveattr = FindLiveAttribute (edge);
00876                       if (liveattr != NULL) RemoveLiveAttribute (edge, ((legoProc *) proc_ptr));
00877                     }
00878                     
00879                     then = time(NULL);
00880                     start_live = clock();
00881                     LiveVariables ((legoProc*) proc_ptr);
00882                     liveness_calls++;
00883                     now = time(NULL);
00884                     finish_live = clock();
00885                     dderr ("LiveVariables() call number " << live_call_number++ << " ended\n");
00886                     elapsed = difftime(now, then);
00887                     elapsed_c = ((finish_live - start_live) / clocks_per_sec);
00888                     dderr ("---Elapsed time is " << elapsed << " seconds\n");
00889                     dderr ("---Elapsed time is " << elapsed_c << " ticks\n"); 
00890                     //total_live += elapsed_c;
00891                     total_live += elapsed;
00892                     
00893                     ReDoLiveVarsAfterGlobal = FALSE; 
00894                     ReDoLiveVarsNextTreegion = FALSE; 
00895                   }
00896                   
00897                   //cerr << "Renaming Conflict !!!\n\n";
00898                   // Don't try to schedule unless predecessors have all been 
00899                   // scheduled (otherwise dom //ism may miss anti-deps
00900                   if (ready_time >= 9990) {
00901                     Ptr++;
00902                     continue; 
00903                   }
00904                   
00905                 }
00906               }
00907               else {
00908                 
00909                 //cerr << "true_dsld_ready_time > IssueCycle !!!\n\n";
00910                 // Don't try to schedule unless predecessors have all been 
00911                 // scheduled (otherwise dom //ism may miss anti-deps
00912                 if (ready_time >= 9990) {
00913                   Ptr++;
00914                   continue; 
00915                 }
00916                 
00917               }
00918             }
00919           
00920             //cerr << "  IssueCycle = " << IssueCycle << "\n"; 
00921             //cerr << "  dsld_ready_time = " << dsld_ready_time << "\n"; 
00922             //cerr << "  ready_time = " << ready_time << "\n"; 
00923             if ((dsld_ready_time < ready_time) && 
00924                 (IssueCycle < ready_time) && 
00925                 (dsld_ready_time <= IssueCycle)) { 
00926               //cerr << "Add load_verify attr !!!\n\n"; 
00927               oprd = new legoOprd; 
00928               oprd->SetOprdType (OT_LITERAL_I); 
00929               oprd->SetLiteralInteger(0); 
00930               AddLcAttribute ("load_verify", oprd, (*Ptr).GetOp(), 
00931                               (legoProc *) proc_ptr); 
00932               Ptr++; 
00933               continue; 
00934             } 
00935             
00936             //cerr << "Candidate Found !!!\n\n"; 
00937             ListPtr = Ptr + 1; 
00938             
00939             derr( ">> GetCandidateNodeTree: candidate found\n" );
00940             // Update output to ListFile for accepted candidate
00941             if ( CreateSchedVizFiles ) {
00942               fprintf (ListFile, "%d\n", (*Ptr).GetOp()->GetOpId());
00943             }
00944             
00945             return Ptr;
00946             
00947           }
00948           else {
00949             derr( "   candidate rejected, has unscheduled predecessor(s)\n" );
00950             // Update output to ListFile for rejected candidate
00951             if ( CreateSchedVizFiles ) {
00952               fprintf (ListFile, "%d\n", (*Ptr).GetOp()->GetOpId());
00953               fprintf (ListFile, "n\n");
00954               fprintf (ListFile, "unscheduled predecessor(s)\n");
00955             }
00956             Ptr++;
00957           }
00958         }
00959       }
00960       else {
00961         derr( "   candidate rejected, not a descendant of current block ptr\n" );
00962         // Update output to ListFile for rejected candidate
00963         if ( CreateSchedVizFiles ) {
00964           fprintf (ListFile, "%d\n", (*Ptr).GetOp()->GetOpId());
00965           fprintf (ListFile, "n\n");
00966           fprintf (ListFile, "non-descendant of current_block_ptr\n");
00967         }
00968         Ptr++;
00969       }
00970     }
00971     else {
00972       derr( "   candidate rejected, already scheduled\n" );
00973       // Update output to ListFile for rejected candidate
00974       if ( CreateSchedVizFiles ) {
00975         fprintf (ListFile, "%d\n", (*Ptr).GetOp()->GetOpId());
00976         fprintf (ListFile, "n\n");
00977         fprintf (ListFile, "already scheduled\n");
00978       }
00979       Ptr++;
00980     }
00981 
00982   }
00983   derr( "<< GetCandidateNodeTree: candidate not found\n" );
00984   return List->end();
00985 }
00986 
00987 //HZ: 08/25/00
00988 /*
00989 void list_scheduler::PrintCandidateNodes( int IssueCycle, ofstream & os1 )
00990 {
00991   ListIterator Ptr;
00992   int sched_time, descendant, predecessors_scheduled; 
00993   
00994   
00995   derr( ">> PrintCandidateNodes\n" );
00996   Ptr = ListPtr;
00997   ListTail = List->end();
00998   
00999   os1 << "IssueCycle: " << IssueCycle << endl;  
01000   
01001   while ( Ptr != ListTail ) {
01002     derr( "   candidate Op " << (*Ptr).GetOp()->GetOpId() << "\n" );
01003     sched_time = (*Ptr).GetOp()->GetSchedTime();
01004     predecessors_scheduled = PredecessorsScheduled( Ptr );
01005     if ( sched_time == UNSCHEDULED  &&
01006         predecessors_scheduled == YES ) {
01007       
01008 //      BuildReadyTimes( Ptr, IssueCycle );
01009 //      ListPtr = Ptr + 1;
01010       
01011 //      derr( ">> GetCandidateNode: candidate found\n" );
01012       // Update output to ListFile for accepted candidate
01013 //      if ( CreateSchedVizFiles ) {
01014 //      fprintf (ListFile, "%d\n", (*Ptr).GetOp()->GetOpId());
01015 //      }
01016  //     return Ptr;
01017  
01018         os1 << (*Ptr).PrintElement(os1);
01019     }
01020     else {
01021       if ( sched_time != UNSCHEDULED ) {
01022         derr( "   candidate rejected, already scheduled\n" );
01023         // Update output to ListFile for rejected candidate
01024         if ( CreateSchedVizFiles ) {
01025           fprintf (ListFile, "%d\n", (*Ptr).GetOp()->GetOpId());
01026           fprintf (ListFile, "n\n");
01027           fprintf (ListFile, "already scheduled\n");
01028         }
01029       }
01030       else {
01031         derr( "   candidate rejected, has unscheduled predecessor(s)\n" );
01032         // Update output to ListFile for rejected candidate
01033         if ( CreateSchedVizFiles ) {
01034           fprintf (ListFile, "%d\n", (*Ptr).GetOp()->GetOpId());
01035           fprintf (ListFile, "n\n");
01036           fprintf (ListFile, "unscheduled predecessor(s)\n");
01037         }
01038       }
01039       Ptr++;
01040     }
01041   }
01042   os1<< "PrintCandidateNode: candidate not found\n" );
01043 
01044 }
01045 */
01046 
01047 
01048 
01049 // GetCandidateNode: scans the list of Ops to try and find one which 
01050 // is unscheduled and has all predecessors scheduled.  Creates 
01051 // "int *operand_ready_times" for the op to be used during scheduling
01052 vector < BigListElement >::iterator
01053    list_scheduler::GetCandidateNode( int IssueCycle )
01054 {
01055   ListIterator Ptr;
01056   int sched_time, descendant, predecessors_scheduled; 
01057   
01058   
01059   derr( ">> GetCandidateNode\n" );
01060   Ptr = ListPtr;
01061   ListTail = List->end();
01062   while ( Ptr != ListTail ) {
01063     derr( "   candidate Op " << (*Ptr).GetOp()->GetOpId() << "\n" );
01064     sched_time = (*Ptr).GetOp()->GetSchedTime();
01065     predecessors_scheduled = PredecessorsScheduled( Ptr );
01066     if ( sched_time == UNSCHEDULED  &&
01067         predecessors_scheduled == YES ) {
01068       
01069       BuildReadyTimes( Ptr, IssueCycle );
01070       ListPtr = Ptr + 1;
01071       
01072       derr( ">> GetCandidateNode: candidate found\n" );
01073       // Update output to ListFile for accepted candidate
01074       if ( CreateSchedVizFiles ) {
01075         fprintf (ListFile, "%d\n", (*Ptr).GetOp()->GetOpId());
01076       }
01077       return Ptr;
01078     }
01079     else {
01080       if ( sched_time != UNSCHEDULED ) {
01081         derr( "   candidate rejected, already scheduled\n" );
01082         // Update output to ListFile for rejected candidate
01083         if ( CreateSchedVizFiles ) {
01084           fprintf (ListFile, "%d\n", (*Ptr).GetOp()->GetOpId());
01085           fprintf (ListFile, "n\n");
01086           fprintf (ListFile, "already scheduled\n");
01087         }
01088       }
01089       else {
01090         derr( "   candidate rejected, has unscheduled predecessor(s)\n" );
01091         // Update output to ListFile for rejected candidate
01092         if ( CreateSchedVizFiles ) {
01093           fprintf (ListFile, "%d\n", (*Ptr).GetOp()->GetOpId());
01094           fprintf (ListFile, "n\n");
01095           fprintf (ListFile, "unscheduled predecessor(s)\n");
01096         }
01097       }
01098       Ptr++;
01099     }
01100   }
01101   derr( "<< GetCandidateNode: candidate not found\n" );
01102   return List->end();
01103 }
01104 
01105 
01106 // ResetListPtr: sets the ListPtr to the first unscheduled Op in List
01107 void list_scheduler::ResetListPtr()
01108 {
01109   vector < BigListElement >::iterator Iter = List->begin();
01110   
01111   derr( ">> ResetListPtr\n" );
01112   while ( Iter != List->end() &&
01113          (*Iter).GetOp()->GetSchedTime() != UNSCHEDULED )
01114     Iter++;
01115   ListPtr = Iter;
01116   derr( "<< ResetListPtr\n" );
01117 }
01118 
01119 void list_scheduler::SimpleRename (legoOp *op, int RegNum, int IncMaxRegNum)
01120 {
01121   oprdList *uses; 
01122   legoOprd *def, *use;
01123   int localRegNum; 
01124   
01125   dderr("RENAME: SimpleRename\n");
01126    
01127   if (!IncMaxRegNum) 
01128     localRegNum = RegNum; 
01129   for (def = op->GetDestOprdPtr(); 
01130        def != NULL; 
01131        def = def->GetNextOprdPtr()) {
01132     if (def->GetOprdType() != OT_UNDEFINED) {
01133       if (IncMaxRegNum)
01134         localRegNum = ++MaxRegNum;
01135       def->SetOprdRegNum (localRegNum);
01136       RemoveOutputDepsAfterRename(def);
01137       RemoveAntiDepsAfterDefRename(def);
01138       dderr("RENAME: rename original def (OpId = " << op->GetOpId() << ") to RegNum " << localRegNum << "\n");
01139       for (uses = Chains->GetDUChains()->Lookup (def);
01140            (uses != NULL) && (Chains->GetDUChains()->NotFound() == FALSE);
01141            uses = uses->GetNextListPtr()) {
01142         use = uses->GetOprdPtr();
01143         use->SetOprdRegNum (localRegNum);
01144         dderr("RENAME: rename use (OpId = " << use->GetParentOpPtr()->GetOpId() << ") to RegNum " << localRegNum << "\n");
01145       }  
01146     }
01147     if (!IncMaxRegNum) 
01148       localRegNum++;
01149   }
01150 }
01151 
01152 void list_scheduler::ForwardGlobalRename (legoOprd *def, int RegNum, 
01153                                           legoOprd *orig_def)
01154 {
01155   oprdList *uses;
01156   legoOprd *use;
01157 
01158   dderr("RENAME: ForwardGlobalRename\n");
01159   
01160   for (uses = Chains->GetDUChains()->Lookup (def);
01161        (uses != NULL) && (Chains->GetDUChains()->NotFound() == FALSE);
01162        uses = uses->GetNextListPtr()) {
01163     use = uses->GetOprdPtr();
01164     if (use->GetOprdRegNum() != RegNum) {
01165       use->SetOprdRegNum (RegNum);
01166       // Turns out it is possible for other defs in treegion to still have 
01167       // dependencies if both dependent ops get renamed during global rename
01168       //RemoveAntiDepsAfterUseRename(use);
01169       dderr("RENAME: rename use (OpId = " << use->GetParentOpPtr()->GetOpId() << ") to RegNum " << RegNum << "\n");
01170       ReverseGlobalRename(use, RegNum, orig_def); 
01171     }
01172   }  
01173 }
01174 
01175 void list_scheduler::ReverseGlobalRename (legoOprd *use, int RegNum, 
01176                                           legoOprd *orig_def)
01177 {
01178   oprdList *defs;
01179   legoOprd *def;
01180   
01181   dderr("RENAME: ReverseGlobalRename\n");
01182   
01183   for (defs = Chains->GetUDChains()->Lookup (use);
01184        (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
01185        defs = defs->GetNextListPtr()) {
01186     def = defs->GetOprdPtr();
01187     if (def->GetOprdRegNum() != RegNum) {
01188       // Need to redo LiveVars immediately after GlobalRename if  
01189       // more than one def in Treegion affected by GlobalRename
01190       if (((legoRegion *) def->GetParentOpPtr()->GetParentBlockPtr())
01191           ->GetParentPtr() == Region) {
01192         ReDoLiveVarsAfterGlobal = TRUE;
01193         // It is also still possible that there is a 'remote' Merge Problem 
01194         // not caught by the original IsMergeProblem() check.
01195         // If there is, finish with the global rename but return a 
01196         // RENAMING_CONFLICT (possible to re-do Rename with Hazardous, 
01197         // forcing a copy to be inserted, but this is infrequent).
01198         if (IsRemoteMergeProblem(def, orig_def) == TRUE) {
01199           MergeProblemDuringGlobal = TRUE; 
01200         }
01201       }
01202       // else the ReDo can wait until starting the next Treegion
01203       else {
01204         ReDoLiveVarsNextTreegion = TRUE;
01205       }
01206       def->SetOprdRegNum (RegNum);
01207       dderr("RENAME: rename def (OpId = " << def->GetParentOpPtr()->GetOpId() << ") to RegNum " << RegNum << "\n");
01208       ForwardGlobalRename(def, RegNum, orig_def);
01209     }  
01210   }  
01211 }
01212 
01213 void list_scheduler::GlobalRename (legoOp *op, int RegNum, int IncMaxRegNum)
01214 {
01215   legoOprd *def;
01216   int localRegNum; 
01217   
01218   dderr("RENAME: GlobalRename\n");
01219   
01220   if (!IncMaxRegNum) 
01221     localRegNum = RegNum; 
01222   for (def = op->GetDestOprdPtr(); 
01223        def != NULL; 
01224        def = def->GetNextOprdPtr()) {
01225     if (def->GetOprdType() != OT_UNDEFINED) {
01226       if (IncMaxRegNum) 
01227         localRegNum = ++MaxRegNum;
01228       def->SetOprdRegNum (localRegNum);
01229       dderr("RENAME: rename original def (OpId = " << op->GetOpId() << ") to RegNum " << localRegNum << "\n");
01230       ForwardGlobalRename(def, localRegNum, def);
01231     }
01232     if (MergeProblemDuringGlobal == FALSE) { 
01233       // Output deps below this op may remain due to global rename, so 
01234       // introduce RemoveOutputDepsAfterRenameUp()
01235       RemoveOutputDepsAfterRenameUp(def);
01236       RemoveAntiDepsAfterDefRename(def);
01237     }
01238     if (!IncMaxRegNum) 
01239       localRegNum++;
01240   }
01241 }
01242 
01243 int list_scheduler::AddCopyOps (legoOp *op)
01244 {
01245   
01246   edgeList *edgelist; 
01247   opEdges *edge; 
01248   legoRegion *block_ptr; 
01249   int block_int; 
01250   legoOp *exit_op, *new_op, *before_op, *last_op_in_multiop, *op_in_multiop; 
01251   opList *exit_ops; 
01252   legoOprd *def, *new_src, *new_dest, *new_pred, *oprd; 
01253   BigListElement Element;
01254   fileTypes filetype;
01255   int orig_op_id, rc, multiop_stime; 
01256   vector < BigListElement >::iterator ListIter, TempListIter, TempListIter2;
01257   oprdList *oprd_list, *new_uses_inside, *new_use_inside;
01258   oprdList *new_use_outside, *prev_use_outside, *uses, *defs;
01259   oprdList *more_uses, *more_defs;
01260   oprdList *orig_uses_outside = NULL;
01261   legoOprd *use, *this_def; 
01262   legoOprd *another_use, *another_def; 
01263   attrs *a; 
01264   vector < SmallListElement >::iterator Front, Back;
01265   enum edgeTypes edgetype;  
01266   int UsePreceedsDefInBlock; 
01267   legoOp *predecessor_op; 
01268   oprdList *orig_ud_chain, *new_ud_chain; 
01269   
01270   dderr("RENAME: AddCopyOps\n");
01271   
01272   // Now that we are renaming for dom //ism (renaming scheduled ops), 
01273   // need to guarantee that copy op can be scheduled. Otherwise we have 
01274   // a RENAMING_CONFLICT
01275         if (op->GetSchedTime() != UNSCHEDULED) 
01276         {
01277                  // Find the last op in this multiop
01278                  for (last_op_in_multiop = current_before_op;
01279                  ((last_op_in_multiop->GetNextLink() != NULL) && 
01280                   (last_op_in_multiop->GetNextLink()->GetSchedTime() != 
01281                         UNSCHEDULED));
01282                  last_op_in_multiop = last_op_in_multiop->GetNextLink())
01283                         ; // Do Nothing
01284                  // See if this is a multiway branch yet. DoTheMessyStuff is not enough 
01285                  // if it is. Bail-out for now
01286                  multiop_stime = last_op_in_multiop->GetSchedTime();
01287                  for (op_in_multiop = last_op_in_multiop->GetPrevLink(); 
01288                  ((op_in_multiop != NULL) &&
01289                   ((op_in_multiop->GetSchedTime() == multiop_stime) || 
01290                         // PrepareToDie() may scatter ops with s_time = 0
01291                         (FindLcAttribute( "dp_remove", op_in_multiop ) != NULL)));
01292                  op_in_multiop = op_in_multiop->GetPrevLink()) 
01293        {
01294                         if (op_in_multiop->GetOpcode() == BRU) 
01295          {
01296                 // this is already a multiway then
01297                 //cerr << "\n\nWarning: Can't AddCopyOp() for scheduled op, Multi-Way branch present (opId = " << op->GetOpId() << ") !!! \n\n";
01298                 return (RENAMING_CONFLICT);
01299                         }
01300                  }
01301                  if (last_op_in_multiop->GetNextLink() == NULL) {
01302                         if (!AllowDownwardCodeMotion) return (RENAMING_CONFLICT);
01303 
01304                         // For it to be ok to proceed, last_op_in_multiop must be a BRCT or BRCF 
01305                         // and must not be a treegion exit. 
01306                         if ((last_op_in_multiop->GetOpcode() != BRCT) &&  
01307                   (last_op_in_multiop->GetOpcode() != BRCF)) {
01308                 return (RENAMING_CONFLICT);
01309                         } 
01310                         for (exit_ops = Region->GetExitOpsPtr(); 
01311                         exit_ops != NULL; 
01312                         exit_ops = exit_ops->GetNextListPtr()) {
01313                 if ((exit_op = exit_ops->GetOpPtr()) == last_op_in_multiop) {
01314                   return (RENAMING_CONFLICT);
01315                 }
01316                         }
01317                  }
01318          }
01319       
01320       
01321         // adding new elements to priority list screws up pointers for original 
01322         // Nodes. Need to remember which op is currently pointed to so 
01323         // that ListPtr can be reset to this Dag Node when done.
01324         orig_op_id = op->GetOpId(); 
01325 
01326         for (def = op->GetDestOprdPtr(); 
01327        def != NULL; 
01328        def = def->GetNextOprdPtr()) 
01329         {
01330         if (def->GetOprdType() != OT_UNDEFINED) 
01331                 {
01332       new_op = new legoOp(++MaxOpId);
01333       copy_ops_added++;
01334       // make sure I copy construct the PredVector
01335       if (op->GetPredVectorPtr() != NULL) 
01336                 {
01337                         new_op->SetPredVectorPtr(new bitvector(*op->GetPredVectorPtr()));
01338                 }
01339       // Copy the "orig_wt" attr if it exists
01340       if ((a = FindLcAttribute( "orig_wt", op )) != NULL) 
01341                 {
01342                         oprd = new legoOprd;
01343                         oprd->SetOprdType (OT_LITERAL_D);
01344                         oprd->SetLiteralDouble (a->GetAttrOprdPtr()->GetLiteralDouble());
01345                         AddLcAttribute ("orig_wt", oprd, new_op,
01346                                         (legoProc *) FindParentRegionType (RT_PROC, new_op));
01347                 }
01348       new_src = new legoOprd(*def);
01349       printf("!1\n");
01350       new_dest = new legoOprd(*def);
01351       printf("!2\n");
01352       filetype = def->GetOprdFileType();
01353       if (filetype != FT_PR) 
01354       if(op->GetPredOprdPtr()!=NULL)
01355       {
01356                         new_pred = new legoOprd(*(op->GetPredOprdPtr()));
01357       }
01358       else
01359            {
01360                         printf("OPCODE:%d\n",op->GetOpcode()); 
01361                         printf("OP-ID:%d\n",op->GetOpId()); 
01362                 }
01363      
01364       printf("!3\n");
01365       if ((filetype == FT_GPR) || (filetype == FT_CR)) 
01366         new_op->SetOpcode(MOVE);
01367       else if (filetype == FT_FPR)
01368         new_op->SetOpcode(MOVEF_D);
01369       else if (filetype == FT_PR)
01370         new_op->SetOpcode(CMPP_W_TRUE_UN_UN);
01371       else 
01372         // no move op for BTR-to-BTR moves, use int MOVE for now 
01373         new_op->SetOpcode(MOVE);
01374       //else if (filetype == FT_BTR)
01375       //new_op->SetOpcode(NOT_SURE);
01376       //else 
01377       //new_op->SetOpcode(NOT_SURE);
01378       if (filetype != FT_PR) {
01379         new_op->SetSrcOprdPtr(new_src);
01380         new_src->SetParentOpPtr(new_op);
01381         // Give the new op the original def and the original op the new dest 
01382         // So that ReachingDefinitions() does not need to be called again.
01383         new_op->SetDestOprdPtr(def);
01384         def->SetParentOpPtr(new_op);
01385         op->SetDestOprdPtr(new_dest);
01386         new_dest->SetParentOpPtr(op);
01387         new_op->SetPredOprdPtr (new_pred);
01388         new_pred->SetParentOpPtr(new_op);
01389         if (new_pred->GetOprdType() == OT_REG) {
01390           // Adjust Chains 
01391           orig_ud_chain = Chains->GetUDChains()->Lookup (op->GetPredOprdPtr());
01392           if (Chains->GetUDChains()->NotFound() == FALSE) {
01393             new_ud_chain = new oprdList(*orig_ud_chain);
01394             Chains->GetUDChains()->Set (new_pred, new_ud_chain); 
01395             // add this use to each def that reaches predicate
01396             for (more_defs = orig_ud_chain;
01397                  more_defs != NULL; 
01398                  more_defs = more_defs->GetNextListPtr()) { 
01399               another_def = more_defs->GetOprdPtr();
01400               for (more_uses = Chains->GetDUChains()->Lookup (another_def);
01401                    more_uses->GetNextListPtr() != NULL;
01402                    more_uses = more_uses->GetNextListPtr()) 
01403                 ; // find end of DUChain
01404               more_uses->SetNextListPtr(new oprdList);
01405               more_uses->GetNextListPtr()->SetOprdPtr(new_pred); 
01406             }
01407           }
01408         }
01409       }
01410       else {
01411         cerr << "\n*** Would like to know if I'm adding any CMPP copy ops (need RDef patch-up work if I am ***\n";
01412         new_op->SetSrcOprdPtr(NULL);
01413         // Give the new op the original def and the original op the new dest 
01414         // So that ReachingDefinitions() does not need to be called again.
01415         new_op->SetDestOprdPtr(def);
01416         def->SetParentOpPtr(new_op);
01417         op->SetDestOprdPtr(new_dest);
01418         new_dest->SetParentOpPtr(op);
01419         new_op->SetPredOprdPtr (new_src);
01420         new_src->SetParentOpPtr(new_op);
01421       }
01422 
01423       // Now adjust Chains for the reaching def between the orig and new ops
01424       oprd_list = new oprdList;
01425       oprd_list->SetOprdPtr (new_src);
01426       Chains->GetDUChains()->Set (new_dest, oprd_list); 
01427       oprd_list = new oprdList;
01428       oprd_list->SetOprdPtr (new_dest);
01429       Chains->GetUDChains()->Set (new_src, oprd_list); 
01430 
01431       // Split original DUChains between those uses inside the Treegion 
01432       // and dominated by the original op and those not. Those inside the 
01433       // Treegion and dominated by the original op go to the original op, 
01434       // the others go the new MOVE op
01435       uses = Chains->GetDUChains()->Lookup (def);
01436       if (Chains->GetDUChains()->NotFound() == FALSE) {
01437         while (uses != NULL) {
01438           use = uses->GetOprdPtr();
01439           // Determine if this use preceeds the defining op in its own block 
01440           UsePreceedsDefInBlock = FALSE; 
01441           // new_op not yet scheduled, use original op to determine if any 
01442           // uses preceed.
01443           for (predecessor_op = op; 
01444                predecessor_op != NULL; 
01445                predecessor_op = predecessor_op->GetPrevLink()) {
01446             if (predecessor_op == use->GetParentOpPtr()) {
01447               UsePreceedsDefInBlock = TRUE; 
01448               break; 
01449             }
01450           }
01451           if ((((legoRegion *) use->GetParentOpPtr()->GetParentBlockPtr())->GetParentPtr() == Region) && 
01452               (DescendantofBlock( (int) op->GetParentBlockPtr(), use->GetParentOpPtr() ) && 
01453                !UsePreceedsDefInBlock)) {
01454             new_uses_inside = Chains->GetDUChains()->Lookup (new_dest);
01455             new_use_inside = new oprdList;
01456             new_use_inside->SetOprdPtr (use);
01457             // need to find the end of the list of uses to add 
01458             // the latest use
01459             while (new_uses_inside->GetNextListPtr() != NULL) {
01460               new_uses_inside = new_uses_inside->GetNextListPtr();
01461             }
01462             new_uses_inside->SetNextListPtr (new_use_inside);
01463             // Now fix the UDChain to match new_use_inside
01464             for (defs = Chains->GetUDChains()->Lookup (use);
01465                  (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
01466                  defs = defs->GetNextListPtr()) {
01467               this_def = defs->GetOprdPtr();
01468               if (this_def == def) {
01469                 defs->SetOprdPtr(new_dest); 
01470               }
01471             }
01472           }
01473           else {
01474             if (orig_uses_outside == NULL) {
01475               orig_uses_outside = new oprdList;
01476               orig_uses_outside->SetOprdPtr(use);
01477               prev_use_outside = orig_uses_outside;
01478             }
01479             else {
01480               new_use_outside = new oprdList;
01481               new_use_outside->SetOprdPtr(use);
01482                 prev_use_outside->SetNextListPtr(new_use_outside);
01483               prev_use_outside = new_use_outside;
01484             }
01485           }
01486           uses = uses->GetNextListPtr();
01487         }
01488         uses = Chains->GetDUChains()->Lookup (def);
01489         delete uses; 
01490         Chains->GetDUChains()->Set (def, orig_uses_outside);
01491       }
01492       
01493       // Add to end of priority list
01494       Element = BigListElement(); 
01495       Element.SetOp(new_op);
01496       Element.SetWeight( -1 );
01497       Element.SetHeight( -1 );  
01498       Element.SetDepth( -1 );
01499 #if defined (_STL_LIST_USED_)
01500       ListIter = List->insert( List->begin(), Element );
01501 #else if defined (_STL_VECTOR_USED_)
01502       List->push_back( Element );
01503       ListIter = List->end();
01504       ListIter--;
01505 #endif
01506       ListCount++;
01507 
01508       // add a flow dep from the original op to the MOVE op (new_op)
01509       // don't need to worry about recursive renaming because we do 
01510       // not add copy ops unless there are uses from within the Treegion
01511       
01512       // First need to find the Node for the original op 
01513       TempListIter = List->begin();
01514       while ((*TempListIter).GetOp()->GetOpId() != op->GetOpId()) {
01515         TempListIter++; 
01516       }
01517       rc = (*ListIter).AddPredecessor( ET_REGFLOW, (*TempListIter).GetOp(), &(*TempListIter) );
01518       derr( " (" << rc << ") " );
01519       rc = (*TempListIter).AddSuccessor( ET_REGFLOW, (*ListIter).GetOp(), &(*ListIter) );
01520       ddderr( " (" << rc << ") " );
01521       ddderr( "Inserted ET_REGFLOW between " << (*TempListIter).GetOp()->GetOpId() << 
01522            " and " << (*ListIter).GetOp()->GetOpId() << "\n" );
01523 
01524       // Also need to split dependencies between original op and new MOVE op.
01525       // Successors first. 
01526       // Flow- and Anti-Deps stay with the original op. Output-Deps need to 
01527       // move to the new MOVE op. Both ops should have the same Memory-Deps
01528       for (Front = (*TempListIter).Successors->begin(),
01529            Back = (*TempListIter).Successors->end(); 
01530            Front != Back; ) {
01531         // first find the DagNode for the Successor op
01532         TempListIter2 = List->begin();
01533         while ((*TempListIter2).GetOp()->GetOpId() != 
01534                (*Front).GetOp()->GetOpId()) 
01535           TempListIter2++; 
01536         // find the edgetype
01537         edgetype = (*Front).GetDependencyType();
01538         // increment now (Front may be removed later) 
01539         Front++;
01540         // if an Output-Dep, want to remove this successor from 
01541         // original op and add it to the new MOVE op.
01542         if (edgetype == ET_REGOUT) {
01543           // Remove this Successor/Predecessor pair from original op
01544           Front = (*TempListIter).RemoveSuccessor(edgetype, 
01545                                                   (*TempListIter2).GetOp());
01546           // Reset Back
01547           Back = (*TempListIter).Successors->end();
01548           ddderr ("\nRemoveSuccessor (opId = " << (*TempListIter2).GetOp()->GetOpId() << ") of opId = " << (*TempListIter).GetOp()->GetOpId() << "\n");  
01549           (*TempListIter2).RemovePredecessor(edgetype, 
01550                                              (*TempListIter).GetOp());
01551           ddderr ("\nRemovePredecessor (opId = " << (*TempListIter).GetOp()->GetOpId() << ") of opId = " << (*TempListIter2).GetOp()->GetOpId() << "\n");
01552           // Add this Successor/Predecessor pair to new MOVE op
01553           rc = (*ListIter).AddSuccessor(edgetype, 
01554                                         (*TempListIter2).GetOp(), 
01555                                         &(*TempListIter2));   
01556           ddderr ("\nAddSuccessor (opId = " << (*TempListIter2).GetOp()->GetOpId() << ") of opId = " << (*ListIter).GetOp()->GetOpId() << ", now " << rc << " Successors\n");
01557           rc = (*TempListIter2).AddPredecessor(edgetype, 
01558                                                (*ListIter).GetOp(), 
01559                                                &(*ListIter));
01560           ddderr ("\nAddPredecessor (opId = " << (*ListIter).GetOp()->GetOpId() << ") of opId = " << (*TempListIter2).GetOp()->GetOpId() << ", now " << rc << " Predecessors\n");
01561         }
01562       }
01563       
01564       // Also need to fix Predecessors if we rename for Output/Anti-Deps
01565       // Output- and Anti-Deps move to the new MOVE op. Both ops should 
01566       // have the same Memory-Deps
01567       for (Front = (*TempListIter).Predecessors->begin(),
01568            Back = (*TempListIter).Predecessors->end(); 
01569            Front != Back; ) {
01570         // first find the DagNode for the Predecessor op
01571         TempListIter2 = List->begin();
01572         while ((*TempListIter2).GetOp()->GetOpId() != 
01573                (*Front).GetOp()->GetOpId()) 
01574           TempListIter2++; 
01575         // find the edgetype
01576         edgetype = (*Front).GetDependencyType();
01577         // increment now (Front may be removed later) 
01578         Front++;
01579         // if an Output-Dep, want to remove this predecessor from 
01580         // original op and add it to the new MOVE op.
01581         if (edgetype == ET_REGOUT) {
01582           // Remove this Successor/Predecessor pair from original op
01583           Front = (*TempListIter).RemovePredecessor(edgetype, 
01584                                                   (*TempListIter2).GetOp());
01585           // Reset Back
01586           Back = (*TempListIter).Predecessors->end();
01587           ddderr ("\nRemovePredecessor (opId = " << (*TempListIter2).GetOp()->GetOpId() << ") of opId = " << (*TempListIter).GetOp()->GetOpId() << "\n");  
01588           (*TempListIter2).RemoveSuccessor(edgetype, 
01589                                              (*TempListIter).GetOp());
01590           ddderr ("\nRemoveSuccessor (opId = " << (*TempListIter).GetOp()->GetOpId() << ") of opId = " << (*TempListIter2).GetOp()->GetOpId() << "\n");
01591           // Add this Successor/Predecessor pair to new MOVE op
01592           rc = (*ListIter).AddPredecessor(edgetype, 
01593                                         (*TempListIter2).GetOp(), 
01594                                         &(*TempListIter2));   
01595           ddderr ("\nAddPredecessor (opId = " << (*TempListIter2).GetOp()->GetOpId() << ") of opId = " << (*ListIter).GetOp()->GetOpId() << ", now " << rc << " Predecessors\n");
01596           rc = (*TempListIter2).AddSuccessor(edgetype, 
01597                                                (*ListIter).GetOp(), 
01598                                                &(*ListIter));
01599           ddderr ("\nAddSuccessor (opId = " << (*ListIter).GetOp()->GetOpId() << ") of opId = " << (*TempListIter2).GetOp()->GetOpId() << ", now " << rc << " Predecessors\n");
01600         }
01601         // if an Anti-Dep, want to remove this predecessor from 
01602         // original op and add it to the new MOVE op.
01603         if (edgetype == ET_REGANTI) {
01604           // Remove this Successor/Predecessor pair from original op
01605           Front = (*TempListIter).RemovePredecessor(edgetype, 
01606                                                   (*TempListIter2).GetOp());
01607           // Reset Back
01608           Back = (*TempListIter).Predecessors->end();
01609           ddderr ("\nRemovePredecessor (opId = " << (*TempListIter2).GetOp()->GetOpId() << ") of opId = " << (*TempListIter).GetOp()->GetOpId() << "\n");  
01610           (*TempListIter2).RemoveSuccessor(edgetype, 
01611                                              (*TempListIter).GetOp());
01612           ddderr ("\nRemoveSuccessor (opId = " << (*TempListIter).GetOp()->GetOpId() << ") of opId = " << (*TempListIter2).GetOp()->GetOpId() << "\n");
01613           // Add this Successor/Predecessor pair to new MOVE op
01614           rc = (*ListIter).AddPredecessor(edgetype, 
01615                                         (*TempListIter2).GetOp(), 
01616                                         &(*TempListIter2));   
01617           ddderr ("\nAddPredecessor (opId = " << (*TempListIter2).GetOp()->GetOpId() << ") of opId = " << (*ListIter).GetOp()->GetOpId() << ", now " << rc << " Predecessors\n");
01618           rc = (*TempListIter2).AddSuccessor(edgetype, 
01619                                                (*ListIter).GetOp(), 
01620                                                &(*ListIter));
01621           ddderr ("\nAddSuccessor (opId = " << (*ListIter).GetOp()->GetOpId() << ") of opId = " << (*TempListIter2).GetOp()->GetOpId() << ", now " << rc << " Predecessors\n");
01622         }
01623       }
01624       
01625       copy_dynamic_op_increase += ((legoRegion *) op->GetParentBlockPtr())->GetWeight(); 
01626       
01627       // Now that we are renaming for dom //ism (renaming scheduled ops), 
01628       // need to make sure the the copy op doesn't appear before 
01629       // any other scheduled ops or DoTheMessyStuff may not work. 
01630       // Trust me on this one. 
01631       if (op->GetSchedTime() != UNSCHEDULED) {
01632         if (last_op_in_multiop->GetNextLink() == NULL) {
01633           AddMidOp(new_op, last_op_in_multiop->GetPrevLink());
01634           DoTheMessyStuff(last_op_in_multiop, (legoProc *) FindParentRegionType (RT_PROC, last_op_in_multiop));
01635         }
01636         else {
01637           AddMidOp(new_op, last_op_in_multiop);
01638         }
01639       }
01640       else {
01641         AddMidOp(new_op, op);
01642       }
01643       dderr("RENAME: Copy added (OpId =  " << MaxOpId << ")\n");
01644       
01645       // need to initialize mdes_info and ru_info pointers
01646       L_build_oper_mdes_info (new_op);
01647       L_create_ru_info_oper (new_op);
01648     }
01649   }
01650   // Now reset ListPtr to the original Op Node and ListPtr Node
01651   ListPtr = List->begin();
01652   while ((*ListPtr).GetOp()->GetOpId() != orig_op_id) ListPtr++; 
01653   Op = ListPtr;
01654   ListPtr++;
01655   
01656   return (NO_RENAMING_CONFLICT);
01657 }
01658 
01659 int list_scheduler::IsRemoteMergeProblem (legoOprd *def, legoOprd *orig_def)
01660 {  
01661   
01662   legoOprd *oprd; 
01663 
01664   if ((def != orig_def) && 
01665       (((legoRegion *) def->GetParentOpPtr()->GetParentBlockPtr())->GetParentPtr() == Region) &&
01666       DescendantofBlock( (int) def->GetParentOpPtr()->GetParentBlockPtr(), orig_def->GetParentOpPtr() )) {
01667     dderr("RENAME: IsRemoteMergeProblem = TRUE\n");
01668     //cerr << "\n\nWarning: RemoteMergeProblem for opId = " << orig_def->GetParentOpPtr()->GetOpId() << " and opId = " << def->GetParentOpPtr()->GetOpId() << "\n\n";
01669     // Expensive to figure out that this op has a merge problem (LiveVars() 
01670     // need to be redone). Make as a MergeProblem for future scheduling 
01671     // attempts
01672     oprd = new legoOprd; 
01673     oprd->SetOprdType (OT_LITERAL_I); 
01674     oprd->SetLiteralInteger(0); 
01675     AddLcAttribute ("merge_problem", oprd, orig_def->GetParentOpPtr(), 
01676                     (legoProc *) FindParentRegionType (RT_PROC, orig_def->GetParentOpPtr())); 
01677     return TRUE; 
01678   }
01679   return FALSE; 
01680 }
01681 
01682 int list_scheduler::IsMergeProblem (legoOprd *orig_def)
01683 {  
01684   legoOprd *use, *def;
01685   oprdList *defs, *uses;
01686   edgeList *edgelist;
01687   opEdges *edge;
01688   int AnyTreegionLiveIn = FALSE; 
01689   int UsePreceedsDefInBlock; 
01690   legoOp *predecessor_op; 
01691 
01692   dderr("RENAME: IsMergeProblem\n");
01693 
01694   if (FindLcAttribute("merge_problem", orig_def->GetParentOpPtr()) != NULL) {
01695     return TRUE; 
01696   }
01697   
01698   // there is a merge problem if a use outside of the treegion has  
01699   // another reaching def from inside the treegion which dominates it.
01700 
01701   for (uses = Chains->GetDUChains()->Lookup (orig_def);
01702        (uses != NULL) && (Chains->GetDUChains()->NotFound() == FALSE);
01703        uses = uses->GetNextListPtr()) {
01704     use = uses->GetOprdPtr();
01705 
01706     // first determine if this use is from outside of treegion or from 
01707     // within the treegion but not dominated by orig_def (due to loopback). 
01708     // Because of the nature of treegions, there can not be a 
01709     // merge problem from within a treegion unless otherwise.
01710 
01711     // Determine if this use preceeds the defining op in its own block 
01712     UsePreceedsDefInBlock = FALSE; 
01713     for (predecessor_op = orig_def->GetParentOpPtr(); 
01714          predecessor_op != NULL; 
01715          predecessor_op = predecessor_op->GetPrevLink()) {
01716       if (predecessor_op == use->GetParentOpPtr()) {
01717         UsePreceedsDefInBlock = TRUE; 
01718         break; 
01719       }
01720     }
01721     if ((((legoRegion *) use->GetParentOpPtr()->GetParentBlockPtr())->GetParentPtr() != Region) || 
01722         (!DescendantofBlock( (int) orig_def->GetParentOpPtr()->GetParentBlockPtr(), use->GetParentOpPtr() ) || UsePreceedsDefInBlock)) {
01723       for (defs = Chains->GetUDChains()->Lookup (use);
01724            (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
01725            defs = defs->GetNextListPtr()) {
01726         def = defs->GetOprdPtr();
01727         // if def != orig_def and is from the same treegion and orig_def is 
01728         // dominated by def, then we have a merge problem.
01729         if ((def != orig_def) && 
01730             (((legoRegion *) def->GetParentOpPtr()->GetParentBlockPtr())->GetParentPtr() == Region) &&
01731             DescendantofBlock( (int) def->GetParentOpPtr()->GetParentBlockPtr(), orig_def->GetParentOpPtr() )) {
01732           dderr("RENAME: IsMergeProblem = TRUE\n");
01733           return TRUE; 
01734         }
01735         // There is also potential for a problem if renaming results in 
01736         // renaming of the same operand live-in to this treegion if global 
01737         // renaming is used. This means that it could be incorrect to 
01738         // speculate the original op even after global renaming. 
01739         for (edgelist = Region->GetInEdgesPtr();
01740              edgelist != NULL; edgelist = edgelist->GetNextListPtr()) {
01741           if ((edge = edgelist->GetEdgePtr()) != NULL)
01742             AnyTreegionLiveIn = anyliveout (orig_def->GetParentOpPtr(), edge);
01743           if (AnyTreegionLiveIn) break;
01744         }
01745         if (AnyTreegionLiveIn) {
01746           dderr("RENAME: IsMergeProblem = TRUE due to TreegionLiveIn\n");
01747           return TRUE; 
01748         }
01749       }
01750     }
01751   }
01752   dderr("RENAME: IsMergeProblem = FALSE\n");
01753   return FALSE; 
01754 }
01755 
01756 int list_scheduler::Rename (legoOp *op, int RegNum, knobs *Knobs, legoRegion *proc_ptr, 
01757             int Final_Pass, int IncMaxRegNum, int Hazardous)
01758 {
01759   int UseOutsideTreeOrNotDom = FALSE, UseInsideTreeAndDom = FALSE, MergeProblem = FALSE;
01760   edgeList *edgelist;
01761   opEdges *edge;
01762   legoOprd *destoprd;
01763   legoOprd *use;
01764   oprdList *uses;
01765   int UsePreceedsDefInBlock; 
01766   legoOp *predecessor_op; 
01767   int rn_conflict; 
01768   char *regiontype, fully_if_convert;
01769   int FullyIfConverted; 
01770   
01771   derr( ">> Rename(): renaming op " << op->GetOpId() << "\n" );
01772   
01773   // Data-Flow analysis (LiveVars()/RDefs()) not yet sophisticated enough 
01774   // to support renaming for FICTs
01775   Knobs->SetDefaultPanel ("ccom");
01776   Knobs->Read ("region", regiontype);
01777   Knobs->Read ("fully-if-convert", fully_if_convert);
01778   FullyIfConverted = FALSE;
01779   if ((strcmp (regiontype, "FICT") == 0) || 
01780       (fully_if_convert && Final_Pass)) {
01781     FullyIfConverted = TRUE;
01782   }
01783   if (FullyIfConverted == TRUE) {
01784     return (RENAMING_CONFLICT);
01785   }
01786   
01787   // Need to determine what type of renaming is required
01788   // If any dests are other then OT_REG. This op actually can not be 
01789   // scheduled at this time (renaming only allowed for OT_REG)
01790   for (destoprd = op->GetDestOprdPtr(); 
01791        destoprd != NULL; 
01792        destoprd = destoprd->GetNextOprdPtr()) {
01793     if ((destoprd->GetOprdType() != OT_REG) && 
01794         (destoprd->GetOprdType() != OT_UNDEFINED)) {
01795       return (RENAMING_CONFLICT);
01796     }
01797     // also can not rename registers already bound by register renaming
01798     if (destoprd->GetOprdRegType() == RT_BR) {
01799       return (RENAMING_CONFLICT); 
01800     }
01801   }
01802 
01803   // Need to determine if there are any uses outside of treegion for this op 
01804   // or if any uses from within treegion are not dominated by this op 
01805   for (destoprd = op->GetDestOprdPtr(); 
01806        destoprd != NULL; 
01807        destoprd = destoprd->GetNextOprdPtr()) {
01808     for (uses = Chains->GetDUChains()->Lookup (destoprd);
01809          (uses != NULL) && (Chains->GetDUChains()->NotFound() == FALSE);
01810          uses = uses->GetNextListPtr()) {
01811       use = uses->GetOprdPtr();
01812       // Determine if this use preceeds the defining op in its own block 
01813       UsePreceedsDefInBlock = FALSE; 
01814       for (predecessor_op = op; 
01815            predecessor_op != NULL; 
01816            predecessor_op = predecessor_op->GetPrevLink()) {
01817         if (predecessor_op == use->GetParentOpPtr()) {
01818           UsePreceedsDefInBlock = TRUE; 
01819           break; 
01820         }
01821       }
01822       if ((((legoRegion *) use->GetParentOpPtr()->GetParentBlockPtr())->GetParentPtr() != Region) || 
01823           (!DescendantofBlock( (int) destoprd->GetParentOpPtr()->GetParentBlockPtr(), use->GetParentOpPtr() ) || UsePreceedsDefInBlock)) {
01824         UseOutsideTreeOrNotDom = TRUE;
01825         break;
01826       }
01827     }
01828     if (UseOutsideTreeOrNotDom) break; 
01829   }
01830 
01831   if (!UseOutsideTreeOrNotDom) {
01832     dderr ("RENAMING: SimpleRename\n");
01833     SimpleRename(op, RegNum, IncMaxRegNum);
01834   }
01835   else {
01836     // A copy must be inserted if a use outside of the treegion 
01837     // (live-out) has more than one reaching definition from within 
01838     // the treegion. Renaming just one of the reaching defs would be 
01839     // incorrect. This happens if the reaching defs merge into a use. 
01840     // I call this the MergeProblem. 
01841     if (!Hazardous) {
01842       for (destoprd = op->GetDestOprdPtr(); 
01843            destoprd != NULL; 
01844            destoprd = destoprd->GetNextOprdPtr()) {
01845         if (destoprd->GetOprdType() != OT_UNDEFINED) 
01846           MergeProblem = IsMergeProblem(destoprd);
01847         if (MergeProblem) break;
01848       } 
01849     }
01850     else {
01851       // It is more hazardous to rename to the same RegNum during operation 
01852       // combining. This can introduce output or anti deps that were not 
01853       // seen during BuildDag() and can result in-correct code. 
01854       MergeProblem = TRUE; 
01855     }
01856     if (MergeProblem) {
01857       // only continue by inserting a copy op if this op has a use from 
01858       // within the Treegion that it dominates. This will also stop 
01859       // recursive replacement of copy ops as they will not have uses from 
01860       // within the Treegion that they dominate
01861       for (destoprd = op->GetDestOprdPtr(); 
01862            destoprd != NULL; 
01863            destoprd = destoprd->GetNextOprdPtr()) {
01864         for (uses = Chains->GetDUChains()->Lookup (destoprd);
01865              (uses != NULL) && (Chains->GetDUChains()->NotFound() == FALSE);
01866              uses = uses->GetNextListPtr()) {
01867           use = uses->GetOprdPtr();
01868           // Determine if this use preceeds the defining op in its own block 
01869           UsePreceedsDefInBlock = FALSE; 
01870           for (predecessor_op = op; 
01871                predecessor_op != NULL; 
01872                predecessor_op = predecessor_op->GetPrevLink()) {
01873             if (predecessor_op == use->GetParentOpPtr()) {
01874               UsePreceedsDefInBlock = TRUE; 
01875               break; 
01876             }
01877           }
01878           if ((((legoRegion *) use->GetParentOpPtr()->GetParentBlockPtr())->GetParentPtr() == Region) &&
01879               (DescendantofBlock( (int) destoprd->GetParentOpPtr()->GetParentBlockPtr(), use->GetParentOpPtr() ) && !UsePreceedsDefInBlock)) {
01880             UseInsideTreeAndDom = TRUE;
01881             break;
01882           }
01883         }
01884         if (UseInsideTreeAndDom) break; 
01885       }
01886       
01887       if (UseInsideTreeAndDom) {
01888         
01889         dderr ("RENAMING: SimpleRenameWithCopy\n");
01890         rn_conflict = AddCopyOps(op);
01891 
01892         if (rn_conflict == RENAMING_CONFLICT) {
01893           derr("RENAMING: rn_conflict, AddCopyOp() unable to schedule copy \n");
01894           return (RENAMING_CONFLICT);
01895         }
01896         
01897         // I can get by with just calling SimpleRename because RDefs 
01898         // have been adjusted during AddCopyOps() so that the only uses of 
01899         // this op (including new copy op) are now all within the Treegion 
01900         SimpleRename(op, RegNum, IncMaxRegNum);
01901         
01902         dderr ("Copy op added while renaming op " << op->GetOpId() << "\n");
01903         
01904         // AddCopyOps() is now incrementally updates RDefs
01905       }
01906       else {
01907         derr("RENAMING: rn_conflict, Merge Problem, no uses dominated by op in Treegion\n");
01908         return (RENAMING_CONFLICT);
01909       }
01910     }
01911     else {
01912       dderr ("RENAMING: GlobalRename\n");
01913       // It is also still possible that there is a 'remote' Merge Problem 
01914       // not caught by the original IsMergeProblem() check.
01915       // If there is, finish with the global rename but return a 
01916       // RENAMING_CONFLICT (possible to re-do Rename with Hazardous, 
01917       // forcing a copy to be inserted, but this is infrequent).
01918       MergeProblemDuringGlobal = FALSE;
01919       GlobalRename(op, RegNum, IncMaxRegNum);
01920       if (MergeProblemDuringGlobal == TRUE) {
01921         return (RENAMING_CONFLICT);
01922       }
01923     }
01924   }
01925   return (NO_RENAMING_CONFLICT);
01926 }
01927 
01928 int list_scheduler::anyliveout (legoOp *op, opEdges *edge)
01929 {
01930   attrs *liveattr;
01931   legoOprd *def, *liveoprd;
01932 
01933   liveattr = FindLiveAttribute (edge);
01934   if (liveattr == NULL) return 0;
01935 
01936   //  for (def = FindFirstDef (op); def != NULL; def = def->GetNextOprdPtr())
01937   for (def = op->GetDestOprdPtr(); def != NULL; def = def->GetNextOprdPtr())
01938     {
01939       for (liveoprd = liveattr->GetAttrOprdPtr();
01940            liveoprd != NULL; liveoprd = liveoprd->GetNextOprdPtr())
01941         {
01942           if (liveoprd->GetOprdType() != def->GetOprdType())
01943             continue;  // different type
01944           if (liveoprd->GetOprdRegNum() != def->GetOprdRegNum())
01945             continue;  // different register number / macro
01946           if ((def->GetOprdType() != OT_MACRO) && 
01947               (liveoprd->GetOprdFileType() != def->GetOprdFileType()))
01948             continue;  // different file type. NOT IMPORTANT for Macro Regs
01949 
01950           // If we get here, the def is live-out along edge.
01951           return 1;
01952         } // end for
01953     } // end for
01954 
01955   // Check the return macro for BRLs too.
01956   if (op->GetOpcode() == BRL)
01957     {
01958       def = FindReturnMacro (op);
01959       if (def == NULL) return 0;  // we're done!
01960       for (liveoprd = liveattr->GetAttrOprdPtr();
01961            liveoprd != NULL; liveoprd = liveoprd->GetNextOprdPtr())
01962         {
01963           if (liveoprd->GetOprdType() != OT_MACRO) continue;
01964           if (liveoprd->GetOprdRegNum() != def->GetOprdRegNum()) continue;
01965           if (liveoprd->GetOprdFileType() != def->GetOprdFileType()) continue;
01966 
01967           // If we get here, the def is live-out along edge.
01968           return 1;
01969         } // end for
01970     } // end if
01971 
01972   return 0;
01973 } // end anyliveout
01974 
01975 void list_scheduler::RemoveOutputDepsAfterRename (legoOprd *renamed_def)
01976 {
01977   legoOp *parent_op; 
01978   vector < BigListElement >::iterator ListPtrParent, ListPtrPredecessor, ListPtrSuccessor;
01979   vector < SmallListElement >::iterator Front, Back;
01980   enum edgeTypes edgetype;  
01981   legoOprd *def1, *def2; 
01982   int StillOutputDependent;
01983 
01984   parent_op = renamed_def->GetParentOpPtr(); 
01985 
01986   // Renaming scope sometimes beyond Treegion scope
01987   if (((legoRegion *) parent_op->GetParentBlockPtr())->GetParentPtr() 
01988       != Region) {
01989     return; 
01990   }
01991   
01992   // Find the op DagNode
01993   ListPtrParent = List->begin();
01994   while ((*ListPtrParent).GetOp()->GetOpId() != 
01995          parent_op->GetOpId()) 
01996     ListPtrParent++; 
01997   
01998   for (Front = (*ListPtrParent).Successors->begin(),
01999        Back = (*ListPtrParent).Successors->end(); 
02000        Front != Back; ) {
02001 
02002     edgetype = (*Front).GetDependencyType();
02003 
02004     // Find the DagNode for the Successor op
02005     ListPtrSuccessor = List->begin();
02006     while ((*ListPtrSuccessor).GetOp()->GetOpId() != 
02007            (*Front).GetOp()->GetOpId()) 
02008       ListPtrSuccessor++; 
02009     
02010     // increment now (Front may be removed later) 
02011     Front++;
02012     
02013     if (edgetype == ET_REGOUT) {
02014       
02015       // This outputdep could be do to another def. Verify that there is no 
02016       // longer an outputdep.
02017       StillOutputDependent = FALSE;
02018       for (def1 = (*ListPtrSuccessor).GetOp()->GetDestOprdPtr();
02019            def1 != NULL;
02020            def1 = def1->GetNextOprdPtr()) {
02021         for (def2 = parent_op->GetDestOprdPtr(); 
02022              def2 != NULL;
02023              def2 = def2->GetNextOprdPtr()) {
02024           if ( def1->GetOprdType() != def2->GetOprdType() ) continue;
02025           if ( def1->GetOprdRegNum() != def2->GetOprdRegNum() ) continue;
02026           if ( def1->GetOprdType() != OT_MACRO &&
02027               def1->GetOprdFileType() != def2->GetOprdFileType() )
02028             continue; 
02029           StillOutputDependent = TRUE;
02030           break; 
02031         }
02032         if (StillOutputDependent) break;
02033       }
02034       
02035       if (!StillOutputDependent) {
02036         // Remove this Pair
02037         Front = (*ListPtrParent).RemoveSuccessor(ET_REGOUT, 
02038                                                  (*ListPtrSuccessor).GetOp());
02039         // Reset Back
02040         Back = (*ListPtrParent).Successors->end();
02041         temperr ("\nRemoveSuccessor (opId = " << (*ListPtrSuccessor).GetOp()->GetOpId() << ") of opId = " << (*ListPtrParent).GetOp()->GetOpId() << "\n");  
02042         (*ListPtrSuccessor).RemovePredecessor(ET_REGOUT, 
02043                                               (*ListPtrParent).GetOp());
02044         temperr ("\nRemovePredecessor (opId = " << (*ListPtrParent).GetOp()->GetOpId() << ") of opId = " << (*ListPtrSuccessor).GetOp()->GetOpId() << "\n");
02045       }
02046     }
02047   }
02048   
02049   for (Front = (*ListPtrParent).Predecessors->begin(),
02050        Back = (*ListPtrParent).Predecessors->end(); 
02051        Front != Back; ) {
02052 
02053     edgetype = (*Front).GetDependencyType();
02054 
02055     // Find the DagNode for the Predecessor op
02056     ListPtrPredecessor = List->begin();
02057     while ((*ListPtrPredecessor).GetOp()->GetOpId() != 
02058            (*Front).GetOp()->GetOpId()) 
02059       ListPtrPredecessor++; 
02060     
02061     // increment now (Front may be removed later) 
02062     Front++;
02063     
02064     if (edgetype == ET_REGOUT) {
02065       
02066       // This outputdep could be do to another def. Verify that there is no 
02067       // longer an outputdep.
02068       StillOutputDependent = FALSE;
02069       for (def1 = (*ListPtrPredecessor).GetOp()->GetDestOprdPtr();
02070            def1 != NULL;
02071            def1 = def1->GetNextOprdPtr()) {
02072         for (def2 = parent_op->GetDestOprdPtr(); 
02073              def2 != NULL;
02074              def2 = def2->GetNextOprdPtr()) {
02075           if ( def1->GetOprdType() != def2->GetOprdType() ) continue;
02076           if ( def1->GetOprdRegNum() != def2->GetOprdRegNum() ) continue;
02077           if ( def1->GetOprdType() != OT_MACRO &&
02078               def1->GetOprdFileType() != def2->GetOprdFileType() )
02079             continue; 
02080           StillOutputDependent = TRUE;
02081           break; 
02082         }
02083         if (StillOutputDependent) break;
02084       }
02085       
02086       if (!StillOutputDependent) {
02087         // Remove this Pair
02088         Front = (*ListPtrParent).RemovePredecessor(ET_REGOUT, 
02089                                                  (*ListPtrPredecessor).GetOp());
02090         // Reset Back
02091         Back = (*ListPtrParent).Predecessors->end();
02092         temperr ("\nRemovePredecessor (opId = " << (*ListPtrPredecessor).GetOp()->GetOpId() << ") of opId = " << (*ListPtrParent).GetOp()->GetOpId() << "\n");  
02093         (*ListPtrPredecessor).RemoveSuccessor(ET_REGOUT, 
02094                                               (*ListPtrParent).GetOp());
02095         temperr ("\nRemoveSuccessor (opId = " << (*ListPtrParent).GetOp()->GetOpId() << ") of opId = " << (*ListPtrPredecessor).GetOp()->GetOpId() << "\n");
02096       }
02097     }
02098   }
02099 }
02100 
02101 void list_scheduler::RemoveOutputDepsAfterRenameUp (legoOprd *renamed_def)
02102 {
02103   legoOp *parent_op; 
02104   vector < BigListElement >::iterator ListPtrParent, ListPtrPredecessor;
02105   vector < SmallListElement >::iterator Front, Back;
02106   enum edgeTypes edgetype;  
02107   legoOprd *def1, *def2; 
02108   int StillOutputDependent;
02109 
02110   parent_op = renamed_def->GetParentOpPtr(); 
02111 
02112   // Renaming scope sometimes beyond Treegion scope
02113   if (((legoRegion *) parent_op->GetParentBlockPtr())->GetParentPtr() 
02114       != Region) {
02115     return; 
02116   }
02117   
02118   // Find the op DagNode
02119   ListPtrParent = List->begin();
02120   while ((*ListPtrParent).GetOp()->GetOpId() != 
02121          parent_op->GetOpId()) 
02122     ListPtrParent++; 
02123   
02124   for (Front = (*ListPtrParent).Predecessors->begin(),
02125        Back = (*ListPtrParent).Predecessors->end(); 
02126        Front != Back; ) {
02127 
02128     edgetype = (*Front).GetDependencyType();
02129 
02130     // Find the DagNode for the Predecessor op
02131     ListPtrPredecessor = List->begin();
02132     while ((*ListPtrPredecessor).GetOp()->GetOpId() != 
02133            (*Front).GetOp()->GetOpId()) 
02134       ListPtrPredecessor++; 
02135     
02136     // increment now (Front may be removed later) 
02137     Front++;
02138     
02139     if (edgetype == ET_REGOUT) {
02140       
02141       // This outputdep could be do to another def. Verify that there is no 
02142       // longer an outputdep.
02143       StillOutputDependent = FALSE;
02144       for (def1 = (*ListPtrPredecessor).GetOp()->GetDestOprdPtr();
02145            def1 != NULL;
02146            def1 = def1->GetNextOprdPtr()) {
02147         for (def2 = parent_op->GetDestOprdPtr(); 
02148              def2 != NULL;
02149              def2 = def2->GetNextOprdPtr()) {
02150           if ( def1->GetOprdType() != def2->GetOprdType() ) continue;
02151           if ( def1->GetOprdRegNum() != def2->GetOprdRegNum() ) continue;
02152           if ( def1->GetOprdType() != OT_MACRO &&
02153               def1->GetOprdFileType() != def2->GetOprdFileType() )
02154             continue; 
02155           StillOutputDependent = TRUE;
02156           break; 
02157         }
02158         if (StillOutputDependent) break;
02159       }
02160       
02161       if (!StillOutputDependent) {
02162         // Remove this Pair
02163         Front = (*ListPtrParent).RemovePredecessor(ET_REGOUT, 
02164                                                  (*ListPtrPredecessor).GetOp());
02165         // Reset Back
02166         Back = (*ListPtrParent).Predecessors->end();
02167         temperr ("\nRemovePredecessor (opId = " << (*ListPtrPredecessor).GetOp()->GetOpId() << ") of opId = " << (*ListPtrParent).GetOp()->GetOpId() << "\n");  
02168         (*ListPtrPredecessor).RemoveSuccessor(ET_REGOUT, 
02169                                               (*ListPtrParent).GetOp());
02170         temperr ("\nRemoveSuccessor (opId = " << (*ListPtrParent).GetOp()->GetOpId() << ") of opId = " << (*ListPtrPredecessor).GetOp()->GetOpId() << "\n");
02171       }
02172     }
02173   }
02174 }
02175 
02176 void list_scheduler::RemoveAntiDepsAfterUseRename (legoOprd *renamed_use)
02177 {
02178   legoOp *parent_op; 
02179   vector < BigListElement >::iterator ListPtrParent, ListPtrSuccessor;
02180   vector < SmallListElement >::iterator Front, Back;
02181   enum edgeTypes edgetype;  
02182   legoOprd *use, *def; 
02183   int StillAntiDependent, def_regid, use_regid;
02184 
02185   parent_op = renamed_use->GetParentOpPtr(); 
02186   
02187   // Renaming scope sometimes beyond Treegion scope
02188   if (((legoRegion *) parent_op->GetParentBlockPtr())->GetParentPtr() 
02189       != Region) {
02190     return; 
02191   }
02192   
02193   // Find the op DagNode
02194   ListPtrParent = List->begin();
02195   while ((*ListPtrParent).GetOp()->GetOpId() != 
02196          parent_op->GetOpId()) 
02197     ListPtrParent++; 
02198   
02199   for (Front = (*ListPtrParent).Successors->begin(),
02200        Back = (*ListPtrParent).Successors->end(); 
02201        Front != Back; ) {
02202 
02203     edgetype = (*Front).GetDependencyType();
02204 
02205     // Find the DagNode for the Successor op
02206     ListPtrSuccessor = List->begin();
02207     while ((*ListPtrSuccessor).GetOp()->GetOpId() != 
02208            (*Front).GetOp()->GetOpId()) 
02209       ListPtrSuccessor++; 
02210     
02211     // increment now (Front may be removed later) 
02212     Front++;
02213     
02214     if (edgetype == ET_REGANTI) {
02215       
02216       // This antidep could be do to another use. Verify that there is no 
02217       // longer an antidep.
02218       StillAntiDependent = FALSE;
02219       for (def = (*ListPtrSuccessor).GetOp()->GetDestOprdPtr();
02220            def != NULL;
02221            def = def->GetNextOprdPtr()) {
02222         for (use = parent_op->GetSrcOprdPtr(); 
02223              use != NULL;
02224              use = use->GetNextOprdPtr()) {
02225           if ( def->GetOprdType() != use->GetOprdType() ) continue;
02226           if ( def->GetOprdRegNum() != use->GetOprdRegNum() ) continue;
02227           if ( def->GetOprdType() != OT_MACRO &&
02228               def->GetOprdFileType() != use->GetOprdFileType() )
02229             continue; 
02230           StillAntiDependent = TRUE;
02231           break; 
02232         }
02233         if (StillAntiDependent) break;
02234         // The use could be the btr operand of a BRL, check other sources
02235         // Need to assume that BRLs use all INT_P*'s, FLT_P*'s, DBL_P*'s. 
02236         if (parent_op->GetOpcode() == BRL) {
02237           for (use_regid = INT_P1; use_regid <= DBL_P2; use_regid++) {
02238             if ( def->GetOprdType() != OT_MACRO ) continue; 
02239             if ( def->GetOprdRegNum() != use_regid ) continue;
02240             StillAntiDependent = TRUE;
02241             break; 
02242           }
02243         }
02244         if (StillAntiDependent) break;
02245       }
02246       if (!StillAntiDependent && 
02247           ((*ListPtrSuccessor).GetOp()->GetOpcode() == BRL)) {
02248         for (def_regid = INT_P1; def_regid <= DBL_RET; def_regid++) {
02249           for (use = parent_op->GetSrcOprdPtr(); 
02250                use != NULL;
02251                use = use->GetNextOprdPtr()) {
02252             if ( use->GetOprdType() != OT_MACRO ) continue;
02253             if ( def_regid != use->GetOprdRegNum() ) continue;
02254             StillAntiDependent = TRUE;
02255             break; 
02256           }
02257           if (StillAntiDependent) break;
02258           // BRLs followed by BRL alway remain dependent
02259           if (parent_op->GetOpcode() == BRL) {
02260             StillAntiDependent = TRUE;
02261           }
02262           if (StillAntiDependent) break;
02263         }
02264       }
02265         
02266       if (!StillAntiDependent) {
02267         // Remove this Pair
02268         Front = (*ListPtrParent).RemoveSuccessor(ET_REGANTI, 
02269                                                  (*ListPtrSuccessor).GetOp());
02270         // Reset Back
02271         Back = (*ListPtrParent).Successors->end();
02272         temperr ("\nRemoveSuccessor (opId = " << (*ListPtrSuccessor).GetOp()->GetOpId() << ") of opId = " << (*ListPtrParent).GetOp()->GetOpId() << "\n");  
02273         (*ListPtrSuccessor).RemovePredecessor(ET_REGANTI, 
02274                                               (*ListPtrParent).GetOp());
02275         temperr ("\nRemovePredecessor (opId = " << (*ListPtrParent).GetOp()->GetOpId() << ") of opId = " << (*ListPtrSuccessor).GetOp()->GetOpId() << "\n");
02276       }
02277     }
02278   }
02279 }
02280 
02281 void list_scheduler::RemoveAntiDepsAfterDefRename (legoOprd *renamed_def)
02282 {
02283   legoOp *parent_op; 
02284   vector < BigListElement >::iterator ListPtrParent, ListPtrPredecessor;
02285   vector < SmallListElement >::iterator Front, Back;
02286   enum edgeTypes edgetype;  
02287   legoOprd *use, *def; 
02288   int StillAntiDependent, def_regid, use_regid;
02289 
02290   parent_op = renamed_def->GetParentOpPtr(); 
02291   
02292   // Renaming scope sometimes beyond Treegion scope
02293   if (((legoRegion *) parent_op->GetParentBlockPtr())->GetParentPtr() 
02294       != Region) {
02295     return; 
02296   }
02297   
02298   // Find the op DagNode
02299   ListPtrParent = List->begin();
02300   while ((*ListPtrParent).GetOp()->GetOpId() != 
02301          parent_op->GetOpId()) 
02302     ListPtrParent++; 
02303   
02304   for (Front = (*ListPtrParent).Predecessors->begin(),
02305        Back = (*ListPtrParent).Predecessors->end(); 
02306        Front != Back; ) {
02307 
02308     edgetype = (*Front).GetDependencyType();
02309 
02310     // Find the DagNode for the Predecessor op
02311     ListPtrPredecessor = List->begin();
02312     while ((*ListPtrPredecessor).GetOp()->GetOpId() != 
02313            (*Front).GetOp()->GetOpId()) 
02314       ListPtrPredecessor++; 
02315     
02316     // increment now (Front may be removed later) 
02317     Front++;
02318     
02319     if (edgetype == ET_REGANTI) {
02320       
02321       // This antidep could be do to another def. Verify that there is no 
02322       // longer an antidep.
02323       StillAntiDependent = FALSE;
02324       for (def = parent_op->GetDestOprdPtr();
02325            def != NULL;
02326            def = def->GetNextOprdPtr()) {
02327         for (use = (*ListPtrPredecessor).GetOp()->GetSrcOprdPtr(); 
02328              use != NULL;
02329              use = use->GetNextOprdPtr()) {
02330           if ( def->GetOprdType() != use->GetOprdType() ) continue;
02331           if ( def->GetOprdRegNum() != use->GetOprdRegNum() ) continue;
02332           if ( def->GetOprdType() != OT_MACRO &&
02333               def->GetOprdFileType() != use->GetOprdFileType() )
02334             continue; 
02335           StillAntiDependent = TRUE;
02336           break; 
02337         }
02338         if (StillAntiDependent) break;
02339         // The use could be the btr operand of a BRL, check other sources
02340         // Need to assume that BRLs use all INT_P*'s, FLT_P*'s, DBL_P*'s. 
02341         if ((*ListPtrPredecessor).GetOp()->GetOpcode() == BRL) {
02342           for (use_regid = INT_P1; use_regid <= DBL_P2; use_regid++) {
02343             if ( def->GetOprdType() != OT_MACRO ) continue; 
02344             if ( def->GetOprdRegNum() != use_regid ) continue;
02345             StillAntiDependent = TRUE;
02346             break; 
02347           }
02348         }
02349         if (StillAntiDependent) break;
02350       }
02351       if (!StillAntiDependent && 
02352           (parent_op->GetOpcode() == BRL)) {
02353         for (def_regid = INT_P1; def_regid <= DBL_RET; def_regid++) {
02354           for (use = (*ListPtrPredecessor).GetOp()->GetSrcOprdPtr();
02355                use != NULL;
02356                use = use->GetNextOprdPtr()) {
02357             if ( use->GetOprdType() != OT_MACRO ) continue;
02358             if ( def_regid != use->GetOprdRegNum() ) continue;
02359             StillAntiDependent = TRUE;
02360             break; 
02361           }
02362           if (StillAntiDependent) break;
02363           // BRLs followed by BRL alway remain dependent
02364           if ((*ListPtrPredecessor).GetOp()->GetOpcode() == BRL) {
02365             StillAntiDependent = TRUE;
02366           }
02367           if (StillAntiDependent) break;
02368         }
02369       }
02370         
02371       if (!StillAntiDependent) {
02372         // Remove this Pair
02373         Front = (*ListPtrParent).RemovePredecessor(ET_REGANTI, 
02374                                                    (*ListPtrPredecessor).GetOp());
02375         // Reset Back
02376         Back = (*ListPtrParent).Predecessors->end();
02377         temperr ("\nRemovePredecessor (opId = " << (*ListPtrPredecessor).GetOp()->GetOpId() << ") of opId = " << (*ListPtrParent).GetOp()->GetOpId() << "\n");  
02378         (*ListPtrPredecessor).RemoveSuccessor(ET_REGANTI, 
02379                                               (*ListPtrParent).GetOp());
02380         temperr ("\nRemoveSuccessor (opId = " << (*ListPtrParent).GetOp()->GetOpId() << ") of opId = " << (*ListPtrPredecessor).GetOp()->GetOpId() << "\n");
02381       }
02382     }
02383   }
02384 }
02385 
02386 
02387 /*
02388  * AddDPRemoveAttribute
02389  *   op = op to annotate
02390  *   returns: new attr attached to op
02391  *
02392  * Attaches a new attr to the op indicating that this op should be removed 
02393  * after list scheduling this region. Ops are removed when dominator 
02394  * parallelism allows them to be merged with other ops. Removing them 
02395  * before list scheduling screws up the dag and priority lists, so it 
02396  * is delayed until after scheduling. 
02397  * 
02398  */
02399 static attrs *
02400 AddDPRemoveAttribute (legoOp *op)
02401 {
02402   legoRegion *block;
02403   legoOprd *oprd;
02404   attrs *attr;
02405 
02406   block = (legoRegion *) op->GetParentBlockPtr();
02407   if (block == NULL) return NULL;
02408 
02409   oprd = new legoOprd;
02410 
02411   attr = AddLcAttribute ("dp_remove", oprd, op,
02412                            (legoProc *) FindParentRegionType (RT_PROC, op));
02413   return attr;
02414 
02415 }
02416 
02417 /*
02418  * copy_operand
02419  *   Src = source operand
02420  *   Target = target operand
02421  *
02422  * Copies fields from Src to Target, assuming a register-type operand.
02423  * Does NOT copy next and prev pointers.
02424  */
02425 void list_scheduler::copy_operand( legoOprd *Src, legoOprd *Target )
02426 {
02427    Target->SetOprdType( Src->GetOprdType() );
02428    Target->SetValid( Src->GetValid() );
02429    Target->SetOprdRegType( Src->GetOprdRegType() );
02430    Target->SetOprdRegNum( Src->GetOprdRegNum() );
02431    Target->SetOprdDataType( Src->GetOprdDataType() );
02432    Target->SetOprdFileType( Src->GetOprdFileType() );
02433    Target->SetOprdRegStyle( Src->GetOprdRegStyle() );
02434    Target->SetIntValue( Src->GetOprdIntValue() );
02435 } // end copy_operand
02436 
02437 /*
02438  * add_to_existing_attr
02439  *   Attr = existing live attribute
02440  *   NewOprd = new operand to add to attribute
02441  *
02442  * Adds a copy of the operand NewOprd to attribute Attr. If a copy
02443  * already resides in Attr, no action is taken.
02444  */
02445 void list_scheduler::add_to_existing_attr( attrs *Attr, legoOprd *NewOprd )
02446 {
02447    legoOprd *OprdPtr, *ShadowPtr;
02448 
02449    derr( ">> add_to_existing_attr\n" );
02450 
02451    // Find the end of the Attr list.
02452 
02453    //   derr( "   Attr before addition\n" );
02454    //   print_attr( Attr );
02455    for ( OprdPtr = ShadowPtr = Attr->GetAttrOprdPtr(); OprdPtr != NULL;
02456          ShadowPtr = OprdPtr, OprdPtr = OprdPtr->GetNextOprdPtr() )
02457      {
02458        if ( OprdPtr->GetOprdType() == NewOprd->GetOprdType() &&
02459             OprdPtr->GetOprdRegNum() == NewOprd->GetOprdRegNum() &&
02460             OprdPtr->GetOprdFileType() == NewOprd->GetOprdFileType() )
02461          {
02462            derr( "   already present in attribute\n" );
02463            return;  // no change
02464          } // end if
02465      } // end for
02466 
02467    // At this point, OprdPtr should be NULL and ShadowPtr should point to
02468    // the last legoOprd in the list.
02469    if ( OprdPtr != NULL ) derr( "   ** OprdPtr not NULL!! **\n" );
02470 
02471    OprdPtr = ShadowPtr->AddOprd();  // create new operand at end of list
02472 
02473    // Copy all legoOprd fields individually.
02474    copy_operand( NewOprd, OprdPtr );
02475 
02476    //   derr( "   Attr after addition\n" );
02477    //   print_attr( Attr );
02478 
02479    derr( "<< add_to_existing_attr\n" );
02480    return;
02481 } // end add_to_existing_attr
02482 
02483 /*
02484  * create_new_attr
02485  *   Edge = edge on which to add live attribute
02486  *   Oprd = operand to add to attribute
02487  *   Proc = proc to whose dictionary to add edge
02488  *
02489  * Creates a new live attribute for Edge containing a copy of Oprd.
02490  */
02491 void list_scheduler::create_new_attr( opEdges *Edge, legoOprd *Oprd, legoProc *Proc )
02492 {
02493   legoOprd *NewOprd = new legoOprd();
02494 
02495   derr( ">> create_new_attr\n" );
02496 
02497   // Copy all legoOprd fields individually.
02498   copy_operand( Oprd, NewOprd );
02499 
02500   // Add the attribute after creating a new operand copy.
02501   AddLiveAttribute( NewOprd, Edge, Proc );
02502 
02503   derr( "<< create_new_attr\n" );
02504   return;
02505 } // end create_new_attr
02506 
02507 int list_scheduler::FixLiveVarsUp (legoOp *op, 
02508                                    legoOp *before_op, 
02509                                    legoProc *proc_ptr)
02510 {
02511   attrs *liveattr;
02512   legoRegion *before_block_ptr, *block_ptr;
02513   edgeList *edgelist;
02514   opEdges *edge;
02515   legoOprd *def;
02516 
02517   before_block_ptr = (legoRegion *) before_op->GetParentBlockPtr();
02518   block_ptr = (legoRegion *) op->GetParentBlockPtr();
02519 
02520   while (block_ptr != before_block_ptr) {
02521     // For each block in treegion (excluding root), only one InEdge
02522     edgelist = block_ptr->GetInEdgesPtr();
02523     edge = edgelist->GetEdgePtr();
02524     for (def = op->GetDestOprdPtr(); 
02525          def != NULL; 
02526          def = def->GetNextOprdPtr()) {
02527       if (def->GetOprdType() != OT_UNDEFINED) {
02528         liveattr = FindLiveAttribute( edge );
02529         if ( liveattr != NULL ) { // exists
02530           add_to_existing_attr( liveattr, def );
02531         }
02532         else {
02533           create_new_attr( edge, def, proc_ptr );
02534         }
02535       }
02536     }
02537     block_ptr = block_ptr->GetParents()->GetRegionPtr();
02538   }
02539 } // end FixLiveVarsUp
02540 
02541 int list_scheduler::FixLiveVarsDown (legoOp *op, 
02542                                      opEdges *edge,
02543                                      legoProc *proc_ptr)
02544 {
02545   attrs *liveattr;
02546   legoOprd *use;
02547 
02548   for (use = op->GetSrcOprdPtr(); 
02549        use != NULL; 
02550        use = use->GetNextOprdPtr()) {
02551     if ((use->GetOprdType() == OT_REG) ||
02552         (use->GetOprdType() == OT_MACRO)) {
02553       liveattr = FindLiveAttribute( edge );
02554       if ( liveattr != NULL ) { // exists
02555         add_to_existing_attr( liveattr, use );
02556       }
02557       else {
02558         create_new_attr( edge, use, proc_ptr );
02559       }
02560     }
02561   }
02562 
02563   for (use = op->GetPredOprdPtr(); 
02564        use != NULL; 
02565        use = use->GetNextOprdPtr()) {
02566     if ((use->GetOprdType() == OT_REG) ||
02567         (use->GetOprdType() == OT_MACRO)) {
02568       liveattr = FindLiveAttribute( edge );
02569       if ( liveattr != NULL ) { // exists
02570         add_to_existing_attr( liveattr, use );
02571       }
02572       else {
02573         create_new_attr( edge, use, proc_ptr );
02574       }
02575     }
02576   }
02577 
02578   if (op->GetOpcode() == BRL) {
02579     // Need to assume that BRLs use all INT_P*'s, FLT_P*'s, and DBL_P*'s. 
02580     legoOprd *Oprd = new legoOprd(); 
02581     // these are always MACRO regs
02582     Oprd->SetOprdType(OT_MACRO);
02583     for (int regid = INT_P1; regid <= DBL_P2; regid++) {
02584       Oprd->SetOprdRegNum(regid);
02585       liveattr = FindLiveAttribute( edge );
02586       if ( liveattr != NULL ) { // exists
02587         add_to_existing_attr( liveattr, Oprd );
02588       }
02589       else {
02590         create_new_attr( edge, Oprd, proc_ptr );
02591       }
02592     }
02593     delete Oprd; 
02594   }
02595 } // end FixLiveVarsDown
02596 
02597 int list_scheduler::FixLiveVarsFromUses(legoOprd *use, legoOp *before_op, 
02598                                         legoProc *proc_ptr) {
02599 
02600   attrs *liveattr;
02601   legoRegion *before_block_ptr, *block_ptr;
02602   edgeList *edgelist;
02603   opEdges *edge;
02604 
02605   before_block_ptr = (legoRegion *) before_op->GetParentBlockPtr();
02606   block_ptr = (legoRegion *) use->GetParentOpPtr()->GetParentBlockPtr();
02607 
02608   while (block_ptr != before_block_ptr) {
02609     // For each block in treegion (excluding root), only one InEdge
02610     edgelist = block_ptr->GetInEdgesPtr();
02611     edge = edgelist->GetEdgePtr();
02612     liveattr = FindLiveAttribute( edge );
02613     if ( liveattr != NULL ) { // exists
02614       add_to_existing_attr( liveattr, use );
02615     }
02616     else {
02617       create_new_attr( edge, use, proc_ptr );
02618     }
02619     block_ptr = block_ptr->GetParents()->GetRegionPtr();
02620   }
02621 } // end FixLiveVarsFromUses
02622 
02623 int list_scheduler::AnyOutputDepsBetween(legoOp *op, legoOp *before_op, 
02624                                          legoOprd *compare_dest) {
02625   
02626   legoOp *traverse_op; 
02627   legoOprd *def; 
02628 
02629   if (op->GetPrevLink() == NULL) {
02630     traverse_op = op->GetInListPtr()->GetOpPtr(); 
02631   }
02632   else {
02633     traverse_op = op->GetPrevLink();
02634   }
02635   while (traverse_op != before_op) {
02636     if (DPG->AreOpsDependent(op, traverse_op) && 
02637         (FindLcAttribute( "dp_remove", traverse_op ) == NULL)) {
02638       for (def = traverse_op->GetDestOprdPtr(); 
02639            def != NULL; 
02640            def = def->GetNextOprdPtr()) {
02641         if (def->GetOprdType() != OT_UNDEFINED) {
02642           if ((def->GetOprdType() == OT_REG) &&
02643               (compare_dest->GetOprdType() == OT_REG) &&
02644               (def->GetOprdFileType() == 
02645                compare_dest->GetOprdFileType()) &&
02646               (def->GetOprdRegNum() == 
02647                compare_dest->GetOprdRegNum())) {
02648             return YES;
02649           }
02650           if ((def->GetOprdType() == OT_MACRO) &&
02651               (compare_dest->GetOprdType() == OT_MACRO) &&
02652               (def->GetOprdRegNum() == 
02653                compare_dest->GetOprdRegNum())) {
02654             return YES;
02655           }
02656         }
02657       }
02658     }
02659     if (traverse_op->GetPrevLink() == NULL) {
02660       traverse_op = traverse_op->GetInListPtr()->GetOpPtr(); 
02661     }
02662     else {
02663       traverse_op = traverse_op->GetPrevLink();
02664     }
02665   }
02666   return NO; 
02667 }
02668 
02669 
02670 // DoTheMessyStuff: This code allows branches to be scheduled above other 
02671 // operations (or allows ops to move below branches) during scheduling.
02672 // This usually results in copy of ops (depending on liveness out of the 
02673 // branches. Priority lists, liveness, and reaching definitions are updated 
02674 // incrementally. 
02675 int list_scheduler::DoTheMessyStuff( legoOp *op, legoRegion *proc_ptr )
02676 {
02677 
02678   legoOp *first_cmerge, *second_cmerge, *above_op, *next_above_op, *duplicate_op; 
02679   opEdges *first_edge, *second_edge;
02680   int TreegionExit, orig_op_id;
02681   opList *exit_ops; 
02682   legoOp *exit_op; 
02683   BigListElement Element;
02684   vector < BigListElement >::iterator ListIter, ListPtr2, ListPtr3;
02685   vector < SmallListElement >::iterator Front, Back;
02686   legoOprd *use, *use_first, *use_second, *def, *def_first, *def_second, *oprd; 
02687   oprdList *uses, *uses_first, *uses_second;
02688   oprdList *defs, *defs_first, *defs_second;
02689   oprdList *prev_use_first, *new_use_first, *prev_use_second, *new_use_second;
02690   oprdList *prev_def_first, *new_def_first, *prev_def_second, *new_def_second;
02691   enum edgeTypes edgetype;  
02692   int rc, eaid; 
02693   attrs *attrdictionary, *attrtail, *atscan;
02694   attrList *atlscan;
02695   legoOprd *btroprd, *cmppoprd, *PredOprd, *new_predicate;
02696   legoOp *cmppop, *pbrrop;
02697   oprdList *new_uses, *new_use, *prev_use, *oprd_list; 
02698   int one_dead;
02699   int UsePreceedsDefInBlock; 
02700   legoOp *predecessor_op;
02701   
02702   TreegionExit = NO; 
02703   for (exit_ops = Region->GetExitOpsPtr(); 
02704        exit_ops != NULL; 
02705        exit_ops = exit_ops->GetNextListPtr()) {
02706     if ((exit_op = exit_ops->GetOpPtr()) == op) {
02707       TreegionExit = YES; 
02708       break; 
02709     }
02710   }
02711   if ((op->GetOpcode() == BRU) ||  
02712       (op->GetOpcode() == DUMMY_BR) || 
02713       TreegionExit) {
02714     for (above_op = op->GetPrevLink();
02715          above_op != current_before_op; 
02716          above_op = above_op->GetPrevLink()) {
02717       if (above_op->GetOpcode() == C_MERGE) {
02718         break;
02719       }
02720       ddderr("\n *** Conflict for opId = " << op->GetOpId() << " ?????\n");
02721       if (DPG->AreOpsDependent(above_op, op)) {
02722         // not really a renaming conflict, but can not move ops 
02723         // below uncond branches (uncond branches should only occur 
02724         // as treegion exits) or other treegion exits
02725         ddderr("Yes there is a conflict\n");
02726         return (RENAMING_CONFLICT);
02727       }
02728     }
02729   }
02730   if (!TreegionExit && 
02731       ((op->GetOpcode() == BRCT) || 
02732        (op->GetOpcode() == BRCF))) { 
02733 
02734     first_cmerge = op->GetOutListPtr()->GetOpPtr(); 
02735     second_cmerge = op->GetOutListPtr()->GetNextListPtr()->GetOpPtr();
02736     first_edge = FindControlEdge (op, first_cmerge, 1);
02737     second_edge = FindControlEdge (op, second_cmerge, 1);
02738     
02739     for (next_above_op = op->GetPrevLink();
02740          ((next_above_op != current_before_op) && 
02741           (next_above_op->GetSchedTime() == UNSCHEDULED) && 
02742           (next_above_op->GetOpcode() != C_MERGE)); ) {
02743       above_op = next_above_op;
02744       next_above_op = above_op->GetPrevLink(); 
02745       
02746       // Store and BRLs no longer need to remain in blocks after moved down. 
02747       // They are now no longer speculative 
02748       if (IsStoreOp(above_op)) {
02749         oprd = new legoOprd;
02750         oprd->SetOprdType (OT_LITERAL_I);
02751         if (op->GetParentBlockPtr() == ((legoTreegion *)Region)->GetRoot()) {
02752           oprd->SetLiteralInteger(0);
02753         }
02754         else {
02755           oprd->SetLiteralInteger(((legoRegion *)current_before_op->GetParentBlockPtr())->GetRegionId());
02756         }
02757         AddLcAttribute ("no_longer_speculative", oprd, above_op, (legoProc *) proc_ptr);
02758       }
02759       if (above_op->GetOpcode() == BRL) {
02760         oprd = new legoOprd;
02761         oprd->SetOprdType (OT_LITERAL_I);
02762         if (op->GetParentBlockPtr() == ((legoTreegion *)Region)->GetRoot()) {
02763           oprd->SetLiteralInteger(0);
02764         }
02765         else {
02766           oprd->SetLiteralInteger(((legoRegion *)current_before_op->GetParentBlockPtr())->GetRegionId());
02767         }
02768         AddLcAttribute ("no_longer_speculative", oprd, above_op, (legoProc *) proc_ptr);
02769       }
02770       
02771       ddderr("\n *** Any for opId = " << op->GetOpId() << " ?????\n");
02772       if (DPG->AreOpsDependent(above_op, op)) {
02773         
02774         if (!AllowDownwardCodeMotion) return (RENAMING_CONFLICT);
02775         
02776         if (!(above_op->IsDummy())) {
02777           one_dead = FALSE;
02778           downward_motion_ops++;
02779         }
02780 
02781         if ((anyliveout(above_op, second_edge) ||
02782              IsStoreOp(above_op) ||  
02783              (above_op->GetOpcode() == BRL)) && 
02784             above_op->GetOpcode() != DEFINE) {
02785           duplicate_op = new legoOp(*above_op);
02786           duplicate_op->SetOpId(++MaxOpId);
02787 
02788           // May need to demote predicate if guarded by a predicate register
02789           if ((duplicate_op->GetOpcode() < CMPP) ||
02790               (duplicate_op->GetOpcode() > FCMPP_D_TRUE_AC_AC)) {
02791             PredOprd = duplicate_op->GetPredOprdPtr();
02792             if (PredOprd != NULL) {
02793               if (PredOprd->GetOprdType() == OT_REG) {
02794                 // Needs demotion
02795                 //cerr << "\nduplicate_op's (OpId = " << duplicate_op->GetOpId() << ") predicate (orig RegId = " << PredOprd->GetOprdRegNum() << ") demoted to ";
02796 
02797                 // Clean-up RDefs before deleting oprd
02798                 for (defs = Chains->GetUDChains()->Lookup (PredOprd);
02799                      (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
02800                      defs = defs->GetNextListPtr()) {
02801                   def = defs->GetOprdPtr();
02802                   new_uses = NULL; 
02803                   for (uses = Chains->GetDUChains()->Lookup (def);
02804                        (uses != NULL) && (Chains->GetDUChains()->NotFound() == FALSE);
02805                        uses = uses->GetNextListPtr()) {
02806                     use = uses->GetOprdPtr();
02807                     if (use != PredOprd) {
02808                       if (new_uses == NULL) {
02809                         new_uses = new oprdList;
02810                         new_uses->SetOprdPtr(use);
02811                         prev_use = new_uses;
02812                       }
02813                       else {
02814                         new_use = new oprdList;
02815                         new_use->SetOprdPtr(use);
02816                         prev_use->SetNextListPtr(new_use);
02817                         prev_use = new_use;
02818                       } 
02819                     }
02820                   }
02821                   if (Chains->GetDUChains()->NotFound() == FALSE) {
02822                     uses = Chains->GetDUChains()->Lookup (def);
02823                     delete uses; 
02824                     Chains->GetDUChains()->Set (def, new_uses);
02825                   }
02826                 }
02827                 Chains->GetUDChains()->Lookup (PredOprd);
02828                 if (Chains->GetUDChains()->NotFound() == FALSE) {
02829                   Chains->GetUDChains()->Delete (PredOprd);
02830                 }
02831                 delete PredOprd; 
02832                 
02833                 // Find the CMPP op for branch 
02834                 cmppoprd = op->GetSrcOprdPtr()->GetNextOprdPtr(); 
02835                 cmppop = NULL;
02836                 for (defs = Chains->GetUDChains()->Lookup (cmppoprd);
02837                      (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
02838                      defs = defs->GetNextListPtr()) {
02839                   def = defs->GetOprdPtr();
02840                   cmppop = def->GetParentOpPtr(); // only one CMPP op should reach
02841                   break; 
02842                 }
02843                 
02844                 dderr ("cmppop OpId is: " << cmppop->GetOpId() << "\n");
02845                 
02846                 if (cmppop == NULL) {
02847                   LegoFatal ("DoTheMessyStuff", "Can't find CMPP for branch");
02848                 } 
02849                 
02850                 // Find the PBR op for branch 
02851                 btroprd = op->GetSrcOprdPtr(); // should be 1st source
02852                 pbrrop = NULL;
02853                 for (defs = Chains->GetUDChains()->Lookup (btroprd);
02854                      (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
02855                      defs = defs->GetNextListPtr()) {
02856                   def = defs->GetOprdPtr();
02857                   pbrrop = def->GetParentOpPtr(); // only one PBRR op should reach
02858                   break; 
02859                 }
02860                 
02861                 dderr ("pbrrop OpId is: " << pbrrop->GetOpId() << "\n");
02862                 
02863                 if (pbrrop == NULL) {
02864                   LegoFatal ("DoTheMessyStuff", "Can't find PBRR/PBRA in block");
02865                 } // end if
02866                 
02867                 if (op->GetOpcode() == BRCT) {
02868                   if (pbrrop->GetSrcOprdPtr()->GetLiteralControlBlock() == 
02869                       ((legoRegion *) second_cmerge->GetParentBlockPtr())->GetRegionId()) {
02870                     new_predicate = new legoOprd(*cmppop->GetDestOprdPtr());
02871                   }
02872                   else {
02873                     new_predicate = new legoOprd(*cmppop->GetDestOprdPtr()
02874                                                  ->GetNextOprdPtr());
02875                   }
02876                 }
02877                 else {
02878                   if (pbrrop->GetSrcOprdPtr()->GetLiteralControlBlock() == 
02879                       ((legoRegion *) second_cmerge->GetParentBlockPtr())->GetRegionId()) {
02880                     new_predicate = new legoOprd(*cmppop->GetDestOprdPtr()
02881                                                  ->GetNextOprdPtr());
02882                   }
02883                   else {
02884                     new_predicate = new legoOprd(*cmppop->GetDestOprdPtr());
02885                   }
02886                 }
02887                 // Assign demoted predicate
02888                 new_predicate->SetNextOprdPtr(NULL);
02889                 duplicate_op->SetPredOprdPtr(new_predicate);
02890                 // Now adjust Chains 
02891                 oprd_list = new oprdList;
02892                 oprd_list->SetOprdPtr (cmppop->GetDestOprdPtr());
02893                 Chains->GetUDChains()->Set (new_predicate, oprd_list); 
02894                 // Add this use to DUChains of cmppop->GetDestOprdPtr()
02895                 if ((Chains->GetDUChains()->Lookup (cmppop->GetDestOprdPtr()) == NULL) || 
02896                     (Chains->GetDUChains()->NotFound() == TRUE)) {
02897                   oprd_list = new oprdList;
02898                   oprd_list->SetOprdPtr (new_predicate);
02899                   Chains->GetDUChains()->Set (cmppop->GetDestOprdPtr(), oprd_list);    
02900                 }
02901                 else {
02902                   for (uses = Chains->GetDUChains()->Lookup (cmppop->GetDestOprdPtr());
02903                        uses->GetNextListPtr() != NULL;
02904                        uses = uses->GetNextListPtr()) 
02905                     ; // find end of DUChain
02906                   uses->SetNextListPtr(new oprdList);
02907                   uses->GetNextListPtr()->SetOprdPtr(new_predicate); 
02908                 }
02909                 //cerr << "RegId = " << new_predicate->GetOprdRegNum() << "\n";
02910               }
02911             }
02912           }
02913           
02914           // Duplicate op attributes.
02915           attrdictionary = ((legoProc*) proc_ptr)->GetAttrDictionary();
02916           if (attrdictionary == NULL)
02917             {
02918               LegoFatal ("DoTheMessyStuff",
02919                          "Attribute dictionary is missing.");
02920             } 
02921           for (attrtail = attrdictionary; attrtail->GetNextAttrPtr() != NULL;
02922                attrtail = attrtail->GetNextAttrPtr()) /* do nothing */;
02923           eaid = FindMaxEdgeAttrId ((legoProc*) proc_ptr);
02924           for (atlscan = duplicate_op->GetOpAttrListPtr(); atlscan != NULL;
02925                atlscan = atlscan->GetNextListPtr()) {
02926             if (atlscan->GetAttrPtr() == NULL)
02927               continue;
02928             atscan = new attrs (*(atlscan->GetAttrPtr()), duplicate_op, ++eaid);
02929             atlscan->SetAttrPtr (atscan);
02930             atscan->SetAttrId (eaid);
02931             atlscan->SetAttrId (eaid);
02932             attrtail->SetNextAttrPtr (atscan);
02933             attrtail = attrtail->GetNextAttrPtr();
02934           } // end for
02935           AddMidOp( duplicate_op, second_cmerge );
02936           FixLiveVarsDown(above_op, second_edge, (legoProc*) proc_ptr);
02937           ddderr("duplicate (opId = " << duplicate_op->GetOpId() << ") added for opId = " << above_op->GetOpId() << "\n");
02938           
02939           // Add to priority list
02940           
02941           // adding new elements to priority list screws up pointers for 
02942           // original Nodes. Need to remember which op is currently pointed 
02943           // to so that ListPtr can be reset to this Dag Node when done.
02944 
02945           orig_op_id = op->GetOpId(); 
02946           
02947           
02948           ListPtr = List->begin();
02949           while ((*ListPtr).GetOp()->GetOpId() != above_op->GetOpId()) ListPtr++; 
02950           Element = BigListElement(*ListPtr); 
02951           Element.SetOp(duplicate_op);
02952           
02953           ListCount++;
02954           // need to initialize mdes_info and ru_info pointers
02955           L_build_oper_mdes_info (duplicate_op);
02956           L_create_ru_info_oper (duplicate_op);
02957           
02958           // Now fix the DPG. Remove edges between successors that 
02959           // are not dominated by the block the op is now in, fix 
02960           // the others. 
02961           for (Front = Element.Successors->begin(),
02962                Back = Element.Successors->end(); 
02963                Front != Back; ) {
02964             // first find the DagNode for the Successor op
02965             ListPtr3 = List->begin();
02966             while ((*ListPtr3).GetOp()->GetOpId() != 
02967                    (*Front).GetOp()->GetOpId()) 
02968               ListPtr3++; 
02969             // find the edgetype
02970             edgetype = (*Front).GetDependencyType();
02971             // increment now (Front may be removed later) 
02972             Front++;
02973             if (DescendantofBlock((int) duplicate_op->GetParentBlockPtr(),
02974                                   (*ListPtr3).GetOp())) {
02975               // Change successor's predecessor op to duplicate_op
02976               // find the DagNode for above_op
02977               ListPtr2 = List->begin();
02978               while ((*ListPtr2).GetOp()->GetOpId() != 
02979                      above_op->GetOpId()) 
02980                 ListPtr2++; 
02981               (*ListPtr3).RemovePredecessor(edgetype, 
02982                                            (*ListPtr2).GetOp());
02983               ddderr ("\nRemovePredecessor (opId = " << (*ListPtr2).GetOp()->GetOpId() << ") of opId = " << (*ListPtr3).GetOp()->GetOpId() << "\n");
02984               (*ListPtr2).RemoveSuccessor(edgetype, 
02985                                           (*ListPtr3).GetOp());
02986               ddderr ("\nRemoveSuccessor (opId = " << (*ListPtr3).GetOp()->GetOpId() << ") of opId = " << (*ListPtr2).GetOp()->GetOpId() << "\n");
02987               rc = (*ListPtr3).AddPredecessor(edgetype, 
02988                                         Element.GetOp(), 
02989                                         &Element);
02990               ddderr ("\nAddPredecessor (opId = " << Element.GetOp()->GetOpId() << ") of opId = " << (*ListPtr3).GetOp()->GetOpId() << ", now " << rc << " Predecessors\n");
02991             }
02992             else {
02993               // Remove this Successor from the new Element
02994               Front = Element.RemoveSuccessor(edgetype, 
02995                                       (*ListPtr3).GetOp());
02996               // Reset Back
02997               Back = Element.Successors->end();
02998               ddderr ("\nRemoveSuccessor (opId = " << (*ListPtr3).GetOp()->GetOpId() << ") of opId = " << Element.GetOp()->GetOpId() << "\n");
02999             }
03000           }
03001           // This op is now a Successor to all of its Predecessors        
03002           for (Front = Element.Predecessors->begin(),
03003                Back = Element.Predecessors->end(); 
03004                Front != Back; Front++ ) {
03005             // Find the DagNode for this Predecessor
03006             ListPtr2 = List->begin();
03007             while ((*ListPtr2).GetOp()->GetOpId() != 
03008                    (*Front).GetOp()->GetOpId()) 
03009               ListPtr2++; 
03010             rc = (*ListPtr2).AddSuccessor((*Front).GetDependencyType(), 
03011                                      Element.GetOp(), 
03012                                      &Element);   
03013             ddderr ("\nAddSuccessor (opId = " << Element.GetOp()->GetOpId() << ") of opId = " << (*ListPtr2).GetOp()->GetOpId() << ", now " << rc << " Successors\n");
03014           }
03015 
03016           ListIter = List->insert( ListPtr, Element );
03017           
03018           // Now reset ListPtr to the original Op Node and ListPtr Node
03019           ListPtr = List->begin();
03020           while ((*ListPtr).GetOp()->GetOpId() != orig_op_id) ListPtr++; 
03021           Op = ListPtr;
03022           ListPtr++;
03023           
03024           // Now fix the RDefs when duplicate ops are added. 
03025           // Redirecting Chains for new duplicate_op should 
03026           // also fix the Chains for original above_op. 
03027           for (def_first = above_op->GetDestOprdPtr(), 
03028                def_second = duplicate_op->GetDestOprdPtr(); 
03029                def_first != NULL; 
03030                def_first = def_first->GetNextOprdPtr(),
03031                def_second = def_second->GetNextOprdPtr()) {
03032             if ((def_first->GetOprdType() == OT_REG) || 
03033                 (def_first->GetOprdType() == OT_MACRO)) {       
03034               
03035               // Fix DUChains. Uses inside the Treegion and dominated by 
03036               // duplicate_op belong only to duplicate_op, those inside 
03037               // the Treegion and dominated by original_op belong only to 
03038               // original op. Others, (either outside of Treegion or source 
03039               // operands) belong to both.       
03040               uses_first = NULL;
03041               uses_second = NULL;
03042               uses = Chains->GetDUChains()->Lookup (def_first);
03043               
03044               while ((uses != NULL) && (Chains->GetDUChains()->NotFound() == FALSE)) {
03045                 use = uses->GetOprdPtr();
03046                 
03047                 // Determine if this use preceeds the def op in its own block 
03048                 UsePreceedsDefInBlock = FALSE; 
03049                 for (predecessor_op = above_op; 
03050                      predecessor_op != NULL; 
03051                      predecessor_op = predecessor_op->GetPrevLink()) {
03052                   if (predecessor_op == use->GetParentOpPtr()) {
03053                     UsePreceedsDefInBlock = TRUE; 
03054                     break; 
03055                   }
03056                 }
03057                 
03058                 if ((((legoRegion *) use->GetParentOpPtr()->GetParentBlockPtr())->GetParentPtr() == Region) && (DescendantofBlock( (int) above_op->GetParentBlockPtr(), use->GetParentOpPtr() ) && !UsePreceedsDefInBlock)) {
03059                   if ((DescendantofBlock( (int) duplicate_op->GetParentBlockPtr(), use->GetParentOpPtr() ))) {
03060                     if (uses_second == NULL) {
03061                       uses_second = new oprdList;
03062                       uses_second->SetOprdPtr(use);
03063                       prev_use_second = uses_second;
03064                     }
03065                     else {
03066                       new_use_second = new oprdList;
03067                       new_use_second->SetOprdPtr(use);
03068                       prev_use_second->SetNextListPtr(new_use_second);
03069                       prev_use_second = new_use_second;
03070                     }
03071                     // also need to patch the UDChain in this case
03072                     for (defs = Chains->GetUDChains()->Lookup (use);
03073                          defs->GetOprdPtr() != def_first;
03074                          defs = defs->GetNextListPtr())
03075                       ; // do nothing (find original def)
03076                     // now fix the original def to be new def of duplicate_op
03077                     defs->SetOprdPtr(def_second);
03078                   }
03079                   else {
03080                     if (uses_first == NULL) {
03081                       uses_first = new oprdList;
03082                       uses_first->SetOprdPtr(use);
03083                       prev_use_first = uses_first;
03084                     }
03085                     else {
03086                       new_use_first = new oprdList;
03087                       new_use_first->SetOprdPtr(use);
03088                       prev_use_first->SetNextListPtr(new_use_first);
03089                       prev_use_first = new_use_first;
03090                     }
03091                   }
03092                 }
03093                 else {
03094                   if (above_op == use->GetParentOpPtr()) {
03095                     // this is a special case of a def looping back to a use 
03096                     // in the same operation. Determine which src of 
03097                     // above_op/duplicate_op use belongs to
03098                     for (use_first = above_op->GetSrcOprdPtr(),
03099                          use_second = duplicate_op->GetSrcOprdPtr();
03100                          use_first != use; 
03101                          use_first = use_first->GetNextOprdPtr(),
03102                          use_second = use_second->GetNextOprdPtr())
03103                       ; // do nothing but increment used here
03104                     if (uses_second == NULL) {
03105                       uses_second = new oprdList;
03106                       uses_second->SetOprdPtr(use_first);
03107                       prev_use_second = uses_second;
03108                     }
03109                     else {
03110                       new_use_second = new oprdList;
03111                       new_use_second->SetOprdPtr(use_first);
03112                       prev_use_second->SetNextListPtr(new_use_second);
03113                       prev_use_second = new_use_second;
03114                     }
03115                     new_use_second = new oprdList;
03116                     new_use_second->SetOprdPtr(use_second);
03117                     prev_use_second->SetNextListPtr(new_use_second);
03118                     prev_use_second = new_use_second;
03119                     if (uses_first == NULL) {
03120                       uses_first = new oprdList;
03121                       uses_first->SetOprdPtr(use_first);
03122                       prev_use_first = uses_first;
03123                     }
03124                     else {
03125                       new_use_first = new oprdList;
03126                       new_use_first->SetOprdPtr(use_first);
03127                       prev_use_first->SetNextListPtr(new_use_first);
03128                       prev_use_first = new_use_first;
03129                     }
03130                     new_use_first = new oprdList;
03131                     new_use_first->SetOprdPtr(use_second);
03132                     prev_use_first->SetNextListPtr(new_use_first);
03133                     prev_use_first = new_use_first;
03134                     
03135                     // need to add a new UDChain for the new duplicate_op use
03136                     // and add to the UDChain of the original above_op
03137                     defs_second = new oprdList;
03138                     defs_second->SetOprdPtr(def_first);
03139                     defs_second->SetNextListPtr(new oprdList);
03140                     defs_second->GetNextListPtr()->SetOprdPtr(def_second);
03141                     Chains->GetUDChains()->Set (use_second, defs_second);
03142                     for (defs_first = Chains->GetUDChains()->Lookup (use_first);
03143                          defs_first->GetNextListPtr() != NULL;
03144                          defs_first = defs_first->GetNextListPtr()) 
03145                       ; // find end of UDChain
03146                     defs_first->SetNextListPtr(new oprdList);
03147                     defs_first->GetNextListPtr()->SetOprdPtr(def_second); 
03148                   }
03149                   else { // this use is outside of treegion and should belong to both
03150                     if (uses_second == NULL) {
03151                       uses_second = new oprdList;
03152                       uses_second->SetOprdPtr(use);
03153                       prev_use_second = uses_second;
03154                     }
03155                     else {
03156                       new_use_second = new oprdList;
03157                       new_use_second->SetOprdPtr(use);
03158                       prev_use_second->SetNextListPtr(new_use_second);
03159                       prev_use_second = new_use_second;
03160                     }
03161                     if (uses_first == NULL) {
03162                       uses_first = new oprdList;
03163                       uses_first->SetOprdPtr(use);
03164                       prev_use_first = uses_first;
03165                     }
03166                     else {
03167                       new_use_first = new oprdList;
03168                       new_use_first->SetOprdPtr(use);
03169                       prev_use_first->SetNextListPtr(new_use_first);
03170                       prev_use_first = new_use_first;
03171                     } 
03172                     // need to add to the UDChain for this use
03173                     for (defs = Chains->GetUDChains()->Lookup (use);
03174                          defs->GetNextListPtr() != NULL;
03175                          defs = defs->GetNextListPtr()) 
03176                       ; // find end of UDChain
03177                     defs->SetNextListPtr(new oprdList);
03178                     defs->GetNextListPtr()->SetOprdPtr(def_second); 
03179                   }
03180                 }
03181                 uses = uses->GetNextListPtr();
03182               }
03183               uses = Chains->GetDUChains()->Lookup (def_first);
03184               if (Chains->GetDUChains()->NotFound() == FALSE) {
03185                 delete uses;    
03186                 Chains->GetDUChains()->Set (def_first, uses_first);
03187                 Chains->GetDUChains()->Set (def_second, uses_second);
03188               }
03189             }
03190           }
03191           for (use_first = above_op->GetSrcOprdPtr(), 
03192                use_second = duplicate_op->GetSrcOprdPtr(); 
03193                use_first != NULL; 
03194                use_first = use_first->GetNextOprdPtr(),
03195                use_second = use_second->GetNextOprdPtr()) {
03196             if ((use_first->GetOprdType() == OT_REG) || 
03197                 (use_first->GetOprdType() == OT_MACRO)) {       
03198               
03199               // Fix Chains.      
03200               defs_second = NULL;
03201               defs = Chains->GetUDChains()->Lookup (use_first);
03202               if (Chains->GetUDChains()->NotFound() == FALSE) {
03203                 while (defs != NULL) {
03204                   def = defs->GetOprdPtr();
03205                   // Build oprdList for UDChain
03206                   if (defs_second == NULL) {
03207                     defs_second = new oprdList;
03208                     defs_second->SetOprdPtr(def);
03209                     prev_def_second = defs_second;
03210                   }
03211                   else {
03212                     new_def_second = new oprdList;
03213                     new_def_second->SetOprdPtr(def);
03214                     prev_def_second->SetNextListPtr(new_def_second);
03215                     prev_def_second = new_def_second;
03216                   }
03217                   // need to add to the DUChain for this def
03218                   for (uses = Chains->GetDUChains()->Lookup (def);
03219                        uses->GetNextListPtr() != NULL;
03220                        uses = uses->GetNextListPtr()) 
03221                     ; // find end of DUChain
03222                   uses->SetNextListPtr(new oprdList);
03223                   uses->GetNextListPtr()->SetOprdPtr(use_second); 
03224                   
03225                   defs = defs->GetNextListPtr();
03226                 }
03227                 Chains->GetUDChains()->Set (use_second, defs_second);
03228               }
03229             }
03230           }
03231           
03232           // Now that I am demoting predicates, I only want to make these 
03233           // updates for CMPP ops (whose predicates are not demoted).  
03234           if ((duplicate_op->GetOpcode() >= CMPP) &&
03235               (duplicate_op->GetOpcode() <= FCMPP_D_TRUE_AC_AC)) {
03236             use_first = above_op->GetPredOprdPtr();
03237             use_second = duplicate_op->GetPredOprdPtr();
03238             if (use_first != NULL) {
03239               if ((use_first->GetOprdType() == OT_REG) || 
03240                   (use_first->GetOprdType() == OT_MACRO)) {     
03241                 
03242                 // Fix Chains.      
03243                 defs_second = NULL;
03244                 defs = Chains->GetUDChains()->Lookup (use_first);
03245                 if (Chains->GetUDChains()->NotFound() == FALSE) {
03246                   while (defs != NULL) {
03247                     def = defs->GetOprdPtr();
03248                     // Build oprdList for UDChain
03249                     if (defs_second == NULL) {
03250                       defs_second = new oprdList;
03251                       defs_second->SetOprdPtr(def);
03252                       prev_def_second = defs_second;
03253                     }
03254                     else {
03255                       new_def_second = new oprdList;
03256                       new_def_second->SetOprdPtr(def);
03257                       prev_def_second->SetNextListPtr(new_def_second);
03258                       prev_def_second = new_def_second;
03259                     }
03260                     // need to add to the DUChain for this def
03261                     for (uses = Chains->GetDUChains()->Lookup (def);
03262                          uses->GetNextListPtr() != NULL;
03263                          uses = uses->GetNextListPtr()) 
03264                       ; // find end of DUChain
03265                     uses->SetNextListPtr(new oprdList);
03266                     uses->GetNextListPtr()->SetOprdPtr(use_second); 
03267                     
03268                     defs = defs->GetNextListPtr();
03269                   }
03270                   Chains->GetUDChains()->Set (use_second, defs_second);
03271                 }
03272               }  
03273             }
03274           }
03275         }
03276         else {
03277           if (!(above_op->IsDummy())) {
03278             one_dead = TRUE; 
03279             unspeculated_ops++;
03280             downward_dynamic_op_reduction += ((legoRegion *) second_cmerge->GetParentBlockPtr())->GetWeight(); 
03281             if ((above_op->GetOpcode() == PBRR) || 
03282                 (above_op->GetOpcode() == PBRA)) {
03283               unspeculated_pbr_ops++;
03284             }
03285           }
03286         }
03287         if ((anyliveout(above_op, first_edge) ||
03288              IsStoreOp(above_op) ||  
03289              (above_op->GetOpcode() == BRL)) && 
03290             above_op->GetOpcode() != DEFINE) {
03291 
03292           // May need to demote predicate if guarded by a predicate register
03293           if ((above_op->GetOpcode() < CMPP) ||
03294               (above_op->GetOpcode() > FCMPP_D_TRUE_AC_AC)) {
03295             PredOprd = above_op->GetPredOprdPtr();
03296             if (PredOprd != NULL) {
03297               if (PredOprd->GetOprdType() == OT_REG) {
03298                 // Needs demotion
03299                 //cerr << "\nabove_op's (OpId = " << above_op->GetOpId() << ") predicate (orig RegId = " << PredOprd->GetOprdRegNum() << ") demoted to ";
03300 
03301                 // Clean-up RDefs before deleting oprd
03302                 for (defs = Chains->GetUDChains()->Lookup (PredOprd);
03303                      (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
03304                      defs = defs->GetNextListPtr()) {
03305                   def = defs->GetOprdPtr();
03306                   new_uses = NULL; 
03307                   for (uses = Chains->GetDUChains()->Lookup (def);
03308                        (uses != NULL) && (Chains->GetDUChains()->NotFound() == FALSE);
03309                        uses = uses->GetNextListPtr()) {
03310                     use = uses->GetOprdPtr();
03311                     if (use != PredOprd) {
03312                       if (new_uses == NULL) {
03313                         new_uses = new oprdList;
03314                         new_uses->SetOprdPtr(use);
03315                         prev_use = new_uses;
03316                       }
03317                       else {
03318                         new_use = new oprdList;
03319                         new_use->SetOprdPtr(use);
03320                         prev_use->SetNextListPtr(new_use);
03321                         prev_use = new_use;
03322                       } 
03323                     }
03324                   }
03325                   if (Chains->GetDUChains()->NotFound() == FALSE) {
03326                     uses = Chains->GetDUChains()->Lookup (def);
03327                     delete uses; 
03328                     Chains->GetDUChains()->Set (def, new_uses);
03329                   }
03330                 }
03331                 Chains->GetUDChains()->Lookup (PredOprd);
03332                 if (Chains->GetUDChains()->NotFound() == FALSE) {
03333                   Chains->GetUDChains()->Delete (PredOprd);
03334                 }
03335                 delete PredOprd; 
03336                 
03337                 // Find the CMPP op for branch 
03338                 cmppoprd = op->GetSrcOprdPtr()->GetNextOprdPtr(); 
03339                 cmppop = NULL;
03340                 for (defs = Chains->GetUDChains()->Lookup (cmppoprd);
03341                      (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
03342                      defs = defs->GetNextListPtr()) {
03343                   def = defs->GetOprdPtr();
03344                   cmppop = def->GetParentOpPtr(); // only one CMPP op should reach
03345                   break; 
03346                 }
03347                 
03348                 dderr ("cmppop OpId is: " << cmppop->GetOpId() << "\n");
03349                 
03350                 if (cmppop == NULL) {
03351                   LegoFatal ("DoTheMessyStuff", "Can't find CMPP for branch");
03352                 } 
03353                 
03354                 // Find the PBR op for branch 
03355                 btroprd = op->GetSrcOprdPtr(); // should be 1st source
03356                 pbrrop = NULL;
03357                 for (defs = Chains->GetUDChains()->Lookup (btroprd);
03358                      (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
03359                      defs = defs->GetNextListPtr()) {
03360                   def = defs->GetOprdPtr();
03361                   pbrrop = def->GetParentOpPtr(); // only one PBRR op should reach
03362                   break; 
03363                 }
03364                 
03365                 dderr ("pbrrop OpId is: " << pbrrop->GetOpId() << "\n");
03366                 
03367                 if (pbrrop == NULL) {
03368                   LegoFatal ("DoTheMessyStuff", "Can't find PBRR/PBRA in block");
03369                 } // end if
03370                 
03371                 if (op->GetOpcode() == BRCT) {
03372                   if (pbrrop->GetSrcOprdPtr()->GetLiteralControlBlock() == 
03373                       ((legoRegion *) first_cmerge->GetParentBlockPtr())->GetRegionId()) {
03374                     new_predicate = new legoOprd(*cmppop->GetDestOprdPtr());
03375                   }
03376                   else {
03377                     new_predicate = new legoOprd(*cmppop->GetDestOprdPtr()
03378                                                  ->GetNextOprdPtr());
03379                   }
03380                 }
03381                 else {
03382                   if (pbrrop->GetSrcOprdPtr()->GetLiteralControlBlock() == 
03383                       ((legoRegion *) first_cmerge->GetParentBlockPtr())->GetRegionId()) {
03384                     new_predicate = new legoOprd(*cmppop->GetDestOprdPtr()
03385                                                  ->GetNextOprdPtr());
03386                   }
03387                   else {
03388                     new_predicate = new legoOprd(*cmppop->GetDestOprdPtr());
03389                   }
03390                 }
03391                 // Assign demoted predicate
03392                 new_predicate->SetNextOprdPtr(NULL);
03393                 above_op->SetPredOprdPtr(new_predicate);
03394                 // Now adjust Chains 
03395                 oprd_list = new oprdList;
03396                 oprd_list->SetOprdPtr (cmppop->GetDestOprdPtr());
03397                 Chains->GetUDChains()->Set (new_predicate, oprd_list); 
03398                 // Add this use to DUChains of cmppop->GetDestOprdPtr()
03399                 if ((Chains->GetDUChains()->Lookup (cmppop->GetDestOprdPtr()) == NULL) || 
03400                     (Chains->GetDUChains()->NotFound() == TRUE)) {
03401                   oprd_list = new oprdList;
03402                   oprd_list->SetOprdPtr (new_predicate);
03403                   Chains->GetDUChains()->Set (cmppop->GetDestOprdPtr(), oprd_list);    
03404                 }
03405                 else {
03406                   for (uses = Chains->GetDUChains()->Lookup (cmppop->GetDestOprdPtr());
03407                        uses->GetNextListPtr() != NULL;
03408                        uses = uses->GetNextListPtr()) 
03409                     ; // find end of DUChain
03410                   uses->SetNextListPtr(new oprdList);
03411                   uses->GetNextListPtr()->SetOprdPtr(new_predicate); 
03412                 }
03413                 //cerr << "RegId = " << new_predicate->GetOprdRegNum() << "\n";
03414               }
03415             }
03416           }
03417           
03418           RemoveMidOp( above_op, NO );
03419           AddMidOp( above_op, first_cmerge );
03420           FixLiveVarsDown(above_op, first_edge, (legoProc*) proc_ptr);
03421           ddderr("opId = " << above_op->GetOpId() << " moved below branch\n");
03422           // now fix the DPG. Remove edges between successors that 
03423           // are not dominated by the block above_op is now in. 
03424           // Find the DagNode for above_op
03425           ListPtr2 = List->begin();
03426           while ((*ListPtr2).GetOp()->GetOpId() != 
03427                  above_op->GetOpId()) 
03428             ListPtr2++; 
03429           for (Front = (*ListPtr2).Successors->begin(),
03430                Back = (*ListPtr2).Successors->end(); 
03431                Front != Back; ) {
03432             // first find the DagNode for the Successor op
03433             ListPtr3 = List->begin();
03434             while ((*ListPtr3).GetOp()->GetOpId() != 
03435                    (*Front).GetOp()->GetOpId()) 
03436               ListPtr3++; 
03437             // find the edgetype
03438             edgetype = (*Front).GetDependencyType();
03439             // increment now (Front may be removed later) 
03440             Front++;
03441             if (!DescendantofBlock((int) above_op->GetParentBlockPtr(),
03442                                    (*ListPtr3).GetOp())) {
03443               // Remove this Predecessor/Successor pair
03444               Front = (*ListPtr2).RemoveSuccessor(edgetype, 
03445                                            (*ListPtr3).GetOp());
03446               // Reset Back
03447               Back = (*ListPtr2).Successors->end();
03448               ddderr ("\nRemoveSuccessor (opId = " << (*ListPtr3).GetOp()->GetOpId() << ") of opId = " << (*ListPtr2).GetOp()->GetOpId() << "\n");
03449               // the Successor's Predecessor is still above_op
03450               (*ListPtr3).RemovePredecessor(edgetype, 
03451                                            (*ListPtr2).GetOp());
03452               ddderr ("\nRemovePredecessor (opId = " << (*ListPtr2).GetOp()->GetOpId() << ") of opId = " << (*ListPtr3).GetOp()->GetOpId() << "\n");
03453             }
03454           }
03455         }
03456         else {
03457           
03458           if (!(above_op->IsDummy())) {
03459             if (one_dead == TRUE) dead_ops++;
03460             unspeculated_ops++;
03461             downward_dynamic_op_reduction += ((legoRegion *) first_cmerge->GetParentBlockPtr())->GetWeight(); 
03462             if ((above_op->GetOpcode() == PBRR) || 
03463                 (above_op->GetOpcode() == PBRA)) {
03464               unspeculated_pbr_ops++;
03465             }
03466           }
03467           
03468           if (above_op->GetOpcode() != DEFINE) {
03469             // this op is dead along this path and therefore does not need to 
03470             // be scheduled. I will use dp_remove attr to delay removal so that 
03471             // RDefs remain valid
03472             AddDPRemoveAttribute ( above_op );
03473             // Set a non-negative_one s_time for above_op (op will be 
03474             // removed anyway)
03475             above_op->SetSchedTime( 0 );
03476             RemoveMidOp( above_op, NO );
03477             if (current_before_op->GetNextLink() == NULL) {
03478               AddMidOp( above_op, current_before_op->GetPrevLink() );
03479             }
03480             else  {
03481               AddMidOp( above_op, current_before_op );
03482             }
03483             if (next_above_op != current_before_op) {
03484               current_before_op = above_op; 
03485             }
03486             else {
03487               current_before_op = above_op; 
03488               next_above_op = current_before_op; 
03489             }
03490             // now fix the DPG. Remove edges between successors and predecessors
03491             ListPtr2 = List->begin();
03492             while ((*ListPtr2).GetOp()->GetOpId() != 
03493                    above_op->GetOpId()) 
03494               ListPtr2++; 
03495             for (Front = (*ListPtr2).Successors->begin(),
03496                  Back = (*ListPtr2).Successors->end(); 
03497                  Front != Back; ) {
03498               // Remove this Predecessor/Successor pair
03499               // first find the DagNode for the Successor op
03500               ListPtr3 = List->begin();
03501               while ((*ListPtr3).GetOp()->GetOpId() != 
03502                      (*Front).GetOp()->GetOpId()) 
03503                 ListPtr3++; 
03504               // find the edgetype
03505               edgetype = (*Front).GetDependencyType();
03506               // increment now (Front may be removed later) 
03507               //Front++;
03508               Front = (*ListPtr2).RemoveSuccessor(edgetype, 
03509                                                   (*ListPtr3).GetOp());
03510               // Reset Back
03511               Back = (*ListPtr2).Successors->end();
03512               ddderr ("\nRemoveSuccessor (opId = " << (*ListPtr3).GetOp()->GetOpId() << ") of opId = " << (*ListPtr2).GetOp()->GetOpId() << "\n");
03513               // the Successor's Predecessor is still above_op
03514               (*ListPtr3).RemovePredecessor(edgetype, 
03515                                             (*ListPtr2).GetOp());
03516               ddderr ("\nRemovePredecessor (opId = " << (*ListPtr2).GetOp()->GetOpId() << ") of opId = " << (*ListPtr3).GetOp()->GetOpId() << "\n");
03517             }
03518             for (Front = (*ListPtr2).Predecessors->begin(),
03519                  Back = (*ListPtr2).Predecessors->end(); 
03520                  Front != Back; ) {
03521               // Remove this Successor/Predecessor pair
03522               // first find the DagNode for the Predecessor op
03523               ListPtr3 = List->begin();
03524               while ((*ListPtr3).GetOp()->GetOpId() != 
03525                      (*Front).GetOp()->GetOpId()) 
03526                 ListPtr3++; 
03527               // find the edgetype
03528               edgetype = (*Front).GetDependencyType();
03529               // increment now (Front may be removed later) 
03530               //Front++;
03531               Front = (*ListPtr2).RemovePredecessor(edgetype, 
03532                                                     (*ListPtr3).GetOp());
03533               // Reset Back
03534               Back = (*ListPtr2).Predecessors->end();
03535               ddderr ("\nRemovePredecessor (opId = " << (*ListPtr3).GetOp()->GetOpId() << ") of opId = " << (*ListPtr2).GetOp()->GetOpId() << "\n");
03536               // the Predecessor's Successor is still above_op
03537               (*ListPtr3).RemoveSuccessor(edgetype, 
03538                                           (*ListPtr2).GetOp());
03539               ddderr ("\nRemoveSuccessor (opId = " << (*ListPtr2).GetOp()->GetOpId() << ") of opId = " << (*ListPtr3).GetOp()->GetOpId() << "\n");
03540             }
03541             ListCount--;
03542             //LegoNonFatal ("DoTheMessyStuff", "Dead Code Found ??\n");
03543           }
03544         }
03545       }
03546     }
03547   }
03548   return (NO_RENAMING_CONFLICT);
03549 }
03550 
03551 // This routine returns the second, complementary destination for a CMPP op.
03552 // If the second predicate dest is OT_UNDEFINED, one will be created. 
03553 // if the CMPP opcode does not produce a complementary second dest, the 
03554 // opcode will be updated. The second destination oprd is returned.
03555 legoOprd *list_scheduler::GetComplementaryDestOprd( legoOp *cmppop ) {
03556 
03557   legoOprd *p1, *p2; 
03558 
03559   if ((cmppop->GetOpcode() < CMPP) ||
03560       (cmppop->GetOpcode() > FCMPP_D_TRUE_AC_AC)) {
03561     LegoNonFatal ("GetComplementaryDestOprd", "Op passed not a CMPP op\n");
03562     return NULL;
03563   } // end if
03564 
03565   // make sure that the second D-action is a complement (odd-number opcode)
03566   div_t remainder = div(cmppop->GetOpcode(), 2);
03567   if (remainder.rem == 0) {
03568     cmppop->SetOpcode((cmppop->GetOpcode() + 1));
03569   }
03570   
03571   p1 = cmppop->GetDestOprdPtr();  // first destination!
03572   if (p1 == NULL || p1->GetNextOprdPtr() == NULL)
03573     {
03574       LegoNonFatal ("GetComplementaryDestOprd", "CMPP %d has bad destinations.",
03575                     cmppop->GetOpId());
03576       return NULL;
03577     } // end if
03578   p2 = p1->GetNextOprdPtr();  // p2 is there always!
03579   if (p1->GetNextOprdPtr()->GetOprdType() != OT_UNDEFINED)
03580     /* do nothing - we have two predicates! */;
03581   else {   // Make a second destination. 
03582     // Make the new operand and plop it into the CMPP.
03583     p2->SetOprdType (p1->GetOprdType());
03584     p2->SetOprdRegNum (++MaxRegNum);
03585     p2->SetOprdRegType (p1->GetOprdRegType());
03586     p2->SetOprdDataType (p1->GetOprdDataType());
03587     p2->SetOprdFileType (p1->GetOprdFileType());
03588     p2->SetOprdOmega (p1->GetOprdOmega());
03589     p2->SetOprdRegStyle (p1->GetOprdRegStyle());
03590     p2->SetIntValue (p1->GetOprdIntValue());
03591   } // end else
03592 
03593   return p2;
03594 }
03595 
03596 
03597 // This routine cleans up ops and adds a dp_remove attr so that they 
03598 // can be remove after procedure is scheduled. Removing them earlier fucks 
03599 // up priority lists and RDefs() 
03600 void list_scheduler::PrepareToDie( legoOp *op ) {
03601 
03602   vector < BigListElement >::iterator ListPtr2, ListPtr3;
03603   vector < SmallListElement >::iterator Front, Back;
03604   enum edgeTypes edgetype;  
03605   
03606   if ((op != current_before_op) &&
03607       (op->GetNextLink() != current_before_op)) {
03608     
03609     if ((op->GetPrevLink() == NULL) && (op->GetNextLink() == NULL)) {
03610       RemoveVeryLastOp( op, NO ); 
03611     }
03612     else if ((op->GetPrevLink() != NULL) && (op->GetNextLink() != NULL)) {
03613       RemoveMidOp( op, NO ); 
03614     }
03615     else if ((op->GetPrevLink() != NULL) && (op->GetNextLink() == NULL)) {
03616       RemoveFinalOp( op, NO ); 
03617     }
03618     else if ((op->GetPrevLink() == NULL) && (op->GetNextLink() != NULL)) {
03619       RemoveFirstOp( op, NO ); 
03620     }
03621     else {
03622       LegoFatal ("PrepareToDie", "OK, now I'm stumped.");    
03623     }
03624     
03625     // Let's not actually delete it yet, it fucks up the priority list. Just 
03626     // schedule it in the previous multi-way branch block and dp_remove it 
03627     // later. Set the s_time so that it appears scheduled and adjust ListCount
03628     AddMidOp( op, current_before_op->GetPrevLink() );
03629   }
03630   
03631   AddDPRemoveAttribute ( op );
03632   if (op->GetSchedTime() == UNSCHEDULED ) {
03633     op->SetSchedTime( 0 );
03634   }
03635   // now fix the DPG. Remove edges between successors and predecessors
03636   ListPtr2 = List->begin();
03637   while ((*ListPtr2).GetOp()->GetOpId() != 
03638          op->GetOpId()) 
03639     ListPtr2++; 
03640   for (Front = (*ListPtr2).Successors->begin(),
03641        Back = (*ListPtr2).Successors->end(); 
03642        Front != Back; ) {
03643     // Remove this Predecessor/Successor pair
03644     // first find the DagNode for the Successor op
03645     ListPtr3 = List->begin();
03646     while ((*ListPtr3).GetOp()->GetOpId() != 
03647            (*Front).GetOp()->GetOpId()) 
03648       ListPtr3++; 
03649     // find the edgetype
03650     edgetype = (*Front).GetDependencyType();
03651     // increment now (Front may be removed later) 
03652     //Front++;
03653     Front = (*ListPtr2).RemoveSuccessor(edgetype, 
03654                                         (*ListPtr3).GetOp());
03655     // Reset Back
03656     Back = (*ListPtr2).Successors->end();
03657     ddderr ("\nRemoveSuccessor (opId = " << (*ListPtr3).GetOp()->GetOpId() << ") of opId = " << (*ListPtr2).GetOp()->GetOpId() << "\n");
03658     // the Successor's Predecessor is still above_op
03659     (*ListPtr3).RemovePredecessor(edgetype, 
03660                                   (*ListPtr2).GetOp());
03661     ddderr ("\nRemovePredecessor (opId = " << (*ListPtr2).GetOp()->GetOpId() << ") of opId = " << (*ListPtr3).GetOp()->GetOpId() << "\n");
03662   }
03663   for (Front = (*ListPtr2).Predecessors->begin(),
03664        Back = (*ListPtr2).Predecessors->end(); 
03665        Front != Back; ) {
03666     // Remove this Successor/Predecessor pair
03667     // first find the DagNode for the Predecessor op
03668     ListPtr3 = List->begin();
03669     while ((*ListPtr3).GetOp()->GetOpId() != 
03670            (*Front).GetOp()->GetOpId()) 
03671       ListPtr3++; 
03672     // find the edgetype
03673     edgetype = (*Front).GetDependencyType();
03674     // increment now (Front may be removed later) 
03675     //Front++;
03676     Front = (*ListPtr2).RemovePredecessor(edgetype, 
03677                                           (*ListPtr3).GetOp());
03678     // Reset Back
03679     Back = (*ListPtr2).Predecessors->end();
03680     ddderr ("\nRemovePredecessor (opId = " << (*ListPtr3).GetOp()->GetOpId() << ") of opId = " << (*ListPtr2).GetOp()->GetOpId() << "\n");
03681     // the Predecessor's Successor is still above_op
03682     (*ListPtr3).RemoveSuccessor(edgetype, 
03683                                 (*ListPtr2).GetOp());
03684     ddderr ("\nRemoveSuccessor (opId = " << (*ListPtr2).GetOp()->GetOpId() << ") of opId = " << (*ListPtr3).GetOp()->GetOpId() << "\n");
03685   }
03686 }
03687 
03688 
03689 // As a result of control flow changes during the forming of Multi-Way 
03690 // branches, some ops get re-targeted. Need to update the dag to reflect 
03691 // new predecessor ops for control deps in these cases. 
03692 void list_scheduler::UpdatePredecessorBranch( legoOp *op, legoOp *old_predecessor_op, legoOp *new_predecessor_op ) {
03693 
03694   vector < BigListElement >::iterator ListPtrOp, ListPtrOld, ListPtrNew, ListPtrCMERGE;
03695   int rc;
03696   legoOp *cmerge_op;
03697 
03698   // Let's also make sure that op's C_MERGE gets the right InList here as 
03699   // this also changes
03700   for (cmerge_op = op;
03701        cmerge_op->GetPrevLink() != NULL; 
03702        cmerge_op = cmerge_op->GetPrevLink())
03703     ; // Do nothing, just find C_MERGE
03704   cmerge_op->GetInListPtr()->SetOpPtr(new_predecessor_op);
03705   
03706   // Find the op DagNode
03707   ListPtrOp = List->begin();
03708   while ((*ListPtrOp).GetOp()->GetOpId() != 
03709          op->GetOpId()) 
03710     ListPtrOp++; 
03711 
03712   // Find the cmerge_op DagNode
03713   ListPtrCMERGE = List->begin();
03714   while ((*ListPtrCMERGE).GetOp()->GetOpId() != 
03715          cmerge_op->GetOpId()) 
03716     ListPtrCMERGE++; 
03717 
03718   // Find the old_predecessor_op DagNode
03719   ListPtrOld = List->begin();
03720   while ((*ListPtrOld).GetOp()->GetOpId() != 
03721          old_predecessor_op->GetOpId()) 
03722     ListPtrOld++; 
03723 
03724   // Find the new_predecessor_op DagNode
03725   ListPtrNew = List->begin();
03726   while ((*ListPtrNew).GetOp()->GetOpId() != 
03727          new_predecessor_op->GetOpId()) 
03728     ListPtrNew++; 
03729 
03730   // Remove the old Predecessor/Successor pair
03731   (*ListPtrOp).RemovePredecessor(ET_CNTL, 
03732                                  (*ListPtrOld).GetOp());
03733   ddderr ("\nRemovePredecessor (opId = " << (*ListPtrOld).GetOp()->GetOpId() << ") of opId = " << (*ListPtrOp).GetOp()->GetOpId() << "\n");
03734   (*ListPtrOld).RemoveSuccessor(ET_CNTL, 
03735                                 (*ListPtrOp).GetOp());
03736   ddderr ("\nRemoveSuccessor (opId = " << (*ListPtrOp).GetOp()->GetOpId() << ") of opId = " << (*ListPtrOld).GetOp()->GetOpId() << "\n");
03737   
03738   // Add the new Predecessor/Successor pair 
03739   rc = (*ListPtrNew).AddSuccessor(ET_CNTL, 
03740                                (*ListPtrOp).GetOp(), 
03741                                &(*ListPtrOp));   
03742   ddderr ("\nAddSuccessor (opId = " << (*ListPtrOp).GetOp()->GetOpId() << ") of opId = " << (*ListPtrNew).GetOp()->GetOpId() << ", now " << rc << " Successors\n");
03743   rc = (*ListPtrOp).AddPredecessor(ET_CNTL, 
03744                                  (*ListPtrNew).GetOp(), 
03745                                  &(*ListPtrNew));
03746   ddderr ("\nAddPredecessor (opId = " << (*ListPtrNew).GetOp()->GetOpId() << ") of opId = " << (*ListPtrOp).GetOp()->GetOpId() << ", now " << rc << " Predecessors\n");
03747   
03748   // Do the same for C_MERGE op
03749   // Remove the old Predecessor/Successor pair
03750   (*ListPtrCMERGE).RemovePredecessor(ET_CNTL, 
03751                                  (*ListPtrOld).GetOp());
03752   ddderr ("\nRemovePredecessor (opId = " << (*ListPtrOld).GetOp()->GetOpId() << ") of opId = " << (*ListPtrCMERGE).GetOp()->GetOpId() << "\n");
03753   (*ListPtrOld).RemoveSuccessor(ET_CNTL, 
03754                                 (*ListPtrCMERGE).GetOp());
03755   ddderr ("\nRemoveSuccessor (opId = " << (*ListPtrCMERGE).GetOp()->GetOpId() << ") of opId = " << (*ListPtrOld).GetOp()->GetOpId() << "\n");
03756   
03757   // Add the new Predecessor/Successor pair 
03758   rc = (*ListPtrNew).AddSuccessor(ET_CNTL, 
03759                                (*ListPtrCMERGE).GetOp(), 
03760                                &(*ListPtrCMERGE));   
03761   ddderr ("\nAddSuccessor (opId = " << (*ListPtrCMERGE).GetOp()->GetOpId() << ") of opId = " << (*ListPtrNew).GetOp()->GetOpId() << ", now " << rc << " Successors\n");
03762   rc = (*ListPtrCMERGE).AddPredecessor(ET_CNTL, 
03763                                  (*ListPtrNew).GetOp(), 
03764                                  &(*ListPtrNew));
03765   ddderr ("\nAddPredecessor (opId = " << (*ListPtrNew).GetOp()->GetOpId() << ") of opId = " << (*ListPtrCMERGE).GetOp()->GetOpId() << ", now " << rc << " Predecessors\n");
03766   
03767 }
03768 
03769 
03770 
03771 // Allowing Multi-Way branches to be formed during list scheduling requires
03772 // even MoreMessyStuff. 
03773 // Here I DoMoreMessyStuff. 
03774 int list_scheduler::DoMoreMessyStuff( legoOp *op, int Final_Pass )
03775 {
03776 
03777   legoRegion *original_block, *current_block, *parent_block, *region;
03778   regionList *allchildren, *lrrscan;
03779   legoProc *parentproc; 
03780   legoOp *c_merge_op, *listop, *predecessor_branch_op=NULL; 
03781   legoOp *pbrrop, *pbrrop2, *cmppop, *cmppop2, *branch_that_needs_new_predecessor; 
03782   legoOp *last_op_in_multiop; 
03783   legoOprd *btroprd, *btroprd2, *def, *use, *oprd, *oprd2, *cmppoprd, *cmppoprd2;
03784   legoOprd *second_pred, *new_pred, *second_pred2, *new_pred2, *delete_oprd;
03785   opList *oplist, *oplisttoremove; 
03786   oprdList *defs, *uses, *oprd_list, *new_uses, *new_use, *prev_use; 
03787   attrList *atl;
03788   attrs *a;
03789   enum attrTypes atype;
03790   int i, TakenBlockId, TakenTakenBlockId; 
03791   int CurrentSTime, CurrentSlot, latency_count; 
03792   opEdges *edge;
03793   vector < BigListElement >::iterator TempListIter, ListPtr2, ListPtr3;
03794   vector < SmallListElement >::iterator Front, Back;
03795   regionList *temprl, *rlist; 
03796   enum edgeTypes edgetype;  
03797   
03798   bool pbrr_used; //HZ: used for the pbrr patch. This pbrr is used elsewhere?
03799   oprdList *use_temp; 
03800   legoOp *temp_br_op;
03801 
03802   //HZ: added to insert the mdes attribute so that we could use Emre's WeldSim
03803   legoOprd *attrmdes;
03804 
03805   ddderr ("\nDoMoreMessyStuff for opId = " << op->GetOpId() << "\n");
03806   
03807   if (!AllowMultiWayBR || !Final_Pass) return (RENAMING_CONFLICT);
03808   
03809   // First determine the block that the op is originally in. Will probably 
03810   // Need to remove this block later. 
03811   original_block = (legoRegion *) op->GetParentBlockPtr(); 
03812   c_merge_op = (legoOp *) original_block->GetItem(0);
03813   // Find parent proc.
03814   parentproc = (legoProc *) FindParentRegionType (RT_PROC, original_block);
03815   // Also want to know which branch this branch is control dependent on 
03816   // (should only be control dependent on one branch (Non-BRL)
03817   TempListIter = List->begin();
03818   while ((*TempListIter).GetOp()->GetOpId() != op->GetOpId()) 
03819     TempListIter++;
03820   for (Front = (*TempListIter).Predecessors->begin(),
03821        Back = (*TempListIter).Predecessors->end(); Front != Back; Front++ ) {
03822     if ((*Front).GetDependencyType() == ET_CNTL) {
03823       predecessor_branch_op = (*Front).GetOp();
03824       ddderr ("predecessor branch OpId = " << predecessor_branch_op->GetOpId() << "\n");
03825       break; 
03826     }
03827   }
03828 
03829   if (predecessor_branch_op == NULL) {
03830     LegoFatal ("DoMoreMessyStuff", "Could not find predecessor branch.");
03831   }
03832   
03833   // Find the last op in predecessor_branch_op's multiop. We will move other 
03834   // branches to the position just before this branch. 
03835   for (last_op_in_multiop = predecessor_branch_op; 
03836        (last_op_in_multiop->GetNextLink() != NULL); 
03837        last_op_in_multiop = last_op_in_multiop->GetNextLink()) {
03838     if ((last_op_in_multiop->GetNextLink()->GetSchedTime() != 
03839          predecessor_branch_op->GetSchedTime()) && 
03840         // PrepareToDie() may temporarily scatter ops with s_time = 0
03841         (FindLcAttribute( "dp_remove", last_op_in_multiop->GetNextLink() ) 
03842          == NULL)) {
03843       ddderr ("last_op_in_multiop: predecessor branch OpId = " << predecessor_branch_op->GetOpId() << "\n");
03844       ddderr ("last_op_in_multiop: last_op_in_multiop OpId = " << last_op_in_multiop->GetOpId() << "\n");      
03845       ddderr ("last_op_in_multiop: GetNextLink() OpId = " << last_op_in_multiop->GetNextLink()->GetOpId() << "\n");    
03846       break; 
03847     }
03848   }
03849   
03850   // Not yet ready to deal with jump tables. There may be some opportunities 
03851   // for improvement here, but skip these guys for now. It will be hard to 
03852   // 'split' jump tables because I need fully resolved predicates for each 
03853   // branch
03854   if (op->GetOpcode() == BRU) {
03855     for (atl = op->GetOpAttrListPtr(); atl != NULL;
03856          atl = atl->GetNextListPtr())
03857       if (atl->GetAttrType() == ATTR_TBLNAME) return (RENAMING_CONFLICT);
03858   }
03859   if (predecessor_branch_op->GetOpcode() == BRU) {
03860     for (atl = predecessor_branch_op->GetOpAttrListPtr(); atl != NULL;
03861          atl = atl->GetNextListPtr())
03862       if (atl->GetAttrType() == ATTR_TBLNAME) return (RENAMING_CONFLICT);
03863   }
03864 
03865   switch (op->GetOpcode()) {
03866   // BRUs and DUMMY_BRs will be removed (previous branches will be re-targeted 
03867   // in this case), otherwise move the branch op. 
03868   case BRU:
03869   case DUMMY_BR:
03870     {
03871       // Adjust one edge, remove the other
03872       edge = FindControlEdge (op, op->GetOutListPtr()->GetOpPtr());
03873       // Update new cmerge's In Op, weight should stay the same
03874       op->GetOutListPtr()->GetOpPtr()->GetInListPtr()->SetOpPtr(predecessor_branch_op);
03875       op->GetOutListPtr()->GetOpPtr()->GetInListPtr()->SetOpId(predecessor_branch_op->GetOpId());
03876       edge->SetFromOpPtr(predecessor_branch_op);
03877       edge->SetFromOpId(predecessor_branch_op->GetOpId());
03878       RemoveEdge(predecessor_branch_op, c_merge_op, parentproc, ET_CNTL); 
03879       // Adjust Out opList
03880       oplist = predecessor_branch_op->GetOutListPtr();
03881       if (oplist->GetOpPtr() == c_merge_op) {
03882         oplist->SetOpPtr(op->GetOutListPtr()->GetOpPtr());
03883         oplist->SetOpId(op->GetOutListPtr()->GetOpPtr()->GetOpId());
03884         oplist->SetWeight(op->GetOutListPtr()->GetWeight());
03885       }
03886       else {
03887         oplist = oplist->GetNextListPtr(); 
03888         oplist->SetOpPtr(op->GetOutListPtr()->GetOpPtr());
03889         oplist->SetOpId(op->GetOutListPtr()->GetOpPtr()->GetOpId());
03890         oplist->SetWeight(op->GetOutListPtr()->GetWeight());
03891       }
03892       if (predecessor_branch_op->GetOpcode() != DUMMY_BR) {
03893         // retarget PBR if this is on the taken path or predecessor is a BRU
03894         btroprd = predecessor_branch_op->GetSrcOprdPtr(); // should be 1st source
03895         pbrrop = NULL;
03896         for (defs = Chains->GetUDChains()->Lookup (btroprd);
03897              (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
03898              defs = defs->GetNextListPtr()) {
03899           def = defs->GetOprdPtr();
03900           pbrrop = def->GetParentOpPtr(); // only one PBRR op should reach
03901           break; 
03902         }
03903         
03904         ddderr ("pbrrop OpId is: " << pbrrop->GetOpId() << "\n");
03905         
03906         if (pbrrop == NULL) {
03907           LegoNonFatal ("DoMoreMessyStuff", "Can't find PBRR/PBRA in block");
03908           return (RENAMING_CONFLICT);
03909         } // end if
03910         
03911         oprd = pbrrop->GetSrcOprdPtr();
03912         if (oprd->GetOprdType() != OT_LITERAL_CB) {
03913           LegoNonFatal ("DoMoreMessyStuff", "PBRR %d not to control block.",
03914                         pbrrop->GetOpId());
03915           return (RENAMING_CONFLICT);
03916         } // end if
03917         if (oprd->GetLiteralControlBlock() == ((legoRegion *) c_merge_op->GetParentBlockPtr())->GetRegionId()) {
03918           oprd->SetLiteralControlBlock(((legoRegion *) op->GetOutListPtr()->GetOpPtr()->GetParentBlockPtr())->GetRegionId());
03919         }   
03920       }   
03921       
03922       // PrepareToDie for op and delete it's corresponding PBR (if BRU)
03923       if (op->GetOpcode() == BRU) {
03924         // Find PBR op
03925         btroprd = op->GetSrcOprdPtr(); // should be 1st source
03926         pbrrop = NULL;
03927         for (defs = Chains->GetUDChains()->Lookup (btroprd);
03928              (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
03929              defs = defs->GetNextListPtr()) {
03930           def = defs->GetOprdPtr();
03931           pbrrop = def->GetParentOpPtr(); // only one PBRR op should reach
03932           break; 
03933         }
03934         
03935         ddderr ("pbrrop OpId is: " << pbrrop->GetOpId() << "\n");
03936         
03937         if (pbrrop == NULL) {
03938           LegoNonFatal ("DoMoreMessyStuff", "Can't find PBRR/PBRA in block");
03939           return (RENAMING_CONFLICT);
03940         } // end if
03941         
03942         //HZ: 03/23/01 pbrr patch
03943         //    adding the processing of the pbrr op such that it would not
03944         //    be removed prematurely. Otherwise, yula would complain about the
03945         //    unfound branch target address, i.e., the BTR is not defined.
03946         //    The problem comes from the following senario:
03947         //      suppose one blcok is the same as the other due to the tail
03948         //      duplication and the pbrr in one block has been scheduled
03949         //      speculatively in a parent block. Then if the pbrr in the 
03950         //      other block is being scheduled, due to the dominator
03951         //      parallelism, this pbrr will be set to dp_remove and the use of
03952         //      this pbrr will be renamed and re-pointed to the former pbrr.
03953         //      Now if one of the two branches using the pbrr can be scheduled
03954         //      into the same parent block, the branches will be combined and
03955         //      its pbrr can be removed. But this removal will cause a problem
03956         //      for the other branch because its def of the src will be not
03957         //      available after the pbrr's removal.
03958         //      Now we add the following patch to this problem:
03959         //       Instead of call preparetodie(pbrr) directly, we will check its
03960         //       uses to see whether there are more valid uses (not set with
03961         //       dp_removal) of this pbrr. If there is, we will not set the
03962         //       dp_removal attribute to this pbrr.
03963         //     Apply this to all the pbrr removals in this function.
03964         
03965         pbrr_used = false;
03966         for(use_temp = Chains->GetDUChains()->Lookup(pbrrop->GetDestOprdPtr());
03967            (use_temp != NULL) && (Chains->GetDUChains()->NotFound() == false);
03968             use_temp = use_temp->GetNextListPtr())
03969         {
03970             temp_br_op = use_temp->GetOprdPtr()->GetParentOpPtr();
03971             if(temp_br_op != op && 
03972                     (FindLcAttribute("dp_remove", temp_br_op) == NULL))
03973             {
03974                 pbrr_used = true;
03975                 break;
03976             }
03977         }
03978                 
03979         if(pbrr_used == false)
03980         {
03981             PrepareToDie(pbrrop);
03982             if (!(pbrrop->IsDummy())) 
03983             {
03984                 multiway_dynamic_op_reduction += ((legoRegion *) pbrrop->GetParentBlockPtr())->GetWeight(); 
03985             }
03986         }
03987         
03988       }
03989       
03990       PrepareToDie(op);
03991       if (!(op->IsDummy())) {
03992         multiway_dynamic_op_reduction += ((legoRegion *) op->GetParentBlockPtr())->GetWeight(); 
03993       }
03994       
03995       break;
03996     }
03997   case RTS:
03998     {
03999       // Static estimator needs to know the original weight for the RTS op,
04000       // difficult to obtain after MultiWay branch formed, add attr.
04001       if (FindLcAttribute( "orig_wt", op ) == NULL) {
04002         oprd = new legoOprd;
04003         oprd->SetOprdType (OT_LITERAL_D);
04004         // FindOpWeight() should be fine before op is moved 
04005         oprd->SetLiteralDouble (FindOpWeight(op));
04006         AddLcAttribute ("orig_wt", oprd, op, parentproc);
04007       }
04008       if ((predecessor_branch_op->GetOpcode() == BRU) || 
04009           (predecessor_branch_op->GetOpcode() == DUMMY_BR)) {
04010         // replace unconditional branch with the RTS 
04011         if (op->GetNextLink() != NULL) {
04012           RemoveMidOp( op, NO ); 
04013         }
04014         else {
04015           RemoveFinalOp( op, NO ); 
04016         } 
04017         AddMidOp( op, last_op_in_multiop->GetPrevLink() );
04018         RemoveEdge(predecessor_branch_op, c_merge_op, parentproc, ET_CNTL); 
04019         current_before_op = last_op_in_multiop; 
04020         
04021         op->SetPredOprdPtr(predecessor_branch_op->GetPredOprdPtr()); 
04022         predecessor_branch_op->SetPredOprdPtr(NULL);
04023           
04024         // Delete predecessor_branch_op and it's corresponding PBR (if BRU)
04025         if (predecessor_branch_op->GetOpcode() == BRU) {
04026           // Find PBR op
04027           btroprd = predecessor_branch_op->GetSrcOprdPtr(); // should be 1st source
04028           pbrrop = NULL;
04029           for (defs = Chains->GetUDChains()->Lookup (btroprd);
04030                (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
04031                defs = defs->GetNextListPtr()) {
04032             def = defs->GetOprdPtr();
04033             pbrrop = def->GetParentOpPtr(); // only one PBRR op should reach
04034             break; 
04035           }
04036           
04037           ddderr ("pbrrop OpId is: " << pbrrop->GetOpId() << "\n");
04038           
04039           if (pbrrop == NULL) {
04040             LegoNonFatal ("DoMoreMessyStuff", "Can't find PBRR/PBRA in block");
04041             return (RENAMING_CONFLICT);
04042           } // end if
04043           
04044           //HZ: pbrr patch
04045           pbrr_used = false;
04046           for(use_temp = Chains->GetDUChains()->Lookup(pbrrop->GetDestOprdPtr());
04047            (use_temp != NULL) && (Chains->GetDUChains()->NotFound() == false);
04048             use_temp = use_temp->GetNextListPtr())
04049           {
04050               temp_br_op = use_temp->GetOprdPtr()->GetParentOpPtr();
04051               if(temp_br_op != predecessor_branch_op && 
04052                     (FindLcAttribute("dp_remove", temp_br_op) == NULL))
04053               {
04054                    pbrr_used = true;
04055                 break;
04056               }
04057           }
04058                 
04059           if(pbrr_used == false)
04060           {
04061             PrepareToDie(pbrrop);
04062             if (!(pbrrop->IsDummy())) 
04063             {
04064                 multiway_dynamic_op_reduction += ((legoRegion *) pbrrop->GetParentBlockPtr())->GetWeight(); 
04065             }
04066           }
04067           
04068         }
04069 
04070         // This was previously scheduled so we can free up these resources
04071         RU_unschedule_op(predecessor_branch_op->GetRUInfoPtr());
04072         L_free_oper_mdes_info (predecessor_branch_op);
04073         L_delete_ru_info_oper(predecessor_branch_op->GetRUInfoPtr());
04074         predecessor_branch_op->SetRUInfoPtr(NULL);
04075         PrepareToDie(predecessor_branch_op);
04076         if (!(predecessor_branch_op->IsDummy())) {
04077           multiway_dynamic_op_reduction += ((legoRegion *) predecessor_branch_op->GetParentBlockPtr())->GetWeight(); 
04078         }
04079         
04080       }
04081       else {
04082         // change predecessor branch to unconditional and move RTS up
04083 
04084         // Find the target of the predecessor_branch_op.
04085         btroprd = predecessor_branch_op->GetSrcOprdPtr(); // should be 1st source
04086         pbrrop = NULL;
04087         for (defs = Chains->GetUDChains()->Lookup (btroprd);
04088              (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
04089              defs = defs->GetNextListPtr()) {
04090           def = defs->GetOprdPtr();
04091           pbrrop = def->GetParentOpPtr(); // only one PBRR op should reach
04092           break; 
04093         }
04094         
04095         ddderr ("pbrrop OpId is: " << pbrrop->GetOpId() << "\n");
04096         
04097         if (pbrrop == NULL) {
04098           LegoNonFatal ("DoMoreMessyStuff", "Can't find PBRR/PBRA in block");
04099           return (RENAMING_CONFLICT);
04100         } // end if
04101         
04102         oprd = pbrrop->GetSrcOprdPtr();
04103         if (oprd->GetOprdType() != OT_LITERAL_CB) {
04104           LegoNonFatal ("DoMoreMessyStuff", "PBRR %d not to control block.",
04105                         pbrrop->GetOpId());
04106           return (RENAMING_CONFLICT);
04107         } // end if
04108         
04109         // Find the Taken Block Id
04110         TakenBlockId = oprd->GetLiteralControlBlock();
04111         
04112         if ((a = FindLcAttribute( "orig_fallthru_pred", predecessor_branch_op )) != NULL) {
04113           new_pred = new legoOprd(*((legoOprd *) (a->GetAttrOprdPtr()->GetLiteralULongLong())));
04114         }
04115         else {
04116           // Find the CMPP op for predecessor branch 
04117           cmppoprd = predecessor_branch_op->GetSrcOprdPtr()->GetNextOprdPtr(); 
04118           cmppop = NULL;
04119           for (defs = Chains->GetUDChains()->Lookup (cmppoprd);
04120                (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
04121                defs = defs->GetNextListPtr()) {
04122             def = defs->GetOprdPtr();
04123             cmppop = def->GetParentOpPtr(); // only one CMPP op should reach
04124             break; 
04125           }
04126           
04127           dderr ("cmppop OpId is: " << cmppop->GetOpId() << "\n");
04128           
04129           if (cmppop == NULL) {
04130             LegoFatal ("DoMoreMessyStuff", "Can't find CMPP for branch");
04131           } 
04132           
04133           second_pred = GetComplementaryDestOprd(cmppop);
04134           new_pred = new legoOprd(*second_pred);
04135         }
04136 
04137         // Now adjust Chains 
04138         oprd_list = new oprdList;
04139         oprd_list->SetOprdPtr (second_pred);
04140         Chains->GetUDChains()->Set (new_pred, oprd_list); 
04141         // Add this use to DUChains of second_pred
04142         if ((a = FindLcAttribute( "orig_fallthru_pred", predecessor_branch_op )) != NULL) {
04143           uses = Chains->GetDUChains()->Lookup ((legoOprd *) (a->GetAttrOprdPtr()->GetLiteralULongLong()));
04144         }
04145         else {
04146           uses = Chains->GetDUChains()->Lookup (second_pred);
04147         }
04148         if ((uses == NULL) || (Chains->GetDUChains()->NotFound() == TRUE)) {
04149           oprd_list = new oprdList;
04150           oprd_list->SetOprdPtr (new_pred);
04151           if ((a = FindLcAttribute( "orig_fallthru_pred", predecessor_branch_op )) != NULL) {
04152             Chains->GetDUChains()->Set (((legoOprd *) (a->GetAttrOprdPtr()->GetLiteralULongLong())), oprd_list);
04153           }
04154           else {
04155             Chains->GetDUChains()->Set (second_pred, oprd_list);
04156           }
04157         }
04158         else {
04159           for (;
04160                uses->GetNextListPtr() != NULL;
04161                uses = uses->GetNextListPtr()) 
04162             ; // find end of DUChain
04163           uses->SetNextListPtr(new oprdList);
04164           uses->GetNextListPtr()->SetOprdPtr(new_pred); 
04165         }
04166 
04167         if (((legoRegion *) c_merge_op->GetParentBlockPtr())
04168             ->GetRegionId() == TakenBlockId) {
04169           if (predecessor_branch_op->GetOpcode() == BRCF) {
04170             op->SetPredOprdPtr(new_pred);
04171             
04172             predecessor_branch_op->SetPredOprdPtr(predecessor_branch_op->GetSrcOprdPtr()
04173                                                   ->GetNextOprdPtr());
04174             predecessor_branch_op->GetSrcOprdPtr()->SetNextOprdPtr(NULL);
04175           }
04176           else if (predecessor_branch_op->GetOpcode() == BRCT) {
04177             op->SetPredOprdPtr(predecessor_branch_op->GetSrcOprdPtr()
04178                                ->GetNextOprdPtr());
04179             
04180             predecessor_branch_op->SetPredOprdPtr(new_pred);
04181             predecessor_branch_op->GetSrcOprdPtr()->SetNextOprdPtr(NULL);
04182             // Need to verify that predecessor_branch_op does not preceed 
04183             // it's new predicate register in this MultiOp (for yula)
04184             if ((predecessor_branch_op->GetNextLink() != NULL) &&
04185                 !((predecessor_branch_op->GetOpcode() == BRCT) ||
04186                   (predecessor_branch_op->GetOpcode() == BRCF))) {
04187               RemoveMidOp(predecessor_branch_op, NO);
04188               // put just before op (depends on same CMPP)
04189               AddMidOp(predecessor_branch_op, op->GetPrevLink()); 
04190             }
04191           }
04192           else {
04193             LegoFatal ("DoMoreMessyStuff", "Branch not a BRCT or BRCF");
04194           }
04195           
04196           // Clean-up previous opcode
04197           CurrentSTime = predecessor_branch_op->GetSchedTime(); 
04198           CurrentSlot = predecessor_branch_op->GetRUInfoPtr()->slot_used; 
04199           RU_unschedule_op(predecessor_branch_op->GetRUInfoPtr());
04200           // Re-do mdes_info and ru_info pointer initialization
04201           L_free_oper_mdes_info (predecessor_branch_op);
04202           L_delete_ru_info_oper(predecessor_branch_op->GetRUInfoPtr());
04203           predecessor_branch_op->SetRUInfoPtr(NULL);
04204 
04205           // Now re-schedule the new opcode
04206           // initialize operand_ready_times to zero
04207           latency_count = mdes_latency_count();
04208           for (i = 0; i < latency_count; i++)
04209             operand_ready_times[i] = 0;
04210           predecessor_branch_op->SetOpcode(BRU);
04211           L_build_oper_mdes_info (predecessor_branch_op);
04212           L_create_ru_info_oper (predecessor_branch_op);
04213           if (RU_schedule_op_at (predecessor_branch_op->GetRUInfoPtr(), 
04214                              predecessor_branch_op->GetMdesInfoPtr(), 
04215                              operand_ready_times, CurrentSTime, 
04216                              CurrentSlot, 0) == -1) {
04217             LegoFatal ("DoMoreMessyStuff", "New Opcode re-schedule failed");
04218           }
04219           else
04220           {
04221               (*Op).GetOp()->SetMdesTime(CurrentSlot); // Emre  
04222               attrmdes=new legoOprd;
04223               attrmdes->SetOprdType(OT_LITERAL_I);
04224               attrmdes->SetLiteralInteger(CurrentSlot);
04225               attrmdes->SetOprdDataType(DT_I);
04226               attrmdes->SetIntValue(0);
04227               attrmdes->SetNextOprdPtr((legoOprd *)NULL);
04228               attrmdes->SetPrevOprdPtr((legoOprd *)NULL);
04229               attrmdes->SetParentOpPtr((legoOp *)NULL);                  
04230               attrmdes->SetParentAttrPtr((attrs *)NULL);
04231               attrmdes->SetValid(1);
04232               AddLcAttribute("Mdes",attrmdes,(*Op).GetOp(),(legoProc *) FindParentRegionType (RT_PROC,(*Op).GetOp()));
04233               (*Op).GetOp()->SetOpLatency(Machine->opLatency((*Op).GetOp())); // Emre                         
04234           }
04235         }
04236         else {
04237           if (predecessor_branch_op->GetOpcode() == BRCT) {
04238             op->SetPredOprdPtr(new_pred);
04239             
04240             predecessor_branch_op->SetPredOprdPtr(predecessor_branch_op->GetSrcOprdPtr()
04241                                                   ->GetNextOprdPtr());
04242             predecessor_branch_op->GetSrcOprdPtr()->SetNextOprdPtr(NULL);
04243           }
04244           else if (predecessor_branch_op->GetOpcode() == BRCF) {
04245             op->SetPredOprdPtr(predecessor_branch_op->GetSrcOprdPtr()
04246                                ->GetNextOprdPtr());
04247             
04248             predecessor_branch_op->SetPredOprdPtr(new_pred);
04249             predecessor_branch_op->GetSrcOprdPtr()->SetNextOprdPtr(NULL);
04250             // Need to verify that predecessor_branch_op does not preceed 
04251             // it's new predicate register in this MultiOp (for yula)
04252             if ((predecessor_branch_op->GetNextLink() != NULL) &&
04253                 !((predecessor_branch_op->GetOpcode() == BRCT) ||
04254                   (predecessor_branch_op->GetOpcode() == BRCF))) {
04255               RemoveMidOp(predecessor_branch_op, NO);
04256               // put just before op (depends on same CMPP)
04257               AddMidOp(predecessor_branch_op, op->GetPrevLink()); 
04258             }
04259           }
04260           else {
04261             LegoFatal ("DoMoreMessyStuff", "Branch not a BRCT or BRCF");
04262           }
04263           // Clean-up previous opcode
04264           CurrentSTime = predecessor_branch_op->GetSchedTime(); 
04265           CurrentSlot = predecessor_branch_op->GetRUInfoPtr()->slot_used; 
04266           RU_unschedule_op(predecessor_branch_op->GetRUInfoPtr());
04267           // Re-do mdes_info and ru_info pointer initialization
04268           L_free_oper_mdes_info (predecessor_branch_op);
04269           L_delete_ru_info_oper(predecessor_branch_op->GetRUInfoPtr());
04270           predecessor_branch_op->SetRUInfoPtr(NULL);
04271 
04272           // Now re-schedule the new opcode
04273           // initialize operand_ready_times to zero
04274           latency_count = mdes_latency_count();
04275           for (i = 0; i < latency_count; i++)
04276             operand_ready_times[i] = 0;
04277           predecessor_branch_op->SetOpcode(BRU);
04278           L_build_oper_mdes_info (predecessor_branch_op);
04279           L_create_ru_info_oper (predecessor_branch_op);
04280           if (RU_schedule_op_at (predecessor_branch_op->GetRUInfoPtr(), 
04281                              predecessor_branch_op->GetMdesInfoPtr(), 
04282                              operand_ready_times, CurrentSTime, 
04283                              CurrentSlot, 0) == -1) {
04284             LegoFatal ("DoMoreMessyStuff", "New Opcode re-schedule failed");
04285           }
04286           else
04287           {
04288               (*Op).GetOp()->SetMdesTime(CurrentSlot); // Emre  
04289               attrmdes=new legoOprd;
04290               attrmdes->SetOprdType(OT_LITERAL_I);
04291               attrmdes->SetLiteralInteger(CurrentSlot);
04292               attrmdes->SetOprdDataType(DT_I);
04293               attrmdes->SetIntValue(0);
04294               attrmdes->SetNextOprdPtr((legoOprd *)NULL);
04295               attrmdes->SetPrevOprdPtr((legoOprd *)NULL);
04296               attrmdes->SetParentOpPtr((legoOp *)NULL);                  
04297               attrmdes->SetParentAttrPtr((attrs *)NULL);
04298               attrmdes->SetValid(1);
04299               AddLcAttribute("Mdes",attrmdes,(*Op).GetOp(),(legoProc *) FindParentRegionType (RT_PROC,(*Op).GetOp()));
04300               (*Op).GetOp()->SetOpLatency(Machine->opLatency((*Op).GetOp())); // Emre                         
04301           }
04302         }
04303         
04304         if (op->GetNextLink() != NULL) {
04305           RemoveMidOp( op, NO ); 
04306         }
04307         else {
04308           RemoveFinalOp( op, NO ); 
04309         } 
04310         AddMidOp( op, last_op_in_multiop->GetPrevLink() );
04311         current_before_op = last_op_in_multiop; 
04312         
04313         oplist = predecessor_branch_op->GetOutListPtr();
04314         if (oplist->GetOpPtr() !=  c_merge_op) {
04315           oplisttoremove = oplist->GetNextListPtr();
04316           oplist->SetNextListPtr(NULL);
04317           RemoveEdge(predecessor_branch_op, oplisttoremove->GetOpPtr(), parentproc, ET_CNTL); 
04318           delete oplisttoremove;
04319         }
04320         else {
04321           oplisttoremove = oplist;
04322           oplist = oplisttoremove->GetNextListPtr();
04323           oplisttoremove->SetNextListPtr(NULL);
04324           RemoveEdge(predecessor_branch_op, oplisttoremove->GetOpPtr(), parentproc, ET_CNTL); 
04325         delete oplisttoremove;
04326           predecessor_branch_op->SetOutListPtr(oplist);
04327         }
04328         
04329         // adjust this op's PBRR 
04330         oprd->SetLiteralControlBlock(((legoRegion *) oplist->GetOpPtr()->GetParentBlockPtr())->GetRegionId());
04331         
04332       }
04333       break;
04334     }
04335   case BRCT:
04336   case BRCF:
04337     {
04338       if (predecessor_branch_op->GetOpcode() == BRU) {
04339         // Retarget predecessor BRU to this BRC*'s fall-thru.
04340         // Replace BRC* with a BRU. 
04341         if (op->GetNextLink() != NULL) {
04342           RemoveMidOp( op, NO ); 
04343         }
04344         else {
04345           RemoveFinalOp( op, NO ); 
04346         } 
04347         AddMidOp( op, last_op_in_multiop->GetPrevLink() );
04348         RemoveEdge(predecessor_branch_op, c_merge_op, parentproc, ET_CNTL); 
04349         current_before_op = last_op_in_multiop; 
04350         
04351         // find predecessor_branch_op's PBR oprd (to redirect later)
04352         btroprd = predecessor_branch_op->GetSrcOprdPtr(); // should be 1st source
04353         pbrrop = NULL;
04354         for (defs = Chains->GetUDChains()->Lookup (btroprd);
04355              (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
04356              defs = defs->GetNextListPtr()) {
04357           def = defs->GetOprdPtr();
04358           pbrrop = def->GetParentOpPtr(); // only one PBRR op should reach
04359           break; 
04360         }
04361         
04362         ddderr ("pbrrop OpId is: " << pbrrop->GetOpId() << "\n");
04363         
04364         if (pbrrop == NULL) {
04365           LegoNonFatal ("DoMoreMessyStuff", "Can't find PBRR/PBRA in block");
04366           return (RENAMING_CONFLICT);
04367         } // end if
04368         
04369         oprd = pbrrop->GetSrcOprdPtr();
04370         if (oprd->GetOprdType() != OT_LITERAL_CB) {
04371           LegoNonFatal ("DoMoreMessyStuff", "PBRR %d not to control block.",
04372                         pbrrop->GetOpId());
04373           return (RENAMING_CONFLICT);
04374         } // end if
04375         
04376         // Make op a predicated BRU. 
04377         // retarget predecessor_branch_op to op's fall-thru (change predicate, 
04378         // edges, and out ops)
04379         
04380         ddderr ("*** Fix this BRU/BRC* predicate ***\n");
04381         
04382         // Find the CMPP op for this branch 
04383         cmppoprd = op->GetSrcOprdPtr()->GetNextOprdPtr(); 
04384         cmppop = NULL;
04385         for (defs = Chains->GetUDChains()->Lookup (cmppoprd);
04386              (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
04387              defs = defs->GetNextListPtr()) {
04388           def = defs->GetOprdPtr();
04389           cmppop = def->GetParentOpPtr(); // only one CMPP op should reach
04390           break; 
04391         }
04392         
04393         dderr ("cmppop OpId is: " << cmppop->GetOpId() << "\n");
04394         
04395         if (cmppop == NULL) {
04396           LegoFatal ("DoMoreMessyStuff", "Can't find CMPP for branch");
04397         } 
04398         
04399         second_pred = GetComplementaryDestOprd(cmppop);
04400         new_pred = new legoOprd(*second_pred);
04401         // Now adjust Chains 
04402         oprd_list = new oprdList;
04403         oprd_list->SetOprdPtr (second_pred);
04404         Chains->GetUDChains()->Set (new_pred, oprd_list); 
04405         // Add this use to DUChains of second_pred
04406         if ((Chains->GetDUChains()->Lookup (second_pred) == NULL) || 
04407             (Chains->GetDUChains()->NotFound() == TRUE)) {
04408           oprd_list = new oprdList;
04409           oprd_list->SetOprdPtr (new_pred);
04410           Chains->GetDUChains()->Set (second_pred, oprd_list);    
04411         }
04412         else {
04413           for (uses = Chains->GetDUChains()->Lookup (second_pred);
04414                uses->GetNextListPtr() != NULL;
04415                uses = uses->GetNextListPtr()) 
04416             ; // find end of DUChain
04417           uses->SetNextListPtr(new oprdList);
04418           uses->GetNextListPtr()->SetOprdPtr(new_pred); 
04419         }
04420 
04421         if (op->GetOpcode() == BRCT) {
04422           op->SetPredOprdPtr(op->GetSrcOprdPtr()->GetNextOprdPtr());
04423           predecessor_branch_op->SetPredOprdPtr(new_pred);
04424           // Need to verify that predecessor_branch_op does not preceed 
04425           // it's new predicate register in this MultiOp (for yula)
04426           if ((predecessor_branch_op->GetNextLink() != NULL) &&
04427               !((predecessor_branch_op->GetOpcode() == BRCT) ||
04428                 (predecessor_branch_op->GetOpcode() == BRCF))) {
04429             RemoveMidOp(predecessor_branch_op, NO);
04430             // put just before op (depends on same CMPP)
04431             AddMidOp(predecessor_branch_op, op->GetPrevLink()); 
04432           }
04433         }
04434         else if (op->GetOpcode() == BRCF) {
04435           op->SetPredOprdPtr(new_pred);
04436           predecessor_branch_op->SetPredOprdPtr(op->GetSrcOprdPtr()->GetNextOprdPtr());
04437           // Need to verify that predecessor_branch_op does not preceed 
04438           // it's new predicate register in this MultiOp (for yula)
04439           if ((predecessor_branch_op->GetNextLink() != NULL) &&
04440               !((predecessor_branch_op->GetOpcode() == BRCT) ||
04441                 (predecessor_branch_op->GetOpcode() == BRCF))) {
04442             RemoveMidOp(predecessor_branch_op, NO);
04443             // put just before op (depends on same CMPP)
04444             AddMidOp(predecessor_branch_op, op->GetPrevLink()); 
04445           }
04446         }
04447         else {
04448           LegoFatal ("DoMoreMessyStuff", "Branch not a BRCT or BRCF");
04449         }
04450 
04451         // Clean-up previous opcode
04452         // Re-do mdes_info and ru_info pointer initialization
04453         L_free_oper_mdes_info (op);
04454         L_delete_ru_info_oper(op->GetRUInfoPtr());
04455         op->SetRUInfoPtr(NULL);
04456         op->SetOpcode(BRU);
04457         op->GetSrcOprdPtr()->SetNextOprdPtr(NULL);
04458         L_build_oper_mdes_info (op);
04459         L_create_ru_info_oper (op);
04460         
04461         // Find the target of the original branch op.
04462         btroprd2 = op->GetSrcOprdPtr(); // should be 1st source
04463         pbrrop2 = NULL;
04464         for (defs = Chains->GetUDChains()->Lookup (btroprd2);
04465              (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
04466              defs = defs->GetNextListPtr()) {
04467           def = defs->GetOprdPtr();
04468           pbrrop2 = def->GetParentOpPtr(); // only one PBRR op should reach
04469           break; 
04470         }
04471         
04472         ddderr ("pbrrop2 OpId is: " << pbrrop2->GetOpId() << "\n");
04473         ddderr ("op OpId is: " << op->GetOpId() << "\n");
04474         
04475         if (pbrrop2 == NULL) {
04476           LegoNonFatal ("DoMoreMessyStuff", "Can't find PBRR/PBRA in block");
04477           return (RENAMING_CONFLICT);
04478         } // end if
04479         
04480         oprd2 = pbrrop2->GetSrcOprdPtr();
04481         if (oprd2->GetOprdType() != OT_LITERAL_CB) {
04482           LegoNonFatal ("DoMoreMessyStuff", "PBRR %d not to control block.",
04483                         pbrrop2->GetOpId());
04484           return (RENAMING_CONFLICT);
04485         } // end if
04486         
04487         // Find the Taken Block Id
04488         TakenTakenBlockId = oprd2->GetLiteralControlBlock();
04489         
04490         oplist = op->GetOutListPtr();
04491         if (((legoRegion *) oplist->GetOpPtr()->GetParentBlockPtr())
04492             ->GetRegionId() ==  TakenTakenBlockId) {
04493           oplisttoremove = oplist->GetNextListPtr();
04494           oplist->SetNextListPtr(NULL);
04495           // Adjust edge for new BRU
04496           edge = FindControlEdge (op, oplisttoremove->GetOpPtr());
04497           edge->SetFromOpPtr(predecessor_branch_op);
04498           edge->SetFromOpId(predecessor_branch_op->GetOpId());
04499           // Remove edge from predecessor_branch_op
04500           RemoveEdge(predecessor_branch_op, c_merge_op, parentproc, ET_CNTL); 
04501           oprd->SetLiteralControlBlock(((legoRegion *) oplisttoremove->GetOpPtr()->GetParentBlockPtr())->GetRegionId());
04502         }
04503         else {
04504           oplisttoremove = oplist;
04505           oplist = oplisttoremove->GetNextListPtr();
04506           oplisttoremove->SetNextListPtr(NULL);
04507           // Adjust edge for new BRU
04508           edge = FindControlEdge (op, oplisttoremove->GetOpPtr());
04509           edge->SetFromOpPtr(predecessor_branch_op);
04510           edge->SetFromOpId(predecessor_branch_op->GetOpId());
04511           // Remove edge from predecessor_branch_op
04512           RemoveEdge(predecessor_branch_op, c_merge_op, parentproc, ET_CNTL); 
04513           oprd->SetLiteralControlBlock(((legoRegion *) oplisttoremove->GetOpPtr()->GetParentBlockPtr())->GetRegionId());
04514           op->SetOutListPtr(oplist); 
04515         }
04516         predecessor_branch_op->GetOutListPtr()->SetOpPtr(oplisttoremove->GetOpPtr());
04517         predecessor_branch_op->GetOutListPtr()->SetOpId(oplisttoremove->GetOpPtr()->GetOpId());
04518         predecessor_branch_op->GetOutListPtr()->SetWeight(oplisttoremove->GetWeight());
04519         // Update new cmerge's In Op, weight should stay the same
04520         oplisttoremove->GetOpPtr()->GetInListPtr()->SetOpPtr(predecessor_branch_op);
04521         oplisttoremove->GetOpPtr()->GetInListPtr()->SetOpId(predecessor_branch_op->GetOpId());
04522         // Find branch_that_needs_new_predecessor 
04523         TempListIter = List->begin();
04524         while ((*TempListIter).GetOp()->GetOpId() != op->GetOpId()) 
04525           TempListIter++;
04526         for (Front = (*TempListIter).Successors->begin(),
04527              Back = (*TempListIter).Successors->end(); 
04528              Front != Back; 
04529              Front++ ) {
04530           if (((*Front).GetDependencyType() == ET_CNTL) && 
04531               (IsBranchOpButNotBRL((*Front).GetOp())) && 
04532               (((legoRegion *) (*Front).GetOp()->GetParentBlockPtr())
04533                ->GetRegionId() !=  TakenTakenBlockId)) {
04534             branch_that_needs_new_predecessor = (*Front).GetOp();
04535             ddderr ("branch_that_needs_new_predecessor OpId = " << branch_that_needs_new_predecessor->GetOpId() << "\n");
04536             break; 
04537           }
04538         }
04539         if (branch_that_needs_new_predecessor != NULL) {
04540           UpdatePredecessorBranch(branch_that_needs_new_predecessor, op, predecessor_branch_op);
04541         }
04542         delete oplisttoremove;
04543       }
04544       else { // predecessor branch is a BRCT or BRCF
04545         if (op->GetNextLink() != NULL) {
04546           RemoveMidOp( op, NO ); 
04547         }
04548         else {
04549           RemoveFinalOp( op, NO ); 
04550         } 
04551         AddMidOp( op, last_op_in_multiop->GetPrevLink() );
04552         current_before_op = last_op_in_multiop; 
04553         
04554         // Find the target of the predecessor_branch_op.
04555         btroprd = predecessor_branch_op->GetSrcOprdPtr(); // should be 1st source
04556         pbrrop = NULL;
04557         for (defs = Chains->GetUDChains()->Lookup (btroprd);
04558              (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
04559              defs = defs->GetNextListPtr()) {
04560           def = defs->GetOprdPtr();
04561           pbrrop = def->GetParentOpPtr(); // only one PBRR op should reach
04562           break; 
04563         }
04564         
04565         ddderr ("pbrrop OpId is: " << pbrrop->GetOpId() << "\n");
04566         
04567         if (pbrrop == NULL) {
04568           LegoNonFatal ("DoMoreMessyStuff", "Can't find PBRR/PBRA in block");
04569           return (RENAMING_CONFLICT);
04570         } // end if
04571         
04572         oprd = pbrrop->GetSrcOprdPtr();
04573         if (oprd->GetOprdType() != OT_LITERAL_CB) {
04574           LegoNonFatal ("DoMoreMessyStuff", "PBRR %d not to control block.",
04575                         pbrrop->GetOpId());
04576           return (RENAMING_CONFLICT);
04577         } // end if
04578         
04579         // Find the Taken Block Id
04580         TakenBlockId = oprd->GetLiteralControlBlock();
04581         
04582         if (((legoRegion *) c_merge_op->GetParentBlockPtr())
04583             ->GetRegionId() == TakenBlockId) {
04584           // Make op a predicated BRU. 
04585           // retarget predecessor_branch_op to op's fall-thru (change 
04586           // predicate,  edges, and out ops)
04587           
04588           // Find the CMPP op for this branch 
04589           cmppoprd = op->GetSrcOprdPtr()->GetNextOprdPtr(); 
04590           cmppop = NULL;
04591           for (defs = Chains->GetUDChains()->Lookup (cmppoprd);
04592                (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
04593                defs = defs->GetNextListPtr()) {
04594             def = defs->GetOprdPtr();
04595             cmppop = def->GetParentOpPtr(); // only one CMPP op should reach
04596             break; 
04597           }
04598           
04599           dderr ("cmppop OpId is: " << cmppop->GetOpId() << "\n");
04600           
04601           if (cmppop == NULL) {
04602             LegoFatal ("DoMoreMessyStuff", "Can't find CMPP for branch");
04603           } 
04604           
04605           second_pred = GetComplementaryDestOprd(cmppop);
04606           new_pred = new legoOprd(*second_pred);
04607           // Now adjust Chains 
04608           oprd_list = new oprdList;
04609           oprd_list->SetOprdPtr (second_pred);
04610           Chains->GetUDChains()->Set (new_pred, oprd_list); 
04611           // Add this use to DUChains of second_pred
04612           if ((Chains->GetDUChains()->Lookup (second_pred) == NULL) || 
04613               (Chains->GetDUChains()->NotFound() == TRUE)) {
04614             oprd_list = new oprdList;
04615             oprd_list->SetOprdPtr (new_pred);
04616             Chains->GetDUChains()->Set (second_pred, oprd_list);          
04617           }
04618           else {
04619             for (uses = Chains->GetDUChains()->Lookup (second_pred);
04620                  uses->GetNextListPtr() != NULL;
04621                  uses = uses->GetNextListPtr()) 
04622               ; // find end of DUChain
04623             uses->SetNextListPtr(new oprdList);
04624             uses->GetNextListPtr()->SetOprdPtr(new_pred); 
04625           }
04626 
04627           // Use existing orig_fallthru_pred or create a new one
04628           if (FindLcAttribute( "orig_fallthru_pred", predecessor_branch_op ) 
04629               == NULL) {
04630             // Find the CMPP op for predecessor_branch_op 
04631             // Will need to add attribute in case we need the original 
04632             // fall-thru predicate for later branches. 
04633             cmppoprd2 = predecessor_branch_op->GetSrcOprdPtr()->GetNextOprdPtr(); 
04634             cmppop2 = NULL;
04635             for (defs = Chains->GetUDChains()->Lookup (cmppoprd2);
04636                  (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
04637                  defs = defs->GetNextListPtr()) {
04638               def = defs->GetOprdPtr();
04639               cmppop2 = def->GetParentOpPtr(); // only one CMPP op should reach
04640               break; 
04641             }
04642             
04643             dderr ("cmppop2 OpId is: " << cmppop2->GetOpId() << "\n");
04644             
04645             if (cmppop2 == NULL) {
04646               LegoFatal ("DoMoreMessyStuff", "Can't find CMPP for branch");
04647             } 
04648             
04649             if (predecessor_branch_op->GetOpcode() == BRCT) { 
04650               second_pred2 = GetComplementaryDestOprd(cmppop2);
04651               new_pred2 = new legoOprd;
04652               new_pred2->SetOprdType (OT_LITERAL_ULLNG);
04653               // want this attr to be the pointer predicate register
04654               new_pred2->SetLiteralULongLong ((int) second_pred2);
04655             }
04656             else if (predecessor_branch_op->GetOpcode() == BRCF) {
04657               new_pred2 = new legoOprd;
04658               new_pred2->SetOprdType (OT_LITERAL_ULLNG);
04659               // want this attr to be the pointer predicate register
04660               new_pred2->SetLiteralULongLong ((int) (cmppop2->GetDestOprdPtr()));
04661             }
04662             else {
04663               LegoFatal ("DoMoreMessyStuff", "Branch not a BRCT or BRCF");
04664             }
04665             
04666             AddLcAttribute ("orig_fallthru_pred", new_pred2, predecessor_branch_op, parentproc);
04667           }
04668             
04669           if (op->GetOpcode() == BRCT) {
04670             op->SetPredOprdPtr(op->GetSrcOprdPtr()->GetNextOprdPtr());
04671             // We no longer need this op's predicate second source
04672             delete_oprd = predecessor_branch_op->GetSrcOprdPtr()->GetNextOprdPtr();
04673             // Clean-up RDefs before deleting oprd
04674             for (defs = Chains->GetUDChains()->Lookup (delete_oprd);
04675                  (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
04676                  defs = defs->GetNextListPtr()) {
04677               def = defs->GetOprdPtr();
04678               new_uses = NULL; 
04679               for (uses = Chains->GetDUChains()->Lookup (def);
04680                    (uses != NULL) && (Chains->GetDUChains()->NotFound() == FALSE);
04681                    uses = uses->GetNextListPtr()) {
04682                 use = uses->GetOprdPtr();
04683                 if (use != delete_oprd) {
04684                   if (new_uses == NULL) {
04685                     new_uses = new oprdList;
04686                     new_uses->SetOprdPtr(use);
04687                     prev_use = new_uses;
04688                   }
04689                   else {
04690                     new_use = new oprdList;
04691                     new_use->SetOprdPtr(use);
04692                     prev_use->SetNextListPtr(new_use);
04693                     prev_use = new_use;
04694                   } 
04695                 }
04696               }
04697               if (Chains->GetDUChains()->NotFound() == FALSE) {
04698                 uses = Chains->GetDUChains()->Lookup (def);
04699                 delete uses; 
04700                 Chains->GetDUChains()->Set (def, new_uses);
04701               }
04702             }
04703             Chains->GetUDChains()->Lookup (delete_oprd);
04704             if (Chains->GetUDChains()->NotFound() == FALSE) {
04705               Chains->GetUDChains()->Delete (delete_oprd);
04706             }
04707             delete delete_oprd; 
04708             predecessor_branch_op->GetSrcOprdPtr()->SetNextOprdPtr(new_pred);
04709           }
04710           else if (op->GetOpcode() == BRCF) {
04711             op->SetPredOprdPtr(new_pred);
04712             // We no longer need this op's predicate second source
04713             delete_oprd = predecessor_branch_op->GetSrcOprdPtr()->GetNextOprdPtr(); 
04714             // Clean-up RDefs before deleting oprd
04715             for (defs = Chains->GetUDChains()->Lookup (delete_oprd);
04716                  (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
04717                  defs = defs->GetNextListPtr()) {
04718               def = defs->GetOprdPtr();
04719               new_uses = NULL; 
04720               for (uses = Chains->GetDUChains()->Lookup (def);
04721                    (uses != NULL) && (Chains->GetDUChains()->NotFound() == FALSE);
04722                    uses = uses->GetNextListPtr()) {
04723                 use = uses->GetOprdPtr();
04724                 if (use != delete_oprd) {
04725                   if (new_uses == NULL) {
04726                     new_uses = new oprdList;
04727                     new_uses->SetOprdPtr(use);
04728                     prev_use = new_uses;
04729                   }
04730                   else {
04731                     new_use = new oprdList;
04732                     new_use->SetOprdPtr(use);
04733                     prev_use->SetNextListPtr(new_use);
04734                     prev_use = new_use;
04735                   } 
04736                 }
04737               }
04738               if (Chains->GetDUChains()->NotFound() == FALSE) {
04739                 uses = Chains->GetDUChains()->Lookup (def);
04740                 delete uses; 
04741                 Chains->GetDUChains()->Set (def, new_uses);
04742               }
04743             }
04744             Chains->GetUDChains()->Lookup (delete_oprd);
04745             if (Chains->GetUDChains()->NotFound() == FALSE) {
04746               Chains->GetUDChains()->Delete (delete_oprd);
04747             }
04748             delete delete_oprd; 
04749             predecessor_branch_op->GetSrcOprdPtr()->SetNextOprdPtr(op->GetSrcOprdPtr()->GetNextOprdPtr());
04750           }
04751           else {
04752             LegoFatal ("DoMoreMessyStuff", "Branch not a BRCT or BRCF");
04753           }
04754 
04755           // Clean-up previous opcode
04756           // Re-do mdes_info and ru_info pointer initialization
04757           L_free_oper_mdes_info (op);
04758           L_delete_ru_info_oper(op->GetRUInfoPtr());
04759           op->SetRUInfoPtr(NULL);
04760           op->SetOpcode(BRU);
04761           op->GetSrcOprdPtr()->SetNextOprdPtr(NULL);
04762           L_build_oper_mdes_info (op);
04763           L_create_ru_info_oper (op);
04764           
04765           // Find the target of the original branch op.
04766           btroprd2 = op->GetSrcOprdPtr(); // should be 1st source
04767           pbrrop2 = NULL;
04768           for (defs = Chains->GetUDChains()->Lookup (btroprd2);
04769                (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
04770                defs = defs->GetNextListPtr()) {
04771             def = defs->GetOprdPtr();
04772             pbrrop2 = def->GetParentOpPtr(); // only one PBRR op should reach
04773             break; 
04774           }
04775           
04776           ddderr ("pbrrop2 OpId is: " << pbrrop2->GetOpId() << "\n");
04777           ddderr ("op OpId is: " << op->GetOpId() << "\n");
04778           
04779           if (pbrrop2 == NULL) {
04780             LegoNonFatal ("DoMoreMessyStuff", "Can't find PBRR/PBRA in block");
04781             return (RENAMING_CONFLICT);
04782           } // end if
04783           
04784           oprd2 = pbrrop2->GetSrcOprdPtr();
04785           if (oprd2->GetOprdType() != OT_LITERAL_CB) {
04786             LegoNonFatal ("DoMoreMessyStuff", "PBRR %d not to control block.",
04787                           pbrrop2->GetOpId());
04788             return (RENAMING_CONFLICT);
04789           } // end if
04790           
04791           // Find the Taken Block Id
04792           TakenTakenBlockId = oprd2->GetLiteralControlBlock();
04793           
04794           oplist = op->GetOutListPtr();
04795           if (((legoRegion *) oplist->GetOpPtr()->GetParentBlockPtr())
04796               ->GetRegionId() ==  TakenTakenBlockId) {
04797             oplisttoremove = oplist->GetNextListPtr();
04798             oplist->SetNextListPtr(NULL);
04799             // Adjust edge for new BRU
04800             edge = FindControlEdge (op, oplisttoremove->GetOpPtr());
04801             edge->SetFromOpPtr(predecessor_branch_op);
04802             edge->SetFromOpId(predecessor_branch_op->GetOpId());
04803             // Remove edge from predecessor_branch_op
04804             RemoveEdge(predecessor_branch_op, c_merge_op, parentproc, ET_CNTL); 
04805             oprd->SetLiteralControlBlock(((legoRegion *) oplisttoremove->GetOpPtr()->GetParentBlockPtr())->GetRegionId());
04806           }
04807           else {
04808             oplisttoremove = oplist;
04809             oplist = oplisttoremove->GetNextListPtr();
04810             oplisttoremove->SetNextListPtr(NULL);
04811             // Adjust edge for new BRU
04812             edge = FindControlEdge (op, oplisttoremove->GetOpPtr());
04813             edge->SetFromOpPtr(predecessor_branch_op);
04814             edge->SetFromOpId(predecessor_branch_op->GetOpId());
04815             // Remove edge from predecessor_branch_op
04816             RemoveEdge(predecessor_branch_op, c_merge_op, parentproc, ET_CNTL); 
04817             oprd->SetLiteralControlBlock(((legoRegion *) oplisttoremove->GetOpPtr()->GetParentBlockPtr())->GetRegionId());
04818             op->SetOutListPtr(oplist); 
04819           }
04820           if (((legoRegion *) predecessor_branch_op->GetOutListPtr()->GetOpPtr()
04821                ->GetParentBlockPtr())->GetRegionId() ==  TakenBlockId) {
04822             predecessor_branch_op->GetOutListPtr()->SetOpPtr(oplisttoremove->GetOpPtr());
04823             predecessor_branch_op->GetOutListPtr()->SetOpId(oplisttoremove->GetOpPtr()->GetOpId());
04824             predecessor_branch_op->GetOutListPtr()->SetWeight(oplisttoremove->GetWeight());
04825           }
04826           else {
04827             predecessor_branch_op->GetOutListPtr()->GetNextListPtr()->SetOpPtr(oplisttoremove->GetOpPtr());
04828             predecessor_branch_op->GetOutListPtr()->GetNextListPtr()->SetOpId(oplisttoremove->GetOpPtr()->GetOpId());     
04829             predecessor_branch_op->GetOutListPtr()->GetNextListPtr()->SetWeight(oplisttoremove->GetWeight());
04830           }
04831           // Update new cmerge's In Op, weight should stay the same
04832           oplisttoremove->GetOpPtr()->GetInListPtr()->SetOpPtr(predecessor_branch_op);
04833           oplisttoremove->GetOpPtr()->GetInListPtr()->SetOpId(predecessor_branch_op->GetOpId());
04834           // Find branch_that_needs_new_predecessor 
04835           TempListIter = List->begin();
04836           while ((*TempListIter).GetOp()->GetOpId() != op->GetOpId()) 
04837             TempListIter++;
04838           for (Front = (*TempListIter).Successors->begin(),
04839                Back = (*TempListIter).Successors->end(); 
04840                Front != Back; 
04841                Front++ ) {
04842             if (((*Front).GetDependencyType() == ET_CNTL) && 
04843                 (IsBranchOpButNotBRL((*Front).GetOp())) && 
04844                 (((legoRegion *) (*Front).GetOp()->GetParentBlockPtr())
04845                  ->GetRegionId() !=  TakenTakenBlockId)) {
04846               branch_that_needs_new_predecessor = (*Front).GetOp();
04847               ddderr ("branch_that_needs_new_predecessor OpId = " << branch_that_needs_new_predecessor->GetOpId() << "\n");
04848               break; 
04849             }
04850           }
04851           if (branch_that_needs_new_predecessor != NULL) {
04852             UpdatePredecessorBranch(branch_that_needs_new_predecessor, op, predecessor_branch_op);
04853           }
04854           delete oplisttoremove;
04855           
04856         }
04857         else {
04858           // Make predecessor_branch_op a predicated BRU. op will now define 
04859           // the fall-thru path for the predecessor block. 
04860 
04861           // Clean-up previous opcode
04862           CurrentSTime = predecessor_branch_op->GetSchedTime(); 
04863           CurrentSlot = predecessor_branch_op->GetRUInfoPtr()->slot_used; 
04864           RU_unschedule_op(predecessor_branch_op->GetRUInfoPtr());
04865           // Re-do mdes_info and ru_info pointer initialization
04866           L_free_oper_mdes_info (predecessor_branch_op);
04867           L_delete_ru_info_oper(predecessor_branch_op->GetRUInfoPtr());
04868           predecessor_branch_op->SetRUInfoPtr(NULL);
04869 
04870           // Now re-schedule the new opcode
04871           // initialize operand_ready_times to zero
04872           latency_count = mdes_latency_count();
04873           for (i = 0; i < latency_count; i++)
04874             operand_ready_times[i] = 0;
04875           predecessor_branch_op->SetOpcode(BRU);
04876           predecessor_branch_op->SetPredOprdPtr(predecessor_branch_op->GetSrcOprdPtr()
04877                                                 ->GetNextOprdPtr());
04878           predecessor_branch_op->GetSrcOprdPtr()->SetNextOprdPtr(NULL);
04879           L_build_oper_mdes_info (predecessor_branch_op);
04880           L_create_ru_info_oper (predecessor_branch_op);
04881           if (RU_schedule_op_at (predecessor_branch_op->GetRUInfoPtr(), 
04882                              predecessor_branch_op->GetMdesInfoPtr(), 
04883                              operand_ready_times, CurrentSTime, 
04884                              CurrentSlot, 0) == -1) {
04885             LegoFatal ("DoMoreMessyStuff", "New Opcode re-schedule failed");
04886           }
04887           else
04888           {
04889               (*Op).GetOp()->SetMdesTime(CurrentSlot); // Emre  
04890               attrmdes=new legoOprd;
04891               attrmdes->SetOprdType(OT_LITERAL_I);
04892               attrmdes->SetLiteralInteger(CurrentSlot);
04893               attrmdes->SetOprdDataType(DT_I);
04894               attrmdes->SetIntValue(0);
04895               attrmdes->SetNextOprdPtr((legoOprd *)NULL);
04896               attrmdes->SetPrevOprdPtr((legoOprd *)NULL);
04897               attrmdes->SetParentOpPtr((legoOp *)NULL);                  
04898               attrmdes->SetParentAttrPtr((attrs *)NULL);
04899               attrmdes->SetValid(1);
04900               AddLcAttribute("Mdes",attrmdes,(*Op).GetOp(),(legoProc *) FindParentRegionType (RT_PROC,(*Op).GetOp()));
04901               (*Op).GetOp()->SetOpLatency(Machine->opLatency((*Op).GetOp())); // Emre                         
04902           }
04903           
04904           oplist = predecessor_branch_op->GetOutListPtr();
04905           if (((legoRegion *) oplist->GetOpPtr()->GetParentBlockPtr())
04906               ->GetRegionId() ==  TakenBlockId) {
04907             oplisttoremove = oplist->GetNextListPtr();
04908             oplist->SetNextListPtr(NULL);
04909             RemoveEdge(predecessor_branch_op, oplisttoremove->GetOpPtr(), parentproc, ET_CNTL); 
04910             delete oplisttoremove;
04911           }
04912           else {
04913             oplisttoremove = oplist;
04914             oplist = oplisttoremove->GetNextListPtr();
04915             oplisttoremove->SetNextListPtr(NULL);
04916             RemoveEdge(predecessor_branch_op, oplisttoremove->GetOpPtr(), parentproc, ET_CNTL); 
04917             delete oplisttoremove;
04918             predecessor_branch_op->SetOutListPtr(oplist);
04919           }
04920 
04921           // Switch op and predecessor_branch_op locations. I want the BRC*
04922           // op to be the last op in the region so that the fall-thru is not 
04923           // taken prematurely by yula
04924 
04925           // Now move predecessor_branch_op from the last position (at least 
04926           // should be last prior to this move) to just before op
04927           RemoveFinalOp(predecessor_branch_op, NO);
04928           AddMidOp(predecessor_branch_op, op->GetPrevLink()); 
04929         }
04930       }
04931       break; 
04932     }
04933   default:
04934     {
04935       LegoFatal ("DoMoreMessyStuff", "Branch opcode not yet supported");
04936     }
04937   }
04938 
04939   // We will need to refresh Parents and Children, Exit Ops/Edges, etc..
04940   current_block = (legoRegion *) current_before_op->GetParentBlockPtr();
04941   allchildren = original_block->GetChildren();
04942   for (lrrscan = allchildren; lrrscan != NULL;
04943        lrrscan = lrrscan->GetNextListPtr()) {
04944     region = lrrscan->GetRegionPtr();
04945     if (region == NULL) continue;
04946     
04947     // Invalidate child's parents.
04948     region->SetParents (NULL);
04949   }
04950   current_block->SetChildren(NULL);
04951   
04952 
04953   // If only the c_merge is left in original block, destroy it and the block
04954   if (original_block->GetCount() == 1) {
04955     
04956     blocks_removed++;
04957     
04958     // First update the treeTraversalRList, this block will disappear
04959     rlist = ((legoTreegion*) Region)->GetTreeTraversalRList();
04960     if (rlist->GetRegionPtr() == original_block) {
04961       temprl = rlist; 
04962       rlist = rlist->GetNextListPtr(); 
04963       temprl->SetNextListPtr(NULL);
04964       delete temprl; 
04965       ((legoTreegion*) Region)->SetTreeTraversalRList(rlist);
04966     }
04967     else {
04968       for (;
04969            rlist->GetNextListPtr()->GetRegionPtr() != original_block; 
04970            rlist = rlist->GetNextListPtr()) {
04971         // just find the one to remove
04972       }
04973       temprl = rlist->GetNextListPtr(); 
04974       rlist->SetNextListPtr(rlist->GetNextListPtr()->GetNextListPtr());
04975       temprl->SetNextListPtr(NULL);
04976       delete temprl; 
04977     }
04978 
04979     PrepareToDie(c_merge_op);
04980 
04981     ListCount--;
04982     
04983     // now destroy original_block
04984     parent_block = original_block->GetParentPtr();
04985     if (parent_block == NULL)
04986     {
04987       LegoFatal ("DoMoreMessyStuff", "Can't find parent of original_block to be removed %d.", original_block->GetRegionId());
04988     } 
04989     // Get rid of attributes before destroying original_block
04990     RemoveLiveAttribute (original_block, parentproc); 
04991     atl = original_block->GetRegionAttrListPtr();
04992     while (atl != NULL)
04993       {
04994         atype = atl->GetAttrType();
04995         if (atype != ATTR_LC)
04996           {
04997             atl = atl->GetNextListPtr(); continue;  // skip to first lc
04998           } // end if
04999         
05000         // Remove the first attribute here.
05001         a = atl->GetAttrPtr();
05002         RemoveLcAttribute (a->GetAttrString(), original_block, parentproc);
05003         
05004         atl = original_block->GetRegionAttrListPtr();  // reset for next scan
05005       } // end while
05006     switch (current_block->GetRegionType())
05007       {
05008       case RT_BB:
05009         ((legoBB *) current_block)->RefreshOps(); 
05010         ((legoBB *) current_block)->RefreshEdges(); 
05011         break;
05012       case RT_SB:
05013         ((legoSB *) current_block)->RefreshOps(); 
05014         ((legoSB *) current_block)->RefreshEdges(); 
05015         break;
05016       case RT_HB:
05017         ((legoHB *) current_block)->RefreshOps(); 
05018         ((legoHB *) current_block)->RefreshEdges(); 
05019         break;
05020       default:
05021         LegoFatal ("DoMoreMessyStuff", "Can not determine RegionType");
05022       } // end switch
05023     
05024     // Since we can not delete this block yet, we need to Refresh It 
05025     // (it is deleted after procedure is schedule)
05026     switch (original_block->GetRegionType())
05027       {
05028       case RT_BB:
05029         ((legoBB *) original_block)->Re