Skip to content

Commit 313751c

Browse files
authored
Merge branch 'release/6.0' into eng/PR-125989715-6.0
2 parents 819ca1a + b099cd5 commit 313751c

File tree

52 files changed

+1035
-222
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1035
-222
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceDiagnostics.swift

+1-4
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ private func log(prefix: Bool = true, _ message: @autoclosure () -> String) {
2929
let lifetimeDependenceDiagnosticsPass = FunctionPass(
3030
name: "lifetime-dependence-diagnostics")
3131
{ (function: Function, context: FunctionPassContext) in
32-
if !context.options.hasFeature(.NonescapableTypes) {
33-
return
34-
}
3532
log(prefix: false, "\n--- Diagnosing lifetime dependence in \(function.name)")
3633
log("\(function)")
3734

@@ -45,7 +42,7 @@ let lifetimeDependenceDiagnosticsPass = FunctionPass(
4542
}
4643
}
4744
for instruction in function.instructions {
48-
if let markDep = instruction as? MarkDependenceInst {
45+
if let markDep = instruction as? MarkDependenceInst, markDep.isUnresolved {
4946
if let lifetimeDep = LifetimeDependence(markDep, context) {
5047
analyze(dependence: lifetimeDep, context)
5148
}

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceInsertion.swift

-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ private func log(prefix: Bool = true, _ message: @autoclosure () -> String) {
3131
let lifetimeDependenceInsertionPass = FunctionPass(
3232
name: "lifetime-dependence-insertion")
3333
{ (function: Function, context: FunctionPassContext) in
34-
if !context.options.hasFeature(.NonescapableTypes) {
35-
return
36-
}
3734
log(prefix: false, "\n--- Inserting lifetime dependence markers in \(function.name)")
3835

3936
for instruction in function.instructions {

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceScopeFixup.swift

-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ private func log(prefix: Bool = true, _ message: @autoclosure () -> String) {
3131
let lifetimeDependenceScopeFixupPass = FunctionPass(
3232
name: "lifetime-dependence-scope-fixup")
3333
{ (function: Function, context: FunctionPassContext) in
34-
if !context.options.hasFeature(.NonescapableTypes) {
35-
return
36-
}
3734
log(prefix: false, "\n--- Scope fixup for lifetime dependence in \(function.name)")
3835

3936
let localReachabilityCache = LocalVariableReachabilityCache()

include/swift/AST/DiagnosticsIRGen.def

+4
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,9 @@ ERROR(temporary_allocation_alignment_not_power_of_2,none,
6565
ERROR(explosion_size_oveflow,none,
6666
"explosion size too large", ())
6767

68+
NOTE(layout_strings_blocked,none,
69+
"Layout string value witnesses have been disabled for module '%0' "
70+
"through block list entry", (StringRef))
71+
6872
#define UNDEFINE_DIAGNOSTIC_MACROS
6973
#include "DefineDiagnosticMacros.h"

include/swift/Basic/BlockListAction.def

+1
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@
2222
BLOCKLIST_ACTION(ShouldUseBinaryModule)
2323
BLOCKLIST_ACTION(ShouldUseTextualModule)
2424
BLOCKLIST_ACTION(DowngradeInterfaceVerificationFailure)
25+
BLOCKLIST_ACTION(ShouldUseLayoutStringValueWitnesses)
2526

2627
#undef BLOCKLIST_ACTION

include/swift/Runtime/LibPrespecialized.h

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ struct LibPrespecializedData {
4848
const LibPrespecializedData<InProcess> *getLibPrespecializedData();
4949
Metadata *getLibPrespecializedMetadata(const TypeContextDescriptor *description,
5050
const void *const *arguments);
51+
void libPrespecializedImageLoaded();
5152

5253
} // namespace swift
5354

lib/AST/ASTContext.cpp

-12
Original file line numberDiff line numberDiff line change
@@ -5867,18 +5867,6 @@ ASTContext::getOpenedExistentialSignature(Type type, GenericSignature parentSig)
58675867
assert(parentSig || !constraint->hasTypeParameter() &&
58685868
"Interface type here requires a parent signature");
58695869

5870-
// The opened archetype signature for a protocol type is identical
5871-
// to the protocol's own canonical generic signature if there aren't any
5872-
// outer generic parameters to worry about.
5873-
if (parentSig.isNull()) {
5874-
if (const auto protoTy = dyn_cast<ProtocolType>(constraint)) {
5875-
return protoTy->getDecl()->getGenericSignature().getCanonicalSignature();
5876-
}
5877-
}
5878-
5879-
// Otherwise we need to build a generic signature that captures any outer
5880-
// generic parameters. This ensures that we keep e.g. generic superclass
5881-
// existentials contained in a well-formed generic context.
58825870
auto canParentSig = parentSig.getCanonicalSignature();
58835871
auto key = std::make_pair(constraint, canParentSig.getPointer());
58845872
auto found = getImpl().ExistentialSignatures.find(key);

lib/Demangling/OldRemangler.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ bool Remangler::trySubstitution(Node *node, SubstitutionEntry &entry) {
242242
return true;
243243

244244
// Go ahead and initialize the substitution entry.
245-
entry.setNode(node, /*treatAsIdentifier=*/ false);
245+
entry = entryForNode(node);
246246

247247
int Idx = findSubstitution(entry);
248248
if (Idx < 0)

lib/Demangling/Remangler.cpp

+86-18
Original file line numberDiff line numberDiff line change
@@ -59,47 +59,115 @@ bool SubstitutionEntry::identifierEquals(Node *lhs, Node *rhs) {
5959
return true;
6060
}
6161

62-
void SubstitutionEntry::deepHash(Node *node) {
62+
bool SubstitutionEntry::deepEquals(Node *lhs, Node *rhs) const {
63+
if (!lhs->isSimilarTo(rhs))
64+
return false;
65+
66+
for (auto li = lhs->begin(), ri = rhs->begin(), le = lhs->end();
67+
li != le; ++li, ++ri) {
68+
if (!deepEquals(*li, *ri))
69+
return false;
70+
}
71+
72+
return true;
73+
}
74+
75+
static inline size_t combineHash(size_t currentHash, size_t newValue) {
76+
return 33 * currentHash + newValue;
77+
}
78+
79+
/// Calculate the hash for a node.
80+
size_t RemanglerBase::hashForNode(Node *node,
81+
bool treatAsIdentifier) {
82+
size_t hash = 0;
83+
6384
if (treatAsIdentifier) {
64-
combineHash((size_t) Node::Kind::Identifier);
85+
hash = combineHash(hash, (size_t)Node::Kind::Identifier);
6586
assert(node->hasText());
6687
switch (node->getKind()) {
6788
case Node::Kind::InfixOperator:
6889
case Node::Kind::PrefixOperator:
6990
case Node::Kind::PostfixOperator:
7091
for (char c : node->getText()) {
71-
combineHash((unsigned char)translateOperatorChar(c));
92+
hash = combineHash(hash, (unsigned char)translateOperatorChar(c));
7293
}
73-
return;
94+
return hash;
7495
default:
7596
break;
7697
}
7798
} else {
78-
combineHash((size_t) node->getKind());
99+
hash = combineHash(hash, (size_t) node->getKind());
79100
}
80101
if (node->hasIndex()) {
81-
combineHash(node->getIndex());
102+
hash = combineHash(hash, node->getIndex());
82103
} else if (node->hasText()) {
83104
for (char c : node->getText()) {
84-
combineHash((unsigned char) c);
105+
hash = combineHash(hash, (unsigned char) c);
85106
}
86107
}
87108
for (Node *child : *node) {
88-
deepHash(child);
109+
SubstitutionEntry entry = entryForNode(child, treatAsIdentifier);
110+
hash = combineHash(hash, entry.hash());
89111
}
112+
113+
return hash;
90114
}
91115

92-
bool SubstitutionEntry::deepEquals(Node *lhs, Node *rhs) const {
93-
if (!lhs->isSimilarTo(rhs))
94-
return false;
116+
/// Rotate a size_t by N bits
117+
static inline size_t rotate(size_t value, size_t shift) {
118+
const size_t bits = sizeof(size_t) * 8;
119+
return (value >> shift) | (value << (bits - shift));
120+
}
95121

96-
for (auto li = lhs->begin(), ri = rhs->begin(), le = lhs->end();
97-
li != le; ++li, ++ri) {
98-
if (!deepEquals(*li, *ri))
99-
return false;
122+
/// Compute a hash value from a node *pointer*.
123+
/// Used for look-ups in HashHash. The numbers in here were determined
124+
/// experimentally.
125+
static inline size_t nodeHash(Node *node) {
126+
// Multiply by a magic number
127+
const size_t nodePrime = ((size_t)node) * 2043;
128+
129+
// We rotate by a different amount because the alignment of Node
130+
// changes depending on the machine's pointer size
131+
switch (sizeof(size_t)) {
132+
case 4:
133+
return rotate(nodePrime, 11);
134+
case 8:
135+
return rotate(nodePrime, 12);
136+
case 16:
137+
return rotate(nodePrime, 13);
138+
default:
139+
return rotate(nodePrime, 12);
100140
}
101-
102-
return true;
141+
}
142+
143+
/// Construct a SubstitutionEntry for a given node.
144+
/// This will look in the HashHash to see if we already know the hash
145+
/// (which avoids recursive hashing on the Node tree).
146+
SubstitutionEntry RemanglerBase::entryForNode(Node *node,
147+
bool treatAsIdentifier) {
148+
const size_t ident = treatAsIdentifier ? 4 : 0;
149+
const size_t hash = nodeHash(node) + ident;
150+
151+
// Use linear probing with a limit
152+
for (size_t n = 0; n < HashHashMaxProbes; ++n) {
153+
const size_t ndx = (hash + n) & (HashHashCapacity - 1);
154+
SubstitutionEntry entry = HashHash[ndx];
155+
156+
if (entry.isEmpty()) {
157+
size_t entryHash = hashForNode(node, treatAsIdentifier);
158+
entry.setNode(node, treatAsIdentifier, entryHash);
159+
HashHash[ndx] = entry;
160+
return entry;
161+
} else if (entry.matches(node, treatAsIdentifier)) {
162+
return entry;
163+
}
164+
}
165+
166+
// Hash table is full at this hash value
167+
SubstitutionEntry entry;
168+
size_t entryHash = hashForNode(node, treatAsIdentifier);
169+
entry.setNode(node, treatAsIdentifier, entryHash);
170+
return entry;
103171
}
104172

105173
// Find a substitution and return its index.
@@ -340,7 +408,7 @@ bool Remangler::trySubstitution(Node *node, SubstitutionEntry &entry,
340408
return true;
341409

342410
// Go ahead and initialize the substitution entry.
343-
entry.setNode(node, treatAsIdentifier);
411+
entry = entryForNode(node, treatAsIdentifier);
344412

345413
int Idx = findSubstitution(entry);
346414
if (Idx < 0)

lib/Demangling/RemanglerBase.h

+27-9
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ class SubstitutionEntry {
4242
bool treatAsIdentifier = false;
4343

4444
public:
45-
void setNode(Node *node, bool treatAsIdentifier) {
45+
void setNode(Node *node, bool treatAsIdentifier, size_t hash) {
4646
this->treatAsIdentifier = treatAsIdentifier;
4747
TheNode = node;
48-
deepHash(node);
48+
StoredHash = hash;
4949
}
5050

5151
struct Hasher {
@@ -54,6 +54,14 @@ class SubstitutionEntry {
5454
}
5555
};
5656

57+
bool isEmpty() const { return !TheNode; }
58+
59+
bool matches(Node *node, bool treatAsIdentifier) const {
60+
return node == TheNode && treatAsIdentifier == this->treatAsIdentifier;
61+
}
62+
63+
size_t hash() const { return StoredHash; }
64+
5765
private:
5866
friend bool operator==(const SubstitutionEntry &lhs,
5967
const SubstitutionEntry &rhs) {
@@ -69,12 +77,6 @@ class SubstitutionEntry {
6977

7078
static bool identifierEquals(Node *lhs, Node *rhs);
7179

72-
void combineHash(size_t newValue) {
73-
StoredHash = 33 * StoredHash + newValue;
74-
}
75-
76-
void deepHash(Node *node);
77-
7880
bool deepEquals(Node *lhs, Node *rhs) const;
7981
};
8082

@@ -131,6 +133,13 @@ class RemanglerBase {
131133
// Used to allocate temporary nodes and the output string (in Buffer).
132134
NodeFactory &Factory;
133135

136+
// Recursively calculating the node hashes can be expensive if the node tree
137+
// is deep, so we keep a hash table mapping (Node *, treatAsIdentifier) pairs
138+
// to hashes.
139+
static const size_t HashHashCapacity = 512; // Must be a power of 2
140+
static const size_t HashHashMaxProbes = 8;
141+
SubstitutionEntry HashHash[HashHashCapacity] = {};
142+
134143
// An efficient hash-map implementation in the spirit of llvm's SmallPtrSet:
135144
// The first 16 substitutions are stored in an inline-allocated array to avoid
136145
// malloc calls in the common case.
@@ -148,7 +157,16 @@ class RemanglerBase {
148157
RemanglerBuffer Buffer;
149158

150159
protected:
151-
RemanglerBase(NodeFactory &Factory) : Factory(Factory), Buffer(Factory) { }
160+
RemanglerBase(NodeFactory &Factory)
161+
: Factory(Factory), Buffer(Factory) { }
162+
163+
/// Compute the hash for a node.
164+
size_t hashForNode(Node *node, bool treatAsIdentifier = false);
165+
166+
/// Construct a SubstitutionEntry for a given node.
167+
/// This will look in the HashHash to see if we already know the hash,
168+
/// to avoid having to walk the entire subtree.
169+
SubstitutionEntry entryForNode(Node *node, bool treatAsIdentifier = false);
152170

153171
/// Find a substitution and return its index.
154172
/// Returns -1 if no substitution is found.

0 commit comments

Comments
 (0)