Commit fb13d4d0 by Jason Merrill

except.c (can_throw): See through a SEQUENCE.

        * except.c (can_throw): See through a SEQUENCE.
        (nothrow_function_p): New fn.
        * except.h: Declare it.
        * function.c (current_function_nothrow): New var.
        (prepare_function_start): Initialize it.
        * output.h: Declare it.
        * toplev.c (rest_of_compilation): Set it.
        * dwarf2out.c (dwarf2out_begin_prologue): Use it.

From-SVN: r32449
parent 8051b178
2000-03-09 Jason Merrill <jason@casey.cygnus.com>
* except.c (can_throw): See through a SEQUENCE.
(nothrow_function_p): New fn.
* except.h: Declare it.
* function.c (current_function_nothrow): New var.
(prepare_function_start): Initialize it.
* output.h: Declare it.
* toplev.c (rest_of_compilation): Set it.
* dwarf2out.c (dwarf2out_begin_prologue): Use it.
2000-03-09 Zack Weinberg <zack@wolery.cumb.org> 2000-03-09 Zack Weinberg <zack@wolery.cumb.org>
* cpphash.c (collect_formal_parameters): strncmp returns 0 for * cpphash.c (collect_formal_parameters): strncmp returns 0 for
...@@ -409,7 +420,7 @@ Mon Mar 6 15:22:29 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> ...@@ -409,7 +420,7 @@ Mon Mar 6 15:22:29 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
(struct tree_int_cst): int_cst_low is now unsigned HOST_WIDE_INT. (struct tree_int_cst): int_cst_low is now unsigned HOST_WIDE_INT.
(attribute_hash_list, type_hash_canon): hashcode is now unsigned. (attribute_hash_list, type_hash_canon): hashcode is now unsigned.
(type_hash_lookup, type_hash_add, type_hash_list): Likewise. (type_hash_lookup, type_hash_add, type_hash_list): Likewise.
(min_precision): Result is unsignd. (min_precision): Result is unsigned.
(add_double, neg_double, mul_double): Low word is unsigned. (add_double, neg_double, mul_double): Low word is unsigned.
(lshift_double, rshift_double, lrotate_double): Likewise. (lshift_double, rshift_double, lrotate_double): Likewise.
(rrotate_double, div_and_round_double): Likewise. (rrotate_double, div_and_round_double): Likewise.
......
...@@ -1889,9 +1889,7 @@ dwarf2out_begin_prologue () ...@@ -1889,9 +1889,7 @@ dwarf2out_begin_prologue ()
fde->dw_fde_current_label = NULL; fde->dw_fde_current_label = NULL;
fde->dw_fde_end = NULL; fde->dw_fde_end = NULL;
fde->dw_fde_cfi = NULL; fde->dw_fde_cfi = NULL;
fde->nothrow = current_function_nothrow;
/* Normally, only calls can throw, so a leaf function will never throw. */
fde->nothrow = (current_function_is_leaf && !asynchronous_exceptions);
args_size = old_args_size = 0; args_size = old_args_size = 0;
} }
...@@ -7394,7 +7392,10 @@ add_abstract_origin_attribute (die, origin) ...@@ -7394,7 +7392,10 @@ add_abstract_origin_attribute (die, origin)
Doing this for nested functions is wrong, however; functions are Doing this for nested functions is wrong, however; functions are
distinct units, and our context might not even be inline. */ distinct units, and our context might not even be inline. */
tree fn = decl_function_context (origin); tree fn = origin;
if (TYPE_P (fn))
fn = TYPE_STUB_DECL (fn);
fn = decl_function_context (fn);
if (fn) if (fn)
gen_abstract_function (fn); gen_abstract_function (fn);
} }
......
...@@ -1646,16 +1646,7 @@ expand_fixup_region_end (cleanup) ...@@ -1646,16 +1646,7 @@ expand_fixup_region_end (cleanup)
} }
/* If we are using the setjmp/longjmp EH codegen method, we emit a /* If we are using the setjmp/longjmp EH codegen method, we emit a
call to __sjthrow. call to __sjthrow. Otherwise, we emit a call to __throw. */
Otherwise, we emit a call to __throw and note that we threw
something, so we know we need to generate the necessary code for
__throw.
Before invoking throw, the __eh_pc variable must have been set up
to contain the PC being thrown from. This address is used by
__throw to determine which exception region (if any) is
responsible for handling the exception. */
void void
emit_throw () emit_throw ()
...@@ -2629,6 +2620,10 @@ static int ...@@ -2629,6 +2620,10 @@ static int
can_throw (insn) can_throw (insn)
rtx insn; rtx insn;
{ {
if (GET_CODE (insn) == INSN
&& GET_CODE (PATTERN (insn)) == SEQUENCE)
insn = XVECEXP (PATTERN (insn), 0, 0);
/* Calls can always potentially throw exceptions, unless they have /* Calls can always potentially throw exceptions, unless they have
a REG_EH_REGION note with a value of 0 or less. */ a REG_EH_REGION note with a value of 0 or less. */
if (GET_CODE (insn) == CALL_INSN) if (GET_CODE (insn) == CALL_INSN)
...@@ -2649,6 +2644,24 @@ can_throw (insn) ...@@ -2649,6 +2644,24 @@ can_throw (insn)
return 0; return 0;
} }
/* Return nonzero if nothing in this function can throw. */
int
nothrow_function_p ()
{
rtx insn;
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
if (can_throw (insn))
return 0;
for (insn = current_function_epilogue_delay_list; insn;
insn = XEXP (insn, 1))
if (can_throw (insn))
return 0;
return 1;
}
/* Scan a exception region looking for the matching end and then /* Scan a exception region looking for the matching end and then
remove it if possible. INSN is the start of the region, N is the remove it if possible. INSN is the start of the region, N is the
region number, and DELETE_OUTER is to note if anything in this region number, and DELETE_OUTER is to note if anything in this
......
...@@ -427,6 +427,10 @@ extern struct label_node *outer_context_label_stack; ...@@ -427,6 +427,10 @@ extern struct label_node *outer_context_label_stack;
extern rtx exception_handler_labels; extern rtx exception_handler_labels;
/* Return nonzero if nothing in this function can throw. */
extern int nothrow_function_p PARAMS ((void));
/* Performs optimizations for exception handling, such as removing /* Performs optimizations for exception handling, such as removing
unnecessary exception regions. Invoked from jump_optimize (). */ unnecessary exception regions. Invoked from jump_optimize (). */
......
...@@ -107,6 +107,11 @@ Boston, MA 02111-1307, USA. */ ...@@ -107,6 +107,11 @@ Boston, MA 02111-1307, USA. */
compiler passes. */ compiler passes. */
int current_function_is_leaf; int current_function_is_leaf;
/* Nonzero if function being compiled doesn't contain any instructions
that can throw an exception. This is set prior to final. */
int current_function_nothrow;
/* Nonzero if function being compiled doesn't modify the stack pointer /* Nonzero if function being compiled doesn't modify the stack pointer
(ignoring the prologue and epilogue). This is only valid after (ignoring the prologue and epilogue). This is only valid after
life_analysis has run. */ life_analysis has run. */
...@@ -5760,6 +5765,7 @@ prepare_function_start () ...@@ -5760,6 +5765,7 @@ prepare_function_start ()
current_function_calls_alloca = 0; current_function_calls_alloca = 0;
current_function_contains_functions = 0; current_function_contains_functions = 0;
current_function_is_leaf = 0; current_function_is_leaf = 0;
current_function_nothrow = 0;
current_function_sp_is_unchanging = 0; current_function_sp_is_unchanging = 0;
current_function_uses_only_leaf_regs = 0; current_function_uses_only_leaf_regs = 0;
current_function_has_computed_jump = 0; current_function_has_computed_jump = 0;
......
...@@ -412,6 +412,11 @@ extern FILE *asm_out_file; ...@@ -412,6 +412,11 @@ extern FILE *asm_out_file;
extern int current_function_is_leaf; extern int current_function_is_leaf;
/* Nonzero if function being compiled doesn't contain any instructions
that can throw an exception. This is set prior to final. */
extern int current_function_nothrow;
/* Nonzero if function being compiled doesn't modify the stack pointer /* Nonzero if function being compiled doesn't modify the stack pointer
(ignoring the prologue and epilogue). This is only valid after (ignoring the prologue and epilogue). This is only valid after
life_analysis has run. */ life_analysis has run. */
......
...@@ -3674,10 +3674,12 @@ rest_of_compilation (decl) ...@@ -3674,10 +3674,12 @@ rest_of_compilation (decl)
print_rtl_graph_with_bb (dump_base_name, ".20.stack", insns); print_rtl_graph_with_bb (dump_base_name, ".20.stack", insns);
} }
if (ggc_p) if (ggc_p)
ggc_collect (); ggc_collect ();
#endif #endif
current_function_nothrow = nothrow_function_p ();
/* Now turn the rtl into assembler code. */ /* Now turn the rtl into assembler code. */
TIMEVAR (final_time, TIMEVAR (final_time,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment