[PATCH] D52067: [inline Cost] Don't mark function accessing varargs as non-inlinable

Sameer AbuAsal via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 13 18:44:56 PDT 2018


sabuasal created this revision.
sabuasal added reviewers: efriedma, fhahn.
Herald added subscribers: haicheng, eraman.

https://reviews.llvm.org/rL323619 upstream marks functions that are calling va_end as not viable for
inlining. This patch reverses that since this va_end doesn't need
access to the vriadic arguments list that are saved on the stack, only
va_start does.


https://reviews.llvm.org/D52067

Files:
  lib/Analysis/InlineCost.cpp
  test/Transforms/Inline/inline-func-vaend.ll


Index: test/Transforms/Inline/inline-func-vaend.ll
===================================================================
--- /dev/null
+++ test/Transforms/Inline/inline-func-vaend.ll
@@ -0,0 +1,64 @@
+; RUN: opt < %s -inline -S | FileCheck %s
+
+; This test checks that we inline functions that have va_end, if
+; they dob't have va_start.
+
+%struct.__va_list = type { i8* }
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @caller(i32 %n, i8* noalias %args, ...) {
+entry:
+  %n.addr = alloca i32, align 4
+  %args.addr = alloca i8*, align 4
+  %ap = alloca %struct.__va_list, align 4
+  store i32 %n, i32* %n.addr, align 4
+  store i8* %args, i8** %args.addr, align 4
+  %ap1 = bitcast %struct.__va_list* %ap to i8*
+  call void @llvm.va_start(i8* %ap1)
+  %0 = load i32, i32* %n.addr, align 4
+  %coerce.dive = getelementptr inbounds %struct.__va_list, %struct.__va_list* %ap, i32 0, i32 0
+  %1 = bitcast i8** %coerce.dive to [1 x i32]*
+  %2 = load [1 x i32], [1 x i32]* %1, align 4
+  call void @always_inlined(i32 %0, [1 x i32] %2)
+  %ap2 = bitcast %struct.__va_list* %ap to i8*
+  call void @llvm.va_end(i8* %ap2)
+  ret void
+}
+
+; CHECK-LABEL: @caller
+; CHECK-NOT:   call void @always_inlined
+
+
+; Function Attrs: nounwind
+declare void @llvm.va_start(i8*)
+
+; Function Attrs: alwaysinline nounwind
+define void @always_inlined(i32 %n, [1 x i32] %a.coerce) {
+entry:
+  %a = alloca %struct.__va_list, align 4
+  %n.addr = alloca i32, align 4
+  %a_copy = alloca %struct.__va_list, align 4
+  %coerce.dive = getelementptr inbounds %struct.__va_list, %struct.__va_list* %a, i32 0, i32 0
+  %0 = bitcast i8** %coerce.dive to [1 x i32]*
+  store [1 x i32] %a.coerce, [1 x i32]* %0, align 4
+  store i32 %n, i32* %n.addr, align 4
+  %1 = bitcast %struct.__va_list* %a_copy to i8*
+  %2 = bitcast %struct.__va_list* %a to i8*
+  call void @llvm.va_copy(i8* %1, i8* %2)
+  %3 = load i32, i32* %n.addr, align 4
+  %coerce.dive1 = getelementptr inbounds %struct.__va_list, %struct.__va_list* %a_copy, i32 0, i32 0
+  %4 = bitcast i8** %coerce.dive1 to [1 x i32]*
+  %5 = load [1 x i32], [1 x i32]* %4, align 4
+  call void @foo([1 x i32] %5, i32 %3)
+  %a_copy2 = bitcast %struct.__va_list* %a_copy to i8*
+  call void @llvm.va_end(i8* %a_copy2)
+  ret void
+}
+
+; Function Attrs: nounwind
+declare void @llvm.va_end(i8*)
+
+; Function Attrs: nounwind
+declare void @llvm.va_copy(i8*, i8*)
+
+declare dso_local void @foo([1 x i32], i32)
Index: lib/Analysis/InlineCost.cpp
===================================================================
--- lib/Analysis/InlineCost.cpp
+++ lib/Analysis/InlineCost.cpp
@@ -1239,7 +1239,6 @@
         HasUninlineableIntrinsic = true;
         return false;
       case Intrinsic::vastart:
-      case Intrinsic::vaend:
         UsesVarArgs = true;
         return false;
       }
@@ -2081,7 +2080,6 @@
         case llvm::Intrinsic::localescape:
         // Disallow inlining of functions that access VarArgs.
         case llvm::Intrinsic::vastart:
-        case llvm::Intrinsic::vaend:
           return false;
         }
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D52067.165406.patch
Type: text/x-patch
Size: 3093 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180914/63e9697b/attachment.bin>


More information about the llvm-commits mailing list