public inbox for jit@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] libgccjit: Add ability to get CPU features
@ 2023-11-09 22:27 Antoni Boucher
  2023-11-09 23:04 ` David Malcolm
  0 siblings, 1 reply; 21+ messages in thread
From: Antoni Boucher @ 2023-11-09 22:27 UTC (permalink / raw)
  To: jit, gcc-patches; +Cc: David Malcolm

[-- Attachment #1: Type: text/plain, Size: 425 bytes --]

Hi.
This patch adds support for getting the CPU features in libgccjit (bug
112466)

There's a TODO in the test:
I'm not sure how to test that gcc_jit_target_info_arch returns the
correct value since it is dependant on the CPU.
Any idea on how to improve this?

Also, I created a CStringHash to be able to have a
std::unordered_set<const char *>. Is there any built-in way of doing
this?

Thanks for the review.

[-- Attachment #2: 0001-libgccjit-Add-ability-to-get-CPU-features.patch --]
[-- Type: text/x-patch, Size: 51157 bytes --]

From 302f9f0bb22deae3deb8249a9127447c3ec4f7c7 Mon Sep 17 00:00:00 2001
From: Antoni Boucher <bouanto@zoho.com>
Date: Mon, 26 Jun 2023 18:29:15 -0400
Subject: [PATCH] libgccjit: Add ability to get CPU features

gcc/ChangeLog:
	PR jit/112466
	* Makefile.in (tm_jit_file_list, tm_jit_include_list, TM_JIT_H,
	JIT_TARGET_DEF, JIT_TARGET_H, JIT_TARGET_OBJS): New variables.
	(tm_jit.h, cs-tm_jit.h, jit/jit-target-hooks-def.h,
	s-jit-target-hooks-def-h): New rules.
	(s-tm-texi): Also check timestamp on jit-target.def.
	(generated_files): Add TM_JIT_H and jit/jit-target-hooks-def.h.
	(build/genhooks.o): Also depend on JIT_TARGET_DEF.
	* config.gcc (tm_jit_file, jit_target_objs, target_has_targetjitm):
	New variables.
	* config/i386/t-i386 (i386-jit.o): New rule.
	* config/t-linux (linux-jit.o): New rule.
	* configure: Regenerate.
	* configure.ac (tm_jit_file_list, tm_jit_include_list,
	jit_target_objs): Add substitutes.
	* doc/tm.texi: Regenerate.
	* doc/tm.texi.in (targetjitm): Document.
	(target_has_targetjitm): Document.
	* genhooks.cc: Include jit/jit-target.def.
	* config/default-jit.cc: New file.
	* config/i386/i386-jit.cc: New file.
	* config/i386/i386-jit.h: New file.
	* config/linux-jit.cc: New file.

gcc/jit/ChangeLog:
	PR jit/112466
	* Make-lang.in (JIT_OBJS): New variable.
	* jit-playback.cc (replay): Include jit-target.h and initialize
	target.
	* jit-playback.h (class get_target_info): New class.
	* jit-recording.cc (recording::context::get_target_info): New
	method.
	* jit-recording.h (recording::context::get_target_info): New
	method.
	* libgccjit.cc: Include jit-target.h.
	(struct gcc_jit_target_info): New struct.
	(gcc_jit_context_get_target_info, gcc_jit_target_info_release,
	gcc_jit_target_info_cpu_supports, gcc_jit_target_info_arch,
	gcc_jit_target_info_supports_128bit_int): New functions.
	* libgccjit.h (gcc_jit_context_get_target_info,
	gcc_jit_target_info_release, gcc_jit_target_info_cpu_supports,
	gcc_jit_target_info_arch, gcc_jit_target_info_supports_128bit_int):
	New functions.
	* libgccjit.map (LIBGCCJIT_ABI_26): New ABI tag.
	* docs/topics/compilation.rst: Add documentation for the
	functions gcc_jit_context_get_target_info, gcc_jit_target_info_release,
	gcc_jit_target_info_cpu_supports, gcc_jit_target_info_arch,
	gcc_jit_target_info_supports_128bit_int.
	* docs/topics/compatibility.rst (LIBGCCJIT_ABI_26): New ABI tag.
	* jit-target-def.h: New file.
	* jit-target.cc: New file.
	* jit-target.def: New file.
	* jit-target.h: New file.

gcc/testsuite/ChangeLog:
	PR jit/112466
	* jit.dg/all-non-failing-tests.h: Mention
	test-target-info.c.
	* jit.dg/test-target-info.c: New test.
---
 gcc/Makefile.in                              |  29 ++-
 gcc/config.gcc                               |  21 ++
 gcc/config/default-jit.cc                    |  29 +++
 gcc/config/i386/i386-jit.cc                  | 195 +++++++++++++++++++
 gcc/config/i386/i386-jit.h                   |  22 +++
 gcc/config/i386/t-i386                       |   4 +
 gcc/config/linux-jit.cc                      |  36 ++++
 gcc/config/t-linux                           |   4 +
 gcc/configure                                |  14 ++
 gcc/configure.ac                             |  14 ++
 gcc/doc/tm.texi                              |  26 +++
 gcc/doc/tm.texi.in                           |  16 ++
 gcc/genhooks.cc                              |   1 +
 gcc/jit/Make-lang.in                         |   8 +-
 gcc/jit/docs/topics/compatibility.rst        |  14 ++
 gcc/jit/docs/topics/compilation.rst          |  51 +++++
 gcc/jit/jit-playback.cc                      |   2 +
 gcc/jit/jit-playback.h                       |  17 +-
 gcc/jit/jit-recording.cc                     |  19 ++
 gcc/jit/jit-recording.h                      |   3 +
 gcc/jit/jit-target-def.h                     |  20 ++
 gcc/jit/jit-target.cc                        |  89 +++++++++
 gcc/jit/jit-target.def                       |  52 +++++
 gcc/jit/jit-target.h                         |  73 +++++++
 gcc/jit/libgccjit.cc                         |  43 ++++
 gcc/jit/libgccjit.h                          |  60 ++++++
 gcc/jit/libgccjit.map                        |   9 +
 gcc/testsuite/jit.dg/all-non-failing-tests.h |   3 +
 gcc/testsuite/jit.dg/test-target-info.c      |  63 ++++++
 29 files changed, 931 insertions(+), 6 deletions(-)
 create mode 100644 gcc/config/default-jit.cc
 create mode 100644 gcc/config/i386/i386-jit.cc
 create mode 100644 gcc/config/i386/i386-jit.h
 create mode 100644 gcc/config/linux-jit.cc
 create mode 100644 gcc/jit/jit-target-def.h
 create mode 100644 gcc/jit/jit-target.cc
 create mode 100644 gcc/jit/jit-target.def
 create mode 100644 gcc/jit/jit-target.h
 create mode 100644 gcc/testsuite/jit.dg/test-target-info.c

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 29cec21c825..701661fbaa0 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -609,6 +609,8 @@ tm_d_file_list=@tm_d_file_list@
 tm_d_include_list=@tm_d_include_list@
 tm_rust_file_list=@tm_rust_file_list@
 tm_rust_include_list=@tm_rust_include_list@
+tm_jit_file_list=@tm_jit_file_list@
+tm_jit_include_list=@tm_jit_include_list@
 build_xm_file_list=@build_xm_file_list@
 build_xm_include_list=@build_xm_include_list@
 build_xm_defines=@build_xm_defines@
@@ -908,6 +910,7 @@ TCONFIG_H = tconfig.h $(xm_file_list)
 TM_P_H    = tm_p.h    $(tm_p_file_list) $(TREE_H)
 TM_D_H    = tm_d.h    $(tm_d_file_list)
 TM_RUST_H = tm_rust.h $(tm_rust_file_list)
+TM_JIT_H  = tm_jit.h    $(tm_jit_file_list)
 GTM_H     = tm.h      $(tm_file_list) insn-constants.h
 TM_H      = $(GTM_H) insn-flags.h $(OPTIONS_H)
 
@@ -967,11 +970,13 @@ C_TARGET_DEF = c-family/c-target.def target-hooks-macros.h
 COMMON_TARGET_DEF = common/common-target.def target-hooks-macros.h
 D_TARGET_DEF = d/d-target.def target-hooks-macros.h
 RUST_TARGET_DEF = rust/rust-target.def target-hooks-macros.h
+JIT_TARGET_DEF = jit/jit-target.def target-hooks-macros.h
 TARGET_H = $(TM_H) target.h $(TARGET_DEF) insn-modes.h insn-codes.h
 C_TARGET_H = c-family/c-target.h $(C_TARGET_DEF)
 COMMON_TARGET_H = common/common-target.h $(INPUT_H) $(COMMON_TARGET_DEF)
 D_TARGET_H = d/d-target.h $(D_TARGET_DEF)
 RUST_TARGET_H = rust/rust-target.h $(RUST_TARGET_DEF)
+JIT_TARGET_H = jit/jit-target.h $(JIT_TARGET_DEF)
 MACHMODE_H = machmode.h mode-classes.def
 HOOKS_H = hooks.h
 HOSTHOOKS_DEF_H = hosthooks-def.h $(HOOKS_H)
@@ -1279,6 +1284,9 @@ CXX_TARGET_OBJS=@cxx_target_objs@
 # Target specific, D specific object file
 D_TARGET_OBJS=@d_target_objs@
 
+# Target specific, JIT specific object file
+JIT_TARGET_OBJS=@jit_target_objs@
+
 # Target specific, Fortran specific object file
 FORTRAN_TARGET_OBJS=@fortran_target_objs@
 
@@ -2023,6 +2031,7 @@ tm.h: cs-tm.h ; @true
 tm_p.h: cs-tm_p.h ; @true
 tm_d.h: cs-tm_d.h ; @true
 tm_rust.h: cs-tm_rust.h ; @true
+tm_jit.h: cs-tm_jit.h ; @true
 
 cs-config.h: Makefile
 	TARGET_CPU_DEFAULT="" \
@@ -2062,6 +2071,11 @@ cs-tm_rust.h: Makefile
 	HEADERS="$(tm_rust_include_list)" DEFINES="" \
 	$(SHELL) $(srcdir)/mkconfig.sh tm_rust.h
 
+cs-tm_jit.h: Makefile
+	TARGET_CPU_DEFAULT="" \
+	HEADERS="$(tm_jit_include_list)" DEFINES="" \
+	$(SHELL) $(srcdir)/mkconfig.sh tm_jit.h
+
 # Don't automatically run autoconf, since configure.ac might be accidentally
 # newer than configure.  Also, this writes into the source directory which
 # might be on a read-only file system.  If configured for maintainer mode
@@ -2731,6 +2745,15 @@ s-rust-target-hooks-def-h: build/genhooks$(build_exeext)
 					     rust/rust-target-hooks-def.h
 	$(STAMP) s-rust-target-hooks-def-h
 
+jit/jit-target-hooks-def.h: s-jit-target-hooks-def-h; @true
+
+s-jit-target-hooks-def-h: build/genhooks$(build_exeext)
+	$(RUN_GEN) build/genhooks$(build_exeext) "JIT Target Hook" \
+					     > tmp-jit-target-hooks-def.h
+	$(SHELL) $(srcdir)/../move-if-change tmp-jit-target-hooks-def.h \
+					     jit/jit-target-hooks-def.h
+	$(STAMP) s-jit-target-hooks-def-h
+
 # check if someone mistakenly only changed tm.texi.
 # We use a different pathname here to avoid a circular dependency.
 s-tm-texi: $(srcdir)/doc/../doc/tm.texi
@@ -2756,6 +2779,7 @@ s-tm-texi: build/genhooks$(build_exeext) $(srcdir)/doc/tm.texi.in
 	    || test $(srcdir)/doc/tm.texi -nt $(srcdir)/common/common-target.def \
 	    || test $(srcdir)/doc/tm.texi -nt $(srcdir)/d/d-target.def \
 	    || test $(srcdir)/doc/tm.texi -nt $(srcdir)/rust/rust-target.def \
+	    || test $(srcdir)/doc/tm.texi -nt $(srcdir)/jit/jit-target.def \
 	  ); then \
 	  echo >&2 ; \
 	  echo You should edit $(srcdir)/doc/tm.texi.in rather than $(srcdir)/doc/tm.texi . >&2 ; \
@@ -2933,6 +2957,7 @@ generated_files = config.h tm.h $(TM_P_H) $(TM_D_H) $(TM_H) multilib.h \
        gimple-match-auto.h generic-match-auto.h \
        c-family/c-target-hooks-def.h d/d-target-hooks-def.h \
        $(TM_RUST_H) rust/rust-target-hooks-def.h \
+       $(TM_JIT_H) jit/jit-target-hooks-def.h \
        case-cfn-macros.h \
        cfn-operators.pd omp-device-properties.h
 
@@ -3067,8 +3092,8 @@ build/genrecog.o : genrecog.cc $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H)	\
   $(CORETYPES_H) $(GTM_H) errors.h $(READ_MD_H) $(GENSUPPORT_H)		\
   $(HASH_TABLE_H) inchash.h
 build/genhooks.o : genhooks.cc $(TARGET_DEF) $(C_TARGET_DEF)		\
-  $(COMMON_TARGET_DEF) $(D_TARGET_DEF) $(RUST_TARGET_DEF) $(BCONFIG_H) \
-  $(SYSTEM_H) errors.h
+  $(COMMON_TARGET_DEF) $(D_TARGET_DEF) $(RUST_TARGET_DEF) $(JIT_TARGET_DEF) \
+  $(BCONFIG_H) $(SYSTEM_H) errors.h
 build/genmddump.o : genmddump.cc $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H)	\
   $(CORETYPES_H) $(GTM_H) errors.h $(READ_MD_H) $(GENSUPPORT_H)
 build/genmatch.o : genmatch.cc $(BCONFIG_H) $(SYSTEM_H) $(CORETYPES_H) \
diff --git a/gcc/config.gcc b/gcc/config.gcc
index ba6d63e33ac..a14de7be8d6 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -149,6 +149,9 @@
 #  d_target_objs	List of extra target-dependent objects that be
 #			linked into the D compiler only.
 #
+#  jit_target_objs	List of extra target-dependent objects that be
+#			linked into the jit compiler only.
+#
 #  fortran_target_objs	List of extra target-dependent objects that be
 #			linked into the fortran compiler only.
 #
@@ -210,6 +213,8 @@
 #
 #  target_has_targetrustm	Set to yes or no depending on whether the target
 #			has its own definition of targetrustm.
+#  target_has_targetjitm	Set to yes or no depending on whether the target
+#			has its own definition of targetdm.
 
 out_file=
 common_out_file=
@@ -226,12 +231,14 @@ extra_options=
 c_target_objs=
 cxx_target_objs=
 d_target_objs=
+jit_target_objs=
 fortran_target_objs=
 rust_target_objs=
 target_has_targetcm=no
 target_has_targetm_common=yes
 target_has_targetdm=no
 target_has_targetrustm=no
+target_has_targetjitm=no
 tm_defines=
 xm_defines=
 # Set this to force installation and use of collect2.
@@ -412,6 +419,7 @@ i[34567]86-*-* | x86_64-*-*)
 	c_target_objs="i386-c.o"
 	cxx_target_objs="i386-c.o"
 	d_target_objs="i386-d.o"
+	jit_target_objs="i386-jit.o"
 	extra_objs="x86-tune-sched.o x86-tune-sched-bd.o x86-tune-sched-atom.o x86-tune-sched-core.o i386-options.o i386-builtins.o i386-expand.o i386-features.o"
 	target_gtfiles="\$(srcdir)/config/i386/i386-builtins.cc \$(srcdir)/config/i386/i386-expand.cc \$(srcdir)/config/i386/i386-options.cc"
 	extra_options="${extra_options} fused-madd.opt"
@@ -614,6 +622,12 @@ then
 	rust_target_objs="${rust_target_objs} ${cpu_type}-rust.o"
 fi
 
+tm_jit_file=
+if test -f ${srcdir}/config/${cpu_type}/${cpu_type}-jit.h
+then
+	tm_jit_file="${tm_jit_file} ${cpu_type}/${cpu_type}-jit.h"
+fi
+
 extra_modes=
 if test -f ${srcdir}/config/${cpu_type}/${cpu_type}-modes.def
 then
@@ -946,9 +960,11 @@ case ${target} in
   case $target in
     *-*-*linux*)
       d_target_objs="${d_target_objs} linux-d.o"
+      jit_target_objs="${jit_target_objs} linux-jit.o"
       target_has_targetdm=yes
       rust_target_objs="${rust_target_objs} linux-rust.o"
       target_has_targetrustm=yes
+      target_has_targetjitm=yes
       ;;
     *-*-kfreebsd*-gnu)
       d_target_objs="${d_target_objs} kfreebsd-d.o"
@@ -3667,6 +3683,10 @@ if [ "$target_has_targetrustm" = "no" ]; then
   rust_target_objs="$rust_target_objs default-rust.o"
 fi
 
+if [ "$target_has_targetjitm" = "no" ]; then
+  jit_target_objs="$jit_target_objs default-jit.o"
+fi
+
 # Support for --with-cpu and related options (and a few unrelated options,
 # too).
 case ${with_cpu} in
@@ -5922,6 +5942,7 @@ case ${target} in
 		c_target_objs="${c_target_objs} ${cpu_type}-c.o"
 		cxx_target_objs="${cxx_target_objs} ${cpu_type}-c.o"
 		d_target_objs="${d_target_objs} ${cpu_type}-d.o"
+		jit_target_objs="${jit_target_objs} ${cpu_type}-jit.o"
 		tmake_file="${cpu_type}/t-${cpu_type} ${tmake_file}"
 		;;
 
diff --git a/gcc/config/default-jit.cc b/gcc/config/default-jit.cc
new file mode 100644
index 00000000000..d286d6c4caa
--- /dev/null
+++ b/gcc/config/default-jit.cc
@@ -0,0 +1,29 @@
+/* Default JIT language target hooks initializer.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm_jit.h"
+#include "jit/jit-target.h"
+#include "jit/jit-target-def.h"
+
+/* Do not include tm.h or tm_p.h here; definitions needed by the target
+   architecture to initialize targetjitm should instead be added to
+   tm_jit.h.  */
+
+struct gcc_targetjitm targetjitm = TARGETJITM_INITIALIZER;
diff --git a/gcc/config/i386/i386-jit.cc b/gcc/config/i386/i386-jit.cc
new file mode 100644
index 00000000000..38b3f66e686
--- /dev/null
+++ b/gcc/config/i386/i386-jit.cc
@@ -0,0 +1,195 @@
+/* Subroutines for the JIT front end on the x86 architecture.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#define IN_TARGET_CODE 1
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "target.h"
+#include "tm.h"
+#include "tm_jit.h"
+#include "jit/jit-target.h"
+#include "jit/jit-target-def.h"
+
+/* Implement TARGET_JIT_REGISTER_CPU_TARGET_INFO.  */
+
+extern const char *host_detect_local_cpu (int argc, const char **argv);
+
+#if TARGET_64BIT_DEFAULT
+const char* x86_bits = "64";
+#else
+const char* x86_bits = "32";
+#endif
+
+void
+ix86_jit_register_target_info (void)
+{
+  const char *params[] = {"arch", x86_bits};
+  const char* local_cpu = host_detect_local_cpu (2, params);
+  std::string arch = local_cpu;
+  free (const_cast <char *> (local_cpu));
+
+  const char* arg = "-march=";
+  size_t arg_pos = arch.find (arg) + strlen (arg);
+  size_t end_pos = arch.find (" ", arg_pos);
+
+  std::string cpu = arch.substr (arg_pos, end_pos - arg_pos);
+  jit_target_set_arch (cpu);
+
+  jit_target_set_128bit_int_support (targetm.scalar_mode_supported_p (TImode));
+
+  if (TARGET_MMX)
+    jit_add_target_info ("target_feature", "mmx");
+  if (TARGET_SSE)
+    jit_add_target_info ("target_feature", "sse");
+  if (TARGET_SSE2)
+    jit_add_target_info ("target_feature", "sse2");
+  if (TARGET_SSE3)
+    jit_add_target_info ("target_feature", "sse3");
+  if (TARGET_SSSE3)
+    jit_add_target_info ("target_feature", "ssse3");
+  if (TARGET_SSE4_1)
+    jit_add_target_info ("target_feature", "sse4.1");
+  if (TARGET_SSE4_2)
+    jit_add_target_info ("target_feature", "sse4.2");
+  if (TARGET_AES)
+    jit_add_target_info ("target_feature", "aes");
+  if (TARGET_SHA)
+    jit_add_target_info ("target_feature", "sha");
+  if (TARGET_AVX)
+    jit_add_target_info ("target_feature", "avx");
+  if (TARGET_AVX2)
+    jit_add_target_info ("target_feature", "avx2");
+  if (TARGET_AVX512F)
+    jit_add_target_info ("target_feature", "avx512f");
+  if (TARGET_AVX512ER)
+    jit_add_target_info ("target_feature", "avx512er");
+  if (TARGET_AVX512CD)
+    jit_add_target_info ("target_feature", "avx512cd");
+  if (TARGET_AVX512PF)
+    jit_add_target_info ("target_feature", "avx512pf");
+  if (TARGET_AVX512DQ)
+    jit_add_target_info ("target_feature", "avx512dq");
+  if (TARGET_AVX512BW)
+    jit_add_target_info ("target_feature", "avx512bw");
+  if (TARGET_AVX512VL)
+    jit_add_target_info ("target_feature", "avx512vl");
+  if (TARGET_AVX512VBMI)
+    jit_add_target_info ("target_feature", "avx512vbmi");
+  if (TARGET_AVX512IFMA)
+    jit_add_target_info ("target_feature", "avx512ifma");
+  if (TARGET_AVX512VPOPCNTDQ)
+    jit_add_target_info ("target_feature", "avx512vpopcntdq");
+  if (TARGET_FMA)
+    jit_add_target_info ("target_feature", "fma");
+  if (TARGET_RTM)
+    jit_add_target_info ("target_feature", "rtm");
+  if (TARGET_SSE4A)
+    jit_add_target_info ("target_feature", "sse4a");
+  if (TARGET_BMI)
+  {
+    jit_add_target_info ("target_feature", "bmi1");
+    jit_add_target_info ("target_feature", "bmi");
+  }
+  if (TARGET_BMI2)
+    jit_add_target_info ("target_feature", "bmi2");
+  if (TARGET_LZCNT)
+    jit_add_target_info ("target_feature", "lzcnt");
+  if (TARGET_TBM)
+    jit_add_target_info ("target_feature", "tbm");
+  if (TARGET_POPCNT)
+    jit_add_target_info ("target_feature", "popcnt");
+  if (TARGET_RDRND)
+  {
+    jit_add_target_info ("target_feature", "rdrand");
+    jit_add_target_info ("target_feature", "rdrnd");
+  }
+  if (TARGET_F16C)
+    jit_add_target_info ("target_feature", "f16c");
+  if (TARGET_RDSEED)
+    jit_add_target_info ("target_feature", "rdseed");
+  if (TARGET_ADX)
+    jit_add_target_info ("target_feature", "adx");
+  if (TARGET_FXSR)
+    jit_add_target_info ("target_feature", "fxsr");
+  if (TARGET_XSAVE)
+    jit_add_target_info ("target_feature", "xsave");
+  if (TARGET_XSAVEOPT)
+    jit_add_target_info ("target_feature", "xsaveopt");
+  if (TARGET_XSAVEC)
+    jit_add_target_info ("target_feature", "xsavec");
+  if (TARGET_XSAVES)
+    jit_add_target_info ("target_feature", "xsaves");
+  if (TARGET_VPCLMULQDQ)
+  {
+    jit_add_target_info ("target_feature", "pclmulqdq");
+    jit_add_target_info ("target_feature", "vpclmulqdq");
+  }
+  if (TARGET_CMPXCHG16B)
+    jit_add_target_info ("target_feature", "cmpxchg16b");
+  if (TARGET_MOVBE)
+    jit_add_target_info ("target_feature", "movbe");
+  if (TARGET_AVX512VBMI2)
+    jit_add_target_info ("target_feature", "avx512vbmi2");
+  if (TARGET_PKU)
+    jit_add_target_info ("target_feature", "pku");
+  if (TARGET_AVX512VNNI)
+    jit_add_target_info ("target_feature", "avx512vnni");
+  if (TARGET_AVX512BF16)
+    jit_add_target_info ("target_feature", "avx512bf16");
+  if (TARGET_AVX512BITALG)
+    jit_add_target_info ("target_feature", "avx512bitalg");
+  if (TARGET_AVX512VP2INTERSECT)
+    jit_add_target_info ("target_feature", "avx512vp2intersect");
+  if (TARGET_PCLMUL)
+    jit_add_target_info ("target_feature", "pclmul");
+  if (TARGET_GFNI)
+    jit_add_target_info ("target_feature", "gfni");
+  if (TARGET_FMA4)
+    jit_add_target_info ("target_feature", "fma4");
+  if (TARGET_XOP)
+    jit_add_target_info ("target_feature", "xop");
+
+  if (TARGET_VAES)
+    jit_add_target_info ("target_feature", "vaes");
+  if (TARGET_LWP)
+    jit_add_target_info ("target_feature", "lwp");
+  if (TARGET_FSGSBASE)
+    jit_add_target_info ("target_feature", "fsgsbase");
+  if (TARGET_SHSTK)
+    jit_add_target_info ("target_feature", "shstk");
+  if (TARGET_PRFCHW)
+    jit_add_target_info ("target_feature", "prfchw");
+  if (TARGET_MWAITX)
+    jit_add_target_info ("target_feature", "mwaitx");
+  if (TARGET_CLZERO)
+    jit_add_target_info ("target_feature", "clzero");
+  if (TARGET_CLDEMOTE)
+    jit_add_target_info ("target_feature", "cldemote");
+  if (TARGET_PTWRITE)
+    jit_add_target_info ("target_feature", "ptwrite");
+  bool hasERMSB = ix86_arch == PROCESSOR_HASWELL
+    || ix86_arch == PROCESSOR_SKYLAKE || ix86_arch == PROCESSOR_SKYLAKE_AVX512
+    || ix86_arch == PROCESSOR_CANNONLAKE
+    || ix86_arch == PROCESSOR_ICELAKE_CLIENT
+    || ix86_arch == PROCESSOR_ICELAKE_SERVER
+    || ix86_arch == PROCESSOR_CASCADELAKE || ix86_arch == PROCESSOR_TIGERLAKE
+    || ix86_arch == PROCESSOR_COOPERLAKE;
+  if (hasERMSB)
+    jit_add_target_info ("target_feature", "ermsbd");
+}
diff --git a/gcc/config/i386/i386-jit.h b/gcc/config/i386/i386-jit.h
new file mode 100644
index 00000000000..4f05e88003f
--- /dev/null
+++ b/gcc/config/i386/i386-jit.h
@@ -0,0 +1,22 @@
+/* Definitions for the jit front end on the x86 architecture.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+/* In i386-jit.cc  */
+extern void ix86_jit_register_target_info (void);
+
+/* Target hooks for jit language.  */
+#define TARGET_JIT_REGISTER_CPU_TARGET_INFO ix86_jit_register_target_info
diff --git a/gcc/config/i386/t-i386 b/gcc/config/i386/t-i386
index f85817d698c..5a24ecea055 100644
--- a/gcc/config/i386/t-i386
+++ b/gcc/config/i386/t-i386
@@ -50,6 +50,10 @@ i386-rust.o: $(srcdir)/config/i386/i386-rust.cc
 	$(COMPILE) $<
 	$(POSTCOMPILE)
 
+i386-jit.o: $(srcdir)/config/i386/i386-jit.cc
+	$(COMPILE) $<
+	$(POSTCOMPILE)
+
 i386-options.o: $(srcdir)/config/i386/i386-options.cc
 	$(COMPILE) $<
 	$(POSTCOMPILE)
diff --git a/gcc/config/linux-jit.cc b/gcc/config/linux-jit.cc
new file mode 100644
index 00000000000..e85a6f3be18
--- /dev/null
+++ b/gcc/config/linux-jit.cc
@@ -0,0 +1,36 @@
+/* Linux support needed only by jit front-end.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_jit.h"
+#include "jit/jit-target.h"
+#include "jit/jit-target-def.h"
+
+/* Implement TARGET_JIT_REGISTER_OS_TARGET_INFO for Linux targets.  */
+
+static void
+linux_jit_register_target_info (void)
+{
+}
+
+#undef TARGET_JIT_REGISTER_OS_TARGET_INFO
+#define TARGET_JIT_REGISTER_OS_TARGET_INFO linux_jit_register_target_info
+
+struct gcc_targetjitm targetjitm = TARGETJITM_INITIALIZER;
diff --git a/gcc/config/t-linux b/gcc/config/t-linux
index 96593fbf27f..14376825d79 100644
--- a/gcc/config/t-linux
+++ b/gcc/config/t-linux
@@ -27,3 +27,7 @@ linux-d.o: $(srcdir)/config/linux-d.cc
 linux-rust.o: $(srcdir)/config/linux-rust.cc
 	  $(COMPILE) $<
 	  $(POSTCOMPILE)
+
+linux-jit.o: $(srcdir)/config/linux-jit.cc
+	  $(COMPILE) $<
+	  $(POSTCOMPILE)
diff --git a/gcc/configure b/gcc/configure
index 0d818ae6850..e359d2fbdcc 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -647,6 +647,7 @@ GMPLIBS
 target_cpu_default
 rust_target_objs
 d_target_objs
+jit_target_objs
 fortran_target_objs
 cxx_target_objs
 c_target_objs
@@ -658,6 +659,8 @@ tm_rust_include_list
 tm_rust_file_list
 tm_d_include_list
 tm_d_file_list
+tm_jit_include_list
+tm_jit_file_list
 tm_p_include_list
 tm_p_file_list
 tm_defines
@@ -13629,6 +13632,17 @@ for f in $tm_rust_file; do
   esac
 done
 
+tm_jit_file_list=
+tm_jit_include_list=
+for f in $tm_jit_file; do
+  case $f in
+    * )
+       tm_jit_file_list="${tm_jit_file_list} \$(srcdir)/config/$f"
+       tm_jit_include_list="${tm_jit_include_list} config/$f"
+       ;;
+  esac
+done
+
 xm_file_list=
 xm_include_list=
 for f in $xm_file; do
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 764a33f0b04..f37409ba77d 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -2451,6 +2451,17 @@ for f in $tm_rust_file; do
   esac
 done
 
+tm_jit_file_list=
+tm_jit_include_list=
+for f in $tm_jit_file; do
+  case $f in
+    * )
+       tm_jit_file_list="${tm_jit_file_list} \$(srcdir)/config/$f"
+       tm_jit_include_list="${tm_jit_include_list} config/$f"
+       ;;
+  esac
+done
+
 xm_file_list=
 xm_include_list=
 for f in $xm_file; do
@@ -7488,6 +7499,8 @@ AC_SUBST(tm_d_file_list)
 AC_SUBST(tm_d_include_list)
 AC_SUBST(tm_rust_file_list)
 AC_SUBST(tm_rust_include_list)
+AC_SUBST(tm_jit_file_list)
+AC_SUBST(tm_jit_include_list)
 AC_SUBST(xm_file_list)
 AC_SUBST(xm_include_list)
 AC_SUBST(xm_defines)
@@ -7497,6 +7510,7 @@ AC_SUBST(cxx_target_objs)
 AC_SUBST(fortran_target_objs)
 AC_SUBST(d_target_objs)
 AC_SUBST(rust_target_objs)
+AC_SUBST(jit_target_objs)
 AC_SUBST(target_cpu_default)
 
 AC_SUBST_FILE(language_hooks)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index f7ac806ff15..5d8857ee07c 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -124,6 +124,14 @@ If targets initialize @code{targetrustm} themselves, they should set
 @code{target_has_targetrustm=yes} in @file{config.gcc}; otherwise a
 default definition is used.
 
+Similarly, there is a @code{targetjitm} variable for hooks that are
+specific to the jit front end, documented as ``JIT Target Hook''.
+This is declared in @file{jit/jit-target.h}, the initializer
+@code{TARGETJITM_INITIALIZER} in @file{jit/jit-target-def.h}.  If targets
+initialize @code{targetjitm} themselves, they should set
+@code{target_has_targetjitm=yes} in @file{config.gcc}; otherwise a default
+definition is used.
+
 @node Driver
 @section Controlling the Compilation Driver, @file{gcc}
 @cindex driver
@@ -11006,6 +11014,24 @@ Similar to @code{TARGET_RUST_CPU_INFO}, but is used for configuration info
 relating to the target operating system.
 @end deftypefn
 
+@node JIT Language and ABI
+@section JIT ABI parameters
+@cindex parameters, jit abi
+
+@deftypefn {JIT Target Hook} void TARGET_JIT_REGISTER_CPU_TARGET_INFO (void)
+Register all target information keys relating to the target CPU using the
+function @code{jit_add_target_info_handlers}, which takes a
+@samp{struct jit_target_info_spec} (defined in @file{jit/jit-target.h}).  The
+keys added by this hook are made available at compile time by the
+@code{__traits(getTargetInfo)} extension, the result is an expression
+describing the requested target information.
+@end deftypefn
+
+@deftypefn {JIT Target Hook} void TARGET_JIT_REGISTER_OS_TARGET_INFO (void)
+Same as @code{TARGET_JIT_CPU_TARGET_INFO}, but is used for keys relating to
+the target operating system.
+@end deftypefn
+
 @node Named Address Spaces
 @section Adding support for named address spaces
 @cindex named address spaces
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 141027e0bb4..7ab80266595 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -124,6 +124,14 @@ If targets initialize @code{targetrustm} themselves, they should set
 @code{target_has_targetrustm=yes} in @file{config.gcc}; otherwise a
 default definition is used.
 
+Similarly, there is a @code{targetjitm} variable for hooks that are
+specific to the jit front end, documented as ``JIT Target Hook''.
+This is declared in @file{jit/jit-target.h}, the initializer
+@code{TARGETJITM_INITIALIZER} in @file{jit/jit-target-def.h}.  If targets
+initialize @code{targetjitm} themselves, they should set
+@code{target_has_targetjitm=yes} in @file{config.gcc}; otherwise a default
+definition is used.
+
 @node Driver
 @section Controlling the Compilation Driver, @file{gcc}
 @cindex driver
@@ -7178,6 +7186,14 @@ floating-point support; they are not included in this mechanism.
 
 @hook TARGET_RUST_OS_INFO
 
+@node JIT Language and ABI
+@section JIT ABI parameters
+@cindex parameters, jit abi
+
+@hook TARGET_JIT_REGISTER_CPU_TARGET_INFO
+
+@hook TARGET_JIT_REGISTER_OS_TARGET_INFO
+
 @node Named Address Spaces
 @section Adding support for named address spaces
 @cindex named address spaces
diff --git a/gcc/genhooks.cc b/gcc/genhooks.cc
index 49414eca531..7064d9659dd 100644
--- a/gcc/genhooks.cc
+++ b/gcc/genhooks.cc
@@ -36,6 +36,7 @@ static struct hook_desc hook_array[] = {
 #include "common/common-target.def"
 #include "d/d-target.def"
 #include "rust/rust-target.def"
+#include "jit/jit-target.def"
 #undef DEFHOOK
 };
 
diff --git a/gcc/jit/Make-lang.in b/gcc/jit/Make-lang.in
index 3fd564a5932..19ef589e55c 100644
--- a/gcc/jit/Make-lang.in
+++ b/gcc/jit/Make-lang.in
@@ -120,7 +120,7 @@ jit.serial = $(LIBGCCJIT_FILENAME)
 # Tell GNU make to ignore these if they exist.
 .PHONY: jit
 
-jit_OBJS = attribs.o \
+JIT_OBJS = attribs.o \
 	jit/dummy-frontend.o \
 	jit/libgccjit.o \
 	jit/jit-logging.o \
@@ -129,13 +129,17 @@ jit_OBJS = attribs.o \
 	jit/jit-result.o \
 	jit/jit-tempdir.o \
 	jit/jit-builtins.o \
+	jit/jit-target.o \
 	jit/jit-spec.o \
 	gcc.o
 
 ifneq (,$(findstring mingw,$(target)))
-jit_OBJS += jit/jit-w32.o
+JIT_OBJS += jit/jit-w32.o
 endif
 
+# All language-specific object files for jit.
+jit_OBJS = $(JIT_OBJS) $(JIT_TARGET_OBJS)
+
 # Use strict warnings for this front end.
 jit-warn = $(STRICT_WARN)
 
diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst
index ebede440ee4..fe73caa3982 100644
--- a/gcc/jit/docs/topics/compatibility.rst
+++ b/gcc/jit/docs/topics/compatibility.rst
@@ -378,3 +378,17 @@ alignment of a variable:
 --------------------
 ``LIBGCCJIT_ABI_25`` covers the addition of
 :func:`gcc_jit_type_get_restrict`
+
+.. _LIBGCCJIT_ABI_26:
+
+``LIBGCCJIT_ABI_26``
+--------------------
+``LIBGCCJIT_ABI_26`` covers the addition of functions to query the target
+information:
+
+  * :func:`gcc_jit_type_get_restrict`
+  * :func:`gcc_jit_context_get_target_info`
+  * :func:`gcc_jit_target_info_release`
+  * :func:`gcc_jit_target_info_cpu_supports`
+  * :func:`gcc_jit_target_info_arch`
+  * :func:`gcc_jit_target_info_supports_128bit_int`
diff --git a/gcc/jit/docs/topics/compilation.rst b/gcc/jit/docs/topics/compilation.rst
index 0911f108ba4..6db1de82c7d 100644
--- a/gcc/jit/docs/topics/compilation.rst
+++ b/gcc/jit/docs/topics/compilation.rst
@@ -199,3 +199,54 @@ The available kinds of output are:
 .. c:macro:: GCC_JIT_OUTPUT_KIND_EXECUTABLE
 
    Compile the context to an executable.
+
+
+Getting information about a target
+**********************************
+
+You can query the target information by using the following API:
+
+.. function:: gcc_jit_target_info * \
+              gcc_jit_context_get_target_info (gcc_jit_context *ctxt)
+
+   Compute the information about a target.
+
+   If the result is non-NULL, the caller becomes responsible for
+   calling :func:`gcc_jit_target_info_release` on it once they're done
+   with it.
+
+.. function:: void \
+              gcc_jit_target_info_release (gcc_jit_target_info *info)
+
+   This function releases all resources associated with the given target info.
+
+.. function:: int \
+              gcc_jit_target_info_cpu_supports (gcc_jit_target_info *info,
+                                                const char *feature)
+
+   Check if the specified target INFO supports the cpu FEATURE.
+
+.. function:: const char * \
+              gcc_jit_target_info_arch (gcc_jit_target_info *info)
+
+   Get the architecture of the currently running CPU.
+
+.. function:: int \
+              gcc_jit_target_info_supports_128bit_int (gcc_jit_target_info *info)
+
+   Check if the specified target INFO supports 128-bit integers.
+
+   The API entrypoints relating to the target info:
+
+      * :c:func:`gcc_jit_context_get_target_info`
+      * :c:func:`gcc_jit_target_info_release`
+      * :c:func:`gcc_jit_target_info_cpu_supports`
+      * :c:func:`gcc_jit_target_info_arch`
+      * :c:func:`gcc_jit_target_info_supports_128bit_int`
+
+   were added in :ref:`LIBGCCJIT_ABI_26`; you can test for their presence
+   using
+
+   .. code-block:: c
+
+      #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc
index 18cc4da25b8..bf53c039e85 100644
--- a/gcc/jit/jit-playback.cc
+++ b/gcc/jit/jit-playback.cc
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "jit-result.h"
 #include "jit-builtins.h"
 #include "jit-tempdir.h"
+#include "jit-target.h"
 
 #ifdef _WIN32
 #include "jit-w32.h"
@@ -3226,6 +3227,7 @@ replay ()
   JIT_LOG_SCOPE (get_logger ());
 
   init_types ();
+  jit_target_init ();
 
   /* Replay the recorded events:  */
   timevar_push (TV_JIT_REPLAY);
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index f9e29d0baec..afa6d281188 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -43,9 +43,10 @@ namespace playback {
 
 /* playback::context is an abstract base class.
 
-   The two concrete subclasses are:
+   The three concrete subclasses are:
    - playback::compile_to_memory
-   - playback::compile_to_file.  */
+   - playback::compile_to_file
+   - playback::get_target_info.  */
 
 class context : public log_user
 {
@@ -405,6 +406,18 @@ class compile_to_file : public context
   const char *m_output_path;
 };
 
+class get_target_info : public context
+{
+ public:
+  get_target_info (recording::context *ctxt) : context (ctxt)
+  {
+  }
+
+  void postprocess (const char *) final override
+  {
+  }
+};
+
 
 /* A temporary wrapper object.
    These objects are (mostly) only valid during replay.
diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc
index 9b5b8005ebe..94978170c10 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -1525,6 +1525,25 @@ recording::context::compile_to_file (enum gcc_jit_output_kind output_kind,
   replayer.compile ();
 }
 
+void
+recording::context::get_target_info ()
+{
+  JIT_LOG_SCOPE (get_logger ());
+
+  log_all_options ();
+
+  if (errors_occurred ())
+    return;
+
+  add_driver_option ("-fsyntax-only");
+
+  /* Set up a get_target_info playback context.  */
+  ::gcc::jit::playback::get_target_info replayer (this);
+
+  /* Use it.  */
+  replayer.compile ();
+}
+
 /* Format the given error using printf's conventions, print
    it to stderr, and add it to the context.  */
 
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 4a8082991fb..a090c85b19e 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -283,6 +283,9 @@ public:
   compile_to_file (enum gcc_jit_output_kind output_kind,
 		   const char *output_path);
 
+  void
+  get_target_info ();
+
   void
   add_error (location *loc, const char *fmt, ...)
       GNU_PRINTF(3, 4);
diff --git a/gcc/jit/jit-target-def.h b/gcc/jit/jit-target-def.h
new file mode 100644
index 00000000000..dcb342fafe7
--- /dev/null
+++ b/gcc/jit/jit-target-def.h
@@ -0,0 +1,20 @@
+/* jit-target-def.h -- Default initializers for jit target hooks.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 3, or (at your option) any
+   later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "jit/jit-target-hooks-def.h"
+#include "tree.h"
+#include "hooks.h"
diff --git a/gcc/jit/jit-target.cc b/gcc/jit/jit-target.cc
new file mode 100644
index 00000000000..e8ac847d3df
--- /dev/null
+++ b/gcc/jit/jit-target.cc
@@ -0,0 +1,89 @@
+/* jit-target.cc -- Target interface for the jit front end.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+
+#include "tree.h"
+#include "memmodel.h"
+#include "fold-const.h"
+#include "diagnostic.h"
+#include "stor-layout.h"
+#include "tm.h"
+#include "tm_p.h"
+#include "target.h"
+#include "calls.h"
+
+#include "jit-target.h"
+
+#include <algorithm>
+
+static target_info jit_target_info;
+
+/* Initialize all variables of the Target structure.  */
+
+void
+jit_target_init ()
+{
+  /* Initialize target info tables, the keys required by the language are added
+     last, so that the OS and CPU handlers can override.  */
+  targetjitm.jit_register_cpu_target_info ();
+  targetjitm.jit_register_os_target_info ();
+}
+
+/* Add all target info in HANDLERS to JIT_TARGET_INFO for use by
+   jit_has_target_value ().  */
+
+void
+jit_add_target_info (const char *key, const char *value)
+{
+  if (jit_target_info.m_info.find (key) == jit_target_info.m_info.end ())
+    jit_target_info.m_info.insert ({key, {value}});
+  else
+    jit_target_info.m_info[key].insert (value);
+}
+
+void
+jit_target_set_arch (std::string const& arch)
+{
+  jit_target_info.m_arch = arch;
+}
+
+void
+jit_target_set_128bit_int_support (bool support)
+{
+  jit_target_info.m_supports_128bit_int = support;
+}
+
+target_info *
+jit_get_target_info ()
+{
+  target_info *info = new target_info {jit_target_info};
+  jit_target_info = target_info{};
+  return info;
+}
+
+bool
+target_info::has_target_value (const char *key, const char *value)
+{
+  if (m_info.find (key) == m_info.end ())
+    return false;
+
+  auto& set = m_info[key];
+  return set.find (value) != set.end ();
+}
diff --git a/gcc/jit/jit-target.def b/gcc/jit/jit-target.def
new file mode 100644
index 00000000000..de0d717b365
--- /dev/null
+++ b/gcc/jit/jit-target.def
@@ -0,0 +1,52 @@
+/* jit-target.def -- Target hook definitions for the jit front end.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 3, or (at your option) any
+   later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* See target-hooks-macros.h for details of macros that should be
+   provided by the including file, and how to use them here.  */
+
+#include "target-hooks-macros.h"
+
+#undef HOOK_TYPE
+#define HOOK_TYPE "JIT Target Hook"
+
+HOOK_VECTOR (TARGETJITM_INITIALIZER, gcc_targetjitm)
+
+#undef HOOK_PREFIX
+#define HOOK_PREFIX "TARGET_"
+
+/* getTargetInfo keys relating to the target CPU.  */
+DEFHOOK
+(jit_register_cpu_target_info,
+ "Register all target information keys relating to the target CPU using the\n\
+function @code{jit_add_target_info_handlers}, which takes a\n\
+@samp{struct jit_target_info_spec} (defined in @file{jit/jit-target.h}).  The\n\
+keys added by this hook are made available at compile time by the\n\
+@code{__traits(getTargetInfo)} extension, the result is an expression\n\
+describing the requested target information.",
+ void, (void),
+ hook_void_void)
+
+/* getTargetInfo keys relating to the target OS.  */
+DEFHOOK
+(jit_register_os_target_info,
+ "Same as @code{TARGET_JIT_CPU_TARGET_INFO}, but is used for keys relating to\n\
+the target operating system.",
+ void, (void),
+ hook_void_void)
+
+/* Close the 'struct gcc_targetdm' definition.  */
+HOOK_VECTOR_END (C90_EMPTY_HACK)
diff --git a/gcc/jit/jit-target.h b/gcc/jit/jit-target.h
new file mode 100644
index 00000000000..6443cd71025
--- /dev/null
+++ b/gcc/jit/jit-target.h
@@ -0,0 +1,73 @@
+/* jit-target.h -- Data structure definitions for target-specific jit behavior.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 3, or (at your option) any
+   later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_JIT_TARGET_H
+#define GCC_JIT_TARGET_H
+
+#define DEFHOOKPOD(NAME, DOC, TYPE, INIT) TYPE NAME;
+#define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) TYPE (* NAME) PARAMS;
+#define DEFHOOK_UNDOC DEFHOOK
+#define HOOKSTRUCT(FRAGMENT) FRAGMENT
+
+#include "jit-target.def"
+
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+
+static size_t hash_cstr (const char *s)
+{
+  const size_t seed = 0;
+  return std::_Hash_bytes (s, std::strlen (s), seed);
+}
+
+struct CStringHash {
+  size_t operator() (const char* const &string) const {
+    auto res = hash_cstr (string);
+    return res;
+  }
+};
+
+struct CStringEqual {
+  bool operator() (const char* const &string1,
+		   const char* const &string2) const {
+      return strcmp (string1, string2) == 0;
+  }
+};
+
+struct target_info {
+  public:
+    bool has_target_value (const char *key, const char *value);
+
+    std::unordered_map<const char *,
+		       std::unordered_set<const char *, CStringHash,
+					  CStringEqual>,
+		       CStringHash, CStringEqual> m_info;
+    std::string m_arch;
+    bool m_supports_128bit_int = false;
+};
+
+/* Each target can provide their own.  */
+extern struct gcc_targetjitm targetjitm;
+
+extern void jit_target_init ();
+extern void jit_target_set_arch (std::string const& arch);
+extern void jit_target_set_128bit_int_support (bool support);
+extern void jit_add_target_info (const char *key, const char *value);
+extern target_info * jit_get_target_info ();
+
+#endif /* GCC_JIT_TARGET_H  */
diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
index 0451b4df7f9..15ba3acc95c 100644
--- a/gcc/jit/libgccjit.cc
+++ b/gcc/jit/libgccjit.cc
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "libgccjit.h"
 #include "jit-recording.h"
 #include "jit-result.h"
+#include "jit-target.h"
 
 /* The opaque types used by the public API are actually subclasses
    of the gcc::jit::recording classes.  */
@@ -44,6 +45,10 @@ struct gcc_jit_result : public gcc::jit::result
 {
 };
 
+struct gcc_jit_target_info : public target_info
+{
+};
+
 struct gcc_jit_object : public gcc::jit::recording::memento
 {
 };
@@ -3679,6 +3684,44 @@ gcc_jit_context_compile_to_file (gcc_jit_context *ctxt,
   ctxt->compile_to_file (output_kind, output_path);
 }
 
+gcc_jit_target_info *
+gcc_jit_context_get_target_info (gcc_jit_context *ctxt)
+{
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  JIT_LOG_FUNC (ctxt->get_logger ());
+
+  ctxt->log ("get_target_info of ctxt: %p", (void *)ctxt);
+
+  ctxt->get_target_info ();
+
+  return (gcc_jit_target_info*) jit_get_target_info ();
+}
+
+void
+gcc_jit_target_info_release (gcc_jit_target_info *info)
+{
+  RETURN_IF_FAIL (info, NULL, NULL, "NULL info");
+  delete info;
+}
+
+int
+gcc_jit_target_info_cpu_supports (gcc_jit_target_info *info,
+				  const char *feature)
+{
+  return info->has_target_value ("target_feature", feature);
+}
+
+const char *
+gcc_jit_target_info_arch (gcc_jit_target_info *info)
+{
+  return info->m_arch.c_str ();
+}
+
+int
+gcc_jit_target_info_supports_128bit_int (gcc_jit_target_info *info)
+{
+  return info->m_supports_128bit_int;
+}
 
 /* Public entrypoint.  See description in libgccjit.h.
 
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index 749f6c24177..a289862311b 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -52,6 +52,9 @@ typedef struct gcc_jit_context gcc_jit_context;
 /* A gcc_jit_result encapsulates the result of an in-memory compilation.  */
 typedef struct gcc_jit_result gcc_jit_result;
 
+/* A gcc_jit_target_info encapsulates the target info.  */
+typedef struct gcc_jit_target_info gcc_jit_target_info;
+
 /* An object created within a context.  Such objects are automatically
    cleaned up when the context is released.
 
@@ -1999,6 +2002,63 @@ gcc_jit_vector_type_get_element_type (gcc_jit_vector_type *vector_type);
 extern gcc_jit_type *
 gcc_jit_type_unqualified (gcc_jit_type *type);
 
+/* Create a gcc_jit_target_info instance.
+
+   This API entrypoint was added in LIBGCCJIT_ABI_26; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+
+extern gcc_jit_target_info *
+gcc_jit_context_get_target_info (gcc_jit_context *ctxt);
+
+/* Release a gcc_jit_target_info instance.
+
+   This API entrypoint was added in LIBGCCJIT_ABI_26; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+
+extern void
+gcc_jit_target_info_release (gcc_jit_target_info *info);
+
+/* Returns non-zero if FEATURE is supported by the specified target.
+
+   This API entrypoint was added in LIBGCCJIT_ABI_26; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+
+extern int
+gcc_jit_target_info_cpu_supports (gcc_jit_target_info *info,
+				  const char *feature);
+
+/* Returns the ARCH of the currently running CPU.
+
+   This API entrypoint was added in LIBGCCJIT_ABI_26; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+
+extern const char *
+gcc_jit_target_info_arch (gcc_jit_target_info *info);
+
+/* Returns non-zero if the target natively supports 128-bit integers.
+
+   This API entrypoint was added in LIBGCCJIT_ABI_26; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+
+extern int
+gcc_jit_target_info_supports_128bit_int (gcc_jit_target_info *info);
+
+/* The target info API was added in LIBGCCJIT_ABI_26; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+#define LIBGCCJIT_HAVE_TARGET_INFO_API
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index 8b90a0e2ff3..30f08ce67d7 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -276,3 +276,12 @@ LIBGCCJIT_ABI_25 {
   global:
     gcc_jit_type_get_restrict;
 } LIBGCCJIT_ABI_24;
+
+LIBGCCJIT_ABI_26 {
+  global:
+    gcc_jit_context_get_target_info;
+    gcc_jit_target_info_release;
+    gcc_jit_target_info_cpu_supports;
+    gcc_jit_target_info_arch;
+    gcc_jit_target_info_supports_128bit_int;
+} LIBGCCJIT_ABI_25;
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index e762563f9bd..f0f7356d687 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -322,6 +322,9 @@
 /* test-setting-alignment.c: This can't be in the testcases array as it
    is target-specific.  */
 
+/* test-target-info.c: This can't be in the testcases array as it
+   is target-specific.  */
+
 /* test-string-literal.c */
 #define create_code create_code_string_literal
 #define verify_code verify_code_string_literal
diff --git a/gcc/testsuite/jit.dg/test-target-info.c b/gcc/testsuite/jit.dg/test-target-info.c
new file mode 100644
index 00000000000..db5591edcbd
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-target-info.c
@@ -0,0 +1,63 @@
+/* { dg-do compile { target x86_64-*-* } } */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#define TEST_PROVIDES_MAIN
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+}
+
+int
+main (int argc, char **argv)
+{
+  /*  This is the same as the main provided by harness.h, but calls gcc_jit_context_get_target_info.  */
+  gcc_jit_context *ctxt;
+  ctxt = gcc_jit_context_acquire ();
+  if (!ctxt)
+    {
+      fail ("gcc_jit_context_acquire failed");
+      return -1;
+    }
+  gcc_jit_target_info* info = gcc_jit_context_get_target_info (ctxt);
+
+  int sse2_supported = gcc_jit_target_info_cpu_supports (info, "sse2");
+  CHECK_VALUE (sse2_supported, 1);
+
+  const char *arch = gcc_jit_target_info_arch (info);
+  // TODO: not sure what value to check here.
+  CHECK_STRING_VALUE (arch, "znver2");
+
+  int supports_128bit_int = gcc_jit_target_info_supports_128bit_int (info);
+  CHECK_VALUE (supports_128bit_int, 1);
+  gcc_jit_target_info_release (info);
+  gcc_jit_context_release (ctxt);
+
+  int i;
+
+  for (i = 1; i <= 5; i++)
+    {
+      snprintf (test, sizeof (test),
+		"%s iteration %d of %d",
+                extract_progname (argv[0]),
+                i, 5);
+
+      //printf ("ITERATION %d\n", i);
+      test_jit (argv[0], NULL);
+      //printf ("\n");
+    }
+
+  totals ();
+
+  return 0;
+}
-- 
2.42.0


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] libgccjit: Add ability to get CPU features
  2023-11-09 22:27 [PATCH] libgccjit: Add ability to get CPU features Antoni Boucher
@ 2023-11-09 23:04 ` David Malcolm
  2023-11-10  0:33   ` Antoni Boucher
                     ` (4 more replies)
  0 siblings, 5 replies; 21+ messages in thread
From: David Malcolm @ 2023-11-09 23:04 UTC (permalink / raw)
  To: Antoni Boucher, jit, gcc-patches

On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
> Hi.
> This patch adds support for getting the CPU features in libgccjit
> (bug
> 112466)
> 
> There's a TODO in the test:
> I'm not sure how to test that gcc_jit_target_info_arch returns the
> correct value since it is dependant on the CPU.
> Any idea on how to improve this?
> 
> Also, I created a CStringHash to be able to have a
> std::unordered_set<const char *>. Is there any built-in way of doing
> this?

Thanks for the patch.

Some high-level questions:

Is this specifically about detecting capabilities of the host that
libgccjit is currently running on? or how the target was configured
when libgccjit was built?

One of the benefits of libgccjit is that, in theory, we support all of
the targets that GCC already supports.  Does this patch change that, or
is this more about giving client code the ability to determine
capabilities of the specific host being compiled for?

I'm nervous about having per-target jit code.  Presumably there's a
reason that we can't reuse existing target logic here - can you please
describe what the problem is.  I see that the ChangeLog has:

> 	* config/i386/i386-jit.cc: New file.

where i386-jit.cc has almost 200 lines of nontrivial code.  Where did
this come from?  Did you base it on existing code in our source tree,
making modifications to fit the new internal API, or did you write it
from scratch?  In either case, how onerous would this be for other
targets?

I'm not at expert at target hooks (or at the i386 backend), so if we do
go with this approach I'd want someone else to review those parts of
the patch.

Have you verified that GCC builds with this patch with jit *not*
enabled in the enabled languages?

[...snip...]

A nitpick:

> +.. function:: const char * \
> +              gcc_jit_target_info_arch (gcc_jit_target_info *info)
> +
> +   Get the architecture of the currently running CPU.

What does this string look like?
How long does the pointer remain valid?

Thanks again; hope the above makes sense
Dave


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] libgccjit: Add ability to get CPU features
  2023-11-09 23:04 ` David Malcolm
@ 2023-11-10  0:33   ` Antoni Boucher
  2023-11-30 22:11     ` Antoni Boucher
  2024-03-05 15:09     ` Frontend access to target features (was Re: [PATCH] libgccjit: Add ability to get CPU features) David Malcolm
  2023-12-13 19:56   ` [PATCH] libgccjit: Add ability to get CPU features Antoni Boucher
                     ` (3 subsequent siblings)
  4 siblings, 2 replies; 21+ messages in thread
From: Antoni Boucher @ 2023-11-10  0:33 UTC (permalink / raw)
  To: David Malcolm, jit, gcc-patches

Hi.
See answers below.

On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
> On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
> > Hi.
> > This patch adds support for getting the CPU features in libgccjit
> > (bug
> > 112466)
> > 
> > There's a TODO in the test:
> > I'm not sure how to test that gcc_jit_target_info_arch returns the
> > correct value since it is dependant on the CPU.
> > Any idea on how to improve this?
> > 
> > Also, I created a CStringHash to be able to have a
> > std::unordered_set<const char *>. Is there any built-in way of
> > doing
> > this?
> 
> Thanks for the patch.
> 
> Some high-level questions:
> 
> Is this specifically about detecting capabilities of the host that
> libgccjit is currently running on? or how the target was configured
> when libgccjit was built?

I'm less sure about this part. I'll need to do more tests.

> 
> One of the benefits of libgccjit is that, in theory, we support all
> of
> the targets that GCC already supports.  Does this patch change that,
> or
> is this more about giving client code the ability to determine
> capabilities of the specific host being compiled for?

This should not change that. If it does, this is a bug.

> 
> I'm nervous about having per-target jit code.  Presumably there's a
> reason that we can't reuse existing target logic here - can you
> please
> describe what the problem is.  I see that the ChangeLog has:
> 
> > 	* config/i386/i386-jit.cc: New file.
> 
> where i386-jit.cc has almost 200 lines of nontrivial code.  Where did
> this come from?  Did you base it on existing code in our source tree,
> making modifications to fit the new internal API, or did you write it
> from scratch?  In either case, how onerous would this be for other
> targets?

This was mostly copied from the same code done for the Rust and D
frontends.
See this commit and the following:
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=b1c06fd9723453dd2b2ec306684cb806dc2b4fbb
The equivalent to i386-jit.cc is there:
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=22e3557e2d52f129f2bbfdc98688b945dba28dc9

> 
> I'm not at expert at target hooks (or at the i386 backend), so if we
> do
> go with this approach I'd want someone else to review those parts of
> the patch.
> 
> Have you verified that GCC builds with this patch with jit *not*
> enabled in the enabled languages?

I will do.

> 
> [...snip...]
> 
> A nitpick:
> 
> > +.. function:: const char * \
> > +              gcc_jit_target_info_arch (gcc_jit_target_info *info)
> > +
> > +   Get the architecture of the currently running CPU.
> 
> What does this string look like?
> How long does the pointer remain valid?

It's the march string, like "znver2", for instance.
It remains valid until we free the gcc_jit_target_info object.

> 
> Thanks again; hope the above makes sense
> Dave
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] libgccjit: Add ability to get CPU features
  2023-11-10  0:33   ` Antoni Boucher
@ 2023-11-30 22:11     ` Antoni Boucher
  2024-03-05 15:09     ` Frontend access to target features (was Re: [PATCH] libgccjit: Add ability to get CPU features) David Malcolm
  1 sibling, 0 replies; 21+ messages in thread
From: Antoni Boucher @ 2023-11-30 22:11 UTC (permalink / raw)
  To: David Malcolm, jit, gcc-patches

See more answers below.

On Thu, 2023-11-09 at 19:33 -0500, Antoni Boucher wrote:
> > Hi.
> > See answers below.
> > 
> > On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
> > > > On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
> > > > > > Hi.
> > > > > > This patch adds support for getting the CPU features in
> > > > > > libgccjit
> > > > > > (bug
> > > > > > 112466)
> > > > > > 
> > > > > > There's a TODO in the test:
> > > > > > I'm not sure how to test that gcc_jit_target_info_arch
> > > > > > returns
> > > > > > the
> > > > > > correct value since it is dependant on the CPU.
> > > > > > Any idea on how to improve this?
> > > > > > 
> > > > > > Also, I created a CStringHash to be able to have a
> > > > > > std::unordered_set<const char *>. Is there any built-in way
> > > > > > of
> > > > > > doing
> > > > > > this?
> > > > 
> > > > Thanks for the patch.
> > > > 
> > > > Some high-level questions:
> > > > 
> > > > Is this specifically about detecting capabilities of the host
> > > > that
> > > > libgccjit is currently running on? or how the target was
> > > > configured
> > > > when libgccjit was built?
> > 
> > I'm less sure about this part. I'll need to do more tests.

This detects the capabilities of the host that libgccjit is currently
running on.

> > 
> > > > 
> > > > One of the benefits of libgccjit is that, in theory, we support
> > > > all
> > > > of
> > > > the targets that GCC already supports.  Does this patch change
> > > > that,
> > > > or
> > > > is this more about giving client code the ability to determine
> > > > capabilities of the specific host being compiled for?
> > 
> > This should not change that. If it does, this is a bug.

To add to this, libgccjit will just report that the feature is not
detected when cross-compiling.

> > 
> > > > 
> > > > I'm nervous about having per-target jit code.  Presumably
> > > > there's a
> > > > reason that we can't reuse existing target logic here - can you
> > > > please
> > > > describe what the problem is.  I see that the ChangeLog has:
> > > > 
> > > > > >  * config/i386/i386-jit.cc: New file.
> > > > 
> > > > where i386-jit.cc has almost 200 lines of nontrivial code. 
> > > > Where
> > > > did
> > > > this come from?  Did you base it on existing code in our source
> > > > tree,
> > > > making modifications to fit the new internal API, or did you
> > > > write
> > > > it
> > > > from scratch?  In either case, how onerous would this be for
> > > > other
> > > > targets?
> > 
> > This was mostly copied from the same code done for the Rust and D
> > frontends.
> > See this commit and the following:
> > https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=b1c06fd9723453dd2b2ec306684cb806dc2b4fbb
> > The equivalent to i386-jit.cc is there:
> > https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=22e3557e2d52f129f2bbfdc98688b945dba28dc9
> > 
> > > > 
> > > > I'm not at expert at target hooks (or at the i386 backend), so
> > > > if
> > > > we
> > > > do
> > > > go with this approach I'd want someone else to review those
> > > > parts
> > > > of
> > > > the patch.
> > > > 
> > > > Have you verified that GCC builds with this patch with jit
> > > > *not*
> > > > enabled in the enabled languages?
> > 
> > I will do.

It does build.

> > 
> > > > 
> > > > [...snip...]
> > > > 
> > > > A nitpick:
> > > > 
> > > > > > +.. function:: const char * \
> > > > > > +              gcc_jit_target_info_arch
> > > > > > (gcc_jit_target_info
> > > > > > *info)
> > > > > > +
> > > > > > +   Get the architecture of the currently running CPU.
> > > > 
> > > > What does this string look like?
> > > > How long does the pointer remain valid?
> > 
> > It's the march string, like "znver2", for instance.
> > It remains valid until we free the gcc_jit_target_info object.
> > 
> > > > 
> > > > Thanks again; hope the above makes sense
> > > > Dave
> > > > 
> > 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] libgccjit: Add ability to get CPU features
  2023-11-09 23:04 ` David Malcolm
  2023-11-10  0:33   ` Antoni Boucher
@ 2023-12-13 19:56   ` Antoni Boucher
  2024-01-10 23:18     ` Antoni Boucher
  2024-01-11 18:49   ` Antoni Boucher
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 21+ messages in thread
From: Antoni Boucher @ 2023-12-13 19:56 UTC (permalink / raw)
  To: David Malcolm, jit, gcc-patches

David: Ping.
I guess if we want to have this merged for this release, it should be
sooner rather than later (if it's still an option).

On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
> On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
> > Hi.
> > This patch adds support for getting the CPU features in libgccjit
> > (bug
> > 112466)
> > 
> > There's a TODO in the test:
> > I'm not sure how to test that gcc_jit_target_info_arch returns the
> > correct value since it is dependant on the CPU.
> > Any idea on how to improve this?
> > 
> > Also, I created a CStringHash to be able to have a
> > std::unordered_set<const char *>. Is there any built-in way of
> > doing
> > this?
> 
> Thanks for the patch.
> 
> Some high-level questions:
> 
> Is this specifically about detecting capabilities of the host that
> libgccjit is currently running on? or how the target was configured
> when libgccjit was built?
> 
> One of the benefits of libgccjit is that, in theory, we support all
> of
> the targets that GCC already supports.  Does this patch change that,
> or
> is this more about giving client code the ability to determine
> capabilities of the specific host being compiled for?
> 
> I'm nervous about having per-target jit code.  Presumably there's a
> reason that we can't reuse existing target logic here - can you
> please
> describe what the problem is.  I see that the ChangeLog has:
> 
> > 	* config/i386/i386-jit.cc: New file.
> 
> where i386-jit.cc has almost 200 lines of nontrivial code.  Where did
> this come from?  Did you base it on existing code in our source tree,
> making modifications to fit the new internal API, or did you write it
> from scratch?  In either case, how onerous would this be for other
> targets?
> 
> I'm not at expert at target hooks (or at the i386 backend), so if we
> do
> go with this approach I'd want someone else to review those parts of
> the patch.
> 
> Have you verified that GCC builds with this patch with jit *not*
> enabled in the enabled languages?
> 
> [...snip...]
> 
> A nitpick:
> 
> > +.. function:: const char * \
> > +              gcc_jit_target_info_arch (gcc_jit_target_info *info)
> > +
> > +   Get the architecture of the currently running CPU.
> 
> What does this string look like?
> How long does the pointer remain valid?
> 
> Thanks again; hope the above makes sense
> Dave
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] libgccjit: Add ability to get CPU features
  2023-12-13 19:56   ` [PATCH] libgccjit: Add ability to get CPU features Antoni Boucher
@ 2024-01-10 23:18     ` Antoni Boucher
  0 siblings, 0 replies; 21+ messages in thread
From: Antoni Boucher @ 2024-01-10 23:18 UTC (permalink / raw)
  To: David Malcolm, jit, gcc-patches

David: Ping in case you missed it.

On Wed, 2023-12-13 at 14:56 -0500, Antoni Boucher wrote:
> David: Ping.
> I guess if we want to have this merged for this release, it should be
> sooner rather than later (if it's still an option).
> 
> On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
> > On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
> > > Hi.
> > > This patch adds support for getting the CPU features in libgccjit
> > > (bug
> > > 112466)
> > > 
> > > There's a TODO in the test:
> > > I'm not sure how to test that gcc_jit_target_info_arch returns
> > > the
> > > correct value since it is dependant on the CPU.
> > > Any idea on how to improve this?
> > > 
> > > Also, I created a CStringHash to be able to have a
> > > std::unordered_set<const char *>. Is there any built-in way of
> > > doing
> > > this?
> > 
> > Thanks for the patch.
> > 
> > Some high-level questions:
> > 
> > Is this specifically about detecting capabilities of the host that
> > libgccjit is currently running on? or how the target was configured
> > when libgccjit was built?
> > 
> > One of the benefits of libgccjit is that, in theory, we support all
> > of
> > the targets that GCC already supports.  Does this patch change
> > that,
> > or
> > is this more about giving client code the ability to determine
> > capabilities of the specific host being compiled for?
> > 
> > I'm nervous about having per-target jit code.  Presumably there's a
> > reason that we can't reuse existing target logic here - can you
> > please
> > describe what the problem is.  I see that the ChangeLog has:
> > 
> > > 	* config/i386/i386-jit.cc: New file.
> > 
> > where i386-jit.cc has almost 200 lines of nontrivial code.  Where
> > did
> > this come from?  Did you base it on existing code in our source
> > tree,
> > making modifications to fit the new internal API, or did you write
> > it
> > from scratch?  In either case, how onerous would this be for other
> > targets?
> > 
> > I'm not at expert at target hooks (or at the i386 backend), so if
> > we
> > do
> > go with this approach I'd want someone else to review those parts
> > of
> > the patch.
> > 
> > Have you verified that GCC builds with this patch with jit *not*
> > enabled in the enabled languages?
> > 
> > [...snip...]
> > 
> > A nitpick:
> > 
> > > +.. function:: const char * \
> > > +              gcc_jit_target_info_arch (gcc_jit_target_info
> > > *info)
> > > +
> > > +   Get the architecture of the currently running CPU.
> > 
> > What does this string look like?
> > How long does the pointer remain valid?
> > 
> > Thanks again; hope the above makes sense
> > Dave
> > 
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] libgccjit: Add ability to get CPU features
  2023-11-09 23:04 ` David Malcolm
  2023-11-10  0:33   ` Antoni Boucher
  2023-12-13 19:56   ` [PATCH] libgccjit: Add ability to get CPU features Antoni Boucher
@ 2024-01-11 18:49   ` Antoni Boucher
  2024-01-19 12:53   ` Antoni Boucher
  2024-01-20 14:50   ` Antoni Boucher
  4 siblings, 0 replies; 21+ messages in thread
From: Antoni Boucher @ 2024-01-11 18:49 UTC (permalink / raw)
  To: David Malcolm, jit, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2441 bytes --]

Here's an updated patch to include the change from this PATCH:
https://gcc.gnu.org/pipermail/jit/2023q4/001763.html

On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
> On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
> > Hi.
> > This patch adds support for getting the CPU features in libgccjit
> > (bug
> > 112466)
> > 
> > There's a TODO in the test:
> > I'm not sure how to test that gcc_jit_target_info_arch returns the
> > correct value since it is dependant on the CPU.
> > Any idea on how to improve this?
> > 
> > Also, I created a CStringHash to be able to have a
> > std::unordered_set<const char *>. Is there any built-in way of
> > doing
> > this?
> 
> Thanks for the patch.
> 
> Some high-level questions:
> 
> Is this specifically about detecting capabilities of the host that
> libgccjit is currently running on? or how the target was configured
> when libgccjit was built?
> 
> One of the benefits of libgccjit is that, in theory, we support all
> of
> the targets that GCC already supports.  Does this patch change that,
> or
> is this more about giving client code the ability to determine
> capabilities of the specific host being compiled for?
> 
> I'm nervous about having per-target jit code.  Presumably there's a
> reason that we can't reuse existing target logic here - can you
> please
> describe what the problem is.  I see that the ChangeLog has:
> 
> > 	* config/i386/i386-jit.cc: New file.
> 
> where i386-jit.cc has almost 200 lines of nontrivial code.  Where did
> this come from?  Did you base it on existing code in our source tree,
> making modifications to fit the new internal API, or did you write it
> from scratch?  In either case, how onerous would this be for other
> targets?
> 
> I'm not at expert at target hooks (or at the i386 backend), so if we
> do
> go with this approach I'd want someone else to review those parts of
> the patch.
> 
> Have you verified that GCC builds with this patch with jit *not*
> enabled in the enabled languages?
> 
> [...snip...]
> 
> A nitpick:
> 
> > +.. function:: const char * \
> > +              gcc_jit_target_info_arch (gcc_jit_target_info *info)
> > +
> > +   Get the architecture of the currently running CPU.
> 
> What does this string look like?
> How long does the pointer remain valid?
> 
> Thanks again; hope the above makes sense
> Dave
> 


[-- Attachment #2: 0001-libgccjit-Add-ability-to-get-CPU-features.patch --]
[-- Type: text/x-patch, Size: 51508 bytes --]

From b1e8df6da7c7876e5cb5c6fde60f0fff854888e3 Mon Sep 17 00:00:00 2001
From: Antoni Boucher <bouanto@zoho.com>
Date: Mon, 26 Jun 2023 18:29:15 -0400
Subject: [PATCH] libgccjit: Add ability to get CPU features

gcc/ChangeLog:
	PR jit/112466
	* Makefile.in (tm_jit_file_list, tm_jit_include_list, TM_JIT_H,
	JIT_TARGET_DEF, JIT_TARGET_H, JIT_TARGET_OBJS): New variables.
	(tm_jit.h, cs-tm_jit.h, jit/jit-target-hooks-def.h,
	s-jit-target-hooks-def-h, default-jit.o): New rules.
	(s-tm-texi): Also check timestamp on jit-target.def.
	(generated_files): Add TM_JIT_H and jit/jit-target-hooks-def.h.
	(build/genhooks.o): Also depend on JIT_TARGET_DEF.
	* config.gcc (tm_jit_file, jit_target_objs, target_has_targetjitm):
	New variables.
	* config/i386/t-i386 (i386-jit.o): New rule.
	* config/t-linux (linux-jit.o): New rule.
	* configure: Regenerate.
	* configure.ac (tm_jit_file_list, tm_jit_include_list,
	jit_target_objs): Add substitutes.
	* doc/tm.texi: Regenerate.
	* doc/tm.texi.in (targetjitm): Document.
	(target_has_targetjitm): Document.
	* genhooks.cc: Include jit/jit-target.def.
	* config/default-jit.cc: New file.
	* config/i386/i386-jit.cc: New file.
	* config/i386/i386-jit.h: New file.
	* config/linux-jit.cc: New file.

gcc/jit/ChangeLog:
	PR jit/112466
	* Make-lang.in (JIT_OBJS): New variable.
	* jit-playback.cc (replay): Include jit-target.h and initialize
	target.
	* jit-playback.h (class get_target_info): New class.
	* jit-recording.cc (recording::context::get_target_info): New
	method.
	* jit-recording.h (recording::context::get_target_info): New
	method.
	* libgccjit.cc: Include jit-target.h.
	(struct gcc_jit_target_info): New struct.
	(gcc_jit_context_get_target_info, gcc_jit_target_info_release,
	gcc_jit_target_info_cpu_supports, gcc_jit_target_info_arch,
	gcc_jit_target_info_supports_128bit_int): New functions.
	* libgccjit.h (gcc_jit_context_get_target_info,
	gcc_jit_target_info_release, gcc_jit_target_info_cpu_supports,
	gcc_jit_target_info_arch, gcc_jit_target_info_supports_128bit_int):
	New functions.
	* libgccjit.map (LIBGCCJIT_ABI_26): New ABI tag.
	* docs/topics/compilation.rst: Add documentation for the
	functions gcc_jit_context_get_target_info, gcc_jit_target_info_release,
	gcc_jit_target_info_cpu_supports, gcc_jit_target_info_arch,
	gcc_jit_target_info_supports_128bit_int.
	* docs/topics/compatibility.rst (LIBGCCJIT_ABI_26): New ABI tag.
	* jit-target-def.h: New file.
	* jit-target.cc: New file.
	* jit-target.def: New file.
	* jit-target.h: New file.

gcc/testsuite/ChangeLog:
	PR jit/112466
	* jit.dg/all-non-failing-tests.h: Mention
	test-target-info.c.
	* jit.dg/test-target-info.c: New test.

Signed-off-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
---
 gcc/Makefile.in                              |  36 +++-
 gcc/config.gcc                               |  21 ++
 gcc/config/default-jit.cc                    |  29 +++
 gcc/config/i386/i386-jit.cc                  | 195 +++++++++++++++++++
 gcc/config/i386/i386-jit.h                   |  22 +++
 gcc/config/i386/t-i386                       |   4 +
 gcc/config/linux-jit.cc                      |  36 ++++
 gcc/config/t-linux                           |   4 +
 gcc/configure                                |  14 ++
 gcc/configure.ac                             |  14 ++
 gcc/doc/tm.texi                              |  26 +++
 gcc/doc/tm.texi.in                           |  16 ++
 gcc/genhooks.cc                              |   1 +
 gcc/jit/Make-lang.in                         |   8 +-
 gcc/jit/docs/topics/compatibility.rst        |  14 ++
 gcc/jit/docs/topics/compilation.rst          |  51 +++++
 gcc/jit/jit-playback.cc                      |   2 +
 gcc/jit/jit-playback.h                       |  17 +-
 gcc/jit/jit-recording.cc                     |  19 ++
 gcc/jit/jit-recording.h                      |   3 +
 gcc/jit/jit-target-def.h                     |  20 ++
 gcc/jit/jit-target.cc                        |  89 +++++++++
 gcc/jit/jit-target.def                       |  52 +++++
 gcc/jit/jit-target.h                         |  73 +++++++
 gcc/jit/libgccjit.cc                         |  43 ++++
 gcc/jit/libgccjit.h                          |  60 ++++++
 gcc/jit/libgccjit.map                        |   9 +
 gcc/testsuite/jit.dg/all-non-failing-tests.h |   3 +
 gcc/testsuite/jit.dg/test-target-info.c      |  63 ++++++
 29 files changed, 938 insertions(+), 6 deletions(-)
 create mode 100644 gcc/config/default-jit.cc
 create mode 100644 gcc/config/i386/i386-jit.cc
 create mode 100644 gcc/config/i386/i386-jit.h
 create mode 100644 gcc/config/linux-jit.cc
 create mode 100644 gcc/jit/jit-target-def.h
 create mode 100644 gcc/jit/jit-target.cc
 create mode 100644 gcc/jit/jit-target.def
 create mode 100644 gcc/jit/jit-target.h
 create mode 100644 gcc/testsuite/jit.dg/test-target-info.c

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 7f2df4b5925..47cc4b29c28 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -609,6 +609,8 @@ tm_d_file_list=@tm_d_file_list@
 tm_d_include_list=@tm_d_include_list@
 tm_rust_file_list=@tm_rust_file_list@
 tm_rust_include_list=@tm_rust_include_list@
+tm_jit_file_list=@tm_jit_file_list@
+tm_jit_include_list=@tm_jit_include_list@
 build_xm_file_list=@build_xm_file_list@
 build_xm_include_list=@build_xm_include_list@
 build_xm_defines=@build_xm_defines@
@@ -908,6 +910,7 @@ TCONFIG_H = tconfig.h $(xm_file_list)
 TM_P_H    = tm_p.h    $(tm_p_file_list) $(TREE_H)
 TM_D_H    = tm_d.h    $(tm_d_file_list)
 TM_RUST_H = tm_rust.h $(tm_rust_file_list)
+TM_JIT_H  = tm_jit.h    $(tm_jit_file_list)
 GTM_H     = tm.h      $(tm_file_list) insn-constants.h
 TM_H      = $(GTM_H) insn-flags.h $(OPTIONS_H)
 
@@ -967,11 +970,13 @@ C_TARGET_DEF = c-family/c-target.def target-hooks-macros.h
 COMMON_TARGET_DEF = common/common-target.def target-hooks-macros.h
 D_TARGET_DEF = d/d-target.def target-hooks-macros.h
 RUST_TARGET_DEF = rust/rust-target.def target-hooks-macros.h
+JIT_TARGET_DEF = jit/jit-target.def target-hooks-macros.h
 TARGET_H = $(TM_H) target.h $(TARGET_DEF) insn-modes.h insn-codes.h
 C_TARGET_H = c-family/c-target.h $(C_TARGET_DEF)
 COMMON_TARGET_H = common/common-target.h $(INPUT_H) $(COMMON_TARGET_DEF)
 D_TARGET_H = d/d-target.h $(D_TARGET_DEF)
 RUST_TARGET_H = rust/rust-target.h $(RUST_TARGET_DEF)
+JIT_TARGET_H = jit/jit-target.h $(JIT_TARGET_DEF)
 MACHMODE_H = machmode.h mode-classes.def
 HOOKS_H = hooks.h
 HOSTHOOKS_DEF_H = hosthooks-def.h $(HOOKS_H)
@@ -1281,6 +1286,9 @@ CXX_TARGET_OBJS=@cxx_target_objs@
 # Target specific, D specific object file
 D_TARGET_OBJS=@d_target_objs@
 
+# Target specific, JIT specific object file
+JIT_TARGET_OBJS=@jit_target_objs@
+
 # Target specific, Fortran specific object file
 FORTRAN_TARGET_OBJS=@fortran_target_objs@
 
@@ -2025,6 +2033,7 @@ tm.h: cs-tm.h ; @true
 tm_p.h: cs-tm_p.h ; @true
 tm_d.h: cs-tm_d.h ; @true
 tm_rust.h: cs-tm_rust.h ; @true
+tm_jit.h: cs-tm_jit.h ; @true
 
 cs-config.h: Makefile
 	TARGET_CPU_DEFAULT="" \
@@ -2064,6 +2073,11 @@ cs-tm_rust.h: Makefile
 	HEADERS="$(tm_rust_include_list)" DEFINES="" \
 	$(SHELL) $(srcdir)/mkconfig.sh tm_rust.h
 
+cs-tm_jit.h: Makefile
+	TARGET_CPU_DEFAULT="" \
+	HEADERS="$(tm_jit_include_list)" DEFINES="" \
+	$(SHELL) $(srcdir)/mkconfig.sh tm_jit.h
+
 # Don't automatically run autoconf, since configure.ac might be accidentally
 # newer than configure.  Also, this writes into the source directory which
 # might be on a read-only file system.  If configured for maintainer mode
@@ -2406,6 +2420,13 @@ default-rust.o: config/default-rust.cc
 	$(COMPILE) $<
 	$(POSTCOMPILE)
 
+# Files used by the JIT language front end.
+
+default-jit.o: config/default-jit.cc
+	$(COMPILE) $<
+	$(POSTCOMPILE)
+
+
 # Language-independent files.
 
 DRIVER_DEFINES = \
@@ -2733,6 +2754,15 @@ s-rust-target-hooks-def-h: build/genhooks$(build_exeext)
 					     rust/rust-target-hooks-def.h
 	$(STAMP) s-rust-target-hooks-def-h
 
+jit/jit-target-hooks-def.h: s-jit-target-hooks-def-h; @true
+
+s-jit-target-hooks-def-h: build/genhooks$(build_exeext)
+	$(RUN_GEN) build/genhooks$(build_exeext) "JIT Target Hook" \
+					     > tmp-jit-target-hooks-def.h
+	$(SHELL) $(srcdir)/../move-if-change tmp-jit-target-hooks-def.h \
+					     jit/jit-target-hooks-def.h
+	$(STAMP) s-jit-target-hooks-def-h
+
 # check if someone mistakenly only changed tm.texi.
 # We use a different pathname here to avoid a circular dependency.
 s-tm-texi: $(srcdir)/doc/../doc/tm.texi
@@ -2758,6 +2788,7 @@ s-tm-texi: build/genhooks$(build_exeext) $(srcdir)/doc/tm.texi.in
 	    || test $(srcdir)/doc/tm.texi -nt $(srcdir)/common/common-target.def \
 	    || test $(srcdir)/doc/tm.texi -nt $(srcdir)/d/d-target.def \
 	    || test $(srcdir)/doc/tm.texi -nt $(srcdir)/rust/rust-target.def \
+	    || test $(srcdir)/doc/tm.texi -nt $(srcdir)/jit/jit-target.def \
 	  ); then \
 	  echo >&2 ; \
 	  echo You should edit $(srcdir)/doc/tm.texi.in rather than $(srcdir)/doc/tm.texi . >&2 ; \
@@ -2935,6 +2966,7 @@ generated_files = config.h tm.h $(TM_P_H) $(TM_D_H) $(TM_H) multilib.h \
        gimple-match-auto.h generic-match-auto.h \
        c-family/c-target-hooks-def.h d/d-target-hooks-def.h \
        $(TM_RUST_H) rust/rust-target-hooks-def.h \
+       $(TM_JIT_H) jit/jit-target-hooks-def.h \
        case-cfn-macros.h \
        cfn-operators.pd omp-device-properties.h
 
@@ -3069,8 +3101,8 @@ build/genrecog.o : genrecog.cc $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H)	\
   $(CORETYPES_H) $(GTM_H) errors.h $(READ_MD_H) $(GENSUPPORT_H)		\
   $(HASH_TABLE_H) inchash.h
 build/genhooks.o : genhooks.cc $(TARGET_DEF) $(C_TARGET_DEF)		\
-  $(COMMON_TARGET_DEF) $(D_TARGET_DEF) $(RUST_TARGET_DEF) $(BCONFIG_H) \
-  $(SYSTEM_H) errors.h
+  $(COMMON_TARGET_DEF) $(D_TARGET_DEF) $(RUST_TARGET_DEF) $(JIT_TARGET_DEF) \
+  $(BCONFIG_H) $(SYSTEM_H) errors.h
 build/genmddump.o : genmddump.cc $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H)	\
   $(CORETYPES_H) $(GTM_H) errors.h $(READ_MD_H) $(GENSUPPORT_H)
 build/genmatch.o : genmatch.cc $(BCONFIG_H) $(SYSTEM_H) $(CORETYPES_H) \
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 6d51bd93f3f..24b1c3bd552 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -149,6 +149,9 @@
 #  d_target_objs	List of extra target-dependent objects that be
 #			linked into the D compiler only.
 #
+#  jit_target_objs	List of extra target-dependent objects that be
+#			linked into the jit compiler only.
+#
 #  fortran_target_objs	List of extra target-dependent objects that be
 #			linked into the fortran compiler only.
 #
@@ -210,6 +213,8 @@
 #
 #  target_has_targetrustm	Set to yes or no depending on whether the target
 #			has its own definition of targetrustm.
+#  target_has_targetjitm	Set to yes or no depending on whether the target
+#			has its own definition of targetdm.
 
 out_file=
 common_out_file=
@@ -226,12 +231,14 @@ extra_options=
 c_target_objs=
 cxx_target_objs=
 d_target_objs=
+jit_target_objs=
 fortran_target_objs=
 rust_target_objs=
 target_has_targetcm=no
 target_has_targetm_common=yes
 target_has_targetdm=no
 target_has_targetrustm=no
+target_has_targetjitm=no
 tm_defines=
 xm_defines=
 # Set this to force installation and use of collect2.
@@ -412,6 +419,7 @@ i[34567]86-*-* | x86_64-*-*)
 	c_target_objs="i386-c.o"
 	cxx_target_objs="i386-c.o"
 	d_target_objs="i386-d.o"
+	jit_target_objs="i386-jit.o"
 	extra_objs="x86-tune-sched.o x86-tune-sched-bd.o x86-tune-sched-atom.o x86-tune-sched-core.o i386-options.o i386-builtins.o i386-expand.o i386-features.o"
 	target_gtfiles="\$(srcdir)/config/i386/i386-builtins.cc \$(srcdir)/config/i386/i386-expand.cc \$(srcdir)/config/i386/i386-options.cc"
 	extra_options="${extra_options} fused-madd.opt"
@@ -615,6 +623,12 @@ then
 	rust_target_objs="${rust_target_objs} ${cpu_type}-rust.o"
 fi
 
+tm_jit_file=
+if test -f ${srcdir}/config/${cpu_type}/${cpu_type}-jit.h
+then
+	tm_jit_file="${tm_jit_file} ${cpu_type}/${cpu_type}-jit.h"
+fi
+
 extra_modes=
 if test -f ${srcdir}/config/${cpu_type}/${cpu_type}-modes.def
 then
@@ -947,9 +961,11 @@ case ${target} in
   case $target in
     *-*-*linux*)
       d_target_objs="${d_target_objs} linux-d.o"
+      jit_target_objs="${jit_target_objs} linux-jit.o"
       target_has_targetdm=yes
       rust_target_objs="${rust_target_objs} linux-rust.o"
       target_has_targetrustm=yes
+      target_has_targetjitm=yes
       ;;
     *-*-kfreebsd*-gnu)
       d_target_objs="${d_target_objs} kfreebsd-d.o"
@@ -3668,6 +3684,10 @@ if [ "$target_has_targetrustm" = "no" ]; then
   rust_target_objs="$rust_target_objs default-rust.o"
 fi
 
+if [ "$target_has_targetjitm" = "no" ]; then
+  jit_target_objs="$jit_target_objs default-jit.o"
+fi
+
 # Support for --with-cpu and related options (and a few unrelated options,
 # too).
 case ${with_cpu} in
@@ -5923,6 +5943,7 @@ case ${target} in
 		c_target_objs="${c_target_objs} ${cpu_type}-c.o"
 		cxx_target_objs="${cxx_target_objs} ${cpu_type}-c.o"
 		d_target_objs="${d_target_objs} ${cpu_type}-d.o"
+		jit_target_objs="${jit_target_objs} ${cpu_type}-jit.o"
 		tmake_file="${cpu_type}/t-${cpu_type} ${tmake_file}"
 		;;
 
diff --git a/gcc/config/default-jit.cc b/gcc/config/default-jit.cc
new file mode 100644
index 00000000000..d286d6c4caa
--- /dev/null
+++ b/gcc/config/default-jit.cc
@@ -0,0 +1,29 @@
+/* Default JIT language target hooks initializer.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm_jit.h"
+#include "jit/jit-target.h"
+#include "jit/jit-target-def.h"
+
+/* Do not include tm.h or tm_p.h here; definitions needed by the target
+   architecture to initialize targetjitm should instead be added to
+   tm_jit.h.  */
+
+struct gcc_targetjitm targetjitm = TARGETJITM_INITIALIZER;
diff --git a/gcc/config/i386/i386-jit.cc b/gcc/config/i386/i386-jit.cc
new file mode 100644
index 00000000000..38b3f66e686
--- /dev/null
+++ b/gcc/config/i386/i386-jit.cc
@@ -0,0 +1,195 @@
+/* Subroutines for the JIT front end on the x86 architecture.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#define IN_TARGET_CODE 1
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "target.h"
+#include "tm.h"
+#include "tm_jit.h"
+#include "jit/jit-target.h"
+#include "jit/jit-target-def.h"
+
+/* Implement TARGET_JIT_REGISTER_CPU_TARGET_INFO.  */
+
+extern const char *host_detect_local_cpu (int argc, const char **argv);
+
+#if TARGET_64BIT_DEFAULT
+const char* x86_bits = "64";
+#else
+const char* x86_bits = "32";
+#endif
+
+void
+ix86_jit_register_target_info (void)
+{
+  const char *params[] = {"arch", x86_bits};
+  const char* local_cpu = host_detect_local_cpu (2, params);
+  std::string arch = local_cpu;
+  free (const_cast <char *> (local_cpu));
+
+  const char* arg = "-march=";
+  size_t arg_pos = arch.find (arg) + strlen (arg);
+  size_t end_pos = arch.find (" ", arg_pos);
+
+  std::string cpu = arch.substr (arg_pos, end_pos - arg_pos);
+  jit_target_set_arch (cpu);
+
+  jit_target_set_128bit_int_support (targetm.scalar_mode_supported_p (TImode));
+
+  if (TARGET_MMX)
+    jit_add_target_info ("target_feature", "mmx");
+  if (TARGET_SSE)
+    jit_add_target_info ("target_feature", "sse");
+  if (TARGET_SSE2)
+    jit_add_target_info ("target_feature", "sse2");
+  if (TARGET_SSE3)
+    jit_add_target_info ("target_feature", "sse3");
+  if (TARGET_SSSE3)
+    jit_add_target_info ("target_feature", "ssse3");
+  if (TARGET_SSE4_1)
+    jit_add_target_info ("target_feature", "sse4.1");
+  if (TARGET_SSE4_2)
+    jit_add_target_info ("target_feature", "sse4.2");
+  if (TARGET_AES)
+    jit_add_target_info ("target_feature", "aes");
+  if (TARGET_SHA)
+    jit_add_target_info ("target_feature", "sha");
+  if (TARGET_AVX)
+    jit_add_target_info ("target_feature", "avx");
+  if (TARGET_AVX2)
+    jit_add_target_info ("target_feature", "avx2");
+  if (TARGET_AVX512F)
+    jit_add_target_info ("target_feature", "avx512f");
+  if (TARGET_AVX512ER)
+    jit_add_target_info ("target_feature", "avx512er");
+  if (TARGET_AVX512CD)
+    jit_add_target_info ("target_feature", "avx512cd");
+  if (TARGET_AVX512PF)
+    jit_add_target_info ("target_feature", "avx512pf");
+  if (TARGET_AVX512DQ)
+    jit_add_target_info ("target_feature", "avx512dq");
+  if (TARGET_AVX512BW)
+    jit_add_target_info ("target_feature", "avx512bw");
+  if (TARGET_AVX512VL)
+    jit_add_target_info ("target_feature", "avx512vl");
+  if (TARGET_AVX512VBMI)
+    jit_add_target_info ("target_feature", "avx512vbmi");
+  if (TARGET_AVX512IFMA)
+    jit_add_target_info ("target_feature", "avx512ifma");
+  if (TARGET_AVX512VPOPCNTDQ)
+    jit_add_target_info ("target_feature", "avx512vpopcntdq");
+  if (TARGET_FMA)
+    jit_add_target_info ("target_feature", "fma");
+  if (TARGET_RTM)
+    jit_add_target_info ("target_feature", "rtm");
+  if (TARGET_SSE4A)
+    jit_add_target_info ("target_feature", "sse4a");
+  if (TARGET_BMI)
+  {
+    jit_add_target_info ("target_feature", "bmi1");
+    jit_add_target_info ("target_feature", "bmi");
+  }
+  if (TARGET_BMI2)
+    jit_add_target_info ("target_feature", "bmi2");
+  if (TARGET_LZCNT)
+    jit_add_target_info ("target_feature", "lzcnt");
+  if (TARGET_TBM)
+    jit_add_target_info ("target_feature", "tbm");
+  if (TARGET_POPCNT)
+    jit_add_target_info ("target_feature", "popcnt");
+  if (TARGET_RDRND)
+  {
+    jit_add_target_info ("target_feature", "rdrand");
+    jit_add_target_info ("target_feature", "rdrnd");
+  }
+  if (TARGET_F16C)
+    jit_add_target_info ("target_feature", "f16c");
+  if (TARGET_RDSEED)
+    jit_add_target_info ("target_feature", "rdseed");
+  if (TARGET_ADX)
+    jit_add_target_info ("target_feature", "adx");
+  if (TARGET_FXSR)
+    jit_add_target_info ("target_feature", "fxsr");
+  if (TARGET_XSAVE)
+    jit_add_target_info ("target_feature", "xsave");
+  if (TARGET_XSAVEOPT)
+    jit_add_target_info ("target_feature", "xsaveopt");
+  if (TARGET_XSAVEC)
+    jit_add_target_info ("target_feature", "xsavec");
+  if (TARGET_XSAVES)
+    jit_add_target_info ("target_feature", "xsaves");
+  if (TARGET_VPCLMULQDQ)
+  {
+    jit_add_target_info ("target_feature", "pclmulqdq");
+    jit_add_target_info ("target_feature", "vpclmulqdq");
+  }
+  if (TARGET_CMPXCHG16B)
+    jit_add_target_info ("target_feature", "cmpxchg16b");
+  if (TARGET_MOVBE)
+    jit_add_target_info ("target_feature", "movbe");
+  if (TARGET_AVX512VBMI2)
+    jit_add_target_info ("target_feature", "avx512vbmi2");
+  if (TARGET_PKU)
+    jit_add_target_info ("target_feature", "pku");
+  if (TARGET_AVX512VNNI)
+    jit_add_target_info ("target_feature", "avx512vnni");
+  if (TARGET_AVX512BF16)
+    jit_add_target_info ("target_feature", "avx512bf16");
+  if (TARGET_AVX512BITALG)
+    jit_add_target_info ("target_feature", "avx512bitalg");
+  if (TARGET_AVX512VP2INTERSECT)
+    jit_add_target_info ("target_feature", "avx512vp2intersect");
+  if (TARGET_PCLMUL)
+    jit_add_target_info ("target_feature", "pclmul");
+  if (TARGET_GFNI)
+    jit_add_target_info ("target_feature", "gfni");
+  if (TARGET_FMA4)
+    jit_add_target_info ("target_feature", "fma4");
+  if (TARGET_XOP)
+    jit_add_target_info ("target_feature", "xop");
+
+  if (TARGET_VAES)
+    jit_add_target_info ("target_feature", "vaes");
+  if (TARGET_LWP)
+    jit_add_target_info ("target_feature", "lwp");
+  if (TARGET_FSGSBASE)
+    jit_add_target_info ("target_feature", "fsgsbase");
+  if (TARGET_SHSTK)
+    jit_add_target_info ("target_feature", "shstk");
+  if (TARGET_PRFCHW)
+    jit_add_target_info ("target_feature", "prfchw");
+  if (TARGET_MWAITX)
+    jit_add_target_info ("target_feature", "mwaitx");
+  if (TARGET_CLZERO)
+    jit_add_target_info ("target_feature", "clzero");
+  if (TARGET_CLDEMOTE)
+    jit_add_target_info ("target_feature", "cldemote");
+  if (TARGET_PTWRITE)
+    jit_add_target_info ("target_feature", "ptwrite");
+  bool hasERMSB = ix86_arch == PROCESSOR_HASWELL
+    || ix86_arch == PROCESSOR_SKYLAKE || ix86_arch == PROCESSOR_SKYLAKE_AVX512
+    || ix86_arch == PROCESSOR_CANNONLAKE
+    || ix86_arch == PROCESSOR_ICELAKE_CLIENT
+    || ix86_arch == PROCESSOR_ICELAKE_SERVER
+    || ix86_arch == PROCESSOR_CASCADELAKE || ix86_arch == PROCESSOR_TIGERLAKE
+    || ix86_arch == PROCESSOR_COOPERLAKE;
+  if (hasERMSB)
+    jit_add_target_info ("target_feature", "ermsbd");
+}
diff --git a/gcc/config/i386/i386-jit.h b/gcc/config/i386/i386-jit.h
new file mode 100644
index 00000000000..4f05e88003f
--- /dev/null
+++ b/gcc/config/i386/i386-jit.h
@@ -0,0 +1,22 @@
+/* Definitions for the jit front end on the x86 architecture.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+/* In i386-jit.cc  */
+extern void ix86_jit_register_target_info (void);
+
+/* Target hooks for jit language.  */
+#define TARGET_JIT_REGISTER_CPU_TARGET_INFO ix86_jit_register_target_info
diff --git a/gcc/config/i386/t-i386 b/gcc/config/i386/t-i386
index f85817d698c..5a24ecea055 100644
--- a/gcc/config/i386/t-i386
+++ b/gcc/config/i386/t-i386
@@ -50,6 +50,10 @@ i386-rust.o: $(srcdir)/config/i386/i386-rust.cc
 	$(COMPILE) $<
 	$(POSTCOMPILE)
 
+i386-jit.o: $(srcdir)/config/i386/i386-jit.cc
+	$(COMPILE) $<
+	$(POSTCOMPILE)
+
 i386-options.o: $(srcdir)/config/i386/i386-options.cc
 	$(COMPILE) $<
 	$(POSTCOMPILE)
diff --git a/gcc/config/linux-jit.cc b/gcc/config/linux-jit.cc
new file mode 100644
index 00000000000..e85a6f3be18
--- /dev/null
+++ b/gcc/config/linux-jit.cc
@@ -0,0 +1,36 @@
+/* Linux support needed only by jit front-end.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_jit.h"
+#include "jit/jit-target.h"
+#include "jit/jit-target-def.h"
+
+/* Implement TARGET_JIT_REGISTER_OS_TARGET_INFO for Linux targets.  */
+
+static void
+linux_jit_register_target_info (void)
+{
+}
+
+#undef TARGET_JIT_REGISTER_OS_TARGET_INFO
+#define TARGET_JIT_REGISTER_OS_TARGET_INFO linux_jit_register_target_info
+
+struct gcc_targetjitm targetjitm = TARGETJITM_INITIALIZER;
diff --git a/gcc/config/t-linux b/gcc/config/t-linux
index 96593fbf27f..14376825d79 100644
--- a/gcc/config/t-linux
+++ b/gcc/config/t-linux
@@ -27,3 +27,7 @@ linux-d.o: $(srcdir)/config/linux-d.cc
 linux-rust.o: $(srcdir)/config/linux-rust.cc
 	  $(COMPILE) $<
 	  $(POSTCOMPILE)
+
+linux-jit.o: $(srcdir)/config/linux-jit.cc
+	  $(COMPILE) $<
+	  $(POSTCOMPILE)
diff --git a/gcc/configure b/gcc/configure
index ee97934ac4f..318de004075 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -648,6 +648,7 @@ GMPLIBS
 target_cpu_default
 rust_target_objs
 d_target_objs
+jit_target_objs
 fortran_target_objs
 cxx_target_objs
 c_target_objs
@@ -659,6 +660,8 @@ tm_rust_include_list
 tm_rust_file_list
 tm_d_include_list
 tm_d_file_list
+tm_jit_include_list
+tm_jit_file_list
 tm_p_include_list
 tm_p_file_list
 tm_defines
@@ -15231,6 +15234,17 @@ for f in $tm_rust_file; do
   esac
 done
 
+tm_jit_file_list=
+tm_jit_include_list=
+for f in $tm_jit_file; do
+  case $f in
+    * )
+       tm_jit_file_list="${tm_jit_file_list} \$(srcdir)/config/$f"
+       tm_jit_include_list="${tm_jit_include_list} config/$f"
+       ;;
+  esac
+done
+
 xm_file_list=
 xm_include_list=
 for f in $xm_file; do
diff --git a/gcc/configure.ac b/gcc/configure.ac
index d0caf820648..618e0345e55 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -2451,6 +2451,17 @@ for f in $tm_rust_file; do
   esac
 done
 
+tm_jit_file_list=
+tm_jit_include_list=
+for f in $tm_jit_file; do
+  case $f in
+    * )
+       tm_jit_file_list="${tm_jit_file_list} \$(srcdir)/config/$f"
+       tm_jit_include_list="${tm_jit_include_list} config/$f"
+       ;;
+  esac
+done
+
 xm_file_list=
 xm_include_list=
 for f in $xm_file; do
@@ -7498,6 +7509,8 @@ AC_SUBST(tm_d_file_list)
 AC_SUBST(tm_d_include_list)
 AC_SUBST(tm_rust_file_list)
 AC_SUBST(tm_rust_include_list)
+AC_SUBST(tm_jit_file_list)
+AC_SUBST(tm_jit_include_list)
 AC_SUBST(xm_file_list)
 AC_SUBST(xm_include_list)
 AC_SUBST(xm_defines)
@@ -7507,6 +7520,7 @@ AC_SUBST(cxx_target_objs)
 AC_SUBST(fortran_target_objs)
 AC_SUBST(d_target_objs)
 AC_SUBST(rust_target_objs)
+AC_SUBST(jit_target_objs)
 AC_SUBST(target_cpu_default)
 
 AC_SUBST_FILE(language_hooks)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index d83ca73b1af..e878d0b003d 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -124,6 +124,14 @@ If targets initialize @code{targetrustm} themselves, they should set
 @code{target_has_targetrustm=yes} in @file{config.gcc}; otherwise a
 default definition is used.
 
+Similarly, there is a @code{targetjitm} variable for hooks that are
+specific to the jit front end, documented as ``JIT Target Hook''.
+This is declared in @file{jit/jit-target.h}, the initializer
+@code{TARGETJITM_INITIALIZER} in @file{jit/jit-target-def.h}.  If targets
+initialize @code{targetjitm} themselves, they should set
+@code{target_has_targetjitm=yes} in @file{config.gcc}; otherwise a default
+definition is used.
+
 @node Driver
 @section Controlling the Compilation Driver, @file{gcc}
 @cindex driver
@@ -11074,6 +11082,24 @@ Similar to @code{TARGET_RUST_CPU_INFO}, but is used for configuration info
 relating to the target operating system.
 @end deftypefn
 
+@node JIT Language and ABI
+@section JIT ABI parameters
+@cindex parameters, jit abi
+
+@deftypefn {JIT Target Hook} void TARGET_JIT_REGISTER_CPU_TARGET_INFO (void)
+Register all target information keys relating to the target CPU using the
+function @code{jit_add_target_info_handlers}, which takes a
+@samp{struct jit_target_info_spec} (defined in @file{jit/jit-target.h}).  The
+keys added by this hook are made available at compile time by the
+@code{__traits(getTargetInfo)} extension, the result is an expression
+describing the requested target information.
+@end deftypefn
+
+@deftypefn {JIT Target Hook} void TARGET_JIT_REGISTER_OS_TARGET_INFO (void)
+Same as @code{TARGET_JIT_CPU_TARGET_INFO}, but is used for keys relating to
+the target operating system.
+@end deftypefn
+
 @node Named Address Spaces
 @section Adding support for named address spaces
 @cindex named address spaces
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 3d3ae12cc2f..7aae8e2b404 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -124,6 +124,14 @@ If targets initialize @code{targetrustm} themselves, they should set
 @code{target_has_targetrustm=yes} in @file{config.gcc}; otherwise a
 default definition is used.
 
+Similarly, there is a @code{targetjitm} variable for hooks that are
+specific to the jit front end, documented as ``JIT Target Hook''.
+This is declared in @file{jit/jit-target.h}, the initializer
+@code{TARGETJITM_INITIALIZER} in @file{jit/jit-target-def.h}.  If targets
+initialize @code{targetjitm} themselves, they should set
+@code{target_has_targetjitm=yes} in @file{config.gcc}; otherwise a default
+definition is used.
+
 @node Driver
 @section Controlling the Compilation Driver, @file{gcc}
 @cindex driver
@@ -7188,6 +7196,14 @@ floating-point support; they are not included in this mechanism.
 
 @hook TARGET_RUST_OS_INFO
 
+@node JIT Language and ABI
+@section JIT ABI parameters
+@cindex parameters, jit abi
+
+@hook TARGET_JIT_REGISTER_CPU_TARGET_INFO
+
+@hook TARGET_JIT_REGISTER_OS_TARGET_INFO
+
 @node Named Address Spaces
 @section Adding support for named address spaces
 @cindex named address spaces
diff --git a/gcc/genhooks.cc b/gcc/genhooks.cc
index 49414eca531..7064d9659dd 100644
--- a/gcc/genhooks.cc
+++ b/gcc/genhooks.cc
@@ -36,6 +36,7 @@ static struct hook_desc hook_array[] = {
 #include "common/common-target.def"
 #include "d/d-target.def"
 #include "rust/rust-target.def"
+#include "jit/jit-target.def"
 #undef DEFHOOK
 };
 
diff --git a/gcc/jit/Make-lang.in b/gcc/jit/Make-lang.in
index 3fd564a5932..19ef589e55c 100644
--- a/gcc/jit/Make-lang.in
+++ b/gcc/jit/Make-lang.in
@@ -120,7 +120,7 @@ jit.serial = $(LIBGCCJIT_FILENAME)
 # Tell GNU make to ignore these if they exist.
 .PHONY: jit
 
-jit_OBJS = attribs.o \
+JIT_OBJS = attribs.o \
 	jit/dummy-frontend.o \
 	jit/libgccjit.o \
 	jit/jit-logging.o \
@@ -129,13 +129,17 @@ jit_OBJS = attribs.o \
 	jit/jit-result.o \
 	jit/jit-tempdir.o \
 	jit/jit-builtins.o \
+	jit/jit-target.o \
 	jit/jit-spec.o \
 	gcc.o
 
 ifneq (,$(findstring mingw,$(target)))
-jit_OBJS += jit/jit-w32.o
+JIT_OBJS += jit/jit-w32.o
 endif
 
+# All language-specific object files for jit.
+jit_OBJS = $(JIT_OBJS) $(JIT_TARGET_OBJS)
+
 # Use strict warnings for this front end.
 jit-warn = $(STRICT_WARN)
 
diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst
index ebede440ee4..fe73caa3982 100644
--- a/gcc/jit/docs/topics/compatibility.rst
+++ b/gcc/jit/docs/topics/compatibility.rst
@@ -378,3 +378,17 @@ alignment of a variable:
 --------------------
 ``LIBGCCJIT_ABI_25`` covers the addition of
 :func:`gcc_jit_type_get_restrict`
+
+.. _LIBGCCJIT_ABI_26:
+
+``LIBGCCJIT_ABI_26``
+--------------------
+``LIBGCCJIT_ABI_26`` covers the addition of functions to query the target
+information:
+
+  * :func:`gcc_jit_type_get_restrict`
+  * :func:`gcc_jit_context_get_target_info`
+  * :func:`gcc_jit_target_info_release`
+  * :func:`gcc_jit_target_info_cpu_supports`
+  * :func:`gcc_jit_target_info_arch`
+  * :func:`gcc_jit_target_info_supports_128bit_int`
diff --git a/gcc/jit/docs/topics/compilation.rst b/gcc/jit/docs/topics/compilation.rst
index 0911f108ba4..6db1de82c7d 100644
--- a/gcc/jit/docs/topics/compilation.rst
+++ b/gcc/jit/docs/topics/compilation.rst
@@ -199,3 +199,54 @@ The available kinds of output are:
 .. c:macro:: GCC_JIT_OUTPUT_KIND_EXECUTABLE
 
    Compile the context to an executable.
+
+
+Getting information about a target
+**********************************
+
+You can query the target information by using the following API:
+
+.. function:: gcc_jit_target_info * \
+              gcc_jit_context_get_target_info (gcc_jit_context *ctxt)
+
+   Compute the information about a target.
+
+   If the result is non-NULL, the caller becomes responsible for
+   calling :func:`gcc_jit_target_info_release` on it once they're done
+   with it.
+
+.. function:: void \
+              gcc_jit_target_info_release (gcc_jit_target_info *info)
+
+   This function releases all resources associated with the given target info.
+
+.. function:: int \
+              gcc_jit_target_info_cpu_supports (gcc_jit_target_info *info,
+                                                const char *feature)
+
+   Check if the specified target INFO supports the cpu FEATURE.
+
+.. function:: const char * \
+              gcc_jit_target_info_arch (gcc_jit_target_info *info)
+
+   Get the architecture of the currently running CPU.
+
+.. function:: int \
+              gcc_jit_target_info_supports_128bit_int (gcc_jit_target_info *info)
+
+   Check if the specified target INFO supports 128-bit integers.
+
+   The API entrypoints relating to the target info:
+
+      * :c:func:`gcc_jit_context_get_target_info`
+      * :c:func:`gcc_jit_target_info_release`
+      * :c:func:`gcc_jit_target_info_cpu_supports`
+      * :c:func:`gcc_jit_target_info_arch`
+      * :c:func:`gcc_jit_target_info_supports_128bit_int`
+
+   were added in :ref:`LIBGCCJIT_ABI_26`; you can test for their presence
+   using
+
+   .. code-block:: c
+
+      #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc
index 18cc4da25b8..bf53c039e85 100644
--- a/gcc/jit/jit-playback.cc
+++ b/gcc/jit/jit-playback.cc
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "jit-result.h"
 #include "jit-builtins.h"
 #include "jit-tempdir.h"
+#include "jit-target.h"
 
 #ifdef _WIN32
 #include "jit-w32.h"
@@ -3226,6 +3227,7 @@ replay ()
   JIT_LOG_SCOPE (get_logger ());
 
   init_types ();
+  jit_target_init ();
 
   /* Replay the recorded events:  */
   timevar_push (TV_JIT_REPLAY);
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index f9e29d0baec..afa6d281188 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -43,9 +43,10 @@ namespace playback {
 
 /* playback::context is an abstract base class.
 
-   The two concrete subclasses are:
+   The three concrete subclasses are:
    - playback::compile_to_memory
-   - playback::compile_to_file.  */
+   - playback::compile_to_file
+   - playback::get_target_info.  */
 
 class context : public log_user
 {
@@ -405,6 +406,18 @@ class compile_to_file : public context
   const char *m_output_path;
 };
 
+class get_target_info : public context
+{
+ public:
+  get_target_info (recording::context *ctxt) : context (ctxt)
+  {
+  }
+
+  void postprocess (const char *) final override
+  {
+  }
+};
+
 
 /* A temporary wrapper object.
    These objects are (mostly) only valid during replay.
diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc
index 9b5b8005ebe..94978170c10 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -1525,6 +1525,25 @@ recording::context::compile_to_file (enum gcc_jit_output_kind output_kind,
   replayer.compile ();
 }
 
+void
+recording::context::get_target_info ()
+{
+  JIT_LOG_SCOPE (get_logger ());
+
+  log_all_options ();
+
+  if (errors_occurred ())
+    return;
+
+  add_driver_option ("-fsyntax-only");
+
+  /* Set up a get_target_info playback context.  */
+  ::gcc::jit::playback::get_target_info replayer (this);
+
+  /* Use it.  */
+  replayer.compile ();
+}
+
 /* Format the given error using printf's conventions, print
    it to stderr, and add it to the context.  */
 
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 4a8082991fb..a090c85b19e 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -283,6 +283,9 @@ public:
   compile_to_file (enum gcc_jit_output_kind output_kind,
 		   const char *output_path);
 
+  void
+  get_target_info ();
+
   void
   add_error (location *loc, const char *fmt, ...)
       GNU_PRINTF(3, 4);
diff --git a/gcc/jit/jit-target-def.h b/gcc/jit/jit-target-def.h
new file mode 100644
index 00000000000..dcb342fafe7
--- /dev/null
+++ b/gcc/jit/jit-target-def.h
@@ -0,0 +1,20 @@
+/* jit-target-def.h -- Default initializers for jit target hooks.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 3, or (at your option) any
+   later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "jit/jit-target-hooks-def.h"
+#include "tree.h"
+#include "hooks.h"
diff --git a/gcc/jit/jit-target.cc b/gcc/jit/jit-target.cc
new file mode 100644
index 00000000000..e8ac847d3df
--- /dev/null
+++ b/gcc/jit/jit-target.cc
@@ -0,0 +1,89 @@
+/* jit-target.cc -- Target interface for the jit front end.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+
+#include "tree.h"
+#include "memmodel.h"
+#include "fold-const.h"
+#include "diagnostic.h"
+#include "stor-layout.h"
+#include "tm.h"
+#include "tm_p.h"
+#include "target.h"
+#include "calls.h"
+
+#include "jit-target.h"
+
+#include <algorithm>
+
+static target_info jit_target_info;
+
+/* Initialize all variables of the Target structure.  */
+
+void
+jit_target_init ()
+{
+  /* Initialize target info tables, the keys required by the language are added
+     last, so that the OS and CPU handlers can override.  */
+  targetjitm.jit_register_cpu_target_info ();
+  targetjitm.jit_register_os_target_info ();
+}
+
+/* Add all target info in HANDLERS to JIT_TARGET_INFO for use by
+   jit_has_target_value ().  */
+
+void
+jit_add_target_info (const char *key, const char *value)
+{
+  if (jit_target_info.m_info.find (key) == jit_target_info.m_info.end ())
+    jit_target_info.m_info.insert ({key, {value}});
+  else
+    jit_target_info.m_info[key].insert (value);
+}
+
+void
+jit_target_set_arch (std::string const& arch)
+{
+  jit_target_info.m_arch = arch;
+}
+
+void
+jit_target_set_128bit_int_support (bool support)
+{
+  jit_target_info.m_supports_128bit_int = support;
+}
+
+target_info *
+jit_get_target_info ()
+{
+  target_info *info = new target_info {jit_target_info};
+  jit_target_info = target_info{};
+  return info;
+}
+
+bool
+target_info::has_target_value (const char *key, const char *value)
+{
+  if (m_info.find (key) == m_info.end ())
+    return false;
+
+  auto& set = m_info[key];
+  return set.find (value) != set.end ();
+}
diff --git a/gcc/jit/jit-target.def b/gcc/jit/jit-target.def
new file mode 100644
index 00000000000..de0d717b365
--- /dev/null
+++ b/gcc/jit/jit-target.def
@@ -0,0 +1,52 @@
+/* jit-target.def -- Target hook definitions for the jit front end.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 3, or (at your option) any
+   later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* See target-hooks-macros.h for details of macros that should be
+   provided by the including file, and how to use them here.  */
+
+#include "target-hooks-macros.h"
+
+#undef HOOK_TYPE
+#define HOOK_TYPE "JIT Target Hook"
+
+HOOK_VECTOR (TARGETJITM_INITIALIZER, gcc_targetjitm)
+
+#undef HOOK_PREFIX
+#define HOOK_PREFIX "TARGET_"
+
+/* getTargetInfo keys relating to the target CPU.  */
+DEFHOOK
+(jit_register_cpu_target_info,
+ "Register all target information keys relating to the target CPU using the\n\
+function @code{jit_add_target_info_handlers}, which takes a\n\
+@samp{struct jit_target_info_spec} (defined in @file{jit/jit-target.h}).  The\n\
+keys added by this hook are made available at compile time by the\n\
+@code{__traits(getTargetInfo)} extension, the result is an expression\n\
+describing the requested target information.",
+ void, (void),
+ hook_void_void)
+
+/* getTargetInfo keys relating to the target OS.  */
+DEFHOOK
+(jit_register_os_target_info,
+ "Same as @code{TARGET_JIT_CPU_TARGET_INFO}, but is used for keys relating to\n\
+the target operating system.",
+ void, (void),
+ hook_void_void)
+
+/* Close the 'struct gcc_targetdm' definition.  */
+HOOK_VECTOR_END (C90_EMPTY_HACK)
diff --git a/gcc/jit/jit-target.h b/gcc/jit/jit-target.h
new file mode 100644
index 00000000000..6443cd71025
--- /dev/null
+++ b/gcc/jit/jit-target.h
@@ -0,0 +1,73 @@
+/* jit-target.h -- Data structure definitions for target-specific jit behavior.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 3, or (at your option) any
+   later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_JIT_TARGET_H
+#define GCC_JIT_TARGET_H
+
+#define DEFHOOKPOD(NAME, DOC, TYPE, INIT) TYPE NAME;
+#define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) TYPE (* NAME) PARAMS;
+#define DEFHOOK_UNDOC DEFHOOK
+#define HOOKSTRUCT(FRAGMENT) FRAGMENT
+
+#include "jit-target.def"
+
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+
+static size_t hash_cstr (const char *s)
+{
+  const size_t seed = 0;
+  return std::_Hash_bytes (s, std::strlen (s), seed);
+}
+
+struct CStringHash {
+  size_t operator() (const char* const &string) const {
+    auto res = hash_cstr (string);
+    return res;
+  }
+};
+
+struct CStringEqual {
+  bool operator() (const char* const &string1,
+		   const char* const &string2) const {
+      return strcmp (string1, string2) == 0;
+  }
+};
+
+struct target_info {
+  public:
+    bool has_target_value (const char *key, const char *value);
+
+    std::unordered_map<const char *,
+		       std::unordered_set<const char *, CStringHash,
+					  CStringEqual>,
+		       CStringHash, CStringEqual> m_info;
+    std::string m_arch;
+    bool m_supports_128bit_int = false;
+};
+
+/* Each target can provide their own.  */
+extern struct gcc_targetjitm targetjitm;
+
+extern void jit_target_init ();
+extern void jit_target_set_arch (std::string const& arch);
+extern void jit_target_set_128bit_int_support (bool support);
+extern void jit_add_target_info (const char *key, const char *value);
+extern target_info * jit_get_target_info ();
+
+#endif /* GCC_JIT_TARGET_H  */
diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
index 0451b4df7f9..15ba3acc95c 100644
--- a/gcc/jit/libgccjit.cc
+++ b/gcc/jit/libgccjit.cc
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "libgccjit.h"
 #include "jit-recording.h"
 #include "jit-result.h"
+#include "jit-target.h"
 
 /* The opaque types used by the public API are actually subclasses
    of the gcc::jit::recording classes.  */
@@ -44,6 +45,10 @@ struct gcc_jit_result : public gcc::jit::result
 {
 };
 
+struct gcc_jit_target_info : public target_info
+{
+};
+
 struct gcc_jit_object : public gcc::jit::recording::memento
 {
 };
@@ -3679,6 +3684,44 @@ gcc_jit_context_compile_to_file (gcc_jit_context *ctxt,
   ctxt->compile_to_file (output_kind, output_path);
 }
 
+gcc_jit_target_info *
+gcc_jit_context_get_target_info (gcc_jit_context *ctxt)
+{
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  JIT_LOG_FUNC (ctxt->get_logger ());
+
+  ctxt->log ("get_target_info of ctxt: %p", (void *)ctxt);
+
+  ctxt->get_target_info ();
+
+  return (gcc_jit_target_info*) jit_get_target_info ();
+}
+
+void
+gcc_jit_target_info_release (gcc_jit_target_info *info)
+{
+  RETURN_IF_FAIL (info, NULL, NULL, "NULL info");
+  delete info;
+}
+
+int
+gcc_jit_target_info_cpu_supports (gcc_jit_target_info *info,
+				  const char *feature)
+{
+  return info->has_target_value ("target_feature", feature);
+}
+
+const char *
+gcc_jit_target_info_arch (gcc_jit_target_info *info)
+{
+  return info->m_arch.c_str ();
+}
+
+int
+gcc_jit_target_info_supports_128bit_int (gcc_jit_target_info *info)
+{
+  return info->m_supports_128bit_int;
+}
 
 /* Public entrypoint.  See description in libgccjit.h.
 
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index 749f6c24177..a289862311b 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -52,6 +52,9 @@ typedef struct gcc_jit_context gcc_jit_context;
 /* A gcc_jit_result encapsulates the result of an in-memory compilation.  */
 typedef struct gcc_jit_result gcc_jit_result;
 
+/* A gcc_jit_target_info encapsulates the target info.  */
+typedef struct gcc_jit_target_info gcc_jit_target_info;
+
 /* An object created within a context.  Such objects are automatically
    cleaned up when the context is released.
 
@@ -1999,6 +2002,63 @@ gcc_jit_vector_type_get_element_type (gcc_jit_vector_type *vector_type);
 extern gcc_jit_type *
 gcc_jit_type_unqualified (gcc_jit_type *type);
 
+/* Create a gcc_jit_target_info instance.
+
+   This API entrypoint was added in LIBGCCJIT_ABI_26; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+
+extern gcc_jit_target_info *
+gcc_jit_context_get_target_info (gcc_jit_context *ctxt);
+
+/* Release a gcc_jit_target_info instance.
+
+   This API entrypoint was added in LIBGCCJIT_ABI_26; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+
+extern void
+gcc_jit_target_info_release (gcc_jit_target_info *info);
+
+/* Returns non-zero if FEATURE is supported by the specified target.
+
+   This API entrypoint was added in LIBGCCJIT_ABI_26; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+
+extern int
+gcc_jit_target_info_cpu_supports (gcc_jit_target_info *info,
+				  const char *feature);
+
+/* Returns the ARCH of the currently running CPU.
+
+   This API entrypoint was added in LIBGCCJIT_ABI_26; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+
+extern const char *
+gcc_jit_target_info_arch (gcc_jit_target_info *info);
+
+/* Returns non-zero if the target natively supports 128-bit integers.
+
+   This API entrypoint was added in LIBGCCJIT_ABI_26; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+
+extern int
+gcc_jit_target_info_supports_128bit_int (gcc_jit_target_info *info);
+
+/* The target info API was added in LIBGCCJIT_ABI_26; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+#define LIBGCCJIT_HAVE_TARGET_INFO_API
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index 8b90a0e2ff3..30f08ce67d7 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -276,3 +276,12 @@ LIBGCCJIT_ABI_25 {
   global:
     gcc_jit_type_get_restrict;
 } LIBGCCJIT_ABI_24;
+
+LIBGCCJIT_ABI_26 {
+  global:
+    gcc_jit_context_get_target_info;
+    gcc_jit_target_info_release;
+    gcc_jit_target_info_cpu_supports;
+    gcc_jit_target_info_arch;
+    gcc_jit_target_info_supports_128bit_int;
+} LIBGCCJIT_ABI_25;
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index e762563f9bd..f0f7356d687 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -322,6 +322,9 @@
 /* test-setting-alignment.c: This can't be in the testcases array as it
    is target-specific.  */
 
+/* test-target-info.c: This can't be in the testcases array as it
+   is target-specific.  */
+
 /* test-string-literal.c */
 #define create_code create_code_string_literal
 #define verify_code verify_code_string_literal
diff --git a/gcc/testsuite/jit.dg/test-target-info.c b/gcc/testsuite/jit.dg/test-target-info.c
new file mode 100644
index 00000000000..db5591edcbd
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-target-info.c
@@ -0,0 +1,63 @@
+/* { dg-do compile { target x86_64-*-* } } */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#define TEST_PROVIDES_MAIN
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+}
+
+int
+main (int argc, char **argv)
+{
+  /*  This is the same as the main provided by harness.h, but calls gcc_jit_context_get_target_info.  */
+  gcc_jit_context *ctxt;
+  ctxt = gcc_jit_context_acquire ();
+  if (!ctxt)
+    {
+      fail ("gcc_jit_context_acquire failed");
+      return -1;
+    }
+  gcc_jit_target_info* info = gcc_jit_context_get_target_info (ctxt);
+
+  int sse2_supported = gcc_jit_target_info_cpu_supports (info, "sse2");
+  CHECK_VALUE (sse2_supported, 1);
+
+  const char *arch = gcc_jit_target_info_arch (info);
+  // TODO: not sure what value to check here.
+  CHECK_STRING_VALUE (arch, "znver2");
+
+  int supports_128bit_int = gcc_jit_target_info_supports_128bit_int (info);
+  CHECK_VALUE (supports_128bit_int, 1);
+  gcc_jit_target_info_release (info);
+  gcc_jit_context_release (ctxt);
+
+  int i;
+
+  for (i = 1; i <= 5; i++)
+    {
+      snprintf (test, sizeof (test),
+		"%s iteration %d of %d",
+                extract_progname (argv[0]),
+                i, 5);
+
+      //printf ("ITERATION %d\n", i);
+      test_jit (argv[0], NULL);
+      //printf ("\n");
+    }
+
+  totals ();
+
+  return 0;
+}
-- 
2.43.0


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] libgccjit: Add ability to get CPU features
  2023-11-09 23:04 ` David Malcolm
                     ` (2 preceding siblings ...)
  2024-01-11 18:49   ` Antoni Boucher
@ 2024-01-19 12:53   ` Antoni Boucher
  2024-01-20 14:50   ` Antoni Boucher
  4 siblings, 0 replies; 21+ messages in thread
From: Antoni Boucher @ 2024-01-19 12:53 UTC (permalink / raw)
  To: David Malcolm, jit, gcc-patches

David: Ping.

On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
> On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
> > Hi.
> > This patch adds support for getting the CPU features in libgccjit
> > (bug
> > 112466)
> > 
> > There's a TODO in the test:
> > I'm not sure how to test that gcc_jit_target_info_arch returns the
> > correct value since it is dependant on the CPU.
> > Any idea on how to improve this?
> > 
> > Also, I created a CStringHash to be able to have a
> > std::unordered_set<const char *>. Is there any built-in way of
> > doing
> > this?
> 
> Thanks for the patch.
> 
> Some high-level questions:
> 
> Is this specifically about detecting capabilities of the host that
> libgccjit is currently running on? or how the target was configured
> when libgccjit was built?
> 
> One of the benefits of libgccjit is that, in theory, we support all
> of
> the targets that GCC already supports.  Does this patch change that,
> or
> is this more about giving client code the ability to determine
> capabilities of the specific host being compiled for?
> 
> I'm nervous about having per-target jit code.  Presumably there's a
> reason that we can't reuse existing target logic here - can you
> please
> describe what the problem is.  I see that the ChangeLog has:
> 
> > 	* config/i386/i386-jit.cc: New file.
> 
> where i386-jit.cc has almost 200 lines of nontrivial code.  Where did
> this come from?  Did you base it on existing code in our source tree,
> making modifications to fit the new internal API, or did you write it
> from scratch?  In either case, how onerous would this be for other
> targets?
> 
> I'm not at expert at target hooks (or at the i386 backend), so if we
> do
> go with this approach I'd want someone else to review those parts of
> the patch.
> 
> Have you verified that GCC builds with this patch with jit *not*
> enabled in the enabled languages?
> 
> [...snip...]
> 
> A nitpick:
> 
> > +.. function:: const char * \
> > +              gcc_jit_target_info_arch (gcc_jit_target_info *info)
> > +
> > +   Get the architecture of the currently running CPU.
> 
> What does this string look like?
> How long does the pointer remain valid?
> 
> Thanks again; hope the above makes sense
> Dave
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] libgccjit: Add ability to get CPU features
  2023-11-09 23:04 ` David Malcolm
                     ` (3 preceding siblings ...)
  2024-01-19 12:53   ` Antoni Boucher
@ 2024-01-20 14:50   ` Antoni Boucher
  2024-01-30 15:50     ` Antoni Boucher
  4 siblings, 1 reply; 21+ messages in thread
From: Antoni Boucher @ 2024-01-20 14:50 UTC (permalink / raw)
  To: David Malcolm, jit, gcc-patches; +Cc: Iain Buclaw

CC-ing Iain in case they can do the review since it is based on how
they did it in the D frontend.
Could you please do the review?
Thanks!

On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
> On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
> > Hi.
> > This patch adds support for getting the CPU features in libgccjit
> > (bug
> > 112466)
> > 
> > There's a TODO in the test:
> > I'm not sure how to test that gcc_jit_target_info_arch returns the
> > correct value since it is dependant on the CPU.
> > Any idea on how to improve this?
> > 
> > Also, I created a CStringHash to be able to have a
> > std::unordered_set<const char *>. Is there any built-in way of
> > doing
> > this?
> 
> Thanks for the patch.
> 
> Some high-level questions:
> 
> Is this specifically about detecting capabilities of the host that
> libgccjit is currently running on? or how the target was configured
> when libgccjit was built?
> 
> One of the benefits of libgccjit is that, in theory, we support all
> of
> the targets that GCC already supports.  Does this patch change that,
> or
> is this more about giving client code the ability to determine
> capabilities of the specific host being compiled for?
> 
> I'm nervous about having per-target jit code.  Presumably there's a
> reason that we can't reuse existing target logic here - can you
> please
> describe what the problem is.  I see that the ChangeLog has:
> 
> > 	* config/i386/i386-jit.cc: New file.
> 
> where i386-jit.cc has almost 200 lines of nontrivial code.  Where did
> this come from?  Did you base it on existing code in our source tree,
> making modifications to fit the new internal API, or did you write it
> from scratch?  In either case, how onerous would this be for other
> targets?
> 
> I'm not at expert at target hooks (or at the i386 backend), so if we
> do
> go with this approach I'd want someone else to review those parts of
> the patch.
> 
> Have you verified that GCC builds with this patch with jit *not*
> enabled in the enabled languages?
> 
> [...snip...]
> 
> A nitpick:
> 
> > +.. function:: const char * \
> > +              gcc_jit_target_info_arch (gcc_jit_target_info *info)
> > +
> > +   Get the architecture of the currently running CPU.
> 
> What does this string look like?
> How long does the pointer remain valid?
> 
> Thanks again; hope the above makes sense
> Dave
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] libgccjit: Add ability to get CPU features
  2024-01-20 14:50   ` Antoni Boucher
@ 2024-01-30 15:50     ` Antoni Boucher
  2024-02-06 12:54       ` Antoni Boucher
  0 siblings, 1 reply; 21+ messages in thread
From: Antoni Boucher @ 2024-01-30 15:50 UTC (permalink / raw)
  To: David Malcolm, jit, gcc-patches; +Cc: Iain Buclaw

David: I'm unsure what to do here. It seems we cannot find a reviewer.
Would it help if I show you the code in gccrs that is similar?
Would it help if I ask someone from gccrs to review this code?

On Sat, 2024-01-20 at 09:50 -0500, Antoni Boucher wrote:
> CC-ing Iain in case they can do the review since it is based on how
> they did it in the D frontend.
> Could you please do the review?
> Thanks!
> 
> On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
> > On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
> > > Hi.
> > > This patch adds support for getting the CPU features in libgccjit
> > > (bug
> > > 112466)
> > > 
> > > There's a TODO in the test:
> > > I'm not sure how to test that gcc_jit_target_info_arch returns
> > > the
> > > correct value since it is dependant on the CPU.
> > > Any idea on how to improve this?
> > > 
> > > Also, I created a CStringHash to be able to have a
> > > std::unordered_set<const char *>. Is there any built-in way of
> > > doing
> > > this?
> > 
> > Thanks for the patch.
> > 
> > Some high-level questions:
> > 
> > Is this specifically about detecting capabilities of the host that
> > libgccjit is currently running on? or how the target was configured
> > when libgccjit was built?
> > 
> > One of the benefits of libgccjit is that, in theory, we support all
> > of
> > the targets that GCC already supports.  Does this patch change
> > that,
> > or
> > is this more about giving client code the ability to determine
> > capabilities of the specific host being compiled for?
> > 
> > I'm nervous about having per-target jit code.  Presumably there's a
> > reason that we can't reuse existing target logic here - can you
> > please
> > describe what the problem is.  I see that the ChangeLog has:
> > 
> > > 	* config/i386/i386-jit.cc: New file.
> > 
> > where i386-jit.cc has almost 200 lines of nontrivial code.  Where
> > did
> > this come from?  Did you base it on existing code in our source
> > tree,
> > making modifications to fit the new internal API, or did you write
> > it
> > from scratch?  In either case, how onerous would this be for other
> > targets?
> > 
> > I'm not at expert at target hooks (or at the i386 backend), so if
> > we
> > do
> > go with this approach I'd want someone else to review those parts
> > of
> > the patch.
> > 
> > Have you verified that GCC builds with this patch with jit *not*
> > enabled in the enabled languages?
> > 
> > [...snip...]
> > 
> > A nitpick:
> > 
> > > +.. function:: const char * \
> > > +              gcc_jit_target_info_arch (gcc_jit_target_info
> > > *info)
> > > +
> > > +   Get the architecture of the currently running CPU.
> > 
> > What does this string look like?
> > How long does the pointer remain valid?
> > 
> > Thanks again; hope the above makes sense
> > Dave
> > 
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] libgccjit: Add ability to get CPU features
  2024-01-30 15:50     ` Antoni Boucher
@ 2024-02-06 12:54       ` Antoni Boucher
  2024-02-13 18:37         ` Antoni Boucher
  0 siblings, 1 reply; 21+ messages in thread
From: Antoni Boucher @ 2024-02-06 12:54 UTC (permalink / raw)
  To: David Malcolm, jit, gcc-patches, Iain Buclaw

David: Ping.

On Tue, 2024-01-30 at 10:50 -0500, Antoni Boucher wrote:
> David: I'm unsure what to do here. It seems we cannot find a
> reviewer.
> Would it help if I show you the code in gccrs that is similar?
> Would it help if I ask someone from gccrs to review this code?
> 
> On Sat, 2024-01-20 at 09:50 -0500, Antoni Boucher wrote:
> > CC-ing Iain in case they can do the review since it is based on how
> > they did it in the D frontend.
> > Could you please do the review?
> > Thanks!
> > 
> > On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
> > > On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
> > > > Hi.
> > > > This patch adds support for getting the CPU features in
> > > > libgccjit
> > > > (bug
> > > > 112466)
> > > > 
> > > > There's a TODO in the test:
> > > > I'm not sure how to test that gcc_jit_target_info_arch returns
> > > > the
> > > > correct value since it is dependant on the CPU.
> > > > Any idea on how to improve this?
> > > > 
> > > > Also, I created a CStringHash to be able to have a
> > > > std::unordered_set<const char *>. Is there any built-in way of
> > > > doing
> > > > this?
> > > 
> > > Thanks for the patch.
> > > 
> > > Some high-level questions:
> > > 
> > > Is this specifically about detecting capabilities of the host
> > > that
> > > libgccjit is currently running on? or how the target was
> > > configured
> > > when libgccjit was built?
> > > 
> > > One of the benefits of libgccjit is that, in theory, we support
> > > all
> > > of
> > > the targets that GCC already supports.  Does this patch change
> > > that,
> > > or
> > > is this more about giving client code the ability to determine
> > > capabilities of the specific host being compiled for?
> > > 
> > > I'm nervous about having per-target jit code.  Presumably there's
> > > a
> > > reason that we can't reuse existing target logic here - can you
> > > please
> > > describe what the problem is.  I see that the ChangeLog has:
> > > 
> > > > 	* config/i386/i386-jit.cc: New file.
> > > 
> > > where i386-jit.cc has almost 200 lines of nontrivial code.  Where
> > > did
> > > this come from?  Did you base it on existing code in our source
> > > tree,
> > > making modifications to fit the new internal API, or did you
> > > write
> > > it
> > > from scratch?  In either case, how onerous would this be for
> > > other
> > > targets?
> > > 
> > > I'm not at expert at target hooks (or at the i386 backend), so if
> > > we
> > > do
> > > go with this approach I'd want someone else to review those parts
> > > of
> > > the patch.
> > > 
> > > Have you verified that GCC builds with this patch with jit *not*
> > > enabled in the enabled languages?
> > > 
> > > [...snip...]
> > > 
> > > A nitpick:
> > > 
> > > > +.. function:: const char * \
> > > > +              gcc_jit_target_info_arch (gcc_jit_target_info
> > > > *info)
> > > > +
> > > > +   Get the architecture of the currently running CPU.
> > > 
> > > What does this string look like?
> > > How long does the pointer remain valid?
> > > 
> > > Thanks again; hope the above makes sense
> > > Dave
> > > 
> > 
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] libgccjit: Add ability to get CPU features
  2024-02-06 12:54       ` Antoni Boucher
@ 2024-02-13 18:37         ` Antoni Boucher
  2024-02-29 15:34           ` Antoni Boucher
  0 siblings, 1 reply; 21+ messages in thread
From: Antoni Boucher @ 2024-02-13 18:37 UTC (permalink / raw)
  To: David Malcolm, jit, gcc-patches, Iain Buclaw

David: Ping.

On Tue, 2024-02-06 at 07:54 -0500, Antoni Boucher wrote:
> David: Ping.
> 
> On Tue, 2024-01-30 at 10:50 -0500, Antoni Boucher wrote:
> > David: I'm unsure what to do here. It seems we cannot find a
> > reviewer.
> > Would it help if I show you the code in gccrs that is similar?
> > Would it help if I ask someone from gccrs to review this code?
> > 
> > On Sat, 2024-01-20 at 09:50 -0500, Antoni Boucher wrote:
> > > CC-ing Iain in case they can do the review since it is based on
> > > how
> > > they did it in the D frontend.
> > > Could you please do the review?
> > > Thanks!
> > > 
> > > On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
> > > > On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
> > > > > Hi.
> > > > > This patch adds support for getting the CPU features in
> > > > > libgccjit
> > > > > (bug
> > > > > 112466)
> > > > > 
> > > > > There's a TODO in the test:
> > > > > I'm not sure how to test that gcc_jit_target_info_arch
> > > > > returns
> > > > > the
> > > > > correct value since it is dependant on the CPU.
> > > > > Any idea on how to improve this?
> > > > > 
> > > > > Also, I created a CStringHash to be able to have a
> > > > > std::unordered_set<const char *>. Is there any built-in way
> > > > > of
> > > > > doing
> > > > > this?
> > > > 
> > > > Thanks for the patch.
> > > > 
> > > > Some high-level questions:
> > > > 
> > > > Is this specifically about detecting capabilities of the host
> > > > that
> > > > libgccjit is currently running on? or how the target was
> > > > configured
> > > > when libgccjit was built?
> > > > 
> > > > One of the benefits of libgccjit is that, in theory, we support
> > > > all
> > > > of
> > > > the targets that GCC already supports.  Does this patch change
> > > > that,
> > > > or
> > > > is this more about giving client code the ability to determine
> > > > capabilities of the specific host being compiled for?
> > > > 
> > > > I'm nervous about having per-target jit code.  Presumably
> > > > there's
> > > > a
> > > > reason that we can't reuse existing target logic here - can you
> > > > please
> > > > describe what the problem is.  I see that the ChangeLog has:
> > > > 
> > > > > 	* config/i386/i386-jit.cc: New file.
> > > > 
> > > > where i386-jit.cc has almost 200 lines of nontrivial code. 
> > > > Where
> > > > did
> > > > this come from?  Did you base it on existing code in our source
> > > > tree,
> > > > making modifications to fit the new internal API, or did you
> > > > write
> > > > it
> > > > from scratch?  In either case, how onerous would this be for
> > > > other
> > > > targets?
> > > > 
> > > > I'm not at expert at target hooks (or at the i386 backend), so
> > > > if
> > > > we
> > > > do
> > > > go with this approach I'd want someone else to review those
> > > > parts
> > > > of
> > > > the patch.
> > > > 
> > > > Have you verified that GCC builds with this patch with jit
> > > > *not*
> > > > enabled in the enabled languages?
> > > > 
> > > > [...snip...]
> > > > 
> > > > A nitpick:
> > > > 
> > > > > +.. function:: const char * \
> > > > > +              gcc_jit_target_info_arch (gcc_jit_target_info
> > > > > *info)
> > > > > +
> > > > > +   Get the architecture of the currently running CPU.
> > > > 
> > > > What does this string look like?
> > > > How long does the pointer remain valid?
> > > > 
> > > > Thanks again; hope the above makes sense
> > > > Dave
> > > > 
> > > 
> > 
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] libgccjit: Add ability to get CPU features
  2024-02-13 18:37         ` Antoni Boucher
@ 2024-02-29 15:34           ` Antoni Boucher
  0 siblings, 0 replies; 21+ messages in thread
From: Antoni Boucher @ 2024-02-29 15:34 UTC (permalink / raw)
  To: David Malcolm, jit, gcc-patches, Iain Buclaw

David: Ping.
Iain: Ping.

On Tue, 2024-02-13 at 13:37 -0500, Antoni Boucher wrote:
> David: Ping.
> 
> On Tue, 2024-02-06 at 07:54 -0500, Antoni Boucher wrote:
> > David: Ping.
> > 
> > On Tue, 2024-01-30 at 10:50 -0500, Antoni Boucher wrote:
> > > David: I'm unsure what to do here. It seems we cannot find a
> > > reviewer.
> > > Would it help if I show you the code in gccrs that is similar?
> > > Would it help if I ask someone from gccrs to review this code?
> > > 
> > > On Sat, 2024-01-20 at 09:50 -0500, Antoni Boucher wrote:
> > > > CC-ing Iain in case they can do the review since it is based on
> > > > how
> > > > they did it in the D frontend.
> > > > Could you please do the review?
> > > > Thanks!
> > > > 
> > > > On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
> > > > > On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
> > > > > > Hi.
> > > > > > This patch adds support for getting the CPU features in
> > > > > > libgccjit
> > > > > > (bug
> > > > > > 112466)
> > > > > > 
> > > > > > There's a TODO in the test:
> > > > > > I'm not sure how to test that gcc_jit_target_info_arch
> > > > > > returns
> > > > > > the
> > > > > > correct value since it is dependant on the CPU.
> > > > > > Any idea on how to improve this?
> > > > > > 
> > > > > > Also, I created a CStringHash to be able to have a
> > > > > > std::unordered_set<const char *>. Is there any built-in way
> > > > > > of
> > > > > > doing
> > > > > > this?
> > > > > 
> > > > > Thanks for the patch.
> > > > > 
> > > > > Some high-level questions:
> > > > > 
> > > > > Is this specifically about detecting capabilities of the host
> > > > > that
> > > > > libgccjit is currently running on? or how the target was
> > > > > configured
> > > > > when libgccjit was built?
> > > > > 
> > > > > One of the benefits of libgccjit is that, in theory, we
> > > > > support
> > > > > all
> > > > > of
> > > > > the targets that GCC already supports.  Does this patch
> > > > > change
> > > > > that,
> > > > > or
> > > > > is this more about giving client code the ability to
> > > > > determine
> > > > > capabilities of the specific host being compiled for?
> > > > > 
> > > > > I'm nervous about having per-target jit code.  Presumably
> > > > > there's
> > > > > a
> > > > > reason that we can't reuse existing target logic here - can
> > > > > you
> > > > > please
> > > > > describe what the problem is.  I see that the ChangeLog has:
> > > > > 
> > > > > > 	* config/i386/i386-jit.cc: New file.
> > > > > 
> > > > > where i386-jit.cc has almost 200 lines of nontrivial code. 
> > > > > Where
> > > > > did
> > > > > this come from?  Did you base it on existing code in our
> > > > > source
> > > > > tree,
> > > > > making modifications to fit the new internal API, or did you
> > > > > write
> > > > > it
> > > > > from scratch?  In either case, how onerous would this be for
> > > > > other
> > > > > targets?
> > > > > 
> > > > > I'm not at expert at target hooks (or at the i386 backend),
> > > > > so
> > > > > if
> > > > > we
> > > > > do
> > > > > go with this approach I'd want someone else to review those
> > > > > parts
> > > > > of
> > > > > the patch.
> > > > > 
> > > > > Have you verified that GCC builds with this patch with jit
> > > > > *not*
> > > > > enabled in the enabled languages?
> > > > > 
> > > > > [...snip...]
> > > > > 
> > > > > A nitpick:
> > > > > 
> > > > > > +.. function:: const char * \
> > > > > > +              gcc_jit_target_info_arch
> > > > > > (gcc_jit_target_info
> > > > > > *info)
> > > > > > +
> > > > > > +   Get the architecture of the currently running CPU.
> > > > > 
> > > > > What does this string look like?
> > > > > How long does the pointer remain valid?
> > > > > 
> > > > > Thanks again; hope the above makes sense
> > > > > Dave
> > > > > 
> > > > 
> > > 
> > 
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Frontend access to target features (was Re: [PATCH] libgccjit: Add ability to get CPU features)
  2023-11-10  0:33   ` Antoni Boucher
  2023-11-30 22:11     ` Antoni Boucher
@ 2024-03-05 15:09     ` David Malcolm
  2024-03-10 11:05       ` Iain Buclaw
  2024-03-19 11:03       ` Arthur Cohen
  1 sibling, 2 replies; 21+ messages in thread
From: David Malcolm @ 2024-03-05 15:09 UTC (permalink / raw)
  To: Antoni Boucher, jit, gcc-patches; +Cc: Iain Buclaw, Arthur Cohen

On Thu, 2023-11-09 at 19:33 -0500, Antoni Boucher wrote:
> Hi.
> See answers below.
> 
> On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
> > On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
> > > Hi.
> > > This patch adds support for getting the CPU features in libgccjit
> > > (bug
> > > 112466)
> > > 
> > > There's a TODO in the test:
> > > I'm not sure how to test that gcc_jit_target_info_arch returns
> > > the
> > > correct value since it is dependant on the CPU.
> > > Any idea on how to improve this?
> > > 
> > > Also, I created a CStringHash to be able to have a
> > > std::unordered_set<const char *>. Is there any built-in way of
> > > doing
> > > this?
> > 
> > Thanks for the patch.
> > 
> > Some high-level questions:
> > 
> > Is this specifically about detecting capabilities of the host that
> > libgccjit is currently running on? or how the target was configured
> > when libgccjit was built?
> 
> I'm less sure about this part. I'll need to do more tests.
> 
> > 
> > One of the benefits of libgccjit is that, in theory, we support all
> > of
> > the targets that GCC already supports.  Does this patch change
> > that,
> > or
> > is this more about giving client code the ability to determine
> > capabilities of the specific host being compiled for?
> 
> This should not change that. If it does, this is a bug.
> 
> > 
> > I'm nervous about having per-target jit code.  Presumably there's a
> > reason that we can't reuse existing target logic here - can you
> > please
> > describe what the problem is.  I see that the ChangeLog has:
> > 
> > >         * config/i386/i386-jit.cc: New file.
> > 
> > where i386-jit.cc has almost 200 lines of nontrivial code.  Where
> > did
> > this come from?  Did you base it on existing code in our source
> > tree,
> > making modifications to fit the new internal API, or did you write
> > it
> > from scratch?  In either case, how onerous would this be for other
> > targets?
> 
> This was mostly copied from the same code done for the Rust and D
> frontends.
> See this commit and the following:
> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=b1c06fd9723453dd2b2ec306684cb806dc2b4fbb
> The equivalent to i386-jit.cc is there:
> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=22e3557e2d52f129f2bbfdc98688b945dba28dc9

[CCing Iain and Arthur re those patches; for reference, the patch being
discussed is attached to :
https://gcc.gnu.org/pipermail/jit/2024q1/001792.html ]

One of my concerns about this patch is that we seem to be gaining code
that's per-(frontend x config) which seems to be copied and pasted with
a search and replace, which could lead to an M*N explosion.

Is there any real difference between the per-config code for the
different frontends, or should there be a general "enumerate all
features of the target" hook that's independent of the frontend? (but
perhaps calls into it).

Am I right in thinking that (rustc with default LLVM backend) has some
set of feature strings that both (rustc with rustc_codegen_gcc) and
gccrs are trying to emulate?  If so, is it presumably a goal that
libgccjit gives identical results to gccrs?  If so, would it be crazy
for libgccjit to consume e.g. config/i386/i386-rust.cc ?

Dave

> 
> > 
> > I'm not at expert at target hooks (or at the i386 backend), so if
> > we
> > do
> > go with this approach I'd want someone else to review those parts
> > of
> > the patch.
> > 
> > Have you verified that GCC builds with this patch with jit *not*
> > enabled in the enabled languages?
> 
> I will do.
> 
> > 
> > [...snip...]
> > 
> > A nitpick:
> > 
> > > +.. function:: const char * \
> > > +              gcc_jit_target_info_arch (gcc_jit_target_info
> > > *info)
> > > +
> > > +   Get the architecture of the currently running CPU.
> > 
> > What does this string look like?
> > How long does the pointer remain valid?
> 
> It's the march string, like "znver2", for instance.
> It remains valid until we free the gcc_jit_target_info object.
> 
> > 
> > Thanks again; hope the above makes sense
> > Dave
> > 
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Frontend access to target features (was Re: [PATCH] libgccjit: Add ability to get CPU features)
  2024-03-05 15:09     ` Frontend access to target features (was Re: [PATCH] libgccjit: Add ability to get CPU features) David Malcolm
@ 2024-03-10 11:05       ` Iain Buclaw
  2024-03-18 11:39         ` Antoni Boucher
  2024-03-19 11:03       ` Arthur Cohen
  1 sibling, 1 reply; 21+ messages in thread
From: Iain Buclaw @ 2024-03-10 11:05 UTC (permalink / raw)
  To: Antoni Boucher, David Malcolm, gcc-patches, jit; +Cc: Arthur Cohen

Excerpts from David Malcolm's message of März 5, 2024 4:09 pm:
> On Thu, 2023-11-09 at 19:33 -0500, Antoni Boucher wrote:
>> Hi.
>> See answers below.
>> 
>> On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
>> > On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
>> > > Hi.
>> > > This patch adds support for getting the CPU features in libgccjit
>> > > (bug
>> > > 112466)
>> > > 
>> > > There's a TODO in the test:
>> > > I'm not sure how to test that gcc_jit_target_info_arch returns
>> > > the
>> > > correct value since it is dependant on the CPU.
>> > > Any idea on how to improve this?
>> > > 
>> > > Also, I created a CStringHash to be able to have a
>> > > std::unordered_set<const char *>. Is there any built-in way of
>> > > doing
>> > > this?
>> > 
>> > Thanks for the patch.
>> > 
>> > Some high-level questions:
>> > 
>> > Is this specifically about detecting capabilities of the host that
>> > libgccjit is currently running on? or how the target was configured
>> > when libgccjit was built?
>> 
>> I'm less sure about this part. I'll need to do more tests.
>> 
>> > 
>> > One of the benefits of libgccjit is that, in theory, we support all
>> > of
>> > the targets that GCC already supports.  Does this patch change
>> > that,
>> > or
>> > is this more about giving client code the ability to determine
>> > capabilities of the specific host being compiled for?
>> 
>> This should not change that. If it does, this is a bug.
>> 
>> > 
>> > I'm nervous about having per-target jit code.  Presumably there's a
>> > reason that we can't reuse existing target logic here - can you
>> > please
>> > describe what the problem is.  I see that the ChangeLog has:
>> > 
>> > >         * config/i386/i386-jit.cc: New file.
>> > 
>> > where i386-jit.cc has almost 200 lines of nontrivial code.  Where
>> > did
>> > this come from?  Did you base it on existing code in our source
>> > tree,
>> > making modifications to fit the new internal API, or did you write
>> > it
>> > from scratch?  In either case, how onerous would this be for other
>> > targets?
>> 
>> This was mostly copied from the same code done for the Rust and D
>> frontends.
>> See this commit and the following:
>> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=b1c06fd9723453dd2b2ec306684cb806dc2b4fbb
>> The equivalent to i386-jit.cc is there:
>> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=22e3557e2d52f129f2bbfdc98688b945dba28dc9
> 
> [CCing Iain and Arthur re those patches; for reference, the patch being
> discussed is attached to :
> https://gcc.gnu.org/pipermail/jit/2024q1/001792.html ]
> 
> One of my concerns about this patch is that we seem to be gaining code
> that's per-(frontend x config) which seems to be copied and pasted with
> a search and replace, which could lead to an M*N explosion.
> 

That's certainly the case with the configure/make rules. Itself I think
is copied originally from the {cpu_type}-protos.h machinery.

It might be worth pointing out that the c-family of front-ends don't
have separate headers because their per-target macros are defined in
{cpu_type}.h directly - for better or worse.

> Is there any real difference between the per-config code for the
> different frontends, or should there be a general "enumerate all
> features of the target" hook that's independent of the frontend? (but
> perhaps calls into it).
> 

As far as I understand, the configure parts should all be identical
between tm_p, tm_d, tm_rust, ..., so would benefit from being templated
to aid any other front-ends adding in their own per target hooks.

> Am I right in thinking that (rustc with default LLVM backend) has some
> set of feature strings that both (rustc with rustc_codegen_gcc) and
> gccrs are trying to emulate?  If so, is it presumably a goal that
> libgccjit gives identical results to gccrs?  If so, would it be crazy
> for libgccjit to consume e.g. config/i386/i386-rust.cc ?

I don't know whether libgccjit can just pull in directly the
implementation of the rust target hooks here.  The per-frontend target
hooks usually also make use of code specific to that front-end -
TARGET_CPU_CPP_BUILTINS and others can't be used by a non-c-family
front-end without adding a plethora of stubs, for example.

Whether or not libgccjit wants to give identical information as as rust
I think is a decision for you as the maintainer of its API.

Iain.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Frontend access to target features (was Re: [PATCH] libgccjit: Add ability to get CPU features)
  2024-03-10 11:05       ` Iain Buclaw
@ 2024-03-18 11:39         ` Antoni Boucher
  0 siblings, 0 replies; 21+ messages in thread
From: Antoni Boucher @ 2024-03-18 11:39 UTC (permalink / raw)
  To: Iain Buclaw, David Malcolm, gcc-patches, jit; +Cc: Arthur Cohen

David: Ping.

Le 2024-03-10 à 07 h 05, Iain Buclaw a écrit :
> Excerpts from David Malcolm's message of März 5, 2024 4:09 pm:
>> On Thu, 2023-11-09 at 19:33 -0500, Antoni Boucher wrote:
>>> Hi.
>>> See answers below.
>>>
>>> On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
>>>> On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
>>>>> Hi.
>>>>> This patch adds support for getting the CPU features in libgccjit
>>>>> (bug
>>>>> 112466)
>>>>>
>>>>> There's a TODO in the test:
>>>>> I'm not sure how to test that gcc_jit_target_info_arch returns
>>>>> the
>>>>> correct value since it is dependant on the CPU.
>>>>> Any idea on how to improve this?
>>>>>
>>>>> Also, I created a CStringHash to be able to have a
>>>>> std::unordered_set<const char *>. Is there any built-in way of
>>>>> doing
>>>>> this?
>>>>
>>>> Thanks for the patch.
>>>>
>>>> Some high-level questions:
>>>>
>>>> Is this specifically about detecting capabilities of the host that
>>>> libgccjit is currently running on? or how the target was configured
>>>> when libgccjit was built?
>>>
>>> I'm less sure about this part. I'll need to do more tests.
>>>
>>>>
>>>> One of the benefits of libgccjit is that, in theory, we support all
>>>> of
>>>> the targets that GCC already supports.  Does this patch change
>>>> that,
>>>> or
>>>> is this more about giving client code the ability to determine
>>>> capabilities of the specific host being compiled for?
>>>
>>> This should not change that. If it does, this is a bug.
>>>
>>>>
>>>> I'm nervous about having per-target jit code.  Presumably there's a
>>>> reason that we can't reuse existing target logic here - can you
>>>> please
>>>> describe what the problem is.  I see that the ChangeLog has:
>>>>
>>>>>          * config/i386/i386-jit.cc: New file.
>>>>
>>>> where i386-jit.cc has almost 200 lines of nontrivial code.  Where
>>>> did
>>>> this come from?  Did you base it on existing code in our source
>>>> tree,
>>>> making modifications to fit the new internal API, or did you write
>>>> it
>>>> from scratch?  In either case, how onerous would this be for other
>>>> targets?
>>>
>>> This was mostly copied from the same code done for the Rust and D
>>> frontends.
>>> See this commit and the following:
>>> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=b1c06fd9723453dd2b2ec306684cb806dc2b4fbb
>>> The equivalent to i386-jit.cc is there:
>>> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=22e3557e2d52f129f2bbfdc98688b945dba28dc9
>>
>> [CCing Iain and Arthur re those patches; for reference, the patch being
>> discussed is attached to :
>> https://gcc.gnu.org/pipermail/jit/2024q1/001792.html ]
>>
>> One of my concerns about this patch is that we seem to be gaining code
>> that's per-(frontend x config) which seems to be copied and pasted with
>> a search and replace, which could lead to an M*N explosion.
>>
> 
> That's certainly the case with the configure/make rules. Itself I think
> is copied originally from the {cpu_type}-protos.h machinery.
> 
> It might be worth pointing out that the c-family of front-ends don't
> have separate headers because their per-target macros are defined in
> {cpu_type}.h directly - for better or worse.
> 
>> Is there any real difference between the per-config code for the
>> different frontends, or should there be a general "enumerate all
>> features of the target" hook that's independent of the frontend? (but
>> perhaps calls into it).
>>
> 
> As far as I understand, the configure parts should all be identical
> between tm_p, tm_d, tm_rust, ..., so would benefit from being templated
> to aid any other front-ends adding in their own per target hooks.
> 
>> Am I right in thinking that (rustc with default LLVM backend) has some
>> set of feature strings that both (rustc with rustc_codegen_gcc) and
>> gccrs are trying to emulate?  If so, is it presumably a goal that
>> libgccjit gives identical results to gccrs?  If so, would it be crazy
>> for libgccjit to consume e.g. config/i386/i386-rust.cc ?
> 
> I don't know whether libgccjit can just pull in directly the
> implementation of the rust target hooks here.  The per-frontend target
> hooks usually also make use of code specific to that front-end -
> TARGET_CPU_CPP_BUILTINS and others can't be used by a non-c-family
> front-end without adding a plethora of stubs, for example.
> 
> Whether or not libgccjit wants to give identical information as as rust
> I think is a decision for you as the maintainer of its API.
> 
> Iain.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Frontend access to target features (was Re: [PATCH] libgccjit: Add ability to get CPU features)
  2024-03-05 15:09     ` Frontend access to target features (was Re: [PATCH] libgccjit: Add ability to get CPU features) David Malcolm
  2024-03-10 11:05       ` Iain Buclaw
@ 2024-03-19 11:03       ` Arthur Cohen
  2024-04-01 12:20         ` Antoni Boucher
  1 sibling, 1 reply; 21+ messages in thread
From: Arthur Cohen @ 2024-03-19 11:03 UTC (permalink / raw)
  To: David Malcolm, Antoni Boucher, jit, gcc-patches; +Cc: Iain Buclaw


[-- Attachment #1.1.1: Type: text/plain, Size: 4782 bytes --]

Hi,

On 3/5/24 16:09, David Malcolm wrote:
> On Thu, 2023-11-09 at 19:33 -0500, Antoni Boucher wrote:
>> Hi.
>> See answers below.
>>
>> On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
>>> On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
>>>> Hi.
>>>> This patch adds support for getting the CPU features in libgccjit
>>>> (bug
>>>> 112466)
>>>>
>>>> There's a TODO in the test:
>>>> I'm not sure how to test that gcc_jit_target_info_arch returns
>>>> the
>>>> correct value since it is dependant on the CPU.
>>>> Any idea on how to improve this?
>>>>
>>>> Also, I created a CStringHash to be able to have a
>>>> std::unordered_set<const char *>. Is there any built-in way of
>>>> doing
>>>> this?
>>>
>>> Thanks for the patch.
>>>
>>> Some high-level questions:
>>>
>>> Is this specifically about detecting capabilities of the host that
>>> libgccjit is currently running on? or how the target was configured
>>> when libgccjit was built?
>>
>> I'm less sure about this part. I'll need to do more tests.
>>
>>>
>>> One of the benefits of libgccjit is that, in theory, we support all
>>> of
>>> the targets that GCC already supports.  Does this patch change
>>> that,
>>> or
>>> is this more about giving client code the ability to determine
>>> capabilities of the specific host being compiled for?
>>
>> This should not change that. If it does, this is a bug.
>>
>>>
>>> I'm nervous about having per-target jit code.  Presumably there's a
>>> reason that we can't reuse existing target logic here - can you
>>> please
>>> describe what the problem is.  I see that the ChangeLog has:
>>>
>>>>          * config/i386/i386-jit.cc: New file.
>>>
>>> where i386-jit.cc has almost 200 lines of nontrivial code.  Where
>>> did
>>> this come from?  Did you base it on existing code in our source
>>> tree,
>>> making modifications to fit the new internal API, or did you write
>>> it
>>> from scratch?  In either case, how onerous would this be for other
>>> targets?
>>
>> This was mostly copied from the same code done for the Rust and D
>> frontends.
>> See this commit and the following:
>> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=b1c06fd9723453dd2b2ec306684cb806dc2b4fbb
>> The equivalent to i386-jit.cc is there:
>> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=22e3557e2d52f129f2bbfdc98688b945dba28dc9
> 
> [CCing Iain and Arthur re those patches; for reference, the patch being
> discussed is attached to :
> https://gcc.gnu.org/pipermail/jit/2024q1/001792.html ]
> 
> One of my concerns about this patch is that we seem to be gaining code
> that's per-(frontend x config) which seems to be copied and pasted with
> a search and replace, which could lead to an M*N explosion.

I think this is definitely already the case, and it would be worth 
investigating if C/C++/Rust/jit can reuse a similar set of target files, 
or how to factor them together. I imagine that all of these components 
share similar needs for the targets they support.

> 
> Is there any real difference between the per-config code for the
> different frontends, or should there be a general "enumerate all
> features of the target" hook that's independent of the frontend? (but
> perhaps calls into it).
> 
> Am I right in thinking that (rustc with default LLVM backend) has some
> set of feature strings that both (rustc with rustc_codegen_gcc) and
> gccrs are trying to emulate?  If so, is it presumably a goal that
> libgccjit gives identical results to gccrs?  If so, would it be crazy
> for libgccjit to consume e.g. config/i386/i386-rust.cc ?

I think this would definitely make sense, and it could probably be 
extended to other frontends. For the time being I think it makes sense 
to try it out for gccrs and jit. But finding a fitting name will be hard :)

Best,

Arthur

> 
> Dave
> 
>>
>>>
>>> I'm not at expert at target hooks (or at the i386 backend), so if
>>> we
>>> do
>>> go with this approach I'd want someone else to review those parts
>>> of
>>> the patch.
>>>
>>> Have you verified that GCC builds with this patch with jit *not*
>>> enabled in the enabled languages?
>>
>> I will do.
>>
>>>
>>> [...snip...]
>>>
>>> A nitpick:
>>>
>>>> +.. function:: const char * \
>>>> +              gcc_jit_target_info_arch (gcc_jit_target_info
>>>> *info)
>>>> +
>>>> +   Get the architecture of the currently running CPU.
>>>
>>> What does this string look like?
>>> How long does the pointer remain valid?
>>
>> It's the march string, like "znver2", for instance.
>> It remains valid until we free the gcc_jit_target_info object.
>>
>>>
>>> Thanks again; hope the above makes sense
>>> Dave
>>>
>>
> 

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3195 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Frontend access to target features (was Re: [PATCH] libgccjit: Add ability to get CPU features)
  2024-03-19 11:03       ` Arthur Cohen
@ 2024-04-01 12:20         ` Antoni Boucher
  2024-04-09 13:21           ` Antoni Boucher
  0 siblings, 1 reply; 21+ messages in thread
From: Antoni Boucher @ 2024-04-01 12:20 UTC (permalink / raw)
  To: Arthur Cohen, David Malcolm, jit, gcc-patches; +Cc: Iain Buclaw

David: Ping.

Le 2024-03-19 à 07 h 03, Arthur Cohen a écrit :
> Hi,
> 
> On 3/5/24 16:09, David Malcolm wrote:
>> On Thu, 2023-11-09 at 19:33 -0500, Antoni Boucher wrote:
>>> Hi.
>>> See answers below.
>>>
>>> On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
>>>> On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
>>>>> Hi.
>>>>> This patch adds support for getting the CPU features in libgccjit
>>>>> (bug
>>>>> 112466)
>>>>>
>>>>> There's a TODO in the test:
>>>>> I'm not sure how to test that gcc_jit_target_info_arch returns
>>>>> the
>>>>> correct value since it is dependant on the CPU.
>>>>> Any idea on how to improve this?
>>>>>
>>>>> Also, I created a CStringHash to be able to have a
>>>>> std::unordered_set<const char *>. Is there any built-in way of
>>>>> doing
>>>>> this?
>>>>
>>>> Thanks for the patch.
>>>>
>>>> Some high-level questions:
>>>>
>>>> Is this specifically about detecting capabilities of the host that
>>>> libgccjit is currently running on? or how the target was configured
>>>> when libgccjit was built?
>>>
>>> I'm less sure about this part. I'll need to do more tests.
>>>
>>>>
>>>> One of the benefits of libgccjit is that, in theory, we support all
>>>> of
>>>> the targets that GCC already supports.  Does this patch change
>>>> that,
>>>> or
>>>> is this more about giving client code the ability to determine
>>>> capabilities of the specific host being compiled for?
>>>
>>> This should not change that. If it does, this is a bug.
>>>
>>>>
>>>> I'm nervous about having per-target jit code.  Presumably there's a
>>>> reason that we can't reuse existing target logic here - can you
>>>> please
>>>> describe what the problem is.  I see that the ChangeLog has:
>>>>
>>>>>          * config/i386/i386-jit.cc: New file.
>>>>
>>>> where i386-jit.cc has almost 200 lines of nontrivial code.  Where
>>>> did
>>>> this come from?  Did you base it on existing code in our source
>>>> tree,
>>>> making modifications to fit the new internal API, or did you write
>>>> it
>>>> from scratch?  In either case, how onerous would this be for other
>>>> targets?
>>>
>>> This was mostly copied from the same code done for the Rust and D
>>> frontends.
>>> See this commit and the following:
>>> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=b1c06fd9723453dd2b2ec306684cb806dc2b4fbb
>>> The equivalent to i386-jit.cc is there:
>>> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=22e3557e2d52f129f2bbfdc98688b945dba28dc9
>>
>> [CCing Iain and Arthur re those patches; for reference, the patch being
>> discussed is attached to :
>> https://gcc.gnu.org/pipermail/jit/2024q1/001792.html ]
>>
>> One of my concerns about this patch is that we seem to be gaining code
>> that's per-(frontend x config) which seems to be copied and pasted with
>> a search and replace, which could lead to an M*N explosion.
> 
> I think this is definitely already the case, and it would be worth 
> investigating if C/C++/Rust/jit can reuse a similar set of target files, 
> or how to factor them together. I imagine that all of these components 
> share similar needs for the targets they support.
> 
>>
>> Is there any real difference between the per-config code for the
>> different frontends, or should there be a general "enumerate all
>> features of the target" hook that's independent of the frontend? (but
>> perhaps calls into it).
>>
>> Am I right in thinking that (rustc with default LLVM backend) has some
>> set of feature strings that both (rustc with rustc_codegen_gcc) and
>> gccrs are trying to emulate?  If so, is it presumably a goal that
>> libgccjit gives identical results to gccrs?  If so, would it be crazy
>> for libgccjit to consume e.g. config/i386/i386-rust.cc ?
> 
> I think this would definitely make sense, and it could probably be 
> extended to other frontends. For the time being I think it makes sense 
> to try it out for gccrs and jit. But finding a fitting name will be hard :)
> 
> Best,
> 
> Arthur
> 
>>
>> Dave
>>
>>>
>>>>
>>>> I'm not at expert at target hooks (or at the i386 backend), so if
>>>> we
>>>> do
>>>> go with this approach I'd want someone else to review those parts
>>>> of
>>>> the patch.
>>>>
>>>> Have you verified that GCC builds with this patch with jit *not*
>>>> enabled in the enabled languages?
>>>
>>> I will do.
>>>
>>>>
>>>> [...snip...]
>>>>
>>>> A nitpick:
>>>>
>>>>> +.. function:: const char * \
>>>>> +              gcc_jit_target_info_arch (gcc_jit_target_info
>>>>> *info)
>>>>> +
>>>>> +   Get the architecture of the currently running CPU.
>>>>
>>>> What does this string look like?
>>>> How long does the pointer remain valid?
>>>
>>> It's the march string, like "znver2", for instance.
>>> It remains valid until we free the gcc_jit_target_info object.
>>>
>>>>
>>>> Thanks again; hope the above makes sense
>>>> Dave
>>>>
>>>
>>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Frontend access to target features (was Re: [PATCH] libgccjit: Add ability to get CPU features)
  2024-04-01 12:20         ` Antoni Boucher
@ 2024-04-09 13:21           ` Antoni Boucher
  2024-04-19 12:34             ` Antoni Boucher
  0 siblings, 1 reply; 21+ messages in thread
From: Antoni Boucher @ 2024-04-09 13:21 UTC (permalink / raw)
  To: David Malcolm, jit, gcc-patches

David: Ping.

Le 2024-04-01 à 08 h 20, Antoni Boucher a écrit :
> David: Ping.
> 
> Le 2024-03-19 à 07 h 03, Arthur Cohen a écrit :
>> Hi,
>>
>> On 3/5/24 16:09, David Malcolm wrote:
>>> On Thu, 2023-11-09 at 19:33 -0500, Antoni Boucher wrote:
>>>> Hi.
>>>> See answers below.
>>>>
>>>> On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
>>>>> On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
>>>>>> Hi.
>>>>>> This patch adds support for getting the CPU features in libgccjit
>>>>>> (bug
>>>>>> 112466)
>>>>>>
>>>>>> There's a TODO in the test:
>>>>>> I'm not sure how to test that gcc_jit_target_info_arch returns
>>>>>> the
>>>>>> correct value since it is dependant on the CPU.
>>>>>> Any idea on how to improve this?
>>>>>>
>>>>>> Also, I created a CStringHash to be able to have a
>>>>>> std::unordered_set<const char *>. Is there any built-in way of
>>>>>> doing
>>>>>> this?
>>>>>
>>>>> Thanks for the patch.
>>>>>
>>>>> Some high-level questions:
>>>>>
>>>>> Is this specifically about detecting capabilities of the host that
>>>>> libgccjit is currently running on? or how the target was configured
>>>>> when libgccjit was built?
>>>>
>>>> I'm less sure about this part. I'll need to do more tests.
>>>>
>>>>>
>>>>> One of the benefits of libgccjit is that, in theory, we support all
>>>>> of
>>>>> the targets that GCC already supports.  Does this patch change
>>>>> that,
>>>>> or
>>>>> is this more about giving client code the ability to determine
>>>>> capabilities of the specific host being compiled for?
>>>>
>>>> This should not change that. If it does, this is a bug.
>>>>
>>>>>
>>>>> I'm nervous about having per-target jit code.  Presumably there's a
>>>>> reason that we can't reuse existing target logic here - can you
>>>>> please
>>>>> describe what the problem is.  I see that the ChangeLog has:
>>>>>
>>>>>>          * config/i386/i386-jit.cc: New file.
>>>>>
>>>>> where i386-jit.cc has almost 200 lines of nontrivial code.  Where
>>>>> did
>>>>> this come from?  Did you base it on existing code in our source
>>>>> tree,
>>>>> making modifications to fit the new internal API, or did you write
>>>>> it
>>>>> from scratch?  In either case, how onerous would this be for other
>>>>> targets?
>>>>
>>>> This was mostly copied from the same code done for the Rust and D
>>>> frontends.
>>>> See this commit and the following:
>>>> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=b1c06fd9723453dd2b2ec306684cb806dc2b4fbb
>>>> The equivalent to i386-jit.cc is there:
>>>> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=22e3557e2d52f129f2bbfdc98688b945dba28dc9
>>>
>>> [CCing Iain and Arthur re those patches; for reference, the patch being
>>> discussed is attached to :
>>> https://gcc.gnu.org/pipermail/jit/2024q1/001792.html ]
>>>
>>> One of my concerns about this patch is that we seem to be gaining code
>>> that's per-(frontend x config) which seems to be copied and pasted with
>>> a search and replace, which could lead to an M*N explosion.
>>
>> I think this is definitely already the case, and it would be worth 
>> investigating if C/C++/Rust/jit can reuse a similar set of target 
>> files, or how to factor them together. I imagine that all of these 
>> components share similar needs for the targets they support.
>>
>>>
>>> Is there any real difference between the per-config code for the
>>> different frontends, or should there be a general "enumerate all
>>> features of the target" hook that's independent of the frontend? (but
>>> perhaps calls into it).
>>>
>>> Am I right in thinking that (rustc with default LLVM backend) has some
>>> set of feature strings that both (rustc with rustc_codegen_gcc) and
>>> gccrs are trying to emulate?  If so, is it presumably a goal that
>>> libgccjit gives identical results to gccrs?  If so, would it be crazy
>>> for libgccjit to consume e.g. config/i386/i386-rust.cc ?
>>
>> I think this would definitely make sense, and it could probably be 
>> extended to other frontends. For the time being I think it makes sense 
>> to try it out for gccrs and jit. But finding a fitting name will be 
>> hard :)
>>
>> Best,
>>
>> Arthur
>>
>>>
>>> Dave
>>>
>>>>
>>>>>
>>>>> I'm not at expert at target hooks (or at the i386 backend), so if
>>>>> we
>>>>> do
>>>>> go with this approach I'd want someone else to review those parts
>>>>> of
>>>>> the patch.
>>>>>
>>>>> Have you verified that GCC builds with this patch with jit *not*
>>>>> enabled in the enabled languages?
>>>>
>>>> I will do.
>>>>
>>>>>
>>>>> [...snip...]
>>>>>
>>>>> A nitpick:
>>>>>
>>>>>> +.. function:: const char * \
>>>>>> +              gcc_jit_target_info_arch (gcc_jit_target_info
>>>>>> *info)
>>>>>> +
>>>>>> +   Get the architecture of the currently running CPU.
>>>>>
>>>>> What does this string look like?
>>>>> How long does the pointer remain valid?
>>>>
>>>> It's the march string, like "znver2", for instance.
>>>> It remains valid until we free the gcc_jit_target_info object.
>>>>
>>>>>
>>>>> Thanks again; hope the above makes sense
>>>>> Dave
>>>>>
>>>>
>>>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Frontend access to target features (was Re: [PATCH] libgccjit: Add ability to get CPU features)
  2024-04-09 13:21           ` Antoni Boucher
@ 2024-04-19 12:34             ` Antoni Boucher
  2024-04-26 13:51               ` Antoni Boucher
  0 siblings, 1 reply; 21+ messages in thread
From: Antoni Boucher @ 2024-04-19 12:34 UTC (permalink / raw)
  To: David Malcolm, jit, gcc-patches

David: Ping.

Le 2024-04-09 à 09 h 21, Antoni Boucher a écrit :
> David: Ping.
> 
> Le 2024-04-01 à 08 h 20, Antoni Boucher a écrit :
>> David: Ping.
>>
>> Le 2024-03-19 à 07 h 03, Arthur Cohen a écrit :
>>> Hi,
>>>
>>> On 3/5/24 16:09, David Malcolm wrote:
>>>> On Thu, 2023-11-09 at 19:33 -0500, Antoni Boucher wrote:
>>>>> Hi.
>>>>> See answers below.
>>>>>
>>>>> On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
>>>>>> On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
>>>>>>> Hi.
>>>>>>> This patch adds support for getting the CPU features in libgccjit
>>>>>>> (bug
>>>>>>> 112466)
>>>>>>>
>>>>>>> There's a TODO in the test:
>>>>>>> I'm not sure how to test that gcc_jit_target_info_arch returns
>>>>>>> the
>>>>>>> correct value since it is dependant on the CPU.
>>>>>>> Any idea on how to improve this?
>>>>>>>
>>>>>>> Also, I created a CStringHash to be able to have a
>>>>>>> std::unordered_set<const char *>. Is there any built-in way of
>>>>>>> doing
>>>>>>> this?
>>>>>>
>>>>>> Thanks for the patch.
>>>>>>
>>>>>> Some high-level questions:
>>>>>>
>>>>>> Is this specifically about detecting capabilities of the host that
>>>>>> libgccjit is currently running on? or how the target was configured
>>>>>> when libgccjit was built?
>>>>>
>>>>> I'm less sure about this part. I'll need to do more tests.
>>>>>
>>>>>>
>>>>>> One of the benefits of libgccjit is that, in theory, we support all
>>>>>> of
>>>>>> the targets that GCC already supports.  Does this patch change
>>>>>> that,
>>>>>> or
>>>>>> is this more about giving client code the ability to determine
>>>>>> capabilities of the specific host being compiled for?
>>>>>
>>>>> This should not change that. If it does, this is a bug.
>>>>>
>>>>>>
>>>>>> I'm nervous about having per-target jit code.  Presumably there's a
>>>>>> reason that we can't reuse existing target logic here - can you
>>>>>> please
>>>>>> describe what the problem is.  I see that the ChangeLog has:
>>>>>>
>>>>>>>          * config/i386/i386-jit.cc: New file.
>>>>>>
>>>>>> where i386-jit.cc has almost 200 lines of nontrivial code.  Where
>>>>>> did
>>>>>> this come from?  Did you base it on existing code in our source
>>>>>> tree,
>>>>>> making modifications to fit the new internal API, or did you write
>>>>>> it
>>>>>> from scratch?  In either case, how onerous would this be for other
>>>>>> targets?
>>>>>
>>>>> This was mostly copied from the same code done for the Rust and D
>>>>> frontends.
>>>>> See this commit and the following:
>>>>> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=b1c06fd9723453dd2b2ec306684cb806dc2b4fbb
>>>>> The equivalent to i386-jit.cc is there:
>>>>> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=22e3557e2d52f129f2bbfdc98688b945dba28dc9
>>>>
>>>> [CCing Iain and Arthur re those patches; for reference, the patch being
>>>> discussed is attached to :
>>>> https://gcc.gnu.org/pipermail/jit/2024q1/001792.html ]
>>>>
>>>> One of my concerns about this patch is that we seem to be gaining code
>>>> that's per-(frontend x config) which seems to be copied and pasted with
>>>> a search and replace, which could lead to an M*N explosion.
>>>
>>> I think this is definitely already the case, and it would be worth 
>>> investigating if C/C++/Rust/jit can reuse a similar set of target 
>>> files, or how to factor them together. I imagine that all of these 
>>> components share similar needs for the targets they support.
>>>
>>>>
>>>> Is there any real difference between the per-config code for the
>>>> different frontends, or should there be a general "enumerate all
>>>> features of the target" hook that's independent of the frontend? (but
>>>> perhaps calls into it).
>>>>
>>>> Am I right in thinking that (rustc with default LLVM backend) has some
>>>> set of feature strings that both (rustc with rustc_codegen_gcc) and
>>>> gccrs are trying to emulate?  If so, is it presumably a goal that
>>>> libgccjit gives identical results to gccrs?  If so, would it be crazy
>>>> for libgccjit to consume e.g. config/i386/i386-rust.cc ?
>>>
>>> I think this would definitely make sense, and it could probably be 
>>> extended to other frontends. For the time being I think it makes 
>>> sense to try it out for gccrs and jit. But finding a fitting name 
>>> will be hard :)
>>>
>>> Best,
>>>
>>> Arthur
>>>
>>>>
>>>> Dave
>>>>
>>>>>
>>>>>>
>>>>>> I'm not at expert at target hooks (or at the i386 backend), so if
>>>>>> we
>>>>>> do
>>>>>> go with this approach I'd want someone else to review those parts
>>>>>> of
>>>>>> the patch.
>>>>>>
>>>>>> Have you verified that GCC builds with this patch with jit *not*
>>>>>> enabled in the enabled languages?
>>>>>
>>>>> I will do.
>>>>>
>>>>>>
>>>>>> [...snip...]
>>>>>>
>>>>>> A nitpick:
>>>>>>
>>>>>>> +.. function:: const char * \
>>>>>>> +              gcc_jit_target_info_arch (gcc_jit_target_info
>>>>>>> *info)
>>>>>>> +
>>>>>>> +   Get the architecture of the currently running CPU.
>>>>>>
>>>>>> What does this string look like?
>>>>>> How long does the pointer remain valid?
>>>>>
>>>>> It's the march string, like "znver2", for instance.
>>>>> It remains valid until we free the gcc_jit_target_info object.
>>>>>
>>>>>>
>>>>>> Thanks again; hope the above makes sense
>>>>>> Dave
>>>>>>
>>>>>
>>>>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Frontend access to target features (was Re: [PATCH] libgccjit: Add ability to get CPU features)
  2024-04-19 12:34             ` Antoni Boucher
@ 2024-04-26 13:51               ` Antoni Boucher
  0 siblings, 0 replies; 21+ messages in thread
From: Antoni Boucher @ 2024-04-26 13:51 UTC (permalink / raw)
  To: David Malcolm, jit, gcc-patches

Now that we have a more general way to check if target-dependent types 
are supported (see this commit: 
https://github.com/rust-lang/gcc/commit/1c9a9b2f1fd914cad911467ec1d29f158643c2ce#diff-018089519ab2b14a34313ded0ae1a2f9fcab5f7bcb2fa31f147e1dc757bbdd7aR4016), 
perhaps we should remove gcc_jit_target_info_supports_128bit_int from 
this patch, or change it to include the more general way.

David, what are your thoughts on this?

Le 2024-04-19 à 08 h 34, Antoni Boucher a écrit :
> David: Ping.
> 
> Le 2024-04-09 à 09 h 21, Antoni Boucher a écrit :
>> David: Ping.
>>
>> Le 2024-04-01 à 08 h 20, Antoni Boucher a écrit :
>>> David: Ping.
>>>
>>> Le 2024-03-19 à 07 h 03, Arthur Cohen a écrit :
>>>> Hi,
>>>>
>>>> On 3/5/24 16:09, David Malcolm wrote:
>>>>> On Thu, 2023-11-09 at 19:33 -0500, Antoni Boucher wrote:
>>>>>> Hi.
>>>>>> See answers below.
>>>>>>
>>>>>> On Thu, 2023-11-09 at 18:04 -0500, David Malcolm wrote:
>>>>>>> On Thu, 2023-11-09 at 17:27 -0500, Antoni Boucher wrote:
>>>>>>>> Hi.
>>>>>>>> This patch adds support for getting the CPU features in libgccjit
>>>>>>>> (bug
>>>>>>>> 112466)
>>>>>>>>
>>>>>>>> There's a TODO in the test:
>>>>>>>> I'm not sure how to test that gcc_jit_target_info_arch returns
>>>>>>>> the
>>>>>>>> correct value since it is dependant on the CPU.
>>>>>>>> Any idea on how to improve this?
>>>>>>>>
>>>>>>>> Also, I created a CStringHash to be able to have a
>>>>>>>> std::unordered_set<const char *>. Is there any built-in way of
>>>>>>>> doing
>>>>>>>> this?
>>>>>>>
>>>>>>> Thanks for the patch.
>>>>>>>
>>>>>>> Some high-level questions:
>>>>>>>
>>>>>>> Is this specifically about detecting capabilities of the host that
>>>>>>> libgccjit is currently running on? or how the target was configured
>>>>>>> when libgccjit was built?
>>>>>>
>>>>>> I'm less sure about this part. I'll need to do more tests.
>>>>>>
>>>>>>>
>>>>>>> One of the benefits of libgccjit is that, in theory, we support all
>>>>>>> of
>>>>>>> the targets that GCC already supports.  Does this patch change
>>>>>>> that,
>>>>>>> or
>>>>>>> is this more about giving client code the ability to determine
>>>>>>> capabilities of the specific host being compiled for?
>>>>>>
>>>>>> This should not change that. If it does, this is a bug.
>>>>>>
>>>>>>>
>>>>>>> I'm nervous about having per-target jit code.  Presumably there's a
>>>>>>> reason that we can't reuse existing target logic here - can you
>>>>>>> please
>>>>>>> describe what the problem is.  I see that the ChangeLog has:
>>>>>>>
>>>>>>>>          * config/i386/i386-jit.cc: New file.
>>>>>>>
>>>>>>> where i386-jit.cc has almost 200 lines of nontrivial code.  Where
>>>>>>> did
>>>>>>> this come from?  Did you base it on existing code in our source
>>>>>>> tree,
>>>>>>> making modifications to fit the new internal API, or did you write
>>>>>>> it
>>>>>>> from scratch?  In either case, how onerous would this be for other
>>>>>>> targets?
>>>>>>
>>>>>> This was mostly copied from the same code done for the Rust and D
>>>>>> frontends.
>>>>>> See this commit and the following:
>>>>>> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=b1c06fd9723453dd2b2ec306684cb806dc2b4fbb
>>>>>> The equivalent to i386-jit.cc is there:
>>>>>> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=22e3557e2d52f129f2bbfdc98688b945dba28dc9
>>>>>
>>>>> [CCing Iain and Arthur re those patches; for reference, the patch 
>>>>> being
>>>>> discussed is attached to :
>>>>> https://gcc.gnu.org/pipermail/jit/2024q1/001792.html ]
>>>>>
>>>>> One of my concerns about this patch is that we seem to be gaining code
>>>>> that's per-(frontend x config) which seems to be copied and pasted 
>>>>> with
>>>>> a search and replace, which could lead to an M*N explosion.
>>>>
>>>> I think this is definitely already the case, and it would be worth 
>>>> investigating if C/C++/Rust/jit can reuse a similar set of target 
>>>> files, or how to factor them together. I imagine that all of these 
>>>> components share similar needs for the targets they support.
>>>>
>>>>>
>>>>> Is there any real difference between the per-config code for the
>>>>> different frontends, or should there be a general "enumerate all
>>>>> features of the target" hook that's independent of the frontend? (but
>>>>> perhaps calls into it).
>>>>>
>>>>> Am I right in thinking that (rustc with default LLVM backend) has some
>>>>> set of feature strings that both (rustc with rustc_codegen_gcc) and
>>>>> gccrs are trying to emulate?  If so, is it presumably a goal that
>>>>> libgccjit gives identical results to gccrs?  If so, would it be crazy
>>>>> for libgccjit to consume e.g. config/i386/i386-rust.cc ?
>>>>
>>>> I think this would definitely make sense, and it could probably be 
>>>> extended to other frontends. For the time being I think it makes 
>>>> sense to try it out for gccrs and jit. But finding a fitting name 
>>>> will be hard :)
>>>>
>>>> Best,
>>>>
>>>> Arthur
>>>>
>>>>>
>>>>> Dave
>>>>>
>>>>>>
>>>>>>>
>>>>>>> I'm not at expert at target hooks (or at the i386 backend), so if
>>>>>>> we
>>>>>>> do
>>>>>>> go with this approach I'd want someone else to review those parts
>>>>>>> of
>>>>>>> the patch.
>>>>>>>
>>>>>>> Have you verified that GCC builds with this patch with jit *not*
>>>>>>> enabled in the enabled languages?
>>>>>>
>>>>>> I will do.
>>>>>>
>>>>>>>
>>>>>>> [...snip...]
>>>>>>>
>>>>>>> A nitpick:
>>>>>>>
>>>>>>>> +.. function:: const char * \
>>>>>>>> +              gcc_jit_target_info_arch (gcc_jit_target_info
>>>>>>>> *info)
>>>>>>>> +
>>>>>>>> +   Get the architecture of the currently running CPU.
>>>>>>>
>>>>>>> What does this string look like?
>>>>>>> How long does the pointer remain valid?
>>>>>>
>>>>>> It's the march string, like "znver2", for instance.
>>>>>> It remains valid until we free the gcc_jit_target_info object.
>>>>>>
>>>>>>>
>>>>>>> Thanks again; hope the above makes sense
>>>>>>> Dave
>>>>>>>
>>>>>>
>>>>>

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2024-04-26 13:51 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-09 22:27 [PATCH] libgccjit: Add ability to get CPU features Antoni Boucher
2023-11-09 23:04 ` David Malcolm
2023-11-10  0:33   ` Antoni Boucher
2023-11-30 22:11     ` Antoni Boucher
2024-03-05 15:09     ` Frontend access to target features (was Re: [PATCH] libgccjit: Add ability to get CPU features) David Malcolm
2024-03-10 11:05       ` Iain Buclaw
2024-03-18 11:39         ` Antoni Boucher
2024-03-19 11:03       ` Arthur Cohen
2024-04-01 12:20         ` Antoni Boucher
2024-04-09 13:21           ` Antoni Boucher
2024-04-19 12:34             ` Antoni Boucher
2024-04-26 13:51               ` Antoni Boucher
2023-12-13 19:56   ` [PATCH] libgccjit: Add ability to get CPU features Antoni Boucher
2024-01-10 23:18     ` Antoni Boucher
2024-01-11 18:49   ` Antoni Boucher
2024-01-19 12:53   ` Antoni Boucher
2024-01-20 14:50   ` Antoni Boucher
2024-01-30 15:50     ` Antoni Boucher
2024-02-06 12:54       ` Antoni Boucher
2024-02-13 18:37         ` Antoni Boucher
2024-02-29 15:34           ` Antoni Boucher

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).