https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87525
Martin Jambor <jamborm at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jamborm at gcc dot gnu.org --- Comment #19 from Martin Jambor <jamborm at gcc dot gnu.org> --- (In reply to Jan Hubicka from comment #14) > Martin, > it seems to me that ipa-cp should not clone extern inline functions unless > it sees that it helps to clone some real functions called from it. Why the > costmodel thinks it is profitable? It does not special-case that kind of situation. Still it is not easy, because the cloning decisions are made on the final sweep over the call graph from callers to callees and whether any callees would be cloned will only be decided in the future. Still, the cost model should probably evaluate these cases differently, perhaps like the patch below. To the extent to which I am able to reproduce the issue (only on gcc 8 and in the "correct" case it segfaults as opposed to endless loop), the adjustment helps, but it is of course only a heuristics. diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index e868b9c2623..f148ceef393 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -4685,15 +4685,23 @@ decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset, fprintf (dump_file, " (caller_count: %i)\n", caller_count); } - if (!good_cloning_opportunity_p (node, val->local_time_benefit, - freq_sum, count_sum, - val->local_size_cost) - && !good_cloning_opportunity_p (node, - val->local_time_benefit - + val->prop_time_benefit, - freq_sum, count_sum, - val->local_size_cost - + val->prop_size_cost)) + if (DECL_EXTERNAL (node->decl) && DECL_DECLARED_INLINE_P (node->decl)) + { + if (!good_cloning_opportunity_p (node, val->prop_time_benefit, + freq_sum, count_sum, + val->local_size_cost + + val->prop_size_cost)) + return false; + } + else if (!good_cloning_opportunity_p (node, val->local_time_benefit, + freq_sum, count_sum, + val->local_size_cost) + && !good_cloning_opportunity_p (node, + val->local_time_benefit + + val->prop_time_benefit, + freq_sum, count_sum, + val->local_size_cost + + val->prop_size_cost)) return false; if (dump_file)