-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[CodeGen] Replace (Min,Max)CSFrameIndex with flag on frame object [NFCI] #170905
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -80,11 +80,6 @@ namespace { | |
| class PEIImpl { | ||
| RegScavenger *RS = nullptr; | ||
|
|
||
| // MinCSFrameIndex, MaxCSFrameIndex - Keeps the range of callee saved | ||
| // stack frame indexes. | ||
| unsigned MinCSFrameIndex = std::numeric_limits<unsigned>::max(); | ||
| unsigned MaxCSFrameIndex = 0; | ||
|
|
||
| // Save and Restore blocks of the current function. Typically there is a | ||
| // single save block, unless Windows EH funclets are involved. | ||
| MBBVector SaveBlocks; | ||
|
|
@@ -456,9 +451,7 @@ void PEIImpl::calculateSaveRestoreBlocks(MachineFunction &MF) { | |
| } | ||
|
|
||
| static void assignCalleeSavedSpillSlots(MachineFunction &F, | ||
| const BitVector &SavedRegs, | ||
| unsigned &MinCSFrameIndex, | ||
| unsigned &MaxCSFrameIndex) { | ||
| const BitVector &SavedRegs) { | ||
| if (SavedRegs.empty()) | ||
| return; | ||
|
|
||
|
|
@@ -490,8 +483,7 @@ static void assignCalleeSavedSpillSlots(MachineFunction &F, | |
|
|
||
| const TargetFrameLowering *TFI = F.getSubtarget().getFrameLowering(); | ||
| MachineFrameInfo &MFI = F.getFrameInfo(); | ||
| if (!TFI->assignCalleeSavedSpillSlots(F, RegInfo, CSI, MinCSFrameIndex, | ||
| MaxCSFrameIndex)) { | ||
| if (!TFI->assignCalleeSavedSpillSlots(F, RegInfo, CSI)) { | ||
| // If target doesn't implement this, use generic code. | ||
|
|
||
| if (CSI.empty()) | ||
|
|
@@ -534,8 +526,7 @@ static void assignCalleeSavedSpillSlots(MachineFunction &F, | |
| // min. | ||
| Alignment = std::min(Alignment, TFI->getStackAlign()); | ||
| FrameIdx = MFI.CreateStackObject(Size, Alignment, true); | ||
| if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx; | ||
| if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx; | ||
| MFI.setIsCalleeSavedObjectIndex(FrameIdx, true); | ||
| } else { | ||
| // Spill it to the stack where we must. | ||
| FrameIdx = MFI.CreateFixedSpillStackObject(Size, FixedSlot->Offset); | ||
|
|
@@ -676,15 +667,13 @@ void PEIImpl::spillCalleeSavedRegs(MachineFunction &MF) { | |
| const Function &F = MF.getFunction(); | ||
| const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); | ||
| MachineFrameInfo &MFI = MF.getFrameInfo(); | ||
| MinCSFrameIndex = std::numeric_limits<unsigned>::max(); | ||
| MaxCSFrameIndex = 0; | ||
|
|
||
| // Determine which of the registers in the callee save list should be saved. | ||
| BitVector SavedRegs; | ||
| TFI->determineCalleeSaves(MF, SavedRegs, RS); | ||
|
|
||
| // Assign stack slots for any callee-saved registers that must be spilled. | ||
| assignCalleeSavedSpillSlots(MF, SavedRegs, MinCSFrameIndex, MaxCSFrameIndex); | ||
| assignCalleeSavedSpillSlots(MF, SavedRegs); | ||
|
|
||
| // Add the code to save and restore the callee saved registers. | ||
| if (!F.hasFnAttribute(Attribute::Naked)) { | ||
|
|
@@ -752,10 +741,10 @@ static inline void AdjustStackOffset(MachineFrameInfo &MFI, int FrameIdx, | |
|
|
||
| /// Compute which bytes of fixed and callee-save stack area are unused and keep | ||
| /// track of them in StackBytesFree. | ||
| static inline void | ||
| computeFreeStackSlots(MachineFrameInfo &MFI, bool StackGrowsDown, | ||
| unsigned MinCSFrameIndex, unsigned MaxCSFrameIndex, | ||
| int64_t FixedCSEnd, BitVector &StackBytesFree) { | ||
| static inline void computeFreeStackSlots(MachineFrameInfo &MFI, | ||
| bool StackGrowsDown, | ||
| int64_t FixedCSEnd, | ||
| BitVector &StackBytesFree) { | ||
| // Avoid undefined int64_t -> int conversion below in extreme case. | ||
| if (FixedCSEnd > std::numeric_limits<int>::max()) | ||
| return; | ||
|
|
@@ -769,11 +758,10 @@ computeFreeStackSlots(MachineFrameInfo &MFI, bool StackGrowsDown, | |
| if (MFI.getStackID(i) == TargetStackID::Default) | ||
| AllocatedFrameSlots.push_back(i); | ||
| // Add callee-save objects if there are any. | ||
| if (MinCSFrameIndex <= MaxCSFrameIndex) { | ||
| for (int i = MinCSFrameIndex; i <= (int)MaxCSFrameIndex; ++i) | ||
| if (MFI.getStackID(i) == TargetStackID::Default) | ||
| AllocatedFrameSlots.push_back(i); | ||
| } | ||
| for (int i = MFI.getObjectIndexBegin(); i < MFI.getObjectIndexEnd(); i++) | ||
| if (MFI.isCalleeSavedObjectIndex(i) && | ||
| MFI.getStackID(i) == TargetStackID::Default) | ||
| AllocatedFrameSlots.push_back(i); | ||
|
|
||
| for (int i : AllocatedFrameSlots) { | ||
| // These are converted from int64_t, but they should always fit in int | ||
|
|
@@ -923,20 +911,28 @@ void PEIImpl::calculateFrameObjectOffsets(MachineFunction &MF) { | |
| Align MaxAlign = MFI.getMaxAlign(); | ||
| // First assign frame offsets to stack objects that are used to spill | ||
| // callee saved registers. | ||
| if (MaxCSFrameIndex >= MinCSFrameIndex) { | ||
| for (unsigned i = 0; i <= MaxCSFrameIndex - MinCSFrameIndex; ++i) { | ||
| unsigned FrameIndex = | ||
| StackGrowsDown ? MinCSFrameIndex + i : MaxCSFrameIndex - i; | ||
|
|
||
| if (StackGrowsDown) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Feel free to reject this, but I think you could do something like: auto AllFIsSeq = seq(MFI.getObjectIndexBegin(), MFI.getObjectIndexEnd());
for (auto [FILo, FIHi] : zip_equal(AllFIsSeq, reverse(AllFIsSeq))) {
int FI = StackGrowsDown ? FILo : FIHi;
// Only allocate objects on the default stack.
if (!MFI.isCalleeSavedObjectIndex(FI) ||
MFI.getStackID(FI) != TargetStackID::Default)
continue;
// TODO: should this just be if (MFI.isDeadObjectIndex(FI))
if (!StackGrowsDown && MFI.isDeadObjectIndex(FI))
continue;
AdjustStackOffset(MFI, FI, StackGrowsDown, Offset, MaxAlign);
}Rather than duplicate the loop for forwards/reverse (IIUC).
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Personally, I'd find that much harder to reason about. The idea of using a sequence is interesting though, maybe we could conditional reverse a sequence instead? I'll play with this a bit and may tag you for review on a followup.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No worries 👍 You could wrap this trick up as: template <typename ContainerTy>
[[nodiscard]] auto conditionally_reverse(ContainerTy &&C, bool Reverse) {
return map_range(zip_equal(reverse(C), C), [Reverse](auto I) {
return Reverse ? std::get<0>(I) : std::get<1>(I);
});
}(Probably would fit in Which allows for: auto AllFIs = seq(MFI.getObjectIndexBegin(), MFI.getObjectIndexEnd());
for (auto FI : conditionally_reverse(AllFIs, /*Reverse=*/!StackGrowsDown)) {
// ...
} |
||
| for (int FI = MFI.getObjectIndexBegin(); FI < MFI.getObjectIndexEnd(); | ||
| FI++) { | ||
| // Only allocate objects on the default stack. | ||
| if (!MFI.isCalleeSavedObjectIndex(FI) || | ||
| MFI.getStackID(FI) != TargetStackID::Default) | ||
| continue; | ||
| // TODO: should we be using MFI.isDeadObjectIndex(FI) here? | ||
| AdjustStackOffset(MFI, FI, StackGrowsDown, Offset, MaxAlign); | ||
| } | ||
| } else { | ||
| for (int FI = MFI.getObjectIndexEnd() - 1; FI >= MFI.getObjectIndexBegin(); | ||
| FI--) { | ||
| // Only allocate objects on the default stack. | ||
| if (MFI.getStackID(FrameIndex) != TargetStackID::Default) | ||
| if (!MFI.isCalleeSavedObjectIndex(FI) || | ||
| MFI.getStackID(FI) != TargetStackID::Default) | ||
| continue; | ||
|
|
||
| // TODO: should this just be if (MFI.isDeadObjectIndex(FrameIndex)) | ||
| if (!StackGrowsDown && MFI.isDeadObjectIndex(FrameIndex)) | ||
| if (MFI.isDeadObjectIndex(FI)) | ||
| continue; | ||
|
|
||
| AdjustStackOffset(MFI, FrameIndex, StackGrowsDown, Offset, MaxAlign); | ||
| AdjustStackOffset(MFI, FI, StackGrowsDown, Offset, MaxAlign); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -1025,7 +1021,7 @@ void PEIImpl::calculateFrameObjectOffsets(MachineFunction &MF) { | |
| for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) { | ||
| if (MFI.isObjectPreAllocated(i) && MFI.getUseLocalStackAllocationBlock()) | ||
| continue; | ||
| if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) | ||
| if (MFI.isCalleeSavedObjectIndex(i)) | ||
| continue; | ||
| if (RS && RS->isScavengingFrameIndex((int)i)) | ||
| continue; | ||
|
|
@@ -1077,7 +1073,7 @@ void PEIImpl::calculateFrameObjectOffsets(MachineFunction &MF) { | |
| for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) { | ||
| if (MFI.isObjectPreAllocated(i) && MFI.getUseLocalStackAllocationBlock()) | ||
| continue; | ||
| if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) | ||
| if (MFI.isCalleeSavedObjectIndex(i)) | ||
| continue; | ||
| if (RS && RS->isScavengingFrameIndex((int)i)) | ||
| continue; | ||
|
|
@@ -1113,8 +1109,7 @@ void PEIImpl::calculateFrameObjectOffsets(MachineFunction &MF) { | |
| if (!ObjectsToAllocate.empty() && | ||
| MF.getTarget().getOptLevel() != CodeGenOptLevel::None && | ||
| MFI.getStackProtectorIndex() < 0 && TFI.enableStackSlotScavenging(MF)) | ||
| computeFreeStackSlots(MFI, StackGrowsDown, MinCSFrameIndex, MaxCSFrameIndex, | ||
| FixedCSEnd, StackBytesFree); | ||
| computeFreeStackSlots(MFI, StackGrowsDown, FixedCSEnd, StackBytesFree); | ||
|
|
||
| // Now walk the objects and actually assign base offsets to them. | ||
| for (auto &Object : ObjectsToAllocate) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.