summaryrefslogtreecommitdiff
path: root/gcc/reg-stack.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1999-11-02 02:09:55 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1999-11-02 02:09:55 +0000
commit8e3edf9813a4f2282b3cc82db367e7e7b7079741 (patch)
treec5a520cf73a007a0f548351a520fde31b59dddc0 /gcc/reg-stack.c
parent2fc453e651840c339b4f1d7386e84d91716f57f9 (diff)
downloadgcc-8e3edf9813a4f2282b3cc82db367e7e7b7079741.tar.gz
* reg-stack.c (convert_regs_1): Handle EH edges specially.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@30336 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reg-stack.c')
-rw-r--r--gcc/reg-stack.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index c30d709fed1..e20e92e8595 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -2514,12 +2514,34 @@ 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)
+ {
+ /* Assert that the lifetimes are as we expect -- one value
+ live at st(0) on the end of the source block, and no
+ values live at the beginning of the destination block. */
+ HARD_REG_SET tmp;
+
+ CLEAR_HARD_REG_SET (tmp);
+ GO_IF_HARD_REG_EQUAL (BLOCK_INFO (e->dest)->stack_in.reg_set,
+ tmp, eh1);
+ abort();
+ eh1:
+
+ SET_HARD_REG_BIT (tmp, FIRST_STACK_REG);
+ GO_IF_HARD_REG_EQUAL (BLOCK_INFO (e->src)->out_reg_set, tmp, eh2);
+ abort();
+ eh2:;
+ }
+
/* It is better to output directly to the end of the block
instead of to the edge, because emit_swap can do minimal
insn scheduling. We can do this when there is only one
edge out, and it is not abnormal. */
- if (block->succ->succ_next == NULL
- && ! (e->flags & EDGE_ABNORMAL))
+ else if (block->succ->succ_next == NULL
+ && ! (e->flags & EDGE_ABNORMAL))
{
/* change_stack kills values in regstack. */
tmpstack = regstack;
@@ -2532,9 +2554,9 @@ convert_regs_1 (file, block)
{
rtx seq, after;
- /* We don't support abnormal edges. Global takes
- care to avoid any live register across them, so
- we should never have to. */
+ /* We don't support abnormal edges. Global takes care to
+ avoid any live register across them, so we should never
+ have to insert instructions on such edges. */
if (e->flags & EDGE_ABNORMAL)
abort ();