Skip to content

Commit

Permalink
[coro async] Don't promote allocas to the frame or rewrite swifterror…
Browse files Browse the repository at this point in the history
… if there are no suspend points

Also don't call function to update the call graph if there are no
clones. The function will fail.

rdar://74277860

Differential Revision: https://reviews.llvm.org/D96620
  • Loading branch information
aschwaighofer committed Feb 16, 2021
1 parent 8260232 commit 627cfd4
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 3 deletions.
7 changes: 5 additions & 2 deletions llvm/lib/Transforms/Coroutines/CoroFrame.cpp
Expand Up @@ -2219,7 +2219,9 @@ void coro::salvageDebugInfo(
}

void coro::buildCoroutineFrame(Function &F, Shape &Shape) {
eliminateSwiftError(F, Shape);
// Don't eliminate swifterror in async functions that won't be split.
if (Shape.ABI != coro::ABI::Async || !Shape.CoroSuspends.empty())
eliminateSwiftError(F, Shape);

if (Shape.ABI == coro::ABI::Switch &&
Shape.SwitchLowering.PromiseAlloca) {
Expand Down Expand Up @@ -2290,7 +2292,8 @@ void coro::buildCoroutineFrame(Function &F, Shape &Shape) {
}

sinkLifetimeStartMarkers(F, Shape, Checker);
collectFrameAllocas(F, Shape, Checker, FrameData.Allocas);
if (Shape.ABI != coro::ABI::Async || !Shape.CoroSuspends.empty())
collectFrameAllocas(F, Shape, Checker, FrameData.Allocas);
LLVM_DEBUG(dumpAllocas(FrameData.Allocas));

// Collect the spills for arguments and other not-materializable values.
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/Transforms/Coroutines/CoroSplit.cpp
Expand Up @@ -584,6 +584,8 @@ void CoroCloner::replaceCoroEnds() {

static void replaceSwiftErrorOps(Function &F, coro::Shape &Shape,
ValueToValueMapTy *VMap) {
if (Shape.ABI == coro::ABI::Async && Shape.CoroSuspends.empty())
return;
Value *CachedSlot = nullptr;
auto getSwiftErrorSlot = [&](Type *ValueTy) -> Value * {
if (CachedSlot) {
Expand Down Expand Up @@ -1811,7 +1813,8 @@ static void updateCallGraphAfterCoroutineSplit(
case coro::ABI::RetconOnce:
// Each clone in the Async/Retcon lowering references of the other clones.
// Let the LazyCallGraph know about all of them at once.
CG.addSplitRefRecursiveFunctions(N.getFunction(), Clones);
if (!Clones.empty())
CG.addSplitRefRecursiveFunctions(N.getFunction(), Clones);
break;
}

Expand Down
54 changes: 54 additions & 0 deletions llvm/test/Transforms/Coroutines/coro-async.ll
Expand Up @@ -445,6 +445,60 @@ entry:
; CHECK: bitcast i8* %3 to %async.task*
; CHECK: }

@no_coro_suspend_fp = constant <{ i32, i32 }>
<{ i32 trunc ( ; Relative pointer to async function
i64 sub (
i64 ptrtoint (void (i8*)* @no_coro_suspend to i64),
i64 ptrtoint (i32* getelementptr inbounds (<{ i32, i32 }>, <{ i32, i32 }>* @no_coro_suspend_fp, i32 0, i32 1) to i64)
)
to i32),
i32 128 ; Initial async context size without space for frame
}>

define swiftcc void @no_coro_suspend(i8* %async.ctx) {
entry:
%some_alloca = alloca i64
%id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,
i8* bitcast (<{i32, i32}>* @no_coro_suspend_fp to i8*))
%hdl = call i8* @llvm.coro.begin(token %id, i8* null)
call void @some_may_write(i64* %some_alloca)
call i1 (i8*, i1, ...) @llvm.coro.end.async(i8* %hdl, i1 0)
unreachable
}

; CHECK-LABEL: define swiftcc void @no_coro_suspend
; CHECK: [[ALLOCA:%.*]] = alloca i64
; CHECK: call void @some_may_write(i64* {{.*}}[[ALLOCA]])

@no_coro_suspend_swifterror_fp = constant <{ i32, i32 }>
<{ i32 trunc ( ; Relative pointer to async function
i64 sub (
i64 ptrtoint (void (i8*)* @no_coro_suspend_swifterror to i64),
i64 ptrtoint (i32* getelementptr inbounds (<{ i32, i32 }>, <{ i32, i32 }>* @no_coro_suspend_swifterror_fp, i32 0, i32 1) to i64)
)
to i32),
i32 128 ; Initial async context size without space for frame
}>

declare void @do_with_swifterror(i64** swifterror)

define swiftcc void @no_coro_suspend_swifterror(i8* %async.ctx) {
entry:
%some_alloca = alloca swifterror i64*
%id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,
i8* bitcast (<{i32, i32}>* @no_coro_suspend_swifterror_fp to i8*))
%hdl = call i8* @llvm.coro.begin(token %id, i8* null)
store i64* null, i64** %some_alloca, align 8
call void @do_with_swifterror(i64** swifterror %some_alloca)
call i1 (i8*, i1, ...) @llvm.coro.end.async(i8* %hdl, i1 0)
unreachable
}

; CHECK-LABEL: define swiftcc void @no_coro_suspend_swifterror
; CHECK: [[ALLOCA:%.*]] = alloca swifterror i64*
; CHECK: store i64* null, i64** [[ALLOCA]]
; CHECK: call void @do_with_swifterror(i64** {{.*}}swifterror{{.*}} [[ALLOCA]])

declare { i8*, i8*, i8*, i8* } @llvm.coro.suspend.async.sl_p0i8p0i8p0i8p0i8s(i8*, i8*, ...)
declare i8* @llvm.coro.prepare.async(i8*)
declare token @llvm.coro.id.async(i32, i32, i32, i8*)
Expand Down

0 comments on commit 627cfd4

Please sign in to comment.