diff options
| author | Juergen Ributzka <juergen@apple.com> | 2014-04-28 18:19:25 +0000 |
|---|---|---|
| committer | Juergen Ributzka <juergen@apple.com> | 2014-04-28 18:19:25 +0000 |
| commit | 4989255432a7954ce8c3937a3561595891edf83d (patch) | |
| tree | 3708381fd96f0ffcca677eb497a7bb1745af51a8 /llvm/lib | |
| parent | 4482dcd0721794fc7560b6b5022e47a69df901c2 (diff) | |
| download | bcm5719-llvm-4989255432a7954ce8c3937a3561595891edf83d.tar.gz bcm5719-llvm-4989255432a7954ce8c3937a3561595891edf83d.zip | |
[PM] Add pass run listeners to the pass manager.
This commit provides the necessary C/C++ APIs and infastructure to enable fine-
grain progress report and safe suspension points after each pass in the pass
manager.
Clients can provide a callback function to the pass manager to call after each
pass. This can be used in a variety of ways (progress report, dumping of IR
between passes, safe suspension of threads, etc).
The run listener list is maintained in the LLVMContext, which allows a multi-
threaded client to be only informed for it's own thread. This of course assumes
that the client created a LLVMContext for each thread.
This fixes <rdar://problem/16728690>
llvm-svn: 207430
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/IR/Core.cpp | 30 | ||||
| -rw-r--r-- | llvm/lib/IR/LLVMContext.cpp | 20 | ||||
| -rw-r--r-- | llvm/lib/IR/LLVMContextImpl.cpp | 26 | ||||
| -rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 16 | ||||
| -rw-r--r-- | llvm/lib/IR/LegacyPassManager.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/IR/Pass.cpp | 13 |
6 files changed, 111 insertions, 1 deletions
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index be5727b3cb3..a843b9f6029 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -27,6 +27,7 @@ #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" +#include "llvm/Pass.h" #include "llvm/PassManager.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -43,6 +44,21 @@ using namespace llvm; #define DEBUG_TYPE "ir" +namespace { +struct LLVMPassRunListener : PassRunListener { + LLVMPassRunListenerHandlerTy Callback; + + LLVMPassRunListener(LLVMContext *Context, LLVMPassRunListenerHandlerTy Fn) + : PassRunListener(Context), Callback(Fn) {} + void passRun(LLVMContext *C, Pass *P, Module *M, Function *F, + BasicBlock *BB) override { + Callback(wrap(C), wrap(P), wrap(M), wrap(F), wrap(BB)); + } +}; +// Create wrappers for C Binding types (see CBindingWrapping.h). +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMPassRunListener, LLVMPassRunListenerRef) +} // end anonymous namespace + void llvm::initializeCore(PassRegistry &Registry) { initializeDominatorTreeWrapperPassPass(Registry); initializePrintModulePassWrapperPass(Registry); @@ -133,7 +149,15 @@ LLVMDiagnosticSeverity LLVMGetDiagInfoSeverity(LLVMDiagnosticInfoRef DI){ return severity; } +LLVMPassRunListenerRef LLVMAddPassRunListener(LLVMContextRef Context, + LLVMPassRunListenerHandlerTy Fn) { + return wrap(new LLVMPassRunListener(unwrap(Context), Fn)); +} +void LLVMRemovePassRunListener(LLVMContextRef Context, + LLVMPassRunListenerRef Listener) { + unwrap(Context)->removeRunListener(unwrap(Listener)); +} /*===-- Operations on modules ---------------------------------------------===*/ @@ -2646,6 +2670,12 @@ void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf) { delete unwrap(MemBuf); } +/*===-- Pass -------------------------------------------------------------===*/ + +const char *LLVMGetPassName(LLVMPassRef P) { + return unwrap(P)->getPassName(); +} + /*===-- Pass Registry -----------------------------------------------------===*/ LLVMPassRegistryRef LLVMGetGlobalPassRegistry(void) { diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp index 588e1217bd4..b2d3bc9061e 100644 --- a/llvm/lib/IR/LLVMContext.cpp +++ b/llvm/lib/IR/LLVMContext.cpp @@ -214,3 +214,23 @@ void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const { E = pImpl->CustomMDKindNames.end(); I != E; ++I) Names[I->second] = I->first(); } + +//===----------------------------------------------------------------------===// +// Pass Run Listeners +//===----------------------------------------------------------------------===// +/// Notify that we finished running a pass. +void LLVMContext::notifyPassRun(Pass *P, Module *M, Function *F, BasicBlock *BB) +{ + pImpl->notifyPassRun(this, P, M, F, BB); +} +/// Register the given PassRunListener to receive notifyPassRun() callbacks +/// whenever a pass ran. The context will take ownership of the listener and +/// free it when the context is destroyed. +void LLVMContext::addRunListener(PassRunListener *L) { + pImpl->addRunListener(L); +} +/// Unregister a PassRunListener so that it no longer receives notifyPassRun() +/// callbacks. Remove and free the listener from the context. +void LLVMContext::removeRunListener(PassRunListener *L) { + pImpl->removeRunListener(L); +} diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp index 30a1ca28c57..50740a0c348 100644 --- a/llvm/lib/IR/LLVMContextImpl.cpp +++ b/llvm/lib/IR/LLVMContextImpl.cpp @@ -15,11 +15,32 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/Module.h" +#include "llvm/PassSupport.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Regex.h" #include <algorithm> using namespace llvm; +/// Notify that we finished running a pass. +void LLVMContextImpl::notifyPassRun(LLVMContext *C, Pass *P, Module *M, + Function *F, BasicBlock *BB) { + for (auto const &L : RunListeners) + L->passRun(C, P, M, F, BB); +} +/// Register the given PassRunListener to receive notifyPassRun() +/// callbacks whenever a pass ran. +void LLVMContextImpl::addRunListener(PassRunListener *L) { + RunListeners.push_back(L); +} +/// Unregister a PassRunListener so that it no longer receives +/// notifyPassRun() callbacks. +void LLVMContextImpl::removeRunListener(PassRunListener *L) { + auto I = std::find(RunListeners.begin(), RunListeners.end(), L); + assert(I != RunListeners.end() && "RunListener not registered!"); + delete *I; + RunListeners.erase(I); +} + LLVMContextImpl::LLVMContextImpl(LLVMContext &C) : TheTrueVal(nullptr), TheFalseVal(nullptr), VoidTy(C, Type::VoidTyID), @@ -188,6 +209,11 @@ LLVMContextImpl::~LLVMContextImpl() { // Destroy MDStrings. DeleteContainerSeconds(MDStringCache); + + // Destroy all run listeners. + for (auto &L : RunListeners) + delete L; + RunListeners.clear(); } // ConstantsContext anchors diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index a6a65e6cacd..5e4919cdf0b 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -40,6 +40,7 @@ class ConstantFP; class LLVMContext; class Type; class Value; +struct PassRunListener; struct DenseMapAPIntKeyInfo { struct KeyTy { @@ -368,13 +369,26 @@ public: typedef DenseMap<const Function *, ReturnInst *> PrefixDataMapTy; PrefixDataMapTy PrefixDataMap; + /// \brief List of listeners to notify about a pass run. + SmallVector<PassRunListener *, 4> RunListeners; + /// \brief Return true if the given pass name should emit optimization /// remarks. bool optimizationRemarksEnabledFor(const char *PassName) const; int getOrAddScopeRecordIdxEntry(MDNode *N, int ExistingIdx); int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx); - + + /// \brief Notify that we finished running a pass. + void notifyPassRun(LLVMContext *, Pass *, Module *, Function *, BasicBlock *); + /// \brief Register the given PassRunListener to receive notifyPassRun() + /// callbacks whenever a pass ran. The context will take ownership of the + /// listener and free it when the context is destroyed. + void addRunListener(PassRunListener *); + /// \brief Unregister a PassRunListener so that it no longer receives + /// notifyPassRun() callbacks. Remove and free the listener from the context. + void removeRunListener(PassRunListener *); + LLVMContextImpl(LLVMContext &C); ~LLVMContextImpl(); }; diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp index b6d75b483f8..aea29fdc5b0 100644 --- a/llvm/lib/IR/LegacyPassManager.cpp +++ b/llvm/lib/IR/LegacyPassManager.cpp @@ -16,6 +16,7 @@ #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/LegacyPassManagers.h" #include "llvm/IR/LegacyPassNameParser.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -1313,6 +1314,8 @@ bool BBPassManager::runOnFunction(Function &F) { TimeRegion PassTimer(getPassTimer(BP)); LocalChanged |= BP->runOnBasicBlock(*I); + + F.getContext().notifyPassRun(BP, F.getParent(), &F, &*I); } Changed |= LocalChanged; @@ -1551,6 +1554,8 @@ bool FPPassManager::runOnFunction(Function &F) { removeNotPreservedAnalysis(FP); recordAvailableAnalysis(FP); removeDeadPasses(FP, F.getName(), ON_FUNCTION_MSG); + + F.getContext().notifyPassRun(FP, F.getParent(), &F); } return Changed; } @@ -1630,6 +1635,8 @@ MPPassManager::runOnModule(Module &M) { removeNotPreservedAnalysis(MP); recordAvailableAnalysis(MP); removeDeadPasses(MP, M.getModuleIdentifier(), ON_MODULE_MSG); + + M.getContext().notifyPassRun(MP, &M); } // Finalize module passes diff --git a/llvm/lib/IR/Pass.cpp b/llvm/lib/IR/Pass.cpp index bb55d2af7cf..58ae821db22 100644 --- a/llvm/lib/IR/Pass.cpp +++ b/llvm/lib/IR/Pass.cpp @@ -17,6 +17,7 @@ #include "llvm/IR/Function.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/LegacyPassNameParser.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/PassRegistry.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -242,6 +243,18 @@ void PassRegistrationListener::enumeratePasses() { PassRegistry::getPassRegistry()->enumerateWith(this); } +//===----------------------------------------------------------------------===// +// PassRunListener implementation +// + +// PassRunListener ctor - Add the current object to the list of +// PassRunListeners... +PassRunListener::PassRunListener(LLVMContext *C) { + C->addRunListener(this); +} + +PassRunListener::~PassRunListener() {} + PassNameParser::~PassNameParser() {} //===----------------------------------------------------------------------===// |

