diff options
author | Jeff Law <law@redhat.com> | 2013-09-10 06:29:58 -0600 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2013-09-10 06:29:58 -0600 |
commit | 581aedec91ca246f52469d349fbd7664d17d6dc2 (patch) | |
tree | a528f05814b7721c32a5846b1aa61eacc0b393d4 /gcc/tree-ssa-threadupdate.c | |
parent | 84cf4ab655292038d1371a801cbffb9fc6b6ecd0 (diff) | |
download | gcc-581aedec91ca246f52469d349fbd7664d17d6dc2.zip gcc-581aedec91ca246f52469d349fbd7664d17d6dc2.tar.gz gcc-581aedec91ca246f52469d349fbd7664d17d6dc2.tar.bz2 |
re PR tree-optimization/58343 (ICE in dfs_enumerate_from, at cfganal.c:1036)
PR tree-optimization/58343
* tree-ssa-threadupdate.c (thread_block): Identify and disable
jump threading requests through loop headers buried in the middle
of a jump threading path.
* tree-ssa-threadedge.c (thread_around_empty_blocks): Fix thinko
in return value/type.
* gcc.c-torture/compile/pr58343.c: New test.
From-SVN: r202441
Diffstat (limited to 'gcc/tree-ssa-threadupdate.c')
-rw-r--r-- | gcc/tree-ssa-threadupdate.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index 8e40f66..3c3d3bc 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -640,14 +640,36 @@ thread_block (basic_block bb, bool noloop_only) else e2 = THREAD_TARGET (e); - if (!e2 + if (!e2 || noloop_only) + { /* If NOLOOP_ONLY is true, we only allow threading through the - header of a loop to exit edges. */ - || (noloop_only - && bb == bb->loop_father->header + header of a loop to exit edges. + + There are two cases to consider. The first when BB is the + loop header. We will attempt to thread this elsewhere, so + we can just continue here. */ + + if (bb == bb->loop_father->header && (!loop_exit_edge_p (bb->loop_father, e2) - || THREAD_TARGET2 (e)))) - continue; + || THREAD_TARGET2 (e))) + continue; + + + /* The second occurs when there was loop header buried in a jump + threading path. We do not try and thread this elsewhere, so + just cancel the jump threading request by clearing the AUX + field now. */ + if (bb->loop_father != e2->src->loop_father + && !loop_exit_edge_p (e2->src->loop_father, e2)) + { + /* Since this case is not handled by our special code + to thread through a loop header, we must explicitly + cancel the threading request here. */ + free (e->aux); + e->aux = NULL; + continue; + } + } if (e->dest == e2->src) update_bb_profile_for_threading (e->dest, EDGE_FREQUENCY (e), |