@@ -291,9 +291,7 @@ static Register getMaxPushPopReg(const MachineFunction &MF,
291
291
const std::vector<CalleeSavedInfo> &CSI) {
292
292
Register MaxPushPopReg = RISCV::NoRegister;
293
293
for (auto &CS : CSI) {
294
- // RISCVRegisterInfo::hasReservedSpillSlot assigns negative frame indices to
295
- // registers which can be saved by Zcmp Push.
296
- if (CS.getFrameIdx () < 0 )
294
+ if (llvm::is_contained (AllPopRegs, CS.getReg ().id ()))
297
295
MaxPushPopReg = std::max (MaxPushPopReg.id (), CS.getReg ().id ());
298
296
}
299
297
// if rlist is {rs, s0-s10}, then s11 will also be included
@@ -532,8 +530,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
532
530
533
531
// FIXME (note copied from Lanai): This appears to be overallocating. Needs
534
532
// investigation. Get the number of bytes to allocate from the FrameInfo.
535
- uint64_t StackSize = getStackSizeWithRVVPadding (MF);
536
- uint64_t RealStackSize = StackSize + RVFI->getReservedSpillsSize ();
533
+ uint64_t RealStackSize = getStackSizeWithRVVPadding (MF);
534
+ uint64_t StackSize = RealStackSize - RVFI->getReservedSpillsSize ();
537
535
uint64_t RVVStackSize = RVFI->getRVVStackSize ();
538
536
539
537
// Early exit if there is no need to allocate on the stack
@@ -590,20 +588,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
590
588
// directives.
591
589
for (const auto &Entry : CSI) {
592
590
int FrameIdx = Entry.getFrameIdx ();
593
- int64_t Offset;
594
- // Offsets for objects with fixed locations (IE: those saved by libcall) are
595
- // simply calculated from the frame index.
596
- if (FrameIdx < 0 ) {
597
- if (RVFI->isPushable (MF)) {
598
- // Callee-saved register stored by Zcmp push is in reverse order.
599
- Offset = -(FrameIdx + RVFI->getRVPushRegs () + 1 ) *
600
- (int64_t )STI.getXLen () / 8 ;
601
- } else {
602
- Offset = FrameIdx * (int64_t )STI.getXLen () / 8 ;
603
- }
604
- } else {
605
- Offset = MFI.getObjectOffset (FrameIdx) - RVFI->getReservedSpillsSize ();
606
- }
591
+ int64_t Offset = MFI.getObjectOffset (FrameIdx);
607
592
Register Reg = Entry.getReg ();
608
593
unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createOffset (
609
594
nullptr , RI->getDwarfRegNum (Reg, true ), Offset));
@@ -746,8 +731,8 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
746
731
if (!CSI.empty ())
747
732
LastFrameDestroy = std::prev (MBBI, CSI.size ());
748
733
749
- uint64_t StackSize = getStackSizeWithRVVPadding (MF);
750
- uint64_t RealStackSize = StackSize + RVFI->getReservedSpillsSize ();
734
+ uint64_t RealStackSize = getStackSizeWithRVVPadding (MF);
735
+ uint64_t StackSize = RealStackSize - RVFI->getReservedSpillsSize ();
751
736
uint64_t FPOffset = RealStackSize - RVFI->getVarArgsSaveSize ();
752
737
uint64_t RVVStackSize = RVFI->getRVVStackSize ();
753
738
@@ -897,8 +882,6 @@ RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
897
882
898
883
if (FrameReg == getFPReg (STI)) {
899
884
Offset += StackOffset::getFixed (RVFI->getVarArgsSaveSize ());
900
- if (FI >= 0 )
901
- Offset -= StackOffset::getFixed (RVFI->getReservedSpillsSize ());
902
885
// When using FP to access scalable vector objects, we need to minus
903
886
// the frame size.
904
887
//
@@ -965,8 +948,7 @@ RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
965
948
if (MFI.isFixedObjectIndex (FI)) {
966
949
assert (!RI->hasStackRealignment (MF) &&
967
950
" Can't index across variable sized realign" );
968
- Offset += StackOffset::get (getStackSizeWithRVVPadding (MF) +
969
- RVFI->getReservedSpillsSize (),
951
+ Offset += StackOffset::get (getStackSizeWithRVVPadding (MF),
970
952
RVFI->getRVVStackSize ());
971
953
} else {
972
954
Offset += StackOffset::getFixed (MFI.getStackSize ());
@@ -1243,47 +1225,17 @@ void RISCVFrameLowering::processFunctionBeforeFrameFinalized(
1243
1225
RVFI->setBranchRelaxationScratchFrameIndex (FI);
1244
1226
}
1245
1227
1246
- if (MFI.getCalleeSavedInfo ().empty () || RVFI->useSaveRestoreLibCalls (MF) ||
1247
- RVFI->isPushable (MF)) {
1248
- RVFI->setCalleeSavedStackSize (0 );
1249
- return ;
1250
- }
1251
-
1252
- unsigned Size = 0 ;
1228
+ unsigned Size = RVFI->getReservedSpillsSize ();
1253
1229
for (const auto &Info : MFI.getCalleeSavedInfo ()) {
1254
1230
int FrameIdx = Info.getFrameIdx ();
1255
- if (MFI.getStackID (FrameIdx) != TargetStackID::Default)
1231
+ if (FrameIdx < 0 || MFI.getStackID (FrameIdx) != TargetStackID::Default)
1256
1232
continue ;
1257
1233
1258
1234
Size += MFI.getObjectSize (FrameIdx);
1259
1235
}
1260
1236
RVFI->setCalleeSavedStackSize (Size);
1261
1237
}
1262
1238
1263
- void RISCVFrameLowering::processFunctionBeforeFrameIndicesReplaced (
1264
- MachineFunction &MF, RegScavenger *RS) const {
1265
- // Remove CalleeSavedInfo for registers saved by Zcmp or save/restore
1266
- // libcalls.
1267
- MachineFrameInfo &MFI = MF.getFrameInfo ();
1268
- const TargetRegisterInfo *TRI = MF.getSubtarget ().getRegisterInfo ();
1269
- const auto *RVFI = MF.getInfo <RISCVMachineFunctionInfo>();
1270
- if (!RVFI->isPushable (MF) && !RVFI->useSaveRestoreLibCalls (MF))
1271
- return ;
1272
- const std::vector<CalleeSavedInfo> &CSIs = MFI.getCalleeSavedInfo ();
1273
- std::vector<CalleeSavedInfo> NewCSIs;
1274
- for (const auto &CSI : CSIs) {
1275
- // Skip CSRs that have fake a frame index.
1276
- int ReservedFI = 0 ;
1277
- if (TRI->hasReservedSpillSlot (MF, CSI.getReg (), ReservedFI)) {
1278
- assert (CSI.getFrameIdx () == ReservedFI &&
1279
- " Reserved CSR spill slot frame index mismatch in CSI" );
1280
- continue ;
1281
- }
1282
- NewCSIs.push_back (CSI);
1283
- }
1284
- MFI.setCalleeSavedInfo (std::move (NewCSIs));
1285
- }
1286
-
1287
1239
// Not preserve stack space within prologue for outgoing variables when the
1288
1240
// function contains variable size objects or there are vector objects accessed
1289
1241
// by the frame pointer.
@@ -1403,6 +1355,93 @@ RISCVFrameLowering::getFirstSPAdjustAmount(const MachineFunction &MF) const {
1403
1355
return 0 ;
1404
1356
}
1405
1357
1358
+ // Offsets which need to be scale by XLen representing locations of CSRs which
1359
+ // are given a fixed location by save/restore libcalls or Zcmp Push/Pop.
1360
+ static const std::pair<MCPhysReg, int8_t > FixedCSRFIMap[] = {
1361
+ {/* ra*/ RISCV::X1, -1 }, {/* s0*/ RISCV::X8, -2 },
1362
+ {/* s1*/ RISCV::X9, -3 }, {/* s2*/ RISCV::X18, -4 },
1363
+ {/* s3*/ RISCV::X19, -5 }, {/* s4*/ RISCV::X20, -6 },
1364
+ {/* s5*/ RISCV::X21, -7 }, {/* s6*/ RISCV::X22, -8 },
1365
+ {/* s7*/ RISCV::X23, -9 }, {/* s8*/ RISCV::X24, -10 },
1366
+ {/* s9*/ RISCV::X25, -11 }, {/* s10*/ RISCV::X26, -12 },
1367
+ {/* s11*/ RISCV::X27, -13 }};
1368
+
1369
+ bool RISCVFrameLowering::assignCalleeSavedSpillSlots (
1370
+ MachineFunction &MF, const TargetRegisterInfo *TRI,
1371
+ std::vector<CalleeSavedInfo> &CSI, unsigned &MinCSFrameIndex,
1372
+ unsigned &MaxCSFrameIndex) const {
1373
+ // Early exit if no callee saved registers are modified!
1374
+ if (CSI.empty ())
1375
+ return true ;
1376
+
1377
+ auto *RVFI = MF.getInfo <RISCVMachineFunctionInfo>();
1378
+
1379
+ if (RVFI->isPushable (MF)) {
1380
+ // Determine how many GPRs we need to push and save it to RVFI.
1381
+ Register MaxReg = getMaxPushPopReg (MF, CSI);
1382
+ if (MaxReg != RISCV::NoRegister) {
1383
+ auto [RegEnc, PushedRegNum] = getPushPopEncodingAndNum (MaxReg);
1384
+ RVFI->setRVPushRegs (PushedRegNum);
1385
+ RVFI->setRVPushStackSize (alignTo ((STI.getXLen () / 8 ) * PushedRegNum, 16 ));
1386
+
1387
+ // Use encoded number to represent registers to spill.
1388
+ RVFI->setRVPushRlist (RegEnc);
1389
+ }
1390
+ }
1391
+
1392
+ MachineFrameInfo &MFI = MF.getFrameInfo ();
1393
+ const TargetRegisterInfo *RegInfo = MF.getSubtarget ().getRegisterInfo ();
1394
+
1395
+ for (auto &CS : CSI) {
1396
+ unsigned Reg = CS.getReg ();
1397
+ const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass (Reg);
1398
+ unsigned Size = RegInfo->getSpillSize (*RC);
1399
+
1400
+ // This might need a fixed stack slot.
1401
+ if (RVFI->useSaveRestoreLibCalls (MF) || RVFI->isPushable (MF)) {
1402
+ const auto *FII = llvm::find_if (
1403
+ FixedCSRFIMap, [&](auto P) { return P.first == CS.getReg (); });
1404
+ if (FII != std::end (FixedCSRFIMap)) {
1405
+ int64_t Offset;
1406
+ if (RVFI->isPushable (MF))
1407
+ Offset = -((FII->second + RVFI->getRVPushRegs () + 1 ) * (int64_t )Size);
1408
+ else
1409
+ Offset = FII->second * (int64_t )Size;
1410
+
1411
+ int FrameIdx = MFI.CreateFixedSpillStackObject (Size, Offset);
1412
+ assert (FrameIdx < 0 );
1413
+ CS.setFrameIdx (FrameIdx);
1414
+ continue ;
1415
+ }
1416
+ }
1417
+
1418
+ // Not a fixed slot.
1419
+ Align Alignment = RegInfo->getSpillAlign (*RC);
1420
+ // We may not be able to satisfy the desired alignment specification of
1421
+ // the TargetRegisterClass if the stack alignment is smaller. Use the
1422
+ // min.
1423
+ Alignment = std::min (Alignment, getStackAlign ());
1424
+ int FrameIdx = MFI.CreateStackObject (Size, Alignment, true );
1425
+ if ((unsigned )FrameIdx < MinCSFrameIndex)
1426
+ MinCSFrameIndex = FrameIdx;
1427
+ if ((unsigned )FrameIdx > MaxCSFrameIndex)
1428
+ MaxCSFrameIndex = FrameIdx;
1429
+ CS.setFrameIdx (FrameIdx);
1430
+ }
1431
+
1432
+ // Allocate a fixed object that covers the full push or libcall size.
1433
+ if (RVFI->isPushable (MF)) {
1434
+ if (int64_t PushSize = RVFI->getRVPushStackSize ())
1435
+ MFI.CreateFixedSpillStackObject (PushSize, -PushSize);
1436
+ } else if (int LibCallRegs = getLibCallID (MF, CSI) + 1 ) {
1437
+ int64_t LibCallFrameSize =
1438
+ alignTo ((STI.getXLen () / 8 ) * LibCallRegs, getStackAlign ());
1439
+ MFI.CreateFixedSpillStackObject (LibCallFrameSize, -LibCallFrameSize);
1440
+ }
1441
+
1442
+ return true ;
1443
+ }
1444
+
1406
1445
bool RISCVFrameLowering::spillCalleeSavedRegisters (
1407
1446
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
1408
1447
ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
@@ -1418,14 +1457,10 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters(
1418
1457
// Emit CM.PUSH with base SPimm & evaluate Push stack
1419
1458
RISCVMachineFunctionInfo *RVFI = MF->getInfo <RISCVMachineFunctionInfo>();
1420
1459
if (RVFI->isPushable (*MF)) {
1421
- Register MaxReg = getMaxPushPopReg (*MF, CSI);
1422
- if (MaxReg != RISCV::NoRegister) {
1423
- auto [RegEnc, PushedRegNum] = getPushPopEncodingAndNum (MaxReg);
1424
- RVFI->setRVPushRegs (PushedRegNum);
1425
- RVFI->setRVPushStackSize (alignTo ((STI.getXLen () / 8 ) * PushedRegNum, 16 ));
1426
-
1460
+ unsigned PushedRegNum = RVFI->getRVPushRegs ();
1461
+ if (PushedRegNum > 0 ) {
1427
1462
// Use encoded number to represent registers to spill.
1428
- RVFI->setRVPushRlist (RegEnc );
1463
+ int RegEnc = RVFI->getRVPushRlist ( );
1429
1464
MachineInstrBuilder PushBuilder =
1430
1465
BuildMI (MBB, MI, DL, TII.get (RISCV::CM_PUSH))
1431
1466
.setMIFlag (MachineInstr::FrameSetup);
0 commit comments