diff options
author | Reid Kleckner <rnk@google.com> | 2019-12-02 16:42:33 -0800 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2020-01-03 11:27:41 -0800 |
commit | 9c2b72821be64db7795dd18586c2ae7edb905c21 (patch) | |
tree | f80ab96f0c8ee84a36f5a08399f5ed73c2d07e9f | |
parent | e5a56f2d50ce1939eba4fddbeb9c8e032db4fc95 (diff) | |
download | bcm5719-llvm-9c2b72821be64db7795dd18586c2ae7edb905c21.tar.gz bcm5719-llvm-9c2b72821be64db7795dd18586c2ae7edb905c21.zip |
Move tail call disabling code to target independent code
When the "disable-tail-calls" attribute was added, checks were added for
it in various backends. Now this code has proliferated, and it is
something the target is responsible for checking. Move that
responsibility back to the ISels (fast, global, and SD).
There's no major functionality change, except for targets that never
implemented this check.
This LLVM attribute was originally added in
d9699bc7bdf0362173fcd256690f61a4d47429c2 (2015).
Reviewers: echristo, MaskRay
Differential Revision: https://reviews.llvm.org/D72118
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/CallLowering.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 22 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelLowering.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 8 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/tail-call.ll | 10 | ||||
-rw-r--r-- | llvm/test/CodeGen/RISCV/tail-calls.ll | 10 |
12 files changed, 54 insertions, 43 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp index cdad92f7db4..4c2dbdd905f 100644 --- a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp @@ -65,7 +65,11 @@ bool CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, ImmutableCallSite CS, Info.SwiftErrorVReg = SwiftErrorVReg; Info.IsMustTailCall = CS.isMustTailCall(); Info.IsTailCall = CS.isTailCall() && - isInTailCallPosition(CS, MIRBuilder.getMF().getTarget()); + isInTailCallPosition(CS, MIRBuilder.getMF().getTarget()) && + (MIRBuilder.getMF() + .getFunction() + .getFnAttribute("disable-tail-calls") + .getValueAsString() != "true"); Info.IsVarArg = CS.getFunctionType()->isVarArg(); return lowerCall(MIRBuilder, Info); } diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index 0d8a547a925..2bec8613e79 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1276,6 +1276,10 @@ bool FastISel::lowerCall(const CallInst *CI) { bool IsTailCall = CI->isTailCall(); if (IsTailCall && !isInTailCallPosition(CS, TM)) IsTailCall = false; + if (IsTailCall && MF->getFunction() + .getFnAttribute("disable-tail-calls") + .getValueAsString() == "true") + IsTailCall = false; CallLoweringInfo CLI; CLI.setCallee(RetTy, FuncTy, CI->getCalledValue(), std::move(Args), CS) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index e879df2f2d9..4fa007710da 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -7075,13 +7075,21 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee, const Value *SwiftErrorVal = nullptr; const TargetLowering &TLI = DAG.getTargetLoweringInfo(); - // We can't tail call inside a function with a swifterror argument. Lowering - // does not support this yet. It would have to move into the swifterror - // register before the call. - auto *Caller = CS.getInstruction()->getParent()->getParent(); - if (TLI.supportSwiftError() && - Caller->getAttributes().hasAttrSomewhere(Attribute::SwiftError)) - isTailCall = false; + if (isTailCall) { + // Avoid emitting tail calls in functions with the disable-tail-calls + // attribute. + auto *Caller = CS.getInstruction()->getParent()->getParent(); + if (Caller->getFnAttribute("disable-tail-calls").getValueAsString() == + "true") + isTailCall = false; + + // We can't tail call inside a function with a swifterror argument. Lowering + // does not support this yet. It would have to move into the swifterror + // register before the call. + if (TLI.supportSwiftError() && + Caller->getAttributes().hasAttrSomewhere(Attribute::SwiftError)) + isTailCall = false; + } for (ImmutableCallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end(); i != e; ++i) { diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 1049a897c6f..9d33c53dd4f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -52,6 +52,10 @@ bool TargetLowering::isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const { const Function &F = DAG.getMachineFunction().getFunction(); + // First, check if tail calls have been disabled in this function. + if (F.getFnAttribute("disable-tail-calls").getValueAsString() == "true") + return false; + // Conservatively require the attributes of the call to match those of // the return. Ignore NoAlias and NonNull because they don't affect the // call sequence. diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index 89c2d43c0bc..fccb1326fee 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -2671,9 +2671,7 @@ bool SITargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const { const Function *ParentFn = CI->getParent()->getParent(); if (AMDGPU::isEntryFunctionCC(ParentFn->getCallingConv())) return false; - - auto Attr = ParentFn->getFnAttribute("disable-tail-calls"); - return (Attr.getValueAsString() != "true"); + return true; } // The wave scratch offset register is used as the global base pointer. diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 9c5f663a9cc..714ce069483 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -2094,11 +2094,10 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, MachineFunction::CallSiteInfo CSInfo; bool isStructRet = (Outs.empty()) ? false : Outs[0].Flags.isSRet(); bool isThisReturn = false; - auto Attr = MF.getFunction().getFnAttribute("disable-tail-calls"); bool PreferIndirect = false; // Disable tail calls if they're not supported. - if (!Subtarget->supportsTailCall() || Attr.getValueAsString() == "true") + if (!Subtarget->supportsTailCall()) isTailCall = false; if (isa<GlobalAddressSDNode>(Callee)) { @@ -2975,9 +2974,7 @@ bool ARMTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const { if (!Subtarget->supportsTailCall()) return false; - auto Attr = - CI->getParent()->getParent()->getFnAttribute("disable-tail-calls"); - if (!CI->isTailCall() || Attr.getValueAsString() == "true") + if (!CI->isTailCall()) return false; return true; diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp index fb78fb48ebf..af1d4cb2bc9 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -233,12 +233,7 @@ HexagonTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool HexagonTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const { // If either no tail call or told not to tail call at all, don't. - auto Attr = - CI->getParent()->getParent()->getFnAttribute("disable-tail-calls"); - if (!CI->isTailCall() || Attr.getValueAsString() == "true") - return false; - - return true; + return CI->isTailCall(); } Register HexagonTargetLowering::getRegisterByName( @@ -408,10 +403,6 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, else CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon); - auto Attr = MF.getFunction().getFnAttribute("disable-tail-calls"); - if (Attr.getValueAsString() == "true") - CLI.IsTailCall = false; - if (CLI.IsTailCall) { bool StructAttrFlag = MF.getFunction().hasStructRetAttr(); CLI.IsTailCall = IsEligibleForTailCallOptimization(Callee, CallConv, diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index e43acb69493..cebbd880569 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -15640,12 +15640,6 @@ bool PPCTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const { if (!CI->isTailCall()) return false; - // If tail calls are disabled for the caller then we are done. - const Function *Caller = CI->getParent()->getParent(); - auto Attr = Caller->getFnAttribute("disable-tail-calls"); - if (Attr.getValueAsString() == "true") - return false; - // If sibling calls have been disabled and tail-calls aren't guaranteed // there is no reason to duplicate. auto &TM = getTargetMachine(); @@ -15658,6 +15652,7 @@ bool PPCTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const { return false; // Make sure the callee and caller calling conventions are eligible for tco. + const Function *Caller = CI->getParent()->getParent(); if (!areCallingConvEligibleForTCO_64SVR4(Caller->getCallingConv(), CI->getCallingConv())) return false; diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index e0eaf85503e..db3836a325c 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -2016,10 +2016,6 @@ bool RISCVTargetLowering::isEligibleForTailCallOptimization( auto &Caller = MF.getFunction(); auto CallerCC = Caller.getCallingConv(); - // Do not tail call opt functions with "disable-tail-calls" attribute. - if (Caller.getFnAttribute("disable-tail-calls").getValueAsString() == "true") - return false; - // Exception-handling functions need a special set of instructions to // indicate a return to the hardware. Tail-calling another function would // probably break this. diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index d58c7e95caa..492c7d4894b 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -3161,9 +3161,7 @@ static bool shouldGuaranteeTCO(CallingConv::ID CC, bool GuaranteedTailCallOpt) { } bool X86TargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const { - auto Attr = - CI->getParent()->getParent()->getFnAttribute("disable-tail-calls"); - if (!CI->isTailCall() || Attr.getValueAsString() == "true") + if (!CI->isTailCall()) return false; ImmutableCallSite CS(CI); @@ -3786,7 +3784,6 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, bool IsGuaranteeTCO = MF.getTarget().Options.GuaranteedTailCallOpt || CallConv == CallingConv::Tail; X86MachineFunctionInfo *X86Info = MF.getInfo<X86MachineFunctionInfo>(); - auto Attr = MF.getFunction().getFnAttribute("disable-tail-calls"); const auto *CI = dyn_cast_or_null<CallInst>(CLI.CS.getInstruction()); const Function *Fn = CI ? CI->getCalledFunction() : nullptr; bool HasNCSR = (CI && CI->hasFnAttr("no_caller_saved_registers")) || @@ -3802,9 +3799,6 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, if (CallConv == CallingConv::X86_INTR) report_fatal_error("X86 interrupts may not be called directly"); - if (Attr.getValueAsString() == "true") - isTailCall = false; - if (Subtarget.isPICStyleGOT() && !IsGuaranteeTCO) { // If we are using a GOT, disable tail calls to external symbols with // default visibility. Tail calling such a symbol requires using a GOT diff --git a/llvm/test/CodeGen/AArch64/tail-call.ll b/llvm/test/CodeGen/AArch64/tail-call.ll index f1c5daf86c9..39a9a711871 100644 --- a/llvm/test/CodeGen/AArch64/tail-call.ll +++ b/llvm/test/CodeGen/AArch64/tail-call.ll @@ -93,6 +93,16 @@ define fastcc void @caller_to16_from16([8 x i64], i64 %a, i64 %b) { ; COMMON-NEXT: b callee_stack16 } +define fastcc void @disable_tail_calls() nounwind "disable-tail-calls"="true" { +; COMMON-LABEL: disable_tail_calls: +; COMMON-NEXT: // %bb. + + tail call fastcc void @callee_stack0() + ret void + +; COMMON: bl callee_stack0 +; COMMON: ret +} ; Weakly-referenced extern functions cannot be tail-called, as AAELF does ; not define the behaviour of branch instructions to undefined weak symbols. diff --git a/llvm/test/CodeGen/RISCV/tail-calls.ll b/llvm/test/CodeGen/RISCV/tail-calls.ll index 30e530b5116..14af16ed3c8 100644 --- a/llvm/test/CodeGen/RISCV/tail-calls.ll +++ b/llvm/test/CodeGen/RISCV/tail-calls.ll @@ -158,6 +158,16 @@ entry: ret void } +; Do not tail call optimize if disabled. +define i32 @disable_tail_calls(i32 %i) nounwind "disable-tail-calls"="true" { +; CHECK-LABEL: disable_tail_calls: +; CHECK-NOT: tail callee_nostruct +; CHECK: call callee_tail +entry: + %rv = tail call i32 @callee_tail(i32 %i) + ret i32 %rv +} + !llvm.module.flags = !{!0} !0 = !{i32 1, !"ProfileSummary", !1} !1 = !{!2, !3, !4, !5, !6, !7, !8, !9} |