public inbox for jit@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] libgccjit: Add support for machine-dependent builtins
@ 2023-02-12  0:30 Antoni Boucher
  2023-02-12  0:32 ` Antoni Boucher
  2023-02-12  1:37 ` Andrew Pinski
  0 siblings, 2 replies; 12+ messages in thread
From: Antoni Boucher @ 2023-02-12  0:30 UTC (permalink / raw)
  To: jit, gcc-patches; +Cc: David Malcolm

Hi.
This patch adds support for machine-dependent builtins in libgccjit
(bug 108762).

There are two things I don't like in this patch:

 1. There are a few functions copied from the C frontend
(common_mark_addressable_vec and a few others).

 2. Getting a target builtin only works from the second compilation
since the type information is recorded at the first compilation. I
couldn't find a way to get the builtin data without using the langhook.
It is necessary to get the type information for type checking and
instrospection.

Any idea how to fix these issues?

Thanks for the review.

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

* Re: [PATCH] libgccjit: Add support for machine-dependent builtins
  2023-02-12  0:30 [PATCH] libgccjit: Add support for machine-dependent builtins Antoni Boucher
@ 2023-02-12  0:32 ` Antoni Boucher
  2023-02-12  1:37 ` Andrew Pinski
  1 sibling, 0 replies; 12+ messages in thread
From: Antoni Boucher @ 2023-02-12  0:32 UTC (permalink / raw)
  To: jit, gcc-patches; +Cc: David Malcolm

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

I forgot to attach the patch.
Here it is.

On Sat, 2023-02-11 at 19:30 -0500, Antoni Boucher via Jit wrote:
> Hi.
> This patch adds support for machine-dependent builtins in libgccjit
> (bug 108762).
> 
> There are two things I don't like in this patch:
> 
>  1. There are a few functions copied from the C frontend
> (common_mark_addressable_vec and a few others).
> 
>  2. Getting a target builtin only works from the second compilation
> since the type information is recorded at the first compilation. I
> couldn't find a way to get the builtin data without using the
> langhook.
> It is necessary to get the type information for type checking and
> instrospection.
> 
> Any idea how to fix these issues?
> 
> Thanks for the review.


[-- Attachment #2: 0001-libgccjit-Add-support-for-machine-dependent-builtins.patch --]
[-- Type: text/x-patch, Size: 60738 bytes --]

From f1f4a113853b416776253b596d7feeb87e608bfd Mon Sep 17 00:00:00 2001
From: Antoni Boucher <bouanto@zoho.com>
Date: Mon, 23 Jan 2023 17:21:15 -0500
Subject: [PATCH] libgccjit: Add support for machine-dependent builtins

gcc/config:
	PR jit/108762
	* i386/i386-builtins.cc: New function (clear_builtin_types).

gcc/jit:
	PR jit/108762
	* docs/topics/compatibility.rst (LIBGCCJIT_ABI_25): New ABI tag.
	* docs/topics/expressions.rst: Add documentation for the
	functions gcc_jit_context_new_rvalue_vector_perm and
	gcc_jit_context_new_vector_access.
	* docs/topics/functions.rst: Add documentation for the function
	gcc_jit_context_get_target_builtin_function.
	* docs/topics/types.rst: Add documentation for GCC_JIT_TYPE_BFLOAT16.
	* dummy-frontend.cc: Include headers target.h, jit-recording.h,
	print-tree.h, unordered_map and string, new variables (target_builtins,
	target_function_types, and target_builtins_ctxt), new function
	(tree_type_to_jit_type).
	* jit-builtins.cc: Specify that the function types are not from
	target builtins.
	* jit-playback.cc: New argument is_target_builtin to new_function, new
	functions (new_rvalue_vector_perm, common_mark_addressable_vec,
	gnu_vector_type_p, lvalue_p, convert_vector_to_array_for_subscript,
	new_vector_access).
	* jit-playback.h: New argument is_target_builtin to
	new_function, new functions (new_rvalue_vector_perm,
	new_vector_access).
	* jit-recording.cc: New argument is_target_builtin to
	new_function_type, function_type constructor and function
	constructor, new functions
	(get_target_builtin_function, new_rvalue_vector_perm,
	new_vector_access, memento_of_new_rvalue_vector_perm,
	memento_of_new_rvalue_vector_perm::replay_into,
	memento_of_new_rvalue_vector_perm::visit_children,
	memento_of_new_rvalue_vector_perm::make_debug_string,
	memento_of_new_rvalue_vector_perm::write_reproducer,
	vector_access::replay_into, vector_access::visit_children,
	vector_access::make_debug_string, vector_access::write_reproducer).
	* jit-recording.h: Include headers string and unordered_map, new
	variable target_function_types, new argument is_target_builtin
	to new_function_type, function_type and function, new classes
	memento_of_new_rvalue_vector_perm and vector_access, new functions
	(get_target_builtin_function, new_rvalue_vector_perm,
	new_vector_access, copy, memento_of_new_rvalue_vector_perm,
	memento_of_new_rvalue_vector_perm::replay_into,
	memento_of_new_rvalue_vector_perm::visit_children,
	memento_of_new_rvalue_vector_perm::make_debug_string,
	memento_of_new_rvalue_vector_perm::write_reproducer,
	vector_access::replay_into, vector_access::visit_children,
	vector_access::make_debug_string, vector_access::write_reproducer).
	* libgccjit.cc: New functions
	(gcc_jit_context_get_target_builtin_function,
	gcc_jit_context_new_vector_access,
	gcc_jit_context_new_rvalue_vector_perm).
	* libgccjit.h: New variant GCC_JIT_TYPE_BFLOAT16 en enum
	gcc_jit_types, new functions
	(gcc_jit_context_get_target_builtin_function,
	gcc_jit_context_new_vector_access,
	gcc_jit_context_new_rvalue_vector_perm).
	* libgccjit.map: New functions
	(gcc_jit_context_get_target_builtin_function,
	gcc_jit_context_new_rvalue_vector_perm,
	gcc_jit_context_new_vector_access).

gcc/testsuite:
	PR jit/108762
	* jit.dg/all-non-failing-tests.h: New test test-target-builtins.c.
	* jit.dg/test-target-builtins.c: New test.
---
 gcc/config/i386/i386-builtins.cc             |  18 ++
 gcc/jit/docs/topics/compatibility.rst        |  10 +
 gcc/jit/docs/topics/expressions.rst          |  45 ++++
 gcc/jit/docs/topics/functions.rst            |  19 ++
 gcc/jit/docs/topics/types.rst                |   2 +
 gcc/jit/dummy-frontend.cc                    | 203 ++++++++++++++-
 gcc/jit/jit-builtins.cc                      |   6 +-
 gcc/jit/jit-common.h                         |   2 +-
 gcc/jit/jit-playback.cc                      | 166 +++++++++++-
 gcc/jit/jit-playback.h                       |  16 +-
 gcc/jit/jit-recording.cc                     | 255 ++++++++++++++++++-
 gcc/jit/jit-recording.h                      | 176 ++++++++++++-
 gcc/jit/libgccjit.cc                         | 127 +++++++++
 gcc/jit/libgccjit.h                          |  44 +++-
 gcc/jit/libgccjit.map                        |   7 +
 gcc/testsuite/jit.dg/all-non-failing-tests.h |   3 +
 gcc/testsuite/jit.dg/test-target-builtins.c  |  77 ++++++
 17 files changed, 1153 insertions(+), 23 deletions(-)
 create mode 100644 gcc/testsuite/jit.dg/test-target-builtins.c

diff --git a/gcc/config/i386/i386-builtins.cc b/gcc/config/i386/i386-builtins.cc
index fc0c82b156e..f9b9937a669 100644
--- a/gcc/config/i386/i386-builtins.cc
+++ b/gcc/config/i386/i386-builtins.cc
@@ -226,6 +226,22 @@ static GTY(()) tree ix86_builtins[(int) IX86_BUILTIN_MAX];
 
 struct builtin_isa ix86_builtins_isa[(int) IX86_BUILTIN_MAX];
 
+static void
+clear_builtin_types (void)
+{
+  for (int i = 0 ; i < IX86_BT_LAST_CPTR + 1 ; i++)
+    ix86_builtin_type_tab[i] = NULL;
+
+  for (int i = 0 ; i < IX86_BUILTIN_MAX ; i++)
+  {
+    ix86_builtins[i] = NULL;
+    ix86_builtins_isa[i].set_and_not_built_p = true;
+  }
+
+  for (int i = 0 ; i < IX86_BT_LAST_ALIAS + 1 ; i++)
+    ix86_builtin_func_type_tab[i] = NULL;
+}
+
 tree get_ix86_builtin (enum ix86_builtins c)
 {
   return ix86_builtins[c];
@@ -1443,6 +1459,8 @@ ix86_init_builtins (void)
 {
   tree ftype, decl;
 
+  clear_builtin_types ();
+
   ix86_init_builtin_types ();
 
   /* Builtins to get CPU type and features. */
diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst
index f4ffa07ec48..402df5b60b7 100644
--- a/gcc/jit/docs/topics/compatibility.rst
+++ b/gcc/jit/docs/topics/compatibility.rst
@@ -371,3 +371,13 @@ alignment of a variable:
 
   * :func:`gcc_jit_lvalue_set_alignment`
   * :func:`gcc_jit_lvalue_get_alignment`
+
+.. _LIBGCCJIT_ABI_25:
+
+``LIBGCCJIT_ABI_25``
+--------------------
+``LIBGCCJIT_ABI_25`` covers the addition of functions to get target builtins and manipulate vectors:
+
+  * :func:`gcc_jit_context_get_target_builtin_function`
+  * :func:`gcc_jit_context_new_rvalue_vector_perm`
+  * :func:`gcc_jit_context_new_vector_access`
diff --git a/gcc/jit/docs/topics/expressions.rst b/gcc/jit/docs/topics/expressions.rst
index 42cfee36302..57905959634 100644
--- a/gcc/jit/docs/topics/expressions.rst
+++ b/gcc/jit/docs/topics/expressions.rst
@@ -295,6 +295,35 @@ Vector expressions
 
       #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_rvalue_from_vector
 
+.. function:: gcc_jit_rvalue * \
+              gcc_jit_context_new_rvalue_vector_perm (gcc_jit_context *ctxt, \
+                                                      gcc_jit_location *loc, \
+                                                      gcc_jit_rvalue *elements1, \
+                                                      gcc_jit_rvalue *elements2, \
+                                                      gcc_jit_rvalue *mask);
+
+   Build a permutation of two vectors.
+
+   "elements1" and "elements2" should have the same type.
+   The length of "mask" and "elements1" should be the same.
+   The element type of "mask" should be integral.
+   The size of the element type of "mask" and "elements1" should be the same.
+
+   This entrypoint was added in :ref:`LIBGCCJIT_ABI_25`; you can test for
+   its presence using
+
+   .. code-block:: c
+
+      #ifdef LIBGCCJIT_HAVE_TARGET_BUILTIN
+
+    Analogous to:
+
+    .. code-block:: c
+
+       __builtin_shuffle (elements1, elements2, mask)
+
+    in C.
+
 Unary Operations
 ****************
 
@@ -1020,3 +1049,19 @@ Field access is provided separately for both lvalues and rvalues.
       PTR[INDEX]
 
    in C (or, indeed, to ``PTR + INDEX``).
+
+.. function:: gcc_jit_lvalue *\
+              gcc_jit_context_new_vector_access (gcc_jit_context *ctxt,\
+                                                 gcc_jit_location *loc,\
+                                                 gcc_jit_rvalue *vector,\
+                                                 gcc_jit_rvalue *index)
+
+   Given an rvalue of vector type ``T __attribute__ ((__vector_size__ (SIZE)))``, get the element `T` at
+   the given index.
+   Analogous to:
+
+   .. code-block:: c
+
+      VECTOR[INDEX]
+
+   in C.
diff --git a/gcc/jit/docs/topics/functions.rst b/gcc/jit/docs/topics/functions.rst
index cf5cb716daf..e9b77fdb892 100644
--- a/gcc/jit/docs/topics/functions.rst
+++ b/gcc/jit/docs/topics/functions.rst
@@ -140,6 +140,25 @@ Functions
       uses such a parameter will lead to an error being emitted within
       the context.
 
+.. function::  gcc_jit_function *\
+               gcc_jit_context_get_target_builtin_function (gcc_jit_context *ctxt,\
+                                                            const char *name)
+
+   Get the :type:`gcc_jit_function` for the built-in function with the
+   given name.  For example:
+
+   .. code-block:: c
+
+      gcc_jit_function *fn
+        = gcc_jit_context_get_target_builtin_function (ctxt, "__builtin_ia32_pmuldq512_mask");
+
+   .. note:: Due to technical limitations with how libgccjit interacts with
+      the insides of GCC, not all built-in functions are supported.  More
+      precisely, not all types are supported for parameters of built-in
+      functions from libgccjit.  Attempts to get a built-in function that
+      uses such a parameter will lead to an error being emitted within
+      the context.
+
 .. function::  gcc_jit_object *\
                gcc_jit_function_as_object (gcc_jit_function *func)
 
diff --git a/gcc/jit/docs/topics/types.rst b/gcc/jit/docs/topics/types.rst
index f5f2aac1f0c..e7db00779cc 100644
--- a/gcc/jit/docs/topics/types.rst
+++ b/gcc/jit/docs/topics/types.rst
@@ -129,6 +129,8 @@ Standard types
        - C99's ``_Complex double``
      * - :c:data:`GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE`
        - C99's ``_Complex long double``
+     * - :c:data:`GCC_JIT_TYPE_BFLOAT16`
+       -
 
 .. function:: gcc_jit_type *\
               gcc_jit_context_get_int_type (gcc_jit_context *ctxt, \
diff --git a/gcc/jit/dummy-frontend.cc b/gcc/jit/dummy-frontend.cc
index 8b7294e32cc..cf7ef66d5b8 100644
--- a/gcc/jit/dummy-frontend.cc
+++ b/gcc/jit/dummy-frontend.cc
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "target.h"
 #include "jit-playback.h"
 #include "stor-layout.h"
 #include "debug.h"
@@ -29,8 +30,14 @@ along with GCC; see the file COPYING3.  If not see
 #include "options.h"
 #include "stringpool.h"
 #include "attribs.h"
+#include "jit-recording.h"
+#include "print-tree.h"
 
 #include <mpfr.h>
+#include <unordered_map>
+#include <string>
+
+using namespace gcc::jit;
 
 /* Attribute handling.  */
 
@@ -86,6 +93,11 @@ static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
   ATTR_EXCL (NULL, false, false, false)
 };
 
+hash_map<nofree_string_hash, tree> target_builtins{};
+std::unordered_map<std::string, recording::function_type*> target_function_types
+{};
+recording::context target_builtins_ctxt{NULL};
+
 /* Table of machine-independent attributes supported in libgccjit.  */
 const struct attribute_spec jit_attribute_table[] =
 {
@@ -594,6 +606,7 @@ jit_langhook_init (void)
 
   build_common_tree_nodes (false);
 
+  target_builtins.empty ();
   build_common_builtin_nodes ();
 
   /* The default precision for floating point numbers.  This is used
@@ -601,6 +614,8 @@ jit_langhook_init (void)
      eventually be controllable by a command line option.  */
   mpfr_set_default_prec (256);
 
+  targetm.init_builtins ();
+
   return true;
 }
 
@@ -668,11 +683,197 @@ jit_langhook_type_for_mode (machine_mode mode, int unsignedp)
   return NULL;
 }
 
-/* Record a builtin function.  We just ignore builtin functions.  */
+recording::type* tree_type_to_jit_type (tree type)
+{
+  if (TREE_CODE (type) == VECTOR_TYPE)
+  {
+    tree inner_type = TREE_TYPE (type);
+    recording::type* element_type = tree_type_to_jit_type (inner_type);
+    poly_uint64 size = TYPE_VECTOR_SUBPARTS (type);
+    long constant_size = size.to_constant ();
+    if (element_type != NULL)
+      return element_type->get_vector (constant_size);
+    return NULL;
+  }
+  if (TREE_CODE (type) == REFERENCE_TYPE)
+    // For __builtin_ms_va_start.
+    // FIXME: wrong type.
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_VOID);
+  if (TREE_CODE (type) == RECORD_TYPE)
+    // For __builtin_sysv_va_copy.
+    // FIXME: wrong type.
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_VOID);
+  for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
+    if (type == FLOATN_NX_TYPE_NODE (i))
+      // FIXME: wrong type.
+      return new recording::memento_of_get_type (&target_builtins_ctxt,
+						 GCC_JIT_TYPE_VOID);
+  if (type == void_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_VOID);
+  else if (type == ptr_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_VOID_PTR);
+  else if (type == const_ptr_type_node)
+  {
+    // Void const ptr.
+    recording::type* result =
+      new recording::memento_of_get_type (&target_builtins_ctxt,
+					  GCC_JIT_TYPE_VOID_PTR);
+    return new recording::memento_of_get_const (result);
+  }
+  else if (type == unsigned_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_UNSIGNED_INT);
+  else if (type == long_unsigned_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_UNSIGNED_LONG);
+  else if (type == integer_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_INT);
+  else if (type == long_integer_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_LONG);
+  else if (type == long_long_integer_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_LONG_LONG);
+  else if (type == signed_char_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_SIGNED_CHAR);
+  else if (type == char_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_CHAR);
+  else if (type == unsigned_intQI_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_UINT8_T);
+  else if (type == short_integer_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_SHORT);
+  else if (type == short_unsigned_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_UNSIGNED_SHORT);
+  else if (type == complex_float_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_COMPLEX_FLOAT);
+  else if (type == complex_double_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_COMPLEX_DOUBLE);
+  else if (type == complex_long_double_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					    GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE);
+  else if (type == float_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_FLOAT);
+  else if (type == double_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_DOUBLE);
+  else if (type == long_double_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_LONG_DOUBLE);
+  else if (type == bfloat16_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_BFLOAT16);
+  else if (type == dfloat128_type_node)
+    // FIXME: wrong type.
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_VOID);
+  else if (type == long_long_unsigned_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_UNSIGNED_LONG_LONG);
+  else if (type == boolean_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_BOOL);
+  else if (type == size_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_SIZE_T);
+  else if (TREE_CODE (type) == POINTER_TYPE)
+  {
+    tree inner_type = TREE_TYPE (type);
+    recording::type* element_type = tree_type_to_jit_type (inner_type);
+    return element_type->get_pointer ();
+  }
+  else
+  {
+    // Attempt to find an unqualified type when the current type has qualifiers.
+    tree tp = TYPE_MAIN_VARIANT (type);
+    for ( ; tp != NULL ; tp = TYPE_NEXT_VARIANT (tp))
+    {
+      if (TYPE_QUALS (tp) == 0 && type != tp)
+      {
+	recording::type* result = tree_type_to_jit_type (tp);
+	if (result != NULL)
+	{
+	  if (TYPE_READONLY (tp))
+	    result = new recording::memento_of_get_const (result);
+	  if (TYPE_VOLATILE (tp))
+	    result = new recording::memento_of_get_volatile (result);
+	  return result;
+	}
+      }
+    }
+
+    fprintf (stderr, "Unknown type:\n");
+    debug_tree (type);
+    abort ();
+  }
+
+  return NULL;
+}
+
+/* Record a builtin function.  We save their types to be able to check types
+   in recording and for reflection.  */
 
 static tree
 jit_langhook_builtin_function (tree decl)
 {
+  if (TREE_CODE (decl) == FUNCTION_DECL)
+  {
+    const char* name = IDENTIFIER_POINTER (DECL_NAME (decl));
+    target_builtins.put (name, decl);
+
+    std::string string_name (name);
+    if (target_function_types.count (string_name) == 0)
+    {
+      tree function_type = TREE_TYPE (decl);
+      tree arg = TYPE_ARG_TYPES (function_type);
+      bool is_variadic = false;
+
+      auto_vec <recording::type *> param_types;
+
+      while (arg != void_list_node)
+      {
+	if (arg == NULL)
+	{
+	  is_variadic = true;
+	  break;
+	}
+	if (arg != void_list_node)
+	{
+	  recording::type* arg_type = tree_type_to_jit_type (TREE_VALUE (arg));
+	  if (arg_type == NULL)
+	    return decl;
+	  param_types.safe_push (arg_type);
+	}
+	arg = TREE_CHAIN (arg);
+      }
+
+      tree result_type = TREE_TYPE (function_type);
+      recording::type* return_type = tree_type_to_jit_type (result_type);
+
+      if (return_type == NULL)
+	return decl;
+
+      recording::function_type* func_type =
+	new recording::function_type (&target_builtins_ctxt, return_type,
+				      param_types.length (),
+				      param_types.address (), is_variadic,
+				      false);
+
+      target_function_types[string_name] = func_type;
+    }
+  }
   return decl;
 }
 
diff --git a/gcc/jit/jit-builtins.cc b/gcc/jit/jit-builtins.cc
index fdd0739789d..63628beac81 100644
--- a/gcc/jit/jit-builtins.cc
+++ b/gcc/jit/jit-builtins.cc
@@ -215,7 +215,8 @@ builtins_manager::make_builtin_function (enum built_in_function builtin_id)
 			     param_types.length (),
 			     params,
 			     func_type->is_variadic (),
-			     builtin_id);
+			     builtin_id,
+			     false);
   delete[] params;
 
   /* PR/64020 - If the client code is using builtin cos or sin,
@@ -582,7 +583,8 @@ builtins_manager::make_fn_type (enum jit_builtin_type,
   result = m_ctxt->new_function_type (return_type,
 				      num_args,
 				      param_types,
-				      is_variadic);
+				      is_variadic,
+				      false);
 
  error:
   delete[] param_types;
diff --git a/gcc/jit/jit-common.h b/gcc/jit/jit-common.h
index 80c1618da96..983c9190d44 100644
--- a/gcc/jit/jit-common.h
+++ b/gcc/jit/jit-common.h
@@ -36,7 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #endif
 #endif
 
-const int NUM_GCC_JIT_TYPES = GCC_JIT_TYPE_INT128_T + 1;
+const int NUM_GCC_JIT_TYPES = GCC_JIT_TYPE_BFLOAT16 + 1;
 
 /* This comment is included by the docs.
 
diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc
index e06f161aad9..209b4cca191 100644
--- a/gcc/jit/jit-playback.cc
+++ b/gcc/jit/jit-playback.cc
@@ -280,6 +280,8 @@ get_tree_node_for_type (enum gcc_jit_types type_)
 
     case GCC_JIT_TYPE_FLOAT:
       return float_type_node;
+    case GCC_JIT_TYPE_BFLOAT16:
+      return bfloat16_type_node;
     case GCC_JIT_TYPE_DOUBLE:
       return double_type_node;
     case GCC_JIT_TYPE_LONG_DOUBLE:
@@ -509,7 +511,8 @@ new_function (location *loc,
 	      const char *name,
 	      const auto_vec<param *> *params,
 	      int is_variadic,
-	      enum built_in_function builtin_id)
+	      enum built_in_function builtin_id,
+	      int is_target_builtin)
 {
   int i;
   param *param;
@@ -543,6 +546,14 @@ new_function (location *loc,
   DECL_RESULT (fndecl) = resdecl;
   DECL_CONTEXT (resdecl) = fndecl;
 
+  if (is_target_builtin)
+  {
+    tree *decl = target_builtins.get (name);
+    if (decl != NULL)
+      fndecl = *decl;
+    else
+      add_error (loc, "cannot find target builtin %s", name);
+  }
   if (builtin_id)
     {
       gcc_assert (loc == NULL);
@@ -1007,10 +1018,31 @@ playback::context::new_rvalue_from_vector (location *,
   vec_alloc (v, elements.length ());
   for (unsigned i = 0; i < elements.length (); ++i)
     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elements[i]->as_tree ());
-  tree t_ctor = build_constructor (type->as_tree (), v);
+  tree t_ctor;
+  t_ctor = build_constructor (type->as_tree (), v);
   return new rvalue (this, t_ctor);
 }
 
+/* Construct a playback::rvalue instance (wrapping a tree) for a
+   vector perm.  */
+
+playback::rvalue *
+playback::context::new_rvalue_vector_perm (location *loc,
+					   rvalue* elements1,
+					   rvalue* elements2,
+					   rvalue* mask)
+{
+  tree t_elements1 = elements1->as_tree ();
+  tree t_elements2 = elements2->as_tree ();
+  tree t_mask = mask->as_tree ();
+
+  tree t_vector_perm = build3 (VEC_PERM_EXPR, TREE_TYPE (t_elements1),
+			       t_elements1, t_elements2, t_mask);
+  if (loc)
+    set_tree_location (t_vector_perm, loc);
+  return new rvalue (this, t_vector_perm);
+}
+
 /* Coerce a tree expression into a boolean tree expression.  */
 
 tree
@@ -1527,6 +1559,136 @@ new_array_access (location *loc,
     }
 }
 
+/* The following functions come from c-common.h.  */
+/* Like c_mark_addressable but don't check register qualifier.  */
+void
+common_mark_addressable_vec (tree t)
+{
+  while (handled_component_p (t) || TREE_CODE (t) == C_MAYBE_CONST_EXPR)
+    {
+      t = TREE_OPERAND (t, 0);
+    }
+  if (!VAR_P (t)
+      && TREE_CODE (t) != PARM_DECL
+      && TREE_CODE (t) != COMPOUND_LITERAL_EXPR
+      && TREE_CODE (t) != TARGET_EXPR)
+    return;
+  if (!VAR_P (t) || !DECL_HARD_REGISTER (t))
+    TREE_ADDRESSABLE (t) = 1;
+  if (TREE_CODE (t) == COMPOUND_LITERAL_EXPR)
+    TREE_ADDRESSABLE (COMPOUND_LITERAL_EXPR_DECL (t)) = 1;
+  else if (TREE_CODE (t) == TARGET_EXPR)
+    TREE_ADDRESSABLE (TARGET_EXPR_SLOT (t)) = 1;
+}
+
+/* Return true if TYPE is a vector type that should be subject to the GNU
+   vector extensions (as opposed to a vector type that is used only for
+   the purposes of defining target-specific built-in functions).  */
+
+inline bool
+gnu_vector_type_p (const_tree type)
+{
+  return TREE_CODE (type) == VECTOR_TYPE && !TYPE_INDIVISIBLE_P (type);
+}
+
+/* Return nonzero if REF is an lvalue valid for this language.
+   Lvalues can be assigned, unless their type has TYPE_READONLY.
+   Lvalues can have their address taken, unless they have C_DECL_REGISTER.  */
+
+bool
+lvalue_p (const_tree ref)
+{
+  const enum tree_code code = TREE_CODE (ref);
+
+  switch (code)
+    {
+    case REALPART_EXPR:
+    case IMAGPART_EXPR:
+    case COMPONENT_REF:
+      return lvalue_p (TREE_OPERAND (ref, 0));
+
+    case C_MAYBE_CONST_EXPR:
+      return lvalue_p (TREE_OPERAND (ref, 1));
+
+    case COMPOUND_LITERAL_EXPR:
+    case STRING_CST:
+      return true;
+
+    case MEM_REF:
+    case TARGET_MEM_REF:
+      /* MEM_REFs can appear from -fgimple parsing or folding, so allow them
+	 here as well.  */
+    case INDIRECT_REF:
+    case ARRAY_REF:
+    case VAR_DECL:
+    case PARM_DECL:
+    case RESULT_DECL:
+    case ERROR_MARK:
+      return (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
+	      && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE);
+
+    case BIND_EXPR:
+      return TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE;
+
+    default:
+      return false;
+    }
+}
+
+bool
+convert_vector_to_array_for_subscript (tree *vecp)
+{
+  bool ret = false;
+  if (gnu_vector_type_p (TREE_TYPE (*vecp)))
+    {
+      tree type = TREE_TYPE (*vecp);
+
+      ret = !lvalue_p (*vecp);
+
+      /* We are building an ARRAY_REF so mark the vector as addressable
+	to not run into the gimplifiers premature setting of DECL_GIMPLE_REG_P
+	 for function parameters.  */
+      /* NOTE: that was the missing piece for making vector access work with
+	optimizations enabled.  */
+      common_mark_addressable_vec (*vecp);
+
+      *vecp = build1 (VIEW_CONVERT_EXPR,
+		      build_array_type_nelts (TREE_TYPE (type),
+					      TYPE_VECTOR_SUBPARTS (type)),
+		      *vecp);
+    }
+  return ret;
+}
+
+/* Construct a playback::lvalue instance (wrapping a tree) for a
+   vector access.  */
+
+playback::lvalue *
+playback::context::
+new_vector_access (location *loc,
+		   rvalue *vector,
+		   rvalue *index)
+{
+  gcc_assert (vector);
+  gcc_assert (index);
+
+  /* For comparison, see:
+       c/c-typeck.cc: build_array_ref
+  */
+
+  tree t_vector = vector->as_tree ();
+  bool non_lvalue = convert_vector_to_array_for_subscript (&t_vector);
+  tree type = TREE_TYPE (TREE_TYPE (t_vector));
+  tree t_result = build4 (ARRAY_REF, type, t_vector, index->as_tree (),
+			  NULL_TREE, NULL_TREE);
+  if (non_lvalue)
+    t_result = non_lvalue (t_result);
+
+  if (loc)
+    set_tree_location (t_result, loc);
+  return new lvalue (this, t_result);
+}
+
 /* Construct a tree for a field access.  */
 
 tree
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index 883159f03c3..648dd2bc058 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -104,7 +104,8 @@ public:
 		const char *name,
 		const auto_vec<param *> *params,
 		int is_variadic,
-		enum built_in_function builtin_id);
+		enum built_in_function builtin_id,
+		int is_target_builtin);
 
   lvalue *
   new_global (location *loc,
@@ -147,6 +148,12 @@ public:
 			  type *type,
 			  const auto_vec<rvalue *> &elements);
 
+  rvalue *
+  new_rvalue_vector_perm (location *loc,
+			  rvalue* elements1,
+			  rvalue* elements2,
+			  rvalue* mask);
+
   rvalue *
   new_unary_op (location *loc,
 		enum gcc_jit_unary_op op,
@@ -191,6 +198,11 @@ public:
 		    rvalue *ptr,
 		    rvalue *index);
 
+  lvalue *
+  new_vector_access (location *loc,
+		     rvalue *vector,
+		     rvalue *index);
+
   void
   set_str_option (enum gcc_jit_str_option opt,
 		  const char *value);
@@ -813,4 +825,6 @@ extern playback::context *active_playback_ctxt;
 
 } // namespace gcc
 
+extern hash_map<nofree_string_hash, tree> target_builtins;
+
 #endif /* JIT_PLAYBACK_H */
diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc
index df0368ff8f7..0c3ea8ec423 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -933,14 +933,16 @@ recording::function_type *
 recording::context::new_function_type (recording::type *return_type,
 				       int num_params,
 				       recording::type **param_types,
-				       int is_variadic)
+				       int is_variadic,
+				       int is_target_builtin)
 {
   recording::function_type *fn_type
     = new function_type (this,
 			 return_type,
 			 num_params,
 			 param_types,
-			 is_variadic);
+			 is_variadic,
+			 is_target_builtin);
   record (fn_type);
   return fn_type;
 }
@@ -962,7 +964,8 @@ recording::context::new_function_ptr_type (recording::location *, /* unused loc
     = new_function_type (return_type,
 			 num_params,
 			 param_types,
-			 is_variadic);
+			 is_variadic,
+			 false);
 
   /* Return a pointer-type to the function type.  */
   return fn_type->get_pointer ();
@@ -1005,7 +1008,7 @@ recording::context::new_function (recording::location *loc,
 			     loc, kind, return_type,
 			     new_string (name),
 			     num_params, params, is_variadic,
-			     builtin_id);
+			     builtin_id, false);
   record (result);
   m_functions.safe_push (result);
 
@@ -1044,6 +1047,53 @@ recording::context::get_builtin_function (const char *name)
   return bm->get_builtin_function (name);
 }
 
+/* Create a recording::function instance for a target-specific builtin.
+
+   Implements the post-error-checking part of
+   gcc_jit_context_get_target_builtin_function.  */
+
+recording::function *
+recording::context::get_target_builtin_function (const char *name)
+{
+  const char *asm_name = name;
+  if (target_function_types.count (name) == 0)
+  {
+    fprintf (stderr, "Cannot find target builtin %s\n", name);
+    return NULL;
+  }
+
+  recording::function_type* func_type = target_function_types[name]
+    ->copy (this)->dyn_cast_function_type ();
+  const vec<type *>& param_types = func_type->get_param_types ();
+  recording::param **params = new recording::param *[param_types.length ()];
+
+  int i;
+  recording::type *param_type;
+  FOR_EACH_VEC_ELT (param_types, i, param_type)
+    {
+      char buf[16];
+      snprintf (buf, 16, "arg%d", i);
+      params[i] = new_param (NULL,
+			     param_type,
+			     buf);
+  }
+
+  recording::function *result =
+    new recording::function (this,
+	  NULL,
+	  GCC_JIT_FUNCTION_IMPORTED,
+	  func_type->get_return_type (),
+	  new_string (asm_name),
+	  param_types.length (),
+	  params,
+	  func_type->is_variadic (),
+	  BUILT_IN_NONE,
+	  true);
+  record (result);
+
+  return result;
+}
+
 /* Create a recording::global instance and add it to this context's list
    of mementos.
 
@@ -1108,6 +1158,19 @@ recording::context::new_rvalue_from_vector (location *loc,
   return result;
 }
 
+recording::rvalue *
+recording::context::new_rvalue_vector_perm (location *loc,
+			  rvalue *elements1,
+			  rvalue *elements2,
+			  rvalue *mask)
+{
+  recording::rvalue *result
+    = new memento_of_new_rvalue_vector_perm (this, loc, elements1, elements2,
+					     mask);
+  record (result);
+  return result;
+}
+
 recording::rvalue *
 recording::context::new_ctor (recording::location *loc,
 			      recording::type *type,
@@ -1309,6 +1372,22 @@ recording::context::new_array_access (recording::location *loc,
   return result;
 }
 
+/* Create a recording::vector_access instance and add it to this context's list
+   of mementos.
+
+   Implements the post-error-checking part of
+   gcc_jit_context_new_vector_access.  */
+
+recording::lvalue *
+recording::context::new_vector_access (recording::location *loc,
+				      recording::rvalue *vector,
+				      recording::rvalue *index)
+{
+  recording::lvalue *result = new vector_access (this, loc, vector, index);
+  record (result);
+  return result;
+}
+
 /* Create a recording::case_ instance and add it to this context's list
    of mementos.
 
@@ -2372,6 +2451,8 @@ recording::memento_of_get_type::get_size ()
     case GCC_JIT_TYPE_FLOAT:
       size = FLOAT_TYPE_SIZE;
       break;
+    case GCC_JIT_TYPE_BFLOAT16:
+      return GET_MODE_UNIT_SIZE (BFmode);
     case GCC_JIT_TYPE_DOUBLE:
       size = DOUBLE_TYPE_SIZE;
       break;
@@ -2431,6 +2512,7 @@ recording::memento_of_get_type::dereference ()
     case GCC_JIT_TYPE_INT64_T:
     case GCC_JIT_TYPE_INT128_T:
     case GCC_JIT_TYPE_FLOAT:
+    case GCC_JIT_TYPE_BFLOAT16:
     case GCC_JIT_TYPE_DOUBLE:
     case GCC_JIT_TYPE_LONG_DOUBLE:
     case GCC_JIT_TYPE_COMPLEX_FLOAT:
@@ -2495,6 +2577,7 @@ recording::memento_of_get_type::is_int () const
       return true;
 
     case GCC_JIT_TYPE_FLOAT:
+    case GCC_JIT_TYPE_BFLOAT16:
     case GCC_JIT_TYPE_DOUBLE:
     case GCC_JIT_TYPE_LONG_DOUBLE:
       return false;
@@ -2553,6 +2636,7 @@ recording::memento_of_get_type::is_signed () const
     case GCC_JIT_TYPE_UINT128_T:
 
     case GCC_JIT_TYPE_FLOAT:
+    case GCC_JIT_TYPE_BFLOAT16:
     case GCC_JIT_TYPE_DOUBLE:
     case GCC_JIT_TYPE_LONG_DOUBLE:
 
@@ -2612,6 +2696,7 @@ recording::memento_of_get_type::is_float () const
       return false;
 
     case GCC_JIT_TYPE_FLOAT:
+    case GCC_JIT_TYPE_BFLOAT16:
     case GCC_JIT_TYPE_DOUBLE:
     case GCC_JIT_TYPE_LONG_DOUBLE:
       return true;
@@ -2675,6 +2760,7 @@ recording::memento_of_get_type::is_bool () const
       return false;
 
     case GCC_JIT_TYPE_FLOAT:
+    case GCC_JIT_TYPE_BFLOAT16:
     case GCC_JIT_TYPE_DOUBLE:
     case GCC_JIT_TYPE_LONG_DOUBLE:
       return false;
@@ -2754,6 +2840,7 @@ static const char * const get_type_strings[] = {
   "__int32_t",    /* GCC_JIT_TYPE_INT32_T */
   "__int64_t",    /* GCC_JIT_TYPE_INT64_T */
   "__int128_t",   /* GCC_JIT_TYPE_INT128_T */
+  "bfloat16",     /* GCC_JIT_TYPE_BFLOAT16 */
 
 };
 
@@ -2800,6 +2887,7 @@ static const char * const get_type_enum_strings[] = {
   "GCC_JIT_TYPE_INT32_T",
   "GCC_JIT_TYPE_INT64_T",
   "GCC_JIT_TYPE_INT128_T",
+  "GCC_JIT_TYPE_BFLOAT16",
 };
 
 void
@@ -3098,11 +3186,13 @@ recording::function_type::function_type (context *ctxt,
 					 type *return_type,
 					 int num_params,
 					 type **param_types,
-					 int is_variadic)
+					 int is_variadic,
+					 int is_target_builtin)
 : type (ctxt),
   m_return_type (return_type),
   m_param_types (),
-  m_is_variadic (is_variadic)
+  m_is_variadic (is_variadic),
+  m_is_target_builtin (is_target_builtin)
 {
   for (int i = 0; i< num_params; i++)
     m_param_types.safe_push (param_types[i]);
@@ -4044,7 +4134,8 @@ recording::function::function (context *ctxt,
 			       int num_params,
 			       recording::param **params,
 			       int is_variadic,
-			       enum built_in_function builtin_id)
+			       enum built_in_function builtin_id,
+			       int is_target_builtin)
 : memento (ctxt),
   m_loc (loc),
   m_kind (kind),
@@ -4055,7 +4146,8 @@ recording::function::function (context *ctxt,
   m_builtin_id (builtin_id),
   m_locals (),
   m_blocks (),
-  m_fn_ptr_type (NULL)
+  m_fn_ptr_type (NULL),
+  m_is_target_builtin (is_target_builtin)
 {
   for (int i = 0; i< num_params; i++)
     {
@@ -4114,7 +4206,8 @@ recording::function::replay_into (replayer *r)
 				     m_name->c_str (),
 				     &params,
 				     m_is_variadic,
-				     m_builtin_id));
+				     m_builtin_id,
+				     m_is_target_builtin));
 }
 
 /* Create a recording::local instance and add it to
@@ -4347,7 +4440,8 @@ recording::function::get_address (recording::location *loc)
 	= m_ctxt->new_function_type (m_return_type,
 				     m_params.length (),
 				     param_types.address (),
-				     m_is_variadic);
+				     m_is_variadic,
+				     m_is_target_builtin);
       m_fn_ptr_type = fn_type->get_pointer ();
     }
   gcc_assert (m_fn_ptr_type);
@@ -5390,6 +5484,91 @@ recording::memento_of_new_rvalue_from_vector::write_reproducer (reproducer &r)
 	   elements_id);
 }
 
+/* The implementation of class
+   gcc::jit::recording::memento_of_new_rvalue_vector_perm.  */
+
+/* The constructor for
+   gcc::jit::recording::memento_of_new_rvalue_vector_perm.  */
+
+recording::memento_of_new_rvalue_vector_perm::
+memento_of_new_rvalue_vector_perm (context *ctxt,
+				   location *loc,
+				   rvalue *elements1,
+				   rvalue *elements2,
+				   rvalue *mask)
+: rvalue (ctxt, loc, elements1->get_type ()),
+  m_elements1 (elements1),
+  m_elements2 (elements2),
+  m_mask (mask)
+{
+}
+
+/* Implementation of pure virtual hook recording::memento::replay_into
+   for recording::memento_of_new_rvalue_vector_perm.  */
+
+void
+recording::memento_of_new_rvalue_vector_perm::replay_into (replayer *r)
+{
+  playback::rvalue *playback_elements1 = m_elements1->playback_rvalue ();
+  playback::rvalue *playback_elements2 = m_elements2->playback_rvalue ();
+  playback::rvalue *playback_mask = m_mask->playback_rvalue ();
+
+  set_playback_obj (r->new_rvalue_vector_perm (playback_location (r, m_loc),
+		    playback_elements1,
+		    playback_elements2,
+		    playback_mask));
+}
+
+/* Implementation of pure virtual hook recording::rvalue::visit_children
+   for recording::memento_of_new_rvalue_from_vector.  */
+
+    void
+recording::memento_of_new_rvalue_vector_perm::visit_children (rvalue_visitor *v)
+{
+  v->visit (m_elements1);
+  v->visit (m_elements2);
+  v->visit (m_mask);
+}
+
+/* Implementation of recording::memento::make_debug_string for
+   vectors.  */
+
+    recording::string *
+recording::memento_of_new_rvalue_vector_perm::make_debug_string ()
+{
+    /* Now build a string.  */
+    string *result = string::from_printf (m_ctxt,
+		"shufflevector (%s, %s, %s)",
+		m_elements1->get_debug_string (),
+		m_elements2->get_debug_string (),
+		m_mask->get_debug_string ());
+
+    return result;
+
+}
+
+/* Implementation of recording::memento::write_reproducer for
+   vectors.  */
+
+    void
+recording::memento_of_new_rvalue_vector_perm::write_reproducer (reproducer &r)
+{
+    const char *id = r.make_identifier (this, "vector");
+  r.write ("  gcc_jit_rvalue *%s =\n"
+	   "    gcc_jit_context_new_rvalue_vector_perm (%s, /* gcc_jit_context *ctxt */\n"
+	   "                                            %s, /* gcc_jit_location *loc */\n"
+	   "                                            %s, /* gcc_jit_rvalue **elements1*/\n"
+	   "                                            %s, /* gcc_jit_rvalue **elements2*/\n"
+	   "                                            %s); /* gcc_jit_rvalue **mask*/\n",
+	   id,
+	   r.get_identifier (get_context ()),
+	   r.get_identifier (m_loc),
+	   r.get_identifier_as_rvalue (m_elements1),
+	   r.get_identifier_as_rvalue (m_elements2),
+	   r.get_identifier_as_rvalue (m_mask));
+}
+
+
 void
 recording::ctor::visit_children (rvalue_visitor *v)
 {
@@ -6260,6 +6439,62 @@ recording::array_access::write_reproducer (reproducer &r)
 	   r.get_identifier_as_rvalue (m_index));
 }
 
+/* The implementation of class gcc::jit::recording::vector_access.  */
+
+/* Implementation of pure virtual hook recording::memento::replay_into
+   for recording::vector_access.  */
+
+void
+recording::vector_access::replay_into (replayer *r)
+{
+  set_playback_obj (
+    r->new_vector_access (playback_location (r, m_loc),
+			  m_vector->playback_rvalue (),
+			  m_index->playback_rvalue ()));
+}
+
+/* Implementation of pure virtual hook recording::rvalue::visit_children
+   for recording::vector_access.  */
+
+void
+recording::vector_access::visit_children (rvalue_visitor *v)
+{
+  v->visit (m_vector);
+  v->visit (m_index);
+}
+
+/* Implementation of recording::memento::make_debug_string for
+   array accesses.  */
+
+recording::string *
+recording::vector_access::make_debug_string ()
+{
+  enum precedence prec = get_precedence ();
+  return string::from_printf (m_ctxt,
+			      "%s[%s]",
+			      m_vector->get_debug_string_parens (prec),
+			      m_index->get_debug_string_parens (prec));
+}
+
+/* Implementation of recording::memento::write_reproducer for
+   vector_access.  */
+
+void
+recording::vector_access::write_reproducer (reproducer &r)
+{
+  const char *id = r.make_identifier (this, "lvalue");
+  r.write ("  gcc_jit_lvalue *%s = \n"
+	   "    gcc_jit_context_new_vector_access (%s, /* gcc_jit_context *ctxt */\n"
+	   "                                       %s, /*gcc_jit_location *loc */\n"
+	   "                                       %s, /* gcc_jit_rvalue *vector */\n"
+	   "                                       %s); /* gcc_jit_rvalue *index */\n",
+	   id,
+	   r.get_identifier (get_context ()),
+	   r.get_identifier (m_loc),
+	   r.get_identifier_as_rvalue (m_vector),
+	   r.get_identifier_as_rvalue (m_index));
+}
+
 /* The implementation of class gcc::jit::recording::access_field_of_lvalue.  */
 
 /* Implementation of pure virtual hook recording::memento::replay_into
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 2dc9448d7c9..4d704e800c3 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -24,12 +24,17 @@ along with GCC; see the file COPYING3.  If not see
 #include "jit-common.h"
 #include "jit-logging.h"
 
+#include <string>
+#include <unordered_map>
+
 class timer;
 
+extern std::unordered_map<std::string, gcc::jit::recording::function_type*>
+  target_function_types;
+
 namespace gcc {
 
 namespace jit {
-
 extern const char * const unary_op_reproducer_strings[];
 extern const char * const binary_op_reproducer_strings[];
 
@@ -116,7 +121,8 @@ public:
   new_function_type (type *return_type,
 		     int num_params,
 		     type **param_types,
-		     int is_variadic);
+		     int is_variadic,
+		     int is_target_builtin);
 
   type *
   new_function_ptr_type (location *loc,
@@ -143,6 +149,9 @@ public:
   function *
   get_builtin_function (const char *name);
 
+  function *
+  get_target_builtin_function (const char *name);
+
   lvalue *
   new_global (location *loc,
 	      enum gcc_jit_global_kind kind,
@@ -173,6 +182,12 @@ public:
 			  vector_type *type,
 			  rvalue **elements);
 
+  rvalue *
+  new_rvalue_vector_perm (location *loc,
+			  rvalue *elements1,
+			  rvalue *elements2,
+			  rvalue *mask);
+
   rvalue *
   new_unary_op (location *loc,
 		enum gcc_jit_unary_op op,
@@ -215,6 +230,11 @@ public:
 		    rvalue *ptr,
 		    rvalue *index);
 
+  lvalue *
+  new_vector_access (location *loc,
+		     rvalue *vector,
+		     rvalue *index);
+
   case_ *
   new_case (rvalue *min_value,
 	    rvalue *max_value,
@@ -539,6 +559,8 @@ public:
      these types.  */
   virtual size_t get_size () { gcc_unreachable (); }
 
+  virtual type* copy (context* ctxt) = 0;
+
   /* Dynamic casts.  */
   virtual function_type *dyn_cast_function_type () { return NULL; }
   virtual function_type *as_a_function_type() { gcc_unreachable (); return NULL; }
@@ -613,6 +635,11 @@ public:
 
   size_t get_size () final override;
 
+  type* copy (context* ctxt) final override
+  {
+    return ctxt->get_type (m_kind);
+  }
+
   bool accepts_writes_from (type *rtype) final override
   {
     if (m_kind == GCC_JIT_TYPE_VOID_PTR)
@@ -664,6 +691,13 @@ public:
 
   type *dereference () final override { return m_other_type; }
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new memento_of_get_pointer (m_other_type->copy (ctxt));
+    ctxt->record (result);
+    return result;
+  }
+
   size_t get_size () final override;
 
   bool accepts_writes_from (type *rtype) final override;
@@ -724,6 +758,13 @@ public:
     return false;
   }
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new memento_of_get_const (m_other_type->copy (ctxt));
+    ctxt->record (result);
+    return result;
+  }
+
   /* Strip off the "const", giving the underlying type.  */
   type *unqualified () final override { return m_other_type; }
 
@@ -757,6 +798,13 @@ public:
     return m_other_type->is_same_type_as (other->is_volatile ());
   }
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new memento_of_get_volatile (m_other_type->copy (ctxt));
+    ctxt->record (result);
+    return result;
+  }
+
   /* Strip off the "volatile", giving the underlying type.  */
   type *unqualified () final override { return m_other_type; }
 
@@ -777,11 +825,23 @@ public:
   : decorated_type (other_type),
     m_alignment_in_bytes (alignment_in_bytes) {}
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new memento_of_get_aligned (m_other_type->copy (ctxt),
+					       m_alignment_in_bytes);
+    ctxt->record (result);
+    return result;
+  }
+
   /* Strip off the alignment, giving the underlying type.  */
   type *unqualified () final override { return m_other_type; }
 
   void replay_into (replayer *) final override;
 
+  vector_type *dyn_cast_vector_type () final override {
+    return m_other_type->dyn_cast_vector_type ();
+  }
+
 private:
   string * make_debug_string () final override;
   void write_reproducer (reproducer &r) final override;
@@ -798,6 +858,13 @@ public:
   : decorated_type (other_type),
     m_num_units (num_units) {}
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new vector_type (m_other_type->copy (ctxt), m_num_units);
+    ctxt->record (result);
+    return result;
+  }
+
   size_t get_num_units () const { return m_num_units; }
 
   vector_type *dyn_cast_vector_type () final override { return this; }
@@ -840,6 +907,14 @@ class array_type : public type
 
   type *dereference () final override;
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new array_type (ctxt, m_loc, m_element_type->copy (ctxt),
+				   m_num_elements);
+    ctxt->record (result);
+    return result;
+  }
+
   bool is_int () const final override { return false; }
   bool is_float () const final override { return false; }
   bool is_bool () const final override { return false; }
@@ -867,7 +942,8 @@ public:
 		 type *return_type,
 		 int num_params,
 		 type **param_types,
-		 int is_variadic);
+		 int is_variadic,
+		 int is_target_builtin);
 
   type *dereference () final override;
   function_type *dyn_cast_function_type () final override { return this; }
@@ -875,6 +951,20 @@ public:
 
   bool is_same_type_as (type *other) final override;
 
+  type* copy (context* ctxt) final override
+  {
+    auto_vec<type *> new_params{};
+    for (size_t i = 0; i < m_param_types.length (); i++)
+      new_params.safe_push (m_param_types[i]->copy (ctxt));
+
+    type* result = new function_type (ctxt, m_return_type->copy (ctxt),
+				      m_param_types.length (),
+				      new_params.address (),
+				      m_is_variadic, m_is_target_builtin);
+    ctxt->record (result);
+    return result;
+  }
+
   bool is_int () const final override { return false; }
   bool is_float () const final override { return false; }
   bool is_bool () const final override { return false; }
@@ -903,6 +993,7 @@ private:
   type *m_return_type;
   auto_vec<type *> m_param_types;
   int m_is_variadic;
+  int m_is_target_builtin;
 };
 
 class field : public memento
@@ -1004,9 +1095,11 @@ public:
     return static_cast <playback::compound_type *> (m_playback_obj);
   }
 
-private:
+protected:
   location *m_loc;
   string *m_name;
+
+private:
   fields *m_fields;
 };
 
@@ -1019,6 +1112,13 @@ public:
 
   struct_ *dyn_cast_struct () final override { return this; }
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new struct_ (ctxt, m_loc, m_name);
+    ctxt->record (result);
+    return result;
+  }
+
   type *
   as_type () { return this; }
 
@@ -1066,6 +1166,13 @@ public:
 
   void replay_into (replayer *r) final override;
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new union_ (ctxt, m_loc, m_name);
+    ctxt->record (result);
+    return result;
+  }
+
   bool is_union () const final override { return true; }
 
 private:
@@ -1274,7 +1381,8 @@ public:
 	    int num_params,
 	    param **params,
 	    int is_variadic,
-	    enum built_in_function builtin_id);
+	    enum built_in_function builtin_id,
+	    int is_target_builtin);
 
   void replay_into (replayer *r) final override;
 
@@ -1329,6 +1437,7 @@ private:
   auto_vec<local *> m_locals;
   auto_vec<block *> m_blocks;
   type *m_fn_ptr_type;
+  int m_is_target_builtin;
 };
 
 class block : public memento
@@ -1597,6 +1706,33 @@ private:
   auto_vec<rvalue *> m_elements;
 };
 
+class memento_of_new_rvalue_vector_perm : public rvalue
+{
+public:
+  memento_of_new_rvalue_vector_perm (context *ctxt,
+				     location *loc,
+				     rvalue *elements1,
+				     rvalue *elements2,
+				     rvalue *mask);
+
+  void replay_into (replayer *r) final override;
+
+  void visit_children (rvalue_visitor *) final override;
+
+private:
+  string * make_debug_string () final override;
+  void write_reproducer (reproducer &r) final override;
+  enum precedence get_precedence () const final override
+  {
+    return PRECEDENCE_PRIMARY;
+  }
+
+private:
+  rvalue *m_elements1;
+  rvalue *m_elements2;
+  rvalue *m_mask;
+};
+
 class ctor : public rvalue
 {
 public:
@@ -1879,6 +2015,36 @@ private:
   rvalue *m_index;
 };
 
+class vector_access : public lvalue
+{
+public:
+  vector_access (context *ctxt,
+		 location *loc,
+		 rvalue *vector,
+		 rvalue *index)
+  : lvalue (ctxt, loc, vector->get_type ()->dyn_cast_vector_type ()
+			     ->get_element_type ()),
+    m_vector (vector),
+    m_index (index)
+  {}
+
+  void replay_into (replayer *r) final override;
+
+  void visit_children (rvalue_visitor *v) final override;
+
+private:
+  string * make_debug_string () final override;
+  void write_reproducer (reproducer &r) final override;
+  enum precedence get_precedence () const final override
+  {
+    return PRECEDENCE_POSTFIX;
+  }
+
+private:
+  rvalue *m_vector;
+  rvalue *m_index;
+};
+
 class access_field_of_lvalue : public lvalue
 {
 public:
diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
index 2def58f6aa7..8056d0c7052 100644
--- a/gcc/jit/libgccjit.cc
+++ b/gcc/jit/libgccjit.cc
@@ -1745,6 +1745,24 @@ gcc_jit_context_new_array_constructor (gcc_jit_context *ctxt,
     reinterpret_cast<gcc::jit::recording::rvalue**>(values));
 }
 
+/* Public entrypoint.  See description in libgccjit.h.
+
+   After error-checking, the real work is done by the
+   gcc::jit::recording::context::get_target_builtin_function method, in
+   jit-recording.c.  */
+
+gcc_jit_function *
+gcc_jit_context_get_target_builtin_function (gcc_jit_context *ctxt,
+					     const char *name)
+{
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  JIT_LOG_FUNC (ctxt->get_logger ());
+  RETURN_NULL_IF_FAIL (name, ctxt, NULL, "NULL name");
+
+  return static_cast <gcc_jit_function *> (
+    ctxt->get_target_builtin_function (name));
+}
+
 /* Public entrypoint.  See description in libgccjit.h.  */
 
 extern gcc_jit_lvalue *
@@ -2422,6 +2440,9 @@ gcc_jit_context_new_cast (gcc_jit_context *ctxt,
   /* LOC can be NULL.  */
   RETURN_NULL_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
   RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
+  gcc::jit::recording::vector_type *vector_type = type->dyn_cast_vector_type ();
+  RETURN_NULL_IF_FAIL (vector_type == NULL, ctxt, loc,
+		       "cannot cast vector types");
   RETURN_NULL_IF_FAIL_PRINTF3 (
     is_valid_cast (rvalue->get_type (), type),
     ctxt, loc,
@@ -2488,6 +2509,39 @@ gcc_jit_context_new_array_access (gcc_jit_context *ctxt,
   return (gcc_jit_lvalue *)ctxt->new_array_access (loc, ptr, index);
 }
 
+/* Public entrypoint.  See description in libgccjit.h.
+
+   After error-checking, the real work is done by the
+   gcc::jit::recording::context::new_vector_access method in
+   jit-recording.cc.  */
+
+extern gcc_jit_lvalue *
+gcc_jit_context_new_vector_access (gcc_jit_context *ctxt,
+				   gcc_jit_location *loc,
+				   gcc_jit_rvalue *vector,
+				   gcc_jit_rvalue *index)
+{
+  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
+  JIT_LOG_FUNC (ctxt->get_logger ());
+  /* LOC can be NULL.  */
+  RETURN_NULL_IF_FAIL (vector, ctxt, loc, "NULL vector");
+  RETURN_NULL_IF_FAIL (index, ctxt, loc, "NULL index");
+  RETURN_NULL_IF_FAIL_PRINTF2 (
+    vector->get_type ()->dyn_cast_vector_type (),
+    ctxt, loc,
+    "vector: %s (type: %s) is not a vector",
+    vector->get_debug_string (),
+    vector->get_type ()->get_debug_string ());
+  RETURN_NULL_IF_FAIL_PRINTF2 (
+    index->get_type ()->is_numeric (),
+    ctxt, loc,
+    "index: %s (type: %s) is not of numeric type",
+    index->get_debug_string (),
+    index->get_type ()->get_debug_string ());
+
+  return (gcc_jit_lvalue *)ctxt->new_vector_access (loc, vector, index);
+}
+
 /* Public entrypoint.  See description in libgccjit.h.
 
    After error-checking, the real work is done by the
@@ -4056,6 +4110,79 @@ gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt,
      (gcc::jit::recording::rvalue **)elements);
 }
 
+/* Public entrypoint.  See description in libgccjit.h.
+
+   After error-checking, the real work is done by the
+   gcc::jit::recording::context::new_rvalue_vector_perm method, in
+   jit-recording.cc.  */
+
+gcc_jit_rvalue *
+gcc_jit_context_new_rvalue_vector_perm (gcc_jit_context *ctxt,
+					gcc_jit_location *loc,
+					gcc_jit_rvalue *elements1,
+					gcc_jit_rvalue *elements2,
+					gcc_jit_rvalue *mask)
+{
+  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL ctxt");
+  JIT_LOG_FUNC (ctxt->get_logger ());
+
+  /* LOC can be NULL.  */
+
+  gcc::jit::recording::type *elements1_type = elements1->get_type ();
+  gcc::jit::recording::type *elements2_type = elements2->get_type ();
+  RETURN_NULL_IF_FAIL_PRINTF4 (
+    compatible_types (elements1->get_type ()->unqualified (),
+		      elements2->get_type ()->unqualified ()),
+    ctxt, loc,
+    "mismatching types for vector perm:"
+    " elements1: %s (type: %s) elements2: %s (type: %s)",
+    elements1->get_debug_string (),
+    elements1_type->get_debug_string (),
+    elements2->get_debug_string (),
+    elements2_type->get_debug_string ());
+
+  gcc::jit::recording::type *mask_type = mask->get_type ();
+  gcc::jit::recording::vector_type *mask_vector_type =
+    mask_type->dyn_cast_vector_type ();
+  gcc::jit::recording::vector_type *elements1_vector_type =
+    elements1_type->dyn_cast_vector_type ();
+
+  size_t mask_len = mask_vector_type->get_num_units ();
+  size_t elements1_len = elements1_vector_type->get_num_units ();
+
+  RETURN_NULL_IF_FAIL_PRINTF2 (
+    mask_len == elements1_len,
+    ctxt, loc,
+    "mismatching length for mask:"
+    " elements1 length: %ld mask length: %ld",
+    mask_len,
+    elements1_len);
+
+  gcc::jit::recording::type *mask_element_type =
+    mask_vector_type->get_element_type ();
+
+  RETURN_NULL_IF_FAIL (
+    mask_element_type->is_int (),
+    ctxt, loc,
+    "elements of mask must be of an integer type");
+
+  gcc::jit::recording::type *elements1_element_type =
+    elements1_vector_type->get_element_type ();
+  size_t mask_element_size = mask_element_type->get_size ();
+  size_t elements1_element_size = elements1_element_type->get_size ();
+
+  RETURN_NULL_IF_FAIL_PRINTF2 (
+    mask_element_size == elements1_element_size,
+    ctxt, loc,
+    "mismatching size for mask element type:"
+    " elements1 element type: %ld mask element type: %ld",
+    mask_element_size,
+    elements1_element_size);
+
+  return (gcc_jit_rvalue *)ctxt->new_rvalue_vector_perm (loc, elements1,
+							 elements2, mask);
+}
+
 /* A mutex around the cached state in parse_basever.
    Ideally this would be within parse_basever, but the mutex is only needed
    by libgccjit.  */
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index 057d3e58e73..821ae0f7a56 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -604,7 +604,9 @@ enum gcc_jit_types
   GCC_JIT_TYPE_INT16_T,
   GCC_JIT_TYPE_INT32_T,
   GCC_JIT_TYPE_INT64_T,
-  GCC_JIT_TYPE_INT128_T
+  GCC_JIT_TYPE_INT128_T,
+
+  GCC_JIT_TYPE_BFLOAT16,
 };
 
 extern gcc_jit_type *
@@ -1021,6 +1023,17 @@ extern gcc_jit_lvalue *
 gcc_jit_global_set_initializer_rvalue (gcc_jit_lvalue *global,
 				       gcc_jit_rvalue *init_value);
 
+/* Create a reference to a machine-specific builtin function (sometimes called
+   intrinsic functions).
+
+   This API entrypoint was added in LIBGCCJIT_ABI_25; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_TARGET_BUILTIN
+*/
+extern gcc_jit_function *
+gcc_jit_context_get_target_builtin_function (gcc_jit_context *ctxt,
+					     const char *name);
+
 #define LIBGCCJIT_HAVE_gcc_jit_global_set_initializer
 
 /* Set an initial value for a global, which must be an array of
@@ -1292,6 +1305,20 @@ gcc_jit_context_new_array_access (gcc_jit_context *ctxt,
 				  gcc_jit_rvalue *ptr,
 				  gcc_jit_rvalue *index);
 
+#define LIBGCCJIT_HAVE_TARGET_BUILTIN
+
+/* Get the element at INDEX in VECTOR.
+
+   This API entrypoint was added in LIBGCCJIT_ABI_25; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_TARGET_BUILTIN
+*/
+extern gcc_jit_lvalue *
+gcc_jit_context_new_vector_access (gcc_jit_context *ctxt,
+				   gcc_jit_location *loc,
+				   gcc_jit_rvalue *vector,
+				   gcc_jit_rvalue *index);
+
 /* Field access is provided separately for both lvalues and rvalues.  */
 
 /* Accessing a field of an lvalue of struct type, analogous to:
@@ -1806,6 +1833,21 @@ gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt,
 					size_t num_elements,
 					gcc_jit_rvalue **elements);
 
+/* Build a permutation vector rvalue from an 3 arrays of elements.
+
+   "vec_type" should be a vector type, created using gcc_jit_type_get_vector.
+
+   This API entrypoint was added in LIBGCCJIT_ABI_25; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_TARGET_BUILTIN
+*/
+extern gcc_jit_rvalue *
+gcc_jit_context_new_rvalue_vector_perm (gcc_jit_context *ctxt,
+					gcc_jit_location *loc,
+					gcc_jit_rvalue *elements1,
+					gcc_jit_rvalue *elements2,
+					gcc_jit_rvalue *mask);
+
 #define LIBGCCJIT_HAVE_gcc_jit_version
 
 /* Functions to retrieve libgccjit version.
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index 25463b94fe8..57750e298e4 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -271,3 +271,10 @@ LIBGCCJIT_ABI_24 {
     gcc_jit_lvalue_set_alignment;
     gcc_jit_lvalue_get_alignment;
 } LIBGCCJIT_ABI_23;
+
+LIBGCCJIT_ABI_25 {
+  global:
+    gcc_jit_context_get_target_builtin_function;
+    gcc_jit_context_new_rvalue_vector_perm;
+    gcc_jit_context_new_vector_access;
+} LIBGCCJIT_ABI_24;
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index 80606076e78..988e14ae9bc 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -319,6 +319,9 @@
 /* test-setting-alignment.c: This can't be in the testcases array as it
    is target-specific.  */
 
+/* test-target-builtins.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-builtins.c b/gcc/testsuite/jit.dg/test-target-builtins.c
new file mode 100644
index 00000000000..0ffb48e97f6
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-target-builtins.c
@@ -0,0 +1,77 @@
+/* { 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)
+{
+  CHECK_NON_NULL (gcc_jit_context_get_target_builtin_function (ctxt, "__builtin_ia32_xgetbv"));
+  gcc_jit_function *builtin_eh_pointer = gcc_jit_context_get_target_builtin_function (ctxt, "__builtin_eh_pointer");
+  CHECK_NON_NULL (builtin_eh_pointer);
+
+  gcc_jit_type *int_type =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+  gcc_jit_type *void_ptr =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID_PTR);
+  gcc_jit_function *func_main =
+    gcc_jit_context_new_function (ctxt, NULL,
+				  GCC_JIT_FUNCTION_EXPORTED,
+				  int_type,
+				  "main",
+				  0, NULL,
+				  0);
+  gcc_jit_rvalue *zero = gcc_jit_context_zero (ctxt, int_type);
+  gcc_jit_block *block = gcc_jit_function_new_block (func_main, NULL);
+  gcc_jit_lvalue *variable = gcc_jit_function_new_local(func_main, NULL, void_ptr, "variable");
+  gcc_jit_block_add_assignment (block, NULL, variable,
+    gcc_jit_context_new_call (ctxt, NULL, builtin_eh_pointer, 1, &zero));
+  gcc_jit_block_end_with_return (block, NULL, zero);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  CHECK_NON_NULL (result);
+}
+
+int
+main (int argc, char **argv)
+{
+  /*  This is the same as the main provided by harness.h, but it first create a dummy context and compile
+      in order to add the target builtins to libgccjit's internal state.  */
+  gcc_jit_context *ctxt;
+  ctxt = gcc_jit_context_acquire ();
+  if (!ctxt)
+    {
+      fail ("gcc_jit_context_acquire failed");
+      return -1;
+    }
+  gcc_jit_result *result;
+  result = gcc_jit_context_compile (ctxt);
+  gcc_jit_result_release (result);
+  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.26.2.7.g19db9cfb68.dirty


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

* Re: [PATCH] libgccjit: Add support for machine-dependent builtins
  2023-02-12  0:30 [PATCH] libgccjit: Add support for machine-dependent builtins Antoni Boucher
  2023-02-12  0:32 ` Antoni Boucher
@ 2023-02-12  1:37 ` Andrew Pinski
  2023-11-23 22:17   ` Antoni Boucher
  2024-01-10 23:29   ` Antoni Boucher
  1 sibling, 2 replies; 12+ messages in thread
From: Andrew Pinski @ 2023-02-12  1:37 UTC (permalink / raw)
  To: Antoni Boucher; +Cc: jit, gcc-patches, David Malcolm

On Sat, Feb 11, 2023 at 4:31 PM Antoni Boucher via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Hi.
> This patch adds support for machine-dependent builtins in libgccjit
> (bug 108762).
>
> There are two things I don't like in this patch:
>
>  1. There are a few functions copied from the C frontend
> (common_mark_addressable_vec and a few others).
>
>  2. Getting a target builtin only works from the second compilation
> since the type information is recorded at the first compilation. I
> couldn't find a way to get the builtin data without using the langhook.
> It is necessary to get the type information for type checking and
> instrospection.
>
> Any idea how to fix these issues?

Seems like you should do this patch in a few steps; that is split it up.
Definitely split out GCC_JIT_TYPE_BFLOAT16 support.
I also think the vector support should be in a different patch too.

Splitting out these parts would definitely make it easier for review
and make incremental improvements.

Thanks,
Andrew Pinski



>
> Thanks for the review.

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

* Re: [PATCH] libgccjit: Add support for machine-dependent builtins
  2023-02-12  1:37 ` Andrew Pinski
@ 2023-11-23 22:17   ` Antoni Boucher
  2023-11-23 22:21     ` Antoni Boucher
  2024-01-10 23:29   ` Antoni Boucher
  1 sibling, 1 reply; 12+ messages in thread
From: Antoni Boucher @ 2023-11-23 22:17 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: jit, gcc-patches, David Malcolm

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

Hi.
I did split the patch and sent one for the bfloat16 support and another
one for the vector support.

Here's the updated patch for the machine-dependent builtins.

Regards.

On Sat, 2023-02-11 at 17:37 -0800, Andrew Pinski wrote:
> On Sat, Feb 11, 2023 at 4:31 PM Antoni Boucher via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
> > 
> > Hi.
> > This patch adds support for machine-dependent builtins in libgccjit
> > (bug 108762).
> > 
> > There are two things I don't like in this patch:
> > 
> >  1. There are a few functions copied from the C frontend
> > (common_mark_addressable_vec and a few others).
> > 
> >  2. Getting a target builtin only works from the second compilation
> > since the type information is recorded at the first compilation. I
> > couldn't find a way to get the builtin data without using the
> > langhook.
> > It is necessary to get the type information for type checking and
> > instrospection.
> > 
> > Any idea how to fix these issues?
> 
> Seems like you should do this patch in a few steps; that is split it
> up.
> Definitely split out GCC_JIT_TYPE_BFLOAT16 support.
> I also think the vector support should be in a different patch too.
> 
> Splitting out these parts would definitely make it easier for review
> and make incremental improvements.
> 
> Thanks,
> Andrew Pinski
> 
> 
> 
> > 
> > Thanks for the review.


[-- Attachment #2: 0001-libgccjit-Add-support-for-machine-dependent-builtins.patch --]
[-- Type: text/x-patch, Size: 33504 bytes --]

From e025f95f4790ae861e709caf23cbc0723c1a3804 Mon Sep 17 00:00:00 2001
From: Antoni Boucher <bouanto@zoho.com>
Date: Mon, 23 Jan 2023 17:21:15 -0500
Subject: [PATCH] libgccjit: Add support for machine-dependent builtins

gcc/ChangeLog:
	PR jit/108762
	* config/i386/i386-builtins.cc: New function (clear_builtin_types).

gcc/jit/ChangeLog:
	PR jit/108762
	* docs/topics/compatibility.rst (LIBGCCJIT_ABI_26): New ABI tag.
	* docs/topics/functions.rst: Add documentation for the function
	gcc_jit_context_get_target_builtin_function.
	* dummy-frontend.cc: Include headers target.h, jit-recording.h,
	print-tree.h, unordered_map and string, new variables (target_builtins,
	target_function_types, and target_builtins_ctxt), new function
	(tree_type_to_jit_type).
	* jit-builtins.cc: Specify that the function types are not from
	target builtins.
	* jit-playback.cc: New argument is_target_builtin to new_function.
	* jit-playback.h: New argument is_target_builtin to
	new_function.
	* jit-recording.cc: New argument is_target_builtin to
	new_function_type, function_type constructor and function
	constructor, new function
	(get_target_builtin_function).
	* jit-recording.h: Include headers string and unordered_map, new
	variable target_function_types, new argument is_target_builtin
	to new_function_type, function_type and function, new functions
	(get_target_builtin_function, copy).
	* libgccjit.cc: New function
	(gcc_jit_context_get_target_builtin_function).
	* libgccjit.h: New function
	(gcc_jit_context_get_target_builtin_function).
	* libgccjit.map: New functions
	(gcc_jit_context_get_target_builtin_function).

gcc/testsuite:
	PR jit/108762
	* jit.dg/all-non-failing-tests.h: New test test-target-builtins.c.
	* jit.dg/test-target-builtins.c: New test.
---
 gcc/config/i386/i386-builtins.cc             |  18 ++
 gcc/jit/docs/topics/compatibility.rst        |   9 +
 gcc/jit/docs/topics/functions.rst            |  19 ++
 gcc/jit/dummy-frontend.cc                    | 204 ++++++++++++++++++-
 gcc/jit/jit-builtins.cc                      |   6 +-
 gcc/jit/jit-playback.cc                      |  11 +-
 gcc/jit/jit-playback.h                       |   5 +-
 gcc/jit/jit-recording.cc                     |  76 ++++++-
 gcc/jit/jit-recording.h                      | 111 +++++++++-
 gcc/jit/libgccjit.cc                         |  18 ++
 gcc/jit/libgccjit.h                          |  13 ++
 gcc/jit/libgccjit.map                        |   4 +
 gcc/testsuite/jit.dg/all-non-failing-tests.h |   3 +
 gcc/testsuite/jit.dg/test-target-builtins.c  |  77 +++++++
 14 files changed, 554 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/jit.dg/test-target-builtins.c

diff --git a/gcc/config/i386/i386-builtins.cc b/gcc/config/i386/i386-builtins.cc
index 42fc3751676..5cc1d6f4d2e 100644
--- a/gcc/config/i386/i386-builtins.cc
+++ b/gcc/config/i386/i386-builtins.cc
@@ -225,6 +225,22 @@ static GTY(()) tree ix86_builtins[(int) IX86_BUILTIN_MAX];
 
 struct builtin_isa ix86_builtins_isa[(int) IX86_BUILTIN_MAX];
 
+static void
+clear_builtin_types (void)
+{
+  for (int i = 0 ; i < IX86_BT_LAST_CPTR + 1 ; i++)
+    ix86_builtin_type_tab[i] = NULL;
+
+  for (int i = 0 ; i < IX86_BUILTIN_MAX ; i++)
+  {
+    ix86_builtins[i] = NULL;
+    ix86_builtins_isa[i].set_and_not_built_p = true;
+  }
+
+  for (int i = 0 ; i < IX86_BT_LAST_ALIAS + 1 ; i++)
+    ix86_builtin_func_type_tab[i] = NULL;
+}
+
 tree get_ix86_builtin (enum ix86_builtins c)
 {
   return ix86_builtins[c];
@@ -1483,6 +1499,8 @@ ix86_init_builtins (void)
 {
   tree ftype, decl;
 
+  clear_builtin_types ();
+
   ix86_init_builtin_types ();
 
   /* Builtins to get CPU type and features. */
diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst
index ebede440ee4..764de23341e 100644
--- a/gcc/jit/docs/topics/compatibility.rst
+++ b/gcc/jit/docs/topics/compatibility.rst
@@ -378,3 +378,12 @@ 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 a function to get target builtins:
+
+  * :func:`gcc_jit_context_get_target_builtin_function`
diff --git a/gcc/jit/docs/topics/functions.rst b/gcc/jit/docs/topics/functions.rst
index cf5cb716daf..e9b77fdb892 100644
--- a/gcc/jit/docs/topics/functions.rst
+++ b/gcc/jit/docs/topics/functions.rst
@@ -140,6 +140,25 @@ Functions
       uses such a parameter will lead to an error being emitted within
       the context.
 
+.. function::  gcc_jit_function *\
+               gcc_jit_context_get_target_builtin_function (gcc_jit_context *ctxt,\
+                                                            const char *name)
+
+   Get the :type:`gcc_jit_function` for the built-in function with the
+   given name.  For example:
+
+   .. code-block:: c
+
+      gcc_jit_function *fn
+        = gcc_jit_context_get_target_builtin_function (ctxt, "__builtin_ia32_pmuldq512_mask");
+
+   .. note:: Due to technical limitations with how libgccjit interacts with
+      the insides of GCC, not all built-in functions are supported.  More
+      precisely, not all types are supported for parameters of built-in
+      functions from libgccjit.  Attempts to get a built-in function that
+      uses such a parameter will lead to an error being emitted within
+      the context.
+
 .. function::  gcc_jit_object *\
                gcc_jit_function_as_object (gcc_jit_function *func)
 
diff --git a/gcc/jit/dummy-frontend.cc b/gcc/jit/dummy-frontend.cc
index a729086bafb..3ca9702d429 100644
--- a/gcc/jit/dummy-frontend.cc
+++ b/gcc/jit/dummy-frontend.cc
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "target.h"
 #include "jit-playback.h"
 #include "stor-layout.h"
 #include "debug.h"
@@ -29,8 +30,14 @@ along with GCC; see the file COPYING3.  If not see
 #include "options.h"
 #include "stringpool.h"
 #include "attribs.h"
+#include "jit-recording.h"
+#include "print-tree.h"
 
 #include <mpfr.h>
+#include <unordered_map>
+#include <string>
+
+using namespace gcc::jit;
 
 /* Attribute handling.  */
 
@@ -86,6 +93,11 @@ static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
   ATTR_EXCL (NULL, false, false, false)
 };
 
+hash_map<nofree_string_hash, tree> target_builtins{};
+std::unordered_map<std::string, recording::function_type*> target_function_types
+{};
+recording::context target_builtins_ctxt{NULL};
+
 /* Table of machine-independent attributes supported in libgccjit.  */
 const struct attribute_spec jit_attribute_table[] =
 {
@@ -594,6 +606,7 @@ jit_langhook_init (void)
 
   build_common_tree_nodes (false);
 
+  target_builtins.empty ();
   build_common_builtin_nodes ();
 
   /* The default precision for floating point numbers.  This is used
@@ -601,6 +614,8 @@ jit_langhook_init (void)
      eventually be controllable by a command line option.  */
   mpfr_set_default_prec (256);
 
+  targetm.init_builtins ();
+
   return true;
 }
 
@@ -668,11 +683,198 @@ jit_langhook_type_for_mode (machine_mode mode, int unsignedp)
   return NULL;
 }
 
-/* Record a builtin function.  We just ignore builtin functions.  */
+recording::type* tree_type_to_jit_type (tree type)
+{
+  if (TREE_CODE (type) == VECTOR_TYPE)
+  {
+    tree inner_type = TREE_TYPE (type);
+    recording::type* element_type = tree_type_to_jit_type (inner_type);
+    poly_uint64 size = TYPE_VECTOR_SUBPARTS (type);
+    long constant_size = size.to_constant ();
+    if (element_type != NULL)
+      return element_type->get_vector (constant_size);
+    return NULL;
+  }
+  if (TREE_CODE (type) == REFERENCE_TYPE)
+    // For __builtin_ms_va_start.
+    // FIXME: wrong type.
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_VOID);
+  if (TREE_CODE (type) == RECORD_TYPE)
+    // For __builtin_sysv_va_copy.
+    // FIXME: wrong type.
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_VOID);
+  for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
+    if (type == FLOATN_NX_TYPE_NODE (i))
+      // FIXME: wrong type.
+      return new recording::memento_of_get_type (&target_builtins_ctxt,
+						 GCC_JIT_TYPE_VOID);
+  if (type == void_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_VOID);
+  else if (type == ptr_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_VOID_PTR);
+  else if (type == const_ptr_type_node)
+  {
+    // Void const ptr.
+    recording::type* result =
+      new recording::memento_of_get_type (&target_builtins_ctxt,
+					  GCC_JIT_TYPE_VOID_PTR);
+    return new recording::memento_of_get_const (result);
+  }
+  else if (type == unsigned_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_UNSIGNED_INT);
+  else if (type == long_unsigned_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_UNSIGNED_LONG);
+  else if (type == integer_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_INT);
+  else if (type == long_integer_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_LONG);
+  else if (type == long_long_integer_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_LONG_LONG);
+  else if (type == signed_char_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_SIGNED_CHAR);
+  else if (type == char_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_CHAR);
+  else if (type == unsigned_intQI_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_UINT8_T);
+  else if (type == short_integer_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_SHORT);
+  else if (type == short_unsigned_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_UNSIGNED_SHORT);
+  else if (type == complex_float_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_COMPLEX_FLOAT);
+  else if (type == complex_double_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_COMPLEX_DOUBLE);
+  else if (type == complex_long_double_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					    GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE);
+  else if (type == float_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_FLOAT);
+  else if (type == double_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_DOUBLE);
+  else if (type == long_double_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_LONG_DOUBLE);
+  else if (type == bfloat16_type_node)
+    // FIXME: wrong type.
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_VOID);
+  else if (type == dfloat128_type_node)
+    // FIXME: wrong type.
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_VOID);
+  else if (type == long_long_unsigned_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_UNSIGNED_LONG_LONG);
+  else if (type == boolean_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_BOOL);
+  else if (type == size_type_node)
+    return new recording::memento_of_get_type (&target_builtins_ctxt,
+					       GCC_JIT_TYPE_SIZE_T);
+  else if (TREE_CODE (type) == POINTER_TYPE)
+  {
+    tree inner_type = TREE_TYPE (type);
+    recording::type* element_type = tree_type_to_jit_type (inner_type);
+    return element_type->get_pointer ();
+  }
+  else
+  {
+    // Attempt to find an unqualified type when the current type has qualifiers.
+    tree tp = TYPE_MAIN_VARIANT (type);
+    for ( ; tp != NULL ; tp = TYPE_NEXT_VARIANT (tp))
+    {
+      if (TYPE_QUALS (tp) == 0 && type != tp)
+      {
+	recording::type* result = tree_type_to_jit_type (tp);
+	if (result != NULL)
+	{
+	  if (TYPE_READONLY (tp))
+	    result = new recording::memento_of_get_const (result);
+	  if (TYPE_VOLATILE (tp))
+	    result = new recording::memento_of_get_volatile (result);
+	  return result;
+	}
+      }
+    }
+
+    fprintf (stderr, "Unknown type:\n");
+    debug_tree (type);
+    abort ();
+  }
+
+  return NULL;
+}
+
+/* Record a builtin function.  We save their types to be able to check types
+   in recording and for reflection.  */
 
 static tree
 jit_langhook_builtin_function (tree decl)
 {
+  if (TREE_CODE (decl) == FUNCTION_DECL)
+  {
+    const char* name = IDENTIFIER_POINTER (DECL_NAME (decl));
+    target_builtins.put (name, decl);
+
+    std::string string_name (name);
+    if (target_function_types.count (string_name) == 0)
+    {
+      tree function_type = TREE_TYPE (decl);
+      tree arg = TYPE_ARG_TYPES (function_type);
+      bool is_variadic = false;
+
+      auto_vec <recording::type *> param_types;
+
+      while (arg != void_list_node)
+      {
+	if (arg == NULL)
+	{
+	  is_variadic = true;
+	  break;
+	}
+	if (arg != void_list_node)
+	{
+	  recording::type* arg_type = tree_type_to_jit_type (TREE_VALUE (arg));
+	  if (arg_type == NULL)
+	    return decl;
+	  param_types.safe_push (arg_type);
+	}
+	arg = TREE_CHAIN (arg);
+      }
+
+      tree result_type = TREE_TYPE (function_type);
+      recording::type* return_type = tree_type_to_jit_type (result_type);
+
+      if (return_type == NULL)
+	return decl;
+
+      recording::function_type* func_type =
+	new recording::function_type (&target_builtins_ctxt, return_type,
+				      param_types.length (),
+				      param_types.address (), is_variadic,
+				      false);
+
+      target_function_types[string_name] = func_type;
+    }
+  }
   return decl;
 }
 
diff --git a/gcc/jit/jit-builtins.cc b/gcc/jit/jit-builtins.cc
index fdd0739789d..63628beac81 100644
--- a/gcc/jit/jit-builtins.cc
+++ b/gcc/jit/jit-builtins.cc
@@ -215,7 +215,8 @@ builtins_manager::make_builtin_function (enum built_in_function builtin_id)
 			     param_types.length (),
 			     params,
 			     func_type->is_variadic (),
-			     builtin_id);
+			     builtin_id,
+			     false);
   delete[] params;
 
   /* PR/64020 - If the client code is using builtin cos or sin,
@@ -582,7 +583,8 @@ builtins_manager::make_fn_type (enum jit_builtin_type,
   result = m_ctxt->new_function_type (return_type,
 				      num_args,
 				      param_types,
-				      is_variadic);
+				      is_variadic,
+				      false);
 
  error:
   delete[] param_types;
diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc
index 18cc4da25b8..d71ee2b61a7 100644
--- a/gcc/jit/jit-playback.cc
+++ b/gcc/jit/jit-playback.cc
@@ -509,7 +509,8 @@ new_function (location *loc,
 	      const char *name,
 	      const auto_vec<param *> *params,
 	      int is_variadic,
-	      enum built_in_function builtin_id)
+	      enum built_in_function builtin_id,
+	      int is_target_builtin)
 {
   int i;
   param *param;
@@ -543,6 +544,14 @@ new_function (location *loc,
   DECL_RESULT (fndecl) = resdecl;
   DECL_CONTEXT (resdecl) = fndecl;
 
+  if (is_target_builtin)
+  {
+    tree *decl = target_builtins.get (name);
+    if (decl != NULL)
+      fndecl = *decl;
+    else
+      add_error (loc, "cannot find target builtin %s", name);
+  }
   if (builtin_id)
     {
       gcc_assert (loc == NULL);
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index f9e29d0baec..06128b4d640 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -104,7 +104,8 @@ public:
 		const char *name,
 		const auto_vec<param *> *params,
 		int is_variadic,
-		enum built_in_function builtin_id);
+		enum built_in_function builtin_id,
+		int is_target_builtin);
 
   lvalue *
   new_global (location *loc,
@@ -818,4 +819,6 @@ extern playback::context *active_playback_ctxt;
 
 } // namespace gcc
 
+extern hash_map<nofree_string_hash, tree> target_builtins;
+
 #endif /* JIT_PLAYBACK_H */
diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc
index 9b5b8005ebe..d63293bd642 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -933,14 +933,16 @@ recording::function_type *
 recording::context::new_function_type (recording::type *return_type,
 				       int num_params,
 				       recording::type **param_types,
-				       int is_variadic)
+				       int is_variadic,
+				       int is_target_builtin)
 {
   recording::function_type *fn_type
     = new function_type (this,
 			 return_type,
 			 num_params,
 			 param_types,
-			 is_variadic);
+			 is_variadic,
+			 is_target_builtin);
   record (fn_type);
   return fn_type;
 }
@@ -962,7 +964,8 @@ recording::context::new_function_ptr_type (recording::location *, /* unused loc
     = new_function_type (return_type,
 			 num_params,
 			 param_types,
-			 is_variadic);
+			 is_variadic,
+			 false);
 
   /* Return a pointer-type to the function type.  */
   return fn_type->get_pointer ();
@@ -1005,7 +1008,7 @@ recording::context::new_function (recording::location *loc,
 			     loc, kind, return_type,
 			     new_string (name),
 			     num_params, params, is_variadic,
-			     builtin_id);
+			     builtin_id, false);
   record (result);
   m_functions.safe_push (result);
 
@@ -1044,6 +1047,53 @@ recording::context::get_builtin_function (const char *name)
   return bm->get_builtin_function (name);
 }
 
+/* Create a recording::function instance for a target-specific builtin.
+
+   Implements the post-error-checking part of
+   gcc_jit_context_get_target_builtin_function.  */
+
+recording::function *
+recording::context::get_target_builtin_function (const char *name)
+{
+  const char *asm_name = name;
+  if (target_function_types.count (name) == 0)
+  {
+    fprintf (stderr, "Cannot find target builtin %s\n", name);
+    return NULL;
+  }
+
+  recording::function_type* func_type = target_function_types[name]
+    ->copy (this)->dyn_cast_function_type ();
+  const vec<type *>& param_types = func_type->get_param_types ();
+  recording::param **params = new recording::param *[param_types.length ()];
+
+  int i;
+  recording::type *param_type;
+  FOR_EACH_VEC_ELT (param_types, i, param_type)
+    {
+      char buf[16];
+      snprintf (buf, 16, "arg%d", i);
+      params[i] = new_param (NULL,
+			     param_type,
+			     buf);
+  }
+
+  recording::function *result =
+    new recording::function (this,
+	  NULL,
+	  GCC_JIT_FUNCTION_IMPORTED,
+	  func_type->get_return_type (),
+	  new_string (asm_name),
+	  param_types.length (),
+	  params,
+	  func_type->is_variadic (),
+	  BUILT_IN_NONE,
+	  true);
+  record (result);
+
+  return result;
+}
+
 /* Create a recording::global instance and add it to this context's list
    of mementos.
 
@@ -3145,11 +3195,13 @@ recording::function_type::function_type (context *ctxt,
 					 type *return_type,
 					 int num_params,
 					 type **param_types,
-					 int is_variadic)
+					 int is_variadic,
+					 int is_target_builtin)
 : type (ctxt),
   m_return_type (return_type),
   m_param_types (),
-  m_is_variadic (is_variadic)
+  m_is_variadic (is_variadic),
+  m_is_target_builtin (is_target_builtin)
 {
   for (int i = 0; i< num_params; i++)
     m_param_types.safe_push (param_types[i]);
@@ -4091,7 +4143,8 @@ recording::function::function (context *ctxt,
 			       int num_params,
 			       recording::param **params,
 			       int is_variadic,
-			       enum built_in_function builtin_id)
+			       enum built_in_function builtin_id,
+			       int is_target_builtin)
 : memento (ctxt),
   m_loc (loc),
   m_kind (kind),
@@ -4102,7 +4155,8 @@ recording::function::function (context *ctxt,
   m_builtin_id (builtin_id),
   m_locals (),
   m_blocks (),
-  m_fn_ptr_type (NULL)
+  m_fn_ptr_type (NULL),
+  m_is_target_builtin (is_target_builtin)
 {
   for (int i = 0; i< num_params; i++)
     {
@@ -4161,7 +4215,8 @@ recording::function::replay_into (replayer *r)
 				     m_name->c_str (),
 				     &params,
 				     m_is_variadic,
-				     m_builtin_id));
+				     m_builtin_id,
+				     m_is_target_builtin));
 }
 
 /* Create a recording::local instance and add it to
@@ -4394,7 +4449,8 @@ recording::function::get_address (recording::location *loc)
 	= m_ctxt->new_function_type (m_return_type,
 				     m_params.length (),
 				     param_types.address (),
-				     m_is_variadic);
+				     m_is_variadic,
+				     m_is_target_builtin);
       m_fn_ptr_type = fn_type->get_pointer ();
     }
   gcc_assert (m_fn_ptr_type);
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 4a8082991fb..81544d6f005 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -24,12 +24,17 @@ along with GCC; see the file COPYING3.  If not see
 #include "jit-common.h"
 #include "jit-logging.h"
 
+#include <string>
+#include <unordered_map>
+
 class timer;
 
+extern std::unordered_map<std::string, gcc::jit::recording::function_type*>
+  target_function_types;
+
 namespace gcc {
 
 namespace jit {
-
 extern const char * const unary_op_reproducer_strings[];
 extern const char * const binary_op_reproducer_strings[];
 
@@ -116,7 +121,8 @@ public:
   new_function_type (type *return_type,
 		     int num_params,
 		     type **param_types,
-		     int is_variadic);
+		     int is_variadic,
+		     int is_target_builtin);
 
   type *
   new_function_ptr_type (location *loc,
@@ -143,6 +149,9 @@ public:
   function *
   get_builtin_function (const char *name);
 
+  function *
+  get_target_builtin_function (const char *name);
+
   lvalue *
   new_global (location *loc,
 	      enum gcc_jit_global_kind kind,
@@ -540,6 +549,8 @@ public:
      these types.  */
   virtual size_t get_size () { gcc_unreachable (); }
 
+  virtual type* copy (context* ctxt) = 0;
+
   /* Dynamic casts.  */
   virtual function_type *dyn_cast_function_type () { return NULL; }
   virtual function_type *as_a_function_type() { gcc_unreachable (); return NULL; }
@@ -615,6 +626,11 @@ public:
 
   size_t get_size () final override;
 
+  type* copy (context* ctxt) final override
+  {
+    return ctxt->get_type (m_kind);
+  }
+
   bool accepts_writes_from (type *rtype) final override
   {
     if (m_kind == GCC_JIT_TYPE_VOID_PTR)
@@ -666,6 +682,13 @@ public:
 
   type *dereference () final override { return m_other_type; }
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new memento_of_get_pointer (m_other_type->copy (ctxt));
+    ctxt->record (result);
+    return result;
+  }
+
   size_t get_size () final override;
 
   bool accepts_writes_from (type *rtype) final override;
@@ -726,6 +749,13 @@ public:
     return false;
   }
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new memento_of_get_const (m_other_type->copy (ctxt));
+    ctxt->record (result);
+    return result;
+  }
+
   /* Strip off the "const", giving the underlying type.  */
   type *unqualified () final override { return m_other_type; }
 
@@ -759,6 +789,13 @@ public:
     return m_other_type->is_same_type_as (other->is_volatile ());
   }
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new memento_of_get_volatile (m_other_type->copy (ctxt));
+    ctxt->record (result);
+    return result;
+  }
+
   /* Strip off the "volatile", giving the underlying type.  */
   type *unqualified () final override { return m_other_type; }
 
@@ -785,6 +822,13 @@ public:
     return m_other_type->is_same_type_as (other->is_restrict ());
   }
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new memento_of_get_restrict (m_other_type->copy (ctxt));
+    ctxt->record (result);
+    return result;
+  }
+
   /* Strip off the "restrict", giving the underlying type.  */
   type *unqualified () final override { return m_other_type; }
 
@@ -805,6 +849,14 @@ public:
   : decorated_type (other_type),
     m_alignment_in_bytes (alignment_in_bytes) {}
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new memento_of_get_aligned (m_other_type->copy (ctxt),
+					       m_alignment_in_bytes);
+    ctxt->record (result);
+    return result;
+  }
+
   /* Strip off the alignment, giving the underlying type.  */
   type *unqualified () final override { return m_other_type; }
 
@@ -826,6 +878,13 @@ public:
   : decorated_type (other_type),
     m_num_units (num_units) {}
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new vector_type (m_other_type->copy (ctxt), m_num_units);
+    ctxt->record (result);
+    return result;
+  }
+
   size_t get_num_units () const { return m_num_units; }
 
   vector_type *dyn_cast_vector_type () final override { return this; }
@@ -868,6 +927,14 @@ class array_type : public type
 
   type *dereference () final override;
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new array_type (ctxt, m_loc, m_element_type->copy (ctxt),
+				   m_num_elements);
+    ctxt->record (result);
+    return result;
+  }
+
   bool is_int () const final override { return false; }
   bool is_float () const final override { return false; }
   bool is_bool () const final override { return false; }
@@ -895,7 +962,8 @@ public:
 		 type *return_type,
 		 int num_params,
 		 type **param_types,
-		 int is_variadic);
+		 int is_variadic,
+		 int is_target_builtin);
 
   type *dereference () final override;
   function_type *dyn_cast_function_type () final override { return this; }
@@ -903,6 +971,20 @@ public:
 
   bool is_same_type_as (type *other) final override;
 
+  type* copy (context* ctxt) final override
+  {
+    auto_vec<type *> new_params{};
+    for (size_t i = 0; i < m_param_types.length (); i++)
+      new_params.safe_push (m_param_types[i]->copy (ctxt));
+
+    type* result = new function_type (ctxt, m_return_type->copy (ctxt),
+				      m_param_types.length (),
+				      new_params.address (),
+				      m_is_variadic, m_is_target_builtin);
+    ctxt->record (result);
+    return result;
+  }
+
   bool is_int () const final override { return false; }
   bool is_float () const final override { return false; }
   bool is_bool () const final override { return false; }
@@ -931,6 +1013,7 @@ private:
   type *m_return_type;
   auto_vec<type *> m_param_types;
   int m_is_variadic;
+  int m_is_target_builtin;
 };
 
 class field : public memento
@@ -1032,9 +1115,11 @@ public:
     return static_cast <playback::compound_type *> (m_playback_obj);
   }
 
-private:
+protected:
   location *m_loc;
   string *m_name;
+
+private:
   fields *m_fields;
 };
 
@@ -1047,6 +1132,13 @@ public:
 
   struct_ *dyn_cast_struct () final override { return this; }
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new struct_ (ctxt, m_loc, m_name);
+    ctxt->record (result);
+    return result;
+  }
+
   type *
   as_type () { return this; }
 
@@ -1094,6 +1186,13 @@ public:
 
   void replay_into (replayer *r) final override;
 
+  type* copy (context* ctxt) final override
+  {
+    type* result = new union_ (ctxt, m_loc, m_name);
+    ctxt->record (result);
+    return result;
+  }
+
   bool is_union () const final override { return true; }
 
 private:
@@ -1302,7 +1401,8 @@ public:
 	    int num_params,
 	    param **params,
 	    int is_variadic,
-	    enum built_in_function builtin_id);
+	    enum built_in_function builtin_id,
+	    int is_target_builtin);
 
   void replay_into (replayer *r) final override;
 
@@ -1357,6 +1457,7 @@ private:
   auto_vec<local *> m_locals;
   auto_vec<block *> m_blocks;
   type *m_fn_ptr_type;
+  int m_is_target_builtin;
 };
 
 class block : public memento
diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
index 0451b4df7f9..9ce4941e6b9 100644
--- a/gcc/jit/libgccjit.cc
+++ b/gcc/jit/libgccjit.cc
@@ -1760,6 +1760,24 @@ gcc_jit_context_new_array_constructor (gcc_jit_context *ctxt,
     reinterpret_cast<gcc::jit::recording::rvalue**>(values));
 }
 
+/* Public entrypoint.  See description in libgccjit.h.
+
+   After error-checking, the real work is done by the
+   gcc::jit::recording::context::get_target_builtin_function method, in
+   jit-recording.c.  */
+
+gcc_jit_function *
+gcc_jit_context_get_target_builtin_function (gcc_jit_context *ctxt,
+					     const char *name)
+{
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  JIT_LOG_FUNC (ctxt->get_logger ());
+  RETURN_NULL_IF_FAIL (name, ctxt, NULL, "NULL name");
+
+  return static_cast <gcc_jit_function *> (
+    ctxt->get_target_builtin_function (name));
+}
+
 /* Public entrypoint.  See description in libgccjit.h.  */
 
 extern gcc_jit_lvalue *
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index 749f6c24177..b70723fd1f6 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -1030,6 +1030,19 @@ extern gcc_jit_lvalue *
 gcc_jit_global_set_initializer_rvalue (gcc_jit_lvalue *global,
 				       gcc_jit_rvalue *init_value);
 
+#define LIBGCCJIT_HAVE_gcc_jit_context_get_target_builtin_function
+
+/* Create a reference to a machine-specific builtin function (sometimes called
+   intrinsic functions).
+
+   This API entrypoint was added in LIBGCCJIT_ABI_25; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_gcc_jit_context_get_target_builtin_function
+*/
+extern gcc_jit_function *
+gcc_jit_context_get_target_builtin_function (gcc_jit_context *ctxt,
+					     const char *name);
+
 #define LIBGCCJIT_HAVE_gcc_jit_global_set_initializer
 
 /* Set an initial value for a global, which must be an array of
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index 8b90a0e2ff3..5be7a63557b 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -276,3 +276,7 @@ LIBGCCJIT_ABI_25 {
   global:
     gcc_jit_type_get_restrict;
 } LIBGCCJIT_ABI_24;
+
+LIBGCCJIT_ABI_26 {
+    gcc_jit_context_get_target_builtin_function;
+} 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..9875cbe623c 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-builtins.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-builtins.c b/gcc/testsuite/jit.dg/test-target-builtins.c
new file mode 100644
index 00000000000..0ffb48e97f6
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-target-builtins.c
@@ -0,0 +1,77 @@
+/* { 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)
+{
+  CHECK_NON_NULL (gcc_jit_context_get_target_builtin_function (ctxt, "__builtin_ia32_xgetbv"));
+  gcc_jit_function *builtin_eh_pointer = gcc_jit_context_get_target_builtin_function (ctxt, "__builtin_eh_pointer");
+  CHECK_NON_NULL (builtin_eh_pointer);
+
+  gcc_jit_type *int_type =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+  gcc_jit_type *void_ptr =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID_PTR);
+  gcc_jit_function *func_main =
+    gcc_jit_context_new_function (ctxt, NULL,
+				  GCC_JIT_FUNCTION_EXPORTED,
+				  int_type,
+				  "main",
+				  0, NULL,
+				  0);
+  gcc_jit_rvalue *zero = gcc_jit_context_zero (ctxt, int_type);
+  gcc_jit_block *block = gcc_jit_function_new_block (func_main, NULL);
+  gcc_jit_lvalue *variable = gcc_jit_function_new_local(func_main, NULL, void_ptr, "variable");
+  gcc_jit_block_add_assignment (block, NULL, variable,
+    gcc_jit_context_new_call (ctxt, NULL, builtin_eh_pointer, 1, &zero));
+  gcc_jit_block_end_with_return (block, NULL, zero);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  CHECK_NON_NULL (result);
+}
+
+int
+main (int argc, char **argv)
+{
+  /*  This is the same as the main provided by harness.h, but it first create a dummy context and compile
+      in order to add the target builtins to libgccjit's internal state.  */
+  gcc_jit_context *ctxt;
+  ctxt = gcc_jit_context_acquire ();
+  if (!ctxt)
+    {
+      fail ("gcc_jit_context_acquire failed");
+      return -1;
+    }
+  gcc_jit_result *result;
+  result = gcc_jit_context_compile (ctxt);
+  gcc_jit_result_release (result);
+  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.1


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

* Re: [PATCH] libgccjit: Add support for machine-dependent builtins
  2023-11-23 22:17   ` Antoni Boucher
@ 2023-11-23 22:21     ` Antoni Boucher
  0 siblings, 0 replies; 12+ messages in thread
From: Antoni Boucher @ 2023-11-23 22:21 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: jit, gcc-patches, David Malcolm

I will need to not forget to update the function tree_type_to_jit_type
in dummy-frontend.cc to add back the support for bfloat16 when the
patch for it is merged.

On Thu, 2023-11-23 at 17:17 -0500, Antoni Boucher wrote:
> Hi.
> I did split the patch and sent one for the bfloat16 support and
> another
> one for the vector support.
> 
> Here's the updated patch for the machine-dependent builtins.
> 
> Regards.
> 
> On Sat, 2023-02-11 at 17:37 -0800, Andrew Pinski wrote:
> > On Sat, Feb 11, 2023 at 4:31 PM Antoni Boucher via Gcc-patches
> > <gcc-patches@gcc.gnu.org> wrote:
> > > 
> > > Hi.
> > > This patch adds support for machine-dependent builtins in
> > > libgccjit
> > > (bug 108762).
> > > 
> > > There are two things I don't like in this patch:
> > > 
> > >  1. There are a few functions copied from the C frontend
> > > (common_mark_addressable_vec and a few others).
> > > 
> > >  2. Getting a target builtin only works from the second
> > > compilation
> > > since the type information is recorded at the first compilation.
> > > I
> > > couldn't find a way to get the builtin data without using the
> > > langhook.
> > > It is necessary to get the type information for type checking and
> > > instrospection.
> > > 
> > > Any idea how to fix these issues?
> > 
> > Seems like you should do this patch in a few steps; that is split
> > it
> > up.
> > Definitely split out GCC_JIT_TYPE_BFLOAT16 support.
> > I also think the vector support should be in a different patch too.
> > 
> > Splitting out these parts would definitely make it easier for
> > review
> > and make incremental improvements.
> > 
> > Thanks,
> > Andrew Pinski
> > 
> > 
> > 
> > > 
> > > Thanks for the review.
> 


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

* Re: [PATCH] libgccjit: Add support for machine-dependent builtins
  2023-02-12  1:37 ` Andrew Pinski
  2023-11-23 22:17   ` Antoni Boucher
@ 2024-01-10 23:29   ` Antoni Boucher
  2024-01-10 23:44     ` David Malcolm
  1 sibling, 1 reply; 12+ messages in thread
From: Antoni Boucher @ 2024-01-10 23:29 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: jit, gcc-patches, David Malcolm

David: Ping in case you missed this patch.

On Sat, 2023-02-11 at 17:37 -0800, Andrew Pinski wrote:
> On Sat, Feb 11, 2023 at 4:31 PM Antoni Boucher via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
> > 
> > Hi.
> > This patch adds support for machine-dependent builtins in libgccjit
> > (bug 108762).
> > 
> > There are two things I don't like in this patch:
> > 
> >  1. There are a few functions copied from the C frontend
> > (common_mark_addressable_vec and a few others).
> > 
> >  2. Getting a target builtin only works from the second compilation
> > since the type information is recorded at the first compilation. I
> > couldn't find a way to get the builtin data without using the
> > langhook.
> > It is necessary to get the type information for type checking and
> > instrospection.
> > 
> > Any idea how to fix these issues?
> 
> Seems like you should do this patch in a few steps; that is split it
> up.
> Definitely split out GCC_JIT_TYPE_BFLOAT16 support.
> I also think the vector support should be in a different patch too.
> 
> Splitting out these parts would definitely make it easier for review
> and make incremental improvements.
> 
> Thanks,
> Andrew Pinski
> 
> 
> 
> > 
> > Thanks for the review.


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

* Re: [PATCH] libgccjit: Add support for machine-dependent builtins
  2024-01-10 23:29   ` Antoni Boucher
@ 2024-01-10 23:44     ` David Malcolm
  2024-01-10 23:58       ` Antoni Boucher
  0 siblings, 1 reply; 12+ messages in thread
From: David Malcolm @ 2024-01-10 23:44 UTC (permalink / raw)
  To: Antoni Boucher, Andrew Pinski; +Cc: jit, gcc-patches

On Wed, 2024-01-10 at 18:29 -0500, Antoni Boucher wrote:
> David: Ping in case you missed this patch.

For some reason it's not showing up in patchwork (or, at least, I can't
find it there).  Do you have a URL for it there?

Sorry about this
Dave

> 
> On Sat, 2023-02-11 at 17:37 -0800, Andrew Pinski wrote:
> > On Sat, Feb 11, 2023 at 4:31 PM Antoni Boucher via Gcc-patches
> > <gcc-patches@gcc.gnu.org> wrote:
> > > 
> > > Hi.
> > > This patch adds support for machine-dependent builtins in
> > > libgccjit
> > > (bug 108762).
> > > 
> > > There are two things I don't like in this patch:
> > > 
> > >  1. There are a few functions copied from the C frontend
> > > (common_mark_addressable_vec and a few others).
> > > 
> > >  2. Getting a target builtin only works from the second
> > > compilation
> > > since the type information is recorded at the first compilation.
> > > I
> > > couldn't find a way to get the builtin data without using the
> > > langhook.
> > > It is necessary to get the type information for type checking and
> > > instrospection.
> > > 
> > > Any idea how to fix these issues?
> > 
> > Seems like you should do this patch in a few steps; that is split
> > it
> > up.
> > Definitely split out GCC_JIT_TYPE_BFLOAT16 support.
> > I also think the vector support should be in a different patch too.
> > 
> > Splitting out these parts would definitely make it easier for
> > review
> > and make incremental improvements.
> > 
> > Thanks,
> > Andrew Pinski
> > 
> > 
> > 
> > > 
> > > Thanks for the review.
> 


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

* Re: [PATCH] libgccjit: Add support for machine-dependent builtins
  2024-01-10 23:44     ` David Malcolm
@ 2024-01-10 23:58       ` Antoni Boucher
  2024-02-08 13:59         ` Antoni Boucher
  0 siblings, 1 reply; 12+ messages in thread
From: Antoni Boucher @ 2024-01-10 23:58 UTC (permalink / raw)
  To: David Malcolm, Andrew Pinski; +Cc: jit, gcc-patches

Here it is: https://gcc.gnu.org/pipermail/jit/2023q4/001725.html

On Wed, 2024-01-10 at 18:44 -0500, David Malcolm wrote:
> On Wed, 2024-01-10 at 18:29 -0500, Antoni Boucher wrote:
> > David: Ping in case you missed this patch.
> 
> For some reason it's not showing up in patchwork (or, at least, I
> can't
> find it there).  Do you have a URL for it there?
> 
> Sorry about this
> Dave
> 
> > 
> > On Sat, 2023-02-11 at 17:37 -0800, Andrew Pinski wrote:
> > > On Sat, Feb 11, 2023 at 4:31 PM Antoni Boucher via Gcc-patches
> > > <gcc-patches@gcc.gnu.org> wrote:
> > > > 
> > > > Hi.
> > > > This patch adds support for machine-dependent builtins in
> > > > libgccjit
> > > > (bug 108762).
> > > > 
> > > > There are two things I don't like in this patch:
> > > > 
> > > >  1. There are a few functions copied from the C frontend
> > > > (common_mark_addressable_vec and a few others).
> > > > 
> > > >  2. Getting a target builtin only works from the second
> > > > compilation
> > > > since the type information is recorded at the first
> > > > compilation.
> > > > I
> > > > couldn't find a way to get the builtin data without using the
> > > > langhook.
> > > > It is necessary to get the type information for type checking
> > > > and
> > > > instrospection.
> > > > 
> > > > Any idea how to fix these issues?
> > > 
> > > Seems like you should do this patch in a few steps; that is split
> > > it
> > > up.
> > > Definitely split out GCC_JIT_TYPE_BFLOAT16 support.
> > > I also think the vector support should be in a different patch
> > > too.
> > > 
> > > Splitting out these parts would definitely make it easier for
> > > review
> > > and make incremental improvements.
> > > 
> > > Thanks,
> > > Andrew Pinski
> > > 
> > > 
> > > 
> > > > 
> > > > Thanks for the review.
> > 
> 


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

* Re: [PATCH] libgccjit: Add support for machine-dependent builtins
  2024-01-10 23:58       ` Antoni Boucher
@ 2024-02-08 13:59         ` Antoni Boucher
  2024-02-15 14:32           ` Antoni Boucher
  0 siblings, 1 reply; 12+ messages in thread
From: Antoni Boucher @ 2024-02-08 13:59 UTC (permalink / raw)
  To: David Malcolm, Andrew Pinski; +Cc: jit, gcc-patches

David: Ping.

On Wed, 2024-01-10 at 18:58 -0500, Antoni Boucher wrote:
> Here it is: https://gcc.gnu.org/pipermail/jit/2023q4/001725.html
> 
> On Wed, 2024-01-10 at 18:44 -0500, David Malcolm wrote:
> > On Wed, 2024-01-10 at 18:29 -0500, Antoni Boucher wrote:
> > > David: Ping in case you missed this patch.
> > 
> > For some reason it's not showing up in patchwork (or, at least, I
> > can't
> > find it there).  Do you have a URL for it there?
> > 
> > Sorry about this
> > Dave
> > 
> > > 
> > > On Sat, 2023-02-11 at 17:37 -0800, Andrew Pinski wrote:
> > > > On Sat, Feb 11, 2023 at 4:31 PM Antoni Boucher via Gcc-patches
> > > > <gcc-patches@gcc.gnu.org> wrote:
> > > > > 
> > > > > Hi.
> > > > > This patch adds support for machine-dependent builtins in
> > > > > libgccjit
> > > > > (bug 108762).
> > > > > 
> > > > > There are two things I don't like in this patch:
> > > > > 
> > > > >  1. There are a few functions copied from the C frontend
> > > > > (common_mark_addressable_vec and a few others).
> > > > > 
> > > > >  2. Getting a target builtin only works from the second
> > > > > compilation
> > > > > since the type information is recorded at the first
> > > > > compilation.
> > > > > I
> > > > > couldn't find a way to get the builtin data without using the
> > > > > langhook.
> > > > > It is necessary to get the type information for type checking
> > > > > and
> > > > > instrospection.
> > > > > 
> > > > > Any idea how to fix these issues?
> > > > 
> > > > Seems like you should do this patch in a few steps; that is
> > > > split
> > > > it
> > > > up.
> > > > Definitely split out GCC_JIT_TYPE_BFLOAT16 support.
> > > > I also think the vector support should be in a different patch
> > > > too.
> > > > 
> > > > Splitting out these parts would definitely make it easier for
> > > > review
> > > > and make incremental improvements.
> > > > 
> > > > Thanks,
> > > > Andrew Pinski
> > > > 
> > > > 
> > > > 
> > > > > 
> > > > > Thanks for the review.
> > > 
> > 
> 


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

* Re: [PATCH] libgccjit: Add support for machine-dependent builtins
  2024-02-08 13:59         ` Antoni Boucher
@ 2024-02-15 14:32           ` Antoni Boucher
  2024-02-29 15:34             ` Antoni Boucher
  0 siblings, 1 reply; 12+ messages in thread
From: Antoni Boucher @ 2024-02-15 14:32 UTC (permalink / raw)
  To: David Malcolm, Andrew Pinski; +Cc: jit, gcc-patches

David: Ping

On Thu, 2024-02-08 at 08:59 -0500, Antoni Boucher wrote:
> David: Ping.
> 
> On Wed, 2024-01-10 at 18:58 -0500, Antoni Boucher wrote:
> > Here it is: https://gcc.gnu.org/pipermail/jit/2023q4/001725.html
> > 
> > On Wed, 2024-01-10 at 18:44 -0500, David Malcolm wrote:
> > > On Wed, 2024-01-10 at 18:29 -0500, Antoni Boucher wrote:
> > > > David: Ping in case you missed this patch.
> > > 
> > > For some reason it's not showing up in patchwork (or, at least, I
> > > can't
> > > find it there).  Do you have a URL for it there?
> > > 
> > > Sorry about this
> > > Dave
> > > 
> > > > 
> > > > On Sat, 2023-02-11 at 17:37 -0800, Andrew Pinski wrote:
> > > > > On Sat, Feb 11, 2023 at 4:31 PM Antoni Boucher via Gcc-
> > > > > patches
> > > > > <gcc-patches@gcc.gnu.org> wrote:
> > > > > > 
> > > > > > Hi.
> > > > > > This patch adds support for machine-dependent builtins in
> > > > > > libgccjit
> > > > > > (bug 108762).
> > > > > > 
> > > > > > There are two things I don't like in this patch:
> > > > > > 
> > > > > >  1. There are a few functions copied from the C frontend
> > > > > > (common_mark_addressable_vec and a few others).
> > > > > > 
> > > > > >  2. Getting a target builtin only works from the second
> > > > > > compilation
> > > > > > since the type information is recorded at the first
> > > > > > compilation.
> > > > > > I
> > > > > > couldn't find a way to get the builtin data without using
> > > > > > the
> > > > > > langhook.
> > > > > > It is necessary to get the type information for type
> > > > > > checking
> > > > > > and
> > > > > > instrospection.
> > > > > > 
> > > > > > Any idea how to fix these issues?
> > > > > 
> > > > > Seems like you should do this patch in a few steps; that is
> > > > > split
> > > > > it
> > > > > up.
> > > > > Definitely split out GCC_JIT_TYPE_BFLOAT16 support.
> > > > > I also think the vector support should be in a different
> > > > > patch
> > > > > too.
> > > > > 
> > > > > Splitting out these parts would definitely make it easier for
> > > > > review
> > > > > and make incremental improvements.
> > > > > 
> > > > > Thanks,
> > > > > Andrew Pinski
> > > > > 
> > > > > 
> > > > > 
> > > > > > 
> > > > > > Thanks for the review.
> > > > 
> > > 
> > 
> 


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

* Re: [PATCH] libgccjit: Add support for machine-dependent builtins
  2024-02-15 14:32           ` Antoni Boucher
@ 2024-02-29 15:34             ` Antoni Boucher
  2024-04-19 12:35               ` Antoni Boucher
  0 siblings, 1 reply; 12+ messages in thread
From: Antoni Boucher @ 2024-02-29 15:34 UTC (permalink / raw)
  To: David Malcolm, Andrew Pinski; +Cc: jit, gcc-patches

David: Ping.

On Thu, 2024-02-15 at 09:32 -0500, Antoni Boucher wrote:
> David: Ping
> 
> On Thu, 2024-02-08 at 08:59 -0500, Antoni Boucher wrote:
> > David: Ping.
> > 
> > On Wed, 2024-01-10 at 18:58 -0500, Antoni Boucher wrote:
> > > Here it is: https://gcc.gnu.org/pipermail/jit/2023q4/001725.html
> > > 
> > > On Wed, 2024-01-10 at 18:44 -0500, David Malcolm wrote:
> > > > On Wed, 2024-01-10 at 18:29 -0500, Antoni Boucher wrote:
> > > > > David: Ping in case you missed this patch.
> > > > 
> > > > For some reason it's not showing up in patchwork (or, at least,
> > > > I
> > > > can't
> > > > find it there).  Do you have a URL for it there?
> > > > 
> > > > Sorry about this
> > > > Dave
> > > > 
> > > > > 
> > > > > On Sat, 2023-02-11 at 17:37 -0800, Andrew Pinski wrote:
> > > > > > On Sat, Feb 11, 2023 at 4:31 PM Antoni Boucher via Gcc-
> > > > > > patches
> > > > > > <gcc-patches@gcc.gnu.org> wrote:
> > > > > > > 
> > > > > > > Hi.
> > > > > > > This patch adds support for machine-dependent builtins in
> > > > > > > libgccjit
> > > > > > > (bug 108762).
> > > > > > > 
> > > > > > > There are two things I don't like in this patch:
> > > > > > > 
> > > > > > >  1. There are a few functions copied from the C frontend
> > > > > > > (common_mark_addressable_vec and a few others).
> > > > > > > 
> > > > > > >  2. Getting a target builtin only works from the second
> > > > > > > compilation
> > > > > > > since the type information is recorded at the first
> > > > > > > compilation.
> > > > > > > I
> > > > > > > couldn't find a way to get the builtin data without using
> > > > > > > the
> > > > > > > langhook.
> > > > > > > It is necessary to get the type information for type
> > > > > > > checking
> > > > > > > and
> > > > > > > instrospection.
> > > > > > > 
> > > > > > > Any idea how to fix these issues?
> > > > > > 
> > > > > > Seems like you should do this patch in a few steps; that is
> > > > > > split
> > > > > > it
> > > > > > up.
> > > > > > Definitely split out GCC_JIT_TYPE_BFLOAT16 support.
> > > > > > I also think the vector support should be in a different
> > > > > > patch
> > > > > > too.
> > > > > > 
> > > > > > Splitting out these parts would definitely make it easier
> > > > > > for
> > > > > > review
> > > > > > and make incremental improvements.
> > > > > > 
> > > > > > Thanks,
> > > > > > Andrew Pinski
> > > > > > 
> > > > > > 
> > > > > > 
> > > > > > > 
> > > > > > > Thanks for the review.
> > > > > 
> > > > 
> > > 
> > 
> 


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

* Re: [PATCH] libgccjit: Add support for machine-dependent builtins
  2024-02-29 15:34             ` Antoni Boucher
@ 2024-04-19 12:35               ` Antoni Boucher
  0 siblings, 0 replies; 12+ messages in thread
From: Antoni Boucher @ 2024-04-19 12:35 UTC (permalink / raw)
  To: David Malcolm, Andrew Pinski; +Cc: jit, gcc-patches

David: Ping.

Le 2024-02-29 à 10 h 34, Antoni Boucher a écrit :
> David: Ping.
> 
> On Thu, 2024-02-15 at 09:32 -0500, Antoni Boucher wrote:
>> David: Ping
>>
>> On Thu, 2024-02-08 at 08:59 -0500, Antoni Boucher wrote:
>>> David: Ping.
>>>
>>> On Wed, 2024-01-10 at 18:58 -0500, Antoni Boucher wrote:
>>>> Here it is: https://gcc.gnu.org/pipermail/jit/2023q4/001725.html
>>>>
>>>> On Wed, 2024-01-10 at 18:44 -0500, David Malcolm wrote:
>>>>> On Wed, 2024-01-10 at 18:29 -0500, Antoni Boucher wrote:
>>>>>> David: Ping in case you missed this patch.
>>>>>
>>>>> For some reason it's not showing up in patchwork (or, at least,
>>>>> I
>>>>> can't
>>>>> find it there).  Do you have a URL for it there?
>>>>>
>>>>> Sorry about this
>>>>> Dave
>>>>>
>>>>>>
>>>>>> On Sat, 2023-02-11 at 17:37 -0800, Andrew Pinski wrote:
>>>>>>> On Sat, Feb 11, 2023 at 4:31 PM Antoni Boucher via Gcc-
>>>>>>> patches
>>>>>>> <gcc-patches@gcc.gnu.org> wrote:
>>>>>>>>
>>>>>>>> Hi.
>>>>>>>> This patch adds support for machine-dependent builtins in
>>>>>>>> libgccjit
>>>>>>>> (bug 108762).
>>>>>>>>
>>>>>>>> There are two things I don't like in this patch:
>>>>>>>>
>>>>>>>>   1. There are a few functions copied from the C frontend
>>>>>>>> (common_mark_addressable_vec and a few others).
>>>>>>>>
>>>>>>>>   2. Getting a target builtin only works from the second
>>>>>>>> compilation
>>>>>>>> since the type information is recorded at the first
>>>>>>>> compilation.
>>>>>>>> I
>>>>>>>> couldn't find a way to get the builtin data without using
>>>>>>>> the
>>>>>>>> langhook.
>>>>>>>> It is necessary to get the type information for type
>>>>>>>> checking
>>>>>>>> and
>>>>>>>> instrospection.
>>>>>>>>
>>>>>>>> Any idea how to fix these issues?
>>>>>>>
>>>>>>> Seems like you should do this patch in a few steps; that is
>>>>>>> split
>>>>>>> it
>>>>>>> up.
>>>>>>> Definitely split out GCC_JIT_TYPE_BFLOAT16 support.
>>>>>>> I also think the vector support should be in a different
>>>>>>> patch
>>>>>>> too.
>>>>>>>
>>>>>>> Splitting out these parts would definitely make it easier
>>>>>>> for
>>>>>>> review
>>>>>>> and make incremental improvements.
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Andrew Pinski
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> Thanks for the review.
>>>>>>
>>>>>
>>>>
>>>
>>
> 

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

end of thread, other threads:[~2024-04-19 12:35 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-12  0:30 [PATCH] libgccjit: Add support for machine-dependent builtins Antoni Boucher
2023-02-12  0:32 ` Antoni Boucher
2023-02-12  1:37 ` Andrew Pinski
2023-11-23 22:17   ` Antoni Boucher
2023-11-23 22:21     ` Antoni Boucher
2024-01-10 23:29   ` Antoni Boucher
2024-01-10 23:44     ` David Malcolm
2024-01-10 23:58       ` Antoni Boucher
2024-02-08 13:59         ` Antoni Boucher
2024-02-15 14:32           ` Antoni Boucher
2024-02-29 15:34             ` Antoni Boucher
2024-04-19 12:35               ` 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).