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

search.C

Go to the documentation of this file.
00001 // search.C
00002 
00003 /*
00004  * LEGO Search Functions
00005  * by Bill Havanki
00006  *
00007  * 7/16/97 WAH:  Created file; added FindParentRegionType.
00008  * 7/17/97 WAH:  Added FindLcAttribute.
00009  * 10/14/97 WAH: Added FindFlag.
00010  * 10/17/97 WAH: Added FindEdgeFrequency.
00011  * 10/28/97 WAH: Added FindLiveAttribute.
00012  * 11/21/97 WAH: Revamped some function calls; added FindLcAttribute for
00013  *               opEdges and FindMaxEdgeAttrId.
00014  * 12/16/97 WAH: Added FindControlEdge.
00015  * 1/14/98 WAH:  Added check for NULL object in FindLcAttribute.
00016  * 1/15/98 WAH:  Added FindFirstBranch.
00017  * 2/11/98 WAH:  Added FindOpWeight.
00018  * 2/12/98 WAH:  Added FindReturnMacro.
00019  * 2/24/98 WAH:  Added IsFallThrough.
00020  * 4/9/98 WAH:   Added FindFreqAttribute.
00021  * 5/6/98 WAH:   Updated classification functions for UDPRED, LDPRED,
00022  *               COPY_B, COPY_H, and COPY_W.
00023  * 02/28/02 HZ:  Updated the IsXXOp functions to the legoOpcode class
00024  */
00025 
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include "lego.H"
00029 #include "search.H"
00030 
00031 // #define SEARCH_DEBUG
00032 #ifdef SEARCH_DEBUG
00033 #define dprintf(s) fprintf s
00034 #define OUTF stderr
00035 #else
00036 #define dprintf(s)
00037 #endif // SEARCH_DEBUG
00038 
00039 // ========================================================================
00040 
00041 /*
00042  * FindMaxOpId
00043  *   proc = procedure to look within
00044  *   returns: legoOp with highest op id, NULL if error
00045  *
00046  * Searches through procedure for op with the highest op id.
00047  */
00048 legoOp *
00049 FindMaxOpId (legoProc *proc)
00050 {
00051   legoOp *allList, *maxop = NULL;
00052   int maxid = -1;
00053 
00054   if (proc->GetRegionType() != RT_PROC)
00055     return NULL;
00056   for (allList = proc->GetListOpPtr();
00057        allList != NULL; allList = allList->GetListOpPtr())
00058     if (allList->GetOpId() > maxid)
00059       {
00060         maxid = allList->GetOpId();
00061         maxop = allList;
00062       } // end if
00063   return maxop;
00064 } // end FindMaxOpId (proc)
00065 
00066 /*
00067  * FindMaxOpId
00068  *   mod = module to look within
00069  *   returns: legoOp with highest op id, NULL if error
00070  *
00071  * Searches through module for op with the highest op id.
00072  *
00073  * If any changes are made to FindMaxOpId, echo them to the copy in
00074  * region.taildup.C (Lego IR).
00075  */
00076 legoOp *
00077 FindMaxOpId (legoModule *mod)
00078 {
00079   legoProc *proc;
00080   legoOp *procop, *maxop = NULL;
00081   int i, maxid = -1;
00082 
00083   if (mod->GetRegionType() != RT_MODULE)
00084     return NULL;
00085   for (i = 0; i < mod->GetCount(); i++)
00086     {
00087       proc = (legoProc *) mod->GetItem(i);
00088       procop = FindMaxOpId (proc);
00089       if (procop != NULL && procop->GetOpId() > maxid)
00090         {
00091           maxid = procop->GetOpId();
00092           maxop = procop;
00093         } // end if
00094     } // end for
00095   return maxop;
00096 } // end FindMaxOpId (mod)
00097 
00098 /*
00099  *      FindMaxRegNum
00100  *      proc_ptr        = the procedure to look in 
00101  *
00102  *
00103  *      Finds the Maximum reg number among all 
00104  *      register files 
00105  *      Regards Rg allocated code 
00106  */ 
00107 
00108 int FindMaxRegNum (legoProc *proc_ptr) 
00109 { 
00110    int          max_id          = 0;
00111    legoOp       *allList        = NULL;
00112    legoOprd     *test_oprd      = NULL;
00113 
00114    if(proc_ptr->GetRegionType() != RT_PROC){
00115         LegoNonFatal("FindMaxRegNum","Warning: find_max_reg_num called for non-procedure.");
00116         return 0;
00117    }
00118    for(allList=proc_ptr->GetListOpPtr();allList!=NULL;allList = allList->GetListOpPtr()){
00119         // Look through all srcs
00120         test_oprd       = allList->GetSrcOprdPtr();
00121         while(test_oprd){
00122                 if(test_oprd->GetOprdType()==OT_REG){ 
00123                         if(test_oprd->GetOprdRegType() == RT_BR){               
00124                                 // In bounded registers, this is the real value  
00125                                 if(test_oprd->GetOprdIntValue()>max_id) max_id  = test_oprd->GetOprdIntValue(); 
00126                         } 
00127                         else    if(test_oprd->GetOprdRegNum()>max_id)   max_id  = test_oprd->GetOprdRegNum();        
00128                 } 
00129                 test_oprd       = test_oprd->GetNextOprdPtr();
00130         }
00131         // ... and all dests
00132         test_oprd       = allList->GetDestOprdPtr();
00133         while(test_oprd){
00134                 if(test_oprd->GetOprdType()==OT_REG){ 
00135                         if(test_oprd->GetOprdRegType() == RT_BR){   
00136                                 if(test_oprd->GetOprdIntValue()>max_id) max_id  = test_oprd->GetOprdIntValue(); 
00137                         } 
00138                         else    if(test_oprd->GetOprdRegNum()>max_id)   max_id  = test_oprd->GetOprdRegNum();        
00139                 } 
00140                 test_oprd       = test_oprd->GetNextOprdPtr();
00141         }
00142    }
00143    return max_id;
00144 }
00145 
00146 /*
00147  *   Same as previous, but looks only through correspondent 
00148  *   file type
00149  */ 
00150 
00151 int FindMaxRegNum (legoProc *proc_ptr,enum fileTypes current_ft)
00152 {
00153    int          max_id          = 0;
00154    legoOp       *allList        = NULL;
00155    legoOprd     *test_oprd      = NULL;
00156 
00157    if(proc_ptr->GetRegionType() != RT_PROC){
00158         LegoNonFatal("FindMaxRegNum","Warning: find_max_reg_num called for non-procedure.");
00159         return 0;
00160    }
00161    for(allList=proc_ptr->GetListOpPtr();allList!=NULL;allList = allList->GetListOpPtr()){
00162         // Look through all srcs
00163         test_oprd       = allList->GetSrcOprdPtr();
00164         while(test_oprd){
00165                 if((test_oprd->GetOprdType() == OT_REG)&&(test_oprd->GetOprdFileType() == current_ft)){ 
00166                         if(test_oprd->GetOprdRegType() == RT_BR){               
00167                                 // In bounded registers, this is the real value
00168                                 if(test_oprd->GetOprdIntValue()>max_id) max_id  = test_oprd->GetOprdIntValue(); 
00169                         } 
00170                         else    if(test_oprd->GetOprdRegNum()>max_id)   max_id  = test_oprd->GetOprdRegNum();        
00171                 } 
00172                 test_oprd       = test_oprd->GetNextOprdPtr();
00173         }
00174         // ... and all dests
00175         test_oprd       = allList->GetDestOprdPtr();
00176         while(test_oprd){
00177                 if((test_oprd->GetOprdType() == OT_REG)&&(test_oprd->GetOprdFileType() == current_ft)){ 
00178                         if(test_oprd->GetOprdRegType() == RT_BR){   
00179                                 if(test_oprd->GetOprdIntValue()>max_id) max_id  = test_oprd->GetOprdIntValue(); 
00180                         } 
00181                         else    if(test_oprd->GetOprdRegNum()>max_id)   max_id  = test_oprd->GetOprdRegNum();        
00182                 } 
00183                 test_oprd       = test_oprd->GetNextOprdPtr();
00184         }
00185    }
00186    return max_id;
00187 }
00188 
00189 // ========================================================================
00190 
00191 /*
00192  * FindMaxEdgeAttrId
00193  *   proc = proc within which to look
00194  *   returns: id of edge or attribute with maximum id, 0 if none found
00195  *
00196  * Searches through the edge and attribute dictionaries of proc and
00197  * returns the id of the edge or attribute with the biggest id.
00198  */
00199 int
00200 FindMaxEdgeAttrId (legoProc *proc)
00201 {
00202   opEdges *edge;
00203   attrs *at;
00204   int maxid = 0;
00205 
00206   // Start by getting dictionaries.
00207   edge = ((legoProc *) proc)->GetEdgeDictionary();
00208   if (edge == NULL)
00209     {
00210       LegoNonFatal ("FindMaxEdgeAttrId", "Edge dictionary is missing.");
00211       return 0;
00212     } // end if
00213   at = ((legoProc *) proc)->GetAttrDictionary();
00214   if (at == NULL)
00215     {
00216       LegoNonFatal ("FindMaxEdgeAttrId", "Attribute dictionary is missing.");
00217       return 0;
00218     } // end if
00219 
00220   for ( ; edge != NULL; edge = edge->GetNextOpEdgePtr())
00221     if (edge->GetEdgeId() > maxid) maxid = edge->GetEdgeId();
00222   for ( ; at != NULL; at = at->GetNextAttrPtr())
00223     if (at->GetAttrId() > maxid) maxid = at->GetAttrId();
00224 
00225   return maxid;
00226 } // end FindMaxEdgeAttrId
00227 
00228 // ========================================================================
00229 
00230 /*
00231  * FindParentRegionType
00232  *   t = type to search for
00233  *   region/op = starting point for parent search
00234  *   returns: region of type t, NULL otherwise
00235  *
00236  * Searches for container of region/op with type t.
00237  */
00238 legoRegion *
00239 FindParentRegionType (enum regionTypes t, legoRegion *region)
00240 {
00241   legoRegion *r;
00242   for (r = region; r != NULL; r = r->GetParentPtr())
00243     if (r->GetRegionType() == t) break;
00244   if (r == NULL) return NULL;
00245   else return (legoProc *) r;
00246 } // end FindParentRegionType (region)
00247 
00248 legoRegion *
00249 FindParentRegionType (legoRegion *region, enum regionTypes t)
00250 {
00251   LegoNonFatal ("FindParentRegionType", "This is a deprecated version of "
00252                 "this function.\nSwap the parameters in the call.");
00253 
00254   return FindParentRegionType (t, region);
00255 }
00256 
00257 legoRegion *
00258 FindParentRegionType (enum regionTypes t, legoOp *op)
00259 {
00260   return FindParentRegionType (t, (legoRegion *) (op->GetParentBlockPtr()));
00261 } // end FindParentRegionType (op)
00262 
00263 legoRegion *
00264 FindParentRegionType (legoOp *op, enum regionTypes t)
00265 {
00266   LegoNonFatal ("FindParentRegionType", "This is a deprecated version of "
00267                 "this function.\nSwap the parameters in the call.");
00268 
00269   return FindParentRegionType (t, op);
00270 }
00271 
00272 // ========================================================================
00273 
00274 /*
00275  * FindFirstBranch
00276  *   region = region within which to search
00277  *   returns: first branch op in region, NULL if no branch found
00278  *
00279  * Runs down the ops of a region and finds the first branch in control
00280  * flow from the first entry op listed.
00281  */
00282 legoOp *
00283 FindFirstBranch (legoRegion *region)
00284 {
00285   opList *opl;
00286   legoOp *opscan;
00287 
00288   opl = region->GetEntryOpsPtr();
00289   if (opl == NULL) return NULL;
00290 
00291   for (opscan = opl->GetOpPtr(); opscan != NULL;
00292        opscan = opscan->GetNextLink())
00293     {
00294       if (opscan->GetOutListPtr() != NULL) return opscan;
00295     } // end for
00296 
00297   return NULL;
00298 } // end FindFirstBranch
00299 
00300 /*
00301  * IsFallThrough
00302  *   src = source op
00303  *   dest = destination op
00304  *   returns: 1 if src can fall-through to dest, 0 otherwise or if error
00305  *
00306  * Determines whether it is possible for control to fall through from
00307  * src directly to dest. src must be a branch, and dest a C_MERGE.
00308  */
00309 int
00310 IsFallThrough (legoOp *src, legoOp *dest)
00311 {
00312   legoOp *walkop;
00313   legoOprd *btr;
00314 
00315   if (src->GetOutListPtr() == NULL)
00316     {
00317       LegoNonFatal ("IsFallThrough", "Source op %d is not a branch!",
00318                     src->GetOpId());
00319       return 0;
00320     } // end if
00321   if (dest->IsCMERGEOp() == false)
00322     {
00323       LegoNonFatal ("IsFallThrough", "Destination op %d is not a merge!",
00324                     dest->GetOpId());
00325       return 0;
00326     } // end if
00327 
00328   // If src is a DUMMY_BR, yes.
00329   if (src->IsDUMMYBROp()) return 1;
00330 
00331   // If dest follows src in the same block, yes.
00332   if (src->GetNextLink() == dest) return 1;
00333 
00334   // If src is a BRU, no.
00335   if (src->IsBRUOp()) return 0;
00336 
00337   // If src is a BRCT or BRCF, walk up to the last PBRR/A. If it prepares
00338   // to branch to the block dest lives in, then it's NOT a fall-through.
00339   if (src->IsBRCONDOp())
00340     {
00341       for (walkop = src->GetPrevLink(); walkop != NULL;
00342            walkop = walkop->GetPrevLink())
00343         {
00344           if (walkop->GetOpcode() == PBRR) break;
00345           if (walkop->GetOpcode() == PBRA) break;
00346         } // end for
00347       if (walkop == NULL)
00348         {
00349           LegoNonFatal ("IsFallThrough", "Can't find PBR before op %d.",
00350                         src->GetOpId());
00351           return 0;
00352         } // end if
00353       btr = walkop->GetSrcOprdPtr();
00354       if (btr == NULL)
00355         {
00356           LegoNonFatal ("IsFallThrough", "No btr operand for op %d.",
00357                         walkop->GetOpId());
00358           return 0;
00359         } // end if
00360       if (btr->GetOprdType() != OT_LITERAL_CB) return 0;  // explicit branch
00361       if (btr->GetLiteralControlBlock() ==
00362           ((legoRegion *) dest->GetParentBlockPtr())->GetRegionId())
00363         return 0;  // the branch is taken to dest, so not fall-thru
00364       return 1;  // else, it is
00365     } // end if (BRCT / BRCF)
00366 
00367   // If haven't figured it out yet, assume it's not a fall-through.
00368   LegoNonFatal ("IsFallThrough", "Don't know how to decide on ops %d and "
00369                 "%d.", src->GetOpId(), dest->GetOpId());
00370   return 0;
00371 } // end IsFallThrough
00372 
00373 // ========================================================================
00374 
00375 /*
00376  * FindControlEdge
00377  *   fromop = op at tail of edge
00378  *   toop = op at head of edge
00379  *   between = whether fromop exits a block and toop enters a block
00380  *   returns: control edge between fromop and toop
00381  *
00382  * Hunts through the edge dictionary to find the first control edge
00383  * between fromop and toop, and returns a pointer to it. If between
00384  * is 1, assumes that fromop is an exit op and toop is an entry op,
00385  * and searches the block edge information only (faster). If that fails,
00386  * the search fails.
00387  */
00388 opEdges *
00389 FindControlEdge (legoOp *fromop, legoOp *toop, int between = 0)
00390 {
00391   opEdges *theedge;
00392 
00393   if (fromop == NULL || toop == NULL)
00394     {
00395       LegoNonFatal ("FindControlEdge", "Passed NULL op.");
00396       return NULL;
00397     } // end if
00398   if (between)
00399     {
00400       legoRegion *fromblock, *toblock;
00401       edgeList *outedges, *inedges;
00402 
00403       fromblock = (legoRegion *) fromop->GetParentBlockPtr();
00404       toblock = (legoRegion *) toop->GetParentBlockPtr();
00405       theedge = NULL;
00406 
00407       if (fromblock == NULL || toblock == NULL)
00408         {
00409           LegoNonFatal ("FindControlEdge", "Can't find parent block of "
00410                         "an op.");
00411         } // end if
00412       else
00413         {
00414           // Search through all of fromblock's exit egdes until the one that
00415           // flows between fromop and toop is found.
00416           for (outedges = fromblock->GetOutEdgesPtr();
00417                outedges != NULL; outedges = outedges->GetNextListPtr())
00418             {
00419               if (outedges->GetEdgePtr()->GetFromOpPtr() != fromop)
00420                 continue;
00421 
00422               for (inedges = toblock->GetInEdgesPtr();
00423                    inedges != NULL; inedges = inedges->GetNextListPtr())
00424                 {
00425                   if (inedges->GetEdgePtr() == outedges->GetEdgePtr())
00426                     {
00427                       theedge = inedges->GetEdgePtr();
00428                       break;
00429                     } // end if
00430                 } // end for
00431 
00432               if (theedge != NULL) return theedge;
00433             } // end for
00434 
00435         } // end else
00436       return NULL;
00437     } // end if
00438 
00439   // We get here if the between test failed. Run through the edge dictionary.
00440   legoProc *proc = (legoProc *) FindParentRegionType (RT_PROC, fromop);
00441   if (proc == NULL)
00442     {
00443       LegoNonFatal ("FindControlEdge", "Couldn;t find proc of op %d.",
00444                     fromop->GetOpId());
00445       return NULL;
00446     } // end if
00447 
00448   for (theedge = proc->GetEdgeDictionary(); theedge != NULL;
00449        theedge = theedge->GetNextOpEdgePtr())
00450     {
00451       if (theedge->GetFromOpPtr() != fromop) continue;
00452       if (theedge->GetToOpPtr() != toop) continue;
00453       if (theedge->GetEdgeType() != ET_CNTL) continue;
00454       // Found it.
00455       return theedge;
00456     } // end for
00457 
00458   // Failed.
00459   return NULL;
00460 } // end FindControlEdge
00461 
00462 // ========================================================================
00463 
00464 /*
00465  * FindLcAttribute
00466  *   lcname = name of lc attribute to search for
00467  *   region/op/edge = where to look for attribute
00468  *   returns: attribute if found, NULL otherwise
00469  *
00470  * Finds the first lc attribute named lcname in the object.
00471  */
00472 static attrs *
00473 FindLcAttribute (char *lcname, void *object, int objtype)
00474 {
00475   attrList *atl;
00476   attrs *a;
00477 
00478   if (object == NULL) return NULL;
00479 
00480   if (objtype == 1)
00481     atl = ((legoRegion *) object)->GetRegionAttrListPtr();
00482   else if (objtype == 0)
00483     atl = ((legoOp *) object)->GetOpAttrListPtr();
00484   else
00485     atl = ((opEdges *) object)->GetEdgeAttrListPtr();
00486 
00487   for ( ; atl != NULL; atl = atl->GetNextListPtr())
00488     if (atl->GetAttrType() == ATTR_LC) break;
00489   if (atl == NULL) return NULL;
00490 
00491   for (a = atl->GetAttrPtr(); a != NULL; a = a->GetNextLcEntryPtr())
00492     if (strcmp (a->GetAttrString(), lcname) == 0) break;
00493 
00494   return a;
00495 } // end FindLcAttribute (object)
00496 
00497 attrs *
00498 FindLcAttribute (char *lcname, legoRegion *region)
00499 {
00500   return FindLcAttribute (lcname, (void *) region, 1);
00501 } // end FindLcAttribute (region)
00502 
00503 attrs *
00504 FindLcAttribute (char *lcname, legoOp *op)
00505 {
00506   return FindLcAttribute (lcname, (void *) op, 0);
00507 } // end FindLcAttribute (op)
00508 
00509 attrs *
00510 FindLcAttribute (char *lcname, opEdges *edge)
00511 {
00512   return FindLcAttribute (lcname, (void *) edge, 2);
00513 } // end FindLcAttribute (edge);
00514 
00515 // ========================================================================
00516 
00517 /*
00518  * FindLiveAttribute
00519  *   edge = edge within which to search
00520  *   returns: live attribute, or NULL if not listed
00521  *
00522  * Returns the live attribute associated with edge.
00523  */
00524 attrs *
00525 FindLiveAttribute (opEdges *edge)
00526 {
00527   attrList *atl;
00528 
00529   for (atl = edge->GetEdgeAttrListPtr(); atl != NULL;
00530        atl = atl->GetNextListPtr())
00531     if (atl->GetAttrType() == ATTR_LIVE)
00532       return atl->GetAttrPtr();
00533 
00534    return NULL;
00535 } // end FindLiveAttribute
00536 
00537 // ========================================================================
00538 
00539 /*
00540  * FindFreqAttribute
00541  *   edge = edge within which to search
00542  *   returns: frequency attribute, or NULL if not listed
00543  *
00544  * Returns the frequency attribute associated with edge.
00545  */
00546 attrList *
00547 FindFreqAttribute (opEdges *edge)
00548 {
00549   attrList *atl;
00550 
00551   if (edge == NULL) return NULL;
00552   for (atl = edge->GetEdgeAttrListPtr(); atl != NULL;
00553        atl = atl->GetNextListPtr())
00554     if (atl->GetAttrType() == ATTR_FREQ) return atl;
00555 
00556   return NULL;
00557 } // end FindFreqAttribute
00558 
00559 // ========================================================================
00560 
00561 /*
00562  * FindEdgeFrequency
00563  *   edge = edge within which to search
00564  *   returns: edge frequency, or -1 if not listed
00565  *
00566  * Returns the frequency of an edge (freq attribute), or -1 if the
00567  * attribute is not present.
00568  */
00569 int
00570 FindEdgeFrequency (opEdges *edge)
00571 {
00572   attrList *atl;
00573 
00574   if (edge == NULL) return -1;
00575 
00576   atl = FindFreqAttribute (edge);
00577   if (atl == NULL) return -1;
00578 
00579   return atl->GetAttrValPtr()->GetAttrValue();
00580 } // end FindEdgeFrequency
00581 
00582 /*
00583  * FindOpWeight
00584  *   op = op for which to get weight
00585  *   returns: true execution frequency of op, -1.0 if an error occurs
00586  *
00587  * Returns the true execution frequency of an op. In a basic block this
00588  * is the same as the basic block's weight, but for a superblock or
00589  * hyperblock it may be less due to side exits above the op.
00590  */
00591 double
00592 FindOpWeight (legoOp *op)
00593 {
00594   legoRegion *pregion;
00595   legoOp *blockop, *prevblockop;
00596   opList *opl;
00597   attrs *a; 
00598   
00599   if (op == NULL)
00600     {
00601       LegoNonFatal ("FindOpWeight", "Passed NULL op.");
00602       return -1.0;
00603     } // end if
00604   pregion = (legoRegion *) op->GetParentBlockPtr();
00605 
00606   // Am I in a basic block? If so, return the block's weight.
00607   if (pregion->GetRegionType() == RT_BB)
00608     return pregion->GetWeight();
00609   // Am I at the top of the block? If so, return the block's weight.
00610   if (op->GetPrevLink() == NULL)
00611     return pregion->GetWeight();
00612 
00613   // If IfConvertHammock or IfConvertTreeBranch was used, use the "orig_wt" 
00614   // attribute that was added to each op
00615   if ((pregion->GetRegionType() == RT_HB) && 
00616       (FindLcAttribute( "use_orig_wt",  pregion) != NULL )) {
00617     // I want the error here if orig_wt not available (it should be)
00618     a = FindLcAttribute( "orig_wt", op ) ;
00619     return (a->GetAttrOprdPtr()->GetLiteralDouble());
00620   }
00621 
00622   // Walk backwards to the last branch or the top of the block,
00623   // whichever comes first.
00624   prevblockop = op;
00625   blockop = op->GetPrevLink();
00626   while (blockop->GetOutListPtr() == NULL && blockop->GetPrevLink() != NULL)
00627     {
00628       //       (m->TinkerOptype (blockop) != BR_OP || blockop->GetOpcode() == BRL
00629       //        || blockop->GetOpcode() == C_MERGE) &&
00630 
00631       prevblockop = blockop;
00632       blockop = blockop->GetPrevLink();
00633     } // end while
00634   dprintf ((OUTF, "Stopped walk at op %d, before op %d.\n",
00635             blockop->GetOpId(), prevblockop->GetOpId()));
00636 
00637   //  if (m->TinkerOptype (blockop) == BR_OP && blockop->GetOpcode() != C_MERGE
00638   //      && blockop->GetOpcode() != BRL)
00639   if (blockop->GetOutListPtr() != NULL)
00640     {  // found branch - get weight of opList pointing into block
00641       for (opl = blockop->GetOutListPtr(); opl != NULL;
00642            opl = opl->GetNextListPtr())
00643         if (opl->GetOpId() == prevblockop->GetOpId())
00644           {
00645             dprintf ((OUTF, "Found fall-through weight %lf.\n",
00646                       opl->GetWeight()));
00647             return opl->GetWeight();
00648           } // end if (, for)
00649       if (opl == NULL)
00650         LegoNonFatal ("FindOpWeight", "Can't find opList from op %d to "
00651                       "op %d.", blockop->GetOpId(), prevblockop->GetOpId());
00652     } // end if
00653   else  // hit top of block - use block weight
00654     {
00655       dprintf ((OUTF, "Hit top - using weight %lf.\n", pregion->GetWeight()));
00656       return pregion->GetWeight();
00657     }
00658   return -1.0;
00659 } // end FindOpWeight
00660 
00661 /*
00662  * FindReturnMacro
00663  *   op = BRL operation
00664  *   returns: macro defined by return from function call, NULL if error
00665  *     or no return value
00666  *
00667  * Returns a pointer to the macro that holds the return value from a
00668  * function call operation (BRL). If op is not a BRL, NULL is returned. If
00669  * op has no return value, NULL is returned as well.
00670  */
00671 legoOprd *
00672 FindReturnMacro (legoOp *op)
00673 {
00674   attrs *retattr;
00675 
00676   if (op->IsBRLOp() == false)
00677     {
00678       LegoNonFatal ("FindReturnMacro", "Op %d not a BRL.", op->GetOpId());
00679       return NULL;
00680     } // end if
00681 
00682   retattr = FindLcAttribute ("ret", op);
00683   if (retattr == NULL) return NULL;
00684 
00685   return retattr->GetAttrOprdPtr();
00686 } // end FindReturnMacro
00687 
00688 // ========================================================================
00689 
00690 /*
00691  * FindFlag
00692  *   name = flag name to find
00693  *   flagiter/op/region = set of flags/op/region in which to search
00694  *   returns: flag if found, NULL otherwise
00695  *
00696  * Searches a set of flags / an op's flags / a region's flags for
00697  * a given flag.
00698  */
00699 flags *
00700 FindFlag (int name, flags *flagiter)
00701 {
00702   flags *f = flagiter;
00703 
00704   for ( ; f != NULL; f = f->GetNextFlagPtr())
00705     if (f->GetFlagName() == name) return f;
00706 
00707   return NULL;   
00708 } // end FindFlag (flags *)
00709 
00710 flags *
00711 FindFlag (int name, legoOp *op)
00712 {
00713   return FindFlag (name, op->GetOpFlagPtr());
00714 } // end FindFlag (op)
00715 
00716 flags *
00717 FindFlag (int name, legoRegion *region)
00718 {
00719   return FindFlag (name, region->GetFlagPtr());
00720 } // end FindFlag (region)
00721 
00722 flags *
00723 FindFlag (flags *flagiter, int name)
00724 {
00725   LegoNonFatal ("FindFlag", "This is a deprecated version of this function.\n"
00726                 "Swap the parameters in the call.");
00727 
00728   return FindFlag (name, flagiter);
00729 }
00730 
00731 flags *
00732 FindFlag (legoOp *op, int name)
00733 {
00734   LegoNonFatal ("FindFlag", "This is a deprecated version of this function.\n"
00735                 "Swap the parameters in the call.");
00736 
00737   return FindFlag (name, op);
00738 }
00739 
00740 flags *
00741 FindFlag (legoRegion *region, int name)
00742 {
00743   LegoNonFatal ("FindFlag", "This is a deprecated version of this function.\n"
00744                 "Swap the parameters in the call.");
00745 
00746   return FindFlag (name, region);
00747 }
00748 
00749 // ========================================================================
00750 
00751 /*
00752  * Is????Op
00753  *   op = op to check
00754  *   returns: 1 if op is of specified type, 0 otherwise
00755  *
00756  * Returns true (1) if op is of a certain classification, and false (0)
00757  * otherwise. The classifications correspond to functional units: an
00758  * integer op is executed on an integer unit, while a load is executed
00759  * on a load (or memory) unit. [Note that comparison opcodes are
00760  * classified both as compares and as either integer or float ops as well.]
00761  */
00762 
00763 static inline int in_range (int x, int a, int b)
00764 {
00765   return (x >= a && x <= b);
00766 } // end in_range
00767 
00768 int IsIntegerOp (legoOp *op)
00769 {
00770     return op->IsIntegerOp();
00771 } // end IsIntegerOp
00772 
00773 int IsFloatOp (legoOp *op)
00774 {
00775     return op->IsFloatOp();
00776 } // end IsFloatOp
00777 
00778 int IsCompareOp (legoOp *op)
00779 {
00780     return op->IsCompareOp();
00781 } // end IsCompareOp
00782 
00783 int IsBranchOp (legoOp *op)
00784 {
00785     return op->IsBranchOp();
00786 } // end IsBranchOp
00787 
00788 int IsBranchOpButNotBRL (legoOp *op)
00789 {
00790     return op->IsBranchOpButNotBRL();
00791 } // end IsBranchOpButNotBRL
00792 
00793 int IsLoadOp (legoOp *op)
00794 {
00795     return op->IsLDOp();
00796 } // end IsLoadOp
00797 
00798 int IsStoreOp (legoOp *op)
00799 {
00800     return op->IsSTOp();
00801 } // end IsStoreOp
00802 
00803 int IsMemoryOp (legoOp *op)
00804 {
00805     return (op->IsLDOp() || op->IsSTOp());
00806 } // end IsMemoryOp
00807 
00808 
00809 //HZ:
00810 //Utility function find_op
00811 //Find the legop ptr to the op with the id in the region
00812 legoOp * find_op(legoRegion * region, int opid)
00813 {
00814     int i;
00815     legoOp *op1 = NULL;
00816     switch(region->GetRegionType())
00817     {
00818         case RT_PROC:
00819         {
00820                 for(i = 0; i < region->GetCount(); i++)
00821                 {
00822                     op1 = find_op((legoRegion *) region->GetItem(i), opid);
00823                     if(op1 != NULL)
00824                         break;
00825                 }
00826                 return op1;
00827                 break;
00828         }
00829         case RT_TREE:
00830         {
00831                 for(i = 0; i < region->GetCount(); i++)
00832                 {
00833                     op1 = find_op((legoRegion *) region->GetItem(i), opid);
00834                     if(op1 != NULL)
00835                         break;
00836                 }
00837                 return op1;
00838                 break;
00839         }
00840         case RT_HB:
00841         case RT_SB:
00842         case RT_BB:
00843         {
00844                 for(i = 0; i < region->GetCount(); i++)
00845                 {
00846                     legoOp * op_ptr = (legoOp *) region->GetItem(i);
00847                     if(op_ptr->GetOpId() == opid)
00848                     {
00849                         op1 = op_ptr;
00850                         break;
00851                     }
00852                 }
00853                 return op1;
00854                 break;
00855         }
00856         
00857     }
00858     return op1;
00859 }
00860 
00861 bool SameOpcode(legoOp *op1, legoOp *op2)
00862 {
00863     if(op1->GetOpcodePtr() == NULL || op2->GetOpcodePtr() == NULL)
00864         return (op1->GetOpcode() == op2->GetOpcode());
00865     else
00866     {
00867         legoOpcode *opc1, *opc2;
00868         opc1 = op1->GetOpcodePtr();
00869         opc2 = op2->GetOpcodePtr();
00870         if(opc1->GetOpcodeClass() == opc2->GetOpcodeClass() &&
00871                 opc1->GetBaseOpcode() == opc2->GetBaseOpcode() ) 
00872         {
00873             switch (opc1->GetOpcodeClass())
00874             {
00875                 case OC_INT:
00876                         return (opc1->GetIaluQuals() == opc2->GetIaluQuals());
00877                         break;
00878                 case OC_PINT:
00879                         return (opc1->GetIsimdQuals() == opc2->GetIsimdQuals());
00880                         break;
00881                 case OC_FP:
00882                         return (opc1->GetFaluQuals() == opc2->GetFaluQuals());
00883                         break;
00884                 case OC_PFP:
00885                         return (opc1->GetFsimdQuals() == opc2->GetFsimdQuals());
00886                         break;
00887                 case OC_CMP:
00888                         return (opc1->GetIcmpQuals() == opc2->GetIcmpQuals());
00889                         break;
00890                 case OC_FCMP:
00891                         return (opc1->GetFcmpQuals() == opc2->GetFcmpQuals());
00892                         break;
00893                 case OC_BR:
00894                         return (opc1->GetBranchQuals() ==
00895                         opc2->GetBranchQuals());
00896                         break;
00897                 case OC_LDST:
00898                         return (opc1->GetImemQuals() == opc2->GetImemQuals());
00899                         break;
00900                 case OC_FPLDST:
00901                         return (opc1->GetFmemQuals() == opc2->GetFmemQuals());
00902                         break;
00903                 case OC_MISC:
00904                         return (opc1->GetMiscQuals() == opc2->GetMiscQuals());
00905                         break;
00906                 default:
00907                         return true;
00908                         break;
00909             }
00910         }
00911         else
00912             return false;
00913     }
00914 }
00915 
00916 //HZ: Testing the legoModule CFG constructions.
00917 //Testing methodology:
00918 //For each function:
00919 //  0. the start op is C_MERGE
00920 //  1. entry/exit op list - of format opList *entryOpsPtr and *exitOpsPtr
00921 //  2. entry/exit edges should be NULL
00922 //  3. region type
00923 //  4. parentPtr should be the legoModule
00924 //  5. parents & children ptr should be NULL
00925 //  6. allListPtr is set
00926 //For each subregion of proc:
00927 //  If the region type is BB:
00928 //    0. the start op is C_MERGE
00929 //    1. entry/exit op list - of format opList *entryOpsPtr and *exitOpsPtr
00930 //                one op for each for BB
00931 //    2. entry/exit edges should be set correctly (see step 5)
00932 //    3. region type
00933 //    4. parentPtr should be set
00934 //    5. parents & children ptr should be set correctly (by checking the entry
00935 //       edges and exit edges)
00936 //    6. allListPtr should be NULL
00937 //  If the region type is Treegion:
00938 //    0. the start op is C_MERGE
00939 //    1. entry/exit op list - of format opList *entryOpsPtr and *exitOpsPtr
00940 //                one op for each for BB
00941 //    2. entry/exit edges should be set correctly (see step 5)
00942 //    3. region type
00943 //    4. parentPtr should be set (Proc)
00944 //    5. parents & children ptr should be set correctly (by checking the entry
00945 //       edges and exit edges)
00946 //    6. allListPtr should set
00947 //For each op in the BB
00948 //    1. if the op is not the entry op or exit op of a region
00949 //          Make sure there is no in edge or out op list
00950 //    2. if the op is the entry op (i.e., C_MERGE),
00951 //          check the in_edges are set correctly (using the entry edge of the
00952 //          parent BB).
00953 //    3. if the op is an exit op (i.e., BR, DUMMYBR, or RTS, also it should be the
00954 //          last op of the parent BB and vise versa), check the Out Op list is
00955 //          set correctly (using the exit edge of the parent BB)
00956 //    4. make sure the prevOpPtr and nextOpPtr are set correctly for each op
00957 //
00958 // Functionality test:
00959 //  1. add ops, remove ops
00960 //  2. duplicate regions
00961 //  3. tree form
00962 //  4. schedule ...
00963 bool legoAudit(legoModule * Module)
00964 {
00965     int i;
00966     if(Module->GetCount() == 0)
00967     {
00968         fprintf(stderr, "legoAudit: warning Empty lego module.\n");
00969         return true;
00970     }
00971     for(i = 0; i < Module->GetCount(); i++)
00972     {
00973         legoProc * proc = (legoProc *) Module->GetItem(i);
00974         //For each function:
00975         //  0. the start op is C_MERGE
00976         assert(proc->GetEntryOpsPtr() != NULL);
00977         legoOp * entry_op = proc->GetEntryOpsPtr()->GetOpPtr();
00978         assert(entry_op->IsCMERGEOp() == true);
00979         //  1. entry/exit op list - of format opList *entryOpsPtr and *exitOpsPtr
00980         if(proc->GetExitOpsPtr() == NULL)
00981         {
00982             fprintf(stderr, "Warning: there seems to be no ret from the proc %s.\n",
00983                     proc->GetProcName());
00984         }
00985         //assert(proc->GetExitOpsPtr() != NULL);
00986         //  2. entry/exit edges should be NULL
00987         assert(proc->GetInEdgesPtr()->GetEdgePtr() == NULL);
00988         assert(proc->GetOutEdgesPtr()->GetEdgePtr() == NULL);
00989         //  3. region type
00990         assert(proc->GetRegionType() == RT_PROC);
00991         //  4. parentPtr should be the legoModule
00992         assert(proc->GetParentPtr() == Module);
00993         //  5. parents & children ptr should be NULL
00994         assert(proc->GetParents() == NULL);
00995         assert(proc->GetChildren() == NULL);
00996         //  6. allListPtr is set
00997         assert(proc->GetListOpPtr() != NULL);
00998         
00999         int j;
01000         for(j = 0; j < proc->GetCount(); j++)
01001         {
01002             legoRegion * region = (legoRegion *) proc->GetItem(j);
01003             if(region->GetRegionType() == RT_BB)
01004             {           
01005                 //For each subregion of proc:
01006                 //  If the region type is BB:
01007                 //    0. the start op is C_MERGE
01008                 legoOp * bb_entry_op = (legoOp *)
01009                         region->GetEntryOpsPtr()->GetOpPtr();
01010                 assert(bb_entry_op->IsCMERGEOp() == true);
01011                 //    1. entry/exit op list - of format opList *entryOpsPtr and *exitOpsPtr
01012                 //                one op for each for BB
01013                 //assert(bb_entry_op == region->GetEntryOpsPtr()->GetOpPtr());
01014                 assert(region->GetEntryOpsPtr()->GetNextListPtr() == NULL);
01015                 
01016                 assert(region->GetExitOpsPtr()->GetNextListPtr() == NULL);              
01017                 //assert(region->GetExitOpsPtr()->GetOpPtr() == region->GetItem(region->GetCount() - 1));
01018 
01019                 //    2. entry/exit edges should be set correctly (see step 5)
01020                 //       make sure the edges correspoond to the parents / children of the BB
01021                 edgeList * bb_in_edges, * bb_out_edges;
01022                 bb_in_edges = region->GetInEdgesPtr();
01023                 bb_out_edges = region->GetOutEdgesPtr();
01024                 if(j != 0) //begining of the proc
01025                 {
01026                     if(bb_in_edges == NULL)
01027                         bb_in_edges = NULL;                 
01028                     assert(bb_in_edges->GetEdgePtr() != NULL);
01029                 }
01030                 if(bb_in_edges != NULL && bb_in_edges->GetEdgePtr() != NULL)
01031                 {
01032                     opEdges * edgep;
01033                     for(; bb_in_edges != NULL; bb_in_edges =
01034                         bb_in_edges->GetNextListPtr())
01035                     {
01036                         edgep = bb_in_edges->GetEdgePtr();
01037                         assert(edgep->GetFromOpId() ==
01038                             edgep->GetFromOpPtr()->GetOpId());
01039                         assert(edgep->GetToOpId() ==
01040                             edgep->GetToOpPtr()->GetOpId());
01041                         assert(edgep->GetToOpPtr() == bb_entry_op);
01042                         int parent_chk = false;
01043                         regionList *pars;
01044                         legoRegion *par;
01045                         for(pars = region->GetParents(); pars != NULL;
01046                             pars = pars->GetNextListPtr())
01047                         {
01048                             par = pars->GetRegionPtr();
01049                             if(edgep->GetFromOpPtr()->GetParentBlockPtr() == par)
01050                             {
01051                                 parent_chk = true;
01052                                 break;
01053                             }
01054                         }
01055                         assert(parent_chk == true);                             
01056                     }
01057                 }
01058                 bool exitBB = false; //exit BB of a proc
01059                 opList * exit_opl = proc->GetExitOpsPtr();
01060                 for(; exit_opl != NULL; exit_opl = exit_opl->GetNextListPtr())
01061                 {
01062                     
01063                     if((exit_opl->GetOpPtr() != 0) && (exit_opl->GetOpPtr()->GetParentBlockPtr() == region))
01064                     {
01065                         exitBB = true;
01066                         break;
01067                     }
01068                     
01069                 }
01070                 //opList *exit_BB_opl = region->GetExitOpsPtr();
01071                 //for(; exit_BB_opl != NULL; exit_BB_opl = exit_BB_opl->GetNextListPtr())
01072                 //{
01073                     
01074                   //  attrs *a = FindLcAttribute("indirect_form", 
01075                   //            (legoOp *)exit_BB_opl->GetOpPtr());
01076                   //  if(!a) continue;
01077                     
01078                   //  exitBB = true;
01079                   //  break;    
01080                 //}
01081                 if(exitBB == false) //last of the proc
01082                 {
01083                     if(bb_out_edges != NULL)
01084                         assert(bb_out_edges->GetEdgePtr() != NULL);
01085                 }
01086                 if(bb_out_edges != NULL && bb_out_edges->GetEdgePtr() != NULL)
01087                 {
01088                     
01089                     opEdges * edgep;
01090                     for(; bb_out_edges != NULL; bb_out_edges =
01091                         bb_out_edges->GetNextListPtr())
01092                     {
01093                         edgep = bb_out_edges->GetEdgePtr();
01094                         assert(edgep->GetFromOpId() ==
01095                             edgep->GetFromOpPtr()->GetOpId());
01096                         assert(edgep->GetToOpId() ==
01097                             edgep->GetToOpPtr()->GetOpId());
01098                         assert(edgep->GetFromOpPtr() == region->GetExitOpsPtr()->GetOpPtr());
01099                         int child_chk = false;
01100                         legoRegion *chd;
01101                         regionList * chdren;
01102                         for(chdren = region->GetChildren(); chdren != NULL;
01103                             chdren = chdren->GetNextListPtr())
01104                         {
01105                             chd = chdren->GetRegionPtr();
01106                             if(edgep->GetToOpPtr()->GetParentBlockPtr() == chd)
01107                             {
01108                                 child_chk = true;
01109                                 break;
01110                             }
01111                         }
01112                         assert(child_chk == true);                              
01113                     }
01114                 }
01115                 
01116                 //    3. region type
01117                 
01118                 //    4. parentPtr should be set
01119                 assert(region->GetParentPtr() != NULL);
01120                 //    5. parents & children ptr should be set correctly (by checking the entry
01121                 //       edges and exit edges) 
01122                 regionList * reg_l;
01123                 for(reg_l = region->GetParents(); reg_l != NULL; reg_l =
01124                         reg_l->GetNextListPtr())
01125                 {
01126                     legoRegion * reg1 = reg_l->GetRegionPtr();
01127                     bool inedge_chk = false;
01128                     edgeList * edge_l;
01129                     for(edge_l = region->GetInEdgesPtr(); edge_l != NULL; edge_l =
01130                             edge_l->GetNextListPtr())
01131                     {
01132                         if(edge_l->GetEdgePtr()->GetFromOpPtr()->GetParentBlockPtr() == reg1)
01133                         {
01134                             inedge_chk = true;
01135                             break;
01136                         }
01137                     }
01138                     assert(inedge_chk == true);
01139                 }
01140                 for(reg_l = region->GetChildren(); reg_l != NULL; reg_l =
01141                         reg_l->GetNextListPtr())
01142                 {
01143                     legoRegion * reg1 = reg_l->GetRegionPtr();
01144                     bool outedge_chk = false;
01145                     edgeList * edge_l;
01146                     for(edge_l = region->GetOutEdgesPtr(); edge_l != NULL; edge_l =
01147                             edge_l->GetNextListPtr())
01148                     {
01149                         if(edge_l->GetEdgePtr()->GetToOpPtr()->GetParentBlockPtr() == reg1)
01150                         {
01151                             outedge_chk = true;
01152                             break;
01153                         }
01154                     }
01155                     assert(outedge_chk == true);
01156                 }
01157                 
01158                 
01159                 //    6. allListPtr should be NULL
01160                 assert(region->GetListOpPtr() == NULL);
01161                 
01162                 //op level checking 
01163                 int k;
01164                 for(legoOp * op = region->GetEntryOpsPtr()->GetOpPtr(); 
01165                         op != NULL; op = op->GetNextLink())
01166                 //              k = 0; k < region->GetCount(); k++)
01167                 {
01168                     //legoOp *op = (legoOp *) region->GetItem(k);
01169                     //For each op in the BB
01170                     //    1. if the op is not the entry op or exit op of a region
01171                     //          Make sure there is no in edge or out op list
01172                     if(op != region->GetEntryOpsPtr()->GetOpPtr()) //(k != 0) 
01173                         assert(op->GetInListPtr() == NULL);
01174                     if(op->GetNextLink() != NULL) //k != region->GetCount() - 1)
01175                     {
01176                         assert(op->GetOutListPtr() == NULL);
01177                         assert(op->IsRETOp() == false && op->IsBRUOp() == false
01178                                 && op->IsBRCONDOp() == false &&
01179                                 op->IsDUMMYBROp() == false);
01180                     }
01181                     //    2. if the op is the entry op (i.e., C_MERGE),
01182                     //          check the in_edges are set correctly (using the entry edge of the
01183                     //          parent BB).
01184                     if(op == region->GetEntryOpsPtr()->GetOpPtr()) //k == 0) //entry op
01185                     {
01186                         assert(op->IsCMERGEOp() == true);
01187                         int num_entry_edges = 0;
01188                         int num_in_ops = 0;
01189                         edgeList * in_edges;
01190                         for(in_edges = ((legoRegion *) op->GetParentBlockPtr())->GetInEdgesPtr();
01191                                     in_edges != NULL; in_edges = in_edges->GetNextListPtr())
01192                         {
01193                             if(in_edges->GetEdgePtr() != NULL)
01194                                 num_entry_edges++;
01195                         }
01196                         opList * ops;
01197                         for(ops = op->GetInListPtr(); ops != NULL; ops = ops->GetNextListPtr())
01198                         {
01199                             if(ops->GetOpPtr() != NULL)
01200                                 num_in_ops++;
01201                         }
01202                         assert(num_in_ops == num_entry_edges);
01203                         
01204                         if(region->GetInEdgesPtr() == NULL || region->GetInEdgesPtr()->GetEdgePtr() == NULL)
01205                             assert(op->GetInListPtr() == NULL || op->GetInListPtr()->GetOpPtr() == NULL);
01206                         if(region->GetInEdgesPtr() != NULL && region->GetInEdgesPtr()->GetEdgePtr() != NULL)
01207                         {
01208                             assert(op->GetInListPtr()->GetOpPtr() != NULL);
01209                             opEdges * edgep;
01210                             edgeList *inedges;
01211                             for(inedges = region->GetInEdgesPtr(); inedges != NULL; inedges =
01212                                  inedges->GetNextListPtr())
01213                             {
01214                                 edgep = inedges->GetEdgePtr();
01215                                 legoOp * from_op = edgep->GetFromOpPtr();
01216                                 bool from_op_chk = false;
01217                                 for(opList * op_l = op->GetInListPtr(); op_l !=
01218                                         NULL; op_l = op_l->GetNextListPtr())
01219                                 {
01220                                     if(from_op == op_l->GetOpPtr())
01221                                     {
01222                                         from_op_chk = true;
01223                                         break;
01224                                     }
01225                                     if(from_op != op_l->GetOpPtr() &&
01226                                         from_op->GetOpId() == op_l->GetOpId())
01227                                     {
01228                                         from_op_chk = true;
01229                                         fprintf(stderr, "legoAudit Warning: Proc name: %s BB %d\n", proc->GetProcName(), region->GetRegionId());
01230                                         fprintf(stderr, " The ops in the parent BB of this BB may have been changed using \
01231 AddItem, AddMidOp, etc. (add/remove op) functions.\n");
01232                                         fprintf(stderr, " Try with write Module out and re-load it in. Then Audit it.\n");  
01233                                         fprintf(stderr, " The reason is that those functions may change the op_ptr in one BB\
01234 while the related oplist keeps the op_ptr when it is constructed.\n");
01235                                     }
01236                                 }
01237                                 assert(from_op_chk == true);
01238                             }
01239                         }                   
01240                     } //entry_op
01241                     
01242                     //    3. if the op is an exit op (i.e., BR, DUMMYBR, or RTS, also it should be the
01243                     //          last op of the parent BB and vise versa), check the Out Op list is
01244                     //          set correctly (using the exit edge of the parent BB)                
01245                     if(op->GetNextLink() == NULL) //k == region->GetCount() - 1) //exit op
01246                     {
01247                         if(!op->IsBRLOp()) //as the proc may end with br.call exit
01248                             assert(op->IsDUMMYBROp() || op->IsBRUOp() || op->IsBRCONDOp() ||
01249                                 op->IsRETOp() || op->IsBreakOp());
01250                         if(op->IsRETOp())
01251                         {
01252                             int num_exit_edges = 0;
01253                             int num_out_ops = 0;
01254                             edgeList * out_edges;
01255                             for(out_edges = ((legoRegion *) op->GetParentBlockPtr())->GetOutEdgesPtr();
01256                                     out_edges != NULL; out_edges = out_edges->GetNextListPtr())
01257                             {
01258                                 if(out_edges->GetEdgePtr() != NULL)
01259                                     num_exit_edges++;
01260                             }
01261                             opList * ops;
01262                             for(ops = op->GetOutListPtr(); ops != NULL; ops = ops->GetNextListPtr())
01263                             {
01264                                 if(ops->GetOpPtr() != NULL)
01265                                     num_out_ops++;
01266                             }
01267                             assert(num_out_ops == num_exit_edges);
01268                             if(op->GetPredOprdPtr() == NULL)
01269                                 assert(num_out_ops == 0);
01270                             else if(op->GetPredOprdPtr()->GetOprdType() !=
01271                                 OT_REG)
01272                                 assert(num_out_ops == 0);
01273                         }
01274                         if(op->IsDUMMYBROp() || op->IsBRUOp())
01275                         {
01276                             int num_exit_edges = 0;
01277                             int num_out_ops = 0;
01278                             edgeList * out_edges;
01279                             
01280                             // We need to add the information here
01281                             for(out_edges = ((legoRegion *) op->GetParentBlockPtr())->GetOutEdgesPtr();
01282                                     out_edges != NULL; out_edges = out_edges->GetNextListPtr())
01283                             {
01284                                 if(out_edges->GetEdgePtr() != NULL)
01285                                     num_exit_edges++;
01286                             }
01287                             opList * ops;
01288                             for(ops = op->GetOutListPtr(); ops != NULL; ops = ops->GetNextListPtr())
01289                             {
01290                                 if(ops->GetOpPtr() != NULL)
01291                                     num_out_ops++;
01292                             }
01293                             assert(num_out_ops == num_exit_edges);
01294                             attrList *atl;
01295                             bool jump_table = false; //switch case structure
01296                             for(atl = op->GetOpAttrListPtr(); atl != NULL; atl =
01297                                     atl->GetNextListPtr())
01298                             {
01299                                 if(atl->GetAttrType() == ATTR_TBLNAME)
01300                                     jump_table = true;
01301                             }
01302                             assert(num_out_ops >= 1);
01303                             if(num_out_ops > 1 && jump_table == false)
01304                             {
01305                                 fprintf(stderr, "legoAudit WARNING: op %d in proc %s may have too many out ops (%d). \n",
01306                                         op->GetOpId(), proc->GetProcName(), num_out_ops);
01307                             }                       
01308                         }
01309                         if(op->IsBRCONDOp())
01310                         {
01311                             int num_exit_edges = 0;
01312                             int num_out_ops = 0;
01313                             edgeList * out_edges;
01314                             for(out_edges = ((legoRegion *) op->GetParentBlockPtr())->GetOutEdgesPtr();
01315                                     out_edges != NULL; out_edges = out_edges->GetNextListPtr())
01316                             {
01317                                 if(out_edges->GetEdgePtr() != NULL)
01318                                     num_exit_edges++;
01319                             }
01320                             opList * ops;
01321                             for(ops = op->GetOutListPtr(); ops != NULL; ops = ops->GetNextListPtr())
01322                             {
01323                                 if(ops->GetOpPtr() != NULL)
01324                                     num_out_ops++;
01325                             }
01326                             assert(num_out_ops == num_exit_edges);
01327                             assert(num_out_ops >= 2);
01328                             if(num_out_ops > 2)
01329                             {
01330                                 fprintf(stderr, "legoAudit warning: op %d in proc %s may have too many out ops (%d).\n",
01331                                         op->GetOpId(), proc->GetProcName(), num_out_ops);
01332                             }                       
01333                         }
01334                         if(region->GetOutEdgesPtr() == NULL || region->GetOutEdgesPtr()->GetEdgePtr() == NULL)
01335                             assert(op->GetOutListPtr() == NULL || op->GetOutListPtr()->GetOpPtr() == NULL);
01336                         if(region->GetOutEdgesPtr() != NULL && region->GetOutEdgesPtr()->GetEdgePtr() != NULL)
01337                         {
01338                             assert(op->GetOutListPtr()->GetOpPtr() != NULL);
01339                             opEdges * edgep;
01340                             edgeList * outedges;
01341                             for(outedges = region->GetOutEdgesPtr(); outedges != NULL; outedges =
01342                                  outedges->GetNextListPtr())
01343                             {
01344                                 edgep = outedges->GetEdgePtr();
01345                                 legoOp * to_op = edgep->GetToOpPtr();
01346                                 bool to_op_chk = false;
01347                                 for(opList * op_l = op->GetOutListPtr(); op_l !=
01348                                         NULL; op_l = op_l->GetNextListPtr())
01349                                 {
01350                                     if(to_op == op_l->GetOpPtr())
01351                                     {
01352                                         to_op_chk = true;
01353                                         break;
01354                                     }
01355                                     if(to_op != op_l->GetOpPtr() &&
01356                                         to_op->GetOpId() == op_l->GetOpId())
01357                                     {
01358                                         to_op_chk = true;
01359                                         fprintf(stderr, "legoAudit Warning: Proc name: %s BB %d\n", proc->GetProcName(), region->GetRegionId());
01360                                         fprintf(stderr, " The ops in the child BB of this BB may have been changed using \
01361 AddItem, AddMidOp, etc. (add/remove op)functions.\n");
01362                                         fprintf(stderr, " Try with write Module out and re-load it in. Then Audit it.\n");  
01363                                         fprintf(stderr, " The reason is that those functions may change the op_ptr in one BB\
01364 while the related oplist keeps the op_ptr when it is constructed.\n");
01365                                     }
01366                                     
01367                                 }
01368                                 assert(to_op_chk == true);
01369                             }
01370                         }
01371                     }//exit op
01372                     
01373                     //    4. make sure the prevOpPtr and nextOpPtr are set correctly for each op. also check those control
01374                     //       relationship appear in the edge dictionary
01375                     if(op != region->GetEntryOpsPtr()->GetOpPtr())
01376                     {
01377                          assert(op->GetPrevLink() != NULL);
01378                          assert(FindControlEdge(op->GetPrevLink(), op) != NULL);
01379                     }
01380                     else
01381                     {
01382                          assert(op->GetPrevLink() == NULL);
01383                         //may be multiple edges pointing to it. But the entry edges checking should take care of it
01384                     }
01385                     opList * opl1;
01386                     bool proc_exit = false;
01387                     for(opl1 = region->GetExitOpsPtr(); opl1 != NULL; opl1 =
01388                             opl1->GetNextListPtr())
01389                     {
01390                         if(op == opl1->GetOpPtr())
01391                         {
01392                             proc_exit = true;
01393                             break;
01394                         }
01395                     }
01396                     if(proc_exit == false)
01397                     {
01398                         assert(op->GetNextLink() != NULL);
01399                         assert(FindControlEdge(op, op->GetNextLink()) != NULL);
01400                     }
01401                     else 
01402                     {
01403                         assert(op->GetNextLink() == NULL);                                                  
01404                         //there may be multiple control edges from this op. But the exit edges checking should take care of
01405                         //it.
01406                     }
01407                     
01408                     //    5. Make sure each op appeared at least in one control edges
01409                     //       For CMERGE op, it may be to_op of N (>=0) edges
01410                     //       For proc exit ops including RTS ops, it may be to_op of 1 edge and from op of 0 edge.
01411                     //       For BRCOND op, it may be to_op of 1 edge and from_op of 2 edges
01412                     //       For other ops, it should be to_op of 1 edge and from_op of 1 edge.
01413                 }//op level
01414             }//BB level
01415             if(region->GetRegionType() == RT_TREE)
01416             {
01417                 //  If the region type is Treegion:
01418                 //    0. the start op is C_MERGE
01419                 //    1. entry/exit op list - of format opList *entryOpsPtr and *exitOpsPtr
01420                 //                one op for each for BB
01421                 //    2. entry/exit edges should be set correctly (see step 5)
01422                 //    3. region type
01423                 //    4. parentPtr should be set (Proc)
01424                 //    5. parents & children ptr should be set correctly (by checking the entry
01425                 //       edges and exit edges)
01426                 //    6. allListPtr should set
01427                 fprintf(stderr, "legoAudit: treegions have not been tested.\n");
01428 
01429             } //treegion level
01430         }//region level
01431         
01432         //check control edges
01433         opEdges * edge;
01434                 
01435         for(edge = proc->GetEdgeDictionary(); edge != NULL; edge =
01436                         edge->GetNextOpEdgePtr())
01437         {
01438             int from_op_id = edge->GetFromOpId();
01439             int to_op_id = edge->GetToOpId();
01440             legoOp * from_op, *to_op;
01441             from_op = find_op(proc, from_op_id); 
01442             assert(from_op != NULL);
01443             //this fromop may not be same as edge->GetFromOpPtr()
01444             // due to the addItem() addMidOps function calls/
01445             //So here we take a conservative approach
01446             to_op = find_op(proc, to_op_id);
01447             assert(to_op != NULL);
01448             if(((legoRegion *)from_op->GetParentBlockPtr())->GetRegionId() != 
01449                         ((legoRegion *)to_op->GetParentBlockPtr())->GetRegionId() )
01450             {
01451                 //inter block edges: check the Freq Attr
01452                 assert(edge->GetEdgeAttrListPtr() != NULL);
01453                 //also make sure this edge appears in entry edges and exit edges
01454                 edgeList * in_edges = ((legoRegion *)to_op->GetParentBlockPtr())->GetInEdgesPtr();
01455                 bool ck_edges = false;
01456                 for(; in_edges != NULL; in_edges = in_edges->GetNextListPtr())
01457                 {
01458                     if(edge == in_edges->GetEdgePtr())
01459                     {
01460                         ck_edges = true;
01461                         break;
01462                     }
01463                 }
01464                 if(ck_edges == false)
01465                 {
01466                     ck_edges = false;
01467                 }
01468                 assert(ck_edges == true);
01469                 ck_edges = false;
01470                 edgeList * out_edges = ((legoRegion *)from_op->GetParentBlockPtr())->GetOutEdgesPtr();
01471                 for(; out_edges != NULL; out_edges = out_edges->GetNextListPtr())
01472                 {
01473                     if(edge == out_edges->GetEdgePtr())
01474                     {
01475                         ck_edges = true;
01476                         break;
01477                     }
01478                 }
01479                 assert(ck_edges == true);
01480             }
01481         }
01482         
01483         //check  the listOpPtr of the proc and the ops
01484         legoOp * allList;
01485         int op_count1 = 0;
01486         for(allList=proc->GetListOpPtr();allList!=NULL;allList = allList->GetListOpPtr())
01487         {
01488             op_count1++;
01489         }
01490         int op_count2 = 0;
01491         for(int rc = 0; rc < proc->GetCount(); rc++)
01492         {
01493             op_count2 += ((legoRegion *)proc->GetItem(rc))->GetCount();
01494         }
01495         assert(op_count1 == op_count2);
01496         
01497     }//proc level
01498     
01499     
01500     //functionality test
01501     
01502     return true;
01503 }
01504 
01505 int FindFirstOutGoingReg(legoProc *Proc)
01506 {
01507         legoRegion *Region;
01508         legoOp *op;
01509         legoOprd *src;
01510         
01511         int Reg = 31;
01512         
01513         op = Proc->GetEntryOpsPtr()->GetOpPtr(); //C_MERGE op
01514         op = op->GetNextLink(); //this one should be the alloc if there is one
01515         
01516         //go through the first BB as scheduling may change its position although
01517         // it should be scheduled right after the C_MERGE
01518         for(; op != NULL; op = op->GetNextLink())
01519         {
01520             if(op->IsAllocOp())
01521                 break;
01522         }
01523         
01524         if(op == NULL || !op->IsAllocOp())
01525         {
01526                 LegoNonFatal ("FindFirstOutGoingReg", "This Proc %s has no alloc instruction.\n",
01527                         Proc->GetProcName());           
01528                 return (-1); 
01529         }
01530         
01531         src = op->GetSrcOprdPtr();
01532         
01533         // Now point towards the number of incoming
01534         // regs.
01535         src = src->GetNextOprdPtr();
01536         Reg = Reg + src->GetLiteralLongLong();
01537         
01538         // Now point towards the number of locals
01539         src = src->GetNextOprdPtr();
01540         Reg = Reg + src->GetLiteralLongLong();
01541         
01542         // Here the (Reg + 1) will be having the starting 
01543         // o/p register, so return it.
01544         
01545         return (Reg + 1); 
01546         
01547 } 
01548 
01549 int FindLastOutGoingReg(legoProc *Proc)
01550 {
01551         legoRegion *Region;
01552         legoOp *op;
01553         legoOprd *src;
01554         
01555         int Reg = 31;
01556         
01557         op = Proc->GetEntryOpsPtr()->GetOpPtr(); //C_MERGE op
01558         op = op->GetNextLink(); //this one should be the alloc if there is one
01559         
01560         
01561         //go through the first BB as scheduling may change its position although
01562         // it should be scheduled right after the C_MERGE
01563         for(; op != NULL; op = op->GetNextLink())
01564         {
01565             if(op->IsAllocOp())
01566                 break;
01567         }
01568         
01569         if(op == NULL || !op->IsAllocOp())
01570         {
01571                 LegoNonFatal ("FindLastOutGoingReg", "This Proc %s has no alloc instruction.\n",
01572                         Proc->GetProcName());           
01573                 return (-2); 
01574         }
01575         
01576         src = op->GetSrcOprdPtr();
01577         
01578         // Now point towards the number of incoming
01579         // regs.
01580         src = src->GetNextOprdPtr();
01581         Reg = Reg + src->GetLiteralLongLong();
01582         
01583         // Now point towards the number of locals
01584         src = src->GetNextOprdPtr();
01585         Reg = Reg + src->GetLiteralLongLong();
01586         
01587         // Now point towards the number of outgoing Regs
01588         src = src->GetNextOprdPtr();
01589         Reg = Reg + src->GetLiteralLongLong();
01590         
01591         // Here the (Reg) will be having the ending 
01592         // o/p register, so return it.
01593         
01594         return (Reg); 
01595         
01596 } 

Generated on Mon Jul 21 20:28:55 2003 for TINKER LEGO DOC by doxygen 1.3.2