This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, RQ Review] convert emulated TLS so that it works with LTO and WHOPR.


Emulated TLS is used by a number of gcc targets and, at present, is not able to support LTO and WHOPR.

This is because the substitution of the control var for the user one is carried out too late to be streamed properly.

The attached patch based on Honza's original suggestions is a "proper" solution to PR44132,
(with the currently applied patch recognized as a work-around).


what this does is to move the substitution of __emutls_v.xxxx to every place that a variable is finalized or a reference gimplified.

The original "master" or "user" vars are marked as not requiring output.
.. although they are still caught in assemble_variable (and friends) just in case someone resets the flag.


Aliases are handled by walking the alias pairs, re-mapping the aliases between the original vars so that they now exist between the control vars.

There are some small rearrangements in varpool_finalize_decl().
The first is to remove the early calls to varpool_assemble_pending_decls() after discussion with Honza on irc.
there is a global call to this in toplev.c
The second is to reorder the
if (node->needed)
varpool_enqueue_needed_node (node);


until *after* all the needed checks are made.
AFAICT it's possible for a var to be marked as finalized without being queued at present, since the finalized flag causes the routine to exit before the enqueing.


I have been using this for a few weeks now on *-darwin{9,10} and tested on cris-elf, which is an emutls target with alises (and as a NULL test that it makes no difference to i686-pc-linux-gnu).

There is a single regression:
gcc.dg/tls/asm-1.c - However, I believe that this regression is due to gimplify_asm() not considering the possibility of needing to expand the arguments (i.e. not specifically a fault in the emu TLS implementation).


===

I put a set of test suite additions on the PR referenced, that run under the torture conditions and therefore are applied with lto/whopr for targets using those. These extra tests are in my local trees
(in fact, I've also applied the approach of making all TLS content in the test- suite applicable to emulated TLS, where appropriate). [see http://gcc.gnu.org/ml/gcc-patches/2010-05/msg00943.html , for example].


There is also an issue to resolve with g++.dg/tls/init-2.C (if that is enabled). Again, this seems to be a problem outside the TLS implementation (in that there are two conflicting error messages and then a failure when it apparently tries to create a constructor for a non-existent var).

====

I would hope that this is reasonably close to applicability, on the ground that the general approach was as suggested by Honza.
However, all misunderstanding &| faults with the rendition are certainly mine ;)


This is my most complex endeavor so far, so please scrutinize carefully and don't bite too hard.

Iain
====

gcc/Changelog:

* emults.c (general): Add some comments on the implementation.
(__emutls_get_address): Adjust memset initial offset.
(__emutls_register_common): Abort on NULL object pointer (debug code, to be removed).


	* expr.c (emutls_var_address): Remove.
	(expand_expr_addr_expr_1): Remove TLS emulation hook.
	(expand_expr_real_1): Ditto.

	* gimplify.c (emutls_var_address): Add proc.
	(gimplify_decl_expr): expand TLS vars.
	(gimplify_var_or_parm_decl): Ditto.
	(omp_notice_variable): Recognize TLS_MODEL_EMULATED.

* passes.c (rest_of_decl_compilation): Substitute TLS control vars for the master.

* varasm.c (get_emutls_init_templ_addr): Do not reset the caller's DECL_INITIAL.
(get_emutls_init_templ_addr): Copy DECL_PRESERVE_P. Create the init template
as soon as we see a valid initializer. Mark the original var with error_mark_node so
that re-initializations will be diagnosed properly. Mark the original var as not to be output.
(emutls_common_1): Do not rely on DECL_COMMON as a decision on whether a constructor
is needed, it is also required for lcomm. Ensure that the var is laid out before the constructor
is built.
(emutls_finalize_control_var): Copy TREE_USED before finalization. Assert on
!DECL_THREAD_LOCAL_P, debug code to be removed.
(asm_output_bss): Do not emit TLS vars for emu tls targets (safety net, should not be
required, perhaps an assert would be better).
(asm_output_aligned_bss): Ditto.
(get_variable_section): Do not allow lcomm unless the target can register common.
(assemble_variable): Remove template init code.
Trap and ignore any TLS master vars (should not be needed maybe better to assert).
(do_assemble_alias): Ditto, remove TLS emulation var substitution.
(finish_aliases_1): Walk alias pairs redirecting aliases between the emulated vars, rather
than their masters.

* varpool.c (varpool_mark_needed_node): Do not handle TLS substitution here.
(decide_is_variable_needed): Or here.
(varpool_finalize_decl): Handle TLS substitution.
Remove early calls to varpool_assemble_pending_decls().
Check enqueuing of vars after all tests for need are complete.
(varpool_analyze_pending_decls): Do not record references if the initializer is error_mark.




Attachment: 160497-emutlsp-diff.txt
Description: Text document



	
	

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]