diff options
author | Tim Northover <tnorthover@apple.com> | 2018-04-07 10:57:03 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2018-04-07 10:57:03 +0000 |
commit | e25e458d5233ef829f90110e1197aa3e1588faf4 (patch) | |
tree | 2b917151fc8ad32f7574c9463a83843a411430a9 /llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp | |
parent | 61061d69eacfb546283f33cba053c29bb1c1ef7e (diff) | |
download | llvm-e25e458d5233ef829f90110e1197aa3e1588faf4.zip llvm-e25e458d5233ef829f90110e1197aa3e1588faf4.tar.gz llvm-e25e458d5233ef829f90110e1197aa3e1588faf4.tar.bz2 |
Reapply ARM: Do not spill CSR to stack on entry to noreturn functions
Should fix UBSan bot by also checking there's no "uwtable" attribute
before skipping. Otherwise the unwind table will be useless since its
moves expect CSRs to actually be preserved.
A noreturn nounwind function can be expected to never return in any way, and by
never returning it will also never have to restore any callee-saved registers
for its caller. This makes it possible to skip spills of those registers during
function entry, saving some stack space and time in the process. This is rather
useful for embedded targets with limited stack space.
Should fix PR9970.
Patch mostly by myeisha (pmb).
llvm-svn: 329494
Diffstat (limited to 'llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp')
-rw-r--r-- | llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp b/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp index 79fafa5..4d6885c 100644 --- a/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp +++ b/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp @@ -36,6 +36,13 @@ 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) && + !MF.getFunction().hasFnAttribute(Attribute::UWTable)); + 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 +92,19 @@ 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) && + !MF.getFunction().hasFnAttribute(Attribute::UWTable) && + enableCalleeSaveSkip(MF)) + return; + // Functions which call __builtin_unwind_init get all their registers saved. bool CallsUnwindInit = MF.callsUnwindInit(); const MachineRegisterInfo &MRI = MF.getRegInfo(); |