aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2012-02-15 03:21:51 +0000
committerAndrew Trick <atrick@apple.com>2012-02-15 03:21:51 +0000
commit79bf288584215f3f3c49050ac1691a6b29c56fec (patch)
treedd59d6ffd51e93d13a44d60635a4b53d9c8273fa
parent5e108eeeef34dd2afa00d1da77bca47188de4244 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150563 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/Passes.h14
-rw-r--r--lib/CodeGen/Passes.cpp166
2 files changed, 128 insertions, 52 deletions
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 2e4fb99081..87835a5865 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -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 &PM;
diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp
index 427e4ac327..ec1f2b4c3b 100644
--- a/lib/CodeGen/Passes.cpp
+++ b/lib/CodeGen/Passes.cpp
@@ -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.");
}
}