summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog48
-rw-r--r--gcc/ada/ChangeLog5
-rw-r--r--gcc/ada/trans.c17
-rw-r--r--gcc/calls.c16
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/dojump.c6
-rw-r--r--gcc/except.c332
-rw-r--r--gcc/except.h46
-rw-r--r--gcc/expr.c245
-rw-r--r--gcc/fold-const.c9
-rw-r--r--gcc/function.c9
-rw-r--r--gcc/gengtype.c47
-rw-r--r--gcc/gimplify.c14
-rw-r--r--gcc/integrate.c1
-rw-r--r--gcc/java/ChangeLog7
-rw-r--r--gcc/java/expr.c270
-rw-r--r--gcc/java/java-tree.h3
-rw-r--r--gcc/java/lang.c2
-rw-r--r--gcc/print-tree.c2
-rw-r--r--gcc/stmt.c873
-rw-r--r--gcc/tree-pretty-print.c4
-rw-r--r--gcc/tree.c5
-rw-r--r--gcc/tree.def22
-rw-r--r--gcc/tree.h17
25 files changed, 114 insertions, 1891 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7ea2a223756..6ab72383141 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 c2be151e536..c4c7c5fd2a1 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 6135dafc02d..da75a353a8e 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 3f427fbe7d5..b1c226de0e2 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 5d2aae04082..d04b5af2d06 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 15cfd8457f8..59133c1d74f 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 27dc5804ebb..0ce27195b9c 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 5a2fe121336..c66ad32d562 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 6f6a6813043..7a5899009ff 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 *);
diff --git a/gcc/expr.c b/gcc/expr.c
index b9fd93863e0..b2e25c75114 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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 ca042501590..05f4a21d6af 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 d2d1dba69e6..57d52eee265 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 55a26de0128..3912c99fef6 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 0493efa0b37..f60ef89bc48 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 9d4379a6b90..9a944b4e0cc 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 b805bf2bda6..b0bdd58aade 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 f2df129bdda..81dfde67987 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 a07f5752f65..1920232c38c 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 2656d45f2bf..b50977e1a3e 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 320879775c3..01e57026153 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);
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 1a99e231890..8970734f375 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -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 743524f481e..e660b448819 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. */
diff --git a/gcc/tree.c b/gcc/tree.c
index 7b0e872711b..009888a5b21 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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 70af240a38f..8068f266758 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.
diff --git a/gcc/tree.h b/gcc/tree.h
index d8c7be239e2..28582dd7ec4 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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);