An implementation of the bit-vector representation of sets.
authorVikram S. Adve <vadve@cs.uiuc.edu>
Wed, 6 Nov 2002 17:14:14 +0000 (17:14 +0000)
committerVikram S. Adve <vadve@cs.uiuc.edu>
Wed, 6 Nov 2002 17:14:14 +0000 (17:14 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4568 91177308-0d34-0410-b5e6-96231b3b80d8

include/Support/BitSetVector.h [new file with mode: 0644]
include/llvm/ADT/BitSetVector.h [new file with mode: 0644]

diff --git a/include/Support/BitSetVector.h b/include/Support/BitSetVector.h
new file mode 100644 (file)
index 0000000..0143413
--- /dev/null
@@ -0,0 +1,239 @@
+//===-- BitVectorSet.h - A bit-vector representation of sets -----*- C++ -*--=//
+//
+// class BitVectorSet --
+// 
+// An implementation of the bit-vector representation of sets.
+// Unlike vector<bool>, this allows much more efficient parallel set
+// operations on bits, by using the bitset template .  The bitset template
+// unfortunately can only represent sets with a size chosen at compile-time.
+// We therefore use a vector of bitsets.  The maxmimum size of our sets
+// (i.e., the size of the universal set) can be chosen at creation time.
+//
+// The size of each Bitset is defined by the macro WORDSIZE.
+// 
+// NOTE: The WORDSIZE macro should be made machine-dependent, in order to use
+// 64-bit words or whatever gives most efficient Bitsets on each platform.
+// 
+// 
+// External functions:
+// 
+// bool Disjoint(const BitSetVector& set1, const BitSetVector& set2):
+//    Tests if two sets have an empty intersection.
+//    This is more efficient than !(set1 & set2).any().
+// 
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_BITVECTORSET_H
+#define LLVM_SUPPORT_BITVECTORSET_H
+
+#include <bitset>
+#include <vector>
+#include <functional>
+#include <iostream>
+
+
+#define WORDSIZE (32U)
+
+
+class BitSetVector {
+  typedef std::bitset<WORDSIZE> bitword;
+  typedef bitword::reference reference;
+  class iterator;
+
+  std::vector<bitword> bitsetVec;
+
+  static unsigned NumWords(unsigned Size) { return (Size+WORDSIZE-1)/WORDSIZE;} 
+
+  const bitword& getWord(unsigned i) const { return bitsetVec[i]; }
+        bitword& getWord(unsigned i)       { return bitsetVec[i]; }
+
+  friend bool Disjoint(const BitSetVector& set1,
+                       const BitSetVector& set2);
+
+  BitSetVector();                       // do not implement!
+
+public:
+  unsigned maxSize;
+
+  /// 
+  /// Constructor: create a set of the maximum size maxSetSize.
+  /// The set is initialized to empty.
+  ///
+  BitSetVector(unsigned maxSetSize)
+    : bitsetVec(BitSetVector::NumWords(maxSetSize)), maxSize(maxSetSize) { }
+
+  /// 
+  ///  Modifier methods: reset, set for entire set, operator[] for one element.
+  ///  
+  void reset() {
+    for(std::vector<bitword>::iterator I=bitsetVec.begin(), E=bitsetVec.end();
+        I != E; ++I)
+      I->reset();
+  }
+  void set() {
+    for(std::vector<bitword>::iterator I=bitsetVec.begin(), E=bitsetVec.end();
+        I != E; ++I)
+      I->set();
+  }
+  std::bitset<32>::reference operator[](unsigned n) {
+    unsigned ndiv = n / WORDSIZE, nmod = n % WORDSIZE;
+    assert(ndiv  < bitsetVec.size() && "BitSetVector: Bit number out of range");
+    return bitsetVec[ndiv][nmod];
+  }
+  iterator begin() { return iterator::begin(*this); }
+  iterator end()   { return iterator::end(*this);   } 
+
+  /// 
+  ///  Set membership operations: single element, any, none, count
+  ///  
+  bool test(unsigned n) const {
+    unsigned ndiv = n / WORDSIZE, nmod = n % WORDSIZE;
+    assert(ndiv  < bitsetVec.size() && "BitSetVector: Bit number out of range");
+    return bitsetVec[ndiv].test(nmod);
+  }
+  bool any() const {
+    for (unsigned i = 0; i < bitsetVec.size(); ++i)
+      if (bitsetVec[i].any())
+        return true;
+    return false;
+  }
+  bool none() const {
+    return ! any();
+  }
+  unsigned count() const {
+    unsigned n = 0;
+    for (unsigned i = 0; i < bitsetVec.size(); ++i)
+      n += bitsetVec[i].count();
+    return n;
+  }
+
+  /// 
+  ///  Set operations: intersection, union, disjoint union, complement.
+  ///  
+  BitSetVector operator& (const BitSetVector& set2) const {
+    assert(maxSize == set2.maxSize && "Illegal intersection");
+    BitSetVector result(maxSize);
+    for (unsigned i = 0; i < bitsetVec.size(); ++i)
+      result.getWord(i) = getWord(i) & set2.getWord(i);
+    return result;
+  }
+  BitSetVector operator| (const BitSetVector& set2) const {
+    assert(maxSize == set2.maxSize && "Illegal intersection");
+    BitSetVector result(maxSize);
+    for (unsigned i = 0; i < bitsetVec.size(); ++i)
+      result.getWord(i) = getWord(i) | set2.getWord(i);
+    return result;
+  }
+  BitSetVector operator^ (const BitSetVector& set2) const {
+    assert(maxSize == set2.maxSize && "Illegal intersection");
+    BitSetVector result(maxSize);
+    for (unsigned i = 0; i < bitsetVec.size(); ++i)
+      result.getWord(i) = getWord(i) ^ set2.getWord(i);
+    return result;
+  }
+  BitSetVector operator~ () const {
+    BitSetVector result(maxSize);
+    for (unsigned i = 0; i < bitsetVec.size(); ++i)
+      (result.getWord(i) = getWord(i)).flip();
+    return result;
+  }
+
+  /// 
+  ///  Printing and debugging support
+  ///  
+  void print(std::ostream &O) const;
+  void dump() const { print(std::cerr); }
+
+public:
+  // 
+  // An iterator to enumerate the bits in a BitSetVector.
+  // Eventually, this needs to inherit from bidirectional_iterator.
+  // But this iterator may not be as useful as I once thought and
+  // may just go away.
+  // 
+  class iterator {
+    unsigned   currentBit;
+    unsigned   currentWord;
+    BitSetVector& bitvec;
+    iterator(unsigned B, unsigned W, BitSetVector _bitvec)
+      : currentBit(B), currentWord(W), bitvec(_bitvec) { }
+  public:
+    iterator(BitSetVector& _bitvec)
+      : currentBit(0), currentWord(0), bitvec(_bitvec) { }
+    iterator(const iterator& I)
+      : currentBit(I.currentBit),currentWord(I.currentWord),bitvec(I.bitvec) { }
+    iterator& operator=(const iterator& I) {
+      currentWord == I.currentWord;
+      currentBit == I.currentBit;
+      bitvec = I.bitvec;
+      return *this;
+    }
+
+    // Increment and decrement operators (pre and post)
+    iterator& operator++() {
+      if (++currentBit == WORDSIZE)
+        { currentBit = 0; if (currentWord < bitvec.maxSize) ++currentWord; }
+      return *this;
+    }
+    iterator& operator--() {
+      if (currentBit == 0) {
+        currentBit = WORDSIZE-1;
+        currentWord = (currentWord == 0)? bitvec.maxSize : --currentWord;
+      }
+      else
+        --currentBit;
+      return *this;
+    }
+    iterator operator++(int) { iterator copy(*this); ++*this; return copy; }
+    iterator operator--(int) { iterator copy(*this); --*this; return copy; }
+
+    // Dereferencing operators
+    reference operator*() {
+      assert(currentWord < bitvec.maxSize &&
+             "Dereferencing iterator past the end of a BitSetVector");
+      return bitvec.getWord(currentWord)[currentBit];
+    }
+
+    // Comparison operator
+    bool operator==(const iterator& I) {
+      return (&I.bitvec == &bitvec &&
+              I.currentWord == currentWord && I.currentBit == currentBit);
+    }
+
+  protected:
+    static iterator begin(BitSetVector& _bitvec) { return iterator(_bitvec); }
+    static iterator end(BitSetVector& _bitvec)   { return iterator(0,
+                                                    _bitvec.maxSize, _bitvec); }
+    friend class BitSetVector;
+  };
+};
+
+
+inline void BitSetVector::print(std::ostream& O) const
+{
+  for (std::vector<bitword>::const_iterator
+         I=bitsetVec.begin(), E=bitsetVec.end(); I != E; ++I)
+    O << "<" << (*I) << ">" << (I+1 == E? "\n" : ", ");
+}
+
+inline std::ostream& operator<< (std::ostream& O, const BitSetVector& bset)
+{
+  bset.print(O);
+  return O;
+};
+
+
+///
+/// Optimized versions of fundamental comparison operations
+/// 
+inline bool Disjoint(const BitSetVector& set1,
+                     const BitSetVector& set2)
+{
+  assert(set1.maxSize == set2.maxSize && "Illegal intersection");
+  for (unsigned i = 0; i < set1.bitsetVec.size(); ++i)
+    if ((set1.getWord(i) & set2.getWord(i)).any())
+      return false;
+  return true;
+}
+
+#endif
diff --git a/include/llvm/ADT/BitSetVector.h b/include/llvm/ADT/BitSetVector.h
new file mode 100644 (file)
index 0000000..0143413
--- /dev/null
@@ -0,0 +1,239 @@
+//===-- BitVectorSet.h - A bit-vector representation of sets -----*- C++ -*--=//
+//
+// class BitVectorSet --
+// 
+// An implementation of the bit-vector representation of sets.
+// Unlike vector<bool>, this allows much more efficient parallel set
+// operations on bits, by using the bitset template .  The bitset template
+// unfortunately can only represent sets with a size chosen at compile-time.
+// We therefore use a vector of bitsets.  The maxmimum size of our sets
+// (i.e., the size of the universal set) can be chosen at creation time.
+//
+// The size of each Bitset is defined by the macro WORDSIZE.
+// 
+// NOTE: The WORDSIZE macro should be made machine-dependent, in order to use
+// 64-bit words or whatever gives most efficient Bitsets on each platform.
+// 
+// 
+// External functions:
+// 
+// bool Disjoint(const BitSetVector& set1, const BitSetVector& set2):
+//    Tests if two sets have an empty intersection.
+//    This is more efficient than !(set1 & set2).any().
+// 
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_BITVECTORSET_H
+#define LLVM_SUPPORT_BITVECTORSET_H
+
+#include <bitset>
+#include <vector>
+#include <functional>
+#include <iostream>
+
+
+#define WORDSIZE (32U)
+
+
+class BitSetVector {
+  typedef std::bitset<WORDSIZE> bitword;
+  typedef bitword::reference reference;
+  class iterator;
+
+  std::vector<bitword> bitsetVec;
+
+  static unsigned NumWords(unsigned Size) { return (Size+WORDSIZE-1)/WORDSIZE;} 
+
+  const bitword& getWord(unsigned i) const { return bitsetVec[i]; }
+        bitword& getWord(unsigned i)       { return bitsetVec[i]; }
+
+  friend bool Disjoint(const BitSetVector& set1,
+                       const BitSetVector& set2);
+
+  BitSetVector();                       // do not implement!
+
+public:
+  unsigned maxSize;
+
+  /// 
+  /// Constructor: create a set of the maximum size maxSetSize.
+  /// The set is initialized to empty.
+  ///
+  BitSetVector(unsigned maxSetSize)
+    : bitsetVec(BitSetVector::NumWords(maxSetSize)), maxSize(maxSetSize) { }
+
+  /// 
+  ///  Modifier methods: reset, set for entire set, operator[] for one element.
+  ///  
+  void reset() {
+    for(std::vector<bitword>::iterator I=bitsetVec.begin(), E=bitsetVec.end();
+        I != E; ++I)
+      I->reset();
+  }
+  void set() {
+    for(std::vector<bitword>::iterator I=bitsetVec.begin(), E=bitsetVec.end();
+        I != E; ++I)
+      I->set();
+  }
+  std::bitset<32>::reference operator[](unsigned n) {
+    unsigned ndiv = n / WORDSIZE, nmod = n % WORDSIZE;
+    assert(ndiv  < bitsetVec.size() && "BitSetVector: Bit number out of range");
+    return bitsetVec[ndiv][nmod];
+  }
+  iterator begin() { return iterator::begin(*this); }
+  iterator end()   { return iterator::end(*this);   } 
+
+  /// 
+  ///  Set membership operations: single element, any, none, count
+  ///  
+  bool test(unsigned n) const {
+    unsigned ndiv = n / WORDSIZE, nmod = n % WORDSIZE;
+    assert(ndiv  < bitsetVec.size() && "BitSetVector: Bit number out of range");
+    return bitsetVec[ndiv].test(nmod);
+  }
+  bool any() const {
+    for (unsigned i = 0; i < bitsetVec.size(); ++i)
+      if (bitsetVec[i].any())
+        return true;
+    return false;
+  }
+  bool none() const {
+    return ! any();
+  }
+  unsigned count() const {
+    unsigned n = 0;
+    for (unsigned i = 0; i < bitsetVec.size(); ++i)
+      n += bitsetVec[i].count();
+    return n;
+  }
+
+  /// 
+  ///  Set operations: intersection, union, disjoint union, complement.
+  ///  
+  BitSetVector operator& (const BitSetVector& set2) const {
+    assert(maxSize == set2.maxSize && "Illegal intersection");
+    BitSetVector result(maxSize);
+    for (unsigned i = 0; i < bitsetVec.size(); ++i)
+      result.getWord(i) = getWord(i) & set2.getWord(i);
+    return result;
+  }
+  BitSetVector operator| (const BitSetVector& set2) const {
+    assert(maxSize == set2.maxSize && "Illegal intersection");
+    BitSetVector result(maxSize);
+    for (unsigned i = 0; i < bitsetVec.size(); ++i)
+      result.getWord(i) = getWord(i) | set2.getWord(i);
+    return result;
+  }
+  BitSetVector operator^ (const BitSetVector& set2) const {
+    assert(maxSize == set2.maxSize && "Illegal intersection");
+    BitSetVector result(maxSize);
+    for (unsigned i = 0; i < bitsetVec.size(); ++i)
+      result.getWord(i) = getWord(i) ^ set2.getWord(i);
+    return result;
+  }
+  BitSetVector operator~ () const {
+    BitSetVector result(maxSize);
+    for (unsigned i = 0; i < bitsetVec.size(); ++i)
+      (result.getWord(i) = getWord(i)).flip();
+    return result;
+  }
+
+  /// 
+  ///  Printing and debugging support
+  ///  
+  void print(std::ostream &O) const;
+  void dump() const { print(std::cerr); }
+
+public:
+  // 
+  // An iterator to enumerate the bits in a BitSetVector.
+  // Eventually, this needs to inherit from bidirectional_iterator.
+  // But this iterator may not be as useful as I once thought and
+  // may just go away.
+  // 
+  class iterator {
+    unsigned   currentBit;
+    unsigned   currentWord;
+    BitSetVector& bitvec;
+    iterator(unsigned B, unsigned W, BitSetVector _bitvec)
+      : currentBit(B), currentWord(W), bitvec(_bitvec) { }
+  public:
+    iterator(BitSetVector& _bitvec)
+      : currentBit(0), currentWord(0), bitvec(_bitvec) { }
+    iterator(const iterator& I)
+      : currentBit(I.currentBit),currentWord(I.currentWord),bitvec(I.bitvec) { }
+    iterator& operator=(const iterator& I) {
+      currentWord == I.currentWord;
+      currentBit == I.currentBit;
+      bitvec = I.bitvec;
+      return *this;
+    }
+
+    // Increment and decrement operators (pre and post)
+    iterator& operator++() {
+      if (++currentBit == WORDSIZE)
+        { currentBit = 0; if (currentWord < bitvec.maxSize) ++currentWord; }
+      return *this;
+    }
+    iterator& operator--() {
+      if (currentBit == 0) {
+        currentBit = WORDSIZE-1;
+        currentWord = (currentWord == 0)? bitvec.maxSize : --currentWord;
+      }
+      else
+        --currentBit;
+      return *this;
+    }
+    iterator operator++(int) { iterator copy(*this); ++*this; return copy; }
+    iterator operator--(int) { iterator copy(*this); --*this; return copy; }
+
+    // Dereferencing operators
+    reference operator*() {
+      assert(currentWord < bitvec.maxSize &&
+             "Dereferencing iterator past the end of a BitSetVector");
+      return bitvec.getWord(currentWord)[currentBit];
+    }
+
+    // Comparison operator
+    bool operator==(const iterator& I) {
+      return (&I.bitvec == &bitvec &&
+              I.currentWord == currentWord && I.currentBit == currentBit);
+    }
+
+  protected:
+    static iterator begin(BitSetVector& _bitvec) { return iterator(_bitvec); }
+    static iterator end(BitSetVector& _bitvec)   { return iterator(0,
+                                                    _bitvec.maxSize, _bitvec); }
+    friend class BitSetVector;
+  };
+};
+
+
+inline void BitSetVector::print(std::ostream& O) const
+{
+  for (std::vector<bitword>::const_iterator
+         I=bitsetVec.begin(), E=bitsetVec.end(); I != E; ++I)
+    O << "<" << (*I) << ">" << (I+1 == E? "\n" : ", ");
+}
+
+inline std::ostream& operator<< (std::ostream& O, const BitSetVector& bset)
+{
+  bset.print(O);
+  return O;
+};
+
+
+///
+/// Optimized versions of fundamental comparison operations
+/// 
+inline bool Disjoint(const BitSetVector& set1,
+                     const BitSetVector& set2)
+{
+  assert(set1.maxSize == set2.maxSize && "Illegal intersection");
+  for (unsigned i = 0; i < set1.bitsetVec.size(); ++i)
+    if ((set1.getWord(i) & set2.getWord(i)).any())
+      return false;
+  return true;
+}
+
+#endif