| 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.inline; | 5 library cps_ir.optimization.inline; |
| 6 | 6 |
| 7 import 'cps_fragment.dart'; | 7 import 'cps_fragment.dart'; |
| 8 import 'cps_ir_builder.dart' show ThisParameterLocal; | 8 import 'cps_ir_builder.dart' show ThisParameterLocal; |
| 9 import 'cps_ir_nodes.dart'; | 9 import 'cps_ir_nodes.dart'; |
| 10 import 'optimizers.dart'; | 10 import 'optimizers.dart'; |
| 11 import 'type_mask_system.dart' show TypeMaskSystem; | 11 import 'type_mask_system.dart' show TypeMaskSystem; |
| 12 import '../dart_types.dart' show DartType, GenericType; | 12 import '../dart_types.dart' show DartType, GenericType; |
| 13 import '../world.dart' show World; | 13 import '../world.dart' show World; |
| 14 import '../elements/elements.dart'; | 14 import '../elements/elements.dart'; |
| 15 import '../js_backend/js_backend.dart' show JavaScriptBackend; | 15 import '../js_backend/js_backend.dart' show JavaScriptBackend; |
| 16 import '../js_backend/codegen/task.dart' show CpsFunctionCompiler; | 16 import '../js_backend/codegen/task.dart' show CpsFunctionCompiler; |
| 17 import '../types/types.dart' show | 17 import '../types/types.dart' show |
| 18 FlatTypeMask, ForwardingTypeMask, TypeMask, UnionTypeMask; | 18 FlatTypeMask, ForwardingTypeMask, TypeMask, UnionTypeMask; |
| 19 import '../universe/call_structure.dart' show CallStructure; | 19 import '../universe/call_structure.dart' show CallStructure; |
| 20 import '../universe/selector.dart' show Selector; | 20 import '../universe/selector.dart' show Selector; |
| 21 import 'package:js_ast/js_ast.dart' as js; |
| 21 | 22 |
| 22 /// Inlining stack entries. | 23 /// Inlining stack entries. |
| 23 /// | 24 /// |
| 24 /// During inlining, a stack is used to detect cycles in the call graph. | 25 /// During inlining, a stack is used to detect cycles in the call graph. |
| 25 class StackEntry { | 26 class StackEntry { |
| 26 // Dynamically resolved calls might be targeting an adapter function that | 27 // Dynamically resolved calls might be targeting an adapter function that |
| 27 // fills in optional arguments not passed at the call site. Therefore these | 28 // fills in optional arguments not passed at the call site. Therefore these |
| 28 // calls are represented by the eventual target and the call structure at | 29 // calls are represented by the eventual target and the call structure at |
| 29 // the call site, which together identify the target. Statically resolved | 30 // the call site, which together identify the target. Statically resolved |
| 30 // calls are represented by the target element and a null call structure. | 31 // calls are represented by the target element and a null call structure. |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 processThrow(Throw nose) => ++size; | 253 processThrow(Throw nose) => ++size; |
| 253 processRethrow(Rethrow node) => ++size; | 254 processRethrow(Rethrow node) => ++size; |
| 254 | 255 |
| 255 // Discount primitives that do not generate code. | 256 // Discount primitives that do not generate code. |
| 256 processRefinement(Refinement node) => --size; | 257 processRefinement(Refinement node) => --size; |
| 257 processBoundsCheck(BoundsCheck node) { | 258 processBoundsCheck(BoundsCheck node) { |
| 258 if (node.hasNoChecks) { | 259 if (node.hasNoChecks) { |
| 259 --size; | 260 --size; |
| 260 } | 261 } |
| 261 } | 262 } |
| 263 |
| 264 processForeignCode(ForeignCode node) { |
| 265 // Count the number of nodes in the JS fragment, and discount the size |
| 266 // originally added by LetPrim. |
| 267 JsSizeVisitor visitor = new JsSizeVisitor(); |
| 268 node.codeTemplate.ast.accept(visitor); |
| 269 size += visitor.size - 1; |
| 270 } |
| 262 } | 271 } |
| 263 | 272 |
| 273 class JsSizeVisitor extends js.BaseVisitor { |
| 274 int size = 0; |
| 275 |
| 276 visitNode(js.Node node) { |
| 277 ++size; |
| 278 return super.visitNode(node); |
| 279 } |
| 280 |
| 281 visitInterpolatedExpression(js.InterpolatedExpression node) { |
| 282 // Suppress call to visitNode. Placeholders should not be counted, because |
| 283 // the argument has already been counted, and will in most cases be inserted |
| 284 // directly in the placeholder. |
| 285 } |
| 286 } |
| 287 |
| 288 |
| 264 class InliningVisitor extends TrampolineRecursiveVisitor { | 289 class InliningVisitor extends TrampolineRecursiveVisitor { |
| 265 final Inliner _inliner; | 290 final Inliner _inliner; |
| 266 | 291 |
| 267 // A successful inlining attempt returns the [Primitive] that represents the | 292 // A successful inlining attempt returns the [Primitive] that represents the |
| 268 // result of the inlined call or null. If the result is non-null, the body | 293 // result of the inlined call or null. If the result is non-null, the body |
| 269 // of the inlined function is available in this field. | 294 // of the inlined function is available in this field. |
| 270 CpsFragment _fragment; | 295 CpsFragment _fragment; |
| 271 | 296 |
| 272 InliningVisitor(this._inliner); | 297 InliningVisitor(this._inliner); |
| 273 | 298 |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 (enclosingClass == backend.helpers.jsNumberClass || | 620 (enclosingClass == backend.helpers.jsNumberClass || |
| 596 enclosingClass == backend.helpers.jsDoubleClass || | 621 enclosingClass == backend.helpers.jsDoubleClass || |
| 597 enclosingClass == backend.helpers.jsIntClass)) { | 622 enclosingClass == backend.helpers.jsIntClass)) { |
| 598 // These should be handled by operator specialization. | 623 // These should be handled by operator specialization. |
| 599 return true; | 624 return true; |
| 600 } | 625 } |
| 601 if (target == backend.helpers.stringInterpolationHelper) return true; | 626 if (target == backend.helpers.stringInterpolationHelper) return true; |
| 602 return false; | 627 return false; |
| 603 } | 628 } |
| 604 } | 629 } |
| OLD | NEW |