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

live.C

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 // 11/20/98 MDJ: Fixed memory leak associated with WriteHashKeys. Need to 
00010 //               delete the WriteHashKeys we allocated before erasing HashTable
00011 // 12/16/98 MDJ: Fixed BB_uses to inlcude BRL MACRO sources used for parameter 
00012 //               passing.
00013 // Mon Jul 20 12:35:19 EDT 1998 Larin:  Changed the BB_live_out. (HB bug)  
00014 
00015 #include <string.h>
00016 #include <iostream.h>
00017 #include <stl.h> 
00018 #include "lego.H"
00019 #include "legoUtil.H"
00020 // #include "rdef.H"
00021 #include "live.H"
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 object.
00040  */
00041 inline void LiveVar::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 object.
00060  */
00061 inline void LiveVar::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 object.
00081  */
00082 inline void LiveVar::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 object.
00105  */
00106 inline void LiveVar::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 
00133 /********************************************
00134 In the case of the predicate associated 
00135 with the register, we can take conservative 
00136 approach by saying that predicate guarded regs
00137 will always use instr. but not kill or define 
00138 the regs : Sau
00139 This step is also taken in "CompleteLiveness"
00140 *********************************************/
00141 void LiveVar::BB_defs( legoOp *OpPtr, int BBId )
00142 {
00143   legoOprd *OprdPtr, *WalkOprdPtr;
00144   legoOp *WalkOpPtr;
00145   SetInfo Info;
00146   SetInfoTable::iterator LookUpIter, EndPtr;
00147 
00148   int RegNum, RegFileType, OprdType, IsBB, NonDef;
00149 
00150 
00151   derr( ">> BB_defs: Op " << OpPtr->GetOpId() << "\n" );
00152 
00153   if(OpPtr->GetPredOprdPtr() != NULL &&
00154         OpPtr->GetPredOprdPtr()->GetOprdType() == OT_REG &&
00155         OpPtr->GetPredOprdPtr()->GetOprdFileType() == FT_PR &&
00156         OpPtr->GetPredOprdPtr()->GetOprdRegNum() != 0)
00157         return;
00158   OprdPtr = OpPtr->GetDestOprdPtr();
00159   while (OprdPtr != NULL)
00160     {
00161       //      if (!(OprdPtr->GetValid())) continue;
00162 
00163       OprdType = OprdPtr->GetOprdType();
00164       if ( OprdType == OT_REG || OprdType == OT_MACRO &&  // reg or macro
00165            OprdPtr->GetValid())  // ... and a valid operand
00166         {
00167           RegNum = OprdPtr->GetOprdRegNum();
00168           RegFileType = OprdPtr->GetOprdFileType();
00169           if ( OprdType == OT_MACRO ) RegFileType = -1;  // pseudo-filetype
00170 
00171           derr( "   Dest Reg: # " << RegNum << ", type: " << RegFileType
00172                 << "\n" );
00173 
00174           // It's not in the def set yet. Skip it if there's a use before it
00175           // in the block / subblock.
00176           NonDef = 0;
00177           for ( WalkOpPtr = OpPtr->GetPrevLink(); WalkOpPtr != NULL &&
00178                   WalkOpPtr->GetOutListPtr() == NULL;
00179                 WalkOpPtr = WalkOpPtr->GetPrevLink() )  // walk up from OpPtr
00180             {
00181               for ( WalkOprdPtr = WalkOpPtr->GetSrcOprdPtr();
00182                     WalkOprdPtr != NULL;
00183                     WalkOprdPtr = WalkOprdPtr->GetNextOprdPtr() )  // srcs...
00184                 {
00185                   if ( WalkOprdPtr->GetOprdType() != OprdType ) continue;
00186                   if ( WalkOprdPtr->GetOprdRegNum() != RegNum ) continue;
00187                   if ( OprdType != OT_MACRO &&
00188                        WalkOprdPtr->GetOprdFileType() != RegFileType )
00189                     continue;
00190 
00191                   // Found a match, so it's not a def.
00192                   derr( "   Found prior use at op " << WalkOpPtr->GetOpId()
00193                         << "\n" );
00194                   NonDef = 1;
00195                   break;
00196                 } // end for
00197               if ( NonDef ) break;
00198             } // for
00199           
00200           // Also check predicate registers if filetype is FT_PR
00201           if ((NonDef == 0) && (OprdPtr->GetOprdFileType() == FT_PR)) {
00202             for ( WalkOpPtr = OpPtr->GetPrevLink(); WalkOpPtr != NULL &&
00203                  WalkOpPtr->GetOutListPtr() == NULL;
00204                  WalkOpPtr = WalkOpPtr->GetPrevLink() )  // walk up from OpPtr
00205               {
00206                 for ( WalkOprdPtr = WalkOpPtr->GetPredOprdPtr();
00207                      WalkOprdPtr != NULL;
00208                      WalkOprdPtr = WalkOprdPtr->GetNextOprdPtr() )  // srcs...
00209                   {
00210                     if ( WalkOprdPtr->GetOprdType() != OprdType ) continue;
00211                     if ( WalkOprdPtr->GetOprdRegNum() != RegNum ) continue;
00212                     if ( OprdType != OT_MACRO &&
00213                         WalkOprdPtr->GetOprdFileType() != RegFileType )
00214                       continue;
00215                     
00216                     // Found a match, so it's not a def.
00217                     derr( "   Found prior use at op " << WalkOpPtr->GetOpId()
00218                          << "\n" );
00219                     NonDef = 1;
00220                     break;
00221                   } // end for
00222                 if ( NonDef ) break;
00223               } // for
00224           }
00225 
00226           // If this is a def (i.e., not a NonDef), write to def set for
00227           // op.
00228           //      if ( NonDef ) continue;  // go to next destination
00229           if ( !NonDef )
00230             {
00231               // Write to def set for op.
00232               IsBB = (((legoRegion *) OpPtr->GetParentBlockPtr())->
00233                       GetRegionType() == RT_BB);
00234               if (IsBB)
00235                 CreateReadHashKey( BBId, RegNum, RegFileType );
00236               else
00237                 CreateReadHashKey( BBId, subblock, RegNum, RegFileType );
00238 
00239               LookUpIter = Table.find( ReadHashKey );  // lookup item
00240               EndPtr = Table.end();
00241               if ( LookUpIter == EndPtr )  // If not found...
00242                 {
00243                   if (IsBB)
00244                     CreateWriteHashKey( BBId, RegNum, RegFileType );
00245                   else
00246                     CreateWriteHashKey( BBId, subblock, RegNum, RegFileType );
00247                   // Create information.
00248                   Info.Use = FALSE;
00249                   Info.Def = TRUE;
00250                   Info.LiveIn = FALSE;
00251                   Info.LiveOut = FALSE;
00252                   Info.Oprd = OprdPtr;
00253                   Table[ WriteHashKey ] = Info;  // write to hash table!
00254                   derr( "   ** Add to def set\n");
00255                 } // end if
00256               else
00257                 {
00258                   (*LookUpIter).second.Def = TRUE;  // turn on def in item
00259                   derr( "   ** Mod to def set\n");
00260                 } // end else
00261             } // end if (is a def)
00262         } // end if (oprd is reg or macro and is valid)
00263 
00264       // Advance to the next operand. If this is the last real destination
00265       // of a BRL, move to the return macro.
00266       if (OpPtr->IsBRLOp() &&
00267           FindReturnMacro (OpPtr) != OprdPtr &&
00268           OprdPtr->GetNextOprdPtr() == NULL)
00269         OprdPtr = FindReturnMacro (OpPtr);  // go to return macro
00270       else
00271         OprdPtr = OprdPtr->GetNextOprdPtr();  // advance as usual
00272       
00273     } // end for
00274 
00275   derr( "<< BB_defs\n" );
00276 } // end LiveVar::BB_defs
00277 
00278 
00279 /*
00280  * BB_uses
00281  *   OpPtr = op on which to work
00282  *   BBId = id of basic block where op resides
00283  *
00284  * Determines the uses for op OpPtr.
00285  */
00286 void LiveVar::BB_uses( legoOp *OpPtr, int BBId )
00287 {
00288   legoOprd *OprdPtr, *WalkOprdPtr;
00289   legoOp *WalkOpPtr;
00290   SetInfo Info;
00291   SetInfoTable::iterator LookUpIter, EndPtr;
00292   attrs *a;
00293 
00294   int RegNum, RegFileType, OprdType, IsBB, NonUse;
00295 
00296 
00297   derr( ">> BB_uses: Op " << OpPtr->GetOpId() << "\n" );
00298 
00299   for (OprdPtr = OpPtr->GetSrcOprdPtr(); OprdPtr != NULL;
00300        OprdPtr = OprdPtr->GetNextOprdPtr() )  // loop through sources
00301     {
00302       if (!(OprdPtr->GetValid())) continue;
00303 
00304       OprdType = OprdPtr->GetOprdType();
00305       if ( OprdType == OT_REG || OprdType == OT_MACRO )  // reg or macro
00306         {
00307           RegNum = OprdPtr->GetOprdRegNum();
00308           RegFileType = OprdPtr->GetOprdFileType();
00309           if ( OprdType == OT_MACRO ) RegFileType = -1;  // pseudo-filetype
00310           derr( "   Src Register:  # " << RegNum << ", type: "
00311                 << RegFileType << "\n" );
00312 
00313           // It's not in the use set yet. Skip it if there's a def before it
00314           // in the block / subblock.
00315           NonUse = 0;
00316           for ( WalkOpPtr = OpPtr->GetPrevLink(); WalkOpPtr != NULL &&
00317                   WalkOpPtr->GetOutListPtr() == NULL;
00318                 WalkOpPtr = WalkOpPtr->GetPrevLink() )  // walk up from OpPtr
00319             {
00320               //              for ( WalkOprdPtr = FindFirstDef (WalkOpPtr);
00321               for ( WalkOprdPtr = WalkOpPtr->GetDestOprdPtr();
00322                     WalkOprdPtr != NULL;
00323                     WalkOprdPtr = WalkOprdPtr->GetNextOprdPtr() )  // defs...
00324                 {
00325                   if ( WalkOprdPtr->GetOprdType() != OprdType ) continue;
00326                   if ( WalkOprdPtr->GetOprdRegNum() != RegNum ) continue;
00327                   if ( OprdType != OT_MACRO &&
00328                        WalkOprdPtr->GetOprdFileType() != RegFileType )
00329                     continue;
00330                   /**************************************
00331                   Check if the walkOpPtr has a predicate
00332                   associated with it, if yes don't
00333                   treat the oprd as a non-use. Rathter
00334                   we should take a conservative approach
00335                   and say it as a "use" : Sau
00336                   ***************************************/
00337                   if(WalkOpPtr->GetPredOprdPtr() != NULL &&
00338                    WalkOpPtr->GetPredOprdPtr()->GetOprdType() == OT_REG &&
00339                    WalkOpPtr->GetPredOprdPtr()->GetOprdFileType() == FT_PR &&
00340                    WalkOpPtr->GetPredOprdPtr()->GetOprdRegNum() != 0)
00341                    continue;
00342                    
00343                    
00344                   // Found a match, so it's not a use.
00345                   derr( "   Found prior def at op " << WalkOpPtr->GetOpId()
00346                         << "\n" );
00347                   NonUse = 1;
00348                   break;
00349                 } // end for
00350               // For BRLs, try to match the return macro as well.
00351               if ( !NonUse && WalkOpPtr->IsBRLOp() &&
00352                    OprdType == OT_MACRO )
00353                 {
00354                   WalkOprdPtr = FindReturnMacro( WalkOpPtr );
00355                   if ( WalkOprdPtr != NULL &&
00356                        WalkOprdPtr->GetOprdRegNum() == RegNum )  // enough
00357                     {
00358                       // Found a match, so it's not a use.
00359                       derr( "   Found prior def at op " << WalkOpPtr->GetOpId()
00360                             << "\n" );
00361                       NonUse = 1;
00362                     } // end if
00363                 } // end if
00364               
00365               if ( NonUse ) break;
00366             } // end for
00367           if ( NonUse ) continue;  // go to next source
00368 
00369           // Write to use set for op.
00370           IsBB = (((legoRegion *) OpPtr->GetParentBlockPtr())->GetRegionType()
00371                   == RT_BB);
00372           if (IsBB)
00373             CreateReadHashKey( BBId, RegNum, RegFileType );
00374           else
00375             CreateReadHashKey( BBId, subblock, RegNum, RegFileType );
00376 
00377           LookUpIter = Table.find( ReadHashKey );  // lookup item
00378           EndPtr = Table.end();
00379           if ( LookUpIter == EndPtr )  // If not found...
00380             {
00381               if (IsBB)
00382                 CreateWriteHashKey( BBId, RegNum, RegFileType );
00383               else
00384                 CreateWriteHashKey( BBId, subblock, RegNum, RegFileType );
00385               // Create information.
00386               Info.Use = TRUE;
00387               Info.Def = FALSE;
00388               Info.LiveIn = FALSE;
00389               Info.LiveOut = FALSE;
00390               Info.Oprd = OprdPtr;
00391               Table[ WriteHashKey ] = Info;  // write to hash table!
00392               derr( "   ** Add to use set\n");
00393             } // if
00394           else
00395             {
00396               (*LookUpIter).second.Use = TRUE;  // turn on use in item
00397               derr( "   ** Mod to use set\n");
00398             } // end else
00399         } // if
00400     } // end for
00401 
00402   // mdj - 8/11/99: Don't forget about Predicate Sources
00403   for (OprdPtr = OpPtr->GetPredOprdPtr(); OprdPtr != NULL;
00404        OprdPtr = OprdPtr->GetNextOprdPtr() )  // loop through pred sources
00405     {
00406       if (!(OprdPtr->GetValid())) continue;
00407 
00408       OprdType = OprdPtr->GetOprdType();
00409       if ( OprdType == OT_REG || OprdType == OT_MACRO )  // reg or macro
00410         {
00411           RegNum = OprdPtr->GetOprdRegNum();
00412           RegFileType = OprdPtr->GetOprdFileType();
00413           if ( OprdType == OT_MACRO ) RegFileType = -1;  // pseudo-filetype
00414           derr( "   Src Register:  # " << RegNum << ", type: "
00415                 << RegFileType << "\n" );
00416 
00417           // It's not in the use set yet. Skip it if there's a def before it
00418           // in the block / subblock.
00419           NonUse = 0;
00420           for ( WalkOpPtr = OpPtr->GetPrevLink(); WalkOpPtr != NULL &&
00421                   WalkOpPtr->GetOutListPtr() == NULL;
00422                 WalkOpPtr = WalkOpPtr->GetPrevLink() )  // walk up from OpPtr
00423             {
00424               //              for ( WalkOprdPtr = FindFirstDef (WalkOpPtr);
00425               for ( WalkOprdPtr = WalkOpPtr->GetDestOprdPtr();
00426                     WalkOprdPtr != NULL;
00427                     WalkOprdPtr = WalkOprdPtr->GetNextOprdPtr() )  // defs...
00428                 {
00429                   if ( WalkOprdPtr->GetOprdType() != OprdType ) continue;
00430                   if ( WalkOprdPtr->GetOprdRegNum() != RegNum ) continue;
00431                   if ( OprdType != OT_MACRO &&
00432                        WalkOprdPtr->GetOprdFileType() != RegFileType )
00433                     continue;
00434 
00435                   // Found a match, so it's not a use.
00436                   derr( "   Found prior def at op " << WalkOpPtr->GetOpId()
00437                         << "\n" );
00438                   NonUse = 1;
00439                   break;
00440                 } // end for
00441               
00442               if ( NonUse ) break;
00443             } // end for
00444           if ( NonUse ) continue;  // go to next source
00445 
00446           // Write to use set for op.
00447           IsBB = (((legoRegion *) OpPtr->GetParentBlockPtr())->GetRegionType()
00448                   == RT_BB);
00449           if (IsBB)
00450             CreateReadHashKey( BBId, RegNum, RegFileType );
00451           else
00452             CreateReadHashKey( BBId, subblock, RegNum, RegFileType );
00453 
00454           LookUpIter = Table.find( ReadHashKey );  // lookup item
00455           EndPtr = Table.end();
00456           if ( LookUpIter == EndPtr )  // If not found...
00457             {
00458               if (IsBB)
00459                 CreateWriteHashKey( BBId, RegNum, RegFileType );
00460               else
00461                 CreateWriteHashKey( BBId, subblock, RegNum, RegFileType );
00462               // Create information.
00463               Info.Use = TRUE;
00464               Info.Def = FALSE;
00465               Info.LiveIn = FALSE;
00466               Info.LiveOut = FALSE;
00467               Info.Oprd = OprdPtr;
00468               Table[ WriteHashKey ] = Info;  // write to hash table!
00469               derr( "   ** Add to use set\n");
00470             } // if
00471           else
00472             {
00473               (*LookUpIter).second.Use = TRUE;  // turn on use in item
00474               derr( "   ** Mod to use set\n");
00475             } // end else
00476         } // if
00477     } // end for
00478 
00479   // mdj - 12/16/98
00480   // Bill didn't understand BRL parameter sources at the time. 
00481   // Need to include these now
00482   // mdj - 3/29/98 
00483   // We need to assume that BRLs use INT_P*'s, FLT_P*'s, DBL_P*'s because 
00484   // recursive subroutine calls may use more parameters than the original call 
00485   /*
00486   if ( OpPtr->GetOpcode() == BRL ) {
00487 //    for (int regid = INT_P1; regid <= INT_P4; regid++) {
00488     for (int regid = INT_P1; regid <= DBL_P2; regid++) {
00489       // create new operands for these, they may not all exist at this time
00490 
00491       OprdType = OT_MACRO;
00492       RegNum = regid;
00493       // this one is always a MACRO
00494       RegFileType = -1;  // pseudo-filetype
00495       derr( "   Src Register:  # " << RegNum << ", type: "
00496            << RegFileType << "\n" );
00497       
00498       // It's not in the use set yet. Skip it if there's a def before it
00499       // in the block / subblock.
00500       NonUse = 0;
00501       for ( WalkOpPtr = OpPtr->GetPrevLink(); WalkOpPtr != NULL &&
00502            WalkOpPtr->GetOutListPtr() == NULL;
00503            WalkOpPtr = WalkOpPtr->GetPrevLink() )  // walk up from OpPtr
00504         {
00505           //          for ( WalkOprdPtr = FindFirstDef (WalkOpPtr);
00506           for ( WalkOprdPtr = WalkOpPtr->GetDestOprdPtr();
00507                WalkOprdPtr != NULL;
00508                WalkOprdPtr = WalkOprdPtr->GetNextOprdPtr() )  // defs...
00509             {
00510               if ( WalkOprdPtr->GetOprdType() != OprdType ) continue;
00511               if ( WalkOprdPtr->GetOprdRegNum() != RegNum ) continue;
00512               if ( OprdType != OT_MACRO &&
00513                   WalkOprdPtr->GetOprdFileType() != RegFileType )
00514                 continue;
00515               
00516               // Found a match, so it's not a use.
00517               derr( "   Found prior def at op " << WalkOpPtr->GetOpId()
00518                    << "\n" );
00519               NonUse = 1;
00520               break;
00521             } // end for
00522           // For BRLs, try to match the return macro as well.
00523           if ( !NonUse && WalkOpPtr->GetOpcode() == BRL &&
00524               OprdType == OT_MACRO )
00525             {
00526               WalkOprdPtr = FindReturnMacro( WalkOpPtr );
00527               if ( WalkOprdPtr != NULL &&
00528                   WalkOprdPtr->GetOprdRegNum() == RegNum )  // enough
00529                 {
00530                   // Found a match, so it's not a use.
00531                   derr( "   Found prior def at op " << WalkOpPtr->GetOpId()
00532                        << "\n" );
00533                   NonUse = 1;
00534                 } // end if
00535             } // end if
00536           
00537           if ( NonUse ) break;
00538         } // end for
00539       if ( NonUse ) continue;  // go to next source
00540       
00541       // Write to use set for op.
00542       IsBB = (((legoRegion *) OpPtr->GetParentBlockPtr())->GetRegionType()
00543               == RT_BB);
00544       if (IsBB)
00545         CreateReadHashKey( BBId, RegNum, RegFileType );
00546       else
00547         CreateReadHashKey( BBId, subblock, RegNum, RegFileType );
00548       
00549       LookUpIter = Table.find( ReadHashKey );  // lookup item
00550       EndPtr = Table.end();
00551       if ( LookUpIter == EndPtr )  // If not found...
00552         {
00553           if (IsBB)
00554             CreateWriteHashKey( BBId, RegNum, RegFileType );
00555           else
00556             CreateWriteHashKey( BBId, subblock, RegNum, RegFileType );
00557           // Create information.
00558           Info.Use = TRUE;
00559           Info.Def = FALSE;
00560           Info.LiveIn = FALSE;
00561           Info.LiveOut = FALSE;
00562           // We need to create a new operand here because this one doesn't 
00563           // actually exist yet for this procedure
00564           OprdPtr = new legoOprd();
00565           OprdPtr->SetOprdType(OT_MACRO);
00566           OprdPtr->SetOprdRegNum(regid);
00567           Info.Oprd = OprdPtr;
00568           Table[ WriteHashKey ] = Info;  // write to hash table!
00569           derr( "   ** Add to use set\n");
00570         } // if
00571       else
00572         {
00573           (*LookUpIter).second.Use = TRUE;  // turn on use in item
00574           derr( "   ** Mod to use set\n");
00575         } // end else
00576     }
00577   } */
00578   
00579   if (OpPtr->IsBRLOp()) 
00580   {
00581     int StartOpReg;
00582     int EndOpReg;
00583     if(OpPtr->GetOpcodePtr() != NULL)
00584     {
00585         // Get the number of outgoing Ops from the 
00586         // Alloc instr, The BRL Ops will not be present 
00587         // in the Leaf procedures
00588         //HZ: make sure proc is a proc
00589         legoProc * proc;
00590         legoRegion * reg_t = ((legoBB *)
00591                 OpPtr->GetParentBlockPtr())->GetParentPtr();
00592         if(reg_t->GetRegionType() == RT_PROC)
00593             proc = (legoProc *)reg_t;
00594         else
00595         {
00596             reg_t = reg_t->GetParentPtr();
00597             proc = (legoProc *) reg_t;
00598         }
00599         assert(reg_t->GetRegionType() == RT_PROC);
00600         //legoProc *proc = (legoProc *)((legoBB *) OpPtr->GetParentBlockPtr())->GetParentPtr();
00601     
00602         if(proc == NULL)
00603         {
00604           LegoNonFatal ("LiveVar->BBuses", "This parent Proc is NULL\n");
00605           exit (-1);
00606         }
00607     
00608         StartOpReg = FindFirstOutGoingReg(proc);
00609         EndOpReg = FindLastOutGoingReg(proc);
00610     }
00611     else
00612     {
00613         StartOpReg = INT_P1;
00614         EndOpReg = DBL_P2; 
00615     }
00616     for (int regid = StartOpReg; regid <= EndOpReg; regid++) {
00617       // create new operands for these, they may not all exist at this time
00618 
00619       if(OpPtr->GetOpcodePtr() != NULL)
00620       {
00621         OprdType = OT_REG;
00622         RegFileType = FT_GPR;
00623       }
00624       else
00625       {
00626         OprdType = OT_MACRO;
00627         // this one is always a MACRO
00628         RegFileType = -1;  // pseudo-filetype
00629       }
00630       
00631       RegNum = regid;
00632       
00633       derr( "   Src Register:  # " << RegNum << ", type: "
00634            << RegFileType << "\n" );
00635       
00636       // It's not in the use set yet. Skip it if there's a def before it
00637       // in the block / subblock.
00638       NonUse = 0;
00639       for ( WalkOpPtr = OpPtr->GetPrevLink(); WalkOpPtr != NULL &&
00640            WalkOpPtr->GetOutListPtr() == NULL;
00641            WalkOpPtr = WalkOpPtr->GetPrevLink() )  // walk up from OpPtr
00642         {
00643           //          for ( WalkOprdPtr = FindFirstDef (WalkOpPtr);
00644           for ( WalkOprdPtr = WalkOpPtr->GetDestOprdPtr();
00645                WalkOprdPtr != NULL;
00646                WalkOprdPtr = WalkOprdPtr->GetNextOprdPtr() )  // defs...
00647             {
00648               if ( WalkOprdPtr->GetOprdType() != OprdType ) continue;
00649               if ( WalkOprdPtr->GetOprdRegNum() != RegNum ) continue;
00650               if ( OprdType != OT_MACRO &&
00651                   WalkOprdPtr->GetOprdFileType() != RegFileType )
00652                 continue;
00653               
00654               // Found a match, so it's not a use.
00655               derr( "   Found prior def at op " << WalkOpPtr->GetOpId()
00656                    << "\n" );
00657               NonUse = 1;
00658               break;
00659             } // end for
00660           // For BRLs, try to match the return macro as well.
00661           if ( !NonUse && WalkOpPtr->IsBRLOp() &&
00662               OprdType == OT_MACRO )
00663             {
00664               WalkOprdPtr = FindReturnMacro( WalkOpPtr );
00665               if ( WalkOprdPtr != NULL &&
00666                   WalkOprdPtr->GetOprdRegNum() == RegNum )  // enough
00667                 {
00668                   // Found a match, so it's not a use.
00669                   derr( "   Found prior def at op " << WalkOpPtr->GetOpId()
00670                        << "\n" );
00671                   NonUse = 1;
00672                 } // end if
00673             } // end if
00674           
00675           if ( NonUse ) break;
00676         } // end for
00677       if ( NonUse ) continue;  // go to next source
00678       
00679       // Write to use set for op.
00680       IsBB = (((legoRegion *) OpPtr->GetParentBlockPtr())->GetRegionType()
00681               == RT_BB);
00682       if (IsBB)
00683         CreateReadHashKey( BBId, RegNum, RegFileType );
00684       else
00685         CreateReadHashKey( BBId, subblock, RegNum, RegFileType );
00686       
00687       LookUpIter = Table.find( ReadHashKey );  // lookup item
00688       EndPtr = Table.end();
00689       if ( LookUpIter == EndPtr )  // If not found...
00690         {
00691           if (IsBB)
00692             CreateWriteHashKey( BBId, RegNum, RegFileType );
00693           else
00694             CreateWriteHashKey( BBId, subblock, RegNum, RegFileType );
00695           // Create information.
00696           Info.Use = TRUE;
00697           Info.Def = FALSE;
00698           Info.LiveIn = FALSE;
00699           Info.LiveOut = FALSE;
00700           // We need to create a new operand here because this one doesn't 
00701           // actually exist yet for this procedure
00702           OprdPtr = new legoOprd();
00703           if(OpPtr->GetOpcodePtr() != NULL)
00704             {
00705              OprdPtr->SetOprdType(OT_REG);
00706              OprdPtr->SetOprdFileType(FT_GPR);
00707              OprdPtr->SetValid(1);
00708              OprdPtr->SetOprdRegType(RT_R);
00709              OprdPtr->SetOprdDataType(DT_I);
00710              OprdPtr->SetOprdRegStyle(RS_STATIC);
00711    
00712             }
00713           else
00714              OprdPtr->SetOprdType(OT_MACRO);
00715           OprdPtr->SetOprdRegNum(regid);
00716           Info.Oprd = OprdPtr;
00717           Table[ WriteHashKey ] = Info;  // write to hash table!
00718           derr( "   ** Add to use set\n");
00719         } // if
00720       else
00721         {
00722           (*LookUpIter).second.Use = TRUE;  // turn on use in item
00723           derr( "   ** Mod to use set\n");
00724         } // end else
00725     }
00726   }
00727   
00728   // mdj - 3/24/99
00729   // Need to make sure that subroutine return parameters are seen as 
00730   // live-out starting at each RTS for the subroutine. 
00731   /* if ( OpPtr->GetOpcode() == RTS ) {
00732     OprdType = OT_MACRO;
00733     for (RegNum = INT_RET; RegNum <= DBL_RET; RegNum++) {
00734       // this one is always a MACRO
00735       RegFileType = -1;  // pseudo-filetype
00736       derr( "   Src Register:  # " << RegNum << ", type: "
00737            << RegFileType << "\n" );
00738     
00739       // It's not in the use set yet. Skip it if there's a def before it
00740       // in the block / subblock.
00741       NonUse = 0;
00742       for ( WalkOpPtr = OpPtr->GetPrevLink(); WalkOpPtr != NULL &&
00743            WalkOpPtr->GetOutListPtr() == NULL;
00744            WalkOpPtr = WalkOpPtr->GetPrevLink() )  // walk up from OpPtr
00745         {
00746           //          for ( WalkOprdPtr = FindFirstDef (WalkOpPtr);
00747           for ( WalkOprdPtr = WalkOpPtr->GetDestOprdPtr();
00748                WalkOprdPtr != NULL;
00749                WalkOprdPtr = WalkOprdPtr->GetNextOprdPtr() )  // defs...
00750             {
00751               if ( WalkOprdPtr->GetOprdType() != OprdType ) continue;
00752               if ( WalkOprdPtr->GetOprdRegNum() != RegNum ) continue;
00753               if ( OprdType != OT_MACRO &&
00754                   WalkOprdPtr->GetOprdFileType() != RegFileType )
00755                 continue;
00756               
00757               // Found a match, so it's not a use.
00758               derr( "   Found prior def at op " << WalkOpPtr->GetOpId()
00759                    << "\n" );
00760               NonUse = 1;
00761               break;
00762             } // end for
00763           // For BRLs, try to match the return macro as well.
00764           if ( !NonUse && WalkOpPtr->GetOpcode() == BRL &&
00765               OprdType == OT_MACRO )
00766             {
00767               WalkOprdPtr = FindReturnMacro( WalkOpPtr );
00768               if ( WalkOprdPtr != NULL &&
00769                   WalkOprdPtr->GetOprdRegNum() == RegNum )  // enough
00770                 {
00771                   // Found a match, so it's not a use.
00772                   derr( "   Found prior def at op " << WalkOpPtr->GetOpId()
00773                        << "\n" );
00774                   NonUse = 1;
00775                 } // end if
00776             } // end if
00777           
00778           if ( NonUse ) break;
00779         } // end for
00780       if ( !NonUse ) {
00781         
00782         // Write to use set for op.
00783         IsBB = (((legoRegion *) OpPtr->GetParentBlockPtr())->GetRegionType()
00784                 == RT_BB);
00785         if (IsBB)
00786           CreateReadHashKey( BBId, RegNum, RegFileType );
00787         else
00788           CreateReadHashKey( BBId, subblock, RegNum, RegFileType );
00789         
00790         LookUpIter = Table.find( ReadHashKey );  // lookup item
00791         EndPtr = Table.end();
00792         if ( LookUpIter == EndPtr )  // If not found...
00793           {
00794             if (IsBB)
00795               CreateWriteHashKey( BBId, RegNum, RegFileType );
00796             else
00797               CreateWriteHashKey( BBId, subblock, RegNum, RegFileType );
00798             // Create information.
00799             Info.Use = TRUE;
00800             Info.Def = FALSE;
00801             Info.LiveIn = FALSE;
00802             Info.LiveOut = FALSE;
00803             // We need to create a new operand here because this one doesn't 
00804             // actually exist yet for this procedure
00805             OprdPtr = new legoOprd();
00806             if(OpPtr->GetOpcodePtr() != NULL)
00807             {
00808              OprdPtr->SetOprdType(OT_REG);
00809              OprdPtr->SetOprdFileType(FT_GPR);
00810              OprdPtr->SetValid(1);
00811              OprdPtr->SetOprdRegType(RT_R);
00812              OprdPtr->SetOprdDataType(DT_I);
00813              OprdPtr->SetOprdRegStyle(RS_STATIC);
00814    
00815             }
00816             else
00817              OprdPtr->SetOprdType(OT_MACRO);
00818             OprdPtr->SetOprdRegNum(RegNum);
00819             Info.Oprd = OprdPtr;
00820             Table[ WriteHashKey ] = Info;  // write to hash table!
00821             derr( "   ** Add to use set\n");
00822           } // if
00823         else
00824           {
00825             (*LookUpIter).second.Use = TRUE;  // turn on use in item
00826             derr( "   ** Mod to use set\n");
00827           } // end else
00828       }
00829     } */
00830     if ( OpPtr->IsRETOp()) {
00831     int StartOpReg;
00832     int EndOpReg;
00833     if(OpPtr->GetOpcodePtr() != NULL)
00834     {
00835         OprdType = OT_REG;
00836         RegFileType = FT_GPR;
00837         StartOpReg = 8;
00838         EndOpReg = 11;
00839     }
00840     else
00841     {
00842         OprdType = OT_MACRO;
00843         RegFileType = -1;  // pseudo-filetype
00844         StartOpReg = INT_RET;
00845         EndOpReg = DBL_RET;
00846     }
00847     for (RegNum = StartOpReg; RegNum <= EndOpReg; RegNum++) {
00848       // this one is always a MACRO
00849      derr( "   Src Register:  # " << RegNum << ", type: "
00850            << RegFileType << "\n" );
00851     
00852       // It's not in the use set yet. Skip it if there's a def before it
00853       // in the block / subblock.
00854       NonUse = 0;
00855       for ( WalkOpPtr = OpPtr->GetPrevLink(); WalkOpPtr != NULL &&
00856            WalkOpPtr->GetOutListPtr() == NULL;
00857            WalkOpPtr = WalkOpPtr->GetPrevLink() )  // walk up from OpPtr
00858         {
00859           //          for ( WalkOprdPtr = FindFirstDef (WalkOpPtr);
00860           for ( WalkOprdPtr = WalkOpPtr->GetDestOprdPtr();
00861                WalkOprdPtr != NULL;
00862                WalkOprdPtr = WalkOprdPtr->GetNextOprdPtr() )  // defs...
00863             {
00864               if ( WalkOprdPtr->GetOprdType() != OprdType ) continue;
00865               if ( WalkOprdPtr->GetOprdRegNum() != RegNum ) continue;
00866               if ( OprdType != OT_MACRO &&
00867                   WalkOprdPtr->GetOprdFileType() != RegFileType )
00868                 continue;
00869               
00870               // Found a match, so it's not a use.
00871               derr( "   Found prior def at op " << WalkOpPtr->GetOpId()
00872                    << "\n" );
00873               // for IA64 code we have become conservative,
00874               // so all the o/p regs are used  
00875               if(OpPtr->GetOpcodePtr() == NULL)
00876               NonUse = 1;
00877               break;
00878             } // end for
00879           // For BRLs, try to match the return macro as well.
00880           if ( !NonUse && WalkOpPtr->IsBRLOp() &&
00881               OprdType == OT_MACRO )
00882             {
00883               WalkOprdPtr = FindReturnMacro( WalkOpPtr );
00884               if ( WalkOprdPtr != NULL &&
00885                   WalkOprdPtr->GetOprdRegNum() == RegNum )  // enough
00886                 {
00887                   // Found a match, so it's not a use.
00888                   derr( "   Found prior def at op " << WalkOpPtr->GetOpId()
00889                        << "\n" );
00890                   NonUse = 1;
00891                 } // end if
00892             } // end if
00893           
00894           if ( NonUse ) break;
00895         } // end for
00896       if ( !NonUse ) {
00897         
00898         // Write to use set for op.
00899         IsBB = (((legoRegion *) OpPtr->GetParentBlockPtr())->GetRegionType()
00900                 == RT_BB);
00901         if (IsBB)
00902           CreateReadHashKey( BBId, RegNum, RegFileType );
00903         else
00904           CreateReadHashKey( BBId, subblock, RegNum, RegFileType );
00905         
00906         LookUpIter = Table.find( ReadHashKey );  // lookup item
00907         EndPtr = Table.end();
00908         if ( LookUpIter == EndPtr )  // If not found...
00909           {
00910             if (IsBB)
00911               CreateWriteHashKey( BBId, RegNum, RegFileType );
00912             else
00913               CreateWriteHashKey( BBId, subblock, RegNum, RegFileType );
00914             // Create information.
00915             Info.Use = TRUE;
00916             Info.Def = FALSE;
00917             Info.LiveIn = FALSE;
00918             Info.LiveOut = FALSE;
00919             // We need to create a new operand here because this one doesn't 
00920             // actually exist yet for this procedure
00921             OprdPtr = new legoOprd();
00922             if(OpPtr->GetOpcodePtr() != NULL)
00923             {
00924              OprdPtr->SetOprdType(OT_REG);
00925              OprdPtr->SetOprdFileType(FT_GPR);
00926              OprdPtr->SetValid(1);
00927              OprdPtr->SetOprdRegType(RT_R);
00928              OprdPtr->SetOprdDataType(DT_I);
00929              OprdPtr->SetOprdRegStyle(RS_STATIC);
00930    
00931             }
00932             else
00933              OprdPtr->SetOprdType(OT_MACRO);
00934             OprdPtr->SetOprdRegNum(RegNum);
00935             Info.Oprd = OprdPtr;
00936             Table[ WriteHashKey ] = Info;  // write to hash table!
00937             derr( "   ** Add to use set\n");
00938           } // if
00939         else
00940           {
00941             (*LookUpIter).second.Use = TRUE;  // turn on use in item
00942             derr( "   ** Mod to use set\n");
00943           } // end else
00944       }
00945     }
00946     // For IA64 we also need to check the "b0"
00947     // present as a source to the "br.ret..."
00948     legoOprd *btr;
00949     btr = OpPtr->GetSrcOprdPtr();
00950     if(btr->GetOprdFileType() == FT_BTR &&
00951         btr->GetOprdRegNum() == 0) {
00952     OprdType = OT_REG;
00953     RegFileType = FT_BTR;
00954     RegNum = 0;
00955     derr( "   Src Register:  # " << RegNum << ", type: "
00956            << RegFileType << "\n" );
00957     
00958       // It's not in the use set yet. Skip it if there's a def before it
00959       // in the block / subblock.
00960       for ( WalkOpPtr = OpPtr->GetPrevLink(); WalkOpPtr != NULL &&
00961            WalkOpPtr->GetOutListPtr() == NULL;
00962            WalkOpPtr = WalkOpPtr->GetPrevLink() )  // walk up from OpPtr
00963         {
00964           //          for ( WalkOprdPtr = FindFirstDef (WalkOpPtr);
00965           for ( WalkOprdPtr = WalkOpPtr->GetDestOprdPtr();
00966                WalkOprdPtr != NULL;
00967                WalkOprdPtr = WalkOprdPtr->GetNextOprdPtr() )  // defs...
00968             {
00969               if ( WalkOprdPtr->GetOprdType() != OprdType ) continue;
00970               if ( WalkOprdPtr->GetOprdRegNum() != RegNum ) continue;
00971               if ( WalkOprdPtr->GetOprdFileType() != RegFileType )
00972                 continue;
00973               
00974               // Found a match, so it's not a use.
00975               derr( "   Found prior def at op " << WalkOpPtr->GetOpId()
00976                    << "\n" );
00977               NonUse = 1;
00978               break;
00979             } // end for
00980             if(NonUse)
00981             break;
00982          }
00983          if ( !NonUse ) {
00984         
00985         // Write to use set for op.
00986         IsBB = (((legoRegion *) OpPtr->GetParentBlockPtr())->GetRegionType()
00987                 == RT_BB);
00988         if (IsBB)
00989           CreateReadHashKey( BBId, RegNum, RegFileType );
00990         else
00991           CreateReadHashKey( BBId, subblock, RegNum, RegFileType );
00992         
00993         LookUpIter = Table.find( ReadHashKey );  // lookup item
00994         EndPtr = Table.end();
00995         if ( LookUpIter == EndPtr )  // If not found...
00996           {
00997             if (IsBB)
00998               CreateWriteHashKey( BBId, RegNum, RegFileType );
00999             else
01000               CreateWriteHashKey( BBId, subblock, RegNum, RegFileType );
01001             // Create information.
01002             Info.Use = TRUE;
01003             Info.Def = FALSE;
01004             Info.LiveIn = FALSE;
01005             Info.LiveOut = FALSE;
01006             // We need to create a new operand here because this one doesn't 
01007             // actually exist yet for this procedure
01008             OprdPtr = new legoOprd();
01009             if(OpPtr->GetOpcodePtr() != NULL)
01010             {
01011              OprdPtr->SetOprdType(OT_REG);
01012              OprdPtr->SetOprdFileType(FT_BTR);
01013              OprdPtr->SetValid(1);
01014              OprdPtr->SetOprdRegType(RT_R);
01015              OprdPtr->SetOprdDataType(DT_I);
01016              OprdPtr->SetOprdRegStyle(RS_STATIC);
01017             }
01018             else
01019             OprdPtr->SetOprdType(OT_MACRO);
01020             OprdPtr->SetOprdRegNum(RegNum);
01021             Info.Oprd = OprdPtr;
01022             Table[ WriteHashKey ] = Info;  // write to hash table!
01023             derr( "   ** Add to use set\n");
01024           } // if
01025         else
01026           {
01027             (*LookUpIter).second.Use = TRUE;  // turn on use in item
01028             derr( "   ** Mod to use set\n");
01029           } // end else
01030       }
01031     }    
01032   }
01033   
01034   derr( "<< BB_uses\n" );
01035 } // end LiveVar::BB_uses
01036 
01037 // ==========================================================================
01038 
01039 // find_control_edge: return a ptr to the control edge between Parent & Child.
01040 //    Assumes that there exists at most 1 control edge between Parent & Child.
01041 /*
01042 static opEdges *find_control_edge( legoOp *ParentExit, legoRegion *Child )
01043 {
01044    legoRegion *Parent = (legoRegion *) ParentExit->GetParentBlockPtr();
01045    int OutEdgeId, InEdgeId;
01046    edgeList *OutEdges, *InEdges;
01047    opEdges *CurrentOutEdge, *CurrentInEdge;
01048 
01049 
01050    // Search through all of Parent's exit egdes until the one that
01051    // flows between Parent & Child is found
01052    for ( OutEdges = Parent->GetOutEdgesPtr(); OutEdges != NULL;
01053       OutEdges = OutEdges->GetNextListPtr() ) {
01054       if ( OutEdges->GetEdgePtr()->GetFromOpPtr() != ParentExit ) continue;
01055       OutEdgeId = OutEdges->GetEdgePtr()->GetEdgeId();
01056 
01057       for ( InEdges = Child->GetInEdgesPtr(); InEdges != NULL;
01058             InEdges = InEdges->GetNextListPtr() ) {
01059          InEdgeId = InEdges->GetEdgePtr()->GetEdgeId();
01060          if ( OutEdgeId == InEdgeId ) return InEdges->GetEdgePtr();
01061       }
01062     }
01063 
01064    return NULL;
01065 }
01066 */
01067 
01068 // print_attr: print the entire attr
01069 /*
01070 static void print_attr( attrs *Attr )
01071 {
01072    legoOprd *OprdPtr;
01073 
01074    derr( ">> print_attr\n" );
01075    for ( OprdPtr = Attr->GetAttrOprdPtr(); OprdPtr != NULL;
01076          OprdPtr = OprdPtr->GetNextOprdPtr() ) {
01077 
01078       int RegNum = OprdPtr->GetOprdRegNum(),
01079           RegFileType = OprdPtr->GetOprdFileType();
01080 
01081       if ( OprdPtr->GetOprdType() == OT_MACRO ) RegFileType = -1;
01082       cerr << "   RegFile " << RegFileType << ", RegNum " << RegNum << "\n";
01083    }
01084    derr( "<< print_attr\n" );
01085 }
01086 */
01087 
01088 /*
01089  * copy_operand
01090  *   Src = source operand
01091  *   Target = target operand
01092  *
01093  * Copies fields from Src to Target, assuming a register-type operand.
01094  * Does NOT copy next and prev pointers.
01095  */
01096 static void copy_operand( legoOprd *Src, legoOprd *Target )
01097 {
01098     if(Src->GetOprdType() != OT_REG)
01099     {
01100         assert(0); //HZ: not being able to process the literal string type of
01101                         //oprd.
01102     }
01103    Target->SetOprdType( Src->GetOprdType() );
01104    Target->SetValid( Src->GetValid() );
01105    Target->SetOprdRegType( Src->GetOprdRegType() );
01106    Target->SetOprdRegNum( Src->GetOprdRegNum() );
01107    Target->SetOprdDataType( Src->GetOprdDataType() );
01108    Target->SetOprdFileType( Src->GetOprdFileType() );
01109    Target->SetOprdRegStyle( Src->GetOprdRegStyle() );
01110    Target->SetIntValue( Src->GetOprdIntValue() );
01111 } // end copy_operand
01112 
01113 /*
01114  * add_to_existing_attr
01115  *   Attr = existing live attribute
01116  *   NewOprd = new operand to add to attribute
01117  *
01118  * Adds a copy of the operand NewOprd to attribute Attr. If a copy
01119  * already resides in Attr, no action is taken.
01120  */
01121 static void add_to_existing_attr( attrs *Attr, legoOprd *NewOprd )
01122 {
01123    legoOprd *OprdPtr, *ShadowPtr;
01124 #ifdef _LIVE_VAR_DEBUG_
01125    int RegNum, RegFileType;
01126 #endif
01127 
01128 
01129    derr( ">> add_to_existing_attr\n" );
01130 
01131    // Find the end of the Attr list.
01132 
01133    //   derr( "   Attr before addition\n" );
01134    //   print_attr( Attr );
01135    for ( OprdPtr = ShadowPtr = Attr->GetAttrOprdPtr(); OprdPtr != NULL;
01136          ShadowPtr = OprdPtr, OprdPtr = OprdPtr->GetNextOprdPtr() )
01137      {
01138        if ( OprdPtr->GetOprdType() == NewOprd->GetOprdType() &&
01139             OprdPtr->GetOprdRegNum() == NewOprd->GetOprdRegNum() &&
01140             OprdPtr->GetOprdFileType() == NewOprd->GetOprdFileType() )
01141          {
01142            derr( "   already present in attribute\n" );
01143            return;  // no change
01144          } // end if
01145      } // end for
01146 
01147    // At this point, OprdPtr should be NULL and ShadowPtr should point to
01148    // the last legoOprd in the list.
01149    if ( OprdPtr != NULL ) derr( "   ** OprdPtr not NULL!! **\n" );
01150 
01151 #ifdef _LIVE_VAR_DEBUG_
01152    RegFileType = NewOprd->GetOprdFileType();
01153    if ( NewOprd->GetOprdType() == OT_MACRO )
01154      RegFileType = -1;
01155    cerr << "   Oprd to be added: RegFile " << RegFileType << ", RegNum "
01156         << NewOprd->GetOprdRegNum() << "\n";
01157 
01158    RegFileType = ShadowPtr->GetOprdFileType();
01159    if ( ShadowPtr->GetOprdType() == OT_MACRO )
01160      RegFileType = -1;
01161    cerr << "   ShadowPtr values: RegFile " << RegFileType << ", RegNum "
01162         << ShadowPtr->GetOprdRegNum() << "\n";
01163 #endif
01164 
01165    OprdPtr = ShadowPtr->AddOprd();  // create new operand at end of list
01166 
01167    // Copy all legoOprd fields individually.
01168    copy_operand( NewOprd, OprdPtr );
01169 
01170 #ifdef _LIVE_VAR_DEBUG_
01171    RegFileType = OprdPtr->GetOprdFileType();
01172    if ( OprdPtr->GetOprdType() == OT_MACRO )
01173      RegFileType = -1;
01174    cerr << "   Newly created Oprd values: RegFile "
01175         << RegFileType << ", RegNum " << OprdPtr->GetOprdRegNum() << "\n";
01176 #endif
01177 
01178    //   derr( "   Attr after addition\n" );
01179    //   print_attr( Attr );
01180 
01181    derr( "<< add_to_existing_attr\n" );
01182    return;
01183 } // end add_to_existing_attr
01184 
01185 /*
01186  * create_new_attr
01187  *   Edge = edge on which to add live attribute
01188  *   Oprd = operand to add to attribute
01189  *   Proc = proc to whose dictionary to add edge
01190  *
01191  * Creates a new live attribute for Edge containing a copy of Oprd.
01192  */
01193 static void create_new_attr( opEdges *Edge, legoOprd *Oprd, legoProc *Proc )
01194 {
01195   legoOprd *NewOprd = new legoOprd();
01196 
01197   derr( ">> create_new_attr\n" );
01198 
01199 #ifdef _LIVE_VAR_DEBUG_
01200   attrs* Attr;
01201   int RegFileType;
01202 
01203   RegFileType = Oprd->GetOprdFileType();
01204   if ( Oprd->GetOprdType() == OT_MACRO )
01205     RegFileType = -1;
01206   cerr << "   Oprd to be added: RegFile " << RegFileType << ", RegNum "
01207        << Oprd->GetOprdRegNum() << "\n";
01208 #endif
01209 
01210   // Copy all legoOprd fields individually.
01211   copy_operand( Oprd, NewOprd );
01212 
01213   // Add the attribute after creating a new operand copy.
01214   AddLiveAttribute( NewOprd, Edge, Proc );
01215 
01216 #ifdef _LIVE_VAR_DEBUG_
01217    //   print_attr( FindLiveAttribute( Edge ) );
01218 #endif
01219 
01220   derr( "<< create_new_attr\n" );
01221   return;
01222 } // end create_new_attr
01223 
01224 // ==========================================================================
01225 
01226 /*
01227  * BB_live_out
01228  *   ProcPtr = proc containing RegionPtr
01229  *   RegionPtr = region for which to create live-out set
01230  *
01231  * out[B] = U (S succ. B) in[S]
01232  *
01233  * Performs the iterative live-out computation.
01234  */
01235 void LiveVar::BB_live_out( legoProc *ProcPtr, legoRegion *RegionPtr )
01236 {
01237   regionList *ChildrenList;
01238   legoRegion *ChildRegionPtr;
01239   legoOp *ExitOp;
01240   opList *ExitOps; 
01241   opEdges *ControlEdge;
01242   SetInfo Info;
01243   SetInfoTable::iterator LookUpIter, LookUpIterLoop, EndPtr;
01244   attrs *Attr;
01245 
01246   int i, BBId = RegionPtr->GetRegionId(), ChildBBId, DoingNextSubBlock,
01247     SkipIt;
01248   char temp, *tempstr;
01249   legoOprd *NewOprd;
01250 
01251 
01252   derr(">> BB_live_out: iteration #" << IterCount << ", BBId " << BBId << " subblock " << subblock << "\n");
01253 
01254   // Ignore empty blocks left behind from Multi-Way branch formation. These 
01255   // blocks are no longer connected to any program control flow and will be 
01256   // removed after the proc is scheduled (they are not removed immediately 
01257   // because that fucks up region_ptrs used for tree-traversal scheduling).
01258   if (RegionPtr->GetCount() == 0)
01259     return; 
01260 
01261   // The next subblock after this one is also a successor. We'll do
01262   // that one last; right now we aren't doing it.
01263   DoingNextSubBlock = 0;
01264 
01265   ChildrenList = (regionList *) RegionPtr->GetChildren();
01266 
01267   // Iterate down children of RegionPtr.
01268   // If ChildrenList is immediately NULL, there's no children except for
01269   // possibly the next subblock. Try accessing that.
01270   if (ChildrenList != NULL)
01271     ChildRegionPtr = (legoRegion *) ChildrenList->GetRegionPtr();
01272   else
01273     {
01274       if ( RegionPtr->GetRegionType() != RT_BB )
01275         {
01276           ChildRegionPtr = RegionPtr;
01277           DoingNextSubBlock = 1;
01278         } // end if
01279       // Else else, we're done.
01280       else ChildRegionPtr = NULL;
01281     } // end else
01282 
01283   while (ChildRegionPtr != NULL)
01284     {
01285     //    if ( (ChildRegionPtr->GetRegionType()) == RT_BB ) {
01286       //    if ( IS_BLOCK(ChildRegionPtr->GetRegionType()) ) {
01287       ChildBBId = ChildRegionPtr->GetRegionId();
01288       derr("   >> BBId " << ChildBBId << " being processed\n" );
01289 
01290       // Immediately find the control edge leading from the exit of
01291       // the current block/subblock to ChildRegionPtr. If it's not there,
01292       // and we're on a subblock, skip it; the edge must come from another
01293       // exit op. This is the edge that will have its attribute updated.
01294       SkipIt = 0;
01295       if ( !DoingNextSubBlock )
01296         {
01297           // Find the relevant exit op from this block/subblock.
01298           if ( RegionPtr->GetRegionType() == RT_BB ) {
01299             
01300             // Because of Multi-Way branching, BB may now have more than one 
01301             // ExitOp. Need to find the appropriate ControlEdge/ExitOp pair
01302             
01303             for (ExitOps = RegionPtr->GetExitOpsPtr();
01304                  ExitOps != NULL; 
01305                  ExitOps = ExitOps->GetNextListPtr()) {
01306               ExitOp = ExitOps->GetOpPtr();
01307               ControlEdge = FindControlEdge (ExitOp, ChildRegionPtr->
01308                                              GetEntryOpsPtr()->GetOpPtr(), 1);
01309               if (ControlEdge != NULL) {
01310                 break; 
01311               }
01312             }
01313           }
01314           else if ( IS_BLOCK(RegionPtr->GetRegionType()) )
01315             {
01316               for ( i = 0, ExitOp = RegionPtr->GetEntryOpsPtr()->GetOpPtr();
01317                    i < subblock; ExitOp = ExitOp->GetNextLink() )
01318                 {
01319                   if ( ExitOp->GetOutListPtr() != NULL ) i++;
01320                   if ( i == subblock ) break;  // count up to subblock
01321                 } // end for
01322               ControlEdge = FindControlEdge (ExitOp, ChildRegionPtr->
01323                                              GetEntryOpsPtr()->GetOpPtr(), 1);
01324             } // end else
01325           else
01326             {
01327               LegoNonFatal ("LiveVar::BB_live_out", "Passed non-block.");
01328               return;
01329             } // end else
01330           derr(">> Exit op is op " << ExitOp->GetOpId() << "\n");
01331 
01332           if ( ControlEdge == NULL )
01333             {
01334               if ( subblock == 0 )
01335                 LegoNonFatal ("liveness", "Can't find control edge from op %d "
01336                               "to region %d.", ExitOp->GetOpId(),
01337                               ChildRegionPtr->GetRegionId());
01338               SkipIt = 1;
01339             } // end if
01340         } // end if
01341 
01342       // Do all entries that start with either:
01343       // <bbid>-     or
01344       // <bbid>/1-   or
01345       // <thisbbid>/<subblock+1>- if we're doing the next subblock
01346       if ( !DoingNextSubBlock ) {
01347         sprintf( LBHashKey, "%d-", ChildBBId );  // look between this ...
01348         sprintf( UBHashKey, "%d0", ChildBBId );  // ... and this!
01349       } // end if
01350       else {
01351         sprintf( LBHashKey, "%d/%d-", BBId, subblock + 1 );  // or this ...
01352         sprintf( UBHashKey, "%d/%d-", BBId, subblock + 2 );  // ... and this!
01353       } // end else
01354 
01355       // Run through every hashtable entry that is in the range of keys
01356       // we're looking for.
01357       for( LookUpIterLoop = Table.lower_bound(LBHashKey);
01358            ((LookUpIterLoop != (Table.lower_bound(UBHashKey))) &&
01359             (LookUpIterLoop != Table.end())) &&
01360              !SkipIt;
01361            LookUpIterLoop++)
01362         {
01363 
01364           // Check that it's not from a subblock of a superblock
01365           // numbered 2 or later (i.e., it must be <bbid>/1-...).
01366           // Larin change begins  
01367           //tempstr = strstr ( (*LookUpIterLoop).first, "/");
01368           //if ( tempstr != NULL ) {
01369             // It's a superblock.
01370             //if ( tempstr [ 1 ] != '1' || tempstr [ 2 ] != '-' ) continue;
01371           //    } // if
01372           // Larin change ends 
01373 
01374           if ((*LookUpIterLoop).second.LiveIn)
01375             {
01376               // OK, we found something live-in. Let's keep a pointer to it.
01377               SetInfoTable::iterator TmpIter = LookUpIterLoop;
01378 
01379               // Check whether it's marked as live-out already from RegionPtr.
01380               // If not, do so, adding a table entry if needed.
01381               ReadHashKey = (*LookUpIterLoop).first;
01382               ReadHashKey = strchr(ReadHashKey, '-');  // pop off end
01383               if ( subblock == 0 )  // create new front
01384                 sprintf( ReadHashPart1, "%d", BBId );
01385               else
01386                 sprintf( ReadHashPart1, "%d/%d", BBId, subblock );
01387               ReadHashKey = strcat(ReadHashPart1,ReadHashKey);  // merge
01388 
01389               LookUpIter = Table.find( ReadHashKey );
01390               EndPtr = Table.end();
01391               if ( LookUpIter == EndPtr ||
01392                    (*LookUpIter).second.LiveOut != TRUE )
01393                 {
01394                   // The value is live-in to the child block.
01395                   derr( "   Live-out (" << ReadHashKey << ") from region "
01396                         << RegionPtr->GetRegionId() << " to region "
01397                         << ChildRegionPtr->GetRegionId() << "\n" );
01398 
01399                   // Make a new table entry if needed.
01400                   if ( LookUpIter == EndPtr )
01401                     {
01402                       WriteHashKey = new char[HASH_KEY_SIZE];   
01403                       strcpy(WriteHashKey, ReadHashKey);
01404                       Info.Use = FALSE;
01405                       Info.Def = FALSE;
01406                       Info.LiveIn = FALSE;
01407                       Info.LiveOut = TRUE;
01408                       Info.Oprd = (*TmpIter).second.Oprd;
01409                       Table[ WriteHashKey ] = Info;
01410                       derr("   Table entry added\n");
01411                     } // end if
01412                   else
01413                     {
01414                       (*LookUpIter).second.LiveOut = TRUE;
01415                       derr("   HashKey " << ReadHashKey <<
01416                            " updated for LiveOut\n");
01417                     } // end else
01418 
01419                   //              ChangeBit = TRUE;  // a change occurred!
01420                 } // end if
01421 
01422               // Set a pointer to the operand that is live-out.
01423               NewOprd = (*TmpIter).second.Oprd;
01424 
01425               // Possibly create a live attribute for this control edge.
01426               // First, see if a live-ness attr exists. If yes, add
01427               // this regid to the end. If no, create a new attr & add this
01428               // regid.
01429               // (This must be here, instead of above when a live-out is
01430               //  first discovered, so that if a value is live-out along
01431               //  multiple edges, each one gets its chance to have its
01432               //  live attribute updated.)
01433 
01434               // Also, we can create a hash table representation of the
01435               // edge information (EdgeInfo), as well or instead. That will
01436               // be made as a postpass.
01437               if ( !DoingNextSubBlock )  // o/w, no edge to bother with
01438                 {
01439                   Attr = FindLiveAttribute( ControlEdge );
01440                   if ( Attr != NULL ) // exists
01441                     add_to_existing_attr( Attr, NewOprd );
01442                   else
01443                     create_new_attr( ControlEdge, NewOprd, ProcPtr );
01444                   derr( "   Edge " << ControlEdge->GetEdgeId() <<
01445                         " updated\n" );
01446                 } // end if
01447             } // if LiveIn
01448         } // for (hashtable items in range)
01449       //    } // if IS_BLOCK
01450 
01451       // Move to next child if we can.
01452       if ( ChildrenList != NULL )
01453         ChildrenList = ChildrenList->GetNextListPtr();
01454 
01455       // If not at end of children list, set ChildRegionPtr.
01456       if ( ChildrenList != NULL )
01457         ChildRegionPtr = (legoRegion *) ChildrenList->GetRegionPtr();
01458       // Else, if we haven't done the next subblock yet, set it up.
01459       else
01460         {
01461           if ( !DoingNextSubBlock && RegionPtr->GetRegionType() != RT_BB )
01462             {
01463               ChildRegionPtr = RegionPtr;
01464               DoingNextSubBlock = 1;
01465             } // end if
01466           // Else else, we're done.
01467           else ChildRegionPtr = NULL;
01468         } // end else
01469     } // while
01470 
01471   derr("<< BB_live_out\n" );
01472   return;
01473 } // end LiveVar::BB_live_out
01474 
01475 /*
01476  * BB_live_in
01477  *   ProcPtr = proc containing RegionPtr
01478  *   RegionPtr = region for which to create live-in set
01479  *
01480  * in[B] = use[B] U (out[B] - def[B])
01481  *
01482  * Performs the iterative live-in computation.
01483  */
01484 void LiveVar::BB_live_in( legoProc *ProcPtr, legoRegion *RegionPtr )
01485 {
01486   SetInfoTable::iterator LookUpIter;  
01487   int BBId = RegionPtr->GetRegionId();
01488   bool Out_Not_Def, old_LiveIn;
01489 
01490   derr(">> BB_live_in: iteration #" << IterCount << ", BBId " << BBId << " subblock " << subblock << "\n");
01491 
01492   // Ignore empty blocks left behind from Multi-Way branch formation. These 
01493   // blocks are no longer connected to any program control flow and will be 
01494   // removed after the proc is scheduled (they are not removed immediately 
01495   // because that fucks up region_ptrs used for tree-traversal scheduling).
01496   if (RegionPtr->GetCount() == 0)
01497     return; 
01498 
01499   // Make up hash-key ranges for operands in the block/subblock.
01500   if ( subblock == 0 ) { // doing basic block
01501     sprintf( LBHashKey, "%d-", BBId );  
01502     sprintf( UBHashKey, "%d0", BBId );  
01503   } // end if
01504   else {
01505     sprintf( LBHashKey, "%d/%d-", BBId, subblock );
01506     sprintf( UBHashKey, "%d/%d-", BBId, subblock + 1 );
01507   } // end else
01508 
01509   // Iterate over each operand in the block/subblock.
01510   for( LookUpIter = Table.lower_bound(LBHashKey);
01511        //       ((LookUpIter != Table.upper_bound(UBHashKey)) &&
01512        ((LookUpIter != Table.lower_bound(UBHashKey)) &&
01513         (LookUpIter != Table.end()));
01514        LookUpIter++)
01515     {
01516       // First find whether it's live-out of this block/subblock but
01517       // not defined here.
01518       if( ((*LookUpIter).second.LiveOut == TRUE) &&
01519           ((*LookUpIter).second.Def == FALSE) )
01520         Out_Not_Def = TRUE;
01521       else Out_Not_Def = FALSE;
01522 
01523       // Now, perform the iteration and check for a change.
01524       old_LiveIn = (*LookUpIter).second.LiveIn;
01525       (*LookUpIter).second.LiveIn =
01526         ((*LookUpIter).second.Use || Out_Not_Def);
01527       if ((*LookUpIter).second.LiveIn != old_LiveIn)
01528         {
01529           ChangeBit = TRUE;
01530           derr("   HashKey " << (*LookUpIter).first <<
01531                " updated for LiveIn\n");
01532         } // end if
01533       //      if ( (*LookUpIter).second.LiveIn != ((*LookUpIter).second.Use ||
01534       //                                         Out_Not_Def) )
01535       //        {
01536       //          (*LookUpIter).second.LiveIn =
01537       //            ((*LookUpIter).second.Use || Out_Not_Def);
01538       //          ChangeBit = TRUE;
01539       //          derr("   HashKey " << (*LookUpIter).first <<
01540       //               " updated for LiveIn\n");
01541       //        } // end if
01542     } // end for
01543   
01544   derr("<< BB_live_in\n" );
01545   return;
01546 } // end LiveVar::BB_live_in
01547 
01548 // ==========================================================================
01549 
01550 /*
01551  * Process
01552  *   RegionPtr = region for which to compute liveness
01553  *   ProcPtr = proc containing RegionPtr
01554  *
01555  * Computes the live-out and live-in sets for RegionPtr if it is a
01556  * block, or for the regions within RegionPtr otherwise. This function
01557  * represents one iteration of the overall iterative algorithm, with
01558  * an implicit hierarchical ordering (not necessarily the fastest).
01559  */
01560 void LiveVar::Process ( legoRegion *RegionPtr, legoProc *ProcPtr )
01561 {
01562   int BBId, RegionCount, NumSubRegions;
01563 
01564   if ( IS_BLOCK (RegionPtr->GetRegionType()) )
01565     {
01566       BBId = RegionPtr->GetRegionId();
01567       //    derr( "BB number " << (j + 1) << ", BBId: " << BBId << "\n");
01568 
01569       // Count the number of subregions (subblocks) if RegionPtr is a
01570       // superblock (or hyperblock).
01571       NumSubRegions = 0;
01572       if ( RegionPtr->GetRegionType() != RT_BB )
01573         {
01574           legoOp *op;
01575 
01576           for ( op = RegionPtr->GetEntryOpsPtr()->GetOpPtr(); op != NULL;
01577                 op = op->GetNextLink() ) {
01578             if ( op->GetOutListPtr() != NULL) NumSubRegions++;
01579           } // end for
01580           derr(">> Contains " << NumSubRegions << " subblocks.\n");
01581         } // end if
01582 
01583       // Loop over each subblock, from the bottom up, for superblocks;
01584       // just do the basic block otherwise.
01585       if ( RegionPtr->GetRegionType() == RT_BB )
01586         {
01587           subblock = 0;
01588           BB_live_out( ProcPtr, RegionPtr );
01589           BB_live_in( ProcPtr, RegionPtr );
01590         } // end if
01591       else for (subblock = NumSubRegions; subblock > 0; subblock--)
01592         {
01593           BB_live_out( ProcPtr, RegionPtr );
01594           BB_live_in( ProcPtr, RegionPtr );
01595         } // end else
01596     } // end if
01597   else
01598     {
01599       RegionCount = RegionPtr->GetCount();
01600       // Try this backwards in interest of compile time
01601       // LiveVars uses 'BACKWARDS' equations
01602       for ( int i = (RegionCount - 1); i >= 0; i--)
01603 //      for (int i = 0; i < RegionCount; i++)
01604         Process ( (legoRegion *) RegionPtr->GetItem ( i ), ProcPtr );
01605     } // end else
01606 
01607   return;
01608 } // end LiveVar::Process
01609 
01610 /*
01611  * analyze
01612  *   RegionPtr = region on which to work (must not be op-holding)
01613  *   ProcPtr = proc containing region
01614  *
01615  * Perform liveness analysis on RegionPtr. If RegionPtr is a block,
01616  * finds defs and uses, then quits. If RegionPtr is not a block but
01617  * not a proc, finds defs and uses of its subregions, then quits.
01618  * If RegionPtr is a proc, finds defs and uses of its subregions,
01619  * then cranks the iterative algorithm.
01620  */
01621 // analyze: perform live-out analysis on ProcPtr
01622 void LiveVar::analyze( legoRegion *RegionPtr, legoProc *ProcPtr )
01623 {
01624   legoRegion *SubRegionPtr;
01625   legoOp *OpPtr;
01626   SetInfoTable::iterator LookUpIter;
01627   
01628   int j, k, RegionCount, OpCount, BBId;
01629 
01630   // Initialize a few things if we are just starting.
01631   if ( RegionPtr->GetRegionType() == RT_PROC )
01632     {
01633       //      Table.map();
01634       // wah 3/24/98
01635       Table = SetInfoTable();
01636       ReadHashKey = new char[ HASH_KEY_SIZE ];
01637       ReadHashPart1 = new char[ HASH_PART_SIZE ];
01638       ReadHashPart2 = new char[ HASH_PART_SIZE ];
01639       ReadHashPart3 = new char[ HASH_PART_SIZE ];
01640       LBHashKey = new char[ HASH_KEY_SIZE ];
01641       UBHashKey = new char[ HASH_KEY_SIZE ];
01642       delete EdgeInfo;
01643     } // end if
01644 
01645   RegionCount = RegionPtr->GetCount();
01646   if ( RegionPtr == (legoRegion *) ProcPtr )
01647     derr( RegionCount << " Region(s) in Proc " << ProcPtr->GetProcName()
01648           << "\n");
01649 
01650   // Go over each subregion of the region.
01651   for ( j = 0; j < RegionCount; j++)
01652     {
01653       SubRegionPtr = (legoRegion *) RegionPtr->GetItem( j ); 
01654 
01655       // If it's a block, do defs and uses for its ops.
01656       if ( IS_BLOCK (SubRegionPtr->GetRegionType()) )
01657         {
01658           BBId = SubRegionPtr->GetRegionId();
01659           derr( "BB number " << (j + 1) << ", BBId: " << BBId << "\n");
01660 
01661           OpCount = SubRegionPtr->GetCount();
01662           derr( OpCount << " Op(s) in BB number " << (j + 1) << "\n");
01663           subblock = 1;  // on first subblock
01664 
01665           // Do defs and uses for each op in the block.
01666           for ( k = 0; k < OpCount; k++)
01667             {
01668               OpPtr = (legoOp *) SubRegionPtr->GetItem( k );
01669               derr( "Op number " << (k + 1) << ", OpId: " << OpPtr->GetOpId()
01670                     << "\n");
01671               BB_uses(OpPtr, BBId);
01672               BB_defs(OpPtr, BBId);
01673               // Increment subblock if just saw branch.
01674               if (OpPtr->GetOutListPtr() != NULL) subblock++;
01675             } // end for
01676         } // end if
01677       else
01678         {
01679           // Do defs and uses for all the subregions.
01680           analyze ( SubRegionPtr, ProcPtr );
01681         } // end else
01682     } // end for
01683 
01684   if ( RegionPtr != (legoRegion *) ProcPtr)
01685     return;  // only proceed if whole proc is done
01686   derr( "** Defs/uses complete **\n" );
01687 
01688   // Here, we know we're on a proc. Set up for cranking the iteration.
01689   ChangeBit = TRUE;
01690   IterCount = 1;
01691   while (ChangeBit == TRUE)
01692     {
01693       ChangeBit = FALSE;
01694       // Try this backwards in interest of compile time
01695       // LiveVars uses 'BACKWARDS' equations
01696       for ( j = (RegionCount - 1); j >= 0; j--)
01697         {
01698           SubRegionPtr = (legoRegion *) RegionPtr->GetItem( j );
01699           Process ( SubRegionPtr, ProcPtr );
01700         } // end for
01701       derr ("Iteration number " << IterCount << "\n");
01702       IterCount++;
01703     } // end while
01704 
01705   // We're done.
01706 #ifdef _LIVE_VAR_DEBUG_
01707   for( LookUpIter = Table.begin();LookUpIter != Table.end();LookUpIter++ ) {
01708     derr( "Key : " );
01709     cerr.width(12);
01710     derr( (*LookUpIter).first );
01711     derr( " -- Def: " << (*LookUpIter).second.Def << ", Use: "
01712           << (*LookUpIter).second.Use << ", LiveIn: "
01713           << (*LookUpIter).second.LiveIn << ", LiveOut: "
01714           << (*LookUpIter).second.LiveOut << "\n" );
01715   }
01716 #endif
01717   if ( CreateTable )
01718     CollectEdgeInfo ( ProcPtr );
01719 
01720   delete [] ReadHashKey;
01721   delete [] ReadHashPart1;
01722   delete [] ReadHashPart2;
01723   delete [] ReadHashPart3;
01724   //  delete [] WriteHashKey;
01725   //  delete [] WriteHashPart1;
01726   //  delete [] WriteHashPart2;
01727   //  delete [] WriteHashPart3;
01728   delete [] LBHashKey;
01729   delete [] UBHashKey;
01730   // mdj - 11/20/98
01731   // delete the WriteHashKeys that we allocated or else they leak
01732   for( LookUpIter = Table.begin();LookUpIter != Table.end();LookUpIter++ ) {
01733     delete ((*LookUpIter).first);
01734   }
01735   Table.erase( Table.begin(), Table.end() );
01736 
01737   return;
01738 } // end LiveVar::analyze
01739 
01740 /*
01741  * analyze
01742  *   modulePtr = legoModule to analyze
01743  *
01744  * Performs live analysis on an entire legoModule.
01745  */
01746 void LiveVar::analyze( legoModule *modulePtr )
01747 { 
01748   legoProc *ProcPtr;
01749   int i, ProcCount;
01750   
01751   ProcCount = modulePtr->GetCount();
01752   derr( ProcCount << " Proc(s) in legoModule\n");
01753 
01754   for ( i = 0; i < ProcCount; i++ )
01755     analyze( ( legoProc *)  modulePtr->GetItem( i ),
01756              ( legoProc *)  modulePtr->GetItem( i ));
01757 }
01758 
01759 // deleteedgeinfo: remove list of operands for given edge (if 0, all!)
01760 void LiveVar::deleteedgeinfo ( int edgeid )
01761 {
01762   if ( EdgeInfo == NULL ) return;
01763   if ( edgeid != 0 ) {
01764     //    oprdl = EdgeInfo->Lookup ( edgeid );
01765     //    if ( ! (EdgeInfo->NotFound()) ) delete oprdl;
01766     EdgeInfo->Delete ( edgeid );
01767     return;
01768   }
01769 
01770   //  for ( EdgeInfo->Start(); ! (EdgeInfo->AtEnd()); EdgeInfo->Next() ) {
01771     //    oprdl = EdgeInfo->LookupCurrent();
01772     //    if ( ! (EdgeInfo->NotFound()) ) delete oprdl;
01773   //  }
01774   EdgeInfo->DeleteAll();
01775   return;
01776 }
01777 
01778 /*
01779  * CollectEdgeInfo
01780  *   ProcPtr = procedure for which to collect information
01781  *
01782  * Creates a hashtable representation of the live attribute information
01783  * found in ProcPtr.
01784  */
01785 void LiveVar::CollectEdgeInfo ( legoProc *ProcPtr )
01786 {
01787   opEdges *edge;
01788   attrs *liveattr;
01789   //  oprdList *liveoprds, *oprdl;
01790   legoOprd *oprd;
01791 
01792   if ( !CreateTable ) return;
01793 
01794   if ( EdgeInfo == NULL )
01795     EdgeInfo = new legoHash <int, legoOprd *, legoHash_lt_int>;
01796   else
01797     deleteedgeinfo (0);
01798 
01799   for ( edge = ProcPtr->GetEdgeDictionary(); edge != NULL;
01800         edge = edge->GetNextOpEdgePtr() ) {
01801     liveattr = FindLiveAttribute (edge);
01802     if ( liveattr == NULL ) continue;
01803 
01804     //    liveoprds = oprdl = NULL;
01805     //    for ( oprd = liveattr->GetAttrOprdPtr(); oprd != NULL;
01806     //    oprd = oprd->GetNextOprdPtr() ) {
01807     //      if ( oprdl != NULL ) {
01808     //  oprdl->SetNextListPtr ( new oprdList );
01809     //  oprdl = oprdl->GetNextListPtr();
01810     //      }
01811     //      else {
01812     //  liveoprds = oprdl = new oprdList;
01813     //      }
01814     //
01815     //      oprdl->SetOprdPtr ( oprd );
01816     //    }
01817 
01818     oprd = liveattr->GetAttrOprdPtr();
01819     //    if ( liveoprds != NULL )
01820     if ( oprd != NULL )
01821       EdgeInfo->Set ( edge->GetEdgeId(), oprd );
01822   }
01823 
01824   return;
01825 } // end CollectEdgeInfo
01826 
01827 
01828 /*
01829  * LiveVariables
01830  *   proc = procedure to analyze
01831  *   maketable = whether to create hashtable of info for return
01832  *   returns: hashtable of liveness information
01833  *
01834  * Performs live variable analysis on procedure proc. The information is
01835  * stored in live attributes directly in the IR, and also returned in
01836  * tabular form.
01837  */
01838 legoHash <int, legoOprd *, legoHash_lt_int> *
01839 LiveVariables (legoProc *proc, int maketable = 0)
01840 {
01841   legoHash <int, legoOprd *, legoHash_lt_int> *LiveInfo;
01842   LiveVar *live = new LiveVar;
01843   if (maketable) live->SetCreateTable (TRUE);
01844   else live->SetCreateTable (FALSE);
01845 
01846   live->analyze (proc, proc);
01847 
01848   LiveInfo = live->GetEdgeInfo();
01849   live->SetEdgeInfo ( NULL );
01850   delete live;
01851   return LiveInfo;
01852 } // end LiveVariables
01853 
01854 
01855 
01856 

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