[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