Commit 7d0aa05b by Jan Hubicka Committed by Jan Hubicka

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
parent 9f25a338
2014-08-07 Jan Hubicka <hubicka@ucw.cz>
* 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.
2014-08-07 Trevor Saunders <tsaunders@mozilla.com>
* Makefile.in: Remove references to pointer-set.c and pointer-set.h.
......
......@@ -2337,11 +2337,46 @@ ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
&& !virtual_method_call_p (target)))
return;
struct cgraph_edge *cs = fbi->node->get_edge (call);
/* If we previously turned the call into a direct call, there is
no need to analyze. */
struct cgraph_edge *cs = fbi->node->get_edge (call);
if (cs && !cs->indirect_unknown_callee)
return;
if (cs->indirect_info->polymorphic)
{
tree otr_type;
HOST_WIDE_INT otr_token;
ipa_polymorphic_call_context context;
tree instance;
tree target = gimple_call_fn (call);
instance = get_polymorphic_call_info (current_function_decl,
target,
&otr_type, &otr_token,
&context, call);
if (get_dynamic_type (instance, &context,
OBJ_TYPE_REF_OBJECT (target),
otr_type, call))
{
gcc_assert (TREE_CODE (otr_type) == RECORD_TYPE);
cs->indirect_info->polymorphic = true;
cs->indirect_info->param_index = -1;
cs->indirect_info->otr_token = otr_token;
cs->indirect_info->otr_type = otr_type;
cs->indirect_info->outer_type = context.outer_type;
cs->indirect_info->speculative_outer_type = context.speculative_outer_type;
cs->indirect_info->offset = context.offset;
cs->indirect_info->speculative_offset = context.speculative_offset;
cs->indirect_info->maybe_in_construction
= context.maybe_in_construction;
cs->indirect_info->maybe_derived_type = context.maybe_derived_type;
cs->indirect_info->speculative_maybe_derived_type
= context.speculative_maybe_derived_type;
}
}
if (TREE_CODE (target) == SSA_NAME)
ipa_analyze_indirect_call_uses (fbi, call, target);
else if (virtual_method_call_p (target))
......
......@@ -95,7 +95,7 @@ tree get_polymorphic_call_info (tree, tree, tree *,
HOST_WIDE_INT *,
ipa_polymorphic_call_context *,
gimple call = NULL);
bool get_dynamic_type (tree, ipa_polymorphic_call_context *, tree, gimple);
bool get_dynamic_type (tree, ipa_polymorphic_call_context *, tree, tree, gimple);
bool get_polymorphic_call_info_from_invariant (ipa_polymorphic_call_context *,
tree, tree, HOST_WIDE_INT);
bool decl_maybe_in_construction_p (tree, tree, gimple, tree);
......
2014-08-07 Jan Hubicka <hubicka@ucw.cz>
* g++.dg/ipa/devirt-35.C: New testcase.
* g++.dg/ipa/devirt-36.C: New testcase.
2014-08-07 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/51312
......
/* { dg-options "-O2 -fdump-ipa-devirt-details -fdump-tree-fre1-details" } */
struct A {virtual int t(void) {return 1;}};
struct B:A {B(); virtual int t(void) {return 2;}};
void test2(struct A *);
int
m(struct B *b)
{
struct A *a = new (B);
a->t(); // This call should be devirtualized by
// FRE because we know type from ctor call
((struct B *)a)->B::t(); // Make devirt possible
// C++ FE won't produce inline body without this
test2(a);
return a->t(); // This call should be devirtualized speculatively because
// test2 may change the type of A by placement new.
// C++ standard is bit imprecise about this.
}
/* { dg-final { scan-ipa-dump "converting indirect call to function virtual int B::t" "fre1" } } */
/* { dg-final { scan-ipa-dump "to virtual int B::t" "devirt" } } */
/* { dg-final { scan-ipa-dump "1 speculatively devirtualized" "devirt" } } */
/* { dg-final { cleanup-ipa-dump "devirt" } } */
/* { dg-final { cleanup-tree-dump "fre" } } */
/* { dg-options "-O2 -fdump-ipa-devirt-details -fdump-tree-fre1-details" } */
struct A {virtual int t(void) {return 1;}};
struct B:A {B(); virtual int t(void) {return 2;}};
struct C {int a; struct B b;};
void test2(struct A *);
int
m(struct B *b)
{
struct C *c = new (C);
struct A *a = &c->b;
a->t(); // This call should be devirtualized by
// FRE because we know type from ctor call
((struct B *)a)->B::t(); // Make devirt possible
// C++ FE won't produce inline body without this
test2(a);
return a->t(); // This call should be devirtualized speculatively because
// test2 may change the type of A by placement new.
// C++ standard is bit imprecise about this.
}
/* { dg-final { scan-ipa-dump "converting indirect call to function virtual int B::t" "fre1" } } */
/* { dg-final { scan-ipa-dump "to virtual int B::t" "devirt" } } */
/* { dg-final { scan-ipa-dump "1 speculatively devirtualized" "devirt" } } */
/* { dg-final { cleanup-ipa-dump "devirt" } } */
/* { dg-final { cleanup-tree-dump "fre" } } */
......@@ -5042,6 +5042,9 @@ ipa_tm_insert_gettmclone_call (struct cgraph_node *node,
}
update_stmt (stmt);
cgraph_edge *e = cgraph_node::get (current_function_decl)->get_edge (stmt);
if (e && e->indirect_info)
e->indirect_info->polymorphic = false;
return true;
}
......
......@@ -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));
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment