@@ -853,6 +853,44 @@ bool RISCVRegisterInfo::getRegAllocationHints(
853
853
const MachineRegisterInfo *MRI = &MF.getRegInfo ();
854
854
auto &Subtarget = MF.getSubtarget <RISCVSubtarget>();
855
855
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
+
856
894
bool BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints (
857
895
VirtReg, Order, Hints, MF, VRM, Matrix);
858
896
@@ -994,6 +1032,36 @@ bool RISCVRegisterInfo::getRegAllocationHints(
994
1032
return BaseImplRetVal;
995
1033
}
996
1034
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
+
997
1065
Register
998
1066
RISCVRegisterInfo::findVRegWithEncoding (const TargetRegisterClass &RegClass,
999
1067
uint16_t Encoding) const {
0 commit comments