LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ImmutableIntervalMap.h
Go to the documentation of this file.
1 //===--- ImmutableIntervalMap.h - Immutable (functional) map ---*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the ImmutableIntervalMap class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_ADT_IMMUTABLEINTERVALMAP_H
15 #define LLVM_ADT_IMMUTABLEINTERVALMAP_H
16 
17 #include "llvm/ADT/ImmutableMap.h"
18 
19 namespace llvm {
20 
21 class Interval {
22 private:
23  int64_t Start;
24  int64_t End;
25 
26 public:
27  Interval(int64_t S, int64_t E) : Start(S), End(E) {}
28 
29  int64_t getStart() const { return Start; }
30  int64_t getEnd() const { return End; }
31 };
32 
33 template <typename T>
35  typedef const std::pair<Interval, T> value_type;
36  typedef const value_type &value_type_ref;
37  typedef const Interval key_type;
38  typedef const Interval &key_type_ref;
39  typedef const T data_type;
40  typedef const T &data_type_ref;
41 
43  return V.first;
44  }
45 
47  return V.second;
48  }
49 
50  static bool isEqual(key_type_ref L, key_type_ref R) {
51  return L.getStart() == R.getStart() && L.getEnd() == R.getEnd();
52  }
53 
56  }
57 
58  static bool isLess(key_type_ref L, key_type_ref R) {
59  // Assume L and R does not overlap.
60  if (L.getStart() < R.getStart()) {
61  assert(L.getEnd() < R.getStart());
62  return true;
63  } else if (L.getStart() == R.getStart()) {
64  assert(L.getEnd() == R.getEnd());
65  return false;
66  } else {
67  assert(L.getStart() > R.getEnd());
68  return false;
69  }
70  }
71 
73  if (K.getStart() >= L.getStart() && K.getEnd() <= L.getEnd())
74  return true;
75  else
76  return false;
77  }
78 
80  ID.AddInteger(V.first.getStart());
81  ID.AddInteger(V.first.getEnd());
82  ImutProfileInfo<T>::Profile(ID, V.second);
83  }
84 };
85 
86 template <typename ImutInfo>
87 class ImutIntervalAVLFactory : public ImutAVLFactory<ImutInfo> {
89  typedef typename ImutInfo::value_type value_type;
90  typedef typename ImutInfo::value_type_ref value_type_ref;
91  typedef typename ImutInfo::key_type key_type;
92  typedef typename ImutInfo::key_type_ref key_type_ref;
93  typedef typename ImutInfo::data_type data_type;
94  typedef typename ImutInfo::data_type_ref data_type_ref;
95 
96 public:
98  : ImutAVLFactory<ImutInfo>(Alloc) {}
99 
100  TreeTy *Add(TreeTy *T, value_type_ref V) {
101  T = add_internal(V,T);
102  this->MarkImmutable(T);
103  return T;
104  }
105 
106  TreeTy *Find(TreeTy *T, key_type_ref K) {
107  if (!T)
108  return NULL;
109 
110  key_type_ref CurrentKey = ImutInfo::KeyOfValue(this->getValue(T));
111 
112  if (ImutInfo::isContainedIn(K, CurrentKey))
113  return T;
114  else if (ImutInfo::isLess(K, CurrentKey))
115  return Find(this->getLeft(T), K);
116  else
117  return Find(this->getRight(T), K);
118  }
119 
120 private:
121  TreeTy *add_internal(value_type_ref V, TreeTy *T) {
122  key_type_ref K = ImutInfo::KeyOfValue(V);
123  T = removeAllOverlaps(T, K);
124  if (this->isEmpty(T))
125  return this->CreateNode(NULL, V, NULL);
126 
127  assert(!T->isMutable());
128 
129  key_type_ref KCurrent = ImutInfo::KeyOfValue(this->Value(T));
130 
131  if (ImutInfo::isLess(K, KCurrent))
132  return this->Balance(add_internal(V, this->Left(T)), this->Value(T),
133  this->Right(T));
134  else
135  return this->Balance(this->Left(T), this->Value(T),
136  add_internal(V, this->Right(T)));
137  }
138 
139  // Remove all overlaps from T.
140  TreeTy *removeAllOverlaps(TreeTy *T, key_type_ref K) {
141  bool Changed;
142  do {
143  Changed = false;
144  T = removeOverlap(T, K, Changed);
145  this->markImmutable(T);
146  } while (Changed);
147 
148  return T;
149  }
150 
151  // Remove one overlap from T.
152  TreeTy *removeOverlap(TreeTy *T, key_type_ref K, bool &Changed) {
153  if (!T)
154  return NULL;
155  Interval CurrentK = ImutInfo::KeyOfValue(this->Value(T));
156 
157  // If current key does not overlap the inserted key.
158  if (CurrentK.getStart() > K.getEnd())
159  return this->Balance(removeOverlap(this->Left(T), K, Changed),
160  this->Value(T), this->Right(T));
161  else if (CurrentK.getEnd() < K.getStart())
162  return this->Balance(this->Left(T), this->Value(T),
163  removeOverlap(this->Right(T), K, Changed));
164 
165  // Current key overlaps with the inserted key.
166  // Remove the current key.
167  Changed = true;
168  data_type_ref OldData = ImutInfo::DataOfValue(this->Value(T));
169  T = this->Remove_internal(CurrentK, T);
170  // Add back the unoverlapped part of the current key.
171  if (CurrentK.getStart() < K.getStart()) {
172  if (CurrentK.getEnd() <= K.getEnd()) {
173  Interval NewK(CurrentK.getStart(), K.getStart()-1);
174  return add_internal(std::make_pair(NewK, OldData), T);
175  } else {
176  Interval NewK1(CurrentK.getStart(), K.getStart()-1);
177  T = add_internal(std::make_pair(NewK1, OldData), T);
178 
179  Interval NewK2(K.getEnd()+1, CurrentK.getEnd());
180  return add_internal(std::make_pair(NewK2, OldData), T);
181  }
182  } else {
183  if (CurrentK.getEnd() > K.getEnd()) {
184  Interval NewK(K.getEnd()+1, CurrentK.getEnd());
185  return add_internal(std::make_pair(NewK, OldData), T);
186  } else
187  return T;
188  }
189  }
190 };
191 
192 /// ImmutableIntervalMap maps an interval [start, end] to a value. The intervals
193 /// in the map are guaranteed to be disjoint.
194 template <typename ValT>
196  : public ImmutableMap<Interval, ValT, ImutIntervalInfo<ValT> > {
197 
198  typedef typename ImutIntervalInfo<ValT>::value_type value_type;
199  typedef typename ImutIntervalInfo<ValT>::value_type_ref value_type_ref;
205 
206 public:
209 
210  class Factory {
212 
213  public:
214  Factory(BumpPtrAllocator& Alloc) : F(Alloc) {}
215 
217  return ImmutableIntervalMap(F.getEmptyTree());
218  }
219 
222  TreeTy *T = F.add(Old.Root, std::pair<key_type, data_type>(K, D));
223  return ImmutableIntervalMap(F.getCanonicalTree(T));
224  }
225 
227  TreeTy *T = F.remove(Old.Root, K);
228  return ImmutableIntervalMap(F.getCanonicalTree(T));
229  }
230 
232  TreeTy *T = F.Find(M.getRoot(), K);
233  if (T)
234  return &T->getValue().second;
235  else
236  return 0;
237  }
238  };
239 
240 private:
241  // For ImmutableIntervalMap, the lookup operation has to be done by the
242  // factory.
243  data_type* lookup(key_type_ref K) const;
244 };
245 
246 } // end namespace llvm
247 
248 #endif
Interval(int64_t S, int64_t E)
int64_t getStart() const
ImutIntervalAVLFactory(BumpPtrAllocator &Alloc)
data_type * lookup(ImmutableIntervalMap M, key_type_ref K)
static key_type_ref KeyOfValue(value_type_ref V)
void AddInteger(signed I)
Definition: FoldingSet.cpp:60
int64_t getEnd() const
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
#define T
static bool isLess(key_type_ref L, key_type_ref R)
static bool isDataEqual(data_type_ref L, data_type_ref R)
void markImmutable(TreeTy *T)
Definition: ImmutableSet.h:599
static bool isEqual(key_type_ref LHS, key_type_ref RHS)
Definition: ImmutableSet.h:901
const value_type & value_type_ref
TreeTy * getRight(TreeTy *T) const
Definition: ImmutableSet.h:428
value_type_ref getValue(TreeTy *T) const
Definition: ImmutableSet.h:429
static void Profile(FoldingSetNodeID &ID, value_type_ref V)
static data_type_ref DataOfValue(value_type_ref V)
TreeTy * getRoot() const
Definition: ImmutableMap.h:141
static bool isEqual(key_type_ref L, key_type_ref R)
TreeTy * Add(TreeTy *T, value_type_ref V)
const value_type & getValue() const
getValue - Returns the data value associated with the tree node.
Definition: ImmutableSet.h:69
bool isEmpty(TreeTy *T) const
Definition: ImmutableSet.h:425
TreeTy * Find(TreeTy *T, key_type_ref K)
static void Profile(FoldingSetNodeID &ID, value_type_ref X)
Definition: ImmutableSet.h:822
LLVM Value Representation.
Definition: Value.h:66
const Interval & key_type_ref
static bool isContainedIn(key_type_ref K, key_type_ref L)
ImmutableIntervalMap add(ImmutableIntervalMap Old, key_type_ref K, data_type_ref D)
const std::pair< Interval, T > value_type
TreeTy * getLeft(TreeTy *T) const
Definition: ImmutableSet.h:427