[modular_aot] Use primary constructors

Issue: https://github.com/dart-lang/sdk/issues/61635
Change-Id: I7476ec7e66edd958c66e31dabcd6ab8d818594e5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/509640
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Alexander Markov
2026-06-08 10:32:03 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent fd7d13ed8c
commit 28d7984e31
23 changed files with 203 additions and 437 deletions
+3 -13
View File
@@ -16,11 +16,7 @@ class _Mapping {
}
/// Wrapper for [ast.VariableContext].
final class AstContext implements Context {
final ast.VariableContext _node;
AstContext(this._node);
final class AstContext(final ast.VariableContext _node) implements Context {
@override
bool isCaptured({required bool enableAsserts}) =>
_node.isCaptured(enableAsserts: enableAsserts);
@@ -30,12 +26,8 @@ final class AstContext implements Context {
}
/// Wrapper for [ast.Scope].
final class AstScope implements Scope {
final _Mapping _mapping;
final ast.Scope _node;
AstScope(this._mapping, this._node);
final class AstScope(final _Mapping _mapping, final ast.Scope _node)
implements Scope {
@override
late final List<Context> contexts = [
for (final node in _node.contexts) _mapping.mapContext(node),
@@ -46,8 +38,6 @@ final class AstScope implements Scope {
final class AstScopes implements Scopes {
final _Mapping _mapping = _Mapping();
AstScopes();
@override
Scope? getScope(ast.TreeNode node) => switch (node) {
ast.ScopeProvider(:var scope?) => _mapping.mapScope(scope),
+5 -7
View File
@@ -1820,13 +1820,11 @@ class AstToIr extends ast.RecursiveVisitor {
}
void _translateClosure(ast.LocalFunction node, CType type) {
final closureFunction =
functionRegistry.getFunction(
function.member,
enclosingFunction: function,
localFunction: node,
)
as ClosureFunction;
final closureFunction = functionRegistry.getFunction(
function.member,
enclosingFunction: function,
localFunction: node,
) as ClosureFunction;
onLocalFunction(closureFunction);
final closureLayout = _computeClosureLayout(closureFunction);
+28 -41
View File
@@ -21,18 +21,17 @@ abstract class RecognizedCallMatcher {
}
/// Recognizes calls to binary [num] operations (except [num./]).
class BinaryNumOp implements RecognizedCallMatcher {
final BinaryIntOpcode intOp;
final BinaryDoubleOpcode doubleOp;
const BinaryNumOp(this.intOp, this.doubleOp);
class const BinaryNumOp(
final BinaryIntOpcode intOp,
final BinaryDoubleOpcode doubleOp,
) implements RecognizedCallMatcher {
/// Recognizes the following combinations of argument types:
///
/// int op int -> int
/// int op double -> double
/// double op int -> double
/// double op double -> double
@override
BuildIR? match(List<CType> args) {
switch (args) {
case [IntType(), IntType()]:
@@ -61,9 +60,8 @@ class BinaryNumOp implements RecognizedCallMatcher {
}
/// Recognizes calls to [num./].
class NumDiv implements RecognizedCallMatcher {
const NumDiv();
class const NumDiv() implements RecognizedCallMatcher {
@override
BuildIR? match(List<CType> args) {
switch (args) {
case [IntType(), IntType()]:
@@ -96,9 +94,8 @@ class NumDiv implements RecognizedCallMatcher {
}
/// Recognizes calls to [num.toDouble].
class NumToDouble implements RecognizedCallMatcher {
const NumToDouble();
class const NumToDouble() implements RecognizedCallMatcher {
@override
BuildIR? match(List<CType> args) {
switch (args) {
case [IntType()]:
@@ -115,9 +112,8 @@ class NumToDouble implements RecognizedCallMatcher {
}
/// Recognizes calls to [num.toInt].
class NumToInt implements RecognizedCallMatcher {
const NumToInt();
class const NumToInt() implements RecognizedCallMatcher {
@override
BuildIR? match(List<CType> args) {
switch (args) {
case [IntType()]:
@@ -134,12 +130,11 @@ class NumToInt implements RecognizedCallMatcher {
}
/// Recognizes calls to [num] comparisons.
class NumComparison implements RecognizedCallMatcher {
final ComparisonOpcode intOp;
final ComparisonOpcode doubleOp;
const NumComparison(this.intOp, this.doubleOp);
class const NumComparison(
final ComparisonOpcode intOp,
final ComparisonOpcode doubleOp,
) implements RecognizedCallMatcher {
@override
BuildIR? match(List<CType> args) {
switch (args) {
case [IntType(), IntType()]:
@@ -157,11 +152,9 @@ class NumComparison implements RecognizedCallMatcher {
}
/// Recognizes calls to binary [int] operations.
class BinaryIntOp implements RecognizedCallMatcher {
final BinaryIntOpcode op;
const BinaryIntOp(this.op);
class const BinaryIntOp(final BinaryIntOpcode op)
implements RecognizedCallMatcher {
@override
BuildIR? match(List<CType> args) {
assert(args[0] is IntType && args[1] is IntType);
return (FlowGraphBuilder builder) {
@@ -171,11 +164,9 @@ class BinaryIntOp implements RecognizedCallMatcher {
}
/// Recognizes calls to unary [int] operations.
class UnaryIntOp implements RecognizedCallMatcher {
final UnaryIntOpcode op;
const UnaryIntOp(this.op);
class const UnaryIntOp(final UnaryIntOpcode op)
implements RecognizedCallMatcher {
@override
BuildIR? match(List<CType> args) {
assert(args[0] is IntType);
return (FlowGraphBuilder builder) {
@@ -185,11 +176,9 @@ class UnaryIntOp implements RecognizedCallMatcher {
}
/// Recognizes calls to binary [double] operations.
class BinaryDoubleOp implements RecognizedCallMatcher {
final BinaryDoubleOpcode op;
const BinaryDoubleOp(this.op);
class const BinaryDoubleOp(final BinaryDoubleOpcode op)
implements RecognizedCallMatcher {
@override
BuildIR? match(List<CType> args) {
assert(args[0] is DoubleType);
switch (args[1]) {
@@ -209,11 +198,9 @@ class BinaryDoubleOp implements RecognizedCallMatcher {
}
/// Recognizes calls to unary [double] operations.
class UnaryDoubleOp implements RecognizedCallMatcher {
final UnaryDoubleOpcode op;
const UnaryDoubleOp(this.op);
class const UnaryDoubleOp(final UnaryDoubleOpcode op)
implements RecognizedCallMatcher {
@override
BuildIR? match(List<CType> args) {
assert(args[0] is DoubleType);
return (FlowGraphBuilder builder) {
+11 -32
View File
@@ -17,15 +17,11 @@ import 'package:kernel/type_environment.dart' show StaticTypeContext;
/// (e.g. constant type arguments) have dedicated subclasses of
/// [ast.AuxiliaryConstant].
extension type ConstantValue(ast.Constant constant) {
factory ConstantValue.fromInt(int value) =>
ConstantValue(ast.IntConstant(value));
factory ConstantValue.fromDouble(double value) =>
ConstantValue(ast.DoubleConstant(value));
factory ConstantValue.fromBool(bool value) =>
ConstantValue(ast.BoolConstant(value));
factory ConstantValue.fromNull() => ConstantValue(ast.NullConstant());
factory ConstantValue.fromString(String value) =>
ConstantValue(ast.StringConstant(value));
factory fromInt(int value) => ConstantValue(ast.IntConstant(value));
factory fromDouble(double value) => ConstantValue(ast.DoubleConstant(value));
factory fromBool(bool value) => ConstantValue(ast.BoolConstant(value));
factory fromNull() => ConstantValue(ast.NullConstant());
factory fromString(String value) => ConstantValue(ast.StringConstant(value));
int get intValue => switch (constant) {
ast.IntConstant(:var value) => value,
@@ -91,9 +87,7 @@ extension type ConstantValue(ast.Constant constant) {
/// Methods of this class return `null` when constant folding
/// cannot be performed (e.g. corresponding operation would
/// throw an exception at runtime).
class ConstantFolding {
const ConstantFolding();
class const ConstantFolding() {
ConstantValue comparison(
ComparisonOpcode op,
ConstantValue left,
@@ -272,11 +266,8 @@ class ConstantFolding {
}
/// Constant type arguments.
class TypeArgumentsConstant extends ast.AuxiliaryConstant {
final List<ast.DartType> types;
TypeArgumentsConstant(this.types);
class TypeArgumentsConstant(final List<ast.DartType> types)
extends ast.AuxiliaryConstant {
@override
void visitChildren(ast.Visitor v) {
ast.visitList(types, v);
@@ -307,8 +298,6 @@ class TypeArgumentsConstant extends ast.AuxiliaryConstant {
/// value of a late local variable, late or static field or
/// a value of an optional parameter which was not passed.
class SentinelConstant extends ast.AuxiliaryConstant {
SentinelConstant();
@override
void visitChildren(ast.Visitor v) {}
@@ -334,18 +323,13 @@ class SentinelConstant extends ast.AuxiliaryConstant {
///
/// Used by certain back-ends to distinguish raw unboxed values
/// (incompatible with Dart objects) from regular constants.
abstract base class UnboxedConstant extends ast.AuxiliaryConstant {
UnboxedConstant();
}
abstract base class UnboxedConstant extends ast.AuxiliaryConstant;
/// Unboxed int constant.
///
/// Used by certain back-ends to distinguish raw unboxed values
/// (incompatible with Dart objects) from regular constants.
final class UnboxedIntConstant extends UnboxedConstant {
final int value;
UnboxedIntConstant(this.value);
final class UnboxedIntConstant(final int value) extends UnboxedConstant {
@override
void visitChildren(ast.Visitor v) {}
@@ -373,10 +357,7 @@ final class UnboxedIntConstant extends UnboxedConstant {
///
/// Used by certain back-ends to distinguish raw unboxed values
/// (incompatible with Dart objects) from regular constants.
final class UnboxedDoubleConstant extends UnboxedConstant {
final double value;
UnboxedDoubleConstant(this.value);
final class UnboxedDoubleConstant(final double value) extends UnboxedConstant {
@override
void visitChildren(ast.Visitor v) {}
@@ -402,8 +383,6 @@ final class UnboxedDoubleConstant extends UnboxedConstant {
/// Synthetic constant representing undefined value of a local variable.
class UndefinedConstant extends ast.AuxiliaryConstant {
UndefinedConstant();
@override
void visitChildren(ast.Visitor v) {}
+10 -32
View File
@@ -485,11 +485,7 @@ final class _PhiIterator implements Iterator<Phi> {
}
/// Iterable over [Phi] instructions in the [JoinBlock].
final class _PhiIterable extends Iterable<Phi> {
final JoinBlock _block;
_PhiIterable(this._block);
final class _PhiIterable(final JoinBlock _block) extends Iterable<Phi> {
@override
Iterator<Phi> get iterator => _PhiIterator(_block);
}
@@ -624,7 +620,7 @@ final class Unreachable extends Instruction
R accept<R>(InstructionVisitor<R> v) => v.visitUnreachable(this);
}
enum ComparisonOpcode {
enum ComparisonOpcode(final String token) {
// Simple object pointer equality.
equal('=='),
notEqual('!='),
@@ -649,9 +645,6 @@ enum ComparisonOpcode {
doubleGreater('double >'),
doubleGreaterOrEqual('double >=');
final String token;
const ComparisonOpcode(this.token);
bool get isIntComparison => switch (this) {
intEqual ||
intNotEqual ||
@@ -1488,7 +1481,7 @@ final class Suspend extends Definition with CanThrow, HasSideEffects {
R accept<R>(InstructionVisitor<R> v) => v.visitSuspend(this);
}
enum BinaryIntOpcode {
enum BinaryIntOpcode(final String token) {
add('+'),
sub('-'),
mul('*'),
@@ -1502,9 +1495,6 @@ enum BinaryIntOpcode {
shiftRight('>>'),
unsignedShiftRight('>>>');
final String token;
const BinaryIntOpcode(this.token);
bool get isCommutative => switch (this) {
add || mul || bitOr || bitAnd || bitXor => true,
_ => false,
@@ -1550,15 +1540,12 @@ final class BinaryIntOp extends Definition with Pure, Idempotent {
R accept<R>(InstructionVisitor<R> v) => v.visitBinaryIntOp(this);
}
enum UnaryIntOpcode {
enum UnaryIntOpcode(final String token) {
neg('-'),
bitNot('~'),
toDouble('toDouble'),
abs('abs'),
sign('sign');
final String token;
const UnaryIntOpcode(this.token);
sign('sign')
}
/// Unary operation on the int operand.
@@ -1585,7 +1572,7 @@ final class UnaryIntOp extends Definition with NoThrow, Pure, Idempotent {
R accept<R>(InstructionVisitor<R> v) => v.visitUnaryIntOp(this);
}
enum BinaryDoubleOpcode {
enum BinaryDoubleOpcode(final String token) {
add('+'),
sub('-'),
mul('*'),
@@ -1594,9 +1581,6 @@ enum BinaryDoubleOpcode {
mod('%'),
rem('remainder');
final String token;
const BinaryDoubleOpcode(this.token);
bool get isCommutative => switch (this) {
add || mul => true,
_ => false,
@@ -1634,7 +1618,7 @@ final class BinaryDoubleOp extends Definition with NoThrow, Pure, Idempotent {
R accept<R>(InstructionVisitor<R> v) => v.visitBinaryDoubleOp(this);
}
enum UnaryDoubleOpcode {
enum UnaryDoubleOpcode(final String token) {
neg('-'),
abs('abs'),
sign('sign'),
@@ -1646,10 +1630,7 @@ enum UnaryDoubleOpcode {
roundToDouble('roundToDouble'),
floorToDouble('floorToDouble'),
ceilToDouble('ceilToDouble'),
truncateToDouble('truncateToDouble');
final String token;
const UnaryDoubleOpcode(this.token);
truncateToDouble('truncateToDouble')
}
/// Unary operation on the double operand.
@@ -1679,11 +1660,8 @@ final class UnaryDoubleOp extends Definition with NoThrow, Pure, Idempotent {
R accept<R>(InstructionVisitor<R> v) => v.visitUnaryDoubleOp(this);
}
enum UnaryBoolOpcode {
not('!');
final String token;
const UnaryBoolOpcode(this.token);
enum UnaryBoolOpcode(final String token) {
not('!')
}
/// Unary operation on the bool operand.
+16 -63
View File
@@ -53,9 +53,7 @@ enum TypeKind {
}
/// Base class for types used in the CFG IR.
sealed class CType {
const CType();
sealed class const CType() {
/// Create CFG IR type from Dart static type.
static CType fromStaticType(ast.DartType dartType) =>
GlobalContext.instance.astToIrTypes.translate(dartType);
@@ -94,11 +92,7 @@ sealed class CType {
}
/// Dart `int` type.
final class IntType extends CType {
final ast.DartType? _dartType;
const IntType([this._dartType]);
final class const IntType([final ast.DartType? _dartType]) extends CType {
@override
TypeKind get kind => TypeKind.intType;
@@ -123,11 +117,7 @@ final class IntType extends CType {
}
/// Dart `double` type.
final class DoubleType extends CType {
final ast.DartType? _dartType;
const DoubleType([this._dartType]);
final class const DoubleType([final ast.DartType? _dartType]) extends CType {
@override
TypeKind get kind => TypeKind.doubleType;
@@ -152,11 +142,7 @@ final class DoubleType extends CType {
}
/// Dart `bool` type.
final class BoolType extends CType {
final ast.DartType? _dartType;
const BoolType([this._dartType]);
final class const BoolType([final ast.DartType? _dartType]) extends CType {
@override
TypeKind get kind => TypeKind.boolType;
@@ -181,11 +167,7 @@ final class BoolType extends CType {
}
/// Dart `String` type.
final class StringType extends CType {
final ast.DartType? _dartType;
const StringType([this._dartType]);
final class const StringType([final ast.DartType? _dartType]) extends CType {
@override
TypeKind get kind => TypeKind.stringType;
@@ -267,11 +249,7 @@ final class RecordType extends CType {
}
/// Dart `Object` type.
final class ObjectType extends CType {
final ast.DartType? _dartType;
const ObjectType([this._dartType]);
final class const ObjectType([final ast.DartType? _dartType]) extends CType {
@override
TypeKind get kind => TypeKind.objectType;
@@ -296,9 +274,7 @@ final class ObjectType extends CType {
}
/// Dart `Null` type.
final class NullType extends CType {
const NullType();
final class const NullType() extends CType {
@override
TypeKind get kind => TypeKind.nullType;
@@ -322,9 +298,7 @@ final class NullType extends CType {
}
/// Dart `Never` type.
final class NeverType extends CType {
const NeverType();
final class const NeverType() extends CType {
@override
TypeKind get kind => TypeKind.neverType;
@@ -348,11 +322,7 @@ final class NeverType extends CType {
}
/// Dart top type such as `Object?`, `dynamic`, `void`, or `FutureOr` of those.
final class TopType extends CType {
final ast.DartType? _dartType;
const TopType([this._dartType]);
final class const TopType([final ast.DartType? _dartType]) extends CType {
@override
TypeKind get kind => TypeKind.top;
@@ -376,15 +346,10 @@ final class TopType extends CType {
}
/// Dart types not covered by the built-in types above.
final class StaticType extends CType {
final class StaticType(final ast.DartType dartType) extends CType {
@override
TypeKind get kind => TypeKind.otherDartType;
@override
final ast.DartType dartType;
StaticType(this.dartType);
@override
bool get isNullable => dartType.isPotentiallyNullable;
@@ -446,9 +411,7 @@ final class StaticType extends CType {
/// Base class for non-Dart types.
/// These types are used for instructions which do not yield Dart instances.
sealed class ExtendedType extends CType {
const ExtendedType();
sealed class const ExtendedType() extends CType {
@override
ast.DartType get dartType => throw ArgumentError(
'${runtimeType} does not have corresponding Dart type',
@@ -486,9 +449,7 @@ sealed class ExtendedType extends CType {
/// [NothingType] is different from the Dart `void` type. `void` means
/// 'the value can be anything, but you must not use the value', and is
/// represented with [TopType].
final class NothingType extends ExtendedType {
const NothingType();
final class const NothingType() extends ExtendedType {
@override
TypeKind get kind => TypeKind.nothing;
@@ -500,9 +461,7 @@ final class NothingType extends ExtendedType {
/// (represented with [SentinelConstant] value).
///
/// After checking, it can be casted to a regular Dart type.
final class LateValueType extends ExtendedType {
const LateValueType();
final class const LateValueType() extends ExtendedType {
@override
TypeKind get kind => TypeKind.lateValue;
@@ -511,9 +470,7 @@ final class LateValueType extends ExtendedType {
}
/// Type of [TypeParameters] instruction.
final class TypeParametersType extends ExtendedType {
const TypeParametersType();
final class const TypeParametersType() extends ExtendedType {
@override
TypeKind get kind => TypeKind.typeParameters;
@@ -522,9 +479,7 @@ final class TypeParametersType extends ExtendedType {
}
/// Type of [TypeArguments] instruction and [Constant] type arguments.
final class TypeArgumentsType extends ExtendedType {
const TypeArgumentsType();
final class const TypeArgumentsType() extends ExtendedType {
@override
TypeKind get kind => TypeKind.typeArguments;
@@ -533,9 +488,7 @@ final class TypeArgumentsType extends ExtendedType {
}
/// Type of [AllocateContext] instruction.
final class ContextType extends ExtendedType {
const ContextType();
final class const ContextType() extends ExtendedType {
@override
TypeKind get kind => TypeKind.context;
+1 -5
View File
@@ -124,11 +124,7 @@ extension type BitVector._(Int64List _bits) {
Iterable<int> get elements => _BitVectorIterable(this);
}
final class _BitVectorIterable extends Iterable<int> {
final BitVector _vector;
_BitVectorIterable(this._vector);
final class _BitVectorIterable(final BitVector _vector) extends Iterable<int> {
@override
Iterator<int> get iterator => _BitVectorIterator(_vector);
}
+1 -1
View File
@@ -4,7 +4,7 @@ description: CFG/SSA compiler IR and optimization passes.
publish_to: none
environment:
sdk: '^3.12.0-0'
sdk: '^3.13.0-0'
resolution: workspace
+25 -22
View File
@@ -68,9 +68,10 @@ void main() {
test('field getter', () {
final member = coreTypes.pragmaName;
final func =
functionRegistry.getFunction(member, isGetter: true)
as ImplicitFieldGetter;
final func = functionRegistry.getFunction(
member,
isGetter: true,
) as ImplicitFieldGetter;
expect(func.member, same(member));
expect(func.hasReceiverParameter, isTrue);
expect(func.hasClosureParameter, isFalse);
@@ -89,9 +90,10 @@ void main() {
'Error',
'_stackTrace',
);
final func =
functionRegistry.getFunction(member, isSetter: true)
as ImplicitFieldSetter;
final func = functionRegistry.getFunction(
member,
isSetter: true,
) as ImplicitFieldSetter;
expect(func.member, same(member));
expect(func.hasReceiverParameter, isTrue);
expect(func.hasClosureParameter, isFalse);
@@ -110,9 +112,10 @@ void main() {
test('field initializer', () {
final member = coreTypes.index.getField('dart:core', 'double', 'nan');
final func =
functionRegistry.getFunction(member, isInitializer: true)
as FieldInitializerFunction;
final func = functionRegistry.getFunction(
member,
isInitializer: true,
) as FieldInitializerFunction;
expect(func.member, same(member));
expect(func.hasReceiverParameter, isFalse);
expect(func.hasClosureParameter, isFalse);
@@ -168,9 +171,10 @@ void main() {
test('tear-off', () {
final member = coreTypes.index.getProcedure('dart:core', 'List', 'empty');
final func =
functionRegistry.getFunction(member, isTearOff: true)
as TearOffFunction;
final func = functionRegistry.getFunction(
member,
isTearOff: true,
) as TearOffFunction;
expect(func.member, same(member));
expect(func.hasReceiverParameter, isFalse);
expect(func.hasClosureParameter, isTrue);
@@ -196,13 +200,11 @@ void main() {
returnType: coreTypes.boolNonNullableRawType,
),
);
final func =
functionRegistry.getFunction(
member,
enclosingFunction: enclosingFunction,
localFunction: localFunction,
)
as LocalFunction;
final func = functionRegistry.getFunction(
member,
enclosingFunction: enclosingFunction,
localFunction: localFunction,
) as LocalFunction;
expect(func.member, same(member));
expect(func.localFunction, same(localFunction));
expect(func.hasReceiverParameter, isFalse);
@@ -221,9 +223,10 @@ void main() {
test('method-extractor', () {
final member = coreTypes.index.getProcedure('dart:core', 'List', 'add');
final func =
functionRegistry.getFunction(member, isMethodExtractor: true)
as MethodExtractor;
final func = functionRegistry.getFunction(
member,
isMethodExtractor: true,
) as MethodExtractor;
expect(func.member, same(member));
expect(func.hasReceiverParameter, isTrue);
expect(func.hasClosureParameter, isFalse);
+1 -7
View File
@@ -175,13 +175,7 @@ class CompileAndDumpIr extends RecursiveVisitor {
}
}
class Difference {
final int line;
final String actual;
final String expected;
Difference(this.line, this.actual, this.expected);
}
class Difference(final int line, final String actual, final String expected);
Difference findFirstDifference(String actual, String expected) {
final actualLines = actual.split('\n');
@@ -260,49 +260,38 @@ enum Extend {
enum Shift { LSL, LSR, ASR, ROR }
/// reg (LSL|LSR|ASR) #imm operand.
class ShiftedRegOperand implements Operand {
final Register reg;
final Shift shift;
final int shiftAmount;
const ShiftedRegOperand(this.reg, this.shift, this.shiftAmount);
}
class const ShiftedRegOperand(
final Register reg,
final Shift shift,
final int shiftAmount,
) implements Operand;
/// reg (U|S)XT(B|H|W|X) #imm operand.
class ExtRegOperand implements Operand {
final Register reg;
final Extend ext;
final int shiftAmount;
const ExtRegOperand(this.reg, this.ext, [this.shiftAmount = 0])
: assert(0 <= shiftAmount && shiftAmount <= 4);
class const ExtRegOperand(
final Register reg,
final Extend ext, [
final int shiftAmount = 0,
]) implements Operand {
this : assert(0 <= shiftAmount && shiftAmount <= 4);
}
/// [base + reg LSL #imm] address operand.
class RegRegAddress implements Address {
final Register base;
final Register reg;
final int shift;
RegRegAddress(this.base, this.reg, this.shift);
}
class RegRegAddress(final Register base, final Register reg, final int shift)
implements Address;
/// [base + reg (S|U)XTW {imm}] address operand.
class RegExtRegAddress implements Address {
final Register base;
final Register reg;
final Extend ext;
final bool scaled;
RegExtRegAddress(this.base, this.reg, this.ext, {this.scaled = false});
}
class RegExtRegAddress(
final Register base,
final Register reg,
final Extend ext, {
final bool scaled = false,
}) implements Address;
class WritebackRegOffsetAddress implements Address {
final Register base;
final int offset;
final bool isPostIndexed;
WritebackRegOffsetAddress(
this.base,
this.offset, {
required this.isPostIndexed,
});
}
class WritebackRegOffsetAddress(
final Register base,
final int offset, {
required final bool isPostIndexed,
}) implements Address;
// Bits to simplify encoding of the instructions.
const int B0 = (1 << 0);
@@ -32,8 +32,6 @@ final class Arm64Constraints extends Constraints {
List<Constraint?>? _parameters;
Arm64Constraints();
@override
int getNumberOfRegisters() => numberOfRegisters;
@@ -57,28 +57,20 @@ enum OperandSize {
}
/// Immediate operand.
class Immediate implements Operand {
final int value;
const Immediate(this.value);
}
class const Immediate(final int value) implements Operand;
/// Address operand.
abstract interface class Address implements Operand {}
abstract interface class Address implements Operand;
/// [base + offset] address operand.
class RegOffsetAddress implements Address {
final Register base;
final int offset;
RegOffsetAddress(this.base, this.offset);
}
class RegOffsetAddress(final Register base, final int offset)
implements Address;
/// Destination of a branch.
class Label {
int _offset = -1;
final branchOffsets = <int>[];
Label();
bool get isBound => _offset >= 0;
// Returns relative offset from the branch to the label,
+6 -8
View File
@@ -8,16 +8,14 @@ import 'package:cfg/ir/functions.dart';
import 'package:native_compiler/back_end/object_pool.dart';
/// Generated code for a function or a stub.
class Code {
final String name;
final CFunction? function;
final Uint8List instructions;
final ObjectPool objectPool;
class Code(
final String name,
final CFunction? function,
final Uint8List instructions,
final ObjectPool objectPool,
) {
/// Offset of instructions in the resulting image.
int? instructionsImageOffset;
Code(this.name, this.function, this.instructions, this.objectPool);
}
/// Comsumer of the generated code.
@@ -7,9 +7,7 @@ import 'package:cfg/ir/instructions.dart';
import 'package:cfg/ir/types.dart';
import 'package:cfg/ir/visitor.dart';
final class AnyCpuRegister implements Constraint {
const AnyCpuRegister();
final class const AnyCpuRegister() implements Constraint {
@override
RegisterClass get registerClass => RegisterClass.cpu;
@@ -17,9 +15,7 @@ final class AnyCpuRegister implements Constraint {
String toString() => 'reg';
}
final class AnyFpuRegister implements Constraint {
const AnyFpuRegister();
final class const AnyFpuRegister() implements Constraint {
@override
RegisterClass get registerClass => RegisterClass.fpu;
@@ -27,12 +23,8 @@ final class AnyFpuRegister implements Constraint {
String toString() => 'fpreg';
}
final class AnyLocation implements Constraint {
@override
final RegisterClass registerClass;
const AnyLocation(this.registerClass);
final class const AnyLocation(final RegisterClass registerClass)
implements Constraint {
@override
String toString() => 'any';
}
@@ -51,17 +43,11 @@ final class AnyLocation implements Constraint {
/// both inputs and outputs.
///
/// TODO: encode constraints as int/Uint32List.
class InstructionConstraints {
final Constraint? result;
final List<Constraint?> inputs;
final List<Constraint> temps;
const InstructionConstraints(
this.result,
this.inputs, [
this.temps = const [],
]);
}
class const InstructionConstraints(
final Constraint? result,
final List<Constraint?> inputs, [
final List<Constraint> temps = const [],
]);
const anyCpuRegister = AnyCpuRegister();
const anyFpuRegister = AnyFpuRegister();
@@ -91,10 +77,8 @@ Constraint? anyLocationOrImmediate(Definition def) =>
/// Base class to define register allocation contraints for
/// inputs/outputs/temporaries of the IR instructions.
abstract base class Constraints
abstract base class const Constraints()
implements InstructionVisitor<InstructionConstraints?> {
const Constraints();
int getNumberOfRegisters();
List<Register> getAllocatableRegisters();
@@ -6,7 +6,7 @@ import 'package:cfg/ir/constant_value.dart' show ConstantValue;
import 'package:cfg/ir/instructions.dart' show MoveOp;
/// A generic operand of a machine instruction.
abstract interface class Operand {}
abstract interface class Operand;
/// Kind of physical register.
enum RegisterClass {
@@ -37,11 +37,8 @@ abstract base class PhysicalRegister implements Constraint, Location, Operand {
}
/// General-purpose register.
final class Register extends PhysicalRegister {
final int index;
final String name;
const Register(this.index, this.name);
final class const Register(final int index, final String name)
extends PhysicalRegister {
@override
RegisterClass get registerClass => RegisterClass.cpu;
@@ -52,11 +49,8 @@ final class Register extends PhysicalRegister {
const Register invalidReg = Register(-1, 'INVALID');
/// Floating-point register.
final class FPRegister extends PhysicalRegister {
final int index;
final String name;
const FPRegister(this.index, this.name);
final class const FPRegister(final int index, final String name)
extends PhysicalRegister {
@override
RegisterClass get registerClass => RegisterClass.fpu;
@@ -67,9 +61,7 @@ final class FPRegister extends PhysicalRegister {
const FPRegister invalidFPReg = FPRegister(-1, 'INVALID');
/// Base class for all stack locations.
sealed class StackLocation implements Location {
const StackLocation();
sealed class const StackLocation() implements Location {
@override
Location get physicalLocation => this;
}
@@ -164,21 +156,14 @@ class Locations {
}
/// Location->location move, part of ParallelMove instruction.
final class Move extends MoveOp {
Location from;
Location to;
Move(this.from, this.to);
final class Move(var Location from, var Location to) extends MoveOp {
@override
String toString() => '$from -> $to';
}
/// Constant->location move, part of ParallelMove instruction.
final class LoadConstant extends MoveOp {
ConstantValue value;
Location to;
LoadConstant(this.value, this.to);
final class LoadConstant(var ConstantValue value, var Location to)
extends MoveOp {
@override
String toString() => '$value -> $to';
}
@@ -30,28 +30,21 @@ class ObjectPool {
/// Base class for specialized object pool entries which are not just
/// object references.
sealed class SpecializedEntry {
const SpecializedEntry();
sealed class const SpecializedEntry() {
/// Number of object pool entries reserved after this entry.
int get numReservedEntries => 0;
}
/// Base class for specialized object pool entries which
/// occupy 2 slots in the object pool.
sealed class PairSpecializedEntry extends SpecializedEntry {
const PairSpecializedEntry();
sealed class const PairSpecializedEntry() extends SpecializedEntry {
/// Number of object pool entries reserved after this entry.
@override
int get numReservedEntries => 1;
}
/// Object pool entry representing tags for the new objects of the given class.
final class NewObjectTags extends SpecializedEntry {
final ast.Class cls;
NewObjectTags(this.cls);
final class NewObjectTags(final ast.Class cls) extends SpecializedEntry {
@override
int get hashCode => cls.hashCode + 19;
@@ -61,13 +54,11 @@ final class NewObjectTags extends SpecializedEntry {
}
/// ICData call object pool entries occupies 2 slots: ICData, dispatcher code.
sealed class ICDataCallEntry extends PairSpecializedEntry {
final CFunction owner;
final ArgumentsShape argumentsShape;
final Name selector;
ICDataCallEntry(this.owner, this.argumentsShape, {required this.selector});
sealed class ICDataCallEntry(
final CFunction owner,
final ArgumentsShape argumentsShape, {
required final Name selector,
}) extends PairSpecializedEntry {
@override
int get hashCode =>
finalizeHash(combineHash(selector.hashCode, argumentsShape.hashCode));
@@ -102,19 +93,14 @@ final class DynamicCallEntry extends ICDataCallEntry {
/// Reserved entry, filled from a preceeding [SpecializedEntry]
/// with a non-zero [numReservedEntries].
final class ReservedEntry extends SpecializedEntry {
const ReservedEntry();
final class const ReservedEntry() extends SpecializedEntry {
@override
int get numReservedEntries => 0;
}
/// Object pool entry representing offset of the static field
/// relative to static field table.
final class StaticFieldOffset extends SpecializedEntry {
final CField field;
StaticFieldOffset(this.field);
final class StaticFieldOffset(final CField field) extends SpecializedEntry {
@override
int get hashCode => field.hashCode + 13;
@@ -125,10 +111,7 @@ final class StaticFieldOffset extends SpecializedEntry {
/// Object pool entry representing a subtype test cache.
/// This is not a specialized entry, it is encoded as a regular object reference.
final class SubtypeTestCache {
final int numInputs;
SubtypeTestCache(this.numInputs);
final class SubtypeTestCache(final int numInputs) {
// Use identity hashCode and == as separate subtype test caches are
// used for each type check.
}
@@ -299,17 +299,14 @@ final class RegisterAllocationChecker extends Pass {
}
/// Abstract value computed in the program.
sealed class _Value {
_Value();
sealed class _Value() {
factory _Value.fromDef(Definition def) =>
(def is Constant) ? _Const(def.value) : _Result(def);
}
/// Value representing a result of the [Definition].
final class _Result extends _Value {
final Definition def;
_Result(this.def) : assert(def is! Constant);
final class _Result(final Definition def) extends _Value {
this : assert(def is! Constant);
@override
bool operator ==(Object other) => other is _Result && def == other.def;
@@ -322,10 +319,7 @@ final class _Result extends _Value {
}
/// Value representing a constant.
final class _Const extends _Value {
final ConstantValue value;
_Const(this.value);
final class _Const(final ConstantValue value) extends _Value {
@override
bool operator ==(Object other) => other is _Const && value == other.value;
@@ -337,10 +331,7 @@ final class _Const extends _Value {
}
/// Invalid value, clobbered in the given [Instruction].
final class _Garbage extends _Value {
final Instruction clobber;
_Garbage(this.clobber);
final class _Garbage(final Instruction clobber) extends _Value {
@override
bool operator ==(Object other) =>
other is _Garbage && clobber == other.clobber;
@@ -355,25 +346,19 @@ final class _Garbage extends _Value {
}
/// Incoming value into the block.
final class _Incoming extends _Value {
final Block block;
final Location loc;
final class _Incoming(final Block block, final Location loc) extends _Value {
_Value? value;
_Incoming(this.block, this.loc);
@override
String toString() => 'incoming $loc at ${IrToText.reference(block)} entry';
}
/// Prints results of the register allocation.
/// Can be used as [IrToText.annotator] or [ErrorContext.annotator].
class RegisterAllocationPrinter {
final BackEndState backEndState;
final Constraints constraints;
RegisterAllocationPrinter(this.backEndState, this.constraints);
class RegisterAllocationPrinter(
final BackEndState backEndState,
final Constraints constraints,
) {
String? print(Instruction instr) {
final constr = constraints.getConstraints(instr);
if (constr == null) {
+1 -5
View File
@@ -46,11 +46,7 @@ extension type Name._(Object /*String|PrivateName*/ raw) implements Object {
/// Private name in a [library].
/// VM mangles such names with a library key (`@nnnn`).
final class PrivateName {
final String text;
final ast.Library library;
PrivateName(this.text, this.library);
final class PrivateName(final String text, final ast.Library library) {
@override
bool operator ==(Object other) =>
other is PrivateName && text == other.text && library == other.library;
@@ -391,12 +391,7 @@ class Header {
}
}
abstract base class LoadCommand {
final MachoImageWriter writer;
final int cmd;
LoadCommand(this.writer, this.cmd);
abstract base class LoadCommand(final MachoImageWriter writer, final int cmd) {
int get unalignedSize;
late final int size = roundUp(unalignedSize, writer.commandAlignment);
@@ -676,14 +671,12 @@ class SymbolTable {
}
}
class Symbol {
final int nameIndex;
final int type;
final Section section;
final int offset;
Symbol(this.nameIndex, this.type, this.section, this.offset);
class Symbol(
final int nameIndex,
final int type,
final Section section,
final int offset,
) {
static const int size = 4 + 1 + 1 + 2 + 8;
void write(BufferedStream stream) {
+18 -27
View File
@@ -194,9 +194,9 @@ class SnapshotSerializer {
out.writeUint(numBaseObjects);
out.writeUint(numObjects);
final codeCluster =
getPredefinedCluster(PredefinedClusters.codes)
as CodeSerializationCluster;
final codeCluster = getPredefinedCluster(
PredefinedClusters.codes,
) as CodeSerializationCluster;
final lastCode = codeCluster._objects.last;
out.writeUint(
lastCode.instructionsImageOffset! + lastCode.instructions.lengthInBytes,
@@ -419,11 +419,7 @@ class SnapshotSerializer {
/// AST Constant which wraps an arbitrary object.
/// Used during snapshot serialization in order to embed arbitrary objects
/// (such as Name) into other constants (such as ListConstant).
class WrapperConstant extends ast.AuxiliaryConstant {
final Object? unwrap;
WrapperConstant(this.unwrap);
class WrapperConstant(final Object? unwrap) extends ast.AuxiliaryConstant {
@override
void visitChildren(ast.Visitor v) => throw 'Should not be called.';
@@ -1222,16 +1218,12 @@ final class InterfaceTypeSerializationCluster extends SerializationCluster {
}
/// Declaration of type parameters, corresponds to the VM TypeParameters object.
class TypeParameters {
final ast.ListConstant names;
final TypeArgumentsConstant bounds;
final TypeArgumentsConstant defaultTypes;
TypeParameters._(this.names, this.bounds, this.defaultTypes);
factory TypeParameters.fromStructuralParameters(
List<ast.StructuralParameter> params,
) {
class TypeParameters._(
final ast.ListConstant names,
final TypeArgumentsConstant bounds,
final TypeArgumentsConstant defaultTypes,
) {
factory fromStructuralParameters(List<ast.StructuralParameter> params) {
final names = getListConstant([for (final p in params) p.name!]);
final bounds = TypeArgumentsConstant([for (final p in params) p.bound]);
final defaultTypes = TypeArgumentsConstant([
@@ -1294,9 +1286,9 @@ final class FunctionTypeSerializationCluster extends SerializationCluster {
_objects.add(type);
if (type.typeParameters.isNotEmpty) {
// Establish StructuralParameter -> owner links.
final typeParamCluster =
serializer.getPredefinedCluster(PredefinedClusters.typeParameterTypes)
as TypeParameterTypeSerializationCluster;
final typeParamCluster = serializer.getPredefinedCluster(
PredefinedClusters.typeParameterTypes,
) as TypeParameterTypeSerializationCluster;
for (final tp in type.typeParameters) {
typeParamCluster._structuralParameterOwner[tp] = type;
}
@@ -1538,12 +1530,11 @@ final class CodeSerializationCluster extends SerializationCluster {
}
}
class ICData {
final CFunction owner;
final ArgumentsShape argumentsShape;
final Name targetName;
ICData(this.owner, this.argumentsShape, this.targetName);
}
class ICData(
final CFunction owner,
final ArgumentsShape argumentsShape,
final Name targetName,
);
final class ICDataSerializationCluster extends SerializationCluster {
final List<ICData> _objects = [];
+1 -1
View File
@@ -4,7 +4,7 @@ description: Compiler targeting native platforms
publish_to: none
environment:
sdk: '^3.12.0-0'
sdk: '^3.13.0-0'
resolution: workspace
+1 -7
View File
@@ -199,13 +199,7 @@ class CompileAndDumpIr extends RecursiveVisitor {
}
}
class Difference {
final int line;
final String actual;
final String expected;
Difference(this.line, this.actual, this.expected);
}
class Difference(final int line, final String actual, final String expected);
Difference findFirstDifference(String actual, String expected) {
final actualLines = actual.split('\n');