diff options
author | amonakov <amonakov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-04-08 11:58:23 +0000 |
---|---|---|
committer | amonakov <amonakov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-04-08 11:58:23 +0000 |
commit | 8ff642e9b42471b6141564480c7d5a08ad75956a (patch) | |
tree | 1fa6f7e96f6d0620dc73960c0139cec0127e43c0 /gcc/sel-sched.c | |
parent | b73edd22fdbdef327dff73be8ba6c107cac135bd (diff) | |
download | gcc-8ff642e9b42471b6141564480c7d5a08ad75956a.tar.gz |
PR rtl-optimization/48235
* sel-sched.c (code_motion_process_successors): Recompute the last
insn in basic block if control flow changed.
(code_motion_path_driver): Ditto. Recompute the first insn as well.
Update condition for ilist_remove.
testsuite:
* gcc.dg/pr48235.c: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@172177 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/sel-sched.c')
-rw-r--r-- | gcc/sel-sched.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index 48fb2e0134d..f409c4fa2cc 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -6369,7 +6369,10 @@ code_motion_process_successors (insn_t insn, av_set_t orig_ops, the iterator becomes invalid. We need to try again. */ if (BLOCK_FOR_INSN (insn)->index != old_index || EDGE_COUNT (bb->succs) != old_succs) - goto rescan; + { + insn = sel_bb_end (BLOCK_FOR_INSN (insn)); + goto rescan; + } } #ifdef ENABLE_CHECKING @@ -6587,21 +6590,37 @@ code_motion_path_driver (insn_t insn, av_set_t orig_ops, ilist_t path, if (!expr) { int res; + rtx last_insn = PREV_INSN (insn); + bool added_to_path; gcc_assert (insn == sel_bb_end (bb)); /* Add bb tail to PATH (but it doesn't make any sense if it's a bb_head - it's already in PATH then). */ if (insn != first_insn) - ilist_add (&path, insn); + { + ilist_add (&path, insn); + added_to_path = true; + } + else + added_to_path = false; /* Process_successors should be able to find at least one successor for which code_motion_path_driver returns TRUE. */ res = code_motion_process_successors (insn, orig_ops, path, static_params); + /* Jump in the end of basic block could have been removed or replaced + during code_motion_process_successors, so recompute insn as the + last insn in bb. */ + if (NEXT_INSN (last_insn) != insn) + { + insn = sel_bb_end (bb); + first_insn = sel_bb_head (bb); + } + /* Remove bb tail from path. */ - if (insn != first_insn) + if (added_to_path) ilist_remove (&path); if (res != 1) |