diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/Hexagon/Hexagon.td | 3 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp | 32 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonFrameLowering.h | 2 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonSubtarget.h | 3 |
4 files changed, 39 insertions, 1 deletions
diff --git a/llvm/lib/Target/Hexagon/Hexagon.td b/llvm/lib/Target/Hexagon/Hexagon.td index 8853dd6d550..dabf37e2887 100644 --- a/llvm/lib/Target/Hexagon/Hexagon.td +++ b/llvm/lib/Target/Hexagon/Hexagon.td @@ -60,6 +60,9 @@ def FeatureDuplex: SubtargetFeature<"duplex", "EnableDuplex", "true", "Enable generation of duplex instruction">; def FeatureReservedR19: SubtargetFeature<"reserved-r19", "ReservedR19", "true", "Reserve register R19">; +def FeatureNoreturnStackElim: SubtargetFeature<"noreturn-stack-elim", + "NoreturnStackElim", "true", + "Eliminate stack allocation in a noreturn function when possible">; //===----------------------------------------------------------------------===// // Hexagon Instruction Predicate Definitions. diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp index 2f3e18c99c5..1600ee3a845 100644 --- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -550,6 +550,36 @@ void HexagonFrameLowering::emitPrologue(MachineFunction &MF, } } +/// Returns true if the target can safely skip saving callee-saved registers +/// for noreturn nounwind functions. +bool HexagonFrameLowering::enableCalleeSaveSkip( + const MachineFunction &MF) const { + const auto &F = MF.getFunction(); + assert(F.hasFnAttribute(Attribute::NoReturn) && + F.getFunction().hasFnAttribute(Attribute::NoUnwind) && + !F.getFunction().hasFnAttribute(Attribute::UWTable)); + + // No need to save callee saved registers if the function does not return. + return MF.getSubtarget<HexagonSubtarget>().noreturnStackElim(); +} + +// Helper function used to determine when to eliminate the stack frame for +// functions marked as noreturn and when the noreturn-stack-elim options are +// specified. When both these conditions are true, then a FP may not be needed +// if the function makes a call. It is very similar to enableCalleeSaveSkip, +// but it used to check if the allocframe can be eliminated as well. +static bool enableAllocFrameElim(const MachineFunction &MF) { + const auto &F = MF.getFunction(); + const auto &MFI = MF.getFrameInfo(); + const auto &HST = MF.getSubtarget<HexagonSubtarget>(); + assert(!MFI.hasVarSizedObjects() && + !HST.getRegisterInfo()->needsStackRealignment(MF)); + return F.hasFnAttribute(Attribute::NoReturn) && + F.hasFnAttribute(Attribute::NoUnwind) && + !F.hasFnAttribute(Attribute::UWTable) && HST.noreturnStackElim() && + MFI.getStackSize() == 0; +} + void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &MBB, bool PrologueStubs) const { MachineFunction &MF = *MBB.getParent(); @@ -994,7 +1024,7 @@ bool HexagonFrameLowering::hasFP(const MachineFunction &MF) const { } const auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>(); - if (MFI.hasCalls() || HMFI.hasClobberLR()) + if ((MFI.hasCalls() && !enableAllocFrameElim(MF)) || HMFI.hasClobberLR()) return true; return false; diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h index 988718860c5..d65d870750f 100644 --- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h +++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h @@ -41,6 +41,8 @@ public: void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override {} + bool enableCalleeSaveSkip(const MachineFunction &MF) const override; + bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector<CalleeSavedInfo> &CSI, const TargetRegisterInfo *TRI) const override { diff --git a/llvm/lib/Target/Hexagon/HexagonSubtarget.h b/llvm/lib/Target/Hexagon/HexagonSubtarget.h index eaae4db6ba9..de8ac917da5 100644 --- a/llvm/lib/Target/Hexagon/HexagonSubtarget.h +++ b/llvm/lib/Target/Hexagon/HexagonSubtarget.h @@ -56,6 +56,7 @@ class HexagonSubtarget : public HexagonGenSubtargetInfo { bool HasMemNoShuf = false; bool EnableDuplex = false; bool ReservedR19 = false; + bool NoreturnStackElim = false; public: Hexagon::ArchEnum HexagonArchVersion; @@ -168,6 +169,8 @@ public: bool hasReservedR19() const { return ReservedR19; } bool usePredicatedCalls() const; + bool noreturnStackElim() const { return NoreturnStackElim; } + bool useBSBScheduling() const { return UseBSBScheduling; } bool enableMachineScheduler() const override; |