6964479: widen normalization of small int and long values should be symmetric

Mon, 28 Jun 2010 10:52:50 -0700

author
kvn
date
Mon, 28 Jun 2010 10:52:50 -0700
changeset 1975
d678e3277048
parent 1973
5f249b390094
child 1976
6027dddc26c6

6964479: widen normalization of small int and long values should be symmetric
Summary: normalize widen value in xmeet() and xdual() methods for types Int and Long so the type meet will be symmetric.
Reviewed-by: jrose

src/share/vm/opto/type.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/opto/type.cpp	Wed Jun 23 09:40:11 2010 -0700
     1.2 +++ b/src/share/vm/opto/type.cpp	Mon Jun 28 10:52:50 2010 -0700
     1.3 @@ -182,6 +182,8 @@
     1.4    return t->hash();
     1.5  }
     1.6  
     1.7 +#define SMALLINT ((juint)3)  // a value too insignificant to consider widening
     1.8 +
     1.9  //--------------------------Initialize_shared----------------------------------
    1.10  void Type::Initialize_shared(Compile* current) {
    1.11    // This method does not need to be locked because the first system
    1.12 @@ -240,6 +242,7 @@
    1.13    assert( TypeInt::CC_GT == TypeInt::ONE,     "types must match for CmpL to work" );
    1.14    assert( TypeInt::CC_EQ == TypeInt::ZERO,    "types must match for CmpL to work" );
    1.15    assert( TypeInt::CC_GE == TypeInt::BOOL,    "types must match for CmpL to work" );
    1.16 +  assert( (juint)(TypeInt::CC->_hi - TypeInt::CC->_lo) <= SMALLINT, "CC is truly small");
    1.17  
    1.18    TypeLong::MINUS_1 = TypeLong::make(-1);        // -1
    1.19    TypeLong::ZERO    = TypeLong::make( 0);        //  0
    1.20 @@ -1054,16 +1057,21 @@
    1.21    return (TypeInt*)(new TypeInt(lo,lo,WidenMin))->hashcons();
    1.22  }
    1.23  
    1.24 -#define SMALLINT ((juint)3)  // a value too insignificant to consider widening
    1.25 -
    1.26 -const TypeInt *TypeInt::make( jint lo, jint hi, int w ) {
    1.27 +static int normalize_int_widen( jint lo, jint hi, int w ) {
    1.28    // Certain normalizations keep us sane when comparing types.
    1.29    // The 'SMALLINT' covers constants and also CC and its relatives.
    1.30 -  assert(CC == NULL || (juint)(CC->_hi - CC->_lo) <= SMALLINT, "CC is truly small");
    1.31    if (lo <= hi) {
    1.32 -    if ((juint)(hi - lo) <= SMALLINT)   w = Type::WidenMin;
    1.33 -    if ((juint)(hi - lo) >= max_juint)  w = Type::WidenMax; // plain int
    1.34 +    if ((juint)(hi - lo) <= SMALLINT)  w = Type::WidenMin;
    1.35 +    if ((juint)(hi - lo) >= max_juint) w = Type::WidenMax; // TypeInt::INT
    1.36 +  } else {
    1.37 +    if ((juint)(lo - hi) <= SMALLINT)  w = Type::WidenMin;
    1.38 +    if ((juint)(lo - hi) >= max_juint) w = Type::WidenMin; // dual TypeInt::INT
    1.39    }
    1.40 +  return w;
    1.41 +}
    1.42 +
    1.43 +const TypeInt *TypeInt::make( jint lo, jint hi, int w ) {
    1.44 +  w = normalize_int_widen(lo, hi, w);
    1.45    return (TypeInt*)(new TypeInt(lo,hi,w))->hashcons();
    1.46  }
    1.47  
    1.48 @@ -1103,14 +1111,14 @@
    1.49  
    1.50    // Expand covered set
    1.51    const TypeInt *r = t->is_int();
    1.52 -  // (Avoid TypeInt::make, to avoid the argument normalizations it enforces.)
    1.53 -  return (new TypeInt( MIN2(_lo,r->_lo), MAX2(_hi,r->_hi), MAX2(_widen,r->_widen) ))->hashcons();
    1.54 +  return make( MIN2(_lo,r->_lo), MAX2(_hi,r->_hi), MAX2(_widen,r->_widen) );
    1.55  }
    1.56  
    1.57  //------------------------------xdual------------------------------------------
    1.58  // Dual: reverse hi & lo; flip widen
    1.59  const Type *TypeInt::xdual() const {
    1.60 -  return new TypeInt(_hi,_lo,WidenMax-_widen);
    1.61 +  int w = normalize_int_widen(_hi,_lo, WidenMax-_widen);
    1.62 +  return new TypeInt(_hi,_lo,w);
    1.63  }
    1.64  
    1.65  //------------------------------widen------------------------------------------
    1.66 @@ -1202,7 +1210,7 @@
    1.67  //-----------------------------filter------------------------------------------
    1.68  const Type *TypeInt::filter( const Type *kills ) const {
    1.69    const TypeInt* ft = join(kills)->isa_int();
    1.70 -  if (ft == NULL || ft->_lo > ft->_hi)
    1.71 +  if (ft == NULL || ft->empty())
    1.72      return Type::TOP;           // Canonical empty value
    1.73    if (ft->_widen < this->_widen) {
    1.74      // Do not allow the value of kill->_widen to affect the outcome.
    1.75 @@ -1304,13 +1312,21 @@
    1.76    return (TypeLong*)(new TypeLong(lo,lo,WidenMin))->hashcons();
    1.77  }
    1.78  
    1.79 +static int normalize_long_widen( jlong lo, jlong hi, int w ) {
    1.80 +  // Certain normalizations keep us sane when comparing types.
    1.81 +  // The 'SMALLINT' covers constants.
    1.82 +  if (lo <= hi) {
    1.83 +    if ((julong)(hi - lo) <= SMALLINT)   w = Type::WidenMin;
    1.84 +    if ((julong)(hi - lo) >= max_julong) w = Type::WidenMax; // TypeLong::LONG
    1.85 +  } else {
    1.86 +    if ((julong)(lo - hi) <= SMALLINT)   w = Type::WidenMin;
    1.87 +    if ((julong)(lo - hi) >= max_julong) w = Type::WidenMin; // dual TypeLong::LONG
    1.88 +  }
    1.89 +  return w;
    1.90 +}
    1.91 +
    1.92  const TypeLong *TypeLong::make( jlong lo, jlong hi, int w ) {
    1.93 -  // Certain normalizations keep us sane when comparing types.
    1.94 -  // The '1' covers constants.
    1.95 -  if (lo <= hi) {
    1.96 -    if ((julong)(hi - lo) <= SMALLINT)    w = Type::WidenMin;
    1.97 -    if ((julong)(hi - lo) >= max_julong)  w = Type::WidenMax; // plain long
    1.98 -  }
    1.99 +  w = normalize_long_widen(lo, hi, w);
   1.100    return (TypeLong*)(new TypeLong(lo,hi,w))->hashcons();
   1.101  }
   1.102  
   1.103 @@ -1351,14 +1367,14 @@
   1.104  
   1.105    // Expand covered set
   1.106    const TypeLong *r = t->is_long(); // Turn into a TypeLong
   1.107 -  // (Avoid TypeLong::make, to avoid the argument normalizations it enforces.)
   1.108 -  return (new TypeLong( MIN2(_lo,r->_lo), MAX2(_hi,r->_hi), MAX2(_widen,r->_widen) ))->hashcons();
   1.109 +  return make( MIN2(_lo,r->_lo), MAX2(_hi,r->_hi), MAX2(_widen,r->_widen) );
   1.110  }
   1.111  
   1.112  //------------------------------xdual------------------------------------------
   1.113  // Dual: reverse hi & lo; flip widen
   1.114  const Type *TypeLong::xdual() const {
   1.115 -  return new TypeLong(_hi,_lo,WidenMax-_widen);
   1.116 +  int w = normalize_long_widen(_hi,_lo, WidenMax-_widen);
   1.117 +  return new TypeLong(_hi,_lo,w);
   1.118  }
   1.119  
   1.120  //------------------------------widen------------------------------------------
   1.121 @@ -1453,7 +1469,7 @@
   1.122  //-----------------------------filter------------------------------------------
   1.123  const Type *TypeLong::filter( const Type *kills ) const {
   1.124    const TypeLong* ft = join(kills)->isa_long();
   1.125 -  if (ft == NULL || ft->_lo > ft->_hi)
   1.126 +  if (ft == NULL || ft->empty())
   1.127      return Type::TOP;           // Canonical empty value
   1.128    if (ft->_widen < this->_widen) {
   1.129      // Do not allow the value of kill->_widen to affect the outcome.

mercurial