@@ -853,6 +853,44 @@ bool RISCVRegisterInfo::getRegAllocationHints(
853853 const MachineRegisterInfo *MRI = &MF.getRegInfo ();
854854 auto &Subtarget = MF.getSubtarget <RISCVSubtarget>();
855855
856+ // Handle RegPairEven/RegPairOdd hints for Zilsd register pairs
857+ std::pair<unsigned , Register> Hint = MRI->getRegAllocationHint (VirtReg);
858+ unsigned HintType = Hint.first ;
859+ Register Partner = Hint.second ;
860+
861+ if (HintType == RISCVRI::RegPairEven || HintType == RISCVRI::RegPairOdd) {
862+ // Check if we want the even or odd register of a consecutive pair
863+ bool WantOdd = (HintType == RISCVRI::RegPairOdd);
864+
865+ // First priority: Check if partner is already allocated
866+ if (Partner.isVirtual () && VRM && VRM->hasPhys (Partner)) {
867+ MCPhysReg PartnerPhys = VRM->getPhys (Partner);
868+ // Calculate the exact register we need for consecutive pairing
869+ MCPhysReg TargetReg = PartnerPhys + (WantOdd ? 1 : -1 );
870+
871+ // Verify it's valid and available
872+ if (RISCV::GPRRegClass.contains (TargetReg) &&
873+ is_contained (Order, TargetReg)) {
874+ Hints.push_back (TargetReg);
875+ }
876+ }
877+
878+ // Second priority: Try to find consecutive register pairs in the allocation
879+ // order
880+ for (MCPhysReg PhysReg : Order) {
881+ if (!PhysReg)
882+ continue ;
883+
884+ unsigned RegNum = getEncodingValue (PhysReg);
885+ // Check if this register matches the even/odd requirement
886+ bool IsOdd = (RegNum % 2 != 0 );
887+
888+ // Verify the pair register exists and is in the same register class
889+ if ((WantOdd && IsOdd) || (!WantOdd && !IsOdd))
890+ Hints.push_back (PhysReg);
891+ }
892+ }
893+
856894 bool BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints (
857895 VirtReg, Order, Hints, MF, VRM, Matrix);
858896
@@ -994,6 +1032,36 @@ bool RISCVRegisterInfo::getRegAllocationHints(
9941032 return BaseImplRetVal;
9951033}
9961034
1035+ void RISCVRegisterInfo::updateRegAllocHint (Register Reg, Register NewReg,
1036+ MachineFunction &MF) const {
1037+ MachineRegisterInfo *MRI = &MF.getRegInfo ();
1038+ std::pair<unsigned , Register> Hint = MRI->getRegAllocationHint (Reg);
1039+
1040+ // Handle RegPairEven/RegPairOdd hints for Zilsd register pairs
1041+ if ((Hint.first == RISCVRI::RegPairOdd ||
1042+ Hint.first == RISCVRI::RegPairEven) &&
1043+ Hint.second .isVirtual ()) {
1044+ // If 'Reg' is one of the even/odd register pair and it's now changed
1045+ // (e.g. coalesced) into a different register, the other register of the
1046+ // pair allocation hint must be updated to reflect the relationship change.
1047+ Register Partner = Hint.second ;
1048+ std::pair<unsigned , Register> PartnerHint =
1049+ MRI->getRegAllocationHint (Partner);
1050+
1051+ // Make sure partner still points to us
1052+ if (PartnerHint.second == Reg) {
1053+ // Update partner to point to NewReg instead of Reg
1054+ MRI->setRegAllocationHint (Partner, PartnerHint.first , NewReg);
1055+
1056+ // If NewReg is virtual, set up the reciprocal hint
1057+ // NewReg takes over Reg's role, so it gets the SAME hint type as Reg
1058+ if (NewReg.isVirtual ()) {
1059+ MRI->setRegAllocationHint (NewReg, Hint.first , Partner);
1060+ }
1061+ }
1062+ }
1063+ }
1064+
9971065Register
9981066RISCVRegisterInfo::findVRegWithEncoding (const TargetRegisterClass &RegClass,
9991067 uint16_t Encoding) const {
0 commit comments