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

static.C

Go to the documentation of this file.
00001 // static.C
00002 // 2/17/98 WAH:  Created - now angst-free!
00003 
00004 #include "lego.H"
00005 #include "legoUtil.H"
00006 #include "static.H"
00007 
00008 //#define STATIC_ESTIMATE_DEBUG
00009 
00010 #ifdef STATIC_ESTIMATE_DEBUG
00011 
00012 #define dprintf(s) fprintf s
00013 #define OUTF stderr
00014 
00015 //#define STATIC_ESTIMATE_DEBUG_VERBOSE
00016 #ifdef STATIC_ESTIMATE_DEBUG_VERBOSE
00017 #define dvprintf(s) fprintf s
00018 #else
00019 #define dvprintf(s)
00020 #endif // STATIC_ESTIMATE_DEBUG_VERBOSE
00021 
00022 #else
00023 #define dprintf(s)
00024 #define dvprintf(s)
00025 
00026 #endif // STATIC_ESTIMATE_DEBUG
00027 
00028 int 
00029 IsTreeExitandDummyBr(legoOp *bottomop, legoTreegion *tree) {
00030   
00031   opList *leafopl;
00032 
00033   if (bottomop->IsDUMMYBROp() == false)
00034     return FALSE;
00035   for (leafopl = tree->GetExitOpsPtr(); leafopl != NULL;
00036        leafopl = leafopl->GetNextListPtr()) {
00037     if (bottomop == leafopl->GetOpPtr())
00038       return TRUE;
00039   }
00040   return FALSE;
00041   
00042 }
00043 
00044 /*
00045  * SchedTimeSpan
00046  *   fromop = op at which to start
00047  *   toop = op at which to stop
00048  *   returns: number of cycles between them, or -1 if error
00049  *
00050  * Returns the difference in schedule times between from and to, plus 1.
00051  * The ops MUST belong to the same block (bb, sb, or hb), and fromop must
00052  * come before toop.
00053  */
00054 static int
00055 SchedTimeSpan (legoOp *fromop, legoOp *toop)
00056 {
00057   legoOp *walkop;
00058   int mintime, maxtime, currtime;
00059   legoRegion *parentblock = (legoRegion *) fromop->GetParentBlockPtr();
00060 
00061   if ((legoRegion *) toop->GetParentBlockPtr() != parentblock)
00062     {
00063       LegoNonFatal ("SchedTimeSpan", "Ops %d and %d belong to different "
00064                     "blocks.", fromop->GetOpId(), toop->GetOpId());
00065       return -1;
00066     } // end if
00067 
00068   mintime = maxtime = fromop->GetSchedTime();
00069 
00070   for (walkop = fromop;
00071        walkop != toop && walkop != NULL;
00072        walkop = walkop->GetNextLink())
00073     {
00074       currtime = walkop->GetSchedTime();
00075       if (currtime < mintime) mintime = currtime;
00076       if (currtime > maxtime) maxtime = currtime;
00077     } // end for
00078   // Catch toop as well.
00079   if (toop != fromop)
00080     {
00081       currtime = toop->GetSchedTime();
00082       if (currtime < mintime) mintime = currtime;
00083       if (currtime > maxtime) maxtime = currtime;
00084     } // end if
00085 
00086   if (walkop == NULL)
00087     {
00088       LegoNonFatal ("SchedTimeSpan", "Op %d does not follow op %d; estimate "
00089                     "is inaccurate.", toop->GetOpId(), fromop->GetOpId());
00090     } // end if
00091 
00092   return (maxtime - mintime + 1);
00093 } // end SchedTimeSpan
00094 
00095 static void
00096 Estimate (legoBB *bb, static_stats *st)
00097 {
00098   legoOp *topop, *bottomop;
00099   double timespan, weight;
00100 
00101   topop = bb->GetEntryOpsPtr()->GetOpPtr();
00102   bottomop = bb->GetExitOpsPtr()->GetOpPtr();
00103 
00104   timespan = (double) SchedTimeSpan (topop, bottomop);
00105   weight = bb->GetWeight();
00106 
00107   // # cycles = schedule length of bb * bb weight
00108   st->numCycles += timespan * weight;
00109   // # dynamic ops = # ops in bb * bb weight
00110   // Note that this OpCount differs slightly from the Treegion OpCount 
00111   // because Treegion estimator does not count pseudo ops
00112   st->numDynamicOps += bb->GetOpCount() * weight;
00113 
00114   dprintf ((OUTF, "Estimate BB %d\t%lf cycles\t%lf ops\n", bb->GetRegionId(),
00115             timespan * weight, bb->GetOpCount() * weight));
00116   return;
00117 } // end Estimate (bb)
00118 
00119 static void
00120 Estimate (legoRegion *hb, static_stats *st)
00121 {
00122   legoOp *topop, *bottomop;
00123   //  legoOp *mintimeop;
00124   double timespan, weight;
00125   //  int lastbranchtime = -1;
00126   int lastpathcycle, opct;
00127 #ifdef STATIC_ESTIMATE_DEBUG
00128   double nc = 0.0, ndo = 0.0;
00129 #endif
00130 
00131   dvprintf ((OUTF, ". estimating superblock %d.\n", hb->GetRegionId()));
00132 
00133   // Iterate through each subblock of the superblock, treating each
00134   // like a basic block. A "subblock" means a basic block-like section
00135   // of a superblock, from a C_MERGE to a branch.
00136   topop = hb->GetEntryOpsPtr()->GetOpPtr();
00137   lastpathcycle = 0;
00138   while (topop != NULL)
00139     {
00140       dvprintf ((OUTF, "... lpc = %d, topop starts at %d.\n",
00141                  lastpathcycle, topop->GetOpId()));
00142       //      mintimeop = NULL;
00143 
00144       // topop begins the subblock. Find the next branch (bottomop).
00145       for (bottomop = topop->GetNextLink(), opct = 0;
00146            bottomop != NULL && bottomop->GetOutListPtr() == NULL;
00147            bottomop = bottomop->GetNextLink())  // step until branch
00148         {
00149           if (!(bottomop->IsDummy())) opct++;  // count real ops in subblock
00150           //      if (bottomop->GetSchedTime() <= lastpathcycle)
00151           //        continue;  // move on - either spec'd or simul. branch
00152 
00153           //      if ((mintimeop == NULL &&
00154           //           bottomop->GetSchedTime() > lastpathcycle) ||
00155           //          (mintimeop != NULL &&
00156           //           bottomop->GetSchedTime() < mintimeop->GetSchedTime()))
00157           //        mintimeop = bottomop;
00158         } // end for
00159 
00160       if (bottomop == NULL)
00161         {
00162           LegoNonFatal ("Estimate", "Couldn't find branch after op %d in "
00163                         "region %d.", topop->GetOpId(), hb->GetRegionId());
00164           return;
00165         } // end if
00166       if (!(bottomop->IsDummy())) opct++;  // catch bottomop for opct
00167       //      topop = mintimeop;  // first non-spec'd op in path (besides br.)
00168       //      dvprintf ((OUTF, "... scanned topop is %d.\n",
00169       //                 (topop == NULL ? 0 : topop->GetOpId())));
00170       //      if (topop == NULL) topop = bottomop;  // if all spec'd except br.
00171       dvprintf ((OUTF, "... bottomop is %d.\n", bottomop->GetOpId()));
00172 
00173       // One detail: if this branch was scheduled the same time as the
00174       // last branch (i.e., if topop becomes bottomop), ignore this subblock's
00175       // cycle time; its execution completely overlaps the last one's
00176       // (dynamic op count still matters though).
00177       //      if (bottomop->GetSchedTime() == lastbranchtime)
00178       //      if (bottomop->GetSchedTime() == topop->GetSchedTime())
00179       //      if (bottomop->GetSchedTime() == lastpathcycle)
00180       //        timespan = 0.0;
00181       //      else
00182         //      timespan = (double) SchedTimeSpan (topop, bottomop);
00183       timespan = (double) (bottomop->GetSchedTime() - lastpathcycle);
00184 
00185       weight = FindOpWeight (topop);  // NOT hb weight, but subblock weight
00186 
00187       // # cycles = schedule length of subblock * subblock weight
00188       st->numCycles += timespan * weight;
00189       // # dynamic ops = # ops in subblock * subblock weight
00190       st->numDynamicOps += ((double) opct) * weight;
00191 #ifdef STATIC_ESTIMATE_DEBUG
00192       nc += timespan * weight;
00193       ndo += ((double) opct) * weight;
00194 #endif
00195 
00196       dvprintf ((OUTF, "... timespan of %lf and weight of %lf gives %lf cycles.\n",
00197                  timespan, weight, timespan * weight));
00198       dvprintf ((OUTF, "... %d ops counted and weight of %lf gives %lf dynamic.\n",
00199                  opct, weight, ((double) opct) * weight));
00200 
00201       // Advance ...
00202       //      lastbranchtime = bottomop->GetSchedTime();
00203       lastpathcycle = bottomop->GetSchedTime();
00204       topop = bottomop->GetNextLink();
00205     } // end while
00206 
00207   dprintf ((OUTF, "Estimate HB %d\t%lf cycles\t%lf ops\n", hb->GetRegionId(),
00208             nc, ndo));
00209   return;
00210 } // end Estimate (hb)
00211 
00212 static void
00213 Estimate (legoTreegion *tree, static_stats *st)
00214 {
00215   legoOp *topop, *bottomop, *leafop, *walkop;
00216   opList *leafopl;
00217   edgeList *exits, *treeexits;
00218   opEdges *exitedge;
00219   legoRegion *block;
00220   regionList *rl, *path;
00221   opList *opl;
00222   double timespan, weight;
00223   //  int lastbranchtime;
00224   int opct, isRTS;
00225   int topop_s_time, bottomop_s_time, all_ops_speculated;
00226   char flag;
00227 #ifdef STATIC_ESTIMATE_DEBUG
00228   double nc = 0.0, ndo = 0.0;
00229 #endif
00230 
00231   // Treat each execution path in the treegion like a superblock, and
00232   // sum up over all paths. Use the weight of the path as the overall
00233   // weight when calculating op count and cycle time for a path.
00234   for (leafopl = tree->GetExitOpsPtr(); leafopl != NULL;
00235        leafopl = leafopl->GetNextListPtr())
00236     {
00237       leafop = leafopl->GetOpPtr();
00238       if (leafop == NULL)
00239         {
00240           LegoNonFatal ("Estimate", "Can't find leaf of treegion %d.",
00241                         tree->GetRegionId());
00242           continue;
00243         } // end if
00244 
00245       // For this exit op, iterate over each treegion exit that emanates
00246       // from it. If it's an RTS, assume the presence of one edge with
00247       // the frequency of the op.
00248       isRTS = (leafop->IsRETOp() ||
00249               leafop->IsBRLExitOp()); //HZ:
00250       if (isRTS)
00251         exits = NULL;
00252       else
00253         exits = ((legoRegion *) leafop->GetParentBlockPtr())->
00254           GetOutEdgesPtr();
00255       while (exits != NULL || isRTS)
00256         {
00257           if (exits != NULL)
00258             {
00259               exitedge = exits->GetEdgePtr();
00260               if (exitedge == NULL)
00261                 {
00262                   LegoNonFatal ("Estimate", "Can't find exit edge of "
00263                                 "treegion %d.", tree->GetRegionId());
00264                   exits = exits->GetNextListPtr();
00265                   continue;
00266                 } // end if
00267 
00268               // Before using this edge, check that it's actually a
00269               // treegion exit edge and that it emanates from leafop.
00270               for (treeexits = tree->GetOutEdgesPtr(); treeexits != NULL;
00271                    treeexits = treeexits->GetNextListPtr())
00272                 if (treeexits->GetEdgePtr() == exitedge) break;
00273               // (Use treeexits as a convenient way to flag that the
00274               // exit edge doesn't emanate from leafop.)
00275               if (exitedge->GetFromOpPtr() != leafop) treeexits = NULL;
00276               if (treeexits == NULL)
00277                 {
00278                   exits = exits->GetNextListPtr();  // skip it
00279                   continue;
00280                 } // end if
00281 
00282               // The path weight is the weight of the edge exiting.
00283               weight = (double) FindEdgeFrequency (exitedge);
00284             } // end if
00285           else
00286             {
00287               exitedge = NULL;
00288               weight = FindOpWeight (leafop);  // path weight = RTS weight
00289             } // end else
00290 
00291           dvprintf ((OUTF, ". beginning path to exit edge %d (op %d), weight "
00292                      "%lf.\n", (exitedge != NULL ? exitedge->GetEdgeId() :
00293                                 0),
00294                      leafop->GetOpId(), weight));
00295 
00296           // Before going through all the rigamarole, if this path has
00297           // no weight, skip it completely.
00298           if (weight == 0)
00299             {
00300               dvprintf ((OUTF, ". path has zero weight - skipping!\n"));
00301               if (!isRTS)
00302                 exits = exits->GetNextListPtr();
00303               isRTS = 0;
00304               continue;
00305             } // end if
00306 
00307           // Walk up the blocks from the leaf to the root, forming a list in
00308           // reverse order as you go.
00309           path = NULL;
00310           for (block = (legoRegion *) leafop->GetParentBlockPtr();
00311                block != NULL;
00312                block = block->GetParents()->GetRegionPtr())
00313             {
00314               rl = new regionList (block);
00315               if (path != NULL)
00316                 path->Prepend (rl);
00317               path = rl;
00318 
00319               if (block == tree->GetRoot()) break;
00320             } // end for
00321           if (block == NULL)
00322             {
00323               LegoNonFatal ("Estimate", "Failed walking to root from op %d "
00324                             "in treegion %d.", leafop->GetOpId(),
00325                             tree->GetRegionId());
00326               if (!isRTS)
00327                 exits = exits->GetNextListPtr();
00328               isRTS = 0;
00329               continue;
00330             } // end if
00331 
00332           // Now proceed down the path from root to leaf, calculating the 
00333           // timespan in op count for each BB in path.
00334           // Path now consists of BBs only as UnBindSB is assumed during 
00335           // treegion formation to improve treegions and also because 
00336           // the dag builder was handling SB incorrectly.
00337           for (rl = path; rl != NULL; rl = rl->GetNextListPtr())
00338             {
00339               block = rl->GetRegionPtr();
00340               dvprintf ((OUTF, "... looking at block %d.\n",
00341                          block->GetRegionId()));
00342               
00343               // mdj - 7/1/98 I am now assuming that UnBindSB is used during 
00344               // treegion formation so that treegions consist only of BBs.
00345               // Therefore, topop is the entry C_MERGE and bottomop is the 
00346               // exit branch (or DUMMY_BR). BBs have only one entry op and 
00347               // one exit op. 
00348               topop = block->GetEntryOpsPtr()->GetOpPtr();
00349               topop_s_time = topop->GetSchedTime();
00350               dvprintf ((OUTF, "... topop is %d.\n",
00351                          topop->GetOpId()));
00352               // Count the real ops in this block while stepping 
00353               // through to the bottomop branch (or DUMMY_BR)
00354               all_ops_speculated = TRUE;
00355               for (bottomop = topop->GetNextLink(), opct = 0;
00356                    bottomop != NULL && bottomop->GetOutListPtr() == NULL;
00357                    bottomop = bottomop->GetNextLink())  // until branch
00358                 {
00359                   if (!(bottomop->IsDummy())) {
00360                     opct++;  // count real ops in block
00361                     if (bottomop->GetSchedTime() >= topop_s_time)
00362                       all_ops_speculated = FALSE;
00363                   }
00364                 } // end for
00365               
00366               if (bottomop == NULL)
00367                 {
00368                   LegoNonFatal ("Estimate", "Couldn't find branch after "
00369                                 "op %d in region %d.", topop->GetOpId(),
00370                                 block->GetRegionId());
00371                   return;
00372                 } // end if
00373               bottomop_s_time = bottomop->GetSchedTime();
00374               if (!(bottomop->IsDummy())) opct++;  // bottomop for opct
00375               dvprintf ((OUTF, "... bottomop is %d.\n",
00376                          bottomop->GetOpId()));
00377               
00378               // Now calculate the timespan...
00379               if (topop_s_time == bottomop_s_time)  // possibly all ops 
00380                                                     // spec'd in BB
00381                 {
00382                   if (all_ops_speculated) 
00383                     if (IsTreeExitandDummyBr(bottomop, tree)) {
00384                       timespan = 0.0;
00385                       // this BB can be removed
00386                     }
00387                     else {
00388                       timespan = 1.0;
00389                       // if bottomop is a DUMMY_BR and BB still has 
00390                       // all_ops_speculated even after speculative code 
00391                       // motion is implemented, this BB can then be 
00392                       // removed safely and then timespan = 0.0
00393                     }
00394                   else 
00395                     timespan = 1.0;
00396                 } // end if
00397               else  // all ops NOT spec'd
00398                 {
00399                   timespan = bottomop_s_time - topop_s_time + 1;
00400                 } // end else
00401               
00402               // Remember we're using the path weight.
00403               // # cycles = schedule length of subblock * subblock weight
00404               st->numCycles += timespan * weight;
00405               // # dynamic ops = # ops in subblock * subblock weight
00406               st->numDynamicOps += ((double) opct) * weight;
00407 #ifdef STATIC_ESTIMATE_DEBUG
00408               nc += timespan * weight;
00409               ndo += ((double) opct) * weight;
00410 #endif
00411               dvprintf ((OUTF, "... path weight is %lf.\n", weight));
00412               dvprintf ((OUTF, "... timespan of %lf gives %lf cycles.\n",
00413                          timespan, timespan * weight));
00414               dvprintf ((OUTF, "... %d ops counted gives %lf dynamic.\n",
00415                          opct, ((double) opct) * weight));
00416               
00417             } // end for (each block in path)
00418           
00419           // Move to next path from this leaf.
00420           if (!isRTS)
00421             exits = exits->GetNextListPtr();  // go to next exit
00422           isRTS = 0;  // only do RTS once
00423           delete path;
00424         }  // end while (there's a path from the leaf)
00425 
00426     } // end for (each leaf)
00427 
00428   dprintf ((OUTF, "Estimate TREE %d\t%lf cycles\t%lf ops\n",
00429             tree->GetRegionId(), nc, ndo));
00430   return;
00431 } // end Estimate (tree)
00432 
00433 static void
00434 EstimateNew (legoTreegion *tree, static_stats *st)
00435 {
00436   legoOp *branchop, *topop, *bottomop, *leafop, *walkop, *finalop;
00437   opList *leafopl, *branchops, *oplist;
00438   edgeList *exits, *treeexits;
00439   opEdges *exitedge;
00440   legoRegion *block;
00441   opList *opl;
00442   double timespan, weight;
00443   //  int lastbranchtime;
00444   int opct, isRTS;
00445   int topop_s_time, bottomop_s_time, all_ops_speculated;
00446   char flag;
00447 #ifdef STATIC_ESTIMATE_DEBUG
00448   double nc = 0.0, ndo = 0.0;
00449 #endif
00450 
00451   // Treat each execution path in the treegion like a superblock, and
00452   // sum up over all paths. Use the weight of the path as the overall
00453   // weight when calculating op count and cycle time for a path.
00454   for (leafopl = tree->GetExitOpsPtr(); leafopl != NULL;
00455        leafopl = leafopl->GetNextListPtr())
00456     {
00457       leafop = leafopl->GetOpPtr();
00458       if (leafop == NULL)
00459         {
00460           LegoNonFatal ("EstimateNew", "Can't find leaf of treegion %d.",
00461                         tree->GetRegionId());
00462           continue;
00463         } // end if
00464 
00465       // For this exit op, iterate over each treegion exit that emanates
00466       // from it. If it's an RTS, assume the presence of one edge with
00467       // the frequency of the op.
00468       isRTS = (leafop->IsRETOp() ||
00469               leafop->IsBRLExitOp()); //HZ: also consider the br.call exit
00470       if (isRTS)
00471         exits = NULL;
00472       else
00473         exits = ((legoRegion *) leafop->GetParentBlockPtr())->
00474           GetOutEdgesPtr();
00475       while (exits != NULL || isRTS)
00476         {
00477           if (exits != NULL)
00478             {
00479               exitedge = exits->GetEdgePtr();
00480               if (exitedge == NULL)
00481                 {
00482                   LegoNonFatal ("EstimateNew", "Can't find exit edge of "
00483                                 "treegion %d.", tree->GetRegionId());
00484                   exits = exits->GetNextListPtr();
00485                   continue;
00486                 } // end if
00487 
00488               // Before using this edge, check that it's actually a
00489               // treegion exit edge and that it emanates from leafop.
00490               for (treeexits = tree->GetOutEdgesPtr(); treeexits != NULL;
00491                    treeexits = treeexits->GetNextListPtr())
00492                 if (treeexits->GetEdgePtr() == exitedge) break;
00493               // (Use treeexits as a convenient way to flag that the
00494               // exit edge doesn't emanate from leafop.)
00495               if (exitedge->GetFromOpPtr() != leafop) treeexits = NULL;
00496               if (treeexits == NULL)
00497                 {
00498                   exits = exits->GetNextListPtr();  // skip it
00499                   continue;
00500                 } // end if
00501 
00502               // The path weight is the weight of the edge exiting.
00503               weight = (double) FindEdgeFrequency (exitedge);
00504             } // end if
00505           else
00506             {
00507               exitedge = NULL;
00508               if (FindLcAttribute( "orig_wt", leafop ) != NULL) {
00509                 weight = FindLcAttribute( "orig_wt", leafop )->GetAttrOprdPtr()->GetLiteralDouble();
00510               }
00511               else {
00512                 weight = FindOpWeight (leafop);  // path weight = RTS weight
00513               }
00514             } // end else
00515 
00516           dvprintf ((OUTF, ". beginning path to exit edge %d (op %d), weight "
00517                      "%lf.\n", (exitedge != NULL ? exitedge->GetEdgeId() :
00518                                 0),
00519                      leafop->GetOpId(), weight));
00520 
00521           // Before going through all the rigamarole, if this path has
00522           // no weight, skip it completely.
00523           if (weight == 0)
00524             {
00525               dvprintf ((OUTF, ". path has zero weight - skipping!\n"));
00526               if (!isRTS)
00527                 exits = exits->GetNextListPtr();
00528               isRTS = 0;
00529               continue;
00530             } // end if
00531 
00532           // Walk up the block branchops from the leafop to the root branchop, 
00533           // forming a opList in reverse order as you go.
00534           branchops = NULL;
00535           for (branchop = leafop;
00536                branchop != NULL;
00537                branchop = ((legoRegion *)branchop->GetParentBlockPtr())->GetInEdgesPtr()->GetEdgePtr()->GetFromOpPtr()) {
00538             oplist = new opList();
00539             oplist->SetOpPtr(branchop);
00540             oplist->SetValid(1); 
00541             if (branchops == NULL) {
00542               branchops = oplist;
00543             }
00544             else {
00545               oplist->SetNextListPtr(branchops); 
00546               branchops = oplist; 
00547             }
00548             if (branchop->GetParentBlockPtr() == tree->GetRoot()) break;
00549           }
00550           if (branchop == NULL)
00551             {
00552               LegoNonFatal ("EstimateNew", "Failed walking to root from op %d "
00553                             "in treegion %d.", leafop->GetOpId(),
00554                             tree->GetRegionId());
00555               if (!isRTS)
00556                 exits = exits->GetNextListPtr();
00557               isRTS = 0;
00558               continue;
00559             } // end if
00560 
00561           // Now proceed down the path from root to leaf, calculating the 
00562           // timespan and op count for each BB in path.
00563           for (oplist = branchops; 
00564                oplist != NULL; 
00565                oplist = oplist->GetNextListPtr()) {
00566 
00567             branchop = oplist->GetOpPtr();
00568             block = (legoRegion *) branchop->GetParentBlockPtr();
00569             dvprintf ((OUTF, "... looking at block %d.\n",
00570                        block->GetRegionId()));
00571             
00572             topop = block->GetEntryOpsPtr()->GetOpPtr();
00573             topop_s_time = topop->GetSchedTime();
00574             dvprintf ((OUTF, "... topop is %d.\n",
00575                        topop->GetOpId()));
00576             // Count the real ops in this block while stepping 
00577             // through to branchop
00578             all_ops_speculated = TRUE;
00579             // finalop is the last op in branchop's multiop
00580             for (finalop = branchop;
00581                  ((finalop->GetNextLink() != NULL) &&  
00582                   (finalop->GetNextLink()->GetSchedTime() == 
00583                    branchop->GetSchedTime())); 
00584                  finalop = finalop->GetNextLink())
00585               ; // just increment finalop
00586             for (bottomop = topop->GetNextLink(), opct = 0;
00587                  bottomop != NULL && bottomop != finalop;
00588                  bottomop = bottomop->GetNextLink())  // until branchop multiop
00589               {
00590                 if (!(bottomop->IsDummy())) {
00591                   opct++;  // count real ops in block
00592                   if (bottomop->GetSchedTime() >= topop_s_time)
00593                     all_ops_speculated = FALSE;
00594                 }
00595               } // end for
00596             
00597             if (bottomop == NULL)
00598               {
00599                 LegoNonFatal ("EstimateNew", "Couldn't find branch after "
00600                               "op %d in region %d.", topop->GetOpId(),
00601                               block->GetRegionId());
00602                 return;
00603               } // end if
00604             bottomop_s_time = bottomop->GetSchedTime();
00605             if (!(bottomop->IsDummy())) opct++;  // bottomop for opct
00606             dvprintf ((OUTF, "... bottomop is %d.\n",
00607                        bottomop->GetOpId()));
00608             
00609             // Now calculate the timespan...
00610             if (topop_s_time == bottomop_s_time)  // possibly all ops 
00611               // spec'd in BB
00612               {
00613                 if (all_ops_speculated) 
00614                   if (IsTreeExitandDummyBr(bottomop, tree)) {
00615                     timespan = 0.0;
00616                     // this BB can be removed
00617                   }
00618                   else {
00619                     timespan = 1.0;
00620                     // if bottomop is a DUMMY_BR and BB still has 
00621                     // all_ops_speculated even after speculative code 
00622                     // motion is implemented, this BB can then be 
00623                     // removed safely and then timespan = 0.0
00624                   }
00625                 else 
00626                   timespan = 1.0;
00627               } // end if
00628             else  // all ops NOT spec'd
00629               {
00630                 timespan = bottomop_s_time - topop_s_time + 1;
00631               } // end else
00632             
00633             // Remember we're using the path weight.
00634             // # cycles = schedule length of subblock * subblock weight
00635             st->numCycles += timespan * weight;
00636             // # dynamic ops = # ops in subblock * subblock weight
00637             st->numDynamicOps += ((double) opct) * weight;
00638 #ifdef STATIC_ESTIMATE_DEBUG
00639             nc += timespan * weight;
00640             ndo += ((double) opct) * weight;
00641 #endif
00642             dvprintf ((OUTF, "... path weight is %lf.\n", weight));
00643             dvprintf ((OUTF, "... timespan of %lf gives %lf cycles.\n",
00644                        timespan, timespan * weight));
00645             dvprintf ((OUTF, "... %d ops counted gives %lf dynamic.\n",
00646                        opct, ((double) opct) * weight));
00647             
00648           } // end for (each block in path)
00649           
00650           // Move to next path from this leaf.
00651           if (!isRTS)
00652             exits = exits->GetNextListPtr();  // go to next exit
00653           isRTS = 0;  // only do RTS once
00654           delete branchops;
00655         }  // end while (there's a path from the leaf)
00656       
00657     } // end for (each leaf)
00658   
00659   dprintf ((OUTF, "EstimateNew TREE %d\t%lf cycles\t%lf ops\n",
00660             tree->GetRegionId(), nc, ndo));
00661   return;
00662 } // end EstimateNew (tree)
00663 
00664 static_stats *
00665 StaticEstimate (legoRegion *region)
00666 {
00667   static_stats *st, *cst;
00668   unsigned i;
00669 
00670   st = new static_stats;
00671 
00672   switch (region->GetRegionType())
00673     {
00674     case RT_BB:
00675       Estimate ((legoBB *) region, st);
00676       break;
00677     case RT_SB:
00678     case RT_HB:
00679       Estimate (region, st);
00680       break;
00681     case RT_TREE:
00682 //      Estimate ((legoTreegion *) region, st);
00683       EstimateNew ((legoTreegion *) region, st);
00684       break;
00685     case RT_TRACE:  // not an estimate for trace scheduling!
00686     case RT_LOOP:
00687     case RT_LOOPBODY:
00688     case RT_PROC:
00689     case RT_MODULE:
00690       // Do the components.
00691       for (i = 0; i < region->GetCount(); i++)
00692         {
00693           cst = StaticEstimate ((legoRegion *) region->GetItem (i));
00694           st->numCycles += cst->numCycles;
00695           st->numDynamicOps += cst->numDynamicOps;
00696           delete cst;
00697         } // for
00698       break;
00699     default:
00700       LegoNonFatal ("StaticEstimate", "Estimation of region type %d is not "
00701                     "done yet.", region->GetRegionType());
00702       break;
00703     } // end switch
00704 
00705   if (region->GetRegionType() == RT_PROC)
00706     dprintf ((OUTF, "Estimate PROC %s:\n%lf cycles\t\t%lf ops\n",
00707               ((legoProc *) region)->GetProcName(), st->numCycles,
00708               st->numDynamicOps));
00709   //  if (region->GetRegionType() == RT_MODULE)
00710   //    dprintf ((OUTF, "Estimate for module:\n%lf cycles\t\t%lf ops\n",
00711   //          ((legoModule *) region)->GetModuleName(), st->numCycles,
00712   //          st->numDynamicOps));
00713   return st;
00714 } // end StaticEstimate

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