diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 6aed2cda3cafb..4c092094343c4 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -574,6 +574,8 @@ tm_p_file_list=@tm_p_file_list@ tm_p_include_list=@tm_p_include_list@ tm_d_file_list=@tm_d_file_list@ tm_d_include_list=@tm_d_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@ @@ -868,6 +870,7 @@ CONFIG_H = config.h $(host_xm_file_list) TCONFIG_H = tconfig.h $(xm_file_list) TM_P_H = tm_p.h $(tm_p_file_list) TM_D_H = tm_d.h $(tm_d_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) @@ -926,10 +929,12 @@ TARGET_DEF = target.def target-hooks-macros.h target-insns.def 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 +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) +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) @@ -1230,6 +1235,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@ @@ -1947,6 +1955,7 @@ tconfig.h: cs-tconfig.h ; @true tm.h: cs-tm.h ; @true tm_p.h: cs-tm_p.h ; @true tm_d.h: cs-tm_d.h ; @true +tm_jit.h: cs-tm_jit.h ; @true cs-config.h: Makefile TARGET_CPU_DEFAULT="" \ @@ -1978,6 +1987,11 @@ cs-tm_d.h: Makefile HEADERS="$(tm_d_include_list)" DEFINES="" \ $(SHELL) $(srcdir)/mkconfig.sh tm_d.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 @@ -2619,6 +2633,15 @@ s-d-target-hooks-def-h: build/genhooks$(build_exeext) d/d-target-hooks-def.h $(STAMP) s-d-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 @@ -2794,7 +2817,7 @@ 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 \ +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 \ @@ -2803,7 +2826,7 @@ generated_files = config.h tm.h $(TM_P_H) $(TM_D_H) $(TM_H) multilib.h \ common/common-target-hooks-def.h pass-instances.def \ gimple-match.cc generic-match.cc \ c-family/c-target-hooks-def.h d/d-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 # @@ -2937,7 +2960,7 @@ 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) $(BCONFIG_H) $(SYSTEM_H) errors.h + $(COMMON_TARGET_DEF) $(D_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) \ diff --git a/gcc/config.gcc b/gcc/config.gcc index c4633e869ac06..6a0fc540bcba9 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -146,6 +146,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. # @@ -201,6 +204,9 @@ # # target_has_targetdm Set to yes or no depending on whether the target # has its own definition of targetdm. +# +# target_has_targetjitm Set to yes or no depending on whether the target +# has its own definition of targetdm. out_file= common_out_file= @@ -217,10 +223,12 @@ extra_options= c_target_objs= cxx_target_objs= d_target_objs= +jit_target_objs= fortran_target_objs= target_has_targetcm=no target_has_targetm_common=yes target_has_targetdm=no +target_has_targetjitm=no tm_defines= xm_defines= # Set this to force installation and use of collect2. @@ -338,6 +346,7 @@ aarch64*-*-*) c_target_objs="aarch64-c.o" cxx_target_objs="aarch64-c.o" d_target_objs="aarch64-d.o" + #jit_target_objs="aarch64-jit.o" extra_objs="aarch64-builtins.o aarch-common.o aarch64-sve-builtins.o aarch64-sve-builtins-shapes.o aarch64-sve-builtins-base.o aarch64-sve-builtins-sve2.o cortex-a57-fma-steering.o aarch64-speculation.o falkor-tag-collision-avoidance.o aarch64-bti-insert.o aarch64-cc-fusion.o" target_gtfiles="\$(srcdir)/config/aarch64/aarch64-builtins.cc \$(srcdir)/config/aarch64/aarch64-sve-builtins.h \$(srcdir)/config/aarch64/aarch64-sve-builtins.cc" target_has_targetm_common=yes @@ -368,6 +377,7 @@ arm*-*-*) c_target_objs="arm-c.o" cxx_target_objs="arm-c.o" d_target_objs="arm-d.o" + #jit_target_objs="arm-jit.o" extra_options="${extra_options} arm/arm-tables.opt" target_gtfiles="\$(srcdir)/config/arm/arm-builtins.cc \$(srcdir)/config/arm/arm-mve-builtins.h \$(srcdir)/config/arm/arm-mve-builtins.cc" ;; @@ -401,6 +411,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" @@ -462,6 +473,7 @@ microblaze*-*-*) mips*-*-*) cpu_type=mips d_target_objs="mips-d.o" + #jit_target_objs="mips-jit.o" extra_headers="loongson.h loongson-mmiintrin.h msa.h" extra_objs="frame-header-opt.o" extra_options="${extra_options} g.opt fused-madd.opt mips/mips-tables.opt" @@ -532,6 +544,7 @@ riscv*) extra_objs="riscv-builtins.o riscv-c.o riscv-sr.o riscv-shorten-memrefs.o riscv-selftests.o riscv-v.o riscv-vsetvl.o" extra_objs="${extra_objs} riscv-vector-builtins.o riscv-vector-builtins-shapes.o riscv-vector-builtins-bases.o" d_target_objs="riscv-d.o" + #jit_target_objs="riscv-jit.o" extra_headers="riscv_vector.h" target_gtfiles="$target_gtfiles \$(srcdir)/config/riscv/riscv-vector-builtins.cc" target_gtfiles="$target_gtfiles \$(srcdir)/config/riscv/riscv-vector-builtins.h" @@ -548,11 +561,13 @@ sparc*-*-*) c_target_objs="sparc-c.o" cxx_target_objs="sparc-c.o" d_target_objs="sparc-d.o" + #jit_target_objs="sparc-jit.o" extra_headers="visintrin.h" ;; s390*-*-*) cpu_type=s390 d_target_objs="s390-d.o" + #jit_target_objs="s390-jit.o" extra_options="${extra_options} fused-madd.opt" extra_headers="s390intrin.h htmintrin.h htmxlintrin.h vecintrin.h" ;; @@ -588,6 +603,12 @@ then tm_d_file="${tm_d_file} ${cpu_type}/${cpu_type}-d.h" 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 @@ -754,9 +775,11 @@ case ${target} in c_target_objs="${c_target_objs} darwin-c.o" cxx_target_objs="${cxx_target_objs} darwin-c.o" d_target_objs="${d_target_objs} darwin-d.o" + #jit_target_objs="${jit_target_objs} darwin-jit.o" fortran_target_objs="darwin-f.o" target_has_targetcm=yes target_has_targetdm=yes + #target_has_targetjitm=yes extra_objs="${extra_objs} darwin.o" extra_gcc_objs="darwin-driver.o" default_use_cxa_atexit=yes @@ -785,8 +808,10 @@ case ${target} in default_use_cxa_atexit=yes use_gcc_stdint=wrap d_target_objs="${d_target_objs} dragonfly-d.o" + #jit_target_objs="${jit_target_objs} dragonfly-jit.o" tmake_file="${tmake_file} t-dragonfly" target_has_targetdm=yes + #target_has_targetjitm=yes ;; *-*-freebsd*) # This is the generic ELF configuration of FreeBSD. Later @@ -836,8 +861,10 @@ case ${target} in esac use_gcc_stdint=wrap d_target_objs="${d_target_objs} freebsd-d.o" + #jit_target_objs="${jit_target_objs} freebsd-jit.o" tmake_file="${tmake_file} t-freebsd" target_has_targetdm=yes + #target_has_targetjitm=yes ;; *-*-fuchsia*) native_system_header_dir=/include @@ -910,19 +937,27 @@ 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 + target_has_targetjitm=yes ;; *-*-kfreebsd*-gnu) d_target_objs="${d_target_objs} kfreebsd-d.o" + #jit_target_objs="${jit_target_objs} kfreebsd-jit.o" target_has_targetdm=yes + #target_has_targetjitm=yes ;; *-*-kopensolaris*-gnu) d_target_objs="${d_target_objs} kopensolaris-d.o" + #jit_target_objs="${jit_target_objs} kopensolaris-jit.o" target_has_targetdm=yes + #target_has_targetjitm=yes ;; *-*-gnu*) d_target_objs="${d_target_objs} gnu-d.o" + #jit_target_objs="${jit_target_objs} gnu-jit.o" target_has_targetdm=yes + #target_has_targetjitm=yes ;; esac ;; @@ -931,6 +966,7 @@ case ${target} in tmake_file="t-netbsd t-slibgcc" extra_objs="${extra_objs} netbsd.o" d_target_objs="${d_target_objs} netbsd-d.o" + #jit_target_objs="${jit_target_objs} netbsd-jit.o" gas=yes gnu_ld=yes use_gcc_stdint=wrap @@ -940,6 +976,7 @@ case ${target} in nbsd_tm_file="netbsd.h netbsd-stdint.h netbsd-elf.h" default_use_cxa_atexit=yes target_has_targetdm=yes + #target_has_targetjitm=yes case ${target} in arm*-* | i[34567]86-* | powerpc*-* | sparc*-* | x86_64-*) default_gnu_indirect_function=yes @@ -959,7 +996,9 @@ case ${target} in ;; esac d_target_objs="${d_target_objs} openbsd-d.o" + #jit_target_objs="${jit_target_objs} openbsd-jit.o" target_has_targetdm=yes + #target_has_targetjitm=yes ;; *-*-phoenix*) gas=yes @@ -1016,6 +1055,7 @@ case ${target} in c_target_objs="${c_target_objs} sol2-c.o" cxx_target_objs="${cxx_target_objs} sol2-c.o sol2-cxx.o" d_target_objs="${d_target_objs} sol2-d.o" + #jit_target_objs="${jit_target_objs} sol2-jit.o" extra_objs="${extra_objs} sol2.o sol2-stubs.o" extra_options="${extra_options} sol2.opt" case ${enable_threads}:${have_pthread_h}:${have_thread_h} in @@ -1024,6 +1064,7 @@ case ${target} in ;; esac target_has_targetdm=yes + #target_has_targetjitm=yes ;; *-*-*vms*) extra_options="${extra_options} vms/vms.opt" @@ -1760,6 +1801,7 @@ hppa*64*-*-linux*) pa/pa64-linux.h" tmake_file="${tmake_file} pa/t-pa pa/t-linux" d_target_objs="${d_target_objs} pa-d.o" + #jit_target_objs="${jit_target_objs} pa-jit.o" gas=yes gnu_ld=yes ;; hppa*-*-linux*) @@ -1768,6 +1810,7 @@ hppa*-*-linux*) pa/pa32-regs.h pa/pa32-linux.h" tmake_file="${tmake_file} pa/t-pa pa/t-linux" d_target_objs="${d_target_objs} pa-d.o" + #jit_target_objs="${jit_target_objs} pa-jit.o" ;; hppa*-*-openbsd*) target_cpu_default="MASK_PA_11" @@ -1776,6 +1819,7 @@ hppa*-*-openbsd*) extra_options="${extra_options} openbsd.opt" tmake_file="pa/t-pa" d_target_objs="${d_target_objs} pa-d.o" + #jit_target_objs="${jit_target_objs} pa-jit.o" gas=yes gnu_ld=yes ;; @@ -1813,6 +1857,7 @@ hppa*64*-*-hpux11*) pa/pa-hpux1010.opt pa/pa64-hpux.opt hpux11.opt" tmake_file="pa/t-pa t-slibgcc" d_target_objs="${d_target_objs} pa-d.o" + #jit_target_objs="${jit_target_objs} pa-jit.o" case x${enable_threads} in x | xyes | xposix ) thread_file=posix @@ -2086,7 +2131,9 @@ i[34567]86-*-cygwin*) c_target_objs="${c_target_objs} msformat-c.o" cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o" d_target_objs="${d_target_objs} cygwin-d.o" + #jit_target_objs="${jit_target_objs} cygwin-jit.o" target_has_targetdm="yes" + #target_has_targetjitm=yes if test x$enable_threads = xyes; then thread_file='posix' fi @@ -2104,7 +2151,9 @@ x86_64-*-cygwin*) c_target_objs="${c_target_objs} msformat-c.o" cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o" d_target_objs="${d_target_objs} cygwin-d.o" + #jit_target_objs="${jit_target_objs} cygwin-jit.o" target_has_targetdm="yes" + #target_has_targetjitm=yes if test x$enable_threads = xyes; then thread_file='posix' fi @@ -2118,8 +2167,10 @@ i[34567]86-*-mingw* | x86_64-*-mingw*) c_target_objs="${c_target_objs} winnt-c.o" cxx_target_objs="${cxx_target_objs} winnt-c.o" d_target_objs="${d_target_objs} winnt-d.o" + #jit_target_objs="${jit_target_objs} winnt-jit.o" target_has_targetcm="yes" target_has_targetdm="yes" + #target_has_targetjitm=yes case ${target} in x86_64-*-* | *-w64-*) need_64bit_isa=yes @@ -3582,6 +3633,10 @@ if [ "$target_has_targetdm" = "no" ]; then d_target_objs="$d_target_objs default-d.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 @@ -5752,6 +5807,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 0000000000000..6bee98a79ce27 --- /dev/null +++ b/gcc/config/default-jit.cc @@ -0,0 +1,28 @@ +/* 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 +. */ + +#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_targetdm targetjitm = TARGETJITM_INITIALIZER; diff --git a/gcc/config/i386/i386-jit.cc b/gcc/config/i386/i386-jit.cc new file mode 100644 index 0000000000000..3014baefc30b6 --- /dev/null +++ b/gcc/config/i386/i386-jit.cc @@ -0,0 +1,216 @@ +/* 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 + +#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_CPU_VERSIONS for x86 targets. */ + +void +ix86_jit_target_versions (void) +{ + if (TARGET_64BIT) + { + jit_add_target_info ("target_arch", "x86_64"); + + // TODO + /*if (TARGET_X32) + jit_add_target_info ("target_arch", "D_X32");*/ + } + else + jit_add_target_info ("target_arch", "x86"); +} + +/* 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 *arch = host_detect_local_cpu (2, params); + + const char* arg = "-march="; + const char* arg_pos = strstr(arch, arg); + const char* arg_value = arg_pos + strlen(arg); + const char* arg_value_end = strchr(arg_value, ' '); + + size_t len = arg_value_end - arg_value; + char *cpu = new char[len]; + strncpy(cpu, arg_value, len); + cpu[len] = '\0'; + jit_target_set_arch (cpu); + + jit_target_set_128bit_int_support (targetm.scalar_mode_supported_p (TImode)); + + free (const_cast (arch)); + + 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"); + + // this is only enabled by choice in llvm, never by default - TODO determine if gcc enables it + // jit_add_target_info("target_feature", "sse-unaligned-mem"); + + 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_SAHF) // would this be better as TARGET_USE_SAHF? + jit_add_target_info("target_feature", "sahf"); + 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 0000000000000..8cfccba405f4c --- /dev/null +++ b/gcc/config/i386/i386-jit.h @@ -0,0 +1,26 @@ +/* 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_target_versions (void); +extern void ix86_jit_register_target_info (void); +extern bool ix86_jit_has_stdcall_convention (unsigned int *, unsigned int *); + +/* Target hooks for jit language. */ +#define TARGET_JIT_CPU_VERSIONS ix86_jit_target_versions +#define TARGET_JIT_REGISTER_CPU_TARGET_INFO ix86_jit_register_target_info +#define TARGET_JIT_HAS_STDCALL_CONVENTION ix86_jit_has_stdcall_convention diff --git a/gcc/config/i386/t-i386 b/gcc/config/i386/t-i386 index ffdbbdfe8cefb..8421b4dba429a 100644 --- a/gcc/config/i386/t-i386 +++ b/gcc/config/i386/t-i386 @@ -46,6 +46,10 @@ i386-d.o: $(srcdir)/config/i386/i386-d.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 0000000000000..20f0d8b4c6567 --- /dev/null +++ b/gcc/config/linux-jit.cc @@ -0,0 +1,48 @@ +/* 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 +. */ + +#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" + +// TODO: remove this hook? +/* Implement TARGET_JIT_OS_VERSIONS for Linux targets. */ + +static void +linux_jit_os_builtins (void) +{ +} + +// TODO: remove this hook? +/* Implement TARGET_JIT_REGISTER_OS_TARGET_INFO for Linux targets. */ + +static void +linux_jit_register_target_info (void) +{ +} + +#undef TARGET_JIT_OS_VERSIONS +#define TARGET_JIT_OS_VERSIONS linux_jit_os_builtins + +#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 03966d5ce968c..0be3fb24404d0 100644 --- a/gcc/config/t-linux +++ b/gcc/config/t-linux @@ -23,3 +23,7 @@ linux.o: $(srcdir)/config/linux.cc linux-d.o: $(srcdir)/config/linux-d.cc $(COMPILE) $< $(POSTCOMPILE) + +linux-jit.o: $(srcdir)/config/linux-jit.cc + $(COMPILE) $< + $(POSTCOMPILE) diff --git a/gcc/configure b/gcc/configure index 254f9b6c9430d..dbbc21381d487 100755 --- a/gcc/configure +++ b/gcc/configure @@ -645,6 +645,7 @@ GMPINC GMPLIBS target_cpu_default d_target_objs +jit_target_objs fortran_target_objs cxx_target_objs c_target_objs @@ -654,6 +655,8 @@ xm_include_list xm_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 @@ -13506,6 +13509,17 @@ for f in $tm_d_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 62bc908b991ff..0513895f7d976 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -2371,6 +2371,17 @@ for f in $tm_d_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 @@ -7328,6 +7339,8 @@ AC_SUBST(tm_p_file_list) AC_SUBST(tm_p_include_list) AC_SUBST(tm_d_file_list) AC_SUBST(tm_d_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) @@ -7336,6 +7349,7 @@ AC_SUBST(c_target_objs) AC_SUBST(cxx_target_objs) AC_SUBST(fortran_target_objs) AC_SUBST(d_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 8fe49c2ba3dbb..f6f39b079a879 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -115,6 +115,14 @@ initialize @code{targetdm} themselves, they should set @code{target_has_targetdm=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 @@ -10902,6 +10910,36 @@ if they have external linkage. If this flag is false, then instantiated decls will be emitted as weak symbols. The default is @code{false}. @end deftypevr +@node JIT Language and ABI +@section JIT ABI parameters +@cindex parameters, jit abi + +@deftypefn {JIT Target Hook} void TARGET_JIT_CPU_VERSIONS (void) +Declare all environmental version identifiers relating to the target CPU +using the function @code{builtin_version}, which takes a string representing +the name of the version. Version identifiers predefined by this hook apply +to all modules that are being compiled and imported. +@end deftypefn + +@deftypefn {JIT Target Hook} void TARGET_JIT_OS_VERSIONS (void) +Similarly to @code{TARGET_JIT_CPU_VERSIONS}, but is used for versions +relating to the target operating system. +@end deftypefn + +@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 62c49ac46de69..b7da440f817a9 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -115,6 +115,14 @@ initialize @code{targetdm} themselves, they should set @code{target_has_targetdm=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 @@ -7127,6 +7135,18 @@ floating-point support; they are not included in this mechanism. @hook TARGET_D_TEMPLATES_ALWAYS_COMDAT +@node JIT Language and ABI +@section JIT ABI parameters +@cindex parameters, jit abi + +@hook TARGET_JIT_CPU_VERSIONS + +@hook TARGET_JIT_OS_VERSIONS + +@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 8bcf99292073b..0d4b13b7a71fc 100644 --- a/gcc/genhooks.cc +++ b/gcc/genhooks.cc @@ -35,6 +35,7 @@ static struct hook_desc hook_array[] = { #include "c-family/c-target.def" #include "common/common-target.def" #include "d/d-target.def" +#include "jit/jit-target.def" #undef DEFHOOK }; diff --git a/gcc/jit/Make-lang.in b/gcc/jit/Make-lang.in index 248ec45b72953..cca0980b42325 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/jit-playback.cc b/gcc/jit/jit-playback.cc index 7a2d3dd091150..0cfa119ed7417 100644 --- a/gcc/jit/jit-playback.cc +++ b/gcc/jit/jit-playback.cc @@ -47,6 +47,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" @@ -3609,6 +3610,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 b767fec6da884..d153f4945d8c2 100644 --- a/gcc/jit/jit-playback.h +++ b/gcc/jit/jit-playback.h @@ -48,9 +48,10 @@ set_variable_attribute(const std::vector. */ + +#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 0000000000000..ad41376fa7fc8 --- /dev/null +++ b/gcc/jit/jit-target.cc @@ -0,0 +1,94 @@ +/* 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 +. */ + +#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 + +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 (const char* 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::~target_info() +{ + free (const_cast ((const void *) m_arch)); +} + +target_info * +jit_get_target_info () +{ + target_info *info = new target_info {std::move(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 0000000000000..92648ac25d8cf --- /dev/null +++ b/gcc/jit/jit-target.def @@ -0,0 +1,70 @@ +/* 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_" + +/* Environmental version identifiers relating to the target CPU. */ +DEFHOOK +(jit_cpu_versions, + "Declare all environmental version identifiers relating to the target CPU\n\ +using the function @code{builtin_version}, which takes a string representing\n\ +the name of the version. Version identifiers predefined by this hook apply\n\ +to all modules that are being compiled and imported.", + void, (void), + hook_void_void) + +/* Environmental version identifiers relating to the target OS. */ +DEFHOOK +(jit_os_versions, + "Similarly to @code{TARGET_JIT_CPU_VERSIONS}, but is used for versions\n\ +relating to the target operating system.", + void, (void), + hook_void_void) + +/* 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 keys\n\ +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 0000000000000..09fd7941c2ef1 --- /dev/null +++ b/gcc/jit/jit-target.h @@ -0,0 +1,70 @@ +/* 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 +#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: + ~target_info(); + + bool has_target_value (const char *key, const char *value); + + std::unordered_map, CStringHash, CStringEqual> m_info; + const char *m_arch = nullptr; + 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 (const char* 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 bbf9423193065..f8cdfc4a91066 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 { }; @@ -3849,6 +3854,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; +} + +bool +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; +} + +bool +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 67d1355fff23b..057e4779f61c0 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. @@ -2071,6 +2074,22 @@ 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); +extern gcc_jit_target_info * +gcc_jit_context_get_target_info (gcc_jit_context *ctxt); + +extern void +gcc_jit_target_info_release (gcc_jit_target_info *info); + +extern bool +gcc_jit_target_info_cpu_supports (gcc_jit_target_info *info, + const char *feature); + +extern const char * +gcc_jit_target_info_arch (gcc_jit_target_info *info); + +extern bool +gcc_jit_target_info_supports_128bit_int (gcc_jit_target_info *info); + /* Given type "T", get type "T __attribute__ ((packed))". */ extern void gcc_jit_type_set_packed (gcc_jit_type *type); diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map index a10a85ceaceaf..e52de0057a50b 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -317,3 +317,12 @@ LIBGCCJIT_ABI_32 { gcc_jit_context_new_vector_access; gcc_jit_set_global_personality_function_name; } LIBGCCJIT_ABI_31; + +LIBGCCJIT_ABI_33 { + 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_32;