diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index ba3637b5c32..b2a2a9c9b8c 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -29,11 +29,6 @@ namespace llvm { class TargetInstrDescriptor; class TargetMachine; - class NodeInfo; - typedef NodeInfo *NodeInfoPtr; - typedef std::vector NIVector; - typedef std::vector::iterator NIIterator; - /// HazardRecognizer - This determines whether or not an instruction can be /// issued this cycle, and whether or not a noop needs to be inserted to handle /// the hazard. @@ -75,203 +70,7 @@ namespace llvm { virtual void EmitNoop() { } }; - - //===--------------------------------------------------------------------===// - /// - /// Node group - This struct is used to manage flagged node groups. - /// - class NodeGroup { - public: - NodeGroup *Next; - private: - NIVector Members; // Group member nodes - NodeInfo *Dominator; // Node with highest latency - unsigned Latency; // Total latency of the group - int Pending; // Number of visits pending before - // adding to order - - public: - // Ctor. - NodeGroup() : Next(NULL), Dominator(NULL), Pending(0) {} - // Accessors - inline void setDominator(NodeInfo *D) { Dominator = D; } - inline NodeInfo *getTop() { return Members.front(); } - inline NodeInfo *getBottom() { return Members.back(); } - inline NodeInfo *getDominator() { return Dominator; } - inline void setLatency(unsigned L) { Latency = L; } - inline unsigned getLatency() { return Latency; } - inline int getPending() const { return Pending; } - inline void setPending(int P) { Pending = P; } - inline int addPending(int I) { return Pending += I; } - - // Pass thru - inline bool group_empty() { return Members.empty(); } - inline NIIterator group_begin() { return Members.begin(); } - inline NIIterator group_end() { return Members.end(); } - inline void group_push_back(const NodeInfoPtr &NI) { - Members.push_back(NI); - } - inline NIIterator group_insert(NIIterator Pos, const NodeInfoPtr &NI) { - return Members.insert(Pos, NI); - } - inline void group_insert(NIIterator Pos, NIIterator First, - NIIterator Last) { - Members.insert(Pos, First, Last); - } - - static void Add(NodeInfo *D, NodeInfo *U); - }; - - //===--------------------------------------------------------------------===// - /// - /// NodeInfo - This struct tracks information used to schedule the a node. - /// - class NodeInfo { - private: - int Pending; // Number of visits pending before - // adding to order - public: - SDNode *Node; // DAG node - InstrStage *StageBegin; // First stage in itinerary - InstrStage *StageEnd; // Last+1 stage in itinerary - unsigned Latency; // Total cycles to complete instr - bool IsCall : 1; // Is function call - bool IsLoad : 1; // Is memory load - bool IsStore : 1; // Is memory store - unsigned Slot; // Node's time slot - NodeGroup *Group; // Grouping information -#ifndef NDEBUG - unsigned Preorder; // Index before scheduling -#endif - - // Ctor. - NodeInfo(SDNode *N = NULL) - : Pending(0) - , Node(N) - , StageBegin(NULL) - , StageEnd(NULL) - , Latency(0) - , IsCall(false) - , Slot(0) - , Group(NULL) -#ifndef NDEBUG - , Preorder(0) -#endif - {} - - // Accessors - inline bool isInGroup() const { - assert(!Group || !Group->group_empty() && "Group with no members"); - return Group != NULL; - } - inline bool isGroupDominator() const { - return isInGroup() && Group->getDominator() == this; - } - inline int getPending() const { - return Group ? Group->getPending() : Pending; - } - inline void setPending(int P) { - if (Group) Group->setPending(P); - else Pending = P; - } - inline int addPending(int I) { - if (Group) return Group->addPending(I); - else return Pending += I; - } - }; - - //===--------------------------------------------------------------------===// - /// - /// NodeGroupIterator - Iterates over all the nodes indicated by the node - /// info. If the node is in a group then iterate over the members of the - /// group, otherwise just the node info. - /// - class NodeGroupIterator { - private: - NodeInfo *NI; // Node info - NIIterator NGI; // Node group iterator - NIIterator NGE; // Node group iterator end - - public: - // Ctor. - NodeGroupIterator(NodeInfo *N) : NI(N) { - // If the node is in a group then set up the group iterator. Otherwise - // the group iterators will trip first time out. - if (N->isInGroup()) { - // get Group - NodeGroup *Group = NI->Group; - NGI = Group->group_begin(); - NGE = Group->group_end(); - // Prevent this node from being used (will be in members list - NI = NULL; - } - } - - /// next - Return the next node info, otherwise NULL. - /// - NodeInfo *next() { - // If members list - if (NGI != NGE) return *NGI++; - // Use node as the result (may be NULL) - NodeInfo *Result = NI; - // Only use once - NI = NULL; - // Return node or NULL - return Result; - } - }; - //===--------------------------------------------------------------------===// - - - //===--------------------------------------------------------------------===// - /// - /// NodeGroupOpIterator - Iterates over all the operands of a node. If the - /// node is a member of a group, this iterates over all the operands of all - /// the members of the group. - /// - class NodeGroupOpIterator { - private: - NodeInfo *NI; // Node containing operands - NodeGroupIterator GI; // Node group iterator - SDNode::op_iterator OI; // Operand iterator - SDNode::op_iterator OE; // Operand iterator end - - /// CheckNode - Test if node has more operands. If not get the next node - /// skipping over nodes that have no operands. - void CheckNode() { - // Only if operands are exhausted first - while (OI == OE) { - // Get next node info - NodeInfo *NI = GI.next(); - // Exit if nodes are exhausted - if (!NI) return; - // Get node itself - SDNode *Node = NI->Node; - // Set up the operand iterators - OI = Node->op_begin(); - OE = Node->op_end(); - } - } - - public: - // Ctor. - NodeGroupOpIterator(NodeInfo *N) - : NI(N), GI(N), OI(SDNode::op_iterator()), OE(SDNode::op_iterator()) {} - - /// isEnd - Returns true when not more operands are available. - /// - inline bool isEnd() { CheckNode(); return OI == OE; } - - /// next - Returns the next available operand. - /// - inline SDOperand next() { - assert(OI != OE && - "Not checking for end of NodeGroupOpIterator correctly"); - return *OI++; - } - }; - class ScheduleDAG { public: SelectionDAG &DAG; // DAG of the current basic block diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp index 90656e47f85..0a92b40fb94 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp @@ -24,6 +24,208 @@ using namespace llvm; namespace { +class NodeInfo; +typedef NodeInfo *NodeInfoPtr; +typedef std::vector NIVector; +typedef std::vector::iterator NIIterator; + +//===--------------------------------------------------------------------===// +/// +/// Node group - This struct is used to manage flagged node groups. +/// +class NodeGroup { +public: + NodeGroup *Next; +private: + NIVector Members; // Group member nodes + NodeInfo *Dominator; // Node with highest latency + unsigned Latency; // Total latency of the group + int Pending; // Number of visits pending before + // adding to order + +public: + // Ctor. + NodeGroup() : Next(NULL), Dominator(NULL), Pending(0) {} + + // Accessors + inline void setDominator(NodeInfo *D) { Dominator = D; } + inline NodeInfo *getTop() { return Members.front(); } + inline NodeInfo *getBottom() { return Members.back(); } + inline NodeInfo *getDominator() { return Dominator; } + inline void setLatency(unsigned L) { Latency = L; } + inline unsigned getLatency() { return Latency; } + inline int getPending() const { return Pending; } + inline void setPending(int P) { Pending = P; } + inline int addPending(int I) { return Pending += I; } + + // Pass thru + inline bool group_empty() { return Members.empty(); } + inline NIIterator group_begin() { return Members.begin(); } + inline NIIterator group_end() { return Members.end(); } + inline void group_push_back(const NodeInfoPtr &NI) { + Members.push_back(NI); + } + inline NIIterator group_insert(NIIterator Pos, const NodeInfoPtr &NI) { + return Members.insert(Pos, NI); + } + inline void group_insert(NIIterator Pos, NIIterator First, + NIIterator Last) { + Members.insert(Pos, First, Last); + } + + static void Add(NodeInfo *D, NodeInfo *U); +}; + +//===--------------------------------------------------------------------===// +/// +/// NodeInfo - This struct tracks information used to schedule the a node. +/// +class NodeInfo { +private: + int Pending; // Number of visits pending before + // adding to order +public: + SDNode *Node; // DAG node + InstrStage *StageBegin; // First stage in itinerary + InstrStage *StageEnd; // Last+1 stage in itinerary + unsigned Latency; // Total cycles to complete instr + bool IsCall : 1; // Is function call + bool IsLoad : 1; // Is memory load + bool IsStore : 1; // Is memory store + unsigned Slot; // Node's time slot + NodeGroup *Group; // Grouping information +#ifndef NDEBUG + unsigned Preorder; // Index before scheduling +#endif + + // Ctor. + NodeInfo(SDNode *N = NULL) + : Pending(0) + , Node(N) + , StageBegin(NULL) + , StageEnd(NULL) + , Latency(0) + , IsCall(false) + , Slot(0) + , Group(NULL) +#ifndef NDEBUG + , Preorder(0) +#endif + {} + + // Accessors + inline bool isInGroup() const { + assert(!Group || !Group->group_empty() && "Group with no members"); + return Group != NULL; + } + inline bool isGroupDominator() const { + return isInGroup() && Group->getDominator() == this; + } + inline int getPending() const { + return Group ? Group->getPending() : Pending; + } + inline void setPending(int P) { + if (Group) Group->setPending(P); + else Pending = P; + } + inline int addPending(int I) { + if (Group) return Group->addPending(I); + else return Pending += I; + } +}; + +//===--------------------------------------------------------------------===// +/// +/// NodeGroupIterator - Iterates over all the nodes indicated by the node +/// info. If the node is in a group then iterate over the members of the +/// group, otherwise just the node info. +/// +class NodeGroupIterator { +private: + NodeInfo *NI; // Node info + NIIterator NGI; // Node group iterator + NIIterator NGE; // Node group iterator end + +public: + // Ctor. + NodeGroupIterator(NodeInfo *N) : NI(N) { + // If the node is in a group then set up the group iterator. Otherwise + // the group iterators will trip first time out. + if (N->isInGroup()) { + // get Group + NodeGroup *Group = NI->Group; + NGI = Group->group_begin(); + NGE = Group->group_end(); + // Prevent this node from being used (will be in members list + NI = NULL; + } + } + + /// next - Return the next node info, otherwise NULL. + /// + NodeInfo *next() { + // If members list + if (NGI != NGE) return *NGI++; + // Use node as the result (may be NULL) + NodeInfo *Result = NI; + // Only use once + NI = NULL; + // Return node or NULL + return Result; + } +}; +//===--------------------------------------------------------------------===// + + +//===--------------------------------------------------------------------===// +/// +/// NodeGroupOpIterator - Iterates over all the operands of a node. If the +/// node is a member of a group, this iterates over all the operands of all +/// the members of the group. +/// +class NodeGroupOpIterator { +private: + NodeInfo *NI; // Node containing operands + NodeGroupIterator GI; // Node group iterator + SDNode::op_iterator OI; // Operand iterator + SDNode::op_iterator OE; // Operand iterator end + + /// CheckNode - Test if node has more operands. If not get the next node + /// skipping over nodes that have no operands. + void CheckNode() { + // Only if operands are exhausted first + while (OI == OE) { + // Get next node info + NodeInfo *NI = GI.next(); + // Exit if nodes are exhausted + if (!NI) return; + // Get node itself + SDNode *Node = NI->Node; + // Set up the operand iterators + OI = Node->op_begin(); + OE = Node->op_end(); + } + } + +public: + // Ctor. + NodeGroupOpIterator(NodeInfo *N) + : NI(N), GI(N), OI(SDNode::op_iterator()), OE(SDNode::op_iterator()) {} + + /// isEnd - Returns true when not more operands are available. + /// + inline bool isEnd() { CheckNode(); return OI == OE; } + + /// next - Returns the next available operand. + /// + inline SDOperand next() { + assert(OI != OE && + "Not checking for end of NodeGroupOpIterator correctly"); + return *OI++; + } +}; + + //===----------------------------------------------------------------------===// /// /// BitsIterator - Provides iteration through individual bits in a bit vector.