1*e4b17023SJohn Marino /* Lower TLS operations to emulation functions.
2*e4b17023SJohn Marino Copyright (C) 2006, 2007, 2008, 2009, 2010
3*e4b17023SJohn Marino Free Software Foundation, Inc.
4*e4b17023SJohn Marino
5*e4b17023SJohn Marino This file is part of GCC.
6*e4b17023SJohn Marino
7*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it
8*e4b17023SJohn Marino under the terms of the GNU General Public License as published by the
9*e4b17023SJohn Marino Free Software Foundation; either version 3, or (at your option) any
10*e4b17023SJohn Marino later version.
11*e4b17023SJohn Marino
12*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT
13*e4b17023SJohn Marino ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15*e4b17023SJohn Marino for more details.
16*e4b17023SJohn Marino
17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
18*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
19*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
20*e4b17023SJohn Marino
21*e4b17023SJohn Marino #include "config.h"
22*e4b17023SJohn Marino #include "system.h"
23*e4b17023SJohn Marino #include "coretypes.h"
24*e4b17023SJohn Marino #include "tree.h"
25*e4b17023SJohn Marino #include "gimple.h"
26*e4b17023SJohn Marino #include "tree-pass.h"
27*e4b17023SJohn Marino #include "tree-flow.h"
28*e4b17023SJohn Marino #include "cgraph.h"
29*e4b17023SJohn Marino #include "langhooks.h"
30*e4b17023SJohn Marino #include "target.h"
31*e4b17023SJohn Marino #include "targhooks.h"
32*e4b17023SJohn Marino #include "tree-iterator.h"
33*e4b17023SJohn Marino
34*e4b17023SJohn Marino
35*e4b17023SJohn Marino /* Whenever a target does not support thread-local storage (TLS) natively,
36*e4b17023SJohn Marino we can emulate it with some run-time support in libgcc. This will in
37*e4b17023SJohn Marino turn rely on "keyed storage" a-la pthread_key_create; essentially all
38*e4b17023SJohn Marino thread libraries provide such functionality.
39*e4b17023SJohn Marino
40*e4b17023SJohn Marino In order to coordinate with the libgcc runtime, each TLS variable is
41*e4b17023SJohn Marino described by a "control variable". This control variable records the
42*e4b17023SJohn Marino required size, alignment, and initial value of the TLS variable for
43*e4b17023SJohn Marino instantiation at runtime. It also stores an integer token to be used
44*e4b17023SJohn Marino by the runtime to find the address of the variable within each thread.
45*e4b17023SJohn Marino
46*e4b17023SJohn Marino On the compiler side, this means that we need to replace all instances
47*e4b17023SJohn Marino of "tls_var" in the code with "*__emutls_get_addr(&control_var)". We
48*e4b17023SJohn Marino also need to eliminate "tls_var" from the symbol table and introduce
49*e4b17023SJohn Marino "control_var".
50*e4b17023SJohn Marino
51*e4b17023SJohn Marino We used to perform all of the transformations during conversion to rtl,
52*e4b17023SJohn Marino and the variable substitutions magically within assemble_variable.
53*e4b17023SJohn Marino However, this late fiddling of the symbol table conflicts with LTO and
54*e4b17023SJohn Marino whole-program compilation. Therefore we must now make all the changes
55*e4b17023SJohn Marino to the symbol table early in the GIMPLE optimization path, before we
56*e4b17023SJohn Marino write things out to LTO intermediate files. */
57*e4b17023SJohn Marino
58*e4b17023SJohn Marino /* These two vectors, once fully populated, are kept in lock-step so that
59*e4b17023SJohn Marino the index of a TLS variable equals the index of its control variable in
60*e4b17023SJohn Marino the other vector. */
61*e4b17023SJohn Marino static varpool_node_set tls_vars;
62*e4b17023SJohn Marino static VEC(varpool_node_ptr, heap) *control_vars;
63*e4b17023SJohn Marino
64*e4b17023SJohn Marino /* For the current basic block, an SSA_NAME that has computed the address
65*e4b17023SJohn Marino of the TLS variable at the corresponding index. */
66*e4b17023SJohn Marino static VEC(tree, heap) *access_vars;
67*e4b17023SJohn Marino
68*e4b17023SJohn Marino /* The type of the control structure, shared with the emutls.c runtime. */
69*e4b17023SJohn Marino static tree emutls_object_type;
70*e4b17023SJohn Marino
71*e4b17023SJohn Marino #if !defined (NO_DOT_IN_LABEL)
72*e4b17023SJohn Marino # define EMUTLS_SEPARATOR "."
73*e4b17023SJohn Marino #elif !defined (NO_DOLLAR_IN_LABEL)
74*e4b17023SJohn Marino # define EMUTLS_SEPARATOR "$"
75*e4b17023SJohn Marino #else
76*e4b17023SJohn Marino # define EMUTLS_SEPARATOR "_"
77*e4b17023SJohn Marino #endif
78*e4b17023SJohn Marino
79*e4b17023SJohn Marino /* Create an IDENTIFIER_NODE by prefixing PREFIX to the
80*e4b17023SJohn Marino IDENTIFIER_NODE NAME's name. */
81*e4b17023SJohn Marino
82*e4b17023SJohn Marino static tree
prefix_name(const char * prefix,tree name)83*e4b17023SJohn Marino prefix_name (const char *prefix, tree name)
84*e4b17023SJohn Marino {
85*e4b17023SJohn Marino unsigned plen = strlen (prefix);
86*e4b17023SJohn Marino unsigned nlen = strlen (IDENTIFIER_POINTER (name));
87*e4b17023SJohn Marino char *toname = (char *) alloca (plen + nlen + 1);
88*e4b17023SJohn Marino
89*e4b17023SJohn Marino memcpy (toname, prefix, plen);
90*e4b17023SJohn Marino memcpy (toname + plen, IDENTIFIER_POINTER (name), nlen + 1);
91*e4b17023SJohn Marino
92*e4b17023SJohn Marino return get_identifier (toname);
93*e4b17023SJohn Marino }
94*e4b17023SJohn Marino
95*e4b17023SJohn Marino /* Create an identifier for the struct __emutls_object, given an identifier
96*e4b17023SJohn Marino of the DECL_ASSEMBLY_NAME of the original object. */
97*e4b17023SJohn Marino
98*e4b17023SJohn Marino static tree
get_emutls_object_name(tree name)99*e4b17023SJohn Marino get_emutls_object_name (tree name)
100*e4b17023SJohn Marino {
101*e4b17023SJohn Marino const char *prefix = (targetm.emutls.var_prefix
102*e4b17023SJohn Marino ? targetm.emutls.var_prefix
103*e4b17023SJohn Marino : "__emutls_v" EMUTLS_SEPARATOR);
104*e4b17023SJohn Marino return prefix_name (prefix, name);
105*e4b17023SJohn Marino }
106*e4b17023SJohn Marino
107*e4b17023SJohn Marino /* Create the fields of the type for the control variables. Ordinarily
108*e4b17023SJohn Marino this must match struct __emutls_object defined in emutls.c. However
109*e4b17023SJohn Marino this is a target hook so that VxWorks can define its own layout. */
110*e4b17023SJohn Marino
111*e4b17023SJohn Marino tree
default_emutls_var_fields(tree type,tree * name ATTRIBUTE_UNUSED)112*e4b17023SJohn Marino default_emutls_var_fields (tree type, tree *name ATTRIBUTE_UNUSED)
113*e4b17023SJohn Marino {
114*e4b17023SJohn Marino tree word_type_node, field, next_field;
115*e4b17023SJohn Marino
116*e4b17023SJohn Marino field = build_decl (UNKNOWN_LOCATION,
117*e4b17023SJohn Marino FIELD_DECL, get_identifier ("__templ"), ptr_type_node);
118*e4b17023SJohn Marino DECL_CONTEXT (field) = type;
119*e4b17023SJohn Marino next_field = field;
120*e4b17023SJohn Marino
121*e4b17023SJohn Marino field = build_decl (UNKNOWN_LOCATION,
122*e4b17023SJohn Marino FIELD_DECL, get_identifier ("__offset"),
123*e4b17023SJohn Marino ptr_type_node);
124*e4b17023SJohn Marino DECL_CONTEXT (field) = type;
125*e4b17023SJohn Marino DECL_CHAIN (field) = next_field;
126*e4b17023SJohn Marino next_field = field;
127*e4b17023SJohn Marino
128*e4b17023SJohn Marino word_type_node = lang_hooks.types.type_for_mode (word_mode, 1);
129*e4b17023SJohn Marino field = build_decl (UNKNOWN_LOCATION,
130*e4b17023SJohn Marino FIELD_DECL, get_identifier ("__align"),
131*e4b17023SJohn Marino word_type_node);
132*e4b17023SJohn Marino DECL_CONTEXT (field) = type;
133*e4b17023SJohn Marino DECL_CHAIN (field) = next_field;
134*e4b17023SJohn Marino next_field = field;
135*e4b17023SJohn Marino
136*e4b17023SJohn Marino field = build_decl (UNKNOWN_LOCATION,
137*e4b17023SJohn Marino FIELD_DECL, get_identifier ("__size"), word_type_node);
138*e4b17023SJohn Marino DECL_CONTEXT (field) = type;
139*e4b17023SJohn Marino DECL_CHAIN (field) = next_field;
140*e4b17023SJohn Marino
141*e4b17023SJohn Marino return field;
142*e4b17023SJohn Marino }
143*e4b17023SJohn Marino
144*e4b17023SJohn Marino /* Initialize emulated tls object TO, which refers to TLS variable DECL and
145*e4b17023SJohn Marino is initialized by PROXY. As above, this is the default implementation of
146*e4b17023SJohn Marino a target hook overridden by VxWorks. */
147*e4b17023SJohn Marino
148*e4b17023SJohn Marino tree
default_emutls_var_init(tree to,tree decl,tree proxy)149*e4b17023SJohn Marino default_emutls_var_init (tree to, tree decl, tree proxy)
150*e4b17023SJohn Marino {
151*e4b17023SJohn Marino VEC(constructor_elt,gc) *v = VEC_alloc (constructor_elt, gc, 4);
152*e4b17023SJohn Marino constructor_elt *elt;
153*e4b17023SJohn Marino tree type = TREE_TYPE (to);
154*e4b17023SJohn Marino tree field = TYPE_FIELDS (type);
155*e4b17023SJohn Marino
156*e4b17023SJohn Marino elt = VEC_quick_push (constructor_elt, v, NULL);
157*e4b17023SJohn Marino elt->index = field;
158*e4b17023SJohn Marino elt->value = fold_convert (TREE_TYPE (field), DECL_SIZE_UNIT (decl));
159*e4b17023SJohn Marino
160*e4b17023SJohn Marino elt = VEC_quick_push (constructor_elt, v, NULL);
161*e4b17023SJohn Marino field = DECL_CHAIN (field);
162*e4b17023SJohn Marino elt->index = field;
163*e4b17023SJohn Marino elt->value = build_int_cst (TREE_TYPE (field),
164*e4b17023SJohn Marino DECL_ALIGN_UNIT (decl));
165*e4b17023SJohn Marino
166*e4b17023SJohn Marino elt = VEC_quick_push (constructor_elt, v, NULL);
167*e4b17023SJohn Marino field = DECL_CHAIN (field);
168*e4b17023SJohn Marino elt->index = field;
169*e4b17023SJohn Marino elt->value = null_pointer_node;
170*e4b17023SJohn Marino
171*e4b17023SJohn Marino elt = VEC_quick_push (constructor_elt, v, NULL);
172*e4b17023SJohn Marino field = DECL_CHAIN (field);
173*e4b17023SJohn Marino elt->index = field;
174*e4b17023SJohn Marino elt->value = proxy;
175*e4b17023SJohn Marino
176*e4b17023SJohn Marino return build_constructor (type, v);
177*e4b17023SJohn Marino }
178*e4b17023SJohn Marino
179*e4b17023SJohn Marino /* Create the structure for struct __emutls_object. This should match the
180*e4b17023SJohn Marino structure at the top of emutls.c, modulo the union there. */
181*e4b17023SJohn Marino
182*e4b17023SJohn Marino static tree
get_emutls_object_type(void)183*e4b17023SJohn Marino get_emutls_object_type (void)
184*e4b17023SJohn Marino {
185*e4b17023SJohn Marino tree type, type_name, field;
186*e4b17023SJohn Marino
187*e4b17023SJohn Marino type = emutls_object_type;
188*e4b17023SJohn Marino if (type)
189*e4b17023SJohn Marino return type;
190*e4b17023SJohn Marino
191*e4b17023SJohn Marino emutls_object_type = type = lang_hooks.types.make_type (RECORD_TYPE);
192*e4b17023SJohn Marino type_name = NULL;
193*e4b17023SJohn Marino field = targetm.emutls.var_fields (type, &type_name);
194*e4b17023SJohn Marino if (!type_name)
195*e4b17023SJohn Marino type_name = get_identifier ("__emutls_object");
196*e4b17023SJohn Marino type_name = build_decl (UNKNOWN_LOCATION,
197*e4b17023SJohn Marino TYPE_DECL, type_name, type);
198*e4b17023SJohn Marino TYPE_NAME (type) = type_name;
199*e4b17023SJohn Marino TYPE_FIELDS (type) = field;
200*e4b17023SJohn Marino layout_type (type);
201*e4b17023SJohn Marino
202*e4b17023SJohn Marino return type;
203*e4b17023SJohn Marino }
204*e4b17023SJohn Marino
205*e4b17023SJohn Marino /* Create a read-only variable like DECL, with the same DECL_INITIAL.
206*e4b17023SJohn Marino This will be used for initializing the emulated tls data area. */
207*e4b17023SJohn Marino
208*e4b17023SJohn Marino static tree
get_emutls_init_templ_addr(tree decl)209*e4b17023SJohn Marino get_emutls_init_templ_addr (tree decl)
210*e4b17023SJohn Marino {
211*e4b17023SJohn Marino tree name, to;
212*e4b17023SJohn Marino
213*e4b17023SJohn Marino if (targetm.emutls.register_common && !DECL_INITIAL (decl)
214*e4b17023SJohn Marino && !DECL_SECTION_NAME (decl))
215*e4b17023SJohn Marino return null_pointer_node;
216*e4b17023SJohn Marino
217*e4b17023SJohn Marino name = DECL_ASSEMBLER_NAME (decl);
218*e4b17023SJohn Marino if (!targetm.emutls.tmpl_prefix || targetm.emutls.tmpl_prefix[0])
219*e4b17023SJohn Marino {
220*e4b17023SJohn Marino const char *prefix = (targetm.emutls.tmpl_prefix
221*e4b17023SJohn Marino ? targetm.emutls.tmpl_prefix
222*e4b17023SJohn Marino : "__emutls_t" EMUTLS_SEPARATOR);
223*e4b17023SJohn Marino name = prefix_name (prefix, name);
224*e4b17023SJohn Marino }
225*e4b17023SJohn Marino
226*e4b17023SJohn Marino to = build_decl (DECL_SOURCE_LOCATION (decl),
227*e4b17023SJohn Marino VAR_DECL, name, TREE_TYPE (decl));
228*e4b17023SJohn Marino SET_DECL_ASSEMBLER_NAME (to, DECL_NAME (to));
229*e4b17023SJohn Marino
230*e4b17023SJohn Marino DECL_ARTIFICIAL (to) = 1;
231*e4b17023SJohn Marino TREE_USED (to) = TREE_USED (decl);
232*e4b17023SJohn Marino TREE_READONLY (to) = 1;
233*e4b17023SJohn Marino DECL_IGNORED_P (to) = 1;
234*e4b17023SJohn Marino DECL_CONTEXT (to) = DECL_CONTEXT (decl);
235*e4b17023SJohn Marino DECL_SECTION_NAME (to) = DECL_SECTION_NAME (decl);
236*e4b17023SJohn Marino DECL_PRESERVE_P (to) = DECL_PRESERVE_P (decl);
237*e4b17023SJohn Marino
238*e4b17023SJohn Marino DECL_WEAK (to) = DECL_WEAK (decl);
239*e4b17023SJohn Marino if (DECL_ONE_ONLY (decl))
240*e4b17023SJohn Marino {
241*e4b17023SJohn Marino make_decl_one_only (to, DECL_ASSEMBLER_NAME (to));
242*e4b17023SJohn Marino TREE_STATIC (to) = TREE_STATIC (decl);
243*e4b17023SJohn Marino TREE_PUBLIC (to) = TREE_PUBLIC (decl);
244*e4b17023SJohn Marino DECL_VISIBILITY (to) = DECL_VISIBILITY (decl);
245*e4b17023SJohn Marino }
246*e4b17023SJohn Marino else
247*e4b17023SJohn Marino TREE_STATIC (to) = 1;
248*e4b17023SJohn Marino
249*e4b17023SJohn Marino DECL_VISIBILITY_SPECIFIED (to) = DECL_VISIBILITY_SPECIFIED (decl);
250*e4b17023SJohn Marino DECL_INITIAL (to) = DECL_INITIAL (decl);
251*e4b17023SJohn Marino DECL_INITIAL (decl) = NULL;
252*e4b17023SJohn Marino
253*e4b17023SJohn Marino if (targetm.emutls.tmpl_section)
254*e4b17023SJohn Marino {
255*e4b17023SJohn Marino DECL_SECTION_NAME (to)
256*e4b17023SJohn Marino = build_string (strlen (targetm.emutls.tmpl_section),
257*e4b17023SJohn Marino targetm.emutls.tmpl_section);
258*e4b17023SJohn Marino }
259*e4b17023SJohn Marino
260*e4b17023SJohn Marino /* Create varpool node for the new variable and finalize it if it is
261*e4b17023SJohn Marino not external one. */
262*e4b17023SJohn Marino if (DECL_EXTERNAL (to))
263*e4b17023SJohn Marino varpool_node (to);
264*e4b17023SJohn Marino else
265*e4b17023SJohn Marino varpool_add_new_variable (to);
266*e4b17023SJohn Marino return build_fold_addr_expr (to);
267*e4b17023SJohn Marino }
268*e4b17023SJohn Marino
269*e4b17023SJohn Marino /* Create and return the control variable for the TLS variable DECL. */
270*e4b17023SJohn Marino
271*e4b17023SJohn Marino static tree
new_emutls_decl(tree decl,tree alias_of)272*e4b17023SJohn Marino new_emutls_decl (tree decl, tree alias_of)
273*e4b17023SJohn Marino {
274*e4b17023SJohn Marino tree name, to;
275*e4b17023SJohn Marino
276*e4b17023SJohn Marino name = DECL_ASSEMBLER_NAME (decl);
277*e4b17023SJohn Marino to = build_decl (DECL_SOURCE_LOCATION (decl), VAR_DECL,
278*e4b17023SJohn Marino get_emutls_object_name (name),
279*e4b17023SJohn Marino get_emutls_object_type ());
280*e4b17023SJohn Marino
281*e4b17023SJohn Marino SET_DECL_ASSEMBLER_NAME (to, DECL_NAME (to));
282*e4b17023SJohn Marino
283*e4b17023SJohn Marino DECL_TLS_MODEL (to) = TLS_MODEL_EMULATED;
284*e4b17023SJohn Marino DECL_ARTIFICIAL (to) = 1;
285*e4b17023SJohn Marino DECL_IGNORED_P (to) = 1;
286*e4b17023SJohn Marino TREE_READONLY (to) = 0;
287*e4b17023SJohn Marino TREE_STATIC (to) = 1;
288*e4b17023SJohn Marino
289*e4b17023SJohn Marino DECL_PRESERVE_P (to) = DECL_PRESERVE_P (decl);
290*e4b17023SJohn Marino DECL_CONTEXT (to) = DECL_CONTEXT (decl);
291*e4b17023SJohn Marino TREE_USED (to) = TREE_USED (decl);
292*e4b17023SJohn Marino TREE_PUBLIC (to) = TREE_PUBLIC (decl);
293*e4b17023SJohn Marino DECL_EXTERNAL (to) = DECL_EXTERNAL (decl);
294*e4b17023SJohn Marino DECL_COMMON (to) = DECL_COMMON (decl);
295*e4b17023SJohn Marino DECL_WEAK (to) = DECL_WEAK (decl);
296*e4b17023SJohn Marino DECL_VISIBILITY (to) = DECL_VISIBILITY (decl);
297*e4b17023SJohn Marino DECL_VISIBILITY_SPECIFIED (to) = DECL_VISIBILITY_SPECIFIED (decl);
298*e4b17023SJohn Marino DECL_RESTRICTED_P (to) = DECL_RESTRICTED_P (decl);
299*e4b17023SJohn Marino DECL_DLLIMPORT_P (to) = DECL_DLLIMPORT_P (decl);
300*e4b17023SJohn Marino
301*e4b17023SJohn Marino DECL_ATTRIBUTES (to) = targetm.merge_decl_attributes (decl, to);
302*e4b17023SJohn Marino
303*e4b17023SJohn Marino if (DECL_ONE_ONLY (decl))
304*e4b17023SJohn Marino make_decl_one_only (to, DECL_ASSEMBLER_NAME (to));
305*e4b17023SJohn Marino
306*e4b17023SJohn Marino /* If we're not allowed to change the proxy object's alignment,
307*e4b17023SJohn Marino pretend it has been set by the user. */
308*e4b17023SJohn Marino if (targetm.emutls.var_align_fixed)
309*e4b17023SJohn Marino DECL_USER_ALIGN (to) = 1;
310*e4b17023SJohn Marino
311*e4b17023SJohn Marino /* If the target wants the control variables grouped, do so. */
312*e4b17023SJohn Marino if (!DECL_COMMON (to) && targetm.emutls.var_section)
313*e4b17023SJohn Marino {
314*e4b17023SJohn Marino DECL_SECTION_NAME (to)
315*e4b17023SJohn Marino = build_string (strlen (targetm.emutls.tmpl_section),
316*e4b17023SJohn Marino targetm.emutls.tmpl_section);
317*e4b17023SJohn Marino }
318*e4b17023SJohn Marino
319*e4b17023SJohn Marino /* If this variable is defined locally, then we need to initialize the
320*e4b17023SJohn Marino control structure with size and alignment information. Initialization
321*e4b17023SJohn Marino of COMMON block variables happens elsewhere via a constructor. */
322*e4b17023SJohn Marino if (!DECL_EXTERNAL (to)
323*e4b17023SJohn Marino && (!DECL_COMMON (to)
324*e4b17023SJohn Marino || (DECL_INITIAL (decl)
325*e4b17023SJohn Marino && DECL_INITIAL (decl) != error_mark_node)))
326*e4b17023SJohn Marino {
327*e4b17023SJohn Marino tree tmpl = get_emutls_init_templ_addr (decl);
328*e4b17023SJohn Marino DECL_INITIAL (to) = targetm.emutls.var_init (to, decl, tmpl);
329*e4b17023SJohn Marino record_references_in_initializer (to, false);
330*e4b17023SJohn Marino }
331*e4b17023SJohn Marino
332*e4b17023SJohn Marino /* Create varpool node for the new variable and finalize it if it is
333*e4b17023SJohn Marino not external one. */
334*e4b17023SJohn Marino if (DECL_EXTERNAL (to))
335*e4b17023SJohn Marino varpool_node (to);
336*e4b17023SJohn Marino else if (!alias_of)
337*e4b17023SJohn Marino varpool_add_new_variable (to);
338*e4b17023SJohn Marino else
339*e4b17023SJohn Marino varpool_create_variable_alias (to,
340*e4b17023SJohn Marino varpool_node_for_asm
341*e4b17023SJohn Marino (DECL_ASSEMBLER_NAME (alias_of))->decl);
342*e4b17023SJohn Marino return to;
343*e4b17023SJohn Marino }
344*e4b17023SJohn Marino
345*e4b17023SJohn Marino /* Look up the index of the TLS variable DECL. This index can then be
346*e4b17023SJohn Marino used in both the control_vars and access_vars arrays. */
347*e4b17023SJohn Marino
348*e4b17023SJohn Marino static unsigned int
emutls_index(tree decl)349*e4b17023SJohn Marino emutls_index (tree decl)
350*e4b17023SJohn Marino {
351*e4b17023SJohn Marino varpool_node_set_iterator i;
352*e4b17023SJohn Marino
353*e4b17023SJohn Marino i = varpool_node_set_find (tls_vars, varpool_get_node (decl));
354*e4b17023SJohn Marino gcc_assert (i.index != ~0u);
355*e4b17023SJohn Marino
356*e4b17023SJohn Marino return i.index;
357*e4b17023SJohn Marino }
358*e4b17023SJohn Marino
359*e4b17023SJohn Marino /* Look up the control variable for the TLS variable DECL. */
360*e4b17023SJohn Marino
361*e4b17023SJohn Marino static tree
emutls_decl(tree decl)362*e4b17023SJohn Marino emutls_decl (tree decl)
363*e4b17023SJohn Marino {
364*e4b17023SJohn Marino struct varpool_node *var;
365*e4b17023SJohn Marino unsigned int i;
366*e4b17023SJohn Marino
367*e4b17023SJohn Marino i = emutls_index (decl);
368*e4b17023SJohn Marino var = VEC_index (varpool_node_ptr, control_vars, i);
369*e4b17023SJohn Marino return var->decl;
370*e4b17023SJohn Marino }
371*e4b17023SJohn Marino
372*e4b17023SJohn Marino /* Generate a call statement to initialize CONTROL_DECL for TLS_DECL.
373*e4b17023SJohn Marino This only needs to happen for TLS COMMON variables; non-COMMON
374*e4b17023SJohn Marino variables can be initialized statically. Insert the generated
375*e4b17023SJohn Marino call statement at the end of PSTMTS. */
376*e4b17023SJohn Marino
377*e4b17023SJohn Marino static void
emutls_common_1(tree tls_decl,tree control_decl,tree * pstmts)378*e4b17023SJohn Marino emutls_common_1 (tree tls_decl, tree control_decl, tree *pstmts)
379*e4b17023SJohn Marino {
380*e4b17023SJohn Marino tree x;
381*e4b17023SJohn Marino tree word_type_node;
382*e4b17023SJohn Marino
383*e4b17023SJohn Marino if (! DECL_COMMON (tls_decl)
384*e4b17023SJohn Marino || (DECL_INITIAL (tls_decl)
385*e4b17023SJohn Marino && DECL_INITIAL (tls_decl) != error_mark_node))
386*e4b17023SJohn Marino return;
387*e4b17023SJohn Marino
388*e4b17023SJohn Marino word_type_node = lang_hooks.types.type_for_mode (word_mode, 1);
389*e4b17023SJohn Marino
390*e4b17023SJohn Marino x = build_call_expr (builtin_decl_explicit (BUILT_IN_EMUTLS_REGISTER_COMMON),
391*e4b17023SJohn Marino 4, build_fold_addr_expr (control_decl),
392*e4b17023SJohn Marino fold_convert (word_type_node,
393*e4b17023SJohn Marino DECL_SIZE_UNIT (tls_decl)),
394*e4b17023SJohn Marino build_int_cst (word_type_node,
395*e4b17023SJohn Marino DECL_ALIGN_UNIT (tls_decl)),
396*e4b17023SJohn Marino get_emutls_init_templ_addr (tls_decl));
397*e4b17023SJohn Marino
398*e4b17023SJohn Marino append_to_statement_list (x, pstmts);
399*e4b17023SJohn Marino }
400*e4b17023SJohn Marino
401*e4b17023SJohn Marino struct lower_emutls_data
402*e4b17023SJohn Marino {
403*e4b17023SJohn Marino struct cgraph_node *cfun_node;
404*e4b17023SJohn Marino struct cgraph_node *builtin_node;
405*e4b17023SJohn Marino tree builtin_decl;
406*e4b17023SJohn Marino basic_block bb;
407*e4b17023SJohn Marino int bb_freq;
408*e4b17023SJohn Marino location_t loc;
409*e4b17023SJohn Marino gimple_seq seq;
410*e4b17023SJohn Marino };
411*e4b17023SJohn Marino
412*e4b17023SJohn Marino /* Given a TLS variable DECL, return an SSA_NAME holding its address.
413*e4b17023SJohn Marino Append any new computation statements required to D->SEQ. */
414*e4b17023SJohn Marino
415*e4b17023SJohn Marino static tree
gen_emutls_addr(tree decl,struct lower_emutls_data * d)416*e4b17023SJohn Marino gen_emutls_addr (tree decl, struct lower_emutls_data *d)
417*e4b17023SJohn Marino {
418*e4b17023SJohn Marino unsigned int index;
419*e4b17023SJohn Marino tree addr;
420*e4b17023SJohn Marino
421*e4b17023SJohn Marino /* Compute the address of the TLS variable with help from runtime. */
422*e4b17023SJohn Marino index = emutls_index (decl);
423*e4b17023SJohn Marino addr = VEC_index (tree, access_vars, index);
424*e4b17023SJohn Marino if (addr == NULL)
425*e4b17023SJohn Marino {
426*e4b17023SJohn Marino struct varpool_node *cvar;
427*e4b17023SJohn Marino tree cdecl;
428*e4b17023SJohn Marino gimple x;
429*e4b17023SJohn Marino
430*e4b17023SJohn Marino cvar = VEC_index (varpool_node_ptr, control_vars, index);
431*e4b17023SJohn Marino cdecl = cvar->decl;
432*e4b17023SJohn Marino TREE_ADDRESSABLE (cdecl) = 1;
433*e4b17023SJohn Marino
434*e4b17023SJohn Marino addr = create_tmp_var (build_pointer_type (TREE_TYPE (decl)), NULL);
435*e4b17023SJohn Marino x = gimple_build_call (d->builtin_decl, 1, build_fold_addr_expr (cdecl));
436*e4b17023SJohn Marino gimple_set_location (x, d->loc);
437*e4b17023SJohn Marino add_referenced_var (cdecl);
438*e4b17023SJohn Marino
439*e4b17023SJohn Marino addr = make_ssa_name (addr, x);
440*e4b17023SJohn Marino gimple_call_set_lhs (x, addr);
441*e4b17023SJohn Marino
442*e4b17023SJohn Marino gimple_seq_add_stmt (&d->seq, x);
443*e4b17023SJohn Marino
444*e4b17023SJohn Marino cgraph_create_edge (d->cfun_node, d->builtin_node, x,
445*e4b17023SJohn Marino d->bb->count, d->bb_freq);
446*e4b17023SJohn Marino
447*e4b17023SJohn Marino /* We may be adding a new reference to a new variable to the function.
448*e4b17023SJohn Marino This means we have to play with the ipa-reference web. */
449*e4b17023SJohn Marino ipa_record_reference (d->cfun_node, NULL, NULL, cvar, IPA_REF_ADDR, x);
450*e4b17023SJohn Marino
451*e4b17023SJohn Marino /* Record this ssa_name for possible use later in the basic block. */
452*e4b17023SJohn Marino VEC_replace (tree, access_vars, index, addr);
453*e4b17023SJohn Marino }
454*e4b17023SJohn Marino
455*e4b17023SJohn Marino return addr;
456*e4b17023SJohn Marino }
457*e4b17023SJohn Marino
458*e4b17023SJohn Marino /* Callback for walk_gimple_op. D = WI->INFO is a struct lower_emutls_data.
459*e4b17023SJohn Marino Given an operand *PTR within D->STMT, if the operand references a TLS
460*e4b17023SJohn Marino variable, then lower the reference to a call to the runtime. Insert
461*e4b17023SJohn Marino any new statements required into D->SEQ; the caller is responsible for
462*e4b17023SJohn Marino placing those appropriately. */
463*e4b17023SJohn Marino
464*e4b17023SJohn Marino static tree
lower_emutls_1(tree * ptr,int * walk_subtrees,void * cb_data)465*e4b17023SJohn Marino lower_emutls_1 (tree *ptr, int *walk_subtrees, void *cb_data)
466*e4b17023SJohn Marino {
467*e4b17023SJohn Marino struct walk_stmt_info *wi = (struct walk_stmt_info *) cb_data;
468*e4b17023SJohn Marino struct lower_emutls_data *d = (struct lower_emutls_data *) wi->info;
469*e4b17023SJohn Marino tree t = *ptr;
470*e4b17023SJohn Marino bool is_addr = false;
471*e4b17023SJohn Marino tree addr;
472*e4b17023SJohn Marino
473*e4b17023SJohn Marino *walk_subtrees = 0;
474*e4b17023SJohn Marino
475*e4b17023SJohn Marino switch (TREE_CODE (t))
476*e4b17023SJohn Marino {
477*e4b17023SJohn Marino case ADDR_EXPR:
478*e4b17023SJohn Marino /* If this is not a straight-forward "&var", but rather something
479*e4b17023SJohn Marino like "&var.a", then we may need special handling. */
480*e4b17023SJohn Marino if (TREE_CODE (TREE_OPERAND (t, 0)) != VAR_DECL)
481*e4b17023SJohn Marino {
482*e4b17023SJohn Marino bool save_changed;
483*e4b17023SJohn Marino
484*e4b17023SJohn Marino /* If we're allowed more than just is_gimple_val, continue. */
485*e4b17023SJohn Marino if (!wi->val_only)
486*e4b17023SJohn Marino {
487*e4b17023SJohn Marino *walk_subtrees = 1;
488*e4b17023SJohn Marino return NULL_TREE;
489*e4b17023SJohn Marino }
490*e4b17023SJohn Marino
491*e4b17023SJohn Marino /* See if any substitution would be made. */
492*e4b17023SJohn Marino save_changed = wi->changed;
493*e4b17023SJohn Marino wi->changed = false;
494*e4b17023SJohn Marino wi->val_only = false;
495*e4b17023SJohn Marino walk_tree (&TREE_OPERAND (t, 0), lower_emutls_1, wi, NULL);
496*e4b17023SJohn Marino wi->val_only = true;
497*e4b17023SJohn Marino
498*e4b17023SJohn Marino /* If so, then extract this entire sub-expression "&p->a" into a
499*e4b17023SJohn Marino new assignment statement, and substitute yet another SSA_NAME. */
500*e4b17023SJohn Marino if (wi->changed)
501*e4b17023SJohn Marino {
502*e4b17023SJohn Marino gimple x;
503*e4b17023SJohn Marino
504*e4b17023SJohn Marino addr = create_tmp_var (TREE_TYPE (t), NULL);
505*e4b17023SJohn Marino x = gimple_build_assign (addr, t);
506*e4b17023SJohn Marino gimple_set_location (x, d->loc);
507*e4b17023SJohn Marino
508*e4b17023SJohn Marino addr = make_ssa_name (addr, x);
509*e4b17023SJohn Marino gimple_assign_set_lhs (x, addr);
510*e4b17023SJohn Marino
511*e4b17023SJohn Marino gimple_seq_add_stmt (&d->seq, x);
512*e4b17023SJohn Marino
513*e4b17023SJohn Marino *ptr = addr;
514*e4b17023SJohn Marino }
515*e4b17023SJohn Marino else
516*e4b17023SJohn Marino wi->changed = save_changed;
517*e4b17023SJohn Marino
518*e4b17023SJohn Marino return NULL_TREE;
519*e4b17023SJohn Marino }
520*e4b17023SJohn Marino
521*e4b17023SJohn Marino t = TREE_OPERAND (t, 0);
522*e4b17023SJohn Marino is_addr = true;
523*e4b17023SJohn Marino /* FALLTHRU */
524*e4b17023SJohn Marino
525*e4b17023SJohn Marino case VAR_DECL:
526*e4b17023SJohn Marino if (!DECL_THREAD_LOCAL_P (t))
527*e4b17023SJohn Marino return NULL_TREE;
528*e4b17023SJohn Marino break;
529*e4b17023SJohn Marino
530*e4b17023SJohn Marino default:
531*e4b17023SJohn Marino /* We're not interested in other decls or types, only subexpressions. */
532*e4b17023SJohn Marino if (EXPR_P (t))
533*e4b17023SJohn Marino *walk_subtrees = 1;
534*e4b17023SJohn Marino /* FALLTHRU */
535*e4b17023SJohn Marino
536*e4b17023SJohn Marino case SSA_NAME:
537*e4b17023SJohn Marino /* Special-case the return of SSA_NAME, since it's so common. */
538*e4b17023SJohn Marino return NULL_TREE;
539*e4b17023SJohn Marino }
540*e4b17023SJohn Marino
541*e4b17023SJohn Marino addr = gen_emutls_addr (t, d);
542*e4b17023SJohn Marino if (is_addr)
543*e4b17023SJohn Marino {
544*e4b17023SJohn Marino /* Replace "&var" with "addr" in the statement. */
545*e4b17023SJohn Marino *ptr = addr;
546*e4b17023SJohn Marino }
547*e4b17023SJohn Marino else
548*e4b17023SJohn Marino {
549*e4b17023SJohn Marino /* Replace "var" with "*addr" in the statement. */
550*e4b17023SJohn Marino t = build2 (MEM_REF, TREE_TYPE (t), addr,
551*e4b17023SJohn Marino build_int_cst (TREE_TYPE (addr), 0));
552*e4b17023SJohn Marino *ptr = t;
553*e4b17023SJohn Marino }
554*e4b17023SJohn Marino
555*e4b17023SJohn Marino wi->changed = true;
556*e4b17023SJohn Marino return NULL_TREE;
557*e4b17023SJohn Marino }
558*e4b17023SJohn Marino
559*e4b17023SJohn Marino /* Lower all of the operands of STMT. */
560*e4b17023SJohn Marino
561*e4b17023SJohn Marino static void
lower_emutls_stmt(gimple stmt,struct lower_emutls_data * d)562*e4b17023SJohn Marino lower_emutls_stmt (gimple stmt, struct lower_emutls_data *d)
563*e4b17023SJohn Marino {
564*e4b17023SJohn Marino struct walk_stmt_info wi;
565*e4b17023SJohn Marino
566*e4b17023SJohn Marino d->loc = gimple_location (stmt);
567*e4b17023SJohn Marino
568*e4b17023SJohn Marino memset (&wi, 0, sizeof (wi));
569*e4b17023SJohn Marino wi.info = d;
570*e4b17023SJohn Marino wi.val_only = true;
571*e4b17023SJohn Marino walk_gimple_op (stmt, lower_emutls_1, &wi);
572*e4b17023SJohn Marino
573*e4b17023SJohn Marino if (wi.changed)
574*e4b17023SJohn Marino update_stmt (stmt);
575*e4b17023SJohn Marino }
576*e4b17023SJohn Marino
577*e4b17023SJohn Marino /* Lower the I'th operand of PHI. */
578*e4b17023SJohn Marino
579*e4b17023SJohn Marino static void
lower_emutls_phi_arg(gimple phi,unsigned int i,struct lower_emutls_data * d)580*e4b17023SJohn Marino lower_emutls_phi_arg (gimple phi, unsigned int i, struct lower_emutls_data *d)
581*e4b17023SJohn Marino {
582*e4b17023SJohn Marino struct walk_stmt_info wi;
583*e4b17023SJohn Marino struct phi_arg_d *pd = gimple_phi_arg (phi, i);
584*e4b17023SJohn Marino
585*e4b17023SJohn Marino /* Early out for a very common case we don't care about. */
586*e4b17023SJohn Marino if (TREE_CODE (pd->def) == SSA_NAME)
587*e4b17023SJohn Marino return;
588*e4b17023SJohn Marino
589*e4b17023SJohn Marino d->loc = pd->locus;
590*e4b17023SJohn Marino
591*e4b17023SJohn Marino memset (&wi, 0, sizeof (wi));
592*e4b17023SJohn Marino wi.info = d;
593*e4b17023SJohn Marino wi.val_only = true;
594*e4b17023SJohn Marino walk_tree (&pd->def, lower_emutls_1, &wi, NULL);
595*e4b17023SJohn Marino
596*e4b17023SJohn Marino /* For normal statements, we let update_stmt do its job. But for phi
597*e4b17023SJohn Marino nodes, we have to manipulate the immediate use list by hand. */
598*e4b17023SJohn Marino if (wi.changed)
599*e4b17023SJohn Marino {
600*e4b17023SJohn Marino gcc_assert (TREE_CODE (pd->def) == SSA_NAME);
601*e4b17023SJohn Marino link_imm_use_stmt (&pd->imm_use, pd->def, phi);
602*e4b17023SJohn Marino }
603*e4b17023SJohn Marino }
604*e4b17023SJohn Marino
605*e4b17023SJohn Marino /* Clear the ACCESS_VARS array, in order to begin a new block. */
606*e4b17023SJohn Marino
607*e4b17023SJohn Marino static inline void
clear_access_vars(void)608*e4b17023SJohn Marino clear_access_vars (void)
609*e4b17023SJohn Marino {
610*e4b17023SJohn Marino memset (VEC_address (tree, access_vars), 0,
611*e4b17023SJohn Marino VEC_length (tree, access_vars) * sizeof(tree));
612*e4b17023SJohn Marino }
613*e4b17023SJohn Marino
614*e4b17023SJohn Marino /* Lower the entire function NODE. */
615*e4b17023SJohn Marino
616*e4b17023SJohn Marino static void
lower_emutls_function_body(struct cgraph_node * node)617*e4b17023SJohn Marino lower_emutls_function_body (struct cgraph_node *node)
618*e4b17023SJohn Marino {
619*e4b17023SJohn Marino struct lower_emutls_data d;
620*e4b17023SJohn Marino bool any_edge_inserts = false;
621*e4b17023SJohn Marino
622*e4b17023SJohn Marino current_function_decl = node->decl;
623*e4b17023SJohn Marino push_cfun (DECL_STRUCT_FUNCTION (node->decl));
624*e4b17023SJohn Marino
625*e4b17023SJohn Marino d.cfun_node = node;
626*e4b17023SJohn Marino d.builtin_decl = builtin_decl_explicit (BUILT_IN_EMUTLS_GET_ADDRESS);
627*e4b17023SJohn Marino /* This is where we introduce the declaration to the IL and so we have to
628*e4b17023SJohn Marino create a node for it. */
629*e4b17023SJohn Marino d.builtin_node = cgraph_get_create_node (d.builtin_decl);
630*e4b17023SJohn Marino
631*e4b17023SJohn Marino FOR_EACH_BB (d.bb)
632*e4b17023SJohn Marino {
633*e4b17023SJohn Marino gimple_stmt_iterator gsi;
634*e4b17023SJohn Marino unsigned int i, nedge;
635*e4b17023SJohn Marino
636*e4b17023SJohn Marino /* Lower each of the PHI nodes of the block, as we may have
637*e4b17023SJohn Marino propagated &tlsvar into a PHI argument. These loops are
638*e4b17023SJohn Marino arranged so that we process each edge at once, and each
639*e4b17023SJohn Marino PHI argument for that edge. */
640*e4b17023SJohn Marino if (!gimple_seq_empty_p (phi_nodes (d.bb)))
641*e4b17023SJohn Marino {
642*e4b17023SJohn Marino /* The calls will be inserted on the edges, and the frequencies
643*e4b17023SJohn Marino will be computed during the commit process. */
644*e4b17023SJohn Marino d.bb_freq = 0;
645*e4b17023SJohn Marino
646*e4b17023SJohn Marino nedge = EDGE_COUNT (d.bb->preds);
647*e4b17023SJohn Marino for (i = 0; i < nedge; ++i)
648*e4b17023SJohn Marino {
649*e4b17023SJohn Marino edge e = EDGE_PRED (d.bb, i);
650*e4b17023SJohn Marino
651*e4b17023SJohn Marino /* We can re-use any SSA_NAME created on this edge. */
652*e4b17023SJohn Marino clear_access_vars ();
653*e4b17023SJohn Marino d.seq = NULL;
654*e4b17023SJohn Marino
655*e4b17023SJohn Marino for (gsi = gsi_start_phis (d.bb);
656*e4b17023SJohn Marino !gsi_end_p (gsi);
657*e4b17023SJohn Marino gsi_next (&gsi))
658*e4b17023SJohn Marino lower_emutls_phi_arg (gsi_stmt (gsi), i, &d);
659*e4b17023SJohn Marino
660*e4b17023SJohn Marino /* Insert all statements generated by all phi nodes for this
661*e4b17023SJohn Marino particular edge all at once. */
662*e4b17023SJohn Marino if (d.seq)
663*e4b17023SJohn Marino {
664*e4b17023SJohn Marino gsi_insert_seq_on_edge (e, d.seq);
665*e4b17023SJohn Marino any_edge_inserts = true;
666*e4b17023SJohn Marino }
667*e4b17023SJohn Marino }
668*e4b17023SJohn Marino }
669*e4b17023SJohn Marino
670*e4b17023SJohn Marino d.bb_freq = compute_call_stmt_bb_frequency (current_function_decl, d.bb);
671*e4b17023SJohn Marino
672*e4b17023SJohn Marino /* We can re-use any SSA_NAME created during this basic block. */
673*e4b17023SJohn Marino clear_access_vars ();
674*e4b17023SJohn Marino
675*e4b17023SJohn Marino /* Lower each of the statements of the block. */
676*e4b17023SJohn Marino for (gsi = gsi_start_bb (d.bb); !gsi_end_p (gsi); gsi_next (&gsi))
677*e4b17023SJohn Marino {
678*e4b17023SJohn Marino d.seq = NULL;
679*e4b17023SJohn Marino lower_emutls_stmt (gsi_stmt (gsi), &d);
680*e4b17023SJohn Marino
681*e4b17023SJohn Marino /* If any new statements were created, insert them immediately
682*e4b17023SJohn Marino before the first use. This prevents variable lifetimes from
683*e4b17023SJohn Marino becoming unnecessarily long. */
684*e4b17023SJohn Marino if (d.seq)
685*e4b17023SJohn Marino gsi_insert_seq_before (&gsi, d.seq, GSI_SAME_STMT);
686*e4b17023SJohn Marino }
687*e4b17023SJohn Marino }
688*e4b17023SJohn Marino
689*e4b17023SJohn Marino if (any_edge_inserts)
690*e4b17023SJohn Marino gsi_commit_edge_inserts ();
691*e4b17023SJohn Marino
692*e4b17023SJohn Marino pop_cfun ();
693*e4b17023SJohn Marino current_function_decl = NULL;
694*e4b17023SJohn Marino }
695*e4b17023SJohn Marino
696*e4b17023SJohn Marino /* Create emutls variable for VAR, DATA is pointer to static
697*e4b17023SJohn Marino ctor body we can add constructors to.
698*e4b17023SJohn Marino Callback for varpool_for_variable_and_aliases. */
699*e4b17023SJohn Marino
700*e4b17023SJohn Marino static bool
create_emultls_var(struct varpool_node * var,void * data)701*e4b17023SJohn Marino create_emultls_var (struct varpool_node *var, void *data)
702*e4b17023SJohn Marino {
703*e4b17023SJohn Marino tree cdecl;
704*e4b17023SJohn Marino struct varpool_node *cvar;
705*e4b17023SJohn Marino
706*e4b17023SJohn Marino cdecl = new_emutls_decl (var->decl, var->alias_of);
707*e4b17023SJohn Marino
708*e4b17023SJohn Marino cvar = varpool_get_node (cdecl);
709*e4b17023SJohn Marino VEC_quick_push (varpool_node_ptr, control_vars, cvar);
710*e4b17023SJohn Marino
711*e4b17023SJohn Marino if (!var->alias)
712*e4b17023SJohn Marino {
713*e4b17023SJohn Marino /* Make sure the COMMON block control variable gets initialized.
714*e4b17023SJohn Marino Note that there's no point in doing this for aliases; we only
715*e4b17023SJohn Marino need to do this once for the main variable. */
716*e4b17023SJohn Marino emutls_common_1 (var->decl, cdecl, (tree *)data);
717*e4b17023SJohn Marino }
718*e4b17023SJohn Marino if (var->alias && !var->alias_of)
719*e4b17023SJohn Marino cvar->alias = true;
720*e4b17023SJohn Marino
721*e4b17023SJohn Marino /* Indicate that the value of the TLS variable may be found elsewhere,
722*e4b17023SJohn Marino preventing the variable from re-appearing in the GIMPLE. We cheat
723*e4b17023SJohn Marino and use the control variable here (rather than a full call_expr),
724*e4b17023SJohn Marino which is special-cased inside the DWARF2 output routines. */
725*e4b17023SJohn Marino SET_DECL_VALUE_EXPR (var->decl, cdecl);
726*e4b17023SJohn Marino DECL_HAS_VALUE_EXPR_P (var->decl) = 1;
727*e4b17023SJohn Marino return false;
728*e4b17023SJohn Marino }
729*e4b17023SJohn Marino
730*e4b17023SJohn Marino /* Main entry point to the tls lowering pass. */
731*e4b17023SJohn Marino
732*e4b17023SJohn Marino static unsigned int
ipa_lower_emutls(void)733*e4b17023SJohn Marino ipa_lower_emutls (void)
734*e4b17023SJohn Marino {
735*e4b17023SJohn Marino struct varpool_node *var;
736*e4b17023SJohn Marino struct cgraph_node *func;
737*e4b17023SJohn Marino bool any_aliases = false;
738*e4b17023SJohn Marino tree ctor_body = NULL;
739*e4b17023SJohn Marino unsigned int i, n_tls;
740*e4b17023SJohn Marino
741*e4b17023SJohn Marino tls_vars = varpool_node_set_new ();
742*e4b17023SJohn Marino
743*e4b17023SJohn Marino /* Examine all global variables for TLS variables. */
744*e4b17023SJohn Marino for (var = varpool_nodes; var ; var = var->next)
745*e4b17023SJohn Marino if (DECL_THREAD_LOCAL_P (var->decl))
746*e4b17023SJohn Marino {
747*e4b17023SJohn Marino gcc_checking_assert (TREE_STATIC (var->decl)
748*e4b17023SJohn Marino || DECL_EXTERNAL (var->decl));
749*e4b17023SJohn Marino varpool_node_set_add (tls_vars, var);
750*e4b17023SJohn Marino if (var->alias && var->analyzed)
751*e4b17023SJohn Marino varpool_node_set_add (tls_vars, varpool_variable_node (var, NULL));
752*e4b17023SJohn Marino }
753*e4b17023SJohn Marino
754*e4b17023SJohn Marino /* If we found no TLS variables, then there is no further work to do. */
755*e4b17023SJohn Marino if (tls_vars->nodes == NULL)
756*e4b17023SJohn Marino {
757*e4b17023SJohn Marino tls_vars = NULL;
758*e4b17023SJohn Marino if (dump_file)
759*e4b17023SJohn Marino fprintf (dump_file, "No TLS variables found.\n");
760*e4b17023SJohn Marino return 0;
761*e4b17023SJohn Marino }
762*e4b17023SJohn Marino
763*e4b17023SJohn Marino /* Allocate the on-the-side arrays that share indicies with the TLS vars. */
764*e4b17023SJohn Marino n_tls = VEC_length (varpool_node_ptr, tls_vars->nodes);
765*e4b17023SJohn Marino control_vars = VEC_alloc (varpool_node_ptr, heap, n_tls);
766*e4b17023SJohn Marino access_vars = VEC_alloc (tree, heap, n_tls);
767*e4b17023SJohn Marino VEC_safe_grow (tree, heap, access_vars, n_tls);
768*e4b17023SJohn Marino
769*e4b17023SJohn Marino /* Create the control variables for each TLS variable. */
770*e4b17023SJohn Marino FOR_EACH_VEC_ELT (varpool_node_ptr, tls_vars->nodes, i, var)
771*e4b17023SJohn Marino {
772*e4b17023SJohn Marino var = VEC_index (varpool_node_ptr, tls_vars->nodes, i);
773*e4b17023SJohn Marino
774*e4b17023SJohn Marino if (var->alias && !var->alias_of)
775*e4b17023SJohn Marino any_aliases = true;
776*e4b17023SJohn Marino else if (!var->alias)
777*e4b17023SJohn Marino varpool_for_node_and_aliases (var, create_emultls_var, &ctor_body, true);
778*e4b17023SJohn Marino }
779*e4b17023SJohn Marino
780*e4b17023SJohn Marino /* If there were any aliases, then frob the alias_pairs vector. */
781*e4b17023SJohn Marino if (any_aliases)
782*e4b17023SJohn Marino {
783*e4b17023SJohn Marino alias_pair *p;
784*e4b17023SJohn Marino FOR_EACH_VEC_ELT (alias_pair, alias_pairs, i, p)
785*e4b17023SJohn Marino if (DECL_THREAD_LOCAL_P (p->decl))
786*e4b17023SJohn Marino {
787*e4b17023SJohn Marino p->decl = emutls_decl (p->decl);
788*e4b17023SJohn Marino p->target = get_emutls_object_name (p->target);
789*e4b17023SJohn Marino }
790*e4b17023SJohn Marino }
791*e4b17023SJohn Marino
792*e4b17023SJohn Marino /* Adjust all uses of TLS variables within the function bodies. */
793*e4b17023SJohn Marino for (func = cgraph_nodes; func; func = func->next)
794*e4b17023SJohn Marino if (func->reachable && func->lowered)
795*e4b17023SJohn Marino lower_emutls_function_body (func);
796*e4b17023SJohn Marino
797*e4b17023SJohn Marino /* Generate the constructor for any COMMON control variables created. */
798*e4b17023SJohn Marino if (ctor_body)
799*e4b17023SJohn Marino cgraph_build_static_cdtor ('I', ctor_body, DEFAULT_INIT_PRIORITY);
800*e4b17023SJohn Marino
801*e4b17023SJohn Marino VEC_free (varpool_node_ptr, heap, control_vars);
802*e4b17023SJohn Marino VEC_free (tree, heap, access_vars);
803*e4b17023SJohn Marino free_varpool_node_set (tls_vars);
804*e4b17023SJohn Marino
805*e4b17023SJohn Marino return TODO_ggc_collect | TODO_verify_all;
806*e4b17023SJohn Marino }
807*e4b17023SJohn Marino
808*e4b17023SJohn Marino /* If the target supports TLS natively, we need do nothing here. */
809*e4b17023SJohn Marino
810*e4b17023SJohn Marino static bool
gate_emutls(void)811*e4b17023SJohn Marino gate_emutls (void)
812*e4b17023SJohn Marino {
813*e4b17023SJohn Marino return !targetm.have_tls;
814*e4b17023SJohn Marino }
815*e4b17023SJohn Marino
816*e4b17023SJohn Marino struct simple_ipa_opt_pass pass_ipa_lower_emutls =
817*e4b17023SJohn Marino {
818*e4b17023SJohn Marino {
819*e4b17023SJohn Marino SIMPLE_IPA_PASS,
820*e4b17023SJohn Marino "emutls", /* name */
821*e4b17023SJohn Marino gate_emutls, /* gate */
822*e4b17023SJohn Marino ipa_lower_emutls, /* execute */
823*e4b17023SJohn Marino NULL, /* sub */
824*e4b17023SJohn Marino NULL, /* next */
825*e4b17023SJohn Marino 0, /* static_pass_number */
826*e4b17023SJohn Marino TV_IPA_OPT, /* tv_id */
827*e4b17023SJohn Marino PROP_cfg | PROP_ssa, /* properties_required */
828*e4b17023SJohn Marino 0, /* properties_provided */
829*e4b17023SJohn Marino 0, /* properties_destroyed */
830*e4b17023SJohn Marino 0, /* todo_flags_start */
831*e4b17023SJohn Marino 0, /* todo_flags_finish */
832*e4b17023SJohn Marino }
833*e4b17023SJohn Marino };
834