diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h index ac580355939..39df7337baa 100644 --- a/include/llvm/CodeGen/LinkAllCodegenComponents.h +++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h @@ -39,10 +39,10 @@ namespace { (void) llvm::createOcamlCollector(); (void) llvm::createShadowStackCollector(); - (void) llvm::createBURRListDAGScheduler(NULL, NULL, NULL); - (void) llvm::createTDRRListDAGScheduler(NULL, NULL, NULL); - (void) llvm::createTDListDAGScheduler(NULL, NULL, NULL); - (void) llvm::createDefaultScheduler(NULL, NULL, NULL); + (void) llvm::createBURRListDAGScheduler(NULL, NULL, NULL, false); + (void) llvm::createTDRRListDAGScheduler(NULL, NULL, NULL, false); + (void) llvm::createTDListDAGScheduler(NULL, NULL, NULL, false); + (void) llvm::createDefaultScheduler(NULL, NULL, NULL, false); } } ForceCodegenLinking; // Force link by creating a global definition. diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 4849f914ca9..ed7801fbfc4 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -396,25 +396,29 @@ namespace llvm { /// reduction list scheduler. ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS, SelectionDAG *DAG, - MachineBasicBlock *BB); + MachineBasicBlock *BB, + bool Fast); /// createTDRRListDAGScheduler - This creates a top down register usage /// reduction list scheduler. ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS, SelectionDAG *DAG, - MachineBasicBlock *BB); + MachineBasicBlock *BB, + bool Fast); /// createTDListDAGScheduler - This creates a top-down list scheduler with /// a hazard recognizer. ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS, SelectionDAG *DAG, - MachineBasicBlock *BB); + MachineBasicBlock *BB, + bool Fast); /// createDefaultScheduler - This creates an instruction scheduler appropriate /// for the target. ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS, SelectionDAG *DAG, - MachineBasicBlock *BB); + MachineBasicBlock *BB, + bool Fast); class SUnitIterator : public forward_iterator { SUnit *Node; diff --git a/include/llvm/CodeGen/SchedulerRegistry.h b/include/llvm/CodeGen/SchedulerRegistry.h index 4c34121d545..db70dee6c5b 100644 --- a/include/llvm/CodeGen/SchedulerRegistry.h +++ b/include/llvm/CodeGen/SchedulerRegistry.h @@ -35,7 +35,7 @@ class RegisterScheduler : public MachinePassRegistryNode { public: typedef ScheduleDAG *(*FunctionPassCtor)(SelectionDAGISel*, SelectionDAG*, - MachineBasicBlock*); + MachineBasicBlock*, bool); static MachinePassRegistry Registry; diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index 7925a007922..3ebe515b38b 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -44,10 +44,11 @@ public: std::vector TopOrder; unsigned DAGSize; CollectorMetadata *GCI; + bool FastISel; static char ID; - explicit SelectionDAGISel(TargetLowering &tli) : - FunctionPass((intptr_t)&ID), TLI(tli), DAGSize(0), GCI(0) {} + explicit SelectionDAGISel(TargetLowering &tli, bool fast = false) : + FunctionPass((intptr_t)&ID), TLI(tli), DAGSize(0), GCI(0), FastISel(fast) {} TargetLowering &getTargetLowering() { return TLI; } diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp index 40c26c290c4..8a1dade30b3 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp @@ -548,7 +548,7 @@ void LatencyPriorityQueue::AdjustPriorityOfUnscheduledPreds(SUnit *SU) { /// recognizer and deletes it when done. ScheduleDAG* llvm::createTDListDAGScheduler(SelectionDAGISel *IS, SelectionDAG *DAG, - MachineBasicBlock *BB) { + MachineBasicBlock *BB, bool Fast) { return new ScheduleDAGList(*DAG, BB, DAG->getTarget(), new LatencyPriorityQueue(), IS->CreateTargetHazardRecognizer()); diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp index f6d68f1ebd8..f881737f999 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -58,6 +58,8 @@ private: /// isBottomUp - This is true if the scheduling problem is bottom-up, false if /// it is top-down. bool isBottomUp; + + bool Fast; /// AvailableQueue - The priority queue to use for the available SUnits. SchedulingPriorityQueue *AvailableQueue; @@ -71,9 +73,9 @@ private: public: ScheduleDAGRRList(SelectionDAG &dag, MachineBasicBlock *bb, - const TargetMachine &tm, bool isbottomup, - SchedulingPriorityQueue *availqueue) - : ScheduleDAG(dag, bb, tm), isBottomUp(isbottomup), + const TargetMachine &tm, bool isbottomup, bool f, + SchedulingPriorityQueue *availqueue) + : ScheduleDAG(dag, bb, tm), isBottomUp(isbottomup), Fast(f), AvailableQueue(availqueue) { } @@ -144,36 +146,6 @@ private: /// even after dynamic insertions of new edges. /// This allows a very fast implementation of IsReachable. - - /** - The idea of the algorithm is taken from - "Online algorithms for managing the topological order of - a directed acyclic graph" by David J. Pearce and Paul H.J. Kelly - This is the MNR algorithm, which was first introduced by - A. Marchetti-Spaccamela, U. Nanni and H. Rohnert in - "Maintaining a topological order under edge insertions". - - Short description of the algorithm: - - Topological ordering, ord, of a DAG maps each node to a topological - index so that for all edges X->Y it is the case that ord(X) < ord(Y). - - This means that if there is a path from the node X to the node Z, - then ord(X) < ord(Z). - - This property can be used to check for reachability of nodes: - if Z is reachable from X, then an insertion of the edge Z->X would - create a cycle. - - The algorithm first computes a topological ordering for the DAG by initializing - the Index2Node and Node2Index arrays and then tries to keep the ordering - up-to-date after edge insertions by reordering the DAG. - - On insertion of the edge X->Y, the algorithm first marks by calling DFS the - nodes reachable from Y, and then shifts them using Shift to lie immediately - after X in Index2Node. - */ - /// InitDAGTopologicalSorting - create the initial topological /// ordering from the DAG to be scheduled. void InitDAGTopologicalSorting(); @@ -212,8 +184,10 @@ void ScheduleDAGRRList::Schedule() { DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) SUnits[su].dumpAll(&DAG)); - CalculateDepths(); - CalculateHeights(); + if (!Fast) { + CalculateDepths(); + CalculateHeights(); + } InitDAGTopologicalSorting(); AvailableQueue->initNodes(SUnits); @@ -225,8 +199,9 @@ void ScheduleDAGRRList::Schedule() { ListScheduleTopDown(); AvailableQueue->releaseState(); - - CommuteNodesToReducePressure(); + + if (!Fast) + CommuteNodesToReducePressure(); DOUT << "*** Final schedule ***\n"; DEBUG(dumpSchedule()); @@ -449,6 +424,33 @@ inline void ScheduleDAGRRList::Allocate(int n, int index) { /// InitDAGTopologicalSorting - create the initial topological /// ordering from the DAG to be scheduled. + +/// The idea of the algorithm is taken from +/// "Online algorithms for managing the topological order of +/// a directed acyclic graph" by David J. Pearce and Paul H.J. Kelly +/// This is the MNR algorithm, which was first introduced by +/// A. Marchetti-Spaccamela, U. Nanni and H. Rohnert in +/// "Maintaining a topological order under edge insertions". +/// +/// Short description of the algorithm: +/// +/// Topological ordering, ord, of a DAG maps each node to a topological +/// index so that for all edges X->Y it is the case that ord(X) < ord(Y). +/// +/// This means that if there is a path from the node X to the node Z, +/// then ord(X) < ord(Z). +/// +/// This property can be used to check for reachability of nodes: +/// if Z is reachable from X, then an insertion of the edge Z->X would +/// create a cycle. +/// +/// The algorithm first computes a topological ordering for the DAG by +/// initializing the Index2Node and Node2Index arrays and then tries to keep +/// the ordering up-to-date after edge insertions by reordering the DAG. +/// +/// On insertion of the edge X->Y, the algorithm first marks by calling DFS +/// the nodes reachable from Y, and then shifts them using Shift to lie +/// immediately after X in Index2Node. void ScheduleDAGRRList::InitDAGTopologicalSorting() { unsigned DAGSize = SUnits.size(); std::vector InDegree(DAGSize); @@ -1335,15 +1337,19 @@ namespace { const TargetInstrInfo *TII; const TargetRegisterInfo *TRI; ScheduleDAGRRList *scheduleDAG; + + bool Fast; public: explicit BURegReductionPriorityQueue(const TargetInstrInfo *tii, - const TargetRegisterInfo *tri) - : TII(tii), TRI(tri), scheduleDAG(NULL) {} + const TargetRegisterInfo *tri, + bool f) + : TII(tii), TRI(tri), scheduleDAG(NULL), Fast(f) {} void initNodes(std::vector &sunits) { SUnits = &sunits; // Add pseudo dependency edges for two-address nodes. - AddPseudoTwoAddrDeps(); + if (!Fast) + AddPseudoTwoAddrDeps(); // Calculate node priorities. CalculateSethiUllmanNumbers(); } @@ -1821,23 +1827,25 @@ void TDRegReductionPriorityQueue::CalculateSethiUllmanNumbers() { llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAGISel *IS, SelectionDAG *DAG, - MachineBasicBlock *BB) { + MachineBasicBlock *BB, + bool Fast) { const TargetInstrInfo *TII = DAG->getTarget().getInstrInfo(); const TargetRegisterInfo *TRI = DAG->getTarget().getRegisterInfo(); BURegReductionPriorityQueue *priorityQueue = - new BURegReductionPriorityQueue(TII, TRI); + new BURegReductionPriorityQueue(TII, TRI, Fast); ScheduleDAGRRList * scheduleDAG = - new ScheduleDAGRRList(*DAG, BB, DAG->getTarget(), true, priorityQueue); + new ScheduleDAGRRList(*DAG, BB, DAG->getTarget(), true, Fast,priorityQueue); priorityQueue->setScheduleDAG(scheduleDAG); return scheduleDAG; } llvm::ScheduleDAG* llvm::createTDRRListDAGScheduler(SelectionDAGISel *IS, SelectionDAG *DAG, - MachineBasicBlock *BB) { - return new ScheduleDAGRRList(*DAG, BB, DAG->getTarget(), false, + MachineBasicBlock *BB, + bool Fast) { + return new ScheduleDAGRRList(*DAG, BB, DAG->getTarget(), false, Fast, new TDRegReductionPriorityQueue()); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 8ba2b789ec6..9ee419251c6 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -266,15 +266,16 @@ namespace llvm { /// for the target. ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS, SelectionDAG *DAG, - MachineBasicBlock *BB) { + MachineBasicBlock *BB, + bool Fast) { TargetLowering &TLI = IS->getTargetLowering(); if (TLI.getSchedulingPreference() == TargetLowering::SchedulingForLatency) { - return createTDListDAGScheduler(IS, DAG, BB); + return createTDListDAGScheduler(IS, DAG, BB, Fast); } else { assert(TLI.getSchedulingPreference() == TargetLowering::SchedulingForRegPressure && "Unknown sched type!"); - return createBURRListDAGScheduler(IS, DAG, BB); + return createBURRListDAGScheduler(IS, DAG, BB, Fast); } } @@ -5611,7 +5612,7 @@ void SelectionDAGISel::ScheduleAndEmitDAG(SelectionDAG &DAG) { RegisterScheduler::setDefault(Ctor); } - ScheduleDAG *SL = Ctor(this, &DAG, BB); + ScheduleDAG *SL = Ctor(this, &DAG, BB, FastISel); BB = SL->Run(); if (ViewSUnitDAGs) SL->viewGraph(); diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index 895c2cf5140..786e92030ab 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -90,10 +90,6 @@ namespace { /// register should set this to true. bool ContainsFPCode; - /// FastISel - Enable fast(er) instruction selection. - /// - bool FastISel; - /// TM - Keep a reference to X86TargetMachine. /// X86TargetMachine &TM; @@ -116,8 +112,8 @@ namespace { public: X86DAGToDAGISel(X86TargetMachine &tm, bool fast) - : SelectionDAGISel(X86Lowering), - ContainsFPCode(false), FastISel(fast), TM(tm), + : SelectionDAGISel(X86Lowering, fast), + ContainsFPCode(false), TM(tm), X86Lowering(*TM.getTargetLowering()), Subtarget(&TM.getSubtarget()) {}