Mercurial > hg > truffle
diff src/share/vm/opto/vectornode.cpp @ 6619:5af51c882207
7192963: assert(_in[req-1] == this) failed: Must pass arg count to 'new'
Summary: Fixed Pack node generation. Not vectorize shift instructions if count is not the same for all shifts and if count is vector.
Reviewed-by: twisti
author | kvn |
---|---|
date | Wed, 22 Aug 2012 11:55:40 -0700 |
parents | 4b0d6fd74911 |
children | e626685e9f6c |
line wrap: on
line diff
--- a/src/share/vm/opto/vectornode.cpp Wed Aug 22 14:29:57 2012 +0200 +++ b/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: