From 8943a0b4d855341542bf9b5fe4d29b616078ca9a Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 21 Jul 2002 17:42:54 -0700 Subject: [PATCH] expr.c (expand_expr): Don't use GOTO_SUBROUTINE_EXPR when finally_block can be re-expanded. * expr.c (expand_expr) [TRY_FINALLY_EXPR]: Don't use GOTO_SUBROUTINE_EXPR when finally_block can be re-expanded. * lang.c (java_unsafe_for_reeval): New. (LANG_HOOKS_UNSAFE_FOR_REEVAL): New. From-SVN: r55636 --- gcc/ChangeLog | 5 ++++ gcc/expr.c | 58 +++++++++++++++++++++++++++++++--------------- gcc/java/ChangeLog | 5 ++++ gcc/java/lang.c | 23 ++++++++++++++++++ 4 files changed, 72 insertions(+), 19 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5bd29d35c5b..55b245a0e72 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2002-07-21 Richard Henderson + + * expr.c (expand_expr) [TRY_FINALLY_EXPR]: Don't use + GOTO_SUBROUTINE_EXPR when finally_block can be re-expanded. + 2002-07-21 Richard Henderson * unroll.c (find_splittable_givs): Do not split DEST_ADDR givs diff --git a/gcc/expr.c b/gcc/expr.c index 7b5810c617c..e70bf905b20 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -8965,29 +8965,49 @@ expand_expr (exp, target, tmode, modifier) { tree try_block = TREE_OPERAND (exp, 0); tree finally_block = TREE_OPERAND (exp, 1); - 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); + if (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. */ + + 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; - target_temp_slot_level = temp_slot_level; + expand_decl_cleanup (NULL_TREE, finally_block); + op0 = expand_expr (try_block, target, tmode, modifier); - 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); + } - 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); return op0; } diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 601e766175f..2ccdd0585dd 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,8 @@ +2002-07-21 Richard Henderson + + * lang.c (java_unsafe_for_reeval): New. + (LANG_HOOKS_UNSAFE_FOR_REEVAL): New. + 2002-07-21 Neil Booth * jcf-path.c (GET_ENV_PATH_LIST): Remove. diff --git a/gcc/java/lang.c b/gcc/java/lang.c index 60f1a1c5931..6d7affacbc9 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -61,6 +61,7 @@ static void java_print_error_function PARAMS ((diagnostic_context *, static int process_option_with_no PARAMS ((const char *, const struct string_option *, int)); +static int java_unsafe_for_reeval PARAMS ((tree)); #ifndef TARGET_OBJECT_SUFFIX # define TARGET_OBJECT_SUFFIX ".o" @@ -238,6 +239,8 @@ struct language_function GTY(()) #define LANG_HOOKS_POST_OPTIONS java_post_options #undef LANG_HOOKS_PARSE_FILE #define LANG_HOOKS_PARSE_FILE java_parse_file +#undef LANG_HOOKS_UNSAFE_FOR_REEVAL +#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 @@ -794,4 +797,24 @@ java_post_options () return false; } +/* Called from unsafe_for_reeval. */ +static int +java_unsafe_for_reeval (t) + tree t; +{ + switch (TREE_CODE (t)) + { + case BLOCK: + /* Our expander tries to expand the variables twice. Boom. */ + if (BLOCK_EXPR_DECLS (t) != NULL) + return 2; + return unsafe_for_reeval (BLOCK_EXPR_BODY (t)); + + default: + break; + } + + return -1; +} + #include "gt-java-lang.h" -- 2.30.2