summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Hexagon/Hexagon.td3
-rw-r--r--llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp32
-rw-r--r--llvm/lib/Target/Hexagon/HexagonFrameLowering.h2
-rw-r--r--llvm/lib/Target/Hexagon/HexagonSubtarget.h3
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;
OpenPOWER on IntegriCloud