@@ -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+
20212076SDValue
20222077X86TargetLowering::LowerCall (TargetLowering::CallLoweringInfo &CLI,
20232078 SmallVectorImpl<SDValue> &InVals) const {
0 commit comments