Skip to content

Commit fb66de6

Browse files
committed
Unify mangling operators for async, @Sendable, @differentiable and @noDerivative.
Repurpose mangling operator `Y` as an umbrella operator that covers new attributes on function types. Free up operators `J`, `j`, and `k`. ``` async ::= 'Ya' // 'async' annotation on function types sendable ::= 'Yb' // @sendable on function types throws ::= 'K' // 'throws' annotation on function types differentiable ::= 'Yjf' // @differentiable(_forward) on function type differentiable ::= 'Yjr' // @differentiable(reverse) on function type differentiable ::= 'Yjd' // @differentiable on function type differentiable ::= 'Yjl' // @differentiable(_linear) on function type ``` Resolves rdar://76299796.
1 parent 82886bf commit fb66de6

File tree

78 files changed

+332
-310
lines changed

Some content is hidden

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

78 files changed

+332
-310
lines changed

docs/ABI/Mangling.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -570,19 +570,19 @@ Types
570570
// they are mangled separately as part of the entity.
571571
params-type ::= empty-list // shortcut for no parameters
572572

573-
sendable ::= 'J' // @Sendable on function types
574-
async ::= 'Y' // 'async' annotation on function types
573+
async ::= 'Ya' // 'async' annotation on function types
574+
sendable ::= 'Yb' // @Sendable on function types
575575
throws ::= 'K' // 'throws' annotation on function types
576-
differentiable ::= 'jf' // @differentiable(_forward) on function type
577-
differentiable ::= 'jr' // @differentiable(reverse) on function type
578-
differentiable ::= 'jd' // @differentiable on function type
579-
differentiable ::= 'jl' // @differentiable(_linear) on function type
576+
differentiable ::= 'Yjf' // @differentiable(_forward) on function type
577+
differentiable ::= 'Yjr' // @differentiable(reverse) on function type
578+
differentiable ::= 'Yjd' // @differentiable on function type
579+
differentiable ::= 'Yjl' // @differentiable(_linear) on function type
580580

581581
type-list ::= list-type '_' list-type* // list of types
582582
type-list ::= empty-list
583583

584584
// FIXME: Consider replacing 'h' with a two-char code
585-
list-type ::= type identifier? 'k'? 'z'? 'h'? 'n'? 'd'? // type with optional label, '@noDerivative', inout convention, shared convention, owned convention, and variadic specifier
585+
list-type ::= type identifier? 'Yk'? 'z'? 'h'? 'n'? 'd'? // type with optional label, '@noDerivative', inout convention, shared convention, owned convention, and variadic specifier
586586

587587
METATYPE-REPR ::= 't' // Thin metatype representation
588588
METATYPE-REPR ::= 'T' // Thick metatype representation

include/swift/Demangling/Demangler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,8 @@ class Demangler : public NodeFactory {
569569

570570
NodePointer demangleTypeMangling();
571571
NodePointer demangleSymbolicReference(unsigned char rawKind);
572+
NodePointer demangleTypeAnnotation();
573+
572574
NodePointer demangleAutoDiffFunctionOrSimpleThunk(Node::Kind nodeKind);
573575
NodePointer demangleAutoDiffFunctionKind();
574576
NodePointer demangleAutoDiffSubsetParametersThunk();

include/swift/Demangling/TypeDecoder.h

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -738,27 +738,6 @@ class TypeDecoder {
738738
++firstChildIdx;
739739
}
740740

741-
bool isThrow = false;
742-
if (Node->getChild(firstChildIdx)->getKind()
743-
== NodeKind::ThrowsAnnotation) {
744-
isThrow = true;
745-
++firstChildIdx;
746-
}
747-
748-
bool isSendable = false;
749-
if (Node->getChild(firstChildIdx)->getKind()
750-
== NodeKind::ConcurrentFunctionType) {
751-
isSendable = true;
752-
++firstChildIdx;
753-
}
754-
755-
bool isAsync = false;
756-
if (Node->getChild(firstChildIdx)->getKind()
757-
== NodeKind::AsyncAnnotation) {
758-
isAsync = true;
759-
++firstChildIdx;
760-
}
761-
762741
FunctionMetadataDifferentiabilityKind diffKind;
763742
if (Node->getChild(firstChildIdx)->getKind() ==
764743
NodeKind::DifferentiableFunctionType) {
@@ -784,6 +763,27 @@ class TypeDecoder {
784763
++firstChildIdx;
785764
}
786765

766+
bool isThrow = false;
767+
if (Node->getChild(firstChildIdx)->getKind()
768+
== NodeKind::ThrowsAnnotation) {
769+
isThrow = true;
770+
++firstChildIdx;
771+
}
772+
773+
bool isSendable = false;
774+
if (Node->getChild(firstChildIdx)->getKind()
775+
== NodeKind::ConcurrentFunctionType) {
776+
isSendable = true;
777+
++firstChildIdx;
778+
}
779+
780+
bool isAsync = false;
781+
if (Node->getChild(firstChildIdx)->getKind()
782+
== NodeKind::AsyncAnnotation) {
783+
isAsync = true;
784+
++firstChildIdx;
785+
}
786+
787787
flags = flags.withConcurrent(isSendable)
788788
.withAsync(isAsync).withThrows(isThrow)
789789
.withDifferentiable(diffKind.isDifferentiable());
@@ -1371,25 +1371,25 @@ class TypeDecoder {
13711371
FunctionParam<BuiltType> &param) -> bool {
13721372
Demangle::NodePointer node = typeNode;
13731373

1374-
auto setOwnership = [&](ValueOwnership ownership) {
1375-
param.setValueOwnership(ownership);
1376-
node = node->getFirstChild();
1377-
hasParamFlags = true;
1378-
};
1379-
13801374
bool recurse = true;
13811375
while (recurse) {
13821376
switch (node->getKind()) {
13831377
case NodeKind::InOut:
1384-
setOwnership(ValueOwnership::InOut);
1378+
param.setValueOwnership(ValueOwnership::InOut);
1379+
node = node->getFirstChild();
1380+
hasParamFlags = true;
13851381
break;
13861382

13871383
case NodeKind::Shared:
1388-
setOwnership(ValueOwnership::Shared);
1384+
param.setValueOwnership(ValueOwnership::Shared);
1385+
node = node->getFirstChild();
1386+
hasParamFlags = true;
13891387
break;
13901388

13911389
case NodeKind::Owned:
1392-
setOwnership(ValueOwnership::Owned);
1390+
param.setValueOwnership(ValueOwnership::Owned);
1391+
node = node->getFirstChild();
1392+
hasParamFlags = true;
13931393
break;
13941394

13951395
case NodeKind::NoDerivative:

lib/AST/ASTMangler.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2448,25 +2448,25 @@ void ASTMangler::appendFunctionSignature(AnyFunctionType *fn,
24482448
appendFunctionResultType(fn->getResult(), forDecl);
24492449
appendFunctionInputType(fn->getParams(), forDecl);
24502450
if (fn->isAsync() || functionMangling == AsyncHandlerBodyMangling)
2451-
appendOperator("Y");
2451+
appendOperator("Ya");
24522452
if (fn->isSendable())
2453-
appendOperator("J");
2453+
appendOperator("Yb");
24542454
if (fn->isThrowing())
24552455
appendOperator("K");
24562456
switch (auto diffKind = fn->getDifferentiabilityKind()) {
24572457
case DifferentiabilityKind::NonDifferentiable:
24582458
break;
24592459
case DifferentiabilityKind::Forward:
2460-
appendOperator("jf");
2460+
appendOperator("Yjf");
24612461
break;
24622462
case DifferentiabilityKind::Reverse:
2463-
appendOperator("jr");
2463+
appendOperator("Yjr");
24642464
break;
24652465
case DifferentiabilityKind::Normal:
2466-
appendOperator("jd");
2466+
appendOperator("Yjd");
24672467
break;
24682468
case DifferentiabilityKind::Linear:
2469-
appendOperator("jl");
2469+
appendOperator("Yjl");
24702470
break;
24712471
}
24722472
}
@@ -2542,7 +2542,7 @@ void ASTMangler::appendTypeListElement(Identifier name, Type elementType,
25422542
appendType(elementType, forDecl);
25432543

25442544
if (flags.isNoDerivative()) {
2545-
appendOperator("k");
2545+
appendOperator("Yk");
25462546
}
25472547
switch (flags.getValueOwnership()) {
25482548
case ValueOwnership::Default:

lib/Demangling/Demangler.cpp

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,22 @@ NodePointer Demangler::demangleSymbolicReference(unsigned char rawKind) {
730730
return resolved;
731731
}
732732

733+
NodePointer Demangler::demangleTypeAnnotation() {
734+
switch (char c2 = nextChar()) {
735+
case 'a':
736+
return createNode(Node::Kind::AsyncAnnotation);
737+
case 'b':
738+
return createNode(Node::Kind::ConcurrentFunctionType);
739+
case 'j':
740+
return demangleDifferentiableFunctionType();
741+
case 'k':
742+
return createType(
743+
createWithChild(Node::Kind::NoDerivative, popTypeAndGetChild()));
744+
default:
745+
return nullptr;
746+
}
747+
}
748+
733749
NodePointer Demangler::demangleOperator() {
734750
recur:
735751
switch (unsigned char c = nextChar()) {
@@ -767,7 +783,6 @@ NodePointer Demangler::demangleOperator() {
767783
}
768784

769785
case 'I': return demangleImplFunctionType();
770-
case 'J': return createNode(Node::Kind::ConcurrentFunctionType);
771786
case 'K': return createNode(Node::Kind::ThrowsAnnotation);
772787
case 'L': return demangleLocalIdentifier();
773788
case 'M': return demangleMetatype();
@@ -782,7 +797,7 @@ NodePointer Demangler::demangleOperator() {
782797
case 'V': return demangleAnyGenericType(Node::Kind::Structure);
783798
case 'W': return demangleWitness();
784799
case 'X': return demangleSpecialType();
785-
case 'Y': return createNode(Node::Kind::AsyncAnnotation);
800+
case 'Y': return demangleTypeAnnotation();
786801
case 'Z': return createWithChild(Node::Kind::Static, popNode(isEntity));
787802
case 'a': return demangleAnyGenericType(Node::Kind::TypeAlias);
788803
case 'c': return popFunctionType(Node::Kind::FunctionType);
@@ -792,10 +807,6 @@ NodePointer Demangler::demangleOperator() {
792807
case 'h': return createType(createWithChild(Node::Kind::Shared,
793808
popTypeAndGetChild()));
794809
case 'i': return demangleSubscript();
795-
case 'j': return demangleDifferentiableFunctionType();
796-
case 'k':
797-
return createType(
798-
createWithChild(Node::Kind::NoDerivative, popTypeAndGetChild()));
799810
case 'l': return demangleGenericSignature(/*hasParamCounts*/ false);
800811
case 'm': return createType(createWithChild(Node::Kind::Metatype,
801812
popNode(Node::Kind::Type)));
@@ -1257,10 +1268,10 @@ NodePointer Demangler::popFunctionType(Node::Kind kind, bool hasClangType) {
12571268
ClangType = demangleClangType();
12581269
}
12591270
addChild(FuncType, ClangType);
1271+
addChild(FuncType, popNode(Node::Kind::DifferentiableFunctionType));
12601272
addChild(FuncType, popNode(Node::Kind::ThrowsAnnotation));
12611273
addChild(FuncType, popNode(Node::Kind::ConcurrentFunctionType));
12621274
addChild(FuncType, popNode(Node::Kind::AsyncAnnotation));
1263-
addChild(FuncType, popNode(Node::Kind::DifferentiableFunctionType));
12641275

12651276
FuncType = addChild(FuncType, popFunctionParams(Node::Kind::ArgumentTuple));
12661277
FuncType = addChild(FuncType, popFunctionParams(Node::Kind::ReturnType));
@@ -1293,6 +1304,9 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
12931304
return nullptr;
12941305

12951306
unsigned FirstChildIdx = 0;
1307+
if (FuncType->getChild(FirstChildIdx)->getKind()
1308+
== Node::Kind::DifferentiableFunctionType)
1309+
++FirstChildIdx;
12961310
if (FuncType->getChild(FirstChildIdx)->getKind()
12971311
== Node::Kind::ThrowsAnnotation)
12981312
++FirstChildIdx;
@@ -1302,9 +1316,6 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
13021316
if (FuncType->getChild(FirstChildIdx)->getKind()
13031317
== Node::Kind::AsyncAnnotation)
13041318
++FirstChildIdx;
1305-
if (FuncType->getChild(FirstChildIdx)->getKind()
1306-
== Node::Kind::DifferentiableFunctionType)
1307-
++FirstChildIdx;
13081319
auto ParameterType = FuncType->getChild(FirstChildIdx);
13091320

13101321
assert(ParameterType->getKind() == Node::Kind::ArgumentTuple);

lib/Demangling/NodePrinter.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,12 @@ class NodePrinter {
809809
unsigned startIndex = 0;
810810
bool isSendable = false, isAsync = false, isThrows = false;
811811
auto diffKind = MangledDifferentiabilityKind::NonDifferentiable;
812+
if (node->getChild(startIndex)->getKind() ==
813+
Node::Kind::DifferentiableFunctionType) {
814+
diffKind =
815+
(MangledDifferentiabilityKind)node->getChild(startIndex)->getIndex();
816+
++startIndex;
817+
}
812818
if (node->getChild(startIndex)->getKind() == Node::Kind::ClangType) {
813819
// handled earlier
814820
++startIndex;
@@ -826,12 +832,6 @@ class NodePrinter {
826832
++startIndex;
827833
isAsync = true;
828834
}
829-
if (node->getChild(startIndex)->getKind() ==
830-
Node::Kind::DifferentiableFunctionType) {
831-
diffKind =
832-
(MangledDifferentiabilityKind)node->getChild(startIndex)->getIndex();
833-
++startIndex;
834-
}
835835

836836
switch (diffKind) {
837837
case MangledDifferentiabilityKind::Forward:

lib/Demangling/Remangler.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1678,7 +1678,7 @@ void Remangler::mangleOwned(Node *node) {
16781678

16791679
void Remangler::mangleNoDerivative(Node *node) {
16801680
mangleSingleChildNode(node);
1681-
Buffer << 'k';
1681+
Buffer << "Yk";
16821682
}
16831683

16841684
void Remangler::mangleInfixOperator(Node *node) {
@@ -2465,15 +2465,15 @@ void Remangler::mangleFullObjCResilientClassStub(Node *node) {
24652465
}
24662466

24672467
void Remangler::mangleConcurrentFunctionType(Node *node) {
2468-
Buffer << 'J';
2468+
Buffer << "Yb";
24692469
}
24702470

24712471
void Remangler::mangleAsyncAnnotation(Node *node) {
2472-
Buffer << 'Y';
2472+
Buffer << "Ya";
24732473
}
24742474

24752475
void Remangler::mangleDifferentiableFunctionType(Node *node) {
2476-
Buffer << 'j' << (char)node->getIndex(); // differentiability kind
2476+
Buffer << "Yj" << (char)node->getIndex(); // differentiability kind
24772477
}
24782478

24792479
void Remangler::mangleThrowsAnnotation(Node *node) {

lib/SILGen/SILGenBridging.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1484,7 +1484,7 @@ SILFunction *SILGenFunction::emitNativeAsyncToForeignThunk(SILDeclRef thunk) {
14841484
assert(thunkSuffix[1] == 'T'
14851485
&& thunkSuffix[0] == 'o'
14861486
&& "not an objc thunk?");
1487-
closureName += "yyYcfU_"; // closure with type () async -> ()
1487+
closureName += "yyYacfU_"; // closure with type () async -> ()
14881488
closureName.push_back(thunkSuffix[1]);
14891489
closureName.push_back(thunkSuffix[0]);
14901490

stdlib/public/runtime/Demangle.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -564,15 +564,6 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
564564
result->addChild(resultTy, Dem);
565565

566566
auto funcNode = Dem.createNode(kind);
567-
if (func->isThrowing())
568-
funcNode->addChild(Dem.createNode(Node::Kind::ThrowsAnnotation), Dem);
569-
if (func->isSendable()) {
570-
funcNode->addChild(
571-
Dem.createNode(Node::Kind::ConcurrentFunctionType), Dem);
572-
}
573-
if (func->isAsync())
574-
funcNode->addChild(Dem.createNode(Node::Kind::AsyncAnnotation), Dem);
575-
576567
switch (func->getDifferentiabilityKind().Value) {
577568
case FunctionMetadataDifferentiabilityKind::NonDifferentiable:
578569
break;
@@ -597,6 +588,14 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
597588
(Node::IndexType)MangledDifferentiabilityKind::Linear), Dem);
598589
break;
599590
}
591+
if (func->isThrowing())
592+
funcNode->addChild(Dem.createNode(Node::Kind::ThrowsAnnotation), Dem);
593+
if (func->isSendable()) {
594+
funcNode->addChild(
595+
Dem.createNode(Node::Kind::ConcurrentFunctionType), Dem);
596+
}
597+
if (func->isAsync())
598+
funcNode->addChild(Dem.createNode(Node::Kind::AsyncAnnotation), Dem);
600599

601600
funcNode->addChild(parameters, Dem);
602601
funcNode->addChild(result, Dem);

test/AutoDiff/SILGen/mangling.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@ import _Differentiation
77
// CHECK-LABEL: sil hidden [ossa] @$s8mangling15nonescapingFunc2fnyS2fXE_tF : $@convention(thin) (@noescape @callee_guaranteed (Float) -> Float) -> () {
88
func nonescapingFunc(fn: (Float) -> Float) {}
99

10-
// CHECK-LABEL: sil hidden [ossa] @$s8mangling8diffFunc2fnyS2fjrXE_tF : $@convention(thin) (@differentiable(reverse) @noescape @callee_guaranteed (Float) -> Float) -> () {
10+
// CHECK-LABEL: sil hidden [ossa] @$s8mangling8diffFunc2fnyS2fYjrXE_tF : $@convention(thin) (@differentiable(reverse) @noescape @callee_guaranteed (Float) -> Float) -> () {
1111
func diffFunc(fn: @differentiable(reverse) (Float) -> Float) {}
1212

13-
// CHECK-LABEL: sil hidden [ossa] @$s8mangling10linearFunc2fnyS2fjlXE_tF : $@convention(thin) (@differentiable(_linear) @noescape @callee_guaranteed (Float) -> Float) -> () {
13+
// CHECK-LABEL: sil hidden [ossa] @$s8mangling10linearFunc2fnyS2fYjlXE_tF : $@convention(thin) (@differentiable(_linear) @noescape @callee_guaranteed (Float) -> Float) -> () {
1414
func linearFunc(fn: @differentiable(_linear) (Float) -> Float) {}
1515

1616
// CHECK-LABEL: sil hidden [ossa] @$s8mangling12escapingFunc2fnS2fcS2fc_tF : $@convention(thin) (@guaranteed @callee_guaranteed (Float) -> Float) -> @owned @callee_guaranteed (Float) -> Float {
1717
func escapingFunc(fn: @escaping (Float) -> Float) -> (Float) -> Float { fn }
1818

19-
// CHECK-LABEL: sil hidden [ossa] @$s8mangling16diffEscapingFunc2fnS2fjrcS2fjrc_tF : $@convention(thin) (@guaranteed @differentiable(reverse) @callee_guaranteed (Float) -> Float) -> @owned @differentiable(reverse) @callee_guaranteed (Float) -> Float {
19+
// CHECK-LABEL: sil hidden [ossa] @$s8mangling16diffEscapingFunc2fnS2fYjrcS2fYjrc_tF : $@convention(thin) (@guaranteed @differentiable(reverse) @callee_guaranteed (Float) -> Float) -> @owned @differentiable(reverse) @callee_guaranteed (Float) -> Float {
2020
func diffEscapingFunc(fn: @escaping @differentiable(reverse) (Float) -> Float) -> @differentiable(reverse) (Float) -> Float { fn }
2121

22-
// CHECK-LABEL: sil hidden [ossa] @$s8mangling18linearEscapingFunc2fnS2fjlcS2fjlc_tF : $@convention(thin) (@guaranteed @differentiable(_linear) @callee_guaranteed (Float) -> Float) -> @owned @differentiable(_linear) @callee_guaranteed (Float) -> Float {
22+
// CHECK-LABEL: sil hidden [ossa] @$s8mangling18linearEscapingFunc2fnS2fYjlcS2fYjlc_tF : $@convention(thin) (@guaranteed @differentiable(_linear) @callee_guaranteed (Float) -> Float) -> @owned @differentiable(_linear) @callee_guaranteed (Float) -> Float {
2323
func linearEscapingFunc(fn: @escaping @differentiable(_linear) (Float) -> Float) -> @differentiable(_linear) (Float) -> Float { fn }

test/AutoDiff/validation-test/function_type_metadata.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ if #available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *) {
5050
String(reflecting: (
5151
@differentiable(reverse)
5252
(Float?, inout @noDerivative Int) -> Float?).self))
53+
expectEqual(
54+
"""
55+
@differentiable(reverse) @Sendable (Swift.Optional<Swift.Float>, \
56+
inout @noDerivative Swift.Int) -> Swift.Optional<Swift.Float>
57+
""",
58+
String(reflecting: (
59+
@differentiable(reverse) @Sendable
60+
(Float?, inout @noDerivative Int) -> Float?).self))
5361
}
5462
}
5563

test/DebugInfo/async-args.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ func forceSplit() async {
99
func withGenericArg<T>(_ msg: T) async {
1010
// This odd debug info is part of a contract with CoroSplit/CoroFrame to fix
1111
// this up after coroutine splitting.
12-
// CHECK-LABEL: {{^define .*}} @"$s1M14withGenericArgyyxYlF"(%swift.context* swiftasync %0
12+
// CHECK-LABEL: {{^define .*}} @"$s1M14withGenericArgyyxYalF"(%swift.context* swiftasync %0
1313
// CHECK: call void @llvm.dbg.declare(metadata %swift.context* %0,
1414
// CHECK-SAME: metadata ![[MSG:[0-9]+]], metadata !DIExpression(
1515
// CHECK-SAME: DW_OP_plus_uconst, {{[0-9]+}}, DW_OP_deref))
@@ -18,7 +18,7 @@ func withGenericArg<T>(_ msg: T) async {
1818
// CHECK-SAME: DW_OP_plus_uconst, {{[0-9]+}}))
1919

2020
await forceSplit()
21-
// CHECK-LABEL: {{^define .*}} @"$s1M14withGenericArgyyxYlFTQ0_"(i8* swiftasync %0)
21+
// CHECK-LABEL: {{^define .*}} @"$s1M14withGenericArgyyxYalFTQ0_"(i8* swiftasync %0)
2222
// CHECK: call void @llvm.dbg.declare(metadata i8* %0,
2323
// CHECK-SAME: metadata ![[MSG_R:[0-9]+]], metadata !DIExpression(DW_OP_deref,
2424
// CHECK-SAME: DW_OP_plus_uconst, [[OFFSET:[0-9]+]],

0 commit comments

Comments
 (0)