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
next prev 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).