[tree-ssa] (analysis) bootstrap failure on armv5l-linux
Jeroen Dobbelaere
jeroen.dobbelaere@advalvas.be
Fri Jun 13 22:48:00 GMT 2003
Hi,
I've been looking to the problem, and this is what I see happening :
In toplev.c, we do optimization of 'basic block reordening' (bbro) :
if (optimize > 0)
{
timevar_push (TV_REORDER_BLOCKS);
open_dump_file (DFI_bbro, decl);
/* Last attempt to optimize CFG, as scheduling, peepholing and insn
splitting possibly introduced more crossjumping opportunities. */
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE
| (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
if (flag_sched2_use_traces && flag_schedule_insns_after_reload)
tracer ();
if (flag_reorder_blocks)
reorder_basic_blocks ();
if (flag_reorder_blocks
|| (flag_sched2_use_traces && flag_schedule_insns_after_reload))
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
timevar_pop (TV_REORDER_BLOCKS);
}
At some moment, basic blocks are merged (cfgcleanup.c:merge_blocks), as
is demonstrated in the tracedump :
(See <http://gcc.gnu.org/ml/gcc/2003-05/msg02062.html>)
[..]
try_optimize_cfg iteration 1
Deleted label in block 1.
Deleted label in block 3.
Deleted label in block 9.
Deleted label in block 10.
Forwarding edge 13->14 to 5 failed.
Merged 15 and 16 without moving.
Merged 17 and 18 without moving.
try_optimize_cfg iteration 2
[..]
The problem the we encounter now is that when blocks 15 and 16 are
merged, the 'register live' information is not updated :
BUT :
- for block 15, r0 is supposed to be live at the beginning and live at
the end, with r0 conditionally being set
- for block 16, the same rules hold. (with a reverse condition)
When those two are merged, r0 will always be set, so it is not live any
more at entry.
At a later optimization stage, this difference is detected, resulting in
an abort.
My 'simple' solution is to add the line after '//@ JDO' to
merge_blocks() (cfgcleanup.c:798)
/* If B has a fallthru edge to C, no need to move anything. */
if (e->flags & EDGE_FALLTHRU)
{
int b_index = b->index, c_index = c->index;
merge_blocks_nomove (b, c);
update_forwarder_flag (b);
//@ JDO 20030613 : a merged block can have a more complete view on
register liveness (??)
b->flags |= BB_DIRTY;
if (rtl_dump_file)
fprintf (rtl_dump_file, "Merged %d and %d without moving.\n",
b_index, c_index);
return b->prev_bb == ENTRY_BLOCK_PTR ? b : b->prev_bb;
}
So that after the merger, the register liveness is updated.
But this is probably not the ideal solution...
Greetings,
Jeroen Dobbelaere
More information about the Gcc
mailing list