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 (and...@sifive.com).
+   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)

Reply via email to