22 gasm_(mcgraph, mcgraph->zone()),
27 switch (node->opcode()) {
28 case IrOpcode::kStart:
30 case IrOpcode::kWasmStructGet:
31 case IrOpcode::kWasmStructSet:
33 case IrOpcode::kWasmArrayLength:
35 case IrOpcode::kAssertNotNull:
37 case IrOpcode::kIsNull:
38 case IrOpcode::kIsNotNull:
40 case IrOpcode::kWasmTypeCheck:
42 case IrOpcode::kWasmTypeCheckAbstract:
44 case IrOpcode::kWasmTypeCast:
46 case IrOpcode::kWasmTypeCastAbstract:
48 case IrOpcode::kTypeGuard:
50 case IrOpcode::kWasmAnyConvertExtern:
52 case IrOpcode::kMerge:
54 case IrOpcode::kIfTrue:
56 case IrOpcode::kIfFalse:
63 if (node->op()->ControlOutputCount() > 0) {
64 DCHECK_EQ(1, node->op()->ControlInputCount());
73bool InDeadBranch(
Node* node) {
74 return node->opcode() == IrOpcode::kDead ||
75 node->opcode() == IrOpcode::kDeadValue ||
79Node* GetAlias(Node* node) {
80 switch (node->opcode()) {
81 case IrOpcode::kWasmTypeCast:
82 case IrOpcode::kWasmTypeCastAbstract:
83 case IrOpcode::kTypeGuard:
84 case IrOpcode::kAssertNotNull:
102 if (!previous_knowledge.
IsEmpty()) {
108 while (current !=
nullptr) {
111 current = GetAlias(current);
112 current_state =
GetState(state_owner);
113 in_new_block =
false;
123 Node*
object,
Node* control,
bool allow_non_wasm) {
124 if (object->opcode() == IrOpcode::kDead ||
125 object->opcode() == IrOpcode::kDeadValue) {
131 if (allow_non_wasm && !raw_type.IsWasm())
return {};
134 NodeWithType type_from_state = state.LookupState(
object);
136 while (object->opcode() == IrOpcode::kTypeGuard && !type_from_state.
IsSet()) {
138 type_from_state = state.LookupState(
object);
140 if (!type_from_state.
IsSet())
return type_from_node;
145 DCHECK(node->opcode() == IrOpcode::kWasmStructGet ||
146 node->opcode() == IrOpcode::kWasmStructSet);
159 node->
opcode() == IrOpcode::kWasmStructGet
160 ?
simplified()->WasmStructGet(op_params.type, op_params.field_index,
163 :
simplified()->WasmStructSet(op_params.type, op_params.field_index,
175 DCHECK_EQ(node->opcode(), IrOpcode::kWasmArrayLength);
200 DCHECK(node->opcode() == IrOpcode::kIfTrue ||
201 node->opcode() == IrOpcode::kIfFalse);
208 switch (condition_node->
opcode()) {
209 case IrOpcode::kWasmTypeCheck:
210 case IrOpcode::kWasmTypeCheckAbstract: {
226 case IrOpcode::kIsNull:
227 case IrOpcode::kIsNotNull: {
251 for (
Node* input : inputs) {
255 auto input_it = inputs.
begin();
262 auto input_end = inputs.
end();
263 for (; input_it != input_end; ++input_it) {
274 DCHECK_EQ(node->opcode(), IrOpcode::kAssertNotNull);
297 DCHECK(node->opcode() == IrOpcode::kIsNull ||
298 node->opcode() == IrOpcode::kIsNotNull);
309 node->opcode() == IrOpcode::kIsNull ? 0 : 1),
316 if (object->opcode() == IrOpcode::kNull) {
319 node->opcode() == IrOpcode::kIsNull ? 1 : 0),
329 DCHECK_EQ(node->opcode(), IrOpcode::kWasmAnyConvertExtern);
332 while (input->opcode() == IrOpcode::kTypeGuard) {
335 if (input->opcode() == IrOpcode::kDead ||
336 input->opcode() == IrOpcode::kDeadValue) {
339 if (input->opcode() == IrOpcode::kWasmExternConvertAny) {
350 DCHECK_EQ(node->opcode(), IrOpcode::kTypeGuard);
360 if (!guarded_type.IsWasm())
return NoChange();
370 DCHECK_EQ(node->opcode(), IrOpcode::kWasmTypeCast);
378 if (InDeadBranch(rtt))
return NoChange();
392 node->RemoveInput(1);
399 TrapId::kTrapIllegalCast);
415 TrapId::kTrapIllegalCast);
430 {object_type.type, current_config.to,
431 current_config.exactness}));
441 DCHECK_EQ(node->opcode(), IrOpcode::kWasmTypeCastAbstract);
449 const bool to_nullable = config.
to.is_nullable();
464 TrapId::kTrapIllegalCast);
471 config.
to.heap_type(), object_type.
module,
480 TrapId::kTrapIllegalCast);
492 {object_type.type, config.to, config.exactness}));
502 DCHECK_EQ(node->opcode(), IrOpcode::kWasmTypeCheck);
510 if (InDeadBranch(rtt))
return NoChange();
555 {object_type.type, current_config.to,
556 current_config.exactness}));
562 DCHECK_EQ(node->opcode(), IrOpcode::kWasmTypeCheckAbstract);
587 const bool implicit_internalize =
591 if (!implicit_internalize &&
593 config.
to.heap_type(), object_type.
module,
613 {object_type.type, config.to, config.exactness}));
Reduction UpdateStates(Node *state_owner, ControlPathState< NodeWithType, node_uniqueness > new_state)
bool IsReduced(Node *node)
ControlPathState< NodeWithType, node_uniqueness > GetState(Node *node)
Reduction TakeStatesFromFirstControl(Node *node)
void ReplaceWithValue(Node *node, Node *value, Node *effect=nullptr, Node *control=nullptr)
static Reduction Replace(Node *node)
void ResetToCommonAncestor(ControlPathState other)
NodeState LookupState(Node *node) const
void InitializeEffectControl(Node *effect, Node *control)
Node * Int32Constant(int32_t value)
static void ChangeOp(Node *node, const Operator *new_op)
static Type GetType(const Node *node)
static bool IsTyped(const Node *node)
static Node * GetEffectInput(Node *node, int index=0)
static Node * GetValueInput(Node *node, int index)
static void SetType(Node *node, Type type)
static Node * GetControlInput(Node *node, int index=0)
constexpr IrOpcode::Value opcode() const
const Operator * op() const
constexpr Opcode opcode() const
static Reduction Changed(Node *node)
static Reduction NoChange()
void SetSourcePosition(Node *node, SourcePosition position)
SourcePosition GetSourcePosition(Node *node) const
Reduction ReduceMerge(Node *node)
Reduction ReduceStart(Node *node)
void UpdateSourcePosition(Node *new_node, Node *old_node)
Reduction ReduceTypeGuard(Node *node)
SourcePositionTable * source_position_table_
WasmGCOperatorReducer(Editor *editor, Zone *temp_zone_, MachineGraph *mcgraph, const wasm::WasmModule *module, SourcePositionTable *source_position_table)
const wasm::WasmModule * module_
Reduction ReduceWasmTypeCheckAbstract(Node *node)
Reduction ReduceWasmArrayLength(Node *node)
Node * SetType(Node *node, wasm::ValueType type)
Reduction Reduce(Node *node) final
wasm::TypeInModule ObjectTypeFromContext(Node *object, Node *control, bool allow_non_wasm=false)
Reduction UpdateNodeAndAliasesTypes(Node *state_owner, ControlPathTypes parent_state, Node *node, wasm::TypeInModule type, bool in_new_block)
SimplifiedOperatorBuilder * simplified()
Reduction ReduceIf(Node *node, bool condition)
Reduction ReduceAssertNotNull(Node *node)
Reduction ReduceWasmTypeCheck(Node *node)
ControlPathState< NodeWithType, kMultipleInstances > ControlPathTypes
Reduction ReduceWasmTypeCastAbstract(Node *node)
Reduction ReduceWasmStructOperation(Node *node)
CommonOperatorBuilder * common()
Reduction ReduceCheckNull(Node *node)
Reduction ReduceWasmTypeCast(Node *node)
Reduction ReduceWasmAnyConvertExtern(Node *node)
void TrapUnless(Node *condition, TrapId reason)
SimplifiedOperatorBuilder * simplified() override
Node * IsNull(Node *object, wasm::ValueType type)
Node * Null(wasm::ValueType type)
Node * IsNotNull(Node *object, wasm::ValueType type)
Node * AssertNotNull(Node *object, wasm::ValueType type, TrapId trap_id)
constexpr bool is_non_nullable() const
constexpr bool is_nullable() const
constexpr bool is_uninhabited() const
constexpr HeapType heap_type() const
constexpr ValueType AsNonNull() const
constexpr ValueType AsNullable(Nullability nullable=kNullable) const
Type TypeGuardTypeOf(Operator const *op)
T const & OpParameter(const Operator *op)
ValueType ToNullSentinel(TypeInModule type)
constexpr IndependentHeapType kWasmAnyRef
V8_INLINE bool IsHeapSubtypeOf(HeapType subtype, HeapType supertype, const WasmModule *sub_module, const WasmModule *super_module)
TypeInModule Intersection(ValueType type1, ValueType type2, const WasmModule *module1, const WasmModule *module2)
constexpr IndependentHeapType kWasmExternRef
constexpr IndependentValueType kWasmI32
V8_INLINE bool HeapTypesUnrelated(HeapType heap1, HeapType heap2, const WasmModule *module1, const WasmModule *module2)
constexpr int kNoSourcePosition
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
const WasmModule * module
SourcePositionTable * source_position_table_
const wasm::WasmModule * module_