1 /* jit.c -- Dummy "frontend" for use during JIT-compilation.
2 Copyright (C) 2013-2024 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"
37 /* Attribute handling. */
39 static tree
handle_alias_attribute (tree
*, tree
, tree
, int, bool *);
40 static tree
handle_always_inline_attribute (tree
*, tree
, tree
, int,
42 static tree
handle_cold_attribute (tree
*, tree
, tree
, int, bool *);
43 static tree
handle_const_attribute (tree
*, tree
, tree
, int, bool *);
44 static tree
handle_fnspec_attribute (tree
*, tree
, tree
, int, bool *);
45 static tree
handle_format_arg_attribute (tree
*, tree
, tree
, int, bool *);
46 static tree
handle_format_attribute (tree
*, tree
, tree
, int, bool *);
47 static tree
handle_leaf_attribute (tree
*, tree
, tree
, int, bool *);
48 static tree
handle_malloc_attribute (tree
*, tree
, tree
, int, bool *);
49 static tree
handle_noinline_attribute (tree
*, tree
, tree
, int, bool *);
50 static tree
handle_nonnull_attribute (tree
*, tree
, tree
, int, bool *);
51 static tree
handle_noreturn_attribute (tree
*, tree
, tree
, int, bool *);
52 static tree
handle_nothrow_attribute (tree
*, tree
, tree
, int, bool *);
53 static tree
handle_novops_attribute (tree
*, tree
, tree
, int, bool *);
54 static tree
handle_patchable_function_entry_attribute (tree
*, tree
, tree
,
56 static tree
handle_pure_attribute (tree
*, tree
, tree
, int, bool *);
57 static tree
handle_returns_twice_attribute (tree
*, tree
, tree
, int, bool *);
58 static tree
handle_sentinel_attribute (tree
*, tree
, tree
, int, bool *);
59 static tree
handle_target_attribute (tree
*, tree
, tree
, int, bool *);
60 static tree
handle_transaction_pure_attribute (tree
*, tree
, tree
, int, bool *);
61 static tree
handle_type_generic_attribute (tree
*, tree
, tree
, int, bool *);
62 static tree
handle_used_attribute (tree
*, tree
, tree
, int, bool *);
63 static tree
handle_visibility_attribute (tree
*, tree
, tree
, int,
65 static tree
handle_weak_attribute (tree
*, tree
, tree
, int, bool *) ;
67 static tree
ignore_attribute (tree
*, tree
, tree
, int, bool *);
69 /* Helper to define attribute exclusions. */
70 #define ATTR_EXCL(name, function, type, variable) \
71 { name, function, type, variable }
73 /* Define attributes that are mutually exclusive with one another. */
74 static const struct attribute_spec::exclusions attr_noreturn_exclusions
[] =
76 ATTR_EXCL ("alloc_align", true, true, true),
77 ATTR_EXCL ("alloc_size", true, true, true),
78 ATTR_EXCL ("const", true, true, true),
79 ATTR_EXCL ("malloc", true, true, true),
80 ATTR_EXCL ("pure", true, true, true),
81 ATTR_EXCL ("returns_twice", true, true, true),
82 ATTR_EXCL ("warn_unused_result", true, true, true),
83 ATTR_EXCL (NULL
, false, false, false),
86 static const struct attribute_spec::exclusions attr_returns_twice_exclusions
[] =
88 ATTR_EXCL ("noreturn", true, true, true),
89 ATTR_EXCL (NULL
, false, false, false),
92 /* Exclusions that apply to attribute alloc_align, alloc_size, and malloc. */
93 static const struct attribute_spec::exclusions attr_alloc_exclusions
[] =
95 ATTR_EXCL ("const", true, true, true),
96 ATTR_EXCL ("noreturn", true, true, true),
97 ATTR_EXCL ("pure", true, true, true),
98 ATTR_EXCL (NULL
, false, false, false),
101 static const struct attribute_spec::exclusions attr_const_pure_exclusions
[] =
103 ATTR_EXCL ("const", true, true, true),
104 ATTR_EXCL ("alloc_align", true, true, true),
105 ATTR_EXCL ("alloc_size", true, true, true),
106 ATTR_EXCL ("malloc", true, true, true),
107 ATTR_EXCL ("noreturn", true, true, true),
108 ATTR_EXCL ("pure", true, true, true),
109 ATTR_EXCL (NULL
, false, false, false)
112 static const struct attribute_spec::exclusions attr_always_inline_exclusions
[] =
114 ATTR_EXCL ("noinline", true, true, true),
115 ATTR_EXCL ("target_clones", true, true, true),
116 ATTR_EXCL (NULL
, false, false, false),
119 extern const struct attribute_spec::exclusions attr_cold_hot_exclusions
[] =
121 ATTR_EXCL ("cold", true, true, true),
122 ATTR_EXCL ("hot", true, true, true),
123 ATTR_EXCL (NULL
, false, false, false)
126 static const struct attribute_spec::exclusions attr_noinline_exclusions
[] =
128 ATTR_EXCL ("always_inline", true, true, true),
129 ATTR_EXCL ("gnu_inline", true, true, true),
130 ATTR_EXCL (NULL
, false, false, false),
133 static const struct attribute_spec::exclusions attr_target_exclusions
[] =
135 ATTR_EXCL ("target_clones", TARGET_HAS_FMV_TARGET_ATTRIBUTE
,
136 TARGET_HAS_FMV_TARGET_ATTRIBUTE
, TARGET_HAS_FMV_TARGET_ATTRIBUTE
),
137 ATTR_EXCL (NULL
, false, false, false),
140 /* Table of machine-independent attributes supported in libgccjit. */
141 static const attribute_spec jit_gnu_attributes
[] =
143 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
144 affects_type_identity, handler, exclude } */
145 { "alias", 1, 1, true, false, false, false,
146 handle_alias_attribute
, NULL
},
147 { "always_inline", 0, 0, true, false, false, false,
148 handle_always_inline_attribute
,
149 attr_always_inline_exclusions
},
150 { "cold", 0, 0, true, false, false, false,
151 handle_cold_attribute
,
152 attr_cold_hot_exclusions
},
153 /* The same comments as for noreturn attributes apply to const ones. */
154 { "const", 0, 0, true, false, false, false,
155 handle_const_attribute
,
156 attr_const_pure_exclusions
},
157 { "fn spec", 1, 1, false, true, true, false,
158 handle_fnspec_attribute
, NULL
},
160 { "leaf", 0, 0, true, false, false, false,
161 handle_leaf_attribute
, NULL
},
162 { "malloc", 0, 0, true, false, false, false,
163 handle_malloc_attribute
, attr_alloc_exclusions
},
164 { "noreturn", 0, 0, true, false, false, false,
165 handle_noreturn_attribute
,
166 attr_noreturn_exclusions
},
167 { "no vops", 0, 0, true, false, false, false,
168 handle_novops_attribute
, NULL
},
169 { "noinline", 0, 0, true, false, false, false,
170 handle_noinline_attribute
,
171 attr_noinline_exclusions
},
172 { "nonnull", 0, -1, false, true, true, false,
173 handle_nonnull_attribute
, NULL
},
174 { "nothrow", 0, 0, true, false, false, false,
175 handle_nothrow_attribute
, NULL
},
176 { "patchable_function_entry", 1, 2, true, false, false, false,
177 handle_patchable_function_entry_attribute
,
179 { "pure", 0, 0, true, false, false, false,
180 handle_pure_attribute
,
181 attr_const_pure_exclusions
},
182 { "returns_twice", 0, 0, true, false, false, false,
183 handle_returns_twice_attribute
,
184 attr_returns_twice_exclusions
},
185 { "sentinel", 0, 1, false, true, true, false,
186 handle_sentinel_attribute
, NULL
},
187 { "target", 1, -1, true, false, false, false,
188 handle_target_attribute
, attr_target_exclusions
},
189 { "type generic", 0, 0, false, true, true, false,
190 handle_type_generic_attribute
, NULL
},
191 { "transaction_pure", 0, 0, false, true, true, false,
192 handle_transaction_pure_attribute
, NULL
},
193 { "used", 0, 0, true, false, false, false,
194 handle_used_attribute
, NULL
},
195 { "visibility", 1, 1, false, false, false, false,
196 handle_visibility_attribute
, NULL
},
197 { "weak", 0, 0, true, false, false, false,
198 handle_weak_attribute
, NULL
},
199 /* For internal use only. The leading '*' both prevents its usage in
200 source code and signals that it may be overridden by machine tables. */
201 { "*tm regparm", 0, 0, false, true, true, false,
202 ignore_attribute
, NULL
},
205 static const scoped_attribute_specs jit_gnu_attribute_table
=
207 "gnu", { jit_gnu_attributes
}
210 /* Give the specifications for the format attributes, used by C and all
213 static const attribute_spec jit_format_attributes
[] =
215 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
216 affects_type_identity, handler, exclude } */
217 { "format", 3, 3, false, true, true, false,
218 handle_format_attribute
, NULL
},
219 { "format_arg", 1, 1, false, true, true, false,
220 handle_format_arg_attribute
, NULL
}
223 static const scoped_attribute_specs jit_format_attribute_table
=
225 "gnu", { jit_format_attributes
}
228 static const scoped_attribute_specs
*const jit_attribute_table
[] =
230 &jit_gnu_attribute_table
,
231 &jit_format_attribute_table
234 /* Attribute handlers. */
236 /* Handle a "noreturn" attribute; arguments as in
237 struct attribute_spec.handler. */
240 handle_noreturn_attribute (tree
*node
, tree
ARG_UNUSED (name
),
241 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
242 bool * ARG_UNUSED (no_add_attrs
))
244 tree type
= TREE_TYPE (*node
);
246 if (TREE_CODE (*node
) == FUNCTION_DECL
)
247 TREE_THIS_VOLATILE (*node
) = 1;
248 else if (TREE_CODE (type
) == POINTER_TYPE
249 && TREE_CODE (TREE_TYPE (type
)) == FUNCTION_TYPE
)
252 (build_type_variant (TREE_TYPE (type
),
253 TYPE_READONLY (TREE_TYPE (type
)), 1));
260 /* Handle a "leaf" attribute; arguments as in
261 struct attribute_spec.handler. */
264 handle_leaf_attribute (tree
*node
, tree name
,
265 tree
ARG_UNUSED (args
),
266 int ARG_UNUSED (flags
), bool *no_add_attrs
)
268 if (TREE_CODE (*node
) != FUNCTION_DECL
)
270 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
271 *no_add_attrs
= true;
273 if (!TREE_PUBLIC (*node
))
275 warning (OPT_Wattributes
, "%qE attribute has no effect on unit local functions", name
);
276 *no_add_attrs
= true;
282 /* Handle a "const" attribute; arguments as in
283 struct attribute_spec.handler. */
286 handle_const_attribute (tree
*node
, tree name
, tree
ARG_UNUSED (args
),
287 int ARG_UNUSED (flags
), bool *no_add_attrs
)
289 tree type
= TREE_TYPE (*node
);
291 /* See FIXME comment on noreturn in c_common_attribute_table. */
292 if (TREE_CODE (*node
) == FUNCTION_DECL
)
293 TREE_READONLY (*node
) = 1;
294 else if (TREE_CODE (type
) == POINTER_TYPE
295 && TREE_CODE (TREE_TYPE (type
)) == FUNCTION_TYPE
)
297 = (build_qualified_type
299 (build_type_variant (TREE_TYPE (type
), 1,
300 TREE_THIS_VOLATILE (TREE_TYPE (type
)))),
304 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
305 *no_add_attrs
= true;
312 /* Handle a "malloc" attribute; arguments as in
313 struct attribute_spec.handler. */
316 handle_malloc_attribute (tree
*node
, tree
ARG_UNUSED (name
),
317 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
318 bool * ARG_UNUSED (no_add_attrs
))
320 if (TREE_CODE (*node
) == FUNCTION_DECL
321 && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node
))))
322 DECL_IS_MALLOC (*node
) = 1;
330 /* Handle a "pure" attribute; arguments as in
331 struct attribute_spec.handler. */
334 handle_pure_attribute (tree
*node
, tree
ARG_UNUSED (name
),
335 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
336 bool * ARG_UNUSED (no_add_attrs
))
338 if (TREE_CODE (*node
) == FUNCTION_DECL
)
339 DECL_PURE_P (*node
) = 1;
347 /* Handle a "no vops" attribute; arguments as in
348 struct attribute_spec.handler. */
351 handle_novops_attribute (tree
*node
, tree
ARG_UNUSED (name
),
352 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
353 bool *ARG_UNUSED (no_add_attrs
))
355 gcc_assert (TREE_CODE (*node
) == FUNCTION_DECL
);
356 DECL_IS_NOVOPS (*node
) = 1;
361 /* Helper for nonnull attribute handling; fetch the operand number
362 from the attribute argument list. */
365 get_nonnull_operand (tree arg_num_expr
, unsigned HOST_WIDE_INT
*valp
)
367 /* Verify the arg number is a constant. */
368 if (!tree_fits_uhwi_p (arg_num_expr
))
371 *valp
= TREE_INT_CST_LOW (arg_num_expr
);
375 /* Handle the "nonnull" attribute. */
378 handle_nonnull_attribute (tree
*node
, tree
ARG_UNUSED (name
),
379 tree args
, int ARG_UNUSED (flags
),
380 bool * ARG_UNUSED (no_add_attrs
))
384 /* If no arguments are specified, all pointer arguments should be
385 non-null. Verify a full prototype is given so that the arguments
386 will have the correct types when we actually check them later.
387 Avoid diagnosing type-generic built-ins since those have no
391 gcc_assert (prototype_p (type
)
392 || !TYPE_ATTRIBUTES (type
)
393 || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type
)));
398 /* Argument list specified. Verify that each argument number references
399 a pointer argument. */
400 for (; args
; args
= TREE_CHAIN (args
))
403 unsigned HOST_WIDE_INT arg_num
= 0, ck_num
;
405 if (!get_nonnull_operand (TREE_VALUE (args
), &arg_num
))
408 argument
= TYPE_ARG_TYPES (type
);
411 for (ck_num
= 1; ; ck_num
++)
413 if (!argument
|| ck_num
== arg_num
)
415 argument
= TREE_CHAIN (argument
);
419 && TREE_CODE (TREE_VALUE (argument
)) == POINTER_TYPE
);
427 /* Handle a "nothrow" attribute; arguments as in
428 struct attribute_spec.handler. */
431 handle_nothrow_attribute (tree
*node
, tree
ARG_UNUSED (name
),
432 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
433 bool * ARG_UNUSED (no_add_attrs
))
435 if (TREE_CODE (*node
) == FUNCTION_DECL
)
436 TREE_NOTHROW (*node
) = 1;
444 /* Handle a "sentinel" attribute. */
447 handle_sentinel_attribute (tree
*node
, tree
ARG_UNUSED (name
), tree args
,
448 int ARG_UNUSED (flags
),
449 bool * ARG_UNUSED (no_add_attrs
))
451 gcc_assert (stdarg_p (*node
));
455 tree position
= TREE_VALUE (args
);
456 gcc_assert (TREE_CODE (position
) == INTEGER_CST
);
457 if (tree_int_cst_lt (position
, integer_zero_node
))
464 /* Handle a "type_generic" attribute. */
467 handle_type_generic_attribute (tree
*node
, tree
ARG_UNUSED (name
),
468 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
469 bool * ARG_UNUSED (no_add_attrs
))
471 /* Ensure we have a function type. */
472 gcc_assert (TREE_CODE (*node
) == FUNCTION_TYPE
);
474 /* Ensure we have a variadic function. */
475 gcc_assert (!prototype_p (*node
) || stdarg_p (*node
));
480 /* Handle a "transaction_pure" attribute. */
483 handle_transaction_pure_attribute (tree
*node
, tree
ARG_UNUSED (name
),
484 tree
ARG_UNUSED (args
),
485 int ARG_UNUSED (flags
),
486 bool * ARG_UNUSED (no_add_attrs
))
488 /* Ensure we have a function type. */
489 gcc_assert (TREE_CODE (*node
) == FUNCTION_TYPE
);
494 /* Handle a "returns_twice" attribute. */
497 handle_returns_twice_attribute (tree
*node
, tree
ARG_UNUSED (name
),
498 tree
ARG_UNUSED (args
),
499 int ARG_UNUSED (flags
),
500 bool * ARG_UNUSED (no_add_attrs
))
502 gcc_assert (TREE_CODE (*node
) == FUNCTION_DECL
);
504 DECL_IS_RETURNS_TWICE (*node
) = 1;
510 handle_patchable_function_entry_attribute (tree
*, tree
, tree
, int, bool *)
512 /* Nothing to be done here. */
516 /* Ignore the given attribute. Used when this attribute may be usefully
517 overridden by the target, but is not used generically. */
520 ignore_attribute (tree
* ARG_UNUSED (node
), tree
ARG_UNUSED (name
),
521 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
524 *no_add_attrs
= true;
528 /* Handle a "format" attribute; arguments as in
529 struct attribute_spec.handler. */
532 handle_format_attribute (tree
* ARG_UNUSED (node
), tree
ARG_UNUSED (name
),
533 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
536 *no_add_attrs
= true;
541 /* Handle a "format_arg" attribute; arguments as in
542 struct attribute_spec.handler. */
545 handle_format_arg_attribute (tree
* ARG_UNUSED (node
), tree
ARG_UNUSED (name
),
546 tree
ARG_UNUSED (args
), int ARG_UNUSED (flags
),
549 *no_add_attrs
= true;
554 /* Handle a "fn spec" attribute; arguments as in
555 struct attribute_spec.handler. */
558 handle_fnspec_attribute (tree
*node ATTRIBUTE_UNUSED
, tree
ARG_UNUSED (name
),
559 tree args
, int ARG_UNUSED (flags
),
560 bool *no_add_attrs ATTRIBUTE_UNUSED
)
563 && TREE_CODE (TREE_VALUE (args
)) == STRING_CST
564 && !TREE_CHAIN (args
));
568 /* Handle an "visibility" attribute; arguments as in
569 struct attribute_spec.handler. */
572 handle_visibility_attribute (tree
*node
, tree name
, tree args
,
573 int ARG_UNUSED (flags
),
574 bool *ARG_UNUSED (no_add_attrs
))
577 tree id
= TREE_VALUE (args
);
578 enum symbol_visibility vis
;
582 if (TREE_CODE (*node
) == ENUMERAL_TYPE
)
584 else if (!RECORD_OR_UNION_TYPE_P (*node
))
586 warning (OPT_Wattributes
, "%qE attribute ignored on non-class types",
590 else if (TYPE_FIELDS (*node
))
592 error ("%qE attribute ignored because %qT is already defined",
597 else if (decl_function_context (decl
) != 0 || !TREE_PUBLIC (decl
))
599 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
603 if (TREE_CODE (id
) != STRING_CST
)
605 error ("visibility argument not a string");
609 /* If this is a type, set the visibility on the type decl. */
612 decl
= TYPE_NAME (decl
);
615 if (TREE_CODE (decl
) == IDENTIFIER_NODE
)
617 warning (OPT_Wattributes
, "%qE attribute ignored on types",
623 if (strcmp (TREE_STRING_POINTER (id
), "default") == 0)
624 vis
= VISIBILITY_DEFAULT
;
625 else if (strcmp (TREE_STRING_POINTER (id
), "internal") == 0)
626 vis
= VISIBILITY_INTERNAL
;
627 else if (strcmp (TREE_STRING_POINTER (id
), "hidden") == 0)
628 vis
= VISIBILITY_HIDDEN
;
629 else if (strcmp (TREE_STRING_POINTER (id
), "protected") == 0)
630 vis
= VISIBILITY_PROTECTED
;
633 error ("attribute %qE argument must be one of %qs, %qs, %qs, or %qs",
634 name
, "default", "hidden", "protected", "internal");
635 vis
= VISIBILITY_DEFAULT
;
638 if (DECL_VISIBILITY_SPECIFIED (decl
)
639 && vis
!= DECL_VISIBILITY (decl
))
641 tree attributes
= (TYPE_P (*node
)
642 ? TYPE_ATTRIBUTES (*node
)
643 : DECL_ATTRIBUTES (decl
));
644 if (lookup_attribute ("visibility", attributes
))
645 error ("%qD redeclared with different visibility", decl
);
646 else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
647 && lookup_attribute ("dllimport", attributes
))
648 error ("%qD was declared %qs which implies default visibility",
650 else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
651 && lookup_attribute ("dllexport", attributes
))
652 error ("%qD was declared %qs which implies default visibility",
656 DECL_VISIBILITY (decl
) = vis
;
657 DECL_VISIBILITY_SPECIFIED (decl
) = 1;
659 /* Go ahead and attach the attribute to the node as well. This is needed
660 so we can determine whether we have VISIBILITY_DEFAULT because the
661 visibility was not specified, or because it was explicitly overridden
662 from the containing scope. */
667 /* Handle a "always_inline" attribute; arguments as in
668 struct attribute_spec.handler. */
671 handle_always_inline_attribute (tree
*node
, tree name
,
672 tree
ARG_UNUSED (args
),
673 int ARG_UNUSED (flags
),
676 if (TREE_CODE (*node
) == FUNCTION_DECL
)
678 /* Set the attribute and mark it for disregarding inline
680 DECL_DISREGARD_INLINE_LIMITS (*node
) = 1;
684 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
685 *no_add_attrs
= true;
691 /* Handle a "cold" and attribute; arguments as in
692 struct attribute_spec.handler. */
695 handle_cold_attribute (tree
*node
, tree name
, tree
ARG_UNUSED (args
),
696 int ARG_UNUSED (flags
), bool *no_add_attrs
)
698 if (TREE_CODE (*node
) == FUNCTION_DECL
699 || TREE_CODE (*node
) == LABEL_DECL
)
701 /* Attribute cold processing is done later with lookup_attribute. */
705 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
706 *no_add_attrs
= true;
712 /* Handle a "noinline" attribute; arguments as in
713 struct attribute_spec.handler. */
716 handle_noinline_attribute (tree
*node
, tree name
,
717 tree
ARG_UNUSED (args
),
718 int ARG_UNUSED (flags
), bool *no_add_attrs
)
720 if (TREE_CODE (*node
) == FUNCTION_DECL
)
721 DECL_UNINLINABLE (*node
) = 1;
724 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
725 *no_add_attrs
= true;
731 /* Handle a "weak" attribute; arguments as in
732 struct attribute_spec.handler. */
735 handle_weak_attribute (tree
*node
, tree name
,
736 tree
ARG_UNUSED (args
),
737 int ARG_UNUSED (flags
),
738 bool * ARG_UNUSED (no_add_attrs
))
740 if (TREE_CODE (*node
) == FUNCTION_DECL
741 && DECL_DECLARED_INLINE_P (*node
))
743 warning (OPT_Wattributes
, "inline function %q+D declared weak", *node
);
744 *no_add_attrs
= true;
746 else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node
)))
748 error ("indirect function %q+D cannot be declared weak", *node
);
749 *no_add_attrs
= true;
752 else if (VAR_OR_FUNCTION_DECL_P (*node
))
753 declare_weak (*node
);
755 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
760 /* Handle a "target" attribute. */
763 handle_target_attribute (tree
*node
, tree name
, tree args
, int flags
,
766 /* Ensure we have a function declaration. */
767 if (TREE_CODE (*node
) != FUNCTION_DECL
)
769 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
770 *no_add_attrs
= true;
772 else if (! targetm
.target_option
.valid_attribute_p (*node
, name
, args
,
774 *no_add_attrs
= true;
776 /* Check that there's no empty string in values of the attribute. */
777 for (tree t
= args
; t
!= NULL_TREE
; t
= TREE_CHAIN (t
))
779 tree value
= TREE_VALUE (t
);
780 if (TREE_CODE (value
) == STRING_CST
781 && TREE_STRING_LENGTH (value
) == 1
782 && TREE_STRING_POINTER (value
)[0] == '\0')
784 warning (OPT_Wattributes
, "empty string in attribute %<target%>");
785 *no_add_attrs
= true;
792 /* Handle a "used" attribute; arguments as in
793 struct attribute_spec.handler. */
796 handle_used_attribute (tree
*pnode
, tree name
, tree
ARG_UNUSED (args
),
797 int ARG_UNUSED (flags
), bool *no_add_attrs
)
801 if (TREE_CODE (node
) == FUNCTION_DECL
802 || (VAR_P (node
) && TREE_STATIC (node
))
803 || (TREE_CODE (node
) == TYPE_DECL
))
805 TREE_USED (node
) = 1;
806 DECL_PRESERVE_P (node
) = 1;
808 DECL_READ_P (node
) = 1;
812 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
813 *no_add_attrs
= true;
819 /* Handle an "alias" or "ifunc" attribute; arguments as in
820 struct attribute_spec.handler, except that IS_ALIAS tells us
821 whether this is an alias as opposed to ifunc attribute. */
824 handle_alias_ifunc_attribute (bool is_alias
, tree
*node
, tree name
, tree args
,
829 if (TREE_CODE (decl
) != FUNCTION_DECL
830 && (!is_alias
|| !VAR_P (decl
)))
832 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
833 *no_add_attrs
= true;
835 else if ((TREE_CODE (decl
) == FUNCTION_DECL
&& DECL_INITIAL (decl
))
836 || (TREE_CODE (decl
) != FUNCTION_DECL
837 && TREE_PUBLIC (decl
) && !DECL_EXTERNAL (decl
))
838 /* A static variable declaration is always a tentative definition,
839 but the alias is a non-tentative definition which overrides. */
840 || (TREE_CODE (decl
) != FUNCTION_DECL
841 && ! TREE_PUBLIC (decl
) && DECL_INITIAL (decl
)))
843 error ("%q+D defined both normally and as %qE attribute", decl
, name
);
844 *no_add_attrs
= true;
848 && (lookup_attribute ("weak", DECL_ATTRIBUTES (decl
))
849 || lookup_attribute ("weakref", DECL_ATTRIBUTES (decl
))))
851 error ("weak %q+D cannot be defined %qE", decl
, name
);
852 *no_add_attrs
= true;
856 /* Note that the very first time we process a nested declaration,
857 decl_function_context will not be set. Indeed, *would* never
858 be set except for the DECL_INITIAL/DECL_EXTERNAL frobbery that
859 we do below. After such frobbery, pushdecl would set the context.
860 In any case, this is never what we want. */
861 else if (decl_function_context (decl
) == 0 && current_function_decl
== NULL
)
865 id
= TREE_VALUE (args
);
866 if (TREE_CODE (id
) != STRING_CST
)
868 error ("attribute %qE argument not a string", name
);
869 *no_add_attrs
= true;
872 id
= get_identifier (TREE_STRING_POINTER (id
));
873 /* This counts as a use of the object pointed to. */
876 if (TREE_CODE (decl
) == FUNCTION_DECL
)
877 DECL_INITIAL (decl
) = error_mark_node
;
879 TREE_STATIC (decl
) = 1;
883 /* ifuncs are also aliases, so set that attribute too. */
884 DECL_ATTRIBUTES (decl
)
885 = tree_cons (get_identifier ("alias"), args
,
886 DECL_ATTRIBUTES (decl
));
887 DECL_ATTRIBUTES (decl
) = tree_cons (get_identifier ("ifunc"),
888 NULL
, DECL_ATTRIBUTES (decl
));
893 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
894 *no_add_attrs
= true;
897 if (decl_in_symtab_p (*node
))
899 struct symtab_node
*n
= symtab_node::get (decl
);
900 if (n
&& n
->refuse_visibility_changes
)
901 error ("%+qD declared %qs after being used",
902 decl
, is_alias
? "alias" : "ifunc");
909 /* Handle an "alias" or "ifunc" attribute; arguments as in
910 struct attribute_spec.handler. */
913 handle_alias_attribute (tree
*node
, tree name
, tree args
,
914 int ARG_UNUSED (flags
), bool *no_add_attrs
)
916 return handle_alias_ifunc_attribute (true, node
, name
, args
, no_add_attrs
);
919 /* (end of attribute-handling). */
921 /* Language-dependent contents of a type. */
923 struct GTY(()) lang_type
928 /* Language-dependent contents of a decl. */
930 struct GTY((variable_size
)) lang_decl
935 /* Language-dependent contents of an identifier. This must include a
938 struct GTY(()) lang_identifier
940 struct tree_identifier common
;
943 /* The resulting tree type. */
945 union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
946 chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
949 union tree_node
GTY((tag ("0"),
950 desc ("tree_node_structure (&%h)"))) generic
;
951 struct lang_identifier
GTY((tag ("1"))) identifier
;
954 /* We don't use language_function. */
956 struct GTY(()) language_function
961 /* GC-marking callback for use from jit_root_tab.
963 If there's an active playback context, call its marking method
964 so that it can mark any pointers it references. */
966 static void my_ggc_walker (void *)
968 if (gcc::jit::active_playback_ctxt
)
969 gcc::jit::active_playback_ctxt
->gt_ggc_mx ();
974 struct ggc_root_tab jit_root_tab
[] =
977 &dummy
, 1, 0, my_ggc_walker
, NULL
982 /* JIT-specific implementation of diagnostic callbacks. */
984 /* Implementation of "begin_diagnostic". */
987 jit_begin_diagnostic (diagnostic_context */
*context*/
,
988 const diagnostic_info */
*diagnostic*/
)
990 gcc_assert (gcc::jit::active_playback_ctxt
);
991 JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt
->get_logger ());
993 /* No-op (apart from logging); the real error-handling is done in the
994 "end_diagnostic" hook. */
997 /* Implementation of "end_diagnostic". */
1000 jit_end_diagnostic (diagnostic_context
*context
,
1001 const diagnostic_info
*diagnostic
,
1004 gcc_assert (gcc::jit::active_playback_ctxt
);
1005 JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt
->get_logger ());
1007 /* Delegate to the playback context (and thence to the
1008 recording context). */
1009 gcc_assert (diagnostic
);
1010 gcc::jit::active_playback_ctxt
->add_diagnostic (context
, *diagnostic
);
1013 /* Language hooks. */
1016 jit_langhook_init (void)
1018 gcc_assert (gcc::jit::active_playback_ctxt
);
1019 JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt
->get_logger ());
1021 static bool registered_root_tab
= false;
1022 if (!registered_root_tab
)
1024 ggc_register_root_tab (jit_root_tab
);
1025 registered_root_tab
= true;
1028 gcc_assert (global_dc
);
1029 diagnostic_starter (global_dc
) = jit_begin_diagnostic
;
1030 diagnostic_finalizer (global_dc
) = jit_end_diagnostic
;
1032 build_common_tree_nodes (false);
1034 build_common_builtin_nodes ();
1036 /* The default precision for floating point numbers. This is used
1037 for floating point constants with abstract type. This may
1038 eventually be controllable by a command line option. */
1039 mpfr_set_default_prec (256);
1045 jit_langhook_parse_file (void)
1047 /* Replay the activity by the client, recorded on the context. */
1048 gcc_assert (gcc::jit::active_playback_ctxt
);
1049 gcc::jit::active_playback_ctxt
->replay ();
1053 jit_langhook_type_for_mode (machine_mode mode
, int unsignedp
)
1055 /* Build any vector types here (see PR 46805). */
1056 if (VECTOR_MODE_P (mode
))
1060 inner
= jit_langhook_type_for_mode (GET_MODE_INNER (mode
), unsignedp
);
1061 if (inner
!= NULL_TREE
)
1062 return build_vector_type_for_mode (inner
, mode
);
1066 if (mode
== TYPE_MODE (float_type_node
))
1067 return float_type_node
;
1069 if (mode
== TYPE_MODE (double_type_node
))
1070 return double_type_node
;
1072 if (mode
== TYPE_MODE (intQI_type_node
))
1073 return unsignedp
? unsigned_intQI_type_node
: intQI_type_node
;
1074 if (mode
== TYPE_MODE (intHI_type_node
))
1075 return unsignedp
? unsigned_intHI_type_node
: intHI_type_node
;
1076 if (mode
== TYPE_MODE (intSI_type_node
))
1077 return unsignedp
? unsigned_intSI_type_node
: intSI_type_node
;
1078 if (mode
== TYPE_MODE (intDI_type_node
))
1079 return unsignedp
? unsigned_intDI_type_node
: intDI_type_node
;
1080 if (mode
== TYPE_MODE (intTI_type_node
))
1081 return unsignedp
? unsigned_intTI_type_node
: intTI_type_node
;
1083 if (mode
== TYPE_MODE (integer_type_node
))
1084 return unsignedp
? unsigned_type_node
: integer_type_node
;
1086 if (mode
== TYPE_MODE (long_integer_type_node
))
1087 return unsignedp
? long_unsigned_type_node
: long_integer_type_node
;
1089 if (mode
== TYPE_MODE (long_long_integer_type_node
))
1090 return unsignedp
? long_long_unsigned_type_node
: long_long_integer_type_node
;
1092 if (COMPLEX_MODE_P (mode
))
1094 if (mode
== TYPE_MODE (complex_float_type_node
))
1095 return complex_float_type_node
;
1096 if (mode
== TYPE_MODE (complex_double_type_node
))
1097 return complex_double_type_node
;
1098 if (mode
== TYPE_MODE (complex_long_double_type_node
))
1099 return complex_long_double_type_node
;
1100 if (mode
== TYPE_MODE (complex_integer_type_node
) && !unsignedp
)
1101 return complex_integer_type_node
;
1104 /* gcc_unreachable */
1108 /* Record a builtin function. We just ignore builtin functions. */
1111 jit_langhook_builtin_function (tree decl
)
1117 jit_langhook_global_bindings_p (void)
1123 jit_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED
)
1129 jit_langhook_getdecls (void)
1134 #undef LANG_HOOKS_NAME
1135 #define LANG_HOOKS_NAME "libgccjit"
1137 #undef LANG_HOOKS_INIT
1138 #define LANG_HOOKS_INIT jit_langhook_init
1140 #undef LANG_HOOKS_PARSE_FILE
1141 #define LANG_HOOKS_PARSE_FILE jit_langhook_parse_file
1143 #undef LANG_HOOKS_TYPE_FOR_MODE
1144 #define LANG_HOOKS_TYPE_FOR_MODE jit_langhook_type_for_mode
1146 #undef LANG_HOOKS_BUILTIN_FUNCTION
1147 #define LANG_HOOKS_BUILTIN_FUNCTION jit_langhook_builtin_function
1149 #undef LANG_HOOKS_GLOBAL_BINDINGS_P
1150 #define LANG_HOOKS_GLOBAL_BINDINGS_P jit_langhook_global_bindings_p
1152 #undef LANG_HOOKS_PUSHDECL
1153 #define LANG_HOOKS_PUSHDECL jit_langhook_pushdecl
1155 #undef LANG_HOOKS_GETDECLS
1156 #define LANG_HOOKS_GETDECLS jit_langhook_getdecls
1158 /* Attribute hooks. */
1159 #undef LANG_HOOKS_ATTRIBUTE_TABLE
1160 #define LANG_HOOKS_ATTRIBUTE_TABLE jit_attribute_table
1162 #undef LANG_HOOKS_DEEP_UNSHARING
1163 #define LANG_HOOKS_DEEP_UNSHARING true
1165 struct lang_hooks lang_hooks
= LANG_HOOKS_INITIALIZER
;
1167 #include "gt-jit-dummy-frontend.h"
1168 #include "gtype-jit.h"