Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-emutls.c @ 68:561a7518be6b
update gcc-4.6
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 21 Aug 2011 07:07:55 +0900 |
parents | |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
67:f6334be47118 | 68:561a7518be6b |
---|---|
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); | |
152 constructor_elt *elt; | |
153 tree type = TREE_TYPE (to); | |
154 tree field = TYPE_FIELDS (type); | |
155 | |
156 elt = VEC_quick_push (constructor_elt, v, NULL); | |
157 elt->index = field; | |
158 elt->value = fold_convert (TREE_TYPE (field), DECL_SIZE_UNIT (decl)); | |
159 | |
160 elt = VEC_quick_push (constructor_elt, v, NULL); | |
161 field = DECL_CHAIN (field); | |
162 elt->index = field; | |
163 elt->value = build_int_cst (TREE_TYPE (field), | |
164 DECL_ALIGN_UNIT (decl)); | |
165 | |
166 elt = VEC_quick_push (constructor_elt, v, NULL); | |
167 field = DECL_CHAIN (field); | |
168 elt->index = field; | |
169 elt->value = null_pointer_node; | |
170 | |
171 elt = VEC_quick_push (constructor_elt, v, NULL); | |
172 field = DECL_CHAIN (field); | |
173 elt->index = field; | |
174 elt->value = proxy; | |
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 | |
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 | |
265 varpool_finalize_decl (to); | |
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 | |
272 new_emutls_decl (tree decl) | |
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) | |
315 = build_string (strlen (targetm.emutls.tmpl_section), | |
316 targetm.emutls.tmpl_section); | |
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 | |
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); | |
336 else | |
337 varpool_finalize_decl (to); | |
338 return to; | |
339 } | |
340 | |
341 /* Look up the index of the TLS variable DECL. This index can then be | |
342 used in both the control_vars and access_vars arrays. */ | |
343 | |
344 static unsigned int | |
345 emutls_index (tree decl) | |
346 { | |
347 varpool_node_set_iterator i; | |
348 | |
349 i = varpool_node_set_find (tls_vars, varpool_get_node (decl)); | |
350 gcc_assert (i.index != ~0u); | |
351 | |
352 return i.index; | |
353 } | |
354 | |
355 /* Look up the control variable for the TLS variable DECL. */ | |
356 | |
357 static tree | |
358 emutls_decl (tree decl) | |
359 { | |
360 struct varpool_node *var; | |
361 unsigned int i; | |
362 | |
363 i = emutls_index (decl); | |
364 var = VEC_index (varpool_node_ptr, control_vars, i); | |
365 return var->decl; | |
366 } | |
367 | |
368 /* Generate a call statement to initialize CONTROL_DECL for TLS_DECL. | |
369 This only needs to happen for TLS COMMON variables; non-COMMON | |
370 variables can be initialized statically. Insert the generated | |
371 call statement at the end of PSTMTS. */ | |
372 | |
373 static void | |
374 emutls_common_1 (tree tls_decl, tree control_decl, tree *pstmts) | |
375 { | |
376 tree x; | |
377 tree word_type_node; | |
378 | |
379 if (! DECL_COMMON (tls_decl) | |
380 || (DECL_INITIAL (tls_decl) | |
381 && DECL_INITIAL (tls_decl) != error_mark_node)) | |
382 return; | |
383 | |
384 word_type_node = lang_hooks.types.type_for_mode (word_mode, 1); | |
385 | |
386 x = build_call_expr (built_in_decls[BUILT_IN_EMUTLS_REGISTER_COMMON], 4, | |
387 build_fold_addr_expr (control_decl), | |
388 fold_convert (word_type_node, | |
389 DECL_SIZE_UNIT (tls_decl)), | |
390 build_int_cst (word_type_node, | |
391 DECL_ALIGN_UNIT (tls_decl)), | |
392 get_emutls_init_templ_addr (tls_decl)); | |
393 | |
394 append_to_statement_list (x, pstmts); | |
395 } | |
396 | |
397 struct lower_emutls_data | |
398 { | |
399 struct cgraph_node *cfun_node; | |
400 struct cgraph_node *builtin_node; | |
401 tree builtin_decl; | |
402 basic_block bb; | |
403 int bb_freq; | |
404 location_t loc; | |
405 gimple_seq seq; | |
406 }; | |
407 | |
408 /* Given a TLS variable DECL, return an SSA_NAME holding its address. | |
409 Append any new computation statements required to D->SEQ. */ | |
410 | |
411 static tree | |
412 gen_emutls_addr (tree decl, struct lower_emutls_data *d) | |
413 { | |
414 unsigned int index; | |
415 tree addr; | |
416 | |
417 /* Compute the address of the TLS variable with help from runtime. */ | |
418 index = emutls_index (decl); | |
419 addr = VEC_index (tree, access_vars, index); | |
420 if (addr == NULL) | |
421 { | |
422 struct varpool_node *cvar; | |
423 tree cdecl; | |
424 gimple x; | |
425 | |
426 cvar = VEC_index (varpool_node_ptr, control_vars, index); | |
427 cdecl = cvar->decl; | |
428 TREE_ADDRESSABLE (cdecl) = 1; | |
429 | |
430 addr = create_tmp_var (build_pointer_type (TREE_TYPE (decl)), NULL); | |
431 x = gimple_build_call (d->builtin_decl, 1, build_fold_addr_expr (cdecl)); | |
432 gimple_set_location (x, d->loc); | |
433 | |
434 addr = make_ssa_name (addr, x); | |
435 gimple_call_set_lhs (x, addr); | |
436 | |
437 gimple_seq_add_stmt (&d->seq, x); | |
438 | |
439 cgraph_create_edge (d->cfun_node, d->builtin_node, x, | |
440 d->bb->count, d->bb_freq, d->bb->loop_depth); | |
441 | |
442 /* We may be adding a new reference to a new variable to the function. | |
443 This means we have to play with the ipa-reference web. */ | |
444 ipa_record_reference (d->cfun_node, NULL, NULL, cvar, IPA_REF_ADDR, x); | |
445 | |
446 /* Record this ssa_name for possible use later in the basic block. */ | |
447 VEC_replace (tree, access_vars, index, addr); | |
448 } | |
449 | |
450 return addr; | |
451 } | |
452 | |
453 /* Callback for walk_gimple_op. D = WI->INFO is a struct lower_emutls_data. | |
454 Given an operand *PTR within D->STMT, if the operand references a TLS | |
455 variable, then lower the reference to a call to the runtime. Insert | |
456 any new statements required into D->SEQ; the caller is responsible for | |
457 placing those appropriately. */ | |
458 | |
459 static tree | |
460 lower_emutls_1 (tree *ptr, int *walk_subtrees, void *cb_data) | |
461 { | |
462 struct walk_stmt_info *wi = (struct walk_stmt_info *) cb_data; | |
463 struct lower_emutls_data *d = (struct lower_emutls_data *) wi->info; | |
464 tree t = *ptr; | |
465 bool is_addr = false; | |
466 tree addr; | |
467 | |
468 *walk_subtrees = 0; | |
469 | |
470 switch (TREE_CODE (t)) | |
471 { | |
472 case ADDR_EXPR: | |
473 /* If this is not a straight-forward "&var", but rather something | |
474 like "&var.a", then we may need special handling. */ | |
475 if (TREE_CODE (TREE_OPERAND (t, 0)) != VAR_DECL) | |
476 { | |
477 bool save_changed; | |
478 | |
479 /* If we're allowed more than just is_gimple_val, continue. */ | |
480 if (!wi->val_only) | |
481 { | |
482 *walk_subtrees = 1; | |
483 return NULL_TREE; | |
484 } | |
485 | |
486 /* See if any substitution would be made. */ | |
487 save_changed = wi->changed; | |
488 wi->changed = false; | |
489 wi->val_only = false; | |
490 walk_tree (&TREE_OPERAND (t, 0), lower_emutls_1, wi, NULL); | |
491 wi->val_only = true; | |
492 | |
493 /* If so, then extract this entire sub-expression "&p->a" into a | |
494 new assignment statement, and substitute yet another SSA_NAME. */ | |
495 if (wi->changed) | |
496 { | |
497 gimple x; | |
498 | |
499 addr = create_tmp_var (TREE_TYPE (t), NULL); | |
500 x = gimple_build_assign (addr, t); | |
501 gimple_set_location (x, d->loc); | |
502 | |
503 addr = make_ssa_name (addr, x); | |
504 gimple_assign_set_lhs (x, addr); | |
505 | |
506 gimple_seq_add_stmt (&d->seq, x); | |
507 | |
508 *ptr = addr; | |
509 } | |
510 else | |
511 wi->changed = save_changed; | |
512 | |
513 return NULL_TREE; | |
514 } | |
515 | |
516 t = TREE_OPERAND (t, 0); | |
517 is_addr = true; | |
518 /* FALLTHRU */ | |
519 | |
520 case VAR_DECL: | |
521 if (!DECL_THREAD_LOCAL_P (t)) | |
522 return NULL_TREE; | |
523 break; | |
524 | |
525 default: | |
526 /* We're not interested in other decls or types, only subexpressions. */ | |
527 if (EXPR_P (t)) | |
528 *walk_subtrees = 1; | |
529 /* FALLTHRU */ | |
530 | |
531 case SSA_NAME: | |
532 /* Special-case the return of SSA_NAME, since it's so common. */ | |
533 return NULL_TREE; | |
534 } | |
535 | |
536 addr = gen_emutls_addr (t, d); | |
537 if (is_addr) | |
538 { | |
539 /* Replace "&var" with "addr" in the statement. */ | |
540 *ptr = addr; | |
541 } | |
542 else | |
543 { | |
544 /* Replace "var" with "*addr" in the statement. */ | |
545 t = build2 (MEM_REF, TREE_TYPE (t), addr, | |
546 build_int_cst (TREE_TYPE (addr), 0)); | |
547 *ptr = t; | |
548 } | |
549 | |
550 wi->changed = true; | |
551 return NULL_TREE; | |
552 } | |
553 | |
554 /* Lower all of the operands of STMT. */ | |
555 | |
556 static void | |
557 lower_emutls_stmt (gimple stmt, struct lower_emutls_data *d) | |
558 { | |
559 struct walk_stmt_info wi; | |
560 | |
561 d->loc = gimple_location (stmt); | |
562 | |
563 memset (&wi, 0, sizeof (wi)); | |
564 wi.info = d; | |
565 wi.val_only = true; | |
566 walk_gimple_op (stmt, lower_emutls_1, &wi); | |
567 | |
568 if (wi.changed) | |
569 update_stmt (stmt); | |
570 } | |
571 | |
572 /* Lower the I'th operand of PHI. */ | |
573 | |
574 static void | |
575 lower_emutls_phi_arg (gimple phi, unsigned int i, struct lower_emutls_data *d) | |
576 { | |
577 struct walk_stmt_info wi; | |
578 struct phi_arg_d *pd = gimple_phi_arg (phi, i); | |
579 | |
580 /* Early out for a very common case we don't care about. */ | |
581 if (TREE_CODE (pd->def) == SSA_NAME) | |
582 return; | |
583 | |
584 d->loc = pd->locus; | |
585 | |
586 memset (&wi, 0, sizeof (wi)); | |
587 wi.info = d; | |
588 wi.val_only = true; | |
589 walk_tree (&pd->def, lower_emutls_1, &wi, NULL); | |
590 | |
591 /* For normal statements, we let update_stmt do its job. But for phi | |
592 nodes, we have to manipulate the immediate use list by hand. */ | |
593 if (wi.changed) | |
594 { | |
595 gcc_assert (TREE_CODE (pd->def) == SSA_NAME); | |
596 link_imm_use_stmt (&pd->imm_use, pd->def, phi); | |
597 } | |
598 } | |
599 | |
600 /* Clear the ACCESS_VARS array, in order to begin a new block. */ | |
601 | |
602 static inline void | |
603 clear_access_vars (void) | |
604 { | |
605 memset (VEC_address (tree, access_vars), 0, | |
606 VEC_length (tree, access_vars) * sizeof(tree)); | |
607 } | |
608 | |
609 /* Lower the entire function NODE. */ | |
610 | |
611 static void | |
612 lower_emutls_function_body (struct cgraph_node *node) | |
613 { | |
614 struct lower_emutls_data d; | |
615 bool any_edge_inserts = false; | |
616 | |
617 current_function_decl = node->decl; | |
618 push_cfun (DECL_STRUCT_FUNCTION (node->decl)); | |
619 | |
620 d.cfun_node = node; | |
621 d.builtin_decl = built_in_decls[BUILT_IN_EMUTLS_GET_ADDRESS]; | |
622 d.builtin_node = cgraph_node (d.builtin_decl); | |
623 | |
624 FOR_EACH_BB (d.bb) | |
625 { | |
626 gimple_stmt_iterator gsi; | |
627 unsigned int i, nedge; | |
628 | |
629 /* Lower each of the PHI nodes of the block, as we may have | |
630 propagated &tlsvar into a PHI argument. These loops are | |
631 arranged so that we process each edge at once, and each | |
632 PHI argument for that edge. */ | |
633 if (!gimple_seq_empty_p (phi_nodes (d.bb))) | |
634 { | |
635 /* The calls will be inserted on the edges, and the frequencies | |
636 will be computed during the commit process. */ | |
637 d.bb_freq = 0; | |
638 | |
639 nedge = EDGE_COUNT (d.bb->preds); | |
640 for (i = 0; i < nedge; ++i) | |
641 { | |
642 edge e = EDGE_PRED (d.bb, i); | |
643 | |
644 /* We can re-use any SSA_NAME created on this edge. */ | |
645 clear_access_vars (); | |
646 d.seq = NULL; | |
647 | |
648 for (gsi = gsi_start_phis (d.bb); | |
649 !gsi_end_p (gsi); | |
650 gsi_next (&gsi)) | |
651 lower_emutls_phi_arg (gsi_stmt (gsi), i, &d); | |
652 | |
653 /* Insert all statements generated by all phi nodes for this | |
654 particular edge all at once. */ | |
655 if (d.seq) | |
656 { | |
657 gsi_insert_seq_on_edge (e, d.seq); | |
658 any_edge_inserts = true; | |
659 } | |
660 } | |
661 } | |
662 | |
663 d.bb_freq = compute_call_stmt_bb_frequency (current_function_decl, d.bb); | |
664 | |
665 /* We can re-use any SSA_NAME created during this basic block. */ | |
666 clear_access_vars (); | |
667 | |
668 /* Lower each of the statements of the block. */ | |
669 for (gsi = gsi_start_bb (d.bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
670 { | |
671 d.seq = NULL; | |
672 lower_emutls_stmt (gsi_stmt (gsi), &d); | |
673 | |
674 /* If any new statements were created, insert them immediately | |
675 before the first use. This prevents variable lifetimes from | |
676 becoming unnecessarily long. */ | |
677 if (d.seq) | |
678 gsi_insert_seq_before (&gsi, d.seq, GSI_SAME_STMT); | |
679 } | |
680 } | |
681 | |
682 if (any_edge_inserts) | |
683 gsi_commit_edge_inserts (); | |
684 | |
685 pop_cfun (); | |
686 current_function_decl = NULL; | |
687 } | |
688 | |
689 /* Main entry point to the tls lowering pass. */ | |
690 | |
691 static unsigned int | |
692 ipa_lower_emutls (void) | |
693 { | |
694 struct varpool_node *var; | |
695 struct cgraph_node *func; | |
696 bool any_aliases = false; | |
697 tree ctor_body = NULL; | |
698 unsigned int i, n_tls; | |
699 | |
700 tls_vars = varpool_node_set_new (); | |
701 | |
702 /* Examine all global variables for TLS variables. */ | |
703 for (var = varpool_nodes; var ; var = var->next) | |
704 if (DECL_THREAD_LOCAL_P (var->decl)) | |
705 { | |
706 gcc_checking_assert (TREE_STATIC (var->decl) | |
707 || DECL_EXTERNAL (var->decl)); | |
708 varpool_node_set_add (tls_vars, var); | |
709 } | |
710 | |
711 /* If we found no TLS variables, then there is no further work to do. */ | |
712 if (tls_vars->nodes == NULL) | |
713 { | |
714 tls_vars = NULL; | |
715 if (dump_file) | |
716 fprintf (dump_file, "No TLS variables found.\n"); | |
717 return 0; | |
718 } | |
719 | |
720 /* Allocate the on-the-side arrays that share indicies with the TLS vars. */ | |
721 n_tls = VEC_length (varpool_node_ptr, tls_vars->nodes); | |
722 control_vars = VEC_alloc (varpool_node_ptr, heap, n_tls); | |
723 access_vars = VEC_alloc (tree, heap, n_tls); | |
724 VEC_safe_grow (tree, heap, access_vars, n_tls); | |
725 | |
726 /* Create the control variables for each TLS variable. */ | |
727 FOR_EACH_VEC_ELT (varpool_node_ptr, tls_vars->nodes, i, var) | |
728 { | |
729 tree cdecl; | |
730 struct varpool_node *cvar; | |
731 | |
732 var = VEC_index (varpool_node_ptr, tls_vars->nodes, i); | |
733 cdecl = new_emutls_decl (var->decl); | |
734 | |
735 cvar = varpool_get_node (cdecl); | |
736 VEC_quick_push (varpool_node_ptr, control_vars, cvar); | |
737 | |
738 if (var->alias) | |
739 { | |
740 any_aliases = true; | |
741 cvar->alias = true; | |
742 } | |
743 else | |
744 { | |
745 /* Make sure the COMMON block control variable gets initialized. | |
746 Note that there's no point in doing this for aliases; we only | |
747 need to do this once for the main variable. */ | |
748 emutls_common_1 (var->decl, cdecl, &ctor_body); | |
749 } | |
750 | |
751 /* Indicate that the value of the TLS variable may be found elsewhere, | |
752 preventing the variable from re-appearing in the GIMPLE. We cheat | |
753 and use the control variable here (rather than a full call_expr), | |
754 which is special-cased inside the DWARF2 output routines. */ | |
755 SET_DECL_VALUE_EXPR (var->decl, cdecl); | |
756 DECL_HAS_VALUE_EXPR_P (var->decl) = 1; | |
757 } | |
758 | |
759 /* If there were any aliases, then frob the alias_pairs vector. */ | |
760 if (any_aliases) | |
761 { | |
762 alias_pair *p; | |
763 FOR_EACH_VEC_ELT (alias_pair, alias_pairs, i, p) | |
764 if (DECL_THREAD_LOCAL_P (p->decl)) | |
765 { | |
766 p->decl = emutls_decl (p->decl); | |
767 p->target = get_emutls_object_name (p->target); | |
768 } | |
769 } | |
770 | |
771 /* Adjust all uses of TLS variables within the function bodies. */ | |
772 for (func = cgraph_nodes; func; func = func->next) | |
773 if (func->reachable && func->lowered) | |
774 lower_emutls_function_body (func); | |
775 | |
776 /* Generate the constructor for any COMMON control variables created. */ | |
777 if (ctor_body) | |
778 cgraph_build_static_cdtor ('I', ctor_body, DEFAULT_INIT_PRIORITY); | |
779 | |
780 VEC_free (varpool_node_ptr, heap, control_vars); | |
781 VEC_free (tree, heap, access_vars); | |
782 tls_vars = NULL; | |
783 | |
784 return TODO_dump_func | TODO_ggc_collect | TODO_verify_all; | |
785 } | |
786 | |
787 /* If the target supports TLS natively, we need do nothing here. */ | |
788 | |
789 static bool | |
790 gate_emutls (void) | |
791 { | |
792 return !targetm.have_tls; | |
793 } | |
794 | |
795 struct simple_ipa_opt_pass pass_ipa_lower_emutls = | |
796 { | |
797 { | |
798 SIMPLE_IPA_PASS, | |
799 "emutls", /* name */ | |
800 gate_emutls, /* gate */ | |
801 ipa_lower_emutls, /* execute */ | |
802 NULL, /* sub */ | |
803 NULL, /* next */ | |
804 0, /* static_pass_number */ | |
805 TV_IPA_OPT, /* tv_id */ | |
806 PROP_cfg | PROP_ssa, /* properties_required */ | |
807 0, /* properties_provided */ | |
808 0, /* properties_destroyed */ | |
809 0, /* todo_flags_start */ | |
810 0, /* todo_flags_finish */ | |
811 } | |
812 }; |