This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Expand unreachable WHILE_STMTs like DO_STMTs (take 2)


> I don't like the code duplication here.  Instead, you could split out the
> interesting do loop code into a separate function that takes 'cond' and
> 'body' args.

The following patch implements Jason's suggestion.  Its been tested on
i686-pc-linux-gnu with a full "make bootstrap", all languages except
treelang, and regression tested with a top-level "make -k check" with
no new failures, and one fixed regression: gcc.dg/duff-2.c.

Ok for mainline?


2003-05-29  Roger Sayle  <roger@eyesopen.com>

	* c-semantics.c (genrtl_do_stmt_1): New function split out from...
	(gen_rtl_do_stmt): ... here.  Call genrtl_do_stmt_1.
	(expand_unreachable_stmt): Expand unreachable while statements
	using genrtl_do_stmt_1.

	* gcc.dg/duff-4.c: New test case.


Index: c-semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-semantics.c,v
retrieving revision 1.61
diff -c -3 -p -r1.61 c-semantics.c
*** c-semantics.c	17 May 2003 22:21:25 -0000	1.61
--- c-semantics.c	29 May 2003 11:14:25 -0000
*************** static tree find_reachable_label_1	PARAM
*** 56,61 ****
--- 56,62 ----
  static tree find_reachable_label	PARAMS ((tree));
  static bool expand_unreachable_if_stmt	PARAMS ((tree));
  static tree expand_unreachable_stmt	PARAMS ((tree, int));
+ static void genrtl_do_stmt_1		PARAMS ((tree, tree));

  /* Create an empty statement tree rooted at T.  */

*************** genrtl_while_stmt (t)
*** 463,476 ****
    expand_end_loop ();
  }

! /* Generate the RTL for T, which is a DO_STMT.  */

! void
! genrtl_do_stmt (t)
!      tree t;
  {
-   tree cond = DO_COND (t);
-
    /* Recognize the common special-case of do { ... } while (0) and do
       not emit the loop widgetry in this case.  In particular this
       avoids cluttering the rtl with dummy loop notes, which can affect
--- 464,476 ----
    expand_end_loop ();
  }

! /* Generate the RTL for a DO_STMT with condition COND and loop BODY
!    body.  This is reused for expanding unreachable WHILE_STMTS.  */

! static void
! genrtl_do_stmt_1 (cond, body)
!      tree cond, body;
  {
    /* Recognize the common special-case of do { ... } while (0) and do
       not emit the loop widgetry in this case.  In particular this
       avoids cluttering the rtl with dummy loop notes, which can affect
*************** genrtl_do_stmt (t)
*** 479,485 ****
    if (!cond || integer_zerop (cond))
      {
        expand_start_null_loop ();
!       expand_stmt (DO_BODY (t));
        expand_end_null_loop ();
      }
    else if (integer_nonzerop (cond))
--- 479,485 ----
    if (!cond || integer_zerop (cond))
      {
        expand_start_null_loop ();
!       expand_stmt (body);
        expand_end_null_loop ();
      }
    else if (integer_nonzerop (cond))
*************** genrtl_do_stmt (t)
*** 488,494 ****
        emit_line_note (input_filename, input_line);
        expand_start_loop (1);

!       expand_stmt (DO_BODY (t));

        emit_line_note (input_filename, input_line);
        expand_end_loop ();
--- 488,494 ----
        emit_line_note (input_filename, input_line);
        expand_start_loop (1);

!       expand_stmt (body);

        emit_line_note (input_filename, input_line);
        expand_end_loop ();
*************** genrtl_do_stmt (t)
*** 499,505 ****
        emit_line_note (input_filename, input_line);
        expand_start_loop_continue_elsewhere (1);

!       expand_stmt (DO_BODY (t));

        expand_loop_continue_here ();
        cond = expand_cond (cond);
--- 499,505 ----
        emit_line_note (input_filename, input_line);
        expand_start_loop_continue_elsewhere (1);

!       expand_stmt (body);

        expand_loop_continue_here ();
        cond = expand_cond (cond);
*************** genrtl_do_stmt (t)
*** 509,514 ****
--- 509,523 ----
      }
  }

+ /* Generate the RTL for T, which is a DO_STMT.  */
+
+ void
+ genrtl_do_stmt (t)
+      tree t;
+ {
+   genrtl_do_stmt_1 (DO_COND (t), DO_BODY (t));
+ }
+
  /* Build the node for a return statement and return it.  */

  tree
*************** expand_unreachable_stmt (t, warn)
*** 1058,1063 ****
--- 1067,1079 ----
  	  if (expand_unreachable_if_stmt (t))
  	    return TREE_CHAIN (t);
  	  break;
+
+ 	case WHILE_STMT:
+ 	  /* If the start of a while statement is unreachable, there is
+ 	     no need to rotate the loop, instead the WHILE_STMT can be
+ 	     expanded like a DO_STMT.  */
+ 	  genrtl_do_stmt_1 (WHILE_COND (t), WHILE_BODY (t));
+ 	  return TREE_CHAIN (t);

  	case COMPOUND_STMT:
  	  {


/* Duff's device is legal C; test to make sure the compiler
   doesn't complain about it.

   Roger Sayle <roger@eyesopen.com>
   Derived from duff-2.c.  */

/* { dg-do run } */
/* { dg-options "-O2" } */

extern void abort (void);
extern void exit (int);

#if __INT_MAX__ >= 2147483647
/* At least 32-bit integers. */
typedef int type32;
#else
typedef long type32;
#endif

type32
cksum (const unsigned char *src, unsigned long size)
{
  type32 ck = 0;

  switch (size & 3)
    {
    do
      {
    case 0:
	ck ^= (type32)*src++ << 24;
	--size;
    case 3:
	ck ^= (type32)*src++ << 16;
	--size;
    case 2:
	ck ^= (type32)*src++ << 8;
	--size;
    case 1:
	ck ^= (type32)*src++;
	--size;
      }
    while (size > 0);
    }

  return ck;
}

const char testpat[] = "The quick brown fox jumped over the lazy dog.";

int
main()
{
  type32 ck;

  ck = cksum ((const unsigned char *) testpat, sizeof (testpat));
  if (ck != 925902908)
    abort ();

  exit (0);
}


Roger
--


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]