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

CompleteLiveness.C

Go to the documentation of this file.
00001 #include "CompleteLiveness.H"
00002 
00003 //#define _LIVE_VAR_DEBUG_
00004 
00005 struct UseDefOprd {
00006         int OprdRegNum;
00007         int OprdFileType;
00008         struct UseDefOprd *next;
00009 };
00010 
00011 legoHash <int, iavector *, legoHash_lt_int> *LiveNess;
00012 
00013 static legoHash <int, struct UseDefOprd *, legoHash_lt_int> *Use;
00014 static legoHash <int, struct UseDefOprd *, legoHash_lt_int> *Def;
00015 static legoHash <int, struct UseDefOprd *, legoHash_lt_int> *L_Out;
00016 
00017 static int MaxGregNum = 0;
00018 static int MaxFregNum = 0;
00019 static int MaxPregNum = 0;
00020 static int MaxBregNum = 0;
00021 
00022 static void
00023 SetUsesAndDefs_Op(legoOp *op) {
00024   legoOprd *dest, *src;
00025   struct UseDefOprd *use, *def;
00026   
00027   //(a). This step is for the defs
00028   
00029   //HZ: in the case of the predicate, we take a conservative approach by saying
00030   // that the predicate guarded insn will only use regs but not kill (define)
00031   // regs. (p0 is always 1)
00032  if(op->GetPredOprdPtr() != NULL && op->GetPredOprdPtr()->GetOprdType() ==
00033          OT_REG && op->GetPredOprdPtr()->GetOprdFileType() == FT_PR && 
00034          op->GetPredOprdPtr()->GetOprdRegNum() != 0)
00035  {
00036      ;
00037  }
00038  else
00039  {
00040   for(dest = op->GetDestOprdPtr();
00041         dest != NULL; dest = dest->GetNextOprdPtr()) {
00042         if(dest->GetOprdType() != OT_REG)
00043         continue;
00044         def = Def->Lookup(op->GetOpId());
00045         if(Def->NotFound()) {
00046           // Thus the op has no element present in the 
00047           // Def table
00048           def = new struct UseDefOprd;
00049           def->OprdRegNum = dest->GetOprdRegNum();
00050           def->OprdFileType = dest->GetOprdFileType();
00051           def->next = NULL;
00052           
00053           Def->Set (op->GetOpId(), def);  
00054         } // end if
00055         else {
00056           // If we are here, there is some previous def
00057           // present
00058           while(def->next != NULL)
00059             def = def->next;
00060             
00061             // Now allocate memory for the next
00062             def->next = new struct UseDefOprd;
00063             def->next->OprdRegNum =  dest->GetOprdRegNum();
00064             def->next->OprdFileType = dest->GetOprdFileType();
00065             def->next->next = NULL;
00066         } // end else
00067   } // end for(dest....
00068  }//end of if (predicated ...)
00069  
00070   //(b). This step is for the Use
00071   for(src = op->GetSrcOprdPtr();
00072         src != NULL; src = src->GetNextOprdPtr()) {
00073         if(src->GetOprdType() != OT_REG)
00074         continue;
00075         use = Use->Lookup(op->GetOpId());
00076         if(Use->NotFound()) {
00077           // Thus the op has no element present in the 
00078           // Def table
00079           use = new struct UseDefOprd;
00080           use->OprdRegNum = src->GetOprdRegNum();
00081           use->OprdFileType = src->GetOprdFileType();
00082           use->next = NULL;
00083           
00084           Use->Set (op->GetOpId(), use);  
00085         } // end if
00086         else {
00087           // If we are here, there is some previous def
00088           // present
00089           while(use->next != NULL)
00090             use = use->next;
00091             
00092             // Now allocate memory for the next
00093             use->next = new struct UseDefOprd;
00094             use->next->OprdRegNum =  src->GetOprdRegNum();
00095             use->next->OprdFileType = src->GetOprdFileType();
00096             use->next->next = NULL;
00097         } // end else
00098   } // end for(src....
00099   
00100   //HZ: bug here, we should set the indirect uses e.g., the parameters of
00101   // br.call
00102   
00103   //(c). Don't forget about the Pred
00104   // These can be the uses for the ops
00105   for(src = op->GetPredOprdPtr();
00106         src != NULL; src = src->GetNextOprdPtr()) {
00107         if(src->GetOprdType() != OT_REG)
00108         continue;
00109         use = Use->Lookup(op->GetOpId());
00110         if(Use->NotFound()) {
00111           // Thus the op has no element present in the 
00112           // Def table
00113           use = new struct UseDefOprd;
00114           use->OprdRegNum = src->GetOprdRegNum();
00115           use->OprdFileType = src->GetOprdFileType();
00116           use->next = NULL;
00117           
00118           Use->Set (op->GetOpId(), use);  
00119         } // end if
00120         else {
00121           // If we are here, there is some previous def
00122           // present
00123           while(use->next != NULL)
00124             use = use->next;
00125             
00126             // Now allocate memory for the next
00127             use->next = new struct UseDefOprd;
00128             use->next->OprdRegNum =  src->GetOprdRegNum();
00129             use->next->OprdFileType = src->GetOprdFileType();
00130             use->next->next = NULL;
00131         } // end else
00132   } // end for(src....
00133   
00134 }
00135 
00136 static int 
00137 Redefine(legoOprd *def, legoOp *UseOp)
00138 {
00139         int Redef;
00140         legoOp *op;
00141         legoOprd *dest;
00142         
00143         // Check the redefinition from the 
00144         // def reg of the UseOp to the 
00145         // last of the BB
00146         Redef = 0;
00147         for(op = UseOp; op != NULL; 
00148                 op = op->GetNextLink()) {
00149           for(dest = op->GetDestOprdPtr(); dest != NULL;
00150                 dest = dest->GetNextOprdPtr()) {
00151                 if(dest->GetOprdType() != 
00152                         def->GetOprdType()) continue;
00153                 if(dest->GetOprdFileType() != 
00154                         def->GetOprdFileType()) continue;
00155                 if(dest->GetOprdRegNum() != 
00156                         def->GetOprdRegNum()) continue;
00157                 // if we are here we have a redefinition
00158                 
00159                 Redef = 1;
00160                 break;
00161           }// end for   
00162           if(Redef) break;
00163         } // end for
00164         
00165         return Redef;
00166 }
00167 static  struct UseDefOprd *
00168 AttachOprdInfo(struct UseDefOprd *Live, 
00169                 legoOprd *oprd) {
00170   struct UseDefOprd *temp;
00171   
00172   if(Live != NULL) {
00173   int confidence = 1;
00174      for(temp = Live; temp->next != NULL;
00175         temp = temp->next) {
00176         if(temp->OprdRegNum != oprd->GetOprdRegNum())
00177         continue;
00178         if(temp->OprdFileType != oprd->GetOprdFileType())
00179         continue;
00180         // The live has this oprd
00181         // so need to attach it again
00182         confidence = 0;
00183      } // end for (temp..)
00184      // check again
00185      if(temp->OprdRegNum == oprd->GetOprdRegNum() &&
00186         temp->OprdFileType == oprd->GetOprdFileType())
00187         confidence = 0;
00188      if(confidence) {
00189      temp->next = new struct UseDefOprd;
00190      temp = temp->next;
00191      temp->OprdRegNum = oprd->GetOprdRegNum();
00192      temp->OprdFileType = oprd->GetOprdFileType();
00193      temp->next = NULL;
00194      } // end if
00195   } // end if
00196   else {
00197         Live = new struct UseDefOprd;
00198         Live->OprdRegNum = oprd->GetOprdRegNum();
00199         Live->OprdFileType = oprd->GetOprdFileType();
00200         Live->next = NULL;
00201   }
00202   return Live;          
00203 } 
00204 static struct UseDefOprd *
00205 GetLiveOut(legoOp *LastOp, 
00206         legoOp *StartOp, legoProc *Proc) {
00207  struct UseDefOprd *LiveOut = NULL, *LiveTemp = NULL;
00208  attrs *Attr;
00209  legoOprd *AttrOprd;
00210  opList *opl;
00211  legoOp *PredOp;
00212  opEdges *ControlEdge1;
00213  
00214  if(LastOp->GetOutListPtr() != NULL) {
00215   for(opl = LastOp->GetOutListPtr(); opl != NULL;
00216         opl = opl->GetNextListPtr()) {
00217         PredOp = (legoOp *) opl->GetOpPtr();
00218         // Find the control Edge 
00219         ControlEdge1 = FindControlEdge (LastOp, PredOp);
00220         if(ControlEdge1 == NULL) {
00221          fprintf(stderr, "There is no Ctrl edge between op %d and op %d\n",
00222                 LastOp->GetOpId(), PredOp->GetOpId());
00223          exit(-1);
00224         } // end if
00225         Attr = FindLiveAttribute(ControlEdge1);
00226         for(AttrOprd = Attr->GetAttrOprdPtr(); AttrOprd != NULL;
00227                 AttrOprd = AttrOprd->GetNextOprdPtr()) {
00228           LiveOut = AttachOprdInfo(LiveOut, AttrOprd);
00229         } // end for(AttrOprd....
00230   } // end for(opl...
00231  } // end if
00232  else {
00233    // This can happen if the Region or the BB
00234    // is the end BB of the Proc. We can say
00235    // in other words that this BB ends in
00236    // "br.ret....."
00237    // Now here can be two cases: -
00238    // (a). if there is only one BB
00239    // in the Proc. so the LiveIn will be NULL
00240    // (b) The Proc has more than one BB
00241    // we will have the LiveIn information
00242    
00243    // if we have the Livein information
00244    // we can operations and get the LiveOut
00245    // of the end Op
00246    
00247    // else we will assume that the only Live regs
00248    // are the O/p regs(regs8 to reg12) and traverse 
00249    // the ops to get the LiveOut
00250    if(Proc->GetCount() < 2) {
00251       // we don't have the LiveIn information
00252       // assume that o/p regs are live at the start
00253       // First of all check they are not redefined
00254       // in the BB.
00255       legoOprd *Oprd = new legoOprd;
00256       Oprd->SetOprdType(OT_REG);
00257       Oprd->SetOprdFileType(FT_GPR);
00258       int i;
00259       for(i = 8; i < 12; i++) {
00260          Oprd->SetOprdRegNum(i);
00261          if(1){
00262            LiveOut = AttachOprdInfo(LiveOut, Oprd);
00263          }
00264       } // end for(i....
00265       delete Oprd;
00266    } // end if
00267    else {
00268      // same principle will be applied here
00269      // the only change will be that 
00270      // we are going to take the o/p regs from the LiveIn
00271      for(opl = StartOp->GetInListPtr(); opl != NULL;
00272         opl = opl->GetNextListPtr()) { 
00273         PredOp = (legoOp *) opl->GetOpPtr();
00274         // Find the control Edge 
00275         ControlEdge1 = FindControlEdge (PredOp, StartOp);
00276         if(ControlEdge1 == NULL) {
00277          fprintf(stderr, "There is no Ctrl edge between op %d and op %d\n",
00278                 PredOp->GetOpId(), StartOp->GetOpId());
00279          exit(-1);
00280         } // end if
00281         Attr = FindLiveAttribute(ControlEdge1);
00282         for(AttrOprd = Attr->GetAttrOprdPtr(); AttrOprd != NULL;
00283                 AttrOprd = AttrOprd->GetNextOprdPtr()) {
00284            if(AttrOprd->GetOprdFileType() != FT_GPR)
00285            continue;
00286            if(AttrOprd->GetOprdRegNum() >= 8 &&
00287                 AttrOprd->GetOprdRegNum() <= 11) {
00288              if(1) {
00289              LiveOut = AttachOprdInfo(LiveOut, AttrOprd);
00290             } //end if
00291            } // end if
00292         } // end for(AttrOprd...
00293    }// end for(opl...
00294   } // end else
00295  } // end else
00296  return LiveOut;
00297 }
00298 static  struct UseDefOprd *
00299 AttachLiveOut(struct UseDefOprd *Live, 
00300                 struct UseDefOprd *oprd) {
00301   struct UseDefOprd *temp;
00302   
00303   if(Live != NULL) {
00304      int confidence = 1;
00305      for(temp = Live; temp->next != NULL;
00306         temp = temp->next) {
00307         if(temp->OprdRegNum != oprd->OprdRegNum)
00308         continue;
00309         if(temp->OprdFileType != oprd->OprdFileType)
00310         continue;
00311         // The live has this oprd
00312         // so need to attach it again
00313         confidence = 0;
00314      } // end for (temp..)
00315      // check again
00316      if(temp->OprdRegNum == oprd->OprdRegNum &&
00317         temp->OprdFileType == oprd->OprdFileType)
00318         confidence = 0;
00319      if(confidence) {
00320      temp->next = new struct UseDefOprd;
00321      temp = temp->next;
00322      temp->OprdRegNum = oprd->OprdRegNum;
00323      temp->OprdFileType = oprd->OprdFileType;
00324      temp->next = NULL;
00325     }
00326   } // end if
00327   else {
00328         Live = new struct UseDefOprd;
00329         Live->OprdRegNum = oprd->OprdRegNum;
00330         Live->OprdFileType = oprd->OprdFileType;
00331         Live->next = NULL;
00332   }
00333   return Live;          
00334 } 
00335 static void
00336 SetLiveOut_AllOps(struct UseDefOprd *LiveOut, 
00337         legoOp *LastOp) {
00338   legoOp *op;
00339   struct UseDefOprd *Out, *use, *def, *def1, *In = NULL;
00340   // Now here we will traverse from the last op 
00341   // to the first op. setting LiveOut using Eqn.
00342   // LiveIn = use[i] U (LiveOut[i] - def[i])
00343   
00344   // first of all set LiveOut for the Last Op
00345   L_Out->Set (LastOp->GetOpId(), LiveOut);
00346   // Now traverse Ops
00347   for(op = LastOp; op != NULL;
00348         op = op->GetPrevLink()) {
00349         Out = L_Out->Lookup(op->GetOpId());
00350         if(L_Out->NotFound()) {
00351          fprintf(stderr, "There is something wrong with Live\n");
00352          exit(-1);
00353         }
00354         // Here the main point is that the LiveIn
00355         // of the Op becomes the LiveOut of the Prev 
00356         // Op
00357         if(op->GetPrevLink() != NULL) {
00358            for(;Out != NULL; Out = Out->next) {
00359                 def1 = Def->Lookup(op->GetOpId());
00360                 int confidence = 1;
00361                 if(!Def->NotFound()) {
00362                    for(def = def1; def != NULL; def = def->next) {
00363                       if(def->OprdRegNum != Out->OprdRegNum)
00364                       continue;
00365                       if(def->OprdFileType != Out->OprdFileType)
00366                       continue;
00367                       
00368                       confidence = 0;
00369                       break;
00370                    }// end for(def..
00371                 }// end if
00372                 if(!confidence)
00373                 continue;
00374                 In = AttachLiveOut(In, Out); 
00375            } // end for(Out..
00376            // Now add the uses
00377             use = Use->Lookup(op->GetOpId());
00378             if(!Use->NotFound()) {
00379                 for(; use != NULL; use = use->next) {
00380                   In = AttachLiveOut(In, use);
00381                 } // end for
00382             } // end if
00383             L_Out->Set (((legoOp *) op->GetPrevLink())->GetOpId(),
00384                         In);
00385             In = NULL;
00386         }// end if
00387   } // end for (op..
00388 }
00389 
00390 static void
00391 SetLiveInformation() {
00392   iavector *s;
00393   struct UseDefOprd *liveOprd;
00394   int opid;
00395   for(L_Out->Start(); !(L_Out->AtEnd()); L_Out->Next()){
00396   liveOprd = L_Out->LookupCurrent();
00397   opid = L_Out->GetCurrentKey(); 
00398   while(liveOprd != NULL) {  
00399      switch(liveOprd->OprdFileType)
00400      {
00401         case FT_GPR: s = LiveNess->Lookup(opid);
00402                      if(LiveNess->NotFound()) {
00403                         s = new iavector(MaxGregNum,
00404                                 MaxFregNum, MaxPregNum, MaxBregNum);
00405                         // Now set the bit representing the particular
00406                         // "reg"
00407                         s->SetGreg(liveOprd->OprdRegNum);
00408                         
00409                         LiveNess->Set(opid, s);
00410                      } // end if
00411                      else
00412                      s->SetGreg(liveOprd->OprdRegNum);
00413                      break;
00414         case FT_FPR: s = LiveNess->Lookup(opid);
00415                      if(LiveNess->NotFound()) {
00416                         s = new iavector(MaxGregNum,
00417                                 MaxFregNum, MaxPregNum, MaxBregNum);
00418                         // Now set the bit representing the particular
00419                         // "reg"
00420                         s->SetFreg(liveOprd->OprdRegNum);
00421                         
00422                         LiveNess->Set(opid, s);
00423                      } // end if
00424                      else
00425                      s->SetFreg(liveOprd->OprdRegNum);
00426                      break;
00427         case FT_PR: s = LiveNess->Lookup(opid);
00428                      if(LiveNess->NotFound()) {
00429                         s = new iavector(MaxGregNum,
00430                                 MaxFregNum, MaxPregNum, MaxBregNum);
00431                         // Now set the bit representing the particular
00432                         // "reg"
00433                         s->SetPreg(liveOprd->OprdRegNum);
00434                         
00435                         LiveNess->Set(opid, s);
00436                      } // end if
00437                      else
00438                      s->SetPreg(liveOprd->OprdRegNum);
00439                      break;
00440         case FT_BTR: s = LiveNess->Lookup(opid);
00441                      if(LiveNess->NotFound()) {
00442                         s = new iavector(MaxGregNum,
00443                                 MaxFregNum, MaxPregNum, MaxBregNum);
00444                         // Now set the bit representing the particular
00445                         // "reg"
00446                         s->SetBreg(liveOprd->OprdRegNum);
00447                         
00448                         LiveNess->Set(opid, s);
00449                      } // end if
00450                      else
00451                      s->SetBreg(liveOprd->OprdRegNum);
00452                      break;
00453      }
00454      liveOprd = liveOprd->next;
00455     } // end while
00456   } // end for
00457 }
00458 
00459 static void
00460 PrintLiveNess() {
00461   iavector *s;
00462   for(LiveNess->Start(); !(LiveNess->AtEnd());
00463         LiveNess->Next()) {
00464      printf("\nGetting the liveness information for op %d\n",
00465                 LiveNess->GetCurrentKey());
00466      s = LiveNess->LookupCurrent();
00467      printf("\nGetting the Live Gregs\n");
00468      int i;
00469      for(i = 0; i < s->GetGregSize(); i++) {
00470        if(s->ReadGreg(i))
00471        printf("reg %d\t", i);
00472      } // end for
00473      printf("\nGetting the Live Gregs\n");
00474      for(i = 0; i < s->GetFregSize(); i++) {
00475        if(s->ReadFreg(i))
00476        printf("freg %d\t", i);
00477      } // end for
00478      printf("\nGetting the Live Pregs\n");
00479      for(i = 0; i < s->GetPregSize(); i++) {
00480        if(s->ReadPreg(i))
00481        printf("preg %d\t", i);
00482      } // end for
00483      printf("\nGetting the Live Bregs\n");
00484      for(i = 0; i < s->GetBregSize(); i++) {
00485        if(s->ReadBreg(i))
00486        printf("breg %d\t", i);
00487      } // end for
00488   } // end for
00489 }
00490 
00491 legoHash <int, iavector *, legoHash_lt_int> * 
00492 CompleteLiveNess(legoProc *Proc) {
00493 legoRegion *Region;
00494 legoOp *op, *StartOp, *LastOp;
00495 legoOprd *src, *preg;
00496 struct UseDefOprd *LiveOut;
00497  LiveVariables(Proc);
00498  // Allocate Memory for the Hash Table
00499  LiveNess = new legoHash <int, iavector *, legoHash_lt_int>; 
00500  
00501  // Get the max reg Num of all the file Type
00502  MaxGregNum = FindMaxRegNum (Proc,FT_GPR) + 1;
00503  
00504  //HZ: should cover r8, r9, r10, r11 even the max reg num is less than 8.
00505  if(MaxGregNum < 32) MaxGregNum = 32;
00506  
00507  MaxFregNum = FindMaxRegNum (Proc,FT_FPR) + 1;
00508  MaxPregNum = FindMaxRegNum (Proc,FT_PR) + 1;
00509  MaxBregNum = FindMaxRegNum (Proc,FT_BTR) + 1;
00510  L_Out = new legoHash <int, struct UseDefOprd *, legoHash_lt_int>;
00511  int j;
00512  for(j = 0; j < Proc->GetCount(); j++) {
00513    Region = (legoRegion *) Proc->GetItem(j);
00514    StartOp = (legoOp *) (Region->GetEntryOpsPtr())->GetOpPtr();
00515    LastOp = (legoOp *) (Region->GetExitOpsPtr())->GetOpPtr();
00516            
00517    // Get the LiveOut of the Region
00518    LiveOut = GetLiveOut(LastOp, StartOp, Proc);
00519            
00520    Use = new legoHash <int, struct UseDefOprd *, legoHash_lt_int>;
00521    Def = new legoHash <int, struct UseDefOprd *, legoHash_lt_int>;
00522    int k;
00523    for(k = 0; k < Region->GetCount(); k++) {
00524     op = (legoOp *) Region->GetItem(k);
00525     // Get the use and the definition set of
00526     // each op in the Region or the BB
00527     // store them in the hash table
00528     // The key of the hash table will be the Op
00529     // ids as they are unique, and the list of oprdRegNum
00530     // and the OprdFileType will be stored as elements
00531     SetUsesAndDefs_Op(op);
00532    } // end for(k ...
00533    SetLiveOut_AllOps(LiveOut, LastOp);
00534    // De-allocate Use and Def
00535    for(Use->Start(); !(Use->AtEnd()); Use->Next()) {
00536     delete Use->LookupCurrent();
00537    }
00538    delete Use;
00539    Use = NULL;
00540    for(Def->Start(); !(Def->AtEnd()); Def->Next()) {
00541     delete Def->LookupCurrent();
00542    }
00543    delete Def;
00544    Def = NULL;
00545  }// end for(j...
00546  SetLiveInformation();
00547  #ifdef _LIVE_VAR_DEBUG_
00548   //PrintLiveNess();
00549  printf("Getting Live out information for the Proc %s\n",
00550                 Proc->GetProcName());
00551  for(L_Out->Start(); !(L_Out->AtEnd()); L_Out->Next()) {
00552    struct UseDefOprd *sau =  L_Out->LookupCurrent();
00553    printf("LiveOut for op %d\n", 
00554    L_Out->GetCurrentKey());
00555    while(sau != NULL) {
00556     switch(sau->OprdFileType) {
00557         case FT_GPR: printf("r%d\t",
00558                    sau->OprdRegNum);
00559                    break;
00560         case FT_FPR: printf("f%d\t",
00561                    sau->OprdRegNum);
00562                    break;
00563         case FT_PR: printf("p%d\t",
00564                    sau->OprdRegNum);
00565                    break;
00566         case FT_BTR: printf("b%d\t",
00567                    sau->OprdRegNum);
00568                    break;
00569     }
00570     sau = sau->next;
00571    }
00572    printf("\n");
00573  } 
00574  #endif
00575  for(L_Out->Start(); !(L_Out->AtEnd()); L_Out->Next()) {
00576  delete L_Out->LookupCurrent();
00577  } 
00578  delete L_Out;
00579  L_Out = NULL;
00580  
00581  return LiveNess;
00582 }

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