#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallSet.h"
/// 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,
public:
virtual ~SchedulingPriorityQueue() {}
- virtual void initNodes(DenseMap<SDNode*, SUnit*> &SUMap,
- std::vector<SUnit> &SUnits) = 0;
+ virtual void initNodes(std::vector<SUnit> &SUnits) = 0;
virtual void addNode(const SUnit *SU) = 0;
virtual void updateNode(const SUnit *SU) = 0;
virtual void releaseState() = 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.
+ /// allows the priority function to adjust the priority of related
+ /// unscheduled nodes, for example.
+ ///
virtual void ScheduledNode(SUnit *) {}
virtual void UnscheduledNode(SUnit *) {}
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
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 -> n).
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() {}
/// Run - perform scheduling.
///
- MachineBasicBlock *Run();
+ void Run();
/// isPassiveNode - Return true if the node is a non-scheduled leaf.
///
/// register number for the results of the node.
///
void EmitNode(SDNode *Node, bool IsClone,
- DenseMap<SDOperand, unsigned> &VRBaseMap);
+ DenseMap<SDValue, unsigned> &VRBaseMap);
/// EmitNoop - Emit a noop instruction.
///
void EmitNoop();
- void EmitSchedule();
+ MachineBasicBlock *EmitSchedule();
void dumpSchedule() const;
- /// Schedule - Order nodes according to selected style.
+ /// Schedule - Order nodes according to selected style, filling
+ /// in the Sequence member.
///
- virtual void Schedule() {}
+ virtual void Schedule() = 0;
private:
/// EmitSubregNode - Generate machine code for subreg nodes.
///
void EmitSubregNode(SDNode *Node,
- DenseMap<SDOperand, unsigned> &VRBaseMap);
+ DenseMap<SDValue, unsigned> &VRBaseMap);
/// getVR - Return the virtual register corresponding to the specified result
/// of the specified node.
- unsigned getVR(SDOperand Op, DenseMap<SDOperand, unsigned> &VRBaseMap);
+ 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, SDOperand Op, unsigned IIOpNum,
+ void AddOperand(MachineInstr *MI, SDValue Op, unsigned IIOpNum,
const TargetInstrDesc *II,
- DenseMap<SDOperand, unsigned> &VRBaseMap);
-
+ DenseMap<SDValue, unsigned> &VRBaseMap);
void AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO);
void EmitCrossRCCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap);
/// implicit physical register output.
void EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone,
unsigned SrcReg,
- DenseMap<SDOperand, unsigned> &VRBaseMap);
+ DenseMap<SDValue, unsigned> &VRBaseMap);
void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
const TargetInstrDesc &II,
- DenseMap<SDOperand, unsigned> &VRBaseMap);
+ DenseMap<SDValue, unsigned> &VRBaseMap);
/// EmitLiveInCopy - Emit a copy for a live in physical register. If the
/// physical register has only a single copy use, then coalesced the copy
/// reduction list scheduler.
ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS,
SelectionDAG *DAG,
- MachineBasicBlock *BB);
+ const TargetMachine *TM,
+ MachineBasicBlock *BB,
+ bool Fast);
/// createTDRRListDAGScheduler - This creates a top down register usage
/// reduction list scheduler.
ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS,
SelectionDAG *DAG,
- MachineBasicBlock *BB);
+ 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,
- MachineBasicBlock *BB);
+ 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,
- MachineBasicBlock *BB);
+ const TargetMachine *TM,
+ MachineBasicBlock *BB,
+ bool Fast);
class SUnitIterator : public forward_iterator<SUnit, ptrdiff_t> {
SUnit *Node;