aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-devirt.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-10-02 09:03:15 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2014-10-02 07:03:15 +0000
commit5ce97055e0f4077280146d62394370882f1b13e0 (patch)
treeb3e82e3cba97dcee5b7ae4802423eec91c41f503 /gcc/ipa-devirt.c
parent9fbbb20da58853217f84a9c4b82c84274c27144f (diff)
downloadgcc-5ce97055e0f4077280146d62394370882f1b13e0.zip
gcc-5ce97055e0f4077280146d62394370882f1b13e0.tar.gz
gcc-5ce97055e0f4077280146d62394370882f1b13e0.tar.bz2
ipa-prop.h (ipa_get_controlled_uses): Add hack to avoid ICE when speculation is added.
* ipa-prop.h (ipa_get_controlled_uses): Add hack to avoid ICE when speculation is added. (ipa_edge_args): Add polymorphic_call_contexts. (ipa_get_ith_polymorhic_call_context): New accesor. (ipa_make_edge_direct_to_target): Add SPECULATIVE parameter. * ipa-prop.c (ipa_print_node_jump_functions_for_edge): Print contexts. (ipa_compute_jump_functions_for_edge): Compute contexts. (update_jump_functions_after_inlining): Update contexts. (ipa_make_edge_direct_to_target): Add SPECULATIVE argument; update dumping; add speculative edge creation. (try_make_edge_direct_virtual_call): Add CTX_PTR parameter; handle context updating. (update_indirect_edges_after_inlining): Pass down context. (ipa_edge_duplication_hook): Duplicate contexts. (ipa_write_node_info): Stream out contexts. (ipa_read_node_info): Stream in contexts. * ipa-devirt.c (type_all_derivations_known_p): Avoid ICE on non-ODR types. (try_speculative_devirtualization): New function. * ipa-utils.h (try_speculative_devirtualization): Declare. From-SVN: r215794
Diffstat (limited to 'gcc/ipa-devirt.c')
-rw-r--r--gcc/ipa-devirt.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index dc47e99..00fc6bb 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -224,6 +224,9 @@ type_all_derivations_known_p (const_tree t)
return true;
if (flag_ltrans)
return false;
+ /* Non-C++ types may have IDENTIFIER_NODE here, do not crash. */
+ if (!TYPE_NAME (t) || TREE_CODE (TYPE_NAME (t)) != TYPE_DECL)
+ return true;
if (type_in_anonymous_namespace_p (t))
return true;
return (decl_function_context (TYPE_NAME (t)) != NULL);
@@ -2734,6 +2737,43 @@ decl_warning_cmp (const void *p1, const void *p2)
return t2->count - t1->count;
}
+
+/* Try speculatively devirtualize call to OTR_TYPE with OTR_TOKEN with
+ context CTX. */
+
+struct cgraph_node *
+try_speculative_devirtualization (tree otr_type, HOST_WIDE_INT otr_token,
+ ipa_polymorphic_call_context ctx)
+{
+ vec <cgraph_node *>targets
+ = possible_polymorphic_call_targets
+ (otr_type, otr_token, ctx, NULL, NULL, true);
+ unsigned int i;
+ struct cgraph_node *likely_target = NULL;
+
+ for (i = 0; i < targets.length (); i++)
+ if (likely_target_p (targets[i]))
+ {
+ if (likely_target)
+ return NULL;
+ likely_target = targets[i];
+ }
+ if (!likely_target
+ ||!likely_target->definition
+ || DECL_EXTERNAL (likely_target->decl))
+ return NULL;
+
+ /* Don't use an implicitly-declared destructor (c++/58678). */
+ struct cgraph_node *non_thunk_target
+ = likely_target->function_symbol ();
+ if (DECL_ARTIFICIAL (non_thunk_target->decl))
+ return NULL;
+ if (likely_target->get_availability () <= AVAIL_INTERPOSABLE
+ && likely_target->can_be_discarded_p ())
+ return NULL;
+ return likely_target;
+}
+
/* The ipa-devirt pass.
When polymorphic call has only one likely target in the unit,
turn it into speculative call. */