diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2014-08-07 22:58:17 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2014-08-07 20:58:17 +0000 |
commit | 7d0aa05b9ead1b114958d8230377c2c25ef54876 (patch) | |
tree | 3358c76f8c1af0e9fe0b8b19fef9b3fe6f0935ff /gcc/tree-ssa-pre.c | |
parent | 9f25a338f91f9c448d57681b6d17a91233222d43 (diff) | |
download | gcc-7d0aa05b9ead1b114958d8230377c2c25ef54876.zip gcc-7d0aa05b9ead1b114958d8230377c2c25ef54876.tar.gz gcc-7d0aa05b9ead1b114958d8230377c2c25ef54876.tar.bz2 |
ipa-devirt.c: Include gimple-pretty-print.h
* ipa-devirt.c: Include gimple-pretty-print.h
(referenced_from_vtable_p): Exclude DECL_EXTERNAL from
further tests.
(decl_maybe_in_construction_p): Fix conditional on cdtor check
(get_polymorphic_call_info): Fix return value
(type_change_info): New sturcture based on ipa-prop
variant.
(noncall_stmt_may_be_vtbl_ptr_store): New predicate
based on ipa-prop variant.
(extr_type_from_vtbl_ptr_store): New function
based on ipa-prop variant.
(record_known_type): New function.
(check_stmt_for_type_change): New function.
(get_dynamic_type): New function.
* ipa-prop.c (ipa_analyze_call_uses): Use get_dynamic_type.
* tree-ssa-pre.c: ipa-utils.h
(eliminate_dom_walker::before_dom_children): Use ipa-devirt
machinery; sanity check with ipa-prop devirtualization.
* trans-mem.c (ipa_tm_insert_gettmclone_call): Clear
polymorphic flag.
* g++.dg/ipa/devirt-35.C: New testcase.
* g++.dg/ipa/devirt-36.C: New testcase.
From-SVN: r213739
Diffstat (limited to 'gcc/tree-ssa-pre.c')
-rw-r--r-- | gcc/tree-ssa-pre.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 8b4d2ba..0e968d5 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -64,6 +64,7 @@ along with GCC; see the file COPYING3. If not see #include "domwalk.h" #include "ipa-prop.h" #include "tree-ssa-propagate.h" +#include "ipa-utils.h" /* TODO: @@ -4360,12 +4361,41 @@ eliminate_dom_walker::before_dom_children (basic_block b) { tree fn = gimple_call_fn (stmt); if (fn - && TREE_CODE (fn) == OBJ_TYPE_REF - && TREE_CODE (OBJ_TYPE_REF_EXPR (fn)) == SSA_NAME) + && flag_devirtualize + && virtual_method_call_p (fn)) { - fn = ipa_intraprocedural_devirtualization (stmt); - if (fn && dbg_cnt (devirt)) + tree otr_type; + HOST_WIDE_INT otr_token; + ipa_polymorphic_call_context context; + tree instance; + bool final; + + instance = get_polymorphic_call_info (current_function_decl, + fn, + &otr_type, &otr_token, &context, stmt); + + get_dynamic_type (instance, &context, + OBJ_TYPE_REF_OBJECT (fn), otr_type, stmt); + + vec <cgraph_node *>targets + = possible_polymorphic_call_targets (obj_type_ref_class (fn), + tree_to_uhwi + (OBJ_TYPE_REF_TOKEN (fn)), + context, + &final); + if (dump_enabled_p ()) + dump_possible_polymorphic_call_targets (dump_file, + obj_type_ref_class (fn), + tree_to_uhwi + (OBJ_TYPE_REF_TOKEN (fn)), + context); + if (final && targets.length () <= 1 && dbg_cnt (devirt)) { + tree fn; + if (targets.length () == 1) + fn = targets[0]->decl; + else + fn = builtin_decl_implicit (BUILT_IN_UNREACHABLE); if (dump_enabled_p ()) { location_t loc = gimple_location_safe (stmt); @@ -4377,6 +4407,8 @@ eliminate_dom_walker::before_dom_children (basic_block b) gimple_call_set_fndecl (stmt, fn); gimple_set_modified (stmt, true); } + else + gcc_assert (!ipa_intraprocedural_devirtualization (stmt)); } } |