147
|
1 //===------ CompileUtils.cpp - Utilities for compiling IR in the JIT ------===//
|
|
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-exception
|
|
6 //
|
|
7 //===----------------------------------------------------------------------===//
|
|
8
|
|
9 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
|
10
|
|
11 #include "llvm/ADT/SmallVector.h"
|
|
12 #include "llvm/ExecutionEngine/ObjectCache.h"
|
|
13 #include "llvm/IR/LegacyPassManager.h"
|
|
14 #include "llvm/IR/Module.h"
|
|
15 #include "llvm/Object/ObjectFile.h"
|
|
16 #include "llvm/Support/Error.h"
|
|
17 #include "llvm/Support/ErrorHandling.h"
|
|
18 #include "llvm/Support/MemoryBuffer.h"
|
|
19 #include "llvm/Support/SmallVectorMemoryBuffer.h"
|
|
20 #include "llvm/Target/TargetMachine.h"
|
|
21
|
|
22 #include <algorithm>
|
|
23
|
|
24 namespace llvm {
|
|
25 namespace orc {
|
|
26
|
|
27 /// Compile a Module to an ObjectFile.
|
|
28 SimpleCompiler::CompileResult SimpleCompiler::operator()(Module &M) {
|
|
29 CompileResult CachedObject = tryToLoadFromObjectCache(M);
|
|
30 if (CachedObject)
|
|
31 return CachedObject;
|
|
32
|
|
33 SmallVector<char, 0> ObjBufferSV;
|
|
34
|
|
35 {
|
|
36 raw_svector_ostream ObjStream(ObjBufferSV);
|
|
37
|
|
38 legacy::PassManager PM;
|
|
39 MCContext *Ctx;
|
|
40 if (TM.addPassesToEmitMC(PM, Ctx, ObjStream))
|
|
41 llvm_unreachable("Target does not support MC emission.");
|
|
42 PM.run(M);
|
|
43 }
|
|
44
|
|
45 auto ObjBuffer = llvm::make_unique<SmallVectorMemoryBuffer>(
|
|
46 std::move(ObjBufferSV),
|
|
47 "<in memory object compiled from " + M.getModuleIdentifier() + ">");
|
|
48
|
|
49 auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
|
|
50
|
|
51 if (Obj) {
|
|
52 notifyObjectCompiled(M, *ObjBuffer);
|
|
53 return std::move(ObjBuffer);
|
|
54 }
|
|
55
|
|
56 // TODO: Actually report errors helpfully.
|
|
57 consumeError(Obj.takeError());
|
|
58 return nullptr;
|
|
59 }
|
|
60
|
|
61 SimpleCompiler::CompileResult
|
|
62 SimpleCompiler::tryToLoadFromObjectCache(const Module &M) {
|
|
63 if (!ObjCache)
|
|
64 return CompileResult();
|
|
65
|
|
66 return ObjCache->getObject(&M);
|
|
67 }
|
|
68
|
|
69 void SimpleCompiler::notifyObjectCompiled(const Module &M,
|
|
70 const MemoryBuffer &ObjBuffer) {
|
|
71 if (ObjCache)
|
|
72 ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef());
|
|
73 }
|
|
74
|
|
75 ConcurrentIRCompiler::ConcurrentIRCompiler(JITTargetMachineBuilder JTMB,
|
|
76 ObjectCache *ObjCache)
|
|
77 : JTMB(std::move(JTMB)), ObjCache(ObjCache) {}
|
|
78
|
|
79 std::unique_ptr<MemoryBuffer> ConcurrentIRCompiler::operator()(Module &M) {
|
|
80 auto TM = cantFail(JTMB.createTargetMachine());
|
|
81 SimpleCompiler C(*TM, ObjCache);
|
|
82 return C(M);
|
|
83 }
|
|
84
|
|
85 } // end namespace orc
|
|
86 } // end namespace llvm
|