JITLinkGeneric.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. //===--------- JITLinkGeneric.cpp - Generic JIT linker utilities ----------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Generic JITLinker utility class.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "JITLinkGeneric.h"
  13. #include "llvm/Support/BinaryStreamReader.h"
  14. #include "llvm/Support/MemoryBuffer.h"
  15. #define DEBUG_TYPE "jitlink"
  16. namespace llvm {
  17. namespace jitlink {
  18. JITLinkerBase::~JITLinkerBase() = default;
  19. void JITLinkerBase::linkPhase1(std::unique_ptr<JITLinkerBase> Self) {
  20. LLVM_DEBUG({
  21. dbgs() << "Starting link phase 1 for graph " << G->getName() << "\n";
  22. });
  23. // Prune and optimize the graph.
  24. if (auto Err = runPasses(Passes.PrePrunePasses))
  25. return Ctx->notifyFailed(std::move(Err));
  26. LLVM_DEBUG({
  27. dbgs() << "Link graph \"" << G->getName() << "\" pre-pruning:\n";
  28. G->dump(dbgs());
  29. });
  30. prune(*G);
  31. LLVM_DEBUG({
  32. dbgs() << "Link graph \"" << G->getName() << "\" post-pruning:\n";
  33. G->dump(dbgs());
  34. });
  35. // Run post-pruning passes.
  36. if (auto Err = runPasses(Passes.PostPrunePasses))
  37. return Ctx->notifyFailed(std::move(Err));
  38. Ctx->getMemoryManager().allocate(
  39. Ctx->getJITLinkDylib(), *G,
  40. [S = std::move(Self)](AllocResult AR) mutable {
  41. // FIXME: Once MSVC implements c++17 order of evaluation rules for calls
  42. // this can be simplified to
  43. // S->linkPhase2(std::move(S), std::move(AR));
  44. auto *TmpSelf = S.get();
  45. TmpSelf->linkPhase2(std::move(S), std::move(AR));
  46. });
  47. }
  48. void JITLinkerBase::linkPhase2(std::unique_ptr<JITLinkerBase> Self,
  49. AllocResult AR) {
  50. if (AR)
  51. Alloc = std::move(*AR);
  52. else
  53. return Ctx->notifyFailed(AR.takeError());
  54. LLVM_DEBUG({
  55. dbgs() << "Link graph \"" << G->getName()
  56. << "\" before post-allocation passes:\n";
  57. G->dump(dbgs());
  58. });
  59. // Run post-allocation passes.
  60. if (auto Err = runPasses(Passes.PostAllocationPasses))
  61. return Ctx->notifyFailed(std::move(Err));
  62. // Notify client that the defined symbols have been assigned addresses.
  63. LLVM_DEBUG(dbgs() << "Resolving symbols defined in " << G->getName() << "\n");
  64. if (auto Err = Ctx->notifyResolved(*G))
  65. return Ctx->notifyFailed(std::move(Err));
  66. auto ExternalSymbols = getExternalSymbolNames();
  67. // If there are no external symbols then proceed immediately with phase 3.
  68. if (ExternalSymbols.empty()) {
  69. LLVM_DEBUG({
  70. dbgs() << "No external symbols for " << G->getName()
  71. << ". Proceeding immediately with link phase 3.\n";
  72. });
  73. // FIXME: Once MSVC implements c++17 order of evaluation rules for calls
  74. // this can be simplified. See below.
  75. auto &TmpSelf = *Self;
  76. TmpSelf.linkPhase3(std::move(Self), AsyncLookupResult());
  77. return;
  78. }
  79. // Otherwise look up the externals.
  80. LLVM_DEBUG({
  81. dbgs() << "Issuing lookup for external symbols for " << G->getName()
  82. << " (may trigger materialization/linking of other graphs)...\n";
  83. });
  84. // We're about to hand off ownership of ourself to the continuation. Grab a
  85. // pointer to the context so that we can call it to initiate the lookup.
  86. //
  87. // FIXME: Once MSVC implements c++17 order of evaluation rules for calls this
  88. // can be simplified to:
  89. //
  90. // Ctx->lookup(std::move(UnresolvedExternals),
  91. // [Self=std::move(Self)](Expected<AsyncLookupResult> Result) {
  92. // Self->linkPhase3(std::move(Self), std::move(Result));
  93. // });
  94. Ctx->lookup(std::move(ExternalSymbols),
  95. createLookupContinuation(
  96. [S = std::move(Self)](
  97. Expected<AsyncLookupResult> LookupResult) mutable {
  98. auto &TmpSelf = *S;
  99. TmpSelf.linkPhase3(std::move(S), std::move(LookupResult));
  100. }));
  101. }
  102. void JITLinkerBase::linkPhase3(std::unique_ptr<JITLinkerBase> Self,
  103. Expected<AsyncLookupResult> LR) {
  104. LLVM_DEBUG({
  105. dbgs() << "Starting link phase 3 for graph " << G->getName() << "\n";
  106. });
  107. // If the lookup failed, bail out.
  108. if (!LR)
  109. return abandonAllocAndBailOut(std::move(Self), LR.takeError());
  110. // Assign addresses to external addressables.
  111. applyLookupResult(*LR);
  112. LLVM_DEBUG({
  113. dbgs() << "Link graph \"" << G->getName()
  114. << "\" before pre-fixup passes:\n";
  115. G->dump(dbgs());
  116. });
  117. if (auto Err = runPasses(Passes.PreFixupPasses))
  118. return abandonAllocAndBailOut(std::move(Self), std::move(Err));
  119. LLVM_DEBUG({
  120. dbgs() << "Link graph \"" << G->getName() << "\" before copy-and-fixup:\n";
  121. G->dump(dbgs());
  122. });
  123. // Fix up block content.
  124. if (auto Err = fixUpBlocks(*G))
  125. return abandonAllocAndBailOut(std::move(Self), std::move(Err));
  126. LLVM_DEBUG({
  127. dbgs() << "Link graph \"" << G->getName() << "\" after copy-and-fixup:\n";
  128. G->dump(dbgs());
  129. });
  130. if (auto Err = runPasses(Passes.PostFixupPasses))
  131. return abandonAllocAndBailOut(std::move(Self), std::move(Err));
  132. Alloc->finalize([S = std::move(Self)](FinalizeResult FR) mutable {
  133. // FIXME: Once MSVC implements c++17 order of evaluation rules for calls
  134. // this can be simplified to
  135. // S->linkPhase2(std::move(S), std::move(AR));
  136. auto *TmpSelf = S.get();
  137. TmpSelf->linkPhase4(std::move(S), std::move(FR));
  138. });
  139. }
  140. void JITLinkerBase::linkPhase4(std::unique_ptr<JITLinkerBase> Self,
  141. FinalizeResult FR) {
  142. LLVM_DEBUG({
  143. dbgs() << "Starting link phase 4 for graph " << G->getName() << "\n";
  144. });
  145. if (!FR)
  146. return Ctx->notifyFailed(FR.takeError());
  147. Ctx->notifyFinalized(std::move(*FR));
  148. LLVM_DEBUG({ dbgs() << "Link of graph " << G->getName() << " complete\n"; });
  149. }
  150. Error JITLinkerBase::runPasses(LinkGraphPassList &Passes) {
  151. for (auto &P : Passes)
  152. if (auto Err = P(*G))
  153. return Err;
  154. return Error::success();
  155. }
  156. JITLinkContext::LookupMap JITLinkerBase::getExternalSymbolNames() const {
  157. // Identify unresolved external symbols.
  158. JITLinkContext::LookupMap UnresolvedExternals;
  159. for (auto *Sym : G->external_symbols()) {
  160. assert(!Sym->getAddress() &&
  161. "External has already been assigned an address");
  162. assert(Sym->getName() != StringRef() && Sym->getName() != "" &&
  163. "Externals must be named");
  164. SymbolLookupFlags LookupFlags =
  165. Sym->isWeaklyReferenced() ? SymbolLookupFlags::WeaklyReferencedSymbol
  166. : SymbolLookupFlags::RequiredSymbol;
  167. UnresolvedExternals[Sym->getName()] = LookupFlags;
  168. }
  169. return UnresolvedExternals;
  170. }
  171. void JITLinkerBase::applyLookupResult(AsyncLookupResult Result) {
  172. for (auto *Sym : G->external_symbols()) {
  173. assert(Sym->getOffset() == 0 &&
  174. "External symbol is not at the start of its addressable block");
  175. assert(!Sym->getAddress() && "Symbol already resolved");
  176. assert(!Sym->isDefined() && "Symbol being resolved is already defined");
  177. auto ResultI = Result.find(Sym->getName());
  178. if (ResultI != Result.end()) {
  179. Sym->getAddressable().setAddress(
  180. orc::ExecutorAddr(ResultI->second.getAddress()));
  181. Sym->setLinkage(ResultI->second.getFlags().isWeak() ? Linkage::Weak
  182. : Linkage::Strong);
  183. Sym->setScope(ResultI->second.getFlags().isExported() ? Scope::Default
  184. : Scope::Hidden);
  185. } else
  186. assert(Sym->isWeaklyReferenced() &&
  187. "Failed to resolve non-weak reference");
  188. }
  189. LLVM_DEBUG({
  190. dbgs() << "Externals after applying lookup result:\n";
  191. for (auto *Sym : G->external_symbols()) {
  192. dbgs() << " " << Sym->getName() << ": "
  193. << formatv("{0:x16}", Sym->getAddress().getValue());
  194. switch (Sym->getLinkage()) {
  195. case Linkage::Strong:
  196. break;
  197. case Linkage::Weak:
  198. dbgs() << " (weak)";
  199. break;
  200. }
  201. switch (Sym->getScope()) {
  202. case Scope::Local:
  203. llvm_unreachable("External symbol should not have local linkage");
  204. case Scope::Hidden:
  205. break;
  206. case Scope::Default:
  207. dbgs() << " (exported)";
  208. break;
  209. }
  210. dbgs() << "\n";
  211. }
  212. });
  213. }
  214. void JITLinkerBase::abandonAllocAndBailOut(std::unique_ptr<JITLinkerBase> Self,
  215. Error Err) {
  216. assert(Err && "Should not be bailing out on success value");
  217. assert(Alloc && "can not call abandonAllocAndBailOut before allocation");
  218. Alloc->abandon([S = std::move(Self), E1 = std::move(Err)](Error E2) mutable {
  219. S->Ctx->notifyFailed(joinErrors(std::move(E1), std::move(E2)));
  220. });
  221. }
  222. void prune(LinkGraph &G) {
  223. std::vector<Symbol *> Worklist;
  224. DenseSet<Block *> VisitedBlocks;
  225. // Build the initial worklist from all symbols initially live.
  226. for (auto *Sym : G.defined_symbols())
  227. if (Sym->isLive())
  228. Worklist.push_back(Sym);
  229. // Propagate live flags to all symbols reachable from the initial live set.
  230. while (!Worklist.empty()) {
  231. auto *Sym = Worklist.back();
  232. Worklist.pop_back();
  233. auto &B = Sym->getBlock();
  234. // Skip addressables that we've visited before.
  235. if (VisitedBlocks.count(&B))
  236. continue;
  237. VisitedBlocks.insert(&B);
  238. for (auto &E : Sym->getBlock().edges()) {
  239. // If the edge target is a defined symbol that is being newly marked live
  240. // then add it to the worklist.
  241. if (E.getTarget().isDefined() && !E.getTarget().isLive())
  242. Worklist.push_back(&E.getTarget());
  243. // Mark the target live.
  244. E.getTarget().setLive(true);
  245. }
  246. }
  247. // Collect all defined symbols to remove, then remove them.
  248. {
  249. LLVM_DEBUG(dbgs() << "Dead-stripping defined symbols:\n");
  250. std::vector<Symbol *> SymbolsToRemove;
  251. for (auto *Sym : G.defined_symbols())
  252. if (!Sym->isLive())
  253. SymbolsToRemove.push_back(Sym);
  254. for (auto *Sym : SymbolsToRemove) {
  255. LLVM_DEBUG(dbgs() << " " << *Sym << "...\n");
  256. G.removeDefinedSymbol(*Sym);
  257. }
  258. }
  259. // Delete any unused blocks.
  260. {
  261. LLVM_DEBUG(dbgs() << "Dead-stripping blocks:\n");
  262. std::vector<Block *> BlocksToRemove;
  263. for (auto *B : G.blocks())
  264. if (!VisitedBlocks.count(B))
  265. BlocksToRemove.push_back(B);
  266. for (auto *B : BlocksToRemove) {
  267. LLVM_DEBUG(dbgs() << " " << *B << "...\n");
  268. G.removeBlock(*B);
  269. }
  270. }
  271. // Collect all external symbols to remove, then remove them.
  272. {
  273. LLVM_DEBUG(dbgs() << "Removing unused external symbols:\n");
  274. std::vector<Symbol *> SymbolsToRemove;
  275. for (auto *Sym : G.external_symbols())
  276. if (!Sym->isLive())
  277. SymbolsToRemove.push_back(Sym);
  278. for (auto *Sym : SymbolsToRemove) {
  279. LLVM_DEBUG(dbgs() << " " << *Sym << "...\n");
  280. G.removeExternalSymbol(*Sym);
  281. }
  282. }
  283. }
  284. } // end namespace jitlink
  285. } // end namespace llvm