146 auto &ctx =
module->getContext();
147 llvm::IRBuilder<> builder(*module);
149 for (
auto &
func : module->getFunctionList()) {
150 if (
func.isDeclaration() ||
func.hasLocalLinkage())
152 if (interfaceFunctions.count(&
func))
158 llvm::FunctionType::get(builder.getVoidTy(), builder.getPtrTy(),
161 auto funcCst =
module->getOrInsertFunction(newName, newType);
162 llvm::Function *interfaceFunc = cast<llvm::Function>(funcCst.getCallee());
163 interfaceFunctions.insert(interfaceFunc);
167 auto *bb = llvm::BasicBlock::Create(ctx);
168 bb->insertInto(interfaceFunc);
169 builder.SetInsertPoint(bb);
170 llvm::Value *argList = interfaceFunc->arg_begin();
172 args.reserve(llvm::size(
func.args()));
173 for (
auto [
index, arg] : llvm::enumerate(
func.args())) {
174 llvm::Value *argIndex = llvm::Constant::getIntegerValue(
175 builder.getInt64Ty(), APInt(64,
index));
176 llvm::Value *argPtrPtr =
177 builder.CreateGEP(builder.getPtrTy(), argList, argIndex);
178 llvm::Value *argPtr = builder.CreateLoad(builder.getPtrTy(), argPtrPtr);
179 llvm::Type *argTy = arg.getType();
180 llvm::Value *
load = builder.CreateLoad(argTy, argPtr);
181 args.push_back(
load);
185 llvm::Value *
result = builder.CreateCall(&
func, args);
188 if (!
result->getType()->isVoidTy()) {
189 llvm::Value *retIndex = llvm::Constant::getIntegerValue(
190 builder.getInt64Ty(), APInt(64, llvm::size(
func.args())));
191 llvm::Value *retPtrPtr =
192 builder.CreateGEP(builder.getPtrTy(), argList, retIndex);
193 llvm::Value *retPtr = builder.CreateLoad(builder.getPtrTy(), retPtrPtr);
194 builder.CreateStore(
result, retPtr);
198 builder.CreateRetVoid();
231 std::unique_ptr<llvm::TargetMachine> tm) {
232 auto engine = std::make_unique<ExecutionEngine>(
234 options.enablePerfNotificationListener);
237 if (
options.enableObjectDump) {
239 if (funcOp.getBlocks().empty())
241 StringRef funcName = funcOp.getSymName();
242 engine->functionNames.push_back(funcName.str());
246 std::unique_ptr<llvm::LLVMContext> ctx(
new llvm::LLVMContext);
248 ctx->getLibraryOptions().assign(*
options.libraryOptions);
249 auto llvmModule =
options.llvmModuleBuilder
250 ?
options.llvmModuleBuilder(m, *ctx)
258 auto tmBuilderOrError = llvm::orc::JITTargetMachineBuilder::detectHost();
259 if (!tmBuilderOrError)
260 return tmBuilderOrError.takeError();
262 tmBuilderOrError->getOptions().MCOptions.LibraryOptions =
264 auto tmOrError = tmBuilderOrError->createTargetMachine();
266 return tmOrError.takeError();
267 tm = std::move(tmOrError.get());
278 auto dataLayout = llvmModule->getDataLayout();
283 options.sharedLibPaths, std::back_inserter(sharedLibPaths),
284 [](StringRef libPath) {
285 SmallString<256> absPath(libPath.begin(), libPath.end());
286 cantFail(llvm::errorCodeToError(llvm::sys::fs::make_absolute(absPath)));
293 llvm::StringMap<void *> exportSymbols;
297 for (
auto &libPath : sharedLibPaths) {
298 auto lib = llvm::sys::DynamicLibrary::getPermanentLibrary(
299 libPath.str().str().c_str());
304 if (!initSym || !destroySim) {
305 jitDyLibPaths.push_back(libPath);
310 initFn(exportSymbols);
313 destroyFns.push_back(destroyFn);
315 engine->destroyFns = std::move(destroyFns);
319 auto objectLinkingLayerCreator = [&](ExecutionSession &session,
320 llvm::jitlink::JITLinkMemoryManager
324 bool reserveAlloc = llvmModule->getTargetTriple().isAArch64();
325 auto objectLayer = std::make_unique<RTDyldObjectLinkingLayer>(
326 session, [sectionMemoryMapper =
options.sectionMemoryMapper,
327 reserveAlloc](
const MemoryBuffer &) {
328 return std::make_unique<SectionMemoryManager>(sectionMemoryMapper,
333 if (engine->gdbListener)
334 objectLayer->registerJITEventListener(*engine->gdbListener);
335 if (engine->perfListener)
336 objectLayer->registerJITEventListener(*engine->perfListener);
341 const llvm::Triple &targetTriple = llvmModule->getTargetTriple();
342 if (targetTriple.isOSBinFormatCOFF()) {
343 objectLayer->setOverrideObjectFlagsWithResponsibilityFlags(
true);
344 objectLayer->setAutoClaimResponsibilityForObjectSymbols(
true);
348 for (
auto &libPath : jitDyLibPaths) {
349 auto mb = llvm::MemoryBuffer::getFile(libPath);
351 errs() <<
"Failed to create MemoryBuffer for: " << libPath
352 <<
"\nError: " << mb.getError().message() <<
"\n";
355 auto &jd = session.createBareJITDylib(std::string(libPath));
356 auto loaded = DynamicLibrarySearchGenerator::Load(
357 libPath.str().c_str(), dataLayout.getGlobalPrefix());
359 errs() <<
"Could not load " << libPath <<
":\n " << loaded.takeError()
363 jd.addGenerator(std::move(*loaded));
364 cantFail(objectLayer->add(jd, std::move(mb.get())));
372 auto compileFunctionCreator = [&](JITTargetMachineBuilder jtmb)
373 ->
Expected<std::unique_ptr<IRCompileLayer::IRCompiler>> {
374 if (
options.jitCodeGenOptLevel)
375 jtmb.setCodeGenOptLevel(*
options.jitCodeGenOptLevel);
376 return std::make_unique<TMOwningSimpleCompiler>(std::move(tm),
377 engine->cache.get());
382 cantFail(llvm::orc::LLJITBuilder()
383 .setCompileFunctionCreator(compileFunctionCreator)
384 .setObjectLinkingLayerCreator(objectLinkingLayerCreator)
385 .setDataLayout(dataLayout)
389 ThreadSafeModule tsm(std::move(llvmModule), std::move(ctx));
391 cantFail(tsm.withModuleDo(
392 [&](llvm::Module &module) { return options.transformer(&module); }));
393 cantFail(jit->addIRModule(std::move(tsm)));
394 engine->jit = std::move(jit);
397 llvm::orc::JITDylib &mainJD = engine->jit->getMainJITDylib();
399 cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(
400 dataLayout.getGlobalPrefix())));
403 auto runtimeSymbolMap = [&](llvm::orc::MangleAndInterner interner) {
404 auto symbolMap = llvm::orc::SymbolMap();
405 for (
auto &exportSymbol : exportSymbols)
406 symbolMap[interner(exportSymbol.getKey())] = {
407 llvm::orc::ExecutorAddr::fromPtr(exportSymbol.getValue()),
408 llvm::JITSymbolFlags::Exported};
411 engine->registerSymbols(runtimeSymbolMap);
412 return std::move(engine);