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