Skip to content

Commit e9a268a

Browse files
authored
Merge pull request #3504 from swiftwasm/main
[pull] swiftwasm from main
2 parents 41a1b9c + 7cab446 commit e9a268a

File tree

17 files changed

+147
-61
lines changed

17 files changed

+147
-61
lines changed

include/swift/AST/ASTMangler.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ class ASTMangler : public Mangler {
5656
/// to fill these in.
5757
bool AllowSymbolicReferences = false;
5858

59+
/// If enabled, allows the use of standard substitutions for types in the
60+
/// concurrency library.
61+
bool AllowConcurrencyStandardSubstitutions = true;
62+
5963
public:
6064
using SymbolicReferent = llvm::PointerUnion<const NominalTypeDecl *,
6165
const OpaqueTypeDecl *>;

include/swift/Demangling/ManglingUtils.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,12 @@ char translateOperatorChar(char op);
9999
std::string translateOperator(StringRef Op);
100100

101101
/// Returns the standard type kind for an 'S' substitution, e.g. 'i' for "Int".
102-
llvm::Optional<StringRef> getStandardTypeSubst(StringRef TypeName);
102+
///
103+
/// \param allowConcurrencyManglings When true, allows the standard
104+
/// substitutions for types in the _Concurrency module that were introduced in
105+
/// Swift 5.5.
106+
llvm::Optional<StringRef> getStandardTypeSubst(
107+
StringRef TypeName, bool allowConcurrencyManglings);
103108

104109
/// Mangles an identifier using a generic Mangler class.
105110
///

include/swift/Demangling/StandardTypesMangling.def

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
/// STANDARD_TYPE(KIND, MANGLING, TYPENAME)
1414
/// The 1-character MANGLING for a known TYPENAME of KIND.
1515
///
16-
/// STANDARD_TYPE_2(KIND, MANGLING, TYPENAME)
16+
/// STANDARD_TYPE_CONCURRENCY(KIND, MANGLING, TYPENAME)
1717
/// The 1-character MANGLING for a known TYPENAME of KIND that is in the
18-
/// second level of standard types, all of which are mangled with the form
19-
/// Sc<MANGLING>.
18+
/// second level of standard types in the Concurrency model, all of which are
19+
/// mangled with the form Sc<MANGLING>.
2020
///
2121
/// OBJC_INTEROP_STANDARD_TYPE(KIND, MANGLING, TYPENAME)
2222
/// The 1-character MANGLING for a known TYPENAME of KIND, for a type that's
@@ -79,25 +79,25 @@ STANDARD_TYPE(Protocol, y, StringProtocol)
7979
STANDARD_TYPE(Protocol, Z, SignedInteger)
8080
STANDARD_TYPE(Protocol, z, BinaryInteger)
8181

82-
STANDARD_TYPE_2(Protocol, A, Actor)
83-
STANDARD_TYPE_2(Structure, C, CheckedContinuation)
84-
STANDARD_TYPE_2(Structure, c, UnsafeContinuation)
85-
STANDARD_TYPE_2(Structure, E, CancellationError)
86-
STANDARD_TYPE_2(Structure, e, UnownedSerialExecutor)
87-
STANDARD_TYPE_2(Protocol, F, Executor)
88-
STANDARD_TYPE_2(Protocol, f, SerialExecutor)
89-
STANDARD_TYPE_2(Structure, G, TaskGroup)
90-
STANDARD_TYPE_2(Structure, g, ThrowingTaskGroup)
91-
STANDARD_TYPE_2(Protocol, I, AsyncIteratorProtocol)
92-
STANDARD_TYPE_2(Protocol, i, AsyncSequence)
93-
STANDARD_TYPE_2(Structure, J, UnownedJob)
94-
STANDARD_TYPE_2(Class, M, MainActor)
95-
STANDARD_TYPE_2(Structure, P, TaskPriority)
96-
STANDARD_TYPE_2(Structure, S, AsyncStream)
97-
STANDARD_TYPE_2(Structure, s, AsyncThrowingStream)
98-
STANDARD_TYPE_2(Structure, T, Task)
99-
STANDARD_TYPE_2(Structure, t, UnsafeCurrentTask)
82+
STANDARD_TYPE_CONCURRENCY(Protocol, A, Actor)
83+
STANDARD_TYPE_CONCURRENCY(Structure, C, CheckedContinuation)
84+
STANDARD_TYPE_CONCURRENCY(Structure, c, UnsafeContinuation)
85+
STANDARD_TYPE_CONCURRENCY(Structure, E, CancellationError)
86+
STANDARD_TYPE_CONCURRENCY(Structure, e, UnownedSerialExecutor)
87+
STANDARD_TYPE_CONCURRENCY(Protocol, F, Executor)
88+
STANDARD_TYPE_CONCURRENCY(Protocol, f, SerialExecutor)
89+
STANDARD_TYPE_CONCURRENCY(Structure, G, TaskGroup)
90+
STANDARD_TYPE_CONCURRENCY(Structure, g, ThrowingTaskGroup)
91+
STANDARD_TYPE_CONCURRENCY(Protocol, I, AsyncIteratorProtocol)
92+
STANDARD_TYPE_CONCURRENCY(Protocol, i, AsyncSequence)
93+
STANDARD_TYPE_CONCURRENCY(Structure, J, UnownedJob)
94+
STANDARD_TYPE_CONCURRENCY(Class, M, MainActor)
95+
STANDARD_TYPE_CONCURRENCY(Structure, P, TaskPriority)
96+
STANDARD_TYPE_CONCURRENCY(Structure, S, AsyncStream)
97+
STANDARD_TYPE_CONCURRENCY(Structure, s, AsyncThrowingStream)
98+
STANDARD_TYPE_CONCURRENCY(Structure, T, Task)
99+
STANDARD_TYPE_CONCURRENCY(Structure, t, UnsafeCurrentTask)
100100

101101
#undef STANDARD_TYPE
102102
#undef OBJC_INTEROP_STANDARD_TYPE
103-
#undef STANDARD_TYPE_2
103+
#undef STANDARD_TYPE_CONCURRENCY

include/swift/SIL/MemAccessUtils.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ SILValue getAccessBase(SILValue address);
171171
/// AccessedStorage::getRoot() and AccessPath::getRoot().
172172
SILValue findReferenceRoot(SILValue ref);
173173

174+
/// Find the first owned root of the reference.
175+
SILValue findOwnershipReferenceRoot(SILValue ref);
176+
174177
/// Return true if \p address points to a let-variable.
175178
///
176179
/// let-variables are only written during let-variable initialization, which is
@@ -1264,9 +1267,13 @@ SILBasicBlock::iterator removeBeginAccess(BeginAccessInst *beginAccess);
12641267

12651268
namespace swift {
12661269

1267-
/// Return true if \p svi is a cast that preserves the identity and
1270+
/// Return true if \p svi is a cast that preserves the identity equivalence of
1271+
/// the reference at operand zero.
1272+
bool isIdentityPreservingRefCast(SingleValueInstruction *svi);
1273+
1274+
/// Return true if \p svi is a cast that preserves the identity equivalence and
12681275
/// reference-counting equivalence of the reference at operand zero.
1269-
bool isRCIdentityPreservingCast(SingleValueInstruction *svi);
1276+
bool isIdentityAndOwnershipPreservingRefCast(SingleValueInstruction *svi);
12701277

12711278
/// If \p svi is an access projection, return an address-type operand for the
12721279
/// incoming address.

lib/AST/ASTMangler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2973,7 +2973,8 @@ bool ASTMangler::tryAppendStandardSubstitution(const GenericTypeDecl *decl) {
29732973
return false;
29742974

29752975
if (isa<NominalTypeDecl>(decl)) {
2976-
if (auto Subst = getStandardTypeSubst(decl->getName().str())) {
2976+
if (auto Subst = getStandardTypeSubst(
2977+
decl->getName().str(), AllowConcurrencyStandardSubstitutions)) {
29772978
if (!SubstMerging.tryMergeSubst(*this, *Subst, /*isStandardSubst*/ true)){
29782979
appendOperator("S", *Subst);
29792980
}

lib/Demangling/Demangler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,7 @@ NodePointer Demangler::createStandardSubstitution(
975975
return createSwiftType(Node::Kind::KIND, #TYPENAME); \
976976
}
977977

978-
#define STANDARD_TYPE_2(KIND, MANGLING, TYPENAME) \
978+
#define STANDARD_TYPE_CONCURRENCY(KIND, MANGLING, TYPENAME) \
979979
if (SecondLevel && Subst == #MANGLING[0]) { \
980980
return createSwiftType(Node::Kind::KIND, #TYPENAME); \
981981
}

lib/Demangling/ManglingUtils.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,16 @@ std::string Mangle::translateOperator(StringRef Op) {
6666
return Encoded;
6767
}
6868

69-
llvm::Optional<StringRef> Mangle::getStandardTypeSubst(StringRef TypeName) {
69+
llvm::Optional<StringRef> Mangle::getStandardTypeSubst(
70+
StringRef TypeName, bool allowConcurrencyManglings) {
7071
#define STANDARD_TYPE(KIND, MANGLING, TYPENAME) \
7172
if (TypeName == #TYPENAME) { \
7273
return StringRef(#MANGLING); \
7374
}
7475

75-
#define STANDARD_TYPE_2(KIND, MANGLING, TYPENAME) \
76-
if (TypeName == #TYPENAME) { \
77-
return StringRef("c" #MANGLING); \
76+
#define STANDARD_TYPE_CONCURRENCY(KIND, MANGLING, TYPENAME) \
77+
if (allowConcurrencyManglings && TypeName == #TYPENAME) { \
78+
return StringRef("c" #MANGLING); \
7879
}
7980

8081
#include "swift/Demangling/StandardTypesMangling.def"

lib/Demangling/Remangler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,8 @@ bool Remangler::mangleStandardSubstitution(Node *node) {
397397
if (node->getChild(1)->getKind() != Node::Kind::Identifier)
398398
return false;
399399

400-
if (auto Subst = getStandardTypeSubst(node->getChild(1)->getText())) {
400+
if (auto Subst = getStandardTypeSubst(
401+
node->getChild(1)->getText(), /*allowConcurrencyManglings=*/true)) {
401402
if (!SubstMerging.tryMergeSubst(*this, *Subst, /*isStandardSubst*/ true)) {
402403
Buffer << 'S' << *Subst;
403404
}

lib/IRGen/IRGenMangler.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "swift/AST/IRGenOptions.h"
1717
#include "swift/AST/ProtocolAssociations.h"
1818
#include "swift/AST/ProtocolConformance.h"
19+
#include "swift/Basic/Platform.h"
1920
#include "swift/Demangling/ManglingMacros.h"
2021
#include "swift/Demangling/Demangle.h"
2122
#include "swift/ABI/MetadataValues.h"
@@ -98,7 +99,8 @@ IRGenMangler::withSymbolicReferences(IRGenModule &IGM,
9899
// manglings already, and the runtime ought to have a lookup table for
99100
// them. Symbolic referencing would be wasteful.
100101
if (type->getModuleContext()->hasStandardSubstitutions()
101-
&& Mangle::getStandardTypeSubst(type->getName().str())) {
102+
&& Mangle::getStandardTypeSubst(
103+
type->getName().str(), AllowConcurrencyStandardSubstitutions)) {
102104
return false;
103105
}
104106

@@ -146,6 +148,17 @@ SymbolicMangling
146148
IRGenMangler::mangleTypeForReflection(IRGenModule &IGM,
147149
CanGenericSignature Sig,
148150
CanType Ty) {
151+
// If our target predates Swift 5.5, we cannot apply the standard
152+
// substitutions for types defined in the Concurrency module.
153+
ASTContext &ctx = Ty->getASTContext();
154+
llvm::SaveAndRestore<bool> savedConcurrencyStandardSubstitutions(
155+
AllowConcurrencyStandardSubstitutions);
156+
if (auto runtimeCompatVersion = getSwiftRuntimeCompatibilityVersionForTarget(
157+
ctx.LangOpts.Target)) {
158+
if (*runtimeCompatVersion < llvm::VersionTuple(5, 5))
159+
AllowConcurrencyStandardSubstitutions = false;
160+
}
161+
149162
return withSymbolicReferences(IGM, [&]{
150163
appendType(Ty, Sig);
151164
});

lib/SIL/Utils/InstructionUtils.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,9 @@ SILValue swift::stripCastsWithoutMarkDependence(SILValue v) {
125125
return v;
126126

127127
if (auto *svi = dyn_cast<SingleValueInstruction>(v)) {
128-
if (isRCIdentityPreservingCast(svi)
129-
|| isa<UncheckedTrivialBitCastInst>(v)
130-
|| isa<BeginAccessInst>(v)
131-
|| isa<EndCOWMutationInst>(v)) {
128+
if (isIdentityPreservingRefCast(svi) ||
129+
isa<UncheckedTrivialBitCastInst>(v) || isa<BeginAccessInst>(v) ||
130+
isa<EndCOWMutationInst>(v)) {
132131
v = svi->getOperand(0);
133132
continue;
134133
}
@@ -141,10 +140,9 @@ SILValue swift::stripCasts(SILValue v) {
141140
while (true) {
142141
v = stripSinglePredecessorArgs(v);
143142
if (auto *svi = dyn_cast<SingleValueInstruction>(v)) {
144-
if (isRCIdentityPreservingCast(svi)
145-
|| isa<UncheckedTrivialBitCastInst>(v)
146-
|| isa<MarkDependenceInst>(v)
147-
|| isa<BeginAccessInst>(v)) {
143+
if (isIdentityPreservingRefCast(svi) ||
144+
isa<UncheckedTrivialBitCastInst>(v) || isa<MarkDependenceInst>(v) ||
145+
isa<BeginAccessInst>(v)) {
148146
v = cast<SingleValueInstruction>(v)->getOperand(0);
149147
continue;
150148
}

lib/SIL/Utils/MemAccessUtils.cpp

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,12 @@ bool swift::isLetAddress(SILValue address) {
365365
// MARK: FindReferenceRoot
366366
//===----------------------------------------------------------------------===//
367367

368+
bool swift::isIdentityPreservingRefCast(SingleValueInstruction *svi) {
369+
// Ignore both copies and other identity and ownership preserving casts
370+
return isa<CopyValueInst>(svi) ||
371+
isIdentityAndOwnershipPreservingRefCast(svi);
372+
}
373+
368374
// On some platforms, casting from a metatype to a reference type dynamically
369375
// allocates a ref-counted box for the metatype. Naturally that is the place
370376
// where RC-identity begins. Considering the source of such a casts to be
@@ -374,12 +380,12 @@ bool swift::isLetAddress(SILValue address) {
374380
// The SILVerifier checks that none of these operations cast a trivial value to
375381
// a reference except unconditional_checked_cast[_value], which is checked By
376382
// SILDynamicCastInst::isRCIdentityPreserving().
377-
bool swift::isRCIdentityPreservingCast(SingleValueInstruction *svi) {
383+
bool swift::isIdentityAndOwnershipPreservingRefCast(
384+
SingleValueInstruction *svi) {
378385
switch (svi->getKind()) {
379386
default:
380387
return false;
381-
// Ignore ownership casts
382-
case SILInstructionKind::CopyValueInst:
388+
// Ignore borrows
383389
case SILInstructionKind::BeginBorrowInst:
384390
// Ignore class type casts
385391
case SILInstructionKind::UpcastInst:
@@ -402,8 +408,12 @@ namespace {
402408
// Essentially RC identity where the starting point is already a reference.
403409
class FindReferenceRoot {
404410
SmallPtrSet<SILPhiArgument *, 4> visitedPhis;
411+
bool preserveOwnership;
405412

406413
public:
414+
FindReferenceRoot(bool preserveOwnership)
415+
: preserveOwnership(preserveOwnership) {}
416+
407417
SILValue findRoot(SILValue ref) && {
408418
SILValue root = recursiveFindRoot(ref);
409419
assert(root && "all phi inputs must be reachable");
@@ -414,8 +424,15 @@ class FindReferenceRoot {
414424
// Return an invalid value for a phi with no resolved inputs.
415425
SILValue recursiveFindRoot(SILValue ref) {
416426
while (auto *svi = dyn_cast<SingleValueInstruction>(ref)) {
417-
if (!isRCIdentityPreservingCast(svi)) {
418-
break;
427+
// If preserveOwnership is true, stop at the first owned root
428+
if (preserveOwnership) {
429+
if (!isIdentityAndOwnershipPreservingRefCast(svi)) {
430+
break;
431+
}
432+
} else {
433+
if (!isIdentityPreservingRefCast(svi)) {
434+
break;
435+
}
419436
}
420437
ref = svi->getOperand(0);
421438
};
@@ -451,7 +468,11 @@ class FindReferenceRoot {
451468
} // end anonymous namespace
452469

453470
SILValue swift::findReferenceRoot(SILValue ref) {
454-
return FindReferenceRoot().findRoot(ref);
471+
return FindReferenceRoot(false /*preserveOwnership*/).findRoot(ref);
472+
}
473+
474+
SILValue swift::findOwnershipReferenceRoot(SILValue ref) {
475+
return FindReferenceRoot(true /*preserveOwnership*/).findRoot(ref);
455476
}
456477

457478
//===----------------------------------------------------------------------===//
@@ -1340,7 +1361,7 @@ AccessPathDefUseTraversal::UseKind
13401361
AccessPathDefUseTraversal::visitSingleValueUser(SingleValueInstruction *svi,
13411362
DFSEntry dfs) {
13421363
if (dfs.isRef()) {
1343-
if (isRCIdentityPreservingCast(svi)) {
1364+
if (isIdentityPreservingRefCast(svi)) {
13441365
pushUsers(svi, dfs);
13451366
return IgnoredUse;
13461367
}

lib/SIL/Verifier/LoadBorrowImmutabilityChecker.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,8 @@ LoadBorrowImmutabilityAnalysis::LoadBorrowImmutabilityAnalysis(
292292
// \p address may be an address, pointer, or box type.
293293
bool LoadBorrowImmutabilityAnalysis::isImmutableInScope(
294294
LoadBorrowInst *lbi, ArrayRef<Operand *> endBorrowUses,
295-
AccessPath accessPath) {
296-
295+
AccessPathWithBase accessPathWithBase) {
296+
auto accessPath = accessPathWithBase.accessPath;
297297
LinearLifetimeChecker checker(deadEndBlocks);
298298
auto writes = cache.get(accessPath);
299299

@@ -303,12 +303,21 @@ bool LoadBorrowImmutabilityAnalysis::isImmutableInScope(
303303
accessPath.getStorage().print(llvm::errs());
304304
return false;
305305
}
306+
auto ownershipRoot = accessPath.getStorage().isReference()
307+
? findOwnershipReferenceRoot(accessPathWithBase.base)
308+
: SILValue();
306309
// Then for each write...
307310
for (auto *op : *writes) {
308311
// First see if the write is a dead end block. In such a case, just skip it.
309312
if (deadEndBlocks.isDeadEnd(op->getUser()->getParent())) {
310313
continue;
311314
}
315+
// A destroy_value will be a definite write only when the destroy is on the
316+
// ownershipRoot
317+
if (isa<DestroyValueInst>(op->getUser())) {
318+
if (op->get() != ownershipRoot)
319+
continue;
320+
}
312321
// See if the write is within the load borrow's lifetime. If it isn't, we
313322
// don't have to worry about it.
314323
if (!checker.validateLifetime(lbi, endBorrowUses, op)) {
@@ -326,7 +335,9 @@ bool LoadBorrowImmutabilityAnalysis::isImmutableInScope(
326335
//===----------------------------------------------------------------------===//
327336

328337
bool LoadBorrowImmutabilityAnalysis::isImmutable(LoadBorrowInst *lbi) {
329-
AccessPath accessPath = AccessPath::computeInScope(lbi->getOperand());
338+
auto accessPathWithBase = AccessPathWithBase::compute(lbi->getOperand());
339+
auto accessPath = accessPathWithBase.accessPath;
340+
330341
// Bail on an invalid AccessPath. AccessPath completeness is verified
331342
// independently--it may be invalid in extraordinary situations. When
332343
// AccessPath is valid, we know all its uses are recognizable.
@@ -358,15 +369,15 @@ bool LoadBorrowImmutabilityAnalysis::isImmutable(LoadBorrowInst *lbi) {
358369
//
359370
// TODO: As a separate analysis, verify that the load_borrow scope is always
360371
// nested within the begin_access scope (to ensure no aliasing access).
361-
return isImmutableInScope(lbi, endBorrowUses, accessPath);
372+
return isImmutableInScope(lbi, endBorrowUses, accessPathWithBase);
362373
}
363374
case AccessedStorage::Argument: {
364375
auto *arg =
365376
cast<SILFunctionArgument>(accessPath.getStorage().getArgument());
366377
if (arg->hasConvention(SILArgumentConvention::Indirect_In_Guaranteed)) {
367378
return true;
368379
}
369-
return isImmutableInScope(lbi, endBorrowUses, accessPath);
380+
return isImmutableInScope(lbi, endBorrowUses, accessPathWithBase);
370381
}
371382
// FIXME: A yielded address could overlap with another in this function.
372383
case AccessedStorage::Yield:
@@ -376,7 +387,7 @@ bool LoadBorrowImmutabilityAnalysis::isImmutable(LoadBorrowInst *lbi) {
376387
case AccessedStorage::Tail:
377388
case AccessedStorage::Global:
378389
case AccessedStorage::Unidentified:
379-
return isImmutableInScope(lbi, endBorrowUses, accessPath);
390+
return isImmutableInScope(lbi, endBorrowUses, accessPathWithBase);
380391
}
381392
llvm_unreachable("Covered switch isn't covered?!");
382393
}

lib/SIL/Verifier/VerifierPrivate.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class LoadBorrowImmutabilityAnalysis {
4141
private:
4242
bool isImmutableInScope(LoadBorrowInst *lbi,
4343
ArrayRef<Operand *> endBorrowUses,
44-
AccessPath accessPath);
44+
AccessPathWithBase accessPathWithBase);
4545
};
4646

4747
} // namespace silverifier

stdlib/private/StdlibUnittest/CMakeLists.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ if (SWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY)
1616
list(APPEND swift_stdlib_unittest_link_libraries "swift_Concurrency")
1717
list(APPEND swift_stdlib_unittest_modules "_Concurrency")
1818
endif()
19-
if (SWIFT_ENABLE_EXPERIMENTAL_DISTRIBUTED)
20-
list(APPEND swift_stdlib_unittest_link_libraries "swift_Distributed")
21-
endif()
2219

2320
add_swift_target_library(swiftStdlibUnittest ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB
2421
# This file should be listed the first. Module name is inferred from the

0 commit comments

Comments
 (0)