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.
Details
- Reviewers
arsenm bogner aditya_nandakumar volkan
Diff Detail
- Repository
- rG LLVM Github Monorepo
- Build Status
Buildable 35933 Build 35932: arc lint + arc unit
Event Timeline
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().
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.
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?