aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2007-09-25 01:54:36 +0000
committerEvan Cheng <evan.cheng@apple.com>2007-09-25 01:54:36 +0000
commita6fb1b6743ee1411accf2d6e636f73f2ee0a7f5b (patch)
tree05eb93ca35bcfe154a16403c81b638ae3abf777b /include/llvm
parenta3602685b34f4c9a1602fdc7fb120a7f51228736 (diff)
downloadexternal_llvm-a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5b.zip
external_llvm-a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5b.tar.gz
external_llvm-a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5b.tar.bz2
Added major new capabilities to scheduler (only BURR for now) to support physical register dependency. The BURR scheduler can now backtrace and duplicate instructions in order to avoid "expensive / impossible to copy" values (e.g. status flag EFLAGS for x86) from being clobbered.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42284 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm')
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h127
1 files changed, 99 insertions, 28 deletions
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
index 17938d7..ad44b24 100644
--- a/include/llvm/CodeGen/ScheduleDAG.h
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -79,12 +79,13 @@ namespace llvm {
/// 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.
- bool isCtrl; // True iff it's a control dependency.
- unsigned PhyReg; // If non-zero, this dep is a phy register dependency.
- int Cost; // Cost of the dependency.
- SDep(SUnit *d, bool c, unsigned r, int t)
- : Dep(d), isCtrl(c), PhyReg(r), Cost(t) {}
+ 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
@@ -92,6 +93,8 @@ namespace llvm {
struct SUnit {
SDNode *Node; // Representative node.
SmallVector<SDNode*,4> FlaggedNodes;// All nodes flagged to Node.
+ unsigned InstanceNo; // Instance#. One SDNode can be multiple
+ // SUnit due to cloning.
// 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.
@@ -103,6 +106,8 @@ namespace llvm {
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 short Latency; // Node latency.
short NumPreds; // # of preds.
short NumSuccs; // # of sucss.
short NumPredsLeft; // # of preds not scheduled.
@@ -111,42 +116,94 @@ namespace llvm {
short NumChainSuccsLeft; // # of chain succs not scheduled.
bool isTwoAddress : 1; // Is a two-address instruction.
bool isCommutable : 1; // Is a commutable instruction.
+ bool hasImplicitDefs : 1; // Has implicit physical reg defs.
bool isPending : 1; // True once pending.
bool isAvailable : 1; // True once available.
bool isScheduled : 1; // True once scheduled.
- unsigned short Latency; // Node latency.
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;
- unsigned NodeNum; // Entry # of node in the node vector.
SUnit(SDNode *node, unsigned nodenum)
- : Node(node), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0),
+ : Node(node), InstanceNo(0), NodeNum(nodenum), Latency(0),
+ NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0),
NumChainPredsLeft(0), NumChainSuccsLeft(0),
- isTwoAddress(false), isCommutable(false),
+ isTwoAddress(false), isCommutable(false), hasImplicitDefs(false),
isPending(false), isAvailable(false), isScheduled(false),
- Latency(0), CycleBound(0), Cycle(0), Depth(0), Height(0),
- NodeNum(nodenum) {}
-
+ CycleBound(0), Cycle(0), Depth(0), Height(0) {}
+
/// 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, unsigned PhyReg = 0, int Cost = 1) {
+ bool addPred(SUnit *N, bool isCtrl, bool isSpecial,
+ unsigned PhyReg = 0, int Cost = 1) {
for (unsigned i = 0, e = Preds.size(); i != e; ++i)
- if (Preds[i].Dep == N && Preds[i].isCtrl == isCtrl)
+ if (Preds[i].Dep == N &&
+ Preds[i].isCtrl == isCtrl && Preds[i].isSpecial == isSpecial)
return false;
- Preds.push_back(SDep(N, isCtrl, PhyReg, Cost));
+ Preds.push_back(SDep(N, PhyReg, Cost, isCtrl, isSpecial));
+ N->Succs.push_back(SDep(this, PhyReg, Cost, isCtrl, isSpecial));
+ if (isCtrl) {
+ if (!N->isScheduled)
+ ++NumChainPredsLeft;
+ if (!isScheduled)
+ ++N->NumChainSuccsLeft;
+ } else {
+ ++NumPreds;
+ ++N->NumSuccs;
+ if (!N->isScheduled)
+ ++NumPredsLeft;
+ if (!isScheduled)
+ ++N->NumSuccsLeft;
+ }
return true;
}
- /// addSucc - This adds the specified node as a succ of the current node if
- /// not already. This returns true if this is a new succ.
- bool addSucc(SUnit *N, bool isCtrl, unsigned PhyReg = 0, int Cost = 1) {
+ 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) {
+ if (!N->isScheduled)
+ --NumChainPredsLeft;
+ if (!isScheduled)
+ --NumChainSuccsLeft;
+ } else {
+ --NumPreds;
+ --N->NumSuccs;
+ if (!N->isScheduled)
+ --NumPredsLeft;
+ if (!isScheduled)
+ --N->NumSuccsLeft;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ bool isPred(SUnit *N) {
+ for (unsigned i = 0, e = Preds.size(); i != e; ++i)
+ if (Preds[i].Dep == N)
+ return true;
+ return false;
+ }
+
+ bool isSucc(SUnit *N) {
for (unsigned i = 0, e = Succs.size(); i != e; ++i)
- if (Succs[i].Dep == N && Succs[i].isCtrl == isCtrl)
- return false;
- Succs.push_back(SDep(N, isCtrl, PhyReg, Cost));
- return true;
+ if (Succs[i].Dep == N)
+ return true;
+ return false;
}
void dump(const SelectionDAG *G) const;
@@ -165,20 +222,27 @@ namespace llvm {
public:
virtual ~SchedulingPriorityQueue() {}
- virtual void initNodes(DenseMap<SDNode*, SUnit*> &SUMap,
+ virtual void initNodes(DenseMap<SDNode*, std::vector<SUnit*> > &SUMap,
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 node that have
/// already been emitted.
virtual void ScheduledNode(SUnit *Node) {}
+
+ virtual void UnscheduledNode(SUnit *Node) {}
};
class ScheduleDAG {
@@ -192,7 +256,8 @@ namespace llvm {
MachineConstantPool *ConstPool; // Target constant pool
std::vector<SUnit*> Sequence; // The schedule. Null SUnit*'s
// represent noop instructions.
- DenseMap<SDNode*, SUnit*> SUnitMap; // SDNode to SUnit mapping (n -> 1).
+ DenseMap<SDNode*, std::vector<SUnit*> > SUnitMap;
+ // SDNode to SUnit mapping (n -> n).
std::vector<SUnit> SUnits; // The scheduling units.
SmallSet<SDNode*, 16> CommuteSet; // Nodes the should be commuted.
@@ -232,6 +297,10 @@ namespace llvm {
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.
@@ -256,7 +325,8 @@ namespace llvm {
/// VRBaseMap contains, for each already emitted node, the first virtual
/// register number for the results of the node.
///
- void EmitNode(SDNode *Node, DenseMap<SDOperand, unsigned> &VRBaseMap);
+ void EmitNode(SDNode *Node, unsigned InstNo,
+ DenseMap<SDOperand, unsigned> &VRBaseMap);
/// EmitNoop - Emit a noop instruction.
///
@@ -264,7 +334,8 @@ namespace llvm {
/// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
/// implicit physical register output.
- void EmitCopyFromReg(SDNode *Node, unsigned ResNo, unsigned SrcReg,
+ void EmitCopyFromReg(SDNode *Node, unsigned ResNo, unsigned InstNo,
+ unsigned SrcReg,
DenseMap<SDOperand, unsigned> &VRBaseMap);
void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,