Mercurial > hg > CbC > CbC_gcc
annotate gcc/varpool.c @ 141:ce508c72660f
copy cbc flang in cfgexpand
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 22 Nov 2018 19:44:39 +0900 |
parents | 84e7813d76e9 |
children | 1830386684a0 |
rev | line source |
---|---|
0 | 1 /* Callgraph handling code. |
131 | 2 Copyright (C) 2003-2018 Free Software Foundation, Inc. |
0 | 3 Contributed by Jan Hubicka |
4 | |
5 This file is part of GCC. | |
6 | |
7 GCC is free software; you can redistribute it and/or modify it under | |
8 the terms of the GNU General Public License as published by the Free | |
9 Software Foundation; either version 3, or (at your option) any later | |
10 version. | |
11 | |
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 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" | |
111 | 24 #include "backend.h" |
25 #include "target.h" | |
0 | 26 #include "tree.h" |
27 #include "gimple.h" | |
111 | 28 #include "timevar.h" |
29 #include "cgraph.h" | |
30 #include "lto-streamer.h" | |
31 #include "varasm.h" | |
32 #include "debug.h" | |
33 #include "output.h" | |
34 #include "omp-offload.h" | |
35 #include "context.h" | |
36 #include "stringpool.h" | |
37 #include "attribs.h" | |
0 | 38 |
111 | 39 const char * const tls_model_names[]={"none", "emulated", |
40 "global-dynamic", "local-dynamic", | |
41 "initial-exec", "local-exec"}; | |
0 | 42 |
111 | 43 /* List of hooks triggered on varpool_node events. */ |
44 struct varpool_node_hook_list { | |
45 varpool_node_hook hook; | |
46 void *data; | |
47 struct varpool_node_hook_list *next; | |
48 }; | |
0 | 49 |
111 | 50 /* Register HOOK to be called with DATA on each removed node. */ |
51 varpool_node_hook_list * | |
52 symbol_table::add_varpool_removal_hook (varpool_node_hook hook, void *data) | |
53 { | |
54 varpool_node_hook_list *entry; | |
55 varpool_node_hook_list **ptr = &m_first_varpool_removal_hook; | |
0 | 56 |
111 | 57 entry = (varpool_node_hook_list *) xmalloc (sizeof (*entry)); |
58 entry->hook = hook; | |
59 entry->data = data; | |
60 entry->next = NULL; | |
61 while (*ptr) | |
62 ptr = &(*ptr)->next; | |
63 *ptr = entry; | |
64 return entry; | |
65 } | |
0 | 66 |
111 | 67 /* Remove ENTRY from the list of hooks called on removing nodes. */ |
68 void | |
69 symbol_table::remove_varpool_removal_hook (varpool_node_hook_list *entry) | |
70 { | |
71 varpool_node_hook_list **ptr = &m_first_varpool_removal_hook; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
72 |
111 | 73 while (*ptr != entry) |
74 ptr = &(*ptr)->next; | |
75 *ptr = entry->next; | |
76 free (entry); | |
77 } | |
0 | 78 |
111 | 79 /* Call all node removal hooks. */ |
80 void | |
81 symbol_table::call_varpool_removal_hooks (varpool_node *node) | |
0 | 82 { |
111 | 83 varpool_node_hook_list *entry = m_first_varpool_removal_hook; |
84 while (entry) | |
85 { | |
86 entry->hook (node, entry->data); | |
87 entry = entry->next; | |
88 } | |
0 | 89 } |
90 | |
111 | 91 /* Register HOOK to be called with DATA on each inserted node. */ |
92 varpool_node_hook_list * | |
93 symbol_table::add_varpool_insertion_hook (varpool_node_hook hook, void *data) | |
0 | 94 { |
111 | 95 varpool_node_hook_list *entry; |
96 varpool_node_hook_list **ptr = &m_first_varpool_insertion_hook; | |
97 | |
98 entry = (varpool_node_hook_list *) xmalloc (sizeof (*entry)); | |
99 entry->hook = hook; | |
100 entry->data = data; | |
101 entry->next = NULL; | |
102 while (*ptr) | |
103 ptr = &(*ptr)->next; | |
104 *ptr = entry; | |
105 return entry; | |
0 | 106 } |
107 | |
111 | 108 /* Remove ENTRY from the list of hooks called on inserted nodes. */ |
109 void | |
110 symbol_table::remove_varpool_insertion_hook (varpool_node_hook_list *entry) | |
0 | 111 { |
111 | 112 varpool_node_hook_list **ptr = &m_first_varpool_insertion_hook; |
113 | |
114 while (*ptr != entry) | |
115 ptr = &(*ptr)->next; | |
116 *ptr = entry->next; | |
117 free (entry); | |
0 | 118 } |
119 | |
111 | 120 /* Call all node insertion hooks. */ |
121 void | |
122 symbol_table::call_varpool_insertion_hooks (varpool_node *node) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
123 { |
111 | 124 varpool_node_hook_list *entry = m_first_varpool_insertion_hook; |
125 while (entry) | |
126 { | |
127 entry->hook (node, entry->data); | |
128 entry = entry->next; | |
129 } | |
130 } | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
131 |
111 | 132 /* Allocate new callgraph node and insert it into basic data structures. */ |
133 | |
134 varpool_node * | |
135 varpool_node::create_empty (void) | |
136 { | |
137 varpool_node *node = ggc_cleared_alloc<varpool_node> (); | |
138 node->type = SYMTAB_VARIABLE; | |
139 return node; | |
140 } | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
141 |
0 | 142 /* Return varpool node assigned to DECL. Create new one when needed. */ |
111 | 143 varpool_node * |
144 varpool_node::get_create (tree decl) | |
0 | 145 { |
111 | 146 varpool_node *node = varpool_node::get (decl); |
147 gcc_checking_assert (VAR_P (decl)); | |
148 if (node) | |
149 return node; | |
0 | 150 |
111 | 151 node = varpool_node::create_empty (); |
152 node->decl = decl; | |
0 | 153 |
111 | 154 if ((flag_openacc || flag_openmp) |
155 && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))) | |
156 { | |
157 node->offloadable = 1; | |
158 if (ENABLE_OFFLOADING && !DECL_EXTERNAL (decl)) | |
159 { | |
160 g->have_offload = true; | |
161 if (!in_lto_p) | |
162 vec_safe_push (offload_vars, decl); | |
163 } | |
164 } | |
165 | |
166 node->register_symbol (); | |
0 | 167 return node; |
168 } | |
169 | |
111 | 170 /* Remove variable from symbol table. */ |
171 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
172 void |
111 | 173 varpool_node::remove (void) |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
174 { |
111 | 175 symtab->call_varpool_removal_hooks (this); |
176 if (lto_file_data) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
177 { |
111 | 178 lto_free_function_in_decl_state_for_node (this); |
179 lto_file_data = NULL; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
180 } |
111 | 181 |
182 /* When streaming we can have multiple nodes associated with decl. */ | |
183 if (symtab->state == LTO_STREAMING) | |
184 ; | |
185 /* Keep constructor when it may be used for folding. We remove | |
186 references to external variables before final compilation. */ | |
187 else if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node | |
188 && !ctor_useable_for_folding_p ()) | |
189 remove_initializer (); | |
190 | |
191 unregister (); | |
192 ggc_free (this); | |
193 } | |
194 | |
195 /* Remove node initializer when it is no longer needed. */ | |
196 void | |
197 varpool_node::remove_initializer (void) | |
198 { | |
199 if (DECL_INITIAL (decl) | |
200 && !DECL_IN_CONSTANT_POOL (decl) | |
201 /* Keep vtables for BINFO folding. */ | |
202 && !DECL_VIRTUAL_P (decl) | |
203 /* FIXME: http://gcc.gnu.org/PR55395 */ | |
204 && debug_info_level == DINFO_LEVEL_NONE | |
205 /* When doing declaration merging we have duplicate | |
206 entries for given decl. Do not attempt to remove | |
207 the boides, or we will end up remiving | |
208 wrong one. */ | |
209 && symtab->state != LTO_STREAMING) | |
210 DECL_INITIAL (decl) = error_mark_node; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
211 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
212 |
111 | 213 /* Dump given varpool node to F. */ |
0 | 214 void |
111 | 215 varpool_node::dump (FILE *f) |
0 | 216 { |
111 | 217 dump_base (f); |
218 fprintf (f, " Availability: %s\n", | |
219 symtab->function_flags_ready | |
220 ? cgraph_availability_names[get_availability ()] | |
0 | 221 : "not-ready"); |
111 | 222 fprintf (f, " Varpool flags:"); |
223 if (DECL_INITIAL (decl)) | |
0 | 224 fprintf (f, " initialized"); |
111 | 225 if (output) |
0 | 226 fprintf (f, " output"); |
111 | 227 if (used_by_single_function) |
228 fprintf (f, " used-by-single-function"); | |
229 if (need_bounds_init) | |
230 fprintf (f, " need-bounds-init"); | |
231 if (TREE_READONLY (decl)) | |
232 fprintf (f, " read-only"); | |
233 if (ctor_useable_for_folding_p ()) | |
234 fprintf (f, " const-value-known"); | |
235 if (writeonly) | |
236 fprintf (f, " write-only"); | |
237 if (tls_model) | |
238 fprintf (f, " tls-%s", tls_model_names [tls_model]); | |
0 | 239 fprintf (f, "\n"); |
240 } | |
241 | |
111 | 242 |
243 /* Dump given varpool node to stderr. */ | |
244 void varpool_node::debug (void) | |
245 { | |
246 varpool_node::dump (stderr); | |
247 } | |
248 | |
249 /* Dump the variable pool to F. */ | |
0 | 250 void |
111 | 251 varpool_node::dump_varpool (FILE *f) |
0 | 252 { |
111 | 253 varpool_node *node; |
0 | 254 |
255 fprintf (f, "variable pool:\n\n"); | |
111 | 256 FOR_EACH_VARIABLE (node) |
257 node->dump (f); | |
0 | 258 } |
259 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
260 /* Dump the variable pool to stderr. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
261 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
262 DEBUG_FUNCTION void |
111 | 263 varpool_node::debug_varpool (void) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
264 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
265 dump_varpool (stderr); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
266 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
267 |
0 | 268 /* Given an assembler name, lookup node. */ |
111 | 269 varpool_node * |
270 varpool_node::get_for_asmname (tree asmname) | |
0 | 271 { |
111 | 272 if (symtab_node *node = symtab_node::get_for_asmname (asmname)) |
273 return dyn_cast <varpool_node *> (node); | |
274 else | |
275 return NULL; | |
0 | 276 } |
277 | |
111 | 278 /* When doing LTO, read variable's constructor from disk if |
279 it is not already present. */ | |
280 | |
281 tree | |
282 varpool_node::get_constructor (void) | |
0 | 283 { |
111 | 284 lto_file_decl_data *file_data; |
285 const char *data, *name; | |
286 size_t len; | |
287 | |
288 if (DECL_INITIAL (decl) != error_mark_node | |
289 || !in_lto_p | |
290 || !lto_file_data) | |
291 return DECL_INITIAL (decl); | |
292 | |
293 timevar_push (TV_IPA_LTO_CTORS_IN); | |
294 | |
295 file_data = lto_file_data; | |
296 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); | |
297 | |
298 /* We may have renamed the declaration, e.g., a static function. */ | |
299 name = lto_get_decl_name_mapping (file_data, name); | |
300 struct lto_in_decl_state *decl_state | |
301 = lto_get_function_in_decl_state (file_data, decl); | |
302 | |
303 data = lto_get_section_data (file_data, LTO_section_function_body, | |
304 name, &len, decl_state->compressed); | |
305 if (!data) | |
306 fatal_error (input_location, "%s: section %s is missing", | |
307 file_data->file_name, | |
308 name); | |
309 | |
131 | 310 if (!quiet_flag) |
311 fprintf (stderr, " in:%s", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); | |
111 | 312 lto_input_variable_constructor (file_data, this, data); |
313 gcc_assert (DECL_INITIAL (decl) != error_mark_node); | |
314 lto_stats.num_function_bodies++; | |
315 lto_free_section_data (file_data, LTO_section_function_body, name, | |
316 data, len, decl_state->compressed); | |
317 lto_free_function_in_decl_state_for_node (this); | |
318 timevar_pop (TV_IPA_LTO_CTORS_IN); | |
319 return DECL_INITIAL (decl); | |
0 | 320 } |
321 | |
111 | 322 /* Return true if variable has constructor that can be used for folding. */ |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
323 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
324 bool |
111 | 325 varpool_node::ctor_useable_for_folding_p (void) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
326 { |
111 | 327 varpool_node *real_node = this; |
328 | |
329 if (real_node->alias && real_node->definition) | |
330 real_node = ultimate_alias_target (); | |
0 | 331 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
332 if (TREE_CODE (decl) == CONST_DECL |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
333 || DECL_IN_CONSTANT_POOL (decl)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
334 return true; |
111 | 335 if (TREE_THIS_VOLATILE (decl)) |
336 return false; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
337 |
111 | 338 /* If we do not have a constructor, we can't use it. */ |
339 if (DECL_INITIAL (real_node->decl) == error_mark_node | |
340 && !real_node->lto_file_data) | |
341 return false; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
342 |
111 | 343 /* Avoid attempts to load constructors that was not streamed. */ |
344 if (flag_ltrans && DECL_INITIAL (real_node->decl) == error_mark_node | |
345 && real_node->body_removed) | |
0 | 346 return false; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
347 |
111 | 348 /* Vtables are defined by their types and must match no matter of interposition |
349 rules. */ | |
350 if (DECL_VIRTUAL_P (decl)) | |
351 { | |
352 /* The C++ front end creates VAR_DECLs for vtables of typeinfo | |
353 classes not defined in the current TU so that it can refer | |
354 to them from typeinfo objects. Avoid returning NULL_TREE. */ | |
355 return DECL_INITIAL (real_node->decl) != NULL; | |
356 } | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
357 |
111 | 358 /* Alias of readonly variable is also readonly, since the variable is stored |
359 in readonly memory. We also accept readonly aliases of non-readonly | |
360 locations assuming that user knows what he is asking for. */ | |
361 if (!TREE_READONLY (decl) && !TREE_READONLY (real_node->decl)) | |
362 return false; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
363 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
364 /* Variables declared 'const' without an initializer |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
365 have zero as the initializer if they may not be |
111 | 366 overridden at link or run time. |
367 | |
368 It is actually requirement for C++ compiler to optimize const variables | |
369 consistently. As a GNU extension, do not enfore this rule for user defined | |
370 weak variables, so we support interposition on: | |
371 static const int dummy = 0; | |
372 extern const int foo __attribute__((__weak__, __alias__("dummy"))); | |
373 */ | |
374 if ((!DECL_INITIAL (real_node->decl) | |
375 || (DECL_WEAK (decl) && !DECL_COMDAT (decl))) | |
376 && (DECL_EXTERNAL (decl) || decl_replaceable_p (decl))) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
377 return false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
378 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
379 /* Variables declared `const' with an initializer are considered |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
380 to not be overwritable with different initializer by default. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
381 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
382 ??? Previously we behaved so for scalar variables but not for array |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
383 accesses. */ |
0 | 384 return true; |
385 } | |
386 | |
111 | 387 /* If DECLARATION is constant variable and its initial value is known |
388 (so we can do constant folding), return its constructor (DECL_INITIAL). | |
389 This may be an expression or NULL when DECL is initialized to 0. | |
390 Return ERROR_MARK_NODE otherwise. | |
391 | |
392 In LTO this may actually trigger reading the constructor from disk. | |
393 For this reason varpool_ctor_useable_for_folding_p should be used when | |
394 the actual constructor value is not needed. */ | |
395 | |
396 tree | |
397 ctor_for_folding (tree decl) | |
0 | 398 { |
111 | 399 varpool_node *node, *real_node; |
400 tree real_decl; | |
401 | |
402 if (!VAR_P (decl) && TREE_CODE (decl) != CONST_DECL) | |
403 return error_mark_node; | |
404 | |
405 if (TREE_CODE (decl) == CONST_DECL | |
406 || DECL_IN_CONSTANT_POOL (decl)) | |
407 return DECL_INITIAL (decl); | |
408 | |
409 if (TREE_THIS_VOLATILE (decl)) | |
410 return error_mark_node; | |
411 | |
412 /* Do not care about automatic variables. Those are never initialized | |
413 anyway, because gimplifier exapnds the code. */ | |
414 if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl)) | |
415 { | |
416 gcc_assert (!TREE_PUBLIC (decl)); | |
417 return error_mark_node; | |
418 } | |
419 | |
420 gcc_assert (VAR_P (decl)); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
421 |
111 | 422 real_node = node = varpool_node::get (decl); |
423 if (node) | |
0 | 424 { |
111 | 425 real_node = node->ultimate_alias_target (); |
426 real_decl = real_node->decl; | |
427 } | |
428 else | |
429 real_decl = decl; | |
430 | |
431 /* See if we are dealing with alias. | |
432 In most cases alias is just alternative symbol pointing to a given | |
433 constructor. This allows us to use interposition rules of DECL | |
434 constructor of REAL_NODE. However weakrefs are special by being just | |
435 alternative name of their target (if defined). */ | |
436 if (decl != real_decl) | |
437 { | |
438 gcc_assert (!DECL_INITIAL (decl) | |
439 || (node->alias && node->get_alias_target () == real_node) | |
440 || DECL_INITIAL (decl) == error_mark_node); | |
441 while (node->transparent_alias && node->analyzed) | |
442 { | |
443 node = node->get_alias_target (); | |
444 decl = node->decl; | |
445 } | |
0 | 446 } |
111 | 447 |
448 if ((!DECL_VIRTUAL_P (real_decl) | |
449 || DECL_INITIAL (real_decl) == error_mark_node | |
450 || !DECL_INITIAL (real_decl)) | |
451 && (!node || !node->ctor_useable_for_folding_p ())) | |
452 return error_mark_node; | |
453 | |
454 /* OK, we can return constructor. See if we need to fetch it from disk | |
455 in LTO mode. */ | |
456 if (DECL_INITIAL (real_decl) != error_mark_node | |
457 || !in_lto_p) | |
458 return DECL_INITIAL (real_decl); | |
459 return real_node->get_constructor (); | |
460 } | |
0 | 461 |
111 | 462 /* Add the variable DECL to the varpool. |
463 Unlike finalize_decl function is intended to be used | |
464 by middle end and allows insertion of new variable at arbitrary point | |
465 of compilation. */ | |
466 void | |
467 varpool_node::add (tree decl) | |
468 { | |
469 varpool_node *node; | |
470 varpool_node::finalize_decl (decl); | |
471 node = varpool_node::get_create (decl); | |
472 symtab->call_varpool_insertion_hooks (node); | |
473 if (node->externally_visible_p ()) | |
474 node->externally_visible = true; | |
475 if (lookup_attribute ("no_reorder", DECL_ATTRIBUTES (decl))) | |
476 node->no_reorder = 1; | |
0 | 477 } |
478 | |
479 /* Return variable availability. See cgraph.h for description of individual | |
480 return values. */ | |
481 enum availability | |
111 | 482 varpool_node::get_availability (symtab_node *ref) |
0 | 483 { |
111 | 484 if (!definition) |
0 | 485 return AVAIL_NOT_AVAILABLE; |
111 | 486 if (!TREE_PUBLIC (decl)) |
487 return AVAIL_AVAILABLE; | |
488 if (DECL_IN_CONSTANT_POOL (decl) | |
489 || DECL_VIRTUAL_P (decl)) | |
490 return AVAIL_AVAILABLE; | |
491 if (transparent_alias && definition) | |
492 { | |
493 enum availability avail; | |
494 | |
495 ultimate_alias_target (&avail, ref); | |
496 return avail; | |
497 } | |
498 /* If this is a reference from symbol itself and there are no aliases, we | |
499 may be sure that the symbol was not interposed by something else because | |
500 the symbol itself would be unreachable otherwise. */ | |
501 if ((this == ref && !has_aliases_p ()) | |
502 || (ref && get_comdat_group () | |
503 && get_comdat_group () == ref->get_comdat_group ())) | |
0 | 504 return AVAIL_AVAILABLE; |
505 /* If the variable can be overwritten, return OVERWRITABLE. Takes | |
111 | 506 care of at least one notable extension - the COMDAT variables |
0 | 507 used to share template instantiations in C++. */ |
111 | 508 if (decl_replaceable_p (decl) |
509 || DECL_EXTERNAL (decl)) | |
510 return AVAIL_INTERPOSABLE; | |
0 | 511 return AVAIL_AVAILABLE; |
512 } | |
513 | |
111 | 514 void |
515 varpool_node::analyze (void) | |
0 | 516 { |
111 | 517 /* When reading back varpool at LTO time, we re-construct the queue in order |
518 to have "needed" list right by inserting all needed nodes into varpool. | |
519 We however don't want to re-analyze already analyzed nodes. */ | |
520 if (!analyzed) | |
0 | 521 { |
111 | 522 gcc_assert (!in_lto_p || symtab->function_flags_ready); |
523 /* Compute the alignment early so function body expanders are | |
524 already informed about increased alignment. */ | |
525 align_variable (decl, 0); | |
526 } | |
527 if (alias) | |
528 resolve_alias (varpool_node::get (alias_target)); | |
529 else if (DECL_INITIAL (decl)) | |
530 record_references_in_initializer (decl, analyzed); | |
531 analyzed = true; | |
532 } | |
0 | 533 |
111 | 534 /* Assemble thunks and aliases associated to varpool node. */ |
535 | |
536 void | |
537 varpool_node::assemble_aliases (void) | |
538 { | |
539 ipa_ref *ref; | |
540 | |
541 FOR_EACH_ALIAS (this, ref) | |
542 { | |
543 varpool_node *alias = dyn_cast <varpool_node *> (ref->referring); | |
544 if (!alias->transparent_alias) | |
545 do_assemble_alias (alias->decl, | |
546 DECL_ASSEMBLER_NAME (decl)); | |
547 alias->assemble_aliases (); | |
0 | 548 } |
549 } | |
550 | |
551 /* Output one variable, if necessary. Return whether we output it. */ | |
111 | 552 |
0 | 553 bool |
111 | 554 varpool_node::assemble_decl (void) |
0 | 555 { |
111 | 556 /* Aliases are outout when their target is produced or by |
557 output_weakrefs. */ | |
558 if (alias) | |
559 return false; | |
0 | 560 |
111 | 561 /* Constant pool is output from RTL land when the reference |
562 survive till this level. */ | |
563 if (DECL_IN_CONSTANT_POOL (decl) && TREE_ASM_WRITTEN (decl)) | |
564 return false; | |
565 | |
566 /* Decls with VALUE_EXPR should not be in the varpool at all. They | |
567 are not real variables, but just info for debugging and codegen. | |
568 Unfortunately at the moment emutls is not updating varpool correctly | |
569 after turning real vars into value_expr vars. */ | |
570 if (DECL_HAS_VALUE_EXPR_P (decl) | |
571 && !targetm.have_tls) | |
572 return false; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
573 |
111 | 574 /* Hard register vars do not need to be output. */ |
575 if (DECL_HARD_REGISTER (decl)) | |
576 return false; | |
577 | |
578 gcc_checking_assert (!TREE_ASM_WRITTEN (decl) | |
579 && VAR_P (decl) | |
580 && !DECL_HAS_VALUE_EXPR_P (decl)); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
581 |
111 | 582 if (!in_other_partition |
583 && !DECL_EXTERNAL (decl)) | |
584 { | |
585 get_constructor (); | |
586 assemble_variable (decl, 0, 1, 0); | |
587 gcc_assert (TREE_ASM_WRITTEN (decl)); | |
588 gcc_assert (definition); | |
589 assemble_aliases (); | |
590 /* After the parser has generated debugging information, augment | |
591 this information with any new location/etc information that may | |
592 have become available after the compilation proper. */ | |
593 debug_hooks->late_global_decl (decl); | |
594 return true; | |
0 | 595 } |
596 | |
597 return false; | |
598 } | |
599 | |
111 | 600 /* Add NODE to queue starting at FIRST. |
601 The queue is linked via AUX pointers and terminated by pointer to 1. */ | |
602 | |
603 static void | |
604 enqueue_node (varpool_node *node, varpool_node **first) | |
605 { | |
606 if (node->aux) | |
607 return; | |
608 gcc_checking_assert (*first); | |
609 node->aux = *first; | |
610 *first = node; | |
611 } | |
0 | 612 |
111 | 613 /* Optimization of function bodies might've rendered some variables as |
614 unnecessary so we want to avoid these from being compiled. Re-do | |
615 reachability starting from variables that are either externally visible | |
616 or was referred from the asm output routines. */ | |
617 | |
0 | 618 void |
111 | 619 symbol_table::remove_unreferenced_decls (void) |
0 | 620 { |
111 | 621 varpool_node *next, *node; |
622 varpool_node *first = (varpool_node *)(void *)1; | |
623 int i; | |
624 ipa_ref *ref = NULL; | |
625 hash_set<varpool_node *> referenced; | |
0 | 626 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
627 if (seen_error ()) |
0 | 628 return; |
629 | |
111 | 630 if (dump_file) |
631 fprintf (dump_file, "Trivially needed variables:"); | |
632 FOR_EACH_DEFINED_VARIABLE (node) | |
0 | 633 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
634 if (node->analyzed |
111 | 635 && (!node->can_remove_if_no_refs_p () |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
636 /* We just expanded all function bodies. See if any of |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
637 them needed the variable. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
638 || DECL_RTL_SET_P (node->decl))) |
111 | 639 { |
640 enqueue_node (node, &first); | |
641 if (dump_file) | |
642 fprintf (dump_file, " %s", node->asm_name ()); | |
643 } | |
0 | 644 } |
111 | 645 while (first != (varpool_node *)(void *)1) |
646 { | |
647 node = first; | |
648 first = (varpool_node *)first->aux; | |
649 | |
650 if (node->same_comdat_group) | |
651 { | |
652 symtab_node *next; | |
653 for (next = node->same_comdat_group; | |
654 next != node; | |
655 next = next->same_comdat_group) | |
656 { | |
657 varpool_node *vnext = dyn_cast <varpool_node *> (next); | |
658 if (vnext && vnext->analyzed && !next->comdat_local_p ()) | |
659 enqueue_node (vnext, &first); | |
660 } | |
661 } | |
662 for (i = 0; node->iterate_reference (i, ref); i++) | |
663 { | |
664 varpool_node *vnode = dyn_cast <varpool_node *> (ref->referred); | |
665 if (vnode | |
666 && !vnode->in_other_partition | |
667 && (!DECL_EXTERNAL (ref->referred->decl) | |
668 || vnode->alias) | |
669 && vnode->analyzed) | |
670 enqueue_node (vnode, &first); | |
671 else | |
672 { | |
673 referenced.add (vnode); | |
674 while (vnode && vnode->alias && vnode->definition) | |
675 { | |
676 vnode = vnode->get_alias_target (); | |
677 referenced.add (vnode); | |
678 } | |
679 } | |
680 } | |
681 } | |
682 if (dump_file) | |
683 fprintf (dump_file, "\nRemoving variables:"); | |
684 for (node = first_defined_variable (); node; node = next) | |
685 { | |
686 next = next_defined_variable (node); | |
687 if (!node->aux && !node->no_reorder) | |
688 { | |
689 if (dump_file) | |
690 fprintf (dump_file, " %s", node->asm_name ()); | |
691 if (referenced.contains(node)) | |
692 node->remove_initializer (); | |
693 else | |
694 node->remove (); | |
695 } | |
696 } | |
697 | |
698 if (dump_file) | |
699 fprintf (dump_file, "\n"); | |
0 | 700 } |
701 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
702 /* For variables in named sections make sure get_variable_section |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
703 is called before we switch to those sections. Then section |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
704 conflicts between read-only and read-only requiring relocations |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
705 sections can be resolved. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
706 void |
111 | 707 varpool_node::finalize_named_section_flags (void) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
708 { |
111 | 709 if (!TREE_ASM_WRITTEN (decl) |
710 && !alias | |
711 && !in_other_partition | |
712 && !DECL_EXTERNAL (decl) | |
713 && VAR_P (decl) | |
714 && !DECL_HAS_VALUE_EXPR_P (decl) | |
715 && get_section ()) | |
716 get_variable_section (decl, false); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
717 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
718 |
0 | 719 /* Output all variables enqueued to be assembled. */ |
720 bool | |
111 | 721 symbol_table::output_variables (void) |
0 | 722 { |
723 bool changed = false; | |
111 | 724 varpool_node *node; |
0 | 725 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
726 if (seen_error ()) |
0 | 727 return false; |
728 | |
111 | 729 remove_unreferenced_decls (); |
730 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
731 timevar_push (TV_VAROUT); |
0 | 732 |
111 | 733 FOR_EACH_DEFINED_VARIABLE (node) |
734 { | |
735 /* Handled in output_in_order. */ | |
736 if (node->no_reorder) | |
737 continue; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
738 |
111 | 739 node->finalize_named_section_flags (); |
740 } | |
0 | 741 |
111 | 742 /* There is a similar loop in output_in_order. Please keep them in sync. */ |
743 FOR_EACH_VARIABLE (node) | |
744 { | |
745 /* Handled in output_in_order. */ | |
746 if (node->no_reorder) | |
747 continue; | |
748 if (DECL_HARD_REGISTER (node->decl) | |
749 || DECL_HAS_VALUE_EXPR_P (node->decl)) | |
750 continue; | |
751 if (node->definition) | |
752 changed |= node->assemble_decl (); | |
0 | 753 else |
111 | 754 assemble_undefined_decl (node->decl); |
0 | 755 } |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
756 timevar_pop (TV_VAROUT); |
0 | 757 return changed; |
758 } | |
759 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
760 /* Attempt to mark ALIAS as an alias to DECL. Return TRUE if successful. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
761 Extra name aliases are output whenever DECL is output. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
762 |
111 | 763 varpool_node * |
764 varpool_node::create_alias (tree alias, tree decl) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
765 { |
111 | 766 varpool_node *alias_node; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
767 |
111 | 768 gcc_assert (VAR_P (decl)); |
769 gcc_assert (VAR_P (alias)); | |
770 alias_node = varpool_node::get_create (alias); | |
771 alias_node->alias = true; | |
772 alias_node->definition = true; | |
773 alias_node->alias_target = decl; | |
774 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL) | |
775 alias_node->weakref = alias_node->transparent_alias = true; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
776 return alias_node; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
777 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
778 |
111 | 779 /* Attempt to mark ALIAS as an alias to DECL. Return TRUE if successful. |
780 Extra name aliases are output whenever DECL is output. */ | |
781 | |
782 varpool_node * | |
783 varpool_node::create_extra_name_alias (tree alias, tree decl) | |
784 { | |
785 varpool_node *alias_node; | |
786 | |
787 /* If aliases aren't supported by the assembler, fail. */ | |
788 if (!TARGET_SUPPORTS_ALIASES) | |
789 return NULL; | |
790 | |
791 alias_node = varpool_node::create_alias (alias, decl); | |
792 alias_node->cpp_implicit_alias = true; | |
793 | |
794 /* Extra name alias mechanizm creates aliases really late | |
795 via DECL_ASSEMBLER_NAME mechanizm. | |
796 This is unfortunate because they are not going through the | |
797 standard channels. Ensure they get output. */ | |
798 if (symtab->cpp_implicit_aliases_done) | |
799 alias_node->resolve_alias (varpool_node::get_create (decl)); | |
800 return alias_node; | |
801 } | |
802 | |
803 /* Worker for call_for_symbol_and_aliases. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
804 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
805 bool |
111 | 806 varpool_node::call_for_symbol_and_aliases_1 (bool (*callback) (varpool_node *, |
807 void *), | |
808 void *data, | |
809 bool include_overwritable) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
810 { |
111 | 811 ipa_ref *ref; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
812 |
111 | 813 FOR_EACH_ALIAS (this, ref) |
814 { | |
815 varpool_node *alias = dyn_cast <varpool_node *> (ref->referring); | |
816 if (include_overwritable | |
817 || alias->get_availability () > AVAIL_INTERPOSABLE) | |
818 if (alias->call_for_symbol_and_aliases (callback, data, | |
819 include_overwritable)) | |
820 return true; | |
821 } | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
822 return false; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
823 } |