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

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

Issue 1743283002: dart2js cps: Use definitions by default, not references. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix long lines and use helpers that we already have Created 4 years, 9 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
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 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 if (argument != null && 230 if (argument != null &&
231 argument.definition.hasExactlyOneUse && 231 argument.definition.hasExactlyOneUse &&
232 parameter.hasNoUses) { 232 parameter.hasNoUses) {
233 --size; 233 --size;
234 } 234 }
235 } 235 }
236 236
237 static int sizeOf(InvocationPrimitive invoke, FunctionDefinition function) { 237 static int sizeOf(InvocationPrimitive invoke, FunctionDefinition function) {
238 SizeVisitor visitor = new SizeVisitor(); 238 SizeVisitor visitor = new SizeVisitor();
239 visitor.visit(function); 239 visitor.visit(function);
240 visitor.countArgument(invoke.receiver, function.thisParameter); 240 visitor.countArgument(invoke.receiverRef, function.thisParameter);
241 for (int i = 0; i < invoke.arguments.length; ++i) { 241 for (int i = 0; i < invoke.argumentRefs.length; ++i) {
242 visitor.countArgument(invoke.arguments[i], function.parameters[i]); 242 visitor.countArgument(invoke.argumentRefs[i], function.parameters[i]);
243 } 243 }
244 return visitor.size; 244 return visitor.size;
245 } 245 }
246 246
247 // Inlining a function incurs a cost equal to the number of primitives and 247 // Inlining a function incurs a cost equal to the number of primitives and
248 // non-jump tail expressions. 248 // non-jump tail expressions.
249 // TODO(kmillikin): Tune the size computation and size bound. 249 // TODO(kmillikin): Tune the size computation and size bound.
250 processLetPrim(LetPrim node) => ++size; 250 processLetPrim(LetPrim node) => ++size;
251 processLetMutable(LetMutable node) => ++size; 251 processLetMutable(LetMutable node) => ++size;
252 processBranch(Branch node) => ++size; 252 processBranch(Branch node) => ++size;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 } 329 }
330 330
331 TypeMask abstractType(Reference<Primitive> ref) { 331 TypeMask abstractType(Reference<Primitive> ref) {
332 return ref.definition.type ?? typeSystem.dynamicType; 332 return ref.definition.type ?? typeSystem.dynamicType;
333 } 333 }
334 334
335 /// Build the IR term for the function that adapts a call site targeting a 335 /// Build the IR term for the function that adapts a call site targeting a
336 /// function that takes optional arguments not passed at the call site. 336 /// function that takes optional arguments not passed at the call site.
337 FunctionDefinition buildAdapter(InvokeMethod node, FunctionElement target) { 337 FunctionDefinition buildAdapter(InvokeMethod node, FunctionElement target) {
338 Parameter thisParameter = new Parameter(new ThisParameterLocal(target)) 338 Parameter thisParameter = new Parameter(new ThisParameterLocal(target))
339 ..type = node.receiver.definition.type; 339 ..type = node.receiver.type;
340 List<Parameter> parameters = new List<Parameter>.generate( 340 List<Parameter> parameters = new List<Parameter>.generate(
341 node.arguments.length, 341 node.argumentRefs.length,
342 (int index) { 342 (int index) {
343 // TODO(kmillikin): Use a hint for the parameter names. 343 // TODO(kmillikin): Use a hint for the parameter names.
344 return new Parameter(null) 344 return new Parameter(null)
345 ..type = node.arguments[index].definition.type; 345 ..type = node.argument(index).type;
346 }); 346 });
347 Continuation returnContinuation = new Continuation.retrn(); 347 Continuation returnContinuation = new Continuation.retrn();
348 CpsFragment cps = new CpsFragment(); 348 CpsFragment cps = new CpsFragment();
349 349
350 FunctionSignature signature = target.functionSignature; 350 FunctionSignature signature = target.functionSignature;
351 int requiredParameterCount = signature.requiredParameterCount; 351 int requiredParameterCount = signature.requiredParameterCount;
352 if (node.callingConvention == CallingConvention.Intercepted || 352 if (node.callingConvention == CallingConvention.Intercepted ||
353 node.callingConvention == CallingConvention.DummyIntercepted) { 353 node.callingConvention == CallingConvention.DummyIntercepted) {
354 ++requiredParameterCount; 354 ++requiredParameterCount;
355 } 355 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 } 437 }
438 438
439 if (isBlacklisted(target)) return null; 439 if (isBlacklisted(target)) return null;
440 440
441 if (invoke.callingConvention == CallingConvention.OneShotIntercepted) { 441 if (invoke.callingConvention == CallingConvention.OneShotIntercepted) {
442 // One-shot interceptor calls with a known target are only inserted on 442 // One-shot interceptor calls with a known target are only inserted on
443 // uncommon code paths, so they should not be inlined. 443 // uncommon code paths, so they should not be inlined.
444 return null; 444 return null;
445 } 445 }
446 446
447 Reference<Primitive> dartReceiver = invoke.dartReceiverReference; 447 Reference<Primitive> dartReceiver = invoke.dartReceiverRef;
448 TypeMask abstractReceiver = 448 TypeMask abstractReceiver =
449 dartReceiver == null ? null : abstractType(dartReceiver); 449 dartReceiver == null ? null : abstractType(dartReceiver);
450 // The receiver is non-null in a method body, unless the receiver is known 450 // The receiver is non-null in a method body, unless the receiver is known
451 // to be `null` (isEmpty covers `null` and unreachable). 451 // to be `null` (isEmpty covers `null` and unreachable).
452 TypeMask abstractReceiverInMethod = abstractReceiver == null 452 TypeMask abstractReceiverInMethod = abstractReceiver == null
453 ? null 453 ? null
454 : abstractReceiver.isEmpty 454 : abstractReceiver.isEmpty
455 ? abstractReceiver 455 ? abstractReceiver
456 : abstractReceiver.nonNullable(); 456 : abstractReceiver.nonNullable();
457 List<TypeMask> abstractArguments = 457 List<TypeMask> abstractArguments =
458 invoke.arguments.map(abstractType).toList(); 458 invoke.argumentRefs.map(abstractType).toList();
459 var cachedResult = _inliner.cache.get(target, callStructure, 459 var cachedResult = _inliner.cache.get(target, callStructure,
460 abstractReceiverInMethod, 460 abstractReceiverInMethod,
461 abstractArguments); 461 abstractArguments);
462 462
463 // Negative inlining result in the cache. 463 // Negative inlining result in the cache.
464 if (cachedResult == InliningCache.NO_INLINE) return null; 464 if (cachedResult == InliningCache.NO_INLINE) return null;
465 465
466 Primitive finish(FunctionDefinition function) { 466 Primitive finish(FunctionDefinition function) {
467 _fragment = new CpsFragment(invoke.sourceInformation); 467 _fragment = new CpsFragment(invoke.sourceInformation);
468 Primitive receiver = invoke.receiver?.definition; 468 Primitive receiver = invoke.receiver;
469 List<Primitive> arguments = 469 List<Primitive> arguments = invoke.arguments.toList();
470 invoke.arguments.map((Reference ref) => ref.definition).toList();
471 // Add a null check to the inlined function body if necessary. The 470 // Add a null check to the inlined function body if necessary. The
472 // cached function body does not contain the null check. 471 // cached function body does not contain the null check.
473 if (dartReceiver != null && abstractReceiver.isNullable) { 472 if (dartReceiver != null && abstractReceiver.isNullable) {
474 Primitive check = nullReceiverGuard( 473 Primitive check = nullReceiverGuard(
475 invoke, _fragment, dartReceiver.definition, abstractReceiver); 474 invoke, _fragment, dartReceiver.definition, abstractReceiver);
476 if (invoke.callingConvention == CallingConvention.Intercepted) { 475 if (invoke.callingConvention == CallingConvention.Intercepted) {
477 arguments[0] = check; 476 arguments[0] = check;
478 } else { 477 } else {
479 receiver = check; 478 receiver = check;
480 } 479 }
(...skipping 30 matching lines...) Expand all
511 return doNotInline(); 510 return doNotInline();
512 } else { 511 } else {
513 function = buildAdapter(invoke, target); 512 function = buildAdapter(invoke, target);
514 } 513 }
515 } else { 514 } else {
516 function = compileToCpsIr(target); 515 function = compileToCpsIr(target);
517 void setValue(Variable variable, Reference<Primitive> value) { 516 void setValue(Variable variable, Reference<Primitive> value) {
518 variable.type = value.definition.type; 517 variable.type = value.definition.type;
519 } 518 }
520 if (invoke.callingConvention == CallingConvention.Intercepted) { 519 if (invoke.callingConvention == CallingConvention.Intercepted) {
521 setValue(function.thisParameter, invoke.receiver); 520 setValue(function.thisParameter, invoke.receiverRef);
522 function.parameters[0].type = abstractReceiverInMethod; 521 function.parameters[0].type = abstractReceiverInMethod;
523 for (int i = 1; i < invoke.arguments.length; ++i) { 522 for (int i = 1; i < invoke.argumentRefs.length; ++i) {
524 setValue(function.parameters[i], invoke.arguments[i]); 523 setValue(function.parameters[i], invoke.argumentRefs[i]);
525 } 524 }
526 } else { 525 } else {
527 if (invoke.receiver != null) { 526 if (invoke.receiverRef != null) {
528 function.thisParameter.type = abstractReceiverInMethod; 527 function.thisParameter.type = abstractReceiverInMethod;
529 } 528 }
530 for (int i = 0; i < invoke.arguments.length; ++i) { 529 for (int i = 0; i < invoke.argumentRefs.length; ++i) {
531 setValue(function.parameters[i], invoke.arguments[i]); 530 setValue(function.parameters[i], invoke.argumentRefs[i]);
532 } 531 }
533 } 532 }
534 optimizeBeforeInlining(function); 533 optimizeBeforeInlining(function);
535 } 534 }
536 535
537 // Inline calls in the body. 536 // Inline calls in the body.
538 _inliner.rewrite(function, callStructure); 537 _inliner.rewrite(function, callStructure);
539 538
540 // Compute the size. 539 // Compute the size.
541 // TODO(kmillikin): Tune the size bound. 540 // TODO(kmillikin): Tune the size bound.
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 (enclosingClass == backend.helpers.jsNumberClass || 619 (enclosingClass == backend.helpers.jsNumberClass ||
621 enclosingClass == backend.helpers.jsDoubleClass || 620 enclosingClass == backend.helpers.jsDoubleClass ||
622 enclosingClass == backend.helpers.jsIntClass)) { 621 enclosingClass == backend.helpers.jsIntClass)) {
623 // These should be handled by operator specialization. 622 // These should be handled by operator specialization.
624 return true; 623 return true;
625 } 624 }
626 if (target == backend.helpers.stringInterpolationHelper) return true; 625 if (target == backend.helpers.stringInterpolationHelper) return true;
627 return false; 626 return false;
628 } 627 }
629 } 628 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698