From db4170697f866dc8620946c77828ef0804996c3d Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Thu, 24 Jan 2013 02:09:57 +0000 Subject: MachineScheduler: enable biasCriticalPath for all DAGs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173318 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MachineScheduler.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/CodeGen/MachineScheduler.cpp') diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index c949266b8b..b9198e8fc6 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -563,6 +563,10 @@ void ScheduleDAGMI::releaseRoots() { for (std::vector::iterator I = SUnits.begin(), E = SUnits.end(); I != E; ++I) { SUnit *SU = &(*I); + + // Order predecessors so DFSResult follows the critical path. + SU->biasCriticalPath(); + // A SUnit is ready to top schedule if it has no predecessors. if (!I->NumPredsLeft && SU != &EntrySU) SchedImpl->releaseTopNode(SU); -- cgit v1.2.3-70-g09d2 From 178f7d08a41f2e9432b96cd27f0c8ea42fa0ac9e Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Fri, 25 Jan 2013 04:01:04 +0000 Subject: MISched: Add SchedDFSResult to ScheduleDAGMI to formalize the interface and allow other strategies to select it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173413 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineScheduler.h | 30 ++++++++++--- lib/CodeGen/MachineScheduler.cpp | 80 ++++++++++++++++++++++----------- test/CodeGen/X86/misched-matrix.ll | 3 ++ 3 files changed, 83 insertions(+), 30 deletions(-) (limited to 'lib/CodeGen/MachineScheduler.cpp') diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h index 68489884dc..cc697a50ab 100644 --- a/include/llvm/CodeGen/MachineScheduler.h +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -43,6 +43,7 @@ class MachineDominatorTree; class MachineLoopInfo; class RegisterClassInfo; class ScheduleDAGInstrs; +class SchedDFSResult; /// MachineSchedContext provides enough context from the MachineScheduler pass /// for the target to instantiate a scheduler. @@ -119,6 +120,9 @@ public: /// be scheduled at the bottom. virtual SUnit *pickNode(bool &IsTopNode) = 0; + /// \brief Scheduler callback to notify that a new subtree is scheduled. + virtual void scheduleTree(unsigned SubtreeID) {} + /// Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an /// instruction and updated scheduled/remaining flags in the DAG nodes. virtual void schedNode(SUnit *SU, bool IsTopNode) = 0; @@ -164,6 +168,8 @@ public: iterator end() { return Queue.end(); } + ArrayRef elements() { return Queue; } + iterator find(SUnit *SU) { return std::find(Queue.begin(), Queue.end(), SU); } @@ -202,6 +208,11 @@ protected: RegisterClassInfo *RegClassInfo; MachineSchedStrategy *SchedImpl; + /// Information about DAG subtrees. If DFSResult is NULL, then SchedulerTrees + /// will be empty. + SchedDFSResult *DFSResult; + BitVector ScheduledTrees; + /// Topo - A topological ordering for SUnits which permits fast IsReachable /// and similar queries. ScheduleDAGTopologicalSort Topo; @@ -243,7 +254,7 @@ protected: public: ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S): ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS), - AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S), + AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S), DFSResult(0), Topo(SUnits, &ExitSU), RPTracker(RegPressure), CurrentTop(), TopRPTracker(TopPressure), CurrentBottom(), BotRPTracker(BotPressure), NextClusterPred(NULL), NextClusterSucc(NULL) { @@ -252,10 +263,7 @@ public: #endif } - virtual ~ScheduleDAGMI() { - DeleteContainerPointers(Mutations); - delete SchedImpl; - } + virtual ~ScheduleDAGMI(); /// Add a postprocessing step to the DAG builder. /// Mutations are applied in the order that they are added after normal DAG @@ -308,6 +316,18 @@ public: const SUnit *getNextClusterSucc() const { return NextClusterSucc; } + /// Initialize a DFSResult after DAG building is complete, and before any + /// queue comparisons. + void initDFSResult(); + + /// Compute DFS result once all interesting roots are discovered. + void computeDFSResult(ArrayRef Roots); + + /// Return a non-null DFS result if the scheduling strategy initialized it. + const SchedDFSResult *getDFSResult() const { return DFSResult; } + + BitVector &getScheduledTrees() { return ScheduledTrees; } + protected: // Top-Level entry points for the schedule() driver... diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index b9198e8fc6..3e5935cca7 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -56,6 +56,9 @@ static cl::opt EnableLoadCluster("misched-cluster", cl::Hidden, static cl::opt EnableMacroFusion("misched-fusion", cl::Hidden, cl::desc("Enable scheduling for macro fusion."), cl::init(true)); +// DAG subtrees must have at least this many nodes. +static const unsigned MinSubtreeSize = 8; + //===----------------------------------------------------------------------===// // Machine Instruction Scheduling Pass and Registry //===----------------------------------------------------------------------===// @@ -301,6 +304,12 @@ void ReadyQueue::dump() { // preservation. //===----------------------------------------------------------------------===// +ScheduleDAGMI::~ScheduleDAGMI() { + delete DFSResult; + DeleteContainerPointers(Mutations); + delete SchedImpl; +} + bool ScheduleDAGMI::addEdge(SUnit *SuccSU, const SDep &PredDep) { if (SuccSU != &ExitSU) { // Do not use WillCreateCycle, it assumes SD scheduling. @@ -504,8 +513,6 @@ void ScheduleDAGMI::schedule() { DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) SUnits[su].dumpAll(this)); - if (ViewMISchedDAGs) viewGraph(); - initQueues(); bool IsTopNode = false; @@ -554,6 +561,19 @@ void ScheduleDAGMI::postprocessDAG() { } } +void ScheduleDAGMI::initDFSResult() { + if (!DFSResult) + DFSResult = new SchedDFSResult(/*BottomU*/true, MinSubtreeSize); + DFSResult->clear(); + DFSResult->resize(SUnits.size()); + ScheduledTrees.clear(); +} + +void ScheduleDAGMI::computeDFSResult(ArrayRef Roots) { + DFSResult->compute(Roots); + ScheduledTrees.resize(DFSResult->getNumSubtrees()); +} + // Release all DAG roots for scheduling. // // Nodes with unreleased weak edges can still be roots. @@ -655,6 +675,15 @@ void ScheduleDAGMI::updateQueues(SUnit *SU, bool IsTopNode) { SU->isScheduled = true; + if (DFSResult) { + unsigned SubtreeID = DFSResult->getSubtreeID(SU); + if (!ScheduledTrees.test(SubtreeID)) { + ScheduledTrees.set(SubtreeID); + DFSResult->scheduleTree(SubtreeID); + SchedImpl->scheduleTree(SubtreeID); + } + } + // Notify the scheduling strategy after updating the DAG. SchedImpl->schedNode(SU, IsTopNode); } @@ -1187,6 +1216,8 @@ void ConvergingScheduler::initialize(ScheduleDAGMI *dag) { Top.init(DAG, SchedModel, &Rem); Bot.init(DAG, SchedModel, &Rem); + DAG->initDFSResult(); + // Initialize resource counts. // Initialize the HazardRecognizers. If itineraries don't exist, are empty, or @@ -1247,6 +1278,8 @@ void ConvergingScheduler::registerRoots() { Rem.CriticalPath = (*I)->getDepth(); } DEBUG(dbgs() << "Critical Path: " << Rem.CriticalPath << '\n'); + + DAG->computeDFSResult(Bot.Available.elements()); } /// Does this SU have a hazard within the current instruction group. @@ -2056,12 +2089,11 @@ ConvergingSchedRegistry("converge", "Standard converging scheduler.", namespace { /// \brief Order nodes by the ILP metric. struct ILPOrder { - SchedDFSResult *DFSResult; - BitVector *ScheduledTrees; + const SchedDFSResult *DFSResult; + const BitVector *ScheduledTrees; bool MaximizeILP; - ILPOrder(SchedDFSResult *dfs, BitVector *schedtrees, bool MaxILP) - : DFSResult(dfs), ScheduledTrees(schedtrees), MaximizeILP(MaxILP) {} + ILPOrder(bool MaxILP): DFSResult(0), ScheduledTrees(0), MaximizeILP(MaxILP) {} /// \brief Apply a less-than relation on node priority. /// @@ -2099,26 +2131,23 @@ class ILPScheduler : public MachineSchedStrategy { /// (a motivating test case must be found). static const unsigned SubtreeLimit = 16; - SchedDFSResult DFSResult; - BitVector ScheduledTrees; + ScheduleDAGMI *DAG; ILPOrder Cmp; std::vector ReadyQ; public: - ILPScheduler(bool MaximizeILP) - : DFSResult(/*BottomUp=*/true, SubtreeLimit), - Cmp(&DFSResult, &ScheduledTrees, MaximizeILP) {} + ILPScheduler(bool MaximizeILP): DAG(0), Cmp(MaximizeILP) {} - virtual void initialize(ScheduleDAGMI *DAG) { + virtual void initialize(ScheduleDAGMI *dag) { + DAG = dag; + DAG->initDFSResult(); + Cmp.DFSResult = DAG->getDFSResult(); + Cmp.ScheduledTrees = &DAG->getScheduledTrees(); ReadyQ.clear(); - DFSResult.clear(); - DFSResult.resize(DAG->SUnits.size()); - ScheduledTrees.clear(); } virtual void registerRoots() { - DFSResult.compute(ReadyQ); - ScheduledTrees.resize(DFSResult.getNumSubtrees()); + DAG->computeDFSResult(ReadyQ); // Restore the heap in ReadyQ with the updated DFS results. std::make_heap(ReadyQ.begin(), ReadyQ.end(), Cmp); } @@ -2135,21 +2164,22 @@ public: IsTopNode = false; DEBUG(dbgs() << "*** Scheduling " << "SU(" << SU->NodeNum << "): " << *SU->getInstr() - << " ILP: " << DFSResult.getILP(SU) - << " Tree: " << DFSResult.getSubtreeID(SU) << " @" - << DFSResult.getSubtreeLevel(DFSResult.getSubtreeID(SU))<< '\n'); + << " ILP: " << DAG->getDFSResult()->getILP(SU) + << " Tree: " << DAG->getDFSResult()->getSubtreeID(SU) << " @" + << DAG->getDFSResult()->getSubtreeLevel( + DAG->getDFSResult()->getSubtreeID(SU)) << '\n'); return SU; } + /// \brief Scheduler callback to notify that a new subtree is scheduled. + virtual void scheduleTree(unsigned SubtreeID) { + std::make_heap(ReadyQ.begin(), ReadyQ.end(), Cmp); + } + /// Callback after a node is scheduled. Mark a newly scheduled tree, notify /// DFSResults, and resort the priority Q. virtual void schedNode(SUnit *SU, bool IsTopNode) { assert(!IsTopNode && "SchedDFSResult needs bottom-up"); - if (!ScheduledTrees.test(DFSResult.getSubtreeID(SU))) { - ScheduledTrees.set(DFSResult.getSubtreeID(SU)); - DFSResult.scheduleTree(DFSResult.getSubtreeID(SU)); - std::make_heap(ReadyQ.begin(), ReadyQ.end(), Cmp); - } } virtual void releaseTopNode(SUnit *) { /*only called for top roots*/ } diff --git a/test/CodeGen/X86/misched-matrix.ll b/test/CodeGen/X86/misched-matrix.ll index f5566e5e5d..d00d17392a 100644 --- a/test/CodeGen/X86/misched-matrix.ll +++ b/test/CodeGen/X86/misched-matrix.ll @@ -8,6 +8,9 @@ ; RUN: -misched=ilpmax -verify-machineinstrs \ ; RUN: | FileCheck %s -check-prefix=ILPMAX ; +; Very temporary xfail during SchedDFSResult churn. +; XFAIL: * +; ; Verify that the MI scheduler minimizes register pressure for a ; uniform set of bottom-up subtrees (unrolled matrix multiply). ; -- cgit v1.2.3-70-g09d2 From 4e1fb1894048455d49d62543b3f83672b27b0000 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Fri, 25 Jan 2013 06:33:57 +0000 Subject: MIsched: Improve the interface to SchedDFS analysis (subtrees). Allow the strategy to select SchedDFS. Allow the results of SchedDFS to affect initialization of the scheduler state. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173425 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineScheduler.h | 14 +++--- include/llvm/CodeGen/ScheduleDFS.h | 7 ++- lib/CodeGen/MachineScheduler.cpp | 62 ++++++++++++++------------ lib/CodeGen/ScheduleDAGInstrs.cpp | 14 +++--- lib/Target/Hexagon/HexagonMachineScheduler.cpp | 8 +++- test/CodeGen/X86/misched-matrix.ll | 3 -- 6 files changed, 61 insertions(+), 47 deletions(-) (limited to 'lib/CodeGen/MachineScheduler.cpp') diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h index cc697a50ab..aa78f5285a 100644 --- a/include/llvm/CodeGen/MachineScheduler.h +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -316,12 +316,9 @@ public: const SUnit *getNextClusterSucc() const { return NextClusterSucc; } - /// Initialize a DFSResult after DAG building is complete, and before any + /// Compute a DFSResult after DAG building is complete, and before any /// queue comparisons. - void initDFSResult(); - - /// Compute DFS result once all interesting roots are discovered. - void computeDFSResult(ArrayRef Roots); + void computeDFSResult(); /// Return a non-null DFS result if the scheduling strategy initialized it. const SchedDFSResult *getDFSResult() const { return DFSResult; } @@ -341,8 +338,8 @@ protected: /// instances of ScheduleDAGMI to perform custom DAG postprocessing. void postprocessDAG(); - /// Identify DAG roots and setup scheduler queues. - void initQueues(); + /// Release ExitSU predecessors and setup scheduler queues. + void initQueues(ArrayRef TopRoots, ArrayRef BotRoots); /// Move an instruction and update register pressure. void scheduleMI(SUnit *SU, bool IsTopNode); @@ -365,7 +362,8 @@ protected: void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos); bool checkSchedLimit(); - void releaseRoots(); + void findRootsAndBiasEdges(SmallVectorImpl &TopRoots, + SmallVectorImpl &BotRoots); void releaseSucc(SUnit *SU, SDep *SuccEdge); void releaseSuccessors(SUnit *SU); diff --git a/include/llvm/CodeGen/ScheduleDFS.h b/include/llvm/CodeGen/ScheduleDFS.h index 54b223269e..e07929290e 100644 --- a/include/llvm/CodeGen/ScheduleDFS.h +++ b/include/llvm/CodeGen/ScheduleDFS.h @@ -127,7 +127,7 @@ public: } /// \brief Compute various metrics for the DAG with given roots. - void compute(ArrayRef Roots); + void compute(ArrayRef SUnits); /// \brief Get the ILP value for a DAG node. /// @@ -140,7 +140,12 @@ public: unsigned getNumSubtrees() const { return SubtreeConnectLevels.size(); } /// \brief Get the ID of the subtree the given DAG node belongs to. + /// + /// For convenience, if DFSResults have not been computed yet, give everything + /// tree ID 0. unsigned getSubtreeID(const SUnit *SU) const { + if (empty()) + return 0; assert(SU->NodeNum < DFSData.size() && "New Node"); return DFSData[SU->NodeNum].SubtreeID; } diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index 3e5935cca7..aa599158e9 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -510,10 +510,19 @@ void ScheduleDAGMI::schedule() { postprocessDAG(); + SmallVector TopRoots, BotRoots; + findRootsAndBiasEdges(TopRoots, BotRoots); + + // Initialize the strategy before modifying the DAG. + // This may initialize a DFSResult to be used for queue priority. + SchedImpl->initialize(this); + DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) SUnits[su].dumpAll(this)); + if (ViewMISchedDAGs) viewGraph(); - initQueues(); + // Initialize ready queues now that the DAG and priority data are finalized. + initQueues(TopRoots, BotRoots); bool IsTopNode = false; while (SUnit *SU = SchedImpl->pickNode(IsTopNode)) { @@ -561,25 +570,18 @@ void ScheduleDAGMI::postprocessDAG() { } } -void ScheduleDAGMI::initDFSResult() { +void ScheduleDAGMI::computeDFSResult() { if (!DFSResult) DFSResult = new SchedDFSResult(/*BottomU*/true, MinSubtreeSize); DFSResult->clear(); - DFSResult->resize(SUnits.size()); ScheduledTrees.clear(); -} - -void ScheduleDAGMI::computeDFSResult(ArrayRef Roots) { - DFSResult->compute(Roots); + DFSResult->resize(SUnits.size()); + DFSResult->compute(SUnits); ScheduledTrees.resize(DFSResult->getNumSubtrees()); } -// Release all DAG roots for scheduling. -// -// Nodes with unreleased weak edges can still be roots. -void ScheduleDAGMI::releaseRoots() { - SmallVector BotRoots; - +void ScheduleDAGMI::findRootsAndBiasEdges(SmallVectorImpl &TopRoots, + SmallVectorImpl &BotRoots) { for (std::vector::iterator I = SUnits.begin(), E = SUnits.end(); I != E; ++I) { SUnit *SU = &(*I); @@ -589,28 +591,33 @@ void ScheduleDAGMI::releaseRoots() { // A SUnit is ready to top schedule if it has no predecessors. if (!I->NumPredsLeft && SU != &EntrySU) - SchedImpl->releaseTopNode(SU); + TopRoots.push_back(SU); // A SUnit is ready to bottom schedule if it has no successors. if (!I->NumSuccsLeft && SU != &ExitSU) BotRoots.push_back(SU); } - // Release bottom roots in reverse order so the higher priority nodes appear - // first. This is more natural and slightly more efficient. - for (SmallVectorImpl::const_reverse_iterator - I = BotRoots.rbegin(), E = BotRoots.rend(); I != E; ++I) - SchedImpl->releaseBottomNode(*I); } /// Identify DAG roots and setup scheduler queues. -void ScheduleDAGMI::initQueues() { +void ScheduleDAGMI::initQueues(ArrayRef TopRoots, + ArrayRef BotRoots) { NextClusterSucc = NULL; NextClusterPred = NULL; - // Initialize the strategy before modifying the DAG. - SchedImpl->initialize(this); - // Release all DAG roots for scheduling, not including EntrySU/ExitSU. - releaseRoots(); + // + // Nodes with unreleased weak edges can still be roots. + // Release top roots in forward order. + for (SmallVectorImpl::const_iterator + I = TopRoots.begin(), E = TopRoots.end(); I != E; ++I) { + SchedImpl->releaseTopNode(*I); + } + // Release bottom roots in reverse order so the higher priority nodes appear + // first. This is more natural and slightly more efficient. + for (SmallVectorImpl::const_reverse_iterator + I = BotRoots.rbegin(), E = BotRoots.rend(); I != E; ++I) { + SchedImpl->releaseBottomNode(*I); + } releaseSuccessors(&EntrySU); releasePredecessors(&ExitSU); @@ -1216,7 +1223,7 @@ void ConvergingScheduler::initialize(ScheduleDAGMI *dag) { Top.init(DAG, SchedModel, &Rem); Bot.init(DAG, SchedModel, &Rem); - DAG->initDFSResult(); + DAG->computeDFSResult(); // Initialize resource counts. @@ -1278,8 +1285,6 @@ void ConvergingScheduler::registerRoots() { Rem.CriticalPath = (*I)->getDepth(); } DEBUG(dbgs() << "Critical Path: " << Rem.CriticalPath << '\n'); - - DAG->computeDFSResult(Bot.Available.elements()); } /// Does this SU have a hazard within the current instruction group. @@ -2140,14 +2145,13 @@ public: virtual void initialize(ScheduleDAGMI *dag) { DAG = dag; - DAG->initDFSResult(); + DAG->computeDFSResult(); Cmp.DFSResult = DAG->getDFSResult(); Cmp.ScheduledTrees = &DAG->getScheduledTrees(); ReadyQ.clear(); } virtual void registerRoots() { - DAG->computeDFSResult(ReadyQ); // Restore the heap in ReadyQ with the updated DFS results. std::make_heap(ReadyQ.begin(), ReadyQ.end(), Cmp); } diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp index 428c1a4032..7ee5207570 100644 --- a/lib/CodeGen/ScheduleDAGInstrs.cpp +++ b/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -1188,16 +1188,20 @@ static bool hasDataSucc(const SUnit *SU) { /// Compute an ILP metric for all nodes in the subDAG reachable via depth-first /// search from this root. -void SchedDFSResult::compute(ArrayRef Roots) { +void SchedDFSResult::compute(ArrayRef SUnits) { if (!IsBottomUp) llvm_unreachable("Top-down ILP metric is unimplemnted"); SchedDFSImpl Impl(*this); - for (ArrayRef::const_iterator - RootI = Roots.begin(), RootE = Roots.end(); RootI != RootE; ++RootI) { + for (ArrayRef::const_iterator + SI = SUnits.begin(), SE = SUnits.end(); SI != SE; ++SI) { + const SUnit *SU = &*SI; + if (Impl.isVisited(SU) || hasDataSucc(SU)) + continue; + SchedDAGReverseDFS DFS; - Impl.visitPreorder(*RootI); - DFS.follow(*RootI); + Impl.visitPreorder(SU); + DFS.follow(SU); for (;;) { // Traverse the leftmost path as far as possible. while (DFS.getPred() != DFS.getPredEnd()) { diff --git a/lib/Target/Hexagon/HexagonMachineScheduler.cpp b/lib/Target/Hexagon/HexagonMachineScheduler.cpp index aef6830752..36dfaa4233 100644 --- a/lib/Target/Hexagon/HexagonMachineScheduler.cpp +++ b/lib/Target/Hexagon/HexagonMachineScheduler.cpp @@ -152,6 +152,12 @@ void VLIWMachineScheduler::schedule() { // Postprocess the DAG to add platform specific artificial dependencies. postprocessDAG(); + SmallVector TopRoots, BotRoots; + findRootsAndBiasEdges(TopRoots, BotRoots); + + // Initialize the strategy before modifying the DAG. + SchedImpl->initialize(this); + // To view Height/Depth correctly, they should be accessed at least once. DEBUG(unsigned maxH = 0; for (unsigned su = 0, e = SUnits.size(); su != e; ++su) @@ -166,7 +172,7 @@ void VLIWMachineScheduler::schedule() { DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) SUnits[su].dumpAll(this)); - initQueues(); + initQueues(TopRoots, BotRoots); bool IsTopNode = false; while (SUnit *SU = SchedImpl->pickNode(IsTopNode)) { diff --git a/test/CodeGen/X86/misched-matrix.ll b/test/CodeGen/X86/misched-matrix.ll index d00d17392a..f5566e5e5d 100644 --- a/test/CodeGen/X86/misched-matrix.ll +++ b/test/CodeGen/X86/misched-matrix.ll @@ -8,9 +8,6 @@ ; RUN: -misched=ilpmax -verify-machineinstrs \ ; RUN: | FileCheck %s -check-prefix=ILPMAX ; -; Very temporary xfail during SchedDFSResult churn. -; XFAIL: * -; ; Verify that the MI scheduler minimizes register pressure for a ; uniform set of bottom-up subtrees (unrolled matrix multiply). ; -- cgit v1.2.3-70-g09d2 From 3084979ff27f48487c7421536144c41a36cae997 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Fri, 25 Jan 2013 07:45:29 +0000 Subject: MachineScheduler support for viewGraph. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173432 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineScheduler.h | 3 ++ include/llvm/CodeGen/ScheduleDAG.h | 4 +- lib/CodeGen/MachineScheduler.cpp | 89 ++++++++++++++++++++++++++++++++- 3 files changed, 93 insertions(+), 3 deletions(-) (limited to 'lib/CodeGen/MachineScheduler.cpp') diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h index aa78f5285a..2e39161d11 100644 --- a/include/llvm/CodeGen/MachineScheduler.h +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -325,6 +325,9 @@ public: BitVector &getScheduledTrees() { return ScheduledTrees; } + void viewGraph(const Twine &Name, const Twine &Title) LLVM_OVERRIDE; + void viewGraph() LLVM_OVERRIDE; + protected: // Top-Level entry points for the schedule() driver... diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 18bef1c402..6792269810 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -578,8 +578,8 @@ namespace llvm { /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered /// using 'dot'. /// - void viewGraph(const Twine &Name, const Twine &Title); - void viewGraph(); + virtual void viewGraph(const Twine &Name, const Twine &Title); + virtual void viewGraph(); virtual void dumpNode(const SUnit *SU) const = 0; diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index aa599158e9..9072dd4b71 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -26,6 +26,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/GraphWriter.h" #include "llvm/Support/raw_ostream.h" #include @@ -557,7 +558,6 @@ void ScheduleDAGMI::buildDAGWithRegPressure() { // Build the DAG, and compute current register pressure. buildSchedGraph(AA, &RPTracker); - if (ViewMISchedDAGs) viewGraph(); // Initialize top/bottom trackers after computing region pressure. initRegPressure(); @@ -2294,3 +2294,90 @@ static MachineSchedRegistry ShufflerRegistry( "shuffle", "Shuffle machine instructions alternating directions", createInstructionShuffler); #endif // !NDEBUG + +//===----------------------------------------------------------------------===// +// GraphWriter support for ScheduleDAGMI. +//===----------------------------------------------------------------------===// + +#ifndef NDEBUG +namespace llvm { + +template<> struct GraphTraits< + ScheduleDAGMI*> : public GraphTraits {}; + +template<> +struct DOTGraphTraits : public DefaultDOTGraphTraits { + + DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} + + static std::string getGraphName(const ScheduleDAG *G) { + return G->MF.getName(); + } + + static bool renderGraphFromBottomUp() { + return true; + } + + static bool isNodeHidden(const SUnit *Node) { + return (Node->NumPreds > 10 || Node->NumSuccs > 10); + } + + static bool hasNodeAddressLabel(const SUnit *Node, + const ScheduleDAG *Graph) { + return false; + } + + /// If you want to override the dot attributes printed for a particular + /// edge, override this method. + static std::string getEdgeAttributes(const SUnit *Node, + SUnitIterator EI, + const ScheduleDAG *Graph) { + if (EI.isArtificialDep()) + return "color=cyan,style=dashed"; + if (EI.isCtrlDep()) + return "color=blue,style=dashed"; + return ""; + } + + static std::string getNodeLabel(const SUnit *SU, const ScheduleDAG *G) { + std::string Str; + raw_string_ostream SS(Str); + SS << "SU(" << SU->NodeNum << ')'; + return SS.str(); + } + static std::string getNodeDescription(const SUnit *SU, const ScheduleDAG *G) { + return G->getGraphNodeLabel(SU); + } + + static std::string getNodeAttributes(const SUnit *N, + const ScheduleDAG *Graph) { + std::string Str("shape=Mrecord"); + const SchedDFSResult *DFS = + static_cast(Graph)->getDFSResult(); + if (DFS) { + Str += ",style=filled,fillcolor=\"#"; + Str += DOT::getColorString(DFS->getSubtreeID(N)); + Str += '"'; + } + return Str; + } +}; +} // namespace llvm +#endif // NDEBUG + +/// viewGraph - Pop up a ghostview window with the reachable parts of the DAG +/// rendered using 'dot'. +/// +void ScheduleDAGMI::viewGraph(const Twine &Name, const Twine &Title) { +#ifndef NDEBUG + ViewGraph(this, Name, false, Title); +#else + errs() << "ScheduleDAGMI::viewGraph is only available in debug builds on " + << "systems with Graphviz or gv!\n"; +#endif // NDEBUG +} + +/// Out-of-line implementation with no arguments is handy for gdb. +void ScheduleDAGMI::viewGraph() { + viewGraph(getDAGName(), "Scheduling-Units Graph for " + getDAGName()); +} -- cgit v1.2.3-70-g09d2 From c855423ff2a18e2168324ac5902cfe862cd4b54f Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Fri, 25 Jan 2013 07:45:31 +0000 Subject: MIsched: Print block name. No functionality. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173433 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MachineScheduler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/CodeGen/MachineScheduler.cpp') diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index 9072dd4b71..821a4f2027 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -263,7 +263,8 @@ bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) { } DEBUG(dbgs() << "********** MI Scheduling **********\n"); DEBUG(dbgs() << MF->getName() - << ":BB#" << MBB->getNumber() << "\n From: " << *I << " To: "; + << ":BB#" << MBB->getNumber() << " " << MBB->getName() + << "\n From: " << *I << " To: "; if (RegionEnd != MBB->end()) dbgs() << *RegionEnd; else dbgs() << "End"; dbgs() << " Remaining: " << RemainingInstrs << "\n"); -- cgit v1.2.3-70-g09d2 From b74564a15ac6bfa85c9597bed842b686be1a1a62 Mon Sep 17 00:00:00 2001 From: Jakub Staszak Date: Fri, 25 Jan 2013 21:44:27 +0000 Subject: Use const reference instead of vector copying. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173497 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MachineScheduler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/CodeGen/MachineScheduler.cpp') diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index 821a4f2027..adf9a57dde 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -467,7 +467,8 @@ void ScheduleDAGMI::initRegPressure() { // Cache the list of excess pressure sets in this region. This will also track // the max pressure in the scheduled code for these sets. RegionCriticalPSets.clear(); - std::vector RegionPressure = RPTracker.getPressure().MaxSetPressure; + const std::vector &RegionPressure = + RPTracker.getPressure().MaxSetPressure; for (unsigned i = 0, e = RegionPressure.size(); i < e; ++i) { unsigned Limit = TRI->getRegPressureSetLimit(i); DEBUG(dbgs() << TRI->getRegPressureSetName(i) -- cgit v1.2.3-70-g09d2 From 4c6a2ba4e01ef75837bb39808a3935bd8687ce67 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Tue, 29 Jan 2013 06:26:35 +0000 Subject: MIsched: cleanup code. Use isBoundaryNode(). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173775 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MachineScheduler.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/CodeGen/MachineScheduler.cpp') diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index adf9a57dde..513d8a9268 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -587,17 +587,19 @@ void ScheduleDAGMI::findRootsAndBiasEdges(SmallVectorImpl &TopRoots, for (std::vector::iterator I = SUnits.begin(), E = SUnits.end(); I != E; ++I) { SUnit *SU = &(*I); + assert(!SU->isBoundaryNode() && "Boundary node should not be in SUnits"); // Order predecessors so DFSResult follows the critical path. SU->biasCriticalPath(); // A SUnit is ready to top schedule if it has no predecessors. - if (!I->NumPredsLeft && SU != &EntrySU) + if (!I->NumPredsLeft) TopRoots.push_back(SU); // A SUnit is ready to bottom schedule if it has no successors. - if (!I->NumSuccsLeft && SU != &ExitSU) + if (!I->NumSuccsLeft) BotRoots.push_back(SU); } + ExitSU.biasCriticalPath(); } /// Identify DAG roots and setup scheduler queues. -- cgit v1.2.3-70-g09d2 From ecb8c2ba6029f02b01b20b110cc1b3b3ea2e1f1c Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Wed, 13 Feb 2013 19:22:27 +0000 Subject: MIsched: HazardRecognizers are created for each DAG. Free them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175067 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MachineScheduler.cpp | 7 ++++++- lib/Target/Hexagon/HexagonMachineScheduler.cpp | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'lib/CodeGen/MachineScheduler.cpp') diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index 513d8a9268..ddaf56627b 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -1054,6 +1054,9 @@ public: #endif void reset() { + // A new HazardRec is created for each DAG and owned by SchedBoundary. + delete HazardRec; + Available.clear(); Pending.clear(); CheckPending = false; @@ -1079,7 +1082,8 @@ public: /// PendingFlag set. SchedBoundary(unsigned ID, const Twine &Name): DAG(0), SchedModel(0), Rem(0), Available(ID, Name+".A"), - Pending(ID << ConvergingScheduler::LogMaxQID, Name+".P") { + Pending(ID << ConvergingScheduler::LogMaxQID, Name+".P"), + HazardRec(0) { reset(); } @@ -1223,6 +1227,7 @@ void ConvergingScheduler::initialize(ScheduleDAGMI *dag) { DAG = dag; SchedModel = DAG->getSchedModel(); TRI = DAG->TRI; + Rem.init(DAG, SchedModel); Top.init(DAG, SchedModel, &Rem); Bot.init(DAG, SchedModel, &Rem); diff --git a/lib/Target/Hexagon/HexagonMachineScheduler.cpp b/lib/Target/Hexagon/HexagonMachineScheduler.cpp index 36dfaa4233..ced17b3c0a 100644 --- a/lib/Target/Hexagon/HexagonMachineScheduler.cpp +++ b/lib/Target/Hexagon/HexagonMachineScheduler.cpp @@ -192,6 +192,7 @@ void ConvergingVLIWScheduler::initialize(ScheduleDAGMI *dag) { DAG = static_cast(dag); SchedModel = DAG->getSchedModel(); TRI = DAG->TRI; + Top.init(DAG, SchedModel); Bot.init(DAG, SchedModel); @@ -199,6 +200,8 @@ void ConvergingVLIWScheduler::initialize(ScheduleDAGMI *dag) { // are disabled, then these HazardRecs will be disabled. const InstrItineraryData *Itin = DAG->getSchedModel()->getInstrItineraries(); const TargetMachine &TM = DAG->MF.getTarget(); + delete Top.HazardRec; + delete Bot.HazardRec; Top.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG); Bot.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG); @@ -683,4 +686,3 @@ void ConvergingVLIWScheduler::schedNode(SUnit *SU, bool IsTopNode) { Bot.bumpNode(SU); } } - -- cgit v1.2.3-70-g09d2 From b717a5084722a5cad843444a8b1b4bf53f1c6325 Mon Sep 17 00:00:00 2001 From: Jakub Staszak Date: Sat, 16 Feb 2013 15:47:26 +0000 Subject: Use const reference instead of vector object when passing an argument to updateScheduledPressure method. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175362 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineScheduler.h | 2 +- lib/CodeGen/MachineScheduler.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/CodeGen/MachineScheduler.cpp') diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h index 2e39161d11..57febe7746 100644 --- a/include/llvm/CodeGen/MachineScheduler.h +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -360,7 +360,7 @@ protected: void initRegPressure(); - void updateScheduledPressure(std::vector NewMaxPressure); + void updateScheduledPressure(const std::vector &NewMaxPressure); void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos); bool checkSchedLimit(); diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index ddaf56627b..589fa1fa02 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -487,7 +487,7 @@ void ScheduleDAGMI::initRegPressure() { // FIXME: When the pressure tracker deals in pressure differences then we won't // iterate over all RegionCriticalPSets[i]. void ScheduleDAGMI:: -updateScheduledPressure(std::vector NewMaxPressure) { +updateScheduledPressure(const std::vector &NewMaxPressure) { for (unsigned i = 0, e = RegionCriticalPSets.size(); i < e; ++i) { unsigned ID = RegionCriticalPSets[i].PSetID; int &MaxUnits = RegionCriticalPSets[i].UnitIncrease; -- cgit v1.2.3-70-g09d2