Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(398)

Side by Side Diff: lib/compiler/implementation/ssa/optimize.dart

Issue 10735051: Fix usage of UNKNOWN/CONFLICTING types for union. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Cosmetic change in comment. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698