| 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 |