PR1255: case ranges.
authorStepan Dyatkovskiy <stpworld@narod.ru>
Sat, 2 Jun 2012 09:42:43 +0000 (09:42 +0000)
committerStepan Dyatkovskiy <stpworld@narod.ru>
Sat, 2 Jun 2012 09:42:43 +0000 (09:42 +0000)
IntRange converted from struct to class. So main change everywhere is replacement of ".Low/High" with ".getLow/getHigh()"

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157884 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Instructions.h
include/llvm/Support/IntegersSubset.h
include/llvm/Support/IntegersSubsetMapping.h
lib/Bitcode/Writer/BitcodeWriter.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
lib/ExecutionEngine/Interpreter/Execution.cpp
lib/Transforms/Utils/Local.cpp
lib/Transforms/Utils/LowerSwitch.cpp
lib/VMCore/Verifier.cpp

index 99186f5f50a5606f5412d69b11f20d8713e2b108..7d82fdaa7a115e08466fddb6780292db46c90816 100644 (file)
@@ -2660,7 +2660,7 @@ public:
       
       // FIXME: Currently we work with ConstantInt based cases.
       // So return CaseValue as ConstantInt.
-      return R.Low.toConstantInt();
+      return R.getLow().toConstantInt();
     }
 
     /// Resolves case value for current case.
index b6ffe1b5014585ae1597d9eb199533d468735cea..7f903cc8a004a0e5afd55bf5cce51a5bf034395c 100644 (file)
@@ -172,34 +172,33 @@ public:
 };
 
 template<class IntType>
-struct IntRange {
-
-  typedef IntRange<IntType> self;
+class IntRange {
+protected:
     IntType Low;
     IntType High;
     bool IsEmpty : 1;
     bool IsSingleNumber : 1;
-// TODO: 
-// public:
-    
+
+public:
+    typedef IntRange<IntType> self;    
     typedef std::pair<self, self> SubRes;
     
     IntRange() : IsEmpty(true) {}
-    IntRange(const self &RHS) :
-      Low(RHS.Low), High(RHS.High), IsEmpty(false), IsSingleNumber(false) {}
+    
     IntRange(const IntType &C) :
       Low(C), High(C), IsEmpty(false), IsSingleNumber(true) {}
+    
     IntRange(const IntType &L, const IntType &H) : Low(L), High(H),
-        IsEmpty(false), IsSingleNumber(false) {}
+      IsEmpty(false), IsSingleNumber(Low == High) {}
     
     bool isEmpty() const { return IsEmpty; }
     bool isSingleNumber() const { return IsSingleNumber; }
     
-    const IntType& getLow() {
+    const IntType& getLow() const {
       assert(!IsEmpty && "Range is empty.");
       return Low;
     }
-    const IntType& getHigh() {
+    const IntType& getHigh() const {
       assert(!IsEmpty && "Range is empty.");
       return High;
     }
@@ -296,10 +295,10 @@ public:
     for (typename RangesCollectionTy::const_iterator i = Links.begin(),
          e = Links.end(); i != e; ++i) {
       RangeLinkTy RangeLink;
-      FlatCollection.push_back(i->Low);
+      FlatCollection.push_back(i->getLow());
       RangeLink.first = &FlatCollection.back();
-      if (i->Low != i->High)
-        FlatCollection.push_back(i->High);
+      if (i->getLow() != i->getHigh())
+        FlatCollection.push_back(i->getHigh());
       RangeLink.second = &FlatCollection.back();
       RangeLinks.push_back(RangeLink);
     }
@@ -336,10 +335,17 @@ public:
     return RangeLinks.size();
   }
   
-  bool isSingleNumber(unsigned idx) const {
+  /// Returns true if whole subset contains single element.
+  bool isSingleNumber() const {
     return RangeLinks.size() == 1 &&
            RangeLinks[0].first == RangeLinks[0].second;
   }
+
+  /// Does the same like getItem(idx).isSingleNumber(), but
+  /// works faster, since we avoid creation of temporary range object. 
+  bool isSingleNumber(unsigned idx) const {
+    return RangeLinks[idx].first == RangeLinks[idx].second;
+  }
   
   /// Returns set the size, that equals number of all values + sizes of all
   /// ranges.
@@ -347,10 +353,10 @@ public:
   /// E.g.: for range [<0>, <1>, <4,8>] the size will 7;
   ///       for range [<0>, <1>, <5>] the size will 3
   unsigned getSize() const {
-    APInt sz(((const APInt&)getItem(0).Low).getBitWidth(), 0);
+    APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
     for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
-      const APInt &Low = getItem(i).Low;
-      const APInt &High = getItem(i).High;
+      const APInt &Low = getItem(i).getLow();
+      const APInt &High = getItem(i).getHigh();
       const APInt &S = High - Low;
       sz += S;
     }
@@ -362,10 +368,10 @@ public:
   /// [<1>, <4,8>] is considered as [1,4,5,6,7,8] 
   /// For range [<1>, <4,8>] getSingleValue(3) returns 6.
   APInt getSingleValue(unsigned idx) const {
-    APInt sz(((const APInt&)getItem(0).Low).getBitWidth(), 0);
+    APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
     for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
-      const APInt &Low = getItem(i).Low;
-      const APInt &High = getItem(i).High;      
+      const APInt &Low = getItem(i).getLow();
+      const APInt &High = getItem(i).getHigh();      
       const APInt& S = High - Low;
       APInt oldSz = sz;
       sz += S;
@@ -439,15 +445,15 @@ public:
          e = Src.end(); i != e; ++i) {
       const Range &R = *i;
       std::vector<Constant*> r;
-      if (R.Low != R.High) {
+      if (R.isSingleNumber()) {
         r.reserve(2);
         // FIXME: Since currently we have ConstantInt based numbers
         // use hack-conversion of IntItem to ConstantInt
-        r.push_back(R.Low.toConstantInt());
-        r.push_back(R.High.toConstantInt());
+        r.push_back(R.getLow().toConstantInt());
+        r.push_back(R.getHigh().toConstantInt());
       } else {
         r.reserve(1);
-        r.push_back(R.Low.toConstantInt());
+        r.push_back(R.getLow().toConstantInt());
       }
       Constant *CV = ConstantVector::get(r);
       Elts.push_back(CV);    
index 7ff317b63257870e55191aae7690f0a353e27f43..b630119aea894a5e857d9d0bca21c4615d57d381 100644 (file)
@@ -36,7 +36,7 @@ public:
   
   struct RangeEx : public RangeTy {
     RangeEx() : Weight(1) {}
-    RangeEx(const RangeTy &R) : RangeTy(R.Low, R.High), Weight(1) {}
+    RangeEx(const RangeTy &R) : RangeTy(R), Weight(1) {}
     RangeEx(const IntTy &C) : RangeTy(C), Weight(1) {}
     RangeEx(const IntTy &L, const IntTy &H) : RangeTy(L, H), Weight(1) {}
     RangeEx(const IntTy &L, const IntTy &H, unsigned W) :
@@ -68,7 +68,7 @@ protected:
   bool Sorted;
   
   bool isIntersected(CaseItemIt& LItem, CaseItemIt& RItem) {
-    return LItem->first.High >= RItem->first.Low;
+    return LItem->first.getHigh() >= RItem->first.getLow();
   }
 
   bool isJoinable(CaseItemIt& LItem, CaseItemIt& RItem) {
@@ -77,10 +77,10 @@ protected:
              "Intersected items with different successors!");
       return false;
     }
-    APInt RLow = RItem->first.Low;
+    APInt RLow = RItem->first.getLow();
     if (RLow != APInt::getNullValue(RLow.getBitWidth()))
       --RLow;
-    return LItem->first.High >= RLow;
+    return LItem->first.getHigh() >= RLow;
   }
   
   void sort() {
@@ -126,22 +126,22 @@ public:
     sort();
     CaseItems OldItems = Items;
     Items.clear();
-    IntTy *Low = &OldItems.begin()->first.Low;
-    IntTy *High = &OldItems.begin()->first.High;
+    const IntTy *Low = &OldItems.begin()->first.getLow();
+    const IntTy *High = &OldItems.begin()->first.getHigh();
     unsigned Weight = 1;
     SuccessorClass *Successor = OldItems.begin()->second;
     for (CaseItemIt i = OldItems.begin(), j = i+1, e = OldItems.end();
         j != e; i = j++) {
       if (isJoinable(i, j)) {
-        IntTy *CurHigh = &j->first.High;
+        const IntTy *CurHigh = &j->first.getHigh();
         ++Weight;
         if (*CurHigh > *High)
           High = CurHigh;
       } else {
         RangeEx R(*Low, *High, Weight);
         add(R, Successor);
-        Low = &j->first.Low;
-        High = &j->first.High
+        Low = &j->first.getLow();
+        High = &j->first.getHigh()
         Weight = 1;
         Successor = j->second;
       }
index 7dd18c87ffebcdc0ec7ce0c01c677de957af8caf..6526b012d811a9c0029d151854a2872498a94326 100644 (file)
@@ -1161,16 +1161,15 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
         Vals64.push_back(CaseRanges.getNumItems());
         for (unsigned ri = 0, rn = CaseRanges.getNumItems(); ri != rn; ++ri) {
           IntegersSubset::Range r = CaseRanges.getItem(ri);
+          bool IsSingleNumber = r.isSingleNumber();
 
-          Vals64.push_back(CaseRanges.isSingleNumber(ri));
+          Vals64.push_back(IsSingleNumber);
 
-          const APInt &Low = r.Low;
-          const APInt &High = r.High;
           unsigned Code, Abbrev; // will unused.
           
-          EmitAPInt(Vals64, Code, Abbrev, Low, true);
-          if (r.Low != r.High)
-            EmitAPInt(Vals64, Code, Abbrev, High, true);
+          EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true);
+          if (!IsSingleNumber)
+            EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true);
         }
         Vals64.push_back(VE.getValueID(i.getCaseSuccessor()));
       }
index 15c4258ddb8e878b7a564a98f94525244bdf4c53..305d03a2419e3454690e11ea4a09ccb376e742c7 100644 (file)
@@ -2458,10 +2458,10 @@ size_t SelectionDAGBuilder::Clusterify(CaseVector& Cases,
 
     // FIXME: Currently work with ConstantInt based numbers.
     // Changing it to APInt based is a pretty heavy for this commit.
-    Cases.push_back(Case(C.first.Low.toConstantInt(),
-                         C.first.High.toConstantInt(), C.second, W));
+    Cases.push_back(Case(C.first.getLow().toConstantInt(),
+                         C.first.getHigh().toConstantInt(), C.second, W));
     
-    if (C.first.Low != C.first.High)
+    if (C.first.getLow() != C.first.getHigh())
     // A range counts double, since it requires two compares.
     ++numCmps;
   }
index d4b6ed00033ace63509818e3b9c0fff9d6779d0b..89c35438ef74dc39e0f1164c431743072cabd2ac 100644 (file)
@@ -655,8 +655,8 @@ void Interpreter::visitSwitchInst(SwitchInst &I) {
     for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) {
       IntegersSubset::Range r = Case.getItem(n);
       // FIXME: Currently work with ConstantInt based numbers.
-      const ConstantInt *LowCI = r.Low.toConstantInt();
-      const ConstantInt *HighCI = r.High.toConstantInt();
+      const ConstantInt *LowCI = r.getLow().toConstantInt();
+      const ConstantInt *HighCI = r.getHigh().toConstantInt();
       GenericValue Low = getOperandValue(const_cast<ConstantInt*>(LowCI), SF);
       GenericValue High = getOperandValue(const_cast<ConstantInt*>(HighCI), SF);
       if (executeICMP_ULE(Low, CondVal, ElTy).IntVal != 0 &&
index a4ddfa5de3ccf488f04aecc33ff8674bf61cdc83..3c6793f3ad05783e0ecd515acacfacd0b1e6200f 100644 (file)
@@ -173,7 +173,7 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions) {
       if (CaseRanges.getNumItems() == 1 && CaseRanges.isSingleNumber(0)) {
         // FIXME: Currently work with ConstantInt based numbers.
         Value *Cond = Builder.CreateICmpEQ(SI->getCondition(),
-            CaseRanges.getItem(0).Low.toConstantInt(),
+            CaseRanges.getItem(0).getLow().toConstantInt(),
             "cond");
 
         // Insert the new branch.
index a4cf7732928628980b5c7ceedd961825e38cc778..1547439b5c6b075dd1fecbf21a1934ddb292a3cc 100644 (file)
@@ -242,9 +242,9 @@ unsigned LowerSwitch::Clusterify(CaseVector& Cases, SwitchInst *SI) {
     
     // FIXME: Currently work with ConstantInt based numbers.
     // Changing it to APInt based is a pretty heavy for this commit.
-    Cases.push_back(CaseRange(C.first.Low.toConstantInt(),
-                              C.first.High.toConstantInt(), C.second));
-    if (C.first.Low != C.first.High)
+    Cases.push_back(CaseRange(C.first.getLow().toConstantInt(),
+                              C.first.getHigh().toConstantInt(), C.second));
+    if (C.first.isSingleNumber())
       // A range counts double, since it requires two compares.
       ++numCmps;
   }
index 4d33c623af5031afdcb3fa2c9b22ef165355f5c8..d9a535c9d8629be36499492b7b460fb73f9a2ab1 100644 (file)
@@ -813,9 +813,9 @@ void Verifier::visitSwitchInst(SwitchInst &SI) {
     IntegersSubset CaseRanges = i.getCaseValueEx();
     for (unsigned ri = 0, rie = CaseRanges.getNumItems(); ri < rie; ++ri) {
       IntegersSubset::Range r = CaseRanges.getItem(ri);
-      Assert1(((const APInt&)r.Low).getBitWidth() == IntTy->getBitWidth(),
+      Assert1(((const APInt&)r.getLow()).getBitWidth() == IntTy->getBitWidth(),
               "Switch constants must all be same type as switch value!", &SI);
-      Assert1(((const APInt&)r.High).getBitWidth() == IntTy->getBitWidth(),
+      Assert1(((const APInt&)r.getHigh()).getBitWidth() == IntTy->getBitWidth(),
               "Switch constants must all be same type as switch value!", &SI);
       Mapping.add(r);
       RangeSetMap[r] = i.getCaseIndex();