Add flag to emit kernel immediately after invoking the CFE
This will be used initially to create the 3-way split in the compiler. Later
this will:
- include our transformation for super mixin calls
- remove the need to emit the .dill after global analysis
- eventually get replaced by a modular step that only builds a portion of the
.dill file.
Change-Id: Iebf2bd6d023716f04dc542ae9b2a85919159c4c0
Reviewed-on: https://dart-review.googlesource.com/c/85840
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Sigmund Cherem <sigmund@google.com>
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 982a2de..391cdd9 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -74,6 +74,7 @@
static const String readData = '--read-data';
static const String writeData = '--write-data';
+ static const String cfeOnly = '--cfe-only';
static const String serverMode = '--server-mode';
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 71225ec..85cc18e 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -168,8 +168,8 @@
enqueuer = backend.makeEnqueuer();
tasks = [
- kernelLoader =
- new KernelLoaderTask(options, provider, reporter, measurer),
+ kernelLoader = new KernelLoaderTask(
+ options, provider, _outputProvider, reporter, measurer),
kernelFrontEndTask,
globalInference = new GlobalTypeInferenceTask(this),
constants = backend.constantCompilerTask,
@@ -255,6 +255,7 @@
if (compilationFailed && !options.generateCodeWithCompileTimeErrors) {
return;
}
+ if (options.cfeOnly) return;
_mainLibraryUri = result.rootLibraryUri;
frontendStrategy.registerLoadedLibraries(result);
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index b97806b..dfab97f 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -263,6 +263,10 @@
compilationStrategy = CompilationStrategy.fromData;
}
+ void setCfeOnly(String argument) {
+ compilationStrategy = CompilationStrategy.toKernel;
+ }
+
void setWriteData(String argument) {
if (compilationStrategy == CompilationStrategy.fromData) {
fail("Cannot read and write serialized simultaneously.");
@@ -333,6 +337,7 @@
new OptionHandler('--libraries-spec=.+', setLibrarySpecificationUri),
new OptionHandler('${Flags.readData}|${Flags.readData}=.+', setReadData),
new OptionHandler('${Flags.writeData}|${Flags.writeData}=.+', setWriteData),
+ new OptionHandler(Flags.cfeOnly, setCfeOnly),
new OptionHandler('--out=.+|-o.*', setOutput, multipleArguments: true),
new OptionHandler('-O.*', setOptimizationLevel),
new OptionHandler(Flags.allowMockCompilation, ignoreOption),
@@ -492,6 +497,10 @@
case CompilationStrategy.direct:
out ??= currentDirectory.resolve('out.js');
break;
+ case CompilationStrategy.toKernel:
+ out ??= currentDirectory.resolve('out.dill');
+ options.add(Flags.cfeOnly);
+ break;
case CompilationStrategy.toData:
out ??= currentDirectory.resolve('out.dill');
writeDataUri ??= currentDirectory.resolve('$out.data');
@@ -544,6 +553,18 @@
}
}
break;
+ case CompilationStrategy.toKernel:
+ int dartCharactersRead = inputProvider.dartCharactersRead;
+ int dataBytesWritten = outputProvider.totalDataWritten;
+ print('Compiled '
+ '${_formatCharacterCount(dartCharactersRead)} characters Dart to '
+ '${_formatCharacterCount(dataBytesWritten)} kernel bytes in '
+ '${_formatDurationAsSeconds(wallclock.elapsed)} seconds');
+ String input = uriPathToNative(scriptName);
+ String dillOutput =
+ relativize(currentDirectory, out, Platform.isWindows);
+ print('Dart file ($input) compiled to ${dillOutput}.');
+ break;
case CompilationStrategy.toData:
int dartCharactersRead = inputProvider.dartCharactersRead;
int dataBytesWritten = outputProvider.totalDataWritten;
@@ -1007,4 +1028,4 @@
});
}
-enum CompilationStrategy { direct, toData, fromData }
+enum CompilationStrategy { direct, toKernel, toData, fromData }
diff --git a/pkg/compiler/lib/src/kernel/loader.dart b/pkg/compiler/lib/src/kernel/loader.dart
index 9df6d22..4d14f55 100644
--- a/pkg/compiler/lib/src/kernel/loader.dart
+++ b/pkg/compiler/lib/src/kernel/loader.dart
@@ -9,6 +9,7 @@
import 'package:front_end/src/fasta/kernel/utils.dart';
import 'package:kernel/ast.dart' as ir;
import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
+import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
import 'package:kernel/kernel.dart' hide LibraryDependency, Combinator;
@@ -18,6 +19,7 @@
import '../common/tasks.dart' show CompilerTask, Measurer;
import '../common.dart';
import '../options.dart';
+import '../util/sink_adapter.dart';
import 'front_end_adapter.dart';
import 'dart2js_target.dart' show Dart2jsTarget;
@@ -31,6 +33,7 @@
final DiagnosticReporter _reporter;
final api.CompilerInput _compilerInput;
+ final api.CompilerOutput _compilerOutput;
final CompilerOptions _options;
@@ -43,8 +46,8 @@
/// This is used for testing.
bool forceSerialization = false;
- KernelLoaderTask(
- this._options, this._compilerInput, this._reporter, Measurer measurer)
+ KernelLoaderTask(this._options, this._compilerInput, this._compilerOutput,
+ this._reporter, Measurer measurer)
: initializedCompilerState = _options.kernelInitializedCompilerState,
super(measurer);
@@ -78,6 +81,20 @@
resolvedUri);
}
if (component == null) return null;
+
+ if (_options.cfeOnly) {
+ measureSubtask('serialize dill', () {
+ _reporter.log('Writing dill to ${_options.outputUri}');
+ api.BinaryOutputSink dillOutput =
+ _compilerOutput.createBinarySink(_options.outputUri);
+ BinaryOutputSinkAdapter irSink =
+ new BinaryOutputSinkAdapter(dillOutput);
+ BinaryPrinter printer = new BinaryPrinter(irSink);
+ printer.writeComponentFile(component);
+ irSink.close();
+ });
+ }
+
if (forceSerialization) {
// TODO(johnniwinther): Remove this when #34942 is fixed.
List<int> data = serializeComponent(component);
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 0c05a18..ed6fcc8 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -62,6 +62,10 @@
/// If this is set, the compilation stops after type inference.
Uri writeDataUri;
+ /// Whether to run only the CFE and emit the generated kernel file in
+ /// [outputUri].
+ bool cfeOnly = false;
+
/// Resolved constant "environment" values passed to the compiler via the `-D`
/// flags.
Map<String, String> environment = const <String, String>{};
@@ -332,7 +336,8 @@
..verbose = _hasOption(options, Flags.verbose)
..showInternalProgress = _hasOption(options, Flags.progress)
..readDataUri = _extractUriOption(options, '${Flags.readData}=')
- ..writeDataUri = _extractUriOption(options, '${Flags.writeData}=');
+ ..writeDataUri = _extractUriOption(options, '${Flags.writeData}=')
+ ..cfeOnly = _hasOption(options, Flags.cfeOnly);
}
void validate() {
diff --git a/pkg/compiler/lib/src/serialization/strategies.dart b/pkg/compiler/lib/src/serialization/strategies.dart
index f4a03db..3b59676 100644
--- a/pkg/compiler/lib/src/serialization/strategies.dart
+++ b/pkg/compiler/lib/src/serialization/strategies.dart
@@ -10,7 +10,6 @@
import 'package:kernel/ast.dart' as ir;
import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
-import '../../compiler_new.dart' as api;
import '../diagnostics/diagnostic_listener.dart';
import '../environment.dart';
import '../js_model/js_world.dart';
@@ -18,6 +17,7 @@
import '../source_file_provider.dart';
import '../types/abstract_value_domain.dart';
import '../types/types.dart';
+import '../util/sink_adapter.dart';
import 'serialization.dart';
import 'task.dart';
@@ -130,19 +130,3 @@
abstractValueStrategy, component, source);
}
}
-
-class BinaryOutputSinkAdapter implements Sink<List<int>> {
- api.BinaryOutputSink output;
-
- BinaryOutputSinkAdapter(this.output);
-
- @override
- void add(List<int> data) {
- output.write(data);
- }
-
- @override
- void close() {
- output.close();
- }
-}
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index b2ce9e1..761d99e 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -16,7 +16,7 @@
import '../options.dart';
import '../types/abstract_value_domain.dart';
import '../types/types.dart';
-import 'strategies.dart';
+import '../util/sink_adapter.dart';
import 'serialization.dart';
void serializeGlobalTypeInferenceResults(
@@ -53,6 +53,9 @@
void serialize(GlobalTypeInferenceResults results) {
measureSubtask('serialize dill', () {
+ // TODO(sigmund): remove entirely: we will do this immediately as soon as
+ // we get the component in the kernel/loader.dart task once we refactor
+ // how we apply our modular kernel transformation for super mixin calls.
compiler.reporter.log('Writing dill to ${compiler.options.outputUri}');
api.BinaryOutputSink dillOutput =
compiler.outputProvider.createBinarySink(compiler.options.outputUri);
diff --git a/pkg/compiler/lib/src/util/sink_adapter.dart b/pkg/compiler/lib/src/util/sink_adapter.dart
new file mode 100644
index 0000000..685d611
--- /dev/null
+++ b/pkg/compiler/lib/src/util/sink_adapter.dart
@@ -0,0 +1,17 @@
+import '../../compiler_new.dart' as api;
+
+class BinaryOutputSinkAdapter implements Sink<List<int>> {
+ api.BinaryOutputSink output;
+
+ BinaryOutputSinkAdapter(this.output);
+
+ @override
+ void add(List<int> data) {
+ output.write(data);
+ }
+
+ @override
+ void close() {
+ output.close();
+ }
+}