11cb0ef41Sopenharmony_ci// Copyright 2014 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#ifndef V8_COMPILER_COMMON_OPERATOR_H_
61cb0ef41Sopenharmony_ci#define V8_COMPILER_COMMON_OPERATOR_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/base/compiler-specific.h"
91cb0ef41Sopenharmony_ci#include "src/codegen/machine-type.h"
101cb0ef41Sopenharmony_ci#include "src/codegen/reloc-info.h"
111cb0ef41Sopenharmony_ci#include "src/codegen/string-constants.h"
121cb0ef41Sopenharmony_ci#include "src/common/globals.h"
131cb0ef41Sopenharmony_ci#include "src/compiler/feedback-source.h"
141cb0ef41Sopenharmony_ci#include "src/compiler/frame-states.h"
151cb0ef41Sopenharmony_ci#include "src/compiler/linkage.h"
161cb0ef41Sopenharmony_ci#include "src/compiler/node-properties.h"
171cb0ef41Sopenharmony_ci#include "src/deoptimizer/deoptimize-reason.h"
181cb0ef41Sopenharmony_ci#include "src/zone/zone-containers.h"
191cb0ef41Sopenharmony_ci#include "src/zone/zone-handle-set.h"
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_cinamespace v8 {
221cb0ef41Sopenharmony_cinamespace internal {
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ciclass StringConstantBase;
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_cinamespace compiler {
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci// Forward declarations.
291cb0ef41Sopenharmony_ciclass CallDescriptor;
301cb0ef41Sopenharmony_cistruct CommonOperatorGlobalCache;
311cb0ef41Sopenharmony_ciclass Operator;
321cb0ef41Sopenharmony_ciclass Type;
331cb0ef41Sopenharmony_ciclass Node;
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci// The semantics of IrOpcode::kBranch changes throughout the pipeline, and in
361cb0ef41Sopenharmony_ci// particular is not the same before SimplifiedLowering (JS semantics) and after
371cb0ef41Sopenharmony_ci// (machine branch semantics). Some passes are applied both before and after
381cb0ef41Sopenharmony_ci// SimplifiedLowering, and use the BranchSemantics enum to know how branches
391cb0ef41Sopenharmony_ci// should be treated.
401cb0ef41Sopenharmony_cienum class BranchSemantics { kJS, kMachine };
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci// Prediction hint for branches.
431cb0ef41Sopenharmony_cienum class BranchHint : uint8_t { kNone, kTrue, kFalse };
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ciinline BranchHint NegateBranchHint(BranchHint hint) {
461cb0ef41Sopenharmony_ci  switch (hint) {
471cb0ef41Sopenharmony_ci    case BranchHint::kNone:
481cb0ef41Sopenharmony_ci      return hint;
491cb0ef41Sopenharmony_ci    case BranchHint::kTrue:
501cb0ef41Sopenharmony_ci      return BranchHint::kFalse;
511cb0ef41Sopenharmony_ci    case BranchHint::kFalse:
521cb0ef41Sopenharmony_ci      return BranchHint::kTrue;
531cb0ef41Sopenharmony_ci  }
541cb0ef41Sopenharmony_ci  UNREACHABLE();
551cb0ef41Sopenharmony_ci}
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ciinline size_t hash_value(BranchHint hint) { return static_cast<size_t>(hint); }
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, BranchHint);
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_cienum class TrapId : uint32_t {
621cb0ef41Sopenharmony_ci#define DEF_ENUM(Name, ...) k##Name,
631cb0ef41Sopenharmony_ci  FOREACH_WASM_TRAPREASON(DEF_ENUM)
641cb0ef41Sopenharmony_ci#undef DEF_ENUM
651cb0ef41Sopenharmony_ci      kInvalid
661cb0ef41Sopenharmony_ci};
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ciinline size_t hash_value(TrapId id) { return static_cast<uint32_t>(id); }
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream&, TrapId trap_id);
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ciTrapId TrapIdOf(const Operator* const op);
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE BranchHint BranchHintOf(const Operator* const)
751cb0ef41Sopenharmony_ci    V8_WARN_UNUSED_RESULT;
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci// Helper function for return nodes, because returns have a hidden value input.
781cb0ef41Sopenharmony_ciint ValueInputCountOfReturn(Operator const* const op);
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci// Parameters for the {Deoptimize} operator.
811cb0ef41Sopenharmony_ciclass DeoptimizeParameters final {
821cb0ef41Sopenharmony_ci public:
831cb0ef41Sopenharmony_ci  DeoptimizeParameters(DeoptimizeReason reason, FeedbackSource const& feedback)
841cb0ef41Sopenharmony_ci      : reason_(reason), feedback_(feedback) {}
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci  DeoptimizeReason reason() const { return reason_; }
871cb0ef41Sopenharmony_ci  const FeedbackSource& feedback() const { return feedback_; }
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci private:
901cb0ef41Sopenharmony_ci  DeoptimizeReason const reason_;
911cb0ef41Sopenharmony_ci  FeedbackSource const feedback_;
921cb0ef41Sopenharmony_ci};
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_cibool operator==(DeoptimizeParameters, DeoptimizeParameters);
951cb0ef41Sopenharmony_cibool operator!=(DeoptimizeParameters, DeoptimizeParameters);
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_cisize_t hast_value(DeoptimizeParameters p);
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream&, DeoptimizeParameters p);
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ciDeoptimizeParameters const& DeoptimizeParametersOf(Operator const* const)
1021cb0ef41Sopenharmony_ci    V8_WARN_UNUSED_RESULT;
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ciclass SelectParameters final {
1051cb0ef41Sopenharmony_ci public:
1061cb0ef41Sopenharmony_ci  explicit SelectParameters(MachineRepresentation representation,
1071cb0ef41Sopenharmony_ci                            BranchHint hint = BranchHint::kNone)
1081cb0ef41Sopenharmony_ci      : representation_(representation), hint_(hint) {}
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  MachineRepresentation representation() const { return representation_; }
1111cb0ef41Sopenharmony_ci  BranchHint hint() const { return hint_; }
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci private:
1141cb0ef41Sopenharmony_ci  const MachineRepresentation representation_;
1151cb0ef41Sopenharmony_ci  const BranchHint hint_;
1161cb0ef41Sopenharmony_ci};
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_cibool operator==(SelectParameters const&, SelectParameters const&);
1191cb0ef41Sopenharmony_cibool operator!=(SelectParameters const&, SelectParameters const&);
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_cisize_t hash_value(SelectParameters const& p);
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream&, SelectParameters const& p);
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE SelectParameters const& SelectParametersOf(
1261cb0ef41Sopenharmony_ci    const Operator* const) V8_WARN_UNUSED_RESULT;
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE CallDescriptor const* CallDescriptorOf(const Operator* const)
1291cb0ef41Sopenharmony_ci    V8_WARN_UNUSED_RESULT;
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE size_t ProjectionIndexOf(const Operator* const)
1321cb0ef41Sopenharmony_ci    V8_WARN_UNUSED_RESULT;
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE MachineRepresentation
1351cb0ef41Sopenharmony_ciLoopExitValueRepresentationOf(const Operator* const) V8_WARN_UNUSED_RESULT;
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE MachineRepresentation
1381cb0ef41Sopenharmony_ciPhiRepresentationOf(const Operator* const) V8_WARN_UNUSED_RESULT;
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci// The {IrOpcode::kParameter} opcode represents an incoming parameter to the
1411cb0ef41Sopenharmony_ci// function. This class bundles the index and a debug name for such operators.
1421cb0ef41Sopenharmony_ciclass ParameterInfo final {
1431cb0ef41Sopenharmony_ci public:
1441cb0ef41Sopenharmony_ci  static constexpr int kMinIndex = Linkage::kJSCallClosureParamIndex;
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ci  ParameterInfo(int index, const char* debug_name)
1471cb0ef41Sopenharmony_ci      : index_(index), debug_name_(debug_name) {
1481cb0ef41Sopenharmony_ci    DCHECK_LE(kMinIndex, index);
1491cb0ef41Sopenharmony_ci  }
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci  int index() const { return index_; }
1521cb0ef41Sopenharmony_ci  const char* debug_name() const { return debug_name_; }
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci private:
1551cb0ef41Sopenharmony_ci  int index_;
1561cb0ef41Sopenharmony_ci  const char* debug_name_;
1571cb0ef41Sopenharmony_ci};
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream&, ParameterInfo const&);
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE int ParameterIndexOf(const Operator* const)
1621cb0ef41Sopenharmony_ci    V8_WARN_UNUSED_RESULT;
1631cb0ef41Sopenharmony_ciconst ParameterInfo& ParameterInfoOf(const Operator* const)
1641cb0ef41Sopenharmony_ci    V8_WARN_UNUSED_RESULT;
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_cistruct ObjectStateInfo final : std::pair<uint32_t, int> {
1671cb0ef41Sopenharmony_ci  ObjectStateInfo(uint32_t object_id, int size)
1681cb0ef41Sopenharmony_ci      : std::pair<uint32_t, int>(object_id, size) {}
1691cb0ef41Sopenharmony_ci  uint32_t object_id() const { return first; }
1701cb0ef41Sopenharmony_ci  int size() const { return second; }
1711cb0ef41Sopenharmony_ci};
1721cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream&, ObjectStateInfo const&);
1731cb0ef41Sopenharmony_cisize_t hash_value(ObjectStateInfo const& p);
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_cistruct TypedObjectStateInfo final
1761cb0ef41Sopenharmony_ci    : std::pair<uint32_t, const ZoneVector<MachineType>*> {
1771cb0ef41Sopenharmony_ci  TypedObjectStateInfo(uint32_t object_id,
1781cb0ef41Sopenharmony_ci                       const ZoneVector<MachineType>* machine_types)
1791cb0ef41Sopenharmony_ci      : std::pair<uint32_t, const ZoneVector<MachineType>*>(object_id,
1801cb0ef41Sopenharmony_ci                                                            machine_types) {}
1811cb0ef41Sopenharmony_ci  uint32_t object_id() const { return first; }
1821cb0ef41Sopenharmony_ci  const ZoneVector<MachineType>* machine_types() const { return second; }
1831cb0ef41Sopenharmony_ci};
1841cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream&, TypedObjectStateInfo const&);
1851cb0ef41Sopenharmony_cisize_t hash_value(TypedObjectStateInfo const& p);
1861cb0ef41Sopenharmony_ci
1871cb0ef41Sopenharmony_ciclass RelocatablePtrConstantInfo final {
1881cb0ef41Sopenharmony_ci public:
1891cb0ef41Sopenharmony_ci  enum Type { kInt32, kInt64 };
1901cb0ef41Sopenharmony_ci
1911cb0ef41Sopenharmony_ci  RelocatablePtrConstantInfo(int32_t value, RelocInfo::Mode rmode)
1921cb0ef41Sopenharmony_ci      : value_(value), rmode_(rmode), type_(kInt32) {}
1931cb0ef41Sopenharmony_ci  RelocatablePtrConstantInfo(int64_t value, RelocInfo::Mode rmode)
1941cb0ef41Sopenharmony_ci      : value_(value), rmode_(rmode), type_(kInt64) {}
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci  intptr_t value() const { return value_; }
1971cb0ef41Sopenharmony_ci  RelocInfo::Mode rmode() const { return rmode_; }
1981cb0ef41Sopenharmony_ci  Type type() const { return type_; }
1991cb0ef41Sopenharmony_ci
2001cb0ef41Sopenharmony_ci private:
2011cb0ef41Sopenharmony_ci  intptr_t value_;
2021cb0ef41Sopenharmony_ci  RelocInfo::Mode rmode_;
2031cb0ef41Sopenharmony_ci  Type type_;
2041cb0ef41Sopenharmony_ci};
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_cibool operator==(RelocatablePtrConstantInfo const& lhs,
2071cb0ef41Sopenharmony_ci                RelocatablePtrConstantInfo const& rhs);
2081cb0ef41Sopenharmony_cibool operator!=(RelocatablePtrConstantInfo const& lhs,
2091cb0ef41Sopenharmony_ci                RelocatablePtrConstantInfo const& rhs);
2101cb0ef41Sopenharmony_ci
2111cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream&, RelocatablePtrConstantInfo const&);
2121cb0ef41Sopenharmony_ci
2131cb0ef41Sopenharmony_cisize_t hash_value(RelocatablePtrConstantInfo const& p);
2141cb0ef41Sopenharmony_ci
2151cb0ef41Sopenharmony_ci// Used to define a sparse set of inputs. This can be used to efficiently encode
2161cb0ef41Sopenharmony_ci// nodes that can have a lot of inputs, but where many inputs can have the same
2171cb0ef41Sopenharmony_ci// value.
2181cb0ef41Sopenharmony_ciclass SparseInputMask final {
2191cb0ef41Sopenharmony_ci public:
2201cb0ef41Sopenharmony_ci  using BitMaskType = uint32_t;
2211cb0ef41Sopenharmony_ci
2221cb0ef41Sopenharmony_ci  // The mask representing a dense input set.
2231cb0ef41Sopenharmony_ci  static const BitMaskType kDenseBitMask = 0x0;
2241cb0ef41Sopenharmony_ci  // The bits representing the end of a sparse input set.
2251cb0ef41Sopenharmony_ci  static const BitMaskType kEndMarker = 0x1;
2261cb0ef41Sopenharmony_ci  // The mask for accessing a sparse input entry in the bitmask.
2271cb0ef41Sopenharmony_ci  static const BitMaskType kEntryMask = 0x1;
2281cb0ef41Sopenharmony_ci
2291cb0ef41Sopenharmony_ci  // The number of bits in the mask, minus one for the end marker.
2301cb0ef41Sopenharmony_ci  static const int kMaxSparseInputs = (sizeof(BitMaskType) * kBitsPerByte - 1);
2311cb0ef41Sopenharmony_ci
2321cb0ef41Sopenharmony_ci  // An iterator over a node's sparse inputs.
2331cb0ef41Sopenharmony_ci  class InputIterator final {
2341cb0ef41Sopenharmony_ci   public:
2351cb0ef41Sopenharmony_ci    InputIterator() = default;
2361cb0ef41Sopenharmony_ci    InputIterator(BitMaskType bit_mask, Node* parent);
2371cb0ef41Sopenharmony_ci
2381cb0ef41Sopenharmony_ci    Node* parent() const { return parent_; }
2391cb0ef41Sopenharmony_ci    int real_index() const { return real_index_; }
2401cb0ef41Sopenharmony_ci
2411cb0ef41Sopenharmony_ci    // Advance the iterator to the next sparse input. Only valid if the iterator
2421cb0ef41Sopenharmony_ci    // has not reached the end.
2431cb0ef41Sopenharmony_ci    void Advance();
2441cb0ef41Sopenharmony_ci
2451cb0ef41Sopenharmony_ci    // Get the current sparse input's real node value. Only valid if the
2461cb0ef41Sopenharmony_ci    // current sparse input is real.
2471cb0ef41Sopenharmony_ci    Node* GetReal() const;
2481cb0ef41Sopenharmony_ci
2491cb0ef41Sopenharmony_ci    // Advance to the next real value or the end. Only valid if the iterator is
2501cb0ef41Sopenharmony_ci    // not dense. Returns the number of empty values that were skipped. This can
2511cb0ef41Sopenharmony_ci    // return 0 and in that case, it does not advance.
2521cb0ef41Sopenharmony_ci    size_t AdvanceToNextRealOrEnd();
2531cb0ef41Sopenharmony_ci
2541cb0ef41Sopenharmony_ci    // Get the current sparse input, returning either a real input node if
2551cb0ef41Sopenharmony_ci    // the current sparse input is real, or the given {empty_value} if the
2561cb0ef41Sopenharmony_ci    // current sparse input is empty.
2571cb0ef41Sopenharmony_ci    Node* Get(Node* empty_value) const {
2581cb0ef41Sopenharmony_ci      return IsReal() ? GetReal() : empty_value;
2591cb0ef41Sopenharmony_ci    }
2601cb0ef41Sopenharmony_ci
2611cb0ef41Sopenharmony_ci    // True if the current sparse input is a real input node.
2621cb0ef41Sopenharmony_ci    bool IsReal() const;
2631cb0ef41Sopenharmony_ci
2641cb0ef41Sopenharmony_ci    // True if the current sparse input is an empty value.
2651cb0ef41Sopenharmony_ci    bool IsEmpty() const { return !IsReal(); }
2661cb0ef41Sopenharmony_ci
2671cb0ef41Sopenharmony_ci    // True if the iterator has reached the end of the sparse inputs.
2681cb0ef41Sopenharmony_ci    bool IsEnd() const;
2691cb0ef41Sopenharmony_ci
2701cb0ef41Sopenharmony_ci   private:
2711cb0ef41Sopenharmony_ci    BitMaskType bit_mask_;
2721cb0ef41Sopenharmony_ci    Node* parent_;
2731cb0ef41Sopenharmony_ci    int real_index_;
2741cb0ef41Sopenharmony_ci  };
2751cb0ef41Sopenharmony_ci
2761cb0ef41Sopenharmony_ci  explicit SparseInputMask(BitMaskType bit_mask) : bit_mask_(bit_mask) {}
2771cb0ef41Sopenharmony_ci
2781cb0ef41Sopenharmony_ci  // Provides a SparseInputMask representing a dense input set.
2791cb0ef41Sopenharmony_ci  static SparseInputMask Dense() { return SparseInputMask(kDenseBitMask); }
2801cb0ef41Sopenharmony_ci
2811cb0ef41Sopenharmony_ci  BitMaskType mask() const { return bit_mask_; }
2821cb0ef41Sopenharmony_ci
2831cb0ef41Sopenharmony_ci  bool IsDense() const { return bit_mask_ == SparseInputMask::kDenseBitMask; }
2841cb0ef41Sopenharmony_ci
2851cb0ef41Sopenharmony_ci  // Counts how many real values are in the sparse array. Only valid for
2861cb0ef41Sopenharmony_ci  // non-dense masks.
2871cb0ef41Sopenharmony_ci  int CountReal() const;
2881cb0ef41Sopenharmony_ci
2891cb0ef41Sopenharmony_ci  // Returns an iterator over the sparse inputs of {node}.
2901cb0ef41Sopenharmony_ci  InputIterator IterateOverInputs(Node* node);
2911cb0ef41Sopenharmony_ci
2921cb0ef41Sopenharmony_ci private:
2931cb0ef41Sopenharmony_ci  //
2941cb0ef41Sopenharmony_ci  // The sparse input mask has a bitmask specifying if the node's inputs are
2951cb0ef41Sopenharmony_ci  // represented sparsely. If the bitmask value is 0, then the inputs are dense;
2961cb0ef41Sopenharmony_ci  // otherwise, they should be interpreted as follows:
2971cb0ef41Sopenharmony_ci  //
2981cb0ef41Sopenharmony_ci  //   * The bitmask represents which values are real, with 1 for real values
2991cb0ef41Sopenharmony_ci  //     and 0 for empty values.
3001cb0ef41Sopenharmony_ci  //   * The inputs to the node are the real values, in the order of the 1s from
3011cb0ef41Sopenharmony_ci  //     least- to most-significant.
3021cb0ef41Sopenharmony_ci  //   * The top bit of the bitmask is a guard indicating the end of the values,
3031cb0ef41Sopenharmony_ci  //     whether real or empty (and is not representative of a real input
3041cb0ef41Sopenharmony_ci  //     itself). This is used so that we don't have to additionally store a
3051cb0ef41Sopenharmony_ci  //     value count.
3061cb0ef41Sopenharmony_ci  //
3071cb0ef41Sopenharmony_ci  // So, for N 1s in the bitmask, there are N - 1 inputs into the node.
3081cb0ef41Sopenharmony_ci  BitMaskType bit_mask_;
3091cb0ef41Sopenharmony_ci};
3101cb0ef41Sopenharmony_ci
3111cb0ef41Sopenharmony_cibool operator==(SparseInputMask const& lhs, SparseInputMask const& rhs);
3121cb0ef41Sopenharmony_cibool operator!=(SparseInputMask const& lhs, SparseInputMask const& rhs);
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_ciclass TypedStateValueInfo final {
3151cb0ef41Sopenharmony_ci public:
3161cb0ef41Sopenharmony_ci  TypedStateValueInfo(ZoneVector<MachineType> const* machine_types,
3171cb0ef41Sopenharmony_ci                      SparseInputMask sparse_input_mask)
3181cb0ef41Sopenharmony_ci      : machine_types_(machine_types), sparse_input_mask_(sparse_input_mask) {}
3191cb0ef41Sopenharmony_ci
3201cb0ef41Sopenharmony_ci  ZoneVector<MachineType> const* machine_types() const {
3211cb0ef41Sopenharmony_ci    return machine_types_;
3221cb0ef41Sopenharmony_ci  }
3231cb0ef41Sopenharmony_ci  SparseInputMask sparse_input_mask() const { return sparse_input_mask_; }
3241cb0ef41Sopenharmony_ci
3251cb0ef41Sopenharmony_ci private:
3261cb0ef41Sopenharmony_ci  ZoneVector<MachineType> const* machine_types_;
3271cb0ef41Sopenharmony_ci  SparseInputMask sparse_input_mask_;
3281cb0ef41Sopenharmony_ci};
3291cb0ef41Sopenharmony_ci
3301cb0ef41Sopenharmony_cibool operator==(TypedStateValueInfo const& lhs, TypedStateValueInfo const& rhs);
3311cb0ef41Sopenharmony_cibool operator!=(TypedStateValueInfo const& lhs, TypedStateValueInfo const& rhs);
3321cb0ef41Sopenharmony_ci
3331cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream&, TypedStateValueInfo const&);
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_cisize_t hash_value(TypedStateValueInfo const& p);
3361cb0ef41Sopenharmony_ci
3371cb0ef41Sopenharmony_ci// Used to mark a region (as identified by BeginRegion/FinishRegion) as either
3381cb0ef41Sopenharmony_ci// JavaScript-observable or not (i.e. allocations are not JavaScript observable
3391cb0ef41Sopenharmony_ci// themselves, but transitioning stores are).
3401cb0ef41Sopenharmony_cienum class RegionObservability : uint8_t { kObservable, kNotObservable };
3411cb0ef41Sopenharmony_ci
3421cb0ef41Sopenharmony_cisize_t hash_value(RegionObservability);
3431cb0ef41Sopenharmony_ci
3441cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream&, RegionObservability);
3451cb0ef41Sopenharmony_ci
3461cb0ef41Sopenharmony_ciRegionObservability RegionObservabilityOf(Operator const*)
3471cb0ef41Sopenharmony_ci    V8_WARN_UNUSED_RESULT;
3481cb0ef41Sopenharmony_ci
3491cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& os,
3501cb0ef41Sopenharmony_ci                         const ZoneVector<MachineType>* types);
3511cb0ef41Sopenharmony_ci
3521cb0ef41Sopenharmony_ciType TypeGuardTypeOf(Operator const*) V8_WARN_UNUSED_RESULT;
3531cb0ef41Sopenharmony_ci
3541cb0ef41Sopenharmony_ciint OsrValueIndexOf(Operator const*) V8_WARN_UNUSED_RESULT;
3551cb0ef41Sopenharmony_ci
3561cb0ef41Sopenharmony_ciSparseInputMask SparseInputMaskOf(Operator const*) V8_WARN_UNUSED_RESULT;
3571cb0ef41Sopenharmony_ci
3581cb0ef41Sopenharmony_ciZoneVector<MachineType> const* MachineTypesOf(Operator const*)
3591cb0ef41Sopenharmony_ci    V8_WARN_UNUSED_RESULT;
3601cb0ef41Sopenharmony_ci
3611cb0ef41Sopenharmony_ci// The ArgumentsElementsState and ArgumentsLengthState can describe the layout
3621cb0ef41Sopenharmony_ci// for backing stores of arguments objects of various types:
3631cb0ef41Sopenharmony_ci//
3641cb0ef41Sopenharmony_ci//                        +------------------------------------+
3651cb0ef41Sopenharmony_ci//  - kUnmappedArguments: | arg0, ... argK-1, argK, ... argN-1 |  {length:N}
3661cb0ef41Sopenharmony_ci//                        +------------------------------------+
3671cb0ef41Sopenharmony_ci//                        +------------------------------------+
3681cb0ef41Sopenharmony_ci//  - kMappedArguments:   | hole, ...   hole, argK, ... argN-1 |  {length:N}
3691cb0ef41Sopenharmony_ci//                        +------------------------------------+
3701cb0ef41Sopenharmony_ci//                                          +------------------+
3711cb0ef41Sopenharmony_ci//  - kRestParameter:                       | argK, ... argN-1 |  {length:N-K}
3721cb0ef41Sopenharmony_ci//                                          +------------------+
3731cb0ef41Sopenharmony_ci//
3741cb0ef41Sopenharmony_ci// Here {K} represents the number for formal parameters of the active function,
3751cb0ef41Sopenharmony_ci// whereas {N} represents the actual number of arguments passed at runtime.
3761cb0ef41Sopenharmony_ci// Note that {N < K} can happen and causes {K} to be capped accordingly.
3771cb0ef41Sopenharmony_ci//
3781cb0ef41Sopenharmony_ci// Also note that it is possible for an arguments object of {kMappedArguments}
3791cb0ef41Sopenharmony_ci// type to carry a backing store of {kUnappedArguments} type when {K == 0}.
3801cb0ef41Sopenharmony_ciusing ArgumentsStateType = CreateArgumentsType;
3811cb0ef41Sopenharmony_ci
3821cb0ef41Sopenharmony_ciArgumentsStateType ArgumentsStateTypeOf(Operator const*) V8_WARN_UNUSED_RESULT;
3831cb0ef41Sopenharmony_ci
3841cb0ef41Sopenharmony_ciuint32_t ObjectIdOf(Operator const*);
3851cb0ef41Sopenharmony_ci
3861cb0ef41Sopenharmony_ciMachineRepresentation DeadValueRepresentationOf(Operator const*)
3871cb0ef41Sopenharmony_ci    V8_WARN_UNUSED_RESULT;
3881cb0ef41Sopenharmony_ci
3891cb0ef41Sopenharmony_ciclass IfValueParameters final {
3901cb0ef41Sopenharmony_ci public:
3911cb0ef41Sopenharmony_ci  IfValueParameters(int32_t value, int32_t comparison_order,
3921cb0ef41Sopenharmony_ci                    BranchHint hint = BranchHint::kNone)
3931cb0ef41Sopenharmony_ci      : value_(value), comparison_order_(comparison_order), hint_(hint) {}
3941cb0ef41Sopenharmony_ci
3951cb0ef41Sopenharmony_ci  int32_t value() const { return value_; }
3961cb0ef41Sopenharmony_ci  int32_t comparison_order() const { return comparison_order_; }
3971cb0ef41Sopenharmony_ci  BranchHint hint() const { return hint_; }
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_ci private:
4001cb0ef41Sopenharmony_ci  int32_t value_;
4011cb0ef41Sopenharmony_ci  int32_t comparison_order_;
4021cb0ef41Sopenharmony_ci  BranchHint hint_;
4031cb0ef41Sopenharmony_ci};
4041cb0ef41Sopenharmony_ci
4051cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE bool operator==(IfValueParameters const&,
4061cb0ef41Sopenharmony_ci                                  IfValueParameters const&);
4071cb0ef41Sopenharmony_ci
4081cb0ef41Sopenharmony_cisize_t hash_value(IfValueParameters const&);
4091cb0ef41Sopenharmony_ci
4101cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
4111cb0ef41Sopenharmony_ci                                           IfValueParameters const&);
4121cb0ef41Sopenharmony_ci
4131cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE IfValueParameters const& IfValueParametersOf(
4141cb0ef41Sopenharmony_ci    const Operator* op) V8_WARN_UNUSED_RESULT;
4151cb0ef41Sopenharmony_ci
4161cb0ef41Sopenharmony_ciconst FrameStateInfo& FrameStateInfoOf(const Operator* op)
4171cb0ef41Sopenharmony_ci    V8_WARN_UNUSED_RESULT;
4181cb0ef41Sopenharmony_ci
4191cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE Handle<HeapObject> HeapConstantOf(const Operator* op)
4201cb0ef41Sopenharmony_ci    V8_WARN_UNUSED_RESULT;
4211cb0ef41Sopenharmony_ci
4221cb0ef41Sopenharmony_ciconst StringConstantBase* StringConstantBaseOf(const Operator* op)
4231cb0ef41Sopenharmony_ci    V8_WARN_UNUSED_RESULT;
4241cb0ef41Sopenharmony_ci
4251cb0ef41Sopenharmony_ciconst char* StaticAssertSourceOf(const Operator* op);
4261cb0ef41Sopenharmony_ci
4271cb0ef41Sopenharmony_ciclass SLVerifierHintParameters final {
4281cb0ef41Sopenharmony_ci public:
4291cb0ef41Sopenharmony_ci  explicit SLVerifierHintParameters(const Operator* semantics,
4301cb0ef41Sopenharmony_ci                                    base::Optional<Type> override_output_type)
4311cb0ef41Sopenharmony_ci      : semantics_(semantics), override_output_type_(override_output_type) {}
4321cb0ef41Sopenharmony_ci
4331cb0ef41Sopenharmony_ci  const Operator* semantics() const { return semantics_; }
4341cb0ef41Sopenharmony_ci  const base::Optional<Type>& override_output_type() const {
4351cb0ef41Sopenharmony_ci    return override_output_type_;
4361cb0ef41Sopenharmony_ci  }
4371cb0ef41Sopenharmony_ci
4381cb0ef41Sopenharmony_ci private:
4391cb0ef41Sopenharmony_ci  const Operator* semantics_;
4401cb0ef41Sopenharmony_ci  base::Optional<Type> override_output_type_;
4411cb0ef41Sopenharmony_ci};
4421cb0ef41Sopenharmony_ci
4431cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE bool operator==(const SLVerifierHintParameters& p1,
4441cb0ef41Sopenharmony_ci                                  const SLVerifierHintParameters& p2);
4451cb0ef41Sopenharmony_ci
4461cb0ef41Sopenharmony_cisize_t hash_value(const SLVerifierHintParameters& p);
4471cb0ef41Sopenharmony_ci
4481cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
4491cb0ef41Sopenharmony_ci                                           const SLVerifierHintParameters& p);
4501cb0ef41Sopenharmony_ci
4511cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE const SLVerifierHintParameters& SLVerifierHintParametersOf(
4521cb0ef41Sopenharmony_ci    const Operator* op) V8_WARN_UNUSED_RESULT;
4531cb0ef41Sopenharmony_ci
4541cb0ef41Sopenharmony_ci// Interface for building common operators that can be used at any level of IR,
4551cb0ef41Sopenharmony_ci// including JavaScript, mid-level, and low-level.
4561cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE CommonOperatorBuilder final
4571cb0ef41Sopenharmony_ci    : public NON_EXPORTED_BASE(ZoneObject) {
4581cb0ef41Sopenharmony_ci public:
4591cb0ef41Sopenharmony_ci  explicit CommonOperatorBuilder(Zone* zone);
4601cb0ef41Sopenharmony_ci  CommonOperatorBuilder(const CommonOperatorBuilder&) = delete;
4611cb0ef41Sopenharmony_ci  CommonOperatorBuilder& operator=(const CommonOperatorBuilder&) = delete;
4621cb0ef41Sopenharmony_ci
4631cb0ef41Sopenharmony_ci  // A dummy value node temporarily used as input when the actual value doesn't
4641cb0ef41Sopenharmony_ci  // matter. This operator is inserted only in SimplifiedLowering and is
4651cb0ef41Sopenharmony_ci  // expected to not survive dead code elimination.
4661cb0ef41Sopenharmony_ci  const Operator* Plug();
4671cb0ef41Sopenharmony_ci
4681cb0ef41Sopenharmony_ci  const Operator* Dead();
4691cb0ef41Sopenharmony_ci  const Operator* DeadValue(MachineRepresentation rep);
4701cb0ef41Sopenharmony_ci  const Operator* Unreachable();
4711cb0ef41Sopenharmony_ci  const Operator* StaticAssert(const char* source);
4721cb0ef41Sopenharmony_ci  // SLVerifierHint is used only during SimplifiedLowering. It may be introduced
4731cb0ef41Sopenharmony_ci  // during lowering to provide additional hints for the verifier. These nodes
4741cb0ef41Sopenharmony_ci  // are removed at the end of SimplifiedLowering after verification.
4751cb0ef41Sopenharmony_ci  const Operator* SLVerifierHint(
4761cb0ef41Sopenharmony_ci      const Operator* semantics,
4771cb0ef41Sopenharmony_ci      const base::Optional<Type>& override_output_type);
4781cb0ef41Sopenharmony_ci  const Operator* End(size_t control_input_count);
4791cb0ef41Sopenharmony_ci  const Operator* Branch(BranchHint = BranchHint::kNone);
4801cb0ef41Sopenharmony_ci  const Operator* IfTrue();
4811cb0ef41Sopenharmony_ci  const Operator* IfFalse();
4821cb0ef41Sopenharmony_ci  const Operator* IfSuccess();
4831cb0ef41Sopenharmony_ci  const Operator* IfException();
4841cb0ef41Sopenharmony_ci  const Operator* Switch(size_t control_output_count);
4851cb0ef41Sopenharmony_ci  const Operator* IfValue(int32_t value, int32_t order = 0,
4861cb0ef41Sopenharmony_ci                          BranchHint hint = BranchHint::kNone);
4871cb0ef41Sopenharmony_ci  const Operator* IfDefault(BranchHint hint = BranchHint::kNone);
4881cb0ef41Sopenharmony_ci  const Operator* Throw();
4891cb0ef41Sopenharmony_ci  const Operator* Deoptimize(DeoptimizeReason reason,
4901cb0ef41Sopenharmony_ci                             FeedbackSource const& feedback);
4911cb0ef41Sopenharmony_ci  const Operator* DeoptimizeIf(DeoptimizeReason reason,
4921cb0ef41Sopenharmony_ci                               FeedbackSource const& feedback);
4931cb0ef41Sopenharmony_ci  const Operator* DeoptimizeUnless(DeoptimizeReason reason,
4941cb0ef41Sopenharmony_ci                                   FeedbackSource const& feedback);
4951cb0ef41Sopenharmony_ci  const Operator* TrapIf(TrapId trap_id);
4961cb0ef41Sopenharmony_ci  const Operator* TrapUnless(TrapId trap_id);
4971cb0ef41Sopenharmony_ci  const Operator* Return(int value_input_count = 1);
4981cb0ef41Sopenharmony_ci  const Operator* Terminate();
4991cb0ef41Sopenharmony_ci
5001cb0ef41Sopenharmony_ci  const Operator* Start(int value_output_count);
5011cb0ef41Sopenharmony_ci  const Operator* Loop(int control_input_count);
5021cb0ef41Sopenharmony_ci  const Operator* Merge(int control_input_count);
5031cb0ef41Sopenharmony_ci  const Operator* Parameter(int index, const char* debug_name = nullptr);
5041cb0ef41Sopenharmony_ci
5051cb0ef41Sopenharmony_ci  const Operator* OsrValue(int index);
5061cb0ef41Sopenharmony_ci
5071cb0ef41Sopenharmony_ci  const Operator* Int32Constant(int32_t);
5081cb0ef41Sopenharmony_ci  const Operator* Int64Constant(int64_t);
5091cb0ef41Sopenharmony_ci  const Operator* TaggedIndexConstant(int32_t value);
5101cb0ef41Sopenharmony_ci  const Operator* Float32Constant(volatile float);
5111cb0ef41Sopenharmony_ci  const Operator* Float64Constant(volatile double);
5121cb0ef41Sopenharmony_ci  const Operator* ExternalConstant(const ExternalReference&);
5131cb0ef41Sopenharmony_ci  const Operator* NumberConstant(volatile double);
5141cb0ef41Sopenharmony_ci  const Operator* PointerConstant(intptr_t);
5151cb0ef41Sopenharmony_ci  const Operator* HeapConstant(const Handle<HeapObject>&);
5161cb0ef41Sopenharmony_ci  const Operator* CompressedHeapConstant(const Handle<HeapObject>&);
5171cb0ef41Sopenharmony_ci  const Operator* ObjectId(uint32_t);
5181cb0ef41Sopenharmony_ci
5191cb0ef41Sopenharmony_ci  const Operator* RelocatableInt32Constant(int32_t value,
5201cb0ef41Sopenharmony_ci                                           RelocInfo::Mode rmode);
5211cb0ef41Sopenharmony_ci  const Operator* RelocatableInt64Constant(int64_t value,
5221cb0ef41Sopenharmony_ci                                           RelocInfo::Mode rmode);
5231cb0ef41Sopenharmony_ci
5241cb0ef41Sopenharmony_ci  const Operator* Select(MachineRepresentation, BranchHint = BranchHint::kNone);
5251cb0ef41Sopenharmony_ci  const Operator* Phi(MachineRepresentation representation,
5261cb0ef41Sopenharmony_ci                      int value_input_count);
5271cb0ef41Sopenharmony_ci  const Operator* EffectPhi(int effect_input_count);
5281cb0ef41Sopenharmony_ci  const Operator* InductionVariablePhi(int value_input_count);
5291cb0ef41Sopenharmony_ci  const Operator* LoopExit();
5301cb0ef41Sopenharmony_ci  const Operator* LoopExitValue(MachineRepresentation rep);
5311cb0ef41Sopenharmony_ci  const Operator* LoopExitEffect();
5321cb0ef41Sopenharmony_ci  const Operator* Checkpoint();
5331cb0ef41Sopenharmony_ci  const Operator* BeginRegion(RegionObservability);
5341cb0ef41Sopenharmony_ci  const Operator* FinishRegion();
5351cb0ef41Sopenharmony_ci  const Operator* StateValues(int arguments, SparseInputMask bitmask);
5361cb0ef41Sopenharmony_ci  const Operator* TypedStateValues(const ZoneVector<MachineType>* types,
5371cb0ef41Sopenharmony_ci                                   SparseInputMask bitmask);
5381cb0ef41Sopenharmony_ci  const Operator* ArgumentsElementsState(ArgumentsStateType type);
5391cb0ef41Sopenharmony_ci  const Operator* ArgumentsLengthState();
5401cb0ef41Sopenharmony_ci  const Operator* ObjectState(uint32_t object_id, int pointer_slots);
5411cb0ef41Sopenharmony_ci  const Operator* TypedObjectState(uint32_t object_id,
5421cb0ef41Sopenharmony_ci                                   const ZoneVector<MachineType>* types);
5431cb0ef41Sopenharmony_ci  const Operator* FrameState(BytecodeOffset bailout_id,
5441cb0ef41Sopenharmony_ci                             OutputFrameStateCombine state_combine,
5451cb0ef41Sopenharmony_ci                             const FrameStateFunctionInfo* function_info);
5461cb0ef41Sopenharmony_ci  const Operator* Call(const CallDescriptor* call_descriptor);
5471cb0ef41Sopenharmony_ci  const Operator* TailCall(const CallDescriptor* call_descriptor);
5481cb0ef41Sopenharmony_ci  const Operator* Projection(size_t index);
5491cb0ef41Sopenharmony_ci  const Operator* Retain();
5501cb0ef41Sopenharmony_ci  const Operator* TypeGuard(Type type);
5511cb0ef41Sopenharmony_ci  const Operator* FoldConstant();
5521cb0ef41Sopenharmony_ci
5531cb0ef41Sopenharmony_ci  // Constructs a new merge or phi operator with the same opcode as {op}, but
5541cb0ef41Sopenharmony_ci  // with {size} inputs.
5551cb0ef41Sopenharmony_ci  const Operator* ResizeMergeOrPhi(const Operator* op, int size);
5561cb0ef41Sopenharmony_ci
5571cb0ef41Sopenharmony_ci  // Constructs function info for frame state construction.
5581cb0ef41Sopenharmony_ci  const FrameStateFunctionInfo* CreateFrameStateFunctionInfo(
5591cb0ef41Sopenharmony_ci      FrameStateType type, int parameter_count, int local_count,
5601cb0ef41Sopenharmony_ci      Handle<SharedFunctionInfo> shared_info);
5611cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
5621cb0ef41Sopenharmony_ci  const FrameStateFunctionInfo* CreateJSToWasmFrameStateFunctionInfo(
5631cb0ef41Sopenharmony_ci      FrameStateType type, int parameter_count, int local_count,
5641cb0ef41Sopenharmony_ci      Handle<SharedFunctionInfo> shared_info,
5651cb0ef41Sopenharmony_ci      const wasm::FunctionSig* signature);
5661cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
5671cb0ef41Sopenharmony_ci
5681cb0ef41Sopenharmony_ci  const Operator* DelayedStringConstant(const StringConstantBase* str);
5691cb0ef41Sopenharmony_ci
5701cb0ef41Sopenharmony_ci private:
5711cb0ef41Sopenharmony_ci  Zone* zone() const { return zone_; }
5721cb0ef41Sopenharmony_ci
5731cb0ef41Sopenharmony_ci  const CommonOperatorGlobalCache& cache_;
5741cb0ef41Sopenharmony_ci  Zone* const zone_;
5751cb0ef41Sopenharmony_ci};
5761cb0ef41Sopenharmony_ci
5771cb0ef41Sopenharmony_ci// Node wrappers.
5781cb0ef41Sopenharmony_ci
5791cb0ef41Sopenharmony_ciclass CommonNodeWrapperBase : public NodeWrapper {
5801cb0ef41Sopenharmony_ci public:
5811cb0ef41Sopenharmony_ci  explicit constexpr CommonNodeWrapperBase(Node* node) : NodeWrapper(node) {}
5821cb0ef41Sopenharmony_ci
5831cb0ef41Sopenharmony_ci  // Valid iff this node has exactly one effect input.
5841cb0ef41Sopenharmony_ci  Effect effect() const {
5851cb0ef41Sopenharmony_ci    DCHECK_EQ(node()->op()->EffectInputCount(), 1);
5861cb0ef41Sopenharmony_ci    return Effect{NodeProperties::GetEffectInput(node())};
5871cb0ef41Sopenharmony_ci  }
5881cb0ef41Sopenharmony_ci
5891cb0ef41Sopenharmony_ci  // Valid iff this node has exactly one control input.
5901cb0ef41Sopenharmony_ci  Control control() const {
5911cb0ef41Sopenharmony_ci    DCHECK_EQ(node()->op()->ControlInputCount(), 1);
5921cb0ef41Sopenharmony_ci    return Control{NodeProperties::GetControlInput(node())};
5931cb0ef41Sopenharmony_ci  }
5941cb0ef41Sopenharmony_ci};
5951cb0ef41Sopenharmony_ci
5961cb0ef41Sopenharmony_ci#define DEFINE_INPUT_ACCESSORS(Name, name, TheIndex, Type) \
5971cb0ef41Sopenharmony_ci  static constexpr int Name##Index() { return TheIndex; }  \
5981cb0ef41Sopenharmony_ci  TNode<Type> name() const {                               \
5991cb0ef41Sopenharmony_ci    return TNode<Type>::UncheckedCast(                     \
6001cb0ef41Sopenharmony_ci        NodeProperties::GetValueInput(node(), TheIndex));  \
6011cb0ef41Sopenharmony_ci  }
6021cb0ef41Sopenharmony_ci
6031cb0ef41Sopenharmony_ci// TODO(jgruber): This class doesn't match the usual OpcodeNode naming
6041cb0ef41Sopenharmony_ci// convention for historical reasons (it was originally a very basic typed node
6051cb0ef41Sopenharmony_ci// wrapper similar to Effect and Control). Consider updating the name, with low
6061cb0ef41Sopenharmony_ci// priority.
6071cb0ef41Sopenharmony_ciclass FrameState : public CommonNodeWrapperBase {
6081cb0ef41Sopenharmony_ci public:
6091cb0ef41Sopenharmony_ci  explicit constexpr FrameState(Node* node) : CommonNodeWrapperBase(node) {
6101cb0ef41Sopenharmony_ci    DCHECK_EQ(node->opcode(), IrOpcode::kFrameState);
6111cb0ef41Sopenharmony_ci  }
6121cb0ef41Sopenharmony_ci
6131cb0ef41Sopenharmony_ci  FrameStateInfo frame_state_info() const {
6141cb0ef41Sopenharmony_ci    return FrameStateInfoOf(node()->op());
6151cb0ef41Sopenharmony_ci  }
6161cb0ef41Sopenharmony_ci
6171cb0ef41Sopenharmony_ci  static constexpr int kFrameStateParametersInput = 0;
6181cb0ef41Sopenharmony_ci  static constexpr int kFrameStateLocalsInput = 1;
6191cb0ef41Sopenharmony_ci  static constexpr int kFrameStateStackInput = 2;
6201cb0ef41Sopenharmony_ci  static constexpr int kFrameStateContextInput = 3;
6211cb0ef41Sopenharmony_ci  static constexpr int kFrameStateFunctionInput = 4;
6221cb0ef41Sopenharmony_ci  static constexpr int kFrameStateOuterStateInput = 5;
6231cb0ef41Sopenharmony_ci  static constexpr int kFrameStateInputCount = 6;
6241cb0ef41Sopenharmony_ci
6251cb0ef41Sopenharmony_ci  // Note: The parameters should be accessed through StateValuesAccess.
6261cb0ef41Sopenharmony_ci  Node* parameters() const {
6271cb0ef41Sopenharmony_ci    Node* n = node()->InputAt(kFrameStateParametersInput);
6281cb0ef41Sopenharmony_ci    DCHECK(n->opcode() == IrOpcode::kStateValues ||
6291cb0ef41Sopenharmony_ci           n->opcode() == IrOpcode::kTypedStateValues);
6301cb0ef41Sopenharmony_ci    return n;
6311cb0ef41Sopenharmony_ci  }
6321cb0ef41Sopenharmony_ci  Node* locals() const {
6331cb0ef41Sopenharmony_ci    Node* n = node()->InputAt(kFrameStateLocalsInput);
6341cb0ef41Sopenharmony_ci    DCHECK(n->opcode() == IrOpcode::kStateValues ||
6351cb0ef41Sopenharmony_ci           n->opcode() == IrOpcode::kTypedStateValues);
6361cb0ef41Sopenharmony_ci    return n;
6371cb0ef41Sopenharmony_ci  }
6381cb0ef41Sopenharmony_ci  // TODO(jgruber): Consider renaming this to the more meaningful
6391cb0ef41Sopenharmony_ci  // 'accumulator'.
6401cb0ef41Sopenharmony_ci  Node* stack() const { return node()->InputAt(kFrameStateStackInput); }
6411cb0ef41Sopenharmony_ci  Node* context() const { return node()->InputAt(kFrameStateContextInput); }
6421cb0ef41Sopenharmony_ci  Node* function() const { return node()->InputAt(kFrameStateFunctionInput); }
6431cb0ef41Sopenharmony_ci
6441cb0ef41Sopenharmony_ci  // An outer frame state exists for inlined functions; otherwise it points at
6451cb0ef41Sopenharmony_ci  // the start node. Could also be dead.
6461cb0ef41Sopenharmony_ci  Node* outer_frame_state() const {
6471cb0ef41Sopenharmony_ci    Node* result = node()->InputAt(kFrameStateOuterStateInput);
6481cb0ef41Sopenharmony_ci    DCHECK(result->opcode() == IrOpcode::kFrameState ||
6491cb0ef41Sopenharmony_ci           result->opcode() == IrOpcode::kStart ||
6501cb0ef41Sopenharmony_ci           result->opcode() == IrOpcode::kDeadValue);
6511cb0ef41Sopenharmony_ci    return result;
6521cb0ef41Sopenharmony_ci  }
6531cb0ef41Sopenharmony_ci};
6541cb0ef41Sopenharmony_ci
6551cb0ef41Sopenharmony_ciclass StartNode final : public CommonNodeWrapperBase {
6561cb0ef41Sopenharmony_ci public:
6571cb0ef41Sopenharmony_ci  explicit constexpr StartNode(Node* node) : CommonNodeWrapperBase(node) {
6581cb0ef41Sopenharmony_ci    DCHECK_EQ(IrOpcode::kStart, node->opcode());
6591cb0ef41Sopenharmony_ci  }
6601cb0ef41Sopenharmony_ci
6611cb0ef41Sopenharmony_ci  // The receiver is counted as part of formal parameters.
6621cb0ef41Sopenharmony_ci  static constexpr int kReceiverOutputCount = 1;
6631cb0ef41Sopenharmony_ci  // These outputs are in addition to formal parameters.
6641cb0ef41Sopenharmony_ci  static constexpr int kExtraOutputCount = 4;
6651cb0ef41Sopenharmony_ci
6661cb0ef41Sopenharmony_ci  // Takes the formal parameter count of the current function (including
6671cb0ef41Sopenharmony_ci  // receiver) and returns the number of value outputs of the start node.
6681cb0ef41Sopenharmony_ci  static constexpr int OutputArityForFormalParameterCount(int argc) {
6691cb0ef41Sopenharmony_ci    constexpr int kClosure = 1;
6701cb0ef41Sopenharmony_ci    constexpr int kNewTarget = 1;
6711cb0ef41Sopenharmony_ci    constexpr int kArgCount = 1;
6721cb0ef41Sopenharmony_ci    constexpr int kContext = 1;
6731cb0ef41Sopenharmony_ci    STATIC_ASSERT(kClosure + kNewTarget + kArgCount + kContext ==
6741cb0ef41Sopenharmony_ci                  kExtraOutputCount);
6751cb0ef41Sopenharmony_ci    // Checking related linkage methods here since they rely on Start node
6761cb0ef41Sopenharmony_ci    // layout.
6771cb0ef41Sopenharmony_ci    DCHECK_EQ(-1, Linkage::kJSCallClosureParamIndex);
6781cb0ef41Sopenharmony_ci    DCHECK_EQ(argc + 0, Linkage::GetJSCallNewTargetParamIndex(argc));
6791cb0ef41Sopenharmony_ci    DCHECK_EQ(argc + 1, Linkage::GetJSCallArgCountParamIndex(argc));
6801cb0ef41Sopenharmony_ci    DCHECK_EQ(argc + 2, Linkage::GetJSCallContextParamIndex(argc));
6811cb0ef41Sopenharmony_ci    return argc + kClosure + kNewTarget + kArgCount + kContext;
6821cb0ef41Sopenharmony_ci  }
6831cb0ef41Sopenharmony_ci
6841cb0ef41Sopenharmony_ci  int FormalParameterCount() const {
6851cb0ef41Sopenharmony_ci    DCHECK_GE(node()->op()->ValueOutputCount(),
6861cb0ef41Sopenharmony_ci              kExtraOutputCount + kReceiverOutputCount);
6871cb0ef41Sopenharmony_ci    return node()->op()->ValueOutputCount() - kExtraOutputCount;
6881cb0ef41Sopenharmony_ci  }
6891cb0ef41Sopenharmony_ci
6901cb0ef41Sopenharmony_ci  int FormalParameterCountWithoutReceiver() const {
6911cb0ef41Sopenharmony_ci    DCHECK_GE(node()->op()->ValueOutputCount(),
6921cb0ef41Sopenharmony_ci              kExtraOutputCount + kReceiverOutputCount);
6931cb0ef41Sopenharmony_ci    return node()->op()->ValueOutputCount() - kExtraOutputCount -
6941cb0ef41Sopenharmony_ci           kReceiverOutputCount;
6951cb0ef41Sopenharmony_ci  }
6961cb0ef41Sopenharmony_ci
6971cb0ef41Sopenharmony_ci  // Note these functions don't return the index of the Start output; instead
6981cb0ef41Sopenharmony_ci  // they return the index assigned to the Parameter node.
6991cb0ef41Sopenharmony_ci  // TODO(jgruber): Consider unifying the two.
7001cb0ef41Sopenharmony_ci  int NewTargetParameterIndex() const {
7011cb0ef41Sopenharmony_ci    return Linkage::GetJSCallNewTargetParamIndex(FormalParameterCount());
7021cb0ef41Sopenharmony_ci  }
7031cb0ef41Sopenharmony_ci  int ArgCountParameterIndex() const {
7041cb0ef41Sopenharmony_ci    return Linkage::GetJSCallArgCountParamIndex(FormalParameterCount());
7051cb0ef41Sopenharmony_ci  }
7061cb0ef41Sopenharmony_ci  int ContextParameterIndex() const {
7071cb0ef41Sopenharmony_ci    return Linkage::GetJSCallContextParamIndex(FormalParameterCount());
7081cb0ef41Sopenharmony_ci  }
7091cb0ef41Sopenharmony_ci
7101cb0ef41Sopenharmony_ci  // TODO(jgruber): Remove this function and use
7111cb0ef41Sopenharmony_ci  // Linkage::GetJSCallContextParamIndex instead. This currently doesn't work
7121cb0ef41Sopenharmony_ci  // because tests don't create valid Start nodes - for example, they may add
7131cb0ef41Sopenharmony_ci  // only two context outputs (and not the closure, new target, argc). Once
7141cb0ef41Sopenharmony_ci  // tests are fixed, remove this function.
7151cb0ef41Sopenharmony_ci  int ContextParameterIndex_MaybeNonStandardLayout() const {
7161cb0ef41Sopenharmony_ci    // The context is always the last parameter to a JavaScript function, and
7171cb0ef41Sopenharmony_ci    // {Parameter} indices start at -1, so value outputs of {Start} look like
7181cb0ef41Sopenharmony_ci    // this: closure, receiver, param0, ..., paramN, context.
7191cb0ef41Sopenharmony_ci    //
7201cb0ef41Sopenharmony_ci    // TODO(jgruber): This function is called from spots that operate on
7211cb0ef41Sopenharmony_ci    // CSA/Torque graphs; Start node layout appears to be different there.
7221cb0ef41Sopenharmony_ci    // These should be unified to avoid confusion. Once done, enable this
7231cb0ef41Sopenharmony_ci    // DCHECK: DCHECK_EQ(LastOutputIndex(), ContextOutputIndex());
7241cb0ef41Sopenharmony_ci    return node()->op()->ValueOutputCount() - 2;
7251cb0ef41Sopenharmony_ci  }
7261cb0ef41Sopenharmony_ci  int LastParameterIndex_MaybeNonStandardLayout() const {
7271cb0ef41Sopenharmony_ci    return ContextParameterIndex_MaybeNonStandardLayout();
7281cb0ef41Sopenharmony_ci  }
7291cb0ef41Sopenharmony_ci
7301cb0ef41Sopenharmony_ci  // Unlike ContextParameterIndex_MaybeNonStandardLayout above, these return
7311cb0ef41Sopenharmony_ci  // output indices (and not the index assigned to a Parameter).
7321cb0ef41Sopenharmony_ci  int NewTargetOutputIndex() const {
7331cb0ef41Sopenharmony_ci    // Indices assigned to parameters are off-by-one (Parameters indices start
7341cb0ef41Sopenharmony_ci    // at -1).
7351cb0ef41Sopenharmony_ci    // TODO(jgruber): Consider starting at 0.
7361cb0ef41Sopenharmony_ci    DCHECK_EQ(Linkage::GetJSCallNewTargetParamIndex(FormalParameterCount()) + 1,
7371cb0ef41Sopenharmony_ci              node()->op()->ValueOutputCount() - 3);
7381cb0ef41Sopenharmony_ci    return node()->op()->ValueOutputCount() - 3;
7391cb0ef41Sopenharmony_ci  }
7401cb0ef41Sopenharmony_ci  int ArgCountOutputIndex() const {
7411cb0ef41Sopenharmony_ci    // Indices assigned to parameters are off-by-one (Parameters indices start
7421cb0ef41Sopenharmony_ci    // at -1).
7431cb0ef41Sopenharmony_ci    // TODO(jgruber): Consider starting at 0.
7441cb0ef41Sopenharmony_ci    DCHECK_EQ(Linkage::GetJSCallArgCountParamIndex(FormalParameterCount()) + 1,
7451cb0ef41Sopenharmony_ci              node()->op()->ValueOutputCount() - 2);
7461cb0ef41Sopenharmony_ci    return node()->op()->ValueOutputCount() - 2;
7471cb0ef41Sopenharmony_ci  }
7481cb0ef41Sopenharmony_ci  int ContextOutputIndex() const {
7491cb0ef41Sopenharmony_ci    // Indices assigned to parameters are off-by-one (Parameters indices start
7501cb0ef41Sopenharmony_ci    // at -1).
7511cb0ef41Sopenharmony_ci    // TODO(jgruber): Consider starting at 0.
7521cb0ef41Sopenharmony_ci    DCHECK_EQ(Linkage::GetJSCallContextParamIndex(FormalParameterCount()) + 1,
7531cb0ef41Sopenharmony_ci              node()->op()->ValueOutputCount() - 1);
7541cb0ef41Sopenharmony_ci    return node()->op()->ValueOutputCount() - 1;
7551cb0ef41Sopenharmony_ci  }
7561cb0ef41Sopenharmony_ci  int LastOutputIndex() const { return ContextOutputIndex(); }
7571cb0ef41Sopenharmony_ci};
7581cb0ef41Sopenharmony_ci
7591cb0ef41Sopenharmony_ci#undef DEFINE_INPUT_ACCESSORS
7601cb0ef41Sopenharmony_ci
7611cb0ef41Sopenharmony_ci}  // namespace compiler
7621cb0ef41Sopenharmony_ci}  // namespace internal
7631cb0ef41Sopenharmony_ci}  // namespace v8
7641cb0ef41Sopenharmony_ci
7651cb0ef41Sopenharmony_ci#endif  // V8_COMPILER_COMMON_OPERATOR_H_
766