src/share/vm/opto/superword.cpp

changeset 4204
b2c669fd8114
parent 4160
f6badecb7ea7
child 4207
410afdc6a07c
     1.1 --- a/src/share/vm/opto/superword.cpp	Mon Oct 22 16:56:03 2012 -0700
     1.2 +++ b/src/share/vm/opto/superword.cpp	Tue Oct 23 13:06:37 2012 -0700
     1.3 @@ -1776,16 +1776,15 @@
     1.4      set_velt_type(n, container_type(n));
     1.5    }
     1.6  
     1.7 -  // Propagate narrowed type backwards through operations
     1.8 +  // Propagate integer narrowed type backwards through operations
     1.9    // that don't depend on higher order bits
    1.10    for (int i = _block.length() - 1; i >= 0; i--) {
    1.11      Node* n = _block.at(i);
    1.12      // Only integer types need be examined
    1.13 -    const Type* vt = velt_type(n);
    1.14 -    if (vt->basic_type() == T_INT) {
    1.15 +    const Type* vtn = velt_type(n);
    1.16 +    if (vtn->basic_type() == T_INT) {
    1.17        uint start, end;
    1.18        VectorNode::vector_operands(n, &start, &end);
    1.19 -      const Type* vt = velt_type(n);
    1.20  
    1.21        for (uint j = start; j < end; j++) {
    1.22          Node* in  = n->in(j);
    1.23 @@ -1801,6 +1800,24 @@
    1.24              }
    1.25            }
    1.26            if (same_type) {
    1.27 +            // For right shifts of small integer types (bool, byte, char, short)
    1.28 +            // we need precise information about sign-ness. Only Load nodes have
    1.29 +            // this information because Store nodes are the same for signed and
    1.30 +            // unsigned values. And any arithmetic operation after a load may
    1.31 +            // expand a value to signed Int so such right shifts can't be used
    1.32 +            // because vector elements do not have upper bits of Int.
    1.33 +            const Type* vt = vtn;
    1.34 +            if (VectorNode::is_shift(in)) {
    1.35 +              Node* load = in->in(1);
    1.36 +              if (load->is_Load() && (velt_type(load)->basic_type() == T_INT)) {
    1.37 +                vt = velt_type(load);
    1.38 +              } else if (in->Opcode() != Op_LShiftI) {
    1.39 +                // Widen type to Int to avoid creation of right shift vector
    1.40 +                // (align + data_size(s1) check in stmts_can_pack() will fail).
    1.41 +                // Note, left shifts work regardless type.
    1.42 +                vt = TypeInt::INT;
    1.43 +              }
    1.44 +            }
    1.45              set_velt_type(in, vt);
    1.46            }
    1.47          }
    1.48 @@ -1841,7 +1858,20 @@
    1.49  // Smallest type containing range of values
    1.50  const Type* SuperWord::container_type(Node* n) {
    1.51    if (n->is_Mem()) {
    1.52 -    return Type::get_const_basic_type(n->as_Mem()->memory_type());
    1.53 +    BasicType bt = n->as_Mem()->memory_type();
    1.54 +    if (n->is_Store() && (bt == T_CHAR)) {
    1.55 +      // Use T_SHORT type instead of T_CHAR for stored values because any
    1.56 +      // preceding arithmetic operation extends values to signed Int.
    1.57 +      bt = T_SHORT;
    1.58 +    }
    1.59 +    if (n->Opcode() == Op_LoadUB) {
    1.60 +      // Adjust type for unsigned byte loads, it is important for right shifts.
    1.61 +      // T_BOOLEAN is used because there is no basic type representing type
    1.62 +      // TypeInt::UBYTE. Use of T_BOOLEAN for vectors is fine because only
    1.63 +      // size (one byte) and sign is important.
    1.64 +      bt = T_BOOLEAN;
    1.65 +    }
    1.66 +    return Type::get_const_basic_type(bt);
    1.67    }
    1.68    const Type* t = _igvn.type(n);
    1.69    if (t->basic_type() == T_INT) {

mercurial