Skip to content

Commit 124c63c

Browse files
author
Xiaohong Gong
committed
8288294: [vector] Add Identity/Ideal transformations for vector logic operations
Reviewed-by: kvn, jbhateja
1 parent 918068a commit 124c63c

File tree

4 files changed

+639
-10
lines changed

4 files changed

+639
-10
lines changed

src/hotspot/share/opto/vectornode.cpp

+108-4
Original file line numberDiff line numberDiff line change
@@ -828,27 +828,42 @@ bool VectorNode::is_vector_shift_count(int opc) {
828828
}
829829
}
830830

831-
static bool is_con_M1(Node* n) {
831+
static bool is_con(Node* n, long con) {
832832
if (n->is_Con()) {
833833
const Type* t = n->bottom_type();
834-
if (t->isa_int() && t->is_int()->get_con() == -1) {
834+
if (t->isa_int() && t->is_int()->get_con() == (int)con) {
835835
return true;
836836
}
837-
if (t->isa_long() && t->is_long()->get_con() == -1) {
837+
if (t->isa_long() && t->is_long()->get_con() == con) {
838838
return true;
839839
}
840840
}
841841
return false;
842842
}
843843

844+
// Return true if every bit in this vector is 1.
844845
bool VectorNode::is_all_ones_vector(Node* n) {
845846
switch (n->Opcode()) {
846847
case Op_ReplicateB:
847848
case Op_ReplicateS:
848849
case Op_ReplicateI:
849850
case Op_ReplicateL:
850851
case Op_MaskAll:
851-
return is_con_M1(n->in(1));
852+
return is_con(n->in(1), -1);
853+
default:
854+
return false;
855+
}
856+
}
857+
858+
// Return true if every bit in this vector is 0.
859+
bool VectorNode::is_all_zeros_vector(Node* n) {
860+
switch (n->Opcode()) {
861+
case Op_ReplicateB:
862+
case Op_ReplicateS:
863+
case Op_ReplicateI:
864+
case Op_ReplicateL:
865+
case Op_MaskAll:
866+
return is_con(n->in(1), 0);
852867
default:
853868
return false;
854869
}
@@ -1776,6 +1791,95 @@ Node* ReverseVNode::Identity(PhaseGVN* phase) {
17761791
return this;
17771792
}
17781793

1794+
Node* AndVNode::Identity(PhaseGVN* phase) {
1795+
// (AndV src (Replicate m1)) => src
1796+
// (AndVMask src (MaskAll m1)) => src
1797+
if (VectorNode::is_all_ones_vector(in(2))) {
1798+
return in(1);
1799+
}
1800+
// (AndV (Replicate zero) src) => (Replicate zero)
1801+
// (AndVMask (MaskAll zero) src) => (MaskAll zero)
1802+
if (VectorNode::is_all_zeros_vector(in(1))) {
1803+
return in(1);
1804+
}
1805+
// The following transformations are only applied to
1806+
// the un-predicated operation, since the VectorAPI
1807+
// masked operation requires the unmasked lanes to
1808+
// save the same values in the first operand.
1809+
if (!is_predicated_vector()) {
1810+
// (AndV (Replicate m1) src) => src
1811+
// (AndVMask (MaskAll m1) src) => src
1812+
if (VectorNode::is_all_ones_vector(in(1))) {
1813+
return in(2);
1814+
}
1815+
// (AndV src (Replicate zero)) => (Replicate zero)
1816+
// (AndVMask src (MaskAll zero)) => (MaskAll zero)
1817+
if (VectorNode::is_all_zeros_vector(in(2))) {
1818+
return in(2);
1819+
}
1820+
}
1821+
1822+
// (AndV src src) => src
1823+
// (AndVMask src src) => src
1824+
if (in(1) == in(2)) {
1825+
return in(1);
1826+
}
1827+
return this;
1828+
}
1829+
1830+
Node* OrVNode::Identity(PhaseGVN* phase) {
1831+
// (OrV (Replicate m1) src) => (Replicate m1)
1832+
// (OrVMask (MaskAll m1) src) => (MaskAll m1)
1833+
if (VectorNode::is_all_ones_vector(in(1))) {
1834+
return in(1);
1835+
}
1836+
// (OrV src (Replicate zero)) => src
1837+
// (OrVMask src (MaskAll zero)) => src
1838+
if (VectorNode::is_all_zeros_vector(in(2))) {
1839+
return in(1);
1840+
}
1841+
// The following transformations are only applied to
1842+
// the un-predicated operation, since the VectorAPI
1843+
// masked operation requires the unmasked lanes to
1844+
// save the same values in the first operand.
1845+
if (!is_predicated_vector()) {
1846+
// (OrV src (Replicate m1)) => (Replicate m1)
1847+
// (OrVMask src (MaskAll m1)) => (MaskAll m1)
1848+
if (VectorNode::is_all_ones_vector(in(2))) {
1849+
return in(2);
1850+
}
1851+
// (OrV (Replicate zero) src) => src
1852+
// (OrVMask (MaskAll zero) src) => src
1853+
if (VectorNode::is_all_zeros_vector(in(1))) {
1854+
return in(2);
1855+
}
1856+
}
1857+
1858+
// (OrV src src) => src
1859+
// (OrVMask src src) => src
1860+
if (in(1) == in(2)) {
1861+
return in(1);
1862+
}
1863+
return this;
1864+
}
1865+
1866+
Node* XorVNode::Ideal(PhaseGVN* phase, bool can_reshape) {
1867+
// (XorV src src) => (Replicate zero)
1868+
// (XorVMask src src) => (MaskAll zero)
1869+
//
1870+
// The transformation is only applied to the un-predicated
1871+
// operation, since the VectorAPI masked operation requires
1872+
// the unmasked lanes to save the same values in the first
1873+
// operand.
1874+
if (!is_predicated_vector() && (in(1) == in(2))) {
1875+
BasicType bt = vect_type()->element_basic_type();
1876+
Node* zero = phase->transform(phase->zerocon(bt));
1877+
return VectorNode::scalar2vector(zero, length(), Type::get_const_basic_type(bt),
1878+
bottom_type()->isa_vectmask() != NULL);
1879+
}
1880+
return NULL;
1881+
}
1882+
17791883
#ifndef PRODUCT
17801884
void VectorBoxAllocateNode::dump_spec(outputStream *st) const {
17811885
CallStaticJavaNode::dump_spec(st);

src/hotspot/share/opto/vectornode.hpp

+12-6
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,10 @@ class VectorNode : public TypeNode {
103103
static bool is_vector_integral_negate_supported(int opc, uint vlen, BasicType bt, bool use_predicate);
104104
static bool is_populate_index_supported(BasicType bt);
105105
static bool is_invariant_vector(Node* n);
106+
// Return true if every bit in this vector is 1.
106107
static bool is_all_ones_vector(Node* n);
108+
// Return true if every bit in this vector is 0.
109+
static bool is_all_zeros_vector(Node* n);
107110
static bool is_vector_bitwise_not_pattern(Node* n);
108111
static Node* degenerate_vector_rotate(Node* n1, Node* n2, bool is_rotate_left, int vlen,
109112
BasicType bt, PhaseGVN* phase);
@@ -714,6 +717,7 @@ class AndVNode : public VectorNode {
714717
public:
715718
AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
716719
virtual int Opcode() const;
720+
virtual Node* Identity(PhaseGVN* phase);
717721
};
718722

719723
//------------------------------AndReductionVNode--------------------------------------
@@ -730,6 +734,7 @@ class OrVNode : public VectorNode {
730734
public:
731735
OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
732736
virtual int Opcode() const;
737+
virtual Node* Identity(PhaseGVN* phase);
733738
};
734739

735740
//------------------------------OrReductionVNode--------------------------------------
@@ -754,6 +759,7 @@ class XorVNode : public VectorNode {
754759
public:
755760
XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
756761
virtual int Opcode() const;
762+
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
757763
};
758764

759765
//------------------------------MinReductionVNode--------------------------------------
@@ -1069,23 +1075,23 @@ class MaskAllNode : public VectorNode {
10691075
};
10701076

10711077
//--------------------------- Vector mask logical and --------------------------------
1072-
class AndVMaskNode : public VectorNode {
1078+
class AndVMaskNode : public AndVNode {
10731079
public:
1074-
AndVMaskNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
1080+
AndVMaskNode(Node* in1, Node* in2, const TypeVect* vt) : AndVNode(in1, in2, vt) {}
10751081
virtual int Opcode() const;
10761082
};
10771083

10781084
//--------------------------- Vector mask logical or ---------------------------------
1079-
class OrVMaskNode : public VectorNode {
1085+
class OrVMaskNode : public OrVNode {
10801086
public:
1081-
OrVMaskNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
1087+
OrVMaskNode(Node* in1, Node* in2, const TypeVect* vt) : OrVNode(in1, in2, vt) {}
10821088
virtual int Opcode() const;
10831089
};
10841090

10851091
//--------------------------- Vector mask logical xor --------------------------------
1086-
class XorVMaskNode : public VectorNode {
1092+
class XorVMaskNode : public XorVNode {
10871093
public:
1088-
XorVMaskNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
1094+
XorVMaskNode(Node* in1, Node* in2, const TypeVect* vt) : XorVNode(in1, in2, vt) {}
10891095
virtual int Opcode() const;
10901096
};
10911097

test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java

+7
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,13 @@ public class IRNode {
191191
public static final String POPCOUNT_L = START + "PopCountL" + MID + END;
192192
public static final String PHI = START + "Phi" + MID + END;
193193

194+
public static final String AND_V = START + "AndV" + MID + END;
195+
public static final String OR_V = START + "OrV" + MID + END;
196+
public static final String XOR_V = START + "XorV" + MID + END;
197+
public static final String AND_V_MASK = START + "AndVMask" + MID + END;
198+
public static final String OR_V_MASK = START + "OrVMask" + MID + END;
199+
public static final String XOR_V_MASK = START + "XorVMask" + MID + END;
200+
194201
public static final String VECTOR_CAST_B2X = START + "VectorCastB2X" + MID + END;
195202
public static final String VECTOR_CAST_S2X = START + "VectorCastS2X" + MID + END;
196203
public static final String VECTOR_CAST_I2X = START + "VectorCastI2X" + MID + END;

0 commit comments

Comments
 (0)