@@ -5190,7 +5190,13 @@ bool PPCTargetLowering::IsEligibleForTailCallOptimization(
51905190 const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
51915191 CallingConv::ID CallerCC, bool isVarArg,
51925192 const SmallVectorImpl<ISD::InputArg> &Ins) const {
5193- if (!getTargetMachine().Options.GuaranteedTailCallOpt)
5193+ bool TailCallOpt = getTargetMachine().Options.GuaranteedTailCallOpt;
5194+
5195+ // Enable SCO on AIX.
5196+ if (!TailCallOpt && !Subtarget.isAIXABI())
5197+ return false;
5198+
5199+ if (DisableSCO)
51945200 return false;
51955201
51965202 // Variable argument functions are not supported.
@@ -5869,6 +5875,7 @@ SDValue PPCTargetLowering::FinishCall(
58695875 Callee.getOpcode() == ISD::TargetExternalSymbol ||
58705876 Callee.getOpcode() == ISD::TargetGlobalAddress ||
58715877 isa<ConstantSDNode>(Callee) ||
5878+ (Subtarget.isAIXABI() && Callee.getOpcode() == ISD::MCSymbol) ||
58725879 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
58735880 "Expecting a global address, external symbol, absolute value, "
58745881 "register or an indirect tail call when PC Relative calls are "
@@ -7244,8 +7251,10 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
72447251 CallConv == CallingConv::Fast) &&
72457252 "Unexpected calling convention!");
72467253
7247- if (getTargetMachine().Options.GuaranteedTailCallOpt)
7248- report_fatal_error("Tail call support is unimplemented on AIX.");
7254+ if (getTargetMachine().Options.GuaranteedTailCallOpt &&
7255+ CallConv != CallingConv::Fast)
7256+ report_fatal_error("Tail call support for non-fastcc calling convention is "
7257+ "unimplemented on AIX.");
72497258
72507259 if (useSoftFloat())
72517260 report_fatal_error("Soft float support is unimplemented on AIX.");
@@ -7254,6 +7263,9 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
72547263
72557264 const bool IsPPC64 = Subtarget.isPPC64();
72567265 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7266+ // Potential tail calls could cause overwriting of argument stack slots.
7267+ const bool IsImmutable = !(getTargetMachine().Options.GuaranteedTailCallOpt &&
7268+ (CallConv == CallingConv::Fast));
72577269
72587270 // Assign locations to all of the incoming arguments.
72597271 SmallVector<CCValAssign, 16> ArgLocs;
@@ -7319,10 +7331,6 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
73197331 // Objects are right-justified because AIX is big-endian.
73207332 if (LocSize > ValSize)
73217333 CurArgOffset += LocSize - ValSize;
7322- // Potential tail calls could cause overwriting of argument stack slots.
7323- const bool IsImmutable =
7324- !(getTargetMachine().Options.GuaranteedTailCallOpt &&
7325- (CallConv == CallingConv::Fast));
73267334 int FI = MFI.CreateFixedObject(ValSize, CurArgOffset, IsImmutable);
73277335 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
73287336 SDValue ArgValue =
@@ -7616,6 +7624,8 @@ SDValue PPCTargetLowering::LowerCall_AIX(
76167624 // The LSA is 24 bytes (6x4) in PPC32 and 48 bytes (6x8) in PPC64.
76177625 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
76187626 const bool IsPPC64 = Subtarget.isPPC64();
7627+ bool IsSibCall =
7628+ CFlags.IsTailCall && !getTargetMachine().Options.GuaranteedTailCallOpt;
76197629 const EVT PtrVT = getPointerTy(DAG.getDataLayout());
76207630 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
76217631 CCInfo.AllocateStack(LinkageSize, Align(PtrByteSize));
@@ -7631,13 +7641,25 @@ SDValue PPCTargetLowering::LowerCall_AIX(
76317641 const unsigned NumBytes = std::max<unsigned>(
76327642 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
76337643
7644+ int SPDiff =
7645+ IsSibCall ? 0 : CalculateTailCallSPDiff(DAG, CFlags.IsTailCall, NumBytes);
7646+
7647+ // To protect arguments on the stack from being clobbered in a tail call,
7648+ // force all the loads to happen before doing any other lowering.
7649+ if (CFlags.IsTailCall)
7650+ Chain = DAG.getStackArgumentTokenFactor(Chain);
7651+
76347652 // Adjust the stack pointer for the new arguments...
76357653 // These operations are automatically eliminated by the prolog/epilog pass.
7636- Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl);
7654+ if (!IsSibCall)
7655+ Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl);
76377656 SDValue CallSeqStart = Chain;
7657+ SDValue LROp, FPOp;
7658+ Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
76387659
76397660 SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
76407661 SmallVector<SDValue, 8> MemOpChains;
7662+ SmallVector<TailCallArgumentInfo, 8> TailCallArguments;
76417663
76427664 // Set up a copy of the stack pointer for loading and storing any
76437665 // arguments that may not fit in the registers available for argument
@@ -7814,13 +7836,17 @@ SDValue PPCTargetLowering::LowerCall_AIX(
78147836 }
78157837
78167838 if (VA.isMemLoc()) {
7839+ if (!CFlags.IsTailCall) {
78177840 SDValue PtrOff =
78187841 DAG.getConstant(VA.getLocMemOffset(), dl, StackPtr.getValueType());
78197842 PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
78207843 MemOpChains.push_back(
78217844 DAG.getStore(Chain, dl, Arg, PtrOff,
78227845 MachinePointerInfo::getStack(MF, VA.getLocMemOffset()),
78237846 Subtarget.getFrameLowering()->getStackAlign()));
7847+ } else
7848+ CalculateTailCallArgDest(DAG, MF, false, Arg, SPDiff,
7849+ VA.getLocMemOffset(), TailCallArguments);
78247850
78257851 continue;
78267852 }
@@ -7903,7 +7929,10 @@ SDValue PPCTargetLowering::LowerCall_AIX(
79037929 InGlue = Chain.getValue(1);
79047930 }
79057931
7906- const int SPDiff = 0;
7932+ if (CFlags.IsTailCall && !IsSibCall)
7933+ PrepareTailCall(DAG, InGlue, Chain, dl, SPDiff, NumBytes, LROp, FPOp,
7934+ TailCallArguments);
7935+
79077936 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
79087937 Callee, SPDiff, NumBytes, Ins, InVals, CB);
79097938}
0 commit comments