diff --git a/llvm/include/llvm/CodeGen/TargetFrameLowering.h b/llvm/include/llvm/CodeGen/TargetFrameLowering.h index 75696faf114cc..c04cd33b3377a 100644 --- a/llvm/include/llvm/CodeGen/TargetFrameLowering.h +++ b/llvm/include/llvm/CodeGen/TargetFrameLowering.h @@ -375,13 +375,13 @@ class LLVM_ABI TargetFrameLowering { virtual StackOffset getFrameIndexReferenceFromSP(const MachineFunction &MF, int FI) const; - /// Returns the callee-saved registers as computed by determineCalleeSaves - /// in the BitVector \p SavedRegs. + /// Returns the callee-saved registers as computed by + /// determinePrologCalleeSaves in the BitVector \p SavedRegs. virtual void getCalleeSaves(const MachineFunction &MF, BitVector &SavedRegs) const; /// This method determines which of the registers reported by - /// TargetRegisterInfo::getCalleeSavedRegs() should actually get saved. + /// getMustPreserveRegisters() should actually get saved. /// The default implementation checks populates the \p SavedRegs bitset with /// all registers which are modified in the function, targets may override /// this function to save additional registers. @@ -390,9 +390,38 @@ class LLVM_ABI TargetFrameLowering { /// This method should not be called by any passes outside of PEI, because /// it may change state passed in by \p MF and \p RS. The preferred /// interface outside PEI is getCalleeSaves. + LLVM_DEPRECATED("Use determinePrologCalleeSaves instead", + "determinePrologCalleeSaves") virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS = nullptr) const; + /// Return the list of registers which must be preserved by the function: the + /// value on exit must be the same as the value on entry. A register from this + /// list does not need to be saved / reloaded if the function did not use it. + const MCPhysReg *getMustPreserveRegisters(MachineFunction &MF) const; + + /// This method determines which of the registers reported by + /// getMustPreserveRegisters() must be saved in prolog and reloaded in epilog + /// regardless of wheather or not they were modified by the function. + virtual void + determineUncondPrologCalleeSaves(MachineFunction &MF, const MCPhysReg *CSRegs, + BitVector &UncondPrologCSRs) const; + + /// If the target has to do all saves / restores of "must preserve" registers + /// in prolog / epilog, this method returns empty set. Otherwise, this method + /// returns the difference between getMustPreserveRegisters and + /// determineUncondPrologCalleeSaves. These registers will be preserved by the + /// code optimizer and do not need to be saved in prolog. + virtual void determineEarlyCalleeSaves(MachineFunction &MF, + BitVector &EarlyCSRs) const; + + /// This method returns those registers in the difference of + /// getMustPreserveRegisters and determineEarlyCalleeSaves that were modified + /// by the function and need to be saved in prolog. + virtual void determinePrologCalleeSaves(MachineFunction &MF, + BitVector &PrologCSRs, + RegScavenger *RS) const; + /// processFunctionBeforeFrameFinalized - This method is called immediately /// before the specified function's frame layout (MF.getFrameInfo()) is /// finalized. Once the frame is finalized, MO_FrameIndex operands are diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h index 35b14e8b8fd30..f8453f8394ab7 100644 --- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h +++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h @@ -1066,7 +1066,7 @@ class LLVM_ABI TargetRegisterInfo : public MCRegisterInfo { /// register is required, the first fixed stack object is reserved as its /// spill slot. This tells PEI not to create a new stack frame /// object for the given register. It should be called only after - /// determineCalleeSaves(). + /// determinePrologCalleeSaves(). virtual bool hasReservedSpillSlot(const MachineFunction &MF, Register Reg, int &FrameIdx) const { return false; diff --git a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h index 6f95f0fea6441..57978c8585a6a 100644 --- a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h +++ b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h @@ -364,6 +364,10 @@ class LLVM_ABI TargetSubtargetInfo : public MCSubtargetInfo { } virtual bool isRegisterReservedByUser(Register R) const { return false; } + + // Return true if the target can ensure before PrologEpilogInsertion that + // callee-saved registers are preserved. + virtual bool savesCSRsEarly() const { return false; } }; } // end namespace llvm diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index 41efe622417c8..2639edcfed0a2 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -681,7 +681,7 @@ void PEIImpl::spillCalleeSavedRegs(MachineFunction &MF) { // Determine which of the registers in the callee save list should be saved. BitVector SavedRegs; - TFI->determineCalleeSaves(MF, SavedRegs, RS); + TFI->determinePrologCalleeSaves(MF, SavedRegs, RS); // Assign stack slots for any callee-saved registers that must be spilled. assignCalleeSavedSpillSlots(MF, SavedRegs, MinCSFrameIndex, MaxCSFrameIndex); diff --git a/llvm/lib/CodeGen/RegisterScavenging.cpp b/llvm/lib/CodeGen/RegisterScavenging.cpp index d8861672a348f..cc5da28a95d85 100644 --- a/llvm/lib/CodeGen/RegisterScavenging.cpp +++ b/llvm/lib/CodeGen/RegisterScavenging.cpp @@ -511,7 +511,7 @@ class ScavengerTest : public MachineFunctionPass { // well enough to initialize the scavenger with some emergency spillslots // for the target. BitVector SavedRegs; - TFL.determineCalleeSaves(MF, SavedRegs, &RS); + TFL.determinePrologCalleeSaves(MF, SavedRegs, &RS); TFL.processFunctionBeforeFrameFinalized(MF, &RS); // Let's scavenge the current function diff --git a/llvm/lib/CodeGen/ShrinkWrap.cpp b/llvm/lib/CodeGen/ShrinkWrap.cpp index 83581052560cb..6933b7614e01d 100644 --- a/llvm/lib/CodeGen/ShrinkWrap.cpp +++ b/llvm/lib/CodeGen/ShrinkWrap.cpp @@ -180,7 +180,7 @@ class ShrinkWrapImpl { const TargetFrameLowering *TFI = MachineFunc->getSubtarget().getFrameLowering(); - TFI->determineCalleeSaves(*MachineFunc, SavedRegs, RS); + TFI->determinePrologCalleeSaves(*MachineFunc, SavedRegs, RS); for (int Reg = SavedRegs.find_first(); Reg != -1; Reg = SavedRegs.find_next(Reg)) diff --git a/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp b/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp index ebf6d1a52448e..95144109ed14a 100644 --- a/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp +++ b/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp @@ -93,36 +93,20 @@ void TargetFrameLowering::getCalleeSaves(const MachineFunction &MF, CalleeSaves.set(Info.getReg()); } +LLVM_DEPRECATED("Use determinePrologCalleeSaves instead", + "determinePrologCalleeSaves") void TargetFrameLowering::determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const { - const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); - - // Resize before the early returns. Some backends expect that - // SavedRegs.size() == TRI.getNumRegs() after this call even if there are no - // saved registers. - SavedRegs.resize(TRI.getNumRegs()); - - // Get the callee saved register list... - const MCPhysReg *CSRegs = nullptr; - - // When interprocedural register allocation is enabled, callee saved register - // list should be empty, since caller saved registers are preferred over - // callee saved registers. Unless it has some risked CSR to be optimized out. - if (MF.getTarget().Options.EnableIPRA && - isSafeForNoCSROpt(MF.getFunction()) && - isProfitableForNoCSROpt(MF.getFunction())) - CSRegs = TRI.getIPRACSRegs(&MF); - else - CSRegs = MF.getRegInfo().getCalleeSavedRegs(); - - // Early exit if there are no callee saved registers. - if (!CSRegs || CSRegs[0] == 0) - return; + determinePrologCalleeSaves(MF, SavedRegs, RS); +} +const MCPhysReg * +TargetFrameLowering::getMustPreserveRegisters(MachineFunction &MF) const { + const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); // In Naked functions we aren't going to save any registers. if (MF.getFunction().hasFnAttribute(Attribute::Naked)) - return; + return nullptr; // Noreturn+nounwind functions never restore CSR, so no saves are needed. // Purely noreturn functions may still return through throws, so those must @@ -135,15 +119,81 @@ void TargetFrameLowering::determineCalleeSaves(MachineFunction &MF, MF.getFunction().hasFnAttribute(Attribute::NoUnwind) && !MF.getFunction().hasFnAttribute(Attribute::UWTable) && enableCalleeSaveSkip(MF)) - return; + return nullptr; + + // When interprocedural register allocation is enabled, callee saved register + // list should be empty, since caller saved registers are preferred over + // callee saved registers. Unless it has some risked CSR to be optimized out. + if (MF.getTarget().Options.EnableIPRA && + isSafeForNoCSROpt(MF.getFunction()) && + isProfitableForNoCSROpt(MF.getFunction())) + return TRI.getIPRACSRegs(&MF); + return MF.getRegInfo().getCalleeSavedRegs(); +} +void TargetFrameLowering::determineUncondPrologCalleeSaves( + MachineFunction &MF, const MCPhysReg *CSRegs, + BitVector &UncondPrologCSRs) const { // Functions which call __builtin_unwind_init get all their registers saved. - bool CallsUnwindInit = MF.callsUnwindInit(); + if (MF.callsUnwindInit()) { + for (unsigned i = 0; CSRegs[i]; ++i) { + unsigned Reg = CSRegs[i]; + UncondPrologCSRs.set(Reg); + } + } + return; +} + +void TargetFrameLowering::determineEarlyCalleeSaves( + MachineFunction &MF, BitVector &EarlyCSRs) const { + const auto &ST = MF.getSubtarget(); + if (!ST.savesCSRsEarly()) + return; + + const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); + // Get the callee saved register list... + const MCPhysReg *CSRegs = getMustPreserveRegisters(MF); + // Early exit if there are no callee saved registers. + if (!CSRegs || CSRegs[0] == 0) + return; + + BitVector UncondPrologCSRs(TRI.getNumRegs(), false); + determineUncondPrologCalleeSaves(MF, CSRegs, UncondPrologCSRs); + + EarlyCSRs.resize(TRI.getNumRegs()); + for (unsigned i = 0; CSRegs[i]; ++i) { + unsigned Reg = CSRegs[i]; + if (!UncondPrologCSRs[Reg]) + EarlyCSRs.set(Reg); + } +} + +void TargetFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &PrologCSRs, + RegScavenger *RS) const { + const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); + + // Resize before the early returns. Some backends expect that + // SavedRegs.size() == TRI.getNumRegs() after this call even if there are no + // saved registers. + PrologCSRs.resize(TRI.getNumRegs()); + + // Get the callee saved register list... + const MCPhysReg *CSRegs = getMustPreserveRegisters(MF); + // Early exit if there are no callee saved registers. + if (!CSRegs || CSRegs[0] == 0) + return; + + determineUncondPrologCalleeSaves(MF, CSRegs, PrologCSRs); + + BitVector EarlyCSRs(TRI.getNumRegs(), false); + determineEarlyCalleeSaves(MF, EarlyCSRs); + const MachineRegisterInfo &MRI = MF.getRegInfo(); for (unsigned i = 0; CSRegs[i]; ++i) { unsigned Reg = CSRegs[i]; - if (CallsUnwindInit || MRI.isPhysRegModified(Reg)) - SavedRegs.set(Reg); + if (MRI.isPhysRegModified(Reg) && !EarlyCSRs[Reg]) + PrologCSRs.set(Reg); } } diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index 7290b3f67c2e3..bd5f2d3547e3b 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -2482,9 +2482,9 @@ void AArch64FrameLowering::determineStackHazardSlot( } } -void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { +void AArch64FrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { // All calls are tail calls in GHC calling conv, and functions have no // prologue/epilogue. if (MF.getFunction().getCallingConv() == CallingConv::GHC) @@ -2654,7 +2654,7 @@ void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF, } LLVM_DEBUG({ - dbgs() << "*** determineCalleeSaves\nSaved CSRs:"; + dbgs() << "*** determinePrologCalleeSaves\nSaved CSRs:"; for (unsigned Reg : SavedRegs.set_bits()) dbgs() << ' ' << printReg(MCRegister(Reg), RegInfo); dbgs() << "\n"; diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.h b/llvm/lib/Target/AArch64/AArch64FrameLowering.h index 32a9bd831989c..6ded0e13ba22d 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.h +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.h @@ -94,8 +94,8 @@ class AArch64FrameLowering : public TargetFrameLowering { unsigned &MinCSFrameIndex, unsigned &MaxCSFrameIndex) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS) const override; /// Returns true if the target will correctly handle shrink wrapping. bool enableShrinkWrapping(const MachineFunction &MF) const override { diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h index 00e0c2511aaf0..f1101605303b6 100644 --- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h +++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h @@ -77,7 +77,7 @@ class AArch64FunctionInfo final : public MachineFunctionInfo { unsigned TailCallReservedStack = 0; /// HasStackFrame - True if this function has a stack frame. Set by - /// determineCalleeSaves(). + /// determinePrologCalleeSaves(). bool HasStackFrame = false; /// Amount of stack frame size, not including callee-saved registers. @@ -379,7 +379,7 @@ class AArch64FunctionInfo final : public MachineFunctionInfo { #ifndef NDEBUG // Make sure the calculated size derived from the CalleeSavedInfo // equals the cached size that was calculated elsewhere (e.g. in - // determineCalleeSaves). + // determinePrologCalleeSaves). ValidateCalleeSavedStackSize = HasCalleeSavedStackSize; #endif diff --git a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp index ffbb111d42221..cfde9651aa45f 100644 --- a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp @@ -1691,9 +1691,9 @@ void SIFrameLowering::determinePrologEpilogSGPRSaves( } // Only report VGPRs to generic code. -void SIFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedVGPRs, - RegScavenger *RS) const { +void SIFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedVGPRs, + RegScavenger *RS) const { SIMachineFunctionInfo *MFI = MF.getInfo(); // If this is a function with the amdgpu_cs_chain[_preserve] calling @@ -1702,7 +1702,7 @@ void SIFrameLowering::determineCalleeSaves(MachineFunction &MF, if (MFI->isChainFunction() && !MF.getFrameInfo().hasTailCall()) return; - TargetFrameLowering::determineCalleeSaves(MF, SavedVGPRs, RS); + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedVGPRs, RS); const GCNSubtarget &ST = MF.getSubtarget(); const SIRegisterInfo *TRI = ST.getRegisterInfo(); @@ -1797,10 +1797,10 @@ void SIFrameLowering::determineCalleeSaves(MachineFunction &MF, SavedVGPRs.reset(Reg.first); } -void SIFrameLowering::determineCalleeSavesSGPR(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void SIFrameLowering::determinePrologCalleeSavesSGPR(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); const SIMachineFunctionInfo *MFI = MF.getInfo(); if (MFI->isEntryFunction()) return; diff --git a/llvm/lib/Target/AMDGPU/SIFrameLowering.h b/llvm/lib/Target/AMDGPU/SIFrameLowering.h index a72772987262e..1d5ea69f00b42 100644 --- a/llvm/lib/Target/AMDGPU/SIFrameLowering.h +++ b/llvm/lib/Target/AMDGPU/SIFrameLowering.h @@ -30,10 +30,10 @@ class SIFrameLowering final : public AMDGPUFrameLowering { StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS = nullptr) const override; - void determineCalleeSavesSGPR(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS = nullptr) const; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS = nullptr) const override; + void determinePrologCalleeSavesSGPR(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS = nullptr) const; void determinePrologEpilogSGPRSaves(MachineFunction &MF, BitVector &SavedRegs, bool NeedExecCopyReservedReg) const; void emitCSRSpillStores(MachineFunction &MF, MachineBasicBlock &MBB, diff --git a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp index cbd08f0fb5dff..ad14822f89f06 100644 --- a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp +++ b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp @@ -257,7 +257,7 @@ bool SILowerSGPRSpills::spillCalleeSavedRegs( // Determine which of the registers in the callee save list should be saved. BitVector SavedRegs; - TFI->determineCalleeSavesSGPR(MF, SavedRegs, RS); + TFI->determinePrologCalleeSavesSGPR(MF, SavedRegs, RS); // Add the code to save and restore the callee saved registers. if (!F.hasFnAttribute(Attribute::Naked)) { diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp index 9abda275d7e42..cac608d3e87be 100644 --- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp @@ -388,8 +388,8 @@ void SIMachineFunctionInfo::shiftWwmVGPRsToLowestRange( SpillPhysVGPRs[Idx] = NewReg; } - // The generic `determineCalleeSaves` might have set the old register if it - // is in the CSR range. + // The generic `determinePrologCalleeSaves` might have set the old register + // if it is in the CSR range. SavedVGPRs.reset(Reg); for (MachineBasicBlock &MBB : MF) { diff --git a/llvm/lib/Target/ARC/ARCFrameLowering.cpp b/llvm/lib/Target/ARC/ARCFrameLowering.cpp index 9f6a79e3210c4..83ce075dc9663 100644 --- a/llvm/lib/Target/ARC/ARCFrameLowering.cpp +++ b/llvm/lib/Target/ARC/ARCFrameLowering.cpp @@ -85,11 +85,11 @@ static unsigned determineLastCalleeSave(ArrayRef CSI) { return Last; } -void ARCFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { +void ARCFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { LLVM_DEBUG(dbgs() << "Determine Callee Saves: " << MF.getName() << "\n"); - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); SavedRegs.set(ARC::BLINK); } diff --git a/llvm/lib/Target/ARC/ARCFrameLowering.h b/llvm/lib/Target/ARC/ARCFrameLowering.h index 089326fe32057..96b69a3328c63 100644 --- a/llvm/lib/Target/ARC/ARCFrameLowering.h +++ b/llvm/lib/Target/ARC/ARCFrameLowering.h @@ -37,8 +37,8 @@ class ARCFrameLowering : public TargetFrameLowering { void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; /// Add explicit callee save registers. - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS) const override; bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp index c19eed122fe63..2066e87b2c135 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -856,9 +856,10 @@ static void emitAligningInstructions(MachineFunction &MF, ARMFunctionInfo *AFI, /// We need the offset of the frame pointer relative to other MachineFrameInfo /// offsets which are encoded relative to SP at function begin. /// See also emitPrologue() for how the FP is set up. -/// Unfortunately we cannot determine this value in determineCalleeSaves() yet -/// as assignCalleeSavedSpillSlots() hasn't run at this point. Instead we use -/// this to produce a conservative estimate that we check in an assert() later. +/// Unfortunately we cannot determine this value in determinePrologCalleeSaves() +/// yet as assignCalleeSavedSpillSlots() hasn't run at this point. Instead we +/// use this to produce a conservative estimate that we check in an assert() +/// later. static int getMaxFPOffset(const ARMSubtarget &STI, const ARMFunctionInfo &AFI, const MachineFunction &MF) { ARMSubtarget::PushPopSplitVariation PushPopSplit = @@ -2510,10 +2511,10 @@ static bool canSpillOnFrameIndexAccess(const MachineFunction &MF, return false; } -void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void ARMFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); // This tells PEI to spill the FP as if it is any other callee-save register // to take advantage the eliminateFrameIndex machinery. This also ensures it // is spilled in the order specified by getCalleeSavedRegs() to make it easier diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.h b/llvm/lib/Target/ARM/ARMFrameLowering.h index 9dc88d4671c38..811e3e95e38ba 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.h +++ b/llvm/lib/Target/ARM/ARMFrameLowering.h @@ -56,8 +56,8 @@ class ARMFrameLowering : public TargetFrameLowering { void getCalleeSaves(const MachineFunction &MF, BitVector &SavedRegs) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS) const override; /// Update the IsRestored flag on LR if it is spilled, based on the return /// instructions. diff --git a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h index b6897608a952c..14b4a87bdbe41 100644 --- a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h +++ b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h @@ -52,7 +52,7 @@ class ARMFunctionInfo : public MachineFunctionInfo { unsigned ReturnRegsCount = 0; /// HasStackFrame - True if this function has a stack frame. Set by - /// determineCalleeSaves(). + /// determinePrologCalleeSaves(). bool HasStackFrame = false; /// RestoreSPFromFP - True if epilogue should restore SP from FP. Set by diff --git a/llvm/lib/Target/AVR/AVRFrameLowering.cpp b/llvm/lib/Target/AVR/AVRFrameLowering.cpp index b919be3d4466d..33ddd91d1859e 100644 --- a/llvm/lib/Target/AVR/AVRFrameLowering.cpp +++ b/llvm/lib/Target/AVR/AVRFrameLowering.cpp @@ -414,10 +414,10 @@ MachineBasicBlock::iterator AVRFrameLowering::eliminateCallFramePseudoInstr( return MBB.erase(MI); } -void AVRFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void AVRFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); // If we have a frame pointer, the Y register needs to be saved as well. if (hasFP(MF)) { diff --git a/llvm/lib/Target/AVR/AVRFrameLowering.h b/llvm/lib/Target/AVR/AVRFrameLowering.h index 7baa5e9d62f60..9d8dfc35df1f6 100644 --- a/llvm/lib/Target/AVR/AVRFrameLowering.h +++ b/llvm/lib/Target/AVR/AVRFrameLowering.h @@ -32,8 +32,8 @@ class AVRFrameLowering : public TargetFrameLowering { const TargetRegisterInfo *TRI) const override; bool hasReservedCallFrame(const MachineFunction &MF) const override; bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS = nullptr) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS = nullptr) const override; MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override; diff --git a/llvm/lib/Target/BPF/BPFFrameLowering.cpp b/llvm/lib/Target/BPF/BPFFrameLowering.cpp index 00780b4d1406f..30bba8d619e5a 100644 --- a/llvm/lib/Target/BPF/BPFFrameLowering.cpp +++ b/llvm/lib/Target/BPF/BPFFrameLowering.cpp @@ -27,10 +27,10 @@ void BPFFrameLowering::emitPrologue(MachineFunction &MF, void BPFFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const {} -void BPFFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void BPFFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); SavedRegs.reset(BPF::R6); SavedRegs.reset(BPF::R7); SavedRegs.reset(BPF::R8); diff --git a/llvm/lib/Target/BPF/BPFFrameLowering.h b/llvm/lib/Target/BPF/BPFFrameLowering.h index 6beffcbe69dd0..f04260126e91a 100644 --- a/llvm/lib/Target/BPF/BPFFrameLowering.h +++ b/llvm/lib/Target/BPF/BPFFrameLowering.h @@ -26,8 +26,8 @@ class BPFFrameLowering : public TargetFrameLowering { void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS) const override; MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, diff --git a/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp b/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp index 98798275e7979..d447fd71f3ace 100644 --- a/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp +++ b/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp @@ -354,10 +354,10 @@ static unsigned estimateRSStackSizeLimit(MachineFunction &MF, return Limit; } -void CSKYFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void CSKYFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); CSKYMachineFunctionInfo *CFI = MF.getInfo(); const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); diff --git a/llvm/lib/Target/CSKY/CSKYFrameLowering.h b/llvm/lib/Target/CSKY/CSKYFrameLowering.h index 0b3b287bb6a55..2c891237240df 100644 --- a/llvm/lib/Target/CSKY/CSKYFrameLowering.h +++ b/llvm/lib/Target/CSKY/CSKYFrameLowering.h @@ -39,8 +39,8 @@ class CSKYFrameLowering : public TargetFrameLowering { StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS) const override; bool assignCalleeSavedSpillSlots( MachineFunction &MF, const TargetRegisterInfo *TRI, diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp index df612262def5e..32ca46c629474 100644 --- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -2058,9 +2058,9 @@ bool HexagonFrameLowering::expandSpillMacros(MachineFunction &MF, return Changed; } -void HexagonFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { +void HexagonFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { auto &HRI = *MF.getSubtarget().getRegisterInfo(); SavedRegs.resize(HRI.getNumRegs()); @@ -2111,7 +2111,7 @@ void HexagonFrameLowering::determineCalleeSaves(MachineFunction &MF, } } - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); } Register HexagonFrameLowering::findPhysReg(MachineFunction &MF, diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h index 926aadb01f50e..92580208695d8 100644 --- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h +++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h @@ -80,8 +80,8 @@ class HexagonFrameLowering : public TargetFrameLowering { MachineBasicBlock::iterator I) const override; void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS = nullptr) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS) const override; bool targetHandlesStackFrameRounding() const override { return true; diff --git a/llvm/lib/Target/Lanai/LanaiFrameLowering.cpp b/llvm/lib/Target/Lanai/LanaiFrameLowering.cpp index 3c3924bd50182..e0f86731df036 100644 --- a/llvm/lib/Target/Lanai/LanaiFrameLowering.cpp +++ b/llvm/lib/Target/Lanai/LanaiFrameLowering.cpp @@ -186,10 +186,10 @@ void LanaiFrameLowering::emitEpilogue(MachineFunction & /*MF*/, .addImm(LPAC::ADD); } -void LanaiFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void LanaiFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); MachineFrameInfo &MFI = MF.getFrameInfo(); const LanaiRegisterInfo *LRI = STI.getRegisterInfo(); diff --git a/llvm/lib/Target/Lanai/LanaiFrameLowering.h b/llvm/lib/Target/Lanai/LanaiFrameLowering.h index 9bd78d008f77e..e7b2fc43dc02b 100644 --- a/llvm/lib/Target/Lanai/LanaiFrameLowering.h +++ b/llvm/lib/Target/Lanai/LanaiFrameLowering.h @@ -44,8 +44,8 @@ class LanaiFrameLowering : public TargetFrameLowering { eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS = nullptr) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS = nullptr) const override; protected: bool hasFPImpl(const MachineFunction & /*MF*/) const override { return true; } diff --git a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp index 690b0639484d0..7d8715cc100bd 100644 --- a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp @@ -379,10 +379,9 @@ uint64_t LoongArchFrameLowering::getFirstSPAdjustAmount( return 0; } -void LoongArchFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void LoongArchFrameLowering::determinePrologCalleeSaves( + MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); // Unconditionally spill RA and FP only if the function uses a frame // pointer. if (hasFP(MF)) { diff --git a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h index 6cbfcf665f6a9..aea68c491b19d 100644 --- a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h +++ b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h @@ -31,8 +31,8 @@ class LoongArchFrameLowering : public TargetFrameLowering { void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS) const override; void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override; diff --git a/llvm/lib/Target/M68k/M68kFrameLowering.cpp b/llvm/lib/Target/M68k/M68kFrameLowering.cpp index ae2bb975bc9d6..7189fd98cea1a 100644 --- a/llvm/lib/Target/M68k/M68kFrameLowering.cpp +++ b/llvm/lib/Target/M68k/M68kFrameLowering.cpp @@ -768,10 +768,10 @@ void M68kFrameLowering::emitEpilogue(MachineFunction &MF, } } -void M68kFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void M68kFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); MachineFrameInfo &MFI = MF.getFrameInfo(); diff --git a/llvm/lib/Target/M68k/M68kFrameLowering.h b/llvm/lib/Target/M68k/M68kFrameLowering.h index ed2bfb605ff13..a696a4d017aba 100644 --- a/llvm/lib/Target/M68k/M68kFrameLowering.h +++ b/llvm/lib/Target/M68k/M68kFrameLowering.h @@ -91,8 +91,8 @@ class M68kFrameLowering : public TargetFrameLowering { /// this function to save additional registers. /// This method also sets up the register scavenger ensuring there is a free /// register or a frameindex available. - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS = nullptr) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS = nullptr) const override; /// Allows target to override spill slot assignment logic. If implemented, /// assignCalleeSavedSpillSlots() should assign frame slots to all CSI diff --git a/llvm/lib/Target/Mips/Mips16FrameLowering.cpp b/llvm/lib/Target/Mips/Mips16FrameLowering.cpp index 44fc720e6ce14..ca09e819b3440 100644 --- a/llvm/lib/Target/Mips/Mips16FrameLowering.cpp +++ b/llvm/lib/Target/Mips/Mips16FrameLowering.cpp @@ -136,10 +136,10 @@ Mips16FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { return isInt<15>(MFI.getMaxCallFrameSize()) && !MFI.hasVarSizedObjects(); } -void Mips16FrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void Mips16FrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); const Mips16InstrInfo &TII = *static_cast(STI.getInstrInfo()); const MipsRegisterInfo &RI = TII.getRegisterInfo(); diff --git a/llvm/lib/Target/Mips/Mips16FrameLowering.h b/llvm/lib/Target/Mips/Mips16FrameLowering.h index 7f0f1cd4ea370..b09247bbae178 100644 --- a/llvm/lib/Target/Mips/Mips16FrameLowering.h +++ b/llvm/lib/Target/Mips/Mips16FrameLowering.h @@ -38,8 +38,8 @@ class Mips16FrameLowering : public MipsFrameLowering { bool hasReservedCallFrame(const MachineFunction &MF) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS) const override; }; } // End llvm namespace diff --git a/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp b/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp index 942194cf31d44..4aaaf410396e5 100644 --- a/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp +++ b/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp @@ -812,10 +812,10 @@ static void setAliasRegs(MachineFunction &MF, BitVector &SavedRegs, SavedRegs.set(*AI); } -void MipsSEFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void MipsSEFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); MipsFunctionInfo *MipsFI = MF.getInfo(); MipsABIInfo ABI = STI.getABI(); diff --git a/llvm/lib/Target/Mips/MipsSEFrameLowering.h b/llvm/lib/Target/Mips/MipsSEFrameLowering.h index 226f7878fa14b..fb6e614d6982e 100644 --- a/llvm/lib/Target/Mips/MipsSEFrameLowering.h +++ b/llvm/lib/Target/Mips/MipsSEFrameLowering.h @@ -36,8 +36,8 @@ class MipsSEFrameLowering : public MipsFrameLowering { bool hasReservedCallFrame(const MachineFunction &MF) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS) const override; private: void emitInterruptEpilogueStub(MachineFunction &MF, diff --git a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp index aae3e49f6c70b..f99fb55fe9eb9 100644 --- a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp @@ -1967,10 +1967,10 @@ void PPCFrameLowering::createTailCallBranchInstr(MachineBasicBlock &MBB) const { } } -void PPCFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void PPCFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); if (Subtarget.isAIXABI()) updateCalleeSaves(MF, SavedRegs); diff --git a/llvm/lib/Target/PowerPC/PPCFrameLowering.h b/llvm/lib/Target/PowerPC/PPCFrameLowering.h index 47f249862946f..8d5acd3b8a562 100644 --- a/llvm/lib/Target/PowerPC/PPCFrameLowering.h +++ b/llvm/lib/Target/PowerPC/PPCFrameLowering.h @@ -110,8 +110,8 @@ class PPCFrameLowering: public TargetFrameLowering { bool needsFP(const MachineFunction &MF) const; void replaceFPWithRealFP(MachineFunction &MF) const; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS = nullptr) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS = nullptr) const override; void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS = nullptr) const override; void addScavengingSpillSlot(MachineFunction &MF, RegScavenger *RS) const; diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index 6d91790c59a84..f780375454b2a 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -32,6 +32,11 @@ using namespace llvm; +static cl::opt UserDefinedUncondPrologCSRs( + "riscv-user-defined-uncond-prolog-csrs", + cl::desc("Comma-separated list of registerst that have to be saved / restored in prolog / epilog. Used for testing only"), cl::init(""), + cl::Hidden); + static Align getABIStackAlignment(RISCVABI::ABI ABI) { if (ABI == RISCVABI::ABI_ILP32E) return Align(4); @@ -1527,12 +1532,37 @@ static MCRegister getRVVBaseRegister(const RISCVRegisterInfo &TRI, return BaseReg; } -void RISCVFrameLowering::determineCalleeSaves(MachineFunction &MF, +#define GET_REGISTER_MATCHER +#include "RISCVGenAsmMatcher.inc" + +void RISCVFrameLowering::determineUncondPrologCalleeSaves(MachineFunction &MF, const MCPhysReg *CSRegs, BitVector &UncondPrologCSRs) const { + const RISCVRegisterInfo *TRI = STI.getRegisterInfo(); + + StringRef RegString(UserDefinedUncondPrologCSRs); + SmallVector RegNames; + llvm::SplitString(RegString, RegNames, ","); + for (auto &Name : RegNames) { + Register Reg = MatchRegisterName(Name); + if (!Reg) + Reg = MatchRegisterAltName(Name); + if (!Reg) { + std::string msg; + raw_string_ostream Msg(msg); + Msg << "Couldn't parse register: " << Name << "\n"; + report_fatal_error(Twine(msg)); + } + UncondPrologCSRs.set(Reg.id()); + } + + TargetFrameLowering::determineUncondPrologCalleeSaves(MF, CSRegs, UncondPrologCSRs); +} + +void RISCVFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); - // In TargetFrameLowering::determineCalleeSaves, any vector register is marked + // In TargetFrameLowering::determinePrologCalleeSaves, any vector register is marked // as saved if any of its subregister is clobbered, this is not correct in // vector registers. We only want the vector register to be marked as saved // if all of its subregisters are clobbered. diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.h b/llvm/lib/Target/RISCV/RISCVFrameLowering.h index 87980dfb09f96..b1835877ecd31 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.h +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.h @@ -34,7 +34,9 @@ class RISCVFrameLowering : public TargetFrameLowering { StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + void determineUncondPrologCalleeSaves(MachineFunction &MF, const MCPhysReg *CSRegs, BitVector &UncondPrologCSRs) const override; + + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override; void processFunctionBeforeFrameFinalized(MachineFunction &MF, diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp index f86265a21d17e..3dcad527304a6 100644 --- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp @@ -75,6 +75,10 @@ static cl::opt EnablePExtCodeGen( "only partial codegen is currently supported)"), cl::init(false), cl::Hidden); +static cl::opt SaveCSREarly("riscv-save-csrs-early", + cl::desc("Save CSRs early"), + cl::init(false), cl::Hidden); + void RISCVSubtarget::anchor() {} RISCVSubtarget & @@ -265,3 +269,7 @@ bool RISCVSubtarget::useMIPSLoadStorePairs() const { bool RISCVSubtarget::useMIPSCCMovInsn() const { return UseMIPSCCMovInsn && HasVendorXMIPSCMov; } + +bool RISCVSubtarget::savesCSRsEarly() const { + return SaveCSREarly; +} diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h index c16b23e290df1..7daf39ff17e57 100644 --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -438,6 +438,8 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo { void overridePostRASchedPolicy(MachineSchedPolicy &Policy, const SchedRegion &Region) const override; + + bool savesCSRsEarly() const override; }; } // namespace llvm diff --git a/llvm/lib/Target/Sparc/SparcFrameLowering.cpp b/llvm/lib/Target/Sparc/SparcFrameLowering.cpp index fa08d4474f39e..f74832faaeea1 100644 --- a/llvm/lib/Target/Sparc/SparcFrameLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcFrameLowering.cpp @@ -314,15 +314,14 @@ void SparcFrameLowering::remapRegsForLeafProc(MachineFunction &MF) const { #endif } -void SparcFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void SparcFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); if (!DisableLeafProc && isLeafProc(MF)) { SparcMachineFunctionInfo *MFI = MF.getInfo(); MFI->setLeafProc(true); remapRegsForLeafProc(MF); } - } diff --git a/llvm/lib/Target/Sparc/SparcFrameLowering.h b/llvm/lib/Target/Sparc/SparcFrameLowering.h index 803856811969b..2c0b40020a25b 100644 --- a/llvm/lib/Target/Sparc/SparcFrameLowering.h +++ b/llvm/lib/Target/Sparc/SparcFrameLowering.h @@ -35,8 +35,8 @@ class SparcFrameLowering : public TargetFrameLowering { MachineBasicBlock::iterator I) const override; bool hasReservedCallFrame(const MachineFunction &MF) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS = nullptr) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS = nullptr) const override; StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override; diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp index 570bbd884a244..747a6c7f18629 100644 --- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp @@ -228,10 +228,9 @@ bool SystemZELFFrameLowering::assignCalleeSavedSpillSlots( return true; } -void SystemZELFFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void SystemZELFFrameLowering::determinePrologCalleeSaves( + MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); MachineFrameInfo &MFFrame = MF.getFrameInfo(); const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); @@ -1093,10 +1092,9 @@ bool SystemZXPLINKFrameLowering::assignCalleeSavedSpillSlots( return true; } -void SystemZXPLINKFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void SystemZXPLINKFrameLowering::determinePrologCalleeSaves( + MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); bool HasFP = hasFP(MF); const SystemZSubtarget &Subtarget = MF.getSubtarget(); diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.h b/llvm/lib/Target/SystemZ/SystemZFrameLowering.h index 57fc73b78bbf7..f685fb259a0da 100644 --- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.h +++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.h @@ -69,8 +69,8 @@ class SystemZELFFrameLowering : public SystemZFrameLowering { assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector &CSI) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS) const override; bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, ArrayRef CSI, @@ -128,8 +128,8 @@ class SystemZXPLINKFrameLowering : public SystemZFrameLowering { const TargetRegisterInfo *TRI, std::vector &CSI) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS) const override; bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, diff --git a/llvm/lib/Target/VE/VEFrameLowering.cpp b/llvm/lib/Target/VE/VEFrameLowering.cpp index 691d2ece34f38..d76fc3f985815 100644 --- a/llvm/lib/Target/VE/VEFrameLowering.cpp +++ b/llvm/lib/Target/VE/VEFrameLowering.cpp @@ -480,10 +480,10 @@ bool VEFrameLowering::isLeafProc(MachineFunction &MF) const { && !hasFP(MF); // Don't need %fp } -void VEFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void VEFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); // Functions having BP need to emit prologue and epilogue to allocate local // buffer on the stack even if the function is a leaf function. diff --git a/llvm/lib/Target/VE/VEFrameLowering.h b/llvm/lib/Target/VE/VEFrameLowering.h index be9cdc01d6f44..7abfaab595c8a 100644 --- a/llvm/lib/Target/VE/VEFrameLowering.h +++ b/llvm/lib/Target/VE/VEFrameLowering.h @@ -47,8 +47,8 @@ class VEFrameLowering : public TargetFrameLowering { bool hasReservedCallFrame(const MachineFunction &MF) const override { return true; } - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS = nullptr) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS = nullptr) const override; StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override; diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index 8bca6344d6521..0d8c9a17f0516 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -3199,10 +3199,10 @@ bool X86FrameLowering::restoreCalleeSavedRegisters( return true; } -void X86FrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void X86FrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); // Spill the BasePtr if it's used. if (TRI->hasBasePointer(MF)) { diff --git a/llvm/lib/Target/X86/X86FrameLowering.h b/llvm/lib/Target/X86/X86FrameLowering.h index f1e3796f5fddd..ab8b0b022238d 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.h +++ b/llvm/lib/Target/X86/X86FrameLowering.h @@ -84,8 +84,8 @@ class X86FrameLowering : public TargetFrameLowering { void adjustForHiPEPrologue(MachineFunction &MF, MachineBasicBlock &PrologueMBB) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS = nullptr) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS = nullptr) const override; bool assignCalleeSavedSpillSlots(MachineFunction &MF, diff --git a/llvm/lib/Target/XCore/XCoreFrameLowering.cpp b/llvm/lib/Target/XCore/XCoreFrameLowering.cpp index 351a221c92ebd..e606ba9a19e3b 100644 --- a/llvm/lib/Target/XCore/XCoreFrameLowering.cpp +++ b/llvm/lib/Target/XCore/XCoreFrameLowering.cpp @@ -522,10 +522,10 @@ MachineBasicBlock::iterator XCoreFrameLowering::eliminateCallFramePseudoInstr( return MBB.erase(I); } -void XCoreFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); +void XCoreFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); XCoreFunctionInfo *XFI = MF.getInfo(); diff --git a/llvm/lib/Target/XCore/XCoreFrameLowering.h b/llvm/lib/Target/XCore/XCoreFrameLowering.h index b06a6f922cdde..aa55e6ba6f8fc 100644 --- a/llvm/lib/Target/XCore/XCoreFrameLowering.h +++ b/llvm/lib/Target/XCore/XCoreFrameLowering.h @@ -46,8 +46,8 @@ namespace llvm { eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS = nullptr) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS = nullptr) const override; void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS = nullptr) const override; diff --git a/llvm/lib/Target/Xtensa/XtensaFrameLowering.cpp b/llvm/lib/Target/Xtensa/XtensaFrameLowering.cpp index 1c0dc66a46144..f9145f1bc3a9b 100644 --- a/llvm/lib/Target/Xtensa/XtensaFrameLowering.cpp +++ b/llvm/lib/Target/Xtensa/XtensaFrameLowering.cpp @@ -344,16 +344,16 @@ MachineBasicBlock::iterator XtensaFrameLowering::eliminateCallFramePseudoInstr( return MBB.erase(I); } -void XtensaFrameLowering::determineCalleeSaves(MachineFunction &MF, - BitVector &SavedRegs, - RegScavenger *RS) const { +void XtensaFrameLowering::determinePrologCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { MCRegister FP = TRI->getFrameRegister(MF); if (STI.isWindowedABI()) { return; } - TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); + TargetFrameLowering::determinePrologCalleeSaves(MF, SavedRegs, RS); // Mark $fp as used if function has dedicated frame pointer. if (hasFP(MF)) diff --git a/llvm/lib/Target/Xtensa/XtensaFrameLowering.h b/llvm/lib/Target/Xtensa/XtensaFrameLowering.h index f0095b8774154..1270e7abfd3ec 100644 --- a/llvm/lib/Target/Xtensa/XtensaFrameLowering.h +++ b/llvm/lib/Target/Xtensa/XtensaFrameLowering.h @@ -44,8 +44,8 @@ class XtensaFrameLowering : public TargetFrameLowering { MutableArrayRef CSI, const TargetRegisterInfo *TRI) const override; - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS) const override; + void determinePrologCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS) const override; void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override; diff --git a/llvm/test/CodeGen/AArch64/arm64-spill-lr.ll b/llvm/test/CodeGen/AArch64/arm64-spill-lr.ll index 24bc04fa0a252..917e92d39a11d 100644 --- a/llvm/test/CodeGen/AArch64/arm64-spill-lr.ll +++ b/llvm/test/CodeGen/AArch64/arm64-spill-lr.ll @@ -2,7 +2,7 @@ @bar = common global i32 0, align 4 ; Leaf function which uses all callee-saved registers and allocates >= 256 bytes -; on the stack this will cause determineCalleeSaves() to spill LR as an +; on the stack this will cause determinePrologCalleeSaves() to spill LR as an ; additional scratch register. ; ; This is a crash-only regression test for rdar://15124582. diff --git a/llvm/test/CodeGen/RISCV/determine-callee-saves.mir b/llvm/test/CodeGen/RISCV/determine-callee-saves.mir new file mode 100644 index 0000000000000..0027e18f905e7 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/determine-callee-saves.mir @@ -0,0 +1,79 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6 +# RUN: llc %s -mtriple=riscv64 -run-pass=prologepilog \ +# RUN: --riscv-save-csrs-early=false \ +# RUN: -o - | FileCheck %s -check-prefixes=NOEARLYCSR +# +# RUN: llc %s -mtriple=riscv64 -run-pass=prologepilog \ +# RUN: --riscv-save-csrs-early=false \ +# RUN: --riscv-user-defined-uncond-prolog-csrs="x19" \ +# RUN: -o - | FileCheck %s -check-prefixes=NOEARLYCSR_UNCONDX19 +# +# RUN: llc %s -mtriple=riscv64 -run-pass=prologepilog \ +# RUN: --riscv-save-csrs-early=true \ +# RUN: -o - | FileCheck %s -check-prefixes=EARLYCSR +# +# RUN: llc %s -mtriple=riscv64 -run-pass=prologepilog \ +# RUN: --riscv-save-csrs-early=true \ +# RUN: --riscv-user-defined-uncond-prolog-csrs="x19" \ +# RUN: -o - | FileCheck %s -check-prefixes=EARLYCSR_UNCONDX19 +--- +name: test0 +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x10 + ; NOEARLYCSR-LABEL: name: test0 + ; NOEARLYCSR: liveins: $x10, $x18 + ; NOEARLYCSR-NEXT: {{ $}} + ; NOEARLYCSR-NEXT: $x2 = frame-setup ADDI $x2, -16 + ; NOEARLYCSR-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16 + ; NOEARLYCSR-NEXT: frame-setup SD killed $x18, $x2, 8 :: (store (s64) into %stack.0) + ; NOEARLYCSR-NEXT: frame-setup CFI_INSTRUCTION offset $x18, -8 + ; NOEARLYCSR-NEXT: $x18 = LD $x10, 0 :: (load (s64)) + ; NOEARLYCSR-NEXT: $x18 = frame-destroy LD $x2, 8 :: (load (s64) from %stack.0) + ; NOEARLYCSR-NEXT: frame-destroy CFI_INSTRUCTION restore $x18 + ; NOEARLYCSR-NEXT: $x2 = frame-destroy ADDI $x2, 16 + ; NOEARLYCSR-NEXT: frame-destroy CFI_INSTRUCTION def_cfa_offset 0 + ; NOEARLYCSR-NEXT: PseudoRET + ; + ; NOEARLYCSR_UNCONDX19-LABEL: name: test0 + ; NOEARLYCSR_UNCONDX19: liveins: $x10, $x18, $x19 + ; NOEARLYCSR_UNCONDX19-NEXT: {{ $}} + ; NOEARLYCSR_UNCONDX19-NEXT: $x2 = frame-setup ADDI $x2, -16 + ; NOEARLYCSR_UNCONDX19-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16 + ; NOEARLYCSR_UNCONDX19-NEXT: frame-setup SD killed $x18, $x2, 8 :: (store (s64) into %stack.0) + ; NOEARLYCSR_UNCONDX19-NEXT: frame-setup SD killed $x19, $x2, 0 :: (store (s64) into %stack.1) + ; NOEARLYCSR_UNCONDX19-NEXT: frame-setup CFI_INSTRUCTION offset $x18, -8 + ; NOEARLYCSR_UNCONDX19-NEXT: frame-setup CFI_INSTRUCTION offset $x19, -16 + ; NOEARLYCSR_UNCONDX19-NEXT: $x18 = LD $x10, 0 :: (load (s64)) + ; NOEARLYCSR_UNCONDX19-NEXT: $x18 = frame-destroy LD $x2, 8 :: (load (s64) from %stack.0) + ; NOEARLYCSR_UNCONDX19-NEXT: $x19 = frame-destroy LD $x2, 0 :: (load (s64) from %stack.1) + ; NOEARLYCSR_UNCONDX19-NEXT: frame-destroy CFI_INSTRUCTION restore $x18 + ; NOEARLYCSR_UNCONDX19-NEXT: frame-destroy CFI_INSTRUCTION restore $x19 + ; NOEARLYCSR_UNCONDX19-NEXT: $x2 = frame-destroy ADDI $x2, 16 + ; NOEARLYCSR_UNCONDX19-NEXT: frame-destroy CFI_INSTRUCTION def_cfa_offset 0 + ; NOEARLYCSR_UNCONDX19-NEXT: PseudoRET + ; + ; EARLYCSR-LABEL: name: test0 + ; EARLYCSR: liveins: $x10 + ; EARLYCSR-NEXT: {{ $}} + ; EARLYCSR-NEXT: $x18 = LD $x10, 0 :: (load (s64)) + ; EARLYCSR-NEXT: PseudoRET + ; + ; EARLYCSR_UNCONDX19-LABEL: name: test0 + ; EARLYCSR_UNCONDX19: liveins: $x10, $x19 + ; EARLYCSR_UNCONDX19-NEXT: {{ $}} + ; EARLYCSR_UNCONDX19-NEXT: $x2 = frame-setup ADDI $x2, -16 + ; EARLYCSR_UNCONDX19-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16 + ; EARLYCSR_UNCONDX19-NEXT: frame-setup SD killed $x19, $x2, 8 :: (store (s64) into %stack.0) + ; EARLYCSR_UNCONDX19-NEXT: frame-setup CFI_INSTRUCTION offset $x19, -8 + ; EARLYCSR_UNCONDX19-NEXT: $x18 = LD $x10, 0 :: (load (s64)) + ; EARLYCSR_UNCONDX19-NEXT: $x19 = frame-destroy LD $x2, 8 :: (load (s64) from %stack.0) + ; EARLYCSR_UNCONDX19-NEXT: frame-destroy CFI_INSTRUCTION restore $x19 + ; EARLYCSR_UNCONDX19-NEXT: $x2 = frame-destroy ADDI $x2, 16 + ; EARLYCSR_UNCONDX19-NEXT: frame-destroy CFI_INSTRUCTION def_cfa_offset 0 + ; EARLYCSR_UNCONDX19-NEXT: PseudoRET + $x18 = LD $x10, 0 :: (load (s64)) + PseudoRET + +...