OLD | NEW |
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.path_based_optimizer; | 4 library dart2js.cps_ir.path_based_optimizer; |
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'; | 9 import '../js_backend/js_backend.dart'; |
10 import 'type_mask_system.dart'; | 10 import 'type_mask_system.dart'; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 /// refined type cannot always be represented exactly, and type propagation | 52 /// refined type cannot always be represented exactly, and type propagation |
53 /// may therefore not see that `x` is a self-interceptor. | 53 /// may therefore not see that `x` is a self-interceptor. |
54 // | 54 // |
55 // TODO(asgerf): A kind of redundant join can arise where a branching condition | 55 // TODO(asgerf): A kind of redundant join can arise where a branching condition |
56 // is known to be true/false on all but one predecessor for a branch. We could | 56 // is known to be true/false on all but one predecessor for a branch. We could |
57 // try to reduce those. | 57 // try to reduce those. |
58 // | 58 // |
59 // TODO(asgerf): Could be more precise if GVN shared expressions that are not | 59 // TODO(asgerf): Could be more precise if GVN shared expressions that are not |
60 // in direct scope of one another, e.g. by using phis pass the shared value. | 60 // in direct scope of one another, e.g. by using phis pass the shared value. |
61 // | 61 // |
62 class PathBasedOptimizer extends TrampolineRecursiveVisitor | 62 class PathBasedOptimizer extends TrampolineRecursiveVisitor implements Pass { |
63 implements Pass { | |
64 String get passName => 'Path-based optimizations'; | 63 String get passName => 'Path-based optimizations'; |
65 | 64 |
66 // Classification of all values. | 65 // Classification of all values. |
67 static const int TRUE = 1 << 0; | 66 static const int TRUE = 1 << 0; |
68 static const int SELF_INTERCEPTOR = 1 << 1; | 67 static const int SELF_INTERCEPTOR = 1 << 1; |
69 static const int INTERCEPTED_TRUTHY = 1 << 2; | 68 static const int INTERCEPTED_TRUTHY = 1 << 2; |
70 static const int FALSE = 1 << 3; | 69 static const int FALSE = 1 << 3; |
71 static const int OTHER_FALSY = 1 << 4; | 70 static const int OTHER_FALSY = 1 << 4; |
72 | 71 |
73 static const int TRUTHY = TRUE | SELF_INTERCEPTOR | INTERCEPTED_TRUTHY; | 72 static const int TRUTHY = TRUE | SELF_INTERCEPTOR | INTERCEPTED_TRUTHY; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 valuesAt[falseCont] = valueOf..[condition] = values & negativeValues; | 150 valuesAt[falseCont] = valueOf..[condition] = values & negativeValues; |
152 } | 151 } |
153 } | 152 } |
154 | 153 |
155 void visitInvokeMethod(InvokeMethod node) { | 154 void visitInvokeMethod(InvokeMethod node) { |
156 int receiverValue = valueOf[node.receiver] ?? ANY; | 155 int receiverValue = valueOf[node.receiver] ?? ANY; |
157 if (!backend.isInterceptedSelector(node.selector)) { | 156 if (!backend.isInterceptedSelector(node.selector)) { |
158 // Only self-interceptors can respond to a non-intercepted selector. | 157 // Only self-interceptors can respond to a non-intercepted selector. |
159 valueOf[node.receiver] = receiverValue & SELF_INTERCEPTOR; | 158 valueOf[node.receiver] = receiverValue & SELF_INTERCEPTOR; |
160 } else if (receiverValue & ~SELF_INTERCEPTOR == 0 && | 159 } else if (receiverValue & ~SELF_INTERCEPTOR == 0 && |
161 node.callingConvention == CallingConvention.Intercepted) { | 160 node.callingConvention == CallingConvention.Intercepted) { |
162 // This is an intercepted call whose receiver is definitely a | 161 // This is an intercepted call whose receiver is definitely a |
163 // self-interceptor. | 162 // self-interceptor. |
164 // TODO(25646): If TypeMasks could represent "any self-interceptor" this | 163 // TODO(25646): If TypeMasks could represent "any self-interceptor" this |
165 // optimization should be subsumed by type propagation. | 164 // optimization should be subsumed by type propagation. |
166 node.interceptorRef.changeTo(node.receiver); | 165 node.interceptorRef.changeTo(node.receiver); |
167 | 166 |
168 // Replace the extra receiver argument with a dummy value if the | 167 // Replace the extra receiver argument with a dummy value if the |
169 // target definitely does not use it. | 168 // target definitely does not use it. |
170 if (typeSystem.targetIgnoresReceiverArgument(node.receiver.type, | 169 if (typeSystem.targetIgnoresReceiverArgument( |
171 node.selector)) { | 170 node.receiver.type, node.selector)) { |
172 node.makeDummyIntercepted(); | 171 node.makeDummyIntercepted(); |
173 } | 172 } |
174 } | 173 } |
175 } | 174 } |
176 } | 175 } |
OLD | NEW |