[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