This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PR 82027] Also stream opt_info of former_clones
- From: Martin Jambor <mjambor at suse dot cz>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Jan Hubicka <jh at suse dot com>
- Date: Thu, 21 Dec 2017 22:50:25 +0100
- Subject: [PR 82027] Also stream opt_info of former_clones
- Authentication-results: sourceware.org; auth=none
Hi,
the problem in PR 82027 is a general one with thunks that are created
for IPA-CP clones. At WPA time, IPA-CP creates a clone that is called
through a thunk. An "artificial thunk" is created in
duplicate_thunk_for_node() in cgraphclones.c. This function also
removes now unnecessary arguments from DECL_ARGUMENTS of the new thunk.
The node gets appropriate args_to_skip so that its call-sites also get
the counterpart actual arguments removed at inline transform time.
Because the artificial thunk is not a virtual clone, it is created with
clone_of NULL and former_clone_of set to the original thunk.
Unfortunately, NULL clone_of means that output_cgraph_opt_summary_p()
returns false for the new artificial_thunk and therefore its
args_to_skip is not streamed and is lost. At inline transform time, we
do not remove the counterpart actual arguments and we end up with
argument mismatch.
The patch below fixes this by streaming args_to_skip also of former
clones, which brings LTO in-line with non-LTO. At WPA time, the only
nodes with non-NULL former_clone_of are artificial thunks created by
duplicate_thunk_for_node(), so it does not grow the streamed IL
unnecessarily.
Unfortunately, I do not remember why we have decided not to create
clones of thunks as virtual clones, which would be arguably a more
natural fix. Perhaps those reasons no longer apply and in gcc 9 we
could do that. However, for GCC 8, 7 and 6, I would prefer this small
non-intrusive one.
Bootstrapped and tested on x86_64-linux, I will attempt an LTO bootstrap
overnight, OK for trunk, gcc 7 and gcc 6 if it passes?
Thanks,
Martin
2017-12-21 Martin Jambor <mjambor@suse.cz>
PR lto/82027
* lto-cgraph.c (output_cgraph_opt_summary_p): Also check former
clones.
testsuite/
* g++.dg/lto/pr82027_0.C: New test.
---
gcc/lto-cgraph.c | 2 +-
gcc/testsuite/g++.dg/lto/pr82027_0.C | 73 ++++++++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/g++.dg/lto/pr82027_0.C
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index a19f8a13dfb..ed3df15b143 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -1958,7 +1958,7 @@ input_offload_tables (bool do_force_output)
static int
output_cgraph_opt_summary_p (struct cgraph_node *node)
{
- return (node->clone_of
+ return ((node->clone_of || node->former_clone_of)
&& (node->clone.tree_map
|| node->clone.args_to_skip
|| node->clone.combined_args_to_skip));
diff --git a/gcc/testsuite/g++.dg/lto/pr82027_0.C b/gcc/testsuite/g++.dg/lto/pr82027_0.C
new file mode 100644
index 00000000000..70cc776b2db
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/pr82027_0.C
@@ -0,0 +1,73 @@
+// { dg-lto-do run }
+// { dg-lto-options { { -O3 -flto } } }
+
+class Position
+{
+ public:
+ Position( void ) {}
+ virtual ~Position() {}
+
+ virtual void calcPercent( const char *name,int pos,int size ) {}
+};
+
+
+class Looper
+{
+ public:
+ Looper( Position *cc,int size )
+ : m_cc(cc), m_size(size) {}
+ virtual ~Looper() {}
+
+ void loop( void )
+ {
+ for( int pos=0; pos<m_size; pos++ )
+ {
+ m_cc->calcPercent( "",pos,m_size );
+ }
+ }
+
+ private:
+ Position *m_cc;
+ int m_size;
+};
+
+
+class EmptyClass
+{
+ public:
+ EmptyClass( void ) {}
+ virtual ~EmptyClass() {}
+};
+
+
+class Combined : public EmptyClass, public Position
+{
+ public:
+ Combined( void ) : m_percent(0) {}
+ ~Combined() {}
+
+ void calcPercent( const char *name,int pos,int size )
+ {
+ int percent = 100*pos/size;
+ if( percent!=m_percent )
+ m_percent = percent;
+ }
+
+ private:
+ int m_percent;
+};
+
+
+
+int main( int argc,char **argv )
+{
+ Combined *comb = new Combined();
+ Looper *looper = new Looper( comb,argc );
+
+ looper->loop();
+
+ delete comb;
+ delete looper;
+
+ return( 0 );
+}
--
2.15.1