Commit 08bb94e9 authored by Mike Stanton's avatar Mike Stanton Committed by Commit Bot

Revert "[turbofan] refactor MachineOperatorBuilder to use less macros"

This change was made in one file as a prototype to see if we should
do it elsewhere. Backing the change out as we aren't planning to
continue the work into the other builders.

Change-Id: I10f24a897d86b86d3c53288006cf41fb3255f1b2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2642376Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Michael Stanton <mvstanton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72356}
parent d3b41d07
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "src/compiler/machine-operator.h" #include "src/compiler/machine-operator.h"
#include <type_traits>
#include "src/base/lazy-instance.h"
#include "src/compiler/opcodes.h" #include "src/compiler/opcodes.h"
#include "src/compiler/operator.h" #include "src/compiler/operator.h"
...@@ -207,6 +207,17 @@ ShiftKind ShiftKindOf(Operator const* op) { ...@@ -207,6 +207,17 @@ ShiftKind ShiftKindOf(Operator const* op) {
return OpParameter<ShiftKind>(op); return OpParameter<ShiftKind>(op);
} }
size_t hash_value(TruncateKind kind) { return static_cast<size_t>(kind); }
std::ostream& operator<<(std::ostream& os, TruncateKind kind) {
switch (kind) {
case TruncateKind::kArchitectureDefault:
return os << "kArchitectureDefault";
case TruncateKind::kSetOverflowToMin:
return os << "kSetOverflowToMin";
}
}
// The format is: // The format is:
// V(Name, properties, value_input_count, control_input_count, output_count) // V(Name, properties, value_input_count, control_input_count, output_count)
#define PURE_BINARY_OP_LIST_32(V) \ #define PURE_BINARY_OP_LIST_32(V) \
...@@ -659,6 +670,14 @@ ShiftKind ShiftKindOf(Operator const* op) { ...@@ -659,6 +670,14 @@ ShiftKind ShiftKindOf(Operator const* op) {
ATOMIC_REPRESENTATION_LIST(V) \ ATOMIC_REPRESENTATION_LIST(V) \
V(kWord64) V(kWord64)
#define ATOMIC_PAIR_BINOP_LIST(V) \
V(Add) \
V(Sub) \
V(And) \
V(Or) \
V(Xor) \
V(Exchange)
#define SIMD_LANE_OP_LIST(V) \ #define SIMD_LANE_OP_LIST(V) \
V(F64x2, 2) \ V(F64x2, 2) \
V(F32x4, 4) \ V(F32x4, 4) \
...@@ -679,397 +698,551 @@ ShiftKind ShiftKindOf(Operator const* op) { ...@@ -679,397 +698,551 @@ ShiftKind ShiftKindOf(Operator const* op) {
#define STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST(V) \ #define STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST(V) \
V(4, 0) V(8, 0) V(16, 0) V(4, 4) V(8, 8) V(16, 16) V(4, 0) V(8, 0) V(16, 0) V(4, 4) V(8, 8) V(16, 16)
template <IrOpcode::Value op, int value_input_count, int effect_input_count,
int control_input_count, int value_output_count,
int effect_output_count, int control_output_count>
struct CachedOperator : public Operator {
CachedOperator(Operator::Properties properties, const char* mnemonic)
: Operator(op, properties, mnemonic, value_input_count,
effect_input_count, control_input_count, value_output_count,
effect_output_count, control_output_count) {}
};
template <IrOpcode::Value op, int value_input_count, int control_input_count,
int value_output_count>
struct CachedPureOperator : public Operator {
CachedPureOperator(Operator::Properties properties, const char* mnemonic)
: Operator(op, Operator::kPure | properties, mnemonic, value_input_count,
0, control_input_count, value_output_count, 0, 0) {}
};
template <class Op>
const Operator* GetCachedOperator() {
STATIC_ASSERT(std::is_trivially_destructible<Op>::value);
static const Op op;
return &op;
}
template <class Op>
const Operator* GetCachedOperator(Operator::Properties properties,
const char* mnemonic) {
#ifdef DEBUG
static Operator::Properties const initial_properties = properties;
static const char* const initial_mnemonic = mnemonic;
DCHECK_EQ(properties, initial_properties);
DCHECK_EQ(mnemonic, initial_mnemonic);
#endif
STATIC_ASSERT(std::is_trivially_destructible<Op>::value);
static const Op op(properties, mnemonic);
return &op;
}
struct StackSlotOperator : public Operator1<StackSlotRepresentation> { struct StackSlotOperator : public Operator1<StackSlotRepresentation> {
explicit StackSlotOperator(int size, int alignment) explicit StackSlotOperator(int size, int alignment)
: Operator1(IrOpcode::kStackSlot, Operator::kNoDeopt | Operator::kNoThrow, : Operator1<StackSlotRepresentation>(
"StackSlot", 0, 0, 0, 1, 0, 0, IrOpcode::kStackSlot, Operator::kNoDeopt | Operator::kNoThrow,
StackSlotRepresentation(size, alignment)) {} "StackSlot", 0, 0, 0, 1, 0, 0,
}; StackSlotRepresentation(size, alignment)) {}
template <int size, int alignment>
struct CachedStackSlotOperator : StackSlotOperator {
CachedStackSlotOperator() : StackSlotOperator(size, alignment) {}
}; };
struct MachineOperatorGlobalCache {
#define PURE(Name, properties, value_input_count, control_input_count, \ #define PURE(Name, properties, value_input_count, control_input_count, \
output_count) \ output_count) \
const OptionalOperator MachineOperatorBuilder::Name() { \ struct Name##Operator final : public Operator { \
return OptionalOperator( \ Name##Operator() \
flags_ & k##Name, \ : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \
GetCachedOperator< \ value_input_count, 0, control_input_count, output_count, 0, \
CachedPureOperator<IrOpcode::k##Name, value_input_count, \ 0) {} \
control_input_count, output_count>>(properties, \ }; \
#Name)); \ Name##Operator k##Name;
} MACHINE_PURE_OP_LIST(PURE)
PURE_OPTIONAL_OP_LIST(PURE) struct NormalWord32SarOperator final : public Operator1<ShiftKind> {
NormalWord32SarOperator()
: Operator1<ShiftKind>(IrOpcode::kWord32Sar, Operator::kPure,
"Word32Sar", 2, 0, 0, 1, 0, 0,
ShiftKind::kNormal) {}
};
NormalWord32SarOperator kNormalWord32Sar;
struct ShiftOutZerosWord32SarOperator final : public Operator1<ShiftKind> {
ShiftOutZerosWord32SarOperator()
: Operator1<ShiftKind>(IrOpcode::kWord32Sar, Operator::kPure,
"Word32Sar", 2, 0, 0, 1, 0, 0,
ShiftKind::kShiftOutZeros) {}
};
ShiftOutZerosWord32SarOperator kShiftOutZerosWord32Sar;
struct NormalWord64SarOperator final : public Operator1<ShiftKind> {
NormalWord64SarOperator()
: Operator1<ShiftKind>(IrOpcode::kWord64Sar, Operator::kPure,
"Word64Sar", 2, 0, 0, 1, 0, 0,
ShiftKind::kNormal) {}
};
NormalWord64SarOperator kNormalWord64Sar;
struct ShiftOutZerosWord64SarOperator final : public Operator1<ShiftKind> {
ShiftOutZerosWord64SarOperator()
: Operator1<ShiftKind>(IrOpcode::kWord64Sar, Operator::kPure,
"Word64Sar", 2, 0, 0, 1, 0, 0,
ShiftKind::kShiftOutZeros) {}
};
ShiftOutZerosWord64SarOperator kShiftOutZerosWord64Sar;
struct ArchitectureDefaultTruncateFloat32ToUint32Operator final
: public Operator1<TruncateKind> {
ArchitectureDefaultTruncateFloat32ToUint32Operator()
: Operator1<TruncateKind>(IrOpcode::kTruncateFloat32ToUint32,
Operator::kPure, "TruncateFloat32ToUint32", 1,
0, 0, 1, 0, 0,
TruncateKind::kArchitectureDefault) {}
};
ArchitectureDefaultTruncateFloat32ToUint32Operator
kArchitectureDefaultTruncateFloat32ToUint32;
struct SetOverflowToMinTruncateFloat32ToUint32Operator final
: public Operator1<TruncateKind> {
SetOverflowToMinTruncateFloat32ToUint32Operator()
: Operator1<TruncateKind>(IrOpcode::kTruncateFloat32ToUint32,
Operator::kPure, "TruncateFloat32ToUint32", 1,
0, 0, 1, 0, 0,
TruncateKind::kSetOverflowToMin) {}
};
SetOverflowToMinTruncateFloat32ToUint32Operator
kSetOverflowToMinTruncateFloat32ToUint32;
struct ArchitectureDefaultTruncateFloat32ToInt32Operator final
: public Operator1<TruncateKind> {
ArchitectureDefaultTruncateFloat32ToInt32Operator()
: Operator1<TruncateKind>(IrOpcode::kTruncateFloat32ToInt32,
Operator::kPure, "TruncateFloat32ToInt32", 1,
0, 0, 1, 0, 0,
TruncateKind::kArchitectureDefault) {}
};
ArchitectureDefaultTruncateFloat32ToInt32Operator
kArchitectureDefaultTruncateFloat32ToInt32;
struct SetOverflowToMinTruncateFloat32ToInt32Operator final
: public Operator1<TruncateKind> {
SetOverflowToMinTruncateFloat32ToInt32Operator()
: Operator1<TruncateKind>(IrOpcode::kTruncateFloat32ToInt32,
Operator::kPure, "TruncateFloat32ToInt32", 1,
0, 0, 1, 0, 0,
TruncateKind::kSetOverflowToMin) {}
};
SetOverflowToMinTruncateFloat32ToInt32Operator
kSetOverflowToMinTruncateFloat32ToInt32;
struct ArchitectureDefaultTruncateFloat64ToInt64Operator final
: public Operator1<TruncateKind> {
ArchitectureDefaultTruncateFloat64ToInt64Operator()
: Operator1(IrOpcode::kTruncateFloat64ToInt64, Operator::kPure,
"TruncateFloat64ToInt64", 1, 0, 0, 1, 0, 0,
TruncateKind::kArchitectureDefault) {}
};
ArchitectureDefaultTruncateFloat64ToInt64Operator
kArchitectureDefaultTruncateFloat64ToInt64;
struct SetOverflowToMinTruncateFloat64ToInt64Operator final
: public Operator1<TruncateKind> {
SetOverflowToMinTruncateFloat64ToInt64Operator()
: Operator1(IrOpcode::kTruncateFloat64ToInt64, Operator::kPure,
"TruncateFloat64ToInt64", 1, 0, 0, 1, 0, 0,
TruncateKind::kSetOverflowToMin) {}
};
SetOverflowToMinTruncateFloat64ToInt64Operator
kSetOverflowToMinTruncateFloat64ToInt64;
PURE_OPTIONAL_OP_LIST(PURE)
#undef PURE #undef PURE
#define OVERFLOW_OP(Name, properties) \ struct PrefetchTemporalOperator final : public Operator {
const Operator* MachineOperatorBuilder::Name() { \ PrefetchTemporalOperator()
return GetCachedOperator< \ : Operator(IrOpcode::kPrefetchTemporal,
CachedOperator<IrOpcode::k##Name, 2, 0, 1, 2, 0, 0>>( \ Operator::kNoDeopt | Operator::kNoThrow, "PrefetchTemporal",
Operator::kEliminatable | Operator::kNoRead | properties, #Name); \ 2, 1, 1, 0, 1, 0) {}
} };
OVERFLOW_OP_LIST(OVERFLOW_OP) PrefetchTemporalOperator kPrefetchTemporal;
struct PrefetchNonTemporalOperator final : public Operator {
PrefetchNonTemporalOperator()
: Operator(IrOpcode::kPrefetchNonTemporal,
Operator::kNoDeopt | Operator::kNoThrow,
"PrefetchNonTemporal", 2, 1, 1, 0, 1, 0) {}
};
PrefetchNonTemporalOperator kPrefetchNonTemporal;
#define OVERFLOW_OP(Name, properties) \
struct Name##Operator final : public Operator { \
Name##Operator() \
: Operator(IrOpcode::k##Name, \
Operator::kEliminatable | Operator::kNoRead | properties, \
#Name, 2, 0, 1, 2, 0, 0) {} \
}; \
Name##Operator k##Name;
OVERFLOW_OP_LIST(OVERFLOW_OP)
#undef OVERFLOW_OP #undef OVERFLOW_OP
template <ShiftKind kind> #define LOAD(Type) \
struct Word32SarOperator : Operator1<ShiftKind> { struct Load##Type##Operator final : public Operator1<LoadRepresentation> { \
Word32SarOperator() Load##Type##Operator() \
: Operator1(IrOpcode::kWord32Sar, Operator::kPure, "Word32Sar", 2, 0, 0, : Operator1<LoadRepresentation>(IrOpcode::kLoad, \
1, 0, 0, kind) {} Operator::kEliminatable, "Load", 2, 1, \
}; 1, 1, 1, 0, MachineType::Type()) {} \
}; \
const Operator* MachineOperatorBuilder::Word32Sar(ShiftKind kind) { struct PoisonedLoad##Type##Operator final \
switch (kind) { : public Operator1<LoadRepresentation> { \
case ShiftKind::kNormal: PoisonedLoad##Type##Operator() \
return GetCachedOperator<Word32SarOperator<ShiftKind::kNormal>>(); : Operator1<LoadRepresentation>( \
case ShiftKind::kShiftOutZeros: IrOpcode::kPoisonedLoad, Operator::kEliminatable, \
return GetCachedOperator<Word32SarOperator<ShiftKind::kShiftOutZeros>>(); "PoisonedLoad", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \
} }; \
} struct UnalignedLoad##Type##Operator final \
: public Operator1<LoadRepresentation> { \
template <ShiftKind kind> UnalignedLoad##Type##Operator() \
struct Word64SarOperator : Operator1<ShiftKind> { : Operator1<LoadRepresentation>( \
Word64SarOperator() IrOpcode::kUnalignedLoad, Operator::kEliminatable, \
: Operator1(IrOpcode::kWord64Sar, Operator::kPure, "Word64Sar", 2, 0, 0, "UnalignedLoad", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \
1, 0, 0, kind) {} }; \
}; struct ProtectedLoad##Type##Operator final \
: public Operator1<LoadRepresentation> { \
const Operator* MachineOperatorBuilder::Word64Sar(ShiftKind kind) { ProtectedLoad##Type##Operator() \
switch (kind) { : Operator1<LoadRepresentation>( \
case ShiftKind::kNormal: IrOpcode::kProtectedLoad, \
return GetCachedOperator<Word64SarOperator<ShiftKind::kNormal>>(); Operator::kNoDeopt | Operator::kNoThrow, "ProtectedLoad", 2, 1, \
case ShiftKind::kShiftOutZeros: 1, 1, 1, 0, MachineType::Type()) {} \
return GetCachedOperator<Word64SarOperator<ShiftKind::kShiftOutZeros>>(); }; \
} Load##Type##Operator kLoad##Type; \
} PoisonedLoad##Type##Operator kPoisonedLoad##Type; \
UnalignedLoad##Type##Operator kUnalignedLoad##Type; \
template <MachineRepresentation rep, MachineSemantic sem> ProtectedLoad##Type##Operator kProtectedLoad##Type;
struct LoadOperator : public Operator1<LoadRepresentation> { MACHINE_TYPE_LIST(LOAD)
LoadOperator() #undef LOAD
: Operator1(IrOpcode::kLoad, Operator::kEliminatable, "Load", 2, 1, 1, 1,
1, 0, LoadRepresentation(rep, sem)) {}
};
template <MachineRepresentation rep, MachineSemantic sem>
struct PoisonedLoadOperator : public Operator1<LoadRepresentation> {
PoisonedLoadOperator()
: Operator1(IrOpcode::kPoisonedLoad, Operator::kEliminatable,
"PoisonedLoad", 2, 1, 1, 1, 1, 0,
LoadRepresentation(rep, sem)) {}
};
template <MachineRepresentation rep, MachineSemantic sem>
struct UnalignedLoadOperator : public Operator1<LoadRepresentation> {
UnalignedLoadOperator()
: Operator1(IrOpcode::kUnalignedLoad, Operator::kEliminatable,
"UnalignedLoad", 2, 1, 1, 1, 1, 0,
LoadRepresentation(rep, sem)) {}
};
template <MachineRepresentation rep, MachineSemantic sem>
struct ProtectedLoadOperator : public Operator1<LoadRepresentation> {
ProtectedLoadOperator()
: Operator1(IrOpcode::kProtectedLoad,
Operator::kNoDeopt | Operator::kNoThrow, "ProtectedLoad", 2,
1, 1, 1, 1, 0, LoadRepresentation(rep, sem)) {}
};
template <MemoryAccessKind kind, LoadTransformation type>
struct LoadTransformOperator : public Operator1<LoadTransformParameters> {
LoadTransformOperator()
: Operator1(IrOpcode::kLoadTransform,
kind == MemoryAccessKind::kProtected
? Operator::kNoDeopt | Operator::kNoThrow
: Operator::kEliminatable,
"LoadTransform", 2, 1, 1, 1, 1, 0,
LoadTransformParameters{kind, type}) {}
};
template <MemoryAccessKind kind, MachineRepresentation rep, MachineSemantic sem,
uint8_t laneidx>
struct LoadLaneOperator : public Operator1<LoadLaneParameters> {
LoadLaneOperator()
: Operator1(
IrOpcode::kLoadLane,
kind == MemoryAccessKind::kProtected
? Operator::kNoDeopt | Operator::kNoThrow
: Operator::kEliminatable,
"LoadLane", 3, 1, 1, 1, 1, 0,
LoadLaneParameters{kind, LoadRepresentation(rep, sem), laneidx}) {}
};
template <MachineRepresentation rep, WriteBarrierKind write_barrier_kind>
struct StoreOperator : public Operator1<StoreRepresentation> {
StoreOperator()
: Operator1(IrOpcode::kStore,
Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
"Store", 3, 1, 1, 0, 1, 0,
StoreRepresentation(rep, write_barrier_kind)) {}
};
template <MachineRepresentation rep>
struct UnalignedStoreOperator : public Operator1<UnalignedStoreRepresentation> {
UnalignedStoreOperator()
: Operator1(IrOpcode::kUnalignedStore,
Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
"UnalignedStore", 3, 1, 1, 0, 1, 0, rep) {}
};
template <MachineRepresentation rep>
struct ProtectedStoreOperator : public Operator1<StoreRepresentation> {
ProtectedStoreOperator()
: Operator1(IrOpcode::kProtectedStore,
Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
"Store", 3, 1, 1, 0, 1, 0,
StoreRepresentation(rep, kNoWriteBarrier)) {}
};
template <MemoryAccessKind kind, MachineRepresentation rep, uint8_t laneidx>
struct StoreLaneOperator : public Operator1<StoreLaneParameters> {
StoreLaneOperator()
: Operator1(IrOpcode::kStoreLane,
Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
"StoreLane", 3, 1, 1, 0, 1, 0,
StoreLaneParameters{kind, rep, laneidx}) {}
};
template <MachineRepresentation rep, MachineSemantic sem> #define LOAD_TRANSFORM_KIND(TYPE, KIND) \
struct Word32AtomicLoadOperator : public Operator1<LoadRepresentation> { struct KIND##LoadTransform##TYPE##Operator final \
Word32AtomicLoadOperator() : public Operator1<LoadTransformParameters> { \
: Operator1(IrOpcode::kWord32AtomicLoad, Operator::kEliminatable, KIND##LoadTransform##TYPE##Operator() \
"Word32AtomicLoad", 2, 1, 1, 1, 1, 0, MachineType(rep, sem)) { : Operator1<LoadTransformParameters>( \
} IrOpcode::kLoadTransform, \
}; MemoryAccessKind::k##KIND == MemoryAccessKind::kProtected \
? Operator::kNoDeopt | Operator::kNoThrow \
: Operator::kEliminatable, \
#KIND "LoadTransform", 2, 1, 1, 1, 1, 0, \
LoadTransformParameters{MemoryAccessKind::k##KIND, \
LoadTransformation::k##TYPE}) {} \
}; \
KIND##LoadTransform##TYPE##Operator k##KIND##LoadTransform##TYPE;
template <MachineRepresentation rep, MachineSemantic sem> #define LOAD_TRANSFORM(TYPE) \
struct Word64AtomicLoadOperator : public Operator1<LoadRepresentation> { LOAD_TRANSFORM_KIND(TYPE, Normal) \
Word64AtomicLoadOperator() LOAD_TRANSFORM_KIND(TYPE, Unaligned) \
: Operator1(IrOpcode::kWord64AtomicLoad, Operator::kEliminatable, LOAD_TRANSFORM_KIND(TYPE, Protected)
"Word64AtomicLoad", 2, 1, 1, 1, 1, 0, MachineType(rep, sem)) {
}
};
template <MachineRepresentation rep> LOAD_TRANSFORM_LIST(LOAD_TRANSFORM)
struct Word32AtomicStoreOperator : public Operator1<MachineRepresentation> { #undef LOAD_TRANSFORM
Word32AtomicStoreOperator() #undef LOAD_TRANSFORM_KIND
: Operator1(IrOpcode::kWord32AtomicStore,
Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
"Word32AtomicStore", 3, 1, 1, 0, 1, 0, rep) {}
};
template <MachineRepresentation rep> #define STACKSLOT(Size, Alignment) \
struct Word64AtomicStoreOperator : public Operator1<MachineRepresentation> { struct StackSlotOfSize##Size##OfAlignment##Alignment##Operator final \
Word64AtomicStoreOperator() : public StackSlotOperator { \
: Operator1(IrOpcode::kWord64AtomicStore, StackSlotOfSize##Size##OfAlignment##Alignment##Operator() \
Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, : StackSlotOperator(Size, Alignment) {} \
"Word64AtomicStore", 3, 1, 1, 0, 1, 0, rep) {} }; \
}; StackSlotOfSize##Size##OfAlignment##Alignment##Operator \
kStackSlotOfSize##Size##OfAlignment##Alignment;
STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST(STACKSLOT)
#undef STACKSLOT
#define STORE(Type) \
struct Store##Type##Operator : public Operator1<StoreRepresentation> { \
explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind) \
: Operator1<StoreRepresentation>( \
IrOpcode::kStore, \
Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
"Store", 3, 1, 1, 0, 1, 0, \
StoreRepresentation(MachineRepresentation::Type, \
write_barrier_kind)) {} \
}; \
struct Store##Type##NoWriteBarrier##Operator final \
: public Store##Type##Operator { \
Store##Type##NoWriteBarrier##Operator() \
: Store##Type##Operator(kNoWriteBarrier) {} \
}; \
struct Store##Type##AssertNoWriteBarrier##Operator final \
: public Store##Type##Operator { \
Store##Type##AssertNoWriteBarrier##Operator() \
: Store##Type##Operator(kAssertNoWriteBarrier) {} \
}; \
struct Store##Type##MapWriteBarrier##Operator final \
: public Store##Type##Operator { \
Store##Type##MapWriteBarrier##Operator() \
: Store##Type##Operator(kMapWriteBarrier) {} \
}; \
struct Store##Type##PointerWriteBarrier##Operator final \
: public Store##Type##Operator { \
Store##Type##PointerWriteBarrier##Operator() \
: Store##Type##Operator(kPointerWriteBarrier) {} \
}; \
struct Store##Type##EphemeronKeyWriteBarrier##Operator final \
: public Store##Type##Operator { \
Store##Type##EphemeronKeyWriteBarrier##Operator() \
: Store##Type##Operator(kEphemeronKeyWriteBarrier) {} \
}; \
struct Store##Type##FullWriteBarrier##Operator final \
: public Store##Type##Operator { \
Store##Type##FullWriteBarrier##Operator() \
: Store##Type##Operator(kFullWriteBarrier) {} \
}; \
struct UnalignedStore##Type##Operator final \
: public Operator1<UnalignedStoreRepresentation> { \
UnalignedStore##Type##Operator() \
: Operator1<UnalignedStoreRepresentation>( \
IrOpcode::kUnalignedStore, \
Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
"UnalignedStore", 3, 1, 1, 0, 1, 0, \
MachineRepresentation::Type) {} \
}; \
struct ProtectedStore##Type##Operator \
: public Operator1<StoreRepresentation> { \
explicit ProtectedStore##Type##Operator() \
: Operator1<StoreRepresentation>( \
IrOpcode::kProtectedStore, \
Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
"Store", 3, 1, 1, 0, 1, 0, \
StoreRepresentation(MachineRepresentation::Type, \
kNoWriteBarrier)) {} \
}; \
Store##Type##NoWriteBarrier##Operator kStore##Type##NoWriteBarrier; \
Store##Type##AssertNoWriteBarrier##Operator \
kStore##Type##AssertNoWriteBarrier; \
Store##Type##MapWriteBarrier##Operator kStore##Type##MapWriteBarrier; \
Store##Type##PointerWriteBarrier##Operator \
kStore##Type##PointerWriteBarrier; \
Store##Type##EphemeronKeyWriteBarrier##Operator \
kStore##Type##EphemeronKeyWriteBarrier; \
Store##Type##FullWriteBarrier##Operator kStore##Type##FullWriteBarrier; \
UnalignedStore##Type##Operator kUnalignedStore##Type; \
ProtectedStore##Type##Operator kProtectedStore##Type;
MACHINE_REPRESENTATION_LIST(STORE)
#undef STORE
#define ATOMIC_OP(op) \ #define ATOMIC_LOAD(Type) \
template <MachineRepresentation rep, MachineSemantic sem> \ struct Word32AtomicLoad##Type##Operator final \
struct op##Operator : public Operator1<MachineType> { \ : public Operator1<LoadRepresentation> { \
op##Operator() \ Word32AtomicLoad##Type##Operator() \
: Operator1(IrOpcode::k##op, Operator::kNoDeopt | Operator::kNoThrow, \ : Operator1<LoadRepresentation>( \
#op, 3, 1, 1, 1, 1, 0, MachineType(rep, sem)) {} \ IrOpcode::kWord32AtomicLoad, Operator::kEliminatable, \
}; "Word32AtomicLoad", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \
ATOMIC_OP(Word32AtomicAdd) }; \
ATOMIC_OP(Word32AtomicSub) Word32AtomicLoad##Type##Operator kWord32AtomicLoad##Type;
ATOMIC_OP(Word32AtomicAnd) ATOMIC_TYPE_LIST(ATOMIC_LOAD)
ATOMIC_OP(Word32AtomicOr) #undef ATOMIC_LOAD
ATOMIC_OP(Word32AtomicXor)
ATOMIC_OP(Word32AtomicExchange) #define ATOMIC_LOAD(Type) \
ATOMIC_OP(Word64AtomicAdd) struct Word64AtomicLoad##Type##Operator final \
ATOMIC_OP(Word64AtomicSub) : public Operator1<LoadRepresentation> { \
ATOMIC_OP(Word64AtomicAnd) Word64AtomicLoad##Type##Operator() \
ATOMIC_OP(Word64AtomicOr) : Operator1<LoadRepresentation>( \
ATOMIC_OP(Word64AtomicXor) IrOpcode::kWord64AtomicLoad, Operator::kEliminatable, \
ATOMIC_OP(Word64AtomicExchange) "Word64AtomicLoad", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \
}; \
Word64AtomicLoad##Type##Operator kWord64AtomicLoad##Type;
ATOMIC_U64_TYPE_LIST(ATOMIC_LOAD)
#undef ATOMIC_LOAD
#define ATOMIC_STORE(Type) \
struct Word32AtomicStore##Type##Operator \
: public Operator1<MachineRepresentation> { \
Word32AtomicStore##Type##Operator() \
: Operator1<MachineRepresentation>( \
IrOpcode::kWord32AtomicStore, \
Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
"Word32AtomicStore", 3, 1, 1, 0, 1, 0, \
MachineRepresentation::Type) {} \
}; \
Word32AtomicStore##Type##Operator kWord32AtomicStore##Type;
ATOMIC_REPRESENTATION_LIST(ATOMIC_STORE)
#undef ATOMIC_STORE
#define ATOMIC_STORE(Type) \
struct Word64AtomicStore##Type##Operator \
: public Operator1<MachineRepresentation> { \
Word64AtomicStore##Type##Operator() \
: Operator1<MachineRepresentation>( \
IrOpcode::kWord64AtomicStore, \
Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
"Word64AtomicStore", 3, 1, 1, 0, 1, 0, \
MachineRepresentation::Type) {} \
}; \
Word64AtomicStore##Type##Operator kWord64AtomicStore##Type;
ATOMIC64_REPRESENTATION_LIST(ATOMIC_STORE)
#undef ATOMIC_STORE
#define ATOMIC_OP(op, type) \
struct op##type##Operator : public Operator1<MachineType> { \
op##type##Operator() \
: Operator1<MachineType>(IrOpcode::k##op, \
Operator::kNoDeopt | Operator::kNoThrow, #op, \
3, 1, 1, 1, 1, 0, MachineType::type()) {} \
}; \
op##type##Operator k##op##type;
#define ATOMIC_OP_LIST(type) \
ATOMIC_OP(Word32AtomicAdd, type) \
ATOMIC_OP(Word32AtomicSub, type) \
ATOMIC_OP(Word32AtomicAnd, type) \
ATOMIC_OP(Word32AtomicOr, type) \
ATOMIC_OP(Word32AtomicXor, type) \
ATOMIC_OP(Word32AtomicExchange, type)
ATOMIC_TYPE_LIST(ATOMIC_OP_LIST)
#undef ATOMIC_OP_LIST
#define ATOMIC64_OP_LIST(type) \
ATOMIC_OP(Word64AtomicAdd, type) \
ATOMIC_OP(Word64AtomicSub, type) \
ATOMIC_OP(Word64AtomicAnd, type) \
ATOMIC_OP(Word64AtomicOr, type) \
ATOMIC_OP(Word64AtomicXor, type) \
ATOMIC_OP(Word64AtomicExchange, type)
ATOMIC_U64_TYPE_LIST(ATOMIC64_OP_LIST)
#undef ATOMIC64_OP_LIST
#undef ATOMIC_OP #undef ATOMIC_OP
template <MachineRepresentation rep, MachineSemantic sem> #define ATOMIC_COMPARE_EXCHANGE(Type) \
struct Word32AtomicCompareExchangeOperator : public Operator1<MachineType> { struct Word32AtomicCompareExchange##Type##Operator \
Word32AtomicCompareExchangeOperator() : public Operator1<MachineType> { \
: Operator1(IrOpcode::kWord32AtomicCompareExchange, Word32AtomicCompareExchange##Type##Operator() \
Operator::kNoDeopt | Operator::kNoThrow, : Operator1<MachineType>(IrOpcode::kWord32AtomicCompareExchange, \
"Word32AtomicCompareExchange", 4, 1, 1, 1, 1, 0, Operator::kNoDeopt | Operator::kNoThrow, \
MachineType(rep, sem)) {} "Word32AtomicCompareExchange", 4, 1, 1, 1, 1, \
}; 0, MachineType::Type()) {} \
}; \
template <MachineRepresentation rep, MachineSemantic sem> Word32AtomicCompareExchange##Type##Operator \
struct Word64AtomicCompareExchangeOperator : public Operator1<MachineType> { kWord32AtomicCompareExchange##Type;
Word64AtomicCompareExchangeOperator() ATOMIC_TYPE_LIST(ATOMIC_COMPARE_EXCHANGE)
: Operator1(IrOpcode::kWord64AtomicCompareExchange, #undef ATOMIC_COMPARE_EXCHANGE
Operator::kNoDeopt | Operator::kNoThrow,
"Word64AtomicCompareExchange", 4, 1, 1, 1, 1, 0, #define ATOMIC_COMPARE_EXCHANGE(Type) \
MachineType(rep, sem)) {} struct Word64AtomicCompareExchange##Type##Operator \
}; : public Operator1<MachineType> { \
Word64AtomicCompareExchange##Type##Operator() \
struct Word32AtomicPairLoadOperator : public Operator { : Operator1<MachineType>(IrOpcode::kWord64AtomicCompareExchange, \
Word32AtomicPairLoadOperator() Operator::kNoDeopt | Operator::kNoThrow, \
: Operator(IrOpcode::kWord32AtomicPairLoad, "Word64AtomicCompareExchange", 4, 1, 1, 1, 1, \
Operator::kNoDeopt | Operator::kNoThrow, 0, MachineType::Type()) {} \
"Word32AtomicPairLoad", 2, 1, 1, 2, 1, 0) {} }; \
}; Word64AtomicCompareExchange##Type##Operator \
kWord64AtomicCompareExchange##Type;
ATOMIC_U64_TYPE_LIST(ATOMIC_COMPARE_EXCHANGE)
#undef ATOMIC_COMPARE_EXCHANGE
struct Word32AtomicPairLoadOperator : public Operator {
Word32AtomicPairLoadOperator()
: Operator(IrOpcode::kWord32AtomicPairLoad,
Operator::kNoDeopt | Operator::kNoThrow,
"Word32AtomicPairLoad", 2, 1, 1, 2, 1, 0) {}
};
Word32AtomicPairLoadOperator kWord32AtomicPairLoad;
struct Word32AtomicPairStoreOperator : public Operator { struct Word32AtomicPairStoreOperator : public Operator {
Word32AtomicPairStoreOperator() Word32AtomicPairStoreOperator()
: Operator(IrOpcode::kWord32AtomicPairStore, : Operator(IrOpcode::kWord32AtomicPairStore,
Operator::kNoDeopt | Operator::kNoThrow, Operator::kNoDeopt | Operator::kNoThrow,
"Word32AtomicPairStore", 4, 1, 1, 0, 1, 0) {} "Word32AtomicPairStore", 4, 1, 1, 0, 1, 0) {}
}; };
Word32AtomicPairStoreOperator kWord32AtomicPairStore;
#define ATOMIC_PAIR_OP(op) \ #define ATOMIC_PAIR_OP(op) \
struct Word32AtomicPair##op##Operator : public Operator { \ struct Word32AtomicPair##op##Operator : public Operator { \
Word32AtomicPair##op##Operator() \ Word32AtomicPair##op##Operator() \
: Operator(IrOpcode::kWord32AtomicPair##op, \ : Operator(IrOpcode::kWord32AtomicPair##op, \
Operator::kNoDeopt | Operator::kNoThrow, \ Operator::kNoDeopt | Operator::kNoThrow, \
"Word32AtomicPair" #op, 4, 1, 1, 2, 1, 0) {} \ "Word32AtomicPair##op", 4, 1, 1, 2, 1, 0) {} \
}; }; \
ATOMIC_PAIR_OP(Add) Word32AtomicPair##op##Operator kWord32AtomicPair##op;
ATOMIC_PAIR_OP(Sub) ATOMIC_PAIR_BINOP_LIST(ATOMIC_PAIR_OP)
ATOMIC_PAIR_OP(And)
ATOMIC_PAIR_OP(Or)
ATOMIC_PAIR_OP(Xor)
ATOMIC_PAIR_OP(Exchange)
#undef ATOMIC_PAIR_OP #undef ATOMIC_PAIR_OP
#undef ATOMIC_PAIR_BINOP_LIST
struct Word32AtomicPairCompareExchangeOperator : public Operator { struct Word32AtomicPairCompareExchangeOperator : public Operator {
Word32AtomicPairCompareExchangeOperator() Word32AtomicPairCompareExchangeOperator()
: Operator(IrOpcode::kWord32AtomicPairCompareExchange, : Operator(IrOpcode::kWord32AtomicPairCompareExchange,
Operator::kNoDeopt | Operator::kNoThrow, Operator::kNoDeopt | Operator::kNoThrow,
"Word32AtomicPairCompareExchange", 6, 1, 1, 2, 1, 0) {} "Word32AtomicPairCompareExchange", 6, 1, 1, 2, 1, 0) {}
}; };
Word32AtomicPairCompareExchangeOperator kWord32AtomicPairCompareExchange;
struct MemoryBarrierOperator : public Operator {
MemoryBarrierOperator()
: Operator(IrOpcode::kMemoryBarrier,
Operator::kNoDeopt | Operator::kNoThrow, "MemoryBarrier", 0, 1,
1, 0, 1, 0) {}
};
// The {BitcastWordToTagged} operator must not be marked as pure (especially struct MemoryBarrierOperator : public Operator {
// not idempotent), because otherwise the splitting logic in the Scheduler MemoryBarrierOperator()
// might decide to split these operators, thus potentially creating live : Operator(IrOpcode::kMemoryBarrier,
// ranges of allocation top across calls or other things that might allocate. Operator::kNoDeopt | Operator::kNoThrow, "MemoryBarrier", 0,
// See https://bugs.chromium.org/p/v8/issues/detail?id=6059 for more details. 1, 1, 0, 1, 0) {}
struct BitcastWordToTaggedOperator : public Operator { };
BitcastWordToTaggedOperator() MemoryBarrierOperator kMemoryBarrier;
: Operator(IrOpcode::kBitcastWordToTagged,
Operator::kEliminatable | Operator::kNoWrite, // The {BitcastWordToTagged} operator must not be marked as pure (especially
"BitcastWordToTagged", 1, 1, 1, 1, 1, 0) {} // not idempotent), because otherwise the splitting logic in the Scheduler
}; // might decide to split these operators, thus potentially creating live
// ranges of allocation top across calls or other things that might allocate.
// See https://bugs.chromium.org/p/v8/issues/detail?id=6059 for more details.
struct BitcastWordToTaggedOperator : public Operator {
BitcastWordToTaggedOperator()
: Operator(IrOpcode::kBitcastWordToTagged,
Operator::kEliminatable | Operator::kNoWrite,
"BitcastWordToTagged", 1, 1, 1, 1, 1, 0) {}
};
BitcastWordToTaggedOperator kBitcastWordToTagged;
struct BitcastTaggedToWordOperator : public Operator { struct BitcastTaggedToWordOperator : public Operator {
BitcastTaggedToWordOperator() BitcastTaggedToWordOperator()
: Operator(IrOpcode::kBitcastTaggedToWord, : Operator(IrOpcode::kBitcastTaggedToWord,
Operator::kEliminatable | Operator::kNoWrite, Operator::kEliminatable | Operator::kNoWrite,
"BitcastTaggedToWord", 1, 1, 1, 1, 1, 0) {} "BitcastTaggedToWord", 1, 1, 1, 1, 1, 0) {}
}; };
BitcastTaggedToWordOperator kBitcastTaggedToWord;
struct BitcastMaybeObjectToWordOperator : public Operator { struct BitcastMaybeObjectToWordOperator : public Operator {
BitcastMaybeObjectToWordOperator() BitcastMaybeObjectToWordOperator()
: Operator(IrOpcode::kBitcastTaggedToWord, : Operator(IrOpcode::kBitcastTaggedToWord,
Operator::kEliminatable | Operator::kNoWrite, Operator::kEliminatable | Operator::kNoWrite,
"BitcastMaybeObjectToWord", 1, 1, 1, 1, 1, 0) {} "BitcastMaybeObjectToWord", 1, 1, 1, 1, 1, 0) {}
}; };
BitcastMaybeObjectToWordOperator kBitcastMaybeObjectToWord;
struct TaggedPoisonOnSpeculationOperator : public Operator { struct TaggedPoisonOnSpeculation : public Operator {
TaggedPoisonOnSpeculationOperator() TaggedPoisonOnSpeculation()
: Operator(IrOpcode::kTaggedPoisonOnSpeculation, : Operator(IrOpcode::kTaggedPoisonOnSpeculation,
Operator::kEliminatable | Operator::kNoWrite, Operator::kEliminatable | Operator::kNoWrite,
"TaggedPoisonOnSpeculation", 1, 1, 1, 1, 1, 0) {} "TaggedPoisonOnSpeculation", 1, 1, 1, 1, 1, 0) {}
}; };
TaggedPoisonOnSpeculation kTaggedPoisonOnSpeculation;
struct Word32PoisonOnSpeculationOperator : public Operator { struct Word32PoisonOnSpeculation : public Operator {
Word32PoisonOnSpeculationOperator() Word32PoisonOnSpeculation()
: Operator(IrOpcode::kWord32PoisonOnSpeculation, : Operator(IrOpcode::kWord32PoisonOnSpeculation,
Operator::kEliminatable | Operator::kNoWrite, Operator::kEliminatable | Operator::kNoWrite,
"Word32PoisonOnSpeculation", 1, 1, 1, 1, 1, 0) {} "Word32PoisonOnSpeculation", 1, 1, 1, 1, 1, 0) {}
}; };
Word32PoisonOnSpeculation kWord32PoisonOnSpeculation;
struct Word64PoisonOnSpeculationOperator : public Operator { struct Word64PoisonOnSpeculation : public Operator {
Word64PoisonOnSpeculationOperator() Word64PoisonOnSpeculation()
: Operator(IrOpcode::kWord64PoisonOnSpeculation, : Operator(IrOpcode::kWord64PoisonOnSpeculation,
Operator::kEliminatable | Operator::kNoWrite, Operator::kEliminatable | Operator::kNoWrite,
"Word64PoisonOnSpeculation", 1, 1, 1, 1, 1, 0) {} "Word64PoisonOnSpeculation", 1, 1, 1, 1, 1, 0) {}
}; };
Word64PoisonOnSpeculation kWord64PoisonOnSpeculation;
struct AbortCSAAssertOperator : public Operator { struct AbortCSAAssertOperator : public Operator {
AbortCSAAssertOperator() AbortCSAAssertOperator()
: Operator(IrOpcode::kAbortCSAAssert, Operator::kNoThrow, : Operator(IrOpcode::kAbortCSAAssert, Operator::kNoThrow,
"AbortCSAAssert", 1, 1, 1, 0, 1, 0) {} "AbortCSAAssert", 1, 1, 1, 0, 1, 0) {}
}; };
AbortCSAAssertOperator kAbortCSAAssert;
struct DebugBreakOperator : public Operator { struct DebugBreakOperator : public Operator {
DebugBreakOperator() DebugBreakOperator()
: Operator(IrOpcode::kDebugBreak, Operator::kNoThrow, "DebugBreak", 0, 1, : Operator(IrOpcode::kDebugBreak, Operator::kNoThrow, "DebugBreak", 0,
1, 0, 1, 0) {} 1, 1, 0, 1, 0) {}
}; };
DebugBreakOperator kDebugBreak;
struct UnsafePointerAddOperator : public Operator { struct UnsafePointerAddOperator final : public Operator {
UnsafePointerAddOperator() UnsafePointerAddOperator()
: Operator(IrOpcode::kUnsafePointerAdd, Operator::kKontrol, : Operator(IrOpcode::kUnsafePointerAdd, Operator::kKontrol,
"UnsafePointerAdd", 2, 1, 1, 1, 1, 0) {} "UnsafePointerAdd", 2, 1, 1, 1, 1, 0) {}
}; };
UnsafePointerAddOperator kUnsafePointerAdd;
template <StackCheckKind kind> struct StackPointerGreaterThanOperator : public Operator1<StackCheckKind> {
struct StackPointerGreaterThanOperator : public Operator1<StackCheckKind> { explicit StackPointerGreaterThanOperator(StackCheckKind kind)
StackPointerGreaterThanOperator() : Operator1<StackCheckKind>(
: Operator1(IrOpcode::kStackPointerGreaterThan, Operator::kEliminatable, IrOpcode::kStackPointerGreaterThan, Operator::kEliminatable,
"StackPointerGreaterThan", 1, 1, 0, 1, 1, 0, kind) {} "StackPointerGreaterThan", 1, 1, 0, 1, 1, 0, kind) {}
};
#define STACK_POINTER_GREATER_THAN(Kind) \
struct StackPointerGreaterThan##Kind##Operator final \
: public StackPointerGreaterThanOperator { \
StackPointerGreaterThan##Kind##Operator() \
: StackPointerGreaterThanOperator(StackCheckKind::k##Kind) {} \
}; \
StackPointerGreaterThan##Kind##Operator kStackPointerGreaterThan##Kind;
STACK_POINTER_GREATER_THAN(JSFunctionEntry)
STACK_POINTER_GREATER_THAN(JSIterationBody)
STACK_POINTER_GREATER_THAN(CodeStubAssembler)
STACK_POINTER_GREATER_THAN(Wasm)
#undef STACK_POINTER_GREATER_THAN
}; };
struct CommentOperator : public Operator1<const char*> { struct CommentOperator : public Operator1<const char*> {
explicit CommentOperator(const char* msg) explicit CommentOperator(const char* msg)
: Operator1(IrOpcode::kComment, Operator::kNoThrow | Operator::kNoWrite, : Operator1<const char*>(IrOpcode::kComment,
"Comment", 0, 1, 1, 0, 1, 0, msg) {} Operator::kNoThrow | Operator::kNoWrite,
"Comment", 0, 1, 1, 0, 1, 0, msg) {}
}; };
namespace {
DEFINE_LAZY_LEAKY_OBJECT_GETTER(MachineOperatorGlobalCache,
GetMachineOperatorGlobalCache)
}
MachineOperatorBuilder::MachineOperatorBuilder( MachineOperatorBuilder::MachineOperatorBuilder(
Zone* zone, MachineRepresentation word, Flags flags, Zone* zone, MachineRepresentation word, Flags flags,
AlignmentRequirements alignmentRequirements) AlignmentRequirements alignmentRequirements)
: zone_(zone), : zone_(zone),
cache_(*GetMachineOperatorGlobalCache()),
word_(word), word_(word),
flags_(flags), flags_(flags),
alignment_requirements_(alignmentRequirements) { alignment_requirements_(alignmentRequirements) {
...@@ -1078,11 +1251,9 @@ MachineOperatorBuilder::MachineOperatorBuilder( ...@@ -1078,11 +1251,9 @@ MachineOperatorBuilder::MachineOperatorBuilder(
} }
const Operator* MachineOperatorBuilder::UnalignedLoad(LoadRepresentation rep) { const Operator* MachineOperatorBuilder::UnalignedLoad(LoadRepresentation rep) {
#define LOAD(Type) \ #define LOAD(Type) \
if (rep == MachineType::Type()) { \ if (rep == MachineType::Type()) { \
return GetCachedOperator< \ return &cache_.kUnalignedLoad##Type; \
UnalignedLoadOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
MACHINE_TYPE_LIST(LOAD) MACHINE_TYPE_LIST(LOAD)
#undef LOAD #undef LOAD
...@@ -1094,8 +1265,7 @@ const Operator* MachineOperatorBuilder::UnalignedStore( ...@@ -1094,8 +1265,7 @@ const Operator* MachineOperatorBuilder::UnalignedStore(
switch (rep) { switch (rep) {
#define STORE(kRep) \ #define STORE(kRep) \
case MachineRepresentation::kRep: \ case MachineRepresentation::kRep: \
return GetCachedOperator< \ return &cache_.kUnalignedStore##kRep;
UnalignedStoreOperator<MachineRepresentation::kRep>>();
MACHINE_REPRESENTATION_LIST(STORE) MACHINE_REPRESENTATION_LIST(STORE)
#undef STORE #undef STORE
case MachineRepresentation::kBit: case MachineRepresentation::kBit:
...@@ -1105,103 +1275,85 @@ const Operator* MachineOperatorBuilder::UnalignedStore( ...@@ -1105,103 +1275,85 @@ const Operator* MachineOperatorBuilder::UnalignedStore(
UNREACHABLE(); UNREACHABLE();
} }
template <TruncateKind kind> #define PURE(Name, properties, value_input_count, control_input_count, \
struct TruncateFloat32ToUint32Operator : Operator1<TruncateKind> { output_count) \
TruncateFloat32ToUint32Operator() const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; }
: Operator1(IrOpcode::kTruncateFloat32ToUint32, Operator::kPure, MACHINE_PURE_OP_LIST(PURE)
"TruncateFloat32ToUint32", 1, 0, 0, 1, 0, 0, kind) {} #undef PURE
};
const Operator* MachineOperatorBuilder::TruncateFloat32ToUint32( const Operator* MachineOperatorBuilder::Word32Sar(ShiftKind kind) {
TruncateKind kind) {
switch (kind) { switch (kind) {
case TruncateKind::kArchitectureDefault: case ShiftKind::kNormal:
return GetCachedOperator<TruncateFloat32ToUint32Operator< return &cache_.kNormalWord32Sar;
TruncateKind::kArchitectureDefault>>(); case ShiftKind::kShiftOutZeros:
case TruncateKind::kSetOverflowToMin: return &cache_.kShiftOutZerosWord32Sar;
return GetCachedOperator<
TruncateFloat32ToUint32Operator<TruncateKind::kSetOverflowToMin>>();
} }
} }
template <TruncateKind kind> const Operator* MachineOperatorBuilder::Word64Sar(ShiftKind kind) {
struct TruncateFloat32ToInt32Operator : Operator1<TruncateKind> { switch (kind) {
TruncateFloat32ToInt32Operator() case ShiftKind::kNormal:
: Operator1(IrOpcode::kTruncateFloat32ToInt32, Operator::kPure, return &cache_.kNormalWord64Sar;
"TruncateFloat32ToInt32", 1, 0, 0, 1, 0, 0, kind) {} case ShiftKind::kShiftOutZeros:
}; return &cache_.kShiftOutZerosWord64Sar;
}
}
const Operator* MachineOperatorBuilder::TruncateFloat32ToInt32( const Operator* MachineOperatorBuilder::TruncateFloat32ToUint32(
TruncateKind kind) { TruncateKind kind) {
switch (kind) { switch (kind) {
case TruncateKind::kArchitectureDefault: case TruncateKind::kArchitectureDefault:
return GetCachedOperator< return &cache_.kArchitectureDefaultTruncateFloat32ToUint32;
TruncateFloat32ToInt32Operator<TruncateKind::kArchitectureDefault>>();
case TruncateKind::kSetOverflowToMin: case TruncateKind::kSetOverflowToMin:
return GetCachedOperator< return &cache_.kSetOverflowToMinTruncateFloat32ToUint32;
TruncateFloat32ToInt32Operator<TruncateKind::kSetOverflowToMin>>();
} }
} }
template <TruncateKind kind>
struct TruncateFloat64ToInt64Operator : Operator1<TruncateKind> {
TruncateFloat64ToInt64Operator()
: Operator1(IrOpcode::kTruncateFloat64ToInt64, Operator::kPure,
"TruncateFloat64ToInt64", 1, 0, 0, 1, 0, 0, kind) {}
};
const Operator* MachineOperatorBuilder::TruncateFloat64ToInt64( const Operator* MachineOperatorBuilder::TruncateFloat64ToInt64(
TruncateKind kind) { TruncateKind kind) {
switch (kind) { switch (kind) {
case TruncateKind::kArchitectureDefault: case TruncateKind::kArchitectureDefault:
return GetCachedOperator< return &cache_.kArchitectureDefaultTruncateFloat64ToInt64;
TruncateFloat64ToInt64Operator<TruncateKind::kArchitectureDefault>>();
case TruncateKind::kSetOverflowToMin: case TruncateKind::kSetOverflowToMin:
return GetCachedOperator< return &cache_.kSetOverflowToMinTruncateFloat64ToInt64;
TruncateFloat64ToInt64Operator<TruncateKind::kSetOverflowToMin>>();
} }
} }
size_t hash_value(TruncateKind kind) { return static_cast<size_t>(kind); } const Operator* MachineOperatorBuilder::TruncateFloat32ToInt32(
TruncateKind kind) {
std::ostream& operator<<(std::ostream& os, TruncateKind kind) {
switch (kind) { switch (kind) {
case TruncateKind::kArchitectureDefault: case TruncateKind::kArchitectureDefault:
return os << "kArchitectureDefault"; return &cache_.kArchitectureDefaultTruncateFloat32ToInt32;
case TruncateKind::kSetOverflowToMin: case TruncateKind::kSetOverflowToMin:
return os << "kSetOverflowToMin"; return &cache_.kSetOverflowToMinTruncateFloat32ToInt32;
} }
} }
#define PURE(Name, properties, value_input_count, control_input_count, \ #define PURE(Name, properties, value_input_count, control_input_count, \
output_count) \ output_count) \
const Operator* MachineOperatorBuilder::Name() { \ const OptionalOperator MachineOperatorBuilder::Name() { \
return GetCachedOperator< \ return OptionalOperator(flags_ & k##Name, &cache_.k##Name); \
CachedPureOperator<IrOpcode::k##Name, value_input_count, \
control_input_count, output_count>>(properties, \
#Name); \
} }
MACHINE_PURE_OP_LIST(PURE) PURE_OPTIONAL_OP_LIST(PURE)
#undef PURE #undef PURE
const Operator* MachineOperatorBuilder::PrefetchTemporal() { const Operator* MachineOperatorBuilder::PrefetchTemporal() {
return GetCachedOperator< return &cache_.kPrefetchTemporal;
CachedOperator<IrOpcode::kPrefetchTemporal, 2, 1, 1, 0, 1, 0>>(
Operator::kNoDeopt | Operator::kNoThrow, "PrefetchTemporal");
} }
const Operator* MachineOperatorBuilder::PrefetchNonTemporal() { const Operator* MachineOperatorBuilder::PrefetchNonTemporal() {
return GetCachedOperator< return &cache_.kPrefetchNonTemporal;
CachedOperator<IrOpcode::kPrefetchNonTemporal, 2, 1, 1, 0, 1, 0>>(
Operator::kNoDeopt | Operator::kNoThrow, "PrefetchNonTemporal");
} }
#define OVERFLOW_OP(Name, properties) \
const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; }
OVERFLOW_OP_LIST(OVERFLOW_OP)
#undef OVERFLOW_OP
const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) { const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
#define LOAD(Type) \ #define LOAD(Type) \
if (rep == MachineType::Type()) { \ if (rep == MachineType::Type()) { \
return GetCachedOperator< \ return &cache_.kLoad##Type; \
LoadOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
MACHINE_TYPE_LIST(LOAD) MACHINE_TYPE_LIST(LOAD)
#undef LOAD #undef LOAD
...@@ -1209,11 +1361,9 @@ const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) { ...@@ -1209,11 +1361,9 @@ const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
} }
const Operator* MachineOperatorBuilder::PoisonedLoad(LoadRepresentation rep) { const Operator* MachineOperatorBuilder::PoisonedLoad(LoadRepresentation rep) {
#define LOAD(Type) \ #define LOAD(Type) \
if (rep == MachineType::Type()) { \ if (rep == MachineType::Type()) { \
return GetCachedOperator< \ return &cache_.kPoisonedLoad##Type; \
PoisonedLoadOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
MACHINE_TYPE_LIST(LOAD) MACHINE_TYPE_LIST(LOAD)
#undef LOAD #undef LOAD
...@@ -1221,11 +1371,9 @@ const Operator* MachineOperatorBuilder::PoisonedLoad(LoadRepresentation rep) { ...@@ -1221,11 +1371,9 @@ const Operator* MachineOperatorBuilder::PoisonedLoad(LoadRepresentation rep) {
} }
const Operator* MachineOperatorBuilder::ProtectedLoad(LoadRepresentation rep) { const Operator* MachineOperatorBuilder::ProtectedLoad(LoadRepresentation rep) {
#define LOAD(Type) \ #define LOAD(Type) \
if (rep == MachineType::Type()) { \ if (rep == MachineType::Type()) { \
return GetCachedOperator< \ return &cache_.kProtectedLoad##Type; \
ProtectedLoadOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
MACHINE_TYPE_LIST(LOAD) MACHINE_TYPE_LIST(LOAD)
#undef LOAD #undef LOAD
...@@ -1234,11 +1382,10 @@ const Operator* MachineOperatorBuilder::ProtectedLoad(LoadRepresentation rep) { ...@@ -1234,11 +1382,10 @@ const Operator* MachineOperatorBuilder::ProtectedLoad(LoadRepresentation rep) {
const Operator* MachineOperatorBuilder::LoadTransform( const Operator* MachineOperatorBuilder::LoadTransform(
MemoryAccessKind kind, LoadTransformation transform) { MemoryAccessKind kind, LoadTransformation transform) {
#define LOAD_TRANSFORM_KIND(TYPE, KIND) \ #define LOAD_TRANSFORM_KIND(TYPE, KIND) \
if (kind == MemoryAccessKind::k##KIND && \ if (kind == MemoryAccessKind::k##KIND && \
transform == LoadTransformation::k##TYPE) { \ transform == LoadTransformation::k##TYPE) { \
return GetCachedOperator<LoadTransformOperator< \ return &cache_.k##KIND##LoadTransform##TYPE; \
MemoryAccessKind::k##KIND, LoadTransformation::k##TYPE>>(); \
} }
#define LOAD_TRANSFORM(TYPE) \ #define LOAD_TRANSFORM(TYPE) \
LOAD_TRANSFORM_KIND(TYPE, Normal) \ LOAD_TRANSFORM_KIND(TYPE, Normal) \
...@@ -1257,9 +1404,14 @@ const Operator* MachineOperatorBuilder::LoadLane(MemoryAccessKind kind, ...@@ -1257,9 +1404,14 @@ const Operator* MachineOperatorBuilder::LoadLane(MemoryAccessKind kind,
#define LOAD_LANE_KIND(TYPE, KIND, LANEIDX) \ #define LOAD_LANE_KIND(TYPE, KIND, LANEIDX) \
if (kind == MemoryAccessKind::k##KIND && rep == MachineType::TYPE() && \ if (kind == MemoryAccessKind::k##KIND && rep == MachineType::TYPE() && \
laneidx == LANEIDX) { \ laneidx == LANEIDX) { \
return GetCachedOperator<LoadLaneOperator< \ return zone_->New<Operator1<LoadLaneParameters>>( \
MemoryAccessKind::k##KIND, MachineType::TYPE().representation(), \ IrOpcode::kLoadLane, \
MachineType::TYPE().semantic(), LANEIDX>>(); \ MemoryAccessKind::k##KIND == MemoryAccessKind::kProtected \
? Operator::kNoDeopt | Operator::kNoThrow \
: Operator::kEliminatable, \
"LoadLane", 3, 1, 1, 1, 1, 0, \
LoadLaneParameters{MemoryAccessKind::k##KIND, \
LoadRepresentation::TYPE(), LANEIDX}); \
} }
#define LOAD_LANE_T(T, LANE) \ #define LOAD_LANE_T(T, LANE) \
...@@ -1288,11 +1440,15 @@ const Operator* MachineOperatorBuilder::LoadLane(MemoryAccessKind kind, ...@@ -1288,11 +1440,15 @@ const Operator* MachineOperatorBuilder::LoadLane(MemoryAccessKind kind,
const Operator* MachineOperatorBuilder::StoreLane(MemoryAccessKind kind, const Operator* MachineOperatorBuilder::StoreLane(MemoryAccessKind kind,
MachineRepresentation rep, MachineRepresentation rep,
uint8_t laneidx) { uint8_t laneidx) {
#define STORE_LANE_KIND(REP, KIND, LANEIDX) \ #define STORE_LANE_KIND(REP, KIND, LANEIDX) \
if (kind == MemoryAccessKind::k##KIND && \ if (kind == MemoryAccessKind::k##KIND && \
rep == MachineRepresentation::REP && laneidx == LANEIDX) { \ rep == MachineRepresentation::REP && laneidx == LANEIDX) { \
return GetCachedOperator<StoreLaneOperator< \ return zone_->New<Operator1<StoreLaneParameters>>( \
MemoryAccessKind::k##KIND, MachineRepresentation::REP, LANEIDX>>(); \ IrOpcode::kStoreLane, \
Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
"StoreLane", 3, 1, 1, 0, 1, 0, \
StoreLaneParameters{MemoryAccessKind::k##KIND, \
MachineRepresentation::REP, LANEIDX}); \
} }
#define STORE_LANE_T(T, LANE) \ #define STORE_LANE_T(T, LANE) \
...@@ -1321,9 +1477,9 @@ const Operator* MachineOperatorBuilder::StoreLane(MemoryAccessKind kind, ...@@ -1321,9 +1477,9 @@ const Operator* MachineOperatorBuilder::StoreLane(MemoryAccessKind kind,
const Operator* MachineOperatorBuilder::StackSlot(int size, int alignment) { const Operator* MachineOperatorBuilder::StackSlot(int size, int alignment) {
DCHECK_LE(0, size); DCHECK_LE(0, size);
DCHECK(alignment == 0 || alignment == 4 || alignment == 8 || alignment == 16); DCHECK(alignment == 0 || alignment == 4 || alignment == 8 || alignment == 16);
#define CASE_CACHED_SIZE(Size, Alignment) \ #define CASE_CACHED_SIZE(Size, Alignment) \
if (size == Size && alignment == Alignment) { \ if (size == Size && alignment == Alignment) { \
return GetCachedOperator<CachedStackSlotOperator<Size, Alignment>>(); \ return &cache_.kStackSlotOfSize##Size##OfAlignment##Alignment; \
} }
STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST(CASE_CACHED_SIZE) STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST(CASE_CACHED_SIZE)
...@@ -1339,28 +1495,22 @@ const Operator* MachineOperatorBuilder::StackSlot(MachineRepresentation rep, ...@@ -1339,28 +1495,22 @@ const Operator* MachineOperatorBuilder::StackSlot(MachineRepresentation rep,
const Operator* MachineOperatorBuilder::Store(StoreRepresentation store_rep) { const Operator* MachineOperatorBuilder::Store(StoreRepresentation store_rep) {
switch (store_rep.representation()) { switch (store_rep.representation()) {
#define STORE(kRep) \ #define STORE(kRep) \
case MachineRepresentation::kRep: \ case MachineRepresentation::kRep: \
switch (store_rep.write_barrier_kind()) { \ switch (store_rep.write_barrier_kind()) { \
case kNoWriteBarrier: \ case kNoWriteBarrier: \
return GetCachedOperator< \ return &cache_.k##Store##kRep##NoWriteBarrier; \
StoreOperator<MachineRepresentation::kRep, kNoWriteBarrier>>(); \ case kAssertNoWriteBarrier: \
case kAssertNoWriteBarrier: \ return &cache_.k##Store##kRep##AssertNoWriteBarrier; \
return GetCachedOperator<StoreOperator<MachineRepresentation::kRep, \ case kMapWriteBarrier: \
kAssertNoWriteBarrier>>(); \ return &cache_.k##Store##kRep##MapWriteBarrier; \
case kMapWriteBarrier: \ case kPointerWriteBarrier: \
return GetCachedOperator< \ return &cache_.k##Store##kRep##PointerWriteBarrier; \
StoreOperator<MachineRepresentation::kRep, kMapWriteBarrier>>(); \ case kEphemeronKeyWriteBarrier: \
case kPointerWriteBarrier: \ return &cache_.k##Store##kRep##EphemeronKeyWriteBarrier; \
return GetCachedOperator<StoreOperator<MachineRepresentation::kRep, \ case kFullWriteBarrier: \
kPointerWriteBarrier>>(); \ return &cache_.k##Store##kRep##FullWriteBarrier; \
case kEphemeronKeyWriteBarrier: \ } \
return GetCachedOperator<StoreOperator<MachineRepresentation::kRep, \
kEphemeronKeyWriteBarrier>>(); \
case kFullWriteBarrier: \
return GetCachedOperator< \
StoreOperator<MachineRepresentation::kRep, kFullWriteBarrier>>(); \
} \
break; break;
MACHINE_REPRESENTATION_LIST(STORE) MACHINE_REPRESENTATION_LIST(STORE)
#undef STORE #undef STORE
...@@ -1374,10 +1524,9 @@ const Operator* MachineOperatorBuilder::Store(StoreRepresentation store_rep) { ...@@ -1374,10 +1524,9 @@ const Operator* MachineOperatorBuilder::Store(StoreRepresentation store_rep) {
const Operator* MachineOperatorBuilder::ProtectedStore( const Operator* MachineOperatorBuilder::ProtectedStore(
MachineRepresentation rep) { MachineRepresentation rep) {
switch (rep) { switch (rep) {
#define STORE(kRep) \ #define STORE(kRep) \
case MachineRepresentation::kRep: \ case MachineRepresentation::kRep: \
return GetCachedOperator< \ return &cache_.kProtectedStore##kRep; \
ProtectedStoreOperator<MachineRepresentation::kRep>>(); \
break; break;
MACHINE_REPRESENTATION_LIST(STORE) MACHINE_REPRESENTATION_LIST(STORE)
#undef STORE #undef STORE
...@@ -1389,46 +1538,42 @@ const Operator* MachineOperatorBuilder::ProtectedStore( ...@@ -1389,46 +1538,42 @@ const Operator* MachineOperatorBuilder::ProtectedStore(
} }
const Operator* MachineOperatorBuilder::UnsafePointerAdd() { const Operator* MachineOperatorBuilder::UnsafePointerAdd() {
return GetCachedOperator<UnsafePointerAddOperator>(); return &cache_.kUnsafePointerAdd;
} }
const Operator* MachineOperatorBuilder::StackPointerGreaterThan( const Operator* MachineOperatorBuilder::StackPointerGreaterThan(
StackCheckKind kind) { StackCheckKind kind) {
switch (kind) { switch (kind) {
case StackCheckKind::kJSFunctionEntry: case StackCheckKind::kJSFunctionEntry:
return GetCachedOperator< return &cache_.kStackPointerGreaterThanJSFunctionEntry;
StackPointerGreaterThanOperator<StackCheckKind::kJSFunctionEntry>>();
case StackCheckKind::kJSIterationBody: case StackCheckKind::kJSIterationBody:
return GetCachedOperator< return &cache_.kStackPointerGreaterThanJSIterationBody;
StackPointerGreaterThanOperator<StackCheckKind::kJSIterationBody>>();
case StackCheckKind::kCodeStubAssembler: case StackCheckKind::kCodeStubAssembler:
return GetCachedOperator<StackPointerGreaterThanOperator< return &cache_.kStackPointerGreaterThanCodeStubAssembler;
StackCheckKind::kCodeStubAssembler>>();
case StackCheckKind::kWasm: case StackCheckKind::kWasm:
return GetCachedOperator< return &cache_.kStackPointerGreaterThanWasm;
StackPointerGreaterThanOperator<StackCheckKind::kWasm>>();
} }
UNREACHABLE(); UNREACHABLE();
} }
const Operator* MachineOperatorBuilder::BitcastWordToTagged() { const Operator* MachineOperatorBuilder::BitcastWordToTagged() {
return GetCachedOperator<BitcastWordToTaggedOperator>(); return &cache_.kBitcastWordToTagged;
} }
const Operator* MachineOperatorBuilder::BitcastTaggedToWord() { const Operator* MachineOperatorBuilder::BitcastTaggedToWord() {
return GetCachedOperator<BitcastTaggedToWordOperator>(); return &cache_.kBitcastTaggedToWord;
} }
const Operator* MachineOperatorBuilder::BitcastMaybeObjectToWord() { const Operator* MachineOperatorBuilder::BitcastMaybeObjectToWord() {
return GetCachedOperator<BitcastMaybeObjectToWordOperator>(); return &cache_.kBitcastMaybeObjectToWord;
} }
const Operator* MachineOperatorBuilder::AbortCSAAssert() { const Operator* MachineOperatorBuilder::AbortCSAAssert() {
return GetCachedOperator<AbortCSAAssertOperator>(); return &cache_.kAbortCSAAssert;
} }
const Operator* MachineOperatorBuilder::DebugBreak() { const Operator* MachineOperatorBuilder::DebugBreak() {
return GetCachedOperator<DebugBreakOperator>(); return &cache_.kDebugBreak;
} }
const Operator* MachineOperatorBuilder::Comment(const char* msg) { const Operator* MachineOperatorBuilder::Comment(const char* msg) {
...@@ -1436,16 +1581,14 @@ const Operator* MachineOperatorBuilder::Comment(const char* msg) { ...@@ -1436,16 +1581,14 @@ const Operator* MachineOperatorBuilder::Comment(const char* msg) {
} }
const Operator* MachineOperatorBuilder::MemBarrier() { const Operator* MachineOperatorBuilder::MemBarrier() {
return GetCachedOperator<MemoryBarrierOperator>(); return &cache_.kMemoryBarrier;
} }
const Operator* MachineOperatorBuilder::Word32AtomicLoad( const Operator* MachineOperatorBuilder::Word32AtomicLoad(
LoadRepresentation rep) { LoadRepresentation rep) {
#define LOAD(Type) \ #define LOAD(Type) \
if (rep == MachineType::Type()) { \ if (rep == MachineType::Type()) { \
return GetCachedOperator< \ return &cache_.kWord32AtomicLoad##Type; \
Word32AtomicLoadOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
ATOMIC_TYPE_LIST(LOAD) ATOMIC_TYPE_LIST(LOAD)
#undef LOAD #undef LOAD
...@@ -1454,10 +1597,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicLoad( ...@@ -1454,10 +1597,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicLoad(
const Operator* MachineOperatorBuilder::Word32AtomicStore( const Operator* MachineOperatorBuilder::Word32AtomicStore(
MachineRepresentation rep) { MachineRepresentation rep) {
#define STORE(kRep) \ #define STORE(kRep) \
if (rep == MachineRepresentation::kRep) { \ if (rep == MachineRepresentation::kRep) { \
return GetCachedOperator< \ return &cache_.kWord32AtomicStore##kRep; \
Word32AtomicStoreOperator<MachineRepresentation::kRep>>(); \
} }
ATOMIC_REPRESENTATION_LIST(STORE) ATOMIC_REPRESENTATION_LIST(STORE)
#undef STORE #undef STORE
...@@ -1465,11 +1607,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicStore( ...@@ -1465,11 +1607,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicStore(
} }
const Operator* MachineOperatorBuilder::Word32AtomicExchange(MachineType type) { const Operator* MachineOperatorBuilder::Word32AtomicExchange(MachineType type) {
#define EXCHANGE(Type) \ #define EXCHANGE(kType) \
if (type == MachineType::Type()) { \ if (type == MachineType::kType()) { \
return GetCachedOperator< \ return &cache_.kWord32AtomicExchange##kType; \
Word32AtomicExchangeOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
ATOMIC_TYPE_LIST(EXCHANGE) ATOMIC_TYPE_LIST(EXCHANGE)
#undef EXCHANGE #undef EXCHANGE
...@@ -1478,11 +1618,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicExchange(MachineType type) { ...@@ -1478,11 +1618,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicExchange(MachineType type) {
const Operator* MachineOperatorBuilder::Word32AtomicCompareExchange( const Operator* MachineOperatorBuilder::Word32AtomicCompareExchange(
MachineType type) { MachineType type) {
#define COMPARE_EXCHANGE(Type) \ #define COMPARE_EXCHANGE(kType) \
if (type == MachineType::Type()) { \ if (type == MachineType::kType()) { \
return GetCachedOperator<Word32AtomicCompareExchangeOperator< \ return &cache_.kWord32AtomicCompareExchange##kType; \
MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
ATOMIC_TYPE_LIST(COMPARE_EXCHANGE) ATOMIC_TYPE_LIST(COMPARE_EXCHANGE)
#undef COMPARE_EXCHANGE #undef COMPARE_EXCHANGE
...@@ -1490,11 +1628,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicCompareExchange( ...@@ -1490,11 +1628,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicCompareExchange(
} }
const Operator* MachineOperatorBuilder::Word32AtomicAdd(MachineType type) { const Operator* MachineOperatorBuilder::Word32AtomicAdd(MachineType type) {
#define ADD(Type) \ #define ADD(kType) \
if (type == MachineType::Type()) { \ if (type == MachineType::kType()) { \
return GetCachedOperator< \ return &cache_.kWord32AtomicAdd##kType; \
Word32AtomicAddOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
ATOMIC_TYPE_LIST(ADD) ATOMIC_TYPE_LIST(ADD)
#undef ADD #undef ADD
...@@ -1502,11 +1638,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicAdd(MachineType type) { ...@@ -1502,11 +1638,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicAdd(MachineType type) {
} }
const Operator* MachineOperatorBuilder::Word32AtomicSub(MachineType type) { const Operator* MachineOperatorBuilder::Word32AtomicSub(MachineType type) {
#define SUB(Type) \ #define SUB(kType) \
if (type == MachineType::Type()) { \ if (type == MachineType::kType()) { \
return GetCachedOperator< \ return &cache_.kWord32AtomicSub##kType; \
Word32AtomicSubOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
ATOMIC_TYPE_LIST(SUB) ATOMIC_TYPE_LIST(SUB)
#undef SUB #undef SUB
...@@ -1514,11 +1648,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicSub(MachineType type) { ...@@ -1514,11 +1648,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicSub(MachineType type) {
} }
const Operator* MachineOperatorBuilder::Word32AtomicAnd(MachineType type) { const Operator* MachineOperatorBuilder::Word32AtomicAnd(MachineType type) {
#define AND(Type) \ #define AND(kType) \
if (type == MachineType::Type()) { \ if (type == MachineType::kType()) { \
return GetCachedOperator< \ return &cache_.kWord32AtomicAnd##kType; \
Word32AtomicAndOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
ATOMIC_TYPE_LIST(AND) ATOMIC_TYPE_LIST(AND)
#undef AND #undef AND
...@@ -1526,11 +1658,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicAnd(MachineType type) { ...@@ -1526,11 +1658,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicAnd(MachineType type) {
} }
const Operator* MachineOperatorBuilder::Word32AtomicOr(MachineType type) { const Operator* MachineOperatorBuilder::Word32AtomicOr(MachineType type) {
#define OR(Type) \ #define OR(kType) \
if (type == MachineType::Type()) { \ if (type == MachineType::kType()) { \
return GetCachedOperator< \ return &cache_.kWord32AtomicOr##kType; \
Word32AtomicOrOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
ATOMIC_TYPE_LIST(OR) ATOMIC_TYPE_LIST(OR)
#undef OR #undef OR
...@@ -1538,11 +1668,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicOr(MachineType type) { ...@@ -1538,11 +1668,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicOr(MachineType type) {
} }
const Operator* MachineOperatorBuilder::Word32AtomicXor(MachineType type) { const Operator* MachineOperatorBuilder::Word32AtomicXor(MachineType type) {
#define XOR(Type) \ #define XOR(kType) \
if (type == MachineType::Type()) { \ if (type == MachineType::kType()) { \
return GetCachedOperator< \ return &cache_.kWord32AtomicXor##kType; \
Word32AtomicXorOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
ATOMIC_TYPE_LIST(XOR) ATOMIC_TYPE_LIST(XOR)
#undef XOR #undef XOR
...@@ -1551,11 +1679,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicXor(MachineType type) { ...@@ -1551,11 +1679,9 @@ const Operator* MachineOperatorBuilder::Word32AtomicXor(MachineType type) {
const Operator* MachineOperatorBuilder::Word64AtomicLoad( const Operator* MachineOperatorBuilder::Word64AtomicLoad(
LoadRepresentation rep) { LoadRepresentation rep) {
#define LOAD(Type) \ #define LOAD(Type) \
if (rep == MachineType::Type()) { \ if (rep == MachineType::Type()) { \
return GetCachedOperator< \ return &cache_.kWord64AtomicLoad##Type; \
Word64AtomicLoadOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
ATOMIC_U64_TYPE_LIST(LOAD) ATOMIC_U64_TYPE_LIST(LOAD)
#undef LOAD #undef LOAD
...@@ -1564,10 +1690,9 @@ const Operator* MachineOperatorBuilder::Word64AtomicLoad( ...@@ -1564,10 +1690,9 @@ const Operator* MachineOperatorBuilder::Word64AtomicLoad(
const Operator* MachineOperatorBuilder::Word64AtomicStore( const Operator* MachineOperatorBuilder::Word64AtomicStore(
MachineRepresentation rep) { MachineRepresentation rep) {
#define STORE(kRep) \ #define STORE(kRep) \
if (rep == MachineRepresentation::kRep) { \ if (rep == MachineRepresentation::kRep) { \
return GetCachedOperator< \ return &cache_.kWord64AtomicStore##kRep; \
Word64AtomicStoreOperator<MachineRepresentation::kRep>>(); \
} }
ATOMIC64_REPRESENTATION_LIST(STORE) ATOMIC64_REPRESENTATION_LIST(STORE)
#undef STORE #undef STORE
...@@ -1575,11 +1700,9 @@ const Operator* MachineOperatorBuilder::Word64AtomicStore( ...@@ -1575,11 +1700,9 @@ const Operator* MachineOperatorBuilder::Word64AtomicStore(
} }
const Operator* MachineOperatorBuilder::Word64AtomicAdd(MachineType type) { const Operator* MachineOperatorBuilder::Word64AtomicAdd(MachineType type) {
#define ADD(Type) \ #define ADD(kType) \
if (type == MachineType::Type()) { \ if (type == MachineType::kType()) { \
return GetCachedOperator< \ return &cache_.kWord64AtomicAdd##kType; \
Word64AtomicAddOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
ATOMIC_U64_TYPE_LIST(ADD) ATOMIC_U64_TYPE_LIST(ADD)
#undef ADD #undef ADD
...@@ -1587,11 +1710,9 @@ const Operator* MachineOperatorBuilder::Word64AtomicAdd(MachineType type) { ...@@ -1587,11 +1710,9 @@ const Operator* MachineOperatorBuilder::Word64AtomicAdd(MachineType type) {
} }
const Operator* MachineOperatorBuilder::Word64AtomicSub(MachineType type) { const Operator* MachineOperatorBuilder::Word64AtomicSub(MachineType type) {
#define SUB(Type) \ #define SUB(kType) \
if (type == MachineType::Type()) { \ if (type == MachineType::kType()) { \
return GetCachedOperator< \ return &cache_.kWord64AtomicSub##kType; \
Word64AtomicSubOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
ATOMIC_U64_TYPE_LIST(SUB) ATOMIC_U64_TYPE_LIST(SUB)
#undef SUB #undef SUB
...@@ -1599,11 +1720,9 @@ const Operator* MachineOperatorBuilder::Word64AtomicSub(MachineType type) { ...@@ -1599,11 +1720,9 @@ const Operator* MachineOperatorBuilder::Word64AtomicSub(MachineType type) {
} }
const Operator* MachineOperatorBuilder::Word64AtomicAnd(MachineType type) { const Operator* MachineOperatorBuilder::Word64AtomicAnd(MachineType type) {
#define AND(Type) \ #define AND(kType) \
if (type == MachineType::Type()) { \ if (type == MachineType::kType()) { \
return GetCachedOperator< \ return &cache_.kWord64AtomicAnd##kType; \
Word64AtomicAndOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
ATOMIC_U64_TYPE_LIST(AND) ATOMIC_U64_TYPE_LIST(AND)
#undef AND #undef AND
...@@ -1611,11 +1730,9 @@ const Operator* MachineOperatorBuilder::Word64AtomicAnd(MachineType type) { ...@@ -1611,11 +1730,9 @@ const Operator* MachineOperatorBuilder::Word64AtomicAnd(MachineType type) {
} }
const Operator* MachineOperatorBuilder::Word64AtomicOr(MachineType type) { const Operator* MachineOperatorBuilder::Word64AtomicOr(MachineType type) {
#define OR(Type) \ #define OR(kType) \
if (type == MachineType::Type()) { \ if (type == MachineType::kType()) { \
return GetCachedOperator< \ return &cache_.kWord64AtomicOr##kType; \
Word64AtomicOrOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
ATOMIC_U64_TYPE_LIST(OR) ATOMIC_U64_TYPE_LIST(OR)
#undef OR #undef OR
...@@ -1623,11 +1740,9 @@ const Operator* MachineOperatorBuilder::Word64AtomicOr(MachineType type) { ...@@ -1623,11 +1740,9 @@ const Operator* MachineOperatorBuilder::Word64AtomicOr(MachineType type) {
} }
const Operator* MachineOperatorBuilder::Word64AtomicXor(MachineType type) { const Operator* MachineOperatorBuilder::Word64AtomicXor(MachineType type) {
#define XOR(Type) \ #define XOR(kType) \
if (type == MachineType::Type()) { \ if (type == MachineType::kType()) { \
return GetCachedOperator< \ return &cache_.kWord64AtomicXor##kType; \
Word64AtomicXorOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
ATOMIC_U64_TYPE_LIST(XOR) ATOMIC_U64_TYPE_LIST(XOR)
#undef XOR #undef XOR
...@@ -1635,11 +1750,9 @@ const Operator* MachineOperatorBuilder::Word64AtomicXor(MachineType type) { ...@@ -1635,11 +1750,9 @@ const Operator* MachineOperatorBuilder::Word64AtomicXor(MachineType type) {
} }
const Operator* MachineOperatorBuilder::Word64AtomicExchange(MachineType type) { const Operator* MachineOperatorBuilder::Word64AtomicExchange(MachineType type) {
#define EXCHANGE(Type) \ #define EXCHANGE(kType) \
if (type == MachineType::Type()) { \ if (type == MachineType::kType()) { \
return GetCachedOperator< \ return &cache_.kWord64AtomicExchange##kType; \
Word64AtomicExchangeOperator<MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
ATOMIC_U64_TYPE_LIST(EXCHANGE) ATOMIC_U64_TYPE_LIST(EXCHANGE)
#undef EXCHANGE #undef EXCHANGE
...@@ -1648,11 +1761,9 @@ const Operator* MachineOperatorBuilder::Word64AtomicExchange(MachineType type) { ...@@ -1648,11 +1761,9 @@ const Operator* MachineOperatorBuilder::Word64AtomicExchange(MachineType type) {
const Operator* MachineOperatorBuilder::Word64AtomicCompareExchange( const Operator* MachineOperatorBuilder::Word64AtomicCompareExchange(
MachineType type) { MachineType type) {
#define COMPARE_EXCHANGE(Type) \ #define COMPARE_EXCHANGE(kType) \
if (type == MachineType::Type()) { \ if (type == MachineType::kType()) { \
return GetCachedOperator<Word64AtomicCompareExchangeOperator< \ return &cache_.kWord64AtomicCompareExchange##kType; \
MachineType::Type().representation(), \
MachineType::Type().semantic()>>(); \
} }
ATOMIC_U64_TYPE_LIST(COMPARE_EXCHANGE) ATOMIC_U64_TYPE_LIST(COMPARE_EXCHANGE)
#undef COMPARE_EXCHANGE #undef COMPARE_EXCHANGE
...@@ -1660,51 +1771,51 @@ const Operator* MachineOperatorBuilder::Word64AtomicCompareExchange( ...@@ -1660,51 +1771,51 @@ const Operator* MachineOperatorBuilder::Word64AtomicCompareExchange(
} }
const Operator* MachineOperatorBuilder::Word32AtomicPairLoad() { const Operator* MachineOperatorBuilder::Word32AtomicPairLoad() {
return GetCachedOperator<Word32AtomicPairLoadOperator>(); return &cache_.kWord32AtomicPairLoad;
} }
const Operator* MachineOperatorBuilder::Word32AtomicPairStore() { const Operator* MachineOperatorBuilder::Word32AtomicPairStore() {
return GetCachedOperator<Word32AtomicPairStoreOperator>(); return &cache_.kWord32AtomicPairStore;
} }
const Operator* MachineOperatorBuilder::Word32AtomicPairAdd() { const Operator* MachineOperatorBuilder::Word32AtomicPairAdd() {
return GetCachedOperator<Word32AtomicPairAddOperator>(); return &cache_.kWord32AtomicPairAdd;
} }
const Operator* MachineOperatorBuilder::Word32AtomicPairSub() { const Operator* MachineOperatorBuilder::Word32AtomicPairSub() {
return GetCachedOperator<Word32AtomicPairSubOperator>(); return &cache_.kWord32AtomicPairSub;
} }
const Operator* MachineOperatorBuilder::Word32AtomicPairAnd() { const Operator* MachineOperatorBuilder::Word32AtomicPairAnd() {
return GetCachedOperator<Word32AtomicPairAndOperator>(); return &cache_.kWord32AtomicPairAnd;
} }
const Operator* MachineOperatorBuilder::Word32AtomicPairOr() { const Operator* MachineOperatorBuilder::Word32AtomicPairOr() {
return GetCachedOperator<Word32AtomicPairOrOperator>(); return &cache_.kWord32AtomicPairOr;
} }
const Operator* MachineOperatorBuilder::Word32AtomicPairXor() { const Operator* MachineOperatorBuilder::Word32AtomicPairXor() {
return GetCachedOperator<Word32AtomicPairXorOperator>(); return &cache_.kWord32AtomicPairXor;
} }
const Operator* MachineOperatorBuilder::Word32AtomicPairExchange() { const Operator* MachineOperatorBuilder::Word32AtomicPairExchange() {
return GetCachedOperator<Word32AtomicPairExchangeOperator>(); return &cache_.kWord32AtomicPairExchange;
} }
const Operator* MachineOperatorBuilder::Word32AtomicPairCompareExchange() { const Operator* MachineOperatorBuilder::Word32AtomicPairCompareExchange() {
return GetCachedOperator<Word32AtomicPairCompareExchangeOperator>(); return &cache_.kWord32AtomicPairCompareExchange;
} }
const Operator* MachineOperatorBuilder::TaggedPoisonOnSpeculation() { const Operator* MachineOperatorBuilder::TaggedPoisonOnSpeculation() {
return GetCachedOperator<TaggedPoisonOnSpeculationOperator>(); return &cache_.kTaggedPoisonOnSpeculation;
} }
const Operator* MachineOperatorBuilder::Word32PoisonOnSpeculation() { const Operator* MachineOperatorBuilder::Word32PoisonOnSpeculation() {
return GetCachedOperator<Word32PoisonOnSpeculationOperator>(); return &cache_.kWord32PoisonOnSpeculation;
} }
const Operator* MachineOperatorBuilder::Word64PoisonOnSpeculation() { const Operator* MachineOperatorBuilder::Word64PoisonOnSpeculation() {
return GetCachedOperator<Word64PoisonOnSpeculationOperator>(); return &cache_.kWord64PoisonOnSpeculation;
} }
const Operator* MachineOperatorBuilder::I32x4WidenI8x16S(uint8_t laneidx) { const Operator* MachineOperatorBuilder::I32x4WidenI8x16S(uint8_t laneidx) {
......
...@@ -18,6 +18,7 @@ namespace internal { ...@@ -18,6 +18,7 @@ namespace internal {
namespace compiler { namespace compiler {
// Forward declarations. // Forward declarations.
struct MachineOperatorGlobalCache;
class Operator; class Operator;
...@@ -989,6 +990,7 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final ...@@ -989,6 +990,7 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final
private: private:
Zone* zone_; Zone* zone_;
MachineOperatorGlobalCache const& cache_;
MachineRepresentation const word_; MachineRepresentation const word_;
Flags const flags_; Flags const flags_;
AlignmentRequirements const alignment_requirements_; AlignmentRequirements const alignment_requirements_;
......
...@@ -68,6 +68,8 @@ class V8_EXPORT_PRIVATE Operator : public NON_EXPORTED_BASE(ZoneObject) { ...@@ -68,6 +68,8 @@ class V8_EXPORT_PRIVATE Operator : public NON_EXPORTED_BASE(ZoneObject) {
Operator(const Operator&) = delete; Operator(const Operator&) = delete;
Operator& operator=(const Operator&) = delete; Operator& operator=(const Operator&) = delete;
virtual ~Operator() = default;
// A small integer unique to all instances of a particular kind of operator, // A small integer unique to all instances of a particular kind of operator,
// useful for quick matching for specific kinds of operators. For fast access // useful for quick matching for specific kinds of operators. For fast access
// the opcode is stored directly in the operator object. // the opcode is stored directly in the operator object.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment