@@ -2018,6 +2018,103 @@ SDValue X86TargetLowering::getMOVL(SelectionDAG &DAG, const SDLoc &dl, MVT VT,
20182018 return DAG.getVectorShuffle (VT, dl, V1, V2, Mask);
20192019}
20202020
2021+ // / Return true if the given stack call argument is already available in the
2022+ // / same position (relatively) of the caller's incoming argument stack.
2023+ static bool MatchingStackOffset (SDValue Arg, unsigned Offset,
2024+ ISD::ArgFlagsTy Flags, MachineFrameInfo &MFI,
2025+ const MachineRegisterInfo *MRI,
2026+ const X86InstrInfo *TII,
2027+ const CCValAssign &VA) {
2028+ unsigned Bytes = Arg.getValueSizeInBits () / 8 ;
2029+
2030+ for (;;) {
2031+ // Look through nodes that don't alter the bits of the incoming value.
2032+ unsigned Op = Arg.getOpcode ();
2033+ if (Op == ISD::ZERO_EXTEND || Op == ISD::ANY_EXTEND || Op == ISD::BITCAST ||
2034+ Op == ISD::AssertZext) {
2035+ Arg = Arg.getOperand (0 );
2036+ continue ;
2037+ }
2038+ if (Op == ISD::TRUNCATE) {
2039+ const SDValue &TruncInput = Arg.getOperand (0 );
2040+ if (TruncInput.getOpcode () == ISD::AssertZext &&
2041+ cast<VTSDNode>(TruncInput.getOperand (1 ))->getVT () ==
2042+ Arg.getValueType ()) {
2043+ Arg = TruncInput.getOperand (0 );
2044+ continue ;
2045+ }
2046+ }
2047+ break ;
2048+ }
2049+
2050+ int FI = INT_MAX;
2051+ if (Arg.getOpcode () == ISD::CopyFromReg) {
2052+ Register VR = cast<RegisterSDNode>(Arg.getOperand (1 ))->getReg ();
2053+ if (!VR.isVirtual ())
2054+ return false ;
2055+ MachineInstr *Def = MRI->getVRegDef (VR);
2056+ if (!Def)
2057+ return false ;
2058+ if (!Flags.isByVal ()) {
2059+ if (!TII->isLoadFromStackSlot (*Def, FI))
2060+ return false ;
2061+ } else {
2062+ unsigned Opcode = Def->getOpcode ();
2063+ if ((Opcode == X86::LEA32r || Opcode == X86::LEA64r ||
2064+ Opcode == X86::LEA64_32r) &&
2065+ Def->getOperand (1 ).isFI ()) {
2066+ FI = Def->getOperand (1 ).getIndex ();
2067+ Bytes = Flags.getByValSize ();
2068+ } else
2069+ return false ;
2070+ }
2071+ } else if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(Arg)) {
2072+ if (Flags.isByVal ())
2073+ // ByVal argument is passed in as a pointer but it's now being
2074+ // dereferenced. e.g.
2075+ // define @foo(%struct.X* %A) {
2076+ // tail call @bar(%struct.X* byval %A)
2077+ // }
2078+ return false ;
2079+ SDValue Ptr = Ld->getBasePtr ();
2080+ FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(Ptr);
2081+ if (!FINode)
2082+ return false ;
2083+ FI = FINode->getIndex ();
2084+ } else if (Arg.getOpcode () == ISD::FrameIndex && Flags.isByVal ()) {
2085+ FrameIndexSDNode *FINode = cast<FrameIndexSDNode>(Arg);
2086+ FI = FINode->getIndex ();
2087+ Bytes = Flags.getByValSize ();
2088+ } else
2089+ return false ;
2090+
2091+ assert (FI != INT_MAX);
2092+ if (!MFI.isFixedObjectIndex (FI))
2093+ return false ;
2094+
2095+ if (Offset != MFI.getObjectOffset (FI))
2096+ return false ;
2097+
2098+ // If this is not byval, check that the argument stack object is immutable.
2099+ // inalloca and argument copy elision can create mutable argument stack
2100+ // objects. Byval objects can be mutated, but a byval call intends to pass the
2101+ // mutated memory.
2102+ if (!Flags.isByVal () && !MFI.isImmutableObjectIndex (FI))
2103+ return false ;
2104+
2105+ if (VA.getLocVT ().getFixedSizeInBits () >
2106+ Arg.getValueSizeInBits ().getFixedValue ()) {
2107+ // If the argument location is wider than the argument type, check that any
2108+ // extension flags match.
2109+ if (Flags.isZExt () != MFI.isObjectZExt (FI) ||
2110+ Flags.isSExt () != MFI.isObjectSExt (FI)) {
2111+ return false ;
2112+ }
2113+ }
2114+
2115+ return Bytes == MFI.getObjectSize (FI);
2116+ }
2117+
20212118// Returns the type of copying which is required to set up a byval argument to
20222119// a tail-called function. This isn't needed for non-tail calls, because they
20232120// always need the equivalent of CopyOnce, but tail-calls sometimes need two to
@@ -2191,7 +2288,6 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
21912288
21922289 SDValue StackPtr;
21932290 const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo ();
2194- int RetAddrSize = 8 ;
21952291
21962292 // If we are doing a tail-call, any byval arguments will be written to stack
21972293 // space which was used for incoming arguments. If any the values being used
@@ -2530,8 +2626,6 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
25302626 NeedsStackCopy = !isTailCall;
25312627 }
25322628
2533- // FIXME: contrary to the arm backend, with the current logic we always
2534- // seem to need a stack copy.
25352629 if (NeedsStackCopy) {
25362630
25372631 auto PtrVT = getPointerTy (DAG.getDataLayout ());
@@ -2542,10 +2636,19 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
25422636 ByValSrc, DstAddr, Chain, Flags, DAG, dl));
25432637 }
25442638 } else {
2545- // Store relative to framepointer.
2546- MemOpChains2.push_back (DAG.getStore (
2547- Chain, dl, Arg, FIN,
2548- MachinePointerInfo::getFixedStack (DAG.getMachineFunction (), FI)));
2639+ // Check if the arguments are already laid out in the right way as
2640+ // the caller's fixed stack objects.
2641+ MachineFrameInfo &MFI = MF.getFrameInfo ();
2642+ const MachineRegisterInfo *MRI = &MF.getRegInfo ();
2643+ const X86InstrInfo *TII = Subtarget.getInstrInfo ();
2644+
2645+ if (!MatchingStackOffset (Arg, VA.getLocMemOffset (), Flags, MFI, MRI,
2646+ TII, VA)) {
2647+ // Store relative to framepointer.
2648+ MemOpChains2.push_back (DAG.getStore (
2649+ Chain, dl, Arg, FIN,
2650+ MachinePointerInfo::getFixedStack (DAG.getMachineFunction (), FI)));
2651+ }
25492652 }
25502653 }
25512654
@@ -2811,102 +2914,6 @@ X86TargetLowering::GetAlignedArgumentStackSize(const unsigned StackSize,
28112914 return alignTo (StackSize + SlotSize, StackAlignment) - SlotSize;
28122915}
28132916
2814- // / Return true if the given stack call argument is already available in the
2815- // / same position (relatively) of the caller's incoming argument stack.
2816- static
2817- bool MatchingStackOffset (SDValue Arg, unsigned Offset, ISD::ArgFlagsTy Flags,
2818- MachineFrameInfo &MFI, const MachineRegisterInfo *MRI,
2819- const X86InstrInfo *TII, const CCValAssign &VA) {
2820- unsigned Bytes = Arg.getValueSizeInBits () / 8 ;
2821-
2822- for (;;) {
2823- // Look through nodes that don't alter the bits of the incoming value.
2824- unsigned Op = Arg.getOpcode ();
2825- if (Op == ISD::ZERO_EXTEND || Op == ISD::ANY_EXTEND || Op == ISD::BITCAST ||
2826- Op == ISD::AssertZext) {
2827- Arg = Arg.getOperand (0 );
2828- continue ;
2829- }
2830- if (Op == ISD::TRUNCATE) {
2831- const SDValue &TruncInput = Arg.getOperand (0 );
2832- if (TruncInput.getOpcode () == ISD::AssertZext &&
2833- cast<VTSDNode>(TruncInput.getOperand (1 ))->getVT () ==
2834- Arg.getValueType ()) {
2835- Arg = TruncInput.getOperand (0 );
2836- continue ;
2837- }
2838- }
2839- break ;
2840- }
2841-
2842- int FI = INT_MAX;
2843- if (Arg.getOpcode () == ISD::CopyFromReg) {
2844- Register VR = cast<RegisterSDNode>(Arg.getOperand (1 ))->getReg ();
2845- if (!VR.isVirtual ())
2846- return false ;
2847- MachineInstr *Def = MRI->getVRegDef (VR);
2848- if (!Def)
2849- return false ;
2850- if (!Flags.isByVal ()) {
2851- if (!TII->isLoadFromStackSlot (*Def, FI))
2852- return false ;
2853- } else {
2854- unsigned Opcode = Def->getOpcode ();
2855- if ((Opcode == X86::LEA32r || Opcode == X86::LEA64r ||
2856- Opcode == X86::LEA64_32r) &&
2857- Def->getOperand (1 ).isFI ()) {
2858- FI = Def->getOperand (1 ).getIndex ();
2859- Bytes = Flags.getByValSize ();
2860- } else
2861- return false ;
2862- }
2863- } else if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(Arg)) {
2864- if (Flags.isByVal ())
2865- // ByVal argument is passed in as a pointer but it's now being
2866- // dereferenced. e.g.
2867- // define @foo(%struct.X* %A) {
2868- // tail call @bar(%struct.X* byval %A)
2869- // }
2870- return false ;
2871- SDValue Ptr = Ld->getBasePtr ();
2872- FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(Ptr);
2873- if (!FINode)
2874- return false ;
2875- FI = FINode->getIndex ();
2876- } else if (Arg.getOpcode () == ISD::FrameIndex && Flags.isByVal ()) {
2877- FrameIndexSDNode *FINode = cast<FrameIndexSDNode>(Arg);
2878- FI = FINode->getIndex ();
2879- Bytes = Flags.getByValSize ();
2880- } else
2881- return false ;
2882-
2883- assert (FI != INT_MAX);
2884- if (!MFI.isFixedObjectIndex (FI))
2885- return false ;
2886-
2887- if (Offset != MFI.getObjectOffset (FI))
2888- return false ;
2889-
2890- // If this is not byval, check that the argument stack object is immutable.
2891- // inalloca and argument copy elision can create mutable argument stack
2892- // objects. Byval objects can be mutated, but a byval call intends to pass the
2893- // mutated memory.
2894- if (!Flags.isByVal () && !MFI.isImmutableObjectIndex (FI))
2895- return false ;
2896-
2897- if (VA.getLocVT ().getFixedSizeInBits () >
2898- Arg.getValueSizeInBits ().getFixedValue ()) {
2899- // If the argument location is wider than the argument type, check that any
2900- // extension flags match.
2901- if (Flags.isZExt () != MFI.isObjectZExt (FI) ||
2902- Flags.isSExt () != MFI.isObjectSExt (FI)) {
2903- return false ;
2904- }
2905- }
2906-
2907- return Bytes == MFI.getObjectSize (FI);
2908- }
2909-
29102917static bool
29112918mayBeSRetTailCallCompatible (const TargetLowering::CallLoweringInfo &CLI,
29122919 Register CallerSRetReg) {
0 commit comments