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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/duplicate_branch.dart

Issue 1585923010: dart2js cps: Eliminate duplicate branches. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Add missing type annotations Created 4 years, 11 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/optimizers.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
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.
4 library dart2js.cps_ir.duplicate_branch;
5
6 import 'cps_ir_nodes.dart';
7 import 'optimizers.dart';
8 import 'cps_fragment.dart';
9
10 /// Removes branches that branch on the same value as a previously seen branch.
11 /// For example:
12 ///
13 /// if (x == y) {
14 /// if (x == y) TRUE else FALSE
15 /// }
16 ///
17 /// ==> ([GVN] pass merges identical expressions)
18 ///
19 /// var b = (x == y)
20 /// if (b) {
21 /// if (b) TRUE else FALSE
22 /// }
23 ///
24 /// ==> (this pass removes the duplicate branch)
25 ///
26 /// var b = (x == y)
27 /// if (b) {
28 /// TRUE
29 /// }
30 //
31 // TODO(asgerf): A kind of redundant join can arise where a branching condition
32 // is known to be true/false on all but one predecessor for a branch. We could
33 // try to reduce those.
34 //
35 // TODO(asgerf): Could be more precise if GVN shared expressions that are not
36 // in direct scope of one another, e.g. by using phis pass the shared value.
37 //
38 class DuplicateBranchEliminator extends TrampolineRecursiveVisitor
39 implements Pass {
40 String get passName => 'Duplicate branch elimination';
41
42 static const int TRUE = 1 << 0;
43 static const int OTHER_TRUTHY = 1 << 1;
44 static const int FALSE = 1 << 2;
45 static const int OTHER_FALSY = 1 << 3;
46
47 static const int TRUTHY = TRUE | OTHER_TRUTHY;
48 static const int FALSY = FALSE | OTHER_FALSY;
49 static const int ANY = TRUTHY | FALSY;
50
51 /// The possible values of the given primitive (or ANY if absent) at the
52 /// current traversal position.
53 Map<Primitive, int> valueOf = <Primitive, int>{};
54
55 /// The possible values of each primitive at the entry to a continuation.
56 ///
57 /// Unreachable continuations are absent from the map.
58 final Map<Continuation, Map<Primitive, int>> valuesAt =
59 <Continuation, Map<Primitive, int>>{};
60
61 void rewrite(FunctionDefinition node) {
62 visit(node);
63 }
64
65 Map<Primitive, int> copy(Map<Primitive, int> map) {
66 return new Map<Primitive, int>.from(map);
67 }
68
69 Expression traverseLetHandler(LetHandler node) {
70 valuesAt[node.handler] = copy(valueOf);
71 push(node.handler);
72 return node.body;
73 }
74
75 Expression traverseContinuation(Continuation cont) {
76 valueOf = valuesAt[cont];
77 if (valueOf == null) {
78 // Do not go into unreachable code.
79 destroyAndReplace(cont.body, new Unreachable());
80 }
81 return cont.body;
82 }
83
84 void visitInvokeContinuation(InvokeContinuation node) {
85 Continuation cont = node.continuation.definition;
86 if (cont.isReturnContinuation) return;
87 if (node.isRecursive) return;
88 Map<Primitive, int> target = valuesAt[cont];
89 if (target == null) {
90 valuesAt[cont] = valueOf;
91 } else {
92 for (Primitive prim in target.keys) {
93 target[prim] |= valueOf[prim] ?? ANY;
94 }
95 }
96 }
97
98 visitBranch(Branch node) {
99 Primitive condition = node.condition.definition.effectiveDefinition;
100 Continuation trueCont = node.trueContinuation.definition;
101 Continuation falseCont = node.falseContinuation.definition;
102 if (condition.hasExactlyOneUse) {
103 // Handle common case specially. Do not add [condition] to the map if
104 // there are no other uses.
105 valuesAt[trueCont] = copy(valueOf);
106 valuesAt[falseCont] = valueOf;
107 return;
108 }
109 int values = valueOf[condition] ?? ANY;
110 int positiveValues = node.isStrictCheck ? TRUE : TRUTHY;
111 int negativeValues = (~positiveValues) & ANY;
112 if (values & positiveValues == 0) {
113 destroyAndReplace(node, new InvokeContinuation(falseCont, []));
114 valuesAt[falseCont] = valueOf;
115 } else if (values & negativeValues == 0) {
116 destroyAndReplace(node, new InvokeContinuation(trueCont, []));
117 valuesAt[trueCont] = valueOf;
118 } else {
119 valuesAt[trueCont] = copy(valueOf)..[condition] = values & positiveValues;
120 valuesAt[falseCont] = valueOf..[condition] = values & negativeValues;
121 }
122 }
123 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/optimizers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698