1 /* jit.c -- Dummy "frontend" for use during JIT-compilation.
2 Copyright (C) 2013-2022 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "jit-playback.h"
24 #include "stor-layout.h"
25 #include "debug.h"
26 #include "langhooks.h"
27 #include "langhooks-def.h"
28 #include "diagnostic.h"
29 #include "options.h"
30 #include "stringpool.h"
31 #include "attribs.h"
32
33 #include <mpfr.h>
34
35 /* Attribute handling. */
36
37 static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
38 static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
39 static tree handle_const_attribute (tree *, tree, tree, int, bool *);
40 static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
41 static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
42 static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
43 static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
44 static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
45 static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
46 static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
47 static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *);
48 static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
49 static tree handle_patchable_function_entry_attribute (tree *, tree, tree,
50 int, bool *);
51 static tree ignore_attribute (tree *, tree, tree, int, bool *);
52
53 static tree handle_format_attribute (tree *, tree, tree, int, bool *);
54 static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
55 static tree handle_format_arg_attribute (tree *, tree, tree, int, bool *);
56
57 /* Helper to define attribute exclusions. */
58 #define ATTR_EXCL(name, function, type, variable) \
59 { name, function, type, variable }
60
61 /* Define attributes that are mutually exclusive with one another. */
62 static const struct attribute_spec::exclusions attr_noreturn_exclusions[] =
63 {
64 ATTR_EXCL ("noreturn", true, true, true),
65 ATTR_EXCL ("alloc_align", true, true, true),
66 ATTR_EXCL ("alloc_size", true, true, true),
67 ATTR_EXCL ("const", true, true, true),
68 ATTR_EXCL ("malloc", true, true, true),
69 ATTR_EXCL ("pure", true, true, true),
70 ATTR_EXCL ("returns_twice", true, true, true),
71 ATTR_EXCL ("warn_unused_result", true, true, true),
72 ATTR_EXCL (NULL, false, false, false),
73 };
74
75 static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] =
76 {
77 ATTR_EXCL ("noreturn", true, true, true),
78 ATTR_EXCL (NULL, false, false, false),
79 };
80
81 static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
82 {
83 ATTR_EXCL ("const", true, true, true),
84 ATTR_EXCL ("noreturn", true, true, true),
85 ATTR_EXCL ("pure", true, true, true),
86 ATTR_EXCL (NULL, false, false, false)
87 };
88
89 /* Table of machine-independent attributes supported in libgccjit. */
90 const struct attribute_spec jit_attribute_table[] =
91 {
92 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
93 affects_type_identity, handler, exclude } */
94 { "noreturn", 0, 0, true, false, false, false,
95 handle_noreturn_attribute,
96 attr_noreturn_exclusions },
97 { "leaf", 0, 0, true, false, false, false,
98 handle_leaf_attribute, NULL },
99 /* The same comments as for noreturn attributes apply to const ones. */
100 { "const", 0, 0, true, false, false, false,
101 handle_const_attribute,
102 attr_const_pure_exclusions },
103 { "malloc", 0, 0, true, false, false, false,
104 handle_malloc_attribute, NULL },
105 { "pure", 0, 0, true, false, false, false,
106 handle_pure_attribute,
107 attr_const_pure_exclusions },
108 { "no vops", 0, 0, true, false, false, false,
109 handle_novops_attribute, NULL },
110 { "nonnull", 0, -1, false, true, true, false,
111 handle_nonnull_attribute, NULL },
112 { "nothrow", 0, 0, true, false, false, false,
113 handle_nothrow_attribute, NULL },
114 { "patchable_function_entry", 1, 2, true, false, false, false,
115 handle_patchable_function_entry_attribute,
116 NULL },
117 { "returns_twice", 0, 0, true, false, false, false,
118 handle_returns_twice_attribute,
119 attr_returns_twice_exclusions },
120 { "sentinel", 0, 1, false, true, true, false,
121 handle_sentinel_attribute, NULL },
122 { "type generic", 0, 0, false, true, true, false,
123 handle_type_generic_attribute, NULL },
124 { "fn spec", 1, 1, false, true, true, false,
125 handle_fnspec_attribute, NULL },
126 { "transaction_pure", 0, 0, false, true, true, false,
127 handle_transaction_pure_attribute, NULL },
128 /* For internal use only. The leading '*' both prevents its usage in
129 source code and signals that it may be overridden by machine tables. */
130 { "*tm regparm", 0, 0, false, true, true, false,
131 ignore_attribute, NULL },
132 { NULL, 0, 0, false, false, false, false, NULL, NULL }
133 };
134
135 /* Give the specifications for the format attributes, used by C and all
136 descendants. */
137
138 const struct attribute_spec jit_format_attribute_table[] =
139 {
140 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
141 affects_type_identity, handler, exclude } */
142 { "format", 3, 3, false, true, true, false,
143 handle_format_attribute, NULL },
144 { "format_arg", 1, 1, false, true, true, false,
145 handle_format_arg_attribute, NULL },
146 { NULL, 0, 0, false, false, false, false, NULL, NULL }
147 };
148
149 /* Attribute handlers. */
150
151 /* Handle a "noreturn" attribute; arguments as in
152 struct attribute_spec.handler. */
153
154 static tree
handle_noreturn_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))155 handle_noreturn_attribute (tree *node, tree ARG_UNUSED (name),
156 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
157 bool * ARG_UNUSED (no_add_attrs))
158 {
159 tree type = TREE_TYPE (*node);
160
161 if (TREE_CODE (*node) == FUNCTION_DECL)
162 TREE_THIS_VOLATILE (*node) = 1;
163 else if (TREE_CODE (type) == POINTER_TYPE
164 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
165 TREE_TYPE (*node)
166 = build_pointer_type
167 (build_type_variant (TREE_TYPE (type),
168 TYPE_READONLY (TREE_TYPE (type)), 1));
169 else
170 gcc_unreachable ();
171
172 return NULL_TREE;
173 }
174
175 /* Handle a "leaf" attribute; arguments as in
176 struct attribute_spec.handler. */
177
178 static tree
handle_leaf_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)179 handle_leaf_attribute (tree *node, tree name,
180 tree ARG_UNUSED (args),
181 int ARG_UNUSED (flags), bool *no_add_attrs)
182 {
183 if (TREE_CODE (*node) != FUNCTION_DECL)
184 {
185 warning (OPT_Wattributes, "%qE attribute ignored", name);
186 *no_add_attrs = true;
187 }
188 if (!TREE_PUBLIC (*node))
189 {
190 warning (OPT_Wattributes, "%qE attribute has no effect on unit local functions", name);
191 *no_add_attrs = true;
192 }
193
194 return NULL_TREE;
195 }
196
197 /* Handle a "const" attribute; arguments as in
198 struct attribute_spec.handler. */
199
200 static tree
handle_const_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))201 handle_const_attribute (tree *node, tree ARG_UNUSED (name),
202 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
203 bool * ARG_UNUSED (no_add_attrs))
204 {
205 if (TREE_CODE (*node) != FUNCTION_DECL
206 || !fndecl_built_in_p (*node))
207 inform (UNKNOWN_LOCATION, "%s:%s: %E: %E", __FILE__, __func__, *node, name);
208
209 tree type = TREE_TYPE (*node);
210
211 /* See FIXME comment on noreturn in c_common_attribute_table. */
212 if (TREE_CODE (*node) == FUNCTION_DECL)
213 TREE_READONLY (*node) = 1;
214 else if (TREE_CODE (type) == POINTER_TYPE
215 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
216 TREE_TYPE (*node)
217 = build_pointer_type
218 (build_type_variant (TREE_TYPE (type), 1,
219 TREE_THIS_VOLATILE (TREE_TYPE (type))));
220 else
221 gcc_unreachable ();
222
223 return NULL_TREE;
224 }
225
226
227 /* Handle a "malloc" attribute; arguments as in
228 struct attribute_spec.handler. */
229
230 static tree
handle_malloc_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))231 handle_malloc_attribute (tree *node, tree ARG_UNUSED (name),
232 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
233 bool * ARG_UNUSED (no_add_attrs))
234 {
235 if (TREE_CODE (*node) == FUNCTION_DECL
236 && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))))
237 DECL_IS_MALLOC (*node) = 1;
238 else
239 gcc_unreachable ();
240
241 return NULL_TREE;
242 }
243
244
245 /* Handle a "pure" attribute; arguments as in
246 struct attribute_spec.handler. */
247
248 static tree
handle_pure_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))249 handle_pure_attribute (tree *node, tree ARG_UNUSED (name),
250 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
251 bool * ARG_UNUSED (no_add_attrs))
252 {
253 if (TREE_CODE (*node) == FUNCTION_DECL)
254 DECL_PURE_P (*node) = 1;
255 else
256 gcc_unreachable ();
257
258 return NULL_TREE;
259 }
260
261
262 /* Handle a "no vops" attribute; arguments as in
263 struct attribute_spec.handler. */
264
265 static tree
handle_novops_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))266 handle_novops_attribute (tree *node, tree ARG_UNUSED (name),
267 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
268 bool *ARG_UNUSED (no_add_attrs))
269 {
270 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
271 DECL_IS_NOVOPS (*node) = 1;
272 return NULL_TREE;
273 }
274
275
276 /* Helper for nonnull attribute handling; fetch the operand number
277 from the attribute argument list. */
278
279 static bool
get_nonnull_operand(tree arg_num_expr,unsigned HOST_WIDE_INT * valp)280 get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
281 {
282 /* Verify the arg number is a constant. */
283 if (!tree_fits_uhwi_p (arg_num_expr))
284 return false;
285
286 *valp = TREE_INT_CST_LOW (arg_num_expr);
287 return true;
288 }
289
290 /* Handle the "nonnull" attribute. */
291
292 static tree
handle_nonnull_attribute(tree * node,tree ARG_UNUSED (name),tree args,int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))293 handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
294 tree args, int ARG_UNUSED (flags),
295 bool * ARG_UNUSED (no_add_attrs))
296 {
297 tree type = *node;
298
299 /* If no arguments are specified, all pointer arguments should be
300 non-null. Verify a full prototype is given so that the arguments
301 will have the correct types when we actually check them later.
302 Avoid diagnosing type-generic built-ins since those have no
303 prototype. */
304 if (!args)
305 {
306 gcc_assert (prototype_p (type)
307 || !TYPE_ATTRIBUTES (type)
308 || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type)));
309
310 return NULL_TREE;
311 }
312
313 /* Argument list specified. Verify that each argument number references
314 a pointer argument. */
315 for (; args; args = TREE_CHAIN (args))
316 {
317 tree argument;
318 unsigned HOST_WIDE_INT arg_num = 0, ck_num;
319
320 if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))
321 gcc_unreachable ();
322
323 argument = TYPE_ARG_TYPES (type);
324 if (argument)
325 {
326 for (ck_num = 1; ; ck_num++)
327 {
328 if (!argument || ck_num == arg_num)
329 break;
330 argument = TREE_CHAIN (argument);
331 }
332
333 gcc_assert (argument
334 && TREE_CODE (TREE_VALUE (argument)) == POINTER_TYPE);
335 }
336 }
337
338 return NULL_TREE;
339 }
340
341
342 /* Handle a "nothrow" attribute; arguments as in
343 struct attribute_spec.handler. */
344
345 static tree
handle_nothrow_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))346 handle_nothrow_attribute (tree *node, tree ARG_UNUSED (name),
347 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
348 bool * ARG_UNUSED (no_add_attrs))
349 {
350 if (TREE_CODE (*node) == FUNCTION_DECL)
351 TREE_NOTHROW (*node) = 1;
352 else
353 gcc_unreachable ();
354
355 return NULL_TREE;
356 }
357
358
359 /* Handle a "sentinel" attribute. */
360
361 static tree
handle_sentinel_attribute(tree * node,tree ARG_UNUSED (name),tree args,int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))362 handle_sentinel_attribute (tree *node, tree ARG_UNUSED (name), tree args,
363 int ARG_UNUSED (flags),
364 bool * ARG_UNUSED (no_add_attrs))
365 {
366 gcc_assert (stdarg_p (*node));
367
368 if (args)
369 {
370 tree position = TREE_VALUE (args);
371 gcc_assert (TREE_CODE (position) == INTEGER_CST);
372 if (tree_int_cst_lt (position, integer_zero_node))
373 gcc_unreachable ();
374 }
375
376 return NULL_TREE;
377 }
378
379 /* Handle a "type_generic" attribute. */
380
381 static tree
handle_type_generic_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))382 handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name),
383 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
384 bool * ARG_UNUSED (no_add_attrs))
385 {
386 /* Ensure we have a function type. */
387 gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
388
389 /* Ensure we have a variadic function. */
390 gcc_assert (!prototype_p (*node) || stdarg_p (*node));
391
392 return NULL_TREE;
393 }
394
395 /* Handle a "transaction_pure" attribute. */
396
397 static tree
handle_transaction_pure_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))398 handle_transaction_pure_attribute (tree *node, tree ARG_UNUSED (name),
399 tree ARG_UNUSED (args),
400 int ARG_UNUSED (flags),
401 bool * ARG_UNUSED (no_add_attrs))
402 {
403 /* Ensure we have a function type. */
404 gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
405
406 return NULL_TREE;
407 }
408
409 /* Handle a "returns_twice" attribute. */
410
411 static tree
handle_returns_twice_attribute(tree * node,tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))412 handle_returns_twice_attribute (tree *node, tree ARG_UNUSED (name),
413 tree ARG_UNUSED (args),
414 int ARG_UNUSED (flags),
415 bool * ARG_UNUSED (no_add_attrs))
416 {
417 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
418
419 DECL_IS_RETURNS_TWICE (*node) = 1;
420
421 return NULL_TREE;
422 }
423
424 static tree
handle_patchable_function_entry_attribute(tree *,tree,tree,int,bool *)425 handle_patchable_function_entry_attribute (tree *, tree, tree, int, bool *)
426 {
427 /* Nothing to be done here. */
428 return NULL_TREE;
429 }
430
431 /* Ignore the given attribute. Used when this attribute may be usefully
432 overridden by the target, but is not used generically. */
433
434 static tree
ignore_attribute(tree * ARG_UNUSED (node),tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)435 ignore_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
436 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
437 bool *no_add_attrs)
438 {
439 *no_add_attrs = true;
440 return NULL_TREE;
441 }
442
443 /* Handle a "format" attribute; arguments as in
444 struct attribute_spec.handler. */
445
446 static tree
handle_format_attribute(tree * ARG_UNUSED (node),tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)447 handle_format_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
448 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
449 bool *no_add_attrs)
450 {
451 *no_add_attrs = true;
452 return NULL_TREE;
453 }
454
455
456 /* Handle a "format_arg" attribute; arguments as in
457 struct attribute_spec.handler. */
458
459 tree
handle_format_arg_attribute(tree * ARG_UNUSED (node),tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)460 handle_format_arg_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
461 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
462 bool *no_add_attrs)
463 {
464 *no_add_attrs = true;
465 return NULL_TREE;
466 }
467
468
469 /* Handle a "fn spec" attribute; arguments as in
470 struct attribute_spec.handler. */
471
472 static tree
handle_fnspec_attribute(tree * node ATTRIBUTE_UNUSED,tree ARG_UNUSED (name),tree args,int ARG_UNUSED (flags),bool * no_add_attrs ATTRIBUTE_UNUSED)473 handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name),
474 tree args, int ARG_UNUSED (flags),
475 bool *no_add_attrs ATTRIBUTE_UNUSED)
476 {
477 gcc_assert (args
478 && TREE_CODE (TREE_VALUE (args)) == STRING_CST
479 && !TREE_CHAIN (args));
480 return NULL_TREE;
481 }
482
483 /* (end of attribute-handling). */
484
485 /* Language-dependent contents of a type. */
486
487 struct GTY(()) lang_type
488 {
489 char dummy;
490 };
491
492 /* Language-dependent contents of a decl. */
493
494 struct GTY((variable_size)) lang_decl
495 {
496 char dummy;
497 };
498
499 /* Language-dependent contents of an identifier. This must include a
500 tree_identifier. */
501
502 struct GTY(()) lang_identifier
503 {
504 struct tree_identifier common;
505 };
506
507 /* The resulting tree type. */
508
509 union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
510 chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
511 lang_tree_node
512 {
513 union tree_node GTY((tag ("0"),
514 desc ("tree_node_structure (&%h)"))) generic;
515 struct lang_identifier GTY((tag ("1"))) identifier;
516 };
517
518 /* We don't use language_function. */
519
520 struct GTY(()) language_function
521 {
522 int dummy;
523 };
524
525 /* GC-marking callback for use from jit_root_tab.
526
527 If there's an active playback context, call its marking method
528 so that it can mark any pointers it references. */
529
my_ggc_walker(void *)530 static void my_ggc_walker (void *)
531 {
532 if (gcc::jit::active_playback_ctxt)
533 gcc::jit::active_playback_ctxt->gt_ggc_mx ();
534 }
535
536 const char *dummy;
537
538 struct ggc_root_tab jit_root_tab[] =
539 {
540 {
541 &dummy, 1, 0, my_ggc_walker, NULL
542 },
543 LAST_GGC_ROOT_TAB
544 };
545
546 /* JIT-specific implementation of diagnostic callbacks. */
547
548 /* Implementation of "begin_diagnostic". */
549
550 static void
jit_begin_diagnostic(diagnostic_context *,diagnostic_info *)551 jit_begin_diagnostic (diagnostic_context */*context*/,
552 diagnostic_info */*diagnostic*/)
553 {
554 gcc_assert (gcc::jit::active_playback_ctxt);
555 JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
556
557 /* No-op (apart from logging); the real error-handling is done in the
558 "end_diagnostic" hook. */
559 }
560
561 /* Implementation of "end_diagnostic". */
562
563 static void
jit_end_diagnostic(diagnostic_context * context,diagnostic_info * diagnostic,diagnostic_t)564 jit_end_diagnostic (diagnostic_context *context,
565 diagnostic_info *diagnostic,
566 diagnostic_t)
567 {
568 gcc_assert (gcc::jit::active_playback_ctxt);
569 JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
570
571 /* Delegate to the playback context (and thence to the
572 recording context). */
573 gcc::jit::active_playback_ctxt->add_diagnostic (context, diagnostic);
574 }
575
576 /* Language hooks. */
577
578 static bool
jit_langhook_init(void)579 jit_langhook_init (void)
580 {
581 gcc_assert (gcc::jit::active_playback_ctxt);
582 JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
583
584 static bool registered_root_tab = false;
585 if (!registered_root_tab)
586 {
587 ggc_register_root_tab (jit_root_tab);
588 registered_root_tab = true;
589 }
590
591 gcc_assert (global_dc);
592 global_dc->begin_diagnostic = jit_begin_diagnostic;
593 global_dc->end_diagnostic = jit_end_diagnostic;
594
595 build_common_tree_nodes (false);
596
597 /* I don't know why this has to be done explicitly. */
598 void_list_node = build_tree_list (NULL_TREE, void_type_node);
599
600 build_common_builtin_nodes ();
601
602 /* The default precision for floating point numbers. This is used
603 for floating point constants with abstract type. This may
604 eventually be controllable by a command line option. */
605 mpfr_set_default_prec (256);
606
607 return true;
608 }
609
610 static void
jit_langhook_parse_file(void)611 jit_langhook_parse_file (void)
612 {
613 /* Replay the activity by the client, recorded on the context. */
614 gcc_assert (gcc::jit::active_playback_ctxt);
615 gcc::jit::active_playback_ctxt->replay ();
616 }
617
618 static tree
jit_langhook_type_for_mode(machine_mode mode,int unsignedp)619 jit_langhook_type_for_mode (machine_mode mode, int unsignedp)
620 {
621 /* Build any vector types here (see PR 46805). */
622 if (VECTOR_MODE_P (mode))
623 {
624 tree inner;
625
626 inner = jit_langhook_type_for_mode (GET_MODE_INNER (mode), unsignedp);
627 if (inner != NULL_TREE)
628 return build_vector_type_for_mode (inner, mode);
629 return NULL_TREE;
630 }
631
632 if (mode == TYPE_MODE (float_type_node))
633 return float_type_node;
634
635 if (mode == TYPE_MODE (double_type_node))
636 return double_type_node;
637
638 if (mode == TYPE_MODE (intQI_type_node))
639 return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
640 if (mode == TYPE_MODE (intHI_type_node))
641 return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
642 if (mode == TYPE_MODE (intSI_type_node))
643 return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
644 if (mode == TYPE_MODE (intDI_type_node))
645 return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
646 if (mode == TYPE_MODE (intTI_type_node))
647 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
648
649 if (mode == TYPE_MODE (integer_type_node))
650 return unsignedp ? unsigned_type_node : integer_type_node;
651
652 if (mode == TYPE_MODE (long_integer_type_node))
653 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
654
655 if (mode == TYPE_MODE (long_long_integer_type_node))
656 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
657
658 if (COMPLEX_MODE_P (mode))
659 {
660 if (mode == TYPE_MODE (complex_float_type_node))
661 return complex_float_type_node;
662 if (mode == TYPE_MODE (complex_double_type_node))
663 return complex_double_type_node;
664 if (mode == TYPE_MODE (complex_long_double_type_node))
665 return complex_long_double_type_node;
666 if (mode == TYPE_MODE (complex_integer_type_node) && !unsignedp)
667 return complex_integer_type_node;
668 }
669
670 /* gcc_unreachable */
671 return NULL;
672 }
673
674 /* Record a builtin function. We just ignore builtin functions. */
675
676 static tree
jit_langhook_builtin_function(tree decl)677 jit_langhook_builtin_function (tree decl)
678 {
679 return decl;
680 }
681
682 static bool
jit_langhook_global_bindings_p(void)683 jit_langhook_global_bindings_p (void)
684 {
685 return true;
686 }
687
688 static tree
jit_langhook_pushdecl(tree decl ATTRIBUTE_UNUSED)689 jit_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED)
690 {
691 gcc_unreachable ();
692 }
693
694 static tree
jit_langhook_getdecls(void)695 jit_langhook_getdecls (void)
696 {
697 return NULL;
698 }
699
700 #undef LANG_HOOKS_NAME
701 #define LANG_HOOKS_NAME "libgccjit"
702
703 #undef LANG_HOOKS_INIT
704 #define LANG_HOOKS_INIT jit_langhook_init
705
706 #undef LANG_HOOKS_PARSE_FILE
707 #define LANG_HOOKS_PARSE_FILE jit_langhook_parse_file
708
709 #undef LANG_HOOKS_TYPE_FOR_MODE
710 #define LANG_HOOKS_TYPE_FOR_MODE jit_langhook_type_for_mode
711
712 #undef LANG_HOOKS_BUILTIN_FUNCTION
713 #define LANG_HOOKS_BUILTIN_FUNCTION jit_langhook_builtin_function
714
715 #undef LANG_HOOKS_GLOBAL_BINDINGS_P
716 #define LANG_HOOKS_GLOBAL_BINDINGS_P jit_langhook_global_bindings_p
717
718 #undef LANG_HOOKS_PUSHDECL
719 #define LANG_HOOKS_PUSHDECL jit_langhook_pushdecl
720
721 #undef LANG_HOOKS_GETDECLS
722 #define LANG_HOOKS_GETDECLS jit_langhook_getdecls
723
724 /* Attribute hooks. */
725 #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
726 #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE jit_attribute_table
727 #undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE
728 #define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE jit_format_attribute_table
729
730 #undef LANG_HOOKS_DEEP_UNSHARING
731 #define LANG_HOOKS_DEEP_UNSHARING true
732
733 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
734
735 #include "gt-jit-dummy-frontend.h"
736 #include "gtype-jit.h"
737