diff options
Diffstat (limited to 'gcc/c-gimplify.c')
-rw-r--r-- | gcc/c-gimplify.c | 269 |
1 files changed, 0 insertions, 269 deletions
diff --git a/gcc/c-gimplify.c b/gcc/c-gimplify.c index fd4ac4ed560..bea288ea0e8 100644 --- a/gcc/c-gimplify.c +++ b/gcc/c-gimplify.c @@ -70,34 +70,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA walk back up, we check that they fit our constraints, and copy them into temporaries if not. */ -/* Local declarations. */ - -enum bc_t { bc_break = 0, bc_continue = 1 }; - -static struct c_gimplify_ctx -{ - /* For handling break and continue. */ - tree current_bc_label; - tree bc_id[2]; -} *ctxp; - -static void -push_context (void) -{ - gcc_assert (!ctxp); - ctxp = (struct c_gimplify_ctx *) xcalloc (1, sizeof (struct c_gimplify_ctx)); - ctxp->bc_id[bc_continue] = get_identifier ("continue"); - ctxp->bc_id[bc_break] = get_identifier ("break"); -} - -static void -pop_context (void) -{ - gcc_assert (ctxp && !ctxp->current_bc_label); - free (ctxp); - ctxp = NULL; -} - /* Gimplification of statement trees. */ /* Convert the tree representation of FNDECL from C frontend trees to @@ -132,9 +104,7 @@ c_genericize (tree fndecl) } /* Go ahead and gimplify for now. */ - push_context (); gimplify_function_tree (fndecl); - pop_context (); /* Dump the genericized tree IR. */ dump_function (TDI_generic, fndecl); @@ -248,225 +218,6 @@ gimplify_expr_stmt (tree *stmt_p) return GS_OK; } -/* Begin a scope which can be exited by a break or continue statement. BC - indicates which. - - Just creates a label and pushes it into the current context. */ - -static tree -begin_bc_block (enum bc_t bc) -{ - tree label = create_artificial_label (); - DECL_NAME (label) = ctxp->bc_id[bc]; - TREE_CHAIN (label) = ctxp->current_bc_label; - ctxp->current_bc_label = label; - return label; -} - -/* Finish a scope which can be exited by a break or continue statement. - LABEL was returned from the most recent call to begin_bc_block. BODY is - an expression for the contents of the scope. - - If we saw a break (or continue) in the scope, append a LABEL_EXPR to - body. Otherwise, just forget the label. */ - -static tree -finish_bc_block (tree label, tree body) -{ - gcc_assert (label == ctxp->current_bc_label); - - if (TREE_USED (label)) - { - tree t, sl = NULL; - - /* Clear the name so flow can delete the label. */ - DECL_NAME (label) = NULL_TREE; - t = build1 (LABEL_EXPR, void_type_node, label); - - append_to_statement_list (body, &sl); - append_to_statement_list (t, &sl); - body = sl; - } - - ctxp->current_bc_label = TREE_CHAIN (label); - TREE_CHAIN (label) = NULL_TREE; - return body; -} - -/* Build a GOTO_EXPR to represent a break or continue statement. BC - indicates which. */ - -static tree -build_bc_goto (enum bc_t bc) -{ - tree label; - tree target_name = ctxp->bc_id[bc]; - - /* Look for the appropriate type of label. */ - for (label = ctxp->current_bc_label; - label; - label = TREE_CHAIN (label)) - if (DECL_NAME (label) == target_name) - break; - - if (label == NULL_TREE) - { - if (bc == bc_break) - error ("break statement not within loop or switch"); - else - error ("continue statement not within loop or switch"); - - return NULL_TREE; - } - - /* Mark the label used for finish_bc_block. */ - TREE_USED (label) = 1; - return build1 (GOTO_EXPR, void_type_node, label); -} - -/* Build a generic representation of one of the C loop forms. COND is the - loop condition or NULL_TREE. BODY is the (possibly compound) statement - controlled by the loop. INCR is the increment expression of a for-loop, - or NULL_TREE. COND_IS_FIRST indicates whether the condition is - evaluated before the loop body as in while and for loops, or after the - loop body as in do-while loops. */ - -static tree -gimplify_c_loop (tree cond, tree body, tree incr, bool cond_is_first) -{ - tree top, entry, exit, cont_block, break_block, stmt_list, t; - location_t stmt_locus; - - stmt_locus = input_location; - stmt_list = NULL_TREE; - entry = NULL_TREE; - - break_block = begin_bc_block (bc_break); - cont_block = begin_bc_block (bc_continue); - - /* If condition is zero don't generate a loop construct. */ - if (cond && integer_zerop (cond)) - { - top = NULL_TREE; - exit = NULL_TREE; - if (cond_is_first) - { - t = build_bc_goto (bc_break); - append_to_statement_list (t, &stmt_list); - } - } - else - { - /* If we use a LOOP_EXPR here, we have to feed the whole thing - back through the main gimplifier to lower it. Given that we - have to gimplify the loop body NOW so that we can resolve - break/continue stmts, seems easier to just expand to gotos. */ - top = build1 (LABEL_EXPR, void_type_node, NULL_TREE); - - /* If we have an exit condition, then we build an IF with gotos either - out of the loop, or to the top of it. If there's no exit condition, - then we just build a jump back to the top. */ - exit = build_and_jump (&LABEL_EXPR_LABEL (top)); - if (cond && !integer_nonzerop (cond)) - { - t = build_bc_goto (bc_break); - exit = build3 (COND_EXPR, void_type_node, cond, exit, t); - exit = fold (exit); - gimplify_stmt (&exit); - - if (cond_is_first) - { - if (incr) - { - entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE); - t = build_and_jump (&LABEL_EXPR_LABEL (entry)); - } - else - t = build_bc_goto (bc_continue); - append_to_statement_list (t, &stmt_list); - } - } - } - - gimplify_stmt (&body); - gimplify_stmt (&incr); - - body = finish_bc_block (cont_block, body); - - append_to_statement_list (top, &stmt_list); - append_to_statement_list (body, &stmt_list); - append_to_statement_list (incr, &stmt_list); - append_to_statement_list (entry, &stmt_list); - append_to_statement_list (exit, &stmt_list); - - annotate_all_with_locus (&stmt_list, stmt_locus); - - return finish_bc_block (break_block, stmt_list); -} - -/* Gimplify a FOR_STMT node. Move the stuff in the for-init-stmt into the - prequeue and hand off to gimplify_c_loop. */ - -static enum gimplify_status -gimplify_for_stmt (tree *stmt_p, tree *pre_p) -{ - tree stmt = *stmt_p; - - if (FOR_INIT_STMT (stmt)) - gimplify_and_add (FOR_INIT_STMT (stmt), pre_p); - - *stmt_p = gimplify_c_loop (FOR_COND (stmt), FOR_BODY (stmt), - FOR_EXPR (stmt), 1); - - return GS_ALL_DONE; -} - -/* Gimplify a WHILE_STMT node. */ - -static enum gimplify_status -gimplify_while_stmt (tree *stmt_p) -{ - tree stmt = *stmt_p; - *stmt_p = gimplify_c_loop (WHILE_COND (stmt), WHILE_BODY (stmt), - NULL_TREE, 1); - return GS_ALL_DONE; -} - -/* Gimplify a DO_STMT node. */ - -static enum gimplify_status -gimplify_do_stmt (tree *stmt_p) -{ - tree stmt = *stmt_p; - *stmt_p = gimplify_c_loop (DO_COND (stmt), DO_BODY (stmt), - NULL_TREE, 0); - return GS_ALL_DONE; -} - -/* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */ - -static enum gimplify_status -gimplify_switch_stmt (tree *stmt_p) -{ - tree stmt = *stmt_p; - tree break_block, body; - location_t stmt_locus = input_location; - - break_block = begin_bc_block (bc_break); - - body = SWITCH_STMT_BODY (stmt); - if (!body) - body = build_empty_stmt (); - - *stmt_p = build3 (SWITCH_EXPR, SWITCH_STMT_TYPE (stmt), - SWITCH_STMT_COND (stmt), body, NULL_TREE); - SET_EXPR_LOCATION (*stmt_p, stmt_locus); - gimplify_stmt (stmt_p); - - *stmt_p = finish_bc_block (break_block, *stmt_p); - return GS_ALL_DONE; -} - /* Gimplification of expression trees. */ /* Gimplify a C99 compound literal expression. This just means adding the @@ -515,29 +266,9 @@ c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED) case COMPOUND_LITERAL_EXPR: return gimplify_compound_literal_expr (expr_p, pre_p); - case FOR_STMT: - return gimplify_for_stmt (expr_p, pre_p); - - case WHILE_STMT: - return gimplify_while_stmt (expr_p); - - case DO_STMT: - return gimplify_do_stmt (expr_p); - - case SWITCH_STMT: - return gimplify_switch_stmt (expr_p); - case EXPR_STMT: return gimplify_expr_stmt (expr_p); - case CONTINUE_STMT: - *expr_p = build_bc_goto (bc_continue); - return GS_ALL_DONE; - - case BREAK_STMT: - *expr_p = build_bc_goto (bc_break); - return GS_ALL_DONE; - default: return GS_UNHANDLED; } |