Hoist the HazardRecognizer out of the ScheduleDAGList.cpp file to where
authorChris Lattner <sabre@nondot.org>
Mon, 6 Mar 2006 00:22:00 +0000 (00:22 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 6 Mar 2006 00:22:00 +0000 (00:22 +0000)
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
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

index e10ee4173d6a420558956e56ba6ac044d3438fae..703e4626d8d3dbfdca29d4babdd7c9387621edbd 100644 (file)
@@ -164,51 +164,6 @@ struct ls_rr_sort : public std::binary_function<SUnit*, SUnit*, bool> {
 };
 
 
-/// 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<SUnit*, std::vector<SUnit*>, 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);
 }
index 3506601704d23fb87f79a2b7b65057da6e2cd167..3e97494a26e77b522c17659c2f2ff6806173d305 100644 (file)
@@ -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::