On 10/06/11 01:04, Ian Lance Taylor wrote:
> On Wed, Oct 5, 2011 at 10:17 AM, Bernd Schmidt <[email protected]>
> wrote:
>>
>> I've committed the following after a x86_64-linux bootstrap.
>
> This patch appears to have broken the Go bootstrap when compiling a C
> file in libgo. Here is a reduced test case:
>
> static struct
> {
> int n;
> unsigned int m;
> _Bool f;
> } g;
>
> _Bool
> f (int s)
> {
> unsigned int b, m;
>
> if (!g.f)
> return 0;
> b = 1 << s;
> while (1)
> {
> m = g.m;
> if (m & b)
> break;
> if (__sync_bool_compare_and_swap (&g.m, m, m|b))
> {
> if (m == 0)
> f2 (&g.n);
> break;
> }
> }
> return 1;
> }
>
> Compiling this file with -O2 -fsplit-stack causes an ICE:
>
> foo.c:29:1: internal compiler error: in maybe_record_trace_start, at
> dwarf2cfi.c:2243
>
> Compiling the file with -O2 -fsplit-stack -fno-shrink-wrap works.
This appears to be because the split prologue contains a jump, which
means the find_many_sub_blocks call reorders the block numbers, and our
indices into bb_flags are off.
I'm testing the following patch, but it won't finish today - feel free
to test and check it in, or to just disable shrink-wrapping with split
prologues.
Bernd
Index: gcc/function.c
===================================================================
--- gcc/function.c (revision 179577)
+++ gcc/function.c (working copy)
@@ -5455,7 +5455,7 @@ thread_prologue_and_epilogue_insns (void
basic_block last_bb;
bool last_bb_active;
#ifdef HAVE_simple_return
- bool unconverted_simple_returns = false;
+ VEC (basic_block, heap) *unconverted_simple_returns = NULL;
basic_block simple_return_block_hot = NULL;
basic_block simple_return_block_cold = NULL;
bool nonempty_prologue;
@@ -5876,7 +5876,8 @@ thread_prologue_and_epilogue_insns (void
{
#ifdef HAVE_simple_return
if (simple_p)
- unconverted_simple_returns = true;
+ VEC_safe_push (basic_block, heap,
+ unconverted_simple_returns, bb);
#endif
continue;
}
@@ -5894,7 +5895,8 @@ thread_prologue_and_epilogue_insns (void
{
#ifdef HAVE_simple_return
if (simple_p)
- unconverted_simple_returns = true;
+ VEC_safe_push (basic_block, heap,
+ unconverted_simple_returns, bb);
#endif
continue;
}
@@ -6042,10 +6044,11 @@ epilogue_done:
convert to conditional simple_returns, but couldn't for some
reason, create a block to hold a simple_return insn and redirect
those remaining edges. */
- if (unconverted_simple_returns)
+ if (!VEC_empty (basic_block, unconverted_simple_returns))
{
- edge_iterator ei2;
basic_block exit_pred = EXIT_BLOCK_PTR->prev_bb;
+ basic_block src_bb;
+ int i;
gcc_assert (entry_edge != orig_entry_edge);
@@ -6062,19 +6065,12 @@ epilogue_done:
simple_return_block_cold = e->dest;
}
- restart_scan:
- for (ei2 = ei_start (last_bb->preds); (e = ei_safe_edge (ei2)); )
+ FOR_EACH_VEC_ELT (basic_block, unconverted_simple_returns, i, src_bb)
{
- basic_block bb = e->src;
+ edge e = find_edge (src_bb, last_bb);
basic_block *pdest_bb;
- if (bb == ENTRY_BLOCK_PTR
- || bitmap_bit_p (&bb_flags, bb->index))
- {
- ei_next (&ei2);
- continue;
- }
- if (BB_PARTITION (e->src) == BB_HOT_PARTITION)
+ if (BB_PARTITION (src_bb) == BB_HOT_PARTITION)
pdest_bb = &simple_return_block_hot;
else
pdest_bb = &simple_return_block_cold;
@@ -6094,8 +6090,8 @@ epilogue_done:
make_edge (bb, EXIT_BLOCK_PTR, 0);
}
redirect_edge_and_branch_force (e, *pdest_bb);
- goto restart_scan;
}
+ VEC_free (basic_block, heap, unconverted_simple_returns);
}
#endif