Skip to content

Commit 19ebd05

Browse files
committed
[ADT] Add a new data structure to enumerate values.
This data structure enumerates values and gives them unqiue indices. This data structure will be used by the AliasAnalysis Cache.
1 parent 886d2fc commit 19ebd05

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

include/swift/Basic/ValueEnumerator.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===--- ValueEnumerator.h --- Enumerates values ----------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_BASIC_VALUEENUMERATOR_H
14+
#define SWIFT_BASIC_VALUEENUMERATOR_H
15+
16+
#include "llvm/ADT/DenseMap.h"
17+
#include "llvm/Support/raw_ostream.h"
18+
19+
namespace swift {
20+
21+
/// / This class maps values to unique indices.
22+
template<class ValueTy, class IndexTy = size_t>
23+
class ValueEnumerator {
24+
/// A running counter to enumerate values.
25+
IndexTy counter;
26+
27+
/// Maps values to unique integers.
28+
llvm::DenseMap<ValueTy, IndexTy> ValueToIndex;
29+
30+
public:
31+
/// Return the index of value \p v.
32+
IndexTy getIndex(const ValueTy &v) {
33+
// Return the index of this Key, if we've assigned one already.
34+
auto It = ValueToIndex.find(v);
35+
if (It != ValueToIndex.end()) {
36+
return It->second;
37+
}
38+
39+
// Generate a new counter for the key.
40+
ValueToIndex[v] = ++counter;
41+
return counter;
42+
}
43+
44+
ValueEnumerator() = default;
45+
46+
/// Forget about key \p v.
47+
void invalidateValue(const ValueTy &v) { ValueToIndex.erase(v); }
48+
49+
/// Clear the enumeration state of the
50+
void clear() {
51+
ValueToIndex.clear();
52+
counter = 0;
53+
}
54+
};
55+
56+
} // end namespace swift
57+
58+
#endif

unittests/Basic/ADTTests.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "swift/Basic/OptionSet.h"
2+
#include "swift/Basic/ValueEnumerator.h"
23
#include "gtest/gtest.h"
34

45
using namespace swift;
@@ -99,3 +100,62 @@ TEST(OptionSet, intptr_t_isConstructible) {
99100
}
100101

101102

103+
TEST(ValueEnumerator, basic) {
104+
105+
{
106+
ValueEnumerator<int> Trans;
107+
// Check that indexing is persistent.
108+
EXPECT_EQ(Trans.getIndex(99), Trans.getIndex(99));
109+
EXPECT_EQ(Trans.getIndex(100), Trans.getIndex(100));
110+
111+
// Check that we don't have collisions.
112+
bool SameIndex = Trans.getIndex(82) == Trans.getIndex(73);
113+
EXPECT_FALSE(SameIndex);
114+
115+
// Check that invalidation works.
116+
// After invalidation the old index must not be equal to the new index.
117+
size_t oldIndex = Trans.getIndex(99);
118+
Trans.invalidateValue(99);
119+
size_t newIndex = Trans.getIndex(99);
120+
EXPECT_FALSE(newIndex == oldIndex);
121+
}
122+
123+
{
124+
const char *string_1 = "hello";
125+
const char *string_2 = "goodbye";
126+
const char *string_3 = ":-)";
127+
ValueEnumerator<const char*> Trans;
128+
EXPECT_EQ(Trans.getIndex(nullptr), Trans.getIndex(nullptr));
129+
EXPECT_EQ(Trans.getIndex(string_1), Trans.getIndex(string_1));
130+
EXPECT_EQ(Trans.getIndex(string_2), Trans.getIndex(string_2));
131+
132+
// Check that invalidation works.
133+
size_t oldIndex = Trans.getIndex(string_3);
134+
Trans.invalidateValue(string_3);
135+
size_t newIndex = Trans.getIndex(string_3);
136+
EXPECT_FALSE(newIndex == oldIndex);
137+
138+
// Check that different values don't give the same index.
139+
EXPECT_FALSE(Trans.getIndex(string_2) == Trans.getIndex(string_3));
140+
}
141+
142+
143+
{
144+
ValueEnumerator<int> Trans;
145+
// Check a bunch of integers.
146+
for (int i = 1; i < 10000; i++) {
147+
EXPECT_TRUE(Trans.getIndex(0) != Trans.getIndex(i));
148+
}
149+
150+
// Check that there are no accidental collisions.
151+
for (int i = 0; i < 10000; i++) {
152+
for (int j = 1; j < 10; j++) {
153+
EXPECT_TRUE(Trans.getIndex(i) != Trans.getIndex(i + j));
154+
}
155+
}
156+
157+
// Check that indexing is still persistent.
158+
EXPECT_EQ(Trans.getIndex(100), Trans.getIndex(100));
159+
}
160+
161+
}

0 commit comments

Comments
 (0)