Chromium Code Reviews| 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 1157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1168 | 1168 |
| 1169 void visitGraph(HGraph visitee) { | 1169 void visitGraph(HGraph visitee) { |
| 1170 graph = visitee; | 1170 graph = visitee; |
| 1171 visitDominatorTree(visitee); | 1171 visitDominatorTree(visitee); |
| 1172 } | 1172 } |
| 1173 | 1173 |
| 1174 void visitFieldGet(HFieldGet node) { | 1174 void visitFieldGet(HFieldGet node) { |
| 1175 if (!node.element.enclosingElement.isClass()) return; | 1175 if (!node.element.enclosingElement.isClass()) return; |
| 1176 Element field = node.element; | 1176 Element field = node.element; |
| 1177 HType type = backend.optimisticFieldTypeAfterConstruction(field); | 1177 HType type = backend.optimisticFieldTypeAfterConstruction(field); |
| 1178 switch (compiler.phase) { | 1178 if (!type.isConflicting() && !type.isUnknown()) { |
|
Mads Ager (google)
2012/07/11 10:24:34
I think we can relax this check but I will look in
| |
| 1179 case Compiler.PHASE_COMPILING: | 1179 switch (compiler.phase) { |
| 1180 if (!type.isConflicting()) { | 1180 case Compiler.PHASE_COMPILING: |
| 1181 compiler.enqueuer.codegen.registerRecompilationCandidate( | 1181 compiler.enqueuer.codegen.registerRecompilationCandidate( |
| 1182 work.element); | 1182 work.element); |
| 1183 } | 1183 break; |
| 1184 break; | 1184 case Compiler.PHASE_RECOMPILING: |
| 1185 case Compiler.PHASE_RECOMPILING: | |
| 1186 if (!type.isConflicting() && !type.isUnknown()) { | |
| 1187 // Check if optimistic type is based on a setter in the constructor | 1185 // Check if optimistic type is based on a setter in the constructor |
| 1188 // body. | 1186 // body. |
| 1189 if (backend.hasConstructorBodyFieldSetter(field)) { | 1187 if (backend.hasConstructorBodyFieldSetter(field)) { |
| 1190 // There is at least one field setter from the constructor. | 1188 // There is at least one field setter from the constructor. |
| 1191 if (!compiler.codegenWorld.hasInvokedSetter(field, compiler)) { | 1189 if (!compiler.codegenWorld.hasInvokedSetter(field, compiler)) { |
| 1192 node.guaranteedType = | 1190 node.guaranteedType = |
| 1193 type.union(backend.fieldSettersTypeSoFar(node.element)); | 1191 type.union(backend.fieldSettersTypeSoFar(node.element)); |
| 1194 } else { | 1192 } else { |
| 1195 node.propagatedType = | 1193 node.propagatedType = |
| 1196 type.union(backend.fieldSettersTypeSoFar(node.element)); | 1194 type.union(backend.fieldSettersTypeSoFar(node.element)); |
| 1197 } | 1195 } |
| 1198 } else { | 1196 } else { |
| 1199 // Optimistic type is based on field initializer list. | 1197 // Optimistic type is based on field initializer list. |
| 1200 if (!compiler.codegenWorld.hasFieldSetter(field, compiler) && | 1198 if (!compiler.codegenWorld.hasFieldSetter(field, compiler) && |
| 1201 !compiler.codegenWorld.hasInvokedSetter(field, compiler)) { | 1199 !compiler.codegenWorld.hasInvokedSetter(field, compiler)) { |
| 1202 node.guaranteedType = type; | 1200 node.guaranteedType = type; |
| 1203 } else { | 1201 } else { |
| 1204 node.propagatedType = type; | 1202 node.propagatedType = type; |
| 1205 } | 1203 } |
| 1206 } | 1204 } |
| 1207 } | 1205 break; |
| 1208 break; | 1206 } |
| 1209 } | 1207 } |
| 1210 } | 1208 } |
| 1211 | 1209 |
| 1212 HInstruction visitEquals(HEquals node) { | 1210 HInstruction visitEquals(HEquals node) { |
| 1213 // Determine if one of the operands is an HFieldGet. | 1211 // Determine if one of the operands is an HFieldGet. |
| 1214 HFieldGet field; | 1212 HFieldGet field; |
| 1215 HInstruction other; | 1213 HInstruction other; |
| 1216 if (node.left is HFieldGet) { | 1214 if (node.left is HFieldGet) { |
| 1217 field = node.left; | 1215 field = node.left; |
| 1218 other = node.right; | 1216 other = node.right; |
| 1219 } else if (node.right is HFieldGet) { | 1217 } else if (node.right is HFieldGet) { |
| 1220 field = node.right; | 1218 field = node.right; |
| 1221 other = node.left; | 1219 other = node.left; |
| 1222 } | 1220 } |
| 1223 // Try to optimize the case where a field which is known to always be an | 1221 // Try to optimize the case where a field which is known to always be an |
| 1224 // integer is compared with a constant integer literal. | 1222 // integer is compared with a constant integer literal. |
| 1225 if (other != null && | 1223 if (other != null && |
| 1226 other is HConstant && | 1224 other.isConstantInteger() && |
| 1227 other.isInteger() && | |
| 1228 field.element != null && | 1225 field.element != null && |
| 1229 field.element.enclosingElement.isClass()) { | 1226 field.element.enclosingElement.isClass()) { |
| 1230 // Calculate the field type from the information available. | 1227 // Calculate the field type from the information available. |
| 1231 HType type = | 1228 HType type = |
| 1232 backend.fieldSettersTypeSoFar(field.element).union( | 1229 backend.fieldSettersTypeSoFar(field.element).union( |
| 1233 backend.typeFromInitializersSoFar(field.element)); | 1230 backend.typeFromInitializersSoFar(field.element)); |
| 1234 if (!type.isConflicting()) { | 1231 if (!type.isUnknown()) { |
| 1235 switch (compiler.phase) { | 1232 switch (compiler.phase) { |
| 1236 case Compiler.PHASE_COMPILING: | 1233 case Compiler.PHASE_COMPILING: |
| 1237 compiler.enqueuer.codegen.registerRecompilationCandidate( | 1234 compiler.enqueuer.codegen.registerRecompilationCandidate( |
| 1238 work.element); | 1235 work.element); |
| 1239 break; | 1236 break; |
| 1240 case Compiler.PHASE_RECOMPILING: | 1237 case Compiler.PHASE_RECOMPILING: |
| 1241 if (compiler.codegenWorld.hasInvokedSetter(field.element, | 1238 if (compiler.codegenWorld.hasInvokedSetter(field.element, |
| 1242 compiler)) { | 1239 compiler)) { |
| 1243 // If there are invoked setters we don't know for sure that the | 1240 // 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 | 1241 // field will hold the calculated, but the fact that the class |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1267 if (node.left is HFieldGet) { | 1264 if (node.left is HFieldGet) { |
| 1268 field = node.left; | 1265 field = node.left; |
| 1269 other = node.right; | 1266 other = node.right; |
| 1270 } else if (node.right is HFieldGet) { | 1267 } else if (node.right is HFieldGet) { |
| 1271 field = node.right; | 1268 field = node.right; |
| 1272 other = node.left; | 1269 other = node.left; |
| 1273 } | 1270 } |
| 1274 // Check that the other operand is a number and that we have type | 1271 // Check that the other operand is a number and that we have type |
| 1275 // information for the field get. | 1272 // information for the field get. |
| 1276 if (other != null && | 1273 if (other != null && |
| 1277 other is HConstant && | 1274 other.isConstantNumber() && |
| 1278 other.isNumber() && | |
| 1279 field.element != null && | 1275 field.element != null && |
| 1280 field.element.enclosingElement.isClass()) { | 1276 field.element.enclosingElement.isClass()) { |
| 1281 // If we have type information for the field and it contains | 1277 // If we have type information for the field and it contains |
| 1282 // NUMBER, we mark for recompilation. | 1278 // NUMBER, we mark for recompilation. |
| 1283 Element fieldElement = field.element; | 1279 Element fieldElement = field.element; |
| 1284 HType fieldSettersType = backend.fieldSettersTypeSoFar(fieldElement); | 1280 HType fieldSettersType = backend.fieldSettersTypeSoFar(fieldElement); |
| 1285 HType initializersType = backend.typeFromInitializersSoFar(fieldElement); | 1281 HType initializersType = backend.typeFromInitializersSoFar(fieldElement); |
| 1286 HType fieldType = fieldSettersType.union(initializersType); | 1282 HType fieldType = fieldSettersType.union(initializersType); |
| 1287 HType type = HType.NUMBER.union(fieldType); | 1283 HType type = HType.NUMBER.union(fieldType); |
| 1288 if (!type.isConflicting()) { | 1284 if (type == HType.NUMBER) { |
| 1289 switch (compiler.phase) { | 1285 switch (compiler.phase) { |
| 1290 case Compiler.PHASE_COMPILING: | 1286 case Compiler.PHASE_COMPILING: |
| 1291 compiler.enqueuer.codegen.registerRecompilationCandidate( | 1287 compiler.enqueuer.codegen.registerRecompilationCandidate( |
| 1292 work.element); | 1288 work.element); |
| 1293 break; | 1289 break; |
| 1294 case Compiler.PHASE_RECOMPILING: | 1290 case Compiler.PHASE_RECOMPILING: |
| 1295 if (compiler.codegenWorld.hasInvokedSetter(fieldElement, | 1291 if (compiler.codegenWorld.hasInvokedSetter(fieldElement, |
| 1296 compiler)) { | 1292 compiler)) { |
| 1297 // If there are invoked setters we don't know for sure | 1293 // If there are invoked setters we don't know for sure |
| 1298 // that the field will hold a value of the calculated | 1294 // that the field will hold a value of the calculated |
| 1299 // type, but the fact that the class itself sticks to | 1295 // type, but the fact that the class itself sticks to |
| 1300 // this type for the field is still a strong signal | 1296 // this type for the field is still a strong signal |
| 1301 // indicating the expected type of the field. | 1297 // indicating the expected type of the field. |
| 1302 field.propagatedType = type; | 1298 field.propagatedType = type; |
| 1303 graph.highTypeLikelyhood = true; | 1299 graph.highTypeLikelyhood = true; |
| 1304 } else { | 1300 } else { |
| 1305 // If there are no invoked setters we know the type of | 1301 // If there are no invoked setters we know the type of |
| 1306 // this field for sure. | 1302 // this field for sure. |
| 1307 field.guaranteedType = type; | 1303 field.guaranteedType = type; |
| 1308 } | 1304 } |
| 1309 break; | 1305 break; |
| 1310 default: | 1306 default: |
| 1311 assert(false); | 1307 assert(false); |
| 1312 break; | 1308 break; |
| 1313 } | 1309 } |
| 1314 } | 1310 } |
| 1315 } | 1311 } |
| 1316 } | 1312 } |
| 1317 } | 1313 } |
| OLD | NEW |