From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2093) id 614D23858D20; Fri, 21 Apr 2023 06:46:26 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 614D23858D20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1682059586; bh=/oDOV04RI4jVkA3RjGUfx7LTXGY7iHLS4hS3ac9KKOQ=; h=From:To:Subject:Date:From; b=Wrvgk7JO3xBdkXt5MEjlR5j512NVWoiWAI94vyKaCYjIPsPNAy/Dia53w+S5jo3YW oiOq2TaMv0aO5sTBZdMWUSBirLfaX3gMz64Ht5LrCmFrypNbspRxQB83k01jNNBc1G 9NWyPlqTDbYxiWFUqJvsC1Z2eee/VBaAdBHqeYHI= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Kito Cheng To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-129] RISC-V: Add local user vsetvl instruction elimination [PR109547] X-Act-Checkin: gcc X-Git-Author: Juzhe-Zhong X-Git-Refname: refs/heads/master X-Git-Oldrev: ce4e4f37fd12f4335c25f508f9fa40492a408556 X-Git-Newrev: d51f2456ee51bd59a79b4725ca0e488c25260bbf Message-Id: <20230421064626.614D23858D20@sourceware.org> Date: Fri, 21 Apr 2023 06:46:26 +0000 (GMT) List-Id: https://gcc.gnu.org/g:d51f2456ee51bd59a79b4725ca0e488c25260bbf commit r14-129-gd51f2456ee51bd59a79b4725ca0e488c25260bbf Author: Juzhe-Zhong Date: Fri Apr 7 09:34:13 2023 +0800 RISC-V: Add local user vsetvl instruction elimination [PR109547] This patch is to enhance optimization for auto-vectorization. Before this patch: Loop: vsetvl a5,a2... vsetvl zero,a5... vle After this patch: Loop: vsetvl a5,a2 vle gcc/ChangeLog: PR target/109547 * config/riscv/riscv-vsetvl.cc (local_eliminate_vsetvl_insn): New function. (vector_insn_info::skip_avl_compatible_p): Ditto. (vector_insn_info::merge): Remove default value. (pass_vsetvl::compute_local_backward_infos): Ditto. (pass_vsetvl::cleanup_insns): Add local vsetvl elimination. * config/riscv/riscv-vsetvl.h: Ditto. gcc/testsuite/ChangeLog: PR target/109547 * gcc.target/riscv/rvv/vsetvl/pr109547.c: New. * gcc.target/riscv/rvv/vsetvl/vsetvl-17.c: Update scan condition. Diff: --- gcc/config/riscv/riscv-vsetvl.cc | 71 +++++++++++++++++++++- gcc/config/riscv/riscv-vsetvl.h | 1 + .../gcc.target/riscv/rvv/vsetvl/pr109547.c | 14 +++++ .../gcc.target/riscv/rvv/vsetvl/vsetvl-17.c | 2 +- 4 files changed, 85 insertions(+), 3 deletions(-) diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index 9c356ce5157..2406931dac0 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -1054,6 +1054,51 @@ change_vsetvl_insn (const insn_info *insn, const vector_insn_info &info) change_insn (rinsn, new_pat); } +static void +local_eliminate_vsetvl_insn (const vector_insn_info &dem) +{ + const insn_info *insn = dem.get_insn (); + if (!insn || insn->is_artificial ()) + return; + rtx_insn *rinsn = insn->rtl (); + const bb_info *bb = insn->bb (); + if (vsetvl_insn_p (rinsn)) + { + rtx vl = get_vl (rinsn); + for (insn_info *i = insn->next_nondebug_insn (); + real_insn_and_same_bb_p (i, bb); i = i->next_nondebug_insn ()) + { + if (i->is_call () || i->is_asm () + || find_access (i->defs (), VL_REGNUM) + || find_access (i->defs (), VTYPE_REGNUM)) + return; + + if (has_vtype_op (i->rtl ())) + { + if (!vsetvl_discard_result_insn_p (PREV_INSN (i->rtl ()))) + return; + rtx avl = get_avl (i->rtl ()); + if (avl != vl) + return; + set_info *def = find_access (i->uses (), REGNO (avl))->def (); + if (def->insn () != insn) + return; + + vector_insn_info new_info; + new_info.parse_insn (i); + if (!new_info.skip_avl_compatible_p (dem)) + return; + + new_info.set_avl_info (dem.get_avl_info ()); + new_info = dem.merge (new_info, LOCAL_MERGE); + change_vsetvl_insn (insn, new_info); + eliminate_insn (PREV_INSN (i->rtl ())); + return; + } + } + } +} + static bool source_equal_p (insn_info *insn1, insn_info *insn2) { @@ -1996,6 +2041,19 @@ vector_insn_info::compatible_p (const vector_insn_info &other) const return true; } +bool +vector_insn_info::skip_avl_compatible_p (const vector_insn_info &other) const +{ + gcc_assert (valid_or_dirty_p () && other.valid_or_dirty_p () + && "Can't compare invalid demanded infos"); + unsigned array_size = sizeof (incompatible_conds) / sizeof (demands_cond); + /* Bypass AVL incompatible cases. */ + for (unsigned i = 1; i < array_size; i++) + if (incompatible_conds[i].dual_incompatible_p (*this, other)) + return false; + return true; +} + bool vector_insn_info::compatible_avl_p (const vl_vtype_info &other) const { @@ -2190,7 +2248,7 @@ vector_insn_info::fuse_mask_policy (const vector_insn_info &info1, vector_insn_info vector_insn_info::merge (const vector_insn_info &merge_info, - enum merge_type type = LOCAL_MERGE) const + enum merge_type type) const { if (!vsetvl_insn_p (get_insn ()->rtl ())) gcc_assert (this->compatible_p (merge_info) @@ -2696,7 +2754,7 @@ pass_vsetvl::compute_local_backward_infos (const bb_info *bb) && !reg_available_p (insn, change)) && change.compatible_p (info)) { - info = change.merge (info); + info = change.merge (info, LOCAL_MERGE); /* Fix PR109399, we should update user vsetvl instruction if there is a change in demand fusion. */ if (vsetvl_insn_p (insn->rtl ())) @@ -3925,6 +3983,15 @@ pass_vsetvl::cleanup_insns (void) const for (insn_info *insn : bb->real_nondebug_insns ()) { rtx_insn *rinsn = insn->rtl (); + const auto &dem = m_vector_manager->vector_insn_infos[insn->uid ()]; + /* Eliminate local vsetvl: + bb 0: + vsetvl a5,a6,... + vsetvl zero,a5. + + Eliminate vsetvl in bb2 when a5 is only coming from + bb 0. */ + local_eliminate_vsetvl_insn (dem); if (vlmax_avl_insn_p (rinsn)) { diff --git a/gcc/config/riscv/riscv-vsetvl.h b/gcc/config/riscv/riscv-vsetvl.h index 237381f7026..4fe08cfc789 100644 --- a/gcc/config/riscv/riscv-vsetvl.h +++ b/gcc/config/riscv/riscv-vsetvl.h @@ -380,6 +380,7 @@ public: void fuse_mask_policy (const vector_insn_info &, const vector_insn_info &); bool compatible_p (const vector_insn_info &) const; + bool skip_avl_compatible_p (const vector_insn_info &) const; bool compatible_avl_p (const vl_vtype_info &) const; bool compatible_avl_p (const avl_info &) const; bool compatible_vtype_p (const vl_vtype_info &) const; diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr109547.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr109547.c new file mode 100644 index 00000000000..88dd87709ab --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr109547.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -fno-schedule-insns -fno-schedule-insns2" } */ + +#include "riscv_vector.h" + +void func(unsigned char *out, unsigned char *in, unsigned long len) { + unsigned long i = 0; + while (i < len) { + unsigned long vl = __riscv_vsetvl_e8m1(len - i); + vuint8m1_t r = __riscv_vle8_v_u8m1(in + i, vl); + __riscv_vse8_v_u8m1(out + i, r, vl); + i += vl; + } +/* { dg-final { scan-assembler-times {vsetvli} 1 { target { no-opts "-O0" no-opts "-g" no-opts "-funroll-loops" } } } } */} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl-17.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl-17.c index ee58f9bbdfc..8a1bbb40fc8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl-17.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl-17.c @@ -11,4 +11,4 @@ void foo(int32_t *in1, int32_t *in2, int32_t *in3, int32_t *out, size_t n, int c __riscv_vse32_v_i32m1(out, c, __riscv_vsetvl_e8mf2 (vl)); } -/* { dg-final { scan-assembler-times {vsetvli} 8 { target { no-opts "-O0" no-opts "-g" no-opts "-funroll-loops" } } } } */ \ No newline at end of file +/* { dg-final { scan-assembler-times {vsetvli} 7 { target { no-opts "-O0" no-opts "-g" no-opts "-funroll-loops" } } } } */