Skip to content

Commit c2a63d7

Browse files
joshualittCommit Bot
authored andcommitted
[dart2js] Add a 'modular analysis' phase.
Change-Id: Idda666911a15e1726a15db65eb0cce2733851fdc Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/237633 Reviewed-by: Mark Zhou <markzipan@google.com> Commit-Queue: Joshua Litt <joshualitt@google.com>
1 parent f1a753a commit c2a63d7

File tree

8 files changed

+167
-109
lines changed

8 files changed

+167
-109
lines changed

pkg/compiler/lib/src/compiler.dart

Lines changed: 65 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import 'kernel/kernel_world.dart';
5050
import 'null_compiler_output.dart' show NullCompilerOutput;
5151
import 'options.dart' show CompilerOptions;
5252
import 'phase/load_kernel.dart' as load_kernel;
53+
import 'phase/modular_analysis.dart' as modular_analysis;
5354
import 'serialization/task.dart';
5455
import 'serialization/serialization.dart';
5556
import 'serialization/strategies.dart';
@@ -322,7 +323,11 @@ class Compiler {
322323
programSplitConstraintsData = constraintParser.read(programSplitJson);
323324
}
324325

325-
if (onlyPerformGlobalTypeInference) {
326+
if (options.cfeOnly) {
327+
await runLoadKernel();
328+
} else if (options.modularMode) {
329+
await runModularAnalysis();
330+
} else if (onlyPerformGlobalTypeInference) {
326331
ir.Component component =
327332
await serializationTask.deserializeComponentAndUpdateOptions();
328333
var closedWorldAndIndices =
@@ -357,48 +362,25 @@ class Compiler {
357362
await generateJavaScriptCode(globalTypeInferenceResults,
358363
indices: closedWorldAndIndices.indices);
359364
} else {
360-
final input = load_kernel.Input(options, provider, reporter,
361-
initializedCompilerState, forceSerializationForTesting);
362-
load_kernel.Output output =
363-
await loadKernelTask.measure(() async => load_kernel.run(input));
365+
load_kernel.Output output = await runLoadKernel();
364366
if (output == null || compilationFailed) return;
365-
reporter.log("Kernel load complete");
366-
if (retainDataForTesting) {
367-
componentForTesting = output.component;
368-
}
369367

370368
ir.Component component = output.component;
371369
List<Uri> libraries = output.libraries;
372370
frontendStrategy.registerLoadedLibraries(component, libraries);
373-
374-
if (options.modularMode) {
375-
await runModularAnalysis(component, output.moduleLibraries);
376-
} else {
377-
List<ModuleData> data;
378-
if (options.hasModularAnalysisInputs) {
379-
data = await serializationTask.deserializeModuleData(component);
380-
}
381-
frontendStrategy.registerModuleData(data);
382-
383-
// After we've deserialized modular data, we trim the component of any
384-
// unnecessary dependencies.
385-
// Note: It is critical we wait to trim the dill until after we've
386-
// deserialized modular data because some of this data may reference
387-
// 'trimmed' elements.
388-
if (options.fromDill) {
389-
if (options.dumpUnusedLibraries) {
390-
dumpUnusedLibraries(component, libraries);
391-
}
392-
if (options.entryUri != null) {
393-
component = trimComponent(component, libraries);
394-
}
395-
}
396-
if (options.cfeOnly) {
397-
await serializationTask.serializeComponent(component);
398-
} else {
399-
await compileFromKernel(output.rootLibraryUri, libraries);
400-
}
371+
List<ModuleData> data;
372+
if (options.hasModularAnalysisInputs) {
373+
data = await serializationTask.deserializeModuleData(component);
401374
}
375+
frontendStrategy.registerModuleData(data);
376+
377+
// After we've deserialized modular data, we trim the component of any
378+
// unnecessary dependencies.
379+
// Note: It is critical we wait to trim the dill until after we've
380+
// deserialized modular data because some of this data may reference
381+
// 'trimmed' elements.
382+
dumpUnusedLibrariesAndTrimComponent(component, libraries);
383+
await compileFromKernel(output.rootLibraryUri, libraries);
402384
}
403385
}
404386

@@ -498,19 +480,54 @@ class Compiler {
498480
return closedWorld;
499481
}
500482

501-
void runModularAnalysis(
502-
ir.Component component, Iterable<Uri> moduleLibraries) {
483+
Future<load_kernel.Output> runLoadKernel() async {
484+
final input = load_kernel.Input(options, provider, reporter,
485+
initializedCompilerState, forceSerializationForTesting);
486+
load_kernel.Output output =
487+
await loadKernelTask.measure(() async => load_kernel.run(input));
488+
if (output == null || compilationFailed) return null;
489+
reporter.log("Kernel load complete");
490+
if (retainDataForTesting) {
491+
componentForTesting = output.component;
492+
}
493+
494+
if (options.cfeOnly) {
495+
ir.Component component = output.component;
496+
dumpUnusedLibrariesAndTrimComponent(component, output.libraries);
497+
await serializationTask.serializeComponent(component);
498+
}
499+
return output;
500+
}
501+
502+
void dumpUnusedLibrariesAndTrimComponent(
503+
ir.Component component, List<Uri> libraries) {
504+
if (options.fromDill) {
505+
if (options.dumpUnusedLibraries) {
506+
dumpUnusedLibraries(component, libraries);
507+
}
508+
if (options.entryUri != null) {
509+
component = trimComponent(component, libraries);
510+
}
511+
}
512+
}
513+
514+
void runModularAnalysis() async {
515+
load_kernel.Output output = await runLoadKernel();
516+
if (output == null || compilationFailed) return;
517+
518+
ir.Component component = output.component;
519+
List<Uri> libraries = output.libraries;
520+
Set<Uri> moduleLibraries = output.moduleLibraries.toSet();
503521
_userCodeLocations
504522
.addAll(moduleLibraries.map((module) => CodeLocation(module)));
505-
selfTask.measureSubtask('runModularAnalysis', () {
506-
var included = moduleLibraries.toSet();
507-
var elementMap = frontendStrategy.elementMap;
508-
var moduleData = computeModuleData(
509-
component, included, options, reporter, environment, elementMap);
510-
if (compilationFailed) return;
511-
serializationTask.testModuleSerialization(moduleData, component);
512-
serializationTask.serializeModuleData(moduleData, component, included);
513-
});
523+
final input = modular_analysis.Input(
524+
options, reporter, environment, component, libraries, moduleLibraries);
525+
ModuleData moduleData = await selfTask.measureSubtask(
526+
'runModularAnalysis', () async => modular_analysis.run(input));
527+
if (compilationFailed) return;
528+
serializationTask.testModuleSerialization(moduleData, component);
529+
serializationTask.serializeModuleData(
530+
moduleData, component, moduleLibraries);
514531
}
515532

516533
GlobalTypeInferenceResults performGlobalTypeInference(

pkg/compiler/lib/src/ir/modular.dart

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ import 'package:front_end/src/api_unstable/dart2js.dart' as ir
1212
import '../diagnostics/diagnostic_listener.dart';
1313
import '../diagnostics/messages.dart';
1414
import '../diagnostics/source_span.dart';
15-
import '../kernel/element_map.dart';
16-
import '../environment.dart';
1715
import '../ir/impact_data.dart';
1816
import '../ir/static_type.dart';
1917
import '../js_backend/annotations.dart';
@@ -92,40 +90,6 @@ ModularMemberData computeModularMemberData(ir.Member node,
9290
return ModularMemberData(scopeModel, impactBuilderData);
9391
}
9492

95-
ModuleData computeModuleData(
96-
ir.Component component,
97-
Set<Uri> includedLibraries,
98-
CompilerOptions options,
99-
DiagnosticReporter reporter,
100-
Environment environment,
101-
KernelToElementMap elementMap) {
102-
var classHierarchy = elementMap.classHierarchy;
103-
var typeEnvironment = elementMap.typeEnvironment;
104-
var constantEvaluator = elementMap.constantEvaluator;
105-
var result = <ir.Member, ImpactBuilderData>{};
106-
void computeForMember(ir.Member member) {
107-
var scopeModel = ScopeModel.from(member, constantEvaluator);
108-
var annotations = processMemberAnnotations(
109-
options, reporter, member, computePragmaAnnotationDataFromIr(member));
110-
result[member] = computeModularMemberData(member,
111-
options: options,
112-
typeEnvironment: typeEnvironment,
113-
classHierarchy: classHierarchy,
114-
scopeModel: scopeModel,
115-
annotations: annotations)
116-
.impactBuilderData;
117-
}
118-
119-
for (var library in component.libraries) {
120-
if (!includedLibraries.contains(library.importUri)) continue;
121-
library.members.forEach(computeForMember);
122-
for (var cls in library.classes) {
123-
cls.members.forEach(computeForMember);
124-
}
125-
}
126-
return ModuleData(result);
127-
}
128-
12993
void reportLocatedMessage(DiagnosticReporter reporter,
13094
ir.LocatedMessage message, List<ir.LocatedMessage> context) {
13195
DiagnosticMessage diagnosticMessage =

pkg/compiler/lib/src/kernel/element_map_impl.dart

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ import '../js_backend/annotations.dart';
3838
import '../js_backend/namer.dart';
3939
import '../js_backend/native_data.dart';
4040
import '../js_model/locals.dart';
41-
import '../kernel/kernel_strategy.dart';
4241
import '../kernel/dart2js_target.dart';
4342
import '../native/behavior.dart';
4443
import '../options.dart';
@@ -58,6 +57,9 @@ class KernelToElementMap implements IrToElementMap {
5857
@override
5958
final DiagnosticReporter reporter;
6059
final Environment _environment;
60+
final NativeBasicDataBuilder nativeBasicDataBuilder =
61+
NativeBasicDataBuilder();
62+
NativeBasicData _nativeBasicData;
6163
KCommonElements _commonElements;
6264
KernelElementEnvironment _elementEnvironment;
6365
DartTypeConverter _typeConverter;
@@ -101,12 +103,10 @@ class KernelToElementMap implements IrToElementMap {
101103
final Map<ir.TreeNode, Local> localFunctionMap = {};
102104

103105
BehaviorBuilder _nativeBehaviorBuilder;
104-
final KernelFrontendStrategy _frontendStrategy;
105106

106107
Map<KMember, Map<ir.Expression, TypeMap>> typeMapsForTesting;
107108

108-
KernelToElementMap(
109-
this.reporter, this._environment, this._frontendStrategy, this.options) {
109+
KernelToElementMap(this.reporter, this._environment, this.options) {
110110
_elementEnvironment = KernelElementEnvironment(this);
111111
_typeConverter = DartTypeConverter(this);
112112
_types = KernelDartTypes(this, options);
@@ -1422,7 +1422,16 @@ class KernelToElementMap implements IrToElementMap {
14221422
}
14231423

14241424
/// NativeBasicData is need for computation of the default super class.
1425-
NativeBasicData get nativeBasicData => _frontendStrategy.nativeBasicData;
1425+
NativeBasicData get nativeBasicData {
1426+
if (_nativeBasicData == null) {
1427+
_nativeBasicData = nativeBasicDataBuilder.close(elementEnvironment);
1428+
assert(
1429+
_nativeBasicData != null,
1430+
failedAt(NO_LOCATION_SPANNABLE,
1431+
"NativeBasicData has not been computed yet."));
1432+
}
1433+
return _nativeBasicData;
1434+
}
14261435

14271436
/// Adds libraries in [component] to the set of libraries.
14281437
///

pkg/compiler/lib/src/kernel/kernel_strategy.dart

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ import 'native_basic_data.dart';
5050
/// Front end strategy that loads '.dill' files and builds a resolved element
5151
/// model from kernel IR nodes.
5252
class KernelFrontendStrategy {
53-
final NativeBasicDataBuilder nativeBasicDataBuilder =
54-
NativeBasicDataBuilder();
55-
NativeBasicData _nativeBasicData;
5653
final CompilerOptions _options;
5754
final CompilerTask _compilerTask;
5855
KernelToElementMap _elementMap;
@@ -84,7 +81,7 @@ class KernelFrontendStrategy {
8481
KernelFrontendStrategy(this._compilerTask, this._options,
8582
DiagnosticReporter reporter, env.Environment environment) {
8683
assert(_compilerTask != null);
87-
_elementMap = KernelToElementMap(reporter, environment, this, _options);
84+
_elementMap = KernelToElementMap(reporter, environment, _options);
8885
_modularStrategy = KernelModularStrategy(_compilerTask, _elementMap);
8986
_backendUsageBuilder = BackendUsageBuilderImpl(this);
9087
noSuchMethodRegistry =
@@ -135,6 +132,7 @@ class KernelFrontendStrategy {
135132
CompilerTask task, Compiler compiler) {
136133
RuntimeTypesNeedBuilder rtiNeedBuilder = _createRuntimeTypesNeedBuilder();
137134
BackendImpacts impacts = BackendImpacts(commonElements, compiler.options);
135+
final nativeBasicData = _elementMap.nativeBasicData;
138136
_nativeResolutionEnqueuer = NativeResolutionEnqueuer(
139137
compiler.options,
140138
elementEnvironment,
@@ -217,24 +215,13 @@ class KernelFrontendStrategy {
217215
annotationsData);
218216
}
219217

220-
NativeBasicData get nativeBasicData {
221-
if (_nativeBasicData == null) {
222-
_nativeBasicData = nativeBasicDataBuilder.close(elementEnvironment);
223-
assert(
224-
_nativeBasicData != null,
225-
failedAt(NO_LOCATION_SPANNABLE,
226-
"NativeBasicData has not been computed yet."));
227-
}
228-
return _nativeBasicData;
229-
}
230-
231218
/// Registers a set of loaded libraries with this strategy.
232219
void registerLoadedLibraries(ir.Component component, List<Uri> libraries) {
233220
_elementMap.addComponent(component);
234221
_irAnnotationData = processAnnotations(
235222
ModularCore(component, _elementMap.constantEvaluator));
236223
_annotationProcessor = KernelAnnotationProcessor(
237-
elementMap, nativeBasicDataBuilder, _irAnnotationData);
224+
elementMap, elementMap.nativeBasicDataBuilder, _irAnnotationData);
238225
for (Uri uri in libraries) {
239226
LibraryEntity library = elementEnvironment.lookupLibrary(uri);
240227
if (maybeEnableNative(library.canonicalUri)) {

pkg/compiler/lib/src/phase/load_kernel.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@ class Output {
5050
/// reachable from the [rootLibraryUri].
5151
///
5252
/// Note that [component] may contain some libraries that are excluded here.
53-
final Iterable<Uri> libraries;
53+
final List<Uri> libraries;
5454

5555
/// When running only dart2js modular analysis, returns the [Uri]s for
5656
/// libraries loaded in the input module.
5757
///
5858
/// This excludes other libraries reachable from them that were loaded as
5959
/// dependencies. The result of [moduleLibraries] is always a subset of
6060
/// [libraries].
61-
final Iterable<Uri> moduleLibraries;
61+
final List<Uri> moduleLibraries;
6262

6363
final fe.InitializedCompilerState initializedCompilerState;
6464

0 commit comments

Comments
 (0)