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 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 if (element == compiler.unnamedListConstructor | 687 if (element == compiler.unnamedListConstructor |
688 && receiver.inputs.length == 1 | 688 && receiver.inputs.length == 1 |
689 && receiver.inputs[0].isInteger()) { | 689 && receiver.inputs[0].isInteger()) { |
690 return receiver.inputs[0]; | 690 return receiver.inputs[0]; |
691 } | 691 } |
692 } else if (receiver.isConstantList() || receiver.isConstantString()) { | 692 } else if (receiver.isConstantList() || receiver.isConstantString()) { |
693 return graph.addConstantInt(receiver.constant.length, compiler); | 693 return graph.addConstantInt(receiver.constant.length, compiler); |
694 } else { | 694 } else { |
695 var type = receiver.instructionType.computeMask(compiler); | 695 var type = receiver.instructionType.computeMask(compiler); |
696 if (type.isContainer && type.length != null) { | 696 if (type.isContainer && type.length != null) { |
697 return graph.addConstantInt(type.length, compiler); | 697 HInstruction constant = graph.addConstantInt(type.length, compiler); |
| 698 if (type.isNullable) { |
| 699 // If the container can be null, we update all uses of the |
| 700 // length access to use the constant instead, but keep the |
| 701 // length access in the graph, to ensure we still have a |
| 702 // null check. |
| 703 node.block.rewrite(node, constant); |
| 704 return node; |
| 705 } else { |
| 706 return constant; |
| 707 } |
698 } | 708 } |
699 } | 709 } |
700 } | 710 } |
701 return node; | 711 return node; |
702 } | 712 } |
703 | 713 |
704 HInstruction visitIndex(HIndex node) { | 714 HInstruction visitIndex(HIndex node) { |
705 if (node.receiver.isConstantList() && node.index.isConstantInteger()) { | 715 if (node.receiver.isConstantList() && node.index.isConstantInteger()) { |
706 var instruction = node.receiver; | 716 var instruction = node.receiver; |
707 List<Constant> entries = instruction.constant.entries; | 717 List<Constant> entries = instruction.constant.entries; |
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1551 // that knows it is not of a specific Type. | 1561 // that knows it is not of a specific Type. |
1552 } | 1562 } |
1553 | 1563 |
1554 for (HIf ifUser in notIfUsers) { | 1564 for (HIf ifUser in notIfUsers) { |
1555 changeUsesDominatedBy(ifUser.elseBlock, input, convertedType); | 1565 changeUsesDominatedBy(ifUser.elseBlock, input, convertedType); |
1556 // TODO(ngeoffray): Also change uses for the then block on a HType | 1566 // TODO(ngeoffray): Also change uses for the then block on a HType |
1557 // that knows it is not of a specific Type. | 1567 // that knows it is not of a specific Type. |
1558 } | 1568 } |
1559 } | 1569 } |
1560 } | 1570 } |
OLD | NEW |