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

yula_not_mine_live.cpp

Go to the documentation of this file.
00001 // live.C
00002 // 12/16/97 WAH: Cosmetic changes; fixed copy_operand (valid field); fixed
00003 //               matching of operands in BB_defs and BB_uses; adjusted
00004 //               live-in computation.
00005 // 1/9/98 WAH:   Fixed bug in finding children of block in BB_live_out;
00006 //               ChildrenList may be NULL.
00007 // 1/22/98 WAH:  Added checks for valid operands.
00008 // 2/12/98 WAH:  Removed FindFirstDef calls to repair handling of BRLs.
00009 
00010 #include <string.h>
00011 #include <iostream.h>
00012 #include <stl.h> 
00013 //#include "lego.H"
00014 //#include "legoUtil.H"
00015 #include        <lego.H>
00016 #include        <legoUtil.H> 
00017 // #include "rdef.H"
00018 //#include "live.H"
00019 #include        "yula_not_mine_live.h" 
00020 
00021 char            *get_string_out_of_op(legoOprd *);
00022 
00023 // Comment out the debug token if you do NOT want debugging info printed
00024 //#define _LIVE_VAR_DEBUG_
00025 #ifdef _LIVE_VAR_DEBUG_
00026 #define derr(s)         cerr << s
00027 #else
00028 #define derr(s)
00029 #endif
00030 
00031 /*
00032  * CreateReadHashKey
00033  *   X = basic block id
00034  *   Y = register number
00035  *   Z = register file type
00036  *
00037  * Creates a hash key for reading the hash table of the form:
00038  *   bbid-regnum-regfiletype
00039  * and places it into the ReadHashKey field of the LiveVar_nm object.
00040  */
00041 inline void LiveVar_nm::CreateReadHashKey (int X, int Y, int Z)
00042 {
00043   sprintf( ReadHashKey, "%d-", (X) );
00044   sprintf( ReadHashPart1, "%d-", (Y) );
00045   sprintf( ReadHashPart2, "%d", (Z) );
00046   ReadHashKey = strcat(ReadHashKey,ReadHashPart1);
00047   ReadHashKey = strcat(ReadHashKey,ReadHashPart2);
00048 }
00049 
00050 /*
00051  * CreateReadHashKey
00052  *   X = basic block id
00053  *   W = subblock id
00054  *   Y = register number
00055  *   Z = register file type
00056  *
00057  * Creates a hash key for reading the hash table of the form:
00058  *   bbid/subblock-regnum-regfiletype
00059  * and places it into the ReadHashKey field of the LiveVar_nm object.
00060  */
00061 inline void LiveVar_nm::CreateReadHashKey (int X, int W, int Y, int Z)
00062 {
00063   sprintf( ReadHashKey, "%d/", (X) );
00064   sprintf( ReadHashPart1, "%d-", (W) );
00065   sprintf( ReadHashPart2, "%d-", (Y) );
00066   sprintf( ReadHashPart3, "%d", (Z) );
00067   ReadHashKey = strcat(ReadHashKey,ReadHashPart1);
00068   ReadHashKey = strcat(ReadHashKey,ReadHashPart2);
00069   ReadHashKey = strcat(ReadHashKey,ReadHashPart3);
00070 }
00071 
00072 /*
00073  * CreateWriteHashKey
00074  *   X = basic block id
00075  *   Y = register number
00076  *   Z = register file type
00077  *
00078  * Creates a hash key for writing to the hash table of the form:
00079  *   bbid-regnum-regfiletype
00080  * and places it into the WriteHashKey field of the LiveVar_nm object.
00081  */
00082 inline void LiveVar_nm::CreateWriteHashKey (int X, int Y, int Z)
00083 {
00084   WriteHashKey = new char[ HASH_KEY_SIZE ];
00085   WriteHashPart1 = new char[ HASH_PART_SIZE ];
00086   WriteHashPart2 = new char[ HASH_PART_SIZE ];
00087   sprintf( WriteHashKey, "%d-", (X) );
00088   sprintf( WriteHashPart1, "%d-", (Y) );
00089   sprintf( WriteHashPart2, "%d", (Z) );
00090   WriteHashKey=strcat(WriteHashKey,WriteHashPart1 );
00091   WriteHashKey=strcat(WriteHashKey,WriteHashPart2 );
00092   delete[] WriteHashPart1; delete[] WriteHashPart2;
00093 }
00094 
00095 /*
00096  * CreateWriteHashKey
00097  *   X = basic block id
00098  *   W = subblock id
00099  *   Y = register number
00100  *   Z = register file type
00101  *
00102  * Creates a hash key for writing to the hash table of the form:
00103  *   bbid/subblcok-regnum-regfiletype
00104  * and places it into the WriteHashKey field of the LiveVar_nm object.
00105  */
00106 inline void LiveVar_nm::CreateWriteHashKey (int X, int W, int Y, int Z)
00107 {
00108   WriteHashKey = new char[ HASH_KEY_SIZE ];
00109   WriteHashPart1 = new char[ HASH_PART_SIZE ];
00110   WriteHashPart2 = new char[ HASH_PART_SIZE ];
00111   WriteHashPart3 = new char[ HASH_PART_SIZE ];
00112   sprintf( WriteHashKey, "%d/", (X) );
00113   sprintf( WriteHashPart1, "%d-", (W) );
00114   sprintf( WriteHashPart2, "%d-", (Y) );
00115   sprintf( WriteHashPart3, "%d", (Z) );
00116   WriteHashKey=strcat(WriteHashKey,WriteHashPart1 );
00117   WriteHashKey=strcat(WriteHashKey,WriteHashPart2 );
00118   WriteHashKey=strcat(WriteHashKey,WriteHashPart3 );
00119   delete[] WriteHashPart1; delete[] WriteHashPart2;
00120   delete[] WriteHashPart3;
00121 }
00122 
00123 static int subblock;
00124 
00125 /*
00126  * BB_defs
00127  *   OpPtr = op on which to work
00128  *   BBId = id of basic block where op resides
00129  *
00130  * Determines the defs for op OpPtr.
00131  */
00132 void LiveVar_nm::BB_defs( legoOp *OpPtr, int BBId )
00133 {
00134   legoOprd *OprdPtr, *WalkOprdPtr;
00135   legoOp *WalkOpPtr;
00136   SetInfo Info;
00137   SetInfoTable::iterator LookUpIter, EndPtr;
00138 
00139   int RegNum, RegFileType, OprdType, IsBB, NonDef;
00140 
00141 
00142   derr( ">> BB_defs: Op " << OpPtr->GetOpId() << "\n" );
00143 
00144   //  for (OprdPtr = FindFirstDef (OpPtr); OprdPtr != NULL;
00145   //       OprdPtr = OprdPtr->GetNextOprdPtr() )  // loop through defs of op
00146   OprdPtr = OpPtr->GetDestOprdPtr();
00147   while (OprdPtr != NULL)
00148     {
00149       //      if (!(OprdPtr->GetValid())) continue;
00150 
00151       OprdType = OprdPtr->GetOprdType();
00152       if ( OprdType == OT_REG || OprdType == OT_MACRO &&  // reg or macro
00153            OprdPtr->GetValid())  // ... and a valid operand
00154         {
00155           RegNum = OprdPtr->GetOprdRegNum();
00156           RegFileType = OprdPtr->GetOprdFileType();
00157           if ( OprdType == OT_MACRO ) RegFileType = -1;  // pseudo-filetype
00158 
00159           derr( "   Dest Reg: # " << RegNum << ", type: " << RegFileType
00160                 << "\n" );
00161 
00162           // It's not in the def set yet. Skip it if there's a use before it
00163           // in the block / subblock.
00164           NonDef = 0;
00165           for ( WalkOpPtr = OpPtr->GetPrevLink(); WalkOpPtr != NULL &&
00166                   WalkOpPtr->GetOutListPtr() == NULL;
00167                 WalkOpPtr = WalkOpPtr->GetPrevLink() )  // walk up from OpPtr
00168             {
00169               for ( WalkOprdPtr = WalkOpPtr->GetSrcOprdPtr();
00170                     WalkOprdPtr != NULL;
00171                     WalkOprdPtr = WalkOprdPtr->GetNextOprdPtr() )  // srcs...
00172                 {
00173                   if ( WalkOprdPtr->GetOprdType() != OprdType ) continue;
00174                   if ( WalkOprdPtr->GetOprdRegNum() != RegNum ) continue;
00175                   if ( OprdType != OT_MACRO &&
00176                        WalkOprdPtr->GetOprdFileType() != RegFileType )
00177                     continue;
00178 
00179                   // Found a match, so it's not a def.
00180                   derr( "   Found prior use at op " << WalkOpPtr->GetOpId()
00181                         << "\n" );
00182                   NonDef = 1;
00183                   break;
00184                 } // end for
00185               if ( NonDef ) break;
00186             } // for
00187 
00188           // If this is a def (i.e., not a NonDef), write to def set for
00189           // op.
00190           //      if ( NonDef ) continue;  // go to next destination
00191           if ( !NonDef )
00192             {
00193               // Write to def set for op.
00194               IsBB = (((legoRegion *) OpPtr->GetParentBlockPtr())->
00195                       GetRegionType() == RT_BB);
00196               if (IsBB)
00197                 CreateReadHashKey( BBId, RegNum, RegFileType );
00198               else
00199                 CreateReadHashKey( BBId, subblock, RegNum, RegFileType );
00200 
00201               LookUpIter = Table.find( ReadHashKey );  // lookup item
00202               EndPtr = Table.end();
00203               if ( LookUpIter == EndPtr )  // If not found...
00204                 {
00205                   if (IsBB)
00206                     CreateWriteHashKey( BBId, RegNum, RegFileType );
00207                   else
00208                     CreateWriteHashKey( BBId, subblock, RegNum, RegFileType );
00209                   // Create information.
00210                   Info.Use = FALSE;
00211                   Info.Def = TRUE;
00212                   Info.LiveIn = FALSE;
00213                   Info.LiveOut = FALSE;
00214                   Info.Oprd = OprdPtr;
00215                   Table[ WriteHashKey ] = Info;  // write to hash table!
00216                   derr( "   ** Add to def set\n");
00217                 } // end if
00218               else
00219                 {
00220                   (*LookUpIter).second.Def = TRUE;  // turn on def in item
00221                   derr( "   ** Mod to def set\n");
00222                 } // end else
00223             } // end if (is a def)
00224         } // end if (oprd is reg or macro and is valid)
00225 
00226       // Advance to the next operand. If this is the last real destination
00227       // of a BRL, move to the return macro.
00228       if (OpPtr->GetOpcode() == BRL &&
00229           FindReturnMacro (OpPtr) != OprdPtr &&
00230           OprdPtr->GetNextOprdPtr() == NULL)
00231         OprdPtr = FindReturnMacro (OpPtr);  // go to return macro
00232       else
00233         OprdPtr = OprdPtr->GetNextOprdPtr();  // advance as usual
00234       
00235     } // end for
00236 
00237   derr( "<< BB_defs\n" );
00238 } // end LiveVar_nm::BB_defs
00239 
00240 
00241 /*
00242  * BB_uses
00243  *   OpPtr = op on which to work
00244  *   BBId = id of basic block where op resides
00245  *
00246  * Determines the uses for op OpPtr.
00247  */
00248 void LiveVar_nm::BB_uses( legoOp *OpPtr, int BBId )
00249 {
00250   legoOprd *OprdPtr, *WalkOprdPtr;
00251   legoOp *WalkOpPtr;
00252   SetInfo Info;
00253   SetInfoTable::iterator LookUpIter, EndPtr;
00254 
00255   int RegNum, RegFileType, OprdType, IsBB, NonUse;
00256 
00257 
00258   derr( ">> BB_uses: Op " << OpPtr->GetOpId() << "\n" );
00259 
00260   for (OprdPtr = OpPtr->GetSrcOprdPtr(); OprdPtr != NULL;
00261        OprdPtr = OprdPtr->GetNextOprdPtr() )  // loop through sources
00262     {
00263       if (!(OprdPtr->GetValid())) continue;
00264 
00265       OprdType = OprdPtr->GetOprdType();
00266       if ( OprdType == OT_REG || OprdType == OT_MACRO )  // reg or macro
00267         {
00268           RegNum = OprdPtr->GetOprdRegNum();
00269           RegFileType = OprdPtr->GetOprdFileType();
00270           if ( OprdType == OT_MACRO ) RegFileType = -1;  // pseudo-filetype
00271           derr( "   Src Register:  # " << RegNum << ", type: "
00272                 << RegFileType << "\n" );
00273 
00274           // It's not in the use set yet. Skip it if there's a def before it
00275           // in the block / subblock.
00276           NonUse = 0;
00277           for ( WalkOpPtr = OpPtr->GetPrevLink(); WalkOpPtr != NULL &&
00278                   WalkOpPtr->GetOutListPtr() == NULL;
00279                 WalkOpPtr = WalkOpPtr->GetPrevLink() )  // walk up from OpPtr
00280             {
00281               //              for ( WalkOprdPtr = FindFirstDef (WalkOpPtr);
00282               for ( WalkOprdPtr = WalkOpPtr->GetDestOprdPtr();
00283                     WalkOprdPtr != NULL;
00284                     WalkOprdPtr = WalkOprdPtr->GetNextOprdPtr() )  // defs...
00285                 {
00286                   if ( WalkOprdPtr->GetOprdType() != OprdType ) continue;
00287                   if ( WalkOprdPtr->GetOprdRegNum() != RegNum ) continue;
00288                   if ( OprdType != OT_MACRO &&
00289                        WalkOprdPtr->GetOprdFileType() != RegFileType )
00290                     continue;
00291 
00292                   // Found a match, so it's not a use.
00293                   derr( "   Found prior def at op " << WalkOpPtr->GetOpId()
00294                         << "\n" );
00295                   NonUse = 1;
00296                   break;
00297                 } // end for
00298               // For BRLs, try to match the return macro as well.
00299               if ( !NonUse && WalkOpPtr->GetOpcode() == BRL &&
00300                    OprdType == OT_MACRO )
00301                 {
00302                   WalkOprdPtr = FindReturnMacro( WalkOpPtr );
00303                   if ( WalkOprdPtr != NULL &&
00304                        WalkOprdPtr->GetOprdRegNum() == RegNum )  // enough
00305                     {
00306                       // Found a match, so it's not a use.
00307                       derr( "   Found prior def at op " << WalkOpPtr->GetOpId()
00308                             << "\n" );
00309                       NonUse = 1;
00310                     } // end if
00311                 } // end if
00312               
00313               if ( NonUse ) break;
00314             } // end for
00315           if ( NonUse ) continue;  // go to next source
00316 
00317           // Write to use set for op.
00318           IsBB = (((legoRegion *) OpPtr->GetParentBlockPtr())->GetRegionType()
00319                   == RT_BB);
00320           if (IsBB)
00321             CreateReadHashKey( BBId, RegNum, RegFileType );
00322           else
00323             CreateReadHashKey( BBId, subblock, RegNum, RegFileType );
00324 
00325           LookUpIter = Table.find( ReadHashKey );  // lookup item
00326           EndPtr = Table.end();
00327           if ( LookUpIter == EndPtr )  // If not found...
00328             {
00329               if (IsBB)
00330                 CreateWriteHashKey( BBId, RegNum, RegFileType );
00331               else
00332                 CreateWriteHashKey( BBId, subblock, RegNum, RegFileType );
00333               // Create information.
00334               Info.Use = TRUE;
00335               Info.Def = FALSE;
00336               Info.LiveIn = FALSE;
00337               Info.LiveOut = FALSE;
00338               Info.Oprd = OprdPtr;
00339               Table[ WriteHashKey ] = Info;  // write to hash table!
00340               derr( "   ** Add to use set\n");
00341             } // if
00342           else
00343             {
00344               (*LookUpIter).second.Use = TRUE;  // turn on use in item
00345               derr( "   ** Mod to use set\n");
00346             } // end else
00347         } // if
00348     } // end for
00349 
00350   derr( "<< BB_uses\n" );
00351 } // end LiveVar_nm::BB_uses
00352 
00353 // ==========================================================================
00354 
00355 // find_control_edge: return a ptr to the control edge between Parent & Child.
00356 //    Assumes that there exists at most 1 control edge between Parent & Child.
00357 /*
00358 static opEdges *find_control_edge( legoOp *ParentExit, legoRegion *Child )
00359 {
00360    legoRegion *Parent = (legoRegion *) ParentExit->GetParentBlockPtr();
00361    int OutEdgeId, InEdgeId;
00362    edgeList *OutEdges, *InEdges;
00363    opEdges *CurrentOutEdge, *CurrentInEdge;
00364 
00365 
00366    // Search through all of Parent's exit egdes until the one that
00367    // flows between Parent & Child is found
00368    for ( OutEdges = Parent->GetOutEdgesPtr(); OutEdges != NULL;
00369       OutEdges = OutEdges->GetNextListPtr() ) {
00370       if ( OutEdges->GetEdgePtr()->GetFromOpPtr() != ParentExit ) continue;
00371       OutEdgeId = OutEdges->GetEdgePtr()->GetEdgeId();
00372 
00373       for ( InEdges = Child->GetInEdgesPtr(); InEdges != NULL;
00374             InEdges = InEdges->GetNextListPtr() ) {
00375          InEdgeId = InEdges->GetEdgePtr()->GetEdgeId();
00376          if ( OutEdgeId == InEdgeId ) return InEdges->GetEdgePtr();
00377       }
00378     }
00379 
00380    return NULL;
00381 }
00382 */
00383 
00384 // print_attr: print the entire attr
00385 /*
00386 static void print_attr( attrs *Attr )
00387 {
00388    legoOprd *OprdPtr;
00389 
00390    derr( ">> print_attr\n" );
00391    for ( OprdPtr = Attr->GetAttrOprdPtr(); OprdPtr != NULL;
00392          OprdPtr = OprdPtr->GetNextOprdPtr() ) {
00393 
00394       int RegNum = OprdPtr->GetOprdRegNum(),
00395           RegFileType = OprdPtr->GetOprdFileType();
00396 
00397       if ( OprdPtr->GetOprdType() == OT_MACRO ) RegFileType = -1;
00398       cerr << "   RegFile " << RegFileType << ", RegNum " << RegNum << "\n";
00399    }
00400    derr( "<< print_attr\n" );
00401 }
00402 */
00403 
00404 /*
00405  * copy_operand
00406  *   Src = source operand
00407  *   Target = target operand
00408  *
00409  * Copies fields from Src to Target, assuming a register-type operand.
00410  * Does NOT copy next and prev pointers.
00411  */
00412 static void copy_operand( legoOprd *Src, legoOprd *Target )
00413 {
00414    Target->SetOprdType( Src->GetOprdType() );
00415    Target->SetValid( Src->GetValid() );
00416    Target->SetOprdRegType( Src->GetOprdRegType() );
00417    Target->SetOprdRegNum( Src->GetOprdRegNum() );
00418    Target->SetOprdDataType( Src->GetOprdDataType() );
00419    Target->SetOprdFileType( Src->GetOprdFileType() );
00420    Target->SetOprdRegStyle( Src->GetOprdRegStyle() );
00421    Target->SetIntValue( Src->GetOprdIntValue() );
00422 } // end copy_operand
00423 
00424 /*
00425  * add_to_existing_attr
00426  *   Attr = existing live attribute
00427  *   NewOprd = new operand to add to attribute
00428  *
00429  * Adds a copy of the operand NewOprd to attribute Attr. If a copy
00430  * already resides in Attr, no action is taken.
00431  */
00432 static void add_to_existing_attr( attrs *Attr, legoOprd *NewOprd )
00433 {
00434    legoOprd *OprdPtr, *ShadowPtr;
00435 #ifdef _LIVE_VAR_DEBUG_
00436    int RegNum, RegFileType;
00437 #endif
00438 
00439 
00440    derr( ">> add_to_existing_attr\t" << get_string_out_of_op(NewOprd) << " \n" );
00441 
00442    // Find the end of the Attr list.
00443 
00444    //   derr( "   Attr before addition\n" );
00445    //   print_attr( Attr );
00446    for ( OprdPtr = ShadowPtr = Attr->GetAttrOprdPtr(); OprdPtr != NULL;
00447          ShadowPtr = OprdPtr, OprdPtr = OprdPtr->GetNextOprdPtr() )
00448      {
00449        if ( OprdPtr->GetOprdType() == NewOprd->GetOprdType() &&
00450             OprdPtr->GetOprdRegNum() == NewOprd->GetOprdRegNum() &&
00451             OprdPtr->GetOprdFileType() == NewOprd->GetOprdFileType() )
00452          {
00453            //derr( "   already present in attribute " );
00454            //fprintf(stderr,"\t\tthis one:(%s).\n",get_string_out_of_op(OprdPtr)); 
00455            //derr( "<< add_to_existing_attr\n" ); 
00456            return;  // no change
00457          } // end if
00458      } // end for
00459 
00460    // At this point, OprdPtr should be NULL and ShadowPtr should point to
00461    // the last legoOprd in the list.
00462    if ( OprdPtr != NULL ) derr( "   ** OprdPtr not NULL!! **\n" );
00463 
00464 #ifdef _LIVE_VAR_DEBUG_
00465    RegFileType = NewOprd->GetOprdFileType();
00466    if ( NewOprd->GetOprdType() == OT_MACRO )
00467      RegFileType = -1;
00468    cerr << "   Oprd to be added: RegFile " << RegFileType << ", RegNum "
00469         << NewOprd->GetOprdRegNum() << "\n";
00470 
00471    RegFileType = ShadowPtr->GetOprdFileType();
00472    if ( ShadowPtr->GetOprdType() == OT_MACRO )
00473      RegFileType = -1;
00474    cerr << "   ShadowPtr values: RegFile " << RegFileType << ", RegNum "
00475         << ShadowPtr->GetOprdRegNum() << "\n";
00476 #endif
00477 
00478    OprdPtr = ShadowPtr->AddOprd();  // create new operand at end of list
00479 
00480    // Copy all legoOprd fields individually.
00481    copy_operand( NewOprd, OprdPtr );
00482 
00483 #ifdef _LIVE_VAR_DEBUG_
00484    RegFileType = OprdPtr->GetOprdFileType();
00485    if ( OprdPtr->GetOprdType() == OT_MACRO )
00486      RegFileType = -1;
00487    cerr << "   Newly created Oprd values: RegFile "
00488         << RegFileType << ", RegNum " << OprdPtr->GetOprdRegNum() << "\n";
00489 #endif
00490 
00491    //   derr( "   Attr after addition\n" );
00492    //   print_attr( Attr );
00493 
00494    derr( "<< add_to_existing_attr\n" );
00495    return;
00496 } // end add_to_existing_attr
00497 
00498 /*
00499  * create_new_attr
00500  *   Edge = edge on which to add live attribute
00501  *   Oprd = operand to add to attribute
00502  *   Proc = proc to whose dictionary to add edge
00503  *
00504  * Creates a new live attribute for Edge containing a copy of Oprd.
00505  */
00506 static void create_new_attr( opEdges *Edge, legoOprd *Oprd, legoProc *Proc )
00507 {
00508   legoOprd *NewOprd = new legoOprd();
00509 
00510   derr( ">> create_new_attr" << get_string_out_of_op(Oprd) << "\n" );
00511 
00512 #ifdef _LIVE_VAR_DEBUG_
00513   attrs* Attr;
00514   int RegFileType;
00515 
00516   RegFileType = Oprd->GetOprdFileType();
00517   if ( Oprd->GetOprdType() == OT_MACRO )
00518     RegFileType = -1;
00519   cerr << "   Oprd to be added: RegFile " << RegFileType << ", RegNum "
00520        << Oprd->GetOprdRegNum() << "\n";
00521 #endif
00522 
00523   // Copy all legoOprd fields individually.
00524   copy_operand( Oprd, NewOprd );
00525 
00526   // Add the attribute after creating a new operand copy.
00527   AddLiveAttribute( NewOprd, Edge, Proc );
00528 
00529 #ifdef _LIVE_VAR_DEBUG_
00530    //   print_attr( FindLiveAttribute( Edge ) );
00531 #endif
00532 
00533   derr( "<< create_new_attr\n" );
00534   return;
00535 } // end create_new_attr
00536 
00537 // ==========================================================================
00538 
00539 /*
00540  * BB_live_out
00541  *   ProcPtr = proc containing RegionPtr
00542  *   RegionPtr = region for which to create live-out set
00543  *
00544  * out[B] = U (S succ. B) in[S]
00545  *
00546  * Performs the iterative live-out computation.
00547  */
00548 void LiveVar_nm::BB_live_out( legoProc *ProcPtr, legoRegion *RegionPtr )
00549 {
00550   regionList    *ChildrenList;
00551   legoRegion    *ChildRegionPtr;
00552   legoOp        *ExitOp;
00553   opEdges       *ControlEdge;
00554   SetInfo       Info;
00555   SetInfoTable::iterator LookUpIter, LookUpIterLoop, EndPtr;
00556   attrs *Attr;
00557 
00558   int           i, BBId = RegionPtr->GetRegionId(), ChildBBId, DoingNextSubBlock,SkipIt; 
00559   char          temp, *tempstr;
00560   legoOprd      *NewOprd;
00561 
00562 
00563   derr(">> BB_live_out: iteration #" << IterCount << ", BBId " << BBId << " subblock " << subblock << "\n");
00564 
00565   // Find the relevant exit op from this block/subblock.
00566   if ( RegionPtr->GetRegionType() == RT_BB )
00567         ExitOp = RegionPtr->GetExitOpsPtr()->GetOpPtr();  // easy!
00568   else if ( IS_BLOCK(RegionPtr->GetRegionType()) ){ 
00569                 for ( i = 0, ExitOp = RegionPtr->GetEntryOpsPtr()->GetOpPtr();i < subblock; ExitOp = ExitOp->GetNextLink() ){  
00570                         if ( ExitOp->GetOutListPtr() != NULL ) i++;
00571                         if ( i == subblock ) break;  // count up to subblock
00572                 } // end for
00573         } // end else
00574   else{ 
00575         LegoNonFatal ("LiveVar_nm::BB_live_out", "Passed non-block.");
00576         return;
00577   } // end else
00578   derr(">> Exit op is op " << ExitOp->GetOpId() << "\n");
00579 
00580   // The next subblock after this one is also a successor. We'll do
00581   // that one last; right now we aren't doing it.
00582   // Larin: It is NEVR done!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00583   // 
00584   DoingNextSubBlock = 0;
00585 
00586   ChildrenList = (regionList *) RegionPtr->GetChildren();
00587 
00588   // Iterate down children of RegionPtr.
00589   // If ChildrenList is immediately NULL, there's no children except for
00590   // possibly the next subblock. Try accessing that.
00591   if (ChildrenList != NULL)     ChildRegionPtr = (legoRegion *) ChildrenList->GetRegionPtr(); 
00592   else{ 
00593         if ( RegionPtr->GetRegionType() != RT_BB ){ 
00594                 ChildRegionPtr          = RegionPtr;
00595                 DoingNextSubBlock       = 1;
00596         } // end if
00597         // Else else, we're done.
00598         else    ChildRegionPtr = NULL;
00599   } // end else
00600 
00601   while (ChildRegionPtr != NULL){ 
00602         //    if ( (ChildRegionPtr->GetRegionType()) == RT_BB ) 
00603         //    if ( IS_BLOCK(ChildRegionPtr->GetRegionType()) ) 
00604       ChildBBId = ChildRegionPtr->GetRegionId();
00605       derr("   >> BBId " << ChildBBId << " being processed (as subblock? " << DoingNextSubBlock << ")\n" );
00606 
00607       // Immediately find the control edge leading from the exit of
00608       // the current block/subblock to ChildRegionPtr. If it's not there,
00609       // and we're on a subblock, skip it; the edge must come from another
00610       // exit op. This is the edge that will have its attribute updated.
00611       SkipIt = 0;
00612       if ( !DoingNextSubBlock ){ 
00613                 ControlEdge = FindControlEdge (ExitOp, ChildRegionPtr->GetEntryOpsPtr()->GetOpPtr(), 1); 
00614                 if ( ControlEdge == NULL ){ 
00615                         //fprintf(stderr,"Set to skipp this edge...\n");        
00616                         if ( subblock == 0 )
00617                                 LegoNonFatal ("liveness", "Can't find control edge from op %d "  
00618                                                 "to region %d.", ExitOp->GetOpId(),
00619                                                 ChildRegionPtr->GetRegionId());
00620                         SkipIt = 1;
00621                 } // end if
00622       } // end if
00623 /* 
00624       else{
00625                 fprintf(stderr,"\tCan we look for an edge from (%d)to (%d) in case of subblock? (%x).\n",
00626                         ExitOp->GetOpId(),
00627                         ChildRegionPtr->GetEntryOpsPtr()->GetOpPtr()->GetOpId(),
00628                         FindControlEdge (ExitOp, ChildRegionPtr->GetEntryOpsPtr()->GetOpPtr(), 1)); 
00629                 // Larin 
00630                 // try to find relevant ENTRY Op to the SUBREGION! 
00631                 // 
00632                 if(ExitOp->GetNextLink()){
00633                         fprintf(stderr,"\tOn other hand, an edge from (%d) to (%d) still cannot be found but make more sence.\n",
00634                                 ExitOp->GetOpId(),
00635                                 ExitOp->GetNextLink()->GetOpId()); 
00636                 }  
00637       } 
00638 */ 
00639 
00640       // Do all entries that start with either:
00641       // <bbid>-     or
00642       // <bbid>/1-   or
00643       // <thisbbid>/<subblock+1>- if we're doing the next subblock
00644       if ( !DoingNextSubBlock ) {
00645                 sprintf( LBHashKey, "%d-", ChildBBId );  // look between this ...
00646                 sprintf( UBHashKey, "%d0", ChildBBId );  // ... and this!
00647       } // end if
00648       else {
00649                 //sprintf( LBHashKey, "%d/%d-", BBId, subblock + 1 );  // or this ...
00650                 //sprintf( UBHashKey, "%d/%d-", BBId, subblock + 2 );  // ... and this!
00651                 sprintf( LBHashKey, "%d/%d-", BBId, subblock+1);  // or this ...
00652                 sprintf( UBHashKey, "%d/%d0", BBId, subblock+1); 
00653       } // end else
00654 
00655 //              fprintf(stderr,"\tDefined LBHashKey (%s),UBHashKey(%s).\n",LBHashKey,UBHashKey); 
00656 /* 
00657         if(ChildBBId == 18){  
00658                 for( LookUpIter = Table.begin();LookUpIter != Table.end();LookUpIter++ ) {
00659                         derr( "Key : " );
00660                         cerr.width(12);
00661                         derr( (*LookUpIter).first );
00662                         derr( " -- Def: " << (*LookUpIter).second.Def << ", Use: "
00663                                 << (*LookUpIter).second.Use << ", LiveIn: "
00664                                 << (*LookUpIter).second.LiveIn << ", LiveOut: "
00665                                 << (*LookUpIter).second.LiveOut << "\n" );
00666                 }
00667         } 
00668         else{
00669                 for( LookUpIterLoop = Table.lower_bound(LBHashKey);
00670                         ((LookUpIterLoop != (Table.lower_bound(UBHashKey))) &&
00671                         (LookUpIterLoop != Table.end())) &&
00672                         !SkipIt;
00673                         LookUpIterLoop++){ 
00674 
00675                         derr( "Key : " );
00676                         cerr.width(12);
00677                         derr( (*LookUpIter).first );
00678                         derr( " -- Def: " << (*LookUpIter).second.Def << ", Use: "
00679                                 << (*LookUpIter).second.Use << ", LiveIn: "
00680                                 << (*LookUpIter).second.LiveIn << ", LiveOut: "
00681                                 << (*LookUpIter).second.LiveOut << "\n" ); 
00682                 } 
00683         } 
00684 */ 
00685 
00686       // Run through every hashtable entry that is in the range of keys
00687       // we're looking for.
00688       for( LookUpIterLoop = Table.lower_bound(LBHashKey);
00689            ((LookUpIterLoop != (Table.lower_bound(UBHashKey))) &&
00690             (LookUpIterLoop != Table.end())) &&
00691              !SkipIt;
00692            LookUpIterLoop++)
00693         {
00694 /* 
00695                 fprintf(stderr,"\tLooking at the entry: "); 
00696                 derr( (*LookUpIterLoop).first );
00697                 derr( " -- Def: " << (*LookUpIterLoop).second.Def << ", Use: "
00698                                 << (*LookUpIterLoop).second.Use << ", LiveIn: "
00699                                 << (*LookUpIterLoop).second.LiveIn << ", LiveOut: "
00700                                 << (*LookUpIterLoop).second.LiveOut << "\n" ); 
00701 */ 
00702 
00703           // Check that it's not from a subblock of a superblock
00704           // numbered 2 or later (i.e., it must be <bbid>/1-...).
00705           //tempstr = strstr ( (*LookUpIterLoop).first, "/");
00706           //if ( tempstr != NULL ) {
00707             // It's a superblock.
00708                 // Larin 
00709                 //fprintf(stderr,"\tthe tempstr (%s).\n",tempstr); 
00710                 //if ( tempstr [ 1 ] != '1' || tempstr [ 2 ] != '-' ) continue;
00711           //} // if
00712 
00713           if ((*LookUpIterLoop).second.LiveIn){ 
00714               // OK, we found something live-in. Let's keep a pointer to it.
00715               //fprintf(stderr,"\tFound live-in .\n"); 
00716               SetInfoTable::iterator TmpIter = LookUpIterLoop;
00717 
00718               // Check whether it's marked as live-out already from RegionPtr.
00719               // If not, do so, adding a table entry if needed.
00720               ReadHashKey       = (*LookUpIterLoop).first;
00721               ReadHashKey       = strchr(ReadHashKey, '-');  // pop off end
00722               if ( subblock == 0 )  // create new front
00723                         sprintf( ReadHashPart1, "%d", BBId );
00724               else
00725                         sprintf( ReadHashPart1, "%d/%d", BBId, subblock );
00726               ReadHashKey = strcat(ReadHashPart1,ReadHashKey);  // merge
00727 
00728               //fprintf(stderr,"\tMerge (%s).\n",ReadHashKey);  
00729 
00730               LookUpIter        = Table.find( ReadHashKey );
00731               EndPtr            = Table.end();
00732               if ( LookUpIter == EndPtr || (*LookUpIter).second.LiveOut != TRUE ){ 
00733                   // The value is live-in to the child block.
00734                   derr( "   Live-out (" << ReadHashKey << ") from region "
00735                         << RegionPtr->GetRegionId() << " to region "
00736                         << ChildRegionPtr->GetRegionId() << "\n" );
00737 
00738                   // Make a new table entry if needed.
00739                   if ( LookUpIter == EndPtr )
00740                     {
00741                       WriteHashKey = new char[HASH_KEY_SIZE];   
00742                       strcpy(WriteHashKey, ReadHashKey);
00743                       Info.Use = FALSE;
00744                       Info.Def = FALSE;
00745                       Info.LiveIn = FALSE;
00746                       Info.LiveOut = TRUE;
00747                       Info.Oprd = (*TmpIter).second.Oprd;
00748                       Table[ WriteHashKey ] = Info;
00749                       derr("   Table entry added\n");
00750                     } // end if
00751                   else
00752                     {
00753                       (*LookUpIter).second.LiveOut = TRUE;
00754                       derr("   HashKey " << ReadHashKey << " updated for LiveOut\n"); 
00755                     } // end else
00756 
00757                   //              ChangeBit = TRUE;  // a change occurred!
00758               } // end if
00759               //else    fprintf(stderr,"\tMissing...\n"); 
00760 
00761               // Set a pointer to the operand that is live-out.
00762               NewOprd = (*TmpIter).second.Oprd;
00763 
00764               //fprintf(stderr,"\tCreated new operand (%s).\n",get_string_out_of_op(NewOprd)); 
00765 
00766               // Possibly create a live attribute for this control edge.
00767               // First, see if a live-ness attr exists. If yes, add
00768               // this regid to the end. If no, create a new attr & add this
00769               // regid.
00770               // (This must be here, instead of above when a live-out is
00771               //  first discovered, so that if a value is live-out along
00772               //  multiple edges, each one gets its chance to have its
00773               //  live attribute updated.)
00774 
00775               // Also, we can create a hash table representation of the
00776               // edge information (EdgeInfo), as well or instead. That will
00777               // be made as a postpass.
00778               if ( !DoingNextSubBlock ){   // o/w, no edge to bother with
00779                   Attr = FindLiveAttribute( ControlEdge );
00780                   if ( Attr != NULL ) // exists
00781                     add_to_existing_attr( Attr, NewOprd );
00782                   else
00783                     create_new_attr( ControlEdge, NewOprd, ProcPtr );
00784                   derr( "   Edge " << ControlEdge->GetEdgeId() <<
00785                         " updated\n" );
00786               } // end if
00787 /* 
00788               else{     // Larin 
00789                   if(ControlEdge)       fprintf(stderr,"\tSuppose to add the new operand to the edge (%d).\n",ControlEdge->GetEdgeId());  
00790                   else                  fprintf(stderr,"\tThere is no edge to add new operand to.\n"); 
00791               } 
00792 */ 
00793           } // if LiveIn
00794         } // for (hashtable items in range)
00795       //     // if IS_BLOCK
00796 
00797       // Move to next child if we can.
00798       if ( ChildrenList != NULL )       ChildrenList = ChildrenList->GetNextListPtr(); 
00799 
00800       // If not at end of children list, set ChildRegionPtr.
00801       if ( ChildrenList != NULL )       ChildRegionPtr = (legoRegion *) ChildrenList->GetRegionPtr(); 
00802       // Else, if we haven't done the next subblock yet, set it up.
00803       else{ 
00804                 if ( !DoingNextSubBlock && RegionPtr->GetRegionType() != RT_BB ){ 
00805                         ChildRegionPtr  = RegionPtr;
00806                         DoingNextSubBlock = 1;
00807                 } // end if
00808                 // Else else, we're done.
00809                 else ChildRegionPtr     = NULL;
00810       } // end else
00811       //fprintf(stderr,"   << done with the block.\n"); 
00812   } // while
00813 
00814   derr("<< BB_live_out\n" );
00815   return;
00816 } // end LiveVar_nm::BB_live_out
00817 
00818 /*
00819  * BB_live_in
00820  *   ProcPtr = proc containing RegionPtr
00821  *   RegionPtr = region for which to create live-in set
00822  *
00823  * in[B] = use[B] U (out[B] - def[B])
00824  *
00825  * Performs the iterative live-in computation.
00826  */
00827 void LiveVar_nm::BB_live_in( legoProc *ProcPtr, legoRegion *RegionPtr )
00828 {
00829   SetInfoTable::iterator LookUpIter;  
00830   int BBId = RegionPtr->GetRegionId();
00831   bool Out_Not_Def, old_LiveIn;
00832 
00833   derr(">> BB_live_in: iteration #" << IterCount << ", BBId " << BBId << " subblock " << subblock << "\n");
00834 
00835   // Make up hash-key ranges for operands in the block/subblock.
00836   if ( subblock == 0 ) { // doing basic block
00837     sprintf( LBHashKey, "%d-", BBId );  
00838     sprintf( UBHashKey, "%d0", BBId );  
00839   } // end if
00840   else {
00841     sprintf( LBHashKey, "%d/%d-", BBId, subblock );
00842     sprintf( UBHashKey, "%d/%d-", BBId, subblock + 1 );
00843   } // end else
00844 
00845   // Iterate over each operand in the block/subblock.
00846   for( LookUpIter = Table.lower_bound(LBHashKey);
00847        //       ((LookUpIter != Table.upper_bound(UBHashKey)) &&
00848        ((LookUpIter != Table.lower_bound(UBHashKey)) &&
00849         (LookUpIter != Table.end()));
00850        LookUpIter++){ 
00851       // First find whether it's live-out of this block/subblock but
00852       // not defined here.
00853         //fprintf(stderr,"Iterating through each oprd of the subblock .\n"); 
00854         if( ((*LookUpIter).second.LiveOut == TRUE) && ((*LookUpIter).second.Def == FALSE) ) 
00855                 Out_Not_Def     = TRUE;
00856         else    Out_Not_Def     = FALSE;
00857 
00858       // Now, perform the iteration and check for a change.
00859         old_LiveIn = (*LookUpIter).second.LiveIn;
00860         (*LookUpIter).second.LiveIn     = ((*LookUpIter).second.Use || Out_Not_Def); 
00861         if ((*LookUpIter).second.LiveIn != old_LiveIn){ 
00862                 ChangeBit = TRUE;
00863                 derr("   HashKey " << (*LookUpIter).first << " updated for LiveIn\n"); 
00864         } // end if
00865       //      if ( (*LookUpIter).second.LiveIn != ((*LookUpIter).second.Use ||
00866       //                                         Out_Not_Def) )
00867       //        {
00868       //          (*LookUpIter).second.LiveIn =
00869       //            ((*LookUpIter).second.Use || Out_Not_Def);
00870       //          ChangeBit = TRUE;
00871       //          derr("   HashKey " << (*LookUpIter).first <<
00872       //               " updated for LiveIn\n");
00873       //        } // end if
00874   } // end for
00875   
00876   derr("<< BB_live_in\n" );
00877   return;
00878 } // end LiveVar_nm::BB_live_in
00879 
00880 // ==========================================================================
00881 
00882 /*
00883  * Process
00884  *   RegionPtr = region for which to compute liveness
00885  *   ProcPtr = proc containing RegionPtr
00886  *
00887  * Computes the live-out and live-in sets for RegionPtr if it is a
00888  * block, or for the regions within RegionPtr otherwise. This function
00889  * represents one iteration of the overall iterative algorithm, with
00890  * an implicit hierarchical ordering (not necessarily the fastest).
00891  */
00892 void LiveVar_nm::Process ( legoRegion *RegionPtr, legoProc *ProcPtr )
00893 {
00894   int BBId, RegionCount, NumSubRegions;
00895 
00896   if(IS_BLOCK (RegionPtr->GetRegionType())){ 
00897         BBId    = RegionPtr->GetRegionId();
00898         derr( "BB with BBId: " << BBId << "\n");
00899 
00900         // Count the number of subregions (subblocks) if RegionPtr is a
00901         // superblock (or hyperblock).
00902         NumSubRegions = 0;
00903         if(RegionPtr->GetRegionType() != RT_BB){ 
00904                 legoOp *op;
00905 
00906                 for(op= RegionPtr->GetEntryOpsPtr()->GetOpPtr();op!=NULL;op=op->GetNextLink()) 
00907                         if(op->GetOutListPtr())         NumSubRegions++;
00908                 derr(">> Contains " << NumSubRegions << " subblocks.\n");
00909         } // end if
00910         // Loop over each subblock, from the bottom up, for superblocks;
00911         // just do the basic block otherwise.
00912         if(RegionPtr->GetRegionType()==RT_BB){ 
00913                 subblock = 0;
00914                 BB_live_out( ProcPtr, RegionPtr );
00915                 BB_live_in( ProcPtr, RegionPtr );
00916         } // end if
00917         else for(subblock = NumSubRegions; subblock>0;subblock--){      // Larin >0;  
00918                 //fprintf(stderr,"\tHere processing subblock (%d).\n",subblock); 
00919                 BB_live_out( ProcPtr, RegionPtr );
00920                 BB_live_in( ProcPtr, RegionPtr );
00921         } // end else
00922   } // end if
00923   else{ 
00924         RegionCount     = RegionPtr->GetCount();
00925         for (int i=0;i<RegionCount;i++)
00926                 Process ( (legoRegion *) RegionPtr->GetItem ( i ), ProcPtr );
00927   } // end else
00928 
00929   return;
00930 } // end LiveVar_nm::Process
00931 
00932 /*
00933  * analyze
00934  *   RegionPtr = region on which to work (must not be op-holding)
00935  *   ProcPtr = proc containing region
00936  *
00937  * Perform liveness analysis on RegionPtr. If RegionPtr is a block,
00938  * finds defs and uses, then quits. If RegionPtr is not a block but
00939  * not a proc, finds defs and uses of its subregions, then quits.
00940  * If RegionPtr is a proc, finds defs and uses of its subregions,
00941  * then cranks the iterative algorithm.
00942  */
00943 // analyze: perform live-out analysis on ProcPtr
00944 void LiveVar_nm::analyze( legoRegion *RegionPtr, legoProc *ProcPtr )
00945 {
00946   legoRegion *SubRegionPtr;
00947   legoOp *OpPtr;
00948 #ifdef _LIVE_VAR_DEBUG_
00949   SetInfoTable::iterator LookUpIter;
00950 #endif
00951   
00952   int j, k, RegionCount, OpCount, BBId;
00953 
00954   // Initialize a few things if we are just starting.
00955   if ( RegionPtr->GetRegionType() == RT_PROC )
00956     {
00957       //      Table.map();
00958       // wah 3/24/98
00959       Table = SetInfoTable();
00960       ReadHashKey = new char[ HASH_KEY_SIZE ];
00961       ReadHashPart1 = new char[ HASH_PART_SIZE ];
00962       ReadHashPart2 = new char[ HASH_PART_SIZE ];
00963       ReadHashPart3 = new char[ HASH_PART_SIZE ];
00964       LBHashKey = new char[ HASH_KEY_SIZE ];
00965       UBHashKey = new char[ HASH_KEY_SIZE ];
00966       delete EdgeInfo;
00967     } // end if
00968 
00969   RegionCount = RegionPtr->GetCount();
00970   if ( RegionPtr == (legoRegion *) ProcPtr )
00971     derr( RegionCount << " Region(s) in Proc " << ProcPtr->GetProcName()
00972           << "\n");
00973 
00974   // Go over each subregion of the region.
00975   for ( j = 0; j < RegionCount; j++)
00976     {
00977       SubRegionPtr = (legoRegion *) RegionPtr->GetItem( j ); 
00978 
00979       // If it's a block, do defs and uses for its ops.
00980       if ( IS_BLOCK (SubRegionPtr->GetRegionType()) )
00981         {
00982           BBId = SubRegionPtr->GetRegionId();
00983           derr( "BB number " << (j + 1) << ", BBId: " << BBId << "\n");
00984 
00985           OpCount = SubRegionPtr->GetCount();
00986           derr( OpCount << " Op(s) in BB number " << (j + 1) << "\n");
00987           subblock = 1;  // on first subblock
00988 
00989           // Do defs and uses for each op in the block.
00990           for ( k = 0; k < OpCount; k++)
00991             {
00992               OpPtr = (legoOp *) SubRegionPtr->GetItem( k );
00993               derr( "Op number " << (k + 1) << ", OpId: " << OpPtr->GetOpId()
00994                     << "\n");
00995               BB_uses(OpPtr, BBId);
00996               BB_defs(OpPtr, BBId);
00997               // Increment subblock if just saw branch.
00998               // Larin 
00999               if (OpPtr->GetOutListPtr() != NULL){
01000                 //fprintf(stderr,"\tDetected Subblock.\n");     
01001                 subblock++;
01002               } 
01003             } // end for
01004         } // end if
01005       else
01006         {
01007           // Do defs and uses for all the subregions.
01008           //fprintf(stderr,"\tThis is subregion.\n"); 
01009           analyze ( SubRegionPtr, ProcPtr );
01010         } // end else
01011     } // end for
01012 
01013   if ( RegionPtr != (legoRegion *) ProcPtr)
01014     return;  // only proceed if whole proc is done
01015   derr( "** Defs/uses complete **\n" );
01016 
01017   // Here, we know we're on a proc. Set up for cranking the iteration.
01018   ChangeBit = TRUE;
01019   IterCount = 1;
01020   while (ChangeBit == TRUE)
01021     {
01022       ChangeBit = FALSE;
01023       for ( j = 0; j < RegionCount; j++)
01024         {
01025           SubRegionPtr = (legoRegion *) RegionPtr->GetItem( j );
01026           Process ( SubRegionPtr, ProcPtr );
01027         } // end for
01028       IterCount++;
01029     } // end while
01030 
01031   // We're done.
01032 #ifdef _LIVE_VAR_DEBUG_
01033   for( LookUpIter = Table.begin();LookUpIter != Table.end();LookUpIter++ ) {
01034     derr( "Key : " );
01035     cerr.width(12);
01036     derr( (*LookUpIter).first );
01037     derr( " -- Def: " << (*LookUpIter).second.Def << ", Use: "
01038           << (*LookUpIter).second.Use << ", LiveIn: "
01039           << (*LookUpIter).second.LiveIn << ", LiveOut: "
01040           << (*LookUpIter).second.LiveOut << "\n" );
01041   }
01042 #endif
01043   if ( CreateTable )
01044     CollectEdgeInfo ( ProcPtr );
01045 
01046   delete [] ReadHashKey;
01047   delete [] ReadHashPart1;
01048   delete [] ReadHashPart2;
01049   delete [] ReadHashPart3;
01050   //  delete [] WriteHashKey;
01051   //  delete [] WriteHashPart1;
01052   //  delete [] WriteHashPart2;
01053   //  delete [] WriteHashPart3;
01054   delete [] LBHashKey;
01055   delete [] UBHashKey;
01056   Table.erase( Table.begin(), Table.end() );
01057   Table.~map();
01058 
01059   return;
01060 } // end LiveVar_nm::analyze
01061 
01062 /*
01063  * analyze
01064  *   modulePtr = legoModule to analyze
01065  *
01066  * Performs live analysis on an entire legoModule.
01067  */
01068 void LiveVar_nm::analyze( legoModule *modulePtr )
01069 { 
01070   legoProc *ProcPtr;
01071   int i, ProcCount;
01072   
01073   ProcCount = modulePtr->GetCount();
01074   derr( ProcCount << " Proc(s) in legoModule\n");
01075 
01076   for ( i = 0; i < ProcCount; i++ )
01077     analyze( ( legoProc *)  modulePtr->GetItem( i ),
01078              ( legoProc *)  modulePtr->GetItem( i ));
01079 }
01080 
01081 // deleteedgeinfo: remove list of operands for given edge (if 0, all!)
01082 void LiveVar_nm::deleteedgeinfo ( int edgeid )
01083 {
01084   if ( EdgeInfo == NULL ) return;
01085   if ( edgeid != 0 ) {
01086     //    oprdl = EdgeInfo->Lookup ( edgeid );
01087     //    if ( ! (EdgeInfo->NotFound()) ) delete oprdl;
01088     EdgeInfo->Delete ( edgeid );
01089     return;
01090   }
01091 
01092   //  for ( EdgeInfo->Start(); ! (EdgeInfo->AtEnd()); EdgeInfo->Next() ) {
01093     //    oprdl = EdgeInfo->LookupCurrent();
01094     //    if ( ! (EdgeInfo->NotFound()) ) delete oprdl;
01095   //  }
01096   EdgeInfo->DeleteAll();
01097   return;
01098 }
01099 
01100 /*
01101  * CollectEdgeInfo
01102  *   ProcPtr = procedure for which to collect information
01103  *
01104  * Creates a hashtable representation of the live attribute information
01105  * found in ProcPtr.
01106  */
01107 void LiveVar_nm::CollectEdgeInfo ( legoProc *ProcPtr )
01108 {
01109   opEdges *edge;
01110   attrs *liveattr;
01111   //  oprdList *liveoprds, *oprdl;
01112   legoOprd *oprd;
01113 
01114   if ( !CreateTable ) return;
01115 
01116   if ( EdgeInfo == NULL )
01117     EdgeInfo = new legoHash <int, legoOprd *, legoHash_lt_int>;
01118   else
01119     deleteedgeinfo (0);
01120 
01121   for ( edge = ProcPtr->GetEdgeDictionary(); edge != NULL;
01122         edge = edge->GetNextOpEdgePtr() ) {
01123     liveattr = FindLiveAttribute (edge);
01124     if ( liveattr == NULL ) continue;
01125 
01126     //    liveoprds = oprdl = NULL;
01127     //    for ( oprd = liveattr->GetAttrOprdPtr(); oprd != NULL;
01128     //    oprd = oprd->GetNextOprdPtr() ) {
01129     //      if ( oprdl != NULL ) {
01130     //  oprdl->SetNextListPtr ( new oprdList );
01131     //  oprdl = oprdl->GetNextListPtr();
01132     //      }
01133     //      else {
01134     //  liveoprds = oprdl = new oprdList;
01135     //      }
01136     //
01137     //      oprdl->SetOprdPtr ( oprd );
01138     //    }
01139 
01140     oprd = liveattr->GetAttrOprdPtr();
01141     //    if ( liveoprds != NULL )
01142     if ( oprd != NULL )
01143       EdgeInfo->Set ( edge->GetEdgeId(), oprd );
01144   }
01145 
01146   return;
01147 } // end CollectEdgeInfo
01148 
01149 
01150 /*
01151  * LiveVariables
01152  *   proc = procedure to analyze
01153  *   maketable = whether to create hashtable of info for return
01154  *   returns: hashtable of liveness information
01155  *
01156  * Performs live variable analysis on procedure proc. The information is
01157  * stored in live attributes directly in the IR, and also returned in
01158  * tabular form.
01159  */
01160 legoHash <int, legoOprd *, legoHash_lt_int> *
01161 LiveVariables_not_mine (legoProc *proc, int maketable = 0)
01162 {
01163   legoHash <int, legoOprd *, legoHash_lt_int> *LiveInfo;
01164   LiveVar_nm *live = new LiveVar_nm;
01165   if (maketable) live->SetCreateTable (TRUE);
01166   else live->SetCreateTable (FALSE);
01167 
01168   live->analyze (proc, proc);
01169 
01170   LiveInfo = live->GetEdgeInfo();
01171   live->SetEdgeInfo ( NULL );
01172   delete live;
01173   return LiveInfo;
01174 } // end LiveVariables
01175 
01176 
01177 
01178 

Generated on Mon Jul 21 20:29:26 2003 for TINKER LEGO DOC by doxygen 1.3.2