1 //===--- LLJITWithObjectCache.cpp - An LLJIT example with an ObjectCache --===//
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-exception
7 //===----------------------------------------------------------------------===//
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"
19 #include "../ExampleModules.h"
22 using namespace llvm::orc
;
24 ExitOnError ExitOnErr
;
26 class MyObjectCache
: public ObjectCache
{
28 void notifyObjectCompiled(const Module
*M
,
29 MemoryBufferRef ObjBuffer
) override
{
30 CachedObjects
[M
->getModuleIdentifier()] = MemoryBuffer::getMemBufferCopy(
31 ObjBuffer
.getBuffer(), ObjBuffer
.getBufferIdentifier());
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";
42 dbgs() << "Object for " << M
->getModuleIdentifier()
43 << " loaded from cache.\n";
44 return MemoryBuffer::getMemBuffer(I
->second
->getMemBufferRef());
48 StringMap
<std::unique_ptr
<MemoryBuffer
>> CachedObjects
;
51 void runJITWithCache(ObjectCache
&ObjCache
) {
53 // Create an LLJIT instance with a custom CompileFunction.
56 .setCompileFunctionCreator(
57 [&](JITTargetMachineBuilder JTMB
)
58 -> Expected
<IRCompileLayer::CompileFunction
> {
59 auto TM
= JTMB
.createTargetMachine();
61 return TM
.takeError();
62 return IRCompileLayer::CompileFunction(
63 TMOwningSimpleCompiler(std::move(*TM
), &ObjCache
));
67 auto M
= ExitOnErr(parseExampleModule(Add1Example
, "add1"));
69 ExitOnErr(J
->addIRModule(std::move(M
)));
71 // Look up the JIT'd function, cast it to a function pointer, then call it.
72 auto Add1Sym
= ExitOnErr(J
->lookup("add1"));
73 int (*Add1
)(int) = (int (*)(int))Add1Sym
.getAddress();
75 int Result
= Add1(42);
76 outs() << "add1(42) = " << Result
<< "\n";
79 int main(int argc
, char *argv
[]) {
81 InitLLVM
X(argc
, argv
);
83 InitializeNativeTarget();
84 InitializeNativeTargetAsmPrinter();
86 cl::ParseCommandLineOptions(argc
, argv
, "HowToUseLLJIT");
87 ExitOnErr
.setBanner(std::string(argv
[0]) + ": ");
89 MyObjectCache MyCache
;
91 runJITWithCache(MyCache
);
92 runJITWithCache(MyCache
);