1*67e74705SXin Li //===-- CGBuilder.h - Choose IRBuilder implementation ----------*- C++ -*-===// 2*67e74705SXin Li // 3*67e74705SXin Li // The LLVM Compiler Infrastructure 4*67e74705SXin Li // 5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source 6*67e74705SXin Li // License. See LICENSE.TXT for details. 7*67e74705SXin Li // 8*67e74705SXin Li //===----------------------------------------------------------------------===// 9*67e74705SXin Li 10*67e74705SXin Li #ifndef LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H 11*67e74705SXin Li #define LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H 12*67e74705SXin Li 13*67e74705SXin Li #include "llvm/IR/DataLayout.h" 14*67e74705SXin Li #include "llvm/IR/IRBuilder.h" 15*67e74705SXin Li #include "Address.h" 16*67e74705SXin Li #include "CodeGenTypeCache.h" 17*67e74705SXin Li 18*67e74705SXin Li namespace clang { 19*67e74705SXin Li namespace CodeGen { 20*67e74705SXin Li 21*67e74705SXin Li class CodeGenFunction; 22*67e74705SXin Li 23*67e74705SXin Li /// \brief This is an IRBuilder insertion helper that forwards to 24*67e74705SXin Li /// CodeGenFunction::InsertHelper, which adds necessary metadata to 25*67e74705SXin Li /// instructions. 26*67e74705SXin Li class CGBuilderInserter : protected llvm::IRBuilderDefaultInserter { 27*67e74705SXin Li public: 28*67e74705SXin Li CGBuilderInserter() = default; CGBuilderInserter(CodeGenFunction * CGF)29*67e74705SXin Li explicit CGBuilderInserter(CodeGenFunction *CGF) : CGF(CGF) {} 30*67e74705SXin Li 31*67e74705SXin Li protected: 32*67e74705SXin Li /// \brief This forwards to CodeGenFunction::InsertHelper. 33*67e74705SXin Li void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, 34*67e74705SXin Li llvm::BasicBlock *BB, 35*67e74705SXin Li llvm::BasicBlock::iterator InsertPt) const; 36*67e74705SXin Li private: 37*67e74705SXin Li CodeGenFunction *CGF = nullptr; 38*67e74705SXin Li }; 39*67e74705SXin Li 40*67e74705SXin Li typedef CGBuilderInserter CGBuilderInserterTy; 41*67e74705SXin Li 42*67e74705SXin Li typedef llvm::IRBuilder<llvm::ConstantFolder, CGBuilderInserterTy> 43*67e74705SXin Li CGBuilderBaseTy; 44*67e74705SXin Li 45*67e74705SXin Li class CGBuilderTy : public CGBuilderBaseTy { 46*67e74705SXin Li /// Storing a reference to the type cache here makes it a lot easier 47*67e74705SXin Li /// to build natural-feeling, target-specific IR. 48*67e74705SXin Li const CodeGenTypeCache &TypeCache; 49*67e74705SXin Li public: CGBuilderTy(const CodeGenTypeCache & TypeCache,llvm::LLVMContext & C)50*67e74705SXin Li CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::LLVMContext &C) 51*67e74705SXin Li : CGBuilderBaseTy(C), TypeCache(TypeCache) {} CGBuilderTy(const CodeGenTypeCache & TypeCache,llvm::LLVMContext & C,const llvm::ConstantFolder & F,const CGBuilderInserterTy & Inserter)52*67e74705SXin Li CGBuilderTy(const CodeGenTypeCache &TypeCache, 53*67e74705SXin Li llvm::LLVMContext &C, const llvm::ConstantFolder &F, 54*67e74705SXin Li const CGBuilderInserterTy &Inserter) 55*67e74705SXin Li : CGBuilderBaseTy(C, F, Inserter), TypeCache(TypeCache) {} CGBuilderTy(const CodeGenTypeCache & TypeCache,llvm::Instruction * I)56*67e74705SXin Li CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::Instruction *I) 57*67e74705SXin Li : CGBuilderBaseTy(I), TypeCache(TypeCache) {} CGBuilderTy(const CodeGenTypeCache & TypeCache,llvm::BasicBlock * BB)58*67e74705SXin Li CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::BasicBlock *BB) 59*67e74705SXin Li : CGBuilderBaseTy(BB), TypeCache(TypeCache) {} 60*67e74705SXin Li getSize(CharUnits N)61*67e74705SXin Li llvm::ConstantInt *getSize(CharUnits N) { 62*67e74705SXin Li return llvm::ConstantInt::get(TypeCache.SizeTy, N.getQuantity()); 63*67e74705SXin Li } getSize(uint64_t N)64*67e74705SXin Li llvm::ConstantInt *getSize(uint64_t N) { 65*67e74705SXin Li return llvm::ConstantInt::get(TypeCache.SizeTy, N); 66*67e74705SXin Li } 67*67e74705SXin Li 68*67e74705SXin Li // Note that we intentionally hide the CreateLoad APIs that don't 69*67e74705SXin Li // take an alignment. 70*67e74705SXin Li llvm::LoadInst *CreateLoad(Address Addr, const llvm::Twine &Name = "") { 71*67e74705SXin Li return CreateAlignedLoad(Addr.getPointer(), 72*67e74705SXin Li Addr.getAlignment().getQuantity(), 73*67e74705SXin Li Name); 74*67e74705SXin Li } CreateLoad(Address Addr,const char * Name)75*67e74705SXin Li llvm::LoadInst *CreateLoad(Address Addr, const char *Name) { 76*67e74705SXin Li // This overload is required to prevent string literals from 77*67e74705SXin Li // ending up in the IsVolatile overload. 78*67e74705SXin Li return CreateAlignedLoad(Addr.getPointer(), 79*67e74705SXin Li Addr.getAlignment().getQuantity(), 80*67e74705SXin Li Name); 81*67e74705SXin Li } 82*67e74705SXin Li llvm::LoadInst *CreateLoad(Address Addr, bool IsVolatile, 83*67e74705SXin Li const llvm::Twine &Name = "") { 84*67e74705SXin Li return CreateAlignedLoad(Addr.getPointer(), 85*67e74705SXin Li Addr.getAlignment().getQuantity(), 86*67e74705SXin Li IsVolatile, 87*67e74705SXin Li Name); 88*67e74705SXin Li } 89*67e74705SXin Li 90*67e74705SXin Li using CGBuilderBaseTy::CreateAlignedLoad; 91*67e74705SXin Li llvm::LoadInst *CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, 92*67e74705SXin Li const llvm::Twine &Name = "") { 93*67e74705SXin Li return CreateAlignedLoad(Addr, Align.getQuantity(), Name); 94*67e74705SXin Li } CreateAlignedLoad(llvm::Value * Addr,CharUnits Align,const char * Name)95*67e74705SXin Li llvm::LoadInst *CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, 96*67e74705SXin Li const char *Name) { 97*67e74705SXin Li return CreateAlignedLoad(Addr, Align.getQuantity(), Name); 98*67e74705SXin Li } 99*67e74705SXin Li llvm::LoadInst *CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, 100*67e74705SXin Li CharUnits Align, 101*67e74705SXin Li const llvm::Twine &Name = "") { 102*67e74705SXin Li assert(Addr->getType()->getPointerElementType() == Ty); 103*67e74705SXin Li return CreateAlignedLoad(Addr, Align.getQuantity(), Name); 104*67e74705SXin Li } 105*67e74705SXin Li llvm::LoadInst *CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, 106*67e74705SXin Li bool IsVolatile, 107*67e74705SXin Li const llvm::Twine &Name = "") { 108*67e74705SXin Li return CreateAlignedLoad(Addr, Align.getQuantity(), IsVolatile, Name); 109*67e74705SXin Li } 110*67e74705SXin Li 111*67e74705SXin Li // Note that we intentionally hide the CreateStore APIs that don't 112*67e74705SXin Li // take an alignment. 113*67e74705SXin Li llvm::StoreInst *CreateStore(llvm::Value *Val, Address Addr, 114*67e74705SXin Li bool IsVolatile = false) { 115*67e74705SXin Li return CreateAlignedStore(Val, Addr.getPointer(), 116*67e74705SXin Li Addr.getAlignment().getQuantity(), IsVolatile); 117*67e74705SXin Li } 118*67e74705SXin Li 119*67e74705SXin Li using CGBuilderBaseTy::CreateAlignedStore; 120*67e74705SXin Li llvm::StoreInst *CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, 121*67e74705SXin Li CharUnits Align, bool IsVolatile = false) { 122*67e74705SXin Li return CreateAlignedStore(Val, Addr, Align.getQuantity(), IsVolatile); 123*67e74705SXin Li } 124*67e74705SXin Li 125*67e74705SXin Li // FIXME: these "default-aligned" APIs should be removed, 126*67e74705SXin Li // but I don't feel like fixing all the builtin code right now. 127*67e74705SXin Li llvm::LoadInst *CreateDefaultAlignedLoad(llvm::Value *Addr, 128*67e74705SXin Li const llvm::Twine &Name = "") { 129*67e74705SXin Li return CGBuilderBaseTy::CreateLoad(Addr, false, Name); 130*67e74705SXin Li } CreateDefaultAlignedLoad(llvm::Value * Addr,const char * Name)131*67e74705SXin Li llvm::LoadInst *CreateDefaultAlignedLoad(llvm::Value *Addr, 132*67e74705SXin Li const char *Name) { 133*67e74705SXin Li return CGBuilderBaseTy::CreateLoad(Addr, false, Name); 134*67e74705SXin Li } 135*67e74705SXin Li llvm::LoadInst *CreateDefaultAlignedLoad(llvm::Value *Addr, bool IsVolatile, 136*67e74705SXin Li const llvm::Twine &Name = "") { 137*67e74705SXin Li return CGBuilderBaseTy::CreateLoad(Addr, IsVolatile, Name); 138*67e74705SXin Li } 139*67e74705SXin Li 140*67e74705SXin Li llvm::StoreInst *CreateDefaultAlignedStore(llvm::Value *Val, 141*67e74705SXin Li llvm::Value *Addr, 142*67e74705SXin Li bool IsVolatile = false) { 143*67e74705SXin Li return CGBuilderBaseTy::CreateStore(Val, Addr, IsVolatile); 144*67e74705SXin Li } 145*67e74705SXin Li 146*67e74705SXin Li /// Emit a load from an i1 flag variable. 147*67e74705SXin Li llvm::LoadInst *CreateFlagLoad(llvm::Value *Addr, 148*67e74705SXin Li const llvm::Twine &Name = "") { 149*67e74705SXin Li assert(Addr->getType()->getPointerElementType() == getInt1Ty()); 150*67e74705SXin Li return CreateAlignedLoad(getInt1Ty(), Addr, CharUnits::One(), Name); 151*67e74705SXin Li } 152*67e74705SXin Li 153*67e74705SXin Li /// Emit a store to an i1 flag variable. CreateFlagStore(bool Value,llvm::Value * Addr)154*67e74705SXin Li llvm::StoreInst *CreateFlagStore(bool Value, llvm::Value *Addr) { 155*67e74705SXin Li assert(Addr->getType()->getPointerElementType() == getInt1Ty()); 156*67e74705SXin Li return CreateAlignedStore(getInt1(Value), Addr, CharUnits::One()); 157*67e74705SXin Li } 158*67e74705SXin Li 159*67e74705SXin Li using CGBuilderBaseTy::CreateBitCast; 160*67e74705SXin Li Address CreateBitCast(Address Addr, llvm::Type *Ty, 161*67e74705SXin Li const llvm::Twine &Name = "") { 162*67e74705SXin Li return Address(CreateBitCast(Addr.getPointer(), Ty, Name), 163*67e74705SXin Li Addr.getAlignment()); 164*67e74705SXin Li } 165*67e74705SXin Li 166*67e74705SXin Li /// Cast the element type of the given address to a different type, 167*67e74705SXin Li /// preserving information like the alignment and address space. 168*67e74705SXin Li Address CreateElementBitCast(Address Addr, llvm::Type *Ty, 169*67e74705SXin Li const llvm::Twine &Name = "") { 170*67e74705SXin Li auto PtrTy = Ty->getPointerTo(Addr.getAddressSpace()); 171*67e74705SXin Li return CreateBitCast(Addr, PtrTy, Name); 172*67e74705SXin Li } 173*67e74705SXin Li 174*67e74705SXin Li using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast; 175*67e74705SXin Li Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, 176*67e74705SXin Li const llvm::Twine &Name = "") { 177*67e74705SXin Li llvm::Value *Ptr = 178*67e74705SXin Li CreatePointerBitCastOrAddrSpaceCast(Addr.getPointer(), Ty, Name); 179*67e74705SXin Li return Address(Ptr, Addr.getAlignment()); 180*67e74705SXin Li } 181*67e74705SXin Li 182*67e74705SXin Li using CGBuilderBaseTy::CreateStructGEP; 183*67e74705SXin Li Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, 184*67e74705SXin Li const llvm::Twine &Name = "") { 185*67e74705SXin Li return Address(CreateStructGEP(Addr.getElementType(), 186*67e74705SXin Li Addr.getPointer(), Index, Name), 187*67e74705SXin Li Addr.getAlignment().alignmentAtOffset(Offset)); 188*67e74705SXin Li } 189*67e74705SXin Li Address CreateStructGEP(Address Addr, unsigned Index, 190*67e74705SXin Li const llvm::StructLayout *Layout, 191*67e74705SXin Li const llvm::Twine &Name = "") { 192*67e74705SXin Li auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index)); 193*67e74705SXin Li return CreateStructGEP(Addr, Index, Offset, Name); 194*67e74705SXin Li } 195*67e74705SXin Li 196*67e74705SXin Li /// Given 197*67e74705SXin Li /// %addr = [n x T]* ... 198*67e74705SXin Li /// produce 199*67e74705SXin Li /// %name = getelementptr inbounds %addr, i64 0, i64 index 200*67e74705SXin Li /// where i64 is actually the target word size. 201*67e74705SXin Li /// 202*67e74705SXin Li /// This API assumes that drilling into an array like this is always 203*67e74705SXin Li /// an inbounds operation. 204*67e74705SXin Li /// 205*67e74705SXin Li /// \param EltSize - the size of the type T in bytes 206*67e74705SXin Li Address CreateConstArrayGEP(Address Addr, uint64_t Index, CharUnits EltSize, 207*67e74705SXin Li const llvm::Twine &Name = "") { 208*67e74705SXin Li return Address(CreateInBoundsGEP(Addr.getPointer(), 209*67e74705SXin Li {getSize(CharUnits::Zero()), 210*67e74705SXin Li getSize(Index)}, 211*67e74705SXin Li Name), 212*67e74705SXin Li Addr.getAlignment().alignmentAtOffset(Index * EltSize)); 213*67e74705SXin Li } 214*67e74705SXin Li 215*67e74705SXin Li /// Given 216*67e74705SXin Li /// %addr = T* ... 217*67e74705SXin Li /// produce 218*67e74705SXin Li /// %name = getelementptr inbounds %addr, i64 index 219*67e74705SXin Li /// where i64 is actually the target word size. 220*67e74705SXin Li /// 221*67e74705SXin Li /// \param EltSize - the size of the type T in bytes 222*67e74705SXin Li Address CreateConstInBoundsGEP(Address Addr, uint64_t Index, 223*67e74705SXin Li CharUnits EltSize, 224*67e74705SXin Li const llvm::Twine &Name = "") { 225*67e74705SXin Li return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(), 226*67e74705SXin Li getSize(Index), Name), 227*67e74705SXin Li Addr.getAlignment().alignmentAtOffset(Index * EltSize)); 228*67e74705SXin Li } 229*67e74705SXin Li 230*67e74705SXin Li /// Given 231*67e74705SXin Li /// %addr = T* ... 232*67e74705SXin Li /// produce 233*67e74705SXin Li /// %name = getelementptr inbounds %addr, i64 index 234*67e74705SXin Li /// where i64 is actually the target word size. 235*67e74705SXin Li /// 236*67e74705SXin Li /// \param EltSize - the size of the type T in bytes 237*67e74705SXin Li Address CreateConstGEP(Address Addr, uint64_t Index, CharUnits EltSize, 238*67e74705SXin Li const llvm::Twine &Name = "") { 239*67e74705SXin Li return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(), 240*67e74705SXin Li getSize(Index), Name), 241*67e74705SXin Li Addr.getAlignment().alignmentAtOffset(Index * EltSize)); 242*67e74705SXin Li } 243*67e74705SXin Li 244*67e74705SXin Li /// Given a pointer to i8, adjust it by a given constant offset. 245*67e74705SXin Li Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, 246*67e74705SXin Li const llvm::Twine &Name = "") { 247*67e74705SXin Li assert(Addr.getElementType() == TypeCache.Int8Ty); 248*67e74705SXin Li return Address(CreateInBoundsGEP(Addr.getPointer(), getSize(Offset), Name), 249*67e74705SXin Li Addr.getAlignment().alignmentAtOffset(Offset)); 250*67e74705SXin Li } 251*67e74705SXin Li Address CreateConstByteGEP(Address Addr, CharUnits Offset, 252*67e74705SXin Li const llvm::Twine &Name = "") { 253*67e74705SXin Li assert(Addr.getElementType() == TypeCache.Int8Ty); 254*67e74705SXin Li return Address(CreateGEP(Addr.getPointer(), getSize(Offset), Name), 255*67e74705SXin Li Addr.getAlignment().alignmentAtOffset(Offset)); 256*67e74705SXin Li } 257*67e74705SXin Li 258*67e74705SXin Li llvm::Value *CreateConstInBoundsByteGEP(llvm::Value *Ptr, CharUnits Offset, 259*67e74705SXin Li const llvm::Twine &Name = "") { 260*67e74705SXin Li assert(Ptr->getType()->getPointerElementType() == TypeCache.Int8Ty); 261*67e74705SXin Li return CreateInBoundsGEP(Ptr, getSize(Offset), Name); 262*67e74705SXin Li } 263*67e74705SXin Li llvm::Value *CreateConstByteGEP(llvm::Value *Ptr, CharUnits Offset, 264*67e74705SXin Li const llvm::Twine &Name = "") { 265*67e74705SXin Li assert(Ptr->getType()->getPointerElementType() == TypeCache.Int8Ty); 266*67e74705SXin Li return CreateGEP(Ptr, getSize(Offset), Name); 267*67e74705SXin Li } 268*67e74705SXin Li 269*67e74705SXin Li using CGBuilderBaseTy::CreateMemCpy; 270*67e74705SXin Li llvm::CallInst *CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, 271*67e74705SXin Li bool IsVolatile = false) { 272*67e74705SXin Li auto Align = std::min(Dest.getAlignment(), Src.getAlignment()); 273*67e74705SXin Li return CreateMemCpy(Dest.getPointer(), Src.getPointer(), Size, 274*67e74705SXin Li Align.getQuantity(), IsVolatile); 275*67e74705SXin Li } 276*67e74705SXin Li llvm::CallInst *CreateMemCpy(Address Dest, Address Src, uint64_t Size, 277*67e74705SXin Li bool IsVolatile = false) { 278*67e74705SXin Li auto Align = std::min(Dest.getAlignment(), Src.getAlignment()); 279*67e74705SXin Li return CreateMemCpy(Dest.getPointer(), Src.getPointer(), Size, 280*67e74705SXin Li Align.getQuantity(), IsVolatile); 281*67e74705SXin Li } 282*67e74705SXin Li 283*67e74705SXin Li using CGBuilderBaseTy::CreateMemMove; 284*67e74705SXin Li llvm::CallInst *CreateMemMove(Address Dest, Address Src, llvm::Value *Size, 285*67e74705SXin Li bool IsVolatile = false) { 286*67e74705SXin Li auto Align = std::min(Dest.getAlignment(), Src.getAlignment()); 287*67e74705SXin Li return CreateMemMove(Dest.getPointer(), Src.getPointer(), Size, 288*67e74705SXin Li Align.getQuantity(), IsVolatile); 289*67e74705SXin Li } 290*67e74705SXin Li 291*67e74705SXin Li using CGBuilderBaseTy::CreateMemSet; 292*67e74705SXin Li llvm::CallInst *CreateMemSet(Address Dest, llvm::Value *Value, 293*67e74705SXin Li llvm::Value *Size, bool IsVolatile = false) { 294*67e74705SXin Li return CreateMemSet(Dest.getPointer(), Value, Size, 295*67e74705SXin Li Dest.getAlignment().getQuantity(), IsVolatile); 296*67e74705SXin Li } 297*67e74705SXin Li }; 298*67e74705SXin Li 299*67e74705SXin Li } // end namespace CodeGen 300*67e74705SXin Li } // end namespace clang 301*67e74705SXin Li 302*67e74705SXin Li #endif 303