10b57cec5SDimitry Andric //===--------- LLJIT.cpp - An ORC-based JIT for compiling LLVM IR ---------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/ExecutionEngine/Orc/LLJIT.h" 105ffd83dbSDimitry Andric #include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h" 11480093f4SDimitry Andric #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h" 1206c3fb27SDimitry Andric #include "llvm/ExecutionEngine/Orc/COFFPlatform.h" 1306c3fb27SDimitry Andric #include "llvm/ExecutionEngine/Orc/ELFNixPlatform.h" 1406c3fb27SDimitry Andric #include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h" 15bdd1243dSDimitry Andric #include "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h" 16fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h" 175ffd83dbSDimitry Andric #include "llvm/ExecutionEngine/Orc/MachOPlatform.h" 18480093f4SDimitry Andric #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" 19e8d8bef9SDimitry Andric #include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h" 200b57cec5SDimitry Andric #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" 21e8d8bef9SDimitry Andric #include "llvm/ExecutionEngine/Orc/Shared/OrcError.h" 22bdd1243dSDimitry Andric #include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h" 230b57cec5SDimitry Andric #include "llvm/ExecutionEngine/SectionMemoryManager.h" 245ffd83dbSDimitry Andric #include "llvm/IR/GlobalVariable.h" 255ffd83dbSDimitry Andric #include "llvm/IR/IRBuilder.h" 260b57cec5SDimitry Andric #include "llvm/IR/Mangler.h" 275ffd83dbSDimitry Andric #include "llvm/IR/Module.h" 285ffd83dbSDimitry Andric #include "llvm/Support/DynamicLibrary.h" 295ffd83dbSDimitry Andric 305ffd83dbSDimitry Andric #define DEBUG_TYPE "orc" 315ffd83dbSDimitry Andric 325ffd83dbSDimitry Andric using namespace llvm; 335ffd83dbSDimitry Andric using namespace llvm::orc; 345ffd83dbSDimitry Andric 355ffd83dbSDimitry Andric namespace { 365ffd83dbSDimitry Andric 375ffd83dbSDimitry Andric /// Adds helper function decls and wrapper functions that call the helper with 385ffd83dbSDimitry Andric /// some additional prefix arguments. 395ffd83dbSDimitry Andric /// 405ffd83dbSDimitry Andric /// E.g. For wrapper "foo" with type i8(i8, i64), helper "bar", and prefix 415ffd83dbSDimitry Andric /// args i32 4 and i16 12345, this function will add: 425ffd83dbSDimitry Andric /// 435ffd83dbSDimitry Andric /// declare i8 @bar(i32, i16, i8, i64) 445ffd83dbSDimitry Andric /// 455ffd83dbSDimitry Andric /// define i8 @foo(i8, i64) { 465ffd83dbSDimitry Andric /// entry: 475ffd83dbSDimitry Andric /// %2 = call i8 @bar(i32 4, i16 12345, i8 %0, i64 %1) 485ffd83dbSDimitry Andric /// ret i8 %2 495ffd83dbSDimitry Andric /// } 505ffd83dbSDimitry Andric /// 515ffd83dbSDimitry Andric Function *addHelperAndWrapper(Module &M, StringRef WrapperName, 525ffd83dbSDimitry Andric FunctionType *WrapperFnType, 535ffd83dbSDimitry Andric GlobalValue::VisibilityTypes WrapperVisibility, 545ffd83dbSDimitry Andric StringRef HelperName, 555ffd83dbSDimitry Andric ArrayRef<Value *> HelperPrefixArgs) { 565ffd83dbSDimitry Andric std::vector<Type *> HelperArgTypes; 575ffd83dbSDimitry Andric for (auto *Arg : HelperPrefixArgs) 585ffd83dbSDimitry Andric HelperArgTypes.push_back(Arg->getType()); 595ffd83dbSDimitry Andric for (auto *T : WrapperFnType->params()) 605ffd83dbSDimitry Andric HelperArgTypes.push_back(T); 615ffd83dbSDimitry Andric auto *HelperFnType = 625ffd83dbSDimitry Andric FunctionType::get(WrapperFnType->getReturnType(), HelperArgTypes, false); 635ffd83dbSDimitry Andric auto *HelperFn = Function::Create(HelperFnType, GlobalValue::ExternalLinkage, 645ffd83dbSDimitry Andric HelperName, M); 655ffd83dbSDimitry Andric 665ffd83dbSDimitry Andric auto *WrapperFn = Function::Create( 675ffd83dbSDimitry Andric WrapperFnType, GlobalValue::ExternalLinkage, WrapperName, M); 685ffd83dbSDimitry Andric WrapperFn->setVisibility(WrapperVisibility); 695ffd83dbSDimitry Andric 705ffd83dbSDimitry Andric auto *EntryBlock = BasicBlock::Create(M.getContext(), "entry", WrapperFn); 715ffd83dbSDimitry Andric IRBuilder<> IB(EntryBlock); 725ffd83dbSDimitry Andric 735ffd83dbSDimitry Andric std::vector<Value *> HelperArgs; 745ffd83dbSDimitry Andric for (auto *Arg : HelperPrefixArgs) 755ffd83dbSDimitry Andric HelperArgs.push_back(Arg); 765ffd83dbSDimitry Andric for (auto &Arg : WrapperFn->args()) 775ffd83dbSDimitry Andric HelperArgs.push_back(&Arg); 785ffd83dbSDimitry Andric auto *HelperResult = IB.CreateCall(HelperFn, HelperArgs); 795ffd83dbSDimitry Andric if (HelperFn->getReturnType()->isVoidTy()) 805ffd83dbSDimitry Andric IB.CreateRetVoid(); 815ffd83dbSDimitry Andric else 825ffd83dbSDimitry Andric IB.CreateRet(HelperResult); 835ffd83dbSDimitry Andric 845ffd83dbSDimitry Andric return WrapperFn; 855ffd83dbSDimitry Andric } 865ffd83dbSDimitry Andric 875ffd83dbSDimitry Andric class GenericLLVMIRPlatformSupport; 885ffd83dbSDimitry Andric 895ffd83dbSDimitry Andric /// orc::Platform component of Generic LLVM IR Platform support. 905ffd83dbSDimitry Andric /// Just forwards calls to the GenericLLVMIRPlatformSupport class below. 915ffd83dbSDimitry Andric class GenericLLVMIRPlatform : public Platform { 925ffd83dbSDimitry Andric public: 935ffd83dbSDimitry Andric GenericLLVMIRPlatform(GenericLLVMIRPlatformSupport &S) : S(S) {} 945ffd83dbSDimitry Andric Error setupJITDylib(JITDylib &JD) override; 9504eeddc0SDimitry Andric Error teardownJITDylib(JITDylib &JD) override; 96e8d8bef9SDimitry Andric Error notifyAdding(ResourceTracker &RT, 97e8d8bef9SDimitry Andric const MaterializationUnit &MU) override; 98e8d8bef9SDimitry Andric Error notifyRemoving(ResourceTracker &RT) override { 995ffd83dbSDimitry Andric // Noop -- Nothing to do (yet). 1005ffd83dbSDimitry Andric return Error::success(); 1015ffd83dbSDimitry Andric } 1025ffd83dbSDimitry Andric 1035ffd83dbSDimitry Andric private: 1045ffd83dbSDimitry Andric GenericLLVMIRPlatformSupport &S; 1055ffd83dbSDimitry Andric }; 1065ffd83dbSDimitry Andric 1075ffd83dbSDimitry Andric /// This transform parses llvm.global_ctors to produce a single initialization 1085ffd83dbSDimitry Andric /// function for the module, records the function, then deletes 1095ffd83dbSDimitry Andric /// llvm.global_ctors. 1105ffd83dbSDimitry Andric class GlobalCtorDtorScraper { 1115ffd83dbSDimitry Andric public: 1125ffd83dbSDimitry Andric GlobalCtorDtorScraper(GenericLLVMIRPlatformSupport &PS, 113349cc55cSDimitry Andric StringRef InitFunctionPrefix, 114349cc55cSDimitry Andric StringRef DeInitFunctionPrefix) 115349cc55cSDimitry Andric : PS(PS), InitFunctionPrefix(InitFunctionPrefix), 116349cc55cSDimitry Andric DeInitFunctionPrefix(DeInitFunctionPrefix) {} 1175ffd83dbSDimitry Andric Expected<ThreadSafeModule> operator()(ThreadSafeModule TSM, 1185ffd83dbSDimitry Andric MaterializationResponsibility &R); 1195ffd83dbSDimitry Andric 1205ffd83dbSDimitry Andric private: 1215ffd83dbSDimitry Andric GenericLLVMIRPlatformSupport &PS; 1225ffd83dbSDimitry Andric StringRef InitFunctionPrefix; 123349cc55cSDimitry Andric StringRef DeInitFunctionPrefix; 1245ffd83dbSDimitry Andric }; 1255ffd83dbSDimitry Andric 1265ffd83dbSDimitry Andric /// Generic IR Platform Support 1275ffd83dbSDimitry Andric /// 1285ffd83dbSDimitry Andric /// Scrapes llvm.global_ctors and llvm.global_dtors and replaces them with 1295ffd83dbSDimitry Andric /// specially named 'init' and 'deinit'. Injects definitions / interposes for 1305ffd83dbSDimitry Andric /// some runtime API, including __cxa_atexit, dlopen, and dlclose. 1315ffd83dbSDimitry Andric class GenericLLVMIRPlatformSupport : public LLJIT::PlatformSupport { 1325ffd83dbSDimitry Andric public: 13306c3fb27SDimitry Andric GenericLLVMIRPlatformSupport(LLJIT &J, JITDylib &PlatformJD) 134349cc55cSDimitry Andric : J(J), InitFunctionPrefix(J.mangle("__orc_init_func.")), 135349cc55cSDimitry Andric DeInitFunctionPrefix(J.mangle("__orc_deinit_func.")) { 1365ffd83dbSDimitry Andric 1375ffd83dbSDimitry Andric getExecutionSession().setPlatform( 1385ffd83dbSDimitry Andric std::make_unique<GenericLLVMIRPlatform>(*this)); 1395ffd83dbSDimitry Andric 140349cc55cSDimitry Andric setInitTransform(J, GlobalCtorDtorScraper(*this, InitFunctionPrefix, 141349cc55cSDimitry Andric DeInitFunctionPrefix)); 1425ffd83dbSDimitry Andric 1435ffd83dbSDimitry Andric SymbolMap StdInterposes; 1445ffd83dbSDimitry Andric 14506c3fb27SDimitry Andric StdInterposes[J.mangleAndIntern("__lljit.platform_support_instance")] = { 14606c3fb27SDimitry Andric ExecutorAddr::fromPtr(this), JITSymbolFlags::Exported}; 14706c3fb27SDimitry Andric StdInterposes[J.mangleAndIntern("__lljit.cxa_atexit_helper")] = { 14806c3fb27SDimitry Andric ExecutorAddr::fromPtr(registerCxaAtExitHelper), JITSymbolFlags()}; 1495ffd83dbSDimitry Andric 15006c3fb27SDimitry Andric cantFail(PlatformJD.define(absoluteSymbols(std::move(StdInterposes)))); 15106c3fb27SDimitry Andric cantFail(setupJITDylib(PlatformJD)); 15206c3fb27SDimitry Andric cantFail(J.addIRModule(PlatformJD, createPlatformRuntimeModule())); 1535ffd83dbSDimitry Andric } 1545ffd83dbSDimitry Andric 1555ffd83dbSDimitry Andric ExecutionSession &getExecutionSession() { return J.getExecutionSession(); } 1565ffd83dbSDimitry Andric 1575ffd83dbSDimitry Andric /// Adds a module that defines the __dso_handle global. 1585ffd83dbSDimitry Andric Error setupJITDylib(JITDylib &JD) { 1595ffd83dbSDimitry Andric 1605ffd83dbSDimitry Andric // Add per-jitdylib standard interposes. 1615ffd83dbSDimitry Andric SymbolMap PerJDInterposes; 16206c3fb27SDimitry Andric PerJDInterposes[J.mangleAndIntern("__lljit.run_atexits_helper")] = { 16306c3fb27SDimitry Andric ExecutorAddr::fromPtr(runAtExitsHelper), JITSymbolFlags()}; 16406c3fb27SDimitry Andric PerJDInterposes[J.mangleAndIntern("__lljit.atexit_helper")] = { 16506c3fb27SDimitry Andric ExecutorAddr::fromPtr(registerAtExitHelper), JITSymbolFlags()}; 1665ffd83dbSDimitry Andric cantFail(JD.define(absoluteSymbols(std::move(PerJDInterposes)))); 1675ffd83dbSDimitry Andric 1685ffd83dbSDimitry Andric auto Ctx = std::make_unique<LLVMContext>(); 1695ffd83dbSDimitry Andric auto M = std::make_unique<Module>("__standard_lib", *Ctx); 1705ffd83dbSDimitry Andric M->setDataLayout(J.getDataLayout()); 1715ffd83dbSDimitry Andric 1725ffd83dbSDimitry Andric auto *Int64Ty = Type::getInt64Ty(*Ctx); 1735ffd83dbSDimitry Andric auto *DSOHandle = new GlobalVariable( 1745ffd83dbSDimitry Andric *M, Int64Ty, true, GlobalValue::ExternalLinkage, 1755ffd83dbSDimitry Andric ConstantInt::get(Int64Ty, reinterpret_cast<uintptr_t>(&JD)), 1765ffd83dbSDimitry Andric "__dso_handle"); 1775ffd83dbSDimitry Andric DSOHandle->setVisibility(GlobalValue::DefaultVisibility); 1785ffd83dbSDimitry Andric DSOHandle->setInitializer( 17906c3fb27SDimitry Andric ConstantInt::get(Int64Ty, ExecutorAddr::fromPtr(&JD).getValue())); 1805ffd83dbSDimitry Andric 1815ffd83dbSDimitry Andric auto *GenericIRPlatformSupportTy = 1825ffd83dbSDimitry Andric StructType::create(*Ctx, "lljit.GenericLLJITIRPlatformSupport"); 1835ffd83dbSDimitry Andric 1845ffd83dbSDimitry Andric auto *PlatformInstanceDecl = new GlobalVariable( 1855ffd83dbSDimitry Andric *M, GenericIRPlatformSupportTy, true, GlobalValue::ExternalLinkage, 1865ffd83dbSDimitry Andric nullptr, "__lljit.platform_support_instance"); 1875ffd83dbSDimitry Andric 1885ffd83dbSDimitry Andric auto *VoidTy = Type::getVoidTy(*Ctx); 1895ffd83dbSDimitry Andric addHelperAndWrapper( 1905ffd83dbSDimitry Andric *M, "__lljit_run_atexits", FunctionType::get(VoidTy, {}, false), 1915ffd83dbSDimitry Andric GlobalValue::HiddenVisibility, "__lljit.run_atexits_helper", 1925ffd83dbSDimitry Andric {PlatformInstanceDecl, DSOHandle}); 1935ffd83dbSDimitry Andric 19481ad6265SDimitry Andric auto *IntTy = Type::getIntNTy(*Ctx, sizeof(int) * CHAR_BIT); 19581ad6265SDimitry Andric auto *AtExitCallbackTy = FunctionType::get(VoidTy, {}, false); 19681ad6265SDimitry Andric auto *AtExitCallbackPtrTy = PointerType::getUnqual(AtExitCallbackTy); 19781ad6265SDimitry Andric addHelperAndWrapper(*M, "atexit", 19881ad6265SDimitry Andric FunctionType::get(IntTy, {AtExitCallbackPtrTy}, false), 19981ad6265SDimitry Andric GlobalValue::HiddenVisibility, "__lljit.atexit_helper", 20081ad6265SDimitry Andric {PlatformInstanceDecl, DSOHandle}); 20181ad6265SDimitry Andric 2025ffd83dbSDimitry Andric return J.addIRModule(JD, ThreadSafeModule(std::move(M), std::move(Ctx))); 2035ffd83dbSDimitry Andric } 2045ffd83dbSDimitry Andric 205e8d8bef9SDimitry Andric Error notifyAdding(ResourceTracker &RT, const MaterializationUnit &MU) { 206e8d8bef9SDimitry Andric auto &JD = RT.getJITDylib(); 2075ffd83dbSDimitry Andric if (auto &InitSym = MU.getInitializerSymbol()) 2085ffd83dbSDimitry Andric InitSymbols[&JD].add(InitSym, SymbolLookupFlags::WeaklyReferencedSymbol); 2095ffd83dbSDimitry Andric else { 2105ffd83dbSDimitry Andric // If there's no identified init symbol attached, but there is a symbol 2115ffd83dbSDimitry Andric // with the GenericIRPlatform::InitFunctionPrefix, then treat that as 2125ffd83dbSDimitry Andric // an init function. Add the symbol to both the InitSymbols map (which 2135ffd83dbSDimitry Andric // will trigger a lookup to materialize the module) and the InitFunctions 2145ffd83dbSDimitry Andric // map (which holds the names of the symbols to execute). 2155ffd83dbSDimitry Andric for (auto &KV : MU.getSymbols()) 2165f757f3fSDimitry Andric if ((*KV.first).starts_with(InitFunctionPrefix)) { 2175ffd83dbSDimitry Andric InitSymbols[&JD].add(KV.first, 2185ffd83dbSDimitry Andric SymbolLookupFlags::WeaklyReferencedSymbol); 2195ffd83dbSDimitry Andric InitFunctions[&JD].add(KV.first); 2205f757f3fSDimitry Andric } else if ((*KV.first).starts_with(DeInitFunctionPrefix)) { 221349cc55cSDimitry Andric DeInitFunctions[&JD].add(KV.first); 2225ffd83dbSDimitry Andric } 2235ffd83dbSDimitry Andric } 2245ffd83dbSDimitry Andric return Error::success(); 2255ffd83dbSDimitry Andric } 2265ffd83dbSDimitry Andric 2275ffd83dbSDimitry Andric Error initialize(JITDylib &JD) override { 2285ffd83dbSDimitry Andric LLVM_DEBUG({ 2295ffd83dbSDimitry Andric dbgs() << "GenericLLVMIRPlatformSupport getting initializers to run\n"; 2305ffd83dbSDimitry Andric }); 2315ffd83dbSDimitry Andric if (auto Initializers = getInitializers(JD)) { 2325ffd83dbSDimitry Andric LLVM_DEBUG( 2335ffd83dbSDimitry Andric { dbgs() << "GenericLLVMIRPlatformSupport running initializers\n"; }); 2345ffd83dbSDimitry Andric for (auto InitFnAddr : *Initializers) { 2355ffd83dbSDimitry Andric LLVM_DEBUG({ 2365ffd83dbSDimitry Andric dbgs() << " Running init " << formatv("{0:x16}", InitFnAddr) 2375ffd83dbSDimitry Andric << "...\n"; 2385ffd83dbSDimitry Andric }); 23906c3fb27SDimitry Andric auto *InitFn = InitFnAddr.toPtr<void (*)()>(); 2405ffd83dbSDimitry Andric InitFn(); 2415ffd83dbSDimitry Andric } 2425ffd83dbSDimitry Andric } else 2435ffd83dbSDimitry Andric return Initializers.takeError(); 2445ffd83dbSDimitry Andric return Error::success(); 2455ffd83dbSDimitry Andric } 2465ffd83dbSDimitry Andric 2475ffd83dbSDimitry Andric Error deinitialize(JITDylib &JD) override { 2485ffd83dbSDimitry Andric LLVM_DEBUG({ 2495ffd83dbSDimitry Andric dbgs() << "GenericLLVMIRPlatformSupport getting deinitializers to run\n"; 2505ffd83dbSDimitry Andric }); 2515ffd83dbSDimitry Andric if (auto Deinitializers = getDeinitializers(JD)) { 2525ffd83dbSDimitry Andric LLVM_DEBUG({ 2535ffd83dbSDimitry Andric dbgs() << "GenericLLVMIRPlatformSupport running deinitializers\n"; 2545ffd83dbSDimitry Andric }); 2555ffd83dbSDimitry Andric for (auto DeinitFnAddr : *Deinitializers) { 2565ffd83dbSDimitry Andric LLVM_DEBUG({ 257e8d8bef9SDimitry Andric dbgs() << " Running deinit " << formatv("{0:x16}", DeinitFnAddr) 2585ffd83dbSDimitry Andric << "...\n"; 2595ffd83dbSDimitry Andric }); 26006c3fb27SDimitry Andric auto *DeinitFn = DeinitFnAddr.toPtr<void (*)()>(); 2615ffd83dbSDimitry Andric DeinitFn(); 2625ffd83dbSDimitry Andric } 2635ffd83dbSDimitry Andric } else 2645ffd83dbSDimitry Andric return Deinitializers.takeError(); 2655ffd83dbSDimitry Andric 2665ffd83dbSDimitry Andric return Error::success(); 2675ffd83dbSDimitry Andric } 2685ffd83dbSDimitry Andric 2695ffd83dbSDimitry Andric void registerInitFunc(JITDylib &JD, SymbolStringPtr InitName) { 2705ffd83dbSDimitry Andric getExecutionSession().runSessionLocked([&]() { 2715ffd83dbSDimitry Andric InitFunctions[&JD].add(InitName); 2725ffd83dbSDimitry Andric }); 2735ffd83dbSDimitry Andric } 2745ffd83dbSDimitry Andric 275349cc55cSDimitry Andric void registerDeInitFunc(JITDylib &JD, SymbolStringPtr DeInitName) { 276349cc55cSDimitry Andric getExecutionSession().runSessionLocked( 277349cc55cSDimitry Andric [&]() { DeInitFunctions[&JD].add(DeInitName); }); 278349cc55cSDimitry Andric } 279349cc55cSDimitry Andric 2805ffd83dbSDimitry Andric private: 28106c3fb27SDimitry Andric Expected<std::vector<ExecutorAddr>> getInitializers(JITDylib &JD) { 2825ffd83dbSDimitry Andric if (auto Err = issueInitLookups(JD)) 2835ffd83dbSDimitry Andric return std::move(Err); 2845ffd83dbSDimitry Andric 2855ffd83dbSDimitry Andric DenseMap<JITDylib *, SymbolLookupSet> LookupSymbols; 286e8d8bef9SDimitry Andric std::vector<JITDylibSP> DFSLinkOrder; 2875ffd83dbSDimitry Andric 28804eeddc0SDimitry Andric if (auto Err = getExecutionSession().runSessionLocked([&]() -> Error { 28904eeddc0SDimitry Andric if (auto DFSLinkOrderOrErr = JD.getDFSLinkOrder()) 29004eeddc0SDimitry Andric DFSLinkOrder = std::move(*DFSLinkOrderOrErr); 29104eeddc0SDimitry Andric else 29204eeddc0SDimitry Andric return DFSLinkOrderOrErr.takeError(); 2935ffd83dbSDimitry Andric 294e8d8bef9SDimitry Andric for (auto &NextJD : DFSLinkOrder) { 295e8d8bef9SDimitry Andric auto IFItr = InitFunctions.find(NextJD.get()); 2965ffd83dbSDimitry Andric if (IFItr != InitFunctions.end()) { 297e8d8bef9SDimitry Andric LookupSymbols[NextJD.get()] = std::move(IFItr->second); 2985ffd83dbSDimitry Andric InitFunctions.erase(IFItr); 2995ffd83dbSDimitry Andric } 3005ffd83dbSDimitry Andric } 30104eeddc0SDimitry Andric return Error::success(); 30204eeddc0SDimitry Andric })) 30304eeddc0SDimitry Andric return std::move(Err); 3045ffd83dbSDimitry Andric 3055ffd83dbSDimitry Andric LLVM_DEBUG({ 3065ffd83dbSDimitry Andric dbgs() << "JITDylib init order is [ "; 307e8d8bef9SDimitry Andric for (auto &JD : llvm::reverse(DFSLinkOrder)) 3085ffd83dbSDimitry Andric dbgs() << "\"" << JD->getName() << "\" "; 3095ffd83dbSDimitry Andric dbgs() << "]\n"; 3105ffd83dbSDimitry Andric dbgs() << "Looking up init functions:\n"; 3115ffd83dbSDimitry Andric for (auto &KV : LookupSymbols) 3125ffd83dbSDimitry Andric dbgs() << " \"" << KV.first->getName() << "\": " << KV.second << "\n"; 3135ffd83dbSDimitry Andric }); 3145ffd83dbSDimitry Andric 3155ffd83dbSDimitry Andric auto &ES = getExecutionSession(); 3165ffd83dbSDimitry Andric auto LookupResult = Platform::lookupInitSymbols(ES, LookupSymbols); 3175ffd83dbSDimitry Andric 3185ffd83dbSDimitry Andric if (!LookupResult) 3195ffd83dbSDimitry Andric return LookupResult.takeError(); 3205ffd83dbSDimitry Andric 32106c3fb27SDimitry Andric std::vector<ExecutorAddr> Initializers; 3225ffd83dbSDimitry Andric while (!DFSLinkOrder.empty()) { 3235ffd83dbSDimitry Andric auto &NextJD = *DFSLinkOrder.back(); 3245ffd83dbSDimitry Andric DFSLinkOrder.pop_back(); 3255ffd83dbSDimitry Andric auto InitsItr = LookupResult->find(&NextJD); 3265ffd83dbSDimitry Andric if (InitsItr == LookupResult->end()) 3275ffd83dbSDimitry Andric continue; 3285ffd83dbSDimitry Andric for (auto &KV : InitsItr->second) 3295ffd83dbSDimitry Andric Initializers.push_back(KV.second.getAddress()); 3305ffd83dbSDimitry Andric } 3315ffd83dbSDimitry Andric 3325ffd83dbSDimitry Andric return Initializers; 3335ffd83dbSDimitry Andric } 3345ffd83dbSDimitry Andric 33506c3fb27SDimitry Andric Expected<std::vector<ExecutorAddr>> getDeinitializers(JITDylib &JD) { 3365ffd83dbSDimitry Andric auto &ES = getExecutionSession(); 3375ffd83dbSDimitry Andric 3385ffd83dbSDimitry Andric auto LLJITRunAtExits = J.mangleAndIntern("__lljit_run_atexits"); 3395ffd83dbSDimitry Andric 3405ffd83dbSDimitry Andric DenseMap<JITDylib *, SymbolLookupSet> LookupSymbols; 341e8d8bef9SDimitry Andric std::vector<JITDylibSP> DFSLinkOrder; 3425ffd83dbSDimitry Andric 34304eeddc0SDimitry Andric if (auto Err = ES.runSessionLocked([&]() -> Error { 34404eeddc0SDimitry Andric if (auto DFSLinkOrderOrErr = JD.getDFSLinkOrder()) 34504eeddc0SDimitry Andric DFSLinkOrder = std::move(*DFSLinkOrderOrErr); 34604eeddc0SDimitry Andric else 34704eeddc0SDimitry Andric return DFSLinkOrderOrErr.takeError(); 3485ffd83dbSDimitry Andric 349e8d8bef9SDimitry Andric for (auto &NextJD : DFSLinkOrder) { 350e8d8bef9SDimitry Andric auto &JDLookupSymbols = LookupSymbols[NextJD.get()]; 351e8d8bef9SDimitry Andric auto DIFItr = DeInitFunctions.find(NextJD.get()); 3525ffd83dbSDimitry Andric if (DIFItr != DeInitFunctions.end()) { 353e8d8bef9SDimitry Andric LookupSymbols[NextJD.get()] = std::move(DIFItr->second); 3545ffd83dbSDimitry Andric DeInitFunctions.erase(DIFItr); 3555ffd83dbSDimitry Andric } 3565ffd83dbSDimitry Andric JDLookupSymbols.add(LLJITRunAtExits, 3575ffd83dbSDimitry Andric SymbolLookupFlags::WeaklyReferencedSymbol); 3585ffd83dbSDimitry Andric } 35904eeddc0SDimitry Andric return Error::success(); 36004eeddc0SDimitry Andric })) 36104eeddc0SDimitry Andric return std::move(Err); 3625ffd83dbSDimitry Andric 3635ffd83dbSDimitry Andric LLVM_DEBUG({ 3645ffd83dbSDimitry Andric dbgs() << "JITDylib deinit order is [ "; 365e8d8bef9SDimitry Andric for (auto &JD : DFSLinkOrder) 3665ffd83dbSDimitry Andric dbgs() << "\"" << JD->getName() << "\" "; 3675ffd83dbSDimitry Andric dbgs() << "]\n"; 3685ffd83dbSDimitry Andric dbgs() << "Looking up deinit functions:\n"; 3695ffd83dbSDimitry Andric for (auto &KV : LookupSymbols) 3705ffd83dbSDimitry Andric dbgs() << " \"" << KV.first->getName() << "\": " << KV.second << "\n"; 3715ffd83dbSDimitry Andric }); 3725ffd83dbSDimitry Andric 3735ffd83dbSDimitry Andric auto LookupResult = Platform::lookupInitSymbols(ES, LookupSymbols); 3745ffd83dbSDimitry Andric 3755ffd83dbSDimitry Andric if (!LookupResult) 3765ffd83dbSDimitry Andric return LookupResult.takeError(); 3775ffd83dbSDimitry Andric 37806c3fb27SDimitry Andric std::vector<ExecutorAddr> DeInitializers; 379e8d8bef9SDimitry Andric for (auto &NextJD : DFSLinkOrder) { 380e8d8bef9SDimitry Andric auto DeInitsItr = LookupResult->find(NextJD.get()); 3815ffd83dbSDimitry Andric assert(DeInitsItr != LookupResult->end() && 3825ffd83dbSDimitry Andric "Every JD should have at least __lljit_run_atexits"); 3835ffd83dbSDimitry Andric 3845ffd83dbSDimitry Andric auto RunAtExitsItr = DeInitsItr->second.find(LLJITRunAtExits); 3855ffd83dbSDimitry Andric if (RunAtExitsItr != DeInitsItr->second.end()) 3865ffd83dbSDimitry Andric DeInitializers.push_back(RunAtExitsItr->second.getAddress()); 3875ffd83dbSDimitry Andric 3885ffd83dbSDimitry Andric for (auto &KV : DeInitsItr->second) 3895ffd83dbSDimitry Andric if (KV.first != LLJITRunAtExits) 3905ffd83dbSDimitry Andric DeInitializers.push_back(KV.second.getAddress()); 3915ffd83dbSDimitry Andric } 3925ffd83dbSDimitry Andric 3935ffd83dbSDimitry Andric return DeInitializers; 3945ffd83dbSDimitry Andric } 3955ffd83dbSDimitry Andric 3965ffd83dbSDimitry Andric /// Issue lookups for all init symbols required to initialize JD (and any 3975ffd83dbSDimitry Andric /// JITDylibs that it depends on). 3985ffd83dbSDimitry Andric Error issueInitLookups(JITDylib &JD) { 3995ffd83dbSDimitry Andric DenseMap<JITDylib *, SymbolLookupSet> RequiredInitSymbols; 400e8d8bef9SDimitry Andric std::vector<JITDylibSP> DFSLinkOrder; 4015ffd83dbSDimitry Andric 40204eeddc0SDimitry Andric if (auto Err = getExecutionSession().runSessionLocked([&]() -> Error { 40304eeddc0SDimitry Andric if (auto DFSLinkOrderOrErr = JD.getDFSLinkOrder()) 40404eeddc0SDimitry Andric DFSLinkOrder = std::move(*DFSLinkOrderOrErr); 40504eeddc0SDimitry Andric else 40604eeddc0SDimitry Andric return DFSLinkOrderOrErr.takeError(); 4075ffd83dbSDimitry Andric 408e8d8bef9SDimitry Andric for (auto &NextJD : DFSLinkOrder) { 409e8d8bef9SDimitry Andric auto ISItr = InitSymbols.find(NextJD.get()); 4105ffd83dbSDimitry Andric if (ISItr != InitSymbols.end()) { 411e8d8bef9SDimitry Andric RequiredInitSymbols[NextJD.get()] = std::move(ISItr->second); 4125ffd83dbSDimitry Andric InitSymbols.erase(ISItr); 4135ffd83dbSDimitry Andric } 4145ffd83dbSDimitry Andric } 41504eeddc0SDimitry Andric return Error::success(); 41604eeddc0SDimitry Andric })) 41704eeddc0SDimitry Andric return Err; 4185ffd83dbSDimitry Andric 4195ffd83dbSDimitry Andric return Platform::lookupInitSymbols(getExecutionSession(), 4205ffd83dbSDimitry Andric RequiredInitSymbols) 4215ffd83dbSDimitry Andric .takeError(); 4225ffd83dbSDimitry Andric } 4235ffd83dbSDimitry Andric 42481ad6265SDimitry Andric static void registerCxaAtExitHelper(void *Self, void (*F)(void *), void *Ctx, 4255ffd83dbSDimitry Andric void *DSOHandle) { 4265ffd83dbSDimitry Andric LLVM_DEBUG({ 42781ad6265SDimitry Andric dbgs() << "Registering cxa atexit function " << (void *)F << " for JD " 42881ad6265SDimitry Andric << (*static_cast<JITDylib **>(DSOHandle))->getName() << "\n"; 42981ad6265SDimitry Andric }); 43081ad6265SDimitry Andric static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.registerAtExit( 43181ad6265SDimitry Andric F, Ctx, DSOHandle); 43281ad6265SDimitry Andric } 43381ad6265SDimitry Andric 43481ad6265SDimitry Andric static void registerAtExitHelper(void *Self, void *DSOHandle, void (*F)()) { 43581ad6265SDimitry Andric LLVM_DEBUG({ 4365ffd83dbSDimitry Andric dbgs() << "Registering atexit function " << (void *)F << " for JD " 4375ffd83dbSDimitry Andric << (*static_cast<JITDylib **>(DSOHandle))->getName() << "\n"; 4385ffd83dbSDimitry Andric }); 4395ffd83dbSDimitry Andric static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.registerAtExit( 44081ad6265SDimitry Andric reinterpret_cast<void (*)(void *)>(F), nullptr, DSOHandle); 4415ffd83dbSDimitry Andric } 4425ffd83dbSDimitry Andric 4435ffd83dbSDimitry Andric static void runAtExitsHelper(void *Self, void *DSOHandle) { 4445ffd83dbSDimitry Andric LLVM_DEBUG({ 4455ffd83dbSDimitry Andric dbgs() << "Running atexit functions for JD " 4465ffd83dbSDimitry Andric << (*static_cast<JITDylib **>(DSOHandle))->getName() << "\n"; 4475ffd83dbSDimitry Andric }); 4485ffd83dbSDimitry Andric static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.runAtExits( 4495ffd83dbSDimitry Andric DSOHandle); 4505ffd83dbSDimitry Andric } 4515ffd83dbSDimitry Andric 4525ffd83dbSDimitry Andric // Constructs an LLVM IR module containing platform runtime globals, 4535ffd83dbSDimitry Andric // functions, and interposes. 4545ffd83dbSDimitry Andric ThreadSafeModule createPlatformRuntimeModule() { 4555ffd83dbSDimitry Andric auto Ctx = std::make_unique<LLVMContext>(); 4565ffd83dbSDimitry Andric auto M = std::make_unique<Module>("__standard_lib", *Ctx); 4575ffd83dbSDimitry Andric M->setDataLayout(J.getDataLayout()); 4585ffd83dbSDimitry Andric 4595ffd83dbSDimitry Andric auto *GenericIRPlatformSupportTy = 4605ffd83dbSDimitry Andric StructType::create(*Ctx, "lljit.GenericLLJITIRPlatformSupport"); 4615ffd83dbSDimitry Andric 4625ffd83dbSDimitry Andric auto *PlatformInstanceDecl = new GlobalVariable( 4635ffd83dbSDimitry Andric *M, GenericIRPlatformSupportTy, true, GlobalValue::ExternalLinkage, 4645ffd83dbSDimitry Andric nullptr, "__lljit.platform_support_instance"); 4655ffd83dbSDimitry Andric 4665ffd83dbSDimitry Andric auto *Int8Ty = Type::getInt8Ty(*Ctx); 4675ffd83dbSDimitry Andric auto *IntTy = Type::getIntNTy(*Ctx, sizeof(int) * CHAR_BIT); 4685ffd83dbSDimitry Andric auto *VoidTy = Type::getVoidTy(*Ctx); 4695ffd83dbSDimitry Andric auto *BytePtrTy = PointerType::getUnqual(Int8Ty); 47081ad6265SDimitry Andric auto *CxaAtExitCallbackTy = FunctionType::get(VoidTy, {BytePtrTy}, false); 47181ad6265SDimitry Andric auto *CxaAtExitCallbackPtrTy = PointerType::getUnqual(CxaAtExitCallbackTy); 4725ffd83dbSDimitry Andric 4735ffd83dbSDimitry Andric addHelperAndWrapper( 4745ffd83dbSDimitry Andric *M, "__cxa_atexit", 47581ad6265SDimitry Andric FunctionType::get(IntTy, {CxaAtExitCallbackPtrTy, BytePtrTy, BytePtrTy}, 4765ffd83dbSDimitry Andric false), 4775ffd83dbSDimitry Andric GlobalValue::DefaultVisibility, "__lljit.cxa_atexit_helper", 4785ffd83dbSDimitry Andric {PlatformInstanceDecl}); 4795ffd83dbSDimitry Andric 4805ffd83dbSDimitry Andric return ThreadSafeModule(std::move(M), std::move(Ctx)); 4815ffd83dbSDimitry Andric } 4825ffd83dbSDimitry Andric 4835ffd83dbSDimitry Andric LLJIT &J; 4845ffd83dbSDimitry Andric std::string InitFunctionPrefix; 485349cc55cSDimitry Andric std::string DeInitFunctionPrefix; 4865ffd83dbSDimitry Andric DenseMap<JITDylib *, SymbolLookupSet> InitSymbols; 4875ffd83dbSDimitry Andric DenseMap<JITDylib *, SymbolLookupSet> InitFunctions; 4885ffd83dbSDimitry Andric DenseMap<JITDylib *, SymbolLookupSet> DeInitFunctions; 4895ffd83dbSDimitry Andric ItaniumCXAAtExitSupport AtExitMgr; 4905ffd83dbSDimitry Andric }; 4915ffd83dbSDimitry Andric 4925ffd83dbSDimitry Andric Error GenericLLVMIRPlatform::setupJITDylib(JITDylib &JD) { 4935ffd83dbSDimitry Andric return S.setupJITDylib(JD); 4945ffd83dbSDimitry Andric } 4955ffd83dbSDimitry Andric 49604eeddc0SDimitry Andric Error GenericLLVMIRPlatform::teardownJITDylib(JITDylib &JD) { 49704eeddc0SDimitry Andric return Error::success(); 49804eeddc0SDimitry Andric } 49904eeddc0SDimitry Andric 500e8d8bef9SDimitry Andric Error GenericLLVMIRPlatform::notifyAdding(ResourceTracker &RT, 5015ffd83dbSDimitry Andric const MaterializationUnit &MU) { 502e8d8bef9SDimitry Andric return S.notifyAdding(RT, MU); 5035ffd83dbSDimitry Andric } 5045ffd83dbSDimitry Andric 5055ffd83dbSDimitry Andric Expected<ThreadSafeModule> 5065ffd83dbSDimitry Andric GlobalCtorDtorScraper::operator()(ThreadSafeModule TSM, 5075ffd83dbSDimitry Andric MaterializationResponsibility &R) { 5085ffd83dbSDimitry Andric auto Err = TSM.withModuleDo([&](Module &M) -> Error { 5095ffd83dbSDimitry Andric auto &Ctx = M.getContext(); 5105ffd83dbSDimitry Andric auto *GlobalCtors = M.getNamedGlobal("llvm.global_ctors"); 511349cc55cSDimitry Andric auto *GlobalDtors = M.getNamedGlobal("llvm.global_dtors"); 5125ffd83dbSDimitry Andric 513349cc55cSDimitry Andric auto RegisterCOrDtors = [&](GlobalVariable *GlobalCOrDtors, 514349cc55cSDimitry Andric bool isCtor) -> Error { 515349cc55cSDimitry Andric // If there's no llvm.global_c/dtor or it's just a decl then skip. 516349cc55cSDimitry Andric if (!GlobalCOrDtors || GlobalCOrDtors->isDeclaration()) 5175ffd83dbSDimitry Andric return Error::success(); 518349cc55cSDimitry Andric std::string InitOrDeInitFunctionName; 519349cc55cSDimitry Andric if (isCtor) 520349cc55cSDimitry Andric raw_string_ostream(InitOrDeInitFunctionName) 5215ffd83dbSDimitry Andric << InitFunctionPrefix << M.getModuleIdentifier(); 522349cc55cSDimitry Andric else 523349cc55cSDimitry Andric raw_string_ostream(InitOrDeInitFunctionName) 524349cc55cSDimitry Andric << DeInitFunctionPrefix << M.getModuleIdentifier(); 5255ffd83dbSDimitry Andric 5265ffd83dbSDimitry Andric MangleAndInterner Mangle(PS.getExecutionSession(), M.getDataLayout()); 527349cc55cSDimitry Andric auto InternedInitOrDeInitName = Mangle(InitOrDeInitFunctionName); 528349cc55cSDimitry Andric if (auto Err = R.defineMaterializing( 529349cc55cSDimitry Andric {{InternedInitOrDeInitName, JITSymbolFlags::Callable}})) 5305ffd83dbSDimitry Andric return Err; 5315ffd83dbSDimitry Andric 532349cc55cSDimitry Andric auto *InitOrDeInitFunc = Function::Create( 533349cc55cSDimitry Andric FunctionType::get(Type::getVoidTy(Ctx), {}, false), 534349cc55cSDimitry Andric GlobalValue::ExternalLinkage, InitOrDeInitFunctionName, &M); 535349cc55cSDimitry Andric InitOrDeInitFunc->setVisibility(GlobalValue::HiddenVisibility); 536349cc55cSDimitry Andric std::vector<std::pair<Function *, unsigned>> InitsOrDeInits; 537349cc55cSDimitry Andric auto COrDtors = isCtor ? getConstructors(M) : getDestructors(M); 538349cc55cSDimitry Andric 539349cc55cSDimitry Andric for (auto E : COrDtors) 540349cc55cSDimitry Andric InitsOrDeInits.push_back(std::make_pair(E.Func, E.Priority)); 541*0fca6ea1SDimitry Andric llvm::stable_sort(InitsOrDeInits, llvm::less_second()); 542349cc55cSDimitry Andric 543349cc55cSDimitry Andric auto *InitOrDeInitFuncEntryBlock = 544349cc55cSDimitry Andric BasicBlock::Create(Ctx, "entry", InitOrDeInitFunc); 545349cc55cSDimitry Andric IRBuilder<> IB(InitOrDeInitFuncEntryBlock); 546349cc55cSDimitry Andric for (auto &KV : InitsOrDeInits) 5475ffd83dbSDimitry Andric IB.CreateCall(KV.first); 5485ffd83dbSDimitry Andric IB.CreateRetVoid(); 5495ffd83dbSDimitry Andric 550349cc55cSDimitry Andric if (isCtor) 551349cc55cSDimitry Andric PS.registerInitFunc(R.getTargetJITDylib(), InternedInitOrDeInitName); 552349cc55cSDimitry Andric else 553349cc55cSDimitry Andric PS.registerDeInitFunc(R.getTargetJITDylib(), InternedInitOrDeInitName); 554349cc55cSDimitry Andric 555349cc55cSDimitry Andric GlobalCOrDtors->eraseFromParent(); 556349cc55cSDimitry Andric return Error::success(); 557349cc55cSDimitry Andric }; 558349cc55cSDimitry Andric 559349cc55cSDimitry Andric if (auto Err = RegisterCOrDtors(GlobalCtors, true)) 560349cc55cSDimitry Andric return Err; 561349cc55cSDimitry Andric if (auto Err = RegisterCOrDtors(GlobalDtors, false)) 562349cc55cSDimitry Andric return Err; 563349cc55cSDimitry Andric 5645ffd83dbSDimitry Andric return Error::success(); 5655ffd83dbSDimitry Andric }); 5665ffd83dbSDimitry Andric 5675ffd83dbSDimitry Andric if (Err) 5685ffd83dbSDimitry Andric return std::move(Err); 5695ffd83dbSDimitry Andric 5705ffd83dbSDimitry Andric return std::move(TSM); 5715ffd83dbSDimitry Andric } 5725ffd83dbSDimitry Andric 573fe6060f1SDimitry Andric /// Inactive Platform Support 574fe6060f1SDimitry Andric /// 575fe6060f1SDimitry Andric /// Explicitly disables platform support. JITDylibs are not scanned for special 576fe6060f1SDimitry Andric /// init/deinit symbols. No runtime API interposes are injected. 577fe6060f1SDimitry Andric class InactivePlatformSupport : public LLJIT::PlatformSupport { 5785ffd83dbSDimitry Andric public: 579fe6060f1SDimitry Andric InactivePlatformSupport() = default; 5805ffd83dbSDimitry Andric 5815ffd83dbSDimitry Andric Error initialize(JITDylib &JD) override { 582fe6060f1SDimitry Andric LLVM_DEBUG(dbgs() << "InactivePlatformSupport: no initializers running for " 583fe6060f1SDimitry Andric << JD.getName() << "\n"); 5845ffd83dbSDimitry Andric return Error::success(); 5855ffd83dbSDimitry Andric } 5865ffd83dbSDimitry Andric 5875ffd83dbSDimitry Andric Error deinitialize(JITDylib &JD) override { 588fe6060f1SDimitry Andric LLVM_DEBUG( 589fe6060f1SDimitry Andric dbgs() << "InactivePlatformSupport: no deinitializers running for " 590fe6060f1SDimitry Andric << JD.getName() << "\n"); 5915ffd83dbSDimitry Andric return Error::success(); 5925ffd83dbSDimitry Andric } 5935ffd83dbSDimitry Andric }; 5945ffd83dbSDimitry Andric 5955ffd83dbSDimitry Andric } // end anonymous namespace 5960b57cec5SDimitry Andric 5970b57cec5SDimitry Andric namespace llvm { 5980b57cec5SDimitry Andric namespace orc { 5990b57cec5SDimitry Andric 6005f757f3fSDimitry Andric Error ORCPlatformSupport::initialize(orc::JITDylib &JD) { 6015f757f3fSDimitry Andric using llvm::orc::shared::SPSExecutorAddr; 6025f757f3fSDimitry Andric using llvm::orc::shared::SPSString; 6035f757f3fSDimitry Andric using SPSDLOpenSig = SPSExecutorAddr(SPSString, int32_t); 6045f757f3fSDimitry Andric enum dlopen_mode : int32_t { 6055f757f3fSDimitry Andric ORC_RT_RTLD_LAZY = 0x1, 6065f757f3fSDimitry Andric ORC_RT_RTLD_NOW = 0x2, 6075f757f3fSDimitry Andric ORC_RT_RTLD_LOCAL = 0x4, 6085f757f3fSDimitry Andric ORC_RT_RTLD_GLOBAL = 0x8 6095f757f3fSDimitry Andric }; 6105f757f3fSDimitry Andric 6115f757f3fSDimitry Andric auto &ES = J.getExecutionSession(); 6125f757f3fSDimitry Andric auto MainSearchOrder = J.getMainJITDylib().withLinkOrderDo( 6135f757f3fSDimitry Andric [](const JITDylibSearchOrder &SO) { return SO; }); 6145f757f3fSDimitry Andric 6155f757f3fSDimitry Andric if (auto WrapperAddr = ES.lookup( 6165f757f3fSDimitry Andric MainSearchOrder, J.mangleAndIntern("__orc_rt_jit_dlopen_wrapper"))) { 6175f757f3fSDimitry Andric return ES.callSPSWrapper<SPSDLOpenSig>(WrapperAddr->getAddress(), 6185f757f3fSDimitry Andric DSOHandles[&JD], JD.getName(), 6195f757f3fSDimitry Andric int32_t(ORC_RT_RTLD_LAZY)); 6205f757f3fSDimitry Andric } else 6215f757f3fSDimitry Andric return WrapperAddr.takeError(); 6225f757f3fSDimitry Andric } 6235f757f3fSDimitry Andric 6245f757f3fSDimitry Andric Error ORCPlatformSupport::deinitialize(orc::JITDylib &JD) { 6255f757f3fSDimitry Andric using llvm::orc::shared::SPSExecutorAddr; 6265f757f3fSDimitry Andric using SPSDLCloseSig = int32_t(SPSExecutorAddr); 6275f757f3fSDimitry Andric 6285f757f3fSDimitry Andric auto &ES = J.getExecutionSession(); 6295f757f3fSDimitry Andric auto MainSearchOrder = J.getMainJITDylib().withLinkOrderDo( 6305f757f3fSDimitry Andric [](const JITDylibSearchOrder &SO) { return SO; }); 6315f757f3fSDimitry Andric 6325f757f3fSDimitry Andric if (auto WrapperAddr = ES.lookup( 6335f757f3fSDimitry Andric MainSearchOrder, J.mangleAndIntern("__orc_rt_jit_dlclose_wrapper"))) { 6345f757f3fSDimitry Andric int32_t result; 6355f757f3fSDimitry Andric auto E = J.getExecutionSession().callSPSWrapper<SPSDLCloseSig>( 6365f757f3fSDimitry Andric WrapperAddr->getAddress(), result, DSOHandles[&JD]); 6375f757f3fSDimitry Andric if (E) 6385f757f3fSDimitry Andric return E; 6395f757f3fSDimitry Andric else if (result) 6405f757f3fSDimitry Andric return make_error<StringError>("dlclose failed", 6415f757f3fSDimitry Andric inconvertibleErrorCode()); 6425f757f3fSDimitry Andric DSOHandles.erase(&JD); 6435f757f3fSDimitry Andric } else 6445f757f3fSDimitry Andric return WrapperAddr.takeError(); 6455f757f3fSDimitry Andric return Error::success(); 6465f757f3fSDimitry Andric } 6475f757f3fSDimitry Andric 6485ffd83dbSDimitry Andric void LLJIT::PlatformSupport::setInitTransform( 6495ffd83dbSDimitry Andric LLJIT &J, IRTransformLayer::TransformFunction T) { 6505ffd83dbSDimitry Andric J.InitHelperTransformLayer->setTransform(std::move(T)); 6515ffd83dbSDimitry Andric } 6525ffd83dbSDimitry Andric 65381ad6265SDimitry Andric LLJIT::PlatformSupport::~PlatformSupport() = default; 6545ffd83dbSDimitry Andric 6550b57cec5SDimitry Andric Error LLJITBuilderState::prepareForConstruction() { 6560b57cec5SDimitry Andric 657e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << "Preparing to create LLJIT instance...\n"); 6585ffd83dbSDimitry Andric 6590b57cec5SDimitry Andric if (!JTMB) { 6605ffd83dbSDimitry Andric LLVM_DEBUG({ 6615ffd83dbSDimitry Andric dbgs() << " No explicitly set JITTargetMachineBuilder. " 6625ffd83dbSDimitry Andric "Detecting host...\n"; 6635ffd83dbSDimitry Andric }); 6640b57cec5SDimitry Andric if (auto JTMBOrErr = JITTargetMachineBuilder::detectHost()) 6650b57cec5SDimitry Andric JTMB = std::move(*JTMBOrErr); 6660b57cec5SDimitry Andric else 6670b57cec5SDimitry Andric return JTMBOrErr.takeError(); 6680b57cec5SDimitry Andric } 6690b57cec5SDimitry Andric 670*0fca6ea1SDimitry Andric if ((ES || EPC) && NumCompileThreads) 671*0fca6ea1SDimitry Andric return make_error<StringError>( 672*0fca6ea1SDimitry Andric "NumCompileThreads cannot be used with a custom ExecutionSession or " 673*0fca6ea1SDimitry Andric "ExecutorProcessControl", 674*0fca6ea1SDimitry Andric inconvertibleErrorCode()); 675*0fca6ea1SDimitry Andric 676*0fca6ea1SDimitry Andric #if !LLVM_ENABLE_THREADS 677*0fca6ea1SDimitry Andric if (NumCompileThreads) 678*0fca6ea1SDimitry Andric return make_error<StringError>( 679*0fca6ea1SDimitry Andric "LLJIT num-compile-threads is " + Twine(NumCompileThreads) + 680*0fca6ea1SDimitry Andric " but LLVM was compiled with LLVM_ENABLE_THREADS=Off", 681*0fca6ea1SDimitry Andric inconvertibleErrorCode()); 682*0fca6ea1SDimitry Andric #endif // !LLVM_ENABLE_THREADS 683*0fca6ea1SDimitry Andric 684*0fca6ea1SDimitry Andric // Only used in debug builds. 685*0fca6ea1SDimitry Andric [[maybe_unused]] bool ConcurrentCompilationSettingDefaulted = 686*0fca6ea1SDimitry Andric !SupportConcurrentCompilation; 687*0fca6ea1SDimitry Andric 688*0fca6ea1SDimitry Andric if (!SupportConcurrentCompilation) { 689*0fca6ea1SDimitry Andric #if LLVM_ENABLE_THREADS 690*0fca6ea1SDimitry Andric SupportConcurrentCompilation = NumCompileThreads || ES || EPC; 691*0fca6ea1SDimitry Andric #else 692*0fca6ea1SDimitry Andric SupportConcurrentCompilation = false; 693*0fca6ea1SDimitry Andric #endif // LLVM_ENABLE_THREADS 694*0fca6ea1SDimitry Andric } else { 695*0fca6ea1SDimitry Andric #if !LLVM_ENABLE_THREADS 696*0fca6ea1SDimitry Andric if (*SupportConcurrentCompilation) 697*0fca6ea1SDimitry Andric return make_error<StringError>( 698*0fca6ea1SDimitry Andric "LLJIT concurrent compilation support requested, but LLVM was built " 699*0fca6ea1SDimitry Andric "with LLVM_ENABLE_THREADS=Off", 700*0fca6ea1SDimitry Andric inconvertibleErrorCode()); 701*0fca6ea1SDimitry Andric #endif // !LLVM_ENABLE_THREADS 702*0fca6ea1SDimitry Andric } 703*0fca6ea1SDimitry Andric 7045ffd83dbSDimitry Andric LLVM_DEBUG({ 705fe6060f1SDimitry Andric dbgs() << " JITTargetMachineBuilder is " 706fe6060f1SDimitry Andric << JITTargetMachineBuilderPrinter(*JTMB, " ") 7075ffd83dbSDimitry Andric << " Pre-constructed ExecutionSession: " << (ES ? "Yes" : "No") 7085ffd83dbSDimitry Andric << "\n" 7095ffd83dbSDimitry Andric << " DataLayout: "; 7105ffd83dbSDimitry Andric if (DL) 7115ffd83dbSDimitry Andric dbgs() << DL->getStringRepresentation() << "\n"; 7125ffd83dbSDimitry Andric else 7135ffd83dbSDimitry Andric dbgs() << "None (will be created by JITTargetMachineBuilder)\n"; 7145ffd83dbSDimitry Andric 7155ffd83dbSDimitry Andric dbgs() << " Custom object-linking-layer creator: " 7165ffd83dbSDimitry Andric << (CreateObjectLinkingLayer ? "Yes" : "No") << "\n" 7175ffd83dbSDimitry Andric << " Custom compile-function creator: " 7185ffd83dbSDimitry Andric << (CreateCompileFunction ? "Yes" : "No") << "\n" 7195ffd83dbSDimitry Andric << " Custom platform-setup function: " 7205ffd83dbSDimitry Andric << (SetUpPlatform ? "Yes" : "No") << "\n" 721*0fca6ea1SDimitry Andric << " Support concurrent compilation: " 722*0fca6ea1SDimitry Andric << (*SupportConcurrentCompilation ? "Yes" : "No"); 723*0fca6ea1SDimitry Andric if (ConcurrentCompilationSettingDefaulted) 724*0fca6ea1SDimitry Andric dbgs() << " (defaulted based on ES / EPC / NumCompileThreads)\n"; 7255ffd83dbSDimitry Andric else 7265ffd83dbSDimitry Andric dbgs() << "\n"; 727*0fca6ea1SDimitry Andric dbgs() << " Number of compile threads: " << NumCompileThreads << "\n"; 7285ffd83dbSDimitry Andric }); 7295ffd83dbSDimitry Andric 73006c3fb27SDimitry Andric // Create DL if not specified. 73106c3fb27SDimitry Andric if (!DL) { 73206c3fb27SDimitry Andric if (auto DLOrErr = JTMB->getDefaultDataLayoutForTarget()) 73306c3fb27SDimitry Andric DL = std::move(*DLOrErr); 73406c3fb27SDimitry Andric else 73506c3fb27SDimitry Andric return DLOrErr.takeError(); 73606c3fb27SDimitry Andric } 73706c3fb27SDimitry Andric 738fe6060f1SDimitry Andric // If neither ES nor EPC has been set then create an EPC instance. 739fe6060f1SDimitry Andric if (!ES && !EPC) { 740fe6060f1SDimitry Andric LLVM_DEBUG({ 741fe6060f1SDimitry Andric dbgs() << "ExecutorProcessControl not specified, " 742fe6060f1SDimitry Andric "Creating SelfExecutorProcessControl instance\n"; 743fe6060f1SDimitry Andric }); 744*0fca6ea1SDimitry Andric 745*0fca6ea1SDimitry Andric std::unique_ptr<TaskDispatcher> D = nullptr; 746*0fca6ea1SDimitry Andric #if LLVM_ENABLE_THREADS 747*0fca6ea1SDimitry Andric if (*SupportConcurrentCompilation) { 748*0fca6ea1SDimitry Andric std::optional<size_t> NumThreads = std ::nullopt; 749*0fca6ea1SDimitry Andric if (NumCompileThreads) 750*0fca6ea1SDimitry Andric NumThreads = NumCompileThreads; 751*0fca6ea1SDimitry Andric D = std::make_unique<DynamicThreadPoolTaskDispatcher>(NumThreads); 752*0fca6ea1SDimitry Andric } else 753*0fca6ea1SDimitry Andric D = std::make_unique<InPlaceTaskDispatcher>(); 754*0fca6ea1SDimitry Andric #endif // LLVM_ENABLE_THREADS 755*0fca6ea1SDimitry Andric if (auto EPCOrErr = 756*0fca6ea1SDimitry Andric SelfExecutorProcessControl::Create(nullptr, std::move(D), nullptr)) 757fe6060f1SDimitry Andric EPC = std::move(*EPCOrErr); 758fe6060f1SDimitry Andric else 759fe6060f1SDimitry Andric return EPCOrErr.takeError(); 76006c3fb27SDimitry Andric } else if (EPC) { 761fe6060f1SDimitry Andric LLVM_DEBUG({ 762fe6060f1SDimitry Andric dbgs() << "Using explicitly specified ExecutorProcessControl instance " 763fe6060f1SDimitry Andric << EPC.get() << "\n"; 764fe6060f1SDimitry Andric }); 76506c3fb27SDimitry Andric } else { 76606c3fb27SDimitry Andric LLVM_DEBUG({ 76706c3fb27SDimitry Andric dbgs() << "Using explicitly specified ExecutionSession instance " 76806c3fb27SDimitry Andric << ES.get() << "\n"; 76906c3fb27SDimitry Andric }); 77006c3fb27SDimitry Andric } 771fe6060f1SDimitry Andric 772480093f4SDimitry Andric // If the client didn't configure any linker options then auto-configure the 773480093f4SDimitry Andric // JIT linker. 7745ffd83dbSDimitry Andric if (!CreateObjectLinkingLayer) { 775480093f4SDimitry Andric auto &TT = JTMB->getTargetTriple(); 77606c3fb27SDimitry Andric bool UseJITLink = false; 77706c3fb27SDimitry Andric switch (TT.getArch()) { 77806c3fb27SDimitry Andric case Triple::riscv64: 77906c3fb27SDimitry Andric case Triple::loongarch64: 78006c3fb27SDimitry Andric UseJITLink = true; 78106c3fb27SDimitry Andric break; 78206c3fb27SDimitry Andric case Triple::aarch64: 78306c3fb27SDimitry Andric UseJITLink = !TT.isOSBinFormatCOFF(); 78406c3fb27SDimitry Andric break; 7857a6dacacSDimitry Andric case Triple::arm: 7867a6dacacSDimitry Andric case Triple::armeb: 7877a6dacacSDimitry Andric case Triple::thumb: 7887a6dacacSDimitry Andric case Triple::thumbeb: 7897a6dacacSDimitry Andric UseJITLink = TT.isOSBinFormatELF(); 7907a6dacacSDimitry Andric break; 79106c3fb27SDimitry Andric case Triple::x86_64: 79206c3fb27SDimitry Andric UseJITLink = !TT.isOSBinFormatCOFF(); 79306c3fb27SDimitry Andric break; 7945f757f3fSDimitry Andric case Triple::ppc64: 7955f757f3fSDimitry Andric UseJITLink = TT.isPPC64ELFv2ABI(); 7965f757f3fSDimitry Andric break; 7975f757f3fSDimitry Andric case Triple::ppc64le: 7985f757f3fSDimitry Andric UseJITLink = TT.isOSBinFormatELF(); 7995f757f3fSDimitry Andric break; 80006c3fb27SDimitry Andric default: 80106c3fb27SDimitry Andric break; 80206c3fb27SDimitry Andric } 80306c3fb27SDimitry Andric if (UseJITLink) { 804*0fca6ea1SDimitry Andric if (!JTMB->getCodeModel()) 805480093f4SDimitry Andric JTMB->setCodeModel(CodeModel::Small); 806*0fca6ea1SDimitry Andric JTMB->setRelocationModel(Reloc::PIC_); 807480093f4SDimitry Andric CreateObjectLinkingLayer = 808fe6060f1SDimitry Andric [](ExecutionSession &ES, 809e8d8bef9SDimitry Andric const Triple &) -> Expected<std::unique_ptr<ObjectLayer>> { 810fe6060f1SDimitry Andric auto ObjLinkingLayer = std::make_unique<ObjectLinkingLayer>(ES); 811bdd1243dSDimitry Andric if (auto EHFrameRegistrar = EPCEHFrameRegistrar::Create(ES)) 812bdd1243dSDimitry Andric ObjLinkingLayer->addPlugin( 813bdd1243dSDimitry Andric std::make_unique<EHFrameRegistrationPlugin>( 814bdd1243dSDimitry Andric ES, std::move(*EHFrameRegistrar))); 815bdd1243dSDimitry Andric else 816bdd1243dSDimitry Andric return EHFrameRegistrar.takeError(); 8175ffd83dbSDimitry Andric return std::move(ObjLinkingLayer); 818480093f4SDimitry Andric }; 819480093f4SDimitry Andric } 820480093f4SDimitry Andric } 821480093f4SDimitry Andric 82206c3fb27SDimitry Andric // If we need a process JITDylib but no setup function has been given then 82306c3fb27SDimitry Andric // create a default one. 8245f757f3fSDimitry Andric if (!SetupProcessSymbolsJITDylib && LinkProcessSymbolsByDefault) { 8255f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "Creating default Process JD setup function\n"); 826647cbc5dSDimitry Andric SetupProcessSymbolsJITDylib = [](LLJIT &J) -> Expected<JITDylibSP> { 8275f757f3fSDimitry Andric auto &JD = 8285f757f3fSDimitry Andric J.getExecutionSession().createBareJITDylib("<Process Symbols>"); 829647cbc5dSDimitry Andric auto G = EPCDynamicLibrarySearchGenerator::GetForTargetProcess( 830647cbc5dSDimitry Andric J.getExecutionSession()); 83106c3fb27SDimitry Andric if (!G) 83206c3fb27SDimitry Andric return G.takeError(); 83306c3fb27SDimitry Andric JD.addGenerator(std::move(*G)); 8345f757f3fSDimitry Andric return &JD; 83506c3fb27SDimitry Andric }; 83606c3fb27SDimitry Andric } 83706c3fb27SDimitry Andric 8380b57cec5SDimitry Andric return Error::success(); 8390b57cec5SDimitry Andric } 8400b57cec5SDimitry Andric 8410b57cec5SDimitry Andric LLJIT::~LLJIT() { 842e8d8bef9SDimitry Andric if (auto Err = ES->endSession()) 843e8d8bef9SDimitry Andric ES->reportError(std::move(Err)); 8440b57cec5SDimitry Andric } 8450b57cec5SDimitry Andric 84606c3fb27SDimitry Andric JITDylibSP LLJIT::getProcessSymbolsJITDylib() { return ProcessSymbols; } 84706c3fb27SDimitry Andric 84806c3fb27SDimitry Andric JITDylibSP LLJIT::getPlatformJITDylib() { return Platform; } 84906c3fb27SDimitry Andric 85006c3fb27SDimitry Andric Expected<JITDylib &> LLJIT::createJITDylib(std::string Name) { 85106c3fb27SDimitry Andric auto JD = ES->createJITDylib(std::move(Name)); 85206c3fb27SDimitry Andric if (!JD) 85306c3fb27SDimitry Andric return JD.takeError(); 85406c3fb27SDimitry Andric 85506c3fb27SDimitry Andric JD->addToLinkOrder(DefaultLinks); 85606c3fb27SDimitry Andric return JD; 85706c3fb27SDimitry Andric } 85806c3fb27SDimitry Andric 85906c3fb27SDimitry Andric Expected<JITDylib &> LLJIT::loadPlatformDynamicLibrary(const char *Path) { 86006c3fb27SDimitry Andric auto G = EPCDynamicLibrarySearchGenerator::Load(*ES, Path); 86106c3fb27SDimitry Andric if (!G) 86206c3fb27SDimitry Andric return G.takeError(); 86306c3fb27SDimitry Andric 86406c3fb27SDimitry Andric if (auto *ExistingJD = ES->getJITDylibByName(Path)) 86506c3fb27SDimitry Andric return *ExistingJD; 86606c3fb27SDimitry Andric 86706c3fb27SDimitry Andric auto &JD = ES->createBareJITDylib(Path); 86806c3fb27SDimitry Andric JD.addGenerator(std::move(*G)); 86906c3fb27SDimitry Andric return JD; 87006c3fb27SDimitry Andric } 87106c3fb27SDimitry Andric 87206c3fb27SDimitry Andric Error LLJIT::linkStaticLibraryInto(JITDylib &JD, 87306c3fb27SDimitry Andric std::unique_ptr<MemoryBuffer> LibBuffer) { 87406c3fb27SDimitry Andric auto G = StaticLibraryDefinitionGenerator::Create(*ObjLinkingLayer, 87506c3fb27SDimitry Andric std::move(LibBuffer)); 87606c3fb27SDimitry Andric if (!G) 87706c3fb27SDimitry Andric return G.takeError(); 87806c3fb27SDimitry Andric 87906c3fb27SDimitry Andric JD.addGenerator(std::move(*G)); 88006c3fb27SDimitry Andric 88106c3fb27SDimitry Andric return Error::success(); 88206c3fb27SDimitry Andric } 88306c3fb27SDimitry Andric 88406c3fb27SDimitry Andric Error LLJIT::linkStaticLibraryInto(JITDylib &JD, const char *Path) { 88506c3fb27SDimitry Andric auto G = StaticLibraryDefinitionGenerator::Load(*ObjLinkingLayer, Path); 88606c3fb27SDimitry Andric if (!G) 88706c3fb27SDimitry Andric return G.takeError(); 88806c3fb27SDimitry Andric 88906c3fb27SDimitry Andric JD.addGenerator(std::move(*G)); 89006c3fb27SDimitry Andric 89106c3fb27SDimitry Andric return Error::success(); 89206c3fb27SDimitry Andric } 89306c3fb27SDimitry Andric 894e8d8bef9SDimitry Andric Error LLJIT::addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM) { 8950b57cec5SDimitry Andric assert(TSM && "Can not add null module"); 8960b57cec5SDimitry Andric 8978bcb0991SDimitry Andric if (auto Err = 8988bcb0991SDimitry Andric TSM.withModuleDo([&](Module &M) { return applyDataLayout(M); })) 8990b57cec5SDimitry Andric return Err; 9000b57cec5SDimitry Andric 901e8d8bef9SDimitry Andric return InitHelperTransformLayer->add(std::move(RT), std::move(TSM)); 902e8d8bef9SDimitry Andric } 903e8d8bef9SDimitry Andric 904e8d8bef9SDimitry Andric Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) { 905e8d8bef9SDimitry Andric return addIRModule(JD.getDefaultResourceTracker(), std::move(TSM)); 906e8d8bef9SDimitry Andric } 907e8d8bef9SDimitry Andric 908e8d8bef9SDimitry Andric Error LLJIT::addObjectFile(ResourceTrackerSP RT, 909e8d8bef9SDimitry Andric std::unique_ptr<MemoryBuffer> Obj) { 910e8d8bef9SDimitry Andric assert(Obj && "Can not add null object"); 911e8d8bef9SDimitry Andric 912e8d8bef9SDimitry Andric return ObjTransformLayer->add(std::move(RT), std::move(Obj)); 9130b57cec5SDimitry Andric } 9140b57cec5SDimitry Andric 9150b57cec5SDimitry Andric Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) { 916e8d8bef9SDimitry Andric return addObjectFile(JD.getDefaultResourceTracker(), std::move(Obj)); 9170b57cec5SDimitry Andric } 9180b57cec5SDimitry Andric 91981ad6265SDimitry Andric Expected<ExecutorAddr> LLJIT::lookupLinkerMangled(JITDylib &JD, 9205ffd83dbSDimitry Andric SymbolStringPtr Name) { 92181ad6265SDimitry Andric if (auto Sym = ES->lookup( 92281ad6265SDimitry Andric makeJITDylibSearchOrder(&JD, JITDylibLookupFlags::MatchAllSymbols), 92381ad6265SDimitry Andric Name)) 92406c3fb27SDimitry Andric return Sym->getAddress(); 92581ad6265SDimitry Andric else 92681ad6265SDimitry Andric return Sym.takeError(); 9270b57cec5SDimitry Andric } 9280b57cec5SDimitry Andric 929e8d8bef9SDimitry Andric Expected<std::unique_ptr<ObjectLayer>> 9300b57cec5SDimitry Andric LLJIT::createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES) { 9310b57cec5SDimitry Andric 9320b57cec5SDimitry Andric // If the config state provided an ObjectLinkingLayer factory then use it. 9330b57cec5SDimitry Andric if (S.CreateObjectLinkingLayer) 9348bcb0991SDimitry Andric return S.CreateObjectLinkingLayer(ES, S.JTMB->getTargetTriple()); 9350b57cec5SDimitry Andric 9360b57cec5SDimitry Andric // Otherwise default to creating an RTDyldObjectLinkingLayer that constructs 9370b57cec5SDimitry Andric // a new SectionMemoryManager for each object. 9388bcb0991SDimitry Andric auto GetMemMgr = []() { return std::make_unique<SectionMemoryManager>(); }; 939fe6060f1SDimitry Andric auto Layer = 9408bcb0991SDimitry Andric std::make_unique<RTDyldObjectLinkingLayer>(ES, std::move(GetMemMgr)); 9418bcb0991SDimitry Andric 94213138422SDimitry Andric if (S.JTMB->getTargetTriple().isOSBinFormatCOFF()) { 943fe6060f1SDimitry Andric Layer->setOverrideObjectFlagsWithResponsibilityFlags(true); 944fe6060f1SDimitry Andric Layer->setAutoClaimResponsibilityForObjectSymbols(true); 94513138422SDimitry Andric } 9468bcb0991SDimitry Andric 947bdd1243dSDimitry Andric if (S.JTMB->getTargetTriple().isOSBinFormatELF() && 948bdd1243dSDimitry Andric (S.JTMB->getTargetTriple().getArch() == Triple::ArchType::ppc64 || 949bdd1243dSDimitry Andric S.JTMB->getTargetTriple().getArch() == Triple::ArchType::ppc64le)) 950bdd1243dSDimitry Andric Layer->setAutoClaimResponsibilityForObjectSymbols(true); 951bdd1243dSDimitry Andric 9528bcb0991SDimitry Andric // FIXME: Explicit conversion to std::unique_ptr<ObjectLayer> added to silence 9538bcb0991SDimitry Andric // errors from some GCC / libstdc++ bots. Remove this conversion (i.e. 9548bcb0991SDimitry Andric // just return ObjLinkingLayer) once those bots are upgraded. 955fe6060f1SDimitry Andric return std::unique_ptr<ObjectLayer>(std::move(Layer)); 9560b57cec5SDimitry Andric } 9570b57cec5SDimitry Andric 95813138422SDimitry Andric Expected<std::unique_ptr<IRCompileLayer::IRCompiler>> 9590b57cec5SDimitry Andric LLJIT::createCompileFunction(LLJITBuilderState &S, 9600b57cec5SDimitry Andric JITTargetMachineBuilder JTMB) { 9610b57cec5SDimitry Andric 9620b57cec5SDimitry Andric /// If there is a custom compile function creator set then use it. 9630b57cec5SDimitry Andric if (S.CreateCompileFunction) 9640b57cec5SDimitry Andric return S.CreateCompileFunction(std::move(JTMB)); 9650b57cec5SDimitry Andric 966*0fca6ea1SDimitry Andric // If using a custom EPC then use a ConcurrentIRCompiler by default. 967*0fca6ea1SDimitry Andric if (*S.SupportConcurrentCompilation) 96813138422SDimitry Andric return std::make_unique<ConcurrentIRCompiler>(std::move(JTMB)); 9690b57cec5SDimitry Andric 9700b57cec5SDimitry Andric auto TM = JTMB.createTargetMachine(); 9710b57cec5SDimitry Andric if (!TM) 9720b57cec5SDimitry Andric return TM.takeError(); 9730b57cec5SDimitry Andric 97413138422SDimitry Andric return std::make_unique<TMOwningSimpleCompiler>(std::move(*TM)); 9750b57cec5SDimitry Andric } 9760b57cec5SDimitry Andric 9770b57cec5SDimitry Andric LLJIT::LLJIT(LLJITBuilderState &S, Error &Err) 97806c3fb27SDimitry Andric : DL(std::move(*S.DL)), TT(S.JTMB->getTargetTriple()) { 9790b57cec5SDimitry Andric 9800b57cec5SDimitry Andric ErrorAsOutParameter _(&Err); 9810b57cec5SDimitry Andric 982fe6060f1SDimitry Andric assert(!(S.EPC && S.ES) && "EPC and ES should not both be set"); 983fe6060f1SDimitry Andric 984fe6060f1SDimitry Andric if (S.EPC) { 985fe6060f1SDimitry Andric ES = std::make_unique<ExecutionSession>(std::move(S.EPC)); 986fe6060f1SDimitry Andric } else if (S.ES) 987fe6060f1SDimitry Andric ES = std::move(S.ES); 988fe6060f1SDimitry Andric else { 989fe6060f1SDimitry Andric if (auto EPC = SelfExecutorProcessControl::Create()) { 990fe6060f1SDimitry Andric ES = std::make_unique<ExecutionSession>(std::move(*EPC)); 991fe6060f1SDimitry Andric } else { 992fe6060f1SDimitry Andric Err = EPC.takeError(); 993fe6060f1SDimitry Andric return; 994fe6060f1SDimitry Andric } 995fe6060f1SDimitry Andric } 996fe6060f1SDimitry Andric 997e8d8bef9SDimitry Andric auto ObjLayer = createObjectLinkingLayer(S, *ES); 998e8d8bef9SDimitry Andric if (!ObjLayer) { 999e8d8bef9SDimitry Andric Err = ObjLayer.takeError(); 1000e8d8bef9SDimitry Andric return; 1001e8d8bef9SDimitry Andric } 1002e8d8bef9SDimitry Andric ObjLinkingLayer = std::move(*ObjLayer); 1003e8d8bef9SDimitry Andric ObjTransformLayer = 1004e8d8bef9SDimitry Andric std::make_unique<ObjectTransformLayer>(*ES, *ObjLinkingLayer); 1005e8d8bef9SDimitry Andric 10060b57cec5SDimitry Andric { 10070b57cec5SDimitry Andric auto CompileFunction = createCompileFunction(S, std::move(*S.JTMB)); 10080b57cec5SDimitry Andric if (!CompileFunction) { 10090b57cec5SDimitry Andric Err = CompileFunction.takeError(); 10100b57cec5SDimitry Andric return; 10110b57cec5SDimitry Andric } 10128bcb0991SDimitry Andric CompileLayer = std::make_unique<IRCompileLayer>( 1013e8d8bef9SDimitry Andric *ES, *ObjTransformLayer, std::move(*CompileFunction)); 10145ffd83dbSDimitry Andric TransformLayer = std::make_unique<IRTransformLayer>(*ES, *CompileLayer); 10155ffd83dbSDimitry Andric InitHelperTransformLayer = 10165ffd83dbSDimitry Andric std::make_unique<IRTransformLayer>(*ES, *TransformLayer); 10170b57cec5SDimitry Andric } 10180b57cec5SDimitry Andric 1019*0fca6ea1SDimitry Andric if (*S.SupportConcurrentCompilation) 10205ffd83dbSDimitry Andric InitHelperTransformLayer->setCloneToNewContextOnEmit(true); 10215ffd83dbSDimitry Andric 102206c3fb27SDimitry Andric if (S.SetupProcessSymbolsJITDylib) { 10235f757f3fSDimitry Andric if (auto ProcSymsJD = S.SetupProcessSymbolsJITDylib(*this)) { 10245f757f3fSDimitry Andric ProcessSymbols = ProcSymsJD->get(); 10255f757f3fSDimitry Andric } else { 10265f757f3fSDimitry Andric Err = ProcSymsJD.takeError(); 102706c3fb27SDimitry Andric return; 102806c3fb27SDimitry Andric } 102906c3fb27SDimitry Andric } 103006c3fb27SDimitry Andric 10315f757f3fSDimitry Andric if (S.PrePlatformSetup) { 10325f757f3fSDimitry Andric if (auto Err2 = S.PrePlatformSetup(*this)) { 10335f757f3fSDimitry Andric Err = std::move(Err2); 103406c3fb27SDimitry Andric return; 103506c3fb27SDimitry Andric } 103606c3fb27SDimitry Andric } 103706c3fb27SDimitry Andric 103806c3fb27SDimitry Andric if (!S.SetUpPlatform) 103906c3fb27SDimitry Andric S.SetUpPlatform = setUpGenericLLVMIRPlatform; 104006c3fb27SDimitry Andric 104106c3fb27SDimitry Andric if (auto PlatformJDOrErr = S.SetUpPlatform(*this)) { 104206c3fb27SDimitry Andric Platform = PlatformJDOrErr->get(); 104306c3fb27SDimitry Andric if (Platform) 104406c3fb27SDimitry Andric DefaultLinks.push_back( 104506c3fb27SDimitry Andric {Platform, JITDylibLookupFlags::MatchExportedSymbolsOnly}); 104606c3fb27SDimitry Andric } else { 104706c3fb27SDimitry Andric Err = PlatformJDOrErr.takeError(); 104806c3fb27SDimitry Andric return; 104906c3fb27SDimitry Andric } 105006c3fb27SDimitry Andric 105106c3fb27SDimitry Andric if (S.LinkProcessSymbolsByDefault) 105206c3fb27SDimitry Andric DefaultLinks.push_back( 105306c3fb27SDimitry Andric {ProcessSymbols, JITDylibLookupFlags::MatchExportedSymbolsOnly}); 105406c3fb27SDimitry Andric 105506c3fb27SDimitry Andric if (auto MainOrErr = createJITDylib("main")) 105606c3fb27SDimitry Andric Main = &*MainOrErr; 105706c3fb27SDimitry Andric else { 105806c3fb27SDimitry Andric Err = MainOrErr.takeError(); 105906c3fb27SDimitry Andric return; 106006c3fb27SDimitry Andric } 10610b57cec5SDimitry Andric } 10620b57cec5SDimitry Andric 10635ffd83dbSDimitry Andric std::string LLJIT::mangle(StringRef UnmangledName) const { 10640b57cec5SDimitry Andric std::string MangledName; 10650b57cec5SDimitry Andric { 10660b57cec5SDimitry Andric raw_string_ostream MangledNameStream(MangledName); 10670b57cec5SDimitry Andric Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL); 10680b57cec5SDimitry Andric } 10690b57cec5SDimitry Andric return MangledName; 10700b57cec5SDimitry Andric } 10710b57cec5SDimitry Andric 10720b57cec5SDimitry Andric Error LLJIT::applyDataLayout(Module &M) { 10730b57cec5SDimitry Andric if (M.getDataLayout().isDefault()) 10740b57cec5SDimitry Andric M.setDataLayout(DL); 10750b57cec5SDimitry Andric 10760b57cec5SDimitry Andric if (M.getDataLayout() != DL) 10770b57cec5SDimitry Andric return make_error<StringError>( 10785ffd83dbSDimitry Andric "Added modules have incompatible data layouts: " + 10795ffd83dbSDimitry Andric M.getDataLayout().getStringRepresentation() + " (module) vs " + 10805ffd83dbSDimitry Andric DL.getStringRepresentation() + " (jit)", 10810b57cec5SDimitry Andric inconvertibleErrorCode()); 10820b57cec5SDimitry Andric 10830b57cec5SDimitry Andric return Error::success(); 10840b57cec5SDimitry Andric } 10850b57cec5SDimitry Andric 108606c3fb27SDimitry Andric Error setUpOrcPlatformManually(LLJIT &J) { 108706c3fb27SDimitry Andric LLVM_DEBUG({ dbgs() << "Setting up orc platform support for LLJIT\n"; }); 1088bdd1243dSDimitry Andric J.setPlatformSupport(std::make_unique<ORCPlatformSupport>(J)); 1089bdd1243dSDimitry Andric return Error::success(); 1090bdd1243dSDimitry Andric } 1091bdd1243dSDimitry Andric 109206c3fb27SDimitry Andric class LoadAndLinkDynLibrary { 109306c3fb27SDimitry Andric public: 109406c3fb27SDimitry Andric LoadAndLinkDynLibrary(LLJIT &J) : J(J) {} 109506c3fb27SDimitry Andric Error operator()(JITDylib &JD, StringRef DLLName) { 109606c3fb27SDimitry Andric if (!DLLName.ends_with_insensitive(".dll")) 109706c3fb27SDimitry Andric return make_error<StringError>("DLLName not ending with .dll", 109806c3fb27SDimitry Andric inconvertibleErrorCode()); 109906c3fb27SDimitry Andric auto DLLNameStr = DLLName.str(); // Guarantees null-termination. 110006c3fb27SDimitry Andric auto DLLJD = J.loadPlatformDynamicLibrary(DLLNameStr.c_str()); 110106c3fb27SDimitry Andric if (!DLLJD) 110206c3fb27SDimitry Andric return DLLJD.takeError(); 110306c3fb27SDimitry Andric JD.addToLinkOrder(*DLLJD); 110406c3fb27SDimitry Andric return Error::success(); 11055ffd83dbSDimitry Andric } 11065ffd83dbSDimitry Andric 110706c3fb27SDimitry Andric private: 110806c3fb27SDimitry Andric LLJIT &J; 110906c3fb27SDimitry Andric }; 111006c3fb27SDimitry Andric 111106c3fb27SDimitry Andric Expected<JITDylibSP> ExecutorNativePlatform::operator()(LLJIT &J) { 111206c3fb27SDimitry Andric auto ProcessSymbolsJD = J.getProcessSymbolsJITDylib(); 111306c3fb27SDimitry Andric if (!ProcessSymbolsJD) 111406c3fb27SDimitry Andric return make_error<StringError>( 111506c3fb27SDimitry Andric "Native platforms require a process symbols JITDylib", 111606c3fb27SDimitry Andric inconvertibleErrorCode()); 111706c3fb27SDimitry Andric 111806c3fb27SDimitry Andric const Triple &TT = J.getTargetTriple(); 111906c3fb27SDimitry Andric ObjectLinkingLayer *ObjLinkingLayer = 112006c3fb27SDimitry Andric dyn_cast<ObjectLinkingLayer>(&J.getObjLinkingLayer()); 112106c3fb27SDimitry Andric 112206c3fb27SDimitry Andric if (!ObjLinkingLayer) 112306c3fb27SDimitry Andric return make_error<StringError>( 11245f757f3fSDimitry Andric "ExecutorNativePlatform requires ObjectLinkingLayer", 112506c3fb27SDimitry Andric inconvertibleErrorCode()); 112606c3fb27SDimitry Andric 112706c3fb27SDimitry Andric std::unique_ptr<MemoryBuffer> RuntimeArchiveBuffer; 112806c3fb27SDimitry Andric if (OrcRuntime.index() == 0) { 112906c3fb27SDimitry Andric auto A = errorOrToExpected(MemoryBuffer::getFile(std::get<0>(OrcRuntime))); 113006c3fb27SDimitry Andric if (!A) 113106c3fb27SDimitry Andric return A.takeError(); 113206c3fb27SDimitry Andric RuntimeArchiveBuffer = std::move(*A); 113306c3fb27SDimitry Andric } else 113406c3fb27SDimitry Andric RuntimeArchiveBuffer = std::move(std::get<1>(OrcRuntime)); 113506c3fb27SDimitry Andric 113606c3fb27SDimitry Andric auto &ES = J.getExecutionSession(); 113706c3fb27SDimitry Andric auto &PlatformJD = ES.createBareJITDylib("<Platform>"); 113806c3fb27SDimitry Andric PlatformJD.addToLinkOrder(*ProcessSymbolsJD); 113906c3fb27SDimitry Andric 114006c3fb27SDimitry Andric J.setPlatformSupport(std::make_unique<ORCPlatformSupport>(J)); 114106c3fb27SDimitry Andric 114206c3fb27SDimitry Andric switch (TT.getObjectFormat()) { 114306c3fb27SDimitry Andric case Triple::COFF: { 114406c3fb27SDimitry Andric const char *VCRuntimePath = nullptr; 114506c3fb27SDimitry Andric bool StaticVCRuntime = false; 114606c3fb27SDimitry Andric if (VCRuntime) { 114706c3fb27SDimitry Andric VCRuntimePath = VCRuntime->first.c_str(); 114806c3fb27SDimitry Andric StaticVCRuntime = VCRuntime->second; 114906c3fb27SDimitry Andric } 115006c3fb27SDimitry Andric if (auto P = COFFPlatform::Create( 115106c3fb27SDimitry Andric ES, *ObjLinkingLayer, PlatformJD, std::move(RuntimeArchiveBuffer), 115206c3fb27SDimitry Andric LoadAndLinkDynLibrary(J), StaticVCRuntime, VCRuntimePath)) 115306c3fb27SDimitry Andric J.getExecutionSession().setPlatform(std::move(*P)); 115406c3fb27SDimitry Andric else 115506c3fb27SDimitry Andric return P.takeError(); 115606c3fb27SDimitry Andric break; 115706c3fb27SDimitry Andric } 115806c3fb27SDimitry Andric case Triple::ELF: { 115906c3fb27SDimitry Andric auto G = StaticLibraryDefinitionGenerator::Create( 116006c3fb27SDimitry Andric *ObjLinkingLayer, std::move(RuntimeArchiveBuffer)); 116106c3fb27SDimitry Andric if (!G) 116206c3fb27SDimitry Andric return G.takeError(); 116306c3fb27SDimitry Andric 116406c3fb27SDimitry Andric if (auto P = ELFNixPlatform::Create(ES, *ObjLinkingLayer, PlatformJD, 116506c3fb27SDimitry Andric std::move(*G))) 116606c3fb27SDimitry Andric J.getExecutionSession().setPlatform(std::move(*P)); 116706c3fb27SDimitry Andric else 116806c3fb27SDimitry Andric return P.takeError(); 116906c3fb27SDimitry Andric break; 117006c3fb27SDimitry Andric } 117106c3fb27SDimitry Andric case Triple::MachO: { 117206c3fb27SDimitry Andric auto G = StaticLibraryDefinitionGenerator::Create( 117306c3fb27SDimitry Andric *ObjLinkingLayer, std::move(RuntimeArchiveBuffer)); 117406c3fb27SDimitry Andric if (!G) 117506c3fb27SDimitry Andric return G.takeError(); 117606c3fb27SDimitry Andric 117706c3fb27SDimitry Andric if (auto P = MachOPlatform::Create(ES, *ObjLinkingLayer, PlatformJD, 117806c3fb27SDimitry Andric std::move(*G))) 117906c3fb27SDimitry Andric ES.setPlatform(std::move(*P)); 118006c3fb27SDimitry Andric else 118106c3fb27SDimitry Andric return P.takeError(); 118206c3fb27SDimitry Andric break; 118306c3fb27SDimitry Andric } 118406c3fb27SDimitry Andric default: 118506c3fb27SDimitry Andric return make_error<StringError>("Unsupported object format in triple " + 118606c3fb27SDimitry Andric TT.str(), 118706c3fb27SDimitry Andric inconvertibleErrorCode()); 118806c3fb27SDimitry Andric } 118906c3fb27SDimitry Andric 119006c3fb27SDimitry Andric return &PlatformJD; 119106c3fb27SDimitry Andric } 119206c3fb27SDimitry Andric 119306c3fb27SDimitry Andric Expected<JITDylibSP> setUpGenericLLVMIRPlatform(LLJIT &J) { 119406c3fb27SDimitry Andric LLVM_DEBUG( 119506c3fb27SDimitry Andric { dbgs() << "Setting up GenericLLVMIRPlatform support for LLJIT\n"; }); 119606c3fb27SDimitry Andric auto ProcessSymbolsJD = J.getProcessSymbolsJITDylib(); 119706c3fb27SDimitry Andric if (!ProcessSymbolsJD) 119806c3fb27SDimitry Andric return make_error<StringError>( 119906c3fb27SDimitry Andric "Native platforms require a process symbols JITDylib", 120006c3fb27SDimitry Andric inconvertibleErrorCode()); 120106c3fb27SDimitry Andric 120206c3fb27SDimitry Andric auto &PlatformJD = J.getExecutionSession().createBareJITDylib("<Platform>"); 120306c3fb27SDimitry Andric PlatformJD.addToLinkOrder(*ProcessSymbolsJD); 120406c3fb27SDimitry Andric 120506c3fb27SDimitry Andric J.setPlatformSupport( 120606c3fb27SDimitry Andric std::make_unique<GenericLLVMIRPlatformSupport>(J, PlatformJD)); 120706c3fb27SDimitry Andric 120806c3fb27SDimitry Andric return &PlatformJD; 120906c3fb27SDimitry Andric } 121006c3fb27SDimitry Andric 121106c3fb27SDimitry Andric Expected<JITDylibSP> setUpInactivePlatform(LLJIT &J) { 1212fe6060f1SDimitry Andric LLVM_DEBUG( 1213fe6060f1SDimitry Andric { dbgs() << "Explicitly deactivated platform support for LLJIT\n"; }); 1214fe6060f1SDimitry Andric J.setPlatformSupport(std::make_unique<InactivePlatformSupport>()); 121506c3fb27SDimitry Andric return nullptr; 12160b57cec5SDimitry Andric } 12170b57cec5SDimitry Andric 12180b57cec5SDimitry Andric Error LLLazyJITBuilderState::prepareForConstruction() { 12190b57cec5SDimitry Andric if (auto Err = LLJITBuilderState::prepareForConstruction()) 12200b57cec5SDimitry Andric return Err; 12210b57cec5SDimitry Andric TT = JTMB->getTargetTriple(); 12220b57cec5SDimitry Andric return Error::success(); 12230b57cec5SDimitry Andric } 12240b57cec5SDimitry Andric 12250b57cec5SDimitry Andric Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) { 12260b57cec5SDimitry Andric assert(TSM && "Can not add null module"); 12270b57cec5SDimitry Andric 12285ffd83dbSDimitry Andric if (auto Err = TSM.withModuleDo( 12295ffd83dbSDimitry Andric [&](Module &M) -> Error { return applyDataLayout(M); })) 12308bcb0991SDimitry Andric return Err; 12310b57cec5SDimitry Andric 1232e8d8bef9SDimitry Andric return CODLayer->add(JD, std::move(TSM)); 12330b57cec5SDimitry Andric } 12340b57cec5SDimitry Andric 12350b57cec5SDimitry Andric LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) { 12360b57cec5SDimitry Andric 12370b57cec5SDimitry Andric // If LLJIT construction failed then bail out. 12380b57cec5SDimitry Andric if (Err) 12390b57cec5SDimitry Andric return; 12400b57cec5SDimitry Andric 12410b57cec5SDimitry Andric ErrorAsOutParameter _(&Err); 12420b57cec5SDimitry Andric 12430b57cec5SDimitry Andric /// Take/Create the lazy-compile callthrough manager. 12440b57cec5SDimitry Andric if (S.LCTMgr) 12450b57cec5SDimitry Andric LCTMgr = std::move(S.LCTMgr); 12460b57cec5SDimitry Andric else { 12470b57cec5SDimitry Andric if (auto LCTMgrOrErr = createLocalLazyCallThroughManager( 124806c3fb27SDimitry Andric S.TT, *ES, S.LazyCompileFailureAddr)) 12490b57cec5SDimitry Andric LCTMgr = std::move(*LCTMgrOrErr); 12500b57cec5SDimitry Andric else { 12510b57cec5SDimitry Andric Err = LCTMgrOrErr.takeError(); 12520b57cec5SDimitry Andric return; 12530b57cec5SDimitry Andric } 12540b57cec5SDimitry Andric } 12550b57cec5SDimitry Andric 12560b57cec5SDimitry Andric // Take/Create the indirect stubs manager builder. 12570b57cec5SDimitry Andric auto ISMBuilder = std::move(S.ISMBuilder); 12580b57cec5SDimitry Andric 12590b57cec5SDimitry Andric // If none was provided, try to build one. 12600b57cec5SDimitry Andric if (!ISMBuilder) 12610b57cec5SDimitry Andric ISMBuilder = createLocalIndirectStubsManagerBuilder(S.TT); 12620b57cec5SDimitry Andric 12630b57cec5SDimitry Andric // No luck. Bail out. 12640b57cec5SDimitry Andric if (!ISMBuilder) { 12650b57cec5SDimitry Andric Err = make_error<StringError>("Could not construct " 12660b57cec5SDimitry Andric "IndirectStubsManagerBuilder for target " + 12670b57cec5SDimitry Andric S.TT.str(), 12680b57cec5SDimitry Andric inconvertibleErrorCode()); 12690b57cec5SDimitry Andric return; 12700b57cec5SDimitry Andric } 12710b57cec5SDimitry Andric 12720b57cec5SDimitry Andric // Create the COD layer. 12738bcb0991SDimitry Andric CODLayer = std::make_unique<CompileOnDemandLayer>( 12745ffd83dbSDimitry Andric *ES, *InitHelperTransformLayer, *LCTMgr, std::move(ISMBuilder)); 12750b57cec5SDimitry Andric 1276*0fca6ea1SDimitry Andric if (*S.SupportConcurrentCompilation) 12770b57cec5SDimitry Andric CODLayer->setCloneToNewContextOnEmit(true); 12780b57cec5SDimitry Andric } 12790b57cec5SDimitry Andric 1280bdd1243dSDimitry Andric // In-process LLJIT uses eh-frame section wrappers via EPC, so we need to force 1281bdd1243dSDimitry Andric // them to be linked in. 1282bdd1243dSDimitry Andric LLVM_ATTRIBUTE_USED void linkComponents() { 1283bdd1243dSDimitry Andric errs() << (void *)&llvm_orc_registerEHFrameSectionWrapper 1284bdd1243dSDimitry Andric << (void *)&llvm_orc_deregisterEHFrameSectionWrapper; 1285bdd1243dSDimitry Andric } 1286bdd1243dSDimitry Andric 12870b57cec5SDimitry Andric } // End namespace orc. 12880b57cec5SDimitry Andric } // End namespace llvm. 1289