PR ipa/59831 (ipa-cp devirt issues)

Martin Jambor mjambor@suse.cz
Tue Feb 4 23:17:00 GMT 2014


Hi,

On Fri, Jan 31, 2014 at 07:22:55AM +0100, Jan Hubicka wrote:

...

> 	PR ipa/59831
> 	* gimple-fold.c (gimple_extract_devirt_binfo_from_cst): Remove.
> 	* ipa-devirt.c (get_poymorphic_call_info_for_decl): Break out from ...
> 	(get_polymorphic_call_info): ... here.
> 	(get_polymorphic_call_info_from_invariant): New function based on
> 	gimple_extract_devirt_binfo_from_cst.
> 	(try_make_edge_direct_virtual_call): Update to use ipa-devirt.
> 	(ipa_get_indirect_edge_target_1): Likewise.
> 	(get_polymorphic_call_info_from_invariant): New function.
> 	(vtable_pointer_value_to_binfo): New function.
> 	* ipa-utils.h (get_polymorphic_call_info_from_invariant): Declare.
> 	(vtable_pointer_value_to_binfo): Declare.
> 	* ipa-prop.c (extr_type_from_vtbl_ptr_store): Use it.
> 	(try_make_edge_direct_virtual_call): Use aggregate propagation;
> 	rewrite handling of constants.
> 	* ipa-cp.c (ipa_get_indirect_edge_target_1): Likewise.
> 
> 	* testsuite/g++.dg/ipa/devirt-21.C: New testcase.
> 	* testsuite/g++.dg/ipa/devirt-20.C: Fix template.

...


> Index: ipa-cp.c
> ===================================================================
> --- ipa-cp.c	(revision 207287)
> +++ ipa-cp.c	(working copy)
> @@ -117,6 +117,7 @@ along with GCC; see the file COPYING3.
>  #include "params.h"
>  #include "ipa-inline.h"
>  #include "ipa-utils.h"
> +#include "print-tree.h"
>  
>  struct ipcp_value;
>  
> @@ -1479,9 +1480,9 @@ ipa_get_indirect_edge_target_1 (struct c
>    HOST_WIDE_INT token, anc_offset;
>    tree otr_type;
>    tree t;
> -  tree target;
> +  tree target = NULL;
>  
> -  if (param_index == -1
> +  if (!flag_devirtualize || param_index == -1
>        || known_vals.length () <= (unsigned int) param_index)
>      return NULL_TREE;
>  
> @@ -1532,25 +1533,76 @@ ipa_get_indirect_edge_target_1 (struct c
>    anc_offset = ie->indirect_info->offset;
>    otr_type = ie->indirect_info->otr_type;
>  
> -  t = known_vals[param_index];
> +  t = NULL;
> +
> +  /* Do we know BINFO?  */
>    if (!t && known_binfos.length () > (unsigned int) param_index)
>      t = known_binfos[param_index];
> -  if (!t)
> -    return NULL_TREE;
> +  /* FIXME: ipcp_discover_new_direct_edges makes no difference between
> +     constants and binfos.  This is because ipa-cp currently assumes that known
> +     value is always better than binfo.  Hopefully this will be fixed when
> +     ipa-cp is turned to propagate polymorphic call contextes.  */
> +  if (known_vals[param_index] && TREE_CODE (known_vals[param_index]) == TREE_BINFO)
> +    t = known_vals[param_index];
>  
> -  if (TREE_CODE (t) != TREE_BINFO)
> +  /* Try to work out BINFO from virtual table pointer value in replacements.  */
> +  if (!t && agg_reps && !ie->indirect_info->by_ref)

At this point you know that !ie->indirect_info->polymorphic is set and
thus ie->indirect_info->by_ref is always false because it really has
no meaning (it is only meaningful when agg_contents is set which is
mutually exclusive with the polymorphic flag).

>      {
> -      tree binfo;
> -      binfo = gimple_extract_devirt_binfo_from_cst
> -		 (t, ie->indirect_info->otr_type);
> -      if (!binfo)
> +      while (agg_reps)
> +	{
> +	  if (agg_reps->index == param_index
> +	      && agg_reps->offset == ie->indirect_info->offset
> +	      && agg_reps->by_ref)
> +	    {
> +	      debug_tree (t);
> +	      t = agg_reps->value;
> +	      t = vtable_pointer_value_to_binfo (t);
> +	      break;
> +	    }
> +	  agg_reps = agg_reps->next;
> +	}
> +    }
> +
> +  /* Try to work out BINFO from virtual table pointer value in known
> +     known aggregate values.  */
> +  if (!t && known_aggs.length () > (unsigned int) param_index
> +      && !ie->indirect_info->by_ref)

The same here.

Thanks,

Martin



More information about the Gcc-patches mailing list