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