# HG changeset patch # User kvn # Date 1348613297 25200 # Node ID 06f52c4d0e188e7a54256671d54a679c728ab810 # Parent 0702f188baeb990e4bba2e83af4bde43b7b5ed70 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 diff -r 0702f188baeb -r 06f52c4d0e18 src/share/vm/opto/superword.cpp --- a/src/share/vm/opto/superword.cpp Tue Sep 25 10:41:15 2012 -0700 +++ b/src/share/vm/opto/superword.cpp Tue Sep 25 15:48:17 2012 -0700 @@ -1088,23 +1088,22 @@ uint start, end; VectorNode::vector_operands(p0, &start, &end); - // Return false if some input is not vector and inside block + // Return false if some inputs are not vectors or vectors with different + // size or alignment. + // Also, for now, return false if not scalar promotion case when inputs are + // the same. Later, implement PackNode and allow differing, non-vector inputs + // (maybe just the ones from outside the block.) for (uint i = start; i < end; i++) { - if (!is_vector_use(p0, i)) { - // For now, return false if not scalar promotion case (inputs are the same.) - // Later, implement PackNode and allow differing, non-vector inputs - // (maybe just the ones from outside the block.) - if (!same_inputs(p, i)) { - return false; - } - } + if (!is_vector_use(p0, i)) + return false; } if (VectorNode::is_shift(p0)) { - // For now, return false if shift count is vector because - // hw does not support it. - if (is_vector_use(p0, 2)) + // For now, return false if shift count is vector or not scalar promotion + // case (different shift counts) because it is not supported yet. + Node* cnt = p0->in(2); + Node_List* cnt_pk = my_pack(cnt); + if (cnt_pk != NULL) return false; - // For the same reason return false if different shift counts. if (!same_inputs(p, 2)) return false; } @@ -1402,7 +1401,7 @@ ShouldNotReachHere(); } assert(vn != NULL, "sanity"); - _phase->_igvn.register_new_node_with_optimizer(vn); + _igvn.register_new_node_with_optimizer(vn); _phase->set_ctrl(vn, _phase->get_ctrl(p->at(0))); for (uint j = 0; j < p->size(); j++) { Node* pm = p->at(j); @@ -1451,9 +1450,9 @@ } else { if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) { cnt = ConNode::make(C, TypeInt::make(mask)); - _phase->_igvn.register_new_node_with_optimizer(cnt); + _igvn.register_new_node_with_optimizer(cnt); cnt = new (C, 3) AndINode(opd, cnt); - _phase->_igvn.register_new_node_with_optimizer(cnt); + _igvn.register_new_node_with_optimizer(cnt); _phase->set_ctrl(cnt, _phase->get_ctrl(opd)); } assert(opd->bottom_type()->isa_int(), "int type only"); @@ -1461,7 +1460,7 @@ cnt = new (C, 2) MoveI2FNode(cnt); } if (cnt != opd) { - _phase->_igvn.register_new_node_with_optimizer(cnt); + _igvn.register_new_node_with_optimizer(cnt); _phase->set_ctrl(cnt, _phase->get_ctrl(opd)); } return cnt; @@ -1473,7 +1472,7 @@ const Type* p0_t = velt_type(p0); VectorNode* vn = VectorNode::scalar2vector(_phase->C, opd, vlen, p0_t); - _phase->_igvn.register_new_node_with_optimizer(vn); + _igvn.register_new_node_with_optimizer(vn); _phase->set_ctrl(vn, _phase->get_ctrl(opd)); #ifdef ASSERT if (TraceNewVectors) { @@ -1496,7 +1495,7 @@ assert(opd_bt == in->bottom_type()->basic_type(), "all same type"); pk->add_opd(in); } - _phase->_igvn.register_new_node_with_optimizer(pk); + _igvn.register_new_node_with_optimizer(pk); _phase->set_ctrl(pk, _phase->get_ctrl(opd)); #ifdef ASSERT if (TraceNewVectors) { @@ -1543,7 +1542,7 @@ int def_pos = alignment(def) / data_size(def); Node* ex = ExtractNode::make(_phase->C, def, def_pos, velt_basic_type(def)); - _phase->_igvn.register_new_node_with_optimizer(ex); + _igvn.register_new_node_with_optimizer(ex); _phase->set_ctrl(ex, _phase->get_ctrl(def)); _igvn.replace_input_of(use, idx, ex); _igvn._worklist.push(def); @@ -2023,33 +2022,33 @@ // incorporate any extra invariant piece producing (offset +/- invar) >>> log2(elt) Node* log2_elt = _igvn.intcon(exact_log2(elt_size)); Node* aref = new (_phase->C, 3) URShiftINode(align_to_ref_p.invar(), log2_elt); - _phase->_igvn.register_new_node_with_optimizer(aref); + _igvn.register_new_node_with_optimizer(aref); _phase->set_ctrl(aref, pre_ctrl); if (align_to_ref_p.negate_invar()) { e = new (_phase->C, 3) SubINode(e, aref); } else { e = new (_phase->C, 3) AddINode(e, aref); } - _phase->_igvn.register_new_node_with_optimizer(e); + _igvn.register_new_node_with_optimizer(e); _phase->set_ctrl(e, pre_ctrl); } if (vw > ObjectAlignmentInBytes) { // incorporate base e +/- base && Mask >>> log2(elt) Node* xbase = new(_phase->C, 2) CastP2XNode(NULL, align_to_ref_p.base()); - _phase->_igvn.register_new_node_with_optimizer(xbase); + _igvn.register_new_node_with_optimizer(xbase); #ifdef _LP64 xbase = new (_phase->C, 2) ConvL2INode(xbase); - _phase->_igvn.register_new_node_with_optimizer(xbase); + _igvn.register_new_node_with_optimizer(xbase); #endif Node* mask = _igvn.intcon(vw-1); Node* masked_xbase = new (_phase->C, 3) AndINode(xbase, mask); - _phase->_igvn.register_new_node_with_optimizer(masked_xbase); + _igvn.register_new_node_with_optimizer(masked_xbase); Node* log2_elt = _igvn.intcon(exact_log2(elt_size)); Node* bref = new (_phase->C, 3) URShiftINode(masked_xbase, log2_elt); - _phase->_igvn.register_new_node_with_optimizer(bref); + _igvn.register_new_node_with_optimizer(bref); _phase->set_ctrl(bref, pre_ctrl); e = new (_phase->C, 3) AddINode(e, bref); - _phase->_igvn.register_new_node_with_optimizer(e); + _igvn.register_new_node_with_optimizer(e); _phase->set_ctrl(e, pre_ctrl); } @@ -2059,20 +2058,20 @@ } else { e = new (_phase->C, 3) AddINode(e, lim0); } - _phase->_igvn.register_new_node_with_optimizer(e); + _igvn.register_new_node_with_optimizer(e); _phase->set_ctrl(e, pre_ctrl); if (stride * scale > 0) { // compute V - (e +/- lim0) Node* va = _igvn.intcon(v_align); e = new (_phase->C, 3) SubINode(va, e); - _phase->_igvn.register_new_node_with_optimizer(e); + _igvn.register_new_node_with_optimizer(e); _phase->set_ctrl(e, pre_ctrl); } // compute N = (exp) % V Node* va_msk = _igvn.intcon(v_align - 1); Node* N = new (_phase->C, 3) AndINode(e, va_msk); - _phase->_igvn.register_new_node_with_optimizer(N); + _igvn.register_new_node_with_optimizer(N); _phase->set_ctrl(N, pre_ctrl); // substitute back into (1), so that new limit @@ -2083,12 +2082,12 @@ } else { lim = new (_phase->C, 3) AddINode(lim0, N); } - _phase->_igvn.register_new_node_with_optimizer(lim); + _igvn.register_new_node_with_optimizer(lim); _phase->set_ctrl(lim, pre_ctrl); Node* constrained = (stride > 0) ? (Node*) new (_phase->C,3) MinINode(lim, orig_limit) : (Node*) new (_phase->C,3) MaxINode(lim, orig_limit); - _phase->_igvn.register_new_node_with_optimizer(constrained); + _igvn.register_new_node_with_optimizer(constrained); _phase->set_ctrl(constrained, pre_ctrl); _igvn.hash_delete(pre_opaq); pre_opaq->set_req(1, constrained); diff -r 0702f188baeb -r 06f52c4d0e18 test/compiler/7200264/Test7200264.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/7200264/Test7200264.sh Tue Sep 25 15:48:17 2012 -0700 @@ -0,0 +1,150 @@ +#!/bin/sh +# +# Copyright (c) 2012, 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. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# + +if [ "${TESTSRC}" = "" ] +then + echo "TESTSRC not set. Test cannot execute. Failed." + exit 1 +fi +echo "TESTSRC=${TESTSRC}" +if [ "${TESTJAVA}" = "" ] +then + echo "TESTJAVA not set. Test cannot execute. Failed." + exit 1 +fi +echo "TESTJAVA=${TESTJAVA}" +if [ "${TESTCLASSES}" = "" ] +then + echo "TESTCLASSES not set. Test cannot execute. Failed." + exit 1 +fi +echo "TESTCLASSES=${TESTCLASSES}" +echo "CLASSPATH=${CLASSPATH}" + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + SunOS | Linux | Darwin ) + NULL=/dev/null + PS=":" + FS="/" + ;; + Windows_* ) + NULL=NUL + PS=";" + FS="\\" + ;; + CYGWIN_* ) + NULL=/dev/null + PS=";" + FS="/" + ;; + * ) + echo "Unrecognized system!" + exit 1; + ;; +esac + + +${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xinternalversion | sed 's/amd64/x86/' | grep "x86" | grep "Server VM" | grep "debug" + +# Only test fastdebug Server VM on x86 +if [ $? != 0 ] +then + echo "Test Passed" + exit 0 +fi + +cp ${TESTSRC}${FS}TestIntVect.java . +${TESTJAVA}${FS}bin${FS}javac -d . TestIntVect.java + +${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xbatch -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+PrintCompilation -XX:+TraceNewVectors TestIntVect > test.out 2>&1 + +COUNT=`grep AddVI test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 4 ] +then + echo "Test Failed: AddVI $COUNT < 4" + exit 1 +fi + +# AddVI is generated for test_subc +COUNT=`grep SubVI test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 4 ] +then + echo "Test Failed: SubVI $COUNT < 4" + exit 1 +fi + +# LShiftVI+SubVI is generated for test_mulc +COUNT=`grep MulVI test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 2 ] +then + echo "Test Failed: MulVI $COUNT < 2" + exit 1 +fi + +COUNT=`grep AndV test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 3 ] +then + echo "Test Failed: AndV $COUNT < 3" + exit 1 +fi + +COUNT=`grep OrV test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 3 ] +then + echo "Test Failed: OrV $COUNT < 3" + exit 1 +fi + +COUNT=`grep XorV test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 3 ] +then + echo "Test Failed: XorV $COUNT < 3" + exit 1 +fi + +COUNT=`grep LShiftVI test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 5 ] +then + echo "Test Failed: LShiftVI $COUNT < 5" + exit 1 +fi + +# RShiftVI + URShiftVI +COUNT=`grep RShiftVI test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 6 ] +then + echo "Test Failed: RShiftVI $COUNT < 6" + exit 1 +fi + +COUNT=`grep URShiftVI test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 3 ] +then + echo "Test Failed: URShiftVI $COUNT < 3" + exit 1 +fi + diff -r 0702f188baeb -r 06f52c4d0e18 test/compiler/7200264/TestIntVect.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/7200264/TestIntVect.java Tue Sep 25 15:48:17 2012 -0700 @@ -0,0 +1,650 @@ +/* + * Copyright (c) 2012, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @bug 7200264 + * @summary 7192963 changes disabled shift vectors + * + * @run shell Test7200264.sh + */ + +/* + * Copy of test/compiler/6340864/TestIntVect.java without performance tests. + */ +public class TestIntVect { + private static final int ARRLEN = 997; + private static final int ITERS = 11000; + private static final int ADD_INIT = Integer.MAX_VALUE-500; + private static final int BIT_MASK = 0xEC80F731; + private static final int VALUE = 15; + private static final int SHIFT = 32; + + public static void main(String args[]) { + System.out.println("Testing Integer vectors"); + int errn = test(); + if (errn > 0) { + System.err.println("FAILED: " + errn + " errors"); + System.exit(97); + } + System.out.println("PASSED"); + } + + static int test() { + int[] a0 = new int[ARRLEN]; + int[] a1 = new int[ARRLEN]; + int[] a2 = new int[ARRLEN]; + int[] a3 = new int[ARRLEN]; + int[] a4 = new int[ARRLEN]; + long[] p2 = new long[ARRLEN/2]; + // Initialize + int gold_sum = 0; + for (int i=0; i>>VALUE)); + } + test_srlv(a0, a1, VALUE); + for (int i=0; i>>VALUE)); + } + + test_srac(a0, a1); + for (int i=0; i>VALUE)); + } + test_srav(a0, a1, VALUE); + for (int i=0; i>VALUE)); + } + + test_sllc_n(a0, a1); + for (int i=0; i>>(-VALUE))); + } + test_srlv(a0, a1, -VALUE); + for (int i=0; i>>(-VALUE))); + } + + test_srac_n(a0, a1); + for (int i=0; i>(-VALUE))); + } + test_srav(a0, a1, -VALUE); + for (int i=0; i>(-VALUE))); + } + + test_sllc_o(a0, a1); + for (int i=0; i>>SHIFT)); + } + test_srlv(a0, a1, SHIFT); + for (int i=0; i>>SHIFT)); + } + + test_srac_o(a0, a1); + for (int i=0; i>SHIFT)); + } + test_srav(a0, a1, SHIFT); + for (int i=0; i>SHIFT)); + } + + test_sllc_on(a0, a1); + for (int i=0; i>>(-SHIFT))); + } + test_srlv(a0, a1, -SHIFT); + for (int i=0; i>>(-SHIFT))); + } + + test_srac_on(a0, a1); + for (int i=0; i>(-SHIFT))); + } + test_srav(a0, a1, -SHIFT); + for (int i=0; i>(-SHIFT))); + } + + test_pack2(p2, a1); + for (int i=0; i>>VALUE); + } + } + static void test_srlc_n(int[] a0, int[] a1) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>>(-VALUE)); + } + } + static void test_srlc_o(int[] a0, int[] a1) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>>SHIFT); + } + } + static void test_srlc_on(int[] a0, int[] a1) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>>(-SHIFT)); + } + } + static void test_srlv(int[] a0, int[] a1, int b) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>>b); + } + } + + static void test_srac(int[] a0, int[] a1) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>VALUE); + } + } + static void test_srac_n(int[] a0, int[] a1) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>(-VALUE)); + } + } + static void test_srac_o(int[] a0, int[] a1) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>SHIFT); + } + } + static void test_srac_on(int[] a0, int[] a1) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>(-SHIFT)); + } + } + static void test_srav(int[] a0, int[] a1, int b) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>b); + } + } + + static void test_pack2(long[] p2, int[] a1) { + if (p2.length*2 > a1.length) return; + for (int i = 0; i < p2.length; i+=1) { + long l0 = (long)a1[i*2+0]; + long l1 = (long)a1[i*2+1]; + p2[i] = (l1 << 32) | (l0 & 0xFFFFFFFFl); + } + } + static void test_unpack2(int[] a0, long[] p2) { + if (p2.length*2 > a0.length) return; + for (int i = 0; i < p2.length; i+=1) { + long l = p2[i]; + a0[i*2+0] = (int)(l & 0xFFFFFFFFl); + a0[i*2+1] = (int)(l >> 32); + } + } + static void test_pack2_swap(long[] p2, int[] a1) { + if (p2.length*2 > a1.length) return; + for (int i = 0; i < p2.length; i+=1) { + long l0 = (long)a1[i*2+0]; + long l1 = (long)a1[i*2+1]; + p2[i] = (l0 << 32) | (l1 & 0xFFFFFFFFl); + } + } + static void test_unpack2_swap(int[] a0, long[] p2) { + if (p2.length*2 > a0.length) return; + for (int i = 0; i < p2.length; i+=1) { + long l = p2[i]; + a0[i*2+0] = (int)(l >> 32); + a0[i*2+1] = (int)(l & 0xFFFFFFFFl); + } + } + + static int verify(String text, int i, int elem, int val) { + if (elem != val) { + System.err.println(text + "[" + i + "] = " + elem + " != " + val); + return 1; + } + return 0; + } + + static int verify(String text, int i, long elem, long val) { + if (elem != val) { + System.err.println(text + "[" + i + "] = " + Long.toHexString(elem) + " != " + Long.toHexString(val)); + return 1; + } + return 0; + } +}