1 //===-- CGBuilder.h - Choose IRBuilder implementation ----------*- C++ -*-===//
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 #ifndef LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H
10 #define LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H
14 #include "CodeGenTypeCache.h"
15 #include "llvm/Analysis/Utils/Local.h"
16 #include "llvm/IR/DataLayout.h"
17 #include "llvm/IR/GEPNoWrapFlags.h"
18 #include "llvm/IR/IRBuilder.h"
19 #include "llvm/IR/Type.h"
25 class CodeGenFunction
;
27 /// This is an IRBuilder insertion helper that forwards to
28 /// CodeGenFunction::InsertHelper, which adds necessary metadata to
30 class CGBuilderInserter final
: public llvm::IRBuilderDefaultInserter
{
34 CGBuilderInserter() = default;
35 explicit CGBuilderInserter(CodeGenFunction
*CGF
) : CGF(CGF
) {}
37 /// This forwards to CodeGenFunction::InsertHelper.
38 void InsertHelper(llvm::Instruction
*I
, const llvm::Twine
&Name
,
39 llvm::BasicBlock::iterator InsertPt
) const override
;
42 CodeGenFunction
*CGF
= nullptr;
45 typedef CGBuilderInserter CGBuilderInserterTy
;
47 typedef llvm::IRBuilder
<llvm::ConstantFolder
, CGBuilderInserterTy
>
50 class CGBuilderTy
: public CGBuilderBaseTy
{
53 /// Storing a reference to the type cache here makes it a lot easier
54 /// to build natural-feeling, target-specific IR.
55 const CodeGenTypeCache
&TypeCache
;
57 CodeGenFunction
*getCGF() const { return getInserter().CGF
; }
59 llvm::Value
*emitRawPointerFromAddress(Address Addr
) const {
60 return Addr
.getBasePointer();
63 template <bool IsInBounds
>
64 Address
createConstGEP2_32(Address Addr
, unsigned Idx0
, unsigned Idx1
,
65 const llvm::Twine
&Name
) {
66 const llvm::DataLayout
&DL
= BB
->getDataLayout();
67 llvm::GetElementPtrInst
*GEP
;
69 GEP
= cast
<llvm::GetElementPtrInst
>(CreateConstInBoundsGEP2_32(
70 Addr
.getElementType(), emitRawPointerFromAddress(Addr
), Idx0
, Idx1
,
73 GEP
= cast
<llvm::GetElementPtrInst
>(CreateConstGEP2_32(
74 Addr
.getElementType(), emitRawPointerFromAddress(Addr
), Idx0
, Idx1
,
77 DL
.getIndexSizeInBits(Addr
.getType()->getPointerAddressSpace()), 0,
79 if (!GEP
->accumulateConstantOffset(DL
, Offset
))
80 llvm_unreachable("offset of GEP with constants is always computable");
81 return Address(GEP
, GEP
->getResultElementType(),
82 Addr
.getAlignment().alignmentAtOffset(
83 CharUnits::fromQuantity(Offset
.getSExtValue())),
84 IsInBounds
? Addr
.isKnownNonNull() : NotKnownNonNull
);
88 CGBuilderTy(const CodeGenTypeCache
&TypeCache
, llvm::LLVMContext
&C
)
89 : CGBuilderBaseTy(C
), TypeCache(TypeCache
) {}
90 CGBuilderTy(const CodeGenTypeCache
&TypeCache
, llvm::LLVMContext
&C
,
91 const llvm::ConstantFolder
&F
,
92 const CGBuilderInserterTy
&Inserter
)
93 : CGBuilderBaseTy(C
, F
, Inserter
), TypeCache(TypeCache
) {}
94 CGBuilderTy(const CodeGenTypeCache
&TypeCache
, llvm::Instruction
*I
)
95 : CGBuilderBaseTy(I
), TypeCache(TypeCache
) {}
96 CGBuilderTy(const CodeGenTypeCache
&TypeCache
, llvm::BasicBlock
*BB
)
97 : CGBuilderBaseTy(BB
), TypeCache(TypeCache
) {}
99 llvm::ConstantInt
*getSize(CharUnits N
) {
100 return llvm::ConstantInt::get(TypeCache
.SizeTy
, N
.getQuantity());
102 llvm::ConstantInt
*getSize(uint64_t N
) {
103 return llvm::ConstantInt::get(TypeCache
.SizeTy
, N
);
106 // Note that we intentionally hide the CreateLoad APIs that don't
107 // take an alignment.
108 llvm::LoadInst
*CreateLoad(Address Addr
, const llvm::Twine
&Name
= "") {
109 return CreateAlignedLoad(Addr
.getElementType(),
110 emitRawPointerFromAddress(Addr
),
111 Addr
.getAlignment().getAsAlign(), Name
);
113 llvm::LoadInst
*CreateLoad(Address Addr
, const char *Name
) {
114 // This overload is required to prevent string literals from
115 // ending up in the IsVolatile overload.
116 return CreateAlignedLoad(Addr
.getElementType(),
117 emitRawPointerFromAddress(Addr
),
118 Addr
.getAlignment().getAsAlign(), Name
);
120 llvm::LoadInst
*CreateLoad(Address Addr
, bool IsVolatile
,
121 const llvm::Twine
&Name
= "") {
122 return CreateAlignedLoad(
123 Addr
.getElementType(), emitRawPointerFromAddress(Addr
),
124 Addr
.getAlignment().getAsAlign(), IsVolatile
, Name
);
127 using CGBuilderBaseTy::CreateAlignedLoad
;
128 llvm::LoadInst
*CreateAlignedLoad(llvm::Type
*Ty
, llvm::Value
*Addr
,
130 const llvm::Twine
&Name
= "") {
131 return CreateAlignedLoad(Ty
, Addr
, Align
.getAsAlign(), Name
);
134 // Note that we intentionally hide the CreateStore APIs that don't
135 // take an alignment.
136 llvm::StoreInst
*CreateStore(llvm::Value
*Val
, Address Addr
,
137 bool IsVolatile
= false) {
138 return CreateAlignedStore(Val
, emitRawPointerFromAddress(Addr
),
139 Addr
.getAlignment().getAsAlign(), IsVolatile
);
142 using CGBuilderBaseTy::CreateAlignedStore
;
143 llvm::StoreInst
*CreateAlignedStore(llvm::Value
*Val
, llvm::Value
*Addr
,
145 bool IsVolatile
= false) {
146 return CreateAlignedStore(Val
, Addr
, Align
.getAsAlign(), IsVolatile
);
149 // FIXME: these "default-aligned" APIs should be removed,
150 // but I don't feel like fixing all the builtin code right now.
151 llvm::StoreInst
*CreateDefaultAlignedStore(llvm::Value
*Val
,
153 bool IsVolatile
= false) {
154 return CGBuilderBaseTy::CreateStore(Val
, Addr
, IsVolatile
);
157 /// Emit a load from an i1 flag variable.
158 llvm::LoadInst
*CreateFlagLoad(llvm::Value
*Addr
,
159 const llvm::Twine
&Name
= "") {
160 return CreateAlignedLoad(getInt1Ty(), Addr
, CharUnits::One(), Name
);
163 /// Emit a store to an i1 flag variable.
164 llvm::StoreInst
*CreateFlagStore(bool Value
, llvm::Value
*Addr
) {
165 return CreateAlignedStore(getInt1(Value
), Addr
, CharUnits::One());
168 llvm::AtomicCmpXchgInst
*
169 CreateAtomicCmpXchg(Address Addr
, llvm::Value
*Cmp
, llvm::Value
*New
,
170 llvm::AtomicOrdering SuccessOrdering
,
171 llvm::AtomicOrdering FailureOrdering
,
172 llvm::SyncScope::ID SSID
= llvm::SyncScope::System
) {
173 return CGBuilderBaseTy::CreateAtomicCmpXchg(
174 Addr
.emitRawPointer(*getCGF()), Cmp
, New
,
175 Addr
.getAlignment().getAsAlign(), SuccessOrdering
, FailureOrdering
,
179 llvm::AtomicRMWInst
*
180 CreateAtomicRMW(llvm::AtomicRMWInst::BinOp Op
, Address Addr
, llvm::Value
*Val
,
181 llvm::AtomicOrdering Ordering
,
182 llvm::SyncScope::ID SSID
= llvm::SyncScope::System
) {
183 return CGBuilderBaseTy::CreateAtomicRMW(
184 Op
, Addr
.emitRawPointer(*getCGF()), Val
,
185 Addr
.getAlignment().getAsAlign(), Ordering
, SSID
);
188 using CGBuilderBaseTy::CreateAddrSpaceCast
;
189 Address
CreateAddrSpaceCast(Address Addr
, llvm::Type
*Ty
,
190 llvm::Type
*ElementTy
,
191 const llvm::Twine
&Name
= "") {
192 if (!Addr
.hasOffset())
193 return Address(CreateAddrSpaceCast(Addr
.getBasePointer(), Ty
, Name
),
194 ElementTy
, Addr
.getAlignment(), Addr
.getPointerAuthInfo(),
195 /*Offset=*/nullptr, Addr
.isKnownNonNull());
196 // Eagerly force a raw address if these is an offset.
198 CreateAddrSpaceCast(Addr
.emitRawPointer(*getCGF()), Ty
, Name
),
199 ElementTy
, Addr
.getAlignment(), Addr
.isKnownNonNull());
202 using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast
;
203 Address
CreatePointerBitCastOrAddrSpaceCast(Address Addr
, llvm::Type
*Ty
,
204 llvm::Type
*ElementTy
,
205 const llvm::Twine
&Name
= "") {
206 if (Addr
.getType()->getAddressSpace() == Ty
->getPointerAddressSpace())
207 return Addr
.withElementType(ElementTy
);
208 return CreateAddrSpaceCast(Addr
, Ty
, ElementTy
, Name
);
212 /// %addr = {T1, T2...}* ...
214 /// %name = getelementptr inbounds nuw %addr, i32 0, i32 index
216 /// This API assumes that drilling into a struct like this is always an
217 /// inbounds and nuw operation.
218 using CGBuilderBaseTy::CreateStructGEP
;
219 Address
CreateStructGEP(Address Addr
, unsigned Index
,
220 const llvm::Twine
&Name
= "") {
221 llvm::StructType
*ElTy
= cast
<llvm::StructType
>(Addr
.getElementType());
222 const llvm::DataLayout
&DL
= BB
->getDataLayout();
223 const llvm::StructLayout
*Layout
= DL
.getStructLayout(ElTy
);
224 auto Offset
= CharUnits::fromQuantity(Layout
->getElementOffset(Index
));
226 return Address(CreateStructGEP(Addr
.getElementType(), Addr
.getBasePointer(),
228 ElTy
->getElementType(Index
),
229 Addr
.getAlignment().alignmentAtOffset(Offset
),
230 Addr
.isKnownNonNull());
234 /// %addr = [n x T]* ...
236 /// %name = getelementptr inbounds %addr, i64 0, i64 index
237 /// where i64 is actually the target word size.
239 /// This API assumes that drilling into an array like this is always
240 /// an inbounds operation.
241 Address
CreateConstArrayGEP(Address Addr
, uint64_t Index
,
242 const llvm::Twine
&Name
= "") {
243 llvm::ArrayType
*ElTy
= cast
<llvm::ArrayType
>(Addr
.getElementType());
244 const llvm::DataLayout
&DL
= BB
->getDataLayout();
246 CharUnits::fromQuantity(DL
.getTypeAllocSize(ElTy
->getElementType()));
249 CreateInBoundsGEP(Addr
.getElementType(), Addr
.getBasePointer(),
250 {getSize(CharUnits::Zero()), getSize(Index
)}, Name
),
251 ElTy
->getElementType(),
252 Addr
.getAlignment().alignmentAtOffset(Index
* EltSize
),
253 Addr
.isKnownNonNull());
259 /// %name = getelementptr inbounds %addr, i64 index
260 /// where i64 is actually the target word size.
261 Address
CreateConstInBoundsGEP(Address Addr
, uint64_t Index
,
262 const llvm::Twine
&Name
= "") {
263 llvm::Type
*ElTy
= Addr
.getElementType();
264 const llvm::DataLayout
&DL
= BB
->getDataLayout();
265 CharUnits EltSize
= CharUnits::fromQuantity(DL
.getTypeAllocSize(ElTy
));
268 CreateInBoundsGEP(ElTy
, Addr
.getBasePointer(), getSize(Index
), Name
),
269 ElTy
, Addr
.getAlignment().alignmentAtOffset(Index
* EltSize
),
270 Addr
.isKnownNonNull());
276 /// %name = getelementptr inbounds %addr, i64 index
277 /// where i64 is actually the target word size.
278 Address
CreateConstGEP(Address Addr
, uint64_t Index
,
279 const llvm::Twine
&Name
= "") {
280 llvm::Type
*ElTy
= Addr
.getElementType();
281 const llvm::DataLayout
&DL
= BB
->getDataLayout();
282 CharUnits EltSize
= CharUnits::fromQuantity(DL
.getTypeAllocSize(ElTy
));
284 return Address(CreateGEP(ElTy
, Addr
.getBasePointer(), getSize(Index
), Name
),
285 Addr
.getElementType(),
286 Addr
.getAlignment().alignmentAtOffset(Index
* EltSize
));
289 /// Create GEP with single dynamic index. The address alignment is reduced
290 /// according to the element size.
291 using CGBuilderBaseTy::CreateGEP
;
292 Address
CreateGEP(CodeGenFunction
&CGF
, Address Addr
, llvm::Value
*Index
,
293 const llvm::Twine
&Name
= "") {
294 const llvm::DataLayout
&DL
= BB
->getDataLayout();
296 CharUnits::fromQuantity(DL
.getTypeAllocSize(Addr
.getElementType()));
299 CreateGEP(Addr
.getElementType(), Addr
.emitRawPointer(CGF
), Index
, Name
),
300 Addr
.getElementType(),
301 Addr
.getAlignment().alignmentOfArrayElement(EltSize
));
304 /// Given a pointer to i8, adjust it by a given constant offset.
305 Address
CreateConstInBoundsByteGEP(Address Addr
, CharUnits Offset
,
306 const llvm::Twine
&Name
= "") {
307 assert(Addr
.getElementType() == TypeCache
.Int8Ty
);
309 CreateInBoundsGEP(Addr
.getElementType(), Addr
.getBasePointer(),
310 getSize(Offset
), Name
),
311 Addr
.getElementType(), Addr
.getAlignment().alignmentAtOffset(Offset
),
312 Addr
.isKnownNonNull());
315 Address
CreateConstByteGEP(Address Addr
, CharUnits Offset
,
316 const llvm::Twine
&Name
= "") {
317 assert(Addr
.getElementType() == TypeCache
.Int8Ty
);
318 return Address(CreateGEP(Addr
.getElementType(), Addr
.getBasePointer(),
319 getSize(Offset
), Name
),
320 Addr
.getElementType(),
321 Addr
.getAlignment().alignmentAtOffset(Offset
));
324 using CGBuilderBaseTy::CreateConstInBoundsGEP2_32
;
325 Address
CreateConstInBoundsGEP2_32(Address Addr
, unsigned Idx0
, unsigned Idx1
,
326 const llvm::Twine
&Name
= "") {
327 return createConstGEP2_32
<true>(Addr
, Idx0
, Idx1
, Name
);
330 using CGBuilderBaseTy::CreateConstGEP2_32
;
331 Address
CreateConstGEP2_32(Address Addr
, unsigned Idx0
, unsigned Idx1
,
332 const llvm::Twine
&Name
= "") {
333 return createConstGEP2_32
<false>(Addr
, Idx0
, Idx1
, Name
);
336 Address
CreateGEP(Address Addr
, ArrayRef
<llvm::Value
*> IdxList
,
337 llvm::Type
*ElementType
, CharUnits Align
,
338 const Twine
&Name
= "",
339 llvm::GEPNoWrapFlags NW
= llvm::GEPNoWrapFlags::none()) {
340 llvm::Value
*Ptr
= emitRawPointerFromAddress(Addr
);
341 return RawAddress(CreateGEP(Addr
.getElementType(), Ptr
, IdxList
, Name
, NW
),
345 using CGBuilderBaseTy::CreateInBoundsGEP
;
346 Address
CreateInBoundsGEP(Address Addr
, ArrayRef
<llvm::Value
*> IdxList
,
347 llvm::Type
*ElementType
, CharUnits Align
,
348 const Twine
&Name
= "") {
349 return RawAddress(CreateInBoundsGEP(Addr
.getElementType(),
350 emitRawPointerFromAddress(Addr
),
352 ElementType
, Align
, Addr
.isKnownNonNull());
355 using CGBuilderBaseTy::CreateIsNull
;
356 llvm::Value
*CreateIsNull(Address Addr
, const Twine
&Name
= "") {
357 if (!Addr
.hasOffset())
358 return CreateIsNull(Addr
.getBasePointer(), Name
);
359 // The pointer isn't null if Addr has an offset since offsets can always
360 // be applied inbound.
361 return llvm::ConstantInt::getFalse(Context
);
364 using CGBuilderBaseTy::CreateMemCpy
;
365 llvm::CallInst
*CreateMemCpy(Address Dest
, Address Src
, llvm::Value
*Size
,
366 bool IsVolatile
= false) {
367 llvm::Value
*DestPtr
= emitRawPointerFromAddress(Dest
);
368 llvm::Value
*SrcPtr
= emitRawPointerFromAddress(Src
);
369 return CreateMemCpy(DestPtr
, Dest
.getAlignment().getAsAlign(), SrcPtr
,
370 Src
.getAlignment().getAsAlign(), Size
, IsVolatile
);
372 llvm::CallInst
*CreateMemCpy(Address Dest
, Address Src
, uint64_t Size
,
373 bool IsVolatile
= false) {
374 llvm::Value
*DestPtr
= emitRawPointerFromAddress(Dest
);
375 llvm::Value
*SrcPtr
= emitRawPointerFromAddress(Src
);
376 return CreateMemCpy(DestPtr
, Dest
.getAlignment().getAsAlign(), SrcPtr
,
377 Src
.getAlignment().getAsAlign(), Size
, IsVolatile
);
380 using CGBuilderBaseTy::CreateMemCpyInline
;
381 llvm::CallInst
*CreateMemCpyInline(Address Dest
, Address Src
, uint64_t Size
) {
382 llvm::Value
*DestPtr
= emitRawPointerFromAddress(Dest
);
383 llvm::Value
*SrcPtr
= emitRawPointerFromAddress(Src
);
384 return CreateMemCpyInline(DestPtr
, Dest
.getAlignment().getAsAlign(), SrcPtr
,
385 Src
.getAlignment().getAsAlign(), getInt64(Size
));
388 using CGBuilderBaseTy::CreateMemMove
;
389 llvm::CallInst
*CreateMemMove(Address Dest
, Address Src
, llvm::Value
*Size
,
390 bool IsVolatile
= false) {
391 llvm::Value
*DestPtr
= emitRawPointerFromAddress(Dest
);
392 llvm::Value
*SrcPtr
= emitRawPointerFromAddress(Src
);
393 return CreateMemMove(DestPtr
, Dest
.getAlignment().getAsAlign(), SrcPtr
,
394 Src
.getAlignment().getAsAlign(), Size
, IsVolatile
);
397 using CGBuilderBaseTy::CreateMemSet
;
398 llvm::CallInst
*CreateMemSet(Address Dest
, llvm::Value
*Value
,
399 llvm::Value
*Size
, bool IsVolatile
= false) {
400 return CreateMemSet(emitRawPointerFromAddress(Dest
), Value
, Size
,
401 Dest
.getAlignment().getAsAlign(), IsVolatile
);
404 using CGBuilderBaseTy::CreateMemSetInline
;
405 llvm::CallInst
*CreateMemSetInline(Address Dest
, llvm::Value
*Value
,
407 return CreateMemSetInline(emitRawPointerFromAddress(Dest
),
408 Dest
.getAlignment().getAsAlign(), Value
,
412 using CGBuilderBaseTy::CreatePreserveStructAccessIndex
;
413 Address
CreatePreserveStructAccessIndex(Address Addr
, unsigned Index
,
415 llvm::MDNode
*DbgInfo
) {
416 llvm::StructType
*ElTy
= cast
<llvm::StructType
>(Addr
.getElementType());
417 const llvm::DataLayout
&DL
= BB
->getDataLayout();
418 const llvm::StructLayout
*Layout
= DL
.getStructLayout(ElTy
);
419 auto Offset
= CharUnits::fromQuantity(Layout
->getElementOffset(Index
));
422 CreatePreserveStructAccessIndex(ElTy
, emitRawPointerFromAddress(Addr
),
423 Index
, FieldIndex
, DbgInfo
),
424 ElTy
->getElementType(Index
),
425 Addr
.getAlignment().alignmentAtOffset(Offset
));
428 using CGBuilderBaseTy::CreatePreserveUnionAccessIndex
;
429 Address
CreatePreserveUnionAccessIndex(Address Addr
, unsigned FieldIndex
,
430 llvm::MDNode
*DbgInfo
) {
431 Addr
.replaceBasePointer(CreatePreserveUnionAccessIndex(
432 Addr
.getBasePointer(), FieldIndex
, DbgInfo
));
436 using CGBuilderBaseTy::CreateLaunderInvariantGroup
;
437 Address
CreateLaunderInvariantGroup(Address Addr
) {
438 Addr
.replaceBasePointer(CreateLaunderInvariantGroup(Addr
.getBasePointer()));
442 using CGBuilderBaseTy::CreateStripInvariantGroup
;
443 Address
CreateStripInvariantGroup(Address Addr
) {
444 Addr
.replaceBasePointer(CreateStripInvariantGroup(Addr
.getBasePointer()));
449 } // end namespace CodeGen
450 } // end namespace clang