OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library cps_ir.optimization.insert_refinements; | 5 library cps_ir.optimization.insert_refinements; |
6 | 6 |
7 import 'dart:math' show min; | 7 import 'dart:math' show min; |
8 import 'optimizers.dart' show Pass; | 8 import 'optimizers.dart' show Pass; |
9 import 'cps_ir_nodes.dart'; | 9 import 'cps_ir_nodes.dart'; |
10 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 } | 104 } |
105 | 105 |
106 /// Refine the type of each argument on [node] according to the provided | 106 /// Refine the type of each argument on [node] according to the provided |
107 /// type masks. | 107 /// type masks. |
108 void _refineArguments( | 108 void _refineArguments( |
109 InvocationPrimitive node, List<TypeMask> argumentSuccessTypes) { | 109 InvocationPrimitive node, List<TypeMask> argumentSuccessTypes) { |
110 if (argumentSuccessTypes == null) return; | 110 if (argumentSuccessTypes == null) return; |
111 | 111 |
112 // Note: node.dartArgumentsLength is shorter when the call doesn't include | 112 // Note: node.dartArgumentsLength is shorter when the call doesn't include |
113 // some optional arguments. | 113 // some optional arguments. |
114 int length = min(argumentSuccessTypes.length, node.dartArgumentsLength); | 114 int length = min(argumentSuccessTypes.length, node.argumentRefs.length); |
115 for (int i = 0; i < length; i++) { | 115 for (int i = 0; i < length; i++) { |
116 TypeMask argSuccessType = argumentSuccessTypes[i]; | 116 TypeMask argSuccessType = argumentSuccessTypes[i]; |
117 | 117 |
118 // Skip arguments that provide no refinement. | 118 // Skip arguments that provide no refinement. |
119 if (argSuccessType == types.dynamicType) continue; | 119 if (argSuccessType == types.dynamicType) continue; |
120 | 120 |
121 applyRefinement(node.parent, | 121 applyRefinement(node.parent, |
122 new Refinement(node.dartArgument(i), argSuccessType)); | 122 new Refinement(node.argument(i), argSuccessType)); |
123 } | 123 } |
124 } | 124 } |
125 | 125 |
126 void visitInvokeStatic(InvokeStatic node) { | 126 void visitInvokeStatic(InvokeStatic node) { |
127 node.argumentRefs.forEach(processReference); | 127 node.argumentRefs.forEach(processReference); |
128 _refineArguments(node, | 128 _refineArguments(node, |
129 _getSuccessTypesForStaticMethod(types, node.target)); | 129 _getSuccessTypesForStaticMethod(types, node.target)); |
130 } | 130 } |
131 | 131 |
132 void visitInvokeMethod(InvokeMethod node) { | 132 void visitInvokeMethod(InvokeMethod node) { |
133 // Update references to their current refined values. | 133 // Update references to their current refined values. |
134 processReference(node.receiverRef); | 134 processReference(node.receiverRef); |
135 node.argumentRefs.forEach(processReference); | 135 node.argumentRefs.forEach(processReference); |
136 | 136 |
137 // If the call is intercepted, we want to refine the actual receiver, | 137 // If the call is intercepted, we want to refine the actual receiver, |
138 // not the interceptor. | 138 // not the interceptor. |
139 Primitive receiver = node.dartReceiver; | 139 Primitive receiver = node.receiver; |
140 | 140 |
141 // Do not try to refine the receiver of closure calls; the class world | 141 // Do not try to refine the receiver of closure calls; the class world |
142 // does not know about closure classes. | 142 // does not know about closure classes. |
143 Selector selector = node.selector; | 143 Selector selector = node.selector; |
144 if (!selector.isClosureCall) { | 144 if (!selector.isClosureCall) { |
145 // Filter away receivers that throw on this selector. | 145 // Filter away receivers that throw on this selector. |
146 TypeMask type = types.receiverTypeFor(selector, node.mask); | 146 TypeMask type = types.receiverTypeFor(selector, node.mask); |
147 Refinement refinement = new Refinement(receiver, type); | 147 Refinement refinement = new Refinement(receiver, type); |
148 LetPrim letPrim = node.parent; | 148 LetPrim letPrim = node.parent; |
149 applyRefinement(letPrim, refinement); | 149 applyRefinement(letPrim, refinement); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 Refinement refinedFalse = new Refinement(second, types.nonNullType); | 226 Refinement refinedFalse = new Refinement(second, types.nonNullType); |
227 pushRefinement(trueCont, refinedTrue); | 227 pushRefinement(trueCont, refinedTrue); |
228 pushRefinement(falseCont, refinedFalse); | 228 pushRefinement(falseCont, refinedFalse); |
229 } else { | 229 } else { |
230 push(trueCont); | 230 push(trueCont); |
231 push(falseCont); | 231 push(falseCont); |
232 } | 232 } |
233 } | 233 } |
234 | 234 |
235 if (condition is InvokeMethod && condition.selector == Selectors.equals) { | 235 if (condition is InvokeMethod && condition.selector == Selectors.equals) { |
236 refineEquality(condition.dartReceiver, | 236 refineEquality(condition.receiver, |
237 condition.dartArgument(0), | 237 condition.argument(0), |
238 trueCont, | 238 trueCont, |
239 falseCont); | 239 falseCont); |
240 return; | 240 return; |
241 } | 241 } |
242 | 242 |
243 if (condition is ApplyBuiltinOperator && | 243 if (condition is ApplyBuiltinOperator && |
244 condition.operator == BuiltinOperator.Identical) { | 244 condition.operator == BuiltinOperator.Identical) { |
245 refineEquality(condition.argument(0), | 245 refineEquality(condition.argument(0), |
246 condition.argument(1), | 246 condition.argument(1), |
247 trueCont, | 247 trueCont, |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 case 'exp': | 422 case 'exp': |
423 case 'log': | 423 case 'log': |
424 return [types.numType]; | 424 return [types.numType]; |
425 case 'pow': | 425 case 'pow': |
426 return [types.numType, types.numType]; | 426 return [types.numType, types.numType]; |
427 } | 427 } |
428 } | 428 } |
429 | 429 |
430 return null; | 430 return null; |
431 } | 431 } |
OLD | NEW |