[wasm-gc][turbofan] Simple escape analysis
We introduce simple escape analysis for wasm-gc objects, where struct allocations that are only assigned to are eliminated. Handling phi uses of allocated objects is left for future work. Bug: v8:11510 Change-Id: Ibd0b220466546e150b26b02890572a5174c6872d Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3229744 Reviewed-by: Nico Hartmann <nicohartmann@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Commit-Queue: Manos Koukoutos <manoskouk@chromium.org> Cr-Commit-Position: refs/heads/main@{#77515}
This commit is contained in:
parent
b7dc9915ff
commit
520dc0d3de
@ -2153,6 +2153,7 @@ filegroup(
|
||||
"src/asmjs/asm-types.h",
|
||||
"src/compiler/int64-lowering.h",
|
||||
"src/compiler/wasm-compiler.h",
|
||||
"src/compiler/wasm-escape-analysis.h",
|
||||
"src/compiler/wasm-inlining.h",
|
||||
"src/debug/debug-wasm-objects.cc",
|
||||
"src/debug/debug-wasm-objects.h",
|
||||
@ -2538,6 +2539,7 @@ filegroup(
|
||||
":is_v8_enable_webassembly": [
|
||||
"src/compiler/int64-lowering.cc",
|
||||
"src/compiler/wasm-compiler.cc",
|
||||
"src/compiler/wasm-escape-analysis.cc",
|
||||
"src/compiler/wasm-inlining.cc",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
|
2
BUILD.gn
2
BUILD.gn
@ -3412,6 +3412,7 @@ v8_header_set("v8_internal_headers") {
|
||||
"src/asmjs/asm-types.h",
|
||||
"src/compiler/int64-lowering.h",
|
||||
"src/compiler/wasm-compiler.h",
|
||||
"src/compiler/wasm-escape-analysis.h",
|
||||
"src/compiler/wasm-inlining.h",
|
||||
"src/debug/debug-wasm-objects-inl.h",
|
||||
"src/debug/debug-wasm-objects.h",
|
||||
@ -3881,6 +3882,7 @@ if (v8_enable_webassembly) {
|
||||
v8_compiler_sources += [
|
||||
"src/compiler/int64-lowering.cc",
|
||||
"src/compiler/wasm-compiler.cc",
|
||||
"src/compiler/wasm-escape-analysis.cc",
|
||||
"src/compiler/wasm-inlining.cc",
|
||||
]
|
||||
}
|
||||
|
@ -96,6 +96,7 @@
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
#include "src/compiler/wasm-compiler.h"
|
||||
#include "src/compiler/wasm-escape-analysis.h"
|
||||
#include "src/compiler/wasm-inlining.h"
|
||||
#include "src/wasm/function-body-decoder.h"
|
||||
#include "src/wasm/function-compiler.h"
|
||||
@ -2013,12 +2014,14 @@ struct WasmOptimizationPhase {
|
||||
WasmInliner inliner(&graph_reducer, env, function_index,
|
||||
data->source_positions(), data->node_origins(),
|
||||
data->mcgraph(), wire_bytes);
|
||||
WasmEscapeAnalysis escape(&graph_reducer, data->mcgraph());
|
||||
AddReducer(data, &graph_reducer, &machine_reducer);
|
||||
AddReducer(data, &graph_reducer, &dead_code_elimination);
|
||||
AddReducer(data, &graph_reducer, &common_reducer);
|
||||
AddReducer(data, &graph_reducer, &value_numbering);
|
||||
if (FLAG_experimental_wasm_gc) {
|
||||
AddReducer(data, &graph_reducer, &load_elimination);
|
||||
AddReducer(data, &graph_reducer, &escape);
|
||||
}
|
||||
if (FLAG_wasm_inlining &&
|
||||
!WasmInliner::any_inlining_impossible(data->graph()->NodeCount())) {
|
||||
|
@ -293,6 +293,24 @@ class WasmGraphAssembler : public GraphAssembler {
|
||||
}
|
||||
|
||||
// Maps and their contents.
|
||||
Node* LoadMap(Node* object) {
|
||||
Node* map_word = LoadFromObject(MachineType::TaggedPointer(), object,
|
||||
HeapObject::kMapOffset - kHeapObjectTag);
|
||||
#ifdef V8_MAP_PACKING
|
||||
return UnpackMapWord(map_word);
|
||||
#else
|
||||
return map_word;
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreMap(Node* heap_object, Node* map) {
|
||||
ObjectAccess access(MachineType::TaggedPointer(), kMapWriteBarrier);
|
||||
#ifdef V8_MAP_PACKING
|
||||
map = PackMapWord(map);
|
||||
#endif
|
||||
StoreToObject(access, heap_object, HeapObject::kMapOffset - kHeapObjectTag,
|
||||
map);
|
||||
}
|
||||
|
||||
Node* LoadInstanceType(Node* map) {
|
||||
return LoadFromObject(
|
||||
@ -5573,7 +5591,7 @@ Node* WasmGraphBuilder::StructNewWithRtt(uint32_t struct_index,
|
||||
base::Vector<Node*> fields) {
|
||||
int size = WasmStruct::Size(type);
|
||||
Node* s = gasm_->Allocate(size);
|
||||
gasm_->StoreMap(s, TNode<Map>::UncheckedCast(rtt));
|
||||
gasm_->StoreMap(s, rtt);
|
||||
gasm_->StoreToObject(
|
||||
ObjectAccess(MachineType::TaggedPointer(), kNoWriteBarrier), s,
|
||||
wasm::ObjectAccess::ToTagged(JSReceiver::kPropertiesOrHashOffset),
|
||||
|
58
src/compiler/wasm-escape-analysis.cc
Normal file
58
src/compiler/wasm-escape-analysis.cc
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
#include "src/compiler/wasm-escape-analysis.h"
|
||||
|
||||
#include "src/compiler/js-graph.h"
|
||||
#include "src/compiler/node-properties.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
Reduction WasmEscapeAnalysis::Reduce(Node* node) {
|
||||
switch (node->opcode()) {
|
||||
case IrOpcode::kAllocateRaw:
|
||||
return ReduceAllocateRaw(node);
|
||||
default:
|
||||
return NoChange();
|
||||
}
|
||||
}
|
||||
|
||||
Reduction WasmEscapeAnalysis::ReduceAllocateRaw(Node* node) {
|
||||
DCHECK_EQ(node->opcode(), IrOpcode::kAllocateRaw);
|
||||
|
||||
// TODO(manoskouk): Account for phis.
|
||||
std::vector<Edge> use_edges;
|
||||
for (Edge edge : node->use_edges()) {
|
||||
if (NodeProperties::IsValueEdge(edge)) {
|
||||
if (edge.index() != 0 ||
|
||||
edge.from()->opcode() != IrOpcode::kStoreToObject) {
|
||||
return NoChange();
|
||||
}
|
||||
}
|
||||
use_edges.push_back(edge);
|
||||
}
|
||||
|
||||
// Remove all stores from the effect chain.
|
||||
for (Edge edge : use_edges) {
|
||||
if (NodeProperties::IsValueEdge(edge)) {
|
||||
Node* use = edge.from();
|
||||
DCHECK_EQ(edge.index(), 0);
|
||||
DCHECK_EQ(use->opcode(), IrOpcode::kStoreToObject);
|
||||
ReplaceWithValue(use, mcgraph_->Dead(),
|
||||
NodeProperties::GetEffectInput(use), mcgraph_->Dead());
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the allocation from the effect and control chains.
|
||||
ReplaceWithValue(node, mcgraph_->Dead(), NodeProperties::GetEffectInput(node),
|
||||
NodeProperties::GetControlInput(node));
|
||||
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
} // namespace v8
|
41
src/compiler/wasm-escape-analysis.h
Normal file
41
src/compiler/wasm-escape-analysis.h
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2021 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_ESCAPE_ANALYSIS_H_
|
||||
#define V8_COMPILER_WASM_ESCAPE_ANALYSIS_H_
|
||||
|
||||
#include "src/compiler/graph-reducer.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
class MachineGraph;
|
||||
|
||||
// Eliminate allocated objects which are only assigned to.
|
||||
// Current restrictions: Does not work for arrays (until they are also allocated
|
||||
// with AllocateRaw). Does not work if the allocated object is passed to a phi.
|
||||
class WasmEscapeAnalysis final : public AdvancedReducer {
|
||||
public:
|
||||
WasmEscapeAnalysis(Editor* editor, MachineGraph* mcgraph)
|
||||
: AdvancedReducer(editor), mcgraph_(mcgraph) {}
|
||||
|
||||
const char* reducer_name() const override { return "WasmEscapeAnalysis"; }
|
||||
|
||||
Reduction Reduce(Node* node) final;
|
||||
|
||||
private:
|
||||
Reduction ReduceAllocateRaw(Node* call);
|
||||
MachineGraph* const mcgraph_;
|
||||
};
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_COMPILER_WASM_ESCAPE_ANALYSIS_H_
|
Loading…
Reference in New Issue
Block a user