ARM: honour -f{no-,}optimize-sibling-calls
authorSaleem Abdulrasool <compnerd@compnerd.org>
Tue, 11 Mar 2014 15:09:54 +0000 (15:09 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Tue, 11 Mar 2014 15:09:54 +0000 (15:09 +0000)
Use the options in the ARMISelLowering to control whether tail calls are
optimised or not.  Previously, this option was entirely ignored on the ARM
target and only honoured on x86.

This option is mostly useful in profiling scenarios.  The default remains that
tail call optimisations will be applied.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203577 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMISelLowering.cpp
test/CodeGen/ARM/tail-call.ll [new file with mode: 0644]

index 8f646deb26673e094e65f731af7a0349a0b89e2f..3d026be51311bf78f7dddf7f179b26a0fea50472 100644 (file)
@@ -1439,9 +1439,11 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
   bool isStructRet    = (Outs.empty()) ? false : Outs[0].Flags.isSRet();
   bool isThisReturn   = false;
   bool isSibCall      = false;
+
   // Disable tail calls if they're not supported.
-  if (!Subtarget->supportsTailCall())
+  if (!Subtarget->supportsTailCall() || MF.getTarget().Options.DisableTailCalls)
     isTailCall = false;
+
   if (isTailCall) {
     // Check if it's really possible to do a tail call.
     isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv,
@@ -2273,7 +2275,7 @@ bool ARMTargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const {
   if (!Subtarget->supportsTailCall())
     return false;
 
-  if (!CI->isTailCall())
+  if (!CI->isTailCall() || getTargetMachine().Options.DisableTailCalls)
     return false;
 
   return !Subtarget->isThumb1Only();
diff --git a/test/CodeGen/ARM/tail-call.ll b/test/CodeGen/ARM/tail-call.ll
new file mode 100644 (file)
index 0000000..270b41d
--- /dev/null
@@ -0,0 +1,21 @@
+; RUN: llc -mtriple armv7 -O0 -o - < %s | FileCheck %s -check-prefix CHECK-TAIL
+; RUN: llc -mtriple armv7 -O0 -disable-tail-calls -o - < %s \
+; RUN:   | FileCheck %s -check-prefix CHECK-NO-TAIL
+
+declare i32 @callee(i32 %i)
+
+define i32 @caller(i32 %i) {
+entry:
+  %r = tail call i32 @callee(i32 %i)
+  ret i32 %r
+}
+
+; CHECK-LABEL: caller
+; CHECK-TAIL: b callee
+
+; CHECK-LABEL: caller
+; CHECK-NO-TAIL: push {lr}
+; CHECK-NO-TAIL: bl callee
+; CHECK-NO-TAIL: pop {lr}
+; CHECK-NO-TAIL: bx lr
+