96 lines · cpp
1//===--- LLJITWithObjectCache.cpp - An LLJIT example with an ObjectCache --===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ADT/StringMap.h"10#include "llvm/ExecutionEngine/ObjectCache.h"11#include "llvm/ExecutionEngine/Orc/LLJIT.h"12#include "llvm/IR/Function.h"13#include "llvm/IR/IRBuilder.h"14#include "llvm/IR/Module.h"15#include "llvm/Support/InitLLVM.h"16#include "llvm/Support/TargetSelect.h"17#include "llvm/Support/raw_ostream.h"18 19#include "../ExampleModules.h"20 21using namespace llvm;22using namespace llvm::orc;23 24ExitOnError ExitOnErr;25 26class MyObjectCache : public ObjectCache {27public:28 void notifyObjectCompiled(const Module *M,29 MemoryBufferRef ObjBuffer) override {30 CachedObjects[M->getModuleIdentifier()] = MemoryBuffer::getMemBufferCopy(31 ObjBuffer.getBuffer(), ObjBuffer.getBufferIdentifier());32 }33 34 std::unique_ptr<MemoryBuffer> getObject(const Module *M) override {35 auto I = CachedObjects.find(M->getModuleIdentifier());36 if (I == CachedObjects.end()) {37 dbgs() << "No object for " << M->getModuleIdentifier()38 << " in cache. Compiling.\n";39 return nullptr;40 }41 42 dbgs() << "Object for " << M->getModuleIdentifier()43 << " loaded from cache.\n";44 return MemoryBuffer::getMemBuffer(I->second->getMemBufferRef());45 }46 47private:48 StringMap<std::unique_ptr<MemoryBuffer>> CachedObjects;49};50 51void runJITWithCache(ObjectCache &ObjCache) {52 53 // Create an LLJIT instance with a custom IRCompiler.54 auto J = ExitOnErr(55 LLJITBuilder()56 .setCompileFunctionCreator(57 [&](JITTargetMachineBuilder JTMB)58 -> Expected<std::unique_ptr<IRCompileLayer::IRCompiler>> {59 auto TM = JTMB.createTargetMachine();60 if (!TM)61 return TM.takeError();62 return std::make_unique<TMOwningSimpleCompiler>(std::move(*TM),63 &ObjCache);64 })65 .create());66 67 auto M = ExitOnErr(parseExampleModule(Add1Example, "add1"));68 69 ExitOnErr(J->addIRModule(std::move(M)));70 71 // Look up the JIT'd function, cast it to a function pointer, then call it.72 auto Add1Addr = ExitOnErr(J->lookup("add1"));73 int (*Add1)(int) = Add1Addr.toPtr<int(int)>();74 75 int Result = Add1(42);76 outs() << "add1(42) = " << Result << "\n";77}78 79int main(int argc, char *argv[]) {80 // Initialize LLVM.81 InitLLVM X(argc, argv);82 83 InitializeNativeTarget();84 InitializeNativeTargetAsmPrinter();85 86 cl::ParseCommandLineOptions(argc, argv, "LLJITWithObjectCache");87 ExitOnErr.setBanner(std::string(argv[0]) + ": ");88 89 MyObjectCache MyCache;90 91 runJITWithCache(MyCache);92 runJITWithCache(MyCache);93 94 return 0;95}96