From 48c4d691bee7cfeb8cd9364b60bb2b899eba9ac0 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 28 Nov 2000 20:44:30 +0100 Subject: [PATCH] loop.c (load_mems): Avoid using next_label to find end_label. * loop.c (load_mems): Avoid using next_label to find end_label. If jumping outside of the loop (other than loop end), don't hoist MEMs out of loop. * gcc.c-torture/execute/loop-8.c: New test. From-SVN: r37823 --- gcc/ChangeLog | 6 +++ gcc/loop.c | 51 ++++++++++++-------- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.c-torture/execute/loop-8.c | 23 +++++++++ 4 files changed, 64 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/loop-8.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d988b9c2e40..662b84944a5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2000-11-28 Jakub Jelinek + + * loop.c (load_mems): Avoid using next_label to find end_label. If + jumping outside of the loop (other than loop end), don't hoist MEMs + out of loop. + 2000-11-28 Jan Hubicka * calls.c (expand_call): Don't disable tail recursion based diff --git a/gcc/loop.c b/gcc/loop.c index 7b4fd319168..75c94cd62c4 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -8716,7 +8716,7 @@ load_mems (loop) int i; rtx p; rtx label = NULL_RTX; - rtx end_label = NULL_RTX; + rtx end_label; /* Nonzero if the next instruction may never be executed. */ int next_maybe_never = 0; int last_max_reg = max_reg_num (); @@ -8724,21 +8724,14 @@ load_mems (loop) if (loop_info->mems_idx == 0) return; - /* Find start of the extended basic block that enters the loop. */ - for (p = loop->start; - PREV_INSN (p) && GET_CODE (p) != CODE_LABEL; - p = PREV_INSN (p)) - ; - - cselib_init (); + /* We cannot use next_label here because it skips over normal insns. */ + end_label = next_nonnote_insn (loop->end); + if (end_label && GET_CODE (end_label) != CODE_LABEL) + end_label = NULL_RTX; - /* Build table of mems that get set to constant values before the - loop. */ - for (; p != loop->start; p = NEXT_INSN (p)) - cselib_process_insn (p); - - /* Check to see if it's possible that some instructions in the - loop are never executed. */ + /* Check to see if it's possible that some instructions in the loop are + never executed. Also check if there is a goto out of the loop other + than right after the end of the loop. */ for (p = next_insn_in_loop (loop, loop->scan_start); p != NULL_RTX && ! maybe_never; p = next_insn_in_loop (loop, p)) @@ -8757,6 +8750,15 @@ load_mems (loop) && NEXT_INSN (NEXT_INSN (p)) == loop->end && any_uncondjump_p (p))) { + /* If this is a jump outside of the loop but not right + after the end of the loop, we would have to emit new fixup + sequences for each such label. */ + if (JUMP_LABEL (p) != end_label + && (INSN_UID (JUMP_LABEL (p)) >= max_uid_for_loop + || INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (loop->start) + || INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (loop->end))) + return; + if (!any_condjump_p (p)) /* Something complicated. */ maybe_never = 1; @@ -8769,6 +8771,19 @@ load_mems (loop) maybe_never = 1; } + /* Find start of the extended basic block that enters the loop. */ + for (p = loop->start; + PREV_INSN (p) && GET_CODE (p) != CODE_LABEL; + p = PREV_INSN (p)) + ; + + cselib_init (); + + /* Build table of mems that get set to constant values before the + loop. */ + for (; p != loop->start; p = NEXT_INSN (p)) + cselib_process_insn (p); + /* Actually move the MEMs. */ for (i = 0; i < loop_info->mems_idx; ++i) { @@ -8960,10 +8975,6 @@ load_mems (loop) { if (label == NULL_RTX) { - /* We must compute the former - right-after-the-end label before we insert - the new one. */ - end_label = next_label (loop->end); label = gen_label_rtx (); emit_label_after (label, loop->end); } @@ -9001,7 +9012,7 @@ load_mems (loop) } } - if (label != NULL_RTX) + if (label != NULL_RTX && end_label != NULL_RTX) { /* Now, we need to replace all references to the previous exit label with the new one. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f60af3fdc82..f8544732f71 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2000-11-28 Jakub Jelinek + + * gcc.c-torture/execute/loop-8.c: New test. + 2000-11-28 Nathan Sidwell * g++.old-deja/g++.other/base1.C: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/loop-8.c b/gcc/testsuite/gcc.c-torture/execute/loop-8.c new file mode 100644 index 00000000000..e8d8cb5f045 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/loop-8.c @@ -0,0 +1,23 @@ +double a[3] = { 0.0, 1.0, 2.0 }; + +void bar (int x, double *y) +{ + if (x || *y != 1.0) + abort (); +} + +int main () +{ + double c; + int d; + for (d = 0; d < 3; d++) + { + c = a[d]; + if (c > 0.0) goto e; + } + bar(1, &c); + exit (1); +e: + bar(0, &c); + exit (0); +} -- 2.30.2