提交 f1d9f548 编写于 作者: K kvn

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
上级 b7890cff
......@@ -182,6 +182,8 @@ int Type::uhash( const Type *const t ) {
return t->hash();
}
#define SMALLINT ((juint)3) // a value too insignificant to consider widening
//--------------------------Initialize_shared----------------------------------
void Type::Initialize_shared(Compile* current) {
// This method does not need to be locked because the first system
......@@ -240,6 +242,7 @@ void Type::Initialize_shared(Compile* current) {
assert( TypeInt::CC_GT == TypeInt::ONE, "types must match for CmpL to work" );
assert( TypeInt::CC_EQ == TypeInt::ZERO, "types must match for CmpL to work" );
assert( TypeInt::CC_GE == TypeInt::BOOL, "types must match for CmpL to work" );
assert( (juint)(TypeInt::CC->_hi - TypeInt::CC->_lo) <= SMALLINT, "CC is truly small");
TypeLong::MINUS_1 = TypeLong::make(-1); // -1
TypeLong::ZERO = TypeLong::make( 0); // 0
......@@ -1054,16 +1057,21 @@ const TypeInt *TypeInt::make( jint lo ) {
return (TypeInt*)(new TypeInt(lo,lo,WidenMin))->hashcons();
}
#define SMALLINT ((juint)3) // a value too insignificant to consider widening
const TypeInt *TypeInt::make( jint lo, jint hi, int w ) {
static int normalize_int_widen( jint lo, jint hi, int w ) {
// Certain normalizations keep us sane when comparing types.
// The 'SMALLINT' covers constants and also CC and its relatives.
assert(CC == NULL || (juint)(CC->_hi - CC->_lo) <= SMALLINT, "CC is truly small");
if (lo <= hi) {
if ((juint)(hi - lo) <= SMALLINT) w = Type::WidenMin;
if ((juint)(hi - lo) >= max_juint) w = Type::WidenMax; // plain int
if ((juint)(hi - lo) >= max_juint) w = Type::WidenMax; // TypeInt::INT
} else {
if ((juint)(lo - hi) <= SMALLINT) w = Type::WidenMin;
if ((juint)(lo - hi) >= max_juint) w = Type::WidenMin; // dual TypeInt::INT
}
return w;
}
const TypeInt *TypeInt::make( jint lo, jint hi, int w ) {
w = normalize_int_widen(lo, hi, w);
return (TypeInt*)(new TypeInt(lo,hi,w))->hashcons();
}
......@@ -1103,14 +1111,14 @@ const Type *TypeInt::xmeet( const Type *t ) const {
// Expand covered set
const TypeInt *r = t->is_int();
// (Avoid TypeInt::make, to avoid the argument normalizations it enforces.)
return (new TypeInt( MIN2(_lo,r->_lo), MAX2(_hi,r->_hi), MAX2(_widen,r->_widen) ))->hashcons();
return make( MIN2(_lo,r->_lo), MAX2(_hi,r->_hi), MAX2(_widen,r->_widen) );
}
//------------------------------xdual------------------------------------------
// Dual: reverse hi & lo; flip widen
const Type *TypeInt::xdual() const {
return new TypeInt(_hi,_lo,WidenMax-_widen);
int w = normalize_int_widen(_hi,_lo, WidenMax-_widen);
return new TypeInt(_hi,_lo,w);
}
//------------------------------widen------------------------------------------
......@@ -1202,7 +1210,7 @@ const Type *TypeInt::narrow( const Type *old ) const {
//-----------------------------filter------------------------------------------
const Type *TypeInt::filter( const Type *kills ) const {
const TypeInt* ft = join(kills)->isa_int();
if (ft == NULL || ft->_lo > ft->_hi)
if (ft == NULL || ft->empty())
return Type::TOP; // Canonical empty value
if (ft->_widen < this->_widen) {
// Do not allow the value of kill->_widen to affect the outcome.
......@@ -1304,13 +1312,21 @@ const TypeLong *TypeLong::make( jlong lo ) {
return (TypeLong*)(new TypeLong(lo,lo,WidenMin))->hashcons();
}
const TypeLong *TypeLong::make( jlong lo, jlong hi, int w ) {
static int normalize_long_widen( jlong lo, jlong hi, int w ) {
// Certain normalizations keep us sane when comparing types.
// The '1' covers constants.
// The 'SMALLINT' covers constants.
if (lo <= hi) {
if ((julong)(hi - lo) <= SMALLINT) w = Type::WidenMin;
if ((julong)(hi - lo) >= max_julong) w = Type::WidenMax; // plain long
if ((julong)(hi - lo) >= max_julong) w = Type::WidenMax; // TypeLong::LONG
} else {
if ((julong)(lo - hi) <= SMALLINT) w = Type::WidenMin;
if ((julong)(lo - hi) >= max_julong) w = Type::WidenMin; // dual TypeLong::LONG
}
return w;
}
const TypeLong *TypeLong::make( jlong lo, jlong hi, int w ) {
w = normalize_long_widen(lo, hi, w);
return (TypeLong*)(new TypeLong(lo,hi,w))->hashcons();
}
......@@ -1351,14 +1367,14 @@ const Type *TypeLong::xmeet( const Type *t ) const {
// Expand covered set
const TypeLong *r = t->is_long(); // Turn into a TypeLong
// (Avoid TypeLong::make, to avoid the argument normalizations it enforces.)
return (new TypeLong( MIN2(_lo,r->_lo), MAX2(_hi,r->_hi), MAX2(_widen,r->_widen) ))->hashcons();
return make( MIN2(_lo,r->_lo), MAX2(_hi,r->_hi), MAX2(_widen,r->_widen) );
}
//------------------------------xdual------------------------------------------
// Dual: reverse hi & lo; flip widen
const Type *TypeLong::xdual() const {
return new TypeLong(_hi,_lo,WidenMax-_widen);
int w = normalize_long_widen(_hi,_lo, WidenMax-_widen);
return new TypeLong(_hi,_lo,w);
}
//------------------------------widen------------------------------------------
......@@ -1453,7 +1469,7 @@ const Type *TypeLong::narrow( const Type *old ) const {
//-----------------------------filter------------------------------------------
const Type *TypeLong::filter( const Type *kills ) const {
const TypeLong* ft = join(kills)->isa_long();
if (ft == NULL || ft->_lo > ft->_hi)
if (ft == NULL || ft->empty())
return Type::TOP; // Canonical empty value
if (ft->_widen < this->_widen) {
// Do not allow the value of kill->_widen to affect the outcome.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册