[llvm-dev] Fwd: [RFC] LLVM Coroutines

Eli Friedman via llvm-dev llvm-dev at lists.llvm.org
Thu Jun 9 13:49:21 PDT 2016

On Thu, Jun 9, 2016 at 1:17 PM, Gor Nishanov <gornishanov at gmail.com> wrote:

> Hi Eli:
> > That said, thinking about it a bit more, I'm not really sure why you
> need to
> > tie the suspend call to the branch in the first place.
> I am not sure I understand the question. Suspend intrinsic is replaced with
> a branch to a return block in the 'f' and with 'ret void' in resume.

Right... but that doesn't mean the call to the suspend intrinsic has to be
the last non-terminator instruction in the basic block before you run
CoroSplit.  You can split the basic block in CoroSplit so any instructions
after the suspend call are part of a different basic block.  Then resume
and destroy both branch to the continuation of the basic block (and run
different codepaths based on the boolean).

> What exactly is your algorithm doing that requires it?  I mean, a naive
> > implementation of CoroSplit based on your llvm.experimental.coro.suspend
> > intrinsic clones the whole function, replaces the result of suspend calls
> > with "true" in one version and "false" in the other, and runs SimplifyCFG
> > to kill the dead code.
> Very close. We do clone function body twice, once for resume and once for
> destroy. We make a new entry block with a switch instruction that will
> branch to
> all resume branches in `f.resume` and to all cleanup branches in
> `f.destroy` and
> then let SimplifyCFG to remove the rest.

Okay, that helps me visualize it.

Changing the subject a little bit. I was thinking we can get rid of the
> coro.fork altogether it we add a third label to the corosuspend.
> Namely:
>   corosuspend [final] [save %token] to label %return.block
>     resume label %resume
>     cleanup label %cleanup
> corosuspend is lowered as follows:
>   in 'f': corosuspend is replaced with `br %return.block`
>   in 'f.resume':
>     add a new entry block with a switch jumping to all resume blocks
>     corosuspend is replaced with `ret void`
>   in 'f.destroy':
>     add a new entry block with a switch jumping to all cleanup blocks
>     corosuspend is replaced with `ret void`
> I think this makes understanding of the model clearer. The only negative
> side
> to a corosuspend with three branching targets is that it is very likely
> that
> to label block will be the same in all corosuspend's thus wasting valuable
> bits. :-)

Yes, this makes sense.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160609/ff236c00/attachment.html>

More information about the llvm-dev mailing list