Mercurial > hg > truffle
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); |