Eliminate the loop that searches through each of the operands
[oota-llvm.git] / include / llvm / CodeGen / ScheduleDAG.h
index 4d3b60e59ae4d681a546c93df0f9ce27fc752b62..ed7d3ed4022035128154747faed7108063491da6 100644 (file)
@@ -118,7 +118,7 @@ namespace llvm {
     }
 
     bool operator==(const SDep &Other) const {
-      if (Dep != Other.Dep) return false;
+      if (Dep != Other.Dep || Latency != Other.Latency) return false;
       switch (Dep.getInt()) {
       case Data:
       case Anti:
@@ -166,10 +166,11 @@ namespace llvm {
       return getKind() != Data;
     }
 
-    /// isArtificial - Test if this is an Order dependence that is marked
-    /// as "artificial", meaning it isn't necessary for correctness.
-    bool isArtificial() const {
-      return getKind() == Order && Contents.Order.isArtificial;
+    /// isNormalMemory - Test if this is an Order dependence between two
+    /// memory accesses where both sides of the dependence access memory
+    /// in non-volatile and fully modeled ways.
+    bool isNormalMemory() const {
+      return getKind() == Order && Contents.Order.isNormalMemory;
     }
 
     /// isMustAlias - Test if this is an Order dependence that is marked
@@ -179,6 +180,12 @@ namespace llvm {
       return getKind() == Order && Contents.Order.isMustAlias;
     }
 
+    /// isArtificial - Test if this is an Order dependence that is marked
+    /// as "artificial", meaning it isn't necessary for correctness.
+    bool isArtificial() const {
+      return getKind() == Order && Contents.Order.isArtificial;
+    }
+
     /// isAssignedRegDep - Test if this is a Data dependence that is
     /// associated with a register.
     bool isAssignedRegDep() const {
@@ -242,10 +249,14 @@ namespace llvm {
     bool isPending        : 1;          // True once pending.
     bool isAvailable      : 1;          // True once available.
     bool isScheduled      : 1;          // True once scheduled.
-    unsigned CycleBound;                // Upper/lower cycle to be scheduled at.
-    unsigned Cycle;                     // Once scheduled, the cycle of the op.
-    unsigned Depth;                     // Node depth;
-    unsigned Height;                    // Node height;
+    bool isScheduleHigh   : 1;          // True if preferable to schedule high.
+    bool isCloned         : 1;          // True if this node has been cloned.
+  private:
+    bool isDepthCurrent   : 1;          // True if Depth is current.
+    bool isHeightCurrent  : 1;          // True if Height is current.
+    unsigned Depth;                     // Node depth.
+    unsigned Height;                    // Node height.
+  public:
     const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null.
     const TargetRegisterClass *CopySrcRC;
     
@@ -256,7 +267,8 @@ namespace llvm {
         Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0),
         isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false),
         isPending(false), isAvailable(false), isScheduled(false),
-        CycleBound(0), Cycle(~0u), Depth(0), Height(0),
+        isScheduleHigh(false), isCloned(false),
+        isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
         CopyDstRC(NULL), CopySrcRC(NULL) {}
 
     /// SUnit - Construct an SUnit for post-regalloc scheduling to represent
@@ -266,7 +278,8 @@ namespace llvm {
         Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0),
         isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false),
         isPending(false), isAvailable(false), isScheduled(false),
-        CycleBound(0), Cycle(~0u), Depth(0), Height(0),
+        isScheduleHigh(false), isCloned(false),
+        isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
         CopyDstRC(NULL), CopySrcRC(NULL) {}
 
     /// setNode - Assign the representative SDNode for this SUnit.
@@ -299,68 +312,49 @@ namespace llvm {
 
     /// addPred - This adds the specified edge as a pred of the current node if
     /// not already.  It also adds the current node as a successor of the
-    /// specified node.  This returns true if this is a new pred.
-    bool addPred(const SDep &D) {
-      // If this node already has this depenence, don't add a redundant one.
-      for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
-        if (Preds[i] == D)
-          return false;
-      // Add a pred to this SUnit.
-      Preds.push_back(D);
-      // Now add a corresponding succ to N.
-      SDep P = D;
-      P.setSUnit(this);
-      SUnit *N = D.getSUnit();
-      N->Succs.push_back(P);
-      // Update the bookkeeping.
-      if (D.getKind() == SDep::Data) {
-        ++NumPreds;
-        ++N->NumSuccs;
-      }
-      if (!N->isScheduled)
-        ++NumPredsLeft;
-      if (!isScheduled)
-        ++N->NumSuccsLeft;
-      return true;
-    }
+    /// specified node.
+    void addPred(const SDep &D);
 
     /// removePred - This removes the specified edge as a pred of the current
     /// node if it exists.  It also removes the current node as a successor of
-    /// the specified node.  This returns true if the edge existed and was
-    /// removed.
-    bool removePred(const SDep &D) {
-      // Find the matching predecessor.
-      for (SmallVector<SDep, 4>::iterator I = Preds.begin(), E = Preds.end();
-           I != E; ++I)
-        if (*I == D) {
-          bool FoundSucc = false;
-          // Find the corresponding successor in N.
-          SDep P = D;
-          P.setSUnit(this);
-          SUnit *N = D.getSUnit();
-          for (SmallVector<SDep, 4>::iterator II = N->Succs.begin(),
-                 EE = N->Succs.end(); II != EE; ++II)
-            if (*II == P) {
-              FoundSucc = true;
-              N->Succs.erase(II);
-              break;
-            }
-          assert(FoundSucc && "Mismatching preds / succs lists!");
-          Preds.erase(I);
-          // Update the bookkeeping;
-          if (D.getKind() == SDep::Data) {
-            --NumPreds;
-            --N->NumSuccs;
-          }
-          if (!N->isScheduled)
-            --NumPredsLeft;
-          if (!isScheduled)
-            --N->NumSuccsLeft;
-          return true;
-        }
-      return false;
+    /// the specified node.
+    void removePred(const SDep &D);
+
+    /// getDepth - Return the depth of this node, which is the length of the
+    /// maximum path up to any node with has no predecessors.
+    unsigned getDepth() const {
+      if (!isDepthCurrent) const_cast<SUnit *>(this)->ComputeDepth();
+      return Depth;
+    }
+
+    /// getHeight - Return the height of this node, which is the length of the
+    /// maximum path down to any node with has no successors.
+    unsigned getHeight() const {
+      if (!isHeightCurrent) const_cast<SUnit *>(this)->ComputeHeight();
+      return Height;
     }
 
+    /// setDepthToAtLeast - If NewDepth is greater than this node's depth
+    /// value, set it to be the new depth value. This also recursively
+    /// marks successor nodes dirty.
+    void setDepthToAtLeast(unsigned NewDepth);
+
+    /// setDepthToAtLeast - If NewDepth is greater than this node's depth
+    /// value, set it to be the new height value. This also recursively
+    /// marks predecessor nodes dirty.
+    void setHeightToAtLeast(unsigned NewHeight);
+
+    /// setDepthDirty - Set a flag in this node to indicate that its
+    /// stored Depth value will require recomputation the next time
+    /// getDepth() is called.
+    void setDepthDirty();
+
+    /// setHeightDirty - Set a flag in this node to indicate that its
+    /// stored Height value will require recomputation the next time
+    /// getHeight() is called.
+    void setHeightDirty();
+
+    /// isPred - Test if node N is a predecessor of this node.
     bool isPred(SUnit *N) {
       for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
         if (Preds[i].getSUnit() == N)
@@ -368,6 +362,7 @@ namespace llvm {
       return false;
     }
     
+    /// isSucc - Test if node N is a successor of this node.
     bool isSucc(SUnit *N) {
       for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i)
         if (Succs[i].getSUnit() == N)
@@ -378,6 +373,10 @@ namespace llvm {
     void dump(const ScheduleDAG *G) const;
     void dumpAll(const ScheduleDAG *G) const;
     void print(raw_ostream &O, const ScheduleDAG *G) const;
+
+  private:
+    void ComputeDepth();
+    void ComputeHeight();
   };
 
   //===--------------------------------------------------------------------===//
@@ -419,19 +418,20 @@ namespace llvm {
   public:
     SelectionDAG *DAG;                    // DAG of the current basic block
     MachineBasicBlock *BB;                // Current basic block
+    MachineBasicBlock::iterator Begin;    // The beginning of the range to be scheduled.
+    MachineBasicBlock::iterator End;      // The end of the range to be scheduled.
     const TargetMachine &TM;              // Target processor
     const TargetInstrInfo *TII;           // Target instruction information
     const TargetRegisterInfo *TRI;        // Target processor register info
     TargetLowering *TLI;                  // Target lowering info
-    MachineFunction *MF;                  // Machine function
+    MachineFunction &MF;                  // Machine function
     MachineRegisterInfo &MRI;             // Virtual/real register map
     MachineConstantPool *ConstPool;       // Target constant pool
     std::vector<SUnit*> Sequence;         // The schedule. Null SUnit*'s
                                           // represent noop instructions.
     std::vector<SUnit> SUnits;            // The scheduling units.
 
-    ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb,
-                const TargetMachine &tm);
+    explicit ScheduleDAG(MachineFunction &mf);
 
     virtual ~ScheduleDAG();
 
@@ -442,21 +442,18 @@ namespace llvm {
   
     /// Run - perform scheduling.
     ///
-    void Run();
+    void Run(SelectionDAG *DAG, MachineBasicBlock *MBB,
+             MachineBasicBlock::iterator Begin,
+             MachineBasicBlock::iterator End);
 
-    /// BuildSchedUnits - Build SUnits and set up their Preds and Succs
+    /// BuildSchedGraph - Build SUnits and set up their Preds and Succs
     /// to form the scheduling dependency graph.
     ///
-    virtual void BuildSchedUnits() = 0;
+    virtual void BuildSchedGraph() = 0;
 
     /// ComputeLatency - Compute node latency.
     ///
-    virtual void ComputeLatency(SUnit *SU) { SU->Latency = 1; }
-
-    /// CalculateDepths, CalculateHeights - Calculate node depth / height.
-    ///
-    void CalculateDepths();
-    void CalculateHeights();
+    virtual void ComputeLatency(SUnit *SU) = 0;
 
   protected:
     /// EmitNoop - Emit a noop instruction.
@@ -492,7 +489,12 @@ namespace llvm {
   protected:
     void AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO);
 
-    void EmitCrossRCCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap);
+    void EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap);
+
+    /// ForceUnitLatencies - Return true if all scheduling edges should be given a
+    /// latency value of one.  The default is to return false; schedulers may
+    /// override this as needed.
+    virtual bool ForceUnitLatencies() const { return false; }
 
   private:
     /// EmitLiveInCopy - Emit a copy for a live in physical register. If the
@@ -549,10 +551,13 @@ namespace llvm {
     const SUnit *getNode() const { return Node; }
     /// isCtrlDep - Test if this is not an SDep::Data dependence.
     bool isCtrlDep() const {
-      return Node->Preds[Operand].isCtrl();
+      return getSDep().isCtrl();
     }
     bool isArtificialDep() const {
-      return Node->Preds[Operand].isArtificial();
+      return getSDep().isArtificial();
+    }
+    const SDep &getSDep() const {
+      return Node->Preds[Operand];
     }
   };