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

machine.c

Go to the documentation of this file.
00001 // machine.c
00002 //
00003 // 3/4/98 WAH:  Separated from scheduler library; minor tweaking.
00004 
00005 #include <iostream.h>
00006 #include <string.h>
00007 #include "legoUtil.H"
00008 #include "lmdes.h"
00009 #include "RU_manager.h"
00010 #include "machine.h"
00011 #include "l_alloc_new.h"
00012 #include "mdes2.h"
00013 #include "lmdes.h"
00014 
00015 /* Debugging support, courtesy of Sumedh */
00016 //#define       _MACHINE_DEBUG_
00017 #ifdef _MACHINE_DEBUG_
00018 #define derr(s)         cerr << s
00019 #else
00020 #define derr(s)
00021 #endif
00022 
00023 //#define GetOpFrequency(X)     (double) (X)->GetBlockId()
00024 
00025 #define SchedLengthErrMsg(X,Y,Z)        \
00026       cerr << "\nERROR: machine::" << X << "\n";                        \
00027       cerr << "\tcycle " << (Y) << " >= RT size " << MaxScheduleLength  \
00028            << "\n";                                                     \
00029       cerr << "\tOp " << (Z) << "\n";                                   \
00030       exit( -1 )
00031 
00032 #define ComputeNumBuses(X)      (X) < 1 ? totalSlots : (X)
00033 
00034 enum TinkerOpType machine::TinkerOptype( legoOp *Op );
00035 double GetSuperblockWeight( legoOp *RRTop, machine *m );
00036 
00037 static char *FunctionName;
00038 
00039 L_Alloc_Pool    *Operand_ready_pool = NULL;
00040   
00041 // NewHandler: exception handling for 'new'
00042 //static void NewHandler()
00043 //{
00044 //   cerr << "\nERROR: machine::" << FunctionName << " failed with w/'new'\n";
00045 //   exit( -125 );
00046 //}
00047 
00048 // GetOpFrequency: takes an Op and returns the value of the "orig_wt"
00049 static double GetOpFrequency( legoOp *op )
00050 {
00051   attrs *wtattr;
00052   legoOprd *oprd;
00053 
00054   wtattr = FindLcAttribute ("orig_wt", op);
00055   if (wtattr == NULL) return -1.0;
00056 
00057   oprd = wtattr->GetAttrOprdPtr();
00058   if (oprd == NULL || oprd->GetOprdType() != OT_LITERAL_D) return -1.0;
00059 
00060   return oprd->GetLiteralDouble();
00061 }
00062 
00063 // Added by Emre
00064 
00065 // opLatency: takes an opcode, returns the latency of the instruction
00066 int machine::opLatency(int opCode )
00067 { 
00068   int alt_id,lat; 
00069   alt_id = mdes_heuristic_alt_id (opCode);
00070   
00071   return(mdes_max_completion_time (opCode, alt_id));
00072 }
00073 
00074 // opLatency: takes an Op, returns the latency of the instruction
00075 int machine::opLatency( legoOp *Op )
00076 {
00077   
00078   int opCode, alt_id; 
00079   RU_Info *ru_info; 
00080   //HZ: //opCode = Op->GetOpcode();
00081   opCode = Op->GetBaseOpcode();
00082 
00083   if (Op->GetSchedTime() == -1) {
00084     alt_id = mdes_heuristic_alt_id (opCode);
00085   }
00086   else {
00087     ru_info = Op->GetRUInfoPtr();               /* Pointer to Resource Usage */
00088     alt_id = RU_SELECTED_ALT_ID(ru_info);
00089   }
00090 
00091   return(mdes_max_completion_time (opCode, alt_id));
00092 }
00093 
00094 
00095 // TinkerOptype: given a REBEL opcode, return which type of TINKER Optype
00096 //    it is. This file depends totally on #define values in legoMap.H.
00097 enum TinkerOpType machine::TinkerOptype( int opcode )
00098 {
00099    int lego_opc = opcode;
00100 
00101    if((( lego_opc >= NO_OP ) && ( lego_opc <= XORCM_W )) ||
00102       (( lego_opc >= EXTS_B ) && ( lego_opc <= MOVE )) ||
00103       (( lego_opc >= LDCM ) && ( lego_opc <= CMPR_W_EV )) ||
00104       (( lego_opc >= CMPP ) && ( lego_opc <= CMPP_W_EV_AC_AC )) ||
00105       (( lego_opc >= PBRR ) && ( lego_opc <= PBRA )) ||
00106       lego_opc == DEFINE || lego_opc == ALLOC || lego_opc == LDPRED ||
00107       lego_opc == LIMM)// || lego_opc == COMMIT)
00108      return INT_OP;
00109    else if((( lego_opc >= FADD_S ) && ( lego_opc <= CONVDS )) ||
00110            (( lego_opc >= MOVEF_S ) && ( lego_opc <= MOVEF_D )) ||
00111            (( lego_opc >= FCMPR_S_FALSE ) && ( lego_opc <= FCMPR_D_TRUE )) ||   
00112            (( lego_opc >= FCMPP_S_FALSE_UN_UN ) && ( lego_opc <= FCMPP_D_TRUE_AC_AC )) || 
00113            lego_opc == FLIMM)
00114      return FP_OP;
00115    else if ((( lego_opc >= L_B_V1_V1 ) && ( lego_opc <= FDSLD_INC_D_C3_C3 )) ||
00116             (( lego_opc >= MOVEGF_L ) && ( lego_opc <= MOVEGF_U )) ||
00117             (( lego_opc >= MOVEGF_L ) && ( lego_opc <= MOVEPG )) ||
00118             (( lego_opc >= DVLD_B ) && ( lego_opc <= FDVLD_D )))
00119       return MEM_OP;
00120    else if (( lego_opc >= BRDVI ) && ( lego_opc <= BRDVF ) ||
00121             ( lego_opc >= BRU ) && ( lego_opc <= BRW_F_F_F ) ||
00122             lego_opc == CONTROL_MERGE || lego_opc == MERGE ||
00123             lego_opc == DUMMY_BR || lego_opc == C_MERGE)// || lego_opc == BORK) 
00124       return BR_OP;
00125    else {
00126       cerr << "TinkerOptype( opcode ): invalid opcode: " << lego_opc << "\n";
00127       exit(-1);
00128    }
00129 }
00130 
00131 
00132 // TinkerOptype: given an Op, return which type of TINKER Optype
00133 //    it is. This file depends totally on #define values in legoMap.H.
00134 enum TinkerOpType machine::TinkerOptype( legoOp *Op )
00135 {
00136     if(Op->GetOpcodePtr() == NULL)
00137         return TinkerOptype( Op->GetOpcode() );
00138     else
00139     {
00140         //check the opcode class for the TINKER opcode type
00141         if(Op->IsIntegerOp() || Op->IsDEFINEOp() || Op->IsCompareOp())
00142             return INT_OP;
00143         else if(Op->IsFloatOp())
00144             return FP_OP;
00145         else if(Op->IsLDOp() || Op->IsSTOp())
00146             return MEM_OP;
00147         else if(Op->IsBranchOp() || Op->IsDUMMYBROp() || Op->IsCMERGEOp())
00148             return BR_OP;
00149         else 
00150         {
00151             cerr << "TinkerOptype( Op ): invalid base opcode: " <<
00152                     Op->GetBaseOpcode() << "\n";
00153             exit(-1);
00154         }              
00155     }
00156 }
00157 
00158 // isStoreOp: returns 1 if opcode is a store, 0 otherwise
00159 //int machine::isStoreOp(int opCode)
00160 //{
00161 
00162 //   if ( opCode >= S_B_V1 && opCode <= FS_INC_D_C3 ) return 1;
00163 //   else return 0;
00164 //}
00165 
00166 
00167 
00168 // isStoreOp: returns 1 if opcode is a store, 0 otherwise
00169 int machine::isStoreOp( legoOp *Op )
00170 {
00171     return (Op->IsSTOp());
00172 //   int opCode;
00173 //
00174 //   opCode = Op->GetOpcode();
00175 //   if ( opCode >= S_B_V1 && opCode <= FS_INC_D_C3 ) return 1;
00176 //   else return 0;
00177 }
00178 
00179 
00180 // isLoadOp: returns 1 if opcode is a load, 0 otherwise
00181 //int machine::isLoadOp(int opCode)
00182 //{
00183 //   if (( opCode >= DVLD_B && opCode <= FDVLD_D ) ||
00184 //       ( opCode >= L_B_V1_V1 && opCode <= FL_INC_D_C3_C3 ) ||
00185 //       ( opCode >= DSLD_B_V1_V1 && opCode <= FDSLD_INC_D_C3_C3 )) 
00186 //     return 1;
00187 //   else return 0;
00188 //}
00189 
00190 
00191 // isLoadOp: returns 1 if opcode is a load, 0 otherwise
00192 int machine::isLoadOp( legoOp *Op )
00193 {
00194     return (Op->IsLDOp());
00195 //   int opCode;
00196 //
00197 //   opCode = Op->GetOpcode();
00198 //   if (( opCode >= DVLD_B && opCode <= FDVLD_D ) ||
00199 //       ( opCode >= L_B_V1_V1 && opCode <= FL_INC_D_C3_C3 ) ||
00200 //       ( opCode >= DSLD_B_V1_V1 && opCode <= FDSLD_INC_D_C3_C3 )) 
00201 //     return 1;
00202 //   else return 0;
00203 }
00204 
00205 
00206 // isBranchOp: returns 1 if opcode is a branch, 0 otherwise
00207 int machine::isBranchOp( legoOp *Op )
00208 {
00209    if ( TinkerOptype( Op ) == BR_OP ) return 1;
00210    else return 0;
00211 }
00212 
00213 
00214 // isRealOp: returns 1 if opcode is an Op that occupies an issue slot
00215 //    and machine resources
00216 //int machine::isRealOp( int opCode )
00217 //{
00218 //   if ( opCode == C_MERGE || opCode == DUMMY_BR || opCode == DEFINE ||
00219 //        opCode == PROLOGUE || opCode == EPILOGUE )
00220 //      return 0;
00221 //   else return 1;
00222 //}
00223 
00224 
00225 // isRealOp: returns 1 if opcode is an Op that occupies an issue slot
00226 //    and machine resources
00227 int machine::isRealOp( legoOp *Op )
00228 {
00229     return Op->IsRealOp();
00230 //   int opCode = Op->GetOpcode();
00231 
00232 //   return isRealOp( opCode );
00233 }
00234 
00235 
00236 // setIssueConfig: allocate issue slots for the ops
00237 void machine::setIssueConfig()
00238 {
00239    int i, j;
00240 
00241 
00242    FunctionName = "setIssueConfig";
00243 
00244    // Get a count of the total # issue slots
00245    totalSlots = mdes_total_slots();
00246 
00247    // Allocate 2-d array as the RRT for the schedule. Allocate an extra
00248    // slot to hold info to aid in debugging.
00249    RRT = new int[ totalSlots ][ MaxScheduleLength ];
00250 
00251    // sumedh: this is aid the static estimation process:
00252    RRTop = new legoOp*[totalSlots][MaxScheduleLength];
00253 
00254    // Init the statuses
00255    for ( i = 0; i < MaxScheduleLength; i++ ) 
00256      for ( j = 0; j < totalSlots; j++ ) {
00257        RRT[ j ][ i ] = EMPTY;
00258        RRTop[j][i] = NULL;      // sumedh: to aid static estimation
00259      }
00260 
00261    // mark that the RRT has been allocated:
00262    allocated = TRUE;
00263 }
00264 
00265 
00266 // adjustIssueStatus: given an opCode, allocate an issue slot for that type
00267 //    of Op in 'cycle', if one is available
00268 void machine::adjustIssueStatus( legoOp *Op, int cycle, int slot )
00269 {
00270    int start, stop, i, OpId;
00271    enum TinkerOpType opType;
00272 
00273 
00274    OpId = Op->GetOpId();
00275    if ( cycle >= MaxScheduleLength ) {
00276       SchedLengthErrMsg( "adjustIssueStatus", cycle, Op->GetOpId() );
00277    }
00278 
00279    derr( ">> machine::adjustIssueStatus "
00280          << ", cycle " << cycle << "\n" );
00281 
00282    RRT[ slot ][ cycle ] = OpId;
00283    RRTop[ slot ][ cycle ] = Op;
00284    LastIssueCycle = LastIssueCycle < cycle ? cycle : LastIssueCycle;
00285    derr( "   placing " << OpId << " into slot " << slot << " <<\n" );
00286    return;
00287 }
00288 
00289 
00290 // adjustWritebackStatus:
00291 void machine::adjustWritebackStatus( legoOp *Op, int cycle )
00292 {
00293    LastWritebackCycle = LastWritebackCycle < cycle ? cycle : LastWritebackCycle;
00294 }
00295 
00296 
00297 // resetIssueSlots: sets the status of issue slots to EMPTY in cluster
00298 void machine::resetIssueStatus( int cycle, int cluster )
00299 {
00300    int i;
00301 
00302    if ( cycle >= MaxScheduleLength ) {
00303       cerr << "\nERROR: machine::resetIssueStatus\n";
00304       cerr << "\tcycle " << cycle << " >= RT size " << MaxScheduleLength
00305            << "\n";
00306       exit( -1 );
00307    }
00308 
00309    for ( i = 0; i < totalSlots; i++ )
00310       RRT[ i ][ cycle ] = EMPTY;
00311 }
00312 
00313 
00314 // resetIssueSlots: sets the status of issue slots to EMPTY
00315 // sanjeev - fix this, 9/4/96
00316 void machine::resetIssueStatus( int cycle )
00317 {
00318    int i;
00319 
00320 
00321    if ( cycle >= MaxScheduleLength ) {
00322       cerr << "\nERROR: machine::resetIssueStatus\n";
00323       cerr << "\tcycle " << cycle << " >= RT size " << MaxScheduleLength
00324            << "\n";
00325       exit( -1 );
00326    }
00327 
00328    if ( cycle < MaxScheduleLength )
00329       for ( i = 0; i < totalSlots; i++ )
00330          RRT[ i ][ cycle ] = EMPTY;
00331 }
00332 
00333 
00334 // resetMachine: clear the RRTs
00335 void machine::resetMachine()
00336 {
00337   int i, j;
00338   
00339   LastIssueCycle = LastWritebackCycle = 0;
00340   for ( i = 0; i < totalSlots; i++ )
00341     for ( j = 0; j < MaxScheduleLength; j++ ) {
00342       RRT[ i ][ j ] = EMPTY;
00343       RRTop[ i ][ j ] = NULL;        // sumedh: to aid static estimation
00344     }
00345 }
00346 
00347 
00348 // showIssueStatus: shows what Ops are to be issued in cycle
00349 void machine::showIssueStatus( int cycle )
00350 {
00351    int i;
00352 
00353 
00354    if ( cycle >= MaxScheduleLength ) {
00355       cerr << "\nERROR: machine::showIssueStatus\n";
00356       cerr << "\tcycle " << cycle << " >= RT size " << MaxScheduleLength
00357            << "\n";
00358       exit( -1 );
00359    }
00360 
00361    for ( i = 1; i < totalSlots; i++ ) {
00362       cerr.width( 5 );
00363       if ( RRT[ i ][ cycle ] == EMPTY ) cerr << "N";
00364       else cerr << RRT[ i ][ cycle ] ;
00365    }
00366    cerr << "   |\n";
00367 }
00368 
00369 
00370 // printSchedule: print out all assignments to 'Cycle' in the schedule
00371 void machine::printSchedule( int Cycle )
00372 {
00373    if ( Cycle >= MaxScheduleLength ) {
00374       cerr << "\nERROR: machine::printSchedule\n";
00375       cerr << "\tcycle " << Cycle << " >= RT size " << MaxScheduleLength
00376            << "\n";
00377       exit( -1 );
00378    }
00379 
00380    PrintSchedule( Cycle );
00381 }
00382 
00383 
00384 // printSchedule: print out all assignments to this point in the schedule
00385 void machine::printSchedule()
00386 {
00387    PrintSchedule( LastWritebackCycle );
00388 }
00389 
00390 
00391 // PrintSchedule: print out all assignments in the schedule up to LastCycle
00392 void machine::PrintSchedule( int LastCycle )
00393 {
00394    int i;
00395    char *OutputStr;
00396 
00397    cerr << "\nSlot assignments are in the order they are defined in the hmdes file. \n"
00398         << "For example: \n"
00399         << "$def !num_IALUs 2 \n$def !num_mem_units 1 \n$def !num_branch_units 1 \n"
00400         << "results in slot 1: IALU, slot 2: IALU, slot 3: MEM, and slot 4: BR \n";
00401    cerr << "         Slot\n";
00402    cerr << " Cycle  ";
00403    for ( i = 1; i < totalSlots; i++ ) {
00404       cerr << " ";
00405       cerr.width( 4 );
00406       cerr << i;
00407    }
00408    cerr << "\n";
00409    
00410    for ( i = 1; i <= totalSlots; i++ )
00411       cerr << "-------";
00412    cerr << "--\n";
00413    for ( i = 1; i <= LastCycle; i++ ) {
00414       cerr << "* ";
00415       cerr.width( 4 );
00416       cerr << i << "  ";
00417       showIssueStatus( i );
00418    }
00419    for ( i = 1; i <= totalSlots; i++ )
00420       cerr << "-------";
00421    cerr << "--\n";
00422 }
00423 
00424 
00425 // estimate the execution time etc. statically
00426 void machine::estimateSchedule (double *TotalOps, double *TotalCycles,
00427                                 int assumeDP = 0)
00428 {
00429   int i, j;
00430   int lastbranchcycle = 0;
00431   int nextlastbranchcycle = 0;
00432   int lastcycle;
00433   double totalcycles = 0.0;
00434   double retiredops  = 0.0;
00435   double regionweight = 0.0, totalweight;
00436   opList *opl;
00437   int region_type;
00438 
00439 
00440   derr( ">> machine::estimateSchedule\n" );
00441 
00442   lastcycle = Bypass == TRUE ? LastIssueCycle : LastWritebackCycle;
00443   if ( Bypass == TRUE ) derr( "   Bypass TRUE\n" );
00444   derr( "   lastcycle = " << lastcycle << "\n" );
00445   for (i=1; i <= lastcycle; i++) {
00446 
00447     double max_br_weight = 0.0;
00448     int ignore;
00449 
00450     derr( "\ncycle=" << i << "\n" );
00451     derr( "-----\n" );
00452 
00453     for (j=1; j < totalSlots; j++) {
00454 
00455       attrList *atl;
00456       attrs *a;
00457       int attr_count;
00458 
00459       derr( "   [j=" << j << "] " );
00460 
00461       derr( "   Processing op " << RRTop[j][i]->GetOpId() << "\n" );
00462       ignore = FindLcAttribute( "ignore-static-estimate", RRTop[j][i] ) == NULL 
00463                ?  0 : 1;
00464 
00465       if (RRT[j][i] != EMPTY && ignore == 0 ) {
00466         legoRegion* tttt = (legoRegion*)(RRTop[j][i]->GetParentBlockPtr());
00467 
00468         derr( "   Doing op " << RRTop[j][i]->GetOpId() );
00469         if ( !isRealOp( RRTop[ j ][ i ] ) ) {
00470            derr( "...skipping psuedo-op\n" );
00471            continue;
00472         }
00473         derr( "\n" );
00474 
00475         // 6/5/97 WAH
00476         // Find the proper profile weight for RRTop[j][i].
00477         //cerr << "DuplicateOpsPtr for " << j << " " << i << " " <<
00478         //  (RRTop[j][i])->GetOpId() << " is " <<
00479         //  (RRTop[j][i])->GetDuplicateOpsPtr() << "\n";
00480         if (assumeDP && ((RRTop[j][i])->GetDuplicateOpsPtr() != NULL))
00481           {
00482             double maxdupweight = 0.0;
00483             totalweight = 0.0;
00484 
00485             derr( "   DP: Scanning Op " << (RRTop[j][i])->GetOpId() << "\n" );
00486             for (opl = (RRTop[j][i])->GetDuplicateOpsPtr(); opl != NULL;
00487                  opl = opl->GetNextListPtr())
00488               {
00489                 if (!(opl->GetValid()))
00490                   {
00491                     derr( "   " << opl->GetOpId() << " is invalid.\n" );
00492                     continue;
00493                   }
00494                 if (((legoRegion *) opl->GetOpPtr()->GetParentBlockPtr())
00495                     ->GetParentPtr() !=
00496                     ((legoRegion *) (RRTop[j][i])->GetParentBlockPtr())
00497                     ->GetParentPtr())
00498                   {
00499                     derr( "   " << opl->GetOpId()
00500                           << " is not in the same treegion.\n" );
00501                     continue;
00502                   }
00503                 if (opl->GetOpPtr()->GetSchedTime() != i)
00504                   {
00505                     derr( "   " << opl->GetOpId() << " is not scheduled in "
00506                           << i << "\n" );
00507                     continue;
00508                   }
00509 
00510                 regionweight = GetOpFrequency (opl->GetOpPtr());
00511                 if (regionweight < 0.0)
00512                 if ( (region_type=tttt->GetRegionType()) == RT_SB ||
00513                      ( region_type == RT_HB && 
00514                       FindFlag( SB, (legoRegion *) 
00515                                opl->GetOpPtr()->GetParentBlockPtr() ) != NULL ) )
00516                     regionweight = GetSuperblockWeight (opl->GetOpPtr(), this);
00517                 else
00518                     regionweight = ((legoRegion *)
00519                                     (opl->GetOpPtr()->GetParentBlockPtr()))
00520                       ->GetWeight();
00521                 if (regionweight > maxdupweight)
00522                   maxdupweight = regionweight;
00523                 totalweight += regionweight;
00524                 derr( "      Total weight is now " << totalweight << " from op "
00525                       << opl->GetOpPtr()->GetOpId() << "\n" );
00526               } // end for
00527             regionweight = maxdupweight;
00528             derr( "   Done scanning.\n" );
00529           } // end if
00530         else
00531           {
00532             regionweight = GetOpFrequency (RRTop[j][i]);
00533             if (regionweight < 0.0)
00534               if (tttt->GetRegionType() == RT_BB)
00535                 regionweight = tttt->GetWeight();
00536               else // it's a superblock or a hyperblock
00537                 regionweight = GetSuperblockWeight (RRTop[j][i], this);
00538             totalweight = regionweight;
00539           } // end else
00540 
00541         // Get the number of dynamic ops actually retired
00542         retiredops += totalweight;
00543         derr ( "   Retired ops now at " << retiredops << "\n" );
00544         // Should the line above actually count how many Ops are in the
00545         // region?
00546 
00547         derr( "   Region weight now " << regionweight << "\n" );
00548 
00549         // branch dependent information
00550         if (TinkerOptype (RRTop[j][i]) == BR_OP &&
00551             RRTop[j][i]->IsBRLOp() == false  &&
00552             RRTop[j][i]->IsCMERGEOp() == false) {
00553           // get the weight of the maximum of n branches
00554           if (regionweight > max_br_weight)
00555             max_br_weight = regionweight;
00556 
00557           // set the cycle number of the last branch(es) seen:
00558           if (lastbranchcycle < i)
00559             nextlastbranchcycle = i;
00560 
00561           derr( "   lastbranchcycle=" << lastbranchcycle
00562                 << ", nextlastbranchcycle=" << nextlastbranchcycle << "\n" );
00563         }
00564       }
00565 
00566     }
00567 
00568     derr( "   (1) max_br_weight=" <<  max_br_weight << "\n" );
00569     // There are blocks that end in a DUMMY_BR and contain real Ops. Treat
00570     // these branches as real branches. I assume that this only happens in
00571     // a basic block.
00572     if ( i == lastcycle && max_br_weight == 0 ) max_br_weight = regionweight;
00573     derr( "   (2) max_br_weight=" <<  max_br_weight << "\n" );
00574     totalcycles += (i-lastbranchcycle)*max_br_weight;
00575     derr( "   Total cycles " << totalcycles << ", total Ops " << retiredops
00576           << "\n" );
00577     lastbranchcycle = nextlastbranchcycle;
00578   }
00579 
00580   (*TotalOps) = retiredops;
00581   (*TotalCycles) = totalcycles;
00582 
00583   // print them out:
00584   derr( "   ESTIMATE:retired Ops=" << retiredops << ", Total cycles="
00585         << totalcycles << ", OPC=" << retiredops/totalcycles << "\n" );
00586   derr( "<< machine::estimateSchedule\n" );
00587 }
00588 
00589 
00590 // ShowParameters: gets the various knobs settings and displays them in
00591 //    formatted output
00592 machine::ShowParameters( knobs *Knobs )
00593 {
00594    char flag, *string, uu;
00595    int latency = 0;
00596 
00597 
00598    Knobs->SetDefaultPanel( "machine" );
00599    Knobs->Read( "PlayDoh", flag );
00600    if ( (int ) flag ) cout << "> PlayDoh machine\n";
00601    Knobs->SetDefaultPanel( "machine" );
00602    Knobs->Read( "lmdesfile", string );
00603    cout << "> Machine model (lmdes file) : ";
00604    cout << string;
00605    cout << "\n";
00606    Knobs->Read( "bypass", flag );
00607    if ( (int) flag ) cout << "Full bypass";
00608    cout << "\n";
00609 }
00610 
00611 
00612 //  get MDES load stuff going    
00613 void machine::initialize_lmdes(knobs *Knobs)
00614 {
00615   char *lmdesfile;
00616   
00617   if (!lmdes_initialized()) {
00618     
00619     Knobs->SetDefaultPanel ("machine");
00620     Knobs->Read ("lmdesfile", lmdesfile);
00621     
00622     L_init_lmdes(lmdesfile, 1, 2, 3, 1);
00623     
00624     Operand_ready_pool = L_create_alloc_pool ("operand_ready_times",
00625                                               mdes_latency_count()*sizeof(int), 100);
00626   }
00627   
00628   setIssueConfig();
00629   clustering = FALSE;
00630   BusLatency = 0;
00631   
00632 }
00633 
00634 
00635 // SetKnobs: set internal values, based on the kbobs file
00636 void machine::SetKnobs( knobs* Knobs )
00637 {
00638    char flag;
00639    char *string;
00640 
00641    Knobs->SetDefaultPanel( "machine" );
00642    Knobs->Read( "bypass", flag );
00643    Bypass = (int) flag;
00644    derr( "   Bypass: " << Bypass << "\n" );
00645 
00646    //  get MDES load stuff going    
00647    initialize_lmdes(Knobs);
00648    
00649 }
00650 
00651 
00652 // Constructor
00653 machine::machine( knobs* Knobs )
00654 {
00655    allocated = FALSE;
00656    Bypass = TRUE;
00657    NumClusters = 1;
00658    ClusterWidth = 0;
00659 //   set_new_handler( NewHandler );
00660    SetKnobs( Knobs );
00661    K = Knobs;
00662 }
00663 
00664 
00665 // Default constructor
00666 machine::machine()
00667 {
00668    int i;
00669 
00670    allocated = FALSE;
00671    Bypass = TRUE;
00672    NumClusters = 1;
00673    ClusterWidth = 0;
00674 //   set_new_handler( NewHandler );
00675 }
00676 
00677 // Default destructor
00678 machine::~machine()
00679 {
00680    if ( allocated == TRUE ) {
00681 
00682       int i;
00683 
00684       // sanjeev - is this the right way to delete a 2-d array??
00685 #if 0
00686       for ( i = 0; i < totalSlots; i++ ) {
00687          delete [] RRT[ i ];
00688          delete [] RRTop[ i ];
00689       }
00690       if ( clustering == TRUE )
00691          for ( i = 0; i < NumBuses; i++ )
00692             delete [] BusRRT[ i ];
00693 #else
00694       delete [] RRT;
00695       delete [] RRTop;
00696       if ( clustering == TRUE ) delete [] BusRRT;
00697 #endif
00698    }
00699 }
00700 
00701 
00702 /******************************** End of machine class *********************/
00703 
00704 // GetSuperBlockWeight: Gets the weights for an Op in a superblock
00705 double GetSuperblockWeight( legoOp *RRTop, machine *m )
00706 {
00707   legoOp *blockop, *prevblockop;
00708   opList *opl;
00709 
00710   // Am I at the top of the block?
00711   if ( RRTop->GetPrevLink() == NULL )
00712       return ((legoRegion *) (RRTop->GetParentBlockPtr()))->GetWeight();
00713 
00714   // walk backwards to the last branch or the top of the block
00715   for (prevblockop = RRTop, blockop = RRTop->GetPrevLink();
00716        (m->TinkerOptype (blockop) != BR_OP || blockop->IsBRLOp()
00717         || blockop->IsCMERGEOp()) &&
00718          blockop->GetPrevLink() != NULL;
00719        prevblockop = blockop,
00720          blockop = blockop->GetPrevLink()) /* do nothing */;
00721 
00722   derr( "Stopped walk at ops " << blockop->GetOpId() << " and "
00723         << prevblockop->GetOpId() << "\n" );
00724   if (m->TinkerOptype (blockop) == BR_OP && blockop->IsCMERGEOp() == false
00725       && blockop->IsBRLOp() == false)
00726     {  // found branch - get weight of opList pointing into block
00727 
00728       for (opl = blockop->GetOutListPtr(); opl != NULL;
00729            opl = opl->GetNextListPtr())
00730         if (opl->GetOpId() == prevblockop->GetOpId())
00731           {
00732             derr( "Found branch weight " << opl->GetWeight() << "\n" );
00733             return opl->GetWeight();
00734           } // end if (, for)
00735       if (opl == NULL)
00736         cerr << "Can't find oplist from " << blockop->GetOpId()
00737              << " to " << prevblockop->GetOpId() << "\n";
00738     } // end if
00739   else  // hit top of block - use block weight
00740     {
00741       derr( "Hit top - using weight " << ((legoRegion *) (blockop->GetParentBlockPtr()))->GetWeight()<< "\n" );
00742       return ((legoRegion *) (blockop->GetParentBlockPtr()))->GetWeight();
00743     }
00744   return 0.0;
00745 } // end GetSuperblockWeight

Generated on Mon Jul 21 20:27:59 2003 for TINKER LEGO DOC by doxygen 1.3.2