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();
232 std::unique_ptr<llvm::TargetMachine> tm) {
233 auto engine = std::make_unique<ExecutionEngine>(
235 options.enablePerfNotificationListener);
238 if (
options.enableObjectDump) {
240 if (funcOp.getBlocks().empty())
242 StringRef funcName = funcOp.getSymName();
243 engine->functionNames.push_back(funcName.str());
247 std::unique_ptr<llvm::LLVMContext> ctx(
new llvm::LLVMContext);
248 auto llvmModule =
options.llvmModuleBuilder
249 ?
options.llvmModuleBuilder(m, *ctx)
257 auto tmBuilderOrError = llvm::orc::JITTargetMachineBuilder::detectHost();
258 if (!tmBuilderOrError)
259 return tmBuilderOrError.takeError();
261 auto tmOrError = tmBuilderOrError->createTargetMachine();
263 return tmOrError.takeError();
264 tm = std::move(tmOrError.get());
275 auto dataLayout = llvmModule->getDataLayout();
280 options.sharedLibPaths, std::back_inserter(sharedLibPaths),
281 [](StringRef libPath) {
282 SmallString<256> absPath(libPath.begin(), libPath.end());
283 cantFail(llvm::errorCodeToError(llvm::sys::fs::make_absolute(absPath)));
290 llvm::StringMap<void *> exportSymbols;
294 for (
auto &libPath : sharedLibPaths) {
295 auto lib = llvm::sys::DynamicLibrary::getPermanentLibrary(
296 libPath.str().str().c_str());
301 if (!initSym || !destroySim) {
302 jitDyLibPaths.push_back(libPath);
307 initFn(exportSymbols);
310 destroyFns.push_back(destroyFn);
312 engine->destroyFns = std::move(destroyFns);
316 auto objectLinkingLayerCreator = [&](ExecutionSession &session) {
317 auto objectLayer = std::make_unique<RTDyldObjectLinkingLayer>(
318 session, [sectionMemoryMapper =
319 options.sectionMemoryMapper](
const MemoryBuffer &) {
320 return std::make_unique<SectionMemoryManager>(sectionMemoryMapper);
324 if (engine->gdbListener)
325 objectLayer->registerJITEventListener(*engine->gdbListener);
326 if (engine->perfListener)
327 objectLayer->registerJITEventListener(*engine->perfListener);
332 const llvm::Triple &targetTriple = llvmModule->getTargetTriple();
333 if (targetTriple.isOSBinFormatCOFF()) {
334 objectLayer->setOverrideObjectFlagsWithResponsibilityFlags(
true);
335 objectLayer->setAutoClaimResponsibilityForObjectSymbols(
true);
339 for (
auto &libPath : jitDyLibPaths) {
340 auto mb = llvm::MemoryBuffer::getFile(libPath);
342 errs() <<
"Failed to create MemoryBuffer for: " << libPath
343 <<
"\nError: " << mb.getError().message() <<
"\n";
346 auto &jd = session.createBareJITDylib(std::string(libPath));
347 auto loaded = DynamicLibrarySearchGenerator::Load(
348 libPath.str().c_str(), dataLayout.getGlobalPrefix());
350 errs() <<
"Could not load " << libPath <<
":\n " << loaded.takeError()
354 jd.addGenerator(std::move(*loaded));
355 cantFail(objectLayer->add(jd, std::move(mb.get())));
363 auto compileFunctionCreator = [&](JITTargetMachineBuilder jtmb)
364 ->
Expected<std::unique_ptr<IRCompileLayer::IRCompiler>> {
365 if (
options.jitCodeGenOptLevel)
366 jtmb.setCodeGenOptLevel(*
options.jitCodeGenOptLevel);
367 return std::make_unique<TMOwningSimpleCompiler>(std::move(tm),
368 engine->cache.get());
373 cantFail(llvm::orc::LLJITBuilder()
374 .setCompileFunctionCreator(compileFunctionCreator)
375 .setObjectLinkingLayerCreator(objectLinkingLayerCreator)
376 .setDataLayout(dataLayout)
380 ThreadSafeModule tsm(std::move(llvmModule), std::move(ctx));
382 cantFail(tsm.withModuleDo(
383 [&](llvm::Module &module) { return options.transformer(&module); }));
384 cantFail(jit->addIRModule(std::move(tsm)));
385 engine->jit = std::move(jit);
388 llvm::orc::JITDylib &mainJD = engine->jit->getMainJITDylib();
390 cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(
391 dataLayout.getGlobalPrefix())));
394 auto runtimeSymbolMap = [&](llvm::orc::MangleAndInterner interner) {
395 auto symbolMap = llvm::orc::SymbolMap();
396 for (
auto &exportSymbol : exportSymbols)
397 symbolMap[interner(exportSymbol.getKey())] = {
398 llvm::orc::ExecutorAddr::fromPtr(exportSymbol.getValue()),
399 llvm::JITSymbolFlags::Exported};
402 engine->registerSymbols(runtimeSymbolMap);
403 return std::move(engine);