From 91d1f417fd89cdbea095f820729df0eb9d465f9f Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Wed, 14 Oct 2020 17:17:44 -0700 Subject: [PATCH] [ORC] Add basic ResourceTracker support to the OrcV2 C Bindings. Based on a patch by Andres Freund. Thanks Andres! --- .../LLJITWithInitializers.cpp | 2 +- llvm/include/llvm-c/Orc.h | 92 ++++++++++++++++++++-- llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h | 20 ++--- llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 17 +++- llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp | 52 ++++++++++++ 5 files changed, 156 insertions(+), 27 deletions(-) diff --git a/llvm/examples/OrcV2Examples/LLJITWithInitializers/LLJITWithInitializers.cpp b/llvm/examples/OrcV2Examples/LLJITWithInitializers/LLJITWithInitializers.cpp index 063b9f6..4fd55c4 100644 --- a/llvm/examples/OrcV2Examples/LLJITWithInitializers/LLJITWithInitializers.cpp +++ b/llvm/examples/OrcV2Examples/LLJITWithInitializers/LLJITWithInitializers.cpp @@ -78,7 +78,7 @@ int main(int argc, char *argv[]) { int32_t InitializersRunFlag = 0; int32_t DeinitializersRunFlag = 0; - ExitOnErr(J->define(absoluteSymbols( + ExitOnErr(J->getMainJITDylib().define(absoluteSymbols( {{J->mangleAndIntern("InitializersRunFlag"), JITEvaluatedSymbol::fromPointer(&InitializersRunFlag)}, {J->mangleAndIntern("DeinitializersRunFlag"), diff --git a/llvm/include/llvm-c/Orc.h b/llvm/include/llvm-c/Orc.h index d0a52e0..c95c11d 100644 --- a/llvm/include/llvm-c/Orc.h +++ b/llvm/include/llvm-c/Orc.h @@ -65,6 +65,11 @@ typedef void (*LLVMOrcErrorReporterFunction)(void *Ctx, LLVMErrorRef Err); typedef struct LLVMOrcOpaqueJITDylib *LLVMOrcJITDylibRef; /** + * A reference to an orc::ResourceTracker instance. + */ +typedef struct LLVMOrcOpaqueResourceTracker *LLVMOrcResourceTrackerRef; + +/** * A reference to an orc::DefinitionGenerator. */ typedef struct LLVMOrcOpaqueDefinitionGenerator @@ -157,6 +162,48 @@ LLVMOrcExecutionSessionIntern(LLVMOrcExecutionSessionRef ES, const char *Name); void LLVMOrcReleaseSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S); /** + * Return a reference to a newly created resource tracker associated with JD. + * The tracker is returned with an initial ref-count of 1, and must be released + * with LLVMOrcReleaseResourceTracker when no longer needed. + */ +LLVMOrcResourceTrackerRef +LLVMOrcJITDylibCreateResourceTracker(LLVMOrcJITDylibRef JD); + +/** + * Return a reference to the default resource tracker for the given JITDylib. + * This operation will increase the retain count of the tracker: Clients should + * call LLVMOrcReleaseResourceTracker when the result is no longer needed. + */ +LLVMOrcResourceTrackerRef +LLVMOrcJITDylibGetDefaultResourceTracker(LLVMOrcJITDylibRef JD); + +/** + * Reduces the ref-count of a ResourceTracker. + */ +void LLVMOrcReleaseResourceTracker(LLVMOrcResourceTrackerRef RT); + +/** + * Transfers tracking of all resources associated with resource tracker SrcRT + * to resource tracker DstRT. + */ +void LLVMOrcResourceTrackerTransferTo(LLVMOrcResourceTrackerRef SrcRT, + LLVMOrcResourceTrackerRef DstRT); + +/** + * Remove all resources associated with the given tracker. See + * ResourceTracker::remove(). + */ +LLVMErrorRef LLVMOrcResourceTrackerRemove(LLVMOrcResourceTrackerRef RT); + +/** + * Dispose of a JITDylib::DefinitionGenerator. This should only be called if + * ownership has not been passed to a JITDylib (e.g. because some error + * prevented the client from calling LLVMOrcJITDylibAddGenerator). + */ +void LLVMOrcDisposeDefinitionGenerator( + LLVMOrcDefinitionGeneratorRef DG); + +/** * Create a "bare" JITDylib. * * The client is responsible for ensuring that the JITDylib's name is unique, @@ -193,12 +240,10 @@ LLVMOrcExecutionSessionCreateJITDylib(LLVMOrcExecutionSessionRef ES, LLVMOrcJITDylibRef LLVMOrcExecutionSessionGetJITDylibByName(const char *Name); /** - * Dispose of a JITDylib::DefinitionGenerator. This should only be called if - * ownership has not been passed to a JITDylib (e.g. because some error - * prevented the client from calling LLVMOrcJITDylibAddGenerator). + * Calls remove on all trackers associated with this JITDylib, see + * JITDylib::clear(). */ -void LLVMOrcDisposeDefinitionGenerator( - LLVMOrcDefinitionGeneratorRef DG); +LLVMErrorRef LLVMOrcJITDylibClear(LLVMOrcJITDylibRef JD); /** * Add a DefinitionGenerator to the given JITDylib. @@ -388,19 +433,52 @@ LLVMOrcLLJITMangleAndIntern(LLVMOrcLLJITRef J, const char *UnmangledName); * LLJIT instance. This operation transfers ownership of the buffer to the * LLJIT instance. The buffer should not be disposed of or referenced once this * function returns. + * + * Resources associated with the given object will be tracked by the given + * JITDylib's default resource tracker. */ LLVMErrorRef LLVMOrcLLJITAddObjectFile(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD, LLVMMemoryBufferRef ObjBuffer); /** - * Add an IR module to the given JITDylib of the given LLJIT instance. This + * Add a buffer representing an object file to the given ResourceTracker's + * JITDylib in the given LLJIT instance. This operation transfers ownership of + * the buffer to the LLJIT instance. The buffer should not be disposed of or + * referenced once this function returns. + * + * Resources associated with the given object will be tracked by ResourceTracker + * RT. + */ +LLVMErrorRef LLVMOrcLLJITAddObjectFileWithRT(LLVMOrcLLJITRef J, + LLVMOrcResourceTrackerRef RT, + LLVMMemoryBufferRef ObjBuffer); + +/** + * Add an IR module to the given JITDylib in the given LLJIT instance. This * operation transfers ownership of the TSM argument to the LLJIT instance. - * The TSM argument should not be 3disposed of or referenced once this + * The TSM argument should not be disposed of or referenced once this * function returns. + * + * Resources associated with the given Module will be tracked by the given + * JITDylib's default resource tracker. */ LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD, LLVMOrcThreadSafeModuleRef TSM); + +/** + * Add an IR module to the given ResourceTracker's JITDylib in the given LLJIT + * instance. This operation transfers ownership of the TSM argument to the LLJIT + * instance. The TSM argument should not be disposed of or referenced once this + * function returns. + * + * Resources associated with the given Module will be tracked by ResourceTracker + * RT. + */ +LLVMErrorRef LLVMOrcLLJITAddLLVMIRModuleWithRT(LLVMOrcLLJITRef J, + LLVMOrcResourceTrackerRef JD, + LLVMOrcThreadSafeModuleRef TSM); + /** * Look up the given symbol in the main JITDylib of the given LLJIT instance. * diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h index 46c91ec..354cf8f 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h @@ -86,21 +86,8 @@ public: return ES->createJITDylib(std::move(Name)); } - /// A convenience method for defining MUs in LLJIT's Main JITDylib. This can - /// be useful for succinctly defining absolute symbols, aliases and - /// re-exports. - template - Error define(std::unique_ptr &&MU) { - return Main->define(std::move(MU)); - } - - /// A convenience method for defining MUs in LLJIT's Main JITDylib. This can - /// be usedful for succinctly defining absolute symbols, aliases and - /// re-exports. - template - Error define(std::unique_ptr &MU) { - return Main->define(MU); - } + /// Adds an IR module with the given ResourceTracker. + Error addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM); /// Adds an IR module to the given JITDylib. Error addIRModule(JITDylib &JD, ThreadSafeModule TSM); @@ -111,6 +98,9 @@ public: } /// Adds an object file to the given JITDylib. + Error addObjectFile(ResourceTrackerSP RT, std::unique_ptr Obj); + + /// Adds an object file to the given JITDylib. Error addObjectFile(JITDylib &JD, std::unique_ptr Obj); /// Adds an object file to the given JITDylib. diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp index 5716fe25..13d4475 100644 --- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp @@ -979,20 +979,29 @@ LLJIT::~LLJIT() { ES->reportError(std::move(Err)); } -Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) { +Error LLJIT::addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM) { assert(TSM && "Can not add null module"); if (auto Err = TSM.withModuleDo([&](Module &M) { return applyDataLayout(M); })) return Err; - return InitHelperTransformLayer->add(JD, std::move(TSM)); + return InitHelperTransformLayer->add(std::move(RT), std::move(TSM)); } -Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr Obj) { +Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) { + return addIRModule(JD.getDefaultResourceTracker(), std::move(TSM)); +} + +Error LLJIT::addObjectFile(ResourceTrackerSP RT, + std::unique_ptr Obj) { assert(Obj && "Can not add null object"); - return ObjTransformLayer.add(JD, std::move(Obj)); + return ObjTransformLayer.add(std::move(RT), std::move(Obj)); +} + +Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr Obj) { + return addObjectFile(JD.getDefaultResourceTracker(), std::move(Obj)); } Expected LLJIT::lookupLinkerMangled(JITDylib &JD, diff --git a/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp b/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp index 4054a46..e90b2dc 100644 --- a/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp +++ b/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp @@ -47,6 +47,7 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SymbolStringPool, LLVMOrcSymbolStringPoolRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcV2CAPIHelper::PoolEntry, LLVMOrcSymbolStringPoolEntryRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITDylib, LLVMOrcJITDylibRef) +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ResourceTracker, LLVMOrcResourceTrackerRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DefinitionGenerator, LLVMOrcDefinitionGeneratorRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeContext, @@ -85,6 +86,37 @@ void LLVMOrcReleaseSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) { OrcV2CAPIHelper::releasePoolEntry(unwrap(S)); } +LLVMOrcResourceTrackerRef +LLVMOrcJITDylibCreateResourceTracker(LLVMOrcJITDylibRef JD) { + auto RT = unwrap(JD)->createResourceTracker(); + // Retain the pointer for the C API client. + RT->Retain(); + return wrap(RT.get()); +} + +LLVMOrcResourceTrackerRef +LLVMOrcJITDylibGetDefaultResourceTracker(LLVMOrcJITDylibRef JD) { + auto RT = unwrap(JD)->getDefaultResourceTracker(); + // Retain the pointer for the C API client. + return wrap(RT.get()); +} + +void LLVMOrcReleaseResourceTracker(LLVMOrcResourceTrackerRef RT) { + ResourceTrackerSP TmpRT(unwrap(RT)); + TmpRT->Release(); +} + +void LLVMOrcResourceTrackerTransferTo(LLVMOrcResourceTrackerRef SrcRT, + LLVMOrcResourceTrackerRef DstRT) { + ResourceTrackerSP TmpRT(unwrap(SrcRT)); + TmpRT->transferTo(*unwrap(DstRT)); +} + +LLVMErrorRef LLVMOrcResourceTrackerRemove(LLVMOrcResourceTrackerRef RT) { + ResourceTrackerSP TmpRT(unwrap(RT)); + return wrap(TmpRT->remove()); +} + LLVMOrcJITDylibRef LLVMOrcExecutionSessionCreateBareJITDylib(LLVMOrcExecutionSessionRef ES, const char *Name) { @@ -113,6 +145,10 @@ void LLVMOrcDisposeDefinitionGenerator( delete unwrap(DG); } +LLVMErrorRef LLVMOrcJITDylibClear(LLVMOrcJITDylibRef JD) { + return wrap(unwrap(JD)->clear()); +} + void LLVMOrcJITDylibAddGenerator(LLVMOrcJITDylibRef JD, LLVMOrcDefinitionGeneratorRef DG) { unwrap(JD)->addGenerator(std::unique_ptr(unwrap(DG))); @@ -271,6 +307,14 @@ LLVMErrorRef LLVMOrcLLJITAddObjectFile(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD, *unwrap(JD), std::unique_ptr(unwrap(ObjBuffer)))); } +LLVMErrorRef LLVMOrcLLJITAddObjectFileWithRT(LLVMOrcLLJITRef J, + LLVMOrcResourceTrackerRef RT, + LLVMMemoryBufferRef ObjBuffer) { + return wrap(unwrap(J)->addObjectFile( + ResourceTrackerSP(unwrap(RT)), + std::unique_ptr(unwrap(ObjBuffer)))); +} + LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD, LLVMOrcThreadSafeModuleRef TSM) { @@ -278,6 +322,14 @@ LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J, return wrap(unwrap(J)->addIRModule(*unwrap(JD), std::move(*TmpTSM))); } +LLVMErrorRef LLVMOrcLLJITAddLLVMIRModuleWithRT(LLVMOrcLLJITRef J, + LLVMOrcResourceTrackerRef RT, + LLVMOrcThreadSafeModuleRef TSM) { + std::unique_ptr TmpTSM(unwrap(TSM)); + return wrap(unwrap(J)->addIRModule(ResourceTrackerSP(unwrap(RT)), + std::move(*TmpTSM))); +} + LLVMErrorRef LLVMOrcLLJITLookup(LLVMOrcLLJITRef J, LLVMOrcJITTargetAddress *Result, const char *Name) { -- 2.7.4