X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FConstantRange.cpp;h=3b91c5bc7a06175bc4dc0036da0379964f997d3b;hb=4d143ee01988e1b52e106ffccbb313937ca5e886;hp=e180f12a1a045f2b7fa14fa731c90bc8d266e081;hpb=d0fde30ce850b78371fd1386338350591f9ff494;p=oota-llvm.git diff --git a/lib/VMCore/ConstantRange.cpp b/lib/VMCore/ConstantRange.cpp index e180f12a1a0..3b91c5bc7a0 100644 --- a/lib/VMCore/ConstantRange.cpp +++ b/lib/VMCore/ConstantRange.cpp @@ -22,11 +22,42 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/ConstantRange.h" -#include "llvm/Type.h" +#include "llvm/Constants.h" #include "llvm/Instruction.h" -#include "llvm/ConstantHandling.h" +#include "llvm/Type.h" +#include + +using namespace llvm; + +static ConstantIntegral *Next(ConstantIntegral *CI) { + if (CI->getType() == Type::BoolTy) + return CI == ConstantBool::True ? ConstantBool::False : ConstantBool::True; + + Constant *Result = ConstantExpr::getAdd(CI, + ConstantInt::get(CI->getType(), 1)); + return cast(Result); +} + +static bool LT(ConstantIntegral *A, ConstantIntegral *B) { + Constant *C = ConstantExpr::getSetLT(A, B); + assert(isa(C) && "Constant folding of integrals not impl??"); + return cast(C)->getValue(); +} + +static bool LTE(ConstantIntegral *A, ConstantIntegral *B) { + Constant *C = ConstantExpr::getSetLE(A, B); + assert(isa(C) && "Constant folding of integrals not impl??"); + return cast(C)->getValue(); +} -namespace llvm { +static bool GT(ConstantIntegral *A, ConstantIntegral *B) { return LT(B, A); } + +static ConstantIntegral *Min(ConstantIntegral *A, ConstantIntegral *B) { + return LT(A, B) ? A : B; +} +static ConstantIntegral *Max(ConstantIntegral *A, ConstantIntegral *B) { + return GT(A, B) ? A : B; +} /// Initialize a full (the default) or empty set for the specified type. /// @@ -39,12 +70,18 @@ ConstantRange::ConstantRange(const Type *Ty, bool Full) { Lower = Upper = ConstantIntegral::getMinValue(Ty); } +/// Initialize a range to hold the single specified value. +/// +ConstantRange::ConstantRange(Constant *V) + : Lower(cast(V)), Upper(Next(cast(V))) { +} + /// Initialize a range of values explicitly... this will assert out if /// Lower==Upper and Lower != Min or Max for its type (or if the two constants /// have different types) /// -ConstantRange::ConstantRange(ConstantIntegral *L, - ConstantIntegral *U) : Lower(L), Upper(U) { +ConstantRange::ConstantRange(Constant *L, Constant *U) + : Lower(cast(L)), Upper(cast(U)) { assert(Lower->getType() == Upper->getType() && "Incompatible types for ConstantRange!"); @@ -54,16 +91,6 @@ ConstantRange::ConstantRange(ConstantIntegral *L, "Lower == Upper, but they aren't min or max for type!"); } -static ConstantIntegral *Next(ConstantIntegral *CI) { - if (CI->getType() == Type::BoolTy) - return CI == ConstantBool::True ? ConstantBool::False : ConstantBool::True; - - // Otherwise use operator+ in the ConstantHandling Library. - Constant *Result = *ConstantInt::get(CI->getType(), 1) + *CI; - assert(Result && "ConstantHandling not implemented for integral plus!?"); - return cast(Result); -} - /// Initialize a set of values that all satisfy the condition with C. /// ConstantRange::ConstantRange(unsigned SetCCOpcode, ConstantIntegral *C) { @@ -110,7 +137,7 @@ bool ConstantRange::isEmptySet() const { /// for example: [100, 8) /// bool ConstantRange::isWrappedSet() const { - return (*(Constant*)Lower > *(Constant*)Upper)->getValue(); + return GT(Lower, Upper); } @@ -133,14 +160,37 @@ uint64_t ConstantRange::getSetSize() const { } // Simply subtract the bounds... - Constant *Result = *(Constant*)Upper - *(Constant*)Lower; - assert(Result && "Subtraction of constant integers not implemented?"); + Constant *Result = ConstantExpr::getSub(Upper, Lower); return cast(Result)->getRawValue(); } +/// contains - Return true if the specified value is in the set. +/// +bool ConstantRange::contains(ConstantInt *Val) const { + if (Lower == Upper) { + if (isFullSet()) return true; + return false; + } + + if (!isWrappedSet()) + return LTE(Lower, Val) && LT(Val, Upper); + return LTE(Lower, Val) || LT(Val, Upper); +} +/// subtract - Subtract the specified constant from the endpoints of this +/// constant range. +ConstantRange ConstantRange::subtract(ConstantInt *CI) const { + assert(CI->getType() == getType() && getType()->isInteger() && + "Cannot subtract from different type range or non-integer!"); + // If the set is empty or full, don't modify the endpoints. + if (Lower == Upper) return *this; + return ConstantRange(ConstantExpr::getSub(Lower, CI), + ConstantExpr::getSub(Upper, CI)); +} + + // intersect1Wrapped - This helper function is used to intersect two ranges when // it is known that LHS is wrapped and RHS isn't. // @@ -150,10 +200,10 @@ static ConstantRange intersect1Wrapped(const ConstantRange &LHS, // Check to see if we overlap on the Left side of RHS... // - if ((*(Constant*)RHS.getLower() < *(Constant*)LHS.getUpper())->getValue()) { + if (LT(RHS.getLower(), LHS.getUpper())) { // We do overlap on the left side of RHS, see if we overlap on the right of // RHS... - if ((*(Constant*)RHS.getUpper() > *(Constant*)LHS.getLower())->getValue()) { + if (GT(RHS.getUpper(), LHS.getLower())) { // Ok, the result overlaps on both the left and right sides. See if the // resultant interval will be smaller if we wrap or not... // @@ -170,7 +220,7 @@ static ConstantRange intersect1Wrapped(const ConstantRange &LHS, } else { // We don't overlap on the left side of RHS, see if we overlap on the right // of RHS... - if ((*(Constant*)RHS.getUpper() > *(Constant*)LHS.getLower())->getValue()) { + if (GT(RHS.getUpper(), LHS.getLower())) { // Simple overlap... return ConstantRange(LHS.getLower(), RHS.getUpper()); } else { @@ -180,18 +230,6 @@ static ConstantRange intersect1Wrapped(const ConstantRange &LHS, } } -static ConstantIntegral *Min(ConstantIntegral *A, ConstantIntegral *B) { - if ((*(Constant*)A < *(Constant*)B)->getValue()) - return A; - return B; -} -static ConstantIntegral *Max(ConstantIntegral *A, ConstantIntegral *B) { - if ((*(Constant*)A > *(Constant*)B)->getValue()) - return A; - return B; -} - - /// intersect - Return the range that results from the intersection of this /// range with another range. /// @@ -206,7 +244,7 @@ ConstantRange ConstantRange::intersectWith(const ConstantRange &CR) const { ConstantIntegral *L = Max(Lower, CR.Lower); ConstantIntegral *U = Min(Upper, CR.Upper); - if ((*L < *U)->getValue()) // If range isn't empty... + if (LT(L, U)) // If range isn't empty... return ConstantRange(L, U); else return ConstantRange(getType(), false); // Otherwise, return empty set @@ -239,10 +277,52 @@ ConstantRange ConstantRange::unionWith(const ConstantRange &CR) const { return *this; } +/// zeroExtend - Return a new range in the specified integer type, which must +/// be strictly larger than the current type. The returned range will +/// correspond to the possible range of values if the source range had been +/// zero extended. +ConstantRange ConstantRange::zeroExtend(const Type *Ty) const { + assert(getLower()->getType()->getPrimitiveSize() < Ty->getPrimitiveSize() && + "Not a value extension"); + if (isFullSet()) { + // Change a source full set into [0, 1 << 8*numbytes) + unsigned SrcTySize = getLower()->getType()->getPrimitiveSize(); + return ConstantRange(Constant::getNullValue(Ty), + ConstantUInt::get(Ty, 1ULL << SrcTySize*8)); + } + + Constant *Lower = getLower(); + Constant *Upper = getUpper(); + if (Lower->getType()->isInteger() && !Lower->getType()->isUnsigned()) { + // Ensure we are doing a ZERO extension even if the input range is signed. + Lower = ConstantExpr::getCast(Lower, Ty->getUnsignedVersion()); + Upper = ConstantExpr::getCast(Upper, Ty->getUnsignedVersion()); + } + + return ConstantRange(ConstantExpr::getCast(Lower, Ty), + ConstantExpr::getCast(Upper, Ty)); +} + +/// truncate - Return a new range in the specified integer type, which must be +/// strictly smaller than the current type. The returned range will +/// correspond to the possible range of values if the source range had been +/// truncated to the specified type. +ConstantRange ConstantRange::truncate(const Type *Ty) const { + assert(getLower()->getType()->getPrimitiveSize() > Ty->getPrimitiveSize() && + "Not a value truncation"); + uint64_t Size = 1ULL << Ty->getPrimitiveSize()*8; + if (isFullSet() || getSetSize() >= Size) + return ConstantRange(getType()); + + return ConstantRange(ConstantExpr::getCast(getLower(), Ty), + ConstantExpr::getCast(getUpper(), Ty)); +} + + /// print - Print out the bounds to a stream... /// void ConstantRange::print(std::ostream &OS) const { - OS << "[" << Lower << "," << Upper << " )"; + OS << "[" << *Lower << "," << *Upper << " )"; } /// dump - Allow printing from a debugger easily... @@ -250,5 +330,3 @@ void ConstantRange::print(std::ostream &OS) const { void ConstantRange::dump() const { print(std::cerr); } - -} // End llvm namespace