re PR target/9786 (Ice in fixup_abnormal_edges with -fnon-call-exceptions -O2)
PR target/9786 * reg-stack.c (convert_regs_1): Purge possible dead eh edges after potential deletion of trapping insn. Avoids later ICE from call to fixup_abnormal_edges. (convert_regs_2): Stack the current block successors before processing this block, that is, before the potential deletion of dead edges by convert_regs_1, because these edges have been used to initialize the predecessors count. From-SVN: r71644
This commit is contained in:
parent
316b38c83c
commit
de582cfbb9
4 changed files with 80 additions and 3 deletions
|
@ -1,3 +1,14 @@
|
|||
2003-09-22 Olivier Hainque <hainque@act-europe.fr>
|
||||
|
||||
PR target/9786
|
||||
* reg-stack.c (convert_regs_1): Purge possible dead eh edges
|
||||
after potential deletion of trapping insn. Avoids later ICE
|
||||
from call to fixup_abnormal_edges.
|
||||
(convert_regs_2): Stack the current block successors before
|
||||
processing this block, that is, before the potential deletion of
|
||||
dead edges by convert_regs_1, because these edges have been used
|
||||
to initialize the predecessors count.
|
||||
|
||||
2003-09-22 Eric Botcazou <ebotcazou@libertysurf.fr>
|
||||
|
||||
* real.c: Fix several nits in the head comment.
|
||||
|
|
|
@ -2638,11 +2638,12 @@ convert_regs_1 (FILE *file, basic_block 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
|
||||
|
@ -2715,6 +2716,7 @@ convert_regs_1 (FILE *file, basic_block block)
|
|||
print_stack (file, ®stack);
|
||||
}
|
||||
subst_stack_regs (insn, ®stack);
|
||||
deleted |= (GET_CODE (insn) == NOTE || INSN_DELETED_P (insn));
|
||||
}
|
||||
}
|
||||
while (next);
|
||||
|
@ -2754,8 +2756,23 @@ convert_regs_1 (FILE *file, basic_block 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
|
||||
|
@ -2800,6 +2817,10 @@ convert_regs_2 (FILE *file, basic_block 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 = xmalloc (sizeof (*stack) * n_basic_blocks);
|
||||
sp = stack;
|
||||
|
||||
|
@ -2811,9 +2832,13 @@ convert_regs_2 (FILE *file, basic_block 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 possible deletion of the
|
||||
trapping insn inside the block. Since the number of predecessors of
|
||||
"block"'s successors has been computed based on the initial edge set,
|
||||
we check for the possiblity to process some of these successors
|
||||
before such an edge deletion may happen. */
|
||||
for (e = block->succ; e ; e = e->succ_next)
|
||||
if (! (e->flags & EDGE_DFS_BACK))
|
||||
{
|
||||
|
@ -2821,6 +2846,9 @@ convert_regs_2 (FILE *file, basic_block block)
|
|||
if (!BLOCK_INFO (e->dest)->predecessors)
|
||||
*sp++ = e->dest;
|
||||
}
|
||||
|
||||
inserted |= convert_regs_1 (file, block);
|
||||
BLOCK_INFO (block)->done = 1;
|
||||
}
|
||||
while (sp != stack);
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2003-09-22 Eric Botcazou <ebotcazou@libertysurf.fr>
|
||||
|
||||
* g++.dg/opt/reg-stack2.C: New test.
|
||||
|
||||
2003-09-21 Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
|
||||
|
||||
* g++.dg/eh/delayslot1.C: New test.
|
||||
|
|
34
gcc/testsuite/g++.dg/opt/reg-stack2.C
Normal file
34
gcc/testsuite/g++.dg/opt/reg-stack2.C
Normal file
|
@ -0,0 +1,34 @@
|
|||
// PR target/9786
|
||||
// Origin: <nick@ilm.com>
|
||||
|
||||
// This used to fail on x86 because the reg-stack pass deleted
|
||||
// an insn that could seemingly trap (but actually doesn't)
|
||||
// without updating the CFG.
|
||||
|
||||
// { dg-do compile }
|
||||
// { dg-options "-O2 -fnon-call-exceptions" }
|
||||
|
||||
struct D1 {
|
||||
float l;
|
||||
D1 GS() const {D1 d;float f=.299*l;d.l=f;return d;}
|
||||
static D1 G() {return D1();}
|
||||
};
|
||||
|
||||
struct D2 {
|
||||
D1 g;
|
||||
D2(const D1& gi) : g(gi) {}
|
||||
D2 GS() const {return D2(g.GS());}
|
||||
};
|
||||
|
||||
class A {
|
||||
public:
|
||||
virtual ~A() {}
|
||||
};
|
||||
|
||||
class B : public A {
|
||||
public:
|
||||
B(const D2& mi);
|
||||
D2 fm;
|
||||
};
|
||||
|
||||
B::B(const D2 &mi) : fm(mi.GS()) {}
|
Loading…
Add table
Reference in a new issue