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 | 3ac52b3e43d02af9f72ff18fab10717f70077dd5 (patch) | |
| tree | 26390b5775339e125b13d1217ceec2c8839eaafb /llvm/lib | |
| parent | 819f27e760801525af23c5bb64ac26421301ccfb (diff) | |
| download | bcm5719-llvm-3ac52b3e43d02af9f72ff18fab10717f70077dd5.tar.gz bcm5719-llvm-3ac52b3e43d02af9f72ff18fab10717f70077dd5.zip | |
Last round of changes for ARM tail calls.
Not turning them on yet.
llvm-svn: 106295
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 21 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrInfo.td | 4 |
2 files changed, 16 insertions, 9 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 5ec995f771c..50258c6f85e 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/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/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index 052104d0533..d95137ae900 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/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), |

