LLVM API Documentation

ConstantRange.cpp

Go to the documentation of this file.
00001 //===-- ConstantRange.cpp - ConstantRange implementation ------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // Represent a range of possible values that may occur when the program is run
00011 // for an integral value.  This keeps track of a lower and upper bound for the
00012 // constant, which MAY wrap around the end of the numeric range.  To do this, it
00013 // keeps track of a [lower, upper) bound, which specifies an interval just like
00014 // STL iterators.  When used with boolean values, the following are important
00015 // ranges (other integral ranges use min/max values for special range values):
00016 //
00017 //  [F, F) = {}     = Empty set
00018 //  [T, F) = {T}
00019 //  [F, T) = {F}
00020 //  [T, T) = {F, T} = Full set
00021 //
00022 //===----------------------------------------------------------------------===//
00023 
00024 #include "llvm/Support/ConstantRange.h"
00025 #include "llvm/Support/raw_ostream.h"
00026 using namespace llvm;
00027 
00028 /// Initialize a full (the default) or empty set for the specified type.
00029 ///
00030 ConstantRange::ConstantRange(uint32_t BitWidth, bool Full) :
00031   Lower(BitWidth, 0), Upper(BitWidth, 0) {
00032   if (Full)
00033     Lower = Upper = APInt::getMaxValue(BitWidth);
00034   else
00035     Lower = Upper = APInt::getMinValue(BitWidth);
00036 }
00037 
00038 /// Initialize a range to hold the single specified value.
00039 ///
00040 ConstantRange::ConstantRange(const APInt & V) : Lower(V), Upper(V + 1) { }
00041 
00042 ConstantRange::ConstantRange(const APInt &L, const APInt &U) :
00043   Lower(L), Upper(U) {
00044   assert(L.getBitWidth() == U.getBitWidth() && 
00045          "ConstantRange with unequal bit widths");
00046   assert((L != U || (L.isMaxValue() || L.isMinValue())) &&
00047          "Lower == Upper, but they aren't min or max value!");
00048 }
00049 
00050 /// isFullSet - Return true if this set contains all of the elements possible
00051 /// for this data-type
00052 bool ConstantRange::isFullSet() const {
00053   return Lower == Upper && Lower.isMaxValue();
00054 }
00055 
00056 /// isEmptySet - Return true if this set contains no members.
00057 ///
00058 bool ConstantRange::isEmptySet() const {
00059   return Lower == Upper && Lower.isMinValue();
00060 }
00061 
00062 /// isWrappedSet - Return true if this set wraps around the top of the range,
00063 /// for example: [100, 8)
00064 ///
00065 bool ConstantRange::isWrappedSet() const {
00066   return Lower.ugt(Upper);
00067 }
00068 
00069 /// getSetSize - Return the number of elements in this set.
00070 ///
00071 APInt ConstantRange::getSetSize() const {
00072   if (isEmptySet()) 
00073     return APInt(getBitWidth(), 0);
00074   if (getBitWidth() == 1) {
00075     if (Lower != Upper)  // One of T or F in the set...
00076       return APInt(2, 1);
00077     return APInt(2, 2);      // Must be full set...
00078   }
00079 
00080   // Simply subtract the bounds...
00081   return Upper - Lower;
00082 }
00083 
00084 /// getUnsignedMax - Return the largest unsigned value contained in the
00085 /// ConstantRange.
00086 ///
00087 APInt ConstantRange::getUnsignedMax() const {
00088   if (isFullSet() || isWrappedSet())
00089     return APInt::getMaxValue(getBitWidth());
00090   else
00091     return getUpper() - 1;
00092 }
00093 
00094 /// getUnsignedMin - Return the smallest unsigned value contained in the
00095 /// ConstantRange.
00096 ///
00097 APInt ConstantRange::getUnsignedMin() const {
00098   if (isFullSet() || (isWrappedSet() && getUpper() != 0))
00099     return APInt::getMinValue(getBitWidth());
00100   else
00101     return getLower();
00102 }
00103 
00104 /// getSignedMax - Return the largest signed value contained in the
00105 /// ConstantRange.
00106 ///
00107 APInt ConstantRange::getSignedMax() const {
00108   APInt SignedMax(APInt::getSignedMaxValue(getBitWidth()));
00109   if (!isWrappedSet()) {
00110     if (getLower().sle(getUpper() - 1))
00111       return getUpper() - 1;
00112     else
00113       return SignedMax;
00114   } else {
00115     if ((getUpper() - 1).slt(getLower())) {
00116       if (getLower() != SignedMax)
00117         return SignedMax;
00118       else
00119         return getUpper() - 1;
00120     } else {
00121       return getUpper() - 1;
00122     }
00123   }
00124 }
00125 
00126 /// getSignedMin - Return the smallest signed value contained in the
00127 /// ConstantRange.
00128 ///
00129 APInt ConstantRange::getSignedMin() const {
00130   APInt SignedMin(APInt::getSignedMinValue(getBitWidth()));
00131   if (!isWrappedSet()) {
00132     if (getLower().sle(getUpper() - 1))
00133       return getLower();
00134     else
00135       return SignedMin;
00136   } else {
00137     if ((getUpper() - 1).slt(getLower())) {
00138       if (getUpper() != SignedMin)
00139         return SignedMin;
00140       else
00141         return getLower();
00142     } else {
00143       return getLower();
00144     }
00145   }
00146 }
00147 
00148 /// contains - Return true if the specified value is in the set.
00149 ///
00150 bool ConstantRange::contains(const APInt &V) const {
00151   if (Lower == Upper)
00152     return isFullSet();
00153 
00154   if (!isWrappedSet())
00155     return Lower.ule(V) && V.ult(Upper);
00156   else
00157     return Lower.ule(V) || V.ult(Upper);
00158 }
00159 
00160 /// subtract - Subtract the specified constant from the endpoints of this
00161 /// constant range.
00162 ConstantRange ConstantRange::subtract(const APInt &Val) const {
00163   assert(Val.getBitWidth() == getBitWidth() && "Wrong bit width");
00164   // If the set is empty or full, don't modify the endpoints.
00165   if (Lower == Upper) 
00166     return *this;
00167   return ConstantRange(Lower - Val, Upper - Val);
00168 }
00169 
00170 
00171 // intersect1Wrapped - This helper function is used to intersect two ranges when
00172 // it is known that LHS is wrapped and RHS isn't.
00173 //
00174 ConstantRange 
00175 ConstantRange::intersect1Wrapped(const ConstantRange &LHS,
00176                                  const ConstantRange &RHS) {
00177   assert(LHS.isWrappedSet() && !RHS.isWrappedSet());
00178 
00179   // Check to see if we overlap on the Left side of RHS...
00180   //
00181   if (RHS.Lower.ult(LHS.Upper)) {
00182     // We do overlap on the left side of RHS, see if we overlap on the right of
00183     // RHS...
00184     if (RHS.Upper.ugt(LHS.Lower)) {
00185       // Ok, the result overlaps on both the left and right sides.  See if the
00186       // resultant interval will be smaller if we wrap or not...
00187       //
00188       if (LHS.getSetSize().ult(RHS.getSetSize()))
00189         return LHS;
00190       else
00191         return RHS;
00192 
00193     } else {
00194       // No overlap on the right, just on the left.
00195       return ConstantRange(RHS.Lower, LHS.Upper);
00196     }
00197   } else {
00198     // We don't overlap on the left side of RHS, see if we overlap on the right
00199     // of RHS...
00200     if (RHS.Upper.ugt(LHS.Lower)) {
00201       // Simple overlap...
00202       return ConstantRange(LHS.Lower, RHS.Upper);
00203     } else {
00204       // No overlap...
00205       return ConstantRange(LHS.getBitWidth(), false);
00206     }
00207   }
00208 }
00209 
00210 /// intersectWith - Return the range that results from the intersection of this
00211 /// range with another range.
00212 ///
00213 ConstantRange ConstantRange::intersectWith(const ConstantRange &CR) const {
00214   assert(getBitWidth() == CR.getBitWidth() && 
00215          "ConstantRange types don't agree!");
00216   // Handle common special cases
00217   if (isEmptySet() || CR.isFullSet())  
00218     return *this;
00219   if (isFullSet()  || CR.isEmptySet()) 
00220     return CR;
00221 
00222   if (!isWrappedSet()) {
00223     if (!CR.isWrappedSet()) {
00224       using namespace APIntOps;
00225       APInt L = umax(Lower, CR.Lower);
00226       APInt U = umin(Upper, CR.Upper);
00227 
00228       if (L.ult(U)) // If range isn't empty...
00229         return ConstantRange(L, U);
00230       else
00231         return ConstantRange(getBitWidth(), false);// Otherwise, empty set
00232     } else
00233       return intersect1Wrapped(CR, *this);
00234   } else {   // We know "this" is wrapped...
00235     if (!CR.isWrappedSet())
00236       return intersect1Wrapped(*this, CR);
00237     else {
00238       // Both ranges are wrapped...
00239       using namespace APIntOps;
00240       APInt L = umax(Lower, CR.Lower);
00241       APInt U = umin(Upper, CR.Upper);
00242       return ConstantRange(L, U);
00243     }
00244   }
00245   return *this;
00246 }
00247 
00248 /// maximalIntersectWith - Return the range that results from the intersection
00249 /// of this range with another range.  The resultant range is guaranteed to
00250 /// include all elements contained in both input ranges, and to have the
00251 /// smallest possible set size that does so.  Because there may be two
00252 /// intersections with the same set size, A.maximalIntersectWith(B) might not
00253 /// be equal to B.maximalIntersect(A).
00254 ConstantRange ConstantRange::maximalIntersectWith(const ConstantRange &CR) const {
00255   assert(getBitWidth() == CR.getBitWidth() && 
00256          "ConstantRange types don't agree!");
00257 
00258   // Handle common cases.
00259   if (   isEmptySet() || CR.isFullSet()) return *this;
00260   if (CR.isEmptySet() ||    isFullSet()) return CR;
00261 
00262   if (!isWrappedSet() && CR.isWrappedSet())
00263     return CR.maximalIntersectWith(*this);
00264 
00265   if (!isWrappedSet() && !CR.isWrappedSet()) {
00266     if (Lower.ult(CR.Lower)) {
00267       if (Upper.ule(CR.Lower))
00268         return ConstantRange(getBitWidth(), false);
00269 
00270       if (Upper.ult(CR.Upper))
00271         return ConstantRange(CR.Lower, Upper);
00272 
00273       return CR;
00274     } else {
00275       if (Upper.ult(CR.Upper))
00276         return *this;
00277 
00278       if (Lower.ult(CR.Upper))
00279         return ConstantRange(Lower, CR.Upper);
00280 
00281       return ConstantRange(getBitWidth(), false);
00282     }
00283   }
00284 
00285   if (isWrappedSet() && !CR.isWrappedSet()) {
00286     if (CR.Lower.ult(Upper)) {
00287       if (CR.Upper.ult(Upper))
00288         return CR;
00289 
00290       if (CR.Upper.ult(Lower))
00291         return ConstantRange(CR.Lower, Upper);
00292 
00293       if (getSetSize().ult(CR.getSetSize()))
00294         return *this;
00295       else
00296         return CR;
00297     } else if (CR.Lower.ult(Lower)) {
00298       if (CR.Upper.ule(Lower))
00299         return ConstantRange(getBitWidth(), false);
00300 
00301       return ConstantRange(Lower, CR.Upper);
00302     }
00303     return CR;
00304   }
00305 
00306   if (CR.Upper.ult(Upper)) {
00307     if (CR.Lower.ult(Upper)) {
00308       if (getSetSize().ult(CR.getSetSize()))
00309         return *this;
00310       else
00311         return CR;
00312     }
00313 
00314     if (CR.Lower.ult(Lower))
00315       return ConstantRange(Lower, CR.Upper);
00316 
00317     return CR;
00318   } else if (CR.Upper.ult(Lower)) {
00319     if (CR.Lower.ult(Lower))
00320       return *this;
00321 
00322     return ConstantRange(CR.Lower, Upper);
00323   }
00324   if (getSetSize().ult(CR.getSetSize()))
00325     return *this;
00326   else
00327     return CR;
00328 }
00329 
00330 
00331 /// unionWith - Return the range that results from the union of this range with
00332 /// another range.  The resultant range is guaranteed to include the elements of
00333 /// both sets, but may contain more.  For example, [3, 9) union [12,15) is
00334 /// [3, 15), which includes 9, 10, and 11, which were not included in either
00335 /// set before.
00336 ///
00337 ConstantRange ConstantRange::unionWith(const ConstantRange &CR) const {
00338   assert(getBitWidth() == CR.getBitWidth() && 
00339          "ConstantRange types don't agree!");
00340 
00341   if (   isFullSet() || CR.isEmptySet()) return *this;
00342   if (CR.isFullSet() ||    isEmptySet()) return CR;
00343 
00344   if (!isWrappedSet() && CR.isWrappedSet()) return CR.unionWith(*this);
00345 
00346   APInt L = Lower, U = Upper;
00347 
00348   if (!isWrappedSet() && !CR.isWrappedSet()) {
00349     if (CR.Lower.ult(L))
00350       L = CR.Lower;
00351 
00352     if (CR.Upper.ugt(U))
00353       U = CR.Upper;
00354   }
00355 
00356   if (isWrappedSet() && !CR.isWrappedSet()) {
00357     if ((CR.Lower.ult(Upper) && CR.Upper.ult(Upper)) ||
00358         (CR.Lower.ugt(Lower) && CR.Upper.ugt(Lower))) {
00359       return *this;
00360     }
00361 
00362     if (CR.Lower.ule(Upper) && Lower.ule(CR.Upper)) {
00363       return ConstantRange(getBitWidth());
00364     }
00365 
00366     if (CR.Lower.ule(Upper) && CR.Upper.ule(Lower)) {
00367       APInt d1 = CR.Upper - Upper, d2 = Lower - CR.Upper;
00368       if (d1.ult(d2)) {
00369         U = CR.Upper;
00370       } else {
00371         L = CR.Upper;
00372       }
00373     }
00374 
00375     if (Upper.ult(CR.Lower) && CR.Upper.ult(Lower)) {
00376       APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Upper;
00377       if (d1.ult(d2)) {
00378         U = CR.Lower + 1;
00379       } else {
00380         L = CR.Upper - 1;
00381       }
00382     }
00383 
00384     if (Upper.ult(CR.Lower) && Lower.ult(CR.Upper)) {
00385       APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Lower;
00386 
00387       if (d1.ult(d2)) {
00388         U = CR.Lower + 1;
00389       } else {
00390         L = CR.Lower;
00391       }
00392     }
00393   }
00394 
00395   if (isWrappedSet() && CR.isWrappedSet()) {
00396     if (Lower.ult(CR.Upper) || CR.Lower.ult(Upper))
00397       return ConstantRange(getBitWidth());
00398 
00399     if (CR.Upper.ugt(U)) {
00400       U = CR.Upper;
00401     }
00402 
00403     if (CR.Lower.ult(L)) {
00404       L = CR.Lower;
00405     }
00406 
00407     if (L == U) return ConstantRange(getBitWidth());
00408   }
00409 
00410   return ConstantRange(L, U);
00411 }
00412 
00413 /// zeroExtend - Return a new range in the specified integer type, which must
00414 /// be strictly larger than the current type.  The returned range will
00415 /// correspond to the possible range of values as if the source range had been
00416 /// zero extended.
00417 ConstantRange ConstantRange::zeroExtend(uint32_t DstTySize) const {
00418   unsigned SrcTySize = getBitWidth();
00419   assert(SrcTySize < DstTySize && "Not a value extension");
00420   if (isFullSet())
00421     // Change a source full set into [0, 1 << 8*numbytes)
00422     return ConstantRange(APInt(DstTySize,0), APInt(DstTySize,1).shl(SrcTySize));
00423 
00424   APInt L = Lower; L.zext(DstTySize);
00425   APInt U = Upper; U.zext(DstTySize);
00426   return ConstantRange(L, U);
00427 }
00428 
00429 /// signExtend - Return a new range in the specified integer type, which must
00430 /// be strictly larger than the current type.  The returned range will
00431 /// correspond to the possible range of values as if the source range had been
00432 /// sign extended.
00433 ConstantRange ConstantRange::signExtend(uint32_t DstTySize) const {
00434   unsigned SrcTySize = getBitWidth();
00435   assert(SrcTySize < DstTySize && "Not a value extension");
00436   if (isFullSet()) {
00437     return ConstantRange(APInt::getHighBitsSet(DstTySize,DstTySize-SrcTySize+1),
00438                          APInt::getLowBitsSet(DstTySize, SrcTySize-1));
00439   }
00440 
00441   APInt L = Lower; L.sext(DstTySize);
00442   APInt U = Upper; U.sext(DstTySize);
00443   return ConstantRange(L, U);
00444 }
00445 
00446 /// truncate - Return a new range in the specified integer type, which must be
00447 /// strictly smaller than the current type.  The returned range will
00448 /// correspond to the possible range of values as if the source range had been
00449 /// truncated to the specified type.
00450 ConstantRange ConstantRange::truncate(uint32_t DstTySize) const {
00451   unsigned SrcTySize = getBitWidth();
00452   assert(SrcTySize > DstTySize && "Not a value truncation");
00453   APInt Size(APInt::getLowBitsSet(SrcTySize, DstTySize));
00454   if (isFullSet() || getSetSize().ugt(Size))
00455     return ConstantRange(DstTySize);
00456 
00457   APInt L = Lower; L.trunc(DstTySize);
00458   APInt U = Upper; U.trunc(DstTySize);
00459   return ConstantRange(L, U);
00460 }
00461 
00462 /// print - Print out the bounds to a stream...
00463 ///
00464 void ConstantRange::print(raw_ostream &OS) const {
00465   OS << "[" << Lower << "," << Upper << ")";
00466 }
00467 
00468 /// dump - Allow printing from a debugger easily...
00469 ///
00470 void ConstantRange::dump() const {
00471   print(errs());
00472 }



This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.