diff options
author | Derek Schuff <dschuff@chromium.org> | 2013-01-09 16:55:43 -0800 |
---|---|---|
committer | Derek Schuff <dschuff@chromium.org> | 2013-01-11 13:47:37 -0800 |
commit | b770d0e0636a4b5ad61b1ca661caee67576c05fc (patch) | |
tree | c486ce032d41f97313c50629bd5b879f53e6ccbf /lib/CodeGen/MachineScheduler.cpp | |
parent | b835840cf112a6178506d834b58aa625f59a8994 (diff) | |
parent | 1ad9253c9d34ccbce3e7e4ea5d87c266cbf93410 (diff) |
Merge commit '1ad9253c9d34ccbce3e7e4ea5d87c266cbf93410'
deplib features commented out due to removal upstream;
will add back as a localmod
Conflicts:
include/llvm/ADT/Triple.h
include/llvm/MC/MCAssembler.h
include/llvm/Target/TargetFrameLowering.h
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.h
lib/CodeGen/BranchFolding.cpp
lib/LLVMBuild.txt
lib/Linker/LinkArchives.cpp
lib/MC/MCAssembler.cpp
lib/MC/MCELFStreamer.cpp
lib/Makefile
lib/Target/ARM/ARMExpandPseudoInsts.cpp
lib/Target/ARM/ARMFrameLowering.cpp
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMSubtarget.h
lib/Target/ARM/ARMTargetObjectFile.cpp
lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
lib/Target/Mips/MipsInstrFPU.td
lib/Target/Mips/MipsInstrInfo.td
lib/Target/X86/X86CodeEmitter.cpp
lib/Target/X86/X86Subtarget.h
lib/VMCore/Module.cpp
test/MC/MachO/ARM/nop-armv4-padding.s
tools/Makefile
tools/llc/llc.cpp
tools/lto/LTOModule.cpp
tools/lto/lto.cpp
Diffstat (limited to 'lib/CodeGen/MachineScheduler.cpp')
-rw-r--r-- | lib/CodeGen/MachineScheduler.cpp | 92 |
1 files changed, 70 insertions, 22 deletions
diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index 8d43360e67..c7afa08fcd 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -14,20 +14,19 @@ #define DEBUG_TYPE "misched" -#include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/MachineScheduler.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/PriorityQueue.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/RegisterClassInfo.h" -#include "llvm/CodeGen/ScheduleDAGILP.h" +#include "llvm/CodeGen/ScheduleDFS.h" #include "llvm/CodeGen/ScheduleHazardRecognizer.h" -#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/PriorityQueue.h" - #include <queue> using namespace llvm; @@ -533,7 +532,7 @@ void ScheduleDAGMI::schedule() { placeDebugValues(); DEBUG({ - unsigned BBNum = top()->getParent()->getNumber(); + unsigned BBNum = begin()->getParent()->getNumber(); dbgs() << "*** Final schedule for BB#" << BBNum << " ***\n"; dumpSchedule(); dbgs() << '\n'; @@ -603,7 +602,11 @@ void ScheduleDAGMI::initQueues() { SchedImpl->registerRoots(); + // Advance past initial DebugValues. + assert(TopRPTracker.getPos() == RegionBegin && "bad initial Top tracker"); CurrentTop = nextIfDebug(RegionBegin, RegionEnd); + TopRPTracker.setPos(CurrentTop); + CurrentBottom = RegionEnd; } @@ -674,6 +677,8 @@ void ScheduleDAGMI::placeDebugValues() { std::pair<MachineInstr *, MachineInstr *> P = *prior(DI); MachineInstr *DbgValue = P.first; MachineBasicBlock::iterator OrigPrevMI = P.second; + if (&*RegionBegin == DbgValue) + ++RegionBegin; BB->splice(++OrigPrevMI, BB, DbgValue); if (OrigPrevMI == llvm::prior(RegionEnd)) RegionEnd = DbgValue; @@ -2054,58 +2059,101 @@ ConvergingSchedRegistry("converge", "Standard converging scheduler.", namespace { /// \brief Order nodes by the ILP metric. struct ILPOrder { - ScheduleDAGILP *ILP; + SchedDFSResult *DFSResult; + BitVector *ScheduledTrees; bool MaximizeILP; - ILPOrder(ScheduleDAGILP *ilp, bool MaxILP): ILP(ilp), MaximizeILP(MaxILP) {} + ILPOrder(SchedDFSResult *dfs, BitVector *schedtrees, bool MaxILP) + : DFSResult(dfs), ScheduledTrees(schedtrees), MaximizeILP(MaxILP) {} /// \brief Apply a less-than relation on node priority. + /// + /// (Return true if A comes after B in the Q.) bool operator()(const SUnit *A, const SUnit *B) const { - // Return true if A comes after B in the Q. + unsigned SchedTreeA = DFSResult->getSubtreeID(A); + unsigned SchedTreeB = DFSResult->getSubtreeID(B); + if (SchedTreeA != SchedTreeB) { + // Unscheduled trees have lower priority. + if (ScheduledTrees->test(SchedTreeA) != ScheduledTrees->test(SchedTreeB)) + return ScheduledTrees->test(SchedTreeB); + + // Trees with shallower connections have have lower priority. + if (DFSResult->getSubtreeLevel(SchedTreeA) + != DFSResult->getSubtreeLevel(SchedTreeB)) { + return DFSResult->getSubtreeLevel(SchedTreeA) + < DFSResult->getSubtreeLevel(SchedTreeB); + } + } if (MaximizeILP) - return ILP->getILP(A) < ILP->getILP(B); + return DFSResult->getILP(A) < DFSResult->getILP(B); else - return ILP->getILP(A) > ILP->getILP(B); + return DFSResult->getILP(A) > DFSResult->getILP(B); } }; /// \brief Schedule based on the ILP metric. class ILPScheduler : public MachineSchedStrategy { - ScheduleDAGILP ILP; + /// In case all subtrees are eventually connected to a common root through + /// data dependence (e.g. reduction), place an upper limit on their size. + /// + /// FIXME: A subtree limit is generally good, but in the situation commented + /// above, where multiple similar subtrees feed a common root, we should + /// only split at a point where the resulting subtrees will be balanced. + /// (a motivating test case must be found). + static const unsigned SubtreeLimit = 16; + + SchedDFSResult DFSResult; + BitVector ScheduledTrees; ILPOrder Cmp; std::vector<SUnit*> ReadyQ; public: ILPScheduler(bool MaximizeILP) - : ILP(/*BottomUp=*/true), Cmp(&ILP, MaximizeILP) {} + : DFSResult(/*BottomUp=*/true, SubtreeLimit), + Cmp(&DFSResult, &ScheduledTrees, MaximizeILP) {} virtual void initialize(ScheduleDAGMI *DAG) { ReadyQ.clear(); - ILP.resize(DAG->SUnits.size()); + DFSResult.clear(); + DFSResult.resize(DAG->SUnits.size()); + ScheduledTrees.clear(); } virtual void registerRoots() { - for (std::vector<SUnit*>::const_iterator - I = ReadyQ.begin(), E = ReadyQ.end(); I != E; ++I) { - ILP.computeILP(*I); - } + DFSResult.compute(ReadyQ); + ScheduledTrees.resize(DFSResult.getNumSubtrees()); + // Restore the heap in ReadyQ with the updated DFS results. + std::make_heap(ReadyQ.begin(), ReadyQ.end(), Cmp); } /// Implement MachineSchedStrategy interface. /// ----------------------------------------- + /// Callback to select the highest priority node from the ready Q. virtual SUnit *pickNode(bool &IsTopNode) { if (ReadyQ.empty()) return NULL; pop_heap(ReadyQ.begin(), ReadyQ.end(), Cmp); SUnit *SU = ReadyQ.back(); ReadyQ.pop_back(); IsTopNode = false; - DEBUG(dbgs() << "*** Scheduling " << *SU->getInstr() - << " ILP: " << ILP.getILP(SU) << '\n'); + DEBUG(dbgs() << "*** Scheduling " << "SU(" << SU->NodeNum << "): " + << *SU->getInstr() + << " ILP: " << DFSResult.getILP(SU) + << " Tree: " << DFSResult.getSubtreeID(SU) << " @" + << DFSResult.getSubtreeLevel(DFSResult.getSubtreeID(SU))<< '\n'); return SU; } - virtual void schedNode(SUnit *, bool) {} + /// 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*/ } |