This is an archive of the discontinued LLVM Phabricator instance.

[GlobalISel] Making MachineCSE runnable in the middle of the GlobalISel
ClosedPublic

Authored by rtereshin on Jan 16 2018, 8:21 PM.

Details

Summary

Right now, it is not possible to run MachineCSE in the middle of the
GlobalISel pipeline. Being able to run generic optimizations between the
core passes of GlobalISel was one of the goals of the new ISel framework.
This is the first attempt to do it in a POC manner.

The problem is that MachineCSE pass assumes all register operands have a
register class, which, in GlobalISel context, won't be true until after the
InstructionSelect pass. The reason for this behaviour is that before
replacing one virtual register with another, MachineCSE pass (and most of
the other optimization machine passes) must check if the virtual registers'
constraints have a (sufficiently large) intersection, and constrain the
resulting register appropriately if such intersection exists.

GlobalISel extends the representation of such constraints from just a
register class to a tripple (low-level type, register bank, register
class).

This commit adds MachineRegisterInfo::constrainRegAttrs method that extends
MachineRegisterInfo::constrainRegClass to such a tripple.

The idea is that going forward we should use:

  • RegisterBankInfo::constrainGenericRegister within GlobalISel's InstructionSelect pass
  • MachineRegisterInfo::constrainRegClass within SelectionDAG ISel and FastISel
  • MachineRegisterInfo::constrainRegAttrs everywhere else

regardless the target and instruction selector it uses.

For that reason I tried to keep the performance overhead of
constrainRegAttrs comparing to constrainRegClass at a minimum, hence the
helper method.

Diff Detail

Event Timeline

rtereshin created this revision.Jan 16 2018, 8:21 PM
rtereshin retitled this revision from [GlobalISel] Making MachineCSE runable in the middle of the GlobalISel to [GlobalISel] Making MachineCSE runnable in the middle of the GlobalISel.Jan 16 2018, 10:28 PM
bogner added a subscriber: bogner.Jan 17 2018, 9:44 AM
bogner added inline comments.
include/llvm/CodeGen/MachineRegisterInfo.h
669

Don't repeat the function name in new doc comments. If the resulting inconsistency with the rest of the file bugs you you can feel free to clean up the others in a separate commit.

lib/CodeGen/MachineRegisterInfo.cpp
67–68

Why explicitly mark this inline?

97–101

Should this advice about which functions to call be put in the doc comments somewhere instead/as well?

test/CodeGen/AArch64/GlobalISel/machine-cse-mid-pipeline.mir
3–39

I don't think anything in this test references the IR, so we can probably remove this whole block for readability.

45–49

Don't bother with the registers block (here and below). The constraints are specified inline in the IR anyway, so it isn't necessary unless you're specifying a preferred-register.

rtereshin marked 3 inline comments as done.Jan 17 2018, 10:55 AM
rtereshin added inline comments.
include/llvm/CodeGen/MachineRegisterInfo.h
669

Okay, thanks! Will remove it.

lib/CodeGen/MachineRegisterInfo.cpp
67–68

It's a non-public helper function only used in 2 places with the only purpose to not repeat getRegClass(Reg) call while falling back to the original version of constrainRegClass. As constrainRegAttrs intends to replace constrainRegClass in most of the places, I don't want to create even an appearance of any unnecessary performance overhead on passes that run after ISel, especially when GlobalISel is not used at all.

97–101

Hm, probably. I'm a bit reluctant to change comments / docs to functions I didn't change though, as it might be considered as "unrelated change". Also, it might be a little too invasive before we actually move everything to constrainRegAttrs, maybe I should make a couple of other machine passes runnable mid-GISel-pipeline, and make it all a separate patch.

What do you think?

test/CodeGen/AArch64/GlobalISel/machine-cse-mid-pipeline.mir
3–39

Oh, interesting. So if just some of the functions are not defined, llc fails with function '<function name>' isn't defined in the provided LLVM IR, but if the entire block is removed it works just fine.

Didn't know that, thanks! Will remove it.

45–49

Great, thanks!

rtereshin marked 3 inline comments as done.
rtereshin added a reviewer: bogner.
rtereshin updated this revision to Diff 130278.Jan 17 2018, 2:42 PM
bogner added inline comments.Jan 17 2018, 3:47 PM
lib/CodeGen/MachineRegisterInfo.cpp
67–68

Sure. It might be clearer to just make this a static function (you'll have to pass in the MachineRegisterInfo, obviously). Then the compiler will see that it's only used twice and do the inlining without the hint.

97–101

I don't think updating doc comments of existing functions to reflect how they relate to a new function is unrelated at all - I'd actually argue that it makes the reason for the change in wording more clear.

test/CodeGen/AArch64/GlobalISel/machine-cse-mid-pipeline.mir
3–39

Yep, if there's no function block at all the parser will make up synthetic functions.

rtereshin marked 8 inline comments as done.Jan 17 2018, 4:07 PM
rtereshin added inline comments.
lib/CodeGen/MachineRegisterInfo.cpp
67–68

Agreed

97–101

All right, I'll update the doc comments instead

rtereshin updated this revision to Diff 130337.Jan 17 2018, 5:35 PM
rtereshin marked 2 inline comments as done.
rtereshin edited the summary of this revision. (Show Details)
bogner accepted this revision.Jan 17 2018, 5:45 PM

LGTM

This revision is now accepted and ready to land.Jan 17 2018, 5:45 PM

Roman asked me to commit this for him off-thread. It's r322805.

Thanks Roman!