- }
-
-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++;
- }
-};
-//===----------------------------------------------------------------------===//
-
-
-//===----------------------------------------------------------------------===//
-///
-/// SimpleSched - Simple two pass scheduler.
-///
-class SimpleSched {
-private:
- MachineBasicBlock *BB; // Current basic block
- SelectionDAG &DAG; // DAG of the current basic block
- const TargetMachine &TM; // Target processor
- const TargetInstrInfo &TII; // Target instruction information
- const MRegisterInfo &MRI; // Target processor register information
- SSARegMap *RegMap; // Virtual/real register map
- MachineConstantPool *ConstPool; // Target constant pool
- unsigned NodeCount; // Number of nodes in DAG
- bool HasGroups; // True if there are any groups
- NodeInfo *Info; // Info for nodes being scheduled
- std::map<SDNode *, NodeInfo *> Map; // Map nodes to info
- NIVector Ordering; // Emit ordering of nodes
- ResourceTally<unsigned> Tally; // Resource usage tally
- unsigned NSlots; // Total latency
- static const unsigned NotFound = ~0U; // Search marker
-
-public:
-
- // Ctor.
- SimpleSched(SelectionDAG &D, MachineBasicBlock *bb)
- : BB(bb), DAG(D), TM(D.getTarget()), TII(*TM.getInstrInfo()),
- MRI(*TM.getRegisterInfo()), RegMap(BB->getParent()->getSSARegMap()),
- ConstPool(BB->getParent()->getConstantPool()),
- NodeCount(0), HasGroups(false), Info(NULL), Map(), Tally(), NSlots(0) {
- assert(&TII && "Target doesn't provide instr info?");
- assert(&MRI && "Target doesn't provide register info?");
- }
-
- // Run - perform scheduling.
- MachineBasicBlock *Run() {
- Schedule();
- return BB;
- }
-
-private:
- /// getNI - Returns the node info for the specified node.
- ///
- inline NodeInfo *getNI(SDNode *Node) { return Map[Node]; }
-
- /// getVR - Returns the virtual register number of the node.
- ///
- inline unsigned getVR(SDOperand Op) {
- NodeInfo *NI = getNI(Op.Val);
- assert(NI->VRBase != 0 && "Node emitted out of order - late");
- return NI->VRBase + Op.ResNo;
- }
-
- static bool isFlagDefiner(SDNode *A);
- static bool isFlagUser(SDNode *A);
- static bool isDefiner(NodeInfo *A, NodeInfo *B);
- static bool isPassiveNode(SDNode *Node);
- void IncludeNode(NodeInfo *NI);
- void VisitAll();
- void Schedule();
- void IdentifyGroups();
- void GatherSchedulingInfo();
- void FakeGroupDominators();
- void PrepareNodeInfo();
- bool isStrongDependency(NodeInfo *A, NodeInfo *B);
- bool isWeakDependency(NodeInfo *A, NodeInfo *B);
- void ScheduleBackward();
- void ScheduleForward();
- void EmitAll();
- void EmitNode(NodeInfo *NI);
- static unsigned CountResults(SDNode *Node);
- static unsigned CountOperands(SDNode *Node);
- unsigned CreateVirtualRegisters(MachineInstr *MI,
- unsigned NumResults,
- const TargetInstrDescriptor &II);
-
- void printChanges(unsigned Index);
- void printSI(std::ostream &O, NodeInfo *NI) const;
- void print(std::ostream &O) const;
- inline void dump(const char *tag) const { std::cerr << tag; dump(); }
- void dump() const;
-};
-
-
-//===----------------------------------------------------------------------===//
-/// Special case itineraries.
-///
-enum {
- CallLatency = 40, // To push calls back in time
-
- RSInteger = 0xC0000000, // Two integer units
- RSFloat = 0x30000000, // Two float units
- RSLoadStore = 0x0C000000, // Two load store units
- RSBranch = 0x02000000 // One branch unit
-};
-static InstrStage CallStage = { CallLatency, RSBranch };
-static InstrStage LoadStage = { 5, RSLoadStore };
-static InstrStage StoreStage = { 2, RSLoadStore };
-static InstrStage IntStage = { 2, RSInteger };
-static InstrStage FloatStage = { 3, RSFloat };
-//===----------------------------------------------------------------------===//
-
-
-//===----------------------------------------------------------------------===//
-
-} // namespace
-
-//===----------------------------------------------------------------------===//
-
-
-//===----------------------------------------------------------------------===//
-/// Add - Adds a definer and user pair to a node group.
-///
-void NodeGroup::Add(NodeInfo *D, NodeInfo *U) {
- // Get current groups
- NodeGroup *DGroup = D->Group;
- NodeGroup *UGroup = U->Group;
- // If both are members of groups
- if (DGroup && UGroup) {
- // There may have been another edge connecting
- if (DGroup == UGroup) return;
- // Add the pending users count
- DGroup->addPending(UGroup->getPending());
- // For each member of the users group
- NodeGroupIterator UNGI(U);
- while (NodeInfo *UNI = UNGI.next() ) {
- // Change the group
- UNI->Group = DGroup;
- // For each member of the definers group
- NodeGroupIterator DNGI(D);
- while (NodeInfo *DNI = DNGI.next() ) {
- // Remove internal edges
- DGroup->addPending(-CountInternalUses(DNI, UNI));