CGBuilder.h revision 296417
119370Spst//===-- CGBuilder.h - Choose IRBuilder implementation ----------*- C++ -*-===// 298944Sobrien// 398944Sobrien// The LLVM Compiler Infrastructure 498944Sobrien// 519370Spst// This file is distributed under the University of Illinois Open Source 619370Spst// License. See LICENSE.TXT for details. 719370Spst// 819370Spst//===----------------------------------------------------------------------===// 919370Spst 1019370Spst#ifndef LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H 1119370Spst#define LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H 1219370Spst 1319370Spst#include "llvm/IR/IRBuilder.h" 1419370Spst#include "Address.h" 1519370Spst#include "CodeGenTypeCache.h" 1619370Spst 1719370Spstnamespace clang { 1819370Spstnamespace CodeGen { 1919370Spst 2019370Spstclass CodeGenFunction; 2119370Spst 2219370Spst/// \brief This is an IRBuilder insertion helper that forwards to 2319370Spst/// CodeGenFunction::InsertHelper, which adds necessary metadata to 2419370Spst/// instructions. 2519370Spsttemplate <bool PreserveNames> 2619370Spstclass CGBuilderInserter 2719370Spst : protected llvm::IRBuilderDefaultInserter<PreserveNames> { 2819370Spstpublic: 2919370Spst CGBuilderInserter() = default; 3019370Spst explicit CGBuilderInserter(CodeGenFunction *CGF) : CGF(CGF) {} 3119370Spst 3219370Spstprotected: 3319370Spst /// \brief This forwards to CodeGenFunction::InsertHelper. 3419370Spst void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, 3519370Spst llvm::BasicBlock *BB, 3619370Spst llvm::BasicBlock::iterator InsertPt) const; 3719370Spstprivate: 3819370Spst CodeGenFunction *CGF = nullptr; 3919370Spst}; 4019370Spst 4119370Spst// Don't preserve names on values in an optimized build. 4219370Spst#ifdef NDEBUG 4319370Spst#define PreserveNames false 4419370Spst#else 4519370Spst#define PreserveNames true 4619370Spst#endif 4719370Spst 4819370Spsttypedef CGBuilderInserter<PreserveNames> CGBuilderInserterTy; 4919370Spst 5019370Spsttypedef llvm::IRBuilder<PreserveNames, llvm::ConstantFolder, 5119370Spst CGBuilderInserterTy> CGBuilderBaseTy; 5219370Spst 5319370Spstclass CGBuilderTy : public CGBuilderBaseTy { 5419370Spst /// Storing a reference to the type cache here makes it a lot easier 5519370Spst /// to build natural-feeling, target-specific IR. 56130803Smarcel const CodeGenTypeCache &TypeCache; 5798944Sobrienpublic: 5819370Spst CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::LLVMContext &C) 5919370Spst : CGBuilderBaseTy(C), TypeCache(TypeCache) {} 6019370Spst CGBuilderTy(const CodeGenTypeCache &TypeCache, 6119370Spst llvm::LLVMContext &C, const llvm::ConstantFolder &F, 6219370Spst const CGBuilderInserterTy &Inserter) 6319370Spst : CGBuilderBaseTy(C, F, Inserter), TypeCache(TypeCache) {} 6419370Spst CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::Instruction *I) 6519370Spst : CGBuilderBaseTy(I), TypeCache(TypeCache) {} 6619370Spst CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::BasicBlock *BB) 6719370Spst : CGBuilderBaseTy(BB), TypeCache(TypeCache) {} 6819370Spst 6919370Spst llvm::ConstantInt *getSize(CharUnits N) { 7019370Spst return llvm::ConstantInt::get(TypeCache.SizeTy, N.getQuantity()); 7119370Spst } 7219370Spst llvm::ConstantInt *getSize(uint64_t N) { 7319370Spst return llvm::ConstantInt::get(TypeCache.SizeTy, N); 7419370Spst } 7519370Spst 7619370Spst // Note that we intentionally hide the CreateLoad APIs that don't 7719370Spst // take an alignment. 7819370Spst llvm::LoadInst *CreateLoad(Address Addr, const llvm::Twine &Name = "") { 7919370Spst return CreateAlignedLoad(Addr.getPointer(), 8019370Spst Addr.getAlignment().getQuantity(), 8119370Spst Name); 8219370Spst } 8319370Spst llvm::LoadInst *CreateLoad(Address Addr, const char *Name) { 8419370Spst // This overload is required to prevent string literals from 8519370Spst // ending up in the IsVolatile overload. 8619370Spst return CreateAlignedLoad(Addr.getPointer(), 8719370Spst Addr.getAlignment().getQuantity(), 8819370Spst Name); 8919370Spst } 9019370Spst llvm::LoadInst *CreateLoad(Address Addr, bool IsVolatile, 9119370Spst const llvm::Twine &Name = "") { 9219370Spst return CreateAlignedLoad(Addr.getPointer(), 9319370Spst Addr.getAlignment().getQuantity(), 9419370Spst IsVolatile, 95130803Smarcel Name); 96130803Smarcel } 9719370Spst 9819370Spst using CGBuilderBaseTy::CreateAlignedLoad; 9919370Spst llvm::LoadInst *CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, 10019370Spst const llvm::Twine &Name = "") { 10119370Spst return CreateAlignedLoad(Addr, Align.getQuantity(), Name); 10219370Spst } 10319370Spst llvm::LoadInst *CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, 10419370Spst const char *Name) { 10519370Spst return CreateAlignedLoad(Addr, Align.getQuantity(), Name); 10619370Spst } 10719370Spst llvm::LoadInst *CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, 108130803Smarcel CharUnits Align, 10919370Spst const llvm::Twine &Name = "") { 11019370Spst assert(Addr->getType()->getPointerElementType() == Ty); 111130803Smarcel return CreateAlignedLoad(Addr, Align.getQuantity(), Name); 112130803Smarcel } 11398944Sobrien llvm::LoadInst *CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, 11419370Spst bool IsVolatile, 11598944Sobrien const llvm::Twine &Name = "") { 11619370Spst return CreateAlignedLoad(Addr, Align.getQuantity(), IsVolatile, Name); 11798944Sobrien } 11819370Spst 11998944Sobrien // Note that we intentionally hide the CreateStore APIs that don't 12046283Sdfr // take an alignment. 12198944Sobrien llvm::StoreInst *CreateStore(llvm::Value *Val, Address Addr, 12246283Sdfr bool IsVolatile = false) { 12319370Spst return CreateAlignedStore(Val, Addr.getPointer(), 12419370Spst Addr.getAlignment().getQuantity(), IsVolatile); 12519370Spst } 12619370Spst 12719370Spst using CGBuilderBaseTy::CreateAlignedStore; 12819370Spst llvm::StoreInst *CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, 12919370Spst CharUnits Align, bool IsVolatile = false) { 13019370Spst return CreateAlignedStore(Val, Addr, Align.getQuantity(), IsVolatile); 13119370Spst } 13219370Spst 13319370Spst // FIXME: these "default-aligned" APIs should be removed, 13419370Spst // but I don't feel like fixing all the builtin code right now. 13519370Spst llvm::LoadInst *CreateDefaultAlignedLoad(llvm::Value *Addr, 13619370Spst const llvm::Twine &Name = "") { 13719370Spst return CGBuilderBaseTy::CreateLoad(Addr, false, Name); 13819370Spst } 13919370Spst llvm::LoadInst *CreateDefaultAlignedLoad(llvm::Value *Addr, 14019370Spst const char *Name) { 14119370Spst return CGBuilderBaseTy::CreateLoad(Addr, false, Name); 14219370Spst } 14319370Spst llvm::LoadInst *CreateDefaultAlignedLoad(llvm::Value *Addr, bool IsVolatile, 14419370Spst const llvm::Twine &Name = "") { 14519370Spst return CGBuilderBaseTy::CreateLoad(Addr, IsVolatile, Name); 14619370Spst } 14719370Spst 14819370Spst llvm::StoreInst *CreateDefaultAlignedStore(llvm::Value *Val, 14919370Spst llvm::Value *Addr, 15019370Spst bool IsVolatile = false) { 15119370Spst return CGBuilderBaseTy::CreateStore(Val, Addr, IsVolatile); 15219370Spst } 15398944Sobrien 15419370Spst /// Emit a load from an i1 flag variable. 15519370Spst llvm::LoadInst *CreateFlagLoad(llvm::Value *Addr, 15619370Spst const llvm::Twine &Name = "") { 15719370Spst assert(Addr->getType()->getPointerElementType() == getInt1Ty()); 15819370Spst return CreateAlignedLoad(getInt1Ty(), Addr, CharUnits::One(), Name); 15919370Spst } 16019370Spst 16119370Spst /// Emit a store to an i1 flag variable. 16219370Spst llvm::StoreInst *CreateFlagStore(bool Value, llvm::Value *Addr) { 16319370Spst assert(Addr->getType()->getPointerElementType() == getInt1Ty()); 16419370Spst return CreateAlignedStore(getInt1(Value), Addr, CharUnits::One()); 16519370Spst } 16619370Spst 16719370Spst using CGBuilderBaseTy::CreateBitCast; 16819370Spst Address CreateBitCast(Address Addr, llvm::Type *Ty, 16919370Spst const llvm::Twine &Name = "") { 17019370Spst return Address(CreateBitCast(Addr.getPointer(), Ty, Name), 17119370Spst Addr.getAlignment()); 17219370Spst } 17319370Spst 17419370Spst /// Cast the element type of the given address to a different type, 17519370Spst /// preserving information like the alignment and address space. 17619370Spst Address CreateElementBitCast(Address Addr, llvm::Type *Ty, 17719370Spst const llvm::Twine &Name = "") { 17819370Spst auto PtrTy = Ty->getPointerTo(Addr.getAddressSpace()); 17919370Spst return CreateBitCast(Addr, PtrTy, Name); 18019370Spst } 18119370Spst 18219370Spst using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast; 18319370Spst Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, 18419370Spst const llvm::Twine &Name = "") { 18519370Spst llvm::Value *Ptr = 18619370Spst CreatePointerBitCastOrAddrSpaceCast(Addr.getPointer(), Ty, Name); 18719370Spst return Address(Ptr, Addr.getAlignment()); 18819370Spst } 18919370Spst 19019370Spst using CGBuilderBaseTy::CreateStructGEP; 19119370Spst Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, 19219370Spst const llvm::Twine &Name = "") { 19319370Spst return Address(CreateStructGEP(Addr.getElementType(), 19419370Spst Addr.getPointer(), Index, Name), 19519370Spst Addr.getAlignment().alignmentAtOffset(Offset)); 19619370Spst } 19719370Spst 19819370Spst /// Given 19919370Spst /// %addr = [n x T]* ... 20019370Spst /// produce 20119370Spst /// %name = getelementptr inbounds %addr, i64 0, i64 index 20219370Spst /// where i64 is actually the target word size. 20319370Spst /// 20419370Spst /// This API assumes that drilling into an array like this is always 20519370Spst /// an inbounds operation. 20619370Spst /// 20719370Spst /// \param EltSize - the size of the type T in bytes 20819370Spst Address CreateConstArrayGEP(Address Addr, uint64_t Index, CharUnits EltSize, 20919370Spst const llvm::Twine &Name = "") { 21019370Spst return Address(CreateInBoundsGEP(Addr.getPointer(), 21119370Spst {getSize(CharUnits::Zero()), 21219370Spst getSize(Index)}, 21319370Spst Name), 21419370Spst Addr.getAlignment().alignmentAtOffset(Index * EltSize)); 21519370Spst } 21619370Spst 21719370Spst /// Given 21819370Spst /// %addr = T* ... 21919370Spst /// produce 22019370Spst /// %name = getelementptr inbounds %addr, i64 index 22119370Spst /// where i64 is actually the target word size. 22219370Spst /// 22319370Spst /// \param EltSize - the size of the type T in bytes 22419370Spst Address CreateConstInBoundsGEP(Address Addr, uint64_t Index, 22519370Spst CharUnits EltSize, 22619370Spst const llvm::Twine &Name = "") { 22719370Spst return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(), 22819370Spst getSize(Index), Name), 22919370Spst Addr.getAlignment().alignmentAtOffset(Index * EltSize)); 23019370Spst } 23119370Spst 23219370Spst /// Given 23319370Spst /// %addr = T* ... 23419370Spst /// produce 23519370Spst /// %name = getelementptr inbounds %addr, i64 index 23619370Spst /// where i64 is actually the target word size. 23719370Spst /// 23819370Spst /// \param EltSize - the size of the type T in bytes 23919370Spst Address CreateConstGEP(Address Addr, uint64_t Index, CharUnits EltSize, 24019370Spst const llvm::Twine &Name = "") { 24119370Spst return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(), 24219370Spst getSize(Index), Name), 24319370Spst Addr.getAlignment().alignmentAtOffset(Index * EltSize)); 24419370Spst } 245130803Smarcel 24619370Spst /// Given a pointer to i8, adjust it by a given constant offset. 24719370Spst Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, 24819370Spst const llvm::Twine &Name = "") { 249130803Smarcel assert(Addr.getElementType() == TypeCache.Int8Ty); 25019370Spst return Address(CreateInBoundsGEP(Addr.getPointer(), getSize(Offset), Name), 25119370Spst Addr.getAlignment().alignmentAtOffset(Offset)); 25219370Spst } 25319370Spst Address CreateConstByteGEP(Address Addr, CharUnits Offset, 25419370Spst const llvm::Twine &Name = "") { 25519370Spst assert(Addr.getElementType() == TypeCache.Int8Ty); 25619370Spst return Address(CreateGEP(Addr.getPointer(), getSize(Offset), Name), 25719370Spst Addr.getAlignment().alignmentAtOffset(Offset)); 25819370Spst } 25919370Spst 26019370Spst llvm::Value *CreateConstInBoundsByteGEP(llvm::Value *Ptr, CharUnits Offset, 26119370Spst const llvm::Twine &Name = "") { 26219370Spst assert(Ptr->getType()->getPointerElementType() == TypeCache.Int8Ty); 26319370Spst return CreateInBoundsGEP(Ptr, getSize(Offset), Name); 26419370Spst } 26519370Spst llvm::Value *CreateConstByteGEP(llvm::Value *Ptr, CharUnits Offset, 26619370Spst const llvm::Twine &Name = "") { 26719370Spst assert(Ptr->getType()->getPointerElementType() == TypeCache.Int8Ty); 26819370Spst return CreateGEP(Ptr, getSize(Offset), Name); 26919370Spst } 27019370Spst 27119370Spst using CGBuilderBaseTy::CreateMemCpy; 27219370Spst llvm::CallInst *CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, 27319370Spst bool IsVolatile = false) { 27419370Spst auto Align = std::min(Dest.getAlignment(), Src.getAlignment()); 27519370Spst return CreateMemCpy(Dest.getPointer(), Src.getPointer(), Size, 27619370Spst Align.getQuantity(), IsVolatile); 27719370Spst } 27819370Spst llvm::CallInst *CreateMemCpy(Address Dest, Address Src, uint64_t Size, 27919370Spst bool IsVolatile = false) { 28019370Spst auto Align = std::min(Dest.getAlignment(), Src.getAlignment()); 28119370Spst return CreateMemCpy(Dest.getPointer(), Src.getPointer(), Size, 28219370Spst Align.getQuantity(), IsVolatile); 28319370Spst } 28419370Spst 28519370Spst using CGBuilderBaseTy::CreateMemMove; 28619370Spst llvm::CallInst *CreateMemMove(Address Dest, Address Src, llvm::Value *Size, 28719370Spst bool IsVolatile = false) { 28819370Spst auto Align = std::min(Dest.getAlignment(), Src.getAlignment()); 289130803Smarcel return CreateMemMove(Dest.getPointer(), Src.getPointer(), Size, 29019370Spst Align.getQuantity(), IsVolatile); 29119370Spst } 29219370Spst 29319370Spst using CGBuilderBaseTy::CreateMemSet; 29419370Spst llvm::CallInst *CreateMemSet(Address Dest, llvm::Value *Value, 29519370Spst llvm::Value *Size, bool IsVolatile = false) { 29619370Spst return CreateMemSet(Dest.getPointer(), Value, Size, 29719370Spst Dest.getAlignment().getQuantity(), IsVolatile); 29819370Spst } 29919370Spst}; 30019370Spst 30119370Spst#undef PreserveNames 30219370Spst 30319370Spst} // end namespace CodeGen 30419370Spst} // end namespace clang 30519370Spst 30619370Spst#endif 30719370Spst