Commit 3904606c authored by Manos Koukoutos's avatar Manos Koukoutos Committed by V8 LUCI CQ

[wasm] Move and add functionality to WasmGraphAssembler

Specifically, move numeric conversions from WasmGraphBuilder, and add
functionality for traps.
These will be used in wasm-gc lowering phases.

Change-Id: I73f0dab28d87db8f1c4c339ea3d871f262e270ab
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3654101Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80638}
parent 2df4d58a
...@@ -1116,16 +1116,14 @@ TrapId WasmGraphBuilder::GetTrapIdForTrap(wasm::TrapReason reason) { ...@@ -1116,16 +1116,14 @@ TrapId WasmGraphBuilder::GetTrapIdForTrap(wasm::TrapReason reason) {
void WasmGraphBuilder::TrapIfTrue(wasm::TrapReason reason, Node* cond, void WasmGraphBuilder::TrapIfTrue(wasm::TrapReason reason, Node* cond,
wasm::WasmCodePosition position) { wasm::WasmCodePosition position) {
TrapId trap_id = GetTrapIdForTrap(reason); TrapId trap_id = GetTrapIdForTrap(reason);
Node* node = SetControl(graph()->NewNode(mcgraph()->common()->TrapIf(trap_id), Node* node = gasm_->TrapIf(cond, trap_id);
cond, effect(), control()));
SetSourcePosition(node, position); SetSourcePosition(node, position);
} }
void WasmGraphBuilder::TrapIfFalse(wasm::TrapReason reason, Node* cond, void WasmGraphBuilder::TrapIfFalse(wasm::TrapReason reason, Node* cond,
wasm::WasmCodePosition position) { wasm::WasmCodePosition position) {
TrapId trap_id = GetTrapIdForTrap(reason); TrapId trap_id = GetTrapIdForTrap(reason);
Node* node = SetControl(graph()->NewNode( Node* node = gasm_->TrapUnless(cond, trap_id);
mcgraph()->common()->TrapUnless(trap_id), cond, effect(), control()));
SetSourcePosition(node, position); SetSourcePosition(node, position);
} }
...@@ -2179,22 +2177,22 @@ void WasmGraphBuilder::BuildEncodeException32BitValue(Node* values_array, ...@@ -2179,22 +2177,22 @@ void WasmGraphBuilder::BuildEncodeException32BitValue(Node* values_array,
uint32_t* index, uint32_t* index,
Node* value) { Node* value) {
Node* upper_halfword_as_smi = Node* upper_halfword_as_smi =
BuildChangeUint31ToSmi(gasm_->Word32Shr(value, Int32Constant(16))); gasm_->BuildChangeUint31ToSmi(gasm_->Word32Shr(value, Int32Constant(16)));
gasm_->StoreFixedArrayElementSmi(values_array, *index, upper_halfword_as_smi); gasm_->StoreFixedArrayElementSmi(values_array, *index, upper_halfword_as_smi);
++(*index); ++(*index);
Node* lower_halfword_as_smi = Node* lower_halfword_as_smi = gasm_->BuildChangeUint31ToSmi(
BuildChangeUint31ToSmi(gasm_->Word32And(value, Int32Constant(0xFFFFu))); gasm_->Word32And(value, Int32Constant(0xFFFFu)));
gasm_->StoreFixedArrayElementSmi(values_array, *index, lower_halfword_as_smi); gasm_->StoreFixedArrayElementSmi(values_array, *index, lower_halfword_as_smi);
++(*index); ++(*index);
} }
Node* WasmGraphBuilder::BuildDecodeException32BitValue(Node* values_array, Node* WasmGraphBuilder::BuildDecodeException32BitValue(Node* values_array,
uint32_t* index) { uint32_t* index) {
Node* upper = BuildChangeSmiToInt32( Node* upper = gasm_->BuildChangeSmiToInt32(
gasm_->LoadFixedArrayElementSmi(values_array, *index)); gasm_->LoadFixedArrayElementSmi(values_array, *index));
(*index)++; (*index)++;
upper = gasm_->Word32Shl(upper, Int32Constant(16)); upper = gasm_->Word32Shl(upper, Int32Constant(16));
Node* lower = BuildChangeSmiToInt32( Node* lower = gasm_->BuildChangeSmiToInt32(
gasm_->LoadFixedArrayElementSmi(values_array, *index)); gasm_->LoadFixedArrayElementSmi(values_array, *index));
(*index)++; (*index)++;
Node* value = gasm_->Word32Or(upper, lower); Node* value = gasm_->Word32Or(upper, lower);
...@@ -2711,7 +2709,7 @@ Node* WasmGraphBuilder::BuildImportCall(const wasm::FunctionSig* sig, ...@@ -2711,7 +2709,7 @@ Node* WasmGraphBuilder::BuildImportCall(const wasm::FunctionSig* sig,
Node* imported_function_refs = Node* imported_function_refs =
LOAD_INSTANCE_FIELD(ImportedFunctionRefs, MachineType::TaggedPointer()); LOAD_INSTANCE_FIELD(ImportedFunctionRefs, MachineType::TaggedPointer());
// Access fixed array at {header_size - tag + func_index * kTaggedSize}. // Access fixed array at {header_size - tag + func_index * kTaggedSize}.
Node* func_index_intptr = BuildChangeUint32ToUintPtr(func_index); Node* func_index_intptr = gasm_->BuildChangeUint32ToUintPtr(func_index);
Node* ref_node = gasm_->LoadFixedArrayElement( Node* ref_node = gasm_->LoadFixedArrayElement(
imported_function_refs, func_index_intptr, MachineType::TaggedPointer()); imported_function_refs, func_index_intptr, MachineType::TaggedPointer());
...@@ -2845,8 +2843,8 @@ Node* WasmGraphBuilder::BuildIndirectCall( ...@@ -2845,8 +2843,8 @@ Node* WasmGraphBuilder::BuildIndirectCall(
table_type.is_reference_to(wasm::HeapType::kFunc) || table_type.is_reference_to(wasm::HeapType::kFunc) ||
table_type.is_nullable(); table_type.is_nullable();
if (needs_signature_check) { if (needs_signature_check) {
Node* int32_scaled_key = Node* int32_scaled_key = gasm_->BuildChangeUint32ToUintPtr(
BuildChangeUint32ToUintPtr(gasm_->Word32Shl(key, Int32Constant(2))); gasm_->Word32Shl(key, Int32Constant(2)));
Node* loaded_sig = gasm_->LoadFromObject(MachineType::Int32(), ift_sig_ids, Node* loaded_sig = gasm_->LoadFromObject(MachineType::Int32(), ift_sig_ids,
int32_scaled_key); int32_scaled_key);
...@@ -2856,7 +2854,7 @@ Node* WasmGraphBuilder::BuildIndirectCall( ...@@ -2856,7 +2854,7 @@ Node* WasmGraphBuilder::BuildIndirectCall(
TrapIfFalse(wasm::kTrapFuncSigMismatch, sig_match, position); TrapIfFalse(wasm::kTrapFuncSigMismatch, sig_match, position);
} }
Node* key_intptr = BuildChangeUint32ToUintPtr(key); Node* key_intptr = gasm_->BuildChangeUint32ToUintPtr(key);
Node* target_instance = gasm_->LoadFixedArrayElement( Node* target_instance = gasm_->LoadFixedArrayElement(
ift_instances, key_intptr, MachineType::TaggedPointer()); ift_instances, key_intptr, MachineType::TaggedPointer());
...@@ -3059,81 +3057,6 @@ Node* WasmGraphBuilder::Invert(Node* node) { ...@@ -3059,81 +3057,6 @@ Node* WasmGraphBuilder::Invert(Node* node) {
return Unop(wasm::kExprI32Eqz, node); return Unop(wasm::kExprI32Eqz, node);
} }
Node* WasmGraphBuilder::BuildTruncateIntPtrToInt32(Node* value) {
return mcgraph()->machine()->Is64() ? gasm_->TruncateInt64ToInt32(value)
: value;
}
Node* WasmGraphBuilder::BuildChangeInt32ToIntPtr(Node* value) {
return mcgraph()->machine()->Is64() ? gasm_->ChangeInt32ToInt64(value)
: value;
}
Node* WasmGraphBuilder::BuildChangeIntPtrToInt64(Node* value) {
return mcgraph()->machine()->Is32() ? gasm_->ChangeInt32ToInt64(value)
: value;
}
Node* WasmGraphBuilder::BuildChangeUint32ToUintPtr(Node* node) {
if (mcgraph()->machine()->Is32()) return node;
// Fold instances of ChangeUint32ToUint64(IntConstant) directly.
Uint32Matcher matcher(node);
if (matcher.HasResolvedValue()) {
uintptr_t value = matcher.ResolvedValue();
return mcgraph()->IntPtrConstant(base::bit_cast<intptr_t>(value));
}
return gasm_->ChangeUint32ToUint64(node);
}
Node* WasmGraphBuilder::BuildSmiShiftBitsConstant() {
return gasm_->IntPtrConstant(kSmiShiftSize + kSmiTagSize);
}
Node* WasmGraphBuilder::BuildSmiShiftBitsConstant32() {
return Int32Constant(kSmiShiftSize + kSmiTagSize);
}
Node* WasmGraphBuilder::BuildChangeInt32ToSmi(Node* value) {
// With pointer compression, only the lower 32 bits are used.
return COMPRESS_POINTERS_BOOL
? gasm_->Word32Shl(value, BuildSmiShiftBitsConstant32())
: gasm_->WordShl(BuildChangeInt32ToIntPtr(value),
BuildSmiShiftBitsConstant());
}
Node* WasmGraphBuilder::BuildChangeUint31ToSmi(Node* value) {
return COMPRESS_POINTERS_BOOL
? gasm_->Word32Shl(value, BuildSmiShiftBitsConstant32())
: gasm_->WordShl(BuildChangeUint32ToUintPtr(value),
BuildSmiShiftBitsConstant());
}
Node* WasmGraphBuilder::BuildChangeSmiToInt32(Node* value) {
return COMPRESS_POINTERS_BOOL
? gasm_->Word32Sar(value, BuildSmiShiftBitsConstant32())
: BuildTruncateIntPtrToInt32(
gasm_->WordSar(value, BuildSmiShiftBitsConstant()));
}
Node* WasmGraphBuilder::BuildChangeSmiToIntPtr(Node* value) {
return COMPRESS_POINTERS_BOOL
? BuildChangeInt32ToIntPtr(
gasm_->Word32Sar(value, BuildSmiShiftBitsConstant32()))
: gasm_->WordSar(value, BuildSmiShiftBitsConstant());
}
Node* WasmGraphBuilder::BuildConvertUint32ToSmiWithSaturation(Node* value,
uint32_t maxval) {
DCHECK(Smi::IsValid(maxval));
Node* max = mcgraph()->Uint32Constant(maxval);
Node* check = gasm_->Uint32LessThanOrEqual(value, max);
Node* valsmi = BuildChangeUint31ToSmi(value);
Node* maxsmi = gasm_->NumberConstant(maxval);
Diamond d(graph(), mcgraph()->common(), check, BranchHint::kTrue);
d.Chain(control());
return d.Phi(MachineRepresentation::kTagged, valsmi, maxsmi);
}
void WasmGraphBuilder::InitInstanceCache( void WasmGraphBuilder::InitInstanceCache(
WasmInstanceCacheNodes* instance_cache) { WasmInstanceCacheNodes* instance_cache) {
// We handle caching of the instance cache nodes manually, and we may reload // We handle caching of the instance cache nodes manually, and we may reload
...@@ -3264,8 +3187,9 @@ Node* WasmGraphBuilder::CurrentMemoryPages() { ...@@ -3264,8 +3187,9 @@ Node* WasmGraphBuilder::CurrentMemoryPages() {
DCHECK_NOT_NULL(mem_size); DCHECK_NOT_NULL(mem_size);
Node* result = Node* result =
gasm_->WordShr(mem_size, Int32Constant(wasm::kWasmPageSizeLog2)); gasm_->WordShr(mem_size, Int32Constant(wasm::kWasmPageSizeLog2));
result = env_->module->is_memory64 ? BuildChangeIntPtrToInt64(result) result = env_->module->is_memory64
: BuildTruncateIntPtrToInt32(result); ? gasm_->BuildChangeIntPtrToInt64(result)
: gasm_->BuildTruncateIntPtrToInt32(result);
return result; return result;
} }
...@@ -3446,7 +3370,7 @@ WasmGraphBuilder::BoundsCheckMem(uint8_t access_size, Node* index, ...@@ -3446,7 +3370,7 @@ WasmGraphBuilder::BoundsCheckMem(uint8_t access_size, Node* index,
// Convert the index to uintptr. // Convert the index to uintptr.
if (!env_->module->is_memory64) { if (!env_->module->is_memory64) {
index = BuildChangeUint32ToUintPtr(index); index = gasm_->BuildChangeUint32ToUintPtr(index);
} else if (kSystemPointerSize == kInt32Size) { } else if (kSystemPointerSize == kInt32Size) {
// In memory64 mode on 32-bit systems, the upper 32 bits need to be zero to // In memory64 mode on 32-bit systems, the upper 32 bits need to be zero to
// succeed the bounds check. // succeed the bounds check.
...@@ -3859,7 +3783,7 @@ Node* WasmGraphBuilder::BuildAsmjsLoadMem(MachineType type, Node* index) { ...@@ -3859,7 +3783,7 @@ Node* WasmGraphBuilder::BuildAsmjsLoadMem(MachineType type, Node* index) {
// Note that we check against the memory size ignoring the size of the // Note that we check against the memory size ignoring the size of the
// stored value, which is conservative if misaligned. Technically, asm.js // stored value, which is conservative if misaligned. Technically, asm.js
// should never have misaligned accesses. // should never have misaligned accesses.
index = BuildChangeUint32ToUintPtr(index); index = gasm_->BuildChangeUint32ToUintPtr(index);
Diamond bounds_check(graph(), mcgraph()->common(), Diamond bounds_check(graph(), mcgraph()->common(),
gasm_->UintLessThan(index, mem_size), BranchHint::kTrue); gasm_->UintLessThan(index, mem_size), BranchHint::kTrue);
bounds_check.Chain(control()); bounds_check.Chain(control());
...@@ -3908,7 +3832,7 @@ Node* WasmGraphBuilder::BuildAsmjsStoreMem(MachineType type, Node* index, ...@@ -3908,7 +3832,7 @@ Node* WasmGraphBuilder::BuildAsmjsStoreMem(MachineType type, Node* index,
BranchHint::kTrue); BranchHint::kTrue);
bounds_check.Chain(control()); bounds_check.Chain(control());
index = BuildChangeUint32ToUintPtr(index); index = gasm_->BuildChangeUint32ToUintPtr(index);
const Operator* store_op = mcgraph()->machine()->Store(StoreRepresentation( const Operator* store_op = mcgraph()->machine()->Store(StoreRepresentation(
type.representation(), WriteBarrierKind::kNoWriteBarrier)); type.representation(), WriteBarrierKind::kNoWriteBarrier));
Node* store = graph()->NewNode(store_op, mem_start, index, val, effect(), Node* store = graph()->NewNode(store_op, mem_start, index, val, effect(),
...@@ -5094,7 +5018,7 @@ void WasmGraphBuilder::MemTypeToUintPtrOrOOBTrap( ...@@ -5094,7 +5018,7 @@ void WasmGraphBuilder::MemTypeToUintPtrOrOOBTrap(
std::initializer_list<Node**> nodes, wasm::WasmCodePosition position) { std::initializer_list<Node**> nodes, wasm::WasmCodePosition position) {
if (!env_->module->is_memory64) { if (!env_->module->is_memory64) {
for (Node** node : nodes) { for (Node** node : nodes) {
*node = BuildChangeUint32ToUintPtr(*node); *node = gasm_->BuildChangeUint32ToUintPtr(*node);
} }
return; return;
} }
...@@ -5182,7 +5106,7 @@ void WasmGraphBuilder::TableCopy(uint32_t table_dst_index, ...@@ -5182,7 +5106,7 @@ void WasmGraphBuilder::TableCopy(uint32_t table_dst_index,
Node* WasmGraphBuilder::TableGrow(uint32_t table_index, Node* value, Node* WasmGraphBuilder::TableGrow(uint32_t table_index, Node* value,
Node* delta) { Node* delta) {
return BuildChangeSmiToInt32(gasm_->CallRuntimeStub( return gasm_->BuildChangeSmiToInt32(gasm_->CallRuntimeStub(
wasm::WasmCode::kWasmTableGrow, Operator::kNoThrow, wasm::WasmCode::kWasmTableGrow, Operator::kNoThrow,
graph()->NewNode(mcgraph()->common()->NumberConstant(table_index)), delta, graph()->NewNode(mcgraph()->common()->NumberConstant(table_index)), delta,
value)); value));
...@@ -5198,7 +5122,7 @@ Node* WasmGraphBuilder::TableSize(uint32_t table_index) { ...@@ -5198,7 +5122,7 @@ Node* WasmGraphBuilder::TableSize(uint32_t table_index) {
assert_size(length_field_size, MachineType::TaggedSigned()), table, assert_size(length_field_size, MachineType::TaggedSigned()), table,
wasm::ObjectAccess::ToTagged(WasmTableObject::kCurrentLengthOffset)); wasm::ObjectAccess::ToTagged(WasmTableObject::kCurrentLengthOffset));
return BuildChangeSmiToInt32(length_smi); return gasm_->BuildChangeSmiToInt32(length_smi);
} }
void WasmGraphBuilder::TableFill(uint32_t table_index, Node* start, Node* value, void WasmGraphBuilder::TableFill(uint32_t table_index, Node* start, Node* value,
...@@ -5427,8 +5351,8 @@ void WasmGraphBuilder::TypeCheck( ...@@ -5427,8 +5351,8 @@ void WasmGraphBuilder::TypeCheck(
// array length, we can access the supertype without bounds-checking the // array length, we can access the supertype without bounds-checking the
// supertype array. // supertype array.
if (config.rtt_depth >= wasm::kMinimumSupertypeArraySize) { if (config.rtt_depth >= wasm::kMinimumSupertypeArraySize) {
Node* supertypes_length = Node* supertypes_length = gasm_->BuildChangeSmiToIntPtr(
BuildChangeSmiToIntPtr(gasm_->LoadFixedArrayLengthAsSmi(supertypes)); gasm_->LoadFixedArrayLengthAsSmi(supertypes));
callbacks.fail_if_not(gasm_->UintLessThan(rtt_depth, supertypes_length), callbacks.fail_if_not(gasm_->UintLessThan(rtt_depth, supertypes_length),
BranchHint::kTrue); BranchHint::kTrue);
} }
...@@ -5762,30 +5686,31 @@ constexpr int kI31To32BitSmiShift = 33; ...@@ -5762,30 +5686,31 @@ constexpr int kI31To32BitSmiShift = 33;
Node* WasmGraphBuilder::I31New(Node* input) { Node* WasmGraphBuilder::I31New(Node* input) {
if (SmiValuesAre31Bits()) { if (SmiValuesAre31Bits()) {
return gasm_->Word32Shl(input, BuildSmiShiftBitsConstant32()); return gasm_->Word32Shl(input, gasm_->BuildSmiShiftBitsConstant32());
} }
DCHECK(SmiValuesAre32Bits()); DCHECK(SmiValuesAre32Bits());
input = BuildChangeInt32ToIntPtr(input); input = gasm_->BuildChangeInt32ToIntPtr(input);
return gasm_->WordShl(input, gasm_->IntPtrConstant(kI31To32BitSmiShift)); return gasm_->WordShl(input, gasm_->IntPtrConstant(kI31To32BitSmiShift));
} }
Node* WasmGraphBuilder::I31GetS(Node* input) { Node* WasmGraphBuilder::I31GetS(Node* input) {
if (SmiValuesAre31Bits()) { if (SmiValuesAre31Bits()) {
input = BuildTruncateIntPtrToInt32(input); input = gasm_->BuildTruncateIntPtrToInt32(input);
return gasm_->Word32SarShiftOutZeros(input, BuildSmiShiftBitsConstant32()); return gasm_->Word32SarShiftOutZeros(input,
gasm_->BuildSmiShiftBitsConstant32());
} }
DCHECK(SmiValuesAre32Bits()); DCHECK(SmiValuesAre32Bits());
return BuildTruncateIntPtrToInt32( return gasm_->BuildTruncateIntPtrToInt32(
gasm_->WordSar(input, gasm_->IntPtrConstant(kI31To32BitSmiShift))); gasm_->WordSar(input, gasm_->IntPtrConstant(kI31To32BitSmiShift)));
} }
Node* WasmGraphBuilder::I31GetU(Node* input) { Node* WasmGraphBuilder::I31GetU(Node* input) {
if (SmiValuesAre31Bits()) { if (SmiValuesAre31Bits()) {
input = BuildTruncateIntPtrToInt32(input); input = gasm_->BuildTruncateIntPtrToInt32(input);
return gasm_->Word32Shr(input, BuildSmiShiftBitsConstant32()); return gasm_->Word32Shr(input, gasm_->BuildSmiShiftBitsConstant32());
} }
DCHECK(SmiValuesAre32Bits()); DCHECK(SmiValuesAre32Bits());
return BuildTruncateIntPtrToInt32( return gasm_->BuildTruncateIntPtrToInt32(
gasm_->WordShr(input, gasm_->IntPtrConstant(kI31To32BitSmiShift))); gasm_->WordShr(input, gasm_->IntPtrConstant(kI31To32BitSmiShift)));
} }
...@@ -5872,7 +5797,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -5872,7 +5797,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
// We expect most integers at runtime to be Smis, so it is important for // We expect most integers at runtime to be Smis, so it is important for
// wrapper performance that Smi conversion be inlined. // wrapper performance that Smi conversion be inlined.
if (SmiValuesAre32Bits()) { if (SmiValuesAre32Bits()) {
return BuildChangeInt32ToSmi(value); return gasm_->BuildChangeInt32ToSmi(value);
} }
DCHECK(SmiValuesAre31Bits()); DCHECK(SmiValuesAre31Bits());
...@@ -5885,7 +5810,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -5885,7 +5810,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
gasm_->GotoIf(ovf, &builtin); gasm_->GotoIf(ovf, &builtin);
// If it didn't overflow, the result is {2 * value} as pointer-sized value. // If it didn't overflow, the result is {2 * value} as pointer-sized value.
Node* smi_tagged = BuildChangeInt32ToIntPtr(gasm_->Projection(0, add)); Node* smi_tagged =
gasm_->BuildChangeInt32ToIntPtr(gasm_->Projection(0, add));
gasm_->Goto(&done, smi_tagged); gasm_->Goto(&done, smi_tagged);
// Otherwise, call builtin, to convert to a HeapNumber. // Otherwise, call builtin, to convert to a HeapNumber.
...@@ -5917,7 +5843,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -5917,7 +5843,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
gasm_->GotoIfNot(IsSmi(value), &builtin); gasm_->GotoIfNot(IsSmi(value), &builtin);
// If Smi, convert to int32. // If Smi, convert to int32.
Node* smi = BuildChangeSmiToInt32(value); Node* smi = gasm_->BuildChangeSmiToInt32(value);
gasm_->Goto(&done, smi); gasm_->Goto(&done, smi);
// Otherwise, call builtin which changes non-Smi to Int32. // Otherwise, call builtin which changes non-Smi to Int32.
...@@ -6221,7 +6147,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -6221,7 +6147,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
mcgraph()->IntPtrConstant( mcgraph()->IntPtrConstant(
IntToSmi(static_cast<int>(type.raw_bit_field())))}; IntToSmi(static_cast<int>(type.raw_bit_field())))};
Node* check = BuildChangeSmiToInt32(BuildCallToRuntimeWithContext( Node* check = gasm_->BuildChangeSmiToInt32(BuildCallToRuntimeWithContext(
Runtime::kWasmIsValidRefValue, js_context, inputs, 3)); Runtime::kWasmIsValidRefValue, js_context, inputs, 3));
Diamond type_check(graph(), mcgraph()->common(), check, BranchHint::kTrue); Diamond type_check(graph(), mcgraph()->common(), check, BranchHint::kTrue);
...@@ -6330,11 +6256,11 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -6330,11 +6256,11 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
} }
Node* SmiToFloat32(Node* input) { Node* SmiToFloat32(Node* input) {
return gasm_->RoundInt32ToFloat32(BuildChangeSmiToInt32(input)); return gasm_->RoundInt32ToFloat32(gasm_->BuildChangeSmiToInt32(input));
} }
Node* SmiToFloat64(Node* input) { Node* SmiToFloat64(Node* input) {
return gasm_->ChangeInt32ToFloat64(BuildChangeSmiToInt32(input)); return gasm_->ChangeInt32ToFloat64(gasm_->BuildChangeSmiToInt32(input));
} }
Node* HeapNumberToFloat64(Node* input) { Node* HeapNumberToFloat64(Node* input) {
...@@ -6346,7 +6272,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -6346,7 +6272,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
Node* FromJSFast(Node* input, wasm::ValueType type) { Node* FromJSFast(Node* input, wasm::ValueType type) {
switch (type.kind()) { switch (type.kind()) {
case wasm::kI32: case wasm::kI32:
return BuildChangeSmiToInt32(input); return gasm_->BuildChangeSmiToInt32(input);
case wasm::kF32: { case wasm::kF32: {
auto done = gasm_->MakeLabel(MachineRepresentation::kFloat32); auto done = gasm_->MakeLabel(MachineRepresentation::kFloat32);
auto heap_number = gasm_->MakeLabel(); auto heap_number = gasm_->MakeLabel();
...@@ -6453,7 +6379,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -6453,7 +6379,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
Node* BuildMultiReturnFixedArrayFromIterable(const wasm::FunctionSig* sig, Node* BuildMultiReturnFixedArrayFromIterable(const wasm::FunctionSig* sig,
Node* iterable, Node* context) { Node* iterable, Node* context) {
Node* length = BuildChangeUint31ToSmi( Node* length = gasm_->BuildChangeUint31ToSmi(
mcgraph()->Uint32Constant(static_cast<uint32_t>(sig->return_count()))); mcgraph()->Uint32Constant(static_cast<uint32_t>(sig->return_count())));
return gasm_->CallBuiltin(Builtin::kIterableToFixedArrayForWasm, return gasm_->CallBuiltin(Builtin::kIterableToFixedArrayForWasm,
Operator::kEliminatable, iterable, length, Operator::kEliminatable, iterable, length,
...@@ -6486,7 +6412,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -6486,7 +6412,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
if (is_import) { if (is_import) {
// Call to an imported function. // Call to an imported function.
// Load function index from {WasmExportedFunctionData}. // Load function index from {WasmExportedFunctionData}.
Node* function_index = BuildChangeSmiToInt32( Node* function_index = gasm_->BuildChangeSmiToInt32(
gasm_->LoadExportedFunctionIndexAsSmi(function_data)); gasm_->LoadExportedFunctionIndexAsSmi(function_data));
BuildImportCall(sig_, base::VectorOf(args), base::VectorOf(rets), BuildImportCall(sig_, base::VectorOf(args), base::VectorOf(rets),
wasm::kNoCodePosition, function_index, kCallContinues); wasm::kNoCodePosition, function_index, kCallContinues);
...@@ -6555,7 +6481,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -6555,7 +6481,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
Node* IsSmi(Node* input) { Node* IsSmi(Node* input) {
return gasm_->Word32Equal( return gasm_->Word32Equal(
gasm_->Word32And(BuildTruncateIntPtrToInt32(input), gasm_->Word32And(gasm_->BuildTruncateIntPtrToInt32(input),
Int32Constant(kSmiTagMask)), Int32Constant(kSmiTagMask)),
Int32Constant(kSmiTag)); Int32Constant(kSmiTag));
} }
......
...@@ -695,19 +695,6 @@ class WasmGraphBuilder { ...@@ -695,19 +695,6 @@ class WasmGraphBuilder {
MachineType result_type, wasm::TrapReason trap_zero, MachineType result_type, wasm::TrapReason trap_zero,
wasm::WasmCodePosition position); wasm::WasmCodePosition position);
Node* BuildTruncateIntPtrToInt32(Node* value);
Node* BuildChangeInt32ToIntPtr(Node* value);
Node* BuildChangeIntPtrToInt64(Node* value);
Node* BuildChangeUint32ToUintPtr(Node*);
Node* BuildChangeInt32ToSmi(Node* value);
Node* BuildChangeUint31ToSmi(Node* value);
Node* BuildSmiShiftBitsConstant();
Node* BuildSmiShiftBitsConstant32();
Node* BuildChangeSmiToInt32(Node* value);
Node* BuildChangeSmiToIntPtr(Node* value);
// generates {index > max ? Smi(max) : Smi(index)}
Node* BuildConvertUint32ToSmiWithSaturation(Node* index, uint32_t maxval);
void MemTypeToUintPtrOrOOBTrap(std::initializer_list<Node**> nodes, void MemTypeToUintPtrOrOOBTrap(std::initializer_list<Node**> nodes,
wasm::WasmCodePosition position); wasm::WasmCodePosition position);
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "src/compiler/wasm-graph-assembler.h" #include "src/compiler/wasm-graph-assembler.h"
#include "src/compiler/diamond.h"
#include "src/compiler/node-matchers.h"
#include "src/wasm/object-access.h" #include "src/wasm/object-access.h"
#include "src/wasm/wasm-objects.h" #include "src/wasm/wasm-objects.h"
...@@ -48,6 +50,77 @@ Node* WasmGraphAssembler::Branch(Node* cond, Node** true_node, ...@@ -48,6 +50,77 @@ Node* WasmGraphAssembler::Branch(Node* cond, Node** true_node,
return branch; return branch;
} }
Node* WasmGraphAssembler::BuildTruncateIntPtrToInt32(Node* value) {
return mcgraph()->machine()->Is64() ? TruncateInt64ToInt32(value) : value;
}
Node* WasmGraphAssembler::BuildChangeInt32ToIntPtr(Node* value) {
return mcgraph()->machine()->Is64() ? ChangeInt32ToInt64(value) : value;
}
Node* WasmGraphAssembler::BuildChangeIntPtrToInt64(Node* value) {
return mcgraph()->machine()->Is32() ? ChangeInt32ToInt64(value) : value;
}
Node* WasmGraphAssembler::BuildChangeUint32ToUintPtr(Node* node) {
if (mcgraph()->machine()->Is32()) return node;
// Fold instances of ChangeUint32ToUint64(IntConstant) directly.
Uint32Matcher matcher(node);
if (matcher.HasResolvedValue()) {
uintptr_t value = matcher.ResolvedValue();
return mcgraph()->IntPtrConstant(base::bit_cast<intptr_t>(value));
}
return ChangeUint32ToUint64(node);
}
Node* WasmGraphAssembler::BuildSmiShiftBitsConstant() {
return IntPtrConstant(kSmiShiftSize + kSmiTagSize);
}
Node* WasmGraphAssembler::BuildSmiShiftBitsConstant32() {
return Int32Constant(kSmiShiftSize + kSmiTagSize);
}
Node* WasmGraphAssembler::BuildChangeInt32ToSmi(Node* value) {
// With pointer compression, only the lower 32 bits are used.
return COMPRESS_POINTERS_BOOL
? Word32Shl(value, BuildSmiShiftBitsConstant32())
: WordShl(BuildChangeInt32ToIntPtr(value),
BuildSmiShiftBitsConstant());
}
Node* WasmGraphAssembler::BuildChangeUint31ToSmi(Node* value) {
return COMPRESS_POINTERS_BOOL
? Word32Shl(value, BuildSmiShiftBitsConstant32())
: WordShl(BuildChangeUint32ToUintPtr(value),
BuildSmiShiftBitsConstant());
}
Node* WasmGraphAssembler::BuildChangeSmiToInt32(Node* value) {
return COMPRESS_POINTERS_BOOL
? Word32Sar(value, BuildSmiShiftBitsConstant32())
: BuildTruncateIntPtrToInt32(
WordSar(value, BuildSmiShiftBitsConstant()));
}
Node* WasmGraphAssembler::BuildConvertUint32ToSmiWithSaturation(
Node* value, uint32_t maxval) {
DCHECK(Smi::IsValid(maxval));
Node* max = mcgraph()->Uint32Constant(maxval);
Node* check = Uint32LessThanOrEqual(value, max);
Node* valsmi = BuildChangeUint31ToSmi(value);
Node* maxsmi = NumberConstant(maxval);
Diamond d(graph(), mcgraph()->common(), check, BranchHint::kTrue);
d.Chain(control());
return d.Phi(MachineRepresentation::kTagged, valsmi, maxsmi);
}
Node* WasmGraphAssembler::BuildChangeSmiToIntPtr(Node* value) {
return COMPRESS_POINTERS_BOOL ? BuildChangeInt32ToIntPtr(Word32Sar(
value, BuildSmiShiftBitsConstant32()))
: WordSar(value, BuildSmiShiftBitsConstant());
}
// Helper functions for dealing with HeapObjects. // Helper functions for dealing with HeapObjects.
// Rule of thumb: if access to a given field in an object is required in // Rule of thumb: if access to a given field in an object is required in
// at least two places, put a helper function here. // at least two places, put a helper function here.
......
...@@ -91,6 +91,29 @@ class WasmGraphAssembler : public GraphAssembler { ...@@ -91,6 +91,29 @@ class WasmGraphAssembler : public GraphAssembler {
NodeProperties::MergeControlToEnd(graph(), common(), control); NodeProperties::MergeControlToEnd(graph(), common(), control);
} }
// Numeric conversions
Node* BuildTruncateIntPtrToInt32(Node* value);
Node* BuildChangeInt32ToIntPtr(Node* value);
Node* BuildChangeIntPtrToInt64(Node* value);
Node* BuildChangeUint32ToUintPtr(Node* node);
Node* BuildSmiShiftBitsConstant();
Node* BuildSmiShiftBitsConstant32();
Node* BuildChangeInt32ToSmi(Node* value);
Node* BuildChangeUint31ToSmi(Node* value);
Node* BuildChangeSmiToInt32(Node* value);
Node* BuildConvertUint32ToSmiWithSaturation(Node* value, uint32_t maxval);
Node* BuildChangeSmiToIntPtr(Node* value);
// Helper functions for dealing with HeapObjects. // Helper functions for dealing with HeapObjects.
// Rule of thumb: if access to a given field in an object is required in // Rule of thumb: if access to a given field in an object is required in
// at least two places, put a helper function here. // at least two places, put a helper function here.
...@@ -221,6 +244,16 @@ class WasmGraphAssembler : public GraphAssembler { ...@@ -221,6 +244,16 @@ class WasmGraphAssembler : public GraphAssembler {
Node* HasInstanceType(Node* heap_object, InstanceType type); Node* HasInstanceType(Node* heap_object, InstanceType type);
Node* TrapIf(Node* condition, TrapId reason) {
return AddNode(graph()->NewNode(mcgraph()->common()->TrapIf(reason),
condition, effect(), control()));
}
Node* TrapUnless(Node* condition, TrapId reason) {
return AddNode(graph()->NewNode(mcgraph()->common()->TrapUnless(reason),
condition, effect(), control()));
}
SimplifiedOperatorBuilder* simplified() { return &simplified_; } SimplifiedOperatorBuilder* simplified() { return &simplified_; }
private: private:
......
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