Mercurial > hg > graal-jvmci-8
comparison src/share/vm/opto/superword.cpp @ 6803:06f52c4d0e18
7200264: 7192963 changes disabled shift vectors
Summary: Replaced is_vector_use() call with explicit check for vector shift's count.
Reviewed-by: twisti, roland, dlong, vlivanov
author | kvn |
---|---|
date | Tue, 25 Sep 2012 15:48:17 -0700 |
parents | 8ae8f9dd7099 |
children | e626685e9f6c |
comparison
equal
deleted
inserted
replaced
6802:0702f188baeb | 6803:06f52c4d0e18 |
---|---|
1086 bool SuperWord::profitable(Node_List* p) { | 1086 bool SuperWord::profitable(Node_List* p) { |
1087 Node* p0 = p->at(0); | 1087 Node* p0 = p->at(0); |
1088 uint start, end; | 1088 uint start, end; |
1089 VectorNode::vector_operands(p0, &start, &end); | 1089 VectorNode::vector_operands(p0, &start, &end); |
1090 | 1090 |
1091 // Return false if some input is not vector and inside block | 1091 // Return false if some inputs are not vectors or vectors with different |
1092 // size or alignment. | |
1093 // Also, for now, return false if not scalar promotion case when inputs are | |
1094 // the same. Later, implement PackNode and allow differing, non-vector inputs | |
1095 // (maybe just the ones from outside the block.) | |
1092 for (uint i = start; i < end; i++) { | 1096 for (uint i = start; i < end; i++) { |
1093 if (!is_vector_use(p0, i)) { | 1097 if (!is_vector_use(p0, i)) |
1094 // For now, return false if not scalar promotion case (inputs are the same.) | 1098 return false; |
1095 // Later, implement PackNode and allow differing, non-vector inputs | |
1096 // (maybe just the ones from outside the block.) | |
1097 if (!same_inputs(p, i)) { | |
1098 return false; | |
1099 } | |
1100 } | |
1101 } | 1099 } |
1102 if (VectorNode::is_shift(p0)) { | 1100 if (VectorNode::is_shift(p0)) { |
1103 // For now, return false if shift count is vector because | 1101 // For now, return false if shift count is vector or not scalar promotion |
1104 // hw does not support it. | 1102 // case (different shift counts) because it is not supported yet. |
1105 if (is_vector_use(p0, 2)) | 1103 Node* cnt = p0->in(2); |
1104 Node_List* cnt_pk = my_pack(cnt); | |
1105 if (cnt_pk != NULL) | |
1106 return false; | 1106 return false; |
1107 // For the same reason return false if different shift counts. | |
1108 if (!same_inputs(p, 2)) | 1107 if (!same_inputs(p, 2)) |
1109 return false; | 1108 return false; |
1110 } | 1109 } |
1111 if (!p0->is_Store()) { | 1110 if (!p0->is_Store()) { |
1112 // For now, return false if not all uses are vector. | 1111 // For now, return false if not all uses are vector. |
1400 vlen_in_bytes = vn->as_Vector()->length_in_bytes(); | 1399 vlen_in_bytes = vn->as_Vector()->length_in_bytes(); |
1401 } else { | 1400 } else { |
1402 ShouldNotReachHere(); | 1401 ShouldNotReachHere(); |
1403 } | 1402 } |
1404 assert(vn != NULL, "sanity"); | 1403 assert(vn != NULL, "sanity"); |
1405 _phase->_igvn.register_new_node_with_optimizer(vn); | 1404 _igvn.register_new_node_with_optimizer(vn); |
1406 _phase->set_ctrl(vn, _phase->get_ctrl(p->at(0))); | 1405 _phase->set_ctrl(vn, _phase->get_ctrl(p->at(0))); |
1407 for (uint j = 0; j < p->size(); j++) { | 1406 for (uint j = 0; j < p->size(); j++) { |
1408 Node* pm = p->at(j); | 1407 Node* pm = p->at(j); |
1409 _igvn.replace_node(pm, vn); | 1408 _igvn.replace_node(pm, vn); |
1410 } | 1409 } |
1449 cnt = ConNode::make(C, TypeInt::make(shift & mask)); | 1448 cnt = ConNode::make(C, TypeInt::make(shift & mask)); |
1450 } | 1449 } |
1451 } else { | 1450 } else { |
1452 if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) { | 1451 if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) { |
1453 cnt = ConNode::make(C, TypeInt::make(mask)); | 1452 cnt = ConNode::make(C, TypeInt::make(mask)); |
1454 _phase->_igvn.register_new_node_with_optimizer(cnt); | 1453 _igvn.register_new_node_with_optimizer(cnt); |
1455 cnt = new (C, 3) AndINode(opd, cnt); | 1454 cnt = new (C, 3) AndINode(opd, cnt); |
1456 _phase->_igvn.register_new_node_with_optimizer(cnt); | 1455 _igvn.register_new_node_with_optimizer(cnt); |
1457 _phase->set_ctrl(cnt, _phase->get_ctrl(opd)); | 1456 _phase->set_ctrl(cnt, _phase->get_ctrl(opd)); |
1458 } | 1457 } |
1459 assert(opd->bottom_type()->isa_int(), "int type only"); | 1458 assert(opd->bottom_type()->isa_int(), "int type only"); |
1460 // Move non constant shift count into XMM register. | 1459 // Move non constant shift count into XMM register. |
1461 cnt = new (C, 2) MoveI2FNode(cnt); | 1460 cnt = new (C, 2) MoveI2FNode(cnt); |
1462 } | 1461 } |
1463 if (cnt != opd) { | 1462 if (cnt != opd) { |
1464 _phase->_igvn.register_new_node_with_optimizer(cnt); | 1463 _igvn.register_new_node_with_optimizer(cnt); |
1465 _phase->set_ctrl(cnt, _phase->get_ctrl(opd)); | 1464 _phase->set_ctrl(cnt, _phase->get_ctrl(opd)); |
1466 } | 1465 } |
1467 return cnt; | 1466 return cnt; |
1468 } | 1467 } |
1469 assert(!opd->is_StoreVector(), "such vector is not expected here"); | 1468 assert(!opd->is_StoreVector(), "such vector is not expected here"); |
1471 // p0's vector. Use p0's type because size of operand's container in | 1470 // p0's vector. Use p0's type because size of operand's container in |
1472 // vector should match p0's size regardless operand's size. | 1471 // vector should match p0's size regardless operand's size. |
1473 const Type* p0_t = velt_type(p0); | 1472 const Type* p0_t = velt_type(p0); |
1474 VectorNode* vn = VectorNode::scalar2vector(_phase->C, opd, vlen, p0_t); | 1473 VectorNode* vn = VectorNode::scalar2vector(_phase->C, opd, vlen, p0_t); |
1475 | 1474 |
1476 _phase->_igvn.register_new_node_with_optimizer(vn); | 1475 _igvn.register_new_node_with_optimizer(vn); |
1477 _phase->set_ctrl(vn, _phase->get_ctrl(opd)); | 1476 _phase->set_ctrl(vn, _phase->get_ctrl(opd)); |
1478 #ifdef ASSERT | 1477 #ifdef ASSERT |
1479 if (TraceNewVectors) { | 1478 if (TraceNewVectors) { |
1480 tty->print("new Vector node: "); | 1479 tty->print("new Vector node: "); |
1481 vn->dump(); | 1480 vn->dump(); |
1494 Node* in = pi->in(opd_idx); | 1493 Node* in = pi->in(opd_idx); |
1495 assert(my_pack(in) == NULL, "Should already have been unpacked"); | 1494 assert(my_pack(in) == NULL, "Should already have been unpacked"); |
1496 assert(opd_bt == in->bottom_type()->basic_type(), "all same type"); | 1495 assert(opd_bt == in->bottom_type()->basic_type(), "all same type"); |
1497 pk->add_opd(in); | 1496 pk->add_opd(in); |
1498 } | 1497 } |
1499 _phase->_igvn.register_new_node_with_optimizer(pk); | 1498 _igvn.register_new_node_with_optimizer(pk); |
1500 _phase->set_ctrl(pk, _phase->get_ctrl(opd)); | 1499 _phase->set_ctrl(pk, _phase->get_ctrl(opd)); |
1501 #ifdef ASSERT | 1500 #ifdef ASSERT |
1502 if (TraceNewVectors) { | 1501 if (TraceNewVectors) { |
1503 tty->print("new Vector node: "); | 1502 tty->print("new Vector node: "); |
1504 pk->dump(); | 1503 pk->dump(); |
1541 // Insert extract operation | 1540 // Insert extract operation |
1542 _igvn.hash_delete(def); | 1541 _igvn.hash_delete(def); |
1543 int def_pos = alignment(def) / data_size(def); | 1542 int def_pos = alignment(def) / data_size(def); |
1544 | 1543 |
1545 Node* ex = ExtractNode::make(_phase->C, def, def_pos, velt_basic_type(def)); | 1544 Node* ex = ExtractNode::make(_phase->C, def, def_pos, velt_basic_type(def)); |
1546 _phase->_igvn.register_new_node_with_optimizer(ex); | 1545 _igvn.register_new_node_with_optimizer(ex); |
1547 _phase->set_ctrl(ex, _phase->get_ctrl(def)); | 1546 _phase->set_ctrl(ex, _phase->get_ctrl(def)); |
1548 _igvn.replace_input_of(use, idx, ex); | 1547 _igvn.replace_input_of(use, idx, ex); |
1549 _igvn._worklist.push(def); | 1548 _igvn._worklist.push(def); |
1550 | 1549 |
1551 bb_insert_after(ex, bb_idx(def)); | 1550 bb_insert_after(ex, bb_idx(def)); |
2021 Node *e = offsn; | 2020 Node *e = offsn; |
2022 if (align_to_ref_p.invar() != NULL) { | 2021 if (align_to_ref_p.invar() != NULL) { |
2023 // incorporate any extra invariant piece producing (offset +/- invar) >>> log2(elt) | 2022 // incorporate any extra invariant piece producing (offset +/- invar) >>> log2(elt) |
2024 Node* log2_elt = _igvn.intcon(exact_log2(elt_size)); | 2023 Node* log2_elt = _igvn.intcon(exact_log2(elt_size)); |
2025 Node* aref = new (_phase->C, 3) URShiftINode(align_to_ref_p.invar(), log2_elt); | 2024 Node* aref = new (_phase->C, 3) URShiftINode(align_to_ref_p.invar(), log2_elt); |
2026 _phase->_igvn.register_new_node_with_optimizer(aref); | 2025 _igvn.register_new_node_with_optimizer(aref); |
2027 _phase->set_ctrl(aref, pre_ctrl); | 2026 _phase->set_ctrl(aref, pre_ctrl); |
2028 if (align_to_ref_p.negate_invar()) { | 2027 if (align_to_ref_p.negate_invar()) { |
2029 e = new (_phase->C, 3) SubINode(e, aref); | 2028 e = new (_phase->C, 3) SubINode(e, aref); |
2030 } else { | 2029 } else { |
2031 e = new (_phase->C, 3) AddINode(e, aref); | 2030 e = new (_phase->C, 3) AddINode(e, aref); |
2032 } | 2031 } |
2033 _phase->_igvn.register_new_node_with_optimizer(e); | 2032 _igvn.register_new_node_with_optimizer(e); |
2034 _phase->set_ctrl(e, pre_ctrl); | 2033 _phase->set_ctrl(e, pre_ctrl); |
2035 } | 2034 } |
2036 if (vw > ObjectAlignmentInBytes) { | 2035 if (vw > ObjectAlignmentInBytes) { |
2037 // incorporate base e +/- base && Mask >>> log2(elt) | 2036 // incorporate base e +/- base && Mask >>> log2(elt) |
2038 Node* xbase = new(_phase->C, 2) CastP2XNode(NULL, align_to_ref_p.base()); | 2037 Node* xbase = new(_phase->C, 2) CastP2XNode(NULL, align_to_ref_p.base()); |
2039 _phase->_igvn.register_new_node_with_optimizer(xbase); | 2038 _igvn.register_new_node_with_optimizer(xbase); |
2040 #ifdef _LP64 | 2039 #ifdef _LP64 |
2041 xbase = new (_phase->C, 2) ConvL2INode(xbase); | 2040 xbase = new (_phase->C, 2) ConvL2INode(xbase); |
2042 _phase->_igvn.register_new_node_with_optimizer(xbase); | 2041 _igvn.register_new_node_with_optimizer(xbase); |
2043 #endif | 2042 #endif |
2044 Node* mask = _igvn.intcon(vw-1); | 2043 Node* mask = _igvn.intcon(vw-1); |
2045 Node* masked_xbase = new (_phase->C, 3) AndINode(xbase, mask); | 2044 Node* masked_xbase = new (_phase->C, 3) AndINode(xbase, mask); |
2046 _phase->_igvn.register_new_node_with_optimizer(masked_xbase); | 2045 _igvn.register_new_node_with_optimizer(masked_xbase); |
2047 Node* log2_elt = _igvn.intcon(exact_log2(elt_size)); | 2046 Node* log2_elt = _igvn.intcon(exact_log2(elt_size)); |
2048 Node* bref = new (_phase->C, 3) URShiftINode(masked_xbase, log2_elt); | 2047 Node* bref = new (_phase->C, 3) URShiftINode(masked_xbase, log2_elt); |
2049 _phase->_igvn.register_new_node_with_optimizer(bref); | 2048 _igvn.register_new_node_with_optimizer(bref); |
2050 _phase->set_ctrl(bref, pre_ctrl); | 2049 _phase->set_ctrl(bref, pre_ctrl); |
2051 e = new (_phase->C, 3) AddINode(e, bref); | 2050 e = new (_phase->C, 3) AddINode(e, bref); |
2052 _phase->_igvn.register_new_node_with_optimizer(e); | 2051 _igvn.register_new_node_with_optimizer(e); |
2053 _phase->set_ctrl(e, pre_ctrl); | 2052 _phase->set_ctrl(e, pre_ctrl); |
2054 } | 2053 } |
2055 | 2054 |
2056 // compute e +/- lim0 | 2055 // compute e +/- lim0 |
2057 if (scale < 0) { | 2056 if (scale < 0) { |
2058 e = new (_phase->C, 3) SubINode(e, lim0); | 2057 e = new (_phase->C, 3) SubINode(e, lim0); |
2059 } else { | 2058 } else { |
2060 e = new (_phase->C, 3) AddINode(e, lim0); | 2059 e = new (_phase->C, 3) AddINode(e, lim0); |
2061 } | 2060 } |
2062 _phase->_igvn.register_new_node_with_optimizer(e); | 2061 _igvn.register_new_node_with_optimizer(e); |
2063 _phase->set_ctrl(e, pre_ctrl); | 2062 _phase->set_ctrl(e, pre_ctrl); |
2064 | 2063 |
2065 if (stride * scale > 0) { | 2064 if (stride * scale > 0) { |
2066 // compute V - (e +/- lim0) | 2065 // compute V - (e +/- lim0) |
2067 Node* va = _igvn.intcon(v_align); | 2066 Node* va = _igvn.intcon(v_align); |
2068 e = new (_phase->C, 3) SubINode(va, e); | 2067 e = new (_phase->C, 3) SubINode(va, e); |
2069 _phase->_igvn.register_new_node_with_optimizer(e); | 2068 _igvn.register_new_node_with_optimizer(e); |
2070 _phase->set_ctrl(e, pre_ctrl); | 2069 _phase->set_ctrl(e, pre_ctrl); |
2071 } | 2070 } |
2072 // compute N = (exp) % V | 2071 // compute N = (exp) % V |
2073 Node* va_msk = _igvn.intcon(v_align - 1); | 2072 Node* va_msk = _igvn.intcon(v_align - 1); |
2074 Node* N = new (_phase->C, 3) AndINode(e, va_msk); | 2073 Node* N = new (_phase->C, 3) AndINode(e, va_msk); |
2075 _phase->_igvn.register_new_node_with_optimizer(N); | 2074 _igvn.register_new_node_with_optimizer(N); |
2076 _phase->set_ctrl(N, pre_ctrl); | 2075 _phase->set_ctrl(N, pre_ctrl); |
2077 | 2076 |
2078 // substitute back into (1), so that new limit | 2077 // substitute back into (1), so that new limit |
2079 // lim = lim0 + N | 2078 // lim = lim0 + N |
2080 Node* lim; | 2079 Node* lim; |
2081 if (stride < 0) { | 2080 if (stride < 0) { |
2082 lim = new (_phase->C, 3) SubINode(lim0, N); | 2081 lim = new (_phase->C, 3) SubINode(lim0, N); |
2083 } else { | 2082 } else { |
2084 lim = new (_phase->C, 3) AddINode(lim0, N); | 2083 lim = new (_phase->C, 3) AddINode(lim0, N); |
2085 } | 2084 } |
2086 _phase->_igvn.register_new_node_with_optimizer(lim); | 2085 _igvn.register_new_node_with_optimizer(lim); |
2087 _phase->set_ctrl(lim, pre_ctrl); | 2086 _phase->set_ctrl(lim, pre_ctrl); |
2088 Node* constrained = | 2087 Node* constrained = |
2089 (stride > 0) ? (Node*) new (_phase->C,3) MinINode(lim, orig_limit) | 2088 (stride > 0) ? (Node*) new (_phase->C,3) MinINode(lim, orig_limit) |
2090 : (Node*) new (_phase->C,3) MaxINode(lim, orig_limit); | 2089 : (Node*) new (_phase->C,3) MaxINode(lim, orig_limit); |
2091 _phase->_igvn.register_new_node_with_optimizer(constrained); | 2090 _igvn.register_new_node_with_optimizer(constrained); |
2092 _phase->set_ctrl(constrained, pre_ctrl); | 2091 _phase->set_ctrl(constrained, pre_ctrl); |
2093 _igvn.hash_delete(pre_opaq); | 2092 _igvn.hash_delete(pre_opaq); |
2094 pre_opaq->set_req(1, constrained); | 2093 pre_opaq->set_req(1, constrained); |
2095 } | 2094 } |
2096 | 2095 |