diff options
Diffstat (limited to 'llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp')
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp index fa20977ec018..a769fdeff568 100644 --- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp @@ -1475,6 +1475,28 @@ void SystemZXPLINKFrameLowering::processFunctionBeforeFrameFinalized( // with existing compilers. MFFrame.setMaxCallFrameSize( std::max(64U, (unsigned)alignTo(MFFrame.getMaxCallFrameSize(), 64))); + + // Add frame values with positive object offsets. Since the displacement from + // the SP/FP is calculated by ObjectOffset + StackSize + Bias, object offsets + // with positive values are in the caller's stack frame. We need to include + // that since it is accessed by displacement to SP/FP. + int64_t LargestArgOffset = 0; + for (int I = MFFrame.getObjectIndexBegin(); I != 0; ++I) { + if (MFFrame.getObjectOffset(I) >= 0) { + int64_t ObjOffset = MFFrame.getObjectOffset(I) + MFFrame.getObjectSize(I); + LargestArgOffset = std::max(ObjOffset, LargestArgOffset); + } + } + + uint64_t MaxReach = (StackSize + Regs.getCallFrameSize() + + Regs.getStackPointerBias() + LargestArgOffset); + + if (!isUInt<12>(MaxReach)) { + // We may need register scavenging slots if some parts of the frame + // are outside the reach of an unsigned 12-bit displacement. + RS->addScavengingFrameIndex(MFFrame.CreateStackObject(8, Align(8), false)); + RS->addScavengingFrameIndex(MFFrame.CreateStackObject(8, Align(8), false)); + } } // Determines the size of the frame, and creates the deferred spill objects. |
