1 | //===- CompileUtils.h - Utilities for compiling IR in the JIT ---*- C++ -*-===// |
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 | // Contains utilities for compiling IR to object files. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H |
14 | #define LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H |
15 | |
16 | #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" |
17 | #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" |
18 | #include "llvm/ExecutionEngine/Orc/Layer.h" |
19 | #include <memory> |
20 | |
21 | namespace llvm { |
22 | |
23 | class MemoryBuffer; |
24 | class Module; |
25 | class ObjectCache; |
26 | class TargetMachine; |
27 | |
28 | namespace orc { |
29 | |
30 | IRSymbolMapper::ManglingOptions |
31 | irManglingOptionsFromTargetOptions(const TargetOptions &Opts); |
32 | |
33 | /// Simple compile functor: Takes a single IR module and returns an ObjectFile. |
34 | /// This compiler supports a single compilation thread and LLVMContext only. |
35 | /// For multithreaded compilation, use ConcurrentIRCompiler below. |
36 | class SimpleCompiler : public IRCompileLayer::IRCompiler { |
37 | public: |
38 | using CompileResult = std::unique_ptr<MemoryBuffer>; |
39 | |
40 | /// Construct a simple compile functor with the given target. |
41 | SimpleCompiler(TargetMachine &TM, ObjectCache *ObjCache = nullptr) |
42 | : IRCompiler(irManglingOptionsFromTargetOptions(Opts: TM.Options)), TM(TM), |
43 | ObjCache(ObjCache) {} |
44 | |
45 | /// Set an ObjectCache to query before compiling. |
46 | void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; } |
47 | |
48 | /// Compile a Module to an ObjectFile. |
49 | Expected<CompileResult> operator()(Module &M) override; |
50 | |
51 | private: |
52 | IRSymbolMapper::ManglingOptions |
53 | manglingOptionsForTargetMachine(const TargetMachine &TM); |
54 | |
55 | CompileResult tryToLoadFromObjectCache(const Module &M); |
56 | void notifyObjectCompiled(const Module &M, const MemoryBuffer &ObjBuffer); |
57 | |
58 | TargetMachine &TM; |
59 | ObjectCache *ObjCache = nullptr; |
60 | }; |
61 | |
62 | /// A SimpleCompiler that owns its TargetMachine. |
63 | /// |
64 | /// This is convenient for clients who don't want to own their TargetMachines, |
65 | /// e.g. LLJIT. |
66 | class TMOwningSimpleCompiler : public SimpleCompiler { |
67 | public: |
68 | TMOwningSimpleCompiler(std::unique_ptr<TargetMachine> TM, |
69 | ObjectCache *ObjCache = nullptr) |
70 | : SimpleCompiler(*TM, ObjCache), TM(std::move(TM)) {} |
71 | |
72 | private: |
73 | // FIXME: shared because std::functions (and consequently |
74 | // IRCompileLayer::CompileFunction) are not moveable. |
75 | std::shared_ptr<llvm::TargetMachine> TM; |
76 | }; |
77 | |
78 | /// A thread-safe version of SimpleCompiler. |
79 | /// |
80 | /// This class creates a new TargetMachine and SimpleCompiler instance for each |
81 | /// compile. |
82 | class ConcurrentIRCompiler : public IRCompileLayer::IRCompiler { |
83 | public: |
84 | ConcurrentIRCompiler(JITTargetMachineBuilder JTMB, |
85 | ObjectCache *ObjCache = nullptr); |
86 | |
87 | void setObjectCache(ObjectCache *ObjCache) { this->ObjCache = ObjCache; } |
88 | |
89 | Expected<std::unique_ptr<MemoryBuffer>> operator()(Module &M) override; |
90 | |
91 | private: |
92 | JITTargetMachineBuilder JTMB; |
93 | ObjectCache *ObjCache = nullptr; |
94 | }; |
95 | |
96 | } // end namespace orc |
97 | |
98 | } // end namespace llvm |
99 | |
100 | #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H |
101 | |