diff options
author | Martin Jambor <mjambor@suse.cz> | 2011-04-19 18:35:33 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2011-04-19 18:35:33 +0200 |
commit | 49c471e3d8e5a505b20672f7029d07bb828cbe1b (patch) | |
tree | f6f04a6735e023b75b60f7849bf8007b8c56b69d /gcc/ipa-cp.c | |
parent | 9714ca724859e90773df206f552937ddc4da004c (diff) | |
download | gcc-49c471e3d8e5a505b20672f7029d07bb828cbe1b.zip gcc-49c471e3d8e5a505b20672f7029d07bb828cbe1b.tar.gz gcc-49c471e3d8e5a505b20672f7029d07bb828cbe1b.tar.bz2 |
ipa-cp.c (ipcp_process_devirtualization_opportunities): Devirtualize also according to actual contants.
2011-04-19 Martin Jambor <mjambor@suse.cz>
* ipa-cp.c (ipcp_process_devirtualization_opportunities): Devirtualize
also according to actual contants.
* gimple-fold.c (gimple_extract_devirt_binfo_from_cst): New function.
(gimple_fold_call): Use it.
* gimple.h (gimple_extract_devirt_binfo_from_cst): Declare.
* testsuite/g++.dg/opt/devirt1.C: Bump to -O2, remove XFAIL.
* testsuite/g++.dg/opt/devirt2.C: New test.
* testsuite/g++.dg/ipa/devirt-g-1.C: Likewise.
From-SVN: r172719
Diffstat (limited to 'gcc/ipa-cp.c')
-rw-r--r-- | gcc/ipa-cp.c | 74 |
1 files changed, 47 insertions, 27 deletions
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index f7413f2..270e58a 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1246,51 +1246,71 @@ ipcp_process_devirtualization_opportunities (struct cgraph_node *node) for (ie = node->indirect_calls; ie; ie = next_ie) { - int param_index, types_count, j; + int param_index; HOST_WIDE_INT token, anc_offset; tree target, delta, otr_type; + struct ipcp_lattice *lat; next_ie = ie->next_callee; if (!ie->indirect_info->polymorphic) continue; param_index = ie->indirect_info->param_index; - if (param_index == -1 - || ipa_param_cannot_devirtualize_p (info, param_index) - || ipa_param_types_vec_empty (info, param_index)) + if (param_index == -1) continue; + lat = ipcp_get_lattice (info, param_index); token = ie->indirect_info->otr_token; anc_offset = ie->indirect_info->anc_offset; otr_type = ie->indirect_info->otr_type; target = NULL_TREE; - types_count = VEC_length (tree, info->params[param_index].types); - for (j = 0; j < types_count; j++) + if (lat->type == IPA_CONST_VALUE) { - tree binfo = VEC_index (tree, info->params[param_index].types, j); - tree d, t; - + tree binfo = gimple_extract_devirt_binfo_from_cst (lat->constant); + if (!binfo) + continue; binfo = get_binfo_at_offset (binfo, anc_offset, otr_type); if (!binfo) - { - target = NULL_TREE; - break; - } + continue; + target = gimple_get_virt_method_for_binfo (token, binfo, &delta, + false); + } + else + { + int types_count, j; - t = gimple_get_virt_method_for_binfo (token, binfo, &d, true); - if (!t) - { - target = NULL_TREE; - break; - } - else if (!target) - { - target = t; - delta = d; - } - else if (target != t || !tree_int_cst_equal (delta, d)) + if (ipa_param_cannot_devirtualize_p (info, param_index) + || ipa_param_types_vec_empty (info, param_index)) + continue; + + types_count = VEC_length (tree, info->params[param_index].types); + for (j = 0; j < types_count; j++) { - target = NULL_TREE; - break; + tree binfo = VEC_index (tree, info->params[param_index].types, j); + tree d, t; + + binfo = get_binfo_at_offset (binfo, anc_offset, otr_type); + if (!binfo) + { + target = NULL_TREE; + break; + } + + t = gimple_get_virt_method_for_binfo (token, binfo, &d, true); + if (!t) + { + target = NULL_TREE; + break; + } + else if (!target) + { + target = t; + delta = d; + } + else if (target != t || !tree_int_cst_equal (delta, d)) + { + target = NULL_TREE; + break; + } } } |