| 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 CompilerOptions get _options => _compiler.options; | 56 CompilerOptions get _options => _compiler.options; |
| 57 | 57 |
| 58 RuntimeTypesSubstitutions get _rtiSubstitutions => _backend.rtiSubstitutions; | 58 RuntimeTypesSubstitutions get _rtiSubstitutions => _backend.rtiSubstitutions; |
| 59 | 59 |
| 60 InterceptorData get _interceptorData => _backend.interceptorData; | 60 InterceptorData get _interceptorData => _backend.interceptorData; |
| 61 | 61 |
| 62 void optimize(CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) { | 62 void optimize(CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) { |
| 63 void runPhase(OptimizationPhase phase) { | 63 void runPhase(OptimizationPhase phase) { |
| 64 measureSubtask(phase.name, () => phase.visitGraph(graph)); | 64 measureSubtask(phase.name, () => phase.visitGraph(graph)); |
| 65 _backend.tracer.traceGraph(phase.name, graph); | 65 _backend.tracer.traceGraph(phase.name, graph); |
| 66 assert(graph.isValid(), 'Graph not valid after ${phase.name}'); | 66 assert(graph.isValid()); |
| 67 } | 67 } |
| 68 | 68 |
| 69 bool trustPrimitives = _options.trustPrimitives; | 69 bool trustPrimitives = _options.trustPrimitives; |
| 70 CodegenRegistry registry = work.registry; | 70 CodegenRegistry registry = work.registry; |
| 71 Set<HInstruction> boundsChecked = new Set<HInstruction>(); | 71 Set<HInstruction> boundsChecked = new Set<HInstruction>(); |
| 72 SsaCodeMotion codeMotion; | 72 SsaCodeMotion codeMotion; |
| 73 SsaLoadElimination loadElimination; | 73 SsaLoadElimination loadElimination; |
| 74 measure(() { | 74 measure(() { |
| 75 List<OptimizationPhase> phases = <OptimizationPhase>[ | 75 List<OptimizationPhase> phases = <OptimizationPhase>[ |
| 76 // Run trivial instruction simplification first to optimize | 76 // Run trivial instruction simplification first to optimize |
| (...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 return null; | 726 return null; |
| 727 } | 727 } |
| 728 | 728 |
| 729 HInstruction visitIdentity(HIdentity node) { | 729 HInstruction visitIdentity(HIdentity node) { |
| 730 HInstruction newInstruction = handleIdentityCheck(node); | 730 HInstruction newInstruction = handleIdentityCheck(node); |
| 731 return newInstruction == null ? super.visitIdentity(node) : newInstruction; | 731 return newInstruction == null ? super.visitIdentity(node) : newInstruction; |
| 732 } | 732 } |
| 733 | 733 |
| 734 void simplifyCondition( | 734 void simplifyCondition( |
| 735 HBasicBlock block, HInstruction condition, bool value) { | 735 HBasicBlock block, HInstruction condition, bool value) { |
| 736 // `excludePhiOutEdges: true` prevents replacing a partially dominated phi | 736 condition.dominatedUsers(block.first).forEach((user) { |
| 737 // node input with a constant. This tends to add unnecessary assignments, by | 737 HInstruction newCondition = _graph.addConstantBool(value, _closedWorld); |
| 738 // transforming the following, which has phi(false, x), | 738 user.changeUse(condition, newCondition); |
| 739 // | 739 }); |
| 740 // if (x) { init(); x = false; } | |
| 741 // | |
| 742 // into this, which has phi(false, false) | |
| 743 // | |
| 744 // if (x) { init(); x = false; } else { x = false; } | |
| 745 // | |
| 746 // which is further simplifed to: | |
| 747 // | |
| 748 // if (x) { init(); } | |
| 749 // ... | |
| 750 // x = false; | |
| 751 // | |
| 752 // This is mostly harmless (if a little confusing) but does cause a lot of | |
| 753 // `x = false;` copies to be inserted when a loop body has many continue | |
| 754 // statements or ends with a switch. | |
| 755 var uses = | |
| 756 DominatedUses.of(condition, block.first, excludePhiOutEdges: true); | |
| 757 if (uses.isEmpty) return; | |
| 758 uses.replaceWith(_graph.addConstantBool(value, _closedWorld)); | |
| 759 } | 740 } |
| 760 | 741 |
| 761 HInstruction visitIf(HIf node) { | 742 HInstruction visitIf(HIf node) { |
| 762 HInstruction condition = node.condition; | 743 HInstruction condition = node.condition; |
| 763 if (condition.isConstant()) return node; | 744 if (condition.isConstant()) return node; |
| 764 bool isNegated = condition is HNot; | 745 bool isNegated = condition is HNot; |
| 765 | 746 |
| 766 if (isNegated) { | 747 if (isNegated) { |
| 767 condition = condition.inputs[0]; | 748 condition = condition.inputs[0]; |
| 768 } else { | 749 } else { |
| (...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1634 // Find the index of the single live predecessor if it exists. | 1615 // Find the index of the single live predecessor if it exists. |
| 1635 int indexOfLive = -1; | 1616 int indexOfLive = -1; |
| 1636 for (int i = 0; i < predecessors.length; i++) { | 1617 for (int i = 0; i < predecessors.length; i++) { |
| 1637 if (predecessors[i].isLive) { | 1618 if (predecessors[i].isLive) { |
| 1638 if (indexOfLive >= 0) continue L; | 1619 if (indexOfLive >= 0) continue L; |
| 1639 indexOfLive = i; | 1620 indexOfLive = i; |
| 1640 } | 1621 } |
| 1641 } | 1622 } |
| 1642 // Run through the phis of the block and replace them with their input | 1623 // Run through the phis of the block and replace them with their input |
| 1643 // that comes from the only live predecessor if that dominates the phi. | 1624 // that comes from the only live predecessor if that dominates the phi. |
| 1644 // | |
| 1645 // TODO(sra): If the input is directly in the only live predecessor, it | |
| 1646 // might be possible to move it into [block] (e.g. all its inputs are | |
| 1647 // dominating.) | |
| 1648 block.forEachPhi((HPhi phi) { | 1625 block.forEachPhi((HPhi phi) { |
| 1649 HInstruction replacement = | 1626 HInstruction replacement = |
| 1650 (indexOfLive >= 0) ? phi.inputs[indexOfLive] : zapInstruction; | 1627 (indexOfLive >= 0) ? phi.inputs[indexOfLive] : zapInstruction; |
| 1651 if (replacement.dominates(phi)) { | 1628 if (replacement.dominates(phi)) { |
| 1652 block.rewrite(phi, replacement); | 1629 block.rewrite(phi, replacement); |
| 1653 block.removePhi(phi); | 1630 block.removePhi(phi); |
| 1654 } | 1631 } |
| 1655 }); | 1632 }); |
| 1656 } | 1633 } |
| 1657 } | 1634 } |
| (...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2186 void visitGraph(HGraph graph) { | 2163 void visitGraph(HGraph graph) { |
| 2187 visitDominatorTree(graph); | 2164 visitDominatorTree(graph); |
| 2188 } | 2165 } |
| 2189 | 2166 |
| 2190 // Update users of [input] that are dominated by [:dominator.first:] | 2167 // Update users of [input] that are dominated by [:dominator.first:] |
| 2191 // to use [TypeKnown] of [input] instead. As the type information depends | 2168 // to use [TypeKnown] of [input] instead. As the type information depends |
| 2192 // on the control flow, we mark the inserted [HTypeKnown] nodes as | 2169 // on the control flow, we mark the inserted [HTypeKnown] nodes as |
| 2193 // non-movable. | 2170 // non-movable. |
| 2194 void insertTypePropagationForDominatedUsers( | 2171 void insertTypePropagationForDominatedUsers( |
| 2195 HBasicBlock dominator, HInstruction input, TypeMask convertedType) { | 2172 HBasicBlock dominator, HInstruction input, TypeMask convertedType) { |
| 2196 DominatedUses dominatedUses = DominatedUses.of(input, dominator.first); | 2173 Setlet<HInstruction> dominatedUsers = input.dominatedUsers(dominator.first); |
| 2197 if (dominatedUses.isEmpty) return; | 2174 if (dominatedUsers.isEmpty) return; |
| 2198 | 2175 |
| 2199 HTypeKnown newInput = new HTypeKnown.pinned(convertedType, input); | 2176 HTypeKnown newInput = new HTypeKnown.pinned(convertedType, input); |
| 2200 dominator.addBefore(dominator.first, newInput); | 2177 dominator.addBefore(dominator.first, newInput); |
| 2201 dominatedUses.replaceWith(newInput); | 2178 dominatedUsers.forEach((HInstruction user) { |
| 2179 user.changeUse(input, newInput); |
| 2180 }); |
| 2202 } | 2181 } |
| 2203 | 2182 |
| 2204 void visitIs(HIs instruction) { | 2183 void visitIs(HIs instruction) { |
| 2205 ResolutionDartType type = instruction.typeExpression; | 2184 ResolutionDartType type = instruction.typeExpression; |
| 2206 if (!instruction.isRawCheck) { | 2185 if (!instruction.isRawCheck) { |
| 2207 return; | 2186 return; |
| 2208 } else if (type.isTypedef) { | 2187 } else if (type.isTypedef) { |
| 2209 return; | 2188 return; |
| 2210 } | 2189 } |
| 2211 ResolutionInterfaceType interfaceType = type; | 2190 ResolutionInterfaceType interfaceType = type; |
| (...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2857 | 2836 |
| 2858 keyedValues.forEach((receiver, values) { | 2837 keyedValues.forEach((receiver, values) { |
| 2859 result.keyedValues[receiver] = | 2838 result.keyedValues[receiver] = |
| 2860 new Map<HInstruction, HInstruction>.from(values); | 2839 new Map<HInstruction, HInstruction>.from(values); |
| 2861 }); | 2840 }); |
| 2862 | 2841 |
| 2863 result.nonEscapingReceivers.addAll(nonEscapingReceivers); | 2842 result.nonEscapingReceivers.addAll(nonEscapingReceivers); |
| 2864 return result; | 2843 return result; |
| 2865 } | 2844 } |
| 2866 } | 2845 } |
| OLD | NEW |