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)