Skip to content

Commit c97637c

Browse files
authored
Merge pull request swiftlang#35655 from DougGregor/concurrent-function-types-sil
[SIL] Add `@concurrent` function types to SIL
2 parents 8c426fc + 99f8d7a commit c97637c

22 files changed

+132
-45
lines changed

docs/ABI/Mangling.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ mangled in to disambiguate.
625625
impl-function-type ::= type* 'I' FUNC-ATTRIBUTES '_'
626626
impl-function-type ::= type* generic-signature 'I' FUNC-ATTRIBUTES '_'
627627

628-
FUNC-ATTRIBUTES ::= PATTERN-SUBS? INVOCATION-SUBS? PSEUDO-GENERIC? CALLEE-ESCAPE? DIFFERENTIABILITY-KIND? CALLEE-CONVENTION FUNC-REPRESENTATION? COROUTINE-KIND? ASYNC? (PARAM-CONVENTION PARAM-DIFFERENTIABILITY?)* RESULT-CONVENTION* ('Y' PARAM-CONVENTION)* ('z' RESULT-CONVENTION RESULT-DIFFERENTIABILITY?)?
628+
FUNC-ATTRIBUTES ::= PATTERN-SUBS? INVOCATION-SUBS? PSEUDO-GENERIC? CALLEE-ESCAPE? DIFFERENTIABILITY-KIND? CALLEE-CONVENTION FUNC-REPRESENTATION? COROUTINE-KIND? CONCURRENT? ASYNC? (PARAM-CONVENTION PARAM-DIFFERENTIABILITY?)* RESULT-CONVENTION* ('Y' PARAM-CONVENTION)* ('z' RESULT-CONVENTION RESULT-DIFFERENTIABILITY?)?
629629

630630
PATTERN-SUBS ::= 's' // has pattern substitutions
631631
INVOCATION-SUB ::= 'I' // has invocation substitutions
@@ -654,6 +654,7 @@ mangled in to disambiguate.
654654
COROUTINE-KIND ::= 'A' // yield-once coroutine
655655
COROUTINE-KIND ::= 'G' // yield-many coroutine
656656

657+
CONCURRENT ::= 'h' // @concurrent
657658
ASYNC ::= 'H' // @async
658659

659660
PARAM-CONVENTION ::= 'i' // indirect in

include/swift/AST/ExtInfo.h

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -615,17 +615,18 @@ class SILExtInfoBuilder {
615615
// If bits are added or removed, then TypeBase::SILFunctionTypeBits
616616
// and NumMaskBits must be updated, and they must match.
617617

618-
// |representation|pseudogeneric| noescape | async | differentiability|
619-
// | 0 .. 3 | 4 | 5 | 6 | 7 .. 8 |
618+
// |representation|pseudogeneric| noescape | concurrent | async | differentiability|
619+
// | 0 .. 3 | 4 | 5 | 6 | 7 | 8 .. 9 |
620620
//
621621
enum : unsigned {
622622
RepresentationMask = 0xF << 0,
623623
PseudogenericMask = 1 << 4,
624624
NoEscapeMask = 1 << 5,
625-
AsyncMask = 1 << 6,
626-
DifferentiabilityMaskOffset = 7,
625+
ConcurrentMask = 1 << 6,
626+
AsyncMask = 1 << 7,
627+
DifferentiabilityMaskOffset = 8,
627628
DifferentiabilityMask = 0x3 << DifferentiabilityMaskOffset,
628-
NumMaskBits = 9
629+
NumMaskBits = 10
629630
};
630631

631632
unsigned bits; // Naturally sized for speed.
@@ -639,10 +640,13 @@ class SILExtInfoBuilder {
639640
: bits(bits), clangTypeInfo(clangTypeInfo.getCanonical()) {}
640641

641642
static constexpr unsigned makeBits(Representation rep, bool isPseudogeneric,
642-
bool isNoEscape, bool isAsync,
643+
bool isNoEscape, bool isConcurrent,
644+
bool isAsync,
643645
DifferentiabilityKind diffKind) {
644646
return ((unsigned)rep) | (isPseudogeneric ? PseudogenericMask : 0) |
645-
(isNoEscape ? NoEscapeMask : 0) | (isAsync ? AsyncMask : 0) |
647+
(isNoEscape ? NoEscapeMask : 0) |
648+
(isConcurrent ? ConcurrentMask : 0) |
649+
(isAsync ? AsyncMask : 0) |
646650
(((unsigned)diffKind << DifferentiabilityMaskOffset) &
647651
DifferentiabilityMask);
648652
}
@@ -652,21 +656,22 @@ class SILExtInfoBuilder {
652656
/// non-pseudogeneric, non-differentiable.
653657
SILExtInfoBuilder()
654658
: SILExtInfoBuilder(makeBits(SILFunctionTypeRepresentation::Thick, false,
655-
false, false,
659+
false, false, false,
656660
DifferentiabilityKind::NonDifferentiable),
657661
ClangTypeInfo(nullptr)) {}
658662

659663
SILExtInfoBuilder(Representation rep, bool isPseudogeneric, bool isNoEscape,
660-
bool isAsync, DifferentiabilityKind diffKind,
661-
const clang::Type *type)
662-
: SILExtInfoBuilder(makeBits(rep, isPseudogeneric, isNoEscape, isAsync,
663-
diffKind),
664+
bool isConcurrent, bool isAsync,
665+
DifferentiabilityKind diffKind, const clang::Type *type)
666+
: SILExtInfoBuilder(makeBits(rep, isPseudogeneric, isNoEscape,
667+
isConcurrent, isAsync, diffKind),
664668
ClangTypeInfo(type)) {}
665669

666670
// Constructor for polymorphic type.
667671
SILExtInfoBuilder(ASTExtInfoBuilder info, bool isPseudogeneric)
668672
: SILExtInfoBuilder(makeBits(info.getSILRepresentation(), isPseudogeneric,
669-
info.isNoEscape(), info.isAsync(),
673+
info.isNoEscape(), info.isConcurrent(),
674+
info.isAsync(),
670675
info.getDifferentiabilityKind()),
671676
info.getClangTypeInfo()) {}
672677

@@ -691,6 +696,8 @@ class SILExtInfoBuilder {
691696
// Is this function guaranteed to be no-escape by the type system?
692697
constexpr bool isNoEscape() const { return bits & NoEscapeMask; }
693698

699+
constexpr bool isConcurrent() const { return bits & ConcurrentMask; }
700+
694701
constexpr bool isAsync() const { return bits & AsyncMask; }
695702

696703
constexpr DifferentiabilityKind getDifferentiabilityKind() const {
@@ -760,6 +767,12 @@ class SILExtInfoBuilder {
760767
clangTypeInfo);
761768
}
762769
LLVM_NODISCARD
770+
SILExtInfoBuilder withConcurrent(bool isConcurrent = true) const {
771+
return SILExtInfoBuilder(isConcurrent ? (bits | ConcurrentMask)
772+
: (bits & ~ConcurrentMask),
773+
clangTypeInfo);
774+
}
775+
LLVM_NODISCARD
763776
SILExtInfoBuilder withAsync(bool isAsync = true) const {
764777
return SILExtInfoBuilder(isAsync ? (bits | AsyncMask) : (bits & ~AsyncMask),
765778
clangTypeInfo);
@@ -822,7 +835,7 @@ class SILExtInfo {
822835
/// A default ExtInfo but with a Thin convention.
823836
static SILExtInfo getThin() {
824837
return SILExtInfoBuilder(SILExtInfoBuilder::Representation::Thin, false,
825-
false, false,
838+
false, false, false,
826839
DifferentiabilityKind::NonDifferentiable, nullptr)
827840
.build();
828841
}
@@ -846,6 +859,8 @@ class SILExtInfo {
846859

847860
constexpr bool isNoEscape() const { return builder.isNoEscape(); }
848861

862+
constexpr bool isConcurrent() const { return builder.isConcurrent(); }
863+
849864
constexpr bool isAsync() const { return builder.isAsync(); }
850865

851866
constexpr DifferentiabilityKind getDifferentiabilityKind() const {
@@ -874,6 +889,9 @@ class SILExtInfo {
874889
return builder.withNoEscape(noEscape).build();
875890
}
876891

892+
SILExtInfo withConcurrent(bool isConcurrent = true) const {
893+
return builder.withConcurrent(isConcurrent).build();
894+
}
877895

878896
SILExtInfo withAsync(bool isAsync = true) const {
879897
return builder.withAsync(isAsync).build();

include/swift/AST/Types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ class alignas(1 << TypeAlignInBits) TypeBase {
316316

317317
protected:
318318
enum { NumAFTExtInfoBits = 10 };
319-
enum { NumSILExtInfoBits = 9 };
319+
enum { NumSILExtInfoBits = 10 };
320320
union { uint64_t OpaqueBits;
321321

322322
SWIFT_INLINE_BITFIELD_BASE(TypeBase, bitmax(NumTypeKindBits,8) +
@@ -4120,6 +4120,7 @@ class SILFunctionType final
41204120
return SILCoroutineKind(Bits.SILFunctionType.CoroutineKind);
41214121
}
41224122

4123+
bool isConcurrent() const { return getExtInfo().isConcurrent(); }
41234124
bool isAsync() const { return getExtInfo().isAsync(); }
41244125

41254126
/// Return the array of all the yields.

include/swift/Demangling/TypeDecoder.h

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -240,52 +240,61 @@ class ImplFunctionTypeFlags {
240240
unsigned Rep : 3;
241241
unsigned Pseudogeneric : 1;
242242
unsigned Escaping : 1;
243+
unsigned Concurrent : 1;
243244
unsigned Async : 1;
244245
unsigned DifferentiabilityKind : 2;
245246

246247
public:
247248
ImplFunctionTypeFlags()
248-
: Rep(0), Pseudogeneric(0), Escaping(0), Async(0),
249+
: Rep(0), Pseudogeneric(0), Escaping(0), Concurrent(0), Async(0),
249250
DifferentiabilityKind(0) {}
250251

251252
ImplFunctionTypeFlags(ImplFunctionRepresentation rep, bool pseudogeneric,
252-
bool noescape, bool async,
253+
bool noescape, bool concurrent, bool async,
253254
ImplFunctionDifferentiabilityKind diffKind)
254255
: Rep(unsigned(rep)), Pseudogeneric(pseudogeneric), Escaping(noescape),
255-
Async(async), DifferentiabilityKind(unsigned(diffKind)) {}
256+
Concurrent(concurrent), Async(async),
257+
DifferentiabilityKind(unsigned(diffKind)) {}
256258

257259
ImplFunctionTypeFlags
258260
withRepresentation(ImplFunctionRepresentation rep) const {
259261
return ImplFunctionTypeFlags(
260-
rep, Pseudogeneric, Escaping, Async,
262+
rep, Pseudogeneric, Escaping, Concurrent, Async,
261263
ImplFunctionDifferentiabilityKind(DifferentiabilityKind));
262264
}
263265

264266
ImplFunctionTypeFlags
265-
withAsync() const {
267+
withConcurrent() const {
266268
return ImplFunctionTypeFlags(
267269
ImplFunctionRepresentation(Rep), Pseudogeneric, Escaping, true,
268-
ImplFunctionDifferentiabilityKind(DifferentiabilityKind));
270+
Async, ImplFunctionDifferentiabilityKind(DifferentiabilityKind));
271+
}
272+
273+
ImplFunctionTypeFlags
274+
withAsync() const {
275+
return ImplFunctionTypeFlags(
276+
ImplFunctionRepresentation(Rep), Pseudogeneric, Escaping, Concurrent,
277+
true, ImplFunctionDifferentiabilityKind(DifferentiabilityKind));
269278
}
270279

271280
ImplFunctionTypeFlags
272281
withEscaping() const {
273282
return ImplFunctionTypeFlags(
274-
ImplFunctionRepresentation(Rep), Pseudogeneric, true, Async,
283+
ImplFunctionRepresentation(Rep), Pseudogeneric, true, Concurrent, Async,
275284
ImplFunctionDifferentiabilityKind(DifferentiabilityKind));
276285
}
277286

278287
ImplFunctionTypeFlags
279288
withPseudogeneric() const {
280289
return ImplFunctionTypeFlags(
281-
ImplFunctionRepresentation(Rep), true, Escaping, Async,
290+
ImplFunctionRepresentation(Rep), true, Escaping, Concurrent, Async,
282291
ImplFunctionDifferentiabilityKind(DifferentiabilityKind));
283292
}
284293

285294
ImplFunctionTypeFlags
286295
withDifferentiabilityKind(ImplFunctionDifferentiabilityKind diffKind) const {
287296
return ImplFunctionTypeFlags(ImplFunctionRepresentation(Rep), Pseudogeneric,
288-
Escaping, Async, diffKind);
297+
Escaping, Concurrent, Async, diffKind);
289298
}
290299

291300
ImplFunctionRepresentation getRepresentation() const {
@@ -296,6 +305,8 @@ class ImplFunctionTypeFlags {
296305

297306
bool isEscaping() const { return Escaping; }
298307

308+
bool isConcurrent() const { return Concurrent; }
309+
299310
bool isPseudogeneric() const { return Pseudogeneric; }
300311

301312
ImplFunctionDifferentiabilityKind getDifferentiabilityKind() const {
@@ -731,7 +742,9 @@ class TypeDecoder {
731742
} else if (child->getKind() == NodeKind::ImplFunctionAttribute) {
732743
if (!child->hasText())
733744
return MAKE_NODE_TYPE_ERROR0(child, "expected text");
734-
if (child->getText() == "@async") {
745+
if (child->getText() == "@concurrent") {
746+
flags = flags.withConcurrent();
747+
} else if (child->getText() == "@async") {
735748
flags = flags.withAsync();
736749
}
737750
} else if (child->getKind() == NodeKind::ImplDifferentiable) {

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ class TypeRefBuilder {
443443
break;
444444
}
445445

446+
funcFlags = funcFlags.withConcurrent(flags.isConcurrent());
446447
funcFlags = funcFlags.withAsync(flags.isAsync());
447448

448449
auto result = createTupleType({}, "");

lib/AST/ASTDemangler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ Type ASTBuilder::createImplFunctionType(
559559
}
560560
auto einfo = SILFunctionType::ExtInfoBuilder(
561561
representation, flags.isPseudogeneric(), !flags.isEscaping(),
562-
flags.isAsync(), diffKind, clangFnType)
562+
flags.isConcurrent(), flags.isAsync(), diffKind, clangFnType)
563563
.build();
564564

565565
return SILFunctionType::get(genericSig, einfo, funcCoroutineKind,

lib/AST/ASTMangler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,6 +1727,11 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn) {
17271727
break;
17281728
}
17291729

1730+
// Concurrent functions.
1731+
if (fn->isConcurrent()) {
1732+
OpArgs.push_back('h');
1733+
}
1734+
17301735
// Asynchronous functions.
17311736
if (fn->isAsync()) {
17321737
OpArgs.push_back('H');

lib/AST/ASTPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4293,6 +4293,9 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
42934293
if (info.isNoEscape()) {
42944294
Printer.printSimpleAttr("@noescape") << " ";
42954295
}
4296+
if (info.isConcurrent()) {
4297+
Printer.printSimpleAttr("@concurrent") << " ";
4298+
}
42964299
if (info.isAsync()) {
42974300
Printer.printSimpleAttr("@async") << " ";
42984301
}

lib/Demangling/Demangler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1877,6 +1877,11 @@ NodePointer Demangler::demangleImplFunctionType() {
18771877
if (CoroAttr)
18781878
type->addChild(createNode(Node::Kind::ImplFunctionAttribute, CoroAttr), *this);
18791879

1880+
if (nextIf('h')) {
1881+
type->addChild(createNode(Node::Kind::ImplFunctionAttribute, "@concurrent"),
1882+
*this);
1883+
}
1884+
18801885
if (nextIf('H')) {
18811886
type->addChild(createNode(Node::Kind::ImplFunctionAttribute, "@async"),
18821887
*this);

lib/Demangling/OldDemangler.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2149,6 +2149,9 @@ class OldDemangler {
21492149
return nullptr;
21502150
}
21512151

2152+
if (Mangled.nextIf('h'))
2153+
addImplFunctionAttribute(type, "@concurrent");
2154+
21522155
if (Mangled.nextIf('H'))
21532156
addImplFunctionAttribute(type, "@async");
21542157

0 commit comments

Comments
 (0)