9#ifndef LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H
10#define LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H
16#include "llvm/Analysis/TargetFolder.h"
17#include "llvm/Analysis/Utils/Local.h"
18#include "llvm/IR/DataLayout.h"
19#include "llvm/IR/GEPNoWrapFlags.h"
20#include "llvm/IR/IRBuilder.h"
21#include "llvm/IR/Type.h"
40 void InsertHelper(llvm::Instruction *I,
const llvm::Twine &Name,
41 llvm::BasicBlock::iterator InsertPt)
const;
49typedef llvm::IRBuilder<llvm::TargetFolder, CGBuilderInserterTy>
61 llvm::Value *emitRawPointerFromAddress(
Address Addr)
const {
62 return Addr.getBasePointer();
65 template <
bool IsInBounds>
67 const llvm::Twine &Name) {
68 const llvm::DataLayout &DL = getDataLayout();
72 emitRawPointerFromAddress(
Addr), Idx0,
76 emitRawPointerFromAddress(
Addr), Idx0, Idx1, Name);
78 DL.getIndexSizeInBits(
Addr.getType()->getPointerAddressSpace()), 0,
80 if (!llvm::GEPOperator::accumulateConstantOffset(
81 Addr.getElementType(), {getInt32(Idx0), getInt32(Idx1)}, DL,
84 "accumulateConstantOffset with constant indices should not fail.");
85 llvm::Type *ElementTy = llvm::GetElementPtrInst::getIndexedType(
86 Addr.getElementType(), {Idx0, Idx1});
88 Addr.getAlignment().alignmentAtOffset(
96 llvm::TargetFolder(CGM.getDataLayout())),
101 llvm::TargetFolder(CGM.getDataLayout()), Inserter),
105 llvm::TargetFolder(CGM.getDataLayout())),
112 return llvm::ConstantInt::getSigned(TypeCache.SizeTy, N.
getQuantity());
115 return llvm::ConstantInt::get(TypeCache.SizeTy, N);
122 emitRawPointerFromAddress(
Addr),
123 Addr.getAlignment().getAsAlign(), Name);
129 emitRawPointerFromAddress(
Addr),
130 Addr.getAlignment().getAsAlign(), Name);
133 const llvm::Twine &Name =
"") {
135 Addr.getElementType(), emitRawPointerFromAddress(
Addr),
136 Addr.getAlignment().getAsAlign(), IsVolatile, Name);
139 using CGBuilderBaseTy::CreateAlignedLoad;
142 const llvm::Twine &Name =
"") {
149 bool IsVolatile =
false) {
151 Addr.getAlignment().getAsAlign(), IsVolatile);
154 using CGBuilderBaseTy::CreateAlignedStore;
157 bool IsVolatile =
false) {
165 bool IsVolatile =
false) {
166 return CGBuilderBaseTy::CreateStore(Val,
Addr, IsVolatile);
171 const llvm::Twine &Name =
"") {
180 llvm::AtomicCmpXchgInst *
182 llvm::AtomicOrdering SuccessOrdering,
183 llvm::AtomicOrdering FailureOrdering,
184 llvm::SyncScope::ID SSID = llvm::SyncScope::System) {
185 return CGBuilderBaseTy::CreateAtomicCmpXchg(
187 Addr.getAlignment().getAsAlign(), SuccessOrdering, FailureOrdering,
191 llvm::AtomicRMWInst *
193 llvm::AtomicOrdering Ordering,
194 llvm::SyncScope::ID SSID = llvm::SyncScope::System) {
195 return CGBuilderBaseTy::CreateAtomicRMW(
196 Op,
Addr.emitRawPointer(*getCGF()), Val,
197 Addr.getAlignment().getAsAlign(), Ordering, SSID);
200 using CGBuilderBaseTy::CreateAddrSpaceCast;
202 llvm::Type *ElementTy,
203 const llvm::Twine &Name =
"") {
204 if (!
Addr.hasOffset())
206 ElementTy,
Addr.getAlignment(),
Addr.getPointerAuthInfo(),
207 nullptr,
Addr.isKnownNonNull());
211 ElementTy,
Addr.getAlignment(),
Addr.isKnownNonNull());
214 using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast;
216 llvm::Type *ElementTy,
217 const llvm::Twine &Name =
"") {
218 if (
Addr.getType()->getAddressSpace() == Ty->getPointerAddressSpace())
219 return Addr.withElementType(ElementTy);
230 using CGBuilderBaseTy::CreateStructGEP;
232 const llvm::Twine &Name =
"") {
234 const llvm::DataLayout &DL = getDataLayout();
235 const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
241 Addr.getAlignment().alignmentAtOffset(Offset),
242 Addr.isKnownNonNull());
254 const llvm::Twine &Name =
"") {
256 const llvm::DataLayout &DL = getDataLayout();
262 {getSize(CharUnits::Zero()), getSize(Index)}, Name),
264 Addr.getAlignment().alignmentAtOffset(Index * EltSize),
265 Addr.isKnownNonNull());
274 const llvm::Twine &Name =
"") {
275 llvm::Type *ElTy =
Addr.getElementType();
276 const llvm::DataLayout &DL = getDataLayout();
281 ElTy,
Addr.getAlignment().alignmentAtOffset(Index * EltSize),
282 Addr.isKnownNonNull());
291 const llvm::Twine &Name =
"") {
292 llvm::Type *ElTy =
Addr.getElementType();
293 const llvm::DataLayout &DL = getDataLayout();
297 Addr.getElementType(),
298 Addr.getAlignment().alignmentAtOffset(Index * EltSize));
303 using CGBuilderBaseTy::CreateGEP;
305 const llvm::Twine &Name =
"") {
306 const llvm::DataLayout &DL = getDataLayout();
312 Addr.getElementType(),
313 Addr.getAlignment().alignmentOfArrayElement(EltSize));
318 const llvm::Twine &Name =
"") {
319 assert(
Addr.getElementType() == TypeCache.Int8Ty);
323 Addr.getElementType(),
Addr.getAlignment().alignmentAtOffset(Offset),
324 Addr.isKnownNonNull());
328 const llvm::Twine &Name =
"") {
329 assert(
Addr.getElementType() == TypeCache.Int8Ty);
332 Addr.getElementType(),
333 Addr.getAlignment().alignmentAtOffset(Offset));
336 using CGBuilderBaseTy::CreateConstInBoundsGEP2_32;
338 const llvm::Twine &Name =
"") {
339 return createConstGEP2_32<true>(
Addr, Idx0, Idx1, Name);
342 using CGBuilderBaseTy::CreateConstGEP2_32;
344 const llvm::Twine &Name =
"") {
345 return createConstGEP2_32<false>(
Addr, Idx0, Idx1, Name);
349 llvm::Type *ElementType,
CharUnits Align,
350 const Twine &Name =
"",
351 llvm::GEPNoWrapFlags NW = llvm::GEPNoWrapFlags::none()) {
352 llvm::Value *Ptr = emitRawPointerFromAddress(
Addr);
357 using CGBuilderBaseTy::CreateInBoundsGEP;
359 llvm::Type *ElementType,
CharUnits Align,
360 const Twine &Name =
"") {
362 emitRawPointerFromAddress(
Addr),
364 ElementType, Align,
Addr.isKnownNonNull());
367 using CGBuilderBaseTy::CreateStructuredGEP;
369 llvm::Value *PtrBase,
371 const Twine &Name =
"") {
374 return CreateStructuredGEP(BaseType, PtrBase, IdxList, Name);
380 llvm::Type *ElementType,
CharUnits Align,
381 const Twine &Name =
"") {
384 emitRawPointerFromAddress(
Addr),
386 ElementType, Align,
Addr.isKnownNonNull());
389 using CGBuilderBaseTy::CreateIsNull;
391 if (!
Addr.hasOffset())
395 return llvm::ConstantInt::getFalse(Context);
398 using CGBuilderBaseTy::CreateMemCpy;
400 bool IsVolatile =
false) {
401 llvm::Value *DestPtr = emitRawPointerFromAddress(Dest);
402 llvm::Value *SrcPtr = emitRawPointerFromAddress(Src);
407 bool IsVolatile =
false) {
408 llvm::Value *DestPtr = emitRawPointerFromAddress(Dest);
409 llvm::Value *SrcPtr = emitRawPointerFromAddress(Src);
414 using CGBuilderBaseTy::CreateMemCpyInline;
416 llvm::Value *DestPtr = emitRawPointerFromAddress(Dest);
417 llvm::Value *SrcPtr = emitRawPointerFromAddress(Src);
422 using CGBuilderBaseTy::CreateMemMove;
424 bool IsVolatile =
false) {
425 llvm::Value *DestPtr = emitRawPointerFromAddress(Dest);
426 llvm::Value *SrcPtr = emitRawPointerFromAddress(Src);
431 using CGBuilderBaseTy::CreateMemSet;
433 llvm::Value *Size,
bool IsVolatile =
false) {
438 using CGBuilderBaseTy::CreateMemSetInline;
446 using CGBuilderBaseTy::CreatePreserveStructAccessIndex;
449 llvm::MDNode *DbgInfo) {
451 const llvm::DataLayout &DL = getDataLayout();
452 const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
457 Index, FieldIndex, DbgInfo),
459 Addr.getAlignment().alignmentAtOffset(Offset));
462 using CGBuilderBaseTy::CreatePreserveUnionAccessIndex;
464 llvm::MDNode *DbgInfo) {
466 Addr.getBasePointer(), FieldIndex, DbgInfo));
470 using CGBuilderBaseTy::CreateLaunderInvariantGroup;
This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit bytes.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits One()
Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
This is an IRBuilder insertion helper that forwards to CodeGenFunction::InsertHelper,...
CGBuilderInserter()=default
void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock::iterator InsertPt) const
This forwards to CodeGenFunction::InsertHelper.
CGBuilderInserter(CodeGenFunction *CGF)
CGBuilderTy(const CodeGenModule &CGM, llvm::BasicBlock *BB)
llvm::LoadInst * CreateLoad(Address Addr, bool IsVolatile, const llvm::Twine &Name="")
llvm::StoreInst * CreateFlagStore(bool Value, llvm::Value *Addr)
Emit a store to an i1 flag variable.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, uint64_t Size, bool IsVolatile=false)
Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, const llvm::Twine &Name="")
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
llvm::CallInst * CreateMemMove(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, llvm::Type *ElementTy, const llvm::Twine &Name="")
llvm::CallInst * CreateMemCpyInline(Address Dest, Address Src, uint64_t Size)
Address CreateAccessChain(bool Logical, Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
llvm::AtomicRMWInst * CreateAtomicRMW(llvm::AtomicRMWInst::BinOp Op, Address Addr, llvm::Value *Val, llvm::AtomicOrdering Ordering, llvm::SyncScope::ID SSID=llvm::SyncScope::System)
Address CreateConstGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, const llvm::Twine &Name="")
Address CreateConstArrayGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = [n x T]* ... produce name = getelementptr inbounds addr, i64 0, i64 index where i64 is a...
llvm::CallInst * CreateMemSetInline(Address Dest, llvm::Value *Value, uint64_t Size)
llvm::StoreInst * CreateDefaultAlignedStore(llvm::Value *Val, llvm::Value *Addr, bool IsVolatile=false)
llvm::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::AtomicCmpXchgInst * CreateAtomicCmpXchg(Address Addr, llvm::Value *Cmp, llvm::Value *New, llvm::AtomicOrdering SuccessOrdering, llvm::AtomicOrdering FailureOrdering, llvm::SyncScope::ID SSID=llvm::SyncScope::System)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Address CreateConstByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Address CreatePreserveStructAccessIndex(Address Addr, unsigned Index, unsigned FieldIndex, llvm::MDNode *DbgInfo)
CGBuilderTy(const CodeGenModule &CGM, llvm::LLVMContext &C, const CGBuilderInserterTy &Inserter)
llvm::LoadInst * CreateFlagLoad(llvm::Value *Addr, const llvm::Twine &Name="")
Emit a load from an i1 flag variable.
Address CreateLaunderInvariantGroup(Address Addr)
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
CGBuilderTy(const CodeGenModule &CGM, llvm::LLVMContext &C)
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
llvm::Value * CreateAccessChain(bool Logical, llvm::Type *BaseType, llvm::Value *PtrBase, ArrayRef< llvm::Value * > IdxList, const Twine &Name="")
Address CreateConstGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = T* ... produce name = getelementptr inbounds addr, i64 index where i64 is actually the t...
llvm::ConstantInt * getSize(CharUnits N)
llvm::LoadInst * CreateLoad(Address Addr, const char *Name)
Address CreatePreserveUnionAccessIndex(Address Addr, unsigned FieldIndex, llvm::MDNode *DbgInfo)
Address CreateAddrSpaceCast(Address Addr, llvm::Type *Ty, llvm::Type *ElementTy, const llvm::Twine &Name="")
Address CreateConstInBoundsGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = T* ... produce name = getelementptr inbounds addr, i64 index where i64 is actually the t...
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
llvm::ConstantInt * getSize(uint64_t N)
CGBuilderTy(const CodeGenModule &CGM, llvm::Instruction *I)
Address CreateGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="", llvm::GEPNoWrapFlags NW=llvm::GEPNoWrapFlags::none())
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
This class organizes the cross-function state that is used while generating LLVM code.
An abstract representation of an aligned address.
CGBuilderInserter CGBuilderInserterTy
llvm::IRBuilder< llvm::TargetFolder, CGBuilderInserterTy > CGBuilderBaseTy
Top level wrappers for InstallAPI frontend operations.
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
This structure provides a set of types that are commonly used during IR emission.