diff options
author | kan <kan@FreeBSD.org> | 2003-11-07 02:43:04 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2003-11-07 02:43:04 +0000 |
commit | b09448931ae541a7a60fd1cf0ebac14b627fba69 (patch) | |
tree | 980c917e2cc50183c4d566d9a0f9a1c818e6a6cd /contrib/gcc/reg-stack.c | |
parent | dc227ec3ae9a56f16c472206f51e4838bb53a644 (diff) | |
download | FreeBSD-src-b09448931ae541a7a60fd1cf0ebac14b627fba69.zip FreeBSD-src-b09448931ae541a7a60fd1cf0ebac14b627fba69.tar.gz |
Gcc 3.3.3 20031106.
Diffstat (limited to 'contrib/gcc/reg-stack.c')
-rw-r--r-- | contrib/gcc/reg-stack.c | 71 |
1 files changed, 55 insertions, 16 deletions
diff --git a/contrib/gcc/reg-stack.c b/contrib/gcc/reg-stack.c index 1537c07..8e6731b 100644 --- a/contrib/gcc/reg-stack.c +++ b/contrib/gcc/reg-stack.c @@ -2616,11 +2616,12 @@ convert_regs_1 (file, block) { struct stack_def regstack; block_info bi = BLOCK_INFO (block); - int inserted, reg; + int deleted, inserted, reg; rtx insn, next; edge e, beste = NULL; inserted = 0; + deleted = 0; any_malformed_asm = false; /* Find the edge we will copy stack from. It should be the most frequent @@ -2652,10 +2653,24 @@ convert_regs_1 (file, block) beste = e; } - /* Entry block does have stack already initialized. */ + /* Initialize stack at block entry. */ if (bi->stack_in.top == -2) - inserted |= compensate_edge (beste, file); + { + if (beste) + inserted |= compensate_edge (beste, file); + else + { + /* No predecessors. Create an arbitrary input stack. */ + int reg; + + bi->stack_in.top = -1; + for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg) + if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg)) + bi->stack_in.reg[++bi->stack_in.top] = reg; + } + } else + /* Entry blocks do have stack already initialized. */ beste = NULL; current_block = block; @@ -2693,6 +2708,7 @@ convert_regs_1 (file, block) print_stack (file, ®stack); } subst_stack_regs (insn, ®stack); + deleted |= (GET_CODE (insn) == NOTE || INSN_DELETED_P (insn)); } } while (next); @@ -2732,8 +2748,23 @@ convert_regs_1 (file, block) nan); insn = emit_insn_after (set, insn); subst_stack_regs (insn, ®stack); + deleted |= (GET_CODE (insn) == NOTE || INSN_DELETED_P (insn)); } } + + /* Amongst the insns possibly deleted during the substitution process above, + might have been the only trapping insn in the block. We purge the now + possibly dead EH edges here to avoid an ICE from fixup_abnormal_edges, + called at the end of convert_regs. The order in which we process the + blocks ensures that we never delete an already processed edge. + + ??? We are normally supposed not to delete trapping insns, so we pretend + that the insns deleted above don't actually trap. It would have been + better to detect this earlier and avoid creating the EH edge in the first + place, still, but we don't have enough information at that time. */ + + if (deleted) + purge_dead_edges (block); /* Something failed if the stack lives don't match. If we had malformed asms, we zapped the instruction itself, but that didn't produce the @@ -2780,6 +2811,10 @@ convert_regs_2 (file, block) basic_block *stack, *sp; int inserted; + /* We process the blocks in a top-down manner, in a way such that one block + is only processed after all its predecessors. The number of predecessors + of every block has already been computed. */ + stack = (basic_block *) xmalloc (sizeof (*stack) * n_basic_blocks); sp = stack; @@ -2791,8 +2826,19 @@ convert_regs_2 (file, block) edge e; block = *--sp; - inserted |= convert_regs_1 (file, block); - BLOCK_INFO (block)->done = 1; + + /* Processing BLOCK is achieved by convert_regs_1, which may purge + some dead EH outgoing edge after the deletion of the trapping + insn inside the block. Since the number of predecessors of + BLOCK's successors was computed based on the initial edge set, + we check the necessity to process some of these successors + before such an edge deletion may happen. However, there is + a pitfall: if BLOCK is the only predecessor of a successor and + the edge between them happens to be deleted, the successor + becomes unreachable and should not be processed. The problem + is that there is no way to preventively detect this case so we + stack the successor in all cases and hand over the task of + fixing up the discrepancy to convert_regs_1. */ for (e = block->succ; e ; e = e->succ_next) if (! (e->flags & EDGE_DFS_BACK)) @@ -2801,6 +2847,9 @@ convert_regs_2 (file, block) if (!BLOCK_INFO (e->dest)->predecessors) *sp++ = e->dest; } + + inserted |= convert_regs_1 (file, block); + BLOCK_INFO (block)->done = 1; } while (sp != stack); @@ -2841,17 +2890,7 @@ convert_regs (file) block_info bi = BLOCK_INFO (b); if (! bi->done) - { - int reg; - - /* Create an arbitrary input stack. */ - bi->stack_in.top = -1; - for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg) - if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg)) - bi->stack_in.reg[++bi->stack_in.top] = reg; - - inserted |= convert_regs_2 (file, b); - } + inserted |= convert_regs_2 (file, b); } clear_aux_for_blocks (); |