[PATCH] Fix overactive reference removal with speculative devirtualization

Jan Hubicka hubicka@ucw.cz
Tue Sep 23 15:03:00 GMT 2014


> Hi,
> 
> code removing references to indirectly-inlined functions can remove a
> few too many when speculative devirtualization gets into the picture.
> Although we already handle the case when speculative devirtualization
> clones an edge with a CONST jump function by also cloning the
> appropriate reference, we do nothing when cloning a PASS_THROUGH jump
> function.  However, inlining can later convert this into a CONST jump
> function and when that gets deleted, the reference is dropped (as a
> part of speculative devirtualization resolution).  Eventually this
> leads to the function being removed as unreachable and missing in the
> final link.  This is fixed by the following patch which increments
> controlled use counter of formal parameters when this kind of edge
> duplication.
> 
> I have also attempted to add a hunk to the edge removal hook that
> would decrement the counter in these situation (dropping the edge
> after all means the call will never happen).  However, I have run into
> ordering issues within indirect inlining (and speculative
> devirtualization resolution which happens as a part of making an edge
> direct).  So at the moment I'm posting only this fix and will work on
> the removal hook later.
> 
> Bootstrapped and tested on x86_64-linux, I have also successfully
> LTO-built Firefox with the patch (when before it was failing).
> 
> Thanks,
> 
> Martin
> 
> 
> 2014-09-19  Martin Jambor  <mjambor@suse.cz>
> 
> 	* ipa-prop.c (ipa_edge_duplication_hook): Update controlled_use_count
> 	when duplicating a PASS_THROUGH jump function when creating a
> 	speculative edge.

OK, perhaps adding a comment would be good idea?
I assume you did not manage to get a self contained testcase.

Honza
> 
> diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
> index bbb417d..29c8681 100644
> --- a/gcc/ipa-prop.c
> +++ b/gcc/ipa-prop.c
> @@ -3643,6 +3643,21 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>  	      dst_jf->value.constant.rdesc = dst_rdesc;
>  	    }
>  	}
> +      else if (dst_jf->type == IPA_JF_PASS_THROUGH
> +	       && src->caller == dst->caller)
> +	{
> +	  struct cgraph_node *inline_root = dst->caller->global.inlined_to
> +	    ? dst->caller->global.inlined_to : dst->caller;
> +	  struct ipa_node_params *root_info = IPA_NODE_REF (inline_root);
> +	  int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
> +
> +	  int c = ipa_get_controlled_uses (root_info, idx);
> +	  if (c != IPA_UNDESCRIBED_USE)
> +	    {
> +	      c++;
> +	      ipa_set_controlled_uses (root_info, idx, c);
> +	    }
> +	}
>      }
>  }
>  



More information about the Gcc-patches mailing list