This is an archive of the discontinued LLVM Phabricator instance.

[Inliner] Handle convergence control when inlining a call
ClosedPublic

Authored by sameerds on Jun 8 2023, 2:40 AM.

Details

Summary

When a convergencectrl token is passed to a convergent call, and the called
function in turn calls the entry intrinsic, the intrinsic is now now replaced
with the convergencectrl token.

The spec requires the following check:

A call from function F to function G can be inlined only if:
- at least one of F or G does not make any convergent calls, or,
- both F and G make the same kind of convergent calls: controlled or
  uncontrolled.

But this change does not implement this complete check. A proper implemenation
require a whole new analysis that identifies convergence in every function. For
now, we skip that and just do a cursory check for the entry intrinsic. The
underlying assumption is that in a compiler flow that fully implements
convergence control tokens, there is no mixing of controlled and uncontrolled
convergent operations in the whole program.

This is a reboot of the original change D85606 by
Nicolai Haehnle <nicolai.haehnle@amd.com>.

Diff Detail

Event Timeline

sameerds created this revision.Jun 8 2023, 2:40 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 8 2023, 2:40 AM
sameerds requested review of this revision.Jun 8 2023, 2:40 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 8 2023, 2:40 AM
sameerds added reviewers: nhaehnle, arsenm, foad, ruiling.
sameerds added a subscriber: Restricted Project.
arsenm added inline comments.Jun 8 2023, 1:24 PM
llvm/lib/Analysis/ConvergenceControlUsage.cpp
34 ↗(On Diff #529543)

Don't think you need has_value()

llvm/test/Transforms/Inline/convergence-inline.ll
3

Pre-commit test with baseline checks

102

Don't use branch on undef

107

Add indirect with convergence bundle call? Also a recursive call?

109

Test where a convergent call is passed as an argument to a call that also has a convergence token

sameerds updated this revision to Diff 531600.Jun 14 2023, 8:54 PM
  • rebase
  • add more tests
sameerds marked 4 inline comments as done.Jun 14 2023, 8:57 PM
sameerds added inline comments.
llvm/test/Transforms/Inline/convergence-inline.ll
3

I didn't understand. Without the changes to the inliner, the IR after inlining will fail the verifier in most cases. What would be the value of having such a test?

The proliferation of the ConvergenceControlUsage makes me a bit uncomfortable. It adds the overhead of an additional iteration over entire functions every time a function is inlined or perhaps the inlining is even attempted. And the only thing we get in exchange is a safety check against mixing controlled and uncontrolled convergent operations. Is it really worth it? I'd expect that in general, a compiler either always emits controlled or always emits uncontrolled operations, which means this isn't actually a scenario we need to worry about too much.

llvm/lib/Transforms/Utils/InlineFunction.cpp
2289–2298

This looks like it's making an assumption that the convergence.entry is the very first instruction. Do we really want to enforce that? Definitely needs a verifier check in that case...

sameerds updated this revision to Diff 532785.Jun 19 2023, 10:02 PM
  • rebase
  • eliminate ConvergenceControlUsage
sameerds edited the summary of this revision. (Show Details)Jun 19 2023, 10:07 PM
sameerds marked an inline comment as done.Jun 19 2023, 10:12 PM

The proliferation of the ConvergenceControlUsage makes me a bit uncomfortable. It adds the overhead of an additional iteration over entire functions every time a function is inlined or perhaps the inlining is even attempted. And the only thing we get in exchange is a safety check against mixing controlled and uncontrolled convergent operations. Is it really worth it? I'd expect that in general, a compiler either always emits controlled or always emits uncontrolled operations, which means this isn't actually a scenario we need to worry about too much.

Agreed. I've removed that analysis and replaced it with a simple check that requires a token operand when the called function contains the entry intrinsic. This is clearly incomplete, but a useful check to have. See comments in InlineFunction.cpp and also in the review description.

Just a thought: Eventually, if we do want to disallow inlining in the presence of both kinds of convergence, we could repurpose the convergent attribute by first making all functions convergent by default. Then we can say that uncontrolled convergent calls are only allowed in a function with the "legacy" convergent attribute. The same function cannot contain controlled convergent calls, including the entry intrinsic.

llvm/lib/Transforms/Utils/InlineFunction.cpp
2289–2298

Yes. We enforce it in D147116.

Thanks, I like this much more :)

llvm/lib/Transforms/Utils/InlineFunction.cpp
2289–2298

Okay thanks, I missed that the first time around.

This needs a little more thought on the various getFirstWhatever methods in BasicBlock though. My main immediate concern is with IRBuilder::setInsertPointPastAllocas, which uses BasicBlock::getFirstNonPHIOrDbgOrAlloca. We'd want this to set the insert point past the entry/loop intrinsic and any allocas.

I wouldn't be surprised if some of the other helpers there should also be adjusted -- for example, getFirstInsertionPt -- but that is less clear to me.

sameerds updated this revision to Diff 540891.Jul 17 2023, 1:11 AM
sameerds marked an inline comment as done.
sameerds edited the summary of this revision. (Show Details)
  • rebase
sameerds marked an inline comment as done.Jul 17 2023, 1:16 AM
sameerds added inline comments.
llvm/lib/Transforms/Utils/InlineFunction.cpp
2289–2298

Sure. We want to incorporate the rules for these intrinsics in all the convenient places, we can do that as a follow-up, right? This change solely focuses on inlining of function calls.

arsenm accepted this revision.Aug 15 2023, 10:45 AM
This revision is now accepted and ready to land.Aug 15 2023, 10:45 AM
This revision was automatically updated to reflect the committed changes.
sameerds marked an inline comment as done.