1 //===--------- LLJIT.cpp - An ORC-based JIT for compiling LLVM IR ---------===// 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 #include "llvm/ExecutionEngine/Orc/LLJIT.h" 10 #include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h" 11 #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h" 12 #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h" 13 #include "llvm/ExecutionEngine/Orc/MachOPlatform.h" 14 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" 15 #include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h" 16 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" 17 #include "llvm/ExecutionEngine/Orc/Shared/OrcError.h" 18 #include "llvm/ExecutionEngine/SectionMemoryManager.h" 19 #include "llvm/IR/GlobalVariable.h" 20 #include "llvm/IR/IRBuilder.h" 21 #include "llvm/IR/Mangler.h" 22 #include "llvm/IR/Module.h" 23 #include "llvm/Support/DynamicLibrary.h" 24 25 #include <map> 26 27 #define DEBUG_TYPE "orc" 28 29 using namespace llvm; 30 using namespace llvm::orc; 31 32 namespace { 33 34 /// Adds helper function decls and wrapper functions that call the helper with 35 /// some additional prefix arguments. 36 /// 37 /// E.g. For wrapper "foo" with type i8(i8, i64), helper "bar", and prefix 38 /// args i32 4 and i16 12345, this function will add: 39 /// 40 /// declare i8 @bar(i32, i16, i8, i64) 41 /// 42 /// define i8 @foo(i8, i64) { 43 /// entry: 44 /// %2 = call i8 @bar(i32 4, i16 12345, i8 %0, i64 %1) 45 /// ret i8 %2 46 /// } 47 /// 48 Function *addHelperAndWrapper(Module &M, StringRef WrapperName, 49 FunctionType *WrapperFnType, 50 GlobalValue::VisibilityTypes WrapperVisibility, 51 StringRef HelperName, 52 ArrayRef<Value *> HelperPrefixArgs) { 53 std::vector<Type *> HelperArgTypes; 54 for (auto *Arg : HelperPrefixArgs) 55 HelperArgTypes.push_back(Arg->getType()); 56 for (auto *T : WrapperFnType->params()) 57 HelperArgTypes.push_back(T); 58 auto *HelperFnType = 59 FunctionType::get(WrapperFnType->getReturnType(), HelperArgTypes, false); 60 auto *HelperFn = Function::Create(HelperFnType, GlobalValue::ExternalLinkage, 61 HelperName, M); 62 63 auto *WrapperFn = Function::Create( 64 WrapperFnType, GlobalValue::ExternalLinkage, WrapperName, M); 65 WrapperFn->setVisibility(WrapperVisibility); 66 67 auto *EntryBlock = BasicBlock::Create(M.getContext(), "entry", WrapperFn); 68 IRBuilder<> IB(EntryBlock); 69 70 std::vector<Value *> HelperArgs; 71 for (auto *Arg : HelperPrefixArgs) 72 HelperArgs.push_back(Arg); 73 for (auto &Arg : WrapperFn->args()) 74 HelperArgs.push_back(&Arg); 75 auto *HelperResult = IB.CreateCall(HelperFn, HelperArgs); 76 if (HelperFn->getReturnType()->isVoidTy()) 77 IB.CreateRetVoid(); 78 else 79 IB.CreateRet(HelperResult); 80 81 return WrapperFn; 82 } 83 84 class GenericLLVMIRPlatformSupport; 85 86 /// orc::Platform component of Generic LLVM IR Platform support. 87 /// Just forwards calls to the GenericLLVMIRPlatformSupport class below. 88 class GenericLLVMIRPlatform : public Platform { 89 public: 90 GenericLLVMIRPlatform(GenericLLVMIRPlatformSupport &S) : S(S) {} 91 Error setupJITDylib(JITDylib &JD) override; 92 Error teardownJITDylib(JITDylib &JD) override; 93 Error notifyAdding(ResourceTracker &RT, 94 const MaterializationUnit &MU) override; 95 Error notifyRemoving(ResourceTracker &RT) override { 96 // Noop -- Nothing to do (yet). 97 return Error::success(); 98 } 99 100 private: 101 GenericLLVMIRPlatformSupport &S; 102 }; 103 104 /// This transform parses llvm.global_ctors to produce a single initialization 105 /// function for the module, records the function, then deletes 106 /// llvm.global_ctors. 107 class GlobalCtorDtorScraper { 108 public: 109 GlobalCtorDtorScraper(GenericLLVMIRPlatformSupport &PS, 110 StringRef InitFunctionPrefix, 111 StringRef DeInitFunctionPrefix) 112 : PS(PS), InitFunctionPrefix(InitFunctionPrefix), 113 DeInitFunctionPrefix(DeInitFunctionPrefix) {} 114 Expected<ThreadSafeModule> operator()(ThreadSafeModule TSM, 115 MaterializationResponsibility &R); 116 117 private: 118 GenericLLVMIRPlatformSupport &PS; 119 StringRef InitFunctionPrefix; 120 StringRef DeInitFunctionPrefix; 121 }; 122 123 /// Generic IR Platform Support 124 /// 125 /// Scrapes llvm.global_ctors and llvm.global_dtors and replaces them with 126 /// specially named 'init' and 'deinit'. Injects definitions / interposes for 127 /// some runtime API, including __cxa_atexit, dlopen, and dlclose. 128 class GenericLLVMIRPlatformSupport : public LLJIT::PlatformSupport { 129 public: 130 GenericLLVMIRPlatformSupport(LLJIT &J) 131 : J(J), InitFunctionPrefix(J.mangle("__orc_init_func.")), 132 DeInitFunctionPrefix(J.mangle("__orc_deinit_func.")) { 133 134 getExecutionSession().setPlatform( 135 std::make_unique<GenericLLVMIRPlatform>(*this)); 136 137 setInitTransform(J, GlobalCtorDtorScraper(*this, InitFunctionPrefix, 138 DeInitFunctionPrefix)); 139 140 SymbolMap StdInterposes; 141 142 StdInterposes[J.mangleAndIntern("__lljit.platform_support_instance")] = 143 JITEvaluatedSymbol(pointerToJITTargetAddress(this), 144 JITSymbolFlags::Exported); 145 StdInterposes[J.mangleAndIntern("__lljit.cxa_atexit_helper")] = 146 JITEvaluatedSymbol(pointerToJITTargetAddress(registerCxaAtExitHelper), 147 JITSymbolFlags()); 148 149 cantFail( 150 J.getMainJITDylib().define(absoluteSymbols(std::move(StdInterposes)))); 151 cantFail(setupJITDylib(J.getMainJITDylib())); 152 cantFail(J.addIRModule(J.getMainJITDylib(), createPlatformRuntimeModule())); 153 } 154 155 ExecutionSession &getExecutionSession() { return J.getExecutionSession(); } 156 157 /// Adds a module that defines the __dso_handle global. 158 Error setupJITDylib(JITDylib &JD) { 159 160 // Add per-jitdylib standard interposes. 161 SymbolMap PerJDInterposes; 162 PerJDInterposes[J.mangleAndIntern("__lljit.run_atexits_helper")] = 163 JITEvaluatedSymbol(pointerToJITTargetAddress(runAtExitsHelper), 164 JITSymbolFlags()); 165 PerJDInterposes[J.mangleAndIntern("__lljit.atexit_helper")] = 166 JITEvaluatedSymbol(pointerToJITTargetAddress(registerAtExitHelper), 167 JITSymbolFlags()); 168 cantFail(JD.define(absoluteSymbols(std::move(PerJDInterposes)))); 169 170 auto Ctx = std::make_unique<LLVMContext>(); 171 auto M = std::make_unique<Module>("__standard_lib", *Ctx); 172 M->setDataLayout(J.getDataLayout()); 173 174 auto *Int64Ty = Type::getInt64Ty(*Ctx); 175 auto *DSOHandle = new GlobalVariable( 176 *M, Int64Ty, true, GlobalValue::ExternalLinkage, 177 ConstantInt::get(Int64Ty, reinterpret_cast<uintptr_t>(&JD)), 178 "__dso_handle"); 179 DSOHandle->setVisibility(GlobalValue::DefaultVisibility); 180 DSOHandle->setInitializer( 181 ConstantInt::get(Int64Ty, pointerToJITTargetAddress(&JD))); 182 183 auto *GenericIRPlatformSupportTy = 184 StructType::create(*Ctx, "lljit.GenericLLJITIRPlatformSupport"); 185 186 auto *PlatformInstanceDecl = new GlobalVariable( 187 *M, GenericIRPlatformSupportTy, true, GlobalValue::ExternalLinkage, 188 nullptr, "__lljit.platform_support_instance"); 189 190 auto *VoidTy = Type::getVoidTy(*Ctx); 191 addHelperAndWrapper( 192 *M, "__lljit_run_atexits", FunctionType::get(VoidTy, {}, false), 193 GlobalValue::HiddenVisibility, "__lljit.run_atexits_helper", 194 {PlatformInstanceDecl, DSOHandle}); 195 196 auto *IntTy = Type::getIntNTy(*Ctx, sizeof(int) * CHAR_BIT); 197 auto *AtExitCallbackTy = FunctionType::get(VoidTy, {}, false); 198 auto *AtExitCallbackPtrTy = PointerType::getUnqual(AtExitCallbackTy); 199 addHelperAndWrapper(*M, "atexit", 200 FunctionType::get(IntTy, {AtExitCallbackPtrTy}, false), 201 GlobalValue::HiddenVisibility, "__lljit.atexit_helper", 202 {PlatformInstanceDecl, DSOHandle}); 203 204 return J.addIRModule(JD, ThreadSafeModule(std::move(M), std::move(Ctx))); 205 } 206 207 Error notifyAdding(ResourceTracker &RT, const MaterializationUnit &MU) { 208 auto &JD = RT.getJITDylib(); 209 if (auto &InitSym = MU.getInitializerSymbol()) 210 InitSymbols[&JD].add(InitSym, SymbolLookupFlags::WeaklyReferencedSymbol); 211 else { 212 // If there's no identified init symbol attached, but there is a symbol 213 // with the GenericIRPlatform::InitFunctionPrefix, then treat that as 214 // an init function. Add the symbol to both the InitSymbols map (which 215 // will trigger a lookup to materialize the module) and the InitFunctions 216 // map (which holds the names of the symbols to execute). 217 for (auto &KV : MU.getSymbols()) 218 if ((*KV.first).startswith(InitFunctionPrefix)) { 219 InitSymbols[&JD].add(KV.first, 220 SymbolLookupFlags::WeaklyReferencedSymbol); 221 InitFunctions[&JD].add(KV.first); 222 } else if ((*KV.first).startswith(DeInitFunctionPrefix)) { 223 DeInitFunctions[&JD].add(KV.first); 224 } 225 } 226 return Error::success(); 227 } 228 229 Error initialize(JITDylib &JD) override { 230 LLVM_DEBUG({ 231 dbgs() << "GenericLLVMIRPlatformSupport getting initializers to run\n"; 232 }); 233 if (auto Initializers = getInitializers(JD)) { 234 LLVM_DEBUG( 235 { dbgs() << "GenericLLVMIRPlatformSupport running initializers\n"; }); 236 for (auto InitFnAddr : *Initializers) { 237 LLVM_DEBUG({ 238 dbgs() << " Running init " << formatv("{0:x16}", InitFnAddr) 239 << "...\n"; 240 }); 241 auto *InitFn = jitTargetAddressToFunction<void (*)()>(InitFnAddr); 242 InitFn(); 243 } 244 } else 245 return Initializers.takeError(); 246 return Error::success(); 247 } 248 249 Error deinitialize(JITDylib &JD) override { 250 LLVM_DEBUG({ 251 dbgs() << "GenericLLVMIRPlatformSupport getting deinitializers to run\n"; 252 }); 253 if (auto Deinitializers = getDeinitializers(JD)) { 254 LLVM_DEBUG({ 255 dbgs() << "GenericLLVMIRPlatformSupport running deinitializers\n"; 256 }); 257 for (auto DeinitFnAddr : *Deinitializers) { 258 LLVM_DEBUG({ 259 dbgs() << " Running deinit " << formatv("{0:x16}", DeinitFnAddr) 260 << "...\n"; 261 }); 262 auto *DeinitFn = jitTargetAddressToFunction<void (*)()>(DeinitFnAddr); 263 DeinitFn(); 264 } 265 } else 266 return Deinitializers.takeError(); 267 268 return Error::success(); 269 } 270 271 void registerInitFunc(JITDylib &JD, SymbolStringPtr InitName) { 272 getExecutionSession().runSessionLocked([&]() { 273 InitFunctions[&JD].add(InitName); 274 }); 275 } 276 277 void registerDeInitFunc(JITDylib &JD, SymbolStringPtr DeInitName) { 278 getExecutionSession().runSessionLocked( 279 [&]() { DeInitFunctions[&JD].add(DeInitName); }); 280 } 281 282 private: 283 284 Expected<std::vector<JITTargetAddress>> getInitializers(JITDylib &JD) { 285 if (auto Err = issueInitLookups(JD)) 286 return std::move(Err); 287 288 DenseMap<JITDylib *, SymbolLookupSet> LookupSymbols; 289 std::vector<JITDylibSP> DFSLinkOrder; 290 291 if (auto Err = getExecutionSession().runSessionLocked([&]() -> Error { 292 if (auto DFSLinkOrderOrErr = JD.getDFSLinkOrder()) 293 DFSLinkOrder = std::move(*DFSLinkOrderOrErr); 294 else 295 return DFSLinkOrderOrErr.takeError(); 296 297 for (auto &NextJD : DFSLinkOrder) { 298 auto IFItr = InitFunctions.find(NextJD.get()); 299 if (IFItr != InitFunctions.end()) { 300 LookupSymbols[NextJD.get()] = std::move(IFItr->second); 301 InitFunctions.erase(IFItr); 302 } 303 } 304 return Error::success(); 305 })) 306 return std::move(Err); 307 308 LLVM_DEBUG({ 309 dbgs() << "JITDylib init order is [ "; 310 for (auto &JD : llvm::reverse(DFSLinkOrder)) 311 dbgs() << "\"" << JD->getName() << "\" "; 312 dbgs() << "]\n"; 313 dbgs() << "Looking up init functions:\n"; 314 for (auto &KV : LookupSymbols) 315 dbgs() << " \"" << KV.first->getName() << "\": " << KV.second << "\n"; 316 }); 317 318 auto &ES = getExecutionSession(); 319 auto LookupResult = Platform::lookupInitSymbols(ES, LookupSymbols); 320 321 if (!LookupResult) 322 return LookupResult.takeError(); 323 324 std::vector<JITTargetAddress> Initializers; 325 while (!DFSLinkOrder.empty()) { 326 auto &NextJD = *DFSLinkOrder.back(); 327 DFSLinkOrder.pop_back(); 328 auto InitsItr = LookupResult->find(&NextJD); 329 if (InitsItr == LookupResult->end()) 330 continue; 331 for (auto &KV : InitsItr->second) 332 Initializers.push_back(KV.second.getAddress()); 333 } 334 335 return Initializers; 336 } 337 338 Expected<std::vector<JITTargetAddress>> getDeinitializers(JITDylib &JD) { 339 auto &ES = getExecutionSession(); 340 341 auto LLJITRunAtExits = J.mangleAndIntern("__lljit_run_atexits"); 342 343 DenseMap<JITDylib *, SymbolLookupSet> LookupSymbols; 344 std::vector<JITDylibSP> DFSLinkOrder; 345 346 if (auto Err = ES.runSessionLocked([&]() -> Error { 347 if (auto DFSLinkOrderOrErr = JD.getDFSLinkOrder()) 348 DFSLinkOrder = std::move(*DFSLinkOrderOrErr); 349 else 350 return DFSLinkOrderOrErr.takeError(); 351 352 for (auto &NextJD : DFSLinkOrder) { 353 auto &JDLookupSymbols = LookupSymbols[NextJD.get()]; 354 auto DIFItr = DeInitFunctions.find(NextJD.get()); 355 if (DIFItr != DeInitFunctions.end()) { 356 LookupSymbols[NextJD.get()] = std::move(DIFItr->second); 357 DeInitFunctions.erase(DIFItr); 358 } 359 JDLookupSymbols.add(LLJITRunAtExits, 360 SymbolLookupFlags::WeaklyReferencedSymbol); 361 } 362 return Error::success(); 363 })) 364 return std::move(Err); 365 366 LLVM_DEBUG({ 367 dbgs() << "JITDylib deinit order is [ "; 368 for (auto &JD : DFSLinkOrder) 369 dbgs() << "\"" << JD->getName() << "\" "; 370 dbgs() << "]\n"; 371 dbgs() << "Looking up deinit functions:\n"; 372 for (auto &KV : LookupSymbols) 373 dbgs() << " \"" << KV.first->getName() << "\": " << KV.second << "\n"; 374 }); 375 376 auto LookupResult = Platform::lookupInitSymbols(ES, LookupSymbols); 377 378 if (!LookupResult) 379 return LookupResult.takeError(); 380 381 std::vector<JITTargetAddress> DeInitializers; 382 for (auto &NextJD : DFSLinkOrder) { 383 auto DeInitsItr = LookupResult->find(NextJD.get()); 384 assert(DeInitsItr != LookupResult->end() && 385 "Every JD should have at least __lljit_run_atexits"); 386 387 auto RunAtExitsItr = DeInitsItr->second.find(LLJITRunAtExits); 388 if (RunAtExitsItr != DeInitsItr->second.end()) 389 DeInitializers.push_back(RunAtExitsItr->second.getAddress()); 390 391 for (auto &KV : DeInitsItr->second) 392 if (KV.first != LLJITRunAtExits) 393 DeInitializers.push_back(KV.second.getAddress()); 394 } 395 396 return DeInitializers; 397 } 398 399 /// Issue lookups for all init symbols required to initialize JD (and any 400 /// JITDylibs that it depends on). 401 Error issueInitLookups(JITDylib &JD) { 402 DenseMap<JITDylib *, SymbolLookupSet> RequiredInitSymbols; 403 std::vector<JITDylibSP> DFSLinkOrder; 404 405 if (auto Err = getExecutionSession().runSessionLocked([&]() -> Error { 406 if (auto DFSLinkOrderOrErr = JD.getDFSLinkOrder()) 407 DFSLinkOrder = std::move(*DFSLinkOrderOrErr); 408 else 409 return DFSLinkOrderOrErr.takeError(); 410 411 for (auto &NextJD : DFSLinkOrder) { 412 auto ISItr = InitSymbols.find(NextJD.get()); 413 if (ISItr != InitSymbols.end()) { 414 RequiredInitSymbols[NextJD.get()] = std::move(ISItr->second); 415 InitSymbols.erase(ISItr); 416 } 417 } 418 return Error::success(); 419 })) 420 return Err; 421 422 return Platform::lookupInitSymbols(getExecutionSession(), 423 RequiredInitSymbols) 424 .takeError(); 425 } 426 427 static void registerCxaAtExitHelper(void *Self, void (*F)(void *), void *Ctx, 428 void *DSOHandle) { 429 LLVM_DEBUG({ 430 dbgs() << "Registering cxa atexit function " << (void *)F << " for JD " 431 << (*static_cast<JITDylib **>(DSOHandle))->getName() << "\n"; 432 }); 433 static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.registerAtExit( 434 F, Ctx, DSOHandle); 435 } 436 437 static void registerAtExitHelper(void *Self, void *DSOHandle, void (*F)()) { 438 LLVM_DEBUG({ 439 dbgs() << "Registering atexit function " << (void *)F << " for JD " 440 << (*static_cast<JITDylib **>(DSOHandle))->getName() << "\n"; 441 }); 442 static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.registerAtExit( 443 reinterpret_cast<void (*)(void *)>(F), nullptr, DSOHandle); 444 } 445 446 static void runAtExitsHelper(void *Self, void *DSOHandle) { 447 LLVM_DEBUG({ 448 dbgs() << "Running atexit functions for JD " 449 << (*static_cast<JITDylib **>(DSOHandle))->getName() << "\n"; 450 }); 451 static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.runAtExits( 452 DSOHandle); 453 } 454 455 // Constructs an LLVM IR module containing platform runtime globals, 456 // functions, and interposes. 457 ThreadSafeModule createPlatformRuntimeModule() { 458 auto Ctx = std::make_unique<LLVMContext>(); 459 auto M = std::make_unique<Module>("__standard_lib", *Ctx); 460 M->setDataLayout(J.getDataLayout()); 461 462 auto *GenericIRPlatformSupportTy = 463 StructType::create(*Ctx, "lljit.GenericLLJITIRPlatformSupport"); 464 465 auto *PlatformInstanceDecl = new GlobalVariable( 466 *M, GenericIRPlatformSupportTy, true, GlobalValue::ExternalLinkage, 467 nullptr, "__lljit.platform_support_instance"); 468 469 auto *Int8Ty = Type::getInt8Ty(*Ctx); 470 auto *IntTy = Type::getIntNTy(*Ctx, sizeof(int) * CHAR_BIT); 471 auto *VoidTy = Type::getVoidTy(*Ctx); 472 auto *BytePtrTy = PointerType::getUnqual(Int8Ty); 473 auto *CxaAtExitCallbackTy = FunctionType::get(VoidTy, {BytePtrTy}, false); 474 auto *CxaAtExitCallbackPtrTy = PointerType::getUnqual(CxaAtExitCallbackTy); 475 476 addHelperAndWrapper( 477 *M, "__cxa_atexit", 478 FunctionType::get(IntTy, {CxaAtExitCallbackPtrTy, BytePtrTy, BytePtrTy}, 479 false), 480 GlobalValue::DefaultVisibility, "__lljit.cxa_atexit_helper", 481 {PlatformInstanceDecl}); 482 483 return ThreadSafeModule(std::move(M), std::move(Ctx)); 484 } 485 486 LLJIT &J; 487 std::string InitFunctionPrefix; 488 std::string DeInitFunctionPrefix; 489 DenseMap<JITDylib *, SymbolLookupSet> InitSymbols; 490 DenseMap<JITDylib *, SymbolLookupSet> InitFunctions; 491 DenseMap<JITDylib *, SymbolLookupSet> DeInitFunctions; 492 ItaniumCXAAtExitSupport AtExitMgr; 493 }; 494 495 Error GenericLLVMIRPlatform::setupJITDylib(JITDylib &JD) { 496 return S.setupJITDylib(JD); 497 } 498 499 Error GenericLLVMIRPlatform::teardownJITDylib(JITDylib &JD) { 500 return Error::success(); 501 } 502 503 Error GenericLLVMIRPlatform::notifyAdding(ResourceTracker &RT, 504 const MaterializationUnit &MU) { 505 return S.notifyAdding(RT, MU); 506 } 507 508 Expected<ThreadSafeModule> 509 GlobalCtorDtorScraper::operator()(ThreadSafeModule TSM, 510 MaterializationResponsibility &R) { 511 auto Err = TSM.withModuleDo([&](Module &M) -> Error { 512 auto &Ctx = M.getContext(); 513 auto *GlobalCtors = M.getNamedGlobal("llvm.global_ctors"); 514 auto *GlobalDtors = M.getNamedGlobal("llvm.global_dtors"); 515 516 auto RegisterCOrDtors = [&](GlobalVariable *GlobalCOrDtors, 517 bool isCtor) -> Error { 518 // If there's no llvm.global_c/dtor or it's just a decl then skip. 519 if (!GlobalCOrDtors || GlobalCOrDtors->isDeclaration()) 520 return Error::success(); 521 std::string InitOrDeInitFunctionName; 522 if (isCtor) 523 raw_string_ostream(InitOrDeInitFunctionName) 524 << InitFunctionPrefix << M.getModuleIdentifier(); 525 else 526 raw_string_ostream(InitOrDeInitFunctionName) 527 << DeInitFunctionPrefix << M.getModuleIdentifier(); 528 529 MangleAndInterner Mangle(PS.getExecutionSession(), M.getDataLayout()); 530 auto InternedInitOrDeInitName = Mangle(InitOrDeInitFunctionName); 531 if (auto Err = R.defineMaterializing( 532 {{InternedInitOrDeInitName, JITSymbolFlags::Callable}})) 533 return Err; 534 535 auto *InitOrDeInitFunc = Function::Create( 536 FunctionType::get(Type::getVoidTy(Ctx), {}, false), 537 GlobalValue::ExternalLinkage, InitOrDeInitFunctionName, &M); 538 InitOrDeInitFunc->setVisibility(GlobalValue::HiddenVisibility); 539 std::vector<std::pair<Function *, unsigned>> InitsOrDeInits; 540 auto COrDtors = isCtor ? getConstructors(M) : getDestructors(M); 541 542 for (auto E : COrDtors) 543 InitsOrDeInits.push_back(std::make_pair(E.Func, E.Priority)); 544 llvm::sort(InitsOrDeInits, llvm::less_second()); 545 546 auto *InitOrDeInitFuncEntryBlock = 547 BasicBlock::Create(Ctx, "entry", InitOrDeInitFunc); 548 IRBuilder<> IB(InitOrDeInitFuncEntryBlock); 549 for (auto &KV : InitsOrDeInits) 550 IB.CreateCall(KV.first); 551 IB.CreateRetVoid(); 552 553 if (isCtor) 554 PS.registerInitFunc(R.getTargetJITDylib(), InternedInitOrDeInitName); 555 else 556 PS.registerDeInitFunc(R.getTargetJITDylib(), InternedInitOrDeInitName); 557 558 GlobalCOrDtors->eraseFromParent(); 559 return Error::success(); 560 }; 561 562 if (auto Err = RegisterCOrDtors(GlobalCtors, true)) 563 return Err; 564 if (auto Err = RegisterCOrDtors(GlobalDtors, false)) 565 return Err; 566 567 return Error::success(); 568 }); 569 570 if (Err) 571 return std::move(Err); 572 573 return std::move(TSM); 574 } 575 576 /// Inactive Platform Support 577 /// 578 /// Explicitly disables platform support. JITDylibs are not scanned for special 579 /// init/deinit symbols. No runtime API interposes are injected. 580 class InactivePlatformSupport : public LLJIT::PlatformSupport { 581 public: 582 InactivePlatformSupport() = default; 583 584 Error initialize(JITDylib &JD) override { 585 LLVM_DEBUG(dbgs() << "InactivePlatformSupport: no initializers running for " 586 << JD.getName() << "\n"); 587 return Error::success(); 588 } 589 590 Error deinitialize(JITDylib &JD) override { 591 LLVM_DEBUG( 592 dbgs() << "InactivePlatformSupport: no deinitializers running for " 593 << JD.getName() << "\n"); 594 return Error::success(); 595 } 596 }; 597 598 } // end anonymous namespace 599 600 namespace llvm { 601 namespace orc { 602 603 void LLJIT::PlatformSupport::setInitTransform( 604 LLJIT &J, IRTransformLayer::TransformFunction T) { 605 J.InitHelperTransformLayer->setTransform(std::move(T)); 606 } 607 608 LLJIT::PlatformSupport::~PlatformSupport() = default; 609 610 Error LLJITBuilderState::prepareForConstruction() { 611 612 LLVM_DEBUG(dbgs() << "Preparing to create LLJIT instance...\n"); 613 614 if (!JTMB) { 615 LLVM_DEBUG({ 616 dbgs() << " No explicitly set JITTargetMachineBuilder. " 617 "Detecting host...\n"; 618 }); 619 if (auto JTMBOrErr = JITTargetMachineBuilder::detectHost()) 620 JTMB = std::move(*JTMBOrErr); 621 else 622 return JTMBOrErr.takeError(); 623 } 624 625 LLVM_DEBUG({ 626 dbgs() << " JITTargetMachineBuilder is " 627 << JITTargetMachineBuilderPrinter(*JTMB, " ") 628 << " Pre-constructed ExecutionSession: " << (ES ? "Yes" : "No") 629 << "\n" 630 << " DataLayout: "; 631 if (DL) 632 dbgs() << DL->getStringRepresentation() << "\n"; 633 else 634 dbgs() << "None (will be created by JITTargetMachineBuilder)\n"; 635 636 dbgs() << " Custom object-linking-layer creator: " 637 << (CreateObjectLinkingLayer ? "Yes" : "No") << "\n" 638 << " Custom compile-function creator: " 639 << (CreateCompileFunction ? "Yes" : "No") << "\n" 640 << " Custom platform-setup function: " 641 << (SetUpPlatform ? "Yes" : "No") << "\n" 642 << " Number of compile threads: " << NumCompileThreads; 643 if (!NumCompileThreads) 644 dbgs() << " (code will be compiled on the execution thread)\n"; 645 else 646 dbgs() << "\n"; 647 }); 648 649 // If neither ES nor EPC has been set then create an EPC instance. 650 if (!ES && !EPC) { 651 LLVM_DEBUG({ 652 dbgs() << "ExecutorProcessControl not specified, " 653 "Creating SelfExecutorProcessControl instance\n"; 654 }); 655 if (auto EPCOrErr = SelfExecutorProcessControl::Create()) 656 EPC = std::move(*EPCOrErr); 657 else 658 return EPCOrErr.takeError(); 659 } else 660 LLVM_DEBUG({ 661 dbgs() << "Using explicitly specified ExecutorProcessControl instance " 662 << EPC.get() << "\n"; 663 }); 664 665 // If the client didn't configure any linker options then auto-configure the 666 // JIT linker. 667 if (!CreateObjectLinkingLayer) { 668 auto &TT = JTMB->getTargetTriple(); 669 if (TT.isOSBinFormatMachO() && 670 (TT.getArch() == Triple::aarch64 || TT.getArch() == Triple::x86_64)) { 671 672 JTMB->setRelocationModel(Reloc::PIC_); 673 JTMB->setCodeModel(CodeModel::Small); 674 CreateObjectLinkingLayer = 675 [](ExecutionSession &ES, 676 const Triple &) -> Expected<std::unique_ptr<ObjectLayer>> { 677 auto ObjLinkingLayer = std::make_unique<ObjectLinkingLayer>(ES); 678 ObjLinkingLayer->addPlugin(std::make_unique<EHFrameRegistrationPlugin>( 679 ES, std::make_unique<jitlink::InProcessEHFrameRegistrar>())); 680 return std::move(ObjLinkingLayer); 681 }; 682 } 683 } 684 685 return Error::success(); 686 } 687 688 LLJIT::~LLJIT() { 689 if (CompileThreads) 690 CompileThreads->wait(); 691 if (auto Err = ES->endSession()) 692 ES->reportError(std::move(Err)); 693 } 694 695 Error LLJIT::addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM) { 696 assert(TSM && "Can not add null module"); 697 698 if (auto Err = 699 TSM.withModuleDo([&](Module &M) { return applyDataLayout(M); })) 700 return Err; 701 702 return InitHelperTransformLayer->add(std::move(RT), std::move(TSM)); 703 } 704 705 Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) { 706 return addIRModule(JD.getDefaultResourceTracker(), std::move(TSM)); 707 } 708 709 Error LLJIT::addObjectFile(ResourceTrackerSP RT, 710 std::unique_ptr<MemoryBuffer> Obj) { 711 assert(Obj && "Can not add null object"); 712 713 return ObjTransformLayer->add(std::move(RT), std::move(Obj)); 714 } 715 716 Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) { 717 return addObjectFile(JD.getDefaultResourceTracker(), std::move(Obj)); 718 } 719 720 Expected<ExecutorAddr> LLJIT::lookupLinkerMangled(JITDylib &JD, 721 SymbolStringPtr Name) { 722 if (auto Sym = ES->lookup( 723 makeJITDylibSearchOrder(&JD, JITDylibLookupFlags::MatchAllSymbols), 724 Name)) 725 return ExecutorAddr(Sym->getAddress()); 726 else 727 return Sym.takeError(); 728 } 729 730 Expected<std::unique_ptr<ObjectLayer>> 731 LLJIT::createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES) { 732 733 // If the config state provided an ObjectLinkingLayer factory then use it. 734 if (S.CreateObjectLinkingLayer) 735 return S.CreateObjectLinkingLayer(ES, S.JTMB->getTargetTriple()); 736 737 // Otherwise default to creating an RTDyldObjectLinkingLayer that constructs 738 // a new SectionMemoryManager for each object. 739 auto GetMemMgr = []() { return std::make_unique<SectionMemoryManager>(); }; 740 auto Layer = 741 std::make_unique<RTDyldObjectLinkingLayer>(ES, std::move(GetMemMgr)); 742 743 if (S.JTMB->getTargetTriple().isOSBinFormatCOFF()) { 744 Layer->setOverrideObjectFlagsWithResponsibilityFlags(true); 745 Layer->setAutoClaimResponsibilityForObjectSymbols(true); 746 } 747 748 // FIXME: Explicit conversion to std::unique_ptr<ObjectLayer> added to silence 749 // errors from some GCC / libstdc++ bots. Remove this conversion (i.e. 750 // just return ObjLinkingLayer) once those bots are upgraded. 751 return std::unique_ptr<ObjectLayer>(std::move(Layer)); 752 } 753 754 Expected<std::unique_ptr<IRCompileLayer::IRCompiler>> 755 LLJIT::createCompileFunction(LLJITBuilderState &S, 756 JITTargetMachineBuilder JTMB) { 757 758 /// If there is a custom compile function creator set then use it. 759 if (S.CreateCompileFunction) 760 return S.CreateCompileFunction(std::move(JTMB)); 761 762 // Otherwise default to creating a SimpleCompiler, or ConcurrentIRCompiler, 763 // depending on the number of threads requested. 764 if (S.NumCompileThreads > 0) 765 return std::make_unique<ConcurrentIRCompiler>(std::move(JTMB)); 766 767 auto TM = JTMB.createTargetMachine(); 768 if (!TM) 769 return TM.takeError(); 770 771 return std::make_unique<TMOwningSimpleCompiler>(std::move(*TM)); 772 } 773 774 LLJIT::LLJIT(LLJITBuilderState &S, Error &Err) 775 : DL(""), TT(S.JTMB->getTargetTriple()) { 776 777 ErrorAsOutParameter _(&Err); 778 779 assert(!(S.EPC && S.ES) && "EPC and ES should not both be set"); 780 781 if (S.EPC) { 782 ES = std::make_unique<ExecutionSession>(std::move(S.EPC)); 783 } else if (S.ES) 784 ES = std::move(S.ES); 785 else { 786 if (auto EPC = SelfExecutorProcessControl::Create()) { 787 ES = std::make_unique<ExecutionSession>(std::move(*EPC)); 788 } else { 789 Err = EPC.takeError(); 790 return; 791 } 792 } 793 794 if (auto MainOrErr = this->ES->createJITDylib("main")) 795 Main = &*MainOrErr; 796 else { 797 Err = MainOrErr.takeError(); 798 return; 799 } 800 801 if (S.DL) 802 DL = std::move(*S.DL); 803 else if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget()) 804 DL = std::move(*DLOrErr); 805 else { 806 Err = DLOrErr.takeError(); 807 return; 808 } 809 810 auto ObjLayer = createObjectLinkingLayer(S, *ES); 811 if (!ObjLayer) { 812 Err = ObjLayer.takeError(); 813 return; 814 } 815 ObjLinkingLayer = std::move(*ObjLayer); 816 ObjTransformLayer = 817 std::make_unique<ObjectTransformLayer>(*ES, *ObjLinkingLayer); 818 819 { 820 auto CompileFunction = createCompileFunction(S, std::move(*S.JTMB)); 821 if (!CompileFunction) { 822 Err = CompileFunction.takeError(); 823 return; 824 } 825 CompileLayer = std::make_unique<IRCompileLayer>( 826 *ES, *ObjTransformLayer, std::move(*CompileFunction)); 827 TransformLayer = std::make_unique<IRTransformLayer>(*ES, *CompileLayer); 828 InitHelperTransformLayer = 829 std::make_unique<IRTransformLayer>(*ES, *TransformLayer); 830 } 831 832 if (S.NumCompileThreads > 0) { 833 InitHelperTransformLayer->setCloneToNewContextOnEmit(true); 834 CompileThreads = 835 std::make_unique<ThreadPool>(hardware_concurrency(S.NumCompileThreads)); 836 ES->setDispatchTask([this](std::unique_ptr<Task> T) { 837 // FIXME: We should be able to use move-capture here, but ThreadPool's 838 // AsyncTaskTys are std::functions rather than unique_functions 839 // (because MSVC's std::packaged_tasks don't support move-only types). 840 // Fix this when all the above gets sorted out. 841 CompileThreads->async([UnownedT = T.release()]() mutable { 842 std::unique_ptr<Task> T(UnownedT); 843 T->run(); 844 }); 845 }); 846 } 847 848 if (S.SetUpPlatform) 849 Err = S.SetUpPlatform(*this); 850 else 851 setUpGenericLLVMIRPlatform(*this); 852 } 853 854 std::string LLJIT::mangle(StringRef UnmangledName) const { 855 std::string MangledName; 856 { 857 raw_string_ostream MangledNameStream(MangledName); 858 Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL); 859 } 860 return MangledName; 861 } 862 863 Error LLJIT::applyDataLayout(Module &M) { 864 if (M.getDataLayout().isDefault()) 865 M.setDataLayout(DL); 866 867 if (M.getDataLayout() != DL) 868 return make_error<StringError>( 869 "Added modules have incompatible data layouts: " + 870 M.getDataLayout().getStringRepresentation() + " (module) vs " + 871 DL.getStringRepresentation() + " (jit)", 872 inconvertibleErrorCode()); 873 874 return Error::success(); 875 } 876 877 void setUpGenericLLVMIRPlatform(LLJIT &J) { 878 LLVM_DEBUG( 879 { dbgs() << "Setting up GenericLLVMIRPlatform support for LLJIT\n"; }); 880 J.setPlatformSupport(std::make_unique<GenericLLVMIRPlatformSupport>(J)); 881 } 882 883 Error setUpInactivePlatform(LLJIT &J) { 884 LLVM_DEBUG( 885 { dbgs() << "Explicitly deactivated platform support for LLJIT\n"; }); 886 J.setPlatformSupport(std::make_unique<InactivePlatformSupport>()); 887 return Error::success(); 888 } 889 890 Error LLLazyJITBuilderState::prepareForConstruction() { 891 if (auto Err = LLJITBuilderState::prepareForConstruction()) 892 return Err; 893 TT = JTMB->getTargetTriple(); 894 return Error::success(); 895 } 896 897 Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) { 898 assert(TSM && "Can not add null module"); 899 900 if (auto Err = TSM.withModuleDo( 901 [&](Module &M) -> Error { return applyDataLayout(M); })) 902 return Err; 903 904 return CODLayer->add(JD, std::move(TSM)); 905 } 906 907 LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) { 908 909 // If LLJIT construction failed then bail out. 910 if (Err) 911 return; 912 913 ErrorAsOutParameter _(&Err); 914 915 /// Take/Create the lazy-compile callthrough manager. 916 if (S.LCTMgr) 917 LCTMgr = std::move(S.LCTMgr); 918 else { 919 if (auto LCTMgrOrErr = createLocalLazyCallThroughManager( 920 S.TT, *ES, S.LazyCompileFailureAddr.getValue())) 921 LCTMgr = std::move(*LCTMgrOrErr); 922 else { 923 Err = LCTMgrOrErr.takeError(); 924 return; 925 } 926 } 927 928 // Take/Create the indirect stubs manager builder. 929 auto ISMBuilder = std::move(S.ISMBuilder); 930 931 // If none was provided, try to build one. 932 if (!ISMBuilder) 933 ISMBuilder = createLocalIndirectStubsManagerBuilder(S.TT); 934 935 // No luck. Bail out. 936 if (!ISMBuilder) { 937 Err = make_error<StringError>("Could not construct " 938 "IndirectStubsManagerBuilder for target " + 939 S.TT.str(), 940 inconvertibleErrorCode()); 941 return; 942 } 943 944 // Create the COD layer. 945 CODLayer = std::make_unique<CompileOnDemandLayer>( 946 *ES, *InitHelperTransformLayer, *LCTMgr, std::move(ISMBuilder)); 947 948 if (S.NumCompileThreads > 0) 949 CODLayer->setCloneToNewContextOnEmit(true); 950 } 951 952 } // End namespace orc. 953 } // End namespace llvm. 954