#include "llvm/ADT/SmallSet.h"
namespace llvm {
- struct InstrStage;
struct SUnit;
class MachineConstantPool;
class MachineFunction;
class MachineRegisterInfo;
class MachineInstr;
class TargetRegisterInfo;
+ class ScheduleDAG;
class SelectionDAG;
class SelectionDAGISel;
class TargetInstrInfo;
/// 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.
- SmallVector<SDNode*,4> FlaggedNodes;// All nodes flagged to Node.
+ MachineInstr *Instr; // Alternatively, a MachineInstr.
+ public:
SUnit *OrigNode; // If not this, the node from which
// this node was cloned.
unsigned NodeNum; // Entry # of node in the node vector.
unsigned NodeQueueId; // Queue id of node.
unsigned short Latency; // Node latency.
- short NumPreds; // # of preds.
- short NumSuccs; // # of sucss.
+ 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.
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), OrigNode(0), NodeNum(nodenum), NodeQueueId(0), Latency(0),
- NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0),
+ : 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,
return false;
}
- void dump(const SelectionDAG *G) const;
- void dumpAll(const SelectionDAG *G) const;
+ void dump(const ScheduleDAG *G) const;
+ void dumpAll(const ScheduleDAG *G) const;
};
//===--------------------------------------------------------------------===//
class ScheduleDAG {
public:
- SelectionDAG &DAG; // DAG of the current basic block
+ SelectionDAG *DAG; // DAG of the current basic block
MachineBasicBlock *BB; // Current basic block
const TargetMachine &TM; // Target processor
const TargetInstrInfo *TII; // Target instruction information
std::vector<SUnit> SUnits; // The scheduling units.
SmallSet<SDNode*, 16> CommuteSet; // Nodes that should be commuted.
- ScheduleDAG(SelectionDAG &dag, MachineBasicBlock *bb,
+ ScheduleDAG(SelectionDAG *dag, MachineBasicBlock *bb,
const TargetMachine &tm);
virtual ~ScheduleDAG() {}
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);
/// 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