Skip to content

Commit

Permalink
LLVM Changes for alloc_align
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Erich Keane committed Mar 23, 2017
1 parent 8f33379 commit ee1fac6
Showing 1 changed file with 60 additions and 17 deletions.
77 changes: 60 additions & 17 deletions llvm/include/llvm/IR/IRBuilder.h
Expand Up @@ -1806,24 +1806,16 @@ class IRBuilder : public IRBuilderBase, public Inserter {
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))
Expand All @@ -1840,9 +1832,60 @@ class IRBuilder : public IRBuilderBase, public Inserter {
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).
Expand Down

0 comments on commit ee1fac6

Please sign in to comment.