diff options
author | Dale Johannesen <dalej@apple.com> | 2010-06-18 18:13:11 +0000 |
---|---|---|
committer | Dale Johannesen <dalej@apple.com> | 2010-06-18 18:13:11 +0000 |
commit | df50d7e238c4802eb2de04646b8f7ff7327730a0 (patch) | |
tree | d4ee7d711ec2796fa2ccdd5cb6a6d08aaa854f29 | |
parent | 2bff8abbf2c02065556332d50c4e4cf86a09034d (diff) |
Last round of changes for ARM tail calls.
Not turning them on yet.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106295 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 21 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 4 |
2 files changed, 16 insertions, 9 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 5ec995f771..50258c6f85 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -1101,7 +1101,7 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee, } } else if (VA.isRegLoc()) { RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); - } else { + } else if (!IsSibCall) { assert(VA.isMemLoc()); MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, Arg, @@ -1357,12 +1357,6 @@ ARMTargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, // Look for obvious safe cases to perform tail call optimization that do not // require ABI changes. This is what gcc calls sibcall. - // Can't do sibcall if stack needs to be dynamically re-aligned. PEI needs to - // emit a special epilogue. - // Not sure yet if this is true on ARM. -//?? if (RegInfo->needsStackRealignment(MF)) -//?? return false; - // Do not sibcall optimize vararg calls unless the call site is not passing // any arguments. if (isVarArg && !Outs.empty()) @@ -1373,6 +1367,19 @@ ARMTargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, if (isCalleeStructRet || isCallerStructRet) return false; + // On Thumb, for the moment, we can only do this to functions defined in this + // compilation, or to indirect calls. A Thumb B to an ARM function is not + // easily fixed up in the linker, unlike BL. + if (Subtarget->isThumb()) { + if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { + const GlobalValue *GV = G->getGlobal(); + if (GV->isDeclaration() || GV->isWeakForLinker()) + return false; + } else if (isa<ExternalSymbolSDNode>(Callee)) { + return false; + } + } + // If the calling conventions do not match, then we'd better make sure the // results are returned in the same way as what the caller expects. if (!CCMatch) { diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 052104d053..d95137ae90 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -1049,7 +1049,7 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in { "@TC_RETURN","\t$dst", []>, Requires<[IsDarwin]>; def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops), - IIC_Br, "b\t$dst @ TAILCALL", + IIC_Br, "b.w\t$dst @ TAILCALL", []>, Requires<[IsDarwin]>; def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops), @@ -1084,7 +1084,7 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in { "@TC_RETURN","\t$dst", []>, Requires<[IsNotDarwin]>; def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops), - IIC_Br, "b\t$dst @ TAILCALL", + IIC_Br, "b.w\t$dst @ TAILCALL", []>, Requires<[IsNotDarwin]>; def TAILJMPrND : AXI<(outs), (ins tGPR:$dst, variable_ops), |