[pkg/vm] Consolidate kernel compilation options to an object

TEST=ci

Change-Id: Ic9a8801bff140b1393decde61917e8c61ab1945d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/370721
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
This commit is contained in:
Alexander Markov 2024-06-10 22:56:50 +00:00 committed by Commit Queue
parent 31a4bb7f60
commit 6ab01427bd
8 changed files with 150 additions and 149 deletions

View file

@ -658,22 +658,25 @@ class FrontendCompiler implements CompilerInterface {
];
}
results = await _runWithPrintRedirection(() => compileToKernel(
_mainSource, compilerOptions,
additionalSources: _additionalSources,
nativeAssets: _nativeAssets,
includePlatform: options['link-platform'],
deleteToStringPackageUris: options['delete-tostring-package-uri'],
keepClassNamesImplementing: options['keep-class-names-implementing'],
aot: options['aot'],
targetOS: options['target-os'],
useGlobalTypeFlowAnalysis: options['tfa'],
useRapidTypeAnalysis: options['rta'],
environmentDefines: environmentDefines,
enableAsserts: options['enable-asserts'],
useProtobufTreeShakerV2: options['protobuf-tree-shaker-v2'],
minimalKernel: options['minimal-kernel'],
treeShakeWriteOnlyFields: options['tree-shake-write-only-fields'],
fromDillFile: options['from-dill']));
new KernelCompilationArguments(
source: _mainSource,
options: compilerOptions,
additionalSources: _additionalSources,
nativeAssets: _nativeAssets,
includePlatform: options['link-platform'],
deleteToStringPackageUris: options['delete-tostring-package-uri'],
keepClassNamesImplementing:
options['keep-class-names-implementing'],
aot: options['aot'],
targetOS: options['target-os'],
useGlobalTypeFlowAnalysis: options['tfa'],
useRapidTypeAnalysis: options['rta'],
environmentDefines: environmentDefines,
enableAsserts: options['enable-asserts'],
useProtobufTreeShakerV2: options['protobuf-tree-shaker-v2'],
minimalKernel: options['minimal-kernel'],
treeShakeWriteOnlyFields: options['tree-shake-write-only-fields'],
fromDillFile: options['from-dill'])));
}
if (results!.component != null) {
transformer?.transform(results.component!);
@ -776,13 +779,11 @@ class FrontendCompiler implements CompilerInterface {
return;
}
final KernelCompilationResults results =
await _runWithPrintRedirection(() => compileToKernel(
null,
_compilerOptions,
final KernelCompilationResults results = await _runWithPrintRedirection(
() => compileToKernel(new KernelCompilationArguments(
options: _compilerOptions,
nativeAssets: _nativeAssets,
environmentDefines: {},
));
)));
_nativeAssetsLibrary = results.nativeAssetsLibrary;
}

View file

@ -129,11 +129,10 @@ class _Client {
final String uriStr = arguments.required<String>('uri');
final vm.KernelCompilationResults compilationResults =
await vm.compileToKernel(
Uri.parse(uriStr),
compilerOptions,
environmentDefines: {},
);
await vm.compileToKernel(new vm.KernelCompilationArguments(
source: Uri.parse(uriStr),
options: compilerOptions,
));
return _serializeComponentWithoutPlatform(
compilationResults.component!,

View file

@ -33,7 +33,7 @@ import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/kernel.dart';
import 'package:kernel/target/targets.dart' show TargetFlags, getTarget;
import 'package:vm/kernel_front_end.dart'
show runGlobalTransformations, ErrorDetector;
show runGlobalTransformations, ErrorDetector, KernelCompilationArguments;
import 'package:vm/modular/target/install.dart' show installAdditionalTargets;
import 'package:vm/transformations/type_flow/transformer.dart' as globalTypeFlow
show transformComponent;
@ -116,18 +116,15 @@ Future main(List<String> args) async {
// The [component] is treeshaken and has TFA annotations. Write output.
if (argResults['aot']) {
const bool useGlobalTypeFlowAnalysis = true;
const bool enableAsserts = false;
const bool useProtobufAwareTreeShakerV2 = true;
final nopErrorDetector = ErrorDetector();
runGlobalTransformations(
target,
component,
useGlobalTypeFlowAnalysis,
enableAsserts,
useProtobufAwareTreeShakerV2,
nopErrorDetector,
);
target,
component,
nopErrorDetector,
KernelCompilationArguments(
useGlobalTypeFlowAnalysis: true,
enableAsserts: false,
useProtobufTreeShakerV2: true));
} else {
globalTypeFlow.transformComponent(target, CoreTypes(component), component,
treeShakeProtobufs: true, treeShakeSignatures: false);

View file

@ -334,7 +334,9 @@ Future<int> runCompiler(ArgResults options, String usage) async {
return badUsageExitCode;
}
final results = await compileToKernel(mainUri, compilerOptions,
final results = await compileToKernel(KernelCompilationArguments(
source: mainUri,
options: compilerOptions,
additionalSources: additionalSources,
nativeAssets: nativeAssetsUri,
resourcesFile: resourcesFileUri,
@ -351,7 +353,7 @@ Future<int> runCompiler(ArgResults options, String usage) async {
minimalKernel: minimalKernel,
treeShakeWriteOnlyFields: treeShakeWriteOnlyFields,
targetOS: targetOS,
fromDillFile: fromDillFile);
fromDillFile: fromDillFile));
errorPrinter.printCompilationMessages();
@ -440,33 +442,61 @@ class KernelCompilationResults {
});
}
// Arguments for [compileToKernel].
class KernelCompilationArguments {
final Uri? source;
final CompilerOptions? options;
final List<Uri> additionalSources;
final Uri? nativeAssets;
final Uri? resourcesFile;
final bool includePlatform;
final List<String> deleteToStringPackageUris;
final List<String> keepClassNamesImplementing;
final bool aot;
final Uri? dynamicInterface;
final Map<String, String> environmentDefines; // Should be mutable.
final bool enableAsserts;
final bool useGlobalTypeFlowAnalysis;
final bool useRapidTypeAnalysis;
final bool treeShakeWriteOnlyFields;
final bool useProtobufTreeShakerV2;
final bool minimalKernel;
final String? targetOS;
final String? fromDillFile;
KernelCompilationArguments({
this.source,
this.options,
this.additionalSources = const <Uri>[],
this.nativeAssets,
this.resourcesFile,
this.includePlatform = false,
this.deleteToStringPackageUris = const <String>[],
this.keepClassNamesImplementing = const <String>[],
this.aot = false,
this.dynamicInterface,
Map<String, String>? environmentDefines,
this.enableAsserts = true,
this.useGlobalTypeFlowAnalysis = false,
this.useRapidTypeAnalysis = true,
this.treeShakeWriteOnlyFields = false,
this.useProtobufTreeShakerV2 = false,
this.minimalKernel = false,
this.targetOS,
this.fromDillFile,
}) : environmentDefines = environmentDefines ?? {};
}
/// Generates a kernel representation of the program whose main library is in
/// the given [source]. Intended for whole program (non-modular) compilation.
/// the given [args.source]. Intended for whole program (non-modular) compilation.
///
/// VM-specific replacement of [kernelForProgram].
///
/// Either [source], or [nativeAssets], or both must be non-null.
/// Either [arg.source], or [args.nativeAssets], or both must be non-null.
Future<KernelCompilationResults> compileToKernel(
Uri? source,
CompilerOptions options, {
List<Uri> additionalSources = const <Uri>[],
Uri? nativeAssets,
Uri? resourcesFile,
bool includePlatform = false,
List<String> deleteToStringPackageUris = const <String>[],
List<String> keepClassNamesImplementing = const <String>[],
Uri? dynamicInterface,
bool aot = false,
bool useGlobalTypeFlowAnalysis = false,
bool useRapidTypeAnalysis = true,
required Map<String, String> environmentDefines,
bool enableAsserts = true,
bool useProtobufTreeShakerV2 = false,
bool minimalKernel = false,
bool treeShakeWriteOnlyFields = false,
String? targetOS = null,
String? fromDillFile = null,
}) async {
KernelCompilationArguments args) async {
final options = args.options!;
// Replace error handler to detect if there are compilation errors.
final errorDetector =
new ErrorDetector(previousErrorHandler: options.onDiagnostic);
@ -474,8 +504,8 @@ Future<KernelCompilationResults> compileToKernel(
final nativeAssetsLibrary =
await NativeAssetsSynthesizer.synthesizeLibraryFromYamlFile(
nativeAssets, errorDetector);
if (source == null) {
args.nativeAssets, errorDetector);
if (args.source == null) {
return KernelCompilationResults.named(
nativeAssetsLibrary: nativeAssetsLibrary,
);
@ -483,15 +513,16 @@ Future<KernelCompilationResults> compileToKernel(
final target = options.target!;
options.environmentDefines =
target.updateEnvironmentDefines(environmentDefines);
target.updateEnvironmentDefines(args.environmentDefines);
CompilerResult? compilerResult;
final fromDillFile = args.fromDillFile;
if (fromDillFile != null) {
compilerResult =
await loadKernel(options.fileSystem, resolveInputUri(fromDillFile));
} else {
compilerResult = await kernelForProgram(source, options,
additionalSources: additionalSources);
compilerResult = await kernelForProgram(args.source!, options,
additionalSources: args.additionalSources);
}
final Component? component = compilerResult?.component;
@ -501,27 +532,18 @@ Future<KernelCompilationResults> compileToKernel(
Set<Library> loadedLibraries = createLoadedLibrariesSet(
compilerResult?.loadedComponents, compilerResult?.sdkComponent,
includePlatform: includePlatform);
includePlatform: args.includePlatform);
if (deleteToStringPackageUris.isNotEmpty && component != null) {
if (args.deleteToStringPackageUris.isNotEmpty && component != null) {
to_string_transformer.transformComponent(
component, deleteToStringPackageUris);
component, args.deleteToStringPackageUris);
}
// Run global transformations only if component is correct.
if ((aot || minimalKernel) && component != null) {
await runGlobalTransformations(target, component, useGlobalTypeFlowAnalysis,
enableAsserts, useProtobufTreeShakerV2, errorDetector,
environmentDefines: options.environmentDefines,
targetOS: targetOS,
minimalKernel: minimalKernel,
treeShakeWriteOnlyFields: treeShakeWriteOnlyFields,
useRapidTypeAnalysis: useRapidTypeAnalysis,
keepClassNamesImplementing: keepClassNamesImplementing,
dynamicInterface: dynamicInterface,
resourcesFile: resourcesFile);
if ((args.aot || args.minimalKernel) && component != null) {
await runGlobalTransformations(target, component, errorDetector, args);
if (minimalKernel) {
if (args.minimalKernel) {
// compiledSources is component.uriToSource.keys.
// Make a copy of compiledSources to detach it from
// component.uriToSource which is cleared below.
@ -570,26 +592,14 @@ Set<Library> createLoadedLibrariesSet(
return loadedLibraries;
}
Future runGlobalTransformations(
Target target,
Component component,
bool useGlobalTypeFlowAnalysis,
bool enableAsserts,
bool useProtobufTreeShakerV2,
ErrorDetector errorDetector,
{bool minimalKernel = false,
bool treeShakeWriteOnlyFields = false,
bool useRapidTypeAnalysis = true,
Map<String, String>? environmentDefines,
List<String>? keepClassNamesImplementing,
Uri? dynamicInterface,
String? targetOS,
Uri? resourcesFile}) async {
Future runGlobalTransformations(Target target, Component component,
ErrorDetector errorDetector, KernelCompilationArguments args) async {
assert(!target.flags.supportMirrors);
if (errorDetector.hasCompilationErrors) return;
final coreTypes = new CoreTypes(component);
final dynamicInterface = args.dynamicInterface;
if (dynamicInterface != null) {
dynamic_interface_annotator.annotateComponent(
File(dynamicInterface.toFilePath()).readAsStringSync(),
@ -608,21 +618,22 @@ Future runGlobalTransformations(
// Perform unreachable code elimination, which should be performed before
// type flow analysis so TFA won't take unreachable code into account.
final targetOS = args.targetOS;
final os = targetOS != null ? TargetOS.fromString(targetOS)! : null;
final evaluator = vm_constant_evaluator.VMConstantEvaluator.create(
target, component, os,
enableAsserts: enableAsserts,
environmentDefines: environmentDefines,
enableAsserts: args.enableAsserts,
environmentDefines: args.environmentDefines,
coreTypes: coreTypes);
unreachable_code_elimination.transformComponent(
target, component, evaluator, enableAsserts);
target, component, evaluator, args.enableAsserts);
if (useGlobalTypeFlowAnalysis) {
if (args.useGlobalTypeFlowAnalysis) {
globalTypeFlow.transformComponent(target, coreTypes, component,
treeShakeSignatures: !minimalKernel,
treeShakeWriteOnlyFields: treeShakeWriteOnlyFields,
treeShakeProtobufs: useProtobufTreeShakerV2,
useRapidTypeAnalysis: useRapidTypeAnalysis);
treeShakeSignatures: !args.minimalKernel,
treeShakeWriteOnlyFields: args.treeShakeWriteOnlyFields,
treeShakeProtobufs: args.useProtobufTreeShakerV2,
useRapidTypeAnalysis: args.useRapidTypeAnalysis);
} else {
devirtualization.transformComponent(coreTypes, component);
no_dynamic_invocations_annotator.transformComponent(component);
@ -638,10 +649,11 @@ Future runGlobalTransformations(
// We don't know yet whether gen_snapshot will want to do obfuscation, but if
// it does it will need the obfuscation prohibitions.
obfuscationProhibitions.transformComponent(
component, coreTypes, target, hierarchy, keepClassNamesImplementing);
component, coreTypes, target, hierarchy, args.keepClassNamesImplementing);
deferred_loading.transformComponent(component, coreTypes, target);
final resourcesFile = args.resourcesFile;
if (resourcesFile != null) {
resource_identifier.transformComponent(component, resourcesFile);
}

View file

@ -55,16 +55,14 @@ main() async {
verifyComponent(
vmTarget, VerificationStage.afterModularTransformations, component);
const useGlobalTypeFlowAnalysis = true;
const enableAsserts = false;
const useProtobufTreeShakerV2 = false;
await runGlobalTransformations(
vmTarget,
component,
useGlobalTypeFlowAnalysis,
enableAsserts,
useProtobufTreeShakerV2,
ErrorDetector());
ErrorDetector(),
KernelCompilationArguments(
useGlobalTypeFlowAnalysis: true,
enableAsserts: false,
useProtobufTreeShakerV2: false));
// Verify after running global transformations.
verifyComponent(

View file

@ -12,7 +12,7 @@ import 'package:kernel/target/targets.dart';
import 'package:kernel/verifier.dart';
import 'package:test/test.dart';
import 'package:vm/kernel_front_end.dart'
show runGlobalTransformations, ErrorDetector;
show runGlobalTransformations, ErrorDetector, KernelCompilationArguments;
import 'package:vm/modular/target/vm.dart' show VmTarget;
import 'package:vm/modular/transformations/ffi/native.dart'
show transformLibraries;
@ -57,19 +57,17 @@ runTestCaseAot(Uri source) async {
Component component = await compileTestCaseToKernelProgram(source,
target: target, experimentalFlags: []);
const bool useGlobalTypeFlowAnalysis = true;
const bool enableAsserts = false;
const bool useProtobufAwareTreeShakerV2 = true;
final nopErrorDetector = ErrorDetector();
runGlobalTransformations(
target,
component,
useGlobalTypeFlowAnalysis,
enableAsserts,
useProtobufAwareTreeShakerV2,
nopErrorDetector,
treeShakeWriteOnlyFields: true,
);
target,
component,
nopErrorDetector,
KernelCompilationArguments(
useGlobalTypeFlowAnalysis: true,
enableAsserts: false,
useProtobufTreeShakerV2: true,
treeShakeWriteOnlyFields: true,
));
verifyComponent(
target, VerificationStage.afterGlobalTransformations, component);

View file

@ -14,7 +14,7 @@ import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import 'package:vm/kernel_front_end.dart'
show runGlobalTransformations, ErrorDetector;
show runGlobalTransformations, ErrorDetector, KernelCompilationArguments;
import 'package:vm/modular/target/vm.dart' show VmTarget;
import 'package:vm/transformations/type_flow/transformer.dart' as globalTypeFlow
show transformComponent;
@ -79,18 +79,16 @@ Future<void> compileAOT(Uri source) async {
// Imitate the global transformations as run by the protobuf-aware tree shaker
// in AOT mode.
// Copied verbatim from pkg/vm/bin/protobuf_aware_treeshaker.dart.
const bool useGlobalTypeFlowAnalysis = true;
const bool enableAsserts = false;
const bool useProtobufAwareTreeShakerV2 = true;
final nopErrorDetector = ErrorDetector();
runGlobalTransformations(
target,
component,
useGlobalTypeFlowAnalysis,
enableAsserts,
useProtobufAwareTreeShakerV2,
nopErrorDetector,
);
target,
component,
nopErrorDetector,
KernelCompilationArguments(
useGlobalTypeFlowAnalysis: true,
enableAsserts: false,
useProtobufTreeShakerV2: true,
));
}
main() {

View file

@ -10,7 +10,7 @@ import 'package:kernel/target/targets.dart';
import 'package:kernel/verifier.dart';
import 'package:test/test.dart';
import 'package:vm/kernel_front_end.dart'
show runGlobalTransformations, ErrorDetector;
show runGlobalTransformations, ErrorDetector, KernelCompilationArguments;
import 'package:vm/modular/target/vm.dart' show VmTarget;
import '../common_test_utils.dart';
@ -33,9 +33,6 @@ void runTestCaseAot(Uri source, bool throws) async {
}
}
const bool useGlobalTypeFlowAnalysis = true;
const bool enableAsserts = false;
const bool useProtobufAwareTreeShakerV2 = true;
final nopErrorDetector = ErrorDetector();
var tempDir = Directory.systemTemp.createTempSync().path;
@ -44,15 +41,16 @@ void runTestCaseAot(Uri source, bool throws) async {
path: path.join(tempDir, 'resources.json'),
);
runGlobalTransformations(
target,
component,
useGlobalTypeFlowAnalysis,
enableAsserts,
useProtobufAwareTreeShakerV2,
nopErrorDetector,
treeShakeWriteOnlyFields: true,
resourcesFile: resourcesFile,
);
target,
component,
nopErrorDetector,
KernelCompilationArguments(
useGlobalTypeFlowAnalysis: true,
enableAsserts: false,
useProtobufTreeShakerV2: true,
treeShakeWriteOnlyFields: true,
resourcesFile: resourcesFile,
));
verifyComponent(
target,