-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[AMDGPU][MachineRegisterInfo] Extend the MRI live-ins check to account for Subreg #126926
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[AMDGPU][MachineRegisterInfo] Extend the MRI live-ins check to account for Subreg #126926
Conversation
@llvm/pr-subscribers-backend-amdgpu Author: Vikash Gupta (vg0204) ChangesThis support extends live-in check for MRI, by adding check for sub-register checks also. It solves a BUG related to SILowerSGPRSpill, where KILL flag is introduced based on MRI live-in list. Now, if a SuperReg is in live-ins, it implies its immediate usage as well as any subpart of it. But, currently, only exact register match is taken care by MRI, bypassing the immediately utilized subregs as not used, thus marking it as Killed, and later machine verfier starts giving error for using killed subreg. Refer #126696 for more details. Full diff: https://github.com/llvm/llvm-project/pull/126926.diff 2 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
index 1c465741cb462..f182b42d2a24a 100644
--- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -1020,7 +1020,7 @@ class MachineRegisterInfo {
return LiveIns;
}
- bool isLiveIn(Register Reg) const;
+ bool isLiveIn(Register Reg, bool CheckForSubreg = false) const;
/// getLiveInPhysReg - If VReg is a live-in virtual register, return the
/// corresponding live-in physical register.
diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
index 937f63f6c5e00..341b0c7207092 100644
--- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
@@ -447,10 +447,22 @@ void MachineRegisterInfo::clearKillFlags(Register Reg) const {
MO.setIsKill(false);
}
-bool MachineRegisterInfo::isLiveIn(Register Reg) const {
- for (const std::pair<MCRegister, Register> &LI : liveins())
+bool MachineRegisterInfo::isLiveIn(Register Reg, bool CheckForSubreg) const {
+ for (const std::pair<MCRegister, Register> &LI : liveins()) {
if ((Register)LI.first == Reg || LI.second == Reg)
return true;
+
+ // Check if Reg is a subreg of live-in register
+ if (CheckForSubreg) {
+ MCRegister PhysReg = LI.first;
+ if (!PhysReg.isValid())
+ continue;
+
+ for (MCPhysReg SubReg : getTargetRegisterInfo()->subregs(PhysReg))
+ if (SubReg == Reg)
+ return true;
+ }
+ }
return false;
}
|
@@ -1020,7 +1020,7 @@ class MachineRegisterInfo { | |||
return LiveIns; | |||
} | |||
|
|||
bool isLiveIn(Register Reg) const; | |||
bool isLiveIn(Register Reg, bool CheckForSubreg = false) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that if we do this, it should not be an option. It should simply be unconditional.
However, I think we need better documented rules for whatever is supposed to be in the livein list. The MachineFunction liveins, for whatever reason, behave differently from MachineBasicBlock's liveins. Why don't they both use the physreg + lane mask?
However, I still think we should replace all of the livein references to be directly in terms of regunits
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, I still think we should replace all of the livein references to be directly in terms of regunits
Makes sense to me, but it would quite a huge task, as live-ins appeared & represented differently across different places need to be handled :
- In MBB, live-ins are stored as physreg + lane mask (regunit based implementation)
- In MachinFunction, live-ins are just pair of <PhysReg, VirtualReg> in association
- In MachineVerfier, MBB's live-ins are calculated as the physReg & all its subregs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that if we do this, it should not be an option. It should simply be unconditional.
Need to see its side-effect on other architectures, as can't comment on their interpretation right! For now, its needed as immediate fix to mentioned crashing mir test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done with it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense to me, but it would quite a huge task, as live-ins appeared & represented differently across different places need to be handled :
In MBB, live-ins are stored as physreg + lane mask (regunit based implementation)
In MachinFunction, live-ins are just pair of <PhysReg, VirtualReg> in association
In MachineVerfier, MBB's live-ins are calculated as the physReg & all its subregs
We should eventually port them to use regunits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done it already for MachineFunction here itself, only apparently seen it left for machine verifier, which will require bit of work, so better to do separately. Any other place @cdevadas @arsenm you think it should be taken care. If its OK with you, I can take it up this task, atleast the supposedly apparent things!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That can be done separately.
This should be a stacked review based of #126696 so that we can see how this patch changes the test. |
@arsenm kind Ping! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second look, I'm not sure what problem this is supposed to solve. Last I checked, the MachineVerifier did not use the MachineRegisterInfo / MachineFunction liveins for anything. It does not factor into the liveness calculation, or verification. Only the MachineBasicBlock's liveins should matter (where we do have actual bugs in the verifier, especially for the entry block).
Can this look at the block live ins instead? |
Yes, thats true and as you said looking into MBB(entry) live-in should apprently take care of machine verifier error spawned in SILowerSgprSpills(). But, if we see from other point of view considering your comments
Don't we really need this! |
block live hold T(physReg+LaneBitmask) as liveIns, so its check is meant to handle only liveIns existing as T, while in SILowerSGPR needs check for CSR physReg used i.e. dword-sized reg as liveIn. So, straight direct check without anything additional not seems possible. With MRI, it holds only the entire live PhysReg as MCRegister in its list, so just its extension by my patch does the job. |
c38bcb7
to
df4bf0b
Compare
@@ -448,9 +448,21 @@ void MachineRegisterInfo::clearKillFlags(Register Reg) const { | |||
} | |||
|
|||
bool MachineRegisterInfo::isLiveIn(Register Reg) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What other users of this exist? I'd prefer to see a patch to SILowerSGPRSpills to not use the MRI liveins before we do anything here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To elaborate, I do not believe MachineRegisterInfo's live in tracking to be generally reliable. GlobalISel doesn't bother adding entries to it for instance. The verifier does not check that it is consistent with the entry block's live in list. Last I looked at it, I thought we could possibly remove the concept entirely.
I think we need to establish a policy on the live in entry : function live ins to see if it makes sense to have liveness tracking. Right now it's only kind of useful in argument lowering for initial codegen
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What other users of this exist? I'd prefer to see a patch to SILowerSGPRSpills to not use the MRI liveins before we do anything here.
It requires LiveRegUnitSet (set of all live regUnits) concept in MBB, and its propagation to all its live-ins related APIs to achieve it. As current isLiveIn is based on exact match of PhysReg (which would discard the idea of subReg check entirely). Can we proceed with this idea!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can it be achieved using LiveRegUnit
??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It requires LiveRegUnitSet (set of all live regUnits) concept in MBB, and its propagation to all its live-ins related APIs to achieve it.
I don't follow. We don't need any liveness tracking to check if a physical register is live into the function. Why can't you just s/MRI.isLiveIn(Reg)/MF.begin()->isLiveIn(Reg)/
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't follow. We don't need any liveness tracking to check if a physical register is live into the function. Why can't you just s/MRI.isLiveIn(Reg)/MF.begin()->isLiveIn(Reg)/?
Because as the current MBB's isLiveIn defined it won't work as expected to get rid of the issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…terator in SILowerSGPRSpills (#129848) This patch replaces use of MachineRegisterInfo's liveIn check with the machine basicBlock's liveIn. As the MRI's liveIn is inconsistent with the entry MBB liveIns, when it comes to the machine verifier checks. PS: Its an alternative solution with respect to #126926.
The alternative way to handle it via usage of MCRegAliasIterator has been merged! |
This support extends live-in check for MRI, by adding check for sub-register checks also. It solves a BUG related to SILowerSGPRSpill, where KILL flag is introduced based on MRI live-in list. Now, if a SuperReg is in live-ins, it implies its immediate usage as well as any subpart of it. But, currently, only exact register match is taken care by MRI, bypassing the immediately utilized subregs as not used, thus marking it as Killed, and later machine verfier starts giving error for using killed subreg.
Refer #126696 for more details.