xref: /netbsd-src/external/gpl3/gcc/dist/gcc/jit/dummy-frontend.cc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
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