#include "targhooks.h"
#include "predict.h"
#include "errors.h"
+#include "riscv-v.h"
using namespace riscv_vector;
e.emit_insn ((enum insn_code) icode, ops);
}
-class rvv_builder : public rtx_vector_builder
-{
-public:
- rvv_builder () : rtx_vector_builder () {}
- rvv_builder (machine_mode mode, unsigned int npatterns,
- unsigned int nelts_per_pattern)
- : rtx_vector_builder (mode, npatterns, nelts_per_pattern)
- {
- m_inner_mode = GET_MODE_INNER (mode);
- m_inner_bits_size = GET_MODE_BITSIZE (m_inner_mode);
- m_inner_bytes_size = GET_MODE_SIZE (m_inner_mode);
- m_mask_mode = get_mask_mode (mode);
-
- gcc_assert (
- int_mode_for_size (inner_bits_size (), 0).exists (&m_inner_int_mode));
- m_int_mode
- = get_vector_mode (m_inner_int_mode, GET_MODE_NUNITS (mode)).require ();
- }
-
- bool can_duplicate_repeating_sequence_p ();
- bool is_repeating_sequence ();
- rtx get_merged_repeating_sequence ();
-
- bool repeating_sequence_use_merge_profitable_p ();
- bool combine_sequence_use_slideup_profitable_p ();
- bool combine_sequence_use_merge_profitable_p ();
- rtx get_merge_scalar_mask (unsigned int, machine_mode) const;
-
- bool single_step_npatterns_p () const;
- bool npatterns_all_equal_p () const;
- bool interleaved_stepped_npatterns_p () const;
- bool npatterns_vid_diff_repeated_p () const;
-
- machine_mode new_mode () const { return m_new_mode; }
- scalar_mode inner_mode () const { return m_inner_mode; }
- scalar_int_mode inner_int_mode () const { return m_inner_int_mode; }
- machine_mode mask_mode () const { return m_mask_mode; }
- machine_mode int_mode () const { return m_int_mode; }
- unsigned int inner_bits_size () const { return m_inner_bits_size; }
- unsigned int inner_bytes_size () const { return m_inner_bytes_size; }
-
-private:
- scalar_mode m_inner_mode;
- scalar_int_mode m_inner_int_mode;
- machine_mode m_new_mode;
- scalar_int_mode m_new_inner_mode;
- machine_mode m_mask_mode;
- machine_mode m_int_mode;
- unsigned int m_inner_bits_size;
- unsigned int m_inner_bytes_size;
-};
-
/* Return true if the vector duplicated by a super element which is the fusion
of consecutive elements.
--- /dev/null
+/* Subroutines used for code generation for RISC-V 'V' Extension for
+ GNU compiler.
+ Copyright (C) 2022-2024 Free Software Foundation, Inc.
+ Contributed by Juzhe Zhong (juzhe.zhong@rivai.ai), RiVAI Technologies Ltd.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_RISCV_V_H
+#define GCC_RISCV_V_H
+
+#include "rtx-vector-builder.h"
+
+using namespace riscv_vector;
+
+namespace riscv_vector {
+
+extern machine_mode get_mask_mode (machine_mode);
+extern opt_machine_mode get_vector_mode (scalar_mode, poly_uint64);
+
+class rvv_builder : public rtx_vector_builder
+{
+public:
+ rvv_builder () : rtx_vector_builder () {}
+ rvv_builder (machine_mode mode, unsigned int npatterns,
+ unsigned int nelts_per_pattern)
+ : rtx_vector_builder (mode, npatterns, nelts_per_pattern)
+ {
+ m_inner_mode = GET_MODE_INNER (mode);
+ m_inner_bits_size = GET_MODE_BITSIZE (m_inner_mode);
+ m_inner_bytes_size = GET_MODE_SIZE (m_inner_mode);
+ m_mask_mode = get_mask_mode (mode);
+
+ gcc_assert (
+ int_mode_for_size (inner_bits_size (), 0).exists (&m_inner_int_mode));
+ m_int_mode
+ = get_vector_mode (m_inner_int_mode, GET_MODE_NUNITS (mode)).require ();
+ }
+
+ bool can_duplicate_repeating_sequence_p ();
+ bool is_repeating_sequence ();
+ rtx get_merged_repeating_sequence ();
+
+ bool repeating_sequence_use_merge_profitable_p ();
+ bool combine_sequence_use_slideup_profitable_p ();
+ bool combine_sequence_use_merge_profitable_p ();
+ rtx get_merge_scalar_mask (unsigned int, machine_mode) const;
+
+ bool single_step_npatterns_p () const;
+ bool npatterns_all_equal_p () const;
+ bool interleaved_stepped_npatterns_p () const;
+ bool npatterns_vid_diff_repeated_p () const;
+
+ machine_mode new_mode () const { return m_new_mode; }
+ scalar_mode inner_mode () const { return m_inner_mode; }
+ scalar_int_mode inner_int_mode () const { return m_inner_int_mode; }
+ machine_mode mask_mode () const { return m_mask_mode; }
+ machine_mode int_mode () const { return m_int_mode; }
+ unsigned int inner_bits_size () const { return m_inner_bits_size; }
+ unsigned int inner_bytes_size () const { return m_inner_bytes_size; }
+
+private:
+ scalar_mode m_inner_mode;
+ scalar_int_mode m_inner_int_mode;
+ machine_mode m_new_mode;
+ scalar_int_mode m_new_inner_mode;
+ machine_mode m_mask_mode;
+ machine_mode m_int_mode;
+ unsigned int m_inner_bits_size;
+ unsigned int m_inner_bytes_size;
+};
+
+} // namespace riscv_vector
+
+#endif // GCC_RISCV_V_H
#include "gcse.h"
#include "tree-dfa.h"
#include "target-globals.h"
+#include "riscv-v.h"
/* This file should be included last. */
#include "target-def.h"
rtx elt;
if (const_vec_duplicate_p (x, &elt))
{
+ if (GET_MODE_CLASS (GET_MODE (x)) == MODE_VECTOR_BOOL)
+ /* Duplicate values of 0/1 can be emitted using vmv.v.i. */
+ return 1;
+
/* We don't allow CONST_VECTOR for DI vector on RV32
system since the ELT constant value can not held
within a single register to disable reload a DI
accurately according to BASE && STEP. */
return 1;
}
+
+ if (CONST_VECTOR_STEPPED_P (x))
+ {
+ /* Some cases are unhandled so we need construct a builder to
+ detect/allow those cases to be handled by the fallthrough
+ handler. */
+ unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
+ unsigned int npatterns = CONST_VECTOR_NPATTERNS (x);
+ rvv_builder builder (GET_MODE(x), npatterns, nelts_per_pattern);
+ for (unsigned int i = 0; i < nelts_per_pattern; i++)
+ {
+ for (unsigned int j = 0; j < npatterns; j++)
+ builder.quick_push (CONST_VECTOR_ELT (x, i * npatterns + j));
+ }
+ builder.finalize ();
+
+ if (builder.single_step_npatterns_p ())
+ {
+ if (builder.npatterns_all_equal_p ())
+ {
+ /* TODO: This cost is not accurate. */
+ return 1;
+ }
+ else
+ {
+ /* TODO: This cost is not accurate. */
+ return 1;
+ }
+ }
+ else if (builder.interleaved_stepped_npatterns_p ())
+ {
+ /* TODO: This cost is not accurate. */
+ return 1;
+ }
+
+ /* Fallthrough. */
+ }
}
/* TODO: We may support more const vector in the future. */