This is an archive of the discontinued LLVM Phabricator instance.

[Statepoints] Reuse stack slots for assignment idioms
AbandonedPublic

Authored by reames on Jun 11 2015, 2:19 PM.

Details

Summary

Reading over @igor's changes in 239472, it hit me that the same scheme could be easily extended to implement one of the existing TODOs in the lowering code.

If we have an idiom that looks like assignment (i.e. a new SSA value produced from some operation where it's input is no longer used), we can reuse the stack slot of the original SSA value for the updated value. This works really nicely for GEPs on x86 because we can use an update directly against the stack slot and avoid a fill, modify, spill pattern entirely.

It doesn't work quite as cleanly for deoptimization arguments, mostly because the original spill slot is not reused for the update. I suspect this might be because we're marking the slot as being updated by the previous statepoint, but I decided to separate that into a separate patch. We at least get better stack slot usage, even if we don't yet get ideal code gen.

(The best option would of course be to directly use the register allocator, but a) that's hard, and b) this is an incremental improvement.)

Diff Detail

Event Timeline

reames updated this revision to Diff 27543.Jun 11 2015, 2:19 PM
reames retitled this revision from to [Statepoints] Reuse stack slots for assignment idioms.
reames updated this object.
reames edited the test plan for this revision. (Show Details)
reames added reviewers: igor-laevsky, sanjoy, pgavlin.
reames added subscribers: Unknown Object (MLST), igor.
igor-laevsky edited edge metadata.EditedJun 11 2015, 3:09 PM

Do I understand correctly that you have relaxed constraints on findPreviousSpillSlot to return location which does not necessarily contains requested value? If so, maybe it's better to rename it? Something like findPreferredSpillSlot.

Also with this approach we can do better for phi nodes. When visiting phi node we can return known location even if some of the phi node branches are unknown. There is TODO for this somewhere in findPreviousSpillSlot. Not sure how profitable it would be though.

lib/CodeGen/SelectionDAG/StatepointLowering.cpp
422–424

Are you certain about this? I do remember experimenting with this approach, but I was seeing quite the opposite picture - almost no redundant stores were removed. But actually it was quite a while ago and I didn't dig to deep into this, maybe my code had some simple mistake. I will try to run few of my old tests on your code tomorrow.

test/CodeGen/X86/statepoint-stack-usage.ll
98

Is that different from back_to_back_calls test?

igor-laevsky added inline comments.Jun 12 2015, 8:37 AM
lib/CodeGen/SelectionDAG/StatepointLowering.cpp
422–424

Yes, as I suspected there is little llvm can do about this redundant stores. Actually from quick glance at the code I don't see place in llvm where it removes dead stores in machine code. There is small function in StackSlotColoring, but it is very limited. MachineCSE and RemoveDeadInstructions explicitly discard all mayStore values.

I am wondering is there any good reason why there is no dead store elimination for the machine code? In theory it should not be very hard to implement.

test/CodeGen/X86/statepoint-stack-usage.ll
137

This actually passes even without your changes. Maybe add some additional oops to the second statepoint, so that by default we would assign different slots for a1 and a1_derived.

@igor - Your restatement is correct. I like your idea of renaming the method, but I hadn't really come up with a great name. As your follow on question about PHIs points out, the current notion is actually stronger than just "preferred". It's more like "preferred so strongly that there can't be a better slot to pick".

Hm, I think I just understood your question about phis after writing that. Were you intending to say that we could special case PHIs where exactly one input had a spill slot assigned and that input's only use is the phi? That avoids the problem of picking one spill slot when multiple are available. Might be worth exploring in a future change.

w.r.t. your comments about DSE, no, I'm not really sure. :) I may be utterly wrong in fact. Having said that, non of the existing test cases break with this change and I didn't see any differences in codegen for the example I happened to look at. I'll revert this part of the patch, but I'll have to introduce another data structure to do it. Can I ask you to submit a test which would have caught this?

@igor - Your restatement is correct. I like your idea of renaming the method, but I hadn't really come up with a great name. As your follow on question about PHIs points out, the current notion is actually stronger than just "preferred". It's more like "preferred so strongly that there can't be a better slot to pick".

Maybe findBestSpillSlot? Or findOptimalSpillSlot.

Hm, I think I just understood your question about phis after writing that. Were you intending to say that we could special case PHIs where exactly one input had a spill slot assigned and that input's only use is the phi? That avoids the problem of picking one spill slot when multiple are available. Might be worth exploring in a future change.

Yes, that's correct. However we don't need to special case only two entry phi nodes. Condition could be "spill slots for all incoming values are same, but some might be unknown". (Currently it is "spill slots for all incoming values are known and same")

w.r.t. your comments about DSE, no, I'm not really sure. :) I may be utterly wrong in fact. Having said that, non of the existing test cases break with this change and I didn't see any differences in codegen for the example I happened to look at. I'll revert this part of the patch, but I'll have to introduce another data structure to do it. Can I ask you to submit a test which would have caught this?

I submitted test case in r239842.

reames abandoned this revision.Aug 26 2015, 4:28 PM

I may come back to this at some point, but I can't justify the time now or any time in the near future.