Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(708)

Side by Side Diff: pkg/compiler/lib/src/cps_ir/inline.dart

Issue 1550463002: Better NullCheck for null-or-number (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 // Positive inlining result in the cache. 372 // Positive inlining result in the cache.
373 if (cachedResult is FunctionDefinition) { 373 if (cachedResult is FunctionDefinition) {
374 FunctionDefinition function = cachedResult; 374 FunctionDefinition function = cachedResult;
375 _fragment = new CpsFragment(invoke.sourceInformation); 375 _fragment = new CpsFragment(invoke.sourceInformation);
376 Primitive receiver = invoke.receiver?.definition; 376 Primitive receiver = invoke.receiver?.definition;
377 List<Primitive> arguments = 377 List<Primitive> arguments =
378 invoke.arguments.map((Reference ref) => ref.definition).toList(); 378 invoke.arguments.map((Reference ref) => ref.definition).toList();
379 // Add a null check to the inlined function body if necessary. The 379 // Add a null check to the inlined function body if necessary. The
380 // cached function body does not contain the null check. 380 // cached function body does not contain the null check.
381 if (dartReceiver != null && abstractReceiver.isNullable) { 381 if (dartReceiver != null && abstractReceiver.isNullable) {
382 Primitive check = 382 Primitive check = nullReceiverGuard(
383 _fragment.letPrim(new NullCheck(dartReceiver.definition, 383 invoke, _fragment, dartReceiver.definition, abstractReceiver);
384 invoke.sourceInformation));
385 check.type = abstractReceiver.nonNullable();
386 if (invoke.callingConvention == CallingConvention.Intercepted) { 384 if (invoke.callingConvention == CallingConvention.Intercepted) {
387 arguments[0] = check; 385 arguments[0] = check;
388 } else { 386 } else {
389 receiver = check; 387 receiver = check;
390 } 388 }
391 } 389 }
392 return _fragment.inlineFunction(function, receiver, arguments, 390 return _fragment.inlineFunction(function, receiver, arguments,
393 hint: invoke.hint); 391 hint: invoke.hint);
394 } 392 }
395 393
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 if (invoke.callingConvention == CallingConvention.Intercepted) { 446 if (invoke.callingConvention == CallingConvention.Intercepted) {
449 arguments[0] = check; 447 arguments[0] = check;
450 } else { 448 } else {
451 receiver = check; 449 receiver = check;
452 } 450 }
453 } 451 }
454 return _fragment.inlineFunction(function, receiver, arguments, 452 return _fragment.inlineFunction(function, receiver, arguments,
455 hint: invoke.hint); 453 hint: invoke.hint);
456 } 454 }
457 455
456 Primitive nullReceiverGuard(InvocationPrimitive invoke,
457 CpsFragment fragment,
458 Primitive dartReceiver,
459 TypeMask abstractReceiver) {
460 Selector selector = invoke is InvokeMethod ? invoke.selector : null;
Harry Terkelsen 2015/12/28 19:30:41 maybe move inside the "if" since that is the only
461 if (typeSystem.isDefinitelyNum(abstractReceiver, allowNull: true)) {
462 Primitive condition = _fragment.letPrim(
463 new ApplyBuiltinOperator(BuiltinOperator.IsNotNumber,
464 <Primitive>[dartReceiver],
465 invoke.sourceInformation));
466 condition.type = typeSystem.boolType;
467 Primitive check = _fragment.letPrim(
468 new NullCheck.guarded(
469 condition, dartReceiver, selector, invoke.sourceInformation));
470 check.type = abstractReceiver.nonNullable();
471 return check;
472 }
473
474 Primitive check = _fragment.letPrim(
475 new NullCheck(dartReceiver, invoke.sourceInformation));
476 check.type = abstractReceiver.nonNullable();
477 return check;
478 }
479
480
458 @override 481 @override
459 Primitive visitInvokeStatic(InvokeStatic node) { 482 Primitive visitInvokeStatic(InvokeStatic node) {
460 return tryInlining(node, node.target, null); 483 return tryInlining(node, node.target, null);
461 } 484 }
462 485
463 @override 486 @override
464 Primitive visitInvokeMethod(InvokeMethod node) { 487 Primitive visitInvokeMethod(InvokeMethod node) {
465 Primitive receiver = node.dartReceiver; 488 Primitive receiver = node.dartReceiver;
466 Element element = world.locateSingleElement(node.selector, receiver.type); 489 Element element = world.locateSingleElement(node.selector, receiver.type);
467 if (element == null || element is! FunctionElement) return null; 490 if (element == null || element is! FunctionElement) return null;
(...skipping 18 matching lines...) Expand all
486 // We cannot inline a constructor invocation containing type arguments 509 // We cannot inline a constructor invocation containing type arguments
487 // because CreateInstance in the body does not know the type arguments. 510 // because CreateInstance in the body does not know the type arguments.
488 // We would incorrectly instantiate a class like A instead of A<B>. 511 // We would incorrectly instantiate a class like A instead of A<B>.
489 // TODO(kmillikin): try to fix this. 512 // TODO(kmillikin): try to fix this.
490 GenericType generic = node.dartType; 513 GenericType generic = node.dartType;
491 if (generic.typeArguments.any((DartType t) => !t.isDynamic)) return null; 514 if (generic.typeArguments.any((DartType t) => !t.isDynamic)) return null;
492 } 515 }
493 return tryInlining(node, node.target, null); 516 return tryInlining(node, node.target, null);
494 } 517 }
495 } 518 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698