Skip to content

Commit ce77651

Browse files
committed
[ConstraintLocator] Always store the PathElementKind in each path element.
1 parent 17e5ec4 commit ce77651

File tree

1 file changed

+31
-74
lines changed

1 file changed

+31
-74
lines changed

lib/Sema/ConstraintLocator.h

Lines changed: 31 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -122,23 +122,19 @@ class ConstraintLocator : public llvm::FoldingSetNode {
122122
class PathElement {
123123
/// Describes the kind of data stored here.
124124
enum StoredKind : unsigned char {
125-
StoredGenericParameter,
126-
StoredProtocolRequirement,
127-
StoredWitness,
128-
StoredGenericSignature,
129-
StoredKeyPathDynamicMemberBase,
130-
StoredPattern,
131-
StoredKindAndValue
125+
StoredPointer,
126+
StoredInteger,
132127
};
133128

129+
PathElementKind kind;
130+
134131
/// The actual storage for the path element, which involves both a
135-
/// kind and (potentially) a value.
132+
/// storage kind and a value.
136133
///
137-
/// The current storage involves a two-bit "storage kind", which selects
138-
/// among the possible value stores. The value stores can either be an
139-
/// archetype (for archetype path elements) or an unsigned value that
140-
/// stores both the specific kind and the (optional) numeric value of that
141-
/// kind. Use \c encodeStorage and \c decodeStorage to work with this value.
134+
/// The current storage involves a three-bit "storage kind", which selects
135+
/// among the possible value stores. The value stores can either be a
136+
/// pointer or an unsigned int. Use \c getValue or \c getStoredPointer
137+
/// to work with this value.
142138
///
143139
/// \note The "storage kind" is stored in the \c storedKind field.
144140
uint64_t storage : 61;
@@ -147,17 +143,6 @@ class ConstraintLocator : public llvm::FoldingSetNode {
147143
/// from the StoredKind enum.
148144
uint64_t storedKind : 3;
149145

150-
/// Encode a path element kind and a value into the storage format.
151-
static uint64_t encodeStorage(PathElementKind kind, uint64_t value) {
152-
return (value << 8) | kind;
153-
}
154-
155-
/// Decode a storage value into path element kind and value.
156-
static std::pair<PathElementKind, uint64_t>
157-
decodeStorage(uint64_t storage) {
158-
return { (PathElementKind)((unsigned)storage & 0xFF), storage >> 8 };
159-
}
160-
161146
/// Retrieve a value associated with the path element.
162147
unsigned getValue(unsigned index) const {
163148
unsigned numValues = numNumericValuesInPathElement(getKind());
@@ -167,32 +152,31 @@ class ConstraintLocator : public llvm::FoldingSetNode {
167152
// being stored in the upper bits, valueN in the lower bits. Therefore we
168153
// need to shift out any extra values in the lower bits.
169154
auto extraValues = numValues - index - 1;
170-
auto value = decodeStorage(storage).second >> (extraValues * 16);
155+
auto value = storage >> (extraValues * 16);
171156
return value & 0xFFFF;
172157
}
173158

174159
PathElement(PathElementKind kind, unsigned value)
175-
: storage(encodeStorage(kind, value)), storedKind(StoredKindAndValue)
160+
: kind(kind), storage(value), storedKind(StoredInteger)
176161
{
177162
assert(numNumericValuesInPathElement(kind) == 1 &&
178163
"Path element kind does not require 1 value");
179164
assert(value == getValue(0) && "value truncated");
180165
}
181166

182167
PathElement(PathElementKind kind, unsigned value0, unsigned value1)
183-
: storage(encodeStorage(kind, value0 << 16 | value1)),
184-
storedKind(StoredKindAndValue)
168+
: kind(kind), storage(value0 << 16 | value1),
169+
storedKind(StoredInteger)
185170
{
186171
assert(numNumericValuesInPathElement(kind) == 2 &&
187172
"Path element kind does not require 2 values");
188173
assert(value0 == getValue(0) && "value0 truncated");
189174
assert(value1 == getValue(1) && "value1 truncated");
190175
}
191176

192-
PathElement(PathElementKind kind, uint64_t value0, uint64_t value1,
193-
uint64_t value2)
194-
: storage(encodeStorage(kind, value0 << 32 | value1 << 16 | value2)),
195-
storedKind(StoredKindAndValue) {
177+
PathElement(PathElementKind kind, uint64_t value0, uint64_t value1, uint64_t value2)
178+
: kind(kind), storage(value0 << 32 | value1 << 16 | value2),
179+
storedKind(StoredInteger) {
196180
assert(numNumericValuesInPathElement(kind) == 3 &&
197181
"Path element kind does not require 3 values");
198182
assert(value0 == getValue(0) && "value0 truncated");
@@ -203,17 +187,17 @@ class ConstraintLocator : public llvm::FoldingSetNode {
203187
/// Store a path element with an associated pointer, accessible using
204188
/// \c getStoredPointer.
205189
template <typename T>
206-
PathElement(StoredKind storedKind, T *ptr)
207-
: storage((reinterpret_cast<uintptr_t>(ptr) >> 3)),
208-
storedKind(storedKind) {
190+
PathElement(PathElementKind kind, T *ptr)
191+
: kind(kind), storage((reinterpret_cast<uintptr_t>(ptr) >> 3)),
192+
storedKind(StoredPointer) {
209193
assert(ptr == getStoredPointer<T>());
210194
}
211195

212196
/// Retrieve an associated pointer for the element. The type \c T must match
213197
/// the type used when creating the path element.
214198
template <typename T>
215199
T *getStoredPointer() const {
216-
assert(storedKind != StoredKindAndValue);
200+
assert(storedKind == StoredPointer);
217201
return reinterpret_cast<T *>(storage << 3);
218202
}
219203

@@ -224,39 +208,14 @@ class ConstraintLocator : public llvm::FoldingSetNode {
224208
#include "ConstraintLocatorPathElts.def"
225209

226210
PathElement(PathElementKind kind)
227-
: storage(encodeStorage(kind, 0)), storedKind(StoredKindAndValue)
211+
: kind(kind), storage(0), storedKind(StoredInteger)
228212
{
229213
assert(numNumericValuesInPathElement(kind) == 0 &&
230214
"Path element requires value");
231215
}
232216

233217
/// Retrieve the kind of path element.
234-
PathElementKind getKind() const {
235-
switch (static_cast<StoredKind>(storedKind)) {
236-
case StoredGenericParameter:
237-
return PathElementKind::GenericParameter;
238-
239-
case StoredProtocolRequirement:
240-
return PathElementKind::ProtocolRequirement;
241-
242-
case StoredWitness:
243-
return PathElementKind::Witness;
244-
245-
case StoredGenericSignature:
246-
return PathElementKind::OpenedGeneric;
247-
248-
case StoredKeyPathDynamicMemberBase:
249-
return PathElementKind::KeyPathDynamicMember;
250-
251-
case StoredPattern:
252-
return PathElementKind::PatternMatch;
253-
254-
case StoredKindAndValue:
255-
return decodeStorage(storage).first;
256-
}
257-
258-
llvm_unreachable("Unhandled StoredKind in switch.");
259-
}
218+
PathElementKind getKind() const { return kind; }
260219

261220
/// Attempts to cast the path element to a specific \c LocatorPathElt
262221
/// subclass, returning \c None if unsuccessful.
@@ -765,31 +724,31 @@ class LocatorPathElt::ContextualType final : public LocatorPathElt {
765724
class LocatorPathElt::Witness final : public LocatorPathElt {
766725
public:
767726
Witness(ValueDecl *witness)
768-
: LocatorPathElt(LocatorPathElt::StoredWitness, witness) {}
727+
: LocatorPathElt(PathElementKind::Witness, witness) {}
769728

770729
ValueDecl *getDecl() const { return getStoredPointer<ValueDecl>(); }
771730

772731
static bool classof(const LocatorPathElt *elt) {
773-
return elt->getKind() == ConstraintLocator::Witness;
732+
return elt->getKind() == PathElementKind::Witness;
774733
}
775734
};
776735

777736
class LocatorPathElt::ProtocolRequirement final : public LocatorPathElt {
778737
public:
779738
ProtocolRequirement(ValueDecl *decl)
780-
: LocatorPathElt(LocatorPathElt::StoredProtocolRequirement, decl) {}
739+
: LocatorPathElt(PathElementKind::ProtocolRequirement, decl) {}
781740

782741
ValueDecl *getDecl() const { return getStoredPointer<ValueDecl>(); }
783742

784743
static bool classof(const LocatorPathElt *elt) {
785-
return elt->getKind() == ConstraintLocator::ProtocolRequirement;
744+
return elt->getKind() == PathElementKind::ProtocolRequirement;
786745
}
787746
};
788747

789748
class LocatorPathElt::GenericParameter final : public LocatorPathElt {
790749
public:
791750
GenericParameter(GenericTypeParamType *type)
792-
: LocatorPathElt(LocatorPathElt::StoredGenericParameter, type) {
751+
: LocatorPathElt(PathElementKind::GenericParameter, type) {
793752
static_assert(alignof(GenericTypeParamType) >= 4,
794753
"archetypes insufficiently aligned");
795754
}
@@ -799,15 +758,14 @@ class LocatorPathElt::GenericParameter final : public LocatorPathElt {
799758
}
800759

801760
static bool classof(const LocatorPathElt *elt) {
802-
return elt->getKind() == ConstraintLocator::GenericParameter;
761+
return elt->getKind() == PathElementKind::GenericParameter;
803762
}
804763
};
805764

806765
class LocatorPathElt::OpenedGeneric final : public LocatorPathElt {
807766
public:
808767
OpenedGeneric(GenericSignature sig)
809-
: LocatorPathElt(LocatorPathElt::StoredGenericSignature,
810-
sig.getPointer()) {}
768+
: LocatorPathElt(PathElementKind::OpenedGeneric, sig.getPointer()) {}
811769

812770
GenericSignature getSignature() const {
813771
return getStoredPointer<GenericSignatureImpl>();
@@ -821,8 +779,7 @@ class LocatorPathElt::OpenedGeneric final : public LocatorPathElt {
821779
class LocatorPathElt::KeyPathDynamicMember final : public LocatorPathElt {
822780
public:
823781
KeyPathDynamicMember(NominalTypeDecl *keyPathDecl)
824-
: LocatorPathElt(LocatorPathElt::StoredKeyPathDynamicMemberBase,
825-
keyPathDecl) {}
782+
: LocatorPathElt(PathElementKind::KeyPathDynamicMember, keyPathDecl) {}
826783

827784
NominalTypeDecl *getKeyPathDecl() const {
828785
return getStoredPointer<NominalTypeDecl>();
@@ -850,7 +807,7 @@ class LocatorPathElt::TernaryBranch final : public LocatorPathElt {
850807
class LocatorPathElt::PatternMatch final : public LocatorPathElt {
851808
public:
852809
PatternMatch(Pattern *pattern)
853-
: LocatorPathElt(LocatorPathElt::StoredPattern, pattern) {}
810+
: LocatorPathElt(PathElementKind::PatternMatch, pattern) {}
854811

855812
Pattern *getPattern() const { return getStoredPointer<Pattern>(); }
856813

0 commit comments

Comments
 (0)