comparison src/share/vm/opto/type.cpp @ 1620:d678e3277048

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
author kvn
date Mon, 28 Jun 2010 10:52:50 -0700
parents c18cbe5936b8
children 14b92b91f460
comparison
equal deleted inserted replaced
1618:5f249b390094 1620:d678e3277048
179 179
180 //------------------------------hash------------------------------------------- 180 //------------------------------hash-------------------------------------------
181 int Type::uhash( const Type *const t ) { 181 int Type::uhash( const Type *const t ) {
182 return t->hash(); 182 return t->hash();
183 } 183 }
184
185 #define SMALLINT ((juint)3) // a value too insignificant to consider widening
184 186
185 //--------------------------Initialize_shared---------------------------------- 187 //--------------------------Initialize_shared----------------------------------
186 void Type::Initialize_shared(Compile* current) { 188 void Type::Initialize_shared(Compile* current) {
187 // This method does not need to be locked because the first system 189 // This method does not need to be locked because the first system
188 // compilations (stub compilations) occur serially. If they are 190 // compilations (stub compilations) occur serially. If they are
238 // compare returning optimizer ideal-type flags. 240 // compare returning optimizer ideal-type flags.
239 assert( TypeInt::CC_LT == TypeInt::MINUS_1, "types must match for CmpL to work" ); 241 assert( TypeInt::CC_LT == TypeInt::MINUS_1, "types must match for CmpL to work" );
240 assert( TypeInt::CC_GT == TypeInt::ONE, "types must match for CmpL to work" ); 242 assert( TypeInt::CC_GT == TypeInt::ONE, "types must match for CmpL to work" );
241 assert( TypeInt::CC_EQ == TypeInt::ZERO, "types must match for CmpL to work" ); 243 assert( TypeInt::CC_EQ == TypeInt::ZERO, "types must match for CmpL to work" );
242 assert( TypeInt::CC_GE == TypeInt::BOOL, "types must match for CmpL to work" ); 244 assert( TypeInt::CC_GE == TypeInt::BOOL, "types must match for CmpL to work" );
245 assert( (juint)(TypeInt::CC->_hi - TypeInt::CC->_lo) <= SMALLINT, "CC is truly small");
243 246
244 TypeLong::MINUS_1 = TypeLong::make(-1); // -1 247 TypeLong::MINUS_1 = TypeLong::make(-1); // -1
245 TypeLong::ZERO = TypeLong::make( 0); // 0 248 TypeLong::ZERO = TypeLong::make( 0); // 0
246 TypeLong::ONE = TypeLong::make( 1); // 1 249 TypeLong::ONE = TypeLong::make( 1); // 1
247 TypeLong::POS = TypeLong::make(0,max_jlong, WidenMin); // Non-neg values 250 TypeLong::POS = TypeLong::make(0,max_jlong, WidenMin); // Non-neg values
1052 //------------------------------make------------------------------------------- 1055 //------------------------------make-------------------------------------------
1053 const TypeInt *TypeInt::make( jint lo ) { 1056 const TypeInt *TypeInt::make( jint lo ) {
1054 return (TypeInt*)(new TypeInt(lo,lo,WidenMin))->hashcons(); 1057 return (TypeInt*)(new TypeInt(lo,lo,WidenMin))->hashcons();
1055 } 1058 }
1056 1059
1057 #define SMALLINT ((juint)3) // a value too insignificant to consider widening 1060 static int normalize_int_widen( jint lo, jint hi, int w ) {
1058
1059 const TypeInt *TypeInt::make( jint lo, jint hi, int w ) {
1060 // Certain normalizations keep us sane when comparing types. 1061 // Certain normalizations keep us sane when comparing types.
1061 // The 'SMALLINT' covers constants and also CC and its relatives. 1062 // The 'SMALLINT' covers constants and also CC and its relatives.
1062 assert(CC == NULL || (juint)(CC->_hi - CC->_lo) <= SMALLINT, "CC is truly small");
1063 if (lo <= hi) { 1063 if (lo <= hi) {
1064 if ((juint)(hi - lo) <= SMALLINT) w = Type::WidenMin; 1064 if ((juint)(hi - lo) <= SMALLINT) w = Type::WidenMin;
1065 if ((juint)(hi - lo) >= max_juint) w = Type::WidenMax; // plain int 1065 if ((juint)(hi - lo) >= max_juint) w = Type::WidenMax; // TypeInt::INT
1066 } 1066 } else {
1067 if ((juint)(lo - hi) <= SMALLINT) w = Type::WidenMin;
1068 if ((juint)(lo - hi) >= max_juint) w = Type::WidenMin; // dual TypeInt::INT
1069 }
1070 return w;
1071 }
1072
1073 const TypeInt *TypeInt::make( jint lo, jint hi, int w ) {
1074 w = normalize_int_widen(lo, hi, w);
1067 return (TypeInt*)(new TypeInt(lo,hi,w))->hashcons(); 1075 return (TypeInt*)(new TypeInt(lo,hi,w))->hashcons();
1068 } 1076 }
1069 1077
1070 //------------------------------meet------------------------------------------- 1078 //------------------------------meet-------------------------------------------
1071 // Compute the MEET of two types. It returns a new Type representation object 1079 // Compute the MEET of two types. It returns a new Type representation object
1101 break; 1109 break;
1102 } 1110 }
1103 1111
1104 // Expand covered set 1112 // Expand covered set
1105 const TypeInt *r = t->is_int(); 1113 const TypeInt *r = t->is_int();
1106 // (Avoid TypeInt::make, to avoid the argument normalizations it enforces.) 1114 return make( MIN2(_lo,r->_lo), MAX2(_hi,r->_hi), MAX2(_widen,r->_widen) );
1107 return (new TypeInt( MIN2(_lo,r->_lo), MAX2(_hi,r->_hi), MAX2(_widen,r->_widen) ))->hashcons();
1108 } 1115 }
1109 1116
1110 //------------------------------xdual------------------------------------------ 1117 //------------------------------xdual------------------------------------------
1111 // Dual: reverse hi & lo; flip widen 1118 // Dual: reverse hi & lo; flip widen
1112 const Type *TypeInt::xdual() const { 1119 const Type *TypeInt::xdual() const {
1113 return new TypeInt(_hi,_lo,WidenMax-_widen); 1120 int w = normalize_int_widen(_hi,_lo, WidenMax-_widen);
1121 return new TypeInt(_hi,_lo,w);
1114 } 1122 }
1115 1123
1116 //------------------------------widen------------------------------------------ 1124 //------------------------------widen------------------------------------------
1117 // Only happens for optimistic top-down optimizations. 1125 // Only happens for optimistic top-down optimizations.
1118 const Type *TypeInt::widen( const Type *old, const Type* limit ) const { 1126 const Type *TypeInt::widen( const Type *old, const Type* limit ) const {
1200 } 1208 }
1201 1209
1202 //-----------------------------filter------------------------------------------ 1210 //-----------------------------filter------------------------------------------
1203 const Type *TypeInt::filter( const Type *kills ) const { 1211 const Type *TypeInt::filter( const Type *kills ) const {
1204 const TypeInt* ft = join(kills)->isa_int(); 1212 const TypeInt* ft = join(kills)->isa_int();
1205 if (ft == NULL || ft->_lo > ft->_hi) 1213 if (ft == NULL || ft->empty())
1206 return Type::TOP; // Canonical empty value 1214 return Type::TOP; // Canonical empty value
1207 if (ft->_widen < this->_widen) { 1215 if (ft->_widen < this->_widen) {
1208 // Do not allow the value of kill->_widen to affect the outcome. 1216 // Do not allow the value of kill->_widen to affect the outcome.
1209 // The widen bits must be allowed to run freely through the graph. 1217 // The widen bits must be allowed to run freely through the graph.
1210 ft = TypeInt::make(ft->_lo, ft->_hi, this->_widen); 1218 ft = TypeInt::make(ft->_lo, ft->_hi, this->_widen);
1302 //------------------------------make------------------------------------------- 1310 //------------------------------make-------------------------------------------
1303 const TypeLong *TypeLong::make( jlong lo ) { 1311 const TypeLong *TypeLong::make( jlong lo ) {
1304 return (TypeLong*)(new TypeLong(lo,lo,WidenMin))->hashcons(); 1312 return (TypeLong*)(new TypeLong(lo,lo,WidenMin))->hashcons();
1305 } 1313 }
1306 1314
1315 static int normalize_long_widen( jlong lo, jlong hi, int w ) {
1316 // Certain normalizations keep us sane when comparing types.
1317 // The 'SMALLINT' covers constants.
1318 if (lo <= hi) {
1319 if ((julong)(hi - lo) <= SMALLINT) w = Type::WidenMin;
1320 if ((julong)(hi - lo) >= max_julong) w = Type::WidenMax; // TypeLong::LONG
1321 } else {
1322 if ((julong)(lo - hi) <= SMALLINT) w = Type::WidenMin;
1323 if ((julong)(lo - hi) >= max_julong) w = Type::WidenMin; // dual TypeLong::LONG
1324 }
1325 return w;
1326 }
1327
1307 const TypeLong *TypeLong::make( jlong lo, jlong hi, int w ) { 1328 const TypeLong *TypeLong::make( jlong lo, jlong hi, int w ) {
1308 // Certain normalizations keep us sane when comparing types. 1329 w = normalize_long_widen(lo, hi, w);
1309 // The '1' covers constants.
1310 if (lo <= hi) {
1311 if ((julong)(hi - lo) <= SMALLINT) w = Type::WidenMin;
1312 if ((julong)(hi - lo) >= max_julong) w = Type::WidenMax; // plain long
1313 }
1314 return (TypeLong*)(new TypeLong(lo,hi,w))->hashcons(); 1330 return (TypeLong*)(new TypeLong(lo,hi,w))->hashcons();
1315 } 1331 }
1316 1332
1317 1333
1318 //------------------------------meet------------------------------------------- 1334 //------------------------------meet-------------------------------------------
1349 break; 1365 break;
1350 } 1366 }
1351 1367
1352 // Expand covered set 1368 // Expand covered set
1353 const TypeLong *r = t->is_long(); // Turn into a TypeLong 1369 const TypeLong *r = t->is_long(); // Turn into a TypeLong
1354 // (Avoid TypeLong::make, to avoid the argument normalizations it enforces.) 1370 return make( MIN2(_lo,r->_lo), MAX2(_hi,r->_hi), MAX2(_widen,r->_widen) );
1355 return (new TypeLong( MIN2(_lo,r->_lo), MAX2(_hi,r->_hi), MAX2(_widen,r->_widen) ))->hashcons();
1356 } 1371 }
1357 1372
1358 //------------------------------xdual------------------------------------------ 1373 //------------------------------xdual------------------------------------------
1359 // Dual: reverse hi & lo; flip widen 1374 // Dual: reverse hi & lo; flip widen
1360 const Type *TypeLong::xdual() const { 1375 const Type *TypeLong::xdual() const {
1361 return new TypeLong(_hi,_lo,WidenMax-_widen); 1376 int w = normalize_long_widen(_hi,_lo, WidenMax-_widen);
1377 return new TypeLong(_hi,_lo,w);
1362 } 1378 }
1363 1379
1364 //------------------------------widen------------------------------------------ 1380 //------------------------------widen------------------------------------------
1365 // Only happens for optimistic top-down optimizations. 1381 // Only happens for optimistic top-down optimizations.
1366 const Type *TypeLong::widen( const Type *old, const Type* limit ) const { 1382 const Type *TypeLong::widen( const Type *old, const Type* limit ) const {
1451 } 1467 }
1452 1468
1453 //-----------------------------filter------------------------------------------ 1469 //-----------------------------filter------------------------------------------
1454 const Type *TypeLong::filter( const Type *kills ) const { 1470 const Type *TypeLong::filter( const Type *kills ) const {
1455 const TypeLong* ft = join(kills)->isa_long(); 1471 const TypeLong* ft = join(kills)->isa_long();
1456 if (ft == NULL || ft->_lo > ft->_hi) 1472 if (ft == NULL || ft->empty())
1457 return Type::TOP; // Canonical empty value 1473 return Type::TOP; // Canonical empty value
1458 if (ft->_widen < this->_widen) { 1474 if (ft->_widen < this->_widen) {
1459 // Do not allow the value of kill->_widen to affect the outcome. 1475 // Do not allow the value of kill->_widen to affect the outcome.
1460 // The widen bits must be allowed to run freely through the graph. 1476 // The widen bits must be allowed to run freely through the graph.
1461 ft = TypeLong::make(ft->_lo, ft->_hi, this->_widen); 1477 ft = TypeLong::make(ft->_lo, ft->_hi, this->_widen);