| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 interface OptimizationPhase { | 5 interface OptimizationPhase { |
| 6 String get name(); | 6 String get name(); |
| 7 void visitGraph(HGraph graph); | 7 void visitGraph(HGraph graph); |
| 8 } | 8 } |
| 9 | 9 |
| 10 class SsaOptimizerTask extends CompilerTask { | 10 class SsaOptimizerTask extends CompilerTask { |
| (...skipping 1192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1203 } else { | 1203 } else { |
| 1204 node.propagatedType = type; | 1204 node.propagatedType = type; |
| 1205 } | 1205 } |
| 1206 } | 1206 } |
| 1207 } | 1207 } |
| 1208 break; | 1208 break; |
| 1209 } | 1209 } |
| 1210 } | 1210 } |
| 1211 | 1211 |
| 1212 HInstruction visitEquals(HEquals node) { | 1212 HInstruction visitEquals(HEquals node) { |
| 1213 // Determine if one of the operands is an HFieldGet. |
| 1214 HFieldGet field; |
| 1215 HInstruction other; |
| 1216 if (node.left is HFieldGet) { |
| 1217 field = node.left; |
| 1218 other = node.right; |
| 1219 } else if (node.right is HFieldGet) { |
| 1220 field = node.right; |
| 1221 other = node.left; |
| 1222 } |
| 1213 // Try to optimize the case where a field which is known to always be an | 1223 // Try to optimize the case where a field which is known to always be an |
| 1214 // integer is compared with a constant integer literal. | 1224 // integer is compared with a constant integer literal. |
| 1215 if (node.left is HFieldGet && | 1225 if (other != null && |
| 1216 node.right is HConstant && | 1226 other is HConstant && |
| 1217 node.right.isInteger()) { | 1227 other.isInteger() && |
| 1218 HFieldGet left = node.left; | 1228 field.element != null && |
| 1219 HConstant right = node.right; | 1229 field.element.enclosingElement.isClass()) { |
| 1220 if (left.element != null && left.element.enclosingElement.isClass()) { | 1230 // Calculate the field type from the information available. |
| 1221 // Calculate the field type from the information available. | 1231 HType type = |
| 1222 HType type = | 1232 backend.fieldSettersTypeSoFar(field.element).union( |
| 1223 backend.fieldSettersTypeSoFar(left.element).union( | 1233 backend.typeFromInitializersSoFar(field.element)); |
| 1224 backend.typeFromInitializersSoFar(left.element)); | 1234 if (!type.isConflicting()) { |
| 1225 switch (compiler.phase) { | 1235 switch (compiler.phase) { |
| 1226 case Compiler.PHASE_COMPILING: | 1236 case Compiler.PHASE_COMPILING: |
| 1227 if (!type.isConflicting()) { | 1237 compiler.enqueuer.codegen.registerRecompilationCandidate( |
| 1228 compiler.enqueuer.codegen.registerRecompilationCandidate( | 1238 work.element); |
| 1229 work.element); | |
| 1230 } | |
| 1231 break; | 1239 break; |
| 1232 case Compiler.PHASE_RECOMPILING: | 1240 case Compiler.PHASE_RECOMPILING: |
| 1233 if (!type.isConflicting()) { | 1241 if (compiler.codegenWorld.hasInvokedSetter(field.element, |
| 1234 if (compiler.codegenWorld.hasInvokedSetter(left.element, | 1242 compiler)) { |
| 1235 compiler)) { | 1243 // If there are invoked setters we don't know for sure that the |
| 1236 // If there are invoked setters we don't know for sure that the | 1244 // field will hold the calculated, but the fact that the class |
| 1237 // field will hold the calculated, but the fact that the class | 1245 // itself stick to this type in the field is still a strong |
| 1238 // itself stick to this type in the field is still a strong | 1246 // signal to indiate the expected type of the field. |
| 1239 // signal to indiate the expected type of the field. | 1247 field.propagatedType = type; |
| 1240 left.propagatedType = type; | 1248 graph.highTypeLikelyhood = true; |
| 1241 graph.highTypeLikelyhood = true; | 1249 } else { |
| 1242 } else { | 1250 // If there are no invoked setters we know the type of this |
| 1243 // If there are no invoked setters we know the type of this | 1251 // field for sure. |
| 1244 // field for sure. | 1252 field.guaranteedType = type; |
| 1245 left.guaranteedType = type; | |
| 1246 } | |
| 1247 } | 1253 } |
| 1248 break; | 1254 break; |
| 1249 default: | 1255 default: |
| 1250 assert(false); | 1256 assert(false); |
| 1251 break; | 1257 break; |
| 1252 } | 1258 } |
| 1253 } | 1259 } |
| 1254 } | 1260 } |
| 1255 } | 1261 } |
| 1256 | 1262 |
| 1263 HInstruction visitBinaryArithmetic(HBinaryArithmetic node) { |
| 1264 // Determine if one of the operands is an HFieldGet. |
| 1265 HFieldGet field; |
| 1266 HInstruction other; |
| 1267 if (node.left is HFieldGet) { |
| 1268 field = node.left; |
| 1269 other = node.right; |
| 1270 } else if (node.right is HFieldGet) { |
| 1271 field = node.right; |
| 1272 other = node.left; |
| 1273 } |
| 1274 // Check that the other operand is a number and that we have type |
| 1275 // information for the field get. |
| 1276 if (other != null && |
| 1277 other is HConstant && |
| 1278 other.isNumber() && |
| 1279 field.element != null && |
| 1280 field.element.enclosingElement.isClass()) { |
| 1281 // If we have type information for the field and it contains |
| 1282 // NUMBER, we mark for recompilation. |
| 1283 Element fieldElement = field.element; |
| 1284 HType fieldSettersType = backend.fieldSettersTypeSoFar(fieldElement); |
| 1285 HType initializersType = backend.typeFromInitializersSoFar(fieldElement); |
| 1286 HType fieldType = fieldSettersType.union(initializersType); |
| 1287 HType type = HType.NUMBER.union(fieldType); |
| 1288 if (!type.isConflicting()) { |
| 1289 switch (compiler.phase) { |
| 1290 case Compiler.PHASE_COMPILING: |
| 1291 compiler.enqueuer.codegen.registerRecompilationCandidate( |
| 1292 work.element); |
| 1293 break; |
| 1294 case Compiler.PHASE_RECOMPILING: |
| 1295 if (compiler.codegenWorld.hasInvokedSetter(fieldElement, |
| 1296 compiler)) { |
| 1297 // If there are invoked setters we don't know for sure |
| 1298 // that the field will hold a value of the calculated |
| 1299 // type, but the fact that the class itself sticks to |
| 1300 // this type for the field is still a strong signal |
| 1301 // indicating the expected type of the field. |
| 1302 field.propagatedType = type; |
| 1303 graph.highTypeLikelyhood = true; |
| 1304 } else { |
| 1305 // If there are no invoked setters we know the type of |
| 1306 // this field for sure. |
| 1307 field.guaranteedType = type; |
| 1308 } |
| 1309 break; |
| 1310 default: |
| 1311 assert(false); |
| 1312 break; |
| 1313 } |
| 1314 } |
| 1315 } |
| 1316 } |
| 1257 } | 1317 } |
| OLD | NEW |