1 | /* Pass to free or clear language-specific data structures from |
2 | the IL before they reach the middle end. |
3 | |
4 | Copyright (C) 1987-2023 Free Software Foundation, Inc. |
5 | |
6 | This file is part of GCC. |
7 | |
8 | GCC is free software; you can redistribute it and/or modify it under |
9 | the terms of the GNU General Public License as published by the Free |
10 | Software Foundation; either version 3, or (at your option) any later |
11 | version. |
12 | |
13 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or |
15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
16 | for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with GCC; see the file COPYING3. If not see |
20 | <http://www.gnu.org/licenses/>. */ |
21 | |
22 | /* This file contains the low level primitives for operating on tree nodes, |
23 | including allocation, list operations, interning of identifiers, |
24 | construction of data type nodes and statement nodes, |
25 | and construction of type conversion nodes. It also contains |
26 | tables index by tree code that describe how to take apart |
27 | nodes of that code. |
28 | |
29 | It is intended to be language-independent but can occasionally |
30 | calls language-dependent routines. */ |
31 | |
32 | #include "config.h" |
33 | #include "system.h" |
34 | #include "coretypes.h" |
35 | #include "backend.h" |
36 | #include "target.h" |
37 | #include "tree.h" |
38 | #include "gimple.h" |
39 | #include "tree-pass.h" |
40 | #include "ssa.h" |
41 | #include "cgraph.h" |
42 | #include "diagnostic.h" |
43 | #include "alias.h" |
44 | #include "attribs.h" |
45 | #include "langhooks.h" |
46 | #include "gimple-iterator.h" |
47 | #include "langhooks-def.h" |
48 | #include "tree-diagnostic.h" |
49 | #include "except.h" |
50 | #include "ipa-utils.h" |
51 | |
52 | namespace { |
53 | |
54 | /* Data used when collecting DECLs and TYPEs for language data removal. */ |
55 | |
56 | class free_lang_data_d |
57 | { |
58 | public: |
59 | free_lang_data_d () : decls (100), types (100) {} |
60 | |
61 | /* Worklist to avoid excessive recursion. */ |
62 | auto_vec<tree> worklist; |
63 | |
64 | /* Set of traversed objects. Used to avoid duplicate visits. */ |
65 | hash_set<tree> pset; |
66 | |
67 | /* Array of symbols to process with free_lang_data_in_decl. */ |
68 | auto_vec<tree> decls; |
69 | |
70 | /* Array of types to process with free_lang_data_in_type. */ |
71 | auto_vec<tree> types; |
72 | }; |
73 | |
74 | |
75 | /* Add type or decl T to one of the list of tree nodes that need their |
76 | language data removed. The lists are held inside FLD. */ |
77 | |
78 | static void |
79 | add_tree_to_fld_list (tree t, class free_lang_data_d *fld) |
80 | { |
81 | if (DECL_P (t)) |
82 | fld->decls.safe_push (obj: t); |
83 | else if (TYPE_P (t)) |
84 | fld->types.safe_push (obj: t); |
85 | else |
86 | gcc_unreachable (); |
87 | } |
88 | |
89 | /* Push tree node T into FLD->WORKLIST. */ |
90 | |
91 | static inline void |
92 | fld_worklist_push (tree t, class free_lang_data_d *fld) |
93 | { |
94 | if (t && !is_lang_specific (t) && !fld->pset.contains (k: t)) |
95 | fld->worklist.safe_push (obj: (t)); |
96 | } |
97 | |
98 | |
99 | |
100 | /* Return simplified TYPE_NAME of TYPE. */ |
101 | |
102 | static tree |
103 | fld_simplified_type_name (tree type) |
104 | { |
105 | if (!TYPE_NAME (type) || TREE_CODE (TYPE_NAME (type)) != TYPE_DECL) |
106 | return TYPE_NAME (type); |
107 | /* Drop TYPE_DECLs in TYPE_NAME in favor of the identifier in the |
108 | TYPE_DECL if the type doesn't have linkage. |
109 | this must match fld_ */ |
110 | if (type != TYPE_MAIN_VARIANT (type) |
111 | || (!DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (type)) |
112 | && (TREE_CODE (type) != RECORD_TYPE |
113 | || !TYPE_BINFO (type) |
114 | || !BINFO_VTABLE (TYPE_BINFO (type))))) |
115 | return DECL_NAME (TYPE_NAME (type)); |
116 | return TYPE_NAME (type); |
117 | } |
118 | |
119 | /* Do same comparsion as check_qualified_type skipping lang part of type |
120 | and be more permissive about type names: we only care that names are |
121 | same (for diagnostics) and that ODR names are the same. |
122 | If INNER_TYPE is non-NULL, be sure that TREE_TYPE match it. */ |
123 | |
124 | static bool |
125 | fld_type_variant_equal_p (tree t, tree v, tree inner_type) |
126 | { |
127 | if (TYPE_QUALS (t) != TYPE_QUALS (v) |
128 | /* We want to match incomplete variants with complete types. |
129 | In this case we need to ignore alignment. */ |
130 | || ((!RECORD_OR_UNION_TYPE_P (t) || COMPLETE_TYPE_P (v)) |
131 | && (TYPE_ALIGN (t) != TYPE_ALIGN (v) |
132 | || TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (v))) |
133 | || fld_simplified_type_name (type: t) != fld_simplified_type_name (type: v) |
134 | || !attribute_list_equal (TYPE_ATTRIBUTES (t), |
135 | TYPE_ATTRIBUTES (v)) |
136 | || (inner_type && TREE_TYPE (v) != inner_type)) |
137 | return false; |
138 | |
139 | return true; |
140 | } |
141 | |
142 | /* Find variant of FIRST that match T and create new one if necessary. |
143 | Set TREE_TYPE to INNER_TYPE if non-NULL. */ |
144 | |
145 | static tree |
146 | fld_type_variant (tree first, tree t, class free_lang_data_d *fld, |
147 | tree inner_type = NULL) |
148 | { |
149 | if (first == TYPE_MAIN_VARIANT (t)) |
150 | return t; |
151 | for (tree v = first; v; v = TYPE_NEXT_VARIANT (v)) |
152 | if (fld_type_variant_equal_p (t, v, inner_type)) |
153 | return v; |
154 | tree v = build_variant_type_copy (first); |
155 | TYPE_READONLY (v) = TYPE_READONLY (t); |
156 | TYPE_VOLATILE (v) = TYPE_VOLATILE (t); |
157 | TYPE_ATOMIC (v) = TYPE_ATOMIC (t); |
158 | TYPE_RESTRICT (v) = TYPE_RESTRICT (t); |
159 | TYPE_ADDR_SPACE (v) = TYPE_ADDR_SPACE (t); |
160 | TYPE_NAME (v) = TYPE_NAME (t); |
161 | TYPE_ATTRIBUTES (v) = TYPE_ATTRIBUTES (t); |
162 | TYPE_CANONICAL (v) = TYPE_CANONICAL (t); |
163 | /* Variants of incomplete types should have alignment |
164 | set to BITS_PER_UNIT. Do not copy the actual alignment. */ |
165 | if (!RECORD_OR_UNION_TYPE_P (v) || COMPLETE_TYPE_P (v)) |
166 | { |
167 | SET_TYPE_ALIGN (v, TYPE_ALIGN (t)); |
168 | TYPE_USER_ALIGN (v) = TYPE_USER_ALIGN (t); |
169 | } |
170 | if (inner_type) |
171 | TREE_TYPE (v) = inner_type; |
172 | gcc_checking_assert (fld_type_variant_equal_p (t,v, inner_type)); |
173 | if (!fld->pset.add (k: v)) |
174 | add_tree_to_fld_list (t: v, fld); |
175 | return v; |
176 | } |
177 | |
178 | /* Map complete types to incomplete types. */ |
179 | |
180 | static hash_map<tree, tree> *fld_incomplete_types; |
181 | |
182 | /* Map types to simplified types. */ |
183 | |
184 | static hash_map<tree, tree> *fld_simplified_types; |
185 | |
186 | /* Produce variant of T whose TREE_TYPE is T2. If it is main variant, |
187 | use MAP to prevent duplicates. */ |
188 | |
189 | static tree |
190 | fld_process_array_type (tree t, tree t2, hash_map<tree, tree> *map, |
191 | class free_lang_data_d *fld) |
192 | { |
193 | if (TREE_TYPE (t) == t2) |
194 | return t; |
195 | |
196 | if (TYPE_MAIN_VARIANT (t) != t) |
197 | { |
198 | return fld_type_variant |
199 | (first: fld_process_array_type (TYPE_MAIN_VARIANT (t), |
200 | TYPE_MAIN_VARIANT (t2), map, fld), |
201 | t, fld, inner_type: t2); |
202 | } |
203 | |
204 | bool existed; |
205 | tree &array |
206 | = map->get_or_insert (k: t, existed: &existed); |
207 | if (!existed) |
208 | { |
209 | array |
210 | = build_array_type_1 (t2, TYPE_DOMAIN (t), TYPE_TYPELESS_STORAGE (t), |
211 | false, false); |
212 | TYPE_CANONICAL (array) = TYPE_CANONICAL (t); |
213 | if (!fld->pset.add (k: array)) |
214 | add_tree_to_fld_list (t: array, fld); |
215 | } |
216 | return array; |
217 | } |
218 | |
219 | /* Return CTX after removal of contexts that are not relevant */ |
220 | |
221 | static tree |
222 | fld_decl_context (tree ctx) |
223 | { |
224 | /* Variably modified types are needed for tree_is_indexable to decide |
225 | whether the type needs to go to local or global section. |
226 | This code is semi-broken but for now it is easiest to keep contexts |
227 | as expected. */ |
228 | if (ctx && TYPE_P (ctx) |
229 | && !variably_modified_type_p (ctx, NULL_TREE)) |
230 | { |
231 | while (ctx && TYPE_P (ctx)) |
232 | ctx = TYPE_CONTEXT (ctx); |
233 | } |
234 | return ctx; |
235 | } |
236 | |
237 | /* For T being aggregate type try to turn it into a incomplete variant. |
238 | Return T if no simplification is possible. */ |
239 | |
240 | static tree |
241 | fld_incomplete_type_of (tree t, class free_lang_data_d *fld) |
242 | { |
243 | if (!t) |
244 | return NULL; |
245 | if (POINTER_TYPE_P (t)) |
246 | { |
247 | tree t2 = fld_incomplete_type_of (TREE_TYPE (t), fld); |
248 | if (t2 != TREE_TYPE (t)) |
249 | { |
250 | tree first; |
251 | if (TREE_CODE (t) == POINTER_TYPE) |
252 | first = build_pointer_type_for_mode (t2, TYPE_MODE (t), |
253 | TYPE_REF_CAN_ALIAS_ALL (t)); |
254 | else |
255 | first = build_reference_type_for_mode (t2, TYPE_MODE (t), |
256 | TYPE_REF_CAN_ALIAS_ALL (t)); |
257 | gcc_assert (TYPE_CANONICAL (t2) != t2 |
258 | && TYPE_CANONICAL (t2) == TYPE_CANONICAL (TREE_TYPE (t))); |
259 | if (!fld->pset.add (k: first)) |
260 | add_tree_to_fld_list (t: first, fld); |
261 | return fld_type_variant (first, t, fld); |
262 | } |
263 | return t; |
264 | } |
265 | if (TREE_CODE (t) == ARRAY_TYPE) |
266 | return fld_process_array_type (t, |
267 | t2: fld_incomplete_type_of (TREE_TYPE (t), fld), |
268 | map: fld_incomplete_types, fld); |
269 | if ((!RECORD_OR_UNION_TYPE_P (t) && TREE_CODE (t) != ENUMERAL_TYPE) |
270 | || !COMPLETE_TYPE_P (t)) |
271 | return t; |
272 | if (TYPE_MAIN_VARIANT (t) == t) |
273 | { |
274 | bool existed; |
275 | tree © |
276 | = fld_incomplete_types->get_or_insert (k: t, existed: &existed); |
277 | |
278 | if (!existed) |
279 | { |
280 | copy = build_distinct_type_copy (t); |
281 | |
282 | /* It is possible that type was not seen by free_lang_data yet. */ |
283 | if (!fld->pset.add (k: copy)) |
284 | add_tree_to_fld_list (t: copy, fld); |
285 | TYPE_SIZE (copy) = NULL; |
286 | TYPE_USER_ALIGN (copy) = 0; |
287 | TYPE_SIZE_UNIT (copy) = NULL; |
288 | TYPE_CANONICAL (copy) = TYPE_CANONICAL (t); |
289 | TREE_ADDRESSABLE (copy) = 0; |
290 | if (AGGREGATE_TYPE_P (t)) |
291 | { |
292 | SET_TYPE_MODE (copy, VOIDmode); |
293 | SET_TYPE_ALIGN (copy, BITS_PER_UNIT); |
294 | TYPE_TYPELESS_STORAGE (copy) = 0; |
295 | TYPE_FIELDS (copy) = NULL; |
296 | TYPE_BINFO (copy) = NULL; |
297 | TYPE_FINAL_P (copy) = 0; |
298 | TYPE_EMPTY_P (copy) = 0; |
299 | } |
300 | else |
301 | { |
302 | TYPE_VALUES (copy) = NULL; |
303 | ENUM_IS_OPAQUE (copy) = 0; |
304 | ENUM_IS_SCOPED (copy) = 0; |
305 | } |
306 | |
307 | /* Build copy of TYPE_DECL in TYPE_NAME if necessary. |
308 | This is needed for ODR violation warnings to come out right (we |
309 | want duplicate TYPE_DECLs whenever the type is duplicated because |
310 | of ODR violation. Because lang data in the TYPE_DECL may not |
311 | have been freed yet, rebuild it from scratch and copy relevant |
312 | fields. */ |
313 | TYPE_NAME (copy) = fld_simplified_type_name (type: copy); |
314 | tree name = TYPE_NAME (copy); |
315 | |
316 | if (name && TREE_CODE (name) == TYPE_DECL) |
317 | { |
318 | gcc_checking_assert (TREE_TYPE (name) == t); |
319 | tree name2 = build_decl (DECL_SOURCE_LOCATION (name), TYPE_DECL, |
320 | DECL_NAME (name), copy); |
321 | if (DECL_ASSEMBLER_NAME_SET_P (name)) |
322 | SET_DECL_ASSEMBLER_NAME (name2, DECL_ASSEMBLER_NAME (name)); |
323 | SET_DECL_ALIGN (name2, 0); |
324 | DECL_CONTEXT (name2) = fld_decl_context |
325 | (DECL_CONTEXT (name)); |
326 | TYPE_NAME (copy) = name2; |
327 | } |
328 | } |
329 | return copy; |
330 | } |
331 | return (fld_type_variant |
332 | (first: fld_incomplete_type_of (TYPE_MAIN_VARIANT (t), fld), t, fld)); |
333 | } |
334 | |
335 | /* Simplify type T for scenarios where we do not need complete pointer |
336 | types. */ |
337 | |
338 | static tree |
339 | fld_simplified_type (tree t, class free_lang_data_d *fld) |
340 | { |
341 | if (!t) |
342 | return t; |
343 | if (POINTER_TYPE_P (t)) |
344 | return fld_incomplete_type_of (t, fld); |
345 | /* FIXME: This triggers verification error, see PR88140. */ |
346 | #if 0 |
347 | if (TREE_CODE (t) == ARRAY_TYPE) |
348 | return fld_process_array_type (t, fld_simplified_type (TREE_TYPE (t), fld), |
349 | fld_simplified_types, fld); |
350 | #endif |
351 | return t; |
352 | } |
353 | |
354 | /* Reset the expression *EXPR_P, a size or position. |
355 | |
356 | ??? We could reset all non-constant sizes or positions. But it's cheap |
357 | enough to not do so and refrain from adding workarounds to dwarf2out.cc. |
358 | |
359 | We need to reset self-referential sizes or positions because they cannot |
360 | be gimplified and thus can contain a CALL_EXPR after the gimplification |
361 | is finished, which will run afoul of LTO streaming. And they need to be |
362 | reset to something essentially dummy but not constant, so as to preserve |
363 | the properties of the object they are attached to. */ |
364 | |
365 | static inline void |
366 | free_lang_data_in_one_sizepos (tree *expr_p) |
367 | { |
368 | tree expr = *expr_p; |
369 | if (CONTAINS_PLACEHOLDER_P (expr)) |
370 | *expr_p = build0 (PLACEHOLDER_EXPR, TREE_TYPE (expr)); |
371 | } |
372 | |
373 | |
374 | /* Reset all the fields in a binfo node BINFO. We only keep |
375 | BINFO_VTABLE, which is used by gimple_fold_obj_type_ref. */ |
376 | |
377 | static void |
378 | free_lang_data_in_binfo (tree binfo) |
379 | { |
380 | unsigned i; |
381 | tree t; |
382 | |
383 | gcc_assert (TREE_CODE (binfo) == TREE_BINFO); |
384 | |
385 | BINFO_VIRTUALS (binfo) = NULL_TREE; |
386 | BINFO_BASE_ACCESSES (binfo) = NULL; |
387 | BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE; |
388 | BINFO_SUBVTT_INDEX (binfo) = NULL_TREE; |
389 | BINFO_VPTR_FIELD (binfo) = NULL_TREE; |
390 | TREE_PUBLIC (binfo) = 0; |
391 | |
392 | FOR_EACH_VEC_ELT (*BINFO_BASE_BINFOS (binfo), i, t) |
393 | free_lang_data_in_binfo (binfo: t); |
394 | } |
395 | |
396 | |
397 | /* Reset all language specific information still present in TYPE. */ |
398 | |
399 | static void |
400 | free_lang_data_in_type (tree type, class free_lang_data_d *fld) |
401 | { |
402 | gcc_assert (TYPE_P (type)); |
403 | |
404 | /* Give the FE a chance to remove its own data first. */ |
405 | lang_hooks.free_lang_data (type); |
406 | |
407 | TREE_LANG_FLAG_0 (type) = 0; |
408 | TREE_LANG_FLAG_1 (type) = 0; |
409 | TREE_LANG_FLAG_2 (type) = 0; |
410 | TREE_LANG_FLAG_3 (type) = 0; |
411 | TREE_LANG_FLAG_4 (type) = 0; |
412 | TREE_LANG_FLAG_5 (type) = 0; |
413 | TREE_LANG_FLAG_6 (type) = 0; |
414 | |
415 | TYPE_NEEDS_CONSTRUCTING (type) = 0; |
416 | |
417 | /* Purge non-marked variants from the variants chain, so that they |
418 | don't reappear in the IL after free_lang_data. */ |
419 | while (TYPE_NEXT_VARIANT (type) |
420 | && !fld->pset.contains (TYPE_NEXT_VARIANT (type))) |
421 | { |
422 | tree t = TYPE_NEXT_VARIANT (type); |
423 | TYPE_NEXT_VARIANT (type) = TYPE_NEXT_VARIANT (t); |
424 | /* Turn the removed types into distinct types. */ |
425 | TYPE_MAIN_VARIANT (t) = t; |
426 | TYPE_NEXT_VARIANT (t) = NULL_TREE; |
427 | } |
428 | |
429 | if (TREE_CODE (type) == FUNCTION_TYPE) |
430 | { |
431 | TREE_TYPE (type) = fld_simplified_type (TREE_TYPE (type), fld); |
432 | /* Remove the const and volatile qualifiers from arguments. The |
433 | C++ front end removes them, but the C front end does not, |
434 | leading to false ODR violation errors when merging two |
435 | instances of the same function signature compiled by |
436 | different front ends. */ |
437 | for (tree p = TYPE_ARG_TYPES (type); p; p = TREE_CHAIN (p)) |
438 | { |
439 | TREE_VALUE (p) = fld_simplified_type (TREE_VALUE (p), fld); |
440 | tree arg_type = TREE_VALUE (p); |
441 | |
442 | if (TYPE_READONLY (arg_type) || TYPE_VOLATILE (arg_type)) |
443 | { |
444 | int quals = TYPE_QUALS (arg_type) |
445 | & ~TYPE_QUAL_CONST |
446 | & ~TYPE_QUAL_VOLATILE; |
447 | TREE_VALUE (p) = build_qualified_type (arg_type, quals); |
448 | if (!fld->pset.add (TREE_VALUE (p))) |
449 | free_lang_data_in_type (TREE_VALUE (p), fld); |
450 | } |
451 | /* C++ FE uses TREE_PURPOSE to store initial values. */ |
452 | TREE_PURPOSE (p) = NULL; |
453 | } |
454 | } |
455 | else if (TREE_CODE (type) == METHOD_TYPE) |
456 | { |
457 | TREE_TYPE (type) = fld_simplified_type (TREE_TYPE (type), fld); |
458 | for (tree p = TYPE_ARG_TYPES (type); p; p = TREE_CHAIN (p)) |
459 | { |
460 | /* C++ FE uses TREE_PURPOSE to store initial values. */ |
461 | TREE_VALUE (p) = fld_simplified_type (TREE_VALUE (p), fld); |
462 | TREE_PURPOSE (p) = NULL; |
463 | } |
464 | } |
465 | else if (RECORD_OR_UNION_TYPE_P (type)) |
466 | { |
467 | /* Remove members that are not FIELD_DECLs from the field list |
468 | of an aggregate. These occur in C++. */ |
469 | for (tree *prev = &TYPE_FIELDS (type), member; (member = *prev);) |
470 | if (TREE_CODE (member) == FIELD_DECL) |
471 | prev = &DECL_CHAIN (member); |
472 | else |
473 | *prev = DECL_CHAIN (member); |
474 | |
475 | TYPE_VFIELD (type) = NULL_TREE; |
476 | |
477 | if (TYPE_BINFO (type)) |
478 | { |
479 | free_lang_data_in_binfo (TYPE_BINFO (type)); |
480 | /* We need to preserve link to bases and virtual table for all |
481 | polymorphic types to make devirtualization machinery working. */ |
482 | if (!BINFO_VTABLE (TYPE_BINFO (type))) |
483 | TYPE_BINFO (type) = NULL; |
484 | } |
485 | } |
486 | else if (INTEGRAL_TYPE_P (type) |
487 | || SCALAR_FLOAT_TYPE_P (type) |
488 | || FIXED_POINT_TYPE_P (type)) |
489 | { |
490 | if (TREE_CODE (type) == ENUMERAL_TYPE) |
491 | { |
492 | ENUM_IS_OPAQUE (type) = 0; |
493 | ENUM_IS_SCOPED (type) = 0; |
494 | /* Type values are used only for C++ ODR checking. Drop them |
495 | for all type variants and non-ODR types. |
496 | For ODR types the data is freed in free_odr_warning_data. */ |
497 | if (!TYPE_VALUES (type)) |
498 | ; |
499 | else if (TYPE_MAIN_VARIANT (type) != type |
500 | || !type_with_linkage_p (t: type) |
501 | || type_in_anonymous_namespace_p (t: type)) |
502 | TYPE_VALUES (type) = NULL; |
503 | else |
504 | register_odr_enum (type); |
505 | } |
506 | free_lang_data_in_one_sizepos (expr_p: &TYPE_MIN_VALUE (type)); |
507 | free_lang_data_in_one_sizepos (expr_p: &TYPE_MAX_VALUE (type)); |
508 | } |
509 | |
510 | TYPE_LANG_SLOT_1 (type) = NULL_TREE; |
511 | |
512 | free_lang_data_in_one_sizepos (expr_p: &TYPE_SIZE (type)); |
513 | free_lang_data_in_one_sizepos (expr_p: &TYPE_SIZE_UNIT (type)); |
514 | |
515 | if (TYPE_CONTEXT (type) |
516 | && TREE_CODE (TYPE_CONTEXT (type)) == BLOCK) |
517 | { |
518 | tree ctx = TYPE_CONTEXT (type); |
519 | do |
520 | { |
521 | ctx = BLOCK_SUPERCONTEXT (ctx); |
522 | } |
523 | while (ctx && TREE_CODE (ctx) == BLOCK); |
524 | TYPE_CONTEXT (type) = ctx; |
525 | } |
526 | |
527 | TYPE_STUB_DECL (type) = NULL; |
528 | TYPE_NAME (type) = fld_simplified_type_name (type); |
529 | } |
530 | |
531 | /* Reset all language specific information still present in symbol |
532 | DECL. */ |
533 | |
534 | static void |
535 | free_lang_data_in_decl (tree decl, class free_lang_data_d *fld) |
536 | { |
537 | gcc_assert (DECL_P (decl)); |
538 | |
539 | /* Give the FE a chance to remove its own data first. */ |
540 | lang_hooks.free_lang_data (decl); |
541 | |
542 | TREE_LANG_FLAG_0 (decl) = 0; |
543 | TREE_LANG_FLAG_1 (decl) = 0; |
544 | TREE_LANG_FLAG_2 (decl) = 0; |
545 | TREE_LANG_FLAG_3 (decl) = 0; |
546 | TREE_LANG_FLAG_4 (decl) = 0; |
547 | TREE_LANG_FLAG_5 (decl) = 0; |
548 | TREE_LANG_FLAG_6 (decl) = 0; |
549 | |
550 | free_lang_data_in_one_sizepos (expr_p: &DECL_SIZE (decl)); |
551 | free_lang_data_in_one_sizepos (expr_p: &DECL_SIZE_UNIT (decl)); |
552 | if (TREE_CODE (decl) == FIELD_DECL) |
553 | { |
554 | DECL_FCONTEXT (decl) = NULL; |
555 | free_lang_data_in_one_sizepos (expr_p: &DECL_FIELD_OFFSET (decl)); |
556 | if (TREE_CODE (DECL_CONTEXT (decl)) == QUAL_UNION_TYPE) |
557 | DECL_QUALIFIER (decl) = NULL_TREE; |
558 | } |
559 | |
560 | if (TREE_CODE (decl) == FUNCTION_DECL) |
561 | { |
562 | struct cgraph_node *node; |
563 | /* Frontends do not set TREE_ADDRESSABLE on public variables even though |
564 | the address may be taken in other unit, so this flag has no practical |
565 | use for middle-end. |
566 | |
567 | It would make more sense if frontends set TREE_ADDRESSABLE to 0 only |
568 | for public objects that indeed cannot be adressed, but it is not |
569 | the case. Set the flag to true so we do not get merge failures for |
570 | i.e. virtual tables between units that take address of it and |
571 | units that don't. */ |
572 | if (TREE_PUBLIC (decl)) |
573 | TREE_ADDRESSABLE (decl) = true; |
574 | TREE_TYPE (decl) = fld_simplified_type (TREE_TYPE (decl), fld); |
575 | if (!(node = cgraph_node::get (decl)) |
576 | || (!node->definition && !node->clones)) |
577 | { |
578 | if (node && !node->declare_variant_alt) |
579 | node->release_body (); |
580 | else |
581 | { |
582 | release_function_body (decl); |
583 | DECL_ARGUMENTS (decl) = NULL; |
584 | DECL_RESULT (decl) = NULL; |
585 | DECL_INITIAL (decl) = error_mark_node; |
586 | } |
587 | } |
588 | if (gimple_has_body_p (decl) || (node && node->thunk)) |
589 | { |
590 | tree t; |
591 | |
592 | /* If DECL has a gimple body, then the context for its |
593 | arguments must be DECL. Otherwise, it doesn't really |
594 | matter, as we will not be emitting any code for DECL. In |
595 | general, there may be other instances of DECL created by |
596 | the front end and since PARM_DECLs are generally shared, |
597 | their DECL_CONTEXT changes as the replicas of DECL are |
598 | created. The only time where DECL_CONTEXT is important |
599 | is for the FUNCTION_DECLs that have a gimple body (since |
600 | the PARM_DECL will be used in the function's body). */ |
601 | for (t = DECL_ARGUMENTS (decl); t; t = TREE_CHAIN (t)) |
602 | DECL_CONTEXT (t) = decl; |
603 | if (!DECL_FUNCTION_SPECIFIC_TARGET (decl)) |
604 | DECL_FUNCTION_SPECIFIC_TARGET (decl) |
605 | = target_option_default_node; |
606 | if (!DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl)) |
607 | DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl) |
608 | = optimization_default_node; |
609 | } |
610 | |
611 | /* DECL_SAVED_TREE holds the GENERIC representation for DECL. |
612 | At this point, it is not needed anymore. */ |
613 | DECL_SAVED_TREE (decl) = NULL_TREE; |
614 | |
615 | /* Clear the abstract origin if it refers to a method. |
616 | Otherwise dwarf2out.cc will ICE as we splice functions out of |
617 | TYPE_FIELDS and thus the origin will not be output |
618 | correctly. */ |
619 | if (DECL_ABSTRACT_ORIGIN (decl) |
620 | && DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl)) |
621 | && RECORD_OR_UNION_TYPE_P |
622 | (DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl)))) |
623 | DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE; |
624 | |
625 | DECL_VINDEX (decl) = NULL_TREE; |
626 | } |
627 | else if (VAR_P (decl)) |
628 | { |
629 | /* See comment above why we set the flag for functions. */ |
630 | if (TREE_PUBLIC (decl)) |
631 | TREE_ADDRESSABLE (decl) = true; |
632 | if ((DECL_EXTERNAL (decl) |
633 | && (!TREE_STATIC (decl) || !TREE_READONLY (decl))) |
634 | || (decl_function_context (decl) && !TREE_STATIC (decl))) |
635 | DECL_INITIAL (decl) = NULL_TREE; |
636 | } |
637 | else if (TREE_CODE (decl) == TYPE_DECL) |
638 | { |
639 | DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; |
640 | DECL_VISIBILITY_SPECIFIED (decl) = 0; |
641 | TREE_PUBLIC (decl) = 0; |
642 | TREE_PRIVATE (decl) = 0; |
643 | DECL_ARTIFICIAL (decl) = 0; |
644 | TYPE_DECL_SUPPRESS_DEBUG (decl) = 0; |
645 | DECL_INITIAL (decl) = NULL_TREE; |
646 | DECL_ORIGINAL_TYPE (decl) = NULL_TREE; |
647 | DECL_MODE (decl) = VOIDmode; |
648 | SET_DECL_ALIGN (decl, 0); |
649 | /* TREE_TYPE is cleared at WPA time in free_odr_warning_data. */ |
650 | } |
651 | else if (TREE_CODE (decl) == FIELD_DECL) |
652 | { |
653 | TREE_TYPE (decl) = fld_simplified_type (TREE_TYPE (decl), fld); |
654 | DECL_INITIAL (decl) = NULL_TREE; |
655 | } |
656 | else if (TREE_CODE (decl) == TRANSLATION_UNIT_DECL |
657 | && DECL_INITIAL (decl) |
658 | && TREE_CODE (DECL_INITIAL (decl)) == BLOCK) |
659 | { |
660 | /* Strip builtins from the translation-unit BLOCK. We still have targets |
661 | without builtin_decl_explicit support and also builtins are shared |
662 | nodes and thus we can't use TREE_CHAIN in multiple lists. */ |
663 | tree *nextp = &BLOCK_VARS (DECL_INITIAL (decl)); |
664 | while (*nextp) |
665 | { |
666 | tree var = *nextp; |
667 | if (TREE_CODE (var) == FUNCTION_DECL |
668 | && fndecl_built_in_p (node: var)) |
669 | *nextp = TREE_CHAIN (var); |
670 | else |
671 | nextp = &TREE_CHAIN (var); |
672 | } |
673 | } |
674 | /* We need to keep field decls associated with their trees. Otherwise tree |
675 | merging may merge some fields and keep others disjoint which in turn will |
676 | not do well with TREE_CHAIN pointers linking them. |
677 | |
678 | Also do not drop containing types for virtual methods and tables because |
679 | these are needed by devirtualization. |
680 | C++ destructors are special because C++ frontends sometimes produces |
681 | virtual destructor as an alias of non-virtual destructor. In |
682 | devirutalization code we always walk through aliases and we need |
683 | context to be preserved too. See PR89335 */ |
684 | if (TREE_CODE (decl) != FIELD_DECL |
685 | && ((TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) |
686 | || (!DECL_VIRTUAL_P (decl) |
687 | && (TREE_CODE (decl) != FUNCTION_DECL |
688 | || !DECL_CXX_DESTRUCTOR_P (decl))))) |
689 | DECL_CONTEXT (decl) = fld_decl_context (DECL_CONTEXT (decl)); |
690 | } |
691 | |
692 | |
693 | /* Operand callback helper for free_lang_data_in_node. *TP is the |
694 | subtree operand being considered. */ |
695 | |
696 | static tree |
697 | find_decls_types_r (tree *tp, int *ws, void *data) |
698 | { |
699 | tree t = *tp; |
700 | class free_lang_data_d *fld = (class free_lang_data_d *) data; |
701 | |
702 | if (TREE_CODE (t) == TREE_LIST) |
703 | return NULL_TREE; |
704 | |
705 | /* Language specific nodes will be removed, so there is no need |
706 | to gather anything under them. */ |
707 | if (is_lang_specific (t)) |
708 | { |
709 | *ws = 0; |
710 | return NULL_TREE; |
711 | } |
712 | |
713 | if (DECL_P (t)) |
714 | { |
715 | /* Note that walk_tree does not traverse every possible field in |
716 | decls, so we have to do our own traversals here. */ |
717 | add_tree_to_fld_list (t, fld); |
718 | |
719 | fld_worklist_push (DECL_NAME (t), fld); |
720 | fld_worklist_push (DECL_CONTEXT (t), fld); |
721 | fld_worklist_push (DECL_SIZE (t), fld); |
722 | fld_worklist_push (DECL_SIZE_UNIT (t), fld); |
723 | |
724 | /* We are going to remove everything under DECL_INITIAL for |
725 | TYPE_DECLs. No point walking them. */ |
726 | if (TREE_CODE (t) != TYPE_DECL) |
727 | fld_worklist_push (DECL_INITIAL (t), fld); |
728 | |
729 | fld_worklist_push (DECL_ATTRIBUTES (t), fld); |
730 | fld_worklist_push (DECL_ABSTRACT_ORIGIN (t), fld); |
731 | |
732 | if (TREE_CODE (t) == FUNCTION_DECL) |
733 | { |
734 | fld_worklist_push (DECL_ARGUMENTS (t), fld); |
735 | fld_worklist_push (DECL_RESULT (t), fld); |
736 | } |
737 | else if (TREE_CODE (t) == FIELD_DECL) |
738 | { |
739 | fld_worklist_push (DECL_FIELD_OFFSET (t), fld); |
740 | fld_worklist_push (DECL_BIT_FIELD_TYPE (t), fld); |
741 | fld_worklist_push (DECL_FIELD_BIT_OFFSET (t), fld); |
742 | fld_worklist_push (DECL_FCONTEXT (t), fld); |
743 | } |
744 | |
745 | if ((VAR_P (t) || TREE_CODE (t) == PARM_DECL) |
746 | && DECL_HAS_VALUE_EXPR_P (t)) |
747 | fld_worklist_push (DECL_VALUE_EXPR (t), fld); |
748 | |
749 | if (TREE_CODE (t) != FIELD_DECL |
750 | && TREE_CODE (t) != TYPE_DECL) |
751 | fld_worklist_push (TREE_CHAIN (t), fld); |
752 | *ws = 0; |
753 | } |
754 | else if (TYPE_P (t)) |
755 | { |
756 | /* Note that walk_tree does not traverse every possible field in |
757 | types, so we have to do our own traversals here. */ |
758 | add_tree_to_fld_list (t, fld); |
759 | |
760 | if (!RECORD_OR_UNION_TYPE_P (t)) |
761 | fld_worklist_push (TYPE_CACHED_VALUES (t), fld); |
762 | fld_worklist_push (TYPE_SIZE (t), fld); |
763 | fld_worklist_push (TYPE_SIZE_UNIT (t), fld); |
764 | fld_worklist_push (TYPE_ATTRIBUTES (t), fld); |
765 | fld_worklist_push (TYPE_POINTER_TO (t), fld); |
766 | fld_worklist_push (TYPE_REFERENCE_TO (t), fld); |
767 | fld_worklist_push (TYPE_NAME (t), fld); |
768 | /* While we do not stream TYPE_POINTER_TO and TYPE_REFERENCE_TO |
769 | lists, we may look types up in these lists and use them while |
770 | optimizing the function body. Thus we need to free lang data |
771 | in them. */ |
772 | if (TREE_CODE (t) == POINTER_TYPE) |
773 | fld_worklist_push (TYPE_NEXT_PTR_TO (t), fld); |
774 | if (TREE_CODE (t) == REFERENCE_TYPE) |
775 | fld_worklist_push (TYPE_NEXT_REF_TO (t), fld); |
776 | if (!POINTER_TYPE_P (t)) |
777 | fld_worklist_push (TYPE_MIN_VALUE_RAW (t), fld); |
778 | /* TYPE_MAX_VALUE_RAW is TYPE_BINFO for record types. */ |
779 | if (!RECORD_OR_UNION_TYPE_P (t)) |
780 | fld_worklist_push (TYPE_MAX_VALUE_RAW (t), fld); |
781 | fld_worklist_push (TYPE_MAIN_VARIANT (t), fld); |
782 | /* Do not walk TYPE_NEXT_VARIANT. We do not stream it and thus |
783 | do not and want not to reach unused variants this way. */ |
784 | if (TYPE_CONTEXT (t)) |
785 | { |
786 | tree ctx = TYPE_CONTEXT (t); |
787 | /* We adjust BLOCK TYPE_CONTEXTs to the innermost non-BLOCK one. |
788 | So push that instead. */ |
789 | while (ctx && TREE_CODE (ctx) == BLOCK) |
790 | ctx = BLOCK_SUPERCONTEXT (ctx); |
791 | fld_worklist_push (t: ctx, fld); |
792 | } |
793 | fld_worklist_push (TYPE_CANONICAL (t), fld); |
794 | |
795 | if (RECORD_OR_UNION_TYPE_P (t) && TYPE_BINFO (t)) |
796 | { |
797 | unsigned i; |
798 | tree tem; |
799 | FOR_EACH_VEC_ELT (*BINFO_BASE_BINFOS (TYPE_BINFO (t)), i, tem) |
800 | fld_worklist_push (TREE_TYPE (tem), fld); |
801 | fld_worklist_push (BINFO_TYPE (TYPE_BINFO (t)), fld); |
802 | fld_worklist_push (BINFO_VTABLE (TYPE_BINFO (t)), fld); |
803 | } |
804 | if (RECORD_OR_UNION_TYPE_P (t)) |
805 | { |
806 | tree tem; |
807 | /* Push all TYPE_FIELDS - there can be interleaving interesting |
808 | and non-interesting things. */ |
809 | tem = TYPE_FIELDS (t); |
810 | while (tem) |
811 | { |
812 | if (TREE_CODE (tem) == FIELD_DECL) |
813 | fld_worklist_push (t: tem, fld); |
814 | tem = TREE_CHAIN (tem); |
815 | } |
816 | } |
817 | if (FUNC_OR_METHOD_TYPE_P (t)) |
818 | fld_worklist_push (TYPE_METHOD_BASETYPE (t), fld); |
819 | |
820 | fld_worklist_push (TYPE_STUB_DECL (t), fld); |
821 | *ws = 0; |
822 | } |
823 | else if (TREE_CODE (t) == BLOCK) |
824 | { |
825 | for (tree *tem = &BLOCK_VARS (t); *tem; ) |
826 | { |
827 | if (TREE_CODE (*tem) != LABEL_DECL |
828 | && (TREE_CODE (*tem) != VAR_DECL |
829 | || !auto_var_in_fn_p (*tem, DECL_CONTEXT (*tem)))) |
830 | { |
831 | gcc_assert (TREE_CODE (*tem) != RESULT_DECL |
832 | && TREE_CODE (*tem) != PARM_DECL); |
833 | *tem = TREE_CHAIN (*tem); |
834 | } |
835 | else |
836 | { |
837 | fld_worklist_push (t: *tem, fld); |
838 | tem = &TREE_CHAIN (*tem); |
839 | } |
840 | } |
841 | for (tree tem = BLOCK_SUBBLOCKS (t); tem; tem = BLOCK_CHAIN (tem)) |
842 | fld_worklist_push (t: tem, fld); |
843 | fld_worklist_push (BLOCK_ABSTRACT_ORIGIN (t), fld); |
844 | } |
845 | |
846 | if (TREE_CODE (t) != IDENTIFIER_NODE |
847 | && CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED)) |
848 | fld_worklist_push (TREE_TYPE (t), fld); |
849 | |
850 | return NULL_TREE; |
851 | } |
852 | |
853 | |
854 | /* Find decls and types in T. */ |
855 | |
856 | static void |
857 | find_decls_types (tree t, class free_lang_data_d *fld) |
858 | { |
859 | while (1) |
860 | { |
861 | if (!fld->pset.contains (k: t)) |
862 | walk_tree (&t, find_decls_types_r, fld, &fld->pset); |
863 | if (fld->worklist.is_empty ()) |
864 | break; |
865 | t = fld->worklist.pop (); |
866 | } |
867 | } |
868 | |
869 | /* Translate all the types in LIST with the corresponding runtime |
870 | types. */ |
871 | |
872 | static tree |
873 | get_eh_types_for_runtime (tree list) |
874 | { |
875 | tree head, prev; |
876 | |
877 | if (list == NULL_TREE) |
878 | return NULL_TREE; |
879 | |
880 | head = build_tree_list (0, lookup_type_for_runtime (TREE_VALUE (list))); |
881 | prev = head; |
882 | list = TREE_CHAIN (list); |
883 | while (list) |
884 | { |
885 | tree n = build_tree_list (0, lookup_type_for_runtime (TREE_VALUE (list))); |
886 | TREE_CHAIN (prev) = n; |
887 | prev = TREE_CHAIN (prev); |
888 | list = TREE_CHAIN (list); |
889 | } |
890 | |
891 | return head; |
892 | } |
893 | |
894 | |
895 | /* Find decls and types referenced in EH region R and store them in |
896 | FLD->DECLS and FLD->TYPES. */ |
897 | |
898 | static void |
899 | find_decls_types_in_eh_region (eh_region r, class free_lang_data_d *fld) |
900 | { |
901 | switch (r->type) |
902 | { |
903 | case ERT_CLEANUP: |
904 | break; |
905 | |
906 | case ERT_TRY: |
907 | { |
908 | eh_catch c; |
909 | |
910 | /* The types referenced in each catch must first be changed to the |
911 | EH types used at runtime. This removes references to FE types |
912 | in the region. */ |
913 | for (c = r->u.eh_try.first_catch; c ; c = c->next_catch) |
914 | { |
915 | c->type_list = get_eh_types_for_runtime (list: c->type_list); |
916 | walk_tree (&c->type_list, find_decls_types_r, fld, &fld->pset); |
917 | } |
918 | } |
919 | break; |
920 | |
921 | case ERT_ALLOWED_EXCEPTIONS: |
922 | r->u.allowed.type_list |
923 | = get_eh_types_for_runtime (list: r->u.allowed.type_list); |
924 | walk_tree (&r->u.allowed.type_list, find_decls_types_r, fld, &fld->pset); |
925 | break; |
926 | |
927 | case ERT_MUST_NOT_THROW: |
928 | walk_tree (&r->u.must_not_throw.failure_decl, |
929 | find_decls_types_r, fld, &fld->pset); |
930 | break; |
931 | } |
932 | } |
933 | |
934 | |
935 | /* Find decls and types referenced in cgraph node N and store them in |
936 | FLD->DECLS and FLD->TYPES. Unlike pass_referenced_vars, this will |
937 | look for *every* kind of DECL and TYPE node reachable from N, |
938 | including those embedded inside types and decls (i.e,, TYPE_DECLs, |
939 | NAMESPACE_DECLs, etc). */ |
940 | |
941 | static void |
942 | find_decls_types_in_node (struct cgraph_node *n, class free_lang_data_d *fld) |
943 | { |
944 | basic_block bb; |
945 | struct function *fn; |
946 | unsigned ix; |
947 | tree t; |
948 | |
949 | find_decls_types (t: n->decl, fld); |
950 | |
951 | if (!gimple_has_body_p (n->decl)) |
952 | return; |
953 | |
954 | gcc_assert (current_function_decl == NULL_TREE && cfun == NULL); |
955 | |
956 | fn = DECL_STRUCT_FUNCTION (n->decl); |
957 | |
958 | /* Traverse locals. */ |
959 | FOR_EACH_LOCAL_DECL (fn, ix, t) |
960 | find_decls_types (t, fld); |
961 | |
962 | /* Traverse EH regions in FN. */ |
963 | { |
964 | eh_region r; |
965 | FOR_ALL_EH_REGION_FN (r, fn) |
966 | find_decls_types_in_eh_region (r, fld); |
967 | } |
968 | |
969 | /* Traverse every statement in FN. */ |
970 | FOR_EACH_BB_FN (bb, fn) |
971 | { |
972 | gphi_iterator psi; |
973 | gimple_stmt_iterator si; |
974 | unsigned i; |
975 | |
976 | for (psi = gsi_start_phis (bb); !gsi_end_p (i: psi); gsi_next (i: &psi)) |
977 | { |
978 | gphi *phi = psi.phi (); |
979 | |
980 | for (i = 0; i < gimple_phi_num_args (gs: phi); i++) |
981 | { |
982 | tree *arg_p = gimple_phi_arg_def_ptr (phi, index: i); |
983 | find_decls_types (t: *arg_p, fld); |
984 | } |
985 | } |
986 | |
987 | for (si = gsi_start_bb (bb); !gsi_end_p (i: si); gsi_next (i: &si)) |
988 | { |
989 | gimple *stmt = gsi_stmt (i: si); |
990 | |
991 | if (is_gimple_call (gs: stmt)) |
992 | find_decls_types (t: gimple_call_fntype (gs: stmt), fld); |
993 | |
994 | for (i = 0; i < gimple_num_ops (gs: stmt); i++) |
995 | { |
996 | tree arg = gimple_op (gs: stmt, i); |
997 | find_decls_types (t: arg, fld); |
998 | /* find_decls_types doesn't walk TREE_PURPOSE of TREE_LISTs, |
999 | which we need for asm stmts. */ |
1000 | if (arg |
1001 | && TREE_CODE (arg) == TREE_LIST |
1002 | && TREE_PURPOSE (arg) |
1003 | && gimple_code (g: stmt) == GIMPLE_ASM) |
1004 | find_decls_types (TREE_PURPOSE (arg), fld); |
1005 | } |
1006 | } |
1007 | } |
1008 | } |
1009 | |
1010 | |
1011 | /* Find decls and types referenced in varpool node N and store them in |
1012 | FLD->DECLS and FLD->TYPES. Unlike pass_referenced_vars, this will |
1013 | look for *every* kind of DECL and TYPE node reachable from N, |
1014 | including those embedded inside types and decls (i.e,, TYPE_DECLs, |
1015 | NAMESPACE_DECLs, etc). */ |
1016 | |
1017 | static void |
1018 | find_decls_types_in_var (varpool_node *v, class free_lang_data_d *fld) |
1019 | { |
1020 | find_decls_types (t: v->decl, fld); |
1021 | } |
1022 | |
1023 | /* Free language specific information for every operand and expression |
1024 | in every node of the call graph. This process operates in three stages: |
1025 | |
1026 | 1- Every callgraph node and varpool node is traversed looking for |
1027 | decls and types embedded in them. This is a more exhaustive |
1028 | search than that done by find_referenced_vars, because it will |
1029 | also collect individual fields, decls embedded in types, etc. |
1030 | |
1031 | 2- All the decls found are sent to free_lang_data_in_decl. |
1032 | |
1033 | 3- All the types found are sent to free_lang_data_in_type. |
1034 | |
1035 | The ordering between decls and types is important because |
1036 | free_lang_data_in_decl sets assembler names, which includes |
1037 | mangling. So types cannot be freed up until assembler names have |
1038 | been set up. */ |
1039 | |
1040 | static void |
1041 | free_lang_data_in_cgraph (class free_lang_data_d *fld) |
1042 | { |
1043 | struct cgraph_node *n; |
1044 | varpool_node *v; |
1045 | tree t; |
1046 | unsigned i; |
1047 | alias_pair *p; |
1048 | |
1049 | /* Find decls and types in the body of every function in the callgraph. */ |
1050 | FOR_EACH_FUNCTION (n) |
1051 | find_decls_types_in_node (n, fld); |
1052 | |
1053 | FOR_EACH_VEC_SAFE_ELT (alias_pairs, i, p) |
1054 | find_decls_types (t: p->decl, fld); |
1055 | |
1056 | /* Find decls and types in every varpool symbol. */ |
1057 | FOR_EACH_VARIABLE (v) |
1058 | find_decls_types_in_var (v, fld); |
1059 | |
1060 | /* Set the assembler name on every decl found. We need to do this |
1061 | now because free_lang_data_in_decl will invalidate data needed |
1062 | for mangling. This breaks mangling on interdependent decls. */ |
1063 | FOR_EACH_VEC_ELT (fld->decls, i, t) |
1064 | assign_assembler_name_if_needed (t); |
1065 | |
1066 | /* Traverse every decl found freeing its language data. */ |
1067 | FOR_EACH_VEC_ELT (fld->decls, i, t) |
1068 | free_lang_data_in_decl (decl: t, fld); |
1069 | |
1070 | /* Traverse every type found freeing its language data. */ |
1071 | FOR_EACH_VEC_ELT (fld->types, i, t) |
1072 | free_lang_data_in_type (type: t, fld); |
1073 | } |
1074 | |
1075 | |
1076 | /* Free resources that are used by FE but are not needed once they are done. */ |
1077 | |
1078 | static unsigned |
1079 | free_lang_data (void) |
1080 | { |
1081 | unsigned i; |
1082 | class free_lang_data_d fld; |
1083 | |
1084 | /* If we are the LTO frontend we have freed lang-specific data already. */ |
1085 | if (in_lto_p |
1086 | || (!flag_generate_lto && !flag_generate_offload)) |
1087 | { |
1088 | /* Rebuild type inheritance graph even when not doing LTO to get |
1089 | consistent profile data. */ |
1090 | rebuild_type_inheritance_graph (); |
1091 | return 0; |
1092 | } |
1093 | |
1094 | fld_incomplete_types = new hash_map<tree, tree>; |
1095 | fld_simplified_types = new hash_map<tree, tree>; |
1096 | |
1097 | /* Provide a dummy TRANSLATION_UNIT_DECL if the FE failed to provide one. */ |
1098 | if (vec_safe_is_empty (v: all_translation_units)) |
1099 | build_translation_unit_decl (NULL_TREE); |
1100 | |
1101 | /* Allocate and assign alias sets to the standard integer types |
1102 | while the slots are still in the way the frontends generated them. */ |
1103 | for (i = 0; i < itk_none; ++i) |
1104 | if (integer_types[i]) |
1105 | TYPE_ALIAS_SET (integer_types[i]) = get_alias_set (integer_types[i]); |
1106 | |
1107 | /* Traverse the IL resetting language specific information for |
1108 | operands, expressions, etc. */ |
1109 | free_lang_data_in_cgraph (fld: &fld); |
1110 | |
1111 | /* Create gimple variants for common types. */ |
1112 | for (unsigned i = 0; i < ARRAY_SIZE (builtin_structptr_types); ++i) |
1113 | builtin_structptr_types[i].node = builtin_structptr_types[i].base; |
1114 | |
1115 | /* Reset some langhooks. Do not reset types_compatible_p, it may |
1116 | still be used indirectly via the get_alias_set langhook. */ |
1117 | lang_hooks.dwarf_name = lhd_dwarf_name; |
1118 | lang_hooks.decl_printable_name = gimple_decl_printable_name; |
1119 | lang_hooks.gimplify_expr = lhd_gimplify_expr; |
1120 | lang_hooks.overwrite_decl_assembler_name = lhd_overwrite_decl_assembler_name; |
1121 | lang_hooks.print_xnode = lhd_print_tree_nothing; |
1122 | lang_hooks.print_decl = lhd_print_tree_nothing; |
1123 | lang_hooks.print_type = lhd_print_tree_nothing; |
1124 | lang_hooks.print_identifier = lhd_print_tree_nothing; |
1125 | |
1126 | lang_hooks.tree_inlining.var_mod_type_p = hook_bool_tree_tree_false; |
1127 | |
1128 | if (flag_checking) |
1129 | { |
1130 | int i; |
1131 | tree t; |
1132 | |
1133 | FOR_EACH_VEC_ELT (fld.types, i, t) |
1134 | verify_type (t); |
1135 | } |
1136 | |
1137 | /* We do not want the default decl_assembler_name implementation, |
1138 | rather if we have fixed everything we want a wrapper around it |
1139 | asserting that all non-local symbols already got their assembler |
1140 | name and only produce assembler names for local symbols. Or rather |
1141 | make sure we never call decl_assembler_name on local symbols and |
1142 | devise a separate, middle-end private scheme for it. */ |
1143 | |
1144 | /* Reset diagnostic machinery. */ |
1145 | tree_diagnostics_defaults (context: global_dc); |
1146 | |
1147 | rebuild_type_inheritance_graph (); |
1148 | |
1149 | delete fld_incomplete_types; |
1150 | delete fld_simplified_types; |
1151 | |
1152 | return 0; |
1153 | } |
1154 | |
1155 | const pass_data pass_data_ipa_free_lang_data = |
1156 | { |
1157 | .type: SIMPLE_IPA_PASS, /* type */ |
1158 | .name: "*free_lang_data" , /* name */ |
1159 | .optinfo_flags: OPTGROUP_NONE, /* optinfo_flags */ |
1160 | .tv_id: TV_IPA_FREE_LANG_DATA, /* tv_id */ |
1161 | .properties_required: 0, /* properties_required */ |
1162 | .properties_provided: 0, /* properties_provided */ |
1163 | .properties_destroyed: 0, /* properties_destroyed */ |
1164 | .todo_flags_start: 0, /* todo_flags_start */ |
1165 | .todo_flags_finish: 0, /* todo_flags_finish */ |
1166 | }; |
1167 | |
1168 | class pass_ipa_free_lang_data : public simple_ipa_opt_pass |
1169 | { |
1170 | public: |
1171 | pass_ipa_free_lang_data (gcc::context *ctxt) |
1172 | : simple_ipa_opt_pass (pass_data_ipa_free_lang_data, ctxt) |
1173 | {} |
1174 | |
1175 | /* opt_pass methods: */ |
1176 | unsigned int execute (function *) final override { return free_lang_data (); } |
1177 | |
1178 | }; // class pass_ipa_free_lang_data |
1179 | |
1180 | } // anon namespace |
1181 | |
1182 | simple_ipa_opt_pass * |
1183 | make_pass_ipa_free_lang_data (gcc::context *ctxt) |
1184 | { |
1185 | return new pass_ipa_free_lang_data (ctxt); |
1186 | } |
1187 | |