00001 #ifndef _INCLUDE_DAG_NODE_ORDERING_H_
00002 #define _INCLUDE_DAG_NODE_ORDERING_H_
00003
00004
00005
00006
00007
00008
00009
00010 #include <TinkerKnobs.H>
00011 #include <dag.H>
00012 #include <machine.h>
00013
00014 #include <search.H>
00015 #include <assert.h>
00016
00017
00018 #if defined (_DAG_NODE_ORDERING_DEBUG_)
00019 #define public_derr(s) cerr << s
00020 #else
00021 #define public_derr(s)
00022 #endif
00023
00024 static double
00025 GetCountHelped (DagNode *node)
00026 {
00027 legoOp *nodeop = node->GetOp();
00028 legoRegion *region;
00029 opList *exitops;
00030 double numhelped;
00031
00032 if (nodeop == NULL) return 0.0;
00033 for (region = (legoRegion *) nodeop->GetParentBlockPtr();
00034 region->GetRegionType() != RT_TREE &&
00035 region->GetRegionType() != RT_SB &&
00036 region->GetRegionType() != RT_HB &&
00037 region->GetRegionType() != RT_PROC;
00038 region = region->GetParentPtr()) ;
00039 if (region->GetRegionType() == RT_PROC)
00040 return 1.0;
00041
00042 exitops = region->GetExitOpsPtr();
00043 numhelped = 0.0;
00044
00045 if (region->GetRegionType() == RT_SB || region->GetRegionType() == RT_HB)
00046 {
00047 for (opList *opl = exitops; opl != NULL; opl = opl->GetNextListPtr())
00048 {
00049 for (legoOp *op = opl->GetOpPtr(); op != NULL;
00050 op = op->GetPrevLink())
00051 if (op == nodeop)
00052 {
00053 numhelped += 1.0;
00054 break;
00055 }
00056 }
00057 return numhelped;
00058 }
00059
00060 if (region->GetRegionType() == RT_TREE)
00061 {
00062 for (opList *opl = exitops; opl != NULL; opl = opl->GetNextListPtr())
00063 {
00064 legoOp *op = opl->GetOpPtr();
00065 while (op != NULL)
00066 {
00067 if (op == nodeop)
00068 {
00069 numhelped += 1.0; break;
00070 }
00071 if (op->GetPrevLink() != NULL)
00072 op = op->GetPrevLink();
00073 else if ((legoRegion *) op->GetParentBlockPtr() !=
00074 ((legoTreegion *) region)->GetRoot())
00075 {
00076 op = ((legoRegion *) op->GetParentBlockPtr())
00077 ->GetParents()->GetRegionPtr()->GetExitOpsPtr()
00078 ->GetOpPtr();
00079 }
00080 else op = NULL;
00081 }
00082 }
00083 return numhelped;
00084 }
00085
00086 return 0.0;
00087 }
00088
00089 static double
00090 GetGlobalWeight (DagNode *node)
00091 {
00092 legoOp *nodeop = node->GetOp();
00093 machine *mach = new machine();
00094 legoOp *blockop, *prevblockop;
00095 opList *opl;
00096 attrs *a;
00097
00098 public_derr( ">> GetGlobalWeight: Op " << node->GetOp()->GetOpId() << "\n" );
00099 legoRegion* tttt = (legoRegion*)(nodeop->GetParentBlockPtr());
00100
00101 if (tttt->GetRegionType() == RT_BB)
00102 return tttt->GetWeight();
00103
00104 if ( nodeop->GetPrevLink() == NULL ) return tttt->GetWeight();
00105
00106
00107
00108 if ((tttt->GetRegionType() == RT_HB) &&
00109 (FindLcAttribute( "use_orig_wt", tttt) != NULL )) {
00110
00111 a = FindLcAttribute( "orig_wt", nodeop ) ;
00112 return (a->GetAttrOprdPtr()->GetLiteralDouble());
00113 }
00114
00115 for (prevblockop = nodeop, blockop = nodeop->GetPrevLink();
00116 (mach->TinkerOptype (blockop) != BR_OP ||
00117 blockop->GetOpcode() == BRL) && blockop->GetPrevLink() != NULL ||
00118 (blockop->GetOpcode() == C_MERGE && blockop->GetPrevLink() != NULL);
00119 prevblockop = blockop,
00120 blockop = blockop->GetPrevLink()) ;
00121
00122 public_derr( " About to call TinkerOptype\n" );
00123 if (mach->TinkerOptype (blockop) == BR_OP)
00124 {
00125 delete mach;
00126 public_derr( " Getting weight\n" );
00127
00128
00129 if (blockop->GetOpcode() == C_MERGE )
00130 return tttt->GetWeight();
00131 for (opl = blockop->GetOutListPtr(); opl != NULL;
00132 opl = opl->GetNextListPtr())
00133 if (opl->GetOpId() == prevblockop->GetOpId())
00134 return opl->GetWeight();
00135 cerr << "Can't find oplist from " << blockop->GetOpId()
00136 << " to " << prevblockop->GetOpId() << "\n";
00137 return 0.0;
00138 }
00139 else
00140 {
00141 delete mach;
00142 return tttt->GetWeight();
00143 }
00144 }
00145
00146 class VLilist
00147 {
00148 public:
00149 VectorList::iterator p;
00150 int depth;
00151 class VLilist *next;
00152
00153 VLilist() {p = NULL; depth = 0; next = NULL;}
00154 VLilist (VectorList::iterator iter)
00155 {p = iter; depth = (*p).GetDepth(); next = NULL;}
00156 ~VLilist() {delete next;}
00157 };
00158
00159 enum node_orderings { DEPENDENCE_HEIGHT, EXIT_COUNT, GLOBAL_WEIGHT,
00160 WEIGHTED_COUNT };
00161
00162 class dag_node_ordering {
00163
00164 private:
00165
00166 node_orderings Ordering;
00167 legoRegion *Region;
00168 dag *D;
00169 int sb_override;
00170
00171
00172 void dag_node_ordering::DoSuperblockPriorities ()
00173 {
00174 VectorList::iterator Front, Back, Current, Predecessor, Step4;
00175 VLilist *queue, *cur, *vliscan;
00176 vector <SmallListElement>::iterator PredIter;
00177 machine *mach = new machine();
00178 int i, maxlevel = 0, brweight;
00179 opList *opl;
00180
00181
00182
00183
00184 D->SetNodeDepths();
00185
00186
00187 #if defined (_STL_LIST_USED_)
00188 Back = D->Vector.end();
00189 for (Front = D->Vector.begin(); Front != Back; Front++)
00190 #else if defined (_STL_VECTOR_USED_)
00191 Back = D->MasterList.end();
00192 for (Front = D->MasterList.begin(); Front != Back; Front++)
00193 #endif
00194 {
00195 if ((*Front).GetDepth() > maxlevel)
00196 maxlevel = (*Front).GetDepth();
00197 }
00198 public_derr ("Max. depth = " << maxlevel << "\n");
00199
00200 #if defined (_STL_LIST_USED_)
00201 for (Front = D->Vector.begin(); Front != Back; Front++)
00202 #else if defined (_STL_VECTOR_USED_)
00203 for (Front = D->MasterList.begin(); Front != Back; Front++)
00204 #endif
00205 {
00206 if (mach->TinkerOptype ((*Front).GetOp()) == BR_OP &&
00207 (*Front).GetOp()->GetOpcode() != BRL &&
00208 (*Front).GetOp()->GetOpcode() != C_MERGE)
00209
00210 {
00211 (*Front).SetDepth (maxlevel - (*Front).GetDepth() + 1);
00212 public_derr ("Setting branch " << (*Front).GetOp()->GetOpId() <<
00213 " path length to " << (*Front).GetDepth() << "\n");
00214 }
00215 (*Front).Value = 0;
00216 }
00217
00218
00219
00220
00221 #if defined (_STL_LIST_USED_)
00222 for (Front = D->Vector.begin(); Front != Back; Front++)
00223 #else if defined (_STL_VECTOR_USED_)
00224 for (Front = D->MasterList.begin(); Front != Back; Front++)
00225 #endif
00226 {
00227 if (mach->TinkerOptype ((*Front).GetOp()) != BR_OP ||
00228 (*Front).GetOp()->GetOpcode() == BRL ||
00229 (*Front).GetOp()->GetOpcode() == C_MERGE)
00230 continue;
00231
00232
00233 if ((*Front).GetOp()->GetOpcode() != RTS)
00234 {
00235 brweight = 0;
00236 for (opl = (*Front).GetOp()->GetOutListPtr(); opl != NULL;
00237 opl = opl->GetNextListPtr())
00238 {
00239 if (opl->GetOpPtr() != (*Front).GetOp()->GetNextLink())
00240 brweight += (int) opl->GetWeight();
00241 }
00242 }
00243 else
00244 {
00245 legoOp *op, *prevop;
00246
00247 for (prevop = (*Front).GetOp(), op = prevop->GetPrevLink();
00248 (mach->TinkerOptype (op) != BR_OP ||
00249 op->GetOpcode() == BRL || op->GetOpcode() == C_MERGE)
00250 && op->GetPrevLink() != NULL;
00251 prevop = op, op = op->GetPrevLink()) ;
00252 brweight = 0;
00253 if (mach->TinkerOptype (op) == BR_OP)
00254 {
00255 for (opl = op->GetOutListPtr(); opl != NULL;
00256 opl = opl->GetNextListPtr())
00257 if (opl->GetOpId() == prevop->GetOpId())
00258 {
00259 brweight += (int) opl->GetWeight();
00260 }
00261 }
00262 else
00263 {
00264 brweight += (int) ((legoRegion *) op->GetParentBlockPtr())
00265 ->GetWeight();
00266 }
00267 }
00268 public_derr ("Branch " << (*Front).GetOp()->GetOpId() <<
00269 " has branch weight " << brweight << "\n");
00270
00271 (*Front).Value += (brweight * (*Front).GetDepth());
00272
00273
00274 queue = new VLilist (Front);
00275 while (queue != NULL)
00276 {
00277 cur = queue;
00278 queue = queue->next;
00279 Current = cur->p;
00280 cur->next = NULL;
00281 delete cur;
00282 public_derr ("Dequeued op " << (*Current).GetOp()->GetOpId() << "\n");
00283
00284
00285 for (PredIter = (*Current).Predecessors->begin();
00286 PredIter != (*Current).Predecessors->end(); PredIter++)
00287 {
00288 Predecessor = (*PredIter).GetDagEntry();
00289
00290
00291 if ((*PredIter).GetDependencyType() == ET_CNTL ||
00292 (*PredIter).GetDependencyType() == ET_REGANTI)
00293
00294 {
00295 if ((*Current).GetDepth() > (*Predecessor).GetDepth())
00296 {
00297 (*Predecessor).SetDepth ((*Current).GetDepth());
00298
00299 cur = new VLilist (Predecessor);
00300 cur->next = queue;
00301 queue = cur;
00302 public_derr ("Enqueued op " <<
00303 (*Predecessor).GetOp()->GetOpId() << "\n");
00304
00305 for (vliscan = queue; vliscan->next != NULL;
00306 vliscan = vliscan->next)
00307 if (vliscan->next->p == Predecessor &&
00308 vliscan->next->depth <=
00309 (*Predecessor).GetDepth())
00310 {
00311 cur = vliscan->next;
00312 vliscan->next = cur->next;
00313 cur->next = NULL;
00314 public_derr ("Killing a queue entry.\n");
00315 delete cur;
00316
00317 if (vliscan->next == NULL) break;
00318 }
00319 }
00320 }
00321 else
00322 {
00323 if ((*Current).GetDepth() +
00324 mach->opLatency ((*Predecessor).GetOp()) >
00325 (*Predecessor).GetDepth())
00326 {
00327
00328 (*Predecessor).SetDepth ((*Current).GetDepth() +
00329 mach->opLatency
00330 ((*Predecessor).GetOp()));
00331
00332 cur = new VLilist (Predecessor);
00333 cur->next = queue;
00334 queue = cur;
00335 public_derr ("Enqueued op " <<
00336 (*Predecessor).GetOp()->GetOpId() << "\n");
00337
00338 for (vliscan = queue; vliscan->next != NULL;
00339 vliscan = vliscan->next)
00340 if (vliscan->next->p == Predecessor &&
00341 vliscan->next->depth <=
00342 (*Predecessor).GetDepth())
00343 {
00344 cur = vliscan->next;
00345 vliscan->next = cur->next;
00346 cur->next = NULL;
00347 public_derr ("Killing a queue entry.\n");
00348 delete cur;
00349
00350 if (vliscan->next == NULL) break;
00351 }
00352 }
00353 }
00354
00355 }
00356 public_derr ("Done with predecessors of op " <<
00357 (*Current).GetOp()->GetOpId() << "\n");
00358 }
00359
00360
00361 #if defined (_STL_LIST_USED_)
00362 for (Step4 = D->Vector.begin(); Step4 != Back; Step4++)
00363 #else if defined (_STL_VECTOR_USED_)
00364 for (Step4 = D->MasterList.begin(); Step4 != Back; Step4++)
00365 #endif
00366 {
00367
00368
00369 (*Step4).Value += (brweight * (*Step4).GetDepth());
00370 public_derr ("Op " << (*Step4).GetOp()->GetOpId() <<
00371 " now has priority " << (*Step4).Value << "\n");
00372 }
00373 }
00374
00375 public_derr ("Done!\n");
00376 D->SetNodeDepths();
00377 delete mach;
00378 return;
00379 }
00380
00381 public:
00382
00383
00384 dag_node_ordering() {}
00385
00386
00387 dag_node_ordering( legoRegion *R )
00388 {
00389 public_derr( ">> dag_node_ordering\n" );
00390 Region = R;
00391 D = (dag *) R->GetDAG();
00392 public_derr( "<< dag_node_ordering\n" );
00393 }
00394
00395 ~dag_node_ordering() {}
00396
00397
00398
00399
00400
00401 void ShowParameters( knobs *Knobs )
00402 {
00403 char *string, flag;
00404
00405 Knobs->SetDefaultPanel( "dag-node-ordering" );
00406 Knobs->Read( "node-ordering", string );
00407 cout << "> Scheduling node ordering: " << string << "\n";
00408 Knobs->Read( "superblock-override", flag );
00409 if ( flag == KNOB_TRUE ) cout << "> Override superblock heuristic\n";
00410 }
00411
00412
00413
00414 void SetKnobs( knobs *Knobs )
00415 {
00416
00417 public_derr( ">> dag_node_ordering::SetKnobs\n" );
00418 Ordering = DEPENDENCE_HEIGHT;
00419 sb_override = 0;
00420 if ( Knobs != NULL ) {
00421
00422 char flag;
00423 char *string;
00424
00425 Knobs->SetDefaultPanel( "dag-node-ordering" );
00426 Knobs->Read( "node-ordering", string );
00427 public_derr( " node ordering selected: " << string << "\n" );
00428 if ( strcmp( string, "none" ) == 0 ||
00429 strcmp( string, "dependence-height" ) == 0 )
00430 Ordering = DEPENDENCE_HEIGHT;
00431 else if ( strcmp( string, "exit-count" ) == 0 )
00432 Ordering = EXIT_COUNT;
00433 else if ( strcmp( string, "global-weight" ) == 0 )
00434 Ordering = GLOBAL_WEIGHT;
00435 else if ( strcmp( string, "weighted-count" ) == 0 )
00436 Ordering = WEIGHTED_COUNT;
00437 Knobs->Read( "superblock-override", flag );
00438 if ( flag == KNOB_TRUE ) sb_override = 1;
00439 public_derr( " sb_override: " << sb_override << "\n" );
00440 }
00441 public_derr( " Node ordering: " );
00442 switch (Ordering) {
00443 case DEPENDENCE_HEIGHT: public_derr( "dependence height\n" );
00444 case EXIT_COUNT: public_derr( "exit count\n" );
00445 case GLOBAL_WEIGHT: public_derr( "global weight\n" );
00446 case WEIGHTED_COUNT: public_derr( "weighted count\n" );
00447 }
00448 public_derr( "<< SetKnobs\n" );
00449 }
00450
00451
00452
00453 SetValueToDepth()
00454 {
00455 VectorList::iterator Front, Back;
00456 int i, size;
00457
00458 public_derr( ">> dag_node_ordering::SetValueToDepth " );
00459 #if defined (_STL_LIST_USED_)
00460 for ( i= 0, Front = D->Vector.begin(), Back = D->Vector.end();
00461 Front != Back; Front++, i++ ) {
00462 #else if defined (_STL_VECTOR_USED_)
00463 for ( i= 0, Front = D->MasterList.begin(), Back = D->MasterList.end();
00464 Front != Back; Front++, i++ ) {
00465 #endif
00466 public_derr( " Node # " << i << ", depth " << (*Front).GetDepth()
00467 << "\n" );
00468 (*Front).Value = (*Front).GetDepth();
00469 }
00470 public_derr( "<< dag_node_ordering::SetValueToDepth\n" );
00471 }
00472
00473
00474
00475 SetValueToWeight()
00476 {
00477 VectorList::iterator Front, Back;
00478 int i, size;
00479
00480 public_derr( ">> dag_node_ordering::SetValueToWeight" );
00481 #if defined (_STL_LIST_USED_)
00482 for ( i= 0, Front = D->Vector.begin(), Back = D->Vector.end();
00483 Front != Back; Front++, i++ ) {
00484 #else if defined (_STL_VECTOR_USED_)
00485 for ( i= 0, Front = D->MasterList.begin(), Back = D->MasterList.end();
00486 Front != Back; Front++, i++ ) {
00487 #endif
00488 public_derr( " Node # " << i << ", weight " << (*Front).GetDepth()
00489 << "\n" );
00490 (*Front).Value = (*Front).GetWeight();
00491 }
00492 public_derr( "<< dag_node_ordering::SetValueToWeight\n" );
00493 }
00494
00495
00496 void SetDagValues()
00497 {
00498 VectorList::iterator Front, Back;
00499 int i, region_type = Region->GetRegionType();
00500
00501
00502 public_derr( ">> SetDagValues\n" );
00503
00504 #if defined (_STL_LIST_USED_)
00505 Back = D->Vector.end();
00506 Front = D->Vector.begin();
00507 #else if defined (_STL_VECTOR_USED_)
00508 Back = D->MasterList.end();
00509 Front = D->MasterList.begin();
00510 #endif
00511
00512
00513 if ( region_type == RT_BB ) Ordering = DEPENDENCE_HEIGHT;
00514 {
00515 legoRegion *scan;
00516 int foundSB = 0, foundTREE = 0;
00517
00518 for (scan = ((legoRegion *) (*Front).GetOp()->GetParentBlockPtr());
00519 scan->GetRegionType() != RT_PROC;
00520 scan = scan->GetParentPtr())
00521 {
00522
00523 if (scan->GetFlagPtr() != NULL &&
00524 scan->GetFlagPtr()->GetFlagName() == SB)
00525 foundSB = 1;
00526 if (scan->GetRegionType() == RT_TREE)
00527 foundTREE = 1;
00528 }
00529 if (foundSB && !foundTREE)
00530 {
00531 DoSuperblockPriorities();
00532 D->SortByHeight();
00533
00534
00535
00536 if ( sb_override == 1 ) {
00537 #if defined (_STL_LIST_USED_)
00538 for (Front = D->Vector.begin(); Front != Back; Front++)
00539 #else if defined (_STL_VECTOR_USED_)
00540 for (Front = D->MasterList.begin(); Front != Back; Front++)
00541 #endif
00542 (*Front).Value = (*Front).GetHeight();
00543 }
00544 D->SortByValue();
00545 return;
00546 }
00547 }
00548
00549 #if defined (_STL_LIST_USED_)
00550 for (Front = D->Vector.begin(); Front != Back; Front++)
00551 # else if defined (_STL_VECTOR_USED_)
00552 for (Front = D->MasterList.begin(); Front != Back; Front++)
00553 #endif
00554 {
00555 int opcode = (*Front).GetOp()->GetOpcode();
00556 if (opcode == BRDVI || opcode == BRDVF ||
00557 (opcode >= BRU && opcode <= BRCF) ||
00558 (opcode >= RTS && opcode <= BRW_F_F_F))
00559 (*Front).Value = 1.0;
00560 else
00561 (*Front).Value = 2.0;
00562 }
00563
00564 D->SetNodeHeights();
00565 D->SortByHeight();
00566
00567 if ( Ordering == DEPENDENCE_HEIGHT )
00568 public_derr( " Dependence height\n" );
00569
00570 else if ( Ordering == EXIT_COUNT )
00571 {
00572 public_derr( " Helped count\n" );
00573 #if defined (_STL_LIST_USED_)
00574 for (i = 0, Front = D->Vector.begin(); Front != Back; Front++, i++)
00575 #else if defined (_STL_VECTOR_USED_)
00576 for (i = 0, Front = D->MasterList.begin(); Front != Back; Front++, i++)
00577 #endif
00578 {
00579 (*Front).Value = GetCountHelped (Front);
00580 public_derr ("Node " << i << " has " << (*Front).Value << "\n");
00581 }
00582 D->SortByValue();
00583 }
00584
00585 else if ( Ordering == GLOBAL_WEIGHT )
00586 {
00587 public_derr( " Global weight\n" );
00588 #if defined (_STL_LIST_USED_)
00589 for (Front = D->Vector.begin(); Front != Back; Front++)
00590 #else if defined (_STL_VECTOR_USED_)
00591 for (Front = D->MasterList.begin(); Front != Back; Front++)
00592 #endif
00593 (*Front).Value = GetGlobalWeight (Front);
00594 D->SortByValue();
00595 }
00596
00597 else if ( Ordering == WEIGHTED_COUNT )
00598 {
00599 public_derr( " Weighted count\n" );
00600 #if defined (_STL_LIST_USED_)
00601 for (Front = D->Vector.begin(); Front != Back; Front++)
00602 #else if defined (_STL_VECTOR_USED_)
00603 for (Front = D->MasterList.begin(); Front != Back; Front++)
00604 #endif
00605 (*Front).Value = GetCountHelped (Front);
00606 D->SortByValue();
00607 #if defined (_STL_LIST_USED_)
00608 for (Front = D->Vector.begin(); Front != Back; Front++)
00609 #else if defined (_STL_VECTOR_USED_)
00610 for (Front = D->MasterList.begin(); Front != Back; Front++)
00611 #endif
00612 (*Front).Value = GetGlobalWeight (Front);
00613 D->SortByValue();
00614 }
00615
00616 public_derr( "<< SetDagValues\n" );
00617 return;
00618 }
00619
00620 };
00621
00622 #endif