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

treeform.C

Go to the documentation of this file.
00001 // treeform.C
00002 
00003 /*
00004  * LEGO Treegion Formation Tool
00005  * by Bill Havanki
00006  * based on code by Sanjeev Banerjia
00007  *
00008  * Initiated February 27, 1997
00009  * Completed (first version) March 19, 1997
00010  *
00011  * Syntax:
00012  * treeform [options] <input Rebel file> [<output Rebel file>]
00013  *   input Rebel file - Rebel file where treegions will be formed
00014  *   output Rebel file - Rebel file with treegions formed
00015  *                       (default = rebelfile_tree.el)
00016  *
00017  * 5/15/97 WAH:  Added support for tail duplication.
00018  * 5/16/97 WAH:  Added support for hammock conversion.
00019  * 5/19/97 WAH:  Changed to using knobs.
00020  * 6/12/97 WAH:  Added h_max_height_expansion and h_max_code_expansion
00021  *               knobs.
00022  * 6/13/97 WAH:  Added saplings_by_weight knob.
00023  * 6/16/97 WAH:  Finished hammock conversion knob implementations.
00024  * 7/22/97 WAH:  Added traceunform, RemoveTreeAttributes, treereform functions;
00025  *               treegions will be placed where root was, not at end.
00026  * 7/23/97 WAH:  Proc is now flagged with HAS_TREE.
00027  * 9/18/97 WAH:  Fixed treeid incrementing.
00028  * 10/2/97 WAH:  Moved construction algorithms from IR to here; added
00029  *               blockmap attribute creation.
00030  * 10/28/97 WAH: Added knob to control whether blocks with setjmp may
00031  *               be tail duplicated.
00032  * 1/22/98 WAH:  Proc is now flagged with HAS_HB if hammocks are made.
00033  * 3/23/98 WAH:  Updated dag usage.
00034  * 4/6/98 WAH:   Reduced machine instantiations to one per treeform call.
00035  * 4/13/98 WAH:  Switched to LEGO Util version of TailDuplicate.
00036  * 11/20/98 MDJ: Fixed bug in treeform(), no longer sensitive to the order of 
00037  *               BB within a procedure.
00038  */
00039 
00040 #include <stdio.h>
00041 #include <iostream.h>
00042 #include <stdlib.h>
00043 #include "lego.H"
00044 #include "legoMach.H"
00045 #include "legoUtil.H"
00046 #include "legoDAG.H"
00047 #include "treeform.H"
00048 #include "hyperform.H"
00049 #include "TinkerKnobs.H"
00050 
00051 #include "loopdetect.H" //HZ for loop edge detection
00052 
00053 //#define TREEFORM_DEBUG
00054 #ifdef TREEFORM_DEBUG
00055 #define dprintf(s) fprintf s
00056 #define OUTF stderr
00057 #else
00058 #define dprintf(s)
00059 #endif // TREEFORM_DEBUG
00060 
00061 // === CONSTRUCTION =================================================
00062 
00063 #define LEGOTREE_FULL (0)
00064 #define LEGOTREE_LINEAR (1)
00065 
00066 /*
00067  * AddBranchAccAttrs
00068  *   proc = procedure to add branch accuracy attributes to 
00069  *
00070  * Add branch accuracy attributes to each conditional branch in this 
00071  * procedure based on profiling data stored in BRaNCH_PT and branch.acc
00072  */
00073 static void
00074 AddBranchAccAttrs (legoProc *proc, char *branch_pt_file, char *branch_acc_file)
00075 {
00076 
00077 char pname[1000];
00078 int found;
00079 int size, profile, mapping, node_id, accesses, correct, incorrect;
00080 float accuracy; 
00081 
00082   int region_count=proc->GetCount();
00083   for(int j=0;j<region_count;j++)
00084     {
00085       legoRegion *region_ptr=(legoRegion *)proc->GetItem(j);
00086       if (IS_BLOCK( region_ptr->GetRegionType() ) ) {
00087         opList *entry_op_list=region_ptr->GetEntryOpsPtr();
00088         legoOp *op_ptr=entry_op_list->GetOpPtr();
00089         for(;op_ptr!=NULL;op_ptr=op_ptr->GetNextLink())
00090           {
00091             int op_code=op_ptr->GetOpcode();
00092             //if(op_code==BRCT)
00093             if(op_ptr->IsBRCONDOp())
00094               {
00095                 FILE *branch_pt_fp = fopen(branch_pt_file,"r");
00096                 FILE *branch_acc_fp = fopen(branch_acc_file,"r");
00097                 found = FALSE;
00098                 while(fscanf(branch_pt_fp,"Proc:%s size=%d\n",&pname,&size)==2)
00099                   {
00100                     if (strcmp(pname, "_MaiN") == 0) {
00101                       strcpy(pname, "_main");
00102                     }
00103                     fscanf(branch_pt_fp,"profile\tmapping\tnode_id\n");
00104                     if (strcmp(pname, proc->GetProcName()) == 0) {
00105                       for(int i=0;i<size;i++)
00106                         {
00107                           fscanf(branch_pt_fp,"%d\t%d\t%d\n",&profile,&mapping,&node_id);
00108                           if (node_id == op_ptr->GetOpId()) {
00109                             for (int m=0; m<mapping; m++) {
00110                               fscanf(branch_acc_fp,"%d\t%d\t%d\t%d\t%f\n",&i,&accesses,&correct,&incorrect,&accuracy);
00111                             }
00112                             // here is the accuracy info for this BRCT
00113                             fscanf(branch_acc_fp,"%d\t%d\t%d\t%d\t%f\n",&i,&accesses,&correct,&incorrect,&accuracy);
00114                             legoOprd *oprd = new legoOprd;
00115                             oprd->SetOprdType (OT_LITERAL_F);
00116                             oprd->SetLiteralFloat (accuracy);
00117                             
00118                             AddLcAttribute ("branch_acc", oprd, op_ptr, (legoProc *) FindParentRegionType (RT_PROC, op_ptr));
00119 
00120                             oprd = new legoOprd;
00121                             oprd->SetOprdType (OT_LITERAL_I);
00122                             oprd->SetLiteralInteger (i);
00123                             
00124                             AddLcAttribute ("branch_mapping", oprd, op_ptr, (legoProc *) FindParentRegionType (RT_PROC, op_ptr));
00125 
00126                             found = TRUE;
00127                             break;
00128                           } 
00129                         }
00130                     }
00131                     else {
00132                       for(int i=0;i<size;i++)
00133                         {
00134                           fscanf(branch_pt_fp,"%d\t%d\t%d\n",&profile,&mapping,&node_id);
00135                         }
00136                     }
00137                     if (found) break; 
00138                   }
00139                 fclose(branch_pt_fp);
00140                 fclose(branch_acc_fp);
00141               }
00142           }
00143       }
00144       else { // otherwise this is a treegion
00145         int treegion_bb_count=region_ptr->GetCount();
00146         for(int k=0;k<treegion_bb_count;k++) {
00147           legoRegion *treegion_bb_ptr=(legoRegion *)region_ptr->GetItem(k);
00148           opList *entry_op_list=treegion_bb_ptr->GetEntryOpsPtr();
00149           legoOp *op_ptr=entry_op_list->GetOpPtr();
00150           for(;op_ptr!=NULL;op_ptr=op_ptr->GetNextLink())
00151             {
00152               int op_code=op_ptr->GetOpcode();
00153               //if(op_code==BRCT)
00154               if(op_ptr->IsBRCONDOp())
00155                 {
00156                 FILE *branch_pt_fp = fopen(branch_pt_file,"r");
00157                 FILE *branch_acc_fp = fopen(branch_acc_file,"r");
00158                 found = FALSE;
00159                 while(fscanf(branch_pt_fp,"Proc:%s size=%d\n",&pname,&size)==2)
00160                   {
00161                     if (strcmp(pname, "_MaiN") == 0) {
00162                       strcpy(pname, "_main");
00163                     }
00164                     fscanf(branch_pt_fp,"profile\tmapping\tnode_id\n");
00165                     if (strcmp(pname, proc->GetProcName()) == 0) {
00166                       for(int i=0;i<size;i++)
00167                         {
00168                           fscanf(branch_pt_fp,"%d\t%d\t%d\n",&profile,&mapping,&node_id);
00169                           if (node_id == op_ptr->GetOpId()) {
00170                             for (int m=0; m<mapping; m++) {
00171                               fscanf(branch_acc_fp,"%d\t%d\t%d\t%d\t%f\n",&i,&accesses,&correct,&incorrect,&accuracy);
00172                             }
00173                             // here is the accuracy info for this BRCT
00174                             fscanf(branch_acc_fp,"%d\t%d\t%d\t%d\t%f\n",&i,&accesses,&correct,&incorrect,&accuracy);
00175                             legoOprd *oprd = new legoOprd;
00176                             oprd->SetOprdType (OT_LITERAL_F);
00177                             oprd->SetLiteralFloat (accuracy);
00178                             
00179                             AddLcAttribute ("branch_acc", oprd, op_ptr, (legoProc *) FindParentRegionType (RT_PROC, op_ptr));
00180 
00181                             oprd = new legoOprd;
00182                             oprd->SetOprdType (OT_LITERAL_I);
00183                             oprd->SetLiteralInteger (i);
00184                             
00185                             AddLcAttribute ("branch_mapping", oprd, op_ptr, (legoProc *) FindParentRegionType (RT_PROC, op_ptr));
00186 
00187                             found = TRUE;
00188                             break;
00189                           } 
00190                         }
00191                     }
00192                     else {
00193                       for(int i=0;i<size;i++)
00194                         {
00195                           fscanf(branch_pt_fp,"%d\t%d\t%d\n",&profile,&mapping,&node_id);
00196                         }
00197                     }
00198                     if (found) break; 
00199                   }
00200                 fclose(branch_pt_fp);
00201                 fclose(branch_acc_fp);
00202                 }
00203             }
00204         }
00205       }
00206     } 
00207 } // end AddBranchAccAttrs
00208 
00209 /*
00210  * DFS
00211  *   tree = treegion to construct
00212  *   begin = first block in tree
00213  *   treetype = as in construct
00214  *   returns:  tree saplings
00215  *
00216  * Performs a standard recursive DFS (depth-first-search) of the block.
00217  * First, this block is checked, and a ref to it is added if needed.
00218  * Then, its successors are searched; this adds to the chain of refs of
00219  * those that cannot be integrated.  This list is returned.
00220  */
00221 static regionList *
00222 DFS (legoTreegion *tree, legoRegion *begin, int treetype)
00223 {
00224   enum regionTypes type;
00225   regionList *localparents, *localchildren;
00226 
00227   regionList *list, *newlist, *nowlist, *temp;
00228   legoRegion *now;
00229   legoRegion *nextopparent, *pregion, *bestregion = NULL;
00230   int i, dontintegrate;
00231   double weight;
00232   int removed = FALSE;
00233   legoRegion *predecessor; 
00234 
00235   list = NULL;
00236   nowlist = new regionList (begin);  // list of blocks left to consider
00237   //  parlist = new regionList (beginpar);  // list of parents for those blocks
00238 
00239   while (nowlist != NULL)
00240     {
00241       now = nowlist->GetRegionPtr();
00242 
00243       // Dequeue nowlist and parlist immediately!
00244       temp = nowlist;
00245       nowlist = nowlist->GetNextListPtr();
00246       temp->SetNextListPtr (NULL);
00247       delete temp;
00248 
00249       type = now->GetRegionType();
00250       dontintegrate = 0;
00251 
00252       dprintf ((OUTF, "DFS: on block %d, type %d.\n", now->GetRegionId(),
00253                 type));
00254 
00255       // Before doing anything, make sure now isn't already in
00256       // a treegion.
00257       for (pregion = now->GetParentPtr(); pregion->GetRegionType() != RT_PROC;
00258            pregion = pregion->GetParentPtr())
00259         if (pregion->GetRegionType() == RT_TREE) break;
00260 
00261       if (pregion->GetRegionType() == RT_TREE)
00262         {
00263           dprintf ((OUTF, "DFS: can't integrate - in a tree already!\n"));
00264           dontintegrate = 1;
00265         } // end if
00266 
00267       // First check this one - if it has more than two previous
00268       // regions, it's no good.  If it isn't a block, it's no good.
00269       if ((dontintegrate == 0) && !(IS_BLOCK(type)))
00270         {
00271           dprintf ((OUTF, "DFS: can't integrate - not a block!\n"));
00272           dontintegrate = 1;
00273         } // end if
00274 
00275       localparents = now->GetParents();
00276       if ((dontintegrate == 0) && localparents != NULL &&
00277           localparents->GetRegionPtr() != NULL)
00278         {
00279           // mdj - 5/15/99: Need to break treegions at setjump/longjump 
00280           // boundaries. Don't integrate if previous block contained a 
00281           // setjump
00282           if ((localparents != NULL) && (localparents->GetRegionPtr() != NULL)
00283               && (now != tree->GetRoot()) && 
00284               (FindLcAttribute( "set_jmp_present", 
00285                                localparents->GetRegionPtr()) != NULL))
00286             {
00287               // previous block contains setjump. Next block must be a treeRoot
00288               dprintf ((OUTF, "DFS: can't integrate - set_jmp_present in previousblock!\n"));
00289               dontintegrate = 1;
00290             } // end if
00291         }
00292       if ((dontintegrate == 0) && localparents != NULL &&
00293           localparents->GetRegionPtr() != NULL)
00294         {
00295           // there is one previous op ... maybe can't integrate
00296           localparents = localparents->GetNextListPtr();
00297           if (localparents != NULL && localparents->GetRegionPtr() != NULL
00298               && now != tree->GetRoot())
00299             {
00300               // there is 2+ prev ops and it's not the root - can't integrate
00301               dprintf ((OUTF, "DFS: can't integrate - multiple inedges!\n"));
00302               dontintegrate = 1;
00303             } // end if
00304         } // end if
00305       
00306       if ((dontintegrate)) {
00307         newlist = new regionList (now);
00308         //        cerr << "Adding block " << now->GetRegionId() << " to regionList; BlockPtr = " << now << "\n";
00309         if (list != NULL)
00310           list->Concatenate (newlist);
00311         else
00312           list = newlist;
00313         
00314         continue;  // while (nowlist != NULL)
00315       } // end if
00316       
00317       dprintf ((OUTF, "DFS: integrating block %d...\n", now->GetRegionId()));
00318       // there is exactly one inedge ... can add after removing from current
00319       // parent.
00320 
00321       // First, see if now can be removed completely (merged with predecessor)
00322       if (now != tree->GetRoot()) {
00323         // if we will be able to remove, will need predecessor
00324         // (there will be only one predecessor if can be removed)
00325         predecessor = now->GetParents()->GetRegionPtr(); 
00326         removed = RemoveUncondBranch(now);
00327       } // end if
00328       
00329       if (removed) { 
00330         localchildren = predecessor->GetChildren(); 
00331         bestregion = NULL; weight = -1.0;
00332       }
00333       else { // Add to tree without merging
00334         pregion = now->GetParentPtr();
00335         if (pregion != NULL)
00336           for (i = 0; i < pregion->GetCount(); i++)
00337             if (pregion->GetItem(i) == (void *) now)
00338               {
00339                 pregion->Detach(i);
00340                 break;
00341               } // end if (, for, if)
00342         tree->AddItem (now);
00343         now->SetParentPtr (tree);
00344         
00345         // Loop through successors of now.
00346         dprintf ((OUTF, "DFS: <<<\nDFS: Ready to enqueue successors of %d...\n",
00347                   now->GetRegionId()));
00348         
00349         localchildren = now->GetChildren(); bestregion = NULL; weight = -1.0;
00350       }
00351       while (localchildren != NULL)
00352         {
00353           nextopparent = localchildren->GetRegionPtr();
00354           if (nextopparent != NULL)
00355             {
00356               if (treetype == LEGOTREE_FULL)
00357                 {
00358                   //          newlist = DFS (nextopparent, now, treetype);
00359                   //          if (list != NULL)
00360                   //            list->Concatenate (newlist);    
00361                   //          else
00362                   //            list = newlist;
00363                   // Add nextopparent to nowlist et al.
00364                   newlist = new regionList (nextopparent);
00365                   newlist->SetNextListPtr (nowlist);
00366                   nowlist = newlist;
00367                   dprintf ((OUTF, "DFS: enqueued region %d.\n",
00368                             nextopparent->GetRegionId()));
00369                 } // end if
00370               else  // treetype == LEGOTREE_LINEAR
00371                 {
00372                   if (nextopparent->GetWeight() > weight)
00373                     {
00374                       weight = nextopparent->GetWeight();
00375                       bestregion = nextopparent;
00376                     } // end if
00377                 } // end else
00378               localchildren = localchildren->GetNextListPtr();
00379             } // end if
00380 
00381         } // end while
00382 
00383       if (treetype == LEGOTREE_LINEAR && bestregion != NULL)
00384         {
00385           int addedexitopalready = 0;
00386 
00387           // Recurse on the best region.
00388           dprintf ((OUTF, "DFS: Best child is region %d!\n",
00389                     bestregion->GetRegionId()));
00390           //      newlist = DFS (bestregion, now, treetype);
00391           newlist = new regionList (bestregion);
00392           newlist->SetNextListPtr (nowlist);
00393           nowlist = newlist;
00394           dprintf ((OUTF, "DFS: enqueued region %d.\n",
00395                     bestregion->GetRegionId()));
00396 
00397           // Also add leftover children to list.
00398           if (removed) { 
00399             localchildren = predecessor->GetChildren(); 
00400           }
00401           else {
00402             localchildren = now->GetChildren();
00403           }
00404           while (localchildren != NULL)
00405             {
00406               nextopparent = localchildren->GetRegionPtr();
00407               if (nextopparent != NULL && nextopparent != bestregion)
00408                 {
00409                   newlist = new regionList (nextopparent);
00410 
00411                   if (list != NULL)
00412                     list->Concatenate (newlist);
00413                   else
00414                     list = newlist;
00415                 } // end if
00416               localchildren = localchildren->GetNextListPtr();
00417             } // end while
00418         } // end if
00419 
00420       dprintf ((OUTF, "DFS: Done enqueueing successors of %d.\nDFS: >>>\n",
00421                 now->GetRegionId()));
00422     } // end while
00423   return list;
00424 } // end DFS
00425 
00426 /*
00427  * Construct
00428  *   tree = treegion to construct
00429  *   start = first basic block to go from
00430  *   treetype = LEGOTREE_FULL for full treegion, LEGOTREE_LINEAR for
00431  *     linear regions
00432  *
00433  * From start, builds a single entry acyclic region or treegion.
00434  * It also records those basic blocks which could not be added to
00435  * the treegion as the treegion children.
00436  */
00437 void
00438 Construct (legoTreegion *tree, legoRegion *start,
00439            int treetype = LEGOTREE_FULL)
00440 {
00441   enum regionTypes type;
00442 
00443   // Basic initialization...
00444   tree->SetInEdgesPtr (NULL);
00445   tree->SetOutEdgesPtr (NULL);
00446   tree->SetFlagPtr (NULL);
00447   tree->SetEntryOpsPtr (NULL);
00448   tree->SetExitOpsPtr (NULL);
00449   tree->SetRegionAttrListPtr (NULL);
00450 
00451   // Bail if nowhere to start or if start is not a block.
00452   if (start == NULL)
00453     return;
00454   type = start->GetRegionType();
00455   if (!(IS_BLOCK(type)))
00456     return;
00457   tree->SetRoot (start);
00458 
00459   // Now, do a DFS search from start down to the succeeding
00460   // basic blocks.
00461   tree->SetSaplings (DFS (tree, start, treetype));
00462 
00463   tree->RefreshOpsAndEdges();
00464   return;
00465 } // end Construct
00466 
00467 /*
00468  * ContinueConstruction
00469  *   tree = treegion to construct
00470  *
00471  * Continues to build upon the current treegion, also updating the
00472  * treegion saplings.
00473  */
00474 static void
00475 ContinueConstruction (legoTreegion *tree)
00476 {
00477   enum regionTypes type;
00478   int i, originalcount;
00479   legoRegion *treeblock, *tbchild;
00480   regionList *tbkids, *list;
00481   unsigned index;
00482 
00483   // First, blow away all exit ops and saplings.
00484   delete tree->GetExitOpsPtr();
00485   tree->SetExitOpsPtr (NULL);
00486   delete tree->GetSaplings(); tree->SetSaplings (NULL);
00487 
00488   // Now, for each block in the treegion, DFS on each child not in
00489   // the tree.
00490   originalcount = tree->GetCount();
00491   for (i = 0; i < originalcount; i++)
00492     {
00493       treeblock = (legoRegion *) tree->GetItem(i);
00494       tbkids = treeblock->GetChildren();
00495       while (tbkids != NULL)
00496         {
00497           tbchild = tbkids->GetRegionPtr();
00498           // Update tbkids now, DFS call can corrupt this entry if block 
00499           // is remove during RemoveUncondBranch() in DFS()
00500           tbkids = tbkids->GetNextListPtr();
00501           if (tbchild != NULL)
00502             // Try to find tbchild in treegion.
00503             index = tree->Search (tbchild);
00504 
00505           if (index == MAX_UNSIGNED)  // no match => not in tree => DFS it
00506             {
00507               list = DFS (tree, tbchild, LEGOTREE_FULL);
00508               if (tree->GetSaplings() != NULL)
00509                 tree->GetSaplings()->Concatenate (list);
00510               else
00511                 if (list != NULL)
00512                   tree->SetSaplings (new regionList (*list));
00513             } // end if
00514 
00515         } // end while
00516 
00517     } // end for
00518 
00519   tree->RefreshOpsAndEdges();
00520   return;
00521 } // end ContinueConstruction
00522 
00523 /*
00524  * Deconstruct
00525  *   tree = treegion to deconstruct
00526  *
00527  * Empties a treegion, marking the component blocks with the treegion id. After
00528  * this method finishes, the treegion may be removed from its container and
00529  * deleted.
00530  */
00531 void
00532 Deconstruct (legoTreegion *tree)
00533 {
00534   legoRegion *region, *pregion;
00535   legoProc *proc;
00536   int i, count;
00537   unsigned treeloc;
00538 
00539   for (region = tree->GetParentPtr();
00540        region != NULL && region->GetRegionType() != RT_PROC;
00541        region = region->GetParentPtr())
00542     /* do nothing */;
00543   if (region == NULL)
00544     {
00545       LegoNonFatal ("Deconstruct (treegion)",
00546                     "Can't find proc of treegion %d.", tree->GetRegionId());
00547       return;
00548     } // end if
00549   proc = (legoProc *) region;
00550   pregion = tree->GetParentPtr();  // not NULL, or would have stopped be4
00551 
00552   // Now, detach each region from treegion and place into trace container.
00553   count = tree->GetCount();
00554   for (i = 0; i < count; i++)
00555     {
00556       region = (legoRegion *) tree->GetItem(0);  // 0, not i, since will Detach
00557 
00558       treeloc = pregion->Search (tree);
00559       if (treeloc == MAX_UNSIGNED)
00560         {
00561           LegoNonFatal ("Deconstruct (treegion)",
00562                         "Couldn't find treegion %d in proc.",
00563                         tree->GetRegionId());
00564           return;
00565         } // end if
00566       tree->Detach (0);
00567       pregion->Insert (region, treeloc);
00568       region->SetParentPtr (pregion);
00569     } // end for
00570 
00571   return;
00572 } // end Deconstruct
00573 
00574 /*
00575  * Reconstruct
00576  *   tree = treegion to reconstruct
00577  *   root = root block of treegion
00578  *
00579  * Reforms a treegion starting from the root block by following "tree"
00580  * attributes with the same id.
00581  */
00582 static void
00583 Reconstruct (legoTreegion *tree, legoRegion *root)
00584 {
00585   legoRegion *region, *pregion, *nextregion;
00586   attrs *treeattr;
00587   regionList *treelist, *temp, *regionchildren;
00588   unsigned index;
00589   int treeid;
00590   
00591   // Basic initialization ...
00592   tree->SetInEdgesPtr (NULL);
00593   tree->SetOutEdgesPtr (NULL);
00594   tree->SetFlagPtr (NULL);
00595   tree->SetEntryOpsPtr (NULL);
00596   tree->SetExitOpsPtr (NULL);
00597   tree->SetRegionAttrListPtr (NULL);
00598   
00599   //  SetWeight (root->GetWeight());
00600   tree->SetWeight (0.0);
00601 
00602   // Bail if nowhere to start or if root is not a block.
00603   if (root == NULL)
00604     return;
00605   if (!(IS_BLOCK(root->GetRegionType())))
00606     return;
00607 
00608   tree->SetRoot (root);
00609   pregion = root->GetParentPtr();
00610   if (pregion == NULL)
00611     {
00612       LegoNonFatal ("Reconstruct (treegion)",
00613                     "Couldn't find parent region of region %d.",
00614                     root->GetRegionId());
00615       return;
00616     } // end if
00617 
00618   // Set up DFS queue and proceed.
00619   treelist = new regionList (root);
00620   while (treelist != NULL)
00621     {
00622       region = treelist->GetRegionPtr();
00623       temp = treelist;
00624       treelist = treelist->GetNextListPtr();
00625       temp->SetNextListPtr (NULL);
00626       delete temp;
00627 
00628       treeattr = FindLcAttribute ("tree", region);
00629       if (treeattr == NULL || treeattr->GetAttrOprdPtr() == NULL)
00630         {
00631           
00632           dprintf ((OUTF, "legoTreegion::Reconstruct: Couldn't find tree "
00633                    "attribute of region %d.\n", region->GetRegionId()));
00634           if (region == root)
00635             {
00636               LegoNonFatal ("Reconstruct (treegion)",
00637                             "Root %d lacks tree attribute.",
00638                             root->GetRegionId());
00639               return;
00640             } // end if
00641           else
00642             continue;
00643         } // end if
00644 
00645       if (region == root)
00646         {
00647           treeid = treeattr->GetAttrOprdPtr()->GetLiteralInteger();
00648           dprintf ((OUTF, "legoTreegion::Reconstruct: Rebuilding treegion "
00649                     "%d.\n", treeid));
00650           tree->SetRegionId (treeid);
00651         } // end if
00652       else if (treeattr->GetAttrOprdPtr()->GetLiteralInteger() != treeid)
00653         {
00654           dprintf ((OUTF, "legoTreegion::Reconstruct: Region %d belongs "
00655                     "to a different treegion.\n", region->GetRegionId()));
00656           continue;
00657         } // end else if
00658 
00659       // Move region from pregion to treegion.
00660       index = pregion->Search (region);
00661       if (index == MAX_UNSIGNED)
00662         {
00663           LegoNonFatal ("Reconstruct (treegion)",
00664                         "Couldn't find region %d in region %d.",
00665                         region->GetRegionId(), pregion->GetRegionId());
00666           break;
00667         } // end if
00668 
00669       dprintf ((OUTF, "legoTreegion::Reconstruct: Moving block %d into "
00670                 "trace.\n", region->GetRegionId()));
00671       pregion->Detach (index);
00672       tree->AddItem (region);
00673       region->SetParentPtr (tree);
00674 
00675       // Queue up the successors of region for consideration next.
00676       for (regionchildren = region->GetChildren();
00677            regionchildren != NULL;
00678            regionchildren = regionchildren->GetNextListPtr())
00679         {
00680           nextregion = regionchildren->GetRegionPtr();
00681           if (nextregion == NULL) continue;
00682           if (nextregion->IsContainedIn (tree)) continue;
00683 
00684           temp = new regionList (nextregion);
00685           temp->SetNextListPtr (treelist);
00686           treelist = temp;
00687         } // end for
00688       
00689     } // end while
00690   
00691   dprintf ((OUTF, "Reconstruct: Stopping treegion.\n"));
00692   tree->RefreshOpsAndEdges();
00693   return;
00694 } // end Reconstruct
00695 
00696 // === FORMATION ====================================================
00697 
00698 /*
00699  * RegionRemoveTreeAttributes
00700  *   region = region within which attributes are removed
00701  *   proc = proc which contains region
00702  *
00703  * Removes region "tree" attributes from region and recursively
00704  * from its components.
00705  */
00706 static void
00707 RegionRemoveTreeAttributes (legoRegion *region, legoProc *proc)
00708 {
00709   RemoveLcAttribute ("tree", region, proc);
00710 
00711   if (IS_BLOCK(region->GetRegionType()))
00712     return;
00713   for (int i = 0; i < region->GetCount(); i++)
00714     RegionRemoveTreeAttributes ((legoRegion *) region->GetItem(i), proc);
00715 
00716   return;
00717 } // end RegionRemoveTreeAttributes
00718 
00719 /*
00720  * RemoveTreeAttributes
00721  *   proc = procedure within which attributes are removed
00722  *
00723  * Removes region "tree" attributes from all regions in a proc.
00724  */
00725 static void
00726 RemoveTreeAttributes (legoProc *proc)
00727 {
00728   RegionRemoveTreeAttributes ((legoRegion *) proc, proc);
00729 } // end RemoveTreeAttributes
00730 
00731 // Slightly modified from list_scheduler::DescendantofBlock()
00732 // 
00733 // descendantofblock: Returns YES if this operation 
00734 // belongs to a block which is a descendant of the 
00735 // block identified by a pointer of value input_block_int. 
00736 int descendantofblock( int input_block_int, legoOp *op )
00737 {
00738   
00739   legoRegion *block_ptr, *root_block_ptr;
00740   regionList *region_list;
00741   int block_int;
00742   legoTreegion *treegion; 
00743 
00744   block_ptr = (legoRegion *) op->GetParentBlockPtr();
00745   block_int = (int) block_ptr;
00746   
00747   treegion = (legoTreegion *) FindParentRegionType (RT_TREE, op);
00748   root_block_ptr = treegion->GetRoot();
00749   while ( (block_int != input_block_int) && (block_ptr != NULL) ) {
00750     if (block_ptr == root_block_ptr)
00751       break;
00752     region_list = block_ptr->GetParents();
00753     // blocks in a treegion have one and only one parent, except root block 
00754     // which has no parents. 
00755     if (region_list != NULL) {
00756       block_ptr = region_list->GetRegionPtr();
00757       block_int = (int) block_ptr;
00758     }
00759     else {
00760       block_ptr = NULL;
00761       block_int = 0;
00762     }
00763   }
00764   
00765   if (block_int == input_block_int) {
00766     return TRUE;
00767   }
00768   else {
00769     return FALSE;
00770   }
00771 }
00772 
00773 void 
00774 lineartreesfromtreegions (legoTreegion *tree)
00775 {
00776 
00777   legoRegion *root, *child, *best_child, *current_block, *bb_for_new_tree;
00778   double weight; 
00779   int children_in_tree_count, max_region_id, i;
00780   regionList *children, *bbs_for_new_tree, *last_bb_for_new_tree; 
00781   legoProc *parentproc; 
00782   legoTreegion *new_tree; 
00783 
00784   root = tree->GetRoot();
00785   
00786   // Figure out if root has more than one child within the treegion (that 
00787   // is not also the root block)
00788   current_block = root; 
00789   while (current_block != NULL) {
00790     best_child = NULL; 
00791     weight = -1.0;
00792     children_in_tree_count = 0;
00793     for (children = current_block->GetChildren();
00794          children != NULL; 
00795          children = children->GetNextListPtr()) {
00796       child = children->GetRegionPtr();
00797       if ((child->GetParentPtr() == tree) &&
00798           (child != tree->GetRoot())) {
00799         children_in_tree_count++;
00800         if (child->GetWeight() > weight) {
00801           weight = child->GetWeight();
00802           best_child = child;
00803         }
00804       }
00805     }
00806     
00807     // Split off treegion(s) if children_in_tree_count > 1
00808     if (children_in_tree_count > 1) {
00809       for (children = current_block->GetChildren();
00810            children != NULL; 
00811            children = children->GetNextListPtr()) {
00812         child = children->GetRegionPtr();
00813         if ((child->GetParentPtr() == tree) &&
00814             (child != tree->GetRoot())) {
00815           // split off another treegion if not best_child
00816           if (child != best_child) {
00817             parentproc = (legoProc *) FindParentRegionType (RT_PROC, tree);
00818             max_region_id = (parentproc->FindMaxRegionId())->GetRegionId();
00819             new_tree = new legoTreegion (++max_region_id);
00820             parentproc->AddItem (new_tree);
00821             new_tree->SetParentPtr (parentproc);
00822             
00823             //HZ: set new_tree's weight
00824             new_tree->SetWeight(child->GetWeight());
00825             
00826             bbs_for_new_tree = NULL;
00827             for (i = 0; i < tree->GetCount(); i++) {
00828               if (descendantofblock((int) child, (legoOp*)((legoRegion *)tree->GetItem(i))->GetItem(0))) {
00829                 if (bbs_for_new_tree == NULL) {
00830                   bbs_for_new_tree = new regionList();
00831                   bbs_for_new_tree->SetRegionPtr((legoRegion *)tree->GetItem(i));
00832                   last_bb_for_new_tree = bbs_for_new_tree;
00833                 }
00834                 else {
00835                   last_bb_for_new_tree->SetNextListPtr(new regionList());
00836                   last_bb_for_new_tree = last_bb_for_new_tree->GetNextListPtr();
00837                   last_bb_for_new_tree->SetRegionPtr((legoRegion *)tree->GetItem(i));
00838                 }
00839               }
00840             }
00841             for (;
00842                  bbs_for_new_tree != NULL;
00843                  bbs_for_new_tree = bbs_for_new_tree->GetNextListPtr()) {
00844               bb_for_new_tree = bbs_for_new_tree->GetRegionPtr(); 
00845               // detach from original tree
00846               for (i = 0; i < tree->GetCount(); i++) {
00847                 if (tree->GetItem(i) == (void *) bb_for_new_tree) {
00848                   tree->Detach(i);
00849                   break;
00850                 }
00851               }
00852               new_tree->AddItem (bb_for_new_tree);
00853               bb_for_new_tree->SetParentPtr (new_tree);
00854               if (bb_for_new_tree == child) {
00855                 new_tree->SetRoot(bb_for_new_tree);
00856               }
00857             }
00858             new_tree->RefreshOps();
00859             new_tree->RefreshEdges();
00860           }
00861           tree->RefreshOps();
00862           tree->RefreshEdges();
00863         }
00864       }
00865     }
00866     current_block = best_child;
00867   }
00868 }
00869 
00870 /* Adds an attribute to each op in treegion having their original basic block ids 
00871    When Ops are speculated, those attributes keep info about where they are 
00872    exactly originated added by Emre Ozer in 04/22/1999
00873 */
00874 
00875 void AddBBIdAttribute(legoProc *proc)
00876 {
00877   legoTreegion *Region;
00878   legoBB       *BBlock;
00879   legoOp       *Op;
00880   legoOprd     *Oprd;
00881   attrs        *attr;
00882   int          BlockId;
00883 
00884   for(int i=0;i < proc->GetCount();i++) {
00885        Region=(legoTreegion *) proc->GetItem(i);
00886        for(int j=0; j<Region->GetCount();j++) {
00887           BBlock= (legoBB *) Region->GetItem(j);
00888           BlockId=BBlock->GetRegionId();
00889           for(int k=0;k<BBlock->GetCount();k++) {
00890             Op=(legoOp *) BBlock->GetItem(k);
00891             Oprd=new legoOprd;
00892             Oprd->SetOprdType(OT_LITERAL_I);
00893             Oprd->SetLiteralInteger(BlockId);
00894             Oprd->SetOprdDataType(DT_I);
00895             Oprd->SetIntValue(0);
00896             Oprd->SetNextOprdPtr((legoOprd *)NULL);
00897             Oprd->SetPrevOprdPtr((legoOprd *)NULL);
00898             Oprd->SetParentOpPtr((legoOp *)NULL);                  
00899             Oprd->SetParentAttrPtr((attrs *)NULL);
00900             Oprd->SetValid(1);
00901             AddLcAttribute("Original-Block-ID",Oprd,Op,proc);
00902           }
00903        }
00904   }
00905 }
00906 
00907 
00908 
00909 /*
00910  * treeform - form treegions
00911  *   proc = procedure within which to form treegions
00912  *   treeid = first treegion id - 1 ( = max region id of proc's module)
00913  *   K = pointer to knobs
00914  *   st = statistics of treegions formed
00915  *
00916  * Forms treegions in the given proc, with ids starting from treeid.
00917  * The various flags trigger whether certain formation options are
00918  * followed. If st is NULL, no statistics are logged.
00919  *   Parameter final: see the comments inside the function
00920  */
00921 void
00922 treeform (legoProc *proc, int& treeid, knobs *K, tree_stats *st = NULL, bool final =
00923 true)
00924 {
00925   regionList *unprocessed, *unptail, *temp, *saplist;
00926   legoRegion *currentregion, *parentregion;
00927   legoTreegion *tree;
00928   machine *mach = NULL;
00929   int RegionType, i, codesize, codesizeorig;
00930   int did_a_hammock = 0;
00931   int did_a_tail_duplication = 0, did_a_tail_duplication_sometime = 0;
00932   unsigned rootindex;
00933 
00934   char do_td, do_cascades, saplings_by_weight, do_hammocks, do_slrs, td_sj;
00935   int max_incoming_edges, max_path_count;
00936   double max_code_expansion, h_max_height_expansion, h_max_code_expansion;
00937   double h_max_opcount;
00938   double miss_predict_penalty;
00939   char *branch_acc_file;
00940   char *branch_pt_file;
00941   char use_branch_profile;
00942   long block_count;
00943   opList *exitopl, *out_cmerges; 
00944   legoRegion *root_block_ptr, *block_ptr; 
00945   opEdges *exit_edge;
00946   double weight, frequency; 
00947   
00948   int inp_start = FindFirstOutGoingReg(proc);
00949   int inp_end = FindLastOutGoingReg(proc);
00950 
00951   dprintf(( OUTF, "treeform: In proc %s...\n", proc->GetProcName() ));
00952   // Before we begin, flag the proc.
00953   AddFlag (HAS_TREE, proc);
00954   // dag builder and tree-traversal scheduling require that treegions 
00955   // consist only of BBs
00956   UnBindSB(proc);
00957 
00958   // Read in knobs.
00959   K->SetDefaultPanel ("rform/tree");
00960   K->Read ("t/d-do", do_td);
00961   K->Read ("t/d-max-code-expansion", max_code_expansion);
00962   K->Read ("t/d-merge-cascade", do_cascades);
00963   K->Read ("t/d-max-incoming-edges", max_incoming_edges);
00964   K->Read ("t/d-max-path-count", max_path_count);
00965   K->Read ("t/d-saplings-by-weight", saplings_by_weight);
00966   K->Read ("t/d-setjmps", td_sj);
00967   K->Read ("hammock-do", do_hammocks);
00968   K->Read ("hammock-max-height-expansion", h_max_height_expansion);
00969   K->Read ("hammock-max-code-expansion", h_max_code_expansion);
00970   K->Read ("hammock-max-opcount", h_max_opcount);
00971   K->Read ("slr-do", do_slrs);
00972   K->Read ("use-branch-profile", use_branch_profile);
00973   K->Read ("branch-acc-file", branch_acc_file);
00974   K->Read ("branch-pt-file", branch_pt_file);
00975   K->Read ("branch-miss-predict-penalty", miss_predict_penalty);
00976 
00977   if (st != NULL)  // get original op count
00978     st->op_count += proc->GetOpCount();
00979 
00980   if (do_hammocks) mach = new machine (K);  // make machine if necessary
00981 
00982   RemoveTreeAttributes (proc);  // remove old tree attributes
00983 
00984   if (use_branch_profile) {
00985     // need to add attributes for the branch accuracies based on profiling
00986     AddBranchAccAttrs(proc, branch_pt_file, branch_acc_file);
00987   }
00988 
00989   unprocessed = new regionList ((legoRegion *) proc->GetEntryOpsPtr()
00990                                 ->GetOpPtr()->GetParentBlockPtr());
00991   unptail = unprocessed;
00992 
00993   while ( unprocessed != NULL )
00994     {
00995       // Dequeue the first region from the list.
00996       while (unprocessed != NULL && unprocessed->GetRegionPtr() == NULL)
00997         {  // skipping nullified entries
00998           dprintf ((OUTF, "treeform: Removing nullified queue entry.\n"));
00999           temp = unprocessed; unprocessed = unprocessed->GetNextListPtr();
01000           temp->SetNextListPtr (NULL); delete temp;
01001         } // end while
01002       if (unprocessed == NULL) break;
01003       dprintf(( OUTF, "treeform: Dequeueing region %d for tree building.\n",
01004                  unprocessed->GetRegionPtr()->GetRegionId() ));
01005       currentregion = unprocessed->GetRegionPtr();
01006       temp = unprocessed;
01007       unprocessed = unprocessed->GetNextListPtr();
01008       if (unprocessed == NULL) unptail = NULL;
01009       temp->SetNextListPtr (NULL);
01010       delete temp;
01011 
01012       // If the dequeued region has already been processed, continue.
01013       for (parentregion = currentregion->GetParentPtr();
01014            parentregion->GetRegionType() != RT_PROC;
01015            parentregion = parentregion->GetParentPtr())
01016         if (parentregion->GetRegionType() == RT_TREE) break;
01017 
01018       if (parentregion->GetRegionType() == RT_TREE)
01019         continue;
01020 
01021       // Make a new treegion and add it to the proc.
01022       dprintf(( OUTF, "treeform: Building new tree.\n" ));
01023       parentregion = currentregion->GetParentPtr();
01024       if (parentregion != NULL)
01025         rootindex = parentregion->Search (currentregion);
01026       else
01027         rootindex = MAX_UNSIGNED;
01028 
01029       tree = new legoTreegion (++treeid);
01030       proc->AddItem (tree);
01031       tree->SetParentPtr (proc);
01032       if (!do_slrs)
01033         Construct (tree, currentregion);
01034       else
01035         Construct (tree, currentregion, LEGOTREE_LINEAR);
01036 
01037 // 11/20/98 mdj - seems like we always want to AddItem() here. Otherwise this 
01038 // code is sensitive to the order of BB regions in a proc and crashes after 
01039 // UNBindSB(). 
01040 //      if (rootindex != MAX_UNSIGNED && parentregion->GetCount() < rootindex) {
01041 //      cerr << "\n\n\n\n*** parentregion->GetCount() = " << parentregion->GetCount() << " < rootindex = " << rootindex << " ***\n" ;
01042 //      parentregion->Insert (currentregion, rootindex);
01043 //      }
01044 //      else
01045 //      proc->AddItem (tree);
01046 //      tree->SetParentPtr (proc);
01047       
01048       for (codesizeorig = 0, i = 0; i < tree->GetCount(); i++)
01049         codesizeorig += ((legoRegion *) tree->GetItem(i))->GetCount();
01050 
01051       did_a_hammock = did_a_tail_duplication =
01052         ((do_td || do_hammocks) ? 1 : 0);
01053       did_a_tail_duplication_sometime = 0;
01054       while (did_a_hammock == 1 || did_a_tail_duplication == 1)
01055         {
01056           did_a_hammock = did_a_tail_duplication = 0;
01057           for (codesize = 0, i = 0; i < tree->GetCount(); i++)
01058             codesize += ((legoRegion *)
01059                          tree->GetItem(i))->GetCount();
01060 
01061           // === HAMMOCK CONVERSION ===
01062           // Must be modified when full hyperblocks are used in LEGO.
01063 
01064           while (do_hammocks)
01065             {
01066               // Find a sapling worthy of hammock conversion.
01067               hammock_info *hinfo;
01068               legoRegion *bestsap = NULL, *candsap, *hammock;
01069               regionList *rl;
01070               int subtreesize, hcroot;
01071 
01072               for (i = 0; i < tree->GetCount(); i++)
01073                 {
01074                   // Destroying h->S, h->T, h->E, h->J blocks seems to fuck 
01075                   // up things such as ParentBlockPtrs of Ops. So I will 
01076                   // just leave them as orphaned blocks now and mark them.
01077                   // Now need to skip these. 
01078 //                if (((legoRegion *)tree->GetItem(i))->IsMarked(RM_GENERAL))
01079 //                  continue; 
01080                   hinfo = DetectHammock ((legoRegion *) tree->GetItem(i));
01081                   if (!(hinfo->HammockDetected()))
01082                     {
01083                       delete hinfo;  // internal block or no hammock off leaf
01084                       continue;
01085                     } // end if
01086 
01087                   candsap = hinfo->J;
01088                   if (candsap->GetParentPtr()->GetRegionType() == RT_TREE)
01089                     continue;  // can't pull in a treegion root!
01090 
01091                   // Add criteria here.
01092                   if (h_max_height_expansion > 0.0)
01093                     {
01094                       dag *DAG;
01095                       VectorList::iterator Front, Back;
01096                       legoOp *hop;
01097                       int height, height_orig, height_CMPP, height_side, max;
01098 
01099                       height = 0;  // height of entire hammock
01100                       height_orig = 0;  // ht. of S - ht. of 1st CMPP in S
01101 
01102                       for (hop = (legoOp *) hinfo->S->GetItem(0);
01103                            hop->IsCMPPOp() == false;   
01104                          //HZ:   hop->GetOpcode() < CMPP ||
01105                          //    hop->GetOpcode() > FCMPP_D_TRUE_AC_AC;
01106                            hop = hop->GetNextLink()) /* do nothing */;
01107                       // hop points to first CMPP in S
01108 
01109                       // Knobs are available...
01110 #ifdef IA64_SUPPORT                   
01111                       DAG = new dag (mach, K, inp_start, inp_end, 8, 11, 8, 15);
01112 #endif
01113 #ifndef IA64_SUPPORT                  
01114                       DAG = new dag (mach, K, 0, 0, 0, 0, 0, 0);
01115 #endif
01116                       
01117                       hinfo->S->SetDAG (DAG);
01118                       DAG->ConstructDag (hinfo->S);
01119                       DAG->SetNodeHeights();
01120                       for (max = 0, Front = DAG->GetList()->begin(),
01121                              Back = DAG->GetList()->end(); Front != Back;
01122                            Front++)
01123                         {
01124                           if ((*Front).GetHeight() > max)
01125                             max = (*Front).GetHeight();
01126                           if ((*Front).GetOp() == hop)
01127                             height_CMPP = (*Front).GetHeight();
01128                         } // end for
01129                       height = max;
01130                       if (hinfo->S->GetRegionType() == RT_BB)
01131                         height_orig = max - 1; // for CMPP
01132                       else
01133                         height_orig = max - height_CMPP + 1;
01134                       dprintf ((OUTF, "treeform: S has height %d, original "
01135                                 "height %d.\n", height, height_orig));
01136                       delete DAG; hinfo->S->SetDAG (NULL);
01137 
01138                       //DAG = new dag (mach, K);
01139 #ifdef IA64_SUPPORT                   
01140                       DAG = new dag (mach, K, inp_start, inp_end, 8, 11, 8, 15);
01141 #endif
01142 #ifndef IA64_SUPPORT                  
01143                       DAG = new dag (mach, K, 0, 0, 0, 0, 0, 0);
01144 #endif
01145                       
01146                       hinfo->T->SetDAG (DAG);
01147                       DAG->ConstructDag (hinfo->T);
01148                       DAG->SetNodeHeights();
01149                       for (max = 0, Front = DAG->GetList()->begin(),
01150                              Back = DAG->GetList()->end(); Front != Back;
01151                            Front++)
01152                         if ((*Front).GetHeight() > max)
01153                           max = (*Front).GetHeight();
01154                       height_side = max;
01155                       dprintf ((OUTF, "treeform: T has height %d.\n",
01156                                 height_side));
01157                       delete DAG; hinfo->T->SetDAG (NULL);
01158 
01159                       //DAG = new dag (mach, K);
01160 #ifdef IA64_SUPPORT                   
01161                       DAG = new dag (mach, K, inp_start, inp_end, 8, 11, 8, 15);
01162 #endif
01163 #ifndef IA64_SUPPORT                  
01164                       DAG = new dag (mach, K, 0, 0, 0, 0, 0, 0);
01165 #endif
01166                       
01167                       hinfo->J->SetDAG (DAG);
01168                       DAG->ConstructDag (hinfo->J);
01169                       DAG->SetNodeHeights();
01170                       for (max = 0, Front = DAG->GetList()->begin(),
01171                              Back = DAG->GetList()->end(); Front != Back;
01172                            Front++)
01173                         if ((*Front).GetHeight() > max)
01174                           max = (*Front).GetHeight();
01175                       height += max;
01176                       dprintf ((OUTF, "treeform: New S+J height is %d.\n",
01177                                 height));
01178                       delete DAG; hinfo->J->SetDAG (NULL);
01179 
01180                       if (!(hinfo->IsDelta()))
01181                         {
01182                           //DAG = new dag (mach, K);
01183 #ifdef IA64_SUPPORT                   
01184                               DAG = new dag (mach, K, inp_start, inp_end, 8, 11, 8, 15);
01185 #endif
01186 #ifndef IA64_SUPPORT                  
01187                               DAG = new dag (mach, K, 0, 0, 0, 0, 0, 0);
01188 #endif
01189                             
01190                           hinfo->E->SetDAG (DAG);
01191                           DAG->ConstructDag (hinfo->E);
01192                           DAG->SetNodeHeights();
01193                           for (max = 0, Front = DAG->GetList()->begin(),
01194                                  Back = DAG->GetList()->end(); Front != Back;
01195                                Front++)
01196                             if ((*Front).GetHeight() > max)
01197                               max = (*Front).GetHeight();
01198                           if (max > height_side)
01199                             height_side = max;
01200                           dprintf ((OUTF, "treeform: New (E) side height "
01201                                     "is %d.\n", height_side));
01202                           delete DAG; hinfo->E->SetDAG (NULL);
01203                         } // end if
01204 
01205                       height += height_side;
01206                       dprintf ((OUTF, "treeform: Final height is %d.\n",
01207                                 height));
01208                       if ((double) height > (double) height_orig *
01209                           h_max_height_expansion) continue;
01210                     } // end if
01211 
01212                   if (h_max_code_expansion > 0.0)
01213                     {
01214                       int opct_orig, opct;
01215                       legoOprd *oprd;
01216 
01217                       if (hinfo->S->GetRegionType() != RT_HB)
01218                         {
01219                           opct_orig = hinfo->S->GetCount();
01220                         } // end if
01221                       else
01222                         {
01223                           opct_orig = 1;  // count branch eliminated before
01224                           // Count ops up to the first predicated op.
01225                           legoOp *tempop = (legoOp *) (hinfo->S->GetItem(0));
01226                           oprd = tempop->GetPredOprdPtr();
01227                           for (int j = 0; j < hinfo->S->GetCount(); j++)
01228                             {
01229                               if (oprd != NULL && oprd->GetOprdType()
01230                                   != OT_LITERAL_P)
01231                                 break;
01232                               tempop = tempop->GetNextLink();
01233                               oprd = tempop->GetPredOprdPtr();
01234                               opct_orig++;
01235                             } // end for
01236                         } // end else
01237 
01238                       opct = hinfo->S->GetCount() + hinfo->T->GetCount()
01239                         + hinfo->J->GetCount() - 6;
01240                       if (!(hinfo->IsDelta()))
01241                         opct += (hinfo->E->GetCount() - 3);
01242                       if ((double) opct > (double) opct_orig *
01243                           h_max_code_expansion) continue;
01244                     } // end if
01245 
01246                   if (h_max_opcount > 0.0) {
01247                     if (hinfo->T->GetOpCount() > h_max_opcount) continue;
01248                     if (!(hinfo->IsDelta()))
01249                       if (hinfo->E->GetOpCount() > h_max_opcount) continue;
01250                   }
01251 
01252                   bestsap = candsap; break;  // passes all tests => OK
01253                 } // end for
01254               if (bestsap == NULL)
01255                 {
01256                   dprintf((OUTF,"treeform: Could not find sapling worthy of "
01257                            "hammock conversion.\n"));
01258                   break;  // out of for loop
01259                 } // end if
01260 
01261               dprintf ((OUTF, "treeform: Merge targeted for h-c is %d.\n",
01262                         bestsap->GetRegionId()));
01263 
01264               // Hammock convert, then continue construction.
01265               hcroot = (tree->GetRoot() == hinfo->S);
01266               // Before continuing, remove hinfo->S and hinfo->J from the
01267               // unprocessed queue so they don't try to spawn new treegions.
01268               for (temp = unprocessed; temp != NULL;
01269                    temp = temp->GetNextListPtr())
01270                 if (temp->GetRegionPtr() == hinfo->J ||
01271                     temp->GetRegionPtr() == hinfo->S)
01272                   {
01273                     dprintf ((OUTF, "treeform: Nullifying queue entry for "
01274                               "region %d.\n",
01275                               temp->GetRegionPtr()->GetRegionId()));
01276                     temp->SetRegionPtr (NULL);
01277                   } // end if
01278               if ((hammock = IfConvertHammock (hinfo, K)) == NULL)
01279                 {
01280                   dprintf ((OUTF, "treeform: Hammock conversion failed.\n"));
01281                   exit (10);
01282                   break;
01283                 } // end if
01284               if (did_a_hammock == 0)
01285                 {
01286                   did_a_hammock = 1;
01287                   AddFlag (HAS_HB, proc);
01288                 } // end if
01289               if (hcroot) tree->SetRoot (hammock);
01290               ContinueConstruction (tree);  // continue building the tree
01291 
01292             } // end while
01293 
01294           // === END HAMMOCK CONVERSION ===
01295 
01296           // === TAIL DUPLICATION ===
01297 
01298           // If we can tail-duplicate, try it here and continue construction.
01299           while (do_td)
01300             {
01301               // Find a sapling worthy of tail duplication.
01302               legoRegion *bestsap = NULL, *bestsapparent = NULL, *duplicate,
01303                 *candsap;
01304               regionList *rl;
01305               edgeList *el;
01306               opEdges *edge;
01307               int qualifies, i;
01308               double maxsapweight = -1.0;
01309 
01310               saplist = tree->GetSaplings();
01311               if (saplist == NULL) break;
01312 
01313               if (max_path_count > 0)
01314                 {
01315                   opList *opl;
01316 
01317                   tree->RefreshExitOps();
01318                   for (i = 0, opl = tree->GetExitOpsPtr(); opl != NULL;
01319                        i++, opl = opl->GetNextListPtr()) /* do nothing */;
01320                   if (i > max_path_count)
01321                     {
01322                       dprintf ((OUTF, "treeform: Ending tail duplication "
01323                                 "with %d paths.\n", i));
01324                       break;
01325                     } // end if
01326                 } // end if
01327 
01328               for (temp = saplist; temp != NULL; temp = temp->GetNextListPtr())
01329                 {
01330                   candsap = temp->GetRegionPtr();
01331 
01332                   // Destroying h->S, h->T, h->E, h->J blocks seems to fuck 
01333                   // up things such as ParentBlockPtrs of Ops. So I will 
01334                   // just leave them as orphaned blocks now and mark them.
01335                   // Now need to skip these. 
01336 //                if (candsap->IsMarked(RM_GENERAL))
01337 //                  continue; 
01338                   
01339                   if (candsap->GetParentPtr()->GetRegionType() != RT_PROC)
01340                     continue;  // sapling can't be in treegion already
01341 
01342                   if (saplings_by_weight &&
01343                       candsap->GetWeight() <= maxsapweight)
01344                     continue;  // use highest weight sapling
01345 
01346                   // Treegion must end with a block containing a setjmp. Don't 
01347                   // Continue duplication after a setjmp. 
01348                   if (FindLcAttribute( "set_jmp_present", 
01349                                       candsap->GetParents()->GetRegionPtr())
01350                       != NULL) 
01351                     continue;  
01352 
01353                   if (!td_sj)  // look for setjmp
01354                     {
01355                       legoOp *sjop;
01356                       legoOprd *sjoprd = NULL;
01357 
01358                       for (sjop = candsap->GetEntryOpsPtr()->GetOpPtr();
01359                            sjop != NULL; sjop = sjop->GetNextLink())
01360                         {
01361                           if (sjop->IsPBRROp() == false) continue;
01362                               //sjop->GetOpcode() != PBRR) continue;
01363                           sjoprd = sjop->GetSrcOprdPtr();
01364                           if (sjoprd->GetOprdType() != OT_LITERAL_L) continue;
01365                           if (strstr (sjoprd->GetLiteralLabel(), "setjmp")
01366                               != NULL) break;  // found setjmp
01367                           else
01368                             sjoprd = NULL;
01369                         } // end for
01370                       if (sjoprd != NULL) continue;
01371                     } // end if
01372 
01373                   if (max_code_expansion > 0.0)
01374                     {
01375                       if ((double) (codesize + 2 * candsap->GetCount()) >
01376                           max_code_expansion * ((double) codesizeorig))
01377                         continue;  // can't exceed code expansion limits
01378                     } // end if
01379 
01380                   //              candsap->SetChildren (NULL);
01381                   if (candsap->GetChildren() == NULL)
01382                     {
01383                       bestsap = candsap;  // if end of proc, definitely!
01384                       if (saplings_by_weight) continue;
01385                       else break;
01386                     } // end if
01387 
01388                   if (do_cascades)
01389                     {
01390                       for (i = 0, rl = candsap->GetChildren(); rl != NULL;
01391                            rl = rl->GetNextListPtr()) i++;
01392                       if (i == 1)  // if merge leads only to one place and ...
01393                         {
01394                           for (i = 0,
01395                                  rl = candsap->GetChildren()->GetRegionPtr()
01396                                  ->GetParents(); rl != NULL;
01397                                rl = rl->GetNextListPtr()) i++;
01398                           if (i > 1)
01399                             {
01400                               bestsap = candsap;  // if merge cascade, yes!
01401                               break;
01402                             } // end if
01403                         } // end if
01404                     } // end if
01405 
01406                   qualifies = 1;
01407                   for (rl = candsap->GetParents(); rl != NULL;
01408                        rl = rl->GetNextListPtr())
01409                     {
01410                       if (rl->GetRegionPtr()->GetParentPtr() !=
01411                           (legoRegion *) tree)
01412                         qualifies = 0;  // sapling no parents outside tree
01413                     } // end for
01414                   if (!qualifies) continue;
01415 
01416                   if (max_incoming_edges >= 2)
01417                     {
01418                       for (i = 0, el = candsap->GetInEdgesPtr(); el != NULL;
01419                            el = el->GetNextListPtr()) i++;
01420                       if (i > max_incoming_edges)
01421                         continue;  // can't have too many inedges
01422                     } // end if
01423 
01424                   bestsap = candsap;  // passes all tests => OK
01425                   if (!saplings_by_weight) break;
01426                   maxsapweight = candsap->GetWeight(); continue;
01427                 } // end for
01428               if (bestsap == NULL)
01429                 {
01430                   dprintf((OUTF,"treeform: Could not find sapling worthy of "
01431                            "tail duplication.\n"));
01432                   break;  // out of for loop
01433                 } // end if
01434 
01435               dprintf ((OUTF, "treeform: Merge targeted for t-d is %d.\n",
01436                         bestsap->GetRegionId()));
01437 
01438               // Find some parent of bestsap in the tree.
01439               for (temp = bestsap->GetParents(); temp != NULL;
01440                    temp = temp->GetNextListPtr())
01441                 {
01442                   if (!(temp->GetRegionPtr()->IsContainedIn (tree)))
01443                     continue;  // parent must be in tree
01444                   bestsapparent = temp->GetRegionPtr(); break;
01445                 } // end for
01446               if (bestsapparent == NULL)
01447                 {
01448                   LegoNonFatal ("treeform", "Could not find parent of "
01449                            "sapling %d worthy of tail duplication.",
01450                            bestsap->GetRegionId());
01451                   break;  // out of for loop
01452                 } // end if
01453               dprintf ((OUTF, "treeform: T-d off block %d.\n",
01454                         bestsapparent->GetRegionId()));
01455 
01456               // Find the op in bestsapparent leading to the sapling.
01457               for (el = bestsapparent->GetOutEdgesPtr(); el != NULL;
01458                    el = el->GetNextListPtr())
01459                 {
01460                   edge = el->GetEdgePtr();
01461                   if ((legoRegion *) (edge->GetToOpPtr()->GetParentBlockPtr())
01462                       == bestsap)
01463                     break;
01464                 } // end for
01465               if (el == NULL)
01466                 {
01467                   LegoNonFatal ("treeform", "Could not find exit op of "
01468                            "parent of sapling %d worthy of tail "
01469                            "duplication.", bestsap->GetRegionId());
01470                   break;  // out of for loop
01471                 } // end if
01472 
01473               // Tail duplicate, and add duplicate to bestsap's container.
01474               duplicate = TailDuplicate (bestsap, edge);
01475               //duplicate = bestsap->TailDuplicate (edge);
01476               //          bestsap->GetParentPtr()->AddItem (duplicate);
01477               //          duplicate->SetParentPtr (bestsap->GetParentPtr());
01478               if (duplicate == NULL)
01479                 {
01480                   dprintf ((OUTF, "treeform: Tail duplication failed.\n"));
01481                   exit (10);
01482                   break;
01483                 } // end if
01484               if (duplicate == bestsap)
01485                 dprintf ((OUTF, "treeform: Ah! Worthy sapling isn't "
01486                           "merge!\n"));
01487               else
01488                 {
01489                   legoOprd *mapoprd;
01490                   attrs *oldattr;
01491 
01492                   mapoprd = new legoOprd;
01493                   mapoprd->SetOprdType (OT_LITERAL_I);
01494                   oldattr = FindLcAttribute ("blockmap", bestsap);
01495                   if (oldattr == NULL)
01496                     mapoprd->SetLiteralInteger (bestsap->GetRegionId());
01497                   else
01498                     mapoprd->SetLiteralInteger (oldattr->GetAttrOprdPtr()
01499                                                 ->GetLiteralInteger());
01500                   AddLcAttribute ("blockmap", mapoprd, duplicate, proc);
01501                   int removed = RemoveUncondBranch(duplicate);
01502                   if (removed) {
01503                     for (temp = unprocessed; temp != NULL;
01504                          temp = temp->GetNextListPtr())
01505                       if (temp->GetRegionPtr() == duplicate )
01506                         {
01507                           dprintf ((OUTF, "treeform: Nullifying queue entry for "
01508                                     "region %d.\n",
01509                                     duplicate->GetRegionId()));
01510                           temp->SetRegionPtr (NULL);
01511                         } // end if
01512                   }
01513                   removed = RemoveUncondBranch(bestsap);
01514                   if (removed) {
01515                     for (temp = unprocessed; temp != NULL;
01516                          temp = temp->GetNextListPtr())
01517                       if (temp->GetRegionPtr() == bestsap )
01518                         {
01519                           dprintf ((OUTF, "treeform: Nullifying queue entry for "
01520                                     "region %d.\n",
01521                                     bestsap->GetRegionId()));
01522                           temp->SetRegionPtr (NULL);
01523                         } // end if
01524                   }
01525                 } // end else
01526 
01527               dprintf ((OUTF, "treeform: Duplicate is block %d.\n",
01528                         duplicate->GetRegionId()));
01529 
01530               did_a_tail_duplication = 1;
01531               did_a_tail_duplication_sometime = 1;
01532               ContinueConstruction (tree);  // continue building the tree
01533 
01534             } // end while
01535           // === END TAIL DUPLICATION ===
01536         } // end big while loop
01537 
01538       if (st != NULL)
01539         {
01540           legoRegion *block;
01541           int i;
01542           long opct;
01543           double rtwt;
01544 
01545           st->tree_count++;
01546           st->block_count += tree->GetCount();
01547           
01548           for (exitopl = tree->GetExitOpsPtr(); 
01549                exitopl != NULL;
01550                exitopl = exitopl->GetNextListPtr()) {
01551             // cerr << "\nExit op (OpId = " << exitopl->GetOpPtr()->GetOpId() << ")\n";
01552             st->path_count++;
01553             // Assuming only one exit op per block at this point 
01554             // (during treeform)
01555             if (exitopl->GetOpPtr()->IsBRCONDOp()
01556                 //HZ:    (exitopl->GetOpPtr()->GetOpcode() == BRCT) || 
01557                 //(exitopl->GetOpPtr()->GetOpcode() == BRCF)
01558                     ) {
01559               weight = 0;
01560               for (out_cmerges = exitopl->GetOpPtr()->GetOutListPtr();
01561                    out_cmerges != NULL;
01562                    out_cmerges = out_cmerges->GetNextListPtr()) {
01563                 if ((((legoRegion *) out_cmerges->GetOpPtr()
01564                       ->GetParentBlockPtr())->GetParentPtr() != tree) || 
01565                     (((legoRegion *) out_cmerges->GetOpPtr()
01566                       ->GetParentBlockPtr()) == tree->GetRoot())) {
01567                   exit_edge = FindControlEdge(exitopl->GetOpPtr(), 
01568                                               out_cmerges->GetOpPtr(), 1);
01569                   frequency = (double) FindEdgeFrequency(exit_edge);
01570                   if (frequency == -1) {
01571                     LegoNonFatal ("treeform", "Edge has no frequency.\n");
01572                   }
01573                   weight += frequency;
01574                 }
01575               }
01576             }
01577             else { // BRUs, DUMMY_BRs, RTSs always fully exit treegion
01578               weight = ((legoRegion *) exitopl->GetOpPtr()->GetParentBlockPtr())->GetWeight();
01579             }
01580             // cerr << "Weight = " << weight << "\n";
01581             st->dynamic_path_count += weight; 
01582             // Find the number of blocks in this path
01583             for (block_count = 1, 
01584                  root_block_ptr = tree->GetRoot(), 
01585                  block_ptr = (legoRegion *) exitopl->GetOpPtr()->GetParentBlockPtr();
01586                  block_ptr != root_block_ptr; 
01587                  block_count++, 
01588                  block_ptr = block_ptr->GetParents()->GetRegionPtr()) {
01589               ; // Just count blocks
01590             }
01591             // cerr << "Blocks in path = " << block_count << "\n";          
01592             st->path_blocks += block_count; 
01593             st->dynamic_path_blocks += (block_count * weight);
01594           }
01595           
01596           rtwt = tree->GetRoot()->GetWeight();
01597           opct = 0;
01598           if (tree->GetCount() >= WTSIZE)
01599             {
01600               LegoFatal ("treeform", "%d blocks in tree is too big. "
01601                          "Recompile with a larger value of WTSIZE.",
01602                          tree->GetCount());
01603               //              exit(2);
01604             } // end if
01605           (st->block_stats[tree->GetCount()].i)++;
01606           (st->block_stats[tree->GetCount()].d) += rtwt;
01607           for (i = 0; i < tree->GetCount(); i++)
01608             {
01609               block = (legoRegion *) tree->GetItem(i);
01610               opct += block->GetOpCount();
01611               st->op_count_expanded += block->GetOpCount();
01612             } // end for
01613           if (opct >= WTSIZE)
01614             {
01615               LegoFatal ("treeform", "%d ops in tree is too big. "
01616                          "Recompile with a larger value of WTSIZE.",
01617                          opct);
01618               //              exit(2);
01619             } // end if
01620           (st->op_stats[opct].i)++;
01621           (st->op_stats[opct].d) += rtwt;
01622           st->total_weight += rtwt;
01623           
01624         } // end if
01625 
01626       
01627       //HZ: 
01628       //In the finding of the best treegion dup candidates, the procedure
01629       // treeform will be called several times
01630       // If I do this fullyresolePredicates very time, I will end up with
01631       // duplicated CMPPs in duplicated treegions:
01632       //e.g. tree1 has an CMPP <p112, p113> = ..., p111 in BB a and 
01633       //               an duped CMPP <p112, p113> = ..., p115 in BB b
01634       // Then in scheduling, if these two CMPPs are moved in the same BB, this
01635       // output deps will mess the program semantics.
01636       
01637       //So I will delay this fullyresolvepredicates call until the last time by
01638       //using a parameter final
01639       //
01640       
01641       // FullyResolvePredicates in the new treegion
01642       ClearMarks (RM_GENERAL, tree);
01643       if(final == true)
01644       {
01645           FullyResolvePredicates( tree->GetRoot(), NULL );
01646           ClearMarks (RM_GENERAL, tree);
01647       }
01648 
01649       // Add tree attributes to regions in treegion.
01650       for (i = 0; i < tree->GetCount(); i++)
01651         {
01652           legoOprd *treeidoprd, *oprd;
01653 
01654           treeidoprd = new legoOprd();
01655           treeidoprd->SetOprdType (OT_LITERAL_I);
01656           treeidoprd->SetLiteralInteger (treeid);
01657           if ((legoRegion *) tree->GetItem(i) == tree->GetRoot())
01658             {  // mark root!
01659               oprd = treeidoprd->AddOprd();
01660               oprd->SetOprdType (OT_LITERAL_I);
01661               oprd->SetLiteralInteger (1);
01662             } // end if
01663           AddLcAttribute ("tree", treeidoprd,
01664                           (legoRegion *) tree->GetItem(i), proc);
01665         } // end for
01666 
01667       // Add all saplings not in a tree already to the unprocessed list.
01668 
01669       for (saplist = tree->GetSaplings(); saplist != NULL;
01670            saplist = saplist->GetNextListPtr())
01671         {
01672           dprintf(( OUTF, "treeform: Examining sapling region %d.\n",
01673                      saplist->GetRegionPtr()->GetRegionId() ));
01674 
01675           // If the sapling belongs to another tree, continue.
01676           for (parentregion = saplist->GetRegionPtr()->GetParentPtr();
01677                parentregion->GetRegionType() != RT_PROC;
01678                parentregion = parentregion->GetParentPtr())
01679             if (parentregion->GetRegionType() == RT_TREE) break;
01680 
01681           if (parentregion->GetRegionType() == RT_TREE)
01682             continue;
01683 
01684           // Enqueue the unprocessed sapling into the list.
01685           dprintf(( OUTF, "treeform: Enqueueing sapling region %d.\n",
01686                      saplist->GetRegionPtr()->GetRegionId() ));
01687           temp = new regionList (saplist->GetRegionPtr());
01688 
01689           if ( unptail == NULL )
01690             unptail = unprocessed = temp;
01691           else
01692             {
01693               unptail->SetNextListPtr (temp);
01694               unptail = temp;
01695             } // end else
01696         } // end for
01697 
01698       treeid = (proc->FindMaxRegionId())->GetRegionId();  // next id (-1)
01699     } // end while
01700   
01701   if (did_a_tail_duplication_sometime)
01702     {
01703       dprintf ((OUTF, "treeform: Refreshing all.\n"));
01704       proc->RefreshAll();
01705     } // end if
01706 
01707   delete mach;  // destroy machine
01708 
01709   dprintf(( OUTF, "treeform: Done with proc %s.\n\n", proc->GetProcName() ));
01710 
01711   AddBBIdAttribute(proc);  // Emre Ozer: Attach  an attribute of original BB ids to each Op in a treegion    
01712     
01713   //HZ: Set all the weights of the treegions
01714   for(int tree_i = 0; tree_i < proc->GetCount(); tree_i++)
01715   {
01716       legoTreegion * tree1_ptr = (legoTreegion *)proc->GetItem(tree_i);
01717       tree1_ptr->SetWeight(tree1_ptr->GetRoot()->GetWeight());
01718   }
01719   if(proc->GetWeight() == 0)
01720       proc->SetWeight(((legoTreegion *)proc->GetItem(0))->GetWeight());
01721   
01722   return;
01723 } // end treeform
01724 
01725 /*
01726  * RegionTreeUnform
01727  *   region = region to look within for treegions
01728  *
01729  * Searches region and (recursively) components for treegions and deconstructs
01730  * those it finds.
01731  */
01732 static void
01733 RegionTreeUnform (legoRegion *region)
01734 {
01735   int i;
01736   unsigned treeloc;
01737   legoRegion *component;
01738 
01739   for (i = 0; i < region->GetCount(); i++)
01740     {
01741       component = (legoRegion *) region->GetItem (i);
01742       switch (component->GetRegionType())
01743         {
01744         case RT_BB:
01745         case RT_SB:
01746         case RT_HB:
01747           break;
01748         case RT_LOOP:
01749         case RT_LOOPBODY:
01750         case RT_TRACE:
01751           RegionTreeUnform (component);
01752           break;
01753         case RT_TREE:
01754           // Deconstruct!
01755           Deconstruct ((legoTreegion *) component);
01756           treeloc = region->Search (component);
01757           if (treeloc == MAX_UNSIGNED)
01758             {
01759               LegoNonFatal ("RegionTreeUnform", "Can't find treegion %d in "
01760                             "region %d.\b", component->GetRegionId(),
01761                             region->GetRegionId());
01762               break;
01763             } // end if
01764           region->Detach (treeloc);
01765           delete component;
01766           i = -1; break;  // reset for loop
01767         } // end switch
01768     } // end for
01769 
01770   return;
01771 } // end RegionTreeUnform
01772 
01773 /*
01774  * treeunform
01775  *   proc = procedure within which to unform treegions
01776  *
01777  * Removes treegions from a procedure via deconstruction.
01778  */
01779 void
01780 treeunform (legoProc *proc)
01781 {
01782   RegionTreeUnform (proc);
01783 
01784   // Before we quit, unflag the proc.
01785   RemoveFlag (HAS_TREE, proc);
01786   return;
01787 } // end treeunform
01788 
01789 /*
01790  * RegionTreeReform
01791  *   region = region to look within for treegions
01792  *   st = see tracereform
01793  *
01794  * Searches region and (recursively) components for treegion roots and
01795  * reconstructs those it can.
01796  */
01797 static void
01798 RegionTreeReform (legoRegion *region, tree_stats *st)
01799 {
01800   int i;
01801   legoRegion *component;
01802 
01803   for (i = 0; i < region->GetCount(); i++)
01804     {
01805       component = (legoRegion *) region->GetItem (i);
01806       switch (component->GetRegionType())
01807         {
01808         case RT_BB:
01809         case RT_SB:
01810         case RT_HB:
01811           {
01812             legoTreegion *tree;
01813             legoRegion *parentregion;
01814             attrs *treeattr;
01815             legoOprd *treeattroprd;
01816             unsigned treeloc;
01817 
01818             dprintf ((OUTF, "treereform: Looking at block %d.\n",
01819                       component->GetRegionId()));
01820             treeattr = FindLcAttribute ("tree", component);
01821             if (treeattr == NULL)
01822               {
01823                 dprintf ((OUTF, "treereform: No tree attribute found.\n"));
01824                 break;
01825               } // end if
01826             treeattroprd = treeattr->GetAttrOprdPtr();
01827             if (treeattroprd == NULL ||
01828                 treeattroprd->GetNextOprdPtr() == NULL ||
01829                 treeattroprd->GetNextOprdPtr()->GetLiteralInteger() != 1)
01830               {
01831                 dprintf ((OUTF, "treereform: Tree attribute found, but "
01832                           "not root.\n"));
01833                 break;
01834               } // end if
01835 
01836             // Make a new treegion and add it to the proc.
01837             dprintf(( OUTF, "treereform: Building new treegion.\n" ));
01838             parentregion = component->GetParentPtr();
01839             if (parentregion != NULL)
01840               treeloc = parentregion->Search (component);
01841             else
01842               treeloc = MAX_UNSIGNED;
01843 
01844             tree = new legoTreegion (0);  // temporary id - Reconstruct gets it
01845             Reconstruct (tree, component);
01846             dprintf(( OUTF, "treereform: Treegion location is index %u.\n",
01847                       treeloc));
01848             if (treeloc != MAX_UNSIGNED)
01849               parentregion->Insert (tree, treeloc);
01850             else
01851               parentregion->AddItem (tree);
01852             tree->SetParentPtr (parentregion);
01853 
01854             if (st != NULL)
01855               {
01856                 legoRegion *block;
01857                 int i;
01858                 long opct;
01859                 double rtwt;
01860 
01861                 st->tree_count++;
01862                 st->block_count += tree->GetCount();
01863                 rtwt = tree->GetRoot()->GetWeight();
01864                 opct = 0;
01865                 if (tree->GetCount() >= WTSIZE)
01866                   {
01867                     LegoFatal ("treereform", "%d blocks in tree is too "
01868                                "big. Recompile with a larger value of "
01869                                "WTSIZE.", tree->GetCount());
01870                     //              exit(2);
01871                   } // end if
01872                 (st->block_stats[tree->GetCount()].i)++;
01873                 (st->block_stats[tree->GetCount()].d) += rtwt;
01874                 for (i = 0; i < tree->GetCount(); i++)
01875                   {
01876                     block = (legoRegion *) tree->GetItem(i);
01877                     opct += block->GetOpCount();
01878                     st->op_count_expanded += block->GetOpCount();
01879                   } // end for
01880                 if (opct >= WTSIZE)
01881                   {
01882                     LegoFatal ("treereform", "%d ops in tree is too "
01883                                "big. Recompile with a larger value of "
01884                                "WTSIZE.", opct);
01885                     exit(2);
01886                   } // end if
01887                 (st->op_stats[opct].i)++;
01888                 (st->op_stats[opct].d) += rtwt;
01889                 st->total_weight += rtwt;
01890               } // end if
01891 
01892           } // end block
01893           break;
01894         case RT_LOOP:
01895         case RT_LOOPBODY:
01896         case RT_TRACE:
01897           RegionTreeReform (component, st);
01898           break;
01899         case RT_TREE:
01900           break;  // already done!
01901         } // end switch
01902     } // end for
01903 
01904   return;
01905 } // end RegionTreeUnform
01906 
01907 /*
01908  * treereform
01909  *   proc = procedure within which to reform treegions
01910  *   st = statistics of traces formed
01911  *
01912  * Adds treegions to a procedure via reconstruction.
01913  */
01914 void
01915 treereform (legoProc *proc, tree_stats *st = NULL)
01916 {
01917   dprintf(( OUTF, "treereform: In proc %s...\n", proc->GetProcName() ));
01918   // Before we begin, flag the proc.
01919   AddFlag (HAS_TREE, proc);
01920 
01921   RegionTreeReform (proc, st);
01922   return;
01923 } // end treereform
01924 
01925 
01926 
01927 //HZ:
01928 void copy_opEdges(opEdges * orig, opEdges * dest, 
01929         int newEdgeId = -1, int newFromOpId = -1,
01930           legoOp *newFromOpPtr = NULL, int newToOpId = -1,
01931           legoOp *newToOpPtr = NULL)
01932 {
01933     //    fprintf(stderr,"Creating OPEDGES %p\n",this);
01934     dest->SetEdgeType(orig->GetEdgeType());
01935     if (newEdgeId != -1)
01936       dest->SetEdgeId(newEdgeId);
01937     else
01938       dest->SetEdgeId(orig->GetEdgeId());  
01939     dest->SetOldEdgeId(orig->GetOldEdgeId());
01940     if (newFromOpId != -1)
01941       dest->SetFromOpId(newFromOpId);
01942     else
01943       dest->SetFromOpId(orig->GetFromOpId()); 
01944     if (newFromOpPtr != NULL)
01945       dest->SetFromOpPtr(newFromOpPtr);
01946     else
01947       dest->SetFromOpPtr(orig->GetFromOpPtr());
01948     dest->SetSrcPort(orig->GetSrcPort());
01949     dest->SetAltSrcPort(orig->GetAltSrcPort());
01950     dest->SetSrcPortType(orig->GetSrcPortType());
01951     if (newToOpId != -1)
01952       dest->SetToOpId(newToOpId);
01953     else
01954       dest->SetToOpId(orig->GetToOpId());  
01955     if (newToOpPtr != NULL)
01956       dest->SetToOpPtr(newToOpPtr);
01957     else
01958       dest->SetToOpPtr(orig->GetToOpPtr());  
01959     dest->SetDestPort(orig->GetDestPort());
01960     dest->SetAltDestPort(orig->GetAltDestPort());
01961     dest->SetDestPortType(orig->GetDestPortType());
01962     dest->SetEdgeUsage(orig->GetEdgeUsage());
01963     dest->SetEdgeStatus(orig->GetEdgeStatus());
01964     dest->SetEdgeLat(orig->GetEdgeLat());
01965     dest->SetEdgeOmega(orig->GetEdgeOmega());
01966     if (orig->GetEdgeAttrListPtr() != NULL)
01967       dest->SetEdgeAttrListPtr(new attrList (*(orig->GetEdgeAttrListPtr())));
01968     else
01969       dest->SetEdgeAttrListPtr(NULL);
01970 //    dest->SetMarkfield(orig->GetMarkfield());
01971     dest->SetNextOpEdgePtr(NULL);  // will be changed anyway
01972 }       
01973 
01974 //Calculate the estimated execution time of the treegion constructed from
01975 // par_tree with tail duplication of cand_tree.
01976 // 1. calculate the ave. max dependence height of the treegion constructed from
01977 // par_tree with tail duplication of cand_tree. Considering the generic case,
01978 // the cand_tree duplication could duplicate the whole cand_tree or just the
01979 // root of the cand_tree (selected by parameter dup_tree).                      
01980 // The parameter proc is the parent ptr containing both par_tree and cand_tree.
01981 // 2. Calculate the width effect of the resource contention
01982 // 3. Calculate the estimated execution time 
01983 double tree_est_time(legoProc * proc, legoTreegion * par_tree, legoTreegion *
01984         cand_tree, legoTreegion * par_tree2, knobs *K, tree_stats *st, int td_type)
01985 {
01986     int inp_start = FindFirstOutGoingReg(proc);
01987     int inp_end = FindLastOutGoingReg(proc);
01988         
01989     legoModule * modu_tmp = new legoModule;
01990     modu_tmp->AddItem(proc);
01991     LegoWrite(modu_tmp, "temp_temp.el");
01992     modu_tmp->Detach(0); //detach the proc
01993     delete modu_tmp;
01994     modu_tmp = new legoModule;
01995     LegoRead("temp_temp.el", modu_tmp);
01996     legoProc * proc_tmp = (legoProc *) modu_tmp->GetItem(0);
01997     legoTreegion * tree_p = NULL;
01998     legoTreegion * tree_c = NULL;
01999     legoTreegion * tree_p2 = NULL;
02000     int i;
02001     for(i = 0; i < proc_tmp->GetCount(); i++)
02002     {
02003         if(((legoTreegion *) proc_tmp->GetItem(i))->GetRegionId() == par_tree->GetRegionId())
02004             tree_p = (legoTreegion *) proc_tmp->GetItem(i);
02005         if(((legoTreegion *) proc_tmp->GetItem(i))->GetRegionId() == cand_tree->GetRegionId())
02006             tree_c = (legoTreegion *) proc_tmp->GetItem(i);
02007         if(td_type == 3)
02008         {
02009             if(((legoTreegion *) proc_tmp->GetItem(i))->GetRegionId() == par_tree2->GetRegionId())
02010                 tree_p2 = (legoTreegion *) proc_tmp->GetItem(i);
02011         }
02012         if(td_type !=3 && tree_p && tree_c) break;
02013         if(td_type == 3 && tree_p && tree_c && tree_p2) break;
02014     }
02015     
02016     legoRegion * root1 = tree_p->GetRoot();
02017     legoRegion * root2 = tree_c->GetRoot();
02018     
02019     legoRegion * root3 = NULL;
02020     if(td_type == 3)
02021         root3 = tree_p2->GetRoot();
02022         
02023 /*              
02024     //1. Construct a new legoProc containing only par_tree and cand_tree
02025     legoModule * modu_tmp = new legoModule();
02026     legoProc * proc_tmp = new legoProc(proc->GetProcName(), 1);
02027     
02028     modu_tmp->AddItem(proc_tmp);
02029     proc_tmp->SetParentPtr(modu_tmp);
02030     proc_tmp->SetWeight(proc->GetWeight());
02031     
02032     legoTreegion * tree_p = new legoTreegion(1);
02033     legoTreegion * tree_c = new legoTreegion(2);
02034     
02035     proc_tmp->AddItem(tree_p);
02036     tree_p->SetParentPtr(proc_tmp);
02037     tree_p->SetWeight(par_tree->GetWeight());
02038     proc_tmp->AddItem(tree_c);       
02039     tree_c->SetParentPtr(proc_tmp);
02040     tree_c->SetWeight(cand_tree->GetWeight());
02041     
02042     //1a. copy all the BBs and the ops
02043     int bb_i;
02044     legoOp * bb_prev_op = NULL;
02045     for(bb_i = 0; bb_i < par_tree->GetCount(); bb_i++)
02046     {
02047         legoBB * bb_t = (legoBB *) par_tree->GetItem(bb_i);
02048         legoBB * bb_p = new legoBB(bb_t->GetRegionId());
02049         for(int op_i =0; op_i < bb_t->GetCount(); op_i++)
02050         {
02051             legoOp *op_p = new legoOp(0);
02052             copy_legoOp((legoOp *)bb_t->GetItem(op_i), op_p);
02053             op_p->SetParentBlockPtr(bb_p);
02054             bb_p->AddItem(op_p);
02055             if(op_i != 0)
02056             {
02057                 op_p->SetPrevLink(bb_prev_op);
02058                 bb_prev_op->SetNextLink(op_p);
02059                 op_p->SetListOpPtr(bb_prev_op);
02060             }
02061             else
02062                 op_p->SetListOpPtr(NULL);
02063             bb_prev_op = op_p;
02064         }
02065         bb_p->SetWeight(bb_t->GetWeight());
02066         tree_p->AddItem(bb_p);
02067         bb_p->SetParentPtr(tree_p);
02068     }
02069     
02070     tree_p->SetRoot((legoRegion *)tree_p->GetItem(0));
02071     
02072     for(bb_i = 0; bb_i < cand_tree->GetCount(); bb_i++)
02073     {
02074         legoBB * bb_t = (legoBB *) cand_tree->GetItem(bb_i);
02075         legoBB * bb_p = new legoBB(bb_t->GetRegionId());
02076         for(int op_i =0; op_i < bb_t->GetCount(); op_i++)
02077         {
02078             legoOp *op_p = new legoOp(0);
02079             copy_legoOp((legoOp *)bb_t->GetItem(op_i), op_p);
02080             op_p->SetParentBlockPtr(bb_p);
02081             bb_p->AddItem(op_p);
02082             if(op_i != 0)
02083             {
02084                 op_p->SetPrevLink(bb_prev_op);
02085                 bb_prev_op->SetNextLink(op_p);
02086                 op_p->SetListOpPtr(bb_prev_op);
02087             }
02088             else
02089                 op_p->SetListOpPtr(NULL);
02090             bb_prev_op = op_p;
02091         }
02092         bb_p->SetWeight(bb_t->GetWeight());
02093         tree_c->AddItem(bb_p);
02094         bb_p->SetParentPtr(tree_c);
02095     }
02096     
02097     tree_c->SetRoot((legoRegion *)tree_c->GetItem(0));
02098     
02099     proc_tmp->SetListOpPtr(bb_prev_op);    
02100     
02101     //1b. copy & reconstruct the edge dictionaries
02102     opEdges * edge_dict = NULL;
02103     opEdges * head = NULL;
02104     opEdges * old_dict = proc->GetEdgeDictionary();
02105     while(old_dict != NULL)
02106     {
02107         int from_BB_id =
02108                 ((legoRegion *) old_dict->GetFromOpPtr()->GetParentBlockPtr())->GetRegionId();
02109         int to_BB_id =
02110                 ((legoRegion *) old_dict->GetToOpPtr()->GetParentBlockPtr())->GetRegionId();
02111         bool from_in_tmp = false;
02112         bool to_in_tmp = false;
02113         int i;
02114         for(i = 0; i <  tree_p->GetCount(); i++)
02115         {
02116             if(from_BB_id == ((legoRegion *)tree_p->GetItem(i))->GetRegionId())
02117                 from_in_tmp = true;
02118             if(to_BB_id == ((legoRegion *)tree_p->GetItem(i))->GetRegionId())
02119                 to_in_tmp = true;
02120             if(from_in_tmp && to_in_tmp) break;
02121         }
02122         for(i = 0; i <  tree_c->GetCount(); i++)
02123         {
02124             if(from_BB_id == ((legoRegion *)tree_c->GetItem(i))->GetRegionId())
02125                 from_in_tmp = true;
02126             if(to_BB_id == ((legoRegion *)tree_c->GetItem(i))->GetRegionId())
02127                 to_in_tmp = true;
02128             if(from_in_tmp && to_in_tmp) break;
02129         }
02130         if(from_in_tmp && to_in_tmp)
02131         {
02132             //find the correct opPtr
02133             int from_op_id = old_dict->GetFromOpPtr()->GetOpId();
02134             int to_op_id = old_dict->GetToOpPtr()->GetOpId();
02135             legoOp * from_op = NULL;
02136             legoOp * to_op = NULL;
02137             
02138             for(i = 0; i <  tree_p->GetCount(); i++)
02139             {
02140                 legoRegion * region1 = (legoRegion *) tree_p->GetItem(i);
02141                 for(int j = 0; j < region1->GetCount(); j++)
02142                 {
02143                     if(from_op_id == ((legoOp *)region1->GetItem(j))->GetOpId())
02144                     {
02145                         from_op = (legoOp *)region1->GetItem(j);
02146                     }
02147                     if(to_op_id == ((legoOp *)region1->GetItem(j))->GetOpId())
02148                     {
02149                         to_op = (legoOp *)region1->GetItem(j);
02150                     }
02151                     if(from_op && to_op) break;
02152                 }
02153                 if(from_op && to_op) break;
02154             }
02155             for(i = 0; i <  tree_c->GetCount(); i++)
02156             {
02157                 legoRegion * region1 = (legoRegion *) tree_c->GetItem(i);
02158                 for(int j = 0; j < region1->GetCount(); j++)
02159                 {
02160                     if(from_op_id == ((legoOp *)region1->GetItem(j))->GetOpId())
02161                     {
02162                         from_op = (legoOp *)region1->GetItem(j);
02163                     }
02164                     if(to_op_id == ((legoOp *)region1->GetItem(j))->GetOpId())
02165                     {
02166                         to_op = (legoOp *)region1->GetItem(j);
02167                     }
02168                     if(from_op && to_op) break;
02169                 }
02170                 if(from_op && to_op) break;
02171             }
02172             if(head == NULL)
02173             {
02174                 edge_dict = new opEdges();
02175                 head = edge_dict;
02176             }
02177             else
02178             {
02179                 edge_dict->SetNextOpEdgePtr(new opEdges());
02180                 edge_dict = edge_dict->GetNextOpEdgePtr();
02181             }
02182             copy_opEdges(old_dict, edge_dict, -1, -1, from_op, -1, to_op);
02183         }
02184         old_dict = old_dict->GetNextOpEdgePtr();
02185     }    
02186     
02187     proc_tmp->SetEdgeDictionary(head);
02188     
02189     //1c. refresh the in_op/out_op list for each op (in/outListPtr) based on the opid
02190     for(bb_i = 0; bb_i < tree_p->GetCount(); bb_i++)
02191     {
02192         legoBB * bb_t = (legoBB *) tree_p->GetItem(bb_i);
02193         for(int op_i =0; op_i < bb_t->GetCount(); op_i++)
02194         {
02195             legoOp * op_p = (legoOp *)bb_t->GetItem(op_i);
02196             opList * inl, * outl;
02197             for(inl = op_p->GetInListPtr(); inl != NULL; inl = inl->GetNextListPtr())
02198             {
02199                 legoOp * opptr = NULL;
02200                 int inl_opid = inl->GetOpId();
02201                 opptr = find_op(proc_tmp, inl_opid);
02202                 if(opptr != NULL)
02203                    inl->SetOpPtr(opptr);
02204             }
02205             for(outl = op_p->GetOutListPtr(); outl != NULL; outl = outl->GetNextListPtr())
02206             {
02207                 legoOp * opptr = NULL;
02208                 int outl_opid = outl->GetOpId();
02209                 opptr = find_op(proc_tmp, outl_opid);
02210                 if(opptr != NULL)
02211                    outl->SetOpPtr(opptr);
02212             }
02213         }
02214     }
02215     for(bb_i = 0; bb_i < tree_c->GetCount(); bb_i++)
02216     {
02217         legoBB * bb_t = (legoBB *) tree_c->GetItem(bb_i);
02218         for(int op_i =0; op_i < bb_t->GetCount(); op_i++)
02219         {
02220             legoOp * op_p = (legoOp *)bb_t->GetItem(op_i);
02221             opList * inl, * outl;
02222             for(inl = op_p->GetInListPtr(); inl != NULL; inl = inl->GetNextListPtr())
02223             {
02224                 legoOp * opptr = NULL;
02225                 int inl_opid = inl->GetOpId();
02226                 opptr = find_op(proc_tmp, inl_opid);
02227                 if(opptr != NULL)
02228                     inl->SetOpPtr(opptr);
02229             }
02230             for(outl = op_p->GetOutListPtr(); outl != NULL; outl = outl->GetNextListPtr())
02231             {
02232                 legoOp * opptr = NULL;
02233                 int outl_opid = outl->GetOpId();
02234                 opptr = find_op(proc_tmp, outl_opid);
02235                 if(opptr != NULL)
02236                     outl->SetOpPtr(opptr);
02237             }
02238         }
02239     }
02240     
02241     //1d. refresh exit/entry oplists, entry/exit edges (in/out lists) at the BB
02242     // level, treegion level, and proc level
02243     for(bb_i = 0; bb_i < tree_p->GetCount(); bb_i++)
02244     {
02245         ((legoBB *)tree_p->GetItem(bb_i))->RefreshAll();
02246     }
02247     for(bb_i = 0; bb_i < tree_c->GetCount(); bb_i++)
02248     {
02249         ((legoBB *)tree_c->GetItem(bb_i))->RefreshAll();
02250     }
02251     
02252     //tree_p->RefreshAll();
02253     //tree_c->RefreshAll();
02254     
02255     proc_tmp->RefreshAll();
02256     
02257     //1e. the attribute dictionary
02258     attrs * attsPtr = new attrs();
02259     proc_tmp->SetAttrDictionary(attsPtr);
02260     
02261         //  legoModule * temp_M;
02262         //  temp_M = new legoModule();
02263         //  temp_M->AddItem(proc_tmp);
02264         //  LegoWrite(temp_M, "teeeee.el");
02265         //  delete temp_M;    
02266 */    
02267     
02268     //2. Tail dup the cand_tree
02269     double weight = 0;
02270     int num_edges = 0;
02271     legoRegion * cand_region = tree_c->GetRoot();
02272     edgeList * out_list; 
02273     opEdges *cand_edges = NULL;
02274     for(out_list = tree_p->GetOutEdgesPtr(); out_list != NULL; out_list =
02275             out_list->GetNextListPtr())
02276     {
02277         opEdges * edges_ptr1 = out_list->GetEdgePtr();
02278         if(edges_ptr1->GetToOpPtr()->GetParentBlockPtr() == cand_region)
02279         {
02280             num_edges++;
02281             double edge_weight = (double) FindEdgeFrequency (edges_ptr1);
02282             if( edge_weight >= weight)
02283             {
02284                 cand_edges = edges_ptr1;
02285                 weight = edge_weight;
02286             }
02287         }
02288     }
02289     assert(cand_edges != NULL);
02290     
02291     //LegoWrite(modu_tmp, "teeeee1.el");
02292     
02293     TreeDuplicate(tree_c, cand_edges, cand_region, tree_p);        
02294     
02295     //LegoWrite(modu_tmp, "teeeee2.el");
02296     
02297     //3. TreeUnform and Form again
02298     int tree_p_id = tree_p->GetRegionId();
02299     if(td_type == 1)
02300     {
02301                 unsigned origloc1 = proc_tmp->Search(tree_p);
02302                 unsigned origloc2 = proc_tmp->Search(tree_c);
02303                 if(origloc1 > origloc2) origloc1 = origloc1 - 1;
02304                 
02305                 Deconstruct(tree_p);
02306                 unsigned treeloc1= proc_tmp->Search(tree_p);
02307                 proc_tmp->Detach(treeloc1);
02308                 delete tree_p;
02309                 Deconstruct(tree_c);
02310                 unsigned treeloc2 = proc_tmp->Search(tree_c);
02311                 proc_tmp->Detach(treeloc2);
02312                 delete tree_c;
02313                 
02314                 legoTreegion * tree_new = new legoTreegion(tree_p_id);
02315                 proc_tmp->Insert(tree_new, origloc1);
02316                 tree_new->SetParentPtr(proc_tmp);
02317                 Construct(tree_new, root1);     
02318                 tree_new->SetWeight(root1->GetWeight());
02319     }
02320     else if (td_type == 2 || td_type == 4)
02321     {
02322                 unsigned origloc1 = proc_tmp->Search(tree_p);
02323                 unsigned origloc2 = proc_tmp->Search(tree_c);
02324                 Deconstruct(tree_p);
02325                 unsigned treeloc1= proc_tmp->Search(tree_p);
02326                 proc_tmp->Detach(treeloc1);
02327                 delete tree_p;
02328                 
02329                 //Do this because the duplicated BBs are still in tree_c
02330                 int tree_c_id = tree_c->GetRegionId();
02331                 Deconstruct(tree_c);
02332                 unsigned treeloc2 = proc_tmp->Search(tree_c);
02333                 proc_tmp->Detach(treeloc2);
02334                 delete tree_c;
02335                 
02336                 legoTreegion * tree_new = new legoTreegion(tree_p_id);
02337                 proc_tmp->Insert(tree_new, origloc1);
02338                 tree_new->SetParentPtr(proc_tmp);
02339                 Construct(tree_new, root1);     
02340                 tree_new->SetWeight(root1->GetWeight());
02341                 
02342                 legoTreegion * tree_c_new = new legoTreegion(tree_c_id);        
02343                 proc_tmp->Insert(tree_c_new, origloc2);
02344                 tree_c_new->SetParentPtr(proc_tmp);
02345                 Construct(tree_c_new, root2);
02346                 tree_c_new->SetWeight(root2->GetWeight());
02347     }
02348     else if(td_type == 3)
02349     {
02350                 unsigned origloc1 = proc_tmp->Search(tree_p);
02351                 unsigned origloc2 = proc_tmp->Search(tree_c);
02352                 unsigned origloc3 = proc_tmp->Search(tree_p2);
02353                 if(origloc1 > origloc2) origloc1 = origloc1 - 1;
02354                 if(origloc3 > origloc2) origloc3 = origloc3 - 1;
02355         
02356                 int tree_p2_id = tree_p2->GetRegionId();
02357                 Deconstruct(tree_p);
02358                 unsigned treeloc1= proc_tmp->Search(tree_p);
02359                 proc_tmp->Detach(treeloc1);
02360                 delete tree_p;
02361                 Deconstruct(tree_c);
02362                 unsigned treeloc2 = proc_tmp->Search(tree_c);
02363                 proc_tmp->Detach(treeloc2);
02364                 delete tree_c;
02365                 Deconstruct(tree_p2);
02366                 unsigned treeloc3 = proc_tmp->Search(tree_p2);
02367                 proc_tmp->Detach(treeloc3);
02368                 delete tree_p2;
02369                 
02370                 legoTreegion * tree_new = new legoTreegion(tree_p_id);
02371                 proc_tmp->Insert(tree_new, origloc1);
02372                 tree_new->SetParentPtr(proc_tmp);
02373                 Construct(tree_new, root1);     
02374                 tree_new->SetWeight(root1->GetWeight());
02375                 
02376                 legoTreegion * tree_new2 = new legoTreegion(tree_p2_id);
02377                 proc_tmp->Insert(tree_new2, origloc3);
02378                 tree_new2->SetParentPtr(proc_tmp);
02379                 Construct(tree_new2, root3);    
02380                 tree_new2->SetWeight(root3->GetWeight());
02381     }
02382 //    treeunform(proc_tmp);
02383     
02384     //LegoWrite(modu_tmp, "teeeee3.el");
02385     
02386 //    int treeid = (proc_tmp->FindMaxRegionId())->GetRegionId();
02387     
02388 //    treeform(proc_tmp, treeid, K, st, false);
02389     
02390     //LegoWrite(modu_tmp, "teeeee4.el");
02391     
02392     //assert(proc_tmp->GetCount() <= 2);
02393     assert(proc_tmp->GetCount() <= proc->GetCount());
02394     
02395     
02396     legoTreegion * tree1 = (legoTreegion *)root1->GetParentPtr();
02397     //legoTreegion * tree1 = (legoTreegion *) proc_tmp->GetItem(0);
02398     
02399     
02400     //4. Calculate the ave max dependence height of the resulting treegion
02401     machine * Mach1 = new machine(K);
02402     //construct the DDG for the candidate pairs, calculate the heuristic
02403     //dag * DDG1 = new dag(Mach1, K);
02404     dag * DDG1;
02405 #ifdef IA64_SUPPORT                   
02406         DDG1 = new dag (Mach1, K, inp_start, inp_end, 8, 11, 8, 15);
02407 #endif
02408 #ifndef IA64_SUPPORT                  
02409         DDG1 = new dag (Mach1, K, 0, 0, 0, 0, 0, 0);
02410 #endif
02411     
02412     DDG1->ConstructDag(tree1);
02413     DDG1->ResetNodeHeights();
02414     DDG1->MaxHeights();    
02415     
02416     //ofstream os1("teeee1.txt");
02417     //DDG1->PrintDag(os1);
02418     //os1.close();    
02419     
02420     double ave_m_h1 = DDG1->GetAveMaxHeight();
02421     double ave_time1 = ave_m_h1 * root1->GetWeight();
02422     
02423     //double ave_m_h2 = 0;
02424     //double width2 = 0;
02425     //double ave_time2 = 0;
02426     //if(proc_tmp->GetCount() == 2) //two treegions remain after the tail dup (a merge point with more than 2
02427                                   //incoming edges
02428     /*
02429     if(proc_tmp->GetCount() == proc->GetCount())
02430     {
02431         legoTreegion * tree2 = (legoTreegion *)root2->GetParentPtr(); 
02432         //legoTreegion * tree2 = (legoTreegion *) proc_tmp->GetItem(1);
02433         assert(tree1 != tree2);
02434         dag * DDG2 = new dag(Mach1, K);
02435         DDG2->ConstructDag(tree2);
02436         DDG2->ResetNodeHeights();
02437         DDG2->MaxHeights();
02438         ave_m_h2 = DDG2->GetAveMaxHeight();
02439         //width2 = tree2->GetOpCount() * 1.0 / (Mach1->GetNumSlots() - 1); 
02440                 //DDG2->GetAveWidth() * 1.0 / (Mach1->GetNumSlots() - 1);
02441         //width2 = (width2 - (int)width2 > 0.09)?(int)(width2 + 1):width2;
02442         //if(ave_m_h2 > width2) 
02443             ave_time2 = ave_m_h2 * tree2->GetRoot()->GetWeight();
02444         //else 
02445         //    ave_time2 = width2 * tree2->GetRoot()->GetWeight();
02446         if(tree2->GetRoot()->GetWeight() <= 0)
02447             ave_time2 = 0;
02448         
02449         delete DDG2;
02450     }
02451     */
02452     double ave_time3 = 0;
02453     if(td_type == 3)
02454     {
02455         legoTreegion * tree3 = (legoTreegion *) root3->GetParentPtr();
02456         assert(tree3 != tree1);
02457         dag * DDG3;
02458 #ifdef IA64_SUPPORT                   
02459         DDG3 = new dag (Mach1, K, inp_start, inp_end, 8, 11, 8, 15);
02460 #endif
02461 #ifndef IA64_SUPPORT                  
02462         DDG3 = new dag (Mach1, K, 0, 0, 0, 0, 0, 0);
02463 #endif
02464         //dag * DDG3 = new dag(Mach1, K);
02465         DDG3->ConstructDag(tree3);
02466         DDG3->ResetNodeHeights();
02467         DDG3->MaxHeights();
02468         ave_time3 = DDG3->GetAveMaxHeight() * root3->GetWeight();
02469         delete DDG3;
02470     }       
02471     //5. Return the result from step 4
02472     delete DDG1;
02473     delete Mach1;
02474     delete modu_tmp;
02475     return(ave_time1 + ave_time3);   
02476 }
02477 
02478 // HZ: 08/31/01 
02479 // Duplicate the sipling regions of the candidate region and the candiate region
02480 // itself as long as all of them are in the treegion source_region.
02481 // 
02482 // As this this function calls itself recursively, by setting the input
02483 // parameters as:
02484 //  source_region = the treegion needs to be duplicated
02485 //  dup_edge = one of the entry edge to the treegion
02486 //  candidate_region = root of the treegion,
02487 //  parenttree = the parent treegion to be expanded
02488 // this function will do the tail duplication at treegion level.
02489 // The return value will be the duplicate of the root block
02490 legoRegion * TreeDuplicate(legoTreegion *source_region, opEdges *dup_edge,
02491         legoRegion *candidate_region, legoTreegion * par_tree)
02492 {
02493     // Find parent proc.
02494     //legoProc * parentproc = (legoProc *) FindParentRegionType (RT_PROC, sourceregion);
02495     //if (parentproc == NULL)
02496       //LegoFatal ("TailDuplicate", "Can't find parent proc of region %d.",
02497         //       sourceregion->GetRegionId());
02498     assert(candidate_region->GetParentPtr() == source_region);
02499     
02500     //duplicate the candidate block    
02501     legoRegion * duplicate = TailDuplicate (candidate_region, dup_edge);
02502     
02503     //Duplicate candidate's child blocks 
02504     if(duplicate == NULL) 
02505     {
02506         cout << "<TreeDup> TailDup returns NULL\n";
02507         return NULL;
02508     }
02509     
02510     edgeList * out_list = duplicate->GetOutEdgesPtr();
02511     int num_out_list = 0;
02512     while (out_list != NULL)
02513     {
02514         opEdges * edges_ptr = out_list->GetEdgePtr();
02515         if((edges_ptr != NULL) && (((legoRegion *) edges_ptr->GetToOpPtr()->GetParentBlockPtr())->GetParentPtr() ==
02516                 source_region))
02517         {
02518             if(edges_ptr->GetToOpPtr()->GetParentBlockPtr() != source_region->GetRoot())
02519             {
02520                 TreeDuplicate(source_region, edges_ptr,
02521                     (legoRegion *) edges_ptr->GetToOpPtr()->GetParentBlockPtr(), par_tree);
02522                 //cout << "I am here\n";
02523             }
02524         }
02525         num_out_list++;
02526         int temp_i;
02527         for(out_list = duplicate->GetOutEdgesPtr(), temp_i = 0; temp_i < num_out_list; out_list =
02528             out_list->GetNextListPtr(), temp_i++);
02529 
02530     }
02531     return (duplicate);
02532 }
02533 
02534 typedef struct tree_pair_
02535 {
02536     legoTreegion * par_tree;  //the parent treegion
02537     legoTreegion * cand_tree; //the candidate treegion that can be duplicated
02538     int td_type; // here we define 4 types of possible tail dup candidate
02539                  // type 1: par_tree dominates cand_tree and there are 2 entry
02540                  //  edges of  cand_tree
02541                  // type 2: par_tree dominates cand_tree and there are more than
02542                  // 2 entry edges of cand_tree
02543                  // type 3: par_tree does not dominate candtree and there are 2
02544                  // entry edges of cand_tree
02545                  // type 4: par_tree does not dominate cand_tree and there are
02546                  // more than 2 edges of cand_tree
02547                  // we will calculate the expected exe. time based on its type
02548     legoTreegion * par_tree2; // the second parent treegion when td_type is 3
02549 } tree_pair;
02550 
02551 
02552 static int n_proc = 0;
02553 
02554 //Find all the acyclic td (tail duplication) candidates in the proc and write them out in a text
02555 // file (stdout)
02556 
02557 void Td_Candidates (legoProc *proc, int& treeid, knobs *K, tree_stats *st = NULL)
02558 {
02559     int inp_start = FindFirstOutGoingReg(proc);
02560     int inp_end = FindLastOutGoingReg(proc);
02561     
02562     //1. forming the natural treegions (treegion formation without tail
02563     //  duplication.
02564     treeform(proc, treeid, K, st, false);
02565     
02566     //detect loop edges in the proc
02567     // Find the dominators.
02568     proc->FindDominators();
02569 
02570     // Mark backedges and loop headers.
02571     markbackedgesandloopheaders (proc);
02572         
02573     n_proc++;
02574     //if(n_proc != 2) return;
02575     
02576     //if(strcmp(proc->GetProcName(), "_getcode") != 0) return;
02577     //cout << "I am here\n";
02578     
02579     //2. Put all possible merge points into a list
02580     vector<tree_pair *> cand_list;
02581     for(unsigned i = 0; i < proc->GetCount(); i++)
02582     {
02583         //go through the treegions
02584         legoTreegion * tree1 = (legoTreegion *)proc->GetItem(i);
02585         
02586         //speed up
02587         if(tree1->GetRoot()->GetWeight() == 0) continue;
02588         
02589         
02590         edgeList * out_list1;
02591         for(out_list1 = tree1->GetOutEdgesPtr(); out_list1 != NULL; out_list1 =
02592             out_list1->GetNextListPtr())
02593         {
02594             opEdges * edges_ptr1 = out_list1->GetEdgePtr();
02595             
02596             if(edges_ptr1 == NULL) continue;
02597             if(edges_ptr1->IsMarked(EM_BACK)) continue;
02598             
02599                    //check for the switch-case statement
02600                    legoOp * br_op_ptr = edges_ptr1->GetFromOpPtr();
02601                    attrList * atl1 = NULL;
02602                    bool sw = false;
02603                    //HZ:if(br_op_ptr->GetOpcode() == BRU)
02604                    if(br_op_ptr->IsBRUOp())
02605                    {
02606                        for (atl1 = br_op_ptr->GetOpAttrListPtr(); atl1 != NULL;
02607                          atl1 = atl1->GetNextListPtr())
02608                               if (atl1->GetAttrType() == ATTR_TBLNAME)
02609                               {
02610                                  sw = true;
02611                                  break;
02612                               }
02613                    }
02614                    if (sw == true) continue;        
02615             
02616             legoRegion * cand_region1 = (legoRegion *) edges_ptr1->GetToOpPtr()->GetParentBlockPtr();
02617             int  qualifies = 1;
02618     
02619             edgeList * in_list1;
02620             int num_in_edges = 0; //used to determine the td_type if qualifies
02621             for(in_list1 = cand_region1->GetInEdgesPtr(); in_list1 != NULL;
02622                     in_list1 = in_list1->GetNextListPtr())
02623             {
02624                 opEdges * edges_ptr2 = in_list1->GetEdgePtr();
02625                 if(edges_ptr2 == NULL) continue;
02626                 if(edges_ptr2->IsMarked(EM_BACK))
02627                         qualifies = 0;
02628                 num_in_edges++;
02629             }
02630                     
02631             if(cand_region1->GetChildren() == NULL)
02632             {
02633                 qualifies = 1;
02634             }
02635             
02636             if(tree1 == (legoTreegion *)cand_region1->GetParentPtr())
02637             {
02638                 qualifies = 0;
02639                 cout << "<treeform_one_by_one> Backedge unselected.\n";
02640             }
02641             
02642             if (qualifies) 
02643             {
02644                 if(FindEdgeFrequency(edges_ptr1) > 0)
02645                 {
02646                     //To speedup the processing: check whether the pair has been in the
02647                     // list already (through a different edge). Anyway we will choose the
02648                     // best edge when we do the tail dup based on par_reg_id and
02649                     // cand_reg_id
02650                     vector <tree_pair *>::iterator pos_1;
02651                     bool in_cd_list = false;
02652                     for(pos_1 = cand_list.begin(); pos_1 != cand_list.end(); pos_1++)
02653                     {
02654                         if((*pos_1)->par_tree == tree1 && (*pos_1)->cand_tree ==
02655                                 (legoTreegion *)cand_region1->GetParentPtr())
02656                         {
02657                             in_cd_list = true;
02658                             break;
02659                         }
02660                     }
02661                     if(in_cd_list) continue;
02662                     
02663                     
02664                     //insert the pair into the list
02665                     tree_pair * tp_ptr;
02666                     tp_ptr = new tree_pair;
02667                     tp_ptr->par_tree = tree1;
02668                     tp_ptr->cand_tree = (legoTreegion *)cand_region1->GetParentPtr();
02669                 
02670                     //set the td_type here
02671                     bool dom = true;
02672                     regionList * rl;
02673                     legoTreegion * par2 = NULL;
02674                     for (rl = cand_region1->GetParents(); rl != NULL; rl = rl->GetNextListPtr())
02675                     {
02676                         par2 = (legoTreegion *) rl->GetRegionPtr()->GetParentPtr();
02677                         if (par2 != (legoRegion *) tree1)
02678                         {
02679                             dom = false;  // par_tree does not dominate cand_tree
02680                             break;
02681                         }
02682                     } // end for
02683                     tp_ptr->td_type = 0;
02684                     tp_ptr->par_tree2 = NULL;
02685                     if(dom == true && num_in_edges == 2) tp_ptr->td_type = 1;
02686                     else if(dom == true && num_in_edges > 2) tp_ptr->td_type = 2;
02687                     else if(dom == false && num_in_edges == 2) 
02688                     {
02689                         tp_ptr->td_type = 3;
02690                         tp_ptr->par_tree2 = par2;
02691                     }
02692                     else if(dom == false && num_in_edges > 2) tp_ptr->td_type = 4;
02693                 
02694                     cand_list.push_back(tp_ptr);
02695                 }
02696             }   //end if(qualifies)    
02697         }//end for out_list1 (go through the outedge list of the treegion)
02698     }//end for i (go through treegions)
02699     
02700     //3. sort the cand_list based on the priority of each candidate, select the best candidate and remove
02701     //  it from the list.
02702     cout << "Proc: " << proc->GetProcName() <<
02703              " Number of possible tail dups: " << cand_list.size() << endl;
02704     
02705     if(cand_list.empty()) 
02706     {
02707         cout << "<treeform_one_by_one> No candidate merge point is found. \n";
02708         return; //no need to dup, as no candidate is found
02709     }
02710             
02711     machine * Mach1 = new machine(K);
02712     vector<tree_pair *>::iterator pos;
02713     
02714     //construct the DDG for the candidate pairs, calculate the heuristic
02715     for(pos = cand_list.begin(); pos != cand_list.end(); pos++)
02716     {
02717         assert((*pos)->td_type >= 1 && (*pos)->td_type <=4);
02718         
02719         //if((*pos)->par_tree->GetRegionId() == 131 && (*pos)->cand_tree->GetRegionId() ==
02720         //      135)
02721         //{
02722         //    int kkkkkk = 11;
02723         //}
02724         
02725         
02726         //dag * DDG1 = new dag(Mach1, K);
02727         dag * DDG1;
02728 #ifdef IA64_SUPPORT                   
02729         DDG1 = new dag (Mach1, K, inp_start, inp_end, 8, 11, 8, 15);
02730 #endif
02731 #ifndef IA64_SUPPORT                  
02732         DDG1 = new dag (Mach1, K, 0, 0, 0, 0, 0, 0);
02733 #endif
02734         
02735         //dag * DDG2 = new dag(Mach1, K);
02736         dag * DDG2;
02737 #ifdef IA64_SUPPORT                   
02738         DDG2 = new dag (Mach1, K, inp_start, inp_end, 8, 11, 8, 15);
02739 #endif
02740 #ifndef IA64_SUPPORT                  
02741         DDG2 = new dag (Mach1, K, 0, 0, 0, 0, 0, 0);
02742 #endif
02743         
02744         DDG1->ConstructDag((*pos)->par_tree);
02745         DDG1->ResetNodeHeights();
02746         DDG1->MaxHeights();
02747             //ofstream os1("teeee2.txt");
02748             //DDG1->PrintDag(os1);
02749             //os1.close();
02750         double ave_m_h1 = DDG1->GetAveMaxHeight();
02751         //int n_path1 = DDG1->GetNumPath();
02752         double ave_time1 = ave_m_h1 * (*pos)->par_tree->GetRoot()->GetWeight(); 
02753                 
02754         DDG2->ConstructDag((*pos)->cand_tree);
02755         DDG2->ResetNodeHeights();
02756         DDG2->MaxHeights();
02757         double ave_m_h2 = DDG2->GetAveMaxHeight();
02758         //int n_path2 = DDG2->GetNumPath();
02759         double ave_time2 = 0;
02760         if((*pos)->td_type == 1 || (*pos)->td_type == 3)
02761         {           
02762             ave_time2 = ave_m_h2 * (*pos)->cand_tree->GetRoot()->GetWeight(); 
02763         }
02764         else
02765         {
02766             //find the edge freq
02767             opEdges * cand_edges = NULL;
02768             double weight = 0;
02769             edgeList * out_list;
02770             legoRegion * cand_region1 = (*pos)->cand_tree->GetRoot();
02771             for(out_list = (*pos)->par_tree->GetOutEdgesPtr(); out_list != NULL; out_list =
02772                     out_list->GetNextListPtr())
02773             {
02774                 opEdges * edges_ptr1 = out_list->GetEdgePtr();
02775                 if(edges_ptr1->GetToOpPtr()->GetParentBlockPtr() == cand_region1)
02776                 {
02777                     double edge_weight = (double) FindEdgeFrequency (edges_ptr1);
02778                     if( edge_weight >= weight)
02779                     {
02780                         cand_edges = edges_ptr1;
02781                         weight = edge_weight;
02782                     }
02783                 }
02784             }
02785             assert(cand_edges != NULL);
02786             
02787             ave_time2 = ave_m_h2 * weight;
02788         }
02789         double ave_time3 = 0;
02790         if((*pos)->td_type == 3)
02791         {
02792             //dag * DDG3 = new dag(Mach1, K);
02793             dag * DDG3;
02794 #ifdef IA64_SUPPORT                   
02795                 DDG3 = new dag (Mach1, K, inp_start, inp_end, 8, 11, 8, 15);
02796 #endif
02797 #ifndef IA64_SUPPORT                  
02798                 DDG3 = new dag (Mach1, K, 0, 0, 0, 0, 0, 0);
02799 #endif
02800             
02801             DDG3->ConstructDag((*pos)->par_tree2);
02802             DDG3->ResetNodeHeights();
02803             DDG3->MaxHeights();
02804             double ave_m_h3 = DDG3->GetAveMaxHeight();
02805             ave_time3 = ave_m_h3 * (*pos)->par_tree2->GetRoot()->GetWeight();   
02806             delete DDG3;
02807         }
02808         //calculating the max dep height for the case when cand_tree is duplicated can appended to par_tree
02809         double ave_time_td;
02810         ave_time_td = tree_est_time(proc, (*pos)->par_tree, (*pos)->cand_tree,
02811                 (*pos)->par_tree2, K, NULL,
02812                 (*pos)->td_type);
02813         
02814         delete DDG2;
02815         delete DDG1;
02816         
02817         double eff = (ave_time1 + ave_time2 + ave_time3 - ave_time_td) / (*pos)->cand_tree->GetOpCount();
02818         
02819         cout << "Proc: " << proc->GetProcName() << " Tree Id: " << (*pos)->par_tree->GetRegionId() << " To Tree Id: " <<
02820             (*pos)->cand_tree->GetRegionId() << endl;
02821         cout << "ave exe time 1: " << ave_time1 << " ave exe time 2: " <<
02822                 ave_time2 << "ave exe time 3: " << ave_time3 <<
02823                 " ave exe time td: " << ave_time_td << endl;
02824         if((*pos)->td_type == 3)
02825             cout << "Efficiency: " << eff << " code size incr: " <<
02826                 (*pos)->cand_tree->GetOpCount() - 1 << " td_type: " << (*pos)->td_type 
02827                 <<" par2_id: " << (*pos)->par_tree2->GetRegionId() << endl;
02828         else
02829             cout << "Efficiency: " << eff << " code size incr: " <<
02830                 (*pos)->cand_tree->GetOpCount() - 1 << " td_type: " << (*pos)->td_type 
02831                 <<" par2_id: " << 0 << endl;
02832             
02833     }
02834     delete Mach1;
02835     
02836     //free the memory allocated by cand_list
02837     for(pos = cand_list.begin(); pos != cand_list.end(); pos++)
02838     {
02839         delete (*pos);
02840     }
02841     
02842     //clear the loop marks
02843     ClearMarks(EM_BACK, proc->GetEdgeDictionary());
02844     /*
02845     pos = cand_list.begin();
02846     
02847     
02848     
02849     //pos++;
02850     //pos++;
02851     //pos++;
02852     //pos++;
02853     //pos++;
02854     //pos++;
02855     //pos++;
02856     //pos++;
02857         
02858     (*pos)->processed = true;
02859     
02860     cout << "Selected: Proc: " << proc->GetProcName() << " Tree Id: " << (*pos)->par_tree->GetRegionId() << " To Tree Id: " <<
02861             (*pos)->cand_tree->GetRegionId() << endl;
02862     cout << "   Base size increase: " << (*pos)->cand_tree->GetOpCount() - 1 << endl;
02863     cout << "Weight of the treegion: " << (*pos)->cand_tree->GetRoot()->GetWeight() << endl;
02864 
02865     pos++;
02866     cout << "Next: Proc: " << proc->GetProcName() << " Tree Id: " << (*pos)->par_tree->GetRegionId() << " To Tree Id: " <<
02867             (*pos)->cand_tree->GetRegionId() << endl;
02868     cout << "   Base size increase: " << (*pos)->cand_tree->GetOpCount() - 1 << endl;
02869     pos--;
02870     
02871     
02872     //4. tail dup the best candidate
02873     legoTreegion * par_tree = (*pos)->par_tree;
02874     legoTreegion * cand_tree = (*pos)->cand_tree;
02875     legoRegion * cand_region = (*pos)->cand_tree->GetRoot();
02876     opEdges * cand_edges = NULL;
02877     double weight = 0;
02878     int num_edges = 0;
02879     edgeList * out_list;
02880     for(out_list = par_tree->GetOutEdgesPtr(); out_list != NULL; out_list =
02881             out_list->GetNextListPtr())
02882     {
02883         opEdges * edges_ptr1 = out_list->GetEdgePtr();
02884         if(edges_ptr1->GetToOpPtr()->GetParentBlockPtr() == cand_region)
02885         {
02886             num_edges++;
02887             double edge_weight = (double) FindEdgeFrequency (edges_ptr1);
02888             if( edge_weight >= weight)
02889             {
02890                 cand_edges = edges_ptr1;
02891                 weight = edge_weight;
02892             }
02893         }
02894     }
02895     assert(cand_edges != NULL);
02896     TreeDuplicate(cand_tree, cand_edges, cand_region, par_tree);
02897     
02898     //5. TreeUnForm
02899     treeunform(proc);
02900     treeid = (proc->FindMaxRegionId())->GetRegionId();
02901     
02902     //6. Forming the treegion again  (go back to step 2 until the code size limit is reached)
02903     // (or go back to step 2 to reform the list due to the changes from the tail duplication? yes, as
02904     // treeunform makes the treegion pointers outdated)
02905     treeform(proc, treeid, K, st);
02906     */
02907 }
02908 
02909 
02910 //Treeform_opt:
02911 //Treegion formation with best code efficiency in terms of tail duplication.
02912 //Methodology: Based on the calculation of the code size efficiency of the td (tail dup)
02913 //candidate, if the resulting efficiency is greater than a threshold, the tail duplication
02914 //will be performed.
02915 
02916 void Treeform_opt (legoProc *proc, int& treeid, knobs *K, tree_stats *st = NULL, double
02917         eff_threshold = 1000)
02918 {
02919     int inp_start = FindFirstOutGoingReg(proc);
02920     int inp_end = FindLastOutGoingReg(proc);
02921     bool no_more_td_cand = false;
02922     machine * Mach1 = new machine(K);
02923    //1. forming the natural treegions (treegion formation without tail
02924    //  duplication. skiped if the source rebel file is known to be natural treegion formed
02925    //treeform(proc, treeid, K, st, false);
02926 
02927     int start_i = 0;
02928     while(no_more_td_cand == false)
02929     {
02930     
02931         //detect loop edges in the proc
02932         // Find the dominators.
02933         proc->FindDominators();
02934 
02935         // Mark backedges and loop headers.
02936         markbackedgesandloopheaders (proc);
02937         
02938         
02939         //2. Find a tail duplication candidate
02940         bool find_candidate = false;
02941         double efficiency;
02942         legoTreegion * tree1 = NULL, * tree2 = NULL, * par_tree2 = NULL;
02943         opEdges * cand_edges = NULL;
02944         int td_type = 0;
02945         
02946         //To speed up the simulation
02947         //No need to start the search from every treegion
02948         //Instead continue from the last iteration
02949         
02950             //for(unsigned i = 0; i < proc->GetCount(); i++)
02951             for(unsigned i = start_i; i < proc->GetCount(); i++)
02952             {
02953                 //go through the treegions
02954                tree1 = (legoTreegion *)proc->GetItem(i);
02955                
02956                //speed up
02957                if(tree1->GetRoot()->GetWeight() == 0) continue;
02958                
02959                edgeList * out_list1;
02960                for(out_list1 = tree1->GetOutEdgesPtr(); out_list1 != NULL; out_list1 =
02961                    out_list1->GetNextListPtr())
02962                {
02963                    opEdges * edges_ptr1 = out_list1->GetEdgePtr();
02964             
02965                    if(edges_ptr1 == NULL) continue;
02966                    if(edges_ptr1->IsMarked(EM_BACK)) continue;
02967                    
02968                    //check for the switch-case statement
02969                    legoOp * br_op_ptr = edges_ptr1->GetFromOpPtr();
02970                    attrList * atl1 = NULL;
02971                    bool sw = false;
02972                    //HZ: if(br_op_ptr->GetOpcode() == BRU)
02973                    if(br_op_ptr->IsBRUOp())
02974                    {
02975                        for (atl1 = br_op_ptr->GetOpAttrListPtr(); atl1 != NULL;
02976                          atl1 = atl1->GetNextListPtr())
02977                               if (atl1->GetAttrType() == ATTR_TBLNAME)
02978                               {
02979                                  sw = true;
02980                                  break;
02981                               }
02982                    }
02983                    if (sw == true) continue;               
02984                                         
02985                    legoRegion * cand_region1 = (legoRegion *) edges_ptr1->GetToOpPtr()->GetParentBlockPtr();
02986                    int  qualifies = 1;
02987                    
02988                     edgeList * in_list1;
02989                     int num_in_edges = 0; //used to determine the td_type if qualifies
02990                     for(in_list1 = cand_region1->GetInEdgesPtr(); in_list1 != NULL;
02991                             in_list1 = in_list1->GetNextListPtr())
02992                     {
02993                         opEdges * edges_ptr2 = in_list1->GetEdgePtr();
02994                         if(edges_ptr2 == NULL) continue;
02995                         if(edges_ptr2->IsMarked(EM_BACK))
02996                                 qualifies = 0;
02997                         num_in_edges++;
02998                     }
02999                    
03000                    if(cand_region1->GetChildren() == NULL)
03001                    {
03002                        qualifies = 1;
03003                    }
03004             
03005                    if(tree1 == (legoTreegion *)cand_region1->GetParentPtr())
03006                    {
03007                        qualifies = 0;
03008                        //cout << "<treeform_one_by_one> Backedge unselected.\n";
03009                    }
03010             
03011                    if (qualifies) 
03012                    {
03013                        double edge_f = FindEdgeFrequency(edges_ptr1);
03014                        cand_edges = edges_ptr1;
03015                        if(edge_f > 0)
03016                        {
03017                            tree2 = (legoTreegion *)cand_region1->GetParentPtr();    
03018                            //insert the pair into the list
03019                            
03020                            //set the td_type here
03021                            bool dom = true;
03022                            regionList * rl;
03023                            par_tree2 = NULL;
03024                            legoTreegion * par2 = NULL;
03025                            for (rl = cand_region1->GetParents(); rl != NULL; rl = rl->GetNextListPtr())
03026                            {
03027                                par2 = (legoTreegion *) rl->GetRegionPtr()->GetParentPtr();
03028                                if (par2 != (legoRegion *) tree1)
03029                                {
03030                                    dom = false;  // par_tree does not dominate cand_tree
03031                                    break;
03032                                }
03033                             } // end for
03034                             if(dom == true && num_in_edges == 2) td_type = 1;
03035                             else if(dom == true && num_in_edges > 2) td_type = 2;
03036                             else if(dom == false && num_in_edges == 2) 
03037                             {
03038                                 td_type = 3;
03039                                 par_tree2 = par2;
03040                             }
03041                             else if(dom == false && num_in_edges > 2) td_type = 4;
03042                                        
03043                            //dag * DDG1 = new dag(Mach1, K);
03044                             dag * DDG1;
03045 #ifdef IA64_SUPPORT                   
03046                                 DDG1 = new dag (Mach1, K, inp_start, inp_end, 8, 11, 8, 15);
03047 #endif
03048 #ifndef IA64_SUPPORT                  
03049                                 DDG1 = new dag (Mach1, K, 0, 0, 0, 0, 0, 0);
03050 #endif
03051                             
03052                        
03053                            DDG1->ConstructDag(tree1);
03054                            DDG1->ResetNodeHeights();
03055                            DDG1->MaxHeights();
03056                        
03057                            double ave_m_h1 = DDG1->GetAveMaxHeight();
03058                        
03059                            //c_p->ave_t1 = ave_m_h1 * tree1->GetRoot()->GetWeight();
03060                            double ave_t1 = ave_m_h1 * tree1->GetRoot()->GetWeight();
03061                        
03062                            //dag * DDG2 = new dag(Mach1, K);
03063                            dag * DDG2;
03064 #ifdef IA64_SUPPORT                   
03065                                 DDG2 = new dag (Mach1, K, inp_start, inp_end, 8, 11, 8, 15);
03066 #endif
03067 #ifndef IA64_SUPPORT                  
03068                                 DDG2 = new dag (Mach1, K, 0, 0, 0, 0, 0, 0);
03069 #endif
03070                            
03071                            DDG2->ConstructDag(tree2);
03072                            DDG2->ResetNodeHeights();
03073                            DDG2->MaxHeights();
03074                        
03075                            double ave_m_h2 = DDG2->GetAveMaxHeight();
03076                            double ave_t2 = 0;
03077                            if(td_type == 1 || td_type == 3)
03078                            {
03079                                ave_t2 = ave_m_h2 * tree2->GetRoot()->GetWeight();
03080                            }
03081                            else
03082                            {
03083                                ave_t2 = ave_m_h2 * edge_f;
03084                            }
03085                            double ave_t3 = 0;
03086                            if(td_type == 3)
03087                            {
03088                                //dag * DDG3 = new dag(Mach1, K);
03089                                dag * DDG3;
03090 #ifdef IA64_SUPPORT                   
03091                                 DDG3 = new dag (Mach1, K, inp_start, inp_end, 8, 11, 8, 15);
03092 #endif
03093 #ifndef IA64_SUPPORT                  
03094                                 DDG3 = new dag (Mach1, K, 0, 0, 0, 0, 0, 0);
03095 #endif
03096                                
03097                                DDG3->ConstructDag(par_tree2);
03098                                DDG3->ResetNodeHeights();
03099                                DDG3->MaxHeights();
03100                                ave_t3 = DDG3->GetAveMaxHeight() * par_tree2->GetRoot()->GetWeight();
03101                                delete DDG3;                            
03102                            }
03103                        
03104                            //c_p->ave_t2 = ave_m_h2 * tree2->GetRoot()->GetWeight();
03105                            //double ave_t2 = ave_m_h2 * tree2->GetRoot()->GetWeight();
03106                            //c_p->ave_td = tree_est_time(proc, tree1, tree2, K);
03107                            double ave_td = tree_est_time(proc, tree1, tree2, par_tree2,
03108                                K, NULL, td_type);
03109                            //c_p->efficiency = (c_p->ave_t1 + c_p->ave_t2 - c_p->ave_td) / tree2->GetOpCount();
03110                            efficiency = (ave_t1 + ave_t2 + ave_t3 - ave_td) / tree2->GetOpCount();
03111                            
03112                            if(efficiency > eff_threshold)
03113                            {
03114                                find_candidate = true;
03115                            }
03116                            
03117                            //also include the case when the size increase is
03118                            //zero
03119                            //if(efficiency > 50 && tree2->GetOpCount() == 1)
03120                            //{
03121                            //    find_candidate = true;
03122                            //}
03123                            
03124                            //also if the actual code size increase is zero
03125                            //current do not consider them
03126                            delete DDG1;
03127                            delete DDG2;                
03128                        } //end if(edge_f > 0)
03129                     }   //end if(qualifies)    
03130                     if(find_candidate) break;               
03131                }//end for out_list1 (go through the outedge list of the treegion)
03132                if(find_candidate) 
03133                {
03134                    if (i > 1)
03135                      start_i = i - 1;
03136                    break;
03137                }
03138            }//end for i (go through treegions)
03139            
03140         //clear the loop marks     
03141         ClearMarks(EM_BACK, proc->GetEdgeDictionary());
03142            
03143         if(find_candidate == false) 
03144         {
03145             no_more_td_cand = true;
03146             break;  
03147         }
03148         //3. tail dup the candidate
03149         cout << "Proc: " << proc->GetProcName() << " Tree Id: " << tree1->GetRegionId() << " To Tree Id: " <<
03150             tree2->GetRegionId() << endl;
03151         
03152         cout << "Efficiency: " << efficiency << " code size incr: " <<
03153                 tree2->GetOpCount() - 1 << endl;
03154         
03155         //4. tail dup the candidate
03156         assert(cand_edges != NULL);
03157         TreeDuplicate(tree2, cand_edges, tree2->GetRoot(), tree1);
03158     
03159         //5. TreeUnForm & reform
03160         legoRegion * root_new = tree1->GetRoot();
03161         int tree1_id = tree1->GetRegionId();
03162         
03163             if(td_type == 1)
03164             {
03165                 unsigned origloc1 = proc->Search(tree1);
03166                 unsigned origloc2 = proc->Search(tree2);
03167                 if(origloc1 > origloc2) origloc1 = origloc1 - 1;
03168                 
03169                 Deconstruct(tree1);
03170                 unsigned treeloc1= proc->Search(tree1);
03171                 proc->Detach(treeloc1);
03172                 delete tree1;
03173                 Deconstruct(tree2);
03174                 unsigned treeloc2 = proc->Search(tree2);
03175                 proc->Detach(treeloc2);
03176                 delete tree2;
03177                 
03178                 legoTreegion * tree_new = new legoTreegion(tree1_id);
03179                 proc->Insert(tree_new, origloc1);
03180                 tree_new->SetParentPtr(proc);
03181                 Construct(tree_new, root_new);
03182                 tree_new->SetWeight(root_new->GetWeight());
03183             }
03184             else if (td_type == 2 || td_type == 4)
03185             {
03186                 unsigned origloc1 = proc->Search(tree1);
03187                 unsigned origloc2 = proc->Search(tree2);
03188                 
03189                 Deconstruct(tree1);
03190                 unsigned treeloc1= proc->Search(tree1);
03191                 proc->Detach(treeloc1);
03192                 delete tree1;
03193                 
03194                 int tree2_id = tree2->GetRegionId();
03195                 legoRegion * root_c = tree2->GetRoot();
03196                 Deconstruct(tree2);
03197                 unsigned treeloc2 = proc->Search(tree2);
03198                 proc->Detach(treeloc2);
03199                 delete tree2;
03200                 
03201                 legoTreegion * tree_new = new legoTreegion(tree1_id);
03202                 proc->Insert(tree_new, origloc1);
03203                 tree_new->SetParentPtr(proc);
03204                 Construct(tree_new, root_new);          
03205                 tree_new->SetWeight(root_new->GetWeight());
03206                 
03207                 legoTreegion * tree2_new = new legoTreegion(tree2_id);  
03208                 proc->Insert(tree2_new, origloc2);
03209                 tree2_new->SetParentPtr(proc);
03210                 Construct(tree2_new, root_c);
03211                 tree2_new->SetWeight(root_c->GetWeight());
03212             }
03213             else if(td_type == 3)
03214             {
03215                 unsigned origloc1 = proc->Search(tree1);
03216                 unsigned origloc2 = proc->Search(tree2);
03217                 unsigned origloc3 = proc->Search(par_tree2);
03218                 if(origloc1 > origloc2) origloc1 = origloc1 - 1;
03219                 if(origloc3 > origloc2) origloc3 = origloc3 - 1;
03220                 
03221                 Deconstruct(tree1);
03222                 unsigned treeloc1= proc->Search(tree1);
03223                 proc->Detach(treeloc1);
03224                 delete tree1;
03225                 Deconstruct(tree2);
03226                 unsigned treeloc2 = proc->Search(tree2);
03227                 proc->Detach(treeloc2);
03228                 delete tree2;
03229                 
03230                 legoRegion * root_new_2 = par_tree2->GetRoot();
03231                 int root_id_2 = par_tree2->GetRegionId();
03232                 Deconstruct(par_tree2);
03233                 unsigned treeloc3 = proc->Search(par_tree2);
03234                 proc->Detach(treeloc3);
03235                 delete par_tree2;
03236                 
03237                 
03238                 legoTreegion * tree_new = new legoTreegion(tree1_id);
03239                 proc->Insert(tree_new, origloc1);
03240                 tree_new->SetParentPtr(proc);
03241                 Construct(tree_new, root_new);
03242                 tree_new->SetWeight(root_new->GetWeight());
03243                 
03244                 legoTreegion * tree_new_2 = new legoTreegion(root_id_2);
03245                 proc->Insert(tree_new_2, origloc3);
03246                 tree_new_2->SetParentPtr(proc);
03247                 Construct(tree_new_2, root_new_2);
03248                 tree_new_2->SetWeight(root_new_2->GetWeight());
03249             }
03250         
03251         //treeunform(proc);
03252         //treeid = (proc->FindMaxRegionId())->GetRegionId();
03253     }
03254         
03255     delete Mach1;
03256 }
03257 

Generated on Mon Jul 21 20:29:17 2003 for TINKER LEGO DOC by doxygen 1.3.2