X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FConstantRange.cpp;h=0d22b323502174376c92db9023299ea1be7f338f;hb=73b43b9b549a75fb0015c825df68abd95705a67c;hp=966de801be0b082ced58d4bab8cdb32de2adf67c;hpb=ae5eb7accf65ee94e22b3d235d466d71268f1e83;p=oota-llvm.git diff --git a/lib/Support/ConstantRange.cpp b/lib/Support/ConstantRange.cpp index 966de801be0..0d22b323502 100644 --- a/lib/Support/ConstantRange.cpp +++ b/lib/Support/ConstantRange.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -246,6 +246,89 @@ 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 @@ -381,7 +464,7 @@ ConstantRange ConstantRange::truncate(uint32_t DstTySize) const { /// void ConstantRange::print(std::ostream &OS) const { OS << "[" << Lower.toStringSigned(10) << "," - << Upper.toStringSigned(10) << " )"; + << Upper.toStringSigned(10) << ")"; } /// dump - Allow printing from a debugger easily...