Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 36 additions & 17 deletions src/hotspot/share/opto/superwordVTransformBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,7 @@ void SuperWordVTransformBuilder::build_inputs_for_vector_vtnodes(VectorSet& vtn_
} else if (vtn->isa_ReductionVector() != nullptr) {
init_req_with_scalar(p0, vtn, 1); // scalar init
init_req_with_vector(pack, vtn, 2); // vector
} else {
assert(vtn->isa_ElementWiseVector() != nullptr, "all other vtnodes are handled above");
} else if (vtn->isa_ElementWiseVector() != nullptr) {
if (VectorNode::is_scalar_rotate(p0) &&
p0->in(2)->is_Con() &&
Matcher::supports_vector_constant_rotates(p0->in(2)->get_int())) {
Expand All @@ -105,14 +104,20 @@ void SuperWordVTransformBuilder::build_inputs_for_vector_vtnodes(VectorSet& vtn_
init_req_with_scalar(p0, vtn, 2); // constant rounding mode
} else if (p0->is_CMove()) {
// Cmp + Bool + CMove -> VectorMaskCmp + VectorBlend.
set_all_req_with_vectors(pack, vtn);
VTransformBoolVectorNode* vtn_mask_cmp = vtn->in_req(1)->isa_BoolVector();
init_all_req_with_vectors(pack, vtn);
// Inputs must be permuted from (mask, blend1, blend2) -> (blend1, blend2, mask)
vtn->swap_req(1, 2);
vtn->swap_req(2, 3);
// If the test was negated: (blend1, blend2, mask) -> (blend2, blend1, mask)
VTransformBoolVectorNode* vtn_mask_cmp = vtn->in_req(3)->isa_BoolVector();
if (vtn_mask_cmp->test()._is_negated) {
vtn->swap_req(2, 3); // swap if test was negated.
vtn->swap_req(1, 2); // swap if test was negated.
}
} else {
set_all_req_with_vectors(pack, vtn);
init_all_req_with_vectors(pack, vtn);
}
} else {
init_all_req_with_vectors(pack, vtn);
}
}
}
Expand All @@ -139,7 +144,7 @@ void SuperWordVTransformBuilder::build_inputs_for_scalar_vtnodes(VectorSet& vtn_
init_req_with_scalar(n, vtn, 0);
continue;
} else {
set_all_req_with_scalars(n, vtn);
init_all_req_with_scalars(n, vtn);
}
}
}
Expand All @@ -149,32 +154,46 @@ VTransformVectorNode* SuperWordVTransformBuilder::make_vector_vtnode_for_pack(co
uint pack_size = pack->size();
Node* p0 = pack->at(0);
int opc = p0->Opcode();
const VTransformVectorNodePrototype prototype = VTransformVectorNodePrototype::make_from_pack(pack, _vloop_analyzer);
VTransformVectorNode* vtn = nullptr;

if (p0->is_Load()) {
const VPointer& scalar_p = _vloop_analyzer.vpointers().vpointer(p0->as_Load());
const VPointer vector_p(scalar_p.make_with_size(scalar_p.size() * pack_size));
vtn = new (_vtransform.arena()) VTransformLoadVectorNode(_vtransform, pack_size, vector_p);
vtn = new (_vtransform.arena()) VTransformLoadVectorNode(_vtransform, prototype, vector_p);
} else if (p0->is_Store()) {
const VPointer& scalar_p = _vloop_analyzer.vpointers().vpointer(p0->as_Store());
const VPointer vector_p(scalar_p.make_with_size(scalar_p.size() * pack_size));
vtn = new (_vtransform.arena()) VTransformStoreVectorNode(_vtransform, pack_size, vector_p);
vtn = new (_vtransform.arena()) VTransformStoreVectorNode(_vtransform, prototype, vector_p);
} else if (p0->is_Cmp()) {
assert(p0->req() == 3, "is it true?");
// TODO: remove req above and below
vtn = new (_vtransform.arena()) VTransformCmpVectorNode(_vtransform, p0->req(), prototype);
} else if (p0->is_Bool()) {
VTransformBoolTest kind = _packset.get_bool_test(pack);
vtn = new (_vtransform.arena()) VTransformBoolVectorNode(_vtransform, pack_size, kind);
vtn = new (_vtransform.arena()) VTransformBoolVectorNode(_vtransform, prototype, kind);
} else if (p0->is_CMove()) {
vtn = new (_vtransform.arena()) VTransformElementWiseVectorNode(_vtransform, p0->req(), prototype, Op_VectorBlend);
} else if (_vloop_analyzer.reductions().is_marked_reduction(p0)) {
vtn = new (_vtransform.arena()) VTransformReductionVectorNode(_vtransform, pack_size);
vtn = new (_vtransform.arena()) VTransformReductionVectorNode(_vtransform, prototype);
} else if (VectorNode::is_muladds2i(p0)) {
// A special kind of binary element-wise vector op: the inputs are "ints" a and b,
// but reinterpreted as two "shorts" [a0, a1] and [b0, b1]:
// v = MulAddS2I(a, b) = a0 * b0 + a1 + b1
assert(p0->req() == 5, "MulAddS2I should have 4 operands");
vtn = new (_vtransform.arena()) VTransformElementWiseVectorNode(_vtransform, 3, pack_size);
vtn = new (_vtransform.arena()) VTransformElementWiseVectorNode(_vtransform, 3, prototype, -1 /* TODO: */);
} else if (VectorNode::is_convert_opcode(opc)) {
assert(p0->req() == 2, "convert should have 2 operands");
BasicType def_bt = _vloop_analyzer.types().velt_basic_type(p0->in(1));
int vopc = VectorCastNode::opcode(opc, def_bt);
vtn = new (_vtransform.arena()) VTransformElementWiseVectorNode(_vtransform, p0->req(), prototype, vopc);
} else if (VectorNode::is_reinterpret_opcode(opc)) {
assert(p0->req() == 2, "reinterpret should have 2 operands");
BasicType src_bt = _vloop_analyzer.types().velt_basic_type(p0->in(1));
vtn = new (_vtransform.arena()) VTransformReinterpretVectorNode(_vtransform, prototype, src_bt);
} else {
assert(p0->req() == 3 ||
p0->is_CMove() ||
VectorNode::is_scalar_op_that_returns_int_but_vector_op_returns_long(opc) ||
VectorNode::is_convert_opcode(opc) ||
VectorNode::is_reinterpret_opcode(opc) ||
VectorNode::is_scalar_unary_op_with_equal_input_and_output_types(opc) ||
opc == Op_FmaD ||
Expand All @@ -183,7 +202,7 @@ VTransformVectorNode* SuperWordVTransformBuilder::make_vector_vtnode_for_pack(co
opc == Op_SignumF ||
opc == Op_SignumD,
"pack type must be in this list");
vtn = new (_vtransform.arena()) VTransformElementWiseVectorNode(_vtransform, p0->req(), pack_size);
vtn = new (_vtransform.arena()) VTransformElementWiseVectorNode(_vtransform, p0->req(), prototype, -1 /*TODO:*/);
}
vtn->set_nodes(pack);
return vtn;
Expand Down Expand Up @@ -291,7 +310,7 @@ void SuperWordVTransformBuilder::init_req_with_vector(const Node_List* pack, VTr
vtn->init_req(j, req);
}

void SuperWordVTransformBuilder::set_all_req_with_scalars(Node* n, VTransformNode* vtn) {
void SuperWordVTransformBuilder::init_all_req_with_scalars(Node* n, VTransformNode* vtn) {
assert(vtn->req() == n->req(), "scalars must have same number of reqs");
for (uint j = 0; j < n->req(); j++) {
Node* def = n->in(j);
Expand All @@ -300,7 +319,7 @@ void SuperWordVTransformBuilder::set_all_req_with_scalars(Node* n, VTransformNod
}
}

void SuperWordVTransformBuilder::set_all_req_with_vectors(const Node_List* pack, VTransformNode* vtn) {
void SuperWordVTransformBuilder::init_all_req_with_vectors(const Node_List* pack, VTransformNode* vtn) {
Node* p0 = pack->at(0);
assert(vtn->req() <= p0->req(), "must have at at most as many reqs");
// Vectors have no ctrl, so ignore it.
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/opto/superwordVTransformBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ class SuperWordVTransformBuilder : public StackObj {
VTransformNode* get_vtnode_or_wrap_as_outer(Node* n);
void init_req_with_scalar(Node* n, VTransformNode* vtn, const int index);
void init_req_with_vector(const Node_List* pack, VTransformNode* vtn, const int index);
void set_all_req_with_scalars(Node* n, VTransformNode* vtn);
void set_all_req_with_vectors(const Node_List* pack, VTransformNode* vtn);
void init_all_req_with_scalars(Node* n, VTransformNode* vtn);
void init_all_req_with_vectors(const Node_List* pack, VTransformNode* vtn);
void add_memory_dependencies_of_node_to_vtnode(Node* n, VTransformNode* vtn, VectorSet& vtn_memory_dependencies);
};

Expand Down
Loading