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

Side by Side Diff: pkg/compiler/lib/src/ssa/optimize.dart

Issue 2755353003: dart2js: Insert HTypeKnown refinement nodes on dominated edges of HPhi nodes. (Closed)
Patch Set: Created 3 years, 9 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
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 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 super(backend.compiler.measurer); 45 super(backend.compiler.measurer);
46 46
47 String get name => 'SSA optimizer'; 47 String get name => 'SSA optimizer';
48 48
49 Compiler get compiler => backend.compiler; 49 Compiler get compiler => backend.compiler;
50 50
51 void optimize(CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) { 51 void optimize(CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) {
52 void runPhase(OptimizationPhase phase) { 52 void runPhase(OptimizationPhase phase) {
53 measureSubtask(phase.name, () => phase.visitGraph(graph)); 53 measureSubtask(phase.name, () => phase.visitGraph(graph));
54 backend.tracer.traceGraph(phase.name, graph); 54 backend.tracer.traceGraph(phase.name, graph);
55 assert(graph.isValid()); 55 assert(graph.isValid(), 'Graph not valid after ${phase.name}');
56 } 56 }
57 57
58 bool trustPrimitives = compiler.options.trustPrimitives; 58 bool trustPrimitives = compiler.options.trustPrimitives;
59 CodegenRegistry registry = work.registry; 59 CodegenRegistry registry = work.registry;
60 Set<HInstruction> boundsChecked = new Set<HInstruction>(); 60 Set<HInstruction> boundsChecked = new Set<HInstruction>();
61 SsaCodeMotion codeMotion; 61 SsaCodeMotion codeMotion;
62 measure(() { 62 measure(() {
63 List<OptimizationPhase> phases = <OptimizationPhase>[ 63 List<OptimizationPhase> phases = <OptimizationPhase>[
64 // Run trivial instruction simplification first to optimize 64 // Run trivial instruction simplification first to optimize
65 // some patterns useful for type conversion. 65 // some patterns useful for type conversion.
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 return null; 704 return null;
705 } 705 }
706 706
707 HInstruction visitIdentity(HIdentity node) { 707 HInstruction visitIdentity(HIdentity node) {
708 HInstruction newInstruction = handleIdentityCheck(node); 708 HInstruction newInstruction = handleIdentityCheck(node);
709 return newInstruction == null ? super.visitIdentity(node) : newInstruction; 709 return newInstruction == null ? super.visitIdentity(node) : newInstruction;
710 } 710 }
711 711
712 void simplifyCondition( 712 void simplifyCondition(
713 HBasicBlock block, HInstruction condition, bool value) { 713 HBasicBlock block, HInstruction condition, bool value) {
714 condition.dominatedUsers(block.first).forEach((user) { 714 // `excludePhiOutEdges: true` prevents replacing a partially dominated phi
715 HInstruction newCondition = graph.addConstantBool(value, closedWorld); 715 // node input with a constant. This tends to add unnecessary assignments, by
716 user.changeUse(condition, newCondition); 716 // transforming the following, which has phi(false, x),
717 }); 717 //
718 // if (x) { init(); x = false; }
719 //
720 // into this, which has phi(false, false)
721 //
722 // if (x) { init(); x = false; } else { x = false; }
723 //
724 // which is further simplifed to:
725 //
726 // if (x) { init(); }
727 // ...
728 // x = false;
729 //
730 // This is mostly harmless (if a little confusing) but does cause a lot of
731 // `x = false;` copies to be inserted when a loop body has many continue
732 // statements or ends with a switch.
Emily Fortuna 2017/04/03 20:48:46 👏👏👏 (that's a hand clapping emoji in case it's not
733 var uses =
734 DominatedUses.of(condition, block.first, excludePhiOutEdges: true);
735 if (uses.isEmpty) return;
736 uses.replaceWith(graph.addConstantBool(value, closedWorld));
718 } 737 }
719 738
720 HInstruction visitIf(HIf node) { 739 HInstruction visitIf(HIf node) {
721 HInstruction condition = node.condition; 740 HInstruction condition = node.condition;
722 if (condition.isConstant()) return node; 741 if (condition.isConstant()) return node;
723 bool isNegated = condition is HNot; 742 bool isNegated = condition is HNot;
724 743
725 if (isNegated) { 744 if (isNegated) {
726 condition = condition.inputs[0]; 745 condition = condition.inputs[0];
727 } else { 746 } else {
(...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after
1591 // Find the index of the single live predecessor if it exists. 1610 // Find the index of the single live predecessor if it exists.
1592 int indexOfLive = -1; 1611 int indexOfLive = -1;
1593 for (int i = 0; i < predecessors.length; i++) { 1612 for (int i = 0; i < predecessors.length; i++) {
1594 if (predecessors[i].isLive) { 1613 if (predecessors[i].isLive) {
1595 if (indexOfLive >= 0) continue L; 1614 if (indexOfLive >= 0) continue L;
1596 indexOfLive = i; 1615 indexOfLive = i;
1597 } 1616 }
1598 } 1617 }
1599 // Run through the phis of the block and replace them with their input 1618 // Run through the phis of the block and replace them with their input
1600 // that comes from the only live predecessor if that dominates the phi. 1619 // that comes from the only live predecessor if that dominates the phi.
1620 //
1621 // TODO(sra): If the input is directly in the only live predecessor, it
1622 // might be possible to move it into [block] (e.g. all its inputs are
1623 // dominating.)
1601 block.forEachPhi((HPhi phi) { 1624 block.forEachPhi((HPhi phi) {
1602 HInstruction replacement = 1625 HInstruction replacement =
1603 (indexOfLive >= 0) ? phi.inputs[indexOfLive] : zapInstruction; 1626 (indexOfLive >= 0) ? phi.inputs[indexOfLive] : zapInstruction;
1604 if (replacement.dominates(phi)) { 1627 if (replacement.dominates(phi)) {
1605 block.rewrite(phi, replacement); 1628 block.rewrite(phi, replacement);
1606 block.removePhi(phi); 1629 block.removePhi(phi);
1607 } 1630 }
1608 }); 1631 });
1609 } 1632 }
1610 } 1633 }
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
2139 void visitGraph(HGraph graph) { 2162 void visitGraph(HGraph graph) {
2140 visitDominatorTree(graph); 2163 visitDominatorTree(graph);
2141 } 2164 }
2142 2165
2143 // Update users of [input] that are dominated by [:dominator.first:] 2166 // Update users of [input] that are dominated by [:dominator.first:]
2144 // to use [TypeKnown] of [input] instead. As the type information depends 2167 // to use [TypeKnown] of [input] instead. As the type information depends
2145 // on the control flow, we mark the inserted [HTypeKnown] nodes as 2168 // on the control flow, we mark the inserted [HTypeKnown] nodes as
2146 // non-movable. 2169 // non-movable.
2147 void insertTypePropagationForDominatedUsers( 2170 void insertTypePropagationForDominatedUsers(
2148 HBasicBlock dominator, HInstruction input, TypeMask convertedType) { 2171 HBasicBlock dominator, HInstruction input, TypeMask convertedType) {
2149 Setlet<HInstruction> dominatedUsers = input.dominatedUsers(dominator.first); 2172 DominatedUses dominatedUses = DominatedUses.of(input, dominator.first);
2150 if (dominatedUsers.isEmpty) return; 2173 if (dominatedUses.isEmpty) return;
2151 2174
2152 HTypeKnown newInput = new HTypeKnown.pinned(convertedType, input); 2175 HTypeKnown newInput = new HTypeKnown.pinned(convertedType, input);
2153 dominator.addBefore(dominator.first, newInput); 2176 dominator.addBefore(dominator.first, newInput);
2154 dominatedUsers.forEach((HInstruction user) { 2177 dominatedUses.replaceWith(newInput);
2155 user.changeUse(input, newInput);
2156 });
2157 } 2178 }
2158 2179
2159 void visitIs(HIs instruction) { 2180 void visitIs(HIs instruction) {
2160 ResolutionDartType type = instruction.typeExpression; 2181 ResolutionDartType type = instruction.typeExpression;
2161 if (!instruction.isRawCheck) { 2182 if (!instruction.isRawCheck) {
2162 return; 2183 return;
2163 } else if (type.isTypedef) { 2184 } else if (type.isTypedef) {
2164 return; 2185 return;
2165 } 2186 }
2166 ResolutionInterfaceType interfaceType = type; 2187 ResolutionInterfaceType interfaceType = type;
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after
2788 2809
2789 keyedValues.forEach((receiver, values) { 2810 keyedValues.forEach((receiver, values) {
2790 result.keyedValues[receiver] = 2811 result.keyedValues[receiver] =
2791 new Map<HInstruction, HInstruction>.from(values); 2812 new Map<HInstruction, HInstruction>.from(values);
2792 }); 2813 });
2793 2814
2794 result.nonEscapingReceivers.addAll(nonEscapingReceivers); 2815 result.nonEscapingReceivers.addAll(nonEscapingReceivers);
2795 return result; 2816 return result;
2796 } 2817 }
2797 } 2818 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698