< prev index next >
src/share/vm/opto/vectornode.cpp
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 37,48 ****
case T_BOOLEAN:
case T_BYTE: return Op_AddVB;
case T_CHAR:
case T_SHORT: return Op_AddVS;
case T_INT: return Op_AddVI;
}
- ShouldNotReachHere();
case Op_AddL:
assert(bt == T_LONG, "must be");
return Op_AddVL;
case Op_AddF:
assert(bt == T_FLOAT, "must be");
--- 37,48 ----
case T_BOOLEAN:
case T_BYTE: return Op_AddVB;
case T_CHAR:
case T_SHORT: return Op_AddVS;
case T_INT: return Op_AddVI;
+ default: ShouldNotReachHere(); return 0;
}
case Op_AddL:
assert(bt == T_LONG, "must be");
return Op_AddVL;
case Op_AddF:
assert(bt == T_FLOAT, "must be");
*** 55,66 ****
case T_BOOLEAN:
case T_BYTE: return Op_SubVB;
case T_CHAR:
case T_SHORT: return Op_SubVS;
case T_INT: return Op_SubVI;
}
- ShouldNotReachHere();
case Op_SubL:
assert(bt == T_LONG, "must be");
return Op_SubVL;
case Op_SubF:
assert(bt == T_FLOAT, "must be");
--- 55,66 ----
case T_BOOLEAN:
case T_BYTE: return Op_SubVB;
case T_CHAR:
case T_SHORT: return Op_SubVS;
case T_INT: return Op_SubVI;
+ default: ShouldNotReachHere(); return 0;
}
case Op_SubL:
assert(bt == T_LONG, "must be");
return Op_SubVL;
case Op_SubF:
assert(bt == T_FLOAT, "must be");
*** 73,84 ****
case T_BOOLEAN:
case T_BYTE: return 0; // Unimplemented
case T_CHAR:
case T_SHORT: return Op_MulVS;
case T_INT: return Op_MulVI;
}
- ShouldNotReachHere();
case Op_MulL:
assert(bt == T_LONG, "must be");
return Op_MulVL;
case Op_MulF:
assert(bt == T_FLOAT, "must be");
--- 73,84 ----
case T_BOOLEAN:
case T_BYTE: return 0; // Unimplemented
case T_CHAR:
case T_SHORT: return Op_MulVS;
case T_INT: return Op_MulVI;
+ default: ShouldNotReachHere(); return 0;
}
case Op_MulL:
assert(bt == T_LONG, "must be");
return Op_MulVL;
case Op_MulF:
assert(bt == T_FLOAT, "must be");
*** 121,144 ****
case T_BOOLEAN:
case T_BYTE: return Op_LShiftVB;
case T_CHAR:
case T_SHORT: return Op_LShiftVS;
case T_INT: return Op_LShiftVI;
}
- ShouldNotReachHere();
case Op_LShiftL:
assert(bt == T_LONG, "must be");
return Op_LShiftVL;
case Op_RShiftI:
switch (bt) {
case T_BOOLEAN:return Op_URShiftVB; // boolean is unsigned value
case T_CHAR: return Op_URShiftVS; // char is unsigned value
case T_BYTE: return Op_RShiftVB;
case T_SHORT: return Op_RShiftVS;
case T_INT: return Op_RShiftVI;
}
- ShouldNotReachHere();
case Op_RShiftL:
assert(bt == T_LONG, "must be");
return Op_RShiftVL;
case Op_URShiftI:
switch (bt) {
--- 121,144 ----
case T_BOOLEAN:
case T_BYTE: return Op_LShiftVB;
case T_CHAR:
case T_SHORT: return Op_LShiftVS;
case T_INT: return Op_LShiftVI;
+ default: ShouldNotReachHere(); return 0;
}
case Op_LShiftL:
assert(bt == T_LONG, "must be");
return Op_LShiftVL;
case Op_RShiftI:
switch (bt) {
case T_BOOLEAN:return Op_URShiftVB; // boolean is unsigned value
case T_CHAR: return Op_URShiftVS; // char is unsigned value
case T_BYTE: return Op_RShiftVB;
case T_SHORT: return Op_RShiftVS;
case T_INT: return Op_RShiftVI;
+ default: ShouldNotReachHere(); return 0;
}
case Op_RShiftL:
assert(bt == T_LONG, "must be");
return Op_RShiftVL;
case Op_URShiftI:
switch (bt) {
*** 149,160 ****
// values produces incorrect Java result for
// negative data because java code should convert
// a short value into int value with sign
// extension before a shift.
case T_INT: return Op_URShiftVI;
}
- ShouldNotReachHere();
case Op_URShiftL:
assert(bt == T_LONG, "must be");
return Op_URShiftVL;
case Op_AndI:
case Op_AndL:
--- 149,160 ----
// values produces incorrect Java result for
// negative data because java code should convert
// a short value into int value with sign
// extension before a shift.
case T_INT: return Op_URShiftVI;
+ default: ShouldNotReachHere(); return 0;
}
case Op_URShiftL:
assert(bt == T_LONG, "must be");
return Op_URShiftVL;
case Op_AndI:
case Op_AndL:
*** 181,192 ****
case Op_StoreI:
case Op_StoreL:
case Op_StoreF:
case Op_StoreD:
return Op_StoreVector;
! }
return 0; // Unimplemented
}
// Also used to check if the code generator
// supports the vector operation.
bool VectorNode::implemented(int opc, uint vlen, BasicType bt) {
--- 181,194 ----
case Op_StoreI:
case Op_StoreL:
case Op_StoreF:
case Op_StoreD:
return Op_StoreVector;
!
! default:
return 0; // Unimplemented
+ }
}
// Also used to check if the code generator
// supports the vector operation.
bool VectorNode::implemented(int opc, uint vlen, BasicType bt) {
*** 206,217 ****
case Op_RShiftI:
case Op_RShiftL:
case Op_URShiftI:
case Op_URShiftL:
return true;
! }
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.
--- 208,220 ----
case Op_RShiftI:
case Op_RShiftL:
case Op_URShiftI:
case Op_URShiftL:
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.
*** 221,232 ****
case Op_ReplicateI:
case Op_ReplicateL:
case Op_ReplicateF:
case Op_ReplicateD:
return true;
! }
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()) {
--- 224,236 ----
case Op_ReplicateI:
case Op_ReplicateL:
case Op_ReplicateF:
case Op_ReplicateD:
return true;
! default:
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()) {
*** 331,357 ****
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);
! }
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);
! }
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();
--- 335,362 ----
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);
! 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();
*** 370,382 ****
return new ReplicateLNode(s, vt);
case T_FLOAT:
return new ReplicateFNode(s, vt);
case T_DOUBLE:
return new ReplicateDNode(s, vt);
! }
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) && !cnt->is_Con(), "only variable shift count");
// Match shift count type with shift vector type.
--- 375,388 ----
return new ReplicateLNode(s, vt);
case T_FLOAT:
return new ReplicateFNode(s, vt);
case T_DOUBLE:
return new ReplicateDNode(s, vt);
! default:
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) && !cnt->is_Con(), "only variable shift count");
// Match shift count type with shift vector type.
*** 388,400 ****
case Op_RShiftI:
case Op_RShiftL:
case Op_URShiftI:
case Op_URShiftL:
return new RShiftCntVNode(cnt, vt);
! }
fatal("Missed vector creation for '%s'", NodeClassNames[shift->Opcode()]);
return NULL;
}
// Return initial Pack node. Additional operands added with add_opd() calls.
PackNode* PackNode::make(Node* s, uint vlen, BasicType bt) {
const TypeVect* vt = TypeVect::make(bt, vlen);
--- 394,407 ----
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;
+ }
}
// Return initial Pack node. Additional operands added with add_opd() calls.
PackNode* PackNode::make(Node* s, uint vlen, BasicType bt) {
const TypeVect* vt = TypeVect::make(bt, vlen);
*** 411,434 ****
return new PackLNode(s, vt);
case T_FLOAT:
return new PackFNode(s, vt);
case T_DOUBLE:
return new PackDNode(s, vt);
! }
fatal("Type '%s' is not supported for vectors", type2name(bt));
return NULL;
}
// Create a binary tree form for Packs. [lo, hi) (half-open) range
PackNode* PackNode::binary_tree_pack(int lo, int hi) {
int ct = hi - lo;
assert(is_power_of_2(ct), "power of 2");
if (ct == 2) {
PackNode* pk = PackNode::make(in(lo), 2, vect_type()->element_basic_type());
pk->add_opd(in(lo+1));
return pk;
-
} else {
int mid = lo + ct/2;
PackNode* n1 = binary_tree_pack(lo, mid);
PackNode* n2 = binary_tree_pack(mid, hi );
--- 418,441 ----
return new PackLNode(s, vt);
case T_FLOAT:
return new PackFNode(s, vt);
case T_DOUBLE:
return new PackDNode(s, vt);
! default:
fatal("Type '%s' is not supported for vectors", type2name(bt));
return NULL;
+ }
}
// Create a binary tree form for Packs. [lo, hi) (half-open) range
PackNode* PackNode::binary_tree_pack(int lo, int hi) {
int ct = hi - lo;
assert(is_power_of_2(ct), "power of 2");
if (ct == 2) {
PackNode* pk = PackNode::make(in(lo), 2, vect_type()->element_basic_type());
pk->add_opd(in(lo+1));
return pk;
} else {
int mid = lo + ct/2;
PackNode* n1 = binary_tree_pack(lo, mid);
PackNode* n2 = binary_tree_pack(mid, hi );
*** 447,460 ****
return new Pack2LNode(n1, n2, TypeVect::make(T_LONG, 2));
case T_FLOAT:
return new PackDNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
case T_DOUBLE:
return new Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
! }
fatal("Type '%s' is not supported for vectors", type2name(bt));
- }
return NULL;
}
// Return the vector version of a scalar load node.
LoadVectorNode* LoadVectorNode::make(int opc, Node* ctl, Node* mem,
Node* adr, const TypePtr* atyp,
--- 454,468 ----
return new Pack2LNode(n1, n2, TypeVect::make(T_LONG, 2));
case T_FLOAT:
return new PackDNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
case T_DOUBLE:
return new Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
! default:
fatal("Type '%s' is not supported for vectors", type2name(bt));
return NULL;
+ }
+ }
}
// Return the vector version of a scalar load node.
LoadVectorNode* LoadVectorNode::make(int opc, Node* ctl, Node* mem,
Node* adr, const TypePtr* atyp,
*** 490,502 ****
return new ExtractLNode(v, pos);
case T_FLOAT:
return new ExtractFNode(v, pos);
case T_DOUBLE:
return new ExtractDNode(v, pos);
! }
fatal("Type '%s' is not supported for vectors", type2name(bt));
return NULL;
}
int ReductionNode::opcode(int opc, BasicType bt) {
int vopc = opc;
switch (opc) {
--- 498,511 ----
return new ExtractLNode(v, pos);
case T_FLOAT:
return new ExtractFNode(v, pos);
case T_DOUBLE:
return new ExtractDNode(v, pos);
! default:
fatal("Type '%s' is not supported for vectors", type2name(bt));
return NULL;
+ }
}
int ReductionNode::opcode(int opc, BasicType bt) {
int vopc = opc;
switch (opc) {
*** 554,566 ****
case Op_AddReductionVD: return new AddReductionVDNode(ctrl, n1, n2);
case Op_MulReductionVI: return new MulReductionVINode(ctrl, n1, n2);
case Op_MulReductionVL: return new MulReductionVLNode(ctrl, n1, n2);
case Op_MulReductionVF: return new MulReductionVFNode(ctrl, n1, n2);
case Op_MulReductionVD: return new MulReductionVDNode(ctrl, n1, n2);
! }
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) &&
--- 563,576 ----
case Op_AddReductionVD: return new AddReductionVDNode(ctrl, n1, n2);
case Op_MulReductionVI: return new MulReductionVINode(ctrl, n1, n2);
case Op_MulReductionVL: return new MulReductionVLNode(ctrl, n1, n2);
case Op_MulReductionVF: return new MulReductionVFNode(ctrl, n1, n2);
case Op_MulReductionVD: return new MulReductionVDNode(ctrl, n1, n2);
! 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) &&
*** 568,573 ****
int vopc = ReductionNode::opcode(opc, bt);
return vopc != opc && Matcher::match_rule_supported(vopc);
}
return false;
}
-
--- 578,582 ----
< prev index next >