[PATCH] Fix ICE in early inliner (PR ipa/65008)

Richard Biener rguenther@suse.de
Thu Feb 19 11:07:00 GMT 2015


On Thu, 19 Feb 2015, Marek Polacek wrote:

> The problem exposed by this PR is (IIUC) that we hadn't gotten around to
> recomputing the inline parameters in the case when optimize_inline_calls
> introduces new statements.  That results in ICEing later on because in
> estimate_edge_growth we assert that estimated size of a statement is not
> 0.
> 
> This happens since r220359 - with this change, we started to perform early
> inlining even in always_inline functions.  So in the following testcase,
> we have in A::A() at the start of early inlining:
> 
>   call_foo (this_2(D));
> 
> Since call_foo is always_inline, we inline it and apply the changes via
> a call to optimize_inline_calls.  That turns the above statement into:
> 
>   A::foo (this_2(D));
> 
> This statement is new and we don't have the inline params for it computed,
> because when estimate_function_body_sizes walked the IL, the stmt wasn't
> there.
> 
> So fixed by doing what we do in early_inliner in a block below, that is,
> recomputing the inline parameters.  I didn't copied the if that calls
> gimple_check_call_matching_types and sets edge->call_stmt_cannot_inline_p,
> I'm not sure if it's needed.
> 
> Does that make sense?
> 
> Bootstrapped/regtested on x86_64-linux.
> 
> 2015-02-19  Marek Polacek  <polacek@redhat.com>
> 
> 	PR ipa/65008
> 	* ipa-inline.c (early_inliner): Recompute inline parameters.
> 
> 	* g++.dg/ipa/pr65008.C: New test.
> 
> diff --git gcc/ipa-inline.c gcc/ipa-inline.c
> index 025f7fc..c445f0a 100644
> --- gcc/ipa-inline.c
> +++ gcc/ipa-inline.c
> @@ -2559,6 +2559,19 @@ early_inliner (function *fun)
>  	{
>  	  timevar_push (TV_INTEGRATION);
>  	  todo |= optimize_inline_calls (current_function_decl);
> +	  /* optimize_inline_calls call above might have introduced new
> +	     statements that don't have inline parameters computed.  */
> +	  for (edge = node->callees; edge; edge = edge->next_callee)

Are cgraph edges up-to-date here?  I'd doubt that...  if so, why not
do this update in the inliner itself where it updates the cgraph edges?

> +	    {
> +	      if (inline_edge_summary_vec.length () > (unsigned) edge->uid)
> +		{
> +		  struct inline_edge_summary *es = inline_edge_summary (edge);
> +		  es->call_stmt_size
> +		    = estimate_num_insns (edge->call_stmt, &eni_size_weights);
> +		  es->call_stmt_time
> +		    = estimate_num_insns (edge->call_stmt, &eni_time_weights);
> +		}
> +	    }
>  	  inline_update_overall_summary (node);
>  	  inlined = false;
>  	  timevar_pop (TV_INTEGRATION);
> diff --git gcc/testsuite/g++.dg/ipa/pr65008.C gcc/testsuite/g++.dg/ipa/pr65008.C
> index e69de29..29b3a2f 100644
> --- gcc/testsuite/g++.dg/ipa/pr65008.C
> +++ gcc/testsuite/g++.dg/ipa/pr65008.C
> @@ -0,0 +1,19 @@
> +// PR ipa/65008
> +// { dg-do compile }
> +// { dg-options "-O2" }
> +
> +struct A
> +{
> +  A ();
> +  virtual void foo () {}
> +};
> +
> +static inline int __attribute__ ((always_inline)) call_foo (A *a)
> +{
> +  a->foo ();
> +}
> +
> +A::A ()
> +{
> +  call_foo (this);
> +}
> 
> 	Marek
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Jennifer Guild,
Dilip Upmanyu, Graham Norton HRB 21284 (AG Nuernberg)



More information about the Gcc-patches mailing list