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

op_scheduler.C

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