ipa/103989 - avoid IPA inlining of small functions with -Og

Message ID spq8858-8sq6-9583-1qoq-401qr6s82561@fhfr.qr
State Committed
Commit c952126870c92cf293d59ffb1497e402eb8fc269
Headers
Series ipa/103989 - avoid IPA inlining of small functions with -Og |

Commit Message

Richard Biener Jan. 18, 2022, 12:52 p.m. UTC
  The following change avoids doing IPA inlining of small functions
into functions compiled with -Og - those functions will see almost no
followup scalar cleanups so that the benefit anticipated by the
inliner will not be realized and instead the late diagnostic code
will be confused by dead code that is left around.

Bootstrap & regtest pending on x86_64-unknown-linux-gnu.

OK?

Thanks,
Richard.

2022-01-18  Richard Biener  <rguenther@suse.de>

	PR ipa/103989
	* ipa-inline.cc (inline_small_functions): Do not enqueue call
	edges originating in functions compiled with -Og.

	* g++.dg/opt/pr103989.C: New testcase.
---
 gcc/ipa-inline.cc                   |  7 ++++++-
 gcc/testsuite/g++.dg/opt/pr103989.C | 30 +++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/opt/pr103989.C
  

Comments

Jan Hubicka Jan. 18, 2022, 1:53 p.m. UTC | #1
> The following change avoids doing IPA inlining of small functions
> into functions compiled with -Og - those functions will see almost no
> followup scalar cleanups so that the benefit anticipated by the
> inliner will not be realized and instead the late diagnostic code
> will be confused by dead code that is left around.
> 
> Bootstrap & regtest pending on x86_64-unknown-linux-gnu.
> 
> OK?
OK.  Do we also want to disable inlining when callee is -Og and caller
is not?

Honza
> 
> Thanks,
> Richard.
> 
> 2022-01-18  Richard Biener  <rguenther@suse.de>
> 
> 	PR ipa/103989
> 	* ipa-inline.cc (inline_small_functions): Do not enqueue call
> 	edges originating in functions compiled with -Og.
> 
> 	* g++.dg/opt/pr103989.C: New testcase.
> ---
>  gcc/ipa-inline.cc                   |  7 ++++++-
>  gcc/testsuite/g++.dg/opt/pr103989.C | 30 +++++++++++++++++++++++++++++
>  2 files changed, 36 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/g++.dg/opt/pr103989.C
> 
> diff --git a/gcc/ipa-inline.cc b/gcc/ipa-inline.cc
> index 38522771118..f8bb072c422 100644
> --- a/gcc/ipa-inline.cc
> +++ b/gcc/ipa-inline.cc
> @@ -2029,7 +2029,12 @@ inline_small_functions (void)
>        struct cgraph_edge *next = NULL;
>        bool has_speculative = false;
>  
> -      if (!opt_for_fn (node->decl, optimize))
> +      if (!opt_for_fn (node->decl, optimize)
> +	  /* With -Og we do not want to perform IPA inlining of small
> +	     functions since there are no scalar cleanups after it
> +	     that would realize the anticipated win.  All abstraction
> +	     is removed during early inlining.  */
> +	  || opt_for_fn (node->decl, optimize_debug))
>  	continue;
>  
>        if (dump_file)
> diff --git a/gcc/testsuite/g++.dg/opt/pr103989.C b/gcc/testsuite/g++.dg/opt/pr103989.C
> new file mode 100644
> index 00000000000..4604811b42a
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/opt/pr103989.C
> @@ -0,0 +1,30 @@
> +// { dg-require-effective-target c++17 }
> +// { dg-options "-Og -Wall" }
> +
> +#include <optional>
> +#include <memory>
> +
> +struct A {
> +  A (int a) : a {a} 
> +  {}
> +
> +  const std::shared_ptr <int> x;
> +  int a;
> +};
> +
> +class B
> +{
> +public:
> +  B (const std::optional <A>& a)
> +    : a {a}
> +  {
> +  }
> +public:
> +  const std::optional <A> a;
> +};
> +
> +int
> +main ()
> +{
> +  B b {std::nullopt};
> +}
> -- 
> 2.31.1
  
Richard Biener Jan. 18, 2022, 2:09 p.m. UTC | #2
On Tue, 18 Jan 2022, Jan Hubicka wrote:

> > The following change avoids doing IPA inlining of small functions
> > into functions compiled with -Og - those functions will see almost no
> > followup scalar cleanups so that the benefit anticipated by the
> > inliner will not be realized and instead the late diagnostic code
> > will be confused by dead code that is left around.
> > 
> > Bootstrap & regtest pending on x86_64-unknown-linux-gnu.
> > 
> > OK?
> OK.  Do we also want to disable inlining when callee is -Og and caller
> is not?

I thought about that but decided to not do that - the issue here
is really that -Og doesn't run post-IPA optimizations so if we
inline a -Og early optimized function into a -O2 optimized function
at IPA time that issue doesn't apply.

So if then we should do that separately and with another motivating
testcase.

Thanks,
Richard.

> 
> Honza
> > 
> > Thanks,
> > Richard.
> > 
> > 2022-01-18  Richard Biener  <rguenther@suse.de>
> > 
> > 	PR ipa/103989
> > 	* ipa-inline.cc (inline_small_functions): Do not enqueue call
> > 	edges originating in functions compiled with -Og.
> > 
> > 	* g++.dg/opt/pr103989.C: New testcase.
> > ---
> >  gcc/ipa-inline.cc                   |  7 ++++++-
> >  gcc/testsuite/g++.dg/opt/pr103989.C | 30 +++++++++++++++++++++++++++++
> >  2 files changed, 36 insertions(+), 1 deletion(-)
> >  create mode 100644 gcc/testsuite/g++.dg/opt/pr103989.C
> > 
> > diff --git a/gcc/ipa-inline.cc b/gcc/ipa-inline.cc
> > index 38522771118..f8bb072c422 100644
> > --- a/gcc/ipa-inline.cc
> > +++ b/gcc/ipa-inline.cc
> > @@ -2029,7 +2029,12 @@ inline_small_functions (void)
> >        struct cgraph_edge *next = NULL;
> >        bool has_speculative = false;
> >  
> > -      if (!opt_for_fn (node->decl, optimize))
> > +      if (!opt_for_fn (node->decl, optimize)
> > +	  /* With -Og we do not want to perform IPA inlining of small
> > +	     functions since there are no scalar cleanups after it
> > +	     that would realize the anticipated win.  All abstraction
> > +	     is removed during early inlining.  */
> > +	  || opt_for_fn (node->decl, optimize_debug))
> >  	continue;
> >  
> >        if (dump_file)
> > diff --git a/gcc/testsuite/g++.dg/opt/pr103989.C b/gcc/testsuite/g++.dg/opt/pr103989.C
> > new file mode 100644
> > index 00000000000..4604811b42a
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/opt/pr103989.C
> > @@ -0,0 +1,30 @@
> > +// { dg-require-effective-target c++17 }
> > +// { dg-options "-Og -Wall" }
> > +
> > +#include <optional>
> > +#include <memory>
> > +
> > +struct A {
> > +  A (int a) : a {a} 
> > +  {}
> > +
> > +  const std::shared_ptr <int> x;
> > +  int a;
> > +};
> > +
> > +class B
> > +{
> > +public:
> > +  B (const std::optional <A>& a)
> > +    : a {a}
> > +  {
> > +  }
> > +public:
> > +  const std::optional <A> a;
> > +};
> > +
> > +int
> > +main ()
> > +{
> > +  B b {std::nullopt};
> > +}
> > -- 
> > 2.31.1
>
  

Patch

diff --git a/gcc/ipa-inline.cc b/gcc/ipa-inline.cc
index 38522771118..f8bb072c422 100644
--- a/gcc/ipa-inline.cc
+++ b/gcc/ipa-inline.cc
@@ -2029,7 +2029,12 @@  inline_small_functions (void)
       struct cgraph_edge *next = NULL;
       bool has_speculative = false;
 
-      if (!opt_for_fn (node->decl, optimize))
+      if (!opt_for_fn (node->decl, optimize)
+	  /* With -Og we do not want to perform IPA inlining of small
+	     functions since there are no scalar cleanups after it
+	     that would realize the anticipated win.  All abstraction
+	     is removed during early inlining.  */
+	  || opt_for_fn (node->decl, optimize_debug))
 	continue;
 
       if (dump_file)
diff --git a/gcc/testsuite/g++.dg/opt/pr103989.C b/gcc/testsuite/g++.dg/opt/pr103989.C
new file mode 100644
index 00000000000..4604811b42a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr103989.C
@@ -0,0 +1,30 @@ 
+// { dg-require-effective-target c++17 }
+// { dg-options "-Og -Wall" }
+
+#include <optional>
+#include <memory>
+
+struct A {
+  A (int a) : a {a} 
+  {}
+
+  const std::shared_ptr <int> x;
+  int a;
+};
+
+class B
+{
+public:
+  B (const std::optional <A>& a)
+    : a {a}
+  {
+  }
+public:
+  const std::optional <A> a;
+};
+
+int
+main ()
+{
+  B b {std::nullopt};
+}