public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Enable inlining into thunks
@ 2016-05-15 22:22 Jan Hubicka
  2016-05-16  9:37 ` Martin Liška
  0 siblings, 1 reply; 3+ messages in thread
From: Jan Hubicka @ 2016-05-15 22:22 UTC (permalink / raw)
  To: gcc-patches

Hi,
this patch teach inliner to inline into thunks. This is easy to do - all we need
is to produce a gimple body when we decide to do so. This fixes some ages old xfails
and enables some 40k inlines in Firefox. Not all those inlines are win, because
the codst model of thunks is wrong.  We need to model that thunk calls are really just
simple jumps. I will do that incrementally.

Bootstrapped/regtested x86_64-linux, will commit it tomorrow.

Honza

	* ipa-inline-analysis.c (compute_inline_parameters): Be more reailistic
	on estimating thunk bodies; do not set inline_failed to CIF_THUNK for
	calls from thunk.
	* ipa-inline-transform.c (inline_call): When inlining into thunk produce
	gimple body.
	(preserve_function_body_p): No need to preserve function body
	* cif-codes.def (CIF_THUNK): Remove.
	* g++.dg/ipa/ivinline-7.C
	* g++.dg/ipa/ivinline-9.C

Index: ipa-inline-analysis.c
===================================================================
--- ipa-inline-analysis.c	(revision 236211)
+++ ipa-inline-analysis.c	(working copy)
@@ -2932,11 +2932,13 @@ compute_inline_parameters (struct cgraph
       struct inline_edge_summary *es = inline_edge_summary (node->callees);
       struct predicate t = true_predicate ();
 
-      node->callees->inline_failed = CIF_THUNK;
       node->local.can_change_signature = false;
-      es->call_stmt_size = INLINE_SIZE_SCALE;
-      es->call_stmt_time = INLINE_TIME_SCALE;
-      account_size_time (info, INLINE_SIZE_SCALE * 2, INLINE_TIME_SCALE * 2, &t);
+      es->call_stmt_size = eni_size_weights.call_cost;
+      es->call_stmt_time = eni_time_weights.call_cost;
+      account_size_time (info, INLINE_SIZE_SCALE * 2,
+			 INLINE_TIME_SCALE * 2, &t);
+      t = not_inlined_predicate ();
+      account_size_time (info, 2 * INLINE_SIZE_SCALE, 0, &t);
       inline_update_overall_summary (node);
       info->self_size = info->size;
       info->self_time = info->time;
	* ipa-inline-transform.c (inline_call): When inlining into thunk turn
	it into gimple function.
	(preserve_function_body_p): No need to preserve body to inline thunk.

Index: ipa-inline-transform.c
===================================================================
--- ipa-inline-transform.c	(revision 236211)
+++ ipa-inline-transform.c	(working copy)
@@ -314,12 +314,20 @@ inline_call (struct cgraph_edge *e, bool
   /* Don't even think of inlining inline clone.  */
   gcc_assert (!callee->global.inlined_to);
 
-  e->inline_failed = CIF_OK;
-  DECL_POSSIBLY_INLINED (callee->decl) = true;
-
   to = e->caller;
   if (to->global.inlined_to)
     to = to->global.inlined_to;
+  if (to->thunk.thunk_p)
+    {
+      if (in_lto_p)
+	to->get_untransformed_body ();
+      to->expand_thunk (false, true);
+      e = to->callees;
+    }
+
+
+  e->inline_failed = CIF_OK;
+  DECL_POSSIBLY_INLINED (callee->decl) = true;
 
   if (DECL_FUNCTION_PERSONALITY (callee->decl))
     DECL_FUNCTION_PERSONALITY (to->decl)
@@ -580,7 +588,7 @@ preserve_function_body_p (struct cgraph_
   gcc_assert (!node->alias && !node->thunk.thunk_p);
 
   /* Look if there is any clone around.  */
-  if (node->clones)
+  if (node->clones && !node->clones->thunk.thunk_p)
     return true;
   return false;
 }
Index: cif-code.def
===================================================================
--- cif-code.def	(revision 236211)
+++ cif-code.def	(working copy)
@@ -95,10 +95,6 @@ DEFCIFCODE(MISMATCHED_ARGUMENTS, CIF_FIN
 DEFCIFCODE(LTO_MISMATCHED_DECLARATIONS, CIF_FINAL_ERROR,
 	   N_("mismatched declarations during linktime optimization"))
 
-/* Caller is thunk.  */
-DEFCIFCODE(THUNK, CIF_FINAL_ERROR,                                             
-          N_("thunk call"))                                                    
-
 /* Call was originally indirect.  */
 DEFCIFCODE(ORIGINALLY_INDIRECT_CALL, CIF_FINAL_NORMAL,
 	   N_("originally indirect function call not considered for inlining"))
Index: testsuite/g++.dg/ipa/ivinline-7.C
===================================================================
--- testsuite/g++.dg/ipa/ivinline-7.C	(revision 236211)
+++ testsuite/g++.dg/ipa/ivinline-7.C	(working copy)
@@ -76,4 +76,4 @@ int main (int argc, char *argv[])
 }
 
 /* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::.*foo"  "inline"  } } */
-/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main"  "inline"  { xfail *-*-* } } } */
+/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main"  "inline"  } } */
Index: testsuite/g++.dg/ipa/ivinline-9.C
===================================================================
--- testsuite/g++.dg/ipa/ivinline-9.C	(revision 236211)
+++ testsuite/g++.dg/ipa/ivinline-9.C	(working copy)
@@ -90,4 +90,4 @@ int main (int argc, char *argv[])
 }
 
 /* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::.*foo"  "inline"  } } */
-/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main"  "inline"  { xfail *-*-* } } } */
+/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main"  "inline"  } } */

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Enable inlining into thunks
  2016-05-15 22:22 Enable inlining into thunks Jan Hubicka
@ 2016-05-16  9:37 ` Martin Liška
  2016-05-16 10:15   ` Jan Hubicka
  0 siblings, 1 reply; 3+ messages in thread
From: Martin Liška @ 2016-05-16  9:37 UTC (permalink / raw)
  To: Jan Hubicka, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2045 bytes --]

On 05/16/2016 12:22 AM, Jan Hubicka wrote:
> Hi,
> this patch teach inliner to inline into thunks. This is easy to do - all we need
> is to produce a gimple body when we decide to do so. This fixes some ages old xfails
> and enables some 40k inlines in Firefox. Not all those inlines are win, because
> the codst model of thunks is wrong.  We need to model that thunk calls are really just
> simple jumps. I will do that incrementally.
> 
> Bootstrapped/regtested x86_64-linux, will commit it tomorrow.

Hi Honza.

I've spotted a new ICE after I've applied all your patches (4) related
to thunk expansion.

tc.ii:13:80: error: Thunk is not supposed to have body
 int C::m_fn2(B &p1, int p2, int p3, int &p4) { m_fn1()->m_fn2(p1, p2, p3, p4); }
                                                                                ^
_ZThn8_N1C5m_fn2ER1BiiRi/37 (virtual int C::_ZThn8_N1C5m_fn2ER1BiiRi(B&, int, int, int&)) @0x7fc693311450
  Type: function definition analyzed
  Visibility: public virtual artificial
  next sharing asm name: 35
  References: 
  Referring: 
  Function virtual int C::_ZThn8_N1C5m_fn2ER1BiiRi(B&, int, int, int&)/37 is inline copy in virtual int C::m_fn2(B&, int, int, int&)/0
  Clone of _ZThn8_N1C5m_fn2ER1BiiRi/19
  Availability: local
  First run: 0
  Function flags: body local
  Thunk fixed offset -8 virtual value 0 has virtual offset 0)
  Called by: _ZN1C5m_fn2ER1BiiRi/36 (speculative) (inlined) (0.33 per call) (can throw external) 
  Calls: *.LTHUNK0/1 (0.33 per call) (can throw external) 
tc.ii:13:80: internal compiler error: verify_cgraph_node failed
0xb3258f cgraph_node::verify_node()
	../../gcc/cgraph.c:3444
0xb20acb symtab_node::verify()
	../../gcc/symtab.c:1177
0xb20b54 symtab_node::verify_symtab_nodes()
	../../gcc/symtab.c:1197
0xb40bc6 symtab_node::checking_verify_symtab_nodes()
	../../gcc/cgraph.h:614
0xdc9bc2 symbol_table::remove_unreachable_nodes(_IO_FILE*)
	../../gcc/ipa.c:690
0x178f732 ipa_inline
	../../gcc/ipa-inline.c:2444
0x179038e execute
	../../gcc/ipa-inline.c:2848

Thanks,
Martin

[-- Attachment #2: tc.ii --]
[-- Type: text/plain, Size: 256 bytes --]

class A;
class B {
public:
  virtual A *m_fn1();
};
class A {
public:
  virtual int m_fn2(B &, int, int, int &) = 0;
};
class C : B, A {
  int m_fn2(B &, int, int, int &);
};
int C::m_fn2(B &p1, int p2, int p3, int &p4) { m_fn1()->m_fn2(p1, p2, p3, p4); }

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Enable inlining into thunks
  2016-05-16  9:37 ` Martin Liška
@ 2016-05-16 10:15   ` Jan Hubicka
  0 siblings, 0 replies; 3+ messages in thread
From: Jan Hubicka @ 2016-05-16 10:15 UTC (permalink / raw)
  To: Martin Liška; +Cc: Jan Hubicka, gcc-patches

> On 05/16/2016 12:22 AM, Jan Hubicka wrote:
> > Hi,
> > this patch teach inliner to inline into thunks. This is easy to do - all we need
> > is to produce a gimple body when we decide to do so. This fixes some ages old xfails
> > and enables some 40k inlines in Firefox. Not all those inlines are win, because
> > the codst model of thunks is wrong.  We need to model that thunk calls are really just
> > simple jumps. I will do that incrementally.
> > 
> > Bootstrapped/regtested x86_64-linux, will commit it tomorrow.
> 
> Hi Honza.
> 
> I've spotted a new ICE after I've applied all your patches (4) related
> to thunk expansion.
> 
> tc.ii:13:80: error: Thunk is not supposed to have body
>  int C::m_fn2(B &p1, int p2, int p3, int &p4) { m_fn1()->m_fn2(p1, p2, p3, p4); }

I forgot two hunks in the final patch, here is version I comitted (which also fixes the ICE you mention):

Index: cgraph.c
===================================================================
--- cgraph.c	(revision 236269)
+++ cgraph.c	(working copy)
@@ -3324,7 +3324,7 @@ cgraph_node::verify_node (void)
 	  error ("More than one edge out of thunk node");
           error_found = true;
 	}
-      if (gimple_has_body_p (decl))
+      if (gimple_has_body_p (decl) && !global.inlined_to)
         {
 	  error ("Thunk is not supposed to have body");
           error_found = true;
Index: cgraphclones.c
===================================================================
--- cgraphclones.c	(revision 236269)
+++ cgraphclones.c	(working copy)
@@ -337,8 +337,6 @@ duplicate_thunk_for_node (cgraph_node *t
 
   cgraph_edge *e = new_thunk->create_edge (node, NULL, 0,
 						  CGRAPH_FREQ_BASE);
-  e->call_stmt_cannot_inline_p = true;
-  e->inline_failed = CIF_THUNK;
   symtab->call_edge_duplication_hooks (thunk->callees, e);
   symtab->call_cgraph_duplication_hooks (thunk, new_thunk);
   return new_thunk;
Index: cif-code.def
===================================================================
--- cif-code.def	(revision 236269)
+++ cif-code.def	(working copy)
@@ -95,10 +95,6 @@ DEFCIFCODE(MISMATCHED_ARGUMENTS, CIF_FIN
 DEFCIFCODE(LTO_MISMATCHED_DECLARATIONS, CIF_FINAL_ERROR,
 	   N_("mismatched declarations during linktime optimization"))
 
-/* Caller is thunk.  */
-DEFCIFCODE(THUNK, CIF_FINAL_ERROR,                                             
-          N_("thunk call"))                                                    
-
 /* Call was originally indirect.  */
 DEFCIFCODE(ORIGINALLY_INDIRECT_CALL, CIF_FINAL_NORMAL,
 	   N_("originally indirect function call not considered for inlining"))
Index: ipa-inline-analysis.c
===================================================================
--- ipa-inline-analysis.c	(revision 236269)
+++ ipa-inline-analysis.c	(working copy)
@@ -2932,11 +2932,13 @@ compute_inline_parameters (struct cgraph
       struct inline_edge_summary *es = inline_edge_summary (node->callees);
       struct predicate t = true_predicate ();
 
-      node->callees->inline_failed = CIF_THUNK;
       node->local.can_change_signature = false;
-      es->call_stmt_size = INLINE_SIZE_SCALE;
-      es->call_stmt_time = INLINE_TIME_SCALE;
-      account_size_time (info, INLINE_SIZE_SCALE * 2, INLINE_TIME_SCALE * 2, &t);
+      es->call_stmt_size = eni_size_weights.call_cost;
+      es->call_stmt_time = eni_time_weights.call_cost;
+      account_size_time (info, INLINE_SIZE_SCALE * 2,
+			 INLINE_TIME_SCALE * 2, &t);
+      t = not_inlined_predicate ();
+      account_size_time (info, 2 * INLINE_SIZE_SCALE, 0, &t);
       inline_update_overall_summary (node);
       info->self_size = info->size;
       info->self_time = info->time;
Index: ipa-inline-transform.c
===================================================================
--- ipa-inline-transform.c	(revision 236269)
+++ ipa-inline-transform.c	(working copy)
@@ -314,12 +314,20 @@ inline_call (struct cgraph_edge *e, bool
   /* Don't even think of inlining inline clone.  */
   gcc_assert (!callee->global.inlined_to);
 
-  e->inline_failed = CIF_OK;
-  DECL_POSSIBLY_INLINED (callee->decl) = true;
-
   to = e->caller;
   if (to->global.inlined_to)
     to = to->global.inlined_to;
+  if (to->thunk.thunk_p)
+    {
+      if (in_lto_p)
+	to->get_untransformed_body ();
+      to->expand_thunk (false, true);
+      e = to->callees;
+    }
+
+
+  e->inline_failed = CIF_OK;
+  DECL_POSSIBLY_INLINED (callee->decl) = true;
 
   if (DECL_FUNCTION_PERSONALITY (callee->decl))
     DECL_FUNCTION_PERSONALITY (to->decl)
@@ -580,7 +588,7 @@ preserve_function_body_p (struct cgraph_
   gcc_assert (!node->alias && !node->thunk.thunk_p);
 
   /* Look if there is any clone around.  */
-  if (node->clones)
+  if (node->clones && !node->clones->thunk.thunk_p)
     return true;
   return false;
 }
Index: testsuite/g++.dg/ipa/ivinline-7.C
===================================================================
--- testsuite/g++.dg/ipa/ivinline-7.C	(revision 236269)
+++ testsuite/g++.dg/ipa/ivinline-7.C	(working copy)
@@ -76,4 +76,4 @@ int main (int argc, char *argv[])
 }
 
 /* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::.*foo"  "inline"  } } */
-/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main"  "inline"  { xfail *-*-* } } } */
+/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main"  "inline"  } } */
Index: testsuite/g++.dg/ipa/ivinline-9.C
===================================================================
--- testsuite/g++.dg/ipa/ivinline-9.C	(revision 236269)
+++ testsuite/g++.dg/ipa/ivinline-9.C	(working copy)
@@ -90,4 +90,4 @@ int main (int argc, char *argv[])
 }
 
 /* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::.*foo"  "inline"  } } */
-/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main"  "inline"  { xfail *-*-* } } } */
+/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main"  "inline"  } } */

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-05-16 10:15 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-15 22:22 Enable inlining into thunks Jan Hubicka
2016-05-16  9:37 ` Martin Liška
2016-05-16 10:15   ` Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).