11cb0ef41Sopenharmony_ci// Copyright 2021 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "src/compiler/wasm-escape-analysis.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include "src/compiler/js-graph.h" 81cb0ef41Sopenharmony_ci#include "src/compiler/node-properties.h" 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_cinamespace v8 { 111cb0ef41Sopenharmony_cinamespace internal { 121cb0ef41Sopenharmony_cinamespace compiler { 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ciReduction WasmEscapeAnalysis::Reduce(Node* node) { 151cb0ef41Sopenharmony_ci switch (node->opcode()) { 161cb0ef41Sopenharmony_ci case IrOpcode::kAllocateRaw: 171cb0ef41Sopenharmony_ci return ReduceAllocateRaw(node); 181cb0ef41Sopenharmony_ci default: 191cb0ef41Sopenharmony_ci return NoChange(); 201cb0ef41Sopenharmony_ci } 211cb0ef41Sopenharmony_ci} 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ciReduction WasmEscapeAnalysis::ReduceAllocateRaw(Node* node) { 241cb0ef41Sopenharmony_ci DCHECK_EQ(node->opcode(), IrOpcode::kAllocateRaw); 251cb0ef41Sopenharmony_ci // TODO(manoskouk): Account for phis. 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci // Collect all value edges of {node} in this vector. 281cb0ef41Sopenharmony_ci std::vector<Edge> value_edges; 291cb0ef41Sopenharmony_ci for (Edge edge : node->use_edges()) { 301cb0ef41Sopenharmony_ci if (NodeProperties::IsValueEdge(edge)) { 311cb0ef41Sopenharmony_ci if (edge.index() != 0 || 321cb0ef41Sopenharmony_ci (edge.from()->opcode() != IrOpcode::kStoreToObject && 331cb0ef41Sopenharmony_ci edge.from()->opcode() != IrOpcode::kInitializeImmutableInObject)) { 341cb0ef41Sopenharmony_ci return NoChange(); 351cb0ef41Sopenharmony_ci } 361cb0ef41Sopenharmony_ci value_edges.push_back(edge); 371cb0ef41Sopenharmony_ci } 381cb0ef41Sopenharmony_ci } 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci // Remove all discovered stores from the effect chain. 411cb0ef41Sopenharmony_ci for (Edge edge : value_edges) { 421cb0ef41Sopenharmony_ci DCHECK(NodeProperties::IsValueEdge(edge)); 431cb0ef41Sopenharmony_ci DCHECK_EQ(edge.index(), 0); 441cb0ef41Sopenharmony_ci Node* use = edge.from(); 451cb0ef41Sopenharmony_ci DCHECK(!use->IsDead()); 461cb0ef41Sopenharmony_ci DCHECK(use->opcode() == IrOpcode::kStoreToObject || 471cb0ef41Sopenharmony_ci use->opcode() == IrOpcode::kInitializeImmutableInObject); 481cb0ef41Sopenharmony_ci // The value stored by this StoreToObject node might be another allocation 491cb0ef41Sopenharmony_ci // which has no more uses. Therefore we have to revisit it. Note that this 501cb0ef41Sopenharmony_ci // will not happen automatically: ReplaceWithValue does not trigger revisits 511cb0ef41Sopenharmony_ci // of former inputs of the replaced node. 521cb0ef41Sopenharmony_ci Node* stored_value = NodeProperties::GetValueInput(use, 2); 531cb0ef41Sopenharmony_ci Revisit(stored_value); 541cb0ef41Sopenharmony_ci ReplaceWithValue(use, mcgraph_->Dead(), NodeProperties::GetEffectInput(use), 551cb0ef41Sopenharmony_ci mcgraph_->Dead()); 561cb0ef41Sopenharmony_ci use->Kill(); 571cb0ef41Sopenharmony_ci } 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci // Remove the allocation from the effect and control chains. 601cb0ef41Sopenharmony_ci ReplaceWithValue(node, mcgraph_->Dead(), NodeProperties::GetEffectInput(node), 611cb0ef41Sopenharmony_ci NodeProperties::GetControlInput(node)); 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci return Changed(node); 641cb0ef41Sopenharmony_ci} 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci} // namespace compiler 671cb0ef41Sopenharmony_ci} // namespace internal 681cb0ef41Sopenharmony_ci} // namespace v8 69