| 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 abstract class OptimizationPhase { | 7 abstract class OptimizationPhase { |
| 8 String get name; | 8 String get name; |
| 9 void visitGraph(HGraph graph); | 9 void visitGraph(HGraph graph); |
| 10 } | 10 } |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 return node; | 194 return node; |
| 195 } | 195 } |
| 196 | 196 |
| 197 HInstruction visitBoolify(HBoolify node) { | 197 HInstruction visitBoolify(HBoolify node) { |
| 198 List<HInstruction> inputs = node.inputs; | 198 List<HInstruction> inputs = node.inputs; |
| 199 assert(inputs.length == 1); | 199 assert(inputs.length == 1); |
| 200 HInstruction input = inputs[0]; | 200 HInstruction input = inputs[0]; |
| 201 HType type = input.instructionType; | 201 HType type = input.instructionType; |
| 202 if (type.isBoolean()) return input; | 202 if (type.isBoolean()) return input; |
| 203 // All values that cannot be 'true' are boolified to false. | 203 // All values that cannot be 'true' are boolified to false. |
| 204 DartType booleanType = backend.jsBoolClass.computeType(compiler); | |
| 205 TypeMask mask = type.computeMask(compiler); | 204 TypeMask mask = type.computeMask(compiler); |
| 206 // TODO(kasperl): Get rid of the null check here once all HTypes | 205 // TODO(kasperl): Get rid of the null check here once all HTypes |
| 207 // have a proper mask. | 206 // have a proper mask. |
| 208 if (mask != null && !mask.contains(booleanType, compiler)) { | 207 if (mask != null && !mask.contains(backend.jsBoolClass, compiler)) { |
| 209 return graph.addConstantBool(false, compiler); | 208 return graph.addConstantBool(false, compiler); |
| 210 } | 209 } |
| 211 return node; | 210 return node; |
| 212 } | 211 } |
| 213 | 212 |
| 214 HInstruction visitNot(HNot node) { | 213 HInstruction visitNot(HNot node) { |
| 215 List<HInstruction> inputs = node.inputs; | 214 List<HInstruction> inputs = node.inputs; |
| 216 assert(inputs.length == 1); | 215 assert(inputs.length == 1); |
| 217 HInstruction input = inputs[0]; | 216 HInstruction input = inputs[0]; |
| 218 if (input is HConstant) { | 217 if (input is HConstant) { |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 && identical(element, compiler.intClass)) { | 629 && identical(element, compiler.intClass)) { |
| 631 // We let the JS semantics decide for that check. | 630 // We let the JS semantics decide for that check. |
| 632 return node; | 631 return node; |
| 633 // We need the [:hasTypeArguments:] check because we don't have | 632 // We need the [:hasTypeArguments:] check because we don't have |
| 634 // the notion of generics in the backend. For example, [:this:] in | 633 // the notion of generics in the backend. For example, [:this:] in |
| 635 // a class [:A<T>:], is currently always considered to have the | 634 // a class [:A<T>:], is currently always considered to have the |
| 636 // raw type. | 635 // raw type. |
| 637 } else if (!RuntimeTypes.hasTypeArguments(type)) { | 636 } else if (!RuntimeTypes.hasTypeArguments(type)) { |
| 638 TypeMask expressionMask = expressionType.computeMask(compiler); | 637 TypeMask expressionMask = expressionType.computeMask(compiler); |
| 639 TypeMask typeMask = (element == compiler.nullClass) | 638 TypeMask typeMask = (element == compiler.nullClass) |
| 640 ? new TypeMask.subtype(type) : new TypeMask.nonNullSubtype(type); | 639 ? new TypeMask.subtype(element) |
| 640 : new TypeMask.nonNullSubtype(element); |
| 641 if (expressionMask.union(typeMask, compiler) == typeMask) { | 641 if (expressionMask.union(typeMask, compiler) == typeMask) { |
| 642 return graph.addConstantBool(true, compiler); | 642 return graph.addConstantBool(true, compiler); |
| 643 } else if (expressionMask.intersection(typeMask, compiler).isEmpty) { | 643 } else if (expressionMask.intersection(typeMask, compiler).isEmpty) { |
| 644 return graph.addConstantBool(false, compiler); | 644 return graph.addConstantBool(false, compiler); |
| 645 } | 645 } |
| 646 } | 646 } |
| 647 return node; | 647 return node; |
| 648 } | 648 } |
| 649 | 649 |
| 650 HInstruction visitTypeConversion(HTypeConversion node) { | 650 HInstruction visitTypeConversion(HTypeConversion node) { |
| (...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1496 implements OptimizationPhase { | 1496 implements OptimizationPhase { |
| 1497 final String name = "SsaTypeconversionInserter"; | 1497 final String name = "SsaTypeconversionInserter"; |
| 1498 final Compiler compiler; | 1498 final Compiler compiler; |
| 1499 | 1499 |
| 1500 SsaTypeConversionInserter(this.compiler); | 1500 SsaTypeConversionInserter(this.compiler); |
| 1501 | 1501 |
| 1502 void visitGraph(HGraph graph) { | 1502 void visitGraph(HGraph graph) { |
| 1503 visitDominatorTree(graph); | 1503 visitDominatorTree(graph); |
| 1504 } | 1504 } |
| 1505 | 1505 |
| 1506 | |
| 1507 // Update users of [input] that are dominated by [:dominator.first:] | 1506 // Update users of [input] that are dominated by [:dominator.first:] |
| 1508 // to use [newInput] instead. | 1507 // to use [newInput] instead. |
| 1509 void changeUsesDominatedBy(HBasicBlock dominator, | 1508 void changeUsesDominatedBy(HBasicBlock dominator, |
| 1510 HInstruction input, | 1509 HInstruction input, |
| 1511 HType convertedType) { | 1510 HType convertedType) { |
| 1512 Set<HInstruction> dominatedUsers = input.dominatedUsers(dominator.first); | 1511 Set<HInstruction> dominatedUsers = input.dominatedUsers(dominator.first); |
| 1513 if (dominatedUsers.isEmpty) return; | 1512 if (dominatedUsers.isEmpty) return; |
| 1514 | 1513 |
| 1515 HTypeConversion newInput = new HTypeConversion( | 1514 HTypeConversion newInput = new HTypeConversion( |
| 1516 null, HTypeConversion.NO_CHECK, convertedType, input); | 1515 null, HTypeConversion.NO_CHECK, convertedType, input); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1536 ifUsers.add(user); | 1535 ifUsers.add(user); |
| 1537 } else if (user is HNot) { | 1536 } else if (user is HNot) { |
| 1538 for (HInstruction notUser in user.usedBy) { | 1537 for (HInstruction notUser in user.usedBy) { |
| 1539 if (notUser is HIf) notIfUsers.add(notUser); | 1538 if (notUser is HIf) notIfUsers.add(notUser); |
| 1540 } | 1539 } |
| 1541 } | 1540 } |
| 1542 } | 1541 } |
| 1543 | 1542 |
| 1544 if (ifUsers.isEmpty && notIfUsers.isEmpty) return; | 1543 if (ifUsers.isEmpty && notIfUsers.isEmpty) return; |
| 1545 | 1544 |
| 1546 HType convertedType = new HType.nonNullSubtype(type, compiler); | 1545 HType convertedType = new HType.nonNullSubtype(element, compiler); |
| 1547 HInstruction input = instruction.expression; | 1546 HInstruction input = instruction.expression; |
| 1548 for (HIf ifUser in ifUsers) { | 1547 for (HIf ifUser in ifUsers) { |
| 1549 changeUsesDominatedBy(ifUser.thenBlock, input, convertedType); | 1548 changeUsesDominatedBy(ifUser.thenBlock, input, convertedType); |
| 1550 // TODO(ngeoffray): Also change uses for the else block on a HType | 1549 // TODO(ngeoffray): Also change uses for the else block on a HType |
| 1551 // that knows it is not of a specific Type. | 1550 // that knows it is not of a specific Type. |
| 1552 } | 1551 } |
| 1553 | 1552 |
| 1554 for (HIf ifUser in notIfUsers) { | 1553 for (HIf ifUser in notIfUsers) { |
| 1555 changeUsesDominatedBy(ifUser.elseBlock, input, convertedType); | 1554 changeUsesDominatedBy(ifUser.elseBlock, input, convertedType); |
| 1556 // TODO(ngeoffray): Also change uses for the then block on a HType | 1555 // TODO(ngeoffray): Also change uses for the then block on a HType |
| 1557 // that knows it is not of a specific Type. | 1556 // that knows it is not of a specific Type. |
| 1558 } | 1557 } |
| 1559 } | 1558 } |
| 1560 } | 1559 } |
| OLD | NEW |