Commit ad73b558 by Richard Henderson Committed by Richard Henderson

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
parent 461fc4de
...@@ -28,6 +28,12 @@ ...@@ -28,6 +28,12 @@
* final.c: Don't check it. * final.c: Don't check it.
* except.c: Provide stub definition. * 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> 2001-03-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* configure.in: Don't check for bcopy. * configure.in: Don't check for bcopy.
......
...@@ -2995,6 +2995,7 @@ tidy_fallthru_edges () ...@@ -2995,6 +2995,7 @@ tidy_fallthru_edges ()
merge the flags for the duplicate edges. So we do not want to merge the flags for the duplicate edges. So we do not want to
check that the edge is not a FALLTHRU edge. */ check that the edge is not a FALLTHRU edge. */
if ((s = b->succ) != NULL if ((s = b->succ) != NULL
&& ! (s->flags & EDGE_COMPLEX)
&& s->succ_next == NULL && s->succ_next == NULL
&& s->dest == c && s->dest == c
/* If the jump insn has side effects, we can't tidy the edge. */ /* 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) ...@@ -3542,13 +3543,19 @@ calculate_global_regs_live (blocks_in, blocks_out, flags)
int flags; int flags;
{ {
basic_block *queue, *qhead, *qtail, *qend; basic_block *queue, *qhead, *qtail, *qend;
regset tmp, new_live_at_end; regset tmp, new_live_at_end, call_used;
regset_head tmp_head; regset_head tmp_head, call_used_head;
regset_head new_live_at_end_head; regset_head new_live_at_end_head;
int i; int i;
tmp = INITIALIZE_REG_SET (tmp_head); tmp = INITIALIZE_REG_SET (tmp_head);
new_live_at_end = INITIALIZE_REG_SET (new_live_at_end_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 /* Create a worklist. Allocate an extra slot for ENTRY_BLOCK, and one
because the `head == tail' style test for an empty queue doesn't 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) ...@@ -3602,7 +3609,18 @@ calculate_global_regs_live (blocks_in, blocks_out, flags)
for (e = bb->succ; e; e = e->succ_next) for (e = bb->succ; e; e = e->succ_next)
{ {
basic_block sb = e->dest; 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. */ /* The all-important stack pointer must always be live. */
...@@ -3750,6 +3768,7 @@ calculate_global_regs_live (blocks_in, blocks_out, flags) ...@@ -3750,6 +3768,7 @@ calculate_global_regs_live (blocks_in, blocks_out, flags)
FREE_REG_SET (tmp); FREE_REG_SET (tmp);
FREE_REG_SET (new_live_at_end); FREE_REG_SET (new_live_at_end);
FREE_REG_SET (call_used);
if (blocks_out) if (blocks_out)
{ {
......
...@@ -2553,10 +2553,15 @@ convert_regs_1 (file, block) ...@@ -2553,10 +2553,15 @@ convert_regs_1 (file, block)
} }
} }
/* Care for EH edges specially. The normal return path may return /* Care for non-call EH edges specially. The normal return path have
a value in st(0), but the EH path will not, and there's no need values in registers. These will be popped en masse by the unwind
to add popping code to the edge. */ library. */
if (e->flags & (EDGE_EH | EDGE_ABNORMAL_CALL)) 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 /* Assert that the lifetimes are as we expect -- one value
live at st(0) on the end of the source block, and no live at st(0) on the end of the source block, and no
......
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