Patchwork Fix PR48900, powerpc duplicate __tls_get_addr calls

login
register
mail settings
Submitter Alan Modra
Date May 6, 2011, 2:17 a.m.
Message ID <20110506021704.GL7018@bubble.grove.modra.org>
Download mbox | patch
Permalink /patch/94337/
State New
Headers show

Comments

Alan Modra - May 6, 2011, 2:17 a.m.
My fix for PR44266 using the libcall machinery to ensure we had a
proper stack frame allocated for __tls_get_addr calls sloppily used r3
as the arg to the dummy libcall.  This made the call seem to depend on
whatever was in r3 previously, at least until we get to the first
split pass and the real arg is exposed.  So DCE couldn't merge calls.
Even for a simple testcase like
	extern __thread int i;
	void foo (void) { i++; }
we get two __tls_get_addr calls if using global-dynamic tls model.

Easliy fixed by giving the dummy libcall an arg of zero.  An
alternative giving slightly better -O0 code would be to say that the
libcall doesn't have any args.  I chose to leave the libcall with one
arg since this is closest to the real __tls_get_addr call, and the
whole point of faking up a libcall here is to have the generic code do
whatever is necessary when making function calls.  It's not totally
impossible to imagine some future ABI change that treats zero arg
calls differently from other calls.

Bootstrapped and regression tested powerpc64-linux.  OK to apply
mainline, 4.6 and 4.5?

	PR target/48900
	* config/rs6000/rs6000.c (rs6000_legitimize_tls_address): Use
	const0_rtx as the arg to the dummy __tls_get_addr libcall.
David Edelsohn - May 6, 2011, 1:10 p.m.
On Thu, May 5, 2011 at 10:17 PM, Alan Modra <amodra@gmail.com> wrote:
> My fix for PR44266 using the libcall machinery to ensure we had a
> proper stack frame allocated for __tls_get_addr calls sloppily used r3
> as the arg to the dummy libcall.  This made the call seem to depend on
> whatever was in r3 previously, at least until we get to the first
> split pass and the real arg is exposed.  So DCE couldn't merge calls.
> Even for a simple testcase like
>        extern __thread int i;
>        void foo (void) { i++; }
> we get two __tls_get_addr calls if using global-dynamic tls model.
>
> Easliy fixed by giving the dummy libcall an arg of zero.  An
> alternative giving slightly better -O0 code would be to say that the
> libcall doesn't have any args.  I chose to leave the libcall with one
> arg since this is closest to the real __tls_get_addr call, and the
> whole point of faking up a libcall here is to have the generic code do
> whatever is necessary when making function calls.  It's not totally
> impossible to imagine some future ABI change that treats zero arg
> calls differently from other calls.
>
> Bootstrapped and regression tested powerpc64-linux.  OK to apply
> mainline, 4.6 and 4.5?
>
>        PR target/48900
>        * config/rs6000/rs6000.c (rs6000_legitimize_tls_address): Use
>        const0_rtx as the arg to the dummy __tls_get_addr libcall.

Okay,.

Thanks, David

Patch

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 173464)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -6412,10 +6412,11 @@  rs6000_legitimize_tls_address (rtx addr,
 
       if (model == TLS_MODEL_GLOBAL_DYNAMIC)
 	{
-	  r3 = gen_rtx_REG (Pmode, 3);
 	  tga = rs6000_tls_get_addr ();
-	  emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
+	  emit_library_call_value (tga, dest, LCT_CONST, Pmode,
+				   1, const0_rtx, Pmode);
 
+	  r3 = gen_rtx_REG (Pmode, 3);
 	  if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
 	    insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
 	  else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
@@ -6432,11 +6433,12 @@  rs6000_legitimize_tls_address (rtx addr,
 	}
       else if (model == TLS_MODEL_LOCAL_DYNAMIC)
 	{
-	  r3 = gen_rtx_REG (Pmode, 3);
 	  tga = rs6000_tls_get_addr ();
 	  tmp1 = gen_reg_rtx (Pmode);
-	  emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
+	  emit_library_call_value (tga, tmp1, LCT_CONST, Pmode,
+				   1, const0_rtx, Pmode);
 
+	  r3 = gen_rtx_REG (Pmode, 3);
 	  if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
 	    insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
 	  else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)