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
This commit is contained in:
Richard Henderson 2002-07-21 17:42:54 -07:00 committed by Richard Henderson
parent b1aef35bb1
commit 8943a0b4d8
4 changed files with 72 additions and 19 deletions

View File

@ -1,3 +1,8 @@
2002-07-21 Richard Henderson <rth@redhat.com>
* 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 <rth@redhat.com>
* unroll.c (find_splittable_givs): Do not split DEST_ADDR givs

View File

@ -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. */
target_temp_slot_level = temp_slot_level;
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;
expand_decl_cleanup (NULL_TREE, cleanup);
op0 = expand_expr (try_block, target, tmode, modifier);
/* 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);
}
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;
}

View File

@ -1,3 +1,8 @@
2002-07-21 Richard Henderson <rth@redhat.com>
* lang.c (java_unsafe_for_reeval): New.
(LANG_HOOKS_UNSAFE_FOR_REEVAL): New.
2002-07-21 Neil Booth <neil@daikokuya.co.uk>
* jcf-path.c (GET_ENV_PATH_LIST): Remove.

View File

@ -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"