OSDN Git Service

* config/alpha/alpha.c (alpha_pad_noreturn): Rename to ...
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Aug 2012 18:44:40 +0000 (18:44 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Aug 2012 18:44:40 +0000 (18:44 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@190262 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/alpha/alpha.c

index 44b0d32..b2e8ec5 100644 (file)
@@ -1,3 +1,13 @@
+2012-08-09  Uros Bizjak  <ubizjak@gmail.com>
+
+       Backport from mainline
+       2012-08-09  Uros Bizjak  <ubizjak@gmail.com>
+
+       * 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.
+
 2012-08-09  H.J. Lu  <hongjiu.lu@intel.com>
 
        Backport from mainline
index 845b0f1..f27c08a 100644 (file)
@@ -9310,17 +9310,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
@@ -9352,8 +9353,28 @@ alpha_pad_noreturn (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     ldah    gp,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:
 
@@ -9373,11 +9394,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 ();