mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-04 01:43:06 +00:00
[PowerPC] Refactor setMinReservedArea and CalculateParameterAndLinkageAreaSize
The PPCISelLowering.cpp routines PPCTargetLowering::setMinReservedArea and CalculateParameterAndLinkageAreaSize are currently used as subroutines from both 64-bit SVR4 and Darwin ABI code. However, the two ABIs are already quite different w.r.t. AltiVec conventions, and they will become more different when the ELFv2 ABI is supported. Also, in general it seems better to disentangle ABI support routines for different ABIs to avoid accidentally affecting one ABI when intending to change only the other. (Actually, the current code strictly speaking already contains a bug: these routines call PPCFrameLowering::getMinCallFrameSize and PPCFrameLowering::getLinkageSize with the IsDarwin parameter set to "true" even on 64-bit SVR4. This bug currently has no adverse effect since those routines always return the same for 64-bit SVR4 and 64-bit Darwin, but it still seems wrong ... I'll fix this in a follow-up commit shortly.) To remove this code sharing, I'm simply inlining both routines into all call sites (there are just two each, one for 64-bit SVR4 and one for Darwin), and simplifying due to constant parameters where possible. A small piece of code that *does* make sense to share is refactored into the new routine EnsureStackAlignment, now also called from 32-bit SVR4 ABI code. No change in generated code is expected. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211493 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fdb6eb65c7
commit
c125f3c15a
@ -2130,6 +2130,15 @@ static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags,
|
||||
|
||||
return ArgSize;
|
||||
}
|
||||
/// EnsureStackAlignment - Round stack frame size up from NumBytes to
|
||||
/// ensure minimum alignment required for target.
|
||||
static unsigned EnsureStackAlignment(const TargetMachine &Target,
|
||||
unsigned NumBytes) {
|
||||
unsigned TargetAlign = Target.getFrameLowering()->getStackAlignment();
|
||||
unsigned AlignMask = TargetAlign - 1;
|
||||
NumBytes = (NumBytes + AlignMask) & ~AlignMask;
|
||||
return NumBytes;
|
||||
}
|
||||
|
||||
SDValue
|
||||
PPCTargetLowering::LowerFormalArguments(SDValue Chain,
|
||||
@ -2285,23 +2294,16 @@ PPCTargetLowering::LowerFormalArguments_32SVR4(
|
||||
|
||||
// Area that is at least reserved in the caller of this function.
|
||||
unsigned MinReservedArea = CCByValInfo.getNextStackOffset();
|
||||
MinReservedArea =
|
||||
std::max(MinReservedArea,
|
||||
PPCFrameLowering::getMinCallFrameSize(false, false));
|
||||
|
||||
// Set the size that is at least reserved in caller of this function. Tail
|
||||
// call optimized function's reserved stack space needs to be aligned so that
|
||||
// taking the difference between two stack areas will result in an aligned
|
||||
// stack.
|
||||
PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
|
||||
|
||||
MinReservedArea =
|
||||
std::max(MinReservedArea,
|
||||
PPCFrameLowering::getMinCallFrameSize(false, false));
|
||||
|
||||
unsigned TargetAlign = DAG.getMachineFunction().getTarget().getFrameLowering()->
|
||||
getStackAlignment();
|
||||
unsigned AlignMask = TargetAlign-1;
|
||||
MinReservedArea = (MinReservedArea + AlignMask) & ~AlignMask;
|
||||
|
||||
FI->setMinReservedArea(MinReservedArea);
|
||||
MinReservedArea = EnsureStackAlignment(MF.getTarget(), MinReservedArea);
|
||||
FuncInfo->setMinReservedArea(MinReservedArea);
|
||||
|
||||
SmallVector<SDValue, 8> MemOps;
|
||||
|
||||
@ -2397,32 +2399,6 @@ PPCTargetLowering::extendArgForPPC64(ISD::ArgFlagsTy Flags, EVT ObjectVT,
|
||||
return DAG.getNode(ISD::TRUNCATE, dl, ObjectVT, ArgVal);
|
||||
}
|
||||
|
||||
// Set the size that is at least reserved in caller of this function. Tail
|
||||
// call optimized functions' reserved stack space needs to be aligned so that
|
||||
// taking the difference between two stack areas will result in an aligned
|
||||
// stack.
|
||||
void
|
||||
PPCTargetLowering::setMinReservedArea(MachineFunction &MF, SelectionDAG &DAG,
|
||||
unsigned nAltivecParamsAtEnd,
|
||||
unsigned MinReservedArea,
|
||||
bool isPPC64) const {
|
||||
PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
|
||||
// Add the Altivec parameters at the end, if needed.
|
||||
if (nAltivecParamsAtEnd) {
|
||||
MinReservedArea = ((MinReservedArea+15)/16)*16;
|
||||
MinReservedArea += 16*nAltivecParamsAtEnd;
|
||||
}
|
||||
MinReservedArea =
|
||||
std::max(MinReservedArea,
|
||||
PPCFrameLowering::getMinCallFrameSize(isPPC64, true));
|
||||
unsigned TargetAlign
|
||||
= DAG.getMachineFunction().getTarget().getFrameLowering()->
|
||||
getStackAlignment();
|
||||
unsigned AlignMask = TargetAlign-1;
|
||||
MinReservedArea = (MinReservedArea + AlignMask) & ~AlignMask;
|
||||
FI->setMinReservedArea(MinReservedArea);
|
||||
}
|
||||
|
||||
SDValue
|
||||
PPCTargetLowering::LowerFormalArguments_64SVR4(
|
||||
SDValue Chain,
|
||||
@ -2680,11 +2656,17 @@ PPCTargetLowering::LowerFormalArguments_64SVR4(
|
||||
InVals.push_back(ArgVal);
|
||||
}
|
||||
|
||||
// Area that is at least reserved in the caller of this function.
|
||||
MinReservedArea =
|
||||
std::max(MinReservedArea,
|
||||
PPCFrameLowering::getMinCallFrameSize(true, true));
|
||||
|
||||
// Set the size that is at least reserved in caller of this function. Tail
|
||||
// call optimized functions' reserved stack space needs to be aligned so that
|
||||
// taking the difference between two stack areas will result in an aligned
|
||||
// stack.
|
||||
setMinReservedArea(MF, DAG, 0, MinReservedArea, true);
|
||||
MinReservedArea = EnsureStackAlignment(MF.getTarget(), MinReservedArea);
|
||||
FuncInfo->setMinReservedArea(MinReservedArea);
|
||||
|
||||
// If the function takes variable number of arguments, make a frame index for
|
||||
// the start of the first vararg value... for expansion of llvm.va_start.
|
||||
@ -3028,11 +3010,23 @@ PPCTargetLowering::LowerFormalArguments_Darwin(
|
||||
InVals.push_back(ArgVal);
|
||||
}
|
||||
|
||||
// Allow for Altivec parameters at the end, if needed.
|
||||
if (nAltivecParamsAtEnd) {
|
||||
MinReservedArea = ((MinReservedArea+15)/16)*16;
|
||||
MinReservedArea += 16*nAltivecParamsAtEnd;
|
||||
}
|
||||
|
||||
// Area that is at least reserved in the caller of this function.
|
||||
MinReservedArea =
|
||||
std::max(MinReservedArea,
|
||||
PPCFrameLowering::getMinCallFrameSize(isPPC64, true));
|
||||
|
||||
// Set the size that is at least reserved in caller of this function. Tail
|
||||
// call optimized functions' reserved stack space needs to be aligned so that
|
||||
// taking the difference between two stack areas will result in an aligned
|
||||
// stack.
|
||||
setMinReservedArea(MF, DAG, nAltivecParamsAtEnd, MinReservedArea, isPPC64);
|
||||
MinReservedArea = EnsureStackAlignment(MF.getTarget(), MinReservedArea);
|
||||
FuncInfo->setMinReservedArea(MinReservedArea);
|
||||
|
||||
// If the function takes variable number of arguments, make a frame index for
|
||||
// the start of the first vararg value... for expansion of llvm.va_start.
|
||||
@ -3071,75 +3065,6 @@ PPCTargetLowering::LowerFormalArguments_Darwin(
|
||||
return Chain;
|
||||
}
|
||||
|
||||
/// CalculateParameterAndLinkageAreaSize - Get the size of the parameter plus
|
||||
/// linkage area for the Darwin ABI, or the 64-bit SVR4 ABI.
|
||||
static unsigned
|
||||
CalculateParameterAndLinkageAreaSize(SelectionDAG &DAG,
|
||||
bool isPPC64,
|
||||
bool isVarArg,
|
||||
unsigned CC,
|
||||
const SmallVectorImpl<ISD::OutputArg>
|
||||
&Outs,
|
||||
const SmallVectorImpl<SDValue> &OutVals,
|
||||
unsigned &nAltivecParamsAtEnd) {
|
||||
// Count how many bytes are to be pushed on the stack, including the linkage
|
||||
// area, and parameter passing area. We start with 24/48 bytes, which is
|
||||
// prereserved space for [SP][CR][LR][3 x unused].
|
||||
unsigned NumBytes = PPCFrameLowering::getLinkageSize(isPPC64, true);
|
||||
unsigned NumOps = Outs.size();
|
||||
unsigned PtrByteSize = isPPC64 ? 8 : 4;
|
||||
|
||||
// Add up all the space actually used.
|
||||
// In 32-bit non-varargs calls, Altivec parameters all go at the end; usually
|
||||
// they all go in registers, but we must reserve stack space for them for
|
||||
// possible use by the caller. In varargs or 64-bit calls, parameters are
|
||||
// assigned stack space in order, with padding so Altivec parameters are
|
||||
// 16-byte aligned.
|
||||
nAltivecParamsAtEnd = 0;
|
||||
for (unsigned i = 0; i != NumOps; ++i) {
|
||||
ISD::ArgFlagsTy Flags = Outs[i].Flags;
|
||||
EVT ArgVT = Outs[i].VT;
|
||||
// Varargs Altivec parameters are padded to a 16 byte boundary.
|
||||
if (ArgVT==MVT::v4f32 || ArgVT==MVT::v4i32 ||
|
||||
ArgVT==MVT::v8i16 || ArgVT==MVT::v16i8 ||
|
||||
ArgVT==MVT::v2f64 || ArgVT==MVT::v2i64) {
|
||||
if (!isVarArg && !isPPC64) {
|
||||
// Non-varargs Altivec parameters go after all the non-Altivec
|
||||
// parameters; handle those later so we know how much padding we need.
|
||||
nAltivecParamsAtEnd++;
|
||||
continue;
|
||||
}
|
||||
// Varargs and 64-bit Altivec parameters are padded to 16 byte boundary.
|
||||
NumBytes = ((NumBytes+15)/16)*16;
|
||||
}
|
||||
NumBytes += CalculateStackSlotSize(ArgVT, Flags, PtrByteSize);
|
||||
}
|
||||
|
||||
// Allow for Altivec parameters at the end, if needed.
|
||||
if (nAltivecParamsAtEnd) {
|
||||
NumBytes = ((NumBytes+15)/16)*16;
|
||||
NumBytes += 16*nAltivecParamsAtEnd;
|
||||
}
|
||||
|
||||
// The prolog code of the callee may store up to 8 GPR argument registers to
|
||||
// the stack, allowing va_start to index over them in memory if its varargs.
|
||||
// Because we cannot tell if this is needed on the caller side, we have to
|
||||
// conservatively assume that it is needed. As such, make sure we have at
|
||||
// least enough stack space for the caller to store the 8 GPRs.
|
||||
NumBytes = std::max(NumBytes,
|
||||
PPCFrameLowering::getMinCallFrameSize(isPPC64, true));
|
||||
|
||||
// Tail call needs the stack to be aligned.
|
||||
if (CC == CallingConv::Fast && DAG.getTarget().Options.GuaranteedTailCallOpt){
|
||||
unsigned TargetAlign = DAG.getMachineFunction().getTarget().
|
||||
getFrameLowering()->getStackAlignment();
|
||||
unsigned AlignMask = TargetAlign-1;
|
||||
NumBytes = (NumBytes + AlignMask) & ~AlignMask;
|
||||
}
|
||||
|
||||
return NumBytes;
|
||||
}
|
||||
|
||||
/// CalculateTailCallSPDiff - Get the amount the stack pointer has to be
|
||||
/// adjusted to accommodate the arguments for the tailcall.
|
||||
static int CalculateTailCallSPDiff(SelectionDAG& DAG, bool isTailCall,
|
||||
@ -4037,16 +3962,37 @@ PPCTargetLowering::LowerCall_64SVR4(SDValue Chain, SDValue Callee,
|
||||
CallConv == CallingConv::Fast)
|
||||
MF.getInfo<PPCFunctionInfo>()->setHasFastCall();
|
||||
|
||||
unsigned nAltivecParamsAtEnd = 0;
|
||||
|
||||
// Count how many bytes are to be pushed on the stack, including the linkage
|
||||
// area, and parameter passing area. We start with at least 48 bytes, which
|
||||
// is reserved space for [SP][CR][LR][3 x unused].
|
||||
// NOTE: For PPC64, nAltivecParamsAtEnd always remains zero as a result
|
||||
// of this call.
|
||||
unsigned NumBytes =
|
||||
CalculateParameterAndLinkageAreaSize(DAG, true, isVarArg, CallConv,
|
||||
Outs, OutVals, nAltivecParamsAtEnd);
|
||||
unsigned NumBytes = PPCFrameLowering::getLinkageSize(true, true);
|
||||
|
||||
// Add up all the space actually used.
|
||||
for (unsigned i = 0; i != NumOps; ++i) {
|
||||
ISD::ArgFlagsTy Flags = Outs[i].Flags;
|
||||
EVT ArgVT = Outs[i].VT;
|
||||
|
||||
// Altivec parameters are padded to a 16 byte boundary.
|
||||
if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
|
||||
ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
|
||||
ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64)
|
||||
NumBytes = ((NumBytes+15)/16)*16;
|
||||
|
||||
NumBytes += CalculateStackSlotSize(ArgVT, Flags, PtrByteSize);
|
||||
}
|
||||
|
||||
// The prolog code of the callee may store up to 8 GPR argument registers to
|
||||
// the stack, allowing va_start to index over them in memory if its varargs.
|
||||
// Because we cannot tell if this is needed on the caller side, we have to
|
||||
// conservatively assume that it is needed. As such, make sure we have at
|
||||
// least enough stack space for the caller to store the 8 GPRs.
|
||||
NumBytes = std::max(NumBytes,
|
||||
PPCFrameLowering::getMinCallFrameSize(true, true));
|
||||
|
||||
// Tail call needs the stack to be aligned.
|
||||
if (getTargetMachine().Options.GuaranteedTailCallOpt &&
|
||||
CallConv == CallingConv::Fast)
|
||||
NumBytes = EnsureStackAlignment(MF.getTarget(), NumBytes);
|
||||
|
||||
// Calculate by how many bytes the stack has to be adjusted in case of tail
|
||||
// call optimization.
|
||||
@ -4440,15 +4386,55 @@ PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,
|
||||
CallConv == CallingConv::Fast)
|
||||
MF.getInfo<PPCFunctionInfo>()->setHasFastCall();
|
||||
|
||||
unsigned nAltivecParamsAtEnd = 0;
|
||||
|
||||
// Count how many bytes are to be pushed on the stack, including the linkage
|
||||
// area, and parameter passing area. We start with 24/48 bytes, which is
|
||||
// prereserved space for [SP][CR][LR][3 x unused].
|
||||
unsigned NumBytes =
|
||||
CalculateParameterAndLinkageAreaSize(DAG, isPPC64, isVarArg, CallConv,
|
||||
Outs, OutVals,
|
||||
nAltivecParamsAtEnd);
|
||||
unsigned NumBytes = PPCFrameLowering::getLinkageSize(isPPC64, true);
|
||||
|
||||
// Add up all the space actually used.
|
||||
// In 32-bit non-varargs calls, Altivec parameters all go at the end; usually
|
||||
// they all go in registers, but we must reserve stack space for them for
|
||||
// possible use by the caller. In varargs or 64-bit calls, parameters are
|
||||
// assigned stack space in order, with padding so Altivec parameters are
|
||||
// 16-byte aligned.
|
||||
unsigned nAltivecParamsAtEnd = 0;
|
||||
for (unsigned i = 0; i != NumOps; ++i) {
|
||||
ISD::ArgFlagsTy Flags = Outs[i].Flags;
|
||||
EVT ArgVT = Outs[i].VT;
|
||||
// Varargs Altivec parameters are padded to a 16 byte boundary.
|
||||
if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
|
||||
ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
|
||||
ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64) {
|
||||
if (!isVarArg && !isPPC64) {
|
||||
// Non-varargs Altivec parameters go after all the non-Altivec
|
||||
// parameters; handle those later so we know how much padding we need.
|
||||
nAltivecParamsAtEnd++;
|
||||
continue;
|
||||
}
|
||||
// Varargs and 64-bit Altivec parameters are padded to 16 byte boundary.
|
||||
NumBytes = ((NumBytes+15)/16)*16;
|
||||
}
|
||||
NumBytes += CalculateStackSlotSize(ArgVT, Flags, PtrByteSize);
|
||||
}
|
||||
|
||||
// Allow for Altivec parameters at the end, if needed.
|
||||
if (nAltivecParamsAtEnd) {
|
||||
NumBytes = ((NumBytes+15)/16)*16;
|
||||
NumBytes += 16*nAltivecParamsAtEnd;
|
||||
}
|
||||
|
||||
// The prolog code of the callee may store up to 8 GPR argument registers to
|
||||
// the stack, allowing va_start to index over them in memory if its varargs.
|
||||
// Because we cannot tell if this is needed on the caller side, we have to
|
||||
// conservatively assume that it is needed. As such, make sure we have at
|
||||
// least enough stack space for the caller to store the 8 GPRs.
|
||||
NumBytes = std::max(NumBytes,
|
||||
PPCFrameLowering::getMinCallFrameSize(isPPC64, true));
|
||||
|
||||
// Tail call needs the stack to be aligned.
|
||||
if (getTargetMachine().Options.GuaranteedTailCallOpt &&
|
||||
CallConv == CallingConv::Fast)
|
||||
NumBytes = EnsureStackAlignment(MF.getTarget(), NumBytes);
|
||||
|
||||
// Calculate by how many bytes the stack has to be adjusted in case of tail
|
||||
// call optimization.
|
||||
|
@ -610,11 +610,6 @@ namespace llvm {
|
||||
extendArgForPPC64(ISD::ArgFlagsTy Flags, EVT ObjectVT, SelectionDAG &DAG,
|
||||
SDValue ArgVal, SDLoc dl) const;
|
||||
|
||||
void
|
||||
setMinReservedArea(MachineFunction &MF, SelectionDAG &DAG,
|
||||
unsigned nAltivecParamsAtEnd,
|
||||
unsigned MinReservedArea, bool isPPC64) const;
|
||||
|
||||
SDValue
|
||||
LowerFormalArguments_Darwin(SDValue Chain,
|
||||
CallingConv::ID CallConv, bool isVarArg,
|
||||
|
Loading…
Reference in New Issue
Block a user