< prev index next >
src/hotspot/share/opto/vectornode.cpp
Print this page
*** 22,31 ****
--- 22,32 ----
*/
#include "precompiled.hpp"
#include "memory/allocation.inline.hpp"
#include "opto/connode.hpp"
+ #include "opto/subnode.hpp"
#include "opto/vectornode.hpp"
#include "utilities/powerOfTwo.hpp"
//------------------------------VectorNode--------------------------------------
*** 115,130 ****
--- 116,170 ----
default: ShouldNotReachHere(); return 0;
}
case Op_AbsL:
assert(bt == T_LONG, "must be");
return Op_AbsVL;
+ case Op_MinI:
+ switch (bt) {
+ case T_BOOLEAN:
+ case T_CHAR: return 0;
+ case T_BYTE:
+ case T_SHORT:
+ case T_INT: return Op_MinV;
+ default: ShouldNotReachHere(); return 0;
+ }
+ case Op_MinL:
+ assert(bt == T_LONG, "must be");
+ return Op_MinV;
+ case Op_MinF:
+ assert(bt == T_FLOAT, "must be");
+ return Op_MinV;
+ case Op_MinD:
+ assert(bt == T_DOUBLE, "must be");
+ return Op_MinV;
+ case Op_MaxI:
+ switch (bt) {
+ case T_BOOLEAN:
+ case T_CHAR: return 0;
+ case T_BYTE:
+ case T_SHORT:
+ case T_INT: return Op_MaxV;
+ default: ShouldNotReachHere(); return 0;
+ }
+ case Op_MaxL:
+ assert(bt == T_LONG, "must be");
+ return Op_MaxV;
+ case Op_MaxF:
+ assert(bt == T_FLOAT, "must be");
+ return Op_MaxV;
+ case Op_MaxD:
+ assert(bt == T_DOUBLE, "must be");
+ return Op_MaxV;
case Op_AbsF:
assert(bt == T_FLOAT, "must be");
return Op_AbsVF;
case Op_AbsD:
assert(bt == T_DOUBLE, "must be");
return Op_AbsVD;
+ case Op_NegI:
+ assert(bt == T_INT, "must be");
+ return Op_NegVI;
case Op_NegF:
assert(bt == T_FLOAT, "must be");
return Op_NegVF;
case Op_NegD:
assert(bt == T_DOUBLE, "must be");
*** 136,145 ****
--- 176,187 ----
assert(bt == T_FLOAT, "must be");
return Op_SqrtVF;
case Op_SqrtD:
assert(bt == T_DOUBLE, "must be");
return Op_SqrtVD;
+ case Op_Not:
+ return Op_NotV;
case Op_PopCountI:
if (bt == T_INT) {
return Op_PopCountVI;
}
// Unimplemented for subword types since bit count changes
*** 167,176 ****
--- 209,224 ----
default: ShouldNotReachHere(); return 0;
}
case Op_RShiftL:
assert(bt == T_LONG, "must be");
return Op_RShiftVL;
+ case Op_URShiftB:
+ assert(bt == T_BYTE, "must be");
+ return Op_URShiftVB;
+ case Op_URShiftS:
+ assert(bt == T_SHORT, "must be");
+ return Op_URShiftVS;
case Op_URShiftI:
switch (bt) {
case T_BOOLEAN:return Op_URShiftVB;
case T_CHAR: return Op_URShiftVS;
case T_BYTE:
*** 192,213 ****
case Op_OrL:
return Op_OrV;
case Op_XorI:
case Op_XorL:
return Op_XorV;
- case Op_MinF:
- assert(bt == T_FLOAT, "must be");
- return Op_MinV;
- case Op_MinD:
- assert(bt == T_DOUBLE, "must be");
- return Op_MinV;
- case Op_MaxF:
- assert(bt == T_FLOAT, "must be");
- return Op_MaxV;
- case Op_MaxD:
- assert(bt == T_DOUBLE, "must be");
- return Op_MaxV;
case Op_LoadB:
case Op_LoadUB:
case Op_LoadUS:
case Op_LoadS:
--- 240,249 ----
*** 230,239 ****
--- 266,298 ----
default:
return 0; // Unimplemented
}
}
+ int VectorNode::replicate_opcode(BasicType bt) {
+ switch(bt) {
+ case T_BOOLEAN:
+ case T_BYTE:
+ return Op_ReplicateB;
+ case T_SHORT:
+ case T_CHAR:
+ return Op_ReplicateS;
+ case T_INT:
+ return Op_ReplicateI;
+ case T_LONG:
+ return Op_ReplicateL;
+ case T_FLOAT:
+ return Op_ReplicateF;
+ case T_DOUBLE:
+ return Op_ReplicateD;
+ default:
+ break;
+ }
+
+ return 0;
+ }
+
// Also used to check if the code generator
// supports the vector operation.
bool VectorNode::implemented(int opc, uint vlen, BasicType bt) {
if (is_java_primitive(bt) &&
(vlen > 1) && is_power_of_2(vlen) &&
*** 282,291 ****
--- 341,382 ----
default:
return false;
}
}
+ bool VectorNode::is_vshift(Node* n) {
+ switch (n->Opcode()) {
+ case Op_LShiftVB:
+ case Op_LShiftVS:
+ case Op_LShiftVI:
+ case Op_LShiftVL:
+
+ case Op_RShiftVB:
+ case Op_RShiftVS:
+ case Op_RShiftVI:
+ case Op_RShiftVL:
+
+ case Op_URShiftVB:
+ case Op_URShiftVS:
+ case Op_URShiftVI:
+ case Op_URShiftVL:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool VectorNode::is_vshift_cnt(Node* n) {
+ switch (n->Opcode()) {
+ case Op_LShiftCntV:
+ case Op_RShiftCntV:
+ return true;
+ default:
+ return false;
+ }
+ }
+
// Check if input is loop invariant vector.
bool VectorNode::is_invariant_vector(Node* n) {
// Only Replicate vector nodes are loop invariant for now.
switch (n->Opcode()) {
case Op_ReplicateB:
*** 348,363 ****
*start = 1;
*end = n->req(); // default is all operands
}
}
! // Return the vector version of a scalar operation node.
! VectorNode* VectorNode::make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt) {
! const TypeVect* vt = TypeVect::make(bt, vlen);
! int vopc = VectorNode::opcode(opc, bt);
// This method should not be called for unimplemented vectors.
! guarantee(vopc > 0, "Vector for '%s' is not implemented", NodeClassNames[opc]);
switch (vopc) {
case Op_AddVB: return new AddVBNode(n1, n2, vt);
case Op_AddVS: return new AddVSNode(n1, n2, vt);
case Op_AddVI: return new AddVINode(n1, n2, vt);
case Op_AddVL: return new AddVLNode(n1, n2, vt);
--- 439,452 ----
*start = 1;
*end = n->req(); // default is all operands
}
}
! // Make a vector node for binary operation
! VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, const TypeVect* vt) {
// This method should not be called for unimplemented vectors.
! guarantee(vopc > 0, "vopc must be > 0");
switch (vopc) {
case Op_AddVB: return new AddVBNode(n1, n2, vt);
case Op_AddVS: return new AddVSNode(n1, n2, vt);
case Op_AddVI: return new AddVINode(n1, n2, vt);
case Op_AddVL: return new AddVLNode(n1, n2, vt);
*** 379,402 ****
case Op_MulVD: return new MulVDNode(n1, n2, vt);
case Op_DivVF: return new DivVFNode(n1, n2, vt);
case Op_DivVD: return new DivVDNode(n1, n2, vt);
case Op_AbsVB: return new AbsVBNode(n1, vt);
case Op_AbsVS: return new AbsVSNode(n1, vt);
case Op_AbsVI: return new AbsVINode(n1, vt);
case Op_AbsVL: return new AbsVLNode(n1, vt);
- case Op_AbsVF: return new AbsVFNode(n1, vt);
- case Op_AbsVD: return new AbsVDNode(n1, vt);
case Op_NegVF: return new NegVFNode(n1, vt);
case Op_NegVD: return new NegVDNode(n1, vt);
case Op_SqrtVF: return new SqrtVFNode(n1, vt);
case Op_SqrtVD: return new SqrtVDNode(n1, vt);
case Op_PopCountVI: return new PopCountVINode(n1, vt);
case Op_LShiftVB: return new LShiftVBNode(n1, n2, vt);
case Op_LShiftVS: return new LShiftVSNode(n1, n2, vt);
case Op_LShiftVI: return new LShiftVINode(n1, n2, vt);
case Op_LShiftVL: return new LShiftVLNode(n1, n2, vt);
--- 468,497 ----
case Op_MulVD: return new MulVDNode(n1, n2, vt);
case Op_DivVF: return new DivVFNode(n1, n2, vt);
case Op_DivVD: return new DivVDNode(n1, n2, vt);
+ case Op_MinV: return new MinVNode(n1, n2, vt);
+ case Op_MaxV: return new MaxVNode(n1, n2, vt);
+
+ case Op_AbsV: return new AbsVNode(n1, vt);
+ case Op_AbsVF: return new AbsVFNode(n1, vt);
+ case Op_AbsVD: return new AbsVDNode(n1, vt);
case Op_AbsVB: return new AbsVBNode(n1, vt);
case Op_AbsVS: return new AbsVSNode(n1, vt);
case Op_AbsVI: return new AbsVINode(n1, vt);
case Op_AbsVL: return new AbsVLNode(n1, vt);
+ case Op_NegVI: return new NegVINode(n1, vt);
case Op_NegVF: return new NegVFNode(n1, vt);
case Op_NegVD: return new NegVDNode(n1, vt);
case Op_SqrtVF: return new SqrtVFNode(n1, vt);
case Op_SqrtVD: return new SqrtVDNode(n1, vt);
case Op_PopCountVI: return new PopCountVINode(n1, vt);
+ case Op_NotV: return new NotVNode(n1, vt);
case Op_LShiftVB: return new LShiftVBNode(n1, n2, vt);
case Op_LShiftVS: return new LShiftVSNode(n1, n2, vt);
case Op_LShiftVI: return new LShiftVINode(n1, n2, vt);
case Op_LShiftVL: return new LShiftVLNode(n1, n2, vt);
*** 409,448 ****
case Op_URShiftVB: return new URShiftVBNode(n1, n2, vt);
case Op_URShiftVS: return new URShiftVSNode(n1, n2, vt);
case Op_URShiftVI: return new URShiftVINode(n1, n2, vt);
case Op_URShiftVL: return new URShiftVLNode(n1, n2, vt);
case Op_AndV: return new AndVNode(n1, n2, vt);
case Op_OrV: return new OrVNode (n1, n2, vt);
case Op_XorV: return new XorVNode(n1, n2, vt);
- case Op_MinV: return new MinVNode(n1, n2, vt);
- case Op_MaxV: return new MaxVNode(n1, n2, vt);
-
case Op_RoundDoubleModeV: return new RoundDoubleModeVNode(n1, n2, vt);
case Op_MulAddVS2VI: return new MulAddVS2VINode(n1, n2, vt);
default:
fatal("Missed vector creation for '%s'", NodeClassNames[vopc]);
return NULL;
}
}
! VectorNode* VectorNode::make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt) {
const TypeVect* vt = TypeVect::make(bt, vlen);
int vopc = VectorNode::opcode(opc, bt);
// This method should not be called for unimplemented vectors.
guarantee(vopc > 0, "Vector for '%s' is not implemented", NodeClassNames[opc]);
switch (vopc) {
case Op_FmaVD: return new FmaVDNode(n1, n2, n3, vt);
case Op_FmaVF: return new FmaVFNode(n1, n2, n3, vt);
default:
fatal("Missed vector creation for '%s'", NodeClassNames[vopc]);
return NULL;
}
}
// Scalar promotion
VectorNode* VectorNode::scalar2vector(Node* s, uint vlen, const Type* opd_t) {
BasicType bt = opd_t->array_element_basic_type();
const TypeVect* vt = opd_t->singleton() ? TypeVect::make(opd_t, vlen)
: TypeVect::make(bt, vlen);
--- 504,562 ----
case Op_URShiftVB: return new URShiftVBNode(n1, n2, vt);
case Op_URShiftVS: return new URShiftVSNode(n1, n2, vt);
case Op_URShiftVI: return new URShiftVINode(n1, n2, vt);
case Op_URShiftVL: return new URShiftVLNode(n1, n2, vt);
+ // Variable shift left
+ case Op_VLShiftV: return new VLShiftVNode(n1, n2, vt);
+ case Op_VRShiftV: return new VRShiftVNode(n1, n2, vt);
+ case Op_VURShiftV: return new VURShiftVNode(n1, n2, vt);
+
case Op_AndV: return new AndVNode(n1, n2, vt);
case Op_OrV: return new OrVNode (n1, n2, vt);
case Op_XorV: return new XorVNode(n1, n2, vt);
case Op_RoundDoubleModeV: return new RoundDoubleModeVNode(n1, n2, vt);
case Op_MulAddVS2VI: return new MulAddVS2VINode(n1, n2, vt);
default:
fatal("Missed vector creation for '%s'", NodeClassNames[vopc]);
return NULL;
}
}
! // Return the vector version of a scalar binary operation node.
! VectorNode* VectorNode::make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt) {
const TypeVect* vt = TypeVect::make(bt, vlen);
int vopc = VectorNode::opcode(opc, bt);
// This method should not be called for unimplemented vectors.
guarantee(vopc > 0, "Vector for '%s' is not implemented", NodeClassNames[opc]);
+ return make(vopc, n1, n2, vt);
+ }
+
+ // Make a vector node for ternary operation
+ VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, Node* n3, const TypeVect* vt) {
+ // This method should not be called for unimplemented vectors.
+ guarantee(vopc > 0, "vopc must be > 0");
switch (vopc) {
case Op_FmaVD: return new FmaVDNode(n1, n2, n3, vt);
case Op_FmaVF: return new FmaVFNode(n1, n2, n3, vt);
default:
fatal("Missed vector creation for '%s'", NodeClassNames[vopc]);
return NULL;
}
}
+ // Return the vector version of a scalar ternary operation node.
+ VectorNode* VectorNode::make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt) {
+ const TypeVect* vt = TypeVect::make(bt, vlen);
+ int vopc = VectorNode::opcode(opc, bt);
+ // This method should not be called for unimplemented vectors.
+ guarantee(vopc > 0, "Vector for '%s' is not implemented", NodeClassNames[opc]);
+ return make(vopc, n1, n2, n3, vt);
+ }
+
// Scalar promotion
VectorNode* VectorNode::scalar2vector(Node* s, uint vlen, const Type* opd_t) {
BasicType bt = opd_t->array_element_basic_type();
const TypeVect* vt = opd_t->singleton() ? TypeVect::make(opd_t, vlen)
: TypeVect::make(bt, vlen);
*** 465,489 ****
fatal("Type '%s' is not supported for vectors", type2name(bt));
return NULL;
}
}
! VectorNode* VectorNode::shift_count(Node* shift, Node* cnt, uint vlen, BasicType bt) {
! assert(VectorNode::is_shift(shift), "sanity");
// Match shift count type with shift vector type.
const TypeVect* vt = TypeVect::make(bt, vlen);
! switch (shift->Opcode()) {
case Op_LShiftI:
case Op_LShiftL:
return new LShiftCntVNode(cnt, vt);
case Op_RShiftI:
case Op_RShiftL:
case Op_URShiftI:
case Op_URShiftL:
return new RShiftCntVNode(cnt, vt);
default:
! fatal("Missed vector creation for '%s'", NodeClassNames[shift->Opcode()]);
return NULL;
}
}
bool VectorNode::is_vector_shift(int opc) {
--- 579,604 ----
fatal("Type '%s' is not supported for vectors", type2name(bt));
return NULL;
}
}
! VectorNode* VectorNode::shift_count(int opc, Node* cnt, uint vlen, BasicType bt) {
// Match shift count type with shift vector type.
const TypeVect* vt = TypeVect::make(bt, vlen);
! switch (opc) {
case Op_LShiftI:
case Op_LShiftL:
return new LShiftCntVNode(cnt, vt);
case Op_RShiftI:
case Op_RShiftL:
+ case Op_URShiftB:
+ case Op_URShiftS:
case Op_URShiftI:
case Op_URShiftL:
return new RShiftCntVNode(cnt, vt);
default:
! fatal("Missed vector creation for '%s'", NodeClassNames[opc]);
return NULL;
}
}
bool VectorNode::is_vector_shift(int opc) {
*** 593,602 ****
--- 708,741 ----
Node* adr, const TypePtr* atyp, Node* val,
uint vlen) {
return new StoreVectorNode(ctl, mem, adr, atyp, val);
}
+ int ExtractNode::opcode(BasicType bt) {
+ switch (bt) {
+ case T_BOOLEAN:
+ return Op_ExtractUB;
+ case T_BYTE:
+ return Op_ExtractB;
+ case T_CHAR:
+ return Op_ExtractC;
+ case T_SHORT:
+ return Op_ExtractS;
+ case T_INT:
+ return Op_ExtractI;
+ case T_LONG:
+ return Op_ExtractL;
+ case T_FLOAT:
+ return Op_ExtractF;
+ case T_DOUBLE:
+ return Op_ExtractD;
+ default:
+ fatal("Type '%s' is not supported for vectors", type2name(bt));
+ return 0;
+ }
+ }
+
// Extract a scalar element of vector.
Node* ExtractNode::make(Node* v, uint position, BasicType bt) {
assert((int)position < Matcher::max_vector_size(bt), "pos in range");
ConINode* pos = ConINode::make((int)position);
switch (bt) {
*** 624,636 ****
int ReductionNode::opcode(int opc, BasicType bt) {
int vopc = opc;
switch (opc) {
case Op_AddI:
! assert(bt == T_INT, "must be");
vopc = Op_AddReductionVI;
break;
case Op_AddL:
assert(bt == T_LONG, "must be");
vopc = Op_AddReductionVL;
break;
case Op_AddF:
--- 763,783 ----
int ReductionNode::opcode(int opc, BasicType bt) {
int vopc = opc;
switch (opc) {
case Op_AddI:
! switch (bt) {
! case T_BOOLEAN:
! case T_CHAR: return 0;
! case T_BYTE:
! case T_SHORT:
! case T_INT:
vopc = Op_AddReductionVI;
break;
+ default: ShouldNotReachHere(); return 0;
+ }
+ break;
case Op_AddL:
assert(bt == T_LONG, "must be");
vopc = Op_AddReductionVL;
break;
case Op_AddF:
*** 640,652 ****
case Op_AddD:
assert(bt == T_DOUBLE, "must be");
vopc = Op_AddReductionVD;
break;
case Op_MulI:
! assert(bt == T_INT, "must be");
vopc = Op_MulReductionVI;
break;
case Op_MulL:
assert(bt == T_LONG, "must be");
vopc = Op_MulReductionVL;
break;
case Op_MulF:
--- 787,807 ----
case Op_AddD:
assert(bt == T_DOUBLE, "must be");
vopc = Op_AddReductionVD;
break;
case Op_MulI:
! switch (bt) {
! case T_BOOLEAN:
! case T_CHAR: return 0;
! case T_BYTE:
! case T_SHORT:
! case T_INT:
vopc = Op_MulReductionVI;
break;
+ default: ShouldNotReachHere(); return 0;
+ }
+ break;
case Op_MulL:
assert(bt == T_LONG, "must be");
vopc = Op_MulReductionVL;
break;
case Op_MulF:
*** 655,700 ****
break;
case Op_MulD:
assert(bt == T_DOUBLE, "must be");
vopc = Op_MulReductionVD;
break;
case Op_MinF:
assert(bt == T_FLOAT, "must be");
vopc = Op_MinReductionV;
break;
case Op_MinD:
assert(bt == T_DOUBLE, "must be");
vopc = Op_MinReductionV;
break;
case Op_MaxF:
assert(bt == T_FLOAT, "must be");
vopc = Op_MaxReductionV;
break;
case Op_MaxD:
assert(bt == T_DOUBLE, "must be");
vopc = Op_MaxReductionV;
break;
case Op_AndI:
! assert(bt == T_INT, "must be");
vopc = Op_AndReductionV;
break;
case Op_AndL:
assert(bt == T_LONG, "must be");
vopc = Op_AndReductionV;
break;
case Op_OrI:
! assert(bt == T_INT, "must be");
vopc = Op_OrReductionV;
break;
case Op_OrL:
assert(bt == T_LONG, "must be");
vopc = Op_OrReductionV;
break;
case Op_XorI:
! assert(bt == T_INT, "must be");
vopc = Op_XorReductionV;
break;
case Op_XorL:
assert(bt == T_LONG, "must be");
vopc = Op_XorReductionV;
break;
default:
--- 810,911 ----
break;
case Op_MulD:
assert(bt == T_DOUBLE, "must be");
vopc = Op_MulReductionVD;
break;
+ case Op_MinI:
+ switch (bt) {
+ case T_BOOLEAN:
+ case T_CHAR: return 0;
+ case T_BYTE:
+ case T_SHORT:
+ case T_INT:
+ vopc = Op_MinReductionV;
+ break;
+ default: ShouldNotReachHere(); return 0;
+ }
+ break;
+ case Op_MinL:
+ assert(bt == T_LONG, "must be");
+ vopc = Op_MinReductionV;
+ break;
case Op_MinF:
assert(bt == T_FLOAT, "must be");
vopc = Op_MinReductionV;
break;
case Op_MinD:
assert(bt == T_DOUBLE, "must be");
vopc = Op_MinReductionV;
break;
+ case Op_MaxI:
+ switch (bt) {
+ case T_BOOLEAN:
+ case T_CHAR: return 0;
+ case T_BYTE:
+ case T_SHORT:
+ case T_INT:
+ vopc = Op_MaxReductionV;
+ break;
+ default: ShouldNotReachHere(); return 0;
+ }
+ break;
+ case Op_MaxL:
+ assert(bt == T_LONG, "must be");
+ vopc = Op_MaxReductionV;
+ break;
case Op_MaxF:
assert(bt == T_FLOAT, "must be");
vopc = Op_MaxReductionV;
break;
case Op_MaxD:
assert(bt == T_DOUBLE, "must be");
vopc = Op_MaxReductionV;
break;
case Op_AndI:
! switch (bt) {
! case T_BOOLEAN:
! case T_CHAR: return 0;
! case T_BYTE:
! case T_SHORT:
! case T_INT:
vopc = Op_AndReductionV;
break;
+ default: ShouldNotReachHere(); return 0;
+ }
+ break;
case Op_AndL:
assert(bt == T_LONG, "must be");
vopc = Op_AndReductionV;
break;
case Op_OrI:
! switch(bt) {
! case T_BOOLEAN:
! case T_CHAR: return 0;
! case T_BYTE:
! case T_SHORT:
! case T_INT:
vopc = Op_OrReductionV;
break;
+ default: ShouldNotReachHere(); return 0;
+ }
+ break;
case Op_OrL:
assert(bt == T_LONG, "must be");
vopc = Op_OrReductionV;
break;
case Op_XorI:
! switch(bt) {
! case T_BOOLEAN:
! case T_CHAR: return 0;
! case T_BYTE:
! case T_SHORT:
! case T_INT:
vopc = Op_XorReductionV;
break;
+ default: ShouldNotReachHere(); return 0;
+ }
+ break;
case Op_XorL:
assert(bt == T_LONG, "must be");
vopc = Op_XorReductionV;
break;
default:
*** 729,742 ****
--- 940,1072 ----
fatal("Missed vector creation for '%s'", NodeClassNames[vopc]);
return NULL;
}
}
+ VectorCastNode* VectorCastNode::make(int vopc, Node* n1, BasicType bt, uint vlen) {
+ const TypeVect* vt = TypeVect::make(bt, vlen);
+ switch (vopc) {
+ case Op_VectorCastB2X: return new VectorCastB2XNode(n1, vt);
+ case Op_VectorCastS2X: return new VectorCastS2XNode(n1, vt);
+ case Op_VectorCastI2X: return new VectorCastI2XNode(n1, vt);
+ case Op_VectorCastL2X: return new VectorCastL2XNode(n1, vt);
+ case Op_VectorCastF2X: return new VectorCastF2XNode(n1, vt);
+ case Op_VectorCastD2X: return new VectorCastD2XNode(n1, vt);
+ default: fatal("unknown node: %s", NodeClassNames[vopc]);
+ }
+ return NULL;
+ }
+
+ int VectorCastNode::opcode(BasicType bt) {
+ switch (bt) {
+ case T_BYTE: return Op_VectorCastB2X;
+ case T_SHORT: return Op_VectorCastS2X;
+ case T_INT: return Op_VectorCastI2X;
+ case T_LONG: return Op_VectorCastL2X;
+ case T_FLOAT: return Op_VectorCastF2X;
+ case T_DOUBLE: return Op_VectorCastD2X;
+ default: Unimplemented();
+ }
+ return 0;
+ }
+
+ Node* ReductionNode::make_reduction_input(PhaseGVN& gvn, int opc, BasicType bt) {
+ int vopc = opcode(opc, bt);
+ guarantee(vopc != opc, "Vector reduction for '%s' is not implemented", NodeClassNames[opc]);
+
+ switch (vopc) {
+ case Op_AndReductionV:
+ switch (bt) {
+ case T_BYTE:
+ case T_SHORT:
+ case T_INT:
+ return gvn.makecon(TypeInt::MINUS_1);
+ case T_LONG:
+ return gvn.makecon(TypeLong::MINUS_1);
+ default:
+ fatal("Missed vector creation for '%s' as the basic type is not correct.", NodeClassNames[vopc]);
+ return NULL;
+ }
+ break;
+ case Op_AddReductionVI: // fallthrough
+ case Op_AddReductionVL: // fallthrough
+ case Op_AddReductionVF: // fallthrough
+ case Op_AddReductionVD:
+ case Op_OrReductionV:
+ case Op_XorReductionV:
+ return gvn.zerocon(bt);
+ case Op_MulReductionVI:
+ return gvn.makecon(TypeInt::ONE);
+ case Op_MulReductionVL:
+ return gvn.makecon(TypeLong::ONE);
+ case Op_MulReductionVF:
+ return gvn.makecon(TypeF::ONE);
+ case Op_MulReductionVD:
+ return gvn.makecon(TypeD::ONE);
+ case Op_MinReductionV:
+ switch (bt) {
+ case T_BYTE:
+ case T_SHORT:
+ case T_INT:
+ return gvn.makecon(TypeInt::MAX);
+ case T_LONG:
+ return gvn.makecon(TypeLong::MAX);
+ case T_FLOAT:
+ return gvn.makecon(TypeF::POS_INF);
+ case T_DOUBLE:
+ return gvn.makecon(TypeD::POS_INF);
+ default: Unimplemented(); return NULL;
+ }
+ break;
+ case Op_MaxReductionV:
+ switch (bt) {
+ case T_BYTE:
+ case T_SHORT:
+ case T_INT:
+ return gvn.makecon(TypeInt::MIN);
+ case T_LONG:
+ return gvn.makecon(TypeLong::MIN);
+ case T_FLOAT:
+ return gvn.makecon(TypeF::NEG_INF);
+ case T_DOUBLE:
+ return gvn.makecon(TypeD::NEG_INF);
+ default: Unimplemented(); return NULL;
+ }
+ break;
+ default:
+ fatal("Missed vector creation for '%s'", NodeClassNames[vopc]);
+ return NULL;
+ }
+ }
+
bool ReductionNode::implemented(int opc, uint vlen, BasicType bt) {
if (is_java_primitive(bt) &&
(vlen > 1) && is_power_of_2(vlen) &&
Matcher::vector_size_supported(bt, vlen)) {
int vopc = ReductionNode::opcode(opc, bt);
return vopc != opc && Matcher::match_rule_supported(vopc);
}
return false;
}
+
+ #ifndef PRODUCT
+ void VectorMaskCmpNode::dump_spec(outputStream *st) const {
+ st->print(" %d #", _predicate); _type->dump_on(st);
+ }
+ #endif // PRODUCT
+
+ Node* VectorReinterpretNode::Identity(PhaseGVN *phase) {
+ Node* n = in(1);
+ if (n->Opcode() == Op_VectorReinterpret) {
+ if (Type::cmp(bottom_type(), n->in(1)->bottom_type()) == 0) {
+ return n->in(1);
+ }
+ }
+ return this;
+ }
+
+ Node* VectorInsertNode::make(Node* vec, Node* new_val, int position) {
+ assert(position < (int)vec->bottom_type()->is_vect()->length(), "pos in range");
+ ConINode* pos = ConINode::make(position);
+ return new VectorInsertNode(vec, new_val, pos, vec->bottom_type()->is_vect());
+ }
+
< prev index next >