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

Side by Side Diff: pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart

Issue 2349163003: Move towards using WorldImpact for codegen (Closed)
Patch Set: Reinsert missing features uses. Created 4 years, 2 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 /// Analysis to determine how to generate code for `LookupMap`s. 5 /// Analysis to determine how to generate code for `LookupMap`s.
6 library compiler.src.js_backend.lookup_map_analysis; 6 library compiler.src.js_backend.lookup_map_analysis;
7 7
8 import 'package:pub_semver/pub_semver.dart'; 8 import 'package:pub_semver/pub_semver.dart';
9 9
10 import '../common.dart'; 10 import '../common.dart';
11 import '../common/registry.dart' show Registry; 11 import '../common/registry.dart' show Registry;
12 import '../compiler.dart' show Compiler; 12 import '../compiler.dart' show Compiler;
13 import '../constants/values.dart' 13 import '../constants/values.dart'
14 show 14 show
15 ConstantValue, 15 ConstantValue,
16 ConstructedConstantValue, 16 ConstructedConstantValue,
17 ListConstantValue, 17 ListConstantValue,
18 NullConstantValue, 18 NullConstantValue,
19 StringConstantValue, 19 StringConstantValue,
20 TypeConstantValue; 20 TypeConstantValue;
21 import '../dart_types.dart' show DartType; 21 import '../dart_types.dart' show DartType;
22 import '../dart_types.dart' show InterfaceType; 22 import '../dart_types.dart' show InterfaceType;
23 import '../elements/elements.dart' 23 import '../elements/elements.dart'
24 show ClassElement, FieldElement, LibraryElement, VariableElement; 24 show ClassElement, FieldElement, LibraryElement, VariableElement;
25 import '../enqueue.dart';
26 import '../universe/world_impact.dart'
27 show WorldImpact, StagedWorldImpactBuilder;
25 import 'js_backend.dart' show JavaScriptBackend; 28 import 'js_backend.dart' show JavaScriptBackend;
26 29
27 /// An analysis and optimization to remove unused entries from a `LookupMap`. 30 /// An analysis and optimization to remove unused entries from a `LookupMap`.
28 /// 31 ///
29 /// `LookupMaps` are defined in `package:lookup_map/lookup_map.dart`. They are 32 /// `LookupMaps` are defined in `package:lookup_map/lookup_map.dart`. They are
30 /// simple maps that contain constant expressions as keys, and that only support 33 /// simple maps that contain constant expressions as keys, and that only support
31 /// the lookup operation. 34 /// the lookup operation.
32 /// 35 ///
33 /// This analysis and optimization will tree-shake the contents of the maps by 36 /// This analysis and optimization will tree-shake the contents of the maps by
34 /// looking at the program and finding which keys are clearly unused. Not all 37 /// looking at the program and finding which keys are clearly unused. Not all
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 /// runtime. Technically if we limit lookup-maps to check for identical keys, 114 /// runtime. Technically if we limit lookup-maps to check for identical keys,
112 /// we could allow const instances of these types. However, we internally use 115 /// we could allow const instances of these types. However, we internally use
113 /// a hash map within lookup-maps today, so we need this restriction. 116 /// a hash map within lookup-maps today, so we need this restriction.
114 final _typesWithEquals = <ClassElement, bool>{}; 117 final _typesWithEquals = <ClassElement, bool>{};
115 118
116 /// Pending work to do if we discover that a new key is in use. For each key 119 /// Pending work to do if we discover that a new key is in use. For each key
117 /// that we haven't seen, we record the list of lookup-maps that contain an 120 /// that we haven't seen, we record the list of lookup-maps that contain an
118 /// entry with that key. 121 /// entry with that key.
119 final _pending = <ConstantValue, List<_LookupMapInfo>>{}; 122 final _pending = <ConstantValue, List<_LookupMapInfo>>{};
120 123
124 final StagedWorldImpactBuilder impactBuilder = new StagedWorldImpactBuilder();
125
121 /// Whether the backend is currently processing the codegen queue. 126 /// Whether the backend is currently processing the codegen queue.
122 bool _inCodegen = false; 127 bool _inCodegen = false;
123 128
124 LookupMapAnalysis(this.backend, this.reporter); 129 LookupMapAnalysis(this.backend, this.reporter);
125 130
131 void onQueueEmpty(Enqueuer enqueuer) {
132 if (enqueuer.isResolutionQueue) return;
133 enqueuer.applyImpact(null, impactBuilder.flush());
134 }
135
126 /// Whether this analysis and optimization is enabled. 136 /// Whether this analysis and optimization is enabled.
127 bool get _isEnabled { 137 bool get _isEnabled {
128 // `lookupMap==off` kept here to make it easy to test disabling this feature 138 // `lookupMap==off` kept here to make it easy to test disabling this feature
129 if (const String.fromEnvironment('lookupMap') == 'off') return false; 139 if (const String.fromEnvironment('lookupMap') == 'off') return false;
130 return typeLookupMapClass != null; 140 return typeLookupMapClass != null;
131 } 141 }
132 142
133 /// Initializes this analysis by providing the resolved library. This is 143 /// Initializes this analysis by providing the resolved library. This is
134 /// invoked during resolution when the `lookup_map` library is discovered. 144 /// invoked during resolution when the `lookup_map` library is discovered.
135 void init(LibraryElement library) { 145 void init(LibraryElement library) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 } 251 }
242 252
243 /// Callback from the enqueuer, invoked when [element] is instantiated. 253 /// Callback from the enqueuer, invoked when [element] is instantiated.
244 void registerInstantiatedClass(ClassElement element) { 254 void registerInstantiatedClass(ClassElement element) {
245 if (!_isEnabled || !_inCodegen) return; 255 if (!_isEnabled || !_inCodegen) return;
246 // TODO(sigmund): only add if .runtimeType is ever used 256 // TODO(sigmund): only add if .runtimeType is ever used
247 _addClassUse(element); 257 _addClassUse(element);
248 } 258 }
249 259
250 /// Callback from the enqueuer, invoked when [type] is instantiated. 260 /// Callback from the enqueuer, invoked when [type] is instantiated.
251 void registerInstantiatedType(InterfaceType type, Registry registry) { 261 void registerInstantiatedType(InterfaceType type) {
252 if (!_isEnabled || !_inCodegen) return; 262 if (!_isEnabled || !_inCodegen) return;
253 // TODO(sigmund): only add if .runtimeType is ever used 263 // TODO(sigmund): only add if .runtimeType is ever used
254 _addClassUse(type.element); 264 _addClassUse(type.element);
255 // TODO(sigmund): only do this when type-argument expressions are used? 265 // TODO(sigmund): only do this when type-argument expressions are used?
256 _addGenerics(type, registry); 266 _addGenerics(type);
257 } 267 }
258 268
259 /// Records generic type arguments in [type], in case they are retrieved and 269 /// Records generic type arguments in [type], in case they are retrieved and
260 /// returned using a type-argument expression. 270 /// returned using a type-argument expression.
261 void _addGenerics(InterfaceType type, Registry registry) { 271 void _addGenerics(InterfaceType type) {
262 if (!type.isGeneric) return; 272 if (!type.isGeneric) return;
263 for (var arg in type.typeArguments) { 273 for (var arg in type.typeArguments) {
264 if (arg is InterfaceType) { 274 if (arg is InterfaceType) {
265 _addClassUse(arg.element); 275 _addClassUse(arg.element);
266 // Note: this call was needed to generate correct code for 276 // Note: this call was needed to generate correct code for
267 // type_lookup_map/generic_type_test 277 // type_lookup_map/generic_type_test
268 // TODO(sigmund): can we get rid of this? 278 // TODO(sigmund): can we get rid of this?
269 backend.registerInstantiatedConstantType( 279 backend.computeImpactForInstantiatedConstantType(
270 backend.typeImplementation.rawType, registry); 280 backend.typeImplementation.rawType, impactBuilder);
271 _addGenerics(arg, registry); 281 _addGenerics(arg);
272 } 282 }
273 } 283 }
274 } 284 }
275 285
276 /// Callback from the codegen enqueuer, invoked when a constant (which is 286 /// Callback from the codegen enqueuer, invoked when a constant (which is
277 /// possibly a const key or a type literal) is used in the program. 287 /// possibly a const key or a type literal) is used in the program.
278 void registerTypeConstant(ClassElement element) { 288 void registerTypeConstant(ClassElement element) {
279 if (!_isEnabled || !_inCodegen) return; 289 if (!_isEnabled || !_inCodegen) return;
280 _addClassUse(element); 290 _addClassUse(element);
281 } 291 }
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 } 410 }
401 411
402 /// Marks that [key] has been seen, and thus, the corresponding entry in this 412 /// Marks that [key] has been seen, and thus, the corresponding entry in this
403 /// map should be considered reachable. 413 /// map should be considered reachable.
404 _markUsed(ConstantValue key) { 414 _markUsed(ConstantValue key) {
405 assert(!emitted); 415 assert(!emitted);
406 assert(unusedEntries.containsKey(key)); 416 assert(unusedEntries.containsKey(key));
407 assert(!usedEntries.containsKey(key)); 417 assert(!usedEntries.containsKey(key));
408 ConstantValue constant = unusedEntries.remove(key); 418 ConstantValue constant = unusedEntries.remove(key);
409 usedEntries[key] = constant; 419 usedEntries[key] = constant;
410 analysis.backend.registerCompileTimeConstant( 420 analysis.backend.computeImpactForCompileTimeConstant(
411 constant, analysis.backend.compiler.globalDependencies); 421 constant, analysis.impactBuilder, false);
412 } 422 }
413 423
414 /// Restores [original] to contain all of the entries marked as possibly used. 424 /// Restores [original] to contain all of the entries marked as possibly used.
415 void _prepareForEmission() { 425 void _prepareForEmission() {
416 ListConstantValue originalEntries = original.fields[analysis.entriesField]; 426 ListConstantValue originalEntries = original.fields[analysis.entriesField];
417 DartType listType = originalEntries.type; 427 DartType listType = originalEntries.type;
418 List<ConstantValue> keyValuePairs = <ConstantValue>[]; 428 List<ConstantValue> keyValuePairs = <ConstantValue>[];
419 usedEntries.forEach((key, value) { 429 usedEntries.forEach((key, value) {
420 keyValuePairs.add(key); 430 keyValuePairs.add(key);
421 keyValuePairs.add(value); 431 keyValuePairs.add(value);
422 }); 432 });
423 433
424 // Note: we are restoring the entries here, see comment in [original]. 434 // Note: we are restoring the entries here, see comment in [original].
425 if (singlePair) { 435 if (singlePair) {
426 assert(keyValuePairs.length == 0 || keyValuePairs.length == 2); 436 assert(keyValuePairs.length == 0 || keyValuePairs.length == 2);
427 if (keyValuePairs.length == 2) { 437 if (keyValuePairs.length == 2) {
428 original.fields[analysis.keyField] = keyValuePairs[0]; 438 original.fields[analysis.keyField] = keyValuePairs[0];
429 original.fields[analysis.valueField] = keyValuePairs[1]; 439 original.fields[analysis.valueField] = keyValuePairs[1];
430 } 440 }
431 } else { 441 } else {
432 original.fields[analysis.entriesField] = 442 original.fields[analysis.entriesField] =
433 new ListConstantValue(listType, keyValuePairs); 443 new ListConstantValue(listType, keyValuePairs);
434 } 444 }
435 } 445 }
436 } 446 }
437 447
438 final _validLookupMapVersionConstraint = new VersionConstraint.parse('^0.0.1'); 448 final _validLookupMapVersionConstraint = new VersionConstraint.parse('^0.0.1');
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/js_interop_analysis.dart ('k') | pkg/compiler/lib/src/js_backend/type_variable_handler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698