Chromium Code Reviews| 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'; |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 398 return null; | 398 return null; |
| 399 } | 399 } |
| 400 | 400 |
| 401 // Don't inline methods that never return. They are usually helper functions | 401 // Don't inline methods that never return. They are usually helper functions |
| 402 // that throw an exception. | 402 // that throw an exception. |
| 403 if (invoke.type.isEmpty && !invoke.type.isNullable) { | 403 if (invoke.type.isEmpty && !invoke.type.isNullable) { |
| 404 // TODO(sra): It would be ok to inline if doing so was shrinking. | 404 // TODO(sra): It would be ok to inline if doing so was shrinking. |
| 405 return null; | 405 return null; |
| 406 } | 406 } |
| 407 | 407 |
| 408 if (isBlacklisted(target)) return null; | |
| 409 | |
| 410 if (invoke.callingConvention == CallingConvention.OneShotIntercepted) { | |
|
Siggi Cherem (dart-lang)
2016/02/05 18:19:39
Is this mainly for the one-shot interceptors you i
asgerf
2016/02/09 12:19:54
Regular one-shot interceptors are inserted later i
| |
| 411 // One-shot interceptor calls with a known target are only inserted on | |
| 412 // uncommon code paths, so they should not be inlined. | |
| 413 return null; | |
| 414 } | |
| 415 | |
| 408 Reference<Primitive> dartReceiver = invoke.dartReceiverReference; | 416 Reference<Primitive> dartReceiver = invoke.dartReceiverReference; |
| 409 TypeMask abstractReceiver = | 417 TypeMask abstractReceiver = |
| 410 dartReceiver == null ? null : abstractType(dartReceiver); | 418 dartReceiver == null ? null : abstractType(dartReceiver); |
| 411 // The receiver is non-null in a method body, unless the receiver is known | 419 // The receiver is non-null in a method body, unless the receiver is known |
| 412 // to be `null` (isEmpty covers `null` and unreachable). | 420 // to be `null` (isEmpty covers `null` and unreachable). |
| 413 TypeMask abstractReceiverInMethod = abstractReceiver == null | 421 TypeMask abstractReceiverInMethod = abstractReceiver == null |
| 414 ? null | 422 ? null |
| 415 : abstractReceiver.isEmpty | 423 : abstractReceiver.isEmpty |
| 416 ? abstractReceiver | 424 ? abstractReceiver |
| 417 : abstractReceiver.nonNullable(); | 425 : abstractReceiver.nonNullable(); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 505 | 513 |
| 506 _inliner.cache.putPositive(target, callStructure, abstractReceiverInMethod, | 514 _inliner.cache.putPositive(target, callStructure, abstractReceiverInMethod, |
| 507 abstractArguments, function); | 515 abstractArguments, function); |
| 508 return finish(function); | 516 return finish(function); |
| 509 } | 517 } |
| 510 | 518 |
| 511 Primitive nullReceiverGuard(InvocationPrimitive invoke, | 519 Primitive nullReceiverGuard(InvocationPrimitive invoke, |
| 512 CpsFragment fragment, | 520 CpsFragment fragment, |
| 513 Primitive dartReceiver, | 521 Primitive dartReceiver, |
| 514 TypeMask abstractReceiver) { | 522 TypeMask abstractReceiver) { |
| 515 Selector selector = invoke is InvokeMethod ? invoke.selector : null; | 523 if (invoke is! InvokeMethod) return dartReceiver; |
| 524 InvokeMethod invokeMethod = invoke; | |
| 525 Selector selector = invokeMethod.selector; | |
| 516 if (typeSystem.isDefinitelyNum(abstractReceiver, allowNull: true)) { | 526 if (typeSystem.isDefinitelyNum(abstractReceiver, allowNull: true)) { |
| 517 Primitive condition = _fragment.letPrim( | 527 Primitive condition = _fragment.letPrim( |
| 518 new ApplyBuiltinOperator(BuiltinOperator.IsNotNumber, | 528 new ApplyBuiltinOperator(BuiltinOperator.IsNotNumber, |
| 519 <Primitive>[dartReceiver], | 529 <Primitive>[dartReceiver], |
| 520 invoke.sourceInformation)); | 530 invoke.sourceInformation)); |
| 521 condition.type = typeSystem.boolType; | 531 condition.type = typeSystem.boolType; |
| 522 Primitive check = _fragment.letPrim( | 532 Primitive check = _fragment.letPrim( |
| 523 new NullCheck.guarded( | 533 new ReceiverCheck.nullCheck(dartReceiver, selector, |
| 524 condition, dartReceiver, selector, invoke.sourceInformation)); | 534 invoke.sourceInformation, |
| 535 condition: condition)); | |
| 525 check.type = abstractReceiver.nonNullable(); | 536 check.type = abstractReceiver.nonNullable(); |
| 526 return check; | 537 return check; |
| 527 } | 538 } |
| 528 | 539 |
| 529 Primitive check = _fragment.letPrim( | 540 Primitive check = _fragment.letPrim( |
| 530 new NullCheck(dartReceiver, invoke.sourceInformation, | 541 new ReceiverCheck.nullCheck(dartReceiver, selector, |
| 531 selector: selector)); | 542 invoke.sourceInformation)); |
| 532 check.type = abstractReceiver.nonNullable(); | 543 check.type = abstractReceiver.nonNullable(); |
| 533 return check; | 544 return check; |
| 534 } | 545 } |
| 535 | 546 |
| 536 | 547 |
| 537 @override | 548 @override |
| 538 Primitive visitInvokeStatic(InvokeStatic node) { | 549 Primitive visitInvokeStatic(InvokeStatic node) { |
| 539 return tryInlining(node, node.target, null); | 550 return tryInlining(node, node.target, null); |
| 540 } | 551 } |
| 541 | 552 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 564 if (node.dartType is GenericType) { | 575 if (node.dartType is GenericType) { |
| 565 // We cannot inline a constructor invocation containing type arguments | 576 // We cannot inline a constructor invocation containing type arguments |
| 566 // because CreateInstance in the body does not know the type arguments. | 577 // because CreateInstance in the body does not know the type arguments. |
| 567 // We would incorrectly instantiate a class like A instead of A<B>. | 578 // We would incorrectly instantiate a class like A instead of A<B>. |
| 568 // TODO(kmillikin): try to fix this. | 579 // TODO(kmillikin): try to fix this. |
| 569 GenericType generic = node.dartType; | 580 GenericType generic = node.dartType; |
| 570 if (generic.typeArguments.any((DartType t) => !t.isDynamic)) return null; | 581 if (generic.typeArguments.any((DartType t) => !t.isDynamic)) return null; |
| 571 } | 582 } |
| 572 return tryInlining(node, node.target, null); | 583 return tryInlining(node, node.target, null); |
| 573 } | 584 } |
| 585 | |
| 586 bool isBlacklisted(FunctionElement target) { | |
| 587 ClassElement enclosingClass = target.enclosingClass; | |
| 588 if (target.isOperator && | |
| 589 (enclosingClass == backend.helpers.jsNumberClass || | |
| 590 enclosingClass == backend.helpers.jsDoubleClass || | |
| 591 enclosingClass == backend.helpers.jsIntClass)) { | |
| 592 // These should be handled by operator specialization. | |
| 593 return true; | |
| 594 } | |
| 595 return false; | |
| 596 } | |
| 574 } | 597 } |
| OLD | NEW |