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

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

Issue 1655183002: dart2js cps: Remove interceptors in cases where type propagation fails. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Remove debugging code & rebase Created 4 years, 10 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
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 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 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 library dart2js.cps_ir.duplicate_branch; 4 library dart2js.cps_ir.duplicate_branch; // FIXME: Rename file.
5 5
6 import 'cps_ir_nodes.dart'; 6 import 'cps_ir_nodes.dart';
7 import 'optimizers.dart'; 7 import 'optimizers.dart';
8 import 'cps_fragment.dart'; 8 import 'cps_fragment.dart';
9 import '../js_backend/js_backend.dart';
10 import '../constants/values.dart';
11 import '../elements/elements.dart';
12 import '../universe/selector.dart';
13 import '../types/types.dart';
14 import 'type_mask_system.dart';
9 15
16 /// Optimizations based on intraprocedural forward dataflow analysis, taking
17 /// into account path information that is not expressed by [Refinement] nodes.
18 ///
19 /// ---
20 ///
10 /// Removes branches that branch on the same value as a previously seen branch. 21 /// Removes branches that branch on the same value as a previously seen branch.
11 /// For example: 22 /// For example:
12 /// 23 ///
13 /// if (x == y) { 24 /// if (x == y) {
14 /// if (x == y) TRUE else FALSE 25 /// if (x == y) TRUE else FALSE
15 /// } 26 /// }
16 /// 27 ///
17 /// ==> ([GVN] pass merges identical expressions) 28 /// ==> ([GVN] pass merges identical expressions)
18 /// 29 ///
19 /// var b = (x == y) 30 /// var b = (x == y)
20 /// if (b) { 31 /// if (b) {
21 /// if (b) TRUE else FALSE 32 /// if (b) TRUE else FALSE
22 /// } 33 /// }
23 /// 34 ///
24 /// ==> (this pass removes the duplicate branch) 35 /// ==> (this pass removes the duplicate branch)
25 /// 36 ///
26 /// var b = (x == y) 37 /// var b = (x == y)
27 /// if (b) { 38 /// if (b) {
28 /// TRUE 39 /// TRUE
29 /// } 40 /// }
41 ///
42 /// ---
43 ///
44 /// Removes interceptors for method calls whose receiver is known to be a
45 /// self-interceptor. For example:
46 ///
47 /// x.foo$1();
48 /// getInterceptor(x).$eq(x, y);
49 ///
50 /// ==> (`x` is a self-interceptor, remove the `getInterceptor` call)
51 ///
52 /// x.foo$1();
53 /// x.$eq(0, y);
54 ///
55 /// Although there is a [Refinement] node after the call to `x.foo$1()`, the
56 /// refined type cannot always be represented exactly, and type propagation
57 /// may therefore not see that `x` is a self-interceptor.
30 // 58 //
31 // TODO(asgerf): A kind of redundant join can arise where a branching condition 59 // 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 60 // is known to be true/false on all but one predecessor for a branch. We could
33 // try to reduce those. 61 // try to reduce those.
34 // 62 //
35 // TODO(asgerf): Could be more precise if GVN shared expressions that are not 63 // 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. 64 // in direct scope of one another, e.g. by using phis pass the shared value.
37 // 65 //
38 class DuplicateBranchEliminator extends TrampolineRecursiveVisitor 66 class PathBasedOptimizer extends TrampolineRecursiveVisitor
39 implements Pass { 67 implements Pass {
40 String get passName => 'Duplicate branch elimination'; 68 String get passName => 'Path-based optimizations';
41 69
70 // Classification of all values.
42 static const int TRUE = 1 << 0; 71 static const int TRUE = 1 << 0;
43 static const int OTHER_TRUTHY = 1 << 1; 72 static const int SELF_INTERCEPTOR = 1 << 1;
44 static const int FALSE = 1 << 2; 73 static const int INTERCEPTED_TRUTHY = 1 << 2;
45 static const int OTHER_FALSY = 1 << 3; 74 static const int FALSE = 1 << 3;
75 static const int OTHER_FALSY = 1 << 4;
46 76
47 static const int TRUTHY = TRUE | OTHER_TRUTHY; 77 static const int TRUTHY = TRUE | SELF_INTERCEPTOR | INTERCEPTED_TRUTHY;
48 static const int FALSY = FALSE | OTHER_FALSY; 78 static const int FALSY = FALSE | OTHER_FALSY;
49 static const int ANY = TRUTHY | FALSY; 79 static const int ANY = TRUTHY | FALSY;
50 80
81 final JavaScriptBackend backend;
82 final TypeMaskSystem typeSystem;
83
84 PathBasedOptimizer(this.backend, this.typeSystem);
85
51 /// The possible values of the given primitive (or ANY if absent) at the 86 /// The possible values of the given primitive (or ANY if absent) at the
52 /// current traversal position. 87 /// current traversal position.
53 Map<Primitive, int> valueOf = <Primitive, int>{}; 88 Map<Primitive, int> valueOf = <Primitive, int>{};
54 89
55 /// The possible values of each primitive at the entry to a continuation. 90 /// The possible values of each primitive at the entry to a continuation.
56 /// 91 ///
57 /// Unreachable continuations are absent from the map. 92 /// Unreachable continuations are absent from the map.
58 final Map<Continuation, Map<Primitive, int>> valuesAt = 93 final Map<Continuation, Map<Primitive, int>> valuesAt =
59 <Continuation, Map<Primitive, int>>{}; 94 <Continuation, Map<Primitive, int>>{};
60 95
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 destroyAndReplace(node, new InvokeContinuation(falseCont, [])); 148 destroyAndReplace(node, new InvokeContinuation(falseCont, []));
114 valuesAt[falseCont] = valueOf; 149 valuesAt[falseCont] = valueOf;
115 } else if (values & negativeValues == 0) { 150 } else if (values & negativeValues == 0) {
116 destroyAndReplace(node, new InvokeContinuation(trueCont, [])); 151 destroyAndReplace(node, new InvokeContinuation(trueCont, []));
117 valuesAt[trueCont] = valueOf; 152 valuesAt[trueCont] = valueOf;
118 } else { 153 } else {
119 valuesAt[trueCont] = copy(valueOf)..[condition] = values & positiveValues; 154 valuesAt[trueCont] = copy(valueOf)..[condition] = values & positiveValues;
120 valuesAt[falseCont] = valueOf..[condition] = values & negativeValues; 155 valuesAt[falseCont] = valueOf..[condition] = values & negativeValues;
121 } 156 }
122 } 157 }
158
159 void visitInvokeMethod(InvokeMethod node) {
160 int receiverValue = valueOf[node.dartReceiver] ?? ANY;
161 if (!backend.isInterceptedSelector(node.selector)) {
162 // Only self-interceptors can respond to a non-intercepted selector.
163 valueOf[node.dartReceiver] = receiverValue & SELF_INTERCEPTOR;
164 } else if (receiverValue & ~SELF_INTERCEPTOR == 0 &&
165 node.callingConvention == CallingConvention.Intercepted) {
166 // This is an intercepted call whose receiver is definitely a
167 // self-interceptor.
168 // TODO(25646): If TypeMasks could represent "any self-interceptor" this
169 // optimization should be subsumed by type propagation.
170 node.receiver.changeTo(node.dartReceiver);
171
172 // Replace the extra receiver argument with a dummy value if the
173 // target definitely does not use it.
174 if (typeSystem.targetIgnoresReceiverArgument(node.dartReceiver.type,
175 node.selector)) {
176 Constant dummy = new Constant(new IntConstantValue(0))
177 ..type = typeSystem.intType;
178 new LetPrim(dummy).insertAbove(node.parent);
179 node.arguments[0].changeTo(dummy);
180 node.callingConvention = CallingConvention.DummyIntercepted;
181 }
182 }
183 }
123 } 184 }
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