xref: /dragonfly/contrib/gcc-4.7/gcc/tree-emutls.c (revision e4b17023)
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