[llvm-commits] [llvm] r94976 - in /llvm/trunk/include/llvm/ADT: ImmutableIntervalMap.h ImmutableMap.h ImmutableSet.h

Zhongxing Xu xuzhongxing at gmail.com
Mon Feb 1 02:43:31 PST 2010


Author: zhongxingxu
Date: Mon Feb  1 04:43:31 2010
New Revision: 94976

URL: http://llvm.org/viewvc/llvm-project?rev=94976&view=rev
Log:
Add an immutable interval map, prepared to be used by flat memory model 
in the analyzer. WIP.

Added:
    llvm/trunk/include/llvm/ADT/ImmutableIntervalMap.h
Modified:
    llvm/trunk/include/llvm/ADT/ImmutableMap.h
    llvm/trunk/include/llvm/ADT/ImmutableSet.h

Added: llvm/trunk/include/llvm/ADT/ImmutableIntervalMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableIntervalMap.h?rev=94976&view=auto

==============================================================================
--- llvm/trunk/include/llvm/ADT/ImmutableIntervalMap.h (added)
+++ llvm/trunk/include/llvm/ADT/ImmutableIntervalMap.h Mon Feb  1 04:43:31 2010
@@ -0,0 +1,199 @@
+//===--- ImmutableIntervalMap.h - Immutable (functional) map  ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ImmutableIntervalMap class.
+//
+//===----------------------------------------------------------------------===//
+#include "llvm/ADT/ImmutableMap.h"
+
+namespace llvm {
+
+class Interval {
+private:
+  uint64_t Start;
+  uint64_t End;
+
+public:
+  Interval(uint64_t S, uint64_t E) : Start(S), End(E) {}
+
+  uint64_t getStart() const { return Start; }
+  uint64_t getEnd() const { return End; }
+};
+
+template <typename T>
+struct ImutIntervalInfo {
+  typedef const std::pair<Interval, T> value_type;
+  typedef const value_type &value_type_ref;
+  typedef const Interval key_type;
+  typedef const Interval &key_type_ref;
+  typedef const T data_type;
+  typedef const T &data_type_ref;
+
+  static key_type_ref KeyOfValue(value_type_ref V) {
+    return V.first;
+  }
+
+  static data_type_ref DataOfValue(value_type_ref V) {
+    return V.second;
+  }
+
+  static bool isEqual(key_type_ref L, key_type_ref R) {
+    return L.getStart() == R.getStart() && L.getEnd() == R.getEnd();
+  }
+
+  static bool isDataEqual(data_type_ref L, data_type_ref R) {
+    return ImutContainerInfo<T>::isEqual(L,R);
+  }
+
+  static bool isLess(key_type_ref L, key_type_ref R) {
+    // Assume L and R does not overlap.
+    if (L.getStart() < R.getStart()) {
+      assert(L.getEnd() < R.getStart());
+      return true;
+    } else if (L.getStart() == R.getStart()) {
+      assert(L.getEnd() == R.getEnd());
+      return false;
+    } else {
+      assert(L.getStart() > R.getEnd());
+      return false;
+    }
+  }
+
+  static void Profile(FoldingSetNodeID &ID, value_type_ref V) {
+    ID.AddInteger(V.first.getStart());
+    ID.AddInteger(V.first.getEnd());
+    ImutProfileInfo<T>::Profile(ID, V.second);
+  }
+};
+
+template <typename ImutInfo> class ImutIntervalAVLFactory;
+
+template <typename ImutInfo>
+class ImutIntervalAVLFactory : public ImutAVLFactory<ImutInfo> {
+  typedef ImutAVLTree<ImutInfo> TreeTy;
+  typedef typename ImutInfo::value_type     value_type;
+  typedef typename ImutInfo::value_type_ref value_type_ref;
+  typedef typename ImutInfo::key_type       key_type;
+  typedef typename ImutInfo::key_type_ref   key_type_ref;
+  typedef typename ImutInfo::data_type      data_type;
+  typedef typename ImutInfo::data_type_ref  data_type_ref;
+
+public:
+  TreeTy *Add(TreeTy* T, value_type_ref V) {
+    T = Add_internal(V,T);
+    MarkImmutable(T);
+    return T;
+  }
+
+private:
+  TreeTy *Add_internal(value_type_ref V, TreeTy *T) {
+    if (isEmpty(T))
+      return CreateNode(NULL, V, NULL);
+
+    assert(!T->isMutable());
+
+    key_type_ref K = ImutInfo::KeyOfValue(V);
+    key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T));
+
+    T = RemoveAllOverlaps(T, K);
+
+    if (ImutInfo::isLess(K, KCurrent))
+      return Balance(Add_internal(V, Left(T)), Value(T), Right(T));
+    else
+      return Balance(Left(T), Value(T), Add_internal(V, Right(T)));
+  }
+
+  // Remove all overlaps from T.
+  TreeTy *RemoveAllOverlaps(TreeTy *T, key_type_ref K) {
+    TreeTy *OldTree, *NewTree;
+    NewTree = T;
+    do {
+      OldTree = NewTree;
+      NewTree = RemoveOverlap(OldTree, K);
+    } while (NewTree != OldTree);
+  }
+
+  // Remove one overlap from T.
+  TreeTy *RemoveOverlap(TreeTy *T, key_type_ref K) {
+    Interval CurrentK = ImutInfo::KeyOfValue(Value(T));
+
+    // If current key does not overlap the inserted key.
+    if (CurrentK.getStart() > K.getEnd())
+      return RemoveOverlap(Left(T), K);
+    else if (CurrentK.getEnd() < K.getStart())
+      return RemoveOverlap(Right(T), K);
+
+    // Current key overlaps with the inserted key.
+    // Remove the current key.
+    T = Remove_internal(CurrentK, T);
+    // Add back the unoverlapped part of the current key.
+    if (CurrentK.getStart() < K.getStart()) {
+      if (CurrentK.getEnd() <= K.getEnd()) {
+        Interval NewK(CurrentK.getStart(), K.getStart()-1);
+        return Add_internal(std::make_pair<key_type, data_type>(NewK, 
+                                           ImutInfo::DataOfValue(Value(T))), T);
+      } else {
+        Interval NewK1(CurrentK.getStart(), K.getStart()-1);
+        T = Add_internal(std::make_pair<key_type, data_type>(NewK1, 
+                                           ImutInfo::DataOfValue(Value(T))), T);
+
+        Interval NewK2(K.getEnd()+1, CurrentK.getEnd());
+        return Add_internal(std::make_pair<key_type, data_type>(NewK2,
+                                           ImutInfo::DataOfValue(Value(T))), T);
+      }
+    } else {
+      if (CurrentK.getEnd() > K.getEnd()) {
+        Interval NewK(K.getEnd()+1, CurrentK.getEnd());
+        return Add_internal(std::make_pair<key_type, data_type>(NewK, 
+                                           ImutInfo::DataOfValue(Value(T))), T);
+      }
+    }
+  }
+};
+
+/// ImmutableIntervalMap maps an interval [start, end] to a value. The intervals
+/// in the map are guaranteed to be disjoint.
+template <typename ValT>
+class ImmutableIntervalMap 
+  : public ImmutableMap<Interval, ValT, ImutIntervalInfo<ValT> > {
+
+  typedef typename ImutIntervalInfo<ValT>::value_type      value_type;
+  typedef typename ImutIntervalInfo<ValT>::value_type_ref  value_type_ref;
+  typedef typename ImutIntervalInfo<ValT>::key_type        key_type;
+  typedef typename ImutIntervalInfo<ValT>::key_type_ref    key_type_ref;
+  typedef typename ImutIntervalInfo<ValT>::data_type       data_type;
+  typedef typename ImutIntervalInfo<ValT>::data_type_ref   data_type_ref;
+  typedef ImutAVLTree<ImutIntervalInfo<ValT> > TreeTy;
+
+public:
+  explicit ImmutableIntervalMap(TreeTy *R) 
+    : ImmutableMap<Interval, ValT, ImutIntervalInfo<ValT> >(R) {}
+
+  class Factory {
+    ImutIntervalAVLFactory<ImutIntervalInfo<ValT> > F;
+
+  public:
+    ImmutableIntervalMap GetEmptyMap() { 
+      return ImmutableIntervalMap(F.GetEmptyTree()); 
+    }
+
+    ImmutableIntervalMap Add(ImmutableIntervalMap Old, 
+                             key_type_ref K, data_type_ref D) {
+      TreeTy *T = F.Add(Old.Root, std::make_pair<key_type, data_type>(K, D));
+      return ImmutableIntervalMap(F.GetCanonicalTree(T));
+    }
+
+    ImmutableIntervalMap Remove(ImmutableIntervalMap Old, key_type_ref K) {
+      TreeTy *T = F.Remove(Old.Root, K);
+      return ImmutableIntervalMap(F.GetCanonicalTree(T));
+    }
+  };
+};
+
+} // end namespace llvm

Modified: llvm/trunk/include/llvm/ADT/ImmutableMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableMap.h?rev=94976&r1=94975&r2=94976&view=diff

==============================================================================
--- llvm/trunk/include/llvm/ADT/ImmutableMap.h (original)
+++ llvm/trunk/include/llvm/ADT/ImmutableMap.h Mon Feb  1 04:43:31 2010
@@ -68,7 +68,7 @@
   typedef typename ValInfo::data_type_ref   data_type_ref;
   typedef ImutAVLTree<ValInfo>              TreeTy;
 
-private:
+protected:
   TreeTy* Root;
 
 public:

Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableSet.h?rev=94976&r1=94975&r2=94976&view=diff

==============================================================================
--- llvm/trunk/include/llvm/ADT/ImmutableSet.h (original)
+++ llvm/trunk/include/llvm/ADT/ImmutableSet.h Mon Feb  1 04:43:31 2010
@@ -27,6 +27,7 @@
 //===----------------------------------------------------------------------===//
 
 template <typename ImutInfo> class ImutAVLFactory;
+template <typename ImutInfo> class ImutIntervalAVLFactory;
 template <typename ImutInfo> class ImutAVLTreeInOrderIterator;
 template <typename ImutInfo> class ImutAVLTreeGenericIterator;
 
@@ -39,6 +40,7 @@
 
   typedef ImutAVLFactory<ImutInfo>          Factory;
   friend class ImutAVLFactory<ImutInfo>;
+  friend class ImutIntervalAVLFactory<ImutInfo>;
 
   friend class ImutAVLTreeGenericIterator<ImutInfo>;
   friend class FoldingSet<ImutAVLTree>;
@@ -389,7 +391,7 @@
   // These have succinct names so that the balancing code
   // is as terse (and readable) as possible.
   //===--------------------------------------------------===//
-private:
+protected:
 
   bool           isEmpty(TreeTy* T) const { return !T; }
   unsigned Height(TreeTy* T) const { return T ? T->getHeight() : 0; }





More information about the llvm-commits mailing list