internal compiler error
Mike Stump
mrs@wrs.com
Mon Sep 15 12:56:00 GMT 1997
> Date: Fri, 05 Sep 1997 21:00:48 -0700
> From: Jim Wilson <wilson@cygnus.com>
> We don't actually want to do this for any setjmp call though, only for
> builtin setjmp calls. And we don't want to make calls go to any label
> whose address was taken, only to those labels which were created by
> expand_builtin_setjmp. Furthermore, for any particular call insn, we
> only want the labels that are for handlers that are in scope, not for all
> of the handlers. I suspect that there is only one handler in scope at
> a time? These are all optimizations though. They will give better code,
> but aren't necessary for correct code.
Ok, below is a start at this, but it isn't finished. It assumes that
all EH code is between the REGION notes, which is false, and that the
region notes that appear, are associated with the region that will be
thrown into, which is also false.
I kinda want to do the markup in the frontend, or in the backend at
expansion time... :-(
I'll come back to this work very soon (~<1 week), but I'm not working
on it right now.
Doing diffs in .:
*** ./flow.c.~1~ Wed Sep 10 14:58:47 1997
--- ./flow.c Wed Sep 10 17:32:59 1997
*************** find_basic_blocks (f, nonlocal_label_lis
*** 380,385 ****
--- 380,405 ----
rtx x, note;
enum rtx_code prev_code, code;
int depth, pass;
+ int max_labelno = max_label_num ();
+ int min_labelno = get_first_label_num ();
+ rtx *labels;
+ rtx handlers;
+
+ /* Generate a handy reference to each label. */
+
+ labels = (rtx *) alloca ((max_labelno - min_labelno) * sizeof (rtx));
+ bzero ((char *) labels, (max_labelno - min_labelno) * sizeof (rtx));
+
+ /* Arrange for labels to be indexed directly by CODE_LABEL_NUMBER. */
+ labels -= min_labelno;
+
+ for (insn = f; insn; insn = NEXT_INSN (insn))
+ {
+ if (GET_CODE (insn) == CODE_LABEL)
+ if (CODE_LABEL_NUMBER (insn) >= min_labelno
+ && CODE_LABEL_NUMBER (insn) < max_labelno)
+ labels[CODE_LABEL_NUMBER (insn)] = insn;
+ }
pass = 1;
restart:
*************** find_basic_blocks (f, nonlocal_label_lis
*** 560,569 ****
if (GET_CODE (insn) == CALL_INSN
&& ! find_reg_note (insn, REG_RETVAL, NULL_RTX))
{
- for (x = nonlocal_label_list; x; x = XEXP (x, 1))
- mark_label_ref (gen_rtx (LABEL_REF, VOIDmode, XEXP (x, 0)),
- insn, 0);
-
/* ??? This could be made smarter:
in some cases it's possible to tell that certain
calls will not do a nonlocal goto.
--- 580,585 ----
*************** find_basic_blocks (f, nonlocal_label_lis
*** 573,579 ****
--- 589,638 ----
only calls to those functions or to other nested
functions that use them could possibly do nonlocal
gotos. */
+
+ for (x = nonlocal_label_list; x; x = XEXP (x, 1))
+ mark_label_ref (gen_rtx (LABEL_REF, VOIDmode, XEXP (x, 0)),
+ insn, 0);
}
+
+ /* Handlers is a stack of outstanding exception handlers for the
+ current insn. The topmost handler will be the handler that
+ control is transferred to, if an exception is thrown. */
+
+ handlers = NULL_RTX;
+
+ for (insn = f; insn; insn = NEXT_INSN (insn))
+ {
+ code = GET_CODE (insn);
+ if (code == NOTE)
+ {
+ if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
+ {
+ rtx label = labels[NOTE_BLOCK_NUMBER (insn)];
+ handlers = gen_rtx (EXPR_LIST, VOIDmode,
+ label , handlers);
+ }
+ else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)
+ {
+ handlers = XEXP (handlers, 1);
+ }
+ }
+
+ /* ??? We would really like to check can_throw (insn) and if
+ that is true, do this, but I don't know if we can do this
+ for all the INSN types. (mrs) */
+
+ else if (GET_CODE (insn) == CALL_INSN
+ && handlers)
+ {
+ /* Find all call insns and mark them as possibly jumping
+ to it's exception handler label. */
+
+ mark_label_ref (gen_rtx (LABEL_REF, VOIDmode,
+ XEXP (handlers, 0)),
+ insn, 0);
+ }
+ }
/* All blocks associated with labels in label_value_list are
trivially considered as marked live, if the list is empty.
*** ./except.c.~1~ Wed Sep 10 15:00:54 1997
--- ./except.c Wed Sep 10 17:11:33 1997
*************** expand_eh_region_start_for_decl (decl)
*** 999,1010 ****
expand_dhc_cleanup (decl);
}
- if (exceptions_via_longjmp == 0)
- note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_BEG);
push_eh_entry (&ehstack);
! if (exceptions_via_longjmp == 0)
! NOTE_BLOCK_NUMBER (note)
! = CODE_LABEL_NUMBER (ehstack.top->entry->exception_handler_label);
if (exceptions_via_longjmp)
start_dynamic_handler ();
}
--- 999,1008 ----
expand_dhc_cleanup (decl);
}
push_eh_entry (&ehstack);
! note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_BEG);
! NOTE_BLOCK_NUMBER (note)
! = CODE_LABEL_NUMBER (ehstack.top->entry->exception_handler_label);
if (exceptions_via_longjmp)
start_dynamic_handler ();
}
*************** expand_eh_region_end (handler)
*** 1033,1049 ****
tree handler;
{
struct eh_entry *entry;
if (! doing_eh (0))
return;
entry = pop_eh_entry (&ehstack);
if (exceptions_via_longjmp == 0)
{
rtx label;
- rtx note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END);
- NOTE_BLOCK_NUMBER (note) = CODE_LABEL_NUMBER (entry->exception_handler_label);
label = gen_label_rtx ();
emit_jump (label);
--- 1031,1049 ----
tree handler;
{
struct eh_entry *entry;
+ rtx note;
if (! doing_eh (0))
return;
entry = pop_eh_entry (&ehstack);
+ note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END);
+ NOTE_BLOCK_NUMBER (note)
+ = CODE_LABEL_NUMBER (entry->exception_handler_label);
if (exceptions_via_longjmp == 0)
{
rtx label;
label = gen_label_rtx ();
emit_jump (label);
*************** exception_optimize ()
*** 2078,2087 ****
{
rtx insn, regions = NULL_RTX;
int n;
-
- /* The below doesn't apply to setjmp/longjmp EH. */
- if (exceptions_via_longjmp)
- return;
/* Remove empty regions. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
--- 2078,2083 ----
*** ./final.c.~1~ Wed Sep 10 15:01:01 1997
--- ./final.c Wed Sep 10 15:07:19 1997
*************** final_scan_insn (insn, file, optimize, p
*** 1379,1385 ****
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
break;
! if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
{
ASM_OUTPUT_INTERNAL_LABEL (file, "LEHB", NOTE_BLOCK_NUMBER (insn));
add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
--- 1379,1386 ----
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
break;
! if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
! && ! exceptions_via_longjmp)
{
ASM_OUTPUT_INTERNAL_LABEL (file, "LEHB", NOTE_BLOCK_NUMBER (insn));
add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
*************** final_scan_insn (insn, file, optimize, p
*** 1389,1395 ****
break;
}
! if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)
{
ASM_OUTPUT_INTERNAL_LABEL (file, "LEHE", NOTE_BLOCK_NUMBER (insn));
#ifdef ASM_OUTPUT_EH_REGION_END
--- 1390,1397 ----
break;
}
! if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END
! && ! exceptions_via_longjmp)
{
ASM_OUTPUT_INTERNAL_LABEL (file, "LEHE", NOTE_BLOCK_NUMBER (insn));
#ifdef ASM_OUTPUT_EH_REGION_END
--------------
More information about the Gcc-bugs
mailing list