diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-08-18 09:22:42 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-08-18 09:22:42 +0000 |
commit | f5e35fedc7811592de814876a85a548cb2f22934 (patch) | |
tree | e1a133f48c521b91466f3bcd74ce9eba66d5faa6 | |
parent | 89f4f2554ec0d99b9c6828757ba949c08e2b209a (diff) | |
download | gcc-f5e35fedc7811592de814876a85a548cb2f22934.tar.gz |
* cgraph.c (cgraph_create_indirect_edge): Discover
polymorphic calls and record basic info into indirect_info.
* gimple-fold.c (gimple_fold_call): When doing BINFO based
devirtualization, ignore objc function calls.
* ipa-cp.c (initialize_node_lattices): Be ready for polymorphic
call with no parm index info.
* ipa-prop.c (ipa_analyze_call_uses): Likewise.
* tree.c (virtual_method_call_p): New function.
* tree.h (virtual_method_call_p): Declare.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201824 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cgraph.c | 18 | ||||
-rw-r--r-- | gcc/gimple-fold.c | 2 | ||||
-rw-r--r-- | gcc/ipa-cp.c | 3 | ||||
-rw-r--r-- | gcc/ipa-prop.c | 2 | ||||
-rw-r--r-- | gcc/tree.c | 21 | ||||
-rw-r--r-- | gcc/tree.h | 1 |
7 files changed, 56 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6462a0559be..faa465ab27f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2013-08-18 Jan Hubicka <jh@suse.cz> + + * cgraph.c (cgraph_create_indirect_edge): Discover + polymorphic calls and record basic info into indirect_info. + * gimple-fold.c (gimple_fold_call): When doing BINFO based + devirtualization, ignore objc function calls. + * ipa-cp.c (initialize_node_lattices): Be ready for polymorphic + call with no parm index info. + * ipa-prop.c (ipa_analyze_call_uses): Likewise. + * tree.c (virtual_method_call_p): New function. + * tree.h (virtual_method_call_p): Declare. + 2013-08-16 Jan Hubicka <jh@suse.cz> PR middle-end/58179 diff --git a/gcc/cgraph.c b/gcc/cgraph.c index a939ae83484..e2f96d6436d 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -925,6 +925,7 @@ cgraph_create_indirect_edge (struct cgraph_node *caller, gimple call_stmt, { struct cgraph_edge *edge = cgraph_create_edge_1 (caller, NULL, call_stmt, count, freq); + tree target; edge->indirect_unknown_callee = 1; initialize_inline_failed (edge); @@ -932,6 +933,23 @@ cgraph_create_indirect_edge (struct cgraph_node *caller, gimple call_stmt, edge->indirect_info = cgraph_allocate_init_indirect_info (); edge->indirect_info->ecf_flags = ecf_flags; + /* Record polymorphic call info. */ + if (call_stmt + && (target = gimple_call_fn (call_stmt)) + && virtual_method_call_p (target)) + { + tree type = obj_type_ref_class (target); + + + /* Only record types can have virtual calls. */ + gcc_assert (TREE_CODE (type) == RECORD_TYPE); + edge->indirect_info->param_index = -1; + edge->indirect_info->otr_token + = tree_low_cst (OBJ_TYPE_REF_TOKEN (target), 1); + edge->indirect_info->otr_type = type; + edge->indirect_info->polymorphic = 1; + } + edge->next_callee = caller->indirect_calls; if (caller->indirect_calls) caller->indirect_calls->prev_callee = edge; diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index e9cd9aa2292..df6aef534eb 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -1105,7 +1105,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace) gimple_call_set_fn (stmt, OBJ_TYPE_REF_EXPR (callee)); changed = true; } - else + else if (virtual_method_call_p (callee)) { tree obj = OBJ_TYPE_REF_OBJECT (callee); tree binfo = gimple_extract_devirt_binfo_from_cst diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 312672cc49f..93934e20de8 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -734,7 +734,8 @@ initialize_node_lattices (struct cgraph_node *node) } for (ie = node->indirect_calls; ie; ie = ie->next_callee) - if (ie->indirect_info->polymorphic) + if (ie->indirect_info->polymorphic + && ie->indirect_info->param_index >= 0) { gcc_checking_assert (ie->indirect_info->param_index >= 0); ipa_get_parm_lattices (info, diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 7cda34637b2..7ffa929c411 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -1922,7 +1922,7 @@ ipa_analyze_call_uses (struct cgraph_node *node, return; if (TREE_CODE (target) == SSA_NAME) ipa_analyze_indirect_call_uses (node, info, parms_ainfo, call, target); - else if (TREE_CODE (target) == OBJ_TYPE_REF) + else if (virtual_method_call_p (target)) ipa_analyze_virtual_call_uses (node, info, call, target); } diff --git a/gcc/tree.c b/gcc/tree.c index 8b4d86585bb..9d4bc7f9fc8 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -11864,6 +11864,27 @@ types_same_for_odr (tree type1, tree type2) return true; } +/* TARGET is a call target of GIMPLE call statement + (obtained by gimple_call_fn). Return true if it is + OBJ_TYPE_REF representing an virtual call of C++ method. + (As opposed to OBJ_TYPE_REF representing objc calls + through a cast where middle-end devirtualization machinery + can't apply.) */ + +bool +virtual_method_call_p (tree target) +{ + if (TREE_CODE (target) != OBJ_TYPE_REF) + return false; + target = TREE_TYPE (target); + gcc_checking_assert (TREE_CODE (target) == POINTER_TYPE); + target = TREE_TYPE (target); + if (TREE_CODE (target) == FUNCTION_TYPE) + return false; + gcc_checking_assert (TREE_CODE (target) == METHOD_TYPE); + return true; +} + /* REF is OBJ_TYPE_REF, return the class the ref corresponds to. */ tree diff --git a/gcc/tree.h b/gcc/tree.h index c1d8d57e8d5..4dbff212b97 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -5974,6 +5974,7 @@ extern location_t tree_nonartificial_location (tree); extern tree block_ultimate_origin (const_tree); extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree); +extern bool virtual_method_call_p (tree); extern tree obj_type_ref_class (tree ref); extern bool types_same_for_odr (tree type1, tree type2); extern tree get_ref_base_and_extent (tree, HOST_WIDE_INT *, |