[llvm] r207430 - [PM] Add pass run listeners to the pass manager.
Juergen Ributzka
juergen at apple.com
Mon Apr 28 11:19:26 PDT 2014
Author: ributzka
Date: Mon Apr 28 13:19:25 2014
New Revision: 207430
URL: http://llvm.org/viewvc/llvm-project?rev=207430&view=rev
Log:
[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>
Modified:
llvm/trunk/include/llvm-c/Core.h
llvm/trunk/include/llvm/IR/LLVMContext.h
llvm/trunk/include/llvm/Pass.h
llvm/trunk/include/llvm/PassSupport.h
llvm/trunk/lib/IR/Core.cpp
llvm/trunk/lib/IR/LLVMContext.cpp
llvm/trunk/lib/IR/LLVMContextImpl.cpp
llvm/trunk/lib/IR/LLVMContextImpl.h
llvm/trunk/lib/IR/LegacyPassManager.cpp
llvm/trunk/lib/IR/Pass.cpp
llvm/trunk/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
Modified: llvm/trunk/include/llvm-c/Core.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=207430&r1=207429&r2=207430&view=diff
==============================================================================
--- llvm/trunk/include/llvm-c/Core.h (original)
+++ llvm/trunk/include/llvm-c/Core.h Mon Apr 28 13:19:25 2014
@@ -112,12 +112,23 @@ typedef struct LLVMOpaqueBuilder *LLVMBu
*/
typedef struct LLVMOpaqueModuleProvider *LLVMModuleProviderRef;
+/** @see llvm::Pass */
+typedef struct LLVMOpaquePass *LLVMPassRef;
+
/** @see llvm::PassManagerBase */
typedef struct LLVMOpaquePassManager *LLVMPassManagerRef;
/** @see llvm::PassRegistry */
typedef struct LLVMOpaquePassRegistry *LLVMPassRegistryRef;
+/** @see llvm::PassRunListener */
+typedef struct LLVMOpaquePassRunListener *LLVMPassRunListenerRef;
+
+/** @see llvm::LLVMPassRunListener */
+typedef void (*LLVMPassRunListenerHandlerTy)(LLVMContextRef, LLVMPassRef,
+ LLVMModuleRef, LLVMValueRef,
+ LLVMBasicBlockRef);
+
/**
* Used to get the users and usees of a Value.
*
@@ -515,6 +526,10 @@ unsigned LLVMGetMDKindIDInContext(LLVMCo
unsigned SLen);
unsigned LLVMGetMDKindID(const char* Name, unsigned SLen);
+LLVMPassRunListenerRef LLVMAddPassRunListener(LLVMContextRef,
+ LLVMPassRunListenerHandlerTy);
+void LLVMRemovePassRunListener(LLVMContextRef, LLVMPassRunListenerRef);
+
/**
* @}
*/
@@ -2761,6 +2776,18 @@ void LLVMDisposeMemoryBuffer(LLVMMemoryB
/**
* @}
+ */
+
+/**
+ * @defgroup LLVMCCorePass Pass
+ *
+ * @{
+ */
+
+const char *LLVMGetPassName(LLVMPassRef);
+
+/**
+ * @}
*/
/**
Modified: llvm/trunk/include/llvm/IR/LLVMContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/LLVMContext.h?rev=207430&r1=207429&r2=207430&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/LLVMContext.h (original)
+++ llvm/trunk/include/llvm/IR/LLVMContext.h Mon Apr 28 13:19:25 2014
@@ -21,16 +21,19 @@
namespace llvm {
-class LLVMContextImpl;
-class StringRef;
-class Twine;
+class BasicBlock;
+class DebugLoc;
+class DiagnosticInfo;
+class Function;
class Instruction;
+class LLVMContextImpl;
class Module;
-class SMDiagnostic;
-class DiagnosticInfo;
+class Pass;
+struct PassRunListener;
template <typename T> class SmallVectorImpl;
-class Function;
-class DebugLoc;
+class SMDiagnostic;
+class StringRef;
+class Twine;
/// This is an important class for using LLVM in a threaded context. It
/// (opaquely) owns and manages the core "global" data of LLVM's core
@@ -136,6 +139,16 @@ public:
void emitOptimizationRemark(const char *PassName, const Function &Fn,
const DebugLoc &DLoc, const Twine &Msg);
+ /// \brief Notify that we finished running a pass.
+ void notifyPassRun(Pass *P, Module *M, Function *F = nullptr,
+ BasicBlock *BB = nullptr);
+ /// \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 *L);
+ /// \brief Unregister a PassRunListener so that it no longer receives
+ /// notifyPassRun() callbacks. Remove and free the listener from the context.
+ void removeRunListener(PassRunListener *L);
private:
LLVMContext(LLVMContext&) LLVM_DELETED_FUNCTION;
void operator=(LLVMContext&) LLVM_DELETED_FUNCTION;
Modified: llvm/trunk/include/llvm/Pass.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Pass.h?rev=207430&r1=207429&r2=207430&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Pass.h (original)
+++ llvm/trunk/include/llvm/Pass.h Mon Apr 28 13:19:25 2014
@@ -29,7 +29,9 @@
#ifndef LLVM_PASS_H
#define LLVM_PASS_H
+#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Compiler.h"
+#include "llvm-c/Core.h"
#include <string>
namespace llvm {
@@ -369,6 +371,9 @@ protected:
/// @brief This is the storage for the -time-passes option.
extern bool TimePassesIsEnabled;
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Pass, LLVMPassRef)
+
} // End llvm namespace
// Include support files that contain important APIs commonly used by Passes,
Modified: llvm/trunk/include/llvm/PassSupport.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/PassSupport.h?rev=207430&r1=207429&r2=207430&view=diff
==============================================================================
--- llvm/trunk/include/llvm/PassSupport.h (original)
+++ llvm/trunk/include/llvm/PassSupport.h Mon Apr 28 13:19:25 2014
@@ -31,6 +31,7 @@
namespace llvm {
class TargetMachine;
+class LLVMContext;
//===---------------------------------------------------------------------------
/// PassInfo class - An instance of this class exists for every pass known by
/// the system, and can be obtained from a live Pass by calling its
@@ -355,6 +356,21 @@ struct PassRegistrationListener {
virtual void passEnumerate(const PassInfo *) {}
};
+//===---------------------------------------------------------------------------
+/// PassRunListener class - This class is meant to be derived from by
+/// clients that are interested in which and when passes are run at runtime.
+struct PassRunListener {
+ /// PassRunListener ctor - Add the current object to the list of
+ /// PassRunListeners...
+ PassRunListener(LLVMContext *);
+
+ virtual ~PassRunListener();
+
+ /// Callback function - This functions is invoked whenever a pass has run.
+ virtual void passRun(LLVMContext *, Pass *, Module *, Function *,
+ BasicBlock *) {}
+};
+
} // End llvm namespace
Modified: llvm/trunk/lib/IR/Core.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Core.cpp?rev=207430&r1=207429&r2=207430&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Core.cpp (original)
+++ llvm/trunk/lib/IR/Core.cpp Mon Apr 28 13:19:25 2014
@@ -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 LLVMGetDiagInfoSe
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(LLVMMemoryB
delete unwrap(MemBuf);
}
+/*===-- Pass -------------------------------------------------------------===*/
+
+const char *LLVMGetPassName(LLVMPassRef P) {
+ return unwrap(P)->getPassName();
+}
+
/*===-- Pass Registry -----------------------------------------------------===*/
LLVMPassRegistryRef LLVMGetGlobalPassRegistry(void) {
Modified: llvm/trunk/lib/IR/LLVMContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContext.cpp?rev=207430&r1=207429&r2=207430&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContext.cpp (original)
+++ llvm/trunk/lib/IR/LLVMContext.cpp Mon Apr 28 13:19:25 2014
@@ -214,3 +214,23 @@ void LLVMContext::getMDKindNames(SmallVe
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);
+}
Modified: llvm/trunk/lib/IR/LLVMContextImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.cpp?rev=207430&r1=207429&r2=207430&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContextImpl.cpp (original)
+++ llvm/trunk/lib/IR/LLVMContextImpl.cpp Mon Apr 28 13:19:25 2014
@@ -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
Modified: llvm/trunk/lib/IR/LLVMContextImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=207430&r1=207429&r2=207430&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContextImpl.h (original)
+++ llvm/trunk/lib/IR/LLVMContextImpl.h Mon Apr 28 13:19:25 2014
@@ -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();
};
Modified: llvm/trunk/lib/IR/LegacyPassManager.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LegacyPassManager.cpp?rev=207430&r1=207429&r2=207430&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LegacyPassManager.cpp (original)
+++ llvm/trunk/lib/IR/LegacyPassManager.cpp Mon Apr 28 13:19:25 2014
@@ -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(Functi
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(Functi
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
Modified: llvm/trunk/lib/IR/Pass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Pass.cpp?rev=207430&r1=207429&r2=207430&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Pass.cpp (original)
+++ llvm/trunk/lib/IR/Pass.cpp Mon Apr 28 13:19:25 2014
@@ -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::enumerate
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() {}
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp?rev=207430&r1=207429&r2=207430&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp Mon Apr 28 13:19:25 2014
@@ -28,6 +28,7 @@ using namespace llvm;
static bool didCallAllocateCodeSection;
static bool didAllocateCompactUnwindSection;
+static bool didCallPassRunListener;
static uint8_t *roundTripAllocateCodeSection(void *object, uintptr_t size,
unsigned alignment,
@@ -64,6 +65,12 @@ static void roundTripDestroy(void *objec
delete static_cast<SectionMemoryManager*>(object);
}
+static void passRunListenerCallback(LLVMContextRef C, LLVMPassRef P,
+ LLVMModuleRef M, LLVMValueRef F,
+ LLVMBasicBlockRef BB) {
+ didCallPassRunListener = true;
+}
+
namespace {
// memory manager to test reserve allocation space callback
@@ -142,6 +149,7 @@ protected:
virtual void SetUp() {
didCallAllocateCodeSection = false;
didAllocateCompactUnwindSection = false;
+ didCallPassRunListener = false;
Module = 0;
Function = 0;
Engine = 0;
@@ -429,3 +437,23 @@ TEST_F(MCJITCAPITest, reserve_allocation
EXPECT_TRUE(MM->UsedCodeSize > 0);
EXPECT_TRUE(MM->UsedDataSizeRW > 0);
}
+
+TEST_F(MCJITCAPITest, pass_run_listener) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ buildSimpleFunction();
+ buildMCJITOptions();
+ buildMCJITEngine();
+ LLVMContextRef C = LLVMGetGlobalContext();
+ LLVMAddPassRunListener(C, passRunListenerCallback);
+ buildAndRunPasses();
+
+ union {
+ void *raw;
+ int (*usable)();
+ } functionPointer;
+ functionPointer.raw = LLVMGetPointerToGlobal(Engine, Function);
+
+ EXPECT_EQ(42, functionPointer.usable());
+ EXPECT_TRUE(didCallPassRunListener);
+}
More information about the llvm-commits
mailing list