[PATCH] D23117: [coroutines] Part 4b: Coroutine Devirtualization: Handle unwinding coro.resume and coro.destroy.

Gor Nishanov via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 3 04:30:07 PDT 2016


GorNishanov created this revision.
GorNishanov added a reviewer: majnemer.
GorNishanov added a subscriber: llvm-commits.
GorNishanov set the repository for this revision to rL LLVM.
Herald added subscribers: mehdi_amini, sanjoy.

This is the 4b patch in the coroutine series. CoroEaly pass now can lower coro.resume and coro.destroy intrinsics called via InvokeInst.

Documentation and overview is here: http://llvm.org/docs/Coroutines.html.

Upstreaming sequence (rough plan):

1. Add documentation. (https://reviews.llvm.org/D22603)
2. Add coroutine intrinsics. (https://reviews.llvm.org/D22659)
3. Add empty coroutine passes. (https://reviews.llvm.org/D22847)
4. Add coroutine devirtualization + tests.
a) Lower coro.resume and coro.destroy (https://reviews.llvm.org/D22998)
b) Handle invoke resumers  <= we are here
c) Do devirtualization
5. Add CGSCC restart trigger + tests.
6. Add coroutine heap elision + tests.
7. Add the rest of the logic (split into more patches)


Repository:
  rL LLVM

https://reviews.llvm.org/D23117

Files:
  lib/IR/Verifier.cpp
  lib/Transforms/Coroutines/CoroEarly.cpp
  test/Transforms/Coroutines/coro-early.ll

Index: test/Transforms/Coroutines/coro-early.ll
===================================================================
--- test/Transforms/Coroutines/coro-early.ll
+++ test/Transforms/Coroutines/coro-early.ll
@@ -20,5 +20,22 @@
 ; CHECK-NEXT: ret void
 }
 
+; CHECK-LABEL: @eh
+define void @eh(i8* %hdl) personality i8* null {
+; CHECK-NEXT: entry
+entry:
+;  CHECK-NEXT: %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
+;  CHECK-NEXT: %1 = bitcast i8* %0 to void (i8*)*
+;  CHECK-NEXT: invoke fastcc void %1(i8* %hdl)
+  invoke void @llvm.coro.resume(i8* %hdl)
+          to label %cont unwind label %ehcleanup
+cont:
+  ret void
+
+ehcleanup:
+  %0 = cleanuppad within none []
+  cleanupret from %0 unwind to caller
+}
+
 declare void @llvm.coro.resume(i8*)
 declare void @llvm.coro.destroy(i8*)
Index: lib/Transforms/Coroutines/CoroEarly.cpp
===================================================================
--- lib/Transforms/Coroutines/CoroEarly.cpp
+++ lib/Transforms/Coroutines/CoroEarly.cpp
@@ -61,7 +61,30 @@
         break;
       }
       Changed = true;
+      continue;
     }
+
+    // The coro.resume and coro.destroy may be called via Invoke Instruction,
+    // and won't be lowered by the code above.
+
+    auto Inv = dyn_cast<InvokeInst>(&I);
+    if (!Inv)
+      continue;
+    auto CalledFn = Inv->getCalledFunction();
+    if (!CalledFn)
+      continue;
+    StringRef Name = CalledFn->getName();
+    if (!Name.startswith("llvm.coro"))
+      continue;
+    if (Name == CORO_RESUME_STR) {
+      lowerResumeOrDestroy(Inv, CoroSubFnInst::ResumeIndex);
+    } else {
+      assert(Name == CORO_DESTROY_STR && "Cannot invoke coroutine intrinsic "
+                                         "other than coro.resume and "
+                                         "coro.destroy");
+      lowerResumeOrDestroy(Inv, CoroSubFnInst::DestroyIndex);
+    }
+    Changed = true;
   }
   return Changed;
 }
Index: lib/IR/Verifier.cpp
===================================================================
--- lib/IR/Verifier.cpp
+++ lib/IR/Verifier.cpp
@@ -3653,11 +3653,13 @@
       Assert(
           !F->isIntrinsic() || isa<CallInst>(I) ||
               F->getIntrinsicID() == Intrinsic::donothing ||
+              F->getIntrinsicID() == Intrinsic::coro_resume ||
+              F->getIntrinsicID() == Intrinsic::coro_destroy ||
               F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void ||
               F->getIntrinsicID() == Intrinsic::experimental_patchpoint_i64 ||
               F->getIntrinsicID() == Intrinsic::experimental_gc_statepoint,
-          "Cannot invoke an intrinsic other than donothing, patchpoint or "
-          "statepoint",
+          "Cannot invoke an intrinsic other than donothing, patchpoint, "
+          "statepoint, coro_resume or coro_destroy",
           &I);
       Assert(F->getParent() == M, "Referencing function in another module!",
              &I, M, F, F->getParent());


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D23117.66644.patch
Type: text/x-patch
Size: 2951 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160803/bc214313/attachment.bin>


More information about the llvm-commits mailing list