[llvm-commits] [llvm] r152278 - in /llvm/trunk: include/llvm/CodeGen/MachineScheduler.h lib/CodeGen/MachineScheduler.cpp
Andrew Trick
atrick at apple.com
Wed Mar 7 17:41:12 PST 2012
Author: atrick
Date: Wed Mar 7 19:41:12 2012
New Revision: 152278
URL: http://llvm.org/viewvc/llvm-project?rev=152278&view=rev
Log:
misched interface: Expose the MachineScheduler pass.
Allow targets to provide their own schedulers (subclass of
ScheduleDAGInstrs) to the misched pass. Select schedulers using
-misched=...
Added:
llvm/trunk/include/llvm/CodeGen/MachineScheduler.h
Modified:
llvm/trunk/lib/CodeGen/MachineScheduler.cpp
Added: llvm/trunk/include/llvm/CodeGen/MachineScheduler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineScheduler.h?rev=152278&view=auto
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineScheduler.h (added)
+++ llvm/trunk/include/llvm/CodeGen/MachineScheduler.h Wed Mar 7 19:41:12 2012
@@ -0,0 +1,86 @@
+//==- MachineScheduler.h - MachineInstr Scheduling Pass ----------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a MachineSchedRegistry for registering alternative machine
+// schedulers. A Target may provide an alternative scheduler implementation by
+// implementing the following boilerplate:
+//
+// static ScheduleDAGInstrs *createCustomMachineSched(MachineSchedContext *C) {
+// return new CustomMachineScheduler(C);
+// }
+// static MachineSchedRegistry
+// SchedDefaultRegistry("custom", "Run my target's custom scheduler",
+// createCustomMachineSched);
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MACHINESCHEDULER_H
+#define MACHINESCHEDULER_H
+
+#include "llvm/CodeGen/MachinePassRegistry.h"
+
+namespace llvm {
+
+class AliasAnalysis;
+class LiveIntervals;
+class MachineDominatorTree;
+class MachineLoopInfo;
+class ScheduleDAGInstrs;
+
+/// MachineSchedContext provides enough context from the MachineScheduler pass
+/// for the target to instantiate a scheduler.
+struct MachineSchedContext {
+ MachineFunction *MF;
+ const MachineLoopInfo *MLI;
+ const MachineDominatorTree *MDT;
+ AliasAnalysis *AA;
+ LiveIntervals *LIS;
+
+ MachineSchedContext(): MF(0), MLI(0), MDT(0), AA(0), LIS(0) {}
+};
+
+/// MachineSchedRegistry provides a selection of available machine instruction
+/// schedulers.
+class MachineSchedRegistry : public MachinePassRegistryNode {
+public:
+ typedef ScheduleDAGInstrs *(*ScheduleDAGCtor)(MachineSchedContext *);
+
+ // RegisterPassParser requires a (misnamed) FunctionPassCtor type.
+ typedef ScheduleDAGCtor FunctionPassCtor;
+
+ static MachinePassRegistry Registry;
+
+ MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C)
+ : MachinePassRegistryNode(N, D, (MachinePassCtor)C) {
+ Registry.Add(this);
+ }
+ ~MachineSchedRegistry() { Registry.Remove(this); }
+
+ // Accessors.
+ //
+ MachineSchedRegistry *getNext() const {
+ return (MachineSchedRegistry *)MachinePassRegistryNode::getNext();
+ }
+ static MachineSchedRegistry *getList() {
+ return (MachineSchedRegistry *)Registry.getList();
+ }
+ static ScheduleDAGCtor getDefault() {
+ return (ScheduleDAGCtor)Registry.getDefault();
+ }
+ static void setDefault(ScheduleDAGCtor C) {
+ Registry.setDefault((MachinePassCtor)C);
+ }
+ static void setListener(MachinePassRegistryListener *L) {
+ Registry.setListener(L);
+ }
+};
+
+} // namespace llvm
+
+#endif
Modified: llvm/trunk/lib/CodeGen/MachineScheduler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineScheduler.cpp?rev=152278&r1=152277&r2=152278&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineScheduler.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineScheduler.cpp Wed Mar 7 19:41:12 2012
@@ -15,7 +15,7 @@
#define DEBUG_TYPE "misched"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
-#include "llvm/CodeGen/MachinePassRegistry.h"
+#include "llvm/CodeGen/MachineScheduler.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
#include "llvm/Analysis/AliasAnalysis.h"
@@ -43,14 +43,9 @@
namespace {
/// MachineScheduler runs after coalescing and before register allocation.
-class MachineScheduler : public MachineFunctionPass {
+class MachineScheduler : public MachineSchedContext,
+ public MachineFunctionPass {
public:
- MachineFunction *MF;
- const TargetInstrInfo *TII;
- const MachineLoopInfo *MLI;
- const MachineDominatorTree *MDT;
- LiveIntervals *LIS;
-
MachineScheduler();
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
@@ -78,7 +73,7 @@
"Machine Instruction Scheduler", false, false)
MachineScheduler::MachineScheduler()
-: MachineFunctionPass(ID), MF(0), MLI(0), MDT(0) {
+: MachineFunctionPass(ID) {
initializeMachineSchedulerPass(*PassRegistry::getPassRegistry());
}
@@ -95,47 +90,9 @@
MachineFunctionPass::getAnalysisUsage(AU);
}
-namespace {
-/// MachineSchedRegistry provides a selection of available machine instruction
-/// schedulers.
-class MachineSchedRegistry : public MachinePassRegistryNode {
-public:
- typedef ScheduleDAGInstrs *(*ScheduleDAGCtor)(MachineScheduler *);
-
- // RegisterPassParser requires a (misnamed) FunctionPassCtor type.
- typedef ScheduleDAGCtor FunctionPassCtor;
-
- static MachinePassRegistry Registry;
-
- MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C)
- : MachinePassRegistryNode(N, D, (MachinePassCtor)C) {
- Registry.Add(this);
- }
- ~MachineSchedRegistry() { Registry.Remove(this); }
-
- // Accessors.
- //
- MachineSchedRegistry *getNext() const {
- return (MachineSchedRegistry *)MachinePassRegistryNode::getNext();
- }
- static MachineSchedRegistry *getList() {
- return (MachineSchedRegistry *)Registry.getList();
- }
- static ScheduleDAGCtor getDefault() {
- return (ScheduleDAGCtor)Registry.getDefault();
- }
- static void setDefault(ScheduleDAGCtor C) {
- Registry.setDefault((MachinePassCtor)C);
- }
- static void setListener(MachinePassRegistryListener *L) {
- Registry.setListener(L);
- }
-};
-} // namespace
-
MachinePassRegistry MachineSchedRegistry::Registry;
-static ScheduleDAGInstrs *createDefaultMachineSched(MachineScheduler *P);
+static ScheduleDAGInstrs *createDefaultMachineSched(MachineSchedContext *C);
/// MachineSchedOpt allows command line selection of the scheduler.
static cl::opt<MachineSchedRegistry::ScheduleDAGCtor, false,
@@ -144,22 +101,97 @@
cl::init(&createDefaultMachineSched), cl::Hidden,
cl::desc("Machine instruction scheduler to use"));
+bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
+ // Initialize the context of the pass.
+ MF = &mf;
+ MLI = &getAnalysis<MachineLoopInfo>();
+ MDT = &getAnalysis<MachineDominatorTree>();
+ AA = &getAnalysis<AliasAnalysis>();
+
+ LIS = &getAnalysis<LiveIntervals>();
+ const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
+
+ // Select the scheduler, or set the default.
+ MachineSchedRegistry::ScheduleDAGCtor Ctor =
+ MachineSchedRegistry::getDefault();
+ if (!Ctor) {
+ Ctor = MachineSchedOpt;
+ MachineSchedRegistry::setDefault(Ctor);
+ }
+ // Instantiate the selected scheduler.
+ OwningPtr<ScheduleDAGInstrs> Scheduler(Ctor(this));
+
+ // Visit all machine basic blocks.
+ for (MachineFunction::iterator MBB = MF->begin(), MBBEnd = MF->end();
+ MBB != MBBEnd; ++MBB) {
+
+ // Break the block into scheduling regions [I, RegionEnd), and schedule each
+ // region as soon as it is discovered.
+ unsigned RemainingCount = MBB->size();
+ for(MachineBasicBlock::iterator RegionEnd = MBB->end();
+ RegionEnd != MBB->begin();) {
+ Scheduler->startBlock(MBB);
+ // The next region starts above the previous region. Look backward in the
+ // instruction stream until we find the nearest boundary.
+ MachineBasicBlock::iterator I = RegionEnd;
+ for(;I != MBB->begin(); --I, --RemainingCount) {
+ if (TII->isSchedulingBoundary(llvm::prior(I), MBB, *MF))
+ break;
+ }
+ // Notify the scheduler of the region, even if we may skip scheduling
+ // it. Perhaps it still needs to be bundled.
+ Scheduler->enterRegion(MBB, I, RegionEnd, RemainingCount);
+
+ // Skip empty scheduling regions (0 or 1 schedulable instructions).
+ if (I == RegionEnd || I == llvm::prior(RegionEnd)) {
+ RegionEnd = llvm::prior(RegionEnd);
+ if (I != RegionEnd)
+ --RemainingCount;
+ // Close the current region. Bundle the terminator if needed.
+ Scheduler->exitRegion();
+ continue;
+ }
+ DEBUG(dbgs() << "MachineScheduling " << MF->getFunction()->getName()
+ << ":BB#" << MBB->getNumber() << "\n From: " << *I << " To: ";
+ if (RegionEnd != MBB->end()) dbgs() << *RegionEnd;
+ else dbgs() << "End";
+ dbgs() << " Remaining: " << RemainingCount << "\n");
+
+ // Inform ScheduleDAGInstrs of the region being scheduled. It calls back
+ // to our schedule() method.
+ Scheduler->schedule();
+ Scheduler->exitRegion();
+
+ // Scheduling has invalidated the current iterator 'I'. Ask the
+ // scheduler for the top of it's scheduled region.
+ RegionEnd = Scheduler->begin();
+ }
+ assert(RemainingCount == 0 && "Instruction count mismatch!");
+ Scheduler->finishBlock();
+ }
+ return true;
+}
+
+void MachineScheduler::print(raw_ostream &O, const Module* m) const {
+ // unimplemented
+}
+
//===----------------------------------------------------------------------===//
-// Machine Instruction Scheduling Common Implementation
-//===----------------------------------------------------------------------===//
+// ScheduleTopeDownLive - Base class for basic top-down scheduling with
+// LiveIntervals preservation.
+// ===----------------------------------------------------------------------===//
namespace {
/// ScheduleTopDownLive is an implementation of ScheduleDAGInstrs that schedules
/// machine instructions while updating LiveIntervals.
class ScheduleTopDownLive : public ScheduleDAGInstrs {
-protected:
- MachineScheduler *Pass;
+ AliasAnalysis *AA;
public:
- ScheduleTopDownLive(MachineScheduler *P):
- ScheduleDAGInstrs(*P->MF, *P->MLI, *P->MDT, /*IsPostRA=*/false, P->LIS),
- Pass(P) {}
+ ScheduleTopDownLive(MachineSchedContext *C):
+ ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
+ AA(C->AA) {}
- /// ScheduleDAGInstrs callback.
+ /// ScheduleDAGInstrs interface.
void schedule();
/// Interface implemented by the selected top-down liveinterval scheduler.
@@ -206,7 +238,7 @@
/// schedule - This is called back from ScheduleDAGInstrs::Run() when it's
/// time to do some work.
void ScheduleTopDownLive::schedule() {
- buildSchedGraph(&Pass->getAnalysis<AliasAnalysis>());
+ buildSchedGraph(AA);
DEBUG(dbgs() << "********** MI Scheduling **********\n");
DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
@@ -236,7 +268,7 @@
++InsertPos;
else {
BB->splice(InsertPos, BB, MI);
- Pass->LIS->handleMove(MI);
+ LIS->handleMove(MI);
if (Begin == InsertPos)
Begin = MI;
}
@@ -246,90 +278,17 @@
}
}
-bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
- // Initialize the context of the pass.
- MF = &mf;
- MLI = &getAnalysis<MachineLoopInfo>();
- MDT = &getAnalysis<MachineDominatorTree>();
- LIS = &getAnalysis<LiveIntervals>();
- TII = MF->getTarget().getInstrInfo();
-
- // Select the scheduler, or set the default.
- MachineSchedRegistry::ScheduleDAGCtor Ctor =
- MachineSchedRegistry::getDefault();
- if (!Ctor) {
- Ctor = MachineSchedOpt;
- MachineSchedRegistry::setDefault(Ctor);
- }
- // Instantiate the selected scheduler.
- OwningPtr<ScheduleDAGInstrs> Scheduler(Ctor(this));
-
- // Visit all machine basic blocks.
- for (MachineFunction::iterator MBB = MF->begin(), MBBEnd = MF->end();
- MBB != MBBEnd; ++MBB) {
-
- // Break the block into scheduling regions [I, RegionEnd), and schedule each
- // region as soon as it is discovered.
- unsigned RemainingCount = MBB->size();
- for(MachineBasicBlock::iterator RegionEnd = MBB->end();
- RegionEnd != MBB->begin();) {
- Scheduler->startBlock(MBB);
- // The next region starts above the previous region. Look backward in the
- // instruction stream until we find the nearest boundary.
- MachineBasicBlock::iterator I = RegionEnd;
- for(;I != MBB->begin(); --I, --RemainingCount) {
- if (TII->isSchedulingBoundary(llvm::prior(I), MBB, *MF))
- break;
- }
- // Notify the scheduler of the region, even if we may skip scheduling
- // it. Perhaps it still needs to be bundled.
- Scheduler->enterRegion(MBB, I, RegionEnd, RemainingCount);
-
- // Skip empty scheduling regions (0 or 1 schedulable instructions).
- if (I == RegionEnd || I == llvm::prior(RegionEnd)) {
- RegionEnd = llvm::prior(RegionEnd);
- if (I != RegionEnd)
- --RemainingCount;
- // Close the current region. Bundle the terminator if needed.
- Scheduler->exitRegion();
- continue;
- }
- DEBUG(dbgs() << "MachineScheduling " << MF->getFunction()->getName()
- << ":BB#" << MBB->getNumber() << "\n From: " << *I << " To: ";
- if (RegionEnd != MBB->end()) dbgs() << *RegionEnd;
- else dbgs() << "End";
- dbgs() << " Remaining: " << RemainingCount << "\n");
-
- // Inform ScheduleDAGInstrs of the region being scheduled. It calls back
- // to our schedule() method.
- Scheduler->schedule();
- Scheduler->exitRegion();
-
- // Scheduling has invalidated the current iterator 'I'. Ask the
- // scheduler for the top of it's scheduled region.
- RegionEnd = Scheduler->begin();
- }
- assert(RemainingCount == 0 && "Instruction count mismatch!");
- Scheduler->finishBlock();
- }
- return true;
-}
-
-void MachineScheduler::print(raw_ostream &O, const Module* m) const {
- // unimplemented
-}
-
//===----------------------------------------------------------------------===//
-// Placeholder for extending the machine instruction scheduler.
+// Placeholder for the default machine instruction scheduler.
//===----------------------------------------------------------------------===//
namespace {
class DefaultMachineScheduler : public ScheduleDAGInstrs {
- MachineScheduler *Pass;
+ AliasAnalysis *AA;
public:
- DefaultMachineScheduler(MachineScheduler *P):
- ScheduleDAGInstrs(*P->MF, *P->MLI, *P->MDT, /*IsPostRA=*/false, P->LIS),
- Pass(P) {}
+ DefaultMachineScheduler(MachineSchedContext *C):
+ ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
+ AA(C->AA) {}
/// schedule - This is called back from ScheduleDAGInstrs::Run() when it's
/// time to do some work.
@@ -337,19 +296,18 @@
};
} // namespace
-static ScheduleDAGInstrs *createDefaultMachineSched(MachineScheduler *P) {
- return new DefaultMachineScheduler(P);
+static ScheduleDAGInstrs *createDefaultMachineSched(MachineSchedContext *C) {
+ return new DefaultMachineScheduler(C);
}
static MachineSchedRegistry
SchedDefaultRegistry("default", "Activate the scheduler pass, "
"but don't reorder instructions",
createDefaultMachineSched);
-
/// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
/// time to do some work.
void DefaultMachineScheduler::schedule() {
- buildSchedGraph(&Pass->getAnalysis<AliasAnalysis>());
+ buildSchedGraph(AA);
DEBUG(dbgs() << "********** MI Scheduling **********\n");
DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
@@ -382,8 +340,8 @@
class InstructionShuffler : public ScheduleTopDownLive {
std::priority_queue<SUnit*, std::vector<SUnit*>, ShuffleSUnitOrder> Queue;
public:
- InstructionShuffler(MachineScheduler *P):
- ScheduleTopDownLive(P) {}
+ InstructionShuffler(MachineSchedContext *C):
+ ScheduleTopDownLive(C) {}
/// ScheduleTopDownLive Interface
@@ -400,8 +358,8 @@
};
} // namespace
-static ScheduleDAGInstrs *createInstructionShuffler(MachineScheduler *P) {
- return new InstructionShuffler(P);
+static ScheduleDAGInstrs *createInstructionShuffler(MachineSchedContext *C) {
+ return new InstructionShuffler(C);
}
static MachineSchedRegistry ShufflerRegistry("shuffle",
"Shuffle machine instructions",
More information about the llvm-commits
mailing list