diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-09-10 12:29:58 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-09-10 12:29:58 +0000 |
commit | e2b72d6c06561814e0a8f0346f24c9fc44c296c4 (patch) | |
tree | a528f05814b7721c32a5846b1aa61eacc0b393d4 /gcc/tree-ssa-threadupdate.c | |
parent | d8a2f83992fe8eefa5e4a7346662ee134f6d3abc (diff) | |
download | gcc-e2b72d6c06561814e0a8f0346f24c9fc44c296c4.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@202441 138bc75d-0d04-0410-961f-82ee72b054a4
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 8e40f6668cf..3c3d3bc80f0 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), |