@@ -239,6 +239,11 @@ static cl::opt<bool> EnableRedZone("aarch64-redzone",
239239 cl::desc (" enable use of redzone on AArch64" ),
240240 cl::init(false ), cl::Hidden);
241241
242+ static cl::opt<bool >
243+ ReverseCSRRestoreSeq (" reverse-csr-restore-seq" ,
244+ cl::desc (" reverse the CSR restore sequence" ),
245+ cl::init(false ), cl::Hidden);
246+
242247static cl::opt<bool > StackTaggingMergeSetTag (
243248 " stack-tagging-merge-settag" ,
244249 cl::desc (" merge settag instruction in function epilog" ), cl::init(true ),
@@ -302,6 +307,8 @@ bool AArch64FrameLowering::homogeneousPrologEpilog(
302307 return false ;
303308 if (!EnableHomogeneousPrologEpilog)
304309 return false ;
310+ if (ReverseCSRRestoreSeq)
311+ return false ;
305312 if (EnableRedZone)
306313 return false ;
307314
@@ -3104,27 +3111,7 @@ bool AArch64FrameLowering::restoreCalleeSavedRegisters(
31043111
31053112 computeCalleeSaveRegisterPairs (MF, CSI, TRI, RegPairs, hasFP (MF));
31063113
3107- if (homogeneousPrologEpilog (MF, &MBB)) {
3108- auto MIB = BuildMI (MBB, MBBI, DL, TII.get (AArch64::HOM_Epilog))
3109- .setMIFlag (MachineInstr::FrameDestroy);
3110- for (auto &RPI : RegPairs) {
3111- MIB.addReg (RPI.Reg1 , RegState::Define);
3112- MIB.addReg (RPI.Reg2 , RegState::Define);
3113- }
3114- return true ;
3115- }
3116-
3117- // For performance reasons restore SVE register in increasing order
3118- auto IsPPR = [](const RegPairInfo &c) { return c.Type == RegPairInfo::PPR; };
3119- auto PPRBegin = std::find_if (RegPairs.begin (), RegPairs.end (), IsPPR);
3120- auto PPREnd = std::find_if (RegPairs.rbegin (), RegPairs.rend (), IsPPR);
3121- std::reverse (PPRBegin, PPREnd.base ());
3122- auto IsZPR = [](const RegPairInfo &c) { return c.Type == RegPairInfo::ZPR; };
3123- auto ZPRBegin = std::find_if (RegPairs.begin (), RegPairs.end (), IsZPR);
3124- auto ZPREnd = std::find_if (RegPairs.rbegin (), RegPairs.rend (), IsZPR);
3125- std::reverse (ZPRBegin, ZPREnd.base ());
3126-
3127- for (const RegPairInfo &RPI : RegPairs) {
3114+ auto EmitMI = [&](const RegPairInfo &RPI) -> MachineBasicBlock::iterator {
31283115 unsigned Reg1 = RPI.Reg1 ;
31293116 unsigned Reg2 = RPI.Reg2 ;
31303117
@@ -3198,6 +3185,43 @@ bool AArch64FrameLowering::restoreCalleeSavedRegisters(
31983185 MachineMemOperand::MOLoad, Size, Alignment));
31993186 if (NeedsWinCFI)
32003187 InsertSEH (MIB, TII, MachineInstr::FrameDestroy);
3188+
3189+ return MIB->getIterator ();
3190+ };
3191+
3192+ if (homogeneousPrologEpilog (MF, &MBB)) {
3193+ auto MIB = BuildMI (MBB, MBBI, DL, TII.get (AArch64::HOM_Epilog))
3194+ .setMIFlag (MachineInstr::FrameDestroy);
3195+ for (auto &RPI : RegPairs) {
3196+ MIB.addReg (RPI.Reg1 , RegState::Define);
3197+ MIB.addReg (RPI.Reg2 , RegState::Define);
3198+ }
3199+ return true ;
3200+ }
3201+
3202+ // For performance reasons restore SVE register in increasing order
3203+ auto IsPPR = [](const RegPairInfo &c) { return c.Type == RegPairInfo::PPR; };
3204+ auto PPRBegin = std::find_if (RegPairs.begin (), RegPairs.end (), IsPPR);
3205+ auto PPREnd = std::find_if (RegPairs.rbegin (), RegPairs.rend (), IsPPR);
3206+ std::reverse (PPRBegin, PPREnd.base ());
3207+ auto IsZPR = [](const RegPairInfo &c) { return c.Type == RegPairInfo::ZPR; };
3208+ auto ZPRBegin = std::find_if (RegPairs.begin (), RegPairs.end (), IsZPR);
3209+ auto ZPREnd = std::find_if (RegPairs.rbegin (), RegPairs.rend (), IsZPR);
3210+ std::reverse (ZPRBegin, ZPREnd.base ());
3211+
3212+ if (ReverseCSRRestoreSeq) {
3213+ MachineBasicBlock::iterator First = MBB.end ();
3214+ for (const RegPairInfo &RPI : reverse (RegPairs)) {
3215+ MachineBasicBlock::iterator It = EmitMI (RPI);
3216+ if (First == MBB.end ())
3217+ First = It;
3218+ }
3219+ if (First != MBB.end ())
3220+ MBB.splice (MBBI, &MBB, First);
3221+ } else {
3222+ for (const RegPairInfo &RPI : RegPairs) {
3223+ (void )EmitMI (RPI);
3224+ }
32013225 }
32023226
32033227 return true ;
0 commit comments