10b57cec5SDimitry Andric //===-- CGBuilder.h - Choose IRBuilder implementation ----------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H 100b57cec5SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "Address.h" 13*0fca6ea1SDimitry Andric #include "CGValue.h" 140b57cec5SDimitry Andric #include "CodeGenTypeCache.h" 15*0fca6ea1SDimitry Andric #include "llvm/Analysis/Utils/Local.h" 166a5eebc1SDimitry Andric #include "llvm/IR/DataLayout.h" 176a5eebc1SDimitry Andric #include "llvm/IR/IRBuilder.h" 186a5eebc1SDimitry Andric #include "llvm/IR/Type.h" 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric namespace clang { 210b57cec5SDimitry Andric namespace CodeGen { 220b57cec5SDimitry Andric 23*0fca6ea1SDimitry Andric class CGBuilderTy; 240b57cec5SDimitry Andric class CodeGenFunction; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric /// This is an IRBuilder insertion helper that forwards to 270b57cec5SDimitry Andric /// CodeGenFunction::InsertHelper, which adds necessary metadata to 280b57cec5SDimitry Andric /// instructions. 295ffd83dbSDimitry Andric class CGBuilderInserter final : public llvm::IRBuilderDefaultInserter { 30*0fca6ea1SDimitry Andric friend CGBuilderTy; 31*0fca6ea1SDimitry Andric 320b57cec5SDimitry Andric public: 330b57cec5SDimitry Andric CGBuilderInserter() = default; 340b57cec5SDimitry Andric explicit CGBuilderInserter(CodeGenFunction *CGF) : CGF(CGF) {} 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric /// This forwards to CodeGenFunction::InsertHelper. 370b57cec5SDimitry Andric void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, 385ffd83dbSDimitry Andric llvm::BasicBlock::iterator InsertPt) const override; 3981ad6265SDimitry Andric 400b57cec5SDimitry Andric private: 410b57cec5SDimitry Andric CodeGenFunction *CGF = nullptr; 420b57cec5SDimitry Andric }; 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric typedef CGBuilderInserter CGBuilderInserterTy; 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric typedef llvm::IRBuilder<llvm::ConstantFolder, CGBuilderInserterTy> 470b57cec5SDimitry Andric CGBuilderBaseTy; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric class CGBuilderTy : public CGBuilderBaseTy { 50*0fca6ea1SDimitry Andric friend class Address; 51*0fca6ea1SDimitry Andric 520b57cec5SDimitry Andric /// Storing a reference to the type cache here makes it a lot easier 530b57cec5SDimitry Andric /// to build natural-feeling, target-specific IR. 540b57cec5SDimitry Andric const CodeGenTypeCache &TypeCache; 5581ad6265SDimitry Andric 56*0fca6ea1SDimitry Andric CodeGenFunction *getCGF() const { return getInserter().CGF; } 57*0fca6ea1SDimitry Andric 58*0fca6ea1SDimitry Andric llvm::Value *emitRawPointerFromAddress(Address Addr) const { 59*0fca6ea1SDimitry Andric return Addr.getBasePointer(); 60*0fca6ea1SDimitry Andric } 61*0fca6ea1SDimitry Andric 62*0fca6ea1SDimitry Andric template <bool IsInBounds> 63*0fca6ea1SDimitry Andric Address createConstGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, 64*0fca6ea1SDimitry Andric const llvm::Twine &Name) { 65*0fca6ea1SDimitry Andric const llvm::DataLayout &DL = BB->getDataLayout(); 66*0fca6ea1SDimitry Andric llvm::GetElementPtrInst *GEP; 67*0fca6ea1SDimitry Andric if (IsInBounds) 68*0fca6ea1SDimitry Andric GEP = cast<llvm::GetElementPtrInst>(CreateConstInBoundsGEP2_32( 69*0fca6ea1SDimitry Andric Addr.getElementType(), emitRawPointerFromAddress(Addr), Idx0, Idx1, 70*0fca6ea1SDimitry Andric Name)); 71*0fca6ea1SDimitry Andric else 72*0fca6ea1SDimitry Andric GEP = cast<llvm::GetElementPtrInst>(CreateConstGEP2_32( 73*0fca6ea1SDimitry Andric Addr.getElementType(), emitRawPointerFromAddress(Addr), Idx0, Idx1, 74*0fca6ea1SDimitry Andric Name)); 75*0fca6ea1SDimitry Andric llvm::APInt Offset( 76*0fca6ea1SDimitry Andric DL.getIndexSizeInBits(Addr.getType()->getPointerAddressSpace()), 0, 77*0fca6ea1SDimitry Andric /*isSigned=*/true); 78*0fca6ea1SDimitry Andric if (!GEP->accumulateConstantOffset(DL, Offset)) 79*0fca6ea1SDimitry Andric llvm_unreachable("offset of GEP with constants is always computable"); 80*0fca6ea1SDimitry Andric return Address(GEP, GEP->getResultElementType(), 81*0fca6ea1SDimitry Andric Addr.getAlignment().alignmentAtOffset( 82*0fca6ea1SDimitry Andric CharUnits::fromQuantity(Offset.getSExtValue())), 83*0fca6ea1SDimitry Andric IsInBounds ? Addr.isKnownNonNull() : NotKnownNonNull); 84*0fca6ea1SDimitry Andric } 85*0fca6ea1SDimitry Andric 860b57cec5SDimitry Andric public: 870b57cec5SDimitry Andric CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::LLVMContext &C) 880b57cec5SDimitry Andric : CGBuilderBaseTy(C), TypeCache(TypeCache) {} 8981ad6265SDimitry Andric CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::LLVMContext &C, 9081ad6265SDimitry Andric const llvm::ConstantFolder &F, 910b57cec5SDimitry Andric const CGBuilderInserterTy &Inserter) 920b57cec5SDimitry Andric : CGBuilderBaseTy(C, F, Inserter), TypeCache(TypeCache) {} 930b57cec5SDimitry Andric CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::Instruction *I) 940b57cec5SDimitry Andric : CGBuilderBaseTy(I), TypeCache(TypeCache) {} 950b57cec5SDimitry Andric CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::BasicBlock *BB) 960b57cec5SDimitry Andric : CGBuilderBaseTy(BB), TypeCache(TypeCache) {} 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric llvm::ConstantInt *getSize(CharUnits N) { 990b57cec5SDimitry Andric return llvm::ConstantInt::get(TypeCache.SizeTy, N.getQuantity()); 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric llvm::ConstantInt *getSize(uint64_t N) { 1020b57cec5SDimitry Andric return llvm::ConstantInt::get(TypeCache.SizeTy, N); 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric // Note that we intentionally hide the CreateLoad APIs that don't 1060b57cec5SDimitry Andric // take an alignment. 1070b57cec5SDimitry Andric llvm::LoadInst *CreateLoad(Address Addr, const llvm::Twine &Name = "") { 108*0fca6ea1SDimitry Andric return CreateAlignedLoad(Addr.getElementType(), 109*0fca6ea1SDimitry Andric emitRawPointerFromAddress(Addr), 1105ffd83dbSDimitry Andric Addr.getAlignment().getAsAlign(), Name); 1110b57cec5SDimitry Andric } 1120b57cec5SDimitry Andric llvm::LoadInst *CreateLoad(Address Addr, const char *Name) { 1130b57cec5SDimitry Andric // This overload is required to prevent string literals from 1140b57cec5SDimitry Andric // ending up in the IsVolatile overload. 115*0fca6ea1SDimitry Andric return CreateAlignedLoad(Addr.getElementType(), 116*0fca6ea1SDimitry Andric emitRawPointerFromAddress(Addr), 1175ffd83dbSDimitry Andric Addr.getAlignment().getAsAlign(), Name); 1180b57cec5SDimitry Andric } 1190b57cec5SDimitry Andric llvm::LoadInst *CreateLoad(Address Addr, bool IsVolatile, 1200b57cec5SDimitry Andric const llvm::Twine &Name = "") { 121*0fca6ea1SDimitry Andric return CreateAlignedLoad( 122*0fca6ea1SDimitry Andric Addr.getElementType(), emitRawPointerFromAddress(Addr), 123*0fca6ea1SDimitry Andric Addr.getAlignment().getAsAlign(), IsVolatile, Name); 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric using CGBuilderBaseTy::CreateAlignedLoad; 1270b57cec5SDimitry Andric llvm::LoadInst *CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, 1280b57cec5SDimitry Andric CharUnits Align, 1290b57cec5SDimitry Andric const llvm::Twine &Name = "") { 130fe6060f1SDimitry Andric return CreateAlignedLoad(Ty, Addr, Align.getAsAlign(), Name); 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric // Note that we intentionally hide the CreateStore APIs that don't 1340b57cec5SDimitry Andric // take an alignment. 1350b57cec5SDimitry Andric llvm::StoreInst *CreateStore(llvm::Value *Val, Address Addr, 1360b57cec5SDimitry Andric bool IsVolatile = false) { 137*0fca6ea1SDimitry Andric return CreateAlignedStore(Val, emitRawPointerFromAddress(Addr), 138480093f4SDimitry Andric Addr.getAlignment().getAsAlign(), IsVolatile); 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric using CGBuilderBaseTy::CreateAlignedStore; 1420b57cec5SDimitry Andric llvm::StoreInst *CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, 14381ad6265SDimitry Andric CharUnits Align, 14481ad6265SDimitry Andric bool IsVolatile = false) { 1455ffd83dbSDimitry Andric return CreateAlignedStore(Val, Addr, Align.getAsAlign(), IsVolatile); 1460b57cec5SDimitry Andric } 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric // FIXME: these "default-aligned" APIs should be removed, 1490b57cec5SDimitry Andric // but I don't feel like fixing all the builtin code right now. 1500b57cec5SDimitry Andric llvm::StoreInst *CreateDefaultAlignedStore(llvm::Value *Val, 1510b57cec5SDimitry Andric llvm::Value *Addr, 1520b57cec5SDimitry Andric bool IsVolatile = false) { 1530b57cec5SDimitry Andric return CGBuilderBaseTy::CreateStore(Val, Addr, IsVolatile); 1540b57cec5SDimitry Andric } 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric /// Emit a load from an i1 flag variable. 1570b57cec5SDimitry Andric llvm::LoadInst *CreateFlagLoad(llvm::Value *Addr, 1580b57cec5SDimitry Andric const llvm::Twine &Name = "") { 1590b57cec5SDimitry Andric return CreateAlignedLoad(getInt1Ty(), Addr, CharUnits::One(), Name); 1600b57cec5SDimitry Andric } 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric /// Emit a store to an i1 flag variable. 1630b57cec5SDimitry Andric llvm::StoreInst *CreateFlagStore(bool Value, llvm::Value *Addr) { 1640b57cec5SDimitry Andric return CreateAlignedStore(getInt1(Value), Addr, CharUnits::One()); 1650b57cec5SDimitry Andric } 1660b57cec5SDimitry Andric 167fe6060f1SDimitry Andric llvm::AtomicCmpXchgInst * 1685f757f3fSDimitry Andric CreateAtomicCmpXchg(Address Addr, llvm::Value *Cmp, llvm::Value *New, 169fe6060f1SDimitry Andric llvm::AtomicOrdering SuccessOrdering, 170fe6060f1SDimitry Andric llvm::AtomicOrdering FailureOrdering, 171fe6060f1SDimitry Andric llvm::SyncScope::ID SSID = llvm::SyncScope::System) { 172fe6060f1SDimitry Andric return CGBuilderBaseTy::CreateAtomicCmpXchg( 173*0fca6ea1SDimitry Andric Addr.emitRawPointer(*getCGF()), Cmp, New, 174*0fca6ea1SDimitry Andric Addr.getAlignment().getAsAlign(), SuccessOrdering, FailureOrdering, 175*0fca6ea1SDimitry Andric SSID); 176fe6060f1SDimitry Andric } 177fe6060f1SDimitry Andric 178fe6060f1SDimitry Andric llvm::AtomicRMWInst * 1795f757f3fSDimitry Andric CreateAtomicRMW(llvm::AtomicRMWInst::BinOp Op, Address Addr, llvm::Value *Val, 1805f757f3fSDimitry Andric llvm::AtomicOrdering Ordering, 181fe6060f1SDimitry Andric llvm::SyncScope::ID SSID = llvm::SyncScope::System) { 182*0fca6ea1SDimitry Andric return CGBuilderBaseTy::CreateAtomicRMW( 183*0fca6ea1SDimitry Andric Op, Addr.emitRawPointer(*getCGF()), Val, 184*0fca6ea1SDimitry Andric Addr.getAlignment().getAsAlign(), Ordering, SSID); 185fe6060f1SDimitry Andric } 186fe6060f1SDimitry Andric 1870b57cec5SDimitry Andric using CGBuilderBaseTy::CreateAddrSpaceCast; 1880b57cec5SDimitry Andric Address CreateAddrSpaceCast(Address Addr, llvm::Type *Ty, 189*0fca6ea1SDimitry Andric llvm::Type *ElementTy, 1900b57cec5SDimitry Andric const llvm::Twine &Name = "") { 191*0fca6ea1SDimitry Andric if (!Addr.hasOffset()) 192*0fca6ea1SDimitry Andric return Address(CreateAddrSpaceCast(Addr.getBasePointer(), Ty, Name), 193*0fca6ea1SDimitry Andric ElementTy, Addr.getAlignment(), Addr.getPointerAuthInfo(), 194*0fca6ea1SDimitry Andric /*Offset=*/nullptr, Addr.isKnownNonNull()); 195*0fca6ea1SDimitry Andric // Eagerly force a raw address if these is an offset. 196*0fca6ea1SDimitry Andric return RawAddress( 197*0fca6ea1SDimitry Andric CreateAddrSpaceCast(Addr.emitRawPointer(*getCGF()), Ty, Name), 198*0fca6ea1SDimitry Andric ElementTy, Addr.getAlignment(), Addr.isKnownNonNull()); 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast; 2020b57cec5SDimitry Andric Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, 20381ad6265SDimitry Andric llvm::Type *ElementTy, 2040b57cec5SDimitry Andric const llvm::Twine &Name = "") { 205*0fca6ea1SDimitry Andric if (Addr.getType()->getAddressSpace() == Ty->getPointerAddressSpace()) 206*0fca6ea1SDimitry Andric return Addr.withElementType(ElementTy); 207*0fca6ea1SDimitry Andric return CreateAddrSpaceCast(Addr, Ty, ElementTy, Name); 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric /// Given 2110b57cec5SDimitry Andric /// %addr = {T1, T2...}* ... 2120b57cec5SDimitry Andric /// produce 2130b57cec5SDimitry Andric /// %name = getelementptr inbounds %addr, i32 0, i32 index 2140b57cec5SDimitry Andric /// 2150b57cec5SDimitry Andric /// This API assumes that drilling into a struct like this is always an 2160b57cec5SDimitry Andric /// inbounds operation. 2170b57cec5SDimitry Andric using CGBuilderBaseTy::CreateStructGEP; 2180b57cec5SDimitry Andric Address CreateStructGEP(Address Addr, unsigned Index, 2190b57cec5SDimitry Andric const llvm::Twine &Name = "") { 2200b57cec5SDimitry Andric llvm::StructType *ElTy = cast<llvm::StructType>(Addr.getElementType()); 221*0fca6ea1SDimitry Andric const llvm::DataLayout &DL = BB->getDataLayout(); 2220b57cec5SDimitry Andric const llvm::StructLayout *Layout = DL.getStructLayout(ElTy); 2230b57cec5SDimitry Andric auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index)); 2240b57cec5SDimitry Andric 225*0fca6ea1SDimitry Andric return Address(CreateStructGEP(Addr.getElementType(), Addr.getBasePointer(), 226*0fca6ea1SDimitry Andric Index, Name), 2270eae32dcSDimitry Andric ElTy->getElementType(Index), 228*0fca6ea1SDimitry Andric Addr.getAlignment().alignmentAtOffset(Offset), 229*0fca6ea1SDimitry Andric Addr.isKnownNonNull()); 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric /// Given 2330b57cec5SDimitry Andric /// %addr = [n x T]* ... 2340b57cec5SDimitry Andric /// produce 2350b57cec5SDimitry Andric /// %name = getelementptr inbounds %addr, i64 0, i64 index 2360b57cec5SDimitry Andric /// where i64 is actually the target word size. 2370b57cec5SDimitry Andric /// 2380b57cec5SDimitry Andric /// This API assumes that drilling into an array like this is always 2390b57cec5SDimitry Andric /// an inbounds operation. 2400b57cec5SDimitry Andric Address CreateConstArrayGEP(Address Addr, uint64_t Index, 2410b57cec5SDimitry Andric const llvm::Twine &Name = "") { 2420b57cec5SDimitry Andric llvm::ArrayType *ElTy = cast<llvm::ArrayType>(Addr.getElementType()); 243*0fca6ea1SDimitry Andric const llvm::DataLayout &DL = BB->getDataLayout(); 2440b57cec5SDimitry Andric CharUnits EltSize = 2450b57cec5SDimitry Andric CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType())); 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric return Address( 248*0fca6ea1SDimitry Andric CreateInBoundsGEP(Addr.getElementType(), Addr.getBasePointer(), 2490b57cec5SDimitry Andric {getSize(CharUnits::Zero()), getSize(Index)}, Name), 2500eae32dcSDimitry Andric ElTy->getElementType(), 25106c3fb27SDimitry Andric Addr.getAlignment().alignmentAtOffset(Index * EltSize), 25206c3fb27SDimitry Andric Addr.isKnownNonNull()); 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric /// Given 2560b57cec5SDimitry Andric /// %addr = T* ... 2570b57cec5SDimitry Andric /// produce 2580b57cec5SDimitry Andric /// %name = getelementptr inbounds %addr, i64 index 2590b57cec5SDimitry Andric /// where i64 is actually the target word size. 2600b57cec5SDimitry Andric Address CreateConstInBoundsGEP(Address Addr, uint64_t Index, 2610b57cec5SDimitry Andric const llvm::Twine &Name = "") { 2620b57cec5SDimitry Andric llvm::Type *ElTy = Addr.getElementType(); 263*0fca6ea1SDimitry Andric const llvm::DataLayout &DL = BB->getDataLayout(); 2640b57cec5SDimitry Andric CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy)); 2650b57cec5SDimitry Andric 266*0fca6ea1SDimitry Andric return Address( 267*0fca6ea1SDimitry Andric CreateInBoundsGEP(ElTy, Addr.getBasePointer(), getSize(Index), Name), 26806c3fb27SDimitry Andric ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize), 26906c3fb27SDimitry Andric Addr.isKnownNonNull()); 2700b57cec5SDimitry Andric } 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric /// Given 2730b57cec5SDimitry Andric /// %addr = T* ... 2740b57cec5SDimitry Andric /// produce 2750b57cec5SDimitry Andric /// %name = getelementptr inbounds %addr, i64 index 2760b57cec5SDimitry Andric /// where i64 is actually the target word size. 2770b57cec5SDimitry Andric Address CreateConstGEP(Address Addr, uint64_t Index, 2780b57cec5SDimitry Andric const llvm::Twine &Name = "") { 279*0fca6ea1SDimitry Andric llvm::Type *ElTy = Addr.getElementType(); 280*0fca6ea1SDimitry Andric const llvm::DataLayout &DL = BB->getDataLayout(); 281*0fca6ea1SDimitry Andric CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy)); 2820b57cec5SDimitry Andric 283*0fca6ea1SDimitry Andric return Address(CreateGEP(ElTy, Addr.getBasePointer(), getSize(Index), Name), 2840eae32dcSDimitry Andric Addr.getElementType(), 285*0fca6ea1SDimitry Andric Addr.getAlignment().alignmentAtOffset(Index * EltSize)); 2860b57cec5SDimitry Andric } 2870b57cec5SDimitry Andric 2880eae32dcSDimitry Andric /// Create GEP with single dynamic index. The address alignment is reduced 2890eae32dcSDimitry Andric /// according to the element size. 2900eae32dcSDimitry Andric using CGBuilderBaseTy::CreateGEP; 291*0fca6ea1SDimitry Andric Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, 2920eae32dcSDimitry Andric const llvm::Twine &Name = "") { 293*0fca6ea1SDimitry Andric const llvm::DataLayout &DL = BB->getDataLayout(); 2940eae32dcSDimitry Andric CharUnits EltSize = 2950eae32dcSDimitry Andric CharUnits::fromQuantity(DL.getTypeAllocSize(Addr.getElementType())); 2960eae32dcSDimitry Andric 29781ad6265SDimitry Andric return Address( 298*0fca6ea1SDimitry Andric CreateGEP(Addr.getElementType(), Addr.emitRawPointer(CGF), Index, Name), 2990eae32dcSDimitry Andric Addr.getElementType(), 300*0fca6ea1SDimitry Andric Addr.getAlignment().alignmentOfArrayElement(EltSize)); 3010eae32dcSDimitry Andric } 3020eae32dcSDimitry Andric 3030b57cec5SDimitry Andric /// Given a pointer to i8, adjust it by a given constant offset. 3040b57cec5SDimitry Andric Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, 3050b57cec5SDimitry Andric const llvm::Twine &Name = "") { 3060b57cec5SDimitry Andric assert(Addr.getElementType() == TypeCache.Int8Ty); 307*0fca6ea1SDimitry Andric return Address( 308*0fca6ea1SDimitry Andric CreateInBoundsGEP(Addr.getElementType(), Addr.getBasePointer(), 309fe6060f1SDimitry Andric getSize(Offset), Name), 310*0fca6ea1SDimitry Andric Addr.getElementType(), Addr.getAlignment().alignmentAtOffset(Offset), 31106c3fb27SDimitry Andric Addr.isKnownNonNull()); 3120b57cec5SDimitry Andric } 313*0fca6ea1SDimitry Andric 3140b57cec5SDimitry Andric Address CreateConstByteGEP(Address Addr, CharUnits Offset, 3150b57cec5SDimitry Andric const llvm::Twine &Name = "") { 3160b57cec5SDimitry Andric assert(Addr.getElementType() == TypeCache.Int8Ty); 317*0fca6ea1SDimitry Andric return Address(CreateGEP(Addr.getElementType(), Addr.getBasePointer(), 318fe6060f1SDimitry Andric getSize(Offset), Name), 3190eae32dcSDimitry Andric Addr.getElementType(), 320*0fca6ea1SDimitry Andric Addr.getAlignment().alignmentAtOffset(Offset)); 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric using CGBuilderBaseTy::CreateConstInBoundsGEP2_32; 3240b57cec5SDimitry Andric Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, 3250b57cec5SDimitry Andric const llvm::Twine &Name = "") { 326*0fca6ea1SDimitry Andric return createConstGEP2_32<true>(Addr, Idx0, Idx1, Name); 327*0fca6ea1SDimitry Andric } 3280b57cec5SDimitry Andric 329*0fca6ea1SDimitry Andric using CGBuilderBaseTy::CreateConstGEP2_32; 330*0fca6ea1SDimitry Andric Address CreateConstGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, 331*0fca6ea1SDimitry Andric const llvm::Twine &Name = "") { 332*0fca6ea1SDimitry Andric return createConstGEP2_32<false>(Addr, Idx0, Idx1, Name); 333*0fca6ea1SDimitry Andric } 334*0fca6ea1SDimitry Andric 335*0fca6ea1SDimitry Andric Address CreateGEP(Address Addr, ArrayRef<llvm::Value *> IdxList, 336*0fca6ea1SDimitry Andric llvm::Type *ElementType, CharUnits Align, 337*0fca6ea1SDimitry Andric const Twine &Name = "") { 338*0fca6ea1SDimitry Andric llvm::Value *Ptr = emitRawPointerFromAddress(Addr); 339*0fca6ea1SDimitry Andric return RawAddress(CreateGEP(Addr.getElementType(), Ptr, IdxList, Name), 340*0fca6ea1SDimitry Andric ElementType, Align); 341*0fca6ea1SDimitry Andric } 342*0fca6ea1SDimitry Andric 343*0fca6ea1SDimitry Andric using CGBuilderBaseTy::CreateInBoundsGEP; 344*0fca6ea1SDimitry Andric Address CreateInBoundsGEP(Address Addr, ArrayRef<llvm::Value *> IdxList, 345*0fca6ea1SDimitry Andric llvm::Type *ElementType, CharUnits Align, 346*0fca6ea1SDimitry Andric const Twine &Name = "") { 347*0fca6ea1SDimitry Andric return RawAddress(CreateInBoundsGEP(Addr.getElementType(), 348*0fca6ea1SDimitry Andric emitRawPointerFromAddress(Addr), 349*0fca6ea1SDimitry Andric IdxList, Name), 350*0fca6ea1SDimitry Andric ElementType, Align, Addr.isKnownNonNull()); 351*0fca6ea1SDimitry Andric } 352*0fca6ea1SDimitry Andric 353*0fca6ea1SDimitry Andric using CGBuilderBaseTy::CreateIsNull; 354*0fca6ea1SDimitry Andric llvm::Value *CreateIsNull(Address Addr, const Twine &Name = "") { 355*0fca6ea1SDimitry Andric if (!Addr.hasOffset()) 356*0fca6ea1SDimitry Andric return CreateIsNull(Addr.getBasePointer(), Name); 357*0fca6ea1SDimitry Andric // The pointer isn't null if Addr has an offset since offsets can always 358*0fca6ea1SDimitry Andric // be applied inbound. 359*0fca6ea1SDimitry Andric return llvm::ConstantInt::getFalse(Context); 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric using CGBuilderBaseTy::CreateMemCpy; 3630b57cec5SDimitry Andric llvm::CallInst *CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, 3640b57cec5SDimitry Andric bool IsVolatile = false) { 365*0fca6ea1SDimitry Andric llvm::Value *DestPtr = emitRawPointerFromAddress(Dest); 366*0fca6ea1SDimitry Andric llvm::Value *SrcPtr = emitRawPointerFromAddress(Src); 367*0fca6ea1SDimitry Andric return CreateMemCpy(DestPtr, Dest.getAlignment().getAsAlign(), SrcPtr, 368*0fca6ea1SDimitry Andric Src.getAlignment().getAsAlign(), Size, IsVolatile); 3690b57cec5SDimitry Andric } 3700b57cec5SDimitry Andric llvm::CallInst *CreateMemCpy(Address Dest, Address Src, uint64_t Size, 3710b57cec5SDimitry Andric bool IsVolatile = false) { 372*0fca6ea1SDimitry Andric llvm::Value *DestPtr = emitRawPointerFromAddress(Dest); 373*0fca6ea1SDimitry Andric llvm::Value *SrcPtr = emitRawPointerFromAddress(Src); 374*0fca6ea1SDimitry Andric return CreateMemCpy(DestPtr, Dest.getAlignment().getAsAlign(), SrcPtr, 375*0fca6ea1SDimitry Andric Src.getAlignment().getAsAlign(), Size, IsVolatile); 3760b57cec5SDimitry Andric } 3770b57cec5SDimitry Andric 3785ffd83dbSDimitry Andric using CGBuilderBaseTy::CreateMemCpyInline; 3795ffd83dbSDimitry Andric llvm::CallInst *CreateMemCpyInline(Address Dest, Address Src, uint64_t Size) { 380*0fca6ea1SDimitry Andric llvm::Value *DestPtr = emitRawPointerFromAddress(Dest); 381*0fca6ea1SDimitry Andric llvm::Value *SrcPtr = emitRawPointerFromAddress(Src); 382*0fca6ea1SDimitry Andric return CreateMemCpyInline(DestPtr, Dest.getAlignment().getAsAlign(), SrcPtr, 3835ffd83dbSDimitry Andric Src.getAlignment().getAsAlign(), getInt64(Size)); 3845ffd83dbSDimitry Andric } 3855ffd83dbSDimitry Andric 3860b57cec5SDimitry Andric using CGBuilderBaseTy::CreateMemMove; 3870b57cec5SDimitry Andric llvm::CallInst *CreateMemMove(Address Dest, Address Src, llvm::Value *Size, 3880b57cec5SDimitry Andric bool IsVolatile = false) { 389*0fca6ea1SDimitry Andric llvm::Value *DestPtr = emitRawPointerFromAddress(Dest); 390*0fca6ea1SDimitry Andric llvm::Value *SrcPtr = emitRawPointerFromAddress(Src); 391*0fca6ea1SDimitry Andric return CreateMemMove(DestPtr, Dest.getAlignment().getAsAlign(), SrcPtr, 392*0fca6ea1SDimitry Andric Src.getAlignment().getAsAlign(), Size, IsVolatile); 3930b57cec5SDimitry Andric } 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric using CGBuilderBaseTy::CreateMemSet; 3960b57cec5SDimitry Andric llvm::CallInst *CreateMemSet(Address Dest, llvm::Value *Value, 3970b57cec5SDimitry Andric llvm::Value *Size, bool IsVolatile = false) { 398*0fca6ea1SDimitry Andric return CreateMemSet(emitRawPointerFromAddress(Dest), Value, Size, 399480093f4SDimitry Andric Dest.getAlignment().getAsAlign(), IsVolatile); 4000b57cec5SDimitry Andric } 4010b57cec5SDimitry Andric 40281ad6265SDimitry Andric using CGBuilderBaseTy::CreateMemSetInline; 40381ad6265SDimitry Andric llvm::CallInst *CreateMemSetInline(Address Dest, llvm::Value *Value, 40481ad6265SDimitry Andric uint64_t Size) { 405*0fca6ea1SDimitry Andric return CreateMemSetInline(emitRawPointerFromAddress(Dest), 40681ad6265SDimitry Andric Dest.getAlignment().getAsAlign(), Value, 40781ad6265SDimitry Andric getInt64(Size)); 40881ad6265SDimitry Andric } 40981ad6265SDimitry Andric 4100b57cec5SDimitry Andric using CGBuilderBaseTy::CreatePreserveStructAccessIndex; 41181ad6265SDimitry Andric Address CreatePreserveStructAccessIndex(Address Addr, unsigned Index, 4120b57cec5SDimitry Andric unsigned FieldIndex, 4130b57cec5SDimitry Andric llvm::MDNode *DbgInfo) { 4140b57cec5SDimitry Andric llvm::StructType *ElTy = cast<llvm::StructType>(Addr.getElementType()); 415*0fca6ea1SDimitry Andric const llvm::DataLayout &DL = BB->getDataLayout(); 4160b57cec5SDimitry Andric const llvm::StructLayout *Layout = DL.getStructLayout(ElTy); 4170b57cec5SDimitry Andric auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index)); 4180b57cec5SDimitry Andric 419*0fca6ea1SDimitry Andric return Address( 420*0fca6ea1SDimitry Andric CreatePreserveStructAccessIndex(ElTy, emitRawPointerFromAddress(Addr), 4210b57cec5SDimitry Andric Index, FieldIndex, DbgInfo), 4220eae32dcSDimitry Andric ElTy->getElementType(Index), 4230b57cec5SDimitry Andric Addr.getAlignment().alignmentAtOffset(Offset)); 4240b57cec5SDimitry Andric } 4250eae32dcSDimitry Andric 426*0fca6ea1SDimitry Andric using CGBuilderBaseTy::CreatePreserveUnionAccessIndex; 427*0fca6ea1SDimitry Andric Address CreatePreserveUnionAccessIndex(Address Addr, unsigned FieldIndex, 428*0fca6ea1SDimitry Andric llvm::MDNode *DbgInfo) { 429*0fca6ea1SDimitry Andric Addr.replaceBasePointer(CreatePreserveUnionAccessIndex( 430*0fca6ea1SDimitry Andric Addr.getBasePointer(), FieldIndex, DbgInfo)); 431*0fca6ea1SDimitry Andric return Addr; 432*0fca6ea1SDimitry Andric } 433*0fca6ea1SDimitry Andric 4340eae32dcSDimitry Andric using CGBuilderBaseTy::CreateLaunderInvariantGroup; 4350eae32dcSDimitry Andric Address CreateLaunderInvariantGroup(Address Addr) { 436*0fca6ea1SDimitry Andric Addr.replaceBasePointer(CreateLaunderInvariantGroup(Addr.getBasePointer())); 437*0fca6ea1SDimitry Andric return Addr; 438*0fca6ea1SDimitry Andric } 439*0fca6ea1SDimitry Andric 440*0fca6ea1SDimitry Andric using CGBuilderBaseTy::CreateStripInvariantGroup; 441*0fca6ea1SDimitry Andric Address CreateStripInvariantGroup(Address Addr) { 442*0fca6ea1SDimitry Andric Addr.replaceBasePointer(CreateStripInvariantGroup(Addr.getBasePointer())); 443*0fca6ea1SDimitry Andric return Addr; 4440eae32dcSDimitry Andric } 4450b57cec5SDimitry Andric }; 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andric } // end namespace CodeGen 4480b57cec5SDimitry Andric } // end namespace clang 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric #endif 451