Skip to content

Commit 4303388

Browse files
authored
Merge pull request #3720 from swiftwasm/main
2 parents 99c1b86 + 8504265 commit 4303388

Some content is hidden

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

57 files changed

+1234
-447
lines changed

docs/ReferenceGuides/UnderscoredAttributes.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,22 @@ override.
376376
This attribute and the corresponding `-warn-implicit-overrides` flag are
377377
used when compiling the standard library and overlays.
378378

379+
## `@_nonSendable`
380+
381+
There is no clang attribute to add a Swift conformance to an imported type, but
382+
there *is* a clang attribute to add a Swift attribute to an imported type. So
383+
`@Sendable` (which is not normally allowed on types) is used from clang headers
384+
to indicate that an unconstrained, fully available `Sendable` conformance should
385+
be added to a given type, while `@_nonSendable` indicates that an unavailable
386+
`Sendable` conformance should be added to it.
387+
388+
`@_nonSendable` can have no options after it, in which case it "beats"
389+
`@Sendable` if both are applied to the same declaration, or it can have
390+
`(_assumed)` after it, in which case `@Sendable` "beats" it.
391+
`@_nonSendable(_assumed)` is intended to be used when mass-marking whole regions
392+
of a header as non-`Sendable` so that you can make spot exceptions with
393+
`@Sendable`.
394+
379395
## `@_objc_non_lazy_realization`
380396

381397
Marks a class as being non-lazily (i.e. eagerly) [realized](/docs/Lexicon.md#realization).

include/swift/AST/Attr.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,13 @@ SIMPLE_DECL_ATTR(_assemblyVision, EmitAssemblyVisionRemarks,
665665
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
666666
120)
667667

668+
DECL_ATTR(_nonSendable, NonSendable,
669+
OnNominalType |
670+
UserInaccessible | AllowMultipleAttributes |
671+
ABIStableToAdd | ABIBreakingToRemove |
672+
APIStableToAdd | APIBreakingToRemove,
673+
121)
674+
668675
// If you're adding a new underscored attribute here, please document it in
669676
// docs/ReferenceGuides/UnderscoredAttributes.md.
670677

include/swift/AST/Attr.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2030,6 +2030,37 @@ class TransposeAttr final
20302030
}
20312031
};
20322032

2033+
enum class NonSendableKind : uint8_t {
2034+
/// A plain '@_nonSendable' attribute. Should be applied directly to
2035+
/// particular declarations; overrides even an explicit 'Sendable'
2036+
/// conformance.
2037+
Specific,
2038+
2039+
/// A '@_nonSendable(_assumed)' attribute. Should be applied to large swaths
2040+
/// of declarations; does not override explicit 'Sendable' conformances.
2041+
Assumed
2042+
};
2043+
2044+
/// Marks a declaration as explicitly non-Sendable.
2045+
class NonSendableAttr : public DeclAttribute {
2046+
public:
2047+
NonSendableAttr(SourceLoc AtLoc, SourceRange Range,
2048+
NonSendableKind Specificity, bool Implicit = false)
2049+
: DeclAttribute(DAK_NonSendable, AtLoc, Range, Implicit),
2050+
Specificity(Specificity)
2051+
{}
2052+
2053+
NonSendableAttr(NonSendableKind Specificity, bool Implicit = false)
2054+
: NonSendableAttr(SourceLoc(), SourceRange(), Specificity, Implicit) {}
2055+
2056+
/// Was this '@_nonSendable(_assumed)'?
2057+
const NonSendableKind Specificity;
2058+
2059+
static bool classof(const DeclAttribute *DA) {
2060+
return DA->getKind() == DAK_NonSendable;
2061+
}
2062+
};
2063+
20332064
/// Attributes that may be applied to declarations.
20342065
class DeclAttributes {
20352066
/// Linked list of declaration attributes.

include/swift/AST/Decl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,6 +1284,8 @@ class ExtensionDecl final : public GenericContext, public Decl,
12841284
SourceLoc getStartLoc() const { return ExtensionLoc; }
12851285
SourceLoc getLocFromSource() const { return ExtensionLoc; }
12861286
SourceRange getSourceRange() const {
1287+
if (!Braces.isValid())
1288+
return SourceRange(ExtensionLoc);
12871289
return { ExtensionLoc, Braces.End };
12881290
}
12891291

include/swift/AST/DiagnosticsParse.def

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,10 +1604,6 @@ ERROR(opened_attribute_id_value,none,
16041604
ERROR(opened_attribute_expected_rparen,none,
16051605
"expected ')' after id value for 'opened' attribute", ())
16061606

1607-
// effects
1608-
ERROR(effects_attribute_expect_option,none,
1609-
"expected '%0' option (readnone, readonly, readwrite)", (StringRef))
1610-
16111607
// unowned
16121608
ERROR(attr_unowned_invalid_specifier,none,
16131609
"expected 'safe' or 'unsafe'", ())

include/swift/AST/SILOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ class SILOptions {
4444
/// Remove all runtime assertions during optimizations.
4545
bool RemoveRuntimeAsserts = false;
4646

47+
/// Enable experimental support for emitting defined borrow scopes.
48+
bool EnableExperimentalLexicalLifetimes = false;
49+
4750
/// Force-run SIL copy propagation to shorten object lifetime in whatever
4851
/// optimization pipeline is currently used.
4952
/// When this is 'false' the pipeline has default behavior.

include/swift/AST/SynthesizedFileUnit.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class SynthesizedFileUnit final : public FileUnit {
2828
SourceFile &SF;
2929

3030
/// Synthesized top level declarations.
31-
TinyPtrVector<ValueDecl *> TopLevelDecls;
31+
TinyPtrVector<Decl *> TopLevelDecls;
3232

3333
/// A unique identifier representing this file; used to mark private decls
3434
/// within the file to keep them from conflicting with other files in the
@@ -43,7 +43,7 @@ class SynthesizedFileUnit final : public FileUnit {
4343
SourceFile &getSourceFile() const { return SF; }
4444

4545
/// Add a synthesized top-level declaration.
46-
void addTopLevelDecl(ValueDecl *D) { TopLevelDecls.push_back(D); }
46+
void addTopLevelDecl(Decl *D) { TopLevelDecls.push_back(D); }
4747

4848
virtual void lookupValue(DeclName name, NLKind lookupKind,
4949
SmallVectorImpl<ValueDecl *> &result) const override;
@@ -56,7 +56,7 @@ class SynthesizedFileUnit final : public FileUnit {
5656

5757
void getTopLevelDecls(SmallVectorImpl<Decl*> &results) const override;
5858

59-
ArrayRef<ValueDecl *> getTopLevelDecls() const {
59+
ArrayRef<Decl *> getTopLevelDecls() const {
6060
return TopLevelDecls;
6161
};
6262

include/swift/Basic/LangOptions.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,6 @@ namespace swift {
303303
/// Enable experimental concurrency model.
304304
bool EnableExperimentalConcurrency = false;
305305

306-
/// Enable experimental support for emitting defined borrow scopes.
307-
bool EnableExperimentalLexicalLifetimes = false;
308-
309306
/// Enable experimental support for named opaque result types, e.g.
310307
/// `func f() -> <T> T`.
311308
bool EnableExperimentalNamedOpaqueTypes = false;

include/swift/SILOptimizer/Utils/OwnershipOptUtils.h

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/Basic/Defer.h"
2323
#include "swift/SIL/BasicBlockUtils.h"
2424
#include "swift/SIL/OwnershipUtils.h"
25+
#include "swift/SIL/PrunedLiveness.h"
2526
#include "swift/SIL/SILModule.h"
2627
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
2728

@@ -34,6 +35,31 @@ inline bool requiresOSSACleanup(SILValue v) {
3435
&& v.getOwnershipKind() != OwnershipKind::Unowned;
3536
}
3637

38+
/// Rewrite the lifetime of \p ownedValue to match \p lifetimeBoundary. This may
39+
/// insert copies at forwarding consumes, including phis.
40+
///
41+
/// Precondition: lifetimeBoundary is dominated by ownedValue.
42+
///
43+
/// Precondition: lifetimeBoundary is a superset of ownedValue's current
44+
/// lifetime (therefore, none of the safety checks done during
45+
/// CanonicalizeOSSALifetime are needed here).
46+
void extendOwnedLifetime(SILValue ownedValue,
47+
PrunedLivenessBoundary &lifetimeBoundary,
48+
InstructionDeleter &deleter);
49+
50+
/// Rewrite the local borrow scope introduced by \p beginBorrow to match \p
51+
/// guaranteedBoundary.
52+
///
53+
/// Precondition: guaranteedBoundary is dominated by beginBorrow which has no
54+
/// reborrows.
55+
///
56+
/// Precondition: guaranteedBoundary is a superset of beginBorrow's current
57+
/// scope (therefore, none of the safety checks done during
58+
/// CanonicalizeBorrowScope are needed here).
59+
void extendLocalBorrow(BeginBorrowInst *beginBorrow,
60+
PrunedLivenessBoundary &guaranteedBoundary,
61+
InstructionDeleter &deleter);
62+
3763
/// Given a new phi that may use a guaranteed value, create nested borrow scopes
3864
/// for its incoming operands and end_borrows that cover the phi's extended
3965
/// borrow scope, which transitively includes any phis that use this phi.
@@ -47,6 +73,73 @@ inline bool requiresOSSACleanup(SILValue v) {
4773
/// newly created phis do not yet have a borrow scope.
4874
bool createBorrowScopeForPhiOperands(SILPhiArgument *newPhi);
4975

76+
//===----------------------------------------------------------------------===//
77+
// GuaranteedOwnershipExtension
78+
//===----------------------------------------------------------------------===//
79+
80+
/// Extend existing guaranteed ownership to cover new guaranteeed uses that are
81+
/// dominated by the borrow introducer.
82+
class GuaranteedOwnershipExtension {
83+
// --- context
84+
InstructionDeleter &deleter;
85+
DeadEndBlocks &deBlocks;
86+
87+
// --- analysis state
88+
PrunedLiveness guaranteedLiveness;
89+
PrunedLiveness ownedLifetime;
90+
SmallVector<SILBasicBlock *, 4> ownedConsumeBlocks;
91+
BeginBorrowInst *beginBorrow = nullptr;
92+
93+
public:
94+
GuaranteedOwnershipExtension(InstructionDeleter &deleter,
95+
DeadEndBlocks &deBlocks)
96+
: deleter(deleter), deBlocks(deBlocks) {}
97+
98+
void clear() {
99+
guaranteedLiveness.clear();
100+
ownedLifetime.clear();
101+
ownedConsumeBlocks.clear();
102+
beginBorrow = nullptr;
103+
}
104+
105+
/// Invalid indicates that the current guaranteed scope is insufficient, and
106+
/// it does not meet the precondition for scope extension.
107+
///
108+
/// Valid indicates that the current guaranteed scope is sufficient with no
109+
/// transformation required.
110+
///
111+
/// ExtendBorrow indicates that the local borrow scope can be extended without
112+
/// affecting the owned lifetime or introducing copies.
113+
///
114+
/// ExtendLifetime indicates that the owned lifetime can be extended possibly
115+
/// requiring additional copies.
116+
enum Status { Invalid, Valid, ExtendBorrow, ExtendLifetime };
117+
118+
/// Can the OSSA ownership of the \p parentAddress cover all uses of the \p
119+
/// childAddress?
120+
///
121+
/// Precondition: \p parentAddress dominates \p childAddress
122+
Status checkAddressOwnership(SILValue parentAddress, SILValue childAddress);
123+
124+
/// Can the OSSA scope of \p borrow cover all \p newUses?
125+
///
126+
/// Precondition: \p borrow dominates \p newUses
127+
Status checkBorrowExtension(BorrowedValue borrow,
128+
ArrayRef<Operand *> newUses);
129+
130+
/// Can the OSSA scope of \p ownedValue cover all the guaranteed \p newUses?
131+
///
132+
/// Precondition: \p ownedValue dominates \p newUses
133+
Status checkLifetimeExtension(SILValue ownedValue,
134+
ArrayRef<Operand *> newUses);
135+
136+
void transform(Status status);
137+
};
138+
139+
//===----------------------------------------------------------------------===//
140+
// RAUW - Replace All Uses With...
141+
//===----------------------------------------------------------------------===//
142+
50143
/// A struct that contains context shared in between different operation +
51144
/// "ownership fixup" utilities. Please do not put actual methods on this, it is
52145
/// meant to be composed with.

lib/AST/ASTPrinter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,8 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
263263
DAK_SetterAccess,
264264
DAK_Lazy,
265265
DAK_StaticInitializeObjCMetadata,
266-
DAK_RestatedObjCConformance
266+
DAK_RestatedObjCConformance,
267+
DAK_NonSendable,
267268
};
268269

269270
return result;

lib/AST/Attr.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,7 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
874874
case DAK_ReferenceOwnership:
875875
case DAK_Effects:
876876
case DAK_Optimize:
877+
case DAK_NonSendable:
877878
if (DeclAttribute::isDeclModifier(getKind())) {
878879
Printer.printKeyword(getAttrName(), Options);
879880
} else if (Options.IsForSwiftInterface && getKind() == DAK_ResultBuilder) {
@@ -1226,6 +1227,15 @@ StringRef DeclAttribute::getAttrName() const {
12261227
}
12271228
llvm_unreachable("Invalid inline kind");
12281229
}
1230+
case DAK_NonSendable: {
1231+
switch (cast<NonSendableAttr>(this)->Specificity) {
1232+
case NonSendableKind::Specific:
1233+
return "_nonSendable";
1234+
case NonSendableKind::Assumed:
1235+
return "_nonSendable(_assumed)";
1236+
}
1237+
llvm_unreachable("Invalid nonSendable kind");
1238+
}
12291239
case DAK_Optimize: {
12301240
switch (cast<OptimizeAttr>(this)->getMode()) {
12311241
case OptimizationMode::NoOptimization:

lib/AST/Module.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2996,8 +2996,11 @@ void SynthesizedFileUnit::lookupValue(
29962996
DeclName name, NLKind lookupKind,
29972997
SmallVectorImpl<ValueDecl *> &result) const {
29982998
for (auto *decl : TopLevelDecls) {
2999-
if (decl->getName().matchesRef(name))
3000-
result.push_back(decl);
2999+
if (auto VD = dyn_cast<ValueDecl>(decl)) {
3000+
if (VD->getName().matchesRef(name)) {
3001+
result.push_back(VD);
3002+
}
3003+
}
30013004
}
30023005
}
30033006

0 commit comments

Comments
 (0)