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

region.C

Go to the documentation of this file.
00001 /*--------------------------------------------------------------------
00002  *
00003  *  region.cpp
00004  *
00005  *  Willie Glover
00006  *
00007  *  12/09/96 WAH: Added tail duplication method.
00008  *  2/13/97 WAH:  Made name change from legoRegionRef to regionList et al.
00009  *  2/28/97 WAH:  Modified GetParents and GetChildren to return regions
00010  *                of the same type only.
00011  *  3/4/97 WAH:   Fixed said modifications to actually work. :)
00012  *  3/20/97 WAH:  Added markfield to legoRegion.
00013  *  3/21/97 WAH:  Copy constructor now adds copy to parent region.
00014  *  4/10/97 WAH:  Added OpKiller and RegionKiller methods.
00015  *  4/11/97 WAH:  Fixed destructor to invalidate children of this'
00016  *                parents and parents of this' children.
00017  *  7/11/97 WAH:  Deconstructor won't remove parents/children of self
00018  *                if self is child/parent.
00019  *  9/3/97 WAH:   Fixed region deconstructor to delete modules correctly.
00020  *  4/22/98 WAH:  Moved FindMaxRegionId here from region.taildup.C.
00021  *-------------------------------------------------------------------*/
00022 
00023 #ifndef LEGOREGION_H
00024 #include "region.H"
00025 #include "flag.H"
00026 #endif
00027 
00028 //void LegoErr(char*);
00029 
00030 legoRegion::legoRegion (enum regionTypes rType, unsigned id)
00031              : legoPSet<void *>()
00032 {
00033   //  fprintf(stderr,"Creating LEGOREGION %p\n",this);
00034   regionId              = id;
00035   regionType            = rType;        // region type
00036   inEdgesPtr            = NULL;         // ptr to list of (op,flowfreq)
00037   outEdgesPtr           = NULL;         // ptr to list of (op,flowfreq)
00038   flagPtr               = NULL;         // ptr to list of region flags
00039   entryOpsPtr           = NULL;         // ptr to list of entry ops
00040   exitOpsPtr            = NULL;         // ptr to list of exit ops
00041   regionAttrListPtr     = NULL;         // ptr to attribute list
00042   weight                = 0;            // ptr to next op in prog flow
00043   parentPtr             = NULL;         // ptr to parent region
00044   parents = children    = NULL;         // ptrs in control flow
00045   dominators            = NULL;         // ptr to dominators
00046   allListPtr            = NULL;         // ptr to list of all ops
00047   markfield             = (long long)0; // array of bits to mark
00048   nestingLevel          = -1;           // level of loop nesting
00049 }
00050 
00051 legoRegion::legoRegion () : legoPSet<void *>()
00052 {
00053   //  fprintf(stderr,"Creating LEGOREGION %p\n",this);
00054   regionId              = 0;            // mark as unintialized
00055   regionType            = RT_BB;                // default to basic block
00056   inEdgesPtr            = NULL;         // ptr to list of (op,flowfreq)
00057   outEdgesPtr           = NULL;         // ptr to list of (op,flowfreq)
00058   flagPtr               = NULL;         // ptr to list of region flags
00059   entryOpsPtr           = NULL;         // ptr to list of entry ops
00060   exitOpsPtr            = NULL;         // ptr to list of exit ops
00061   regionAttrListPtr     = NULL;         // ptr to attribute list
00062   weight                = 0;            // ptr to next op in prog flow
00063   parentPtr             = NULL;         // ptr to parent region
00064   parents = children    = NULL;         // ptrs in control flow
00065   dominators            = NULL;         // ptr to dominators
00066   allListPtr            = NULL;         // ptr to list of all ops
00067   markfield             = (long long)0; // array of bits to mark
00068   nestingLevel          = -1;           // level of loop nesting
00069 }
00070 
00071 legoRegion::legoRegion (const legoRegion &orig) :
00072   legoPSet<void *> ((legoPSet<void *>) orig)
00073 {
00074   //  fprintf(stderr,"Creating LEGOREGION %p\n",this);
00075   regionId      = orig.regionId;  // will be changed anyway
00076   regionType    = orig.regionType;
00077 
00078   if (orig.inEdgesPtr != NULL)
00079         inEdgesPtr = new edgeList (*(orig.inEdgesPtr));
00080   else  inEdgesPtr = NULL; 
00081 
00082   if (orig.outEdgesPtr != NULL)
00083         outEdgesPtr = new edgeList (*(orig.outEdgesPtr));
00084   else  outEdgesPtr = NULL; 
00085 
00086   if (orig.flagPtr != NULL)
00087         flagPtr = new flags (*(orig.flagPtr));
00088   else  flagPtr = NULL; 
00089 
00090   if (orig.entryOpsPtr != NULL)
00091         entryOpsPtr = new opList (*(orig.entryOpsPtr));
00092   else  entryOpsPtr = NULL; 
00093 
00094   if (orig.exitOpsPtr != NULL)
00095         exitOpsPtr = new opList (*(orig.exitOpsPtr));
00096   else  exitOpsPtr = NULL; 
00097 
00098   if (orig.regionAttrListPtr != NULL)
00099         regionAttrListPtr = new attrList (*(orig.regionAttrListPtr));
00100   else  regionAttrListPtr = NULL; 
00101 
00102   weight        = orig.weight;
00103   parentPtr     = orig.parentPtr;
00104   parents       = NULL;                 // don't bother copying - will be constructed on demand
00105   children      = NULL;
00106   dominators    = NULL;                 // don't bother copying - will be wrong anyway
00107   allListPtr    = orig.allListPtr;
00108   markfield     = orig.markfield;
00109   nestingLevel  = orig.nestingLevel;
00110   DAG           = NULL;                 // since can be anything, don't want to copy construct
00111 
00112   if (parentPtr != NULL)
00113     parentPtr->AddItem (this);
00114 } // end copy constructor
00115 
00116 legoRegion::~legoRegion()
00117 {
00118   regionList *rl;
00119   legoRegion *r, *rp;
00120 
00121   Mark (RM_KISSOFDEATH);
00122   delete flagPtr;
00123   delete entryOpsPtr;
00124   delete exitOpsPtr;
00125   delete regionAttrListPtr;
00126 
00127   // Destroy the parent/children lists of surrounding regions, so they
00128   // don't continue pointing to this. However, don't bother if the
00129   // encompassing proc is marked for death, since we're bound to end up
00130   // pointing to something that was just deleted.
00131 
00132   for (r = this; r->regionType != RT_PROC; r = r->parentPtr)
00133     if (r->regionType == RT_MODULE) break;
00134   if (!(r->IsMarked (RM_KISSOFDEATH)))
00135     {
00136       // Need to get to all parents, so construct list now!
00137       for (rl = GetParents(); rl != NULL; rl = rl->GetNextListPtr())
00138         {  // loop through parents of this one
00139           r = rl->GetRegionPtr();
00140           if (r != NULL && r != this)
00141             {
00142               delete r->children;  // delete children list
00143               r->children = NULL;
00144             } // end if
00145           for (rp = r->parentPtr; rp->regionType != RT_PROC;
00146                rp = rp->parentPtr)  // loop through containers of parent
00147             {
00148               delete rp->children;  // delete container's children list
00149               rp->children = NULL;
00150             } // end for
00151         } // end for
00152       delete parents;
00153       // Need to get to all children, so construct list now!
00154       for (rl = GetChildren(); rl != NULL; rl = rl->GetNextListPtr())
00155         {  // sim. for children of this one
00156           r = rl->GetRegionPtr();
00157           if (r != NULL && r != this)
00158             {
00159               delete r->parents;
00160               r->parents = NULL;
00161             } // end if
00162           for (rp = r->parentPtr; rp->regionType != RT_PROC;
00163                rp = rp->parentPtr)
00164             {
00165               delete rp->parents;
00166               rp->parents = NULL;
00167             } // end for
00168         } // end for
00169       delete children;
00170     } // end if
00171   else
00172     {
00173       delete parents;
00174       delete children;
00175     } // end else
00176   delete dominators;
00177   delete inEdgesPtr;
00178   delete outEdgesPtr;
00179 
00180   // Don't call Keeler - they're void *.
00181   //  fprintf(stderr,"Deleting LEGOREGION %p\n",this);
00182 } // end destructor
00183 
00184 /*
00185  * RefreshAll
00186  *
00187  * Calls RefreshOpsAndEdges on all contained regions, then self.
00188  */
00189 void
00190 legoRegion::RefreshAll (void)
00191 {
00192   if (!(IS_BLOCK(regionType)))
00193     for (unsigned i = 0; i < GetCount(); i++)
00194       ((legoRegion *) GetItem (i))->RefreshAll();
00195 
00196   RefreshOpsAndEdges();
00197   return;
00198 } // end RefreshAll
00199 
00200 /*------------------------------------------------------------------
00201  *   Name:        RegionMap.C
00202  *   Designer:    Willie Glover
00203  *   Created:     4/24/96
00204  *   Description: This file maps legoRegion's char*.
00205  *------------------------------------------------------------------
00206  *
00207  *-----------------------------------------------------------------*/
00208 
00209 static const char * const regionNames[] = {
00210   "proc",  "bb",  "hb",  "sb",  "loop",  "loopbody", "trace",
00211   "module", "tree", ""
00212 };
00213 char *RegionMap(int rType)
00214 {
00215   char *regionName;
00216 
00217   regionName = const_cast<char *>(regionNames[rType]);
00218   return regionName;
00219 }
00220 
00221 /*------------------------------------------------------------------
00222  *   Name:        FindOpId.C
00223  *   Designer:    Willie Glover
00224  *   Created:     6/27/96
00225  *   Description: input is opId.  output in legoOp*. Start the search 
00226  *                at the first op in this region (use allListPtr).
00227  *------------------------------------------------------------------
00228  *
00229  *-----------------------------------------------------------------*/
00230 legoOp *legoRegion::FindOpId(int currOpId)
00231 {
00232   legoOp *returnOpPtr = NULL;
00233   legoOp *firstOpPtr = NULL;
00234   legoRegion *nextRegionPtr = NULL;
00235   switch (this->regionType) {
00236     case RT_PROC:
00237        nextRegionPtr = (legoRegion *)GetItem(0);
00238        if ( nextRegionPtr == NULL) { return returnOpPtr; }
00239        while ( (nextRegionPtr->regionType == RT_PROC) ||
00240                (nextRegionPtr->regionType == RT_LOOPBODY) ) {
00241         // fprintf(stderr,"in 1st FindOpId while block/n");
00242          nextRegionPtr = (legoRegion *)nextRegionPtr->GetItem(0);
00243        }
00244        firstOpPtr = (legoOp *)nextRegionPtr->GetItem(0);
00245        break;
00246     case RT_BB:
00247        firstOpPtr = (legoOp *)GetItem(0);
00248        break;
00249     case RT_HB:
00250        firstOpPtr = (legoOp *)GetItem(0);
00251        break;
00252     case RT_SB:
00253        firstOpPtr = (legoOp *)GetItem(0);
00254        break;
00255     case RT_LOOP:
00256        firstOpPtr = (legoOp *)GetItem(0);
00257        break;
00258     case RT_LOOPBODY:
00259        nextRegionPtr = (legoRegion *)GetItem(0);
00260        if ( nextRegionPtr == NULL) { return returnOpPtr; }
00261        while ( (nextRegionPtr->regionType == RT_PROC) ||
00262                (nextRegionPtr->regionType == RT_LOOPBODY) ) {
00263         // fprintf(stderr,"in 2nd FindOpId while block/n");
00264          nextRegionPtr = (legoRegion *)nextRegionPtr->GetItem(0);
00265        }
00266        firstOpPtr = (legoOp *)nextRegionPtr->GetItem(0);
00267        break;
00268     default:
00269        return returnOpPtr;
00270        break;
00271   }
00272   returnOpPtr = firstOpPtr;
00273   while ( currOpId != returnOpPtr->GetOpId() ) {
00274         // fprintf(stderr,"  opPtr =%p",returnOpPtr);
00275         // fprintf(stderr,"opId =%d/n",returnOpPtr->GetOpId());
00276     returnOpPtr = returnOpPtr->GetListOpPtr();
00277     if (returnOpPtr == NULL) { return returnOpPtr; }
00278   }
00279     return returnOpPtr;
00280 }
00281 
00282 //---------------------------------------------------------------------------
00283 
00284 regionList *
00285 legoRegion::GetParents (void)
00286 {
00287   edgeList *inedgelist, *scan;
00288   opEdges *inedge;
00289   legoOp *prevop;
00290   legoRegion *prevopparent;
00291   regionList *head = NULL, *current;
00292 
00293   if (parents != NULL)  // already built parent list
00294     return parents;
00295   // else build on demand
00296 
00297   inedgelist = GetInEdgesPtr();
00298   if (inedgelist != NULL)  // otherwise, no in edges = no parents
00299     {
00300       for (scan = inedgelist, inedge = scan->GetEdgePtr();
00301            inedge != NULL;
00302            inedge = scan->GetEdgePtr())  // ( don't update scan here)
00303         {
00304           prevop = inedge->GetFromOpPtr();
00305           if (prevop != NULL)  // otherwise, skip if missing op
00306             {
00307               prevopparent = (legoRegion *) prevop->GetParentBlockPtr();
00308               while (prevopparent->GetRegionType() != RT_MODULE)
00309                 {
00310                   if ((prevopparent->GetRegionType() == regionType) ||
00311                       (IS_BLOCK(prevopparent->GetRegionType()) &&
00312                        IS_BLOCK(regionType)))
00313                     {
00314                       current = new regionList (prevopparent);
00315 
00316                       if (head != NULL)
00317                         head->Concatenate (current);
00318                       else
00319                         head = current;
00320                       break;
00321                     } // end if
00322                   prevopparent = prevopparent->GetParentPtr();
00323                 } // end while
00324             } // end if
00325                         
00326           // Advance scan and check for NULL.
00327           scan = scan->GetNextListPtr();
00328           if (scan == NULL)
00329             break;
00330         } // end for
00331     } // end if
00332 
00333   parents = head;
00334   return head;
00335 } // end legoRegion::GetParents
00336 
00337 void legoRegion::SetParents (regionList *p)
00338 {
00339   delete parents;
00340   parents = p;
00341 } // end SetParents
00342 
00343 regionList *
00344 legoRegion::GetChildren (void)
00345 {
00346   edgeList *outedgelist, *scan;
00347   opEdges *outedge;
00348   legoOp *nextop;
00349   legoRegion *nextopparent;
00350   regionList *head = NULL, *current;
00351 
00352   if (children != NULL)  // already built children list
00353     return children;
00354   // else build on demand
00355 
00356   outedgelist = GetOutEdgesPtr();
00357   if (outedgelist != NULL)  // otherwise, no out edges = no children
00358     {
00359       for (scan = outedgelist, outedge = scan->GetEdgePtr();
00360            outedge != NULL;
00361            outedge = scan->GetEdgePtr())  // ( don't update scan here)
00362         {
00363           nextop = outedge->GetToOpPtr();
00364           if (nextop != NULL)  // otherwise, skip if missing op
00365             {
00366               nextopparent = (legoRegion *) nextop->GetParentBlockPtr();
00367               while (nextopparent->GetRegionType() != RT_MODULE)
00368                 {
00369                   if ((nextopparent->GetRegionType() == regionType) ||
00370                       (IS_BLOCK(nextopparent->GetRegionType()) &&
00371                        IS_BLOCK(regionType)))
00372                     {
00373                       current = new regionList (nextopparent);
00374 
00375                       if (head != NULL)
00376                         head->Concatenate (current);
00377                       else
00378                         head = current;
00379                       break;
00380                     } // end if
00381                   nextopparent = nextopparent->GetParentPtr();
00382                 } // end while
00383             } // end if
00384                         
00385           // Advance scan and check for NULL.
00386           scan = scan->GetNextListPtr();
00387           if (scan == NULL)
00388             break;
00389         } // end for
00390     } // end if
00391 
00392   children = head;
00393   return head;
00394 } // end legoRegion::GetChildren
00395 
00396 void legoRegion::SetChildren (regionList *c)
00397 {
00398   delete children;
00399   children = c;
00400 } // end SetChildren
00401 
00402 /*
00403  * legoRegion::IsContainedIn
00404  *   r = region being searched for
00405  *
00406  * Returns whether this region is contained in r. By definition, a
00407  * region contains itself.
00408  */
00409 int
00410 legoRegion::IsContainedIn (legoRegion *r)
00411 {
00412   legoRegion *parent;
00413 
00414   for (parent = this; parent != NULL; parent = parent->GetParentPtr())
00415     {
00416       if (parent == r)
00417         return 1;
00418     } // end for
00419 
00420   return 0;
00421 } // end legoRegion::IsContainedIn
00422 
00423 /*
00424  * legoRegion::Contains
00425  *   r = region being searched for
00426  *
00427  * Returns whether this region contains r. By definition, a region
00428  * contains itself.
00429  */
00430 int
00431 legoRegion::Contains (legoRegion *r)
00432 {
00433   return (r->IsContainedIn (this));
00434 }
00435 
00436 //---------------------------------------------------------------------------
00437 
00438 /*
00439  * FindMaxRegionId
00440  *   reg = region to look within
00441  *   returns: the region with the largest id within it
00442  *
00443  * Finds the largest region id within the given region.
00444  */
00445 legoRegion *
00446 legoRegion::FindMaxRegionId (void)
00447 {
00448   int i;
00449   legoRegion *block, *maxblock = NULL, *candblock;
00450 
00451   for (i = 0; i < GetCount(); i++)
00452     {
00453       block = (legoRegion *) GetItem(i);
00454       if (!(IS_BLOCK(block->GetRegionType())))
00455         candblock = block->FindMaxRegionId();
00456       else
00457         candblock = block;
00458       if ((maxblock == NULL) ||
00459           (candblock->GetRegionId() > maxblock->GetRegionId()))
00460         maxblock = candblock;
00461     } // end for
00462 
00463   // Also check yourself!
00464   if (this->GetRegionType() != RT_PROC &&
00465       this->GetRegionType() != RT_MODULE &&
00466       this->GetRegionId() > maxblock->GetRegionId())
00467     maxblock = this;
00468 
00469   return maxblock;
00470 } // end FindMaxRegionId
00471 
00472 //---------------------------------------------------------------------------
00473 
00474 /*
00475  * regionList::Concatenate
00476  *   newhead = pointer to new refs
00477  *
00478  * Concatenates the list headed by newhead onto this one. Any duplicates
00479  * are removed. (Therefore this is a UNION.)
00480  */
00481 void
00482 regionList::Concatenate (class regionList *newhead)
00483 {
00484   class regionList *oldhead, *oldtail, *r, *o, *dead;
00485 
00486   for (oldhead = oldtail = this; oldtail->GetNextListPtr() != NULL;
00487        oldtail = oldtail->GetNextListPtr()) ;
00488 
00489   r = newhead;
00490   while (r != NULL)
00491     {
00492       // Try to get o to point to a duplicate.
00493       for (o = oldhead; o != NULL; o = o->GetNextListPtr())
00494         {
00495           if (o->GetRegionPtr() == r->GetRegionPtr())
00496             break;  // found same ref, so stop
00497         } // end for
00498 
00499       if (o == NULL)
00500         {  // no duplicates, so append it
00501           oldtail->Append (r);  // append r to list
00502           oldtail = r;  // it's the new tail
00503           r = r->GetNextListPtr();
00504           oldtail->SetNextListPtr (NULL);  // it's the tail
00505         } // end if
00506       else
00507         {  // a duplicate, so move to next, then delete this one
00508           dead = r;
00509           r = r->GetNextListPtr();
00510           dead->SetNextListPtr (NULL);  // to avoid deleting r
00511           delete dead;
00512         } // end else
00513     } // end while
00514 
00515   oldtail->SetNextListPtr (NULL);  // terminate new list
00516   return;
00517 
00518 } // end Concatenate
00519 
00520 /*
00521  * regionList::Intersect
00522  *   newhead = pointer to new refs
00523  *
00524  * Intersects the list headed by newhead with this one. Neither list
00525  * is destroyed. Note that this returns a NEW list.
00526  */
00527 regionList *
00528 regionList::Intersect (class regionList *newhead)
00529 {
00530   regionList *oldhead, *oldtail, *r, *o, *dead;
00531   regionList *intersection = NULL, *itail;
00532 
00533   for (oldhead = oldtail = this; oldtail->GetNextListPtr() != NULL;
00534        oldtail = oldtail->GetNextListPtr()) ;
00535 
00536   for (o = oldhead; o != NULL; o = o->GetNextListPtr())
00537     {
00538       // Try to get r to point to a duplicate.
00539       for (r = newhead; r != NULL; r = r->GetNextListPtr())
00540         {
00541           if (o->GetRegionPtr() == r->GetRegionPtr())
00542             break;  // found same ref, so stop
00543         } // end for
00544 
00545       if (r != NULL)
00546         {  // found duplicate, so create new entry
00547           if (intersection != NULL)
00548             {
00549               itail->SetNextListPtr (new regionList);
00550               itail = itail->GetNextListPtr();
00551             } // end if
00552           else
00553             intersection = itail = new regionList;
00554           itail->SetRegionPtr (o->GetRegionPtr());
00555         } // end if
00556 
00557     } // end while
00558 
00559   return intersection;
00560 
00561 } // end Intersect
00562 
00563 /*
00564  * OpKiller, RegionKiller
00565  *
00566  * Deletes the objects (of type legoOp *, legoRegion *) contained
00567  * in the region.
00568  *
00569  * Why are these here, you ask? Well, legoRegions weren't getting
00570  * deleted properly before. They hold pointers to void, so the
00571  * legoPArr method PEmpty deleted them as (void *), which skipped
00572  * the component legoOps' / legoRegions' destructors weren't
00573  * being called.
00574  *
00575  * The awesome solution is to make legoRegion still a template.
00576  * Then, a legoBB derives from legoRegion<legoOp *>, and legoProc
00577  * derives from legoRegion<legoRegion <whatever> >. Unfortunately,
00578  * you can't just leave "whatever" there.
00579  *
00580  * The nearly-as-awesome solution is to make PEmpty a member
00581  * template, with template parameter X being the type of whatever
00582  * is being held by the legoPArr. The calls from legoPArr and
00583  * legoPSet can call it with X = T. legoRegion can use X = void *.
00584  * The legoBB can use X = legoOp *, and the legoProc can use
00585  * legoRegion *. But, gcc 2.7.2 DOESN'T SUPPORT MEMBER TEMPLATES!
00586  *
00587  * No problem, make it a template function not in a class, which
00588  * gcc CAN do, and make it a friend of legoRegion ... which
00589  * gcc CAN'T do (that's a known BUG in gcc).
00590  *
00591  * So the template function (Keeler) can't be a friend, but other
00592  * than that, it can work.
00593  *
00594  * Still, it needs to do everything PEmpty did, including calling
00595  * legoPArr::Empty(). Since Keeler isn't a friend of legoRegion,
00596  * it can't say r->Data.Empty(), so this function has to be
00597  * public in legoRegion, which is dangerous, but required.
00598  *
00599  * And, alas, I can't even get this to compile as a template,
00600  * so I'll overload it with X as legoRegion * and again as legoOp *.
00601  *
00602  * But then it might as well be inside legoRegion, since it's not
00603  * a template anymore!
00604  *
00605  * In the future, SOMEBODY, PLEASE MAKE SOMETHING THAT WORKS BETTER!!!
00606  */
00607 void legoRegion::OpKiller (void)
00608 {
00609   unsigned i;
00610   int count;
00611   void *item;
00612 
00613   //  fprintf (stderr,"I am the KEELER of OPS!\n");
00614   count = GetCount();
00615 
00616   if (IsOwner())
00617   for (i = 0; i < count; i++)
00618     {
00619       item = GetItem(i);
00620       delete (legoOp *) item;
00621     } // end for
00622   Data.Empty();
00623   //  fprintf (stderr,"I KEEL the OPS!\n");
00624 } // end legoRegion::OpKiller
00625 
00626 void legoRegion::RegionKiller (void)
00627 {
00628   unsigned i;
00629   int count;
00630   void *item;
00631 
00632   //  fprintf(stderr,"I am the KEELER of REEGIONS!\n");
00633   count = GetCount();
00634 
00635   if (IsOwner())
00636   for (i = 0; i < count; i++)
00637     {
00638       item = GetItem(i);
00639       delete (legoRegion *) item;
00640     } // end for
00641   Data.Empty();
00642   //  fprintf(stderr,"I KEEL the REEGIONS!\n");
00643 } // end legoRegion::RegionKiller
00644 
00645 
00646 
00647 
00648 
00649 

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