11cb0ef41Sopenharmony_ci// Copyright 2013 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_NODE_H_ 61cb0ef41Sopenharmony_ci#define V8_COMPILER_NODE_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/common/globals.h" 91cb0ef41Sopenharmony_ci#include "src/compiler/graph-zone-traits.h" 101cb0ef41Sopenharmony_ci#include "src/compiler/opcodes.h" 111cb0ef41Sopenharmony_ci#include "src/compiler/operator.h" 121cb0ef41Sopenharmony_ci#include "src/compiler/types.h" 131cb0ef41Sopenharmony_ci#include "src/zone/zone-containers.h" 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_cinamespace v8 { 161cb0ef41Sopenharmony_cinamespace internal { 171cb0ef41Sopenharmony_cinamespace compiler { 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci// Forward declarations. 201cb0ef41Sopenharmony_ciclass Edge; 211cb0ef41Sopenharmony_ciclass Graph; 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ci// Marks are used during traversal of the graph to distinguish states of nodes. 251cb0ef41Sopenharmony_ci// Each node has a mark which is a monotonically increasing integer, and a 261cb0ef41Sopenharmony_ci// {NodeMarker} has a range of values that indicate states of a node. 271cb0ef41Sopenharmony_ciusing Mark = uint32_t; 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci// NodeIds are identifying numbers for nodes that can be used to index auxiliary 301cb0ef41Sopenharmony_ci// out-of-line data associated with each node. 311cb0ef41Sopenharmony_ciusing NodeId = uint32_t; 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci// A Node is the basic primitive of graphs. Nodes are chained together by 341cb0ef41Sopenharmony_ci// input/use chains but by default otherwise contain only an identifying number 351cb0ef41Sopenharmony_ci// which specific applications of graphs and nodes can use to index auxiliary 361cb0ef41Sopenharmony_ci// out-of-line data, especially transient data. 371cb0ef41Sopenharmony_ci// 381cb0ef41Sopenharmony_ci// In addition Nodes only contain a mutable Operator that may change during 391cb0ef41Sopenharmony_ci// compilation, e.g. during lowering passes. Other information that needs to be 401cb0ef41Sopenharmony_ci// associated with Nodes during compilation must be stored out-of-line indexed 411cb0ef41Sopenharmony_ci// by the Node's id. 421cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE Node final { 431cb0ef41Sopenharmony_ci public: 441cb0ef41Sopenharmony_ci static Node* New(Zone* zone, NodeId id, const Operator* op, int input_count, 451cb0ef41Sopenharmony_ci Node* const* inputs, bool has_extensible_inputs); 461cb0ef41Sopenharmony_ci static Node* Clone(Zone* zone, NodeId id, const Node* node); 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci inline bool IsDead() const; 491cb0ef41Sopenharmony_ci void Kill(); 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci const Operator* op() const { return op_; } 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci constexpr IrOpcode::Value opcode() const { 541cb0ef41Sopenharmony_ci DCHECK_GE(IrOpcode::kLast, op_->opcode()); 551cb0ef41Sopenharmony_ci return static_cast<IrOpcode::Value>(op_->opcode()); 561cb0ef41Sopenharmony_ci } 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci NodeId id() const { return IdField::decode(bit_field_); } 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci int InputCount() const { 611cb0ef41Sopenharmony_ci return has_inline_inputs() ? InlineCountField::decode(bit_field_) 621cb0ef41Sopenharmony_ci : outline_inputs()->count_; 631cb0ef41Sopenharmony_ci } 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci#ifdef DEBUG 661cb0ef41Sopenharmony_ci void Verify(); 671cb0ef41Sopenharmony_ci#else 681cb0ef41Sopenharmony_ci inline void Verify() {} 691cb0ef41Sopenharmony_ci#endif 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci Node* InputAt(int index) const { 721cb0ef41Sopenharmony_ci DCHECK_LE(0, index); 731cb0ef41Sopenharmony_ci DCHECK_LT(index, InputCount()); 741cb0ef41Sopenharmony_ci return *GetInputPtrConst(index); 751cb0ef41Sopenharmony_ci } 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci void ReplaceInput(int index, Node* new_to) { 781cb0ef41Sopenharmony_ci DCHECK_LE(0, index); 791cb0ef41Sopenharmony_ci DCHECK_LT(index, InputCount()); 801cb0ef41Sopenharmony_ci ZoneNodePtr* input_ptr = GetInputPtr(index); 811cb0ef41Sopenharmony_ci Node* old_to = *input_ptr; 821cb0ef41Sopenharmony_ci if (old_to != new_to) { 831cb0ef41Sopenharmony_ci Use* use = GetUsePtr(index); 841cb0ef41Sopenharmony_ci if (old_to) old_to->RemoveUse(use); 851cb0ef41Sopenharmony_ci *input_ptr = new_to; 861cb0ef41Sopenharmony_ci if (new_to) new_to->AppendUse(use); 871cb0ef41Sopenharmony_ci } 881cb0ef41Sopenharmony_ci } 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci void AppendInput(Zone* zone, Node* new_to); 911cb0ef41Sopenharmony_ci void InsertInput(Zone* zone, int index, Node* new_to); 921cb0ef41Sopenharmony_ci void InsertInputs(Zone* zone, int index, int count); 931cb0ef41Sopenharmony_ci // Returns the removed input. 941cb0ef41Sopenharmony_ci Node* RemoveInput(int index); 951cb0ef41Sopenharmony_ci void NullAllInputs(); 961cb0ef41Sopenharmony_ci void TrimInputCount(int new_input_count); 971cb0ef41Sopenharmony_ci // Can trim, extend by appending new inputs, or do nothing. 981cb0ef41Sopenharmony_ci void EnsureInputCount(Zone* zone, int new_input_count); 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci int UseCount() const; 1011cb0ef41Sopenharmony_ci void ReplaceUses(Node* replace_to); 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci class InputEdges; 1041cb0ef41Sopenharmony_ci inline InputEdges input_edges(); 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci class Inputs; 1071cb0ef41Sopenharmony_ci inline Inputs inputs() const; 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci class UseEdges final { 1101cb0ef41Sopenharmony_ci public: 1111cb0ef41Sopenharmony_ci using value_type = Edge; 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci class iterator; 1141cb0ef41Sopenharmony_ci inline iterator begin() const; 1151cb0ef41Sopenharmony_ci inline iterator end() const; 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci bool empty() const; 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci explicit UseEdges(Node* node) : node_(node) {} 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_ci private: 1221cb0ef41Sopenharmony_ci Node* node_; 1231cb0ef41Sopenharmony_ci }; 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci UseEdges use_edges() { return UseEdges(this); } 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci class V8_EXPORT_PRIVATE Uses final { 1281cb0ef41Sopenharmony_ci public: 1291cb0ef41Sopenharmony_ci using value_type = Node*; 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci class const_iterator; 1321cb0ef41Sopenharmony_ci inline const_iterator begin() const; 1331cb0ef41Sopenharmony_ci inline const_iterator end() const; 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ci bool empty() const; 1361cb0ef41Sopenharmony_ci 1371cb0ef41Sopenharmony_ci explicit Uses(Node* node) : node_(node) {} 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_ci private: 1401cb0ef41Sopenharmony_ci Node* node_; 1411cb0ef41Sopenharmony_ci }; 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci Uses uses() { return Uses(this); } 1441cb0ef41Sopenharmony_ci 1451cb0ef41Sopenharmony_ci // Returns true if {owner} is the only user of {this} node. 1461cb0ef41Sopenharmony_ci bool OwnedBy(Node const* owner) const; 1471cb0ef41Sopenharmony_ci 1481cb0ef41Sopenharmony_ci // Returns true if {owner1} and {owner2} are the only users of {this} node. 1491cb0ef41Sopenharmony_ci bool OwnedBy(Node const* owner1, Node const* owner2) const; 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_ci void Print() const { Print(1); } 1521cb0ef41Sopenharmony_ci void Print(int depth) const; 1531cb0ef41Sopenharmony_ci void Print(std::ostream&, int depth = 1) const; 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci private: 1561cb0ef41Sopenharmony_ci template <typename NodePtrT> 1571cb0ef41Sopenharmony_ci inline static Node* NewImpl(Zone* zone, NodeId id, const Operator* op, 1581cb0ef41Sopenharmony_ci int input_count, NodePtrT const* inputs, 1591cb0ef41Sopenharmony_ci bool has_extensible_inputs); 1601cb0ef41Sopenharmony_ci 1611cb0ef41Sopenharmony_ci struct Use; 1621cb0ef41Sopenharmony_ci using ZoneUsePtr = GraphZoneTraits::Ptr<Use>; 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ci // Out of line storage for inputs when the number of inputs overflowed the 1651cb0ef41Sopenharmony_ci // capacity of the inline-allocated space. 1661cb0ef41Sopenharmony_ci struct OutOfLineInputs { 1671cb0ef41Sopenharmony_ci ZoneNodePtr node_; 1681cb0ef41Sopenharmony_ci int count_; 1691cb0ef41Sopenharmony_ci int capacity_; 1701cb0ef41Sopenharmony_ci 1711cb0ef41Sopenharmony_ci // Inputs are allocated right behind the OutOfLineInputs instance. 1721cb0ef41Sopenharmony_ci inline ZoneNodePtr* inputs(); 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_ci static OutOfLineInputs* New(Zone* zone, int capacity); 1751cb0ef41Sopenharmony_ci void ExtractFrom(Use* use_ptr, ZoneNodePtr* input_ptr, int count); 1761cb0ef41Sopenharmony_ci }; 1771cb0ef41Sopenharmony_ci using ZoneOutOfLineInputsPtr = GraphZoneTraits::Ptr<OutOfLineInputs>; 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_ci // A link in the use chain for a node. Every input {i} to a node {n} has an 1801cb0ef41Sopenharmony_ci // associated {Use} which is linked into the use chain of the {i} node. 1811cb0ef41Sopenharmony_ci struct Use { 1821cb0ef41Sopenharmony_ci ZoneUsePtr next; 1831cb0ef41Sopenharmony_ci ZoneUsePtr prev; 1841cb0ef41Sopenharmony_ci uint32_t bit_field_; 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_ci int input_index() const { return InputIndexField::decode(bit_field_); } 1871cb0ef41Sopenharmony_ci bool is_inline_use() const { return InlineField::decode(bit_field_); } 1881cb0ef41Sopenharmony_ci ZoneNodePtr* input_ptr() { 1891cb0ef41Sopenharmony_ci int index = input_index(); 1901cb0ef41Sopenharmony_ci Use* start = this + 1 + index; 1911cb0ef41Sopenharmony_ci ZoneNodePtr* inputs = 1921cb0ef41Sopenharmony_ci is_inline_use() ? reinterpret_cast<Node*>(start)->inline_inputs() 1931cb0ef41Sopenharmony_ci : reinterpret_cast<OutOfLineInputs*>(start)->inputs(); 1941cb0ef41Sopenharmony_ci return &inputs[index]; 1951cb0ef41Sopenharmony_ci } 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci Node* from() { 1981cb0ef41Sopenharmony_ci Use* start = this + 1 + input_index(); 1991cb0ef41Sopenharmony_ci return is_inline_use() ? reinterpret_cast<Node*>(start) 2001cb0ef41Sopenharmony_ci : reinterpret_cast<OutOfLineInputs*>(start)->node_; 2011cb0ef41Sopenharmony_ci } 2021cb0ef41Sopenharmony_ci 2031cb0ef41Sopenharmony_ci using InlineField = base::BitField<bool, 0, 1>; 2041cb0ef41Sopenharmony_ci using InputIndexField = base::BitField<unsigned, 1, 31>; 2051cb0ef41Sopenharmony_ci }; 2061cb0ef41Sopenharmony_ci 2071cb0ef41Sopenharmony_ci //============================================================================ 2081cb0ef41Sopenharmony_ci //== Memory layout =========================================================== 2091cb0ef41Sopenharmony_ci //============================================================================ 2101cb0ef41Sopenharmony_ci // Saving space for big graphs is important. We use a memory layout trick to 2111cb0ef41Sopenharmony_ci // be able to map {Node} objects to {Use} objects and vice-versa in a 2121cb0ef41Sopenharmony_ci // space-efficient manner. 2131cb0ef41Sopenharmony_ci // 2141cb0ef41Sopenharmony_ci // {Use} links are laid out in memory directly before a {Node}, followed by 2151cb0ef41Sopenharmony_ci // direct pointers to input {Nodes}. 2161cb0ef41Sopenharmony_ci // 2171cb0ef41Sopenharmony_ci // inline case: 2181cb0ef41Sopenharmony_ci // |Use #N |Use #N-1|...|Use #1 |Use #0 |Node xxxx |I#0|I#1|...|I#N-1|I#N| 2191cb0ef41Sopenharmony_ci // ^ ^ ^ 2201cb0ef41Sopenharmony_ci // + Use + Node + Input 2211cb0ef41Sopenharmony_ci // 2221cb0ef41Sopenharmony_ci // Since every {Use} instance records its {input_index}, pointer arithmetic 2231cb0ef41Sopenharmony_ci // can compute the {Node}. 2241cb0ef41Sopenharmony_ci // 2251cb0ef41Sopenharmony_ci // out-of-line case: 2261cb0ef41Sopenharmony_ci // |Node xxxx | 2271cb0ef41Sopenharmony_ci // ^ + outline ------------------+ 2281cb0ef41Sopenharmony_ci // +----------------------------------------+ 2291cb0ef41Sopenharmony_ci // | | 2301cb0ef41Sopenharmony_ci // v | node 2311cb0ef41Sopenharmony_ci // |Use #N |Use #N-1|...|Use #1 |Use #0 |OOL xxxxx |I#0|I#1|...|I#N-1|I#N| 2321cb0ef41Sopenharmony_ci // ^ ^ 2331cb0ef41Sopenharmony_ci // + Use + Input 2341cb0ef41Sopenharmony_ci // 2351cb0ef41Sopenharmony_ci // Out-of-line storage of input lists is needed if appending an input to 2361cb0ef41Sopenharmony_ci // a node exceeds the maximum inline capacity. 2371cb0ef41Sopenharmony_ci 2381cb0ef41Sopenharmony_ci Node(NodeId id, const Operator* op, int inline_count, int inline_capacity); 2391cb0ef41Sopenharmony_ci Node(const Node&) = delete; 2401cb0ef41Sopenharmony_ci Node& operator=(const Node&) = delete; 2411cb0ef41Sopenharmony_ci 2421cb0ef41Sopenharmony_ci inline Address inputs_location() const; 2431cb0ef41Sopenharmony_ci 2441cb0ef41Sopenharmony_ci ZoneNodePtr* inline_inputs() const { 2451cb0ef41Sopenharmony_ci return reinterpret_cast<ZoneNodePtr*>(inputs_location()); 2461cb0ef41Sopenharmony_ci } 2471cb0ef41Sopenharmony_ci OutOfLineInputs* outline_inputs() const { 2481cb0ef41Sopenharmony_ci return *reinterpret_cast<ZoneOutOfLineInputsPtr*>(inputs_location()); 2491cb0ef41Sopenharmony_ci } 2501cb0ef41Sopenharmony_ci void set_outline_inputs(OutOfLineInputs* outline) { 2511cb0ef41Sopenharmony_ci *reinterpret_cast<ZoneOutOfLineInputsPtr*>(inputs_location()) = outline; 2521cb0ef41Sopenharmony_ci } 2531cb0ef41Sopenharmony_ci 2541cb0ef41Sopenharmony_ci ZoneNodePtr const* GetInputPtrConst(int input_index) const { 2551cb0ef41Sopenharmony_ci return has_inline_inputs() ? &(inline_inputs()[input_index]) 2561cb0ef41Sopenharmony_ci : &(outline_inputs()->inputs()[input_index]); 2571cb0ef41Sopenharmony_ci } 2581cb0ef41Sopenharmony_ci ZoneNodePtr* GetInputPtr(int input_index) { 2591cb0ef41Sopenharmony_ci return has_inline_inputs() ? &(inline_inputs()[input_index]) 2601cb0ef41Sopenharmony_ci : &(outline_inputs()->inputs()[input_index]); 2611cb0ef41Sopenharmony_ci } 2621cb0ef41Sopenharmony_ci Use* GetUsePtr(int input_index) { 2631cb0ef41Sopenharmony_ci Use* ptr = has_inline_inputs() ? reinterpret_cast<Use*>(this) 2641cb0ef41Sopenharmony_ci : reinterpret_cast<Use*>(outline_inputs()); 2651cb0ef41Sopenharmony_ci return &ptr[-1 - input_index]; 2661cb0ef41Sopenharmony_ci } 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ci void AppendUse(Use* use); 2691cb0ef41Sopenharmony_ci void RemoveUse(Use* use); 2701cb0ef41Sopenharmony_ci 2711cb0ef41Sopenharmony_ci void* operator new(size_t, void* location) { return location; } 2721cb0ef41Sopenharmony_ci 2731cb0ef41Sopenharmony_ci // Only NodeProperties should manipulate the op. 2741cb0ef41Sopenharmony_ci void set_op(const Operator* op) { op_ = op; } 2751cb0ef41Sopenharmony_ci 2761cb0ef41Sopenharmony_ci // Only NodeProperties should manipulate the type. 2771cb0ef41Sopenharmony_ci Type type() const { return type_; } 2781cb0ef41Sopenharmony_ci void set_type(Type type) { type_ = type; } 2791cb0ef41Sopenharmony_ci 2801cb0ef41Sopenharmony_ci // Only NodeMarkers should manipulate the marks on nodes. 2811cb0ef41Sopenharmony_ci Mark mark() const { return mark_; } 2821cb0ef41Sopenharmony_ci void set_mark(Mark mark) { mark_ = mark; } 2831cb0ef41Sopenharmony_ci 2841cb0ef41Sopenharmony_ci inline bool has_inline_inputs() const { 2851cb0ef41Sopenharmony_ci return InlineCountField::decode(bit_field_) != kOutlineMarker; 2861cb0ef41Sopenharmony_ci } 2871cb0ef41Sopenharmony_ci 2881cb0ef41Sopenharmony_ci void ClearInputs(int start, int count); 2891cb0ef41Sopenharmony_ci 2901cb0ef41Sopenharmony_ci using IdField = base::BitField<NodeId, 0, 24>; 2911cb0ef41Sopenharmony_ci using InlineCountField = base::BitField<unsigned, 24, 4>; 2921cb0ef41Sopenharmony_ci using InlineCapacityField = base::BitField<unsigned, 28, 4>; 2931cb0ef41Sopenharmony_ci static const int kOutlineMarker = InlineCountField::kMax; 2941cb0ef41Sopenharmony_ci static const int kMaxInlineCapacity = InlineCapacityField::kMax - 1; 2951cb0ef41Sopenharmony_ci 2961cb0ef41Sopenharmony_ci const Operator* op_; 2971cb0ef41Sopenharmony_ci Type type_; 2981cb0ef41Sopenharmony_ci Mark mark_; 2991cb0ef41Sopenharmony_ci uint32_t bit_field_; 3001cb0ef41Sopenharmony_ci ZoneUsePtr first_use_; 3011cb0ef41Sopenharmony_ci 3021cb0ef41Sopenharmony_ci friend class Edge; 3031cb0ef41Sopenharmony_ci friend class NodeMarkerBase; 3041cb0ef41Sopenharmony_ci friend class NodeProperties; 3051cb0ef41Sopenharmony_ci}; 3061cb0ef41Sopenharmony_ci 3071cb0ef41Sopenharmony_ciAddress Node::inputs_location() const { 3081cb0ef41Sopenharmony_ci return reinterpret_cast<Address>(this) + sizeof(Node); 3091cb0ef41Sopenharmony_ci} 3101cb0ef41Sopenharmony_ci 3111cb0ef41Sopenharmony_ciZoneNodePtr* Node::OutOfLineInputs::inputs() { 3121cb0ef41Sopenharmony_ci return reinterpret_cast<ZoneNodePtr*>(reinterpret_cast<Address>(this) + 3131cb0ef41Sopenharmony_ci sizeof(Node::OutOfLineInputs)); 3141cb0ef41Sopenharmony_ci} 3151cb0ef41Sopenharmony_ci 3161cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& os, const Node& n); 3171cb0ef41Sopenharmony_ci 3181cb0ef41Sopenharmony_ci// Base class for node wrappers. 3191cb0ef41Sopenharmony_ciclass NodeWrapper { 3201cb0ef41Sopenharmony_ci public: 3211cb0ef41Sopenharmony_ci explicit constexpr NodeWrapper(Node* node) : node_(node) {} 3221cb0ef41Sopenharmony_ci operator Node*() const { return node_; } 3231cb0ef41Sopenharmony_ci Node* operator->() const { return node_; } 3241cb0ef41Sopenharmony_ci 3251cb0ef41Sopenharmony_ci protected: 3261cb0ef41Sopenharmony_ci Node* node() const { return node_; } 3271cb0ef41Sopenharmony_ci void set_node(Node* node) { 3281cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(node); 3291cb0ef41Sopenharmony_ci node_ = node; 3301cb0ef41Sopenharmony_ci } 3311cb0ef41Sopenharmony_ci 3321cb0ef41Sopenharmony_ci private: 3331cb0ef41Sopenharmony_ci Node* node_; 3341cb0ef41Sopenharmony_ci}; 3351cb0ef41Sopenharmony_ci 3361cb0ef41Sopenharmony_ci// Wrapper classes for special node/edge types (effect, control, frame states). 3371cb0ef41Sopenharmony_ci 3381cb0ef41Sopenharmony_ciclass Effect : public NodeWrapper { 3391cb0ef41Sopenharmony_ci public: 3401cb0ef41Sopenharmony_ci explicit constexpr Effect(Node* node) : NodeWrapper(node) { 3411cb0ef41Sopenharmony_ci // TODO(jgruber): Remove the End special case. 3421cb0ef41Sopenharmony_ci SLOW_DCHECK(node == nullptr || node->op()->opcode() == IrOpcode::kEnd || 3431cb0ef41Sopenharmony_ci node->op()->EffectOutputCount() > 0); 3441cb0ef41Sopenharmony_ci } 3451cb0ef41Sopenharmony_ci 3461cb0ef41Sopenharmony_ci // Support the common `Node* x = effect = ...` pattern. 3471cb0ef41Sopenharmony_ci Node* operator=(Node* value) { 3481cb0ef41Sopenharmony_ci DCHECK_GT(value->op()->EffectOutputCount(), 0); 3491cb0ef41Sopenharmony_ci set_node(value); 3501cb0ef41Sopenharmony_ci return value; 3511cb0ef41Sopenharmony_ci } 3521cb0ef41Sopenharmony_ci}; 3531cb0ef41Sopenharmony_ci 3541cb0ef41Sopenharmony_ciclass Control : public NodeWrapper { 3551cb0ef41Sopenharmony_ci public: 3561cb0ef41Sopenharmony_ci explicit constexpr Control(Node* node) : NodeWrapper(node) { 3571cb0ef41Sopenharmony_ci // TODO(jgruber): Remove the End special case. 3581cb0ef41Sopenharmony_ci SLOW_DCHECK(node == nullptr || node->opcode() == IrOpcode::kEnd || 3591cb0ef41Sopenharmony_ci node->op()->ControlOutputCount() > 0); 3601cb0ef41Sopenharmony_ci } 3611cb0ef41Sopenharmony_ci 3621cb0ef41Sopenharmony_ci // Support the common `Node* x = control = ...` pattern. 3631cb0ef41Sopenharmony_ci Node* operator=(Node* value) { 3641cb0ef41Sopenharmony_ci DCHECK_GT(value->op()->ControlOutputCount(), 0); 3651cb0ef41Sopenharmony_ci set_node(value); 3661cb0ef41Sopenharmony_ci return value; 3671cb0ef41Sopenharmony_ci } 3681cb0ef41Sopenharmony_ci}; 3691cb0ef41Sopenharmony_ci 3701cb0ef41Sopenharmony_ci// Typedefs to shorten commonly used Node containers. 3711cb0ef41Sopenharmony_ciusing NodeDeque = ZoneDeque<Node*>; 3721cb0ef41Sopenharmony_ciusing NodeSet = ZoneSet<Node*>; 3731cb0ef41Sopenharmony_ciusing NodeVector = ZoneVector<Node*>; 3741cb0ef41Sopenharmony_ciusing NodeVectorVector = ZoneVector<NodeVector>; 3751cb0ef41Sopenharmony_ci 3761cb0ef41Sopenharmony_ciclass Node::InputEdges final { 3771cb0ef41Sopenharmony_ci public: 3781cb0ef41Sopenharmony_ci using value_type = Edge; 3791cb0ef41Sopenharmony_ci 3801cb0ef41Sopenharmony_ci class iterator; 3811cb0ef41Sopenharmony_ci inline iterator begin() const; 3821cb0ef41Sopenharmony_ci inline iterator end() const; 3831cb0ef41Sopenharmony_ci 3841cb0ef41Sopenharmony_ci bool empty() const { return count_ == 0; } 3851cb0ef41Sopenharmony_ci int count() const { return count_; } 3861cb0ef41Sopenharmony_ci 3871cb0ef41Sopenharmony_ci inline value_type operator[](int index) const; 3881cb0ef41Sopenharmony_ci 3891cb0ef41Sopenharmony_ci InputEdges(ZoneNodePtr* input_root, Use* use_root, int count) 3901cb0ef41Sopenharmony_ci : input_root_(input_root), use_root_(use_root), count_(count) {} 3911cb0ef41Sopenharmony_ci 3921cb0ef41Sopenharmony_ci private: 3931cb0ef41Sopenharmony_ci ZoneNodePtr* input_root_; 3941cb0ef41Sopenharmony_ci Use* use_root_; 3951cb0ef41Sopenharmony_ci int count_; 3961cb0ef41Sopenharmony_ci}; 3971cb0ef41Sopenharmony_ci 3981cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE Node::Inputs final { 3991cb0ef41Sopenharmony_ci public: 4001cb0ef41Sopenharmony_ci using value_type = Node*; 4011cb0ef41Sopenharmony_ci 4021cb0ef41Sopenharmony_ci class const_iterator; 4031cb0ef41Sopenharmony_ci inline const_iterator begin() const; 4041cb0ef41Sopenharmony_ci inline const_iterator end() const; 4051cb0ef41Sopenharmony_ci 4061cb0ef41Sopenharmony_ci bool empty() const { return count_ == 0; } 4071cb0ef41Sopenharmony_ci int count() const { return count_; } 4081cb0ef41Sopenharmony_ci 4091cb0ef41Sopenharmony_ci inline value_type operator[](int index) const; 4101cb0ef41Sopenharmony_ci 4111cb0ef41Sopenharmony_ci explicit Inputs(ZoneNodePtr const* input_root, int count) 4121cb0ef41Sopenharmony_ci : input_root_(input_root), count_(count) {} 4131cb0ef41Sopenharmony_ci 4141cb0ef41Sopenharmony_ci private: 4151cb0ef41Sopenharmony_ci ZoneNodePtr const* input_root_; 4161cb0ef41Sopenharmony_ci int count_; 4171cb0ef41Sopenharmony_ci}; 4181cb0ef41Sopenharmony_ci 4191cb0ef41Sopenharmony_ci// An encapsulation for information associated with a single use of node as a 4201cb0ef41Sopenharmony_ci// input from another node, allowing access to both the defining node and 4211cb0ef41Sopenharmony_ci// the node having the input. 4221cb0ef41Sopenharmony_ciclass Edge final { 4231cb0ef41Sopenharmony_ci public: 4241cb0ef41Sopenharmony_ci Node* from() const { return use_->from(); } 4251cb0ef41Sopenharmony_ci Node* to() const { return *input_ptr_; } 4261cb0ef41Sopenharmony_ci int index() const { 4271cb0ef41Sopenharmony_ci int const index = use_->input_index(); 4281cb0ef41Sopenharmony_ci DCHECK_LT(index, use_->from()->InputCount()); 4291cb0ef41Sopenharmony_ci return index; 4301cb0ef41Sopenharmony_ci } 4311cb0ef41Sopenharmony_ci 4321cb0ef41Sopenharmony_ci bool operator==(const Edge& other) { return input_ptr_ == other.input_ptr_; } 4331cb0ef41Sopenharmony_ci bool operator!=(const Edge& other) { return !(*this == other); } 4341cb0ef41Sopenharmony_ci 4351cb0ef41Sopenharmony_ci void UpdateTo(Node* new_to) { 4361cb0ef41Sopenharmony_ci Node* old_to = *input_ptr_; 4371cb0ef41Sopenharmony_ci if (old_to != new_to) { 4381cb0ef41Sopenharmony_ci if (old_to) old_to->RemoveUse(use_); 4391cb0ef41Sopenharmony_ci *input_ptr_ = new_to; 4401cb0ef41Sopenharmony_ci if (new_to) new_to->AppendUse(use_); 4411cb0ef41Sopenharmony_ci } 4421cb0ef41Sopenharmony_ci } 4431cb0ef41Sopenharmony_ci 4441cb0ef41Sopenharmony_ci private: 4451cb0ef41Sopenharmony_ci friend class Node::UseEdges::iterator; 4461cb0ef41Sopenharmony_ci friend class Node::InputEdges; 4471cb0ef41Sopenharmony_ci friend class Node::InputEdges::iterator; 4481cb0ef41Sopenharmony_ci 4491cb0ef41Sopenharmony_ci Edge(Node::Use* use, ZoneNodePtr* input_ptr) 4501cb0ef41Sopenharmony_ci : use_(use), input_ptr_(input_ptr) { 4511cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(use); 4521cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(input_ptr); 4531cb0ef41Sopenharmony_ci DCHECK_EQ(input_ptr, use->input_ptr()); 4541cb0ef41Sopenharmony_ci } 4551cb0ef41Sopenharmony_ci 4561cb0ef41Sopenharmony_ci Node::Use* use_; 4571cb0ef41Sopenharmony_ci ZoneNodePtr* input_ptr_; 4581cb0ef41Sopenharmony_ci}; 4591cb0ef41Sopenharmony_ci 4601cb0ef41Sopenharmony_cibool Node::IsDead() const { 4611cb0ef41Sopenharmony_ci Node::Inputs inputs = this->inputs(); 4621cb0ef41Sopenharmony_ci return inputs.count() > 0 && inputs[0] == nullptr; 4631cb0ef41Sopenharmony_ci} 4641cb0ef41Sopenharmony_ci 4651cb0ef41Sopenharmony_ciNode::InputEdges Node::input_edges() { 4661cb0ef41Sopenharmony_ci int inline_count = InlineCountField::decode(bit_field_); 4671cb0ef41Sopenharmony_ci if (inline_count != kOutlineMarker) { 4681cb0ef41Sopenharmony_ci return InputEdges(inline_inputs(), reinterpret_cast<Use*>(this) - 1, 4691cb0ef41Sopenharmony_ci inline_count); 4701cb0ef41Sopenharmony_ci } else { 4711cb0ef41Sopenharmony_ci return InputEdges(outline_inputs()->inputs(), 4721cb0ef41Sopenharmony_ci reinterpret_cast<Use*>(outline_inputs()) - 1, 4731cb0ef41Sopenharmony_ci outline_inputs()->count_); 4741cb0ef41Sopenharmony_ci } 4751cb0ef41Sopenharmony_ci} 4761cb0ef41Sopenharmony_ci 4771cb0ef41Sopenharmony_ciNode::Inputs Node::inputs() const { 4781cb0ef41Sopenharmony_ci int inline_count = InlineCountField::decode(bit_field_); 4791cb0ef41Sopenharmony_ci if (inline_count != kOutlineMarker) { 4801cb0ef41Sopenharmony_ci return Inputs(inline_inputs(), inline_count); 4811cb0ef41Sopenharmony_ci } else { 4821cb0ef41Sopenharmony_ci return Inputs(outline_inputs()->inputs(), outline_inputs()->count_); 4831cb0ef41Sopenharmony_ci } 4841cb0ef41Sopenharmony_ci} 4851cb0ef41Sopenharmony_ci 4861cb0ef41Sopenharmony_ci// A forward iterator to visit the edges for the input dependencies of a node. 4871cb0ef41Sopenharmony_ciclass Node::InputEdges::iterator final { 4881cb0ef41Sopenharmony_ci public: 4891cb0ef41Sopenharmony_ci using iterator_category = std::forward_iterator_tag; 4901cb0ef41Sopenharmony_ci using difference_type = std::ptrdiff_t; 4911cb0ef41Sopenharmony_ci using value_type = Edge; 4921cb0ef41Sopenharmony_ci using pointer = Edge*; 4931cb0ef41Sopenharmony_ci using reference = Edge&; 4941cb0ef41Sopenharmony_ci 4951cb0ef41Sopenharmony_ci iterator() : use_(nullptr), input_ptr_(nullptr) {} 4961cb0ef41Sopenharmony_ci iterator(const iterator& other) = default; 4971cb0ef41Sopenharmony_ci 4981cb0ef41Sopenharmony_ci Edge operator*() const { return Edge(use_, input_ptr_); } 4991cb0ef41Sopenharmony_ci bool operator==(const iterator& other) const { 5001cb0ef41Sopenharmony_ci return input_ptr_ == other.input_ptr_; 5011cb0ef41Sopenharmony_ci } 5021cb0ef41Sopenharmony_ci bool operator!=(const iterator& other) const { return !(*this == other); } 5031cb0ef41Sopenharmony_ci iterator& operator++() { 5041cb0ef41Sopenharmony_ci input_ptr_++; 5051cb0ef41Sopenharmony_ci use_--; 5061cb0ef41Sopenharmony_ci return *this; 5071cb0ef41Sopenharmony_ci } 5081cb0ef41Sopenharmony_ci iterator operator++(int); 5091cb0ef41Sopenharmony_ci iterator& operator+=(difference_type offset) { 5101cb0ef41Sopenharmony_ci input_ptr_ += offset; 5111cb0ef41Sopenharmony_ci use_ -= offset; 5121cb0ef41Sopenharmony_ci return *this; 5131cb0ef41Sopenharmony_ci } 5141cb0ef41Sopenharmony_ci iterator operator+(difference_type offset) const { 5151cb0ef41Sopenharmony_ci return iterator(use_ - offset, input_ptr_ + offset); 5161cb0ef41Sopenharmony_ci } 5171cb0ef41Sopenharmony_ci difference_type operator-(const iterator& other) const { 5181cb0ef41Sopenharmony_ci return input_ptr_ - other.input_ptr_; 5191cb0ef41Sopenharmony_ci } 5201cb0ef41Sopenharmony_ci 5211cb0ef41Sopenharmony_ci private: 5221cb0ef41Sopenharmony_ci friend class Node; 5231cb0ef41Sopenharmony_ci 5241cb0ef41Sopenharmony_ci explicit iterator(Use* use, ZoneNodePtr* input_ptr) 5251cb0ef41Sopenharmony_ci : use_(use), input_ptr_(input_ptr) {} 5261cb0ef41Sopenharmony_ci 5271cb0ef41Sopenharmony_ci Use* use_; 5281cb0ef41Sopenharmony_ci ZoneNodePtr* input_ptr_; 5291cb0ef41Sopenharmony_ci}; 5301cb0ef41Sopenharmony_ci 5311cb0ef41Sopenharmony_ci 5321cb0ef41Sopenharmony_ciNode::InputEdges::iterator Node::InputEdges::begin() const { 5331cb0ef41Sopenharmony_ci return Node::InputEdges::iterator(use_root_, input_root_); 5341cb0ef41Sopenharmony_ci} 5351cb0ef41Sopenharmony_ci 5361cb0ef41Sopenharmony_ci 5371cb0ef41Sopenharmony_ciNode::InputEdges::iterator Node::InputEdges::end() const { 5381cb0ef41Sopenharmony_ci return Node::InputEdges::iterator(use_root_ - count_, input_root_ + count_); 5391cb0ef41Sopenharmony_ci} 5401cb0ef41Sopenharmony_ci 5411cb0ef41Sopenharmony_ciEdge Node::InputEdges::operator[](int index) const { 5421cb0ef41Sopenharmony_ci return Edge(use_root_ + index, input_root_ + index); 5431cb0ef41Sopenharmony_ci} 5441cb0ef41Sopenharmony_ci 5451cb0ef41Sopenharmony_ci// A forward iterator to visit the inputs of a node. 5461cb0ef41Sopenharmony_ciclass Node::Inputs::const_iterator final { 5471cb0ef41Sopenharmony_ci public: 5481cb0ef41Sopenharmony_ci using iterator_category = std::forward_iterator_tag; 5491cb0ef41Sopenharmony_ci using difference_type = std::ptrdiff_t; 5501cb0ef41Sopenharmony_ci using value_type = Node*; 5511cb0ef41Sopenharmony_ci using pointer = const value_type*; 5521cb0ef41Sopenharmony_ci using reference = value_type&; 5531cb0ef41Sopenharmony_ci 5541cb0ef41Sopenharmony_ci const_iterator(const const_iterator& other) = default; 5551cb0ef41Sopenharmony_ci 5561cb0ef41Sopenharmony_ci Node* operator*() const { return *input_ptr_; } 5571cb0ef41Sopenharmony_ci bool operator==(const const_iterator& other) const { 5581cb0ef41Sopenharmony_ci return input_ptr_ == other.input_ptr_; 5591cb0ef41Sopenharmony_ci } 5601cb0ef41Sopenharmony_ci bool operator!=(const const_iterator& other) const { 5611cb0ef41Sopenharmony_ci return !(*this == other); 5621cb0ef41Sopenharmony_ci } 5631cb0ef41Sopenharmony_ci const_iterator& operator++() { 5641cb0ef41Sopenharmony_ci ++input_ptr_; 5651cb0ef41Sopenharmony_ci return *this; 5661cb0ef41Sopenharmony_ci } 5671cb0ef41Sopenharmony_ci const_iterator operator++(int); 5681cb0ef41Sopenharmony_ci const_iterator& operator+=(difference_type offset) { 5691cb0ef41Sopenharmony_ci input_ptr_ += offset; 5701cb0ef41Sopenharmony_ci return *this; 5711cb0ef41Sopenharmony_ci } 5721cb0ef41Sopenharmony_ci const_iterator operator+(difference_type offset) const { 5731cb0ef41Sopenharmony_ci return const_iterator(input_ptr_ + offset); 5741cb0ef41Sopenharmony_ci } 5751cb0ef41Sopenharmony_ci difference_type operator-(const const_iterator& other) const { 5761cb0ef41Sopenharmony_ci return input_ptr_ - other.input_ptr_; 5771cb0ef41Sopenharmony_ci } 5781cb0ef41Sopenharmony_ci 5791cb0ef41Sopenharmony_ci private: 5801cb0ef41Sopenharmony_ci friend class Node::Inputs; 5811cb0ef41Sopenharmony_ci 5821cb0ef41Sopenharmony_ci explicit const_iterator(ZoneNodePtr const* input_ptr) 5831cb0ef41Sopenharmony_ci : input_ptr_(input_ptr) {} 5841cb0ef41Sopenharmony_ci 5851cb0ef41Sopenharmony_ci ZoneNodePtr const* input_ptr_; 5861cb0ef41Sopenharmony_ci}; 5871cb0ef41Sopenharmony_ci 5881cb0ef41Sopenharmony_ci 5891cb0ef41Sopenharmony_ciNode::Inputs::const_iterator Node::Inputs::begin() const { 5901cb0ef41Sopenharmony_ci return const_iterator(input_root_); 5911cb0ef41Sopenharmony_ci} 5921cb0ef41Sopenharmony_ci 5931cb0ef41Sopenharmony_ci 5941cb0ef41Sopenharmony_ciNode::Inputs::const_iterator Node::Inputs::end() const { 5951cb0ef41Sopenharmony_ci return const_iterator(input_root_ + count_); 5961cb0ef41Sopenharmony_ci} 5971cb0ef41Sopenharmony_ci 5981cb0ef41Sopenharmony_ciNode* Node::Inputs::operator[](int index) const { return input_root_[index]; } 5991cb0ef41Sopenharmony_ci 6001cb0ef41Sopenharmony_ci// A forward iterator to visit the uses edges of a node. 6011cb0ef41Sopenharmony_ciclass Node::UseEdges::iterator final { 6021cb0ef41Sopenharmony_ci public: 6031cb0ef41Sopenharmony_ci iterator(const iterator& other) = default; 6041cb0ef41Sopenharmony_ci 6051cb0ef41Sopenharmony_ci Edge operator*() const { return Edge(current_, current_->input_ptr()); } 6061cb0ef41Sopenharmony_ci bool operator==(const iterator& other) const { 6071cb0ef41Sopenharmony_ci return current_ == other.current_; 6081cb0ef41Sopenharmony_ci } 6091cb0ef41Sopenharmony_ci bool operator!=(const iterator& other) const { return !(*this == other); } 6101cb0ef41Sopenharmony_ci iterator& operator++() { 6111cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(current_); 6121cb0ef41Sopenharmony_ci current_ = next_; 6131cb0ef41Sopenharmony_ci next_ = current_ ? static_cast<Node::Use*>(current_->next) : nullptr; 6141cb0ef41Sopenharmony_ci return *this; 6151cb0ef41Sopenharmony_ci } 6161cb0ef41Sopenharmony_ci iterator operator++(int); 6171cb0ef41Sopenharmony_ci 6181cb0ef41Sopenharmony_ci private: 6191cb0ef41Sopenharmony_ci friend class Node::UseEdges; 6201cb0ef41Sopenharmony_ci 6211cb0ef41Sopenharmony_ci iterator() : current_(nullptr), next_(nullptr) {} 6221cb0ef41Sopenharmony_ci explicit iterator(Node* node) 6231cb0ef41Sopenharmony_ci : current_(node->first_use_), 6241cb0ef41Sopenharmony_ci next_(current_ ? static_cast<Node::Use*>(current_->next) : nullptr) {} 6251cb0ef41Sopenharmony_ci 6261cb0ef41Sopenharmony_ci Node::Use* current_; 6271cb0ef41Sopenharmony_ci Node::Use* next_; 6281cb0ef41Sopenharmony_ci}; 6291cb0ef41Sopenharmony_ci 6301cb0ef41Sopenharmony_ci 6311cb0ef41Sopenharmony_ciNode::UseEdges::iterator Node::UseEdges::begin() const { 6321cb0ef41Sopenharmony_ci return Node::UseEdges::iterator(this->node_); 6331cb0ef41Sopenharmony_ci} 6341cb0ef41Sopenharmony_ci 6351cb0ef41Sopenharmony_ci 6361cb0ef41Sopenharmony_ciNode::UseEdges::iterator Node::UseEdges::end() const { 6371cb0ef41Sopenharmony_ci return Node::UseEdges::iterator(); 6381cb0ef41Sopenharmony_ci} 6391cb0ef41Sopenharmony_ci 6401cb0ef41Sopenharmony_ci 6411cb0ef41Sopenharmony_ci// A forward iterator to visit the uses of a node. 6421cb0ef41Sopenharmony_ciclass Node::Uses::const_iterator final { 6431cb0ef41Sopenharmony_ci public: 6441cb0ef41Sopenharmony_ci using iterator_category = std::forward_iterator_tag; 6451cb0ef41Sopenharmony_ci using difference_type = int; 6461cb0ef41Sopenharmony_ci using value_type = Node*; 6471cb0ef41Sopenharmony_ci using pointer = Node**; 6481cb0ef41Sopenharmony_ci using reference = Node*&; 6491cb0ef41Sopenharmony_ci 6501cb0ef41Sopenharmony_ci Node* operator*() const { return current_->from(); } 6511cb0ef41Sopenharmony_ci bool operator==(const const_iterator& other) const { 6521cb0ef41Sopenharmony_ci return other.current_ == current_; 6531cb0ef41Sopenharmony_ci } 6541cb0ef41Sopenharmony_ci bool operator!=(const const_iterator& other) const { 6551cb0ef41Sopenharmony_ci return other.current_ != current_; 6561cb0ef41Sopenharmony_ci } 6571cb0ef41Sopenharmony_ci const_iterator& operator++() { 6581cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(current_); 6591cb0ef41Sopenharmony_ci // Checking no use gets mutated while iterating through them, a potential 6601cb0ef41Sopenharmony_ci // very tricky cause of bug. 6611cb0ef41Sopenharmony_ci current_ = current_->next; 6621cb0ef41Sopenharmony_ci#ifdef DEBUG 6631cb0ef41Sopenharmony_ci DCHECK_EQ(current_, next_); 6641cb0ef41Sopenharmony_ci next_ = current_ ? current_->next : nullptr; 6651cb0ef41Sopenharmony_ci#endif 6661cb0ef41Sopenharmony_ci return *this; 6671cb0ef41Sopenharmony_ci } 6681cb0ef41Sopenharmony_ci const_iterator operator++(int); 6691cb0ef41Sopenharmony_ci 6701cb0ef41Sopenharmony_ci private: 6711cb0ef41Sopenharmony_ci friend class Node::Uses; 6721cb0ef41Sopenharmony_ci 6731cb0ef41Sopenharmony_ci const_iterator() : current_(nullptr) {} 6741cb0ef41Sopenharmony_ci explicit const_iterator(Node* node) 6751cb0ef41Sopenharmony_ci : current_(node->first_use_) 6761cb0ef41Sopenharmony_ci#ifdef DEBUG 6771cb0ef41Sopenharmony_ci , 6781cb0ef41Sopenharmony_ci next_(current_ ? current_->next : nullptr) 6791cb0ef41Sopenharmony_ci#endif 6801cb0ef41Sopenharmony_ci { 6811cb0ef41Sopenharmony_ci } 6821cb0ef41Sopenharmony_ci 6831cb0ef41Sopenharmony_ci Node::Use* current_; 6841cb0ef41Sopenharmony_ci#ifdef DEBUG 6851cb0ef41Sopenharmony_ci Node::Use* next_; 6861cb0ef41Sopenharmony_ci#endif 6871cb0ef41Sopenharmony_ci}; 6881cb0ef41Sopenharmony_ci 6891cb0ef41Sopenharmony_ci 6901cb0ef41Sopenharmony_ciNode::Uses::const_iterator Node::Uses::begin() const { 6911cb0ef41Sopenharmony_ci return const_iterator(this->node_); 6921cb0ef41Sopenharmony_ci} 6931cb0ef41Sopenharmony_ci 6941cb0ef41Sopenharmony_ci 6951cb0ef41Sopenharmony_ciNode::Uses::const_iterator Node::Uses::end() const { return const_iterator(); } 6961cb0ef41Sopenharmony_ci 6971cb0ef41Sopenharmony_ci} // namespace compiler 6981cb0ef41Sopenharmony_ci} // namespace internal 6991cb0ef41Sopenharmony_ci} // namespace v8 7001cb0ef41Sopenharmony_ci 7011cb0ef41Sopenharmony_ci#endif // V8_COMPILER_NODE_H_ 702