Skip to content

Commit

Permalink
8295261: RISC-V: Support ReductionV instructions for Vector API
Browse files Browse the repository at this point in the history
Reviewed-by: yadongwang, dzhang, fyang, eliu
  • Loading branch information
zifeihan authored and RealFYang committed Nov 7, 2022
1 parent 556377a commit 087cedc
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 3 deletions.
28 changes: 28 additions & 0 deletions src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp
Expand Up @@ -1689,3 +1689,31 @@ bool C2_MacroAssembler::in_scratch_emit_size() {
}
return MacroAssembler::in_scratch_emit_size();
}

void C2_MacroAssembler::reduce_operation(Register dst, VectorRegister tmp,
Register src1, VectorRegister src2,
BasicType bt, REDUCTION_OP op) {
Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
vsetvli(t0, x0, sew);

vmv_s_x(tmp, src1);

switch (op) {
case REDUCTION_OP::ADD:
vredsum_vs(tmp, src2, tmp);
break;
case REDUCTION_OP::AND:
vredand_vs(tmp, src2, tmp);
break;
case REDUCTION_OP::OR:
vredor_vs(tmp, src2, tmp);
break;
case REDUCTION_OP::XOR:
vredxor_vs(tmp, src2, tmp);
break;
default:
ShouldNotReachHere();
}

vmv_x_s(dst, tmp);
}
4 changes: 4 additions & 0 deletions src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp
Expand Up @@ -195,4 +195,8 @@
VectorRegister tmp1, VectorRegister tmp2,
bool is_double, bool is_min);

void reduce_operation(Register dst, VectorRegister tmp,
Register src1, VectorRegister src2,
BasicType bt, REDUCTION_OP op);

#endif // CPU_RISCV_C2_MACROASSEMBLER_RISCV_HPP
3 changes: 3 additions & 0 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
Expand Up @@ -1300,4 +1300,7 @@ class SkipIfEqual {
~SkipIfEqual();
};

// reduction related operations
enum REDUCTION_OP {ADD, AND, OR, XOR};

#endif // CPU_RISCV_MACROASSEMBLER_RISCV_HPP
105 changes: 102 additions & 3 deletions src/hotspot/cpu/riscv/riscv_v.ad
Expand Up @@ -63,9 +63,6 @@ source %{
case Op_ExtractS:
case Op_ExtractUB:
// Vector API specific
case Op_AndReductionV:
case Op_OrReductionV:
case Op_XorReductionV:
case Op_LoadVectorGather:
case Op_StoreVectorScatter:
case Op_VectorBlend:
Expand Down Expand Up @@ -809,6 +806,108 @@ instruct vnegD(vReg dst, vReg src) %{
ins_pipe(pipe_slow);
%}

// vector and reduction

instruct reduce_andI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
predicate(Matcher::vector_element_basic_type(n->in(2)) != T_LONG);
match(Set dst (AndReductionV src1 src2));
effect(TEMP tmp);
ins_cost(VEC_COST);
format %{ "vmv.s.x $tmp, $src1\t#@reduce_andI\n\t"
"vredand.vs $tmp, $src2, $tmp\n\t"
"vmv.x.s $dst, $tmp" %}
ins_encode %{
BasicType bt = Matcher::vector_element_basic_type(this, $src2);
__ reduce_operation($dst$$Register, as_VectorRegister($tmp$$reg),
$src1$$Register, as_VectorRegister($src2$$reg), bt, REDUCTION_OP::AND);
%}
ins_pipe(pipe_slow);
%}

instruct reduce_andL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
match(Set dst (AndReductionV src1 src2));
effect(TEMP tmp);
ins_cost(VEC_COST);
format %{ "vmv.s.x $tmp, $src1\t#@reduce_andL\n\t"
"vredand.vs $tmp, $src2, $tmp\n\t"
"vmv.x.s $dst, $tmp" %}
ins_encode %{
BasicType bt = Matcher::vector_element_basic_type(this, $src2);
__ reduce_operation($dst$$Register, as_VectorRegister($tmp$$reg),
$src1$$Register, as_VectorRegister($src2$$reg), bt, REDUCTION_OP::AND);
%}
ins_pipe(pipe_slow);
%}

// vector or reduction

instruct reduce_orI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
predicate(Matcher::vector_element_basic_type(n->in(2)) != T_LONG);
match(Set dst (OrReductionV src1 src2));
effect(TEMP tmp);
ins_cost(VEC_COST);
format %{ "vmv.s.x $tmp, $src1\t#@reduce_orI\n\t"
"vredor.vs $tmp, $src2, $tmp\n\t"
"vmv.x.s $dst, $tmp" %}
ins_encode %{
BasicType bt = Matcher::vector_element_basic_type(this, $src2);
__ reduce_operation($dst$$Register, as_VectorRegister($tmp$$reg),
$src1$$Register, as_VectorRegister($src2$$reg), bt, REDUCTION_OP::OR);
%}
ins_pipe(pipe_slow);
%}

instruct reduce_orL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
match(Set dst (OrReductionV src1 src2));
effect(TEMP tmp);
ins_cost(VEC_COST);
format %{ "vmv.s.x $tmp, $src1\t#@reduce_orL\n\t"
"vredor.vs $tmp, $src2, $tmp\n\t"
"vmv.x.s $dst, $tmp" %}
ins_encode %{
BasicType bt = Matcher::vector_element_basic_type(this, $src2);
__ reduce_operation($dst$$Register, as_VectorRegister($tmp$$reg),
$src1$$Register, as_VectorRegister($src2$$reg), bt, REDUCTION_OP::OR);
%}
ins_pipe(pipe_slow);
%}

// vector xor reduction

instruct reduce_xorI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
predicate(Matcher::vector_element_basic_type(n->in(2)) != T_LONG);
match(Set dst (XorReductionV src1 src2));
effect(TEMP tmp);
ins_cost(VEC_COST);
format %{ "vmv.s.x $tmp, $src1\t#@reduce_xorI\n\t"
"vredxor.vs $tmp, $src2, $tmp\n\t"
"vmv.x.s $dst, $tmp" %}
ins_encode %{
BasicType bt = Matcher::vector_element_basic_type(this, $src2);
__ reduce_operation($dst$$Register, as_VectorRegister($tmp$$reg),
$src1$$Register, as_VectorRegister($src2$$reg), bt, REDUCTION_OP::XOR);
%}
ins_pipe(pipe_slow);
%}

instruct reduce_xorL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{
predicate(Matcher::vector_element_basic_type(n->in(2)) == T_LONG);
match(Set dst (XorReductionV src1 src2));
effect(TEMP tmp);
ins_cost(VEC_COST);
format %{ "vmv.s.x $tmp, $src1\t#@reduce_xorL\n\t"
"vredxor.vs $tmp, $src2, $tmp\n\t"
"vmv.x.s $dst, $tmp" %}
ins_encode %{
BasicType bt = Matcher::vector_element_basic_type(this, $src2);
__ reduce_operation($dst$$Register, as_VectorRegister($tmp$$reg),
$src1$$Register, as_VectorRegister($src2$$reg), bt, REDUCTION_OP::XOR);
%}
ins_pipe(pipe_slow);
%}

// vector add reduction

instruct reduce_addB(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{
Expand Down

1 comment on commit 087cedc

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.