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

addremove.C

Go to the documentation of this file.
00001 // addremove.C
00002 
00003 /*
00004  * LEGO Object Adding/Removing Functions
00005  * by Bill Havanki
00006  *
00007  * 5/13/97 WAH:  Created file; added RemoveEdge, RemoveMidOp.
00008  * 7/9/97  WAH:  Added AddEdge, AddMidOp.
00009  * 7/16/97 WAH:  Added AddLcAttribute, RemoveLcAttribute.
00010  * 7/18/97 WAH:  Enhanced ", " to work on opEdges too; added AddLiveAttribute,
00011  *               RemoveLiveAttribute.
00012  * 7/23/97 WAH:  Added AddFlag, RemoveFlag.
00013  * 8/1/97  WAH:  Added ClearRegionMarks.
00014  * 9/2/97  WAH:  Fixed bug in AddPointerAttribute; added edge type parameter
00015  *               to adding/removing edges.
00016  * 10/11/97 WAH: Functions return created objects; attribute operand
00017  *               parentPtr is set.
00018  * 10/16/97 WAH: Added AddFreqAttribute, RemoveFreqAttribute.
00019  * 10/29/97 WAH: Fixed minor bug in AddPointerAttribute (oprd->SetParentPtr).
00020  * 10/31/97 WAH: Fixed finding of available id for new edge in AddEdge;
00021  *               added choice whether to delete op in RemoveMidOp.
00022  * 11/3/97 WAH:  Fixed RemoveMidOp to remove op from region.
00023  * 11/21/97 WAH: Revamped some function calls; changed AddPointerAttribute
00024  *               to allocate its own lcname (yikes!).
00025  * 12/8/97 WAH:  Fixed AddMidOp and RemoveMidOp to update opLists.
00026  * 12/11/97 WAH: Undid 11/21 change to AddPointerAttribute; causes core
00027  *               dumps (yikes again!); changed AddMidOp to add op to
00028  *               block before adding edge.
00029  * 1/13/98 WAH:  Fixed NULL dereferencing in AddPointerAttribute (newattr)
00030  *               and RemovePointerAttribute (atl).
00031  * 1/14/98 WAH:  Added AddBBAlongEdge.
00032  * 1/16/98 WAH:  Fixed RemoveMidOp again (see 11/3/97) to not Detach if
00033  *               the op is already detached.
00034  * 1/27/98 WAH:  Updated RemoveEdge to delete edge attributes and RemoveMidOp
00035  *               to delete op attributes and RemovePointerAttribute to
00036  *               delete attribute operands.
00037  * 1/29/98 WAH:  Added AddToList and RemoveFromList.
00038  * 1/30/98 WAH:  Replaced some code with function calls.
00039  * 4/9/98 WAH:   Enhanced RemoveFromList for opLists to key on weight as well.
00040  * 4/22/98 WAH:  Updated legoOprd::parentPtr.
00041  * Thu Aug 27 09:55:16 EDT 1998 LSY:    Add SplitParentBlockBeforeOp and RemoveLastOp 
00042  * 11/2/98 MDJ:  Fixed bug in ClearMarks, previously did not work for treegions
00043  * 11/11/98 MDJ: Fixed bug in RemoveMidOp(), now allListPtr for the proc is 
00044  *               updated correctly in the end case
00045  */
00046 
00047 #include <stdio.h>
00048 #include <stdlib.h>
00049 #include "lego.H"
00050 #include "search.H"
00051 #include "addremove.H"
00052 #include "modify.H"
00053 
00054 //#define ADDREMOVE_DEBUG
00055 #ifdef ADDREMOVE_DEBUG
00056 #define dprintf(s) fprintf s
00057 #define OUTF stderr
00058 #else
00059 #define dprintf(s)
00060 #endif // ADDREMOVE_DEBUG
00061 
00062 // Object types for add/remove functions.
00063 #define ADDREMOVE_REGION (0)
00064 #define ADDREMOVE_OP (1)
00065 #define ADDREMOVE_EDGE (2)
00066 
00067 // ========================================================================
00068 
00069 /*
00070  * AddToList (all flavors)
00071  *   list = list on which to work
00072  *   object = op, edge, or region to add to list
00073  *   valid = valid bit
00074  *   weight = profile weight (opList only)
00075  *   returns: list if not originally NULL, new list otherwise.
00076  *
00077  * Adds a reference to object to the end of the list given. The valid bit
00078  * of the list object is set to valid, and the weight of an opList is set to
00079  * the weight given. If list is NULL, a new list is created and returned.
00080  * If list is not NULL, list is returned.
00081  *
00082  * If a reference to the object exists, no changes are made, and list is
00083  * returned.
00084  */
00085 
00086 opList *
00087 AddToList (opList *list, legoOp *object, int valid = 1, double weight = 0.0)
00088 {
00089   opList *lprev, *l, *add;
00090 
00091   // Try to find duplicate.
00092   for (lprev = NULL, l = list; l != NULL;
00093        lprev = l, l = l->GetNextListPtr())
00094     {
00095       if (l->GetOpPtr() == object) return list;
00096     } // end for
00097 
00098   add = new opList;
00099   if (lprev != NULL)
00100     lprev->SetNextListPtr (add);
00101   else
00102     list = add;
00103 
00104   add->SetOpPtr (object);
00105   add->SetOpId (object->GetOpId());
00106   add->SetValid (valid);
00107   add->SetWeight (weight);
00108 
00109   return list;
00110 } // end AddToList (opList)
00111 
00112 edgeList *
00113 AddToList (edgeList *list, opEdges *object, int valid = 1)
00114 {
00115   edgeList *lprev, *l, *add;
00116 
00117   // Try to find duplicate.
00118   for (lprev = NULL, l = list; l != NULL;
00119        lprev = l, l = l->GetNextListPtr())
00120     {
00121       if (l->GetEdgePtr() == object) return list;
00122     } // end for
00123 
00124   add = new edgeList;
00125   if (lprev != NULL)
00126     lprev->SetNextListPtr (add);
00127   else
00128     list = add;
00129 
00130   add->SetEdgePtr (object);
00131   add->SetEdgeId (object->GetEdgeId());
00132   add->SetValid (valid);
00133 
00134   return list;
00135 } // end AddToList (edgeList)
00136 
00137 regionList *
00138 AddToList (regionList *list, legoRegion *object, int valid = 1)
00139 {
00140   regionList *lprev, *l, *add;
00141 
00142   // Try to find duplicate.
00143   for (lprev = NULL, l = list; l != NULL;
00144        lprev = l, l = l->GetNextListPtr())
00145     {
00146       if (l->GetRegionPtr() == object) return list;
00147     } // end for
00148 
00149   add = new regionList;
00150   if (lprev != NULL)
00151     lprev->SetNextListPtr (add);
00152   else
00153     list = add;
00154 
00155   add->SetRegionPtr (object);
00156   add->SetValid (valid);
00157 
00158   return list;
00159 } // end AddToList (regionList)
00160 
00161 // ========================================================================
00162 
00163 /*
00164  * RemoveFromList (all flavors)
00165  *   list = list on which to work
00166  *   object = op, edge, or region to remove list
00167  *   weight = profile weight (opList only)
00168  *   returns: new list
00169  *
00170  * Removes a reference to object from the the list given.
00171  * If list is NULL, no actions are taken and NULL is returned.
00172  * If list is not NULL, the reference is removed and the new list is
00173  *   returned;
00174  * if the only reference in list is to object, it is removed and NULL is
00175  *   returned instead.
00176  *
00177  * If no reference to the object exists, no changes are made, and list is
00178  * returned.
00179  */
00180 
00181 opList *
00182 RemoveFromList (opList *list, legoOp *object, double weight = -1.0)
00183 {
00184   opList *l, *lprev, *remove;
00185 
00186   if (list == NULL) return NULL;
00187 
00188   for (lprev = NULL, l = list; l != NULL;
00189        lprev = l, l = l->GetNextListPtr())
00190     {
00191       if (weight != -1.0 && l->GetWeight() != weight) continue;
00192       if (l->GetOpPtr() == object) break;
00193     } // end for
00194 
00195   if (l == NULL) return list;
00196 
00197   if (lprev != NULL)
00198     {
00199       lprev->SetNextListPtr (l->GetNextListPtr());
00200       remove = list;
00201     } // end if
00202   else
00203     remove = l->GetNextListPtr();
00204 
00205   l->SetNextListPtr (NULL);
00206   delete l;
00207 
00208   return remove;
00209 } // end RemoveFromList (opList)
00210 
00211 edgeList *
00212 RemoveFromList (edgeList *list, opEdges *object)
00213 {
00214   edgeList *l, *lprev, *remove;
00215 
00216   if (list == NULL) return NULL;
00217 
00218   for (lprev = NULL, l = list; l->GetEdgePtr() != object && l != NULL;
00219        lprev = l, l = l->GetNextListPtr()) ;
00220 
00221   if (l == NULL) return list;
00222 
00223   if (lprev != NULL)
00224     {
00225       lprev->SetNextListPtr (l->GetNextListPtr());
00226       remove = list;
00227     } // end if
00228   else
00229     remove = l->GetNextListPtr();
00230 
00231   l->SetNextListPtr (NULL);
00232   delete l;
00233 
00234   return remove;
00235 } // end RemoveFromList (edgeList)
00236 
00237 regionList *
00238 RemoveFromList (regionList *list, legoRegion *object)
00239 {
00240   regionList *l, *lprev, *remove;
00241 
00242   if (list == NULL) return NULL;
00243 
00244   for (lprev = NULL, l = list; l->GetRegionPtr() != object && l != NULL;
00245        lprev = l, l = l->GetNextListPtr()) ;
00246 
00247   if (l == NULL) return list;
00248 
00249   if (lprev != NULL)
00250     {
00251       lprev->SetNextListPtr (l->GetNextListPtr());
00252       remove = list;
00253     } // end if
00254   else
00255     remove = l->GetNextListPtr();
00256 
00257   l->SetNextListPtr (NULL);
00258   delete l;
00259 
00260   return remove;
00261 } // end RemoveFromList (regionList)
00262 
00263 // ========================================================================
00264 
00265 /*
00266  * AddEdge
00267  *   fromop = op at tail of edge
00268  *   toop = op at head of edge
00269  *   et = type of edge to add
00270  *   srcPort = port of source op's operand
00271  *   destPort = port of destination op's operand
00272  *   returns: new opEdges, or NULL if failure
00273  *
00274  * Inserts an edge into the edge dictionary of proc going from op fromop
00275  * to op toop.
00276  */
00277 opEdges *
00278 AddEdge (legoOp *fromop, legoOp *toop, enum edgeTypes et,
00279          int srcPort = 0, int destPort = 0)
00280 {
00281   legoProc *proc;
00282   opEdges *edgeprev, *edge;
00283   attrs *attr;
00284   int maxedgeid = -1;
00285 
00286   proc = (legoProc *) FindParentRegionType (RT_PROC, fromop);
00287   if (proc == NULL)
00288     {
00289       LegoNonFatal ("AddEdge", "Couldn't find proc of op %d.",
00290                     fromop->GetOpId());
00291       return NULL;
00292     } // end if
00293 
00294   // Look for edge already in dictionary.
00295   for (edgeprev = NULL, edge = proc->GetEdgeDictionary();
00296        edge != NULL;
00297        edgeprev = edge, edge = edge->GetNextOpEdgePtr())
00298     if (edge->GetFromOpPtr() == fromop &&
00299         edge->GetToOpPtr() == toop &&
00300         edge->GetEdgeType() == et &&
00301         edge->GetSrcPort() == srcPort &&
00302         edge->GetDestPort() == destPort)
00303       return NULL;
00304 
00305   maxedgeid = FindMaxEdgeAttrId (proc);
00306 
00307   edge = new opEdges();
00308   edge->SetEdgeId (maxedgeid + 1);
00309   edge->SetFromOpId (fromop->GetOpId());
00310   edge->SetFromOpPtr (fromop);
00311   edge->SetSrcPort (srcPort);
00312   edge->SetToOpId (toop->GetOpId());
00313   edge->SetToOpPtr (toop);
00314   edge->SetDestPort (destPort);
00315   edge->SetEdgeStatus (STATUS_CERTAIN);
00316   edge->SetEdgeLat (1);
00317   edge->SetEdgeType (et);
00318   edge->SetNextOpEdgePtr(NULL);
00319   switch (et)
00320     {
00321     case ET_CNTL:
00322       edge->SetSrcPortType (PT_CTL);
00323       edge->SetDestPortType (PT_CTL);
00324       break;
00325     case ET_REGFLOW:
00326       edge->SetSrcPortType (PT_DEST);
00327       edge->SetDestPortType (PT_SRC);
00328       break;
00329     case ET_REGANTI:
00330       edge->SetSrcPortType (PT_SRC);
00331       edge->SetDestPortType (PT_DEST);
00332       break;
00333     case ET_REGOUT:
00334       edge->SetSrcPortType (PT_DEST);
00335       edge->SetDestPortType (PT_DEST);
00336       break;
00337     case ET_MEM:
00338       edge->SetSrcPortType (PT_MEM);
00339       edge->SetDestPortType (PT_MEM);
00340       break;
00341     default:
00342       break;
00343     } // end switch
00344   
00345   if (edgeprev != NULL)
00346     edgeprev->SetNextOpEdgePtr (edge);
00347   else
00348     proc->SetEdgeDictionary (edge);
00349 
00350   return edge;
00351 } // end AddEdge
00352 
00353 opEdges *
00354 AddEdge (legoOp *fromop, legoOp *toop, legoProc *proc, enum edgeTypes et,
00355          int srcPort = 0, int destPort = 0)
00356 {
00357   LegoNonFatal ("AddEdge", "This is a deprecated version of this function.\n"
00358                 "Remove the legoProc * parameter from the call.");
00359 
00360   return AddEdge (fromop, toop, et, srcPort, destPort);
00361 } // end AddEdge
00362 
00363 // ========================================================================
00364 
00365 /*
00366  * AddMidOp
00367  *   midop = op to be added
00368  *   beforeop = op before where midop should be added
00369  *
00370  * Inserts midop into a block just after beforeop while properly updating
00371  * all links and whatnot.
00372  */
00373 void
00374 AddMidOp (legoOp *midop, legoOp *beforeop)
00375 {
00376   legoRegion *region;
00377   legoProc *proc;
00378   opEdges *edge;
00379   legoOp *afterop;
00380   opList *oplscan;
00381 
00382   if (midop == NULL || beforeop == NULL)
00383     {
00384       LegoNonFatal ("AddMidOp", "Passed NULL argument.");
00385       return;
00386     } // end if
00387 
00388   proc = (legoProc *) FindParentRegionType (RT_PROC, beforeop);
00389   if (proc == NULL)
00390     {
00391       LegoNonFatal ("AddMidOp", "Couldn't find proc of op %d.",
00392                     beforeop->GetOpId());
00393       return;
00394     } // end if
00395 
00396   afterop = beforeop->GetNextLink();
00397   if (afterop == NULL)
00398     {
00399       LegoNonFatal ("AddMidOp", "Couldn't find op after %d.",
00400                     beforeop->GetOpId());
00401       return;
00402     } // end if
00403 
00404   // Find edge from beforeop to afterop.
00405   edge = FindControlEdge (beforeop, afterop);
00406   if (edge == NULL)
00407     {
00408       LegoNonFatal ("AddMidOp", "Couldn't find edge from beforeop to "
00409                     "afterop.");
00410       return;
00411     }
00412 
00413   // Point edge to midop.
00414   edge->SetToOpPtr (midop);
00415   edge->SetToOpId (midop->GetOpId());
00416   beforeop->SetNextLink (midop);
00417   midop->SetPrevLink (beforeop);
00418 
00419   // Insert midop into block and add to proc list.
00420   region = (legoRegion *) beforeop->GetParentBlockPtr();
00421   region->AddItem (midop);
00422   midop->SetParentBlockPtr (region);
00423   midop->SetListOpPtr (proc->GetListOpPtr());
00424   proc->SetListOpPtr (midop);
00425 
00426   // Add new edge from midop to afterop.
00427   AddEdge (midop, afterop, ET_CNTL);
00428   midop->SetNextLink (afterop);
00429   afterop->SetPrevLink (midop);
00430 
00431   // Change beforeop's reference to afterop to point to midop instead.
00432   for (oplscan = beforeop->GetOutListPtr();
00433        oplscan != NULL;
00434        oplscan = oplscan->GetNextListPtr())
00435     {
00436       if (oplscan->GetOpId() == afterop->GetOpId())
00437         {
00438           oplscan->SetOpPtr (midop);
00439           oplscan->SetOpId (midop->GetOpId());
00440           break;
00441         } // end if
00442     } // end for
00443 
00444   return;
00445 } // end AddMidOp
00446 
00447 // ========================================================================
00448 
00449 /*
00450  * RemoveEdge
00451  *   fromopid = id of op at tail of edge
00452  *   toopid = id of op at head of edge
00453  *   proc = proc whose dictionary contains the edge
00454  *   et = type of edge to remove
00455  *   srcPort = port of source op's operand
00456  *   destPort = port of destination op's operand
00457  *   returns: 1 if edge removed, 0 if no match found
00458  *
00459  * Searches the edge dictionary of proc and removes the edge going from
00460  * op fromopid to op toopid.
00461  */
00462 int
00463 RemoveEdge (int fromopid, int toopid, legoProc *proc, enum edgeTypes et,
00464             int srcPort = EDGEPORT_DONTCARE, int destPort = EDGEPORT_DONTCARE)
00465 {
00466   opEdges *edgeprev, *edge;
00467   int retval = 0;
00468 
00469   for (edgeprev = NULL, edge = proc->GetEdgeDictionary();
00470        edge != NULL;
00471        edgeprev = edge, edge = edge->GetNextOpEdgePtr())
00472     {
00473       if (edge->GetFromOpId() != fromopid || edge->GetToOpId() != toopid)
00474         continue;  // different ops
00475       if (srcPort > EDGEPORT_DONTCARE && edge->GetSrcPort() != srcPort)
00476         continue;  // src ports don't match
00477       if (destPort > EDGEPORT_DONTCARE && edge->GetDestPort() != destPort)
00478         continue;  // dest ports don't match
00479 
00480       if (edgeprev != NULL)
00481         edgeprev->SetNextOpEdgePtr (edge->GetNextOpEdgePtr());
00482       else
00483         proc->SetEdgeDictionary (edge->GetNextOpEdgePtr());
00484       edge->SetNextOpEdgePtr (NULL);
00485       delete edge;
00486       retval = 1; break;
00487     } // end for
00488 
00489   return retval;
00490 } // end RemoveEdge (int, int, ...)
00491 
00492 int
00493 RemoveEdge (legoOp *fromop, legoOp *toop, enum edgeTypes et,
00494             int srcPort = EDGEPORT_DONTCARE, int destPort = EDGEPORT_DONTCARE)
00495 {
00496   legoProc *proc = (legoProc *) FindParentRegionType (RT_PROC, fromop);
00497   if (proc == NULL)
00498     {
00499       LegoNonFatal ("RemoveEdge", "Couldn't find proc of op %d.",
00500                     fromop->GetOpId());
00501       return 0;
00502     } // end if
00503 
00504   return RemoveEdge (fromop->GetOpId(), toop->GetOpId(), proc, et, srcPort,
00505                      destPort);
00506 } // end RemoveEdge (legoOp *, legoOp *, ...)
00507 
00508 int
00509 RemoveEdge (legoOp *fromop, legoOp *toop, legoProc *proc, enum edgeTypes et,
00510             int srcPort = EDGEPORT_DONTCARE, int destPort = EDGEPORT_DONTCARE)
00511 {
00512   //  LegoNonFatal ("RemoveEdge", "This is a deprecated version of this "
00513   //            "function.\nRemove the legoProc * parameter from the call.");
00514 
00515   return RemoveEdge (fromop, toop, et, srcPort, destPort);
00516 }
00517 
00518 // ========================================================================
00519 
00520 /*
00521  * RemoveMidOp
00522  *   midop = op to be removed
00523  *   destroy = whether to delete op
00524  *
00525  * Removes midop from existence while properly updating all links
00526  * and whatnot.
00527  */
00528 void
00529 RemoveMidOp (legoOp *midop, int destroy = 0)
00530 {
00531   legoProc *proc;
00532   legoOp *listop, *listopprev;
00533   opEdges *edgeprev, *edge;
00534   opList *oplscan;
00535   legoRegion *block;
00536   unsigned loc;
00537 
00538   proc = (legoProc *) FindParentRegionType (RT_PROC, midop);
00539   if (proc == NULL)
00540     {
00541       LegoNonFatal ("RemoveMidOp", "Couldn't find proc of op %d.",
00542                     midop->GetOpId());
00543       return;
00544     } // end if
00545 
00546   if (midop->GetPrevLink() == NULL || midop->GetNextLink() == NULL)
00547     {
00548       LegoNonFatal ("RemoveMidOp", "Op %d not in middle.", midop->GetOpId());
00549       return;
00550     } // end if
00551 
00552   // Remove edge leading out, point edge leading in to next op.
00553   RemoveEdge (midop->GetOpId(), midop->GetNextLink()->GetOpId(), proc,
00554               ET_CNTL);
00555 
00556   for (edgeprev = NULL, edge = proc->GetEdgeDictionary();
00557        edge != NULL &&
00558          (edge->GetFromOpId() != midop->GetPrevLink()->GetOpId() ||
00559           edge->GetToOpId() != midop->GetOpId());
00560        edgeprev = edge, edge = edge->GetNextOpEdgePtr())
00561     /* do nothing */;
00562   if (edge != NULL)
00563     {
00564       edge->SetToOpPtr (midop->GetNextLink());
00565       edge->SetToOpId (midop->GetNextLink()->GetOpId());
00566     } // end if
00567 
00568   // Change previous op's reference to currentop to point to the next op
00569   // instead (does stuff for C_MERGE only).
00570   for (oplscan = midop->GetPrevLink()->GetOutListPtr();
00571        oplscan != NULL;
00572        oplscan = oplscan->GetNextListPtr())
00573     {
00574       if (oplscan->GetOpId() == midop->GetOpId())
00575         {
00576           oplscan->SetOpPtr (midop->GetNextLink());
00577           oplscan->SetOpId (midop->GetNextLink()->GetOpId());
00578           break;
00579         } // end if
00580     } // end for
00581   
00582   // Remove from op chains.
00583   midop->GetPrevLink()->SetNextLink (midop->GetNextLink());
00584   midop->GetNextLink()->SetPrevLink (midop->GetPrevLink());
00585   midop->SetPrevLink (NULL);
00586   midop->SetNextLink (NULL);
00587 
00588   // mdj 11/11/98 - fixed bug, now when proc->GetListOpPtr() == midop, 
00589   // lists are updated correctly
00590   if ((listop = proc->GetListOpPtr()) != midop) {
00591     for (;
00592          listop != NULL && listop->GetListOpPtr() != midop;
00593          listop = listop->GetListOpPtr())
00594       /* do nothing */;
00595   }
00596   if (listop != NULL)
00597     {
00598       if (proc->GetListOpPtr() != midop)
00599         listop->SetListOpPtr (midop->GetListOpPtr());
00600       else
00601         proc->SetListOpPtr (midop->GetListOpPtr());
00602     } // end if
00603   midop->SetListOpPtr (NULL);
00604 
00605   // Detach from region.
00606   block = (legoRegion *) midop->GetParentBlockPtr();
00607   loc = block->Search (midop);
00608   if (loc != MAX_UNSIGNED)
00609     block->Detach (loc);
00610   
00611   if (destroy)  // blow away attributes, then op
00612     {
00613       attrList *atl;
00614       attrs *a;
00615       enum attrTypes atype;
00616 
00617       RemoveLiveAttribute (midop, proc);  // kill live attribute right off
00618 
00619       atl = midop->GetOpAttrListPtr();
00620       while (atl != NULL)
00621         {
00622           atype = atl->GetAttrType();
00623           if (atype != ATTR_LC)
00624             {
00625               atl = atl->GetNextListPtr(); continue;  // skip to first lc
00626             } // end if
00627 
00628           // Remove the first attribute here.
00629           a = atl->GetAttrPtr();
00630           RemoveLcAttribute (a->GetAttrString(), midop, proc);
00631 
00632           atl = midop->GetOpAttrListPtr();  // reset for next scan
00633         } // end while
00634       delete midop;
00635     } // end if
00636   return;
00637 } // end RemoveMidOp
00638 
00639 void
00640 RemoveMidOp (legoOp *midop, legoProc *proc, int destroy = 0)
00641 {
00642   //  LegoNonFatal ("RemoveMidOp", "This is a deprecated version of this "
00643   //            "function.\nRemove the legoProc * parameter from the call.");
00644 
00645   RemoveMidOp (midop, destroy);
00646 }
00647 
00648 // ========================================================================
00649 
00650 /*
00651  * RemoveFinalOp
00652  *   midop = op to be removed
00653  *   destroy = whether to delete op
00654  *
00655  * Removes midop from existence while properly updating all links
00656  * and whatnot.
00657  */
00658 void
00659 RemoveFinalOp (legoOp *finalop, int destroy = 0)
00660 {
00661   legoProc *proc;
00662   legoOp *listop, *listopprev;
00663   opEdges *edgeprev, *edge;
00664   opList *oplscan;
00665   legoRegion *block;
00666   unsigned loc;
00667 
00668   proc = (legoProc *) FindParentRegionType (RT_PROC, finalop);
00669   if (proc == NULL)
00670     {
00671       LegoNonFatal ("RemoveFinalOp", "Couldn't find proc of op %d.",
00672                     finalop->GetOpId());
00673       return;
00674     } // end if
00675 
00676   if (finalop->GetPrevLink() == NULL || finalop->GetNextLink() != NULL)
00677     {
00678       LegoNonFatal ("RemoveFinalOp", "Op %d not the final op in block.", finalop->GetOpId());
00679       return;
00680     } // end if
00681 
00682   // Remove the edge between the previous op and finalop 
00683   RemoveEdge (finalop->GetPrevLink()->GetOpId(), finalop->GetOpId(), proc,
00684               ET_CNTL);
00685   
00686   // Remove from op chains.
00687   finalop->GetPrevLink()->SetNextLink (NULL);
00688   finalop->SetPrevLink (NULL);
00689   finalop->SetNextLink (NULL);
00690 
00691   // mdj 11/11/98 - fixed bug, now when proc->GetListOpPtr() == finalop, 
00692   // lists are updated correctly
00693   if ((listop = proc->GetListOpPtr()) != finalop) {
00694     for (;
00695          listop != NULL && listop->GetListOpPtr() != finalop;
00696          listop = listop->GetListOpPtr())
00697       /* do nothing */;
00698   }
00699   if (listop != NULL)
00700     {
00701       if (proc->GetListOpPtr() != finalop)
00702         listop->SetListOpPtr (finalop->GetListOpPtr());
00703       else
00704         proc->SetListOpPtr (finalop->GetListOpPtr());
00705     } // end if
00706   finalop->SetListOpPtr (NULL);
00707 
00708   // Detach from region.
00709   block = (legoRegion *) finalop->GetParentBlockPtr();
00710   loc = block->Search (finalop);
00711   if (loc != MAX_UNSIGNED)
00712     block->Detach (loc);
00713   
00714   if (destroy)  // blow away attributes, then op
00715     {
00716       attrList *atl;
00717       attrs *a;
00718       enum attrTypes atype;
00719 
00720       RemoveLiveAttribute (finalop, proc);  // kill live attribute right off
00721 
00722       atl = finalop->GetOpAttrListPtr();
00723       while (atl != NULL)
00724         {
00725           atype = atl->GetAttrType();
00726           if (atype != ATTR_LC)
00727             {
00728               atl = atl->GetNextListPtr(); continue;  // skip to first lc
00729             } // end if
00730 
00731           // Remove the first attribute here.
00732           a = atl->GetAttrPtr();
00733           RemoveLcAttribute (a->GetAttrString(), finalop, proc);
00734 
00735           atl = finalop->GetOpAttrListPtr();  // reset for next scan
00736         } // end while
00737       delete finalop;
00738     } // end if
00739   return;
00740 } // end RemoveFinalOp
00741 
00742 /*
00743  * RemoveFirstOp
00744  *   firstop = op to be removed
00745  *   destroy = whether to delete op
00746  *
00747  * Removes firstop from existence while properly updating all links
00748  * and whatnot.
00749  */
00750 void
00751 RemoveFirstOp (legoOp *firstop, int destroy = 0)
00752 {
00753   legoProc *proc;
00754   legoOp *listop, *listopprev;
00755   opEdges *edgeprev, *edge;
00756   opList *oplscan;
00757   legoRegion *block;
00758   unsigned loc;
00759 
00760   proc = (legoProc *) FindParentRegionType (RT_PROC, firstop);
00761   if (proc == NULL)
00762     {
00763       LegoNonFatal ("RemoveFirstOp", "Couldn't find proc of op %d.",
00764                     firstop->GetOpId());
00765       return;
00766     } // end if
00767 
00768   if (firstop->GetPrevLink() != NULL || firstop->GetNextLink() == NULL)
00769     {
00770       LegoNonFatal ("RemoveFirstOp", "Op %d not the first op in block.", firstop->GetOpId());
00771       return;
00772     } // end if
00773 
00774   // Remove edge leading out.
00775   RemoveEdge (firstop->GetOpId(), firstop->GetNextLink()->GetOpId(), proc,
00776               ET_CNTL);
00777 
00778   // Remove from op chains.
00779   firstop->GetNextLink()->SetPrevLink (NULL);
00780   firstop->SetPrevLink (NULL);
00781   firstop->SetNextLink (NULL);
00782 
00783   // mdj 11/11/98 - fixed bug, now when proc->GetListOpPtr() == firstop, 
00784   // lists are updated correctly
00785   if ((listop = proc->GetListOpPtr()) != firstop) {
00786     for (;
00787          listop != NULL && listop->GetListOpPtr() != firstop;
00788          listop = listop->GetListOpPtr())
00789       /* do nothing */;
00790   }
00791   if (listop != NULL)
00792     {
00793       if (proc->GetListOpPtr() != firstop)
00794         listop->SetListOpPtr (firstop->GetListOpPtr());
00795       else
00796         proc->SetListOpPtr (firstop->GetListOpPtr());
00797     } // end if
00798   firstop->SetListOpPtr (NULL);
00799 
00800   // Detach from region.
00801   block = (legoRegion *) firstop->GetParentBlockPtr();
00802   loc = block->Search (firstop);
00803   if (loc != MAX_UNSIGNED)
00804     block->Detach (loc);
00805   
00806   if (destroy)  // blow away attributes, then op
00807     {
00808       attrList *atl;
00809       attrs *a;
00810       enum attrTypes atype;
00811 
00812       RemoveLiveAttribute (firstop, proc);  // kill live attribute right off
00813 
00814       atl = firstop->GetOpAttrListPtr();
00815       while (atl != NULL)
00816         {
00817           atype = atl->GetAttrType();
00818           if (atype != ATTR_LC)
00819             {
00820               atl = atl->GetNextListPtr(); continue;  // skip to first lc
00821             } // end if
00822 
00823           // Remove the first attribute here.
00824           a = atl->GetAttrPtr();
00825           RemoveLcAttribute (a->GetAttrString(), firstop, proc);
00826 
00827           atl = firstop->GetOpAttrListPtr();  // reset for next scan
00828         } // end while
00829       delete firstop;
00830     } // end if
00831   return;
00832 } // end RemoveFirstOp
00833 
00834 /*
00835  * RemoveVeryLastOp
00836  *   verylastop = op to be removed
00837  *   destroy = whether to delete op
00838  *
00839  * Removes verylastop from existence while properly updating all links
00840  * and whatnot.
00841  */
00842 void
00843 RemoveVeryLastOp (legoOp *verylastop, int destroy = 0)
00844 {
00845   legoProc *proc;
00846   legoOp *listop, *listopprev;
00847   opEdges *edgeprev, *edge;
00848   opList *oplscan;
00849   legoRegion *block;
00850   unsigned loc;
00851 
00852   proc = (legoProc *) FindParentRegionType (RT_PROC, verylastop);
00853   if (proc == NULL)
00854     {
00855       LegoNonFatal ("RemoveVeryLastOp", "Couldn't find proc of op %d.",
00856                     verylastop->GetOpId());
00857       return;
00858     } // end if
00859 
00860   if (verylastop->GetPrevLink() != NULL || verylastop->GetNextLink() != NULL)
00861     {
00862       LegoNonFatal ("RemoveVeryLastOp", "Op %d not the very last op in block.", verylastop->GetOpId());
00863       return;
00864     } // end if
00865 
00866   // Remove from op chains.
00867   verylastop->SetPrevLink (NULL);
00868   verylastop->SetNextLink (NULL);
00869 
00870   // mdj 11/11/98 - fixed bug, now when proc->GetListOpPtr() == verylastop, 
00871   // lists are updated correctly
00872   if ((listop = proc->GetListOpPtr()) != verylastop) {
00873     for (;
00874          listop != NULL && listop->GetListOpPtr() != verylastop;
00875          listop = listop->GetListOpPtr())
00876       /* do nothing */;
00877   }
00878   if (listop != NULL)
00879     {
00880       if (proc->GetListOpPtr() != verylastop)
00881         listop->SetListOpPtr (verylastop->GetListOpPtr());
00882       else
00883         proc->SetListOpPtr (verylastop->GetListOpPtr());
00884     } // end if
00885   verylastop->SetListOpPtr (NULL);
00886 
00887   // Detach from region.
00888   block = (legoRegion *) verylastop->GetParentBlockPtr();
00889   loc = block->Search (verylastop);
00890   if (loc != MAX_UNSIGNED)
00891     block->Detach (loc);
00892   
00893   if (destroy)  // blow away attributes, then op
00894     {
00895       attrList *atl;
00896       attrs *a;
00897       enum attrTypes atype;
00898 
00899       RemoveLiveAttribute (verylastop, proc);  // kill live attribute right off
00900 
00901       atl = verylastop->GetOpAttrListPtr();
00902       while (atl != NULL)
00903         {
00904           atype = atl->GetAttrType();
00905           if (atype != ATTR_LC)
00906             {
00907               atl = atl->GetNextListPtr(); continue;  // skip to first lc
00908             } // end if
00909 
00910           // Remove the first attribute here.
00911           a = atl->GetAttrPtr();
00912           RemoveLcAttribute (a->GetAttrString(), verylastop, proc);
00913 
00914           atl = verylastop->GetOpAttrListPtr();  // reset for next scan
00915         } // end while
00916       delete verylastop;
00917     } // end if
00918   return;
00919 } // end RemoveVeryLastOp
00920 
00921 /*
00922  * RemoveLastOp  
00923  *   last_op = op to be removed
00924  *   destroy = whether to delete op
00925  *
00926  * Removes last from existence
00927  */
00928 void RemoveLastOp(legoOp *last_op,int destroy = 0)
00929 {
00930    legoOp       *prev_op        = NULL;
00931    legoOp       *list_op        = NULL;
00932    legoProc     *proc_ptr       = NULL;
00933    opEdges      *op_edge        = NULL;
00934 
00935 
00936    if(!last_op){
00937         LegoNonFatal ("RemoveLastOp", "Empty argument passed");
00938         return;
00939    }
00940    if(!(prev_op = last_op->GetPrevLink())){
00941         LegoNonFatal ("RemoveLastOp", "Empty GetPrevLink");
00942         return;
00943    }
00944    if(!(proc_ptr = (legoProc *) FindParentRegionType (RT_PROC, last_op))){
00945         LegoNonFatal ("RemoveLastOp", "Couldn't find proc of op %d.",last_op->GetOpId());
00946         return;
00947    }
00948    //
00949    // Step 1:  Search the opEdge  from prev_op to last_op
00950    //
00951    int          prev_op_id      = prev_op->GetOpId();
00952    int          last_op_id      = last_op->GetOpId();
00953    opEdges      *edge_dict      = proc_ptr->GetEdgeDictionary();
00954    opEdges      *prev_op_edge   = NULL;
00955 
00956    for(op_edge=edge_dict;op_edge;op_edge=op_edge->GetNextOpEdgePtr()){
00957         if(op_edge->GetFromOpId()==prev_op_id && op_edge->GetToOpId()==last_op_id)      break;
00958         prev_op_edge    = op_edge;
00959    }
00960    //
00961    // Step 2: set prev_op_edge to next (delete this op_edge)
00962    //
00963    assert(op_edge!=NULL);
00964    prev_op_edge->SetNextOpEdgePtr(op_edge->GetNextOpEdgePtr());
00965    //
00966    // set link of prev_op
00967    //
00968    prev_op->SetNextLink(NULL);
00969 
00970    for(list_op=proc_ptr->GetListOpPtr();list_op!=NULL && list_op->GetListOpPtr()!=last_op;list_op=list_op->GetListOpPtr());
00971    if(list_op){
00972         if(list_op!=proc_ptr->GetListOpPtr())   list_op->SetListOpPtr(last_op->GetListOpPtr());
00973         else                                    proc_ptr->SetListOpPtr(last_op->GetListOpPtr());
00974    }
00975    last_op->SetListOpPtr(NULL);
00976    //
00977    // Detach from region
00978    // if not already detached
00979    //
00980    legoRegion   *bb     = (legoRegion *)last_op->GetParentBlockPtr();
00981    unsigned     loc     = bb->Search(last_op);
00982    if(loc != MAX_UNSIGNED)      bb->Detach(loc);
00983 
00984    // If needed then destroy the op
00985    // blow away attributes, then op
00986    if (destroy){
00987         attrList        *atl;
00988         attrs           *a;
00989         enum attrTypes  atype;
00990 
00991         RemoveLiveAttribute (last_op, proc_ptr);  // kill live attribute right off
00992         atl     = last_op->GetOpAttrListPtr();
00993         while(atl){
00994                 atype   = atl->GetAttrType();
00995                 if (atype != ATTR_LC){
00996                         atl     = atl->GetNextListPtr();
00997                         continue;  // skip to first lc
00998                 } // end if
00999                 // Remove the first attribute here.
01000                 a       = atl->GetAttrPtr();
01001                 RemoveLcAttribute (a->GetAttrString(), last_op, proc_ptr);
01002                 atl     = last_op->GetOpAttrListPtr();  // reset for next scan
01003         } // end while
01004         delete last_op;
01005    }
01006 }
01007 
01008 void RemoveLastOp(legoOp *last_op, legoProc *proc, int destroy = 0)
01009 {
01010    RemoveLastOp(last_op,destroy); 
01011 } 
01012 
01013 /*
01014  * AddBBAlongEdge
01015  *   edge = edge on which new block is placed
01016  *   proc = containing proc
01017  *   returns: pointer to new legoBB, or NULL if failure
01018  *
01019  * Creates a new empty basic block along the edge given, such that the
01020  * block now exists directly between the region at the tail of the edge
01021  * and the one at the head. The block is added to the parent region of
01022  * the destination block, just before it in the set.
01023  */
01024 legoBB *
01025 AddBBAlongEdge (opEdges *edge, legoProc *proc)
01026 {
01027   opEdges *newedge;
01028   legoOp *fromop, *toop, *alllist, *top, *dummy_br;
01029   legoRegion *fromregion, *toregion, *parentregion, *r;
01030   legoBB *newblock;
01031   legoOprd *oprd;
01032   opList *opl;
01033   int id;
01034   unsigned loc;
01035   double fromweight;
01036 
01037   if (edge == NULL || proc == NULL)
01038     {
01039       LegoNonFatal ("AddBBAlongEdge", "Passed NULL parameter.");
01040       return NULL;
01041     } // end if
01042 
01043   fromop = edge->GetFromOpPtr();
01044   toop = edge->GetToOpPtr();
01045   if (fromop == NULL || toop == NULL)
01046     {
01047       LegoFatal ("AddBBAlongEdge", "Edge source is %p, destination %p - "
01048                  "one of them is NULL.", fromop, toop);
01049     } // end if
01050 
01051   fromregion = (legoRegion *) fromop->GetParentBlockPtr();
01052   toregion = (legoRegion *) toop->GetParentBlockPtr();
01053   if (fromregion == NULL || toregion == NULL)
01054     {
01055       LegoFatal ("AddBBAlongEdge", "Parent of op %p is %p; parent of %p "
01056                  "is %p - one of the parents is NULL.", fromop, fromregion,
01057                  toop, toregion);
01058     } // end if
01059 
01060   parentregion = toregion->GetParentPtr();
01061   if (parentregion == NULL)
01062     {
01063       LegoFatal ("AddBBAlongEdge", "Parent of %p region is NULL.",
01064                  toregion);
01065     } // end if
01066 
01067   dprintf ((OUTF, "AddBBAlongEdge: insering block along edge %d into region "
01068             "%d.\n", edge->GetEdgeId(), parentregion->GetRegionId()));
01069 
01070   // Make a new basic block.
01071   id = proc->FindMaxRegionId()->GetRegionId();
01072   newblock = new legoBB (id + 1);
01073   loc = parentregion->Search (toregion);
01074   if (loc != MAX_UNSIGNED)
01075     parentregion->Insert (newblock, loc);
01076   else
01077     parentregion->AddItem (newblock);
01078   newblock->SetParentPtr (parentregion);
01079 
01080   // Put in C_MERGE and DUMMY_BR ops.
01081   for (alllist = proc->GetListOpPtr(); alllist->GetListOpPtr() != NULL;
01082        alllist = alllist->GetListOpPtr()) ;
01083   id = (FindMaxOpId (proc))->GetOpId() + 1;
01084 
01085   // op id (C_MERGE [u<>] [u<>])
01086   top = new legoOp (id++);
01087   top->SetOpcode (C_MERGE);
01088   top->SetParentBlockPtr (newblock);
01089   alllist->SetListOpPtr (top);
01090   alllist = top;
01091 
01092   oprd = new legoOprd;
01093   oprd->SetOprdType (OT_UNDEFINED);
01094   oprd->SetParentOpPtr (top);
01095   top->SetSrcOprdPtr (oprd);
01096   oprd = new legoOprd;
01097   oprd->SetOprdType (OT_UNDEFINED);
01098   oprd->SetParentOpPtr (top);
01099   top->SetDestOprdPtr (oprd);
01100 
01101   newblock->AddItem(top);
01102   dprintf ((OUTF, "Added C_MERGE %d to new basic block.\n", top->GetOpId()));
01103 
01104   // op id (DUMMY_BR [u<>] [u<>])
01105   dummy_br = new legoOp (id++);
01106   dummy_br->SetOpcode (DUMMY_BR);
01107   dummy_br->SetParentBlockPtr (newblock);
01108   alllist->SetListOpPtr (dummy_br);
01109   alllist = dummy_br;
01110 
01111   oprd = new legoOprd;
01112   oprd->SetOprdType (OT_UNDEFINED);
01113   oprd->SetParentOpPtr (dummy_br);
01114   dummy_br->SetSrcOprdPtr (oprd);
01115   oprd = new legoOprd;
01116   oprd->SetOprdType (OT_UNDEFINED);
01117   oprd->SetParentOpPtr (dummy_br);
01118   dummy_br->SetDestOprdPtr (oprd);
01119 
01120   top->SetNextLink (dummy_br);
01121   dummy_br->SetPrevLink (top);
01122   newblock->AddItem (dummy_br);
01123   dprintf ((OUTF, "Added DUMMY_BR %d to new basic block.\n",
01124             dummy_br->GetOpId()));
01125 
01126   // Add the edge between them.
01127   newedge = AddEdge (top, dummy_br, ET_CNTL);
01128   dprintf ((OUTF, "Added edge %d between new ops.\n", newedge->GetEdgeId()));
01129 
01130   // Now, take the edge that points to toregion and point it to 
01131   // the new block instead.
01132   RedirectEdge (edge, EDGE_TO, top);
01133   dprintf ((OUTF, "Redirected edge %d to point to op %d.\n",
01134             edge->GetEdgeId(), top->GetOpId()));
01135 
01136   // Set the new block's weight to the weight of the incoming edge.
01137   fromweight = (double) FindEdgeFrequency (edge);
01138   newblock->SetWeight (fromweight);
01139 
01140   // Next, add an edge between the newblock and toregion, and update the
01141   // outLists and inLists.
01142   newedge = AddEdge (dummy_br, toop, ET_CNTL);
01143   AddFreqAttribute ((int) fromweight, 0, newedge);
01144   dprintf ((OUTF, "Added edge %d from new basic block to following block.\n",
01145             newedge->GetEdgeId()));
01146 
01147   opl = new opList;
01148   dummy_br->SetOutListPtr (opl);
01149   opl->SetOpPtr (toop);
01150   opl->SetOpId (toop->GetOpId());
01151   opl->SetValid (1);
01152   opl->SetWeight (fromweight);
01153   dprintf ((OUTF, "Added ref to op %d to dummy_br %d.\n", toop->GetOpId(),
01154             dummy_br->GetOpId()));
01155 
01156   // Add ref to dummy_br to inList of to block.
01157   opl = AddToList (toop->GetInListPtr(), dummy_br, 1, fromweight);
01158   toop->SetInListPtr (opl);
01159   dprintf ((OUTF, "Added ref the other way.\n"));
01160 
01161   // Before we exit, refresh the following regions:
01162   // * newblock
01163   // * toregion and all its parents (same as newblock's)
01164   // * fromregion and all its parents
01165 
01166   ClearMarks (RM_GENERAL, proc);
01167 
01168   dprintf ((OUTF, "Refreshing new block...\n"));
01169   newblock->RefreshOpsAndEdges();
01170   newblock->Mark (RM_GENERAL);
01171 
01172   dprintf ((OUTF, "Refreshing toregion and parents...\n"));
01173   toregion->RefreshEdges();  // ops didn't change
01174   for (r = toregion->GetParentPtr(); r->GetRegionType() != RT_MODULE;
01175        r = r->GetParentPtr())
01176     {
01177       r->RefreshOpsAndEdges();  // ops may have changed, edges did
01178       r->Mark (RM_GENERAL);
01179     } // end for
01180 
01181   dprintf ((OUTF, "Refreshing fromregion and parents...\n"));
01182   fromregion->RefreshEdges();  // ops didn't change
01183   for (r = fromregion->GetParentPtr(); r->GetRegionType() != RT_MODULE;
01184        r = r->GetParentPtr())
01185     {
01186       if (r->IsMarked (RM_GENERAL)) break;  // hit common parent, stop!
01187       r->RefreshEdges();  // ops didn't change
01188       r->Mark (RM_GENERAL);
01189     } // end for
01190 
01191   dprintf ((OUTF, "Done creating new block.\n"));
01192   return newblock;
01193 } // end AddBBAlongEdge
01194 
01195 
01196 /*
01197  * SplitParentBlockBeforeOp 
01198  * op_ptr - split before this instruction 
01199  *
01200  * Splits the parent block of op_ptr right before it, 
01201  * and returns ptr to the new block. 
01202  * NOT TESTED FOR HB,SB 
01203  */ 
01204 legoRegion *SplitParentBlockBeforeOp(legoOp *op_ptr)
01205 {
01206    legoProc     *proc_ptr               = NULL;
01207    legoOp       *branch_from_region     = NULL;
01208    legoRegion   *from_region            = NULL;
01209    legoRegion   *new_region             = NULL;
01210    legoRegion   *parent_region          = NULL;
01211    int          index                   = 0;
01212    int          this_edge_weight        = 0;    // assume edge freq.
01213    int          max_op_id               = 0;
01214 
01215    if(!op_ptr){
01216         LegoNonFatal ("SplitParentBlockBeforeOp", "Empty argument passed");
01217         return  NULL;
01218    }
01219    if(!(proc_ptr = (legoProc *) FindParentRegionType (RT_PROC, op_ptr))){
01220         LegoNonFatal ("SplitParentBlockBeforeOp", "Couldn't find proc of op %d.",op_ptr->GetOpId());
01221         return NULL;
01222    }
01223    if(!(from_region = (legoRegion *)op_ptr->GetParentBlockPtr())){
01224         LegoNonFatal ("SplitParentBlockBeforeOp", "Couldn't find Parent block of op %d.",op_ptr->GetOpId());
01225         return NULL;
01226    }
01227    if(!(branch_from_region = op_ptr->GetPrevLink())){
01228         LegoNonFatal ("SplitParentBlockBeforeOp", "Empty GetPrevLink");
01229         return NULL;
01230    }
01231    //
01232    // Create new region (BB)
01233    //
01234    new_region           = new legoBB((proc_ptr->FindMaxRegionId()->GetRegionId())+1);
01235    parent_region        = from_region->GetParentPtr();
01236    this_edge_weight     = (int)from_region->GetWeight();
01237    max_op_id            = (FindMaxOpId(proc_ptr))->GetOpId()+1;
01238 
01239    for(index=0;index<parent_region->GetCount();index++)
01240         if(from_region==(legoRegion *)parent_region->GetItem(index))    break;
01241 
01242    if(index < (parent_region->GetCount())-1)    parent_region->Insert(new_region,index+1);
01243    else                                         parent_region->AddItem(new_region);
01244 
01245    new_region->SetParentPtr(parent_region);
01246    //
01247    // Step 1: Put C_MERGE
01248    //
01249    legoOp       *alllist,*top,*dummy_br,*pbrr;
01250 
01251    for(alllist=proc_ptr->GetListOpPtr();alllist->GetListOpPtr()!=NULL;alllist=alllist->GetListOpPtr()) ;
01252    top          = new legoOp (max_op_id++);
01253    top->SetOpcode (C_MERGE);
01254    top->SetParentBlockPtr (new_region);
01255    alllist->SetListOpPtr (top);
01256    alllist      = top;
01257 
01258    legoOprd     *oprd   = new legoOprd;
01259    oprd->SetOprdType (OT_UNDEFINED);
01260    oprd->SetParentOpPtr (top);
01261    top->SetSrcOprdPtr (oprd);
01262    oprd = new legoOprd;
01263    oprd->SetOprdType (OT_UNDEFINED);
01264    oprd->SetParentOpPtr (top);
01265    top->SetDestOprdPtr (oprd);
01266    new_region->AddItem(top);
01267    //
01268    // Step 2: Put DUMMY_BR
01269    //
01270    dummy_br     = new legoOp (max_op_id++);
01271    dummy_br->SetOpcode (DUMMY_BR);
01272    dummy_br->SetParentBlockPtr (new_region);
01273    alllist->SetListOpPtr (dummy_br);
01274    alllist      = dummy_br;
01275 
01276    oprd = new legoOprd;
01277    oprd->SetOprdType (OT_UNDEFINED);
01278    oprd->SetParentOpPtr (dummy_br);
01279    dummy_br->SetSrcOprdPtr (oprd);
01280    oprd = new legoOprd;
01281    oprd->SetOprdType (OT_UNDEFINED);
01282    oprd->SetParentOpPtr (dummy_br);
01283    dummy_br->SetDestOprdPtr (oprd);
01284 
01285    top->SetNextLink (dummy_br);
01286    dummy_br->SetPrevLink (top);
01287    new_region->AddItem (dummy_br);
01288 
01289    //
01290    // Step 3: Add the edge between them.
01291    //
01292    opEdges *new_edge = AddEdge (top, dummy_br, ET_CNTL);
01293    //
01294    // Step 4: copy op from op_ptr to new_region
01295    //
01296    legoOp          *current_op          = top;
01297    legoOp          *copy_op_ptr         = NULL;
01298    attrs           *attrdictionary;
01299    attrs           *attrtail, *atscan;
01300    attrList        *atlscan;
01301    int             eaid                 = FindMaxEdgeAttrId(proc_ptr);
01302 
01303    if(!(attrdictionary = proc_ptr->GetAttrDictionary())){
01304         LegoNonFatal ("SplitParentBlockBeforeOp", "Attribute dictionary is missing.");
01305         return NULL;
01306    }
01307    for (attrtail = attrdictionary; attrtail->GetNextAttrPtr(); attrtail = attrtail->GetNextAttrPtr()) ;    // find the last one
01308 
01309    for(legoOp *my_op=op_ptr;my_op!=NULL;my_op=my_op->GetNextLink()){ 
01310                 copy_op_ptr     = new legoOp(*my_op);
01311                 copy_op_ptr->SetParentBlockPtr(new_region);
01312                 AddMidOp(copy_op_ptr,current_op);
01313                 // copy op attributes
01314                 //
01315                 for (atlscan = copy_op_ptr->GetOpAttrListPtr();atlscan;atlscan = atlscan->GetNextListPtr()){
01316                         if (atlscan->GetAttrPtr() == NULL)      continue;
01317                         atscan          = new attrs (*(atlscan->GetAttrPtr()),copy_op_ptr,++eaid);
01318                         atlscan->SetAttrPtr (atscan);
01319                         atscan->SetAttrId (eaid);
01320                         atlscan->SetAttrId (eaid);
01321                         attrtail->SetNextAttrPtr (atscan);
01322                         attrtail        = attrtail->GetNextAttrPtr();
01323                 }
01324                 current_op      = copy_op_ptr;
01325    }
01326    //
01327    // Step 5: remove ops in from_region
01328    //
01329    legoOp *next_op;
01330    for(legoOp *my_op = op_ptr;my_op;my_op=next_op){
01331                 if(next_op = my_op->GetNextLink())      RemoveMidOp(my_op,1);
01332                 else                                    RemoveLastOp(my_op,1);
01333    }
01334    // record the last branch in new region
01335    //
01336    legoOp  *last_branch_new_region = dummy_br->GetPrevLink();
01337    // 
01338    // Step 6: remove dummy_br in new_region
01339    // 
01340    RemoveLastOp(dummy_br,1);
01341    //
01342    // Step 7: set weight in new_region
01343    //
01344    new_region->SetWeight(from_region->GetWeight());
01345    //
01346    // Step 8: create opList for top in new region
01347    //
01348    opList *top_op_list=new opList();
01349    top->SetInListPtr(top_op_list);
01350    top_op_list->SetOpPtr(branch_from_region);
01351    top_op_list->SetOpId(branch_from_region->GetOpId());
01352    top_op_list->SetValid(1);
01353    top_op_list->SetWeight(this_edge_weight);
01354    //
01355    // Step 9: create entryoplist for new_region
01356    //
01357    opList *entry_op_list=new opList();
01358    entry_op_list->SetOpPtr(top);
01359    entry_op_list->SetOpId(top->GetOpId());
01360    entry_op_list->SetValid(1);
01361    new_region->SetEntryOpsPtr(entry_op_list);
01362    //
01363    // Step 10: create exitoplist for new_region
01364    //
01365    opList *exit_op_list=new opList();
01366    exit_op_list->SetOpPtr(last_branch_new_region);
01367    exit_op_list->SetOpId(last_branch_new_region->GetOpId());
01368    exit_op_list->SetValid(1);
01369    new_region->SetExitOpsPtr(exit_op_list);
01370    //
01371    // Step 11:  Search the last opEdge in the edge dictionary
01372    //
01373    opEdges *last_op_edge;
01374    opEdges *edge_dict=proc_ptr->GetEdgeDictionary();
01375    for(last_op_edge=edge_dict;last_op_edge->GetNextOpEdgePtr()!=NULL;last_op_edge=last_op_edge->GetNextOpEdgePtr());
01376    //
01377    // Step 12: create new opEdges to connect branch_from_region & top
01378    //
01379    opEdges *new_op_edge    = new opEdges();
01380    new_op_edge->SetEdgeType(ET_CNTL);
01381    new_op_edge->SetEdgeId(last_op_edge->GetEdgeId()+1);
01382    new_op_edge->SetFromOpId(branch_from_region->GetOpId());
01383    new_op_edge->SetToOpId(top->GetOpId());
01384    new_op_edge->SetFromOpPtr(branch_from_region);
01385    new_op_edge->SetToOpPtr(top);
01386    new_op_edge->SetNextOpEdgePtr(NULL);
01387    new_op_edge->SetSrcPortType(PT_CTL);
01388    new_op_edge->SetDestPortType(PT_CTL);
01389    new_op_edge->SetEdgeLat(1);
01390 
01391    last_op_edge->SetNextOpEdgePtr(new_op_edge);
01392    AddFreqAttribute(this_edge_weight,0,new_op_edge);
01393    //
01394    // Step 13: create edgeList to new_op_edge
01395    //          and SetInEdgePtr in new_region
01396    //
01397    edgeList *new_edge_list=new edgeList();
01398    new_edge_list->SetValid(1);
01399    new_edge_list->SetEdgePtr(new_op_edge);
01400    new_edge_list->SetEdgeId(new_op_edge->GetEdgeId());
01401    new_region->SetInEdgesPtr(new_edge_list);
01402    //
01403    // Step 14:  SetOutEdgePtr in new_region
01404    //           and update all of them accordingly 
01405    //
01406    new_region->SetOutEdgesPtr(from_region->GetOutEdgesPtr());
01407 
01408    edgeList     *out_edges_of_original_block    =       new_region->GetOutEdgesPtr();
01409    opEdges      *current_out_edge               =       NULL;
01410 
01411    while(out_edges_of_original_block){
01412         if(current_out_edge = out_edges_of_original_block->GetEdgePtr()) 
01413                 current_out_edge->SetFromOpPtr(last_branch_new_region);
01414         out_edges_of_original_block     = out_edges_of_original_block->GetNextListPtr();
01415    }
01416    //
01417    // Step 15: create edgeList to new_op_edge
01418    //          and SetOutEdgePtr in from_region
01419    //
01420    new_edge_list=new edgeList();
01421    new_edge_list->SetValid(1);
01422    new_edge_list->SetEdgePtr(new_op_edge);
01423    new_edge_list->SetEdgeId(new_op_edge->GetEdgeId());
01424    from_region->SetOutEdgesPtr(new_edge_list);
01425    //
01426    // Step 16: create opList for branch_from_region
01427    //
01428    opList *bfr_op_list=new opList();
01429    branch_from_region->SetOutListPtr(bfr_op_list);
01430    bfr_op_list->SetOpPtr(top);
01431    bfr_op_list->SetOpId(top->GetOpId());
01432    bfr_op_list->SetValid(1);
01433    bfr_op_list->SetWeight(this_edge_weight);
01434    //
01435    // Step 17: create exitoplist for from_region
01436    //
01437    exit_op_list=new opList();
01438    exit_op_list->SetOpPtr(branch_from_region);
01439    exit_op_list->SetOpId(branch_from_region->GetOpId());
01440    exit_op_list->SetValid(1);
01441    from_region->SetExitOpsPtr(exit_op_list);
01442    //
01443    // Step 18: return ptr to the new_region
01444    //
01445    return new_region;
01446 }
01447 
01448 // ========================================================================
01449 
01450 static flags *
01451 AddFlag (int flagname, void *object, int objtype)
01452 {
01453   flags *f;
01454 
01455   if (objtype == ADDREMOVE_REGION)
01456     f = ((legoRegion *) object)->GetFlagPtr();
01457   else
01458     f = ((legoOp *) object)->GetOpFlagPtr();
01459 
01460   for ( ; f != NULL && f->GetNextFlagPtr() != NULL;  // don't step past last!
01461         f = f->GetNextFlagPtr())
01462     if (f->GetFlagName() == flagname) return f;
01463   if (f != NULL && f->GetFlagName() == flagname) return f;  // for last flag
01464 
01465   // Make new flag and attach appropriately.
01466   if (f == NULL)
01467     {
01468       f = new flags;
01469       if (objtype == ADDREMOVE_REGION)
01470         ((legoRegion *) object)->SetFlagPtr (f);
01471       else
01472         ((legoOp *) object)->SetFlagPtr (f);
01473     } // end if
01474   else
01475     {
01476       f->SetNextFlagPtr (new flags);
01477       f = f->GetNextFlagPtr();
01478     } // end else
01479   f->SetFlagName (flagname);
01480 
01481   return f;
01482 } // end AddFlag (object)
01483 
01484 /*
01485  * AddFlag
01486  *   flagname = name of flag to be added
01487  *   region = region within which flag is added
01488  *   returns: new flag or existing flag with same name
01489  *
01490  * Adds flag with name flagname to region.
01491  */
01492 flags *
01493 AddFlag (int flagname, legoRegion *region)
01494 {
01495   return AddFlag (flagname, (void *) region, ADDREMOVE_REGION);
01496 } // end AddFlag (region)
01497 
01498 /*
01499  * AddFlag
01500  *   flagname = name of flag to be added
01501  *   op = op for which flag is added
01502  *   returns: new flag or existing flag with same name
01503  *
01504  * Adds flag with name flagname to op.
01505  */
01506 flags *
01507 AddFlag (int flagname, legoOp *op)
01508 {
01509   return AddFlag (flagname, (void *) op, ADDREMOVE_OP);
01510 } // end AddFlag (op)
01511 
01512 // ========================================================================
01513 
01514 static void
01515 RemoveFlag (int flagname, void *object, int objtype)
01516 {
01517   flags *fprev, *f;
01518 
01519   fprev = NULL;
01520   if (objtype == ADDREMOVE_REGION)
01521     f = ((legoRegion *) object)->GetFlagPtr();
01522   else
01523     f = ((legoOp *) object)->GetOpFlagPtr();
01524   if (f == NULL) return;  // no flags
01525 
01526   // Find the flag with the name flagname.
01527   for ( ; f->GetFlagName() != flagname;
01528         fprev = f, f = f->GetNextFlagPtr()) /* do nothing */;
01529   if (f == NULL) return;  // flag not there
01530 
01531   // Remove f from the list of flags.
01532   if (fprev == NULL)
01533     {
01534       if (objtype == ADDREMOVE_REGION)
01535         ((legoRegion *) object)->SetFlagPtr (f->GetNextFlagPtr());
01536       else
01537         ((legoOp *) object)->SetFlagPtr (f->GetNextFlagPtr());
01538     } // end if
01539   else
01540     fprev->SetNextFlagPtr (f->GetNextFlagPtr());
01541   f->SetNextFlagPtr (NULL);
01542   delete f;
01543 
01544   return;
01545 } // end RemoveFlag (object)
01546 
01547 /*
01548  * RemoveFlag
01549  *   flagname = name of flag to be removed
01550  *   region = region within which flag is removed
01551  *
01552  * Removes flag with name flagname from region.
01553  */
01554 void
01555 RemoveFlag (int flagname, legoRegion *region)
01556 {
01557   RemoveFlag (flagname, (void *) region, ADDREMOVE_REGION);
01558 } // end RemoveFlag (region)
01559 
01560 /*
01561  * RemoveFlag
01562  *   flagname = name of flag to be removed
01563  *   op = op for which flag is removed
01564  *
01565  * Removes flag with name flagname from op.
01566  */
01567 void
01568 RemoveFlag (int flagname, legoOp *op)
01569 {
01570   RemoveFlag (flagname, (void *) op, ADDREMOVE_OP);
01571 } // end RemoveFlag (op)
01572 
01573 // ========================================================================
01574 
01575 attrs *
01576 AddPointerAttribute (enum attrTypes atype, char *lcname, legoOprd *oprd,
01577                      void *object, int objtype, legoProc *proc)
01578 {
01579   opEdges *edgedictionary;
01580   attrs *newattr, *attrdictionary;
01581   attrList *atl;
01582   int foundit, maxeaid;
01583 
01584   // Get dictionaries and scan for highest id.
01585   edgedictionary = proc->GetEdgeDictionary();
01586   if (edgedictionary == NULL)
01587     {
01588       LegoNonFatal ("AddPointerAttribute", "Edge dictionary is missing.");
01589       return NULL;
01590     } // end if
01591   attrdictionary = proc->GetAttrDictionary();
01592   if (attrdictionary == NULL)
01593     {
01594       LegoNonFatal ("AddPointerAttribute", "Attribute dictionary is missing.");
01595       return NULL;
01596     } // end if
01597   maxeaid = -1;
01598 
01599   for ( ; edgedictionary != NULL;
01600         edgedictionary = edgedictionary->GetNextOpEdgePtr())
01601     if (edgedictionary->GetEdgeId() > maxeaid)
01602       maxeaid = edgedictionary->GetEdgeId();
01603   for ( ; attrdictionary->GetNextAttrPtr() != NULL;  // don't step past last!
01604         attrdictionary = attrdictionary->GetNextAttrPtr())
01605     if (attrdictionary->GetAttrId() > maxeaid)
01606       maxeaid = attrdictionary->GetAttrId();
01607   if (attrdictionary->GetAttrId() > maxeaid)
01608     maxeaid = attrdictionary->GetAttrId();  // for last attrs in dictionary
01609 
01610   // Find "atype" type attrList of object, or create empty one if absent.
01611   if (objtype == ADDREMOVE_REGION)
01612     atl = ((legoRegion *) object)->GetRegionAttrListPtr();
01613   else if (objtype == ADDREMOVE_OP)
01614     atl = ((legoOp *) object)->GetOpAttrListPtr();
01615   else
01616     atl = ((opEdges *) object)->GetEdgeAttrListPtr();
01617   for ( ; atl != NULL && atl->GetNextListPtr() != NULL;
01618         atl = atl->GetNextListPtr())
01619     if (atl->GetAttrType() == atype) break;
01620   if (atl == NULL)
01621     {
01622       atl = new attrList;
01623       if (objtype == ADDREMOVE_REGION)
01624         ((legoRegion *) object)->SetRegionAttrListPtr (atl);
01625       else if (objtype == ADDREMOVE_OP)
01626         ((legoOp *) object)->SetOpAttrListPtr (atl);
01627       else
01628         ((opEdges *) object)->SetEdgeAttrListPtr (atl);
01629       atl->SetAttrType (atype);
01630       atl->SetValid (1);
01631     } // end if
01632   else if (atl->GetAttrType() != atype)
01633     {
01634       atl->SetNextListPtr (new attrList);
01635       atl = atl->GetNextListPtr();
01636       atl->SetAttrType (atype);
01637       atl->SetValid (1);
01638     } // end else
01639 
01640   // Search for preexisting "lcname" attribute, or create if missing.
01641   if (atype == ATTR_LC)
01642     {
01643       for (foundit = 0, newattr = atl->GetAttrPtr();
01644            newattr != NULL && newattr->GetNextLcEntryPtr() != NULL;
01645            newattr = newattr->GetNextLcEntryPtr())
01646         if (strcmp (newattr->GetAttrString(), lcname) == 0)
01647           {
01648             foundit = 1; break;
01649           } // end if
01650       if (newattr != NULL &&
01651           strcmp (newattr->GetAttrString(), lcname) == 0)  // get last one
01652         foundit = 1;
01653     } // end if
01654   else
01655     newattr = atl->GetAttrPtr();  // get first attr if not lc(ode)
01656   if (newattr == NULL)
01657     {
01658       newattr = new attrs;
01659       atl->SetAttrPtr (newattr);
01660       newattr->SetAttrId (++maxeaid);
01661       atl->SetAttrId (maxeaid);
01662       attrdictionary->SetNextAttrPtr (newattr);
01663       attrdictionary = attrdictionary->GetNextAttrPtr();
01664     } // end if
01665   else if (!foundit && atype == ATTR_LC)
01666     {
01667       newattr->SetNextLcEntryPtr (new attrs);
01668       newattr = newattr->GetNextLcEntryPtr();
01669       //      newattr->SetAttrId (++maxeaid);
01670       //      attrdictionary->SetNextAttrPtr (newattr);
01671       //      attrdictionary = attrdictionary->GetNextAttrPtr();
01672     } // end else
01673 
01674   // Set attribute fields and quit.
01675   newattr->SetAttrType (atype);  // OK even if already there
01676   newattr->SetAttrString (lcname); // ditto
01677   delete newattr->GetAttrOprdPtr();  // OK even if NOT already there
01678   newattr->SetAttrOprdPtr (oprd);
01679   if (oprd != NULL)
01680     {
01681       oprd->SetParentAttrPtr (newattr);
01682       if (objtype == ADDREMOVE_OP)
01683         oprd->SetParentOpPtr ((legoOp *) object);
01684     } // end if
01685   return newattr;
01686 } // end AddPointerAttribute
01687 
01688 // ========================================================================
01689 
01690 /*
01691  * AddLcAttribute
01692  *   lcname = name of lc attribute
01693  *   oprd = new value of attribute
01694  *   region = region within which attribute is added
01695  *   proc = proc which contains region
01696  *   returns: new attribute, or existing attribute with same name
01697  *
01698  * Adds lc attribute with name lcname and value oprd to region.
01699  */
01700 attrs *
01701 AddLcAttribute (char *lcname, legoOprd *oprd, legoRegion *region,
01702                 legoProc *proc)
01703 {
01704   return AddPointerAttribute (ATTR_LC, lcname, oprd, (void *) region,
01705                               ADDREMOVE_REGION, proc);
01706 } // end AddLcAttribute (region)
01707 
01708 /*
01709  * AddLcAttribute
01710  *   lcname = name of lc attribute
01711  *   oprd = new value of attribute
01712  *   op = op for which attribute is added
01713  *   proc = proc which contains op
01714  *   returns: new attribute, or existing attribute with same name
01715  *
01716  * Adds lc attribute with name lcname and value oprd to op.
01717  */
01718 attrs *
01719 AddLcAttribute (char *lcname, legoOprd *oprd, legoOp *op, legoProc *proc)
01720 {
01721   return AddPointerAttribute (ATTR_LC, lcname, oprd, (void *) op,
01722                               ADDREMOVE_OP, proc);
01723 } // end AddLcAttribute (op)
01724 
01725 /*
01726  * AddLcAttribute
01727  *   lcname = name of lc attribute
01728  *   oprd = new value of attribute
01729  *   edge = edge for which attribute is added
01730  *   proc = proc which contains edge
01731  *   returns: new attribute, or existing attribute with same name
01732  *
01733  * Adds lc attribute with name lcname and value oprd to edge.
01734  */
01735 attrs *
01736 AddLcAttribute (char *lcname, legoOprd *oprd, opEdges *edge, legoProc *proc)
01737 {
01738   return AddPointerAttribute (ATTR_LC, lcname, oprd, (void *) edge,
01739                               ADDREMOVE_EDGE, proc);
01740 } // end AddLcAttribute (edge)
01741 
01742 
01743 /*
01744  * AddLiveAttribute
01745  *   oprd = new value of attribute
01746  *   region = region within which attribute is added
01747  *   proc = proc which contains region
01748  *   returns: new attribute, or existing attribute with same name
01749  *
01750  * Adds live attribute with value oprd to region.
01751  */
01752 attrs *
01753 AddLiveAttribute (legoOprd *oprd, legoRegion *region, legoProc *proc)
01754 {
01755   return AddPointerAttribute (ATTR_LIVE, NULL, oprd, (void *) region,
01756                               ADDREMOVE_REGION, proc);
01757 } // end AddLiveAttribute (region)
01758 
01759 /*
01760  * AddLiveAttribute
01761  *   oprd = new value of attribute
01762  *   op = op for which attribute is added
01763  *   proc = proc which contains op
01764  *   returns: new attribute, or existing attribute with same name
01765  *
01766  * Adds live attribute with value oprd to op.
01767  */
01768 attrs *
01769 AddLiveAttribute (legoOprd *oprd, legoOp *op, legoProc *proc)
01770 {
01771   return AddPointerAttribute (ATTR_LIVE, NULL, oprd, (void *) op,
01772                               ADDREMOVE_OP, proc);
01773 } // end AddLiveAttribute (op)
01774 
01775 /*
01776  * AddLiveAttribute
01777  *   oprd = new value of attribute
01778  *   edge = edge for which attribute is added
01779  *   proc = proc which contains edge
01780  *   returns: new attribute, or existing attribute with same name
01781  *
01782  * Adds live attribute with value oprd to edge.
01783  */
01784 attrs *
01785 AddLiveAttribute (legoOprd *oprd, opEdges *edge, legoProc *proc)
01786 {
01787   return AddPointerAttribute (ATTR_LIVE, NULL, oprd, (void *) edge,
01788                               ADDREMOVE_EDGE, proc);
01789 } // end AddLiveAttribute (edge)
01790 
01791 // ========================================================================
01792 
01793 static void
01794 RemovePointerAttribute (int atype, char *lcname, void *object, int objtype,
01795                         legoProc *proc)
01796 {
01797   attrList *atl, *atlprev;
01798   attrs *aprev, *a, *adictprev, *adict;
01799   int i;
01800 
01801   // Scan through region attribute list for lc attribute.
01802   if (objtype == ADDREMOVE_REGION)
01803     atl = ((legoRegion *) object)->GetRegionAttrListPtr();
01804   else if (objtype == ADDREMOVE_OP)
01805     atl = ((legoOp *) object)->GetOpAttrListPtr();
01806   else
01807     atl = ((opEdges *) object)->GetEdgeAttrListPtr();
01808 
01809   for (atlprev = NULL;
01810        atl != NULL;
01811        atlprev = atl, atl = atl->GetNextListPtr())
01812     {
01813       if (atl->GetAttrType() != atype) continue;
01814 
01815       aprev = NULL;
01816       if (atype == ATTR_LC)
01817         {
01818           for (a = atl->GetAttrPtr();
01819                a != NULL;
01820                aprev = a, a = a->GetNextLcEntryPtr())
01821             if (strcmp (a->GetAttrString(), lcname) == 0) break;
01822         } // end if
01823       else
01824         a = atl->GetAttrPtr();
01825       if (a == NULL) continue;
01826 
01827       // Remove a from attribute dictionary if a is the first lc
01828       // attribute in its lc list. 
01829       if (aprev == NULL)  // a is the first (lc) attribute
01830         {
01831           adict = proc->GetAttrDictionary();
01832           if (adict != NULL)
01833             {
01834               // Find a in dictionary.
01835               for (adictprev = NULL; adict != NULL;
01836                    adictprev = adict, adict = adict->GetNextAttrPtr())
01837                 if (adict == a) break;
01838 
01839               // adictprev now points to the attribute before a in the
01840               // attribute dictionary.
01841               // If a is the only lc attribute in its list, remove
01842               // the attribute from the dictionary completely. Otherwise,
01843               // swap in the one next in line.
01844               if (atype == ATTR_LC && a->GetNextLcEntryPtr() != NULL)
01845                 {  // swap in next one
01846                   if (adictprev != NULL)  // not first attr in dict
01847                     adictprev->SetNextAttrPtr (a->GetNextLcEntryPtr());
01848                   else
01849                     proc->SetAttrDictionary (a->GetNextLcEntryPtr());
01850                   a->GetNextLcEntryPtr()->SetNextAttrPtr
01851                     (a->GetNextAttrPtr());
01852                   a->GetNextLcEntryPtr()->SetAttrType (ATTR_LC);
01853                   a->GetNextLcEntryPtr()->SetAttrId (a->GetAttrId());
01854 
01855                   atl->SetAttrPtr (a->GetNextLcEntryPtr());
01856                 } // end if
01857               else
01858                 {  // Remove completely.
01859                   if (adictprev != NULL)
01860                     adictprev->SetNextAttrPtr (a->GetNextAttrPtr());
01861                   else
01862                     proc->SetAttrDictionary (a->GetNextAttrPtr());
01863                   // Can leave atl alone, it will be deleted next...
01864                 } // end else
01865             } // end if
01866 
01867           // Remove the attrList completely if it only refers to this
01868           // one (only possible if this is the only lc attribute).
01869           if (atype != ATTR_LC || a->GetNextLcEntryPtr() == NULL)
01870             {
01871               if (atlprev != NULL)
01872                 atlprev->SetNextListPtr (atl->GetNextListPtr());
01873               else
01874                 {
01875                   if (objtype == ADDREMOVE_REGION)
01876                     ((legoRegion *) object)->SetRegionAttrListPtr
01877                       (atl->GetNextListPtr());
01878                   else if (objtype == ADDREMOVE_OP)
01879                     ((legoOp *) object)->SetOpAttrListPtr
01880                       (atl->GetNextListPtr());
01881                   else
01882                     ((opEdges *) object)->SetEdgeAttrListPtr
01883                       (atl->GetNextListPtr());
01884                   } // end else
01885               atl->SetNextListPtr (NULL);
01886               delete atl;
01887               atl = atlprev;  // back up for next iteration
01888             } // end if
01889 
01890           a->SetNextLcEntryPtr (NULL);
01891           a->SetNextAttrPtr (NULL);
01892           delete a;
01893 
01894           if (atl == NULL) break;
01895         } // end if
01896       else // a is not the first attribute in list
01897         {
01898           aprev->SetNextLcEntryPtr (a->GetNextLcEntryPtr());
01899           a->SetNextLcEntryPtr (NULL);
01900           a->SetNextAttrPtr (NULL);
01901           delete a;
01902         } // end else
01903     } // end for
01904 
01905   return;
01906 } // end RemovePointerAttribute
01907 
01908 // ========================================================================
01909 
01910 /*
01911  * RemoveLcAttribute
01912  *   lcname = name of lc attribute
01913  *   region = region within which attribute is removed
01914  *   proc = proc which contains region
01915  *
01916  * Removes lc attribute with name lcname from existence.
01917  */
01918 void
01919 RemoveLcAttribute (char *lcname, legoRegion *region, legoProc *proc)
01920 {
01921   RemovePointerAttribute (ATTR_LC, lcname, (void *) region,
01922                           ADDREMOVE_REGION, proc);
01923   return;
01924 } // end RemoveLcAttribute (region);
01925 
01926 /*
01927  * RemoveLcAttribute
01928  *   lcname = name of lc attribute
01929  *   op = op for which attribute is removed
01930  *   proc = proc which contains op
01931  *
01932  * Removes lc attribute with name lcname from existence.
01933  */
01934 void
01935 RemoveLcAttribute (char *lcname, legoOp *op, legoProc *proc)
01936 {
01937   RemovePointerAttribute (ATTR_LC, lcname, (void *) op,
01938                           ADDREMOVE_OP, proc);
01939   return;
01940 } // end RemoveLcAttribute (op)
01941 
01942 /*
01943  * RemoveLcAttribute
01944  *   lcname = name of lc attribute
01945  *   edge = edge for which attribute is removed
01946  *   proc = proc which contains edge
01947  *
01948  * Removes lc attribute with name lcname from existence.
01949  */
01950 void
01951 RemoveLcAttribute (char *lcname, opEdges *edge, legoProc *proc)
01952 {
01953   RemovePointerAttribute (ATTR_LC, lcname, (void *) edge,
01954                           ADDREMOVE_EDGE, proc);
01955   return;
01956 } // end RemoveLcAttribute (edge)
01957 
01958 /*
01959  * RemoveLiveAttribute
01960  *   region = region within which attribute is removed
01961  *   proc = proc which contains region
01962  *
01963  * Removes live attribute from existence.
01964  */
01965 void
01966 RemoveLiveAttribute (legoRegion *region, legoProc *proc)
01967 {
01968   RemovePointerAttribute (ATTR_LIVE, NULL, (void *) region,
01969                           ADDREMOVE_REGION, proc);
01970   return;
01971 } // end RemoveLiveAttribute (region);
01972 
01973 /*
01974  * RemoveLiveAttribute
01975  *   op = op for which attribute is removed
01976  *   proc = proc which contains op
01977  *
01978  * Removes live attribute from existence.
01979  */
01980 void
01981 RemoveLiveAttribute (legoOp *op, legoProc *proc)
01982 {
01983   RemovePointerAttribute (ATTR_LIVE, NULL, (void *) op,
01984                           ADDREMOVE_OP, proc);
01985   return;
01986 } // end RemoveLiveAttribute (op)
01987 
01988 /*
01989  * RemoveLiveAttribute
01990  *   edge = edge for which attribute is removed
01991  *   proc = proc which contains edge
01992  *
01993  * Removes live attribute from existence.
01994  */
01995 void
01996 RemoveLiveAttribute (opEdges *edge, legoProc *proc)
01997 {
01998   RemovePointerAttribute (ATTR_LIVE, NULL, (void *) edge,
01999                           ADDREMOVE_EDGE, proc);
02000   return;
02001 } // end RemoveLiveAttribute (edge)
02002 
02003 // ========================================================================
02004 
02005 /*
02006  * AddFreqAttribute
02007  *   weight = profile weight
02008  *   value = 0 for DUMMY_BR, 1/0 for conditional branch taken/not taken,
02009  *     cc value for jumptable edge, 1 for control merge (regardless of ops)
02010  *   edge = edge to which to add attribute
02011  *
02012  * Adds freq attribute with weight and value to edge.
02013  */
02014 attrList *
02015 AddFreqAttribute (int weight, int value, opEdges *edge)
02016 {
02017   attrList *atl;
02018   intList *il;
02019 
02020   for (atl = edge->GetEdgeAttrListPtr(); atl != NULL &&
02021          atl->GetNextListPtr() != NULL; atl = atl->GetNextListPtr())
02022     if (atl->GetAttrType() == ATTR_FREQ) break;
02023 
02024   if (atl == NULL)
02025     {
02026       atl = new attrList;
02027       atl->SetAttrType (ATTR_FREQ);
02028       atl->SetValid (1);
02029       edge->SetEdgeAttrListPtr (atl);
02030     }
02031   else if (atl->GetAttrType() != ATTR_FREQ)
02032     {
02033       atl->SetNextListPtr (new attrList);
02034       atl = atl->GetNextListPtr();
02035       atl->SetAttrType (ATTR_FREQ);
02036       atl->SetValid (1);
02037     }
02038   il = atl->GetAttrValPtr();
02039   if (il == NULL)
02040     {
02041       il = new intList;
02042       atl->SetAttrValPtr (il);
02043     } // end if
02044   il->SetAttrValue (weight);
02045   if (il->GetNextIntListPtr() == NULL)
02046     il->SetNextIntListPtr (new intList);
02047   il->GetNextIntListPtr()->SetAttrValue (value);
02048 
02049   return atl;
02050 } // end AddFreqAttribute
02051 
02052 /*
02053  * RemoveFreqAttribute
02054  *   edge = edge from which to remove attribute
02055  *
02056  * Removes the freq attribute from an edge.
02057  */
02058 void
02059 RemoveFreqAttribute (opEdges *edge)
02060 {
02061   attrList *atl, *atlprev;
02062 
02063   for (atlprev = NULL, atl = edge->GetEdgeAttrListPtr();
02064        atl != NULL;
02065        atlprev = atl, atl = atl->GetNextListPtr())
02066     if (atl->GetAttrType() == ATTR_FREQ)
02067       {
02068         if (atlprev != NULL)
02069           atlprev->SetNextListPtr (atl->GetNextListPtr());
02070         else
02071           edge->SetEdgeAttrListPtr (atl->GetNextListPtr());
02072         atl->SetNextListPtr (NULL);
02073         delete atl;
02074         break;
02075       } // end if
02076   return;
02077 } // end RemoveFreqAttribute
02078 
02079 // ========================================================================
02080 
02081 /*
02082  * ClearMarks
02083  *   m = mark to clear
02084  *   region = region to look within for mark
02085  *
02086  * Clears the mark m from region and all regions it contains.
02087  */
02088 void
02089 ClearMarks (long long m, legoRegion *region)
02090 {
02091   legoRegion *component;
02092 
02093   region->Unmark (m);
02094   if (!(IS_BLOCK (region->GetRegionType())))
02095     for (unsigned i = 0; i < region->GetCount(); i++)
02096       {
02097         component = (legoRegion *) region->GetItem(i);
02098         if (IS_BLOCK (component->GetRegionType()))
02099           component->Unmark (m);  // to avoid recursing one more level
02100         else
02101           ClearMarks (m, component);
02102       } // end for
02103 
02104   return;
02105 } // end ClearMarks (legoRegion *)
02106 
02107 /*
02108  * ClearMarks
02109  *   m = mark to clear
02110  *   edge = edge to start with clearing mark
02111  *
02112  * Clears the mark m from edges and all edges following it.
02113  */
02114 void
02115 ClearMarks (long long m, opEdges *edge)
02116 {
02117   opEdges *e;
02118 
02119   for (e = edge; e != NULL; e = e->GetNextOpEdgePtr())
02120     e->Unmark (m);
02121   return;
02122 } // end ClearMarks (opEdges *)
02123 
02124 // ========================================================================

Generated on Mon Jul 21 20:23:58 2003 for TINKER LEGO DOC by doxygen 1.3.2