This is an archive of the discontinued LLVM Phabricator instance.

[RS4GC] Use "deopt" operand bundles
ClosedPublic

Authored by sanjoy on Oct 1 2015, 6:37 PM.

Details

Summary

This is a step towards using operand bundles to carry deopt state till
RewriteStatepointsForGC. The change adds a flag to
RewriteStatepointsForGC that teaches it to pick up deopt state from a
"deopt" operand bundle attached to the call or invoke it is
wrapping.

The command line flag added, -rs4gc-use-deopt-bundles, will only exist
for a short while. Once we are able to pipe deopt bundle state through
the full optimization pipeline without problems, we will "constant fold"
-rs4gc-use-deopt-bundles to true.

Diff Detail

Repository
rL LLVM

Event Timeline

sanjoy updated this revision to Diff 36327.Oct 1 2015, 6:37 PM
sanjoy retitled this revision from to [RewriteStatepointsForGC] Use "deopt" operand bundles.
sanjoy updated this object.
sanjoy added reviewers: reames, swaroop.sridhar.
sanjoy added a subscriber: llvm-commits.
sanjoy updated this revision to Diff 36574.Oct 5 2015, 5:23 PM

Add test cases and do what it takes to get them to pass:

  • The tests were ported automatically, so there may be some skew in the ; CHECK lines. I'll audit them before checking in, but please comment if you find some obvious goof-up.
  • This change fixes a bug in the earlier version of this change: if the return value of a function being wrapped in gc.statepoint is itself live over some safepoint, we cannot just RAUW / erase that function call because we may have a raw pointer to it in some PartiallyConstructedSafepointRecord. This updated change fixes this issue by deferring the RAUW and erase from parent till after the live sets have been made explicit in the IR.

PS: while this update is not logically distinct from change it is
updating, I can separate out the update into a separate change if you
think that will make the review easier.

reames edited edge metadata.Oct 6 2015, 3:40 PM

There's enough changing in this diff that I can't really get a sense for what's going on. I'm going to need you to split this up a bit. There appear to be a couple of refactorings hidden within this patch. Please separate them and submit them.

lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
168 ↗(On Diff #36574)

Changing to an AssertVH is a refactoring, please separate.

193 ↗(On Diff #36574)

This is the same as isGCLeafFunction in PlaceSafepoints. Pull into a common utility file. /Utils/Local.h?

212 ↗(On Diff #36574)

This feels like a missing function on CallSite. getOperandBundle(Name)?

1370 ↗(On Diff #36574)

This bit really confused me. Refactoring? Or something subtle that's not documented/explained?

1446 ↗(On Diff #36574)

This section is a refactoring, please separate.

sanjoy retitled this revision from [RewriteStatepointsForGC] Use "deopt" operand bundles to [RS4GC] Use "deopt" operand bundles.Oct 6 2015, 5:14 PM
sanjoy edited edge metadata.
sanjoy updated this revision to Diff 36692.Oct 6 2015, 5:39 PM
  • extract out most of the non-semantic refactoring to make this change simpler
sanjoy updated this revision to Diff 36693.Oct 6 2015, 5:54 PM
  • add a comment

Mostly minor comments. Question about transition args is potentially not minor.

lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
1354 ↗(On Diff #36693)

This comment could be far clearer. I shouldn't have to go look at what perform does to understand the purpose of the class.

1362 ↗(On Diff #36693)

add assert Old != New.

1364 ↗(On Diff #36693)

minor: The common name for this would be something like "do".

1414 ↗(On Diff #36693)

Does this mean that to support the MSFT guys, we're going to need both code paths for a while to come? I think it does.

1530 ↗(On Diff #36693)

Sinking these asserts into the else clause would be far more clear.

1543 ↗(On Diff #36693)

We've already taken the name for the token above. This needs adjusted for the new location.

1555 ↗(On Diff #36693)

Wait, what? Oh, your replacements also does deletion. Got it. Slightly confusing.

1561 ↗(On Diff #36693)

I believe both schemes could use the deferred update safely for the record. Less divergent code.

2415 ↗(On Diff #36693)

You need a comment here about what this is and why it's needed.

2429 ↗(On Diff #36693)

Followed by: clear replacements

2436 ↗(On Diff #36693)

Any reason this can't be done immediate after inserting the statepoint? Having it in the next loop after the replacements makes me think there's a reason for that?

test/Transforms/RewriteStatepointsForGC/deopt-bundles/base-pointers-1.ll
1 ↗(On Diff #36693)

I am really buged by the fact that you need to duplicate all the test cases like this. I don't have a good alternative other than what we've already discussed, but I'm worried this is a sign of poor factoring in the code.

reames requested changes to this revision.Oct 8 2015, 10:21 AM
reames edited edge metadata.
This revision now requires changes to proceed.Oct 8 2015, 10:21 AM
sanjoy updated this revision to Diff 37434.Oct 14 2015, 6:48 PM
sanjoy edited edge metadata.
sanjoy marked 8 inline comments as done.
  • address review. Note that some names have changed because I changed how I named Token when using deopt bundles.
lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
1354 ↗(On Diff #36692)

There's a comment on why this is needed before the Replacements.emplace_back(CS.getInstruction(), GCResult); bit.

1364 ↗(On Diff #36693)

Renamed to doReplacement.

1414 ↗(On Diff #36693)

We need to have a discussion about this (I'll send out an email shortly); but yes, we'll have to keep both paths till LLILC is able to generate "gc-transition" operand bundles. I think the changes to LLILC should be fairly minimal (and will probably actually reduce complexity in LLILC), but this is really gated on us bringing operand bundles to an adequate level of stability.

1555 ↗(On Diff #36693)

Mentioned that in the comment.

1561 ↗(On Diff #36693)

I agree that it would be correct to have both schemes to use DeferredReplacement; but I suspect that will be more confusing to read since in one case we'd replace one token with another, whereas in the other case we'd replace a normal return value with gc_result (so there will be some divergent code anyway).

sanjoy updated this object.Oct 15 2015, 3:23 PM
sanjoy edited edge metadata.
reames accepted this revision.Oct 15 2015, 3:42 PM
reames edited edge metadata.

LGTM w/minor comments. My concern about test duplication still stands, but given this is a temporary step, I'm okay with it for a short period.

lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
79 ↗(On Diff #37434)

I think this needs to default to true.

1416 ↗(On Diff #37434)

Add a TODO please.

This revision is now accepted and ready to land.Oct 15 2015, 3:42 PM
sanjoy marked 2 inline comments as done.Oct 15 2015, 6:14 PM
This revision was automatically updated to reflect the committed changes.