Skip to content

Commit

Permalink
Refactor computeKnownBits alignment handling code
Browse files Browse the repository at this point in the history
Reviewed By: reames, hfinkel

Differential Revision: http://reviews.llvm.org/D12958

llvm-svn: 248892
  • Loading branch information
arpilipe committed Sep 30, 2015
1 parent dade196 commit 029d853
Showing 1 changed file with 38 additions and 53 deletions.
91 changes: 38 additions & 53 deletions llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1409,6 +1409,37 @@ static void computeKnownBitsFromOperator(Operator *I, APInt &KnownZero,
}
}

static unsigned getAlignment(Value *V, const DataLayout &DL) {
unsigned Align = 0;
if (auto *GO = dyn_cast<GlobalObject>(V)) {
Align = GO->getAlignment();
if (Align == 0) {
if (auto *GVar = dyn_cast<GlobalVariable>(GO)) {
Type *ObjectType = GVar->getType()->getElementType();
if (ObjectType->isSized()) {
// If the object is defined in the current Module, we'll be giving
// it the preferred alignment. Otherwise, we have to assume that it
// may only have the minimum ABI alignment.
if (GVar->isStrongDefinitionForLinker())
Align = DL.getPreferredAlignment(GVar);
else
Align = DL.getABITypeAlignment(ObjectType);
}
}
}
} else if (Argument *A = dyn_cast<Argument>(V)) {
Align = A->getType()->isPointerTy() ? A->getParamAlignment() : 0;

if (!Align && A->hasStructRetAttr()) {
// An sret parameter has at least the ABI alignment of the return type.
Type *EltTy = cast<PointerType>(A->getType())->getElementType();
if (EltTy->isSized())
Align = DL.getABITypeAlignment(EltTy);
}
}
return Align;
}

/// Determine which bits of V are known to be either zero or one and return
/// them in the KnownZero/KnownOne bit sets.
///
Expand Down Expand Up @@ -1469,59 +1500,6 @@ void computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne,
return;
}

// The address of an aligned GlobalValue has trailing zeros.
if (auto *GO = dyn_cast<GlobalObject>(V)) {
unsigned Align = GO->getAlignment();
if (Align == 0) {
if (auto *GVar = dyn_cast<GlobalVariable>(GO)) {
Type *ObjectType = GVar->getType()->getElementType();
if (ObjectType->isSized()) {
// If the object is defined in the current Module, we'll be giving
// it the preferred alignment. Otherwise, we have to assume that it
// may only have the minimum ABI alignment.
if (GVar->isStrongDefinitionForLinker())
Align = DL.getPreferredAlignment(GVar);
else
Align = DL.getABITypeAlignment(ObjectType);
}
}
}
if (Align > 0)
KnownZero = APInt::getLowBitsSet(BitWidth,
countTrailingZeros(Align));
else
KnownZero.clearAllBits();
KnownOne.clearAllBits();
return;
}

if (Argument *A = dyn_cast<Argument>(V)) {
unsigned Align = A->getType()->isPointerTy() ? A->getParamAlignment() : 0;

if (!Align && A->hasStructRetAttr()) {
// An sret parameter has at least the ABI alignment of the return type.
Type *EltTy = cast<PointerType>(A->getType())->getElementType();
if (EltTy->isSized())
Align = DL.getABITypeAlignment(EltTy);
}

if (Align)
KnownZero = APInt::getLowBitsSet(BitWidth, countTrailingZeros(Align));
else
KnownZero.clearAllBits();
KnownOne.clearAllBits();

// Don't give up yet... there might be an assumption that provides more
// information...
computeKnownBitsFromAssume(V, KnownZero, KnownOne, DL, Depth, Q);

// Or a dominating condition for that matter
if (EnableDomConditions && Depth <= DomConditionsMaxDepth)
computeKnownBitsFromDominatingCondition(V, KnownZero, KnownOne, DL,
Depth, Q);
return;
}

// Start out not knowing anything.
KnownZero.clearAllBits(); KnownOne.clearAllBits();

Expand All @@ -1541,6 +1519,13 @@ void computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne,
if (Operator *I = dyn_cast<Operator>(V))
computeKnownBitsFromOperator(I, KnownZero, KnownOne, DL, Depth, Q);

// Aligned pointers have trailing zeros - refine KnownZero set
if (V->getType()->isPointerTy()) {
unsigned Align = getAlignment(V, DL);
if (Align)
KnownZero |= APInt::getLowBitsSet(BitWidth, countTrailingZeros(Align));
}

// computeKnownBitsFromAssume and computeKnownBitsFromDominatingCondition
// strictly refines KnownZero and KnownOne. Therefore, we run them after
// computeKnownBitsFromOperator.
Expand Down

0 comments on commit 029d853

Please sign in to comment.