public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: juzhe.zhong@rivai.ai
To: gcc-patches@gcc.gnu.org
Cc: kito.cheng@gmail.com, palmer@dabbelt.com, juzhe.zhong@rivai.ai
Subject: [PATCH 03/21]   Add RVV datatypes
Date: Tue, 31 May 2022 16:49:54 +0800	[thread overview]
Message-ID: <20220531085012.269719-4-juzhe.zhong@rivai.ai> (raw)
In-Reply-To: <20220531085012.269719-1-juzhe.zhong@rivai.ai>

From: zhongjuzhe <juzhe.zhong@rivai.ai>

gcc/ChangeLog:

        * config/riscv/riscv-vector-builtins.cc (make_type_sizeless): New function.
        (sizeless_type_p): New function.
        (vector_builtin_mode): New function.
        (vector_legal_vlmul): New function.
        (add_vector_type_attribute): New function.
        (register_general_builtin_types): New function.
        (DEFINE_SCALAR_PTR_TYPE_NODE): New function.
        (register_builtin_types): New function.
        (register_vector_type): New function.
        (handle_pragma_vector): New function.
        (lookup_rvv_type_attribute): New function.
        (builtin_type_p): New function.
        (verify_type_context): New function.
        (mangle_builtin_type): New function.
        * config/riscv/riscv-vector-builtins.h (builtin_type_p): New function.
        (verify_type_context): New function.
        (mangle_builtin_type): New function.
        * config/riscv/riscv.cc (riscv_vector_mode_supported_p): New function.
        (riscv_vector_alignment): New function.
        (riscv_vectorize_preferred_vector_alignment): New function.
        (riscv_simd_vector_alignment_reachable): New function.
        (riscv_builtin_support_vector_misalignment): New function.
        (riscv_compatible_vector_types_p): New function.
        (riscv_verify_type_context): New function.
        (riscv_mangle_type): New function.
        (TARGET_VECTOR_MODE_SUPPORTED_P): New targethook.
        (TARGET_VECTOR_ALIGNMENT): New targethook.
        (TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT): New targethook.
        (TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE): New targethook.
        (TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT): New targethook.
        (TARGET_COMPATIBLE_VECTOR_TYPES_P): New targethook.
        (TARGET_VERIFY_TYPE_CONTEXT): New targethook.
        (TARGET_MANGLE_TYPE): New targethook.
        
---
 gcc/config/riscv/riscv-vector-builtins.cc | 466 ++++++++++++++++++++++
 gcc/config/riscv/riscv-vector-builtins.h  |   3 +
 gcc/config/riscv/riscv.cc                 | 144 +++++++
 3 files changed, 613 insertions(+)

diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 7ea07a24b5b..ef734572add 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -109,6 +109,286 @@ static unsigned int NUM_INSN_FUNC;
 
 static void init_def_variables ();
 
+/* Force TYPE to be a sizeless type.  */
+static void
+make_type_sizeless (tree type)
+{
+  TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("RVV sizeless type"),
+				      NULL_TREE, TYPE_ATTRIBUTES (type));
+}
+
+/* Return true if TYPE is a sizeless type.  */
+static bool
+sizeless_type_p (const_tree type)
+{
+  if (type == error_mark_node)
+    return NULL_TREE;
+  return lookup_attribute ("RVV sizeless type", TYPE_ATTRIBUTES (type));
+}
+
+machine_mode
+vector_builtin_mode (scalar_mode inner_mode, enum vlmul_field_enum vlmul)
+{
+  switch (inner_mode)
+    {
+    case E_BImode:
+      return vlmul == VLMUL_FIELD_000   ? VNx16BImode
+             : vlmul == VLMUL_FIELD_001 ? VNx32BImode
+             : vlmul == VLMUL_FIELD_010 ? VNx64BImode
+             : vlmul == VLMUL_FIELD_011 ? VNx128BImode
+             : vlmul == VLMUL_FIELD_111 ? VNx8BImode
+             : vlmul == VLMUL_FIELD_110 ? VNx4BImode
+                                       : VNx2BImode;
+
+    case E_QImode:
+      return vlmul == VLMUL_FIELD_000   ? VNx16QImode
+             : vlmul == VLMUL_FIELD_001 ? VNx32QImode
+             : vlmul == VLMUL_FIELD_010 ? VNx64QImode
+             : vlmul == VLMUL_FIELD_011 ? VNx128QImode
+             : vlmul == VLMUL_FIELD_111 ? VNx8QImode
+             : vlmul == VLMUL_FIELD_110 ? VNx4QImode
+                                       : VNx2QImode;
+
+    case E_HImode:
+      if (vlmul == VLMUL_FIELD_101)
+        gcc_unreachable ();
+
+      return vlmul == VLMUL_FIELD_000   ? VNx8HImode
+             : vlmul == VLMUL_FIELD_001 ? VNx16HImode
+             : vlmul == VLMUL_FIELD_010 ? VNx32HImode
+             : vlmul == VLMUL_FIELD_011 ? VNx64HImode
+             : vlmul == VLMUL_FIELD_111 ? VNx4HImode
+                                       : VNx2HImode;
+
+    case E_SImode:
+      if (vlmul == VLMUL_FIELD_101 || vlmul == VLMUL_FIELD_110)
+        gcc_unreachable ();
+
+      return vlmul == VLMUL_FIELD_000   ? VNx4SImode
+             : vlmul == VLMUL_FIELD_001 ? VNx8SImode
+             : vlmul == VLMUL_FIELD_010 ? VNx16SImode
+             : vlmul == VLMUL_FIELD_011 ? VNx32SImode
+                                       : VNx2SImode;
+
+    case E_DImode:
+      if (vlmul == VLMUL_FIELD_101 || vlmul == VLMUL_FIELD_110 ||
+          vlmul == VLMUL_FIELD_111)
+        gcc_unreachable ();
+
+      return vlmul == VLMUL_FIELD_000   ? VNx2DImode
+             : vlmul == VLMUL_FIELD_001 ? VNx4DImode
+             : vlmul == VLMUL_FIELD_010 ? VNx8DImode
+                                       : VNx16DImode;
+
+    case E_SFmode:
+      if (vlmul == VLMUL_FIELD_101 || vlmul == VLMUL_FIELD_110)
+        gcc_unreachable ();
+
+      return vlmul == VLMUL_FIELD_000   ? VNx4SFmode
+             : vlmul == VLMUL_FIELD_001 ? VNx8SFmode
+             : vlmul == VLMUL_FIELD_010 ? VNx16SFmode
+             : vlmul == VLMUL_FIELD_011 ? VNx32SFmode
+                                       : VNx2SFmode;
+
+    case E_DFmode:
+      if (vlmul == VLMUL_FIELD_101 || vlmul == VLMUL_FIELD_110 ||
+          vlmul == VLMUL_FIELD_111)
+        gcc_unreachable ();
+
+      return vlmul == VLMUL_FIELD_000   ? VNx2DFmode
+             : vlmul == VLMUL_FIELD_001 ? VNx4DFmode
+             : vlmul == VLMUL_FIELD_010 ? VNx8DFmode
+                                       : VNx16DFmode;
+
+    default:
+      gcc_unreachable ();
+    }
+
+  gcc_unreachable ();
+}
+
+static bool
+vector_legal_vlmul (scalar_mode inner_mode, enum vlmul_field_enum vlmul)
+{
+  if (vlmul == VLMUL_FIELD_100)
+    return false;
+
+  switch (inner_mode)
+    {
+    case E_HImode:
+      return vlmul != VLMUL_FIELD_101;
+
+    case E_SImode:
+    case E_SFmode:
+      return vlmul != VLMUL_FIELD_101 && vlmul != VLMUL_FIELD_110;
+
+    case E_DImode:
+    case E_DFmode:
+      return vlmul <= VLMUL_FIELD_011;
+
+    default:
+      break;
+    }
+
+  return true;
+}
+
+/* Record that TYPE is an ABI-defined VECTOR type that contains SEW and LMUL
+   information for RVV vector.  MANGLED_NAME, if nonnull, is the ABI-defined
+   mangling of the type.
+ */
+static void
+add_vector_type_attribute (tree type, unsigned int nf, unsigned int sew, unsigned int vlmul,
+			   unsigned int is_bool, const char *mangled_name)
+{
+  tree mangled_name_tree
+    = (mangled_name ? get_identifier (mangled_name) : NULL_TREE);
+
+  tree value = tree_cons (NULL_TREE, mangled_name_tree, NULL_TREE);
+  value = tree_cons (NULL_TREE, size_int (nf), value);
+  value = tree_cons (NULL_TREE, size_int (sew), value);
+  value = tree_cons (NULL_TREE, size_int (vlmul), value);
+  value = tree_cons (NULL_TREE, size_int (is_bool), value);
+  TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("RVV type"), value,
+				      TYPE_ATTRIBUTES (type));
+}
+
+/* These codes copied from ARM. */
+static void
+register_general_builtin_types (void)
+{
+  scalar_types[VECTOR_TYPE_bool] = boolean_type_node;
+  scalar_types[VECTOR_TYPE_int8] = intQI_type_node;
+  scalar_types[VECTOR_TYPE_uint8] = unsigned_intQI_type_node;
+  scalar_types[VECTOR_TYPE_int16] = intHI_type_node;
+  scalar_types[VECTOR_TYPE_uint16] = unsigned_intHI_type_node;
+
+  if (TARGET_64BIT)
+    {
+      scalar_types[VECTOR_TYPE_int32] = intSI_type_node;
+      scalar_types[VECTOR_TYPE_uint32] = unsigned_intSI_type_node;
+    }
+  else
+    {
+      /* int32_t/uint32_t defined as `long`/`unsigned long` in RV32,
+          but intSI_type_node/unsigned_intSI_type_node is
+          `int` and `unsigned int`, so use long_integer_type_node and
+          long_unsigned_type_node here for type consistent.  */
+      scalar_types[VECTOR_TYPE_int32] = long_integer_type_node;
+      scalar_types[VECTOR_TYPE_uint32] = long_unsigned_type_node;
+    }
+
+  scalar_types[VECTOR_TYPE_int64] = intDI_type_node;
+  scalar_types[VECTOR_TYPE_uint64] = unsigned_intDI_type_node;
+  scalar_types[VECTOR_TYPE_float32] = float_type_node;
+  scalar_types[VECTOR_TYPE_float64] = double_type_node;
+
+  /* Pointer type */
+#define DEFINE_SCALAR_PTR_TYPE_NODE(NBITS)                                     \
+  scalar_pointer_types[VECTOR_TYPE_int##NBITS] =                               \
+      build_pointer_type (scalar_types[VECTOR_TYPE_int##NBITS]);               \
+  scalar_pointer_types[VECTOR_TYPE_uint##NBITS] =                              \
+      build_pointer_type (scalar_types[VECTOR_TYPE_uint##NBITS]);              \
+  const_scalar_pointer_types[VECTOR_TYPE_int##NBITS] = build_pointer_type (    \
+      build_type_variant (scalar_types[VECTOR_TYPE_int##NBITS], 1, 0));        \
+  const_scalar_pointer_types[VECTOR_TYPE_uint##NBITS] = build_pointer_type (   \
+      build_type_variant (scalar_types[VECTOR_TYPE_uint##NBITS], 1, 0));
+
+  DEFINE_SCALAR_PTR_TYPE_NODE (8)
+  DEFINE_SCALAR_PTR_TYPE_NODE (16)
+  DEFINE_SCALAR_PTR_TYPE_NODE (32)
+  DEFINE_SCALAR_PTR_TYPE_NODE (64)
+
+  scalar_pointer_types[VECTOR_TYPE_float32] = float_ptr_type_node;
+  scalar_pointer_types[VECTOR_TYPE_float64] = double_ptr_type_node;
+  const_scalar_pointer_types[VECTOR_TYPE_float32] = build_pointer_type (
+      build_type_variant (scalar_types[VECTOR_TYPE_float32], 1, 0));
+  const_scalar_pointer_types[VECTOR_TYPE_float64] = build_pointer_type (
+      build_type_variant (scalar_types[VECTOR_TYPE_float64], 1, 0));
+}
+
+/* Register the built-in VECTOR ABI types, such as __rvv_int8mf8_t.  */
+static void
+register_builtin_types ()
+{
+  for (unsigned int i = 0; i < NUM_VECTOR_TYPES; ++i)
+    {
+      tree eltype = scalar_types[i];
+      scalar_mode elmode =
+          (eltype == boolean_type_node) ? BImode : SCALAR_TYPE_MODE (eltype);
+
+      for (unsigned int j = 0; j < ARRAY_SIZE (vector_vlmuls); ++j)
+        {
+          if (!vector_legal_vlmul (elmode, vector_vlmuls[j].vlmul))
+            continue;
+
+          char abi_name[NAME_MAXLEN] = {0};
+          char mangled_name[NAME_MAXLEN] = {0};
+          bool is_bool;
+          tree vectype;
+          unsigned int sew = GET_MODE_BITSIZE (elmode);
+          machine_mode mode =
+              vector_builtin_mode (elmode, vector_vlmuls[j].vlmul);
+          
+          /* mask type in RVV.  */
+          vectype = build_vector_type_for_mode (eltype, mode);
+
+          /* NOTE: Reference to 'omp_clause_aligned_alignment' function in
+             omp-low.c. We don't know why we need this protection, it seems
+             to make the buildup of GCC more reliable. */
+          if (TYPE_MODE (vectype) != mode)
+            continue;
+                
+          if (eltype == boolean_type_node)
+            {
+              gcc_assert (VECTOR_MODE_P (TYPE_MODE (vectype)) &&
+                          TYPE_MODE (vectype) == mode &&
+                          TYPE_MODE (vectype) == TYPE_MODE_RAW (vectype) &&
+                          TYPE_ALIGN (vectype) == 8 &&
+                          known_eq (tree_to_poly_uint64 (TYPE_SIZE (vectype)),
+                                    BITS_PER_RISCV_VECTOR));
+              is_bool = true;
+            }
+          else
+            {
+              gcc_assert (VECTOR_MODE_P (TYPE_MODE (vectype)) &&
+                          TYPE_MODE (vectype) == mode &&
+                          TYPE_MODE_RAW (vectype) == mode &&
+                          TYPE_ALIGN (vectype) <= 128 &&
+                          known_eq (tree_to_poly_uint64 (TYPE_SIZE (vectype)),
+                                    GET_MODE_BITSIZE (mode)));
+              is_bool = false;
+            }
+          /* These codes copied from ARM. */
+          /* abi_name and api_name follows vector type implementation in LLVM.
+             Take sew = 8, vlmul = 1/8 for example,
+             abi_name = __rvv_int8mf8_t,
+             api_name = vint8mf8_t.
+             The mangle name follows the rule of aarch64
+             that is "u" + length of (abi_name) + abi_name.
+             So that mangle_name = u15__rvv_int8mf8_t.  */
+          snprintf (abi_name, NAME_MAXLEN, "__rvv_%s%s_t",
+                    vector_type_infos[i].elem_name,
+                    is_bool ? vector_vlmuls[j].boolnum
+                            : vector_vlmuls[j].suffix);
+          snprintf (mangled_name, NAME_MAXLEN, "u%d__rvv_%s%s_t",
+                    (int)strlen (abi_name), vector_type_infos[i].elem_name,
+                    is_bool ? vector_vlmuls[j].boolnum
+                            : vector_vlmuls[j].suffix);
+          vectype = build_distinct_type_copy (vectype);
+          gcc_assert (vectype == TYPE_MAIN_VARIANT (vectype));
+          SET_TYPE_STRUCTURAL_EQUALITY (vectype);
+          TYPE_ARTIFICIAL (vectype) = 1;
+          TYPE_INDIVISIBLE_P (vectype) = 1;
+          add_vector_type_attribute (vectype, 1, sew, vector_vlmuls[j].vlmul, is_bool,
+                                     mangled_name);
+          make_type_sizeless (vectype);
+          internal_vector_types[i][j] = vectype;
+          lang_hooks.types.register_builtin_type (vectype, abi_name);
+        }
+    }
+}
+
 /* Initialize all compiler built-ins related to RVV that should be
    defined at start-up.  */
 void
@@ -116,6 +396,192 @@ init_builtins ()
 {
   if (!TARGET_VECTOR)
     return;
+  
+  register_general_builtin_types ();
+  register_builtin_types ();
+
+  if (in_lto_p)
+    handle_pragma_vector ();
+}
+
+/* These codes copied from ARM. */
+/* Register vector type TYPE under its risv_vector.h name.  */
+static void
+register_vector_type (unsigned int type, unsigned int lmul)
+{
+  tree vectype = internal_vector_types[type][lmul];
+  char rvv_name[NAME_MAXLEN] = {0};
+  snprintf (rvv_name, NAME_MAXLEN, "v%s%s_t", vector_type_infos[type].elem_name,
+            strcmp (vector_type_infos[type].elem_name, "bool") == 0
+                ? vector_vlmuls[lmul].boolnum
+                : vector_vlmuls[lmul].suffix);
+  tree id = get_identifier (rvv_name);
+  tree decl = build_decl (input_location, TYPE_DECL, id, vectype);
+  decl = lang_hooks.decls.pushdecl (decl);
+
+  /* Record the new RVV type if pushdecl succeeded without error.  Use
+     the ABI type otherwise, so that the type we record at least has the
+     right form, even if it doesn't have the right name.  This should give
+     better error recovery behavior than installing error_mark_node or
+     installing an incorrect type.  */
+  if (decl && TREE_CODE (decl) == TYPE_DECL &&
+      TREE_TYPE (decl) != error_mark_node &&
+      TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == vectype)
+    vectype = TREE_TYPE (decl);
+
+  vector_types[0][type][lmul] = vectype;
+  vector_pointer_types[type][lmul] = build_pointer_type (vectype);
+}
+
+/* Implement #pragma riscv intrinsic vector.  */
+void
+handle_pragma_vector ()
+{
+  if (function_table)
+    {
+      error ("duplicate definition of %qs", "vector");
+      return;
+    }
+
+  /* Define the vector and tuple types.  */
+  for (unsigned int i = 0; i < NUM_VECTOR_TYPES; ++i)
+    {
+      tree eltype = scalar_types[i];
+      scalar_mode elmode =
+          (eltype == boolean_type_node) ? BImode : SCALAR_TYPE_MODE (eltype);
+
+      for (unsigned int j = 0; j < ARRAY_SIZE (vector_vlmuls); ++j)
+        {
+          if (!vector_legal_vlmul (elmode, vector_vlmuls[j].vlmul))
+            continue;
+            
+          register_vector_type (i, j);
+        }
+    }
+
+  init_def_variables ();
+
+  /* Define the functions.  */
+  function_table = new hash_table<registered_function_hasher> (1023);
+
+  for (unsigned int i = 0; i < NUM_INSN_FUNC; ++i)
+    all_vector_functions[i]->register_function ();
+}
+
+/* If TYPE is an ABI-defined RVV type, return its attribute descriptor,
+   otherwise return null.  */
+static tree
+lookup_rvv_type_attribute (const_tree type)
+{
+  if (type == error_mark_node)
+    return NULL_TREE;
+  return lookup_attribute ("RVV type", TYPE_ATTRIBUTES (type));
+}
+
+/* Return true if TYPE is a built-in RVV type defined by the ABI or RVV.  */
+bool
+builtin_type_p (const_tree type)
+{
+  return lookup_rvv_type_attribute (type);
+}
+
+/* Implement TARGET_VERIFY_TYPE_CONTEXT for RVV types.  */
+bool
+verify_type_context (location_t loc, type_context_kind context,
+                     const_tree type, bool silent_p)
+{
+  if (!sizeless_type_p (type))
+    return true;
+
+  switch (context)
+    {
+    case TCTX_SIZEOF:
+    case TCTX_STATIC_STORAGE:
+      if (!silent_p)
+        error_at (loc, "RVV type %qT does not have a fixed size", type);
+
+      return false;
+
+    case TCTX_ALIGNOF:
+      if (!silent_p)
+        error_at (loc, "RVV type %qT does not have a defined alignment", type);
+
+      return false;
+
+    case TCTX_THREAD_STORAGE:
+      if (!silent_p)
+        error_at (loc,
+                  "variables of type %qT cannot have thread-local"
+                  " storage duration",
+                  type);
+
+      return false;
+
+    case TCTX_POINTER_ARITH:
+      if (!silent_p)
+        error_at (loc, "arithmetic on pointer to RVV type %qT", type);
+
+      return false;
+
+    case TCTX_FIELD:
+      if (silent_p)
+        ;
+      else if (lang_GNU_CXX ())
+        error_at (loc, "member variables cannot have RVV type %qT", type);
+      else
+        error_at (loc, "fields cannot have RVV type %qT", type);
+
+      return false;
+
+    case TCTX_ARRAY_ELEMENT:
+      if (!silent_p)
+        error_at (loc, "array elements cannot have RVV type %qT", type);
+
+      return false;
+
+    case TCTX_ALLOCATION:
+      if (!silent_p)
+        error_at (loc, "cannot allocate objects with RVV type %qT", type);
+
+      return false;
+
+    case TCTX_DEALLOCATION:
+      if (!silent_p)
+        error_at (loc, "cannot delete objects with RVV type %qT", type);
+
+      return false;
+
+    case TCTX_EXCEPTIONS:
+      if (!silent_p)
+        error_at (loc, "cannot throw or catch RVV type %qT", type);
+
+      return false;
+
+    case TCTX_CAPTURE_BY_COPY:
+      if (!silent_p)
+        error_at (loc, "capture by copy of RVV type %qT", type);
+
+      return false;
+    }
+
+  gcc_unreachable ();
+}
+
+/* If TYPE is a built-in type defined by the RVV ABI, return the mangled name,
+   otherwise return NULL.  */
+const char *
+mangle_builtin_type (const_tree type)
+{
+  /* ??? The C++ frontend normally strips qualifiers and attributes before
+     calling this hook, adding separate mangling for attributes that affect
+     type identity.  Fortunately the type copy will have the same TYPE_NAME
+     as the original, so we can get the attributes from there.  */
+  if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
+    type = TREE_TYPE (TYPE_NAME (type));
+  if (tree attr = lookup_rvv_type_attribute (type))
+    if (tree id = TREE_VALUE (chain_index (4, TREE_VALUE (attr))))
+      return IDENTIFIER_POINTER (id);
+  return NULL;
 }
 
 /* Return the function decl with RVV function subcode CODE, or error_mark_node
diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
index 6bba4c90c3a..ef91248035c 100644
--- a/gcc/config/riscv/riscv-vector-builtins.h
+++ b/gcc/config/riscv/riscv-vector-builtins.h
@@ -53,6 +53,9 @@ rtx expand_builtin (unsigned int, tree, rtx);
 bool check_builtin_call (location_t, vec<location_t>, unsigned int,
 			 tree, unsigned int, tree *);
 machine_mode vector_builtin_mode (scalar_mode, enum vlmul_field_enum);
+bool builtin_type_p (const_tree);
+bool verify_type_context (location_t, type_context_kind, const_tree, bool);
+const char * mangle_builtin_type (const_tree);
 
 } // end namespace riscv_vector
 
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index b82a38da7c9..8c78e726a19 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -67,6 +67,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-vectorizer.h"
 #include "tree-ssa-loop-niter.h"
 #include "rtx-vector-builder.h"
+#include "riscv-vector-builtins.h"
+#include "riscv-vector.h"
 
 /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF.  */
 #define UNSPEC_ADDRESS_P(X)					\
@@ -5780,6 +5782,124 @@ riscv_asan_shadow_offset (void)
   return TARGET_64BIT ? (HOST_WIDE_INT_1 << 29) : 0;
 }
 
+/* Implement TARGET_VECTOR_MODE_SUPPORTED_P.  */
+
+static bool
+riscv_vector_mode_supported_p (machine_mode mode)
+{
+  if (TARGET_VECTOR && rvv_mode_p (mode))
+    return true;
+
+  return false;
+}
+
+/* Implement TARGET_VECTOR_ALIGNMENT.  */
+
+static HOST_WIDE_INT
+riscv_vector_alignment (const_tree type)
+{
+  /* ??? Checking the mode isn't ideal, but VECTOR_BOOLEAN_TYPE_P can
+     be set for non-predicate vectors of booleans.  Modes are the most
+     direct way we have of identifying real RVV predicate types.  */
+  /* FIXME: RVV didn't mention the alignment of bool, we uses
+     one byte align.  */
+  if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_VECTOR_BOOL)
+    return 8;
+
+  widest_int min_size =
+      constant_lower_bound (wi::to_poly_widest (TYPE_SIZE (type)));
+  return wi::umin (min_size, 128).to_uhwi ();
+}
+
+/* Implement target hook TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT.  */
+
+static poly_uint64
+riscv_vectorize_preferred_vector_alignment (const_tree type)
+{
+  if (rvv_mode_p (TYPE_MODE (type)))
+    {
+      /* If the length of the vector is a fixed power of 2, try to align
+      to that length, otherwise don't try to align at all.  */
+      HOST_WIDE_INT result;
+
+      if (!GET_MODE_BITSIZE (TYPE_MODE (type)).is_constant (&result) ||
+          !pow2p_hwi (result))
+        result = TYPE_ALIGN (TREE_TYPE (type));
+
+      return result;
+    }
+
+  return default_preferred_vector_alignment (type);
+}
+
+/* Implement target hook TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE.  */
+
+static bool
+riscv_simd_vector_alignment_reachable (const_tree type, bool is_packed)
+{
+  if (is_packed)
+    return false;
+
+  /* For fixed-length vectors, check that the vectorizer will aim for
+     full-vector alignment.  This isn't true for generic GCC vectors
+     that are wider than the ABI maximum of 128 bits.  */
+  poly_uint64 preferred_alignment =
+      riscv_vectorize_preferred_vector_alignment (type);
+  if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST &&
+      maybe_ne (wi::to_widest (TYPE_SIZE (type)), preferred_alignment))
+    return false;
+
+  /* Vectors whose size is <= BIGGEST_ALIGNMENT are naturally aligned.  */
+  return true;
+}
+
+/* Return true if the vector misalignment factor is supported by the
+   target.  */
+
+static bool
+riscv_builtin_support_vector_misalignment (machine_mode mode, const_tree type,
+                                           int misalignment, bool is_packed)
+{
+  return default_builtin_support_vector_misalignment (mode, type, misalignment,
+                                                      is_packed);
+}
+
+/* Implement TARGET_COMPATIBLE_VECTOR_TYPES_P.  */
+
+static bool
+riscv_compatible_vector_types_p (const_tree type1, const_tree type2)
+{
+  return (riscv_vector::builtin_type_p (type1) ==
+          riscv_vector::builtin_type_p (type2));
+}
+
+/* Implement TARGET_VERIFY_TYPE_CONTEXT.  */
+
+static bool
+riscv_verify_type_context (location_t loc, type_context_kind context,
+                           const_tree type, bool silent_p)
+{
+  return riscv_vector::verify_type_context (loc, context, type, silent_p);
+}
+
+/* Implement TARGET_MANGLE_TYPE.  */
+
+static const char *
+riscv_mangle_type (const_tree type)
+{
+  /* Mangle all vector type for vector extension.  */
+  /* The mangle name follows the rule of aarch64
+     that is "u" + length of (abi_name) + abi_name. */
+  if (TYPE_NAME (type) != NULL)
+    {
+      const char *res = riscv_vector::mangle_builtin_type (type);
+      if (res)
+        return res;
+    }
+  /* Use the default mangling.  */
+  return NULL;
+}
+
 /* Initialize the GCC target structure.  */
 #undef TARGET_ASM_ALIGNED_HI_OP
 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
@@ -5974,6 +6094,30 @@ riscv_asan_shadow_offset (void)
 #define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_ENDIAN)
 #endif
 
+#undef TARGET_VECTOR_MODE_SUPPORTED_P
+#define TARGET_VECTOR_MODE_SUPPORTED_P riscv_vector_mode_supported_p
+
+#undef TARGET_VECTOR_ALIGNMENT
+#define TARGET_VECTOR_ALIGNMENT riscv_vector_alignment
+
+#undef TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT
+#define TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT riscv_vectorize_preferred_vector_alignment
+
+#undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
+#define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE riscv_simd_vector_alignment_reachable
+
+#undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
+#define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT riscv_builtin_support_vector_misalignment
+
+#undef TARGET_COMPATIBLE_VECTOR_TYPES_P
+#define TARGET_COMPATIBLE_VECTOR_TYPES_P riscv_compatible_vector_types_p
+
+#undef TARGET_VERIFY_TYPE_CONTEXT
+#define TARGET_VERIFY_TYPE_CONTEXT riscv_verify_type_context
+
+#undef TARGET_MANGLE_TYPE
+#define TARGET_MANGLE_TYPE riscv_mangle_type
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-riscv.h"
-- 
2.36.1




  parent reply	other threads:[~2022-05-31  8:50 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-31  8:49 [PATCH 00/21] *** Add RVV (RISC-V 'V' Extension) support *** juzhe.zhong
2022-05-31  8:49 ` [PATCH 01/21] Add RVV modes and support scalable vector juzhe.zhong
2022-05-31  8:49 ` [PATCH 02/21] Add RVV intrinsic framework juzhe.zhong
2022-05-31  8:49 ` juzhe.zhong [this message]
2022-05-31  8:49 ` [PATCH 04/21] Add RVV intrinsic enable #pragma riscv intrinsic "vector" and introduce RVV header "riscv_vector.h" juzhe.zhong
2022-05-31  8:49 ` [PATCH 05/21] Add RVV configuration intrinsic juzhe.zhong
2022-05-31  8:49 ` [PATCH 06/21] Add insert-vsetvl pass juzhe.zhong
2022-05-31  8:49 ` [PATCH 07/21] Add register spilling support juzhe.zhong
2022-05-31  8:49 ` [PATCH 08/21] Add poly manipulation juzhe.zhong
2022-05-31  8:50 ` [PATCH 09/21] Add misc function intrinsic support juzhe.zhong
2022-05-31  8:50 ` [PATCH 11/21] Add calling function support juzhe.zhong
2022-05-31  8:50 ` [PATCH 12/21] Add set get intrinsic support juzhe.zhong
2022-05-31  8:50 ` [PATCH 13/21] Adjust scalable frame and full testcases juzhe.zhong
2022-05-31  8:50 ` [PATCH 15/21] Add integer intrinsics juzhe.zhong
2022-05-31  8:50 ` [PATCH 18/21] Add rest intrinsic support juzhe.zhong
2022-05-31 16:51 ` [PATCH 00/21] *** Add RVV (RISC-V 'V' Extension) support *** Palmer Dabbelt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220531085012.269719-4-juzhe.zhong@rivai.ai \
    --to=juzhe.zhong@rivai.ai \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=kito.cheng@gmail.com \
    --cc=palmer@dabbelt.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).