c-semantics.c (genrtl_do_stmt_1): New function split out from...
authorRoger Sayle <roger@eyesopen.com>
Thu, 29 May 2003 16:33:47 +0000 (16:33 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Thu, 29 May 2003 16:33:47 +0000 (16:33 +0000)
* 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.

From-SVN: r67224

gcc/ChangeLog
gcc/c-semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/duff-4.c [new file with mode: 0644]

index 9e316929f6d67777d4260fe1b959a9dac4126f37..780a9f78d4fe82339ab4c48bd56412412b85986f 100644 (file)
@@ -1,3 +1,10 @@
+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.
+
 2003-05-29  Richard Sandiford  <rsandifo@redhat.com>
 
        * config/mips/mips-protos.h (mips_output_load_label): Declare.
index a5cf7754a60d79e4592e74aebcfa9295cade9161..374e9f13dec15f597277e2a023dd9db5c6151729 100644 (file)
@@ -56,6 +56,7 @@ static tree find_reachable_label_1    PARAMS ((tree *, int *, void *));
 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.  */
 
@@ -463,14 +464,13 @@ genrtl_while_stmt (t)
   expand_end_loop ();
 }
 
-/* Generate the RTL for T, which is a DO_STMT.  */
+/* Generate the RTL for a DO_STMT with condition COND and loop BODY
+   body.  This is reused for expanding unreachable WHILE_STMTS.  */
 
-void
-genrtl_do_stmt (t)
-     tree t;
+static void
+genrtl_do_stmt_1 (cond, body)
+     tree cond, body;
 {
-  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
@@ -479,7 +479,7 @@ genrtl_do_stmt (t)
   if (!cond || integer_zerop (cond))
     {
       expand_start_null_loop ();
-      expand_stmt (DO_BODY (t));
+      expand_stmt (body);
       expand_end_null_loop ();
     }
   else if (integer_nonzerop (cond))
@@ -488,7 +488,7 @@ genrtl_do_stmt (t)
       emit_line_note (input_filename, input_line);
       expand_start_loop (1);
 
-      expand_stmt (DO_BODY (t));
+      expand_stmt (body);
 
       emit_line_note (input_filename, input_line);
       expand_end_loop ();
@@ -499,7 +499,7 @@ genrtl_do_stmt (t)
       emit_line_note (input_filename, input_line);
       expand_start_loop_continue_elsewhere (1);
 
-      expand_stmt (DO_BODY (t));
+      expand_stmt (body);
 
       expand_loop_continue_here ();
       cond = expand_cond (cond);
@@ -509,6 +509,15 @@ genrtl_do_stmt (t)
     }
 }
 
+/* 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
@@ -1059,6 +1068,13 @@ expand_unreachable_stmt (t, warn)
            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:
          {
            tree n;
index 6f47f9a04dd75af7ceb6ae26407333a10ee8407e..e61b14860986694a31cb28c415f36990467840b5 100644 (file)
@@ -1,3 +1,7 @@
+2003-05-29  Roger Sayle  <roger@eyesopen.com>
+
+       * gcc.dg/duff-4.c: New test case.
+
 2003-05-27  David Billinghurst (David.Billinghurst@riotinto.com)
 
        PR fortran/10843
diff --git a/gcc/testsuite/gcc.dg/duff-4.c b/gcc/testsuite/gcc.dg/duff-4.c
new file mode 100644 (file)
index 0000000..7032285
--- /dev/null
@@ -0,0 +1,60 @@
+/* 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);
+}