aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/CodeGen')
-rw-r--r--include/llvm/CodeGen/LatencyPriorityQueue.h124
-rw-r--r--include/llvm/CodeGen/LinkAllCodegenComponents.h2
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h206
-rw-r--r--include/llvm/CodeGen/ScheduleDAGInstrs.h69
-rw-r--r--include/llvm/CodeGen/ScheduleDAGSDNodes.h233
5 files changed, 449 insertions, 185 deletions
diff --git a/include/llvm/CodeGen/LatencyPriorityQueue.h b/include/llvm/CodeGen/LatencyPriorityQueue.h
new file mode 100644
index 0000000..f04d2ed
--- /dev/null
+++ b/include/llvm/CodeGen/LatencyPriorityQueue.h
@@ -0,0 +1,124 @@
+//===---- 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
diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h
index 2853500..610d66b 100644
--- a/include/llvm/CodeGen/LinkAllCodegenComponents.h
+++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h
@@ -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 {
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
index 49dabe6..ee25203 100644
--- a/include/llvm/CodeGen/ScheduleDAG.h
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -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 @@ namespace llvm {
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 @@ namespace llvm {
: 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 @@ namespace llvm {
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 @@ namespace llvm {
///
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 @@ namespace llvm {
///
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;
+ /// addCustomGraphFeatures - Add custom features for a visualization of
+ /// the ScheduleDAG.
+ virtual void addCustomGraphFeatures(GraphWriter<ScheduleDAG*> &GW) const {}
- void AddOperand(MachineInstr *MI, SDValue Op, unsigned IIOpNum,
- const TargetInstrDesc *II,
- DenseMap<SDValue, unsigned> &VRBaseMap);
+ 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 @@ namespace llvm {
/// 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;
diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h
new file mode 100644
index 0000000..703c5b0
--- /dev/null
+++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -0,0 +1,69 @@
+//==- llvm/CodeGen/ScheduleDAGInstrs.h - MachineInstr Scheduling -*- C++ -*-==//
+//
+// 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 ScheduleDAGInstrs class, which implements
+// scheduling for a MachineInstr-based dependency graph.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
+#define LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
+
+#include "llvm/CodeGen/ScheduleDAG.h"
+
+namespace llvm {
+ struct SUnit;
+ class MachineConstantPool;
+ class MachineFunction;
+ class MachineModuleInfo;
+ class MachineRegisterInfo;
+ class MachineInstr;
+ class TargetRegisterInfo;
+ class ScheduleDAG;
+ class SelectionDAG;
+ class SelectionDAGISel;
+ class TargetInstrInfo;
+ class TargetInstrDesc;
+ class TargetLowering;
+ class TargetMachine;
+ class TargetRegisterClass;
+
+ class ScheduleDAGInstrs : public ScheduleDAG {
+ public:
+ ScheduleDAGInstrs(MachineBasicBlock *bb,
+ const TargetMachine &tm);
+
+ virtual ~ScheduleDAGInstrs() {}
+
+ /// 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();
+ }
+
+ /// BuildSchedUnits - Build SUnits from the MachineBasicBlock that we are
+ /// input.
+ virtual void BuildSchedUnits();
+
+ 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;
+ };
+}
+
+#endif
diff --git a/include/llvm/CodeGen/ScheduleDAGSDNodes.h b/include/llvm/CodeGen/ScheduleDAGSDNodes.h
new file mode 100644
index 0000000..caa1d0a
--- /dev/null
+++ b/include/llvm/CodeGen/ScheduleDAGSDNodes.h
@@ -0,0 +1,233 @@
+//===---- llvm/CodeGen/ScheduleDAGSDNodes.h - SDNode Scheduling -*- C++ -*-===//
+//
+// 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 ScheduleDAGSDNodes class, which implements
+// scheduling for an SDNode-based dependency graph.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SCHEDULEDAGSDNODES_H
+#define LLVM_CODEGEN_SCHEDULEDAGSDNODES_H
+
+#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/ADT/SmallSet.h"
+
+namespace llvm {
+ struct SUnit;
+ class MachineConstantPool;
+ class MachineFunction;
+ class MachineModuleInfo;
+ class MachineRegisterInfo;
+ class MachineInstr;
+ class TargetRegisterInfo;
+ class ScheduleDAG;
+ class SelectionDAG;
+ class SelectionDAGISel;
+ 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() {}
+ };
+
+ class ScheduleDAGSDNodes : public ScheduleDAG {
+ public:
+ SmallSet<SDNode*, 16> CommuteSet; // Nodes that should be commuted.
+
+ ScheduleDAGSDNodes(SelectionDAG *dag, MachineBasicBlock *bb,
+ const TargetMachine &tm);
+
+ virtual ~ScheduleDAGSDNodes() {}
+
+ /// 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();
+ }
+
+ /// 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.
+ virtual void BuildSchedUnits();
+
+ /// ComputeLatency - Compute node latency.
+ ///
+ 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
+ /// (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);
+
+ 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.
+ ///
+ 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);
+
+ /// 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);
+ };
+
+ /// 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);
+}
+
+#endif