github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/jit/OrcLazyJIT.cpp (about) 1 //===- OrcLazyJIT.cpp - Basic Orc-based JIT for lazy execution ------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "OrcLazyJIT.h" 11 #include "jit/jit_exception.h" 12 #include "llvm/ADT/Triple.h" 13 #include "llvm/ExecutionEngine/ExecutionEngine.h" 14 #include "llvm/Support/CodeGen.h" 15 #include "llvm/Support/CommandLine.h" 16 #include "llvm/Support/DynamicLibrary.h" 17 #include "llvm/Support/ErrorHandling.h" 18 #include "llvm/Support/FileSystem.h" 19 #include <cstdint> 20 #include <cstdio> 21 #include <cstdlib> 22 #include <iostream> 23 #include <system_error> 24 25 namespace { 26 27 enum class DumpKind { 28 NoDump, 29 DumpFuncsToStdOut, 30 DumpModsToStdOut, 31 DumpModsToDisk 32 }; 33 34 } // end anonymous namespace 35 36 llvm::OrcLazyJIT::TransformFtor llvm::OrcLazyJIT::createDebugDumper() { 37 DumpKind OrcDumpKind = DumpKind::NoDump; 38 switch (OrcDumpKind) { 39 case DumpKind::NoDump: 40 return [](std::shared_ptr<Module> M) { return M; }; 41 42 case DumpKind::DumpFuncsToStdOut: 43 return [](std::shared_ptr<Module> M) { 44 std::cout << "[ " << std::endl; 45 46 for (const auto &F : *M) { 47 if (F.isDeclaration()) { 48 continue; 49 } 50 51 if (F.hasName()) { 52 std::string Name(F.getName()); 53 std::cout << Name << std::endl; 54 } else { 55 std::cout << "<anon> " << std::endl; 56 } 57 } 58 59 std::cout << "]\n" << std::endl; 60 return M; 61 }; 62 63 case DumpKind::DumpModsToStdOut: 64 return [](std::shared_ptr<Module> M) { 65 outs() << "----- Module Start -----\n" 66 << *M << "----- Module End -----\n"; 67 68 return M; 69 }; 70 71 case DumpKind::DumpModsToDisk: 72 return [](std::shared_ptr<Module> M) { 73 std::error_code EC; 74 raw_fd_ostream Out(M->getModuleIdentifier() + ".ll", EC, sys::fs::F_Text); 75 if (EC) { 76 errs() << "Couldn't open " << M->getModuleIdentifier() 77 << " for dumping.\nError:" << EC.message() << "\n"; 78 exit(1); 79 } 80 Out << *M; 81 return M; 82 }; 83 } 84 llvm_unreachable("Unknown DumpKind"); 85 } 86 87 llvm::Error llvm::OrcLazyJIT::addModule(std::shared_ptr<Module> M) { 88 if (M->getDataLayout().isDefault()) 89 M->setDataLayout(DL); 90 91 // Rename, bump linkage and record static constructors and destructors. 92 // We have to do this before we hand over ownership of the module to the 93 // JIT. 94 std::vector<std::string> CtorNames, DtorNames; 95 { 96 unsigned CtorId = 0, DtorId = 0; 97 for (auto Ctor : orc::getConstructors(*M)) { 98 std::string NewCtorName = ("$static_ctor." + Twine(CtorId++)).str(); 99 Ctor.Func->setName(NewCtorName); 100 Ctor.Func->setLinkage(GlobalValue::ExternalLinkage); 101 Ctor.Func->setVisibility(GlobalValue::HiddenVisibility); 102 CtorNames.push_back(mangle(NewCtorName)); 103 } 104 for (auto Dtor : orc::getDestructors(*M)) { 105 std::string NewDtorName = ("$static_dtor." + Twine(DtorId++)).str(); 106 Dtor.Func->setLinkage(GlobalValue::ExternalLinkage); 107 Dtor.Func->setVisibility(GlobalValue::HiddenVisibility); 108 DtorNames.push_back(mangle(Dtor.Func->getName())); 109 Dtor.Func->setName(NewDtorName); 110 } 111 } 112 113 // Symbol resolution order: 114 // 1) Search the JIT symbols. 115 // 2) Check for C++ runtime overrides. 116 // 3) Search the host process (LLI)'s symbol table. 117 if (!ModulesHandle) { 118 auto Resolver = orc::createLambdaResolver( 119 [this](const std::string &Name) -> JITSymbol { 120 if (auto Sym = CODLayer.findSymbol(Name, true)) 121 return Sym; 122 return CXXRuntimeOverrides.searchOverrides(Name); 123 }, 124 [this](const std::string &Name) { 125 if (auto Addr = RTDyldMemoryManager::getSymbolAddressInProcess(Name)) 126 return JITSymbol(Addr, JITSymbolFlags::Exported); 127 return JITSymbol(nullptr); 128 }); 129 130 // Add the module to the JIT. 131 if (auto ModulesHandleOrErr = 132 CODLayer.addModule(std::move(M), std::move(Resolver))) 133 ModulesHandle = std::move(*ModulesHandleOrErr); 134 else 135 return ModulesHandleOrErr.takeError(); 136 137 } else if (auto Err = CODLayer.addExtraModule(*ModulesHandle, std::move(M))) 138 return Err; 139 140 // Run the static constructors, and save the static destructor runner for 141 // execution when the JIT is torn down. 142 orc::CtorDtorRunner<CODLayerT> CtorRunner(std::move(CtorNames), 143 *ModulesHandle); 144 if (auto Err = CtorRunner.runViaLayer(CODLayer)) 145 return Err; 146 147 IRStaticDestructorRunners.emplace_back(std::move(DtorNames), *ModulesHandle); 148 149 return Error::success(); 150 } 151 152 // Defined in lli.cpp. 153 // CodeGenOpt::Level getOptLevel(); 154 155