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