Skip to content

Commit d776d4e

Browse files
committed
implement tail call
1 parent 92e5060 commit d776d4e

File tree

5 files changed

+51
-10
lines changed

5 files changed

+51
-10
lines changed

llvm/lib/Target/PowerPC/PPCFrameLowering.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1935,6 +1935,9 @@ void PPCFrameLowering::createTailCallBranchInstr(MachineBasicBlock &MBB) const {
19351935
else if (JumpTarget.isSymbol())
19361936
BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)).
19371937
addExternalSymbol(JumpTarget.getSymbolName());
1938+
else if (JumpTarget.isMCSymbol())
1939+
BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB))
1940+
.addSym(JumpTarget.getMCSymbol());
19381941
else
19391942
llvm_unreachable("Expecting Global or External Symbol");
19401943
} else if (RetOpcode == PPC::TCRETURNri) {
@@ -1954,6 +1957,9 @@ void PPCFrameLowering::createTailCallBranchInstr(MachineBasicBlock &MBB) const {
19541957
else if (JumpTarget.isSymbol())
19551958
BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)).
19561959
addExternalSymbol(JumpTarget.getSymbolName());
1960+
else if (JumpTarget.isMCSymbol())
1961+
BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8))
1962+
.addSym(JumpTarget.getMCSymbol());
19571963
else
19581964
llvm_unreachable("Expecting Global or External Symbol");
19591965
} else if (RetOpcode == PPC::TCRETURNri8) {

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

llvm/lib/Target/PowerPC/PPCInstr64Bit.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,8 @@ def : Pat<(PPCtc_return (i64 texternalsym:$dst), imm:$imm),
474474
def : Pat<(PPCtc_return CTRRC8:$dst, imm:$imm),
475475
(TCRETURNri8 CTRRC8:$dst, imm:$imm)>;
476476

477+
def : Pat<(PPCtc_return (i64 mcsym:$dst), imm:$imm),
478+
(TCRETURNdi8 mcsym:$dst, imm:$imm)>;
477479

478480
// 64-bit CR instructions
479481
let Interpretation64Bit = 1, isCodeGenOnly = 1 in {

llvm/lib/Target/PowerPC/PPCInstrInfo.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3155,6 +3155,10 @@ def : Pat<(PPCtc_return CTRRC:$dst, imm:$imm),
31553155
(TCRETURNri CTRRC:$dst, imm:$imm)>;
31563156

31573157
def : Pat<(int_ppc_fence), (FENCE)>;
3158+
3159+
def : Pat<(PPCtc_return (i32 mcsym:$dst), imm:$imm),
3160+
(TCRETURNdi mcsym:$dst, imm:$imm)>;
3161+
31583162
def : Pat<(int_ppc_readflm), (MFFS)>;
31593163
def : Pat<(int_ppc_mffsl), (MFFSL)>;
31603164

llvm/test/CodeGen/PowerPC/ppc64-sibcall-shrinkwrap.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ exit:
3636
; CHECK-SCO-SR: stdu 1, -{{[0-9]+}}(1)
3737
; CHECK-SCO-SR: bl __assert_fail
3838

39-
; CHECK-AIX: LLVM ERROR: Tail call support is unimplemented on AIX.
39+
; CHECK-AIX: LLVM ERROR: Tail call support for non-fastcc calling convention is unimplemented on AIX.
4040
}
4141

4242
define dso_local fastcc i8 @LVComputationKind(

0 commit comments

Comments
 (0)