Revert Christopher Lamb's load/store alignment changes.
[oota-llvm.git] / include / llvm / CodeGen / ScheduleDAG.h
index 5f9236d401776e75d3b2ae0d2f85b0d8447a567d..f934cf327e672551483de712acd6a7b163870f0a 100644 (file)
 #define LLVM_CODEGEN_SCHEDULEDAG_H
 
 #include "llvm/CodeGen/SelectionDAG.h"
-
-#include <set>
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallSet.h"
 
 namespace llvm {
   struct InstrStage;
   class MachineConstantPool;
-  class MachineDebugInfo;
+  class MachineModuleInfo;
   class MachineInstr;
   class MRegisterInfo;
   class SelectionDAG;
+  class SelectionDAGISel;
   class SSARegMap;
   class TargetInstrInfo;
   class TargetInstrDescriptor;
@@ -41,7 +42,7 @@ namespace llvm {
     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.
+      NoopHazard     // This instruction can't be emitted, and needs noops.
     };
     
     /// getHazardType - Return the hazard type of emitting this node.  There are
@@ -77,13 +78,20 @@ namespace llvm {
   /// a group of nodes flagged together.
   struct SUnit {
     SDNode *Node;                       // Representative node.
-    std::vector<SDNode*> FlaggedNodes;  // All nodes flagged to Node.
+    SmallVector<SDNode*,4> FlaggedNodes;// All nodes flagged to Node.
     
     // Preds/Succs - The SUnits before/after us in the graph.  The boolean value
     // is true if the edge is a token chain edge, false if it is a value edge. 
-    std::set<std::pair<SUnit*,bool> > Preds;  // All sunit predecessors.
-    std::set<std::pair<SUnit*,bool> > Succs;  // All sunit successors.
+    SmallVector<std::pair<SUnit*,bool>, 4> Preds;  // All sunit predecessors.
+    SmallVector<std::pair<SUnit*,bool>, 4> Succs;  // All sunit successors.
 
+    typedef SmallVector<std::pair<SUnit*,bool>, 4>::iterator pred_iterator;
+    typedef SmallVector<std::pair<SUnit*,bool>, 4>::iterator succ_iterator;
+    typedef SmallVector<std::pair<SUnit*,bool>, 4>::const_iterator 
+      const_pred_iterator;
+    typedef SmallVector<std::pair<SUnit*,bool>, 4>::const_iterator 
+      const_succ_iterator;
+    
     short NumPreds;                     // # of preds.
     short NumSuccs;                     // # of sucss.
     short NumPredsLeft;                 // # of preds not scheduled.
@@ -91,7 +99,7 @@ namespace llvm {
     short NumChainPredsLeft;            // # of chain preds not scheduled.
     short NumChainSuccsLeft;            // # of chain succs not scheduled.
     bool isTwoAddress     : 1;          // Is a two-address instruction.
-    bool isDefNUseOperand : 1;          // Is a def&use operand.
+    bool isCommutable     : 1;          // Is a commutable instruction.
     bool isPending        : 1;          // True once pending.
     bool isAvailable      : 1;          // True once available.
     bool isScheduled      : 1;          // True once scheduled.
@@ -105,11 +113,31 @@ namespace llvm {
     SUnit(SDNode *node, unsigned nodenum)
       : Node(node), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0),
         NumChainPredsLeft(0), NumChainSuccsLeft(0),
-        isTwoAddress(false), isDefNUseOperand(false),
+        isTwoAddress(false), isCommutable(false),
         isPending(false), isAvailable(false), isScheduled(false),
         Latency(0), CycleBound(0), Cycle(0), Depth(0), Height(0),
         NodeNum(nodenum) {}
     
+    /// addPred - This adds the specified node as a pred of the current node if
+    /// not already.  This returns true if this is a new pred.
+    bool addPred(SUnit *N, bool isChain) {
+      for (unsigned i = 0, e = Preds.size(); i != e; ++i)
+        if (Preds[i].first == N && Preds[i].second == isChain)
+          return false;
+      Preds.push_back(std::make_pair(N, isChain));
+      return true;
+    }
+
+    /// addSucc - This adds the specified node as a succ of the current node if
+    /// not already.  This returns true if this is a new succ.
+    bool addSucc(SUnit *N, bool isChain) {
+      for (unsigned i = 0, e = Succs.size(); i != e; ++i)
+        if (Succs[i].first == N && Succs[i].second == isChain)
+          return false;
+      Succs.push_back(std::make_pair(N, isChain));
+      return true;
+    }
+    
     void dump(const SelectionDAG *G) const;
     void dumpAll(const SelectionDAG *G) const;
   };
@@ -126,7 +154,8 @@ namespace llvm {
   public:
     virtual ~SchedulingPriorityQueue() {}
   
-    virtual void initNodes(const std::vector<SUnit> &SUnits) = 0;
+    virtual void initNodes(DenseMap<SDNode*, SUnit*> &SUMap,
+                           std::vector<SUnit> &SUnits) = 0;
     virtual void releaseState() = 0;
   
     virtual bool empty() const = 0;
@@ -143,18 +172,6 @@ namespace llvm {
 
   class ScheduleDAG {
   public:
-
-    // Scheduling heuristics
-    enum SchedHeuristics {
-      defaultScheduling,      // Let the target specify its preference.
-      noScheduling,           // No scheduling, emit breadth first sequence.
-      simpleScheduling,       // Two pass, min. critical path, max. utilization.
-      simpleNoItinScheduling, // Same as above exact using generic latency.
-      listSchedulingBURR,     // Bottom-up reg reduction list scheduling.
-      listSchedulingTDRR,     // Top-down reg reduction list scheduling.
-      listSchedulingTD        // Top-down list scheduler.
-    };
-
     SelectionDAG &DAG;                    // DAG of the current basic block
     MachineBasicBlock *BB;                // Current basic block
     const TargetMachine &TM;              // Target processor
@@ -162,10 +179,11 @@ namespace llvm {
     const MRegisterInfo *MRI;             // Target processor register info
     SSARegMap *RegMap;                    // Virtual/real register map
     MachineConstantPool *ConstPool;       // Target constant pool
-    std::vector<SUnit*> Sequence;         // The schedule.  Null SUnit*'s represent
-                                          // noop instructions.
-    std::map<SDNode*, SUnit*> SUnitMap;   // SDNode to SUnit mapping (n -> 1).
+    std::vector<SUnit*> Sequence;         // The schedule. Null SUnit*'s
+                                          // represent noop instructions.
+    DenseMap<SDNode*, SUnit*> SUnitMap;   // SDNode to SUnit mapping (n -> 1).
     std::vector<SUnit> SUnits;            // The scheduling units.
+    SmallSet<SDNode*, 16> CommuteSet;     // Nodes the should be commuted.
 
     ScheduleDAG(SelectionDAG &dag, MachineBasicBlock *bb,
                 const TargetMachine &tm)
@@ -208,11 +226,21 @@ namespace llvm {
     void CalculateDepths();
     void CalculateHeights();
 
+    /// CountResults - The results of target nodes have register or immediate
+    /// operands first, then an optional chain, and optional flag operands
+    /// (which do not go into the machine instrs.)
+    static unsigned CountResults(SDNode *Node);
+
+    /// CountOperands  The inputs to target nodes have any actual inputs first,
+    /// followed by an optional chain operand, then flag operands.  Compute the
+    /// number of actual operands that  will go into the machine instr.
+    static unsigned CountOperands(SDNode *Node);
+
     /// EmitNode - Generate machine code for an node and needed dependencies.
     /// VRBaseMap contains, for each already emitted node, the first virtual
     /// register number for the results of the node.
     ///
-    void EmitNode(SDNode *Node, std::map<SDNode*, unsigned> &VRBaseMap);
+    void EmitNode(SDNode *Node, DenseMap<SDNode*, unsigned> &VRBaseMap);
     
     /// EmitNoop - Emit a noop instruction.
     ///
@@ -229,32 +257,50 @@ namespace llvm {
   private:
     void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum,
                     const TargetInstrDescriptor *II,
-                    std::map<SDNode*, unsigned> &VRBaseMap);
+                    DenseMap<SDNode*, unsigned> &VRBaseMap);
   };
 
-  ScheduleDAG *createBFS_DAGScheduler(SelectionDAG &DAG, MachineBasicBlock *BB);
+  /// createBFS_DAGScheduler - This creates a simple breadth first instruction
+  /// scheduler.
+  ScheduleDAG *createBFS_DAGScheduler(SelectionDAGISel *IS,
+                                      SelectionDAG *DAG,
+                                      MachineBasicBlock *BB);
   
   /// createSimpleDAGScheduler - This creates a simple two pass instruction
-  /// scheduler.
-  ScheduleDAG* createSimpleDAGScheduler(bool NoItins, SelectionDAG &DAG,
+  /// scheduler using instruction itinerary.
+  ScheduleDAG* createSimpleDAGScheduler(SelectionDAGISel *IS,
+                                        SelectionDAG *DAG,
                                         MachineBasicBlock *BB);
 
+  /// createNoItinsDAGScheduler - This creates a simple two pass instruction
+  /// scheduler without using instruction itinerary.
+  ScheduleDAG* createNoItinsDAGScheduler(SelectionDAGISel *IS,
+                                         SelectionDAG *DAG,
+                                         MachineBasicBlock *BB);
+
   /// createBURRListDAGScheduler - This creates a bottom up register usage
   /// reduction list scheduler.
-  ScheduleDAG* createBURRListDAGScheduler(SelectionDAG &DAG,
+  ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS,
+                                          SelectionDAG *DAG,
                                           MachineBasicBlock *BB);
   
   /// createTDRRListDAGScheduler - This creates a top down register usage
   /// reduction list scheduler.
-  ScheduleDAG* createTDRRListDAGScheduler(SelectionDAG &DAG,
+  ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS,
+                                          SelectionDAG *DAG,
                                           MachineBasicBlock *BB);
   
   /// createTDListDAGScheduler - This creates a top-down list scheduler with
-  /// the specified hazard recognizer.  This takes ownership of the hazard
-  /// recognizer and deletes it when done.
-  ScheduleDAG* createTDListDAGScheduler(SelectionDAG &DAG,
-                                        MachineBasicBlock *BB,
-                                        HazardRecognizer *HR);
+  /// a hazard recognizer.
+  ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS,
+                                        SelectionDAG *DAG,
+                                        MachineBasicBlock *BB);
+                                        
+  /// createDefaultScheduler - This creates an instruction scheduler appropriate
+  /// for the target.
+  ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
+                                      SelectionDAG *DAG,
+                                      MachineBasicBlock *BB);
 }
 
 #endif