This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fun with the unroller
- To: egcs-patches at egcs dot cygnus dot com
- Subject: Fun with the unroller
- From: Jeffrey A Law <law at upchuck dot cygnus dot com>
- Date: Wed, 07 Apr 1999 23:45:54 -0600
- Reply-To: law at cygnus dot com
Loop unrolling was incorrectly unrolling a loop in one of the plumhall
tests on the mn103 target.
Basically the loop looked like:
loop_start:
blah blah blah
(note/i 59 57 432 "" NOTE_INSN_LOOP_CONT)
(note 432 59 61 "" NOTE_INSN_LOOP_VTOP)
(insn/i 61 432 62 (set (reg/s:SI 38)
(reg/v:SI 34)) 8 {movsi+1} (nil)
(nil))
(insn/i 62 61 63 (set (reg/v:SI 34)
(plus:SI (reg/v:SI 34)
(const_int -1 [0xffffffff]))) 23 {subsi3-1} (nil)
(nil))
(insn/i 63 62 64 (set (cc0)
(reg/s:SI 38)) 15 {tstsi} (nil)
(nil))
(jump_insn/i 64 63 65 (set (pc)
(if_then_else (ne (cc0)
(const_int 0 [0x0]))
(label_ref 53)
(pc))) 65 {bne+1} (nil)
(nil))
Note that the unroller will (correctly) not copy insn 63 or insn 64. Thus
(reg:SI 38) is used outside the copied loop body.
However, (reg:SI 38) was marked as local in the loop body because the set of
(reg:SI 38) in insn 61 dominated the use in insn 63.
The code to determine the domination relationship did not account for the fact
that insn 63 will not copied. Ugh.
Anyway, this fixes the bug.
* unroll.c (unroll_loop): For HAVE_cc0 machines, adjust copy_end_luid
to account for the uncopied insn that sets cc0 at the end of the loop.
Index: unroll.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/unroll.c,v
retrieving revision 1.55
diff -c -3 -p -r1.55 unroll.c
*** unroll.c 1999/04/07 13:22:29 1.55
--- unroll.c 1999/04/08 05:48:45
*************** unroll_loop (loop_end, insn_count, loop_
*** 790,795 ****
--- 790,803 ----
since it will also be used outside the loop. */
if (GET_CODE (copy_end) == JUMP_INSN)
copy_end_luid--;
+
+ /* If we have a target that uses cc0, then we also must not duplicate
+ the insn that sets cc0 before the jump insn. */
+ #ifdef HAVE_cc0
+ if (GET_CODE (copy_end) == JUMP_INSN)
+ copy_end_luid--;
+ #endif
+
/* If copy_start points to the NOTE that starts the loop, then we must
use the next luid, because invariant pseudo-regs moved out of the loop
have their lifetimes modified to start here, but they are not safe