This is an archive of the discontinued LLVM Phabricator instance.

[coroutines] Add handling for unwind coro.ends
ClosedPublic

Authored by GorNishanov on Oct 12 2016, 7:06 PM.

Details

Summary

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.

Diff Detail

Event Timeline

GorNishanov retitled this revision from to [coroutines] Add handling for unwind coro.ends.
GorNishanov updated this object.
GorNishanov added a reviewer: majnemer.
GorNishanov added a subscriber: llvm-commits.
majnemer accepted this revision.Oct 27 2016, 10:07 AM
majnemer edited edge metadata.

LGTM

This revision is now accepted and ready to land.Oct 27 2016, 10:07 AM
GorNishanov edited edge metadata.

merge with top of the trunk. Preparing to land.

This revision was automatically updated to reflect the committed changes.