This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Improve initial RTL generation for loops
- From: Roger Sayle <roger at eyesopen dot com>
- To: <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 10 Sep 2002 14:50:45 -0600 (MDT)
- Subject: [PATCH] Improve initial RTL generation for loops
The following patch improves the RTL that GCC initially generates for
loops. Investigation of PR optimization/6405 [and related failures
in another patch I'm working on] reveals that the problems are caused
by NOTE_INSN_LOOP_* notes being corrupted by cleaning up the CFG prior
to the loop optimization pass.
A contributing factor is that GCC currently generates incredibly
convoluted RTL for unconditional/infinite loops. For example,
a loop such as "for(;;) foo()" is initially expanded to RTL as:
goto L1
barrier
L2: call foo
L1: goto L3
barrier
L3: goto L2
barrier
Alas when this flow graph is cleaned up, many of the interspersed
loop notes provided by the front-ends aren't correctly moved.
The patch below avoids these problems from the start. By adding
one or two simple tweaks to the RTL expansion routines, the above
loop is initially created as
L1: call foo
goto L1
barrier
which doesn't need to be tidied up, but more importantly preserves
all of the loop notes for the loop optimization pass. Amongst the
other benefits are that we no longer generate lots of RTL just to
have it deleted shortly after.
The patch below has been tested by a complete "make bootstrap"
and "make -k check", all languages except Ada and treelang, on
i686-pc-linux-gnu with no new regressions.
Ok for the gcc-3_4-basic-improvements-branch?
2002-09-10 Roger Sayle <roger@eyesopen.com>
* stmt.c (expand_end_loop): Don't rotate the loop when there
are no instructions in the test, i.e. the loop is unconditional.
(expand_exit_loop_if_false): Optimize RTL generation of loop
tests when the condition is always true or always false.
* c-semantics.c (genrtl_do_stmt): Optimize RTL generation of
do-loops when the condition is always true.
(genrtl_for_stmt): Optimize RTL generation of for-loops when
the for-expression is empty.
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.269
diff -c -3 -p -r1.269 stmt.c
*** stmt.c 14 Aug 2002 10:04:48 -0000 1.269
--- stmt.c 10 Sep 2002 05:31:51 -0000
*************** expand_end_loop ()
*** 2495,2500 ****
--- 2495,2501 ----
rtx start_label = loop_stack->data.loop.start_label;
rtx etc_note;
int eh_regions, debug_blocks;
+ bool empty_test;
/* Mark the continue-point at the top of the loop if none elsewhere. */
if (start_label == loop_stack->data.loop.continue_label)
*************** expand_end_loop ()
*** 2538,2543 ****
--- 2539,2545 ----
/* Scan insns from the top of the loop looking for the END_TOP_COND note. */
+ empty_test = true;
eh_regions = debug_blocks = 0;
for (etc_note = start_label; etc_note ; etc_note = NEXT_INSN (etc_note))
if (GET_CODE (etc_note) == NOTE)
*************** expand_end_loop ()
*** 2578,2586 ****
--- 2580,2591 ----
else if (NOTE_LINE_NUMBER (etc_note) == NOTE_INSN_BLOCK_END)
debug_blocks--;
}
+ else if (INSN_P (etc_note))
+ empty_test = false;
if (etc_note
&& optimize
+ && ! empty_test
&& eh_regions == 0
&& (debug_blocks == 0 || optimize >= 2)
&& NEXT_INSN (etc_note) != NULL_RTX
*************** expand_exit_loop_if_false (whichloop, co
*** 2699,2716 ****
struct nesting *whichloop;
tree cond;
{
! rtx label = gen_label_rtx ();
! rtx last_insn;
clear_last_expr ();
if (whichloop == 0)
whichloop = loop_stack;
if (whichloop == 0)
return 0;
/* In order to handle fixups, we actually create a conditional jump
around an unconditional branch to exit the loop. If fixups are
necessary, they go before the unconditional branch. */
do_jump (cond, NULL_RTX, label);
last_insn = get_last_insn ();
if (GET_CODE (last_insn) == CODE_LABEL)
--- 2704,2727 ----
struct nesting *whichloop;
tree cond;
{
! rtx label, last_insn;
clear_last_expr ();
if (whichloop == 0)
whichloop = loop_stack;
if (whichloop == 0)
return 0;
+
+ if (integer_onep (cond))
+ return 1;
+ if (integer_zerop (cond))
+ return expand_exit_loop (whichloop);
+
/* In order to handle fixups, we actually create a conditional jump
around an unconditional branch to exit the loop. If fixups are
necessary, they go before the unconditional branch. */
+ label = gen_label_rtx ();
do_jump (cond, NULL_RTX, label);
last_insn = get_last_insn ();
if (GET_CODE (last_insn) == CODE_LABEL)
Index: c-semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-semantics.c,v
retrieving revision 1.45
diff -c -3 -p -r1.45 c-semantics.c
*** c-semantics.c 22 Aug 2002 23:22:51 -0000 1.45
--- c-semantics.c 10 Sep 2002 05:31:51 -0000
*************** genrtl_do_stmt (t)
*** 454,459 ****
--- 454,470 ----
expand_stmt (DO_BODY (t));
expand_end_null_loop ();
}
+ else if (integer_onep (cond))
+ {
+ emit_nop ();
+ emit_line_note (input_filename, lineno);
+ expand_start_loop (1);
+
+ expand_stmt (DO_BODY (t));
+
+ emit_line_note (input_filename, lineno);
+ expand_end_loop ();
+ }
else
{
emit_nop ();
*************** genrtl_for_stmt (t)
*** 518,524 ****
/* Expand the initialization. */
emit_nop ();
emit_line_note (input_filename, lineno);
! expand_start_loop_continue_elsewhere (1);
genrtl_do_pushlevel ();
cond = expand_cond (FOR_COND (t));
--- 529,538 ----
/* Expand the initialization. */
emit_nop ();
emit_line_note (input_filename, lineno);
! if (FOR_EXPR (t))
! expand_start_loop_continue_elsewhere (1);
! else
! expand_start_loop (1);
genrtl_do_pushlevel ();
cond = expand_cond (FOR_COND (t));
*************** genrtl_for_stmt (t)
*** 540,548 ****
input_filename = saved_filename;
lineno = saved_lineno;
emit_line_note (input_filename, lineno);
- expand_loop_continue_here ();
if (FOR_EXPR (t))
! genrtl_expr_stmt (FOR_EXPR (t));
expand_end_loop ();
}
--- 554,564 ----
input_filename = saved_filename;
lineno = saved_lineno;
emit_line_note (input_filename, lineno);
if (FOR_EXPR (t))
! {
! expand_loop_continue_here ();
! genrtl_expr_stmt (FOR_EXPR (t));
! }
expand_end_loop ();
}
Roger
--
Roger Sayle, E-mail: roger@eyesopen.com
OpenEye Scientific Software, WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road, Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507. Fax: (+1) 505-473-0833