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

Reply via email to