[PATCH] D25543: [coroutines] Add handling for unwind coro.ends

Gor Nishanov via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 12 19:06:18 PDT 2016


GorNishanov created this revision.
GorNishanov added a reviewer: majnemer.
GorNishanov added a subscriber: llvm-commits.
Herald added a subscriber: mehdi_amini.

The purpose of coro.end intrinsic is to allow frontends to mark the cleanup and
other code that is only relevant during the initial invocation of the coroutine
and should not be present in resume and destroy parts.

In landing pads coro.end is replaced with an appropriate instruction to unwind to 
caller. The handling of coro.end differs depending on whether the target is 
using landingpad or WinEH exception model.

For landingpad based exception model, it is expected that frontend uses the 
`coro.end`_ intrinsic as follows:

  ehcleanup:
    %InResumePart = call i1 @llvm.coro.end(i8* null, i1 true)
    br i1 %InResumePart, label %eh.resume, label %cleanup.cont
  
  cleanup.cont:
    ; rest of the cleanup
  
  eh.resume:
    %exn = load i8*, i8** %exn.slot, align 8
    %sel = load i32, i32* %ehselector.slot, align 4
    %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn, 0
    %lpad.val29 = insertvalue { i8*, i32 } %lpad.val, i32 %sel, 1
    resume { i8*, i32 } %lpad.val29

The `CoroSpit` pass replaces `coro.end` with ``True`` in the resume functions,
thus leading to immediate unwind to the caller, whereas in start function it
is replaced with ``False``, thus allowing to proceed to the rest of the cleanup
code that is only needed during initial invocation of the coroutine.

For Windows Exception handling model, a frontend should attach a funclet bundle
referring to an enclosing cleanuppad as follows:

  ehcleanup: 
    %tok = cleanuppad within none []
    %unused = call i1 @llvm.coro.end(i8* null, i1 true) [ "funclet"(token %tok) ]
    cleanupret from %tok unwind label %RestOfTheCleanup

The `CoroSplit` pass, if the funclet bundle is present, will insert 
``cleanupret from %tok unwind to caller`` before
the `coro.end`_ intrinsic and will remove the rest of the block.


https://reviews.llvm.org/D25543

Files:
  docs/Coroutines.rst
  include/llvm/IR/Intrinsics.td
  lib/Transforms/Coroutines/CoroSplit.cpp
  test/Transforms/Coroutines/ArgAddr.ll
  test/Transforms/Coroutines/coro-split-00.ll
  test/Transforms/Coroutines/coro-split-01.ll
  test/Transforms/Coroutines/coro-split-02.ll
  test/Transforms/Coroutines/coro-split-dbg.ll
  test/Transforms/Coroutines/coro-split-eh.ll
  test/Transforms/Coroutines/ex0.ll
  test/Transforms/Coroutines/ex1.ll
  test/Transforms/Coroutines/ex2.ll
  test/Transforms/Coroutines/ex3.ll
  test/Transforms/Coroutines/ex4.ll
  test/Transforms/Coroutines/ex5.ll
  test/Transforms/Coroutines/no-suspend.ll
  test/Transforms/Coroutines/phi-coro-end.ll
  test/Transforms/Coroutines/restart-trigger.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D25543.74468.patch
Type: text/x-patch
Size: 24042 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161013/ee4c8489/attachment.bin>


More information about the llvm-commits mailing list