1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | #ifndef LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H |
10 | #define LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H |
11 | |
12 | #include "llvm/IR/DataLayout.h" |
13 | #include "llvm/IR/IRBuilder.h" |
14 | #include "Address.h" |
15 | #include "CodeGenTypeCache.h" |
16 | |
17 | namespace clang { |
18 | namespace CodeGen { |
19 | |
20 | class CodeGenFunction; |
21 | |
22 | |
23 | |
24 | |
25 | class CGBuilderInserter : protected llvm::IRBuilderDefaultInserter { |
26 | public: |
27 | CGBuilderInserter() = default; |
28 | explicit CGBuilderInserter(CodeGenFunction *CGF) : CGF(CGF) {} |
29 | |
30 | protected: |
31 | |
32 | void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, |
33 | llvm::BasicBlock *BB, |
34 | llvm::BasicBlock::iterator InsertPt) const; |
35 | private: |
36 | CodeGenFunction *CGF = nullptr; |
37 | }; |
38 | |
39 | typedef CGBuilderInserter CGBuilderInserterTy; |
40 | |
41 | typedef llvm::IRBuilder<llvm::ConstantFolder, CGBuilderInserterTy> |
42 | CGBuilderBaseTy; |
43 | |
44 | class CGBuilderTy : public CGBuilderBaseTy { |
45 | |
46 | |
47 | const CodeGenTypeCache &TypeCache; |
48 | public: |
49 | CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::LLVMContext &C) |
50 | : CGBuilderBaseTy(C), TypeCache(TypeCache) {} |
51 | CGBuilderTy(const CodeGenTypeCache &TypeCache, |
52 | llvm::LLVMContext &C, const llvm::ConstantFolder &F, |
53 | const CGBuilderInserterTy &Inserter) |
54 | : CGBuilderBaseTy(C, F, Inserter), TypeCache(TypeCache) {} |
55 | CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::Instruction *I) |
56 | : CGBuilderBaseTy(I), TypeCache(TypeCache) {} |
57 | CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::BasicBlock *BB) |
58 | : CGBuilderBaseTy(BB), TypeCache(TypeCache) {} |
59 | |
60 | llvm::ConstantInt *getSize(CharUnits N) { |
61 | return llvm::ConstantInt::get(TypeCache.SizeTy, N.getQuantity()); |
62 | } |
63 | llvm::ConstantInt *getSize(uint64_t N) { |
64 | return llvm::ConstantInt::get(TypeCache.SizeTy, N); |
65 | } |
66 | |
67 | |
68 | |
69 | llvm::LoadInst *CreateLoad(Address Addr, const llvm::Twine &Name = "") { |
70 | return CreateAlignedLoad(Addr.getPointer(), |
71 | Addr.getAlignment().getQuantity(), |
72 | Name); |
73 | } |
74 | llvm::LoadInst *CreateLoad(Address Addr, const char *Name) { |
75 | |
76 | |
77 | return CreateAlignedLoad(Addr.getPointer(), |
78 | Addr.getAlignment().getQuantity(), |
79 | Name); |
80 | } |
81 | llvm::LoadInst *CreateLoad(Address Addr, bool IsVolatile, |
82 | const llvm::Twine &Name = "") { |
83 | return CreateAlignedLoad(Addr.getPointer(), |
84 | Addr.getAlignment().getQuantity(), |
85 | IsVolatile, |
86 | Name); |
87 | } |
88 | |
89 | using CGBuilderBaseTy::CreateAlignedLoad; |
90 | llvm::LoadInst *CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, |
91 | const llvm::Twine &Name = "") { |
92 | return CreateAlignedLoad(Addr, Align.getQuantity(), Name); |
93 | } |
94 | llvm::LoadInst *CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, |
95 | const char *Name) { |
96 | return CreateAlignedLoad(Addr, Align.getQuantity(), Name); |
97 | } |
98 | llvm::LoadInst *CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, |
99 | CharUnits Align, |
100 | const llvm::Twine &Name = "") { |
101 | getType()->getPointerElementType() == Ty", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGBuilder.h", 101, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Addr->getType()->getPointerElementType() == Ty); |
102 | return CreateAlignedLoad(Addr, Align.getQuantity(), Name); |
103 | } |
104 | |
105 | |
106 | |
107 | llvm::StoreInst *CreateStore(llvm::Value *Val, Address Addr, |
108 | bool IsVolatile = false) { |
109 | return CreateAlignedStore(Val, Addr.getPointer(), |
110 | Addr.getAlignment().getQuantity(), IsVolatile); |
111 | } |
112 | |
113 | using CGBuilderBaseTy::CreateAlignedStore; |
114 | llvm::StoreInst *CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, |
115 | CharUnits Align, bool IsVolatile = false) { |
116 | return CreateAlignedStore(Val, Addr, Align.getQuantity(), IsVolatile); |
117 | } |
118 | |
119 | |
120 | |
121 | llvm::StoreInst *CreateDefaultAlignedStore(llvm::Value *Val, |
122 | llvm::Value *Addr, |
123 | bool IsVolatile = false) { |
124 | return CGBuilderBaseTy::CreateStore(Val, Addr, IsVolatile); |
125 | } |
126 | |
127 | |
128 | llvm::LoadInst *CreateFlagLoad(llvm::Value *Addr, |
129 | const llvm::Twine &Name = "") { |
130 | getType()->getPointerElementType() == getInt1Ty()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGBuilder.h", 130, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Addr->getType()->getPointerElementType() == getInt1Ty()); |
131 | return CreateAlignedLoad(getInt1Ty(), Addr, CharUnits::One(), Name); |
132 | } |
133 | |
134 | |
135 | llvm::StoreInst *CreateFlagStore(bool Value, llvm::Value *Addr) { |
136 | getType()->getPointerElementType() == getInt1Ty()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGBuilder.h", 136, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Addr->getType()->getPointerElementType() == getInt1Ty()); |
137 | return CreateAlignedStore(getInt1(Value), Addr, CharUnits::One()); |
138 | } |
139 | |
140 | using CGBuilderBaseTy::CreateBitCast; |
141 | Address CreateBitCast(Address Addr, llvm::Type *Ty, |
142 | const llvm::Twine &Name = "") { |
143 | return Address(CreateBitCast(Addr.getPointer(), Ty, Name), |
144 | Addr.getAlignment()); |
145 | } |
146 | |
147 | using CGBuilderBaseTy::CreateAddrSpaceCast; |
148 | Address CreateAddrSpaceCast(Address Addr, llvm::Type *Ty, |
149 | const llvm::Twine &Name = "") { |
150 | return Address(CreateAddrSpaceCast(Addr.getPointer(), Ty, Name), |
151 | Addr.getAlignment()); |
152 | } |
153 | |
154 | |
155 | |
156 | Address CreateElementBitCast(Address Addr, llvm::Type *Ty, |
157 | const llvm::Twine &Name = "") { |
158 | auto PtrTy = Ty->getPointerTo(Addr.getAddressSpace()); |
159 | return CreateBitCast(Addr, PtrTy, Name); |
160 | } |
161 | |
162 | using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast; |
163 | Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, |
164 | const llvm::Twine &Name = "") { |
165 | llvm::Value *Ptr = |
166 | CreatePointerBitCastOrAddrSpaceCast(Addr.getPointer(), Ty, Name); |
167 | return Address(Ptr, Addr.getAlignment()); |
168 | } |
169 | |
170 | |
171 | |
172 | |
173 | |
174 | |
175 | |
176 | |
177 | using CGBuilderBaseTy::CreateStructGEP; |
178 | Address CreateStructGEP(Address Addr, unsigned Index, |
179 | const llvm::Twine &Name = "") { |
180 | llvm::StructType *ElTy = cast<llvm::StructType>(Addr.getElementType()); |
181 | const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); |
182 | const llvm::StructLayout *Layout = DL.getStructLayout(ElTy); |
183 | auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index)); |
184 | |
185 | return Address(CreateStructGEP(Addr.getElementType(), |
186 | Addr.getPointer(), Index, Name), |
187 | Addr.getAlignment().alignmentAtOffset(Offset)); |
188 | } |
189 | |
190 | |
191 | |
192 | |
193 | |
194 | |
195 | |
196 | |
197 | |
198 | Address CreateConstArrayGEP(Address Addr, uint64_t Index, |
199 | const llvm::Twine &Name = "") { |
200 | llvm::ArrayType *ElTy = cast<llvm::ArrayType>(Addr.getElementType()); |
201 | const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); |
202 | CharUnits EltSize = |
203 | CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType())); |
204 | |
205 | return Address( |
206 | CreateInBoundsGEP(Addr.getPointer(), |
207 | {getSize(CharUnits::Zero()), getSize(Index)}, Name), |
208 | Addr.getAlignment().alignmentAtOffset(Index * EltSize)); |
209 | } |
210 | |
211 | |
212 | |
213 | |
214 | |
215 | |
216 | Address CreateConstInBoundsGEP(Address Addr, uint64_t Index, |
217 | const llvm::Twine &Name = "") { |
218 | llvm::Type *ElTy = Addr.getElementType(); |
219 | const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); |
220 | CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy)); |
221 | |
222 | return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(), |
223 | getSize(Index), Name), |
224 | Addr.getAlignment().alignmentAtOffset(Index * EltSize)); |
225 | } |
226 | |
227 | |
228 | |
229 | |
230 | |
231 | |
232 | Address CreateConstGEP(Address Addr, uint64_t Index, |
233 | const llvm::Twine &Name = "") { |
234 | const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); |
235 | CharUnits EltSize = |
236 | CharUnits::fromQuantity(DL.getTypeAllocSize(Addr.getElementType())); |
237 | |
238 | return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(), |
239 | getSize(Index), Name), |
240 | Addr.getAlignment().alignmentAtOffset(Index * EltSize)); |
241 | } |
242 | |
243 | |
244 | Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, |
245 | const llvm::Twine &Name = "") { |
246 | assert(Addr.getElementType() == TypeCache.Int8Ty); |
247 | return Address(CreateInBoundsGEP(Addr.getPointer(), getSize(Offset), Name), |
248 | Addr.getAlignment().alignmentAtOffset(Offset)); |
249 | } |
250 | Address CreateConstByteGEP(Address Addr, CharUnits Offset, |
251 | const llvm::Twine &Name = "") { |
252 | assert(Addr.getElementType() == TypeCache.Int8Ty); |
253 | return Address(CreateGEP(Addr.getPointer(), getSize(Offset), Name), |
254 | Addr.getAlignment().alignmentAtOffset(Offset)); |
255 | } |
256 | |
257 | using CGBuilderBaseTy::CreateConstInBoundsGEP2_32; |
258 | Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, |
259 | const llvm::Twine &Name = "") { |
260 | const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); |
261 | |
262 | auto *GEP = cast<llvm::GetElementPtrInst>(CreateConstInBoundsGEP2_32( |
263 | Addr.getElementType(), Addr.getPointer(), Idx0, Idx1, Name)); |
264 | llvm::APInt Offset( |
265 | DL.getIndexSizeInBits(Addr.getType()->getPointerAddressSpace()), 0, |
266 | ); |
267 | if (!GEP->accumulateConstantOffset(DL, Offset)) |
268 | llvm_unreachable("offset of GEP with constants is always computable"); |
269 | return Address(GEP, Addr.getAlignment().alignmentAtOffset( |
270 | CharUnits::fromQuantity(Offset.getSExtValue()))); |
271 | } |
272 | |
273 | using CGBuilderBaseTy::CreateMemCpy; |
274 | llvm::CallInst *CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, |
275 | bool IsVolatile = false) { |
276 | return CreateMemCpy(Dest.getPointer(), Dest.getAlignment().getQuantity(), |
277 | Src.getPointer(), Src.getAlignment().getQuantity(), |
278 | Size,IsVolatile); |
279 | } |
280 | llvm::CallInst *CreateMemCpy(Address Dest, Address Src, uint64_t Size, |
281 | bool IsVolatile = false) { |
282 | return CreateMemCpy(Dest.getPointer(), Dest.getAlignment().getQuantity(), |
283 | Src.getPointer(), Src.getAlignment().getQuantity(), |
284 | Size, IsVolatile); |
285 | } |
286 | |
287 | using CGBuilderBaseTy::CreateMemMove; |
288 | llvm::CallInst *CreateMemMove(Address Dest, Address Src, llvm::Value *Size, |
289 | bool IsVolatile = false) { |
290 | return CreateMemMove(Dest.getPointer(), Dest.getAlignment().getQuantity(), |
291 | Src.getPointer(), Src.getAlignment().getQuantity(), |
292 | Size, IsVolatile); |
293 | } |
294 | |
295 | using CGBuilderBaseTy::CreateMemSet; |
296 | llvm::CallInst *CreateMemSet(Address Dest, llvm::Value *Value, |
297 | llvm::Value *Size, bool IsVolatile = false) { |
298 | return CreateMemSet(Dest.getPointer(), Value, Size, |
299 | Dest.getAlignment().getQuantity(), IsVolatile); |
300 | } |
301 | }; |
302 | |
303 | } |
304 | } |
305 | |
306 | #endif |
307 | |