This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Improvement to loop optimization in presence of inlining
Sun Jun 28 18:25:20 1998 Mark Mitchell <mark@markmitchell.com>
* jump.c (duplicate_loop_exit_test): Don't refuse to copy a
section of code just because it contains
NOTE_INSN_BLOCK_{BEG,END}. Do refuse to move partial blocks,
though.
* stmt.c (expand_end_loop): Likewise. Also, don't refuse to
move CALL_INSNs or CODE_LABELs.
This patch, I have just realized, will screw up debugging information.
I shall have to think about how to fix that. For now, I'd still
appreciate comments on the patch, but I hereby retract it from the
submission queue. :-(
OK, here's an improved version. This version should not through
debugging information into total disarray. Jeff, OK?
--
Mark Mitchell mark@markmitchell.com
Mark Mitchell Consulting http://www.markmitchell.com
Sun Jun 28 18:25:20 1998 Mark Mitchell <mark@markmitchell.com>
* jump.c (duplicate_loop_exit_test): Don't refuse to copy a
section of code just because it contains
NOTE_INSN_BLOCK_{BEG,END}.
* stmt.c (expand_end_loop): Likewise. Also, don't refuse to
move CALL_INSNs or CODE_LABELs. When moving code, don't move
NOTE_INSN_BLOCK_{BEG,END}.
Index: jump.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/jump.c,v
retrieving revision 1.27
diff -c -p -r1.27 jump.c
*** jump.c 1998/06/27 23:30:35 1.27
--- jump.c 1998/06/29 19:55:53
*************** duplicate_loop_exit_test (loop_start)
*** 2400,2407 ****
This can be avoided by checking here for NOTE_INSN_LOOP_CONT. */
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
- || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
- || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT)
return 0;
break;
--- 2400,2405 ----
Index: stmt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/stmt.c,v
retrieving revision 1.43
diff -c -p -r1.43 stmt.c
*** stmt.c 1998/06/25 15:14:28 1.43
--- stmt.c 1998/06/29 21:35:09
*************** expand_end_loop ()
*** 1923,1939 ****
do_pending_stack_adjust ();
! /* If optimizing, perhaps reorder the loop. If the loop
! starts with a conditional exit, roll that to the end
! where it will optimize together with the jump back.
!
! We look for the last conditional branch to the exit that we encounter
! before hitting 30 insns or a CALL_INSN. If we see an unconditional
! branch to the exit first, use it.
! We must also stop at NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes
! because moving them is not valid. */
!
if (optimize
&&
! (GET_CODE (insn) == JUMP_INSN
--- 1923,1954 ----
do_pending_stack_adjust ();
! /* If optimizing, perhaps reorder the loop. If the loop starts with
! a loop exit, roll that to the end where it will optimize together
! with the jump back.
!
! We look for the conditional branch to the exit, except that once
! we find such a branch, we don't look past 30 instructions.
!
! In more detail, if the loop presently looks like this (in pseudo-C):
!
! start_label:
! if (test) goto end_label;
! body;
! goto start_label;
! end_label;
!
! transform it to look like:
!
! goto start_label;
! newstart_label:
! body;
! if (test) goto end_label;
! goto newstart_label;
! end_label;
! Here, the `test' may actually consist of some reasonably complex
! code, terminating in a test. */
if (optimize
&&
! (GET_CODE (insn) == JUMP_INSN
*************** expand_end_loop ()
*** 1946,1959 ****
for (insn = NEXT_INSN (loop_stack->data.loop.start_label); insn;
insn = NEXT_INSN (insn))
{
- if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == CODE_LABEL)
- break;
-
- if (GET_CODE (insn) == NOTE
- && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
- || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END))
- break;
-
if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == INSN)
num_insns++;
--- 1961,1966 ----
*************** expand_end_loop ()
*** 1994,1999 ****
--- 2001,2007 ----
to jump to there. */
register rtx newstart_label = gen_label_rtx ();
register rtx start_move = start_label;
+ rtx next_insn;
/* If the start label is preceded by a NOTE_INSN_LOOP_CONT note,
then we want to move this note also. */
*************** expand_end_loop ()
*** 2003,2009 ****
start_move = PREV_INSN (start_move);
emit_label_after (newstart_label, PREV_INSN (start_move));
! reorder_insns (start_move, last_test_insn, get_last_insn ());
emit_jump_insn_after (gen_jump (start_label),
PREV_INSN (newstart_label));
emit_barrier_after (PREV_INSN (newstart_label));
--- 2011,2048 ----
start_move = PREV_INSN (start_move);
emit_label_after (newstart_label, PREV_INSN (start_move));
!
! /* Actually move the insns. Start at the beginning, and
! keep copying insns until we've copied the
! last_test_insn. */
! for (insn = start_move; insn; insn = next_insn)
! {
! /* Figure out which insn comes after this one. We have
! to do this before me move INSN. */
! if (insn == last_test_insn)
! /* We've moved all the insns. */
! next_insn = NULL_RTX;
! else
! next_insn = NEXT_INSN (insn);
!
! if (GET_CODE (insn) == NOTE
! && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
! || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END))
! /* We don't want to move NOTE_INSN_BLOCK_BEGs or
! NOTE_INSN_BLOCK_ENDs because the correct generation
! of debugging information depends on these appearing
! in the same order in the RTL and in the tree
! structure, where they are represented as BLOCKs.
! So, we don't move block notes. Of course, moving
! the code inside the block is likely to make it
! impossible to debug the instructions in the exit
! test, but such is the price of optimization. */
! continue;
!
! /* Move the INSN. */
! reorder_insns (insn, insn, get_last_insn ());
! }
!
emit_jump_insn_after (gen_jump (start_label),
PREV_INSN (newstart_label));
emit_barrier_after (PREV_INSN (newstart_label));