diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/Analysis/ScalarEvolution.h | 7 | ||||
| -rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 59 | 
2 files changed, 66 insertions, 0 deletions
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h index e3d429934cc..41725be1ca3 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -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. diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index fd97db8a9dc..98ab6f484ea 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -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  | 

