aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/c-semantics.c34
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/duff-4.c60
4 files changed, 96 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9e31692..780a9f7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/c-semantics.c b/gcc/c-semantics.c
index a5cf775..374e9f1 100644
--- a/gcc/c-semantics.c
+++ b/gcc/c-semantics.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6f47f9a..e61b148 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..7032285
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/duff-4.c
@@ -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);
+}