00001
00002
00003
00004 #include "lego.H"
00005 #include "legoUtil.H"
00006 #include "static.H"
00007
00008
00009
00010 #ifdef STATIC_ESTIMATE_DEBUG
00011
00012 #define dprintf(s) fprintf s
00013 #define OUTF stderr
00014
00015
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
00046
00047
00048
00049
00050
00051
00052
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 }
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 }
00078
00079 if (toop != fromop)
00080 {
00081 currtime = toop->GetSchedTime();
00082 if (currtime < mintime) mintime = currtime;
00083 if (currtime > maxtime) maxtime = currtime;
00084 }
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 }
00091
00092 return (maxtime - mintime + 1);
00093 }
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
00108 st->numCycles += timespan * weight;
00109
00110
00111
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 }
00118
00119 static void
00120 Estimate (legoRegion *hb, static_stats *st)
00121 {
00122 legoOp *topop, *bottomop;
00123
00124 double timespan, weight;
00125
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
00134
00135
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
00143
00144
00145 for (bottomop = topop->GetNextLink(), opct = 0;
00146 bottomop != NULL && bottomop->GetOutListPtr() == NULL;
00147 bottomop = bottomop->GetNextLink())
00148 {
00149 if (!(bottomop->IsDummy())) opct++;
00150
00151
00152
00153
00154
00155
00156
00157
00158 }
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 }
00166 if (!(bottomop->IsDummy())) opct++;
00167
00168
00169
00170
00171 dvprintf ((OUTF, "... bottomop is %d.\n", bottomop->GetOpId()));
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 timespan = (double) (bottomop->GetSchedTime() - lastpathcycle);
00184
00185 weight = FindOpWeight (topop);
00186
00187
00188 st->numCycles += timespan * weight;
00189
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
00202
00203 lastpathcycle = bottomop->GetSchedTime();
00204 topop = bottomop->GetNextLink();
00205 }
00206
00207 dprintf ((OUTF, "Estimate HB %d\t%lf cycles\t%lf ops\n", hb->GetRegionId(),
00208 nc, ndo));
00209 return;
00210 }
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
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
00232
00233
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 }
00244
00245
00246
00247
00248 isRTS = (leafop->IsRETOp() ||
00249 leafop->IsBRLExitOp());
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 }
00267
00268
00269
00270 for (treeexits = tree->GetOutEdgesPtr(); treeexits != NULL;
00271 treeexits = treeexits->GetNextListPtr())
00272 if (treeexits->GetEdgePtr() == exitedge) break;
00273
00274
00275 if (exitedge->GetFromOpPtr() != leafop) treeexits = NULL;
00276 if (treeexits == NULL)
00277 {
00278 exits = exits->GetNextListPtr();
00279 continue;
00280 }
00281
00282
00283 weight = (double) FindEdgeFrequency (exitedge);
00284 }
00285 else
00286 {
00287 exitedge = NULL;
00288 weight = FindOpWeight (leafop);
00289 }
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
00297
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 }
00306
00307
00308
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 }
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 }
00331
00332
00333
00334
00335
00336
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
00344
00345
00346
00347
00348 topop = block->GetEntryOpsPtr()->GetOpPtr();
00349 topop_s_time = topop->GetSchedTime();
00350 dvprintf ((OUTF, "... topop is %d.\n",
00351 topop->GetOpId()));
00352
00353
00354 all_ops_speculated = TRUE;
00355 for (bottomop = topop->GetNextLink(), opct = 0;
00356 bottomop != NULL && bottomop->GetOutListPtr() == NULL;
00357 bottomop = bottomop->GetNextLink())
00358 {
00359 if (!(bottomop->IsDummy())) {
00360 opct++;
00361 if (bottomop->GetSchedTime() >= topop_s_time)
00362 all_ops_speculated = FALSE;
00363 }
00364 }
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 }
00373 bottomop_s_time = bottomop->GetSchedTime();
00374 if (!(bottomop->IsDummy())) opct++;
00375 dvprintf ((OUTF, "... bottomop is %d.\n",
00376 bottomop->GetOpId()));
00377
00378
00379 if (topop_s_time == bottomop_s_time)
00380
00381 {
00382 if (all_ops_speculated)
00383 if (IsTreeExitandDummyBr(bottomop, tree)) {
00384 timespan = 0.0;
00385
00386 }
00387 else {
00388 timespan = 1.0;
00389
00390
00391
00392
00393 }
00394 else
00395 timespan = 1.0;
00396 }
00397 else
00398 {
00399 timespan = bottomop_s_time - topop_s_time + 1;
00400 }
00401
00402
00403
00404 st->numCycles += timespan * weight;
00405
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 }
00418
00419
00420 if (!isRTS)
00421 exits = exits->GetNextListPtr();
00422 isRTS = 0;
00423 delete path;
00424 }
00425
00426 }
00427
00428 dprintf ((OUTF, "Estimate TREE %d\t%lf cycles\t%lf ops\n",
00429 tree->GetRegionId(), nc, ndo));
00430 return;
00431 }
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
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
00452
00453
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 }
00464
00465
00466
00467
00468 isRTS = (leafop->IsRETOp() ||
00469 leafop->IsBRLExitOp());
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 }
00487
00488
00489
00490 for (treeexits = tree->GetOutEdgesPtr(); treeexits != NULL;
00491 treeexits = treeexits->GetNextListPtr())
00492 if (treeexits->GetEdgePtr() == exitedge) break;
00493
00494
00495 if (exitedge->GetFromOpPtr() != leafop) treeexits = NULL;
00496 if (treeexits == NULL)
00497 {
00498 exits = exits->GetNextListPtr();
00499 continue;
00500 }
00501
00502
00503 weight = (double) FindEdgeFrequency (exitedge);
00504 }
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);
00513 }
00514 }
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
00522
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 }
00531
00532
00533
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 }
00560
00561
00562
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
00577
00578 all_ops_speculated = TRUE;
00579
00580 for (finalop = branchop;
00581 ((finalop->GetNextLink() != NULL) &&
00582 (finalop->GetNextLink()->GetSchedTime() ==
00583 branchop->GetSchedTime()));
00584 finalop = finalop->GetNextLink())
00585 ;
00586 for (bottomop = topop->GetNextLink(), opct = 0;
00587 bottomop != NULL && bottomop != finalop;
00588 bottomop = bottomop->GetNextLink())
00589 {
00590 if (!(bottomop->IsDummy())) {
00591 opct++;
00592 if (bottomop->GetSchedTime() >= topop_s_time)
00593 all_ops_speculated = FALSE;
00594 }
00595 }
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 }
00604 bottomop_s_time = bottomop->GetSchedTime();
00605 if (!(bottomop->IsDummy())) opct++;
00606 dvprintf ((OUTF, "... bottomop is %d.\n",
00607 bottomop->GetOpId()));
00608
00609
00610 if (topop_s_time == bottomop_s_time)
00611
00612 {
00613 if (all_ops_speculated)
00614 if (IsTreeExitandDummyBr(bottomop, tree)) {
00615 timespan = 0.0;
00616
00617 }
00618 else {
00619 timespan = 1.0;
00620
00621
00622
00623
00624 }
00625 else
00626 timespan = 1.0;
00627 }
00628 else
00629 {
00630 timespan = bottomop_s_time - topop_s_time + 1;
00631 }
00632
00633
00634
00635 st->numCycles += timespan * weight;
00636
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 }
00649
00650
00651 if (!isRTS)
00652 exits = exits->GetNextListPtr();
00653 isRTS = 0;
00654 delete branchops;
00655 }
00656
00657 }
00658
00659 dprintf ((OUTF, "EstimateNew TREE %d\t%lf cycles\t%lf ops\n",
00660 tree->GetRegionId(), nc, ndo));
00661 return;
00662 }
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
00683 EstimateNew ((legoTreegion *) region, st);
00684 break;
00685 case RT_TRACE:
00686 case RT_LOOP:
00687 case RT_LOOPBODY:
00688 case RT_PROC:
00689 case RT_MODULE:
00690
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 }
00698 break;
00699 default:
00700 LegoNonFatal ("StaticEstimate", "Estimation of region type %d is not "
00701 "done yet.", region->GetRegionType());
00702 break;
00703 }
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
00710
00711
00712
00713 return st;
00714 }