blob: 2660bc5a108111d9e0c0b09e1f35da7b42dd841b [file] [log] [blame]
// Copyright (c) 2026, 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:cfg/ir/functions.dart';
import 'package:cfg/ir/ssa_computation.dart';
import 'package:cfg/passes/constant_propagation.dart';
import 'package:cfg/passes/control_flow_optimizations.dart';
import 'package:cfg/passes/pass.dart';
import 'package:cfg/passes/simplification.dart';
import 'package:cfg/passes/value_numbering.dart';
import 'package:native_compiler/back_end/arm64/code_generator.dart';
import 'package:native_compiler/back_end/arm64/constraints.dart';
import 'package:native_compiler/back_end/arm64/stack_frame.dart';
import 'package:native_compiler/back_end/arm64/stub_code_generator.dart';
import 'package:native_compiler/back_end/back_end_state.dart';
import 'package:native_compiler/back_end/code.dart';
import 'package:native_compiler/back_end/code_generator.dart';
import 'package:native_compiler/back_end/constraints.dart';
import 'package:native_compiler/back_end/regalloc_checker.dart';
import 'package:native_compiler/back_end/register_allocator.dart';
import 'package:native_compiler/back_end/stack_frame.dart';
import 'package:native_compiler/back_end/stub_code_generator.dart';
import 'package:native_compiler/passes/lowering.dart';
import 'package:native_compiler/passes/reorder_blocks.dart';
import 'package:native_compiler/runtime/object_layout.dart';
import 'package:native_compiler/runtime/vm_defs.dart';
import 'package:native_compiler/snapshot/image_writer.dart';
import 'package:native_compiler/snapshot/macho/macho_image_writer.dart';
enum TargetCPU {
arm64;
static final String defaultName = arm64.name;
static final List<String> allowedNames = [for (final v in values) v.name];
static TargetCPU fromName(String name) => values.byName(name);
}
enum ImageFormat {
macho;
static final String defaultName = macho.name;
static final List<String> allowedNames = [for (final v in values) v.name];
static ImageFormat fromName(String name) => values.byName(name);
}
abstract base class Configuration {
final TargetCPU targetCPU;
final ImageFormat imageFormat;
final bool enableAsserts;
final String outputLibraryName;
Configuration(
this.targetCPU,
this.imageFormat, {
required this.enableAsserts,
required this.outputLibraryName,
});
VMOffsets get vmOffsets;
ObjectLayout get objectLayout;
Pipeline createPipeline(
CFunction function,
FunctionRegistry functionRegistry,
StubFactory stubFactory,
CodeConsumer consumeGeneratedCode,
);
Constraints createConstraints() => switch (targetCPU) {
TargetCPU.arm64 => Arm64Constraints(),
};
StackFrame createStackFrame(CFunction function) => switch (targetCPU) {
TargetCPU.arm64 => Arm64StackFrame(function),
};
CodeGenerator createCodeGenerator(BackEndState backEndState) =>
switch (targetCPU) {
TargetCPU.arm64 => Arm64CodeGenerator(backEndState),
};
StubFactory createStubFactory(CodeConsumer consumeGeneratedCode) =>
switch (targetCPU) {
TargetCPU.arm64 => Arm64StubFactory(vmOffsets, consumeGeneratedCode),
};
ImageWriter createImageWriter() => switch (imageFormat) {
ImageFormat.macho => MachoImageWriter(targetCPU, outputLibraryName),
};
}
final class DevelopmentCompilerConfiguration extends Configuration {
DevelopmentCompilerConfiguration(
super.targetCPU,
super.imageFormat, {
required super.enableAsserts,
required super.outputLibraryName,
});
@override
late final VMOffsets vmOffsets = switch (targetCPU) {
TargetCPU.arm64 => Arm64VMOffsets(),
};
@override
late final ObjectLayout objectLayout = switch (targetCPU) {
TargetCPU.arm64 => ObjectLayout(
vmOffsets,
wordSize: 8,
compressedWordSize: 8,
),
};
@override
Pipeline createPipeline(
CFunction function,
FunctionRegistry functionRegistry,
StubFactory stubFactory,
CodeConsumer consumeGeneratedCode,
) {
final backEndState = BackEndState();
backEndState.vmOffsets = vmOffsets;
backEndState.objectLayout = objectLayout;
backEndState.stubFactory = stubFactory;
backEndState.stackFrame = createStackFrame(function);
backEndState.consumeGeneratedCode = consumeGeneratedCode;
final constraints = createConstraints();
return Pipeline([
SSAComputation(),
ValueNumbering(simplification: Simplification()),
ConstantPropagation(),
ControlFlowOptimizations(),
Lowering(functionRegistry),
ReorderBlocks(backEndState),
LinearScanRegisterAllocator(backEndState, constraints),
RegisterAllocationChecker(backEndState, constraints),
createCodeGenerator(backEndState),
]);
}
}