aboutsummaryrefslogtreecommitdiff
path: root/gcc/loop.c
diff options
context:
space:
mode:
authorJ"orn Rennecke <amylaar@cygnus.co.uk>1998-12-08 14:50:03 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>1998-12-08 14:50:03 +0000
commit5353610bac132c98bf81ba8275658ac380e33849 (patch)
tree4a6ebb92a0bc307d49627551fdf771d6f47baae6 /gcc/loop.c
parent03d937fcebea686f9d4f456daa0f8251e0de67c8 (diff)
downloadgcc-5353610bac132c98bf81ba8275658ac380e33849.zip
gcc-5353610bac132c98bf81ba8275658ac380e33849.tar.gz
gcc-5353610bac132c98bf81ba8275658ac380e33849.tar.bz2
loop.c (strength_reduce): If scan_start points to the loop exit test...
* loop.c (strength_reduce): If scan_start points to the loop exit test, be wary of subversive use of gotos inside expression statements. Don't set maybe_multiple for a backward jump that does not include the label under consideration into its range. * unroll.c (biv_total_increment): Make use of maybe_multiple field. From-SVN: r24196
Diffstat (limited to 'gcc/loop.c')
-rw-r--r--gcc/loop.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/gcc/loop.c b/gcc/loop.c
index d7cb630..e989b3c 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -3555,6 +3555,11 @@ strength_reduce (scan_start, end, loop_top, insn_count,
struct loop_info loop_iteration_info;
struct loop_info *loop_info = &loop_iteration_info;
+ /* If scan_start points to the loop exit test, we have to be wary of
+ subversive use of gotos inside expression statements. */
+ if (prev_nonnote_insn (scan_start) != prev_nonnote_insn (loop_start))
+ maybe_multiple = back_branch_in_range_p (scan_start, loop_start, loop_end);
+
reg_iv_type = (enum iv_mode *) alloca (max_reg_before_loop
* sizeof (enum iv_mode));
bzero ((char *) reg_iv_type, max_reg_before_loop * sizeof (enum iv_mode));
@@ -3618,8 +3623,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
/* Past CODE_LABEL, we get to insns that may be executed multiple
times. The only way we can be sure that they can't is if every
jump insn between here and the end of the loop either
- returns, exits the loop, is a forward jump, or is a jump
- to the loop start. */
+ returns, exits the loop, is a jump to a location that is still
+ behind the label, or is a jump to the loop start. */
if (GET_CODE (p) == CODE_LABEL)
{
@@ -3648,9 +3653,12 @@ strength_reduce (scan_start, end, loop_top, insn_count,
|| (JUMP_LABEL (insn) != 0
&& JUMP_LABEL (insn) != scan_start
&& (INSN_UID (JUMP_LABEL (insn)) >= max_uid_for_loop
- || INSN_UID (insn) >= max_uid_for_loop
- || (INSN_LUID (JUMP_LABEL (insn))
- < INSN_LUID (insn))))))
+ || (INSN_UID (p) < max_uid_for_loop
+ ? (INSN_LUID (JUMP_LABEL (insn))
+ <= INSN_LUID (p))
+ : (INSN_UID (insn) >= max_uid_for_loop
+ || (INSN_LUID (JUMP_LABEL (insn))
+ < INSN_LUID (insn))))))))
{
maybe_multiple = 1;
break;