Skip to content

Commit aec968d

Browse files
Merge pull request #10132 from nate-chandler/coro-popless
[Coro] RetconOnceDynamic: Popless return on null allocator.
2 parents 6e0f052 + 570f7b4 commit aec968d

File tree

8 files changed

+45
-1
lines changed

8 files changed

+45
-1
lines changed

llvm/include/llvm/AsmParser/LLToken.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ enum Kind {
161161
kw_anyregcc,
162162
kw_swiftcc,
163163
kw_swifttailcc,
164+
kw_swiftcorocc,
164165
kw_preserve_mostcc,
165166
kw_preserve_allcc,
166167
kw_preserve_nonecc,

llvm/include/llvm/IR/CallingConv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,10 @@ namespace CallingConv {
270270
/// Preserve X1-X15, X19-X29, SP, Z0-Z31, P0-P15.
271271
AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1 = 111,
272272

273+
/// This follows the Swift calling convention in how arguments are passed
274+
/// but doesn't clean up the stack on a return.
275+
SwiftCoro = 112, // FIXME: allocate
276+
273277
/// The highest possible ID. Must be some 2^k - 1.
274278
MaxID = 1023
275279
};

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,6 +1754,10 @@ def int_coro_await_suspend_handle : Intrinsic<[],
17541754
[llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty],
17551755
[Throws]>;
17561756

1757+
// FIXME: enforce musttail
1758+
// XXX: attrs; not throws, wb DefaultAttrsIntrinsic
1759+
def int_coro_return : Intrinsic<[llvm_any_ty], [LLVMMatchType<0>], []>;
1760+
17571761
// Coroutine Lowering Intrinsics. Used internally by coroutine passes.
17581762

17591763
def int_coro_subfn_addr : DefaultAttrsIntrinsic<

llvm/lib/AsmParser/LLLexer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,7 @@ lltok::Kind LLLexer::LexIdentifier() {
619619
KEYWORD(x86_regcallcc);
620620
KEYWORD(swiftcc);
621621
KEYWORD(swifttailcc);
622+
KEYWORD(swiftcorocc);
622623
KEYWORD(anyregcc);
623624
KEYWORD(preserve_mostcc);
624625
KEYWORD(preserve_allcc);

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2187,6 +2187,7 @@ void LLParser::parseOptionalDLLStorageClass(unsigned &Res) {
21872187
/// ::= 'ghccc'
21882188
/// ::= 'swiftcc'
21892189
/// ::= 'swifttailcc'
2190+
/// ::= 'swiftcorocc'
21902191
/// ::= 'x86_intrcc'
21912192
/// ::= 'hhvmcc'
21922193
/// ::= 'hhvm_ccc'
@@ -2252,6 +2253,7 @@ bool LLParser::parseOptionalCallingConv(unsigned &CC) {
22522253
case lltok::kw_ghccc: CC = CallingConv::GHC; break;
22532254
case lltok::kw_swiftcc: CC = CallingConv::Swift; break;
22542255
case lltok::kw_swifttailcc: CC = CallingConv::SwiftTail; break;
2256+
case lltok::kw_swiftcorocc: CC = CallingConv::SwiftCoro; break;
22552257
case lltok::kw_x86_intrcc: CC = CallingConv::X86_INTR; break;
22562258
case lltok::kw_hhvmcc:
22572259
CC = CallingConv::DUMMY_HHVM;

llvm/lib/IR/AsmWriter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) {
343343
case CallingConv::SPIR_KERNEL: Out << "spir_kernel"; break;
344344
case CallingConv::Swift: Out << "swiftcc"; break;
345345
case CallingConv::SwiftTail: Out << "swifttailcc"; break;
346+
case CallingConv::SwiftCoro: Out << "swiftcorocc"; break;
346347
case CallingConv::X86_INTR: Out << "x86_intrcc"; break;
347348
case CallingConv::DUMMY_HHVM:
348349
Out << "hhvmcc";

llvm/lib/Transforms/Coroutines/CoroCleanup.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ bool Lowerer::lower(Function &F) {
7272
case Intrinsic::coro_id_async:
7373
II->replaceAllUsesWith(ConstantTokenNone::get(Context));
7474
break;
75+
case Intrinsic::coro_return:
76+
// FIXME: Remove this case with backend support.
77+
II->replaceAllUsesWith(II->getArgOperand(0));
78+
break;
7579
case Intrinsic::coro_subfn_addr:
7680
lowerSubFn(Builder, cast<CoroSubFnInst>(II));
7781
break;

llvm/lib/Transforms/Coroutines/CoroSplit.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1967,7 +1967,34 @@ static void splitRetconCoroutine(Function &F, coro::Shape &Shape,
19671967
RetV = Builder.CreateInsertValue(RetV, ReturnPHIs[I], I);
19681968
}
19691969

1970-
Builder.CreateRet(RetV);
1970+
if (Shape.ABI == coro::ABI::RetconOnceDynamic &&
1971+
F.getCallingConv() == CallingConv::SwiftCoro) {
1972+
// %retval = ...
1973+
// %null_allocator = icmp %1, null
1974+
// br i1 %null_allocator, label %popless, label %normal
1975+
// popless:
1976+
// ret %retval
1977+
// normal:
1978+
// %popless_retval = musttail call i64 @llvm.coro.return(%retval)
1979+
// ret %popless_retval
1980+
auto *NullAllocator = Builder.CreateCmp(
1981+
CmpInst::Predicate::ICMP_EQ, Shape.RetconLowering.Allocator,
1982+
ConstantPointerNull::get(
1983+
cast<PointerType>(Shape.RetconLowering.Allocator->getType())));
1984+
auto *PoplessReturnBB = BasicBlock::Create(
1985+
F.getContext(), "coro.return.popless", &F, NewSuspendBB);
1986+
auto *NormalReturnBB = BasicBlock::Create(
1987+
F.getContext(), "coro.return.normal", &F, NewSuspendBB);
1988+
Builder.CreateCondBr(NullAllocator, PoplessReturnBB, NormalReturnBB);
1989+
IRBuilder<> PoplessBuilder(PoplessReturnBB);
1990+
auto *WrapRetV = PoplessBuilder.CreateIntrinsic(
1991+
RetV->getType(), Intrinsic::coro_return, {RetV});
1992+
PoplessBuilder.CreateRet(WrapRetV);
1993+
IRBuilder<> NormalBuilder(NormalReturnBB);
1994+
NormalBuilder.CreateRet(RetV);
1995+
} else {
1996+
Builder.CreateRet(RetV);
1997+
}
19711998
}
19721999

19732000
// Branch to the return block.

0 commit comments

Comments
 (0)