Proteus
Programmable JIT compilation and optimization for C/C++ using LLVM
Loading...
Searching...
No Matches
LLVMCodeBuilder.h
Go to the documentation of this file.
1#ifndef PROTEUS_FRONTEND_LLVM_CODE_BUILDER_H
2#define PROTEUS_FRONTEND_LLVM_CODE_BUILDER_H
3
5
6#include <cstdint>
7#include <functional>
8#include <memory>
9#include <string>
10#include <tuple>
11#include <vector>
12
13namespace llvm {
14class AllocaInst;
15class ArrayType;
16class BasicBlock;
17class Function;
18class IRBuilderBase;
19class LLVMContext;
20class Module;
21class Type;
22} // namespace llvm
23
24namespace proteus {
25
30public:
32 LLVMCodeBuilder(std::unique_ptr<llvm::LLVMContext> Ctx,
33 std::unique_ptr<llvm::Module> Mod,
35 ~LLVMCodeBuilder() override;
36
37 TargetModelType getTargetModel() const override { return TargetModel; }
38
41
42 // -----------------------------------------------------------------------
43 // LLVM-specific (non-virtual) accessors.
44 // -----------------------------------------------------------------------
45
47 llvm::IRBuilderBase &getIRBuilder();
48
49 llvm::Function &getFunction();
50 llvm::Module &getModule();
51 llvm::LLVMContext &getContext();
52
54 std::unique_ptr<llvm::LLVMContext> takeLLVMContext();
56 std::unique_ptr<llvm::Module> takeModule();
57
58 // -----------------------------------------------------------------------
59 // Basic block operations.
60 // -----------------------------------------------------------------------
61 std::tuple<llvm::BasicBlock *, llvm::BasicBlock *> splitCurrentBlock();
62 llvm::BasicBlock *createBasicBlock(const std::string &Name = "",
63 llvm::BasicBlock *InsertBefore = nullptr);
64 void eraseTerminator(llvm::BasicBlock *BB);
65 llvm::BasicBlock *getUniqueSuccessor(llvm::BasicBlock *BB);
66
67 // -----------------------------------------------------------------------
68 // Scope management.
69 // -----------------------------------------------------------------------
70 void pushScope(const char *File, int Line, ScopeKind Kind,
71 llvm::BasicBlock *NextBlock);
72
73 // -----------------------------------------------------------------------
74 // Control flow (LLVM-specific overloads / extensions).
75 // -----------------------------------------------------------------------
76 void createBr(llvm::BasicBlock *Dest);
77 void createCondBr(IRValue *Cond, llvm::BasicBlock *True,
78 llvm::BasicBlock *False);
79
80 // -----------------------------------------------------------------------
81 // Type accessors.
82 // -----------------------------------------------------------------------
83 llvm::Type *getPointerType(llvm::Type *ElemTy, unsigned AS);
84 llvm::Type *getPointerTypeUnqual(llvm::Type *ElemTy);
85 llvm::Type *getInt16Ty();
86 llvm::Type *getInt32Ty();
87 llvm::Type *getInt64Ty();
88 llvm::Type *getFloatTy();
89
90 // -----------------------------------------------------------------------
91 // Type queries.
92 // -----------------------------------------------------------------------
93 unsigned getAddressSpace(llvm::Type *Ty);
94 bool isIntegerTy(llvm::Type *Ty);
95 bool isFloatingPointTy(llvm::Type *Ty);
96
97 // -----------------------------------------------------------------------
98 // Alloca/array emission.
99 // -----------------------------------------------------------------------
100 IRValue *emitAlloca(llvm::Type *Ty, const std::string &Name,
102 IRValue *emitArrayCreate(llvm::Type *Ty, AddressSpace AT,
103 const std::string &Name);
104
105 // -----------------------------------------------------------------------
106 // CodeBuilder overrides — function management.
107 // -----------------------------------------------------------------------
108 IRFunction *addFunction(const std::string &Name, IRType RetTy,
109 const std::vector<IRType> &ArgTys) override;
110 void setFunctionName(IRFunction *F, const std::string &Name) override;
111 IRValue *getArg(IRFunction *F, size_t Idx) override;
112 void beginFunction(IRFunction *F, const char *File, int Line) override;
113 void endFunction() override;
114
115 // -----------------------------------------------------------------------
116 // CodeBuilder overrides — insertion point management.
117 // -----------------------------------------------------------------------
118 void setInsertPointAtEntry() override;
119 void clearInsertPoint() override;
120
121 // -----------------------------------------------------------------------
122 // CodeBuilder overrides — high-level control flow.
123 // -----------------------------------------------------------------------
124 void beginIf(IRValue *Cond, const char *File, int Line) override;
125 void endIf() override;
126 void beginFor(IRValue *IterSlot, IRType IterTy, IRValue *InitVal,
127 IRValue *UpperBoundVal, IRValue *IncVal, bool IsSigned,
128 const char *File, int Line, LoopHints Hints = {}) override;
129 void endFor() override;
130 void beginWhile(std::function<IRValue *()> CondFn, const char *File,
131 int Line) override;
132 void endWhile() override;
133 void createRetVoid() override;
134 void createRet(IRValue *V) override;
135
136 // -----------------------------------------------------------------------
137 // CodeBuilder overrides — arithmetic.
138 // -----------------------------------------------------------------------
139 IRValue *createArith(ArithOp Op, IRValue *LHS, IRValue *RHS,
140 IRType Ty) override;
141
142 // -----------------------------------------------------------------------
143 // CodeBuilder overrides — atomics.
144 // -----------------------------------------------------------------------
145 IRValue *createAtomicAdd(IRValue *Addr, IRValue *Val) override;
146 IRValue *createAtomicSub(IRValue *Addr, IRValue *Val) override;
147 IRValue *createAtomicMax(IRValue *Addr, IRValue *Val) override;
148 IRValue *createAtomicMin(IRValue *Addr, IRValue *Val) override;
149
150 // -----------------------------------------------------------------------
151 // CodeBuilder overrides — comparisons.
152 // -----------------------------------------------------------------------
153 IRValue *createCmp(CmpOp Op, IRValue *LHS, IRValue *RHS, IRType Ty) override;
154
155 // -----------------------------------------------------------------------
156 // CodeBuilder overrides — logical.
157 // -----------------------------------------------------------------------
158 IRValue *createAnd(IRValue *LHS, IRValue *RHS) override;
159 IRValue *createOr(IRValue *LHS, IRValue *RHS) override;
160 IRValue *createXor(IRValue *LHS, IRValue *RHS) override;
161 IRValue *createNot(IRValue *Val) override;
162
163 // -----------------------------------------------------------------------
164 // CodeBuilder overrides — load/store.
165 // -----------------------------------------------------------------------
167 const std::string &Name = "") override;
168 void createStore(IRValue *Val, IRValue *Ptr) override;
169
170 // -----------------------------------------------------------------------
171 // CodeBuilder overrides — casts.
172 // -----------------------------------------------------------------------
173 IRValue *createCast(IRValue *V, IRType FromTy, IRType ToTy) override;
174 IRValue *createBitCast(IRValue *V, IRType DestTy) override;
175 IRValue *createZExt(IRValue *V, IRType DestTy) override;
176
177 // -----------------------------------------------------------------------
178 // CodeBuilder overrides — constants.
179 // -----------------------------------------------------------------------
180 IRValue *getConstantInt(IRType Ty, uint64_t Val) override;
181 IRValue *getConstantFP(IRType Ty, double Val) override;
182
183 // -----------------------------------------------------------------------
184 // CodeBuilder overrides — GEP.
185 // -----------------------------------------------------------------------
186 VarAlloc getElementPtr(IRValue *Base, IRType BaseTy, IRValue *Index,
187 IRType ElemTy) override;
188 VarAlloc getElementPtr(IRValue *Base, IRType BaseTy, size_t Index,
189 IRType ElemTy) override;
190
191 // -----------------------------------------------------------------------
192 // CodeBuilder overrides — calls.
193 // -----------------------------------------------------------------------
194 IRValue *createCall(const std::string &FName, IRType RetTy,
195 const std::vector<IRType> &ArgTys,
196 const std::vector<IRValue *> &Args) override;
197 IRValue *createCall(const std::string &FName, IRType RetTy) override;
198
199 // -----------------------------------------------------------------------
200 // CodeBuilder overrides — storage-aware load/store.
201 // -----------------------------------------------------------------------
202 IRValue *loadScalar(IRValue *Slot, IRType ValueTy) override;
203 void storeScalar(IRValue *Slot, IRValue *Val) override;
204 IRValue *loadAddress(IRValue *Slot, IRType AllocTy) override;
205 void storeAddress(IRValue *Slot, IRValue *Addr) override;
206 IRValue *loadFromPointee(IRValue *Slot, IRType AllocTy,
207 IRType ValueTy) override;
208 void storeToPointee(IRValue *Slot, IRType AllocTy, IRValue *Val) override;
209
210 // -----------------------------------------------------------------------
211 // CodeBuilder overrides — alloc factories.
212 // -----------------------------------------------------------------------
213 VarAlloc allocScalar(const std::string &Name, IRType ValueTy) override;
214 VarAlloc allocPointer(const std::string &Name, IRType ElemTy,
215 unsigned AddrSpace = 0) override;
216 VarAlloc allocArray(const std::string &Name, AddressSpace AS, IRType ElemTy,
217 size_t NElem) override;
218
219 // -----------------------------------------------------------------------
220 // CodeBuilder overrides — GPU kernel support.
221 // -----------------------------------------------------------------------
222#if defined(PROTEUS_ENABLE_CUDA) || defined(PROTEUS_ENABLE_HIP)
223 void setKernel(IRFunction *F) override;
224 void setLaunchBoundsForKernel(IRFunction *F, int MaxThreadsPerBlock,
225 int MinBlocksPerSM) override;
226#endif
227
228private:
229 struct Impl;
230 std::unique_ptr<Impl> PImpl;
231 llvm::Function *F;
232 TargetModelType TargetModel;
233
235 llvm::Function *unwrapFunction(IRFunction *IRF);
236
237 // -----------------------------------------------------------------------
238 // Insertion point management (LLVM-specific extensions).
239 // -----------------------------------------------------------------------
240 void setInsertPoint(llvm::BasicBlock *BB);
241 void setInsertPointBegin(llvm::BasicBlock *BB);
242 llvm::BasicBlock *getInsertBlock();
243
244 // -----------------------------------------------------------------------
245 // Private low-level arithmetic dispatch (called by createArith).
246 // -----------------------------------------------------------------------
247 IRValue *createAdd(IRValue *LHS, IRValue *RHS);
248 IRValue *createFAdd(IRValue *LHS, IRValue *RHS);
249 IRValue *createSub(IRValue *LHS, IRValue *RHS);
250 IRValue *createFSub(IRValue *LHS, IRValue *RHS);
251 IRValue *createMul(IRValue *LHS, IRValue *RHS);
252 IRValue *createFMul(IRValue *LHS, IRValue *RHS);
253 IRValue *createUDiv(IRValue *LHS, IRValue *RHS);
254 IRValue *createSDiv(IRValue *LHS, IRValue *RHS);
255 IRValue *createFDiv(IRValue *LHS, IRValue *RHS);
256 IRValue *createURem(IRValue *LHS, IRValue *RHS);
257 IRValue *createSRem(IRValue *LHS, IRValue *RHS);
258 IRValue *createFRem(IRValue *LHS, IRValue *RHS);
259
260 // -----------------------------------------------------------------------
261 // Private low-level comparison dispatch (called by createCmp).
262 // -----------------------------------------------------------------------
263 IRValue *createICmpEQ(IRValue *LHS, IRValue *RHS);
264 IRValue *createICmpNE(IRValue *LHS, IRValue *RHS);
265 IRValue *createICmpSLT(IRValue *LHS, IRValue *RHS);
266 IRValue *createICmpSGT(IRValue *LHS, IRValue *RHS);
267 IRValue *createICmpSGE(IRValue *LHS, IRValue *RHS);
268 IRValue *createICmpSLE(IRValue *LHS, IRValue *RHS);
269 IRValue *createICmpUGT(IRValue *LHS, IRValue *RHS);
270 IRValue *createICmpUGE(IRValue *LHS, IRValue *RHS);
271 IRValue *createICmpULT(IRValue *LHS, IRValue *RHS);
272 IRValue *createICmpULE(IRValue *LHS, IRValue *RHS);
273 IRValue *createFCmpOEQ(IRValue *LHS, IRValue *RHS);
274 IRValue *createFCmpONE(IRValue *LHS, IRValue *RHS);
275 IRValue *createFCmpOLT(IRValue *LHS, IRValue *RHS);
276 IRValue *createFCmpOLE(IRValue *LHS, IRValue *RHS);
277 IRValue *createFCmpOGT(IRValue *LHS, IRValue *RHS);
278 IRValue *createFCmpOGE(IRValue *LHS, IRValue *RHS);
279 IRValue *createFCmpULT(IRValue *LHS, IRValue *RHS);
280 IRValue *createFCmpULE(IRValue *LHS, IRValue *RHS);
281
282 // -----------------------------------------------------------------------
283 // Private low-level cast dispatch (called by createCast).
284 // -----------------------------------------------------------------------
285 IRValue *createIntCast(IRValue *V, IRType DestTy, bool IsSigned);
286 IRValue *createFPCast(IRValue *V, IRType DestTy);
287 IRValue *createSIToFP(IRValue *V, IRType DestTy);
288 IRValue *createUIToFP(IRValue *V, IRType DestTy);
289 IRValue *createFPToSI(IRValue *V, IRType DestTy);
290 IRValue *createFPToUI(IRValue *V, IRType DestTy);
291
292 // -----------------------------------------------------------------------
293 // Private GEP helpers (called by getElementPtr).
294 // -----------------------------------------------------------------------
295 IRValue *createInBoundsGEP(IRType Ty, IRValue *Ptr,
296 const std::vector<IRValue *> &IdxList,
297 const std::string &Name = "");
298 // NOLINTNEXTLINE
299 IRValue *createConstInBoundsGEP1_64(IRType Ty, IRValue *Ptr, size_t Idx);
300 // NOLINTNEXTLINE
301 IRValue *createConstInBoundsGEP2_64(IRType Ty, IRValue *Ptr, size_t Idx0,
302 size_t Idx1);
303 unsigned getAddressSpaceFromValue(IRValue *PtrVal);
304};
305
306} // namespace proteus
307
308#endif // PROTEUS_FRONTEND_LLVM_CODE_BUILDER_H
char int void ** Args
Definition CompilerInterfaceHost.cpp:22
Definition CodeBuilder.h:66
Definition IRFunction.h:9
Definition IRValue.h:15
Definition LLVMCodeBuilder.h:29
void beginWhile(std::function< IRValue *()> CondFn, const char *File, int Line) override
Definition LLVMCodeBuilder.cpp:383
IRValue * createAtomicSub(IRValue *Addr, IRValue *Val) override
Definition LLVMCodeBuilder.cpp:491
IRValue * createOr(IRValue *LHS, IRValue *RHS) override
Definition LLVMCodeBuilder.cpp:600
IRValue * createArith(ArithOp Op, IRValue *LHS, IRValue *RHS, IRType Ty) override
Definition LLVMCodeBuilder.cpp:731
IRValue * loadScalar(IRValue *Slot, IRType ValueTy) override
Load the value stored directly in Slot (scalar alloca).
Definition LLVMCodeBuilder.cpp:996
llvm::LLVMContext & getContext()
Definition LLVMCodeBuilder.cpp:107
unsigned getAddressSpace(llvm::Type *Ty)
Definition LLVMCodeBuilder.cpp:863
IRValue * createCmp(CmpOp Op, IRValue *LHS, IRValue *RHS, IRType Ty) override
Definition LLVMCodeBuilder.cpp:763
llvm::IRBuilderBase & getIRBuilder()
Get the underlying IRBuilderBase (internal use only).
Definition LLVMCodeBuilder.cpp:91
VarAlloc allocPointer(const std::string &Name, IRType ElemTy, unsigned AddrSpace=0) override
Definition LLVMCodeBuilder.cpp:1039
void beginIf(IRValue *Cond, const char *File, int Line) override
Definition LLVMCodeBuilder.cpp:245
IRFunction * addFunction(const std::string &Name, IRType RetTy, const std::vector< IRType > &ArgTys) override
Definition LLVMCodeBuilder.cpp:115
llvm::Module & getModule()
Definition LLVMCodeBuilder.cpp:99
llvm::BasicBlock * createBasicBlock(const std::string &Name="", llvm::BasicBlock *InsertBefore=nullptr)
Definition LLVMCodeBuilder.cpp:178
IRValue * createAtomicMin(IRValue *Addr, IRValue *Val) override
Definition LLVMCodeBuilder.cpp:511
llvm::Type * getInt32Ty()
Definition LLVMCodeBuilder.cpp:858
void storeScalar(IRValue *Slot, IRValue *Val) override
Store Val directly into Slot (scalar alloca).
Definition LLVMCodeBuilder.cpp:1001
void endWhile() override
Definition LLVMCodeBuilder.cpp:413
IRValue * createZExt(IRValue *V, IRType DestTy) override
Definition LLVMCodeBuilder.cpp:690
VarAlloc allocArray(const std::string &Name, AddressSpace AS, IRType ElemTy, size_t NElem) override
Definition LLVMCodeBuilder.cpp:1048
void createBr(llvm::BasicBlock *Dest)
Definition LLVMCodeBuilder.cpp:624
IRValue * emitAlloca(llvm::Type *Ty, const std::string &Name, AddressSpace AS=AddressSpace::DEFAULT)
Definition LLVMCodeBuilder.cpp:909
void eraseTerminator(llvm::BasicBlock *BB)
Definition LLVMCodeBuilder.cpp:184
IRValue * createBitCast(IRValue *V, IRType DestTy) override
Definition LLVMCodeBuilder.cpp:681
LLVMCodeBuilder(const LLVMCodeBuilder &)=delete
IRValue * createXor(IRValue *LHS, IRValue *RHS) override
Definition LLVMCodeBuilder.cpp:604
void createStore(IRValue *Val, IRValue *Ptr) override
Definition LLVMCodeBuilder.cpp:619
IRValue * getConstantInt(IRType Ty, uint64_t Val) override
Definition LLVMCodeBuilder.cpp:696
llvm::Type * getInt16Ty()
Definition LLVMCodeBuilder.cpp:857
LLVMCodeBuilder(std::unique_ptr< llvm::LLVMContext > Ctx, std::unique_ptr< llvm::Module > Mod, TargetModelType TM=TargetModelType::HOST)
Construct as owner of LLVMContext and Module.
VarAlloc getElementPtr(IRValue *Base, IRType BaseTy, IRValue *Index, IRType ElemTy) override
Definition LLVMCodeBuilder.cpp:811
IRValue * createCast(IRValue *V, IRType FromTy, IRType ToTy) override
Definition LLVMCodeBuilder.cpp:799
llvm::BasicBlock * getUniqueSuccessor(llvm::BasicBlock *BB)
Definition LLVMCodeBuilder.cpp:191
void createRet(IRValue *V) override
Definition LLVMCodeBuilder.cpp:642
void beginFor(IRValue *IterSlot, IRType IterTy, IRValue *InitVal, IRValue *UpperBoundVal, IRValue *IncVal, bool IsSigned, const char *File, int Line, LoopHints Hints={}) override
Definition LLVMCodeBuilder.cpp:290
std::tuple< llvm::BasicBlock *, llvm::BasicBlock * > splitCurrentBlock()
Definition LLVMCodeBuilder.cpp:171
void endFor() override
Definition LLVMCodeBuilder.cpp:366
IRValue * createAtomicAdd(IRValue *Addr, IRValue *Val) override
Definition LLVMCodeBuilder.cpp:481
IRValue * createLoad(IRType Ty, IRValue *Ptr, const std::string &Name="") override
Definition LLVMCodeBuilder.cpp:613
std::unique_ptr< llvm::Module > takeModule()
Transfer ownership of the Module (leaves internal pointer null).
Definition LLVMCodeBuilder.cpp:144
IRValue * loadFromPointee(IRValue *Slot, IRType AllocTy, IRType ValueTy) override
Dereference the pointer stored in Slot, then load the pointee.
Definition LLVMCodeBuilder.cpp:1014
IRValue * createAnd(IRValue *LHS, IRValue *RHS) override
Definition LLVMCodeBuilder.cpp:596
std::unique_ptr< llvm::LLVMContext > takeLLVMContext()
Transfer ownership of the LLVMContext (leaves internal pointer null).
Definition LLVMCodeBuilder.cpp:140
bool isIntegerTy(llvm::Type *Ty)
Definition LLVMCodeBuilder.cpp:875
TargetModelType getTargetModel() const override
Definition LLVMCodeBuilder.h:37
void storeToPointee(IRValue *Slot, IRType AllocTy, IRValue *Val) override
Dereference the pointer stored in Slot, then store Val to it.
Definition LLVMCodeBuilder.cpp:1022
void endFunction() override
Definition LLVMCodeBuilder.cpp:232
llvm::Type * getInt64Ty()
Definition LLVMCodeBuilder.cpp:859
LLVMCodeBuilder & operator=(const LLVMCodeBuilder &)=delete
llvm::Type * getPointerType(llvm::Type *ElemTy, unsigned AS)
Definition LLVMCodeBuilder.cpp:851
llvm::Function & getFunction()
Definition LLVMCodeBuilder.cpp:93
llvm::Type * getFloatTy()
Definition LLVMCodeBuilder.cpp:860
IRValue * getConstantFP(IRType Ty, double Val) override
Definition LLVMCodeBuilder.cpp:699
IRValue * createAtomicMax(IRValue *Addr, IRValue *Val) override
Definition LLVMCodeBuilder.cpp:501
IRValue * loadAddress(IRValue *Slot, IRType AllocTy) override
Load the pointer stored in Slot (pointer alloca).
Definition LLVMCodeBuilder.cpp:1005
void storeAddress(IRValue *Slot, IRValue *Addr) override
Store Addr into Slot (pointer alloca).
Definition LLVMCodeBuilder.cpp:1010
void pushScope(const char *File, int Line, ScopeKind Kind, llvm::BasicBlock *NextBlock)
Definition LLVMCodeBuilder.cpp:200
void setInsertPointAtEntry() override
Definition LLVMCodeBuilder.cpp:158
void createRetVoid() override
Definition LLVMCodeBuilder.cpp:631
void createCondBr(IRValue *Cond, llvm::BasicBlock *True, llvm::BasicBlock *False)
Definition LLVMCodeBuilder.cpp:626
llvm::Type * getPointerTypeUnqual(llvm::Type *ElemTy)
Definition LLVMCodeBuilder.cpp:854
IRValue * emitArrayCreate(llvm::Type *Ty, AddressSpace AT, const std::string &Name)
Definition LLVMCodeBuilder.cpp:922
VarAlloc allocScalar(const std::string &Name, IRType ValueTy) override
Definition LLVMCodeBuilder.cpp:1033
void beginFunction(IRFunction *F, const char *File, int Line) override
Set F as the active function and begin IR emission.
Definition LLVMCodeBuilder.cpp:207
void endIf() override
Definition LLVMCodeBuilder.cpp:274
void clearInsertPoint() override
Definition LLVMCodeBuilder.cpp:164
IRValue * getArg(IRFunction *F, size_t Idx) override
Return the Nth argument of F as an IRValue.
Definition LLVMCodeBuilder.cpp:1058
void setFunctionName(IRFunction *F, const std::string &Name) override
Rename the function identified by F.
Definition LLVMCodeBuilder.cpp:135
IRValue * createNot(IRValue *Val) override
Definition LLVMCodeBuilder.cpp:608
bool isFloatingPointTy(llvm::Type *Ty)
Definition LLVMCodeBuilder.cpp:876
IRValue * createCall(const std::string &FName, IRType RetTy, const std::vector< IRType > &ArgTys, const std::vector< IRValue * > &Args) override
Definition LLVMCodeBuilder.cpp:881
Definition CompiledLibrary.h:7
Definition MemoryCache.h:26
AddressSpace
Definition AddressSpace.h:6
TargetModelType
Definition TargetModel.h:8
ArithOp
Semantic arithmetic operation selector.
Definition CodeBuilder.h:43
CmpOp
Semantic comparison operation selector.
Definition CodeBuilder.h:46
void setLaunchBoundsForKernel(Function &F, int MaxThreadsPerSM, int MinBlocksPerSM=0)
Definition CoreLLVMCUDA.h:87
ScopeKind
Definition CodeBuilder.h:40
Definition IRType.h:34
Definition CodeBuilder.h:21
Definition CodeBuilder.h:29