[cfg-branch] fix BB duplication versus libcalls
Jan Hubicka
jh@suse.cz
Tue Nov 13 15:03:00 GMT 2001
Found as failure during mips bootstrap.
Wed Nov 14 14:04:14 CET 2001 Jan Hubicka <jh@suse.cz>
* cfglayout.c (cfg_layout_duplicate_bb): Grok libcall sequences.
Index: tracer.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Attic/tracer.c,v
retrieving revision 1.1.2.5
diff -c -3 -p -r1.1.2.5 tracer.c
*** tracer.c 2001/11/13 15:38:56 1.1.2.5
--- tracer.c 2001/11/14 13:05:43
***************
*** 45,51 ****
--- 45,66 ----
static int cmpblocks PARAMS ((const void *a, const void *b));
static void layout_traces PARAMS ((void));
static void construct_traces PARAMS ((void));
+ static int count_insns PARAMS ((basic_block));
+ /* Return number of instructions in the block. */
+ static int
+ count_insns (bb)
+ basic_block bb;
+ {
+ rtx insn;
+ int n = 0;
+
+ for (insn = bb->head; insn != NEXT_INSN (bb->end); insn = NEXT_INSN (insn))
+ if (active_insn_p (insn))
+ n++;
+ return n;
+ }
+
/* Return true if BB has been seen - it is connected to some trace
already. */
*************** construct_traces ()
*** 102,110 ****
--- 117,129 ----
basic_block *blocks = xmalloc (sizeof (basic_block) * n_basic_blocks);
int i;
int numblocks = n_basic_blocks;
+ int ninsns = 0, nduplicated = 0;
for (i = 0; i < numblocks; i++)
blocks [i] = BASIC_BLOCK (i);
+
+ for (i = 0; i < n_basic_blocks; i++)
+ ninsns += count_insns (BASIC_BLOCK (i));
qsort (blocks, numblocks, sizeof (basic_block), cmpblocks);
*************** construct_traces ()
*** 112,180 ****
{
basic_block bb = blocks [i];
! if (!seen (bb))
{
edge e;
! basic_block seed = bb;
if (rtl_dump_file)
! fprintf (rtl_dump_file, "Trace seed %i forward:\n", bb->index);
! while ((e = find_best_successor (bb)) != NULL)
{
! basic_block bb2 = e->dest;
! if (find_best_predecessor (bb2) != e
! || bb2 == EXIT_BLOCK_PTR
|| seen (bb2)
|| (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX)))
break;
if (rtl_dump_file)
! fprintf (rtl_dump_file, " %i", bb2->index);
! if (bb2->pred && bb2->pred->pred_next)
! {
! if (rtl_dump_file)
! fprintf (rtl_dump_file, " (duplicated)\n");
! if (!cfg_layout_can_duplicate_bb_p (bb2))
! break;
! bb2 = cfg_layout_duplicate_bb (bb2, e);
! }
! else if (rtl_dump_file)
! fprintf (rtl_dump_file, "\n");
! RBI (bb)->next = bb2;
! RBI (bb2)->visited = 1;
bb = bb2;
}
if (rtl_dump_file)
! fprintf (rtl_dump_file, " backward\n");
! bb = seed;
! while ((e = find_best_predecessor (bb)) != NULL)
{
! basic_block bb2 = e->src;
! if (find_best_successor (bb2) != e
! || bb2 == ENTRY_BLOCK_PTR
|| seen (bb2)
|| (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX)))
break;
if (rtl_dump_file)
! fprintf (rtl_dump_file, " %i", bb2->index);
! if (bb->pred && bb->pred->pred_next)
{
if (rtl_dump_file)
! fprintf (rtl_dump_file, "(duplicated)\n");
! if (!cfg_layout_can_duplicate_bb_p (bb))
! break;
! bb = cfg_layout_duplicate_bb (bb, e);
}
else if (rtl_dump_file)
fprintf (rtl_dump_file, "\n");
! RBI (bb2)->next = bb;
! RBI (bb)->visited = 1;
bb = bb2;
}
! if (rtl_dump_file)
! fprintf (rtl_dump_file, "\n");
}
}
free (blocks);
}
--- 131,197 ----
{
basic_block bb = blocks [i];
! while (!seen (bb))
{
edge e;
! bool found = 0;
if (rtl_dump_file)
! fprintf (rtl_dump_file, "Trace seed %i", bb->index);
!
! /* Look backward for the start of trace. */
! while ((e = find_best_predecessor (bb)) != NULL)
{
! basic_block bb2 = e->src;
! if (find_best_successor (bb2) != e
! || bb2 == ENTRY_BLOCK_PTR
|| seen (bb2)
|| (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX)))
break;
if (rtl_dump_file)
! fprintf (rtl_dump_file, " %i", bb2->index);
bb = bb2;
}
if (rtl_dump_file)
! fprintf (rtl_dump_file, "\n");
! /* Follow the trace doing duplication during process if needed.
! ??? This may trace terminate earlier than the loop above
! expects. The Hwu algorithm first finds whole trace and then
! duplicates it, but this looks like more fair heuristics
! (definitly resulting in fewer duplicates). */
! while ((e = find_best_successor (bb)) != NULL)
{
! basic_block bb2 = e->dest;
! if (find_best_predecessor (bb2) != e
! || bb2 == EXIT_BLOCK_PTR
|| seen (bb2)
|| (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX)))
break;
if (rtl_dump_file)
! fprintf (rtl_dump_file, " %i", bb2->index);
! if (bb2->pred && bb2->pred->pred_next
! && cfg_layout_can_duplicate_bb_p (bb2))
{
if (rtl_dump_file)
! fprintf (rtl_dump_file, " (duplicated)\n");
! bb2 = cfg_layout_duplicate_bb (bb2, e);
}
else if (rtl_dump_file)
fprintf (rtl_dump_file, "\n");
! found = 1;
! RBI (bb)->next = bb2;
! RBI (bb2)->visited = 1;
bb = bb2;
+ nduplicated += count_insns (bb2);
}
! if (!found)
! break;
}
}
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Duplicated %i insns (%i%%)\n", nduplicated,
+ nduplicated * 100 / ninsns);
free (blocks);
}
More information about the Gcc-patches
mailing list