This is an archive of the discontinued LLVM Phabricator instance.

[PlaceSafepoints] Introduce a -spp-no-statepoints flag
ClosedPublic

Authored by sanjoy on Jan 21 2016, 6:50 PM.

Details

Summary

This change adds a -spp-no-statepoints flag to PlaceSafepoints that
bypasses the code that wraps newly introduced polls and existing calls
in gc.statepoint. With -spp-no-statepoints enabled, PlaceSafepoints
effectively becomes a safpeoint poll insertion pass.

The eventual goal is to "constant fold" this option, along with
-rs4gc-use-deopt-bundles to true, once clients using gc.statepoint
are okay doing so.

Diff Detail

Repository
rL LLVM

Event Timeline

sanjoy updated this revision to Diff 45636.Jan 21 2016, 6:50 PM
sanjoy retitled this revision from to [PlaceSafepoints] Introduce a -spp-no-statepoints flag.
sanjoy updated this object.
sanjoy added reviewers: pgavlin, reames, JosephTremoulet.
sanjoy added a subscriber: llvm-commits.
reames edited edge metadata.Jan 22 2016, 10:02 AM

Sanjoy, I don't see anything wrong with this patch per say, but I'm a bit confused about how you're expecting this to fit together with RS4GC. That pass currently has two modes, one which consumes statepoints, and one which consumes calls with deopt. You don't seem to be emitting either form here. What am I missing?

Sanjoy, I don't see anything wrong with this patch per say, but I'm a bit confused about how you're expecting this to fit together with RS4GC. That pass currently has two modes, one which consumes statepoints, and one which consumes calls with deopt. You don't seem to be emitting either form here. What am I missing?

That's a really good question.

For environments that don't care about deoptimization at all (which I
think includes LLILC), RS4GC can be run with
-rs4gc-allow-statepoint-with-no-deopt-info. Then RS4GC will work as
expected with calls / invokes with no "deopt" operand bundles
(i.e. the deopt section in the gc.statepoints it creates will be empty
for such calls).

Environments that do care about deoptimization and want to run
PlaceSafepoints will have to provide their own deopt info, and attach
them to all non-leaf calls including the call in the safepoint poll
slow path, if there is one. For sanity checking, in these cases we
should set -rs4gc-allow-statepoint-with-no-deopt-info to false
(unless not having deopt info for some gc.statepoint is actually a
valid thing to do in this case).

And the third possibility is to not use PlaceSafepoints at all, and
instead emit all safepoint polls early (with appropriate deopt state),
and have an optimization pass remove unnecessary polls as appropriate;
and run RS4GC afterwards. For some strange reason, this third
approach sounds very familiar. :)

Are there other possibilities that you can think of?

Sanjoy, I don't see anything wrong with this patch per say, but I'm a bit confused about how you're expecting this to fit together with RS4GC. That pass currently has two modes, one which consumes statepoints, and one which consumes calls with deopt. You don't seem to be emitting either form here. What am I missing?

That's a really good question.

For environments that don't care about deoptimization at all (which I
think includes LLILC), RS4GC can be run with
-rs4gc-allow-statepoint-with-no-deopt-info. Then RS4GC will work as
expected with calls / invokes with no "deopt" operand bundles
(i.e. the deopt section in the gc.statepoints it creates will be empty
for such calls).

Environments that do care about deoptimization and want to run
PlaceSafepoints will have to provide their own deopt info, and attach
them to all non-leaf calls including the call in the safepoint poll
slow path, if there is one. For sanity checking, in these cases we
should set -rs4gc-allow-statepoint-with-no-deopt-info to false
(unless not having deopt info for some gc.statepoint is actually a
valid thing to do in this case).

And the third possibility is to not use PlaceSafepoints at all, and
instead emit all safepoint polls early (with appropriate deopt state),
and have an optimization pass remove unnecessary polls as appropriate;
and run RS4GC afterwards. For some strange reason, this third
approach sounds very familiar. :)

Are there other possibilities that you can think of?

Hm, the proliferation of options here doesn't seem like a good thing.

What is we tried the following:

  • PlaceSafepoints *only* inserts calls to poll functions. No statepoints at all. (i.e. mostly this patch, but make it unconditional)
  • RS4GC excepts only calls, optionally with deopt info. We completely drop the old statepoint input case. We allow GC's to opt into a requirement that all calls have deopt operands via a predicate on the gc name (and eventually, the strategy).

I'm also wondering if we should upstream the optimize poll placement pass we have (since it shares so much with PlaceSafepoints) and gut the smarts from PlaceSafepoints. We could either have both passes call the same logic, or simply run one after the other. I'm really bothered by the code duplication here. I understand your argument (previously) that late insertion is better for folks who don't have deopt, but I'm bugged by the divergent code it has caused.

Sanjoy, I don't see anything wrong with this patch per say, but I'm a bit confused about how you're expecting this to fit together with RS4GC. That pass currently has two modes, one which consumes statepoints, and one which consumes calls with deopt. You don't seem to be emitting either form here. What am I missing?

That's a really good question.

For environments that don't care about deoptimization at all (which I
think includes LLILC), RS4GC can be run with
-rs4gc-allow-statepoint-with-no-deopt-info. Then RS4GC will work as
expected with calls / invokes with no "deopt" operand bundles
(i.e. the deopt section in the gc.statepoints it creates will be empty
for such calls).

Environments that do care about deoptimization and want to run
PlaceSafepoints will have to provide their own deopt info, and attach
them to all non-leaf calls including the call in the safepoint poll
slow path, if there is one. For sanity checking, in these cases we
should set -rs4gc-allow-statepoint-with-no-deopt-info to false
(unless not having deopt info for some gc.statepoint is actually a
valid thing to do in this case).

And the third possibility is to not use PlaceSafepoints at all, and
instead emit all safepoint polls early (with appropriate deopt state),
and have an optimization pass remove unnecessary polls as appropriate;
and run RS4GC afterwards. For some strange reason, this third
approach sounds very familiar. :)

Are there other possibilities that you can think of?

Hm, the proliferation of options here doesn't seem like a good thing.

What is we tried the following:

  • PlaceSafepoints *only* inserts calls to poll functions. No statepoints at all. (i.e. mostly this patch, but make it unconditional)

Yes, that's the eventual goal, as stated in the commit message. But I
want to give the LLILC developers a chance to

a. Test that this new pass pipeline works for them
b. Change the frontend to emit gc-transition arguments as operand bundles

  • RS4GC excepts only calls, optionally with deopt info. We completely drop the old statepoint input case. We allow GC's to opt into a requirement that all calls have deopt operands via a predicate on the gc name (and eventually, the strategy).

+1

I'm also wondering if we should upstream the optimize poll placement pass we have (since it shares so much with PlaceSafepoints) and gut the smarts from PlaceSafepoints. We could either have both passes call the same logic, or simply run one after the other. I'm really bothered by the code duplication here. I understand your argument (previously) that late insertion is better for folks who don't have deopt, but I'm bugged by the divergent code it has caused.

I think there is a possibility to have this upstream PlaceSafepoints
and the to-be-upstream-now-downstream OptimizeSafepointPolls pass
share code i.e. despite being logically different optimization
passes, they could call into a unified set of helper routines.

reames accepted this revision.Jan 22 2016, 12:42 PM
reames edited edge metadata.

With the explanation of overall direction, LGTM.

FYI, when you get back to switching the default, you'll need to port all the tests to the new output format.

lib/Transforms/Scalar/PlaceSafepoints.cpp
670 ↗(On Diff #45636)

I would like to see a bit more context here. In particular, we expect this to become the default, and that rs4gc will take over this responsibility.

This revision is now accepted and ready to land.Jan 22 2016, 12:42 PM
This revision was automatically updated to reflect the committed changes.
pgavlin edited edge metadata.Jan 22 2016, 1:07 PM

The mechanics look good to me as well. Thanks for the edifying discussion, too :)