This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch, RQ Review] convert emulated TLS so that it works with LTO and WHOPR.
- From: IainS <developer at sandoe-acoustics dot co dot uk>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Jakub Jelinek <jakub at redhat dot com>, Jan Hubicka <hubicka at ucw dot cz>
- Date: Wed, 9 Jun 2010 21:09:03 +0100
- Subject: [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