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 override;
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 = BB->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(
103 llvm::TargetFolder(CGM.getDataLayout())),
110 return llvm::ConstantInt::getSigned(TypeCache.SizeTy, N.
getQuantity());
113 return llvm::ConstantInt::get(TypeCache.SizeTy, N);
120 emitRawPointerFromAddress(
Addr),
121 Addr.getAlignment().getAsAlign(), Name);
127 emitRawPointerFromAddress(
Addr),
128 Addr.getAlignment().getAsAlign(), Name);
131 const llvm::Twine &Name =
"") {
133 Addr.getElementType(), emitRawPointerFromAddress(
Addr),
134 Addr.getAlignment().getAsAlign(), IsVolatile, Name);
137 using CGBuilderBaseTy::CreateAlignedLoad;
140 const llvm::Twine &Name =
"") {
147 bool IsVolatile =
false) {
149 Addr.getAlignment().getAsAlign(), IsVolatile);
152 using CGBuilderBaseTy::CreateAlignedStore;
155 bool IsVolatile =
false) {
163 bool IsVolatile =
false) {
164 return CGBuilderBaseTy::CreateStore(Val,
Addr, IsVolatile);
169 const llvm::Twine &Name =
"") {
178 llvm::AtomicCmpXchgInst *
180 llvm::AtomicOrdering SuccessOrdering,
181 llvm::AtomicOrdering FailureOrdering,
182 llvm::SyncScope::ID SSID = llvm::SyncScope::System) {
183 return CGBuilderBaseTy::CreateAtomicCmpXchg(
185 Addr.getAlignment().getAsAlign(), SuccessOrdering, FailureOrdering,
189 llvm::AtomicRMWInst *
191 llvm::AtomicOrdering Ordering,
192 llvm::SyncScope::ID SSID = llvm::SyncScope::System) {
193 return CGBuilderBaseTy::CreateAtomicRMW(
194 Op,
Addr.emitRawPointer(*getCGF()), Val,
195 Addr.getAlignment().getAsAlign(), Ordering, SSID);
198 using CGBuilderBaseTy::CreateAddrSpaceCast;
200 llvm::Type *ElementTy,
201 const llvm::Twine &Name =
"") {
202 if (!
Addr.hasOffset())
204 ElementTy,
Addr.getAlignment(),
Addr.getPointerAuthInfo(),
205 nullptr,
Addr.isKnownNonNull());
209 ElementTy,
Addr.getAlignment(),
Addr.isKnownNonNull());
212 using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast;
214 llvm::Type *ElementTy,
215 const llvm::Twine &Name =
"") {
216 if (
Addr.getType()->getAddressSpace() == Ty->getPointerAddressSpace())
217 return Addr.withElementType(ElementTy);
228 using CGBuilderBaseTy::CreateStructGEP;
230 const llvm::Twine &Name =
"") {
232 const llvm::DataLayout &DL = BB->getDataLayout();
233 const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
239 Addr.getAlignment().alignmentAtOffset(Offset),
240 Addr.isKnownNonNull());
252 const llvm::Twine &Name =
"") {
254 const llvm::DataLayout &DL = BB->getDataLayout();
260 {getSize(CharUnits::Zero()), getSize(Index)}, Name),
262 Addr.getAlignment().alignmentAtOffset(Index * EltSize),
263 Addr.isKnownNonNull());
272 const llvm::Twine &Name =
"") {
273 llvm::Type *ElTy =
Addr.getElementType();
274 const llvm::DataLayout &DL = BB->getDataLayout();
279 ElTy,
Addr.getAlignment().alignmentAtOffset(Index * EltSize),
280 Addr.isKnownNonNull());
289 const llvm::Twine &Name =
"") {
290 llvm::Type *ElTy =
Addr.getElementType();
291 const llvm::DataLayout &DL = BB->getDataLayout();
295 Addr.getElementType(),
296 Addr.getAlignment().alignmentAtOffset(Index * EltSize));
301 using CGBuilderBaseTy::CreateGEP;
303 const llvm::Twine &Name =
"") {
304 const llvm::DataLayout &DL = BB->getDataLayout();
310 Addr.getElementType(),
311 Addr.getAlignment().alignmentOfArrayElement(EltSize));
316 const llvm::Twine &Name =
"") {
317 assert(
Addr.getElementType() == TypeCache.Int8Ty);
321 Addr.getElementType(),
Addr.getAlignment().alignmentAtOffset(Offset),
322 Addr.isKnownNonNull());
326 const llvm::Twine &Name =
"") {
327 assert(
Addr.getElementType() == TypeCache.Int8Ty);
330 Addr.getElementType(),
331 Addr.getAlignment().alignmentAtOffset(Offset));
334 using CGBuilderBaseTy::CreateConstInBoundsGEP2_32;
336 const llvm::Twine &Name =
"") {
337 return createConstGEP2_32<true>(
Addr, Idx0, Idx1, Name);
340 using CGBuilderBaseTy::CreateConstGEP2_32;
342 const llvm::Twine &Name =
"") {
343 return createConstGEP2_32<false>(
Addr, Idx0, Idx1, Name);
347 llvm::Type *ElementType,
CharUnits Align,
348 const Twine &Name =
"",
349 llvm::GEPNoWrapFlags NW = llvm::GEPNoWrapFlags::none()) {
350 llvm::Value *Ptr = emitRawPointerFromAddress(
Addr);
355 using CGBuilderBaseTy::CreateInBoundsGEP;
357 llvm::Type *ElementType,
CharUnits Align,
358 const Twine &Name =
"") {
360 emitRawPointerFromAddress(
Addr),
362 ElementType, Align,
Addr.isKnownNonNull());
365 using CGBuilderBaseTy::CreateIsNull;
367 if (!
Addr.hasOffset())
371 return llvm::ConstantInt::getFalse(Context);
374 using CGBuilderBaseTy::CreateMemCpy;
376 bool IsVolatile =
false) {
377 llvm::Value *DestPtr = emitRawPointerFromAddress(Dest);
378 llvm::Value *SrcPtr = emitRawPointerFromAddress(Src);
383 bool IsVolatile =
false) {
384 llvm::Value *DestPtr = emitRawPointerFromAddress(Dest);
385 llvm::Value *SrcPtr = emitRawPointerFromAddress(Src);
390 using CGBuilderBaseTy::CreateMemCpyInline;
392 llvm::Value *DestPtr = emitRawPointerFromAddress(Dest);
393 llvm::Value *SrcPtr = emitRawPointerFromAddress(Src);
398 using CGBuilderBaseTy::CreateMemMove;
400 bool IsVolatile =
false) {
401 llvm::Value *DestPtr = emitRawPointerFromAddress(Dest);
402 llvm::Value *SrcPtr = emitRawPointerFromAddress(Src);
407 using CGBuilderBaseTy::CreateMemSet;
409 llvm::Value *Size,
bool IsVolatile =
false) {
414 using CGBuilderBaseTy::CreateMemSetInline;
422 using CGBuilderBaseTy::CreatePreserveStructAccessIndex;
425 llvm::MDNode *DbgInfo) {
427 const llvm::DataLayout &DL = BB->getDataLayout();
428 const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
433 Index, FieldIndex, DbgInfo),
435 Addr.getAlignment().alignmentAtOffset(Offset));
438 using CGBuilderBaseTy::CreatePreserveUnionAccessIndex;
440 llvm::MDNode *DbgInfo) {
442 Addr.getBasePointer(), FieldIndex, DbgInfo));
446 using CGBuilderBaseTy::CreateLaunderInvariantGroup;
452 using CGBuilderBaseTy::CreateStripInvariantGroup;
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - 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
CGBuilderInserter(CodeGenFunction *CGF)
void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock::iterator InsertPt) const override
This forwards to CodeGenFunction::InsertHelper.
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)
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="")
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 CreateStripInvariantGroup(Address Addr)
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
The JSON file list parser is used to communicate input to InstallAPI.
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.