@@ -5082,9 +5082,8 @@ static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB) {
50825082
50835083// Returns true if TCO is possible between the callers and callees
50845084// calling conventions.
5085- static bool
5086- areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC,
5087- CallingConv::ID CalleeCC) {
5085+ static bool areCallingConvEligibleForTCO(CallingConv::ID CallerCC,
5086+ CallingConv::ID CalleeCC) {
50885087 // Tail calls are possible with fastcc and ccc.
50895088 auto isTailCallableCC = [] (CallingConv::ID CC){
50905089 return CC == CallingConv::C || CC == CallingConv::Fast;
@@ -5113,7 +5112,7 @@ bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
51135112 if (isVarArg) return false;
51145113
51155114 // Check that the calling conventions are compatible for tco.
5116- if (!areCallingConvEligibleForTCO_64SVR4 (CallerCC, CalleeCC))
5115+ if (!areCallingConvEligibleForTCO (CallerCC, CalleeCC))
51175116 return false;
51185117
51195118 // Caller contains any byval parameter is not supported.
@@ -5183,6 +5182,110 @@ bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
51835182 return true;
51845183}
51855184
5185+ static bool
5186+ needStackSlotPassParameters_AIX(const PPCSubtarget &Subtarget,
5187+ const SmallVectorImpl<ISD::OutputArg> &Outs) {
5188+ const bool IsPPC64 = Subtarget.isPPC64();
5189+ const Align PtrAlign = IsPPC64 ? Align(8) : Align(4);
5190+ const unsigned PhyGPRsNum = 8;
5191+ const unsigned PhyVRsNum = 12;
5192+ unsigned PhyGPRAllocated = 0;
5193+ unsigned PhyVRAllocated = 0;
5194+
5195+ for (unsigned i = 0; i != Outs.size(); ++i) {
5196+ MVT ArgVT = Outs[i].VT;
5197+ ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
5198+ if (ArgFlags.isByVal()) {
5199+ const unsigned ByValSize = ArgFlags.getByValSize();
5200+ const unsigned StackSize = alignTo(ByValSize, PtrAlign);
5201+ PhyGPRAllocated += StackSize / PtrAlign.value();
5202+ if (PhyGPRAllocated > PhyGPRsNum)
5203+ return true;
5204+ continue;
5205+ }
5206+
5207+ switch (ArgVT.SimpleTy) {
5208+ default:
5209+ report_fatal_error("Unhandled value type for argument.");
5210+ case MVT::i64:
5211+ // i64 arguments should have been split to i32 for PPC32.
5212+ assert(IsPPC64 && "PPC32 should have split i64 values.");
5213+ [[fallthrough]];
5214+ case MVT::i1:
5215+ case MVT::i32:
5216+ if (++PhyGPRAllocated > PhyGPRsNum)
5217+ return true;
5218+ break;
5219+ case MVT::f32:
5220+ case MVT::f64: {
5221+ const unsigned StoreSize = ArgVT.getStoreSize();
5222+ PhyGPRAllocated += StoreSize / PtrAlign.value();
5223+ if (PhyGPRAllocated > PhyGPRsNum)
5224+ return true;
5225+ break;
5226+ }
5227+ case MVT::v4f32:
5228+ case MVT::v4i32:
5229+ case MVT::v8i16:
5230+ case MVT::v16i8:
5231+ case MVT::v2i64:
5232+ case MVT::v2f64:
5233+ case MVT::v1i128:
5234+ if (++PhyVRAllocated > PhyVRsNum)
5235+ return true;
5236+ }
5237+ }
5238+
5239+ return false;
5240+ }
5241+
5242+ bool PPCTargetLowering::IsEligibleForTailCallOptimization_AIX(
5243+ const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
5244+ CallingConv::ID CallerCC, const CallBase *CB, bool isVarArg,
5245+ const SmallVectorImpl<ISD::OutputArg> &Outs, const Function *CallerFunc,
5246+ bool isCalleeExternalSymbol) const {
5247+ bool TailCallOpt = getTargetMachine().Options.GuaranteedTailCallOpt;
5248+
5249+ if (DisableSCO && !TailCallOpt)
5250+ return false;
5251+
5252+ // Variadic argument functions are not supported.
5253+ if (isVarArg)
5254+ return false;
5255+
5256+ // Check that the calling conventions are compatible for tco.
5257+ if (!areCallingConvEligibleForTCO(CallerCC, CalleeCC))
5258+ return false;
5259+
5260+ if (!Subtarget.isUsingPCRelativeCalls() &&
5261+ !isFunctionGlobalAddress(CalleeGV) && !isCalleeExternalSymbol)
5262+ return false;
5263+
5264+ // TCO allows altering callee ABI, so we don't have to check further.
5265+ if (CalleeCC == CallingConv::Fast && TailCallOpt)
5266+ return true;
5267+
5268+ if (DisableSCO)
5269+ return false;
5270+
5271+ if (CallerCC != CalleeCC && needStackSlotPassParameters_AIX(Subtarget, Outs))
5272+ return false;
5273+
5274+ // If callee use the same argument list that caller is using, then we can
5275+ // apply SCO on this case. If it is not, then we need to check if callee needs
5276+ // stack for passing arguments.
5277+ // PC Relative tail calls may not have a CallBase.
5278+ // If there is no CallBase we cannot verify if we have the same argument
5279+ // list so assume that we don't have the same argument list.
5280+ if (CB && !hasSameArgumentList(CallerFunc, *CB) &&
5281+ needStackSlotPassParameters_AIX(Subtarget, Outs))
5282+ return false;
5283+ else if (!CB && needStackSlotPassParameters_AIX(Subtarget, Outs))
5284+ return false;
5285+
5286+ return true;
5287+ }
5288+
51865289/// IsEligibleForTailCallOptimization - Check whether the call is eligible
51875290/// for tail call optimization. Targets which want to do tail call
51885291/// optimization should implement this function.
@@ -5943,9 +6046,14 @@ bool PPCTargetLowering::isEligibleForTCO(
59436046 return IsEligibleForTailCallOptimization_64SVR4(
59446047 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
59456048 isCalleeExternalSymbol);
5946- else
5947- return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5948- isVarArg, Ins);
6049+
6050+ else if (Subtarget.isAIXABI())
6051+ return IsEligibleForTailCallOptimization_AIX(CalleeGV, CalleeCC, CallerCC,
6052+ CB, isVarArg, Outs, CallerFunc,
6053+ isCalleeExternalSymbol);
6054+
6055+ return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
6056+ isVarArg, Ins);
59496057}
59506058
59516059SDValue
@@ -7251,11 +7359,6 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
72517359 CallConv == CallingConv::Fast) &&
72527360 "Unexpected calling convention!");
72537361
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.");
7258-
72597362 if (useSoftFloat())
72607363 report_fatal_error("Soft float support is unimplemented on AIX.");
72617364
@@ -7641,8 +7744,11 @@ SDValue PPCTargetLowering::LowerCall_AIX(
76417744 const unsigned NumBytes = std::max<unsigned>(
76427745 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
76437746
7644- int SPDiff =
7645- IsSibCall ? 0 : CalculateTailCallSPDiff(DAG, CFlags.IsTailCall, NumBytes);
7747+ unsigned AlignNumBytes =
7748+ EnsureStackAlignment(Subtarget.getFrameLowering(), NumBytes);
7749+ int SPDiff = IsSibCall ? 0
7750+ : CalculateTailCallSPDiff(DAG, CFlags.IsTailCall,
7751+ AlignNumBytes);
76467752
76477753 // To protect arguments on the stack from being clobbered in a tail call,
76487754 // force all the loads to happen before doing any other lowering.
@@ -7928,11 +8034,11 @@ SDValue PPCTargetLowering::LowerCall_AIX(
79288034 Chain = DAG.getCopyToReg(Chain, dl, Reg.first, Reg.second, InGlue);
79298035 InGlue = Chain.getValue(1);
79308036 }
7931-
7932- if (CFlags.IsTailCall && !IsSibCall)
7933- PrepareTailCall(DAG, InGlue, Chain, dl, SPDiff, NumBytes, LROp, FPOp,
7934- TailCallArguments);
7935-
8037+ /*
8038+ if (CFlags.IsTailCall && !IsSibCall)
8039+ PrepareTailCall(DAG, InGlue, Chain, dl, SPDiff, NumBytes, LROp, FPOp,
8040+ TailCallArguments);
8041+ */
79368042 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
79378043 Callee, SPDiff, NumBytes, Ins, InVals, CB);
79388044}
@@ -19271,9 +19377,9 @@ bool PPCTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
1927119377
1927219378 // Make sure the callee and caller calling conventions are eligible for tco.
1927319379 const Function *Caller = CI->getParent()->getParent();
19274- if (!areCallingConvEligibleForTCO_64SVR4 (Caller->getCallingConv(),
19275- CI->getCallingConv()))
19276- return false;
19380+ if (!areCallingConvEligibleForTCO (Caller->getCallingConv(),
19381+ CI->getCallingConv()))
19382+ return false;
1927719383
1927819384 // If the function is local then we have a good chance at tail-calling it
1927919385 return getTargetMachine().shouldAssumeDSOLocal(Callee);
0 commit comments