hotspot/src/share/vm/opto/vectornode.cpp
changeset 13490 d19348851d2e
parent 13488 a9ec58a1f613
child 13895 f6dfe4123709
--- 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: