+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.
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. */
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
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))
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 ();
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);
}
}
+/* 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
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;
--- /dev/null
+/* 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);
+}