aboutsummaryrefslogtreecommitdiff
path: root/gcc/sel-sched.c
diff options
context:
space:
mode:
authoramonakov <amonakov@138bc75d-0d04-0410-961f-82ee72b054a4>2011-04-08 11:58:23 +0000
committeramonakov <amonakov@138bc75d-0d04-0410-961f-82ee72b054a4>2011-04-08 11:58:23 +0000
commit8ff642e9b42471b6141564480c7d5a08ad75956a (patch)
tree1fa6f7e96f6d0620dc73960c0139cec0127e43c0 /gcc/sel-sched.c
parentb73edd22fdbdef327dff73be8ba6c107cac135bd (diff)
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.c25
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)