[llvm-commits] [llvm] r157815 - in /llvm/trunk: include/llvm/Support/IntegersSubset.h include/llvm/Support/IntegersSubsetMapping.h lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Stepan Dyatkovskiy stpworld at narod.ru
Fri Jun 1 09:17:58 PDT 2012


Author: dyatkovskiy
Date: Fri Jun  1 11:17:57 2012
New Revision: 157815

URL: http://llvm.org/viewvc/llvm-project?rev=157815&view=rev
Log:
PR1255: case ranges.
IntegersSubset devided into IntegersSubsetGeneric and into IntegersSubset itself. The first has no references to ConstantInt and works with IntItem only.
IntegersSubsetMapping also made generic. Here added second template parameter "IntegersSubsetTy" that allows to use on of two IntegersSubset types described below.


Modified:
    llvm/trunk/include/llvm/Support/IntegersSubset.h
    llvm/trunk/include/llvm/Support/IntegersSubsetMapping.h
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Modified: llvm/trunk/include/llvm/Support/IntegersSubset.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/IntegersSubset.h?rev=157815&r1=157814&r2=157815&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/IntegersSubset.h (original)
+++ llvm/trunk/include/llvm/Support/IntegersSubset.h Fri Jun  1 11:17:57 2012
@@ -19,6 +19,8 @@
 #ifndef CONSTANTRANGESSET_H_
 #define CONSTANTRANGESSET_H_
 
+#include <list>
+
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/LLVMContext.h"
@@ -109,8 +111,12 @@
   INT_ITEM_DEFINE_COMPARISON(>, ugt)
   INT_ITEM_DEFINE_COMPARISON(<=, ule)
   INT_ITEM_DEFINE_COMPARISON(>=, uge)
+  
   INT_ITEM_DEFINE_COMPARISON(==, eq)
+  INT_ITEM_DEFINE_OP_STANDARD_INT(bool,==,uint64_t)
+  
   INT_ITEM_DEFINE_COMPARISON(!=, ne)
+  INT_ITEM_DEFINE_OP_STANDARD_INT(bool,!=,uint64_t)
   
   INT_ITEM_DEFINE_BINARY_OP(*)
   INT_ITEM_DEFINE_BINARY_OP(+)
@@ -160,7 +166,7 @@
         LikeThis.ConstantIntVal->getContext(), V));
     return fromConstantInt(C);
   }
-  ConstantInt *toConstantInt() {
+  ConstantInt *toConstantInt() const {
     return ConstantIntVal;
   }
 };
@@ -261,30 +267,41 @@
   };      
 
 //===----------------------------------------------------------------------===//
-/// ConstantRangesSet - class that implements constant set of ranges.
-/// It is a wrapper for some real "holder" class (currently ConstantArray).
-/// It contains functions, that allows to parse "holder" like a set of ranges.
-/// Note: It is assumed that "holder" is inherited from Constant object.
-///       ConstantRangesSet may be converted to and from Constant* pointer.
-///
-class IntegersSubset {
-  Constant *Array;
+/// IntegersSubsetGeneric - class that implements the subset of integers. It
+/// consists from ranges and single numbers.
+class IntegersSubsetGeneric {
 public:
+  // Use Chris Lattner idea, that was initially described here:
+  // http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120213/136954.html
+  // In short, for more compact memory consumption we can store flat
+  // numbers collection, and define range as pair of indices.
+  // In that case we can safe some memory on 32 bit machines.
+  typedef std::list<IntItem> FlatCollectionTy;
+  typedef std::pair<IntItem*, IntItem*> RangeLinkTy;
+  typedef SmallVector<RangeLinkTy, 64> RangeLinksTy;
+  typedef RangeLinksTy::iterator RangeLinksConstIt;
   
-  bool IsWide;
+protected:
   
-  // implicit
-  IntegersSubset(Constant *V) : Array(V) {
-    ArrayType *ArrTy = cast<ArrayType>(Array->getType());
-    VectorType *VecTy = cast<VectorType>(ArrTy->getElementType());
-    IntegerType *IntTy = cast<IntegerType>(VecTy->getElementType());
-    IsWide = IntTy->getBitWidth() > 64;    
-  }
+  FlatCollectionTy FlatCollection;
+  RangeLinksTy RangeLinks;
   
-  operator Constant*() { return Array; }
-  operator const Constant*() const { return Array; }
-  Constant *operator->() { return Array; }
-  const Constant *operator->() const { return Array; }
+public:
+  
+  template<class RangesCollectionTy>
+  IntegersSubsetGeneric(const RangesCollectionTy& Links) {
+    assert(Links.size() && "Empty ranges are not allowed.");
+    for (typename RangesCollectionTy::const_iterator i = Links.begin(),
+         e = Links.end(); i != e; ++i) {
+      RangeLinkTy RangeLink;
+      FlatCollection.push_back(i->Low);
+      RangeLink.first = &FlatCollection.back();
+      if (i->Low != i->High)
+        FlatCollection.push_back(i->High);
+      RangeLink.second = &FlatCollection.back();
+      RangeLinks.push_back(RangeLink);
+    }
+  }
   
   typedef IntRange Range;
  
@@ -293,81 +310,33 @@
   /// contained ranges.
   bool isSatisfies(const IntItem &CheckingVal) const {
     for (unsigned i = 0, e = getNumItems(); i < e; ++i) {
-      const Constant *CV = Array->getAggregateElement(i);
-      unsigned VecSize = cast<VectorType>(CV->getType())->getNumElements();
-      switch (VecSize) {
-      case 1:
-        if (cast<const ConstantInt>(CV->getAggregateElement(0U))->getValue() ==
-            CheckingVal)
+      if (RangeLinks[i].first == RangeLinks[i].second) {
+        if (*RangeLinks[i].first == CheckingVal)
           return true;
-        break;
-      case 2: {
-        const APInt &Lo =
-            cast<const ConstantInt>(CV->getAggregateElement(0U))->getValue();
-        const APInt &Hi =
-            cast<const ConstantInt>(CV->getAggregateElement(1))->getValue();
-        if (Lo.uge(CheckingVal) && Hi.ule(CheckingVal))
-          return true;
-      }
-        break;
-      default:
-        assert(0 && "Only pairs and single numbers are allowed here.");
-        break;
-      }
+      } else if (*RangeLinks[i].first >= CheckingVal &&
+                 *RangeLinks[i].second <= CheckingVal) 
+        return true;
     }
     return false;    
   }
   
   /// Returns set's item with given index.
-  Range getItem(unsigned idx) {
-    Constant *CV = Array->getAggregateElement(idx);
-    unsigned NumEls = cast<VectorType>(CV->getType())->getNumElements();
-    switch (NumEls) {
-    case 1:
-      return Range(IntItem::fromConstantInt(
-                    cast<ConstantInt>(CV->getAggregateElement(0U))));
-    case 2:
-      return Range(IntItem::fromConstantInt(
-                     cast<ConstantInt>(CV->getAggregateElement(0U))),
-                   IntItem::fromConstantInt(
-                     cast<ConstantInt>(CV->getAggregateElement(1U))));
-    default:
-      assert(0 && "Only pairs and single numbers are allowed here.");
-      return Range();
-    }    
-  }
-  
-  const Range getItem(unsigned idx) const {
-    const Constant *CV = Array->getAggregateElement(idx);
-    
-    unsigned NumEls = cast<VectorType>(CV->getType())->getNumElements();
-    switch (NumEls) {
-    case 1:
-      return Range(IntItem::fromConstantInt(
-                     cast<ConstantInt>(CV->getAggregateElement(0U))),
-                   IntItem::fromConstantInt(cast<ConstantInt>(
-                     cast<ConstantInt>(CV->getAggregateElement(0U)))));
-    case 2:
-      return Range(IntItem::fromConstantInt(
-                     cast<ConstantInt>(CV->getAggregateElement(0U))),
-                   IntItem::fromConstantInt(
-                   cast<ConstantInt>(CV->getAggregateElement(1))));
-    default:
-      assert(0 && "Only pairs and single numbers are allowed here.");
-      return Range();
-    }    
-  }
+  Range getItem(unsigned idx) const {
+    const RangeLinkTy &Link = RangeLinks[idx];
+    if (Link.first != Link.second)
+      return Range(*Link.first, *Link.second);
+    else
+      return Range(*Link.first);
+  }  
   
   /// Return number of items (ranges) stored in set.
   unsigned getNumItems() const {
-    return cast<ArrayType>(Array->getType())->getNumElements();
+    return RangeLinks.size();
   }
   
-  bool isWideNumberFormat() const { return IsWide; }
-  
   bool isSingleNumber(unsigned idx) const {
-    Constant *CV = Array->getAggregateElement(idx);
-    return cast<VectorType>(CV->getType())->getNumElements() == 1;
+    return RangeLinks.size() == 1 &&
+           RangeLinks[0].first == RangeLinks[0].second;
   }
   
   /// Returns set the size, that equals number of all values + sizes of all
@@ -411,6 +380,86 @@
   }
 };  
 
+//===----------------------------------------------------------------------===//
+/// IntegersSubset - currenly is extension of IntegersSubsetGeneric
+/// that also supports conversion to/from Constant* object.
+class IntegersSubset : public IntegersSubsetGeneric {
+  Constant *Holder;
+  
+  static unsigned getNumItemsFromConstant(Constant *C) {
+    return cast<ArrayType>(C->getType())->getNumElements();
+  }
+  
+  static Range getItemFromConstant(Constant *C, unsigned idx) {
+    const Constant *CV = C->getAggregateElement(idx);
+    
+    unsigned NumEls = cast<VectorType>(CV->getType())->getNumElements();
+    switch (NumEls) {
+    case 1:
+      return Range(IntItem::fromConstantInt(
+                     cast<ConstantInt>(CV->getAggregateElement(0U))),
+                   IntItem::fromConstantInt(cast<ConstantInt>(
+                     cast<ConstantInt>(CV->getAggregateElement(0U)))));
+    case 2:
+      return Range(IntItem::fromConstantInt(
+                     cast<ConstantInt>(CV->getAggregateElement(0U))),
+                   IntItem::fromConstantInt(
+                   cast<ConstantInt>(CV->getAggregateElement(1))));
+    default:
+      assert(0 && "Only pairs and single numbers are allowed here.");
+      return Range();
+    }    
+  }  
+  
+  std::vector<Range> rangesFromConstant(Constant *C) {
+    unsigned NumItems = getNumItemsFromConstant(C);
+    std::vector<Range> r;
+    r.reserve(NumItems);
+    for (unsigned i = 0, e = NumItems; i != e; ++i)
+      r.push_back(getItemFromConstant(C, i));
+    return r;
+  }
+  
+public:
+  
+  IntegersSubset(Constant *C) : IntegersSubsetGeneric(rangesFromConstant(C)),
+                                Holder(C) {}
+  
+  // implicit
+  template<class RangesCollectionTy>
+  IntegersSubset(const RangesCollectionTy& Src) :
+    IntegersSubsetGeneric(Src) {
+    
+    std::vector<Constant*> Elts;
+    Elts.reserve(Src.size());
+    for (typename RangesCollectionTy::const_iterator i = Src.begin(),
+         e = Src.end(); i != e; ++i) {
+      const Range &R = *i;
+      std::vector<Constant*> r;
+      if (R.Low != R.High) {
+        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());
+      } else {
+        r.reserve(1);
+        r.push_back(R.Low.toConstantInt());
+      }
+      Constant *CV = ConstantVector::get(r);
+      Elts.push_back(CV);    
+    }
+    ArrayType *ArrTy =
+        ArrayType::get(Elts.front()->getType(), (uint64_t)Elts.size());
+    Holder = ConstantArray::get(ArrTy, Elts);    
+  }
+  
+  operator Constant*() { return Holder; }
+  operator const Constant*() const { return Holder; }
+  Constant *operator->() { return Holder; }
+  const Constant *operator->() const { return Holder; }
+};  
+
 }
 
 #endif /* CONSTANTRANGESSET_H_ */

Modified: llvm/trunk/include/llvm/Support/IntegersSubsetMapping.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/IntegersSubsetMapping.h?rev=157815&r1=157814&r2=157815&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/IntegersSubsetMapping.h (original)
+++ llvm/trunk/include/llvm/Support/IntegersSubsetMapping.h Fri Jun  1 11:17:57 2012
@@ -26,14 +26,14 @@
 
 namespace llvm {
 
-template <class SuccessorClass>
+template <class SuccessorClass, class IntegersSubsetTy>
 class IntegersSubsetMapping {
 public:
   
-  typedef IntegersSubset::Range RangeTy;
+  typedef IntRange RangeTy;
   
   struct RangeEx : public RangeTy {
-    typedef IntegersSubset::Range RangeTy;
+    typedef IntRange RangeTy;
     RangeEx() : Weight(1) {}
     RangeEx(const RangeTy &R) : RangeTy(R.Low, R.High), Weight(1) {}
     RangeEx(const IntItem &C) : RangeTy(C), Weight(1) {}
@@ -88,31 +88,6 @@
       Sorted = true;
     }
   }
-
-  IntegersSubset getCase(RangesCollection& Src) {
-    std::vector<Constant*> Elts;
-    Elts.reserve(Src.size());
-    for (RangesCollectionIt i = Src.begin(), e = Src.end(); i != e; ++i) {
-      RangeTy &R = *i;
-      std::vector<Constant*> r;
-      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());
-      } else {
-        r.reserve(1);
-        r.push_back(R.Low.toConstantInt());
-      }
-      Constant *CV = ConstantVector::get(r);
-      Elts.push_back(CV);    
-    }
-    ArrayType *ArrTy =
-        ArrayType::get(Elts.front()->getType(), (uint64_t)Elts.size());
-    Constant *Array = ConstantArray::get(ArrTy, Elts);
-    return IntegersSubset(Array);     
-  }  
   
 public:
   
@@ -122,7 +97,7 @@
   // factory.
   typedef CaseItemIt RangeIterator;
   
-  typedef std::pair<SuccessorClass*, IntegersSubset> Case;
+  typedef std::pair<SuccessorClass*, IntegersSubsetTy> Case;
   typedef std::list<Case> Cases;
   
   IntegersSubsetMapping() {
@@ -214,7 +189,7 @@
     for (RangeIterator i = this->begin(); i != this->end(); ++i)
       TheCRSMap[i->second].push_back(i->first);
     for (CRSMapIt i = TheCRSMap.begin(), e = TheCRSMap.end(); i != e; ++i)
-      TheCases.push_back(std::make_pair(i->first, getCase(i->second)));
+      TheCases.push_back(std::make_pair(i->first, IntegersSubsetTy(i->second)));
   }
   
   /// Builds the finalized case objects ignoring successor values, as though
@@ -223,7 +198,7 @@
     RangesCollection Ranges;
     for (RangeIterator i = this->begin(); i != this->end(); ++i)
       Ranges.push_back(i->first);
-    return getCase(Ranges);
+    return IntegersSubsetTy(Ranges);
   }  
   
   /// Returns true if there is no ranges and values inside.
@@ -234,7 +209,7 @@
 };
 
 class BasicBlock;
-typedef IntegersSubsetMapping<BasicBlock> IntegersSubsetToBB;
+typedef IntegersSubsetMapping<BasicBlock, IntegersSubset> IntegersSubsetToBB;
 
 }
 

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=157815&r1=157814&r2=157815&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Fri Jun  1 11:17:57 2012
@@ -2427,7 +2427,7 @@
   
   /// Use a shorter form of declaration, and also
   /// show the we want to use CRSBuilder as Clusterifier.
-  typedef IntegersSubsetMapping<MachineBasicBlock> Clusterifier;
+  typedef IntegersSubsetMapping<MachineBasicBlock, IntegersSubset> Clusterifier;
   
   Clusterifier TheClusterifier;
 





More information about the llvm-commits mailing list