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

Side by Side Diff: pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart

Issue 2938203003: Compute KernelClosureRepresentationInfo.variableIsUsedInTryOrSync (Closed)
Patch Set: Merge KernelClosureConversionTask and KernelClosureDataLookup Created 3 years, 6 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) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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 dart2js.kernel.backend_strategy; 5 library dart2js.kernel.backend_strategy;
6 6
7 import 'package:kernel/ast.dart' as ir; 7 import 'package:kernel/ast.dart' as ir;
8 8
9 import '../backend_strategy.dart'; 9 import '../backend_strategy.dart';
10 import '../closure.dart'; 10 import '../closure.dart';
(...skipping 15 matching lines...) Expand all
26 import '../options.dart'; 26 import '../options.dart';
27 import '../ssa/builder_kernel.dart'; 27 import '../ssa/builder_kernel.dart';
28 import '../ssa/nodes.dart'; 28 import '../ssa/nodes.dart';
29 import '../ssa/ssa.dart'; 29 import '../ssa/ssa.dart';
30 import '../ssa/types.dart'; 30 import '../ssa/types.dart';
31 import '../types/types.dart'; 31 import '../types/types.dart';
32 import '../universe/selector.dart'; 32 import '../universe/selector.dart';
33 import '../universe/world_builder.dart'; 33 import '../universe/world_builder.dart';
34 import '../universe/world_impact.dart'; 34 import '../universe/world_impact.dart';
35 import '../world.dart'; 35 import '../world.dart';
36 import 'closure.dart';
36 import 'element_map_impl.dart'; 37 import 'element_map_impl.dart';
37 import 'kernel_strategy.dart'; 38 import 'kernel_strategy.dart';
38 39
39 /// Backend strategy that uses the kernel elements as the backend model. 40 /// Backend strategy that uses the kernel elements as the backend model.
40 // TODO(johnniwinther): Replace this with a strategy based on the J-element 41 // TODO(johnniwinther): Replace this with a strategy based on the J-element
41 // model. 42 // model.
42 class KernelBackendStrategy implements BackendStrategy { 43 class KernelBackendStrategy implements BackendStrategy {
43 final Compiler _compiler; 44 final Compiler _compiler;
44 Sorter _sorter; 45 Sorter _sorter;
46 ClosureConversionTask _closureDataLookup;
47 GlobalLocalsMap _globalLocalsMap = new GlobalLocalsMap();
45 48
46 KernelBackendStrategy(this._compiler); 49 KernelBackendStrategy(this._compiler);
47 50
51 KernelToElementMap get _elementMap {
52 KernelFrontEndStrategy frontendStrategy = _compiler.frontendStrategy;
53 return frontendStrategy.elementMap;
54 }
55
48 @override 56 @override
49 ClosedWorldRefiner createClosedWorldRefiner(KernelClosedWorld closedWorld) { 57 ClosedWorldRefiner createClosedWorldRefiner(KernelClosedWorld closedWorld) {
50 return closedWorld; 58 return closedWorld;
51 } 59 }
52 60
53 @override 61 @override
54 Sorter get sorter { 62 Sorter get sorter {
55 if (_sorter == null) { 63 if (_sorter == null) {
56 KernelFrontEndStrategy frontendStrategy = _compiler.frontendStrategy; 64 KernelFrontEndStrategy frontendStrategy = _compiler.frontendStrategy;
57 _sorter = new KernelSorter(frontendStrategy.elementMap); 65 _sorter = new KernelSorter(frontendStrategy.elementMap);
58 } 66 }
59 return _sorter; 67 return _sorter;
60 } 68 }
61 69
62 @override 70 @override
63 ClosureConversionTask createClosureConversionTask(Compiler compiler) => 71 ClosureConversionTask get closureDataLookup =>
64 new KernelClosureConversionTask(compiler.measurer); 72 _closureDataLookup ??= new KernelClosureConversionTask(
73 _compiler.measurer, _elementMap, _globalLocalsMap);
65 74
66 @override 75 @override
67 WorkItemBuilder createCodegenWorkItemBuilder(ClosedWorld closedWorld) { 76 WorkItemBuilder createCodegenWorkItemBuilder(ClosedWorld closedWorld) {
68 return new KernelCodegenWorkItemBuilder(_compiler.backend, closedWorld); 77 return new KernelCodegenWorkItemBuilder(_compiler.backend, closedWorld);
69 } 78 }
70 79
71 @override 80 @override
72 CodegenWorldBuilder createCodegenWorldBuilder( 81 CodegenWorldBuilder createCodegenWorldBuilder(
73 NativeBasicData nativeBasicData, 82 NativeBasicData nativeBasicData,
74 ClosedWorld closedWorld, 83 ClosedWorld closedWorld,
75 SelectorConstraintsStrategy selectorConstraintsStrategy) { 84 SelectorConstraintsStrategy selectorConstraintsStrategy) {
76 KernelFrontEndStrategy frontendStrategy = _compiler.frontendStrategy;
77 return new KernelCodegenWorldBuilder( 85 return new KernelCodegenWorldBuilder(
78 frontendStrategy.elementMap, 86 _elementMap,
79 closedWorld.elementEnvironment, 87 closedWorld.elementEnvironment,
80 nativeBasicData, 88 nativeBasicData,
81 closedWorld, 89 closedWorld,
82 selectorConstraintsStrategy); 90 selectorConstraintsStrategy);
83 } 91 }
84 92
85 @override 93 @override
86 SsaBuilder createSsaBuilder(CompilerTask task, JavaScriptBackend backend, 94 SsaBuilder createSsaBuilder(CompilerTask task, JavaScriptBackend backend,
87 SourceInformationStrategy sourceInformationStrategy) { 95 SourceInformationStrategy sourceInformationStrategy) {
88 KernelFrontEndStrategy strategy = backend.compiler.frontendStrategy; 96 return new KernelSsaBuilder(
89 KernelToElementMap elementMap = strategy.elementMap; 97 task, backend.compiler, _elementMap, _globalLocalsMap);
90 return new KernelSsaBuilder(task, backend.compiler, elementMap);
91 } 98 }
92 99
93 @override 100 @override
94 SourceInformationStrategy get sourceInformationStrategy => 101 SourceInformationStrategy get sourceInformationStrategy =>
95 const JavaScriptSourceInformationStrategy(); 102 const JavaScriptSourceInformationStrategy();
96 } 103 }
97 104
98 class KernelCodegenWorkItemBuilder implements WorkItemBuilder { 105 class KernelCodegenWorkItemBuilder implements WorkItemBuilder {
99 final JavaScriptBackend _backend; 106 final JavaScriptBackend _backend;
100 final ClosedWorld _closedWorld; 107 final ClosedWorld _closedWorld;
(...skipping 30 matching lines...) Expand all
131 WorldImpact run() { 138 WorldImpact run() {
132 return _backend.codegen(this, _closedWorld); 139 return _backend.codegen(this, _closedWorld);
133 } 140 }
134 } 141 }
135 142
136 /// Task for building SSA from kernel IR loaded from .dill. 143 /// Task for building SSA from kernel IR loaded from .dill.
137 class KernelSsaBuilder implements SsaBuilder { 144 class KernelSsaBuilder implements SsaBuilder {
138 final CompilerTask task; 145 final CompilerTask task;
139 final Compiler _compiler; 146 final Compiler _compiler;
140 final KernelToElementMap _elementMap; 147 final KernelToElementMap _elementMap;
148 final GlobalLocalsMap _globalLocalsMap;
141 149
142 KernelSsaBuilder(this.task, this._compiler, this._elementMap); 150 KernelSsaBuilder(
151 this.task, this._compiler, this._elementMap, this._globalLocalsMap);
143 152
144 @override 153 @override
145 HGraph build(CodegenWorkItem work, ClosedWorld closedWorld) { 154 HGraph build(CodegenWorkItem work, ClosedWorld closedWorld) {
155 KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(work.element);
146 KernelSsaGraphBuilder builder = new KernelSsaGraphBuilder( 156 KernelSsaGraphBuilder builder = new KernelSsaGraphBuilder(
147 work.element, 157 work.element,
148 work.element.enclosingClass, 158 work.element.enclosingClass,
149 _elementMap.getMemberNode(work.element), 159 _elementMap.getMemberNode(work.element),
150 _compiler, 160 _compiler,
151 _elementMap, 161 _elementMap,
152 new KernelToTypeInferenceMapImpl(closedWorld), 162 new KernelToTypeInferenceMapImpl(closedWorld),
153 new KernelToLocalsMapImpl(work.element), 163 localsMap,
154 closedWorld, 164 closedWorld,
155 _compiler.codegenWorldBuilder, 165 _compiler.codegenWorldBuilder,
156 work.registry, 166 work.registry,
157 _compiler.closureDataLookup, 167 _compiler.backendStrategy.closureDataLookup,
158 // TODO(johnniwinther): Support these: 168 // TODO(johnniwinther): Support these:
159 const SourceInformationBuilder(), 169 const SourceInformationBuilder(),
160 null, // Function node used as capture scope id. 170 null, // Function node used as capture scope id.
161 targetIsConstructorBody: false); 171 targetIsConstructorBody: false);
162 return builder.build(); 172 return builder.build();
163 } 173 }
164 } 174 }
165 175
166 class KernelToTypeInferenceMapImpl implements KernelToTypeInferenceMap { 176 class KernelToTypeInferenceMapImpl implements KernelToTypeInferenceMap {
167 final ClosedWorld _closedWorld; 177 final ClosedWorld _closedWorld;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 ir.MethodInvocation invocation, ClosedWorld closedWorld) { 251 ir.MethodInvocation invocation, ClosedWorld closedWorld) {
242 return _closedWorld.commonMasks.dynamicType; 252 return _closedWorld.commonMasks.dynamicType;
243 } 253 }
244 254
245 @override 255 @override
246 TypeMask getReturnTypeOf(FunctionEntity function) { 256 TypeMask getReturnTypeOf(FunctionEntity function) {
247 return _closedWorld.commonMasks.dynamicType; 257 return _closedWorld.commonMasks.dynamicType;
248 } 258 }
249 } 259 }
250 260
261 class GlobalLocalsMap {
262 Map<MemberEntity, KernelToLocalsMap> _localsMaps =
263 <MemberEntity, KernelToLocalsMap>{};
264
265 KernelToLocalsMap getLocalsMap(MemberEntity member) {
266 return _localsMaps.putIfAbsent(
267 member, () => new KernelToLocalsMapImpl(member));
268 }
269 }
270
251 class KernelToLocalsMapImpl implements KernelToLocalsMap { 271 class KernelToLocalsMapImpl implements KernelToLocalsMap {
252 final List<MemberEntity> _members = <MemberEntity>[]; 272 final List<MemberEntity> _members = <MemberEntity>[];
253 Map<ir.VariableDeclaration, KLocal> _map = <ir.VariableDeclaration, KLocal>{}; 273 Map<ir.VariableDeclaration, KLocal> _map = <ir.VariableDeclaration, KLocal>{};
254 274
255 MemberEntity get currentMember => _members.last; 275 MemberEntity get currentMember => _members.last;
256 276
257 KernelToLocalsMapImpl(MemberEntity member) { 277 KernelToLocalsMapImpl(MemberEntity member) {
258 _members.add(member); 278 _members.add(member);
259 } 279 }
260 280
(...skipping 17 matching lines...) Expand all
278 @override 298 @override
279 Local getLocal(ir.VariableDeclaration node) { 299 Local getLocal(ir.VariableDeclaration node) {
280 return _map.putIfAbsent(node, () { 300 return _map.putIfAbsent(node, () {
281 return new KLocal(node.name, currentMember); 301 return new KLocal(node.name, currentMember);
282 }); 302 });
283 } 303 }
284 304
285 @override 305 @override
286 LoopClosureRepresentationInfo getClosureRepresentationInfoForLoop( 306 LoopClosureRepresentationInfo getClosureRepresentationInfoForLoop(
287 ClosureDataLookup closureLookup, ir.TreeNode node) { 307 ClosureDataLookup closureLookup, ir.TreeNode node) {
288 return const LoopClosureRepresentationInfo(); 308 return closureLookup.getClosureRepresentationInfoForLoop(node);
289 } 309 }
290 } 310 }
291 311
292 class KLocal implements Local { 312 class KLocal implements Local {
293 final String name; 313 final String name;
294 final MemberEntity memberContext; 314 final MemberEntity memberContext;
295 315
296 KLocal(this.name, this.memberContext); 316 KLocal(this.name, this.memberContext);
297 317
298 @override 318 @override
299 Entity get executableContext => memberContext; 319 Entity get executableContext => memberContext;
300 320
301 String toString() { 321 String toString() {
302 StringBuffer sb = new StringBuffer(); 322 StringBuffer sb = new StringBuffer();
303 sb.write('local('); 323 sb.write('local(');
304 if (memberContext.enclosingClass != null) { 324 if (memberContext.enclosingClass != null) {
305 sb.write(memberContext.enclosingClass.name); 325 sb.write(memberContext.enclosingClass.name);
306 sb.write('.'); 326 sb.write('.');
307 } 327 }
308 sb.write(memberContext.name); 328 sb.write(memberContext.name);
309 sb.write('#'); 329 sb.write('#');
310 sb.write(name); 330 sb.write(name);
311 sb.write(')'); 331 sb.write(')');
312 return sb.toString(); 332 return sb.toString();
313 } 333 }
314 } 334 }
315 335
316 /// Closure conversion code using our new Entity model. Closure conversion is
317 /// necessary because the semantics of closures are slightly different in Dart
318 /// than JavaScript. Closure conversion is separated out into two phases:
319 /// generation of a new (temporary) representation to store where variables need
320 /// to be hoisted/captured up at another level to re-write the closure, and then
321 /// the code generation phase where we generate elements and/or instructions to
322 /// represent this new code path.
323 ///
324 /// For a general explanation of how closure conversion works at a high level,
325 /// check out:
326 /// http://siek.blogspot.com/2012/07/essence-of-closure-conversion.html or
327 /// http://matt.might.net/articles/closure-conversion/.
328 class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> {
329 KernelClosureConversionTask(Measurer measurer) : super(measurer);
330
331 /// The combined steps of generating our intermediate representation of
332 /// closures that need to be rewritten and generating the element model.
333 /// Ultimately these two steps will be split apart with the second step
334 /// happening later in compilation just before codegen. These steps are
335 /// combined here currently to provide a consistent interface to the rest of
336 /// the compiler until we are ready to separate these phases.
337 @override
338 void convertClosures(Iterable<MemberEntity> processedEntities,
339 ClosedWorldRefiner closedWorldRefiner) {
340 // TODO(efortuna): implement.
341 }
342
343 @override
344 ClosureAnalysisInfo getClosureAnalysisInfo(ir.Node node) {
345 return const ClosureAnalysisInfo();
346 }
347
348 @override
349 LoopClosureRepresentationInfo getClosureRepresentationInfoForLoop(
350 ir.Node loopNode) {
351 return const LoopClosureRepresentationInfo();
352 }
353
354 @override
355 ClosureRepresentationInfo getClosureRepresentationInfo(Entity entity) {
356 if (entity is MemberEntity) {
357 ThisLocal thisLocal;
358 if (entity.isInstanceMember) {
359 thisLocal = new ThisLocal(entity);
360 }
361 return new ClosureClassMap(null, null, null, thisLocal);
362 }
363 return const ClosureRepresentationInfo();
364 }
365 }
366
367 class KernelSorter implements Sorter { 336 class KernelSorter implements Sorter {
368 final KernelToElementMapImpl elementMap; 337 final KernelToElementMapImpl elementMap;
369 338
370 KernelSorter(this.elementMap); 339 KernelSorter(this.elementMap);
371 340
372 int _compareLibraries(LibraryEntity a, LibraryEntity b) { 341 int _compareLibraries(LibraryEntity a, LibraryEntity b) {
373 return utils.compareLibrariesUris(a.canonicalUri, b.canonicalUri); 342 return utils.compareLibrariesUris(a.canonicalUri, b.canonicalUri);
374 } 343 }
375 344
376 int _compareNodes( 345 int _compareNodes(
(...skipping 27 matching lines...) Expand all
404 Iterable<ClassEntity> sortClasses(Iterable<ClassEntity> classes) { 373 Iterable<ClassEntity> sortClasses(Iterable<ClassEntity> classes) {
405 return classes.toList() 374 return classes.toList()
406 ..sort((ClassEntity a, ClassEntity b) { 375 ..sort((ClassEntity a, ClassEntity b) {
407 int r = _compareLibraries(a.library, b.library); 376 int r = _compareLibraries(a.library, b.library);
408 if (r != 0) return r; 377 if (r != 0) return r;
409 return _compareNodes( 378 return _compareNodes(
410 a, elementMap.getClassNode(a), b, elementMap.getClassNode(b)); 379 a, elementMap.getClassNode(a), b, elementMap.getClassNode(b));
411 }); 380 });
412 } 381 }
413 } 382 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698