diff mbox

Strenghten early inliner analysis

Message ID 20141230113749.GB13958@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka Dec. 30, 2014, 11:37 a.m. UTC
Hi,
this patch enables inline predicates for early inlining, too.  This is easy to do because
we do have call stmt around and know if parameters are constants.

Bootstrapped/regtested x86_64-linux, comitted.

Honza

	* ipa-inline-analyssi.c (edge_set_predicate): Reset size/time when
	target is UNREACHABLE.
	(evaluate_properties_for_edge): If call statemet is available, use it
	to determine compile time constants.
	(estimate_function_body_sizes): Enable predicates for early inliner.
	(estimate_calls_size_and_time): Speedup.
	(inline_merge_summary): Evaluate properties for early inliner, too.

	* gcc.dg/ipa/inline-7.c: New testcase.

Comments

Markus Trippelsdorf Dec. 30, 2014, 1:21 p.m. UTC | #1
On 2014.12.30 at 12:37 +0100, Jan Hubicka wrote:
> Hi,
> this patch enables inline predicates for early inlining, too.  This is easy to do because
> we do have call stmt around and know if parameters are constants.
> 
> Bootstrapped/regtested x86_64-linux, comitted.

This causes Firefox LTO build on ppc64 to fail:

/home/trippels/gcc_test/usr/local/bin/c++ -fPIC -Wall -Wempty-body -Woverloaded-virtual -Wsign-compare -Wwrite-strings -Werror=endif-labels -Werror=int-to-pointer-cast -Werror=missing-braces -Werror=pointer-arith -Werror=return-type -Werror=sequence-point -Werror=unused-label -Werror=trigraphs -Werror=type-limits -Wno-invalid-offsetof -Wcast-align -flto=80 --param lto-partitions=80 -mcpu=power8 -ffunction-sections -fdata-sections -fno-exceptions -fno-strict-aliasing -frtti -fno-exceptions -fno-math-errno -std=gnu++0x -pthread -pipe -UDEBUG -DNDEBUG -O3 -DU_STATIC_IMPLEMENTATION -fvisibility=hidden -W -Wall -pedantic -Wpointer-arith -Wwrite-strings -Wno-long-long -Wno-unused -Wno-unused-parameter   -lpthread -Wl,--hash-style=gnu,--as-needed,--gc-sections,--icf=all -Wl,-z,noexecstack -Wl,-z,text -Wl,--build-id -Wl,--gc-sections  -o ../../bin/genrb errmsg.o genrb.o parse.o read.o reslist.o ustr.o rbutil.o wrtjava.o rle.o wrtxml.o prscmnts.o -L../../lib -licutu -L../../lib -licui18n -L../../lib -licuuc -L../../stubdata -licudata -lpthread -ldl -lm
lto1: internal compiler error: in inline_merge_summary, at ipa-inline-analysis.c:3611
0x10490b63 inline_merge_summary(cgraph_edge*)
        ../../gcc/gcc/ipa-inline-analysis.c:3611
0x10d0fa4b inline_call(cgraph_edge*, bool, vec<cgraph_edge*, va_heap, vl_ptr>*, int*, bool, bool*)
        ../../gcc/gcc/ipa-inline-transform.c:326
0x10d07b1b inline_small_functions
        ../../gcc/gcc/ipa-inline.c:1813
0x10d07b1b ipa_inline
        ../../gcc/gcc/ipa-inline.c:2185
0x10d07b1b execute
        ../../gcc/gcc/ipa-inline.c:2558
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
lto-wrapper: fatal error: /home/trippels/gcc_test/usr/local/bin/c++ returned 1 exit status

Will open a bug report later.
H.J. Lu Dec. 30, 2014, 4:31 p.m. UTC | #2
On Tue, Dec 30, 2014 at 5:21 AM, Markus Trippelsdorf
<markus@trippelsdorf.de> wrote:
> On 2014.12.30 at 12:37 +0100, Jan Hubicka wrote:
>> Hi,
>> this patch enables inline predicates for early inlining, too.  This is easy to do because
>> we do have call stmt around and know if parameters are constants.
>>
>> Bootstrapped/regtested x86_64-linux, comitted.
>
> This causes Firefox LTO build on ppc64 to fail:
>

It also caused:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64447
H.J. Lu Jan. 1, 2015, 6:14 p.m. UTC | #3
On Tue, Dec 30, 2014 at 8:31 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Tue, Dec 30, 2014 at 5:21 AM, Markus Trippelsdorf
> <markus@trippelsdorf.de> wrote:
>> On 2014.12.30 at 12:37 +0100, Jan Hubicka wrote:
>>> Hi,
>>> this patch enables inline predicates for early inlining, too.  This is easy to do because
>>> we do have call stmt around and know if parameters are constants.
>>>
>>> Bootstrapped/regtested x86_64-linux, comitted.
>>
>> This causes Firefox LTO build on ppc64 to fail:
>>
>
> It also caused:
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64447
>

This also caused:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64465

and is not fixed as of revision 219136.
diff mbox

Patch

===================================================================
--- ipa-inline-analysis.c	(revision 219107)
+++ ipa-inline-analysis.c	(working copy)
@@ -770,6 +770,8 @@  edge_set_predicate (struct cgraph_edge *
       e->redirect_callee (cgraph_node::get_create
 			    (builtin_decl_implicit (BUILT_IN_UNREACHABLE)));
       e->inline_failed = CIF_UNREACHABLE;
+      es->call_stmt_size = 0;
+      es->call_stmt_time = 0;
       if (callee)
 	callee->remove_symbol_and_inline_clones ();
     }
@@ -940,6 +942,14 @@  evaluate_properties_for_edge (struct cgr
 	{
 	  struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
 	  tree cst = ipa_value_from_jfunc (parms_info, jf);
+
+	  if (!cst && e->call_stmt
+	      && i < (int)gimple_call_num_args (e->call_stmt))
+	    {
+	      cst = gimple_call_arg (e->call_stmt, i);
+	      if (!is_gimple_min_invariant (cst))
+		cst = NULL;
+	    }
 	  if (cst)
 	    {
 	      gcc_checking_assert (TREE_CODE (cst) != TREE_BINFO);
@@ -958,6 +968,22 @@  evaluate_properties_for_edge (struct cgr
 	  known_aggs[i] = &jf->agg;
 	}
     }
+  else if (e->call_stmt && !e->call_stmt_cannot_inline_p
+	   && ((clause_ptr && info->conds) || known_vals_ptr))
+    {
+      int i, count = (int)gimple_call_num_args (e->call_stmt);
+
+      if (count && (info->conds || known_vals_ptr))
+	known_vals.safe_grow_cleared (count);
+      for (i = 0; i < count; i++)
+	{
+	  tree cst = gimple_call_arg (e->call_stmt, i);
+	  if (!is_gimple_min_invariant (cst))
+	    cst = NULL;
+	  if (cst)
+	    known_vals[i] = cst;
+	}
+    }
 
   if (clause_ptr)
     *clause_ptr = evaluate_conditions_for_known_args (callee, inline_p,
@@ -2464,10 +2490,22 @@  estimate_function_body_sizes (struct cgr
   info->conds = NULL;
   info->entry = NULL;
 
-  if (opt_for_fn (node->decl, optimize) && !early)
+  /* When optimizing and analyzing for IPA inliner, initialize loop optimizer
+     so we can produce proper inline hints.
+
+     When optimizing and analyzing for early inliner, initialize node params
+     so we can produce correct BB predicates.  */
+     
+  if (opt_for_fn (node->decl, optimize))
     {
       calculate_dominance_info (CDI_DOMINATORS);
-      loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
+      if (!early)
+        loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
+      else
+	{
+	  ipa_check_create_node_params ();
+	  ipa_initialize_node_params (node);
+	}
 
       if (ipa_node_params_sum)
 	{
@@ -2704,7 +2742,7 @@  estimate_function_body_sizes (struct cgr
     time = MAX_TIME;
   free (order);
 
-  if (!early && nonconstant_names.exists ())
+  if (nonconstant_names.exists () && !early)
     {
       struct loop *loop;
       predicate loop_iterations = true_predicate ();
@@ -2809,9 +2847,12 @@  estimate_function_body_sizes (struct cgr
   inline_summaries->get (node)->self_time = time;
   inline_summaries->get (node)->self_size = size;
   nonconstant_names.release ();
-  if (opt_for_fn (node->decl, optimize) && !early)
+  if (opt_for_fn (node->decl, optimize))
     {
-      loop_optimizer_finalize ();
+      if (!early)
+        loop_optimizer_finalize ();
+      else
+	ipa_free_all_node_params ();
       free_dominance_info (CDI_DOMINATORS);
     }
   if (dump_file)
@@ -3062,6 +3103,13 @@  estimate_calls_size_and_time (struct cgr
   for (e = node->callees; e; e = e->next_callee)
     {
       struct inline_edge_summary *es = inline_edge_summary (e);
+
+      /* Do not care about zero sized builtins.  */
+      if (e->inline_failed && !es->call_stmt_size)
+	{
+	  gcc_checking_assert (!es->call_stmt_time);
+	  continue;
+	}
       if (!es->predicate
 	  || evaluate_predicate (es->predicate, possible_truths))
 	{
@@ -3522,13 +3570,14 @@  inline_merge_summary (struct cgraph_edge
   else
     toplev_predicate = true_predicate ();
 
+  if (callee_info->conds)
+    evaluate_properties_for_edge (edge, true, &clause, NULL, NULL, NULL);
   if (ipa_node_params_sum && callee_info->conds)
     {
       struct ipa_edge_args *args = IPA_EDGE_REF (edge);
       int count = ipa_get_cs_argument_count (args);
       int i;
 
-      evaluate_properties_for_edge (edge, true, &clause, NULL, NULL, NULL);
       if (count)
 	{
 	  operand_map.safe_grow_cleared (count);
Index: testsuite/gcc.dg/ipa/inline-7.c
===================================================================
--- testsuite/gcc.dg/ipa/inline-7.c	(revision 0)
+++ testsuite/gcc.dg/ipa/inline-7.c	(revision 0)
@@ -0,0 +1,25 @@ 
+/* Check that early inliner works out that a is empty of parameter 0.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-einline -fno-partial-inlining"  } */
+void t(void);
+int a (int b)
+{
+  if (!b)
+   {
+	t();
+	t();
+	t();
+	t();
+	t();
+	t();
+	t();
+   }
+}
+void
+m()
+{
+ a(1);
+ a(0);
+}
+/* { dg-final { scan-tree-dump-times "Inlining a into m" 1 "einline"  } } */
+/* { dg-final { cleanup-tree-dump "einline" } } */