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

dag.C

Go to the documentation of this file.
00001 // dag.C
00002 //
00003 // 2/11/98 WAH:  Broke away from Scheduler package; minor patching up;
00004 //               disabled PrintGraphicDag.
00005 // 3/23/98 WAH:  Added call to RemoveUndefPredecessors.
00006 // 3/30/98 WAH:  Removed bad destructor calls.
00007 // 4/2/98 WAH:   Removed all explicit destructor calls; blew away old
00008 // 11/20/98 MDJ: Fixed memory leak associated with WriteHashKeys. Need to 
00009 //               delete the WriteHashKeys we allocated before erasing HashTable
00010 //               PrintGraphicDag code.
00011 
00012 #include <iostream.h>
00013 #include <fstream.h>
00014 #include "legoUtil.H"
00015 #include "legoMach.H"
00016 #include "dag.H"
00017 #include "bitvector.H"
00018 
00019 /* Open issues:
00020 
00021 1) The dependencies for the very last Op in a Lego basic block are initially
00022    set but later lost.
00023    Work around: Dependencies are visible after the STL _list_ is copied to a
00024                 vector.
00025 
00026 2) DAG building crashes in non-debug mode.
00027    Work around: Have debug mode write its output to /dev/null.
00028    3/19/98 WAH:  This has been taken care of (sort of) - see the anecdote
00029                  in dag_dependency.C.
00030 
00031 3) Predication is not accounted for when determining dependencies between
00032    Ops.
00033 */
00034 
00035 /* Debugging support, courtesy of Sumedh */
00036 //#define _SHOW_VECTORS_
00037 //#define _DAG_DEBUG_
00038 //#define ddderr(s)  cerr << s
00039 #define ddderr(s)  
00040 //#define dderr(s)  cerr << s
00041 #define dderr(s)  
00042 #if defined (_DAG_DEBUG_)
00043    #define derr(s)  cerr << s
00044 #else
00045    #define derr(s)  
00046 #endif
00047 
00048 // #define _STL_SORTING_
00049 
00050 // wah 3/24/98 in macros, changed ??.BigListElement() to ?? = BigListElement()
00051 #define PrepOpForInsertion(X,Y,Z)                       \
00052                 (X) = BigListElement();                 \
00053                 (X).SetOp( (Y) );                       \
00054                 (X).SetWeight( (Z) );                   \
00055                 (X).SetHeight( -1 );                    \
00056                 (X).SetDepth( -1 )
00057 
00058 
00059 #define SetClusterId(X,Y)                                       \
00060       if ( (A=FindLcAttribute( "clusterid", (X) )) != NULL ) {  \
00061          legoOprd *OprdPtr = A->GetAttrOprdPtr();               \
00062          (Y).ClusterId = OprdPtr->GetLiteralInteger();          \
00063       }
00064 
00065 
00066 #define CorrectionCode()        Element = BigListElement();     \
00067                                 Element.SetOp( NULL );          \
00068                                 InsertOp( Element );            \
00069                                 MasterList.pop_back()
00070 
00071 
00072 static char *FunctionName;
00073 
00074 #include "dag_utilities.C"              // Utility routines
00075 #include "dag_dependency.C"             // Routines to detect dependencies
00076 #include "dag_sort.C"                   // Comparsion routines for sorting
00077 
00078 extern int MaxRegNum; 
00079 
00080 /*
00081  * UpdateTreeTraversalRList
00082  * 
00083  */
00084 void 
00085 UpdateTreeTraversalRList (legoRegion *region)
00086 {
00087 
00088   derr( ">> UpdateTreeTraversalRList\n" );
00089 
00090   regionList *treetraversalrl, *thisrl; 
00091   
00092   treetraversalrl = ((legoTreegion *)region->GetParentPtr())
00093     ->GetTreeTraversalRList();
00094   if (treetraversalrl != NULL) {
00095     for (;
00096          treetraversalrl->GetNextListPtr() != NULL;
00097          treetraversalrl = treetraversalrl->GetNextListPtr())
00098       ; // find the end of the list
00099   }
00100 
00101   // Add this region to the end
00102   thisrl = new regionList();
00103   thisrl->SetRegionPtr(region);
00104   
00105   if (treetraversalrl == NULL) {
00106     ((legoTreegion *)region->GetParentPtr())->SetTreeTraversalRList(thisrl);
00107   }
00108   else {
00109     treetraversalrl->SetNextListPtr(thisrl);
00110   }
00111   
00112 }
00113 
00114 // mdj 6/9/98 add attribute for tree-traversal treegion scheduling
00115 /*
00116  * AddNextBlockAttribute
00117  *   op = op to annotate
00118  *   returns: new attr attached to op
00119  *
00120  * Attaches a new attr to the op with the ptr to the next block in 
00121  * the tree-traversal search used to ConstructTreeDag. The pointer 
00122  * will be used to determine which ops to mask out of the priority 
00123  * list for tree-traversal scheduling. Ops that are not "below" this 
00124  * block are not considered for scheduling
00125  * 
00126  */
00127 static attrs *
00128 AddNextBlockAttribute (legoRegion *region, int BlockPtr)
00129 {
00130   legoOprd *oprd;
00131   attrs *wtattr;
00132 
00133   derr( ">> AddNextBlockAttribute\n" );
00134 
00135   oprd = new legoOprd;
00136   oprd->SetOprdType (OT_LITERAL_ULLNG);
00137   oprd->SetLiteralULongLong (BlockPtr);
00138 
00139   derr ("... adding next_block_int = " << BlockPtr << " to region id " 
00140         << region->GetRegionId() << "\n" );
00141   wtattr = AddLcAttribute ("next_block_int", oprd, region,
00142                            (legoProc *) FindParentRegionType (RT_PROC, region));
00143   return wtattr;
00144 
00145 }
00146 
00147 // PrintGraphicDag: shows the dag in a graphic manner
00148 void dag::PrintGraphicDag( int print_control_edges )
00149 {
00150   LegoNonFatal ("dag::PrintGraphicDag", "This function has been disabled.\n"
00151                 "A new graph drawing routine, DrawDAG, is in the LEGO "
00152                 "Analysis library.");
00153   return;
00154 }
00155 
00156 
00157 
00158 // PrintVectorDag:
00159 void dag::PrintVectorDag( vector < BigListElement > *V )
00160 {
00161    vector < BigListElement >::iterator Front, Back;
00162 
00163    for( Front = V->begin(), Back = V->end(); Front != Back; Front++ )
00164       (*Front).PrintElement();
00165 }
00166 
00167 //HZ: 08/29/00
00168 void dag::PrintVectorDag( vector < BigListElement > *V, ofstream & os1)
00169 {
00170    vector < BigListElement >::iterator Front, Back;
00171 
00172    for( Front = V->begin(), Back = V->end(); Front != Back; Front++ )
00173       (*Front).PrintElement(os1);
00174 }
00175 
00176 
00177 
00178 // PrintDag: prints only the MasterList portion of the DAG
00179 void dag::PrintDag()
00180 {
00181    BigListElement Element;
00182    MainList::iterator Front, Back;
00183 
00184 
00185    cerr << "\nPrinting the DAG\n----------------\n";
00186 
00187 #if defined (_STL_LIST_USED_)
00188    if ( VectorActive == 1 ) {
00189       if ( Vector.size() == 0 ) {
00190          cerr << "*** Empty dag!! ***\n";
00191          return;
00192       }
00193       cerr << "   DAG has " << Vector.size() << " nodes\n";
00194       PrintVectorDag( &Vector );
00195       return;
00196    } // if
00197    else {
00198       if ( MasterList.size() == 0 ) {
00199          cerr << "*** Empty dag!! ***\n";
00200          return;
00201       }
00202       cerr << "   DAG has " << MasterList.size() << " nodes\n";
00203       for( Front = MasterList.begin(), Back = MasterList.end(); Front != Back;
00204            Front++ )
00205          (*Front).PrintElement();
00206    }
00207 #else if defined (_STL_VECTOR_USED_)
00208    if ( MasterList.size() == 0 ) {
00209       cerr << "*** Empty dag!! ***\n";
00210       return;
00211    }
00212    cerr << "   DAG has " << MasterList.size() << " nodes\n";
00213    PrintVectorDag( &MasterList );
00214 #endif
00215 }
00216 
00217 //HZ: 08/24/00
00218 // PrintDag: prints only the MasterList portion of the DAG
00219 void dag::PrintDag(ofstream & os1)
00220 {
00221    BigListElement Element;
00222    MainList::iterator Front, Back;
00223 
00224    cerr << "\nPrinting the DAG\n----------------\n";
00225 
00226 #if defined (_STL_LIST_USED_)
00227    if ( VectorActive == 1 ) {
00228       if ( Vector.size() == 0 ) {
00229          cerr << "*** Empty dag!! ***\n";
00230          return;
00231       }
00232       os1 << "   DAG has " << Vector.size() << " nodes\n";
00233       PrintVectorDag( &Vector, os1 );
00234       return;
00235    } // if
00236    else {
00237       if ( MasterList.size() == 0 ) {
00238          os1 << "*** Empty dag!! ***\n";
00239          return;
00240       }
00241       os1 << "   DAG has " << MasterList.size() << " nodes\n";
00242       for( Front = MasterList.begin(), Back = MasterList.end(); Front != Back;
00243            Front++ )
00244          (*Front).PrintElement(os1);
00245    }
00246 #else if defined (_STL_VECTOR_USED_)
00247    if ( MasterList.size() == 0 ) {
00248       os1 << "*** Empty dag!! ***\n";
00249       return;
00250    }
00251    os1 << "   DAG has " << MasterList.size() << " nodes\n";
00252    PrintVectorDag( &MasterList, os1 );
00253 #endif
00254 }
00255 
00256 
00257 
00258 // InsertOp: insert Element into MasterList
00259 MainList::iterator dag::InsertOp( BigListElement Element )
00260 {
00261 
00262    MainList::iterator MasterListIter;
00263 
00264 #if defined (_STL_LIST_USED_)
00265    MasterListIter = MasterList.insert( MasterList.begin(), Element )
00266 #else if defined (_STL_VECTOR_USED_)
00267    MasterList.push_back( Element );
00268    MasterListIter = MasterList.end();
00269    MasterListIter--;
00270 #endif
00271 
00272    return MasterListIter;
00273 }
00274 
00275 
00276 // SetBrDeps: sets control dep arcs to Target from Front to Back
00277 void dag::SetBrDeps( MainList::iterator MasterListIter )
00278 {
00279    int rc;
00280    MainList::iterator Front;
00281 
00282    derr( ">> SetBrDeps\n" );
00283    for ( Front = BranchBarrier; Front != MasterListIter;
00284 #if defined (_STL_LIST_USED_)
00285         Front-- ) {
00286 #else if defined (_STL_VECTOR_USED_)
00287      Front++ ) {
00288 #endif
00289       if ((*MasterListIter).GetOp()->IsBRLOp()) {
00290         // only add edges between other BRL ops, if dependent
00291         if ((*Front).GetOp()->IsBRLOp()) {
00292           if (AreOpsDependent((*Front).GetOp(), (*MasterListIter).GetOp())) {
00293             dderr( ">> Inserted br-dep edge between "
00294                   << (*Front).GetOp()->GetOpId() );
00295             rc = (*Front).AddSuccessor( ET_CNTL, (*MasterListIter).GetOp(),
00296                                        &(*MasterListIter) );
00297             dderr( " (" << rc << ") " );
00298             rc = (*MasterListIter).AddPredecessorBeginning( ET_CNTL, (*Front).GetOp(),
00299                                                   &(*Front) );
00300             dderr( " and " << (*MasterListIter).GetOp()->GetOpId() << " (" << rc
00301                   << ")\n" );
00302           }
00303         }
00304       }
00305     } // for
00306    derr( "<< SetBrDeps\n" );
00307 }
00308 
00309 
00310 // SetBrDepsFirst: sets control dep arcs to Target from Front to Back
00311 // mdj 5/14/98 I added this function to get the correct dep from the 
00312 // branch in the parent BB to the first branch in a sibling BB. Previously,
00313 // control edges were being added from sibling BB to sibling BB incorrectly
00314 void dag::SetBrDepsFirst( MainList::iterator MasterListIter, legoRegion *Region )
00315 {
00316   int rc;
00317   MainList::iterator Front, Search, Search2;
00318   legoOp *EntryOp;
00319   opList *ParentExitOp;
00320   
00321   derr( ">> SetBrDepsFirst\n" );
00322   // because this is a treegion, the only InEdge is from the branch 
00323   // from the parent BB
00324   EntryOp = (legoOp *) Region->GetItem( 0 );
00325   ParentExitOp = EntryOp->GetInListPtr();
00326 #if defined (_STL_LIST_USED_)
00327   Search = MasterList.begin();
00328 #else if defined (_STL_VECTOR_USED_)
00329   Search = MasterList.begin();
00330 #endif
00331   while ( ParentExitOp->GetOpId() != (*Search).GetOp()->GetOpId() ) {
00332 #if defined (_STL_LIST_USED_)
00333     Search++;
00334 #else if defined (_STL_VECTOR_USED_)
00335     Search++;
00336 #endif
00337   }
00338   dderr( ">> Inserted br-dep edge between "
00339        << (*Search).GetOp()->GetOpId() );
00340   rc = (*Search).AddSuccessor( ET_CNTL, (*MasterListIter).GetOp(),
00341                               &(*MasterListIter) );
00342   dderr( " (" << rc << ") " );
00343   rc = (*MasterListIter).AddPredecessorBeginning( ET_CNTL, (*Search).GetOp(),
00344                                         &(*Search) );
00345   dderr( " and " << (*MasterListIter).GetOp()->GetOpId() << " (" << rc
00346        << ")\n" );
00347   
00348   // Now add a control edge from the ParentExitOp to the entry C_MERGE 
00349 #if defined (_STL_LIST_USED_)
00350   Search2 = MasterList.begin();
00351 #else if defined (_STL_VECTOR_USED_)
00352   Search2 = MasterList.begin();
00353 #endif
00354   while ( EntryOp->GetOpId() != (*Search2).GetOp()->GetOpId() ) {
00355 #if defined (_STL_LIST_USED_)
00356     Search2+
00357 #else if defined (_STL_VECTOR_USED_)
00358     Search2++;
00359 #endif
00360   }
00361   dderr( ">> Inserted control edge between "
00362        << (*Search).GetOp()->GetOpId() );
00363   rc = (*Search).AddSuccessor( ET_CNTL, (*Search2).GetOp(),
00364                               &(*Search2) );
00365   dderr( " (" << rc << ") " );
00366   rc = (*Search2).AddPredecessorBeginning( ET_CNTL, (*Search).GetOp(),
00367                                         &(*Search) );
00368   dderr( " and entry C_MERGE " << (*Search2).GetOp()->GetOpId() << " (" << rc
00369        << ")\n" );
00370   
00371   // Now handle the other edges for ops preceding this branch
00372   for (Front = BranchBarrier;
00373        Front != MasterListIter;
00374 #if defined (_STL_LIST_USED_)
00375        Front-- ) {
00376 #else if defined (_STL_VECTOR_USED_)
00377     Front++ ) {
00378 #endif 
00379          if ((*MasterListIter).GetOp()->IsBRLOp()) {
00380            // only add edges between other BRL ops, if dependent
00381            if ((*Front).GetOp()->IsBRLOp()) {
00382              if (AreOpsDependent((*Front).GetOp(), (*MasterListIter).GetOp())) {
00383                dderr( ">> Inserted br-dep edge between "
00384                      << (*Front).GetOp()->GetOpId() );
00385                rc = (*Front).AddSuccessor( ET_CNTL, (*MasterListIter).GetOp(),
00386                                           &(*MasterListIter) );
00387                dderr( " (" << rc << ") " );
00388                rc = (*MasterListIter).AddPredecessorBeginning( ET_CNTL, (*Front).GetOp(),
00389                                                               &(*Front) );
00390                dderr( " and " << (*MasterListIter).GetOp()->GetOpId() << " (" << rc
00391                      << ")\n" );
00392              }
00393            }
00394          }
00395        } // for
00396   derr( "<< SetBrDepsFirst\n" );
00397 }
00398 
00399 
00400 // 
00401 void dag::SetPBRDeps( MainList::iterator MasterListIter, legoRegion *Region )
00402 {
00403   int rc;
00404   MainList::iterator Front, Search, Search2;
00405   legoOp *EntryOp;
00406   opList *ParentExitOp;
00407   
00408   derr( ">> SetPBRDeps\n" );
00409   // because this is a treegion, the only InEdge is from the branch 
00410   // from the parent BB
00411   EntryOp = (legoOp *) Region->GetItem( 0 );
00412   ParentExitOp = EntryOp->GetInListPtr();
00413 #if defined (_STL_LIST_USED_)
00414   Search = MasterList.begin();
00415 #else if defined (_STL_VECTOR_USED_)
00416   Search = MasterList.begin();
00417 #endif
00418   while ( ParentExitOp->GetOpId() != (*Search).GetOp()->GetOpId() ) {
00419 #if defined (_STL_LIST_USED_)
00420     Search++;
00421 #else if defined (_STL_VECTOR_USED_)
00422     Search++;
00423 #endif
00424   }
00425   dderr( ">> Inserted PBR br-dep edge between "
00426        << (*Search).GetOp()->GetOpId() );
00427   rc = (*Search).AddSuccessor( ET_CNTL, (*MasterListIter).GetOp(),
00428                               &(*MasterListIter) );
00429   dderr( " (" << rc << ") " );
00430   rc = (*MasterListIter).AddPredecessorBeginning( ET_CNTL, (*Search).GetOp(),
00431                                         &(*Search) );
00432   dderr( " and " << (*MasterListIter).GetOp()->GetOpId() << " (" << rc
00433        << ")\n" );
00434   
00435   derr( "<< SetPBRDeps\n" );
00436 }
00437 
00438 
00439 // ConstructTreeDag: Construct a DAG for the tree region
00440 void dag::ConstructTreeDag(legoRegion *Region, DagHashTable *TablePtr, 
00441                            vector <MainList::iterator> *StoreListPtr,
00442                            vector <MainList::iterator> *LoadListPtr)
00443 {
00444    regionList *Descendant;
00445    legoRegion *ParentRegion, *CurrentRegion;
00446    int OpCount;
00447    legoOp *CurrentOp;
00448    BigListElement Element;
00449    int i;
00450    MainList::iterator MasterListIter, Front, Back, TmpFront, TmpBack;
00451    DagHashTable MyTable;
00452    vector <MainList::iterator> MyStoreList;
00453    vector <MainList::iterator> MyLoadList;
00454    attrs *RC;
00455    int FirstBranch = 1;
00456    legoOprd *PredOprd; 
00457    int true_predicate; 
00458 
00459 
00460    FunctionName = "ConstructTreeDag()";
00461    
00462    if (NotRoot)
00463      UpdateTreeTraversalRList(Region);
00464    prev_block_ptr = Region;
00465    
00466    OpCount = Region->GetCount();
00467    derr( ">> ConstructTreeDag: block " << Region->GetRegionId()
00468          << " w/" << OpCount << " Ops -- BEGIN\n" );
00469 #if defined(_STL_LIST_USED_)
00470    // Assume that new insertions into the list will expand the vector
00471    // by no more than 100%.
00472    Vector.reserve( 2 * OpCount );
00473 #endif
00474    if ( TablePtr != NULL )
00475      {
00476        //       Table.~DagHashTable();
00477        Table = *TablePtr;
00478      } // end if
00479    
00480    if (StoreListPtr != NULL) { 
00481      StoreList.erase( StoreList.begin(), StoreList.end() );     
00482      StoreList = (*StoreListPtr); 
00483    }
00484    if (LoadListPtr != NULL) { 
00485      LoadList.erase( LoadList.begin(), LoadList.end() );
00486      LoadList = (*LoadListPtr); 
00487    }
00488    
00489 #if defined(_STL_LIST_USED_)
00490    TmpFront = MasterList.begin();
00491 #endif
00492    for ( i = 0, CurrentOp = (legoOp *) Region->GetItem( 0 ); i < OpCount;
00493          i++ ) {
00494 
00495       attrs *A;
00496 
00497       derr( "** Op # " << i << ", Op id " << CurrentOp->GetOpId() );
00498       NumNodes++;
00499       PrepOpForInsertion( Element, CurrentOp, Region->GetWeight() );
00500 
00501       // Insert the Op into the Master List
00502       SetClusterId( CurrentOp, Element );
00503       MasterListIter = InsertOp( Element );
00504       Element = (*MasterListIter);
00505       derr( ", cluster " << Element.ClusterId << ", list size "
00506             << MasterList.size() << "\n" );
00507 
00508       // Set the branch barrier
00509       if ( i == 0 ) {
00510          BranchBarrier = MasterListIter;
00511       }
00512 
00513       // Don't let DEFINES affect the DPG
00514       if (CurrentOp->IsDEFINEOp()) {
00515         CurrentOp = CurrentOp->GetNextLink();
00516         continue; 
00517       }
00518 
00519       FlowDeps( MasterListIter, &Element );
00520       OutputAntiDeps( MasterListIter, &Element );
00521       UpdateUseStatus( MasterListIter, &Element );
00522 
00523       // Set branch dependency edges
00524       if ( Machine->TinkerOptype( (*MasterListIter).GetOp() )
00525           == BR_OP && i != 0 ) {
00526         if (NotRoot == 1) {
00527           SetBrDepsFirst( MasterListIter, Region );
00528         }
00529         else {
00530           SetBrDeps( MasterListIter );
00531         }
00532       } // if
00533       
00534       // Set PBRR dependency edges. These edges allow PBRRs to intermix with
00535       // the multi-way branch ops (in the same cycle if zero latency PBRRs)
00536       // But limits them from being speculated higher
00537       
00538       if (NotRoot == 1) {
00539         if ((*MasterListIter).GetOp()->IsPBROp()) {
00540            SetPBRDeps( MasterListIter, Region );
00541         }
00542       }
00543 
00544       // Prevent the speculation of stores
00545       // Right now "mem_independent" never appears in source rebel. Left this
00546       // hook in code in case we ever do any memory disambiguation
00547       RC = FindLcAttribute( "mem_independent", (*MasterListIter).GetOp() );
00548       if ((IsStoreOp( (*MasterListIter).GetOp() ) && RC == NULL) ||
00549           (IsLoadOp( (*MasterListIter).GetOp() ) && RC == NULL) || 
00550           (*MasterListIter).GetOp()->IsBRLOp()) {
00551         // Determine if op has a true predicate
00552         PredOprd = (*MasterListIter).GetOp()->GetPredOprdPtr();
00553         true_predicate = TRUE; 
00554         if (PredOprd != NULL) 
00555           if (PredOprd->GetOprdType() != OT_LITERAL_P ||
00556               PredOprd->GetLiteralPredicate() != TRUE ) 
00557             true_predicate = FALSE; 
00558 
00559         // Either push op onto appropriate StoreList/LoadList or refresh 
00560         // Lists before pushing op on
00561         if ( IsLoadOp( (*MasterListIter).GetOp() ) || !true_predicate ) {
00562           if (IsLoadOp( (*MasterListIter).GetOp())) {
00563             LoadList.push_back(MasterListIter); 
00564           }
00565           else {
00566             StoreList.push_back(MasterListIter); 
00567           }
00568         }
00569         else {
00570           StoreList.erase( StoreList.begin(), StoreList.end() );           
00571           LoadList.erase( LoadList.begin(), LoadList.end() );
00572           if (IsLoadOp( (*MasterListIter).GetOp())) {
00573             LoadList.push_back(MasterListIter); 
00574           }
00575           else {
00576             StoreList.push_back(MasterListIter); 
00577           }
00578         }
00579         derr( ">> Store barrier set to Op "
00580              << (*MasterListIter).GetOp()->GetOpId() << "\n" );
00581       }
00582       CurrentOp = CurrentOp->GetNextLink();
00583    } // for all Ops
00584 
00585    // Since the last entry in a list/vector doesn't 'show up', use some
00586    // extra logic to correct the situation.
00587    CorrectionCode();
00588 
00589    // Mark this block
00590    Region->Mark( RM_GENERAL );
00591    MyTable = DagHashTable ( Table );
00592    MyStoreList = StoreList;
00593    MyLoadList = LoadList;
00594 #if defined(_STL_LIST_USED_)
00595    CopyListToVector( MasterList.begin(), TmpFront );
00596 #endif
00597    derr( "   Examining children of region " << Region->GetRegionId()
00598          << "\n" );
00599 
00600    // Cycle through all of the children for the current node being processed
00601    for ( Descendant = Region->GetChildren(),
00602          ParentRegion = Region->GetParentPtr(); Descendant != NULL;
00603          Descendant = Descendant->GetNextListPtr() ) {
00604 
00605       derr( "   Child of region " << Region->GetRegionId()
00606             << " is region " << Descendant->GetRegionPtr()->GetRegionId()
00607             << "\n" );
00608 
00609       // Check if the current descendant is in the same tree.
00610       if ( ParentRegion != Descendant->GetRegionPtr()->GetParentPtr()
00611            || Region == Descendant->GetRegionPtr()
00612            || Descendant->GetRegionPtr()->IsMarked( RM_GENERAL ) == 1 )
00613          continue;
00614 
00615       CurrentRegion = Descendant->GetRegionPtr();
00616       derr( "   Build DAG for region " << CurrentRegion->GetRegionId()
00617             << "\n" );
00618       // mdj 5/14/98 setBrDepsFirst patch
00619       NotRoot = 1;
00620       ConstructTreeDag( CurrentRegion, &MyTable, &MyStoreList, &MyLoadList );
00621    }
00622    MyTable.erase( MyTable.begin(), MyTable.end() );
00623    MyStoreList.erase( MyStoreList.begin(), MyStoreList.end() );    
00624    MyLoadList.erase( MyLoadList.begin(), MyLoadList.end() );
00625    derr( "<< ConstructTreeDag: block " << Region->GetRegionId()
00626          << " -- DONE\n" );
00627 }
00628 
00629 
00630 // ConstructLinearDag: Construct a DAG for the linear region
00631 void dag::ConstructLinearDag( legoRegion *ParentRegion )
00632 {
00633    int i, rc, OpCount, region_type = ParentRegion->GetRegionType();
00634    BigListElement Element;
00635    legoOp *CurrentOp;
00636    legoRegion *Region;
00637    MainList::iterator MasterListIter, Front, Back;
00638    double weight = ParentRegion->GetWeight();
00639    attrs *RC;
00640    legoOprd *PredOprd; 
00641    int true_predicate; 
00642 
00643 
00644    FunctionName = "ConstructLinearDag()";
00645    derr( ">> ConstructLinearDag\n" );
00646    OpCount = ParentRegion->GetCount();
00647    // wah 3/20/98 Added #ifdef.
00648 #ifdef _DAG_DEBUG_
00649    if ( region_type == RT_SB || ( region_type == RT_HB &&
00650         FindFlag( SB, ParentRegion ) != NULL  )  )
00651       {derr( "   Superblock " );}
00652    else {derr( "   Basic block " );}
00653    derr( ParentRegion->GetRegionId() << " has " << OpCount << " Ops.\n" );
00654 #endif
00655 
00656 #if defined (_STL_VECTOR_USED_)
00657    MasterList.reserve( OpCount + 1 );
00658 #endif
00659    for ( i = 0, CurrentOp = (legoOp *) ParentRegion->GetItem( 0 );
00660          i < OpCount; i++ ) {
00661 
00662       attrs *A;
00663 
00664       derr( "   Op # " << i << ", Op id " << CurrentOp->GetOpId() );
00665       NumNodes++;
00666 
00667       // DON'T REMOVE THE BRACES AROUND THE PrepOpForInsertion(). It's a
00668       // macro.
00669       if ( region_type == RT_BB ) {
00670          PrepOpForInsertion( Element, CurrentOp, weight );
00671       }
00672       else if ( region_type == RT_HB || region_type == RT_SB ) {
00673         PrepOpForInsertion( Element, CurrentOp,
00674                            FindOpWeight( CurrentOp ) );
00675       }
00676 
00677       // Insert the Op into the Master List
00678       SetClusterId( CurrentOp, Element );
00679       MasterListIter = InsertOp( Element );
00680       Element = (*MasterListIter);
00681       derr( ", cluster " << Element.ClusterId << "\n" );
00682 
00683       // Set the first branch barrier
00684       if ( i == 0 ) {
00685         BranchBarrier = MasterListIter;
00686       }
00687 
00688       // Don't let DEFINES affect the DPG
00689       if (CurrentOp->IsDEFINEOp()) {
00690         CurrentOp = CurrentOp->GetNextLink();
00691         continue; 
00692       }
00693 
00694       FlowDeps( MasterListIter, &Element );
00695       OutputAntiDeps( MasterListIter, &Element );
00696       UpdateUseStatus( MasterListIter, &Element );
00697 
00698       // Set branch dependency edges
00699       if ( Machine->TinkerOptype( (*MasterListIter).GetOp() )
00700           == BR_OP && i != 0 ) {
00701         SetBrDeps( MasterListIter );
00702       } // if
00703       
00704       // Prevent the speculation of stores
00705       // Right now "mem_independent" never appears in source rebel. Left this
00706       // hook in code in case we ever do any memory disambiguation
00707       RC = FindLcAttribute( "mem_independent", (*MasterListIter).GetOp() );
00708       if (( IsStoreOp( (*MasterListIter).GetOp() ) && RC == NULL ) ||
00709           ( IsLoadOp( (*MasterListIter).GetOp() ) && RC == NULL ) || 
00710           (*MasterListIter).GetOp()->IsBRLOp()) {
00711         // Determine if op has a true predicate
00712         PredOprd = (*MasterListIter).GetOp()->GetPredOprdPtr();
00713         true_predicate = TRUE; 
00714         if (PredOprd != NULL) 
00715           if (PredOprd->GetOprdType() != OT_LITERAL_P ||
00716               PredOprd->GetLiteralPredicate() != TRUE ) 
00717             true_predicate = FALSE; 
00718 
00719         // Either push op onto appropriate StoreList/LoadList or refresh 
00720         // Lists before pushing op on
00721         if ( IsLoadOp( (*MasterListIter).GetOp() ) || !true_predicate ) {
00722           if (IsLoadOp( (*MasterListIter).GetOp())) {
00723             LoadList.push_back(MasterListIter); 
00724           }
00725           else {
00726             StoreList.push_back(MasterListIter); 
00727           }
00728         }
00729         else {
00730           StoreList.erase( StoreList.begin(), StoreList.end() );           
00731           LoadList.erase( LoadList.begin(), LoadList.end() );
00732           if (IsLoadOp( (*MasterListIter).GetOp())) {
00733             LoadList.push_back(MasterListIter); 
00734           }
00735           else {
00736             StoreList.push_back(MasterListIter); 
00737           }
00738         }
00739         derr( ">> Store barrier set to Op "
00740              << (*MasterListIter).GetOp()->GetOpId() << "\n" );
00741       }
00742       CurrentOp = CurrentOp->GetNextLink();
00743     } // for all Ops
00744    
00745    // Since the last entry in a list/vector doesn't 'show up', use some
00746    // extra logic to correct the situation.
00747    CorrectionCode();
00748 
00749 #if defined (_STL_LIST_USED_)
00750    MasterList.reverse();
00751    CopyListToVector();
00752 #endif
00753    derr( "<< ConstructLinearDag\n" );
00754 }
00755 
00756 
00757 // ConstructDag: Construct a DAG for the Region
00758 void dag::ConstructDag( legoRegion *Region )
00759 {
00760    int region_type;
00761 
00762    FunctionName = "ConstructDag()";
00763    derr( ">> ConstructDag\n" );
00764    ParentRegion = Region;
00765    
00766    //HZ:
00767    //calculate the num of execution paths in the treegion and fill in the path
00768    //info using exit_ops 
00769    opList * op_list1;
00770    num_path = 0;
00771    for(op_list1 = Region->GetExitOpsPtr(); op_list1 != NULL; op_list1 =
00772         op_list1->GetNextListPtr())
00773    {
00774        legoOp * exit_op1 = op_list1->GetOpPtr();
00775        if(exit_op1 != NULL)
00776        {
00777            //set up the path_BB_id (exit BB_id for each path)
00778            path_BB_ids[num_path] =
00779                 ((legoRegion *)exit_op1->GetParentBlockPtr())->GetRegionId();
00780            
00781            //set up the weight for each path
00782            if(exit_op1->IsRETOp())
00783                weights[num_path] =
00784                 ((legoRegion *)exit_op1->GetParentBlockPtr())->GetWeight();
00785            else if(((legoRegion *)exit_op1->GetParentBlockPtr())->GetWeight() >
00786                0)
00787            {
00788                //use the exit edge freq.
00789                //Find the corresponding exit edge(s) and sum up their freqs
00790                //Note that we can not use the region weight as RTS case, as the
00791                // exit edge of the region may not be a true exit edge.
00792                //For example, the fall through edge of a br is a true exit deg
00793                //and its taken edge point to another BB in the same treegion,
00794                // when calculating the weight of the fall through path, the takn
00795                // freq should not be counted.
00796                edgeList *oel = ((legoRegion
00797                        *)exit_op1->GetParentBlockPtr())->GetOutEdgesPtr();
00798                double s_weight = 0;
00799                for(; oel != NULL; oel = oel->GetNextListPtr())
00800                {
00801                    opEdges * edge_p = oel->GetEdgePtr();
00802                    if(edge_p != NULL)
00803                    {
00804                        assert(edge_p->GetFromOpId() == exit_op1->GetOpId());
00805                        if(find_op(Region, edge_p->GetToOpId()) == NULL
00806                                || edge_p->GetToOpId() ==
00807                                Region->GetEntryOpsPtr()->GetOpId())
00808                        {
00809                            //true exit edge
00810                            s_weight += FindEdgeFrequency(edge_p);
00811                        }
00812                    }
00813                }
00814                weights[num_path] = s_weight;
00815            }
00816            else
00817                weights[num_path] = 0;
00818            //setup the # of ops for each path 
00819            int num_op = 0;
00820            legoRegion * temp_reg = (legoRegion *)exit_op1->GetParentBlockPtr();
00821            while(1)
00822            {
00823                if(ParentRegion->GetRegionType() == RT_TREE)
00824                {
00825                    if(temp_reg == ((legoTreegion *)ParentRegion)->GetRoot())
00826                    {
00827                        num_op += temp_reg->GetOpCount();
00828                        break;
00829                    }
00830                }
00831                else 
00832                {
00833                    if(temp_reg == ParentRegion)
00834                    {
00835                        num_op += temp_reg->GetOpCount();
00836                        break;
00837                    }
00838                }
00839                num_op += temp_reg->GetOpCount();
00840                temp_reg = temp_reg->GetParents()->GetRegionPtr();
00841            }
00842            num_ops[num_path] = num_op;
00843            
00844            num_path++;
00845            if(num_path > MAX_NUM_PATH)
00846            {
00847                cout << "Fatal: <DAG Contruction> Paths exceeds MAX_NUM_PATH.\n";
00848                exit(-1);
00849            }
00850        }
00851        else
00852        {
00853            cout << "<DAG Contruction> exit_op not found... \n";
00854        }
00855    }
00856    printf("dag.c: ConstructDag(): EndFor\n");
00857    
00858    if ( !IS_BLOCK( (region_type=Region->GetRegionType()) ) ) {
00859 
00860       int i, BlockCount, OpCount;
00861       legoRegion *CurrentRegion;
00862 
00863       // Count the # of Ops in the region
00864       BlockCount = ParentRegion->GetCount();
00865       derr( "   Treegion " << ParentRegion->GetRegionId() << " has "
00866             << BlockCount << " blocks\n" );
00867       for ( i = 0, OpCount = 0; i < BlockCount; i++ ) {
00868          CurrentRegion = (legoRegion *) ParentRegion->GetItem( i );
00869          OpCount += CurrentRegion->GetCount();
00870          derr( "      Sub-region " << CurrentRegion->GetRegionId()
00871                << " has " << CurrentRegion->GetCount() << " Ops "
00872                << " ( total = " << OpCount << " )\n" );
00873       }
00874 #if defined (_STL_VECTOR_USED_)
00875       MasterList.reserve( OpCount + 1 );
00876       derr( "** " << OpCount << " entries reserved\n" );
00877 #elif defined (_STL_LIST_USED_)
00878       Vector.reserve( OpCount );
00879 #endif
00880 
00881       if ( region_type == RT_TREE ) {
00882          legoTreegion *Tree = (legoTreegion *) ParentRegion;
00883          // mdj 5/14/98 setBrDepsFirst patch
00884          NotRoot = 0;   
00885          ConstructTreeDag( Tree->GetRoot(), NULL, NULL, NULL );
00886          
00887          //HZ: as ConstructTreeDag marks the RM_GENERAL, here to clear it
00888          ClearMarks (RM_GENERAL, Tree);
00889       }
00890       else if ( region_type == RT_TRACE ) {
00891          legoTrace *Trace = (legoTrace *) ParentRegion;
00892          for ( i = 0; i < BlockCount; i++ ) {
00893             CurrentRegion = (legoTrace *) ParentRegion->GetItem( i );
00894             ConstructLinearDag( CurrentRegion );
00895          }
00896       }
00897       // SetSublistPtrs();
00898 #if defined (_STL_LIST_USED_)
00899       DestructBigList( &MasterList );
00900       VectorActive = 1;
00901 #endif
00902    printf("dag.c: ConstructDag(): EndIf\n");
00903    }
00904 
00905    // sanjeev - We do not use hyperblocks at all, but Elcor labels its
00906    // superblocks as hyperblocks. So I need to realize that a HB is really
00907    // a SB w/a different label.
00908    else 
00909   {
00910       ConstructLinearDag( ParentRegion );
00911         printf("dag.c: ConstructDag(): EndElse\n");
00912   }
00913 
00914    // Remove thos spurious ET_UNDEF edges (see dag_dependency.C).
00915    RemoveUndefPredecessors();
00916    printf("RemoveUndef\n");
00917    SetNodeHeights();
00918    printf("SetNodeHeights\n");
00919    SetNodeDepths();
00920    printf("SetNodeDepths\n");
00921    derr( "<< ConstructDag\n" );
00922 }
00923 
00924 
00925 // Stats: get size info on the adjacency list
00926 dag::Stats()
00927 {
00928    int i, j, size;
00929 
00930 
00931    cout << "> DAG stats\n";
00932    cout << ">\n";
00933 #if defined (_STL_LIST_USED_)
00934    if ( VectorActive == 1 )
00935       cout << "> Master list has " << Vector.size() << " nodes\n";
00936    else 
00937       cout << "> Master list has " << MasterList.size() << " nodes\n";
00938 #elif defined (_STL_VECTOR_USED_)
00939       cout << "> Master list has " << MasterList.size() << " nodes\n";
00940 #endif
00941 
00942    cout << "> Hash table has " << Table.size() << " nodes\n\n";
00943 }
00944 
00945 
00946 // dag: constructor
00947 dag::dag( machine *mdes, int Inp_start, int Inp_end, int Ret_start, int Ret_end, int Fp_ret_start,
00948         int Fp_ret_end )
00949 {
00950    derr( ">> dag::constructor\n" );
00951    FunctionName = "constructor()";
00952    Machine = mdes;
00953    VectorActive = 0;
00954    NumNodes = KillDagFlag = 0;
00955    ReadHashKey = new char[ Hash_Key_Size ];
00956    ReadHashReg = new char[ Hash_Reg_Size ];
00957    
00958    //HZ:
00959    max_heights = new double[MAX_NUM_PATH];
00960    path_BB_ids = new int[MAX_NUM_PATH];
00961    weights = new double[MAX_NUM_PATH];
00962    num_ops = new int[MAX_NUM_PATH];
00963    num_path = 0;
00964    ave_max_height = 0;
00965 
00966    inp_start = Inp_start;
00967    inp_end = Inp_end;
00968    ret_start = Ret_start;
00969    ret_end = Ret_end;
00970    fp_ret_start = Fp_ret_start;
00971    fp_ret_end = Fp_ret_end;   
00972    
00973    derr( "<< dag::constructor\n" );
00974    
00975 }
00976 
00977 
00978 // dag: constructor
00979 dag::dag( machine *mdes, knobs *Knobs, int Inp_start, int Inp_end, int Ret_start, int Ret_end, int Fp_ret_start,
00980         int Fp_ret_end )
00981 {
00982    derr( ">> dag::constructor\n" );
00983    FunctionName = "constructor()";
00984    Machine = mdes;
00985    VectorActive = 0;
00986    NumNodes = KillDagFlag = 0;
00987    ReadHashKey = new char[ Hash_Key_Size ];
00988    ReadHashReg = new char[ Hash_Reg_Size ];
00989 
00990    // Read knobs
00991    Knobs->SetDefaultPanel( "estimator" );
00992 
00993    //HZ:
00994    max_heights = new double[MAX_NUM_PATH];
00995    path_BB_ids = new int[MAX_NUM_PATH];
00996    weights = new double[MAX_NUM_PATH];
00997    num_ops = new int[MAX_NUM_PATH];
00998    num_path = 0;
00999    ave_max_height = 0;
01000    
01001    inp_start = Inp_start;
01002    inp_end = Inp_end;
01003    ret_start = Ret_start;
01004    ret_end = Ret_end;
01005    fp_ret_start = Fp_ret_start;
01006    fp_ret_end = Fp_ret_end;
01007    
01008    derr( "<< dag::constructor\n" );
01009 }
01010 
01011 
01012 // DeleteDefUseTable: delete the def-use table
01013 void dag::DeleteDefUseTable()
01014 {
01015    derr( ">> DeleteDefUseTable\n" );
01016    delete[] ReadHashKey;
01017    delete[] ReadHashReg;
01018 
01019    // 11/20/98 MDJ: Fixed memory leak associated with WriteHashKeys
01020    for(vector <char *>::const_iterator LookUpIter = HashKeyList.begin();
01021        LookUpIter != HashKeyList.end();
01022        LookUpIter++ ) {
01023      delete ((*LookUpIter));
01024    }
01025    HashKeyList.erase( HashKeyList.begin(), HashKeyList.end() );
01026 
01027    Table.erase( Table.begin(), Table.end() );
01028    derr( "<< DeleteDefUseTable\n" );
01029 }
01030 
01031 
01032 // DeleteGraphNodes: delete the adjacency list
01033 void dag::DeleteGraphNodes()
01034 {
01035    derr( ">> DeleteGraphNodes\n" );
01036 #if defined (_STL_LIST_USED_)
01037    if ( VectorActive == 1 ) {
01038       derr( "   Delete Vector\n" );
01039       DestructBigVector( &Vector );
01040    }
01041    else {
01042       derr( "   Delete MainList List\n" );
01043       DestructBigList( &MasterList );
01044    }
01045 #else if defined (_STL_VECTOR_USED_)
01046    derr( "   Delete MasterList Vector\n" );
01047    DestructBigVector( &MasterList );
01048 #endif
01049    derr( "<< DeleteGraphNodes\n" );
01050 }
01051 
01052 
01053 // KillDag: destructor
01054 void dag::KillDag()
01055 {
01056    derr( ">> KillDag\n" );
01057    KillDagFlag = 1;
01058    DeleteDefUseTable();
01059    DeleteGraphNodes();
01060    derr( "<< KillDag\n" );
01061 }
01062 
01063 
01064 // dag: destructor
01065 dag::~dag()
01066 {
01067     //HZ:
01068     if(path_BB_ids != NULL) 
01069     {
01070         delete path_BB_ids;
01071         path_BB_ids = NULL;
01072     }
01073     if(max_heights != NULL)
01074     {
01075         delete max_heights;
01076         max_heights = NULL;
01077     }
01078     if(weights != NULL)
01079     {
01080         delete weights;
01081         weights = NULL;
01082     }
01083     if(num_ops != NULL)
01084     {
01085         delete num_ops;
01086         num_ops = NULL;
01087     }
01088    if ( KillDagFlag == 1 ) return;
01089    derr( ">> ~dag\n" );
01090    KillDag();
01091    derr( "<< ~dag\n" );
01092 }

Generated on Mon Jul 21 20:24:05 2003 for TINKER LEGO DOC by doxygen 1.3.2