[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:
parent
52f55f38f2
commit
1047e423a2
@ -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",
|
||||
|
2
BUILD.gn
2
BUILD.gn
@ -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 = [
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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()),
|
||||
|
@ -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) {
|
||||
|
59
src/compiler/turboshaft/representations.cc
Normal file
59
src/compiler/turboshaft/representations.cc
Normal 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
|
543
src/compiler/turboshaft/representations.h
Normal file
543
src/compiler/turboshaft/representations.h
Normal 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_
|
@ -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_
|
||||
|
Loading…
Reference in New Issue
Block a user