This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Handle gc.relocate(null) in one iteration
ClosedPublic

Authored by skatkov on Mar 4 2020, 2:32 AM.

Details

Summary

InstCombine adds users of transformed instruction to working list to
process on the same iteration. However gc.relocate may have a hidden
user (next gc.relocate) which is connected through gc.statepoint intrinsic and
there is no direct def-use chain between them.

In this case if the next gc.relocation is already processed it will not be added
to worklist and will not be able to be processed on the same iteration.
Let's we have the following case:
A = gc.relocate(null)
B = statepoint(A)
C = gc.relocate(B, hidden(A))
If C is already considered then after replacement of A with null, statepoint B
instruction will be added to the queue but not C.
C can be processed only on the next iteration.

If the chain of relocation is pretty long the many iteration may be required.
This change is to reduce the number of iteration to meet the latest changes
related to reducing infinite loop threshold.

This is a quick (not best) fix. In the follow up patches I plan to move gc relocation
handling into statepoint handler. This should also help to remove unused gc live
entries in statepoint bundle.

Diff Detail

Event Timeline

skatkov created this revision.Mar 4 2020, 2:32 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 4 2020, 2:32 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
skatkov marked an inline comment as done.Mar 4 2020, 2:36 AM
skatkov added inline comments.
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
1818

safe -> save.

skatkov updated this revision to Diff 248132.Mar 4 2020, 2:49 AM

Can gc.relocate(null) be constant folded? I quickly glanced over code and it seems it's not. Could you double-check it?
After quick look through initial worklist construction in AddReachableCodeToWorklist from Transforms/InstCombine/InstructionCombining.cpp, it seems to me that if gc.relocate(null) was constant folded, this problem would not exist.
Am I missed something here?

reames added a comment.Mar 4 2020, 4:23 PM

I don't think this is quite the right factoring, for two reasons:

  1. This applies to the other gc_relocate transforms as well (e.g. undef, non-null, etc..)
  2. This applies in the other direction to a chain of dead gc.relocates. (Actually, it looks like we don't recurse the chain at all?)

I'm not sure on the right approach here. One idea would be to add a gc_statepoint case to the intrinsic switch and phrase many of these transforms as a change to the statepoint operand list. (i.e. we can remove null, undef, and duplicate entries and thus have to renumber gc.relocates.)

One way to think about it is that the "statepoint" is really the whole sequence. And as a result, we're not doing a transform on one instruction at a time, but the whole "unit" of instructions. Not sure I really like that though.

skatkov abandoned this revision.Mar 12 2020, 10:46 PM

Need to think about other approach

skatkov updated this revision to Diff 285004.Aug 12 2020, 1:34 AM
skatkov edited the summary of this revision. (Show Details)

I've updated the patch, please take a look.

reames accepted this revision.Aug 13 2020, 7:44 AM

LGTM

Serguei and I discussed this one fairly extensively offline. Long term, we're probably going to move to a model where we process all of the projections for a statepoint in a single pass when visiting the statepoint, but for the moment, we need to decrease the number of instcombine iterations. In particular, with recent efforts to clamp the number of iterations in debug builds, we are seeing R+A crashes in downstream tests, so this change is really a regression fix.

This revision is now accepted and ready to land.Aug 13 2020, 7:44 AM
This revision was automatically updated to reflect the committed changes.