Fix the inliner so that the optsize function attribute don't alter the
authorPatrik Hägglund <patrik.h.hagglund@ericsson.com>
Wed, 23 May 2012 13:42:57 +0000 (13:42 +0000)
committerPatrik Hägglund <patrik.h.hagglund@ericsson.com>
Wed, 23 May 2012 13:42:57 +0000 (13:42 +0000)
inline threshold if the global inline threshold is lower (as for -Oz).

Reviewed by Chandler Carruth and Bill Wendling.

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

lib/Transforms/IPO/Inliner.cpp
test/Transforms/Inline/inline-optsize.ll [new file with mode: 0644]

index dc9cbfb05e29137646730c66d72d2a500a46b208..29a82189054a50edeecc1c1ec1482c9a6253cec8 100644 (file)
@@ -201,19 +201,22 @@ static bool InlineCallIfPossible(CallSite CS, InlineFunctionInfo &IFI,
 }
 
 unsigned Inliner::getInlineThreshold(CallSite CS) const {
-  int thres = InlineThreshold;
+  int thres = InlineThreshold; // -inline-threshold or else selected by
+                               // overall opt level
 
-  // Listen to optsize when -inline-limit is not given.
+  // If -inline-threshold is not given, listen to the optsize attribute when it
+  // would decrease the threshold.
   Function *Caller = CS.getCaller();
-  if (Caller && !Caller->isDeclaration() &&
-      Caller->hasFnAttr(Attribute::OptimizeForSize) &&
-      InlineLimit.getNumOccurrences() == 0)
+  bool OptSize = Caller && !Caller->isDeclaration() &&
+    Caller->hasFnAttr(Attribute::OptimizeForSize);
+  if (!(InlineLimit.getNumOccurrences() > 0) && OptSize && OptSizeThreshold < thres)
     thres = OptSizeThreshold;
 
-  // Listen to inlinehint when it would increase the threshold.
+  // Listen to the inlinehint attribute when it would increase the threshold.
   Function *Callee = CS.getCalledFunction();
-  if (HintThreshold > thres && Callee && !Callee->isDeclaration() &&
-      Callee->hasFnAttr(Attribute::InlineHint))
+  bool InlineHint = Callee && !Callee->isDeclaration() &&
+    Callee->hasFnAttr(Attribute::InlineHint);
+  if (InlineHint && HintThreshold > thres)
     thres = HintThreshold;
 
   return thres;
diff --git a/test/Transforms/Inline/inline-optsize.ll b/test/Transforms/Inline/inline-optsize.ll
new file mode 100644 (file)
index 0000000..20d7426
--- /dev/null
@@ -0,0 +1,33 @@
+; RUN: opt -S -Oz %s | FileCheck %s -check-prefix=OZ
+; RUN: opt -S -O2 %s | FileCheck %s -check-prefix=O2
+
+; The inline threshold for a function with the optsize attribute is currently
+; the same as the global inline threshold for -Os. Check that the optsize
+; function attribute don't alter the function specific inline threshold if the
+; global inline threshold is lower (as for -Oz).
+
+@a = global i32 4
+
+; This function should be larger than the inline threshold for -Oz (25), but
+; smaller than the inline threshold for optsize (75).
+define i32 @inner() {
+  %a1 = load volatile i32* @a
+  %x1 = add i32 %a1,  %a1
+  %a2 = load volatile i32* @a
+  %x2 = add i32 %x1, %a2
+  %a3 = load volatile i32* @a
+  %x3 = add i32 %x2, %a3
+  %a4 = load volatile i32* @a
+  %x4 = add i32 %x3, %a4
+  %a5 = load volatile i32* @a
+  %x5 = add i32 %x3, %a5
+  ret i32 %x5
+}
+
+; @inner() should be inlined for -O2 but not for -Oz.
+; OZ: call
+; O2-NOT: call
+define i32 @outer() optsize {
+   %r = call i32 @inner()
+   ret i32 %r
+}