summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@google.com>2016-02-23 18:13:07 +0000
committerDerek Schuff <dschuff@google.com>2016-02-23 18:13:07 +0000
commit4b3bb213b2d21d862542cfe1965fbd4cab28f1a8 (patch)
treed52642210677862f16aa2797f371911c258dbc71 /llvm/lib
parent1b9fae5a40a92e2bb6c35286b2b9f2a58809423b (diff)
downloadbcm5719-llvm-4b3bb213b2d21d862542cfe1965fbd4cab28f1a8.tar.gz
bcm5719-llvm-4b3bb213b2d21d862542cfe1965fbd4cab28f1a8.zip
[WebAssembly] Implement red zone for user stack
Implements a mostly-conventional redzone for the userspace stack. Because we have unsigned load/store offsets we continue to use a local SP subtracted from the incoming SP but do not write it back to memory. Differential Revision: http://reviews.llvm.org/D17525 llvm-svn: 261662
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp28
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.h8
2 files changed, 31 insertions, 5 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
index c5f43d806ed..ece8974408b 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
@@ -34,7 +34,6 @@ using namespace llvm;
#define DEBUG_TYPE "wasm-frame-info"
-// TODO: Implement a red zone?
// TODO: wasm64
// TODO: Emit TargetOpcode::CFI_INSTRUCTION instructions
@@ -59,6 +58,24 @@ bool WebAssemblyFrameLowering::hasReservedCallFrame(
return !MF.getFrameInfo()->hasVarSizedObjects();
}
+
+/// Returns true if this function needs a local user-space stack pointer.
+/// Unlike a machine stack pointer, the wasm user stack pointer is a global
+/// variable, so it is loaded into a register in the prolog.
+bool WebAssemblyFrameLowering::needsSP(const MachineFunction &MF,
+ const MachineFrameInfo &MFI) const {
+ return MFI.getStackSize() || MFI.adjustsStack() || hasFP(MF);
+}
+
+/// Returns true if the local user-space stack pointer needs to be written back
+/// to memory by this function (this is not meaningful if needsSP is false). If
+/// false, the stack red zone can be used and only a local SP is needed.
+bool WebAssemblyFrameLowering::needsSPWriteback(
+ const MachineFunction &MF, const MachineFrameInfo &MFI) const {
+ return MFI.getStackSize() > RedZoneSize || MFI.hasCalls() ||
+ MF.getFunction()->hasFnAttribute(Attribute::NoRedZone);
+}
+
static void writeSPToMemory(unsigned SrcReg, MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator &InsertPt,
@@ -88,7 +105,8 @@ void WebAssemblyFrameLowering::eliminateCallFramePseudoInstr(
assert(!I->getOperand(0).getImm() && hasFP(MF) &&
"Call frame pseudos should only be used for dynamic stack adjustment");
const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
- if (I->getOpcode() == TII->getCallFrameDestroyOpcode()) {
+ if (I->getOpcode() == TII->getCallFrameDestroyOpcode() &&
+ needsSPWriteback(MF, *MF.getFrameInfo())) {
DebugLoc DL = I->getDebugLoc();
writeSPToMemory(WebAssembly::SP32, MF, MBB, I, DL);
}
@@ -103,8 +121,8 @@ void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF,
"WebAssembly should not have callee-saved registers");
auto *WFI = MF.getInfo<WebAssemblyFunctionInfo>();
+ if (!needsSP(MF, *MFI)) return;
uint64_t StackSize = MFI->getStackSize();
- if (!StackSize && !MFI->adjustsStack() && !hasFP(MF)) return;
const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
auto &MRI = MF.getRegInfo();
@@ -152,7 +170,7 @@ void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF,
WebAssembly::FP32)
.addReg(WebAssembly::SP32);
}
- if (StackSize) {
+ if (StackSize && needsSPWriteback(MF, *MFI)) {
writeSPToMemory(WebAssembly::SP32, MF, MBB, InsertPt, DL);
}
}
@@ -161,7 +179,7 @@ void WebAssemblyFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
auto *MFI = MF.getFrameInfo();
uint64_t StackSize = MFI->getStackSize();
- if (!StackSize && !MFI->adjustsStack() && !hasFP(MF)) return;
+ if (!needsSP(MF, *MFI) || !needsSPWriteback(MF, *MFI)) return;
auto *WFI = MF.getInfo<WebAssemblyFunctionInfo>();
const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
auto &MRI = MF.getRegInfo();
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.h b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.h
index 39f3f04e68d..cb3b011aeb8 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.h
@@ -19,9 +19,12 @@
#include "llvm/Target/TargetFrameLowering.h"
namespace llvm {
+class MachineFrameInfo;
class WebAssemblyFrameLowering final : public TargetFrameLowering {
public:
+ static const size_t RedZoneSize = 128;
+
WebAssemblyFrameLowering()
: TargetFrameLowering(StackGrowsDown, /*StackAlignment=*/16,
/*LocalAreaOffset=*/0,
@@ -38,6 +41,11 @@ class WebAssemblyFrameLowering final : public TargetFrameLowering {
bool hasFP(const MachineFunction &MF) const override;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
+
+ private:
+ bool needsSP(const MachineFunction &MF, const MachineFrameInfo &MFI) const;
+ bool needsSPWriteback(const MachineFunction &MF,
+ const MachineFrameInfo &MFI) const;
};
} // end namespace llvm
OpenPOWER on IntegriCloud