Add an option to enable the SSA based peephole optimizer.
[oota-llvm.git] / lib / VMCore / ConstantRange.cpp
index 1414b9becac2bf4016021f848109fe990bd7c150..e180f12a1a045f2b7fa14fa731c90bc8d266e081 100644 (file)
@@ -1,4 +1,11 @@
 //===-- ConstantRange.cpp - ConstantRange implementation ------------------===//
+// 
+//                     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.
+// 
+//===----------------------------------------------------------------------===//
 //
 // Represent a range of possible values that may occur when the program is run
 // for an integral value.  This keeps track of a lower and upper bound for the
@@ -19,6 +26,8 @@
 #include "llvm/Instruction.h"
 #include "llvm/ConstantHandling.h"
 
+namespace llvm {
+
 /// Initialize a full (the default) or empty set for the specified type.
 ///
 ConstantRange::ConstantRange(const Type *Ty, bool Full) {
@@ -67,16 +76,16 @@ ConstantRange::ConstantRange(unsigned SetCCOpcode, ConstantIntegral *C) {
     Upper = C;
     return;
   case Instruction::SetGT:
-    Upper = ConstantIntegral::getMaxValue(C->getType());
     Lower = Next(C);
+    Upper = ConstantIntegral::getMinValue(C->getType());  // Min = Next(Max)
     return;
   case Instruction::SetLE:
     Lower = ConstantIntegral::getMinValue(C->getType());
     Upper = Next(C);
     return;
   case Instruction::SetGE:
-    Upper = ConstantIntegral::getMaxValue(C->getType());
     Lower = C;
+    Upper = ConstantIntegral::getMinValue(C->getType());  // Min = Next(Max)
     return;
   }
 }
@@ -126,10 +135,7 @@ uint64_t ConstantRange::getSetSize() const {
   // Simply subtract the bounds...
   Constant *Result = *(Constant*)Upper - *(Constant*)Lower;
   assert(Result && "Subtraction of constant integers not implemented?");
-  if (getType()->isSigned())
-    return (uint64_t)cast<ConstantSInt>(Result)->getValue();
-  else
-    return cast<ConstantUInt>(Result)->getValue();
+  return cast<ConstantInt>(Result)->getRawValue();
 }
 
 
@@ -142,10 +148,6 @@ static ConstantRange intersect1Wrapped(const ConstantRange &LHS,
                                        const ConstantRange &RHS) {
   assert(LHS.isWrappedSet() && !RHS.isWrappedSet());
 
-  // Handle common special cases
-  if (RHS.isEmptySet()) return RHS;
-  if (RHS.isFullSet()) return LHS;
-
   // Check to see if we overlap on the Left side of RHS...
   //
   if ((*(Constant*)RHS.getLower() < *(Constant*)LHS.getUpper())->getValue()) {
@@ -178,21 +180,34 @@ 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.
 ///
 ConstantRange ConstantRange::intersectWith(const ConstantRange &CR) const {
   assert(getType() == CR.getType() && "ConstantRange types don't agree!");
+  // Handle common special cases
+  if (isEmptySet() || CR.isFullSet())  return *this;
+  if (isFullSet()  || CR.isEmptySet()) return CR;
 
   if (!isWrappedSet()) {
     if (!CR.isWrappedSet()) {
-      const Constant &L = std::max(*(Constant*)Lower, *(Constant*)CR.Lower);
-      const Constant &U = std::min(*(Constant*)Upper, *(Constant*)CR.Upper);
+      ConstantIntegral *L = Max(Lower, CR.Lower);
+      ConstantIntegral *U = Min(Upper, CR.Upper);
 
-      if ((L < U)->getValue())  // If range isn't empty...
-        return ConstantRange(cast<ConstantIntegral>((Constant*)&L),
-                             cast<ConstantIntegral>((Constant*)&U));
+      if ((*L < *U)->getValue())  // If range isn't empty...
+        return ConstantRange(L, U);
       else
         return ConstantRange(getType(), false);  // Otherwise, return empty set
     } else
@@ -202,11 +217,9 @@ ConstantRange ConstantRange::intersectWith(const ConstantRange &CR) const {
       return intersect1Wrapped(*this, CR);
     else {
       // Both ranges are wrapped...
-      const Constant &L = std::max(*(Constant*)Lower, *(Constant*)CR.Lower);
-      const Constant &U = std::min(*(Constant*)Upper, *(Constant*)CR.Upper);
-
-      return ConstantRange(cast<ConstantIntegral>((Constant*)&L),
-                           cast<ConstantIntegral>((Constant*)&U));      
+      ConstantIntegral *L = Max(Lower, CR.Lower);
+      ConstantIntegral *U = Min(Upper, CR.Upper);
+      return ConstantRange(L, U);
     }
   }
   return *this;
@@ -237,3 +250,5 @@ void ConstantRange::print(std::ostream &OS) const {
 void ConstantRange::dump() const {
   print(std::cerr);
 }
+
+} // End llvm namespace