[dart2wasm] Start using VM's dead code elimination pass

Tested: existing tests
Change-Id: Idff55466336d53e4c20ab5c18efa6a7358bccbc0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/354261
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Tess Strickland <sstrickl@google.com>
This commit is contained in:
Ömer Sinan Ağacan 2024-02-26 15:30:24 +00:00 committed by Commit Queue
parent b673fb57ed
commit 0ad3f77424
4 changed files with 52 additions and 10 deletions

View file

@ -25,13 +25,15 @@ import 'package:kernel/kernel.dart' show writeComponentToText;
import 'package:kernel/verifier.dart';
import 'package:vm/kernel_front_end.dart' show writeDepfile;
import 'package:vm/transformations/unreachable_code_elimination.dart'
as unreachable_code_elimination;
import 'package:vm/transformations/type_flow/transformer.dart' as globalTypeFlow
show transformComponent;
import 'package:vm/transformations/mixin_deduplication.dart'
as mixin_deduplication show transformComponent;
import 'package:dart2wasm/compiler_options.dart' as compiler;
import 'package:dart2wasm/constant_evaluator.dart';
import 'package:dart2wasm/js/runtime_generator.dart' as js;
import 'package:dart2wasm/record_class_generator.dart';
import 'package:dart2wasm/records.dart';
@ -110,6 +112,11 @@ Future<CompilerOutput?> compileToModule(compiler.WasmCompilerOptions options,
CoreTypes coreTypes = compilerResult.coreTypes!;
ClassHierarchy classHierarchy = compilerResult.classHierarchy!;
ConstantEvaluator constantEvaluator =
ConstantEvaluator(options, target, component, coreTypes, classHierarchy);
unreachable_code_elimination.transformComponent(target, component,
constantEvaluator, options.translatorOptions.enableAsserts);
if (options.dumpKernelAfterCfe != null) {
writeComponentToText(component, path: options.dumpKernelAfterCfe!);
}

View file

@ -0,0 +1,35 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:kernel/ast.dart';
import 'package:kernel/type_environment.dart';
import 'package:front_end/src/fasta/kernel/constant_evaluator.dart' as kernel;
import 'package:kernel/core_types.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:vm/transformations/vm_constant_evaluator.dart';
import 'package:dart2wasm/compiler_options.dart';
import 'package:dart2wasm/target.dart';
class ConstantEvaluator extends kernel.ConstantEvaluator
implements VMConstantEvaluator {
ConstantEvaluator(WasmCompilerOptions options, WasmTarget target,
Component component, CoreTypes coreTypes, ClassHierarchy classHierarchy)
: super(
target.dartLibrarySupport,
target.constantsBackend,
component,
options.environment,
TypeEnvironment(coreTypes, classHierarchy),
const kernel.SimpleErrorReporter(),
enableTripleShift: true,
enableAsserts: options.translatorOptions.enableAsserts,
errorOnUnevaluatedConstant: true,
evaluationMode: kernel.EvaluationMode.strong,
);
@override
bool shouldEvaluateMember(Member node) => false;
}

View file

@ -32,9 +32,6 @@ class SimpleUnreachableCodeElimination extends RemovingTransformer {
SimpleUnreachableCodeElimination(this.constantEvaluator,
{required this.enableAsserts, required this.soundNullSafety});
bool _shouldEvaluateMember(Member node) =>
constantEvaluator.hasTargetOS && constantEvaluator.isPlatformConst(node);
Never _throwPlatformConstError(Member node, String message) {
final uri = constantEvaluator.getFileUri(node);
final offset = constantEvaluator.getFileOffset(uri, node);
@ -65,7 +62,7 @@ class SimpleUnreachableCodeElimination extends RemovingTransformer {
TreeNode defaultMember(Member node, TreeNode? removalSentinel) {
_staticTypeContext =
StaticTypeContext(node, constantEvaluator.typeEnvironment);
if (_shouldEvaluateMember(node)) {
if (constantEvaluator.shouldEvaluateMember(node)) {
_checkPlatformConstMember(node);
// Create a StaticGet to ensure the member is evaluated at least once,
// and then replace the field initializer or getter body with the result.
@ -251,7 +248,7 @@ class SimpleUnreachableCodeElimination extends RemovingTransformer {
throw 'StaticGet from const field $target should be evaluated by front-end: $node';
}
if (!_shouldEvaluateMember(target)) {
if (!constantEvaluator.shouldEvaluateMember(target)) {
return super.visitStaticGet(node, removalSentinel);
}

View file

@ -100,21 +100,24 @@ class VMConstantEvaluator extends ConstantEvaluator {
evaluationMode: EvaluationMode.fromNnbdMode(nnbdMode));
}
bool get hasTargetOS => _targetOS != null;
bool get _hasTargetOS => _targetOS != null;
bool isPlatformConst(Member member) => _pragmaParser
bool _isPlatformConst(Member member) => _pragmaParser
.parsedPragmas<ParsedPlatformConstPragma>(member.annotations)
.isNotEmpty;
bool shouldEvaluateMember(Member node) =>
_hasTargetOS && _isPlatformConst(node);
@override
Constant visitStaticGet(StaticGet node) {
assert(hasTargetOS);
assert(_hasTargetOS);
final target = node.target;
// This visitor can be called recursively while evaluating an abstraction
// over the Platform getters and fields, so check that the visited node has
// an appropriately annotated target.
if (!isPlatformConst(target)) return super.visitStaticGet(node);
if (!_isPlatformConst(target)) return super.visitStaticGet(node);
visitedLibraries.add(target.enclosingLibrary);