This is an archive of the discontinued LLVM Phabricator instance.

Move llvm::Register from CodeGen to MC to correct a layering issue
AbandonedPublic

Authored by dsanders on Jul 31 2019, 6:51 PM.

Details

Summary

The MC layer uses unsigned as registers in the same way as CodeGen (e.g.
MCRegisterClass::contains(). Move llvm::Register to the MC layer so we can
use it in MC API's too.

Event Timeline

dsanders created this revision.Jul 31 2019, 6:51 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 31 2019, 6:51 PM

I had been planning on introducing a distinct "MCRegister" or "MCReg" for this purpose (to mostly replace MCPhysReg usage), with promotion from MCRegister->Register being allowed, but not the inverse.

I had been planning on introducing a distinct "MCRegister" or "MCReg" for this purpose (to mostly replace MCPhysReg usage), with promotion from MCRegister->Register being allowed, but not the inverse.

I agree with having a class wrapping MCPhysReg but I think MCRegister needs to know about the namespacing, vregs, etc. as there's places in the MC layer API's where unsigned isn't limited to MCPhysReg. Once it knows about all that, I doubt a CodeGen-layer Register class would be different from MCRegister.

MCRegisterClass::contains() is the main example I have at the moment. It's often called with virtual register arguments and returns false for this case. You can check this by adding assert(Reg == (Reg & 0xFFFF)) to this function and you'll see it fail on lots of tests as the vregs are passed in (I originally found it by changing unsigned to MCPhysReg in MCRegisterInfo's API's and found that two AMDGPU tests started failing). It happens because TargetRegisterClass::contains() forwards on to MCRegisterClass::contains().

MCRegisterClass::contains() is the main example I have at the moment. It's often called with virtual register arguments and returns false for this case.

This sounds really broken. I would expect that to be an illegal call

MCRegisterClass::contains() is the main example I have at the moment. It's often called with virtual register arguments and returns false for this case.

This sounds really broken. I would expect that to be an illegal call

Are you referring to calling TargetRegisterClass::contains() on vregs to begin with or passing them on to MCRegisterClass::contains?
The former is happening everywhere as far as I can see but we could practically make the latter true.

FWIW, this is the only vregs in MC layer case I've found so far but I'm worried that there are more non-physical registers in the MC objects. Historically there's nothing stopping it and I don't have a very good way to discover it at the moment.

MCRegisterClass::contains() is the main example I have at the moment. It's often called with virtual register arguments and returns false for this case.

This sounds really broken. I would expect that to be an illegal call

Are you referring to calling TargetRegisterClass::contains() on vregs to begin with or passing them on to MCRegisterClass::contains?
The former is happening everywhere as far as I can see but we could practically make the latter true.

Both. It doesn't make any sense to pass a virtual register to either. For a virtual register you would check the register class from MachineRegisterInfo

MCRegisterClass::contains() is the main example I have at the moment. It's often called with virtual register arguments and returns false for this case.

This sounds really broken. I would expect that to be an illegal call

Are you referring to calling TargetRegisterClass::contains() on vregs to begin with or passing them on to MCRegisterClass::contains?
The former is happening everywhere as far as I can see but we could practically make the latter true.

Both. It doesn't make any sense to pass a virtual register to either. For a virtual register you would check the register class from MachineRegisterInfo

I can see some sense to the former as a virtual register is never a member of a register class. It will usually give the intended result for passes that act on physical registers.

At this point, here's my plan for these couple patches:

  • Make https://reviews.llvm.org/D65553 independent of this patch so that we have the correct namespacing in Register
  • Move the definition of the physical register namespace to a stub MCRegister class to allow us to start checking for vregs/stack-slots in the MC layer. Making an actual MCRegister to replace is a separate piece of work (I have another patch that changes various unsigned to MCPhysReg in MCRegisterInfo and it would make more sense to go along with that)
  • Add a if (!isPhysical()) return false to TargetRegisterInfo::contains() to prevent non-physreg's leaking into the MC layer by that method

I don't want to take on sorting out the callers of TargetRegisterInfo::contains() though I think that's going to be a rabbit hole and I'm trying to get back to that SrcOp patch :-) (the reason I looked into this on the way is the implicit cast operator from Register to unsigned can still give some easy routes to accidentally mix up immediates and registers, I was looking into the difficulty of requiring it explicit casts)

Does that sound good?

arsenm accepted this revision.Jul 31 2019, 8:03 PM

LGTM

This revision is now accepted and ready to land.Jul 31 2019, 8:03 PM
dsanders planned changes to this revision.Jul 31 2019, 8:22 PM

I assume the green tick was something phabricator did automatically :-)

dsanders abandoned this revision.Aug 1 2019, 1:10 PM

All the patches to replace this are up. Abandoning the original