Skip to content

Commit e12da2e

Browse files
committed
add X86TargetLowering::ByValNeedsCopyForTailCall
1 parent 2482d8f commit e12da2e

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

llvm/lib/Target/X86/X86ISelLowering.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,19 @@ namespace llvm {
10671067
//===--------------------------------------------------------------------===//
10681068
// X86 Implementation of the TargetLowering interface
10691069
class X86TargetLowering final : public TargetLowering {
1070+
// Copying needed for an outgoing byval argument.
1071+
enum ByValCopyKind {
1072+
// Argument is already in the correct location, no copy needed.
1073+
NoCopy,
1074+
// Argument value is currently in the local stack frame, needs copying to
1075+
// outgoing arguemnt area.
1076+
CopyOnce,
1077+
// Argument value is currently in the outgoing argument area, but not at
1078+
// the correct offset, so needs copying via a temporary in local stack
1079+
// space.
1080+
CopyViaTemp,
1081+
};
1082+
10701083
public:
10711084
explicit X86TargetLowering(const X86TargetMachine &TM,
10721085
const X86Subtarget &STI);
@@ -1775,6 +1788,9 @@ namespace llvm {
17751788
SDValue LowerADDROFRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
17761789
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
17771790
SDValue LowerFRAME_TO_ARGS_OFFSET(SDValue Op, SelectionDAG &DAG) const;
1791+
ByValCopyKind ByValNeedsCopyForTailCall(SelectionDAG &DAG, SDValue Src,
1792+
SDValue Dst,
1793+
ISD::ArgFlagsTy Flags) const;
17781794
SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
17791795
SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
17801796
SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;

llvm/lib/Target/X86/X86ISelLoweringCall.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2018,6 +2018,61 @@ SDValue X86TargetLowering::getMOVL(SelectionDAG &DAG, const SDLoc &dl, MVT VT,
20182018
return DAG.getVectorShuffle(VT, dl, V1, V2, Mask);
20192019
}
20202020

2021+
// Returns the type of copying which is required to set up a byval argument to
2022+
// a tail-called function. This isn't needed for non-tail calls, because they
2023+
// always need the equivalent of CopyOnce, but tail-calls sometimes need two to
2024+
// avoid clobbering another argument (CopyViaTemp), and sometimes can be
2025+
// optimised to zero copies when forwarding an argument from the caller's
2026+
// caller (NoCopy).
2027+
X86TargetLowering::ByValCopyKind X86TargetLowering::ByValNeedsCopyForTailCall(
2028+
SelectionDAG &DAG, SDValue Src, SDValue Dst, ISD::ArgFlagsTy Flags) const {
2029+
MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
2030+
2031+
// Globals are always safe to copy from.
2032+
if (isa<GlobalAddressSDNode>(Src) || isa<ExternalSymbolSDNode>(Src))
2033+
return CopyOnce;
2034+
2035+
// Can only analyse frame index nodes, conservatively assume we need a
2036+
// temporary.
2037+
auto *SrcFrameIdxNode = dyn_cast<FrameIndexSDNode>(Src);
2038+
auto *DstFrameIdxNode = dyn_cast<FrameIndexSDNode>(Dst);
2039+
if (!SrcFrameIdxNode || !DstFrameIdxNode)
2040+
return CopyViaTemp;
2041+
2042+
int SrcFI = SrcFrameIdxNode->getIndex();
2043+
int DstFI = DstFrameIdxNode->getIndex();
2044+
assert(MFI.isFixedObjectIndex(DstFI) &&
2045+
"byval passed in non-fixed stack slot");
2046+
2047+
int64_t SrcOffset = MFI.getObjectOffset(SrcFI);
2048+
int64_t DstOffset = MFI.getObjectOffset(DstFI);
2049+
2050+
// FIXME:
2051+
2052+
// // If the source is in the local frame, then the copy to the argument
2053+
// memory
2054+
// // is always valid.
2055+
// bool FixedSrc = MFI.isFixedObjectIndex(SrcFI);
2056+
// if (!FixedSrc ||
2057+
// (FixedSrc && SrcOffset < -(int64_t)AFI->getArgRegsSaveSize()))
2058+
// return CopyOnce;
2059+
2060+
// In the case of byval arguments split between registers and the stack,
2061+
// computeAddrForCallArg returns a FrameIndex which corresponds only to the
2062+
// stack portion, but the Src SDValue will refer to the full value, including
2063+
// the local stack memory that the register portion gets stored into. We only
2064+
// need to compare them for equality, so normalise on the full value version.
2065+
uint64_t RegSize = Flags.getByValSize() - MFI.getObjectSize(DstFI);
2066+
DstOffset -= RegSize;
2067+
2068+
// If the value is already in the correct location, then no copying is
2069+
// needed. If not, then we need to copy via a temporary.
2070+
if (SrcOffset == DstOffset)
2071+
return NoCopy;
2072+
else
2073+
return CopyViaTemp;
2074+
}
2075+
20212076
SDValue
20222077
X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
20232078
SmallVectorImpl<SDValue> &InVals) const {

0 commit comments

Comments
 (0)