diff options
Diffstat (limited to 'include/llvm/IR/IRBuilder.h')
-rw-r--r-- | include/llvm/IR/IRBuilder.h | 104 |
1 files changed, 85 insertions, 19 deletions
diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h index 1d9c16989de9..bc689f3b01d7 100644 --- a/include/llvm/IR/IRBuilder.h +++ b/include/llvm/IR/IRBuilder.h @@ -33,6 +33,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" @@ -75,7 +76,7 @@ class IRBuilderCallbackInserter : IRBuilderDefaultInserter { public: IRBuilderCallbackInserter(std::function<void(Instruction *)> Callback) - : Callback(Callback) {} + : Callback(std::move(Callback)) {} protected: void InsertHelper(Instruction *I, const Twine &Name, @@ -560,6 +561,22 @@ public: Type *ResultType, const Twine &Name = ""); + /// Create a call to intrinsic \p ID with 2 operands which is mangled on the + /// first type. + CallInst *CreateBinaryIntrinsic(Intrinsic::ID ID, + Value *LHS, Value *RHS, + const Twine &Name = ""); + + /// Create call to the minnum intrinsic. + CallInst *CreateMinNum(Value *LHS, Value *RHS, const Twine &Name = "") { + return CreateBinaryIntrinsic(Intrinsic::minnum, LHS, RHS, Name); + } + + /// Create call to the maxnum intrinsic. + CallInst *CreateMaxNum(Value *LHS, Value *RHS, const Twine &Name = "") { + return CreateBinaryIntrinsic(Intrinsic::minnum, LHS, RHS, Name); + } + private: /// \brief Create a call to a masked intrinsic with given Id. CallInst *CreateMaskedIntrinsic(Intrinsic::ID Id, ArrayRef<Value *> Ops, @@ -1073,9 +1090,15 @@ public: // Instruction creation methods: Memory Instructions //===--------------------------------------------------------------------===// + AllocaInst *CreateAlloca(Type *Ty, unsigned AddrSpace, + Value *ArraySize = nullptr, const Twine &Name = "") { + return Insert(new AllocaInst(Ty, AddrSpace, ArraySize), Name); + } + AllocaInst *CreateAlloca(Type *Ty, Value *ArraySize = nullptr, const Twine &Name = "") { - return Insert(new AllocaInst(Ty, ArraySize), Name); + const DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); + return Insert(new AllocaInst(Ty, DL.getAllocaAddrSpace(), ArraySize), Name); } // \brief Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of // converting the string to 'bool' for the isVolatile parameter. @@ -1790,24 +1813,16 @@ public: return V; } - /// \brief Create an assume intrinsic call that represents an alignment - /// assumption on the provided pointer. - /// - /// An optional offset can be provided, and if it is provided, the offset - /// must be subtracted from the provided pointer to get the pointer with the - /// specified alignment. - CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue, - unsigned Alignment, - Value *OffsetValue = nullptr) { - assert(isa<PointerType>(PtrValue->getType()) && - "trying to create an alignment assumption on a non-pointer?"); - - PointerType *PtrTy = cast<PointerType>(PtrValue->getType()); - Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace()); +private: + /// \brief Helper function that creates an assume intrinsic call that + /// represents an alignment assumption on the provided Ptr, Mask, Type + /// and Offset. + CallInst *CreateAlignmentAssumptionHelper(const DataLayout &DL, + Value *PtrValue, Value *Mask, + Type *IntPtrTy, + Value *OffsetValue) { Value *PtrIntValue = CreatePtrToInt(PtrValue, IntPtrTy, "ptrint"); - Value *Mask = ConstantInt::get(IntPtrTy, - Alignment > 0 ? Alignment - 1 : 0); if (OffsetValue) { bool IsOffsetZero = false; if (ConstantInt *CI = dyn_cast<ConstantInt>(OffsetValue)) @@ -1824,9 +1839,60 @@ public: Value *Zero = ConstantInt::get(IntPtrTy, 0); Value *MaskedPtr = CreateAnd(PtrIntValue, Mask, "maskedptr"); Value *InvCond = CreateICmpEQ(MaskedPtr, Zero, "maskcond"); - return CreateAssumption(InvCond); } + +public: + /// \brief Create an assume intrinsic call that represents an alignment + /// assumption on the provided pointer. + /// + /// An optional offset can be provided, and if it is provided, the offset + /// must be subtracted from the provided pointer to get the pointer with the + /// specified alignment. + CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue, + unsigned Alignment, + Value *OffsetValue = nullptr) { + assert(isa<PointerType>(PtrValue->getType()) && + "trying to create an alignment assumption on a non-pointer?"); + PointerType *PtrTy = cast<PointerType>(PtrValue->getType()); + Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace()); + + Value *Mask = ConstantInt::get(IntPtrTy, Alignment > 0 ? Alignment - 1 : 0); + return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy, + OffsetValue); + } + // + /// \brief Create an assume intrinsic call that represents an alignment + /// assumption on the provided pointer. + /// + /// An optional offset can be provided, and if it is provided, the offset + /// must be subtracted from the provided pointer to get the pointer with the + /// specified alignment. + /// + /// This overload handles the condition where the Alignment is dependent + /// on an existing value rather than a static value. + CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue, + Value *Alignment, + Value *OffsetValue = nullptr) { + assert(isa<PointerType>(PtrValue->getType()) && + "trying to create an alignment assumption on a non-pointer?"); + PointerType *PtrTy = cast<PointerType>(PtrValue->getType()); + Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace()); + + if (Alignment->getType() != IntPtrTy) + Alignment = CreateIntCast(Alignment, IntPtrTy, /*isSigned*/ true, + "alignmentcast"); + Value *IsPositive = + CreateICmp(CmpInst::ICMP_SGT, Alignment, + ConstantInt::get(Alignment->getType(), 0), "ispositive"); + Value *PositiveMask = + CreateSub(Alignment, ConstantInt::get(IntPtrTy, 1), "positivemask"); + Value *Mask = CreateSelect(IsPositive, PositiveMask, + ConstantInt::get(IntPtrTy, 0), "mask"); + + return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy, + OffsetValue); + } }; // Create wrappers for C Binding types (see CBindingWrapping.h). |