[llvm] [RISCV][GISEL] lowerFormalArguments for variadic arguments (PR #73064)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 28 18:03:10 PST 2023
================
@@ -423,18 +423,79 @@ bool RISCVCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
return true;
}
+static const MCPhysReg ArgGPRs[] = {RISCV::X10, RISCV::X11, RISCV::X12,
+ RISCV::X13, RISCV::X14, RISCV::X15,
+ RISCV::X16, RISCV::X17};
+
+/// If there are varargs that were passed in a0-a7, the data in those registers
+/// must be copied to the varargs save area on the stack.
+void RISCVCallLowering::saveVarArgRegisters(
+ MachineIRBuilder &MIRBuilder, CallLowering::IncomingValueHandler &Handler,
+ IncomingValueAssigner &Assigner, CCState &CCInfo) const {
+ MachineFunction &MF = MIRBuilder.getMF();
+ const RISCVSubtarget &Subtarget = MF.getSubtarget<RISCVSubtarget>();
+ unsigned XLenInBytes = Subtarget.getXLen() / 8;
+ ArrayRef<MCPhysReg> ArgRegs(ArgGPRs);
+ unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
+
+ // Offset of the first variable argument from stack pointer, and size of
+ // the vararg save area. For now, the varargs save area is either zero or
+ // large enough to hold a0-a7.
+ int VaArgOffset, VarArgsSaveSize;
+ // If all registers are allocated, then all varargs must be passed on the
+ // stack and we don't need to save any argregs.
+ if (ArgRegs.size() == Idx) {
+ VaArgOffset = Assigner.StackSize;
+ VarArgsSaveSize = 0;
+ } else {
+ VarArgsSaveSize = XLenInBytes * (ArgRegs.size() - Idx);
+ VaArgOffset = -VarArgsSaveSize;
+ }
+
+ // Record the frame index of the first variable argument which is a value
+ // necessary to G_VASTART.
+ MachineFrameInfo &MFI = MF.getFrameInfo();
+ int FI = MFI.CreateFixedObject(XLenInBytes, VaArgOffset, true);
+ RISCVMachineFunctionInfo *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
+ RVFI->setVarArgsFrameIndex(FI);
+
+ // If saving an odd number of registers then create an extra stack slot to
+ // ensure that the frame pointer is 2*XLEN-aligned, which in turn ensures
+ // offsets to even-numbered registered remain 2*XLEN-aligned.
+ if (Idx % 2) {
+ MFI.CreateFixedObject(XLenInBytes, VaArgOffset - (int)XLenInBytes, true);
+ VarArgsSaveSize += XLenInBytes;
+ }
+ RVFI->setVarArgsSaveSize(VarArgsSaveSize);
+
+ // Copy the integer registers that may have been used for passing varargs
+ // to the vararg save area.
+ const LLT p0 = LLT::pointer(0, Subtarget.getXLen());
+ const LLT sXLen = LLT::scalar(Subtarget.getXLen());
+ const MVT XLenMVT = MVT::getIntegerVT(Subtarget.getXLen());
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ for (unsigned I = Idx; I < ArgRegs.size(); ++I, VaArgOffset += XLenInBytes) {
+ const Register VReg = MRI.createGenericVirtualRegister(sXLen);
+ Handler.assignValueToReg(
+ VReg, ArgRegs[I],
+ CCValAssign::getReg(I + MF.getFunction().getNumOperands(), XLenMVT,
+ ArgRegs[I], XLenMVT, CCValAssign::Full));
+ FI = MFI.CreateFixedObject(XLenInBytes, VaArgOffset, true);
+ auto FIN = MIRBuilder.buildFrameIndex(p0, FI);
+ auto MPO = MachinePointerInfo::getFixedStack(MF, FI);
+ MIRBuilder.buildStore(VReg, FIN, MPO, inferAlignFromPtrInfo(MF, MPO));
+ }
----------------
topperc wrote:
The Value is stored in the MachinePointerInfo. The getFixedStack call is what sets it.
https://github.com/llvm/llvm-project/pull/73064
More information about the llvm-commits
mailing list