Hello,

As some folks perhaps have noticed, my effort to make gcc use cfglayout
mode between expand and, roughly, sched1, have stagnated a bit.  I am
completely stuck on a problem that I basically can't trigger.  In other
words, I *know* I should expect problems if I make a certain change, but
I haven't been able to actually trigger that problem.

Let me explain that...  Consider the following code, from loop-unroll.c:

basic_block
split_edge_and_insert (edge e, rtx insns)
{
  basic_block bb;

  if (!insns)
    return NULL;
  bb = split_edge (e);
  emit_insn_after (insns, BB_END (bb));
  bb->flags |= BB_SUPERBLOCK;
  return bb;
}

We call this function to insert insns sequences produced by either
compare_and_jump_seq or expand_simple_binop.  compare_and_jump_seq can
produce insns sequences with control flow insns in it (i.e. jumps) (I am
not sure about expand_simple_binop, but I think it never needs control
flow insns).

We have to split a block with multiple control flow insns into multiple
blocks at some point.  We could split it in place, but loop-unroll
decides to defer it until going out of cfglayout mode, where we now have
to call break_superblocks to split the basic blocks with BB_SUPERBLOCK
set on them.

Here comes the problem: break_superblocks() doesn't work in cfglayout
mode.  There is no serialized insns stream, so you can't know what the
fallthrough edge should be.  I could fix this, but it is both unclean
and hard.  The alternative is to go out of cfglayout mode, fixup the
CFG, and go back into cfglayout mode.  Wasteful, IMHO, so I'd like to
avoid that solution, too.

I don't want to go out of cfglayout mode (I want to stay in it,
that's the whole point ;-) and since break_superblocks() doesn't work
for me, I have re-introduced find_sub_basic_blocks (which was removed
by Kazu long ago), made it work in cfglayout mode, and use it in
split_edge_and_insert().  That way, I update the CFG in place, and
simply avoid break_superblocks.

This was not hard to do.  I think.

But now that I've implemented it, I need to test the new code somehow.
And I can't find a test case.  I've tried to craft some test case based
on how I understand loop-unroll should work, but I did not succeed.  So
I moved on to brute force methods.

I have tested a small patch on i686, x86_64, ia64, mips, and sh:
----------------------------------------------------------
Index: loop-unroll.c
===================================================================
--- loop-unroll.c       (revision 122011)
+++ loop-unroll.c       (working copy)
@@ -879,7 +879,6 @@ split_edge_and_insert (edge e, rtx insns
     return NULL;
   bb = split_edge (e);
   emit_insn_after (insns, BB_END (bb));
-  bb->flags |= BB_SUPERBLOCK;
   return bb;
 }

----------------------------------------------------------

My thoughts here were, that if I can make the compiler crash with this
patch, my new find_sub_basic_blocks should fix that crash.  So I'm
trying to make gcc crash with the above patch.

I know for sure that the compiler would crash if it finds a basic block
with more than one control flow insn, but without the BB_SUPERBLOCK flag.
verify_flow_info has good checks for this.

But the patch doesn't trigger failures on the targets I tested.  I can't
get gcc to ICE with this patch, hence I can't find a test case for my
patch.

So I'm looking for help here: Who can help me find a test case to trigger
a verify_flow_info ICE in GCC with the above patch applied?  Can people
try this patch on their favorite target, and see if they can trigger a
test suite failure?

Hope you can help,

Thanks,

Gr.
Steven


Reply via email to