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,
315 llvm::jitlink::JITLinkMemoryManager
319 bool reserveAlloc = llvmModule->getTargetTriple().isAArch64();
320 auto objectLayer = std::make_unique<RTDyldObjectLinkingLayer>(
321 session, [sectionMemoryMapper =
options.sectionMemoryMapper,
322 reserveAlloc](
const MemoryBuffer &) {
323 return std::make_unique<SectionMemoryManager>(sectionMemoryMapper,
328 if (engine->gdbListener)
329 objectLayer->registerJITEventListener(*engine->gdbListener);
330 if (engine->perfListener)
331 objectLayer->registerJITEventListener(*engine->perfListener);
336 const llvm::Triple &targetTriple = llvmModule->getTargetTriple();
337 if (targetTriple.isOSBinFormatCOFF()) {
338 objectLayer->setOverrideObjectFlagsWithResponsibilityFlags(
true);
339 objectLayer->setAutoClaimResponsibilityForObjectSymbols(
true);
343 for (
auto &libPath : jitDyLibPaths) {
344 auto mb = llvm::MemoryBuffer::getFile(libPath);
346 errs() <<
"Failed to create MemoryBuffer for: " << libPath
347 <<
"\nError: " << mb.getError().message() <<
"\n";
350 auto &jd = session.createBareJITDylib(std::string(libPath));
351 auto loaded = DynamicLibrarySearchGenerator::Load(
352 libPath.str().c_str(), dataLayout.getGlobalPrefix());
354 errs() <<
"Could not load " << libPath <<
":\n " << loaded.takeError()
358 jd.addGenerator(std::move(*loaded));
359 cantFail(objectLayer->add(jd, std::move(mb.get())));
367 auto compileFunctionCreator = [&](JITTargetMachineBuilder jtmb)
368 ->
Expected<std::unique_ptr<IRCompileLayer::IRCompiler>> {
369 if (
options.jitCodeGenOptLevel)
370 jtmb.setCodeGenOptLevel(*
options.jitCodeGenOptLevel);
371 return std::make_unique<TMOwningSimpleCompiler>(std::move(tm),
372 engine->cache.get());
377 cantFail(llvm::orc::LLJITBuilder()
378 .setCompileFunctionCreator(compileFunctionCreator)
379 .setObjectLinkingLayerCreator(objectLinkingLayerCreator)
380 .setDataLayout(dataLayout)
384 ThreadSafeModule tsm(std::move(llvmModule), std::move(ctx));
386 cantFail(tsm.withModuleDo(
387 [&](llvm::Module &module) { return options.transformer(&module); }));
388 cantFail(jit->addIRModule(std::move(tsm)));
389 engine->jit = std::move(jit);
392 llvm::orc::JITDylib &mainJD = engine->jit->getMainJITDylib();
394 cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(
395 dataLayout.getGlobalPrefix())));
398 auto runtimeSymbolMap = [&](llvm::orc::MangleAndInterner interner) {
399 auto symbolMap = llvm::orc::SymbolMap();
400 for (
auto &exportSymbol : exportSymbols)
401 symbolMap[interner(exportSymbol.getKey())] = {
402 llvm::orc::ExecutorAddr::fromPtr(exportSymbol.getValue()),
403 llvm::JITSymbolFlags::Exported};
406 engine->registerSymbols(runtimeSymbolMap);
407 return std::move(engine);