From 03fc53c174e654adae4e42a0c352c7937de2cd87 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 6 Mar 2006 00:22:00 +0000 Subject: [PATCH] Hoist the HazardRecognizer out of the ScheduleDAGList.cpp file to where targets can implement them. Make the top-down scheduler non-g5-specific. Remove the old testing hazard recognizer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26569 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp | 130 +++--------------- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 14 +- 2 files changed, 32 insertions(+), 112 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp index e10ee4173d6..703e4626d8d 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp @@ -164,51 +164,6 @@ struct ls_rr_sort : public std::binary_function { }; -/// HazardRecognizer - This determines whether or not an instruction can be -/// issued this cycle, and whether or not a noop needs to be inserted to handle -/// the hazard. -namespace { - class HazardRecognizer { - public: - virtual ~HazardRecognizer() {} - - enum HazardType { - NoHazard, // This instruction can be emitted at this cycle. - Hazard, // This instruction can't be emitted at this cycle. - NoopHazard, // This instruction can't be emitted, and needs noops. - }; - - /// getHazardType - Return the hazard type of emitting this node. There are - /// three possible results. Either: - /// * NoHazard: it is legal to issue this instruction on this cycle. - /// * Hazard: issuing this instruction would stall the machine. If some - /// other instruction is available, issue it first. - /// * NoopHazard: issuing this instruction would break the program. If - /// some other instruction can be issued, do so, otherwise issue a noop. - virtual HazardType getHazardType(SDNode *Node) { - return NoHazard; - } - - /// EmitInstruction - This callback is invoked when an instruction is - /// emitted, to advance the hazard state. - virtual void EmitInstruction(SDNode *Node) { - } - - /// AdvanceCycle - This callback is invoked when no instructions can be - /// issued on this cycle without a hazard. This should increment the - /// internal state of the hazard recognizer so that previously "Hazard" - /// instructions will now not be hazards. - virtual void AdvanceCycle() { - } - - /// EmitNoop - This callback is invoked when a noop was added to the - /// instruction stream. - virtual void EmitNoop() { - } - }; -} - - /// ScheduleDAGList - List scheduler. class ScheduleDAGList : public ScheduleDAG { private: @@ -226,7 +181,7 @@ private: bool isBottomUp; /// HazardRec - The hazard recognizer to use. - HazardRecognizer *HazardRec; + HazardRecognizer &HazardRec; typedef std::priority_queue, ls_rr_sort> AvailableQueueTy; @@ -234,11 +189,10 @@ private: public: ScheduleDAGList(SelectionDAG &dag, MachineBasicBlock *bb, const TargetMachine &tm, bool isbottomup, - HazardRecognizer *HR = 0) + HazardRecognizer &HR) : ScheduleDAG(listSchedulingBURR, dag, bb, tm), - CurrCycle(0), HeadSUnit(NULL), TailSUnit(NULL), isBottomUp(isbottomup) { - if (HR == 0) HR = new HazardRecognizer(); - HazardRec = HR; + CurrCycle(0), HeadSUnit(NULL), TailSUnit(NULL), isBottomUp(isbottomup), + HazardRec(HR) { } ~ScheduleDAGList() { @@ -248,8 +202,6 @@ public: delete SU; SU = NextSU; } - - delete HazardRec; } void Schedule(); @@ -271,6 +223,8 @@ private: }; } // end namespace +HazardRecognizer::~HazardRecognizer() {} + /// NewSUnit - Creates a new SUnit and return a ptr to it. SUnit *ScheduleDAGList::NewSUnit(SDNode *N) { @@ -465,11 +419,13 @@ void ScheduleDAGList::ListScheduleBottomUp() { void ScheduleDAGList::ListScheduleTopDown() { // Available queue. AvailableQueueTy Available; + + HazardRec.StartBasicBlock(); // Emit the entry node first. SUnit *Entry = SUnitMap[DAG.getEntryNode().Val]; ScheduleNodeTopDown(Available, Entry); - HazardRec->EmitInstruction(Entry->Node); + HazardRec.EmitInstruction(Entry->Node); // All leaves to Available queue. for (SUnit *SU = HeadSUnit; SU != NULL; SU = SU->Next) { @@ -489,7 +445,7 @@ void ScheduleDAGList::ListScheduleTopDown() { SUnit *CurrNode = Available.top(); Available.pop(); HazardRecognizer::HazardType HT = - HazardRec->getHazardType(CurrNode->Node); + HazardRec.getHazardType(CurrNode->Node); if (HT == HazardRecognizer::NoHazard) { FoundNode = CurrNode; break; @@ -510,19 +466,19 @@ void ScheduleDAGList::ListScheduleTopDown() { // If we found a node to schedule, do it now. if (FoundNode) { ScheduleNodeTopDown(Available, FoundNode); - HazardRec->EmitInstruction(FoundNode->Node); + HazardRec.EmitInstruction(FoundNode->Node); } else if (!HasNoopHazards) { // Otherwise, we have a pipeline stall, but no other problem, just advance // the current cycle and try again. DEBUG(std::cerr << "*** Advancing cycle, no work to do"); - HazardRec->AdvanceCycle(); + HazardRec.AdvanceCycle(); ++NumStalls; } else { // Otherwise, we have no instructions to issue and we have instructions // that will fault if we don't do this right. This is the case for // processors without pipeline interlocks and other cases. DEBUG(std::cerr << "*** Emitting noop"); - HazardRec->EmitNoop(); + HazardRec.EmitNoop(); Sequence.push_back(0); // NULL SUnit* -> noop ++NumNoops; } @@ -720,7 +676,7 @@ void ScheduleDAGList::Schedule() { // Build scheduling units. BuildSchedUnits(); - // Calculate node prirorities. + // Calculate node priorities. CalculatePriorities(); // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate. @@ -739,56 +695,14 @@ void ScheduleDAGList::Schedule() { llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAG &DAG, MachineBasicBlock *BB) { - return new ScheduleDAGList(DAG, BB, DAG.getTarget(), true); + HazardRecognizer HR; + return new ScheduleDAGList(DAG, BB, DAG.getTarget(), true, HR); } -/// G5HazardRecognizer - A hazard recognizer for the PowerPC G5 processor. -/// FIXME: Move to the PowerPC backend. -class G5HazardRecognizer : public HazardRecognizer { - // Totally bogus hazard recognizer, used to test noop insertion. This requires - // a noop between copyfromreg's. - unsigned EmittedCopyFromReg; -public: - G5HazardRecognizer() { - EmittedCopyFromReg = 0; - } - - virtual HazardType getHazardType(SDNode *Node) { - if (Node->getOpcode() == ISD::CopyFromReg && EmittedCopyFromReg) - return NoopHazard; - return NoHazard; - } - - /// EmitInstruction - This callback is invoked when an instruction is - /// emitted, to advance the hazard state. - virtual void EmitInstruction(SDNode *Node) { - if (Node->getOpcode() == ISD::CopyFromReg) { - EmittedCopyFromReg = 5; - } else if (EmittedCopyFromReg) { - --EmittedCopyFromReg; - } - } - - /// AdvanceCycle - This callback is invoked when no instructions can be - /// issued on this cycle without a hazard. This should increment the - /// internal state of the hazard recognizer so that previously "Hazard" - /// instructions will now not be hazards. - virtual void AdvanceCycle() { - } - - /// EmitNoop - This callback is invoked when a noop was added to the - /// instruction stream. - virtual void EmitNoop() { - --EmittedCopyFromReg; - } -}; - - -/// createTDG5ListDAGScheduler - This creates a top-down list scheduler for -/// the PowerPC G5. FIXME: pull the priority function out into the PPC -/// backend! -ScheduleDAG* llvm::createTDG5ListDAGScheduler(SelectionDAG &DAG, - MachineBasicBlock *BB) { - return new ScheduleDAGList(DAG, BB, DAG.getTarget(), false, - new G5HazardRecognizer()); +/// createTDListDAGScheduler - This creates a top-down list scheduler with the +/// specified hazard recognizer. +ScheduleDAG* llvm::createTDListDAGScheduler(SelectionDAG &DAG, + MachineBasicBlock *BB, + HazardRecognizer &HR) { + return new ScheduleDAGList(DAG, BB, DAG.getTarget(), false, HR); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 3506601704d..3e97494a26e 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -76,8 +76,8 @@ namespace { "except using generic latency"), clEnumValN(listSchedulingBURR, "list-burr", "Bottom up register reduction list scheduling"), - clEnumValN(listSchedulingG5, "list-g5", - "Scheduling for the PowerPC G5"), + clEnumValN(listSchedulingTD, "list-td", + "Top-down list scheduler"), clEnumValEnd)); } // namespace @@ -2473,14 +2473,20 @@ void SelectionDAGISel::ScheduleAndEmitDAG(SelectionDAG &DAG) { case listSchedulingBURR: SL = createBURRListDAGScheduler(DAG, BB); break; - case listSchedulingG5: - SL = createTDG5ListDAGScheduler(DAG, BB); + case listSchedulingTD: + SL = createTDListDAGScheduler(DAG, BB, GetTargetHazardRecognizer()); break; } BB = SL->Run(); delete SL; } +HazardRecognizer &SelectionDAGISel:: +GetTargetHazardRecognizer() { + static HazardRecognizer DefaultRecognizer; + return DefaultRecognizer; +} + /// SelectInlineAsmMemoryOperands - Calls to this are automatically generated /// by tblgen. Others should not call it. void SelectionDAGISel::