From: Robert Suchanek <[email protected]>

--param early-inlining-insns-cold=NUMBER
--param max-inline-insns-small-and-cold=NUMBER

Analysis shows that the main difference between -O2 and -Os goes down to
inlining of cold or unlikely functions. The new parameters (defaulted to
0) mean to disable these limitations with -Os. NUMBER could be set to
something like 4-32 to see the impact.

The main reason that smaller functions are treated as cold or unlikely
is the function cgraph_maybe_hot_edge_p () always returning FALSE for
-Os.

gcc/
        * ipa-inline.cc (want_early_inline_function_p): Check if the
        growth is greater than param_early_inlining_insns_cold.
        (want_inline_small_function_p): Check if the growth is greater
        than param_max_inline_insns_small_and_cold.
        * params.opt (early-inlining-insns-cold): New option.
        (max-inline-insns-small-and-cold): Likewise.

gcc/testsuite/
        * gcc.dg/inline-cold-1.c: New test.
        * gcc.dg/inline-cold-2.c: New test.
        * gcc.dg/ipa/inline-cold-1.c: New test.
        * gcc.dg/ipa/inline-cold-2.c: New test.

Cherry-picked c38d7e548cbb3defb141efb528cb356333e8eb7a
from https://github.com/MIPS/gcc

Signed-off-by: Robert Suchanek <[email protected]>
Signed-off-by: Faraz Shahbazker <[email protected]>
Signed-off-by: Aleksandar Rakic <[email protected]>
Signed-off-by: Eldar Osmanovic <[email protected]>
---
 gcc/ipa-inline.cc                        |  4 +++-
 gcc/params.opt                           |  8 ++++++++
 gcc/testsuite/gcc.dg/inline-cold-1.c     | 21 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/inline-cold-2.c     | 21 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/ipa/inline-cold-1.c | 21 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/ipa/inline-cold-2.c | 21 +++++++++++++++++++++
 6 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/inline-cold-1.c
 create mode 100644 gcc/testsuite/gcc.dg/inline-cold-2.c
 create mode 100644 gcc/testsuite/gcc.dg/ipa/inline-cold-1.c
 create mode 100644 gcc/testsuite/gcc.dg/ipa/inline-cold-2.c

diff --git a/gcc/ipa-inline.cc b/gcc/ipa-inline.cc
index 5a7615666cc..928c2bb3f92 100644
--- a/gcc/ipa-inline.cc
+++ b/gcc/ipa-inline.cc
@@ -819,7 +819,8 @@ want_early_inline_function_p (struct cgraph_edge *e)
 
       if (!want_inline || growth <= param_max_inline_insns_size)
        ;
-      else if (!e->maybe_hot_p ())
+      else if (!e->maybe_hot_p ()
+              && growth > param_early_inlining_insns_cold)
        {
          if (dump_enabled_p ())
            dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
@@ -1082,6 +1083,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool 
report)
        }
       /* If call is cold, do not inline when function body would grow. */
       else if (!e->maybe_hot_p (callee_speedup (e))
+              && growth > param_max_inline_insns_small_and_cold
               && (growth >= inline_insns_single (e->caller, false, false)
                   || growth_positive_p (callee, e, growth)))
        {
diff --git a/gcc/params.opt b/gcc/params.opt
index 90f9943c8cb..f89b5b2dd5b 100644
--- a/gcc/params.opt
+++ b/gcc/params.opt
@@ -150,6 +150,10 @@ Maximum size (in bytes) of objects tracked bytewise by 
dead store elimination.
 Common Joined UInteger Var(param_early_inlining_insns) Init(6) Optimization 
Param
 Maximal estimated growth of function body caused by early inlining of single 
call.
 
+-param=early-inlining-insns-cold=
+Common Joined UInteger Var(param_early_inlining_insns_cold) Init(0) 
Optimization Param
+Maximal estimated growth of function body caused by early inlining of cold 
call.
+
 -param=file-cache-files=
 Common Joined UInteger Var(param_file_cache_files) Init(16) Param
 Maximum number of files in the file cache.
@@ -654,6 +658,10 @@ The maximum number of instructions when inlining for size.
 Common Joined UInteger Var(param_max_inline_insns_small) Optimization Param
 The maximum number of instructions when automatically inlining small functions.
 
+-param=max-inline-insns-small-and-cold=
+Common Joined UInteger Var(param_max_inline_insns_small_and_cold) Optimization 
Init(0) Param
+The maximum number of instructions in a small and cold function eligible for 
inlining.
+
 -param=max-inline-recursive-depth=
 Common Joined UInteger Var(param_max_inline_recursive_depth) Optimization 
Init(8) Param
 The maximum depth of recursive inlining for inline functions.
diff --git a/gcc/testsuite/gcc.dg/inline-cold-1.c 
b/gcc/testsuite/gcc.dg/inline-cold-1.c
new file mode 100644
index 00000000000..d7752dc5ec6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/inline-cold-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fdump-tree-einline-details" }*/
+
+volatile int v;
+
+int
+foo (int x)
+{
+  v += x;
+  v += 1;
+  return v;
+}
+
+int
+main (int argc, char **argv)
+{
+  return foo(argc);
+}
+
+/* { dg-final { scan-tree-dump "will not early inline: 
main/\[0-9\]*->foo/\[0-9\]*, call is cold and code would grow by" "einline" } } 
*/
+/* { dg-final { scan-tree-dump-not "Inlining foo/\[0-9\]* into main/\[0-9\]*" 
"einline" } } */
diff --git a/gcc/testsuite/gcc.dg/inline-cold-2.c 
b/gcc/testsuite/gcc.dg/inline-cold-2.c
new file mode 100644
index 00000000000..3de8d18b9c2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/inline-cold-2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fdump-tree-einline-details --param 
early-inlining-insns-cold=32" }*/
+
+volatile int v;
+
+int
+foo (int x)
+{
+  v += x;
+  v += 1;
+  return v;
+}
+
+int
+main (int argc, char **argv)
+{
+  return foo(argc);
+}
+
+/* { dg-final { scan-tree-dump "Inlining foo/\[0-9]* into main/\[0-9]*" 
"einline" } } */
+/* { dg-final { scan-tree-dump-not "will not early inline: main/\[0-9]* -> 
foo/\[0-9]*, call is cold and code would grow by" "einline" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/inline-cold-1.c 
b/gcc/testsuite/gcc.dg/ipa/inline-cold-1.c
new file mode 100644
index 00000000000..27ad518e3bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/inline-cold-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fno-early-inlining -fno-partial-inlining -fno-ipa-cp 
-fdump-ipa-inline-details" }*/
+
+volatile int v;
+
+int
+foo (int x)
+{
+  v += x;
+  v += 1;
+  return v;
+}
+
+int
+main (int argc, char **argv)
+{
+  return foo(argc);
+}
+
+/* { dg-final { scan-ipa-dump "not inlinable: main/\[0-9\]* -> foo/\[0-9\]*, 
call is unlikely and code size would grow" "inline" } } */
+/* { dg-final { scan-ipa-dump-not "Inlined foo/\[0-9\]* into main/\[0-9\]*" 
"inline" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/inline-cold-2.c 
b/gcc/testsuite/gcc.dg/ipa/inline-cold-2.c
new file mode 100644
index 00000000000..6b1ed8bab1b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/inline-cold-2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fno-early-inlining -fno-partial-inlining -fno-ipa-cp 
-fdump-ipa-inline-details --param max-inline-insns-small-and-cold=32" }*/
+
+volatile int v;
+
+int
+foo (int x)
+{
+  v += x;
+  v += 1;
+  return v;
+}
+
+int
+main (int argc, char **argv)
+{
+  return foo(argc);
+}
+
+/* { dg-final { scan-ipa-dump "Inlined foo/\[0-9\]* into main/\[0-9\]*" 
"inline" } } */
+/* { dg-final { scan-ipa-dump-not "not inlinable: main/\[0-9\]* -> 
foo/\[0-9\]*, call is unlikely and code size would grow" "inline" } } */
-- 
2.43.0

Reply via email to