diff options
-rw-r--r-- | gcc/ChangeLog | 48 | ||||
-rw-r--r-- | gcc/ada/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/ada/trans.c | 17 | ||||
-rw-r--r-- | gcc/calls.c | 16 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/dojump.c | 6 | ||||
-rw-r--r-- | gcc/except.c | 332 | ||||
-rw-r--r-- | gcc/except.h | 46 | ||||
-rw-r--r-- | gcc/expr.c | 245 | ||||
-rw-r--r-- | gcc/fold-const.c | 9 | ||||
-rw-r--r-- | gcc/function.c | 9 | ||||
-rw-r--r-- | gcc/gengtype.c | 47 | ||||
-rw-r--r-- | gcc/gimplify.c | 14 | ||||
-rw-r--r-- | gcc/integrate.c | 1 | ||||
-rw-r--r-- | gcc/java/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/java/expr.c | 270 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 3 | ||||
-rw-r--r-- | gcc/java/lang.c | 2 | ||||
-rw-r--r-- | gcc/print-tree.c | 2 | ||||
-rw-r--r-- | gcc/stmt.c | 873 | ||||
-rw-r--r-- | gcc/tree-pretty-print.c | 4 | ||||
-rw-r--r-- | gcc/tree.c | 5 | ||||
-rw-r--r-- | gcc/tree.def | 22 | ||||
-rw-r--r-- | gcc/tree.h | 17 |
25 files changed, 114 insertions, 1891 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7ea2a22..6ab7238 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,51 @@ +2004-07-08 Richard Henderson <rth@redhat.com> + + * except.c (expand_eh_region_start, expand_eh_region_end, + expand_eh_handler, expand_eh_region_end_cleanup, + expand_start_all_catch, expand_start_catch, expand_end_catch, + expand_end_all_catch, expand_eh_region_end_allowed, + expand_eh_region_end_must_not_throw, expand_eh_region_end_throw, + expand_eh_region_end_fixup): Remove. + * stmt.c (struct nesting): Remove stack_level, innermost_stack_block, + cleanups, outer_cleanups, label_chain, exception_region. + (struct goto_fixup): Remove stack_level, cleanup_list_list. + (struct label_chain): Remove. + (struct stmt_status): Remove x_stack_block_stack. + (stack_block_stack, expand_goto_internal, expand_fixup, expand_fixups, + fixup_gotos, save_stack_pointer, expand_decl_cleanup, + expand_decl_cleanup_eh, expand_cleanups, start_cleanup_deferral, + end_cleanup_deferral, last_cleanup_this_contour, + containing_blocks_have_cleanups_or_stack_level, + any_pending_cleanups): Remove. + (expand_null_return_1): Take no arguments. + (expand_label, expand_naked_return, expand_return, + expand_start_bindings_and_block, expand_end_bindings, expand_decl, + expand_anon_union_decl, expand_start_case, pushcase, pushcase_range, + expand_end_case_type): Don't use any of them. + * calls.c (expand_call): Likewise. + * dojump.c (do_jump): Likewise. + * function.c (expand_function_end): Likewise. + * expr.c (store_expr, expand_expr_real_1): Likewise. + (safe_from_p): Don't handle WITH_CLEANUP_EXPR, CLEANUP_POINT_EXPR. + (expand_expr_real_1): Don't handle WITH_CLEANUP_EXPR, + CLEANUP_POINT_EXPR, TARGET_EXPR, TRY_CATCH_EXPR, CATCH_EXPR, + EH_FILTER_EXPR, TRY_FINALLY_EXPR, GOTO_SUBROUTINE_EXPR. + * fold-const.c (fold_checksum_tree): Use first_rtl_op. + * gengtype.c (adjust_field_tree_exp): Remove rtl op handling. + * gimplify.c (gimplify_cleanup_point_expr): Renumber operands + for WITH_CLEANUP_EXPR. + (gimple_push_cleanup): Likewise. + * integrate.c (copy_decl_for_inlining): Don't DECL_TOO_LATE. + * print-tree.c (print_node): Likewise. + * tree-pretty-print.c (dump_generic_node): Remove GOTO_SUBROUTINE_EXPR. + * tree.c (first_rtl_op): Always just TREE_CODE_LENGTH. + (has_cleanups): Remove GOTO_SUBROUTINE_EXPR. + * tree.def (WITH_CLEANUP_EXPR): Remove op1 and op2. + (GOTO_SUBROUTINE_EXPR): Remove. + * tree.h (WITH_CLEANUP_EXPR_RTL): Remove. + (DECL_TOO_LATE): Remove. + * except.h, tree.h: Update decls. + 2004-07-08 Paolo Bonzini <bonzini@gnu.org> * explow.c (optimize_save_area_alloca): Do not accept parameters. diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index c2be151..c4c7c5f 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2004-07-08 Richard Henderson <rth@redhat.com> + + * trans.c (gnat_to_gnu <N_Handled_Sequence_Of_Statements>): Update + commentary. + 2004-07-06 Vincent Celier <celier@gnat.com> * vms_conv.ads: Minor reformatting. diff --git a/gcc/ada/trans.c b/gcc/ada/trans.c index 6135daf..da75a35 100644 --- a/gcc/ada/trans.c +++ b/gcc/ada/trans.c @@ -3236,20 +3236,9 @@ gnat_to_gnu (Node_Id gnat_node) case N_Handled_Sequence_Of_Statements: /* The GCC exception handling mechanism can handle both ZCX and SJLJ - schemes and we have our own SJLJ mechanism. To call the GCC - mechanism, we first call expand_eh_region_start if there is at least - one handler associated with the region. We then generate code for - the region and call expand_start_all_catch to announce that the - associated handlers are going to be generated. - - For each handler we call expand_start_catch, generate code for the - handler, and then call expand_end_catch. - - After all the handlers, we call expand_end_all_catch. - - Here we deal with the region level calls and the - N_Exception_Handler branch deals with the handler level calls - (start_catch/end_catch). + schemes and we have our own SJLJ mechanism. To call the GCC + mechanism, we call add_cleanup, and when we leave the binding, + end_stmt_group will create the TRY_FINALLY_EXPR. ??? The region level calls down there have been specifically put in place for a ZCX context and currently the order in which things are diff --git a/gcc/calls.c b/gcc/calls.c index 3f427fb..b1c226d 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -2263,7 +2263,6 @@ expand_call (tree exp, rtx target, int ignore) || !flag_optimize_sibling_calls || !rtx_equal_function_value_matters || current_nesting_level () == 0 - || any_pending_cleanups () || args_size.var || lookup_stmt_eh_region (exp) >= 0) try_tail_call = 0; @@ -2343,10 +2342,6 @@ expand_call (tree exp, rtx target, int ignore) /* Do the same for the function address if it is an expression. */ if (!fndecl) addr = fix_unsafe_tree (addr); - /* Expanding one of those dangerous arguments could have added - cleanups, but otherwise give it a whirl. */ - if (any_pending_cleanups ()) - try_tail_call = 0; } @@ -2959,16 +2954,6 @@ expand_call (tree exp, rtx target, int ignore) /* If value type not void, return an rtx for the value. */ - /* If there are cleanups to be called, don't use a hard reg as target. - We need to double check this and see if it matters anymore. */ - if (any_pending_cleanups ()) - { - if (target && REG_P (target) - && REGNO (target) < FIRST_PSEUDO_REGISTER) - target = 0; - sibcall_failure = 1; - } - if (TYPE_MODE (TREE_TYPE (exp)) == VOIDmode || ignore) target = const0_rtx; @@ -3222,7 +3207,6 @@ expand_call (tree exp, rtx target, int ignore) clear_pending_stack_adjust (); emit_insn (gen_rtx_CLOBBER (VOIDmode, stack_pointer_rtx)); emit_move_insn (virtual_stack_dynamic_rtx, stack_pointer_rtx); - save_stack_pointer (); } return target; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5d2aae0..d04b5af 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,7 @@ +2004-07-08 Richard Henderson <rth@redhat.com> + + * cp-tree.h (expand_eh_spec_block): Remove. + 2004-07-07 Mark Mitchell <mark@codesourcery.com> * cp-tree.h (saved_scope): Remove x_previous_class_type and diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 15cfd84..59133c1 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3833,7 +3833,6 @@ extern void init_exception_processing (void); extern tree expand_start_catch_block (tree); extern void expand_end_catch_block (void); extern void expand_builtin_throw (void); -extern void expand_eh_spec_block (tree); extern void expand_exception_blocks (void); extern tree build_exc_ptr (void); extern tree build_throw (tree); diff --git a/gcc/dojump.c b/gcc/dojump.c index 27dc580..0ce2719 100644 --- a/gcc/dojump.c +++ b/gcc/dojump.c @@ -290,18 +290,14 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label) if (if_false_label == 0) if_false_label = drop_through_label = gen_label_rtx (); do_jump (TREE_OPERAND (exp, 0), if_false_label, NULL_RTX); - start_cleanup_deferral (); do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label); - end_cleanup_deferral (); break; case TRUTH_ORIF_EXPR: if (if_true_label == 0) if_true_label = drop_through_label = gen_label_rtx (); do_jump (TREE_OPERAND (exp, 0), NULL_RTX, if_true_label); - start_cleanup_deferral (); do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label); - end_cleanup_deferral (); break; case COMPOUND_EXPR: @@ -362,7 +358,6 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label) do_jump (TREE_OPERAND (exp, 0), label1, NULL_RTX); - start_cleanup_deferral (); /* Now the THEN-expression. */ do_jump (TREE_OPERAND (exp, 1), if_false_label ? if_false_label : drop_through_label, @@ -375,7 +370,6 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label) do_jump (TREE_OPERAND (exp, 2), if_false_label ? if_false_label : drop_through_label, if_true_label ? if_true_label : drop_through_label); - end_cleanup_deferral (); } break; diff --git a/gcc/except.c b/gcc/except.c index 5a2fe12..c66ad32 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -260,8 +260,6 @@ static hashval_t t2r_hash (const void *); static void add_type_for_runtime (tree); static tree lookup_type_for_runtime (tree); -static struct eh_region *expand_eh_region_end (void); - static void resolve_fixup_regions (void); static void remove_fixup_regions (void); static void remove_unreachable_regions (rtx); @@ -574,141 +572,6 @@ set_eh_region_tree_label (struct eh_region *region, tree lab) region->tree_label = lab; } -/* Start an exception handling region. All instructions emitted - after this point are considered to be part of the region until - expand_eh_region_end is invoked. */ - -void -expand_eh_region_start (void) -{ - struct eh_region *new; - rtx note; - - if (! doing_eh (0)) - return; - - new = gen_eh_region (ERT_UNKNOWN, cfun->eh->cur_region); - cfun->eh->cur_region = new; - - /* Create a note marking the start of this region. */ - note = emit_note (NOTE_INSN_EH_REGION_BEG); - NOTE_EH_HANDLER (note) = new->region_number; -} - -/* Common code to end a region. Returns the region just ended. */ - -static struct eh_region * -expand_eh_region_end (void) -{ - struct eh_region *cur_region = cfun->eh->cur_region; - rtx note; - - /* Create a note marking the end of this region. */ - note = emit_note (NOTE_INSN_EH_REGION_END); - NOTE_EH_HANDLER (note) = cur_region->region_number; - - /* Pop. */ - cfun->eh->cur_region = cur_region->outer; - - return cur_region; -} - -/* Expand HANDLER, which is the operand 1 of a TRY_CATCH_EXPR. Catch - blocks and C++ exception-specifications are handled specially. */ - -void -expand_eh_handler (tree handler) -{ - tree inner = expr_first (handler); - - switch (TREE_CODE (inner)) - { - case CATCH_EXPR: - expand_start_all_catch (); - expand_expr (handler, const0_rtx, VOIDmode, 0); - expand_end_all_catch (); - break; - - case EH_FILTER_EXPR: - if (EH_FILTER_MUST_NOT_THROW (handler)) - expand_eh_region_end_must_not_throw (EH_FILTER_FAILURE (handler)); - else - expand_eh_region_end_allowed (EH_FILTER_TYPES (handler), - EH_FILTER_FAILURE (handler)); - break; - - default: - expand_eh_region_end_cleanup (handler); - break; - } -} - -/* End an exception handling region for a cleanup. HANDLER is an - expression to expand for the cleanup. */ - -void -expand_eh_region_end_cleanup (tree handler) -{ - struct eh_region *region; - tree protect_cleanup_actions; - rtx around_label; - rtx data_save[2]; - - if (! doing_eh (0)) - return; - - region = expand_eh_region_end (); - region->type = ERT_CLEANUP; - region->label = gen_label_rtx (); - region->u.cleanup.exp = handler; - region->u.cleanup.prev_try = cfun->eh->try_region; - - around_label = gen_label_rtx (); - emit_jump (around_label); - - emit_label (region->label); - - if (flag_non_call_exceptions || region->may_contain_throw) - { - /* Give the language a chance to specify an action to be taken if an - exception is thrown that would propagate out of the HANDLER. */ - protect_cleanup_actions - = (lang_protect_cleanup_actions - ? (*lang_protect_cleanup_actions) () - : NULL_TREE); - - if (protect_cleanup_actions) - expand_eh_region_start (); - - /* In case this cleanup involves an inline destructor with a try block in - it, we need to save the EH return data registers around it. */ - data_save[0] = gen_reg_rtx (ptr_mode); - emit_move_insn (data_save[0], get_exception_pointer (cfun)); - data_save[1] = gen_reg_rtx (word_mode); - emit_move_insn (data_save[1], get_exception_filter (cfun)); - - expand_expr (handler, const0_rtx, VOIDmode, 0); - - emit_move_insn (cfun->eh->exc_ptr, data_save[0]); - emit_move_insn (cfun->eh->filter, data_save[1]); - - if (protect_cleanup_actions) - expand_eh_region_end_must_not_throw (protect_cleanup_actions); - - /* We need any stack adjustment complete before the around_label. */ - do_pending_stack_adjust (); - } - - /* We delay the generation of the _Unwind_Resume until we generate - landing pads. We emit a marker here so as to get good control - flow data in the meantime. */ - region->resume - = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number)); - emit_barrier (); - - emit_label (around_label); -} - void expand_resx_expr (tree exp) { @@ -719,197 +582,6 @@ expand_resx_expr (tree exp) emit_barrier (); } -/* End an exception handling region for a try block, and prepares - for subsequent calls to expand_start_catch. */ - -void -expand_start_all_catch (void) -{ - struct eh_region *region; - - if (! doing_eh (1)) - return; - - region = expand_eh_region_end (); - region->type = ERT_TRY; - region->u.try.prev_try = cfun->eh->try_region; - region->u.try.continue_label = gen_label_rtx (); - - cfun->eh->try_region = region; - - emit_jump (region->u.try.continue_label); -} - -/* Begin a catch clause. TYPE is the type caught, a list of such - types, (in the case of Java) an ADDR_EXPR which points to the - runtime type to match, or null if this is a catch-all - clause. Providing a type list enables to associate the catch region - with potentially several exception types, which is useful e.g. for - Ada. */ - -void -expand_start_catch (tree type_or_list) -{ - struct eh_region *c; - rtx note; - - if (! doing_eh (0)) - return; - - c = gen_eh_region_catch (cfun->eh->try_region, type_or_list); - cfun->eh->cur_region = c; - - c->label = gen_label_rtx (); - emit_label (c->label); - - note = emit_note (NOTE_INSN_EH_REGION_BEG); - NOTE_EH_HANDLER (note) = c->region_number; -} - -/* End a catch clause. Control will resume after the try/catch block. */ - -void -expand_end_catch (void) -{ - if (! doing_eh (0)) - return; - - expand_eh_region_end (); - emit_jump (cfun->eh->try_region->u.try.continue_label); -} - -/* End a sequence of catch handlers for a try block. */ - -void -expand_end_all_catch (void) -{ - struct eh_region *try_region; - - if (! doing_eh (0)) - return; - - try_region = cfun->eh->try_region; - cfun->eh->try_region = try_region->u.try.prev_try; - - emit_label (try_region->u.try.continue_label); -} - -/* End an exception region for an exception type filter. ALLOWED is a - TREE_LIST of types to be matched by the runtime. FAILURE is an - expression to invoke if a mismatch occurs. - - ??? We could use these semantics for calls to rethrow, too; if we can - see the surrounding catch clause, we know that the exception we're - rethrowing satisfies the "filter" of the catch type. */ - -void -expand_eh_region_end_allowed (tree allowed, tree failure) -{ - struct eh_region *region; - rtx around_label; - - if (! doing_eh (0)) - return; - - region = expand_eh_region_end (); - region->type = ERT_ALLOWED_EXCEPTIONS; - region->u.allowed.type_list = allowed; - region->label = gen_label_rtx (); - - for (; allowed ; allowed = TREE_CHAIN (allowed)) - add_type_for_runtime (TREE_VALUE (allowed)); - - /* We must emit the call to FAILURE here, so that if this function - throws a different exception, that it will be processed by the - correct region. */ - - around_label = gen_label_rtx (); - emit_jump (around_label); - - emit_label (region->label); - expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL); - /* We must adjust the stack before we reach the AROUND_LABEL because - the call to FAILURE does not occur on all paths to the - AROUND_LABEL. */ - do_pending_stack_adjust (); - - emit_label (around_label); -} - -/* End an exception region for a must-not-throw filter. FAILURE is an - expression invoke if an uncaught exception propagates this far. - - This is conceptually identical to expand_eh_region_end_allowed with - an empty allowed list (if you passed "std::terminate" instead of - "__cxa_call_unexpected"), but they are represented differently in - the C++ LSDA. */ - -void -expand_eh_region_end_must_not_throw (tree failure) -{ - struct eh_region *region; - rtx around_label; - - if (! doing_eh (0)) - return; - - region = expand_eh_region_end (); - region->type = ERT_MUST_NOT_THROW; - region->label = gen_label_rtx (); - - /* We must emit the call to FAILURE here, so that if this function - throws a different exception, that it will be processed by the - correct region. */ - - around_label = gen_label_rtx (); - emit_jump (around_label); - - emit_label (region->label); - expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL); - - emit_label (around_label); -} - -/* End an exception region for a throw. No handling goes on here, - but it's the easiest way for the front-end to indicate what type - is being thrown. */ - -void -expand_eh_region_end_throw (tree type) -{ - struct eh_region *region; - - if (! doing_eh (0)) - return; - - region = expand_eh_region_end (); - region->type = ERT_THROW; - region->u.throw.type = type; -} - -/* End a fixup region. Within this region the cleanups for the immediately - enclosing region are _not_ run. This is used for goto cleanup to avoid - destroying an object twice. - - This would be an extraordinarily simple prospect, were it not for the - fact that we don't actually know what the immediately enclosing region - is. This surprising fact is because expand_cleanups is currently - generating a sequence that it will insert somewhere else. We collect - the proper notion of "enclosing" in convert_from_eh_region_ranges. */ - -void -expand_eh_region_end_fixup (tree handler) -{ - struct eh_region *fixup; - - if (! doing_eh (0)) - return; - - fixup = expand_eh_region_end (); - fixup->type = ERT_FIXUP; - fixup->u.fixup.cleanup_exp = handler; -} - /* Note that the current EH region (if any) may contain a throw, or a call to a function which itself may contain a throw. */ @@ -962,9 +634,7 @@ get_exception_filter (struct function *fun) /* This section is for the exception handling specific optimization pass. */ -/* Random access the exception region tree. It's just as simple to - collect the regions this way as in expand_eh_region_start, but - without having to realloc memory. */ +/* Random access the exception region tree. */ void collect_eh_region_array (void) diff --git a/gcc/except.h b/gcc/except.h index 6f6a681..7a58990 100644 --- a/gcc/except.h +++ b/gcc/except.h @@ -35,52 +35,6 @@ struct eh_region; /* Test: is exception handling turned on? */ extern int doing_eh (int); -/* Start an exception handling region. All instructions emitted after - this point are considered to be part of the region until an - expand_eh_region_end variant is invoked. */ -extern void expand_eh_region_start (void); - -/* End an exception handling region for a cleanup. HANDLER is an - expression to expand for the cleanup. */ -extern void expand_eh_region_end_cleanup (tree); - -/* End an exception handling region for a try block, and prepares - for subsequent calls to expand_start_catch. */ -extern void expand_start_all_catch (void); - -/* Begin a catch clause. TYPE is an object to be matched by the - runtime, or a list of such objects, or null if this is a catch-all - clause. */ -extern void expand_start_catch (tree); - -/* End a catch clause. Control will resume after the try/catch block. */ -extern void expand_end_catch (void); - -/* End a sequence of catch handlers for a try block. */ -extern void expand_end_all_catch (void); - -/* End an exception region for an exception type filter. ALLOWED is a - TREE_LIST of TREE_VALUE objects to be matched by the runtime. - FAILURE is a function to invoke if a mismatch occurs. */ -extern void expand_eh_region_end_allowed (tree, tree); - -/* End an exception region for a must-not-throw filter. FAILURE is a - function to invoke if an uncaught exception propagates this far. */ -extern void expand_eh_region_end_must_not_throw (tree); - -/* End an exception region for a throw. No handling goes on here, - but it's the easiest way for the front-end to indicate what type - is being thrown. */ -extern void expand_eh_region_end_throw (tree); - -/* End a fixup region. Within this region the cleanups for the immediately - enclosing region are _not_ run. This is used for goto cleanup to avoid - destroying an object twice. */ -extern void expand_eh_region_end_fixup (tree); - -/* End some sort of EH region, depending on the argument. */ -extern void expand_eh_handler (tree); - /* Note that the current EH region (if any) may contain a throw, or a call to a function which itself may contain a throw. */ extern void note_eh_region_may_contain_throw (struct eh_region *); @@ -4071,16 +4071,12 @@ store_expr (tree exp, rtx target, int want_value) do_pending_stack_adjust (); NO_DEFER_POP; jumpifnot (TREE_OPERAND (exp, 0), lab1); - start_cleanup_deferral (); store_expr (TREE_OPERAND (exp, 1), target, want_value & 2); - end_cleanup_deferral (); emit_queue (); emit_jump_insn (gen_jump (lab2)); emit_barrier (); emit_label (lab1); - start_cleanup_deferral (); store_expr (TREE_OPERAND (exp, 2), target, want_value & 2); - end_cleanup_deferral (); emit_queue (); emit_label (lab2); OK_DEFER_POP; @@ -6042,10 +6038,10 @@ safe_from_p (rtx x, tree exp, int top_p) break; case WITH_CLEANUP_EXPR: - exp_rtl = WITH_CLEANUP_EXPR_RTL (exp); - break; - case CLEANUP_POINT_EXPR: + /* Lowered by gimplify.c. */ + abort (); + case SAVE_EXPR: return safe_from_p (x, TREE_OPERAND (exp, 0), 0); @@ -7345,36 +7341,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, case OBJ_TYPE_REF: return expand_expr (OBJ_TYPE_REF_EXPR (exp), target, tmode, modifier); - case WITH_CLEANUP_EXPR: - if (WITH_CLEANUP_EXPR_RTL (exp) == 0) - { - WITH_CLEANUP_EXPR_RTL (exp) - = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier); - expand_decl_cleanup_eh (NULL_TREE, TREE_OPERAND (exp, 1), - CLEANUP_EH_ONLY (exp)); - - /* That's it for this cleanup. */ - TREE_OPERAND (exp, 1) = 0; - } - return WITH_CLEANUP_EXPR_RTL (exp); - - case CLEANUP_POINT_EXPR: - { - /* Start a new binding layer that will keep track of all cleanup - actions to be performed. */ - expand_start_bindings (2); - - target_temp_slot_level = temp_slot_level; - - op0 = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier); - /* If we're going to use this value, load it up now. */ - if (! ignore) - op0 = force_not_mem (op0); - preserve_temp_slots (op0); - expand_end_bindings (NULL_TREE, 0, 0); - } - return op0; - case CALL_EXPR: /* Check for a built-in function. */ if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR @@ -8180,15 +8146,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, tree then_ = TREE_OPERAND (exp, 1); tree else_ = TREE_OPERAND (exp, 2); - /* If we do not have any pending cleanups or stack_levels - to restore, and at least one arm of the COND_EXPR is a - GOTO_EXPR to a local label, then we can emit more efficient - code by using jumpif/jumpifnot instead of the 'if' machinery. */ - if (! optimize - || containing_blocks_have_cleanups_or_stack_level ()) - ; - else if (TREE_CODE (then_) == GOTO_EXPR - && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL) + if (TREE_CODE (then_) == GOTO_EXPR + && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL) { jumpif (pred, label_rtx (GOTO_DESTINATION (then_))); return expand_expr (else_, const0_rtx, VOIDmode, 0); @@ -8202,7 +8161,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, /* Just use the 'if' machinery. */ expand_start_cond (pred, 0); - start_cleanup_deferral (); expand_expr (then_, const0_rtx, VOIDmode, 0); exp = else_; @@ -8225,7 +8183,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, expand_start_else (); expand_expr (exp, const0_rtx, VOIDmode, 0); } - end_cleanup_deferral (); expand_end_cond (); return const0_rtx; } @@ -8422,7 +8379,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, else jumpifnot (TREE_OPERAND (exp, 0), op0); - start_cleanup_deferral (); if (binary_op && temp == 0) /* Just touch the other operand. */ expand_expr (TREE_OPERAND (binary_op, 1), @@ -8458,7 +8414,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, modifier == EXPAND_STACK_PARM ? 2 : 0); jumpif (TREE_OPERAND (exp, 0), op0); - start_cleanup_deferral (); if (TREE_TYPE (TREE_OPERAND (exp, 2)) != void_type_node) store_expr (TREE_OPERAND (exp, 2), temp, modifier == EXPAND_STACK_PARM ? 2 : 0); @@ -8483,7 +8438,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, modifier == EXPAND_STACK_PARM ? 2 : 0); jumpifnot (TREE_OPERAND (exp, 0), op0); - start_cleanup_deferral (); if (TREE_TYPE (TREE_OPERAND (exp, 1)) != void_type_node) store_expr (TREE_OPERAND (exp, 1), temp, modifier == EXPAND_STACK_PARM ? 2 : 0); @@ -8497,8 +8451,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, op1 = gen_label_rtx (); jumpifnot (TREE_OPERAND (exp, 0), op0); - start_cleanup_deferral (); - /* One branch of the cond can be void, if it never returns. For example A ? throw : E */ if (temp != 0 @@ -8508,12 +8460,10 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, else expand_expr (TREE_OPERAND (exp, 1), ignore ? const0_rtx : NULL_RTX, VOIDmode, 0); - end_cleanup_deferral (); emit_queue (); emit_jump_insn (gen_jump (op1)); emit_barrier (); emit_label (op0); - start_cleanup_deferral (); if (temp != 0 && TREE_TYPE (TREE_OPERAND (exp, 2)) != void_type_node) store_expr (TREE_OPERAND (exp, 2), temp, @@ -8523,8 +8473,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, ignore ? const0_rtx : NULL_RTX, VOIDmode, 0); } - end_cleanup_deferral (); - emit_queue (); emit_label (op1); OK_DEFER_POP; @@ -8532,98 +8480,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, return temp; } - case TARGET_EXPR: - { - /* Something needs to be initialized, but we didn't know - where that thing was when building the tree. For example, - it could be the return value of a function, or a parameter - to a function which lays down in the stack, or a temporary - variable which must be passed by reference. - - We guarantee that the expression will either be constructed - or copied into our original target. */ - - tree slot = TREE_OPERAND (exp, 0); - tree cleanups = NULL_TREE; - tree exp1; - - if (TREE_CODE (slot) != VAR_DECL) - abort (); - - if (! ignore) - target = original_target; - - /* Set this here so that if we get a target that refers to a - register variable that's already been used, put_reg_into_stack - knows that it should fix up those uses. */ - TREE_USED (slot) = 1; - - if (target == 0) - { - if (DECL_RTL_SET_P (slot)) - { - target = DECL_RTL (slot); - /* If we have already expanded the slot, so don't do - it again. (mrs) */ - if (TREE_OPERAND (exp, 1) == NULL_TREE) - return target; - } - else - { - target = assign_temp (type, 2, 0, 1); - SET_DECL_RTL (slot, target); - - /* Since SLOT is not known to the called function - to belong to its stack frame, we must build an explicit - cleanup. This case occurs when we must build up a reference - to pass the reference as an argument. In this case, - it is very likely that such a reference need not be - built here. */ - - if (TREE_OPERAND (exp, 2) == 0) - TREE_OPERAND (exp, 2) - = lang_hooks.maybe_build_cleanup (slot); - cleanups = TREE_OPERAND (exp, 2); - } - } - else - { - /* This case does occur, when expanding a parameter which - needs to be constructed on the stack. The target - is the actual stack address that we want to initialize. - The function we call will perform the cleanup in this case. */ - - /* If we have already assigned it space, use that space, - not target that we were passed in, as our target - parameter is only a hint. */ - if (DECL_RTL_SET_P (slot)) - { - target = DECL_RTL (slot); - /* If we have already expanded the slot, so don't do - it again. (mrs) */ - if (TREE_OPERAND (exp, 1) == NULL_TREE) - return target; - } - else - SET_DECL_RTL (slot, target); - } - - exp1 = TREE_OPERAND (exp, 3) = TREE_OPERAND (exp, 1); - /* Mark it as expanded. */ - TREE_OPERAND (exp, 1) = NULL_TREE; - - if (VOID_TYPE_P (TREE_TYPE (exp1))) - /* If the initializer is void, just expand it; it will initialize - the object directly. */ - expand_expr (exp1, const0_rtx, VOIDmode, 0); - else - store_expr (exp1, target, modifier == EXPAND_STACK_PARM ? 2 : 0); - - expand_decl_cleanup_eh (NULL_TREE, cleanups, CLEANUP_EH_ONLY (exp)); - - return target; - } - case INIT_EXPR: { tree lhs = TREE_OPERAND (exp, 0); @@ -8927,94 +8783,17 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, return const0_rtx; case TRY_CATCH_EXPR: - { - tree handler = TREE_OPERAND (exp, 1); - - expand_eh_region_start (); - op0 = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, 0); - expand_eh_handler (handler); - - return op0; - } - case CATCH_EXPR: - expand_start_catch (CATCH_TYPES (exp)); - expand_expr (CATCH_BODY (exp), const0_rtx, VOIDmode, 0); - expand_end_catch (); - return const0_rtx; - case EH_FILTER_EXPR: - /* Should have been handled in expand_eh_handler. */ - abort (); - case TRY_FINALLY_EXPR: - { - tree try_block = TREE_OPERAND (exp, 0); - tree finally_block = TREE_OPERAND (exp, 1); - - if ((!optimize && lang_protect_cleanup_actions == NULL) - || unsafe_for_reeval (finally_block) > 1) - { - /* In this case, wrapping FINALLY_BLOCK in an UNSAVE_EXPR - is not sufficient, so we cannot expand the block twice. - So we play games with GOTO_SUBROUTINE_EXPR to let us - expand the thing only once. */ - /* When not optimizing, we go ahead with this form since - (1) user breakpoints operate more predictably without - code duplication, and - (2) we're not running any of the global optimizers - that would explode in time/space with the highly - connected CFG created by the indirect branching. */ - - rtx finally_label = gen_label_rtx (); - rtx done_label = gen_label_rtx (); - rtx return_link = gen_reg_rtx (Pmode); - tree cleanup = build (GOTO_SUBROUTINE_EXPR, void_type_node, - (tree) finally_label, (tree) return_link); - TREE_SIDE_EFFECTS (cleanup) = 1; - - /* Start a new binding layer that will keep track of all cleanup - actions to be performed. */ - expand_start_bindings (2); - target_temp_slot_level = temp_slot_level; - - expand_decl_cleanup (NULL_TREE, cleanup); - op0 = expand_expr (try_block, target, tmode, modifier); - - preserve_temp_slots (op0); - expand_end_bindings (NULL_TREE, 0, 0); - emit_jump (done_label); - emit_label (finally_label); - expand_expr (finally_block, const0_rtx, VOIDmode, 0); - emit_indirect_jump (return_link); - emit_label (done_label); - } - else - { - expand_start_bindings (2); - target_temp_slot_level = temp_slot_level; - - expand_decl_cleanup (NULL_TREE, finally_block); - op0 = expand_expr (try_block, target, tmode, modifier); - - preserve_temp_slots (op0); - expand_end_bindings (NULL_TREE, 0, 0); - } - - return op0; - } + /* Lowered by tree-eh.c. */ + abort (); - case GOTO_SUBROUTINE_EXPR: - { - rtx subr = (rtx) TREE_OPERAND (exp, 0); - rtx return_link = *(rtx *) &TREE_OPERAND (exp, 1); - rtx return_address = gen_label_rtx (); - emit_move_insn (return_link, - gen_rtx_LABEL_REF (Pmode, return_address)); - emit_jump (subr); - emit_label (return_address); - return const0_rtx; - } + case WITH_CLEANUP_EXPR: + case CLEANUP_POINT_EXPR: + case TARGET_EXPR: + /* Lowered by gimplify.c. */ + abort (); case VA_ARG_EXPR: return expand_builtin_va_arg (TREE_OPERAND (exp, 0), type); diff --git a/gcc/fold-const.c b/gcc/fold-const.c index ca04250..05f4a21 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -9048,7 +9048,6 @@ fold_checksum_tree (tree expr, struct md5_ctx *ctx, htab_t ht) fold_checksum_tree (TREE_TYPE (expr), ctx, ht); if (TREE_CODE_CLASS (code) != 't' && TREE_CODE_CLASS (code) != 'd') fold_checksum_tree (TREE_CHAIN (expr), ctx, ht); - len = TREE_CODE_LENGTH (code); switch (TREE_CODE_CLASS (code)) { case 'c': @@ -9085,18 +9084,12 @@ fold_checksum_tree (tree expr, struct md5_ctx *ctx, htab_t ht) } break; case 'e': - switch (code) - { - case GOTO_SUBROUTINE_EXPR: len = 0; break; - case WITH_CLEANUP_EXPR: len = 2; break; - default: break; - } - /* Fall through. */ case 'r': case '<': case '1': case '2': case 's': + len = first_rtl_op (code); for (i = 0; i < len; ++i) fold_checksum_tree (TREE_OPERAND (expr, i), ctx, ht); break; diff --git a/gcc/function.c b/gcc/function.c index d2d1dba..57d52ee 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -4549,15 +4549,6 @@ expand_function_end (void) sh mach_dep_reorg) that still try and compute their own lifetime info instead of using the general framework. */ use_return_register (); - - /* Fix up any gotos that jumped out to the outermost - binding level of the function. - Must follow emitting RETURN_LABEL. */ - - /* If you have any cleanups to do at this point, - and they need to create temporary variables, - then you will lose. */ - expand_fixups (get_insns ()); } rtx diff --git a/gcc/gengtype.c b/gcc/gengtype.c index 55a26de..3912c99 100644 --- a/gcc/gengtype.c +++ b/gcc/gengtype.c @@ -644,15 +644,6 @@ adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED) { pair_p flds; options_p nodot; - size_t i; - static const struct { - const char *name; - int first_rtl; - int num_rtl; - } data[] = { - { "GOTO_SUBROUTINE_EXPR", 0, 2 }, - { "WITH_CLEANUP_EXPR", 2, 1 }, - }; if (t->kind != TYPE_ARRAY) { @@ -684,44 +675,6 @@ adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED) flds->opt->info = ""; } - for (i = 0; i < ARRAY_SIZE (data); i++) - { - pair_p old_flds = flds; - pair_p subfields = NULL; - int r_index; - const char *sname; - - for (r_index = 0; - r_index < data[i].first_rtl + data[i].num_rtl; - r_index++) - { - pair_p old_subf = subfields; - subfields = xmalloc (sizeof (*subfields)); - subfields->next = old_subf; - subfields->name = xasprintf ("[%d]", r_index); - if (r_index < data[i].first_rtl) - subfields->type = t->u.a.p; - else - subfields->type = create_pointer (find_structure ("rtx_def", 0)); - subfields->line.file = __FILE__; - subfields->line.line = __LINE__; - subfields->opt = nodot; - } - - flds = xmalloc (sizeof (*flds)); - flds->next = old_flds; - flds->name = ""; - sname = xasprintf ("tree_exp_%s", data[i].name); - new_structure (sname, 0, &lexer_line, subfields, NULL); - flds->type = find_structure (sname, 0); - flds->line.file = __FILE__; - flds->line.line = __LINE__; - flds->opt = xmalloc (sizeof (*flds->opt)); - flds->opt->next = nodot; - flds->opt->name = "tag"; - flds->opt->info = data[i].name; - } - new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot); return find_structure ("tree_exp_subunion", 1); } diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 0493efa..f60ef89 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -3210,7 +3210,7 @@ gimplify_cleanup_point_expr (tree *expr_p, tree *pre_p) { if (tsi_one_before_end_p (iter)) { - tsi_link_before (&iter, TREE_OPERAND (wce, 1), TSI_SAME_STMT); + tsi_link_before (&iter, TREE_OPERAND (wce, 0), TSI_SAME_STMT); tsi_delink (&iter); break; } @@ -3220,8 +3220,8 @@ gimplify_cleanup_point_expr (tree *expr_p, tree *pre_p) sl = tsi_split_statement_list_after (&iter); tfe = build (TRY_FINALLY_EXPR, void_type_node, sl, NULL_TREE); - append_to_statement_list (TREE_OPERAND (wce, 1), - &TREE_OPERAND (tfe, 1)); + append_to_statement_list (TREE_OPERAND (wce, 0), + &TREE_OPERAND (tfe, 1)); *wce_p = tfe; iter = tsi_start (sl); } @@ -3285,8 +3285,7 @@ gimple_push_cleanup (tree var, tree cleanup, tree *pre_p) tree ftrue = build (MODIFY_EXPR, void_type_node, flag, boolean_true_node); cleanup = build (COND_EXPR, void_type_node, flag, cleanup, NULL); - wce = build (WITH_CLEANUP_EXPR, void_type_node, NULL_TREE, - cleanup, NULL_TREE); + wce = build (WITH_CLEANUP_EXPR, void_type_node, cleanup); append_to_statement_list (ffalse, &gimplify_ctxp->conditional_cleanups); append_to_statement_list (wce, &gimplify_ctxp->conditional_cleanups); append_to_statement_list (ftrue, pre_p); @@ -3298,12 +3297,11 @@ gimple_push_cleanup (tree var, tree cleanup, tree *pre_p) } else { - wce = build (WITH_CLEANUP_EXPR, void_type_node, NULL_TREE, - cleanup, NULL_TREE); + wce = build (WITH_CLEANUP_EXPR, void_type_node, cleanup); append_to_statement_list (wce, pre_p); } - gimplify_stmt (&TREE_OPERAND (wce, 1)); + gimplify_stmt (&TREE_OPERAND (wce, 0)); } /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */ diff --git a/gcc/integrate.c b/gcc/integrate.c index 9d4379a..9a944b4 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -160,7 +160,6 @@ copy_decl_for_inlining (tree decl, tree from_fn, tree to_fn) if (TREE_CODE (copy) == LABEL_DECL) { TREE_ADDRESSABLE (copy) = 0; - DECL_TOO_LATE (copy) = 0; } } diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index b805bf2..b0bdd58 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,10 @@ +2004-07-08 Richard Henderson <rth@redhat.com> + + * expr.c (case_identity, get_primitive_array_vtable, + java_expand_expr, emit_init_test_initialization): Remove. + * java-tree.h (java_expand_expr): Remove. + * lang.c (LANG_HOOKS_EXPAND_EXPR): Remove. + 2004-07-07 Per Bothner <per@bothner.com> * class.c (build_static_field_ref): Add a NOP_EXPR; otherwise we diff --git a/gcc/java/expr.c b/gcc/java/expr.c index f2df129..81dfde6 100644 --- a/gcc/java/expr.c +++ b/gcc/java/expr.c @@ -85,9 +85,7 @@ static void java_push_constant_from_pool (struct JCF *, int); static void java_stack_pop (int); static tree build_java_throw_out_of_bounds_exception (tree); static tree build_java_check_indexed_type (tree, tree); -static tree case_identity (tree, tree); static unsigned char peek_opcode_at_pc (struct JCF *, int, int); -static int emit_init_test_initialization (void **entry, void * ptr); static GTY(()) tree operand_type[59]; @@ -2455,241 +2453,6 @@ load_type_state (tree label) type_map [i] = TREE_VEC_ELT (vec, i); } -/* Do the expansion of a Java switch. With Gcc, switches are front-end - dependent things, but they rely on gcc routines. This function is - placed here because it uses things defined locally in parse.y. */ - -static tree -case_identity (tree t __attribute__ ((__unused__)), tree v) -{ - return v; -} - -/* Return the name of the vtable for an array of a given primitive - type. */ -static tree -get_primitive_array_vtable (tree elt) -{ - tree r; - if (elt == boolean_type_node) - r = boolean_array_vtable; - else if (elt == byte_type_node) - r = byte_array_vtable; - else if (elt == char_type_node) - r = char_array_vtable; - else if (elt == short_type_node) - r = short_array_vtable; - else if (elt == int_type_node) - r = int_array_vtable; - else if (elt == long_type_node) - r = long_array_vtable; - else if (elt == float_type_node) - r = float_array_vtable; - else if (elt == double_type_node) - r = double_array_vtable; - else - abort (); - return build_address_of (r); -} - -struct rtx_def * -java_expand_expr (tree exp, rtx target, enum machine_mode tmode, - int modifier /* Actually an enum expand_modifier. */, - rtx *alt_rtl ATTRIBUTE_UNUSED) -{ - tree current; - - abort (); - - switch (TREE_CODE (exp)) - { - - case EXPR_WITH_FILE_LOCATION: - { - rtx to_return; - const char *saved_input_filename = input_filename; - int saved_lineno = input_line; - input_filename = EXPR_WFL_FILENAME (exp); - input_line = EXPR_WFL_LINENO (exp); - if (EXPR_WFL_EMIT_LINE_NOTE (exp)) - emit_line_note (input_location); - /* Possibly avoid switching back and forth here. */ - to_return = expand_expr (EXPR_WFL_NODE (exp), target, tmode, modifier); - input_filename = saved_input_filename; - input_line = saved_lineno; - return to_return; - } - - case NEW_ARRAY_INIT: - { - rtx tmp; - tree array_type = TREE_TYPE (TREE_TYPE (exp)); - tree element_type = TYPE_ARRAY_ELEMENT (array_type); - tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type))); - HOST_WIDE_INT ilength = java_array_type_length (array_type); - tree length = build_int_2 (ilength, 0); - tree init = TREE_OPERAND (exp, 0); - tree array_decl; - - /* See if we can generate the array statically. */ - if (TREE_CONSTANT (init) && TREE_STATIC (exp) - && JPRIMITIVE_TYPE_P (element_type)) - { - tree temp, value, init_decl; - struct rtx_def *r; - START_RECORD_CONSTRUCTOR (temp, object_type_node); - PUSH_FIELD_VALUE (temp, "vtable", - get_primitive_array_vtable (element_type)); - if (! flag_hash_synchronization) - PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node); - FINISH_RECORD_CONSTRUCTOR (temp); - START_RECORD_CONSTRUCTOR (value, array_type); - PUSH_SUPER_VALUE (value, temp); - PUSH_FIELD_VALUE (value, "length", length); - PUSH_FIELD_VALUE (value, "data", init); - FINISH_RECORD_CONSTRUCTOR (value); - - init_decl = build_decl (VAR_DECL, generate_name (), array_type); - pushdecl_top_level (init_decl); - TREE_STATIC (init_decl) = 1; - DECL_INITIAL (init_decl) = value; - DECL_IGNORED_P (init_decl) = 1; - TREE_READONLY (init_decl) = 1; - /* Hash synchronization requires at least 64-bit alignment. */ - if (flag_hash_synchronization && POINTER_SIZE < 64) - DECL_ALIGN (init_decl) = 64; - rest_of_decl_compilation (init_decl, NULL, 1, 0); - TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1; - init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl); - r = expand_expr (init, target, tmode, modifier); - return r; - } - - array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp)); - expand_decl (array_decl); - tmp = expand_assignment (array_decl, - build_new_array (element_type, length), - 1); - if (TREE_CONSTANT (init) - && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type)) - { - tree init_decl; - init_decl = build_decl (VAR_DECL, generate_name (), - TREE_TYPE (init)); - pushdecl_top_level (init_decl); - TREE_STATIC (init_decl) = 1; - DECL_INITIAL (init_decl) = init; - DECL_IGNORED_P (init_decl) = 1; - TREE_READONLY (init_decl) = 1; - rest_of_decl_compilation (init_decl, NULL, 1, 0); - TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1; - init = init_decl; - } - expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld), - build_java_indirect_ref (array_type, - array_decl, flag_check_references), - data_fld, NULL_TREE), - init, 0); - return tmp; - } - case BLOCK: - if (BLOCK_EXPR_BODY (exp)) - { - tree local; - rtx last; - tree body = BLOCK_EXPR_BODY (exp); - /* Set to 1 or more when we found a static class - initialization flag. */ - int found_class_initialization_flag = 0; - - pushlevel (2); /* 2 and above */ - expand_start_bindings (0); - local = BLOCK_EXPR_DECLS (exp); - while (local) - { - tree next = TREE_CHAIN (local); - found_class_initialization_flag += - LOCAL_CLASS_INITIALIZATION_FLAG_P (local); - layout_decl (local, 0); - expand_decl (pushdecl (local)); - local = next; - } - - /* Emit initialization code for test flags if we saw one. */ - if (! always_initialize_class_p - && current_function_decl - && found_class_initialization_flag) - htab_traverse - (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), - emit_init_test_initialization, NULL); - - /* Avoid deep recursion for long block. */ - while (TREE_CODE (body) == COMPOUND_EXPR) - { - expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0); - emit_queue (); - body = TREE_OPERAND (body, 1); - } - last = expand_expr (body, NULL_RTX, VOIDmode, 0); - emit_queue (); - expand_end_bindings (getdecls (), 1, 0); - poplevel (1, 1, 0); - return last; - } - return const0_rtx; - - case CASE_EXPR: - { - tree duplicate; - if (pushcase (TREE_OPERAND (exp, 0), case_identity, - build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), - &duplicate) == 2) - { - EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp); - parse_error_context - (wfl_operator, "Duplicate case label: `%s'", - print_int_node (TREE_OPERAND (exp, 0))); - } - return const0_rtx; - } - - case DEFAULT_EXPR: - pushcase (NULL_TREE, 0, - build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL); - return const0_rtx; - - case TRY_EXPR: - /* We expand a try[-catch] block */ - - /* Expand the try block */ - expand_eh_region_start (); - expand_expr_stmt (TREE_OPERAND (exp, 0)); - expand_start_all_catch (); - - /* Expand all catch clauses (EH handlers) */ - for (current = TREE_OPERAND (exp, 1); current; - current = TREE_CHAIN (current)) - { - tree catch = TREE_OPERAND (current, 0); - tree decl = BLOCK_EXPR_DECLS (catch); - tree type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE); - - expand_start_catch (prepare_eh_table_type (type)); - expand_expr_stmt (TREE_OPERAND (current, 0)); - expand_end_catch (); - } - expand_end_all_catch (); - return const0_rtx; - - case JAVA_EXC_OBJ_EXPR: - return expand_expr (build_exception_object_ref (TREE_TYPE (exp)), - target, tmode, modifier); - - default: - internal_error ("can't expand %s", tree_code_name [TREE_CODE (exp)]); - } -} - /* Go over METHOD's bytecode and note instruction starts in instruction_bits[]. */ @@ -3448,39 +3211,6 @@ force_evaluation_order (tree node) return node; } -/* Called for every element in DECL_FUNCTION_INIT_TEST_TABLE of a - method in order to emit initialization code for each test flag. */ - -static int -emit_init_test_initialization (void **entry, void *x ATTRIBUTE_UNUSED) -{ - struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry; - tree klass = build_class_ref (ite->key); - tree rhs; - - /* If the DECL_INITIAL of the test flag is set to true, it - means that the class is already initialized the time it - is in use. */ - if (DECL_INITIAL (ite->value) == boolean_true_node) - rhs = boolean_true_node; - /* Otherwise, we initialize the class init check variable by looking - at the `state' field of the class to see if it is already - initialized. This makes things a bit faster if the class is - already initialized, which should be the common case. */ - else - rhs = build (GE_EXPR, boolean_type_node, - build (COMPONENT_REF, byte_type_node, - build1 (INDIRECT_REF, class_type_node, klass), - lookup_field (&class_type_node, - get_identifier ("state")), - NULL_TREE), - build_int_2 (JV_STATE_DONE, 0)); - - expand_expr_stmt (build (MODIFY_EXPR, boolean_type_node, - ite->value, rhs)); - return true; -} - /* EXPR_WITH_FILE_LOCATION are used to keep track of the exact location where an expression or an identifier were encountered. It is necessary for languages where the frontend parser will handle diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index a07f575..1920232 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -1333,9 +1333,6 @@ extern tree decl_constant_value (tree); extern void java_mark_class_local (tree); -#if defined(RTX_CODE) && defined (HAVE_MACHINE_MODES) -struct rtx_def * java_expand_expr (tree, rtx, enum machine_mode, int, rtx *); -#endif extern void java_inlining_merge_static_initializers (tree, void *); extern void java_inlining_map_static_initializers (tree, void *); diff --git a/gcc/java/lang.c b/gcc/java/lang.c index 2656d45..b50977e 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -224,8 +224,6 @@ struct language_function GTY(()) #define LANG_HOOKS_UNSAFE_FOR_REEVAL java_unsafe_for_reeval #undef LANG_HOOKS_MARK_ADDRESSABLE #define LANG_HOOKS_MARK_ADDRESSABLE java_mark_addressable -#undef LANG_HOOKS_EXPAND_EXPR -#define LANG_HOOKS_EXPAND_EXPR java_expand_expr #undef LANG_HOOKS_TRUTHVALUE_CONVERSION #define LANG_HOOKS_TRUTHVALUE_CONVERSION java_truthvalue_conversion #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL diff --git a/gcc/print-tree.c b/gcc/print-tree.c index 3208797..01e5702 100644 --- a/gcc/print-tree.c +++ b/gcc/print-tree.c @@ -337,8 +337,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent) if (TREE_CODE (node) == FIELD_DECL && DECL_NONADDRESSABLE_P (node)) fputs (" nonaddressable", file); - if (TREE_CODE (node) == LABEL_DECL && DECL_TOO_LATE (node)) - fputs (" too-late", file); if (TREE_CODE (node) == LABEL_DECL && DECL_ERROR_ISSUED (node)) fputs (" error-issued", file); @@ -164,33 +164,10 @@ struct nesting GTY(()) /* Sequence number of this binding contour within the function, in order of entry. */ int block_start_count; - /* Nonzero => value to restore stack to on exit. */ - rtx stack_level; /* The NOTE that starts this contour. Used by expand_goto to check whether the destination is within each contour or not. */ rtx first_insn; - /* Innermost containing binding contour that has a stack level. */ - struct nesting *innermost_stack_block; - /* List of cleanups to be run on exit from this contour. - This is a list of expressions to be evaluated. - The TREE_PURPOSE of each link is the ..._DECL node - which the cleanup pertains to. */ - tree cleanups; - /* List of cleanup-lists of blocks containing this block, - as they were at the locus where this block appears. - There is an element for each containing block, - ordered innermost containing block first. - The tail of this list can be 0, - if all remaining elements would be empty lists. - The element's TREE_VALUE is the cleanup-list of that block, - which may be null. */ - tree outer_cleanups; - /* Chain of labels defined inside this binding contour. - For contours that have stack levels or cleanups. */ - struct label_chain *label_chain; - /* Nonzero if this is associated with an EH region. */ - int exception_region; /* The saved target_temp_slot_level from our outer block. We may reset target_temp_slot_level to be the level of this block, if that is done, target_temp_slot_level @@ -251,8 +228,6 @@ do { struct nesting *target = STACK; \ cond_stack = cond_stack->next; \ if (block_stack == this) \ block_stack = block_stack->next; \ - if (stack_block_stack == this) \ - stack_block_stack = stack_block_stack->next; \ if (case_stack == this) \ case_stack = case_stack->next; \ nesting_depth = nesting_stack->depth - 1; \ @@ -284,28 +259,6 @@ struct goto_fixup GTY(()) /* Number of binding contours started in current function before the label reference. */ int block_start_count; - /* The outermost stack level that should be restored for this jump. - Each time a binding contour that resets the stack is exited, - if the target label is *not* yet defined, this slot is updated. */ - rtx stack_level; - /* List of lists of cleanup expressions to be run by this goto. - There is one element for each block that this goto is within. - The tail of this list can be 0, - if all remaining elements would be empty. - The TREE_VALUE contains the cleanup list of that block as of the - time this goto was seen. - The TREE_ADDRESSABLE flag is 1 for a block that has been exited. */ - tree cleanup_list_list; -}; - -/* Within any binding contour that must restore a stack level, - all labels are recorded with a chain of these structures. */ - -struct label_chain GTY(()) -{ - /* Points to following fixup. */ - struct label_chain *next; - tree label; }; struct stmt_status GTY(()) @@ -315,10 +268,6 @@ struct stmt_status GTY(()) /* If any new stacks are added here, add them to POPSTACKS too. */ - /* Chain of all pending binding contours that restore stack levels - or have cleanups. */ - struct nesting * x_stack_block_stack; - /* Chain of all pending conditional statements. */ struct nesting * x_cond_stack; @@ -343,7 +292,6 @@ struct stmt_status GTY(()) }; #define block_stack (cfun->stmt->x_block_stack) -#define stack_block_stack (cfun->stmt->x_stack_block_stack) #define cond_stack (cfun->stmt->x_cond_stack) #define case_stack (cfun->stmt->x_case_stack) #define nesting_stack (cfun->stmt->x_nesting_stack) @@ -357,18 +305,14 @@ int using_eh_for_cleanups_p = 0; static int n_occurrences (int, const char *); static bool decl_conflicts_with_clobbers_p (tree, const HARD_REG_SET); -static void expand_goto_internal (tree, rtx, rtx); -static int expand_fixup (tree, rtx, rtx); static void expand_nl_goto_receiver (void); -static void fixup_gotos (struct nesting *, rtx, tree, rtx, int); static bool check_operand_nalternatives (tree, tree); static bool check_unique_operand_names (tree, tree); static char *resolve_operand_name_1 (char *, tree, tree); -static void expand_null_return_1 (rtx); +static void expand_null_return_1 (void); static enum br_predictor return_prediction (rtx); static rtx shift_return_value (rtx); static void expand_value_return (rtx); -static void expand_cleanups (tree, int, int); static void do_jump_if_equal (rtx, rtx, rtx, int); static int estimate_case_costs (case_node_ptr); static bool same_case_target_p (rtx, rtx); @@ -507,7 +451,6 @@ expand_computed_goto (tree exp) void expand_label (tree label) { - struct label_chain *p; rtx label_r = label_rtx (label); do_pending_stack_adjust (); @@ -528,14 +471,6 @@ expand_label (tree label) if (DECL_NONLOCAL (label) || FORCED_LABEL (label)) maybe_set_first_label_num (label_r); - - if (stack_block_stack != 0) - { - p = ggc_alloc (sizeof (struct label_chain)); - p->next = stack_block_stack->data.block.label_chain; - stack_block_stack->data.block.label_chain = p; - p->label = label; - } } /* Generate RTL code for a `goto' statement with target label LABEL. @@ -553,385 +488,7 @@ expand_goto (tree label) abort (); #endif - expand_goto_internal (label, label_rtx (label), NULL_RTX); -} - -/* Generate RTL code for a `goto' statement with target label BODY. - LABEL should be a LABEL_REF. - LAST_INSN, if non-0, is the rtx we should consider as the last - insn emitted (for the purposes of cleaning up a return). */ - -static void -expand_goto_internal (tree body, rtx label, rtx last_insn) -{ - struct nesting *block; - rtx stack_level = 0; - - if (GET_CODE (label) != CODE_LABEL) - abort (); - - /* If label has already been defined, we can tell now - whether and how we must alter the stack level. */ - - if (PREV_INSN (label) != 0) - { - /* Find the innermost pending block that contains the label. - (Check containment by comparing insn-uids.) - Then restore the outermost stack level within that block, - and do cleanups of all blocks contained in it. */ - for (block = block_stack; block; block = block->next) - { - if (INSN_UID (block->data.block.first_insn) < INSN_UID (label)) - break; - if (block->data.block.stack_level != 0) - stack_level = block->data.block.stack_level; - /* Execute the cleanups for blocks we are exiting. */ - if (block->data.block.cleanups != 0) - { - expand_cleanups (block->data.block.cleanups, 1, 1); - do_pending_stack_adjust (); - } - } - - if (stack_level) - { - /* Ensure stack adjust isn't done by emit_jump, as this - would clobber the stack pointer. This one should be - deleted as dead by flow. */ - clear_pending_stack_adjust (); - do_pending_stack_adjust (); - - /* Don't do this adjust if it's to the end label and this function - is to return with a depressed stack pointer. */ - if (label == return_label - && (((TREE_CODE (TREE_TYPE (current_function_decl)) - == FUNCTION_TYPE) - && (TYPE_RETURNS_STACK_DEPRESSED - (TREE_TYPE (current_function_decl)))))) - ; - else - emit_stack_restore (SAVE_BLOCK, stack_level, NULL_RTX); - } - - if (body != 0 && DECL_TOO_LATE (body)) - error ("jump to `%s' invalidly jumps into binding contour", - IDENTIFIER_POINTER (DECL_NAME (body))); - } - /* Label not yet defined: may need to put this goto - on the fixup list. */ - else if (! expand_fixup (body, label, last_insn)) - { - /* No fixup needed. Record that the label is the target - of at least one goto that has no fixup. */ - if (body != 0) - TREE_ADDRESSABLE (body) = 1; - } - - emit_jump (label); -} - -/* Generate if necessary a fixup for a goto - whose target label in tree structure (if any) is TREE_LABEL - and whose target in rtl is RTL_LABEL. - - If LAST_INSN is nonzero, we pretend that the jump appears - after insn LAST_INSN instead of at the current point in the insn stream. - - The fixup will be used later to insert insns just before the goto. - Those insns will restore the stack level as appropriate for the - target label, and will (in the case of C++) also invoke any object - destructors which have to be invoked when we exit the scopes which - are exited by the goto. - - Value is nonzero if a fixup is made. */ - -static int -expand_fixup (tree tree_label, rtx rtl_label, rtx last_insn) -{ - struct nesting *block, *end_block; - - /* See if we can recognize which block the label will be output in. - This is possible in some very common cases. - If we succeed, set END_BLOCK to that block. - Otherwise, set it to 0. */ - - if (cond_stack - && (rtl_label == cond_stack->data.cond.endif_label - || rtl_label == cond_stack->data.cond.next_label)) - end_block = cond_stack; - else - end_block = 0; - - /* Now set END_BLOCK to the binding level to which we will return. */ - - if (end_block) - { - struct nesting *next_block = end_block->all; - block = block_stack; - - /* First see if the END_BLOCK is inside the innermost binding level. - If so, then no cleanups or stack levels are relevant. */ - while (next_block && next_block != block) - next_block = next_block->all; - - if (next_block) - return 0; - - /* Otherwise, set END_BLOCK to the innermost binding level - which is outside the relevant control-structure nesting. */ - next_block = block_stack->next; - for (block = block_stack; block != end_block; block = block->all) - if (block == next_block) - next_block = next_block->next; - end_block = next_block; - } - - /* Does any containing block have a stack level or cleanups? - If not, no fixup is needed, and that is the normal case - (the only case, for standard C). */ - for (block = block_stack; block != end_block; block = block->next) - if (block->data.block.stack_level != 0 - || block->data.block.cleanups != 0) - break; - - if (block != end_block) - { - /* Ok, a fixup is needed. Add a fixup to the list of such. */ - struct goto_fixup *fixup = ggc_alloc (sizeof (struct goto_fixup)); - /* In case an old stack level is restored, make sure that comes - after any pending stack adjust. */ - /* ?? If the fixup isn't to come at the present position, - doing the stack adjust here isn't useful. Doing it with our - settings at that location isn't useful either. Let's hope - someone does it! */ - if (last_insn == 0) - do_pending_stack_adjust (); - fixup->target = tree_label; - fixup->target_rtl = rtl_label; - - /* Create a BLOCK node and a corresponding matched set of - NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes at - this point. The notes will encapsulate any and all fixup - code which we might later insert at this point in the insn - stream. Also, the BLOCK node will be the parent (i.e. the - `SUPERBLOCK') of any other BLOCK nodes which we might create - later on when we are expanding the fixup code. - - Note that optimization passes might move the *_BLOCK notes away, - so we use a NOTE_INSN_DELETED as a placeholder. */ - - { - rtx original_before_jump - = last_insn ? last_insn : get_last_insn (); - rtx start; - rtx end; - tree block; - - block = make_node (BLOCK); - TREE_USED (block) = 1; - - BLOCK_CHAIN (block) - = BLOCK_CHAIN (DECL_INITIAL (current_function_decl)); - BLOCK_CHAIN (DECL_INITIAL (current_function_decl)) - = block; - - start_sequence (); - start = emit_note (NOTE_INSN_BLOCK_BEG); - NOTE_BLOCK (start) = block; - fixup->before_jump = emit_note (NOTE_INSN_DELETED); - end = emit_note (NOTE_INSN_BLOCK_END); - NOTE_BLOCK (end) = block; - fixup->context = block; - end_sequence (); - emit_insn_after (start, original_before_jump); - } - - fixup->block_start_count = current_block_start_count; - fixup->stack_level = 0; - fixup->cleanup_list_list - = ((block->data.block.outer_cleanups - || block->data.block.cleanups) - ? tree_cons (NULL_TREE, block->data.block.cleanups, - block->data.block.outer_cleanups) - : 0); - fixup->next = goto_fixup_chain; - goto_fixup_chain = fixup; - } - - return block != 0; -} - -/* Expand any needed fixups in the outputmost binding level of the - function. FIRST_INSN is the first insn in the function. */ - -void -expand_fixups (rtx first_insn) -{ - fixup_gotos (NULL, NULL_RTX, NULL_TREE, first_insn, 0); -} - -/* When exiting a binding contour, process all pending gotos requiring fixups. - THISBLOCK is the structure that describes the block being exited. - STACK_LEVEL is the rtx for the stack level to restore exiting this contour. - CLEANUP_LIST is a list of expressions to evaluate on exiting this contour. - FIRST_INSN is the insn that began this contour. - - Gotos that jump out of this contour must restore the - stack level and do the cleanups before actually jumping. - - DONT_JUMP_IN positive means report error if there is a jump into this - contour from before the beginning of the contour. This is also done if - STACK_LEVEL is nonzero unless DONT_JUMP_IN is negative. */ - -static void -fixup_gotos (struct nesting *thisblock, rtx stack_level, - tree cleanup_list, rtx first_insn, int dont_jump_in) -{ - struct goto_fixup *f, *prev; - - /* F is the fixup we are considering; PREV is the previous one. */ - /* We run this loop in two passes so that cleanups of exited blocks - are run first, and blocks that are exited are marked so - afterwards. */ - - for (prev = 0, f = goto_fixup_chain; f; prev = f, f = f->next) - { - /* Test for a fixup that is inactive because it is already handled. */ - if (f->before_jump == 0) - { - /* Delete inactive fixup from the chain, if that is easy to do. */ - if (prev != 0) - prev->next = f->next; - } - /* Has this fixup's target label been defined? - If so, we can finalize it. */ - else if (PREV_INSN (f->target_rtl) != 0) - { - rtx cleanup_insns; - - /* If this fixup jumped into this contour from before the beginning - of this contour, report an error. This code used to use - the first non-label insn after f->target_rtl, but that's - wrong since such can be added, by things like put_var_into_stack - and have INSN_UIDs that are out of the range of the block. */ - /* ??? Bug: this does not detect jumping in through intermediate - blocks that have stack levels or cleanups. - It detects only a problem with the innermost block - around the label. */ - if (f->target != 0 - && (dont_jump_in > 0 || (dont_jump_in == 0 && stack_level) - || cleanup_list) - && INSN_UID (first_insn) < INSN_UID (f->target_rtl) - && INSN_UID (first_insn) > INSN_UID (f->before_jump) - && ! DECL_ERROR_ISSUED (f->target)) - { - error ("%Jlabel '%D' used before containing binding contour", - f->target, f->target); - /* Prevent multiple errors for one label. */ - DECL_ERROR_ISSUED (f->target) = 1; - } - - /* We will expand the cleanups into a sequence of their own and - then later on we will attach this new sequence to the insn - stream just ahead of the actual jump insn. */ - - start_sequence (); - - /* Temporarily restore the lexical context where we will - logically be inserting the fixup code. We do this for the - sake of getting the debugging information right. */ - - lang_hooks.decls.pushlevel (0); - lang_hooks.decls.set_block (f->context); - - /* Expand the cleanups for blocks this jump exits. */ - if (f->cleanup_list_list) - { - tree lists; - for (lists = f->cleanup_list_list; lists; lists = TREE_CHAIN (lists)) - /* Marked elements correspond to blocks that have been closed. - Do their cleanups. */ - if (TREE_ADDRESSABLE (lists) - && TREE_VALUE (lists) != 0) - { - expand_cleanups (TREE_VALUE (lists), 1, 1); - /* Pop any pushes done in the cleanups, - in case function is about to return. */ - do_pending_stack_adjust (); - } - } - - /* Restore stack level for the biggest contour that this - jump jumps out of. */ - if (f->stack_level - && ! (f->target_rtl == return_label - && ((TREE_CODE (TREE_TYPE (current_function_decl)) - == FUNCTION_TYPE) - && (TYPE_RETURNS_STACK_DEPRESSED - (TREE_TYPE (current_function_decl)))))) - emit_stack_restore (SAVE_BLOCK, f->stack_level, f->before_jump); - - /* Finish up the sequence containing the insns which implement the - necessary cleanups, and then attach that whole sequence to the - insn stream just ahead of the actual jump insn. Attaching it - at that point insures that any cleanups which are in fact - implicit C++ object destructions (which must be executed upon - leaving the block) appear (to the debugger) to be taking place - in an area of the generated code where the object(s) being - destructed are still "in scope". */ - - cleanup_insns = get_insns (); - lang_hooks.decls.poplevel (1, 0, 0); - - end_sequence (); - emit_insn_after (cleanup_insns, f->before_jump); - - f->before_jump = 0; - } - } - - /* For any still-undefined labels, do the cleanups for this block now. - We must do this now since items in the cleanup list may go out - of scope when the block ends. */ - for (prev = 0, f = goto_fixup_chain; f; prev = f, f = f->next) - if (f->before_jump != 0 - && PREV_INSN (f->target_rtl) == 0 - /* Label has still not appeared. If we are exiting a block with - a stack level to restore, that started before the fixup, - mark this stack level as needing restoration - when the fixup is later finalized. */ - && thisblock != 0 - /* Note: if THISBLOCK == 0 and we have a label that hasn't appeared, it - means the label is undefined. That's erroneous, but possible. */ - && (thisblock->data.block.block_start_count - <= f->block_start_count)) - { - tree lists = f->cleanup_list_list; - rtx cleanup_insns; - - for (; lists; lists = TREE_CHAIN (lists)) - /* If the following elt. corresponds to our containing block - then the elt. must be for this block. */ - if (TREE_CHAIN (lists) == thisblock->data.block.outer_cleanups) - { - start_sequence (); - lang_hooks.decls.pushlevel (0); - lang_hooks.decls.set_block (f->context); - expand_cleanups (TREE_VALUE (lists), 1, 1); - do_pending_stack_adjust (); - cleanup_insns = get_insns (); - lang_hooks.decls.poplevel (1, 0, 0); - end_sequence (); - if (cleanup_insns != 0) - f->before_jump - = emit_insn_after (cleanup_insns, f->before_jump); - - f->cleanup_list_list = TREE_CHAIN (lists); - } - - if (stack_level) - f->stack_level = stack_level; - } + emit_jump (label_rtx (label)); } /* Return the number of times character C occurs in string S. */ @@ -2297,16 +1854,12 @@ preserve_subexpressions_p (void) void expand_null_return (void) { - rtx last_insn; - - last_insn = get_last_insn (); - /* If this function was declared to return a value, but we didn't, clobber the return registers so that they are not propagated live to the rest of the function. */ clobber_return_register (); - expand_null_return_1 (last_insn); + expand_null_return_1 (); } /* Generate RTL to return directly from the current function. @@ -2315,17 +1868,16 @@ expand_null_return (void) void expand_naked_return (void) { - rtx last_insn, end_label; - - last_insn = get_last_insn (); - end_label = naked_return_label; + rtx end_label; clear_pending_stack_adjust (); do_pending_stack_adjust (); + end_label = naked_return_label; if (end_label == 0) end_label = naked_return_label = gen_label_rtx (); - expand_goto_internal (NULL_TREE, end_label, last_insn); + + emit_jump (end_label); } /* Try to guess whether the value of return means error code. */ @@ -2389,7 +1941,6 @@ shift_return_value (rtx val) static void expand_value_return (rtx val) { - rtx last_insn; rtx return_reg; enum br_predictor pred; @@ -2405,7 +1956,6 @@ expand_value_return (rtx val) } - last_insn = get_last_insn (); return_reg = DECL_RTL (DECL_RESULT (current_function_decl)); /* Copy the value to the return location @@ -2431,23 +1981,23 @@ expand_value_return (rtx val) emit_move_insn (return_reg, val); } - expand_null_return_1 (last_insn); + expand_null_return_1 (); } -/* Output a return with no value. If LAST_INSN is nonzero, - pretend that the return takes place after LAST_INSN. */ +/* Output a return with no value. */ static void -expand_null_return_1 (rtx last_insn) +expand_null_return_1 (void) { - rtx end_label = return_label; + rtx end_label; clear_pending_stack_adjust (); do_pending_stack_adjust (); + end_label = return_label; if (end_label == 0) end_label = return_label = gen_label_rtx (); - expand_goto_internal (NULL_TREE, end_label, last_insn); + emit_jump (end_label); } /* Generate RTL to evaluate the expression RETVAL and return it @@ -2456,15 +2006,6 @@ expand_null_return_1 (rtx last_insn) void expand_return (tree retval) { - /* If there are any cleanups to be performed, then they will - be inserted following LAST_INSN. It is desirable - that the last_insn, for such purposes, should be the - last insn before computing the return value. Otherwise, cleanups - which call functions can clobber the return value. */ - /* ??? rms: I think that is erroneous, because in C++ it would - run destructors on variables that might be used in the subsequent - computation of the return value. */ - rtx last_insn = 0; rtx result_rtl; rtx val = 0; tree retval_rhs; @@ -2487,14 +2028,13 @@ expand_return (tree retval) } else if (TREE_CODE (retval) == RESULT_DECL) retval_rhs = retval; - else if ((TREE_CODE (retval) == MODIFY_EXPR || TREE_CODE (retval) == INIT_EXPR) + else if ((TREE_CODE (retval) == MODIFY_EXPR + || TREE_CODE (retval) == INIT_EXPR) && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL) retval_rhs = TREE_OPERAND (retval, 1); else retval_rhs = retval; - last_insn = get_last_insn (); - result_rtl = DECL_RTL (DECL_RESULT (current_function_decl)); /* If the result is an aggregate that is being returned in one (or more) @@ -2502,8 +2042,7 @@ expand_return (tree retval) copying a BLKmode value into registers. We could put this code in a more general area (for use by everyone instead of just function call/return), but until this feature is generally usable it is kept here - (and in expand_call). The value must go into a pseudo in case there - are cleanups that will clobber the real return register. */ + (and in expand_call). */ if (retval_rhs != 0 && TYPE_MODE (TREE_TYPE (retval_rhs)) == BLKmode @@ -2631,13 +2170,12 @@ expand_return (tree retval) val = expand_expr (retval_rhs, val, GET_MODE (val), 0); val = force_not_mem (val); emit_queue (); - /* Return the calculated value, doing cleanups first. */ + /* Return the calculated value. */ expand_value_return (shift_return_value (val)); } else { - /* No cleanups or no hard reg used; - calculate value into hard return reg. */ + /* No hard reg used; calculate value into hard return reg. */ expand_expr (retval, const0_rtx, VOIDmode, 0); emit_queue (); expand_value_return (result_rtl); @@ -2686,9 +2224,6 @@ expand_start_bindings_and_block (int flags, tree block) thisblock->next = block_stack; thisblock->all = nesting_stack; thisblock->depth = ++nesting_depth; - thisblock->data.block.stack_level = 0; - thisblock->data.block.cleanups = 0; - thisblock->data.block.exception_region = 0; thisblock->data.block.block_target_temp_slot_level = target_temp_slot_level; thisblock->data.block.conditional_code = 0; @@ -2701,16 +2236,6 @@ expand_start_bindings_and_block (int flags, tree block) never the last instruction. */ emit_note (NOTE_INSN_DELETED); - if (block_stack - && !(block_stack->data.block.cleanups == NULL_TREE - && block_stack->data.block.outer_cleanups == NULL_TREE)) - thisblock->data.block.outer_cleanups - = tree_cons (NULL_TREE, block_stack->data.block.cleanups, - block_stack->data.block.outer_cleanups); - else - thisblock->data.block.outer_cleanups = 0; - thisblock->data.block.label_chain = 0; - thisblock->data.block.innermost_stack_block = stack_block_stack; thisblock->data.block.first_insn = note; thisblock->data.block.block_start_count = ++current_block_start_count; thisblock->exit_label = exit_flag ? gen_label_rtx () : 0; @@ -2906,7 +2431,7 @@ warn_about_unused_variables (tree vars) void expand_end_bindings (tree vars, int mark_ends ATTRIBUTE_UNUSED, - int dont_jump_in) + int dont_jump_in ATTRIBUTE_UNUSED) { struct nesting *thisblock = block_stack; @@ -2920,71 +2445,7 @@ expand_end_bindings (tree vars, int mark_ends ATTRIBUTE_UNUSED, emit_label (thisblock->exit_label); } - /* Don't allow jumping into a block that has a stack level. - Cleanups are allowed, though. */ - if (dont_jump_in > 0 - || (dont_jump_in == 0 && thisblock->data.block.stack_level != 0)) - { - struct label_chain *chain; - - /* Any labels in this block are no longer valid to go to. - Mark them to cause an error message. */ - for (chain = thisblock->data.block.label_chain; chain; chain = chain->next) - { - DECL_TOO_LATE (chain->label) = 1; - /* If any goto without a fixup came to this label, - that must be an error, because gotos without fixups - come from outside all saved stack-levels. */ - if (TREE_ADDRESSABLE (chain->label)) - error ("%Jlabel '%D' used before containing binding contour", - chain->label, chain->label); - } - } - - /* Restore stack level in effect before the block - (only if variable-size objects allocated). */ - /* Perform any cleanups associated with the block. */ - - if (thisblock->data.block.stack_level != 0 - || thisblock->data.block.cleanups != 0) - { - int reachable; - rtx insn; - - /* Only clean up here if this point can actually be reached. */ - insn = get_last_insn (); - if (GET_CODE (insn) == NOTE) - insn = prev_nonnote_insn (insn); - reachable = (! insn || GET_CODE (insn) != BARRIER); - - /* Do the cleanups. */ - expand_cleanups (thisblock->data.block.cleanups, 0, reachable); - if (reachable) - do_pending_stack_adjust (); - - /* Restore the stack level. */ - - if (reachable && thisblock->data.block.stack_level != 0) - { - emit_stack_restore (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION, - thisblock->data.block.stack_level, NULL_RTX); - if (cfun->nonlocal_goto_save_area) - update_nonlocal_goto_save_area (); - } - - /* Any gotos out of this block must also do these things. - Also report any gotos with fixups that came to labels in this - level. */ - fixup_gotos (thisblock, - thisblock->data.block.stack_level, - thisblock->data.block.cleanups, - thisblock->data.block.first_insn, - dont_jump_in); - } - - /* Mark the beginning and end of the scope if requested. - We do this now, after running cleanups on the variables - just going out of scope, so they are in scope for their cleanups. */ + /* Mark the beginning and end of the scope if requested. */ /* Get rid of the beginning-mark if we don't make an end-mark. */ NOTE_LINE_NUMBER (thisblock->data.block.first_insn) = NOTE_INSN_DELETED; @@ -2994,30 +2455,12 @@ expand_end_bindings (tree vars, int mark_ends ATTRIBUTE_UNUSED, /* Restore block_stack level for containing block. */ - stack_block_stack = thisblock->data.block.innermost_stack_block; POPSTACK (block_stack); /* Pop the stack slot nesting and free any slots at this level. */ pop_temp_slots (); } -/* Generate code to save the stack pointer at the start of the current block - and set up to restore it on exit. */ - -void -save_stack_pointer (void) -{ - struct nesting *thisblock = block_stack; - - if (thisblock->data.block.stack_level == 0) - { - emit_stack_save (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION, - &thisblock->data.block.stack_level, - thisblock->data.block.first_insn); - stack_block_stack = thisblock; - } -} - /* Generate RTL for the automatic variable declaration DECL. (Other kinds of declarations are simply ignored if seen here.) */ @@ -3143,7 +2586,6 @@ expand_decl (tree decl) /* Record the stack pointer on entry to block, if have not already done so. */ do_pending_stack_adjust (); - save_stack_pointer (); /* Compute the variable's size, in bytes. This will expand any needed SAVE_EXPRs for the first time. */ @@ -3270,133 +2712,15 @@ expand_decl_init (tree decl) pop_temp_slots (); } -/* CLEANUP is an expression to be executed at exit from this binding contour; - for example, in C++, it might call the destructor for this variable. - - We wrap CLEANUP in an UNSAVE_EXPR node, so that we can expand the - CLEANUP multiple times, and have the correct semantics. This - happens in exception handling, for gotos, returns, breaks that - leave the current scope. - - If CLEANUP is nonzero and DECL is zero, we record a cleanup - that is not associated with any particular variable. */ - -int -expand_decl_cleanup (tree decl, tree cleanup) -{ - struct nesting *thisblock; - - /* Error if we are not in any block. */ - if (cfun == 0 || block_stack == 0) - return 0; - - thisblock = block_stack; - - /* Record the cleanup if there is one. */ - - if (cleanup != 0) - { - tree t; - rtx seq; - tree *cleanups = &thisblock->data.block.cleanups; - int cond_context = conditional_context (); - - if (cond_context) - { - rtx flag = gen_reg_rtx (word_mode); - rtx set_flag_0; - tree cond; - - start_sequence (); - emit_move_insn (flag, const0_rtx); - set_flag_0 = get_insns (); - end_sequence (); - - thisblock->data.block.last_unconditional_cleanup - = emit_insn_after (set_flag_0, - thisblock->data.block.last_unconditional_cleanup); - - emit_move_insn (flag, const1_rtx); - - cond = build_decl (VAR_DECL, NULL_TREE, - lang_hooks.types.type_for_mode (word_mode, 1)); - SET_DECL_RTL (cond, flag); - - /* Conditionalize the cleanup. */ - cleanup = build (COND_EXPR, void_type_node, - lang_hooks.truthvalue_conversion (cond), - cleanup, integer_zero_node); - cleanup = fold (cleanup); - - cleanups = &thisblock->data.block.cleanups; - } - - cleanup = unsave_expr (cleanup); - - t = *cleanups = tree_cons (decl, cleanup, *cleanups); - - if (! cond_context) - /* If this block has a cleanup, it belongs in stack_block_stack. */ - stack_block_stack = thisblock; - - if (cond_context) - { - start_sequence (); - } - - if (! using_eh_for_cleanups_p) - TREE_ADDRESSABLE (t) = 1; - else - expand_eh_region_start (); - - if (cond_context) - { - seq = get_insns (); - end_sequence (); - if (seq) - thisblock->data.block.last_unconditional_cleanup - = emit_insn_after (seq, - thisblock->data.block.last_unconditional_cleanup); - } - else - { - thisblock->data.block.last_unconditional_cleanup - = get_last_insn (); - /* When we insert instructions after the last unconditional cleanup, - we don't adjust last_insn. That means that a later add_insn will - clobber the instructions we've just added. The easiest way to - fix this is to just insert another instruction here, so that the - instructions inserted after the last unconditional cleanup are - never the last instruction. */ - emit_note (NOTE_INSN_DELETED); - } - } - return 1; -} - -/* Like expand_decl_cleanup, but maybe only run the cleanup if an exception - is thrown. */ - -int -expand_decl_cleanup_eh (tree decl, tree cleanup, int eh_only) -{ - int ret = expand_decl_cleanup (decl, cleanup); - if (cleanup && ret) - { - tree node = block_stack->data.block.cleanups; - CLEANUP_EH_ONLY (node) = eh_only; - } - return ret; -} /* DECL is an anonymous union. CLEANUP is a cleanup for DECL. DECL_ELTS is the list of elements that belong to DECL's type. In each, the TREE_VALUE is a VAR_DECL, and the TREE_PURPOSE a cleanup. */ void -expand_anon_union_decl (tree decl, tree cleanup, tree decl_elts) +expand_anon_union_decl (tree decl, tree cleanup ATTRIBUTE_UNUSED, + tree decl_elts) { - struct nesting *thisblock = cfun == 0 ? 0 : block_stack; rtx x; tree t; @@ -3409,14 +2733,12 @@ expand_anon_union_decl (tree decl, tree cleanup, tree decl_elts) } expand_decl (decl); - expand_decl_cleanup (decl, cleanup); x = DECL_RTL (decl); /* Go through the elements, assigning RTL to each. */ for (t = decl_elts; t; t = TREE_CHAIN (t)) { tree decl_elt = TREE_VALUE (t); - tree cleanup_elt = TREE_PURPOSE (t); enum machine_mode mode = TYPE_MODE (TREE_TYPE (decl_elt)); /* If any of the elements are addressable, so is the entire @@ -3453,145 +2775,9 @@ expand_anon_union_decl (tree decl, tree cleanup, tree decl_elts) } else abort (); - - /* Record the cleanup if there is one. */ - - if (cleanup != 0) - thisblock->data.block.cleanups - = tree_cons (decl_elt, cleanup_elt, - thisblock->data.block.cleanups); } } -/* Expand a list of cleanups LIST. - Elements may be expressions or may be nested lists. - - If IN_FIXUP is nonzero, we are generating this cleanup for a fixup - goto and handle protection regions specially in that case. - - If REACHABLE, we emit code, otherwise just inform the exception handling - code about this finalization. */ - -static void -expand_cleanups (tree list, int in_fixup, int reachable) -{ - tree tail; - for (tail = list; tail; tail = TREE_CHAIN (tail)) - if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST) - expand_cleanups (TREE_VALUE (tail), in_fixup, reachable); - else - { - if (! in_fixup && using_eh_for_cleanups_p) - expand_eh_region_end_cleanup (TREE_VALUE (tail)); - - if (reachable && !CLEANUP_EH_ONLY (tail)) - { - /* Cleanups may be run multiple times. For example, - when exiting a binding contour, we expand the - cleanups associated with that contour. When a goto - within that binding contour has a target outside that - contour, it will expand all cleanups from its scope to - the target. Though the cleanups are expanded multiple - times, the control paths are non-overlapping so the - cleanups will not be executed twice. */ - - /* We may need to protect from outer cleanups. */ - if (in_fixup && using_eh_for_cleanups_p) - { - expand_eh_region_start (); - - expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0); - - expand_eh_region_end_fixup (TREE_VALUE (tail)); - } - else - expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0); - - free_temp_slots (); - } - } -} - -/* Mark when the context we are emitting RTL for as a conditional - context, so that any cleanup actions we register with - expand_decl_init will be properly conditionalized when those - cleanup actions are later performed. Must be called before any - expression (tree) is expanded that is within a conditional context. */ - -void -start_cleanup_deferral (void) -{ - /* block_stack can be NULL if we are inside the parameter list. It is - OK to do nothing, because cleanups aren't possible here. */ - if (block_stack) - ++block_stack->data.block.conditional_code; -} - -/* Mark the end of a conditional region of code. Because cleanup - deferrals may be nested, we may still be in a conditional region - after we end the currently deferred cleanups, only after we end all - deferred cleanups, are we back in unconditional code. */ - -void -end_cleanup_deferral (void) -{ - /* block_stack can be NULL if we are inside the parameter list. It is - OK to do nothing, because cleanups aren't possible here. */ - if (block_stack) - --block_stack->data.block.conditional_code; -} - -tree -last_cleanup_this_contour (void) -{ - if (block_stack == 0) - return 0; - - return block_stack->data.block.cleanups; -} - - -/* Return nonzero if any containing block has a stack level or - cleanups. */ - -int -containing_blocks_have_cleanups_or_stack_level (void) -{ - struct nesting *block; - - for (block = block_stack; block; block = block->next) - if (block->data.block.stack_level != 0 - || block->data.block.cleanups != 0) - return 1; - - return 0; -} - -/* Return 1 if there are any pending cleanups at this point. - Check the current contour as well as contours that enclose - the current contour. */ - -int -any_pending_cleanups (void) -{ - struct nesting *block; - - if (cfun == NULL || cfun->stmt == NULL || block_stack == 0) - return 0; - - if (block_stack->data.block.cleanups != NULL) - return 1; - - if (block_stack->data.block.outer_cleanups == 0) - return 0; - - for (block = block_stack->next; block; block = block->next) - if (block->data.block.cleanups != 0) - return 1; - - return 0; -} - /* Enter a case (Pascal) or switch (C) statement. Push a block onto case_stack and nesting_stack to accumulate the case-labels that are seen @@ -3635,8 +2821,6 @@ expand_start_case (int exit_flag, tree expr, tree type, emit_note (NOTE_INSN_DELETED); thiscase->data.case_stmt.start = get_last_insn (); - - start_cleanup_deferral (); } /* Accumulate one case or default label inside a case or switch statement. @@ -3649,7 +2833,6 @@ expand_start_case (int exit_flag, tree expr, tree type, If VALUE is a duplicate or overlaps, return 2 and do nothing except store the (first) duplicate node in *DUPLICATE. If VALUE is out of range, return 3 and do nothing. - If we are jumping into the scope of a cleanup or var-sized array, return 5. Return 0 on success. Extended to handle range statements. */ @@ -3665,10 +2848,6 @@ pushcase (tree value, tree (*converter) (tree, tree), tree label, if (! (case_stack && case_stack->data.case_stmt.start)) return 1; - if (stack_block_stack - && stack_block_stack->depth > case_stack->depth) - return 5; - index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr); nominal_type = case_stack->data.case_stmt.nominal_type; @@ -3710,10 +2889,6 @@ pushcase_range (tree value1, tree value2, tree (*converter) (tree, tree), if (! (case_stack && case_stack->data.case_stmt.start)) return 1; - if (stack_block_stack - && stack_block_stack->depth > case_stack->depth) - return 5; - index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr); nominal_type = case_stack->data.case_stmt.nominal_type; @@ -4268,8 +3443,6 @@ expand_end_case_type (tree orig_index, tree orig_type) if (count != 0) range = fold (build (MINUS_EXPR, index_type, maxval, minval)); - end_cleanup_deferral (); - if (count == 0) { expand_expr (index_expr, const0_rtx, VOIDmode, 0); @@ -4482,8 +3655,6 @@ expand_end_case_type (tree orig_index, tree orig_type) reorder_insns (before_case, end, thiscase->data.case_stmt.start); } - else - end_cleanup_deferral (); if (thiscase->exit_label && !exit_done) emit_label (thiscase->exit_label); diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index 743524f..e660b44 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -1185,10 +1185,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags, is_expr = false; break; - case GOTO_SUBROUTINE_EXPR: - NIY; - break; - case LABEL_EXPR: op0 = TREE_OPERAND (node, 0); /* If this is for break or continue, don't bother printing it. */ @@ -1493,10 +1493,6 @@ first_rtl_op (enum tree_code code) { switch (code) { - case GOTO_SUBROUTINE_EXPR: - return 0; - case WITH_CLEANUP_EXPR: - return 2; default: return TREE_CODE_LENGTH (code); } @@ -1850,7 +1846,6 @@ has_cleanups (tree exp) switch (TREE_CODE (exp)) { case TARGET_EXPR: - case GOTO_SUBROUTINE_EXPR: case WITH_CLEANUP_EXPR: return 1; diff --git a/gcc/tree.def b/gcc/tree.def index 70af240..8068f26 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -494,16 +494,11 @@ DEFTREECODE (LABELED_BLOCK_EXPR, "labeled_block_expr", 'e', 2) DEFTREECODE (CALL_EXPR, "call_expr", 'e', 3) /* Specify a value to compute along with its corresponding cleanup. - Operand 0 argument is an expression whose value needs a cleanup. - Operand 1 is the cleanup expression for the object. - Operand 2 is unused. - The cleanup is executed by the first enclosing CLEANUP_POINT_EXPR, if - it exists, otherwise it is the responsibility of the caller to manually - call expand_start_target_temps/expand_end_target_temps, as needed. - - This differs from TRY_CATCH_EXPR in that operand 2 is always - evaluated when an exception isn't thrown when cleanups are run. */ -DEFTREECODE (WITH_CLEANUP_EXPR, "with_cleanup_expr", 'e', 3) + Operand 0 is the cleanup expression. + The cleanup is executed by the first enclosing CLEANUP_POINT_EXPR, + which must exist. This differs from TRY_CATCH_EXPR in that operand 1 + is always evaluated when cleanups are run. */ +DEFTREECODE (WITH_CLEANUP_EXPR, "with_cleanup_expr", 'e', 1) /* Specify a cleanup point. Operand 0 is an expression that may have cleanups. If it does, those @@ -790,13 +785,6 @@ DEFTREECODE (LABEL_EXPR, "label_expr", 's', 1) The type should be void and the value should be ignored. */ DEFTREECODE (GOTO_EXPR, "goto_expr", 's', 1) -/* Used internally for cleanups in the implementation of TRY_FINALLY_EXPR. - (Specifically, it is created by expand_expr, not front-ends.) - Operand 0 is the rtx for the start of the subroutine we need to call. - Operand 1 is the rtx for a variable in which to store the address - of where the subroutine should return to. */ -DEFTREECODE (GOTO_SUBROUTINE_EXPR, "goto_subroutine", 's', 2) - /* RETURN. Evaluates operand 0, then returns from the current function. Presumably that operand is an assignment that stores into the RESULT_DECL that hold the value to be returned. @@ -1025,10 +1025,6 @@ struct tree_vec GTY(()) && VOID_TYPE_P (TREE_TYPE (NODE)) \ && integer_zerop (TREE_OPERAND (NODE, 0))) -/* In a WITH_CLEANUP_EXPR node. */ -#define WITH_CLEANUP_EXPR_RTL(NODE) \ - TREE_RTL_OPERAND_CHECK (NODE, WITH_CLEANUP_EXPR, 2) - /* In a CONSTRUCTOR node. */ #define CONSTRUCTOR_ELTS(NODE) TREE_OPERAND_CHECK_CODE (NODE, CONSTRUCTOR, 0) @@ -2013,10 +2009,6 @@ extern GTY (()) unsigned binfo_lang_slots; specially. */ #define DECL_BIT_FIELD(NODE) (FIELD_DECL_CHECK (NODE)->decl.bit_field_flag) -/* In a LABEL_DECL, nonzero means label was defined inside a binding - contour that restored a stack level and which is now exited. */ -#define DECL_TOO_LATE(NODE) (LABEL_DECL_CHECK (NODE)->decl.bit_field_flag) - /* Unused in FUNCTION_DECL. */ /* In a VAR_DECL that's static, @@ -3333,7 +3325,6 @@ extern bool commutative_tree_code (enum tree_code); /* In stmt.c */ -extern void expand_fixups (rtx); extern void expand_expr_stmt (tree); extern void expand_expr_stmt_value (tree, int, int); extern int warn_if_unused_value (tree, location_t); @@ -3355,13 +3346,10 @@ extern void expand_start_bindings_and_block (int, tree); expand_start_bindings_and_block(flags, NULL_TREE) extern void expand_end_bindings (tree, int, int); extern void warn_about_unused_variables (tree); -extern void start_cleanup_deferral (void); -extern void end_cleanup_deferral (void); extern int is_body_block (tree); extern int conditional_context (void); extern struct nesting * current_nesting_level (void); -extern tree last_cleanup_this_contour (void); extern void expand_start_case (int, tree, tree, const char *); extern void expand_end_case_type (tree, tree); #define expand_end_case(cond) expand_end_case_type (cond, NULL) @@ -3613,17 +3601,12 @@ extern void expand_asm_operands (tree, tree, tree, tree, int, location_t); extern void expand_asm_expr (tree); extern bool asm_op_is_mem_input (tree, tree); extern tree resolve_asm_operand_names (tree, tree, tree); -extern int any_pending_cleanups (void); extern void init_stmt_for_function (void); extern void expand_start_target_temps (void); extern void expand_end_target_temps (void); extern void expand_elseif (tree); -extern void save_stack_pointer (void); extern void expand_decl (tree); -extern int expand_decl_cleanup (tree, tree); -extern int expand_decl_cleanup_eh (tree, tree, int); extern void expand_anon_union_decl (tree, tree, tree); -extern int containing_blocks_have_cleanups_or_stack_level (void); /* In gimplify.c. */ extern tree create_artificial_label (void); |