X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FConstantRange.cpp;h=fdfe28aaa95c88289d6cb830422f66f46f271e8a;hb=e15c2db9935eee66a8008f1bd09882aff2ed3aae;hp=becb8b61f78322b8535bb5b9bdc6357017419c42;hpb=3400e6af6b10acea219c02ac262637220f84218f;p=oota-llvm.git diff --git a/lib/Support/ConstantRange.cpp b/lib/Support/ConstantRange.cpp index becb8b61f78..fdfe28aaa95 100644 --- a/lib/Support/ConstantRange.cpp +++ b/lib/Support/ConstantRange.cpp @@ -44,22 +44,20 @@ ConstantRange::ConstantRange(const APInt &L, const APInt &U) : Lower(L), Upper(U) { assert(L.getBitWidth() == U.getBitWidth() && "ConstantRange with unequal bit widths"); - uint32_t BitWidth = L.getBitWidth(); - assert((L != U || (L == APInt::getMaxValue(BitWidth) || - L == APInt::getMinValue(BitWidth))) && + assert((L != U || (L.isMaxValue() || L.isMinValue())) && "Lower == Upper, but they aren't min or max value!"); } /// isFullSet - Return true if this set contains all of the elements possible /// for this data-type bool ConstantRange::isFullSet() const { - return Lower == Upper && Lower == APInt::getMaxValue(getBitWidth()); + return Lower == Upper && Lower.isMaxValue(); } /// isEmptySet - Return true if this set contains no members. /// bool ConstantRange::isEmptySet() const { - return Lower == Upper && Lower == APInt::getMinValue(getBitWidth()); + return Lower == Upper && Lower.isMinValue(); } /// isWrappedSet - Return true if this set wraps around the top of the range, @@ -108,9 +106,9 @@ APInt ConstantRange::getUnsignedMin() const { /// ConstantRange. /// APInt ConstantRange::getSignedMax() const { - APInt SignedMax = APInt::getSignedMaxValue(getBitWidth()); + APInt SignedMax(APInt::getSignedMaxValue(getBitWidth())); if (!isWrappedSet()) { - if (getLower().slt(getUpper() - 1)) + if (getLower().sle(getUpper() - 1)) return getUpper() - 1; else return SignedMax; @@ -130,9 +128,9 @@ APInt ConstantRange::getSignedMax() const { /// ConstantRange. /// APInt ConstantRange::getSignedMin() const { - APInt SignedMin = APInt::getSignedMinValue(getBitWidth()); + APInt SignedMin(APInt::getSignedMinValue(getBitWidth())); if (!isWrappedSet()) { - if (getLower().slt(getUpper() - 1)) + if (getLower().sle(getUpper() - 1)) return getLower(); else return SignedMin; @@ -248,11 +246,94 @@ ConstantRange ConstantRange::intersectWith(const ConstantRange &CR) const { return *this; } +/// maximalIntersectWith - Return the range that results from the intersection +/// of this range with another range. The resultant range is guaranteed to +/// include all elements contained in both input ranges, and to have the +/// smallest possible set size that does so. Because there may be two +/// intersections with the same set size, A.maximalIntersectWith(B) might not +/// be equal to B.maximalIntersect(A). +ConstantRange ConstantRange::maximalIntersectWith(const ConstantRange &CR) const { + assert(getBitWidth() == CR.getBitWidth() && + "ConstantRange types don't agree!"); + + // Handle common cases. + if ( isEmptySet() || CR.isFullSet()) return *this; + if (CR.isEmptySet() || isFullSet()) return CR; + + if (!isWrappedSet() && CR.isWrappedSet()) + return CR.maximalIntersectWith(*this); + + if (!isWrappedSet() && !CR.isWrappedSet()) { + if (Lower.ult(CR.Lower)) { + if (Upper.ule(CR.Lower)) + return ConstantRange(getBitWidth(), false); + + if (Upper.ult(CR.Upper)) + return ConstantRange(CR.Lower, Upper); + + return CR; + } else { + if (Upper.ult(CR.Upper)) + return *this; + + if (Lower.ult(CR.Upper)) + return ConstantRange(Lower, CR.Upper); + + return ConstantRange(getBitWidth(), false); + } + } + + if (isWrappedSet() && !CR.isWrappedSet()) { + if (CR.Lower.ult(Upper)) { + if (CR.Upper.ult(Upper)) + return CR; + + if (CR.Upper.ult(Lower)) + return ConstantRange(CR.Lower, Upper); + + if (getSetSize().ult(CR.getSetSize())) + return *this; + else + return CR; + } else if (CR.Lower.ult(Lower)) { + if (CR.Upper.ule(Lower)) + return ConstantRange(getBitWidth(), false); + + return ConstantRange(Lower, CR.Upper); + } + return CR; + } + + if (CR.Upper.ult(Upper)) { + if (CR.Lower.ult(Upper)) { + if (getSetSize().ult(CR.getSetSize())) + return *this; + else + return CR; + } + + if (CR.Lower.ult(Lower)) + return ConstantRange(Lower, CR.Upper); + + return CR; + } else if (CR.Upper.ult(Lower)) { + if (CR.Lower.ult(Lower)) + return *this; + + return ConstantRange(CR.Lower, Upper); + } + if (getSetSize().ult(CR.getSetSize())) + return *this; + else + return CR; +} + + /// unionWith - Return the range that results from the union of this range with /// another range. The resultant range is guaranteed to include the elements of -/// both sets, but may contain more. For example, [3, 9) union [12,15) is [3, -/// 15), which includes 9, 10, and 11, which were not included in either set -/// before. +/// both sets, but may contain more. For example, [3, 9) union [12,15) is +/// [3, 15), which includes 9, 10, and 11, which were not included in either +/// set before. /// ConstantRange ConstantRange::unionWith(const ConstantRange &CR) const { assert(getBitWidth() == CR.getBitWidth() && @@ -261,13 +342,71 @@ ConstantRange ConstantRange::unionWith(const ConstantRange &CR) const { if ( isFullSet() || CR.isEmptySet()) return *this; if (CR.isFullSet() || isEmptySet()) return CR; + if (!isWrappedSet() && CR.isWrappedSet()) return CR.unionWith(*this); + APInt L = Lower, U = Upper; - if (!contains(CR.Lower)) - L = APIntOps::umin(L, CR.Lower); + if (!isWrappedSet() && !CR.isWrappedSet()) { + if (CR.Lower.ult(L)) + L = CR.Lower; + + if (CR.Upper.ugt(U)) + U = CR.Upper; + } + + if (isWrappedSet() && !CR.isWrappedSet()) { + if ((CR.Lower.ult(Upper) && CR.Upper.ult(Upper)) || + (CR.Lower.ugt(Lower) && CR.Upper.ugt(Lower))) { + return *this; + } + + if (CR.Lower.ule(Upper) && Lower.ule(CR.Upper)) { + return ConstantRange(getBitWidth()); + } + + if (CR.Lower.ule(Upper) && CR.Upper.ule(Lower)) { + APInt d1 = CR.Upper - Upper, d2 = Lower - CR.Upper; + if (d1.ult(d2)) { + U = CR.Upper; + } else { + L = CR.Upper; + } + } + + if (Upper.ult(CR.Lower) && CR.Upper.ult(Lower)) { + APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Upper; + if (d1.ult(d2)) { + U = CR.Lower + 1; + } else { + L = CR.Upper - 1; + } + } + + if (Upper.ult(CR.Lower) && Lower.ult(CR.Upper)) { + APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Lower; + + if (d1.ult(d2)) { + U = CR.Lower + 1; + } else { + L = CR.Lower; + } + } + } + + if (isWrappedSet() && CR.isWrappedSet()) { + if (Lower.ult(CR.Upper) || CR.Lower.ult(Upper)) + return ConstantRange(getBitWidth()); + + if (CR.Upper.ugt(U)) { + U = CR.Upper; + } + + if (CR.Lower.ult(L)) { + L = CR.Lower; + } - if (!contains(CR.Upper - 1)) - U = APIntOps::umax(U, CR.Upper); + if (L == U) return ConstantRange(getBitWidth()); + } return ConstantRange(L, U); } @@ -288,6 +427,23 @@ ConstantRange ConstantRange::zeroExtend(uint32_t DstTySize) const { return ConstantRange(L, U); } +/// signExtend - 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 as if the source range had been +/// sign extended. +ConstantRange ConstantRange::signExtend(uint32_t DstTySize) const { + unsigned SrcTySize = getBitWidth(); + assert(SrcTySize < DstTySize && "Not a value extension"); + if (isFullSet()) { + return ConstantRange(APInt::getHighBitsSet(DstTySize,DstTySize-SrcTySize+1), + APInt::getLowBitsSet(DstTySize, SrcTySize-1)); + } + + APInt L = Lower; L.sext(DstTySize); + APInt U = Upper; U.sext(DstTySize); + return ConstantRange(L, U); +} + /// 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 as if the source range had been @@ -295,7 +451,7 @@ ConstantRange ConstantRange::zeroExtend(uint32_t DstTySize) const { ConstantRange ConstantRange::truncate(uint32_t DstTySize) const { unsigned SrcTySize = getBitWidth(); assert(SrcTySize > DstTySize && "Not a value truncation"); - APInt Size = APInt::getMaxValue(DstTySize).zext(SrcTySize); + APInt Size(APInt::getLowBitsSet(SrcTySize, DstTySize)); if (isFullSet() || getSetSize().ugt(Size)) return ConstantRange(DstTySize);