diff options
author | Oliver Stannard <oliver.stannard@arm.com> | 2024-06-07 10:58:10 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-07 10:58:10 +0100 |
commit | 1a5239251ead73ee57f4e2f7fc93433ac7cf18b1 (patch) | |
tree | a2c31e3c7dce81d19f390f97e9d9754b5dbeda81 /llvm/lib | |
parent | b87a80d4ebca9e1c065f0d2762e500078c4badca (diff) | |
download | llvm-1a5239251ead73ee57f4e2f7fc93433ac7cf18b1.zip llvm-1a5239251ead73ee57f4e2f7fc93433ac7cf18b1.tar.gz llvm-1a5239251ead73ee57f4e2f7fc93433ac7cf18b1.tar.bz2 |
[ARM] r11 is reserved when using -mframe-chain=aapcs (#86951)
When using the -mframe-chain=aapcs or -mframe-chain=aapcs-leaf options,
we cannot use r11 as an allocatable register, even if
-fomit-frame-pointer is also used. This is so that r11 will always point
to a valid frame record, even if we don't create one in every function.
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/CommandFlags.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/CodeGen/TargetOptionsImpl.cpp | 21 | ||||
-rw-r--r-- | llvm/lib/IR/Function.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMFeatures.td | 11 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMFrameLowering.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMFrameLowering.h | 1 |
8 files changed, 39 insertions, 14 deletions
diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp index 677460a..8fc65d7 100644 --- a/llvm/lib/CodeGen/CommandFlags.cpp +++ b/llvm/lib/CodeGen/CommandFlags.cpp @@ -211,6 +211,9 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() { "Disable frame pointer elimination"), clEnumValN(FramePointerKind::NonLeaf, "non-leaf", "Disable frame pointer elimination for non-leaf frame"), + clEnumValN(FramePointerKind::Reserved, "reserved", + "Enable frame pointer elimination, but reserve the frame " + "pointer register"), clEnumValN(FramePointerKind::None, "none", "Enable frame pointer elimination"))); CGBINDOPT(FramePointerUsage); @@ -693,6 +696,8 @@ void codegen::setFunctionAttributes(StringRef CPU, StringRef Features, NewAttrs.addAttribute("frame-pointer", "all"); else if (getFramePointerUsage() == FramePointerKind::NonLeaf) NewAttrs.addAttribute("frame-pointer", "non-leaf"); + else if (getFramePointerUsage() == FramePointerKind::Reserved) + NewAttrs.addAttribute("frame-pointer", "reserved"); else if (getFramePointerUsage() == FramePointerKind::None) NewAttrs.addAttribute("frame-pointer", "none"); } diff --git a/llvm/lib/CodeGen/TargetOptionsImpl.cpp b/llvm/lib/CodeGen/TargetOptionsImpl.cpp index af5d101..5bf1d26 100644 --- a/llvm/lib/CodeGen/TargetOptionsImpl.cpp +++ b/llvm/lib/CodeGen/TargetOptionsImpl.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/StringSwitch.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/TargetFrameLowering.h" @@ -21,7 +22,7 @@ using namespace llvm; /// DisableFramePointerElim - This returns true if frame pointer elimination /// optimization should be disabled for the given machine function. bool TargetOptions::DisableFramePointerElim(const MachineFunction &MF) const { - // Check to see if the target want to forcably keep frame pointer. + // Check to see if the target want to forcibly keep frame pointer. if (MF.getSubtarget().getFrameLowering()->keepFramePointer(MF)) return true; @@ -34,11 +35,27 @@ bool TargetOptions::DisableFramePointerElim(const MachineFunction &MF) const { return true; if (FP == "non-leaf") return MF.getFrameInfo().hasCalls(); - if (FP == "none") + if (FP == "none" || FP == "reserved") return false; llvm_unreachable("unknown frame pointer flag"); } +bool TargetOptions::FramePointerIsReserved(const MachineFunction &MF) const { + // Check to see if the target want to forcibly keep frame pointer. + if (MF.getSubtarget().getFrameLowering()->keepFramePointer(MF)) + return true; + + const Function &F = MF.getFunction(); + + if (!F.hasFnAttribute("frame-pointer")) + return false; + + StringRef FP = F.getFnAttribute("frame-pointer").getValueAsString(); + return StringSwitch<bool>(FP) + .Cases("all", "non-leaf", "reserved", true) + .Case("none", false); +} + /// HonorSignDependentRoundingFPMath - Return true if the codegen must assume /// that the rounding mode of the FPU can change from its default. bool TargetOptions::HonorSignDependentRoundingFPMath() const { diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 13fa1af..3f73502 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -383,6 +383,9 @@ Function *Function::createWithDefaultAttr(FunctionType *Ty, case FramePointerKind::None: // 0 ("none") is the default. break; + case FramePointerKind::Reserved: + B.addAttribute("frame-pointer", "reserved"); + break; case FramePointerKind::NonLeaf: B.addAttribute("frame-pointer", "non-leaf"); break; diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 684e544..e592720 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -2322,7 +2322,7 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs, if (Attrs.hasFnAttr("frame-pointer")) { StringRef FP = Attrs.getFnAttr("frame-pointer").getValueAsString(); - if (FP != "all" && FP != "non-leaf" && FP != "none") + if (FP != "all" && FP != "non-leaf" && FP != "none" && FP != "reserved") CheckFailed("invalid value for 'frame-pointer' attribute: " + FP, V); } diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 9adf758..c149db31 100644 --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -207,7 +207,7 @@ getReservedRegs(const MachineFunction &MF) const { markSuperRegs(Reserved, ARM::PC); markSuperRegs(Reserved, ARM::FPSCR); markSuperRegs(Reserved, ARM::APSR_NZCV); - if (TFI->hasFP(MF)) + if (TFI->isFPReserved(MF)) markSuperRegs(Reserved, STI.getFramePointerReg()); if (hasBasePointer(MF)) markSuperRegs(Reserved, BasePtr); diff --git a/llvm/lib/Target/ARM/ARMFeatures.td b/llvm/lib/Target/ARM/ARMFeatures.td index 84481af..8b0ade5 100644 --- a/llvm/lib/Target/ARM/ARMFeatures.td +++ b/llvm/lib/Target/ARM/ARMFeatures.td @@ -548,16 +548,15 @@ def FeatureFixCortexA57AES1742098 : SubtargetFeature<"fix-cortex-a57-aes-1742098 "FixCortexA57AES1742098", "true", "Work around Cortex-A57 Erratum 1742098 / Cortex-A72 Erratum 1655431 (AES)">; +// If frame pointers are in use, they must follow the AAPCS definition, which +// always uses R11 as the frame pointer. If this is not set, we can use R7 as +// the frame pointer for Thumb1-only code, which is more efficient, but less +// compatible. Note that this feature does not control whether frame pointers +// are emitted, that is controlled by the "frame-pointer" function attribute. def FeatureAAPCSFrameChain : SubtargetFeature<"aapcs-frame-chain", "CreateAAPCSFrameChain", "true", "Create an AAPCS compliant frame chain">; -def FeatureAAPCSFrameChainLeaf : SubtargetFeature<"aapcs-frame-chain-leaf", - "CreateAAPCSFrameChainLeaf", "true", - "Create an AAPCS compliant frame chain " - "for leaf functions", - [FeatureAAPCSFrameChain]>; - // Assume that lock-free 32-bit atomics are available, even if the target // and operating system combination would not usually provide them. The user // is responsible for providing any necessary __sync implementations. Code diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp index 11496a6..831b6b0 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -215,7 +215,7 @@ bool ARMFrameLowering::hasFP(const MachineFunction &MF) const { /// isFPReserved - Return true if the frame pointer register should be /// considered a reserved register on the scope of the specified function. bool ARMFrameLowering::isFPReserved(const MachineFunction &MF) const { - return hasFP(MF) || MF.getSubtarget<ARMSubtarget>().createAAPCSFrameChain(); + return hasFP(MF) || MF.getTarget().Options.FramePointerIsReserved(MF); } /// hasReservedCallFrame - Under normal circumstances, when a frame pointer is @@ -2233,10 +2233,10 @@ bool ARMFrameLowering::enableShrinkWrapping(const MachineFunction &MF) const { return true; } -static bool requiresAAPCSFrameRecord(const MachineFunction &MF) { +bool ARMFrameLowering::requiresAAPCSFrameRecord( + const MachineFunction &MF) const { const auto &Subtarget = MF.getSubtarget<ARMSubtarget>(); - return Subtarget.createAAPCSFrameChainLeaf() || - (Subtarget.createAAPCSFrameChain() && MF.getFrameInfo().hasCalls()); + return Subtarget.createAAPCSFrameChain() && hasFP(MF); } // Thumb1 may require a spill when storing to a frame index through FP (or any diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.h b/llvm/lib/Target/ARM/ARMFrameLowering.h index 3c7358d..6a31b73 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.h +++ b/llvm/lib/Target/ARM/ARMFrameLowering.h @@ -47,6 +47,7 @@ public: bool hasFP(const MachineFunction &MF) const override; bool isFPReserved(const MachineFunction &MF) const; + bool requiresAAPCSFrameRecord(const MachineFunction &MF) const; bool hasReservedCallFrame(const MachineFunction &MF) const override; bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override; StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, |