gcc/ChangeLog:
* config.gcc (extra_objs): Include vector pass.
* config/riscv/t-riscv : Likewise.
* config/riscv/riscv-pass.c : New.
* config/riscv/riscv.opt (-mdelete-vsetvl): Likewise.
---
gcc/config.gcc | 2 +-
gcc/config/riscv/riscv-pass.c | 195 ++++++++++++++++++++++++++++++++++
gcc/config/riscv/riscv.opt | 4 +
gcc/config/riscv/t-riscv | 4 +
4 files changed, 204 insertions(+), 1 deletion(-)
create mode 100755 gcc/config/riscv/riscv-pass.c
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 4c4db7bcb7b..4308670746a 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -512,7 +512,7 @@ powerpc*-*-*)
;;
riscv*)
cpu_type=riscv
- extra_objs="riscv-builtins.o riscv-c.o"
+ extra_objs="riscv-builtins.o riscv-c.o riscv-pass.o"
d_target_objs="riscv-d.o"
extra_headers="riscv-vector.h"
;;
diff --git a/gcc/config/riscv/riscv-pass.c b/gcc/config/riscv/riscv-pass.c
new file mode 100755
index 00000000000..376eeead1d2
--- /dev/null
+++ b/gcc/config/riscv/riscv-pass.c
@@ -0,0 +1,195 @@
+/* Subroutines used for code generation for RISC-V.
+ Copyright (C) 2011-2018 Free Software Foundation, Inc.
+ Contributed by Andrew Waterman ([email protected]).
+ Based on MIPS target for GNU compiler.
+
+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/>. */
+
+#define IN_TARGET_CODE 1
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "regs.h"
+#include "insn-config.h"
+#include "insn-attr.h"
+#include "recog.h"
+#include "output.h"
+#include "alias.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "attribs.h"
+#include "varasm.h"
+#include "stor-layout.h"
+#include "calls.h"
+#include "function.h"
+#include "explow.h"
+#include "memmodel.h"
+#include "emit-rtl.h"
+#include "reload.h"
+#include "tm_p.h"
+#include "target.h"
+#include "target-def.h"
+#include "basic-block.h"
+#include "expr.h"
+#include "optabs.h"
+#include "bitmap.h"
+#include "df.h"
+#include "diagnostic.h"
+#include "builtins.h"
+#include "predict.h"
+#include "backend.h"
+#include "pass_manager.h"
+#include "tree-pass.h"
+#include "context.h"
+#include "cfgrtl.h"
+
+
+static unsigned int
+xck_dvsetvl (void)
+{
+ basic_block bb;
+ rtx_insn *insn;
+
+ rtx pat;
+ rtx vector_insn;
+ rtx_insn *vsetvl_insn;
+ int unspec;
+
+ FOR_EACH_BB_FN (bb, cfun)
+ {
+ vector_insn = NULL_RTX;
+ vsetvl_insn = NULL;
+
+ FOR_BB_INSNS_REVERSE (bb, insn)
+ {
+ if (!NONDEBUG_INSN_P (insn))
+ continue;
+
+ if (!NONJUMP_INSN_P(insn))
+ vsetvl_insn = NULL;
+
+ pat = PATTERN (insn);
+
+ if (GET_CODE (pat) == PARALLEL)
+ pat = XVECEXP (pat, 0, 0);
+
+ if (GET_CODE (pat) != SET)
+ continue;
+
+ pat = SET_SRC (pat);
+
+ if (GET_CODE (pat) != UNSPEC)
+ continue;
+
+ unspec = XINT (pat, 1);
+
+ if (unspec >= UNSPEC_VSTART
+ && unspec <= UNSPEC_VEND)
+ vector_insn = insn;
+
+ if (unspec == UNSPEC_VSETVLI
+ || unspec == UNSPEC_VSETVLI_MAX
+ || unspec == UNSPEC_VSETVLR)
+ {
+ if (vsetvl_insn
+ && rtx_equal_p(PATTERN(vsetvl_insn), PATTERN(insn)))
+ {
+ bool deletex = true;
+
+ if (unspec == UNSPEC_VSETVLI
+ && reg_set_between_p(XVECEXP (pat, 0, 0), insn,
vsetvl_insn))
+ deletex = false;
+
+ if (unspec == UNSPEC_VSETVLR
+ && (reg_set_between_p(XVECEXP (pat, 0, 0), insn,
vsetvl_insn)
+ || reg_set_between_p(XVECEXP (pat, 0, 1), insn,
vsetvl_insn)))
+ deletex = false;
+
+ if (deletex)
+ delete_insn(vsetvl_insn);
+ }
+
+ vsetvl_insn = insn;
+ vector_insn = NULL_RTX;
+ }
+ }
+ }
+ return 0;
+}
+
+const pass_data pass_data_xck_dvsetvl =
+{
+ RTL_PASS, /* type */
+ "dvsetvl", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_df_finish, /* todo_flags_finish */
+};
+
+class pass_xck_dvsetvl : public rtl_opt_pass
+{
+public:
+ pass_xck_dvsetvl (gcc::context *ctxt)
+ : rtl_opt_pass (pass_data_xck_dvsetvl, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate (function *) { return TARGET_VECTOR && riscv_insn_dvsetvl; }
+ unsigned int execute (function *) { return xck_dvsetvl (); }
+};
+
+rtl_opt_pass *
+make_pass_xck_dvsetvl (gcc::context *ctxt)
+{
+ return new pass_xck_dvsetvl (ctxt);
+}
+
+
+void
+xck_register_pass (
+ rtl_opt_pass *(*make_pass_func) (gcc::context *),
+ enum pass_positioning_ops pass_pos,
+ const char *ref_pass_name)
+{
+ opt_pass *new_opt_pass = make_pass_func (g);
+
+ struct register_pass_info insert_pass =
+ {
+ new_opt_pass, /* pass */
+ ref_pass_name, /* reference_pass_name */
+ 1, /* ref_pass_instance_number */
+ pass_pos /* po_op */
+ };
+
+ register_pass (&insert_pass);
+}
+
+void
+xck_register_passes (void)
+{
+ xck_register_pass (
+ make_pass_xck_dvsetvl,
+ PASS_POS_INSERT_BEFORE,
+ "final");
+}
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 25c5c9d3545..e73ac70feae 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -128,6 +128,10 @@ Target Bool Var(riscv_mrelax) Init(1)
Take advantage of linker relaxations to reduce the number of instructions
required to materialize symbol addresses.
+mdelete-vsetvl
+Target Report Var(riscv_insn_dvsetvl) Init(1) Undocumented
+Optimize code by deleting redundancy vsetvl.
+
Mask(64BIT)
Mask(MUL)
diff --git a/gcc/config/riscv/t-riscv b/gcc/config/riscv/t-riscv
index ece3a75d512..eead8aa5f9f 100644
--- a/gcc/config/riscv/t-riscv
+++ b/gcc/config/riscv/t-riscv
@@ -14,3 +14,7 @@ riscv-d.o: $(srcdir)/config/riscv/riscv-d.c
$(COMPILE) $<
$(POSTCOMPILE)
+riscv-pass.o: $(srcdir)/config/riscv/riscv-pass.c $(CONFIG_H) $(SYSTEM_H) \
+ coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H) $(TARGET_H)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/riscv/riscv-pass.c
--
2.24.3 (Apple Git-128)