Re: [PATCH, alpha]: Prevent another case of linker issues with exception handler

2012-08-09 Thread Uros Bizjak
On Thu, Aug 9, 2012 at 3:04 PM, Uros Bizjak  wrote:

> 2012-08-09  Uros Bizjak  
>
> * config/alpha/alpha.c (alpha_pad_noreturn): Rename to ...
> (alpha_pad_function_end): ... this.  Also insert NOP between
> sibling call and GP load.
> (alpha_reorg): Update call to alpha_pad_function_end.  Expand comment.
>
> Patch was bootstrapped and regression tested on alphaev68-pc-linux-gnu.
>
> OK for mainline and release branches?

Now with the patch.

Uros.
Index: alpha.c
===
--- alpha.c (revision 190247)
+++ alpha.c (working copy)
@@ -9258,17 +9258,18 @@ alpha_align_insns (unsigned int max_align,
 }
 }
 
-/* Insert an unop between a noreturn function call and GP load.  */
+/* Insert an unop between sibcall or noreturn function call and GP load.  */
 
 static void
-alpha_pad_noreturn (void)
+alpha_pad_function_end (void)
 {
   rtx insn, next;
 
   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
 {
   if (! (CALL_P (insn)
-&& find_reg_note (insn, REG_NORETURN, NULL_RTX)))
+&& (SIBLING_CALL_P (insn)
+|| find_reg_note (insn, REG_NORETURN, NULL_RTX
 continue;
 
   /* Make sure we do not split a call and its corresponding
@@ -9300,11 +9301,31 @@ static void
 static void
 alpha_reorg (void)
 {
-  /* Workaround for a linker error that triggers when an
- exception handler immediatelly follows a noreturn function.
+  /* Workaround for a linker error that triggers when an exception
+ handler immediatelly follows a sibcall or a noreturn function.
 
+In the sibcall case:
+
  The instruction stream from an object file:
 
+ 1d8:   00 00 fb 6b jmp (t12)
+ 1dc:   00 00 ba 27 ldahgp,0(ra)
+ 1e0:   00 00 bd 23 lda gp,0(gp)
+ 1e4:   00 00 7d a7 ldq t12,0(gp)
+ 1e8:   00 40 5b 6b jsr ra,(t12),1ec <__funcZ+0x1ec>
+
+ was converted in the final link pass to:
+
+   12003aa88:   67 fa ff c3 br  120039428 <...>
+   12003aa8c:   00 00 fe 2f unop
+   12003aa90:   00 00 fe 2f unop
+   12003aa94:   48 83 7d a7 ldq t12,-31928(gp)
+   12003aa98:   00 40 5b 6b jsr ra,(t12),12003aa9c <__func+0x1ec>
+
+And in the noreturn case:
+
+ The instruction stream from an object file:
+
   54:   00 40 5b 6b jsr ra,(t12),58 <__func+0x58>
   58:   00 00 ba 27 ldahgp,0(ra)
   5c:   00 00 bd 23 lda gp,0(gp)
@@ -9321,11 +9342,11 @@ alpha_reorg (void)
 
  GP load instructions were wrongly cleared by the linker relaxation
  pass.  This workaround prevents removal of GP loads by inserting
- an unop instruction between a noreturn function call and
+ an unop instruction between a sibcall or noreturn function call and
  exception handler prologue.  */
 
   if (current_function_has_exception_handlers ())
-alpha_pad_noreturn ();
+alpha_pad_function_end ();
 
   if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
 alpha_handle_trap_shadows ();


[PATCH, alpha]: Prevent another case of linker issues with exception handler

2012-08-09 Thread Uros Bizjak
Hello!

This problem is similar to [1], but in this case issue
occurs when exception handler immediately follows sibcall function.
This happens in libstdc++,

./include/ext/pb_ds/detail/binary_heap_/split_join_fn_imps.hpp: 130

This is the reason for testcase failure in [2]:

Running target unix
FAIL: ext/pb_ds/regression/priority_queue_rand.cc execution test

We have to prevent this situation in the same way as in [1]: pad
sibcall function call with a nop, when GP load immediately follows the
call. Following patch fixes the failure.

2012-08-09  Uros Bizjak  

* config/alpha/alpha.c (alpha_pad_noreturn): Rename to ...
(alpha_pad_function_end): ... this.  Also insert NOP between
sibling call and GP load.
(alpha_reorg): Update call to alpha_pad_function_end.  Expand comment.

Patch was bootstrapped and regression tested on alphaev68-pc-linux-gnu.

OK for mainline and release branches?

[1] http://gcc.gnu.org/ml/gcc-patches/2008-12/msg01097.html
[2] http://gcc.gnu.org/ml/gcc-testresults/2012-08/msg00583.html

Uros.