flow.c (tidy_fallthru_edges): Don't combine complex edges.

* flow.c (tidy_fallthru_edges): Don't combine complex edges.
        (calculate_global_regs_live): Kill call-clobbered registers
        across exception edges.
        * reg-stack.c (convert_regs_1): Kill the entire target stack
        across non-call exception edges.

From-SVN: r40909
This commit is contained in:
Richard Henderson 2001-03-27 22:22:23 -08:00 committed by Richard Henderson
parent 461fc4de6a
commit ad73b55832
3 changed files with 37 additions and 7 deletions

View File

@ -28,6 +28,12 @@
* final.c: Don't check it.
* except.c: Provide stub definition.
* flow.c (tidy_fallthru_edges): Don't combine complex edges.
(calculate_global_regs_live): Kill call-clobbered registers
across exception edges.
* reg-stack.c (convert_regs_1): Kill the entire target stack
across non-call exception edges.
2001-03-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* configure.in: Don't check for bcopy.

View File

@ -2995,6 +2995,7 @@ tidy_fallthru_edges ()
merge the flags for the duplicate edges. So we do not want to
check that the edge is not a FALLTHRU edge. */
if ((s = b->succ) != NULL
&& ! (s->flags & EDGE_COMPLEX)
&& s->succ_next == NULL
&& s->dest == c
/* If the jump insn has side effects, we can't tidy the edge. */
@ -3542,13 +3543,19 @@ calculate_global_regs_live (blocks_in, blocks_out, flags)
int flags;
{
basic_block *queue, *qhead, *qtail, *qend;
regset tmp, new_live_at_end;
regset_head tmp_head;
regset tmp, new_live_at_end, call_used;
regset_head tmp_head, call_used_head;
regset_head new_live_at_end_head;
int i;
tmp = INITIALIZE_REG_SET (tmp_head);
new_live_at_end = INITIALIZE_REG_SET (new_live_at_end_head);
call_used = INITIALIZE_REG_SET (call_used_head);
/* Inconveniently, this is only redily available in hard reg set form. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
if (call_used_regs[i])
SET_REGNO_REG_SET (call_used, i);
/* Create a worklist. Allocate an extra slot for ENTRY_BLOCK, and one
because the `head == tail' style test for an empty queue doesn't
@ -3602,7 +3609,18 @@ calculate_global_regs_live (blocks_in, blocks_out, flags)
for (e = bb->succ; e; e = e->succ_next)
{
basic_block sb = e->dest;
IOR_REG_SET (new_live_at_end, sb->global_live_at_start);
/* Call-clobbered registers die across exception and call edges. */
/* ??? Abnormal call edges ignored for the moment, as this gets
confused by sibling call edges, which crashes reg-stack. */
if (e->flags & EDGE_EH)
{
bitmap_operation (tmp, sb->global_live_at_start,
call_used, BITMAP_AND_COMPL);
IOR_REG_SET (new_live_at_end, tmp);
}
else
IOR_REG_SET (new_live_at_end, sb->global_live_at_start);
}
/* The all-important stack pointer must always be live. */
@ -3750,6 +3768,7 @@ calculate_global_regs_live (blocks_in, blocks_out, flags)
FREE_REG_SET (tmp);
FREE_REG_SET (new_live_at_end);
FREE_REG_SET (call_used);
if (blocks_out)
{

View File

@ -2553,10 +2553,15 @@ convert_regs_1 (file, block)
}
}
/* Care for EH edges specially. The normal return path may return
a value in st(0), but the EH path will not, and there's no need
to add popping code to the edge. */
if (e->flags & (EDGE_EH | EDGE_ABNORMAL_CALL))
/* Care for non-call EH edges specially. The normal return path have
values in registers. These will be popped en masse by the unwind
library. */
if ((e->flags & (EDGE_EH | EDGE_ABNORMAL_CALL)) == EDGE_EH)
target_stack->top = -1;
/* Other calls may appear to have values live in st(0), but the
abnormal return path will not have actually loaded the values. */
else if (e->flags & EDGE_ABNORMAL_CALL)
{
/* Assert that the lifetimes are as we expect -- one value
live at st(0) on the end of the source block, and no