@@ -239,6 +239,11 @@ static cl::opt<bool> EnableRedZone("aarch64-redzone",
239
239
cl::desc (" enable use of redzone on AArch64" ),
240
240
cl::init(false ), cl::Hidden);
241
241
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
+
242
247
static cl::opt<bool > StackTaggingMergeSetTag (
243
248
" stack-tagging-merge-settag" ,
244
249
cl::desc (" merge settag instruction in function epilog" ), cl::init(true ),
@@ -302,6 +307,8 @@ bool AArch64FrameLowering::homogeneousPrologEpilog(
302
307
return false ;
303
308
if (!EnableHomogeneousPrologEpilog)
304
309
return false ;
310
+ if (ReverseCSRRestoreSeq)
311
+ return false ;
305
312
if (EnableRedZone)
306
313
return false ;
307
314
@@ -3104,27 +3111,7 @@ bool AArch64FrameLowering::restoreCalleeSavedRegisters(
3104
3111
3105
3112
computeCalleeSaveRegisterPairs (MF, CSI, TRI, RegPairs, hasFP (MF));
3106
3113
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 {
3128
3115
unsigned Reg1 = RPI.Reg1 ;
3129
3116
unsigned Reg2 = RPI.Reg2 ;
3130
3117
@@ -3198,6 +3185,43 @@ bool AArch64FrameLowering::restoreCalleeSavedRegisters(
3198
3185
MachineMemOperand::MOLoad, Size, Alignment));
3199
3186
if (NeedsWinCFI)
3200
3187
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
+ }
3201
3225
}
3202
3226
3203
3227
return true ;
0 commit comments