[PATCH 5/6] [RS6000] Use standard call patterns for __tls_get_addr calls

Segher Boessenkool segher@kernel.crashing.org
Tue Nov 27 16:29:00 GMT 2018


Hi!

On Tue, Nov 13, 2018 at 11:22:43PM +1030, Alan Modra wrote:
> Version 2.
> 
> The current code handling __tls_get_addr calls for powerpc*-linux
> generates a call then overwrites the call insn with a special
> tls_{gd,ld}_{aix,sysv} pattern.  It's done that way to support
> !TARGET_TLS_MARKERS, where the arg setup insns need to be emitted
> immediately before the branch and link.  When TARGET_TLS_MARKERS, the
> arg setup insns are split from the actual call, but we then have a
> non-standard call pattern that needs to be carried through to output.
> 
> This patch changes that scheme, to instead use the standard call
> patterns for __tls_get_addr calls, except for the now rare
> !TARGET_TLS_MARKERS case.  Doing it this way should be better for
> maintenance as the !TARGET_TLS_MARKERS code can eventually disappear.
> It also makes it possible to support longcalls (and in following
> patches, inline plt calls) for __tls_get_addr without introducing yet
> more special call patterns.
> 
> __tls_get_addr calls do however need to be different to standard
> calls, because when TARGET_TLS_MARKERS the calls are decorated with an
> argument specifier, eg. "bl __tls_get_addr(thread_var@tlsgd)" that
> causes a reloc to be emitted by the assembler tying the call to its
> arg setup insns.  I chose to smuggle the arg in the currently unused
> stack size rtl.
> 
> I've also introduced rs6000_call_sysv to generate rtl for sysv calls,
> as rs6000_call_aix does for aix and elfv2 calls.  This allows
> rs6000_longcall_ref to be local to rs6000.c since the calls in the
> expanders never did anything for darwin.
> 
> 	* config/rs6000/predicates.md (unspec_tls): New.
> 	* config/rs6000/rs6000-protos.h (rs6000_call_template),
> 	(rs6000_sibcall_template): Update prototype.
> 	(rs6000_longcall_ref): Delete.
> 	(rs6000_call_sysv): Declare.
> 	* config/rs6000/rs6000.c (edit_tls_call_insn): New function.
> 	(global_tlsarg): New variable.
> 	(rs6000_legitimize_tls_address): Rewrite __tls_get_addr call
> 	handling.
> 	(print_operand): Extract UNSPEC_TLSGD address operand.
> 	(rs6000_call_template, rs6000_sibcall_template): Remove arg
> 	parameter, extract from second call operand instead.
> 	(rs6000_longcall_ref): Make static, localize vars.
> 	(rs6000_call_aix): Rename parameter to reflect new usage.  Take
> 	tlsarg from global_tlsarg.  Don't create unused rtl or nop insns.
> 	(rs6000_sibcall_aix): Rename parameter to reflect new usage.  Take
> 	tlsarg from global_tlsarg.
> 	(rs6000_call_sysv): New function.
> 	* config/rs6000/rs6000.md: Adjust rs6000_call_template and
> 	rs6000_sibcall_template throughout.
> 	(tls_gd_aix, tls_gd_sysv, tls_gd_call_aix, tls_gd_call_sysv): Delete.
> 	(tls_ld_aix, tls_ld_sysv, tls_ld_call_aix, tls_ld_call_sysv): Delete.
> 	(tls_gdld_aix, tls_gdld_sysv): New insns, replacing above.
> 	(tls_gd): Swap operand order.  Simplify mode selection.
> 	(tls_gd_high, tls_gd_low): Swap operand order.
> 	(tls_ld): Remove const_int 0 vector element from UNSPEC_TLSLD.
> 	Simplify mode selection.
> 	(tls_ld_high, tls_ld_low): Similarly adjust UNSPEC_TLSLD.
> 	(call, call_value): Don't assert for second call operand.
> 	Use rs6000_call_sysv.


> +/* Passes the tls arg value for global dynamic and local dynamic
> +   emit_library_call_value in rs6000_legitimize_Tls_address to
> +   rs6000_call_aix and rs6000_call_sysv.  This is used to emit the
> +   marker relocs put on __tls_get_addr calls.  */
> +static rtx global_tlsarg;

Typo (s/_Tls/_tls/).

> +(define_insn "*tls_gdld_aix<P:bits>"
> +  [(match_parallel 3 ""

A match_parallel without predicate...  Does this work?!  Does this not
accidentally pick up the wrong things?

Do you think we should to deprecate -mtls-markers in GCC 9?

Please test with -mtls-markers, too, if you can, and test on AIX.

Looks fine.  Thank you for the cleanup!  Okay for trunk, but please do the
extra testing.


Segher



More information about the Gcc-patches mailing list