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

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

Issue 1608953002: dart2js: Turn the CPS inlining cache into a general compilation cache. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 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 | pkg/compiler/lib/src/js_backend/codegen/task.dart » ('j') | 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 /// During inlining a cache is used to remember inlining decisions for shared 79 /// During inlining a cache is used to remember inlining decisions for shared
80 /// parts of the call graph, to avoid exploring them more than once. 80 /// parts of the call graph, to avoid exploring them more than once.
81 /// 81 ///
82 /// The cache maps a tuple of (function element, call structure, 82 /// The cache maps a tuple of (function element, call structure,
83 /// abstract receiver, abstract arguments) to a boolean inlining decision and 83 /// abstract receiver, abstract arguments) to a boolean inlining decision and
84 /// an IR function definition if the decision is positive. 84 /// an IR function definition if the decision is positive.
85 class InliningCache { 85 class InliningCache {
86 static const int ABSENT = -1; 86 static const int ABSENT = -1;
87 static const int NO_INLINE = 0; 87 static const int NO_INLINE = 0;
88 88
89 final Map<ExecutableElement, FunctionDefinition> unoptimized =
90 <ExecutableElement, FunctionDefinition>{};
91
89 final Map<ExecutableElement, List<CacheEntry>> map = 92 final Map<ExecutableElement, List<CacheEntry>> map =
90 <ExecutableElement, List<CacheEntry>>{}; 93 <ExecutableElement, List<CacheEntry>>{};
91 94
92 // When function definitions are put into or removed from the cache, they are 95 // When function definitions are put into or removed from the cache, they are
93 // copied because the compiler passes will mutate them. 96 // copied because the compiler passes will mutate them.
94 final CopyingVisitor copier = new CopyingVisitor(); 97 final CopyingVisitor copier = new CopyingVisitor();
95 98
96 void _putInternal(ExecutableElement element, CallStructure callStructure, 99 void _putInternal(ExecutableElement element, CallStructure callStructure,
97 TypeMask receiver, 100 TypeMask receiver,
98 List<TypeMask> arguments, 101 List<TypeMask> arguments,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 FunctionDefinition function = copier.copy(entry.function); 140 FunctionDefinition function = copier.copy(entry.function);
138 ParentVisitor.setParents(function); 141 ParentVisitor.setParents(function);
139 return function; 142 return function;
140 } 143 }
141 return NO_INLINE; 144 return NO_INLINE;
142 } 145 }
143 } 146 }
144 } 147 }
145 return ABSENT; 148 return ABSENT;
146 } 149 }
150
151 /// Cache the unoptimized CPS term for a function.
152 ///
153 /// The unoptimized term should not have any inlining-context-specific
154 /// optimizations applied to it. It will be used to compile the
155 /// non-specialized version of the function.
156 void putUnoptimized(ExecutableElement element, FunctionDefinition function) {
157 unoptimized.putIfAbsent(element, () => copier.copy(function));
158 }
159
160 /// Look up the unoptimized CPS term for a function.
161 ///
162 /// The unoptimized term will not have any inlining-context-specific
163 /// optimizations applied to it. It can be used to compile the
164 /// non-specialized version of the function.
165 FunctionDefinition getUnoptimized(ExecutableElement element) {
166 FunctionDefinition function = unoptimized[element];
167 if (function != null) {
168 function = copier.copy(function);
169 ParentVisitor.setParents(function);
170 }
171 return function;
172 }
147 } 173 }
148 174
149 class Inliner implements Pass { 175 class Inliner implements Pass {
150 get passName => 'Inline calls'; 176 get passName => 'Inline calls';
151 177
152 final CpsFunctionCompiler functionCompiler; 178 final CpsFunctionCompiler functionCompiler;
153 179
154 final InliningCache cache = new InliningCache(); 180 final InliningCache cache = new InliningCache();
155 181
156 final List<StackEntry> stack = <StackEntry>[]; 182 final List<StackEntry> stack = <StackEntry>[];
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 462
437 FunctionDefinition function; 463 FunctionDefinition function;
438 if (callStructure != null && 464 if (callStructure != null &&
439 target.functionSignature.parameterCount != 465 target.functionSignature.parameterCount !=
440 callStructure.argumentCount) { 466 callStructure.argumentCount) {
441 // The argument count at the call site does not match the target's 467 // The argument count at the call site does not match the target's
442 // formal parameter count. Build the IR term for an adapter function 468 // formal parameter count. Build the IR term for an adapter function
443 // body. 469 // body.
444 function = buildAdapter(invoke, target); 470 function = buildAdapter(invoke, target);
445 } else { 471 } else {
446 function = _inliner.functionCompiler.compileToCpsIr(target); 472 function = compileToCpsIr(target);
447 void setValue(Variable variable, Reference<Primitive> value) { 473 void setValue(Variable variable, Reference<Primitive> value) {
448 variable.type = value.definition.type; 474 variable.type = value.definition.type;
449 } 475 }
450 if (invoke.callingConvention == CallingConvention.Intercepted) { 476 if (invoke.callingConvention == CallingConvention.Intercepted) {
451 setValue(function.thisParameter, invoke.receiver); 477 setValue(function.thisParameter, invoke.receiver);
452 function.parameters[0].type = abstractReceiverInMethod; 478 function.parameters[0].type = abstractReceiverInMethod;
453 for (int i = 1; i < invoke.arguments.length; ++i) { 479 for (int i = 1; i < invoke.arguments.length; ++i) {
454 setValue(function.parameters[i], invoke.arguments[i]); 480 setValue(function.parameters[i], invoke.arguments[i]);
455 } 481 }
456 } else { 482 } else {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 // We cannot inline a constructor invocation containing type arguments 560 // We cannot inline a constructor invocation containing type arguments
535 // because CreateInstance in the body does not know the type arguments. 561 // because CreateInstance in the body does not know the type arguments.
536 // We would incorrectly instantiate a class like A instead of A<B>. 562 // We would incorrectly instantiate a class like A instead of A<B>.
537 // TODO(kmillikin): try to fix this. 563 // TODO(kmillikin): try to fix this.
538 GenericType generic = node.dartType; 564 GenericType generic = node.dartType;
539 if (generic.typeArguments.any((DartType t) => !t.isDynamic)) return null; 565 if (generic.typeArguments.any((DartType t) => !t.isDynamic)) return null;
540 } 566 }
541 return tryInlining(node, node.target, null); 567 return tryInlining(node, node.target, null);
542 } 568 }
543 } 569 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/js_backend/codegen/task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698