mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-16 17:14:41 +02:00
8264104: Eliminate unnecessary vector mask conversion during VectorUnbox for floating point VectorMask
Reviewed-by: kvn, vlivanov
This commit is contained in:
parent
64e21307a8
commit
e0151a6fb1
9 changed files with 103 additions and 1 deletions
|
@ -3334,6 +3334,36 @@ instruct storemask2L(vecD dst, vecX src, immI_8 size)
|
||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// vector mask cast
|
||||||
|
|
||||||
|
instruct vmaskcastD(vecD dst)
|
||||||
|
%{
|
||||||
|
predicate(n->bottom_type()->is_vect()->length_in_bytes() == 8 &&
|
||||||
|
n->in(1)->bottom_type()->is_vect()->length_in_bytes() == 8 &&
|
||||||
|
n->bottom_type()->is_vect()->length() == n->in(1)->bottom_type()->is_vect()->length());
|
||||||
|
match(Set dst (VectorMaskCast dst));
|
||||||
|
ins_cost(0);
|
||||||
|
format %{ "vmaskcast $dst\t# empty" %}
|
||||||
|
ins_encode %{
|
||||||
|
// empty
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_class_empty);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct vmaskcastX(vecX dst)
|
||||||
|
%{
|
||||||
|
predicate(n->bottom_type()->is_vect()->length_in_bytes() == 16 &&
|
||||||
|
n->in(1)->bottom_type()->is_vect()->length_in_bytes() == 16 &&
|
||||||
|
n->bottom_type()->is_vect()->length() == n->in(1)->bottom_type()->is_vect()->length());
|
||||||
|
match(Set dst (VectorMaskCast dst));
|
||||||
|
ins_cost(0);
|
||||||
|
format %{ "vmaskcast $dst\t# empty" %}
|
||||||
|
ins_encode %{
|
||||||
|
// empty
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_class_empty);
|
||||||
|
%}
|
||||||
|
|
||||||
//-------------------------------- LOAD_IOTA_INDICES----------------------------------
|
//-------------------------------- LOAD_IOTA_INDICES----------------------------------
|
||||||
|
|
||||||
instruct loadcon8B(vecD dst, immI0 src)
|
instruct loadcon8B(vecD dst, immI0 src)
|
||||||
|
|
|
@ -1258,6 +1258,27 @@ instruct storemask2L(vecD dst, vecX src, immI_8 size)
|
||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// vector mask cast
|
||||||
|
dnl
|
||||||
|
define(`VECTOR_MASK_CAST', `
|
||||||
|
instruct vmaskcast$1`'(vec$1 dst)
|
||||||
|
%{
|
||||||
|
predicate(n->bottom_type()->is_vect()->length_in_bytes() == $2 &&
|
||||||
|
n->in(1)->bottom_type()->is_vect()->length_in_bytes() == $2 &&
|
||||||
|
n->bottom_type()->is_vect()->length() == n->in(1)->bottom_type()->is_vect()->length());
|
||||||
|
match(Set dst (VectorMaskCast dst));
|
||||||
|
ins_cost(0);
|
||||||
|
format %{ "vmaskcast $dst\t# empty" %}
|
||||||
|
ins_encode %{
|
||||||
|
// empty
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_class_empty);
|
||||||
|
%}')dnl
|
||||||
|
dnl $1 $2
|
||||||
|
VECTOR_MASK_CAST(D, 8)
|
||||||
|
VECTOR_MASK_CAST(X, 16)
|
||||||
|
dnl
|
||||||
|
|
||||||
//-------------------------------- LOAD_IOTA_INDICES----------------------------------
|
//-------------------------------- LOAD_IOTA_INDICES----------------------------------
|
||||||
dnl
|
dnl
|
||||||
define(`PREDICATE', `ifelse($1, 8,
|
define(`PREDICATE', `ifelse($1, 8,
|
||||||
|
|
|
@ -1760,3 +1760,18 @@ instruct vsubD(vReg dst, vReg src1, vReg src2) %{
|
||||||
%}
|
%}
|
||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// vector mask cast
|
||||||
|
|
||||||
|
instruct vmaskcast(vReg dst) %{
|
||||||
|
predicate(UseSVE > 0 && n->bottom_type()->is_vect()->length() == n->in(1)->bottom_type()->is_vect()->length() &&
|
||||||
|
n->bottom_type()->is_vect()->length_in_bytes() == n->in(1)->bottom_type()->is_vect()->length_in_bytes());
|
||||||
|
match(Set dst (VectorMaskCast dst));
|
||||||
|
ins_cost(0);
|
||||||
|
format %{ "vmaskcast $dst\t# empty (sve)" %}
|
||||||
|
ins_encode %{
|
||||||
|
// empty
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_class_empty);
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
|
@ -904,3 +904,18 @@ BINARY_OP_UNPREDICATED(vsubI, SubVI, S, 4, sve_sub)
|
||||||
BINARY_OP_UNPREDICATED(vsubL, SubVL, D, 2, sve_sub)
|
BINARY_OP_UNPREDICATED(vsubL, SubVL, D, 2, sve_sub)
|
||||||
BINARY_OP_UNPREDICATED(vsubF, SubVF, S, 4, sve_fsub)
|
BINARY_OP_UNPREDICATED(vsubF, SubVF, S, 4, sve_fsub)
|
||||||
BINARY_OP_UNPREDICATED(vsubD, SubVD, D, 2, sve_fsub)
|
BINARY_OP_UNPREDICATED(vsubD, SubVD, D, 2, sve_fsub)
|
||||||
|
|
||||||
|
// vector mask cast
|
||||||
|
|
||||||
|
instruct vmaskcast(vReg dst) %{
|
||||||
|
predicate(UseSVE > 0 && n->bottom_type()->is_vect()->length() == n->in(1)->bottom_type()->is_vect()->length() &&
|
||||||
|
n->bottom_type()->is_vect()->length_in_bytes() == n->in(1)->bottom_type()->is_vect()->length_in_bytes());
|
||||||
|
match(Set dst (VectorMaskCast dst));
|
||||||
|
ins_cost(0);
|
||||||
|
format %{ "vmaskcast $dst\t# empty (sve)" %}
|
||||||
|
ins_encode %{
|
||||||
|
// empty
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_class_empty);
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
|
@ -4200,7 +4200,8 @@ bool MatchRule::is_vector() const {
|
||||||
"FmaVD", "FmaVF","PopCountVI",
|
"FmaVD", "FmaVF","PopCountVI",
|
||||||
// Next are not supported currently.
|
// Next are not supported currently.
|
||||||
"PackB","PackS","PackI","PackL","PackF","PackD","Pack2L","Pack2D",
|
"PackB","PackS","PackI","PackL","PackF","PackD","Pack2L","Pack2D",
|
||||||
"ExtractB","ExtractUB","ExtractC","ExtractS","ExtractI","ExtractL","ExtractF","ExtractD"
|
"ExtractB","ExtractUB","ExtractC","ExtractS","ExtractI","ExtractL","ExtractF","ExtractD",
|
||||||
|
"VectorMaskCast"
|
||||||
};
|
};
|
||||||
int cnt = sizeof(vector_list)/sizeof(char*);
|
int cnt = sizeof(vector_list)/sizeof(char*);
|
||||||
if (_rChild) {
|
if (_rChild) {
|
||||||
|
|
|
@ -446,6 +446,7 @@ macro(VectorBoxAllocate)
|
||||||
macro(VectorUnbox)
|
macro(VectorUnbox)
|
||||||
macro(VectorMaskWrapper)
|
macro(VectorMaskWrapper)
|
||||||
macro(VectorMaskCmp)
|
macro(VectorMaskCmp)
|
||||||
|
macro(VectorMaskCast)
|
||||||
macro(VectorTest)
|
macro(VectorTest)
|
||||||
macro(VectorBlend)
|
macro(VectorBlend)
|
||||||
macro(VectorRearrange)
|
macro(VectorRearrange)
|
||||||
|
|
|
@ -1232,6 +1232,13 @@ Node* VectorUnboxNode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
||||||
bool is_vector_mask = vbox_klass->is_subclass_of(ciEnv::current()->vector_VectorMask_klass());
|
bool is_vector_mask = vbox_klass->is_subclass_of(ciEnv::current()->vector_VectorMask_klass());
|
||||||
bool is_vector_shuffle = vbox_klass->is_subclass_of(ciEnv::current()->vector_VectorShuffle_klass());
|
bool is_vector_shuffle = vbox_klass->is_subclass_of(ciEnv::current()->vector_VectorShuffle_klass());
|
||||||
if (is_vector_mask) {
|
if (is_vector_mask) {
|
||||||
|
if (in_vt->length_in_bytes() == out_vt->length_in_bytes() &&
|
||||||
|
Matcher::match_rule_supported_vector(Op_VectorMaskCast, out_vt->length(), out_vt->element_basic_type())) {
|
||||||
|
// Apply "VectorUnbox (VectorBox vmask) ==> VectorMaskCast (vmask)"
|
||||||
|
// directly. This could avoid the transformation ordering issue from
|
||||||
|
// "VectorStoreMask (VectorLoadMask vmask) => vmask".
|
||||||
|
return new VectorMaskCastNode(value, out_vt);
|
||||||
|
}
|
||||||
// VectorUnbox (VectorBox vmask) ==> VectorLoadMask (VectorStoreMask vmask)
|
// VectorUnbox (VectorBox vmask) ==> VectorLoadMask (VectorStoreMask vmask)
|
||||||
value = phase->transform(VectorStoreMaskNode::make(*phase, value, in_vt->element_basic_type(), in_vt->length()));
|
value = phase->transform(VectorStoreMaskNode::make(*phase, value, in_vt->element_basic_type(), in_vt->length()));
|
||||||
return new VectorLoadMaskNode(value, out_vt);
|
return new VectorLoadMaskNode(value, out_vt);
|
||||||
|
|
|
@ -1240,6 +1240,17 @@ class VectorStoreMaskNode : public VectorNode {
|
||||||
static VectorStoreMaskNode* make(PhaseGVN& gvn, Node* in, BasicType in_type, uint num_elem);
|
static VectorStoreMaskNode* make(PhaseGVN& gvn, Node* in, BasicType in_type, uint num_elem);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class VectorMaskCastNode : public VectorNode {
|
||||||
|
public:
|
||||||
|
VectorMaskCastNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {
|
||||||
|
const TypeVect* in_vt = in->bottom_type()->is_vect();
|
||||||
|
assert(in_vt->length() == vt->length(), "vector length must match");
|
||||||
|
assert(type2aelembytes(in_vt->element_basic_type()) == type2aelembytes(vt->element_basic_type()), "element size must match");
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int Opcode() const;
|
||||||
|
};
|
||||||
|
|
||||||
// This is intended for use as a simple reinterpret node that has no cast.
|
// This is intended for use as a simple reinterpret node that has no cast.
|
||||||
class VectorReinterpretNode : public VectorNode {
|
class VectorReinterpretNode : public VectorNode {
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1878,6 +1878,7 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
|
||||||
declare_c2_type(VectorInsertNode, VectorNode) \
|
declare_c2_type(VectorInsertNode, VectorNode) \
|
||||||
declare_c2_type(VectorUnboxNode, VectorNode) \
|
declare_c2_type(VectorUnboxNode, VectorNode) \
|
||||||
declare_c2_type(VectorReinterpretNode, VectorNode) \
|
declare_c2_type(VectorReinterpretNode, VectorNode) \
|
||||||
|
declare_c2_type(VectorMaskCastNode, VectorNode) \
|
||||||
declare_c2_type(VectorBoxNode, Node) \
|
declare_c2_type(VectorBoxNode, Node) \
|
||||||
declare_c2_type(VectorBoxAllocateNode, CallStaticJavaNode) \
|
declare_c2_type(VectorBoxAllocateNode, CallStaticJavaNode) \
|
||||||
declare_c2_type(VectorTestNode, Node) \
|
declare_c2_type(VectorTestNode, Node) \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue