summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/wasm-gc-operator-reducer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/wasm-gc-operator-reducer.cc')
-rw-r--r--deps/v8/src/compiler/wasm-gc-operator-reducer.cc129
1 files changed, 111 insertions, 18 deletions
diff --git a/deps/v8/src/compiler/wasm-gc-operator-reducer.cc b/deps/v8/src/compiler/wasm-gc-operator-reducer.cc
index cbda5422e8..40aaa43bb3 100644
--- a/deps/v8/src/compiler/wasm-gc-operator-reducer.cc
+++ b/deps/v8/src/compiler/wasm-gc-operator-reducer.cc
@@ -25,6 +25,11 @@ Reduction WasmGCOperatorReducer::Reduce(Node* node) {
switch (node->opcode()) {
case IrOpcode::kStart:
return ReduceStart(node);
+ case IrOpcode::kWasmStructGet:
+ case IrOpcode::kWasmStructSet:
+ return ReduceWasmStructOperation(node);
+ case IrOpcode::kWasmArrayLength:
+ return ReduceWasmArrayLength(node);
case IrOpcode::kAssertNotNull:
return ReduceAssertNotNull(node);
case IrOpcode::kIsNull:
@@ -34,12 +39,16 @@ Reduction WasmGCOperatorReducer::Reduce(Node* node) {
return ReduceWasmTypeCheck(node);
case IrOpcode::kWasmTypeCast:
return ReduceWasmTypeCast(node);
+ case IrOpcode::kWasmExternInternalize:
+ return ReduceWasmExternInternalize(node);
case IrOpcode::kMerge:
return ReduceMerge(node);
case IrOpcode::kIfTrue:
return ReduceIf(node, true);
case IrOpcode::kIfFalse:
return ReduceIf(node, false);
+ case IrOpcode::kDead:
+ return NoChange();
case IrOpcode::kLoop:
return TakeStatesFromFirstControl(node);
default:
@@ -60,7 +69,7 @@ bool InDeadBranch(Node* node) {
Node* GetAlias(Node* node) {
switch (node->opcode()) {
- case IrOpcode::kWasmTypeCheck:
+ case IrOpcode::kWasmTypeCast:
case IrOpcode::kTypeGuard:
case IrOpcode::kAssertNotNull:
return NodeProperties::GetValueInput(node, 0);
@@ -117,6 +126,58 @@ wasm::TypeInModule WasmGCOperatorReducer::ObjectTypeFromContext(Node* object,
: type_from_node;
}
+Reduction WasmGCOperatorReducer::ReduceWasmStructOperation(Node* node) {
+ DCHECK(node->opcode() == IrOpcode::kWasmStructGet ||
+ node->opcode() == IrOpcode::kWasmStructSet);
+ Node* control = NodeProperties::GetControlInput(node);
+ if (!IsReduced(control)) return NoChange();
+ Node* object = NodeProperties::GetValueInput(node, 0);
+
+ wasm::TypeInModule object_type = ObjectTypeFromContext(object, control);
+ if (object_type.type.is_bottom()) return NoChange();
+
+ if (object_type.type.is_non_nullable()) {
+ // If the object is known to be non-nullable in the context, remove the null
+ // check.
+ auto op_params = OpParameter<WasmFieldInfo>(node->op());
+ const Operator* new_op =
+ node->opcode() == IrOpcode::kWasmStructGet
+ ? simplified()->WasmStructGet(op_params.type, op_params.field_index,
+ op_params.is_signed,
+ kWithoutNullCheck)
+ : simplified()->WasmStructSet(op_params.type, op_params.field_index,
+ kWithoutNullCheck);
+ NodeProperties::ChangeOp(node, new_op);
+ }
+
+ object_type.type = object_type.type.AsNonNull();
+
+ return UpdateNodeAndAliasesTypes(node, GetState(control), object, object_type,
+ false);
+}
+
+Reduction WasmGCOperatorReducer::ReduceWasmArrayLength(Node* node) {
+ DCHECK_EQ(node->opcode(), IrOpcode::kWasmArrayLength);
+ Node* control = NodeProperties::GetControlInput(node);
+ if (!IsReduced(control)) return NoChange();
+ Node* object = NodeProperties::GetValueInput(node, 0);
+
+ wasm::TypeInModule object_type = ObjectTypeFromContext(object, control);
+ if (object_type.type.is_bottom()) return NoChange();
+
+ if (object_type.type.is_non_nullable()) {
+ // If the object is known to be non-nullable in the context, remove the null
+ // check.
+ const Operator* new_op = simplified()->WasmArrayLength(kWithoutNullCheck);
+ NodeProperties::ChangeOp(node, new_op);
+ }
+
+ object_type.type = object_type.type.AsNonNull();
+
+ return UpdateNodeAndAliasesTypes(node, GetState(control), object, object_type,
+ false);
+}
+
// If the condition of this node's branch is a type check or a null check,
// add the additional information about the type-checked node to the path
// state.
@@ -202,13 +263,15 @@ Reduction WasmGCOperatorReducer::ReduceAssertNotNull(Node* node) {
// Optimize the check away if the argument is known to be non-null.
if (object_type.type.is_non_nullable()) {
- ReplaceWithValue(node, object);
- node->Kill();
- return Replace(object);
+ // First, relax control.
+ ReplaceWithValue(node, node, node, control);
+ // Use a TypeGuard node to not lose any type information.
+ NodeProperties::ChangeOp(
+ node, common()->TypeGuard(NodeProperties::GetType(node)));
+ return Changed(node);
}
object_type.type = object_type.type.AsNonNull();
-
return UpdateNodeAndAliasesTypes(node, GetState(control), node, object_type,
false);
}
@@ -224,16 +287,20 @@ Reduction WasmGCOperatorReducer::ReduceCheckNull(Node* node) {
// Optimize the check away if the argument is known to be non-null.
if (object_type.type.is_non_nullable()) {
- ReplaceWithValue(
- node, gasm_.Int32Constant(node->opcode() == IrOpcode::kIsNull ? 0 : 1));
+ ReplaceWithValue(node,
+ SetType(gasm_.Int32Constant(
+ node->opcode() == IrOpcode::kIsNull ? 0 : 1),
+ wasm::kWasmI32));
node->Kill();
return Replace(object); // Irrelevant replacement.
}
// Optimize the check away if the argument is known to be null.
if (object->opcode() == IrOpcode::kNull) {
- ReplaceWithValue(
- node, gasm_.Int32Constant(node->opcode() == IrOpcode::kIsNull ? 1 : 0));
+ ReplaceWithValue(node,
+ SetType(gasm_.Int32Constant(
+ node->opcode() == IrOpcode::kIsNull ? 1 : 0),
+ wasm::kWasmI32));
node->Kill();
return Replace(object); // Irrelevant replacement.
}
@@ -241,6 +308,23 @@ Reduction WasmGCOperatorReducer::ReduceCheckNull(Node* node) {
return NoChange();
}
+Reduction WasmGCOperatorReducer::ReduceWasmExternInternalize(Node* node) {
+ DCHECK_EQ(node->opcode(), IrOpcode::kWasmExternInternalize);
+ // Remove redundant extern.internalize(extern.externalize(...)) pattern.
+ // TODO(mliedtke): Currently this doesn't get fully removed, probably due to
+ // not running dead code elimination in this pipeline step. What would it cost
+ // us to run it here?
+ if (NodeProperties::GetValueInput(node, 0)->opcode() ==
+ IrOpcode::kWasmExternExternalize) {
+ Node* externalize = node->InputAt(0);
+ Node* input = externalize->InputAt(0);
+ ReplaceWithValue(node, input);
+ node->Kill();
+ return Replace(input);
+ }
+ return TakeStatesFromFirstControl(node);
+}
+
Reduction WasmGCOperatorReducer::ReduceWasmTypeCast(Node* node) {
DCHECK_EQ(node->opcode(), IrOpcode::kWasmTypeCast);
Node* effect = NodeProperties::GetEffectInput(node);
@@ -259,13 +343,20 @@ Reduction WasmGCOperatorReducer::ReduceWasmTypeCast(Node* node) {
wasm::HeapType(rtt_type.type.ref_index()),
object_type.module, rtt_type.module)) {
if (to_nullable) {
- // Type cast will always succeed. Remove it.
- ReplaceWithValue(node, object);
- node->Kill();
- return Replace(object);
+ // Type cast will always succeed. Turn it into a TypeGuard to not lose any
+ // type information.
+ // First, relax control.
+ ReplaceWithValue(node, node, node, control);
+ // Remove rtt input.
+ node->RemoveInput(1);
+ NodeProperties::ChangeOp(
+ node, common()->TypeGuard(NodeProperties::GetType(node)));
+ return Changed(node);
} else {
gasm_.InitializeEffectControl(effect, control);
- return Replace(gasm_.AssertNotNull(object));
+ return Replace(SetType(gasm_.AssertNotNull(object, object_type.type,
+ TrapId::kTrapIllegalCast),
+ object_type.type.AsNonNull()));
}
}
@@ -276,11 +367,12 @@ Reduction WasmGCOperatorReducer::ReduceWasmTypeCast(Node* node) {
// A cast between unrelated types can only succeed if the argument is null.
// Otherwise, it always fails.
Node* non_trapping_condition = object_type.type.is_nullable() && to_nullable
- ? gasm_.IsNull(object)
+ ? gasm_.IsNull(object, object_type.type)
: gasm_.Int32Constant(0);
gasm_.TrapUnless(SetType(non_trapping_condition, wasm::kWasmI32),
TrapId::kTrapIllegalCast);
- Node* null_node = SetType(gasm_.Null(), wasm::ToNullSentinel(object_type));
+ Node* null_node = SetType(gasm_.Null(object_type.type),
+ wasm::ToNullSentinel(object_type));
ReplaceWithValue(node, null_node, gasm_.effect(), gasm_.control());
node->Kill();
return Replace(null_node);
@@ -322,7 +414,7 @@ Reduction WasmGCOperatorReducer::ReduceWasmTypeCheck(Node* node) {
// Type cast will fail only on null.
gasm_.InitializeEffectControl(effect, control);
Node* condition = SetType(object_type.type.is_nullable() && !null_succeeds
- ? gasm_.IsNotNull(object)
+ ? gasm_.IsNotNull(object, object_type.type)
: gasm_.Int32Constant(1),
wasm::kWasmI32);
ReplaceWithValue(node, condition);
@@ -339,7 +431,8 @@ Reduction WasmGCOperatorReducer::ReduceWasmTypeCheck(Node* node) {
if (null_succeeds && object_type.type.is_nullable()) {
// The cast only succeeds in case of null.
gasm_.InitializeEffectControl(effect, control);
- condition = SetType(gasm_.IsNull(object), wasm::kWasmI32);
+ condition =
+ SetType(gasm_.IsNull(object, object_type.type), wasm::kWasmI32);
} else {
// The cast never succeeds.
condition = SetType(gasm_.Int32Constant(0), wasm::kWasmI32);