diff options
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 4 | ||||
-rw-r--r-- | lib/Target/ARM/ARMSubtarget.cpp | 3 | ||||
-rw-r--r-- | lib/Target/ARM/ARMSubtarget.h | 6 | ||||
-rw-r--r-- | test/CodeGen/ARM/call-tc.ll | 4 |
4 files changed, 15 insertions, 2 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index c352b46571..6386c4d0d8 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -1222,8 +1222,8 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee, MachineFunction &MF = DAG.getMachineFunction(); bool IsStructRet = (Outs.empty()) ? false : Outs[0].Flags.isSRet(); bool IsSibCall = false; - // Temporarily disable tail calls so things don't break. - if (!EnableARMTailCalls) + // Disable tail calls if they're not supported. + if (!EnableARMTailCalls && !Subtarget->supportsTailCall()) isTailCall = false; if (isTailCall) { // Check if it's really possible to do a tail call. diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp index 82e542281e..247d6be59a 100644 --- a/lib/Target/ARM/ARMSubtarget.cpp +++ b/lib/Target/ARM/ARMSubtarget.cpp @@ -60,6 +60,7 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU, , PostRAScheduler(false) , IsR9Reserved(ReserveR9) , UseMovt(false) + , SupportsTailCall(false) , HasFP16(false) , HasD16(false) , HasHardwareDivide(false) @@ -113,6 +114,8 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU, else { IsR9Reserved = ReserveR9 | !HasV6Ops; UseMovt = DarwinUseMOVT && hasV6T2Ops(); + const Triple &T = getTargetTriple(); + SupportsTailCall = T.getOS() == Triple::IOS && !T.isOSVersionLT(5, 0); } if (!isThumb() || hasThumb2()) diff --git a/lib/Target/ARM/ARMSubtarget.h b/lib/Target/ARM/ARMSubtarget.h index 47e076a7f1..b63e1085fb 100644 --- a/lib/Target/ARM/ARMSubtarget.h +++ b/lib/Target/ARM/ARMSubtarget.h @@ -93,6 +93,11 @@ protected: /// imms (including global addresses). bool UseMovt; + /// SupportsTailCall - True if the OS supports tail call. The dynamic linker + /// must be able to synthesize call stubs for interworking between ARM and + /// Thumb. + bool SupportsTailCall; + /// HasFP16 - True if subtarget supports half-precision FP (We support VFP+HF /// only so far) bool HasFP16; @@ -234,6 +239,7 @@ protected: bool isR9Reserved() const { return IsR9Reserved; } bool useMovt() const { return UseMovt && hasV6T2Ops(); } + bool supportsTailCall() const { return SupportsTailCall; } bool allowsUnalignedMem() const { return AllowsUnalignedMem; } diff --git a/test/CodeGen/ARM/call-tc.ll b/test/CodeGen/ARM/call-tc.ll index e01750be81..f78d9980be 100644 --- a/test/CodeGen/ARM/call-tc.ll +++ b/test/CodeGen/ARM/call-tc.ll @@ -1,6 +1,10 @@ ; RUN: llc < %s -mtriple=armv6-apple-darwin -mattr=+vfp2 -arm-tail-calls | FileCheck %s -check-prefix=CHECKV6 ; RUN: llc < %s -mtriple=armv6-linux-gnueabi -relocation-model=pic -mattr=+vfp2 -arm-tail-calls | FileCheck %s -check-prefix=CHECKELF ; RUN: llc < %s -mtriple=thumbv7-apple-darwin -arm-tail-calls | FileCheck %s -check-prefix=CHECKT2D +; RUN: llc < %s -mtriple=thumbv7-apple-ios5.0 | FileCheck %s -check-prefix=CHECKT2D + +; Enable tailcall optimization for iOS 5.0 +; rdar://9120031 @t = weak global i32 ()* null ; <i32 ()**> [#uses=1] |