[RISCV] Support for varargs
Includes support for expanding va_copy. Also adds support for using 'aligned'
registers when necessary for vararg calls, and ensure the frame pointer always
points to the bottom of the vararg spill region. This is necessary to ensure
that the saved return address and stack pointer are always available at fixed
known offsets of the frame pointer.
Differential Revision: https://reviews.llvm.org/D40805
llvm-svn: 322215
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index e9e003e..e1448ba 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "RISCVFrameLowering.h"
+#include "RISCVMachineFunctionInfo.h"
#include "RISCVSubtarget.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -91,6 +92,7 @@
}
MachineFrameInfo &MFI = MF.getFrameInfo();
+ auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
MachineBasicBlock::iterator MBBI = MBB.begin();
unsigned FPReg = getFPReg(STI);
@@ -124,7 +126,8 @@
std::advance(MBBI, CSI.size());
// Generate new FP.
- adjustReg(MBB, MBBI, DL, FPReg, SPReg, StackSize, MachineInstr::FrameSetup);
+ adjustReg(MBB, MBBI, DL, FPReg, SPReg, StackSize - RVFI->getVarArgsSaveSize(),
+ MachineInstr::FrameSetup);
}
void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
@@ -137,6 +140,7 @@
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
MachineFrameInfo &MFI = MF.getFrameInfo();
+ auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
DebugLoc DL = MBBI->getDebugLoc();
unsigned FPReg = getFPReg(STI);
unsigned SPReg = getSPReg(STI);
@@ -153,7 +157,8 @@
// necessary if the stack pointer was modified, meaning the stack size is
// unknown.
if (RI->needsStackRealignment(MF) || MFI.hasVarSizedObjects()) {
- adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg, -StackSize,
+ adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg,
+ -StackSize + RVFI->getVarArgsSaveSize(),
MachineInstr::FrameDestroy);
}
@@ -166,6 +171,7 @@
unsigned &FrameReg) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo();
+ const auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
// Callee-saved registers should be referenced relative to the stack
// pointer (positive offset), otherwise use the frame pointer (negative
@@ -182,10 +188,13 @@
MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
}
- FrameReg = RI->getFrameRegister(MF);
if (FI >= MinCSFI && FI <= MaxCSFI) {
FrameReg = RISCV::X2;
Offset += MF.getFrameInfo().getStackSize();
+ } else {
+ FrameReg = RI->getFrameRegister(MF);
+ assert(hasFP(MF) && "Offset calculation incorrect if !hasFP");
+ Offset += RVFI->getVarArgsSaveSize();
}
return Offset;
}