diff options
author | Evan Cheng <evan.cheng@apple.com> | 2007-09-25 01:54:36 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2007-09-25 01:54:36 +0000 |
commit | 93f143e286acad609336954b78a87cf19091c53c (patch) | |
tree | 05eb93ca35bcfe154a16403c81b638ae3abf777b /include | |
parent | 0d7bb10b8770d41571dd2d8b5a1743cf6b734327 (diff) | |
download | external_llvm-93f143e286acad609336954b78a87cf19091c53c.zip external_llvm-93f143e286acad609336954b78a87cf19091c53c.tar.gz external_llvm-93f143e286acad609336954b78a87cf19091c53c.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')
-rw-r--r-- | include/llvm/CodeGen/ScheduleDAG.h | 127 |
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, |