diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-11-02 02:09:55 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-11-02 02:09:55 +0000 |
commit | 8e3edf9813a4f2282b3cc82db367e7e7b7079741 (patch) | |
tree | c5a520cf73a007a0f548351a520fde31b59dddc0 /gcc/reg-stack.c | |
parent | 2fc453e651840c339b4f1d7386e84d91716f57f9 (diff) | |
download | gcc-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.c | 32 |
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 (); |