OSDN Git Service

[ORC] Add C API support for defining absolute symbols.
authorLang Hames <lhames@gmail.com>
Fri, 16 Oct 2020 03:33:22 +0000 (20:33 -0700)
committerLang Hames <lhames@gmail.com>
Mon, 19 Oct 2020 08:59:04 +0000 (01:59 -0700)
Also tweaks the definition of TryToGenerate to make it dovetail more neatly
with the new function.

llvm/include/llvm-c/Orc.h
llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp

index a617318..525da93 100644 (file)
@@ -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().
  */
index a147727..7ee96e3 100644 (file)
@@ -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<DefinitionGenerator> TmpDG(unwrap(DG));
+}
+
+void LLVMOrcDisposeMaterializationUnit(LLVMOrcMaterializationUnitRef MU) {
+  std::unique_ptr<MaterializationUnit> 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<MaterializationUnit> 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<DefinitionGenerator>(unwrap(DG)));
 }
 
-void LLVMOrcDisposeDefinitionGenerator(LLVMOrcDefinitionGeneratorRef DG) {
-  std::unique_ptr<DefinitionGenerator> TmpDG(unwrap(DG));
-}
-
 LLVMOrcDefinitionGeneratorRef LLVMOrcCreateCustomCAPIDefinitionGenerator(
     void *Ctx, LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction F) {
   auto DG = std::make_unique<CAPIDefinitionGenerator>(Ctx, F);