From: Akira Hatanaka Date: Tue, 9 Jun 2015 19:07:19 +0000 (+0000) Subject: Remove DisableTailCalls from TargetOptions and the code in resetTargetOptions X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=0e3246a86f553aa6fae35d3bfb91de81dd66a18b;p=oota-llvm.git Remove DisableTailCalls from TargetOptions and the code in resetTargetOptions that was resetting it. Remove the uses of DisableTailCalls in subclasses of TargetLowering and use the value of function attribute "disable-tail-calls" instead. Also, unconditionally add pass TailCallElim to the pipeline and check the function attribute at the start of runOnFunction to disable the pass on a per-function basis. This is part of the work to remove TargetMachine::resetTargetOptions, and since DisableTailCalls was the last non-fast-math option that was being reset in that function, we should be able to remove the function entirely after the work to propagate IR-level fast-math flags to DAG nodes is completed. Out-of-tree users should remove the uses of DisableTailCalls and make changes to attach attribute "disable-tail-calls"="true" or "false" to the functions in the IR. rdar://problem/13752163 Differential Revision: http://reviews.llvm.org/D10099 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239427 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h index b824df3013d..c5183dc42b1 100644 --- a/include/llvm/CodeGen/CommandFlags.h +++ b/include/llvm/CodeGen/CommandFlags.h @@ -16,6 +16,7 @@ #ifndef LLVM_CODEGEN_COMMANDFLAGS_H #define LLVM_CODEGEN_COMMANDFLAGS_H +#include "llvm/ADT/StringExtras.h" #include "llvm/IR/Module.h" #include "llvm/MC/MCTargetOptionsCommandFlags.h" #include "llvm//MC/SubtargetFeature.h" @@ -247,7 +248,6 @@ static inline TargetOptions InitTargetOptionsFromCodeGenFlags() { Options.FloatABIType = FloatABIForCalls; Options.NoZerosInBSS = DontPlaceZerosInBSS; Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt; - Options.DisableTailCalls = DisableTailCalls; Options.StackAlignmentOverride = OverrideStackAlignment; Options.TrapFuncName = TrapFuncName; Options.PositionIndependentExecutable = EnablePIE; @@ -315,6 +315,11 @@ static inline void setFunctionAttributes(StringRef CPU, StringRef Features, "no-frame-pointer-elim", DisableFPElim ? "true" : "false"); + if (DisableTailCalls.getNumOccurrences() > 0) + NewAttrs = NewAttrs.addAttribute(Ctx, AttributeSet::FunctionIndex, + "disable-tail-calls", + toStringRef(DisableTailCalls)); + // Let NewAttrs override Attrs. NewAttrs = Attrs.addAttributes(Ctx, AttributeSet::FunctionIndex, NewAttrs); F.setAttributes(NewAttrs); diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index 8f8b78d9b0b..a4e0954129d 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -67,7 +67,7 @@ namespace llvm { HonorSignDependentRoundingFPMathOption(false), NoZerosInBSS(false), GuaranteedTailCallOpt(false), - DisableTailCalls(false), StackAlignmentOverride(0), + StackAlignmentOverride(0), EnableFastISel(false), PositionIndependentExecutable(false), UseInitArray(false), DisableIntegratedAS(false), CompressDebugSections(false), FunctionSections(false), @@ -137,10 +137,6 @@ namespace llvm { /// as their parent function, etc.), using an alternate ABI if necessary. unsigned GuaranteedTailCallOpt : 1; - /// DisableTailCalls - This flag controls whether we will use tail calls. - /// Disabling them may be useful to maintain a correct call stack. - unsigned DisableTailCalls : 1; - /// StackAlignmentOverride - Override default stack alignment for target. unsigned StackAlignmentOverride; @@ -236,7 +232,6 @@ inline bool operator==(const TargetOptions &LHS, ARE_EQUAL(HonorSignDependentRoundingFPMathOption) && ARE_EQUAL(NoZerosInBSS) && ARE_EQUAL(GuaranteedTailCallOpt) && - ARE_EQUAL(DisableTailCalls) && ARE_EQUAL(StackAlignmentOverride) && ARE_EQUAL(EnableFastISel) && ARE_EQUAL(PositionIndependentExecutable) && diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 47c8400a668..2cfbc39a05b 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -1483,9 +1483,10 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, bool isStructRet = (Outs.empty()) ? false : Outs[0].Flags.isSRet(); bool isThisReturn = false; bool isSibCall = false; + auto Attr = MF.getFunction()->getFnAttribute("disable-tail-calls"); // Disable tail calls if they're not supported. - if (!Subtarget->supportsTailCall() || MF.getTarget().Options.DisableTailCalls) + if (!Subtarget->supportsTailCall() || Attr.getValueAsString() == "true") isTailCall = false; if (isTailCall) { @@ -2375,7 +2376,9 @@ bool ARMTargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const { if (!Subtarget->supportsTailCall()) return false; - if (!CI->isTailCall() || getTargetMachine().Options.DisableTailCalls) + auto Attr = + CI->getParent()->getParent()->getFnAttribute("disable-tail-calls"); + if (!CI->isTailCall() || Attr.getValueAsString() == "true") return false; return !Subtarget->isThumb1Only(); diff --git a/lib/Target/Hexagon/HexagonISelLowering.cpp b/lib/Target/Hexagon/HexagonISelLowering.cpp index 74d92aef25a..6e9e69f5a2c 100644 --- a/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -397,7 +397,9 @@ HexagonTargetLowering::LowerReturn(SDValue Chain, bool HexagonTargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const { // If either no tail call or told not to tail call at all, don't. - if (!CI->isTailCall() || HTM.Options.DisableTailCalls) + auto Attr = + CI->getParent()->getParent()->getFnAttribute("disable-tail-calls"); + if (!CI->isTailCall() || Attr.getValueAsString() == "true") return false; return true; @@ -486,7 +488,8 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, else CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon); - if (DAG.getTarget().Options.DisableTailCalls) + auto Attr = MF.getFunction()->getFnAttribute("disable-tail-calls"); + if (Attr.getValueAsString() == "true") isTailCall = false; if (isTailCall) { diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp index 28242502ec8..04881264b4a 100644 --- a/lib/Target/TargetMachine.cpp +++ b/lib/Target/TargetMachine.cpp @@ -70,7 +70,6 @@ void TargetMachine::resetTargetOptions(const Function &F) const { RESET_OPTION(UnsafeFPMath, "unsafe-fp-math"); RESET_OPTION(NoInfsFPMath, "no-infs-fp-math"); RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math"); - RESET_OPTION(DisableTailCalls, "disable-tail-calls"); } /// getRelocationModel - Returns the code generation relocation model. The diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index e3ec288a683..88598a1ddd0 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -2233,7 +2233,9 @@ static bool IsCCallConvention(CallingConv::ID CC) { } bool X86TargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const { - if (!CI->isTailCall() || getTargetMachine().Options.DisableTailCalls) + auto Attr = + CI->getParent()->getParent()->getFnAttribute("disable-tail-calls"); + if (!CI->isTailCall() || Attr.getValueAsString() == "true") return false; CallSite CS(CI); @@ -2762,8 +2764,9 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, StructReturnType SR = callIsStructReturn(Outs); bool IsSibcall = false; X86MachineFunctionInfo *X86Info = MF.getInfo(); + auto Attr = MF.getFunction()->getFnAttribute("disable-tail-calls"); - if (MF.getTarget().Options.DisableTailCalls) + if (Attr.getValueAsString() == "true") isTailCall = false; if (Subtarget->isPICStyleGOT() && diff --git a/lib/Transforms/IPO/PassManagerBuilder.cpp b/lib/Transforms/IPO/PassManagerBuilder.cpp index 3496a663f53..963f1bb13aa 100644 --- a/lib/Transforms/IPO/PassManagerBuilder.cpp +++ b/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -94,7 +94,6 @@ PassManagerBuilder::PassManagerBuilder() { SizeLevel = 0; LibraryInfo = nullptr; Inliner = nullptr; - DisableTailCalls = false; DisableUnitAtATime = false; DisableUnrollLoops = false; BBVectorize = RunBBVectorization; @@ -238,8 +237,7 @@ void PassManagerBuilder::populateModulePassManager( MPM.add(createInstructionCombiningPass()); // Combine silly seq's addExtensionsToPM(EP_Peephole, MPM); - if (!DisableTailCalls) - MPM.add(createTailCallEliminationPass()); // Eliminate tail calls + MPM.add(createTailCallEliminationPass()); // Eliminate tail calls MPM.add(createCFGSimplificationPass()); // Merge & remove BBs MPM.add(createReassociatePass()); // Reassociate expressions // Rotate Loop - disable header duplication at -Oz diff --git a/lib/Transforms/Scalar/TailRecursionElimination.cpp b/lib/Transforms/Scalar/TailRecursionElimination.cpp index 9eef1327c3f..c7de2e2965c 100644 --- a/lib/Transforms/Scalar/TailRecursionElimination.cpp +++ b/lib/Transforms/Scalar/TailRecursionElimination.cpp @@ -158,6 +158,9 @@ bool TailCallElim::runOnFunction(Function &F) { if (skipOptnoneFunction(F)) return false; + if (F.getFnAttribute("disable-tail-calls").getValueAsString() == "true") + return false; + bool AllCallsAreTailCalls = false; bool Modified = markTails(F, AllCallsAreTailCalls); if (AllCallsAreTailCalls) diff --git a/test/CodeGen/ARM/disable-tail-calls.ll b/test/CodeGen/ARM/disable-tail-calls.ll new file mode 100644 index 00000000000..18aa4723fd3 --- /dev/null +++ b/test/CodeGen/ARM/disable-tail-calls.ll @@ -0,0 +1,40 @@ +; RUN: llc < %s -march arm | FileCheck %s --check-prefix=NO-OPTION +; RUN: llc < %s -march arm -disable-tail-calls | FileCheck %s --check-prefix=DISABLE-TRUE +; RUN: llc < %s -march arm -disable-tail-calls=false | FileCheck %s --check-prefix=DISABLE-FALSE + +; Check that command line option "-disable-tail-calls" overrides function +; attribute "disable-tail-calls". + +; NO-OPTION-LABEL: {{\_?}}func_attr +; NO-OPTION: bl {{\_?}}callee + +; DISABLE-FALSE-LABEL: {{\_?}}func_attr +; DISABLE-FALSE: b {{\_?}}callee + +; DISABLE-TRUE-LABEL: {{\_?}}func_attr +; DISABLE-TRUE: bl {{\_?}}callee + +define i32 @func_attr(i32 %a) #0 { +entry: + %call = tail call i32 @callee(i32 %a) + ret i32 %call +} + +; NO-OPTION-LABEL: {{\_?}}func_noattr +; NO-OPTION: b {{\_?}}callee + +; DISABLE-FALSE-LABEL: {{\_?}}func_noattr +; DISABLE-FALSE: b {{\_?}}callee + +; DISABLE-TRUE-LABEL: {{\_?}}func_noattr +; DISABLE-TRUE: bl {{\_?}}callee + +define i32 @func_noattr(i32 %a) { +entry: + %call = tail call i32 @callee(i32 %a) + ret i32 %call +} + +declare i32 @callee(i32) + +attributes #0 = { "disable-tail-calls"="true" } diff --git a/test/CodeGen/X86/disable-tail-calls.ll b/test/CodeGen/X86/disable-tail-calls.ll new file mode 100644 index 00000000000..80e8fd74e92 --- /dev/null +++ b/test/CodeGen/X86/disable-tail-calls.ll @@ -0,0 +1,40 @@ +; RUN: llc < %s -march x86-64 | FileCheck %s --check-prefix=NO-OPTION +; RUN: llc < %s -march x86-64 -disable-tail-calls | FileCheck %s --check-prefix=DISABLE-TRUE +; RUN: llc < %s -march x86-64 -disable-tail-calls=false | FileCheck %s --check-prefix=DISABLE-FALSE + +; Check that command line option "-disable-tail-calls" overrides function +; attribute "disable-tail-calls". + +; NO-OPTION-LABEL: {{\_?}}func_attr +; NO-OPTION: callq {{\_?}}callee + +; DISABLE-FALSE-LABEL: {{\_?}}func_attr +; DISABLE-FALSE: jmp {{\_?}}callee + +; DISABLE-TRUE-LABEL: {{\_?}}func_attr +; DISABLE-TRUE: callq {{\_?}}callee + +define i32 @func_attr(i32 %a) #0 { +entry: + %call = tail call i32 @callee(i32 %a) + ret i32 %call +} + +; NO-OPTION-LABEL: {{\_?}}func_noattr +; NO-OPTION: jmp {{\_?}}callee + +; DISABLE-FALSE-LABEL: {{\_?}}func_noattr +; DISABLE-FALSE: jmp {{\_?}}callee + +; DISABLE-TRUE-LABEL: {{\_?}}func_noattr +; DISABLE-TRUE: callq {{\_?}}callee + +define i32 @func_noattr(i32 %a) { +entry: + %call = tail call i32 @callee(i32 %a) + ret i32 %call +} + +declare i32 @callee(i32) + +attributes #0 = { "disable-tail-calls"="true" }