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