Skip to content

Commit 4fd17c1

Browse files
authored
Merge pull request #30154 from rjmccall/impl-mangling-coroutines
Mangle coroutine information when mangling SILFunctionTypes
2 parents fd6060b + 9df969a commit 4fd17c1

File tree

12 files changed

+85
-18
lines changed

12 files changed

+85
-18
lines changed

docs/ABI/Mangling.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ mangled in to disambiguate.
585585
impl-function-type ::= type* 'I' FUNC-ATTRIBUTES '_'
586586
impl-function-type ::= type* generic-signature 'I' PSEUDO-GENERIC? FUNC-ATTRIBUTES '_'
587587

588-
FUNC-ATTRIBUTES ::= CALLEE-ESCAPE? CALLEE-CONVENTION FUNC-REPRESENTATION? PARAM-CONVENTION* RESULT-CONVENTION* ('z' RESULT-CONVENTION)
588+
FUNC-ATTRIBUTES ::= CALLEE-ESCAPE? CALLEE-CONVENTION FUNC-REPRESENTATION? COROUTINE-KIND? PARAM-CONVENTION* RESULT-CONVENTION* ('Y' PARAM-CONVENTION)* ('z' RESULT-CONVENTION)?
589589

590590
PSEUDO-GENERIC ::= 'P'
591591

@@ -603,6 +603,9 @@ mangled in to disambiguate.
603603
FUNC-REPRESENTATION ::= 'K' // closure
604604
FUNC-REPRESENTATION ::= 'W' // protocol witness
605605

606+
COROUTINE-KIND ::= 'A' // yield-once coroutine
607+
COROUTINE-KIND ::= 'G' // yield-many coroutine
608+
606609
PARAM-CONVENTION ::= 'i' // indirect in
607610
PARAM-CONVENTION ::= 'c' // indirect in constant
608611
PARAM-CONVENTION ::= 'l' // indirect inout

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ NODE(ImplSubstitutions)
118118
CONTEXT_NODE(ImplicitClosure)
119119
NODE(ImplParameter)
120120
NODE(ImplResult)
121+
NODE(ImplYield)
121122
NODE(ImplErrorResult)
122123
NODE(InOut)
123124
NODE(InfixOperator)

include/swift/Demangling/Demangler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ class Demangler : public NodeFactory {
516516
NodePointer popAnyProtocolConformanceList();
517517
NodePointer demangleRetroactiveConformance();
518518
NodePointer demangleInitializer();
519-
NodePointer demangleImplParamConvention();
519+
NodePointer demangleImplParamConvention(Node::Kind ConvKind);
520520
NodePointer demangleImplResultConvention(Node::Kind ConvKind);
521521
NodePointer demangleImplFunctionType();
522522
NodePointer demangleMetatype();

lib/AST/ASTMangler.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,6 +1499,18 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn) {
14991499
OpArgs.push_back('W');
15001500
break;
15011501
}
1502+
1503+
// Coroutine kind. This is mangled in all pointer auth modes.
1504+
switch (fn->getCoroutineKind()) {
1505+
case SILCoroutineKind::None:
1506+
break;
1507+
case SILCoroutineKind::YieldOnce:
1508+
OpArgs.push_back('A');
1509+
break;
1510+
case SILCoroutineKind::YieldMany:
1511+
OpArgs.push_back('G');
1512+
break;
1513+
}
15021514

15031515
// Mangle the parameters.
15041516
for (auto param : fn->getParameters()) {
@@ -1512,6 +1524,13 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn) {
15121524
appendType(result.getInterfaceType());
15131525
}
15141526

1527+
// Mangle the yields.
1528+
for (auto yield : fn->getYields()) {
1529+
OpArgs.push_back('Y');
1530+
OpArgs.push_back(getParamConvention(yield.getConvention()));
1531+
appendType(yield.getInterfaceType());
1532+
}
1533+
15151534
// Mangle the error result if present.
15161535
if (fn->hasErrorResult()) {
15171536
auto error = fn->getErrorResult();

lib/Demangling/Demangler.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,7 +1692,7 @@ NodePointer Demangler::demangleBoundGenericArgs(NodePointer Nominal,
16921692
return createWithChildren(kind, createType(Nominal), args);
16931693
}
16941694

1695-
NodePointer Demangler::demangleImplParamConvention() {
1695+
NodePointer Demangler::demangleImplParamConvention(Node::Kind ConvKind) {
16961696
const char *attr = nullptr;
16971697
switch (nextChar()) {
16981698
case 'i': attr = "@in"; break;
@@ -1710,7 +1710,7 @@ NodePointer Demangler::demangleImplParamConvention() {
17101710
pushBack();
17111711
return nullptr;
17121712
}
1713-
return createWithChild(Node::Kind::ImplParameter,
1713+
return createWithChild(ConvKind,
17141714
createNode(Node::Kind::ImplConvention, attr));
17151715
}
17161716

@@ -1783,10 +1783,19 @@ NodePointer Demangler::demangleImplFunctionType() {
17831783
if (FAttr)
17841784
type->addChild(createNode(Node::Kind::ImplFunctionAttribute, FAttr), *this);
17851785

1786+
const char *CoroAttr = nullptr;
1787+
if (nextIf('A'))
1788+
CoroAttr = "@yield_once";
1789+
else if (nextIf('G'))
1790+
CoroAttr = "@yield_many";
1791+
if (CoroAttr)
1792+
type->addChild(createNode(Node::Kind::ImplFunctionAttribute, CoroAttr), *this);
1793+
17861794
addChild(type, GenSig);
17871795

17881796
int NumTypesToAdd = 0;
1789-
while (NodePointer Param = demangleImplParamConvention()) {
1797+
while (NodePointer Param =
1798+
demangleImplParamConvention(Node::Kind::ImplParameter)) {
17901799
type = addChild(type, Param);
17911800
NumTypesToAdd++;
17921801
}
@@ -1795,6 +1804,14 @@ NodePointer Demangler::demangleImplFunctionType() {
17951804
type = addChild(type, Result);
17961805
NumTypesToAdd++;
17971806
}
1807+
while (nextIf('Y')) {
1808+
NodePointer YieldResult =
1809+
demangleImplParamConvention(Node::Kind::ImplYield);
1810+
if (!YieldResult)
1811+
return nullptr;
1812+
type = addChild(type, YieldResult);
1813+
NumTypesToAdd++;
1814+
}
17981815
if (nextIf('z')) {
17991816
NodePointer ErrorResult = demangleImplResultConvention(
18001817
Node::Kind::ImplErrorResult);

lib/Demangling/NodePrinter.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ class NodePrinter {
395395
case Node::Kind::ImplicitClosure:
396396
case Node::Kind::ImplParameter:
397397
case Node::Kind::ImplResult:
398+
case Node::Kind::ImplYield:
398399
case Node::Kind::ImplErrorResult:
399400
case Node::Kind::InOut:
400401
case Node::Kind::InfixOperator:
@@ -766,6 +767,7 @@ class NodePrinter {
766767
transitionTo(Inputs);
767768
print(child);
768769
} else if (child->getKind() == Node::Kind::ImplResult
770+
|| child->getKind() == Node::Kind::ImplYield
769771
|| child->getKind() == Node::Kind::ImplErrorResult) {
770772
if (curState == Results) Printer << ", ";
771773
transitionTo(Results);
@@ -2010,7 +2012,12 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
20102012
return nullptr;
20112013
case Node::Kind::ImplErrorResult:
20122014
Printer << "@error ";
2013-
LLVM_FALLTHROUGH;
2015+
printChildren(Node, " ");
2016+
return nullptr;
2017+
case Node::Kind::ImplYield:
2018+
Printer << "@yields ";
2019+
printChildren(Node, " ");
2020+
return nullptr;
20142021
case Node::Kind::ImplParameter:
20152022
case Node::Kind::ImplResult:
20162023
printChildren(Node, " ");

lib/Demangling/OldRemangler.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,10 @@ void Remangler::mangleImplFunctionAttribute(Node *node) {
12271227
Buffer << "CO";
12281228
} else if (text == "@convention(witness_method)") {
12291229
Buffer << "Cw";
1230+
} else if (text == "@yield_once") {
1231+
Buffer << "A";
1232+
} else if (text == "@yield_many") {
1233+
Buffer << "G";
12301234
} else {
12311235
unreachable("bad impl-function-attribute");
12321236
}
@@ -1248,6 +1252,12 @@ void Remangler::mangleImplResult(Node *node) {
12481252
mangleChildNodes(node); // impl convention, type
12491253
}
12501254

1255+
void Remangler::mangleImplYield(Node *node) {
1256+
assert(node->getNumChildren() == 2);
1257+
Buffer << 'Y';
1258+
mangleChildNodes(node); // impl convention, type
1259+
}
1260+
12511261
void Remangler::mangleImplEscaping(Node *node) {
12521262
// The old mangler does not encode escaping.
12531263
}

lib/Demangling/Remangler.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,7 @@ void Remangler::mangleImplFunctionType(Node *node) {
14131413
switch (auto kind = Child->getKind()) {
14141414
case Node::Kind::ImplParameter:
14151415
case Node::Kind::ImplResult:
1416+
case Node::Kind::ImplYield:
14161417
case Node::Kind::ImplErrorResult:
14171418
mangleChildNode(Child, 1);
14181419
break;
@@ -1473,11 +1474,16 @@ void Remangler::mangleImplFunctionType(Node *node) {
14731474
.Case("@convention(objc_method)", 'O')
14741475
.Case("@convention(closure)", 'K')
14751476
.Case("@convention(witness_method)", 'W')
1477+
.Case("@yield_once", 'A')
1478+
.Case("@yield_many", 'G')
14761479
.Default(0);
14771480
assert(FuncAttr && "invalid impl function attribute");
14781481
Buffer << FuncAttr;
14791482
break;
14801483
}
1484+
case Node::Kind::ImplYield:
1485+
Buffer << 'Y';
1486+
LLVM_FALLTHROUGH;
14811487
case Node::Kind::ImplParameter: {
14821488
char ConvCh =
14831489
llvm::StringSwitch<char>(Child->getFirstChild()->getText())
@@ -1532,6 +1538,10 @@ void Remangler::mangleImplResult(Node *node) {
15321538
unreachable("handled inline");
15331539
}
15341540

1541+
void Remangler::mangleImplYield(Node *node) {
1542+
unreachable("handled inline");
1543+
}
1544+
15351545
void Remangler::mangleImplErrorResult(Node *node) {
15361546
unreachable("handled inline");
15371547
}

test/IRGen/yield_once.sil

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ sil @marker : $(Builtin.Int32) -> ()
1010
// CHECK-SAME: [[CORO_ATTRIBUTES:#[0-9]+]]
1111
sil @test_simple : $@yield_once () -> () {
1212
entry:
13-
// CHECK-32: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], i8* %0, i8* bitcast (void (i8*, i1)* @"$sIet_TC" to i8*), i8* bitcast (i8* (i32)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
14-
// CHECK-64: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$sIet_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
13+
// CHECK-32: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], i8* %0, i8* bitcast (void (i8*, i1)* @"$sIetA_TC" to i8*), i8* bitcast (i8* (i32)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
14+
// CHECK-64: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$sIetA_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
1515
// CHECK-NEXT: [[BEGIN:%.*]] = call i8* @llvm.coro.begin(token [[ID]], i8* null)
1616

1717
// CHECK-NEXT: call swiftcc void @marker(i32 1000)
@@ -43,7 +43,7 @@ unwind:
4343
// CHECK-NEXT: unreachable
4444
}
4545

46-
// CHECK-LABEL: declare{{( dllimport)?}}{{( protected)?}} swiftcc void @"$sIet_TC"
46+
// CHECK-LABEL: declare{{( dllimport)?}}{{( protected)?}} swiftcc void @"$sIetA_TC"
4747
// CHECK-SAME: (i8* noalias dereferenceable([[BUFFER_SIZE]]), i1)
4848

4949
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test_simple_call(i1 %0)

test/IRGen/yield_once_big.sil

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ entry:
3838
// CHECK-64-SAME: , align 8
3939

4040
// Coroutine setup.
41-
// CHECK-32-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s14yield_once_big9SomeClassCRbzlIet_TC" to i8*), i8* bitcast (i8* (i32)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
42-
// CHECK-64-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s14yield_once_big9SomeClassCRbzlIet_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
41+
// CHECK-32-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s14yield_once_big3BigVyxGAA9SomeClassCRbzlIetAYc_TC" to i8*), i8* bitcast (i8* (i32)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
42+
// CHECK-64-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s14yield_once_big3BigVyxGAA9SomeClassCRbzlIetAYc_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
4343
// CHECK-NEXT: [[BEGIN:%.*]] = call i8* @llvm.coro.begin(token [[ID]], i8* null)
4444
// CHECK-NEXT: store %swift.type*
4545

@@ -86,7 +86,7 @@ unwind:
8686
// CHECK-NEXT: unreachable
8787
}
8888

89-
// CHECK-LABEL: declare{{( dllimport)?}}{{( protected)?}} swiftcc void @"$s14yield_once_big9SomeClassCRbzlIet_TC"
89+
// CHECK-LABEL: declare{{( dllimport)?}}{{( protected)?}} swiftcc void @"$s14yield_once_big3BigVyxGAA9SomeClassCRbzlIetAYc_TC"
9090
// CHECK-SAME: (i8* noalias dereferenceable([[BUFFER_SIZE]]), i1)
9191

9292
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test_simple_call(i1 %0)

test/IRGen/yield_once_biggish.sil

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ entry:
3939
// CHECK-64-SAME: , align 8
4040

4141
// Coroutine setup.
42-
// CHECK-32-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s18yield_once_biggish9SomeClassCRbzlIet_TC" to i8*), i8* bitcast (i8* (i32)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
43-
// CHECK-64-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s18yield_once_biggish9SomeClassCRbzlIet_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
42+
// CHECK-32-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s18yield_once_biggish7BiggishVyxGAA9SomeClassCRbzlIetAYx_TC" to i8*), i8* bitcast (i8* (i32)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
43+
// CHECK-64-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s18yield_once_biggish7BiggishVyxGAA9SomeClassCRbzlIetAYx_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
4444
// CHECK-NEXT: [[BEGIN:%.*]] = call i8* @llvm.coro.begin(token [[ID]], i8* null)
4545
// CHECK-NEXT: store %swift.type*
4646
// CHECK-NEXT: call swiftcc void @marker(i32 1000)
@@ -94,7 +94,7 @@ unwind:
9494
// CHECK-NEXT: unreachable
9595
}
9696

97-
// CHECK-LABEL: declare{{( dllimport)?}}{{( protected)?}} swiftcc void @"$s18yield_once_biggish9SomeClassCRbzlIet_TC"
97+
// CHECK-LABEL: declare{{( dllimport)?}}{{( protected)?}} swiftcc void @"$s18yield_once_biggish7BiggishVyxGAA9SomeClassCRbzlIetAYx_TC"
9898
// CHECK-SAME: (i8* noalias dereferenceable([[BUFFER_SIZE]]), i1)
9999

100100
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test_simple_call(i1 %0)

test/IRGen/yield_once_indirect.sil

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ entry:
3030
// CHECK-64-SAME: , align 8
3131

3232
// Coroutine setup.
33-
// CHECK-32-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s19yield_once_indirect9SomeClassCRbzlIet_TC" to i8*), i8* bitcast (i8* (i32)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
34-
// CHECK-64-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s19yield_once_indirect9SomeClassCRbzlIet_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
33+
// CHECK-32-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s19yield_once_indirect8IndirectVyxGAA9SomeClassCRbzlIetAYi_TC" to i8*), i8* bitcast (i8* (i32)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
34+
// CHECK-64-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s19yield_once_indirect8IndirectVyxGAA9SomeClassCRbzlIetAYi_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
3535
// CHECK-NEXT: [[BEGIN:%.*]] = call i8* @llvm.coro.begin(token [[ID]], i8* null)
3636
// CHECK-NEXT: store %swift.type*
3737
// CHECK-NEXT: call swiftcc void @marker(i32 1000)
@@ -83,7 +83,7 @@ unwind:
8383
// CHECK-NEXT: unreachable
8484
}
8585

86-
// CHECK-LABEL: declare{{( dllimport)?}}{{( protected)?}} swiftcc void @"$s19yield_once_indirect9SomeClassCRbzlIet_TC"
86+
// CHECK-LABEL: declare{{( dllimport)?}}{{( protected)?}} swiftcc void @"$s19yield_once_indirect8IndirectVyxGAA9SomeClassCRbzlIetAYi_TC"
8787
// CHECK-SAME: (i8* noalias dereferenceable([[BUFFER_SIZE]]), i1)
8888

8989
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test_simple_call(i1 %0)

0 commit comments

Comments
 (0)