v8/src/compiler/wasm-graph-assembler.h
Manos Koukoutos 40fa77a8ec [wasm] Various small cleanups
Notably:
- As per convention, TrapIf/Unless should not return a control node.
- Wasm-gc pipeline should not depend on FLAG_wasm_inlining.

Change-Id: Ic593db1f979bec1cedfd9384b21487fc2763a35b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3771640
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81806}
2022-07-19 12:45:35 +00:00

278 lines
8.8 KiB
C++

// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#if !V8_ENABLE_WEBASSEMBLY
#error This header should only be included if WebAssembly is enabled.
#endif // !V8_ENABLE_WEBASSEMBLY
#ifndef V8_COMPILER_WASM_GRAPH_ASSEMBLER_H_
#define V8_COMPILER_WASM_GRAPH_ASSEMBLER_H_
#include "src/compiler/graph-assembler.h"
#include "src/wasm/wasm-code-manager.h"
namespace v8 {
namespace internal {
namespace compiler {
constexpr Builtin WasmRuntimeStubIdToBuiltinName(
wasm::WasmCode::RuntimeStubId runtime_stub_id) {
switch (runtime_stub_id) {
#define DEF_CASE(name) \
case wasm::WasmCode::k##name: \
return Builtin::k##name;
#define DEF_TRAP_CASE(name) DEF_CASE(ThrowWasm##name)
WASM_RUNTIME_STUB_LIST(DEF_CASE, DEF_TRAP_CASE)
#undef DEF_CASE
#undef DEF_TRAP_CASE
default:
UNREACHABLE();
}
}
CallDescriptor* GetBuiltinCallDescriptor(
Builtin name, Zone* zone, StubCallMode stub_mode,
bool needs_frame_state = false,
Operator::Properties properties = Operator::kNoProperties);
ObjectAccess ObjectAccessForGCStores(wasm::ValueType type);
class WasmGraphAssembler : public GraphAssembler {
public:
WasmGraphAssembler(MachineGraph* mcgraph, Zone* zone)
: GraphAssembler(mcgraph, zone), simplified_(zone) {}
template <typename... Args>
Node* CallRuntimeStub(wasm::WasmCode::RuntimeStubId stub_id,
Operator::Properties properties, Args*... args) {
auto* call_descriptor = GetBuiltinCallDescriptor(
WasmRuntimeStubIdToBuiltinName(stub_id), temp_zone(),
StubCallMode::kCallWasmRuntimeStub, false, properties);
// A direct call to a wasm runtime stub defined in this module.
// Just encode the stub index. This will be patched at relocation.
Node* call_target = mcgraph()->RelocatableIntPtrConstant(
stub_id, RelocInfo::WASM_STUB_CALL);
return Call(call_descriptor, call_target, args...);
}
Node* GetBuiltinPointerTarget(Builtin builtin) {
static_assert(std::is_same<Smi, BuiltinPtr>(), "BuiltinPtr must be Smi");
return NumberConstant(static_cast<int>(builtin));
}
template <typename... Args>
Node* CallBuiltin(Builtin name, Operator::Properties properties,
Args*... args) {
auto* call_descriptor = GetBuiltinCallDescriptor(
name, temp_zone(), StubCallMode::kCallBuiltinPointer, false,
properties);
Node* call_target = GetBuiltinPointerTarget(name);
return Call(call_descriptor, call_target, args...);
}
// Sets {true_node} and {false_node} to their corresponding Branch outputs.
// Returns the Branch node. Does not change control().
Node* Branch(Node* cond, Node** true_node, Node** false_node,
BranchHint hint);
Node* NumberConstant(double value) {
return graph()->NewNode(mcgraph()->common()->NumberConstant(value));
}
Node* SmiConstant(Tagged_t value) {
Address tagged_value = Internals::IntToSmi(static_cast<int>(value));
return kTaggedSize == kInt32Size
? Int32Constant(static_cast<int32_t>(tagged_value))
: Int64Constant(static_cast<int64_t>(tagged_value));
}
void MergeControlToEnd(Node* 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.
// Rule of thumb: if access to a given field in an object is required in
// at least two places, put a helper function here.
Node* Allocate(int size);
Node* Allocate(Node* size,
AllowLargeObjects allow_large = AllowLargeObjects::kTrue);
Node* LoadFromObject(MachineType type, Node* base, Node* offset);
Node* LoadFromObject(MachineType type, Node* base, int offset) {
return LoadFromObject(type, base, IntPtrConstant(offset));
}
Node* LoadImmutableFromObject(MachineType type, Node* base, Node* offset);
Node* LoadImmutableFromObject(MachineType type, Node* base, int offset) {
return LoadImmutableFromObject(type, base, IntPtrConstant(offset));
}
Node* LoadImmutable(LoadRepresentation rep, Node* base, Node* offset);
Node* LoadImmutable(LoadRepresentation rep, Node* base, int offset) {
return LoadImmutable(rep, base, IntPtrConstant(offset));
}
Node* StoreToObject(ObjectAccess access, Node* base, Node* offset,
Node* value);
Node* StoreToObject(ObjectAccess access, Node* base, int offset,
Node* value) {
return StoreToObject(access, base, IntPtrConstant(offset), value);
}
Node* InitializeImmutableInObject(ObjectAccess access, Node* base,
Node* offset, Node* value);
Node* InitializeImmutableInObject(ObjectAccess access, Node* base, int offset,
Node* value) {
return InitializeImmutableInObject(access, base, IntPtrConstant(offset),
value);
}
Node* IsI31(Node* object);
// Maps and their contents.
Node* LoadMap(Node* object);
void StoreMap(Node* heap_object, Node* map);
Node* LoadInstanceType(Node* map);
Node* LoadWasmTypeInfo(Node* map);
// FixedArrays.
Node* LoadFixedArrayLengthAsSmi(Node* fixed_array);
Node* LoadFixedArrayElement(Node* fixed_array, Node* index_intptr,
MachineType type = MachineType::AnyTagged());
Node* LoadImmutableFixedArrayElement(
Node* fixed_array, Node* index_intptr,
MachineType type = MachineType::AnyTagged());
Node* LoadFixedArrayElement(Node* array, int index, MachineType type);
Node* LoadFixedArrayElementSmi(Node* array, int index) {
return LoadFixedArrayElement(array, index, MachineType::TaggedSigned());
}
Node* LoadFixedArrayElementPtr(Node* array, int index) {
return LoadFixedArrayElement(array, index, MachineType::TaggedPointer());
}
Node* LoadFixedArrayElementAny(Node* array, int index) {
return LoadFixedArrayElement(array, index, MachineType::AnyTagged());
}
Node* StoreFixedArrayElement(Node* array, int index, Node* value,
ObjectAccess access);
Node* StoreFixedArrayElementSmi(Node* array, int index, Node* value) {
return StoreFixedArrayElement(
array, index, value,
ObjectAccess(MachineType::TaggedSigned(), kNoWriteBarrier));
}
Node* StoreFixedArrayElementAny(Node* array, int index, Node* value) {
return StoreFixedArrayElement(
array, index, value,
ObjectAccess(MachineType::AnyTagged(), kFullWriteBarrier));
}
// Functions, SharedFunctionInfos, FunctionData.
Node* LoadSharedFunctionInfo(Node* js_function);
Node* LoadContextFromJSFunction(Node* js_function);
Node* LoadFunctionDataFromJSFunction(Node* js_function);
Node* LoadExportedFunctionIndexAsSmi(Node* exported_function_data);
Node* LoadExportedFunctionInstance(Node* exported_function_data);
// JavaScript objects.
Node* LoadJSArrayElements(Node* js_array);
// WasmGC objects.
Node* FieldOffset(const wasm::StructType* type, uint32_t field_index);
Node* StoreStructField(Node* struct_object, const wasm::StructType* type,
uint32_t field_index, Node* value);
Node* WasmArrayElementOffset(Node* index, wasm::ValueType element_type);
Node* LoadWasmArrayLength(Node* array);
Node* IsDataRefMap(Node* map);
Node* WasmTypeCheck(Node* object, Node* rtt, WasmTypeCheckConfig config);
Node* WasmTypeCast(Node* object, Node* rtt, WasmTypeCheckConfig config);
Node* Null();
Node* IsNull(Node* object);
Node* IsNotNull(Node* object);
Node* AssertNotNull(Node* object);
// Generic helpers.
Node* HasInstanceType(Node* heap_object, InstanceType type);
void TrapIf(Node* condition, TrapId reason) {
AddNode(graph()->NewNode(mcgraph()->common()->TrapIf(reason), condition,
effect(), control()));
}
void TrapUnless(Node* condition, TrapId reason) {
AddNode(graph()->NewNode(mcgraph()->common()->TrapUnless(reason), condition,
effect(), control()));
}
SimplifiedOperatorBuilder* simplified() { return &simplified_; }
private:
SimplifiedOperatorBuilder simplified_;
};
} // namespace compiler
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_WASM_GRAPH_ASSEMBLER_H_