mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-17 16:29:40 +08:00
optabs.c (emit_libcall_block): Add a REG_EH_REGION reg note to all calls within a libcall block to indicate no...
* optabs.c (emit_libcall_block): Add a REG_EH_REGION reg note to all calls within a libcall block to indicate no throws are possible. * flow.c (find_basic_blocks, find_basic_blocks_1): Don't look for libcall blocks. Don't add edges to exception handlers if we see a REG_EH_REGION note with a value of 0. (make_edges): Override active_eh_region vector if the call has a note indicating the call does not throw. From-SVN: r24757
This commit is contained in:
parent
35a6fc8294
commit
b472794d0e
@ -1,3 +1,13 @@
|
||||
Tue Jan 19 12:30:37 EST 1999 Andrew MacLeod <amacleod@cygnus.com>
|
||||
|
||||
* optabs.c (emit_libcall_block): Add a REG_EH_REGION reg note to all
|
||||
calls within a libcall block to indicate no throws are possible.
|
||||
* flow.c (find_basic_blocks, find_basic_blocks_1): Don't look for
|
||||
libcall blocks. Don't add edges to exception handlers if we see
|
||||
a REG_EH_REGION note with a value of 0.
|
||||
(make_edges): Override active_eh_region vector if the call has a note
|
||||
indicating the call does not throw.
|
||||
|
||||
1999-01-19 Vladimir N. Makarov <vmakarov@cygnus.com>
|
||||
|
||||
* config/rs6000/sysv4.h (CC1_SPEC): Fix correct numbers of {}.
|
||||
|
67
gcc/flow.c
67
gcc/flow.c
@ -309,7 +309,6 @@ find_basic_blocks (f, nregs, file)
|
||||
register rtx insn;
|
||||
register int i;
|
||||
rtx nonlocal_label_list = nonlocal_label_rtx_list ();
|
||||
int in_libcall_block = 0;
|
||||
|
||||
/* Avoid leaking memory if this is called multiple times per compiled
|
||||
function. */
|
||||
@ -326,11 +325,6 @@ find_basic_blocks (f, nregs, file)
|
||||
|
||||
for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
|
||||
{
|
||||
/* Track when we are inside in LIBCALL block. */
|
||||
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
|
||||
&& find_reg_note (insn, REG_LIBCALL, NULL_RTX))
|
||||
in_libcall_block = 1;
|
||||
|
||||
code = GET_CODE (insn);
|
||||
|
||||
/* A basic block starts at label, or after something that can jump. */
|
||||
@ -354,17 +348,23 @@ find_basic_blocks (f, nregs, file)
|
||||
emit_insn_after (nop, prev_call);
|
||||
}
|
||||
}
|
||||
/* We change the code of the CALL_INSN, so that it won't start a
|
||||
new block. */
|
||||
if (code == CALL_INSN && in_libcall_block)
|
||||
code = INSN;
|
||||
|
||||
/* Record whether this call created an edge. */
|
||||
if (code == CALL_INSN)
|
||||
{
|
||||
prev_call = insn;
|
||||
call_had_abnormal_edge = (nonlocal_label_list != 0 || eh_region);
|
||||
}
|
||||
{
|
||||
rtx note = find_reg_note(insn, REG_EH_REGION, NULL_RTX);
|
||||
|
||||
/* We change the code of the CALL_INSN, so that it won't start a
|
||||
new block. */
|
||||
if (note && XINT (XEXP (note, 0), 0) == 0)
|
||||
code = INSN;
|
||||
else
|
||||
{
|
||||
prev_call = insn;
|
||||
call_had_abnormal_edge = (nonlocal_label_list != 0
|
||||
|| eh_region);
|
||||
}
|
||||
}
|
||||
|
||||
else if (code != NOTE && code != BARRIER)
|
||||
prev_call = 0;
|
||||
|
||||
@ -374,10 +374,6 @@ find_basic_blocks (f, nregs, file)
|
||||
++eh_region;
|
||||
else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)
|
||||
--eh_region;
|
||||
|
||||
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
|
||||
&& find_reg_note (insn, REG_RETVAL, NULL_RTX))
|
||||
in_libcall_block = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -447,7 +443,6 @@ find_basic_blocks_1 (f, nonlocal_labels)
|
||||
rtx note, eh_note;
|
||||
enum rtx_code prev_code, code;
|
||||
int depth;
|
||||
int in_libcall_block = 0;
|
||||
int call_had_abnormal_edge = 0;
|
||||
|
||||
active_eh_region = (int *) alloca ((max_uid_for_flow + 1) * sizeof (int));
|
||||
@ -475,12 +470,6 @@ find_basic_blocks_1 (f, nonlocal_labels)
|
||||
for (eh_note = NULL_RTX, insn = f, i = -1, prev_code = JUMP_INSN, depth = 1;
|
||||
insn; insn = NEXT_INSN (insn))
|
||||
{
|
||||
|
||||
/* Track when we are inside in LIBCALL block. */
|
||||
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
|
||||
&& find_reg_note (insn, REG_LIBCALL, NULL_RTX))
|
||||
in_libcall_block = 1;
|
||||
|
||||
code = GET_CODE (insn);
|
||||
if (code == NOTE)
|
||||
{
|
||||
@ -550,16 +539,19 @@ find_basic_blocks_1 (f, nonlocal_labels)
|
||||
for every insn, since most insns can throw. */
|
||||
else if (eh_note
|
||||
&& (asynchronous_exceptions
|
||||
|| (GET_CODE (insn) == CALL_INSN
|
||||
&& ! in_libcall_block)))
|
||||
|| (GET_CODE (insn) == CALL_INSN)))
|
||||
active_eh_region[INSN_UID (insn)] =
|
||||
NOTE_BLOCK_NUMBER (XEXP (eh_note, 0));
|
||||
BLOCK_NUM (insn) = i;
|
||||
|
||||
/* We change the code of the CALL_INSN, so that it won't start a
|
||||
new block. */
|
||||
if (code == CALL_INSN && in_libcall_block)
|
||||
code = INSN;
|
||||
new block if it doesn't throw. */
|
||||
if (code == CALL_INSN)
|
||||
{
|
||||
rtx rnote = find_reg_note(insn, REG_EH_REGION, NULL_RTX);
|
||||
if (rnote && XINT (XEXP (rnote, 0), 0) == 0)
|
||||
code = INSN;
|
||||
}
|
||||
|
||||
/* Record whether this call created an edge. */
|
||||
if (code == CALL_INSN)
|
||||
@ -568,9 +560,6 @@ find_basic_blocks_1 (f, nonlocal_labels)
|
||||
if (code != NOTE)
|
||||
prev_code = code;
|
||||
|
||||
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
|
||||
&& find_reg_note (insn, REG_RETVAL, NULL_RTX))
|
||||
in_libcall_block = 0;
|
||||
}
|
||||
|
||||
if (i + 1 != n_basic_blocks)
|
||||
@ -839,9 +828,15 @@ make_edges (i)
|
||||
|| (GET_CODE (insn) == CALL_INSN
|
||||
&& ! find_reg_note (insn, REG_RETVAL, NULL_RTX)))
|
||||
{
|
||||
if (active_eh_region[INSN_UID (insn)])
|
||||
int region = active_eh_region[INSN_UID (insn)];
|
||||
note = find_reg_note(insn, REG_EH_REGION, NULL_RTX);
|
||||
|
||||
/* Override region if we see a REG_EH_REGION note. */
|
||||
if (note)
|
||||
region = XINT (XEXP (note, 0), 0);
|
||||
|
||||
if (region)
|
||||
{
|
||||
int region;
|
||||
handler_info *ptr;
|
||||
region = active_eh_region[INSN_UID (insn)];
|
||||
for ( ; region; region = nested_eh_region[region])
|
||||
|
15
gcc/optabs.c
15
gcc/optabs.c
@ -2596,6 +2596,21 @@ emit_libcall_block (insns, target, result, equiv)
|
||||
{
|
||||
rtx prev, next, first, last, insn;
|
||||
|
||||
/* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
|
||||
reg note to indicate that this call cannot throw. (Unless there is
|
||||
already a REG_EH_REGION note.) */
|
||||
|
||||
for (insn = insns; insn; insn = NEXT_INSN (insn))
|
||||
{
|
||||
if (GET_CODE (insn) == CALL_INSN)
|
||||
{
|
||||
rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
|
||||
if (note == NULL_RTX)
|
||||
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (0),
|
||||
REG_NOTES (insn));
|
||||
}
|
||||
}
|
||||
|
||||
/* First emit all insns that set pseudos. Remove them from the list as
|
||||
we go. Avoid insns that set pseudos which were referenced in previous
|
||||
insns. These can be generated by move_by_pieces, for example,
|
||||
|
Loading…
Reference in New Issue
Block a user