145 auto &ctx =
module->getContext();
146 llvm::IRBuilder<> builder(ctx);
148 for (
auto &
func : module->getFunctionList()) {
149 if (
func.isDeclaration() ||
func.hasLocalLinkage())
151 if (interfaceFunctions.count(&
func))
157 llvm::FunctionType::get(builder.getVoidTy(), builder.getPtrTy(),
160 auto funcCst =
module->getOrInsertFunction(newName, newType);
161 llvm::Function *interfaceFunc = cast<llvm::Function>(funcCst.getCallee());
162 interfaceFunctions.insert(interfaceFunc);
166 auto *bb = llvm::BasicBlock::Create(ctx);
167 bb->insertInto(interfaceFunc);
168 builder.SetInsertPoint(bb);
169 llvm::Value *argList = interfaceFunc->arg_begin();
171 args.reserve(llvm::size(
func.args()));
172 for (
auto [
index, arg] : llvm::enumerate(
func.args())) {
173 llvm::Value *argIndex = llvm::Constant::getIntegerValue(
174 builder.getInt64Ty(), APInt(64,
index));
175 llvm::Value *argPtrPtr =
176 builder.CreateGEP(builder.getPtrTy(), argList, argIndex);
177 llvm::Value *argPtr = builder.CreateLoad(builder.getPtrTy(), argPtrPtr);
178 llvm::Type *argTy = arg.getType();
179 llvm::Value *
load = builder.CreateLoad(argTy, argPtr);
180 args.push_back(
load);
184 llvm::Value *
result = builder.CreateCall(&
func, args);
187 if (!
result->getType()->isVoidTy()) {
188 llvm::Value *retIndex = llvm::Constant::getIntegerValue(
189 builder.getInt64Ty(), APInt(64, llvm::size(
func.args())));
190 llvm::Value *retPtrPtr =
191 builder.CreateGEP(builder.getPtrTy(), argList, retIndex);
192 llvm::Value *retPtr = builder.CreateLoad(builder.getPtrTy(), retPtrPtr);
193 builder.CreateStore(
result, retPtr);
197 builder.CreateRetVoid();
230 std::unique_ptr<llvm::TargetMachine> tm) {
231 auto engine = std::make_unique<ExecutionEngine>(
233 options.enablePerfNotificationListener);
236 if (
options.enableObjectDump) {
238 if (funcOp.getBlocks().empty())
240 StringRef funcName = funcOp.getSymName();
241 engine->functionNames.push_back(funcName.str());
245 std::unique_ptr<llvm::LLVMContext> ctx(
new llvm::LLVMContext);
246 auto llvmModule =
options.llvmModuleBuilder
247 ?
options.llvmModuleBuilder(m, *ctx)
255 auto tmBuilderOrError = llvm::orc::JITTargetMachineBuilder::detectHost();
256 if (!tmBuilderOrError)
257 return tmBuilderOrError.takeError();
259 auto tmOrError = tmBuilderOrError->createTargetMachine();
261 return tmOrError.takeError();
262 tm = std::move(tmOrError.get());
273 auto dataLayout = llvmModule->getDataLayout();
278 options.sharedLibPaths, std::back_inserter(sharedLibPaths),
279 [](StringRef libPath) {
280 SmallString<256> absPath(libPath.begin(), libPath.end());
281 cantFail(llvm::errorCodeToError(llvm::sys::fs::make_absolute(absPath)));
288 llvm::StringMap<void *> exportSymbols;
292 for (
auto &libPath : sharedLibPaths) {
293 auto lib = llvm::sys::DynamicLibrary::getPermanentLibrary(
294 libPath.str().str().c_str());
299 if (!initSym || !destroySim) {
300 jitDyLibPaths.push_back(libPath);
305 initFn(exportSymbols);
308 destroyFns.push_back(destroyFn);
310 engine->destroyFns = std::move(destroyFns);
314 auto objectLinkingLayerCreator = [&](ExecutionSession &session) {
317 bool reserveAlloc = llvmModule->getTargetTriple().isAArch64();
318 auto objectLayer = std::make_unique<RTDyldObjectLinkingLayer>(
319 session, [sectionMemoryMapper =
options.sectionMemoryMapper,
320 reserveAlloc](
const MemoryBuffer &) {
321 return std::make_unique<SectionMemoryManager>(sectionMemoryMapper,
326 if (engine->gdbListener)
327 objectLayer->registerJITEventListener(*engine->gdbListener);
328 if (engine->perfListener)
329 objectLayer->registerJITEventListener(*engine->perfListener);
334 const llvm::Triple &targetTriple = llvmModule->getTargetTriple();
335 if (targetTriple.isOSBinFormatCOFF()) {
336 objectLayer->setOverrideObjectFlagsWithResponsibilityFlags(
true);
337 objectLayer->setAutoClaimResponsibilityForObjectSymbols(
true);
341 for (
auto &libPath : jitDyLibPaths) {
342 auto mb = llvm::MemoryBuffer::getFile(libPath);
344 errs() <<
"Failed to create MemoryBuffer for: " << libPath
345 <<
"\nError: " << mb.getError().message() <<
"\n";
348 auto &jd = session.createBareJITDylib(std::string(libPath));
349 auto loaded = DynamicLibrarySearchGenerator::Load(
350 libPath.str().c_str(), dataLayout.getGlobalPrefix());
352 errs() <<
"Could not load " << libPath <<
":\n " << loaded.takeError()
356 jd.addGenerator(std::move(*loaded));
357 cantFail(objectLayer->add(jd, std::move(mb.get())));
365 auto compileFunctionCreator = [&](JITTargetMachineBuilder jtmb)
366 ->
Expected<std::unique_ptr<IRCompileLayer::IRCompiler>> {
367 if (
options.jitCodeGenOptLevel)
368 jtmb.setCodeGenOptLevel(*
options.jitCodeGenOptLevel);
369 return std::make_unique<TMOwningSimpleCompiler>(std::move(tm),
370 engine->cache.get());
375 cantFail(llvm::orc::LLJITBuilder()
376 .setCompileFunctionCreator(compileFunctionCreator)
377 .setObjectLinkingLayerCreator(objectLinkingLayerCreator)
378 .setDataLayout(dataLayout)
382 ThreadSafeModule tsm(std::move(llvmModule), std::move(ctx));
384 cantFail(tsm.withModuleDo(
385 [&](llvm::Module &module) { return options.transformer(&module); }));
386 cantFail(jit->addIRModule(std::move(tsm)));
387 engine->jit = std::move(jit);
390 llvm::orc::JITDylib &mainJD = engine->jit->getMainJITDylib();
392 cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(
393 dataLayout.getGlobalPrefix())));
396 auto runtimeSymbolMap = [&](llvm::orc::MangleAndInterner interner) {
397 auto symbolMap = llvm::orc::SymbolMap();
398 for (
auto &exportSymbol : exportSymbols)
399 symbolMap[interner(exportSymbol.getKey())] = {
400 llvm::orc::ExecutorAddr::fromPtr(exportSymbol.getValue()),
401 llvm::JITSymbolFlags::Exported};
404 engine->registerSymbols(runtimeSymbolMap);
405 return std::move(engine);