mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	Move a method that creates constant ranges relative to another constant range
per icmp predicate out of predsimplify and into ConstantRange. Add another utility method that determines whether one range is a subset of another. Combine with the former to determine whether icmp pred range, range is known to be true or not. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75357 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -58,6 +58,12 @@ public: | |||||||
|   /// assert out if the two APInt's are not the same bit width. |   /// assert out if the two APInt's are not the same bit width. | ||||||
|   ConstantRange(const APInt& Lower, const APInt& Upper); |   ConstantRange(const APInt& Lower, const APInt& Upper); | ||||||
|  |  | ||||||
|  |   /// makeICmpRegion - Return the range of values that a value must be within | ||||||
|  |   /// in order for the comparison specified by the predicate against range | ||||||
|  |   /// Other to be true. | ||||||
|  |   static ConstantRange makeICmpRegion(unsigned Pred, | ||||||
|  |                                       const ConstantRange &Other); | ||||||
|  |  | ||||||
|   /// getLower - Return the lower value for this range... |   /// getLower - Return the lower value for this range... | ||||||
|   /// |   /// | ||||||
|   const APInt &getLower() const { return Lower; } |   const APInt &getLower() const { return Lower; } | ||||||
| @@ -88,6 +94,10 @@ public: | |||||||
|   /// |   /// | ||||||
|   bool contains(const APInt &Val) const; |   bool contains(const APInt &Val) const; | ||||||
|  |  | ||||||
|  |   /// contains - Return true if the other range is a subset of this one. | ||||||
|  |   /// | ||||||
|  |   bool contains(const ConstantRange &CR) const; | ||||||
|  |  | ||||||
|   /// getSingleElement - If this set contains a single element, return it, |   /// getSingleElement - If this set contains a single element, return it, | ||||||
|   /// otherwise return null. |   /// otherwise return null. | ||||||
|   /// |   /// | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ | |||||||
|  |  | ||||||
| #include "llvm/Support/ConstantRange.h" | #include "llvm/Support/ConstantRange.h" | ||||||
| #include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | ||||||
|  | #include "llvm/Instructions.h" | ||||||
| using namespace llvm; | using namespace llvm; | ||||||
|  |  | ||||||
| /// Initialize a full (the default) or empty set for the specified type. | /// Initialize a full (the default) or empty set for the specified type. | ||||||
| @@ -46,6 +47,53 @@ ConstantRange::ConstantRange(const APInt &L, const APInt &U) : | |||||||
|          "Lower == Upper, but they aren't min or max value!"); |          "Lower == Upper, but they aren't min or max value!"); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | ConstantRange ConstantRange::makeICmpRegion(unsigned Pred, | ||||||
|  |                                             const ConstantRange &CR) { | ||||||
|  |   uint32_t W = CR.getBitWidth(); | ||||||
|  |   switch (Pred) { | ||||||
|  |     default: assert(!"Invalid ICmp predicate to makeICmpRegion()"); | ||||||
|  |     case ICmpInst::ICMP_EQ: | ||||||
|  |       return ConstantRange(CR.getLower(), CR.getUpper()); | ||||||
|  |     case ICmpInst::ICMP_NE: | ||||||
|  |       if (CR.isSingleElement()) | ||||||
|  |         return ConstantRange(CR.getUpper(), CR.getLower()); | ||||||
|  |       return ConstantRange(W); | ||||||
|  |     case ICmpInst::ICMP_ULT: | ||||||
|  |       return ConstantRange(APInt::getMinValue(W), CR.getUnsignedMax()); | ||||||
|  |     case ICmpInst::ICMP_SLT: | ||||||
|  |       return ConstantRange(APInt::getSignedMinValue(W), CR.getSignedMax()); | ||||||
|  |     case ICmpInst::ICMP_ULE: { | ||||||
|  |       APInt UMax(CR.getUnsignedMax()); | ||||||
|  |       if (UMax.isMaxValue()) | ||||||
|  |         return ConstantRange(W); | ||||||
|  |       return ConstantRange(APInt::getMinValue(W), UMax + 1); | ||||||
|  |     } | ||||||
|  |     case ICmpInst::ICMP_SLE: { | ||||||
|  |       APInt SMax(CR.getSignedMax()); | ||||||
|  |       if (SMax.isMaxSignedValue() || (SMax+1).isMaxSignedValue()) | ||||||
|  |         return ConstantRange(W); | ||||||
|  |       return ConstantRange(APInt::getSignedMinValue(W), SMax + 1); | ||||||
|  |     } | ||||||
|  |     case ICmpInst::ICMP_UGT: | ||||||
|  |       return ConstantRange(CR.getUnsignedMin() + 1, APInt::getNullValue(W)); | ||||||
|  |     case ICmpInst::ICMP_SGT: | ||||||
|  |       return ConstantRange(CR.getSignedMin() + 1, | ||||||
|  |                            APInt::getSignedMinValue(W)); | ||||||
|  |     case ICmpInst::ICMP_UGE: { | ||||||
|  |       APInt UMin(CR.getUnsignedMin()); | ||||||
|  |       if (UMin.isMinValue()) | ||||||
|  |         return ConstantRange(W); | ||||||
|  |       return ConstantRange(UMin, APInt::getNullValue(W)); | ||||||
|  |     } | ||||||
|  |     case ICmpInst::ICMP_SGE: { | ||||||
|  |       APInt SMin(CR.getSignedMin()); | ||||||
|  |       if (SMin.isMinSignedValue()) | ||||||
|  |         return ConstantRange(W); | ||||||
|  |       return ConstantRange(SMin, APInt::getSignedMinValue(W)); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| /// isFullSet - Return true if this set contains all of the elements possible | /// isFullSet - Return true if this set contains all of the elements possible | ||||||
| /// for this data-type | /// for this data-type | ||||||
| bool ConstantRange::isFullSet() const { | bool ConstantRange::isFullSet() const { | ||||||
| @@ -156,6 +204,30 @@ bool ConstantRange::contains(const APInt &V) const { | |||||||
|     return Lower.ule(V) || V.ult(Upper); |     return Lower.ule(V) || V.ult(Upper); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// contains - Return true if the argument is a subset of this range. | ||||||
|  | /// Two equal set contain each other. The empty set is considered to be | ||||||
|  | /// contained by all other sets. | ||||||
|  | /// | ||||||
|  | bool ConstantRange::contains(const ConstantRange &Other) const { | ||||||
|  |   if (isFullSet()) return true; | ||||||
|  |   if (Other.isFullSet()) return false; | ||||||
|  |   if (Other.isEmptySet()) return true; | ||||||
|  |   if (isEmptySet()) return false; | ||||||
|  |  | ||||||
|  |   if (!isWrappedSet()) { | ||||||
|  |     if (Other.isWrappedSet()) | ||||||
|  |       return false; | ||||||
|  |  | ||||||
|  |     return Lower.ule(Other.getLower()) && Other.getUpper().ule(Upper); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (!Other.isWrappedSet()) | ||||||
|  |     return Other.getUpper().ule(Upper) || | ||||||
|  |            Lower.ule(Other.getLower()); | ||||||
|  |  | ||||||
|  |   return Other.getUpper().ule(Upper) && Lower.ule(Other.getLower()); | ||||||
|  | } | ||||||
|  |  | ||||||
| /// subtract - Subtract the specified constant from the endpoints of this | /// subtract - Subtract the specified constant from the endpoints of this | ||||||
| /// constant range. | /// constant range. | ||||||
| ConstantRange ConstantRange::subtract(const APInt &Val) const { | ConstantRange ConstantRange::subtract(const APInt &Val) const { | ||||||
|   | |||||||
| @@ -990,7 +990,7 @@ namespace { | |||||||
|       assert(!CR.isEmptySet() && "Can't deal with empty set."); |       assert(!CR.isEmptySet() && "Can't deal with empty set."); | ||||||
|  |  | ||||||
|       if (LV == NE) |       if (LV == NE) | ||||||
|         return makeConstantRange(ICmpInst::ICMP_NE, CR); |         return ConstantRange::makeICmpRegion(ICmpInst::ICMP_NE, CR); | ||||||
|  |  | ||||||
|       unsigned LV_s = LV & (SGT_BIT|SLT_BIT); |       unsigned LV_s = LV & (SGT_BIT|SLT_BIT); | ||||||
|       unsigned LV_u = LV & (UGT_BIT|ULT_BIT); |       unsigned LV_u = LV & (UGT_BIT|ULT_BIT); | ||||||
| @@ -999,73 +999,24 @@ namespace { | |||||||
|       ConstantRange Range(CR.getBitWidth()); |       ConstantRange Range(CR.getBitWidth()); | ||||||
|  |  | ||||||
|       if (LV_s == SGT_BIT) { |       if (LV_s == SGT_BIT) { | ||||||
|         Range = Range.maximalIntersectWith(makeConstantRange( |         Range = Range.maximalIntersectWith(ConstantRange::makeICmpRegion( | ||||||
|                     hasEQ ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_SGT, CR)); |                     hasEQ ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_SGT, CR)); | ||||||
|       } else if (LV_s == SLT_BIT) { |       } else if (LV_s == SLT_BIT) { | ||||||
|         Range = Range.maximalIntersectWith(makeConstantRange( |         Range = Range.maximalIntersectWith(ConstantRange::makeICmpRegion( | ||||||
|                     hasEQ ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_SLT, CR)); |                     hasEQ ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_SLT, CR)); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       if (LV_u == UGT_BIT) { |       if (LV_u == UGT_BIT) { | ||||||
|         Range = Range.maximalIntersectWith(makeConstantRange( |         Range = Range.maximalIntersectWith(ConstantRange::makeICmpRegion( | ||||||
|                     hasEQ ? ICmpInst::ICMP_UGE : ICmpInst::ICMP_UGT, CR)); |                     hasEQ ? ICmpInst::ICMP_UGE : ICmpInst::ICMP_UGT, CR)); | ||||||
|       } else if (LV_u == ULT_BIT) { |       } else if (LV_u == ULT_BIT) { | ||||||
|         Range = Range.maximalIntersectWith(makeConstantRange( |         Range = Range.maximalIntersectWith(ConstantRange::makeICmpRegion( | ||||||
|                     hasEQ ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_ULT, CR)); |                     hasEQ ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_ULT, CR)); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       return Range; |       return Range; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// makeConstantRange - Creates a ConstantRange representing the set of all |  | ||||||
|     /// value that match the ICmpInst::Predicate with any of the values in CR. |  | ||||||
|     ConstantRange makeConstantRange(ICmpInst::Predicate ICmpOpcode, |  | ||||||
|                                     const ConstantRange &CR) { |  | ||||||
|       uint32_t W = CR.getBitWidth(); |  | ||||||
|       switch (ICmpOpcode) { |  | ||||||
|         default: assert(!"Invalid ICmp opcode to makeConstantRange()"); |  | ||||||
|         case ICmpInst::ICMP_EQ: |  | ||||||
|           return ConstantRange(CR.getLower(), CR.getUpper()); |  | ||||||
|         case ICmpInst::ICMP_NE: |  | ||||||
|           if (CR.isSingleElement()) |  | ||||||
|             return ConstantRange(CR.getUpper(), CR.getLower()); |  | ||||||
|           return ConstantRange(W); |  | ||||||
|         case ICmpInst::ICMP_ULT: |  | ||||||
|           return ConstantRange(APInt::getMinValue(W), CR.getUnsignedMax()); |  | ||||||
|         case ICmpInst::ICMP_SLT: |  | ||||||
|           return ConstantRange(APInt::getSignedMinValue(W), CR.getSignedMax()); |  | ||||||
|         case ICmpInst::ICMP_ULE: { |  | ||||||
|           APInt UMax(CR.getUnsignedMax()); |  | ||||||
|           if (UMax.isMaxValue()) |  | ||||||
|             return ConstantRange(W); |  | ||||||
|           return ConstantRange(APInt::getMinValue(W), UMax + 1); |  | ||||||
|         } |  | ||||||
|         case ICmpInst::ICMP_SLE: { |  | ||||||
|           APInt SMax(CR.getSignedMax()); |  | ||||||
|           if (SMax.isMaxSignedValue() || (SMax+1).isMaxSignedValue()) |  | ||||||
|             return ConstantRange(W); |  | ||||||
|           return ConstantRange(APInt::getSignedMinValue(W), SMax + 1); |  | ||||||
|         } |  | ||||||
|         case ICmpInst::ICMP_UGT: |  | ||||||
|           return ConstantRange(CR.getUnsignedMin() + 1, APInt::getNullValue(W)); |  | ||||||
|         case ICmpInst::ICMP_SGT: |  | ||||||
|           return ConstantRange(CR.getSignedMin() + 1, |  | ||||||
|                                APInt::getSignedMinValue(W)); |  | ||||||
|         case ICmpInst::ICMP_UGE: { |  | ||||||
|           APInt UMin(CR.getUnsignedMin()); |  | ||||||
|           if (UMin.isMinValue()) |  | ||||||
|             return ConstantRange(W); |  | ||||||
|           return ConstantRange(UMin, APInt::getNullValue(W)); |  | ||||||
|         } |  | ||||||
|         case ICmpInst::ICMP_SGE: { |  | ||||||
|           APInt SMin(CR.getSignedMin()); |  | ||||||
|           if (SMin.isMinSignedValue()) |  | ||||||
|             return ConstantRange(W); |  | ||||||
|           return ConstantRange(SMin, APInt::getSignedMinValue(W)); |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| #ifndef NDEBUG | #ifndef NDEBUG | ||||||
|     bool isCanonical(Value *V, DomTreeDFS::Node *Subtree) { |     bool isCanonical(Value *V, DomTreeDFS::Node *Subtree) { | ||||||
|       return V == VN.canonicalize(V, Subtree); |       return V == VN.canonicalize(V, Subtree); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user