aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
commit145449b1e420787bb99721a429341fa6be3adfb6 (patch)
tree1d56ae694a6de602e348dd80165cf881a36600ed /llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
parentecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff)
Diffstat (limited to 'llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp')
-rw-r--r--llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp90
1 files changed, 82 insertions, 8 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
index 610627e7e3f0..43bc7426cfa8 100644
--- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
@@ -13,6 +13,7 @@
#include "SystemZMachineFunctionInfo.h"
#include "SystemZRegisterInfo.h"
#include "SystemZSubtarget.h"
+#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
@@ -95,8 +96,7 @@ typedef std::vector<SZFrameSortingObj> SZFrameObjVec;
void SystemZELFFrameLowering::orderFrameObjects(
const MachineFunction &MF, SmallVectorImpl<int> &ObjectsToAllocate) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
- const SystemZInstrInfo *TII =
- static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
+ auto *TII = MF.getSubtarget<SystemZSubtarget>().getInstrInfo();
// Make a vector of sorting objects to track all MFI objects and mark those
// to be sorted as valid.
@@ -1153,12 +1153,6 @@ void SystemZXPLINKFrameLowering::emitPrologue(MachineFunction &MF,
MFFrame.setStackSize(MFFrame.getStackSize() + Regs.getCallFrameSize());
uint64_t StackSize = MFFrame.getStackSize();
- // FIXME: Implement support for large stack sizes, when the stack extension
- // routine needs to be called.
- if (StackSize > 1024 * 1024) {
- llvm_unreachable("Huge Stack Frame not yet supported on z/OS");
- }
-
if (ZFI->getSpillGPRRegs().LowGPR) {
// Skip over the GPR saves.
if ((MBBI != MBB.end()) && ((MBBI->getOpcode() == SystemZ::STMG))) {
@@ -1201,6 +1195,18 @@ void SystemZXPLINKFrameLowering::emitPrologue(MachineFunction &MF,
emitIncrement(MBB, InsertPt, DL, Regs.getStackPointerRegister(), Delta,
ZII);
+
+ // If the requested stack size is larger than the guard page, then we need
+ // to check if we need to call the stack extender. This requires adding a
+ // conditional branch, but splitting the prologue block is not possible at
+ // this point since it would invalidate the SaveBlocks / RestoreBlocks sets
+ // of PEI in the single block function case. Build a pseudo to be handled
+ // later by inlineStackProbe().
+ const uint64_t GuardPageSize = 1024 * 1024;
+ if (StackSize > GuardPageSize) {
+ assert(StoreInstr && "Wrong insertion point");
+ BuildMI(MBB, InsertPt, DL, ZII->get(SystemZ::XPLINK_STACKALLOC));
+ }
}
if (HasFP) {
@@ -1239,6 +1245,74 @@ void SystemZXPLINKFrameLowering::emitEpilogue(MachineFunction &MF,
}
}
+// Emit a compare of the stack pointer against the stack floor, and a call to
+// the LE stack extender if needed.
+void SystemZXPLINKFrameLowering::inlineStackProbe(
+ MachineFunction &MF, MachineBasicBlock &PrologMBB) const {
+ auto *ZII =
+ static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
+
+ MachineInstr *StackAllocMI = nullptr;
+ for (MachineInstr &MI : PrologMBB)
+ if (MI.getOpcode() == SystemZ::XPLINK_STACKALLOC) {
+ StackAllocMI = &MI;
+ break;
+ }
+ if (StackAllocMI == nullptr)
+ return;
+
+ MachineBasicBlock &MBB = PrologMBB;
+ const DebugLoc DL = StackAllocMI->getDebugLoc();
+
+ // The 2nd half of block MBB after split.
+ MachineBasicBlock *NextMBB;
+
+ // Add new basic block for the call to the stack overflow function.
+ MachineBasicBlock *StackExtMBB =
+ MF.CreateMachineBasicBlock(MBB.getBasicBlock());
+ MF.push_back(StackExtMBB);
+
+ // LG r3,72(,r3)
+ BuildMI(StackExtMBB, DL, ZII->get(SystemZ::LG), SystemZ::R3D)
+ .addReg(SystemZ::R3D)
+ .addImm(72)
+ .addReg(0);
+ // BASR r3,r3
+ BuildMI(StackExtMBB, DL, ZII->get(SystemZ::CallBASR_STACKEXT))
+ .addReg(SystemZ::R3D);
+
+ // LLGT r3,1208
+ BuildMI(MBB, StackAllocMI, DL, ZII->get(SystemZ::LLGT), SystemZ::R3D)
+ .addReg(0)
+ .addImm(1208)
+ .addReg(0);
+ // CG r4,64(,r3)
+ BuildMI(MBB, StackAllocMI, DL, ZII->get(SystemZ::CG))
+ .addReg(SystemZ::R4D)
+ .addReg(SystemZ::R3D)
+ .addImm(64)
+ .addReg(0);
+ // JLL b'0100',F'37'
+ BuildMI(MBB, StackAllocMI, DL, ZII->get(SystemZ::BRC))
+ .addImm(SystemZ::CCMASK_ICMP)
+ .addImm(SystemZ::CCMASK_CMP_LT)
+ .addMBB(StackExtMBB);
+
+ NextMBB = SystemZ::splitBlockBefore(StackAllocMI, &MBB);
+ MBB.addSuccessor(NextMBB);
+ MBB.addSuccessor(StackExtMBB);
+
+ // Add jump back from stack extension BB.
+ BuildMI(StackExtMBB, DL, ZII->get(SystemZ::J)).addMBB(NextMBB);
+ StackExtMBB->addSuccessor(NextMBB);
+
+ StackAllocMI->eraseFromParent();
+
+ // Compute the live-in lists for the new blocks.
+ recomputeLiveIns(*NextMBB);
+ recomputeLiveIns(*StackExtMBB);
+}
+
bool SystemZXPLINKFrameLowering::hasFP(const MachineFunction &MF) const {
return (MF.getFrameInfo().hasVarSizedObjects());
}