--- a/hotspot/src/share/vm/opto/vectornode.cpp Wed Aug 22 14:29:57 2012 +0200
+++ b/hotspot/src/share/vm/opto/vectornode.cpp Wed Aug 22 11:55:40 2012 -0700
@@ -31,7 +31,7 @@
// Return the vector operator for the specified scalar operation
// and vector length. Also used to check if the code generator
// supports the vector operation.
-int VectorNode::opcode(int sopc, uint vlen, BasicType bt) {
+int VectorNode::opcode(int sopc, BasicType bt) {
switch (sopc) {
case Op_AddI:
switch (bt) {
@@ -161,7 +161,7 @@
if (is_java_primitive(bt) &&
(vlen > 1) && is_power_of_2(vlen) &&
Matcher::vector_size_supported(bt, vlen)) {
- int vopc = VectorNode::opcode(opc, vlen, bt);
+ int vopc = VectorNode::opcode(opc, bt);
return vopc > 0 && Matcher::has_match_rule(vopc);
}
return false;
@@ -195,10 +195,54 @@
return false;
}
+// [Start, end) half-open range defining which operands are vectors
+void VectorNode::vector_operands(Node* n, uint* start, uint* end) {
+ switch (n->Opcode()) {
+ case Op_LoadB: case Op_LoadUB:
+ case Op_LoadS: case Op_LoadUS:
+ case Op_LoadI: case Op_LoadL:
+ case Op_LoadF: case Op_LoadD:
+ case Op_LoadP: case Op_LoadN:
+ *start = 0;
+ *end = 0; // no vector operands
+ break;
+ case Op_StoreB: case Op_StoreC:
+ case Op_StoreI: case Op_StoreL:
+ case Op_StoreF: case Op_StoreD:
+ case Op_StoreP: case Op_StoreN:
+ *start = MemNode::ValueIn;
+ *end = MemNode::ValueIn + 1; // 1 vector operand
+ break;
+ case Op_LShiftI: case Op_LShiftL:
+ case Op_RShiftI: case Op_RShiftL:
+ case Op_URShiftI: case Op_URShiftL:
+ *start = 1;
+ *end = 2; // 1 vector operand
+ break;
+ case Op_AddI: case Op_AddL: case Op_AddF: case Op_AddD:
+ case Op_SubI: case Op_SubL: case Op_SubF: case Op_SubD:
+ case Op_MulI: case Op_MulL: case Op_MulF: case Op_MulD:
+ case Op_DivF: case Op_DivD:
+ case Op_AndI: case Op_AndL:
+ case Op_OrI: case Op_OrL:
+ case Op_XorI: case Op_XorL:
+ *start = 1;
+ *end = 3; // 2 vector operands
+ break;
+ case Op_CMoveI: case Op_CMoveL: case Op_CMoveF: case Op_CMoveD:
+ *start = 2;
+ *end = n->req();
+ break;
+ default:
+ *start = 1;
+ *end = n->req(); // default is all operands
+ }
+}
+
// Return the vector version of a scalar operation node.
VectorNode* VectorNode::make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt) {
const TypeVect* vt = TypeVect::make(bt, vlen);
- int vopc = VectorNode::opcode(opc, vlen, bt);
+ int vopc = VectorNode::opcode(opc, bt);
switch (vopc) {
case Op_AddVB: return new (C, 3) AddVBNode(n1, n2, vt);
@@ -278,38 +322,39 @@
switch (bt) {
case T_BOOLEAN:
case T_BYTE:
- return new (C, vlen+1) PackBNode(s, vt);
+ return new (C, 2) PackBNode(s, vt);
case T_CHAR:
case T_SHORT:
- return new (C, vlen+1) PackSNode(s, vt);
+ return new (C, 2) PackSNode(s, vt);
case T_INT:
- return new (C, vlen+1) PackINode(s, vt);
+ return new (C, 2) PackINode(s, vt);
case T_LONG:
- return new (C, vlen+1) PackLNode(s, vt);
+ return new (C, 2) PackLNode(s, vt);
case T_FLOAT:
- return new (C, vlen+1) PackFNode(s, vt);
+ return new (C, 2) PackFNode(s, vt);
case T_DOUBLE:
- return new (C, vlen+1) PackDNode(s, vt);
+ return new (C, 2) PackDNode(s, vt);
}
ShouldNotReachHere();
return NULL;
}
// Create a binary tree form for Packs. [lo, hi) (half-open) range
-Node* PackNode::binaryTreePack(Compile* C, int lo, int hi) {
+PackNode* PackNode::binary_tree_pack(Compile* C, int lo, int hi) {
int ct = hi - lo;
assert(is_power_of_2(ct), "power of 2");
if (ct == 2) {
PackNode* pk = PackNode::make(C, in(lo), 2, vect_type()->element_basic_type());
- pk->add_opd(1, in(lo+1));
+ pk->add_opd(in(lo+1));
return pk;
} else {
int mid = lo + ct/2;
- Node* n1 = binaryTreePack(C, lo, mid);
- Node* n2 = binaryTreePack(C, mid, hi );
+ PackNode* n1 = binary_tree_pack(C, lo, mid);
+ PackNode* n2 = binary_tree_pack(C, mid, hi );
- BasicType bt = vect_type()->element_basic_type();
+ BasicType bt = n1->vect_type()->element_basic_type();
+ assert(bt == n2->vect_type()->element_basic_type(), "should be the same");
switch (bt) {
case T_BOOLEAN:
case T_BYTE: