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 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 5 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
6 import '../common/names.dart' show Selectors; | 6 import '../common/names.dart' show Selectors; |
7 import '../common/tasks.dart' show CompilerTask; | 7 import '../common/tasks.dart' show CompilerTask; |
8 import '../compiler.dart' show Compiler; | 8 import '../compiler.dart' show Compiler; |
9 import '../constants/constant_system.dart'; | 9 import '../constants/constant_system.dart'; |
10 import '../constants/values.dart'; | 10 import '../constants/values.dart'; |
(...skipping 1605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1616 eliminatedSideEffects = | 1616 eliminatedSideEffects = |
1617 eliminatedSideEffects || instruction.sideEffects.hasSideEffects(); | 1617 eliminatedSideEffects || instruction.sideEffects.hasSideEffects(); |
1618 removeUsers(instruction); | 1618 removeUsers(instruction); |
1619 block.remove(instruction); | 1619 block.remove(instruction); |
1620 } else if (isDeadCode(instruction)) { | 1620 } else if (isDeadCode(instruction)) { |
1621 block.remove(instruction); | 1621 block.remove(instruction); |
1622 } | 1622 } |
1623 instruction = previous; | 1623 instruction = previous; |
1624 } | 1624 } |
1625 block.forEachPhi(simplifyPhi); | 1625 block.forEachPhi(simplifyPhi); |
| 1626 evacuateTakenBranch(block); |
1626 } | 1627 } |
1627 | 1628 |
1628 void simplifyPhi(HPhi phi) { | 1629 void simplifyPhi(HPhi phi) { |
1629 // If the phi is of the form `phi(x, HTypeKnown(x))`, it does not strengthen | 1630 // If the phi is of the form `phi(x, HTypeKnown(x))`, it does not strengthen |
1630 // `x`. We can replace the phi with `x` to potentially make the HTypeKnown | 1631 // `x`. We can replace the phi with `x` to potentially make the HTypeKnown |
1631 // refinement node dead and potentially make a HIf control no HPhis. | 1632 // refinement node dead and potentially make a HIf control no HPhis. |
1632 | 1633 |
1633 // TODO(sra): Implement version of this test that works for a subgraph of | 1634 // TODO(sra): Implement version of this test that works for a subgraph of |
1634 // HPhi nodes. | 1635 // HPhi nodes. |
1635 HInstruction base = null; | 1636 HInstruction base = null; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1695 // Do a simple single-block region test first. | 1696 // Do a simple single-block region test first. |
1696 if (start.last is HGoto && | 1697 if (start.last is HGoto && |
1697 start.successors.length == 1 && | 1698 start.successors.length == 1 && |
1698 start.successors.single == end) { | 1699 start.successors.single == end) { |
1699 return 1; | 1700 return 1; |
1700 } | 1701 } |
1701 // TODO(sra): Implement fuller test. | 1702 // TODO(sra): Implement fuller test. |
1702 return null; | 1703 return null; |
1703 } | 1704 } |
1704 | 1705 |
| 1706 /// If [block] is an always-taken branch, move the code from the taken branch |
| 1707 /// into [block]. This has the effect of making the instructions available for |
| 1708 /// further optimizations by moving them to a position that dominates the join |
| 1709 /// point of the if-then-else. |
| 1710 // TODO(29475): Delete dead blocks instead. |
| 1711 void evacuateTakenBranch(HBasicBlock block) { |
| 1712 if (!block.isLive) return; |
| 1713 HControlFlow branch = block.last; |
| 1714 if (branch is HIf) { |
| 1715 if (branch.thenBlock.isLive == branch.elseBlock.isLive) return; |
| 1716 assert(branch.condition.isConstant()); |
| 1717 HBasicBlock target = |
| 1718 branch.thenBlock.isLive ? branch.thenBlock : branch.elseBlock; |
| 1719 HInstruction instruction = target.first; |
| 1720 while (!instruction.isControlFlow()) { |
| 1721 HInstruction next = instruction.next; |
| 1722 if (instruction is HTypeKnown && instruction.isPinned) break; |
| 1723 instruction.block.detach(instruction); |
| 1724 block.moveAtExit(instruction); |
| 1725 instruction = next; |
| 1726 } |
| 1727 } |
| 1728 } |
| 1729 |
1705 void cleanPhis() { | 1730 void cleanPhis() { |
1706 L: | 1731 L: |
1707 for (HBasicBlock block in _graph.blocks) { | 1732 for (HBasicBlock block in _graph.blocks) { |
1708 List<HBasicBlock> predecessors = block.predecessors; | 1733 List<HBasicBlock> predecessors = block.predecessors; |
1709 // Zap all inputs to phis that correspond to dead blocks. | 1734 // Zap all inputs to phis that correspond to dead blocks. |
1710 block.forEachPhi((HPhi phi) { | 1735 block.forEachPhi((HPhi phi) { |
1711 for (int i = 0; i < phi.inputs.length; ++i) { | 1736 for (int i = 0; i < phi.inputs.length; ++i) { |
1712 if (!predecessors[i].isLive && phi.inputs[i] != zapInstruction) { | 1737 if (!predecessors[i].isLive && phi.inputs[i] != zapInstruction) { |
1713 replaceInput(i, phi, zapInstruction); | 1738 replaceInput(i, phi, zapInstruction); |
1714 } | 1739 } |
(...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2951 | 2976 |
2952 keyedValues.forEach((receiver, values) { | 2977 keyedValues.forEach((receiver, values) { |
2953 result.keyedValues[receiver] = | 2978 result.keyedValues[receiver] = |
2954 new Map<HInstruction, HInstruction>.from(values); | 2979 new Map<HInstruction, HInstruction>.from(values); |
2955 }); | 2980 }); |
2956 | 2981 |
2957 result.nonEscapingReceivers.addAll(nonEscapingReceivers); | 2982 result.nonEscapingReceivers.addAll(nonEscapingReceivers); |
2958 return result; | 2983 return result; |
2959 } | 2984 } |
2960 } | 2985 } |
OLD | NEW |