+ 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;
+ }
+
+ /// 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;