From 3a4ed52447a304516beb8f8d9474f79d930016e7 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Wed, 15 Feb 2012 03:21:47 +0000 Subject: [PATCH] Added TargetPassConfig::disablePass/substitutePass as a general mechanism to override specific passes. llvm-svn: 150562 --- include/llvm/CodeGen/Passes.h | 23 ++++++++++++-- include/llvm/Pass.h | 2 +- lib/CodeGen/Passes.cpp | 48 +++++++++++++++++++++++++---- lib/Target/PTX/PTXTargetMachine.cpp | 8 ++--- lib/VMCore/Pass.cpp | 4 +-- 5 files changed, 69 insertions(+), 16 deletions(-) diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index e9778f66f6b..2e4fb990812 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -33,6 +33,8 @@ namespace llvm { extern char &NoPassID; // Allow targets to choose not to run a pass. +class PassConfigImpl; + /// Target-Independent Code Generator Pass Configuration Options. /// /// This is an ImmutablePass solely for the purpose of exposing CodeGen options @@ -41,7 +43,8 @@ class TargetPassConfig : public ImmutablePass { protected: TargetMachine *TM; PassManagerBase ± - bool Initialized; // Flagged after all passes are configured. + PassConfigImpl *Impl; // Internal data structures + bool Initialized; // Flagged after all passes are configured. // Target Pass Options // Targets provide a default setting, user flags override. @@ -69,6 +72,7 @@ public: return TM->getTargetLowering(); } + // void setInitialized() { Initialized = true; } CodeGenOpt::Level getOptLevel() const { return TM->getOptLevel(); } @@ -78,6 +82,18 @@ public: bool getEnableTailMerge() const { return EnableTailMerge; } void setEnableTailMerge(bool Enable) { setOpt(EnableTailMerge, Enable); } + /// Allow the target to override a specific pass without overriding the pass + /// pipeline. When passes are added to the standard pipeline at the + /// point where StadardID is expected, add TargetID in its place. + void substitutePass(char &StandardID, char &TargetID); + + /// Allow the target to disable a specific standard pass. + void disablePass(char &ID) { substitutePass(ID, NoPassID); } + + /// Return the pass ssubtituted for StandardID by the target. + /// If no substitution exists, return StandardID. + AnalysisID getPassSubstitution(AnalysisID StandardID) const; + /// Return true if the optimized regalloc pipeline is enabled. bool getOptimizeRegAlloc() const; @@ -187,8 +203,9 @@ protected: /// Utilities for targets to add passes to the pass manager. /// - /// Add a target-independent CodeGen pass at this point in the pipeline. - void addPass(char &ID); + /// Add a CodeGen pass at this point in the pipeline after checking overrides. + /// Return the pass that was added, or NoPassID. + AnalysisID addPass(char &ID); /// addMachinePasses helper to create the target-selected or overriden /// regalloc pass. diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index a0cbca121d5..888537daa42 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -177,7 +177,7 @@ public: // createPass - Create a object for the specified pass class, // or null if it is not known. - static Pass *createPass(char &TI); + static Pass *createPass(AnalysisID ID); /// getAnalysisIfAvailable() - Subclasses use this function to /// get analysis information that might be around, for example to update it. diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp index 285d5df6346..427e4ac327f 100644 --- a/lib/CodeGen/Passes.cpp +++ b/lib/CodeGen/Passes.cpp @@ -115,16 +115,34 @@ char TargetPassConfig::ID = 0; static char NoPassIDAnchor = 0; char &llvm::NoPassID = NoPassIDAnchor; +namespace llvm { +class PassConfigImpl { +public: + // List of passes explicitly substituted by this target. Normally this is + // empty, but it is a convenient way to suppress or replace specific passes + // that are part of a standard pass pipeline without overridding the entire + // pipeline. This mechanism allows target options to inherit a standard pass's + // user interface. For example, a target may disable a standard pass by + // default by substituting NoPass, and the user may still enable that standard + // pass with an explicit command line option. + DenseMap TargetPasses; +}; +} // namespace llvm + // Out of line virtual method. -TargetPassConfig::~TargetPassConfig() {} +TargetPassConfig::~TargetPassConfig() { + delete Impl; +} // Out of line constructor provides default values for pass options and // registers all common codegen passes. TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm) - : ImmutablePass(ID), TM(tm), PM(pm), Initialized(false), + : ImmutablePass(ID), TM(tm), PM(pm), Impl(0), Initialized(false), DisableVerify(false), EnableTailMerge(true) { + Impl = new PassConfigImpl(); + // Register all target independent codegen passes to activate their PassIDs, // including this pass itself. initializeCodeGen(*PassRegistry::getPassRegistry()); @@ -149,15 +167,33 @@ void TargetPassConfig::setOpt(bool &Opt, bool Val) { Opt = Val; } -void TargetPassConfig::addPass(char &ID) { - if (&ID == &NoPassID) - return; +void TargetPassConfig::substitutePass(char &StandardID, char &TargetID) { + Impl->TargetPasses[&StandardID] = &TargetID; +} +AnalysisID TargetPassConfig::getPassSubstitution(AnalysisID ID) const { + DenseMap::const_iterator + I = Impl->TargetPasses.find(ID); + if (I == Impl->TargetPasses.end()) + return ID; + return I->second; +} + +/// Add a CodeGen pass at this point in the pipeline after checking for target +/// and command line overrides. +AnalysisID TargetPassConfig::addPass(char &ID) { + assert(!Initialized && "PassConfig is immutable"); + + AnalysisID FinalID = getPassSubstitution(&ID); // FIXME: check user overrides - Pass *P = Pass::createPass(ID); + if (FinalID == &NoPassID) + return FinalID; + + Pass *P = Pass::createPass(FinalID); if (!P) llvm_unreachable("Pass ID not registered"); PM.add(P); + return FinalID; } void TargetPassConfig::printNoVerify(const char *Banner) const { diff --git a/lib/Target/PTX/PTXTargetMachine.cpp b/lib/Target/PTX/PTXTargetMachine.cpp index 056bc07efa3..61285b15452 100644 --- a/lib/Target/PTX/PTXTargetMachine.cpp +++ b/lib/Target/PTX/PTXTargetMachine.cpp @@ -151,11 +151,11 @@ bool PTXPassConfig::addPostRegAlloc() { /// Add passes that optimize machine instructions after register allocation. void PTXPassConfig::addMachineLateOptimization() { - addPass(BranchFolderPassID); - printNoVerify("After BranchFolding"); + if (addPass(BranchFolderPassID) != &NoPassID) + printNoVerify("After BranchFolding"); - addPass(TailDuplicateID); - printNoVerify("After TailDuplicate"); + if (addPass(TailDuplicateID) != &NoPassID) + printNoVerify("After TailDuplicate"); } bool PTXPassConfig::addPreEmitPass() { diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp index 07ac3c35c1a..994a7ffceea 100644 --- a/lib/VMCore/Pass.cpp +++ b/lib/VMCore/Pass.cpp @@ -189,8 +189,8 @@ const PassInfo *Pass::lookupPassInfo(StringRef Arg) { return PassRegistry::getPassRegistry()->getPassInfo(Arg); } -Pass *Pass::createPass(char &TI) { - const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(&TI); +Pass *Pass::createPass(AnalysisID ID) { + const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(ID); if (!PI) return NULL; return PI->createPass();