[turboshaft] restructure MachineRepresentation and MachineType

Bug: v8:12783
Change-Id: I5de98493d67c7c797d4a1b2dcd18c0347821f0f8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3870471
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Auto-Submit: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83262}
This commit is contained in:
Tobias Tebbi 2022-09-16 12:18:17 +02:00 committed by V8 LUCI CQ
parent 52f55f38f2
commit 1047e423a2
13 changed files with 1152 additions and 420 deletions

View File

@ -2878,6 +2878,8 @@ filegroup(
"src/compiler/turboshaft/optimization-phase.h",
"src/compiler/turboshaft/recreate-schedule.cc",
"src/compiler/turboshaft/recreate-schedule.h",
"src/compiler/turboshaft/representations.cc",
"src/compiler/turboshaft/representations.h",
"src/compiler/turboshaft/sidetable.h",
"src/compiler/turboshaft/utils.h",
"src/compiler/turboshaft/value-numbering-assembler.h",

View File

@ -2933,6 +2933,7 @@ v8_header_set("v8_internal_headers") {
"src/compiler/turboshaft/operations.h",
"src/compiler/turboshaft/optimization-phase.h",
"src/compiler/turboshaft/recreate-schedule.h",
"src/compiler/turboshaft/representations.h",
"src/compiler/turboshaft/sidetable.h",
"src/compiler/turboshaft/utils.h",
"src/compiler/turboshaft/value-numbering-assembler.h",
@ -4229,6 +4230,7 @@ v8_source_set("v8_turboshaft") {
"src/compiler/turboshaft/operations.cc",
"src/compiler/turboshaft/optimization-phase.cc",
"src/compiler/turboshaft/recreate-schedule.cc",
"src/compiler/turboshaft/representations.cc",
]
public_deps = [

View File

@ -152,10 +152,6 @@ class MachineType {
constexpr bool IsCompressedPointer() const {
return representation() == MachineRepresentation::kCompressedPointer;
}
constexpr static MachineRepresentation TaggedRepresentation() {
return (kTaggedSize == 4) ? MachineRepresentation::kWord32
: MachineRepresentation::kWord64;
}
constexpr static MachineRepresentation PointerRepresentation() {
return (kSystemPointerSize == 4) ? MachineRepresentation::kWord32
: MachineRepresentation::kWord64;

View File

@ -32,229 +32,321 @@ class AssemblerInterface : public Superclass {
using Superclass::Superclass;
using Base = Superclass;
#define DECL_MULTI_REP_BINOP(name, operation, kind) \
OpIndex name(OpIndex left, OpIndex right, MachineRepresentation rep) { \
#define DECL_MULTI_REP_BINOP(name, operation, rep_type, kind) \
OpIndex name(OpIndex left, OpIndex right, rep_type rep) { \
return subclass().operation(left, right, operation##Op::Kind::k##kind, \
rep); \
}
#define DECL_SINGLE_REP_BINOP(name, operation, kind, rep) \
OpIndex name(OpIndex left, OpIndex right) { \
return subclass().operation(left, right, operation##Op::Kind::k##kind, \
MachineRepresentation::k##rep); \
rep); \
}
#define DECL_SINGLE_REP_BINOP_NO_KIND(name, operation, rep) \
OpIndex name(OpIndex left, OpIndex right) { \
return subclass().operation(left, right, MachineRepresentation::k##rep); \
#define DECL_SINGLE_REP_BINOP_NO_KIND(name, operation, rep) \
OpIndex name(OpIndex left, OpIndex right) { \
return subclass().operation(left, right, rep); \
}
DECL_MULTI_REP_BINOP(WordAdd, WordBinop, Add)
DECL_SINGLE_REP_BINOP(Word32Add, WordBinop, Add, Word32)
DECL_SINGLE_REP_BINOP(Word64Add, WordBinop, Add, Word64)
DECL_MULTI_REP_BINOP(WordAdd, WordBinop, WordRepresentation, Add)
DECL_SINGLE_REP_BINOP(Word32Add, WordBinop, Add, WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Word64Add, WordBinop, Add, WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(WordMul, WordBinop, Mul)
DECL_SINGLE_REP_BINOP(Word32Mul, WordBinop, Mul, Word32)
DECL_SINGLE_REP_BINOP(Word64Mul, WordBinop, Mul, Word64)
DECL_MULTI_REP_BINOP(WordMul, WordBinop, WordRepresentation, Mul)
DECL_SINGLE_REP_BINOP(Word32Mul, WordBinop, Mul, WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Word64Mul, WordBinop, Mul, WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(WordBitwiseAnd, WordBinop, BitwiseAnd)
DECL_SINGLE_REP_BINOP(Word32BitwiseAnd, WordBinop, BitwiseAnd, Word32)
DECL_SINGLE_REP_BINOP(Word64BitwiseAnd, WordBinop, BitwiseAnd, Word64)
DECL_MULTI_REP_BINOP(WordBitwiseAnd, WordBinop, WordRepresentation,
BitwiseAnd)
DECL_SINGLE_REP_BINOP(Word32BitwiseAnd, WordBinop, BitwiseAnd,
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Word64BitwiseAnd, WordBinop, BitwiseAnd,
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(WordBitwiseOr, WordBinop, BitwiseOr)
DECL_SINGLE_REP_BINOP(Word32BitwiseOr, WordBinop, BitwiseOr, Word32)
DECL_SINGLE_REP_BINOP(Word64BitwiseOr, WordBinop, BitwiseOr, Word64)
DECL_MULTI_REP_BINOP(WordBitwiseOr, WordBinop, WordRepresentation, BitwiseOr)
DECL_SINGLE_REP_BINOP(Word32BitwiseOr, WordBinop, BitwiseOr,
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Word64BitwiseOr, WordBinop, BitwiseOr,
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(WordBitwiseXor, WordBinop, BitwiseXor)
DECL_SINGLE_REP_BINOP(Word32BitwiseXor, WordBinop, BitwiseXor, Word32)
DECL_SINGLE_REP_BINOP(Word64BitwiseXor, WordBinop, BitwiseXor, Word64)
DECL_MULTI_REP_BINOP(WordBitwiseXor, WordBinop, WordRepresentation,
BitwiseXor)
DECL_SINGLE_REP_BINOP(Word32BitwiseXor, WordBinop, BitwiseXor,
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Word64BitwiseXor, WordBinop, BitwiseXor,
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(WordSub, WordBinop, Sub)
DECL_SINGLE_REP_BINOP(Word32Sub, WordBinop, Sub, Word32)
DECL_SINGLE_REP_BINOP(Word64Sub, WordBinop, Sub, Word64)
DECL_MULTI_REP_BINOP(WordSub, WordBinop, WordRepresentation, Sub)
DECL_SINGLE_REP_BINOP(Word32Sub, WordBinop, Sub, WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Word64Sub, WordBinop, Sub, WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(IntDiv, WordBinop, SignedDiv)
DECL_SINGLE_REP_BINOP(Int32Div, WordBinop, SignedDiv, Word32)
DECL_SINGLE_REP_BINOP(Int64Div, WordBinop, SignedDiv, Word64)
DECL_MULTI_REP_BINOP(UintDiv, WordBinop, UnsignedDiv)
DECL_SINGLE_REP_BINOP(Uint32Div, WordBinop, UnsignedDiv, Word32)
DECL_SINGLE_REP_BINOP(Uint64Div, WordBinop, UnsignedDiv, Word64)
DECL_MULTI_REP_BINOP(IntMod, WordBinop, SignedMod)
DECL_SINGLE_REP_BINOP(Int32Mod, WordBinop, SignedMod, Word32)
DECL_SINGLE_REP_BINOP(Int64Mod, WordBinop, SignedMod, Word64)
DECL_MULTI_REP_BINOP(UintMod, WordBinop, UnsignedMod)
DECL_SINGLE_REP_BINOP(Uint32Mod, WordBinop, UnsignedMod, Word32)
DECL_SINGLE_REP_BINOP(Uint64Mod, WordBinop, UnsignedMod, Word64)
DECL_MULTI_REP_BINOP(IntDiv, WordBinop, WordRepresentation, SignedDiv)
DECL_SINGLE_REP_BINOP(Int32Div, WordBinop, SignedDiv,
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Int64Div, WordBinop, SignedDiv,
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(UintDiv, WordBinop, WordRepresentation, UnsignedDiv)
DECL_SINGLE_REP_BINOP(Uint32Div, WordBinop, UnsignedDiv,
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Uint64Div, WordBinop, UnsignedDiv,
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(IntMod, WordBinop, WordRepresentation, SignedMod)
DECL_SINGLE_REP_BINOP(Int32Mod, WordBinop, SignedMod,
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Int64Mod, WordBinop, SignedMod,
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(UintMod, WordBinop, WordRepresentation, UnsignedMod)
DECL_SINGLE_REP_BINOP(Uint32Mod, WordBinop, UnsignedMod,
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Uint64Mod, WordBinop, UnsignedMod,
WordRepresentation::Word64())
DECL_SINGLE_REP_BINOP(Int32MulOverflownBits, WordBinop,
SignedMulOverflownBits, Word32)
SignedMulOverflownBits, WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Uint32MulOverflownBits, WordBinop,
UnsignedMulOverflownBits, Word32)
UnsignedMulOverflownBits, WordRepresentation::Word32())
DECL_MULTI_REP_BINOP(IntAddCheckOverflow, OverflowCheckedBinop, SignedAdd)
DECL_MULTI_REP_BINOP(IntAddCheckOverflow, OverflowCheckedBinop,
WordRepresentation, SignedAdd)
DECL_SINGLE_REP_BINOP(Int32AddCheckOverflow, OverflowCheckedBinop, SignedAdd,
Word32)
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Int64AddCheckOverflow, OverflowCheckedBinop, SignedAdd,
Word64)
DECL_MULTI_REP_BINOP(IntSubCheckOverflow, OverflowCheckedBinop, SignedSub)
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(IntSubCheckOverflow, OverflowCheckedBinop,
WordRepresentation, SignedSub)
DECL_SINGLE_REP_BINOP(Int32SubCheckOverflow, OverflowCheckedBinop, SignedSub,
Word32)
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Int64SubCheckOverflow, OverflowCheckedBinop, SignedSub,
Word64)
DECL_MULTI_REP_BINOP(IntMulCheckOverflow, OverflowCheckedBinop, SignedMul)
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(IntMulCheckOverflow, OverflowCheckedBinop,
WordRepresentation, SignedMul)
DECL_SINGLE_REP_BINOP(Int32MulCheckOverflow, OverflowCheckedBinop, SignedMul,
Word32)
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Int64MulCheckOverflow, OverflowCheckedBinop, SignedMul,
Word64)
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(FloatAdd, FloatBinop, Add)
DECL_SINGLE_REP_BINOP(Float32Add, FloatBinop, Add, Float32)
DECL_SINGLE_REP_BINOP(Float64Add, FloatBinop, Add, Float64)
DECL_MULTI_REP_BINOP(FloatMul, FloatBinop, Mul)
DECL_SINGLE_REP_BINOP(Float32Mul, FloatBinop, Mul, Float32)
DECL_SINGLE_REP_BINOP(Float64Mul, FloatBinop, Mul, Float64)
DECL_MULTI_REP_BINOP(FloatSub, FloatBinop, Sub)
DECL_SINGLE_REP_BINOP(Float32Sub, FloatBinop, Sub, Float32)
DECL_SINGLE_REP_BINOP(Float64Sub, FloatBinop, Sub, Float64)
DECL_MULTI_REP_BINOP(FloatDiv, FloatBinop, Div)
DECL_SINGLE_REP_BINOP(Float32Div, FloatBinop, Div, Float32)
DECL_SINGLE_REP_BINOP(Float64Div, FloatBinop, Div, Float64)
DECL_MULTI_REP_BINOP(FloatMin, FloatBinop, Min)
DECL_SINGLE_REP_BINOP(Float32Min, FloatBinop, Min, Float32)
DECL_SINGLE_REP_BINOP(Float64Min, FloatBinop, Min, Float64)
DECL_MULTI_REP_BINOP(FloatMax, FloatBinop, Max)
DECL_SINGLE_REP_BINOP(Float32Max, FloatBinop, Max, Float32)
DECL_SINGLE_REP_BINOP(Float64Max, FloatBinop, Max, Float64)
DECL_SINGLE_REP_BINOP(Float64Mod, FloatBinop, Mod, Float64)
DECL_SINGLE_REP_BINOP(Float64Power, FloatBinop, Power, Float64)
DECL_SINGLE_REP_BINOP(Float64Atan2, FloatBinop, Atan2, Float64)
DECL_MULTI_REP_BINOP(FloatAdd, FloatBinop, FloatRepresentation, Add)
DECL_SINGLE_REP_BINOP(Float32Add, FloatBinop, Add,
FloatRepresentation::Float32())
DECL_SINGLE_REP_BINOP(Float64Add, FloatBinop, Add,
FloatRepresentation::Float64())
DECL_MULTI_REP_BINOP(FloatMul, FloatBinop, FloatRepresentation, Mul)
DECL_SINGLE_REP_BINOP(Float32Mul, FloatBinop, Mul,
FloatRepresentation::Float32())
DECL_SINGLE_REP_BINOP(Float64Mul, FloatBinop, Mul,
FloatRepresentation::Float64())
DECL_MULTI_REP_BINOP(FloatSub, FloatBinop, FloatRepresentation, Sub)
DECL_SINGLE_REP_BINOP(Float32Sub, FloatBinop, Sub,
FloatRepresentation::Float32())
DECL_SINGLE_REP_BINOP(Float64Sub, FloatBinop, Sub,
FloatRepresentation::Float64())
DECL_MULTI_REP_BINOP(FloatDiv, FloatBinop, FloatRepresentation, Div)
DECL_SINGLE_REP_BINOP(Float32Div, FloatBinop, Div,
FloatRepresentation::Float32())
DECL_SINGLE_REP_BINOP(Float64Div, FloatBinop, Div,
FloatRepresentation::Float64())
DECL_MULTI_REP_BINOP(FloatMin, FloatBinop, FloatRepresentation, Min)
DECL_SINGLE_REP_BINOP(Float32Min, FloatBinop, Min,
FloatRepresentation::Float32())
DECL_SINGLE_REP_BINOP(Float64Min, FloatBinop, Min,
FloatRepresentation::Float64())
DECL_MULTI_REP_BINOP(FloatMax, FloatBinop, FloatRepresentation, Max)
DECL_SINGLE_REP_BINOP(Float32Max, FloatBinop, Max,
FloatRepresentation::Float32())
DECL_SINGLE_REP_BINOP(Float64Max, FloatBinop, Max,
FloatRepresentation::Float64())
DECL_SINGLE_REP_BINOP(Float64Mod, FloatBinop, Mod,
FloatRepresentation::Float64())
DECL_SINGLE_REP_BINOP(Float64Power, FloatBinop, Power,
FloatRepresentation::Float64())
DECL_SINGLE_REP_BINOP(Float64Atan2, FloatBinop, Atan2,
FloatRepresentation::Float64())
DECL_MULTI_REP_BINOP(ShiftRightArithmeticShiftOutZeros, Shift,
ShiftRightArithmeticShiftOutZeros)
WordRepresentation, ShiftRightArithmeticShiftOutZeros)
DECL_SINGLE_REP_BINOP(Word32ShiftRightArithmeticShiftOutZeros, Shift,
ShiftRightArithmeticShiftOutZeros, Word32)
ShiftRightArithmeticShiftOutZeros,
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Word64ShiftRightArithmeticShiftOutZeros, Shift,
ShiftRightArithmeticShiftOutZeros, Word64)
DECL_MULTI_REP_BINOP(ShiftRightArithmetic, Shift, ShiftRightArithmetic)
ShiftRightArithmeticShiftOutZeros,
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(ShiftRightArithmetic, Shift, WordRepresentation,
ShiftRightArithmetic)
DECL_SINGLE_REP_BINOP(Word32ShiftRightArithmetic, Shift, ShiftRightArithmetic,
Word32)
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Word64ShiftRightArithmetic, Shift, ShiftRightArithmetic,
Word64)
DECL_MULTI_REP_BINOP(ShiftRightLogical, Shift, ShiftRightLogical)
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(ShiftRightLogical, Shift, WordRepresentation,
ShiftRightLogical)
DECL_SINGLE_REP_BINOP(Word32ShiftRightLogical, Shift, ShiftRightLogical,
Word32)
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Word64ShiftRightLogical, Shift, ShiftRightLogical,
Word64)
DECL_MULTI_REP_BINOP(ShiftLeft, Shift, ShiftLeft)
DECL_SINGLE_REP_BINOP(Word32ShiftLeft, Shift, ShiftLeft, Word32)
DECL_SINGLE_REP_BINOP(Word64ShiftLeft, Shift, ShiftLeft, Word64)
DECL_MULTI_REP_BINOP(RotateRight, Shift, RotateRight)
DECL_SINGLE_REP_BINOP(Word32RotateRight, Shift, RotateRight, Word32)
DECL_SINGLE_REP_BINOP(Word64RotateRight, Shift, RotateRight, Word64)
DECL_MULTI_REP_BINOP(RotateLeft, Shift, RotateLeft)
DECL_SINGLE_REP_BINOP(Word32RotateLeft, Shift, RotateLeft, Word32)
DECL_SINGLE_REP_BINOP(Word64RotateLeft, Shift, RotateLeft, Word64)
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(ShiftLeft, Shift, WordRepresentation, ShiftLeft)
DECL_SINGLE_REP_BINOP(Word32ShiftLeft, Shift, ShiftLeft,
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Word64ShiftLeft, Shift, ShiftLeft,
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(RotateRight, Shift, WordRepresentation, RotateRight)
DECL_SINGLE_REP_BINOP(Word32RotateRight, Shift, RotateRight,
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Word64RotateRight, Shift, RotateRight,
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(RotateLeft, Shift, WordRepresentation, RotateLeft)
DECL_SINGLE_REP_BINOP(Word32RotateLeft, Shift, RotateLeft,
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Word64RotateLeft, Shift, RotateLeft,
WordRepresentation::Word64())
OpIndex ShiftRightLogical(OpIndex left, uint32_t right,
MachineRepresentation rep) {
WordRepresentation rep) {
DCHECK_GE(right, 0);
DCHECK_LT(right, ElementSizeInBits(rep));
return ShiftRightLogical(left, Word32Constant(right), rep);
DCHECK_LT(right, rep.bit_width());
return ShiftRightLogical(left, this->Word32Constant(right), rep);
}
OpIndex ShiftRightArithmetic(OpIndex left, uint32_t right,
MachineRepresentation rep) {
WordRepresentation rep) {
DCHECK_GE(right, 0);
DCHECK_LT(right, ElementSizeInBits(rep));
return ShiftRightArithmetic(left, Word32Constant(right), rep);
DCHECK_LT(right, rep.bit_width());
return ShiftRightArithmetic(left, this->Word32Constant(right), rep);
}
DECL_SINGLE_REP_BINOP_NO_KIND(Word32Equal, Equal, Word32)
DECL_SINGLE_REP_BINOP_NO_KIND(Word64Equal, Equal, Word64)
DECL_SINGLE_REP_BINOP_NO_KIND(Float32Equal, Equal, Float32)
DECL_SINGLE_REP_BINOP_NO_KIND(Float64Equal, Equal, Float64)
DECL_SINGLE_REP_BINOP_NO_KIND(Word32Equal, Equal,
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP_NO_KIND(Word64Equal, Equal,
WordRepresentation::Word64())
DECL_SINGLE_REP_BINOP_NO_KIND(Float32Equal, Equal,
FloatRepresentation::Float32())
DECL_SINGLE_REP_BINOP_NO_KIND(Float64Equal, Equal,
FloatRepresentation::Float64())
DECL_MULTI_REP_BINOP(IntLessThan, Comparison, SignedLessThan)
DECL_SINGLE_REP_BINOP(Int32LessThan, Comparison, SignedLessThan, Word32)
DECL_SINGLE_REP_BINOP(Int64LessThan, Comparison, SignedLessThan, Word64)
DECL_MULTI_REP_BINOP(UintLessThan, Comparison, UnsignedLessThan)
DECL_SINGLE_REP_BINOP(Uint32LessThan, Comparison, UnsignedLessThan, Word32)
DECL_SINGLE_REP_BINOP(Uint64LessThan, Comparison, UnsignedLessThan, Word64)
DECL_MULTI_REP_BINOP(FloatLessThan, Comparison, SignedLessThan)
DECL_SINGLE_REP_BINOP(Float32LessThan, Comparison, SignedLessThan, Float32)
DECL_SINGLE_REP_BINOP(Float64LessThan, Comparison, SignedLessThan, Float64)
DECL_MULTI_REP_BINOP(IntLessThan, Comparison, RegisterRepresentation,
SignedLessThan)
DECL_SINGLE_REP_BINOP(Int32LessThan, Comparison, SignedLessThan,
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Int64LessThan, Comparison, SignedLessThan,
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(UintLessThan, Comparison, RegisterRepresentation,
UnsignedLessThan)
DECL_SINGLE_REP_BINOP(Uint32LessThan, Comparison, UnsignedLessThan,
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Uint64LessThan, Comparison, UnsignedLessThan,
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(FloatLessThan, Comparison, RegisterRepresentation,
SignedLessThan)
DECL_SINGLE_REP_BINOP(Float32LessThan, Comparison, SignedLessThan,
FloatRepresentation::Float32())
DECL_SINGLE_REP_BINOP(Float64LessThan, Comparison, SignedLessThan,
FloatRepresentation::Float64())
DECL_MULTI_REP_BINOP(IntLessThanOrEqual, Comparison, SignedLessThanOrEqual)
DECL_MULTI_REP_BINOP(IntLessThanOrEqual, Comparison, RegisterRepresentation,
SignedLessThanOrEqual)
DECL_SINGLE_REP_BINOP(Int32LessThanOrEqual, Comparison, SignedLessThanOrEqual,
Word32)
WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Int64LessThanOrEqual, Comparison, SignedLessThanOrEqual,
Word64)
DECL_MULTI_REP_BINOP(UintLessThanOrEqual, Comparison, UnsignedLessThanOrEqual)
WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(UintLessThanOrEqual, Comparison, RegisterRepresentation,
UnsignedLessThanOrEqual)
DECL_SINGLE_REP_BINOP(Uint32LessThanOrEqual, Comparison,
UnsignedLessThanOrEqual, Word32)
UnsignedLessThanOrEqual, WordRepresentation::Word32())
DECL_SINGLE_REP_BINOP(Uint64LessThanOrEqual, Comparison,
UnsignedLessThanOrEqual, Word64)
DECL_MULTI_REP_BINOP(FloatLessThanOrEqual, Comparison, SignedLessThanOrEqual)
UnsignedLessThanOrEqual, WordRepresentation::Word64())
DECL_MULTI_REP_BINOP(FloatLessThanOrEqual, Comparison, RegisterRepresentation,
SignedLessThanOrEqual)
DECL_SINGLE_REP_BINOP(Float32LessThanOrEqual, Comparison,
SignedLessThanOrEqual, Float32)
SignedLessThanOrEqual, FloatRepresentation::Float32())
DECL_SINGLE_REP_BINOP(Float64LessThanOrEqual, Comparison,
SignedLessThanOrEqual, Float64)
SignedLessThanOrEqual, FloatRepresentation::Float64())
#undef DECL_SINGLE_REP_BINOP
#undef DECL_MULTI_REP_BINOP
#undef DECL_SINGLE_REP_BINOP_NO_KIND
#define DECL_MULTI_REP_UNARY(name, operation, kind) \
OpIndex name(OpIndex input, MachineRepresentation rep) { \
#define DECL_MULTI_REP_UNARY(name, operation, rep_type, kind) \
OpIndex name(OpIndex input, rep_type rep) { \
return subclass().operation(input, operation##Op::Kind::k##kind, rep); \
}
#define DECL_SINGLE_REP_UNARY(name, operation, kind, rep) \
OpIndex name(OpIndex input) { \
return subclass().operation(input, operation##Op::Kind::k##kind, \
MachineRepresentation::k##rep); \
#define DECL_SINGLE_REP_UNARY(name, operation, kind, rep) \
OpIndex name(OpIndex input) { \
return subclass().operation(input, operation##Op::Kind::k##kind, rep); \
}
DECL_MULTI_REP_UNARY(FloatAbs, FloatUnary, Abs)
DECL_SINGLE_REP_UNARY(Float32Abs, FloatUnary, Abs, Float32)
DECL_SINGLE_REP_UNARY(Float64Abs, FloatUnary, Abs, Float64)
DECL_MULTI_REP_UNARY(FloatNegate, FloatUnary, Negate)
DECL_SINGLE_REP_UNARY(Float32Negate, FloatUnary, Negate, Float32)
DECL_SINGLE_REP_UNARY(Float64Negate, FloatUnary, Negate, Float64)
DECL_SINGLE_REP_UNARY(Float64SilenceNaN, FloatUnary, SilenceNaN, Float64)
DECL_MULTI_REP_UNARY(FloatRoundDown, FloatUnary, RoundDown)
DECL_SINGLE_REP_UNARY(Float32RoundDown, FloatUnary, RoundDown, Float32)
DECL_SINGLE_REP_UNARY(Float64RoundDown, FloatUnary, RoundDown, Float64)
DECL_MULTI_REP_UNARY(FloatRoundUp, FloatUnary, RoundUp)
DECL_SINGLE_REP_UNARY(Float32RoundUp, FloatUnary, RoundUp, Float32)
DECL_SINGLE_REP_UNARY(Float64RoundUp, FloatUnary, RoundUp, Float64)
DECL_MULTI_REP_UNARY(FloatRoundToZero, FloatUnary, RoundToZero)
DECL_SINGLE_REP_UNARY(Float32RoundToZero, FloatUnary, RoundToZero, Float32)
DECL_SINGLE_REP_UNARY(Float64RoundToZero, FloatUnary, RoundToZero, Float64)
DECL_MULTI_REP_UNARY(FloatRoundTiesEven, FloatUnary, RoundTiesEven)
DECL_MULTI_REP_UNARY(FloatAbs, FloatUnary, FloatRepresentation, Abs)
DECL_SINGLE_REP_UNARY(Float32Abs, FloatUnary, Abs,
FloatRepresentation::Float32())
DECL_SINGLE_REP_UNARY(Float64Abs, FloatUnary, Abs,
FloatRepresentation::Float64())
DECL_MULTI_REP_UNARY(FloatNegate, FloatUnary, FloatRepresentation, Negate)
DECL_SINGLE_REP_UNARY(Float32Negate, FloatUnary, Negate,
FloatRepresentation::Float32())
DECL_SINGLE_REP_UNARY(Float64Negate, FloatUnary, Negate,
FloatRepresentation::Float64())
DECL_SINGLE_REP_UNARY(Float64SilenceNaN, FloatUnary, SilenceNaN,
FloatRepresentation::Float64())
DECL_MULTI_REP_UNARY(FloatRoundDown, FloatUnary, FloatRepresentation,
RoundDown)
DECL_SINGLE_REP_UNARY(Float32RoundDown, FloatUnary, RoundDown,
FloatRepresentation::Float32())
DECL_SINGLE_REP_UNARY(Float64RoundDown, FloatUnary, RoundDown,
FloatRepresentation::Float64())
DECL_MULTI_REP_UNARY(FloatRoundUp, FloatUnary, FloatRepresentation, RoundUp)
DECL_SINGLE_REP_UNARY(Float32RoundUp, FloatUnary, RoundUp,
FloatRepresentation::Float32())
DECL_SINGLE_REP_UNARY(Float64RoundUp, FloatUnary, RoundUp,
FloatRepresentation::Float64())
DECL_MULTI_REP_UNARY(FloatRoundToZero, FloatUnary, FloatRepresentation,
RoundToZero)
DECL_SINGLE_REP_UNARY(Float32RoundToZero, FloatUnary, RoundToZero,
FloatRepresentation::Float32())
DECL_SINGLE_REP_UNARY(Float64RoundToZero, FloatUnary, RoundToZero,
FloatRepresentation::Float64())
DECL_MULTI_REP_UNARY(FloatRoundTiesEven, FloatUnary, FloatRepresentation,
RoundTiesEven)
DECL_SINGLE_REP_UNARY(Float32RoundTiesEven, FloatUnary, RoundTiesEven,
Float32)
FloatRepresentation::Float32())
DECL_SINGLE_REP_UNARY(Float64RoundTiesEven, FloatUnary, RoundTiesEven,
Float64)
DECL_SINGLE_REP_UNARY(Float64Log, FloatUnary, Log, Float64)
DECL_MULTI_REP_UNARY(FloatSqrt, FloatUnary, Sqrt)
DECL_SINGLE_REP_UNARY(Float32Sqrt, FloatUnary, Sqrt, Float32)
DECL_SINGLE_REP_UNARY(Float64Sqrt, FloatUnary, Sqrt, Float64)
DECL_SINGLE_REP_UNARY(Float64Exp, FloatUnary, Exp, Float64)
DECL_SINGLE_REP_UNARY(Float64Expm1, FloatUnary, Expm1, Float64)
DECL_SINGLE_REP_UNARY(Float64Sin, FloatUnary, Sin, Float64)
DECL_SINGLE_REP_UNARY(Float64Cos, FloatUnary, Cos, Float64)
DECL_SINGLE_REP_UNARY(Float64Sinh, FloatUnary, Sinh, Float64)
DECL_SINGLE_REP_UNARY(Float64Cosh, FloatUnary, Cosh, Float64)
DECL_SINGLE_REP_UNARY(Float64Asin, FloatUnary, Asin, Float64)
DECL_SINGLE_REP_UNARY(Float64Acos, FloatUnary, Acos, Float64)
DECL_SINGLE_REP_UNARY(Float64Asinh, FloatUnary, Asinh, Float64)
DECL_SINGLE_REP_UNARY(Float64Acosh, FloatUnary, Acosh, Float64)
DECL_SINGLE_REP_UNARY(Float64Tan, FloatUnary, Tan, Float64)
DECL_SINGLE_REP_UNARY(Float64Tanh, FloatUnary, Tanh, Float64)
FloatRepresentation::Float64())
DECL_SINGLE_REP_UNARY(Float64Log, FloatUnary, Log,
FloatRepresentation::Float64())
DECL_MULTI_REP_UNARY(FloatSqrt, FloatUnary, FloatRepresentation, Sqrt)
DECL_SINGLE_REP_UNARY(Float32Sqrt, FloatUnary, Sqrt,
FloatRepresentation::Float32())
DECL_SINGLE_REP_UNARY(Float64Sqrt, FloatUnary, Sqrt,
FloatRepresentation::Float64())
DECL_SINGLE_REP_UNARY(Float64Exp, FloatUnary, Exp,
FloatRepresentation::Float64())
DECL_SINGLE_REP_UNARY(Float64Expm1, FloatUnary, Expm1,
FloatRepresentation::Float64())
DECL_SINGLE_REP_UNARY(Float64Sin, FloatUnary, Sin,
FloatRepresentation::Float64())
DECL_SINGLE_REP_UNARY(Float64Cos, FloatUnary, Cos,
FloatRepresentation::Float64())
DECL_SINGLE_REP_UNARY(Float64Sinh, FloatUnary, Sinh,
FloatRepresentation::Float64())
DECL_SINGLE_REP_UNARY(Float64Cosh, FloatUnary, Cosh,
FloatRepresentation::Float64())
DECL_SINGLE_REP_UNARY(Float64Asin, FloatUnary, Asin,
FloatRepresentation::Float64())
DECL_SINGLE_REP_UNARY(Float64Acos, FloatUnary, Acos,
FloatRepresentation::Float64())
DECL_SINGLE_REP_UNARY(Float64Asinh, FloatUnary, Asinh,
FloatRepresentation::Float64())
DECL_SINGLE_REP_UNARY(Float64Acosh, FloatUnary, Acosh,
FloatRepresentation::Float64())
DECL_SINGLE_REP_UNARY(Float64Tan, FloatUnary, Tan,
FloatRepresentation::Float64())
DECL_SINGLE_REP_UNARY(Float64Tanh, FloatUnary, Tanh,
FloatRepresentation::Float64())
DECL_MULTI_REP_UNARY(WordReverseBytes, WordUnary, ReverseBytes)
DECL_SINGLE_REP_UNARY(Word32ReverseBytes, WordUnary, ReverseBytes, Word32)
DECL_SINGLE_REP_UNARY(Word64ReverseBytes, WordUnary, ReverseBytes, Word64)
DECL_MULTI_REP_UNARY(WordCountLeadingZeros, WordUnary, CountLeadingZeros)
DECL_MULTI_REP_UNARY(WordReverseBytes, WordUnary, WordRepresentation,
ReverseBytes)
DECL_SINGLE_REP_UNARY(Word32ReverseBytes, WordUnary, ReverseBytes,
WordRepresentation::Word32())
DECL_SINGLE_REP_UNARY(Word64ReverseBytes, WordUnary, ReverseBytes,
WordRepresentation::Word64())
DECL_MULTI_REP_UNARY(WordCountLeadingZeros, WordUnary, WordRepresentation,
CountLeadingZeros)
DECL_SINGLE_REP_UNARY(Word32CountLeadingZeros, WordUnary, CountLeadingZeros,
Word32)
WordRepresentation::Word32())
DECL_SINGLE_REP_UNARY(Word64CountLeadingZeros, WordUnary, CountLeadingZeros,
Word64)
WordRepresentation::Word64())
#undef DECL_SINGLE_REP_UNARY
#undef DECL_MULTI_REP_UNARY
@ -270,15 +362,13 @@ class AssemblerInterface : public Superclass {
OpIndex Word64Constant(int64_t value) {
return Word64Constant(static_cast<uint64_t>(value));
}
OpIndex WordConstant(uint64_t value, MachineRepresentation rep) {
OpIndex WordConstant(uint64_t value, WordRepresentation rep) {
switch (rep) {
case MachineRepresentation::kWord32:
DCHECK(value <= MaxUnsignedValue(MachineRepresentation::kWord32));
case WordRepresentation::Word32():
DCHECK(value <= WordRepresentation::Word32().MaxUnsignedValue());
return Word32Constant(static_cast<uint32_t>(value));
case MachineRepresentation::kWord64:
case WordRepresentation::Word64():
return Word64Constant(value);
default:
UNREACHABLE();
}
}
OpIndex Float32Constant(float value) {
@ -287,14 +377,12 @@ class AssemblerInterface : public Superclass {
OpIndex Float64Constant(double value) {
return subclass().Constant(ConstantOp::Kind::kFloat64, value);
}
OpIndex FloatConstant(double value, MachineRepresentation rep) {
OpIndex FloatConstant(double value, FloatRepresentation rep) {
switch (rep) {
case MachineRepresentation::kFloat32:
case FloatRepresentation::Float32():
return Float32Constant(static_cast<float>(value));
case MachineRepresentation::kFloat64:
case FloatRepresentation::Float64():
return Float64Constant(value);
default:
UNREACHABLE();
}
}
OpIndex NumberConstant(double value) {
@ -317,8 +405,8 @@ class AssemblerInterface : public Superclass {
#define DECL_CHANGE(name, kind, from, to) \
OpIndex name(OpIndex input) { \
return subclass().Change(input, ChangeOp::Kind::k##kind, \
MachineRepresentation::k##from, \
MachineRepresentation::k##to); \
RegisterRepresentation::from(), \
RegisterRepresentation::to()); \
}
DECL_CHANGE(BitcastWord32ToWord64, Bitcast, Word32, Word64)
@ -388,7 +476,7 @@ class Assembler
current_operation_origin_ = operation_origin;
}
OpIndex Phi(base::Vector<const OpIndex> inputs, MachineRepresentation rep) {
OpIndex Phi(base::Vector<const OpIndex> inputs, RegisterRepresentation rep) {
DCHECK(current_block()->IsMerge() &&
inputs.size() == current_block()->Predecessors().size());
return Base::Phi(inputs, rep);

View File

@ -77,21 +77,22 @@ void DecompressionAnalyzer::ProcessOperation(const Operation& op) {
case Opcode::kStore: {
auto& store = op.Cast<StoreOp>();
MarkAsNeedsDecompression(store.base());
if (!IsAnyTagged(store.stored_rep))
if (!store.stored_rep.IsTagged()) {
MarkAsNeedsDecompression(store.value());
}
break;
}
case Opcode::kIndexedStore: {
auto& store = op.Cast<IndexedStoreOp>();
MarkAsNeedsDecompression(store.base());
MarkAsNeedsDecompression(store.index());
if (!IsAnyTagged(store.stored_rep))
if (!store.stored_rep.IsTagged()) {
MarkAsNeedsDecompression(store.value());
}
break;
}
case Opcode::kFrameState:
// The deopt code knows how to handle Compressed inputs, both
// MachineRepresentation kCompressed values and CompressedHeapConstants.
// The deopt code knows how to handle compressed inputs.
break;
case Opcode::kPhi: {
// Replicate the phi's state for its inputs.
@ -107,7 +108,7 @@ void DecompressionAnalyzer::ProcessOperation(const Operation& op) {
}
case Opcode::kEqual: {
auto& equal = op.Cast<EqualOp>();
if (equal.rep == MachineRepresentation::kWord64) {
if (equal.rep == WordRepresentation::Word64()) {
MarkAsNeedsDecompression(equal.left());
MarkAsNeedsDecompression(equal.right());
}
@ -115,7 +116,7 @@ void DecompressionAnalyzer::ProcessOperation(const Operation& op) {
}
case Opcode::kComparison: {
auto& comp = op.Cast<ComparisonOp>();
if (comp.rep == MachineRepresentation::kWord64) {
if (comp.rep == WordRepresentation::Word64()) {
MarkAsNeedsDecompression(comp.left());
MarkAsNeedsDecompression(comp.right());
}
@ -123,7 +124,7 @@ void DecompressionAnalyzer::ProcessOperation(const Operation& op) {
}
case Opcode::kWordBinop: {
auto& binary_op = op.Cast<WordBinopOp>();
if (binary_op.rep == MachineRepresentation::kWord64) {
if (binary_op.rep == WordRepresentation::Word64()) {
MarkAsNeedsDecompression(binary_op.left());
MarkAsNeedsDecompression(binary_op.right());
}
@ -131,15 +132,14 @@ void DecompressionAnalyzer::ProcessOperation(const Operation& op) {
}
case Opcode::kShift: {
auto& shift_op = op.Cast<ShiftOp>();
if (shift_op.rep == MachineRepresentation::kWord64) {
if (shift_op.rep == WordRepresentation::Word64()) {
MarkAsNeedsDecompression(shift_op.left());
}
break;
}
case Opcode::kChange: {
auto& change = op.Cast<ChangeOp>();
if (change.to == MachineRepresentation::kWord64 &&
NeedsDecompression(op)) {
if (change.to == WordRepresentation::Word64() && NeedsDecompression(op)) {
MarkAsNeedsDecompression(change.input());
}
break;
@ -187,28 +187,28 @@ void RunDecompressionOptimization(Graph& graph, Zone* phase_zone) {
}
case Opcode::kPhi: {
auto& phi = op.Cast<PhiOp>();
if (phi.rep == MachineRepresentation::kTagged) {
phi.rep = MachineRepresentation::kCompressed;
} else if (phi.rep == MachineRepresentation::kTaggedPointer) {
phi.rep = MachineRepresentation::kCompressedPointer;
if (phi.rep == RegisterRepresentation::Tagged()) {
phi.rep = RegisterRepresentation::Tagged();
}
break;
}
case Opcode::kLoad: {
auto& load = op.Cast<LoadOp>();
if (load.loaded_rep == MachineType::AnyTagged()) {
load.loaded_rep = MachineType::AnyCompressed();
} else if (load.loaded_rep == MachineType::TaggedPointer()) {
load.loaded_rep = MachineType::CompressedPointer();
if (load.loaded_rep.IsTagged()) {
DCHECK_EQ(load.result_rep,
any_of(RegisterRepresentation::Tagged(),
RegisterRepresentation::Compressed()));
load.result_rep = RegisterRepresentation::Compressed();
}
break;
}
case Opcode::kIndexedLoad: {
auto& load = op.Cast<IndexedLoadOp>();
if (load.loaded_rep == MachineType::AnyTagged()) {
load.loaded_rep = MachineType::AnyCompressed();
} else if (load.loaded_rep == MachineType::TaggedPointer()) {
load.loaded_rep = MachineType::CompressedPointer();
if (load.loaded_rep.IsTagged()) {
DCHECK_EQ(load.result_rep,
any_of(RegisterRepresentation::Tagged(),
RegisterRepresentation::Compressed()));
load.result_rep = RegisterRepresentation::Compressed();
}
break;
}

View File

@ -287,7 +287,9 @@ OpIndex GraphBuilder::Process(
case IrOpcode::kPhi: {
int input_count = op->ValueInputCount();
MachineRepresentation rep = PhiRepresentationOf(op);
RegisterRepresentation rep =
RegisterRepresentation::FromMachineRepresentation(
PhiRepresentationOf(op));
if (assembler.current_block()->IsLoop()) {
DCHECK_EQ(input_count, 2);
return assembler.PendingLoopPhi(Map(node->InputAt(0)), rep,
@ -405,9 +407,9 @@ OpIndex GraphBuilder::Process(
case IrOpcode::kWord64Sar:
case IrOpcode::kWord32Sar: {
MachineRepresentation rep = opcode == IrOpcode::kWord64Sar
? MachineRepresentation::kWord64
: MachineRepresentation::kWord32;
WordRepresentation rep = opcode == IrOpcode::kWord64Sar
? WordRepresentation::Word64()
: WordRepresentation::Word32();
ShiftOp::Kind kind;
switch (ShiftKindOf(op)) {
case ShiftKind::kShiftOutZeros:
@ -463,8 +465,8 @@ OpIndex GraphBuilder::Process(
#define CHANGE_CASE(opcode, kind, from, to) \
case IrOpcode::k##opcode: \
return assembler.Change(Map(node->InputAt(0)), ChangeOp::Kind::k##kind, \
MachineRepresentation::k##from, \
MachineRepresentation::k##to);
RegisterRepresentation::from(), \
RegisterRepresentation::to());
CHANGE_CASE(BitcastWord32ToWord64, Bitcast, Word32, Word64)
CHANGE_CASE(BitcastFloat32ToInt32, Bitcast, Float32, Word32)
@ -501,8 +503,8 @@ OpIndex GraphBuilder::Process(
break;
}
return assembler.Change(Map(node->InputAt(0)), kind,
MachineRepresentation::kFloat64,
MachineRepresentation::kWord64);
RegisterRepresentation::Float64(),
RegisterRepresentation::Word64());
}
case IrOpcode::kFloat64InsertLowWord32:
@ -516,16 +518,18 @@ OpIndex GraphBuilder::Process(
case IrOpcode::kBitcastTaggedToWord:
return assembler.TaggedBitcast(Map(node->InputAt(0)),
MachineRepresentation::kTagged,
MachineType::PointerRepresentation());
RegisterRepresentation::Tagged(),
RegisterRepresentation::PointerSized());
case IrOpcode::kBitcastWordToTagged:
return assembler.TaggedBitcast(Map(node->InputAt(0)),
MachineType::PointerRepresentation(),
MachineRepresentation::kTagged);
RegisterRepresentation::PointerSized(),
RegisterRepresentation::Tagged());
case IrOpcode::kLoad:
case IrOpcode::kUnalignedLoad: {
MachineType loaded_rep = LoadRepresentationOf(op);
MemoryRepresentation loaded_rep =
MemoryRepresentation::FromMachineType(LoadRepresentationOf(op));
RegisterRepresentation result_rep = loaded_rep.ToRegisterRepresentation();
Node* base = node->InputAt(0);
Node* index = node->InputAt(1);
LoadOp::Kind kind = opcode == IrOpcode::kLoad
@ -533,19 +537,19 @@ OpIndex GraphBuilder::Process(
: LoadOp::Kind::kRawUnaligned;
if (index->opcode() == IrOpcode::kInt32Constant) {
int32_t offset = OpParameter<int32_t>(index->op());
return assembler.Load(Map(base), kind, loaded_rep, offset);
return assembler.Load(Map(base), kind, loaded_rep, result_rep, offset);
}
if (index->opcode() == IrOpcode::kInt64Constant) {
int64_t offset = OpParameter<int64_t>(index->op());
if (base::IsValueInRangeForNumericType<int32_t>(offset)) {
return assembler.Load(Map(base), kind, loaded_rep,
return assembler.Load(Map(base), kind, loaded_rep, result_rep,
static_cast<int32_t>(offset));
}
}
int32_t offset = 0;
uint8_t element_size_log2 = 0;
return assembler.IndexedLoad(Map(base), Map(index), kind, loaded_rep,
offset, element_size_log2);
result_rep, offset, element_size_log2);
}
case IrOpcode::kStore:
@ -563,21 +567,26 @@ OpIndex GraphBuilder::Process(
if (index->opcode() == IrOpcode::kInt32Constant) {
int32_t offset = OpParameter<int32_t>(index->op());
return assembler.Store(Map(base), Map(value), kind,
store_rep.representation(),
MemoryRepresentation::FromMachineRepresentation(
store_rep.representation()),
store_rep.write_barrier_kind(), offset);
}
if (index->opcode() == IrOpcode::kInt64Constant) {
int64_t offset = OpParameter<int64_t>(index->op());
if (base::IsValueInRangeForNumericType<int32_t>(offset)) {
return assembler.Store(
Map(base), Map(value), kind, store_rep.representation(),
Map(base), Map(value), kind,
MemoryRepresentation::FromMachineRepresentation(
store_rep.representation()),
store_rep.write_barrier_kind(), static_cast<int32_t>(offset));
}
}
int32_t offset = 0;
uint8_t element_size_log2 = 0;
return assembler.IndexedStore(
Map(base), Map(index), Map(value), kind, store_rep.representation(),
Map(base), Map(index), Map(value), kind,
MemoryRepresentation::FromMachineRepresentation(
store_rep.representation()),
store_rep.write_barrier_kind(), offset, element_size_log2);
}

View File

@ -100,26 +100,34 @@ std::ostream& operator<<(std::ostream& os, FloatUnaryOp::Kind kind) {
}
// static
bool FloatUnaryOp::IsSupported(Kind kind, MachineRepresentation rep) {
switch (kind) {
case Kind::kRoundDown:
return rep == MachineRepresentation::kFloat32
? SupportedOperations::float32_round_down()
: SupportedOperations::float64_round_down();
case Kind::kRoundUp:
return rep == MachineRepresentation::kFloat32
? SupportedOperations::float32_round_up()
: SupportedOperations::float64_round_up();
case Kind::kRoundToZero:
return rep == MachineRepresentation::kFloat32
? SupportedOperations::float32_round_to_zero()
: SupportedOperations::float64_round_to_zero();
case Kind::kRoundTiesEven:
return rep == MachineRepresentation::kFloat32
? SupportedOperations::float32_round_ties_even()
: SupportedOperations::float64_round_ties_even();
default:
return true;
bool FloatUnaryOp::IsSupported(Kind kind, FloatRepresentation rep) {
switch (rep) {
case FloatRepresentation::Float32():
switch (kind) {
case Kind::kRoundDown:
return SupportedOperations::float32_round_down();
case Kind::kRoundUp:
return SupportedOperations::float32_round_up();
case Kind::kRoundToZero:
return SupportedOperations::float32_round_to_zero();
case Kind::kRoundTiesEven:
return SupportedOperations::float32_round_ties_even();
default:
return true;
}
case FloatRepresentation::Float64():
switch (kind) {
case Kind::kRoundDown:
return SupportedOperations::float64_round_down();
case Kind::kRoundUp:
return SupportedOperations::float64_round_up();
case Kind::kRoundToZero:
return SupportedOperations::float64_round_to_zero();
case Kind::kRoundTiesEven:
return SupportedOperations::float64_round_ties_even();
default:
return true;
}
}
}

View File

@ -25,6 +25,7 @@
#include "src/common/globals.h"
#include "src/compiler/globals.h"
#include "src/compiler/turboshaft/fast-hash.h"
#include "src/compiler/turboshaft/representations.h"
#include "src/compiler/turboshaft/utils.h"
#include "src/compiler/write-barrier-kind.h"
#include "src/zone/zone.h"
@ -562,7 +563,7 @@ struct WordBinopOp : FixedArityOperationT<2, WordBinopOp> {
kUnsignedMod,
};
Kind kind;
MachineRepresentation rep;
WordRepresentation rep;
static constexpr OpProperties properties = OpProperties::Pure();
@ -588,10 +589,7 @@ struct WordBinopOp : FixedArityOperationT<2, WordBinopOp> {
}
}
static bool IsAssociative(Kind kind, MachineRepresentation rep) {
if (IsFloatingPoint(rep)) {
return false;
}
static bool IsAssociative(Kind kind) {
switch (kind) {
case Kind::kAdd:
case Kind::kMul:
@ -630,13 +628,11 @@ struct WordBinopOp : FixedArityOperationT<2, WordBinopOp> {
}
}
WordBinopOp(OpIndex left, OpIndex right, Kind kind, MachineRepresentation rep)
WordBinopOp(OpIndex left, OpIndex right, Kind kind, WordRepresentation rep)
: Base(left, right), kind(kind), rep(rep) {
DCHECK_EQ(rep, any_of(MachineRepresentation::kWord32,
MachineRepresentation::kWord64));
DCHECK_IMPLIES(kind == any_of(Kind::kSignedMulOverflownBits,
Kind::kUnsignedMulOverflownBits),
rep == MachineRepresentation::kWord32);
rep == WordRepresentation::Word32());
}
auto options() const { return std::tuple{kind, rep}; }
void PrintOptions(std::ostream& os) const;
@ -655,7 +651,7 @@ struct FloatBinopOp : FixedArityOperationT<2, FloatBinopOp> {
kAtan2,
};
Kind kind;
MachineRepresentation rep;
FloatRepresentation rep;
static constexpr OpProperties properties = OpProperties::Pure();
@ -678,13 +674,10 @@ struct FloatBinopOp : FixedArityOperationT<2, FloatBinopOp> {
}
}
FloatBinopOp(OpIndex left, OpIndex right, Kind kind,
MachineRepresentation rep)
FloatBinopOp(OpIndex left, OpIndex right, Kind kind, FloatRepresentation rep)
: Base(left, right), kind(kind), rep(rep) {
DCHECK_EQ(rep, any_of(MachineRepresentation::kFloat32,
MachineRepresentation::kFloat64));
DCHECK_IMPLIES(kind == any_of(Kind::kPower, Kind::kAtan2, Kind::kMod),
rep == MachineRepresentation::kFloat64);
rep == FloatRepresentation::Float64());
}
auto options() const { return std::tuple{kind, rep}; }
void PrintOptions(std::ostream& os) const;
@ -698,7 +691,7 @@ struct OverflowCheckedBinopOp
kSignedSub,
};
Kind kind;
MachineRepresentation rep;
WordRepresentation rep;
static constexpr OpProperties properties = OpProperties::Pure();
@ -716,9 +709,9 @@ struct OverflowCheckedBinopOp
}
OverflowCheckedBinopOp(OpIndex left, OpIndex right, Kind kind,
MachineRepresentation rep)
WordRepresentation rep)
: Base(left, right), kind(kind), rep(rep) {
DCHECK_EQ(rep, MachineRepresentation::kWord32);
DCHECK_EQ(rep, WordRepresentation::Word32());
}
auto options() const { return std::tuple{kind, rep}; }
void PrintOptions(std::ostream& os) const;
@ -730,16 +723,13 @@ struct WordUnaryOp : FixedArityOperationT<1, WordUnaryOp> {
kCountLeadingZeros,
};
Kind kind;
MachineRepresentation rep;
WordRepresentation rep;
static constexpr OpProperties properties = OpProperties::Pure();
OpIndex input() const { return Base::input(0); }
explicit WordUnaryOp(OpIndex input, Kind kind, MachineRepresentation rep)
: Base(input), kind(kind), rep(rep) {
DCHECK_EQ(rep, any_of(MachineRepresentation::kWord32,
MachineRepresentation::kWord64));
}
explicit WordUnaryOp(OpIndex input, Kind kind, WordRepresentation rep)
: Base(input), kind(kind), rep(rep) {}
auto options() const { return std::tuple{kind, rep}; }
};
std::ostream& operator<<(std::ostream& os, WordUnaryOp::Kind kind);
@ -769,17 +759,15 @@ struct FloatUnaryOp : FixedArityOperationT<1, FloatUnaryOp> {
kTanh,
};
Kind kind;
MachineRepresentation rep;
FloatRepresentation rep;
static constexpr OpProperties properties = OpProperties::Pure();
OpIndex input() const { return Base::input(0); }
static bool IsSupported(Kind kind, MachineRepresentation rep);
static bool IsSupported(Kind kind, FloatRepresentation rep);
explicit FloatUnaryOp(OpIndex input, Kind kind, MachineRepresentation rep)
explicit FloatUnaryOp(OpIndex input, Kind kind, FloatRepresentation rep)
: Base(input), kind(kind), rep(rep) {
DCHECK_EQ(rep, any_of(MachineRepresentation::kFloat32,
MachineRepresentation::kFloat64));
DCHECK(IsSupported(kind, rep));
}
auto options() const { return std::tuple{kind, rep}; }
@ -796,7 +784,7 @@ struct ShiftOp : FixedArityOperationT<2, ShiftOp> {
kRotateLeft
};
Kind kind;
MachineRepresentation rep;
WordRepresentation rep;
static constexpr OpProperties properties = OpProperties::Pure();
@ -830,29 +818,26 @@ struct ShiftOp : FixedArityOperationT<2, ShiftOp> {
}
}
ShiftOp(OpIndex left, OpIndex right, Kind kind, MachineRepresentation rep)
: Base(left, right), kind(kind), rep(rep) {
DCHECK_EQ(rep, any_of(MachineRepresentation::kWord32,
MachineRepresentation::kWord64));
}
ShiftOp(OpIndex left, OpIndex right, Kind kind, WordRepresentation rep)
: Base(left, right), kind(kind), rep(rep) {}
auto options() const { return std::tuple{kind, rep}; }
};
std::ostream& operator<<(std::ostream& os, ShiftOp::Kind kind);
struct EqualOp : FixedArityOperationT<2, EqualOp> {
MachineRepresentation rep;
RegisterRepresentation rep;
static constexpr OpProperties properties = OpProperties::Pure();
OpIndex left() const { return input(0); }
OpIndex right() const { return input(1); }
EqualOp(OpIndex left, OpIndex right, MachineRepresentation rep)
EqualOp(OpIndex left, OpIndex right, RegisterRepresentation rep)
: Base(left, right), rep(rep) {
DCHECK(rep == MachineRepresentation::kWord32 ||
rep == MachineRepresentation::kWord64 ||
rep == MachineRepresentation::kFloat32 ||
rep == MachineRepresentation::kFloat64);
DCHECK(rep == any_of(RegisterRepresentation::Word32(),
RegisterRepresentation::Word64(),
RegisterRepresentation::Float32(),
RegisterRepresentation::Float64()));
}
auto options() const { return std::tuple{rep}; }
};
@ -865,7 +850,7 @@ struct ComparisonOp : FixedArityOperationT<2, ComparisonOp> {
kUnsignedLessThanOrEqual
};
Kind kind;
MachineRepresentation rep;
RegisterRepresentation rep;
static constexpr OpProperties properties = OpProperties::Pure();
@ -873,12 +858,12 @@ struct ComparisonOp : FixedArityOperationT<2, ComparisonOp> {
OpIndex right() const { return input(1); }
ComparisonOp(OpIndex left, OpIndex right, Kind kind,
MachineRepresentation rep)
RegisterRepresentation rep)
: Base(left, right), kind(kind), rep(rep) {
DCHECK_EQ(rep, any_of(MachineRepresentation::kWord32,
MachineRepresentation::kWord64,
MachineRepresentation::kFloat32,
MachineRepresentation::kFloat64));
DCHECK_EQ(rep, any_of(RegisterRepresentation::Word32(),
RegisterRepresentation::Word64(),
RegisterRepresentation::Float32(),
RegisterRepresentation::Float64()));
}
auto options() const { return std::tuple{kind, rep}; }
};
@ -915,15 +900,15 @@ struct ChangeOp : FixedArityOperationT<1, ChangeOp> {
kBitcast
};
Kind kind;
MachineRepresentation from;
MachineRepresentation to;
RegisterRepresentation from;
RegisterRepresentation to;
static constexpr OpProperties properties = OpProperties::Pure();
OpIndex input() const { return Base::input(0); }
ChangeOp(OpIndex input, Kind kind, MachineRepresentation from,
MachineRepresentation to)
ChangeOp(OpIndex input, Kind kind, RegisterRepresentation from,
RegisterRepresentation to)
: Base(input), kind(kind), from(from), to(to) {}
auto options() const { return std::tuple{kind, from, to}; }
};
@ -946,28 +931,28 @@ struct Float64InsertWord32Op : FixedArityOperationT<2, Float64InsertWord32Op> {
std::ostream& operator<<(std::ostream& os, Float64InsertWord32Op::Kind kind);
struct TaggedBitcastOp : FixedArityOperationT<1, TaggedBitcastOp> {
MachineRepresentation from;
MachineRepresentation to;
RegisterRepresentation from;
RegisterRepresentation to;
// Due to moving GC, converting from or to pointers doesn't commute with GC.
static constexpr OpProperties properties = OpProperties::Reading();
OpIndex input() const { return Base::input(0); }
TaggedBitcastOp(OpIndex input, MachineRepresentation from,
MachineRepresentation to)
TaggedBitcastOp(OpIndex input, RegisterRepresentation from,
RegisterRepresentation to)
: Base(input), from(from), to(to) {}
auto options() const { return std::tuple{from, to}; }
};
struct PhiOp : OperationT<PhiOp> {
MachineRepresentation rep;
RegisterRepresentation rep;
static constexpr OpProperties properties = OpProperties::Pure();
static constexpr size_t kLoopPhiBackEdgeIndex = 1;
explicit PhiOp(base::Vector<const OpIndex> inputs, MachineRepresentation rep)
explicit PhiOp(base::Vector<const OpIndex> inputs, RegisterRepresentation rep)
: Base(inputs), rep(rep) {}
auto options() const { return std::tuple{rep}; }
};
@ -975,7 +960,7 @@ struct PhiOp : OperationT<PhiOp> {
// Only used when moving a loop phi to a new graph while the loop backedge has
// not been emitted yet.
struct PendingLoopPhiOp : FixedArityOperationT<1, PendingLoopPhiOp> {
MachineRepresentation rep;
RegisterRepresentation rep;
union {
// Used when transforming a Turboshaft graph.
// This is not an input because it refers to the old graph.
@ -988,12 +973,12 @@ struct PendingLoopPhiOp : FixedArityOperationT<1, PendingLoopPhiOp> {
OpIndex first() const { return input(0); }
PendingLoopPhiOp(OpIndex first, MachineRepresentation rep,
PendingLoopPhiOp(OpIndex first, RegisterRepresentation rep,
OpIndex old_backedge_index)
: Base(first), rep(rep), old_backedge_index(old_backedge_index) {
DCHECK(old_backedge_index.valid());
}
PendingLoopPhiOp(OpIndex first, MachineRepresentation rep,
PendingLoopPhiOp(OpIndex first, RegisterRepresentation rep,
Node* old_backedge_node)
: Base(first), rep(rep), old_backedge_node(old_backedge_node) {}
std::tuple<> options() const { UNREACHABLE(); }
@ -1030,24 +1015,24 @@ struct ConstantOp : FixedArityOperationT<0, ConstantOp> {
static constexpr OpProperties properties = OpProperties::Pure();
MachineRepresentation Representation() const {
RegisterRepresentation Representation() const {
switch (kind) {
case Kind::kWord32:
return MachineRepresentation::kWord32;
return RegisterRepresentation::Word32();
case Kind::kWord64:
return MachineRepresentation::kWord64;
return RegisterRepresentation::Word64();
case Kind::kFloat32:
return MachineRepresentation::kFloat32;
return RegisterRepresentation::Float32();
case Kind::kFloat64:
return MachineRepresentation::kFloat64;
return RegisterRepresentation::Float64();
case Kind::kExternal:
case Kind::kTaggedIndex:
return MachineType::PointerRepresentation();
return RegisterRepresentation::PointerSized();
case Kind::kHeapObject:
case Kind::kNumber:
return MachineRepresentation::kTagged;
return RegisterRepresentation::Tagged();
case Kind::kCompressedHeapObject:
return MachineRepresentation::kCompressed;
return RegisterRepresentation::Compressed();
}
}
@ -1055,7 +1040,7 @@ struct ConstantOp : FixedArityOperationT<0, ConstantOp> {
: Base(), kind(kind), storage(storage) {
DCHECK_IMPLIES(
kind == Kind::kWord32,
storage.integral <= MaxUnsignedValue(MachineRepresentation::kWord32));
storage.integral <= WordRepresentation::Word32().MaxUnsignedValue());
}
uint64_t integral() const {
@ -1217,20 +1202,34 @@ struct ConstantOp : FixedArityOperationT<0, ConstantOp> {
// For Kind::tagged_base: subtract kHeapObjectTag,
// `base` has to be the object start.
// For (u)int8/16, the value will be sign- or zero-extended to Word32.
// When result_rep is RegisterRepresentation::Compressed(), then the load does
// not decompress the value.
struct LoadOp : FixedArityOperationT<1, LoadOp> {
enum class Kind { kTaggedBase, kRawAligned, kRawUnaligned };
enum class Kind : uint8_t { kTaggedBase, kRawAligned, kRawUnaligned };
Kind kind;
MachineType loaded_rep;
MemoryRepresentation loaded_rep;
RegisterRepresentation result_rep;
int32_t offset;
static constexpr OpProperties properties = OpProperties::Reading();
OpIndex base() const { return input(0); }
LoadOp(OpIndex base, Kind kind, MachineType loaded_rep, int32_t offset)
: Base(base), kind(kind), loaded_rep(loaded_rep), offset(offset) {}
LoadOp(OpIndex base, Kind kind, MemoryRepresentation loaded_rep,
RegisterRepresentation result_rep, int32_t offset)
: Base(base),
kind(kind),
loaded_rep(loaded_rep),
result_rep(result_rep),
offset(offset) {
DCHECK(loaded_rep.ToRegisterRepresentation() == result_rep ||
(loaded_rep.IsTagged() &&
result_rep == RegisterRepresentation::Compressed()));
}
void PrintOptions(std::ostream& os) const;
auto options() const { return std::tuple{kind, loaded_rep, offset}; }
auto options() const {
return std::tuple{kind, loaded_rep, result_rep, offset};
}
};
inline bool IsAlignedAccess(LoadOp::Kind kind) {
@ -1247,10 +1246,13 @@ inline bool IsAlignedAccess(LoadOp::Kind kind) {
// For Kind::tagged_base: subtract kHeapObjectTag,
// `base` has to be the object start.
// For (u)int8/16, the value will be sign- or zero-extended to Word32.
// When result_rep is RegisterRepresentation::Compressed(), then the load does
// not decompress the value.
struct IndexedLoadOp : FixedArityOperationT<2, IndexedLoadOp> {
using Kind = LoadOp::Kind;
Kind kind;
MachineType loaded_rep;
MemoryRepresentation loaded_rep;
RegisterRepresentation result_rep;
uint8_t element_size_log2; // multiply index with 2^element_size_log2
int32_t offset; // add offset to scaled index
@ -1259,13 +1261,20 @@ struct IndexedLoadOp : FixedArityOperationT<2, IndexedLoadOp> {
OpIndex base() const { return input(0); }
OpIndex index() const { return input(1); }
IndexedLoadOp(OpIndex base, OpIndex index, Kind kind, MachineType loaded_rep,
int32_t offset, uint8_t element_size_log2)
IndexedLoadOp(OpIndex base, OpIndex index, Kind kind,
MemoryRepresentation loaded_rep,
RegisterRepresentation result_rep, int32_t offset,
uint8_t element_size_log2)
: Base(base, index),
kind(kind),
loaded_rep(loaded_rep),
result_rep(result_rep),
element_size_log2(element_size_log2),
offset(offset) {}
offset(offset) {
DCHECK(loaded_rep.ToRegisterRepresentation() == result_rep ||
(loaded_rep.IsTagged() &&
result_rep == RegisterRepresentation::Compressed()));
}
void PrintOptions(std::ostream& os) const;
auto options() const {
return std::tuple{kind, loaded_rep, offset, element_size_log2};
@ -1278,7 +1287,7 @@ struct IndexedLoadOp : FixedArityOperationT<2, IndexedLoadOp> {
struct StoreOp : FixedArityOperationT<2, StoreOp> {
using Kind = LoadOp::Kind;
Kind kind;
MachineRepresentation stored_rep;
MemoryRepresentation stored_rep;
WriteBarrierKind write_barrier;
int32_t offset;
@ -1288,7 +1297,7 @@ struct StoreOp : FixedArityOperationT<2, StoreOp> {
OpIndex value() const { return input(1); }
StoreOp(OpIndex base, OpIndex value, Kind kind,
MachineRepresentation stored_rep, WriteBarrierKind write_barrier,
MemoryRepresentation stored_rep, WriteBarrierKind write_barrier,
int32_t offset)
: Base(base, value),
kind(kind),
@ -1307,7 +1316,7 @@ struct StoreOp : FixedArityOperationT<2, StoreOp> {
struct IndexedStoreOp : FixedArityOperationT<3, IndexedStoreOp> {
using Kind = StoreOp::Kind;
Kind kind;
MachineRepresentation stored_rep;
MemoryRepresentation stored_rep;
WriteBarrierKind write_barrier;
uint8_t element_size_log2; // multiply index with 2^element_size_log2
int32_t offset; // add offset to scaled index
@ -1319,7 +1328,7 @@ struct IndexedStoreOp : FixedArityOperationT<3, IndexedStoreOp> {
OpIndex value() const { return input(2); }
IndexedStoreOp(OpIndex base, OpIndex index, OpIndex value, Kind kind,
MachineRepresentation stored_rep,
MemoryRepresentation stored_rep,
WriteBarrierKind write_barrier, int32_t offset,
uint8_t element_size_log2)
: Base(base, index, value),

View File

@ -445,12 +445,12 @@ struct OptimizationPhase<Analyzer, Assembler>::Impl {
}
OpIndex ReduceLoad(const LoadOp& op) {
return assembler.Load(MapToNewGraph(op.base()), op.kind, op.loaded_rep,
op.offset);
op.result_rep, op.offset);
}
OpIndex ReduceIndexedLoad(const IndexedLoadOp& op) {
return assembler.IndexedLoad(
MapToNewGraph(op.base()), MapToNewGraph(op.index()), op.kind,
op.loaded_rep, op.offset, op.element_size_log2);
op.loaded_rep, op.result_rep, op.offset, op.element_size_log2);
}
OpIndex ReduceStore(const StoreOp& op) {
return assembler.Store(MapToNewGraph(op.base()), MapToNewGraph(op.value()),

View File

@ -169,7 +169,7 @@ Node* ScheduleBuilder::ProcessOperation(const WordBinopOp& op) {
using Kind = WordBinopOp::Kind;
const Operator* o;
switch (op.rep) {
case MachineRepresentation::kWord32:
case WordRepresentation::Word32():
switch (op.kind) {
case Kind::kAdd:
o = machine.Int32Add();
@ -209,7 +209,7 @@ Node* ScheduleBuilder::ProcessOperation(const WordBinopOp& op) {
break;
}
break;
case MachineRepresentation::kWord64:
case WordRepresentation::Word64():
switch (op.kind) {
case Kind::kAdd:
o = machine.Int64Add();
@ -255,7 +255,7 @@ Node* ScheduleBuilder::ProcessOperation(const FloatBinopOp& op) {
using Kind = FloatBinopOp::Kind;
const Operator* o;
switch (op.rep) {
case MachineRepresentation::kFloat32:
case FloatRepresentation::Float32():
switch (op.kind) {
case Kind::kAdd:
o = machine.Float32Add();
@ -281,7 +281,7 @@ Node* ScheduleBuilder::ProcessOperation(const FloatBinopOp& op) {
UNREACHABLE();
}
break;
case MachineRepresentation::kFloat64:
case FloatRepresentation::Float64():
switch (op.kind) {
case Kind::kAdd:
o = machine.Float64Add();
@ -321,7 +321,7 @@ Node* ScheduleBuilder::ProcessOperation(const FloatBinopOp& op) {
Node* ScheduleBuilder::ProcessOperation(const OverflowCheckedBinopOp& op) {
const Operator* o;
switch (op.rep) {
case MachineRepresentation::kWord32:
case WordRepresentation::Word32():
switch (op.kind) {
case OverflowCheckedBinopOp::Kind::kSignedAdd:
o = machine.Int32AddWithOverflow();
@ -334,7 +334,7 @@ Node* ScheduleBuilder::ProcessOperation(const OverflowCheckedBinopOp& op) {
break;
}
break;
case MachineRepresentation::kWord64:
case WordRepresentation::Word64():
switch (op.kind) {
case OverflowCheckedBinopOp::Kind::kSignedAdd:
o = machine.Int64AddWithOverflow();
@ -352,9 +352,9 @@ Node* ScheduleBuilder::ProcessOperation(const OverflowCheckedBinopOp& op) {
return AddNode(o, {GetNode(op.left()), GetNode(op.right())});
}
Node* ScheduleBuilder::ProcessOperation(const WordUnaryOp& op) {
DCHECK(op.rep == MachineRepresentation::kWord32 ||
op.rep == MachineRepresentation::kWord64);
bool word64 = op.rep == MachineRepresentation::kWord64;
DCHECK(op.rep == WordRepresentation::Word32() ||
op.rep == WordRepresentation::Word64());
bool word64 = op.rep == WordRepresentation::Word64();
const Operator* o;
switch (op.kind) {
case WordUnaryOp::Kind::kReverseBytes:
@ -367,9 +367,9 @@ Node* ScheduleBuilder::ProcessOperation(const WordUnaryOp& op) {
return AddNode(o, {GetNode(op.input())});
}
Node* ScheduleBuilder::ProcessOperation(const FloatUnaryOp& op) {
DCHECK(op.rep == MachineRepresentation::kFloat32 ||
op.rep == MachineRepresentation::kFloat64);
bool float64 = op.rep == MachineRepresentation::kFloat64;
DCHECK(op.rep == FloatRepresentation::Float32() ||
op.rep == FloatRepresentation::Float64());
bool float64 = op.rep == FloatRepresentation::Float64();
const Operator* o;
switch (op.kind) {
case FloatUnaryOp::Kind::kAbs:
@ -398,68 +398,68 @@ Node* ScheduleBuilder::ProcessOperation(const FloatUnaryOp& op) {
o = float64 ? machine.Float64Sqrt() : machine.Float32Sqrt();
break;
case FloatUnaryOp::Kind::kSilenceNaN:
DCHECK_EQ(op.rep, MachineRepresentation::kFloat64);
DCHECK_EQ(op.rep, FloatRepresentation::Float64());
o = machine.Float64SilenceNaN();
break;
case FloatUnaryOp::Kind::kLog:
DCHECK_EQ(op.rep, MachineRepresentation::kFloat64);
DCHECK_EQ(op.rep, FloatRepresentation::Float64());
o = machine.Float64Log();
break;
case FloatUnaryOp::Kind::kExp:
DCHECK_EQ(op.rep, MachineRepresentation::kFloat64);
DCHECK_EQ(op.rep, FloatRepresentation::Float64());
o = machine.Float64Exp();
break;
case FloatUnaryOp::Kind::kExpm1:
DCHECK_EQ(op.rep, MachineRepresentation::kFloat64);
DCHECK_EQ(op.rep, FloatRepresentation::Float64());
o = machine.Float64Expm1();
break;
case FloatUnaryOp::Kind::kSin:
DCHECK_EQ(op.rep, MachineRepresentation::kFloat64);
DCHECK_EQ(op.rep, FloatRepresentation::Float64());
o = machine.Float64Sin();
break;
case FloatUnaryOp::Kind::kCos:
DCHECK_EQ(op.rep, MachineRepresentation::kFloat64);
DCHECK_EQ(op.rep, FloatRepresentation::Float64());
o = machine.Float64Cos();
break;
case FloatUnaryOp::Kind::kAsin:
DCHECK_EQ(op.rep, MachineRepresentation::kFloat64);
DCHECK_EQ(op.rep, FloatRepresentation::Float64());
o = machine.Float64Asin();
break;
case FloatUnaryOp::Kind::kAcos:
DCHECK_EQ(op.rep, MachineRepresentation::kFloat64);
DCHECK_EQ(op.rep, FloatRepresentation::Float64());
o = machine.Float64Acos();
break;
case FloatUnaryOp::Kind::kSinh:
DCHECK_EQ(op.rep, MachineRepresentation::kFloat64);
DCHECK_EQ(op.rep, FloatRepresentation::Float64());
o = machine.Float64Sinh();
break;
case FloatUnaryOp::Kind::kCosh:
DCHECK_EQ(op.rep, MachineRepresentation::kFloat64);
DCHECK_EQ(op.rep, FloatRepresentation::Float64());
o = machine.Float64Cosh();
break;
case FloatUnaryOp::Kind::kAsinh:
DCHECK_EQ(op.rep, MachineRepresentation::kFloat64);
DCHECK_EQ(op.rep, FloatRepresentation::Float64());
o = machine.Float64Asinh();
break;
case FloatUnaryOp::Kind::kAcosh:
DCHECK_EQ(op.rep, MachineRepresentation::kFloat64);
DCHECK_EQ(op.rep, FloatRepresentation::Float64());
o = machine.Float64Acosh();
break;
case FloatUnaryOp::Kind::kTan:
DCHECK_EQ(op.rep, MachineRepresentation::kFloat64);
DCHECK_EQ(op.rep, FloatRepresentation::Float64());
o = machine.Float64Tan();
break;
case FloatUnaryOp::Kind::kTanh:
DCHECK_EQ(op.rep, MachineRepresentation::kFloat64);
DCHECK_EQ(op.rep, FloatRepresentation::Float64());
o = machine.Float64Tanh();
break;
}
return AddNode(o, {GetNode(op.input())});
}
Node* ScheduleBuilder::ProcessOperation(const ShiftOp& op) {
DCHECK(op.rep == MachineRepresentation::kWord32 ||
op.rep == MachineRepresentation::kWord64);
bool word64 = op.rep == MachineRepresentation::kWord64;
DCHECK(op.rep == WordRepresentation::Word32() ||
op.rep == WordRepresentation::Word64());
bool word64 = op.rep == WordRepresentation::Word64();
const Operator* o;
switch (op.kind) {
case ShiftOp::Kind::kShiftRightArithmeticShiftOutZeros:
@ -487,16 +487,16 @@ Node* ScheduleBuilder::ProcessOperation(const ShiftOp& op) {
Node* ScheduleBuilder::ProcessOperation(const EqualOp& op) {
const Operator* o;
switch (op.rep) {
case MachineRepresentation::kWord32:
case RegisterRepresentation::Word32():
o = machine.Word32Equal();
break;
case MachineRepresentation::kWord64:
case RegisterRepresentation::Word64():
o = machine.Word64Equal();
break;
case MachineRepresentation::kFloat32:
case RegisterRepresentation::Float32():
o = machine.Float32Equal();
break;
case MachineRepresentation::kFloat64:
case RegisterRepresentation::Float64():
o = machine.Float64Equal();
break;
default:
@ -507,7 +507,7 @@ Node* ScheduleBuilder::ProcessOperation(const EqualOp& op) {
Node* ScheduleBuilder::ProcessOperation(const ComparisonOp& op) {
const Operator* o;
switch (op.rep) {
case MachineRepresentation::kWord32:
case RegisterRepresentation::Word32():
switch (op.kind) {
case ComparisonOp::Kind::kSignedLessThan:
o = machine.Int32LessThan();
@ -523,7 +523,7 @@ Node* ScheduleBuilder::ProcessOperation(const ComparisonOp& op) {
break;
}
break;
case MachineRepresentation::kWord64:
case RegisterRepresentation::Word64():
switch (op.kind) {
case ComparisonOp::Kind::kSignedLessThan:
o = machine.Int64LessThan();
@ -539,7 +539,7 @@ Node* ScheduleBuilder::ProcessOperation(const ComparisonOp& op) {
break;
}
break;
case MachineRepresentation::kFloat32:
case RegisterRepresentation::Float32():
switch (op.kind) {
case ComparisonOp::Kind::kSignedLessThan:
o = machine.Float32LessThan();
@ -552,7 +552,7 @@ Node* ScheduleBuilder::ProcessOperation(const ComparisonOp& op) {
UNREACHABLE();
}
break;
case MachineRepresentation::kFloat64:
case RegisterRepresentation::Float64():
switch (op.kind) {
case ComparisonOp::Kind::kSignedLessThan:
o = machine.Float64LessThan();
@ -575,125 +575,125 @@ Node* ScheduleBuilder::ProcessOperation(const ChangeOp& op) {
switch (op.kind) {
using Kind = ChangeOp::Kind;
case Kind::kFloatConversion:
if (op.from == MachineRepresentation::kFloat64 &&
op.to == MachineRepresentation::kFloat32) {
if (op.from == FloatRepresentation::Float64() &&
op.to == FloatRepresentation::Float32()) {
o = machine.TruncateFloat64ToFloat32();
} else if (op.from == MachineRepresentation::kFloat32 &&
op.to == MachineRepresentation::kFloat64) {
} else if (op.from == FloatRepresentation::Float32() &&
op.to == FloatRepresentation::Float64()) {
o = machine.ChangeFloat32ToFloat64();
} else {
UNIMPLEMENTED();
}
break;
case Kind::kSignedFloatTruncate:
if (op.from == MachineRepresentation::kFloat64 &&
op.to == MachineRepresentation::kWord64) {
if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word64()) {
o = machine.TruncateFloat64ToInt64(TruncateKind::kArchitectureDefault);
} else if (op.from == MachineRepresentation::kFloat64 &&
op.to == MachineRepresentation::kWord32) {
} else if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word32()) {
o = machine.RoundFloat64ToInt32();
} else {
UNIMPLEMENTED();
}
break;
case Kind::kSignedFloatTruncateOverflowToMin:
if (op.from == MachineRepresentation::kFloat64 &&
op.to == MachineRepresentation::kWord64) {
if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word64()) {
o = machine.TruncateFloat64ToInt64(TruncateKind::kSetOverflowToMin);
} else {
UNIMPLEMENTED();
}
break;
case Kind::kJSFloatTruncate:
if (op.from == MachineRepresentation::kFloat64 &&
op.to == MachineRepresentation::kWord32) {
if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word32()) {
o = machine.TruncateFloat64ToWord32();
} else {
UNIMPLEMENTED();
}
break;
case Kind::kSignedToFloat:
if (op.from == MachineRepresentation::kWord32 &&
op.to == MachineRepresentation::kFloat64) {
if (op.from == WordRepresentation::Word32() &&
op.to == FloatRepresentation::Float64()) {
o = machine.ChangeInt32ToFloat64();
} else if (op.from == MachineRepresentation::kWord64 &&
op.to == MachineRepresentation::kFloat64) {
} else if (op.from == WordRepresentation::Word64() &&
op.to == FloatRepresentation::Float64()) {
o = machine.ChangeInt64ToFloat64();
} else {
UNIMPLEMENTED();
}
break;
case Kind::kUnsignedToFloat:
if (op.from == MachineRepresentation::kWord32 &&
op.to == MachineRepresentation::kFloat64) {
if (op.from == WordRepresentation::Word32() &&
op.to == FloatRepresentation::Float64()) {
o = machine.ChangeUint32ToFloat64();
} else {
UNIMPLEMENTED();
}
break;
case Kind::kExtractHighHalf:
DCHECK_EQ(op.from, MachineRepresentation::kFloat64);
DCHECK_EQ(op.to, MachineRepresentation::kWord32);
DCHECK_EQ(op.from, FloatRepresentation::Float64());
DCHECK_EQ(op.to, WordRepresentation::Word32());
o = machine.Float64ExtractHighWord32();
break;
case Kind::kExtractLowHalf:
DCHECK_EQ(op.from, MachineRepresentation::kFloat64);
DCHECK_EQ(op.to, MachineRepresentation::kWord32);
DCHECK_EQ(op.from, FloatRepresentation::Float64());
DCHECK_EQ(op.to, WordRepresentation::Word32());
o = machine.Float64ExtractLowWord32();
break;
case Kind::kBitcast:
if (op.from == MachineRepresentation::kWord32 &&
op.to == MachineRepresentation::kWord64) {
if (op.from == WordRepresentation::Word32() &&
op.to == WordRepresentation::Word64()) {
o = machine.BitcastWord32ToWord64();
} else if (op.from == MachineRepresentation::kFloat32 &&
op.to == MachineRepresentation::kWord32) {
} else if (op.from == FloatRepresentation::Float32() &&
op.to == WordRepresentation::Word32()) {
o = machine.BitcastFloat32ToInt32();
} else if (op.from == MachineRepresentation::kWord32 &&
op.to == MachineRepresentation::kFloat32) {
} else if (op.from == WordRepresentation::Word32() &&
op.to == FloatRepresentation::Float32()) {
o = machine.BitcastInt32ToFloat32();
} else if (op.from == MachineRepresentation::kFloat64 &&
op.to == MachineRepresentation::kWord64) {
} else if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word64()) {
o = machine.BitcastFloat64ToInt64();
} else if (op.from == MachineRepresentation::kWord64 &&
op.to == MachineRepresentation::kFloat64) {
} else if (op.from == WordRepresentation::Word64() &&
op.to == FloatRepresentation::Float64()) {
o = machine.BitcastInt64ToFloat64();
} else {
UNIMPLEMENTED();
}
break;
case Kind::kSignExtend:
if (op.from == MachineRepresentation::kWord32 &&
op.to == MachineRepresentation::kWord64) {
if (op.from == WordRepresentation::Word32() &&
op.to == WordRepresentation::Word64()) {
o = machine.ChangeInt32ToInt64();
} else {
UNIMPLEMENTED();
}
break;
case Kind::kZeroExtend:
if (op.from == MachineRepresentation::kWord32 &&
op.to == MachineRepresentation::kWord64) {
if (op.from == WordRepresentation::Word32() &&
op.to == WordRepresentation::Word64()) {
o = machine.ChangeUint32ToUint64();
} else {
UNIMPLEMENTED();
}
break;
case Kind::kSignedNarrowing:
if (op.from == MachineRepresentation::kFloat64 &&
op.to == MachineRepresentation::kWord64) {
if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word64()) {
o = machine.ChangeFloat64ToInt64();
} else if (op.from == MachineRepresentation::kFloat64 &&
op.to == MachineRepresentation::kWord32) {
} else if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word32()) {
o = machine.ChangeFloat64ToInt32();
} else {
UNIMPLEMENTED();
}
break;
case Kind::kUnsignedNarrowing:
if (op.from == MachineRepresentation::kFloat64 &&
op.to == MachineRepresentation::kWord64) {
if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word64()) {
o = machine.ChangeFloat64ToUint64();
} else if (op.from == MachineRepresentation::kFloat64 &&
op.to == MachineRepresentation::kWord32) {
} else if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word32()) {
o = machine.ChangeFloat64ToUint32();
} else {
UNIMPLEMENTED();
@ -714,11 +714,11 @@ Node* ScheduleBuilder::ProcessOperation(const Float64InsertWord32Op& op) {
}
Node* ScheduleBuilder::ProcessOperation(const TaggedBitcastOp& op) {
const Operator* o;
if (op.from == MachineRepresentation::kTagged &&
op.to == MachineType::PointerRepresentation()) {
if (op.from == RegisterRepresentation::Tagged() &&
op.to == RegisterRepresentation::PointerSized()) {
o = machine.BitcastTaggedToWord();
} else if (op.from == MachineType::PointerRepresentation() &&
op.to == MachineRepresentation::kTagged) {
} else if (op.from == RegisterRepresentation::PointerSized() &&
op.to == RegisterRepresentation::Tagged()) {
o = machine.BitcastWordToTagged();
} else {
UNIMPLEMENTED();
@ -765,8 +765,8 @@ Node* ScheduleBuilder::ProcessOperation(const LoadOp& op) {
}
Node* base = GetNode(op.base());
return AddNode(IsAlignedAccess(op.kind)
? machine.Load(op.loaded_rep)
: machine.UnalignedLoad(op.loaded_rep),
? machine.Load(op.loaded_rep.ToMachineType())
: machine.UnalignedLoad(op.loaded_rep.ToMachineType()),
{base, IntPtrConstant(offset)});
}
Node* ScheduleBuilder::ProcessOperation(const IndexedLoadOp& op) {
@ -783,9 +783,16 @@ Node* ScheduleBuilder::ProcessOperation(const IndexedLoadOp& op) {
if (offset != 0) {
index = IntPtrAdd(index, IntPtrConstant(offset));
}
return AddNode(IsAlignedAccess(op.kind)
? machine.Load(op.loaded_rep)
: machine.UnalignedLoad(op.loaded_rep),
MachineType loaded_rep = op.loaded_rep.ToMachineType();
if (op.result_rep == RegisterRepresentation::Compressed()) {
if (loaded_rep == MachineType::AnyTagged()) {
loaded_rep = MachineType::AnyCompressed();
} else if (loaded_rep == MachineType::TaggedPointer()) {
loaded_rep = MachineType::CompressedPointer();
}
}
return AddNode(IsAlignedAccess(op.kind) ? machine.Load(loaded_rep)
: machine.UnalignedLoad(loaded_rep),
{base, index});
}
Node* ScheduleBuilder::ProcessOperation(const StoreOp& op) {
@ -798,10 +805,11 @@ Node* ScheduleBuilder::ProcessOperation(const StoreOp& op) {
Node* value = GetNode(op.value());
const Operator* o;
if (IsAlignedAccess(op.kind)) {
o = machine.Store(StoreRepresentation(op.stored_rep, op.write_barrier));
o = machine.Store(StoreRepresentation(
op.stored_rep.ToMachineType().representation(), op.write_barrier));
} else {
DCHECK_EQ(op.write_barrier, WriteBarrierKind::kNoWriteBarrier);
o = machine.UnalignedStore(op.stored_rep);
o = machine.UnalignedStore(op.stored_rep.ToMachineType().representation());
}
return AddNode(o, {base, IntPtrConstant(offset), value});
}
@ -822,10 +830,11 @@ Node* ScheduleBuilder::ProcessOperation(const IndexedStoreOp& op) {
}
const Operator* o;
if (IsAlignedAccess(op.kind)) {
o = machine.Store(StoreRepresentation(op.stored_rep, op.write_barrier));
o = machine.Store(StoreRepresentation(
op.stored_rep.ToMachineType().representation(), op.write_barrier));
} else {
DCHECK_EQ(op.write_barrier, WriteBarrierKind::kNoWriteBarrier);
o = machine.UnalignedStore(op.stored_rep);
o = machine.UnalignedStore(op.stored_rep.ToMachineType().representation());
}
return AddNode(o, {base, index, value});
}
@ -909,7 +918,8 @@ Node* ScheduleBuilder::ProcessOperation(const PhiOp& op) {
Node* input = GetNode(op.input(0));
// The second `input` is a placeholder that is patched when we process the
// backedge.
Node* node = AddNode(common.Phi(op.rep, 2), {input, input});
Node* node =
AddNode(common.Phi(op.rep.machine_representation(), 2), {input, input});
loop_phis.emplace_back(node, op.input(1));
return node;
} else {
@ -917,7 +927,8 @@ Node* ScheduleBuilder::ProcessOperation(const PhiOp& op) {
for (OpIndex i : op.inputs()) {
inputs.push_back(GetNode(i));
}
return AddNode(common.Phi(op.rep, op.input_count), base::VectorOf(inputs));
return AddNode(common.Phi(op.rep.machine_representation(), op.input_count),
base::VectorOf(inputs));
}
}
Node* ScheduleBuilder::ProcessOperation(const ProjectionOp& op) {

View File

@ -0,0 +1,59 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/turboshaft/representations.h"
namespace v8::internal::compiler::turboshaft {
std::ostream& operator<<(std::ostream& os, RegisterRepresentation rep) {
switch (rep) {
case RegisterRepresentation::Word32():
return os << "Word32";
case RegisterRepresentation::Word64():
return os << "Word64";
case RegisterRepresentation::Float32():
return os << "Float32";
case RegisterRepresentation::Float64():
return os << "Float64";
case RegisterRepresentation::Tagged():
return os << "Tagged";
case RegisterRepresentation::Compressed():
return os << "Compressed";
}
}
std::ostream& operator<<(std::ostream& os, MemoryRepresentation rep) {
switch (rep) {
case MemoryRepresentation::Int8():
return os << "Int8";
case MemoryRepresentation::Uint8():
return os << "Uint8";
case MemoryRepresentation::Int16():
return os << "Int16";
case MemoryRepresentation::Uint16():
return os << "Uint16";
case MemoryRepresentation::Int32():
return os << "Int32";
case MemoryRepresentation::Uint32():
return os << "Uint32";
case MemoryRepresentation::Int64():
return os << "Int64";
case MemoryRepresentation::Uint64():
return os << "Uint64";
case MemoryRepresentation::Float32():
return os << "Float32";
case MemoryRepresentation::Float64():
return os << "Float64";
case MemoryRepresentation::AnyTagged():
return os << "AnyTagged";
case MemoryRepresentation::TaggedPointer():
return os << "TaggedPointer";
case MemoryRepresentation::TaggedSigned():
return os << "TaggedSigned";
case MemoryRepresentation::SandboxedPointer():
return os << "SandboxedPointer";
}
}
} // namespace v8::internal::compiler::turboshaft

View File

@ -0,0 +1,543 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_COMPILER_TURBOSHAFT_REPRESENTATIONS_H_
#define V8_COMPILER_TURBOSHAFT_REPRESENTATIONS_H_
#include <cstdint>
#include "src/base/functional.h"
#include "src/base/logging.h"
#include "src/codegen/machine-type.h"
#include "src/compiler/turboshaft/utils.h"
namespace v8::internal::compiler::turboshaft {
class RegisterRepresentation {
public:
enum class Enum : uint8_t {
kWord32,
kWord64,
kFloat32,
kFloat64,
kTagged,
kCompressed
};
explicit constexpr RegisterRepresentation(Enum value) : value_(value) {}
constexpr Enum value() const { return value_; }
constexpr operator Enum() const { return value(); }
static constexpr RegisterRepresentation Word32() {
return RegisterRepresentation(Enum::kWord32);
}
static constexpr RegisterRepresentation Word64() {
return RegisterRepresentation(Enum::kWord64);
}
static constexpr RegisterRepresentation Float32() {
return RegisterRepresentation(Enum::kFloat32);
}
static constexpr RegisterRepresentation Float64() {
return RegisterRepresentation(Enum::kFloat64);
}
// A tagged pointer stored in a register, in the case of pointer compression
// it is an uncompressed pointer or a Smi.
static constexpr RegisterRepresentation Tagged() {
return RegisterRepresentation(Enum::kTagged);
}
// A compressed tagged pointer stored in a register, the upper 32bit are
// unspecified.
static constexpr RegisterRepresentation Compressed() {
return RegisterRepresentation(Enum::kCompressed);
}
// The equivalent of intptr_t/uintptr_t: An integral type with the same size
// as machine pointers.
static constexpr RegisterRepresentation PointerSized() {
if constexpr (kSystemPointerSize == 4) {
return Word32();
} else {
DCHECK_EQ(kSystemPointerSize, 8);
return Word64();
}
}
uint64_t MaxUnsignedValue() const {
switch (this->value()) {
case Word32():
return std::numeric_limits<uint32_t>::max();
case Word64():
return std::numeric_limits<uint64_t>::max();
case Enum::kFloat32:
case Enum::kFloat64:
case Enum::kTagged:
case Enum::kCompressed:
UNREACHABLE();
}
}
MachineRepresentation machine_representation() const {
switch (*this) {
case Word32():
return MachineRepresentation::kWord32;
case Word64():
return MachineRepresentation::kWord64;
case Float32():
return MachineRepresentation::kFloat32;
case Float64():
return MachineRepresentation::kFloat64;
case Tagged():
return MachineRepresentation::kTagged;
case Compressed():
return MachineRepresentation::kCompressed;
}
}
uint16_t bit_width() const {
switch (*this) {
case Word32():
return 32;
case Word64():
return 64;
case Float32():
return 32;
case Float64():
return 64;
case Tagged():
return kSystemPointerSize;
case Compressed():
return kSystemPointerSize;
}
}
static RegisterRepresentation FromMachineRepresentation(
MachineRepresentation rep) {
switch (rep) {
case MachineRepresentation::kBit:
case MachineRepresentation::kWord8:
case MachineRepresentation::kWord16:
case MachineRepresentation::kWord32:
return Word32();
case MachineRepresentation::kWord64:
return Word64();
case MachineRepresentation::kTaggedSigned:
case MachineRepresentation::kTaggedPointer:
case MachineRepresentation::kTagged:
return Tagged();
case MachineRepresentation::kCompressedPointer:
case MachineRepresentation::kCompressed:
return Compressed();
case MachineRepresentation::kFloat32:
return Float32();
case MachineRepresentation::kFloat64:
return Float64();
case MachineRepresentation::kMapWord:
case MachineRepresentation::kSandboxedPointer:
case MachineRepresentation::kNone:
case MachineRepresentation::kSimd128:
case MachineRepresentation::kSimd256:
UNREACHABLE();
}
}
private:
Enum value_;
};
V8_INLINE bool operator==(RegisterRepresentation a, RegisterRepresentation b) {
return a.value() == b.value();
}
V8_INLINE bool operator!=(RegisterRepresentation a, RegisterRepresentation b) {
return a.value() != b.value();
}
V8_INLINE size_t hash_value(RegisterRepresentation rep) {
return static_cast<size_t>(rep.value());
}
std::ostream& operator<<(std::ostream& os, RegisterRepresentation rep);
class WordRepresentation : public RegisterRepresentation {
public:
enum class Enum : uint8_t {
kWord32 = static_cast<int>(RegisterRepresentation::Enum::kWord32),
kWord64 = static_cast<int>(RegisterRepresentation::Enum::kWord64)
};
explicit constexpr WordRepresentation(Enum value)
: RegisterRepresentation(
static_cast<RegisterRepresentation::Enum>(value)) {}
static constexpr WordRepresentation Word32() {
return WordRepresentation(Enum::kWord32);
}
static constexpr WordRepresentation Word64() {
return WordRepresentation(Enum::kWord64);
}
constexpr Enum value() const {
return static_cast<Enum>(RegisterRepresentation::value());
}
constexpr operator Enum() const { return value(); }
// Hide the superclass implicit conversion with an uninstantiable template.
template <Uninstantiable&>
explicit constexpr operator RegisterRepresentation::Enum() const;
constexpr uint64_t MaxUnsignedValue() const {
switch (*this) {
case Word32():
return std::numeric_limits<uint32_t>::max();
case Word64():
return std::numeric_limits<uint64_t>::max();
}
}
};
class FloatRepresentation : public RegisterRepresentation {
public:
enum class Enum : uint8_t {
kFloat32 = static_cast<int>(RegisterRepresentation::Enum::kFloat32),
kFloat64 = static_cast<int>(RegisterRepresentation::Enum::kFloat64)
};
static constexpr FloatRepresentation Float32() {
return FloatRepresentation(Enum::kFloat32);
}
static constexpr FloatRepresentation Float64() {
return FloatRepresentation(Enum::kFloat64);
}
constexpr Enum value() const {
return static_cast<Enum>(RegisterRepresentation::value());
}
constexpr operator Enum() const { return value(); }
// Hide the superclass implicit conversion with an uninstantiable template.
template <Uninstantiable&>
explicit constexpr operator RegisterRepresentation::Enum() const;
private:
explicit constexpr FloatRepresentation(Enum value)
: RegisterRepresentation(
static_cast<RegisterRepresentation::Enum>(value)) {}
};
class MemoryRepresentation {
public:
enum class Enum : uint8_t {
kInt8,
kUint8,
kInt16,
kUint16,
kInt32,
kUint32,
kInt64,
kUint64,
kFloat32,
kFloat64,
kAnyTagged,
kTaggedPointer,
kTaggedSigned,
kSandboxedPointer,
};
explicit constexpr MemoryRepresentation(Enum value) : value_(value) {}
constexpr Enum value() const { return value_; }
constexpr operator Enum() const { return value(); }
static constexpr MemoryRepresentation Int8() {
return MemoryRepresentation(Enum::kInt8);
}
static constexpr MemoryRepresentation Uint8() {
return MemoryRepresentation(Enum::kUint8);
}
static constexpr MemoryRepresentation Int16() {
return MemoryRepresentation(Enum::kInt16);
}
static constexpr MemoryRepresentation Uint16() {
return MemoryRepresentation(Enum::kUint16);
}
static constexpr MemoryRepresentation Int32() {
return MemoryRepresentation(Enum::kInt32);
}
static constexpr MemoryRepresentation Uint32() {
return MemoryRepresentation(Enum::kUint32);
}
static constexpr MemoryRepresentation Int64() {
return MemoryRepresentation(Enum::kInt64);
}
static constexpr MemoryRepresentation Uint64() {
return MemoryRepresentation(Enum::kUint64);
}
static constexpr MemoryRepresentation Float32() {
return MemoryRepresentation(Enum::kFloat32);
}
static constexpr MemoryRepresentation Float64() {
return MemoryRepresentation(Enum::kFloat64);
}
static constexpr MemoryRepresentation AnyTagged() {
return MemoryRepresentation(Enum::kAnyTagged);
}
static constexpr MemoryRepresentation TaggedPointer() {
return MemoryRepresentation(Enum::kTaggedPointer);
}
static constexpr MemoryRepresentation TaggedSigned() {
return MemoryRepresentation(Enum::kTaggedSigned);
}
static constexpr MemoryRepresentation SandboxedPointer() {
return MemoryRepresentation(Enum::kSandboxedPointer);
}
bool IsWord() const {
switch (*this) {
case Int8():
case Uint8():
case Int16():
case Uint16():
case Int32():
case Uint32():
case Int64():
case Uint64():
return true;
case Float32():
case Float64():
case AnyTagged():
case TaggedPointer():
case TaggedSigned():
case SandboxedPointer():
return false;
}
}
bool IsSigned() const {
switch (*this) {
case Int8():
case Int16():
case Int32():
case Int64():
return true;
case Uint8():
case Uint16():
case Uint32():
case Uint64():
return false;
case Float32():
case Float64():
case AnyTagged():
case TaggedPointer():
case TaggedSigned():
case SandboxedPointer():
DCHECK(false);
return false;
}
}
bool IsTagged() const {
switch (*this) {
case AnyTagged():
case TaggedPointer():
case TaggedSigned():
return true;
case Int8():
case Int16():
case Int32():
case Int64():
case Uint8():
case Uint16():
case Uint32():
case Uint64():
case Float32():
case Float64():
case SandboxedPointer():
return false;
}
}
bool CanBeTaggedPointer() const {
switch (*this) {
case AnyTagged():
case TaggedPointer():
return true;
case TaggedSigned():
case Int8():
case Int16():
case Int32():
case Int64():
case Uint8():
case Uint16():
case Uint32():
case Uint64():
case Float32():
case Float64():
case SandboxedPointer():
return false;
}
}
RegisterRepresentation ToRegisterRepresentation() const {
switch (*this) {
case Int8():
case Uint8():
case Int16():
case Uint16():
case Int32():
case Uint32():
return RegisterRepresentation::Word32();
case Int64():
case Uint64():
return RegisterRepresentation::Word64();
case Float32():
return RegisterRepresentation::Float32();
case Float64():
return RegisterRepresentation::Float64();
case AnyTagged():
case TaggedPointer():
case TaggedSigned():
return RegisterRepresentation::Tagged();
case SandboxedPointer():
return RegisterRepresentation::Word64();
}
}
MachineType ToMachineType() const {
switch (*this) {
case Int8():
return MachineType::Int8();
case Uint8():
return MachineType::Uint8();
case Int16():
return MachineType::Int16();
case Uint16():
return MachineType::Uint16();
case Int32():
return MachineType::Int32();
case Uint32():
return MachineType::Uint32();
case Int64():
return MachineType::Int64();
case Uint64():
return MachineType::Uint64();
case Float32():
return MachineType::Float32();
case Float64():
return MachineType::Float64();
case AnyTagged():
return MachineType::AnyTagged();
case TaggedPointer():
return MachineType::TaggedPointer();
case TaggedSigned():
return MachineType::TaggedSigned();
case SandboxedPointer():
return MachineType::SandboxedPointer();
}
}
static MemoryRepresentation FromMachineType(MachineType type) {
switch (type.representation()) {
case MachineRepresentation::kWord8:
return type.IsSigned() ? Int8() : Uint8();
case MachineRepresentation::kWord16:
return type.IsSigned() ? Int16() : Uint16();
case MachineRepresentation::kWord32:
return type.IsSigned() ? Int32() : Uint32();
case MachineRepresentation::kWord64:
return type.IsSigned() ? Int64() : Uint64();
case MachineRepresentation::kTaggedSigned:
return TaggedSigned();
case MachineRepresentation::kTaggedPointer:
return TaggedPointer();
case MachineRepresentation::kTagged:
return AnyTagged();
case MachineRepresentation::kFloat32:
return Float32();
case MachineRepresentation::kFloat64:
return Float64();
case MachineRepresentation::kSandboxedPointer:
return SandboxedPointer();
case MachineRepresentation::kNone:
case MachineRepresentation::kMapWord:
case MachineRepresentation::kBit:
case MachineRepresentation::kSimd128:
case MachineRepresentation::kSimd256:
case MachineRepresentation::kCompressedPointer:
case MachineRepresentation::kCompressed:
UNREACHABLE();
}
}
static MemoryRepresentation FromMachineRepresentation(
MachineRepresentation rep) {
switch (rep) {
case MachineRepresentation::kWord8:
return Uint8();
case MachineRepresentation::kWord16:
return Uint16();
case MachineRepresentation::kWord32:
return Uint32();
case MachineRepresentation::kWord64:
return Uint64();
case MachineRepresentation::kTaggedSigned:
return TaggedSigned();
case MachineRepresentation::kTaggedPointer:
return TaggedPointer();
case MachineRepresentation::kTagged:
return AnyTagged();
case MachineRepresentation::kFloat32:
return Float32();
case MachineRepresentation::kFloat64:
return Float64();
case MachineRepresentation::kSandboxedPointer:
return SandboxedPointer();
case MachineRepresentation::kNone:
case MachineRepresentation::kMapWord:
case MachineRepresentation::kBit:
case MachineRepresentation::kSimd128:
case MachineRepresentation::kSimd256:
case MachineRepresentation::kCompressedPointer:
case MachineRepresentation::kCompressed:
UNREACHABLE();
}
}
uint8_t SizeInBytes() const {
switch (*this) {
case Int8():
case Uint8():
return 1;
case Int16():
case Uint16():
return 2;
case Int32():
case Uint32():
case Float32():
return 4;
case Int64():
case Uint64():
case Float64():
case SandboxedPointer():
return 8;
case AnyTagged():
case TaggedPointer():
case TaggedSigned():
return kTaggedSize;
}
}
private:
Enum value_;
};
V8_INLINE bool operator==(MemoryRepresentation a, MemoryRepresentation b) {
return a.value() == b.value();
}
V8_INLINE bool operator!=(MemoryRepresentation a, MemoryRepresentation b) {
return a.value() != b.value();
}
V8_INLINE size_t hash_value(MemoryRepresentation rep) {
return static_cast<size_t>(rep.value());
}
std::ostream& operator<<(std::ostream& os, MemoryRepresentation rep);
} // namespace v8::internal::compiler::turboshaft
#endif // V8_COMPILER_TURBOSHAFT_REPRESENTATIONS_H_

View File

@ -86,6 +86,11 @@ std::ostream& operator<<(std::ostream& os, all_of<Ts...> all) {
return all.PrintTo(os, std::index_sequence_for<Ts...>{});
}
class Uninstantiable {
private:
constexpr Uninstantiable() = default;
};
} // namespace v8::internal::compiler::turboshaft
#endif // V8_COMPILER_TURBOSHAFT_UTILS_H_