LLVM API Documentation
00001 //===----- ScheduleDAGRRList.cpp - Reg pressure reduction list scheduler --===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This implements bottom-up and top-down register pressure reduction list 00011 // schedulers, using standard algorithms. The basic approach uses a priority 00012 // queue of available nodes to schedule. One at a time, nodes are taken from 00013 // the priority queue (thus in priority order), checked for legality to 00014 // schedule, and emitted if legal. 00015 // 00016 //===----------------------------------------------------------------------===// 00017 00018 #define DEBUG_TYPE "pre-RA-sched" 00019 #include "llvm/CodeGen/ScheduleDAGSDNodes.h" 00020 #include "llvm/CodeGen/SchedulerRegistry.h" 00021 #include "llvm/CodeGen/SelectionDAGISel.h" 00022 #include "llvm/Target/TargetRegisterInfo.h" 00023 #include "llvm/Target/TargetData.h" 00024 #include "llvm/Target/TargetMachine.h" 00025 #include "llvm/Target/TargetInstrInfo.h" 00026 #include "llvm/Support/Debug.h" 00027 #include "llvm/Support/Compiler.h" 00028 #include "llvm/ADT/PriorityQueue.h" 00029 #include "llvm/ADT/SmallSet.h" 00030 #include "llvm/ADT/Statistic.h" 00031 #include "llvm/ADT/STLExtras.h" 00032 #include <climits> 00033 #include "llvm/Support/CommandLine.h" 00034 using namespace llvm; 00035 00036 STATISTIC(NumBacktracks, "Number of times scheduler backtracked"); 00037 STATISTIC(NumUnfolds, "Number of nodes unfolded"); 00038 STATISTIC(NumDups, "Number of duplicated nodes"); 00039 STATISTIC(NumPRCopies, "Number of physical register copies"); 00040 00041 static RegisterScheduler 00042 burrListDAGScheduler("list-burr", 00043 "Bottom-up register reduction list scheduling", 00044 createBURRListDAGScheduler); 00045 static RegisterScheduler 00046 tdrListrDAGScheduler("list-tdrr", 00047 "Top-down register reduction list scheduling", 00048 createTDRRListDAGScheduler); 00049 00050 namespace { 00051 //===----------------------------------------------------------------------===// 00052 /// ScheduleDAGRRList - The actual register reduction list scheduler 00053 /// implementation. This supports both top-down and bottom-up scheduling. 00054 /// 00055 class VISIBILITY_HIDDEN ScheduleDAGRRList : public ScheduleDAGSDNodes { 00056 private: 00057 /// isBottomUp - This is true if the scheduling problem is bottom-up, false if 00058 /// it is top-down. 00059 bool isBottomUp; 00060 00061 /// AvailableQueue - The priority queue to use for the available SUnits. 00062 SchedulingPriorityQueue *AvailableQueue; 00063 00064 /// LiveRegDefs - A set of physical registers and their definition 00065 /// that are "live". These nodes must be scheduled before any other nodes that 00066 /// modifies the registers can be scheduled. 00067 unsigned NumLiveRegs; 00068 std::vector<SUnit*> LiveRegDefs; 00069 std::vector<unsigned> LiveRegCycles; 00070 00071 /// Topo - A topological ordering for SUnits which permits fast IsReachable 00072 /// and similar queries. 00073 ScheduleDAGTopologicalSort Topo; 00074 00075 public: 00076 ScheduleDAGRRList(MachineFunction &mf, 00077 bool isbottomup, 00078 SchedulingPriorityQueue *availqueue) 00079 : ScheduleDAGSDNodes(mf), isBottomUp(isbottomup), 00080 AvailableQueue(availqueue), Topo(SUnits) { 00081 } 00082 00083 ~ScheduleDAGRRList() { 00084 delete AvailableQueue; 00085 } 00086 00087 void Schedule(); 00088 00089 /// IsReachable - Checks if SU is reachable from TargetSU. 00090 bool IsReachable(const SUnit *SU, const SUnit *TargetSU) { 00091 return Topo.IsReachable(SU, TargetSU); 00092 } 00093 00094 /// WillCreateCycle - Returns true if adding an edge from SU to TargetSU will 00095 /// create a cycle. 00096 bool WillCreateCycle(SUnit *SU, SUnit *TargetSU) { 00097 return Topo.WillCreateCycle(SU, TargetSU); 00098 } 00099 00100 /// AddPred - adds a predecessor edge to SUnit SU. 00101 /// This returns true if this is a new predecessor. 00102 /// Updates the topological ordering if required. 00103 void AddPred(SUnit *SU, const SDep &D) { 00104 Topo.AddPred(SU, D.getSUnit()); 00105 SU->addPred(D); 00106 } 00107 00108 /// RemovePred - removes a predecessor edge from SUnit SU. 00109 /// This returns true if an edge was removed. 00110 /// Updates the topological ordering if required. 00111 void RemovePred(SUnit *SU, const SDep &D) { 00112 Topo.RemovePred(SU, D.getSUnit()); 00113 SU->removePred(D); 00114 } 00115 00116 private: 00117 void ReleasePred(SUnit *SU, const SDep *PredEdge); 00118 void ReleaseSucc(SUnit *SU, const SDep *SuccEdge); 00119 void CapturePred(SDep *PredEdge); 00120 void ScheduleNodeBottomUp(SUnit*, unsigned); 00121 void ScheduleNodeTopDown(SUnit*, unsigned); 00122 void UnscheduleNodeBottomUp(SUnit*); 00123 void BacktrackBottomUp(SUnit*, unsigned, unsigned&); 00124 SUnit *CopyAndMoveSuccessors(SUnit*); 00125 void InsertCopiesAndMoveSuccs(SUnit*, unsigned, 00126 const TargetRegisterClass*, 00127 const TargetRegisterClass*, 00128 SmallVector<SUnit*, 2>&); 00129 bool DelayForLiveRegsBottomUp(SUnit*, SmallVector<unsigned, 4>&); 00130 void ListScheduleTopDown(); 00131 void ListScheduleBottomUp(); 00132 00133 00134 /// CreateNewSUnit - Creates a new SUnit and returns a pointer to it. 00135 /// Updates the topological ordering if required. 00136 SUnit *CreateNewSUnit(SDNode *N) { 00137 unsigned NumSUnits = SUnits.size(); 00138 SUnit *NewNode = NewSUnit(N); 00139 // Update the topological ordering. 00140 if (NewNode->NodeNum >= NumSUnits) 00141 Topo.InitDAGTopologicalSorting(); 00142 return NewNode; 00143 } 00144 00145 /// CreateClone - Creates a new SUnit from an existing one. 00146 /// Updates the topological ordering if required. 00147 SUnit *CreateClone(SUnit *N) { 00148 unsigned NumSUnits = SUnits.size(); 00149 SUnit *NewNode = Clone(N); 00150 // Update the topological ordering. 00151 if (NewNode->NodeNum >= NumSUnits) 00152 Topo.InitDAGTopologicalSorting(); 00153 return NewNode; 00154 } 00155 00156 /// ForceUnitLatencies - Return true, since register-pressure-reducing 00157 /// scheduling doesn't need actual latency information. 00158 bool ForceUnitLatencies() const { return true; } 00159 }; 00160 } // end anonymous namespace 00161 00162 00163 /// Schedule - Schedule the DAG using list scheduling. 00164 void ScheduleDAGRRList::Schedule() { 00165 DOUT << "********** List Scheduling **********\n"; 00166 00167 NumLiveRegs = 0; 00168 LiveRegDefs.resize(TRI->getNumRegs(), NULL); 00169 LiveRegCycles.resize(TRI->getNumRegs(), 0); 00170 00171 // Build the scheduling graph. 00172 BuildSchedGraph(); 00173 00174 DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) 00175 SUnits[su].dumpAll(this)); 00176 Topo.InitDAGTopologicalSorting(); 00177 00178 AvailableQueue->initNodes(SUnits); 00179 00180 // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate. 00181 if (isBottomUp) 00182 ListScheduleBottomUp(); 00183 else 00184 ListScheduleTopDown(); 00185 00186 AvailableQueue->releaseState(); 00187 } 00188 00189 //===----------------------------------------------------------------------===// 00190 // Bottom-Up Scheduling 00191 //===----------------------------------------------------------------------===// 00192 00193 /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to 00194 /// the AvailableQueue if the count reaches zero. Also update its cycle bound. 00195 void ScheduleDAGRRList::ReleasePred(SUnit *SU, const SDep *PredEdge) { 00196 SUnit *PredSU = PredEdge->getSUnit(); 00197 --PredSU->NumSuccsLeft; 00198 00199 #ifndef NDEBUG 00200 if (PredSU->NumSuccsLeft < 0) { 00201 cerr << "*** Scheduling failed! ***\n"; 00202 PredSU->dump(this); 00203 cerr << " has been released too many times!\n"; 00204 assert(0); 00205 } 00206 #endif 00207 00208 if (PredSU->NumSuccsLeft == 0) { 00209 PredSU->isAvailable = true; 00210 AvailableQueue->push(PredSU); 00211 } 00212 } 00213 00214 /// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending 00215 /// count of its predecessors. If a predecessor pending count is zero, add it to 00216 /// the Available queue. 00217 void ScheduleDAGRRList::ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle) { 00218 DOUT << "*** Scheduling [" << CurCycle << "]: "; 00219 DEBUG(SU->dump(this)); 00220 00221 assert(CurCycle >= SU->getHeight() && "Node scheduled below its height!"); 00222 SU->setHeightToAtLeast(CurCycle); 00223 Sequence.push_back(SU); 00224 00225 // Bottom up: release predecessors 00226 for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); 00227 I != E; ++I) { 00228 ReleasePred(SU, &*I); 00229 if (I->isAssignedRegDep()) { 00230 // This is a physical register dependency and it's impossible or 00231 // expensive to copy the register. Make sure nothing that can 00232 // clobber the register is scheduled between the predecessor and 00233 // this node. 00234 if (!LiveRegDefs[I->getReg()]) { 00235 ++NumLiveRegs; 00236 LiveRegDefs[I->getReg()] = I->getSUnit(); 00237 LiveRegCycles[I->getReg()] = CurCycle; 00238 } 00239 } 00240 } 00241 00242 // Release all the implicit physical register defs that are live. 00243 for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); 00244 I != E; ++I) { 00245 if (I->isAssignedRegDep()) { 00246 if (LiveRegCycles[I->getReg()] == I->getSUnit()->getHeight()) { 00247 assert(NumLiveRegs > 0 && "NumLiveRegs is already zero!"); 00248 assert(LiveRegDefs[I->getReg()] == SU && 00249 "Physical register dependency violated?"); 00250 --NumLiveRegs; 00251 LiveRegDefs[I->getReg()] = NULL; 00252 LiveRegCycles[I->getReg()] = 0; 00253 } 00254 } 00255 } 00256 00257 SU->isScheduled = true; 00258 AvailableQueue->ScheduledNode(SU); 00259 } 00260 00261 /// CapturePred - This does the opposite of ReleasePred. Since SU is being 00262 /// unscheduled, incrcease the succ left count of its predecessors. Remove 00263 /// them from AvailableQueue if necessary. 00264 void ScheduleDAGRRList::CapturePred(SDep *PredEdge) { 00265 SUnit *PredSU = PredEdge->getSUnit(); 00266 if (PredSU->isAvailable) { 00267 PredSU->isAvailable = false; 00268 if (!PredSU->isPending) 00269 AvailableQueue->remove(PredSU); 00270 } 00271 00272 ++PredSU->NumSuccsLeft; 00273 } 00274 00275 /// UnscheduleNodeBottomUp - Remove the node from the schedule, update its and 00276 /// its predecessor states to reflect the change. 00277 void ScheduleDAGRRList::UnscheduleNodeBottomUp(SUnit *SU) { 00278 DOUT << "*** Unscheduling [" << SU->getHeight() << "]: "; 00279 DEBUG(SU->dump(this)); 00280 00281 AvailableQueue->UnscheduledNode(SU); 00282 00283 for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); 00284 I != E; ++I) { 00285 CapturePred(&*I); 00286 if (I->isAssignedRegDep() && SU->getHeight() == LiveRegCycles[I->getReg()]) { 00287 assert(NumLiveRegs > 0 && "NumLiveRegs is already zero!"); 00288 assert(LiveRegDefs[I->getReg()] == I->getSUnit() && 00289 "Physical register dependency violated?"); 00290 --NumLiveRegs; 00291 LiveRegDefs[I->getReg()] = NULL; 00292 LiveRegCycles[I->getReg()] = 0; 00293 } 00294 } 00295 00296 for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); 00297 I != E; ++I) { 00298 if (I->isAssignedRegDep()) { 00299 if (!LiveRegDefs[I->getReg()]) { 00300 LiveRegDefs[I->getReg()] = SU; 00301 ++NumLiveRegs; 00302 } 00303 if (I->getSUnit()->getHeight() < LiveRegCycles[I->getReg()]) 00304 LiveRegCycles[I->getReg()] = I->getSUnit()->getHeight(); 00305 } 00306 } 00307 00308 SU->setHeightDirty(); 00309 SU->isScheduled = false; 00310 SU->isAvailable = true; 00311 AvailableQueue->push(SU); 00312 } 00313 00314 /// BacktrackBottomUp - Backtrack scheduling to a previous cycle specified in 00315 /// BTCycle in order to schedule a specific node. 00316 void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, unsigned BtCycle, 00317 unsigned &CurCycle) { 00318 SUnit *OldSU = NULL; 00319 while (CurCycle > BtCycle) { 00320 OldSU = Sequence.back(); 00321 Sequence.pop_back(); 00322 if (SU->isSucc(OldSU)) 00323 // Don't try to remove SU from AvailableQueue. 00324 SU->isAvailable = false; 00325 UnscheduleNodeBottomUp(OldSU); 00326 --CurCycle; 00327 } 00328 00329 assert(!SU->isSucc(OldSU) && "Something is wrong!"); 00330 00331 ++NumBacktracks; 00332 } 00333 00334 /// CopyAndMoveSuccessors - Clone the specified node and move its scheduled 00335 /// successors to the newly created node. 00336 SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) { 00337 if (SU->getNode()->getFlaggedNode()) 00338 return NULL; 00339 00340 SDNode *N = SU->getNode(); 00341 if (!N) 00342 return NULL; 00343 00344 SUnit *NewSU; 00345 bool TryUnfold = false; 00346 for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) { 00347 MVT VT = N->getValueType(i); 00348 if (VT == MVT::Flag) 00349 return NULL; 00350 else if (VT == MVT::Other) 00351 TryUnfold = true; 00352 } 00353 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { 00354 const SDValue &Op = N->getOperand(i); 00355 MVT VT = Op.getNode()->getValueType(Op.getResNo()); 00356 if (VT == MVT::Flag) 00357 return NULL; 00358 } 00359 00360 if (TryUnfold) { 00361 SmallVector<SDNode*, 2> NewNodes; 00362 if (!TII->unfoldMemoryOperand(*DAG, N, NewNodes)) 00363 return NULL; 00364 00365 DOUT << "Unfolding SU # " << SU->NodeNum << "\n"; 00366 assert(NewNodes.size() == 2 && "Expected a load folding node!"); 00367 00368 N = NewNodes[1]; 00369 SDNode *LoadNode = NewNodes[0]; 00370 unsigned NumVals = N->getNumValues(); 00371 unsigned OldNumVals = SU->getNode()->getNumValues(); 00372 for (unsigned i = 0; i != NumVals; ++i) 00373 DAG->ReplaceAllUsesOfValueWith(SDValue(SU->getNode(), i), SDValue(N, i)); 00374 DAG->ReplaceAllUsesOfValueWith(SDValue(SU->getNode(), OldNumVals-1), 00375 SDValue(LoadNode, 1)); 00376 00377 // LoadNode may already exist. This can happen when there is another 00378 // load from the same location and producing the same type of value 00379 // but it has different alignment or volatileness. 00380 bool isNewLoad = true; 00381 SUnit *LoadSU; 00382 if (LoadNode->getNodeId() != -1) { 00383 LoadSU = &SUnits[LoadNode->getNodeId()]; 00384 isNewLoad = false; 00385 } else { 00386 LoadSU = CreateNewSUnit(LoadNode); 00387 LoadNode->setNodeId(LoadSU->NodeNum); 00388 ComputeLatency(LoadSU); 00389 } 00390 00391 SUnit *NewSU = CreateNewSUnit(N); 00392 assert(N->getNodeId() == -1 && "Node already inserted!"); 00393 N->setNodeId(NewSU->NodeNum); 00394 00395 const TargetInstrDesc &TID = TII->get(N->getMachineOpcode()); 00396 for (unsigned i = 0; i != TID.getNumOperands(); ++i) { 00397 if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) { 00398 NewSU->isTwoAddress = true; 00399 break; 00400 } 00401 } 00402 if (TID.isCommutable()) 00403 NewSU->isCommutable = true; 00404 ComputeLatency(NewSU); 00405 00406 SDep ChainPred; 00407 SmallVector<SDep, 4> ChainSuccs; 00408 SmallVector<SDep, 4> LoadPreds; 00409 SmallVector<SDep, 4> NodePreds; 00410 SmallVector<SDep, 4> NodeSuccs; 00411 for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); 00412 I != E; ++I) { 00413 if (I->isCtrl()) 00414 ChainPred = *I; 00415 else if (I->getSUnit()->getNode() && 00416 I->getSUnit()->getNode()->isOperandOf(LoadNode)) 00417 LoadPreds.push_back(*I); 00418 else 00419 NodePreds.push_back(*I); 00420 } 00421 for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); 00422 I != E; ++I) { 00423 if (I->isCtrl()) 00424 ChainSuccs.push_back(*I); 00425 else 00426 NodeSuccs.push_back(*I); 00427 } 00428 00429 if (ChainPred.getSUnit()) { 00430 RemovePred(SU, ChainPred); 00431 if (isNewLoad) 00432 AddPred(LoadSU, ChainPred); 00433 } 00434 for (unsigned i = 0, e = LoadPreds.size(); i != e; ++i) { 00435 const SDep &Pred = LoadPreds[i]; 00436 RemovePred(SU, Pred); 00437 if (isNewLoad) { 00438 AddPred(LoadSU, Pred); 00439 } 00440 } 00441 for (unsigned i = 0, e = NodePreds.size(); i != e; ++i) { 00442 const SDep &Pred = NodePreds[i]; 00443 RemovePred(SU, Pred); 00444 AddPred(NewSU, Pred); 00445 } 00446 for (unsigned i = 0, e = NodeSuccs.size(); i != e; ++i) { 00447 SDep D = NodeSuccs[i]; 00448 SUnit *SuccDep = D.getSUnit(); 00449 D.setSUnit(SU); 00450 RemovePred(SuccDep, D); 00451 D.setSUnit(NewSU); 00452 AddPred(SuccDep, D); 00453 } 00454 for (unsigned i = 0, e = ChainSuccs.size(); i != e; ++i) { 00455 SDep D = ChainSuccs[i]; 00456 SUnit *SuccDep = D.getSUnit(); 00457 D.setSUnit(SU); 00458 RemovePred(SuccDep, D); 00459 if (isNewLoad) { 00460 D.setSUnit(LoadSU); 00461 AddPred(SuccDep, D); 00462 } 00463 } 00464 if (isNewLoad) { 00465 AddPred(NewSU, SDep(LoadSU, SDep::Order, LoadSU->Latency)); 00466 } 00467 00468 if (isNewLoad) 00469 AvailableQueue->addNode(LoadSU); 00470 AvailableQueue->addNode(NewSU); 00471 00472 ++NumUnfolds; 00473 00474 if (NewSU->NumSuccsLeft == 0) { 00475 NewSU->isAvailable = true; 00476 return NewSU; 00477 } 00478 SU = NewSU; 00479 } 00480 00481 DOUT << "Duplicating SU # " << SU->NodeNum << "\n"; 00482 NewSU = CreateClone(SU); 00483 00484 // New SUnit has the exact same predecessors. 00485 for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); 00486 I != E; ++I) 00487 if (!I->isArtificial()) 00488 AddPred(NewSU, *I); 00489 00490 // Only copy scheduled successors. Cut them from old node's successor 00491 // list and move them over. 00492 SmallVector<std::pair<SUnit *, SDep>, 4> DelDeps; 00493 for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); 00494 I != E; ++I) { 00495 if (I->isArtificial()) 00496 continue; 00497 SUnit *SuccSU = I->getSUnit(); 00498 if (SuccSU->isScheduled) { 00499 SDep D = *I; 00500 D.setSUnit(NewSU); 00501 AddPred(SuccSU, D); 00502 D.setSUnit(SU); 00503 DelDeps.push_back(std::make_pair(SuccSU, D)); 00504 } 00505 } 00506 for (unsigned i = 0, e = DelDeps.size(); i != e; ++i) 00507 RemovePred(DelDeps[i].first, DelDeps[i].second); 00508 00509 AvailableQueue->updateNode(SU); 00510 AvailableQueue->addNode(NewSU); 00511 00512 ++NumDups; 00513 return NewSU; 00514 } 00515 00516 /// InsertCopiesAndMoveSuccs - Insert register copies and move all 00517 /// scheduled successors of the given SUnit to the last copy. 00518 void ScheduleDAGRRList::InsertCopiesAndMoveSuccs(SUnit *SU, unsigned Reg, 00519 const TargetRegisterClass *DestRC, 00520 const TargetRegisterClass *SrcRC, 00521 SmallVector<SUnit*, 2> &Copies) { 00522 SUnit *CopyFromSU = CreateNewSUnit(NULL); 00523 CopyFromSU->CopySrcRC = SrcRC; 00524 CopyFromSU->CopyDstRC = DestRC; 00525 00526 SUnit *CopyToSU = CreateNewSUnit(NULL); 00527 CopyToSU->CopySrcRC = DestRC; 00528 CopyToSU->CopyDstRC = SrcRC; 00529 00530 // Only copy scheduled successors. Cut them from old node's successor 00531 // list and move them over. 00532 SmallVector<std::pair<SUnit *, SDep>, 4> DelDeps; 00533 for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); 00534 I != E; ++I) { 00535 if (I->isArtificial()) 00536 continue; 00537 SUnit *SuccSU = I->getSUnit(); 00538 if (SuccSU->isScheduled) { 00539 SDep D = *I; 00540 D.setSUnit(CopyToSU); 00541 AddPred(SuccSU, D); 00542 DelDeps.push_back(std::make_pair(SuccSU, *I)); 00543 } 00544 } 00545 for (unsigned i = 0, e = DelDeps.size(); i != e; ++i) 00546 RemovePred(DelDeps[i].first, DelDeps[i].second); 00547 00548 AddPred(CopyFromSU, SDep(SU, SDep::Data, SU->Latency, Reg)); 00549 AddPred(CopyToSU, SDep(CopyFromSU, SDep::Data, CopyFromSU->Latency, 0)); 00550 00551 AvailableQueue->updateNode(SU); 00552 AvailableQueue->addNode(CopyFromSU); 00553 AvailableQueue->addNode(CopyToSU); 00554 Copies.push_back(CopyFromSU); 00555 Copies.push_back(CopyToSU); 00556 00557 ++NumPRCopies; 00558 } 00559 00560 /// getPhysicalRegisterVT - Returns the ValueType of the physical register 00561 /// definition of the specified node. 00562 /// FIXME: Move to SelectionDAG? 00563 static MVT getPhysicalRegisterVT(SDNode *N, unsigned Reg, 00564 const TargetInstrInfo *TII) { 00565 const TargetInstrDesc &TID = TII->get(N->getMachineOpcode()); 00566 assert(TID.ImplicitDefs && "Physical reg def must be in implicit def list!"); 00567 unsigned NumRes = TID.getNumDefs(); 00568 for (const unsigned *ImpDef = TID.getImplicitDefs(); *ImpDef; ++ImpDef) { 00569 if (Reg == *ImpDef) 00570 break; 00571 ++NumRes; 00572 } 00573 return N->getValueType(NumRes); 00574 } 00575 00576 /// DelayForLiveRegsBottomUp - Returns true if it is necessary to delay 00577 /// scheduling of the given node to satisfy live physical register dependencies. 00578 /// If the specific node is the last one that's available to schedule, do 00579 /// whatever is necessary (i.e. backtracking or cloning) to make it possible. 00580 bool ScheduleDAGRRList::DelayForLiveRegsBottomUp(SUnit *SU, 00581 SmallVector<unsigned, 4> &LRegs){ 00582 if (NumLiveRegs == 0) 00583 return false; 00584 00585 SmallSet<unsigned, 4> RegAdded; 00586 // If this node would clobber any "live" register, then it's not ready. 00587 for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); 00588 I != E; ++I) { 00589 if (I->isAssignedRegDep()) { 00590 unsigned Reg = I->getReg(); 00591 if (LiveRegDefs[Reg] && LiveRegDefs[Reg] != I->getSUnit()) { 00592 if (RegAdded.insert(Reg)) 00593 LRegs.push_back(Reg); 00594 } 00595 for (const unsigned *Alias = TRI->getAliasSet(Reg); 00596 *Alias; ++Alias) 00597 if (LiveRegDefs[*Alias] && LiveRegDefs[*Alias] != I->getSUnit()) { 00598 if (RegAdded.insert(*Alias)) 00599 LRegs.push_back(*Alias); 00600 } 00601 } 00602 } 00603 00604 for (SDNode *Node = SU->getNode(); Node; Node = Node->getFlaggedNode()) { 00605 if (!Node->isMachineOpcode()) 00606 continue; 00607 const TargetInstrDesc &TID = TII->get(Node->getMachineOpcode()); 00608 if (!TID.ImplicitDefs) 00609 continue; 00610 for (const unsigned *Reg = TID.ImplicitDefs; *Reg; ++Reg) { 00611 if (LiveRegDefs[*Reg] && LiveRegDefs[*Reg] != SU) { 00612 if (RegAdded.insert(*Reg)) 00613 LRegs.push_back(*Reg); 00614 } 00615 for (const unsigned *Alias = TRI->getAliasSet(*Reg); 00616 *Alias; ++Alias) 00617 if (LiveRegDefs[*Alias] && LiveRegDefs[*Alias] != SU) { 00618 if (RegAdded.insert(*Alias)) 00619 LRegs.push_back(*Alias); 00620 } 00621 } 00622 } 00623 return !LRegs.empty(); 00624 } 00625 00626 00627 /// ListScheduleBottomUp - The main loop of list scheduling for bottom-up 00628 /// schedulers. 00629 void ScheduleDAGRRList::ListScheduleBottomUp() { 00630 unsigned CurCycle = 0; 00631 // Add root to Available queue. 00632 if (!SUnits.empty()) { 00633 SUnit *RootSU = &SUnits[DAG->getRoot().getNode()->getNodeId()]; 00634 assert(RootSU->Succs.empty() && "Graph root shouldn't have successors!"); 00635 RootSU->isAvailable = true; 00636 AvailableQueue->push(RootSU); 00637 } 00638 00639 // While Available queue is not empty, grab the node with the highest 00640 // priority. If it is not ready put it back. Schedule the node. 00641 SmallVector<SUnit*, 4> NotReady; 00642 DenseMap<SUnit*, SmallVector<unsigned, 4> > LRegsMap; 00643 Sequence.reserve(SUnits.size()); 00644 while (!AvailableQueue->empty()) { 00645 bool Delayed = false; 00646 LRegsMap.clear(); 00647 SUnit *CurSU = AvailableQueue->pop(); 00648 while (CurSU) { 00649 SmallVector<unsigned, 4> LRegs; 00650 if (!DelayForLiveRegsBottomUp(CurSU, LRegs)) 00651 break; 00652 Delayed = true; 00653 LRegsMap.insert(std::make_pair(CurSU, LRegs)); 00654 00655 CurSU->isPending = true; // This SU is not in AvailableQueue right now. 00656 NotReady.push_back(CurSU); 00657 CurSU = AvailableQueue->pop(); 00658 } 00659 00660 // All candidates are delayed due to live physical reg dependencies. 00661 // Try backtracking, code duplication, or inserting cross class copies 00662 // to resolve it. 00663 if (Delayed && !CurSU) { 00664 for (unsigned i = 0, e = NotReady.size(); i != e; ++i) { 00665 SUnit *TrySU = NotReady[i]; 00666 SmallVector<unsigned, 4> &LRegs = LRegsMap[TrySU]; 00667 00668 // Try unscheduling up to the point where it's safe to schedule 00669 // this node. 00670 unsigned LiveCycle = CurCycle; 00671 for (unsigned j = 0, ee = LRegs.size(); j != ee; ++j) { 00672 unsigned Reg = LRegs[j]; 00673 unsigned LCycle = LiveRegCycles[Reg]; 00674 LiveCycle = std::min(LiveCycle, LCycle); 00675 } 00676 SUnit *OldSU = Sequence[LiveCycle]; 00677 if (!WillCreateCycle(TrySU, OldSU)) { 00678 BacktrackBottomUp(TrySU, LiveCycle, CurCycle); 00679 // Force the current node to be scheduled before the node that 00680 // requires the physical reg dep. 00681 if (OldSU->isAvailable) { 00682 OldSU->isAvailable = false; 00683 AvailableQueue->remove(OldSU); 00684 } 00685 AddPred(TrySU, SDep(OldSU, SDep::Order, /*Latency=*/1, 00686 /*Reg=*/0, /*isNormalMemory=*/false, 00687 /*isMustAlias=*/false, /*isArtificial=*/true)); 00688 // If one or more successors has been unscheduled, then the current 00689 // node is no longer avaialable. Schedule a successor that's now 00690 // available instead. 00691 if (!TrySU->isAvailable) 00692 CurSU = AvailableQueue->pop(); 00693 else { 00694 CurSU = TrySU; 00695 TrySU->isPending = false; 00696 NotReady.erase(NotReady.begin()+i); 00697 } 00698 break; 00699 } 00700 } 00701 00702 if (!CurSU) { 00703 // Can't backtrack. If it's too expensive to copy the value, then try 00704 // duplicate the nodes that produces these "too expensive to copy" 00705 // values to break the dependency. In case even that doesn't work, 00706 // insert cross class copies. 00707 // If it's not too expensive, i.e. cost != -1, issue copies. 00708 SUnit *TrySU = NotReady[0]; 00709 SmallVector<unsigned, 4> &LRegs = LRegsMap[TrySU]; 00710 assert(LRegs.size() == 1 && "Can't handle this yet!"); 00711 unsigned Reg = LRegs[0]; 00712 SUnit *LRDef = LiveRegDefs[Reg]; 00713 MVT VT = getPhysicalRegisterVT(LRDef->getNode(), Reg, TII); 00714 const TargetRegisterClass *RC = 00715 TRI->getPhysicalRegisterRegClass(Reg, VT); 00716 const TargetRegisterClass *DestRC = TRI->getCrossCopyRegClass(RC); 00717 00718 // If cross copy register class is null, then it must be possible copy 00719 // the value directly. Do not try duplicate the def. 00720 SUnit *NewDef = 0; 00721 if (DestRC) 00722 NewDef = CopyAndMoveSuccessors(LRDef); 00723 else 00724 DestRC = RC; 00725 if (!NewDef) { 00726 // Issue copies, these can be expensive cross register class copies. 00727 SmallVector<SUnit*, 2> Copies; 00728 InsertCopiesAndMoveSuccs(LRDef, Reg, DestRC, RC, Copies); 00729 DOUT << "Adding an edge from SU #" << TrySU->NodeNum 00730 << " to SU #" << Copies.front()->NodeNum << "\n"; 00731 AddPred(TrySU, SDep(Copies.front(), SDep::Order, /*Latency=*/1, 00732 /*Reg=*/0, /*isNormalMemory=*/false, 00733 /*isMustAlias=*/false, 00734 /*isArtificial=*/true)); 00735 NewDef = Copies.back(); 00736 } 00737 00738 DOUT << "Adding an edge from SU #" << NewDef->NodeNum 00739 << " to SU #" << TrySU->NodeNum << "\n"; 00740 LiveRegDefs[Reg] = NewDef; 00741 AddPred(NewDef, SDep(TrySU, SDep::Order, /*Latency=*/1, 00742 /*Reg=*/0, /*isNormalMemory=*/false, 00743 /*isMustAlias=*/false, 00744 /*isArtificial=*/true)); 00745 TrySU->isAvailable = false; 00746 CurSU = NewDef; 00747 } 00748 00749 assert(CurSU && "Unable to resolve live physical register dependencies!"); 00750 } 00751 00752 // Add the nodes that aren't ready back onto the available list. 00753 for (unsigned i = 0, e = NotReady.size(); i != e; ++i) { 00754 NotReady[i]->isPending = false; 00755 // May no longer be available due to backtracking. 00756 if (NotReady[i]->isAvailable) 00757 AvailableQueue->push(NotReady[i]); 00758 } 00759 NotReady.clear(); 00760 00761 if (CurSU) 00762 ScheduleNodeBottomUp(CurSU, CurCycle); 00763 ++CurCycle; 00764 } 00765 00766 // Reverse the order if it is bottom up. 00767 std::reverse(Sequence.begin(), Sequence.end()); 00768 00769 #ifndef NDEBUG 00770 VerifySchedule(isBottomUp); 00771 #endif 00772 } 00773 00774 //===----------------------------------------------------------------------===// 00775 // Top-Down Scheduling 00776 //===----------------------------------------------------------------------===// 00777 00778 /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to 00779 /// the AvailableQueue if the count reaches zero. Also update its cycle bound. 00780 void ScheduleDAGRRList::ReleaseSucc(SUnit *SU, const SDep *SuccEdge) { 00781 SUnit *SuccSU = SuccEdge->getSUnit(); 00782 --SuccSU->NumPredsLeft; 00783 00784 #ifndef NDEBUG 00785 if (SuccSU->NumPredsLeft < 0) { 00786 cerr << "*** Scheduling failed! ***\n"; 00787 SuccSU->dump(this); 00788 cerr << " has been released too many times!\n"; 00789 assert(0); 00790 } 00791 #endif 00792 00793 if (SuccSU->NumPredsLeft == 0) { 00794 SuccSU->isAvailable = true; 00795 AvailableQueue->push(SuccSU); 00796 } 00797 } 00798 00799 /// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending 00800 /// count of its successors. If a successor pending count is zero, add it to 00801 /// the Available queue. 00802 void ScheduleDAGRRList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) { 00803 DOUT << "*** Scheduling [" << CurCycle << "]: "; 00804 DEBUG(SU->dump(this)); 00805 00806 assert(CurCycle >= SU->getDepth() && "Node scheduled above its depth!"); 00807 SU->setDepthToAtLeast(CurCycle); 00808 Sequence.push_back(SU); 00809 00810 // Top down: release successors 00811 for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); 00812 I != E; ++I) { 00813 assert(!I->isAssignedRegDep() && 00814 "The list-tdrr scheduler doesn't yet support physreg dependencies!"); 00815 00816 ReleaseSucc(SU, &*I); 00817 } 00818 00819 SU->isScheduled = true; 00820 AvailableQueue->ScheduledNode(SU); 00821 } 00822 00823 /// ListScheduleTopDown - The main loop of list scheduling for top-down 00824 /// schedulers. 00825 void ScheduleDAGRRList::ListScheduleTopDown() { 00826 unsigned CurCycle = 0; 00827 00828 // All leaves to Available queue. 00829 for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { 00830 // It is available if it has no predecessors. 00831 if (SUnits[i].Preds.empty()) { 00832 AvailableQueue->push(&SUnits[i]); 00833 SUnits[i].isAvailable = true; 00834 } 00835 } 00836 00837 // While Available queue is not empty, grab the node with the highest 00838 // priority. If it is not ready put it back. Schedule the node. 00839 Sequence.reserve(SUnits.size()); 00840 while (!AvailableQueue->empty()) { 00841 SUnit *CurSU = AvailableQueue->pop(); 00842 00843 if (CurSU) 00844 ScheduleNodeTopDown(CurSU, CurCycle); 00845 ++CurCycle; 00846 } 00847 00848 #ifndef NDEBUG 00849 VerifySchedule(isBottomUp); 00850 #endif 00851 } 00852 00853 00854 //===----------------------------------------------------------------------===// 00855 // RegReductionPriorityQueue Implementation 00856 //===----------------------------------------------------------------------===// 00857 // 00858 // This is a SchedulingPriorityQueue that schedules using Sethi Ullman numbers 00859 // to reduce register pressure. 00860 // 00861 namespace { 00862 template<class SF> 00863 class RegReductionPriorityQueue; 00864 00865 /// Sorting functions for the Available queue. 00866 struct bu_ls_rr_sort : public std::binary_function<SUnit*, SUnit*, bool> { 00867 RegReductionPriorityQueue<bu_ls_rr_sort> *SPQ; 00868 bu_ls_rr_sort(RegReductionPriorityQueue<bu_ls_rr_sort> *spq) : SPQ(spq) {} 00869 bu_ls_rr_sort(const bu_ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} 00870 00871 bool operator()(const SUnit* left, const SUnit* right) const; 00872 }; 00873 00874 struct td_ls_rr_sort : public std::binary_function<SUnit*, SUnit*, bool> { 00875 RegReductionPriorityQueue<td_ls_rr_sort> *SPQ; 00876 td_ls_rr_sort(RegReductionPriorityQueue<td_ls_rr_sort> *spq) : SPQ(spq) {} 00877 td_ls_rr_sort(const td_ls_rr_sort &RHS) : SPQ(RHS.SPQ) {} 00878 00879 bool operator()(const SUnit* left, const SUnit* right) const; 00880 }; 00881 } // end anonymous namespace 00882 00883 static inline bool isCopyFromLiveIn(const SUnit *SU) { 00884 SDNode *N = SU->getNode(); 00885 return N && N->getOpcode() == ISD::CopyFromReg && 00886 N->getOperand(N->getNumOperands()-1).getValueType() != MVT::Flag; 00887 } 00888 00889 /// CalcNodeSethiUllmanNumber - Compute Sethi Ullman number. 00890 /// Smaller number is the higher priority. 00891 static unsigned 00892 CalcNodeSethiUllmanNumber(const SUnit *SU, std::vector<unsigned> &SUNumbers) { 00893 unsigned &SethiUllmanNumber = SUNumbers[SU->NodeNum]; 00894 if (SethiUllmanNumber != 0) 00895 return SethiUllmanNumber; 00896 00897 unsigned Extra = 0; 00898 for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); 00899 I != E; ++I) { 00900 if (I->isCtrl()) continue; // ignore chain preds 00901 SUnit *PredSU = I->getSUnit(); 00902 unsigned PredSethiUllman = CalcNodeSethiUllmanNumber(PredSU, SUNumbers); 00903 if (PredSethiUllman > SethiUllmanNumber) { 00904 SethiUllmanNumber = PredSethiUllman; 00905 Extra = 0; 00906 } else if (PredSethiUllman == SethiUllmanNumber && !I->isCtrl()) 00907 ++Extra; 00908 } 00909 00910 SethiUllmanNumber += Extra; 00911 00912 if (SethiUllmanNumber == 0) 00913 SethiUllmanNumber = 1; 00914 00915 return SethiUllmanNumber; 00916 } 00917 00918 namespace { 00919 template<class SF> 00920 class VISIBILITY_HIDDEN RegReductionPriorityQueue 00921 : public SchedulingPriorityQueue { 00922 PriorityQueue<SUnit*, std::vector<SUnit*>, SF> Queue; 00923 unsigned currentQueueId; 00924 00925 protected: 00926 // SUnits - The SUnits for the current graph. 00927 std::vector<SUnit> *SUnits; 00928 00929 const TargetInstrInfo *TII; 00930 const TargetRegisterInfo *TRI; 00931 ScheduleDAGRRList *scheduleDAG; 00932 00933 // SethiUllmanNumbers - The SethiUllman number for each node. 00934 std::vector<unsigned> SethiUllmanNumbers; 00935 00936 public: 00937 RegReductionPriorityQueue(const TargetInstrInfo *tii, 00938 const TargetRegisterInfo *tri) : 00939 Queue(SF(this)), currentQueueId(0), 00940 TII(tii), TRI(tri), scheduleDAG(NULL) {} 00941 00942 void initNodes(std::vector<SUnit> &sunits) { 00943 SUnits = &sunits; 00944 // Add pseudo dependency edges for two-address nodes. 00945 AddPseudoTwoAddrDeps(); 00946 // Calculate node priorities. 00947 CalculateSethiUllmanNumbers(); 00948 } 00949 00950 void addNode(const SUnit *SU) { 00951 unsigned SUSize = SethiUllmanNumbers.size(); 00952 if (SUnits->size() > SUSize) 00953 SethiUllmanNumbers.resize(SUSize*2, 0); 00954 CalcNodeSethiUllmanNumber(SU, SethiUllmanNumbers); 00955 } 00956 00957 void updateNode(const SUnit *SU) { 00958 SethiUllmanNumbers[SU->NodeNum] = 0; 00959 CalcNodeSethiUllmanNumber(SU, SethiUllmanNumbers); 00960 } 00961 00962 void releaseState() { 00963 SUnits = 0; 00964 SethiUllmanNumbers.clear(); 00965 } 00966 00967 unsigned getNodePriority(const SUnit *SU) const { 00968 assert(SU->NodeNum < SethiUllmanNumbers.size()); 00969 unsigned Opc = SU->getNode() ? SU->getNode()->getOpcode() : 0; 00970 if (Opc == ISD::CopyFromReg && !isCopyFromLiveIn(SU)) 00971 // CopyFromReg should be close to its def because it restricts 00972 // allocation choices. But if it is a livein then perhaps we want it 00973 // closer to its uses so it can be coalesced. 00974 return 0xffff; 00975 if (Opc == ISD::TokenFactor || Opc == ISD::CopyToReg) 00976 // CopyToReg should be close to its uses to facilitate coalescing and 00977 // avoid spilling. 00978 return 0; 00979 if (Opc == TargetInstrInfo::EXTRACT_SUBREG || 00980 Opc == TargetInstrInfo::INSERT_SUBREG) 00981 // EXTRACT_SUBREG / INSERT_SUBREG should be close to its use to 00982 // facilitate coalescing. 00983 return 0; 00984 if (SU->NumSuccs == 0) 00985 // If SU does not have a use, i.e. it doesn't produce a value that would 00986 // be consumed (e.g. store), then it terminates a chain of computation. 00987 // Give it a large SethiUllman number so it will be scheduled right 00988 // before its predecessors that it doesn't lengthen their live ranges. 00989 return 0xffff; 00990 if (SU->NumPreds == 0) 00991 // If SU does not have a def, schedule it close to its uses because it 00992 // does not lengthen any live ranges. 00993 return 0; 00994 return SethiUllmanNumbers[SU->NodeNum]; 00995 } 00996 00997 unsigned size() const { return Queue.size(); } 00998 00999 bool empty() const { return Queue.empty(); } 01000 01001 void push(SUnit *U) { 01002 assert(!U->NodeQueueId && "Node in the queue already"); 01003 U->NodeQueueId = ++currentQueueId; 01004 Queue.push(U); 01005 } 01006 01007 void push_all(const std::vector<SUnit *> &Nodes) { 01008 for (unsigned i = 0, e = Nodes.size(); i != e; ++i) 01009 push(Nodes[i]); 01010 } 01011 01012 SUnit *pop() { 01013 if (empty()) return NULL; 01014 SUnit *V = Queue.top(); 01015 Queue.pop(); 01016 V->NodeQueueId = 0; 01017 return V; 01018 } 01019 01020 void remove(SUnit *SU) { 01021 assert(!Queue.empty() && "Queue is empty!"); 01022 assert(SU->NodeQueueId != 0 && "Not in queue!"); 01023 Queue.erase_one(SU); 01024 SU->NodeQueueId = 0; 01025 } 01026 01027 void setScheduleDAG(ScheduleDAGRRList *scheduleDag) { 01028 scheduleDAG = scheduleDag; 01029 } 01030 01031 protected: 01032 bool canClobber(const SUnit *SU, const SUnit *Op); 01033 void AddPseudoTwoAddrDeps(); 01034 void CalculateSethiUllmanNumbers(); 01035 }; 01036 01037 typedef RegReductionPriorityQueue<bu_ls_rr_sort> 01038 BURegReductionPriorityQueue; 01039 01040 typedef RegReductionPriorityQueue<td_ls_rr_sort> 01041 TDRegReductionPriorityQueue; 01042 } 01043 01044 /// closestSucc - Returns the scheduled cycle of the successor which is 01045 /// closet to the current cycle. 01046 static unsigned closestSucc(const SUnit *SU) { 01047 unsigned MaxHeight = 0; 01048 for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); 01049 I != E; ++I) { 01050 unsigned Height = I->getSUnit()->getHeight(); 01051 // If there are bunch of CopyToRegs stacked up, they should be considered 01052 // to be at the same position. 01053 if (I->getSUnit()->getNode() && 01054 I->getSUnit()->getNode()->getOpcode() == ISD::CopyToReg) 01055 Height = closestSucc(I->getSUnit())+1; 01056 if (Height > MaxHeight) 01057 MaxHeight = Height; 01058 } 01059 return MaxHeight; 01060 } 01061 01062 /// calcMaxScratches - Returns an cost estimate of the worse case requirement 01063 /// for scratch registers. Live-in operands and live-out results don't count 01064 /// since they are "fixed". 01065 static unsigned calcMaxScratches(const SUnit *SU) { 01066 unsigned Scratches = 0; 01067 for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); 01068 I != E; ++I) { 01069 if (I->isCtrl()) continue; // ignore chain preds 01070 if (!I->getSUnit()->getNode() || 01071 I->getSUnit()->getNode()->getOpcode() != ISD::CopyFromReg) 01072 Scratches++; 01073 } 01074 for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); 01075 I != E; ++I) { 01076 if (I->isCtrl()) continue; // ignore chain succs 01077 if (!I->getSUnit()->getNode() || 01078 I->getSUnit()->getNode()->getOpcode() != ISD::CopyToReg) 01079 Scratches += 10; 01080 } 01081 return Scratches; 01082 } 01083 01084 // Bottom up 01085 bool bu_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const { 01086 unsigned LPriority = SPQ->getNodePriority(left); 01087 unsigned RPriority = SPQ->getNodePriority(right); 01088 if (LPriority != RPriority) 01089 return LPriority > RPriority; 01090 01091 // Try schedule def + use closer when Sethi-Ullman numbers are the same. 01092 // e.g. 01093 // t1 = op t2, c1 01094 // t3 = op t4, c2 01095 // 01096 // and the following instructions are both ready. 01097 // t2 = op c3 01098 // t4 = op c4 01099 // 01100 // Then schedule t2 = op first. 01101 // i.e. 01102 // t4 = op c4 01103 // t2 = op c3 01104 // t1 = op t2, c1 01105 // t3 = op t4, c2 01106 // 01107 // This creates more short live intervals. 01108 unsigned LDist = closestSucc(left); 01109 unsigned RDist = closestSucc(right); 01110 if (LDist != RDist) 01111 return LDist < RDist; 01112 01113 // Intuitively, it's good to push down instructions whose results are 01114 // liveout so their long live ranges won't conflict with other values 01115 // which are needed inside the BB. Further prioritize liveout instructions 01116 // by the number of operands which are calculated within the BB. 01117 unsigned LScratch = calcMaxScratches(left); 01118 unsigned RScratch = calcMaxScratches(right); 01119 if (LScratch != RScratch) 01120 return LScratch > RScratch; 01121 01122 if (left->getHeight() != right->getHeight()) 01123 return left->getHeight() > right->getHeight(); 01124 01125 if (left->getDepth() != right->getDepth()) 01126 return left->getDepth() < right->getDepth(); 01127 01128 assert(left->NodeQueueId && right->NodeQueueId && 01129 "NodeQueueId cannot be zero"); 01130 return (left->NodeQueueId > right->NodeQueueId); 01131 } 01132 01133 template<class SF> 01134 bool 01135 RegReductionPriorityQueue<SF>::canClobber(const SUnit *SU, const SUnit *Op) { 01136 if (SU->isTwoAddress) { 01137 unsigned Opc = SU->getNode()->getMachineOpcode(); 01138 const TargetInstrDesc &TID = TII->get(Opc); 01139 unsigned NumRes = TID.getNumDefs(); 01140 unsigned NumOps = TID.getNumOperands() - NumRes; 01141 for (unsigned i = 0; i != NumOps; ++i) { 01142 if (TID.getOperandConstraint(i+NumRes, TOI::TIED_TO) != -1) { 01143 SDNode *DU = SU->getNode()->getOperand(i).getNode(); 01144 if (DU->getNodeId() != -1 && 01145 Op->OrigNode == &(*SUnits)[DU->getNodeId()]) 01146 return true; 01147 } 01148 } 01149 } 01150 return false; 01151 } 01152 01153 01154 /// hasCopyToRegUse - Return true if SU has a value successor that is a 01155 /// CopyToReg node. 01156 static bool hasCopyToRegUse(const SUnit *SU) { 01157 for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); 01158 I != E; ++I) { 01159 if (I->isCtrl()) continue; 01160 const SUnit *SuccSU = I->getSUnit(); 01161 if (SuccSU->getNode() && SuccSU->getNode()->getOpcode() == ISD::CopyToReg) 01162 return true; 01163 } 01164 return false; 01165 } 01166 01167 /// canClobberPhysRegDefs - True if SU would clobber one of SuccSU's 01168 /// physical register defs. 01169 static bool canClobberPhysRegDefs(const SUnit *SuccSU, const SUnit *SU, 01170 const TargetInstrInfo *TII, 01171 const TargetRegisterInfo *TRI) { 01172 SDNode *N = SuccSU->getNode(); 01173 unsigned NumDefs = TII->get(N->getMachineOpcode()).getNumDefs(); 01174 const unsigned *ImpDefs = TII->get(N->getMachineOpcode()).getImplicitDefs(); 01175 assert(ImpDefs && "Caller should check hasPhysRegDefs"); 01176 const unsigned *SUImpDefs = 01177 TII->get(SU->getNode()->getMachineOpcode()).getImplicitDefs(); 01178 if (!SUImpDefs) 01179 return false; 01180 for (unsigned i = NumDefs, e = N->getNumValues(); i != e; ++i) { 01181 MVT VT = N->getValueType(i); 01182 if (VT == MVT::Flag || VT == MVT::Other) 01183 continue; 01184 if (!N->hasAnyUseOfValue(i)) 01185 continue; 01186 unsigned Reg = ImpDefs[i - NumDefs]; 01187 for (;*SUImpDefs; ++SUImpDefs) { 01188 unsigned SUReg = *SUImpDefs; 01189 if (TRI->regsOverlap(Reg, SUReg)) 01190 return true; 01191 } 01192 } 01193 return false; 01194 } 01195 01196 /// AddPseudoTwoAddrDeps - If two nodes share an operand and one of them uses 01197 /// it as a def&use operand. Add a pseudo control edge from it to the other 01198 /// node (if it won't create a cycle) so the two-address one will be scheduled 01199 /// first (lower in the schedule). If both nodes are two-address, favor the 01200 /// one that has a CopyToReg use (more likely to be a loop induction update). 01201 /// If both are two-address, but one is commutable while the other is not 01202 /// commutable, favor the one that's not commutable. 01203 template<class SF> 01204 void RegReductionPriorityQueue<SF>::AddPseudoTwoAddrDeps() { 01205 for (unsigned i = 0, e = SUnits->size(); i != e; ++i) { 01206 SUnit *SU = &(*SUnits)[i]; 01207 if (!SU->isTwoAddress) 01208 continue; 01209 01210 SDNode *Node = SU->getNode(); 01211 if (!Node || !Node->isMachineOpcode() || SU->getNode()->getFlaggedNode()) 01212 continue; 01213 01214 unsigned Opc = Node->getMachineOpcode(); 01215 const TargetInstrDesc &TID = TII->get(Opc); 01216 unsigned NumRes = TID.getNumDefs(); 01217 unsigned NumOps = TID.getNumOperands() - NumRes; 01218 for (unsigned j = 0; j != NumOps; ++j) { 01219 if (TID.getOperandConstraint(j+NumRes, TOI::TIED_TO) == -1) 01220 continue; 01221 SDNode *DU = SU->getNode()->getOperand(j).getNode(); 01222 if (DU->getNodeId() == -1) 01223 continue; 01224 const SUnit *DUSU = &(*SUnits)[DU->getNodeId()]; 01225 if (!DUSU) continue; 01226 for (SUnit::const_succ_iterator I = DUSU->Succs.begin(), 01227 E = DUSU->Succs.end(); I != E; ++I) { 01228 if (I->isCtrl()) continue; 01229 SUnit *SuccSU = I->getSUnit(); 01230 if (SuccSU == SU) 01231 continue; 01232 // Be conservative. Ignore if nodes aren't at roughly the same 01233 // depth and height. 01234 if (SuccSU->getHeight() < SU->getHeight() && 01235 (SU->getHeight() - SuccSU->getHeight()) > 1) 01236 continue; 01237 if (!SuccSU->getNode() || !SuccSU->getNode()->isMachineOpcode()) 01238 continue; 01239 // Don't constrain nodes with physical register defs if the 01240 // predecessor can clobber them. 01241 if (SuccSU->hasPhysRegDefs) { 01242 if (canClobberPhysRegDefs(SuccSU, SU, TII, TRI)) 01243 continue; 01244 } 01245 // Don't constraint extract_subreg / insert_subreg these may be 01246 // coalesced away. We don't them close to their uses. 01247 unsigned SuccOpc = SuccSU->getNode()->getMachineOpcode(); 01248 if (SuccOpc == TargetInstrInfo::EXTRACT_SUBREG || 01249 SuccOpc == TargetInstrInfo::INSERT_SUBREG) 01250 continue; 01251 if ((!canClobber(SuccSU, DUSU) || 01252 (hasCopyToRegUse(SU) && !hasCopyToRegUse(SuccSU)) || 01253 (!SU->isCommutable && SuccSU->isCommutable)) && 01254 !scheduleDAG->IsReachable(SuccSU, SU)) { 01255 DOUT << "Adding a pseudo-two-addr edge from SU # " << SU->NodeNum 01256 << " to SU #" << SuccSU->NodeNum << "\n"; 01257 scheduleDAG->AddPred(SU, SDep(SuccSU, SDep::Order, /*Latency=*/0, 01258 /*Reg=*/0, /*isNormalMemory=*/false, 01259 /*isMustAlias=*/false, 01260 /*isArtificial=*/true)); 01261 } 01262 } 01263 } 01264 } 01265 } 01266 01267 /// CalculateSethiUllmanNumbers - Calculate Sethi-Ullman numbers of all 01268 /// scheduling units. 01269 template<class SF> 01270 void RegReductionPriorityQueue<SF>::CalculateSethiUllmanNumbers() { 01271 SethiUllmanNumbers.assign(SUnits->size(), 0); 01272 01273 for (unsigned i = 0, e = SUnits->size(); i != e; ++i) 01274 CalcNodeSethiUllmanNumber(&(*SUnits)[i], SethiUllmanNumbers); 01275 } 01276 01277 /// LimitedSumOfUnscheduledPredsOfSuccs - Compute the sum of the unscheduled 01278 /// predecessors of the successors of the SUnit SU. Stop when the provided 01279 /// limit is exceeded. 01280 static unsigned LimitedSumOfUnscheduledPredsOfSuccs(const SUnit *SU, 01281 unsigned Limit) { 01282 unsigned Sum = 0; 01283 for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); 01284 I != E; ++I) { 01285 const SUnit *SuccSU = I->getSUnit(); 01286 for (SUnit::const_pred_iterator II = SuccSU->Preds.begin(), 01287 EE = SuccSU->Preds.end(); II != EE; ++II) { 01288 SUnit *PredSU = II->getSUnit(); 01289 if (!PredSU->isScheduled) 01290 if (++Sum > Limit) 01291 return Sum; 01292 } 01293 } 01294 return Sum; 01295 } 01296 01297 01298 // Top down 01299 bool td_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const { 01300 unsigned LPriority = SPQ->getNodePriority(left); 01301 unsigned RPriority = SPQ->getNodePriority(right); 01302 bool LIsTarget = left->getNode() && left->getNode()->isMachineOpcode(); 01303 bool RIsTarget = right->getNode() && right->getNode()->isMachineOpcode(); 01304 bool LIsFloater = LIsTarget && left->NumPreds == 0; 01305 bool RIsFloater = RIsTarget && right->NumPreds == 0; 01306 unsigned LBonus = (LimitedSumOfUnscheduledPredsOfSuccs(left,1) == 1) ? 2 : 0; 01307 unsigned RBonus = (LimitedSumOfUnscheduledPredsOfSuccs(right,1) == 1) ? 2 : 0; 01308 01309 if (left->NumSuccs == 0 && right->NumSuccs != 0) 01310 return false; 01311 else if (left->NumSuccs != 0 && right->NumSuccs == 0) 01312 return true; 01313 01314 if (LIsFloater) 01315 LBonus -= 2; 01316 if (RIsFloater) 01317 RBonus -= 2; 01318 if (left->NumSuccs == 1) 01319 LBonus += 2; 01320 if (right->NumSuccs == 1) 01321 RBonus += 2; 01322 01323 if (LPriority+LBonus != RPriority+RBonus) 01324 return LPriority+LBonus < RPriority+RBonus; 01325 01326 if (left->getDepth() != right->getDepth()) 01327 return left->getDepth() < right->getDepth(); 01328 01329 if (left->NumSuccsLeft != right->NumSuccsLeft) 01330 return left->NumSuccsLeft > right->NumSuccsLeft; 01331 01332 assert(left->NodeQueueId && right->NodeQueueId && 01333 "NodeQueueId cannot be zero"); 01334 return (left->NodeQueueId > right->NodeQueueId); 01335 } 01336 01337 //===----------------------------------------------------------------------===// 01338 // Public Constructor Functions 01339 //===----------------------------------------------------------------------===// 01340 01341 llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAGISel *IS, 01342 bool) { 01343 const TargetMachine &TM = IS->TM; 01344 const TargetInstrInfo *TII = TM.getInstrInfo(); 01345 const TargetRegisterInfo *TRI = TM.getRegisterInfo(); 01346 01347 BURegReductionPriorityQueue *PQ = new BURegReductionPriorityQueue(TII, TRI); 01348 01349 ScheduleDAGRRList *SD = 01350 new ScheduleDAGRRList(*IS->MF, true, PQ); 01351 PQ->setScheduleDAG(SD); 01352 return SD; 01353 } 01354 01355 llvm::ScheduleDAG* llvm::createTDRRListDAGScheduler(SelectionDAGISel *IS, 01356 bool) { 01357 const TargetMachine &TM = IS->TM; 01358 const TargetInstrInfo *TII = TM.getInstrInfo(); 01359 const TargetRegisterInfo *TRI = TM.getRegisterInfo(); 01360 01361 TDRegReductionPriorityQueue *PQ = new TDRegReductionPriorityQueue(TII, TRI); 01362 01363 ScheduleDAGRRList *SD = 01364 new ScheduleDAGRRList(*IS->MF, false, PQ); 01365 PQ->setScheduleDAG(SD); 01366 return SD; 01367 }