[llvm-commits] [llvm] r59676 - in /llvm/trunk: include/llvm/CodeGen/ lib/CodeGen/ lib/CodeGen/SelectionDAG/ lib/Target/CellSPU/ lib/Target/PowerPC/

Dan Gohman gohman at apple.com
Wed Nov 19 15:19:03 PST 2008


Author: djg
Date: Wed Nov 19 17:18:57 2008
New Revision: 59676

URL: http://llvm.org/viewvc/llvm-project?rev=59676&view=rev
Log:
Experimental post-pass scheduling support. Post-pass scheduling
is currently off by default, and can be enabled with
-disable-post-RA-scheduler=false.

This doesn't have a significant impact on most code yet because it doesn't
yet do anything to address anti-dependencies and it doesn't attempt to
disambiguate memory references. Also, several popular targets
don't have pipeline descriptions yet.

The majority of the changes here are splitting the SelectionDAG-specific
code out of ScheduleDAG, so that ScheduleDAG can be moved to
libLLVMCodeGen.a. The interface between ScheduleDAG-using code and
the rest of the scheduling code is somewhat rough and will evolve.

Added:
    llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h
      - copied unchanged from r59477, llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h
    llvm/trunk/include/llvm/CodeGen/ScheduleDAGInstrs.h
      - copied, changed from r59324, llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h
    llvm/trunk/include/llvm/CodeGen/ScheduleDAGSDNodes.h
      - copied, changed from r59324, llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h
    llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp
      - copied, changed from r59477, llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp
    llvm/trunk/lib/CodeGen/ScheduleDAG.cpp
      - copied, changed from r59324, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
    llvm/trunk/lib/CodeGen/ScheduleDAGEmit.cpp
      - copied, changed from r59282, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp
    llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp
      - copied, changed from r59324, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
    llvm/trunk/lib/CodeGen/ScheduleDAGPrinter.cpp
      - copied, changed from r59660, llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
      - copied, changed from r59324, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
      - copied, changed from r59282, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp
Removed:
    llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp
Modified:
    llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h
    llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h
    llvm/trunk/lib/CodeGen/CMakeLists.txt
    llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/CMakeLists.txt
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
    llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h
    llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h

Modified: llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h?rev=59676&r1=59675&r2=59676&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h (original)
+++ llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h Wed Nov 19 17:18:57 2008
@@ -16,7 +16,7 @@
 #define LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H
 
 #include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/ScheduleDAGSDNodes.h"
 #include "llvm/CodeGen/GCs.h"
 
 namespace {

Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=59676&r1=59675&r2=59676&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original)
+++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Wed Nov 19 17:18:57 2008
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // This file implements the ScheduleDAG class, which is used as the common
-// base class for SelectionDAG-based instruction scheduler.
+// base class for instruction schedulers.
 //
 //===----------------------------------------------------------------------===//
 
@@ -16,10 +16,9 @@
 #define LLVM_CODEGEN_SCHEDULEDAG_H
 
 #include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
 
 namespace llvm {
   struct SUnit;
@@ -31,51 +30,13 @@
   class TargetRegisterInfo;
   class ScheduleDAG;
   class SelectionDAG;
-  class SelectionDAGISel;
+  class SDNode;
   class TargetInstrInfo;
   class TargetInstrDesc;
   class TargetLowering;
   class TargetMachine;
   class TargetRegisterClass;
-
-  /// 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.
-  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 *) {
-      return NoHazard;
-    }
-    
-    /// EmitInstruction - This callback is invoked when an instruction is
-    /// emitted, to advance the hazard state.
-    virtual void EmitInstruction(SDNode *) {}
-    
-    /// 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() {}
-  };
+  template<class Graph> class GraphWriter;
 
   /// SDep - Scheduling dependency. It keeps track of dependent nodes,
   /// cost of the depdenency, etc.
@@ -89,8 +50,7 @@
       : Dep(d), Reg(r), Cost(t), isCtrl(c), isSpecial(s) {}
   };
 
-  /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
-  /// a group of nodes flagged together.
+  /// SUnit - Scheduling unit. This is a node in the scheduling DAG.
   struct SUnit {
   private:
     SDNode *Node;                       // Representative node.
@@ -294,12 +254,11 @@
     std::vector<SUnit*> Sequence;         // The schedule. Null SUnit*'s
                                           // represent noop instructions.
     std::vector<SUnit> SUnits;            // The scheduling units.
-    SmallSet<SDNode*, 16> CommuteSet;     // Nodes that should be commuted.
 
     ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb,
                 const TargetMachine &tm);
 
-    virtual ~ScheduleDAG() {}
+    virtual ~ScheduleDAG();
 
     /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
     /// using 'dot'.
@@ -310,84 +269,27 @@
     ///
     void Run();
 
-    /// isPassiveNode - Return true if the node is a non-scheduled leaf.
+    /// BuildSchedUnits - Build SUnits and set up their Preds and Succs
+    /// to form the scheduling dependency graph.
     ///
-    static bool isPassiveNode(SDNode *Node) {
-      if (isa<ConstantSDNode>(Node))       return true;
-      if (isa<ConstantFPSDNode>(Node))     return true;
-      if (isa<RegisterSDNode>(Node))       return true;
-      if (isa<GlobalAddressSDNode>(Node))  return true;
-      if (isa<BasicBlockSDNode>(Node))     return true;
-      if (isa<FrameIndexSDNode>(Node))     return true;
-      if (isa<ConstantPoolSDNode>(Node))   return true;
-      if (isa<JumpTableSDNode>(Node))      return true;
-      if (isa<ExternalSymbolSDNode>(Node)) return true;
-      if (isa<MemOperandSDNode>(Node))     return true;
-      if (Node->getOpcode() == ISD::EntryToken) return true;
-      return false;
-    }
-
-    /// NewSUnit - Creates a new SUnit and return a ptr to it.
-    ///
-    SUnit *NewSUnit(SDNode *N) {
-      SUnits.push_back(SUnit(N, (unsigned)SUnits.size()));
-      SUnits.back().OrigNode = &SUnits.back();
-      return &SUnits.back();
-    }
-
-    /// NewSUnit - Creates a new SUnit and return a ptr to it.
-    ///
-    SUnit *NewSUnit(MachineInstr *MI) {
-      SUnits.push_back(SUnit(MI, (unsigned)SUnits.size()));
-      SUnits.back().OrigNode = &SUnits.back();
-      return &SUnits.back();
-    }
-
-    /// Clone - Creates a clone of the specified SUnit. It does not copy the
-    /// predecessors / successors info nor the temporary scheduling states.
-    SUnit *Clone(SUnit *N);
-    
-    /// BuildSchedUnits - Build SUnits from the selection dag that we are input.
-    /// This SUnit graph is similar to the SelectionDAG, but represents flagged
-    /// together nodes with a single SUnit.
-    void BuildSchedUnits();
+    virtual void BuildSchedUnits() = 0;
 
     /// ComputeLatency - Compute node latency.
     ///
-    void ComputeLatency(SUnit *SU);
+    virtual void ComputeLatency(SUnit *SU) { SU->Latency = 1; }
 
     /// CalculateDepths, CalculateHeights - Calculate node depth / height.
     ///
     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 special operands that describe memory references, then an
-    /// optional chain operand, then flag operands.  Compute the number of
-    /// actual operands that will go into the resulting MachineInstr.
-    static unsigned CountOperands(SDNode *Node);
-
-    /// ComputeMemOperandsEnd - Find the index one past the last
-    /// MemOperandSDNode operand
-    static unsigned ComputeMemOperandsEnd(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, bool IsClone,
-                  DenseMap<SDValue, unsigned> &VRBaseMap);
-    
+  protected:
     /// EmitNoop - Emit a noop instruction.
     ///
     void EmitNoop();
 
-    MachineBasicBlock *EmitSchedule();
+  public:
+    virtual MachineBasicBlock *EmitSchedule() = 0;
 
     void dumpSchedule() const;
 
@@ -396,41 +298,22 @@
     ///
     virtual void Schedule() = 0;
 
-    /// getGraphpNodeLabel - Return a label for an SUnit node in a Graphviz or similar
-    /// graph visualization.
-    virtual std::string getGraphNodeLabel(const SUnit *SU) const;
+    virtual void dumpNode(const SUnit *SU) const = 0;
 
-  private:
-    /// EmitSubregNode - Generate machine code for subreg nodes.
-    ///
-    void EmitSubregNode(SDNode *Node, 
-                        DenseMap<SDValue, unsigned> &VRBaseMap);
+    /// getGraphNodeLabel - Return a label for an SUnit node in a visualization
+    /// of the ScheduleDAG.
+    virtual std::string getGraphNodeLabel(const SUnit *SU) const = 0;
 
-    /// getVR - Return the virtual register corresponding to the specified result
-    /// of the specified node.
-    unsigned getVR(SDValue Op, DenseMap<SDValue, unsigned> &VRBaseMap);
-  
-    /// getDstOfCopyToRegUse - If the only use of the specified result number of
-    /// node is a CopyToReg, return its destination register. Return 0 otherwise.
-    unsigned getDstOfOnlyCopyToRegUse(SDNode *Node, unsigned ResNo) const;
-
-    void AddOperand(MachineInstr *MI, SDValue Op, unsigned IIOpNum,
-                    const TargetInstrDesc *II,
-                    DenseMap<SDValue, unsigned> &VRBaseMap);
+    /// addCustomGraphFeatures - Add custom features for a visualization of
+    /// the ScheduleDAG.
+    virtual void addCustomGraphFeatures(GraphWriter<ScheduleDAG*> &GW) const {}
+
+  protected:
     void AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO);
 
     void EmitCrossRCCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap);
 
-    /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
-    /// implicit physical register output.
-    void EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone,
-                         unsigned SrcReg,
-                         DenseMap<SDValue, unsigned> &VRBaseMap);
-    
-    void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
-                                const TargetInstrDesc &II,
-                                DenseMap<SDValue, unsigned> &VRBaseMap);
-
+  private:
     /// EmitLiveInCopy - Emit a copy for a live in physical register. If the
     /// physical register has only a single copy use, then coalesced the copy
     /// if possible.
@@ -444,53 +327,8 @@
     /// and if it has live ins that need to be copied into vregs, emit the
     /// copies into the top of the block.
     void EmitLiveInCopies(MachineBasicBlock *MBB);
-
-    /// BuildSchedUnitsFromMBB - Build SUnits from the MachineBasicBlock.
-    /// This SUnit graph is similar to the pre-regalloc SUnit graph, but represents
-    /// MachineInstrs directly instead of SDNodes.
-    void BuildSchedUnitsFromMBB();
   };
 
-  /// createBURRListDAGScheduler - This creates a bottom up register usage
-  /// reduction list scheduler.
-  ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS,
-                                          SelectionDAG *DAG,
-                                          const TargetMachine *TM,
-                                          MachineBasicBlock *BB,
-                                          bool Fast);
-  
-  /// createTDRRListDAGScheduler - This creates a top down register usage
-  /// reduction list scheduler.
-  ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS,
-                                          SelectionDAG *DAG,
-                                          const TargetMachine *TM,
-                                          MachineBasicBlock *BB,
-                                          bool Fast);
-  
-  /// createTDListDAGScheduler - This creates a top-down list scheduler with
-  /// a hazard recognizer.
-  ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS,
-                                        SelectionDAG *DAG,
-                                        const TargetMachine *TM,
-                                        MachineBasicBlock *BB,
-                                        bool Fast);
-                                        
-  /// createFastDAGScheduler - This creates a "fast" scheduler.
-  ///
-  ScheduleDAG *createFastDAGScheduler(SelectionDAGISel *IS,
-                                      SelectionDAG *DAG,
-                                      const TargetMachine *TM,
-                                      MachineBasicBlock *BB,
-                                      bool Fast);
-
-  /// createDefaultScheduler - This creates an instruction scheduler appropriate
-  /// for the target.
-  ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
-                                      SelectionDAG *DAG,
-                                      const TargetMachine *TM,
-                                      MachineBasicBlock *BB,
-                                      bool Fast);
-
   class SUnitIterator : public forward_iterator<SUnit, ptrdiff_t> {
     SUnit *Node;
     unsigned Operand;

Copied: llvm/trunk/include/llvm/CodeGen/ScheduleDAGInstrs.h (from r59324, llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAGInstrs.h?p2=llvm/trunk/include/llvm/CodeGen/ScheduleDAGInstrs.h&p1=llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h&r1=59324&r2=59676&rev=59676&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original)
+++ llvm/trunk/include/llvm/CodeGen/ScheduleDAGInstrs.h Wed Nov 19 17:18:57 2008
@@ -1,4 +1,4 @@
-//===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===//
+//==- llvm/CodeGen/ScheduleDAGInstrs.h - MachineInstr Scheduling -*- C++ -*-==//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,22 +7,17 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements the ScheduleDAG class, which is used as the common
-// base class for SelectionDAG-based instruction scheduler.
+// This file implements the ScheduleDAGInstrs class, which implements
+// scheduling for a MachineInstr-based dependency graph.
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CODEGEN_SCHEDULEDAG_H
-#define LLVM_CODEGEN_SCHEDULEDAG_H
+#ifndef LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
+#define LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
 
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/SmallSet.h"
+#include "llvm/CodeGen/ScheduleDAG.h"
 
 namespace llvm {
-  struct InstrStage;
   struct SUnit;
   class MachineConstantPool;
   class MachineFunction;
@@ -30,6 +25,7 @@
   class MachineRegisterInfo;
   class MachineInstr;
   class TargetRegisterInfo;
+  class ScheduleDAG;
   class SelectionDAG;
   class SelectionDAGISel;
   class TargetInstrInfo;
@@ -38,301 +34,12 @@
   class TargetMachine;
   class TargetRegisterClass;
 
-  /// 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.
-  class HazardRecognizer {
+  class ScheduleDAGInstrs : public ScheduleDAG {
   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 *) {
-      return NoHazard;
-    }
-    
-    /// EmitInstruction - This callback is invoked when an instruction is
-    /// emitted, to advance the hazard state.
-    virtual void EmitInstruction(SDNode *) {}
-    
-    /// 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() {}
-  };
-
-  /// SDep - Scheduling dependency. It keeps track of dependent nodes,
-  /// cost of the depdenency, etc.
-  struct SDep {
-    SUnit    *Dep;           // Dependent - either a predecessor or a successor.
-    unsigned  Reg;           // If non-zero, this dep is a phy register dependency.
-    int       Cost;          // Cost of the dependency.
-    bool      isCtrl    : 1; // True iff it's a control dependency.
-    bool      isSpecial : 1; // True iff it's a special ctrl dep added during sched.
-    SDep(SUnit *d, unsigned r, int t, bool c, bool s)
-      : Dep(d), Reg(r), Cost(t), isCtrl(c), isSpecial(s) {}
-  };
-
-  /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
-  /// a group of nodes flagged together.
-  struct SUnit {
-  private:
-    SDNode *Node;                       // Representative node.
-    MachineInstr *Instr;                // Alternatively, a MachineInstr.
-  public:
-    SUnit *OrigNode;                    // If not this, the node from which
-                                        // this node was cloned.
-    
-    // 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. 
-    SmallVector<SDep, 4> Preds;  // All sunit predecessors.
-    SmallVector<SDep, 4> Succs;  // All sunit successors.
-
-    typedef SmallVector<SDep, 4>::iterator pred_iterator;
-    typedef SmallVector<SDep, 4>::iterator succ_iterator;
-    typedef SmallVector<SDep, 4>::const_iterator const_pred_iterator;
-    typedef SmallVector<SDep, 4>::const_iterator const_succ_iterator;
-    
-    unsigned NodeNum;                   // Entry # of node in the node vector.
-    unsigned NodeQueueId;               // Queue id of node.
-    unsigned short Latency;             // Node latency.
-    short NumPreds;                     // # of non-control preds.
-    short NumSuccs;                     // # of non-control sucss.
-    short NumPredsLeft;                 // # of preds not scheduled.
-    short NumSuccsLeft;                 // # of succs not scheduled.
-    bool isTwoAddress     : 1;          // Is a two-address instruction.
-    bool isCommutable     : 1;          // Is a commutable instruction.
-    bool hasPhysRegDefs   : 1;          // Has physreg defs that are being used.
-    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;
-    const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null.
-    const TargetRegisterClass *CopySrcRC;
-    
-    /// SUnit - Construct an SUnit for pre-regalloc scheduling to represent
-    /// an SDNode and any nodes flagged to it.
-    SUnit(SDNode *node, unsigned nodenum)
-      : Node(node), Instr(0), OrigNode(0), NodeNum(nodenum), NodeQueueId(0),
-        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(0), Depth(0), Height(0),
-        CopyDstRC(NULL), CopySrcRC(NULL) {}
-
-    /// SUnit - Construct an SUnit for post-regalloc scheduling to represent
-    /// a MachineInstr.
-    SUnit(MachineInstr *instr, unsigned nodenum)
-      : Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum), NodeQueueId(0),
-        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(0), Depth(0), Height(0),
-        CopyDstRC(NULL), CopySrcRC(NULL) {}
-
-    /// setNode - Assign the representative SDNode for this SUnit.
-    /// This may be used during pre-regalloc scheduling.
-    void setNode(SDNode *N) {
-      assert(!Instr && "Setting SDNode of SUnit with MachineInstr!");
-      Node = N;
-    }
+    ScheduleDAGInstrs(MachineBasicBlock *bb,
+                      const TargetMachine &tm);
 
-    /// getNode - Return the representative SDNode for this SUnit.
-    /// This may be used during pre-regalloc scheduling.
-    SDNode *getNode() const {
-      assert(!Instr && "Reading SDNode of SUnit with MachineInstr!");
-      return Node;
-    }
-
-    /// setInstr - Assign the instruction for the SUnit.
-    /// This may be used during post-regalloc scheduling.
-    void setInstr(MachineInstr *MI) {
-      assert(!Node && "Setting MachineInstr of SUnit with SDNode!");
-      Instr = MI;
-    }
-
-    /// getInstr - Return the representative MachineInstr for this SUnit.
-    /// This may be used during post-regalloc scheduling.
-    MachineInstr *getInstr() const {
-      assert(!Node && "Reading MachineInstr of SUnit with SDNode!");
-      return Instr;
-    }
-
-    /// 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 isCtrl, bool isSpecial,
-                 unsigned PhyReg = 0, int Cost = 1) {
-      for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
-        if (Preds[i].Dep == N &&
-            Preds[i].isCtrl == isCtrl && Preds[i].isSpecial == isSpecial)
-          return false;
-      Preds.push_back(SDep(N, PhyReg, Cost, isCtrl, isSpecial));
-      N->Succs.push_back(SDep(this, PhyReg, Cost, isCtrl, isSpecial));
-      if (!isCtrl) {
-        ++NumPreds;
-        ++N->NumSuccs;
-      }
-      if (!N->isScheduled)
-        ++NumPredsLeft;
-      if (!isScheduled)
-        ++N->NumSuccsLeft;
-      return true;
-    }
-
-    bool removePred(SUnit *N, bool isCtrl, bool isSpecial) {
-      for (SmallVector<SDep, 4>::iterator I = Preds.begin(), E = Preds.end();
-           I != E; ++I)
-        if (I->Dep == N && I->isCtrl == isCtrl && I->isSpecial == isSpecial) {
-          bool FoundSucc = false;
-          for (SmallVector<SDep, 4>::iterator II = N->Succs.begin(),
-                 EE = N->Succs.end(); II != EE; ++II)
-            if (II->Dep == this &&
-                II->isCtrl == isCtrl && II->isSpecial == isSpecial) {
-              FoundSucc = true;
-              N->Succs.erase(II);
-              break;
-            }
-          assert(FoundSucc && "Mismatching preds / succs lists!");
-          Preds.erase(I);
-          if (!isCtrl) {
-            --NumPreds;
-            --N->NumSuccs;
-          }
-          if (!N->isScheduled)
-            --NumPredsLeft;
-          if (!isScheduled)
-            --N->NumSuccsLeft;
-          return true;
-        }
-      return false;
-    }
-
-    bool isPred(SUnit *N) {
-      for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
-        if (Preds[i].Dep == N)
-          return true;
-      return false;
-    }
-    
-    bool isSucc(SUnit *N) {
-      for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i)
-        if (Succs[i].Dep == N)
-          return true;
-      return false;
-    }
-    
-    void dump(const SelectionDAG *G) const;
-    void dumpAll(const SelectionDAG *G) const;
-  };
-
-  //===--------------------------------------------------------------------===//
-  /// SchedulingPriorityQueue - This interface is used to plug different
-  /// priorities computation algorithms into the list scheduler. It implements
-  /// the interface of a standard priority queue, where nodes are inserted in 
-  /// arbitrary order and returned in priority order.  The computation of the
-  /// priority and the representation of the queue are totally up to the
-  /// implementation to decide.
-  /// 
-  class SchedulingPriorityQueue {
-  public:
-    virtual ~SchedulingPriorityQueue() {}
-  
-    virtual void initNodes(std::vector<SUnit> &SUnits) = 0;
-    virtual void addNode(const SUnit *SU) = 0;
-    virtual void updateNode(const SUnit *SU) = 0;
-    virtual void releaseState() = 0;
-
-    virtual unsigned size() const = 0;
-    virtual bool empty() const = 0;
-    virtual void push(SUnit *U) = 0;
-  
-    virtual void push_all(const std::vector<SUnit *> &Nodes) = 0;
-    virtual SUnit *pop() = 0;
-
-    virtual void remove(SUnit *SU) = 0;
-
-    /// ScheduledNode - As each node is scheduled, this method is invoked.  This
-    /// allows the priority function to adjust the priority of related
-    /// unscheduled nodes, for example.
-    ///
-    virtual void ScheduledNode(SUnit *) {}
-
-    virtual void UnscheduledNode(SUnit *) {}
-  };
-
-  class ScheduleDAG {
-  public:
-    SelectionDAG *DAG;                    // DAG of the current basic block
-    MachineBasicBlock *BB;                // Current basic block
-    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
-    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.
-    SmallSet<SDNode*, 16> CommuteSet;     // Nodes that should be commuted.
-
-    ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb,
-                const TargetMachine &tm);
-
-    virtual ~ScheduleDAG() {}
-
-    /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
-    /// using 'dot'.
-    ///
-    void viewGraph();
-  
-    /// Run - perform scheduling.
-    ///
-    void Run();
-
-    /// isPassiveNode - Return true if the node is a non-scheduled leaf.
-    ///
-    static bool isPassiveNode(SDNode *Node) {
-      if (isa<ConstantSDNode>(Node))       return true;
-      if (isa<ConstantFPSDNode>(Node))     return true;
-      if (isa<RegisterSDNode>(Node))       return true;
-      if (isa<GlobalAddressSDNode>(Node))  return true;
-      if (isa<BasicBlockSDNode>(Node))     return true;
-      if (isa<FrameIndexSDNode>(Node))     return true;
-      if (isa<ConstantPoolSDNode>(Node))   return true;
-      if (isa<JumpTableSDNode>(Node))      return true;
-      if (isa<ExternalSymbolSDNode>(Node)) return true;
-      if (isa<MemOperandSDNode>(Node))     return true;
-      if (Node->getOpcode() == ISD::EntryToken) return true;
-      return false;
-    }
-
-    /// NewSUnit - Creates a new SUnit and return a ptr to it.
-    ///
-    SUnit *NewSUnit(SDNode *N) {
-      SUnits.push_back(SUnit(N, (unsigned)SUnits.size()));
-      SUnits.back().OrigNode = &SUnits.back();
-      return &SUnits.back();
-    }
+    virtual ~ScheduleDAGInstrs() {}
 
     /// NewSUnit - Creates a new SUnit and return a ptr to it.
     ///
@@ -342,211 +49,20 @@
       return &SUnits.back();
     }
 
-    /// Clone - Creates a clone of the specified SUnit. It does not copy the
-    /// predecessors / successors info nor the temporary scheduling states.
-    SUnit *Clone(SUnit *N);
-    
-    /// BuildSchedUnits - Build SUnits from the selection dag that we are input.
-    /// This SUnit graph is similar to the SelectionDAG, but represents flagged
-    /// together nodes with a single SUnit.
-    void BuildSchedUnits();
-
-    /// ComputeLatency - Compute node latency.
-    ///
-    void ComputeLatency(SUnit *SU);
-
-    /// CalculateDepths, CalculateHeights - Calculate node depth / height.
-    ///
-    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 special operands that describe memory references, then an
-    /// optional chain operand, then flag operands.  Compute the number of
-    /// actual operands that will go into the resulting MachineInstr.
-    static unsigned CountOperands(SDNode *Node);
-
-    /// ComputeMemOperandsEnd - Find the index one past the last
-    /// MemOperandSDNode operand
-    static unsigned ComputeMemOperandsEnd(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, bool IsClone,
-                  DenseMap<SDValue, unsigned> &VRBaseMap);
-    
-    /// EmitNoop - Emit a noop instruction.
-    ///
-    void EmitNoop();
-
-    MachineBasicBlock *EmitSchedule();
+    /// BuildSchedUnits - Build SUnits from the MachineBasicBlock that we are
+    /// input.
+    virtual void BuildSchedUnits();
 
-    void dumpSchedule() const;
+    virtual MachineBasicBlock *EmitSchedule();
 
     /// Schedule - Order nodes according to selected style, filling
     /// in the Sequence member.
     ///
     virtual void Schedule() = 0;
 
-  private:
-    /// EmitSubregNode - Generate machine code for subreg nodes.
-    ///
-    void EmitSubregNode(SDNode *Node, 
-                        DenseMap<SDValue, unsigned> &VRBaseMap);
-
-    /// getVR - Return the virtual register corresponding to the specified result
-    /// of the specified node.
-    unsigned getVR(SDValue Op, DenseMap<SDValue, unsigned> &VRBaseMap);
-  
-    /// getDstOfCopyToRegUse - If the only use of the specified result number of
-    /// node is a CopyToReg, return its destination register. Return 0 otherwise.
-    unsigned getDstOfOnlyCopyToRegUse(SDNode *Node, unsigned ResNo) const;
-
-    void AddOperand(MachineInstr *MI, SDValue Op, unsigned IIOpNum,
-                    const TargetInstrDesc *II,
-                    DenseMap<SDValue, unsigned> &VRBaseMap);
-    void AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO);
-
-    void EmitCrossRCCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap);
-
-    /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
-    /// implicit physical register output.
-    void EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone,
-                         unsigned SrcReg,
-                         DenseMap<SDValue, unsigned> &VRBaseMap);
-    
-    void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
-                                const TargetInstrDesc &II,
-                                DenseMap<SDValue, unsigned> &VRBaseMap);
-
-    /// EmitLiveInCopy - Emit a copy for a live in physical register. If the
-    /// physical register has only a single copy use, then coalesced the copy
-    /// if possible.
-    void EmitLiveInCopy(MachineBasicBlock *MBB,
-                        MachineBasicBlock::iterator &InsertPos,
-                        unsigned VirtReg, unsigned PhysReg,
-                        const TargetRegisterClass *RC,
-                        DenseMap<MachineInstr*, unsigned> &CopyRegMap);
-
-    /// EmitLiveInCopies - If this is the first basic block in the function,
-    /// and if it has live ins that need to be copied into vregs, emit the
-    /// copies into the top of the block.
-    void EmitLiveInCopies(MachineBasicBlock *MBB);
-
-    /// BuildSchedUnitsFromMBB - Build SUnits from the MachineBasicBlock.
-    /// This SUnit graph is similar to the pre-regalloc SUnit graph, but represents
-    /// MachineInstrs directly instead of SDNodes.
-    void BuildSchedUnitsFromMBB();
-  };
-
-  /// createBURRListDAGScheduler - This creates a bottom up register usage
-  /// reduction list scheduler.
-  ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS,
-                                          SelectionDAG *DAG,
-                                          const TargetMachine *TM,
-                                          MachineBasicBlock *BB,
-                                          bool Fast);
-  
-  /// createTDRRListDAGScheduler - This creates a top down register usage
-  /// reduction list scheduler.
-  ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS,
-                                          SelectionDAG *DAG,
-                                          const TargetMachine *TM,
-                                          MachineBasicBlock *BB,
-                                          bool Fast);
-  
-  /// createTDListDAGScheduler - This creates a top-down list scheduler with
-  /// a hazard recognizer.
-  ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS,
-                                        SelectionDAG *DAG,
-                                        const TargetMachine *TM,
-                                        MachineBasicBlock *BB,
-                                        bool Fast);
-                                        
-  /// createFastDAGScheduler - This creates a "fast" scheduler.
-  ///
-  ScheduleDAG *createFastDAGScheduler(SelectionDAGISel *IS,
-                                      SelectionDAG *DAG,
-                                      const TargetMachine *TM,
-                                      MachineBasicBlock *BB,
-                                      bool Fast);
-
-  /// createDefaultScheduler - This creates an instruction scheduler appropriate
-  /// for the target.
-  ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
-                                      SelectionDAG *DAG,
-                                      const TargetMachine *TM,
-                                      MachineBasicBlock *BB,
-                                      bool Fast);
-
-  class SUnitIterator : public forward_iterator<SUnit, ptrdiff_t> {
-    SUnit *Node;
-    unsigned Operand;
-
-    SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {}
-  public:
-    bool operator==(const SUnitIterator& x) const {
-      return Operand == x.Operand;
-    }
-    bool operator!=(const SUnitIterator& x) const { return !operator==(x); }
-
-    const SUnitIterator &operator=(const SUnitIterator &I) {
-      assert(I.Node == Node && "Cannot assign iterators to two different nodes!");
-      Operand = I.Operand;
-      return *this;
-    }
-
-    pointer operator*() const {
-      return Node->Preds[Operand].Dep;
-    }
-    pointer operator->() const { return operator*(); }
-
-    SUnitIterator& operator++() {                // Preincrement
-      ++Operand;
-      return *this;
-    }
-    SUnitIterator operator++(int) { // Postincrement
-      SUnitIterator tmp = *this; ++*this; return tmp;
-    }
-
-    static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); }
-    static SUnitIterator end  (SUnit *N) {
-      return SUnitIterator(N, (unsigned)N->Preds.size());
-    }
-
-    unsigned getOperand() const { return Operand; }
-    const SUnit *getNode() const { return Node; }
-    bool isCtrlDep() const { return Node->Preds[Operand].isCtrl; }
-    bool isSpecialDep() const { return Node->Preds[Operand].isSpecial; }
-  };
+    virtual void dumpNode(const SUnit *SU) const;
 
-  template <> struct GraphTraits<SUnit*> {
-    typedef SUnit NodeType;
-    typedef SUnitIterator ChildIteratorType;
-    static inline NodeType *getEntryNode(SUnit *N) { return N; }
-    static inline ChildIteratorType child_begin(NodeType *N) {
-      return SUnitIterator::begin(N);
-    }
-    static inline ChildIteratorType child_end(NodeType *N) {
-      return SUnitIterator::end(N);
-    }
-  };
-
-  template <> struct GraphTraits<ScheduleDAG*> : public GraphTraits<SUnit*> {
-    typedef std::vector<SUnit>::iterator nodes_iterator;
-    static nodes_iterator nodes_begin(ScheduleDAG *G) {
-      return G->SUnits.begin();
-    }
-    static nodes_iterator nodes_end(ScheduleDAG *G) {
-      return G->SUnits.end();
-    }
+    virtual std::string getGraphNodeLabel(const SUnit *SU) const;
   };
 }
 

Copied: llvm/trunk/include/llvm/CodeGen/ScheduleDAGSDNodes.h (from r59324, llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAGSDNodes.h?p2=llvm/trunk/include/llvm/CodeGen/ScheduleDAGSDNodes.h&p1=llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h&r1=59324&r2=59676&rev=59676&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original)
+++ llvm/trunk/include/llvm/CodeGen/ScheduleDAGSDNodes.h Wed Nov 19 17:18:57 2008
@@ -1,4 +1,4 @@
-//===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===//
+//===---- llvm/CodeGen/ScheduleDAGSDNodes.h - SDNode Scheduling -*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,22 +7,19 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements the ScheduleDAG class, which is used as the common
-// base class for SelectionDAG-based instruction scheduler.
+// This file implements the ScheduleDAGSDNodes class, which implements
+// scheduling for an SDNode-based dependency graph.
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CODEGEN_SCHEDULEDAG_H
-#define LLVM_CODEGEN_SCHEDULEDAG_H
+#ifndef LLVM_CODEGEN_SCHEDULEDAGSDNODES_H
+#define LLVM_CODEGEN_SCHEDULEDAGSDNODES_H
 
-#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/ScheduleDAG.h"
 #include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/GraphTraits.h"
 #include "llvm/ADT/SmallSet.h"
 
 namespace llvm {
-  struct InstrStage;
   struct SUnit;
   class MachineConstantPool;
   class MachineFunction;
@@ -30,6 +27,7 @@
   class MachineRegisterInfo;
   class MachineInstr;
   class TargetRegisterInfo;
+  class ScheduleDAG;
   class SelectionDAG;
   class SelectionDAGISel;
   class TargetInstrInfo;
@@ -77,237 +75,14 @@
     virtual void EmitNoop() {}
   };
 
-  /// SDep - Scheduling dependency. It keeps track of dependent nodes,
-  /// cost of the depdenency, etc.
-  struct SDep {
-    SUnit    *Dep;           // Dependent - either a predecessor or a successor.
-    unsigned  Reg;           // If non-zero, this dep is a phy register dependency.
-    int       Cost;          // Cost of the dependency.
-    bool      isCtrl    : 1; // True iff it's a control dependency.
-    bool      isSpecial : 1; // True iff it's a special ctrl dep added during sched.
-    SDep(SUnit *d, unsigned r, int t, bool c, bool s)
-      : Dep(d), Reg(r), Cost(t), isCtrl(c), isSpecial(s) {}
-  };
-
-  /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
-  /// a group of nodes flagged together.
-  struct SUnit {
-  private:
-    SDNode *Node;                       // Representative node.
-    MachineInstr *Instr;                // Alternatively, a MachineInstr.
+  class ScheduleDAGSDNodes : public ScheduleDAG {
   public:
-    SUnit *OrigNode;                    // If not this, the node from which
-                                        // this node was cloned.
-    
-    // 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. 
-    SmallVector<SDep, 4> Preds;  // All sunit predecessors.
-    SmallVector<SDep, 4> Succs;  // All sunit successors.
-
-    typedef SmallVector<SDep, 4>::iterator pred_iterator;
-    typedef SmallVector<SDep, 4>::iterator succ_iterator;
-    typedef SmallVector<SDep, 4>::const_iterator const_pred_iterator;
-    typedef SmallVector<SDep, 4>::const_iterator const_succ_iterator;
-    
-    unsigned NodeNum;                   // Entry # of node in the node vector.
-    unsigned NodeQueueId;               // Queue id of node.
-    unsigned short Latency;             // Node latency.
-    short NumPreds;                     // # of non-control preds.
-    short NumSuccs;                     // # of non-control sucss.
-    short NumPredsLeft;                 // # of preds not scheduled.
-    short NumSuccsLeft;                 // # of succs not scheduled.
-    bool isTwoAddress     : 1;          // Is a two-address instruction.
-    bool isCommutable     : 1;          // Is a commutable instruction.
-    bool hasPhysRegDefs   : 1;          // Has physreg defs that are being used.
-    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;
-    const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null.
-    const TargetRegisterClass *CopySrcRC;
-    
-    /// SUnit - Construct an SUnit for pre-regalloc scheduling to represent
-    /// an SDNode and any nodes flagged to it.
-    SUnit(SDNode *node, unsigned nodenum)
-      : Node(node), Instr(0), OrigNode(0), NodeNum(nodenum), NodeQueueId(0),
-        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(0), Depth(0), Height(0),
-        CopyDstRC(NULL), CopySrcRC(NULL) {}
-
-    /// SUnit - Construct an SUnit for post-regalloc scheduling to represent
-    /// a MachineInstr.
-    SUnit(MachineInstr *instr, unsigned nodenum)
-      : Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum), NodeQueueId(0),
-        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(0), Depth(0), Height(0),
-        CopyDstRC(NULL), CopySrcRC(NULL) {}
-
-    /// setNode - Assign the representative SDNode for this SUnit.
-    /// This may be used during pre-regalloc scheduling.
-    void setNode(SDNode *N) {
-      assert(!Instr && "Setting SDNode of SUnit with MachineInstr!");
-      Node = N;
-    }
-
-    /// getNode - Return the representative SDNode for this SUnit.
-    /// This may be used during pre-regalloc scheduling.
-    SDNode *getNode() const {
-      assert(!Instr && "Reading SDNode of SUnit with MachineInstr!");
-      return Node;
-    }
-
-    /// setInstr - Assign the instruction for the SUnit.
-    /// This may be used during post-regalloc scheduling.
-    void setInstr(MachineInstr *MI) {
-      assert(!Node && "Setting MachineInstr of SUnit with SDNode!");
-      Instr = MI;
-    }
-
-    /// getInstr - Return the representative MachineInstr for this SUnit.
-    /// This may be used during post-regalloc scheduling.
-    MachineInstr *getInstr() const {
-      assert(!Node && "Reading MachineInstr of SUnit with SDNode!");
-      return Instr;
-    }
-
-    /// 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 isCtrl, bool isSpecial,
-                 unsigned PhyReg = 0, int Cost = 1) {
-      for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
-        if (Preds[i].Dep == N &&
-            Preds[i].isCtrl == isCtrl && Preds[i].isSpecial == isSpecial)
-          return false;
-      Preds.push_back(SDep(N, PhyReg, Cost, isCtrl, isSpecial));
-      N->Succs.push_back(SDep(this, PhyReg, Cost, isCtrl, isSpecial));
-      if (!isCtrl) {
-        ++NumPreds;
-        ++N->NumSuccs;
-      }
-      if (!N->isScheduled)
-        ++NumPredsLeft;
-      if (!isScheduled)
-        ++N->NumSuccsLeft;
-      return true;
-    }
-
-    bool removePred(SUnit *N, bool isCtrl, bool isSpecial) {
-      for (SmallVector<SDep, 4>::iterator I = Preds.begin(), E = Preds.end();
-           I != E; ++I)
-        if (I->Dep == N && I->isCtrl == isCtrl && I->isSpecial == isSpecial) {
-          bool FoundSucc = false;
-          for (SmallVector<SDep, 4>::iterator II = N->Succs.begin(),
-                 EE = N->Succs.end(); II != EE; ++II)
-            if (II->Dep == this &&
-                II->isCtrl == isCtrl && II->isSpecial == isSpecial) {
-              FoundSucc = true;
-              N->Succs.erase(II);
-              break;
-            }
-          assert(FoundSucc && "Mismatching preds / succs lists!");
-          Preds.erase(I);
-          if (!isCtrl) {
-            --NumPreds;
-            --N->NumSuccs;
-          }
-          if (!N->isScheduled)
-            --NumPredsLeft;
-          if (!isScheduled)
-            --N->NumSuccsLeft;
-          return true;
-        }
-      return false;
-    }
-
-    bool isPred(SUnit *N) {
-      for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
-        if (Preds[i].Dep == N)
-          return true;
-      return false;
-    }
-    
-    bool isSucc(SUnit *N) {
-      for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i)
-        if (Succs[i].Dep == N)
-          return true;
-      return false;
-    }
-    
-    void dump(const SelectionDAG *G) const;
-    void dumpAll(const SelectionDAG *G) const;
-  };
-
-  //===--------------------------------------------------------------------===//
-  /// SchedulingPriorityQueue - This interface is used to plug different
-  /// priorities computation algorithms into the list scheduler. It implements
-  /// the interface of a standard priority queue, where nodes are inserted in 
-  /// arbitrary order and returned in priority order.  The computation of the
-  /// priority and the representation of the queue are totally up to the
-  /// implementation to decide.
-  /// 
-  class SchedulingPriorityQueue {
-  public:
-    virtual ~SchedulingPriorityQueue() {}
-  
-    virtual void initNodes(std::vector<SUnit> &SUnits) = 0;
-    virtual void addNode(const SUnit *SU) = 0;
-    virtual void updateNode(const SUnit *SU) = 0;
-    virtual void releaseState() = 0;
-
-    virtual unsigned size() const = 0;
-    virtual bool empty() const = 0;
-    virtual void push(SUnit *U) = 0;
-  
-    virtual void push_all(const std::vector<SUnit *> &Nodes) = 0;
-    virtual SUnit *pop() = 0;
-
-    virtual void remove(SUnit *SU) = 0;
-
-    /// ScheduledNode - As each node is scheduled, this method is invoked.  This
-    /// allows the priority function to adjust the priority of related
-    /// unscheduled nodes, for example.
-    ///
-    virtual void ScheduledNode(SUnit *) {}
-
-    virtual void UnscheduledNode(SUnit *) {}
-  };
-
-  class ScheduleDAG {
-  public:
-    SelectionDAG *DAG;                    // DAG of the current basic block
-    MachineBasicBlock *BB;                // Current basic block
-    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
-    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.
     SmallSet<SDNode*, 16> CommuteSet;     // Nodes that should be commuted.
 
-    ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb,
-                const TargetMachine &tm);
-
-    virtual ~ScheduleDAG() {}
+    ScheduleDAGSDNodes(SelectionDAG *dag, MachineBasicBlock *bb,
+                       const TargetMachine &tm);
 
-    /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
-    /// using 'dot'.
-    ///
-    void viewGraph();
-  
-    /// Run - perform scheduling.
-    ///
-    void Run();
+    virtual ~ScheduleDAGSDNodes() {}
 
     /// isPassiveNode - Return true if the node is a non-scheduled leaf.
     ///
@@ -334,31 +109,21 @@
       return &SUnits.back();
     }
 
-    /// NewSUnit - Creates a new SUnit and return a ptr to it.
-    ///
-    SUnit *NewSUnit(MachineInstr *MI) {
-      SUnits.push_back(SUnit(MI, (unsigned)SUnits.size()));
-      SUnits.back().OrigNode = &SUnits.back();
-      return &SUnits.back();
-    }
-
     /// Clone - Creates a clone of the specified SUnit. It does not copy the
     /// predecessors / successors info nor the temporary scheduling states.
+    ///
     SUnit *Clone(SUnit *N);
     
+    virtual SelectionDAG *getDAG() { return DAG; }
+
     /// BuildSchedUnits - Build SUnits from the selection dag that we are input.
     /// This SUnit graph is similar to the SelectionDAG, but represents flagged
     /// together nodes with a single SUnit.
-    void BuildSchedUnits();
+    virtual void BuildSchedUnits();
 
     /// ComputeLatency - Compute node latency.
     ///
-    void ComputeLatency(SUnit *SU);
-
-    /// CalculateDepths, CalculateHeights - Calculate node depth / height.
-    ///
-    void CalculateDepths();
-    void CalculateHeights();
+    virtual void ComputeLatency(SUnit *SU);
 
     /// CountResults - The results of target nodes have register or immediate
     /// operands first, then an optional chain, and optional flag operands
@@ -382,19 +147,19 @@
     void EmitNode(SDNode *Node, bool IsClone,
                   DenseMap<SDValue, unsigned> &VRBaseMap);
     
-    /// EmitNoop - Emit a noop instruction.
-    ///
-    void EmitNoop();
-
-    MachineBasicBlock *EmitSchedule();
-
-    void dumpSchedule() const;
+    virtual MachineBasicBlock *EmitSchedule();
 
     /// Schedule - Order nodes according to selected style, filling
     /// in the Sequence member.
     ///
     virtual void Schedule() = 0;
 
+    virtual void dumpNode(const SUnit *SU) const;
+
+    virtual std::string getGraphNodeLabel(const SUnit *SU) const;
+
+    virtual void getCustomGraphFeatures(GraphWriter<ScheduleDAG*> &GW) const;
+
   private:
     /// EmitSubregNode - Generate machine code for subreg nodes.
     ///
@@ -412,9 +177,6 @@
     void AddOperand(MachineInstr *MI, SDValue Op, unsigned IIOpNum,
                     const TargetInstrDesc *II,
                     DenseMap<SDValue, unsigned> &VRBaseMap);
-    void AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO);
-
-    void EmitCrossRCCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap);
 
     /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
     /// implicit physical register output.
@@ -425,25 +187,6 @@
     void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
                                 const TargetInstrDesc &II,
                                 DenseMap<SDValue, unsigned> &VRBaseMap);
-
-    /// EmitLiveInCopy - Emit a copy for a live in physical register. If the
-    /// physical register has only a single copy use, then coalesced the copy
-    /// if possible.
-    void EmitLiveInCopy(MachineBasicBlock *MBB,
-                        MachineBasicBlock::iterator &InsertPos,
-                        unsigned VirtReg, unsigned PhysReg,
-                        const TargetRegisterClass *RC,
-                        DenseMap<MachineInstr*, unsigned> &CopyRegMap);
-
-    /// EmitLiveInCopies - If this is the first basic block in the function,
-    /// and if it has live ins that need to be copied into vregs, emit the
-    /// copies into the top of the block.
-    void EmitLiveInCopies(MachineBasicBlock *MBB);
-
-    /// BuildSchedUnitsFromMBB - Build SUnits from the MachineBasicBlock.
-    /// This SUnit graph is similar to the pre-regalloc SUnit graph, but represents
-    /// MachineInstrs directly instead of SDNodes.
-    void BuildSchedUnitsFromMBB();
   };
 
   /// createBURRListDAGScheduler - This creates a bottom up register usage
@@ -485,69 +228,6 @@
                                       const TargetMachine *TM,
                                       MachineBasicBlock *BB,
                                       bool Fast);
-
-  class SUnitIterator : public forward_iterator<SUnit, ptrdiff_t> {
-    SUnit *Node;
-    unsigned Operand;
-
-    SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {}
-  public:
-    bool operator==(const SUnitIterator& x) const {
-      return Operand == x.Operand;
-    }
-    bool operator!=(const SUnitIterator& x) const { return !operator==(x); }
-
-    const SUnitIterator &operator=(const SUnitIterator &I) {
-      assert(I.Node == Node && "Cannot assign iterators to two different nodes!");
-      Operand = I.Operand;
-      return *this;
-    }
-
-    pointer operator*() const {
-      return Node->Preds[Operand].Dep;
-    }
-    pointer operator->() const { return operator*(); }
-
-    SUnitIterator& operator++() {                // Preincrement
-      ++Operand;
-      return *this;
-    }
-    SUnitIterator operator++(int) { // Postincrement
-      SUnitIterator tmp = *this; ++*this; return tmp;
-    }
-
-    static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); }
-    static SUnitIterator end  (SUnit *N) {
-      return SUnitIterator(N, (unsigned)N->Preds.size());
-    }
-
-    unsigned getOperand() const { return Operand; }
-    const SUnit *getNode() const { return Node; }
-    bool isCtrlDep() const { return Node->Preds[Operand].isCtrl; }
-    bool isSpecialDep() const { return Node->Preds[Operand].isSpecial; }
-  };
-
-  template <> struct GraphTraits<SUnit*> {
-    typedef SUnit NodeType;
-    typedef SUnitIterator ChildIteratorType;
-    static inline NodeType *getEntryNode(SUnit *N) { return N; }
-    static inline ChildIteratorType child_begin(NodeType *N) {
-      return SUnitIterator::begin(N);
-    }
-    static inline ChildIteratorType child_end(NodeType *N) {
-      return SUnitIterator::end(N);
-    }
-  };
-
-  template <> struct GraphTraits<ScheduleDAG*> : public GraphTraits<SUnit*> {
-    typedef std::vector<SUnit>::iterator nodes_iterator;
-    static nodes_iterator nodes_begin(ScheduleDAG *G) {
-      return G->SUnits.begin();
-    }
-    static nodes_iterator nodes_end(ScheduleDAG *G) {
-      return G->SUnits.end();
-    }
-  };
 }
 
 #endif

Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=59676&r1=59675&r2=59676&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/CMakeLists.txt (original)
+++ llvm/trunk/lib/CodeGen/CMakeLists.txt Wed Nov 19 17:18:57 2008
@@ -8,6 +8,7 @@
   IfConversion.cpp
   IntrinsicLowering.cpp
   LLVMTargetMachine.cpp
+  LatencyPriorityQueue.cpp
   LiveInterval.cpp
   LiveIntervalAnalysis.cpp
   LiveStackAnalysis.cpp
@@ -40,6 +41,10 @@
   RegAllocSimple.cpp
   RegisterCoalescer.cpp
   RegisterScavenging.cpp
+  ScheduleDAG.cpp
+  ScheduleDAGEmit.cpp
+  ScheduleDAGInstrs.cpp
+  ScheduleDAGPrinter.cpp
   ShadowStackGC.cpp
   SimpleRegisterCoalescing.cpp
   StackProtector.cpp

Copied: llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp (from r59477, llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp?p2=llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp&p1=llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp&r1=59477&r2=59676&rev=59676&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp (original)
+++ llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp Wed Nov 19 17:18:57 2008
@@ -14,7 +14,7 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "scheduler"
-#include "LatencyPriorityQueue.h"
+#include "llvm/CodeGen/LatencyPriorityQueue.h"
 #include "llvm/Support/Debug.h"
 using namespace llvm;
 

Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=59676&r1=59675&r2=59676&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original)
+++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Wed Nov 19 17:18:57 2008
@@ -20,16 +20,22 @@
 
 #define DEBUG_TYPE "post-RA-sched"
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/ScheduleDAGInstrs.h"
+#include "llvm/CodeGen/LatencyPriorityQueue.h"
+#include "llvm/CodeGen/SchedulerRegistry.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/ADT/Statistic.h"
 using namespace llvm;
 
+STATISTIC(NumStalls, "Number of pipeline stalls");
+
 namespace {
-  class VISIBILITY_HIDDEN SchedulePostRATDList : public MachineFunctionPass {
+  class VISIBILITY_HIDDEN PostRAScheduler : public MachineFunctionPass {
   public:
     static char ID;
-    SchedulePostRATDList() : MachineFunctionPass(&ID) {}
+    PostRAScheduler() : MachineFunctionPass(&ID) {}
   private:
     MachineFunction *MF;
     const TargetMachine *TM;
@@ -40,27 +46,208 @@
 
     bool runOnMachineFunction(MachineFunction &Fn);
   };
-  char SchedulePostRATDList::ID = 0;
+  char PostRAScheduler::ID = 0;
+
+  class VISIBILITY_HIDDEN SchedulePostRATDList : public ScheduleDAGInstrs {
+  public:
+    SchedulePostRATDList(MachineBasicBlock *mbb, const TargetMachine &tm)
+      : ScheduleDAGInstrs(mbb, tm) {}
+  private:
+    MachineFunction *MF;
+    const TargetMachine *TM;
+
+    /// AvailableQueue - The priority queue to use for the available SUnits.
+    ///
+    LatencyPriorityQueue AvailableQueue;
+  
+    /// PendingQueue - This contains all of the instructions whose operands have
+    /// been issued, but their results are not ready yet (due to the latency of
+    /// the operation).  Once the operands becomes available, the instruction is
+    /// added to the AvailableQueue.
+    std::vector<SUnit*> PendingQueue;
+
+  public:
+    const char *getPassName() const {
+      return "Post RA top-down list latency scheduler (STUB)";
+    }
+
+    bool runOnMachineFunction(MachineFunction &Fn);
+
+    void Schedule();
+
+  private:
+    void ReleaseSucc(SUnit *SU, SUnit *SuccSU, bool isChain);
+    void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle);
+    void ListScheduleTopDown();
+  };
 }
 
-bool SchedulePostRATDList::runOnMachineFunction(MachineFunction &Fn) {
-  DOUT << "SchedulePostRATDList\n";
+bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) {
+  DOUT << "PostRAScheduler\n";
   MF = &Fn;
   TM = &MF->getTarget();
 
   // Loop over all of the basic blocks
   for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();
-       MBB != MBBe; ++MBB)
-    ;
+       MBB != MBBe; ++MBB) {
+
+    SchedulePostRATDList Scheduler(MBB, *TM);
+
+    Scheduler.Run();
+
+    Scheduler.EmitSchedule();
+  }
 
   return true;
 }
   
+/// Schedule - Schedule the DAG using list scheduling.
+void SchedulePostRATDList::Schedule() {
+  DOUT << "********** List Scheduling **********\n";
+  
+  // Build scheduling units.
+  BuildSchedUnits();
+
+  AvailableQueue.initNodes(SUnits);
+  
+  ListScheduleTopDown();
+  
+  AvailableQueue.releaseState();
+}
+
+//===----------------------------------------------------------------------===//
+//  Top-Down Scheduling
+//===----------------------------------------------------------------------===//
+
+/// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to
+/// the PendingQueue if the count reaches zero. Also update its cycle bound.
+void SchedulePostRATDList::ReleaseSucc(SUnit *SU, SUnit *SuccSU, bool isChain) {
+  --SuccSU->NumPredsLeft;
+  
+#ifndef NDEBUG
+  if (SuccSU->NumPredsLeft < 0) {
+    cerr << "*** Scheduling failed! ***\n";
+    SuccSU->dump(this);
+    cerr << " has been released too many times!\n";
+    assert(0);
+  }
+#endif
+  
+  // Compute how many cycles it will be before this actually becomes
+  // available.  This is the max of the start time of all predecessors plus
+  // their latencies.
+  // If this is a token edge, we don't need to wait for the latency of the
+  // preceeding instruction (e.g. a long-latency load) unless there is also
+  // some other data dependence.
+  unsigned PredDoneCycle = SU->Cycle;
+  if (!isChain)
+    PredDoneCycle += SU->Latency;
+  else if (SU->Latency)
+    PredDoneCycle += 1;
+  SuccSU->CycleBound = std::max(SuccSU->CycleBound, PredDoneCycle);
+  
+  if (SuccSU->NumPredsLeft == 0) {
+    PendingQueue.push_back(SuccSU);
+  }
+}
+
+/// ScheduleNodeTopDown - Add the node to the schedule. Decrement the pending
+/// count of its successors. If a successor pending count is zero, add it to
+/// the Available queue.
+void SchedulePostRATDList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) {
+  DOUT << "*** Scheduling [" << CurCycle << "]: ";
+  DEBUG(SU->dump(this));
+  
+  Sequence.push_back(SU);
+  SU->Cycle = CurCycle;
+
+  // Top down: release successors.
+  for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
+       I != E; ++I)
+    ReleaseSucc(SU, I->Dep, I->isCtrl);
+
+  SU->isScheduled = true;
+  AvailableQueue.ScheduledNode(SU);
+}
+
+/// ListScheduleTopDown - The main loop of list scheduling for top-down
+/// schedulers.
+void SchedulePostRATDList::ListScheduleTopDown() {
+  unsigned CurCycle = 0;
+
+  // All leaves to Available queue.
+  for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
+    // It is available if it has no predecessors.
+    if (SUnits[i].Preds.empty()) {
+      AvailableQueue.push(&SUnits[i]);
+      SUnits[i].isAvailable = true;
+    }
+  }
+  
+  // While Available queue is not empty, grab the node with the highest
+  // priority. If it is not ready put it back.  Schedule the node.
+  Sequence.reserve(SUnits.size());
+  while (!AvailableQueue.empty() || !PendingQueue.empty()) {
+    // Check to see if any of the pending instructions are ready to issue.  If
+    // so, add them to the available queue.
+    for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) {
+      if (PendingQueue[i]->CycleBound == CurCycle) {
+        AvailableQueue.push(PendingQueue[i]);
+        PendingQueue[i]->isAvailable = true;
+        PendingQueue[i] = PendingQueue.back();
+        PendingQueue.pop_back();
+        --i; --e;
+      } else {
+        assert(PendingQueue[i]->CycleBound > CurCycle && "Negative latency?");
+      }
+    }
+    
+    // If there are no instructions available, don't try to issue anything, and
+    // don't advance the hazard recognizer.
+    if (AvailableQueue.empty()) {
+      ++CurCycle;
+      continue;
+    }
+
+    SUnit *FoundSUnit = AvailableQueue.pop();
+    
+    // If we found a node to schedule, do it now.
+    if (FoundSUnit) {
+      ScheduleNodeTopDown(FoundSUnit, CurCycle);
+
+      // If this is a pseudo-op node, we don't want to increment the current
+      // cycle.
+      if (FoundSUnit->Latency)  // Don't increment CurCycle for pseudo-ops!
+        ++CurCycle;        
+    } else {
+      // Otherwise, we have a pipeline stall, but no other problem, just advance
+      // the current cycle and try again.
+      DOUT << "*** Advancing cycle, no work to do\n";
+      ++NumStalls;
+      ++CurCycle;
+    }
+  }
+
+#ifndef NDEBUG
+  // Verify that all SUnits were scheduled.
+  bool AnyNotSched = false;
+  for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
+    if (SUnits[i].NumPredsLeft != 0) {
+      if (!AnyNotSched)
+        cerr << "*** List scheduling failed! ***\n";
+      SUnits[i].dump(this);
+      cerr << "has not been scheduled!\n";
+      AnyNotSched = true;
+    }
+  }
+  assert(!AnyNotSched);
+#endif
+}
 
 //===----------------------------------------------------------------------===//
 //                         Public Constructor Functions
 //===----------------------------------------------------------------------===//
 
 FunctionPass *llvm::createPostRAScheduler() {
-  return new SchedulePostRATDList();
+  return new PostRAScheduler();
 }

Copied: llvm/trunk/lib/CodeGen/ScheduleDAG.cpp (from r59324, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAG.cpp?p2=llvm/trunk/lib/CodeGen/ScheduleDAG.cpp&p1=llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp&r1=59324&r2=59676&rev=59676&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/ScheduleDAG.cpp Wed Nov 19 17:18:57 2008
@@ -30,267 +30,7 @@
   ConstPool = MF->getConstantPool();
 }
 
-/// CheckForPhysRegDependency - Check if the dependency between def and use of
-/// a specified operand is a physical register dependency. If so, returns the
-/// register and the cost of copying the register.
-static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
-                                      const TargetRegisterInfo *TRI, 
-                                      const TargetInstrInfo *TII,
-                                      unsigned &PhysReg, int &Cost) {
-  if (Op != 2 || User->getOpcode() != ISD::CopyToReg)
-    return;
-
-  unsigned Reg = cast<RegisterSDNode>(User->getOperand(1))->getReg();
-  if (TargetRegisterInfo::isVirtualRegister(Reg))
-    return;
-
-  unsigned ResNo = User->getOperand(2).getResNo();
-  if (Def->isMachineOpcode()) {
-    const TargetInstrDesc &II = TII->get(Def->getMachineOpcode());
-    if (ResNo >= II.getNumDefs() &&
-        II.ImplicitDefs[ResNo - II.getNumDefs()] == Reg) {
-      PhysReg = Reg;
-      const TargetRegisterClass *RC =
-        TRI->getPhysicalRegisterRegClass(Reg, Def->getValueType(ResNo));
-      Cost = RC->getCopyCost();
-    }
-  }
-}
-
-SUnit *ScheduleDAG::Clone(SUnit *Old) {
-  SUnit *SU = NewSUnit(Old->getNode());
-  SU->OrigNode = Old->OrigNode;
-  SU->Latency = Old->Latency;
-  SU->isTwoAddress = Old->isTwoAddress;
-  SU->isCommutable = Old->isCommutable;
-  SU->hasPhysRegDefs = Old->hasPhysRegDefs;
-  return SU;
-}
-
-
-/// BuildSchedUnits - Build SUnits from the selection dag that we are input.
-/// This SUnit graph is similar to the SelectionDAG, but represents flagged
-/// together nodes with a single SUnit.
-void ScheduleDAG::BuildSchedUnits() {
-  // For post-regalloc scheduling, build the SUnits from the MachineInstrs
-  // in the MachineBasicBlock.
-  if (!DAG) {
-    BuildSchedUnitsFromMBB();
-    return;
-  }
-
-  // Reserve entries in the vector for each of the SUnits we are creating.  This
-  // ensure that reallocation of the vector won't happen, so SUnit*'s won't get
-  // invalidated.
-  SUnits.reserve(DAG->allnodes_size());
-  
-  // During scheduling, the NodeId field of SDNode is used to map SDNodes
-  // to their associated SUnits by holding SUnits table indices. A value
-  // of -1 means the SDNode does not yet have an associated SUnit.
-  for (SelectionDAG::allnodes_iterator NI = DAG->allnodes_begin(),
-       E = DAG->allnodes_end(); NI != E; ++NI)
-    NI->setNodeId(-1);
-
-  for (SelectionDAG::allnodes_iterator NI = DAG->allnodes_begin(),
-       E = DAG->allnodes_end(); NI != E; ++NI) {
-    if (isPassiveNode(NI))  // Leaf node, e.g. a TargetImmediate.
-      continue;
-    
-    // If this node has already been processed, stop now.
-    if (NI->getNodeId() != -1) continue;
-    
-    SUnit *NodeSUnit = NewSUnit(NI);
-    
-    // See if anything is flagged to this node, if so, add them to flagged
-    // nodes.  Nodes can have at most one flag input and one flag output.  Flags
-    // are required the be the last operand and result of a node.
-    
-    // Scan up to find flagged preds.
-    SDNode *N = NI;
-    if (N->getNumOperands() &&
-        N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) {
-      do {
-        N = N->getOperand(N->getNumOperands()-1).getNode();
-        assert(N->getNodeId() == -1 && "Node already inserted!");
-        N->setNodeId(NodeSUnit->NodeNum);
-      } while (N->getNumOperands() &&
-               N->getOperand(N->getNumOperands()-1).getValueType()== MVT::Flag);
-    }
-    
-    // Scan down to find any flagged succs.
-    N = NI;
-    while (N->getValueType(N->getNumValues()-1) == MVT::Flag) {
-      SDValue FlagVal(N, N->getNumValues()-1);
-      
-      // There are either zero or one users of the Flag result.
-      bool HasFlagUse = false;
-      for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); 
-           UI != E; ++UI)
-        if (FlagVal.isOperandOf(*UI)) {
-          HasFlagUse = true;
-          assert(N->getNodeId() == -1 && "Node already inserted!");
-          N->setNodeId(NodeSUnit->NodeNum);
-          N = *UI;
-          break;
-        }
-      if (!HasFlagUse) break;
-    }
-    
-    // If there are flag operands involved, N is now the bottom-most node
-    // of the sequence of nodes that are flagged together.
-    // Update the SUnit.
-    NodeSUnit->setNode(N);
-    assert(N->getNodeId() == -1 && "Node already inserted!");
-    N->setNodeId(NodeSUnit->NodeNum);
-
-    ComputeLatency(NodeSUnit);
-  }
-  
-  // Pass 2: add the preds, succs, etc.
-  for (unsigned su = 0, e = SUnits.size(); su != e; ++su) {
-    SUnit *SU = &SUnits[su];
-    SDNode *MainNode = SU->getNode();
-    
-    if (MainNode->isMachineOpcode()) {
-      unsigned Opc = MainNode->getMachineOpcode();
-      const TargetInstrDesc &TID = TII->get(Opc);
-      for (unsigned i = 0; i != TID.getNumOperands(); ++i) {
-        if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) {
-          SU->isTwoAddress = true;
-          break;
-        }
-      }
-      if (TID.isCommutable())
-        SU->isCommutable = true;
-    }
-    
-    // Find all predecessors and successors of the group.
-    for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) {
-      if (N->isMachineOpcode() &&
-          TII->get(N->getMachineOpcode()).getImplicitDefs() &&
-          CountResults(N) > TII->get(N->getMachineOpcode()).getNumDefs())
-        SU->hasPhysRegDefs = true;
-      
-      for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
-        SDNode *OpN = N->getOperand(i).getNode();
-        if (isPassiveNode(OpN)) continue;   // Not scheduled.
-        SUnit *OpSU = &SUnits[OpN->getNodeId()];
-        assert(OpSU && "Node has no SUnit!");
-        if (OpSU == SU) continue;           // In the same group.
-
-        MVT OpVT = N->getOperand(i).getValueType();
-        assert(OpVT != MVT::Flag && "Flagged nodes should be in same sunit!");
-        bool isChain = OpVT == MVT::Other;
-
-        unsigned PhysReg = 0;
-        int Cost = 1;
-        // Determine if this is a physical register dependency.
-        CheckForPhysRegDependency(OpN, N, i, TRI, TII, PhysReg, Cost);
-        SU->addPred(OpSU, isChain, false, PhysReg, Cost);
-      }
-    }
-  }
-}
-
-void ScheduleDAG::BuildSchedUnitsFromMBB() {
-  SUnits.clear();
-  SUnits.reserve(BB->size());
-
-  std::vector<SUnit *> PendingLoads;
-  SUnit *Terminator = 0;
-  SUnit *Chain = 0;
-  SUnit *Defs[TargetRegisterInfo::FirstVirtualRegister] = {};
-  std::vector<SUnit *> Uses[TargetRegisterInfo::FirstVirtualRegister] = {};
-  int Cost = 1; // FIXME
-
-  for (MachineBasicBlock::iterator MII = BB->end(), MIE = BB->begin();
-       MII != MIE; --MII) {
-    MachineInstr *MI = prior(MII);
-    SUnit *SU = NewSUnit(MI);
-
-    for (unsigned j = 0, n = MI->getNumOperands(); j != n; ++j) {
-      const MachineOperand &MO = MI->getOperand(j);
-      if (!MO.isReg()) continue;
-      unsigned Reg = MO.getReg();
-      if (Reg == 0) continue;
-
-      assert(TRI->isPhysicalRegister(Reg) && "Virtual register encountered!");
-      std::vector<SUnit *> &UseList = Uses[Reg];
-      SUnit *&Def = Defs[Reg];
-      // Optionally add output and anti dependences
-      if (Def && Def != SU)
-        Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false,
-                     /*PhyReg=*/Reg, Cost);
-      for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
-        SUnit *&Def = Defs[*Alias];
-        if (Def && Def != SU)
-          Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false,
-                       /*PhyReg=*/*Alias, Cost);
-      }
-
-      if (MO.isDef()) {
-        // Add any data dependencies.
-        for (unsigned i = 0, e = UseList.size(); i != e; ++i)
-          if (UseList[i] != SU)
-            UseList[i]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false,
-                                /*PhysReg=*/Reg, Cost);
-        for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
-          std::vector<SUnit *> &UseList = Uses[*Alias];
-          for (unsigned i = 0, e = UseList.size(); i != e; ++i)
-            if (UseList[i] != SU)
-              UseList[i]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false,
-                                  /*PhysReg=*/*Alias, Cost);
-        }
-
-        UseList.clear();
-        Def = SU;
-      } else {
-        UseList.push_back(SU);
-      }
-    }
-    bool False = false;
-    bool True = true;
-    if (!MI->isSafeToMove(TII, False)) {
-      if (Chain)
-        Chain->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false);
-      for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k)
-        PendingLoads[k]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false);
-      PendingLoads.clear();
-      Chain = SU;
-    } else if (!MI->isSafeToMove(TII, True)) {
-      if (Chain)
-        Chain->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false);
-      PendingLoads.push_back(SU);
-    }
-    if (Terminator && SU->Succs.empty())
-      Terminator->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false);
-    if (MI->getDesc().isTerminator())
-      Terminator = SU;
-  }
-}
-
-void ScheduleDAG::ComputeLatency(SUnit *SU) {
-  const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
-  
-  // Compute the latency for the node.  We use the sum of the latencies for
-  // all nodes flagged together into this SUnit.
-  if (InstrItins.isEmpty()) {
-    // No latency information.
-    SU->Latency = 1;
-    return;
-  }
-
-  SU->Latency = 0;
-  for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) {
-    if (N->isMachineOpcode()) {
-      unsigned SchedClass = TII->get(N->getMachineOpcode()).getSchedClass();
-      const InstrStage *S = InstrItins.begin(SchedClass);
-      const InstrStage *E = InstrItins.end(SchedClass);
-      for (; S != E; ++S)
-        SU->Latency += S->Cycles;
-    }
-  }
-}
+ScheduleDAG::~ScheduleDAG() {}
 
 /// CalculateDepths - compute depths using algorithms for the longest
 /// paths in the DAG
@@ -401,46 +141,11 @@
   }
 }
 
-/// 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 resulting MachineInstr).
-unsigned ScheduleDAG::CountResults(SDNode *Node) {
-  unsigned N = Node->getNumValues();
-  while (N && Node->getValueType(N - 1) == MVT::Flag)
-    --N;
-  if (N && Node->getValueType(N - 1) == MVT::Other)
-    --N;    // Skip over chain result.
-  return N;
-}
-
-/// CountOperands - The inputs to target nodes have any actual inputs first,
-/// followed by special operands that describe memory references, then an
-/// optional chain operand, then an optional flag operand.  Compute the number
-/// of actual operands that will go into the resulting MachineInstr.
-unsigned ScheduleDAG::CountOperands(SDNode *Node) {
-  unsigned N = ComputeMemOperandsEnd(Node);
-  while (N && isa<MemOperandSDNode>(Node->getOperand(N - 1).getNode()))
-    --N; // Ignore MEMOPERAND nodes
-  return N;
-}
-
-/// ComputeMemOperandsEnd - Find the index one past the last MemOperandSDNode
-/// operand
-unsigned ScheduleDAG::ComputeMemOperandsEnd(SDNode *Node) {
-  unsigned N = Node->getNumOperands();
-  while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag)
-    --N;
-  if (N && Node->getOperand(N - 1).getValueType() == MVT::Other)
-    --N; // Ignore chain if it exists.
-  return N;
-}
-
-
 /// dump - dump the schedule.
 void ScheduleDAG::dumpSchedule() const {
   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
     if (SUnit *SU = Sequence[i])
-      SU->dump(DAG);
+      SU->dump(this);
     else
       cerr << "**** NOOP ****\n";
   }
@@ -459,25 +164,12 @@
 
 /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
 /// a group of nodes flagged together.
-void SUnit::dump(const SelectionDAG *G) const {
+void SUnit::dump(const ScheduleDAG *G) const {
   cerr << "SU(" << NodeNum << "): ";
-  if (getNode())
-    getNode()->dump(G);
-  else
-    cerr << "CROSS RC COPY ";
-  cerr << "\n";
-  SmallVector<SDNode *, 4> FlaggedNodes;
-  for (SDNode *N = getNode()->getFlaggedNode(); N; N = N->getFlaggedNode())
-    FlaggedNodes.push_back(N);
-  while (!FlaggedNodes.empty()) {
-    cerr << "    ";
-    FlaggedNodes.back()->dump(G);
-    cerr << "\n";
-    FlaggedNodes.pop_back();
-  }
+  G->dumpNode(this);
 }
 
-void SUnit::dumpAll(const SelectionDAG *G) const {
+void SUnit::dumpAll(const ScheduleDAG *G) const {
   dump(G);
 
   cerr << "  # preds left       : " << NumPredsLeft << "\n";

Copied: llvm/trunk/lib/CodeGen/ScheduleDAGEmit.cpp (from r59282, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGEmit.cpp?p2=llvm/trunk/lib/CodeGen/ScheduleDAGEmit.cpp&p1=llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp&r1=59282&r2=59676&rev=59676&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp (original)
+++ llvm/trunk/lib/CodeGen/ScheduleDAGEmit.cpp Wed Nov 19 17:18:57 2008
@@ -28,612 +28,10 @@
 #include "llvm/Support/MathExtras.h"
 using namespace llvm;
 
-STATISTIC(NumCommutes,   "Number of instructions commuted");
-
-/// getInstrOperandRegClass - Return register class of the operand of an
-/// instruction of the specified TargetInstrDesc.
-static const TargetRegisterClass*
-getInstrOperandRegClass(const TargetRegisterInfo *TRI, 
-                        const TargetInstrInfo *TII, const TargetInstrDesc &II,
-                        unsigned Op) {
-  if (Op >= II.getNumOperands()) {
-    assert(II.isVariadic() && "Invalid operand # of instruction");
-    return NULL;
-  }
-  if (II.OpInfo[Op].isLookupPtrRegClass())
-    return TII->getPointerRegClass();
-  return TRI->getRegClass(II.OpInfo[Op].RegClass);
-}
-
-/// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
-/// implicit physical register output.
-void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
-                                  bool IsClone, unsigned SrcReg,
-                                  DenseMap<SDValue, unsigned> &VRBaseMap) {
-  unsigned VRBase = 0;
-  if (TargetRegisterInfo::isVirtualRegister(SrcReg)) {
-    // Just use the input register directly!
-    SDValue Op(Node, ResNo);
-    if (IsClone)
-      VRBaseMap.erase(Op);
-    bool isNew = VRBaseMap.insert(std::make_pair(Op, SrcReg)).second;
-    isNew = isNew; // Silence compiler warning.
-    assert(isNew && "Node emitted out of order - early");
-    return;
-  }
-
-  // If the node is only used by a CopyToReg and the dest reg is a vreg, use
-  // the CopyToReg'd destination register instead of creating a new vreg.
-  bool MatchReg = true;
-  const TargetRegisterClass *UseRC = NULL;
-  for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
-       UI != E; ++UI) {
-    SDNode *User = *UI;
-    bool Match = true;
-    if (User->getOpcode() == ISD::CopyToReg && 
-        User->getOperand(2).getNode() == Node &&
-        User->getOperand(2).getResNo() == ResNo) {
-      unsigned DestReg = cast<RegisterSDNode>(User->getOperand(1))->getReg();
-      if (TargetRegisterInfo::isVirtualRegister(DestReg)) {
-        VRBase = DestReg;
-        Match = false;
-      } else if (DestReg != SrcReg)
-        Match = false;
-    } else {
-      for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) {
-        SDValue Op = User->getOperand(i);
-        if (Op.getNode() != Node || Op.getResNo() != ResNo)
-          continue;
-        MVT VT = Node->getValueType(Op.getResNo());
-        if (VT == MVT::Other || VT == MVT::Flag)
-          continue;
-        Match = false;
-        if (User->isMachineOpcode()) {
-          const TargetInstrDesc &II = TII->get(User->getMachineOpcode());
-          const TargetRegisterClass *RC =
-            getInstrOperandRegClass(TRI,TII,II,i+II.getNumDefs());
-          if (!UseRC)
-            UseRC = RC;
-          else if (RC)
-            assert(UseRC == RC &&
-                   "Multiple uses expecting different register classes!");
-        }
-      }
-    }
-    MatchReg &= Match;
-    if (VRBase)
-      break;
-  }
-
-  MVT VT = Node->getValueType(ResNo);
-  const TargetRegisterClass *SrcRC = 0, *DstRC = 0;
-  SrcRC = TRI->getPhysicalRegisterRegClass(SrcReg, VT);
-  
-  // Figure out the register class to create for the destreg.
-  if (VRBase) {
-    DstRC = MRI.getRegClass(VRBase);
-  } else if (UseRC) {
-    assert(UseRC->hasType(VT) && "Incompatible phys register def and uses!");
-    DstRC = UseRC;
-  } else {
-    DstRC = TLI->getRegClassFor(VT);
-  }
-    
-  // If all uses are reading from the src physical register and copying the
-  // register is either impossible or very expensive, then don't create a copy.
-  if (MatchReg && SrcRC->getCopyCost() < 0) {
-    VRBase = SrcReg;
-  } else {
-    // Create the reg, emit the copy.
-    VRBase = MRI.createVirtualRegister(DstRC);
-    bool Emitted =
-      TII->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, DstRC, SrcRC);
-    Emitted = Emitted; // Silence compiler warning.
-    assert(Emitted && "Unable to issue a copy instruction!");
-  }
-
-  SDValue Op(Node, ResNo);
-  if (IsClone)
-    VRBaseMap.erase(Op);
-  bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second;
-  isNew = isNew; // Silence compiler warning.
-  assert(isNew && "Node emitted out of order - early");
-}
-
-/// getDstOfCopyToRegUse - If the only use of the specified result number of
-/// node is a CopyToReg, return its destination register. Return 0 otherwise.
-unsigned ScheduleDAG::getDstOfOnlyCopyToRegUse(SDNode *Node,
-                                               unsigned ResNo) const {
-  if (!Node->hasOneUse())
-    return 0;
-
-  SDNode *User = *Node->use_begin();
-  if (User->getOpcode() == ISD::CopyToReg && 
-      User->getOperand(2).getNode() == Node &&
-      User->getOperand(2).getResNo() == ResNo) {
-    unsigned Reg = cast<RegisterSDNode>(User->getOperand(1))->getReg();
-    if (TargetRegisterInfo::isVirtualRegister(Reg))
-      return Reg;
-  }
-  return 0;
-}
-
-void ScheduleDAG::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
-                                 const TargetInstrDesc &II,
-                                 DenseMap<SDValue, unsigned> &VRBaseMap) {
-  assert(Node->getMachineOpcode() != TargetInstrInfo::IMPLICIT_DEF &&
-         "IMPLICIT_DEF should have been handled as a special case elsewhere!");
-
-  for (unsigned i = 0; i < II.getNumDefs(); ++i) {
-    // If the specific node value is only used by a CopyToReg and the dest reg
-    // is a vreg, use the CopyToReg'd destination register instead of creating
-    // a new vreg.
-    unsigned VRBase = 0;
-    for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
-         UI != E; ++UI) {
-      SDNode *User = *UI;
-      if (User->getOpcode() == ISD::CopyToReg && 
-          User->getOperand(2).getNode() == Node &&
-          User->getOperand(2).getResNo() == i) {
-        unsigned Reg = cast<RegisterSDNode>(User->getOperand(1))->getReg();
-        if (TargetRegisterInfo::isVirtualRegister(Reg)) {
-          VRBase = Reg;
-          MI->addOperand(MachineOperand::CreateReg(Reg, true));
-          break;
-        }
-      }
-    }
-
-    // Create the result registers for this node and add the result regs to
-    // the machine instruction.
-    if (VRBase == 0) {
-      const TargetRegisterClass *RC = getInstrOperandRegClass(TRI, TII, II, i);
-      assert(RC && "Isn't a register operand!");
-      VRBase = MRI.createVirtualRegister(RC);
-      MI->addOperand(MachineOperand::CreateReg(VRBase, true));
-    }
-
-    SDValue Op(Node, i);
-    bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second;
-    isNew = isNew; // Silence compiler warning.
-    assert(isNew && "Node emitted out of order - early");
-  }
-}
-
-/// getVR - Return the virtual register corresponding to the specified result
-/// of the specified node.
-unsigned ScheduleDAG::getVR(SDValue Op,
-                            DenseMap<SDValue, unsigned> &VRBaseMap) {
-  if (Op.isMachineOpcode() &&
-      Op.getMachineOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
-    // Add an IMPLICIT_DEF instruction before every use.
-    unsigned VReg = getDstOfOnlyCopyToRegUse(Op.getNode(), Op.getResNo());
-    // IMPLICIT_DEF can produce any type of result so its TargetInstrDesc
-    // does not include operand register class info.
-    if (!VReg) {
-      const TargetRegisterClass *RC = TLI->getRegClassFor(Op.getValueType());
-      VReg = MRI.createVirtualRegister(RC);
-    }
-    BuildMI(BB, TII->get(TargetInstrInfo::IMPLICIT_DEF), VReg);
-    return VReg;
-  }
-
-  DenseMap<SDValue, unsigned>::iterator I = VRBaseMap.find(Op);
-  assert(I != VRBaseMap.end() && "Node emitted out of order - late");
-  return I->second;
-}
-
-
-/// AddOperand - Add the specified operand to the specified machine instr.  II
-/// specifies the instruction information for the node, and IIOpNum is the
-/// operand number (in the II) that we are adding. IIOpNum and II are used for 
-/// assertions only.
-void ScheduleDAG::AddOperand(MachineInstr *MI, SDValue Op,
-                             unsigned IIOpNum,
-                             const TargetInstrDesc *II,
-                             DenseMap<SDValue, unsigned> &VRBaseMap) {
-  if (Op.isMachineOpcode()) {
-    // Note that this case is redundant with the final else block, but we
-    // include it because it is the most common and it makes the logic
-    // simpler here.
-    assert(Op.getValueType() != MVT::Other &&
-           Op.getValueType() != MVT::Flag &&
-           "Chain and flag operands should occur at end of operand list!");
-    // Get/emit the operand.
-    unsigned VReg = getVR(Op, VRBaseMap);
-    const TargetInstrDesc &TID = MI->getDesc();
-    bool isOptDef = IIOpNum < TID.getNumOperands() &&
-      TID.OpInfo[IIOpNum].isOptionalDef();
-    MI->addOperand(MachineOperand::CreateReg(VReg, isOptDef));
-    
-    // Verify that it is right.
-    assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?");
-#ifndef NDEBUG
-    if (II) {
-      // There may be no register class for this operand if it is a variadic
-      // argument (RC will be NULL in this case).  In this case, we just assume
-      // the regclass is ok.
-      const TargetRegisterClass *RC =
-                          getInstrOperandRegClass(TRI, TII, *II, IIOpNum);
-      assert((RC || II->isVariadic()) && "Expected reg class info!");
-      const TargetRegisterClass *VRC = MRI.getRegClass(VReg);
-      if (RC && VRC != RC) {
-        cerr << "Register class of operand and regclass of use don't agree!\n";
-        cerr << "Operand = " << IIOpNum << "\n";
-        cerr << "Op->Val = "; Op.getNode()->dump(DAG); cerr << "\n";
-        cerr << "MI = "; MI->print(cerr);
-        cerr << "VReg = " << VReg << "\n";
-        cerr << "VReg RegClass     size = " << VRC->getSize()
-             << ", align = " << VRC->getAlignment() << "\n";
-        cerr << "Expected RegClass size = " << RC->getSize()
-             << ", align = " << RC->getAlignment() << "\n";
-        cerr << "Fatal error, aborting.\n";
-        abort();
-      }
-    }
-#endif
-  } else if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
-    MI->addOperand(MachineOperand::CreateImm(C->getZExtValue()));
-  } else if (ConstantFPSDNode *F = dyn_cast<ConstantFPSDNode>(Op)) {
-    const ConstantFP *CFP = F->getConstantFPValue();
-    MI->addOperand(MachineOperand::CreateFPImm(CFP));
-  } else if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(Op)) {
-    MI->addOperand(MachineOperand::CreateReg(R->getReg(), false));
-  } else if (GlobalAddressSDNode *TGA = dyn_cast<GlobalAddressSDNode>(Op)) {
-    MI->addOperand(MachineOperand::CreateGA(TGA->getGlobal(),TGA->getOffset()));
-  } else if (BasicBlockSDNode *BB = dyn_cast<BasicBlockSDNode>(Op)) {
-    MI->addOperand(MachineOperand::CreateMBB(BB->getBasicBlock()));
-  } else if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op)) {
-    MI->addOperand(MachineOperand::CreateFI(FI->getIndex()));
-  } else if (JumpTableSDNode *JT = dyn_cast<JumpTableSDNode>(Op)) {
-    MI->addOperand(MachineOperand::CreateJTI(JT->getIndex()));
-  } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op)) {
-    int Offset = CP->getOffset();
-    unsigned Align = CP->getAlignment();
-    const Type *Type = CP->getType();
-    // MachineConstantPool wants an explicit alignment.
-    if (Align == 0) {
-      Align = TM.getTargetData()->getPreferredTypeAlignmentShift(Type);
-      if (Align == 0) {
-        // Alignment of vector types.  FIXME!
-        Align = TM.getTargetData()->getABITypeSize(Type);
-        Align = Log2_64(Align);
-      }
-    }
-    
-    unsigned Idx;
-    if (CP->isMachineConstantPoolEntry())
-      Idx = ConstPool->getConstantPoolIndex(CP->getMachineCPVal(), Align);
-    else
-      Idx = ConstPool->getConstantPoolIndex(CP->getConstVal(), Align);
-    MI->addOperand(MachineOperand::CreateCPI(Idx, Offset));
-  } else if (ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op)) {
-    MI->addOperand(MachineOperand::CreateES(ES->getSymbol()));
-  } else {
-    assert(Op.getValueType() != MVT::Other &&
-           Op.getValueType() != MVT::Flag &&
-           "Chain and flag operands should occur at end of operand list!");
-    unsigned VReg = getVR(Op, VRBaseMap);
-    MI->addOperand(MachineOperand::CreateReg(VReg, false));
-    
-    // Verify that it is right.  Note that the reg class of the physreg and the
-    // vreg don't necessarily need to match, but the target copy insertion has
-    // to be able to handle it.  This handles things like copies from ST(0) to
-    // an FP vreg on x86.
-    assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?");
-    if (II && !II->isVariadic()) {
-      assert(getInstrOperandRegClass(TRI, TII, *II, IIOpNum) &&
-             "Don't have operand info for this instruction!");
-    }
-  }  
-}
-
 void ScheduleDAG::AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO) {
   MI->addMemOperand(*MF, MO);
 }
 
-/// getSubRegisterRegClass - Returns the register class of specified register
-/// class' "SubIdx"'th sub-register class.
-static const TargetRegisterClass*
-getSubRegisterRegClass(const TargetRegisterClass *TRC, unsigned SubIdx) {
-  // Pick the register class of the subregister
-  TargetRegisterInfo::regclass_iterator I =
-    TRC->subregclasses_begin() + SubIdx-1;
-  assert(I < TRC->subregclasses_end() && 
-         "Invalid subregister index for register class");
-  return *I;
-}
-
-/// getSuperRegisterRegClass - Returns the register class of a superreg A whose
-/// "SubIdx"'th sub-register class is the specified register class and whose
-/// type matches the specified type.
-static const TargetRegisterClass*
-getSuperRegisterRegClass(const TargetRegisterClass *TRC,
-                         unsigned SubIdx, MVT VT) {
-  // Pick the register class of the superegister for this type
-  for (TargetRegisterInfo::regclass_iterator I = TRC->superregclasses_begin(),
-         E = TRC->superregclasses_end(); I != E; ++I)
-    if ((*I)->hasType(VT) && getSubRegisterRegClass(*I, SubIdx) == TRC)
-      return *I;
-  assert(false && "Couldn't find the register class");
-  return 0;
-}
-
-/// EmitSubregNode - Generate machine code for subreg nodes.
-///
-void ScheduleDAG::EmitSubregNode(SDNode *Node, 
-                           DenseMap<SDValue, unsigned> &VRBaseMap) {
-  unsigned VRBase = 0;
-  unsigned Opc = Node->getMachineOpcode();
-  
-  // If the node is only used by a CopyToReg and the dest reg is a vreg, use
-  // the CopyToReg'd destination register instead of creating a new vreg.
-  for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
-       UI != E; ++UI) {
-    SDNode *User = *UI;
-    if (User->getOpcode() == ISD::CopyToReg && 
-        User->getOperand(2).getNode() == Node) {
-      unsigned DestReg = cast<RegisterSDNode>(User->getOperand(1))->getReg();
-      if (TargetRegisterInfo::isVirtualRegister(DestReg)) {
-        VRBase = DestReg;
-        break;
-      }
-    }
-  }
-  
-  if (Opc == TargetInstrInfo::EXTRACT_SUBREG) {
-    unsigned SubIdx = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
-
-    // Create the extract_subreg machine instruction.
-    MachineInstr *MI = BuildMI(*MF, TII->get(TargetInstrInfo::EXTRACT_SUBREG));
-
-    // Figure out the register class to create for the destreg.
-    unsigned VReg = getVR(Node->getOperand(0), VRBaseMap);
-    const TargetRegisterClass *TRC = MRI.getRegClass(VReg);
-    const TargetRegisterClass *SRC = getSubRegisterRegClass(TRC, SubIdx);
-
-    if (VRBase) {
-      // Grab the destination register
-#ifndef NDEBUG
-      const TargetRegisterClass *DRC = MRI.getRegClass(VRBase);
-      assert(SRC && DRC && SRC == DRC && 
-             "Source subregister and destination must have the same class");
-#endif
-    } else {
-      // Create the reg
-      assert(SRC && "Couldn't find source register class");
-      VRBase = MRI.createVirtualRegister(SRC);
-    }
-    
-    // Add def, source, and subreg index
-    MI->addOperand(MachineOperand::CreateReg(VRBase, true));
-    AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap);
-    MI->addOperand(MachineOperand::CreateImm(SubIdx));
-    BB->push_back(MI);    
-  } else if (Opc == TargetInstrInfo::INSERT_SUBREG ||
-             Opc == TargetInstrInfo::SUBREG_TO_REG) {
-    SDValue N0 = Node->getOperand(0);
-    SDValue N1 = Node->getOperand(1);
-    SDValue N2 = Node->getOperand(2);
-    unsigned SubReg = getVR(N1, VRBaseMap);
-    unsigned SubIdx = cast<ConstantSDNode>(N2)->getZExtValue();
-    
-      
-    // Figure out the register class to create for the destreg.
-    const TargetRegisterClass *TRC = 0;
-    if (VRBase) {
-      TRC = MRI.getRegClass(VRBase);
-    } else {
-      TRC = getSuperRegisterRegClass(MRI.getRegClass(SubReg), SubIdx, 
-                                     Node->getValueType(0));
-      assert(TRC && "Couldn't determine register class for insert_subreg");
-      VRBase = MRI.createVirtualRegister(TRC); // Create the reg
-    }
-    
-    // Create the insert_subreg or subreg_to_reg machine instruction.
-    MachineInstr *MI = BuildMI(*MF, TII->get(Opc));
-    MI->addOperand(MachineOperand::CreateReg(VRBase, true));
-    
-    // If creating a subreg_to_reg, then the first input operand
-    // is an implicit value immediate, otherwise it's a register
-    if (Opc == TargetInstrInfo::SUBREG_TO_REG) {
-      const ConstantSDNode *SD = cast<ConstantSDNode>(N0);
-      MI->addOperand(MachineOperand::CreateImm(SD->getZExtValue()));
-    } else
-      AddOperand(MI, N0, 0, 0, VRBaseMap);
-    // Add the subregster being inserted
-    AddOperand(MI, N1, 0, 0, VRBaseMap);
-    MI->addOperand(MachineOperand::CreateImm(SubIdx));
-    BB->push_back(MI);
-  } else
-    assert(0 && "Node is not insert_subreg, extract_subreg, or subreg_to_reg");
-     
-  SDValue Op(Node, 0);
-  bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second;
-  isNew = isNew; // Silence compiler warning.
-  assert(isNew && "Node emitted out of order - early");
-}
-
-/// EmitNode - Generate machine code for an node and needed dependencies.
-///
-void ScheduleDAG::EmitNode(SDNode *Node, bool IsClone,
-                           DenseMap<SDValue, unsigned> &VRBaseMap) {
-  // If machine instruction
-  if (Node->isMachineOpcode()) {
-    unsigned Opc = Node->getMachineOpcode();
-    
-    // Handle subreg insert/extract specially
-    if (Opc == TargetInstrInfo::EXTRACT_SUBREG || 
-        Opc == TargetInstrInfo::INSERT_SUBREG ||
-        Opc == TargetInstrInfo::SUBREG_TO_REG) {
-      EmitSubregNode(Node, VRBaseMap);
-      return;
-    }
-
-    if (Opc == TargetInstrInfo::IMPLICIT_DEF)
-      // We want a unique VR for each IMPLICIT_DEF use.
-      return;
-    
-    const TargetInstrDesc &II = TII->get(Opc);
-    unsigned NumResults = CountResults(Node);
-    unsigned NodeOperands = CountOperands(Node);
-    unsigned MemOperandsEnd = ComputeMemOperandsEnd(Node);
-    bool HasPhysRegOuts = (NumResults > II.getNumDefs()) &&
-                          II.getImplicitDefs() != 0;
-#ifndef NDEBUG
-    unsigned NumMIOperands = NodeOperands + NumResults;
-    assert((II.getNumOperands() == NumMIOperands ||
-            HasPhysRegOuts || II.isVariadic()) &&
-           "#operands for dag node doesn't match .td file!"); 
-#endif
-
-    // Create the new machine instruction.
-    MachineInstr *MI = BuildMI(*MF, II);
-    
-    // Add result register values for things that are defined by this
-    // instruction.
-    if (NumResults)
-      CreateVirtualRegisters(Node, MI, II, VRBaseMap);
-    
-    // Emit all of the actual operands of this instruction, adding them to the
-    // instruction as appropriate.
-    for (unsigned i = 0; i != NodeOperands; ++i)
-      AddOperand(MI, Node->getOperand(i), i+II.getNumDefs(), &II, VRBaseMap);
-
-    // Emit all of the memory operands of this instruction
-    for (unsigned i = NodeOperands; i != MemOperandsEnd; ++i)
-      AddMemOperand(MI, cast<MemOperandSDNode>(Node->getOperand(i))->MO);
-
-    // Commute node if it has been determined to be profitable.
-    if (CommuteSet.count(Node)) {
-      MachineInstr *NewMI = TII->commuteInstruction(MI);
-      if (NewMI == 0)
-        DOUT << "Sched: COMMUTING FAILED!\n";
-      else {
-        DOUT << "Sched: COMMUTED TO: " << *NewMI;
-        if (MI != NewMI) {
-          MF->DeleteMachineInstr(MI);
-          MI = NewMI;
-        }
-        ++NumCommutes;
-      }
-    }
-
-    if (II.usesCustomDAGSchedInsertionHook())
-      // Insert this instruction into the basic block using a target
-      // specific inserter which may returns a new basic block.
-      BB = TLI->EmitInstrWithCustomInserter(MI, BB);
-    else
-      BB->push_back(MI);
-
-    // Additional results must be an physical register def.
-    if (HasPhysRegOuts) {
-      for (unsigned i = II.getNumDefs(); i < NumResults; ++i) {
-        unsigned Reg = II.getImplicitDefs()[i - II.getNumDefs()];
-        if (Node->hasAnyUseOfValue(i))
-          EmitCopyFromReg(Node, i, IsClone, Reg, VRBaseMap);
-      }
-    }
-    return;
-  }
-
-  switch (Node->getOpcode()) {
-  default:
-#ifndef NDEBUG
-    Node->dump(DAG);
-#endif
-    assert(0 && "This target-independent node should have been selected!");
-    break;
-  case ISD::EntryToken:
-    assert(0 && "EntryToken should have been excluded from the schedule!");
-    break;
-  case ISD::TokenFactor: // fall thru
-    break;
-  case ISD::CopyToReg: {
-    unsigned SrcReg;
-    SDValue SrcVal = Node->getOperand(2);
-    if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(SrcVal))
-      SrcReg = R->getReg();
-    else
-      SrcReg = getVR(SrcVal, VRBaseMap);
-      
-    unsigned DestReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
-    if (SrcReg == DestReg) // Coalesced away the copy? Ignore.
-      break;
-      
-    const TargetRegisterClass *SrcTRC = 0, *DstTRC = 0;
-    // Get the register classes of the src/dst.
-    if (TargetRegisterInfo::isVirtualRegister(SrcReg))
-      SrcTRC = MRI.getRegClass(SrcReg);
-    else
-      SrcTRC = TRI->getPhysicalRegisterRegClass(SrcReg,SrcVal.getValueType());
-
-    if (TargetRegisterInfo::isVirtualRegister(DestReg))
-      DstTRC = MRI.getRegClass(DestReg);
-    else
-      DstTRC = TRI->getPhysicalRegisterRegClass(DestReg,
-                                            Node->getOperand(1).getValueType());
-    TII->copyRegToReg(*BB, BB->end(), DestReg, SrcReg, DstTRC, SrcTRC);
-    break;
-  }
-  case ISD::CopyFromReg: {
-    unsigned SrcReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
-    EmitCopyFromReg(Node, 0, IsClone, SrcReg, VRBaseMap);
-    break;
-  }
-  case ISD::INLINEASM: {
-    unsigned NumOps = Node->getNumOperands();
-    if (Node->getOperand(NumOps-1).getValueType() == MVT::Flag)
-      --NumOps;  // Ignore the flag operand.
-      
-    // Create the inline asm machine instruction.
-    MachineInstr *MI = BuildMI(*MF, TII->get(TargetInstrInfo::INLINEASM));
-
-    // Add the asm string as an external symbol operand.
-    const char *AsmStr =
-      cast<ExternalSymbolSDNode>(Node->getOperand(1))->getSymbol();
-    MI->addOperand(MachineOperand::CreateES(AsmStr));
-      
-    // Add all of the operand registers to the instruction.
-    for (unsigned i = 2; i != NumOps;) {
-      unsigned Flags =
-        cast<ConstantSDNode>(Node->getOperand(i))->getZExtValue();
-      unsigned NumVals = Flags >> 3;
-        
-      MI->addOperand(MachineOperand::CreateImm(Flags));
-      ++i;  // Skip the ID value.
-        
-      switch (Flags & 7) {
-      default: assert(0 && "Bad flags!");
-      case 2:   // Def of register.
-        for (; NumVals; --NumVals, ++i) {
-          unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
-          MI->addOperand(MachineOperand::CreateReg(Reg, true));
-        }
-        break;
-      case 6:   // Def of earlyclobber register.
-        for (; NumVals; --NumVals, ++i) {
-          unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
-          MI->addOperand(MachineOperand::CreateReg(Reg, true, false, false, 
-                                                   false, 0, true));
-        }
-        break;
-      case 1:  // Use of register.
-      case 3:  // Immediate.
-      case 4:  // Addressing mode.
-        // The addressing mode has been selected, just add all of the
-        // operands to the machine instruction.
-        for (; NumVals; --NumVals, ++i)
-          AddOperand(MI, Node->getOperand(i), 0, 0, VRBaseMap);
-        break;
-      }
-    }
-    BB->push_back(MI);
-    break;
-  }
-  }
-}
-
 void ScheduleDAG::EmitNoop() {
   TII->insertNoop(*BB, BB->end());
 }
@@ -643,7 +41,7 @@
   for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
        I != E; ++I) {
     if (I->isCtrl) continue;  // ignore chain preds
-    if (!I->Dep->getNode()) {
+    if (I->Dep->CopyDstRC) {
       // Copy to physical register.
       DenseMap<SUnit*, unsigned>::iterator VRI = VRBaseMap.find(I->Dep);
       assert(VRI != VRBaseMap.end() && "Node emitted out of order - late");
@@ -672,46 +70,3 @@
     break;
   }
 }
-
-/// EmitSchedule - Emit the machine code in scheduled order.
-MachineBasicBlock *ScheduleDAG::EmitSchedule() {
-  // For post-regalloc scheduling, we're rescheduling the instructions in the
-  // block, so start by removing them from the block.
-  if (!DAG)
-    while (!BB->empty())
-      BB->remove(BB->begin());
-
-  DenseMap<SDValue, unsigned> VRBaseMap;
-  DenseMap<SUnit*, unsigned> CopyVRBaseMap;
-  for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
-    SUnit *SU = Sequence[i];
-    if (!SU) {
-      // Null SUnit* is a noop.
-      EmitNoop();
-      continue;
-    }
-
-    // For post-regalloc scheduling, we already have the instruction;
-    // just append it to the block.
-    if (!DAG) {
-      BB->push_back(SU->getInstr());
-      continue;
-    }
-
-    // For pre-regalloc scheduling, create instructions corresponding to the
-    // SDNode and any flagged SDNodes and append them to the block.
-    SmallVector<SDNode *, 4> FlaggedNodes;
-    for (SDNode *N = SU->getNode()->getFlaggedNode(); N; N = N->getFlaggedNode())
-      FlaggedNodes.push_back(N);
-    while (!FlaggedNodes.empty()) {
-      EmitNode(FlaggedNodes.back(), SU->OrigNode != SU, VRBaseMap);
-      FlaggedNodes.pop_back();
-    }
-    if (!SU->getNode())
-      EmitCrossRCCopy(SU, CopyVRBaseMap);
-    else
-      EmitNode(SU->getNode(), SU->OrigNode != SU, VRBaseMap);
-  }
-
-  return BB;
-}

Copied: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (from r59324, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?p2=llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp&p1=llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp&r1=59324&r2=59676&rev=59676&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Wed Nov 19 17:18:57 2008
@@ -12,187 +12,20 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "pre-RA-sched"
-#include "llvm/CodeGen/ScheduleDAG.h"
+#define DEBUG_TYPE "sched-instrs"
+#include "llvm/CodeGen/ScheduleDAGInstrs.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
 using namespace llvm;
 
-ScheduleDAG::ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb,
-                         const TargetMachine &tm)
-  : DAG(dag), BB(bb), TM(tm), MRI(BB->getParent()->getRegInfo()) {
-  TII = TM.getInstrInfo();
-  MF  = BB->getParent();
-  TRI = TM.getRegisterInfo();
-  TLI = TM.getTargetLowering();
-  ConstPool = MF->getConstantPool();
-}
-
-/// CheckForPhysRegDependency - Check if the dependency between def and use of
-/// a specified operand is a physical register dependency. If so, returns the
-/// register and the cost of copying the register.
-static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
-                                      const TargetRegisterInfo *TRI, 
-                                      const TargetInstrInfo *TII,
-                                      unsigned &PhysReg, int &Cost) {
-  if (Op != 2 || User->getOpcode() != ISD::CopyToReg)
-    return;
-
-  unsigned Reg = cast<RegisterSDNode>(User->getOperand(1))->getReg();
-  if (TargetRegisterInfo::isVirtualRegister(Reg))
-    return;
-
-  unsigned ResNo = User->getOperand(2).getResNo();
-  if (Def->isMachineOpcode()) {
-    const TargetInstrDesc &II = TII->get(Def->getMachineOpcode());
-    if (ResNo >= II.getNumDefs() &&
-        II.ImplicitDefs[ResNo - II.getNumDefs()] == Reg) {
-      PhysReg = Reg;
-      const TargetRegisterClass *RC =
-        TRI->getPhysicalRegisterRegClass(Reg, Def->getValueType(ResNo));
-      Cost = RC->getCopyCost();
-    }
-  }
-}
-
-SUnit *ScheduleDAG::Clone(SUnit *Old) {
-  SUnit *SU = NewSUnit(Old->getNode());
-  SU->OrigNode = Old->OrigNode;
-  SU->Latency = Old->Latency;
-  SU->isTwoAddress = Old->isTwoAddress;
-  SU->isCommutable = Old->isCommutable;
-  SU->hasPhysRegDefs = Old->hasPhysRegDefs;
-  return SU;
-}
-
-
-/// BuildSchedUnits - Build SUnits from the selection dag that we are input.
-/// This SUnit graph is similar to the SelectionDAG, but represents flagged
-/// together nodes with a single SUnit.
-void ScheduleDAG::BuildSchedUnits() {
-  // For post-regalloc scheduling, build the SUnits from the MachineInstrs
-  // in the MachineBasicBlock.
-  if (!DAG) {
-    BuildSchedUnitsFromMBB();
-    return;
-  }
+ScheduleDAGInstrs::ScheduleDAGInstrs(MachineBasicBlock *bb,
+                                     const TargetMachine &tm)
+  : ScheduleDAG(0, bb, tm) {}
 
-  // Reserve entries in the vector for each of the SUnits we are creating.  This
-  // ensure that reallocation of the vector won't happen, so SUnit*'s won't get
-  // invalidated.
-  SUnits.reserve(DAG->allnodes_size());
-  
-  // During scheduling, the NodeId field of SDNode is used to map SDNodes
-  // to their associated SUnits by holding SUnits table indices. A value
-  // of -1 means the SDNode does not yet have an associated SUnit.
-  for (SelectionDAG::allnodes_iterator NI = DAG->allnodes_begin(),
-       E = DAG->allnodes_end(); NI != E; ++NI)
-    NI->setNodeId(-1);
-
-  for (SelectionDAG::allnodes_iterator NI = DAG->allnodes_begin(),
-       E = DAG->allnodes_end(); NI != E; ++NI) {
-    if (isPassiveNode(NI))  // Leaf node, e.g. a TargetImmediate.
-      continue;
-    
-    // If this node has already been processed, stop now.
-    if (NI->getNodeId() != -1) continue;
-    
-    SUnit *NodeSUnit = NewSUnit(NI);
-    
-    // See if anything is flagged to this node, if so, add them to flagged
-    // nodes.  Nodes can have at most one flag input and one flag output.  Flags
-    // are required the be the last operand and result of a node.
-    
-    // Scan up to find flagged preds.
-    SDNode *N = NI;
-    if (N->getNumOperands() &&
-        N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) {
-      do {
-        N = N->getOperand(N->getNumOperands()-1).getNode();
-        assert(N->getNodeId() == -1 && "Node already inserted!");
-        N->setNodeId(NodeSUnit->NodeNum);
-      } while (N->getNumOperands() &&
-               N->getOperand(N->getNumOperands()-1).getValueType()== MVT::Flag);
-    }
-    
-    // Scan down to find any flagged succs.
-    N = NI;
-    while (N->getValueType(N->getNumValues()-1) == MVT::Flag) {
-      SDValue FlagVal(N, N->getNumValues()-1);
-      
-      // There are either zero or one users of the Flag result.
-      bool HasFlagUse = false;
-      for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); 
-           UI != E; ++UI)
-        if (FlagVal.isOperandOf(*UI)) {
-          HasFlagUse = true;
-          assert(N->getNodeId() == -1 && "Node already inserted!");
-          N->setNodeId(NodeSUnit->NodeNum);
-          N = *UI;
-          break;
-        }
-      if (!HasFlagUse) break;
-    }
-    
-    // If there are flag operands involved, N is now the bottom-most node
-    // of the sequence of nodes that are flagged together.
-    // Update the SUnit.
-    NodeSUnit->setNode(N);
-    assert(N->getNodeId() == -1 && "Node already inserted!");
-    N->setNodeId(NodeSUnit->NodeNum);
-
-    ComputeLatency(NodeSUnit);
-  }
-  
-  // Pass 2: add the preds, succs, etc.
-  for (unsigned su = 0, e = SUnits.size(); su != e; ++su) {
-    SUnit *SU = &SUnits[su];
-    SDNode *MainNode = SU->getNode();
-    
-    if (MainNode->isMachineOpcode()) {
-      unsigned Opc = MainNode->getMachineOpcode();
-      const TargetInstrDesc &TID = TII->get(Opc);
-      for (unsigned i = 0; i != TID.getNumOperands(); ++i) {
-        if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) {
-          SU->isTwoAddress = true;
-          break;
-        }
-      }
-      if (TID.isCommutable())
-        SU->isCommutable = true;
-    }
-    
-    // Find all predecessors and successors of the group.
-    for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) {
-      if (N->isMachineOpcode() &&
-          TII->get(N->getMachineOpcode()).getImplicitDefs() &&
-          CountResults(N) > TII->get(N->getMachineOpcode()).getNumDefs())
-        SU->hasPhysRegDefs = true;
-      
-      for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
-        SDNode *OpN = N->getOperand(i).getNode();
-        if (isPassiveNode(OpN)) continue;   // Not scheduled.
-        SUnit *OpSU = &SUnits[OpN->getNodeId()];
-        assert(OpSU && "Node has no SUnit!");
-        if (OpSU == SU) continue;           // In the same group.
-
-        MVT OpVT = N->getOperand(i).getValueType();
-        assert(OpVT != MVT::Flag && "Flagged nodes should be in same sunit!");
-        bool isChain = OpVT == MVT::Other;
-
-        unsigned PhysReg = 0;
-        int Cost = 1;
-        // Determine if this is a physical register dependency.
-        CheckForPhysRegDependency(OpN, N, i, TRI, TII, PhysReg, Cost);
-        SU->addPred(OpSU, isChain, false, PhysReg, Cost);
-      }
-    }
-  }
-}
-
-void ScheduleDAG::BuildSchedUnitsFromMBB() {
+void ScheduleDAGInstrs::BuildSchedUnits() {
   SUnits.clear();
   SUnits.reserve(BB->size());
 
@@ -269,250 +102,34 @@
   }
 }
 
-void ScheduleDAG::ComputeLatency(SUnit *SU) {
-  const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
-  
-  // Compute the latency for the node.  We use the sum of the latencies for
-  // all nodes flagged together into this SUnit.
-  if (InstrItins.isEmpty()) {
-    // No latency information.
-    SU->Latency = 1;
-    return;
-  }
-
-  SU->Latency = 0;
-  for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) {
-    if (N->isMachineOpcode()) {
-      unsigned SchedClass = TII->get(N->getMachineOpcode()).getSchedClass();
-      const InstrStage *S = InstrItins.begin(SchedClass);
-      const InstrStage *E = InstrItins.end(SchedClass);
-      for (; S != E; ++S)
-        SU->Latency += S->Cycles;
-    }
-  }
+void ScheduleDAGInstrs::dumpNode(const SUnit *SU) const {
+  SU->getInstr()->dump();
 }
 
-/// CalculateDepths - compute depths using algorithms for the longest
-/// paths in the DAG
-void ScheduleDAG::CalculateDepths() {
-  unsigned DAGSize = SUnits.size();
-  std::vector<SUnit*> WorkList;
-  WorkList.reserve(DAGSize);
-
-  // Initialize the data structures
-  for (unsigned i = 0, e = DAGSize; i != e; ++i) {
-    SUnit *SU = &SUnits[i];
-    unsigned Degree = SU->Preds.size();
-    // Temporarily use the Depth field as scratch space for the degree count.
-    SU->Depth = Degree;
-
-    // Is it a node without dependencies?
-    if (Degree == 0) {
-        assert(SU->Preds.empty() && "SUnit should have no predecessors");
-        // Collect leaf nodes
-        WorkList.push_back(SU);
-    }
-  }
-
-  // Process nodes in the topological order
-  while (!WorkList.empty()) {
-    SUnit *SU = WorkList.back();
-    WorkList.pop_back();
-    unsigned SUDepth = 0;
-
-    // Use dynamic programming:
-    // When current node is being processed, all of its dependencies
-    // are already processed.
-    // So, just iterate over all predecessors and take the longest path
-    for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
-         I != E; ++I) {
-      unsigned PredDepth = I->Dep->Depth;
-      if (PredDepth+1 > SUDepth) {
-          SUDepth = PredDepth + 1;
-      }
-    }
+std::string ScheduleDAGInstrs::getGraphNodeLabel(const SUnit *SU) const {
+  std::string s;
+  raw_string_ostream oss(s);
+  SU->getInstr()->print(oss);
+  return oss.str();
+}
+
+// EmitSchedule - Emit the machine code in scheduled order.
+MachineBasicBlock *ScheduleDAGInstrs::EmitSchedule() {
+  // For MachineInstr-based scheduling, we're rescheduling the instructions in
+  // the block, so start by removing them from the block.
+  while (!BB->empty())
+    BB->remove(BB->begin());
 
-    SU->Depth = SUDepth;
-
-    // Update degrees of all nodes depending on current SUnit
-    for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
-         I != E; ++I) {
-      SUnit *SU = I->Dep;
-      if (!--SU->Depth)
-        // If all dependencies of the node are processed already,
-        // then the longest path for the node can be computed now
-        WorkList.push_back(SU);
-    }
-  }
-}
-
-/// CalculateHeights - compute heights using algorithms for the longest
-/// paths in the DAG
-void ScheduleDAG::CalculateHeights() {
-  unsigned DAGSize = SUnits.size();
-  std::vector<SUnit*> WorkList;
-  WorkList.reserve(DAGSize);
-
-  // Initialize the data structures
-  for (unsigned i = 0, e = DAGSize; i != e; ++i) {
-    SUnit *SU = &SUnits[i];
-    unsigned Degree = SU->Succs.size();
-    // Temporarily use the Height field as scratch space for the degree count.
-    SU->Height = Degree;
-
-    // Is it a node without dependencies?
-    if (Degree == 0) {
-        assert(SU->Succs.empty() && "Something wrong");
-        assert(WorkList.empty() && "Should be empty");
-        // Collect leaf nodes
-        WorkList.push_back(SU);
-    }
-  }
-
-  // Process nodes in the topological order
-  while (!WorkList.empty()) {
-    SUnit *SU = WorkList.back();
-    WorkList.pop_back();
-    unsigned SUHeight = 0;
-
-    // Use dynamic programming:
-    // When current node is being processed, all of its dependencies
-    // are already processed.
-    // So, just iterate over all successors and take the longest path
-    for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
-         I != E; ++I) {
-      unsigned SuccHeight = I->Dep->Height;
-      if (SuccHeight+1 > SUHeight) {
-          SUHeight = SuccHeight + 1;
-      }
-    }
-
-    SU->Height = SUHeight;
-
-    // Update degrees of all nodes depending on current SUnit
-    for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
-         I != E; ++I) {
-      SUnit *SU = I->Dep;
-      if (!--SU->Height)
-        // If all dependencies of the node are processed already,
-        // then the longest path for the node can be computed now
-        WorkList.push_back(SU);
-    }
-  }
-}
-
-/// 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 resulting MachineInstr).
-unsigned ScheduleDAG::CountResults(SDNode *Node) {
-  unsigned N = Node->getNumValues();
-  while (N && Node->getValueType(N - 1) == MVT::Flag)
-    --N;
-  if (N && Node->getValueType(N - 1) == MVT::Other)
-    --N;    // Skip over chain result.
-  return N;
-}
-
-/// CountOperands - The inputs to target nodes have any actual inputs first,
-/// followed by special operands that describe memory references, then an
-/// optional chain operand, then an optional flag operand.  Compute the number
-/// of actual operands that will go into the resulting MachineInstr.
-unsigned ScheduleDAG::CountOperands(SDNode *Node) {
-  unsigned N = ComputeMemOperandsEnd(Node);
-  while (N && isa<MemOperandSDNode>(Node->getOperand(N - 1).getNode()))
-    --N; // Ignore MEMOPERAND nodes
-  return N;
-}
-
-/// ComputeMemOperandsEnd - Find the index one past the last MemOperandSDNode
-/// operand
-unsigned ScheduleDAG::ComputeMemOperandsEnd(SDNode *Node) {
-  unsigned N = Node->getNumOperands();
-  while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag)
-    --N;
-  if (N && Node->getOperand(N - 1).getValueType() == MVT::Other)
-    --N; // Ignore chain if it exists.
-  return N;
-}
-
-
-/// dump - dump the schedule.
-void ScheduleDAG::dumpSchedule() const {
   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
-    if (SUnit *SU = Sequence[i])
-      SU->dump(DAG);
-    else
-      cerr << "**** NOOP ****\n";
-  }
-}
-
-
-/// Run - perform scheduling.
-///
-void ScheduleDAG::Run() {
-  Schedule();
-  
-  DOUT << "*** Final schedule ***\n";
-  DEBUG(dumpSchedule());
-  DOUT << "\n";
-}
+    SUnit *SU = Sequence[i];
+    if (!SU) {
+      // Null SUnit* is a noop.
+      EmitNoop();
+      continue;
+    }
 
-/// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
-/// a group of nodes flagged together.
-void SUnit::dump(const SelectionDAG *G) const {
-  cerr << "SU(" << NodeNum << "): ";
-  if (getNode())
-    getNode()->dump(G);
-  else
-    cerr << "CROSS RC COPY ";
-  cerr << "\n";
-  SmallVector<SDNode *, 4> FlaggedNodes;
-  for (SDNode *N = getNode()->getFlaggedNode(); N; N = N->getFlaggedNode())
-    FlaggedNodes.push_back(N);
-  while (!FlaggedNodes.empty()) {
-    cerr << "    ";
-    FlaggedNodes.back()->dump(G);
-    cerr << "\n";
-    FlaggedNodes.pop_back();
+    BB->push_back(SU->getInstr());
   }
-}
-
-void SUnit::dumpAll(const SelectionDAG *G) const {
-  dump(G);
 
-  cerr << "  # preds left       : " << NumPredsLeft << "\n";
-  cerr << "  # succs left       : " << NumSuccsLeft << "\n";
-  cerr << "  Latency            : " << Latency << "\n";
-  cerr << "  Depth              : " << Depth << "\n";
-  cerr << "  Height             : " << Height << "\n";
-
-  if (Preds.size() != 0) {
-    cerr << "  Predecessors:\n";
-    for (SUnit::const_succ_iterator I = Preds.begin(), E = Preds.end();
-         I != E; ++I) {
-      if (I->isCtrl)
-        cerr << "   ch  #";
-      else
-        cerr << "   val #";
-      cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")";
-      if (I->isSpecial)
-        cerr << " *";
-      cerr << "\n";
-    }
-  }
-  if (Succs.size() != 0) {
-    cerr << "  Successors:\n";
-    for (SUnit::const_succ_iterator I = Succs.begin(), E = Succs.end();
-         I != E; ++I) {
-      if (I->isCtrl)
-        cerr << "   ch  #";
-      else
-        cerr << "   val #";
-      cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")";
-      if (I->isSpecial)
-        cerr << " *";
-      cerr << "\n";
-    }
-  }
-  cerr << "\n";
+  return BB;
 }

Copied: llvm/trunk/lib/CodeGen/ScheduleDAGPrinter.cpp (from r59660, llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGPrinter.cpp?p2=llvm/trunk/lib/CodeGen/ScheduleDAGPrinter.cpp&p1=llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp&r1=59660&r2=59676&rev=59676&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/ScheduleDAGPrinter.cpp Wed Nov 19 17:18:57 2008
@@ -1,4 +1,4 @@
-//===-- SelectionDAGPrinter.cpp - Implement SelectionDAG::viewGraph() -----===//
+//===-- ScheduleDAGPrinter.cpp - Implement ScheduleDAG::viewGraph() -------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,14 +7,13 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This implements the SelectionDAG::viewGraph method.
+// This implements the ScheduleDAG::viewGraph method.
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Constants.h"
 #include "llvm/Function.h"
 #include "llvm/Assembly/Writer.h"
-#include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/CodeGen/ScheduleDAG.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFunction.h"
@@ -33,358 +32,6 @@
 
 namespace llvm {
   template<>
-  struct DOTGraphTraits<SelectionDAG*> : public DefaultDOTGraphTraits {
-    static bool hasEdgeDestLabels() {
-      return true;
-    }
-
-    static unsigned numEdgeDestLabels(const void *Node) {
-      return ((const SDNode *) Node)->getNumValues();
-    }
-
-    static std::string getEdgeDestLabel(const void *Node, unsigned i) {
-      return ((const SDNode *) Node)->getValueType(i).getMVTString();
-    }
-
-    /// edgeTargetsEdgeSource - This method returns true if this outgoing edge
-    /// should actually target another edge source, not a node.  If this method is
-    /// implemented, getEdgeTarget should be implemented.
-    template<typename EdgeIter>
-    static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I) {
-      return true;
-    }
-
-    /// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is
-    /// called to determine which outgoing edge of Node is the target of this
-    /// edge.
-    template<typename EdgeIter>
-    static EdgeIter getEdgeTarget(const void *Node, EdgeIter I) {
-      SDNode *TargetNode = *I;
-      SDNodeIterator NI = SDNodeIterator::begin(TargetNode);
-      std::advance(NI, I.getNode()->getOperand(I.getOperand()).getResNo());
-      return NI;
-    }
-
-    static std::string getGraphName(const SelectionDAG *G) {
-      return G->getMachineFunction().getFunction()->getName();
-    }
-
-    static bool renderGraphFromBottomUp() {
-      return true;
-    }
-    
-    static bool hasNodeAddressLabel(const SDNode *Node,
-                                    const SelectionDAG *Graph) {
-      return true;
-    }
-    
-    /// If you want to override the dot attributes printed for a particular
-    /// edge, override this method.
-    template<typename EdgeIter>
-    static std::string getEdgeAttributes(const void *Node, EdgeIter EI) {
-      SDValue Op = EI.getNode()->getOperand(EI.getOperand());
-      MVT VT = Op.getValueType();
-      if (VT == MVT::Flag)
-        return "color=red,style=bold";
-      else if (VT == MVT::Other)
-        return "color=blue,style=dashed";
-      return "";
-    }
-    
-
-    static std::string getNodeLabel(const SDNode *Node,
-                                    const SelectionDAG *Graph);
-    static std::string getNodeAttributes(const SDNode *N,
-                                         const SelectionDAG *Graph) {
-#ifndef NDEBUG
-      const std::string &Attrs = Graph->getGraphAttrs(N);
-      if (!Attrs.empty()) {
-        if (Attrs.find("shape=") == std::string::npos)
-          return std::string("shape=Mrecord,") + Attrs;
-        else
-          return Attrs;
-      }
-#endif
-      return "shape=Mrecord";
-    }
-
-    static void addCustomGraphFeatures(SelectionDAG *G,
-                                       GraphWriter<SelectionDAG*> &GW) {
-      GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot");
-      if (G->getRoot().getNode())
-        GW.emitEdge(0, -1, G->getRoot().getNode(), G->getRoot().getResNo(),
-                    "color=blue,style=dashed");
-    }
-  };
-}
-
-std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
-                                                        const SelectionDAG *G) {
-  std::string Op = Node->getOperationName(G);
-
-  if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(Node)) {
-    Op += ": " + utostr(CSDN->getZExtValue());
-  } else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(Node)) {
-    Op += ": " + ftostr(CSDN->getValueAPF());
-  } else if (const GlobalAddressSDNode *GADN =
-             dyn_cast<GlobalAddressSDNode>(Node)) {
-    Op += ": " + GADN->getGlobal()->getName();
-    if (int64_t Offset = GADN->getOffset()) {
-      if (Offset > 0)
-        Op += "+" + itostr(Offset);
-      else
-        Op += itostr(Offset);
-    }
-  } else if (const FrameIndexSDNode *FIDN = dyn_cast<FrameIndexSDNode>(Node)) {
-    Op += " " + itostr(FIDN->getIndex());
-  } else if (const JumpTableSDNode *JTDN = dyn_cast<JumpTableSDNode>(Node)) {
-    Op += " " + itostr(JTDN->getIndex());
-  } else if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Node)){
-    if (CP->isMachineConstantPoolEntry()) {
-      Op += '<';
-      {
-        raw_string_ostream OSS(Op);
-        OSS << *CP->getMachineCPVal();
-      }
-      Op += '>';
-    } else {
-      if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
-        Op += "<" + ftostr(CFP->getValueAPF()) + ">";
-      else if (ConstantInt *CI = dyn_cast<ConstantInt>(CP->getConstVal()))
-        Op += "<" + utostr(CI->getZExtValue()) + ">";
-      else {
-        Op += '<';
-        {
-          raw_string_ostream OSS(Op);
-          WriteAsOperand(OSS, CP->getConstVal(), false);
-        }
-        Op += '>';
-      }
-    }
-    Op += " A=" + itostr(1 << CP->getAlignment());
-  } else if (const BasicBlockSDNode *BBDN = dyn_cast<BasicBlockSDNode>(Node)) {
-    Op = "BB: ";
-    const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock();
-    if (LBB)
-      Op += LBB->getName();
-    //Op += " " + (const void*)BBDN->getBasicBlock();
-  } else if (const RegisterSDNode *R = dyn_cast<RegisterSDNode>(Node)) {
-    if (G && R->getReg() != 0 &&
-        TargetRegisterInfo::isPhysicalRegister(R->getReg())) {
-      Op = Op + " " +
-        G->getTarget().getRegisterInfo()->getName(R->getReg());
-    } else {
-      Op += " #" + utostr(R->getReg());
-    }
-  } else if (const DbgStopPointSDNode *D = dyn_cast<DbgStopPointSDNode>(Node)) {
-    Op += ": " + D->getCompileUnit()->getFileName();
-    Op += ":" + utostr(D->getLine());
-    if (D->getColumn() != 0)
-      Op += ":" + utostr(D->getColumn());
-  } else if (const LabelSDNode *L = dyn_cast<LabelSDNode>(Node)) {
-    Op += ": LabelID=" + utostr(L->getLabelID());
-  } else if (const CallSDNode *C = dyn_cast<CallSDNode>(Node)) {
-    Op += ": CallingConv=" + utostr(C->getCallingConv());
-    if (C->isVarArg())
-      Op += ", isVarArg";
-    if (C->isTailCall())
-      Op += ", isTailCall";
-  } else if (const ExternalSymbolSDNode *ES =
-             dyn_cast<ExternalSymbolSDNode>(Node)) {
-    Op += "'" + std::string(ES->getSymbol()) + "'";
-  } else if (const SrcValueSDNode *M = dyn_cast<SrcValueSDNode>(Node)) {
-    if (M->getValue())
-      Op += "<" + M->getValue()->getName() + ">";
-    else
-      Op += "<null>";
-  } else if (const MemOperandSDNode *M = dyn_cast<MemOperandSDNode>(Node)) {
-    const Value *V = M->MO.getValue();
-    Op += '<';
-    if (!V) {
-      Op += "(unknown)";
-    } else if (isa<PseudoSourceValue>(V)) {
-      // PseudoSourceValues don't have names, so use their print method.
-      {
-        raw_string_ostream OSS(Op);
-        OSS << *M->MO.getValue();
-      }
-    } else {
-      Op += V->getName();
-    }
-    Op += '+' + itostr(M->MO.getOffset()) + '>';
-  } else if (const ARG_FLAGSSDNode *N = dyn_cast<ARG_FLAGSSDNode>(Node)) {
-    Op = Op + " AF=" + N->getArgFlags().getArgFlagsString();
-  } else if (const VTSDNode *N = dyn_cast<VTSDNode>(Node)) {
-    Op = Op + " VT=" + N->getVT().getMVTString();
-  } else if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(Node)) {
-    bool doExt = true;
-    switch (LD->getExtensionType()) {
-    default: doExt = false; break;
-    case ISD::EXTLOAD:
-      Op = Op + "<anyext ";
-      break;
-    case ISD::SEXTLOAD:
-      Op = Op + " <sext ";
-      break;
-    case ISD::ZEXTLOAD:
-      Op = Op + " <zext ";
-      break;
-    }
-    if (doExt)
-      Op += LD->getMemoryVT().getMVTString() + ">";
-    if (LD->isVolatile())
-      Op += "<V>";
-    Op += LD->getIndexedModeName(LD->getAddressingMode());
-    if (LD->getAlignment() > 1)
-      Op += " A=" + utostr(LD->getAlignment());
-  } else if (const StoreSDNode *ST = dyn_cast<StoreSDNode>(Node)) {
-    if (ST->isTruncatingStore())
-      Op += "<trunc " + ST->getMemoryVT().getMVTString() + ">";
-    if (ST->isVolatile())
-      Op += "<V>";
-    Op += ST->getIndexedModeName(ST->getAddressingMode());
-    if (ST->getAlignment() > 1)
-      Op += " A=" + utostr(ST->getAlignment());
-  }
-
-#if 0
-  Op += " Id=" + itostr(Node->getNodeId());
-#endif
-  
-  return Op;
-}
-
-
-/// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
-/// rendered using 'dot'.
-///
-void SelectionDAG::viewGraph(const std::string &Title) {
-// This code is only for debugging!
-#ifndef NDEBUG
-  ViewGraph(this, "dag." + getMachineFunction().getFunction()->getName(),
-            Title);
-#else
-  cerr << "SelectionDAG::viewGraph is only available in debug builds on "
-       << "systems with Graphviz or gv!\n";
-#endif  // NDEBUG
-}
-
-// This overload is defined out-of-line here instead of just using a
-// default parameter because this is easiest for gdb to call.
-void SelectionDAG::viewGraph() {
-  viewGraph("");
-}
-
-/// clearGraphAttrs - Clear all previously defined node graph attributes.
-/// Intended to be used from a debugging tool (eg. gdb).
-void SelectionDAG::clearGraphAttrs() {
-#ifndef NDEBUG
-  NodeGraphAttrs.clear();
-#else
-  cerr << "SelectionDAG::clearGraphAttrs is only available in debug builds"
-       << " on systems with Graphviz or gv!\n";
-#endif
-}
-
-
-/// setGraphAttrs - Set graph attributes for a node. (eg. "color=red".)
-///
-void SelectionDAG::setGraphAttrs(const SDNode *N, const char *Attrs) {
-#ifndef NDEBUG
-  NodeGraphAttrs[N] = Attrs;
-#else
-  cerr << "SelectionDAG::setGraphAttrs is only available in debug builds"
-       << " on systems with Graphviz or gv!\n";
-#endif
-}
-
-
-/// getGraphAttrs - Get graph attributes for a node. (eg. "color=red".)
-/// Used from getNodeAttributes.
-const std::string SelectionDAG::getGraphAttrs(const SDNode *N) const {
-#ifndef NDEBUG
-  std::map<const SDNode *, std::string>::const_iterator I =
-    NodeGraphAttrs.find(N);
-    
-  if (I != NodeGraphAttrs.end())
-    return I->second;
-  else
-    return "";
-#else
-  cerr << "SelectionDAG::getGraphAttrs is only available in debug builds"
-       << " on systems with Graphviz or gv!\n";
-  return std::string("");
-#endif
-}
-
-/// setGraphColor - Convenience for setting node color attribute.
-///
-void SelectionDAG::setGraphColor(const SDNode *N, const char *Color) {
-#ifndef NDEBUG
-  NodeGraphAttrs[N] = std::string("color=") + Color;
-#else
-  cerr << "SelectionDAG::setGraphColor is only available in debug builds"
-       << " on systems with Graphviz or gv!\n";
-#endif
-}
-
-/// setSubgraphColorHelper - Implement setSubgraphColor.  Return
-/// whether we truncated the search.
-///
-bool SelectionDAG::setSubgraphColorHelper(SDNode *N, const char *Color, DenseSet<SDNode *> &visited,
-                                          int level, bool &printed) {
-  bool hit_limit = false;
-
-#ifndef NDEBUG
-  if (level >= 20) {
-    if (!printed) {
-      printed = true;
-      DOUT << "setSubgraphColor hit max level\n";
-    }
-    return true;
-  }
-
-  unsigned oldSize = visited.size();
-  visited.insert(N);
-  if (visited.size() != oldSize) {
-    setGraphColor(N, Color);
-    for(SDNodeIterator i = SDNodeIterator::begin(N), iend = SDNodeIterator::end(N);
-        i != iend;
-        ++i) {
-      hit_limit = setSubgraphColorHelper(*i, Color, visited, level+1, printed) || hit_limit;
-    }
-  }
-#else
-  cerr << "SelectionDAG::setSubgraphColor is only available in debug builds"
-       << " on systems with Graphviz or gv!\n";
-#endif
-  return hit_limit;
-}
-
-/// setSubgraphColor - Convenience for setting subgraph color attribute.
-///
-void SelectionDAG::setSubgraphColor(SDNode *N, const char *Color) {
-#ifndef NDEBUG
-  DenseSet<SDNode *> visited;
-  bool printed = false;
-  if (setSubgraphColorHelper(N, Color, visited, 0, printed)) {
-    // Visually mark that we hit the limit
-    if (strcmp(Color, "red") == 0) {
-      setSubgraphColorHelper(N, "blue", visited, 0, printed);
-    }
-    else if (strcmp(Color, "yellow") == 0) {
-      setSubgraphColorHelper(N, "green", visited, 0, printed);
-    }
-  }
-
-#else
-  cerr << "SelectionDAG::setSubgraphColor is only available in debug builds"
-       << " on systems with Graphviz or gv!\n";
-#endif
-}
-
-namespace llvm {
-  template<>
   struct DOTGraphTraits<ScheduleDAG*> : public DefaultDOTGraphTraits {
     static std::string getGraphName(const ScheduleDAG *G) {
       return G->MF->getFunction()->getName();
@@ -420,56 +67,16 @@
 
     static void addCustomGraphFeatures(ScheduleDAG *G,
                                        GraphWriter<ScheduleDAG*> &GW) {
-      // Draw a special "GraphRoot" node to indicate the root of the graph.
-      GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot");
-      if (G->DAG) {
-        // For an SDNode-based ScheduleDAG, point to the root of the ScheduleDAG.
-        const SDNode *N = G->DAG->getRoot().getNode();
-        if (N && N->getNodeId() != -1)
-          GW.emitEdge(0, -1, &G->SUnits[N->getNodeId()], -1,
-                      "color=blue,style=dashed");
-      } else {
-        // For a MachineInstr-based ScheduleDAG, find a root to point to.
-        for (unsigned i = 0, e = G->SUnits.size(); i != e; ++i) {
-          if (G->SUnits[i].Succs.empty()) {
-            GW.emitEdge(0, -1, &G->SUnits[i], -1,
-                        "color=blue,style=dashed");
-            break;
-          }
-        }
-      }
+      return G->addCustomGraphFeatures(GW);
     }
   };
 }
 
 std::string DOTGraphTraits<ScheduleDAG*>::getNodeLabel(const SUnit *SU,
                                                        const ScheduleDAG *G) {
-  std::string Op;
-
-  if (G->DAG) {
-    if (!SU->getNode())
-      Op = "<CROSS RC COPY>";
-    else {
-      SmallVector<SDNode *, 4> FlaggedNodes;
-      for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode())
-        FlaggedNodes.push_back(N);
-      while (!FlaggedNodes.empty()) {
-        Op += DOTGraphTraits<SelectionDAG*>::getNodeLabel(FlaggedNodes.back(),
-                                                          G->DAG) + "\n";
-        FlaggedNodes.pop_back();
-      }
-    }
-  } else {
-    std::string s;
-    raw_string_ostream oss(s);
-    SU->getInstr()->print(oss);
-    Op += oss.str();
-  }
-
-  return Op;
+  return G->getGraphNodeLabel(SU);
 }
 
-
 /// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
 /// rendered using 'dot'.
 ///

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/CMakeLists.txt?rev=59676&r1=59675&r2=59676&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/CMakeLists.txt (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/CMakeLists.txt Wed Nov 19 17:18:57 2008
@@ -2,15 +2,14 @@
   CallingConvLower.cpp
   DAGCombiner.cpp
   FastISel.cpp
-  LatencyPriorityQueue.cpp
   LegalizeDAG.cpp
   LegalizeFloatTypes.cpp
   LegalizeIntegerTypes.cpp
   LegalizeTypes.cpp
   LegalizeTypesGeneric.cpp
   LegalizeVectorTypes.cpp
-  ScheduleDAG.cpp
-  ScheduleDAGEmit.cpp
+  ScheduleDAGSDNodes.cpp
+  ScheduleDAGSDNodesEmit.cpp
   ScheduleDAGFast.cpp
   ScheduleDAGList.cpp
   ScheduleDAGRRList.cpp

Removed: llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp?rev=59675&view=auto

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.cpp (removed)
@@ -1,165 +0,0 @@
-//===---- LatencyPriorityQueue.cpp - A latency-oriented priority queue ----===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the LatencyPriorityQueue class, which is a
-// SchedulingPriorityQueue that schedules using latency information to
-// reduce the length of the critical path through the basic block.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "scheduler"
-#include "LatencyPriorityQueue.h"
-#include "llvm/Support/Debug.h"
-using namespace llvm;
-
-bool latency_sort::operator()(const SUnit *LHS, const SUnit *RHS) const {
-  unsigned LHSNum = LHS->NodeNum;
-  unsigned RHSNum = RHS->NodeNum;
-
-  // The most important heuristic is scheduling the critical path.
-  unsigned LHSLatency = PQ->getLatency(LHSNum);
-  unsigned RHSLatency = PQ->getLatency(RHSNum);
-  if (LHSLatency < RHSLatency) return true;
-  if (LHSLatency > RHSLatency) return false;
-  
-  // After that, if two nodes have identical latencies, look to see if one will
-  // unblock more other nodes than the other.
-  unsigned LHSBlocked = PQ->getNumSolelyBlockNodes(LHSNum);
-  unsigned RHSBlocked = PQ->getNumSolelyBlockNodes(RHSNum);
-  if (LHSBlocked < RHSBlocked) return true;
-  if (LHSBlocked > RHSBlocked) return false;
-  
-  // Finally, just to provide a stable ordering, use the node number as a
-  // deciding factor.
-  return LHSNum < RHSNum;
-}
-
-
-/// CalcNodePriority - Calculate the maximal path from the node to the exit.
-///
-int LatencyPriorityQueue::CalcLatency(const SUnit &SU) {
-  int &Latency = Latencies[SU.NodeNum];
-  if (Latency != -1)
-    return Latency;
-
-  std::vector<const SUnit*> WorkList;
-  WorkList.push_back(&SU);
-  while (!WorkList.empty()) {
-    const SUnit *Cur = WorkList.back();
-    bool AllDone = true;
-    int MaxSuccLatency = 0;
-    for (SUnit::const_succ_iterator I = Cur->Succs.begin(),E = Cur->Succs.end();
-         I != E; ++I) {
-      int SuccLatency = Latencies[I->Dep->NodeNum];
-      if (SuccLatency == -1) {
-        AllDone = false;
-        WorkList.push_back(I->Dep);
-      } else {
-        MaxSuccLatency = std::max(MaxSuccLatency, SuccLatency);
-      }
-    }
-    if (AllDone) {
-      Latencies[Cur->NodeNum] = MaxSuccLatency + Cur->Latency;
-      WorkList.pop_back();
-    }
-  }
-
-  return Latency;
-}
-
-/// CalculatePriorities - Calculate priorities of all scheduling units.
-void LatencyPriorityQueue::CalculatePriorities() {
-  Latencies.assign(SUnits->size(), -1);
-  NumNodesSolelyBlocking.assign(SUnits->size(), 0);
-
-  // For each node, calculate the maximal path from the node to the exit.
-  std::vector<std::pair<const SUnit*, unsigned> > WorkList;
-  for (unsigned i = 0, e = SUnits->size(); i != e; ++i) {
-    const SUnit *SU = &(*SUnits)[i];
-    if (SU->Succs.empty())
-      WorkList.push_back(std::make_pair(SU, 0U));
-  }
-
-  while (!WorkList.empty()) {
-    const SUnit *SU = WorkList.back().first;
-    unsigned SuccLat = WorkList.back().second;
-    WorkList.pop_back();
-    int &Latency = Latencies[SU->NodeNum];
-    if (Latency == -1 || (SU->Latency + SuccLat) > (unsigned)Latency) {
-      Latency = SU->Latency + SuccLat;
-      for (SUnit::const_pred_iterator I = SU->Preds.begin(),E = SU->Preds.end();
-           I != E; ++I)
-        WorkList.push_back(std::make_pair(I->Dep, Latency));
-    }
-  }
-}
-
-/// getSingleUnscheduledPred - If there is exactly one unscheduled predecessor
-/// of SU, return it, otherwise return null.
-SUnit *LatencyPriorityQueue::getSingleUnscheduledPred(SUnit *SU) {
-  SUnit *OnlyAvailablePred = 0;
-  for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
-       I != E; ++I) {
-    SUnit &Pred = *I->Dep;
-    if (!Pred.isScheduled) {
-      // We found an available, but not scheduled, predecessor.  If it's the
-      // only one we have found, keep track of it... otherwise give up.
-      if (OnlyAvailablePred && OnlyAvailablePred != &Pred)
-        return 0;
-      OnlyAvailablePred = &Pred;
-    }
-  }
-      
-  return OnlyAvailablePred;
-}
-
-void LatencyPriorityQueue::push_impl(SUnit *SU) {
-  // Look at all of the successors of this node.  Count the number of nodes that
-  // this node is the sole unscheduled node for.
-  unsigned NumNodesBlocking = 0;
-  for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
-       I != E; ++I)
-    if (getSingleUnscheduledPred(I->Dep) == SU)
-      ++NumNodesBlocking;
-  NumNodesSolelyBlocking[SU->NodeNum] = NumNodesBlocking;
-  
-  Queue.push(SU);
-}
-
-
-// ScheduledNode - As nodes are scheduled, we look to see if there are any
-// successor nodes that have a single unscheduled predecessor.  If so, that
-// single predecessor has a higher priority, since scheduling it will make
-// the node available.
-void LatencyPriorityQueue::ScheduledNode(SUnit *SU) {
-  for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
-       I != E; ++I)
-    AdjustPriorityOfUnscheduledPreds(I->Dep);
-}
-
-/// AdjustPriorityOfUnscheduledPreds - One of the predecessors of SU was just
-/// scheduled.  If SU is not itself available, then there is at least one
-/// predecessor node that has not been scheduled yet.  If SU has exactly ONE
-/// unscheduled predecessor, we want to increase its priority: it getting
-/// scheduled will make this node available, so it is better than some other
-/// node of the same priority that will not make a node available.
-void LatencyPriorityQueue::AdjustPriorityOfUnscheduledPreds(SUnit *SU) {
-  if (SU->isAvailable) return;  // All preds scheduled.
-  
-  SUnit *OnlyAvailablePred = getSingleUnscheduledPred(SU);
-  if (OnlyAvailablePred == 0 || !OnlyAvailablePred->isAvailable) return;
-  
-  // Okay, we found a single predecessor that is available, but not scheduled.
-  // Since it is available, it must be in the priority queue.  First remove it.
-  remove(OnlyAvailablePred);
-
-  // Reinsert the node into the priority queue, which recomputes its
-  // NumNodesSolelyBlocking value.
-  push(OnlyAvailablePred);
-}

Removed: llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h?rev=59675&view=auto

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LatencyPriorityQueue.h (removed)
@@ -1,124 +0,0 @@
-//===---- LatencyPriorityQueue.h - A latency-oriented priority queue ------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the LatencyPriorityQueue class, which is a
-// SchedulingPriorityQueue that schedules using latency information to
-// reduce the length of the critical path through the basic block.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LATENCY_PRIORITY_QUEUE_H
-#define LATENCY_PRIORITY_QUEUE_H
-
-#include "llvm/CodeGen/ScheduleDAG.h"
-#include "llvm/ADT/PriorityQueue.h"
-
-namespace llvm {
-  class LatencyPriorityQueue;
-  
-  /// Sorting functions for the Available queue.
-  struct latency_sort : public std::binary_function<SUnit*, SUnit*, bool> {
-    LatencyPriorityQueue *PQ;
-    explicit latency_sort(LatencyPriorityQueue *pq) : PQ(pq) {}
-    
-    bool operator()(const SUnit* left, const SUnit* right) const;
-  };
-
-  class LatencyPriorityQueue : public SchedulingPriorityQueue {
-    // SUnits - The SUnits for the current graph.
-    std::vector<SUnit> *SUnits;
-    
-    // Latencies - The latency (max of latency from this node to the bb exit)
-    // for each node.
-    std::vector<int> Latencies;
-
-    /// NumNodesSolelyBlocking - This vector contains, for every node in the
-    /// Queue, the number of nodes that the node is the sole unscheduled
-    /// predecessor for.  This is used as a tie-breaker heuristic for better
-    /// mobility.
-    std::vector<unsigned> NumNodesSolelyBlocking;
-
-    PriorityQueue<SUnit*, std::vector<SUnit*>, latency_sort> Queue;
-  public:
-    LatencyPriorityQueue() : Queue(latency_sort(this)) {
-    }
-    
-    void initNodes(std::vector<SUnit> &sunits) {
-      SUnits = &sunits;
-      // Calculate node priorities.
-      CalculatePriorities();
-    }
-
-    void addNode(const SUnit *SU) {
-      Latencies.resize(SUnits->size(), -1);
-      NumNodesSolelyBlocking.resize(SUnits->size(), 0);
-      CalcLatency(*SU);
-    }
-
-    void updateNode(const SUnit *SU) {
-      Latencies[SU->NodeNum] = -1;
-      CalcLatency(*SU);
-    }
-
-    void releaseState() {
-      SUnits = 0;
-      Latencies.clear();
-    }
-    
-    unsigned getLatency(unsigned NodeNum) const {
-      assert(NodeNum < Latencies.size());
-      return Latencies[NodeNum];
-    }
-    
-    unsigned getNumSolelyBlockNodes(unsigned NodeNum) const {
-      assert(NodeNum < NumNodesSolelyBlocking.size());
-      return NumNodesSolelyBlocking[NodeNum];
-    }
-    
-    unsigned size() const { return Queue.size(); }
-
-    bool empty() const { return Queue.empty(); }
-    
-    virtual void push(SUnit *U) {
-      push_impl(U);
-    }
-    void push_impl(SUnit *U);
-    
-    void push_all(const std::vector<SUnit *> &Nodes) {
-      for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
-        push_impl(Nodes[i]);
-    }
-    
-    SUnit *pop() {
-      if (empty()) return NULL;
-      SUnit *V = Queue.top();
-      Queue.pop();
-      return V;
-    }
-
-    void remove(SUnit *SU) {
-      assert(!Queue.empty() && "Not in queue!");
-      Queue.erase_one(SU);
-    }
-
-    // ScheduledNode - As nodes are scheduled, we look to see if there are any
-    // successor nodes that have a single unscheduled predecessor.  If so, that
-    // single predecessor has a higher priority, since scheduling it will make
-    // the node available.
-    void ScheduledNode(SUnit *Node);
-
-  private:
-    void CalculatePriorities();
-    int CalcLatency(const SUnit &SU);
-    void AdjustPriorityOfUnscheduledPreds(SUnit *SU);
-    SUnit *getSingleUnscheduledPred(SUnit *SU);
-  };
-}
-
-#endif

Removed: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=59675&view=auto

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (removed)
@@ -1,522 +0,0 @@
-//===---- ScheduleDAG.cpp - Implement the ScheduleDAG class ---------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This implements the ScheduleDAG class, which is a base class used by
-// scheduling implementation classes.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "pre-RA-sched"
-#include "llvm/CodeGen/ScheduleDAG.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace llvm;
-
-ScheduleDAG::ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb,
-                         const TargetMachine &tm)
-  : DAG(dag), BB(bb), TM(tm), MRI(BB->getParent()->getRegInfo()) {
-  TII = TM.getInstrInfo();
-  MF  = BB->getParent();
-  TRI = TM.getRegisterInfo();
-  TLI = TM.getTargetLowering();
-  ConstPool = MF->getConstantPool();
-}
-
-/// CheckForPhysRegDependency - Check if the dependency between def and use of
-/// a specified operand is a physical register dependency. If so, returns the
-/// register and the cost of copying the register.
-static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
-                                      const TargetRegisterInfo *TRI, 
-                                      const TargetInstrInfo *TII,
-                                      unsigned &PhysReg, int &Cost) {
-  if (Op != 2 || User->getOpcode() != ISD::CopyToReg)
-    return;
-
-  unsigned Reg = cast<RegisterSDNode>(User->getOperand(1))->getReg();
-  if (TargetRegisterInfo::isVirtualRegister(Reg))
-    return;
-
-  unsigned ResNo = User->getOperand(2).getResNo();
-  if (Def->isMachineOpcode()) {
-    const TargetInstrDesc &II = TII->get(Def->getMachineOpcode());
-    if (ResNo >= II.getNumDefs() &&
-        II.ImplicitDefs[ResNo - II.getNumDefs()] == Reg) {
-      PhysReg = Reg;
-      const TargetRegisterClass *RC =
-        TRI->getPhysicalRegisterRegClass(Reg, Def->getValueType(ResNo));
-      Cost = RC->getCopyCost();
-    }
-  }
-}
-
-SUnit *ScheduleDAG::Clone(SUnit *Old) {
-  SUnit *SU = NewSUnit(Old->getNode());
-  SU->OrigNode = Old->OrigNode;
-  SU->Latency = Old->Latency;
-  SU->isTwoAddress = Old->isTwoAddress;
-  SU->isCommutable = Old->isCommutable;
-  SU->hasPhysRegDefs = Old->hasPhysRegDefs;
-  return SU;
-}
-
-
-/// BuildSchedUnits - Build SUnits from the selection dag that we are input.
-/// This SUnit graph is similar to the SelectionDAG, but represents flagged
-/// together nodes with a single SUnit.
-void ScheduleDAG::BuildSchedUnits() {
-  // For post-regalloc scheduling, build the SUnits from the MachineInstrs
-  // in the MachineBasicBlock.
-  if (!DAG) {
-    BuildSchedUnitsFromMBB();
-    return;
-  }
-
-  // Reserve entries in the vector for each of the SUnits we are creating.  This
-  // ensure that reallocation of the vector won't happen, so SUnit*'s won't get
-  // invalidated.
-  SUnits.reserve(DAG->allnodes_size());
-  
-  // During scheduling, the NodeId field of SDNode is used to map SDNodes
-  // to their associated SUnits by holding SUnits table indices. A value
-  // of -1 means the SDNode does not yet have an associated SUnit.
-  for (SelectionDAG::allnodes_iterator NI = DAG->allnodes_begin(),
-       E = DAG->allnodes_end(); NI != E; ++NI)
-    NI->setNodeId(-1);
-
-  for (SelectionDAG::allnodes_iterator NI = DAG->allnodes_begin(),
-       E = DAG->allnodes_end(); NI != E; ++NI) {
-    if (isPassiveNode(NI))  // Leaf node, e.g. a TargetImmediate.
-      continue;
-    
-    // If this node has already been processed, stop now.
-    if (NI->getNodeId() != -1) continue;
-    
-    SUnit *NodeSUnit = NewSUnit(NI);
-    
-    // See if anything is flagged to this node, if so, add them to flagged
-    // nodes.  Nodes can have at most one flag input and one flag output.  Flags
-    // are required the be the last operand and result of a node.
-    
-    // Scan up to find flagged preds.
-    SDNode *N = NI;
-    if (N->getNumOperands() &&
-        N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) {
-      do {
-        N = N->getOperand(N->getNumOperands()-1).getNode();
-        assert(N->getNodeId() == -1 && "Node already inserted!");
-        N->setNodeId(NodeSUnit->NodeNum);
-      } while (N->getNumOperands() &&
-               N->getOperand(N->getNumOperands()-1).getValueType()== MVT::Flag);
-    }
-    
-    // Scan down to find any flagged succs.
-    N = NI;
-    while (N->getValueType(N->getNumValues()-1) == MVT::Flag) {
-      SDValue FlagVal(N, N->getNumValues()-1);
-      
-      // There are either zero or one users of the Flag result.
-      bool HasFlagUse = false;
-      for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); 
-           UI != E; ++UI)
-        if (FlagVal.isOperandOf(*UI)) {
-          HasFlagUse = true;
-          assert(N->getNodeId() == -1 && "Node already inserted!");
-          N->setNodeId(NodeSUnit->NodeNum);
-          N = *UI;
-          break;
-        }
-      if (!HasFlagUse) break;
-    }
-    
-    // If there are flag operands involved, N is now the bottom-most node
-    // of the sequence of nodes that are flagged together.
-    // Update the SUnit.
-    NodeSUnit->setNode(N);
-    assert(N->getNodeId() == -1 && "Node already inserted!");
-    N->setNodeId(NodeSUnit->NodeNum);
-
-    ComputeLatency(NodeSUnit);
-  }
-  
-  // Pass 2: add the preds, succs, etc.
-  for (unsigned su = 0, e = SUnits.size(); su != e; ++su) {
-    SUnit *SU = &SUnits[su];
-    SDNode *MainNode = SU->getNode();
-    
-    if (MainNode->isMachineOpcode()) {
-      unsigned Opc = MainNode->getMachineOpcode();
-      const TargetInstrDesc &TID = TII->get(Opc);
-      for (unsigned i = 0; i != TID.getNumOperands(); ++i) {
-        if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) {
-          SU->isTwoAddress = true;
-          break;
-        }
-      }
-      if (TID.isCommutable())
-        SU->isCommutable = true;
-    }
-    
-    // Find all predecessors and successors of the group.
-    for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) {
-      if (N->isMachineOpcode() &&
-          TII->get(N->getMachineOpcode()).getImplicitDefs() &&
-          CountResults(N) > TII->get(N->getMachineOpcode()).getNumDefs())
-        SU->hasPhysRegDefs = true;
-      
-      for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
-        SDNode *OpN = N->getOperand(i).getNode();
-        if (isPassiveNode(OpN)) continue;   // Not scheduled.
-        SUnit *OpSU = &SUnits[OpN->getNodeId()];
-        assert(OpSU && "Node has no SUnit!");
-        if (OpSU == SU) continue;           // In the same group.
-
-        MVT OpVT = N->getOperand(i).getValueType();
-        assert(OpVT != MVT::Flag && "Flagged nodes should be in same sunit!");
-        bool isChain = OpVT == MVT::Other;
-
-        unsigned PhysReg = 0;
-        int Cost = 1;
-        // Determine if this is a physical register dependency.
-        CheckForPhysRegDependency(OpN, N, i, TRI, TII, PhysReg, Cost);
-        SU->addPred(OpSU, isChain, false, PhysReg, Cost);
-      }
-    }
-  }
-}
-
-void ScheduleDAG::BuildSchedUnitsFromMBB() {
-  SUnits.clear();
-  SUnits.reserve(BB->size());
-
-  std::vector<SUnit *> PendingLoads;
-  SUnit *Terminator = 0;
-  SUnit *Chain = 0;
-  SUnit *Defs[TargetRegisterInfo::FirstVirtualRegister] = {};
-  std::vector<SUnit *> Uses[TargetRegisterInfo::FirstVirtualRegister] = {};
-  int Cost = 1; // FIXME
-
-  for (MachineBasicBlock::iterator MII = BB->end(), MIE = BB->begin();
-       MII != MIE; --MII) {
-    MachineInstr *MI = prior(MII);
-    SUnit *SU = NewSUnit(MI);
-
-    for (unsigned j = 0, n = MI->getNumOperands(); j != n; ++j) {
-      const MachineOperand &MO = MI->getOperand(j);
-      if (!MO.isReg()) continue;
-      unsigned Reg = MO.getReg();
-      if (Reg == 0) continue;
-
-      assert(TRI->isPhysicalRegister(Reg) && "Virtual register encountered!");
-      std::vector<SUnit *> &UseList = Uses[Reg];
-      SUnit *&Def = Defs[Reg];
-      // Optionally add output and anti dependences
-      if (Def && Def != SU)
-        Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false,
-                     /*PhyReg=*/Reg, Cost);
-      for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
-        SUnit *&Def = Defs[*Alias];
-        if (Def && Def != SU)
-          Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false,
-                       /*PhyReg=*/*Alias, Cost);
-      }
-
-      if (MO.isDef()) {
-        // Add any data dependencies.
-        for (unsigned i = 0, e = UseList.size(); i != e; ++i)
-          if (UseList[i] != SU)
-            UseList[i]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false,
-                                /*PhysReg=*/Reg, Cost);
-        for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
-          std::vector<SUnit *> &UseList = Uses[*Alias];
-          for (unsigned i = 0, e = UseList.size(); i != e; ++i)
-            if (UseList[i] != SU)
-              UseList[i]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false,
-                                  /*PhysReg=*/*Alias, Cost);
-        }
-
-        UseList.clear();
-        Def = SU;
-      } else {
-        UseList.push_back(SU);
-      }
-    }
-    bool False = false;
-    bool True = true;
-    if (!MI->isSafeToMove(TII, False)) {
-      if (Chain)
-        Chain->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false);
-      for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k)
-        PendingLoads[k]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false);
-      PendingLoads.clear();
-      Chain = SU;
-    } else if (!MI->isSafeToMove(TII, True)) {
-      if (Chain)
-        Chain->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false);
-      PendingLoads.push_back(SU);
-    }
-    if (Terminator && SU->Succs.empty())
-      Terminator->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false);
-    if (MI->getDesc().isTerminator())
-      Terminator = SU;
-  }
-}
-
-void ScheduleDAG::ComputeLatency(SUnit *SU) {
-  const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
-  
-  // Compute the latency for the node.  We use the sum of the latencies for
-  // all nodes flagged together into this SUnit.
-  if (InstrItins.isEmpty()) {
-    // No latency information.
-    SU->Latency = 1;
-    return;
-  }
-
-  SU->Latency = 0;
-  for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) {
-    if (N->isMachineOpcode()) {
-      unsigned SchedClass = TII->get(N->getMachineOpcode()).getSchedClass();
-      const InstrStage *S = InstrItins.begin(SchedClass);
-      const InstrStage *E = InstrItins.end(SchedClass);
-      for (; S != E; ++S)
-        SU->Latency += S->Cycles;
-    }
-  }
-}
-
-/// CalculateDepths - compute depths using algorithms for the longest
-/// paths in the DAG
-void ScheduleDAG::CalculateDepths() {
-  unsigned DAGSize = SUnits.size();
-  std::vector<SUnit*> WorkList;
-  WorkList.reserve(DAGSize);
-
-  // Initialize the data structures
-  for (unsigned i = 0, e = DAGSize; i != e; ++i) {
-    SUnit *SU = &SUnits[i];
-    unsigned Degree = SU->Preds.size();
-    // Temporarily use the Depth field as scratch space for the degree count.
-    SU->Depth = Degree;
-
-    // Is it a node without dependencies?
-    if (Degree == 0) {
-        assert(SU->Preds.empty() && "SUnit should have no predecessors");
-        // Collect leaf nodes
-        WorkList.push_back(SU);
-    }
-  }
-
-  // Process nodes in the topological order
-  while (!WorkList.empty()) {
-    SUnit *SU = WorkList.back();
-    WorkList.pop_back();
-    unsigned SUDepth = 0;
-
-    // Use dynamic programming:
-    // When current node is being processed, all of its dependencies
-    // are already processed.
-    // So, just iterate over all predecessors and take the longest path
-    for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
-         I != E; ++I) {
-      unsigned PredDepth = I->Dep->Depth;
-      if (PredDepth+1 > SUDepth) {
-          SUDepth = PredDepth + 1;
-      }
-    }
-
-    SU->Depth = SUDepth;
-
-    // Update degrees of all nodes depending on current SUnit
-    for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
-         I != E; ++I) {
-      SUnit *SU = I->Dep;
-      if (!--SU->Depth)
-        // If all dependencies of the node are processed already,
-        // then the longest path for the node can be computed now
-        WorkList.push_back(SU);
-    }
-  }
-}
-
-/// CalculateHeights - compute heights using algorithms for the longest
-/// paths in the DAG
-void ScheduleDAG::CalculateHeights() {
-  unsigned DAGSize = SUnits.size();
-  std::vector<SUnit*> WorkList;
-  WorkList.reserve(DAGSize);
-
-  // Initialize the data structures
-  for (unsigned i = 0, e = DAGSize; i != e; ++i) {
-    SUnit *SU = &SUnits[i];
-    unsigned Degree = SU->Succs.size();
-    // Temporarily use the Height field as scratch space for the degree count.
-    SU->Height = Degree;
-
-    // Is it a node without dependencies?
-    if (Degree == 0) {
-        assert(SU->Succs.empty() && "Something wrong");
-        assert(WorkList.empty() && "Should be empty");
-        // Collect leaf nodes
-        WorkList.push_back(SU);
-    }
-  }
-
-  // Process nodes in the topological order
-  while (!WorkList.empty()) {
-    SUnit *SU = WorkList.back();
-    WorkList.pop_back();
-    unsigned SUHeight = 0;
-
-    // Use dynamic programming:
-    // When current node is being processed, all of its dependencies
-    // are already processed.
-    // So, just iterate over all successors and take the longest path
-    for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
-         I != E; ++I) {
-      unsigned SuccHeight = I->Dep->Height;
-      if (SuccHeight+1 > SUHeight) {
-          SUHeight = SuccHeight + 1;
-      }
-    }
-
-    SU->Height = SUHeight;
-
-    // Update degrees of all nodes depending on current SUnit
-    for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
-         I != E; ++I) {
-      SUnit *SU = I->Dep;
-      if (!--SU->Height)
-        // If all dependencies of the node are processed already,
-        // then the longest path for the node can be computed now
-        WorkList.push_back(SU);
-    }
-  }
-}
-
-/// 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 resulting MachineInstr).
-unsigned ScheduleDAG::CountResults(SDNode *Node) {
-  unsigned N = Node->getNumValues();
-  while (N && Node->getValueType(N - 1) == MVT::Flag)
-    --N;
-  if (N && Node->getValueType(N - 1) == MVT::Other)
-    --N;    // Skip over chain result.
-  return N;
-}
-
-/// CountOperands - The inputs to target nodes have any actual inputs first,
-/// followed by special operands that describe memory references, then an
-/// optional chain operand, then an optional flag operand.  Compute the number
-/// of actual operands that will go into the resulting MachineInstr.
-unsigned ScheduleDAG::CountOperands(SDNode *Node) {
-  unsigned N = ComputeMemOperandsEnd(Node);
-  while (N && isa<MemOperandSDNode>(Node->getOperand(N - 1).getNode()))
-    --N; // Ignore MEMOPERAND nodes
-  return N;
-}
-
-/// ComputeMemOperandsEnd - Find the index one past the last MemOperandSDNode
-/// operand
-unsigned ScheduleDAG::ComputeMemOperandsEnd(SDNode *Node) {
-  unsigned N = Node->getNumOperands();
-  while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag)
-    --N;
-  if (N && Node->getOperand(N - 1).getValueType() == MVT::Other)
-    --N; // Ignore chain if it exists.
-  return N;
-}
-
-
-/// dump - dump the schedule.
-void ScheduleDAG::dumpSchedule() const {
-  for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
-    if (SUnit *SU = Sequence[i])
-      SU->dump(this);
-    else
-      cerr << "**** NOOP ****\n";
-  }
-}
-
-
-/// Run - perform scheduling.
-///
-void ScheduleDAG::Run() {
-  Schedule();
-  
-  DOUT << "*** Final schedule ***\n";
-  DEBUG(dumpSchedule());
-  DOUT << "\n";
-}
-
-/// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
-/// a group of nodes flagged together.
-void SUnit::print(raw_ostream &O, const ScheduleDAG *G) const {
-  O << "SU(" << NodeNum << "): ";
-  if (getNode()) {
-    SmallVector<SDNode *, 4> FlaggedNodes;
-    for (SDNode *N = getNode(); N; N = N->getFlaggedNode())
-      FlaggedNodes.push_back(N);
-    while (!FlaggedNodes.empty()) {
-      O << "    ";
-      FlaggedNodes.back()->print(O, G->DAG);
-      O << "\n";
-      FlaggedNodes.pop_back();
-    }
-  } else {
-    O << "CROSS RC COPY\n";
-  }
-}
-
-void SUnit::dump(const ScheduleDAG *G) const {
-  print(errs(), G);
-}
-
-void SUnit::dumpAll(const ScheduleDAG *G) const {
-  dump(G);
-
-  cerr << "  # preds left       : " << NumPredsLeft << "\n";
-  cerr << "  # succs left       : " << NumSuccsLeft << "\n";
-  cerr << "  Latency            : " << Latency << "\n";
-  cerr << "  Depth              : " << Depth << "\n";
-  cerr << "  Height             : " << Height << "\n";
-
-  if (Preds.size() != 0) {
-    cerr << "  Predecessors:\n";
-    for (SUnit::const_succ_iterator I = Preds.begin(), E = Preds.end();
-         I != E; ++I) {
-      if (I->isCtrl)
-        cerr << "   ch  #";
-      else
-        cerr << "   val #";
-      cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")";
-      if (I->isSpecial)
-        cerr << " *";
-      cerr << "\n";
-    }
-  }
-  if (Succs.size() != 0) {
-    cerr << "  Successors:\n";
-    for (SUnit::const_succ_iterator I = Succs.begin(), E = Succs.end();
-         I != E; ++I) {
-      if (I->isCtrl)
-        cerr << "   ch  #";
-      else
-        cerr << "   val #";
-      cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")";
-      if (I->isSpecial)
-        cerr << " *";
-      cerr << "\n";
-    }
-  }
-  cerr << "\n";
-}

Removed: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp?rev=59675&view=auto

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp (removed)
@@ -1,717 +0,0 @@
-//===---- ScheduleDAGEmit.cpp - Emit routines for the ScheduleDAG class ---===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This implements the Emit routines for the ScheduleDAG class, which creates
-// MachineInstrs according to the computed schedule.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "pre-RA-sched"
-#include "llvm/CodeGen/ScheduleDAG.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetLowering.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/MathExtras.h"
-using namespace llvm;
-
-STATISTIC(NumCommutes,   "Number of instructions commuted");
-
-/// getInstrOperandRegClass - Return register class of the operand of an
-/// instruction of the specified TargetInstrDesc.
-static const TargetRegisterClass*
-getInstrOperandRegClass(const TargetRegisterInfo *TRI, 
-                        const TargetInstrInfo *TII, const TargetInstrDesc &II,
-                        unsigned Op) {
-  if (Op >= II.getNumOperands()) {
-    assert(II.isVariadic() && "Invalid operand # of instruction");
-    return NULL;
-  }
-  if (II.OpInfo[Op].isLookupPtrRegClass())
-    return TII->getPointerRegClass();
-  return TRI->getRegClass(II.OpInfo[Op].RegClass);
-}
-
-/// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
-/// implicit physical register output.
-void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
-                                  bool IsClone, unsigned SrcReg,
-                                  DenseMap<SDValue, unsigned> &VRBaseMap) {
-  unsigned VRBase = 0;
-  if (TargetRegisterInfo::isVirtualRegister(SrcReg)) {
-    // Just use the input register directly!
-    SDValue Op(Node, ResNo);
-    if (IsClone)
-      VRBaseMap.erase(Op);
-    bool isNew = VRBaseMap.insert(std::make_pair(Op, SrcReg)).second;
-    isNew = isNew; // Silence compiler warning.
-    assert(isNew && "Node emitted out of order - early");
-    return;
-  }
-
-  // If the node is only used by a CopyToReg and the dest reg is a vreg, use
-  // the CopyToReg'd destination register instead of creating a new vreg.
-  bool MatchReg = true;
-  const TargetRegisterClass *UseRC = NULL;
-  for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
-       UI != E; ++UI) {
-    SDNode *User = *UI;
-    bool Match = true;
-    if (User->getOpcode() == ISD::CopyToReg && 
-        User->getOperand(2).getNode() == Node &&
-        User->getOperand(2).getResNo() == ResNo) {
-      unsigned DestReg = cast<RegisterSDNode>(User->getOperand(1))->getReg();
-      if (TargetRegisterInfo::isVirtualRegister(DestReg)) {
-        VRBase = DestReg;
-        Match = false;
-      } else if (DestReg != SrcReg)
-        Match = false;
-    } else {
-      for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) {
-        SDValue Op = User->getOperand(i);
-        if (Op.getNode() != Node || Op.getResNo() != ResNo)
-          continue;
-        MVT VT = Node->getValueType(Op.getResNo());
-        if (VT == MVT::Other || VT == MVT::Flag)
-          continue;
-        Match = false;
-        if (User->isMachineOpcode()) {
-          const TargetInstrDesc &II = TII->get(User->getMachineOpcode());
-          const TargetRegisterClass *RC =
-            getInstrOperandRegClass(TRI,TII,II,i+II.getNumDefs());
-          if (!UseRC)
-            UseRC = RC;
-          else if (RC)
-            assert(UseRC == RC &&
-                   "Multiple uses expecting different register classes!");
-        }
-      }
-    }
-    MatchReg &= Match;
-    if (VRBase)
-      break;
-  }
-
-  MVT VT = Node->getValueType(ResNo);
-  const TargetRegisterClass *SrcRC = 0, *DstRC = 0;
-  SrcRC = TRI->getPhysicalRegisterRegClass(SrcReg, VT);
-  
-  // Figure out the register class to create for the destreg.
-  if (VRBase) {
-    DstRC = MRI.getRegClass(VRBase);
-  } else if (UseRC) {
-    assert(UseRC->hasType(VT) && "Incompatible phys register def and uses!");
-    DstRC = UseRC;
-  } else {
-    DstRC = TLI->getRegClassFor(VT);
-  }
-    
-  // If all uses are reading from the src physical register and copying the
-  // register is either impossible or very expensive, then don't create a copy.
-  if (MatchReg && SrcRC->getCopyCost() < 0) {
-    VRBase = SrcReg;
-  } else {
-    // Create the reg, emit the copy.
-    VRBase = MRI.createVirtualRegister(DstRC);
-    bool Emitted =
-      TII->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, DstRC, SrcRC);
-    Emitted = Emitted; // Silence compiler warning.
-    assert(Emitted && "Unable to issue a copy instruction!");
-  }
-
-  SDValue Op(Node, ResNo);
-  if (IsClone)
-    VRBaseMap.erase(Op);
-  bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second;
-  isNew = isNew; // Silence compiler warning.
-  assert(isNew && "Node emitted out of order - early");
-}
-
-/// getDstOfCopyToRegUse - If the only use of the specified result number of
-/// node is a CopyToReg, return its destination register. Return 0 otherwise.
-unsigned ScheduleDAG::getDstOfOnlyCopyToRegUse(SDNode *Node,
-                                               unsigned ResNo) const {
-  if (!Node->hasOneUse())
-    return 0;
-
-  SDNode *User = *Node->use_begin();
-  if (User->getOpcode() == ISD::CopyToReg && 
-      User->getOperand(2).getNode() == Node &&
-      User->getOperand(2).getResNo() == ResNo) {
-    unsigned Reg = cast<RegisterSDNode>(User->getOperand(1))->getReg();
-    if (TargetRegisterInfo::isVirtualRegister(Reg))
-      return Reg;
-  }
-  return 0;
-}
-
-void ScheduleDAG::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
-                                 const TargetInstrDesc &II,
-                                 DenseMap<SDValue, unsigned> &VRBaseMap) {
-  assert(Node->getMachineOpcode() != TargetInstrInfo::IMPLICIT_DEF &&
-         "IMPLICIT_DEF should have been handled as a special case elsewhere!");
-
-  for (unsigned i = 0; i < II.getNumDefs(); ++i) {
-    // If the specific node value is only used by a CopyToReg and the dest reg
-    // is a vreg, use the CopyToReg'd destination register instead of creating
-    // a new vreg.
-    unsigned VRBase = 0;
-    for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
-         UI != E; ++UI) {
-      SDNode *User = *UI;
-      if (User->getOpcode() == ISD::CopyToReg && 
-          User->getOperand(2).getNode() == Node &&
-          User->getOperand(2).getResNo() == i) {
-        unsigned Reg = cast<RegisterSDNode>(User->getOperand(1))->getReg();
-        if (TargetRegisterInfo::isVirtualRegister(Reg)) {
-          VRBase = Reg;
-          MI->addOperand(MachineOperand::CreateReg(Reg, true));
-          break;
-        }
-      }
-    }
-
-    // Create the result registers for this node and add the result regs to
-    // the machine instruction.
-    if (VRBase == 0) {
-      const TargetRegisterClass *RC = getInstrOperandRegClass(TRI, TII, II, i);
-      assert(RC && "Isn't a register operand!");
-      VRBase = MRI.createVirtualRegister(RC);
-      MI->addOperand(MachineOperand::CreateReg(VRBase, true));
-    }
-
-    SDValue Op(Node, i);
-    bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second;
-    isNew = isNew; // Silence compiler warning.
-    assert(isNew && "Node emitted out of order - early");
-  }
-}
-
-/// getVR - Return the virtual register corresponding to the specified result
-/// of the specified node.
-unsigned ScheduleDAG::getVR(SDValue Op,
-                            DenseMap<SDValue, unsigned> &VRBaseMap) {
-  if (Op.isMachineOpcode() &&
-      Op.getMachineOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
-    // Add an IMPLICIT_DEF instruction before every use.
-    unsigned VReg = getDstOfOnlyCopyToRegUse(Op.getNode(), Op.getResNo());
-    // IMPLICIT_DEF can produce any type of result so its TargetInstrDesc
-    // does not include operand register class info.
-    if (!VReg) {
-      const TargetRegisterClass *RC = TLI->getRegClassFor(Op.getValueType());
-      VReg = MRI.createVirtualRegister(RC);
-    }
-    BuildMI(BB, TII->get(TargetInstrInfo::IMPLICIT_DEF), VReg);
-    return VReg;
-  }
-
-  DenseMap<SDValue, unsigned>::iterator I = VRBaseMap.find(Op);
-  assert(I != VRBaseMap.end() && "Node emitted out of order - late");
-  return I->second;
-}
-
-
-/// AddOperand - Add the specified operand to the specified machine instr.  II
-/// specifies the instruction information for the node, and IIOpNum is the
-/// operand number (in the II) that we are adding. IIOpNum and II are used for 
-/// assertions only.
-void ScheduleDAG::AddOperand(MachineInstr *MI, SDValue Op,
-                             unsigned IIOpNum,
-                             const TargetInstrDesc *II,
-                             DenseMap<SDValue, unsigned> &VRBaseMap) {
-  if (Op.isMachineOpcode()) {
-    // Note that this case is redundant with the final else block, but we
-    // include it because it is the most common and it makes the logic
-    // simpler here.
-    assert(Op.getValueType() != MVT::Other &&
-           Op.getValueType() != MVT::Flag &&
-           "Chain and flag operands should occur at end of operand list!");
-    // Get/emit the operand.
-    unsigned VReg = getVR(Op, VRBaseMap);
-    const TargetInstrDesc &TID = MI->getDesc();
-    bool isOptDef = IIOpNum < TID.getNumOperands() &&
-      TID.OpInfo[IIOpNum].isOptionalDef();
-    MI->addOperand(MachineOperand::CreateReg(VReg, isOptDef));
-    
-    // Verify that it is right.
-    assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?");
-#ifndef NDEBUG
-    if (II) {
-      // There may be no register class for this operand if it is a variadic
-      // argument (RC will be NULL in this case).  In this case, we just assume
-      // the regclass is ok.
-      const TargetRegisterClass *RC =
-                          getInstrOperandRegClass(TRI, TII, *II, IIOpNum);
-      assert((RC || II->isVariadic()) && "Expected reg class info!");
-      const TargetRegisterClass *VRC = MRI.getRegClass(VReg);
-      if (RC && VRC != RC) {
-        cerr << "Register class of operand and regclass of use don't agree!\n";
-        cerr << "Operand = " << IIOpNum << "\n";
-        cerr << "Op->Val = "; Op.getNode()->dump(DAG); cerr << "\n";
-        cerr << "MI = "; MI->print(cerr);
-        cerr << "VReg = " << VReg << "\n";
-        cerr << "VReg RegClass     size = " << VRC->getSize()
-             << ", align = " << VRC->getAlignment() << "\n";
-        cerr << "Expected RegClass size = " << RC->getSize()
-             << ", align = " << RC->getAlignment() << "\n";
-        cerr << "Fatal error, aborting.\n";
-        abort();
-      }
-    }
-#endif
-  } else if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
-    MI->addOperand(MachineOperand::CreateImm(C->getZExtValue()));
-  } else if (ConstantFPSDNode *F = dyn_cast<ConstantFPSDNode>(Op)) {
-    const ConstantFP *CFP = F->getConstantFPValue();
-    MI->addOperand(MachineOperand::CreateFPImm(CFP));
-  } else if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(Op)) {
-    MI->addOperand(MachineOperand::CreateReg(R->getReg(), false));
-  } else if (GlobalAddressSDNode *TGA = dyn_cast<GlobalAddressSDNode>(Op)) {
-    MI->addOperand(MachineOperand::CreateGA(TGA->getGlobal(),TGA->getOffset()));
-  } else if (BasicBlockSDNode *BB = dyn_cast<BasicBlockSDNode>(Op)) {
-    MI->addOperand(MachineOperand::CreateMBB(BB->getBasicBlock()));
-  } else if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op)) {
-    MI->addOperand(MachineOperand::CreateFI(FI->getIndex()));
-  } else if (JumpTableSDNode *JT = dyn_cast<JumpTableSDNode>(Op)) {
-    MI->addOperand(MachineOperand::CreateJTI(JT->getIndex()));
-  } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op)) {
-    int Offset = CP->getOffset();
-    unsigned Align = CP->getAlignment();
-    const Type *Type = CP->getType();
-    // MachineConstantPool wants an explicit alignment.
-    if (Align == 0) {
-      Align = TM.getTargetData()->getPreferredTypeAlignmentShift(Type);
-      if (Align == 0) {
-        // Alignment of vector types.  FIXME!
-        Align = TM.getTargetData()->getABITypeSize(Type);
-        Align = Log2_64(Align);
-      }
-    }
-    
-    unsigned Idx;
-    if (CP->isMachineConstantPoolEntry())
-      Idx = ConstPool->getConstantPoolIndex(CP->getMachineCPVal(), Align);
-    else
-      Idx = ConstPool->getConstantPoolIndex(CP->getConstVal(), Align);
-    MI->addOperand(MachineOperand::CreateCPI(Idx, Offset));
-  } else if (ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op)) {
-    MI->addOperand(MachineOperand::CreateES(ES->getSymbol()));
-  } else {
-    assert(Op.getValueType() != MVT::Other &&
-           Op.getValueType() != MVT::Flag &&
-           "Chain and flag operands should occur at end of operand list!");
-    unsigned VReg = getVR(Op, VRBaseMap);
-    MI->addOperand(MachineOperand::CreateReg(VReg, false));
-    
-    // Verify that it is right.  Note that the reg class of the physreg and the
-    // vreg don't necessarily need to match, but the target copy insertion has
-    // to be able to handle it.  This handles things like copies from ST(0) to
-    // an FP vreg on x86.
-    assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?");
-    if (II && !II->isVariadic()) {
-      assert(getInstrOperandRegClass(TRI, TII, *II, IIOpNum) &&
-             "Don't have operand info for this instruction!");
-    }
-  }  
-}
-
-void ScheduleDAG::AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO) {
-  MI->addMemOperand(*MF, MO);
-}
-
-/// getSubRegisterRegClass - Returns the register class of specified register
-/// class' "SubIdx"'th sub-register class.
-static const TargetRegisterClass*
-getSubRegisterRegClass(const TargetRegisterClass *TRC, unsigned SubIdx) {
-  // Pick the register class of the subregister
-  TargetRegisterInfo::regclass_iterator I =
-    TRC->subregclasses_begin() + SubIdx-1;
-  assert(I < TRC->subregclasses_end() && 
-         "Invalid subregister index for register class");
-  return *I;
-}
-
-/// getSuperRegisterRegClass - Returns the register class of a superreg A whose
-/// "SubIdx"'th sub-register class is the specified register class and whose
-/// type matches the specified type.
-static const TargetRegisterClass*
-getSuperRegisterRegClass(const TargetRegisterClass *TRC,
-                         unsigned SubIdx, MVT VT) {
-  // Pick the register class of the superegister for this type
-  for (TargetRegisterInfo::regclass_iterator I = TRC->superregclasses_begin(),
-         E = TRC->superregclasses_end(); I != E; ++I)
-    if ((*I)->hasType(VT) && getSubRegisterRegClass(*I, SubIdx) == TRC)
-      return *I;
-  assert(false && "Couldn't find the register class");
-  return 0;
-}
-
-/// EmitSubregNode - Generate machine code for subreg nodes.
-///
-void ScheduleDAG::EmitSubregNode(SDNode *Node, 
-                           DenseMap<SDValue, unsigned> &VRBaseMap) {
-  unsigned VRBase = 0;
-  unsigned Opc = Node->getMachineOpcode();
-  
-  // If the node is only used by a CopyToReg and the dest reg is a vreg, use
-  // the CopyToReg'd destination register instead of creating a new vreg.
-  for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
-       UI != E; ++UI) {
-    SDNode *User = *UI;
-    if (User->getOpcode() == ISD::CopyToReg && 
-        User->getOperand(2).getNode() == Node) {
-      unsigned DestReg = cast<RegisterSDNode>(User->getOperand(1))->getReg();
-      if (TargetRegisterInfo::isVirtualRegister(DestReg)) {
-        VRBase = DestReg;
-        break;
-      }
-    }
-  }
-  
-  if (Opc == TargetInstrInfo::EXTRACT_SUBREG) {
-    unsigned SubIdx = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
-
-    // Create the extract_subreg machine instruction.
-    MachineInstr *MI = BuildMI(*MF, TII->get(TargetInstrInfo::EXTRACT_SUBREG));
-
-    // Figure out the register class to create for the destreg.
-    unsigned VReg = getVR(Node->getOperand(0), VRBaseMap);
-    const TargetRegisterClass *TRC = MRI.getRegClass(VReg);
-    const TargetRegisterClass *SRC = getSubRegisterRegClass(TRC, SubIdx);
-
-    if (VRBase) {
-      // Grab the destination register
-#ifndef NDEBUG
-      const TargetRegisterClass *DRC = MRI.getRegClass(VRBase);
-      assert(SRC && DRC && SRC == DRC && 
-             "Source subregister and destination must have the same class");
-#endif
-    } else {
-      // Create the reg
-      assert(SRC && "Couldn't find source register class");
-      VRBase = MRI.createVirtualRegister(SRC);
-    }
-    
-    // Add def, source, and subreg index
-    MI->addOperand(MachineOperand::CreateReg(VRBase, true));
-    AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap);
-    MI->addOperand(MachineOperand::CreateImm(SubIdx));
-    BB->push_back(MI);    
-  } else if (Opc == TargetInstrInfo::INSERT_SUBREG ||
-             Opc == TargetInstrInfo::SUBREG_TO_REG) {
-    SDValue N0 = Node->getOperand(0);
-    SDValue N1 = Node->getOperand(1);
-    SDValue N2 = Node->getOperand(2);
-    unsigned SubReg = getVR(N1, VRBaseMap);
-    unsigned SubIdx = cast<ConstantSDNode>(N2)->getZExtValue();
-    
-      
-    // Figure out the register class to create for the destreg.
-    const TargetRegisterClass *TRC = 0;
-    if (VRBase) {
-      TRC = MRI.getRegClass(VRBase);
-    } else {
-      TRC = getSuperRegisterRegClass(MRI.getRegClass(SubReg), SubIdx, 
-                                     Node->getValueType(0));
-      assert(TRC && "Couldn't determine register class for insert_subreg");
-      VRBase = MRI.createVirtualRegister(TRC); // Create the reg
-    }
-    
-    // Create the insert_subreg or subreg_to_reg machine instruction.
-    MachineInstr *MI = BuildMI(*MF, TII->get(Opc));
-    MI->addOperand(MachineOperand::CreateReg(VRBase, true));
-    
-    // If creating a subreg_to_reg, then the first input operand
-    // is an implicit value immediate, otherwise it's a register
-    if (Opc == TargetInstrInfo::SUBREG_TO_REG) {
-      const ConstantSDNode *SD = cast<ConstantSDNode>(N0);
-      MI->addOperand(MachineOperand::CreateImm(SD->getZExtValue()));
-    } else
-      AddOperand(MI, N0, 0, 0, VRBaseMap);
-    // Add the subregster being inserted
-    AddOperand(MI, N1, 0, 0, VRBaseMap);
-    MI->addOperand(MachineOperand::CreateImm(SubIdx));
-    BB->push_back(MI);
-  } else
-    assert(0 && "Node is not insert_subreg, extract_subreg, or subreg_to_reg");
-     
-  SDValue Op(Node, 0);
-  bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second;
-  isNew = isNew; // Silence compiler warning.
-  assert(isNew && "Node emitted out of order - early");
-}
-
-/// EmitNode - Generate machine code for an node and needed dependencies.
-///
-void ScheduleDAG::EmitNode(SDNode *Node, bool IsClone,
-                           DenseMap<SDValue, unsigned> &VRBaseMap) {
-  // If machine instruction
-  if (Node->isMachineOpcode()) {
-    unsigned Opc = Node->getMachineOpcode();
-    
-    // Handle subreg insert/extract specially
-    if (Opc == TargetInstrInfo::EXTRACT_SUBREG || 
-        Opc == TargetInstrInfo::INSERT_SUBREG ||
-        Opc == TargetInstrInfo::SUBREG_TO_REG) {
-      EmitSubregNode(Node, VRBaseMap);
-      return;
-    }
-
-    if (Opc == TargetInstrInfo::IMPLICIT_DEF)
-      // We want a unique VR for each IMPLICIT_DEF use.
-      return;
-    
-    const TargetInstrDesc &II = TII->get(Opc);
-    unsigned NumResults = CountResults(Node);
-    unsigned NodeOperands = CountOperands(Node);
-    unsigned MemOperandsEnd = ComputeMemOperandsEnd(Node);
-    bool HasPhysRegOuts = (NumResults > II.getNumDefs()) &&
-                          II.getImplicitDefs() != 0;
-#ifndef NDEBUG
-    unsigned NumMIOperands = NodeOperands + NumResults;
-    assert((II.getNumOperands() == NumMIOperands ||
-            HasPhysRegOuts || II.isVariadic()) &&
-           "#operands for dag node doesn't match .td file!"); 
-#endif
-
-    // Create the new machine instruction.
-    MachineInstr *MI = BuildMI(*MF, II);
-    
-    // Add result register values for things that are defined by this
-    // instruction.
-    if (NumResults)
-      CreateVirtualRegisters(Node, MI, II, VRBaseMap);
-    
-    // Emit all of the actual operands of this instruction, adding them to the
-    // instruction as appropriate.
-    for (unsigned i = 0; i != NodeOperands; ++i)
-      AddOperand(MI, Node->getOperand(i), i+II.getNumDefs(), &II, VRBaseMap);
-
-    // Emit all of the memory operands of this instruction
-    for (unsigned i = NodeOperands; i != MemOperandsEnd; ++i)
-      AddMemOperand(MI, cast<MemOperandSDNode>(Node->getOperand(i))->MO);
-
-    // Commute node if it has been determined to be profitable.
-    if (CommuteSet.count(Node)) {
-      MachineInstr *NewMI = TII->commuteInstruction(MI);
-      if (NewMI == 0)
-        DOUT << "Sched: COMMUTING FAILED!\n";
-      else {
-        DOUT << "Sched: COMMUTED TO: " << *NewMI;
-        if (MI != NewMI) {
-          MF->DeleteMachineInstr(MI);
-          MI = NewMI;
-        }
-        ++NumCommutes;
-      }
-    }
-
-    if (II.usesCustomDAGSchedInsertionHook())
-      // Insert this instruction into the basic block using a target
-      // specific inserter which may returns a new basic block.
-      BB = TLI->EmitInstrWithCustomInserter(MI, BB);
-    else
-      BB->push_back(MI);
-
-    // Additional results must be an physical register def.
-    if (HasPhysRegOuts) {
-      for (unsigned i = II.getNumDefs(); i < NumResults; ++i) {
-        unsigned Reg = II.getImplicitDefs()[i - II.getNumDefs()];
-        if (Node->hasAnyUseOfValue(i))
-          EmitCopyFromReg(Node, i, IsClone, Reg, VRBaseMap);
-      }
-    }
-    return;
-  }
-
-  switch (Node->getOpcode()) {
-  default:
-#ifndef NDEBUG
-    Node->dump(DAG);
-#endif
-    assert(0 && "This target-independent node should have been selected!");
-    break;
-  case ISD::EntryToken:
-    assert(0 && "EntryToken should have been excluded from the schedule!");
-    break;
-  case ISD::TokenFactor: // fall thru
-    break;
-  case ISD::CopyToReg: {
-    unsigned SrcReg;
-    SDValue SrcVal = Node->getOperand(2);
-    if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(SrcVal))
-      SrcReg = R->getReg();
-    else
-      SrcReg = getVR(SrcVal, VRBaseMap);
-      
-    unsigned DestReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
-    if (SrcReg == DestReg) // Coalesced away the copy? Ignore.
-      break;
-      
-    const TargetRegisterClass *SrcTRC = 0, *DstTRC = 0;
-    // Get the register classes of the src/dst.
-    if (TargetRegisterInfo::isVirtualRegister(SrcReg))
-      SrcTRC = MRI.getRegClass(SrcReg);
-    else
-      SrcTRC = TRI->getPhysicalRegisterRegClass(SrcReg,SrcVal.getValueType());
-
-    if (TargetRegisterInfo::isVirtualRegister(DestReg))
-      DstTRC = MRI.getRegClass(DestReg);
-    else
-      DstTRC = TRI->getPhysicalRegisterRegClass(DestReg,
-                                            Node->getOperand(1).getValueType());
-    TII->copyRegToReg(*BB, BB->end(), DestReg, SrcReg, DstTRC, SrcTRC);
-    break;
-  }
-  case ISD::CopyFromReg: {
-    unsigned SrcReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
-    EmitCopyFromReg(Node, 0, IsClone, SrcReg, VRBaseMap);
-    break;
-  }
-  case ISD::INLINEASM: {
-    unsigned NumOps = Node->getNumOperands();
-    if (Node->getOperand(NumOps-1).getValueType() == MVT::Flag)
-      --NumOps;  // Ignore the flag operand.
-      
-    // Create the inline asm machine instruction.
-    MachineInstr *MI = BuildMI(*MF, TII->get(TargetInstrInfo::INLINEASM));
-
-    // Add the asm string as an external symbol operand.
-    const char *AsmStr =
-      cast<ExternalSymbolSDNode>(Node->getOperand(1))->getSymbol();
-    MI->addOperand(MachineOperand::CreateES(AsmStr));
-      
-    // Add all of the operand registers to the instruction.
-    for (unsigned i = 2; i != NumOps;) {
-      unsigned Flags =
-        cast<ConstantSDNode>(Node->getOperand(i))->getZExtValue();
-      unsigned NumVals = Flags >> 3;
-        
-      MI->addOperand(MachineOperand::CreateImm(Flags));
-      ++i;  // Skip the ID value.
-        
-      switch (Flags & 7) {
-      default: assert(0 && "Bad flags!");
-      case 2:   // Def of register.
-        for (; NumVals; --NumVals, ++i) {
-          unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
-          MI->addOperand(MachineOperand::CreateReg(Reg, true));
-        }
-        break;
-      case 6:   // Def of earlyclobber register.
-        for (; NumVals; --NumVals, ++i) {
-          unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
-          MI->addOperand(MachineOperand::CreateReg(Reg, true, false, false, 
-                                                   false, 0, true));
-        }
-        break;
-      case 1:  // Use of register.
-      case 3:  // Immediate.
-      case 4:  // Addressing mode.
-        // The addressing mode has been selected, just add all of the
-        // operands to the machine instruction.
-        for (; NumVals; --NumVals, ++i)
-          AddOperand(MI, Node->getOperand(i), 0, 0, VRBaseMap);
-        break;
-      }
-    }
-    BB->push_back(MI);
-    break;
-  }
-  }
-}
-
-void ScheduleDAG::EmitNoop() {
-  TII->insertNoop(*BB, BB->end());
-}
-
-void ScheduleDAG::EmitCrossRCCopy(SUnit *SU,
-                                  DenseMap<SUnit*, unsigned> &VRBaseMap) {
-  for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
-       I != E; ++I) {
-    if (I->isCtrl) continue;  // ignore chain preds
-    if (!I->Dep->getNode()) {
-      // Copy to physical register.
-      DenseMap<SUnit*, unsigned>::iterator VRI = VRBaseMap.find(I->Dep);
-      assert(VRI != VRBaseMap.end() && "Node emitted out of order - late");
-      // Find the destination physical register.
-      unsigned Reg = 0;
-      for (SUnit::const_succ_iterator II = SU->Succs.begin(),
-             EE = SU->Succs.end(); II != EE; ++II) {
-        if (I->Reg) {
-          Reg = I->Reg;
-          break;
-        }
-      }
-      assert(I->Reg && "Unknown physical register!");
-      TII->copyRegToReg(*BB, BB->end(), Reg, VRI->second,
-                        SU->CopyDstRC, SU->CopySrcRC);
-    } else {
-      // Copy from physical register.
-      assert(I->Reg && "Unknown physical register!");
-      unsigned VRBase = MRI.createVirtualRegister(SU->CopyDstRC);
-      bool isNew = VRBaseMap.insert(std::make_pair(SU, VRBase)).second;
-      isNew = isNew; // Silence compiler warning.
-      assert(isNew && "Node emitted out of order - early");
-      TII->copyRegToReg(*BB, BB->end(), VRBase, I->Reg,
-                        SU->CopyDstRC, SU->CopySrcRC);
-    }
-    break;
-  }
-}
-
-/// EmitSchedule - Emit the machine code in scheduled order.
-MachineBasicBlock *ScheduleDAG::EmitSchedule() {
-  // For post-regalloc scheduling, we're rescheduling the instructions in the
-  // block, so start by removing them from the block.
-  if (!DAG)
-    while (!BB->empty())
-      BB->remove(BB->begin());
-
-  DenseMap<SDValue, unsigned> VRBaseMap;
-  DenseMap<SUnit*, unsigned> CopyVRBaseMap;
-  for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
-    SUnit *SU = Sequence[i];
-    if (!SU) {
-      // Null SUnit* is a noop.
-      EmitNoop();
-      continue;
-    }
-
-    // For post-regalloc scheduling, we already have the instruction;
-    // just append it to the block.
-    if (!DAG) {
-      BB->push_back(SU->getInstr());
-      continue;
-    }
-
-    // For pre-regalloc scheduling, create instructions corresponding to the
-    // SDNode and any flagged SDNodes and append them to the block.
-    SmallVector<SDNode *, 4> FlaggedNodes;
-    for (SDNode *N = SU->getNode()->getFlaggedNode(); N; N = N->getFlaggedNode())
-      FlaggedNodes.push_back(N);
-    while (!FlaggedNodes.empty()) {
-      EmitNode(FlaggedNodes.back(), SU->OrigNode != SU, VRBaseMap);
-      FlaggedNodes.pop_back();
-    }
-    if (!SU->getNode())
-      EmitCrossRCCopy(SU, CopyVRBaseMap);
-    else
-      EmitNode(SU->getNode(), SU->OrigNode != SU, VRBaseMap);
-  }
-
-  return BB;
-}

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp?rev=59676&r1=59675&r2=59676&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Wed Nov 19 17:18:57 2008
@@ -12,7 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "pre-RA-sched"
-#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/ScheduleDAGSDNodes.h"
 #include "llvm/CodeGen/SchedulerRegistry.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetData.h"
@@ -58,7 +58,7 @@
 //===----------------------------------------------------------------------===//
 /// ScheduleDAGFast - The actual "fast" list scheduler implementation.
 ///
-class VISIBILITY_HIDDEN ScheduleDAGFast : public ScheduleDAG {
+class VISIBILITY_HIDDEN ScheduleDAGFast : public ScheduleDAGSDNodes {
 private:
   /// AvailableQueue - The priority queue to use for the available SUnits.
   FastPriorityQueue AvailableQueue;
@@ -73,7 +73,7 @@
 public:
   ScheduleDAGFast(SelectionDAG *dag, MachineBasicBlock *bb,
                   const TargetMachine &tm)
-    : ScheduleDAG(dag, bb, tm) {}
+    : ScheduleDAGSDNodes(dag, bb, tm) {}
 
   void Schedule();
 

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=59676&r1=59675&r2=59676&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Wed Nov 19 17:18:57 2008
@@ -19,7 +19,8 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "pre-RA-sched"
-#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/LatencyPriorityQueue.h"
+#include "llvm/CodeGen/ScheduleDAGSDNodes.h"
 #include "llvm/CodeGen/SchedulerRegistry.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
 #include "llvm/Target/TargetRegisterInfo.h"
@@ -30,7 +31,6 @@
 #include "llvm/Support/Compiler.h"
 #include "llvm/ADT/PriorityQueue.h"
 #include "llvm/ADT/Statistic.h"
-#include "LatencyPriorityQueue.h"
 #include <climits>
 using namespace llvm;
 
@@ -46,7 +46,7 @@
 /// ScheduleDAGList - The actual list scheduler implementation.  This supports
 /// top-down scheduling.
 ///
-class VISIBILITY_HIDDEN ScheduleDAGList : public ScheduleDAG {
+class VISIBILITY_HIDDEN ScheduleDAGList : public ScheduleDAGSDNodes {
 private:
   /// AvailableQueue - The priority queue to use for the available SUnits.
   ///
@@ -66,7 +66,7 @@
                   const TargetMachine &tm,
                   SchedulingPriorityQueue *availqueue,
                   HazardRecognizer *HR)
-    : ScheduleDAG(dag, bb, tm),
+    : ScheduleDAGSDNodes(dag, bb, tm),
       AvailableQueue(availqueue), HazardRec(HR) {
     }
 
@@ -212,13 +212,13 @@
         if (!N) break;
         FoundNode = N;
       }
-      
+    
       HazardRecognizer::HazardType HT = HazardRec->getHazardType(FoundNode);
       if (HT == HazardRecognizer::NoHazard) {
         FoundSUnit = CurSUnit;
         break;
       }
-      
+    
       // Remember if this is a noop hazard.
       HasNoopHazards |= HT == HazardRecognizer::NoopHazard;
       

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=59676&r1=59675&r2=59676&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Nov 19 17:18:57 2008
@@ -16,7 +16,7 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "pre-RA-sched"
-#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/ScheduleDAGSDNodes.h"
 #include "llvm/CodeGen/SchedulerRegistry.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetData.h"
@@ -53,7 +53,7 @@
 /// ScheduleDAGRRList - The actual register reduction list scheduler
 /// implementation.  This supports both top-down and bottom-up scheduling.
 ///
-class VISIBILITY_HIDDEN ScheduleDAGRRList : public ScheduleDAG {
+class VISIBILITY_HIDDEN ScheduleDAGRRList : public ScheduleDAGSDNodes {
 private:
   /// isBottomUp - This is true if the scheduling problem is bottom-up, false if
   /// it is top-down.
@@ -77,7 +77,7 @@
   ScheduleDAGRRList(SelectionDAG *dag, MachineBasicBlock *bb,
                     const TargetMachine &tm, bool isbottomup, bool f,
                     SchedulingPriorityQueue *availqueue)
-    : ScheduleDAG(dag, bb, tm), isBottomUp(isbottomup), Fast(f),
+    : ScheduleDAGSDNodes(dag, bb, tm), isBottomUp(isbottomup), Fast(f),
       AvailableQueue(availqueue) {
     }
 

Copied: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp (from r59324, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp?p2=llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp&p1=llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp&r1=59324&r2=59676&rev=59676&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Wed Nov 19 17:18:57 2008
@@ -1,4 +1,4 @@
-//===---- ScheduleDAG.cpp - Implement the ScheduleDAG class ---------------===//
+//===--- ScheduleDAGSDNodes.cpp - Implement the ScheduleDAGSDNodes class --===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -13,21 +13,28 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "pre-RA-sched"
-#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/ScheduleDAGSDNodes.h"
+#include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
 using namespace llvm;
 
-ScheduleDAG::ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb,
-                         const TargetMachine &tm)
-  : DAG(dag), BB(bb), TM(tm), MRI(BB->getParent()->getRegInfo()) {
-  TII = TM.getInstrInfo();
-  MF  = BB->getParent();
-  TRI = TM.getRegisterInfo();
-  TLI = TM.getTargetLowering();
-  ConstPool = MF->getConstantPool();
+ScheduleDAGSDNodes::ScheduleDAGSDNodes(SelectionDAG *dag, MachineBasicBlock *bb,
+                                       const TargetMachine &tm)
+  : ScheduleDAG(dag, bb, tm) {
+}
+
+SUnit *ScheduleDAGSDNodes::Clone(SUnit *Old) {
+  SUnit *SU = NewSUnit(Old->getNode());
+  SU->OrigNode = Old->OrigNode;
+  SU->Latency = Old->Latency;
+  SU->isTwoAddress = Old->isTwoAddress;
+  SU->isCommutable = Old->isCommutable;
+  SU->hasPhysRegDefs = Old->hasPhysRegDefs;
+  return SU;
 }
 
 /// CheckForPhysRegDependency - Check if the dependency between def and use of
@@ -57,28 +64,10 @@
   }
 }
 
-SUnit *ScheduleDAG::Clone(SUnit *Old) {
-  SUnit *SU = NewSUnit(Old->getNode());
-  SU->OrigNode = Old->OrigNode;
-  SU->Latency = Old->Latency;
-  SU->isTwoAddress = Old->isTwoAddress;
-  SU->isCommutable = Old->isCommutable;
-  SU->hasPhysRegDefs = Old->hasPhysRegDefs;
-  return SU;
-}
-
-
 /// BuildSchedUnits - Build SUnits from the selection dag that we are input.
 /// This SUnit graph is similar to the SelectionDAG, but represents flagged
 /// together nodes with a single SUnit.
-void ScheduleDAG::BuildSchedUnits() {
-  // For post-regalloc scheduling, build the SUnits from the MachineInstrs
-  // in the MachineBasicBlock.
-  if (!DAG) {
-    BuildSchedUnitsFromMBB();
-    return;
-  }
-
+void ScheduleDAGSDNodes::BuildSchedUnits() {
   // Reserve entries in the vector for each of the SUnits we are creating.  This
   // ensure that reallocation of the vector won't happen, so SUnit*'s won't get
   // invalidated.
@@ -192,84 +181,7 @@
   }
 }
 
-void ScheduleDAG::BuildSchedUnitsFromMBB() {
-  SUnits.clear();
-  SUnits.reserve(BB->size());
-
-  std::vector<SUnit *> PendingLoads;
-  SUnit *Terminator = 0;
-  SUnit *Chain = 0;
-  SUnit *Defs[TargetRegisterInfo::FirstVirtualRegister] = {};
-  std::vector<SUnit *> Uses[TargetRegisterInfo::FirstVirtualRegister] = {};
-  int Cost = 1; // FIXME
-
-  for (MachineBasicBlock::iterator MII = BB->end(), MIE = BB->begin();
-       MII != MIE; --MII) {
-    MachineInstr *MI = prior(MII);
-    SUnit *SU = NewSUnit(MI);
-
-    for (unsigned j = 0, n = MI->getNumOperands(); j != n; ++j) {
-      const MachineOperand &MO = MI->getOperand(j);
-      if (!MO.isReg()) continue;
-      unsigned Reg = MO.getReg();
-      if (Reg == 0) continue;
-
-      assert(TRI->isPhysicalRegister(Reg) && "Virtual register encountered!");
-      std::vector<SUnit *> &UseList = Uses[Reg];
-      SUnit *&Def = Defs[Reg];
-      // Optionally add output and anti dependences
-      if (Def && Def != SU)
-        Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false,
-                     /*PhyReg=*/Reg, Cost);
-      for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
-        SUnit *&Def = Defs[*Alias];
-        if (Def && Def != SU)
-          Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false,
-                       /*PhyReg=*/*Alias, Cost);
-      }
-
-      if (MO.isDef()) {
-        // Add any data dependencies.
-        for (unsigned i = 0, e = UseList.size(); i != e; ++i)
-          if (UseList[i] != SU)
-            UseList[i]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false,
-                                /*PhysReg=*/Reg, Cost);
-        for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
-          std::vector<SUnit *> &UseList = Uses[*Alias];
-          for (unsigned i = 0, e = UseList.size(); i != e; ++i)
-            if (UseList[i] != SU)
-              UseList[i]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false,
-                                  /*PhysReg=*/*Alias, Cost);
-        }
-
-        UseList.clear();
-        Def = SU;
-      } else {
-        UseList.push_back(SU);
-      }
-    }
-    bool False = false;
-    bool True = true;
-    if (!MI->isSafeToMove(TII, False)) {
-      if (Chain)
-        Chain->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false);
-      for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k)
-        PendingLoads[k]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false);
-      PendingLoads.clear();
-      Chain = SU;
-    } else if (!MI->isSafeToMove(TII, True)) {
-      if (Chain)
-        Chain->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false);
-      PendingLoads.push_back(SU);
-    }
-    if (Terminator && SU->Succs.empty())
-      Terminator->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false);
-    if (MI->getDesc().isTerminator())
-      Terminator = SU;
-  }
-}
-
-void ScheduleDAG::ComputeLatency(SUnit *SU) {
+void ScheduleDAGSDNodes::ComputeLatency(SUnit *SU) {
   const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
   
   // Compute the latency for the node.  We use the sum of the latencies for
@@ -292,119 +204,10 @@
   }
 }
 
-/// CalculateDepths - compute depths using algorithms for the longest
-/// paths in the DAG
-void ScheduleDAG::CalculateDepths() {
-  unsigned DAGSize = SUnits.size();
-  std::vector<SUnit*> WorkList;
-  WorkList.reserve(DAGSize);
-
-  // Initialize the data structures
-  for (unsigned i = 0, e = DAGSize; i != e; ++i) {
-    SUnit *SU = &SUnits[i];
-    unsigned Degree = SU->Preds.size();
-    // Temporarily use the Depth field as scratch space for the degree count.
-    SU->Depth = Degree;
-
-    // Is it a node without dependencies?
-    if (Degree == 0) {
-        assert(SU->Preds.empty() && "SUnit should have no predecessors");
-        // Collect leaf nodes
-        WorkList.push_back(SU);
-    }
-  }
-
-  // Process nodes in the topological order
-  while (!WorkList.empty()) {
-    SUnit *SU = WorkList.back();
-    WorkList.pop_back();
-    unsigned SUDepth = 0;
-
-    // Use dynamic programming:
-    // When current node is being processed, all of its dependencies
-    // are already processed.
-    // So, just iterate over all predecessors and take the longest path
-    for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
-         I != E; ++I) {
-      unsigned PredDepth = I->Dep->Depth;
-      if (PredDepth+1 > SUDepth) {
-          SUDepth = PredDepth + 1;
-      }
-    }
-
-    SU->Depth = SUDepth;
-
-    // Update degrees of all nodes depending on current SUnit
-    for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
-         I != E; ++I) {
-      SUnit *SU = I->Dep;
-      if (!--SU->Depth)
-        // If all dependencies of the node are processed already,
-        // then the longest path for the node can be computed now
-        WorkList.push_back(SU);
-    }
-  }
-}
-
-/// CalculateHeights - compute heights using algorithms for the longest
-/// paths in the DAG
-void ScheduleDAG::CalculateHeights() {
-  unsigned DAGSize = SUnits.size();
-  std::vector<SUnit*> WorkList;
-  WorkList.reserve(DAGSize);
-
-  // Initialize the data structures
-  for (unsigned i = 0, e = DAGSize; i != e; ++i) {
-    SUnit *SU = &SUnits[i];
-    unsigned Degree = SU->Succs.size();
-    // Temporarily use the Height field as scratch space for the degree count.
-    SU->Height = Degree;
-
-    // Is it a node without dependencies?
-    if (Degree == 0) {
-        assert(SU->Succs.empty() && "Something wrong");
-        assert(WorkList.empty() && "Should be empty");
-        // Collect leaf nodes
-        WorkList.push_back(SU);
-    }
-  }
-
-  // Process nodes in the topological order
-  while (!WorkList.empty()) {
-    SUnit *SU = WorkList.back();
-    WorkList.pop_back();
-    unsigned SUHeight = 0;
-
-    // Use dynamic programming:
-    // When current node is being processed, all of its dependencies
-    // are already processed.
-    // So, just iterate over all successors and take the longest path
-    for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
-         I != E; ++I) {
-      unsigned SuccHeight = I->Dep->Height;
-      if (SuccHeight+1 > SUHeight) {
-          SUHeight = SuccHeight + 1;
-      }
-    }
-
-    SU->Height = SUHeight;
-
-    // Update degrees of all nodes depending on current SUnit
-    for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
-         I != E; ++I) {
-      SUnit *SU = I->Dep;
-      if (!--SU->Height)
-        // If all dependencies of the node are processed already,
-        // then the longest path for the node can be computed now
-        WorkList.push_back(SU);
-    }
-  }
-}
-
 /// 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 resulting MachineInstr).
-unsigned ScheduleDAG::CountResults(SDNode *Node) {
+unsigned ScheduleDAGSDNodes::CountResults(SDNode *Node) {
   unsigned N = Node->getNumValues();
   while (N && Node->getValueType(N - 1) == MVT::Flag)
     --N;
@@ -417,7 +220,7 @@
 /// followed by special operands that describe memory references, then an
 /// optional chain operand, then an optional flag operand.  Compute the number
 /// of actual operands that will go into the resulting MachineInstr.
-unsigned ScheduleDAG::CountOperands(SDNode *Node) {
+unsigned ScheduleDAGSDNodes::CountOperands(SDNode *Node) {
   unsigned N = ComputeMemOperandsEnd(Node);
   while (N && isa<MemOperandSDNode>(Node->getOperand(N - 1).getNode()))
     --N; // Ignore MEMOPERAND nodes
@@ -426,7 +229,7 @@
 
 /// ComputeMemOperandsEnd - Find the index one past the last MemOperandSDNode
 /// operand
-unsigned ScheduleDAG::ComputeMemOperandsEnd(SDNode *Node) {
+unsigned ScheduleDAGSDNodes::ComputeMemOperandsEnd(SDNode *Node) {
   unsigned N = Node->getNumOperands();
   while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag)
     --N;
@@ -436,83 +239,19 @@
 }
 
 
-/// dump - dump the schedule.
-void ScheduleDAG::dumpSchedule() const {
-  for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
-    if (SUnit *SU = Sequence[i])
-      SU->dump(DAG);
-    else
-      cerr << "**** NOOP ****\n";
-  }
-}
-
-
-/// Run - perform scheduling.
-///
-void ScheduleDAG::Run() {
-  Schedule();
-  
-  DOUT << "*** Final schedule ***\n";
-  DEBUG(dumpSchedule());
-  DOUT << "\n";
-}
-
-/// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
-/// a group of nodes flagged together.
-void SUnit::dump(const SelectionDAG *G) const {
-  cerr << "SU(" << NodeNum << "): ";
-  if (getNode())
-    getNode()->dump(G);
+void ScheduleDAGSDNodes::dumpNode(const SUnit *SU) const {
+  if (SU->getNode())
+    SU->getNode()->dump(DAG);
   else
     cerr << "CROSS RC COPY ";
   cerr << "\n";
   SmallVector<SDNode *, 4> FlaggedNodes;
-  for (SDNode *N = getNode()->getFlaggedNode(); N; N = N->getFlaggedNode())
+  for (SDNode *N = SU->getNode()->getFlaggedNode(); N; N = N->getFlaggedNode())
     FlaggedNodes.push_back(N);
   while (!FlaggedNodes.empty()) {
     cerr << "    ";
-    FlaggedNodes.back()->dump(G);
+    FlaggedNodes.back()->dump(DAG);
     cerr << "\n";
     FlaggedNodes.pop_back();
   }
 }
-
-void SUnit::dumpAll(const SelectionDAG *G) const {
-  dump(G);
-
-  cerr << "  # preds left       : " << NumPredsLeft << "\n";
-  cerr << "  # succs left       : " << NumSuccsLeft << "\n";
-  cerr << "  Latency            : " << Latency << "\n";
-  cerr << "  Depth              : " << Depth << "\n";
-  cerr << "  Height             : " << Height << "\n";
-
-  if (Preds.size() != 0) {
-    cerr << "  Predecessors:\n";
-    for (SUnit::const_succ_iterator I = Preds.begin(), E = Preds.end();
-         I != E; ++I) {
-      if (I->isCtrl)
-        cerr << "   ch  #";
-      else
-        cerr << "   val #";
-      cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")";
-      if (I->isSpecial)
-        cerr << " *";
-      cerr << "\n";
-    }
-  }
-  if (Succs.size() != 0) {
-    cerr << "  Successors:\n";
-    for (SUnit::const_succ_iterator I = Succs.begin(), E = Succs.end();
-         I != E; ++I) {
-      if (I->isCtrl)
-        cerr << "   ch  #";
-      else
-        cerr << "   val #";
-      cerr << I->Dep << " - SU(" << I->Dep->NodeNum << ")";
-      if (I->isSpecial)
-        cerr << " *";
-      cerr << "\n";
-    }
-  }
-  cerr << "\n";
-}

Copied: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp (from r59282, llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp?p2=llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp&p1=llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp&r1=59282&r2=59676&rev=59676&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp Wed Nov 19 17:18:57 2008
@@ -13,7 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "pre-RA-sched"
-#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/ScheduleDAGSDNodes.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -47,9 +47,9 @@
 
 /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
 /// implicit physical register output.
-void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
-                                  bool IsClone, unsigned SrcReg,
-                                  DenseMap<SDValue, unsigned> &VRBaseMap) {
+void ScheduleDAGSDNodes::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
+                                         bool IsClone, unsigned SrcReg,
+                                         DenseMap<SDValue, unsigned> &VRBaseMap) {
   unsigned VRBase = 0;
   if (TargetRegisterInfo::isVirtualRegister(SrcReg)) {
     // Just use the input register directly!
@@ -142,8 +142,8 @@
 
 /// getDstOfCopyToRegUse - If the only use of the specified result number of
 /// node is a CopyToReg, return its destination register. Return 0 otherwise.
-unsigned ScheduleDAG::getDstOfOnlyCopyToRegUse(SDNode *Node,
-                                               unsigned ResNo) const {
+unsigned ScheduleDAGSDNodes::getDstOfOnlyCopyToRegUse(SDNode *Node,
+                                                      unsigned ResNo) const {
   if (!Node->hasOneUse())
     return 0;
 
@@ -158,7 +158,7 @@
   return 0;
 }
 
-void ScheduleDAG::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
+void ScheduleDAGSDNodes::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
                                  const TargetInstrDesc &II,
                                  DenseMap<SDValue, unsigned> &VRBaseMap) {
   assert(Node->getMachineOpcode() != TargetInstrInfo::IMPLICIT_DEF &&
@@ -202,8 +202,8 @@
 
 /// getVR - Return the virtual register corresponding to the specified result
 /// of the specified node.
-unsigned ScheduleDAG::getVR(SDValue Op,
-                            DenseMap<SDValue, unsigned> &VRBaseMap) {
+unsigned ScheduleDAGSDNodes::getVR(SDValue Op,
+                                   DenseMap<SDValue, unsigned> &VRBaseMap) {
   if (Op.isMachineOpcode() &&
       Op.getMachineOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
     // Add an IMPLICIT_DEF instruction before every use.
@@ -228,10 +228,10 @@
 /// specifies the instruction information for the node, and IIOpNum is the
 /// operand number (in the II) that we are adding. IIOpNum and II are used for 
 /// assertions only.
-void ScheduleDAG::AddOperand(MachineInstr *MI, SDValue Op,
-                             unsigned IIOpNum,
-                             const TargetInstrDesc *II,
-                             DenseMap<SDValue, unsigned> &VRBaseMap) {
+void ScheduleDAGSDNodes::AddOperand(MachineInstr *MI, SDValue Op,
+                                    unsigned IIOpNum,
+                                    const TargetInstrDesc *II,
+                                    DenseMap<SDValue, unsigned> &VRBaseMap) {
   if (Op.isMachineOpcode()) {
     // Note that this case is redundant with the final else block, but we
     // include it because it is the most common and it makes the logic
@@ -328,10 +328,6 @@
   }  
 }
 
-void ScheduleDAG::AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO) {
-  MI->addMemOperand(*MF, MO);
-}
-
 /// getSubRegisterRegClass - Returns the register class of specified register
 /// class' "SubIdx"'th sub-register class.
 static const TargetRegisterClass*
@@ -361,8 +357,8 @@
 
 /// EmitSubregNode - Generate machine code for subreg nodes.
 ///
-void ScheduleDAG::EmitSubregNode(SDNode *Node, 
-                           DenseMap<SDValue, unsigned> &VRBaseMap) {
+void ScheduleDAGSDNodes::EmitSubregNode(SDNode *Node, 
+                                        DenseMap<SDValue, unsigned> &VRBaseMap) {
   unsigned VRBase = 0;
   unsigned Opc = Node->getMachineOpcode();
   
@@ -456,8 +452,8 @@
 
 /// EmitNode - Generate machine code for an node and needed dependencies.
 ///
-void ScheduleDAG::EmitNode(SDNode *Node, bool IsClone,
-                           DenseMap<SDValue, unsigned> &VRBaseMap) {
+void ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone,
+                                  DenseMap<SDValue, unsigned> &VRBaseMap) {
   // If machine instruction
   if (Node->isMachineOpcode()) {
     unsigned Opc = Node->getMachineOpcode();
@@ -634,53 +630,8 @@
   }
 }
 
-void ScheduleDAG::EmitNoop() {
-  TII->insertNoop(*BB, BB->end());
-}
-
-void ScheduleDAG::EmitCrossRCCopy(SUnit *SU,
-                                  DenseMap<SUnit*, unsigned> &VRBaseMap) {
-  for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
-       I != E; ++I) {
-    if (I->isCtrl) continue;  // ignore chain preds
-    if (!I->Dep->getNode()) {
-      // Copy to physical register.
-      DenseMap<SUnit*, unsigned>::iterator VRI = VRBaseMap.find(I->Dep);
-      assert(VRI != VRBaseMap.end() && "Node emitted out of order - late");
-      // Find the destination physical register.
-      unsigned Reg = 0;
-      for (SUnit::const_succ_iterator II = SU->Succs.begin(),
-             EE = SU->Succs.end(); II != EE; ++II) {
-        if (I->Reg) {
-          Reg = I->Reg;
-          break;
-        }
-      }
-      assert(I->Reg && "Unknown physical register!");
-      TII->copyRegToReg(*BB, BB->end(), Reg, VRI->second,
-                        SU->CopyDstRC, SU->CopySrcRC);
-    } else {
-      // Copy from physical register.
-      assert(I->Reg && "Unknown physical register!");
-      unsigned VRBase = MRI.createVirtualRegister(SU->CopyDstRC);
-      bool isNew = VRBaseMap.insert(std::make_pair(SU, VRBase)).second;
-      isNew = isNew; // Silence compiler warning.
-      assert(isNew && "Node emitted out of order - early");
-      TII->copyRegToReg(*BB, BB->end(), VRBase, I->Reg,
-                        SU->CopyDstRC, SU->CopySrcRC);
-    }
-    break;
-  }
-}
-
 /// EmitSchedule - Emit the machine code in scheduled order.
-MachineBasicBlock *ScheduleDAG::EmitSchedule() {
-  // For post-regalloc scheduling, we're rescheduling the instructions in the
-  // block, so start by removing them from the block.
-  if (!DAG)
-    while (!BB->empty())
-      BB->remove(BB->begin());
-
+MachineBasicBlock *ScheduleDAGSDNodes::EmitSchedule() {
   DenseMap<SDValue, unsigned> VRBaseMap;
   DenseMap<SUnit*, unsigned> CopyVRBaseMap;
   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
@@ -691,13 +642,6 @@
       continue;
     }
 
-    // For post-regalloc scheduling, we already have the instruction;
-    // just append it to the block.
-    if (!DAG) {
-      BB->push_back(SU->getInstr());
-      continue;
-    }
-
     // For pre-regalloc scheduling, create instructions corresponding to the
     // SDNode and any flagged SDNodes and append them to the block.
     SmallVector<SDNode *, 4> FlaggedNodes;

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=59676&r1=59675&r2=59676&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Nov 19 17:18:57 2008
@@ -34,7 +34,7 @@
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/ScheduleDAGSDNodes.h"
 #include "llvm/CodeGen/SchedulerRegistry.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/Target/TargetRegisterInfo.h"

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp?rev=59676&r1=59675&r2=59676&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Wed Nov 19 17:18:57 2008
@@ -15,7 +15,7 @@
 #include "llvm/Function.h"
 #include "llvm/Assembly/Writer.h"
 #include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/ScheduleDAGSDNodes.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
@@ -383,71 +383,7 @@
 #endif
 }
 
-namespace llvm {
-  template<>
-  struct DOTGraphTraits<ScheduleDAG*> : public DefaultDOTGraphTraits {
-    static std::string getGraphName(const ScheduleDAG *G) {
-      return G->MF->getFunction()->getName();
-    }
-
-    static bool renderGraphFromBottomUp() {
-      return true;
-    }
-    
-    static bool hasNodeAddressLabel(const SUnit *Node,
-                                    const ScheduleDAG *Graph) {
-      return true;
-    }
-    
-    /// If you want to override the dot attributes printed for a particular
-    /// edge, override this method.
-    template<typename EdgeIter>
-    static std::string getEdgeAttributes(const void *Node, EdgeIter EI) {
-      if (EI.isSpecialDep())
-        return "color=cyan,style=dashed";
-      if (EI.isCtrlDep())
-        return "color=blue,style=dashed";
-      return "";
-    }
-    
-
-    static std::string getNodeLabel(const SUnit *Node,
-                                    const ScheduleDAG *Graph);
-    static std::string getNodeAttributes(const SUnit *N,
-                                         const ScheduleDAG *Graph) {
-      return "shape=Mrecord";
-    }
-
-    static void addCustomGraphFeatures(ScheduleDAG *G,
-                                       GraphWriter<ScheduleDAG*> &GW) {
-      // Draw a special "GraphRoot" node to indicate the root of the graph.
-      GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot");
-      if (G->DAG) {
-        // For an SDNode-based ScheduleDAG, point to the root of the ScheduleDAG.
-        const SDNode *N = G->DAG->getRoot().getNode();
-        if (N && N->getNodeId() != -1)
-          GW.emitEdge(0, -1, &G->SUnits[N->getNodeId()], -1,
-                      "color=blue,style=dashed");
-      } else {
-        // For a MachineInstr-based ScheduleDAG, find a root to point to.
-        for (unsigned i = 0, e = G->SUnits.size(); i != e; ++i) {
-          if (G->SUnits[i].Succs.empty()) {
-            GW.emitEdge(0, -1, &G->SUnits[i], -1,
-                        "color=blue,style=dashed");
-            break;
-          }
-        }
-      }
-    }
-  };
-}
-
-std::string DOTGraphTraits<ScheduleDAG*>::getNodeLabel(const SUnit *SU,
-                                                       const ScheduleDAG *G) {
-  return G->getGraphNodeLabel(SU);
-}
-
-std::string ScheduleDAG::getGraphNodeLabel(const SUnit *SU) const {
+std::string ScheduleDAGSDNodes::getGraphNodeLabel(const SUnit *SU) const {
   std::string s;
   raw_string_ostream O(s);
   O << "SU(" << SU->NodeNum << "): ";
@@ -467,17 +403,13 @@
   return O.str();
 }
 
-/// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
-/// rendered using 'dot'.
-///
-void ScheduleDAG::viewGraph() {
-// This code is only for debugging!
-#ifndef NDEBUG
-  ViewGraph(this, "dag." + MF->getFunction()->getName(),
-            "Scheduling-Units Graph for " + MF->getFunction()->getName() + ':' +
-            BB->getBasicBlock()->getName());
-#else
-  cerr << "ScheduleDAG::viewGraph is only available in debug builds on "
-       << "systems with Graphviz or gv!\n";
-#endif  // NDEBUG
+void ScheduleDAGSDNodes::getCustomGraphFeatures(GraphWriter<ScheduleDAG*> &GW) const {
+  if (DAG) {
+    // Draw a special "GraphRoot" node to indicate the root of the graph.
+    GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot");
+    const SDNode *N = DAG->getRoot().getNode();
+    if (N && N->getNodeId() != -1)
+      GW.emitEdge(0, -1, &SUnits[N->getNodeId()], -1,
+                  "color=blue,style=dashed");
+  }
 }

Modified: llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h?rev=59676&r1=59675&r2=59676&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h (original)
+++ llvm/trunk/lib/Target/CellSPU/SPUHazardRecognizers.h Wed Nov 19 17:18:57 2008
@@ -15,7 +15,7 @@
 #ifndef SPUHAZRECS_H
 #define SPUHAZRECS_H
 
-#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/ScheduleDAGSDNodes.h"
 #include "SPUInstrInfo.h"
 
 namespace llvm {

Modified: llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h?rev=59676&r1=59675&r2=59676&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.h Wed Nov 19 17:18:57 2008
@@ -14,7 +14,7 @@
 #ifndef PPCHAZRECS_H
 #define PPCHAZRECS_H
 
-#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/ScheduleDAGSDNodes.h"
 #include "PPCInstrInfo.h"
 
 namespace llvm {





More information about the llvm-commits mailing list