X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FScheduleDAG.h;h=b3d05c700ac0f17f14a2353f5b4b7203bdb96559;hb=a75ce9f5d2236d93c117e861e60e6f3f748c9555;hp=fdbbb1ee20eacf5ac7c9e2fa99376e491a2d28ae;hpb=d10e68c2cb61f2c9569ca80e1c54b2e40ee066d2;p=oota-llvm.git diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index fdbbb1ee20e..b3d05c700ac 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -16,6 +16,7 @@ #define LLVM_CODEGEN_SCHEDULEDAG_H #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/Target/TargetMachine.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/GraphTraits.h" @@ -27,7 +28,6 @@ namespace llvm { class SUnit; class MachineConstantPool; class MachineFunction; - class MachineModuleInfo; class MachineRegisterInfo; class MachineInstr; class TargetRegisterInfo; @@ -35,7 +35,6 @@ namespace llvm { class SDNode; class TargetInstrInfo; class TargetInstrDesc; - class TargetLowering; class TargetMachine; class TargetRegisterClass; template class GraphWriter; @@ -222,6 +221,9 @@ namespace llvm { } }; + template <> + struct isPodLike { static const bool value = true; }; + /// SUnit - Scheduling unit. This is a node in the scheduling DAG. class SUnit { private: @@ -230,9 +232,8 @@ namespace llvm { 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. + + // Preds/Succs - The SUnits before/after us in the graph. SmallVector Preds; // All sunit predecessors. SmallVector Succs; // All sunit successors. @@ -240,14 +241,15 @@ namespace llvm { typedef SmallVector::iterator succ_iterator; typedef SmallVector::const_iterator const_pred_iterator; typedef SmallVector::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. unsigned NumPreds; // # of SDep::Data preds. unsigned NumSuccs; // # of SDep::Data sucss. unsigned NumPredsLeft; // # of preds not scheduled. unsigned NumSuccsLeft; // # of succs not scheduled. + unsigned short Latency; // Node latency. + bool isCall : 1; // Is a function call. 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. @@ -257,6 +259,9 @@ namespace llvm { bool isScheduled : 1; // True once scheduled. bool isScheduleHigh : 1; // True if preferable to schedule high. bool isCloned : 1; // True if this node has been cloned. + Sched::Preference SchedulingPref; // Scheduling preference. + + SmallVector DbgInstrList; // dbg_values referencing this. private: bool isDepthCurrent : 1; // True if Depth is current. bool isHeightCurrent : 1; // True if Height is current. @@ -265,39 +270,45 @@ namespace llvm { public: 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), - hasPhysRegClobbers(false), + : Node(node), Instr(0), OrigNode(0), NodeNum(nodenum), + NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), + NumSuccsLeft(0), Latency(0), + isCall(false), isTwoAddress(false), isCommutable(false), + hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), isAvailable(false), isScheduled(false), isScheduleHigh(false), isCloned(false), + SchedulingPref(Sched::None), isDepthCurrent(false), isHeightCurrent(false), 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), - hasPhysRegClobbers(false), + : Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum), + NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), + NumSuccsLeft(0), Latency(0), + isCall(false), isTwoAddress(false), isCommutable(false), + hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), isAvailable(false), isScheduled(false), isScheduleHigh(false), isCloned(false), + SchedulingPref(Sched::None), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), CopyDstRC(NULL), CopySrcRC(NULL) {} /// SUnit - Construct a placeholder SUnit. SUnit() - : Node(0), Instr(0), OrigNode(0), NodeNum(~0u), NodeQueueId(0), - Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), - isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), - hasPhysRegClobbers(false), + : Node(0), Instr(0), OrigNode(0), NodeNum(~0u), + NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), + NumSuccsLeft(0), Latency(0), + isCall(false), isTwoAddress(false), isCommutable(false), + hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), isAvailable(false), isScheduled(false), isScheduleHigh(false), isCloned(false), + SchedulingPref(Sched::None), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), CopyDstRC(NULL), CopySrcRC(NULL) {} @@ -315,6 +326,10 @@ namespace llvm { return Node; } + /// isInstr - Return true if this SUnit refers to a machine instruction as + /// opposed to an SDNode. + bool isInstr() const { return Instr; } + /// setInstr - Assign the instruction for the SUnit. /// This may be used during post-regalloc scheduling. void setInstr(MachineInstr *MI) { @@ -342,25 +357,27 @@ namespace llvm { /// getDepth - Return the depth of this node, which is the length of the /// maximum path up to any node with has no predecessors. unsigned getDepth() const { - if (!isDepthCurrent) const_cast(this)->ComputeDepth(); + if (!isDepthCurrent) + const_cast(this)->ComputeDepth(); return Depth; } /// getHeight - Return the height of this node, which is the length of the /// maximum path down to any node with has no successors. unsigned getHeight() const { - if (!isHeightCurrent) const_cast(this)->ComputeHeight(); + if (!isHeightCurrent) + const_cast(this)->ComputeHeight(); return Height; } - /// setDepthToAtLeast - If NewDepth is greater than this node's depth - /// value, set it to be the new depth value. This also recursively - /// marks successor nodes dirty. + /// setDepthToAtLeast - If NewDepth is greater than this node's + /// depth value, set it to be the new depth value. This also + /// recursively marks successor nodes dirty. void setDepthToAtLeast(unsigned NewDepth); - /// setDepthToAtLeast - If NewDepth is greater than this node's depth - /// value, set it to be the new height value. This also recursively - /// marks predecessor nodes dirty. + /// setDepthToAtLeast - If NewDepth is greater than this node's + /// depth value, set it to be the new height value. This also + /// recursively marks predecessor nodes dirty. void setHeightToAtLeast(unsigned NewHeight); /// setDepthDirty - Set a flag in this node to indicate that its @@ -380,7 +397,7 @@ namespace llvm { return true; return false; } - + /// isSucc - Test if node N is a successor of this node. bool isSucc(SUnit *N) { for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i) @@ -388,7 +405,7 @@ namespace llvm { return true; return false; } - + void dump(const ScheduleDAG *G) const; void dumpAll(const ScheduleDAG *G) const; void print(raw_ostream &O, const ScheduleDAG *G) const; @@ -401,29 +418,48 @@ namespace llvm { //===--------------------------------------------------------------------===// /// SchedulingPriorityQueue - This interface is used to plug different /// priorities computation algorithms into the list scheduler. It implements - /// the interface of a standard priority queue, where nodes are inserted in + /// the interface of a standard priority queue, where nodes are inserted in /// arbitrary order and returned in priority order. The computation of the /// priority and the representation of the queue are totally up to the /// implementation to decide. - /// + /// class SchedulingPriorityQueue { + unsigned CurCycle; + bool HasReadyFilter; public: + SchedulingPriorityQueue(bool rf = false): + CurCycle(0), HasReadyFilter(rf) {} virtual ~SchedulingPriorityQueue() {} - + + virtual bool isBottomUp() const = 0; + virtual void initNodes(std::vector &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; + + bool hasReadyFilter() const { return HasReadyFilter; } + + virtual bool isReady(SUnit *U) const { + assert(!HasReadyFilter && "The ready filter must override isReady()"); + return true; + } virtual void push(SUnit *U) = 0; - - virtual void push_all(const std::vector &Nodes) = 0; + + void push_all(const std::vector &Nodes) { + for (std::vector::const_iterator I = Nodes.begin(), + E = Nodes.end(); I != E; ++I) + push(*I); + } + virtual SUnit *pop() = 0; virtual void remove(SUnit *SU) = 0; + virtual void dump(ScheduleDAG *DAG) const {} + /// ScheduledNode - As each node is scheduled, this method is invoked. This /// allows the priority function to adjust the priority of related /// unscheduled nodes, for example. @@ -431,6 +467,14 @@ namespace llvm { virtual void ScheduledNode(SUnit *) {} virtual void UnscheduledNode(SUnit *) {} + + void setCurCycle(unsigned Cycle) { + CurCycle = Cycle; + } + + unsigned getCurCycle() const { + return CurCycle; + } }; class ScheduleDAG { @@ -440,10 +484,8 @@ namespace llvm { const TargetMachine &TM; // Target processor const TargetInstrInfo *TII; // Target instruction information const TargetRegisterInfo *TRI; // Target processor register info - const TargetLowering *TLI; // Target lowering info MachineFunction &MF; // Machine function MachineRegisterInfo &MRI; // Virtual/real register map - MachineConstantPool *ConstPool; // Target constant pool std::vector Sequence; // The schedule. Null SUnit*'s // represent noop instructions. std::vector SUnits; // The scheduling units. @@ -454,16 +496,22 @@ namespace llvm { virtual ~ScheduleDAG(); + /// getInstrDesc - Return the TargetInstrDesc of this SUnit. + /// Return NULL for SDNodes without a machine opcode. + const TargetInstrDesc *getInstrDesc(const SUnit *SU) const { + if (SU->isInstr()) return &SU->getInstr()->getDesc(); + return getNodeDesc(SU->getNode()); + } + /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered /// using 'dot'. /// void viewGraph(); - + /// EmitSchedule - Insert MachineInstrs into the MachineBasicBlock /// according to the order specified in Sequence. /// - virtual MachineBasicBlock* - EmitSchedule(DenseMap*) = 0; + virtual MachineBasicBlock *EmitSchedule() = 0; void dumpSchedule() const; @@ -518,6 +566,10 @@ namespace llvm { void EmitNoop(); void EmitPhysRegCopy(SUnit *SU, DenseMap &VRBaseMap); + + private: + // Return the TargetInstrDesc of this SDNode or NULL. + const TargetInstrDesc *getNodeDesc(const SDNode *Node) const; }; class SUnitIterator : public std::iterator &SUnits); - /// InitDAGTopologicalSorting - create the initial topological + /// InitDAGTopologicalSorting - create the initial topological /// ordering from the DAG to be scheduled. void InitDAGTopologicalSorting();