From 24afffe63a7b0c545ab854f7955c9b4322e7e690 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Thu, 15 Oct 2020 20:33:22 -0700 Subject: [PATCH] [ORC] Add C API support for defining absolute symbols. Also tweaks the definition of TryToGenerate to make it dovetail more neatly with the new function. --- llvm/include/llvm-c/Orc.h | 104 ++++++++++++++++++++---- llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp | 63 ++++++++++---- 2 files changed, 136 insertions(+), 31 deletions(-) diff --git a/llvm/include/llvm-c/Orc.h b/llvm/include/llvm-c/Orc.h index a617318..525da93 100644 --- a/llvm/include/llvm-c/Orc.h +++ b/llvm/include/llvm-c/Orc.h @@ -39,6 +39,35 @@ LLVM_C_EXTERN_C_BEGIN typedef uint64_t LLVMOrcJITTargetAddress; /** + * Represents generic linkage flags for a symbol definition. + */ +typedef enum { + LLVMJITSymbolGenericFlagsExported = 1U << 0, + LLVMJITSymbolGenericFlagsWeak = 1U << 1 +} LLVMJITSymbolGenericFlags; + +/** + * Represents target specific flags for a symbol definition. + */ +typedef uint8_t LLVMJITTargetSymbolFlags; + +/** + * Represents the linkage flags for a symbol definition. + */ +typedef struct { + uint8_t GenericFlags; + uint8_t TargetFlags; +} LLVMJITSymbolFlags; + +/** + * Represents an evaluated symbol address and flags. + */ +typedef struct { + LLVMOrcJITTargetAddress Address; + LLVMJITSymbolFlags Flags; +} LLVMJITEvaluatedSymbol; + +/** * A reference to an orc::ExecutionSession instance. */ typedef struct LLVMOrcOpaqueExecutionSession *LLVMOrcExecutionSessionRef; @@ -60,6 +89,20 @@ typedef struct LLVMOrcOpaqueSymbolStringPoolEntry *LLVMOrcSymbolStringPoolEntryRef; /** + * Represents a pair of a symbol name and an evaluated symbol. + */ +typedef struct { + LLVMOrcSymbolStringPoolEntryRef Name; + LLVMJITEvaluatedSymbol Sym; +} LLVMJITCSymbolMapPair; + +/** + * Represents a list of (SymbolStringPtr, JITEvaluatedSymbol) pairs that can be + * used to construct a SymbolMap. + */ +typedef LLVMJITCSymbolMapPair *LLVMOrcCSymbolMapPairs; + +/** * Lookup kind. This can be used by definition generators when deciding whether * to produce a definition for a requested symbol. * @@ -112,6 +155,11 @@ typedef struct { typedef LLVMOrcCLookupSetElement *LLVMOrcCLookupSet; /** + * A reference to an orc::MaterializationUnit. + */ +typedef struct LLVMOrcOpaqueMaterializationUnit *LLVMOrcMaterializationUnitRef; + +/** * A reference to an orc::JITDylib instance. */ typedef struct LLVMOrcOpaqueJITDylib *LLVMOrcJITDylibRef; @@ -178,7 +226,7 @@ typedef LLVMErrorRef (*LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction)( LLVMOrcDefinitionGeneratorRef GeneratorObj, void *Ctx, LLVMOrcLookupStateRef *LookupState, LLVMOrcLookupKind Kind, LLVMOrcJITDylibRef JD, LLVMOrcJITDylibLookupFlags JDLookupFlags, - LLVMOrcCLookupSet LookupSet); + LLVMOrcCLookupSet LookupSet, size_t LookupSetSize); /** * Predicate function for SymbolStringPoolEntries. @@ -272,22 +320,6 @@ void LLVMOrcRetainSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S); 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); @@ -314,6 +346,18 @@ void LLVMOrcDisposeDefinitionGenerator( LLVMOrcDefinitionGeneratorRef DG); /** + * Dispose of a MaterializationUnit. + */ +void LLVMOrcDisposeMaterializationUnit(LLVMOrcMaterializationUnitRef MU); + +/** + * Create a MaterializationUnit to define the given symbols as pointing to + * the corresponding raw addresses. + */ +LLVMOrcMaterializationUnitRef +LLVMOrcAbsoluteSymbols(LLVMOrcCSymbolMapPairs Syms, size_t NumPairs); + +/** * Create a "bare" JITDylib. * * The client is responsible for ensuring that the JITDylib's name is unique, @@ -350,6 +394,32 @@ LLVMOrcExecutionSessionCreateJITDylib(LLVMOrcExecutionSessionRef ES, LLVMOrcJITDylibRef LLVMOrcExecutionSessionGetJITDylibByName(const char *Name); /** + * 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); + +/** + * Add the given MaterializationUnit to the given JITDylib. + * + * If this operation succeeds then JITDylib JD will take ownership of MU. + * If the operation fails then ownership remains with the caller who should + * call LLVMOrcDisposeMaterializationUnit to destroy it. + */ +LLVMErrorRef LLVMOrcJITDylibDefine(LLVMOrcJITDylibRef JD, + LLVMOrcMaterializationUnitRef MU); + +/** * Calls remove on all trackers associated with this JITDylib, see * JITDylib::clear(). */ diff --git a/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp b/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp index a147727..7ee96e3 100644 --- a/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp +++ b/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp @@ -31,6 +31,10 @@ public: return Result; } + static SymbolStringPtr retainSymbolStringPtr(PoolEntryPtr P) { + return SymbolStringPtr(P); + } + static PoolEntryPtr getRawPoolEntryPtr(const SymbolStringPtr &S) { return S.S; } @@ -61,6 +65,8 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionSession, LLVMOrcExecutionSessionRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SymbolStringPool, LLVMOrcSymbolStringPoolRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcV2CAPIHelper::PoolEntry, LLVMOrcSymbolStringPoolEntryRef) +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MaterializationUnit, + LLVMOrcMaterializationUnitRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITDylib, LLVMOrcJITDylibRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ResourceTracker, LLVMOrcResourceTrackerRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DefinitionGenerator, @@ -120,6 +126,8 @@ public: CLookupSet.reserve(LookupSet.size()); for (auto &KV : LookupSet) { LLVMOrcSymbolLookupFlags SLF; + LLVMOrcSymbolStringPoolEntryRef Name = + ::wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(KV.first)); switch (KV.second) { case SymbolLookupFlags::RequiredSymbol: SLF = LLVMOrcSymbolLookupFlagsRequiredSymbol; @@ -128,16 +136,13 @@ public: SLF = LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol; break; } - - CLookupSet.push_back( - {::wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(KV.first)), SLF}); + CLookupSet.push_back({Name, SLF}); } - CLookupSet.push_back({nullptr, LLVMOrcSymbolLookupFlagsRequiredSymbol}); // Run the C TryToGenerate function. - auto Err = - unwrap(TryToGenerate(::wrap(this), Ctx, &LSR, CLookupKind, ::wrap(&JD), - CJDLookupFlags, CLookupSet.data())); + auto Err = unwrap(TryToGenerate(::wrap(this), Ctx, &LSR, CLookupKind, + ::wrap(&JD), CJDLookupFlags, + CLookupSet.data(), CLookupSet.size())); // Restore the lookup state. OrcV2CAPIHelper::resetLookupState(LS, ::unwrap(LSR)); @@ -214,9 +219,32 @@ LLVMErrorRef LLVMOrcResourceTrackerRemove(LLVMOrcResourceTrackerRef RT) { return wrap(TmpRT->remove()); } -void LLVMOrcDisposeDefinitionGenerator( - LLVMOrcDefinitionGeneratorRef DG) { - delete unwrap(DG); +void LLVMOrcDisposeDefinitionGenerator(LLVMOrcDefinitionGeneratorRef DG) { + std::unique_ptr TmpDG(unwrap(DG)); +} + +void LLVMOrcDisposeMaterializationUnit(LLVMOrcMaterializationUnitRef MU) { + std::unique_ptr TmpMU(unwrap(MU)); +} + +LLVMOrcMaterializationUnitRef +LLVMOrcAbsoluteSymbols(LLVMOrcCSymbolMapPairs Syms, size_t NumPairs) { + SymbolMap SM; + for (size_t I = 0; I != NumPairs; ++I) { + JITSymbolFlags Flags; + + if (Syms[I].Sym.Flags.GenericFlags & LLVMJITSymbolGenericFlagsExported) + Flags |= JITSymbolFlags::Exported; + if (Syms[I].Sym.Flags.GenericFlags & LLVMJITSymbolGenericFlagsWeak) + Flags |= JITSymbolFlags::Weak; + + Flags.getTargetFlags() = Syms[I].Sym.Flags.TargetFlags; + + SM[OrcV2CAPIHelper::retainSymbolStringPtr(unwrap(Syms[I].Name))] = + JITEvaluatedSymbol(Syms[I].Sym.Address, Flags); + } + + return wrap(absoluteSymbols(std::move(SM)).release()); } LLVMOrcJITDylibRef @@ -242,6 +270,17 @@ LLVMOrcExecutionSessionGetJITDylibByName(LLVMOrcExecutionSessionRef ES, return wrap(unwrap(ES)->getJITDylibByName(Name)); } +LLVMErrorRef LLVMOrcJITDylibDefine(LLVMOrcJITDylibRef JD, + LLVMOrcMaterializationUnitRef MU) { + std::unique_ptr TmpMU(unwrap(MU)); + + if (auto Err = unwrap(JD)->define(TmpMU)) { + TmpMU.release(); + return wrap(std::move(Err)); + } + return LLVMErrorSuccess; +} + LLVMErrorRef LLVMOrcJITDylibClear(LLVMOrcJITDylibRef JD) { return wrap(unwrap(JD)->clear()); } @@ -251,10 +290,6 @@ void LLVMOrcJITDylibAddGenerator(LLVMOrcJITDylibRef JD, unwrap(JD)->addGenerator(std::unique_ptr(unwrap(DG))); } -void LLVMOrcDisposeDefinitionGenerator(LLVMOrcDefinitionGeneratorRef DG) { - std::unique_ptr TmpDG(unwrap(DG)); -} - LLVMOrcDefinitionGeneratorRef LLVMOrcCreateCustomCAPIDefinitionGenerator( void *Ctx, LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction F) { auto DG = std::make_unique(Ctx, F); -- 2.7.4