diff options
author | Martin Jambor <mjambor@suse.cz> | 2014-12-02 11:12:27 +0100 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2014-12-02 11:12:27 +0100 |
commit | 47f4756ed1a23d93e586ad82e50e759fa4c24b6b (patch) | |
tree | 72ac8b75d1a23f45e3f88b78b6ade9d43c45254a | |
parent | c271ca677e13442bf7a660deee9a4030107c87e0 (diff) | |
download | gcc-47f4756ed1a23d93e586ad82e50e759fa4c24b6b.zip gcc-47f4756ed1a23d93e586ad82e50e759fa4c24b6b.tar.gz gcc-47f4756ed1a23d93e586ad82e50e759fa4c24b6b.tar.bz2 |
re PR ipa/63814 (g++.dg/ipa/pr61160-1.C fails with -m32 -fPIC)
2014-12-02 Martin Jambor <mjambor@suse.cz>
PR ipa/63814
* ipa-cp.c (same_node_or_its_all_contexts_clone_p): New function.
(cgraph_edge_brings_value_p): New parameter dest, use
same_node_or_its_all_contexts_clone_p and check availability.
(cgraph_edge_brings_value_p): Likewise.
(get_info_about_necessary_edges): New parameter dest, pass it to
cgraph_edge_brings_value_p. Update caller.
(gather_edges_for_value): Likewise.
(perhaps_add_new_callers): Use cgraph_edge_brings_value_p to check
both the destination and availability.
From-SVN: r218265
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/ipa-cp.c | 95 |
2 files changed, 65 insertions, 43 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 139881a..91bde4f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2014-12-02 Martin Jambor <mjambor@suse.cz> + + PR ipa/63814 + * ipa-cp.c (same_node_or_its_all_contexts_clone_p): New function. + (cgraph_edge_brings_value_p): New parameter dest, use + same_node_or_its_all_contexts_clone_p and check availability. + (cgraph_edge_brings_value_p): Likewise. + (get_info_about_necessary_edges): New parameter dest, pass it to + cgraph_edge_brings_value_p. Update caller. + (gather_edges_for_value): Likewise. + (perhaps_add_new_callers): Use cgraph_edge_brings_value_p to check + both the destination and availability. + 2014-12-02 Uros Bizjak <ubizjak@gmail.com> PR target/64113 diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index f97912b..4086265 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -2779,17 +2779,31 @@ get_clone_agg_value (struct cgraph_node *node, HOST_WIDE_INT offset, return NULL_TREE; } -/* Return true if edge CS does bring about the value described by SRC. */ +/* Return true is NODE is DEST or its clone for all contexts. */ static bool -cgraph_edge_brings_value_p (struct cgraph_edge *cs, - ipcp_value_source<tree> *src) +same_node_or_its_all_contexts_clone_p (cgraph_node *node, cgraph_node *dest) +{ + if (node == dest) + return true; + + struct ipa_node_params *info = IPA_NODE_REF (node); + return info->is_all_contexts_clone && info->ipcp_orig_node == dest; +} + +/* Return true if edge CS does bring about the value described by SRC to node + DEST or its clone for all contexts. */ + +static bool +cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src, + cgraph_node *dest) { struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); - cgraph_node *real_dest = cs->callee->function_symbol (); - struct ipa_node_params *dst_info = IPA_NODE_REF (real_dest); + enum availability availability; + cgraph_node *real_dest = cs->callee->function_symbol (&availability); - if ((dst_info->ipcp_orig_node && !dst_info->is_all_contexts_clone) + if (!same_node_or_its_all_contexts_clone_p (real_dest, dest) + || availability <= AVAIL_INTERPOSABLE || caller_info->node_dead) return false; if (!src->val) @@ -2828,18 +2842,18 @@ cgraph_edge_brings_value_p (struct cgraph_edge *cs, } } -/* Return true if edge CS does bring about the value described by SRC. */ +/* Return true if edge CS does bring about the value described by SRC to node + DEST or its clone for all contexts. */ static bool -cgraph_edge_brings_value_p (struct cgraph_edge *cs, - ipcp_value_source<ipa_polymorphic_call_context> - *src) +cgraph_edge_brings_value_p (cgraph_edge *cs, + ipcp_value_source<ipa_polymorphic_call_context> *src, + cgraph_node *dest) { struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); cgraph_node *real_dest = cs->callee->function_symbol (); - struct ipa_node_params *dst_info = IPA_NODE_REF (real_dest); - if ((dst_info->ipcp_orig_node && !dst_info->is_all_contexts_clone) + if (!same_node_or_its_all_contexts_clone_p (real_dest, dest) || caller_info->node_dead) return false; if (!src->val) @@ -2865,13 +2879,14 @@ get_next_cgraph_edge_clone (struct cgraph_edge *cs) return next_edge_clone[cs->uid]; } -/* Given VAL, iterate over all its sources and if they still hold, add their - edge frequency and their number into *FREQUENCY and *CALLER_COUNT - respectively. */ +/* Given VAL that is intended for DEST, iterate over all its sources and if + they still hold, add their edge frequency and their number into *FREQUENCY + and *CALLER_COUNT respectively. */ template <typename valtype> static bool -get_info_about_necessary_edges (ipcp_value<valtype> *val, int *freq_sum, +get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest, + int *freq_sum, gcov_type *count_sum, int *caller_count) { ipcp_value_source<valtype> *src; @@ -2884,7 +2899,7 @@ get_info_about_necessary_edges (ipcp_value<valtype> *val, int *freq_sum, struct cgraph_edge *cs = src->cs; while (cs) { - if (cgraph_edge_brings_value_p (cs, src)) + if (cgraph_edge_brings_value_p (cs, src, dest)) { count++; freq += cs->frequency; @@ -2901,12 +2916,13 @@ get_info_about_necessary_edges (ipcp_value<valtype> *val, int *freq_sum, return hot; } -/* Return a vector of incoming edges that do bring value VAL. It is assumed - their number is known and equal to CALLER_COUNT. */ +/* Return a vector of incoming edges that do bring value VAL to node DEST. It + is assumed their number is known and equal to CALLER_COUNT. */ template <typename valtype> static vec<cgraph_edge *> -gather_edges_for_value (ipcp_value<valtype> *val, int caller_count) +gather_edges_for_value (ipcp_value<valtype> *val, cgraph_node *dest, + int caller_count) { ipcp_value_source<valtype> *src; vec<cgraph_edge *> ret; @@ -2917,7 +2933,7 @@ gather_edges_for_value (ipcp_value<valtype> *val, int caller_count) struct cgraph_edge *cs = src->cs; while (cs) { - if (cgraph_edge_brings_value_p (cs, src)) + if (cgraph_edge_brings_value_p (cs, src, dest)) ret.quick_push (cs); cs = get_next_cgraph_edge_clone (cs); } @@ -3778,27 +3794,20 @@ perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val) struct cgraph_edge *cs = src->cs; while (cs) { - enum availability availability; - struct cgraph_node *dst = cs->callee->function_symbol (&availability); - if ((dst == node || IPA_NODE_REF (dst)->is_all_contexts_clone) - && availability > AVAIL_INTERPOSABLE - && cgraph_edge_brings_value_p (cs, src)) + if (cgraph_edge_brings_value_p (cs, src, node) + && cgraph_edge_brings_all_scalars_for_node (cs, val->spec_node) + && cgraph_edge_brings_all_agg_vals_for_node (cs, val->spec_node)) { - if (cgraph_edge_brings_all_scalars_for_node (cs, val->spec_node) - && cgraph_edge_brings_all_agg_vals_for_node (cs, - val->spec_node)) - { - if (dump_file) - fprintf (dump_file, " - adding an extra caller %s/%i" - " of %s/%i\n", - xstrdup (cs->caller->name ()), - cs->caller->order, - xstrdup (val->spec_node->name ()), - val->spec_node->order); - - cs->redirect_callee (val->spec_node); - redirected_sum += cs->count; - } + if (dump_file) + fprintf (dump_file, " - adding an extra caller %s/%i" + " of %s/%i\n", + xstrdup (cs->caller->name ()), + cs->caller->order, + xstrdup (val->spec_node->name ()), + val->spec_node->order); + + cs->redirect_callee (val->spec_node); + redirected_sum += cs->count; } cs = get_next_cgraph_edge_clone (cs); } @@ -3923,7 +3932,7 @@ decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset, val->local_size_cost + overall_size); return false; } - else if (!get_info_about_necessary_edges (val, &freq_sum, &count_sum, + else if (!get_info_about_necessary_edges (val, node, &freq_sum, &count_sum, &caller_count)) return false; @@ -3953,7 +3962,7 @@ decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset, fprintf (dump_file, " Creating a specialized node of %s/%i.\n", node->name (), node->order); - callers = gather_edges_for_value (val, caller_count); + callers = gather_edges_for_value (val, node, caller_count); if (offset == -1) modify_known_vectors_with_val (&known_csts, &known_contexts, val, index); else |