1 | /* Language-dependent hooks for LTO. |
2 | Copyright (C) 2009-2023 Free Software Foundation, Inc. |
3 | Contributed by CodeSourcery, Inc. |
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" |
24 | #include "target.h" |
25 | #include "function.h" |
26 | #include "basic-block.h" |
27 | #include "tree.h" |
28 | #include "gimple.h" |
29 | #include "stringpool.h" |
30 | #include "diagnostic-core.h" |
31 | #include "stor-layout.h" |
32 | #include "langhooks.h" |
33 | #include "langhooks-def.h" |
34 | #include "debug.h" |
35 | #include "lto-tree.h" |
36 | #include "lto.h" |
37 | #include "lto-common.h" |
38 | #include "stringpool.h" |
39 | #include "attribs.h" |
40 | |
41 | /* LTO specific dumps. */ |
42 | int lto_link_dump_id, decl_merge_dump_id, partition_dump_id; |
43 | |
44 | static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *); |
45 | static tree handle_leaf_attribute (tree *, tree, tree, int, bool *); |
46 | static tree handle_const_attribute (tree *, tree, tree, int, bool *); |
47 | static tree handle_malloc_attribute (tree *, tree, tree, int, bool *); |
48 | static tree handle_pure_attribute (tree *, tree, tree, int, bool *); |
49 | static tree handle_novops_attribute (tree *, tree, tree, int, bool *); |
50 | static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *); |
51 | static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *); |
52 | static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *); |
53 | static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *); |
54 | static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *); |
55 | static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *); |
56 | static tree handle_patchable_function_entry_attribute (tree *, tree, tree, |
57 | int, bool *); |
58 | static tree ignore_attribute (tree *, tree, tree, int, bool *); |
59 | |
60 | static tree handle_format_attribute (tree *, tree, tree, int, bool *); |
61 | static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *); |
62 | static tree handle_format_arg_attribute (tree *, tree, tree, int, bool *); |
63 | |
64 | /* Helper to define attribute exclusions. */ |
65 | #define ATTR_EXCL(name, function, type, variable) \ |
66 | { name, function, type, variable } |
67 | |
68 | /* Define attributes that are mutually exclusive with one another. */ |
69 | static const struct attribute_spec::exclusions attr_noreturn_exclusions[] = |
70 | { |
71 | ATTR_EXCL ("noreturn" , true, true, true), |
72 | ATTR_EXCL ("alloc_align" , true, true, true), |
73 | ATTR_EXCL ("alloc_size" , true, true, true), |
74 | ATTR_EXCL ("const" , true, true, true), |
75 | ATTR_EXCL ("malloc" , true, true, true), |
76 | ATTR_EXCL ("pure" , true, true, true), |
77 | ATTR_EXCL ("returns_twice" , true, true, true), |
78 | ATTR_EXCL ("warn_unused_result" , true, true, true), |
79 | ATTR_EXCL (NULL, false, false, false), |
80 | }; |
81 | |
82 | static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] = |
83 | { |
84 | ATTR_EXCL ("noreturn" , true, true, true), |
85 | ATTR_EXCL (NULL, false, false, false), |
86 | }; |
87 | |
88 | static const struct attribute_spec::exclusions attr_const_pure_exclusions[] = |
89 | { |
90 | ATTR_EXCL ("const" , true, true, true), |
91 | ATTR_EXCL ("noreturn" , true, true, true), |
92 | ATTR_EXCL ("pure" , true, true, true), |
93 | ATTR_EXCL (NULL, false, false, false) |
94 | }; |
95 | |
96 | /* Table of machine-independent attributes supported in GIMPLE. */ |
97 | const struct attribute_spec lto_attribute_table[] = |
98 | { |
99 | /* { name, min_len, max_len, decl_req, type_req, fn_type_req, |
100 | affects_type_identity, handler, exclude } */ |
101 | { .name: "noreturn" , .min_length: 0, .max_length: 0, .decl_required: true, .type_required: false, .function_type_required: false, .affects_type_identity: false, |
102 | .handler: handle_noreturn_attribute, |
103 | .exclude: attr_noreturn_exclusions }, |
104 | { .name: "leaf" , .min_length: 0, .max_length: 0, .decl_required: true, .type_required: false, .function_type_required: false, .affects_type_identity: false, |
105 | .handler: handle_leaf_attribute, NULL }, |
106 | /* The same comments as for noreturn attributes apply to const ones. */ |
107 | { .name: "const" , .min_length: 0, .max_length: 0, .decl_required: true, .type_required: false, .function_type_required: false, .affects_type_identity: false, |
108 | .handler: handle_const_attribute, |
109 | .exclude: attr_const_pure_exclusions }, |
110 | { .name: "malloc" , .min_length: 0, .max_length: 0, .decl_required: true, .type_required: false, .function_type_required: false, .affects_type_identity: false, |
111 | .handler: handle_malloc_attribute, NULL }, |
112 | { .name: "pure" , .min_length: 0, .max_length: 0, .decl_required: true, .type_required: false, .function_type_required: false, .affects_type_identity: false, |
113 | .handler: handle_pure_attribute, |
114 | .exclude: attr_const_pure_exclusions }, |
115 | { .name: "no vops" , .min_length: 0, .max_length: 0, .decl_required: true, .type_required: false, .function_type_required: false, .affects_type_identity: false, |
116 | .handler: handle_novops_attribute, NULL }, |
117 | { .name: "nonnull" , .min_length: 0, .max_length: -1, .decl_required: false, .type_required: true, .function_type_required: true, .affects_type_identity: false, |
118 | .handler: handle_nonnull_attribute, NULL }, |
119 | { .name: "nothrow" , .min_length: 0, .max_length: 0, .decl_required: true, .type_required: false, .function_type_required: false, .affects_type_identity: false, |
120 | .handler: handle_nothrow_attribute, NULL }, |
121 | { .name: "patchable_function_entry" , .min_length: 1, .max_length: 2, .decl_required: true, .type_required: false, .function_type_required: false, .affects_type_identity: false, |
122 | .handler: handle_patchable_function_entry_attribute, |
123 | NULL }, |
124 | { .name: "returns_twice" , .min_length: 0, .max_length: 0, .decl_required: true, .type_required: false, .function_type_required: false, .affects_type_identity: false, |
125 | .handler: handle_returns_twice_attribute, |
126 | .exclude: attr_returns_twice_exclusions }, |
127 | { .name: "sentinel" , .min_length: 0, .max_length: 1, .decl_required: false, .type_required: true, .function_type_required: true, .affects_type_identity: false, |
128 | .handler: handle_sentinel_attribute, NULL }, |
129 | { .name: "type generic" , .min_length: 0, .max_length: 0, .decl_required: false, .type_required: true, .function_type_required: true, .affects_type_identity: false, |
130 | .handler: handle_type_generic_attribute, NULL }, |
131 | { .name: "fn spec" , .min_length: 1, .max_length: 1, .decl_required: false, .type_required: true, .function_type_required: true, .affects_type_identity: false, |
132 | .handler: handle_fnspec_attribute, NULL }, |
133 | { .name: "transaction_pure" , .min_length: 0, .max_length: 0, .decl_required: false, .type_required: true, .function_type_required: true, .affects_type_identity: false, |
134 | .handler: handle_transaction_pure_attribute, NULL }, |
135 | /* For internal use only. The leading '*' both prevents its usage in |
136 | source code and signals that it may be overridden by machine tables. */ |
137 | { .name: "*tm regparm" , .min_length: 0, .max_length: 0, .decl_required: false, .type_required: true, .function_type_required: true, .affects_type_identity: false, |
138 | .handler: ignore_attribute, NULL }, |
139 | { NULL, .min_length: 0, .max_length: 0, .decl_required: false, .type_required: false, .function_type_required: false, .affects_type_identity: false, NULL, NULL } |
140 | }; |
141 | |
142 | /* Give the specifications for the format attributes, used by C and all |
143 | descendants. */ |
144 | |
145 | const struct attribute_spec lto_format_attribute_table[] = |
146 | { |
147 | /* { name, min_len, max_len, decl_req, type_req, fn_type_req, |
148 | affects_type_identity, handler, exclude } */ |
149 | { .name: "format" , .min_length: 3, .max_length: 3, .decl_required: false, .type_required: true, .function_type_required: true, .affects_type_identity: false, |
150 | .handler: handle_format_attribute, NULL }, |
151 | { .name: "format_arg" , .min_length: 1, .max_length: 1, .decl_required: false, .type_required: true, .function_type_required: true, .affects_type_identity: false, |
152 | .handler: handle_format_arg_attribute, NULL }, |
153 | { NULL, .min_length: 0, .max_length: 0, .decl_required: false, .type_required: false, .function_type_required: false, .affects_type_identity: false, NULL, NULL } |
154 | }; |
155 | |
156 | enum built_in_attribute |
157 | { |
158 | #define DEF_ATTR_NULL_TREE(ENUM) ENUM, |
159 | #define DEF_ATTR_INT(ENUM, VALUE) ENUM, |
160 | #define DEF_ATTR_STRING(ENUM, VALUE) ENUM, |
161 | #define DEF_ATTR_IDENT(ENUM, STRING) ENUM, |
162 | #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM, |
163 | #include "builtin-attrs.def" |
164 | #undef DEF_ATTR_NULL_TREE |
165 | #undef DEF_ATTR_INT |
166 | #undef DEF_ATTR_STRING |
167 | #undef DEF_ATTR_IDENT |
168 | #undef DEF_ATTR_TREE_LIST |
169 | ATTR_LAST |
170 | }; |
171 | |
172 | static GTY(()) tree built_in_attributes[(int) ATTR_LAST]; |
173 | |
174 | /* Builtin types. */ |
175 | |
176 | enum lto_builtin_type |
177 | { |
178 | #define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME, |
179 | #define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME, |
180 | #define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME, |
181 | #define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME, |
182 | #define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME, |
183 | #define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME, |
184 | #define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME, |
185 | #define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ |
186 | ARG6) NAME, |
187 | #define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ |
188 | ARG6, ARG7) NAME, |
189 | #define DEF_FUNCTION_TYPE_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ |
190 | ARG6, ARG7, ARG8) NAME, |
191 | #define DEF_FUNCTION_TYPE_9(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ |
192 | ARG6, ARG7, ARG8, ARG9) NAME, |
193 | #define DEF_FUNCTION_TYPE_10(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ |
194 | ARG6, ARG7, ARG8, ARG9, ARG10) NAME, |
195 | #define DEF_FUNCTION_TYPE_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ |
196 | ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME, |
197 | #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME, |
198 | #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME, |
199 | #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME, |
200 | #define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME, |
201 | #define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME, |
202 | #define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG6) \ |
203 | NAME, |
204 | #define DEF_FUNCTION_TYPE_VAR_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ |
205 | ARG6) NAME, |
206 | #define DEF_FUNCTION_TYPE_VAR_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ |
207 | ARG6, ARG7) NAME, |
208 | #define DEF_POINTER_TYPE(NAME, TYPE) NAME, |
209 | #include "builtin-types.def" |
210 | #undef DEF_PRIMITIVE_TYPE |
211 | #undef DEF_FUNCTION_TYPE_0 |
212 | #undef DEF_FUNCTION_TYPE_1 |
213 | #undef DEF_FUNCTION_TYPE_2 |
214 | #undef DEF_FUNCTION_TYPE_3 |
215 | #undef DEF_FUNCTION_TYPE_4 |
216 | #undef DEF_FUNCTION_TYPE_5 |
217 | #undef DEF_FUNCTION_TYPE_6 |
218 | #undef DEF_FUNCTION_TYPE_7 |
219 | #undef DEF_FUNCTION_TYPE_8 |
220 | #undef DEF_FUNCTION_TYPE_9 |
221 | #undef DEF_FUNCTION_TYPE_10 |
222 | #undef DEF_FUNCTION_TYPE_11 |
223 | #undef DEF_FUNCTION_TYPE_VAR_0 |
224 | #undef DEF_FUNCTION_TYPE_VAR_1 |
225 | #undef DEF_FUNCTION_TYPE_VAR_2 |
226 | #undef DEF_FUNCTION_TYPE_VAR_3 |
227 | #undef DEF_FUNCTION_TYPE_VAR_4 |
228 | #undef DEF_FUNCTION_TYPE_VAR_5 |
229 | #undef DEF_FUNCTION_TYPE_VAR_6 |
230 | #undef DEF_FUNCTION_TYPE_VAR_7 |
231 | #undef DEF_POINTER_TYPE |
232 | BT_LAST |
233 | }; |
234 | |
235 | typedef enum lto_builtin_type builtin_type; |
236 | |
237 | static GTY(()) tree builtin_types[(int) BT_LAST + 1]; |
238 | |
239 | static GTY(()) tree string_type_node; |
240 | static GTY(()) tree const_string_type_node; |
241 | static GTY(()) tree wint_type_node; |
242 | static GTY(()) tree intmax_type_node; |
243 | static GTY(()) tree uintmax_type_node; |
244 | static GTY(()) tree signed_size_type_node; |
245 | |
246 | /* Flags needed to process builtins.def. */ |
247 | int flag_isoc94; |
248 | int flag_isoc99; |
249 | int flag_isoc11; |
250 | int flag_isoc23; |
251 | |
252 | /* Attribute handlers. */ |
253 | |
254 | /* Handle a "noreturn" attribute; arguments as in |
255 | struct attribute_spec.handler. */ |
256 | |
257 | static tree |
258 | handle_noreturn_attribute (tree *node, tree ARG_UNUSED (name), |
259 | tree ARG_UNUSED (args), int ARG_UNUSED (flags), |
260 | bool * ARG_UNUSED (no_add_attrs)) |
261 | { |
262 | tree type = TREE_TYPE (*node); |
263 | |
264 | if (TREE_CODE (*node) == FUNCTION_DECL) |
265 | TREE_THIS_VOLATILE (*node) = 1; |
266 | else if (TREE_CODE (type) == POINTER_TYPE |
267 | && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) |
268 | TREE_TYPE (*node) |
269 | = build_pointer_type |
270 | (build_type_variant (TREE_TYPE (type), |
271 | TYPE_READONLY (TREE_TYPE (type)), 1)); |
272 | else |
273 | gcc_unreachable (); |
274 | |
275 | return NULL_TREE; |
276 | } |
277 | |
278 | /* Handle a "leaf" attribute; arguments as in |
279 | struct attribute_spec.handler. */ |
280 | |
281 | static tree |
282 | handle_leaf_attribute (tree *node, tree name, |
283 | tree ARG_UNUSED (args), |
284 | int ARG_UNUSED (flags), bool *no_add_attrs) |
285 | { |
286 | if (TREE_CODE (*node) != FUNCTION_DECL) |
287 | { |
288 | warning (OPT_Wattributes, "%qE attribute ignored" , name); |
289 | *no_add_attrs = true; |
290 | } |
291 | if (!TREE_PUBLIC (*node)) |
292 | { |
293 | warning (OPT_Wattributes, "%qE attribute has no effect on unit local functions" , name); |
294 | *no_add_attrs = true; |
295 | } |
296 | |
297 | return NULL_TREE; |
298 | } |
299 | |
300 | /* Handle a "const" attribute; arguments as in |
301 | struct attribute_spec.handler. */ |
302 | |
303 | static tree |
304 | handle_const_attribute (tree *node, tree ARG_UNUSED (name), |
305 | tree ARG_UNUSED (args), int ARG_UNUSED (flags), |
306 | bool * ARG_UNUSED (no_add_attrs)) |
307 | { |
308 | if (TREE_CODE (*node) != FUNCTION_DECL |
309 | || !fndecl_built_in_p (node: *node)) |
310 | inform (UNKNOWN_LOCATION, "%s:%s: %E: %E" , __FILE__, __func__, *node, name); |
311 | |
312 | tree type = TREE_TYPE (*node); |
313 | |
314 | /* See FIXME comment on noreturn in c_common_attribute_table. */ |
315 | if (TREE_CODE (*node) == FUNCTION_DECL) |
316 | TREE_READONLY (*node) = 1; |
317 | else if (TREE_CODE (type) == POINTER_TYPE |
318 | && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) |
319 | TREE_TYPE (*node) |
320 | = build_pointer_type |
321 | (build_type_variant (TREE_TYPE (type), 1, |
322 | TREE_THIS_VOLATILE (TREE_TYPE (type)))); |
323 | else |
324 | gcc_unreachable (); |
325 | |
326 | return NULL_TREE; |
327 | } |
328 | |
329 | |
330 | /* Handle a "malloc" attribute; arguments as in |
331 | struct attribute_spec.handler. */ |
332 | |
333 | static tree |
334 | handle_malloc_attribute (tree *node, tree ARG_UNUSED (name), |
335 | tree ARG_UNUSED (args), int ARG_UNUSED (flags), |
336 | bool * ARG_UNUSED (no_add_attrs)) |
337 | { |
338 | if (TREE_CODE (*node) == FUNCTION_DECL |
339 | && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node)))) |
340 | DECL_IS_MALLOC (*node) = 1; |
341 | else |
342 | gcc_unreachable (); |
343 | |
344 | return NULL_TREE; |
345 | } |
346 | |
347 | |
348 | /* Handle a "pure" attribute; arguments as in |
349 | struct attribute_spec.handler. */ |
350 | |
351 | static tree |
352 | handle_pure_attribute (tree *node, tree ARG_UNUSED (name), |
353 | tree ARG_UNUSED (args), int ARG_UNUSED (flags), |
354 | bool * ARG_UNUSED (no_add_attrs)) |
355 | { |
356 | if (TREE_CODE (*node) == FUNCTION_DECL) |
357 | DECL_PURE_P (*node) = 1; |
358 | else |
359 | gcc_unreachable (); |
360 | |
361 | return NULL_TREE; |
362 | } |
363 | |
364 | |
365 | /* Handle a "no vops" attribute; arguments as in |
366 | struct attribute_spec.handler. */ |
367 | |
368 | static tree |
369 | handle_novops_attribute (tree *node, tree ARG_UNUSED (name), |
370 | tree ARG_UNUSED (args), int ARG_UNUSED (flags), |
371 | bool *ARG_UNUSED (no_add_attrs)) |
372 | { |
373 | gcc_assert (TREE_CODE (*node) == FUNCTION_DECL); |
374 | DECL_IS_NOVOPS (*node) = 1; |
375 | return NULL_TREE; |
376 | } |
377 | |
378 | |
379 | /* Helper for nonnull attribute handling; fetch the operand number |
380 | from the attribute argument list. */ |
381 | |
382 | static bool |
383 | get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp) |
384 | { |
385 | /* Verify the arg number is a constant. */ |
386 | if (!tree_fits_uhwi_p (arg_num_expr)) |
387 | return false; |
388 | |
389 | *valp = TREE_INT_CST_LOW (arg_num_expr); |
390 | return true; |
391 | } |
392 | |
393 | /* Handle the "nonnull" attribute. */ |
394 | |
395 | static tree |
396 | handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name), |
397 | tree args, int ARG_UNUSED (flags), |
398 | bool * ARG_UNUSED (no_add_attrs)) |
399 | { |
400 | tree type = *node; |
401 | |
402 | /* If no arguments are specified, all pointer arguments should be |
403 | non-null. Verify a full prototype is given so that the arguments |
404 | will have the correct types when we actually check them later. |
405 | Avoid diagnosing type-generic built-ins since those have no |
406 | prototype. */ |
407 | if (!args) |
408 | { |
409 | gcc_assert (prototype_p (type) |
410 | || !TYPE_ATTRIBUTES (type) |
411 | || lookup_attribute ("type generic" , TYPE_ATTRIBUTES (type))); |
412 | |
413 | return NULL_TREE; |
414 | } |
415 | |
416 | /* Argument list specified. Verify that each argument number references |
417 | a pointer argument. */ |
418 | for (; args; args = TREE_CHAIN (args)) |
419 | { |
420 | tree argument; |
421 | unsigned HOST_WIDE_INT arg_num = 0, ck_num; |
422 | |
423 | if (!get_nonnull_operand (TREE_VALUE (args), valp: &arg_num)) |
424 | gcc_unreachable (); |
425 | |
426 | argument = TYPE_ARG_TYPES (type); |
427 | if (argument) |
428 | { |
429 | for (ck_num = 1; ; ck_num++) |
430 | { |
431 | if (!argument || ck_num == arg_num) |
432 | break; |
433 | argument = TREE_CHAIN (argument); |
434 | } |
435 | |
436 | gcc_assert (argument |
437 | && TREE_CODE (TREE_VALUE (argument)) == POINTER_TYPE); |
438 | } |
439 | } |
440 | |
441 | return NULL_TREE; |
442 | } |
443 | |
444 | |
445 | /* Handle a "nothrow" attribute; arguments as in |
446 | struct attribute_spec.handler. */ |
447 | |
448 | static tree |
449 | handle_nothrow_attribute (tree *node, tree ARG_UNUSED (name), |
450 | tree ARG_UNUSED (args), int ARG_UNUSED (flags), |
451 | bool * ARG_UNUSED (no_add_attrs)) |
452 | { |
453 | if (TREE_CODE (*node) == FUNCTION_DECL) |
454 | TREE_NOTHROW (*node) = 1; |
455 | else |
456 | gcc_unreachable (); |
457 | |
458 | return NULL_TREE; |
459 | } |
460 | |
461 | |
462 | /* Handle a "sentinel" attribute. */ |
463 | |
464 | static tree |
465 | handle_sentinel_attribute (tree *node, tree ARG_UNUSED (name), tree args, |
466 | int ARG_UNUSED (flags), |
467 | bool * ARG_UNUSED (no_add_attrs)) |
468 | { |
469 | gcc_assert (stdarg_p (*node)); |
470 | |
471 | if (args) |
472 | { |
473 | tree position = TREE_VALUE (args); |
474 | gcc_assert (TREE_CODE (position) == INTEGER_CST); |
475 | if (tree_int_cst_lt (t1: position, integer_zero_node)) |
476 | gcc_unreachable (); |
477 | } |
478 | |
479 | return NULL_TREE; |
480 | } |
481 | |
482 | /* Handle a "type_generic" attribute. */ |
483 | |
484 | static tree |
485 | handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name), |
486 | tree ARG_UNUSED (args), int ARG_UNUSED (flags), |
487 | bool * ARG_UNUSED (no_add_attrs)) |
488 | { |
489 | /* Ensure we have a function type. */ |
490 | gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE); |
491 | |
492 | /* Ensure we have a variadic function. */ |
493 | gcc_assert (!prototype_p (*node) || stdarg_p (*node)); |
494 | |
495 | return NULL_TREE; |
496 | } |
497 | |
498 | /* Handle a "transaction_pure" attribute. */ |
499 | |
500 | static tree |
501 | handle_transaction_pure_attribute (tree *node, tree ARG_UNUSED (name), |
502 | tree ARG_UNUSED (args), |
503 | int ARG_UNUSED (flags), |
504 | bool * ARG_UNUSED (no_add_attrs)) |
505 | { |
506 | /* Ensure we have a function type. */ |
507 | gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE); |
508 | |
509 | return NULL_TREE; |
510 | } |
511 | |
512 | /* Handle a "returns_twice" attribute. */ |
513 | |
514 | static tree |
515 | handle_returns_twice_attribute (tree *node, tree ARG_UNUSED (name), |
516 | tree ARG_UNUSED (args), |
517 | int ARG_UNUSED (flags), |
518 | bool * ARG_UNUSED (no_add_attrs)) |
519 | { |
520 | gcc_assert (TREE_CODE (*node) == FUNCTION_DECL); |
521 | |
522 | DECL_IS_RETURNS_TWICE (*node) = 1; |
523 | |
524 | return NULL_TREE; |
525 | } |
526 | |
527 | static tree |
528 | handle_patchable_function_entry_attribute (tree *, tree, tree, int, bool *) |
529 | { |
530 | /* Nothing to be done here. */ |
531 | return NULL_TREE; |
532 | } |
533 | |
534 | /* Ignore the given attribute. Used when this attribute may be usefully |
535 | overridden by the target, but is not used generically. */ |
536 | |
537 | static tree |
538 | ignore_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name), |
539 | tree ARG_UNUSED (args), int ARG_UNUSED (flags), |
540 | bool *no_add_attrs) |
541 | { |
542 | *no_add_attrs = true; |
543 | return NULL_TREE; |
544 | } |
545 | |
546 | /* Handle a "format" attribute; arguments as in |
547 | struct attribute_spec.handler. */ |
548 | |
549 | static tree |
550 | handle_format_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name), |
551 | tree ARG_UNUSED (args), int ARG_UNUSED (flags), |
552 | bool *no_add_attrs) |
553 | { |
554 | *no_add_attrs = true; |
555 | return NULL_TREE; |
556 | } |
557 | |
558 | |
559 | /* Handle a "format_arg" attribute; arguments as in |
560 | struct attribute_spec.handler. */ |
561 | |
562 | tree |
563 | handle_format_arg_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name), |
564 | tree ARG_UNUSED (args), int ARG_UNUSED (flags), |
565 | bool *no_add_attrs) |
566 | { |
567 | *no_add_attrs = true; |
568 | return NULL_TREE; |
569 | } |
570 | |
571 | |
572 | /* Handle a "fn spec" attribute; arguments as in |
573 | struct attribute_spec.handler. */ |
574 | |
575 | static tree |
576 | handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name), |
577 | tree args, int ARG_UNUSED (flags), |
578 | bool *no_add_attrs ATTRIBUTE_UNUSED) |
579 | { |
580 | gcc_assert (args |
581 | && TREE_CODE (TREE_VALUE (args)) == STRING_CST |
582 | && !TREE_CHAIN (args)); |
583 | return NULL_TREE; |
584 | } |
585 | |
586 | /* Cribbed from c-common.cc. */ |
587 | |
588 | static void |
589 | def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...) |
590 | { |
591 | tree t; |
592 | tree *args = XALLOCAVEC (tree, n); |
593 | va_list list; |
594 | int i; |
595 | bool err = false; |
596 | |
597 | va_start (list, n); |
598 | for (i = 0; i < n; ++i) |
599 | { |
600 | builtin_type a = (builtin_type) va_arg (list, int); |
601 | t = builtin_types[a]; |
602 | if (t == error_mark_node) |
603 | err = true; |
604 | args[i] = t; |
605 | } |
606 | va_end (list); |
607 | |
608 | t = builtin_types[ret]; |
609 | if (err) |
610 | t = error_mark_node; |
611 | if (t == error_mark_node) |
612 | ; |
613 | else if (var) |
614 | t = build_varargs_function_type_array (t, n, args); |
615 | else |
616 | t = build_function_type_array (t, n, args); |
617 | |
618 | builtin_types[def] = t; |
619 | } |
620 | |
621 | /* Used to help initialize the builtin-types.def table. When a type of |
622 | the correct size doesn't exist, use error_mark_node instead of NULL. |
623 | The later results in segfaults even when a decl using the type doesn't |
624 | get invoked. */ |
625 | |
626 | static tree |
627 | builtin_type_for_size (int size, bool unsignedp) |
628 | { |
629 | tree type = lang_hooks.types.type_for_size (size, unsignedp); |
630 | return type ? type : error_mark_node; |
631 | } |
632 | |
633 | /* Support for DEF_BUILTIN. */ |
634 | |
635 | static void |
636 | def_builtin_1 (enum built_in_function fncode, const char *name, |
637 | enum built_in_class fnclass, tree fntype, tree libtype, |
638 | bool both_p, bool fallback_p, bool nonansi_p, |
639 | tree fnattrs, bool implicit_p) |
640 | { |
641 | tree decl; |
642 | const char *libname; |
643 | |
644 | if (fntype == error_mark_node) |
645 | return; |
646 | |
647 | libname = name + strlen (s: "__builtin_" ); |
648 | decl = add_builtin_function (name, type: fntype, function_code: fncode, cl: fnclass, |
649 | library_name: (fallback_p ? libname : NULL), |
650 | attrs: fnattrs); |
651 | |
652 | if (both_p |
653 | && !flag_no_builtin |
654 | && !(nonansi_p && flag_no_nonansi_builtin)) |
655 | add_builtin_function (name: libname, type: libtype, function_code: fncode, cl: fnclass, |
656 | NULL, attrs: fnattrs); |
657 | |
658 | set_builtin_decl (fncode, decl, implicit_p); |
659 | } |
660 | |
661 | |
662 | /* Initialize the attribute table for all the supported builtins. */ |
663 | |
664 | static void |
665 | lto_init_attributes (void) |
666 | { |
667 | /* Fill in the built_in_attributes array. */ |
668 | #define DEF_ATTR_NULL_TREE(ENUM) \ |
669 | built_in_attributes[(int) ENUM] = NULL_TREE; |
670 | #define DEF_ATTR_INT(ENUM, VALUE) \ |
671 | built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE); |
672 | #define DEF_ATTR_STRING(ENUM, VALUE) \ |
673 | built_in_attributes[(int) ENUM] = build_string (strlen (VALUE), VALUE); |
674 | #define DEF_ATTR_IDENT(ENUM, STRING) \ |
675 | built_in_attributes[(int) ENUM] = get_identifier (STRING); |
676 | #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) \ |
677 | built_in_attributes[(int) ENUM] \ |
678 | = tree_cons (built_in_attributes[(int) PURPOSE], \ |
679 | built_in_attributes[(int) VALUE], \ |
680 | built_in_attributes[(int) CHAIN]); |
681 | #include "builtin-attrs.def" |
682 | #undef DEF_ATTR_NULL_TREE |
683 | #undef DEF_ATTR_INT |
684 | #undef DEF_ATTR_STRING |
685 | #undef DEF_ATTR_IDENT |
686 | #undef DEF_ATTR_TREE_LIST |
687 | } |
688 | |
689 | /* Create builtin types and functions. VA_LIST_REF_TYPE_NODE and |
690 | VA_LIST_ARG_TYPE_NODE are used in builtin-types.def. */ |
691 | |
692 | static void |
693 | lto_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED, |
694 | tree va_list_arg_type_node ATTRIBUTE_UNUSED) |
695 | { |
696 | #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \ |
697 | builtin_types[ENUM] = VALUE; |
698 | #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \ |
699 | def_fn_type (ENUM, RETURN, 0, 0); |
700 | #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \ |
701 | def_fn_type (ENUM, RETURN, 0, 1, ARG1); |
702 | #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \ |
703 | def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2); |
704 | #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \ |
705 | def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3); |
706 | #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \ |
707 | def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4); |
708 | #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \ |
709 | def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5); |
710 | #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ |
711 | ARG6) \ |
712 | def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); |
713 | #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ |
714 | ARG6, ARG7) \ |
715 | def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); |
716 | #define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ |
717 | ARG6, ARG7, ARG8) \ |
718 | def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \ |
719 | ARG7, ARG8); |
720 | #define DEF_FUNCTION_TYPE_9(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ |
721 | ARG6, ARG7, ARG8, ARG9) \ |
722 | def_fn_type (ENUM, RETURN, 0, 9, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \ |
723 | ARG7, ARG8, ARG9); |
724 | #define DEF_FUNCTION_TYPE_10(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ |
725 | ARG6, ARG7, ARG8, ARG9, ARG10) \ |
726 | def_fn_type (ENUM, RETURN, 0, 10, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \ |
727 | ARG7, ARG8, ARG9, ARG10); |
728 | #define DEF_FUNCTION_TYPE_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ |
729 | ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \ |
730 | def_fn_type (ENUM, RETURN, 0, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \ |
731 | ARG7, ARG8, ARG9, ARG10, ARG11); |
732 | #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \ |
733 | def_fn_type (ENUM, RETURN, 1, 0); |
734 | #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \ |
735 | def_fn_type (ENUM, RETURN, 1, 1, ARG1); |
736 | #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \ |
737 | def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2); |
738 | #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \ |
739 | def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3); |
740 | #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \ |
741 | def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4); |
742 | #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \ |
743 | def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5); |
744 | #define DEF_FUNCTION_TYPE_VAR_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ |
745 | ARG6) \ |
746 | def_fn_type (ENUM, RETURN, 1, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); |
747 | #define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ |
748 | ARG6, ARG7) \ |
749 | def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); |
750 | #define DEF_POINTER_TYPE(ENUM, TYPE) \ |
751 | builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]); |
752 | |
753 | #include "builtin-types.def" |
754 | |
755 | #undef DEF_PRIMITIVE_TYPE |
756 | #undef DEF_FUNCTION_TYPE_0 |
757 | #undef DEF_FUNCTION_TYPE_1 |
758 | #undef DEF_FUNCTION_TYPE_2 |
759 | #undef DEF_FUNCTION_TYPE_3 |
760 | #undef DEF_FUNCTION_TYPE_4 |
761 | #undef DEF_FUNCTION_TYPE_5 |
762 | #undef DEF_FUNCTION_TYPE_6 |
763 | #undef DEF_FUNCTION_TYPE_7 |
764 | #undef DEF_FUNCTION_TYPE_8 |
765 | #undef DEF_FUNCTION_TYPE_9 |
766 | #undef DEF_FUNCTION_TYPE_10 |
767 | #undef DEF_FUNCTION_TYPE_11 |
768 | #undef DEF_FUNCTION_TYPE_VAR_0 |
769 | #undef DEF_FUNCTION_TYPE_VAR_1 |
770 | #undef DEF_FUNCTION_TYPE_VAR_2 |
771 | #undef DEF_FUNCTION_TYPE_VAR_3 |
772 | #undef DEF_FUNCTION_TYPE_VAR_4 |
773 | #undef DEF_FUNCTION_TYPE_VAR_5 |
774 | #undef DEF_FUNCTION_TYPE_VAR_6 |
775 | #undef DEF_FUNCTION_TYPE_VAR_7 |
776 | #undef DEF_POINTER_TYPE |
777 | builtin_types[(int) BT_LAST] = NULL_TREE; |
778 | |
779 | lto_init_attributes (); |
780 | |
781 | #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P,\ |
782 | NONANSI_P, ATTRS, IMPLICIT, COND) \ |
783 | if (NAME && COND) \ |
784 | def_builtin_1 (ENUM, NAME, CLASS, builtin_types[(int) TYPE], \ |
785 | builtin_types[(int) LIBTYPE], BOTH_P, FALLBACK_P, \ |
786 | NONANSI_P, built_in_attributes[(int) ATTRS], IMPLICIT); |
787 | #include "builtins.def" |
788 | } |
789 | |
790 | static GTY(()) tree registered_builtin_types; |
791 | |
792 | /* Language hooks. */ |
793 | |
794 | static bool |
795 | lto_complain_wrong_lang_p (const struct cl_option *option ATTRIBUTE_UNUSED) |
796 | { |
797 | /* The LTO front end inherits all the options from the first front |
798 | end that was used. However, not all the original front end |
799 | options make sense in LTO. |
800 | |
801 | A real solution would be to filter this in collect2, but collect2 |
802 | does not have access to all the option attributes to know what to |
803 | filter. So, in lto1 we silently accept inherited flags and do |
804 | nothing about it. */ |
805 | return false; |
806 | } |
807 | |
808 | static void |
809 | lto_init_options_struct (struct gcc_options *opts) |
810 | { |
811 | /* By default, C99-like requirements for complex multiply and divide. |
812 | ??? Until the complex method is encoded in the IL this is the only |
813 | safe choice. This will pessimize Fortran code with LTO unless |
814 | people specify a complex method manually or use -ffast-math. */ |
815 | opts->x_flag_complex_method = 2; |
816 | opts->x_flag_default_complex_method = opts->x_flag_complex_method; |
817 | } |
818 | |
819 | /* Handle command-line option SCODE. If the option takes an argument, it is |
820 | stored in ARG, which is otherwise NULL. VALUE holds either a numerical |
821 | argument or a binary value indicating whether the positive or negative form |
822 | of the option was supplied. */ |
823 | |
824 | const char *resolution_file_name; |
825 | static bool |
826 | lto_handle_option (size_t scode, const char *arg, |
827 | HOST_WIDE_INT value ATTRIBUTE_UNUSED, |
828 | int kind ATTRIBUTE_UNUSED, |
829 | location_t loc ATTRIBUTE_UNUSED, |
830 | const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED) |
831 | { |
832 | enum opt_code code = (enum opt_code) scode; |
833 | bool result = true; |
834 | |
835 | switch (code) |
836 | { |
837 | case OPT_fresolution_: |
838 | resolution_file_name = arg; |
839 | break; |
840 | |
841 | case OPT_Wabi: |
842 | warn_psabi = value; |
843 | break; |
844 | |
845 | case OPT_fwpa: |
846 | flag_wpa = value ? "" : NULL; |
847 | break; |
848 | |
849 | default: |
850 | break; |
851 | } |
852 | |
853 | return result; |
854 | } |
855 | |
856 | /* Perform post-option processing. Does additional initialization based on |
857 | command-line options. PFILENAME is the main input filename. Returns false |
858 | to enable subsequent back-end initialization. */ |
859 | |
860 | static bool |
861 | lto_post_options (const char **pfilename ATTRIBUTE_UNUSED) |
862 | { |
863 | /* -fltrans and -fwpa are mutually exclusive. Check for that here. */ |
864 | if (flag_wpa && flag_ltrans) |
865 | error ("%<-fwpa%> and %<-fltrans%> are mutually exclusive" ); |
866 | |
867 | if (flag_ltrans) |
868 | { |
869 | flag_generate_lto = 0; |
870 | |
871 | /* During LTRANS, we are not looking at the whole program, only |
872 | a subset of the whole callgraph. */ |
873 | flag_whole_program = 0; |
874 | } |
875 | |
876 | if (flag_wpa) |
877 | flag_generate_lto = 1; |
878 | |
879 | /* Initialize the codegen flags according to the output type. */ |
880 | switch (flag_lto_linker_output) |
881 | { |
882 | case LTO_LINKER_OUTPUT_REL: /* .o: incremental link producing LTO IL */ |
883 | /* Configure compiler same way as normal frontend would do with -flto: |
884 | this way we read the trees (declarations & types), symbol table, |
885 | optimization summaries and link them. Subsequently we output new LTO |
886 | file. */ |
887 | flag_lto = "" ; |
888 | flag_incremental_link = INCREMENTAL_LINK_LTO; |
889 | flag_whole_program = 0; |
890 | flag_wpa = 0; |
891 | flag_generate_lto = 1; |
892 | /* It would be cool to produce .o file directly, but our current |
893 | simple objects does not contain the lto symbol markers. Go the slow |
894 | way through the asm file. */ |
895 | lang_hooks.lto.begin_section = lhd_begin_section; |
896 | lang_hooks.lto.append_data = lhd_append_data; |
897 | lang_hooks.lto.end_section = lhd_end_section; |
898 | if (flag_ltrans) |
899 | error ("%<-flinker-output=rel%> and %<-fltrans%> are mutually " |
900 | "exclusive" ); |
901 | break; |
902 | |
903 | case LTO_LINKER_OUTPUT_NOLTOREL: /* .o: incremental link producing asm */ |
904 | flag_incremental_link = INCREMENTAL_LINK_NOLTO; |
905 | break; |
906 | |
907 | case LTO_LINKER_OUTPUT_DYN: /* .so: PID library */ |
908 | /* On some targets, like i386 it makes sense to build PIC library wihout |
909 | -fpic for performance reasons. So no need to adjust flags. */ |
910 | break; |
911 | |
912 | case LTO_LINKER_OUTPUT_PIE: /* PIE binary */ |
913 | /* If -fPIC or -fPIE was used at compile time, be sure that |
914 | flag_pie is 2. */ |
915 | flag_pie = MAX (flag_pie, flag_pic); |
916 | flag_pic = flag_pie; |
917 | flag_shlib = 0; |
918 | break; |
919 | |
920 | case LTO_LINKER_OUTPUT_EXEC: /* Normal executable */ |
921 | flag_pic = 0; |
922 | flag_pie = 0; |
923 | flag_shlib = 0; |
924 | break; |
925 | |
926 | case LTO_LINKER_OUTPUT_UNKNOWN: |
927 | break; |
928 | } |
929 | |
930 | /* Excess precision other than "fast" requires front-end |
931 | support. */ |
932 | if (flag_excess_precision == EXCESS_PRECISION_DEFAULT) |
933 | flag_excess_precision = EXCESS_PRECISION_FAST; |
934 | |
935 | /* When partitioning, we can tear appart STRING_CSTs uses from the same |
936 | TU into multiple partitions. Without constant merging the constants |
937 | might not be equal at runtime. See PR50199. */ |
938 | if (!flag_merge_constants) |
939 | flag_merge_constants = 1; |
940 | |
941 | /* Initialize the compiler back end. */ |
942 | return false; |
943 | } |
944 | |
945 | /* Return a data type that has machine mode MODE. |
946 | If the mode is an integer, |
947 | then UNSIGNEDP selects between signed and unsigned types. |
948 | If the mode is a fixed-point mode, |
949 | then UNSIGNEDP selects between saturating and nonsaturating types. */ |
950 | |
951 | static tree |
952 | lto_type_for_mode (machine_mode mode, int unsigned_p) |
953 | { |
954 | tree t; |
955 | int i; |
956 | |
957 | if (mode == TYPE_MODE (integer_type_node)) |
958 | return unsigned_p ? unsigned_type_node : integer_type_node; |
959 | |
960 | if (mode == TYPE_MODE (signed_char_type_node)) |
961 | return unsigned_p ? unsigned_char_type_node : signed_char_type_node; |
962 | |
963 | if (mode == TYPE_MODE (short_integer_type_node)) |
964 | return unsigned_p ? short_unsigned_type_node : short_integer_type_node; |
965 | |
966 | if (mode == TYPE_MODE (long_integer_type_node)) |
967 | return unsigned_p ? long_unsigned_type_node : long_integer_type_node; |
968 | |
969 | if (mode == TYPE_MODE (long_long_integer_type_node)) |
970 | return unsigned_p ? long_long_unsigned_type_node : long_long_integer_type_node; |
971 | |
972 | for (i = 0; i < NUM_INT_N_ENTS; i ++) |
973 | if (int_n_enabled_p[i] |
974 | && mode == int_n_data[i].m) |
975 | return (unsigned_p ? int_n_trees[i].unsigned_type |
976 | : int_n_trees[i].signed_type); |
977 | |
978 | if (mode == QImode) |
979 | return unsigned_p ? unsigned_intQI_type_node : intQI_type_node; |
980 | |
981 | if (mode == HImode) |
982 | return unsigned_p ? unsigned_intHI_type_node : intHI_type_node; |
983 | |
984 | if (mode == SImode) |
985 | return unsigned_p ? unsigned_intSI_type_node : intSI_type_node; |
986 | |
987 | if (mode == DImode) |
988 | return unsigned_p ? unsigned_intDI_type_node : intDI_type_node; |
989 | |
990 | #if HOST_BITS_PER_WIDE_INT >= 64 |
991 | if (mode == TYPE_MODE (intTI_type_node)) |
992 | return unsigned_p ? unsigned_intTI_type_node : intTI_type_node; |
993 | #endif |
994 | |
995 | if (float16_type_node && mode == TYPE_MODE (float16_type_node)) |
996 | return float16_type_node; |
997 | |
998 | if (mode == TYPE_MODE (float_type_node)) |
999 | return float_type_node; |
1000 | |
1001 | if (mode == TYPE_MODE (double_type_node)) |
1002 | return double_type_node; |
1003 | |
1004 | if (mode == TYPE_MODE (long_double_type_node)) |
1005 | return long_double_type_node; |
1006 | |
1007 | for (i = 0; i < NUM_FLOATN_NX_TYPES; i++) |
1008 | if (FLOATN_NX_TYPE_NODE (i) != NULL_TREE |
1009 | && mode == TYPE_MODE (FLOATN_NX_TYPE_NODE (i))) |
1010 | return FLOATN_NX_TYPE_NODE (i); |
1011 | |
1012 | if (mode == TYPE_MODE (void_type_node)) |
1013 | return void_type_node; |
1014 | |
1015 | if (mode == TYPE_MODE (build_pointer_type (char_type_node)) |
1016 | || mode == TYPE_MODE (build_pointer_type (integer_type_node))) |
1017 | { |
1018 | unsigned int precision |
1019 | = GET_MODE_PRECISION (mode: as_a <scalar_int_mode> (m: mode)); |
1020 | return (unsigned_p |
1021 | ? make_unsigned_type (precision) |
1022 | : make_signed_type (precision)); |
1023 | } |
1024 | |
1025 | if (COMPLEX_MODE_P (mode)) |
1026 | { |
1027 | machine_mode inner_mode; |
1028 | tree inner_type; |
1029 | |
1030 | if (mode == TYPE_MODE (complex_float_type_node)) |
1031 | return complex_float_type_node; |
1032 | if (mode == TYPE_MODE (complex_double_type_node)) |
1033 | return complex_double_type_node; |
1034 | if (mode == TYPE_MODE (complex_long_double_type_node)) |
1035 | return complex_long_double_type_node; |
1036 | |
1037 | for (i = 0; i < NUM_FLOATN_NX_TYPES; i++) |
1038 | if (COMPLEX_FLOATN_NX_TYPE_NODE (i) != NULL_TREE |
1039 | && mode == TYPE_MODE (COMPLEX_FLOATN_NX_TYPE_NODE (i))) |
1040 | return COMPLEX_FLOATN_NX_TYPE_NODE (i); |
1041 | |
1042 | if (mode == TYPE_MODE (complex_integer_type_node) && !unsigned_p) |
1043 | return complex_integer_type_node; |
1044 | |
1045 | inner_mode = GET_MODE_INNER (mode); |
1046 | inner_type = lto_type_for_mode (mode: inner_mode, unsigned_p); |
1047 | if (inner_type != NULL_TREE) |
1048 | return build_complex_type (inner_type); |
1049 | } |
1050 | else if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL |
1051 | && valid_vector_subparts_p (subparts: GET_MODE_NUNITS (mode))) |
1052 | { |
1053 | unsigned int elem_bits = vector_element_size (GET_MODE_PRECISION (mode), |
1054 | GET_MODE_NUNITS (mode)); |
1055 | tree bool_type = build_nonstandard_boolean_type (elem_bits); |
1056 | return build_vector_type_for_mode (bool_type, mode); |
1057 | } |
1058 | else if (VECTOR_MODE_P (mode) |
1059 | && valid_vector_subparts_p (subparts: GET_MODE_NUNITS (mode))) |
1060 | { |
1061 | machine_mode inner_mode = GET_MODE_INNER (mode); |
1062 | tree inner_type = lto_type_for_mode (mode: inner_mode, unsigned_p); |
1063 | if (inner_type != NULL_TREE) |
1064 | return build_vector_type_for_mode (inner_type, mode); |
1065 | } |
1066 | |
1067 | if (dfloat32_type_node != NULL_TREE |
1068 | && mode == TYPE_MODE (dfloat32_type_node)) |
1069 | return dfloat32_type_node; |
1070 | if (dfloat64_type_node != NULL_TREE |
1071 | && mode == TYPE_MODE (dfloat64_type_node)) |
1072 | return dfloat64_type_node; |
1073 | if (dfloat128_type_node != NULL_TREE |
1074 | && mode == TYPE_MODE (dfloat128_type_node)) |
1075 | return dfloat128_type_node; |
1076 | |
1077 | if (ALL_SCALAR_FIXED_POINT_MODE_P (mode)) |
1078 | { |
1079 | if (mode == TYPE_MODE (short_fract_type_node)) |
1080 | return unsigned_p ? sat_short_fract_type_node : short_fract_type_node; |
1081 | if (mode == TYPE_MODE (fract_type_node)) |
1082 | return unsigned_p ? sat_fract_type_node : fract_type_node; |
1083 | if (mode == TYPE_MODE (long_fract_type_node)) |
1084 | return unsigned_p ? sat_long_fract_type_node : long_fract_type_node; |
1085 | if (mode == TYPE_MODE (long_long_fract_type_node)) |
1086 | return unsigned_p ? sat_long_long_fract_type_node |
1087 | : long_long_fract_type_node; |
1088 | |
1089 | if (mode == TYPE_MODE (unsigned_short_fract_type_node)) |
1090 | return unsigned_p ? sat_unsigned_short_fract_type_node |
1091 | : unsigned_short_fract_type_node; |
1092 | if (mode == TYPE_MODE (unsigned_fract_type_node)) |
1093 | return unsigned_p ? sat_unsigned_fract_type_node |
1094 | : unsigned_fract_type_node; |
1095 | if (mode == TYPE_MODE (unsigned_long_fract_type_node)) |
1096 | return unsigned_p ? sat_unsigned_long_fract_type_node |
1097 | : unsigned_long_fract_type_node; |
1098 | if (mode == TYPE_MODE (unsigned_long_long_fract_type_node)) |
1099 | return unsigned_p ? sat_unsigned_long_long_fract_type_node |
1100 | : unsigned_long_long_fract_type_node; |
1101 | |
1102 | if (mode == TYPE_MODE (short_accum_type_node)) |
1103 | return unsigned_p ? sat_short_accum_type_node : short_accum_type_node; |
1104 | if (mode == TYPE_MODE (accum_type_node)) |
1105 | return unsigned_p ? sat_accum_type_node : accum_type_node; |
1106 | if (mode == TYPE_MODE (long_accum_type_node)) |
1107 | return unsigned_p ? sat_long_accum_type_node : long_accum_type_node; |
1108 | if (mode == TYPE_MODE (long_long_accum_type_node)) |
1109 | return unsigned_p ? sat_long_long_accum_type_node |
1110 | : long_long_accum_type_node; |
1111 | |
1112 | if (mode == TYPE_MODE (unsigned_short_accum_type_node)) |
1113 | return unsigned_p ? sat_unsigned_short_accum_type_node |
1114 | : unsigned_short_accum_type_node; |
1115 | if (mode == TYPE_MODE (unsigned_accum_type_node)) |
1116 | return unsigned_p ? sat_unsigned_accum_type_node |
1117 | : unsigned_accum_type_node; |
1118 | if (mode == TYPE_MODE (unsigned_long_accum_type_node)) |
1119 | return unsigned_p ? sat_unsigned_long_accum_type_node |
1120 | : unsigned_long_accum_type_node; |
1121 | if (mode == TYPE_MODE (unsigned_long_long_accum_type_node)) |
1122 | return unsigned_p ? sat_unsigned_long_long_accum_type_node |
1123 | : unsigned_long_long_accum_type_node; |
1124 | |
1125 | if (mode == QQmode) |
1126 | return unsigned_p ? sat_qq_type_node : qq_type_node; |
1127 | if (mode == HQmode) |
1128 | return unsigned_p ? sat_hq_type_node : hq_type_node; |
1129 | if (mode == SQmode) |
1130 | return unsigned_p ? sat_sq_type_node : sq_type_node; |
1131 | if (mode == DQmode) |
1132 | return unsigned_p ? sat_dq_type_node : dq_type_node; |
1133 | if (mode == TQmode) |
1134 | return unsigned_p ? sat_tq_type_node : tq_type_node; |
1135 | |
1136 | if (mode == UQQmode) |
1137 | return unsigned_p ? sat_uqq_type_node : uqq_type_node; |
1138 | if (mode == UHQmode) |
1139 | return unsigned_p ? sat_uhq_type_node : uhq_type_node; |
1140 | if (mode == USQmode) |
1141 | return unsigned_p ? sat_usq_type_node : usq_type_node; |
1142 | if (mode == UDQmode) |
1143 | return unsigned_p ? sat_udq_type_node : udq_type_node; |
1144 | if (mode == UTQmode) |
1145 | return unsigned_p ? sat_utq_type_node : utq_type_node; |
1146 | |
1147 | if (mode == HAmode) |
1148 | return unsigned_p ? sat_ha_type_node : ha_type_node; |
1149 | if (mode == SAmode) |
1150 | return unsigned_p ? sat_sa_type_node : sa_type_node; |
1151 | if (mode == DAmode) |
1152 | return unsigned_p ? sat_da_type_node : da_type_node; |
1153 | if (mode == TAmode) |
1154 | return unsigned_p ? sat_ta_type_node : ta_type_node; |
1155 | |
1156 | if (mode == UHAmode) |
1157 | return unsigned_p ? sat_uha_type_node : uha_type_node; |
1158 | if (mode == USAmode) |
1159 | return unsigned_p ? sat_usa_type_node : usa_type_node; |
1160 | if (mode == UDAmode) |
1161 | return unsigned_p ? sat_uda_type_node : uda_type_node; |
1162 | if (mode == UTAmode) |
1163 | return unsigned_p ? sat_uta_type_node : uta_type_node; |
1164 | } |
1165 | |
1166 | for (t = registered_builtin_types; t; t = TREE_CHAIN (t)) |
1167 | { |
1168 | tree type = TREE_VALUE (t); |
1169 | if (TYPE_MODE (type) == mode |
1170 | && VECTOR_TYPE_P (type) == VECTOR_MODE_P (mode) |
1171 | && !!unsigned_p == !!TYPE_UNSIGNED (type)) |
1172 | return type; |
1173 | } |
1174 | return NULL_TREE; |
1175 | } |
1176 | |
1177 | /* Return true if we are in the global binding level. */ |
1178 | |
1179 | static bool |
1180 | lto_global_bindings_p (void) |
1181 | { |
1182 | return cfun == NULL; |
1183 | } |
1184 | |
1185 | static void |
1186 | lto_set_decl_assembler_name (tree decl) |
1187 | { |
1188 | /* This is almost the same as lhd_set_decl_assembler_name, except that |
1189 | we need to uniquify file-scope names, even if they are not |
1190 | TREE_PUBLIC, to avoid conflicts between individual files. */ |
1191 | tree id; |
1192 | |
1193 | if (TREE_PUBLIC (decl)) |
1194 | id = targetm.mangle_decl_assembler_name (decl, DECL_NAME (decl)); |
1195 | else |
1196 | { |
1197 | const char *name = IDENTIFIER_POINTER (DECL_NAME (decl)); |
1198 | char *label; |
1199 | static unsigned long num; |
1200 | |
1201 | ASM_FORMAT_PRIVATE_NAME (label, name, num++); |
1202 | id = get_identifier (label); |
1203 | } |
1204 | |
1205 | SET_DECL_ASSEMBLER_NAME (decl, id); |
1206 | } |
1207 | |
1208 | static tree |
1209 | lto_pushdecl (tree t ATTRIBUTE_UNUSED) |
1210 | { |
1211 | /* Do nothing, since we get all information from DWARF and LTO |
1212 | sections. */ |
1213 | return NULL_TREE; |
1214 | } |
1215 | |
1216 | static tree |
1217 | lto_getdecls (void) |
1218 | { |
1219 | /* We have our own write_globals langhook, hence the getdecls |
1220 | langhook shouldn't be used, except by dbxout.cc, so we can't |
1221 | just abort here. */ |
1222 | return NULL_TREE; |
1223 | } |
1224 | |
1225 | static tree |
1226 | lto_builtin_function (tree decl) |
1227 | { |
1228 | return decl; |
1229 | } |
1230 | |
1231 | static void |
1232 | lto_register_builtin_type (tree type, const char *name) |
1233 | { |
1234 | tree decl; |
1235 | |
1236 | if (!TYPE_NAME (type)) |
1237 | { |
1238 | decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL, |
1239 | get_identifier (name), type); |
1240 | DECL_ARTIFICIAL (decl) = 1; |
1241 | TYPE_NAME (type) = decl; |
1242 | } |
1243 | |
1244 | registered_builtin_types = tree_cons (0, type, registered_builtin_types); |
1245 | } |
1246 | |
1247 | /* Build nodes that would have be created by the C front-end; necessary |
1248 | for including builtin-types.def and ultimately builtins.def. */ |
1249 | |
1250 | static void |
1251 | lto_build_c_type_nodes (void) |
1252 | { |
1253 | gcc_assert (void_type_node); |
1254 | |
1255 | string_type_node = build_pointer_type (char_type_node); |
1256 | const_string_type_node |
1257 | = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST)); |
1258 | |
1259 | if (strcmp (SIZE_TYPE, s2: "unsigned int" ) == 0) |
1260 | { |
1261 | intmax_type_node = integer_type_node; |
1262 | uintmax_type_node = unsigned_type_node; |
1263 | signed_size_type_node = integer_type_node; |
1264 | } |
1265 | else if (strcmp (SIZE_TYPE, s2: "long unsigned int" ) == 0) |
1266 | { |
1267 | intmax_type_node = long_integer_type_node; |
1268 | uintmax_type_node = long_unsigned_type_node; |
1269 | signed_size_type_node = long_integer_type_node; |
1270 | } |
1271 | else if (strcmp (SIZE_TYPE, s2: "long long unsigned int" ) == 0) |
1272 | { |
1273 | intmax_type_node = long_long_integer_type_node; |
1274 | uintmax_type_node = long_long_unsigned_type_node; |
1275 | signed_size_type_node = long_long_integer_type_node; |
1276 | } |
1277 | else |
1278 | { |
1279 | int i; |
1280 | |
1281 | signed_size_type_node = NULL_TREE; |
1282 | for (i = 0; i < NUM_INT_N_ENTS; i++) |
1283 | if (int_n_enabled_p[i]) |
1284 | { |
1285 | char name[50], altname[50]; |
1286 | sprintf (s: name, format: "__int%d unsigned" , int_n_data[i].bitsize); |
1287 | sprintf (s: altname, format: "__int%d__ unsigned" , int_n_data[i].bitsize); |
1288 | |
1289 | if (strcmp (s1: name, SIZE_TYPE) == 0 |
1290 | || strcmp (s1: altname, SIZE_TYPE) == 0) |
1291 | { |
1292 | intmax_type_node = int_n_trees[i].signed_type; |
1293 | uintmax_type_node = int_n_trees[i].unsigned_type; |
1294 | signed_size_type_node = int_n_trees[i].signed_type; |
1295 | } |
1296 | } |
1297 | if (signed_size_type_node == NULL_TREE) |
1298 | gcc_unreachable (); |
1299 | } |
1300 | |
1301 | wint_type_node = unsigned_type_node; |
1302 | pid_type_node = integer_type_node; |
1303 | } |
1304 | |
1305 | /* Perform LTO-specific initialization. */ |
1306 | |
1307 | static bool |
1308 | lto_init (void) |
1309 | { |
1310 | int i; |
1311 | |
1312 | /* Initialize LTO-specific data structures. */ |
1313 | in_lto_p = true; |
1314 | |
1315 | /* We need to generate LTO if running in WPA mode. */ |
1316 | flag_generate_lto = (flag_incremental_link == INCREMENTAL_LINK_LTO |
1317 | || flag_wpa != NULL); |
1318 | |
1319 | /* Create the basic integer types. */ |
1320 | build_common_tree_nodes (flag_signed_char); |
1321 | |
1322 | /* The global tree for the main identifier is filled in by |
1323 | language-specific front-end initialization that is not run in the |
1324 | LTO back-end. It appears that all languages that perform such |
1325 | initialization currently do so in the same way, so we do it here. */ |
1326 | if (main_identifier_node == NULL_TREE) |
1327 | main_identifier_node = get_identifier ("main" ); |
1328 | |
1329 | /* In the C++ front-end, fileptr_type_node is defined as a variant |
1330 | copy of ptr_type_node, rather than ptr_node itself. The |
1331 | distinction should only be relevant to the front-end, so we |
1332 | always use the C definition here in lto1. |
1333 | Likewise for const struct tm*. */ |
1334 | for (unsigned i = 0; i < ARRAY_SIZE (builtin_structptr_types); ++i) |
1335 | { |
1336 | gcc_assert (builtin_structptr_types[i].node |
1337 | == builtin_structptr_types[i].base); |
1338 | gcc_assert (TYPE_MAIN_VARIANT (builtin_structptr_types[i].node) |
1339 | == builtin_structptr_types[i].base); |
1340 | } |
1341 | |
1342 | lto_build_c_type_nodes (); |
1343 | gcc_assert (va_list_type_node); |
1344 | |
1345 | if (TREE_CODE (va_list_type_node) == ARRAY_TYPE) |
1346 | { |
1347 | tree x = build_pointer_type (TREE_TYPE (va_list_type_node)); |
1348 | lto_define_builtins (va_list_ref_type_node: x, va_list_arg_type_node: x); |
1349 | } |
1350 | else |
1351 | { |
1352 | lto_define_builtins (va_list_ref_type_node: build_reference_type (va_list_type_node), |
1353 | va_list_type_node); |
1354 | } |
1355 | |
1356 | targetm.init_builtins (); |
1357 | build_common_builtin_nodes (); |
1358 | |
1359 | /* Assign names to the builtin types, otherwise they'll end up |
1360 | as __unknown__ in debug info. |
1361 | ??? We simply need to stop pre-seeding the streamer cache. |
1362 | Below is modeled after from c-common.cc:c_common_nodes_and_builtins */ |
1363 | #define NAME_TYPE(t,n) \ |
1364 | if (t) \ |
1365 | TYPE_NAME (t) = build_decl (UNKNOWN_LOCATION, TYPE_DECL, \ |
1366 | get_identifier (n), t) |
1367 | NAME_TYPE (integer_type_node, "int" ); |
1368 | NAME_TYPE (char_type_node, "char" ); |
1369 | NAME_TYPE (long_integer_type_node, "long int" ); |
1370 | NAME_TYPE (unsigned_type_node, "unsigned int" ); |
1371 | NAME_TYPE (long_unsigned_type_node, "long unsigned int" ); |
1372 | NAME_TYPE (long_long_integer_type_node, "long long int" ); |
1373 | NAME_TYPE (long_long_unsigned_type_node, "long long unsigned int" ); |
1374 | NAME_TYPE (short_integer_type_node, "short int" ); |
1375 | NAME_TYPE (short_unsigned_type_node, "short unsigned int" ); |
1376 | if (signed_char_type_node != char_type_node) |
1377 | NAME_TYPE (signed_char_type_node, "signed char" ); |
1378 | if (unsigned_char_type_node != char_type_node) |
1379 | NAME_TYPE (unsigned_char_type_node, "unsigned char" ); |
1380 | NAME_TYPE (float_type_node, "float" ); |
1381 | NAME_TYPE (double_type_node, "double" ); |
1382 | NAME_TYPE (long_double_type_node, "long double" ); |
1383 | NAME_TYPE (void_type_node, "void" ); |
1384 | NAME_TYPE (boolean_type_node, "bool" ); |
1385 | NAME_TYPE (complex_float_type_node, "complex float" ); |
1386 | NAME_TYPE (complex_double_type_node, "complex double" ); |
1387 | NAME_TYPE (complex_long_double_type_node, "complex long double" ); |
1388 | for (i = 0; i < NUM_INT_N_ENTS; i++) |
1389 | if (int_n_enabled_p[i]) |
1390 | { |
1391 | char name[50]; |
1392 | sprintf (s: name, format: "__int%d" , int_n_data[i].bitsize); |
1393 | NAME_TYPE (int_n_trees[i].signed_type, name); |
1394 | } |
1395 | #undef NAME_TYPE |
1396 | |
1397 | return true; |
1398 | } |
1399 | |
1400 | /* Register c++-specific dumps. */ |
1401 | |
1402 | void |
1403 | lto_register_dumps (gcc::dump_manager *dumps) |
1404 | { |
1405 | lto_link_dump_id = dumps->dump_register |
1406 | (suffix: ".lto-link" , swtch: "ipa-lto-link" , glob: "ipa-lto-link" , |
1407 | dkind: DK_ipa, optgroup_flags: OPTGROUP_NONE, take_ownership: false); |
1408 | decl_merge_dump_id = dumps->dump_register |
1409 | (suffix: ".lto-decl-merge" , swtch: "ipa-lto-decl-merge" , glob: "ipa-lto-decl-merge" , |
1410 | dkind: DK_ipa, optgroup_flags: OPTGROUP_NONE, take_ownership: false); |
1411 | partition_dump_id = dumps->dump_register |
1412 | (suffix: ".lto-partition" , swtch: "ipa-lto-partition" , glob: "ipa-lto-partition" , |
1413 | dkind: DK_ipa, optgroup_flags: OPTGROUP_NONE, take_ownership: false); |
1414 | } |
1415 | |
1416 | |
1417 | /* Initialize tree structures required by the LTO front end. */ |
1418 | |
1419 | static void lto_init_ts (void) |
1420 | { |
1421 | tree_contains_struct[NAMESPACE_DECL][TS_DECL_MINIMAL] = 1; |
1422 | } |
1423 | |
1424 | #undef LANG_HOOKS_NAME |
1425 | #define LANG_HOOKS_NAME "GNU GIMPLE" |
1426 | #undef LANG_HOOKS_OPTION_LANG_MASK |
1427 | #define LANG_HOOKS_OPTION_LANG_MASK lto_option_lang_mask |
1428 | #undef LANG_HOOKS_COMPLAIN_WRONG_LANG_P |
1429 | #define LANG_HOOKS_COMPLAIN_WRONG_LANG_P lto_complain_wrong_lang_p |
1430 | #undef LANG_HOOKS_INIT_OPTIONS_STRUCT |
1431 | #define LANG_HOOKS_INIT_OPTIONS_STRUCT lto_init_options_struct |
1432 | #undef LANG_HOOKS_REGISTER_DUMPS |
1433 | #define LANG_HOOKS_REGISTER_DUMPS lto_register_dumps |
1434 | #undef LANG_HOOKS_HANDLE_OPTION |
1435 | #define LANG_HOOKS_HANDLE_OPTION lto_handle_option |
1436 | #undef LANG_HOOKS_POST_OPTIONS |
1437 | #define LANG_HOOKS_POST_OPTIONS lto_post_options |
1438 | #undef LANG_HOOKS_GET_ALIAS_SET |
1439 | #define LANG_HOOKS_GET_ALIAS_SET gimple_get_alias_set |
1440 | #undef LANG_HOOKS_TYPE_FOR_MODE |
1441 | #define LANG_HOOKS_TYPE_FOR_MODE lto_type_for_mode |
1442 | #undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME |
1443 | #define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME lto_set_decl_assembler_name |
1444 | #undef LANG_HOOKS_GLOBAL_BINDINGS_P |
1445 | #define LANG_HOOKS_GLOBAL_BINDINGS_P lto_global_bindings_p |
1446 | #undef LANG_HOOKS_PUSHDECL |
1447 | #define LANG_HOOKS_PUSHDECL lto_pushdecl |
1448 | #undef LANG_HOOKS_GETDECLS |
1449 | #define LANG_HOOKS_GETDECLS lto_getdecls |
1450 | #undef LANG_HOOKS_REGISTER_BUILTIN_TYPE |
1451 | #define LANG_HOOKS_REGISTER_BUILTIN_TYPE lto_register_builtin_type |
1452 | #undef LANG_HOOKS_BUILTIN_FUNCTION |
1453 | #define LANG_HOOKS_BUILTIN_FUNCTION lto_builtin_function |
1454 | #undef LANG_HOOKS_INIT |
1455 | #define LANG_HOOKS_INIT lto_init |
1456 | #undef LANG_HOOKS_PARSE_FILE |
1457 | #define LANG_HOOKS_PARSE_FILE lto_main |
1458 | #undef LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS |
1459 | #define LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS true |
1460 | #undef LANG_HOOKS_TYPES_COMPATIBLE_P |
1461 | #define LANG_HOOKS_TYPES_COMPATIBLE_P NULL |
1462 | #undef LANG_HOOKS_EH_PERSONALITY |
1463 | #define LANG_HOOKS_EH_PERSONALITY lto_eh_personality |
1464 | |
1465 | /* Attribute hooks. */ |
1466 | #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE |
1467 | #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE lto_attribute_table |
1468 | #undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE |
1469 | #define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE lto_format_attribute_table |
1470 | |
1471 | #undef LANG_HOOKS_BEGIN_SECTION |
1472 | #define LANG_HOOKS_BEGIN_SECTION lto_obj_begin_section |
1473 | #undef LANG_HOOKS_APPEND_DATA |
1474 | #define LANG_HOOKS_APPEND_DATA lto_obj_append_data |
1475 | #undef LANG_HOOKS_END_SECTION |
1476 | #define LANG_HOOKS_END_SECTION lto_obj_end_section |
1477 | |
1478 | #undef LANG_HOOKS_INIT_TS |
1479 | #define LANG_HOOKS_INIT_TS lto_init_ts |
1480 | |
1481 | struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; |
1482 | |
1483 | /* Language hooks that are not part of lang_hooks. */ |
1484 | |
1485 | tree |
1486 | convert (tree type ATTRIBUTE_UNUSED, tree expr ATTRIBUTE_UNUSED) |
1487 | { |
1488 | gcc_unreachable (); |
1489 | } |
1490 | |
1491 | /* Tree walking support. */ |
1492 | |
1493 | static enum lto_tree_node_structure_enum |
1494 | lto_tree_node_structure (union lang_tree_node *t ATTRIBUTE_UNUSED) |
1495 | { |
1496 | return TS_LTO_GENERIC; |
1497 | } |
1498 | |
1499 | #include "gtype-lto.h" |
1500 | #include "gt-lto-lto-lang.h" |
1501 | |