diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2014-10-02 09:03:15 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2014-10-02 07:03:15 +0000 |
commit | 5ce97055e0f4077280146d62394370882f1b13e0 (patch) | |
tree | b3e82e3cba97dcee5b7ae4802423eec91c41f503 /gcc/ipa-devirt.c | |
parent | 9fbbb20da58853217f84a9c4b82c84274c27144f (diff) | |
download | gcc-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.c | 40 |
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. */ |