diff options
Diffstat (limited to 'llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp')
-rw-r--r-- | llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp b/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp index 79fafa5497f..76c5425b692 100644 --- a/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp +++ b/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp @@ -36,6 +36,12 @@ bool TargetFrameLowering::noFramePointerElim(const MachineFunction &MF) const { return Attr.getValueAsString() == "true"; } +bool TargetFrameLowering::enableCalleeSaveSkip(const MachineFunction &MF) const { + assert(MF.getFunction().hasFnAttribute(Attribute::NoReturn) && + MF.getFunction().hasFnAttribute(Attribute::NoUnwind)); + return false; +} + /// Returns the displacement from the frame register to the stack /// frame of the specified index, along with the frame register used /// (in output arg FrameReg). This is the default implementation which @@ -85,6 +91,18 @@ void TargetFrameLowering::determineCalleeSaves(MachineFunction &MF, if (MF.getFunction().hasFnAttribute(Attribute::Naked)) return; + // Noreturn+nounwind functions never restore CSR, so no saves are needed. + // Purely noreturn functions may still return through throws, so those must + // save CSR for caller exception handlers. + // + // If the function uses longjmp to break out of its current path of + // execution we do not need the CSR spills either: setjmp stores all CSRs + // it was called with into the jmp_buf, which longjmp then restores. + if (MF.getFunction().hasFnAttribute(Attribute::NoReturn) && + MF.getFunction().hasFnAttribute(Attribute::NoUnwind) && + enableCalleeSaveSkip(MF)) + return; + // Functions which call __builtin_unwind_init get all their registers saved. bool CallsUnwindInit = MF.callsUnwindInit(); const MachineRegisterInfo &MRI = MF.getRegInfo(); |