forked from OSchip/llvm-project
Allow CodeGen (llc) command line options to work as expected.
The llc command line options for enabling/disabling passes are local to CodeGen/Passes.cpp. This patch associates those options with standard pass IDs so they work regardless of how the target configures the passes. A target has two ways of overriding standard passes: 1) Redefine the pass pipeline (override TargetPassConfig::add%Stage) 2) Replace or suppress individiual passes with TargetPassConfig::substitutePass. In both cases, the command line options associated with the pass override the target default. For example, say a target wants to disable machine instruction scheduling by default: - The target calls disablePass(MachineSchedulerID) but otherwise does not override any TargetPassConfig methods. - Without any llc options, no scheduler is run. - With -enable-misched, the standard machine scheduler is run and honors the -misched=... flag to select the scheduler variant, which may be used for performance evaluation or testing. Sorry overridePass is ugly. I haven't thought of a better way without replacing the cl::opt framework. I hope to do that one day... I haven't figured out why CodeGen uses char& for pass IDs. AnalysisID is much easier to use and less bug prone. I'm using it wherever I can for internal implementation. Maybe later we can change the global pass ID definitions as well. llvm-svn: 150563
This commit is contained in:
parent
c9ce9d2315
commit
e9a951c00b
|
@ -40,6 +40,20 @@ class PassConfigImpl;
|
|||
/// This is an ImmutablePass solely for the purpose of exposing CodeGen options
|
||||
/// to the internals of other CodeGen passes.
|
||||
class TargetPassConfig : public ImmutablePass {
|
||||
public:
|
||||
/// Pseudo Pass IDs. These are defined within TargetPassConfig because they
|
||||
/// are unregistered pass IDs. They are only useful for use with
|
||||
/// TargetPassConfig APIs to identify multiple occurrences of the same pass.
|
||||
///
|
||||
|
||||
/// EarlyTailDuplicate - A clone of the TailDuplicate pass that runs early
|
||||
/// during codegen, on SSA form.
|
||||
static char EarlyTailDuplicateID;
|
||||
|
||||
/// PostRAMachineLICM - A clone of the LICM pass that runs during late machine
|
||||
/// optimization after regalloc.
|
||||
static char PostRAMachineLICMID;
|
||||
|
||||
protected:
|
||||
TargetMachine *TM;
|
||||
PassManagerBase ±
|
||||
|
|
|
@ -80,30 +80,95 @@ 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) {
|
||||
/// Allow standard passes to be disabled by command line options. This supports
|
||||
/// simple binary flags that either suppress the pass or do nothing.
|
||||
/// i.e. -disable-mypass=false has no effect.
|
||||
/// These should be converted to boolOrDefault in order to use applyOverride.
|
||||
static AnalysisID applyDisable(AnalysisID ID, bool Override) {
|
||||
if (Override)
|
||||
return &NoPassID;
|
||||
return ID;
|
||||
}
|
||||
|
||||
/// Allow Pass selection to be overriden by command line options. This supports
|
||||
/// flags with ternary conditions. TargetID is passed through by default. The
|
||||
/// pass is suppressed when the option is false. When the option is true, the
|
||||
/// StandardID is selected if the target provides no default.
|
||||
static AnalysisID applyOverride(AnalysisID TargetID, cl::boolOrDefault Override,
|
||||
AnalysisID StandardID) {
|
||||
switch (Override) {
|
||||
case cl::BOU_UNSET:
|
||||
return DefaultID;
|
||||
return TargetID;
|
||||
case cl::BOU_TRUE:
|
||||
if (&DefaultID != &NoPassID)
|
||||
return DefaultID;
|
||||
if (OptionalIDPtr == &NoPassID)
|
||||
if (TargetID != &NoPassID)
|
||||
return TargetID;
|
||||
if (StandardID == &NoPassID)
|
||||
report_fatal_error("Target cannot enable pass");
|
||||
return *OptionalIDPtr;
|
||||
return StandardID;
|
||||
case cl::BOU_FALSE:
|
||||
return NoPassID;
|
||||
return &NoPassID;
|
||||
}
|
||||
llvm_unreachable("Invalid command line option state");
|
||||
}
|
||||
|
||||
/// Allow standard passes to be disabled by the command line, regardless of who
|
||||
/// is adding the pass.
|
||||
///
|
||||
/// StandardID is the pass identified in the standard pass pipeline and provided
|
||||
/// to addPass(). It may be a target-specific ID in the case that the target
|
||||
/// directly adds its own pass, but in that case we harmlessly fall through.
|
||||
///
|
||||
/// TargetID is the pass that the target has configured to override StandardID.
|
||||
///
|
||||
/// StandardID may be a pseudo ID. In that case TargetID is the name of the real
|
||||
/// pass to run. This allows multiple options to control a single pass depending
|
||||
/// on where in the pipeline that pass is added.
|
||||
static AnalysisID overridePass(AnalysisID StandardID, AnalysisID TargetID) {
|
||||
if (StandardID == &PostRASchedulerID)
|
||||
return applyDisable(TargetID, DisablePostRA);
|
||||
|
||||
if (StandardID == &BranchFolderPassID)
|
||||
return applyDisable(TargetID, DisableBranchFold);
|
||||
|
||||
if (StandardID == &TailDuplicateID)
|
||||
return applyDisable(TargetID, DisableTailDuplicate);
|
||||
|
||||
if (StandardID == &TargetPassConfig::EarlyTailDuplicateID)
|
||||
return applyDisable(TargetID, DisableEarlyTailDup);
|
||||
|
||||
if (StandardID == &MachineBlockPlacementID)
|
||||
return applyDisable(TargetID, DisableCodePlace);
|
||||
|
||||
if (StandardID == &CodePlacementOptID)
|
||||
return applyDisable(TargetID, DisableCodePlace);
|
||||
|
||||
if (StandardID == &StackSlotColoringID)
|
||||
return applyDisable(TargetID, DisableSSC);
|
||||
|
||||
if (StandardID == &DeadMachineInstructionElimID)
|
||||
return applyDisable(TargetID, DisableMachineDCE);
|
||||
|
||||
if (StandardID == &MachineLICMID)
|
||||
return applyDisable(TargetID, DisableMachineLICM);
|
||||
|
||||
if (StandardID == &MachineCSEID)
|
||||
return applyDisable(TargetID, DisableMachineCSE);
|
||||
|
||||
if (StandardID == &MachineSchedulerID)
|
||||
return applyOverride(TargetID, EnableMachineSched, StandardID);
|
||||
|
||||
if (StandardID == &TargetPassConfig::PostRAMachineLICMID)
|
||||
return applyDisable(TargetID, DisablePostRAMachineLICM);
|
||||
|
||||
if (StandardID == &MachineSinkingID)
|
||||
return applyDisable(TargetID, DisableMachineSink);
|
||||
|
||||
if (StandardID == &MachineCopyPropagationID)
|
||||
return applyDisable(TargetID, DisableCopyProp);
|
||||
|
||||
return TargetID;
|
||||
}
|
||||
|
||||
//===---------------------------------------------------------------------===//
|
||||
/// TargetPassConfig
|
||||
//===---------------------------------------------------------------------===//
|
||||
|
@ -115,6 +180,10 @@ char TargetPassConfig::ID = 0;
|
|||
static char NoPassIDAnchor = 0;
|
||||
char &llvm::NoPassID = NoPassIDAnchor;
|
||||
|
||||
// Pseudo Pass IDs.
|
||||
char TargetPassConfig::EarlyTailDuplicateID = 0;
|
||||
char TargetPassConfig::PostRAMachineLICMID = 0;
|
||||
|
||||
namespace llvm {
|
||||
class PassConfigImpl {
|
||||
public:
|
||||
|
@ -146,6 +215,13 @@ TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm)
|
|||
// Register all target independent codegen passes to activate their PassIDs,
|
||||
// including this pass itself.
|
||||
initializeCodeGen(*PassRegistry::getPassRegistry());
|
||||
|
||||
// Substitute Pseudo Pass IDs for real ones.
|
||||
substitutePass(EarlyTailDuplicateID, TailDuplicateID);
|
||||
substitutePass(PostRAMachineLICMID, MachineLICMID);
|
||||
|
||||
// Temporarily disable experimental passes.
|
||||
substitutePass(MachineSchedulerID, NoPassID);
|
||||
}
|
||||
|
||||
/// createPassConfig - Create a pass configuration object to be used by
|
||||
|
@ -184,8 +260,8 @@ AnalysisID TargetPassConfig::getPassSubstitution(AnalysisID ID) const {
|
|||
AnalysisID TargetPassConfig::addPass(char &ID) {
|
||||
assert(!Initialized && "PassConfig is immutable");
|
||||
|
||||
AnalysisID FinalID = getPassSubstitution(&ID);
|
||||
// FIXME: check user overrides
|
||||
AnalysisID TargetID = getPassSubstitution(&ID);
|
||||
AnalysisID FinalID = overridePass(&ID, TargetID);
|
||||
if (FinalID == &NoPassID)
|
||||
return FinalID;
|
||||
|
||||
|
@ -325,7 +401,7 @@ void TargetPassConfig::addMachinePasses() {
|
|||
printNoVerify("After PreSched2 passes");
|
||||
|
||||
// Second pass scheduler.
|
||||
if (getOptLevel() != CodeGenOpt::None && !DisablePostRA) {
|
||||
if (getOptLevel() != CodeGenOpt::None) {
|
||||
addPass(PostRASchedulerID);
|
||||
printNoVerify("After PostRAScheduler");
|
||||
}
|
||||
|
@ -336,7 +412,7 @@ void TargetPassConfig::addMachinePasses() {
|
|||
PM.add(createGCInfoPrinter(dbgs()));
|
||||
|
||||
// Basic block placement.
|
||||
if (getOptLevel() != CodeGenOpt::None && !DisableCodePlace)
|
||||
if (getOptLevel() != CodeGenOpt::None)
|
||||
addBlockPlacement();
|
||||
|
||||
if (addPreEmitPass())
|
||||
|
@ -346,10 +422,8 @@ void TargetPassConfig::addMachinePasses() {
|
|||
/// Add passes that optimize machine instructions in SSA form.
|
||||
void TargetPassConfig::addMachineSSAOptimization() {
|
||||
// Pre-ra tail duplication.
|
||||
if (!DisableEarlyTailDup) {
|
||||
addPass(TailDuplicateID);
|
||||
if (addPass(EarlyTailDuplicateID) != &NoPassID)
|
||||
printAndVerify("After Pre-RegAlloc TailDuplicate");
|
||||
}
|
||||
|
||||
// Optimize PHIs before DCE: removing dead PHI cycles may make more
|
||||
// instructions dead.
|
||||
|
@ -363,16 +437,12 @@ void TargetPassConfig::addMachineSSAOptimization() {
|
|||
// there is one known exception: lowered code for arguments that are only
|
||||
// used by tail calls, where the tail calls reuse the incoming stack
|
||||
// arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).
|
||||
if (!DisableMachineDCE)
|
||||
addPass(DeadMachineInstructionElimID);
|
||||
addPass(DeadMachineInstructionElimID);
|
||||
printAndVerify("After codegen DCE pass");
|
||||
|
||||
if (!DisableMachineLICM)
|
||||
addPass(MachineLICMID);
|
||||
if (!DisableMachineCSE)
|
||||
addPass(MachineCSEID);
|
||||
if (!DisableMachineSink)
|
||||
addPass(MachineSinkingID);
|
||||
addPass(MachineLICMID);
|
||||
addPass(MachineCSEID);
|
||||
addPass(MachineSinkingID);
|
||||
printAndVerify("After Machine LICM, CSE and Sinking passes");
|
||||
|
||||
addPass(PeepholeOptimizerID);
|
||||
|
@ -494,7 +564,7 @@ void TargetPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) {
|
|||
addPass(RegisterCoalescerID);
|
||||
|
||||
// PreRA instruction scheduling.
|
||||
addPass(enablePass(getSchedPass(), EnableMachineSched, &MachineSchedulerID));
|
||||
addPass(MachineSchedulerID);
|
||||
|
||||
// Add the selected register allocation pass.
|
||||
PM.add(RegAllocPass);
|
||||
|
@ -512,14 +582,12 @@ void TargetPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) {
|
|||
//
|
||||
// FIXME: Re-enable coloring with register when it's capable of adding
|
||||
// kill markers.
|
||||
if (!DisableSSC)
|
||||
addPass(StackSlotColoringID);
|
||||
addPass(StackSlotColoringID);
|
||||
|
||||
// Run post-ra machine LICM to hoist reloads / remats.
|
||||
//
|
||||
// FIXME: can this move into MachineLateOptimization?
|
||||
if (!DisablePostRAMachineLICM)
|
||||
addPass(MachineLICMID);
|
||||
addPass(PostRAMachineLICMID);
|
||||
|
||||
printAndVerify("After StackSlotColoring and postra Machine LICM");
|
||||
}
|
||||
|
@ -531,40 +599,34 @@ void TargetPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) {
|
|||
/// Add passes that optimize machine instructions after register allocation.
|
||||
void TargetPassConfig::addMachineLateOptimization() {
|
||||
// Branch folding must be run after regalloc and prolog/epilog insertion.
|
||||
if (!DisableBranchFold) {
|
||||
addPass(BranchFolderPassID);
|
||||
if (addPass(BranchFolderPassID) != &NoPassID)
|
||||
printNoVerify("After BranchFolding");
|
||||
}
|
||||
|
||||
// Tail duplication.
|
||||
if (!DisableTailDuplicate) {
|
||||
addPass(TailDuplicateID);
|
||||
if (addPass(TailDuplicateID) != &NoPassID)
|
||||
printNoVerify("After TailDuplicate");
|
||||
}
|
||||
|
||||
// Copy propagation.
|
||||
if (!DisableCopyProp) {
|
||||
addPass(MachineCopyPropagationID);
|
||||
if (addPass(MachineCopyPropagationID) != &NoPassID)
|
||||
printNoVerify("After copy propagation pass");
|
||||
}
|
||||
}
|
||||
|
||||
/// Add standard basic block placement passes.
|
||||
void TargetPassConfig::addBlockPlacement() {
|
||||
AnalysisID ID = &NoPassID;
|
||||
if (EnableBlockPlacement) {
|
||||
// MachineBlockPlacement is an experimental pass which is disabled by
|
||||
// default currently. Eventually it should subsume CodePlacementOpt, so
|
||||
// when enabled, the other is disabled.
|
||||
addPass(MachineBlockPlacementID);
|
||||
printNoVerify("After MachineBlockPlacement");
|
||||
ID = addPass(MachineBlockPlacementID);
|
||||
} else {
|
||||
addPass(CodePlacementOptID);
|
||||
printNoVerify("After CodePlacementOpt");
|
||||
ID = addPass(CodePlacementOptID);
|
||||
}
|
||||
if (ID != &NoPassID) {
|
||||
// Run a separate pass to collect block placement statistics.
|
||||
if (EnableBlockPlacementStats)
|
||||
addPass(MachineBlockPlacementStatsID);
|
||||
|
||||
// Run a separate pass to collect block placement statistics.
|
||||
if (EnableBlockPlacementStats) {
|
||||
addPass(MachineBlockPlacementStatsID);
|
||||
printNoVerify("After MachineBlockPlacementStats");
|
||||
printNoVerify("After machine block placement.");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue