[PATCH] Improved loop lowering in c_finish_loop
Roger Sayle
roger@eyesopen.com
Sat Dec 4 20:29:00 GMT 2004
PR middle-end/12454 is a 4.0 regression caused by the algorithms used
by GCC to lower front-end trees to generic/gimple. This is actually a
class of regressions are many of the performance/memory optimizations
used by gcc 3.4.x's RTL expanders were never ported to mainline's tree
lowering routines.
I thought I'd start simple, with the patch below. This patch address
the initial generic we generate for C loops whose conditions are known
at compile-time. The effects are shown by the .t02.original dumps below;
less memory allocated, faster compile-times, fewer stack exhaustions...
SOURCE BEFORE AFTER
while(1) goto <D1123>; <D1122>:;
body(); <D1122>:; body ();
body (); goto <D1122>;
<D1123>:;
goto <D1122>;
<D1124>:;
while(0) goto <D1128>; goto <D1125>;
body(); <D1127>:; body ();
body (); <D1125>:;
<D1128>:;
goto <D1129>;
<D1129>:;
do { <D1134>:; <D1130>:;
body(); body (); body ();
} while(1); goto <D1134>; goto <D1130>;
<D1135>:;
do { body (); body ();
body();
} while(0);
The following patch has been tested on i686-pc-linux-gnu with a full
"make bootstrap", all default languages, and regression tested with a
top-level "make -k check" with no new failures.
Ok for mainline?
2004-12-04 Roger Sayle <roger@eyesopen.com>
* c-typeck.c (c_finish_loop): Improve initial implementations
for loops whose conditions are known at compile-time.
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.401
diff -c -3 -p -r1.401 c-typeck.c
*** c-typeck.c 25 Nov 2004 17:11:23 -0000 1.401
--- c-typeck.c 4 Dec 2004 15:27:20 -0000
*************** c_finish_loop (location_t start_locus, t
*** 6659,6668 ****
{
tree entry = NULL, exit = NULL, t;
! /* Detect do { ... } while (0) and don't generate loop construct. */
! if (cond && !cond_is_first && integer_zerop (cond))
! cond = NULL;
! if (cond_is_first || cond)
{
tree top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
--- 6659,6675 ----
{
tree entry = NULL, exit = NULL, t;
! /* If the condition is zero don't generate a loop construct. */
! if (cond && integer_zerop (cond))
! {
! if (cond_is_first)
! {
! t = build_and_jump (&blab);
! SET_EXPR_LOCATION (t, start_locus);
! add_stmt (t);
! }
! }
! else
{
tree top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
*************** c_finish_loop (location_t start_locus, t
*** 6671,6677 ****
then we just build a jump back to the top. */
exit = build_and_jump (&LABEL_EXPR_LABEL (top));
! if (cond)
{
/* Canonicalize the loop condition to the end. This means
generating a branch to the loop condition. Reuse the
--- 6678,6684 ----
then we just build a jump back to the top. */
exit = build_and_jump (&LABEL_EXPR_LABEL (top));
! if (cond && !integer_nonzerop (cond))
{
/* Canonicalize the loop condition to the end. This means
generating a branch to the loop condition. Reuse the
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
More information about the Gcc-patches
mailing list