[llvm] 627cfd4 - [coro async] Don't promote allocas to the frame or rewrite swifterror if there are no suspend points

Arnold Schwaighofer via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 16 09:06:26 PST 2021


Author: Arnold Schwaighofer
Date: 2021-02-16T09:05:38-08:00
New Revision: 627cfd4394b0c4677c8a33338d92bd92101b8ee1

URL: https://github.com/llvm/llvm-project/commit/627cfd4394b0c4677c8a33338d92bd92101b8ee1
DIFF: https://github.com/llvm/llvm-project/commit/627cfd4394b0c4677c8a33338d92bd92101b8ee1.diff

LOG: [coro async] Don't promote allocas to the frame or rewrite  swifterror 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

Added: 
    

Modified: 
    llvm/lib/Transforms/Coroutines/CoroFrame.cpp
    llvm/lib/Transforms/Coroutines/CoroSplit.cpp
    llvm/test/Transforms/Coroutines/coro-async.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index 7ef69c4a9985..b3279bb5dc71 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -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) {
@@ -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.

diff  --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index 04f426db8421..52c06e87c9ff 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -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) {
@@ -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;
     }
 

diff  --git a/llvm/test/Transforms/Coroutines/coro-async.ll b/llvm/test/Transforms/Coroutines/coro-async.ll
index 6114d742575a..aa834052d1ac 100644
--- a/llvm/test/Transforms/Coroutines/coro-async.ll
+++ b/llvm/test/Transforms/Coroutines/coro-async.ll
@@ -445,6 +445,60 @@ entry:
 ; CHECK: bitcast i8* %3 to %async.task*
 ; CHECK: }
 
+ at 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]])
+
+ at 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*)


        


More information about the llvm-commits mailing list