diff options
author | Shiva Chen <shiva0217@gmail.com> | 2018-03-20 01:39:17 +0000 |
---|---|---|
committer | Shiva Chen <shiva0217@gmail.com> | 2018-03-20 01:39:17 +0000 |
commit | cbd498ac10427778a6133b9dc3a78c3a5e9ec6cd (patch) | |
tree | e2b2fcdef9f6681091aa1b6046ef9477f343bebc /llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | |
parent | 2330d6cd550203d6ebc262e87b4a736e70ffad74 (diff) | |
download | bcm5719-llvm-cbd498ac10427778a6133b9dc3a78c3a5e9ec6cd.tar.gz bcm5719-llvm-cbd498ac10427778a6133b9dc3a78c3a5e9ec6cd.zip |
[RISCV] Preserve stack space for outgoing arguments when the function contain variable size objects
E.g.
bar (int x)
{
char p[x];
push outgoing variables for foo.
call foo
}
We need to generate stack adjustment instructions for outgoing arguments by
eliminateCallFramePseudoInstr when the function contains variable size
objects to avoid outgoing variables corrupt the variable size object.
Default hasReservedCallFrame will return !hasFP().
We don't want to generate extra sp adjustment instructions when hasFP()
return true, So We override hasReservedCallFrame as !hasVarSizedObjects().
Differential Revision: https://reviews.llvm.org/D43752
llvm-svn: 327938
Diffstat (limited to 'llvm/lib/Target/RISCV/RISCVFrameLowering.cpp')
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index 33703f5ec20..3dc1e3dbb27 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -43,21 +43,6 @@ void RISCVFrameLowering::determineFrameLayout(MachineFunction &MF) const { uint64_t StackAlign = RI->needsStackRealignment(MF) ? MFI.getMaxAlignment() : getStackAlignment(); - // Get the maximum call frame size of all the calls. - uint64_t MaxCallFrameSize = MFI.getMaxCallFrameSize(); - - // If we have dynamic alloca then MaxCallFrameSize needs to be aligned so - // that allocations will be aligned. - if (MFI.hasVarSizedObjects()) - MaxCallFrameSize = alignTo(MaxCallFrameSize, StackAlign); - - // Update maximum call frame size. - MFI.setMaxCallFrameSize(MaxCallFrameSize); - - // Include call frame size in total. - if (!(hasReservedCallFrame(MF) && MFI.adjustsStack())) - FrameSize += MaxCallFrameSize; - // Make sure the frame is aligned. FrameSize = alignTo(FrameSize, StackAlign); @@ -246,3 +231,39 @@ void RISCVFrameLowering::processFunctionBeforeFrameFinalized( RS->addScavengingFrameIndex(RegScavFI); } } + +// Not preserve stack space within prologue for outgoing variables when the +// function contains variable size objects and let eliminateCallFramePseudoInstr +// preserve stack space for it. +bool RISCVFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { + return !MF.getFrameInfo().hasVarSizedObjects(); +} + +// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions. +MachineBasicBlock::iterator RISCVFrameLowering::eliminateCallFramePseudoInstr( + MachineFunction &MF, MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI) const { + unsigned SPReg = RISCV::X2; + DebugLoc DL = MI->getDebugLoc(); + + if (!hasReservedCallFrame(MF)) { + // If space has not been reserved for a call frame, ADJCALLSTACKDOWN and + // ADJCALLSTACKUP must be converted to instructions manipulating the stack + // pointer. This is necessary when there is a variable length stack + // allocation (e.g. alloca), which means it's not possible to allocate + // space for outgoing arguments from within the function prologue. + int64_t Amount = MI->getOperand(0).getImm(); + + if (Amount != 0) { + // Ensure the stack remains aligned after adjustment. + Amount = alignSPAdjust(Amount); + + if (MI->getOpcode() == RISCV::ADJCALLSTACKDOWN) + Amount = -Amount; + + adjustReg(MBB, MI, DL, SPReg, SPReg, Amount, MachineInstr::NoFlags); + } + } + + return MBB.erase(MI); +} |