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