-
Notifications
You must be signed in to change notification settings - Fork 15.5k
[llvm][RISCV] Implement Zilsd load/store pair optimization #158640
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
Changes from 1 commit
4bbf382
5722750
569a86c
ce8fc11
2ff058f
a4cca81
294d83e
14c0463
57c10b5
7c9b744
90f3aa4
ed57a2c
fff9d4b
483104e
66d95f1
c4c4925
7c377e3
fe67c22
696bad8
d79e21c
2a87065
44f5809
9453b78
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -853,6 +853,44 @@ bool RISCVRegisterInfo::getRegAllocationHints( | |
| const MachineRegisterInfo *MRI = &MF.getRegInfo(); | ||
| auto &Subtarget = MF.getSubtarget<RISCVSubtarget>(); | ||
|
|
||
| // Handle RegPairEven/RegPairOdd hints for Zilsd register pairs | ||
| std::pair<unsigned, Register> Hint = MRI->getRegAllocationHint(VirtReg); | ||
| unsigned HintType = Hint.first; | ||
| Register Partner = Hint.second; | ||
|
|
||
| if (HintType == RISCVRI::RegPairEven || HintType == RISCVRI::RegPairOdd) { | ||
| // Check if we want the even or odd register of a consecutive pair | ||
| bool WantOdd = (HintType == RISCVRI::RegPairOdd); | ||
|
|
||
| // First priority: Check if partner is already allocated | ||
| if (Partner.isVirtual() && VRM && VRM->hasPhys(Partner)) { | ||
| MCPhysReg PartnerPhys = VRM->getPhys(Partner); | ||
topperc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // Calculate the exact register we need for consecutive pairing | ||
| MCPhysReg TargetReg = PartnerPhys + (WantOdd ? 1 : -1); | ||
|
|
||
| // Verify it's valid and available | ||
| if (RISCV::GPRRegClass.contains(TargetReg) && | ||
| is_contained(Order, TargetReg)) { | ||
| Hints.push_back(TargetReg); | ||
| } | ||
| } | ||
|
|
||
| // Second priority: Try to find consecutive register pairs in the allocation | ||
| // order | ||
| for (MCPhysReg PhysReg : Order) { | ||
| if (!PhysReg) | ||
| continue; | ||
|
|
||
| unsigned RegNum = getEncodingValue(PhysReg); | ||
| // Check if this register matches the even/odd requirement | ||
| bool IsOdd = (RegNum % 2 != 0); | ||
|
|
||
| // Verify the pair register exists and is in the same register class | ||
| if ((WantOdd && IsOdd) || (!WantOdd && !IsOdd)) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we check reserved registers here like ARM so we don't hint X5 which can never pair with the reserved X4 register. We don't want to hint S1(X9) when S0(X8) is reserved for the frame pointer. And we don't want to hint X1, since X0 and X1 isn't a valid pair. Users can also reserved registers from the command line. We can fix this in a follow up. |
||
| Hints.push_back(PhysReg); | ||
| } | ||
| } | ||
|
|
||
| bool BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints( | ||
| VirtReg, Order, Hints, MF, VRM, Matrix); | ||
|
|
||
|
|
@@ -994,6 +1032,36 @@ bool RISCVRegisterInfo::getRegAllocationHints( | |
| return BaseImplRetVal; | ||
| } | ||
|
|
||
| void RISCVRegisterInfo::updateRegAllocHint(Register Reg, Register NewReg, | ||
| MachineFunction &MF) const { | ||
| MachineRegisterInfo *MRI = &MF.getRegInfo(); | ||
| std::pair<unsigned, Register> Hint = MRI->getRegAllocationHint(Reg); | ||
|
|
||
| // Handle RegPairEven/RegPairOdd hints for Zilsd register pairs | ||
| if ((Hint.first == RISCVRI::RegPairOdd || | ||
| Hint.first == RISCVRI::RegPairEven) && | ||
| Hint.second.isVirtual()) { | ||
| // If 'Reg' is one of the even/odd register pair and it's now changed | ||
| // (e.g. coalesced) into a different register, the other register of the | ||
| // pair allocation hint must be updated to reflect the relationship change. | ||
| Register Partner = Hint.second; | ||
| std::pair<unsigned, Register> PartnerHint = | ||
| MRI->getRegAllocationHint(Partner); | ||
|
|
||
| // Make sure partner still points to us | ||
| if (PartnerHint.second == Reg) { | ||
| // Update partner to point to NewReg instead of Reg | ||
| MRI->setRegAllocationHint(Partner, PartnerHint.first, NewReg); | ||
|
|
||
| // If NewReg is virtual, set up the reciprocal hint | ||
| // NewReg takes over Reg's role, so it gets the SAME hint type as Reg | ||
| if (NewReg.isVirtual()) { | ||
topperc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| MRI->setRegAllocationHint(NewReg, Hint.first, Partner); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Register | ||
| RISCVRegisterInfo::findVRegWithEncoding(const TargetRegisterClass &RegClass, | ||
| uint16_t Encoding) const { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.