aot_orc_extra.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "llvm-c/LLJIT.h"
  6. #include "llvm-c/Orc.h"
  7. #include "llvm-c/OrcEE.h"
  8. #include "llvm-c/TargetMachine.h"
  9. #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
  10. #include "llvm/ExecutionEngine/Orc/LLJIT.h"
  11. #include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
  12. #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
  13. #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
  14. #include "llvm/ExecutionEngine/SectionMemoryManager.h"
  15. #include "llvm/Support/CBindingWrapping.h"
  16. #include "aot_orc_extra.h"
  17. #include "aot.h"
  18. using namespace llvm;
  19. using namespace llvm::orc;
  20. using GlobalValueSet = std::set<const GlobalValue *>;
  21. namespace llvm {
  22. namespace orc {
  23. class InProgressLookupState;
  24. class OrcV2CAPIHelper
  25. {
  26. public:
  27. using PoolEntry = SymbolStringPtr::PoolEntry;
  28. using PoolEntryPtr = SymbolStringPtr::PoolEntryPtr;
  29. // Move from SymbolStringPtr to PoolEntryPtr (no change in ref count).
  30. static PoolEntryPtr moveFromSymbolStringPtr(SymbolStringPtr S)
  31. {
  32. PoolEntryPtr Result = nullptr;
  33. std::swap(Result, S.S);
  34. return Result;
  35. }
  36. // Move from a PoolEntryPtr to a SymbolStringPtr (no change in ref count).
  37. static SymbolStringPtr moveToSymbolStringPtr(PoolEntryPtr P)
  38. {
  39. SymbolStringPtr S;
  40. S.S = P;
  41. return S;
  42. }
  43. // Copy a pool entry to a SymbolStringPtr (increments ref count).
  44. static SymbolStringPtr copyToSymbolStringPtr(PoolEntryPtr P)
  45. {
  46. return SymbolStringPtr(P);
  47. }
  48. static PoolEntryPtr getRawPoolEntryPtr(const SymbolStringPtr &S)
  49. {
  50. return S.S;
  51. }
  52. static void retainPoolEntry(PoolEntryPtr P)
  53. {
  54. SymbolStringPtr S(P);
  55. S.S = nullptr;
  56. }
  57. static void releasePoolEntry(PoolEntryPtr P)
  58. {
  59. SymbolStringPtr S;
  60. S.S = P;
  61. }
  62. static InProgressLookupState *extractLookupState(LookupState &LS)
  63. {
  64. return LS.IPLS.release();
  65. }
  66. static void resetLookupState(LookupState &LS, InProgressLookupState *IPLS)
  67. {
  68. return LS.reset(IPLS);
  69. }
  70. };
  71. } // namespace orc
  72. } // namespace llvm
  73. // ORC.h
  74. DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionSession, LLVMOrcExecutionSessionRef)
  75. DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRTransformLayer, LLVMOrcIRTransformLayerRef)
  76. DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITDylib, LLVMOrcJITDylibRef)
  77. DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITTargetMachineBuilder,
  78. LLVMOrcJITTargetMachineBuilderRef)
  79. DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectTransformLayer,
  80. LLVMOrcObjectTransformLayerRef)
  81. DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcV2CAPIHelper::PoolEntry,
  82. LLVMOrcSymbolStringPoolEntryRef)
  83. DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SymbolStringPool, LLVMOrcSymbolStringPoolRef)
  84. DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeModule, LLVMOrcThreadSafeModuleRef)
  85. // LLJIT.h
  86. DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJITBuilder, LLVMOrcLLJITBuilderRef)
  87. DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLLazyJITBuilder, LLVMOrcLLLazyJITBuilderRef)
  88. DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLLazyJIT, LLVMOrcLLLazyJITRef)
  89. void
  90. LLVMOrcLLJITBuilderSetNumCompileThreads(LLVMOrcLLJITBuilderRef Builder,
  91. unsigned NumCompileThreads)
  92. {
  93. unwrap(Builder)->setNumCompileThreads(NumCompileThreads);
  94. }
  95. LLVMOrcLLLazyJITBuilderRef
  96. LLVMOrcCreateLLLazyJITBuilder(void)
  97. {
  98. return wrap(new LLLazyJITBuilder());
  99. }
  100. void
  101. LLVMOrcDisposeLLLazyJITBuilder(LLVMOrcLLLazyJITBuilderRef Builder)
  102. {
  103. delete unwrap(Builder);
  104. }
  105. void
  106. LLVMOrcLLLazyJITBuilderSetNumCompileThreads(LLVMOrcLLLazyJITBuilderRef Builder,
  107. unsigned NumCompileThreads)
  108. {
  109. unwrap(Builder)->setNumCompileThreads(NumCompileThreads);
  110. }
  111. void
  112. LLVMOrcLLLazyJITBuilderSetJITTargetMachineBuilder(
  113. LLVMOrcLLLazyJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMP)
  114. {
  115. unwrap(Builder)->setJITTargetMachineBuilder(*unwrap(JTMP));
  116. /* Destroy the JTMP, similar to
  117. LLVMOrcLLJITBuilderSetJITTargetMachineBuilder */
  118. LLVMOrcDisposeJITTargetMachineBuilder(JTMP);
  119. }
  120. static Optional<CompileOnDemandLayer::GlobalValueSet>
  121. PartitionFunction(GlobalValueSet Requested)
  122. {
  123. std::vector<const GlobalValue *> GVsToAdd;
  124. for (auto *GV : Requested) {
  125. if (isa<Function>(GV) && GV->hasName()) {
  126. auto &F = cast<Function>(*GV); /* get LLVM function */
  127. const Module *M = F.getParent(); /* get LLVM module */
  128. auto GVName = GV->getName(); /* get the function name */
  129. const char *gvname = GVName.begin(); /* C function name */
  130. const char *wrapper;
  131. uint32 prefix_len = strlen(AOT_FUNC_PREFIX);
  132. /* Convert "aot_func#n_wrapper" to "aot_func#n" */
  133. if (strstr(gvname, AOT_FUNC_PREFIX)
  134. && (wrapper = strstr(gvname + prefix_len, "_wrapper"))) {
  135. char buf[16] = { 0 };
  136. char func_name[64];
  137. int group_stride, i, j;
  138. bh_assert(wrapper - (gvname + prefix_len) > 0);
  139. /* Get AOT function index */
  140. bh_memcpy_s(buf, (uint32)sizeof(buf), gvname + prefix_len,
  141. (uint32)(wrapper - (gvname + prefix_len)));
  142. i = atoi(buf);
  143. group_stride = WASM_ORC_JIT_BACKEND_THREAD_NUM;
  144. /* Compile some functions each time */
  145. for (j = 0; j < WASM_ORC_JIT_COMPILE_THREAD_NUM; j++) {
  146. snprintf(func_name, sizeof(func_name), "%s%d",
  147. AOT_FUNC_PREFIX, i + j * group_stride);
  148. Function *F1 = M->getFunction(func_name);
  149. if (F1) {
  150. LOG_DEBUG("compile func %s", func_name);
  151. GVsToAdd.push_back(cast<GlobalValue>(F1));
  152. }
  153. }
  154. }
  155. }
  156. }
  157. for (auto *GV : GVsToAdd) {
  158. Requested.insert(GV);
  159. }
  160. return Requested;
  161. }
  162. LLVMErrorRef
  163. LLVMOrcCreateLLLazyJIT(LLVMOrcLLLazyJITRef *Result,
  164. LLVMOrcLLLazyJITBuilderRef Builder)
  165. {
  166. assert(Result && "Result can not be null");
  167. if (!Builder)
  168. Builder = LLVMOrcCreateLLLazyJITBuilder();
  169. auto J = unwrap(Builder)->create();
  170. LLVMOrcDisposeLLLazyJITBuilder(Builder);
  171. if (!J) {
  172. Result = nullptr;
  173. return 0;
  174. }
  175. LLLazyJIT *lazy_jit = J->release();
  176. lazy_jit->setPartitionFunction(PartitionFunction);
  177. *Result = wrap(lazy_jit);
  178. return LLVMErrorSuccess;
  179. }
  180. LLVMErrorRef
  181. LLVMOrcDisposeLLLazyJIT(LLVMOrcLLLazyJITRef J)
  182. {
  183. delete unwrap(J);
  184. return LLVMErrorSuccess;
  185. }
  186. LLVMErrorRef
  187. LLVMOrcLLLazyJITAddLLVMIRModule(LLVMOrcLLLazyJITRef J, LLVMOrcJITDylibRef JD,
  188. LLVMOrcThreadSafeModuleRef TSM)
  189. {
  190. std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(TSM));
  191. return wrap(unwrap(J)->addLazyIRModule(*unwrap(JD), std::move(*TmpTSM)));
  192. }
  193. LLVMErrorRef
  194. LLVMOrcLLLazyJITLookup(LLVMOrcLLLazyJITRef J, LLVMOrcExecutorAddress *Result,
  195. const char *Name)
  196. {
  197. assert(Result && "Result can not be null");
  198. auto Sym = unwrap(J)->lookup(Name);
  199. if (!Sym) {
  200. *Result = 0;
  201. return wrap(Sym.takeError());
  202. }
  203. #if LLVM_VERSION_MAJOR < 15
  204. *Result = Sym->getAddress();
  205. #else
  206. *Result = Sym->getValue();
  207. #endif
  208. return LLVMErrorSuccess;
  209. }
  210. LLVMOrcSymbolStringPoolEntryRef
  211. LLVMOrcLLLazyJITMangleAndIntern(LLVMOrcLLLazyJITRef J,
  212. const char *UnmangledName)
  213. {
  214. return wrap(OrcV2CAPIHelper::moveFromSymbolStringPtr(
  215. unwrap(J)->mangleAndIntern(UnmangledName)));
  216. }
  217. LLVMOrcJITDylibRef
  218. LLVMOrcLLLazyJITGetMainJITDylib(LLVMOrcLLLazyJITRef J)
  219. {
  220. return wrap(&unwrap(J)->getMainJITDylib());
  221. }
  222. const char *
  223. LLVMOrcLLLazyJITGetTripleString(LLVMOrcLLLazyJITRef J)
  224. {
  225. return unwrap(J)->getTargetTriple().str().c_str();
  226. }
  227. LLVMOrcExecutionSessionRef
  228. LLVMOrcLLLazyJITGetExecutionSession(LLVMOrcLLLazyJITRef J)
  229. {
  230. return wrap(&unwrap(J)->getExecutionSession());
  231. }
  232. LLVMOrcIRTransformLayerRef
  233. LLVMOrcLLLazyJITGetIRTransformLayer(LLVMOrcLLLazyJITRef J)
  234. {
  235. return wrap(&unwrap(J)->getIRTransformLayer());
  236. }
  237. LLVMOrcObjectTransformLayerRef
  238. LLVMOrcLLLazyJITGetObjTransformLayer(LLVMOrcLLLazyJITRef J)
  239. {
  240. return wrap(&unwrap(J)->getObjTransformLayer());
  241. }