[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