[llvm-dev] Operand bundles and gc transition arguments

Sanjoy Das via llvm-dev llvm-dev at lists.llvm.org
Wed Oct 14 20:44:03 PDT 2015

As part of adding `"deopt"` operand bundles, we're aiming to change
RewriteStatepointsForGC (called RS4GC henceforth) from rewriting
existing `gc.statepoint` calls to transforming normal LLVM calls and
invokes into `gc.statepoint` calls and invokes (i.e. to do
PlaceSafepoints + RS4GC in one step).  This will make `gc.statepoint`
an artifact of the gc lowering strategy that only appears very late in
the pipeline, and not a generic "meta call".  For us, this opens up
the possibility of making the optimizer work well around calls with
deopt state (e.g. be able to inline through calls with deopt state).

Currently a "non-rewritten" `gc.statepoint` call (i.e. before RS4GC
has run, without explicit relocations) carries two categories of

   1. Deoptimization state.
   2. GC Transition args and StatepointFlags.

Once we have relatively stable[1] support for operand bundles
upstream, LLVM will be able to carry deoptimization state directly on
calls and invokes using a `"deopt"` operand bundle.  This will obviate
reason (1) for keeping non-rewritten `gc.statepoint` s in the IR.
This leaves (2), which I think can be dealt with in three ways:

  a. Change LLILC to emit unmanaged calls with a `"gc-transition"`
     operand bundle holding the transition arguments instead of a
     `gc.statepoint` wrapped call holding them.  RS4GC would then would
     then parse and transcribe that information into the "transition
     args" field of the `gc.statepoint` it creates.

  b. Have an adapter pass that "unwraps" `gc.statepoint` calls into
     normal calls that have whatever transition args the
     `gc.statepoint` had in its `"gc-transition"` operand bundle
     (i.e. "call @gc.statepoint(@f, transition_args={foo, bar})" =>
     "call @f() [ "gc-transition"(foo, bar) ]").  Run this adapter pass
     before RS4GC and keep LLILC unchanged.

  c. Have RS4GC operate in two modes -- a "legacy" mode that works like
     today's RS4GC, and a mode that is operand bundle aware.

Overall, I think (a) will be both faster and more elegant than
(b).  (c) is basically what D13372 does, and I'd strongly prefer not
keeping it in tree long term.

What do you think?  This does not need to be decided / designed
immediately -- we're still several weeks (at least) away from a
stable, working implementation of operand bundles.  But I figured that
it makes sense to start the discussion sooner than later.

[1]: i.e. the optimizer does not miscompile IR with operand bundles

-- Sanjoy

More information about the llvm-dev mailing list