1 /* jit.c -- Dummy "frontend" for use during JIT-compilation.
2 Copyright (C) 2013-2023 Free Software Foundation, Inc.
4 This file is part of GCC.
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
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
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/>. */
22 #include "coretypes.h"
23 #include "jit-playback.h"
24 #include "stor-layout.h"
26 #include "langhooks.h"
27 #include "langhooks-def.h"
28 #include "diagnostic.h"
30 #include "stringpool.h"
35 /* Attribute handling. */
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
,
51 static tree
ignore_attribute (tree
*, tree
, tree
, int, bool *);
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 *);
57 /* Helper to define attribute exclusions. */
58 #define ATTR_EXCL(name, function, type, variable) \
59 { name, function, type, variable }
61 /* Define attributes that are mutually exclusive with one another. */
62 static const struct attribute_spec::exclusions attr_noreturn_exclusions
[] =
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),
75 static const struct attribute_spec::exclusions attr_returns_twice_exclusions
[] =
77 ATTR_EXCL ("noreturn", true, true, true),
78 ATTR_EXCL (NULL
, false, false, false),
81 static const struct attribute_spec::exclusions attr_const_pure_exclusions
[] =
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)
89 /* Table of machine-independent attributes supported in libgccjit. */
90 const struct attribute_spec jit_attribute_table
[] =
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
,
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
}
135 /* Give the specifications for the format attributes, used by C and all
138 const struct attribute_spec jit_format_attribute_table
[] =
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
}
149 /* Attribute handlers. */
151 /* Handle a "noreturn" attribute; arguments as in
152 struct attribute_spec.handler. */
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
))
159 tree type
= TREE_TYPE (*node
);
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
)
167 (build_type_variant (TREE_TYPE (type
),
168 TYPE_READONLY (TREE_TYPE (type
)), 1));
175 /* Handle a "leaf" attribute; arguments as in
176 struct attribute_spec.handler. */
179 handle_leaf_attribute (tree
*node
, tree name
,
180 tree
ARG_UNUSED (args
),
181 int ARG_UNUSED (flags
), bool *no_add_attrs
)
183 if (TREE_CODE (*node
) != FUNCTION_DECL
)
185 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
186 *no_add_attrs
= true;
188 if (!TREE_PUBLIC (*node
))
190 warning (OPT_Wattributes
, "%qE attribute has no effect on unit local functions", name
);
191 *no_add_attrs
= true;
197 /* Handle a "const" attribute; arguments as in
198 struct attribute_spec.handler. */
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
))
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
);
209 tree type
= TREE_TYPE (*node
);
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
)
218 (build_type_variant (TREE_TYPE (type
), 1,
219 TREE_THIS_VOLATILE (TREE_TYPE (type
))));
227 /* Handle a "malloc" attribute; arguments as in
228 struct attribute_spec.handler. */
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
))
235 if (TREE_CODE (*node
) == FUNCTION_DECL
236 && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node
))))
237 DECL_IS_MALLOC (*node
) = 1;
245 /* Handle a "pure" attribute; arguments as in
246 struct attribute_spec.handler. */
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
))
253 if (TREE_CODE (*node
) == FUNCTION_DECL
)
254 DECL_PURE_P (*node
) = 1;
262 /* Handle a "no vops" attribute; arguments as in
263 struct attribute_spec.handler. */
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
))
270 gcc_assert (TREE_CODE (*node
) == FUNCTION_DECL
);
271 DECL_IS_NOVOPS (*node
) = 1;
276 /* Helper for nonnull attribute handling; fetch the operand number
277 from the attribute argument list. */
280 get_nonnull_operand (tree arg_num_expr
, unsigned HOST_WIDE_INT
*valp
)
282 /* Verify the arg number is a constant. */
283 if (!tree_fits_uhwi_p (arg_num_expr
))
286 *valp
= TREE_INT_CST_LOW (arg_num_expr
);
290 /* Handle the "nonnull" attribute. */
293 handle_nonnull_attribute (tree
*node
, tree
ARG_UNUSED (name
),
294 tree args
, int ARG_UNUSED (flags
),
295 bool * ARG_UNUSED (no_add_attrs
))
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
306 gcc_assert (prototype_p (type
)
307 || !TYPE_ATTRIBUTES (type
)
308 || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type
)));
313 /* Argument list specified. Verify that each argument number references
314 a pointer argument. */
315 for (; args
; args
= TREE_CHAIN (args
))
318 unsigned HOST_WIDE_INT arg_num
= 0, ck_num
;
320 if (!get_nonnull_operand (TREE_VALUE (args
), &arg_num
))
323 argument
= TYPE_ARG_TYPES (type
);
326 for (ck_num
= 1; ; ck_num
++)
328 if (!argument
|| ck_num
== arg_num
)
330 argument
= TREE_CHAIN (argument
);
334 && TREE_CODE (TREE_VALUE (argument
)) == POINTER_TYPE
);
342 /* Handle a "nothrow" attribute; arguments as in
343 struct attribute_spec.handler. */
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
))
350 if (TREE_CODE (*node
) == FUNCTION_DECL
)
351 TREE_NOTHROW (*node
) = 1;
359 /* Handle a "sentinel" attribute. */
362 handle_sentinel_attribute (tree
*node
, tree
ARG_UNUSED (name
), tree args
,
363 int ARG_UNUSED (flags
),
364 bool * ARG_UNUSED (no_add_attrs
))
366 gcc_assert (stdarg_p (*node
));
370 tree position
= TREE_VALUE (args
);
371 gcc_assert (TREE_CODE (position
) == INTEGER_CST
);
372 if (tree_int_cst_lt (position
, integer_zero_node
))
379 /* Handle a "type_generic" attribute. */
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
))
386 /* Ensure we have a function type. */
387 gcc_assert (TREE_CODE (*node
) == FUNCTION_TYPE
);
389 /* Ensure we have a variadic function. */
390 gcc_assert (!prototype_p (*node
) || stdarg_p (*node
));
395 /* Handle a "transaction_pure" attribute. */
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
))
403 /* Ensure we have a function type. */
404 gcc_assert (TREE_CODE (*node
) == FUNCTION_TYPE
);
409 /* Handle a "returns_twice" attribute. */
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
))
417 gcc_assert (TREE_CODE (*node
) == FUNCTION_DECL
);
419 DECL_IS_RETURNS_TWICE (*node
) = 1;
425 handle_patchable_function_entry_attribute (tree
*, tree
, tree
, int, bool *)
427 /* Nothing to be done here. */
431 /* Ignore the given attribute. Used when this attribute may be usefully
432 overridden by the target, but is not used generically. */
435 ignore_attribute (tree
* ARG_UNUSED (node
), tree
ARG_UNUSED (name
),
436 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
439 *no_add_attrs
= true;
443 /* Handle a "format" attribute; arguments as in
444 struct attribute_spec.handler. */
447 handle_format_attribute (tree
* ARG_UNUSED (node
), tree
ARG_UNUSED (name
),
448 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
451 *no_add_attrs
= true;
456 /* Handle a "format_arg" attribute; arguments as in
457 struct attribute_spec.handler. */
460 handle_format_arg_attribute (tree
* ARG_UNUSED (node
), tree
ARG_UNUSED (name
),
461 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
464 *no_add_attrs
= true;
469 /* Handle a "fn spec" attribute; arguments as in
470 struct attribute_spec.handler. */
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
)
478 && TREE_CODE (TREE_VALUE (args
)) == STRING_CST
479 && !TREE_CHAIN (args
));
483 /* (end of attribute-handling). */
485 /* Language-dependent contents of a type. */
487 struct GTY(()) lang_type
492 /* Language-dependent contents of a decl. */
494 struct GTY((variable_size
)) lang_decl
499 /* Language-dependent contents of an identifier. This must include a
502 struct GTY(()) lang_identifier
504 struct tree_identifier common
;
507 /* The resulting tree type. */
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")))
513 union tree_node
GTY((tag ("0"),
514 desc ("tree_node_structure (&%h)"))) generic
;
515 struct lang_identifier
GTY((tag ("1"))) identifier
;
518 /* We don't use language_function. */
520 struct GTY(()) language_function
525 /* GC-marking callback for use from jit_root_tab.
527 If there's an active playback context, call its marking method
528 so that it can mark any pointers it references. */
530 static void my_ggc_walker (void *)
532 if (gcc::jit::active_playback_ctxt
)
533 gcc::jit::active_playback_ctxt
->gt_ggc_mx ();
538 struct ggc_root_tab jit_root_tab
[] =
541 &dummy
, 1, 0, my_ggc_walker
, NULL
546 /* JIT-specific implementation of diagnostic callbacks. */
548 /* Implementation of "begin_diagnostic". */
551 jit_begin_diagnostic (diagnostic_context */
*context*/
,
552 diagnostic_info */
*diagnostic*/
)
554 gcc_assert (gcc::jit::active_playback_ctxt
);
555 JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt
->get_logger ());
557 /* No-op (apart from logging); the real error-handling is done in the
558 "end_diagnostic" hook. */
561 /* Implementation of "end_diagnostic". */
564 jit_end_diagnostic (diagnostic_context
*context
,
565 diagnostic_info
*diagnostic
,
568 gcc_assert (gcc::jit::active_playback_ctxt
);
569 JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt
->get_logger ());
571 /* Delegate to the playback context (and thence to the
572 recording context). */
573 gcc::jit::active_playback_ctxt
->add_diagnostic (context
, diagnostic
);
576 /* Language hooks. */
579 jit_langhook_init (void)
581 gcc_assert (gcc::jit::active_playback_ctxt
);
582 JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt
->get_logger ());
584 static bool registered_root_tab
= false;
585 if (!registered_root_tab
)
587 ggc_register_root_tab (jit_root_tab
);
588 registered_root_tab
= true;
591 gcc_assert (global_dc
);
592 diagnostic_starter (global_dc
) = jit_begin_diagnostic
;
593 diagnostic_finalizer (global_dc
) = jit_end_diagnostic
;
595 build_common_tree_nodes (false);
597 build_common_builtin_nodes ();
599 /* The default precision for floating point numbers. This is used
600 for floating point constants with abstract type. This may
601 eventually be controllable by a command line option. */
602 mpfr_set_default_prec (256);
608 jit_langhook_parse_file (void)
610 /* Replay the activity by the client, recorded on the context. */
611 gcc_assert (gcc::jit::active_playback_ctxt
);
612 gcc::jit::active_playback_ctxt
->replay ();
616 jit_langhook_type_for_mode (machine_mode mode
, int unsignedp
)
618 /* Build any vector types here (see PR 46805). */
619 if (VECTOR_MODE_P (mode
))
623 inner
= jit_langhook_type_for_mode (GET_MODE_INNER (mode
), unsignedp
);
624 if (inner
!= NULL_TREE
)
625 return build_vector_type_for_mode (inner
, mode
);
629 if (mode
== TYPE_MODE (float_type_node
))
630 return float_type_node
;
632 if (mode
== TYPE_MODE (double_type_node
))
633 return double_type_node
;
635 if (mode
== TYPE_MODE (intQI_type_node
))
636 return unsignedp
? unsigned_intQI_type_node
: intQI_type_node
;
637 if (mode
== TYPE_MODE (intHI_type_node
))
638 return unsignedp
? unsigned_intHI_type_node
: intHI_type_node
;
639 if (mode
== TYPE_MODE (intSI_type_node
))
640 return unsignedp
? unsigned_intSI_type_node
: intSI_type_node
;
641 if (mode
== TYPE_MODE (intDI_type_node
))
642 return unsignedp
? unsigned_intDI_type_node
: intDI_type_node
;
643 if (mode
== TYPE_MODE (intTI_type_node
))
644 return unsignedp
? unsigned_intTI_type_node
: intTI_type_node
;
646 if (mode
== TYPE_MODE (integer_type_node
))
647 return unsignedp
? unsigned_type_node
: integer_type_node
;
649 if (mode
== TYPE_MODE (long_integer_type_node
))
650 return unsignedp
? long_unsigned_type_node
: long_integer_type_node
;
652 if (mode
== TYPE_MODE (long_long_integer_type_node
))
653 return unsignedp
? long_long_unsigned_type_node
: long_long_integer_type_node
;
655 if (COMPLEX_MODE_P (mode
))
657 if (mode
== TYPE_MODE (complex_float_type_node
))
658 return complex_float_type_node
;
659 if (mode
== TYPE_MODE (complex_double_type_node
))
660 return complex_double_type_node
;
661 if (mode
== TYPE_MODE (complex_long_double_type_node
))
662 return complex_long_double_type_node
;
663 if (mode
== TYPE_MODE (complex_integer_type_node
) && !unsignedp
)
664 return complex_integer_type_node
;
667 /* gcc_unreachable */
671 /* Record a builtin function. We just ignore builtin functions. */
674 jit_langhook_builtin_function (tree decl
)
680 jit_langhook_global_bindings_p (void)
686 jit_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED
)
692 jit_langhook_getdecls (void)
697 #undef LANG_HOOKS_NAME
698 #define LANG_HOOKS_NAME "libgccjit"
700 #undef LANG_HOOKS_INIT
701 #define LANG_HOOKS_INIT jit_langhook_init
703 #undef LANG_HOOKS_PARSE_FILE
704 #define LANG_HOOKS_PARSE_FILE jit_langhook_parse_file
706 #undef LANG_HOOKS_TYPE_FOR_MODE
707 #define LANG_HOOKS_TYPE_FOR_MODE jit_langhook_type_for_mode
709 #undef LANG_HOOKS_BUILTIN_FUNCTION
710 #define LANG_HOOKS_BUILTIN_FUNCTION jit_langhook_builtin_function
712 #undef LANG_HOOKS_GLOBAL_BINDINGS_P
713 #define LANG_HOOKS_GLOBAL_BINDINGS_P jit_langhook_global_bindings_p
715 #undef LANG_HOOKS_PUSHDECL
716 #define LANG_HOOKS_PUSHDECL jit_langhook_pushdecl
718 #undef LANG_HOOKS_GETDECLS
719 #define LANG_HOOKS_GETDECLS jit_langhook_getdecls
721 /* Attribute hooks. */
722 #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
723 #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE jit_attribute_table
724 #undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE
725 #define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE jit_format_attribute_table
727 #undef LANG_HOOKS_DEEP_UNSHARING
728 #define LANG_HOOKS_DEEP_UNSHARING true
730 struct lang_hooks lang_hooks
= LANG_HOOKS_INITIALIZER
;
732 #include "gt-jit-dummy-frontend.h"
733 #include "gtype-jit.h"