145 auto &ctx =
module->getContext();
146 llvm::IRBuilder<> builder(ctx);
148 for (
auto &
func : module->getFunctionList()) {
149 if (
func.isDeclaration()) {
152 if (interfaceFunctions.count(&
func)) {
159 llvm::FunctionType::get(builder.getVoidTy(), builder.getPtrTy(),
162 auto funcCst =
module->getOrInsertFunction(newName, newType);
163 llvm::Function *interfaceFunc = cast<llvm::Function>(funcCst.getCallee());
164 interfaceFunctions.insert(interfaceFunc);
168 auto *bb = llvm::BasicBlock::Create(ctx);
169 bb->insertInto(interfaceFunc);
170 builder.SetInsertPoint(bb);
171 llvm::Value *argList = interfaceFunc->arg_begin();
173 args.reserve(llvm::size(
func.args()));
174 for (
auto [
index, arg] : llvm::enumerate(
func.args())) {
175 llvm::Value *argIndex = llvm::Constant::getIntegerValue(
176 builder.getInt64Ty(), APInt(64,
index));
177 llvm::Value *argPtrPtr =
178 builder.CreateGEP(builder.getPtrTy(), argList, argIndex);
179 llvm::Value *argPtr = builder.CreateLoad(builder.getPtrTy(), argPtrPtr);
180 llvm::Type *argTy = arg.getType();
181 llvm::Value *
load = builder.CreateLoad(argTy, argPtr);
182 args.push_back(
load);
186 llvm::Value *
result = builder.CreateCall(&
func, args);
189 if (!
result->getType()->isVoidTy()) {
190 llvm::Value *retIndex = llvm::Constant::getIntegerValue(
191 builder.getInt64Ty(), APInt(64, llvm::size(
func.args())));
192 llvm::Value *retPtrPtr =
193 builder.CreateGEP(builder.getPtrTy(), argList, retIndex);
194 llvm::Value *retPtr = builder.CreateLoad(builder.getPtrTy(), retPtrPtr);
195 builder.CreateStore(
result, retPtr);
199 builder.CreateRetVoid();
234 std::unique_ptr<llvm::TargetMachine> tm) {
235 auto engine = std::make_unique<ExecutionEngine>(
237 options.enablePerfNotificationListener);
240 if (
options.enableObjectDump) {
242 if (funcOp.getBlocks().empty())
244 StringRef funcName = funcOp.getSymName();
245 engine->functionNames.push_back(funcName.str());
249 std::unique_ptr<llvm::LLVMContext> ctx(
new llvm::LLVMContext);
250 auto llvmModule =
options.llvmModuleBuilder
251 ?
options.llvmModuleBuilder(m, *ctx)
259 auto tmBuilderOrError = llvm::orc::JITTargetMachineBuilder::detectHost();
260 if (!tmBuilderOrError)
261 return tmBuilderOrError.takeError();
263 auto tmOrError = tmBuilderOrError->createTargetMachine();
265 return tmOrError.takeError();
266 tm = std::move(tmOrError.get());
277 auto dataLayout = llvmModule->getDataLayout();
282 options.sharedLibPaths, std::back_inserter(sharedLibPaths),
283 [](StringRef libPath) {
284 SmallString<256> absPath(libPath.begin(), libPath.end());
285 cantFail(llvm::errorCodeToError(llvm::sys::fs::make_absolute(absPath)));
292 llvm::StringMap<void *> exportSymbols;
296 for (
auto &libPath : sharedLibPaths) {
297 auto lib = llvm::sys::DynamicLibrary::getPermanentLibrary(
298 libPath.str().str().c_str());
303 if (!initSym || !destroySim) {
304 jitDyLibPaths.push_back(libPath);
309 initFn(exportSymbols);
312 destroyFns.push_back(destroyFn);
314 engine->destroyFns = std::move(destroyFns);
318 auto objectLinkingLayerCreator = [&](ExecutionSession &session) {
319 auto objectLayer = std::make_unique<RTDyldObjectLinkingLayer>(
320 session, [sectionMemoryMapper =
321 options.sectionMemoryMapper](
const MemoryBuffer &) {
322 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);