Skip to content

Commit a22b599

Browse files
committed
[llvm] support save/restore point splitting in shrink-wrap
This patch introduces "-enable-shrink-wrap-into-multiple-points" option, which enables splitting Save and Restore points during ShrinkWrap pass, i.e. insert registers saves and restores as close as possible to their usage. Current algorithm disables Save / Restore point splitting for functions with instructions with FrameIndex operands, with EHPads and with any Stack accesses beacuse it is difficult to prove the safety of it. This patch also add support for multiple Save / Restore points only for RISCV. Now ShrinkWrap produces: - list of SavePoint + Registers - list of RestorePoint + Registers - Prolog (NCD of Save points) - Epilog (NCPD of Restore points)
1 parent e7c0fb9 commit a22b599

File tree

9 files changed

+734
-152
lines changed

9 files changed

+734
-152
lines changed

llvm/include/llvm/CodeGen/TargetFrameLowering.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ class LLVM_ABI TargetFrameLowering {
201201
return false;
202202
}
203203

204+
/// enableCSRSaveRestorePointsSplit - Returns true if the target support
205+
/// multiple save/restore points in shrink wrapping.
206+
virtual bool enableCSRSaveRestorePointsSplit() const { return false; }
207+
204208
/// Returns true if the stack slot holes in the fixed and callee-save stack
205209
/// area should be used when allocating other stack locations to reduce stack
206210
/// size.

llvm/lib/CodeGen/PrologEpilogInserter.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -458,19 +458,19 @@ void PEIImpl::calculateSaveRestoreBlocks(MachineFunction &MF) {
458458

459459
// Use the points found by shrink-wrapping, if any.
460460
if (!MFI.getSavePoints().empty()) {
461-
assert(MFI.getSavePoints().size() == 1 &&
462-
"Multiple save points are not yet supported!");
463-
const auto &SavePoint = *MFI.getSavePoints().begin();
464-
SaveBlocks.push_back(SavePoint.first);
465-
assert(MFI.getRestorePoints().size() == 1 &&
466-
"Multiple restore points are not yet supported!");
467-
const auto &RestorePoint = *MFI.getRestorePoints().begin();
468-
MachineBasicBlock *RestoreBlock = RestorePoint.first;
469-
// If RestoreBlock does not have any successor and is not a return block
470-
// then the end point is unreachable and we do not need to insert any
471-
// epilogue.
472-
if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock())
473-
RestoreBlocks.push_back(RestoreBlock);
461+
assert(!MFI.getRestorePoints().empty() &&
462+
"Both restore and save must be set");
463+
for (auto &item : MFI.getSavePoints())
464+
SaveBlocks.push_back(item.first);
465+
466+
for (auto &item : MFI.getRestorePoints()) {
467+
MachineBasicBlock *RestoreBlock = item.first;
468+
// If RestoreBlock does not have any successor and is not a return block
469+
// then the end point is unreachable and we do not need to insert any
470+
// epilogue.
471+
if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock())
472+
RestoreBlocks.push_back(RestoreBlock);
473+
}
474474
return;
475475
}
476476

@@ -767,7 +767,7 @@ void PEIImpl::spillCalleeSavedRegs(MachineFunction &MF) {
767767
for (auto &CS : CSI)
768768
RegToInfo.insert({CS.getReg(), &CS});
769769

770-
if (MFI.getSavePoints().size() > 1) {
770+
if (!MFI.getSavePoints().empty()) {
771771
fillCSInfoPerBB(MFI, RegToInfo, PrologBlocks, /*isSave=*/true);
772772
fillCSInfoPerBB(MFI, RegToInfo, EpilogBlocks, /*isSave=*/false);
773773
} else {
@@ -801,7 +801,7 @@ void PEIImpl::spillCalleeSavedRegs(MachineFunction &MF) {
801801
updateLiveness(MF, Save, Restore, CS);
802802
}
803803

804-
if (MFI.getRestorePoints().size() <= 1) {
804+
if (MFI.getRestorePoints().empty()) {
805805
SaveRestorePoints RestorePts;
806806
for (MachineBasicBlock *EpilogBlock : EpilogBlocks)
807807
RestorePts.insert({EpilogBlock, MFI.getCalleeSavedInfo()});

0 commit comments

Comments
 (0)