11cb0ef41Sopenharmony_ci// Copyright 2016 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_GRAPH_ASSEMBLER_H_
61cb0ef41Sopenharmony_ci#define V8_COMPILER_GRAPH_ASSEMBLER_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/codegen/tnode.h"
91cb0ef41Sopenharmony_ci#include "src/compiler/feedback-source.h"
101cb0ef41Sopenharmony_ci#include "src/compiler/js-graph.h"
111cb0ef41Sopenharmony_ci#include "src/compiler/node.h"
121cb0ef41Sopenharmony_ci#include "src/compiler/simplified-operator.h"
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_cinamespace v8 {
151cb0ef41Sopenharmony_cinamespace internal {
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ciclass JSGraph;
181cb0ef41Sopenharmony_ciclass Graph;
191cb0ef41Sopenharmony_ciclass Oddball;
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci// TODO(jgruber): Currently this is too permissive, but at least it lets us
221cb0ef41Sopenharmony_ci// document which functions expect JS booleans. If a real Boolean type becomes
231cb0ef41Sopenharmony_ci// possible in the future, use that instead.
241cb0ef41Sopenharmony_ciusing Boolean = Oddball;
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_cinamespace compiler {
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ciclass Reducer;
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci#define PURE_ASSEMBLER_MACH_UNOP_LIST(V) \
311cb0ef41Sopenharmony_ci  V(BitcastFloat32ToInt32)               \
321cb0ef41Sopenharmony_ci  V(BitcastFloat64ToInt64)               \
331cb0ef41Sopenharmony_ci  V(BitcastInt32ToFloat32)               \
341cb0ef41Sopenharmony_ci  V(BitcastWord32ToWord64)               \
351cb0ef41Sopenharmony_ci  V(BitcastInt64ToFloat64)               \
361cb0ef41Sopenharmony_ci  V(ChangeFloat32ToFloat64)              \
371cb0ef41Sopenharmony_ci  V(ChangeFloat64ToInt32)                \
381cb0ef41Sopenharmony_ci  V(ChangeFloat64ToInt64)                \
391cb0ef41Sopenharmony_ci  V(ChangeFloat64ToUint32)               \
401cb0ef41Sopenharmony_ci  V(ChangeInt32ToFloat64)                \
411cb0ef41Sopenharmony_ci  V(ChangeInt32ToInt64)                  \
421cb0ef41Sopenharmony_ci  V(ChangeInt64ToFloat64)                \
431cb0ef41Sopenharmony_ci  V(ChangeUint32ToFloat64)               \
441cb0ef41Sopenharmony_ci  V(ChangeUint32ToUint64)                \
451cb0ef41Sopenharmony_ci  V(Float64Abs)                          \
461cb0ef41Sopenharmony_ci  V(Float64ExtractHighWord32)            \
471cb0ef41Sopenharmony_ci  V(Float64ExtractLowWord32)             \
481cb0ef41Sopenharmony_ci  V(Float64SilenceNaN)                   \
491cb0ef41Sopenharmony_ci  V(RoundFloat64ToInt32)                 \
501cb0ef41Sopenharmony_ci  V(RoundInt32ToFloat32)                 \
511cb0ef41Sopenharmony_ci  V(TruncateFloat64ToFloat32)            \
521cb0ef41Sopenharmony_ci  V(TruncateFloat64ToWord32)             \
531cb0ef41Sopenharmony_ci  V(TruncateInt64ToInt32)                \
541cb0ef41Sopenharmony_ci  V(Word32ReverseBytes)                  \
551cb0ef41Sopenharmony_ci  V(Word64ReverseBytes)
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci#define PURE_ASSEMBLER_MACH_BINOP_LIST(V) \
581cb0ef41Sopenharmony_ci  V(Float64Add)                           \
591cb0ef41Sopenharmony_ci  V(Float64Div)                           \
601cb0ef41Sopenharmony_ci  V(Float64Equal)                         \
611cb0ef41Sopenharmony_ci  V(Float64InsertHighWord32)              \
621cb0ef41Sopenharmony_ci  V(Float64InsertLowWord32)               \
631cb0ef41Sopenharmony_ci  V(Float64LessThan)                      \
641cb0ef41Sopenharmony_ci  V(Float64LessThanOrEqual)               \
651cb0ef41Sopenharmony_ci  V(Float64Mod)                           \
661cb0ef41Sopenharmony_ci  V(Float64Sub)                           \
671cb0ef41Sopenharmony_ci  V(Int32Add)                             \
681cb0ef41Sopenharmony_ci  V(Int32LessThan)                        \
691cb0ef41Sopenharmony_ci  V(Int32LessThanOrEqual)                 \
701cb0ef41Sopenharmony_ci  V(Int32Mul)                             \
711cb0ef41Sopenharmony_ci  V(Int32Sub)                             \
721cb0ef41Sopenharmony_ci  V(Int64Sub)                             \
731cb0ef41Sopenharmony_ci  V(IntAdd)                               \
741cb0ef41Sopenharmony_ci  V(IntLessThan)                          \
751cb0ef41Sopenharmony_ci  V(IntMul)                               \
761cb0ef41Sopenharmony_ci  V(IntSub)                               \
771cb0ef41Sopenharmony_ci  V(Uint32LessThan)                       \
781cb0ef41Sopenharmony_ci  V(Uint32LessThanOrEqual)                \
791cb0ef41Sopenharmony_ci  V(Uint64LessThan)                       \
801cb0ef41Sopenharmony_ci  V(Uint64LessThanOrEqual)                \
811cb0ef41Sopenharmony_ci  V(UintLessThan)                         \
821cb0ef41Sopenharmony_ci  V(Word32And)                            \
831cb0ef41Sopenharmony_ci  V(Word32Equal)                          \
841cb0ef41Sopenharmony_ci  V(Word32Or)                             \
851cb0ef41Sopenharmony_ci  V(Word32Sar)                            \
861cb0ef41Sopenharmony_ci  V(Word32SarShiftOutZeros)               \
871cb0ef41Sopenharmony_ci  V(Word32Shl)                            \
881cb0ef41Sopenharmony_ci  V(Word32Shr)                            \
891cb0ef41Sopenharmony_ci  V(Word32Xor)                            \
901cb0ef41Sopenharmony_ci  V(Word64And)                            \
911cb0ef41Sopenharmony_ci  V(Word64Equal)                          \
921cb0ef41Sopenharmony_ci  V(Word64Or)                             \
931cb0ef41Sopenharmony_ci  V(Word64Sar)                            \
941cb0ef41Sopenharmony_ci  V(Word64SarShiftOutZeros)               \
951cb0ef41Sopenharmony_ci  V(Word64Shl)                            \
961cb0ef41Sopenharmony_ci  V(Word64Shr)                            \
971cb0ef41Sopenharmony_ci  V(Word64Xor)                            \
981cb0ef41Sopenharmony_ci  V(WordAnd)                              \
991cb0ef41Sopenharmony_ci  V(WordEqual)                            \
1001cb0ef41Sopenharmony_ci  V(WordOr)                               \
1011cb0ef41Sopenharmony_ci  V(WordSar)                              \
1021cb0ef41Sopenharmony_ci  V(WordSarShiftOutZeros)                 \
1031cb0ef41Sopenharmony_ci  V(WordShl)                              \
1041cb0ef41Sopenharmony_ci  V(WordShr)                              \
1051cb0ef41Sopenharmony_ci  V(WordXor)
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci#define CHECKED_ASSEMBLER_MACH_BINOP_LIST(V) \
1081cb0ef41Sopenharmony_ci  V(Int32AddWithOverflow)                    \
1091cb0ef41Sopenharmony_ci  V(Int32Div)                                \
1101cb0ef41Sopenharmony_ci  V(Int32Mod)                                \
1111cb0ef41Sopenharmony_ci  V(Int32MulWithOverflow)                    \
1121cb0ef41Sopenharmony_ci  V(Int32SubWithOverflow)                    \
1131cb0ef41Sopenharmony_ci  V(Int64Div)                                \
1141cb0ef41Sopenharmony_ci  V(Int64Mod)                                \
1151cb0ef41Sopenharmony_ci  V(Uint32Div)                               \
1161cb0ef41Sopenharmony_ci  V(Uint32Mod)                               \
1171cb0ef41Sopenharmony_ci  V(Uint64Div)                               \
1181cb0ef41Sopenharmony_ci  V(Uint64Mod)
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci#define JSGRAPH_SINGLETON_CONSTANT_LIST(V)      \
1211cb0ef41Sopenharmony_ci  V(AllocateInOldGenerationStub, Code)          \
1221cb0ef41Sopenharmony_ci  V(AllocateInYoungGenerationStub, Code)        \
1231cb0ef41Sopenharmony_ci  V(AllocateRegularInOldGenerationStub, Code)   \
1241cb0ef41Sopenharmony_ci  V(AllocateRegularInYoungGenerationStub, Code) \
1251cb0ef41Sopenharmony_ci  V(BigIntMap, Map)                             \
1261cb0ef41Sopenharmony_ci  V(BooleanMap, Map)                            \
1271cb0ef41Sopenharmony_ci  V(EmptyString, String)                        \
1281cb0ef41Sopenharmony_ci  V(False, Boolean)                             \
1291cb0ef41Sopenharmony_ci  V(FixedArrayMap, Map)                         \
1301cb0ef41Sopenharmony_ci  V(FixedDoubleArrayMap, Map)                   \
1311cb0ef41Sopenharmony_ci  V(WeakFixedArrayMap, Map)                     \
1321cb0ef41Sopenharmony_ci  V(HeapNumberMap, Map)                         \
1331cb0ef41Sopenharmony_ci  V(MinusOne, Number)                           \
1341cb0ef41Sopenharmony_ci  V(NaN, Number)                                \
1351cb0ef41Sopenharmony_ci  V(NoContext, Object)                          \
1361cb0ef41Sopenharmony_ci  V(Null, Oddball)                              \
1371cb0ef41Sopenharmony_ci  V(One, Number)                                \
1381cb0ef41Sopenharmony_ci  V(TheHole, Oddball)                           \
1391cb0ef41Sopenharmony_ci  V(ToNumberBuiltin, Code)                      \
1401cb0ef41Sopenharmony_ci  V(PlainPrimitiveToNumberBuiltin, Code)        \
1411cb0ef41Sopenharmony_ci  V(True, Boolean)                              \
1421cb0ef41Sopenharmony_ci  V(Undefined, Oddball)                         \
1431cb0ef41Sopenharmony_ci  V(Zero, Number)
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ciclass GraphAssembler;
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_cienum class GraphAssemblerLabelType { kDeferred, kNonDeferred, kLoop };
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci// Label with statically known count of incoming branches and phis.
1501cb0ef41Sopenharmony_citemplate <size_t VarCount>
1511cb0ef41Sopenharmony_ciclass GraphAssemblerLabel {
1521cb0ef41Sopenharmony_ci public:
1531cb0ef41Sopenharmony_ci  Node* PhiAt(size_t index);
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ci  template <typename T>
1561cb0ef41Sopenharmony_ci  TNode<T> PhiAt(size_t index) {
1571cb0ef41Sopenharmony_ci    // TODO(jgruber): Investigate issues on ptr compression bots and enable.
1581cb0ef41Sopenharmony_ci    // DCHECK(IsMachineRepresentationOf<T>(representations_[index]));
1591cb0ef41Sopenharmony_ci    return TNode<T>::UncheckedCast(PhiAt(index));
1601cb0ef41Sopenharmony_ci  }
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci  GraphAssemblerLabel(GraphAssemblerLabelType type, int loop_nesting_level,
1631cb0ef41Sopenharmony_ci                      const std::array<MachineRepresentation, VarCount>& reps)
1641cb0ef41Sopenharmony_ci      : type_(type),
1651cb0ef41Sopenharmony_ci        loop_nesting_level_(loop_nesting_level),
1661cb0ef41Sopenharmony_ci        representations_(reps) {}
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci  ~GraphAssemblerLabel() { DCHECK(IsBound() || merged_count_ == 0); }
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci private:
1711cb0ef41Sopenharmony_ci  friend class GraphAssembler;
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_ci  void SetBound() {
1741cb0ef41Sopenharmony_ci    DCHECK(!IsBound());
1751cb0ef41Sopenharmony_ci    is_bound_ = true;
1761cb0ef41Sopenharmony_ci  }
1771cb0ef41Sopenharmony_ci  bool IsBound() const { return is_bound_; }
1781cb0ef41Sopenharmony_ci  bool IsDeferred() const {
1791cb0ef41Sopenharmony_ci    return type_ == GraphAssemblerLabelType::kDeferred;
1801cb0ef41Sopenharmony_ci  }
1811cb0ef41Sopenharmony_ci  bool IsLoop() const { return type_ == GraphAssemblerLabelType::kLoop; }
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_ci  bool is_bound_ = false;
1841cb0ef41Sopenharmony_ci  const GraphAssemblerLabelType type_;
1851cb0ef41Sopenharmony_ci  const int loop_nesting_level_;
1861cb0ef41Sopenharmony_ci  size_t merged_count_ = 0;
1871cb0ef41Sopenharmony_ci  Node* effect_;
1881cb0ef41Sopenharmony_ci  Node* control_;
1891cb0ef41Sopenharmony_ci  std::array<Node*, VarCount> bindings_;
1901cb0ef41Sopenharmony_ci  const std::array<MachineRepresentation, VarCount> representations_;
1911cb0ef41Sopenharmony_ci};
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_ciusing NodeChangedCallback = std::function<void(Node*)>;
1941cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE GraphAssembler {
1951cb0ef41Sopenharmony_ci public:
1961cb0ef41Sopenharmony_ci  // Constructs a GraphAssembler. If {schedule} is not null, the graph assembler
1971cb0ef41Sopenharmony_ci  // will maintain the schedule as it updates blocks.
1981cb0ef41Sopenharmony_ci  GraphAssembler(
1991cb0ef41Sopenharmony_ci      MachineGraph* jsgraph, Zone* zone,
2001cb0ef41Sopenharmony_ci      base::Optional<NodeChangedCallback> node_changed_callback = base::nullopt,
2011cb0ef41Sopenharmony_ci      bool mark_loop_exits = false);
2021cb0ef41Sopenharmony_ci  virtual ~GraphAssembler();
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_ci  void Reset();
2051cb0ef41Sopenharmony_ci  void InitializeEffectControl(Node* effect, Node* control);
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_ci  // Create label.
2081cb0ef41Sopenharmony_ci  template <typename... Reps>
2091cb0ef41Sopenharmony_ci  GraphAssemblerLabel<sizeof...(Reps)> MakeLabelFor(
2101cb0ef41Sopenharmony_ci      GraphAssemblerLabelType type, Reps... reps) {
2111cb0ef41Sopenharmony_ci    std::array<MachineRepresentation, sizeof...(Reps)> reps_array = {reps...};
2121cb0ef41Sopenharmony_ci    return MakeLabel<sizeof...(Reps)>(reps_array, type);
2131cb0ef41Sopenharmony_ci  }
2141cb0ef41Sopenharmony_ci
2151cb0ef41Sopenharmony_ci  // As above, but with an std::array of machine representations.
2161cb0ef41Sopenharmony_ci  template <int VarCount>
2171cb0ef41Sopenharmony_ci  GraphAssemblerLabel<VarCount> MakeLabel(
2181cb0ef41Sopenharmony_ci      std::array<MachineRepresentation, VarCount> reps_array,
2191cb0ef41Sopenharmony_ci      GraphAssemblerLabelType type) {
2201cb0ef41Sopenharmony_ci    return GraphAssemblerLabel<VarCount>(type, loop_nesting_level_, reps_array);
2211cb0ef41Sopenharmony_ci  }
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_ci  // Convenience wrapper for creating non-deferred labels.
2241cb0ef41Sopenharmony_ci  template <typename... Reps>
2251cb0ef41Sopenharmony_ci  GraphAssemblerLabel<sizeof...(Reps)> MakeLabel(Reps... reps) {
2261cb0ef41Sopenharmony_ci    return MakeLabelFor(GraphAssemblerLabelType::kNonDeferred, reps...);
2271cb0ef41Sopenharmony_ci  }
2281cb0ef41Sopenharmony_ci
2291cb0ef41Sopenharmony_ci  // Convenience wrapper for creating loop labels.
2301cb0ef41Sopenharmony_ci  template <typename... Reps>
2311cb0ef41Sopenharmony_ci  GraphAssemblerLabel<sizeof...(Reps)> MakeLoopLabel(Reps... reps) {
2321cb0ef41Sopenharmony_ci    return MakeLabelFor(GraphAssemblerLabelType::kLoop, reps...);
2331cb0ef41Sopenharmony_ci  }
2341cb0ef41Sopenharmony_ci
2351cb0ef41Sopenharmony_ci  // Convenience wrapper for creating deferred labels.
2361cb0ef41Sopenharmony_ci  template <typename... Reps>
2371cb0ef41Sopenharmony_ci  GraphAssemblerLabel<sizeof...(Reps)> MakeDeferredLabel(Reps... reps) {
2381cb0ef41Sopenharmony_ci    return MakeLabelFor(GraphAssemblerLabelType::kDeferred, reps...);
2391cb0ef41Sopenharmony_ci  }
2401cb0ef41Sopenharmony_ci
2411cb0ef41Sopenharmony_ci  // Value creation.
2421cb0ef41Sopenharmony_ci  Node* IntPtrConstant(intptr_t value);
2431cb0ef41Sopenharmony_ci  Node* UintPtrConstant(uintptr_t value);
2441cb0ef41Sopenharmony_ci  Node* Int32Constant(int32_t value);
2451cb0ef41Sopenharmony_ci  Node* Uint32Constant(uint32_t value);
2461cb0ef41Sopenharmony_ci  Node* Int64Constant(int64_t value);
2471cb0ef41Sopenharmony_ci  Node* Uint64Constant(uint64_t value);
2481cb0ef41Sopenharmony_ci  Node* UniqueIntPtrConstant(intptr_t value);
2491cb0ef41Sopenharmony_ci  Node* Float64Constant(double value);
2501cb0ef41Sopenharmony_ci  Node* Projection(int index, Node* value);
2511cb0ef41Sopenharmony_ci  Node* ExternalConstant(ExternalReference ref);
2521cb0ef41Sopenharmony_ci
2531cb0ef41Sopenharmony_ci  Node* Parameter(int index);
2541cb0ef41Sopenharmony_ci
2551cb0ef41Sopenharmony_ci  Node* LoadFramePointer();
2561cb0ef41Sopenharmony_ci
2571cb0ef41Sopenharmony_ci  Node* LoadHeapNumberValue(Node* heap_number);
2581cb0ef41Sopenharmony_ci
2591cb0ef41Sopenharmony_ci#define PURE_UNOP_DECL(Name) Node* Name(Node* input);
2601cb0ef41Sopenharmony_ci  PURE_ASSEMBLER_MACH_UNOP_LIST(PURE_UNOP_DECL)
2611cb0ef41Sopenharmony_ci#undef PURE_UNOP_DECL
2621cb0ef41Sopenharmony_ci
2631cb0ef41Sopenharmony_ci#define BINOP_DECL(Name) Node* Name(Node* left, Node* right);
2641cb0ef41Sopenharmony_ci  PURE_ASSEMBLER_MACH_BINOP_LIST(BINOP_DECL)
2651cb0ef41Sopenharmony_ci  CHECKED_ASSEMBLER_MACH_BINOP_LIST(BINOP_DECL)
2661cb0ef41Sopenharmony_ci#undef BINOP_DECL
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci#ifdef V8_MAP_PACKING
2691cb0ef41Sopenharmony_ci  Node* PackMapWord(TNode<Map> map);
2701cb0ef41Sopenharmony_ci  TNode<Map> UnpackMapWord(Node* map_word);
2711cb0ef41Sopenharmony_ci#endif
2721cb0ef41Sopenharmony_ci  TNode<Map> LoadMap(Node* object);
2731cb0ef41Sopenharmony_ci
2741cb0ef41Sopenharmony_ci  Node* DebugBreak();
2751cb0ef41Sopenharmony_ci
2761cb0ef41Sopenharmony_ci  // Unreachable nodes are similar to Goto in that they reset effect/control to
2771cb0ef41Sopenharmony_ci  // nullptr and it's thus not possible to append other nodes without first
2781cb0ef41Sopenharmony_ci  // binding a new label.
2791cb0ef41Sopenharmony_ci  // The block_updater_successor label is a crutch to work around block updater
2801cb0ef41Sopenharmony_ci  // weaknesses (see the related comment in ConnectUnreachableToEnd); if the
2811cb0ef41Sopenharmony_ci  // block updater exists, we cannot connect unreachable to end, instead we
2821cb0ef41Sopenharmony_ci  // must preserve the Goto pattern.
2831cb0ef41Sopenharmony_ci  Node* Unreachable(GraphAssemblerLabel<0u>* block_updater_successor = nullptr);
2841cb0ef41Sopenharmony_ci  // This special variant doesn't connect the Unreachable node to end, and does
2851cb0ef41Sopenharmony_ci  // not reset current effect/control. Intended only for special use-cases like
2861cb0ef41Sopenharmony_ci  // lowering DeadValue.
2871cb0ef41Sopenharmony_ci  Node* UnreachableWithoutConnectToEnd();
2881cb0ef41Sopenharmony_ci
2891cb0ef41Sopenharmony_ci  Node* IntPtrEqual(Node* left, Node* right);
2901cb0ef41Sopenharmony_ci  Node* TaggedEqual(Node* left, Node* right);
2911cb0ef41Sopenharmony_ci
2921cb0ef41Sopenharmony_ci  Node* SmiSub(Node* left, Node* right);
2931cb0ef41Sopenharmony_ci  Node* SmiLessThan(Node* left, Node* right);
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ci  Node* Float64RoundDown(Node* value);
2961cb0ef41Sopenharmony_ci  Node* Float64RoundTruncate(Node* value);
2971cb0ef41Sopenharmony_ci  Node* TruncateFloat64ToInt64(Node* value, TruncateKind kind);
2981cb0ef41Sopenharmony_ci
2991cb0ef41Sopenharmony_ci  Node* BitcastWordToTagged(Node* value);
3001cb0ef41Sopenharmony_ci  Node* BitcastWordToTaggedSigned(Node* value);
3011cb0ef41Sopenharmony_ci  Node* BitcastTaggedToWord(Node* value);
3021cb0ef41Sopenharmony_ci  Node* BitcastTaggedToWordForTagAndSmiBits(Node* value);
3031cb0ef41Sopenharmony_ci  Node* BitcastMaybeObjectToWord(Node* value);
3041cb0ef41Sopenharmony_ci
3051cb0ef41Sopenharmony_ci  Node* TypeGuard(Type type, Node* value);
3061cb0ef41Sopenharmony_ci  Node* Checkpoint(FrameState frame_state);
3071cb0ef41Sopenharmony_ci
3081cb0ef41Sopenharmony_ci  TNode<RawPtrT> StackSlot(int size, int alignment);
3091cb0ef41Sopenharmony_ci
3101cb0ef41Sopenharmony_ci  Node* Store(StoreRepresentation rep, Node* object, Node* offset, Node* value);
3111cb0ef41Sopenharmony_ci  Node* Store(StoreRepresentation rep, Node* object, int offset, Node* value);
3121cb0ef41Sopenharmony_ci  Node* Load(MachineType type, Node* object, Node* offset);
3131cb0ef41Sopenharmony_ci  Node* Load(MachineType type, Node* object, int offset);
3141cb0ef41Sopenharmony_ci
3151cb0ef41Sopenharmony_ci  Node* StoreUnaligned(MachineRepresentation rep, Node* object, Node* offset,
3161cb0ef41Sopenharmony_ci                       Node* value);
3171cb0ef41Sopenharmony_ci  Node* LoadUnaligned(MachineType type, Node* object, Node* offset);
3181cb0ef41Sopenharmony_ci
3191cb0ef41Sopenharmony_ci  Node* ProtectedStore(MachineRepresentation rep, Node* object, Node* offset,
3201cb0ef41Sopenharmony_ci                       Node* value);
3211cb0ef41Sopenharmony_ci  Node* ProtectedLoad(MachineType type, Node* object, Node* offset);
3221cb0ef41Sopenharmony_ci
3231cb0ef41Sopenharmony_ci  Node* Retain(Node* buffer);
3241cb0ef41Sopenharmony_ci  Node* UnsafePointerAdd(Node* base, Node* external);
3251cb0ef41Sopenharmony_ci
3261cb0ef41Sopenharmony_ci  Node* DeoptimizeIf(DeoptimizeReason reason, FeedbackSource const& feedback,
3271cb0ef41Sopenharmony_ci                     Node* condition, Node* frame_state);
3281cb0ef41Sopenharmony_ci  Node* DeoptimizeIfNot(DeoptimizeReason reason, FeedbackSource const& feedback,
3291cb0ef41Sopenharmony_ci                        Node* condition, Node* frame_state);
3301cb0ef41Sopenharmony_ci  TNode<Object> Call(const CallDescriptor* call_descriptor, int inputs_size,
3311cb0ef41Sopenharmony_ci                     Node** inputs);
3321cb0ef41Sopenharmony_ci  TNode<Object> Call(const Operator* op, int inputs_size, Node** inputs);
3331cb0ef41Sopenharmony_ci  template <typename... Args>
3341cb0ef41Sopenharmony_ci  TNode<Object> Call(const CallDescriptor* call_descriptor, Node* first_arg,
3351cb0ef41Sopenharmony_ci                     Args... args);
3361cb0ef41Sopenharmony_ci  template <typename... Args>
3371cb0ef41Sopenharmony_ci  TNode<Object> Call(const Operator* op, Node* first_arg, Args... args);
3381cb0ef41Sopenharmony_ci  void TailCall(const CallDescriptor* call_descriptor, int inputs_size,
3391cb0ef41Sopenharmony_ci                Node** inputs);
3401cb0ef41Sopenharmony_ci
3411cb0ef41Sopenharmony_ci  // Basic control operations.
3421cb0ef41Sopenharmony_ci  template <size_t VarCount>
3431cb0ef41Sopenharmony_ci  void Bind(GraphAssemblerLabel<VarCount>* label);
3441cb0ef41Sopenharmony_ci
3451cb0ef41Sopenharmony_ci  template <typename... Vars>
3461cb0ef41Sopenharmony_ci  void Goto(GraphAssemblerLabel<sizeof...(Vars)>* label, Vars...);
3471cb0ef41Sopenharmony_ci
3481cb0ef41Sopenharmony_ci  // Branch hints are inferred from if_true/if_false deferred states.
3491cb0ef41Sopenharmony_ci  void BranchWithCriticalSafetyCheck(Node* condition,
3501cb0ef41Sopenharmony_ci                                     GraphAssemblerLabel<0u>* if_true,
3511cb0ef41Sopenharmony_ci                                     GraphAssemblerLabel<0u>* if_false);
3521cb0ef41Sopenharmony_ci
3531cb0ef41Sopenharmony_ci  // Branch hints are inferred from if_true/if_false deferred states.
3541cb0ef41Sopenharmony_ci  template <typename... Vars>
3551cb0ef41Sopenharmony_ci  void Branch(Node* condition, GraphAssemblerLabel<sizeof...(Vars)>* if_true,
3561cb0ef41Sopenharmony_ci              GraphAssemblerLabel<sizeof...(Vars)>* if_false, Vars...);
3571cb0ef41Sopenharmony_ci
3581cb0ef41Sopenharmony_ci  template <typename... Vars>
3591cb0ef41Sopenharmony_ci  void BranchWithHint(Node* condition,
3601cb0ef41Sopenharmony_ci                      GraphAssemblerLabel<sizeof...(Vars)>* if_true,
3611cb0ef41Sopenharmony_ci                      GraphAssemblerLabel<sizeof...(Vars)>* if_false,
3621cb0ef41Sopenharmony_ci                      BranchHint hint, Vars...);
3631cb0ef41Sopenharmony_ci
3641cb0ef41Sopenharmony_ci  // Control helpers.
3651cb0ef41Sopenharmony_ci
3661cb0ef41Sopenharmony_ci  // {GotoIf(c, l, h)} is equivalent to {BranchWithHint(c, l, templ, h);
3671cb0ef41Sopenharmony_ci  // Bind(templ)}.
3681cb0ef41Sopenharmony_ci  template <typename... Vars>
3691cb0ef41Sopenharmony_ci  void GotoIf(Node* condition, GraphAssemblerLabel<sizeof...(Vars)>* label,
3701cb0ef41Sopenharmony_ci              BranchHint hint, Vars...);
3711cb0ef41Sopenharmony_ci
3721cb0ef41Sopenharmony_ci  // {GotoIfNot(c, l, h)} is equivalent to {BranchWithHint(c, templ, l, h);
3731cb0ef41Sopenharmony_ci  // Bind(templ)}.
3741cb0ef41Sopenharmony_ci  // The branch hint refers to the expected outcome of the provided condition,
3751cb0ef41Sopenharmony_ci  // so {GotoIfNot(..., BranchHint::kTrue)} means "optimize for the case where
3761cb0ef41Sopenharmony_ci  // the branch is *not* taken".
3771cb0ef41Sopenharmony_ci  template <typename... Vars>
3781cb0ef41Sopenharmony_ci  void GotoIfNot(Node* condition, GraphAssemblerLabel<sizeof...(Vars)>* label,
3791cb0ef41Sopenharmony_ci                 BranchHint hint, Vars...);
3801cb0ef41Sopenharmony_ci
3811cb0ef41Sopenharmony_ci  // {GotoIf(c, l)} is equivalent to {Branch(c, l, templ);Bind(templ)}.
3821cb0ef41Sopenharmony_ci  template <typename... Vars>
3831cb0ef41Sopenharmony_ci  void GotoIf(Node* condition, GraphAssemblerLabel<sizeof...(Vars)>* label,
3841cb0ef41Sopenharmony_ci              Vars...);
3851cb0ef41Sopenharmony_ci
3861cb0ef41Sopenharmony_ci  // {GotoIfNot(c, l)} is equivalent to {Branch(c, templ, l);Bind(templ)}.
3871cb0ef41Sopenharmony_ci  template <typename... Vars>
3881cb0ef41Sopenharmony_ci  void GotoIfNot(Node* condition, GraphAssemblerLabel<sizeof...(Vars)>* label,
3891cb0ef41Sopenharmony_ci                 Vars...);
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ci  bool HasActiveBlock() const {
3921cb0ef41Sopenharmony_ci    // This is false if the current block has been terminated (e.g. by a Goto or
3931cb0ef41Sopenharmony_ci    // Unreachable). In that case, a new label must be bound before we can
3941cb0ef41Sopenharmony_ci    // continue emitting nodes.
3951cb0ef41Sopenharmony_ci    return control() != nullptr;
3961cb0ef41Sopenharmony_ci  }
3971cb0ef41Sopenharmony_ci
3981cb0ef41Sopenharmony_ci  // Updates current effect and control based on outputs of {node}.
3991cb0ef41Sopenharmony_ci  V8_INLINE void UpdateEffectControlWith(Node* node) {
4001cb0ef41Sopenharmony_ci    if (node->op()->EffectOutputCount() > 0) {
4011cb0ef41Sopenharmony_ci      effect_ = node;
4021cb0ef41Sopenharmony_ci    }
4031cb0ef41Sopenharmony_ci    if (node->op()->ControlOutputCount() > 0) {
4041cb0ef41Sopenharmony_ci      control_ = node;
4051cb0ef41Sopenharmony_ci    }
4061cb0ef41Sopenharmony_ci  }
4071cb0ef41Sopenharmony_ci
4081cb0ef41Sopenharmony_ci  // Adds {node} to the current position and updates assembler's current effect
4091cb0ef41Sopenharmony_ci  // and control.
4101cb0ef41Sopenharmony_ci  Node* AddNode(Node* node);
4111cb0ef41Sopenharmony_ci
4121cb0ef41Sopenharmony_ci  template <typename T>
4131cb0ef41Sopenharmony_ci  TNode<T> AddNode(Node* node) {
4141cb0ef41Sopenharmony_ci    return TNode<T>::UncheckedCast(AddNode(node));
4151cb0ef41Sopenharmony_ci  }
4161cb0ef41Sopenharmony_ci
4171cb0ef41Sopenharmony_ci  void ConnectUnreachableToEnd();
4181cb0ef41Sopenharmony_ci
4191cb0ef41Sopenharmony_ci  // Add an inline reducers such that nodes added to the graph will be run
4201cb0ef41Sopenharmony_ci  // through the reducers and possibly further lowered. Each reducer should
4211cb0ef41Sopenharmony_ci  // operate on independent node types since once a reducer changes a node we
4221cb0ef41Sopenharmony_ci  // no longer run any other reducers on that node. The reducers should also
4231cb0ef41Sopenharmony_ci  // only generate new nodes that wouldn't be further reduced, as new nodes
4241cb0ef41Sopenharmony_ci  // generated by a reducer won't be passed through the reducers again.
4251cb0ef41Sopenharmony_ci  void AddInlineReducer(Reducer* reducer) {
4261cb0ef41Sopenharmony_ci    inline_reducers_.push_back(reducer);
4271cb0ef41Sopenharmony_ci  }
4281cb0ef41Sopenharmony_ci
4291cb0ef41Sopenharmony_ci  Control control() const { return Control(control_); }
4301cb0ef41Sopenharmony_ci  Effect effect() const { return Effect(effect_); }
4311cb0ef41Sopenharmony_ci
4321cb0ef41Sopenharmony_ci protected:
4331cb0ef41Sopenharmony_ci  template <typename... Vars>
4341cb0ef41Sopenharmony_ci  void MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label, Vars... vars);
4351cb0ef41Sopenharmony_ci
4361cb0ef41Sopenharmony_ci  V8_INLINE Node* AddClonedNode(Node* node);
4371cb0ef41Sopenharmony_ci
4381cb0ef41Sopenharmony_ci  MachineGraph* mcgraph() const { return mcgraph_; }
4391cb0ef41Sopenharmony_ci  Graph* graph() const { return mcgraph_->graph(); }
4401cb0ef41Sopenharmony_ci  Zone* temp_zone() const { return temp_zone_; }
4411cb0ef41Sopenharmony_ci  CommonOperatorBuilder* common() const { return mcgraph()->common(); }
4421cb0ef41Sopenharmony_ci  MachineOperatorBuilder* machine() const { return mcgraph()->machine(); }
4431cb0ef41Sopenharmony_ci
4441cb0ef41Sopenharmony_ci  // Updates machinery for creating {LoopExit,LoopExitEffect,LoopExitValue}
4451cb0ef41Sopenharmony_ci  // nodes on loop exits (which are necessary for loop peeling).
4461cb0ef41Sopenharmony_ci  //
4471cb0ef41Sopenharmony_ci  // All labels created while a LoopScope is live are considered to be inside
4481cb0ef41Sopenharmony_ci  // the loop.
4491cb0ef41Sopenharmony_ci  template <MachineRepresentation... Reps>
4501cb0ef41Sopenharmony_ci  class V8_NODISCARD LoopScope final {
4511cb0ef41Sopenharmony_ci   private:
4521cb0ef41Sopenharmony_ci    // The internal scope is only here to increment the graph assembler's
4531cb0ef41Sopenharmony_ci    // nesting level prior to `loop_header_label` creation below.
4541cb0ef41Sopenharmony_ci    class V8_NODISCARD LoopScopeInternal {
4551cb0ef41Sopenharmony_ci     public:
4561cb0ef41Sopenharmony_ci      explicit LoopScopeInternal(GraphAssembler* gasm)
4571cb0ef41Sopenharmony_ci          : previous_loop_nesting_level_(gasm->loop_nesting_level_),
4581cb0ef41Sopenharmony_ci            gasm_(gasm) {
4591cb0ef41Sopenharmony_ci        gasm->loop_nesting_level_++;
4601cb0ef41Sopenharmony_ci      }
4611cb0ef41Sopenharmony_ci
4621cb0ef41Sopenharmony_ci      ~LoopScopeInternal() {
4631cb0ef41Sopenharmony_ci        gasm_->loop_nesting_level_--;
4641cb0ef41Sopenharmony_ci        DCHECK_EQ(gasm_->loop_nesting_level_, previous_loop_nesting_level_);
4651cb0ef41Sopenharmony_ci      }
4661cb0ef41Sopenharmony_ci
4671cb0ef41Sopenharmony_ci     private:
4681cb0ef41Sopenharmony_ci      const int previous_loop_nesting_level_;
4691cb0ef41Sopenharmony_ci      GraphAssembler* const gasm_;
4701cb0ef41Sopenharmony_ci    };
4711cb0ef41Sopenharmony_ci
4721cb0ef41Sopenharmony_ci   public:
4731cb0ef41Sopenharmony_ci    explicit LoopScope(GraphAssembler* gasm)
4741cb0ef41Sopenharmony_ci        : internal_scope_(gasm),
4751cb0ef41Sopenharmony_ci          gasm_(gasm),
4761cb0ef41Sopenharmony_ci          loop_header_label_(gasm->MakeLoopLabel(Reps...)) {
4771cb0ef41Sopenharmony_ci      // This feature may only be used if it has been enabled.
4781cb0ef41Sopenharmony_ci      DCHECK(gasm_->mark_loop_exits_);
4791cb0ef41Sopenharmony_ci      gasm->loop_headers_.push_back(&loop_header_label_.control_);
4801cb0ef41Sopenharmony_ci      DCHECK_EQ(static_cast<int>(gasm_->loop_headers_.size()),
4811cb0ef41Sopenharmony_ci                gasm_->loop_nesting_level_);
4821cb0ef41Sopenharmony_ci    }
4831cb0ef41Sopenharmony_ci
4841cb0ef41Sopenharmony_ci    ~LoopScope() {
4851cb0ef41Sopenharmony_ci      DCHECK_EQ(static_cast<int>(gasm_->loop_headers_.size()),
4861cb0ef41Sopenharmony_ci                gasm_->loop_nesting_level_);
4871cb0ef41Sopenharmony_ci      gasm_->loop_headers_.pop_back();
4881cb0ef41Sopenharmony_ci    }
4891cb0ef41Sopenharmony_ci
4901cb0ef41Sopenharmony_ci    GraphAssemblerLabel<sizeof...(Reps)>* loop_header_label() {
4911cb0ef41Sopenharmony_ci      return &loop_header_label_;
4921cb0ef41Sopenharmony_ci    }
4931cb0ef41Sopenharmony_ci
4941cb0ef41Sopenharmony_ci   private:
4951cb0ef41Sopenharmony_ci    const LoopScopeInternal internal_scope_;
4961cb0ef41Sopenharmony_ci    GraphAssembler* const gasm_;
4971cb0ef41Sopenharmony_ci    GraphAssemblerLabel<sizeof...(Reps)> loop_header_label_;
4981cb0ef41Sopenharmony_ci  };
4991cb0ef41Sopenharmony_ci
5001cb0ef41Sopenharmony_ci  // Upon destruction, restores effect and control to the state at construction.
5011cb0ef41Sopenharmony_ci  class V8_NODISCARD RestoreEffectControlScope {
5021cb0ef41Sopenharmony_ci   public:
5031cb0ef41Sopenharmony_ci    explicit RestoreEffectControlScope(GraphAssembler* gasm)
5041cb0ef41Sopenharmony_ci        : gasm_(gasm), effect_(gasm->effect()), control_(gasm->control()) {}
5051cb0ef41Sopenharmony_ci
5061cb0ef41Sopenharmony_ci    ~RestoreEffectControlScope() {
5071cb0ef41Sopenharmony_ci      gasm_->effect_ = effect_;
5081cb0ef41Sopenharmony_ci      gasm_->control_ = control_;
5091cb0ef41Sopenharmony_ci    }
5101cb0ef41Sopenharmony_ci
5111cb0ef41Sopenharmony_ci   private:
5121cb0ef41Sopenharmony_ci    GraphAssembler* const gasm_;
5131cb0ef41Sopenharmony_ci    const Effect effect_;
5141cb0ef41Sopenharmony_ci    const Control control_;
5151cb0ef41Sopenharmony_ci  };
5161cb0ef41Sopenharmony_ci
5171cb0ef41Sopenharmony_ci private:
5181cb0ef41Sopenharmony_ci  class BlockInlineReduction;
5191cb0ef41Sopenharmony_ci
5201cb0ef41Sopenharmony_ci  template <typename... Vars>
5211cb0ef41Sopenharmony_ci  void BranchImpl(Node* condition,
5221cb0ef41Sopenharmony_ci                  GraphAssemblerLabel<sizeof...(Vars)>* if_true,
5231cb0ef41Sopenharmony_ci                  GraphAssemblerLabel<sizeof...(Vars)>* if_false,
5241cb0ef41Sopenharmony_ci                  BranchHint hint, Vars...);
5251cb0ef41Sopenharmony_ci
5261cb0ef41Sopenharmony_ci  Zone* temp_zone_;
5271cb0ef41Sopenharmony_ci  MachineGraph* mcgraph_;
5281cb0ef41Sopenharmony_ci  Node* effect_;
5291cb0ef41Sopenharmony_ci  Node* control_;
5301cb0ef41Sopenharmony_ci  // {node_changed_callback_} should be called when a node outside the
5311cb0ef41Sopenharmony_ci  // subgraph created by the graph assembler changes.
5321cb0ef41Sopenharmony_ci  base::Optional<NodeChangedCallback> node_changed_callback_;
5331cb0ef41Sopenharmony_ci
5341cb0ef41Sopenharmony_ci  // Inline reducers enable reductions to be performed to nodes as they are
5351cb0ef41Sopenharmony_ci  // added to the graph with the graph assembler.
5361cb0ef41Sopenharmony_ci  ZoneVector<Reducer*> inline_reducers_;
5371cb0ef41Sopenharmony_ci  bool inline_reductions_blocked_;
5381cb0ef41Sopenharmony_ci
5391cb0ef41Sopenharmony_ci  // Track loop information in order to properly mark loop exits with
5401cb0ef41Sopenharmony_ci  // {LoopExit,LoopExitEffect,LoopExitValue} nodes. The outermost level has
5411cb0ef41Sopenharmony_ci  // a nesting level of 0. See also GraphAssembler::LoopScope.
5421cb0ef41Sopenharmony_ci  int loop_nesting_level_ = 0;
5431cb0ef41Sopenharmony_ci  ZoneVector<Node**> loop_headers_;
5441cb0ef41Sopenharmony_ci
5451cb0ef41Sopenharmony_ci  // Feature configuration. As more features are added, this should be turned
5461cb0ef41Sopenharmony_ci  // into a bitfield.
5471cb0ef41Sopenharmony_ci  const bool mark_loop_exits_;
5481cb0ef41Sopenharmony_ci};
5491cb0ef41Sopenharmony_ci
5501cb0ef41Sopenharmony_citemplate <size_t VarCount>
5511cb0ef41Sopenharmony_ciNode* GraphAssemblerLabel<VarCount>::PhiAt(size_t index) {
5521cb0ef41Sopenharmony_ci  DCHECK(IsBound());
5531cb0ef41Sopenharmony_ci  DCHECK_LT(index, VarCount);
5541cb0ef41Sopenharmony_ci  return bindings_[index];
5551cb0ef41Sopenharmony_ci}
5561cb0ef41Sopenharmony_ci
5571cb0ef41Sopenharmony_citemplate <typename... Vars>
5581cb0ef41Sopenharmony_civoid GraphAssembler::MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label,
5591cb0ef41Sopenharmony_ci                                Vars... vars) {
5601cb0ef41Sopenharmony_ci  RestoreEffectControlScope restore_effect_control_scope(this);
5611cb0ef41Sopenharmony_ci
5621cb0ef41Sopenharmony_ci  const int merged_count = static_cast<int>(label->merged_count_);
5631cb0ef41Sopenharmony_ci  static constexpr int kVarCount = sizeof...(vars);
5641cb0ef41Sopenharmony_ci  std::array<Node*, kVarCount> var_array = {vars...};
5651cb0ef41Sopenharmony_ci
5661cb0ef41Sopenharmony_ci  const bool is_loop_exit = label->loop_nesting_level_ != loop_nesting_level_;
5671cb0ef41Sopenharmony_ci  if (is_loop_exit) {
5681cb0ef41Sopenharmony_ci    // This feature may only be used if it has been enabled.
5691cb0ef41Sopenharmony_ci    USE(mark_loop_exits_);
5701cb0ef41Sopenharmony_ci    DCHECK(mark_loop_exits_);
5711cb0ef41Sopenharmony_ci    // Jumping from loops to loops not supported.
5721cb0ef41Sopenharmony_ci    DCHECK(!label->IsLoop());
5731cb0ef41Sopenharmony_ci    // Currently only the simple case of jumping one level is supported.
5741cb0ef41Sopenharmony_ci    DCHECK_EQ(label->loop_nesting_level_, loop_nesting_level_ - 1);
5751cb0ef41Sopenharmony_ci    DCHECK(!loop_headers_.empty());
5761cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(*loop_headers_.back());
5771cb0ef41Sopenharmony_ci
5781cb0ef41Sopenharmony_ci    // Mark this exit to enable loop peeling.
5791cb0ef41Sopenharmony_ci    AddNode(graph()->NewNode(common()->LoopExit(), control(),
5801cb0ef41Sopenharmony_ci                             *loop_headers_.back()));
5811cb0ef41Sopenharmony_ci    AddNode(graph()->NewNode(common()->LoopExitEffect(), effect(), control()));
5821cb0ef41Sopenharmony_ci    for (size_t i = 0; i < kVarCount; i++) {
5831cb0ef41Sopenharmony_ci      var_array[i] = AddNode(graph()->NewNode(
5841cb0ef41Sopenharmony_ci          common()->LoopExitValue(MachineRepresentation::kTagged), var_array[i],
5851cb0ef41Sopenharmony_ci          control()));
5861cb0ef41Sopenharmony_ci    }
5871cb0ef41Sopenharmony_ci  }
5881cb0ef41Sopenharmony_ci
5891cb0ef41Sopenharmony_ci  if (label->IsLoop()) {
5901cb0ef41Sopenharmony_ci    if (merged_count == 0) {
5911cb0ef41Sopenharmony_ci      DCHECK(!label->IsBound());
5921cb0ef41Sopenharmony_ci      label->control_ =
5931cb0ef41Sopenharmony_ci          graph()->NewNode(common()->Loop(2), control(), control());
5941cb0ef41Sopenharmony_ci      label->effect_ = graph()->NewNode(common()->EffectPhi(2), effect(),
5951cb0ef41Sopenharmony_ci                                        effect(), label->control_);
5961cb0ef41Sopenharmony_ci      Node* terminate = graph()->NewNode(common()->Terminate(), label->effect_,
5971cb0ef41Sopenharmony_ci                                         label->control_);
5981cb0ef41Sopenharmony_ci      NodeProperties::MergeControlToEnd(graph(), common(), terminate);
5991cb0ef41Sopenharmony_ci      for (size_t i = 0; i < kVarCount; i++) {
6001cb0ef41Sopenharmony_ci        label->bindings_[i] =
6011cb0ef41Sopenharmony_ci            graph()->NewNode(common()->Phi(label->representations_[i], 2),
6021cb0ef41Sopenharmony_ci                             var_array[i], var_array[i], label->control_);
6031cb0ef41Sopenharmony_ci      }
6041cb0ef41Sopenharmony_ci    } else {
6051cb0ef41Sopenharmony_ci      DCHECK(label->IsBound());
6061cb0ef41Sopenharmony_ci      DCHECK_EQ(1, merged_count);
6071cb0ef41Sopenharmony_ci      label->control_->ReplaceInput(1, control());
6081cb0ef41Sopenharmony_ci      label->effect_->ReplaceInput(1, effect());
6091cb0ef41Sopenharmony_ci      for (size_t i = 0; i < kVarCount; i++) {
6101cb0ef41Sopenharmony_ci        label->bindings_[i]->ReplaceInput(1, var_array[i]);
6111cb0ef41Sopenharmony_ci        CHECK(!NodeProperties::IsTyped(var_array[i]));  // Unsupported.
6121cb0ef41Sopenharmony_ci      }
6131cb0ef41Sopenharmony_ci    }
6141cb0ef41Sopenharmony_ci  } else {
6151cb0ef41Sopenharmony_ci    DCHECK(!label->IsLoop());
6161cb0ef41Sopenharmony_ci    DCHECK(!label->IsBound());
6171cb0ef41Sopenharmony_ci    if (merged_count == 0) {
6181cb0ef41Sopenharmony_ci      // Just set the control, effect and variables directly.
6191cb0ef41Sopenharmony_ci      label->control_ = control();
6201cb0ef41Sopenharmony_ci      label->effect_ = effect();
6211cb0ef41Sopenharmony_ci      for (size_t i = 0; i < kVarCount; i++) {
6221cb0ef41Sopenharmony_ci        label->bindings_[i] = var_array[i];
6231cb0ef41Sopenharmony_ci      }
6241cb0ef41Sopenharmony_ci    } else if (merged_count == 1) {
6251cb0ef41Sopenharmony_ci      // Create merge, effect phi and a phi for each variable.
6261cb0ef41Sopenharmony_ci      label->control_ =
6271cb0ef41Sopenharmony_ci          graph()->NewNode(common()->Merge(2), label->control_, control());
6281cb0ef41Sopenharmony_ci      label->effect_ = graph()->NewNode(common()->EffectPhi(2), label->effect_,
6291cb0ef41Sopenharmony_ci                                        effect(), label->control_);
6301cb0ef41Sopenharmony_ci      for (size_t i = 0; i < kVarCount; i++) {
6311cb0ef41Sopenharmony_ci        label->bindings_[i] = graph()->NewNode(
6321cb0ef41Sopenharmony_ci            common()->Phi(label->representations_[i], 2), label->bindings_[i],
6331cb0ef41Sopenharmony_ci            var_array[i], label->control_);
6341cb0ef41Sopenharmony_ci      }
6351cb0ef41Sopenharmony_ci    } else {
6361cb0ef41Sopenharmony_ci      // Append to the merge, effect phi and phis.
6371cb0ef41Sopenharmony_ci      DCHECK_EQ(IrOpcode::kMerge, label->control_->opcode());
6381cb0ef41Sopenharmony_ci      label->control_->AppendInput(graph()->zone(), control());
6391cb0ef41Sopenharmony_ci      NodeProperties::ChangeOp(label->control_,
6401cb0ef41Sopenharmony_ci                               common()->Merge(merged_count + 1));
6411cb0ef41Sopenharmony_ci
6421cb0ef41Sopenharmony_ci      DCHECK_EQ(IrOpcode::kEffectPhi, label->effect_->opcode());
6431cb0ef41Sopenharmony_ci      label->effect_->ReplaceInput(merged_count, effect());
6441cb0ef41Sopenharmony_ci      label->effect_->AppendInput(graph()->zone(), label->control_);
6451cb0ef41Sopenharmony_ci      NodeProperties::ChangeOp(label->effect_,
6461cb0ef41Sopenharmony_ci                               common()->EffectPhi(merged_count + 1));
6471cb0ef41Sopenharmony_ci
6481cb0ef41Sopenharmony_ci      for (size_t i = 0; i < kVarCount; i++) {
6491cb0ef41Sopenharmony_ci        DCHECK_EQ(IrOpcode::kPhi, label->bindings_[i]->opcode());
6501cb0ef41Sopenharmony_ci        label->bindings_[i]->ReplaceInput(merged_count, var_array[i]);
6511cb0ef41Sopenharmony_ci        label->bindings_[i]->AppendInput(graph()->zone(), label->control_);
6521cb0ef41Sopenharmony_ci        NodeProperties::ChangeOp(
6531cb0ef41Sopenharmony_ci            label->bindings_[i],
6541cb0ef41Sopenharmony_ci            common()->Phi(label->representations_[i], merged_count + 1));
6551cb0ef41Sopenharmony_ci        if (NodeProperties::IsTyped(label->bindings_[i])) {
6561cb0ef41Sopenharmony_ci          CHECK(NodeProperties::IsTyped(var_array[i]));
6571cb0ef41Sopenharmony_ci          Type old_type = NodeProperties::GetType(label->bindings_[i]);
6581cb0ef41Sopenharmony_ci          Type new_type = Type::Union(
6591cb0ef41Sopenharmony_ci              old_type, NodeProperties::GetType(var_array[i]), graph()->zone());
6601cb0ef41Sopenharmony_ci          NodeProperties::SetType(label->bindings_[i], new_type);
6611cb0ef41Sopenharmony_ci        }
6621cb0ef41Sopenharmony_ci      }
6631cb0ef41Sopenharmony_ci    }
6641cb0ef41Sopenharmony_ci  }
6651cb0ef41Sopenharmony_ci  label->merged_count_++;
6661cb0ef41Sopenharmony_ci}
6671cb0ef41Sopenharmony_ci
6681cb0ef41Sopenharmony_citemplate <size_t VarCount>
6691cb0ef41Sopenharmony_civoid GraphAssembler::Bind(GraphAssemblerLabel<VarCount>* label) {
6701cb0ef41Sopenharmony_ci  DCHECK_NULL(control());
6711cb0ef41Sopenharmony_ci  DCHECK_NULL(effect());
6721cb0ef41Sopenharmony_ci  DCHECK_LT(0, label->merged_count_);
6731cb0ef41Sopenharmony_ci  DCHECK_EQ(label->loop_nesting_level_, loop_nesting_level_);
6741cb0ef41Sopenharmony_ci
6751cb0ef41Sopenharmony_ci  control_ = label->control_;
6761cb0ef41Sopenharmony_ci  effect_ = label->effect_;
6771cb0ef41Sopenharmony_ci
6781cb0ef41Sopenharmony_ci  label->SetBound();
6791cb0ef41Sopenharmony_ci
6801cb0ef41Sopenharmony_ci  if (label->merged_count_ > 1 || label->IsLoop()) {
6811cb0ef41Sopenharmony_ci    AddNode(label->control_);
6821cb0ef41Sopenharmony_ci    AddNode(label->effect_);
6831cb0ef41Sopenharmony_ci    for (size_t i = 0; i < VarCount; i++) {
6841cb0ef41Sopenharmony_ci      AddNode(label->bindings_[i]);
6851cb0ef41Sopenharmony_ci    }
6861cb0ef41Sopenharmony_ci  } else {
6871cb0ef41Sopenharmony_ci    // If the basic block does not have a control node, insert a dummy
6881cb0ef41Sopenharmony_ci    // Merge node, so that other passes have a control node to start from.
6891cb0ef41Sopenharmony_ci    control_ = AddNode(graph()->NewNode(common()->Merge(1), control()));
6901cb0ef41Sopenharmony_ci  }
6911cb0ef41Sopenharmony_ci}
6921cb0ef41Sopenharmony_ci
6931cb0ef41Sopenharmony_citemplate <typename... Vars>
6941cb0ef41Sopenharmony_civoid GraphAssembler::Branch(Node* condition,
6951cb0ef41Sopenharmony_ci                            GraphAssemblerLabel<sizeof...(Vars)>* if_true,
6961cb0ef41Sopenharmony_ci                            GraphAssemblerLabel<sizeof...(Vars)>* if_false,
6971cb0ef41Sopenharmony_ci                            Vars... vars) {
6981cb0ef41Sopenharmony_ci  BranchHint hint = BranchHint::kNone;
6991cb0ef41Sopenharmony_ci  if (if_true->IsDeferred() != if_false->IsDeferred()) {
7001cb0ef41Sopenharmony_ci    hint = if_false->IsDeferred() ? BranchHint::kTrue : BranchHint::kFalse;
7011cb0ef41Sopenharmony_ci  }
7021cb0ef41Sopenharmony_ci
7031cb0ef41Sopenharmony_ci  BranchImpl(condition, if_true, if_false, hint, vars...);
7041cb0ef41Sopenharmony_ci}
7051cb0ef41Sopenharmony_ci
7061cb0ef41Sopenharmony_citemplate <typename... Vars>
7071cb0ef41Sopenharmony_civoid GraphAssembler::BranchWithHint(
7081cb0ef41Sopenharmony_ci    Node* condition, GraphAssemblerLabel<sizeof...(Vars)>* if_true,
7091cb0ef41Sopenharmony_ci    GraphAssemblerLabel<sizeof...(Vars)>* if_false, BranchHint hint,
7101cb0ef41Sopenharmony_ci    Vars... vars) {
7111cb0ef41Sopenharmony_ci  BranchImpl(condition, if_true, if_false, hint, vars...);
7121cb0ef41Sopenharmony_ci}
7131cb0ef41Sopenharmony_ci
7141cb0ef41Sopenharmony_citemplate <typename... Vars>
7151cb0ef41Sopenharmony_civoid GraphAssembler::BranchImpl(Node* condition,
7161cb0ef41Sopenharmony_ci                                GraphAssemblerLabel<sizeof...(Vars)>* if_true,
7171cb0ef41Sopenharmony_ci                                GraphAssemblerLabel<sizeof...(Vars)>* if_false,
7181cb0ef41Sopenharmony_ci                                BranchHint hint, Vars... vars) {
7191cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(control());
7201cb0ef41Sopenharmony_ci
7211cb0ef41Sopenharmony_ci  Node* branch = graph()->NewNode(common()->Branch(hint), condition, control());
7221cb0ef41Sopenharmony_ci
7231cb0ef41Sopenharmony_ci  control_ = graph()->NewNode(common()->IfTrue(), branch);
7241cb0ef41Sopenharmony_ci  MergeState(if_true, vars...);
7251cb0ef41Sopenharmony_ci
7261cb0ef41Sopenharmony_ci  control_ = graph()->NewNode(common()->IfFalse(), branch);
7271cb0ef41Sopenharmony_ci  MergeState(if_false, vars...);
7281cb0ef41Sopenharmony_ci
7291cb0ef41Sopenharmony_ci  control_ = nullptr;
7301cb0ef41Sopenharmony_ci  effect_ = nullptr;
7311cb0ef41Sopenharmony_ci}
7321cb0ef41Sopenharmony_ci
7331cb0ef41Sopenharmony_citemplate <typename... Vars>
7341cb0ef41Sopenharmony_civoid GraphAssembler::Goto(GraphAssemblerLabel<sizeof...(Vars)>* label,
7351cb0ef41Sopenharmony_ci                          Vars... vars) {
7361cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(control());
7371cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(effect());
7381cb0ef41Sopenharmony_ci  MergeState(label, vars...);
7391cb0ef41Sopenharmony_ci
7401cb0ef41Sopenharmony_ci  control_ = nullptr;
7411cb0ef41Sopenharmony_ci  effect_ = nullptr;
7421cb0ef41Sopenharmony_ci}
7431cb0ef41Sopenharmony_ci
7441cb0ef41Sopenharmony_citemplate <typename... Vars>
7451cb0ef41Sopenharmony_civoid GraphAssembler::GotoIf(Node* condition,
7461cb0ef41Sopenharmony_ci                            GraphAssemblerLabel<sizeof...(Vars)>* label,
7471cb0ef41Sopenharmony_ci                            BranchHint hint, Vars... vars) {
7481cb0ef41Sopenharmony_ci  Node* branch = graph()->NewNode(common()->Branch(hint), condition, control());
7491cb0ef41Sopenharmony_ci
7501cb0ef41Sopenharmony_ci  control_ = graph()->NewNode(common()->IfTrue(), branch);
7511cb0ef41Sopenharmony_ci  MergeState(label, vars...);
7521cb0ef41Sopenharmony_ci
7531cb0ef41Sopenharmony_ci  control_ = AddNode(graph()->NewNode(common()->IfFalse(), branch));
7541cb0ef41Sopenharmony_ci}
7551cb0ef41Sopenharmony_ci
7561cb0ef41Sopenharmony_citemplate <typename... Vars>
7571cb0ef41Sopenharmony_civoid GraphAssembler::GotoIfNot(Node* condition,
7581cb0ef41Sopenharmony_ci                               GraphAssemblerLabel<sizeof...(Vars)>* label,
7591cb0ef41Sopenharmony_ci                               BranchHint hint, Vars... vars) {
7601cb0ef41Sopenharmony_ci  Node* branch = graph()->NewNode(common()->Branch(hint), condition, control());
7611cb0ef41Sopenharmony_ci
7621cb0ef41Sopenharmony_ci  control_ = graph()->NewNode(common()->IfFalse(), branch);
7631cb0ef41Sopenharmony_ci  MergeState(label, vars...);
7641cb0ef41Sopenharmony_ci
7651cb0ef41Sopenharmony_ci  control_ = AddNode(graph()->NewNode(common()->IfTrue(), branch));
7661cb0ef41Sopenharmony_ci}
7671cb0ef41Sopenharmony_ci
7681cb0ef41Sopenharmony_citemplate <typename... Vars>
7691cb0ef41Sopenharmony_civoid GraphAssembler::GotoIf(Node* condition,
7701cb0ef41Sopenharmony_ci                            GraphAssemblerLabel<sizeof...(Vars)>* label,
7711cb0ef41Sopenharmony_ci                            Vars... vars) {
7721cb0ef41Sopenharmony_ci  BranchHint hint =
7731cb0ef41Sopenharmony_ci      label->IsDeferred() ? BranchHint::kFalse : BranchHint::kNone;
7741cb0ef41Sopenharmony_ci  return GotoIf(condition, label, hint, vars...);
7751cb0ef41Sopenharmony_ci}
7761cb0ef41Sopenharmony_ci
7771cb0ef41Sopenharmony_citemplate <typename... Vars>
7781cb0ef41Sopenharmony_civoid GraphAssembler::GotoIfNot(Node* condition,
7791cb0ef41Sopenharmony_ci                               GraphAssemblerLabel<sizeof...(Vars)>* label,
7801cb0ef41Sopenharmony_ci                               Vars... vars) {
7811cb0ef41Sopenharmony_ci  BranchHint hint = label->IsDeferred() ? BranchHint::kTrue : BranchHint::kNone;
7821cb0ef41Sopenharmony_ci  return GotoIfNot(condition, label, hint, vars...);
7831cb0ef41Sopenharmony_ci}
7841cb0ef41Sopenharmony_ci
7851cb0ef41Sopenharmony_citemplate <typename... Args>
7861cb0ef41Sopenharmony_ciTNode<Object> GraphAssembler::Call(const CallDescriptor* call_descriptor,
7871cb0ef41Sopenharmony_ci                                   Node* first_arg, Args... args) {
7881cb0ef41Sopenharmony_ci  const Operator* op = common()->Call(call_descriptor);
7891cb0ef41Sopenharmony_ci  return Call(op, first_arg, args...);
7901cb0ef41Sopenharmony_ci}
7911cb0ef41Sopenharmony_ci
7921cb0ef41Sopenharmony_citemplate <typename... Args>
7931cb0ef41Sopenharmony_ciTNode<Object> GraphAssembler::Call(const Operator* op, Node* first_arg,
7941cb0ef41Sopenharmony_ci                                   Args... args) {
7951cb0ef41Sopenharmony_ci  Node* args_array[] = {first_arg, args..., effect(), control()};
7961cb0ef41Sopenharmony_ci  int size = static_cast<int>(1 + sizeof...(args)) + op->EffectInputCount() +
7971cb0ef41Sopenharmony_ci             op->ControlInputCount();
7981cb0ef41Sopenharmony_ci  return Call(op, size, args_array);
7991cb0ef41Sopenharmony_ci}
8001cb0ef41Sopenharmony_ci
8011cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE JSGraphAssembler : public GraphAssembler {
8021cb0ef41Sopenharmony_ci public:
8031cb0ef41Sopenharmony_ci  // Constructs a JSGraphAssembler. If {schedule} is not null, the graph
8041cb0ef41Sopenharmony_ci  // assembler will maintain the schedule as it updates blocks.
8051cb0ef41Sopenharmony_ci  JSGraphAssembler(
8061cb0ef41Sopenharmony_ci      JSGraph* jsgraph, Zone* zone,
8071cb0ef41Sopenharmony_ci      base::Optional<NodeChangedCallback> node_changed_callback = base::nullopt,
8081cb0ef41Sopenharmony_ci      bool mark_loop_exits = false)
8091cb0ef41Sopenharmony_ci      : GraphAssembler(jsgraph, zone, node_changed_callback, mark_loop_exits),
8101cb0ef41Sopenharmony_ci        jsgraph_(jsgraph) {}
8111cb0ef41Sopenharmony_ci
8121cb0ef41Sopenharmony_ci  Node* SmiConstant(int32_t value);
8131cb0ef41Sopenharmony_ci  TNode<HeapObject> HeapConstant(Handle<HeapObject> object);
8141cb0ef41Sopenharmony_ci  TNode<Object> Constant(const ObjectRef& ref);
8151cb0ef41Sopenharmony_ci  TNode<Number> NumberConstant(double value);
8161cb0ef41Sopenharmony_ci  Node* CEntryStubConstant(int result_size);
8171cb0ef41Sopenharmony_ci
8181cb0ef41Sopenharmony_ci#define SINGLETON_CONST_DECL(Name, Type) TNode<Type> Name##Constant();
8191cb0ef41Sopenharmony_ci  JSGRAPH_SINGLETON_CONSTANT_LIST(SINGLETON_CONST_DECL)
8201cb0ef41Sopenharmony_ci#undef SINGLETON_CONST_DECL
8211cb0ef41Sopenharmony_ci
8221cb0ef41Sopenharmony_ci#define SINGLETON_CONST_TEST_DECL(Name, ...) \
8231cb0ef41Sopenharmony_ci  TNode<Boolean> Is##Name(TNode<Object> value);
8241cb0ef41Sopenharmony_ci  JSGRAPH_SINGLETON_CONSTANT_LIST(SINGLETON_CONST_TEST_DECL)
8251cb0ef41Sopenharmony_ci#undef SINGLETON_CONST_TEST_DECL
8261cb0ef41Sopenharmony_ci
8271cb0ef41Sopenharmony_ci  Node* Allocate(AllocationType allocation, Node* size);
8281cb0ef41Sopenharmony_ci  Node* LoadField(FieldAccess const&, Node* object);
8291cb0ef41Sopenharmony_ci  template <typename T>
8301cb0ef41Sopenharmony_ci  TNode<T> LoadField(FieldAccess const& access, TNode<HeapObject> object) {
8311cb0ef41Sopenharmony_ci    // TODO(jgruber): Investigate issues on ptr compression bots and enable.
8321cb0ef41Sopenharmony_ci    // DCHECK(IsMachineRepresentationOf<T>(
8331cb0ef41Sopenharmony_ci    //     access.machine_type.representation()));
8341cb0ef41Sopenharmony_ci    return TNode<T>::UncheckedCast(LoadField(access, object));
8351cb0ef41Sopenharmony_ci  }
8361cb0ef41Sopenharmony_ci  Node* LoadElement(ElementAccess const&, Node* object, Node* index);
8371cb0ef41Sopenharmony_ci  template <typename T>
8381cb0ef41Sopenharmony_ci  TNode<T> LoadElement(ElementAccess const& access, TNode<HeapObject> object,
8391cb0ef41Sopenharmony_ci                       TNode<Number> index) {
8401cb0ef41Sopenharmony_ci    // TODO(jgruber): Investigate issues on ptr compression bots and enable.
8411cb0ef41Sopenharmony_ci    // DCHECK(IsMachineRepresentationOf<T>(
8421cb0ef41Sopenharmony_ci    //     access.machine_type.representation()));
8431cb0ef41Sopenharmony_ci    return TNode<T>::UncheckedCast(LoadElement(access, object, index));
8441cb0ef41Sopenharmony_ci  }
8451cb0ef41Sopenharmony_ci  Node* StoreField(FieldAccess const&, Node* object, Node* value);
8461cb0ef41Sopenharmony_ci  Node* StoreElement(ElementAccess const&, Node* object, Node* index,
8471cb0ef41Sopenharmony_ci                     Node* value);
8481cb0ef41Sopenharmony_ci  void TransitionAndStoreElement(MapRef double_map, MapRef fast_map,
8491cb0ef41Sopenharmony_ci                                 TNode<HeapObject> object, TNode<Number> index,
8501cb0ef41Sopenharmony_ci                                 TNode<Object> value);
8511cb0ef41Sopenharmony_ci  TNode<Number> StringLength(TNode<String> string);
8521cb0ef41Sopenharmony_ci  TNode<Boolean> ReferenceEqual(TNode<Object> lhs, TNode<Object> rhs);
8531cb0ef41Sopenharmony_ci  TNode<Number> PlainPrimitiveToNumber(TNode<Object> value);
8541cb0ef41Sopenharmony_ci  TNode<Number> NumberMin(TNode<Number> lhs, TNode<Number> rhs);
8551cb0ef41Sopenharmony_ci  TNode<Number> NumberMax(TNode<Number> lhs, TNode<Number> rhs);
8561cb0ef41Sopenharmony_ci  TNode<Boolean> NumberEqual(TNode<Number> lhs, TNode<Number> rhs);
8571cb0ef41Sopenharmony_ci  TNode<Boolean> NumberLessThan(TNode<Number> lhs, TNode<Number> rhs);
8581cb0ef41Sopenharmony_ci  TNode<Boolean> NumberLessThanOrEqual(TNode<Number> lhs, TNode<Number> rhs);
8591cb0ef41Sopenharmony_ci  TNode<Number> NumberAdd(TNode<Number> lhs, TNode<Number> rhs);
8601cb0ef41Sopenharmony_ci  TNode<Number> NumberSubtract(TNode<Number> lhs, TNode<Number> rhs);
8611cb0ef41Sopenharmony_ci  TNode<String> StringSubstring(TNode<String> string, TNode<Number> from,
8621cb0ef41Sopenharmony_ci                                TNode<Number> to);
8631cb0ef41Sopenharmony_ci  TNode<Boolean> ObjectIsCallable(TNode<Object> value);
8641cb0ef41Sopenharmony_ci  TNode<Boolean> ObjectIsUndetectable(TNode<Object> value);
8651cb0ef41Sopenharmony_ci  Node* CheckIf(Node* cond, DeoptimizeReason reason);
8661cb0ef41Sopenharmony_ci  TNode<Boolean> NumberIsFloat64Hole(TNode<Number> value);
8671cb0ef41Sopenharmony_ci  TNode<Boolean> ToBoolean(TNode<Object> value);
8681cb0ef41Sopenharmony_ci  TNode<Object> ConvertTaggedHoleToUndefined(TNode<Object> value);
8691cb0ef41Sopenharmony_ci  TNode<FixedArrayBase> MaybeGrowFastElements(ElementsKind kind,
8701cb0ef41Sopenharmony_ci                                              const FeedbackSource& feedback,
8711cb0ef41Sopenharmony_ci                                              TNode<JSArray> array,
8721cb0ef41Sopenharmony_ci                                              TNode<FixedArrayBase> elements,
8731cb0ef41Sopenharmony_ci                                              TNode<Number> new_length,
8741cb0ef41Sopenharmony_ci                                              TNode<Number> old_length);
8751cb0ef41Sopenharmony_ci  Node* StringCharCodeAt(TNode<String> string, TNode<Number> position);
8761cb0ef41Sopenharmony_ci
8771cb0ef41Sopenharmony_ci  JSGraph* jsgraph() const { return jsgraph_; }
8781cb0ef41Sopenharmony_ci  Isolate* isolate() const { return jsgraph()->isolate(); }
8791cb0ef41Sopenharmony_ci  SimplifiedOperatorBuilder* simplified() const {
8801cb0ef41Sopenharmony_ci    return jsgraph()->simplified();
8811cb0ef41Sopenharmony_ci  }
8821cb0ef41Sopenharmony_ci
8831cb0ef41Sopenharmony_ci protected:
8841cb0ef41Sopenharmony_ci  Operator const* PlainPrimitiveToNumberOperator();
8851cb0ef41Sopenharmony_ci
8861cb0ef41Sopenharmony_ci private:
8871cb0ef41Sopenharmony_ci  JSGraph* jsgraph_;
8881cb0ef41Sopenharmony_ci  SetOncePointer<Operator const> to_number_operator_;
8891cb0ef41Sopenharmony_ci};
8901cb0ef41Sopenharmony_ci
8911cb0ef41Sopenharmony_ci}  // namespace compiler
8921cb0ef41Sopenharmony_ci}  // namespace internal
8931cb0ef41Sopenharmony_ci}  // namespace v8
8941cb0ef41Sopenharmony_ci
8951cb0ef41Sopenharmony_ci#endif  // V8_COMPILER_GRAPH_ASSEMBLER_H_
896