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