Add TargetPassConfig hooks for scheduling/bundling.

In case the MachineScheduling pass I'm working on doesn't work well
for another target, they can completely override it. This also adds a
hook immediately after the RegAlloc pass to cleanup immediately after
vregs go away. We may want to fold it into the postRA hook later.

llvm-svn: 150298
This commit is contained in:
Andrew Trick 2012-02-11 07:11:32 +00:00
parent e199b4e82e
commit f8d8f89c1c
2 changed files with 63 additions and 7 deletions

View File

@ -31,6 +31,8 @@ namespace llvm {
namespace llvm {
extern char &NoPassID; // Allow targets to choose not to run a pass.
/// Target-Independent Code Generator Pass Configuration Options.
///
/// This is an ImmutablePass solely for the purpose of exposing CodeGen options
@ -136,10 +138,26 @@ protected:
/// LLVMTargetMachine provides standard regalloc passes for most targets.
virtual void addOptimizedRegAlloc(FunctionPass *RegAllocPass);
/// addPostRegAlloc - This method may be implemented by targets that want
/// to run passes after register allocation but before prolog-epilog
/// insertion. This should return true if -print-machineinstrs should print
/// after these passes.
/// getSchedPass - This method may be implemented by target that want to
/// completely override the MachineScheduler pass with a new pass, rather than
/// inheriting from ScheduleDAGInstrs.
virtual char &getSchedPass() { return NoPassID; }
/// addFinalizeRegAlloc - This method may be implemented by targets that want
/// to run passes within the regalloc pipeline, immediately after the register
/// allocation pass itself. These passes run as soon as virtual regisiters
/// have been rewritten to physical registers but before and other postRA
/// optimization happens. Targets that have marked instructions for bundling
/// must have finalized those bundles by the time these passes have run,
/// because subsequent passes are not guaranteed to be bundle-aware.
virtual bool addFinalizeRegAlloc() {
return false;
}
/// addPostRegAlloc - This method may be implemented by targets that want to
/// run passes after register allocation pass pipeline but before
/// prolog-epilog insertion. This should return true if -print-machineinstrs
/// should print after these passes.
virtual bool addPostRegAlloc() {
return false;
}

View File

@ -54,7 +54,8 @@ static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden,
static cl::opt<cl::boolOrDefault>
OptimizeRegAlloc("optimize-regalloc", cl::Hidden,
cl::desc("Enable optimized register allocation compilation path."));
static cl::opt<bool> EnableMachineSched("enable-misched", cl::Hidden,
static cl::opt<cl::boolOrDefault>
EnableMachineSched("enable-misched", cl::Hidden,
cl::desc("Enable the machine instruction scheduling pass."));
static cl::opt<bool> EnableStrongPHIElim("strong-phi-elim", cl::Hidden,
cl::desc("Use strong PHI elimination."));
@ -79,6 +80,30 @@ static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden,
cl::desc("Verify generated machine code"),
cl::init(getenv("LLVM_VERIFY_MACHINEINSTRS")!=NULL));
// Allow Pass selection to be overriden by command line options.
//
// DefaultID is the default pass to run which may be NoPassID, or may be
// overriden by the target.
//
// OptionalID is a pass that may be forcibly enabled by the user when the
// default is NoPassID.
char &enablePass(char &DefaultID, cl::boolOrDefault Override,
char *OptionalIDPtr = &NoPassID) {
switch (Override) {
case cl::BOU_UNSET:
return DefaultID;
case cl::BOU_TRUE:
if (&DefaultID != &NoPassID)
return DefaultID;
if (OptionalIDPtr == &NoPassID)
report_fatal_error("Target cannot enable pass");
return *OptionalIDPtr;
case cl::BOU_FALSE:
return NoPassID;
}
llvm_unreachable("Invalid command line option state");
}
//===---------------------------------------------------------------------===//
/// TargetPassConfig
//===---------------------------------------------------------------------===//
@ -87,6 +112,9 @@ INITIALIZE_PASS(TargetPassConfig, "targetpassconfig",
"Target Pass Configuration", false, false)
char TargetPassConfig::ID = 0;
static char NoPassIDAnchor = 0;
char &llvm::NoPassID = NoPassIDAnchor;
// Out of line virtual method.
TargetPassConfig::~TargetPassConfig() {}
@ -122,6 +150,9 @@ void TargetPassConfig::setOpt(bool &Opt, bool Val) {
}
void TargetPassConfig::addPass(char &ID) {
if (&ID == &NoPassID)
return;
// FIXME: check user overrides
Pass *P = Pass::createPass(ID);
if (!P)
@ -427,13 +458,20 @@ void TargetPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) {
addPass(RegisterCoalescerID);
// PreRA instruction scheduling.
if (EnableMachineSched)
addPass(MachineSchedulerID);
addPass(enablePass(getSchedPass(), EnableMachineSched, &MachineSchedulerID));
// Add the selected register allocation pass.
PM.add(RegAllocPass);
printAndVerify("After Register Allocation");
// FinalizeRegAlloc is convenient until MachineInstrBundles is more mature,
// but eventually, all users of it should probably be moved to addPostRA and
// it can go away. Currently, it's the intended place for targets to run
// FinalizeMachineBundles, because passes other than MachineScheduling an
// RegAlloc itself may not be aware of bundles.
if (addFinalizeRegAlloc())
printAndVerify("After RegAlloc finalization");
// Perform stack slot coloring and post-ra machine LICM.
//
// FIXME: Re-enable coloring with register when it's capable of adding