From: Richard Henderson Date: Wed, 1 Nov 2000 10:28:32 +0000 (-0800) Subject: stmt.c (expand_start_null_loop): New. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f0de0c5d1735d0e47fcd9eed2c55c7447be3db7c;p=gcc.git stmt.c (expand_start_null_loop): New. * stmt.c (expand_start_null_loop): New. (expand_end_null_loop): New. * c-semantics.c (genrtl_do_stmt): Use them. * tree.h: Declare them. From-SVN: r37186 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a29f68c5804..c8b0dff26d3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2000-11-01 Richard Henderson + + * stmt.c (expand_start_null_loop): New. + (expand_end_null_loop): New. + * c-semantics.c (genrtl_do_stmt): Use them. + * tree.h: Declare them. + 2000-11-01 Richard Henderson * cppmain.c (scan_buffer): Don't avoid paste for assembly. diff --git a/gcc/c-semantics.c b/gcc/c-semantics.c index 625f7261a92..f3210633ad9 100644 --- a/gcc/c-semantics.c +++ b/gcc/c-semantics.c @@ -487,7 +487,11 @@ genrtl_do_stmt (t) avoids cluttering the rtl with dummy loop notes, which can affect alignment of adjacent labels. */ if (integer_zerop (cond)) - expand_stmt (DO_BODY (t)); + { + expand_start_null_loop (); + expand_stmt (DO_BODY (t)); + expand_end_null_loop (); + } else { emit_nop (); diff --git a/gcc/stmt.c b/gcc/stmt.c index 92774817824..fd0647aef18 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -2294,6 +2294,30 @@ expand_start_loop_continue_elsewhere (exit_flag) return thisloop; } +/* Begin a null, aka do { } while (0) "loop". But since the contents + of said loop can still contain a break, we must frob the loop nest. */ + +struct nesting * +expand_start_null_loop () +{ + register struct nesting *thisloop = ALLOC_NESTING (); + + /* Make an entry on loop_stack for the loop we are entering. */ + + thisloop->next = loop_stack; + thisloop->all = nesting_stack; + thisloop->depth = ++nesting_depth; + thisloop->data.loop.start_label = emit_note (NULL, NOTE_INSN_DELETED); + thisloop->data.loop.end_label = gen_label_rtx (); + thisloop->data.loop.alt_end_label = NULL_RTX; + thisloop->data.loop.continue_label = NULL_RTX; + thisloop->exit_label = thisloop->data.loop.end_label; + loop_stack = thisloop; + nesting_stack = thisloop; + + return thisloop; +} + /* Specify the continuation point for a loop started with expand_start_loop_continue_elsewhere. Use this at the point in the code to which a continue statement @@ -2620,6 +2644,19 @@ expand_end_loop () last_expr_type = 0; } +/* Finish a null loop, aka do { } while (0). */ + +void +expand_end_null_loop () +{ + do_pending_stack_adjust (); + emit_label (loop_stack->data.loop.end_label); + + POPSTACK (loop_stack); + + last_expr_type = 0; +} + /* Generate a jump to the current loop's continue-point. This is usually the top of the loop, but may be specified explicitly elsewhere. If not currently inside a loop, diff --git a/gcc/tree.h b/gcc/tree.h index 17f09a13acf..2c8e1fa2cd4 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2460,8 +2460,10 @@ extern void expand_start_else PARAMS ((void)); extern void expand_start_elseif PARAMS ((tree)); extern struct nesting *expand_start_loop PARAMS ((int)); extern struct nesting *expand_start_loop_continue_elsewhere PARAMS ((int)); +extern struct nesting *expand_start_null_loop PARAMS ((void)); extern void expand_loop_continue_here PARAMS ((void)); extern void expand_end_loop PARAMS ((void)); +extern void expand_end_null_loop PARAMS ((void)); extern int expand_continue_loop PARAMS ((struct nesting *)); extern int expand_exit_loop PARAMS ((struct nesting *)); extern int expand_exit_loop_if_false PARAMS ((struct nesting *,