Message ID | 4E8CEC99.2000105@codesourcery.com |
---|---|
State | New |
Headers | show |
Bernd Schmidt <bernds@codesourcery.com> writes: > 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. Thinking about it I think this is the wrong approach. The -fsplit-stack code by definition has to wrap the entire function and it can not modify any callee-saved registers. We should do shrink wrapping before -fsplit-stack, not the other way around. Ian
On 10/06/11 05:17, Ian Lance Taylor wrote: > Thinking about it I think this is the wrong approach. The -fsplit-stack > code by definition has to wrap the entire function and it can not modify > any callee-saved registers. We should do shrink wrapping before > -fsplit-stack, not the other way around. Sorry, I'm not following what you're saying here. Can you elaborate? Bernd
On 10/06/11 01:47, Bernd Schmidt wrote: > 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. Testing of the patch completed - ok? Regardless of split-stack it seems like a cleanup and eliminates a potential source of errors. Bernd
On 10/06/2011 06:37 AM, Bernd Schmidt wrote: > On 10/06/11 01:47, Bernd Schmidt wrote: >> 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. > > Testing of the patch completed - ok? Regardless of split-stack it seems > like a cleanup and eliminates a potential source of errors. Yes, patch is ok. r~
Bernd Schmidt <bernds@codesourcery.com> writes: > On 10/06/11 05:17, Ian Lance Taylor wrote: >> Thinking about it I think this is the wrong approach. The -fsplit-stack >> code by definition has to wrap the entire function and it can not modify >> any callee-saved registers. We should do shrink wrapping before >> -fsplit-stack, not the other way around. > > Sorry, I'm not following what you're saying here. Can you elaborate? Basically -fsplit-stack wraps the entire function in code that (on x86_64) looks like cmpq %fs:112, %rsp jae .L2 movl $24, %r10d movl $0, %r11d call __morestack ret .L2: There is absolutely no reason to try to shrink wrap that code. It will never help. That code always has to be first. It especially has to be first because the gold linker recognizes the prologue specially when a split-stack function calls a non-split-stack function, in order to request a larger stack. Therefore, it seems to me that we should apply shrink wrapping to the function as it exists *before* the split-stack prologue is created. The flag_split_stack bit should be moved after the flag_shrink_wrap bit. Ian
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