diff options
author | Martin Jambor <mjambor@suse.cz> | 2014-01-17 20:05:52 +0100 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2014-01-17 20:05:52 +0100 |
commit | aef836828d33f32ac63d67d0e83180551b5a6fa8 (patch) | |
tree | 99d29bfe2635feedfde70f316326b6f7131e8e24 /gcc/ipa-cp.c | |
parent | 3b9c787b5765717c5284543ef4140bd840b2bf36 (diff) | |
download | gcc-aef836828d33f32ac63d67d0e83180551b5a6fa8.zip gcc-aef836828d33f32ac63d67d0e83180551b5a6fa8.tar.gz gcc-aef836828d33f32ac63d67d0e83180551b5a6fa8.tar.bz2 |
re PR ipa/59736 (ice with -O3 in cgraph_edge_brings_value_p)
2014-01-17 Martin Jambor <mjambor@suse.cz>
PR ipa/59736
* ipa-cp.c (prev_edge_clone): New variable.
(grow_next_edge_clone_vector): Renamed to grow_edge_clone_vectors.
Also resize prev_edge_clone vector.
(ipcp_edge_duplication_hook): Also update prev_edge_clone.
(ipcp_edge_removal_hook): New function.
(ipcp_driver): Register ipcp_edge_removal_hook.
From-SVN: r206729
Diffstat (limited to 'gcc/ipa-cp.c')
-rw-r--r-- | gcc/ipa-cp.c | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index a6a44e6..10fa4b6 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -2321,13 +2321,17 @@ ipcp_discover_new_direct_edges (struct cgraph_node *node, edge. */ static vec<cgraph_edge_p> next_edge_clone; +static vec<cgraph_edge_p> prev_edge_clone; static inline void -grow_next_edge_clone_vector (void) +grow_edge_clone_vectors (void) { if (next_edge_clone.length () <= (unsigned) cgraph_edge_max_uid) next_edge_clone.safe_grow_cleared (cgraph_edge_max_uid + 1); + if (prev_edge_clone.length () + <= (unsigned) cgraph_edge_max_uid) + prev_edge_clone.safe_grow_cleared (cgraph_edge_max_uid + 1); } /* Edge duplication hook to grow the appropriate linked list in @@ -2335,13 +2339,34 @@ grow_next_edge_clone_vector (void) static void ipcp_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst, - __attribute__((unused)) void *data) + void *) { - grow_next_edge_clone_vector (); - next_edge_clone[dst->uid] = next_edge_clone[src->uid]; + grow_edge_clone_vectors (); + + struct cgraph_edge *old_next = next_edge_clone[src->uid]; + if (old_next) + prev_edge_clone[old_next->uid] = dst; + prev_edge_clone[dst->uid] = src; + + next_edge_clone[dst->uid] = old_next; next_edge_clone[src->uid] = dst; } +/* Hook that is called by cgraph.c when an edge is removed. */ + +static void +ipcp_edge_removal_hook (struct cgraph_edge *cs, void *) +{ + grow_edge_clone_vectors (); + + struct cgraph_edge *prev = prev_edge_clone[cs->uid]; + struct cgraph_edge *next = next_edge_clone[cs->uid]; + if (prev) + next_edge_clone[prev->uid] = next; + if (next) + prev_edge_clone[next->uid] = prev; +} + /* See if NODE is a clone with a known aggregate value at a given OFFSET of a parameter with the given INDEX. */ @@ -3568,13 +3593,17 @@ static unsigned int ipcp_driver (void) { struct cgraph_2edge_hook_list *edge_duplication_hook_holder; + struct cgraph_edge_hook_list *edge_removal_hook_holder; struct topo_info topo; ipa_check_create_node_params (); ipa_check_create_edge_args (); - grow_next_edge_clone_vector (); + grow_edge_clone_vectors (); edge_duplication_hook_holder = cgraph_add_edge_duplication_hook (&ipcp_edge_duplication_hook, NULL); + edge_removal_hook_holder = + cgraph_add_edge_removal_hook (&ipcp_edge_removal_hook, NULL); + ipcp_values_pool = create_alloc_pool ("IPA-CP values", sizeof (struct ipcp_value), 32); ipcp_sources_pool = create_alloc_pool ("IPA-CP value sources", @@ -3600,6 +3629,7 @@ ipcp_driver (void) /* Free all IPCP structures. */ free_toporder_info (&topo); next_edge_clone.release (); + cgraph_remove_edge_removal_hook (edge_removal_hook_holder); cgraph_remove_edge_duplication_hook (edge_duplication_hook_holder); ipa_free_all_structures_after_ipa_cp (); if (dump_file) |