[PATCH] D26748: [ARM] Relax restriction on variadic functions for tailcall optimization

Pablo Barrio via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 16 07:14:35 PST 2016


pbarrio created this revision.
pbarrio added reviewers: rengolin, olista01.
pbarrio added a subscriber: llvm-commits.
Herald added a subscriber: aemerson.

Variadic functions can be treated in the same way as normal functions
with respect to the number and types of parameters.


https://reviews.llvm.org/D26748

Files:
  lib/Target/ARM/ARMISelLowering.cpp
  test/CodeGen/ARM/tail-call.ll


Index: test/CodeGen/ARM/tail-call.ll
===================================================================
--- test/CodeGen/ARM/tail-call.ll
+++ test/CodeGen/ARM/tail-call.ll
@@ -30,3 +30,52 @@
   tail call void @callee_weak()
   ret void
 }
+
+; A tail call can be optimized if all the arguments can be passed in registers
+; R0-R3, or the remaining arguments are already in the caller's parameter area
+; in the stack. Variadic functions are no different.
+declare i32 @variadic(i32, ...)
+
+; e.g. four integers
+define void @v_caller_ints1(i32 %a, i32 %b) {
+; CHECK-LABEL: v_caller_ints1:
+; CHECK-TAIL: b variadic
+; CHECK-NO-TAIL: bl variadic
+entry:
+  %call = tail call i32 (i32, ...) @variadic(i32 %a, i32 %b, i32 %b, i32 %a)
+  ret void
+}
+
+; e.g. two 32-bit integers, one 64-bit integer (needs to span two regs)
+define void @v_caller_ints2(i32 %y, i64 %z) {
+; CHECK-LABEL: v_caller_ints2:
+; CHECK-TAIL: b variadic
+; CHECK-NO-TAIL: bl variadic
+entry:
+  %call = tail call i32 (i32, ...) @variadic(i32 %y, i64 %z, i32 %y)
+  ret void
+}
+
+; e.g. two 32-bit integers, one 64-bit integer and another 64-bit integer that
+; doesn't fit in r0-r3 but comes from the caller argument list and is in the
+; same position.
+define void @v_caller_ints3(i64 %a, i32 %b, i32 %c, i64 %d) {
+; CHECK-LABEL: v_caller_ints3:
+; CHECK-TAIL: b variadic
+; CHECK-NO-TAIL: bl variadic
+entry:
+  %call = tail call i32 (i32, ...) @variadic(i32 %b, i32 %c, i64 %a, i64 %d)
+  ret void
+}
+
+; If the arguments do not fit in r0-r3 and the existing parameters cannot be
+; taken from the caller's parameter region, the optimization is not supported.
+
+; e.g. one 32-bit integer, two 64-bit integers
+define void @v_caller_ints_fail(i32 %y, i64 %z) {
+; CHECK-LABEL: v_caller_ints_fail:
+; CHECK: bl variadic
+entry:
+  %call = tail call i32 (i32, ...) @variadic(i32 %y, i64 %z, i64 %z)
+  ret void
+}
Index: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- lib/Target/ARM/ARMISelLowering.cpp
+++ lib/Target/ARM/ARMISelLowering.cpp
@@ -2314,11 +2314,6 @@
   // Look for obvious safe cases to perform tail call optimization that do not
   // require ABI changes. This is what gcc calls sibcall.
 
-  // Do not sibcall optimize vararg calls unless the call site is not passing
-  // any arguments.
-  if (isVarArg && !Outs.empty())
-    return false;
-
   // Exception-handling functions need a special set of instructions to indicate
   // a return to the hardware. Tail-calling another function would probably
   // break this.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D26748.78186.patch
Type: text/x-patch
Size: 2578 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161116/59d69d42/attachment.bin>


More information about the llvm-commits mailing list