From: Antoni Boucher Date: Fri, 21 Mar 2025 17:13:41 +0000 (-0400) Subject: libgccjit: Add ability to get CPU features X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Ftrunk;p=thirdparty%2Fgcc.git 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. * 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. 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 populate_target_info): New class. * jit-recording.cc (recording::context::populate_target_info): New method. * jit-recording.h (recording::context::populate_target_info): New method. (recording::context::m_populated_target_info): New field. * 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_target_dependent_type): 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_target_dependent_type): New functions. * libgccjit.map (LIBGCCJIT_ABI_35): 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_target_dependent_type. * docs/topics/compatibility.rst (LIBGCCJIT_ABI_35): 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. * jit.dg/test-error-target-info.c: New test. --- diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 6a9d6204c869..e36e04a62eab 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -613,6 +613,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@ @@ -917,6 +919,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) @@ -977,11 +980,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) @@ -1297,6 +1302,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@ @@ -2105,6 +2113,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="" \ @@ -2144,6 +2153,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 @@ -2611,6 +2625,12 @@ default-d.o: config/default-d.cc $(COMPILE) $< $(POSTCOMPILE) +# Files used by the JIT language front end. + +default-jit.o: config/default-jit.cc + $(COMPILE) $< + $(POSTCOMPILE) + # Files used by the Rust language front end. default-rust.o: config/default-rust.cc @@ -2963,6 +2983,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 @@ -3160,8 +3189,8 @@ s-gtype: $(EXTRA_GTYPE_DEPS) build/gengtype$(build_exeext) \ -r gtype.state $(STAMP) s-gtype -generated_files = config.h tm.h $(TM_P_H) $(TM_D_H) $(TM_H) multilib.h \ - $(simple_generated_h) specs.h \ +generated_files = config.h tm.h $(TM_P_H) $(TM_D_H) $(TM_JIT_H) $(TM_H) \ + multilib.h $(simple_generated_h) specs.h \ tree-check.h genrtl.h insn-modes.h insn-modes-inline.h \ tm-preds.h tm-constrs.h \ $(ALL_GTFILES_H) gtype-desc.cc gtype-desc.h version.h \ @@ -3172,6 +3201,7 @@ generated_files = config.h tm.h $(TM_P_H) $(TM_D_H) $(TM_H) multilib.h \ c-family/c-target-hooks-def.h d/d-target-hooks-def.h \ $(TM_RUST_H) rust/rust-target-hooks-def.h \ case-cfn-macros.h \ + jit/jit-target-hooks-def.h case-cfn-macros.h \ cfn-operators.pd omp-device-properties.h # @@ -3305,8 +3335,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 9c8f4d05330b..a73bf9578e91 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,9 @@ # # 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 targetjitm. out_file= common_out_file= @@ -226,12 +232,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. @@ -416,6 +424,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" @@ -620,6 +629,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 @@ -3714,6 +3729,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 @@ -6087,6 +6106,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 000000000000..a03308ef6dab --- /dev/null +++ b/gcc/config/default-jit.cc @@ -0,0 +1,30 @@ +/* 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 +. */ + +#define INCLUDE_STRING +#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 000000000000..c1e2929a4735 --- /dev/null +++ b/gcc/config/i386/i386-jit.cc @@ -0,0 +1,71 @@ +/* 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 +. */ + +#define IN_TARGET_CODE 1 + +#define INCLUDE_STRING +#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. */ + +#ifndef CROSS_DIRECTORY_STRUCTURE +extern const char *host_detect_local_cpu (int argc, const char **argv); +#endif + +#if TARGET_64BIT_DEFAULT +const char* x86_bits = "64"; +#else +const char* x86_bits = "32"; +#endif + +void +ix86_jit_register_target_info (void) +{ +#ifndef CROSS_DIRECTORY_STRUCTURE + const char *params[] = {"arch", x86_bits}; + const char* local_cpu = host_detect_local_cpu (2, params); + if (local_cpu) + { + std::string arch = local_cpu; + free (const_cast (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); + } +#endif + + if (targetm.scalar_mode_supported_p (TImode)) + { + jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_UINT128_T); + jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_INT128_T); + } + +#define ADD_TARGET_INFO jit_add_target_info +#include "i386-rust-and-jit.inc" +#undef ADD_TARGET_INFO +} diff --git a/gcc/config/i386/i386-jit.h b/gcc/config/i386/i386-jit.h new file mode 100644 index 000000000000..1d65001476ee --- /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 +. */ + +/* 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 2508f89cd06a..e5fc929c1fec 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/configure b/gcc/configure index 38d8cd919cba..0fb09f430da6 100755 --- a/gcc/configure +++ b/gcc/configure @@ -651,6 +651,7 @@ GMPLIBS target_cpu_default rust_target_objs d_target_objs +jit_target_objs fortran_target_objs cxx_target_objs c_target_objs @@ -662,6 +663,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 @@ -15114,6 +15117,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 19975fa5be5b..684639d4cafd 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -2443,6 +2443,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 @@ -7596,6 +7607,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) @@ -7605,6 +7618,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 0d109391f0b1..6012cd93680d 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -126,6 +126,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 @@ -11396,6 +11404,17 @@ 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}, which takes a key and a value. The +keys added by this hook are made available at compile time by calling +get_target_info. +@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 b28519081587..7fcd2ff99890 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -126,6 +126,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 @@ -7302,6 +7310,12 @@ 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 + @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 b984bee69ea8..529417b50f22 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 59afe264a856..0429137d694d 100644 --- a/gcc/jit/Make-lang.in +++ b/gcc/jit/Make-lang.in @@ -130,7 +130,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 \ @@ -139,13 +139,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 1c4b81bfff1a..19be33eb4b50 100644 --- a/gcc/jit/docs/topics/compatibility.rst +++ b/gcc/jit/docs/topics/compatibility.rst @@ -453,3 +453,16 @@ temporary variable: ``LIBGCCJIT_ABI_34`` covers the addition of * :func:`gcc_jit_context_set_output_ident` + +.. _LIBGCCJIT_ABI_35: + +``LIBGCCJIT_ABI_35`` +-------------------- +``LIBGCCJIT_ABI_35`` covers the addition of functions to query the target +information: + + * :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_target_dependent_type` diff --git a/gcc/jit/docs/topics/compilation.rst b/gcc/jit/docs/topics/compilation.rst index 3d3a9ab4db33..80c80af510d2 100644 --- a/gcc/jit/docs/topics/compilation.rst +++ b/gcc/jit/docs/topics/compilation.rst @@ -199,3 +199,59 @@ 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, e.g. the value of -march + equivalent to -march=native. Ex.: znver3 + + The underlying buffer is only valid until the gcc_jit_target_info is + released. + +.. function:: int \ + gcc_jit_target_info_supports_target_dependent_type (gcc_jit_target_info *info, + enum gcc_jit_types type) + + Check if the specified target INFO supports target-dependent types like + 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_target_dependent_type` + + were added in :ref:`LIBGCCJIT_ABI_35`; 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 4473d8b55521..291ddeb2cca2 100644 --- a/gcc/jit/jit-playback.cc +++ b/gcc/jit/jit-playback.cc @@ -50,6 +50,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" @@ -3605,6 +3606,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 b0625dca71f1..07dab6fa3895 100644 --- a/gcc/jit/jit-playback.h +++ b/gcc/jit/jit-playback.h @@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "varasm.h" #include "jit-recording.h" +#include "jit-target.h" namespace diagnostics { @@ -57,9 +58,10 @@ set_variable_string_attribute ( /* 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::populate_target_info */ class context : public log_user { @@ -326,6 +328,18 @@ public: void add_top_level_asm (const char *asm_stmts); + target_info *get_target_info () + { + return &m_target_info; + } + + target_info *move_target_info () + { + target_info *info = new target_info {std::move (m_target_info)}; + m_target_info = target_info{}; + return info; + } + private: void dump_generated_code (); @@ -429,6 +443,8 @@ private: auto_vec m_source_files; auto_vec > m_cached_locations; + + target_info m_target_info; }; class compile_to_memory : public context @@ -461,6 +477,18 @@ class compile_to_file : public context const char *m_output_path; }; +class populate_target_info : public context +{ + public: + populate_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 8da3cb059156..2f4ecc318251 100644 --- a/gcc/jit/jit-recording.cc +++ b/gcc/jit/jit-recording.cc @@ -1629,6 +1629,13 @@ recording::context::enable_dump (const char *dumpname, result * recording::context::compile () { + if (m_populated_target_info) + { + add_error (NULL, + "cannot compile after calling gcc_jit_context_get_target_info"); + return NULL; + } + JIT_LOG_SCOPE (get_logger ()); log_all_options (); @@ -1659,6 +1666,13 @@ void recording::context::compile_to_file (enum gcc_jit_output_kind output_kind, const char *output_path) { + if (m_populated_target_info) + { + add_error (NULL, + "cannot compile after calling gcc_jit_context_get_target_info"); + return; + } + JIT_LOG_SCOPE (get_logger ()); log_all_options (); @@ -1677,6 +1691,28 @@ recording::context::compile_to_file (enum gcc_jit_output_kind output_kind, replayer.compile (); } +void +recording::context::populate_target_info () +{ + JIT_LOG_SCOPE (get_logger ()); + + log_all_options (); + + if (errors_occurred ()) + return; + + add_driver_option ("-fsyntax-only"); + m_populated_target_info = true; + + /* Set up a populate_target_info playback context. */ + ::gcc::jit::playback::populate_target_info replayer (this); + + /* Use it. */ + replayer.compile (); + + m_target_info = replayer.move_target_info (); +} + /* 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 0ac9245c2df5..4d41faa0446a 100644 --- a/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "jit-common.h" #include "jit-logging.h" +#include "jit-target.h" #include "libgccjit.h" #include @@ -328,6 +329,16 @@ public: compile_to_file (enum gcc_jit_output_kind output_kind, const char *output_path); + void + populate_target_info (); + + target_info *move_target_info () + { + target_info *info = m_target_info; + m_target_info = nullptr; + return info; + } + void add_error (location *loc, const char *fmt, ...) GNU_PRINTF(3, 4); @@ -412,7 +423,11 @@ private: type *m_basic_types[NUM_GCC_JIT_TYPES]; type *m_FILE_type; + bool m_populated_target_info = false; + builtins_manager *m_builtins_manager; // lazily created + + target_info *m_target_info; }; diff --git a/gcc/jit/jit-target-def.h b/gcc/jit/jit-target-def.h new file mode 100644 index 000000000000..dcb342fafe7d --- /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 + . */ + +#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 000000000000..40b47971c44c --- /dev/null +++ b/gcc/jit/jit-target.cc @@ -0,0 +1,96 @@ +/* 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 +. */ + +#define INCLUDE_STRING +#define INCLUDE_ALGORITHM +#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-playback.h" +#include "jit-target.h" + +/* 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 CPU handler can override. */ + targetjitm.jit_register_cpu_target_info (); +} + +/* Add a target info key:value to JIT_TARGET_INFO for use by + target_info::has_target_value (). */ + +void +jit_add_target_info (const char *key, const char *value) +{ + gcc_assert (gcc::jit::active_playback_ctxt != NULL); + target_info* jit_target_info + = gcc::jit::active_playback_ctxt->get_target_info (); + 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) +{ + gcc_assert (gcc::jit::active_playback_ctxt != NULL); + target_info* jit_target_info + = gcc::jit::active_playback_ctxt->get_target_info (); + jit_target_info->m_arch = arch; +} + +void +jit_target_add_supported_target_dependent_type (enum gcc_jit_types type_) +{ + gcc_assert (gcc::jit::active_playback_ctxt != NULL); + target_info* jit_target_info + = gcc::jit::active_playback_ctxt->get_target_info (); + jit_target_info->m_supported_target_dependent_types.insert (type_); +} + +target_info * +jit_get_target_info () +{ + gcc_assert (gcc::jit::active_playback_ctxt != NULL); + target_info* info = gcc::jit::active_playback_ctxt->move_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 000000000000..5e657eb4e137 --- /dev/null +++ b/gcc/jit/jit-target.def @@ -0,0 +1,42 @@ +/* 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 + . */ + +/* 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}, which takes a key and a value. The\n\ +keys added by this hook are made available at compile time by calling\n\ +get_target_info.", + 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 000000000000..626ae8179ff1 --- /dev/null +++ b/gcc/jit/jit-target.h @@ -0,0 +1,75 @@ +/* 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 + . */ + +#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 "libgccjit.h" + +#include +#include + +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, + CStringHash, CStringEqual> + m_info; + std::string m_arch; + std::unordered_set m_supported_target_dependent_types; +}; + +/* 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_add_supported_target_dependent_type (enum gcc_jit_types type_); +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 725a5d53d06f..33369447074b 100644 --- a/gcc/jit/libgccjit.cc +++ b/gcc/jit/libgccjit.cc @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #define INCLUDE_MUTEX +#define INCLUDE_STRING #include "system.h" #include "coretypes.h" #include "timevar.h" @@ -29,6 +30,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 +46,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 { }; @@ -3900,6 +3906,51 @@ gcc_jit_context_set_output_ident (gcc_jit_context *ctxt, ctxt->set_output_ident (output_ident); } +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 ("populate_target_info of ctxt: %p", (void *)ctxt); + + ctxt->populate_target_info (); + + return (gcc_jit_target_info*) ctxt->move_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_VAL_IF_FAIL (info, 0, NULL, NULL, "NULL info"); + RETURN_VAL_IF_FAIL (feature, 0, NULL, NULL, "NULL feature"); + return info->has_target_value ("target_feature", feature); +} + +const char * +gcc_jit_target_info_arch (gcc_jit_target_info *info) +{ + RETURN_NULL_IF_FAIL (info, NULL, NULL, "NULL info"); + return info->m_arch.c_str (); +} + +int +gcc_jit_target_info_supports_target_dependent_type (gcc_jit_target_info *info, + enum gcc_jit_types type) +{ + RETURN_VAL_IF_FAIL (info, 0, NULL, NULL, "NULL info"); + return info->m_supported_target_dependent_types.find (type) + != info->m_supported_target_dependent_types.end (); +} + /* Public entrypoint. See description in libgccjit.h. After error-checking, the real work is done by the diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index bc9fcaee2453..a58551007931 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -57,6 +57,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. @@ -2131,6 +2134,60 @@ gcc_jit_function_add_string_attribute (gcc_jit_function *func, enum gcc_jit_fn_attribute attribute, const char* value); +/* Create a gcc_jit_target_info instance. + + This API entrypoint was added in LIBGCCJIT_ABI_35; 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_35; 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_35; 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_35; 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 the target-dependent type + TYPE. + + This API entrypoint was added in LIBGCCJIT_ABI_35; you can test for its + presence using + #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API +*/ +extern int +gcc_jit_target_info_supports_target_dependent_type (gcc_jit_target_info *info, + enum gcc_jit_types type); + +/* The target info API was added in LIBGCCJIT_ABI_35; you can test for its + presence using + #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API +*/ +#define LIBGCCJIT_HAVE_TARGET_INFO_API + extern void gcc_jit_function_add_integer_array_attribute ( gcc_jit_function *func, diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map index fcb6e6f2a55d..4662ca4b3c02 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -325,3 +325,12 @@ LIBGCCJIT_ABI_34 { global: gcc_jit_context_set_output_ident; } LIBGCCJIT_ABI_33; + +LIBGCCJIT_ABI_35 { + 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_target_dependent_type; +} LIBGCCJIT_ABI_34; diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h index add5619aebd4..4aa18e3b7678 100644 --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h @@ -424,6 +424,9 @@ #undef create_code #undef verify_code +/* test-target-info.c: This can't be in the testcases array as it + is target-specific. */ + /* test-types.c */ #define create_code create_code_types #define verify_code verify_code_types diff --git a/gcc/testsuite/jit.dg/test-error-target-info.c b/gcc/testsuite/jit.dg/test-error-target-info.c new file mode 100644 index 000000000000..a2426458285d --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-target-info.c @@ -0,0 +1,60 @@ +/* { dg-do compile { target x86_64-*-* } } */ + +#include +#include + +#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); + gcc_jit_context_compile (ctxt); + + gcc_jit_target_info_release (info); + + /* Verify that the correct error message was emitted. */ + CHECK_STRING_VALUE (gcc_jit_context_get_last_error (ctxt), + "cannot compile after calling gcc_jit_context_get_target_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; +} 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 000000000000..edae18aa1143 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-target-info.c @@ -0,0 +1,61 @@ +/* { dg-do compile { target x86_64-*-* } } */ + +#include +#include + +#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); + + int supports_128bit_int = + gcc_jit_target_info_supports_target_dependent_type (info, + GCC_JIT_TYPE_INT128_T); + 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; +}