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

hammock.C

Go to the documentation of this file.
00001 /*
00002  * hammock.C
00003  *
00004  * Hammock conversion function.
00005  *
00006  * 5/13/97 WAH:  Created.
00007  * 6/12/97 WAH:  Modified initialization of NextPredRedNum to be
00008  *               next free register number over ALL registers.
00009  * 6/16/97 WAH:  Predicate copies also copy OprdRegType (had forgotten).
00010  * 10/11/97 WAH: Added setting of operand parentPtr.
00011  * 12/8/97 WAH:  Added explicit parameter to SweepOps call.
00012  * 1/16/98 WAH:  Cleaned up hammock function; added RM_HAMMOCK marking;
00013  *               added check for has_hb or has_sb flag before detection.
00014  * 1/21/98 WAH:  Fixed update of E block's incoming edge during if-conversion.
00015  * 1/22/98 WAH:  Changed AddWeightAttribute to make lcode attribute
00016  *               instead of using blockId field; proc now flagged has_hb.
00017  * 1/27/98 WAH:  Fixed if-conversion of hammock with sb S block.
00018  * 4/23/98 WAH:  Updated legoOprd::parentPtr.
00019  */
00020 
00021 #include <stdio.h>
00022 #include "lego.H"
00023 #include "legoUtil.H"
00024 #include "hyperform.H"
00025 #include "chains.H"
00026 #include "bitvector.H"
00027 
00028 //#define _HAMMOCK_DEBUG
00029 //#define _SHOW_VECTORS
00030 //#define dderr(_s_)  cerr << _s_
00031 #define dderr(_s_)  
00032 
00033 #ifdef _HAMMOCK_DEBUG
00034 legoModule *M = NULL;
00035 int numnum = 0;
00036 #define dderr(_s_)  cerr << _s_
00037 #define dprintf(s) fprintf s
00038 #define OUTF stderr
00039 #else
00040 #define dprintf(s)
00041 #endif // _HAMMOCK_DEBUG
00042 
00043 //#define HAMMOCK_WRITE_INTERMEDIATE_REBEL
00044 
00045 extern chains* Chains;
00046 
00047 //===========================================================================
00048 
00049 /*
00050  * isStraight
00051  *   r = pointer to region in question
00052  *   returns: 1 if r is straight, 0 otherwise
00053  *
00054  * Determines whether a region is straight, i.e., whether it has exactly
00055  * one parent and exactly one child.
00056  */
00057 static int isStraight (legoRegion *r)
00058 {
00059   regionList *l = r->GetParents();  // check if exactly one parent
00060   if (l == NULL || l->GetRegionPtr() == NULL || l->GetNextListPtr() != NULL)
00061     return 0;
00062 
00063   l = r->GetChildren();  // check if exactly one child
00064   if (l == NULL || l->GetRegionPtr() == NULL || l->GetNextListPtr() != NULL)
00065     return 0;
00066 
00067   return 1;  
00068 } // end isStraight
00069 
00070 /*
00071  * DetectHammock
00072  *   S = start block of hammock
00073  *   returns: hammock information
00074  *
00075  * Looks for a hammock starting at S (start) and stopping at J (join).
00076  * The hammock may be either a diamond shape (with two blocks T (then)
00077  * and E (else) - an if-then-else) or a triangular "delta" shape (with
00078  * one block T - and if-then) in between S and J.
00079  */
00080 hammock_info *DetectHammock (legoRegion *S)
00081 {
00082   hammock_info *h;
00083   legoRegion *temp;
00084   regionList *l;
00085   int foundS, foundT, foundE;
00086   int notdiamond;
00087 
00088   h = new hammock_info;
00089   if (!(IS_BLOCK(S->GetRegionType())))
00090     return h;
00091 
00092   // 1. S may only have exactly two children.
00093   l = S->GetChildren();  // l = children of S
00094   if (l == NULL || l->GetRegionPtr() == NULL) return h;
00095   h->T = l->GetRegionPtr();  // T = first child of S
00096   l = l->GetNextListPtr();
00097   if (l == NULL || l->GetRegionPtr() == NULL) return h;
00098   h->E = l->GetRegionPtr();  // E = second child of S
00099   if (l->GetNextListPtr() != NULL) return h;
00100 
00101   // 2. T must be straight and between different blocks; set J to its child.
00102   //    If T isn't straight, try switching T and E.
00103   notdiamond = 0;
00104   if (isStraight (h->T) && h->T->GetChildren()->GetRegionPtr() != S)
00105     {
00106       // T is fine.
00107       h->J = h->T->GetChildren()->GetRegionPtr();
00108     } // end if
00109   else
00110     {
00111       temp = h->T; h->T = h->E; h->E = temp;
00112       notdiamond = 1;  // If first T won't work, can't be a diamond!
00113       if (isStraight (h->T) && h->T->GetChildren()->GetRegionPtr() != S)
00114         {
00115           // T is now fine.
00116           h->J = h->T->GetChildren()->GetRegionPtr();
00117         } // end if
00118       else
00119         return h;  // neither one works, so give up
00120     } // end if
00121 
00122   // 3. Try to detect a delta: if J == E, and J has no parents besides
00123   //    S and T, it's a delta.
00124   if (h->J == h->E)  // may be a delta
00125     {
00126       while (1)  // this is a kludge to allow the breaks out of the testing
00127         {
00128           foundS = foundT = 0;
00129           l = h->J->GetParents();  // l = parents of J
00130           if (l == NULL)
00131             {  // must have at least one parent (T)
00132               dprintf((OUTF, "DetectHammock: inconsistency error 1.\n"));
00133               return h;  // not a delta
00134             } // end if
00135           temp = l->GetRegionPtr();
00136           if (temp == S)
00137             foundS = 1;
00138           else if (temp == h->T)
00139             foundT = 1;
00140           else break;  // found parent not S or T => not a delta
00141           
00142           l = l->GetNextListPtr();
00143           if (l == NULL)
00144             return h;  // has only one parent => not a delta OR DIAMOND
00145           if (l->GetNextListPtr() != NULL)
00146             return h;  // J has > 2 parents => not a delta OR DIAMOND
00147 
00148           temp = l->GetRegionPtr();
00149           if (temp == S)
00150             foundS = 1;
00151           else if (temp == h->T)
00152             foundT = 1;
00153           else  // found parent not S or T => not a delta
00154             break;
00155 
00156           if (!foundS || !foundT)  // should have found S and T both
00157             break;
00158 
00159           h->S = S;
00160           h->E = NULL;  // flag as delta
00161           return h;  // IT'S A DELTA!
00162         } // end while
00163     } // end if
00164 
00165   // 4. Now look for a diamond. We know that T goes straight from S to
00166   //    J. Check that E does as well. Then make sure that J's only parents
00167   //    are T and E. If this is all true, it's a diamond.
00168   if (notdiamond) return h;  // determined when finding T in step 2
00169   if (!(isStraight (h->E))) return h;
00170   l = h->E->GetParents();  // l = parents of E
00171   if (l == NULL || l->GetRegionPtr() != S)
00172     {
00173       dprintf ((OUTF, "DetectHammock: inconsistency error 2.\n"));
00174       return h;
00175     } // end if
00176 
00177   l = h->E->GetChildren();  // l = children of E
00178   if (l == NULL)
00179     {
00180       dprintf ((OUTF, "DetectHammock: inconsistency error 2.\n"));
00181       return h;
00182     }
00183   if (l->GetRegionPtr() != h->J)  // E's child is not J => not a diamond
00184     return h;
00185 
00186   foundT = foundE = 0;
00187   l = h->J->GetParents();  // l = parents of J
00188   if (l == NULL)
00189     {  // must have at least one parent (T)
00190       dprintf((OUTF, "DetectHammock: inconsistency error 1.\n"));
00191       return h;  // not a delta
00192     } // end if
00193   temp = l->GetRegionPtr();
00194   if (temp == h->T)
00195     foundT = 1;
00196   else if (temp == h->E)
00197     foundE = 1;
00198   else return h;  // found parent not S or T => not a diamond
00199           
00200   l = l->GetNextListPtr();  // from delta
00201   if (l == NULL)
00202     return h;  // has only one parent => not a diamond
00203   if (l->GetNextListPtr() != NULL)
00204     return h;  // J has > 2 parents => not a diamond
00205 
00206   temp = l->GetRegionPtr();
00207   if (temp == h->T)
00208     foundT = 1;
00209   else if (temp == h->E)
00210     foundE = 1;
00211   else  // found parent not T or E => not a diamond
00212     return h;
00213 
00214   if (!foundT || !foundE)  // should have found T and E both
00215     return h;
00216 
00217   h->S = S;
00218   return h;  // IT'S A DIAMOND!
00219 } // end DetectHammock
00220 
00221 //===========================================================================
00222 
00223 /*
00224  * RevertCodePosSuperblock
00225  *   sb = pointer to superblock
00226  *   proc = pointer to proc containing sb
00227  *
00228  * Lcode requires proper code positioning, while LEGO-style Rebel
00229  * doesn't. Some blocks in Lcode which could be ordinary blocks end
00230  * up becoming superblocks to ensure code positioning. In other
00231  * words, a block with a single decision at the bottom (BRCT, BRCF)
00232  * may be turned into a superblock if neither target block can be
00233  * placed immediately after the decision block as a fall-through;
00234  * as a superblock, the single decision branch is followed by an
00235  * explicit branch (BRU) to the alternate target.
00236  *
00237  * This function turns such a block back into a single-branch block.
00238  * It will still be a sb/hb region, but in all other respects will
00239  * be a basic block again.
00240  */
00241 void
00242 RevertCodePosSuperblock (legoRegion *sb, legoProc *proc)
00243 {
00244   int qualifies = 1;
00245   opList *exits;
00246   legoOp *exit1, *exit2, *opscan, *fallthru, *opscanprev;
00247   attrList *atl1, *atl2;
00248   attrs *a1, *a2;
00249   legoOprd *attroprd;
00250   opEdges *edge;
00251   opList *opl;
00252 
00253   // Check whether the block qualifies.
00254   // 1. Must be sb or hb.
00255   if (sb->GetRegionType() != RT_HB &&
00256       sb->GetRegionType() != RT_SB) qualifies = 0;
00257 
00258   // 2. Must have exactly two exit ops.
00259   if (qualifies)
00260     {
00261 
00262       exits = sb->GetExitOpsPtr();
00263       if (exits == NULL || exits->GetNextListPtr() == NULL ||
00264           exits->GetNextListPtr()->GetNextListPtr() != NULL)
00265         qualifies = 0;
00266     } // end if
00267 
00268   // 3. First exit must be BRCT or BRCF and second (bottom) must be BRU.
00269   if (qualifies)
00270     {
00271       exit1 = exits->GetOpPtr();
00272       exit2 = exits->GetNextListPtr()->GetOpPtr();
00273       if (exit1->GetNextLink() == NULL)  // conditional must be first
00274         {
00275           legoOp *swap;
00276 
00277           swap = exit1; exit1 = exit2; exit2 = swap;
00278         } // end if
00279 
00280       if (!(exit1->IsBRCONDOp()) || !(exit2->IsBRUOp()))
00281         qualifies = 0;
00282     } // end if
00283 
00284   // 4. After exit1 must come a C_MERGE, then a PBRR/PBRA, then exit2.
00285   if (qualifies)
00286     {
00287       opscan = exit1->GetNextLink();
00288       if (opscan == NULL ||
00289           !(opscan->IsCMERGEOp()))
00290         qualifies = 0;
00291     } // end if
00292   if (qualifies)
00293     {
00294       opscan = opscan->GetNextLink();
00295       if (opscan == NULL || !(opscan->IsPBROp() != PBRR))
00296         qualifies = 0;
00297     } // end if
00298   if (qualifies && opscan->GetNextLink() != exit2)
00299     qualifies = 0;
00300 
00301   if (!qualifies)
00302     {
00303       LegoNonFatal ("RevertCodePosSuperblock",
00304                     "Block %d doesn't qualify for reversion.",
00305                     sb->GetRegionId());
00306       return;
00307     } // end if
00308 
00309   // First, blow away the C_MERGE and PBRR/PBRA ops and their attributes.
00310   RemoveMidOp (exit1->GetNextLink(), 1);  // C_MERGE
00311   RemoveMidOp (exit1->GetNextLink(), 1);  // PBRR/PBRA
00312 
00313   // Now, merge exit1 and exit2 together. This will be done clumsily
00314   // when it comes to lc attributes: exit1 will take on all of exit2's that
00315   // don't conflict.
00316   RemoveLiveAttribute (exit2, proc);
00317 
00318   // Merge lc attributes.
00319   atl2 = exit2->GetOpAttrListPtr();
00320   while (atl2 != NULL)  // don't bother if no attributes to merge
00321     {
00322       // Move attributes over one by one.
00323       switch (atl2->GetAttrType())
00324         {
00325         case ATTR_LC:
00326           // Loop through the lc attributes, copying needed ones.
00327           a2 = atl2->GetAttrPtr();
00328           if (a2 != NULL)
00329             {
00330               a1 = FindLcAttribute (a2->GetAttrString(), exit1);
00331               if (a1 == NULL)  // if not there, move over
00332                 AddLcAttribute (a2->GetAttrString(), a2->GetAttrOprdPtr(),
00333                                 exit1, proc);
00334               a2->SetAttrOprdPtr (NULL);  // preserve operands in new one
00335               RemoveLcAttribute (a2->GetAttrString(), exit2, proc);
00336             } // end if
00337 
00338           atl2 = exit2->GetOpAttrListPtr();  // start from beginning again
00339           break;
00340         default:
00341           atl2 = atl2->GetNextListPtr();  // skip to next attrList
00342           break;
00343         } // end switch
00344 
00345     } // end while
00346 
00347   // Redirect edge from exit2 to exit1.
00348   fallthru = exit2->GetOutListPtr()->GetOpPtr();
00349   if (fallthru == NULL)
00350     LegoFatal ("RevertCodePosSuperblock", "Can't find op following op %d.",
00351                exit2->GetOpId());
00352   edge = FindControlEdge (exit2, fallthru);
00353   if (edge == NULL)
00354     LegoFatal ("RevertCodePosSuperblock", "Can't find edge from "
00355                "op %d to op %d.", exit2->GetOpId(), fallthru->GetOpId());
00356   edge->SetFromOpPtr (exit1);
00357   edge->SetFromOpId (exit1->GetOpId());
00358 
00359   // Add fallthru to exit1's outlist.
00360   opl = exit2->GetOutListPtr();
00361   opl->SetNextListPtr (exit1->GetOutListPtr());
00362   exit1->SetOutListPtr (opl);
00363   exit2->SetOutListPtr (NULL);  // moved off exit2
00364 
00365   // Change fallthru's inlist to refer to exit1.
00366   opl = fallthru->GetInListPtr();
00367   opl->SetOpPtr (exit1);
00368   opl->SetOpId (exit1->GetOpId());
00369 
00370   // Remove edge between exit1 and exit2.
00371   edge = FindControlEdge (exit1, exit2);
00372   if (edge == NULL)
00373     LegoFatal ("RevertCodePosSuperblock", "Can't find edge from "
00374                "op %d to op %d.", exit1->GetOpId(), exit2->GetOpId());
00375   RemoveEdge (exit1, exit2, ET_CNTL);
00376 
00377   // Remove exit2 now!
00378   exit1->SetNextLink (NULL);
00379   for (opscanprev = NULL, opscan = proc->GetListOpPtr();
00380        opscan != exit2; opscanprev = opscan, opscan = opscan->GetListOpPtr()) ;
00381   if (opscanprev != NULL)
00382     opscanprev->SetListOpPtr (opscan->GetListOpPtr());
00383   else
00384     proc->SetListOpPtr (opscan->GetListOpPtr());
00385   delete exit2;
00386 
00387   // Cleanup.
00388   while (sb->GetRegionType() != RT_PROC)
00389     {
00390       sb->RefreshOps();
00391       sb = sb->GetParentPtr();
00392     } // end while
00393 
00394   return;
00395 } // end RevertCodePosSuperblock
00396 
00397 
00398 /*
00399  * NextPredRegNum
00400  *
00401  * Indicates the next available predicate register number. Initialize
00402  * this to zero before running through a proc.
00403  */
00404 int NextPredRegNum = 0;
00405 
00406 /*
00407  * MakeDupPred
00408  *   orig = pointer to original predicate
00409  *   returns: new duplicate of predicate
00410  *
00411  * Makes a new predicate operand the same as orig while avoiding using
00412  * the copy constructor.
00413  */
00414 static legoOprd *
00415 MakeDupPred (legoOprd *orig)
00416 {
00417   legoOprd *newp;
00418 
00419   // Want to avoid copy constructor (chaining along nextOperandPtr).
00420   newp = new legoOprd;
00421   newp->SetOprdType (orig->GetOprdType());
00422   newp->SetOprdRegType (orig->GetOprdRegType());
00423   newp->SetOprdRegNum (orig->GetOprdRegNum());
00424   newp->SetOprdDataType (orig->GetOprdDataType());
00425   newp->SetOprdFileType (orig->GetOprdFileType());
00426   newp->SetOprdOmega (orig->GetOprdOmega());
00427   newp->SetOprdRegStyle (orig->GetOprdRegStyle());
00428   newp->SetIntValue (orig->GetOprdIntValue());
00429 
00430   return newp;
00431 } // end MakeDupPred
00432 
00433 /*
00434  * AddWeightAttribute
00435  *   op = op to annotate
00436  *   returns: new attr attached to op
00437  *
00438  * Attaches a new attr to the op saying what the weight of its block
00439  * is.
00440  */
00441 static attrs *
00442 AddWeightAttribute (legoOp *op)
00443 {
00444   legoRegion *block;
00445   legoOprd *oprd;
00446   attrs *wtattr;
00447 
00448   block = (legoRegion *) op->GetParentBlockPtr();
00449   if (block == NULL) return NULL;
00450 
00451   oprd = new legoOprd;
00452   oprd->SetOprdType (OT_LITERAL_D);
00453   oprd->SetLiteralDouble (block->GetWeight());
00454 
00455   // Only update orig_wt for an op one time, as HBs may be in merged into 
00456   // other HBs. In this case we are only interested in the orig BB weight.
00457   if (FindLcAttribute( "orig_wt", op ) == NULL) {
00458     wtattr = AddLcAttribute ("orig_wt", oprd, op,
00459                              (legoProc *) FindParentRegionType (RT_PROC, op));
00460     return wtattr;
00461   }
00462   else {
00463     return NULL;
00464   }
00465   
00466   //  attrList *atl;
00467   //  intList *il;
00468 
00469 
00470   //  op->SetBlockId ((int) weight);
00471   //  return NULL;
00472 
00473   // for (atl = op->GetOpAttrListPtr();
00474   //       atl != NULL && atl->GetNextListPtr() != NULL &&
00475   //     atl->GetAttrType() != ATTR_FREQ;
00476   //       atl = atl->GetNextListPtr()) /* do nothing */;
00477   //  if (atl == NULL)
00478   //    {
00479   //      atl = new attrList;
00480   //      op->SetOpAttrListPtr (atl);
00481   //    } // end if
00482   //  else if (atl->GetAttrType() != ATTR_FREQ)
00483   //    {
00484   //      atl->SetNextListPtr (new attrList);
00485   //      atl = atl->GetNextListPtr();
00486   //    } // end else
00487   //  atl->SetAttrType (ATTR_FREQ);
00488   //  atl->SetValid(1);
00489   //  if (atl->GetAttrValPtr() == NULL)
00490   //    atl->SetAttrValPtr (new intList);
00491   //  il = atl->GetAttrValPtr();
00492   //  il->SetValid(1);
00493   //  il->SetAttrValue ((int) weight);
00494   //  return atl;
00495 }
00496 
00497 /*
00498  * AddOrthoPredAttribute
00499  *   op = op to annotate
00500  *   returns: new attr attached to op
00501  *
00502  * Attaches a new attr to the op with the predicate reg number of the 
00503  * orthogonal operations. For if-converted if-then-else statements, 
00504  * orthogonal predicates will be assigned to the then and else subblocks.
00505  * The dag builder will use this information so that deps are not included
00506  * between these orthogonal operations
00507  * 
00508  */
00509 static attrs *
00510 AddOrthoPredAttribute (legoOp *op, int PredRegNumb)
00511 {
00512   legoRegion *block;
00513   legoOprd *oprd;
00514   attrs *wtattr;
00515 
00516   block = (legoRegion *) op->GetParentBlockPtr();
00517   if (block == NULL) return NULL;
00518 
00519   oprd = new legoOprd;
00520   oprd->SetOprdType (OT_LITERAL_I);
00521   oprd->SetLiteralInteger (PredRegNumb);
00522 
00523   wtattr = AddLcAttribute ("orthogonal_pred_reg_numb", oprd, op,
00524                            (legoProc *) FindParentRegionType (RT_PROC, op));
00525   return wtattr;
00526 
00527 }
00528 
00529 /*
00530  * AddZerosRight
00531  *   vector = bitvector to manipulate
00532  *   num_valid_bits = number of currently valid bits in bit vector, we can 
00533  *                    assume they are right justified (in low-order bits)
00534  *   num_shift_bits = number of zeros to add to the right of currently valid 
00535  *                    bits
00536  *
00537  * Assumes previous checking eliminates overflow possibility
00538  * 
00539  */
00540 void
00541 AddZerosRight (bitvector *vector, int num_valid_bits, int num_shift_bits)
00542 {
00543   
00544   dderr ("\nAdding " << num_shift_bits << " zeros to the right of a vector with " << num_valid_bits << " valid bits\n");
00545 #ifdef _SHOW_VECTORS
00546   vector->Show();
00547 #endif // _SHOW_VECTORS
00548   if (num_shift_bits > 0) {
00549     for (int i = 0; i < num_valid_bits; i++) {
00550       if (vector->Read((num_valid_bits - 1) - i)) {
00551         vector->Set(((num_valid_bits - 1) - i) + num_shift_bits);
00552         vector->Reset((num_valid_bits - 1) - i);
00553       }
00554     }
00555   }
00556 #ifdef _SHOW_VECTORS
00557   vector->Show();
00558 #endif // _SHOW_VECTORS
00559 }
00560 
00561 /*
00562  * ReplicateBits
00563  *   vector = bitvector to manipulate
00564  *   num_valid_bits = number of currently valid bits in bit vector, we can 
00565  *                    assume they are right justified (in low-order bits)
00566  *   num_copies = Final vector should contain this many copies of the original 
00567  *
00568  * Assumes previous checking eliminates overflow possibility
00569  * 
00570  */
00571 void
00572 ReplicateBits (bitvector *vector, int num_valid_bits, int num_copies)
00573 {
00574 
00575   dderr ("\nReplicating for " << num_copies << " copies of original vector with " << num_valid_bits << " valid bits\n");
00576 #ifdef _SHOW_VECTORS
00577   vector->Show();
00578 #endif // _SHOW_VECTORS
00579   for (int i = 1; i < num_copies; i++) {
00580     for (int j = 0; j < num_valid_bits; j++) {
00581       if (vector->Read((num_valid_bits - 1) - j)) {
00582         vector->Set(((num_valid_bits - 1) - j) + (i * num_valid_bits));
00583       }
00584     }
00585   }
00586 #ifdef _SHOW_VECTORS
00587   vector->Show();
00588 #endif // _SHOW_VECTORS
00589 }
00590 
00591 /*
00592  * ReplicateBitsMask
00593  *   vector = bitvector to manipulate
00594  *   num_valid_bits = number of currently valid bits in bit vector, we can 
00595  *                    assume they are right justified (in low-order bits)
00596  *   num_copies = Final vector should contain this many copies of the original 
00597  *
00598  * Assumes previous checking eliminates overflow possibility
00599  * 
00600  */
00601 bitvector *
00602 ReplicateBitsMask (bitvector *vector, bitvector *mask,
00603                     int num_valid_bits, int pattern_size, int PredVectorSize)
00604 {
00605 
00606   dderr ("\nReplicating with Mask for a copy of input vector at each valid bit in mask. Mask with " << num_valid_bits << " valid bits\n");
00607 #ifdef _SHOW_VECTORS
00608   cerr << "Mask Vector :\n";
00609   mask->Show();
00610   cerr << "Input Vector :\n";
00611   vector->Show();
00612 #endif // _SHOW_VECTORS
00613   
00614   bitvector *new_vector = new bitvector(PredVectorSize);
00615   
00616   int new_i = 0;
00617   for (int i = 0; i < num_valid_bits; i++) {
00618     if (mask->Read(i)) {
00619       for (int j = 0; j < pattern_size; j++) {
00620         if (vector->Read(j)) {
00621           new_vector->Set(new_i);
00622         }
00623         new_i++; 
00624       }
00625     }  
00626     else {
00627       new_i++;
00628     }
00629   }
00630   
00631   delete vector; 
00632 
00633 #ifdef _SHOW_VECTORS
00634   new_vector->Show();
00635 #endif // _SHOW_VECTORS
00636 
00637   return new_vector; 
00638 }
00639 
00640 /*
00641  * MultiplyBits
00642  *   vector = bitvector to manipulate
00643  *   num_valid_bits = number of currently valid bits in bit vector, we can 
00644  *                    assume they are right justified (in low-order bits)
00645  *   num_mults = Final vector should contain this many copies of the original 
00646  *
00647  * Assumes previous checking eliminates overflow possibility
00648  * 
00649  */
00650 void
00651 MultiplyBits (bitvector *vector, int num_valid_bits, int num_mults)
00652 {
00653 
00654   dderr ("\nMultiplying for " << num_mults << " mults of each bit in the original vector with originally " << num_valid_bits << " valid bits\n");
00655 #ifdef _SHOW_VECTORS
00656   vector->Show();
00657 #endif // _SHOW_VECTORS
00658   for (int i = num_valid_bits; i >= 1; i--) {
00659     if (vector->Read(i - 1)) {
00660       for (int j = num_mults; j >= 1; j--) {
00661         vector->Set(((i * num_mults) - j));
00662       }
00663       // Leave the very last bit alone
00664       if (i != 1) {
00665         vector->Reset(i - 1);
00666       }
00667     }  
00668   }
00669 #ifdef _SHOW_VECTORS
00670   vector->Show();
00671 #endif // _SHOW_VECTORS
00672 }
00673 
00674 /*
00675  * MultiplyBitsMask
00676  *   vector = bitvector to manipulate
00677  *   num_valid_bits = number of currently valid bits in bit vector, we can 
00678  *                    assume they are right justified (in low-order bits)
00679  *   num_mults = Final vector should contain this many copies of the original 
00680  *
00681  * Assumes previous checking eliminates overflow possibility
00682  * 
00683  */
00684 bitvector *
00685 MultiplyBitsMask (bitvector *vector, bitvector *mask, 
00686                    int num_valid_bits, int num_mults, int PredVectorSize)
00687 {
00688   
00689   dderr ("\nMultiplying with Mask for " << num_mults << " mults of each bit if valid in mask. Vector with originally " << num_valid_bits << " valid bits\n");
00690 #ifdef _SHOW_VECTORS
00691   cerr << "Mask Vector :\n";
00692   mask->Show();
00693   cerr << "Input Vector :\n";
00694   vector->Show();
00695 #endif // _SHOW_VECTORS
00696   
00697   bitvector *new_vector = new bitvector(PredVectorSize);
00698   
00699   int new_i = 0;
00700   for (int i = 0; i < num_valid_bits; i++) {
00701     if (mask->Read(i)) {
00702       if (vector->Read(i)) {      
00703         for (int j = 0; j < num_mults; j++) {
00704           new_vector->Set(new_i);
00705           new_i++;
00706         }
00707       }
00708       else {
00709         new_i = new_i + num_mults; 
00710       }
00711     }
00712     else {
00713       if (vector->Read(i)) {      
00714         new_vector->Set(new_i);
00715       }      
00716       new_i++;
00717     }
00718   }
00719 
00720   delete vector; 
00721   
00722 #ifdef _SHOW_VECTORS
00723   new_vector->Show();
00724 #endif // _SHOW_VECTORS
00725 
00726   return new_vector; 
00727 }
00728 
00729 /*
00730  * IfConvertHammock
00731  *   h = pointer to hammock information
00732  *   returns: pointer to if-converted code (hyperblock), NULL if error
00733  *
00734  * Performs if-conversion (predication) on a hammock control structure.
00735  * Predicates ops in the T and E blocks appropriately, then creates a
00736  * hyperblock to hold the ops of S, T, E, and J, in order. This new
00737  * hyperblock is returned.
00738  *
00739  * This is actually rather complicated...>:P
00740  */
00741 legoRegion *IfConvertHammock (hammock_info *h, knobs *K)
00742 {
00743   legoRegion *hyp;
00744   legoProc *proc;
00745   legoOprd *p1, *p2, *curp, *pT = NULL, *pE = NULL, *oprd;
00746 
00747   opList *opl;
00748   legoOp *lastop, *pbrrop, *op;
00749   int fromopid, toopid;
00750 
00751   int makingnewHB, isBRCT, PBRRblock;
00752 
00753   bitvector *new_SorJ_vector, *new_T_vector, *new_E_vector; 
00754   int S_size, T_size, E_size; 
00755   int PredVectorSize, required_vector_size; 
00756   attrs *a; 
00757   attrList *atl;
00758   enum attrTypes atype;
00759 
00760   dprintf((OUTF, "IfConvertHammock: --- converting starting at %d ---\n",
00761            h->S->GetRegionId()));
00762   if (!(h->HammockDetected()))
00763     return NULL;
00764   if (h->T == NULL || h->J == NULL)
00765     return NULL;
00766 
00767   for (hyp = h->S; hyp->GetRegionType() != RT_PROC;
00768        hyp = hyp->GetParentPtr())  // just using hyp as generic pointer
00769     if (hyp == NULL)
00770       {
00771         dprintf((OUTF,"IfConvertHammock: can't find proc!\n"));
00772         return NULL;
00773       } // end if (for)
00774   proc = (legoProc *) hyp;
00775 
00776   if (h->S->GetRegionType() != RT_HB)
00777     {
00778       hyp = new legoHB (h->S->GetRegionId());  // make new hyperblock
00779       hyp->SetWeight (h->S->GetWeight());
00780       oprd = new legoOprd;
00781       oprd->SetOprdType (OT_LITERAL_I);
00782       oprd->SetLiteralInteger(0);
00783       AddLcAttribute ("use_orig_wt", oprd, hyp, proc); 
00784       makingnewHB = 1;
00785     } // end if
00786   else
00787     {
00788       hyp = h->S;  // use existing hyperblock
00789       makingnewHB = 0;
00790     } // end else
00791 
00792   // Read in knobs.
00793   K->SetDefaultPanel ("rform/tree");
00794   K->Read ("num-bits-pred-vector", PredVectorSize);
00795 
00796   // Determine if PredVector length requirements can be satisfied
00797   // by PredVectorSize
00798   if ( (a = FindLcAttribute( "pred_vector_size", h->S )) != NULL ) 
00799     S_size = a->GetAttrOprdPtr()->GetLiteralInteger();
00800   else 
00801     S_size = 1; 
00802   if ( (a = FindLcAttribute( "pred_vector_size", h->T )) != NULL ) 
00803     T_size = a->GetAttrOprdPtr()->GetLiteralInteger();
00804   else 
00805     T_size = 1; 
00806   if (!(h->IsDelta())) 
00807     if ( (a = FindLcAttribute( "pred_vector_size", h->E )) != NULL ) 
00808       E_size = a->GetAttrOprdPtr()->GetLiteralInteger();
00809     else 
00810       E_size = 1; 
00811   else 
00812     E_size = 1; 
00813   required_vector_size = ((T_size + E_size) * S_size);
00814   if (required_vector_size > PredVectorSize) {
00815     LegoNonFatal ("IfConvertHammock", "Need more PredVectorSize to continue if-conversion !!!\n.");
00816     return NULL;
00817   }
00818   // Update hyp's pred_vector_size attr
00819   oprd = new legoOprd;
00820   oprd->SetOprdType (OT_LITERAL_I);
00821   oprd->SetLiteralInteger(required_vector_size);
00822   AddLcAttribute ("pred_vector_size", oprd, hyp, proc); 
00823   // Create Prototype for Join PredVector
00824   new_SorJ_vector = new bitvector(PredVectorSize);   
00825   new_T_vector = new bitvector(PredVectorSize);   
00826   new_E_vector = new bitvector(PredVectorSize);   
00827   for (int i = 0; i < required_vector_size; i++) {
00828     new_SorJ_vector->Set(i);
00829   }
00830   // The following vectors are only used for BB used for the first time in 
00831   // a HB (they will only replace a NULL PredVector)
00832   new_T_vector->Set(0);
00833   new_E_vector->Set(T_size);
00834   if (S_size > 1) {
00835 //    MultiplyBits(new_T_vector, (T_size + E_size), S_size);
00836 //    MultiplyBits(new_E_vector, (T_size + E_size), S_size);
00837     ReplicateBits(new_T_vector, (T_size + E_size), S_size);
00838     ReplicateBits(new_E_vector, (T_size + E_size), S_size);
00839   }
00840   dderr ("S_size = " << S_size << "\n");
00841   dderr ("T_size = " << T_size << "\n");
00842   dderr ("E_size = " << E_size << "\n");
00843   dderr ("required_vector_size = " << required_vector_size << "\n");
00844 #ifdef _SHOW_VECTORS
00845   new_SorJ_vector->Show();
00846   new_T_vector->Show();
00847   new_E_vector->Show();
00848 #endif // _SHOW_VECTORS
00849   
00850   while (1)
00851     {
00852       for (opl = h->S->GetExitOpsPtr();  // find last op in block
00853            opl != NULL && opl->GetOpPtr()->GetNextLink() != NULL;
00854            opl = opl->GetNextListPtr()) /* do nothing */;
00855       if (opl == NULL)
00856         {
00857           LegoNonFatal ("IfConvertHammock", "Can't find last op in S "
00858                         "block %d.", h->S->GetRegionId());
00859           return NULL;
00860         }
00861       lastop = opl->GetOpPtr();
00862 
00863       // If lastop is a BRU, it's probably a pseudo-superblock, which
00864       // should be cleaned up now.
00865       if (!(lastop->IsBRUOp())) break;  // normal
00866 
00867       RevertCodePosSuperblock (hyp, proc);  // then get the last op again...
00868     } // end while
00869 
00870   if (lastop->GetSrcOprdPtr() == NULL ||
00871       lastop->GetSrcOprdPtr()->GetNextOprdPtr() == NULL)
00872     {
00873       LegoNonFatal ("IfConvertHammock", "Can't find predicate source of "
00874                     "branch %d.", lastop->GetOpId());  // will need it later
00875       return NULL;
00876     } // end if
00877 
00878   // STEP 1: Analysis and setup.
00879 
00880   // 1a. Determine whether branch is BRCT or BRCF.
00881   //if (lastop->IsBRCTOp())
00882     if(lastop->GetOpcode() == BRCT)
00883   {
00884       LegoNonFatal("IfConvertHammock", "BRCF is not supported yet.");
00885     isBRCT = 1;
00886   }
00887   else
00888   {
00889       LegoNonFatal("IfConvertHammock", "BRCF is not supported yet.");
00890     isBRCT = 0;
00891   }
00892 
00893   // 1b. Find the target of the branch.
00894   for (pbrrop = lastop;
00895        pbrrop != NULL && !(pbrrop->IsPBROp());
00896        pbrrop = pbrrop->GetPrevLink()) /* do nothing */;
00897   if (pbrrop == NULL)
00898     {
00899       LegoNonFatal ("IfConvertHammock", "Can't find PBRR/PBRA in block %d.",
00900                     h->S->GetRegionId());
00901       return NULL;
00902     } // end if
00903   oprd = pbrrop->GetSrcOprdPtr();
00904   if (oprd->GetOprdType() != OT_LITERAL_CB)
00905     {
00906       LegoNonFatal ("IfConvertHammock", "PBRR %d not to control block.",
00907                     pbrrop->GetOpId());
00908       return NULL;
00909     } // end if
00910   PBRRblock = oprd->GetLiteralControlBlock();
00911   if (PBRRblock != h->T->GetRegionId() &&
00912       PBRRblock != h->J->GetRegionId() &&
00913       !(!(h->IsDelta()) && PBRRblock == h->E->GetRegionId()))
00914     {
00915       LegoNonFatal ("IfConvertHammock", "Can't find block %d in hammock.",
00916                     PBRRblock);
00917       return NULL;
00918     } // end if
00919 
00920   // 1c. Find the predicate operands that are the destination of the last
00921   //     CMPP in S. Put the first in p1, the second in p2. If the second
00922   //     isn't there, take care of it.
00923   for (op = lastop;  // scan back to last CMPP
00924        op != NULL && op->IsCMPPOp();
00925        op = op->GetPrevLink()) /* do nothing */;
00926 
00927   if (op == NULL)
00928     {
00929       LegoNonFatal ("IfConvertHammock", "Can't find CMPP for branch %d.",
00930                     lastop->GetOpId());
00931       return NULL;
00932     } // end if
00933 
00934   // mdj - 4/1/99 (No April Fool's joke, this change is really needed)
00935   // Not guaranteed to work everytime but should for the Rebel files 
00936   // that I have inspected. Seems that the second dest D-action of a CMPP is 
00937   // 'always' the same as the first for our source from IMPACT/ELCOR. We need 
00938   // the second dest to be the complement of the first (increment opcode)
00939   // make sure that the second D-action is a complement (odd-number opcode)
00940   //op->SetOpcode((op->GetOpcode() + 1));
00941   div_t remainder = div(op->GetOpcode(), 2);
00942   if (remainder.rem == 0) {
00943     op->SetOpcode((op->GetOpcode() + 1));
00944   }
00945     
00946   p1 = op->GetDestOprdPtr();  // first destination!
00947   if (p1 == NULL || p1->GetNextOprdPtr() == NULL)
00948     {
00949       LegoNonFatal ("IfConvertHammock", "CMPP %d has bad destinations.",
00950                     op->GetOpId());
00951       return NULL;
00952     } // end if
00953   p2 = p1->GetNextOprdPtr();  // p2 is there always!
00954   if (p1->GetNextOprdPtr()->GetOprdType() != OT_UNDEFINED)
00955     /* do nothing - we have two predicates! */;
00956   // Nuts, there's no second destination. Before making one, it isn't
00957   // really required if this is a delta.
00958   else if (h->IsDelta())
00959     {
00960       // OK, there are four cases to consider:
00961       //       | branch to T      | branch to J
00962       //       |                  |
00963       //  BRCT | pT = p1          | make p2; pT = p2
00964       //  -----|------------------|-----------------
00965       //  BRCF | make p2; pT = p2 | pT = p1
00966       //
00967       // Well, I'll be damned, I find myself wishing for a logical
00968       // XNOR operator...
00969       if ((PBRRblock == h->T->GetRegionId() && isBRCT) ||
00970           (PBRRblock != h->T->GetRegionId() && !isBRCT))
00971         pT = p1;
00972       else
00973         {
00974           // Don't bother fixing PBRR or BRCT, since they're going
00975           // away anyway. We do need to add p2, since T must be
00976           // predicated on the complement of the CMPP.
00977           p2->SetOprdType (p1->GetOprdType());
00978           p2->SetOprdRegType (p1->GetOprdRegType());
00979           p2->SetOprdRegNum (p1->GetOprdRegNum());
00980           p2->SetOprdDataType (p1->GetOprdDataType());
00981           p2->SetOprdFileType (p1->GetOprdFileType());
00982           p2->SetOprdOmega (p1->GetOprdOmega());
00983           p2->SetOprdRegStyle (p1->GetOprdRegStyle());
00984           p2->SetIntValue (p1->GetOprdIntValue());
00985           p1->SetOprdRegNum (0);  // throw away other result
00986           pT = p2;
00987         } // end else
00988     } // end else if
00989   else
00990     {
00991       // We need a second destination (for the diamond). Scan through
00992       // every op in the proc to find the next predicate register that's
00993       // free.
00994       if (NextPredRegNum == 0)  // find it
00995         {
00996           legoOp *o;
00997           legoOprd *d;
00998           for (o = proc->GetListOpPtr(); o != NULL; o = o->GetListOpPtr())
00999             {
01000               for (d = o->GetSrcOprdPtr(); d != NULL; d = d->GetNextOprdPtr())
01001                 if (d->GetOprdType() == OT_REG &&
01002                     //              (d->GetOprdDataType() == DT_P ||
01003                     //               d->GetOprdFileType() == FT_PR) &&
01004                     d->GetOprdRegNum() > NextPredRegNum)
01005                   NextPredRegNum = d->GetOprdRegNum();
01006 
01007               for (d = o->GetDestOprdPtr(); d != NULL; d = d->GetNextOprdPtr())
01008                 if (d->GetOprdType() == OT_REG &&
01009                     //              (d->GetOprdDataType() == DT_P ||
01010                     //               d->GetOprdFileType() == FT_PR) &&
01011                     d->GetOprdRegNum() > NextPredRegNum)
01012                   NextPredRegNum = d->GetOprdRegNum();
01013 
01014               for (d = o->GetPredOprdPtr(); d != NULL; d = d->GetNextOprdPtr())
01015                 if (d->GetOprdType() == OT_REG &&
01016                     //              (d->GetOprdDataType() == DT_P ||
01017                     //               d->GetOprdFileType() == FT_PR) &&
01018                     d->GetOprdRegNum() > NextPredRegNum)
01019                   NextPredRegNum = d->GetOprdRegNum();
01020             } // end for
01021 
01022           NextPredRegNum++;  // next available one
01023           dprintf((OUTF, "IfConvertHammock: NextPredRegNum = %d\n",
01024                    NextPredRegNum));
01025         } // end if
01026 
01027       // Make the new operand and plop it into the CMPP.
01028       p2->SetOprdType (p1->GetOprdType());
01029       p2->SetOprdRegNum (NextPredRegNum++);
01030       p2->SetOprdRegType (p1->GetOprdRegType());
01031       p2->SetOprdDataType (p1->GetOprdDataType());
01032       p2->SetOprdFileType (p1->GetOprdFileType());
01033       p2->SetOprdOmega (p1->GetOprdOmega());
01034       p2->SetOprdRegStyle (p1->GetOprdRegStyle());
01035       p2->SetIntValue (p1->GetOprdIntValue());
01036     } // end else
01037 
01038   // 1d. Figure out pT and pE, the predicates for T and E, if it's a diamond.
01039   //          | branch to T       | branch to E
01040   //          |                   |
01041   //  BRCT pX | pT = pX, pE = !pX | pT = !pX, pE = pX
01042   //          |                   |
01043   //  BRCF pX | pT = !pX, pE = pX | pT = pX, pE = !pX
01044   if (!(h->IsDelta()))
01045     {
01046       legoOprd *pX;
01047 
01048       pX = lastop->GetSrcOprdPtr()->GetNextOprdPtr();
01049       if (pX->GetOprdRegNum() == p1->GetOprdRegNum())
01050         pX = p1;  // point pX to p1
01051       else
01052         pX = p2;  // point pX to p2
01053 
01054       if ((PBRRblock == h->T->GetRegionId() && isBRCT) ||
01055           (PBRRblock == h->E->GetRegionId() && !isBRCT))
01056         {
01057           pT = pX;
01058           pE = (pT == p1 ? p2 : p1);
01059         } // end if
01060       else
01061         {
01062           pE = pX;
01063           pT = (pE == p1 ? p2 : p1);
01064         } // end else
01065     } // end if
01066 
01067   // STEP 2: If-Conversion
01068 
01069   legoOprd *Tpredicate;
01070   legoOprd *Epredicate;
01071   legoOp *prevop;
01072 
01073   regionList *rl;
01074   legoRegion *region;
01075   unsigned i, count;
01076 
01077   // 2a. Make new prototype predicate legoOprds based on pT (and pE,
01078   //     if needed.
01079   Tpredicate = MakeDupPred (pT);
01080   if (pE != NULL)
01081     Epredicate = MakeDupPred (pE);
01082   else
01083     Epredicate = NULL;
01084 
01085   // 2b. Invalidate children lists of parents of S, and parents lists
01086   //     of children of J. Also, if S is the hyperblock, remove its
01087   //     parents and children.
01088   for (rl = h->S->GetParents(); rl != NULL; rl = rl->GetNextListPtr())
01089     {
01090       region = rl->GetRegionPtr();
01091       if (region != NULL)
01092         {
01093           delete (region->GetChildren());
01094           region->SetChildren (NULL);
01095         } // end if
01096     } // end for
01097   for (rl = h->J->GetChildren(); rl != NULL; rl = rl->GetNextListPtr())
01098     {
01099       region = rl->GetRegionPtr();
01100       if (region != NULL)
01101         {
01102           delete (region->GetParents());
01103           region->SetParents (NULL);
01104         } // end if
01105     } // end for
01106   if (!makingnewHB)
01107     {
01108       delete (h->S->GetParents());
01109       h->S->SetParents (NULL);
01110       delete (h->S->GetChildren());
01111       h->S->SetChildren (NULL);
01112     } // end if
01113   
01114   // 2c. Move ops from S to hyp. Remove the PBRR op. At the end,
01115   //     destroy the edge not leading to T.
01116   count = h->S->GetCount();
01117   for (i = 0; i < count; i++)
01118     {
01119       if (makingnewHB)
01120         op = (legoOp *) h->S->GetItem(0);
01121       else
01122         op = (legoOp *) h->S->GetItem(i);
01123       AddWeightAttribute (op);
01124       // Set PredVector and orig_hammock_hb_id attribute
01125       if (op->GetPredVectorPtr() == NULL) { 
01126         op->SetPredVectorPtr(new bitvector(*new_SorJ_vector));
01127       }
01128       else {
01129         MultiplyBits(op->GetPredVectorPtr(), S_size, (T_size + E_size));
01130       }
01131       dderr ("OpId = " << op->GetOpId() << " (a S op)\n");
01132 //      oprd = new legoOprd;
01133 //      oprd->SetOprdType (OT_LITERAL_I);
01134 //      oprd->SetLiteralInteger(hyp->GetRegionId());
01135 //      cerr << "OpId = " << op->GetOpId() << ", orig_hammock_hb_id = " << hyp->GetRegionId() << " (a S op)\n";
01136 //      AddLcAttribute ("orig_hammock_hb_id", oprd, op, proc);
01137       if ((op->IsPBROp()) &&
01138           op->GetSrcOprdPtr()->GetOprdType() == OT_LITERAL_CB)
01139         {
01140           dprintf((OUTF,"IfConvertHammock: removing PBRR %d from S.\n",
01141                    op->GetOpId()));
01142           if (makingnewHB)
01143             h->S->Detach (0);
01144           else
01145             {
01146               h->S->Detach (i--);  // backtrack i by one
01147               count--;  // count is one less now too
01148             } // end else
01149           RemoveMidOp (op);
01150         } // end if
01151       else if (makingnewHB)
01152         {
01153           dprintf((OUTF,"IfConvertHammock: moving op %d from S.\n",
01154                    op->GetOpId()));
01155           h->S->Detach (0);
01156           hyp->AddItem(op);
01157           op->SetParentBlockPtr (hyp);
01158         } // end if
01159     } // end for
01160   prevop = op;
01161 
01162   fromopid = op->GetOpId();
01163   if (h->IsDelta())
01164     toopid = h->J->GetEntryOpsPtr()->GetOpPtr()->GetOpId();  // S->J
01165   else
01166     toopid = h->E->GetEntryOpsPtr()->GetOpPtr()->GetOpId();  // S->E
01167   RemoveEdge (fromopid, toopid, proc, ET_CNTL);
01168 
01169   // 2d. Move ops from T to hyp, predicating them on Tpredicate.
01170   //     Remove the PBRR op.
01171   count = h->T->GetCount();
01172   for (i = 0; i < count; i++)
01173     {
01174       op = (legoOp *) h->T->GetItem(0);
01175       AddWeightAttribute (op);
01176 //      if (Epredicate != NULL)
01177 //      AddOrthoPredAttribute (op, Epredicate->GetOprdRegNum() );
01178       h->T->Detach (0);
01179       if (!(op->IsPBROp()) ||
01180           op->GetSrcOprdPtr()->GetOprdType() != OT_LITERAL_CB)
01181         {
01182           dprintf((OUTF,"IfConvertHammock: moving op %d from T.\n",
01183                    op->GetOpId()));
01184           hyp->AddItem(op);
01185           op->SetParentBlockPtr (hyp);
01186           // Set PredVector and orig_hammock_hb_id attribute
01187           if (op->GetPredVectorPtr() == NULL) { 
01188             op->SetPredVectorPtr(new bitvector(*new_T_vector));
01189           }
01190           else {
01191             // Don't need to add zeros left, already zeros
01192 //          MultiplyBits(op->GetPredVectorPtr(), (T_size + E_size), S_size);
01193             ReplicateBits(op->GetPredVectorPtr(), (T_size + E_size), S_size);
01194           }
01195           dderr ("OpId = " << op->GetOpId() << " (a T op)\n");
01196 //        oprd = new legoOprd;
01197 //        oprd->SetOprdType (OT_LITERAL_I);
01198 //        oprd->SetLiteralInteger(hyp->GetRegionId());
01199 //        cerr << "OpId = " << op->GetOpId() << ", orig_hammock_hb_id = " << hyp->GetRegionId() << " (a T op)\n";
01200 //        AddLcAttribute ("orig_hammock_hb_id", oprd, op, proc);
01201         } // end if
01202       else
01203         {
01204           dprintf((OUTF,"IfConvertHammock: removing PBRR %d from T.\n",
01205                    op->GetOpId()));
01206           RemoveMidOp (op);
01207         } // end else
01208       if (i == 0)
01209         {
01210           prevop->SetNextLink (op);
01211           op->SetPrevLink (prevop);
01212         } // end if
01213 
01214       oprd = op->GetPredOprdPtr();
01215       // mdj - 4/2/99
01216       // Only want to update TRUE predicates here. If the predicate is now 
01217       // non-TRUE, it was updated by a prior hammock conversion. Leaving 
01218       // these predicates alone while updating (predicating) the CMPP ops 
01219       // that create these predicates produces the correct predicate values
01220       int dont_change_pred = 0;
01221       if (oprd != NULL) {
01222         if (oprd->GetOprdType() != OT_LITERAL_P ||
01223             oprd->GetLiteralPredicate() != TRUE ) {
01224           dont_change_pred = 1;
01225         }
01226         else {
01227           delete oprd;
01228         }
01229       }
01230       if (!dont_change_pred) {
01231         oprd = new legoOprd (*Tpredicate);
01232         op->SetPredOprdPtr (oprd);
01233         oprd->SetParentOpPtr (op);
01234       }
01235     } // end for
01236   prevop = op;
01237   
01238   // 2e. If E needs to be done, move ops from E to hyp,
01239   //     predicating them on EPredicate. Remove the PBRR op. Get the edge
01240   //     coming out of T to point to E instead (i.e., get edge from last
01241   //     op in T to be to first op in E instead).
01242   if (Epredicate != NULL)
01243     {
01244       count = h->E->GetCount();
01245       for (i = 0; i < count; i++)
01246         {
01247           op = (legoOp *) h->E->GetItem(0);
01248           AddWeightAttribute (op);
01249 //        AddOrthoPredAttribute (op, Tpredicate->GetOprdRegNum() );
01250           if (i == 0)
01251             {
01252               // Move that edge. It's still referenced by T.
01253               opEdges *fixedge = h->T->GetOutEdgesPtr()->GetEdgePtr();
01254               if (fixedge->GetFromOpPtr() != prevop)
01255                 LegoFatal ("IfConvertHammock", "Out edge of block %d "
01256                            "does not originate from op %d.",
01257                            h->T->GetRegionId(), prevop->GetOpId());
01258               fixedge->SetToOpPtr (op);
01259               fixedge->SetToOpId (op->GetOpId());
01260               //              h->E->GetInEdgesPtr()->GetEdgePtr()->SetFromOpPtr (prevop);
01261               //              h->E->GetInEdgesPtr()->GetEdgePtr()->SetFromOpId
01262               //                (prevop->GetOpId());
01263             } // end if
01264           h->E->Detach (0);
01265           if (!(op->IsPBROp()) ||
01266               op->GetSrcOprdPtr()->GetOprdType() != OT_LITERAL_CB)
01267             {
01268               dprintf((OUTF,"IfConvertHammock: moving op %d from E.\n",
01269                        op->GetOpId()));
01270               hyp->AddItem(op);
01271               op->SetParentBlockPtr (hyp);
01272               // Set PredVector and orig_hammock_hb_id attribute
01273               if (op->GetPredVectorPtr() == NULL) { 
01274                 op->SetPredVectorPtr(new bitvector(*new_E_vector));
01275               }
01276               else {
01277                 AddZerosRight(op->GetPredVectorPtr(), E_size, T_size); 
01278 //              MultiplyBits(op->GetPredVectorPtr(), (T_size + E_size), S_size);
01279                 ReplicateBits(op->GetPredVectorPtr(), (T_size + E_size), S_size);
01280               }
01281               dderr ("OpId = " << op->GetOpId() << " (a E op)\n");
01282 //            oprd = new legoOprd;
01283 //            oprd->SetOprdType (OT_LITERAL_I);
01284 //            oprd->SetLiteralInteger(hyp->GetRegionId());
01285 //            cerr << "OpId = " << op->GetOpId() << ", orig_hammock_hb_id = " << hyp->GetRegionId() << " (a E op)\n";
01286 //            AddLcAttribute ("orig_hammock_hb_id", oprd, op, proc);
01287             } // end if
01288           else
01289             {
01290               dprintf((OUTF,"IfConvertHammock: removing PBRR %d from E.\n",
01291                        op->GetOpId()));
01292               RemoveMidOp (op);
01293             } // end else
01294           if (i == 0)
01295             {
01296               prevop->SetNextLink (op);
01297               op->SetPrevLink (prevop);
01298             } // end if
01299 
01300           oprd = op->GetPredOprdPtr();
01301           // mdj - 4/2/99
01302           // Only want to update TRUE predicates here. If the predicate is now 
01303           // non-TRUE, it was updated by a prior hammock conversion. Leaving 
01304           // these predicates alone while updating (predicating) the CMPP ops 
01305           // that create these predicates produces the correct predicate values
01306           int dont_change_pred = 0;
01307           if (oprd != NULL) {
01308             if (oprd->GetOprdType() != OT_LITERAL_P ||
01309                 oprd->GetLiteralPredicate() != TRUE ) {
01310               dont_change_pred = 1;
01311             }
01312             else {
01313               delete oprd;
01314             }
01315           }
01316           if (!dont_change_pred) {
01317             oprd = new legoOprd (*Epredicate);
01318             op->SetPredOprdPtr (oprd);
01319             oprd->SetParentOpPtr (op);
01320           }
01321         } // end for
01322       prevop = op;
01323     } // end if
01324 
01325   // 2f. Move ops from J to hyp.
01326   count = h->J->GetCount();
01327   for (i = 0; i < count; i++)
01328     {
01329       op = (legoOp *) h->J->GetItem(0);
01330       AddWeightAttribute (op);
01331       h->J->Detach (0);
01332       dprintf((OUTF,"IfConvertHammock: moving op %d from J.\n",
01333                op->GetOpId()));
01334       hyp->AddItem(op);
01335       op->SetParentBlockPtr (hyp);
01336       // Set PredVector and orig_hammock_hb_id attribute
01337       if (op->GetPredVectorPtr() == NULL) { 
01338         op->SetPredVectorPtr(new bitvector(*new_SorJ_vector));
01339       }
01340       else {
01341         MultiplyBits(op->GetPredVectorPtr(), S_size, (T_size + E_size));
01342       }
01343       dderr ("OpId = " << op->GetOpId() << " (a J op)\n");
01344 //      oprd = new legoOprd;
01345 //      oprd->SetOprdType (OT_LITERAL_I);
01346 //      oprd->SetLiteralInteger(hyp->GetRegionId());
01347 //      cerr << "OpId = " << op->GetOpId() << ", orig_hammock_hb_id = " << hyp->GetRegionId() << " (a J op)\n";
01348 //      AddLcAttribute ("orig_hammock_hb_id", oprd, op, proc);
01349       if (i == 0)
01350         {
01351           prevop->SetNextLink (op);
01352           op->SetPrevLink (prevop);
01353         } // end if
01354     } // end for
01355 
01356   // 2g. Remove S, T, E, and J, and insert hyp.
01357   region = h->S->GetParentPtr();
01358   if (region == NULL)
01359     {
01360       dprintf((OUTF,"IfConvertHammock: can't find parent of S.\n"));
01361       return NULL;
01362     } // end if (for)
01363   if (makingnewHB)
01364     {
01365       i = region->Search (h->S);
01366       // Get rid of attributes before destroying h->S
01367       RemoveLiveAttribute (h->S, proc); 
01368       atl = h->S->GetRegionAttrListPtr();
01369       while (atl != NULL)
01370         {
01371           atype = atl->GetAttrType();
01372           if (atype != ATTR_LC)
01373             {
01374               atl = atl->GetNextListPtr(); continue;  // skip to first lc
01375             } // end if
01376           
01377           // Remove the first attribute here.
01378           a = atl->GetAttrPtr();
01379           RemoveLcAttribute (a->GetAttrString(), h->S, proc);
01380           
01381           atl = h->S->GetRegionAttrListPtr();  // reset for next scan
01382         } // end while
01383       if (i == MAX_UNSIGNED)
01384         {
01385           LegoNonFatal ("IfConvertHammock", "Can't find S block %d in its "
01386                         "parent region %d.", h->S->GetRegionId(),
01387                         region->GetRegionId());
01388           return NULL;
01389         } // end if
01390       if (h->S == ((legoTreegion *)region)->GetRoot())
01391         ((legoTreegion *)region)->SetRoot(hyp);
01392       // Destroying h->S, h->T, h->E, h->J blocks seems to fuck 
01393       // up things such as ParentBlockPtrs of Ops. So I will 
01394       // just leave them as orphaned blocks now and mark them. 
01395       // Will skip them in later in treeform()
01396 //      h->S->Mark (RM_GENERAL);
01397       region->DestroyItem (i);
01398 //      region->Insert (hyp, i);
01399       region->AddItem (hyp);
01400       hyp->SetParentPtr (region);
01401 //      if (!(region->IsOwner())) delete h->S;
01402     } // end if
01403 
01404   region = h->T->GetParentPtr();
01405   if (region == NULL)
01406     {
01407       LegoNonFatal ("IfConvertHammock", "Can't find parent of T block %d.",
01408                     h->T->GetRegionId());
01409       return NULL;
01410     } // end if (for)
01411   i = region->Search (h->T);
01412   // Get rid of attributes before destroying h->T
01413   RemoveLiveAttribute (h->T, proc); 
01414   atl = h->T->GetRegionAttrListPtr();
01415   while (atl != NULL)
01416     {
01417       atype = atl->GetAttrType();
01418       if (atype != ATTR_LC)
01419         {
01420           atl = atl->GetNextListPtr(); continue;  // skip to first lc
01421         } // end if
01422       
01423       // Remove the first attribute here.
01424       a = atl->GetAttrPtr();
01425       RemoveLcAttribute (a->GetAttrString(), h->T, proc);
01426       
01427       atl = h->T->GetRegionAttrListPtr();  // reset for next scan
01428     } // end while
01429   if (i == MAX_UNSIGNED)
01430     {
01431       LegoNonFatal ("IfConvertHammock", "Can't find T block %d in its "
01432                     "parent region %d.", h->T->GetRegionId(),
01433                     region->GetRegionId());
01434       return NULL;
01435     } // end if
01436   // Destroying h->S, h->T, h->E, h->J blocks seems to fuck 
01437   // up things such as ParentBlockPtrs of Ops. So I will 
01438   // just leave them as orphaned blocks now and mark them. 
01439   // Will skip them in later in treeform()
01440 //  h->T->Mark (RM_GENERAL);
01441   region->DestroyItem (i);
01442 //  if (!(region->IsOwner())) delete h->T;
01443 
01444   if (!(h->IsDelta()))
01445     {
01446       region = h->E->GetParentPtr();
01447       if (region == NULL)
01448         {
01449           LegoNonFatal ("IfConvertHammock", "Can't find parent of E block "
01450                         "%d.", h->E->GetRegionId());
01451           return NULL;
01452         } // end if (for)
01453       i = region->Search (h->E);
01454       // Get rid of attributes before destroying h->E
01455       RemoveLiveAttribute (h->E, proc); 
01456       atl = h->E->GetRegionAttrListPtr();
01457       while (atl != NULL)
01458         {
01459           atype = atl->GetAttrType();
01460           if (atype != ATTR_LC)
01461             {
01462               atl = atl->GetNextListPtr(); continue;  // skip to first lc
01463             } // end if
01464           
01465           // Remove the first attribute here.
01466           a = atl->GetAttrPtr();
01467           RemoveLcAttribute (a->GetAttrString(), h->E, proc);
01468           
01469           atl = h->E->GetRegionAttrListPtr();  // reset for next scan
01470         } // end while
01471       if (i == MAX_UNSIGNED)
01472         {
01473           LegoNonFatal ("IfConvertHammock", "Can't find E block %d in its "
01474                         "parent region %d.", h->E->GetRegionId(),
01475                         region->GetRegionId());
01476           return NULL;
01477         } // end if
01478       // Destroying h->S, h->T, h->E, h->J blocks seems to fuck 
01479       // up things such as ParentBlockPtrs of Ops. So I will 
01480       // just leave them as orphaned blocks now and mark them. 
01481       // Will skip them in later in treeform()
01482 //      h->E->Mark (RM_GENERAL);
01483       region->DestroyItem (i);
01484 //      if (!(region->IsOwner())) delete h->E;
01485     } // end if
01486 
01487   region = h->J->GetParentPtr();
01488   if (region == NULL)
01489     {
01490       LegoNonFatal ("IfConvertHammock", "Can't find parent of J block %d.",
01491                     h->J->GetRegionId());
01492       return NULL;
01493     } // end if (for)
01494   i = region->Search (h->J);
01495   // Get rid of attributes before destroying h->J
01496   RemoveLiveAttribute (h->J, proc); 
01497   atl = h->J->GetRegionAttrListPtr();
01498   while (atl != NULL)
01499     {
01500       atype = atl->GetAttrType();
01501       if (atype != ATTR_LC)
01502         {
01503           atl = atl->GetNextListPtr(); continue;  // skip to first lc
01504         } // end if
01505       
01506       // Remove the first attribute here.
01507       a = atl->GetAttrPtr();
01508       RemoveLcAttribute (a->GetAttrString(), h->J, proc);
01509       
01510       atl = h->J->GetRegionAttrListPtr();  // reset for next scan
01511     } // end while
01512   if (i == MAX_UNSIGNED)
01513     {
01514       LegoNonFatal ("IfConvertHammock", "Can't find J block %d in its "
01515                     "parent region %d.", h->J->GetRegionId(),
01516                     region->GetRegionId());
01517       return NULL;
01518     } // end if
01519   // Destroying h->S, h->T, h->E, h->J blocks seems to fuck 
01520   // up things such as ParentBlockPtrs of Ops. So I will 
01521   // just leave them as orphaned blocks now and mark them. 
01522   // Will skip them in later in treeform()
01523 //  h->J->Mark (RM_GENERAL);
01524   region->DestroyItem (i);
01525 //  if (!(region->IsOwner())) delete h->J;
01526 
01527   // 2h. Run SweepOps on hyp to remove interior branches and C_MERGEs.
01528   ((legoHB *)hyp)->RefreshOps();  // need for sweeping
01529   //  ((legoHB *)hyp)->SweepOps (1);
01530   sweepops ((legoHB *) hyp, 1);
01531 
01532   // 2i. Refresh the op/edge lists for hyp. Other regions don't need
01533   //     to be altered.
01534 
01535   ((legoHB *) hyp)->RefreshOps();
01536   ((legoHB *) hyp)->RefreshEdges();
01537   // actually, may need to also refresh treegion
01538 //  if (((legoRegion *)hyp->GetParentPtr())->GetRegionType() == RT_TREE) {
01539 //    ((legoTreegion *)hyp->GetParentPtr())->RefreshOps();
01540 //    ((legoTreegion *)hyp->GetParentPtr())->RefreshEdges();
01541 //  }
01542 
01543   delete Tpredicate;
01544   delete Epredicate;
01545   delete new_SorJ_vector;
01546   delete new_T_vector;
01547   delete new_E_vector;
01548 
01549   return hyp;
01550 } // end IfConvertHammock
01551 
01552 //===========================================================================
01553 
01554 
01555 /*
01556  * IfConvertTreeBranch
01557  *   returns: pointer to if-converted code (hyperblock), NULL if error
01558  *
01559  * Performs if-conversion (predication) on treegion based on branch profiling.
01560  *
01561  * This is actually rather complicated...>:P
01562  */
01563 legoOp *IfConvertTreeBranch (legoOp *branchop, knobs *K)
01564 {
01565   legoRegion *hyp;
01566   legoProc *proc;
01567   legoTreegion *tree;
01568   legoOprd *p1, *p2, *pX, *pTaken = NULL, *pFallThru = NULL;
01569   legoOprd *btroprd, *cmppoprd, *def, *use, *oprd;
01570   oprdList *defs, *uses;
01571   legoRegion *TakenBlock, *FallThruBlock, *BranchBlock; 
01572 
01573   opList *oplist, *oplisttoremove;
01574   legoOp *lastop, *pbrrop, *cmppop, *op, *fixlinkop, *return_prev_op;
01575   legoOp *prevop, *cmergetakenop, *cmergefallthruop;
01576   legoOp *FirstItem, *NextItem, *ThisItem, *listop;
01577   legoOp *TakenBRU, *FallThruBRU, *FallThruPBRR;
01578   legoOp *duplicatecmppop; 
01579   int fromopid, toopid;
01580   int opid, eaid, newregnum, count_uses;
01581 
01582   int makingnewHB, isBRCT, PBRRblock;
01583   int TreegionExit, TakenBlockInTree, FallThruBlockInTree;
01584   int AddCtrlEdge=FALSE, AddCtrlEdgeTaken=FALSE, AddCtrlEdgeFallThru=FALSE; 
01585   int AddCtrlEdgeTakenPrev=FALSE, AddCtrlEdgeFallThruPrev=FALSE;
01586   int AddCtrlEdgeFallThruPBRR=FALSE, AddCtrlEdgeFix=FALSE;
01587   legoOp *takenfromop, *takentoop, *fallthrufromop, *fallthrutoop;
01588   legoOp *takenprevfromop, *takenprevtoop, *fallthruprevfromop, *fallthruprevtoop;
01589   legoOp *fallthrupbrrfromop, *fallthrupbrrtoop;
01590   legoOp *fixfromop, *fixtoop;
01591   legoOp *removeedgefromop, *removeedgetoop;
01592   opEdges *edge;
01593   int Branch_size, Taken_size, FallThru_size; 
01594   int Branch_count; 
01595   legoOp *temp_op; 
01596   opList *temp_oplist;
01597 
01598   attrs *attrdictionary, *attrtail, *atscan, *a;
01599   attrList *atlscan, *atl;
01600 
01601   bitvector *new_true_vector, *new_taken_vector, *new_fallthru_vector, *temp_vector, *mask_vector; 
01602   int PredVectorSize, required_vector_size;
01603 
01604   enum attrTypes atype;
01605   
01606   FILE *converted_fp;
01607 
01608   BranchBlock = (legoRegion *) branchop->GetParentBlockPtr();
01609 
01610   dprintf((OUTF, "IfConvertTreeBranch: --- converting starting at %d ---\n",
01611            BranchBlock->GetRegionId()));
01612 
01613   // Determine if branch is a Treegion exit
01614   tree = (legoTreegion *) FindParentRegionType(RT_TREE, branchop);
01615   if (tree == NULL) return NULL; 
01616   TreegionExit = FALSE;
01617   for (oplist = tree->GetExitOpsPtr();
01618        oplist != NULL;
01619        oplist = oplist->GetNextListPtr()) {
01620     if ((op = oplist->GetOpPtr()) != NULL) 
01621       if (op == branchop) {
01622         TreegionExit = TRUE;
01623         break; 
01624       }
01625   }
01626 
01627   // Make sure that branch is a BRCT or BRCF op
01628   //if (branchop->IsBRCTOp())
01629   if(branchop->GetOpcode() == BRCT)
01630   {
01631       LegoNonFatal("IfConvertHammock", "BRCF is not supported yet.");      
01632     isBRCT = 1;
01633   }
01634   //else if (branchop->IsBRCFOp())
01635   else if(branchop->GetOpcode() == BRCF)
01636   {
01637       LegoNonFatal("IfConvertHammock", "BRCF is not supported yet.");
01638     isBRCT = 0;
01639   }
01640   else 
01641     return NULL; 
01642 
01643   // Make sure that the branch has only two exit ops
01644   oplist = branchop->GetOutListPtr();
01645   if (oplist == NULL || oplist->GetNextListPtr() == NULL ||
01646       oplist->GetNextListPtr()->GetNextListPtr() != NULL)
01647     return NULL;
01648   
01649   // Find the procedure
01650   proc = (legoProc *) FindParentRegionType(RT_PROC, branchop);
01651   if (proc == NULL) {
01652     dprintf((OUTF,"IfConvertTreeBranch: can't find proc!\n"));
01653     return NULL;    
01654   }
01655   
01656   // Make a new hyperblock if necessary
01657   if (BranchBlock->GetRegionType() != RT_HB)
01658     {
01659       hyp = new legoHB (BranchBlock->GetRegionId());  // make new hyperblock
01660       hyp->SetWeight (BranchBlock->GetWeight());
01661       oprd = new legoOprd;
01662       oprd->SetOprdType (OT_LITERAL_I);
01663       oprd->SetLiteralInteger(0);
01664       AddLcAttribute ("use_orig_wt", oprd, hyp, proc); 
01665       makingnewHB = 1;
01666     } // end if
01667   else
01668     {
01669       hyp = BranchBlock;  // use existing hyperblock
01670       makingnewHB = 0;
01671     } // end else
01672 
01673   if (branchop->GetSrcOprdPtr() == NULL ||
01674       branchop->GetSrcOprdPtr()->GetNextOprdPtr() == NULL)
01675     {
01676       LegoNonFatal ("IfConvertTreeBranch", "Can't find predicate source of "
01677                     "branch %d.", branchop->GetOpId());  // will need it later
01678       return NULL;
01679     } // end if
01680 
01681   // STEP 1: Analysis and setup.
01682 
01683   // 1a. Because I may want to IfConvertTreeBranch() after scheduling, I will 
01684   // use Chains to determine predecessor PBRR and CMPP. Requires 
01685   // ReachingDefinitions analysis to be current. 
01686   if (Chains == NULL) {
01687     LegoNonFatal ("IfConvertTreeBranch", "Chains is NULL: call ReachingDefinitions().");
01688     return NULL;
01689   } // end if
01690 
01691   // 1b. Find the target of the branch.
01692   btroprd = branchop->GetSrcOprdPtr(); // should be 1st source
01693   pbrrop = NULL;
01694   for (defs = Chains->GetUDChains()->Lookup (btroprd);
01695        (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
01696        defs = defs->GetNextListPtr()) {
01697     def = defs->GetOprdPtr();
01698     pbrrop = def->GetParentOpPtr(); // only one PBRR op should reach
01699     break; 
01700   }
01701 
01702   dderr ("pbrrop OpId is: " << pbrrop->GetOpId() << "\n");
01703   dderr ("branchop OpId is: " << branchop->GetOpId() << "\n");
01704   
01705   if (pbrrop == NULL) {
01706     LegoNonFatal ("IfConvertTreeBranch", "Can't find PBRR/PBRA in block %d.",
01707                   BranchBlock->GetRegionId());
01708     return NULL;
01709   } // end if
01710 
01711   oprd = pbrrop->GetSrcOprdPtr();
01712   if (oprd->GetOprdType() != OT_LITERAL_CB) {
01713     LegoNonFatal ("IfConvertTreeBranch", "PBRR %d not to control block.",
01714                   pbrrop->GetOpId());
01715     return NULL;
01716   } // end if
01717   
01718   // Find the Taken and FallThru Blocks 
01719   PBRRblock = oprd->GetLiteralControlBlock();
01720   oplist = branchop->GetOutListPtr();
01721   if (((legoRegion *) oplist->GetOpPtr()->GetParentBlockPtr())
01722       ->GetRegionId() ==  PBRRblock) {
01723     dderr ("oplist Valid = " << oplist->GetValid() << "\n");
01724     TakenBlock = (legoRegion *) oplist->GetOpPtr()->GetParentBlockPtr();
01725     dderr ("oplist Valid = " << oplist->GetNextListPtr()->GetValid() << "\n");
01726     FallThruBlock = (legoRegion *) oplist->GetNextListPtr()->GetOpPtr()->GetParentBlockPtr();
01727   }
01728   else if (((legoRegion *) oplist->GetNextListPtr()->GetOpPtr()
01729             ->GetParentBlockPtr())->GetRegionId() ==  PBRRblock) {
01730     dderr ("oplist Valid = " << oplist->GetValid() << "\n");
01731     FallThruBlock = (legoRegion *) oplist->GetOpPtr()->GetParentBlockPtr();
01732     dderr ("oplist Valid = " << oplist->GetNextListPtr()->GetValid() << "\n");
01733     TakenBlock = (legoRegion *) oplist->GetNextListPtr()->GetOpPtr()->GetParentBlockPtr();
01734   }
01735   else {
01736     LegoNonFatal ("IfConvertTreeBranch", "Could not determine TakenBlock and FallThruBlock in block %d.", BranchBlock->GetRegionId());
01737     return NULL;
01738   } // end if
01739 
01740   dderr ("BranchBlock Id is: " << BranchBlock->GetRegionId() << "\n");  
01741   dderr ("TakenBlock Id is: " << TakenBlock->GetRegionId() << "\n");  
01742   dderr ("FallThruBlock Id is: " << FallThruBlock->GetRegionId() << "\n");  
01743   
01744   // If TreegionExit == TRUE, determine if TakenBlock and FallThruBlock are 
01745   // within the Treegion (but not a loop back to Root)
01746   TakenBlockInTree = TRUE;
01747   FallThruBlockInTree = TRUE;
01748   if (TreegionExit == TRUE) {
01749     if ((tree != 
01750         ((legoTreegion *) FindParentRegionType(RT_TREE, TakenBlock))) ||
01751         (TakenBlock == tree->GetRoot())) {
01752       TakenBlockInTree = FALSE;
01753     }
01754     if ((tree != 
01755         ((legoTreegion *) FindParentRegionType(RT_TREE, FallThruBlock))) ||
01756         (FallThruBlock == tree->GetRoot())) {
01757       FallThruBlockInTree = FALSE;
01758     }
01759   }
01760   
01761   if ((TreegionExit == 1) && (TakenBlockInTree == 1) && (FallThruBlockInTree == 1))
01762     cerr << "Break Here\n";
01763 
01764   // Read in knobs.
01765   K->SetDefaultPanel ("rform/tree");
01766   K->Read ("num-bits-pred-vector", PredVectorSize);
01767 
01768   // Determine if PredVector length requirements can be satisfied
01769   // by PredVectorSize
01770   if ( (a = FindLcAttribute( "pred_vector_size", BranchBlock )) != NULL ) 
01771     Branch_size = a->GetAttrOprdPtr()->GetLiteralInteger();
01772   else 
01773     Branch_size = 1;
01774   if (branchop->GetPredVectorPtr() != NULL) {
01775     temp_vector = branchop->GetPredVectorPtr(); 
01776 #ifdef _SHOW_VECTORS
01777     dderr ("branchop vector :\n");
01778     temp_vector->Show();
01779 #endif // _SHOW_VECTORS
01780     Branch_count = 0; 
01781     for (int i = 0; i < Branch_size; i++) {
01782       if (temp_vector->Read(i)) {
01783         Branch_count++; 
01784       }
01785     }
01786   }
01787   else {
01788     Branch_count = 1; 
01789   }
01790   if (TakenBlockInTree) {
01791     if ( (a = FindLcAttribute( "pred_vector_size", TakenBlock )) != NULL ) 
01792       Taken_size = a->GetAttrOprdPtr()->GetLiteralInteger();
01793     else 
01794       Taken_size = 1; 
01795   }
01796   else {
01797     Taken_size = 1; 
01798   }
01799   if (FallThruBlockInTree) {
01800     if ( (a = FindLcAttribute( "pred_vector_size", FallThruBlock )) != NULL ) 
01801       FallThru_size = a->GetAttrOprdPtr()->GetLiteralInteger();
01802     else 
01803       FallThru_size = 1; 
01804   }
01805   else {
01806     FallThru_size = 1; 
01807   }
01808   required_vector_size = ((Branch_count * (Taken_size + FallThru_size - 1)) + Branch_size);
01809   if (required_vector_size > PredVectorSize) {
01810     LegoNonFatal ("IfConvertTreeBranch", "Need more PredVectorSize to continue if
01811 -conversion !!!\n.");
01812     return NULL;
01813   }
01814   // Update hyp's pred_vector_size attr
01815   oprd = new legoOprd;
01816   oprd->SetOprdType (OT_LITERAL_I);
01817   oprd->SetLiteralInteger(required_vector_size);
01818   AddLcAttribute ("pred_vector_size", oprd, hyp, proc); 
01819   // Create Prototype for Join PredVector
01820   new_true_vector = new bitvector(PredVectorSize);   
01821   new_taken_vector = new bitvector(PredVectorSize);   
01822   new_fallthru_vector = new bitvector(PredVectorSize); 
01823   if (branchop->GetPredVectorPtr() != NULL) {
01824     mask_vector = new bitvector(*branchop->GetPredVectorPtr()); 
01825   }
01826   else {
01827     mask_vector = new bitvector(PredVectorSize);
01828     mask_vector->Set(0);
01829   }
01830   for (int i = 0; i < required_vector_size; i++) {
01831     new_true_vector->Set(i);
01832   }
01833   // The following vectors are only used for BB used for the first time in 
01834   // a HB (they will only replace a NULL PredVector)
01835   new_taken_vector->Set(0);
01836   new_fallthru_vector->Set(Taken_size);
01837   new_taken_vector = ReplicateBitsMask(new_taken_vector, mask_vector, Branch_size, (Taken_size + FallThru_size), PredVectorSize);
01838   new_fallthru_vector = ReplicateBitsMask(new_fallthru_vector, mask_vector, Branch_size, (Taken_size + FallThru_size), PredVectorSize);
01839   dderr ("\nBranch_size = " << Branch_size << "\n");
01840   dderr ("Taken_size = " << Taken_size << "\n");
01841   dderr ("FallThru_size = " << FallThru_size << "\n");
01842   dderr ("Branch_count = " << Branch_count << "\n");
01843   dderr ("required_vector_size = " << required_vector_size << "\n");
01844 #ifdef _SHOW_VECTORS
01845   new_true_vector->Show();
01846   new_taken_vector->Show();
01847   new_fallthru_vector->Show();
01848 #endif // _SHOW_VECTORS
01849   
01850 
01851 
01852   // If we need new BRUs to a TakenBlock or FallThruBlock not in the Treegion, 
01853   // copy construct them now from orig branchop and orig pbrrop before 
01854   // they are removed. 
01855   cmergetakenop = TakenBlock->GetEntryOpsPtr()->GetOpPtr();
01856   cmergefallthruop = FallThruBlock->GetEntryOpsPtr()->GetOpPtr();
01857   if (TreegionExit == TRUE) {
01858     if (TakenBlockInTree == FALSE) {
01859       opid = (FindMaxOpId ((legoProc *) proc))->GetOpId();
01860       // Add weight attr now to branchop so that it is copy constructed to the 
01861       // new BRU
01862       AddWeightAttribute (branchop);
01863       TakenBRU = new legoOp(*branchop);
01864       TakenBRU->SetOpcode(BRU);
01865       TakenBRU->SetOpId (++opid);
01866 //      // make sure to copy the hammockPredVector
01867 //      if (branchop->GetHammockPredVectorPtr() != NULL) {
01868 //      TakenBRU->SetHammockPredVectorPtr(new bitvector(*branchop->GetHammockPredVectorPtr()));
01869 //      }
01870       TakenBRU->SetParentBlockPtr (hyp);
01871       // Add to proc allListPtr - ops are enqueued in reverse.
01872       TakenBRU->SetListOpPtr(proc->GetListOpPtr());
01873       proc->SetListOpPtr (TakenBRU);
01874       // Get rid of the predicate source
01875       oprd = TakenBRU->GetSrcOprdPtr()->GetNextOprdPtr();
01876       TakenBRU->GetSrcOprdPtr()->SetNextOprdPtr(NULL);
01877       delete oprd; 
01878       // Duplicate op attributes.
01879       attrdictionary = proc->GetAttrDictionary();
01880       for (attrtail = attrdictionary; attrtail->GetNextAttrPtr() != NULL;
01881            attrtail = attrtail->GetNextAttrPtr()) /* do nothing */;
01882       eaid = FindMaxEdgeAttrId (proc);
01883       for (atlscan = TakenBRU->GetOpAttrListPtr(); atlscan != NULL;
01884            atlscan = atlscan->GetNextListPtr())
01885         {
01886           if (atlscan->GetAttrPtr() == NULL)
01887             continue;
01888           atscan = new attrs (*(atlscan->GetAttrPtr()), TakenBRU, ++eaid);
01889           atlscan->SetAttrPtr (atscan);
01890           atscan->SetAttrId (eaid);
01891           atlscan->SetAttrId (eaid);
01892           attrtail->SetNextAttrPtr (atscan);
01893           attrtail = attrtail->GetNextAttrPtr();
01894         } // end for
01895       // Get rid of out op to FallThruBlock
01896       oplist = TakenBRU->GetOutListPtr();
01897       // FallThruBlock is either the 1st or 2nd op on oplist
01898       if (TakenBlock == 
01899           (legoRegion *) oplist->GetOpPtr()->GetParentBlockPtr()) {
01900         oplisttoremove = oplist->GetNextListPtr();
01901         oplist->SetNextListPtr(NULL);
01902         delete oplisttoremove;
01903       }
01904       else {
01905         oplisttoremove = oplist;
01906         oplist = oplisttoremove->GetNextListPtr();
01907         oplisttoremove->SetNextListPtr(NULL);
01908         delete oplisttoremove;
01909         TakenBRU->SetOutListPtr(oplist);
01910       }
01911       // Fix Out Edge
01912       edge = FindControlEdge (branchop, cmergetakenop, 1);
01913       if (edge == NULL)
01914         LegoFatal ("IfConvertTreeBranch", "Can't find edge from "
01915                    "op %d to op %d.", TakenBRU->GetOpId(), cmergetakenop->GetOpId());
01916       // Re-do inList for the op that this edge reaches
01917       for (temp_oplist = edge->GetToOpPtr()->GetInListPtr();
01918            temp_oplist->GetOpPtr() != branchop;
01919            temp_oplist = temp_oplist->GetNextListPtr())
01920         ; // just find the list element that needs updating
01921       temp_oplist->SetOpPtr(TakenBRU);
01922       temp_oplist->SetOpId(TakenBRU->GetOpId()); 
01923       edge->SetFromOpPtr (TakenBRU);
01924       edge->SetFromOpId (TakenBRU->GetOpId());
01925     }
01926     
01927     if (FallThruBlockInTree == FALSE) {
01928       opid = (FindMaxOpId ((legoProc *) proc))->GetOpId();
01929       // Add weight attr now to branchop so that it is copy constructed to the 
01930       // new BRUs
01931       AddWeightAttribute (branchop);
01932       FallThruBRU = new legoOp(*branchop);
01933       FallThruBRU->SetOpcode(BRU);
01934       FallThruBRU->SetOpId (++opid);
01935 //      if (branchop->GetHammockPredVectorPtr() != NULL) {
01936 //      FallThruBRU->SetHammockPredVectorPtr(new bitvector(*branchop->GetHammockPredVectorPtr()));
01937 //      }
01938       FallThruBRU->SetParentBlockPtr (hyp);
01939       // Add to proc allListPtr - ops are enqueued in reverse.
01940       FallThruBRU->SetListOpPtr(proc->GetListOpPtr());
01941       proc->SetListOpPtr (FallThruBRU);
01942       // Get rid of the predicate source
01943       oprd = FallThruBRU->GetSrcOprdPtr()->GetNextOprdPtr();
01944       FallThruBRU->GetSrcOprdPtr()->SetNextOprdPtr(NULL);
01945       delete oprd; 
01946       // ReDo the BTR source
01947       oprd = FallThruBRU->GetSrcOprdPtr();
01948       newregnum = FindMaxRegNum (proc);
01949       oprd->SetOprdRegNum(++newregnum);
01950       //delete oprd;      
01951       //FallThruBRU->SetSrcOprdPtr(NULL);
01952       // Duplicate op attributes.
01953       attrdictionary = proc->GetAttrDictionary();
01954       for (attrtail = attrdictionary; attrtail->GetNextAttrPtr() != NULL;
01955            attrtail = attrtail->GetNextAttrPtr()) /* do nothing */;
01956       eaid = FindMaxEdgeAttrId (proc);
01957       for (atlscan = FallThruBRU->GetOpAttrListPtr(); atlscan != NULL;
01958            atlscan = atlscan->GetNextListPtr())
01959         {
01960           if (atlscan->GetAttrPtr() == NULL)
01961             continue;
01962           atscan = new attrs (*(atlscan->GetAttrPtr()), FallThruBRU, ++eaid);
01963           atlscan->SetAttrPtr (atscan);
01964           atscan->SetAttrId (eaid);
01965           atlscan->SetAttrId (eaid);
01966           attrtail->SetNextAttrPtr (atscan);
01967           attrtail = attrtail->GetNextAttrPtr();
01968         } // end for
01969       // Get rid of out op to TakenBlock
01970       oplist = FallThruBRU->GetOutListPtr();
01971       // TakenBlock is either the 1st or 2nd op on oplist
01972       if (FallThruBlock == 
01973           (legoRegion *) oplist->GetOpPtr()->GetParentBlockPtr()) {
01974         oplisttoremove = oplist->GetNextListPtr();
01975         oplist->SetNextListPtr(NULL);
01976         delete oplisttoremove;
01977       }
01978       else {
01979         oplisttoremove = oplist;
01980         oplist = oplisttoremove->GetNextListPtr();
01981         oplisttoremove->SetNextListPtr(NULL);
01982         delete oplisttoremove;
01983         FallThruBRU->SetOutListPtr(oplist);
01984       }
01985       // Fix Out Edge
01986       edge = FindControlEdge (branchop, cmergefallthruop, 1);
01987       if (edge == NULL)
01988         LegoFatal ("IfConvertTreeBranch", "Can't find edge from "
01989                    "op %d to op %d.", FallThruBRU->GetOpId(), cmergefallthruop->GetOpId());
01990       // Re-do inList for the op that this edge reaches
01991       for (temp_oplist = edge->GetToOpPtr()->GetInListPtr();
01992            temp_oplist->GetOpPtr() != branchop;
01993            temp_oplist = temp_oplist->GetNextListPtr())
01994         ; // just find the list element that needs updating
01995       temp_oplist->SetOpPtr(FallThruBRU);
01996       temp_oplist->SetOpId(FallThruBRU->GetOpId()); 
01997       edge->SetFromOpPtr (FallThruBRU);
01998       edge->SetFromOpId (FallThruBRU->GetOpId()); 
01999       
02000       // FallThruBRU also needs a new PBR
02001       opid = (FindMaxOpId ((legoProc *) proc))->GetOpId();
02002       // Add weight attr now to pbrrop so that it is copy constructed to the 
02003       // new PBRR
02004       AddWeightAttribute (pbrrop);
02005       FallThruPBRR = new legoOp(*pbrrop);
02006       FallThruPBRR->SetOpId (++opid);
02007 //      if (pbrrop->GetHammockPredVectorPtr() != NULL) {
02008 //      FallThruPBRR->SetHammockPredVectorPtr(new bitvector(*pbrrop->GetHammockPredVectorPtr()));
02009 //      }
02010       FallThruPBRR->SetParentBlockPtr (hyp);
02011       // Add to proc allListPtr - ops are enqueued in reverse.
02012       FallThruPBRR->SetListOpPtr(proc->GetListOpPtr());
02013       proc->SetListOpPtr (FallThruPBRR);
02014       // ReDo the BTR dest
02015       oprd = FallThruPBRR->GetDestOprdPtr();
02016       oprd->SetOprdRegNum(newregnum);
02017       // ReDo the CB literal
02018       oprd = FallThruPBRR->GetSrcOprdPtr();
02019       oprd->SetLiteralControlBlock (FallThruBlock->GetRegionId());
02020       // Duplicate op attributes.
02021       for (attrtail = attrdictionary; attrtail->GetNextAttrPtr() != NULL;
02022            attrtail = attrtail->GetNextAttrPtr()) /* do nothing */;
02023       eaid = FindMaxEdgeAttrId (proc);
02024       for (atlscan = FallThruPBRR->GetOpAttrListPtr(); atlscan != NULL;
02025            atlscan = atlscan->GetNextListPtr())
02026         {
02027           if (atlscan->GetAttrPtr() == NULL)
02028             continue;
02029           atscan = new attrs (*(atlscan->GetAttrPtr()), FallThruPBRR, ++eaid);
02030           atlscan->SetAttrPtr (atscan);
02031           atscan->SetAttrId (eaid);
02032           atlscan->SetAttrId (eaid);
02033           attrtail->SetNextAttrPtr (atscan);
02034           attrtail = attrtail->GetNextAttrPtr();
02035         } // end for
02036     }
02037   }
02038     
02039   // Don't destroy this PBR if it reaches any other branches (possible 
02040   // if speculated and dominator parallel) or if TakenBlockInTree == FALSE
02041   int destroy = TRUE;
02042   if (TakenBlockInTree == TRUE) {
02043     for (uses = Chains->GetDUChains()->Lookup (def);
02044          (uses != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
02045          uses = uses->GetNextListPtr()) {
02046       use = uses->GetOprdPtr();
02047       if (use->GetParentOpPtr() != branchop) {
02048         destroy = FALSE;
02049         break; 
02050       } 
02051     }
02052   }
02053   else {
02054     destroy = FALSE;
02055   }
02056 
02057   return_prev_op = branchop->GetPrevLink(); 
02058   if (destroy) {
02059     if (pbrrop == return_prev_op) {
02060       return_prev_op = pbrrop->GetPrevLink(); 
02061     }
02062     RemoveMidOp(pbrrop, 1);
02063   }
02064 
02065   // 1c. Find the predicate operands that are the destination of the CMPP.
02066   //     Put the first in p1, the second in p2. If the second isn't there, 
02067   //     take care of it.
02068   cmppoprd = branchop->GetSrcOprdPtr()->GetNextOprdPtr(); // 2nd source
02069   cmppop = NULL;
02070   for (defs = Chains->GetUDChains()->Lookup (cmppoprd);
02071        (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
02072        defs = defs->GetNextListPtr()) {
02073     def = defs->GetOprdPtr();
02074     cmppop = def->GetParentOpPtr(); // only one CMPP op should reach
02075     break; 
02076   }
02077   
02078   dderr ("cmppop OpId is: " << cmppop->GetOpId() << "\n");
02079 
02080   if (cmppop == NULL) {
02081     LegoNonFatal ("IfConvertTreeBranch", "Can't find CMPP for branch %d.",
02082                   BranchBlock->GetRegionId());
02083     return NULL;
02084   } // end if
02085 
02086   if (cmppop->IsCMPPOp()) {
02087     LegoNonFatal ("IfConvertTreeBranch", "Can't find CMPP for branch %d.",
02088                   BranchBlock->GetRegionId());
02089     return NULL;
02090   } // end if
02091 
02092   // make sure that the second D-action is a complement (odd-number opcode)
02093   div_t remainder = div(cmppop->GetOpcode(), 2);
02094   if (remainder.rem == 0) {
02095     cmppop->SetOpcode((cmppop->GetOpcode() + 1));
02096   }
02097   
02098   p1 = cmppop->GetDestOprdPtr();  // first destination!
02099   if (p1 == NULL || p1->GetNextOprdPtr() == NULL)
02100     {
02101       LegoNonFatal ("IfConvertTreeBranch", "CMPP %d has bad destinations.",
02102                     cmppop->GetOpId());
02103       return NULL;
02104     } // end if
02105   p2 = p1->GetNextOprdPtr();  // p2 is there always!
02106   if (p1->GetNextOprdPtr()->GetOprdType() != OT_UNDEFINED)
02107     /* do nothing - we have two predicates! */;
02108   else {   // Nuts, there's no second destination. 
02109     // We need a second destination. Scan through
02110     // every op in the proc to find the next predicate register that's
02111     // free.
02112     if (NextPredRegNum == 0) {  // find it
02113       legoOp *o;
02114       legoOprd *d;
02115       for (o = proc->GetListOpPtr(); o != NULL; o = o->GetListOpPtr()) {
02116         for (d = o->GetSrcOprdPtr(); d != NULL; d = d->GetNextOprdPtr())
02117           if (d->GetOprdType() == OT_REG &&
02118               //                    (d->GetOprdDataType() == DT_P ||
02119               //                     d->GetOprdFileType() == FT_PR) &&
02120               d->GetOprdRegNum() > NextPredRegNum)
02121             NextPredRegNum = d->GetOprdRegNum();
02122         
02123         for (d = o->GetDestOprdPtr(); d != NULL; d = d->GetNextOprdPtr())
02124           if (d->GetOprdType() == OT_REG &&
02125               //                    (d->GetOprdDataType() == DT_P ||
02126               //                     d->GetOprdFileType() == FT_PR) &&
02127               d->GetOprdRegNum() > NextPredRegNum)
02128             NextPredRegNum = d->GetOprdRegNum();
02129         
02130         for (d = o->GetPredOprdPtr(); d != NULL; d = d->GetNextOprdPtr())
02131           if (d->GetOprdType() == OT_REG &&
02132               //                    (d->GetOprdDataType() == DT_P ||
02133               //                     d->GetOprdFileType() == FT_PR) &&
02134               d->GetOprdRegNum() > NextPredRegNum)
02135             NextPredRegNum = d->GetOprdRegNum();
02136       } // end for
02137       
02138       NextPredRegNum++;  // next available one
02139       dprintf((OUTF, "IfConvertTreeBranch: NextPredRegNum = %d\n",
02140                NextPredRegNum));
02141     } // end if
02142     
02143     // For hyperblocks, need to make sure that all predicates start out 
02144     // unique, so I will also refresh p1's number. With the lack of control
02145     // flow within a hyperblock control flow out can get confused when more 
02146     // than one CMPP uses the same prednumb (especially after scheduling). 
02147     // TailDuplication of CMPPs is a source for this problem. Once again, 
02148     // learned this one the hard way. 
02149 
02150     // If p1 reaches more than one branch (possible if merged due to dominator
02151     // parallelism) copy construct a new CMPP
02152     for (count_uses = 0, uses = Chains->GetDUChains()->Lookup (p1);
02153          (uses != NULL) && (Chains->GetDUChains()->NotFound() == FALSE);
02154          count_uses++, uses = uses->GetNextListPtr()) 
02155       use = uses->GetOprdPtr();  // just count uses
02156     if (count_uses > 1) { // more than one use found, copy construct CMPP
02157   // should update RDefs somewhere around here so that I do not need to 
02158   // copy construct CMPPs that now only reach one use.
02159       dderr ("*** This part has not been debugged yet *** count = " << count_uses << "\n");
02160       duplicatecmppop = new legoOp(*cmppop);
02161       duplicatecmppop->SetOpId(FindMaxOpId((legoProc *) proc)->GetOpId() + 1);
02162       // Duplicate op attributes.
02163       attrdictionary = proc->GetAttrDictionary();
02164       for (attrtail = attrdictionary; attrtail->GetNextAttrPtr() != NULL;
02165            attrtail = attrtail->GetNextAttrPtr()) /* do nothing */;
02166       eaid = FindMaxEdgeAttrId (proc);
02167       for (atlscan = duplicatecmppop->GetOpAttrListPtr(); atlscan != NULL;
02168            atlscan = atlscan->GetNextListPtr())
02169         {
02170           if (atlscan->GetAttrPtr() == NULL)
02171             continue;
02172           atscan = new attrs (*(atlscan->GetAttrPtr()), duplicatecmppop, ++eaid);
02173           atlscan->SetAttrPtr (atscan);
02174           atscan->SetAttrId (eaid);
02175           atlscan->SetAttrId (eaid);
02176           attrtail->SetNextAttrPtr (atscan);
02177           attrtail = attrtail->GetNextAttrPtr();
02178         } // end for
02179       // make sure to copy the hammockPredVector
02180       if (cmppop->GetPredVectorPtr() != NULL) {
02181         duplicatecmppop->SetPredVectorPtr(new bitvector(*cmppop->GetPredVectorPtr()));
02182       }
02183       
02184       p1 = duplicatecmppop->GetDestOprdPtr();  // first destination!
02185       if (p1 == NULL || p1->GetNextOprdPtr() == NULL)
02186         {
02187           LegoNonFatal ("IfConvertTreeBranch", "duplicatecmppop %d has bad destinations.",
02188                         duplicatecmppop->GetOpId());
02189           return NULL;
02190         } // end if
02191       AddMidOp (duplicatecmppop, cmppop);
02192       p2 = p1->GetNextOprdPtr();  // p2 is there always!
02193       p1->SetOprdRegNum (NextPredRegNum);
02194       // Need the same new number for the branch that this reaches
02195       branchop->GetSrcOprdPtr()->GetNextOprdPtr()->SetOprdRegNum(NextPredRegNum++);
02196     }
02197     else { // just rename p1 and the branchop that it should reach
02198       dderr ("A-OK: count = " << count_uses << "\n");
02199       dderr ("branchopId = " << branchop->GetOpId() << "\n");
02200       dderr ("UseOpId = " << use->GetParentOpPtr()->GetOpId() << "\n");
02201       p1->SetOprdRegNum (NextPredRegNum);
02202       // Need the same new number for the branch that this reaches
02203       branchop->GetSrcOprdPtr()->GetNextOprdPtr()->SetOprdRegNum(NextPredRegNum++);
02204     }
02205     
02206     // Make the new operand and plop it into the CMPP.
02207     p2->SetOprdType (p1->GetOprdType());
02208     p2->SetOprdRegNum (NextPredRegNum++);
02209     p2->SetOprdRegType (p1->GetOprdRegType());
02210     p2->SetOprdDataType (p1->GetOprdDataType());
02211     p2->SetOprdFileType (p1->GetOprdFileType());
02212     p2->SetOprdOmega (p1->GetOprdOmega());
02213     p2->SetOprdRegStyle (p1->GetOprdRegStyle());
02214     p2->SetIntValue (p1->GetOprdIntValue());
02215   } // end else
02216 
02217   // 1d. Figure out pTaken and pFallThru, the predicates for the 
02218   //     Taken Block and FallThru Block
02219   //          |       branch to Taken        |
02220   //          |                              |
02221   //  BRCT pX | pTaken = pX, pFallThru = !pX | 
02222   //          |                              |
02223   //  BRCF pX | pTaken = !pX, pFallThru = pX | 
02224 
02225   pX = branchop->GetSrcOprdPtr()->GetNextOprdPtr();
02226   if (pX->GetOprdRegNum() == p1->GetOprdRegNum())
02227     pX = p1;  // point pX to p1
02228   else
02229     pX = p2;  // point pX to p2
02230   
02231   if (isBRCT)    {
02232     pTaken = pX;
02233     pFallThru = (pTaken == p1 ? p2 : p1);
02234   } // end if
02235   else {
02236     pFallThru = pX;
02237     pTaken = (pFallThru == p1 ? p2 : p1);
02238   } // end else
02239   
02240   // STEP 2: If-Conversion
02241 
02242   legoOprd *Tpredicate;
02243   legoOprd *Fpredicate;
02244 
02245   regionList *rl;
02246   legoRegion *region;
02247   unsigned i, count;
02248   int mapping; 
02249 
02250   // Output to iF_CoNVeRTeD_PT file that the mapping of this branchop 
02251   // will be if-converted
02252   converted_fp = fopen("./iF_CoNVeRTeD_PT", "a");
02253   if(converted_fp==NULL) {
02254     LegoFatal ("IfConvertTreeBranch", "Could not open iF_CoNVeRTeD_PT.");
02255   }
02256   if ( (a = FindLcAttribute( "branch_mapping", branchop )) != NULL ) {
02257     mapping = a->GetAttrOprdPtr()->GetLiteralInteger();
02258     fprintf(converted_fp,"%d\n", mapping);
02259     fclose(converted_fp);
02260   }
02261   else {
02262 //    LegoNonFatal ("IfConvertTreeBranch", "No mapping for branchop Id %d\n.",
02263 //                branchop->GetOpId());
02264   }
02265 
02266   fprintf(converted_fp,"%d\n", mapping);
02267   fclose(converted_fp);
02268   
02269   // 2a. Make new prototype predicate legoOprds based on pTaken and pFallThru
02270   Tpredicate = MakeDupPred (pTaken);
02271   Fpredicate = MakeDupPred (pFallThru);
02272 
02273   // 2b. Invalidate children lists of parents of branchop's
02274   //     region_ptr, and invalidate parents lists of children of branchop's 
02275   //     region_ptgr. Also, invalidate parents of the children of the Taken 
02276   //     and FallThru Blocks.
02277 
02278   // I'm pretty sure that I do not need all of these (especially because 
02279   // RefreshEdges also resets) but added them while chasing bug and it 
02280   // works with them now, and it NEEDs to keep working
02281   for (rl = BranchBlock->GetParents(); 
02282        rl != NULL; 
02283        rl = rl->GetNextListPtr())
02284     {
02285       region = rl->GetRegionPtr();
02286       if (region != NULL)
02287         {
02288           delete (region->GetChildren());
02289           region->SetChildren (NULL);
02290         } // end if
02291     } // end for
02292   for (rl = BranchBlock->GetChildren(); 
02293        rl != NULL; 
02294        rl = rl->GetNextListPtr())
02295     {
02296       region = rl->GetRegionPtr();
02297       if (region != NULL)
02298         {
02299           delete (region->GetParents());
02300           region->SetParents (NULL);
02301         } // end if
02302     } // end for
02303   for (rl = TakenBlock->GetChildren(); 
02304        rl != NULL; 
02305        rl = rl->GetNextListPtr())
02306     {
02307       region = rl->GetRegionPtr();
02308       if (region != NULL)
02309         {
02310           delete (region->GetParents());
02311           region->SetParents (NULL);
02312         } // end if
02313     } // end for
02314   for (rl = TakenBlock->GetParents(); 
02315        rl != NULL; 
02316        rl = rl->GetNextListPtr())
02317     {
02318       region = rl->GetRegionPtr();
02319       if (region != NULL)
02320         {
02321           delete (region->GetChildren());
02322           region->SetChildren (NULL);
02323         } // end if
02324     } // end for
02325   for (rl = FallThruBlock->GetChildren(); 
02326        rl != NULL; 
02327        rl = rl->GetNextListPtr())
02328     {
02329       region = rl->GetRegionPtr();
02330       if (region != NULL)
02331         {
02332           delete (region->GetParents());
02333           region->SetParents (NULL);
02334         } // end if
02335     } // end for
02336   for (rl = FallThruBlock->GetParents(); 
02337        rl != NULL; 
02338        rl = rl->GetNextListPtr())
02339     {
02340       region = rl->GetRegionPtr();
02341       if (region != NULL)
02342         {
02343           delete (region->GetChildren());
02344           region->SetChildren (NULL);
02345         } // end if
02346     } // end for
02347 
02348   fixlinkop = NULL;
02349   if (branchop->GetNextLink() != NULL)
02350     fixlinkop = branchop->GetNextLink();
02351   
02352   if (!makingnewHB) {
02353     // Just Update PredVector for ops already in hyp
02354     for (FirstItem = (legoOp *) BranchBlock->GetItem(0); 
02355          FirstItem->GetPrevLink() != NULL;
02356          FirstItem = FirstItem->GetPrevLink())
02357       ; // do nothing
02358     for (NextItem = FirstItem; NextItem != NULL; ) {
02359       ThisItem = NextItem; 
02360       NextItem = NextItem->GetNextLink();
02361       // Add/Update PredVector
02362       if (ThisItem->GetPredVectorPtr() == NULL) { 
02363         LegoNonFatal ("IfConvertTreeBranch", "Can't find PredVector for OpId %d  "
02364                       " in HBId %d.", ThisItem->GetOpId(), BranchBlock->GetRegionId());
02365         ThisItem->SetPredVectorPtr(new bitvector(*new_true_vector));
02366       }
02367       else {
02368         ThisItem->SetPredVectorPtr(MultiplyBitsMask(ThisItem->GetPredVectorPtr(), mask_vector, Branch_size, (Taken_size + FallThru_size), PredVectorSize));
02369       }
02370       dderr ("OpId = " << ThisItem->GetOpId() << " (a BranchBlock op)\n");
02371     } // end for
02372   }
02373 
02374   prevop = branchop->GetPrevLink();
02375   removeedgefromop = prevop;
02376   removeedgetoop = branchop;
02377   RemoveEdge (prevop, branchop, proc, ET_CNTL);  
02378   branchop->GetPrevLink()->SetNextLink (NULL);
02379   if (branchop->GetNextLink() != NULL) {
02380     RemoveEdge (branchop, branchop->GetNextLink(), proc, ET_CNTL); 
02381     branchop->SetNextLink(NULL); 
02382   }
02383   branchop->SetPrevLink (NULL);
02384   branchop->SetNextLink (NULL);
02385   if (TakenBlockInTree == TRUE) {
02386     cmergetakenop->GetNextLink()->SetPrevLink (NULL);
02387     RemoveEdge (cmergetakenop, cmergetakenop->GetNextLink(), proc, ET_CNTL);  
02388     cmergetakenop->SetPrevLink (NULL);
02389     cmergetakenop->SetNextLink (NULL);
02390     RemoveEdge (branchop, cmergetakenop, proc, ET_CNTL);  
02391   }
02392   if (FallThruBlockInTree == TRUE) {
02393     cmergefallthruop->GetNextLink()->SetPrevLink (NULL);
02394     RemoveEdge (cmergefallthruop, cmergefallthruop->GetNextLink(), proc, ET_CNTL);  
02395     cmergefallthruop->SetPrevLink (NULL);
02396     cmergefallthruop->SetNextLink (NULL);
02397     RemoveEdge (branchop, cmergefallthruop, proc, ET_CNTL);  
02398   }
02399   
02400   // remove branchop from allList, etc. 
02401   if ((listop = proc->GetListOpPtr()) != branchop) {
02402     for (;
02403          listop != NULL && listop->GetListOpPtr() != branchop;
02404          listop = listop->GetListOpPtr())
02405       /* do nothing */;
02406   }
02407   if (listop != NULL)
02408     {
02409       if (proc->GetListOpPtr() != branchop)
02410         listop->SetListOpPtr (branchop->GetListOpPtr());
02411       else
02412         proc->SetListOpPtr (branchop->GetListOpPtr());
02413     } // end if
02414   branchop->SetListOpPtr (NULL);
02415     
02416   // Detach from region.
02417   BranchBlock->Detach(BranchBlock->Search(branchop));
02418   
02419   RemoveLiveAttribute (branchop, proc);  // kill live attribute right off
02420   
02421   atl = branchop->GetOpAttrListPtr();
02422   while (atl != NULL)
02423     {
02424       atype = atl->GetAttrType();
02425       if (atype != ATTR_LC)
02426         {
02427           atl = atl->GetNextListPtr(); continue;  // skip to first lc
02428         } // end if
02429       
02430       // Remove the first attribute here.
02431       a = atl->GetAttrPtr();
02432       RemoveLcAttribute (a->GetAttrString(), branchop, proc);
02433       
02434       atl = branchop->GetOpAttrListPtr();  // reset for next scan
02435     } // end while
02436   delete branchop;
02437   
02438   // remove cmergetakenop from allList, etc. 
02439   if (TakenBlockInTree == TRUE) {
02440     if ((listop = proc->GetListOpPtr()) != cmergetakenop) {
02441       for (;
02442            listop != NULL && listop->GetListOpPtr() != cmergetakenop;
02443            listop = listop->GetListOpPtr())
02444         /* do nothing */;
02445     }
02446     if (listop != NULL)
02447       {
02448         if (proc->GetListOpPtr() != cmergetakenop)
02449           listop->SetListOpPtr (cmergetakenop->GetListOpPtr());
02450         else
02451           proc->SetListOpPtr (cmergetakenop->GetListOpPtr());
02452       } // end if
02453     cmergetakenop->SetListOpPtr (NULL);
02454     
02455     // Detach from region.
02456     TakenBlock->Detach(TakenBlock->Search(cmergetakenop));
02457     
02458     RemoveLiveAttribute (cmergetakenop, proc);  // kill live attribute right off
02459     
02460     atl = cmergetakenop->GetOpAttrListPtr();
02461     while (atl != NULL)
02462       {
02463         atype = atl->GetAttrType();
02464         if (atype != ATTR_LC)
02465           {
02466             atl = atl->GetNextListPtr(); continue;  // skip to first lc
02467           } // end if
02468         
02469         // Remove the first attribute here.
02470         a = atl->GetAttrPtr();
02471         RemoveLcAttribute (a->GetAttrString(), cmergetakenop, proc);
02472         
02473         atl = cmergetakenop->GetOpAttrListPtr();  // reset for next scan
02474       } // end while
02475     delete cmergetakenop;
02476   }
02477   
02478   // remove cmergefallthruop from allList, etc. 
02479   if (FallThruBlockInTree == TRUE) {
02480     if ((listop = proc->GetListOpPtr()) != cmergefallthruop) {
02481       for (;
02482            listop != NULL && listop->GetListOpPtr() != cmergefallthruop;
02483            listop = listop->GetListOpPtr())
02484         /* do nothing */;
02485     }
02486     if (listop != NULL)
02487       {
02488         if (proc->GetListOpPtr() != cmergefallthruop)
02489           listop->SetListOpPtr (cmergefallthruop->GetListOpPtr());
02490         else
02491           proc->SetListOpPtr (cmergefallthruop->GetListOpPtr());
02492       } // end if
02493     cmergefallthruop->SetListOpPtr (NULL);
02494     
02495     // Detach from region.
02496     FallThruBlock->Detach(FallThruBlock->Search(cmergefallthruop));
02497     
02498     RemoveLiveAttribute (cmergefallthruop, proc);  // kill live attribute right off
02499     
02500     atl = cmergefallthruop->GetOpAttrListPtr();
02501     while (atl != NULL)
02502       {
02503         atype = atl->GetAttrType();
02504         if (atype != ATTR_LC)
02505           {
02506             atl = atl->GetNextListPtr(); continue;  // skip to first lc
02507           } // end if
02508         
02509         // Remove the first attribute here.
02510         a = atl->GetAttrPtr();
02511         RemoveLcAttribute (a->GetAttrString(), cmergefallthruop, proc);
02512         
02513         atl = cmergefallthruop->GetOpAttrListPtr();  // reset for next scan
02514       } // end while
02515     delete cmergefallthruop;
02516   }
02517   
02518   // 2c. Move ops from branchop region to hyp. At the end,
02519   //     destroy the edge leading to FallThru Block.
02520   // Remove branchop in BranchBlock and C_MERGEs in 
02521   // TakenBlock and FallThruBlock
02522   if (makingnewHB) {
02523     for (FirstItem = (legoOp *) BranchBlock->GetItem(0); 
02524          FirstItem->GetPrevLink() != NULL;
02525          FirstItem = FirstItem->GetPrevLink())
02526       ; // do nothing
02527     for (NextItem = FirstItem; NextItem != NULL; ) {
02528       ThisItem = NextItem; 
02529       NextItem = NextItem->GetNextLink();
02530       AddWeightAttribute (ThisItem);
02531       dprintf((OUTF,"IfConvertTreeBranch: moving op %d from BranchBlock.\n",
02532                ThisItem->GetOpId()));
02533       BranchBlock->Detach(BranchBlock->Search(ThisItem));
02534       hyp->AddItem(ThisItem);
02535       ThisItem->SetParentBlockPtr (hyp);
02536       // Add/Update PredVector
02537       if (ThisItem->GetPredVectorPtr() == NULL) { 
02538         ThisItem->SetPredVectorPtr(new bitvector(*new_true_vector));
02539       }
02540       else {
02541         ThisItem->SetPredVectorPtr(MultiplyBitsMask(ThisItem->GetPredVectorPtr(), mask_vector, Branch_size, (Taken_size + FallThru_size), PredVectorSize));
02542       }
02543       dderr ("OpId = " << ThisItem->GetOpId() << " (a BranchBlock op)\n");
02544     } // end for
02545     prevop = ThisItem;
02546   }
02547   
02548   // 2d. Move ops from Taken Block to hyp, predicating them on Tpredicate.
02549   if (TakenBlockInTree == TRUE) {
02550     for (FirstItem = (legoOp *) TakenBlock->GetItem(0); 
02551          FirstItem->GetPrevLink() != NULL;
02552          FirstItem = FirstItem->GetPrevLink())
02553       ; // do nothing
02554     for (NextItem = FirstItem, i = 0; NextItem != NULL; i++) {
02555       ThisItem = NextItem; 
02556       NextItem = NextItem->GetNextLink();
02557       AddWeightAttribute (ThisItem);
02558       TakenBlock->Detach(TakenBlock->Search(ThisItem));
02559       dprintf((OUTF,"IfConvertTreeBranch: moving op %d from Taken.\n",
02560                ThisItem->GetOpId()));
02561       hyp->AddItem(ThisItem);
02562       ThisItem->SetParentBlockPtr (hyp);
02563       
02564       if (i == 0) {
02565 //      if (AddCtrlEdge == TRUE) {
02566           AddCtrlEdgeTaken = TRUE; 
02567           takenfromop = prevop; 
02568           takentoop = ThisItem; 
02569 //        AddCtrlEdge = FALSE;
02570 //      }
02571         prevop->SetNextLink (ThisItem);
02572         ThisItem->SetPrevLink (prevop);
02573       } // end if
02574       
02575       oprd = ThisItem->GetPredOprdPtr();
02576       // mdj - 4/2/99
02577       // Only want to update TRUE predicates here. If the predicate is now 
02578       // non-TRUE, it was updated by a prior hammock conversion. Leaving 
02579       // these predicates alone while updating (predicating) the CMPP ops 
02580       // that create these predicates produces the correct predicate values
02581       int dont_change_pred = 0;
02582       if (oprd != NULL) {
02583         if (oprd->GetOprdType() != OT_LITERAL_P ||
02584             oprd->GetLiteralPredicate() != TRUE ) {
02585           dont_change_pred = 1;
02586         }
02587         else {
02588           delete oprd;
02589         }
02590       }
02591       if (!dont_change_pred) {
02592         oprd = new legoOprd (*Tpredicate);
02593         ThisItem->SetPredOprdPtr (oprd);
02594         oprd->SetParentOpPtr (ThisItem);
02595       }
02596       // Set PredVector and orig_tree_hb_id attribute
02597       if (ThisItem->GetPredVectorPtr() == NULL) { 
02598         ThisItem->SetPredVectorPtr(new bitvector(*new_taken_vector));
02599       }
02600       else {
02601         // Don't need to add zeros left for fallthru path
02602         ThisItem->SetPredVectorPtr(ReplicateBitsMask(ThisItem->GetPredVectorPtr(), mask_vector, Branch_size, (Taken_size + FallThru_size), PredVectorSize));
02603       }
02604       dderr ("OpId = " << ThisItem->GetOpId() << " (a TakenBlock op)\n");
02605 //      ThisItem->SetPredVectorPtr(new bitvector(*taken_vector));
02606 //      oprd = new legoOprd;
02607 //      oprd->SetOprdType (OT_LITERAL_I);
02608 //      oprd->SetLiteralInteger(hyp->GetRegionId());
02609 //      AddLcAttribute ("orig_tree_hb_id", oprd, ThisItem, proc);
02610     } // end for
02611     prevop = ThisItem;
02612   }  
02613   else {
02614     dderr ("adding TakenBRU op " << TakenBRU->GetOpId() << " to hyp. \n");
02615     dprintf((OUTF,"IfConvertTreeBranch: adding TakenBRU op %d to hyp.\n",
02616              TakenBRU->GetOpId()));
02617     hyp->AddItem(TakenBRU);
02618     TakenBRU->SetParentBlockPtr (hyp);
02619     
02620     prevop->SetNextLink (TakenBRU);
02621     TakenBRU->SetPrevLink (prevop);
02622     AddCtrlEdgeTakenPrev = TRUE; 
02623     takenprevfromop = prevop;
02624     takenprevtoop = TakenBRU;
02625     //AddEdge(prevop, TakenBRU, ET_CNTL);
02626     
02627     // When changing conditional branches to unconditional branches, 
02628     // we always want to update the predicate source (not just update 
02629     // for TRUE predicates as before).
02630     oprd = TakenBRU->GetPredOprdPtr();
02631     delete oprd;
02632     oprd = new legoOprd (*Tpredicate);
02633     TakenBRU->SetPredOprdPtr (oprd);
02634     oprd->SetParentOpPtr (TakenBRU);
02635     // Set PredVector and orig_tree_hb_id attribute
02636     TakenBRU->SetPredVectorPtr(new bitvector(*new_taken_vector));
02637     dderr ("OpId = " << TakenBRU->GetOpId() << " (TakenBRU op)\n");
02638 //    oprd = new legoOprd;
02639 //    oprd->SetOprdType (OT_LITERAL_I);
02640 //    oprd->SetLiteralInteger(hyp->GetRegionId());
02641 //    AddLcAttribute ("orig_tree_hb_id", oprd, TakenBRU, proc);
02642 
02643     prevop = TakenBRU;
02644 //    AddCtrlEdge = TRUE;
02645   }
02646   
02647   // 2e. Move ops from FallThru Block to hyp, predicating them on Fpredicate.
02648   if (FallThruBlockInTree == TRUE) {
02649     for (FirstItem = (legoOp *) FallThruBlock->GetItem(0); 
02650          FirstItem->GetPrevLink() != NULL;
02651          FirstItem = FirstItem->GetPrevLink())
02652       ; // do nothing
02653     for (NextItem = FirstItem, i = 0; NextItem != NULL; i++) {
02654       ThisItem = NextItem; 
02655       NextItem = NextItem->GetNextLink();
02656       AddWeightAttribute (ThisItem);
02657       FallThruBlock->Detach(FallThruBlock->Search(ThisItem));
02658       dprintf((OUTF,"IfConvertTreeBranch: moving op %d from FallThru.\n",
02659                ThisItem->GetOpId()));
02660       hyp->AddItem(ThisItem);
02661       ThisItem->SetParentBlockPtr (hyp);
02662       
02663       if (i == 0) {
02664 //      if (AddCtrlEdge == TRUE) {
02665           AddCtrlEdgeFallThru = TRUE; 
02666           fallthrufromop = prevop; 
02667           fallthrutoop = ThisItem; 
02668 //        AddCtrlEdge = FALSE;
02669 //      }
02670         prevop->SetNextLink (ThisItem);
02671         ThisItem->SetPrevLink (prevop);
02672       } // end if
02673       
02674       oprd = ThisItem->GetPredOprdPtr();
02675       // mdj - 4/2/99
02676       // Only want to update TRUE predicates here. If the predicate is now 
02677       // non-TRUE, it was updated by a prior hammock conversion. Leaving 
02678       // these predicates alone while updating (predicating) the CMPP ops 
02679       // that create these predicates produces the correct predicate values
02680       int dont_change_pred = 0;
02681       if (oprd != NULL) {
02682         if (oprd->GetOprdType() != OT_LITERAL_P ||
02683             oprd->GetLiteralPredicate() != TRUE ) {
02684           dont_change_pred = 1;
02685         }
02686         else {
02687           delete oprd;
02688         }
02689       }
02690       if (!dont_change_pred) {
02691         oprd = new legoOprd (*Fpredicate);
02692         ThisItem->SetPredOprdPtr (oprd);
02693         oprd->SetParentOpPtr (ThisItem);
02694       }
02695       // Set PredVector and orig_tree_hb_id attribute
02696       if (ThisItem->GetPredVectorPtr() == NULL) { 
02697         ThisItem->SetPredVectorPtr(new bitvector(*new_fallthru_vector));
02698       }
02699       else {
02700         // Add zeros right for additional taken paths
02701         AddZerosRight(ThisItem->GetPredVectorPtr(), FallThru_size, (Taken_size));
02702         ThisItem->SetPredVectorPtr(ReplicateBitsMask(ThisItem->GetPredVectorPtr(), mask_vector, Branch_size, (Taken_size + FallThru_size), PredVectorSize));
02703       }
02704       dderr ("OpId = " << ThisItem->GetOpId() << " (a FallThruBlock op)\n");
02705 //      ThisItem->SetPredVectorPtr(new bitvector(*fallthru_vector));
02706 //      oprd = new legoOprd;
02707 //      oprd->SetOprdType (OT_LITERAL_I);
02708 //      oprd->SetLiteralInteger(hyp->GetRegionId());
02709 //      AddLcAttribute ("orig_tree_hb_id", oprd, ThisItem, proc);
02710     } // end for
02711     prevop = ThisItem;
02712   }  
02713   else {
02714     dderr ("adding FallThruBRU op " << FallThruBRU->GetOpId() << " to hyp. \n");
02715     dderr ("also adding FallThruPBRR op " << FallThruPBRR->GetOpId() << " to hyp. \n");
02716     dprintf((OUTF,"IfConvertTreeBranch: adding FallThruBRU op %d to hyp.\n",
02717              FallThruBRU->GetOpId()));
02718 
02719     hyp->AddItem(FallThruPBRR);
02720     FallThruPBRR->SetParentBlockPtr (hyp);
02721     
02722     prevop->SetNextLink (FallThruPBRR);
02723     FallThruPBRR->SetPrevLink (prevop);
02724     AddCtrlEdgeFallThruPrev = TRUE;
02725     fallthruprevfromop = prevop;
02726     fallthruprevtoop = FallThruPBRR;
02727     //AddEdge(prevop, FallThruPBRR, ET_CNTL);
02728     
02729     // When changing conditional branches to unconditional branches, 
02730     // we always want to update the predicate source (not just update 
02731     // for TRUE predicates as before).
02732     oprd = FallThruPBRR->GetPredOprdPtr();
02733     delete oprd;
02734     oprd = new legoOprd (*Fpredicate);
02735     FallThruPBRR->SetPredOprdPtr (oprd);
02736     oprd->SetParentOpPtr (FallThruPBRR);
02737     // Set PredVector and orig_tree_hb_id attribute
02738     FallThruPBRR->SetPredVectorPtr(new bitvector(*new_fallthru_vector));
02739     dderr ("OpId = " << FallThruPBRR->GetOpId() << " (FallThruPBRR op)\n");
02740 //    oprd = new legoOprd;
02741 //    oprd->SetOprdType (OT_LITERAL_I);
02742 //    oprd->SetLiteralInteger(hyp->GetRegionId());
02743 //    AddLcAttribute ("orig_tree_hb_id", oprd, FallThruPBRR, proc);
02744 
02745     hyp->AddItem(FallThruBRU);
02746     FallThruBRU->SetParentBlockPtr (hyp);
02747     
02748     FallThruPBRR->SetNextLink (FallThruBRU);
02749     FallThruBRU->SetPrevLink (FallThruPBRR);
02750     AddCtrlEdgeFallThruPBRR = TRUE;
02751     fallthrupbrrfromop = FallThruPBRR;
02752     fallthrupbrrtoop = FallThruBRU;
02753     //AddEdge(prevop, FallThruBRU, ET_CNTL);
02754     
02755     // When changing conditional branches to unconditional branches, 
02756     // we always want to update the predicate source (not just update 
02757     // for TRUE predicates as before).
02758     oprd = FallThruBRU->GetPredOprdPtr();
02759     delete oprd;
02760     oprd = new legoOprd (*Fpredicate);
02761     FallThruBRU->SetPredOprdPtr (oprd);
02762     oprd->SetParentOpPtr (FallThruBRU);
02763     // Set PredVector and orig_tree_hb_id attribute
02764     FallThruBRU->SetPredVectorPtr(new bitvector(*new_fallthru_vector));
02765     dderr ("OpId = " << FallThruBRU->GetOpId() << " (FallThruBRU op)\n");
02766 //    oprd = new legoOprd;
02767 //    oprd->SetOprdType (OT_LITERAL_I);
02768 //    oprd->SetLiteralInteger(hyp->GetRegionId());
02769 //    AddLcAttribute ("orig_tree_hb_id", oprd, FallThruBRU, proc);
02770 
02771     prevop = FallThruBRU;
02772 //    AddCtrlEdge = TRUE;
02773   }
02774 
02775   // 2f. May need to fix an edge if blocks were added to an existing hyperblock
02776   if (!makingnewHB && (fixlinkop != NULL)) {
02777 //    if (AddCtrlEdge == TRUE) {
02778       AddCtrlEdgeFix = TRUE; 
02779       fixfromop = prevop; 
02780       fixtoop = fixlinkop; 
02781 //      AddCtrlEdge = FALSE;
02782 //    }
02783     prevop->SetNextLink (fixlinkop);
02784     fixlinkop->SetPrevLink (prevop);    
02785   }
02786   
02787   // 2g. Remove BranchBlock, TakenBlock, and FallThruBlock, and insert hyp.
02788   region = BranchBlock->GetParentPtr();
02789   if (region == NULL) {
02790     dprintf((OUTF,"IfConvertTreeBranch: can't find parent of BranchBlock.\n"));
02791     return NULL;
02792   } // end if (for)
02793   if (makingnewHB) {
02794     i = region->Search (BranchBlock);
02795     // Get rid of attributes before destroying BranchBlock
02796     RemoveLiveAttribute (BranchBlock, proc); 
02797     atl = BranchBlock->GetRegionAttrListPtr();
02798     while (atl != NULL)
02799       {
02800         atype = atl->GetAttrType();
02801         if (atype != ATTR_LC)
02802           {
02803             atl = atl->GetNextListPtr(); continue;  // skip to first lc
02804           } // end if
02805         
02806         // Remove the first attribute here.
02807         a = atl->GetAttrPtr();
02808         RemoveLcAttribute (a->GetAttrString(), BranchBlock, proc);
02809         
02810         atl = BranchBlock->GetRegionAttrListPtr();  // reset for next scan
02811       } // end while
02812     if (i == MAX_UNSIGNED) {
02813       LegoNonFatal ("IfConvertTreeBranch", "Can't find BranchBlock %d in its "
02814                     "parent region %d.", BranchBlock->GetRegionId(),
02815                     region->GetRegionId());
02816       return NULL;
02817     } // end if
02818     if (BranchBlock == tree->GetRoot())
02819       tree->SetRoot(hyp);
02820     // Destroying BranchBlock, TakenBlock, FallThruBlock blocks seems to fuck 
02821     // up things such as ParentBlockPtrs of Ops. So I will 
02822     // just leave them as orphaned blocks now and mark them. 
02823     // Will skip them later
02824 //    BranchBlock->Mark (RM_GENERAL);
02825     region->DestroyItem (i);
02826 //    region->Insert (hyp, i);
02827     region->AddItem (hyp);
02828     hyp->SetParentPtr (region);
02829 //    if (!(region->IsOwner())) delete BranchBlock;
02830   } // end if
02831 
02832   // Add required ctrl edges now that hyp belongs to proc 
02833   if (AddCtrlEdgeTakenPrev == TRUE) {
02834     AddEdge(takenprevfromop, takenprevtoop, ET_CNTL);
02835     AddCtrlEdgeTakenPrev = FALSE; 
02836   }
02837   if (AddCtrlEdgeTaken == TRUE) {
02838     AddEdge(takenfromop, takentoop, ET_CNTL);
02839     AddCtrlEdgeTaken = FALSE; 
02840   }
02841   if (AddCtrlEdgeFallThruPrev == TRUE) {
02842     AddEdge(fallthruprevfromop, fallthruprevtoop, ET_CNTL);
02843     AddCtrlEdgeFallThruPrev = FALSE; 
02844   }
02845   if (AddCtrlEdgeFallThruPBRR == TRUE) {
02846     AddEdge(fallthrupbrrfromop, fallthrupbrrtoop, ET_CNTL);
02847     AddCtrlEdgeFallThruPBRR = FALSE; 
02848   }
02849   if (AddCtrlEdgeFallThru == TRUE) {
02850     AddEdge(fallthrufromop, fallthrutoop, ET_CNTL);
02851     AddCtrlEdgeFallThru = FALSE; 
02852   }
02853   if (AddCtrlEdgeFix == TRUE) {
02854     AddEdge(fixfromop, fixtoop, ET_CNTL);
02855     AddCtrlEdgeFix = FALSE; 
02856   }
02857 
02858   if (TakenBlockInTree == TRUE) {
02859     region = TakenBlock->GetParentPtr();
02860     if (region == NULL) {
02861       LegoNonFatal ("IfConvertTreeBranch", "Can't find parent of TakenBlock %d.",
02862                     TakenBlock->GetRegionId());
02863       return NULL;
02864     } // end if (for)
02865     i = region->Search (TakenBlock);
02866     // Get rid of attributes before destroying TakenBlock
02867     RemoveLiveAttribute (TakenBlock, proc); 
02868     atl = TakenBlock->GetRegionAttrListPtr();
02869     while (atl != NULL)
02870       {
02871         atype = atl->GetAttrType();
02872         if (atype != ATTR_LC)
02873           {
02874             atl = atl->GetNextListPtr(); continue;  // skip to first lc
02875           } // end if
02876         
02877         // Remove the first attribute here.
02878         a = atl->GetAttrPtr();
02879         RemoveLcAttribute (a->GetAttrString(), TakenBlock, proc);
02880         
02881         atl = TakenBlock->GetRegionAttrListPtr();  // reset for next scan
02882       } // end while
02883     if (i == MAX_UNSIGNED) {
02884       LegoNonFatal ("IfConvertTreeBranch", "Can't find TakenBlock %d in its "
02885                     "parent region %d.", TakenBlock->GetRegionId(),
02886                     region->GetRegionId());
02887       return NULL;
02888     } // end if
02889     // Destroying BranchBlock, TakenBlock, FallThruBlock blocks seems to fuck 
02890     // up things such as ParentBlockPtrs of Ops. So I will 
02891     // just leave them as orphaned blocks now and mark them. 
02892     // Will skip them later
02893 //    TakenBlock->Mark (RM_GENERAL);
02894     region->DestroyItem (i);
02895 //    if (!(region->IsOwner())) delete TakenBlock;
02896   }
02897   
02898   if (FallThruBlockInTree == TRUE) {
02899     region = FallThruBlock->GetParentPtr();
02900     if (region == NULL) {
02901       LegoNonFatal ("IfConvertTreeBranch", "Can't find parent of FallThruBlock %d.",
02902                     FallThruBlock->GetRegionId());
02903       return NULL;
02904     } // end if (for)
02905     i = region->Search (FallThruBlock);
02906     // Get rid of attributes before destroying FallThruBlock
02907     RemoveLiveAttribute (FallThruBlock, proc); 
02908     atl = FallThruBlock->GetRegionAttrListPtr();
02909     while (atl != NULL)
02910       {
02911         atype = atl->GetAttrType();
02912         if (atype != ATTR_LC)
02913           {
02914             atl = atl->GetNextListPtr(); continue;  // skip to first lc
02915           } // end if
02916         
02917         // Remove the first attribute here.
02918         a = atl->GetAttrPtr();
02919         RemoveLcAttribute (a->GetAttrString(), FallThruBlock, proc);
02920         
02921         atl = FallThruBlock->GetRegionAttrListPtr();  // reset for next scan
02922       } // end while
02923     if (i == MAX_UNSIGNED) {
02924       LegoNonFatal ("IfConvertTreeBranch", "Can't find FallThruBlock %d in its "
02925                     "parent region %d.", FallThruBlock->GetRegionId(),
02926                     region->GetRegionId());
02927       return NULL;
02928     } // end if
02929     // Destroying BranchBlock, TakenBlock, FallThruBlock blocks seems to fuck 
02930     // up things such as ParentBlockPtrs of Ops. So I will 
02931     // just leave them as orphaned blocks now and mark them. 
02932     // Will skip them later
02933 //    FallThruBlock->Mark (RM_GENERAL);
02934     region->DestroyItem (i);
02935 //    if (!(region->IsOwner())) delete FallThruBlock;
02936   }
02937   
02938   // 2h. Refresh the ops/edges 
02939   ((legoHB *)hyp)->RefreshOps(); 
02940   ((legoHB *)hyp)->RefreshEdges(); 
02941   // Refresh tree regardless 
02942 //  tree->RefreshAll(); 
02943   ((legoTreegion *)tree)->RefreshOps();
02944   ((legoTreegion *)tree)->RefreshEdges();
02945   if ((TakenBlockInTree == FALSE) &&
02946       (TakenBlock != BranchBlock)) {
02947 //    TakenBlock->RefreshOpsAndEdges();
02948     switch (TakenBlock->GetRegionType())
02949       {
02950       case RT_BB:
02951         ((legoBB *) TakenBlock)->RefreshOps(); 
02952         ((legoBB *) TakenBlock)->RefreshEdges(); 
02953         break;
02954       case RT_SB:
02955         ((legoSB *) TakenBlock)->RefreshOps(); 
02956         ((legoSB *) TakenBlock)->RefreshEdges(); 
02957         break;
02958       case RT_HB:
02959         ((legoHB *) TakenBlock)->RefreshOps(); 
02960         ((legoHB *) TakenBlock)->RefreshEdges(); 
02961         break;
02962       default:
02963         LegoFatal ("IfConvertTree", "Can not determine RegionType");
02964       } // end switch
02965     // Should Refresh Parent if TakenBlock already belongs to another Treeion
02966     if (((legoRegion *)TakenBlock->GetParentPtr())->GetRegionType() 
02967         == RT_TREE) {
02968       ((legoTreegion *)TakenBlock->GetParentPtr())->RefreshEntryOps();
02969       ((legoTreegion *)TakenBlock->GetParentPtr())->RefreshEntryEdges();
02970     }
02971   }
02972   if ((FallThruBlockInTree == FALSE) &&
02973       (FallThruBlock != BranchBlock)) {
02974 //    FallThruBlock->RefreshOpsAndEdges();
02975     switch (FallThruBlock->GetRegionType())
02976       {
02977       case RT_BB:
02978         ((legoBB *) FallThruBlock)->RefreshOps(); 
02979         ((legoBB *) FallThruBlock)->RefreshEdges(); 
02980         break;
02981       case RT_SB:
02982         ((legoSB *) FallThruBlock)->RefreshOps(); 
02983         ((legoSB *) FallThruBlock)->RefreshEdges(); 
02984         break;
02985       case RT_HB:
02986         ((legoHB *) FallThruBlock)->RefreshOps(); 
02987         ((legoHB *) FallThruBlock)->RefreshEdges(); 
02988         break;
02989       default:
02990         LegoFatal ("IfConvertTree", "Can not determine RegionType");
02991       } // end switch
02992     // Should Refresh Parent if FallThruBlock already belongs to another Treeion
02993     if (((legoRegion *)FallThruBlock->GetParentPtr())->GetRegionType() 
02994         == RT_TREE) {
02995       ((legoTreegion *)FallThruBlock->GetParentPtr())->RefreshEntryOps();
02996       ((legoTreegion *)FallThruBlock->GetParentPtr())->RefreshEntryEdges();
02997     }
02998   }
02999 //  if (TreegionExit) {
03000 //    tree->RefreshOpsAndEdges();
03001 //  }
03002 
03003   delete Tpredicate;
03004   delete Fpredicate;
03005   delete new_true_vector;
03006   delete new_taken_vector;
03007   delete new_fallthru_vector; 
03008   delete mask_vector; 
03009 
03010   return return_prev_op;
03011 } // end IfConvertTreeBranch
03012 
03013 
03014 
03015 void PredicateTreeBranch (legoOp *branchop) 
03016 {
03017 
03018   legoOp *predicate_op, *op; 
03019   legoOprd *predicate_oprd; 
03020   legoTreegion *tree;
03021   legoOprd *p1, *p2, *pX, *pTaken = NULL, *pFallThru = NULL;
03022   legoOprd *btroprd, *cmppoprd, *def, *use, *oprd;
03023   oprdList *defs, *uses;
03024   legoRegion *TakenBlock, *FallThruBlock; 
03025   legoOp *pbrrop, *cmppop;
03026   legoOp *duplicatecmppop; 
03027   attrs *attrdictionary, *attrtail, *atscan;
03028   attrList *atlscan;
03029   int eaid, count_uses, isBRCT, PBRRblock;
03030   int TreegionExit, TakenBlockInTree, FallThruBlockInTree;
03031   opList *oplist; 
03032   legoOprd *Tpredicate, *Fpredicate;
03033   legoProc *proc; 
03034 
03035 
03036   // Determine if branch is a Treegion exit
03037   tree = (legoTreegion *) FindParentRegionType(RT_TREE, branchop);
03038   if (tree == NULL) return; 
03039   TreegionExit = FALSE;
03040   for (oplist = tree->GetExitOpsPtr();
03041        oplist != NULL;
03042        oplist = oplist->GetNextListPtr()) {
03043     if ((op = oplist->GetOpPtr()) != NULL) 
03044       if (op == branchop) {
03045         TreegionExit = TRUE;
03046         break; 
03047       }
03048   }
03049 
03050   // Make sure that branch is a BRCT or BRCF op
03051   //if (branchop->IsBRCTOp())
03052   if(branchop->GetOpcode() == BRCT)
03053   {
03054       LegoNonFatal("IfConvertHammock", "BRCF is not supported yet.");      
03055     isBRCT = 1;
03056   }
03057   //else if (branchop->IsBRCFOp())
03058   else if(branchop->GetOpcode() == BRCF)
03059   {
03060       LegoNonFatal("IfConvertHammock", "BRCF is not supported yet.");
03061     isBRCT = 0;
03062   }
03063   else 
03064     return; 
03065 
03066   // Make sure that the branch has only two exit ops
03067   oplist = branchop->GetOutListPtr();
03068   if (oplist == NULL || oplist->GetNextListPtr() == NULL ||
03069       oplist->GetNextListPtr()->GetNextListPtr() != NULL)
03070     return;
03071   
03072   if (Chains == NULL) {
03073     LegoNonFatal ("PredicateTreeBranch", "Chains is NULL: call ReachingDefinitions().");
03074     return;
03075   } // end if
03076 
03077   // 1b. Find the target of the branch.
03078   btroprd = branchop->GetSrcOprdPtr(); // should be 1st source
03079   pbrrop = NULL;
03080   for (defs = Chains->GetUDChains()->Lookup (btroprd);
03081        (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
03082        defs = defs->GetNextListPtr()) {
03083     def = defs->GetOprdPtr();
03084     pbrrop = def->GetParentOpPtr(); // only one PBRR op should reach
03085     break; 
03086   }
03087 
03088   dderr ("pbrrop OpId is: " << pbrrop->GetOpId() << "\n");
03089   dderr ("branchop OpId is: " << branchop->GetOpId() << "\n");
03090   
03091   if (pbrrop == NULL) {
03092     LegoNonFatal ("PredicateTreeBranch", "Can't find PBRR/PBRA in block.");
03093     return;
03094   } // end if
03095 
03096   oprd = pbrrop->GetSrcOprdPtr();
03097   if (oprd->GetOprdType() != OT_LITERAL_CB) {
03098     LegoNonFatal ("PredicateTreeBranch", "PBRR %d not to control block.",
03099                   pbrrop->GetOpId());
03100     return;
03101   } // end if
03102   
03103   // Find the Taken and FallThru Blocks 
03104   PBRRblock = oprd->GetLiteralControlBlock();
03105   oplist = branchop->GetOutListPtr();
03106   if (((legoRegion *) oplist->GetOpPtr()->GetParentBlockPtr())
03107       ->GetRegionId() ==  PBRRblock) {
03108     dderr ("oplist Valid = " << oplist->GetValid() << "\n");
03109     TakenBlock = (legoRegion *) oplist->GetOpPtr()->GetParentBlockPtr();
03110     dderr ("oplist Valid = " << oplist->GetNextListPtr()->GetValid() << "\n");
03111     FallThruBlock = (legoRegion *) oplist->GetNextListPtr()->GetOpPtr()->GetParentBlockPtr();
03112   }
03113   else if (((legoRegion *) oplist->GetNextListPtr()->GetOpPtr()
03114             ->GetParentBlockPtr())->GetRegionId() ==  PBRRblock) {
03115     dderr ("oplist Valid = " << oplist->GetValid() << "\n");
03116     FallThruBlock = (legoRegion *) oplist->GetOpPtr()->GetParentBlockPtr();
03117     dderr ("oplist Valid = " << oplist->GetNextListPtr()->GetValid() << "\n");
03118     TakenBlock = (legoRegion *) oplist->GetNextListPtr()->GetOpPtr()->GetParentBlockPtr();
03119   }
03120   else {
03121     LegoNonFatal ("PredicateTreeBranch", "Could not determine TakenBlock and FallThruBlock in block");
03122     return;
03123   } // end if
03124 
03125   dderr ("TakenBlock Id is: " << TakenBlock->GetRegionId() << "\n");  
03126   dderr ("FallThruBlock Id is: " << FallThruBlock->GetRegionId() << "\n");  
03127   
03128   // If TreegionExit == TRUE, determine if TakenBlock and FallThruBlock are 
03129   // within the Treegion (but not a loop back to Root)
03130   TakenBlockInTree = TRUE;
03131   FallThruBlockInTree = TRUE;
03132   if (TreegionExit == TRUE) {
03133     if ((tree != 
03134         ((legoTreegion *) FindParentRegionType(RT_TREE, TakenBlock))) ||
03135         (TakenBlock == tree->GetRoot())) {
03136       TakenBlockInTree = FALSE;
03137     }
03138     if ((tree != 
03139         ((legoTreegion *) FindParentRegionType(RT_TREE, FallThruBlock))) ||
03140         (FallThruBlock == tree->GetRoot())) {
03141       FallThruBlockInTree = FALSE;
03142     }
03143   }
03144 
03145   if ((TakenBlockInTree == FALSE) && (FallThruBlockInTree == FALSE)) 
03146     return; // Nothing to predicate in tree
03147 
03148   // Find the procedure
03149   proc = (legoProc *) FindParentRegionType(RT_PROC, branchop);
03150   if (proc == NULL) {
03151     dprintf((OUTF,"PredicateTreeBranch: can't find proc!\n"));
03152     return;    
03153   }
03154   
03155   // 1c. Find the predicate operands that are the destination of the CMPP.
03156   //     Put the first in p1, the second in p2. If the second isn't there, 
03157   //     take care of it.
03158   cmppoprd = branchop->GetSrcOprdPtr()->GetNextOprdPtr(); // 2nd source
03159   cmppop = NULL;
03160   for (defs = Chains->GetUDChains()->Lookup (cmppoprd);
03161        (defs != NULL) && (Chains->GetUDChains()->NotFound() == FALSE);
03162        defs = defs->GetNextListPtr()) {
03163     def = defs->GetOprdPtr();
03164     cmppop = def->GetParentOpPtr(); // only one CMPP op should reach
03165     break; 
03166   }
03167   
03168   dderr ("cmppop OpId is: " << cmppop->GetOpId() << "\n");
03169 
03170   if (cmppop == NULL) {
03171     LegoNonFatal ("PredicateTreeBranch", "Can't find CMPP for branch");
03172     return;
03173   } // end if
03174 
03175   if (cmppop->IsCMPPOp()) {
03176     LegoNonFatal ("PredicateTreeBranch", "Can't find CMPP for branch.");
03177     return;
03178   } // end if
03179 
03180   // make sure that the second D-action is a complement (odd-number opcode)
03181   div_t remainder = div(cmppop->GetOpcode(), 2);
03182   if (remainder.rem == 0) {
03183     cmppop->SetOpcode((cmppop->GetOpcode() + 1));
03184   }
03185   
03186   p1 = cmppop->GetDestOprdPtr();  // first destination!
03187   if (p1 == NULL || p1->GetNextOprdPtr() == NULL)
03188     {
03189       LegoNonFatal ("PredicateTreeBranch", "CMPP %d has bad destinations.",
03190                     cmppop->GetOpId());
03191       return;
03192     } // end if
03193   p2 = p1->GetNextOprdPtr();  // p2 is there always!
03194   if (p1->GetNextOprdPtr()->GetOprdType() != OT_UNDEFINED)
03195     /* do nothing - we have two predicates! */;
03196   else {   // Nuts, there's no second destination. 
03197     // We need a second destination. Scan through
03198     // every op in the proc to find the next predicate register that's
03199     // free.
03200     if (NextPredRegNum == 0) {  // find it
03201       legoOp *o;
03202       legoOprd *d;
03203       for (o = proc->GetListOpPtr(); o != NULL; o = o->GetListOpPtr()) {
03204         for (d = o->GetSrcOprdPtr(); d != NULL; d = d->GetNextOprdPtr())
03205           if (d->GetOprdType() == OT_REG &&
03206               //                    (d->GetOprdDataType() == DT_P ||
03207               //                     d->GetOprdFileType() == FT_PR) &&
03208               d->GetOprdRegNum() > NextPredRegNum)
03209             NextPredRegNum = d->GetOprdRegNum();
03210         
03211         for (d = o->GetDestOprdPtr(); d != NULL; d = d->GetNextOprdPtr())
03212           if (d->GetOprdType() == OT_REG &&
03213               //                    (d->GetOprdDataType() == DT_P ||
03214               //                     d->GetOprdFileType() == FT_PR) &&
03215               d->GetOprdRegNum() > NextPredRegNum)
03216             NextPredRegNum = d->GetOprdRegNum();
03217         
03218         for (d = o->GetPredOprdPtr(); d != NULL; d = d->GetNextOprdPtr())
03219           if (d->GetOprdType() == OT_REG &&
03220               //                    (d->GetOprdDataType() == DT_P ||
03221               //                     d->GetOprdFileType() == FT_PR) &&
03222               d->GetOprdRegNum() > NextPredRegNum)
03223             NextPredRegNum = d->GetOprdRegNum();
03224       } // end for
03225       
03226       NextPredRegNum++;  // next available one
03227       dprintf((OUTF, "PredicateTreeBranch: NextPredRegNum = %d\n",
03228                NextPredRegNum));
03229     } // end if
03230     
03231     // For hyperblocks, need to make sure that all predicates start out 
03232     // unique, so I will also refresh p1's number. With the lack of control
03233     // flow within a hyperblock control flow out can get confused when more 
03234     // than one CMPP uses the same prednumb (especially after scheduling). 
03235     // TailDuplication of CMPPs is a source for this problem. Once again, 
03236     // learned this one the hard way. 
03237 
03238     // If p1 reaches more than one branch (possible if merged due to dominator
03239     // parallelism) copy construct a new CMPP
03240     for (count_uses = 0, uses = Chains->GetDUChains()->Lookup (p1);
03241          (uses != NULL) && (Chains->GetDUChains()->NotFound() == FALSE);
03242          count_uses++, uses = uses->GetNextListPtr()) 
03243       use = uses->GetOprdPtr();  // just count uses
03244     if (count_uses > 1) { // more than one use found, copy construct CMPP
03245   // should update RDefs somewhere around here so that I do not need to 
03246   // copy construct CMPPs that now only reach one use.
03247       dderr ("*** This part has not been debugged yet *** count = " << count_uses << "\n");
03248       duplicatecmppop = new legoOp(*cmppop);
03249       duplicatecmppop->SetOpId(FindMaxOpId((legoProc *) proc)->GetOpId() + 1);
03250       // Duplicate op attributes.
03251       attrdictionary = proc->GetAttrDictionary();
03252       for (attrtail = attrdictionary; attrtail->GetNextAttrPtr() != NULL;
03253            attrtail = attrtail->GetNextAttrPtr()) /* do nothing */;
03254       eaid = FindMaxEdgeAttrId (proc);
03255       for (atlscan = duplicatecmppop->GetOpAttrListPtr(); atlscan != NULL;
03256            atlscan = atlscan->GetNextListPtr())
03257         {
03258           if (atlscan->GetAttrPtr() == NULL)
03259             continue;
03260           atscan = new attrs (*(atlscan->GetAttrPtr()), duplicatecmppop, ++eaid);
03261           atlscan->SetAttrPtr (atscan);
03262           atscan->SetAttrId (eaid);
03263           atlscan->SetAttrId (eaid);
03264           attrtail->SetNextAttrPtr (atscan);
03265           attrtail = attrtail->GetNextAttrPtr();
03266         } // end for
03267       // make sure to copy the hammockPredVector
03268       if (cmppop->GetPredVectorPtr() != NULL) {
03269         duplicatecmppop->SetPredVectorPtr(new bitvector(*cmppop->GetPredVectorPtr()));
03270       }
03271       
03272       p1 = duplicatecmppop->GetDestOprdPtr();  // first destination!
03273       if (p1 == NULL || p1->GetNextOprdPtr() == NULL)
03274         {
03275           LegoNonFatal ("PredicateTreeBranch", "duplicatecmppop %d has bad destinations.",
03276                         duplicatecmppop->GetOpId());
03277           return;
03278         } // end if
03279       AddMidOp (duplicatecmppop, cmppop);
03280       p2 = p1->GetNextOprdPtr();  // p2 is there always!
03281       p1->SetOprdRegNum (NextPredRegNum);
03282       // Need the same new number for the branch that this reaches
03283       branchop->GetSrcOprdPtr()->GetNextOprdPtr()->SetOprdRegNum(NextPredRegNum++);
03284     }
03285     else { // just rename p1 and the branchop that it should reach
03286       dderr ("A-OK: count = " << count_uses << "\n");
03287       dderr ("branchopId = " << branchop->GetOpId() << "\n");
03288       dderr ("UseOpId = " << use->GetParentOpPtr()->GetOpId() << "\n");
03289       p1->SetOprdRegNum (NextPredRegNum);
03290       // Need the same new number for the branch that this reaches
03291       branchop->GetSrcOprdPtr()->GetNextOprdPtr()->SetOprdRegNum(NextPredRegNum++);
03292     }
03293     
03294     // Make the new operand and plop it into the CMPP.
03295     p2->SetOprdType (p1->GetOprdType());
03296     p2->SetOprdRegNum (NextPredRegNum++);
03297     p2->SetOprdRegType (p1->GetOprdRegType());
03298     p2->SetOprdDataType (p1->GetOprdDataType());
03299     p2->SetOprdFileType (p1->GetOprdFileType());
03300     p2->SetOprdOmega (p1->GetOprdOmega());
03301     p2->SetOprdRegStyle (p1->GetOprdRegStyle());
03302     p2->SetIntValue (p1->GetOprdIntValue());
03303   } // end else
03304 
03305   // 1d. Figure out pTaken and pFallThru, the predicates for the 
03306   //     Taken Block and FallThru Block
03307   //          |       branch to Taken        |
03308   //          |                              |
03309   //  BRCT pX | pTaken = pX, pFallThru = !pX | 
03310   //          |                              |
03311   //  BRCF pX | pTaken = !pX, pFallThru = pX | 
03312 
03313   pX = branchop->GetSrcOprdPtr()->GetNextOprdPtr();
03314   if (pX->GetOprdRegNum() == p1->GetOprdRegNum())
03315     pX = p1;  // point pX to p1
03316   else
03317     pX = p2;  // point pX to p2
03318   
03319   if (isBRCT)    {
03320     pTaken = pX;
03321     pFallThru = (pTaken == p1 ? p2 : p1);
03322   } // end if
03323   else {
03324     pFallThru = pX;
03325     pTaken = (pFallThru == p1 ? p2 : p1);
03326   } // end else
03327   
03328   // 2a. Make new prototype predicate legoOprds based on pTaken and pFallThru
03329   Tpredicate = MakeDupPred (pTaken);
03330   Fpredicate = MakeDupPred (pFallThru);
03331 
03332   // Predicate ops in TakenBlock
03333   if (TakenBlockInTree == TRUE) {
03334     for (predicate_op = TakenBlock->GetEntryOpsPtr()->GetOpPtr();
03335          predicate_op != NULL;
03336          predicate_op = predicate_op->GetNextLink()) {
03337       
03338       // Don't bother with C_MERGES and branches other than BRLs
03339       if (predicate_op->IsCMERGEOp()) {
03340         continue; 
03341       }
03342       if (IsBranchOpButNotBRL(predicate_op)) {
03343         continue; 
03344       }
03345       
03346       // If already predicated, leave alone (assume already fully resolved)
03347       predicate_oprd = predicate_op->GetPredOprdPtr();
03348       int dont_change_pred = 0;
03349       if (predicate_oprd != NULL) {
03350         if (predicate_oprd->GetOprdType() != OT_LITERAL_P ||
03351             predicate_oprd->GetLiteralPredicate() != TRUE ) {
03352           dont_change_pred = 1;
03353         }
03354         else {
03355           delete predicate_oprd;
03356         }
03357       }
03358       if (!dont_change_pred) {
03359         predicate_oprd = new legoOprd (*Tpredicate);
03360         predicate_op->SetPredOprdPtr (predicate_oprd);
03361         predicate_oprd->SetParentOpPtr (predicate_op);
03362       }
03363     }
03364   }
03365 
03366   // Predicate ops in TallThruBlock
03367   if (FallThruBlockInTree == TRUE) {
03368     for (predicate_op = FallThruBlock->GetEntryOpsPtr()->GetOpPtr();
03369          predicate_op != NULL;
03370          predicate_op = predicate_op->GetNextLink()) {
03371       
03372       // Don't bother with C_MERGES and branches other than BRLs
03373       if (predicate_op->IsCMERGEOp()) {
03374         continue; 
03375       }
03376       if (IsBranchOpButNotBRL(predicate_op)) {
03377         continue; 
03378       }
03379       
03380       // If already predicated, leave alone (assume already fully resolved)
03381       predicate_oprd = predicate_op->GetPredOprdPtr();
03382       int dont_change_pred = 0;
03383       if (predicate_oprd != NULL) {
03384         if (predicate_oprd->GetOprdType() != OT_LITERAL_P ||
03385             predicate_oprd->GetLiteralPredicate() != TRUE ) {
03386           dont_change_pred = 1;
03387         }
03388         else {
03389           delete predicate_oprd;
03390         }
03391       }
03392       if (!dont_change_pred) {
03393         predicate_oprd = new legoOprd (*Fpredicate);
03394         predicate_op->SetPredOprdPtr (predicate_oprd);
03395         predicate_oprd->SetParentOpPtr (predicate_op);
03396       }
03397     }
03398   }
03399 
03400   delete Tpredicate;
03401   delete Fpredicate;
03402 
03403 }
03404 
03405 
03406 /*
03407  * IfConvertAndPredicateTreeBranch
03408  *
03409  * Calls IfConvertTreeBranch(legoOp *) or PredicateTreeBranch(legoOp *) 
03410  * for each branch in a Region
03411  *
03412  */
03413 void IfConvertAndPredicateTreeBranch (legoRegion *region, knobs *K)
03414 {
03415   legoRegion *childregion, *newregion;
03416   regionList *rl;
03417   legoOp *op, *entryop, *findblockop; 
03418   attrs *a;
03419   int mapping; 
03420   float accuracy; 
03421   int redoregion;
03422 
03423   region->Mark (RM_GENERAL);
03424   entryop = region->GetEntryOpsPtr()->GetOpPtr();
03425   redoregion = FALSE;
03426 
03427   for (op = entryop; 
03428        op != NULL;
03429        op = op->GetNextLink()) {
03430     if (op->IsBRCONDOp()) {
03431       if ( (a = FindLcAttribute( "branch_acc", op )) != NULL ) 
03432         accuracy = a->GetAttrOprdPtr()->GetLiteralFloat();
03433       else 
03434         accuracy = -1;
03435       if ( (a = FindLcAttribute( "branch_mapping", op )) != NULL ) 
03436         mapping = a->GetAttrOprdPtr()->GetLiteralInteger();
03437       else 
03438         mapping = -1;
03439       dderr ("branch mapping is " << mapping << "\n");
03440       dderr ("\t-- accuracy profiled to be " << accuracy << "\n");
03441       if ((accuracy < 0.90) && (accuracy != -1)) {
03442         // may need to redo a different block if new hyperblock is created
03443         // will use PrevLink to find new hyperblock to redo.
03444         // findblockop necessary because branchop (op) if removed
03445         //      findblockop = op->GetPrevLink();
03446         if ((findblockop = IfConvertTreeBranch (op, K)) != NULL) {
03447           redoregion = TRUE;
03448           break;
03449         }
03450       }
03451       else {
03452         PredicateTreeBranch (op);
03453       }
03454     }
03455   }
03456 
03457   if (redoregion) {
03458     dderr ("IfConvertAndPredicateTreeBranch: ReDoRegion !!\n");
03459     newregion = (legoRegion *) findblockop->GetParentBlockPtr();
03460     IfConvertAndPredicateTreeBranch (newregion, K);
03461   }
03462   else {
03463     for (rl = region->GetChildren();
03464          rl != NULL; 
03465          rl = rl->GetNextListPtr()) {
03466       childregion = rl->GetRegionPtr();
03467       if ((childregion != NULL) &&
03468           (!childregion->IsMarked(RM_GENERAL)) &&
03469           (FindParentRegionType(RT_TREE, childregion) == 
03470            FindParentRegionType(RT_TREE, region))) {
03471         IfConvertAndPredicateTreeBranch (childregion, K);
03472         // introduction of a new hyperblock may corrupt rl, redo 
03473         rl = region->GetChildren();
03474       }
03475     }
03476   }
03477   return; 
03478 }
03479 
03480 
03481 /*
03482  * IfConvertAndPredicateTreeBranch
03483  *
03484  * Calls IfConvertTreeBranch(legoOp *) or PredicateTreeBranch(legoOp *) 
03485  * for each branch in a Region
03486  *
03487  */
03488 void IfConvertAndPredicateTreeBranch (legoTreegion *tree, knobs *K)
03489 {
03490   legoRegion *treeroot;
03491   
03492   ClearMarks (RM_GENERAL, tree);
03493   treeroot = tree->GetRoot();
03494   IfConvertAndPredicateTreeBranch (treeroot, K);
03495   return; 
03496 }
03497 
03498 
03499 /*
03500  * FullyIfConvertTreeBranch
03501  *
03502  * Calls IfConvertTreeBranch(legoOp *) for each branch in a Region
03503  *
03504  */
03505 void FullyIfConvertTreeBranch (legoRegion *region, knobs *K)
03506 {
03507   legoRegion *childregion, *newregion;
03508   regionList *rl;
03509   legoOp *op, *entryop, *findblockop; 
03510   attrs *a;
03511   int mapping; 
03512   float accuracy; 
03513   int redoregion;
03514 
03515   region->Mark (RM_GENERAL);
03516   entryop = region->GetEntryOpsPtr()->GetOpPtr();
03517   redoregion = FALSE;
03518 
03519   for (op = entryop; 
03520        op != NULL;
03521        op = op->GetNextLink()) {
03522     if (op->IsBRCONDOp()) {
03523       // may need to redo a different block if new hyperblock is created
03524       // will use PrevLink to find new hyperblock to redo.
03525       // findblockop necessary because branchop (op) if removed
03526       //        findblockop = op->GetPrevLink();
03527       if ((findblockop = IfConvertTreeBranch (op, K)) != NULL) {
03528         redoregion = TRUE;
03529         break;
03530       }
03531     }
03532   }
03533   
03534   if (redoregion) {
03535     dderr ("FullyIfConvertTreeBranch: ReDoRegion !!\n");
03536     newregion = (legoRegion *) findblockop->GetParentBlockPtr();
03537     FullyIfConvertTreeBranch (newregion, K);
03538   }
03539   else {
03540     for (rl = region->GetChildren();
03541          rl != NULL; 
03542          rl = rl->GetNextListPtr()) {
03543       childregion = rl->GetRegionPtr();
03544       if ((childregion != NULL) &&
03545           (!childregion->IsMarked(RM_GENERAL)) &&
03546           (FindParentRegionType(RT_TREE, childregion) == 
03547            FindParentRegionType(RT_TREE, region))) {
03548         FullyIfConvertTreeBranch (childregion, K);
03549         // introduction of a new hyperblock may corrupt rl, redo 
03550         rl = region->GetChildren();
03551       }
03552     }
03553   }
03554   return; 
03555 }
03556 
03557 
03558 /*
03559  * FullyIfConvertTreeBranch
03560  *
03561  * Calls IfConvertTreeBranch(legoOp *) for each branch in a Region
03562  *
03563  */
03564 void FullyIfConvertTreeBranch (legoTreegion *tree, knobs *K)
03565 {
03566   legoRegion *treeroot;
03567   
03568   ClearMarks (RM_GENERAL, tree);
03569   treeroot = tree->GetRoot();
03570   FullyIfConvertTreeBranch (treeroot, K);
03571   return; 
03572 }
03573 
03574 
03575 /*
03576  * FullyPredicateTreeBranch
03577  *
03578  * Calls PredicateTreeBranch(legoOp *) for each branch in a Region
03579  *
03580  */
03581 void FullyPredicateTreeBranch (legoRegion *region)
03582 {
03583   legoRegion *childregion, *newregion;
03584   regionList *rl;
03585   legoOp *op, *entryop, *findblockop; 
03586   attrs *a;
03587   int mapping; 
03588   float accuracy; 
03589   int redoregion;
03590 
03591   region->Mark (RM_GENERAL);
03592   entryop = region->GetEntryOpsPtr()->GetOpPtr();
03593   redoregion = FALSE;
03594 
03595   for (op = entryop; 
03596        op != NULL;
03597        op = op->GetNextLink()) {
03598     if (op->IsBRCONDOp()) {
03599       PredicateTreeBranch (op); 
03600     }
03601   }
03602   
03603   for (rl = region->GetChildren();
03604        rl != NULL; 
03605        rl = rl->GetNextListPtr()) {
03606     childregion = rl->GetRegionPtr();
03607     if ((childregion != NULL) &&
03608         (!childregion->IsMarked(RM_GENERAL)) &&
03609         (FindParentRegionType(RT_TREE, childregion) == 
03610          FindParentRegionType(RT_TREE, region))) {
03611       FullyPredicateTreeBranch (childregion);
03612       // introduction of a new hyperblock may corrupt rl, redo 
03613       rl = region->GetChildren();
03614     }
03615   }
03616   
03617   return; 
03618 }
03619 
03620 
03621 /*
03622  * FullyPredicateTreeBranch
03623  *
03624  * Calls PredicateTreeBranch(legoOp *) for each branch in a Region
03625  *
03626  */
03627 void FullyPredicateTreeBranch (legoTreegion *tree)
03628 {
03629   legoRegion *treeroot;
03630   
03631   ClearMarks (RM_GENERAL, tree);
03632   treeroot = tree->GetRoot();
03633   FullyPredicateTreeBranch (treeroot);
03634   return; 
03635 }
03636 
03637 
03638 //===========================================================================
03639 
03640 /*
03641  * DetectAndConvertHammock
03642  *   r = possible S region for hammock
03643  *   returns: result of if-conversion if successful, NULL otherwise
03644  *
03645  * Looks for a hammock at r and converts it if possible.
03646  */
03647 legoRegion *DetectAndConvertHammock (legoRegion *r, knobs *K)
03648 {
03649   hammock_info *h = DetectHammock (r);
03650   if (h->HammockDetected())
03651     {
03652       legoRegion *retval = IfConvertHammock (h, K);
03653       delete h;
03654       return retval;
03655     } // end if
03656   else
03657     {
03658       delete h;
03659       return NULL;
03660     } // end else
03661 } // end DetectAndConvertHammock
03662 
03663 /*
03664  * hammock
03665  *   r = region to consider for hammock conversion
03666  *   d = whether detection only is desired
03667  *   st = statistics of hammocks formed
03668  *   returns: 1 if hammock was found/converted, 0 otherwise
03669  *
03670  * Converts r and all contained regions to hammocks if possible. If st
03671  * is NULL, no statistics are logged.
03672  */
03673 int
03674 hammock (legoRegion *r, int d, knobs *K, hammock_stats *st = NULL)
03675 {
03676   int i, converted;
03677   hammock_info *h;
03678   regionList *l;
03679 
03680 #ifdef _HAMMOCK_DEBUG
03681   char fname[20];
03682 #endif
03683 
03684   if (r->GetRegionType() == RT_PROC)
03685     {
03686 #ifdef _HAMMOCK_DEBUG
03687       M = (legoModule *) (r->GetParentPtr());
03688 #endif
03689       dprintf ((OUTF, "Hammock: in proc %s.\n",
03690                 ((legoProc *) r)->GetProcName()));
03691       if (FindFlag (HAS_HB, r) != NULL ||
03692           FindFlag (HAS_SB, r) != NULL)
03693         {
03694           dprintf ((OUTF, "Hammock: proc contains hyperblocks or superblocks "
03695                     "already - aborting.\n"));
03696           return 0;
03697         } // end if
03698       ClearMarks (RM_GENERAL, r);
03699     } // end if
03700 
03701   if (!(IS_BLOCK(r->GetRegionType())))
03702     {  // r may hold blocks
03703       do
03704         {
03705           converted = 0;  // didn't convert anything
03706           for (i = 0; i < r->GetCount(); i++)
03707             {
03708               converted = hammock ((legoRegion *) r->GetItem(i), d, K, st);
03709               if (converted) break;  // stop after first conversion
03710             } // end for
03711 #ifdef HAMMOCK_WRITE_INTERMEDIATE_REBEL
03712           if (converted && !d)
03713             {
03714               sprintf (fname, "h%d.el", numnum++);
03715               LegoWrite (M, fname);
03716             } // end if
03717 #endif
03718                          
03719         } while (converted);  // if converted, restart on r since it changed
03720 
03721       if (r->GetRegionType() == RT_PROC) AddFlag (HAS_HB, r);
03722       return 0;  // in order to continue wih next container
03723     } // end if
03724   else  // it's a block ...
03725     {
03726       // A note about the use of marks here.
03727       // Two marks are used:
03728       // * RM_GENERAL: marks the S, T, and E blocks of existing hammocks.
03729       //   This is so subsequent detections don't use them as S blocks.
03730       // * RM_HAMMOCK: marks hyperblocks that are if-converted hammocks.
03731       //   The T and E blocks of a hammock can't be if-converted blocks
03732       //   themselves, since the architecture can't use multiple predicates.
03733       if (r->IsMarked (RM_GENERAL))  // mark => S, T, or E of existing hammock
03734         {
03735           //      r->Unmark (RM_GENERAL);
03736           return 0;  // shouldn't look for hammock here
03737         } // end if
03738       dprintf ((OUTF,"Hammock: analyzing block %d...", r->GetRegionId()));
03739       h = DetectHammock (r);
03740       if (h->HammockDetected() && !(h->T->IsMarked (RM_HAMMOCK)) &&
03741           !(h->E->IsMarked (RM_HAMMOCK)))  // can't have i-c'd T/E blocks
03742         {
03743           h->S->Mark (RM_GENERAL);  // mark S so we don't detect it agai
03744           h->T->Mark (RM_GENERAL);  // mark T so we don't use as S later
03745           if (h->IsDelta())
03746             dprintf ((OUTF,"found delta.\n"));
03747           else
03748             {
03749               dprintf ((OUTF,"found diamond.\n"));
03750               h->E->Mark (RM_GENERAL);  // mark E same as T
03751             } // end else
03752           if (h->S->GetRegionType() == RT_HB &&
03753               !(h->S->IsMarked (RM_HAMMOCK)))
03754             dprintf ((OUTF, "S block is code positioning SB!\n"));
03755 
03756           if (st != NULL)
03757             {
03758               if (h->IsDelta())
03759                 st->numdelta++;
03760               else
03761                 st->numdiamond++;
03762             } // end if
03763 
03764           if (!d)
03765             {
03766               r = IfConvertHammock (h, K);
03767               if (r == NULL)
03768                 {
03769                   LegoFatal ("Hammock", "If-conversion failed.");
03770                   exit(10);
03771                 } // end if
03772               delete h;
03773               r->Mark (RM_HAMMOCK);  // tag it
03774             } // end if
03775           return 1;  // woo-hoo! Got one!
03776         } // end if
03777       else
03778         {
03779           dprintf ((OUTF,"no hammock found.\n"));
03780           delete h;
03781           return 0;
03782         } // end else
03783     } // end else
03784 
03785   return 0;
03786 } // end hammock

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