aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/dwarf2out.c9
-rw-r--r--gcc/except.c33
-rw-r--r--gcc/except.h4
-rw-r--r--gcc/function.c6
-rw-r--r--gcc/output.h5
-rw-r--r--gcc/toplev.c6
7 files changed, 59 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a362174..cc420c7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+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>
* 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>
(struct tree_int_cst): int_cst_low is now unsigned HOST_WIDE_INT.
(attribute_hash_list, type_hash_canon): hashcode is now unsigned.
(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.
(lshift_double, rshift_double, lrotate_double): Likewise.
(rrotate_double, div_and_round_double): Likewise.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 20e8a1b..0f18779 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -1889,9 +1889,7 @@ dwarf2out_begin_prologue ()
fde->dw_fde_current_label = NULL;
fde->dw_fde_end = NULL;
fde->dw_fde_cfi = NULL;
-
- /* Normally, only calls can throw, so a leaf function will never throw. */
- fde->nothrow = (current_function_is_leaf && !asynchronous_exceptions);
+ fde->nothrow = current_function_nothrow;
args_size = old_args_size = 0;
}
@@ -7394,7 +7392,10 @@ add_abstract_origin_attribute (die, origin)
Doing this for nested functions is wrong, however; functions are
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)
gen_abstract_function (fn);
}
diff --git a/gcc/except.c b/gcc/except.c
index 7ecfaf8..987305a 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -1646,16 +1646,7 @@ expand_fixup_region_end (cleanup)
}
/* If we are using the setjmp/longjmp EH codegen method, we emit a
- call to __sjthrow.
-
- 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. */
+ call to __sjthrow. Otherwise, we emit a call to __throw. */
void
emit_throw ()
@@ -2629,6 +2620,10 @@ static int
can_throw (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
a REG_EH_REGION note with a value of 0 or less. */
if (GET_CODE (insn) == CALL_INSN)
@@ -2649,6 +2644,24 @@ can_throw (insn)
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
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
diff --git a/gcc/except.h b/gcc/except.h
index a1408c3..1087bc1 100644
--- a/gcc/except.h
+++ b/gcc/except.h
@@ -427,6 +427,10 @@ extern struct label_node *outer_context_label_stack;
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
unnecessary exception regions. Invoked from jump_optimize (). */
diff --git a/gcc/function.c b/gcc/function.c
index 093a0d8..1ffb821 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -107,6 +107,11 @@ Boston, MA 02111-1307, USA. */
compiler passes. */
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
(ignoring the prologue and epilogue). This is only valid after
life_analysis has run. */
@@ -5760,6 +5765,7 @@ prepare_function_start ()
current_function_calls_alloca = 0;
current_function_contains_functions = 0;
current_function_is_leaf = 0;
+ current_function_nothrow = 0;
current_function_sp_is_unchanging = 0;
current_function_uses_only_leaf_regs = 0;
current_function_has_computed_jump = 0;
diff --git a/gcc/output.h b/gcc/output.h
index 160f124..97c6f2e 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -412,6 +412,11 @@ extern FILE *asm_out_file;
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
(ignoring the prologue and epilogue). This is only valid after
life_analysis has run. */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index f10e1e2..8e1d5f7 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -3674,10 +3674,12 @@ rest_of_compilation (decl)
print_rtl_graph_with_bb (dump_base_name, ".20.stack", insns);
}
- if (ggc_p)
- ggc_collect ();
+ if (ggc_p)
+ ggc_collect ();
#endif
+ current_function_nothrow = nothrow_function_p ();
+
/* Now turn the rtl into assembler code. */
TIMEVAR (final_time,