Add a ScalarEvolution::getAnyExtendExpr utility function for performing

extension with unspecified bits.

llvm-svn: 73293
This commit is contained in:
Dan Gohman 2009-06-13 15:56:47 +00:00
parent 9782caa369
commit 8db2edcf7f
2 changed files with 66 additions and 0 deletions

View File

@ -393,6 +393,7 @@ namespace llvm {
SCEVHandle getTruncateExpr(const SCEVHandle &Op, const Type *Ty);
SCEVHandle getZeroExtendExpr(const SCEVHandle &Op, const Type *Ty);
SCEVHandle getSignExtendExpr(const SCEVHandle &Op, const Type *Ty);
SCEVHandle getAnyExtendExpr(const SCEVHandle &Op, const Type *Ty);
SCEVHandle getAddExpr(std::vector<SCEVHandle> &Ops);
SCEVHandle getAddExpr(const SCEVHandle &LHS, const SCEVHandle &RHS) {
std::vector<SCEVHandle> Ops;
@ -465,6 +466,12 @@ namespace llvm {
/// it is sign extended. The conversion must not be narrowing.
SCEVHandle getNoopOrSignExtend(const SCEVHandle &V, const Type *Ty);
/// getNoopOrAnyExtend - Return a SCEV corresponding to a conversion of
/// the input value to the specified type. If the type must be extended,
/// it is extended with unspecified bits. The conversion must not be
/// narrowing.
SCEVHandle getNoopOrAnyExtend(const SCEVHandle &V, const Type *Ty);
/// getTruncateOrNoop - Return a SCEV corresponding to a conversion of the
/// input value to the specified type. The conversion must not be
/// widening.

View File

@ -937,6 +937,48 @@ SCEVHandle ScalarEvolution::getSignExtendExpr(const SCEVHandle &Op,
return Result;
}
/// getAnyExtendExpr - Return a SCEV for the given operand extended with
/// unspecified bits out to the given type.
///
SCEVHandle ScalarEvolution::getAnyExtendExpr(const SCEVHandle &Op,
const Type *Ty) {
assert(getTypeSizeInBits(Op->getType()) < getTypeSizeInBits(Ty) &&
"This is not an extending conversion!");
assert(isSCEVable(Ty) &&
"This is not a conversion to a SCEVable type!");
Ty = getEffectiveSCEVType(Ty);
// Sign-extend negative constants.
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(Op))
if (SC->getValue()->getValue().isNegative())
return getSignExtendExpr(Op, Ty);
// Peel off a truncate cast.
if (const SCEVTruncateExpr *T = dyn_cast<SCEVTruncateExpr>(Op)) {
SCEVHandle NewOp = T->getOperand();
if (getTypeSizeInBits(NewOp->getType()) < getTypeSizeInBits(Ty))
return getAnyExtendExpr(NewOp, Ty);
return getTruncateOrNoop(NewOp, Ty);
}
// Next try a zext cast. If the cast is folded, use it.
SCEVHandle ZExt = getZeroExtendExpr(Op, Ty);
if (!isa<SCEVZeroExtendExpr>(ZExt))
return ZExt;
// Next try a sext cast. If the cast is folded, use it.
SCEVHandle SExt = getSignExtendExpr(Op, Ty);
if (!isa<SCEVSignExtendExpr>(SExt))
return SExt;
// If the expression is obviously signed, use the sext cast value.
if (isa<SCEVSMaxExpr>(Op))
return SExt;
// Absent any other information, use the zext cast value.
return ZExt;
}
/// getAddExpr - Get a canonical add expression, or something simpler if
/// possible.
SCEVHandle ScalarEvolution::getAddExpr(std::vector<SCEVHandle> &Ops) {
@ -1903,6 +1945,23 @@ ScalarEvolution::getNoopOrSignExtend(const SCEVHandle &V, const Type *Ty) {
return getSignExtendExpr(V, Ty);
}
/// getNoopOrAnyExtend - Return a SCEV corresponding to a conversion of
/// the input value to the specified type. If the type must be extended,
/// it is extended with unspecified bits. The conversion must not be
/// narrowing.
SCEVHandle
ScalarEvolution::getNoopOrAnyExtend(const SCEVHandle &V, const Type *Ty) {
const Type *SrcTy = V->getType();
assert((SrcTy->isInteger() || (TD && isa<PointerType>(SrcTy))) &&
(Ty->isInteger() || (TD && isa<PointerType>(Ty))) &&
"Cannot noop or any extend with non-integer arguments!");
assert(getTypeSizeInBits(SrcTy) <= getTypeSizeInBits(Ty) &&
"getNoopOrAnyExtend cannot truncate!");
if (getTypeSizeInBits(SrcTy) == getTypeSizeInBits(Ty))
return V; // No conversion
return getAnyExtendExpr(V, Ty);
}
/// getTruncateOrNoop - Return a SCEV corresponding to a conversion of the
/// input value to the specified type. The conversion must not be widening.
SCEVHandle