forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLocalTypeDataCache.h
141 lines (112 loc) · 3.91 KB
/
LocalTypeDataCache.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//===-- LocalTypeDataCache.h - Dominance-scoped type data cache -*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the LocalTypeDataCache type, which is used by
// IRGenFunction to cache the information available for types in a local
// context.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_IRGEN_LOCALTYPEDATACACHE_H
#define SWIFT_IRGEN_LOCALTYPEDATACACHE_H
#include "swift/AST/Type.h"
#include <utility>
namespace swift {
class TypeBase;
namespace irgen {
enum class ValueWitness : unsigned;
/// A nonce value for storing some sort of locally-known information
/// about a type.
class LocalTypeData {
public:
using RawType = unsigned;
private:
RawType Value;
explicit LocalTypeData(unsigned Value) : Value(Value) {}
/// Magic values for special kinds of index.
enum : RawType {
Metatype = ~0U,
ValueWitnessTable = ~1U,
ValueWitnessBase = 0xFFFFFF00U,
};
public:
LocalTypeData() = default;
// The magic values are all in the "negative" range and so do
// not collide with reasonable index values.
/// A reference to the type metadata.
static LocalTypeData forMetatype() { return LocalTypeData(Metatype); }
/// A reference to the value witness table.
static LocalTypeData forValueWitnessTable() {
return LocalTypeData(ValueWitnessTable);
}
/// A reference to a specific value witness.
static LocalTypeData forValueWitness(ValueWitness witness) {
return LocalTypeData((unsigned)witness + ValueWitnessBase);
}
/// A reference to a protocol witness table for an archetype.
static LocalTypeData forArchetypeProtocolWitness(unsigned index) {
return LocalTypeData(index);
}
RawType getRawValue() const {
return Value;
}
};
class LocalTypeDataCache {
public:
using Key = std::pair<TypeBase*, LocalTypeData::RawType>;
static Key getKey(CanType type, LocalTypeData index) {
return Key(type.getPointer(), index.getRawValue());
}
/// An opaque class for storing keys for the dominance callback. The
/// key is assumed to be something like a pointer, and a null pointer is
/// assumed to mean a non-dominating point.
class DominanceKey {
void *Value;
public:
explicit DominanceKey(void *value = nullptr) : Value(value) {}
template <class T> T* as() const { return reinterpret_cast<T*>(Value); }
explicit operator bool() const { return Value != nullptr; }
};
/// A RAII object for managing a dominance scope.
class DominanceScope {
LocalTypeDataCache &Cache;
DominanceKey OldDefinitionPoint;
public:
explicit DominanceScope(LocalTypeDataCache &cache, DominanceKey newPoint)
: Cache(cache), OldDefinitionPoint(cache.ActiveDefinitionPoint) {
cache.ActiveDefinitionPoint = newPoint;
assert(!newPoint || cache.Callback);
}
DominanceScope(const DominanceScope &other) = delete;
DominanceScope &operator=(const DominanceScope &other) = delete;
~DominanceScope() {
Cache.ActiveDefinitionPoint = OldDefinitionPoint;
}
};
using DominanceCallback = bool(IRGenFunction &IGF, DominanceKey key);
private:
/// The dominance callback. This can be set at most once; when it's not
/// set, the cache must never have a non-null active definition point.
DominanceCallback *Callback = nullptr;
DominanceKey ActiveDefinitionPoint;
struct CacheEntryBase {
DominanceKey DefinitionPoint;
};
struct Source {
llvm::Value *Value;
MetadataPath::Map<llvm::Value*> Path;
};
std::vector<
public:
};
}
}
#endif