15ef59e75Smrg /* jit.c -- Dummy "frontend" for use during JIT-compilation.
2*dd083157Smrg    Copyright (C) 2013-2020 Free Software Foundation, Inc.
35ef59e75Smrg 
45ef59e75Smrg This file is part of GCC.
55ef59e75Smrg 
65ef59e75Smrg GCC is free software; you can redistribute it and/or modify it under
75ef59e75Smrg the terms of the GNU General Public License as published by the Free
85ef59e75Smrg Software Foundation; either version 3, or (at your option) any later
95ef59e75Smrg version.
105ef59e75Smrg 
115ef59e75Smrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
125ef59e75Smrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
135ef59e75Smrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
145ef59e75Smrg for more details.
155ef59e75Smrg 
165ef59e75Smrg You should have received a copy of the GNU General Public License
175ef59e75Smrg along with GCC; see the file COPYING3.  If not see
185ef59e75Smrg <http://www.gnu.org/licenses/>.  */
195ef59e75Smrg 
205ef59e75Smrg #include "config.h"
215ef59e75Smrg #include "system.h"
225ef59e75Smrg #include "coretypes.h"
2363aace61Smrg #include "jit-playback.h"
245ef59e75Smrg #include "stor-layout.h"
255ef59e75Smrg #include "debug.h"
265ef59e75Smrg #include "langhooks.h"
275ef59e75Smrg #include "langhooks-def.h"
286a5c9aabSmrg #include "diagnostic.h"
295ef59e75Smrg 
305ef59e75Smrg 
315ef59e75Smrg #include <mpfr.h>
325ef59e75Smrg 
335ef59e75Smrg /* Language-dependent contents of a type.  */
345ef59e75Smrg 
355ef59e75Smrg struct GTY(()) lang_type
365ef59e75Smrg {
375ef59e75Smrg   char dummy;
385ef59e75Smrg };
395ef59e75Smrg 
405ef59e75Smrg /* Language-dependent contents of a decl.  */
415ef59e75Smrg 
425ef59e75Smrg struct GTY((variable_size)) lang_decl
435ef59e75Smrg {
445ef59e75Smrg   char dummy;
455ef59e75Smrg };
465ef59e75Smrg 
475ef59e75Smrg /* Language-dependent contents of an identifier.  This must include a
485ef59e75Smrg    tree_identifier.  */
495ef59e75Smrg 
505ef59e75Smrg struct GTY(()) lang_identifier
515ef59e75Smrg {
525ef59e75Smrg   struct tree_identifier common;
535ef59e75Smrg };
545ef59e75Smrg 
555ef59e75Smrg /* The resulting tree type.  */
565ef59e75Smrg 
575ef59e75Smrg union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
585ef59e75Smrg 	   chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
595ef59e75Smrg lang_tree_node
605ef59e75Smrg {
615ef59e75Smrg   union tree_node GTY((tag ("0"),
625ef59e75Smrg 		       desc ("tree_node_structure (&%h)"))) generic;
635ef59e75Smrg   struct lang_identifier GTY((tag ("1"))) identifier;
645ef59e75Smrg };
655ef59e75Smrg 
665ef59e75Smrg /* We don't use language_function.  */
675ef59e75Smrg 
685ef59e75Smrg struct GTY(()) language_function
695ef59e75Smrg {
705ef59e75Smrg   int dummy;
715ef59e75Smrg };
725ef59e75Smrg 
735ef59e75Smrg /* GC-marking callback for use from jit_root_tab.
745ef59e75Smrg 
755ef59e75Smrg    If there's an active playback context, call its marking method
765ef59e75Smrg    so that it can mark any pointers it references.  */
775ef59e75Smrg 
my_ggc_walker(void *)785ef59e75Smrg static void my_ggc_walker (void *)
795ef59e75Smrg {
805ef59e75Smrg   if (gcc::jit::active_playback_ctxt)
815ef59e75Smrg     gcc::jit::active_playback_ctxt->gt_ggc_mx ();
825ef59e75Smrg }
835ef59e75Smrg 
845ef59e75Smrg const char *dummy;
855ef59e75Smrg 
865ef59e75Smrg struct ggc_root_tab jit_root_tab[] =
875ef59e75Smrg   {
885ef59e75Smrg     {
895ef59e75Smrg       &dummy, 1, 0, my_ggc_walker, NULL
905ef59e75Smrg     },
915ef59e75Smrg     LAST_GGC_ROOT_TAB
925ef59e75Smrg   };
935ef59e75Smrg 
946a5c9aabSmrg /* JIT-specific implementation of diagnostic callbacks.  */
956a5c9aabSmrg 
966a5c9aabSmrg /* Implementation of "begin_diagnostic".  */
976a5c9aabSmrg 
986a5c9aabSmrg static void
jit_begin_diagnostic(diagnostic_context *,diagnostic_info *)996a5c9aabSmrg jit_begin_diagnostic (diagnostic_context */*context*/,
1006a5c9aabSmrg 		      diagnostic_info */*diagnostic*/)
1016a5c9aabSmrg {
1026a5c9aabSmrg   gcc_assert (gcc::jit::active_playback_ctxt);
1036a5c9aabSmrg   JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
1046a5c9aabSmrg 
1056a5c9aabSmrg   /* No-op (apart from logging); the real error-handling is done in the
1066a5c9aabSmrg      "end_diagnostic" hook.  */
1076a5c9aabSmrg }
1086a5c9aabSmrg 
1096a5c9aabSmrg /* Implementation of "end_diagnostic".  */
1106a5c9aabSmrg 
1116a5c9aabSmrg static void
jit_end_diagnostic(diagnostic_context * context,diagnostic_info * diagnostic,diagnostic_t)1126a5c9aabSmrg jit_end_diagnostic (diagnostic_context *context,
11381418a27Smrg 		    diagnostic_info *diagnostic,
11481418a27Smrg 		    diagnostic_t)
1156a5c9aabSmrg {
1166a5c9aabSmrg   gcc_assert (gcc::jit::active_playback_ctxt);
1176a5c9aabSmrg   JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
1186a5c9aabSmrg 
1196a5c9aabSmrg   /* Delegate to the playback context (and thence to the
1206a5c9aabSmrg      recording context).  */
1216a5c9aabSmrg   gcc::jit::active_playback_ctxt->add_diagnostic (context, diagnostic);
1226a5c9aabSmrg }
1236a5c9aabSmrg 
1245ef59e75Smrg /* Language hooks.  */
1255ef59e75Smrg 
1265ef59e75Smrg static bool
jit_langhook_init(void)1275ef59e75Smrg jit_langhook_init (void)
1285ef59e75Smrg {
1295ef59e75Smrg   gcc_assert (gcc::jit::active_playback_ctxt);
1305ef59e75Smrg   JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
1315ef59e75Smrg 
1325ef59e75Smrg   static bool registered_root_tab = false;
1335ef59e75Smrg   if (!registered_root_tab)
1345ef59e75Smrg     {
1355ef59e75Smrg       ggc_register_root_tab (jit_root_tab);
1365ef59e75Smrg       registered_root_tab = true;
1375ef59e75Smrg     }
1385ef59e75Smrg 
1396a5c9aabSmrg   gcc_assert (global_dc);
1406a5c9aabSmrg   global_dc->begin_diagnostic = jit_begin_diagnostic;
1416a5c9aabSmrg   global_dc->end_diagnostic = jit_end_diagnostic;
1426a5c9aabSmrg 
14363aace61Smrg   build_common_tree_nodes (false);
1445ef59e75Smrg 
1455ef59e75Smrg   /* I don't know why this has to be done explicitly.  */
1465ef59e75Smrg   void_list_node = build_tree_list (NULL_TREE, void_type_node);
1475ef59e75Smrg 
1485ef59e75Smrg   build_common_builtin_nodes ();
1495ef59e75Smrg 
1505ef59e75Smrg   /* The default precision for floating point numbers.  This is used
1515ef59e75Smrg      for floating point constants with abstract type.  This may
1525ef59e75Smrg      eventually be controllable by a command line option.  */
1535ef59e75Smrg   mpfr_set_default_prec (256);
1545ef59e75Smrg 
1555ef59e75Smrg   return true;
1565ef59e75Smrg }
1575ef59e75Smrg 
1585ef59e75Smrg static void
jit_langhook_parse_file(void)1595ef59e75Smrg jit_langhook_parse_file (void)
1605ef59e75Smrg {
1615ef59e75Smrg   /* Replay the activity by the client, recorded on the context.  */
1625ef59e75Smrg   gcc_assert (gcc::jit::active_playback_ctxt);
1635ef59e75Smrg   gcc::jit::active_playback_ctxt->replay ();
1645ef59e75Smrg }
1655ef59e75Smrg 
1665ef59e75Smrg static tree
jit_langhook_type_for_mode(machine_mode mode,int unsignedp)1673903d7f3Smrg jit_langhook_type_for_mode (machine_mode mode, int unsignedp)
1685ef59e75Smrg {
1693903d7f3Smrg   /* Build any vector types here (see PR 46805).  */
1703903d7f3Smrg   if (VECTOR_MODE_P (mode))
1713903d7f3Smrg     {
1723903d7f3Smrg       tree inner;
1733903d7f3Smrg 
1743903d7f3Smrg       inner = jit_langhook_type_for_mode (GET_MODE_INNER (mode), unsignedp);
1753903d7f3Smrg       if (inner != NULL_TREE)
1763903d7f3Smrg 	return build_vector_type_for_mode (inner, mode);
1773903d7f3Smrg       return NULL_TREE;
1783903d7f3Smrg     }
1793903d7f3Smrg 
1805ef59e75Smrg   if (mode == TYPE_MODE (float_type_node))
1815ef59e75Smrg     return float_type_node;
1825ef59e75Smrg 
1835ef59e75Smrg   if (mode == TYPE_MODE (double_type_node))
1845ef59e75Smrg     return double_type_node;
1855ef59e75Smrg 
18663aace61Smrg   if (mode == TYPE_MODE (intQI_type_node))
18763aace61Smrg     return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
18863aace61Smrg   if (mode == TYPE_MODE (intHI_type_node))
18963aace61Smrg     return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
19063aace61Smrg   if (mode == TYPE_MODE (intSI_type_node))
19163aace61Smrg     return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
19263aace61Smrg   if (mode == TYPE_MODE (intDI_type_node))
19363aace61Smrg     return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
19463aace61Smrg   if (mode == TYPE_MODE (intTI_type_node))
19563aace61Smrg     return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
19663aace61Smrg 
1975ef59e75Smrg   if (mode == TYPE_MODE (integer_type_node))
1985ef59e75Smrg     return unsignedp ? unsigned_type_node : integer_type_node;
1995ef59e75Smrg 
2005ef59e75Smrg   if (mode == TYPE_MODE (long_integer_type_node))
2015ef59e75Smrg     return unsignedp ? long_unsigned_type_node : long_integer_type_node;
2025ef59e75Smrg 
2035ef59e75Smrg   if (mode == TYPE_MODE (long_long_integer_type_node))
2045ef59e75Smrg     return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
2055ef59e75Smrg 
2065ef59e75Smrg   if (COMPLEX_MODE_P (mode))
2075ef59e75Smrg     {
2085ef59e75Smrg       if (mode == TYPE_MODE (complex_float_type_node))
2095ef59e75Smrg 	return complex_float_type_node;
2105ef59e75Smrg       if (mode == TYPE_MODE (complex_double_type_node))
2115ef59e75Smrg 	return complex_double_type_node;
2125ef59e75Smrg       if (mode == TYPE_MODE (complex_long_double_type_node))
2135ef59e75Smrg 	return complex_long_double_type_node;
2145ef59e75Smrg       if (mode == TYPE_MODE (complex_integer_type_node) && !unsignedp)
2155ef59e75Smrg 	return complex_integer_type_node;
2165ef59e75Smrg     }
2175ef59e75Smrg 
2185ef59e75Smrg   /* gcc_unreachable */
2195ef59e75Smrg   return NULL;
2205ef59e75Smrg }
2215ef59e75Smrg 
2225ef59e75Smrg /* Record a builtin function.  We just ignore builtin functions.  */
2235ef59e75Smrg 
2245ef59e75Smrg static tree
jit_langhook_builtin_function(tree decl)2255ef59e75Smrg jit_langhook_builtin_function (tree decl)
2265ef59e75Smrg {
2275ef59e75Smrg   return decl;
2285ef59e75Smrg }
2295ef59e75Smrg 
2305ef59e75Smrg static bool
jit_langhook_global_bindings_p(void)2315ef59e75Smrg jit_langhook_global_bindings_p (void)
2325ef59e75Smrg {
2335ef59e75Smrg   gcc_unreachable ();
2345ef59e75Smrg   return true;
2355ef59e75Smrg }
2365ef59e75Smrg 
2375ef59e75Smrg static tree
jit_langhook_pushdecl(tree decl ATTRIBUTE_UNUSED)2385ef59e75Smrg jit_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED)
2395ef59e75Smrg {
2405ef59e75Smrg   gcc_unreachable ();
2415ef59e75Smrg }
2425ef59e75Smrg 
2435ef59e75Smrg static tree
jit_langhook_getdecls(void)2445ef59e75Smrg jit_langhook_getdecls (void)
2455ef59e75Smrg {
2465ef59e75Smrg   return NULL;
2475ef59e75Smrg }
2485ef59e75Smrg 
2495ef59e75Smrg #undef LANG_HOOKS_NAME
2505ef59e75Smrg #define LANG_HOOKS_NAME		"libgccjit"
2515ef59e75Smrg 
2525ef59e75Smrg #undef LANG_HOOKS_INIT
2535ef59e75Smrg #define LANG_HOOKS_INIT		jit_langhook_init
2545ef59e75Smrg 
2555ef59e75Smrg #undef LANG_HOOKS_PARSE_FILE
2565ef59e75Smrg #define LANG_HOOKS_PARSE_FILE		jit_langhook_parse_file
2575ef59e75Smrg 
2585ef59e75Smrg #undef LANG_HOOKS_TYPE_FOR_MODE
2595ef59e75Smrg #define LANG_HOOKS_TYPE_FOR_MODE	jit_langhook_type_for_mode
2605ef59e75Smrg 
2615ef59e75Smrg #undef LANG_HOOKS_BUILTIN_FUNCTION
2625ef59e75Smrg #define LANG_HOOKS_BUILTIN_FUNCTION	jit_langhook_builtin_function
2635ef59e75Smrg 
2645ef59e75Smrg #undef LANG_HOOKS_GLOBAL_BINDINGS_P
2655ef59e75Smrg #define LANG_HOOKS_GLOBAL_BINDINGS_P	jit_langhook_global_bindings_p
2665ef59e75Smrg 
2675ef59e75Smrg #undef LANG_HOOKS_PUSHDECL
2685ef59e75Smrg #define LANG_HOOKS_PUSHDECL		jit_langhook_pushdecl
2695ef59e75Smrg 
2705ef59e75Smrg #undef LANG_HOOKS_GETDECLS
2715ef59e75Smrg #define LANG_HOOKS_GETDECLS		jit_langhook_getdecls
2725ef59e75Smrg 
2735ef59e75Smrg struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
2745ef59e75Smrg 
2755ef59e75Smrg #include "gt-jit-dummy-frontend.h"
2765ef59e75Smrg #include "gtype-jit.h"
277