This is an archive of the discontinued LLVM Phabricator instance.

[GlobalISel] Add a new IR canonicalization pass
AbandonedPublic

Authored by aemerson on Sep 11 2018, 3:00 PM.

Details

Summary

This pass is intended to contain IR transformations to make GlobalISel more effective, even running at -O0.

Motivated by discussions on D51362

The only canonicalization done in this initial version is swapping of icmp operands to ensure constants are on the RHS.

Diff Detail

Repository
rL LLVM

Event Timeline

aemerson created this revision.Sep 11 2018, 3:00 PM

Hi Amara,

Thanks for putting this up.

I like the general approach.

Couple of open questions:

  • Given this is canonicalization as opposed to optimization, shouldn't this be mandatory? I.e., if GISel runs, this runs. Alternatively, should we use another name not to imply this is mandatory (like beautification, I know this is ugly :P).
  • Given this runs on IR, I assume we won't need something similar at the MIR level, is that correct?
  • Given this runs on IR, I am guessing there are/will be some redundant code with InstCombine. Could/should we move the core of the logic in a separate library/file that could be called directly by this pass and InstCombine.
  • This kind of canonicalization could be useful to other ISels, should we make this a mandatory pass period? I.e., not tie to GISel at all.

Cheers,
-Quentin

Hi Quentin,

Thanks for taking a look.

  • Given this is canonicalization as opposed to optimization, shouldn't this be mandatory? I.e., if GISel runs, this runs. Alternatively, should we use another name not to imply this is mandatory (like beautification, I know this is ugly :P).

Are you referring to the enable-gisel-canonicalize option? I can remove that to force it to always run when GISel does, it's just an old habit of mine to add toggle flags for new passes.

  • Given this runs on IR, I assume we won't need something similar at the MIR level, is that correct?

Not that I can see. There may be cases where we need to re-do canonicalization if legalizer breaks it, but as we discussed we should try to fix that in the offending passes if possible.

  • Given this runs on IR, I am guessing there are/will be some redundant code with InstCombine. Could/should we move the core of the logic in a separate library/file that could be called directly by this pass and InstCombine.

Perhaps, for this particular case it's less code to just do it manually since it's almost trivial. I think if we wanted to share the code in future then we'd need to create a new library, to prevent LLVMCodeGen having to depend on LLVMInstCombine which would be weird.

  • This kind of canonicalization could be useful to other ISels, should we make this a mandatory pass period? I.e., not tie to GISel at all.

Maybe, but we don't have a real motivating use case right now. SelectionDAG already handles the compare immediate case already at -O0. -O0 canonicalizations is where I see this being most useful in order to be on par with the other ISels, and at higher opt levels we can rely on instcombine to do most of it.

Cheers,
-Quentin

qcolombet accepted this revision.Sep 13 2018, 9:45 AM

Hi Amara,

Are you referring to the enable-gisel-canonicalize option? I can remove that to force it to always run when GISel does, it's just an old habit of mine to add toggle flags for new passes.

Yes, I was referring to this.
I think it depends what's the intent: is this required for correctness (always run) or simply yield better code.
If this is for correctness (say for instance because we conservatively declare that we don't want to handle weird cases), then we should have a way to enforce (verifier) it.

There may be cases where we need to re-do canonicalization if legalizer breaks it, but as we discussed we should try to fix that in the offending passes if possible.

Sounds good to me.

I think if we wanted to share the code in future then we'd need to create a new library, to prevent LLVMCodeGen having to depend on LLVMInstCombine which would be weird.

Agree.

Maybe, but we don't have a real motivating use case right now. SelectionDAG already handles the compare immediate case already at -O0. -O0 canonicalizations is where I see this being most useful in order to be on par with the other ISels, and at higher opt levels we can rely on instcombine to do most of it.

FastISel may benefit from it as well, but I agree this is not strictly require plus we are killing fastisel, so not changing its inputs mean no need to do more validations :).

LGTM (one thing to think about is what we discuss regarding correctness vs. beautification, but that shouldn't hold this PR)

Cheers,
-Quentin

This revision is now accepted and ready to land.Sep 13 2018, 9:45 AM
qcolombet added inline comments.Sep 13 2018, 9:46 AM
lib/CodeGen/TargetPassConfig.cpp
737

That additional line shouldn't be here I believe.

FWIW, I am still not convince this is a good thing to match SDISel behavior at O0, but this is the least bad solution of doing that IMHO.

This isn't really ideal because of how trivial it is currently. The issue is that if we added the capability to InstSimplify (which is where it would fit most naturally), we'd still end up with the problem of running the whole of InstSimplify in the GlobalISel pipeline. It's reasonable for now I think so I'll commit with the changes requested.

Hi Amara - would it be possible to add this as part of AArch64 pass pipeline? Adding this to all targets would result in needless burning of compile time for targets that don't need this.

Hi Amara - would it be possible to add this as part of AArch64 pass pipeline? Adding this to all targets would result in needless burning of compile time for targets that don't need this.

I expect other targets to also want to do this at some point, more often than not. I can introduce a target hook to let targets opt out, rather than opt-in, then we can assume for most target's GISel implementation that the IR's been canonicalized?

Hi Amara - would it be possible to add this as part of AArch64 pass pipeline? Adding this to all targets would result in needless burning of compile time for targets that don't need this.

I expect other targets to also want to do this at some point, more often than not. I can introduce a target hook to let targets opt out, rather than opt-in, then we can assume for most target's GISel implementation that the IR's been canonicalized?

That sounds reasonable. Thanks

aemerson updated this revision to Diff 166274.Sep 20 2018, 5:55 AM

@aditya_nandakumar I've added a target hook that defaults to enabling this.

aemerson requested review of this revision.Sep 20 2018, 5:56 AM
aemerson abandoned this revision.Jan 24 2019, 2:21 PM