diff options
| author | Erich Keane <erich.keane@intel.com> | 2017-03-23 20:38:34 +0000 | 
|---|---|---|
| committer | Erich Keane <erich.keane@intel.com> | 2017-03-23 20:38:34 +0000 | 
| commit | ee1fac61d842d628ffe01c5fadd47fd936a2312f (patch) | |
| tree | f9eede396d7378ab4e2aac36e9753fe35daa8904 /llvm/include | |
| parent | 8f3337950e88ae7934ffda13f15f1b9dc7e6a9a5 (diff) | |
| download | bcm5719-llvm-ee1fac61d842d628ffe01c5fadd47fd936a2312f.tar.gz bcm5719-llvm-ee1fac61d842d628ffe01c5fadd47fd936a2312f.zip | |
LLVM Changes for alloc_align
GCC has the alloc_align attribute, which is similar to assume_aligned, except the attribute's parameter is the index of the integer parameter that needs aligning to.
This is the required LLVM changes to make this happen.
Differential Revision: https://reviews.llvm.org/D29598
llvm-svn: 298643
Diffstat (limited to 'llvm/include')
| -rw-r--r-- | llvm/include/llvm/IR/IRBuilder.h | 77 | 
1 files changed, 60 insertions, 17 deletions
| diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index fb26aeb33df..bd2123701ba 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -1806,24 +1806,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)) @@ -1840,9 +1832,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). | 

