aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-pre.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-08-07 22:58:17 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2014-08-07 20:58:17 +0000
commit7d0aa05b9ead1b114958d8230377c2c25ef54876 (patch)
tree3358c76f8c1af0e9fe0b8b19fef9b3fe6f0935ff /gcc/tree-ssa-pre.c
parent9f25a338f91f9c448d57681b6d17a91233222d43 (diff)
downloadgcc-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.c40
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));
}
}