[llvm-dev] RFC: Coroutine Optimization Passes
David Majnemer via llvm-dev
llvm-dev at lists.llvm.org
Fri Jul 15 10:59:30 PDT 2016
On Thu, Jul 14, 2016 at 9:28 PM, Gor Nishanov <gornishanov at gmail.com> wrote:
> Hi David:
> >> How do you deal with basic blocks which appear to be used by multiple
> >> of the coroutine? We handled this in WinEHPrepare by cloning any BBs
> >> were shared.
> I experimented with several approaches, but, cloning ended up being the
> and most reliable. Suspend points express three different control flows
> can happen at the suspend point: a suspension (default), resumption (0) and
> destruction (1).
> %0 = call i8 @llvm.coro.suspend([..])
> switch i8 %0, label %suspend [i8 0, label %resume,
> i8 1, label %destroy]
> I slap a switch that jumps to all suspend points in the function. Then I
> the function twice (one will become resume clone, and another destroy
> This switch becomes the entry block in the clones. Then, I RAUW
> with -1, 0, or 1 (in original, resume and destroy clones respectively) and
> SimplifyCFG do the rest. (This is slightly simplified explanation, but it
> give the idea).
I like it, sounds nice and simple :)
> >> I would remove the attribute. There are all sorts of tricks you can do
> >> avoid scanning the function for calls to the intrinsic. For example,
> >> can see if a declaration of your intrinsic exists and, if so, if it has
> >> users in the function in question (under the assumption that there are
> Aye-aye. Will remove the attribute.
> With respect to lessening the impact of coroutine passes, one approach I
> was to look during doInitialize whether there are any uses of coroutine
> intrinsics and set a flag if there are any, or maybe build a set of
> with coroutines intrinsics in doInitialize, so that in runOnFunction, I
> can just
> check whether the function is in the set and skip if it is not.
> Then, I scared myself silly that some optimization passes can materialize
> new functions or new function bodies and I will miss them. So I stopped
> I think your approach takes care of my "materialization" concern. (BTW, I
> even know if that is a real concern).
Functions can be created from nothing in LLVM.
> But may not be profitable if there are a
> lot of small functions that are faster to scan for coroutine intrinsics
> then to
> scan potentially longer list of coroutine intrinsics users.
I find that unlikely but we can always benchmark it if we get concerned.
I'd use a naive approach to start out with.
If it shows up on profiles, we can optimize it.
> BTW, Do you have a preference on how to restart CGSCC pipeline? One of the
> options I listed (repeated in P.S), or even some better way I did not think
I'm not an expert in that area. I think you will want someone like
Chandler or Hal to give advice here.
> Thank you,
> Option 1: https://reviews.llvm.org/D21569 (no longer relevant, since we
> removing AttrKind::Coroutine)
> Option 2: https://reviews.llvm.org/D21570 (bool& Devirt in runSCC)
> Option 3: https://reviews.llvm.org/D21572 (virtual bool
> Option 4: Fake devirtualized call in a function pass, so that RefreshSCC
> detect devirtualization and restart the pipeline by itself.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the llvm-dev