Skip to content

Commit 49a7772

Browse files
authored
[CodeGen] Replace (Min,Max)CSFrameIndex with flag on frame object [NFCI] (#170905)
This removes the tracking of the MinCSFrameIndex, and MaxCSFrameIndex markers, simplifying the target API. This brings the tracking for callee save spill slots in line with how we handle other properties of stack locations. A couple notes: 1) This requires doing scans of the entire object range, but we have other such instances in the code already, so I doubt this will matter in practice. 2) This removes the requirement that callee saved spill slots be contiguous in the frame index identified space. I marked this as NFCI because if prior code violated the contiguous range assumption - I can't find a case where we did - then this change might adjust frame layout in some edge cases. The motivation for this is mostly code readability, but I might use this as a primitive for something in an upcoming patch series around shrink wrapping. Haven't decided yet.
1 parent 4930e94 commit 49a7772

File tree

9 files changed

+78
-109
lines changed

9 files changed

+78
-109
lines changed

llvm/include/llvm/CodeGen/MachineFrameInfo.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ class MachineFrameInfo {
153153
/// register allocator.
154154
bool isStatepointSpillSlot = false;
155155

156+
/// If true, this stack slot is used for spilling a callee saved register
157+
/// in the calling convention of the containing function.
158+
bool isCalleeSaved = false;
159+
156160
/// Identifier for stack memory type analagous to address space. If this is
157161
/// non-0, the meaning is target defined. Offsets cannot be directly
158162
/// compared between objects with different stack IDs. The object may not
@@ -762,6 +766,18 @@ class MachineFrameInfo {
762766
return Objects[ObjectIdx+NumFixedObjects].isStatepointSpillSlot;
763767
}
764768

769+
bool isCalleeSavedObjectIndex(int ObjectIdx) const {
770+
assert(unsigned(ObjectIdx + NumFixedObjects) < Objects.size() &&
771+
"Invalid Object Idx!");
772+
return Objects[ObjectIdx + NumFixedObjects].isCalleeSaved;
773+
}
774+
775+
void setIsCalleeSavedObjectIndex(int ObjectIdx, bool IsCalleeSaved) {
776+
assert(unsigned(ObjectIdx + NumFixedObjects) < Objects.size() &&
777+
"Invalid Object Idx!");
778+
Objects[ObjectIdx + NumFixedObjects].isCalleeSaved = IsCalleeSaved;
779+
}
780+
765781
/// \see StackID
766782
uint8_t getStackID(int ObjectIdx) const {
767783
return Objects[ObjectIdx+NumFixedObjects].StackID;

llvm/include/llvm/CodeGen/TargetFrameLowering.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,6 @@ class LLVM_ABI TargetFrameLowering {
159159
/// returns false, spill slots will be assigned using generic implementation.
160160
/// assignCalleeSavedSpillSlots() may add, delete or rearrange elements of
161161
/// CSI.
162-
virtual bool assignCalleeSavedSpillSlots(MachineFunction &MF,
163-
const TargetRegisterInfo *TRI,
164-
std::vector<CalleeSavedInfo> &CSI,
165-
unsigned &MinCSFrameIndex,
166-
unsigned &MaxCSFrameIndex) const {
167-
return assignCalleeSavedSpillSlots(MF, TRI, CSI);
168-
}
169-
170162
virtual bool
171163
assignCalleeSavedSpillSlots(MachineFunction &MF,
172164
const TargetRegisterInfo *TRI,

llvm/lib/CodeGen/PrologEpilogInserter.cpp

Lines changed: 32 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,6 @@ namespace {
8080
class PEIImpl {
8181
RegScavenger *RS = nullptr;
8282

83-
// MinCSFrameIndex, MaxCSFrameIndex - Keeps the range of callee saved
84-
// stack frame indexes.
85-
unsigned MinCSFrameIndex = std::numeric_limits<unsigned>::max();
86-
unsigned MaxCSFrameIndex = 0;
87-
8883
// Save and Restore blocks of the current function. Typically there is a
8984
// single save block, unless Windows EH funclets are involved.
9085
MBBVector SaveBlocks;
@@ -456,9 +451,7 @@ void PEIImpl::calculateSaveRestoreBlocks(MachineFunction &MF) {
456451
}
457452

458453
static void assignCalleeSavedSpillSlots(MachineFunction &F,
459-
const BitVector &SavedRegs,
460-
unsigned &MinCSFrameIndex,
461-
unsigned &MaxCSFrameIndex) {
454+
const BitVector &SavedRegs) {
462455
if (SavedRegs.empty())
463456
return;
464457

@@ -490,8 +483,7 @@ static void assignCalleeSavedSpillSlots(MachineFunction &F,
490483

491484
const TargetFrameLowering *TFI = F.getSubtarget().getFrameLowering();
492485
MachineFrameInfo &MFI = F.getFrameInfo();
493-
if (!TFI->assignCalleeSavedSpillSlots(F, RegInfo, CSI, MinCSFrameIndex,
494-
MaxCSFrameIndex)) {
486+
if (!TFI->assignCalleeSavedSpillSlots(F, RegInfo, CSI)) {
495487
// If target doesn't implement this, use generic code.
496488

497489
if (CSI.empty())
@@ -534,8 +526,7 @@ static void assignCalleeSavedSpillSlots(MachineFunction &F,
534526
// min.
535527
Alignment = std::min(Alignment, TFI->getStackAlign());
536528
FrameIdx = MFI.CreateStackObject(Size, Alignment, true);
537-
if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx;
538-
if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx;
529+
MFI.setIsCalleeSavedObjectIndex(FrameIdx, true);
539530
} else {
540531
// Spill it to the stack where we must.
541532
FrameIdx = MFI.CreateFixedSpillStackObject(Size, FixedSlot->Offset);
@@ -676,15 +667,13 @@ void PEIImpl::spillCalleeSavedRegs(MachineFunction &MF) {
676667
const Function &F = MF.getFunction();
677668
const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
678669
MachineFrameInfo &MFI = MF.getFrameInfo();
679-
MinCSFrameIndex = std::numeric_limits<unsigned>::max();
680-
MaxCSFrameIndex = 0;
681670

682671
// Determine which of the registers in the callee save list should be saved.
683672
BitVector SavedRegs;
684673
TFI->determineCalleeSaves(MF, SavedRegs, RS);
685674

686675
// Assign stack slots for any callee-saved registers that must be spilled.
687-
assignCalleeSavedSpillSlots(MF, SavedRegs, MinCSFrameIndex, MaxCSFrameIndex);
676+
assignCalleeSavedSpillSlots(MF, SavedRegs);
688677

689678
// Add the code to save and restore the callee saved registers.
690679
if (!F.hasFnAttribute(Attribute::Naked)) {
@@ -752,10 +741,10 @@ static inline void AdjustStackOffset(MachineFrameInfo &MFI, int FrameIdx,
752741

753742
/// Compute which bytes of fixed and callee-save stack area are unused and keep
754743
/// track of them in StackBytesFree.
755-
static inline void
756-
computeFreeStackSlots(MachineFrameInfo &MFI, bool StackGrowsDown,
757-
unsigned MinCSFrameIndex, unsigned MaxCSFrameIndex,
758-
int64_t FixedCSEnd, BitVector &StackBytesFree) {
744+
static inline void computeFreeStackSlots(MachineFrameInfo &MFI,
745+
bool StackGrowsDown,
746+
int64_t FixedCSEnd,
747+
BitVector &StackBytesFree) {
759748
// Avoid undefined int64_t -> int conversion below in extreme case.
760749
if (FixedCSEnd > std::numeric_limits<int>::max())
761750
return;
@@ -769,11 +758,10 @@ computeFreeStackSlots(MachineFrameInfo &MFI, bool StackGrowsDown,
769758
if (MFI.getStackID(i) == TargetStackID::Default)
770759
AllocatedFrameSlots.push_back(i);
771760
// Add callee-save objects if there are any.
772-
if (MinCSFrameIndex <= MaxCSFrameIndex) {
773-
for (int i = MinCSFrameIndex; i <= (int)MaxCSFrameIndex; ++i)
774-
if (MFI.getStackID(i) == TargetStackID::Default)
775-
AllocatedFrameSlots.push_back(i);
776-
}
761+
for (int i = MFI.getObjectIndexBegin(); i < MFI.getObjectIndexEnd(); i++)
762+
if (MFI.isCalleeSavedObjectIndex(i) &&
763+
MFI.getStackID(i) == TargetStackID::Default)
764+
AllocatedFrameSlots.push_back(i);
777765

778766
for (int i : AllocatedFrameSlots) {
779767
// These are converted from int64_t, but they should always fit in int
@@ -923,20 +911,28 @@ void PEIImpl::calculateFrameObjectOffsets(MachineFunction &MF) {
923911
Align MaxAlign = MFI.getMaxAlign();
924912
// First assign frame offsets to stack objects that are used to spill
925913
// callee saved registers.
926-
if (MaxCSFrameIndex >= MinCSFrameIndex) {
927-
for (unsigned i = 0; i <= MaxCSFrameIndex - MinCSFrameIndex; ++i) {
928-
unsigned FrameIndex =
929-
StackGrowsDown ? MinCSFrameIndex + i : MaxCSFrameIndex - i;
930-
914+
if (StackGrowsDown) {
915+
for (int FI = MFI.getObjectIndexBegin(); FI < MFI.getObjectIndexEnd();
916+
FI++) {
917+
// Only allocate objects on the default stack.
918+
if (!MFI.isCalleeSavedObjectIndex(FI) ||
919+
MFI.getStackID(FI) != TargetStackID::Default)
920+
continue;
921+
// TODO: should we be using MFI.isDeadObjectIndex(FI) here?
922+
AdjustStackOffset(MFI, FI, StackGrowsDown, Offset, MaxAlign);
923+
}
924+
} else {
925+
for (int FI = MFI.getObjectIndexEnd() - 1; FI >= MFI.getObjectIndexBegin();
926+
FI--) {
931927
// Only allocate objects on the default stack.
932-
if (MFI.getStackID(FrameIndex) != TargetStackID::Default)
928+
if (!MFI.isCalleeSavedObjectIndex(FI) ||
929+
MFI.getStackID(FI) != TargetStackID::Default)
933930
continue;
934931

935-
// TODO: should this just be if (MFI.isDeadObjectIndex(FrameIndex))
936-
if (!StackGrowsDown && MFI.isDeadObjectIndex(FrameIndex))
932+
if (MFI.isDeadObjectIndex(FI))
937933
continue;
938934

939-
AdjustStackOffset(MFI, FrameIndex, StackGrowsDown, Offset, MaxAlign);
935+
AdjustStackOffset(MFI, FI, StackGrowsDown, Offset, MaxAlign);
940936
}
941937
}
942938

@@ -1025,7 +1021,7 @@ void PEIImpl::calculateFrameObjectOffsets(MachineFunction &MF) {
10251021
for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) {
10261022
if (MFI.isObjectPreAllocated(i) && MFI.getUseLocalStackAllocationBlock())
10271023
continue;
1028-
if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
1024+
if (MFI.isCalleeSavedObjectIndex(i))
10291025
continue;
10301026
if (RS && RS->isScavengingFrameIndex((int)i))
10311027
continue;
@@ -1077,7 +1073,7 @@ void PEIImpl::calculateFrameObjectOffsets(MachineFunction &MF) {
10771073
for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) {
10781074
if (MFI.isObjectPreAllocated(i) && MFI.getUseLocalStackAllocationBlock())
10791075
continue;
1080-
if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
1076+
if (MFI.isCalleeSavedObjectIndex(i))
10811077
continue;
10821078
if (RS && RS->isScavengingFrameIndex((int)i))
10831079
continue;
@@ -1113,8 +1109,7 @@ void PEIImpl::calculateFrameObjectOffsets(MachineFunction &MF) {
11131109
if (!ObjectsToAllocate.empty() &&
11141110
MF.getTarget().getOptLevel() != CodeGenOptLevel::None &&
11151111
MFI.getStackProtectorIndex() < 0 && TFI.enableStackSlotScavenging(MF))
1116-
computeFreeStackSlots(MFI, StackGrowsDown, MinCSFrameIndex, MaxCSFrameIndex,
1117-
FixedCSEnd, StackBytesFree);
1112+
computeFreeStackSlots(MFI, StackGrowsDown, FixedCSEnd, StackBytesFree);
11181113

11191114
// Now walk the objects and actually assign base offsets to them.
11201115
for (auto &Object : ObjectsToAllocate)

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2755,8 +2755,7 @@ void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF,
27552755

27562756
bool AArch64FrameLowering::assignCalleeSavedSpillSlots(
27572757
MachineFunction &MF, const TargetRegisterInfo *RegInfo,
2758-
std::vector<CalleeSavedInfo> &CSI, unsigned &MinCSFrameIndex,
2759-
unsigned &MaxCSFrameIndex) const {
2758+
std::vector<CalleeSavedInfo> &CSI) const {
27602759
bool NeedsWinCFI = needsWinCFI(MF);
27612760
unsigned StackHazardSize = getStackHazardSize(MF);
27622761
// To match the canonical windows frame layout, reverse the list of
@@ -2779,10 +2778,7 @@ bool AArch64FrameLowering::assignCalleeSavedSpillSlots(
27792778
if (UsesWinAAPCS && hasFP(MF) && AFI->hasSwiftAsyncContext()) {
27802779
int FrameIdx = MFI.CreateStackObject(8, Align(16), true);
27812780
AFI->setSwiftAsyncContextFrameIdx(FrameIdx);
2782-
if ((unsigned)FrameIdx < MinCSFrameIndex)
2783-
MinCSFrameIndex = FrameIdx;
2784-
if ((unsigned)FrameIdx > MaxCSFrameIndex)
2785-
MaxCSFrameIndex = FrameIdx;
2781+
MFI.setIsCalleeSavedObjectIndex(FrameIdx, true);
27862782
}
27872783

27882784
// Insert VG into the list of CSRs, immediately before LR if saved.
@@ -2812,31 +2808,21 @@ bool AArch64FrameLowering::assignCalleeSavedSpillSlots(
28122808
LLVM_DEBUG(dbgs() << "Created CSR Hazard at slot " << HazardSlotIndex
28132809
<< "\n");
28142810
AFI->setStackHazardCSRSlotIndex(HazardSlotIndex);
2815-
if ((unsigned)HazardSlotIndex < MinCSFrameIndex)
2816-
MinCSFrameIndex = HazardSlotIndex;
2817-
if ((unsigned)HazardSlotIndex > MaxCSFrameIndex)
2818-
MaxCSFrameIndex = HazardSlotIndex;
2811+
MFI.setIsCalleeSavedObjectIndex(HazardSlotIndex, true);
28192812
}
28202813

28212814
unsigned Size = RegInfo->getSpillSize(*RC);
28222815
Align Alignment(RegInfo->getSpillAlign(*RC));
28232816
int FrameIdx = MFI.CreateStackObject(Size, Alignment, true);
28242817
CS.setFrameIdx(FrameIdx);
2825-
2826-
if ((unsigned)FrameIdx < MinCSFrameIndex)
2827-
MinCSFrameIndex = FrameIdx;
2828-
if ((unsigned)FrameIdx > MaxCSFrameIndex)
2829-
MaxCSFrameIndex = FrameIdx;
2818+
MFI.setIsCalleeSavedObjectIndex(FrameIdx, true);
28302819

28312820
// Grab 8 bytes below FP for the extended asynchronous frame info.
28322821
if (hasFP(MF) && AFI->hasSwiftAsyncContext() && !UsesWinAAPCS &&
28332822
Reg == AArch64::FP) {
28342823
FrameIdx = MFI.CreateStackObject(8, Alignment, true);
28352824
AFI->setSwiftAsyncContextFrameIdx(FrameIdx);
2836-
if ((unsigned)FrameIdx < MinCSFrameIndex)
2837-
MinCSFrameIndex = FrameIdx;
2838-
if ((unsigned)FrameIdx > MaxCSFrameIndex)
2839-
MaxCSFrameIndex = FrameIdx;
2825+
MFI.setIsCalleeSavedObjectIndex(FrameIdx, true);
28402826
}
28412827
LastReg = Reg;
28422828
}
@@ -2848,10 +2834,7 @@ bool AArch64FrameLowering::assignCalleeSavedSpillSlots(
28482834
LLVM_DEBUG(dbgs() << "Created CSR Hazard at slot " << HazardSlotIndex
28492835
<< "\n");
28502836
AFI->setStackHazardCSRSlotIndex(HazardSlotIndex);
2851-
if ((unsigned)HazardSlotIndex < MinCSFrameIndex)
2852-
MinCSFrameIndex = HazardSlotIndex;
2853-
if ((unsigned)HazardSlotIndex > MaxCSFrameIndex)
2854-
MaxCSFrameIndex = HazardSlotIndex;
2837+
MFI.setIsCalleeSavedObjectIndex(HazardSlotIndex, true);
28552838
}
28562839

28572840
return true;
@@ -2968,9 +2951,8 @@ static SVEStackSizes determineSVEStackSizes(MachineFunction &MF,
29682951
}
29692952

29702953
for (int FI = 0, E = MFI.getObjectIndexEnd(); FI != E; ++FI) {
2971-
if (FI == StackProtectorFI || MFI.isDeadObjectIndex(FI))
2972-
continue;
2973-
if (MaxCSFrameIndex >= FI && FI >= MinCSFrameIndex)
2954+
if (FI == StackProtectorFI || MFI.isDeadObjectIndex(FI) ||
2955+
MFI.isCalleeSavedObjectIndex(FI))
29742956
continue;
29752957

29762958
if (MFI.getStackID(FI) != TargetStackID::ScalableVector &&

llvm/lib/Target/AArch64/AArch64FrameLowering.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,10 @@ class AArch64FrameLowering : public TargetFrameLowering {
8888

8989
bool hasReservedCallFrame(const MachineFunction &MF) const override;
9090

91-
bool assignCalleeSavedSpillSlots(MachineFunction &MF,
92-
const TargetRegisterInfo *TRI,
93-
std::vector<CalleeSavedInfo> &CSI,
94-
unsigned &MinCSFrameIndex,
95-
unsigned &MaxCSFrameIndex) const override;
91+
bool
92+
assignCalleeSavedSpillSlots(MachineFunction &MF,
93+
const TargetRegisterInfo *TRI,
94+
std::vector<CalleeSavedInfo> &CSI) const override;
9695

9796
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
9897
RegScavenger *RS) const override;

llvm/lib/Target/AMDGPU/SIFrameLowering.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,9 +1844,7 @@ void SIFrameLowering::determineCalleeSavesSGPR(MachineFunction &MF,
18441844

18451845
static void assignSlotsUsingVGPRBlocks(MachineFunction &MF,
18461846
const GCNSubtarget &ST,
1847-
std::vector<CalleeSavedInfo> &CSI,
1848-
unsigned &MinCSFrameIndex,
1849-
unsigned &MaxCSFrameIndex) {
1847+
std::vector<CalleeSavedInfo> &CSI) {
18501848
SIMachineFunctionInfo *FuncInfo = MF.getInfo<SIMachineFunctionInfo>();
18511849
MachineFrameInfo &MFI = MF.getFrameInfo();
18521850
const SIRegisterInfo *TRI = ST.getRegisterInfo();
@@ -1915,10 +1913,7 @@ static void assignSlotsUsingVGPRBlocks(MachineFunction &MF,
19151913
int FrameIdx =
19161914
MFI.CreateStackObject(BlockSize, TRI->getSpillAlign(*BlockRegClass),
19171915
/*isSpillSlot=*/true);
1918-
if ((unsigned)FrameIdx < MinCSFrameIndex)
1919-
MinCSFrameIndex = FrameIdx;
1920-
if ((unsigned)FrameIdx > MaxCSFrameIndex)
1921-
MaxCSFrameIndex = FrameIdx;
1916+
MFI.setIsCalleeSavedObjectIndex(FrameIdx, true);
19221917

19231918
CSIt->setFrameIdx(FrameIdx);
19241919
CSIt->setReg(RegBlock);
@@ -1928,21 +1923,20 @@ static void assignSlotsUsingVGPRBlocks(MachineFunction &MF,
19281923

19291924
bool SIFrameLowering::assignCalleeSavedSpillSlots(
19301925
MachineFunction &MF, const TargetRegisterInfo *TRI,
1931-
std::vector<CalleeSavedInfo> &CSI, unsigned &MinCSFrameIndex,
1932-
unsigned &MaxCSFrameIndex) const {
1926+
std::vector<CalleeSavedInfo> &CSI) const {
19331927
if (CSI.empty())
19341928
return true; // Early exit if no callee saved registers are modified!
19351929

19361930
const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
19371931
bool UseVGPRBlocks = ST.useVGPRBlockOpsForCSR();
19381932

19391933
if (UseVGPRBlocks)
1940-
assignSlotsUsingVGPRBlocks(MF, ST, CSI, MinCSFrameIndex, MaxCSFrameIndex);
1934+
assignSlotsUsingVGPRBlocks(MF, ST, CSI);
19411935

1942-
return assignCalleeSavedSpillSlots(MF, TRI, CSI) || UseVGPRBlocks;
1936+
return assignCalleeSavedSpillSlotsImpl(MF, TRI, CSI) || UseVGPRBlocks;
19431937
}
19441938

1945-
bool SIFrameLowering::assignCalleeSavedSpillSlots(
1939+
bool SIFrameLowering::assignCalleeSavedSpillSlotsImpl(
19461940
MachineFunction &MF, const TargetRegisterInfo *TRI,
19471941
std::vector<CalleeSavedInfo> &CSI) const {
19481942
if (CSI.empty())

llvm/lib/Target/AMDGPU/SIFrameLowering.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,9 @@ class SIFrameLowering final : public AMDGPUFrameLowering {
4949
const TargetRegisterInfo *TRI,
5050
std::vector<CalleeSavedInfo> &CSI) const override;
5151

52-
bool assignCalleeSavedSpillSlots(MachineFunction &MF,
53-
const TargetRegisterInfo *TRI,
54-
std::vector<CalleeSavedInfo> &CSI,
55-
unsigned &MinCSFrameIndex,
56-
unsigned &MaxCSFrameIndex) const override;
52+
bool assignCalleeSavedSpillSlotsImpl(MachineFunction &MF,
53+
const TargetRegisterInfo *TRI,
54+
std::vector<CalleeSavedInfo> &CSI) const;
5755

5856
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
5957
MachineBasicBlock::iterator MI,

0 commit comments

Comments
 (0)