1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_COMPILER_COMMON_OPERATOR_H_
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_COMPILER_COMMON_OPERATOR_H_
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/assembler.h"
9c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/base/compiler-specific.h"
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/frame-states.h"
11f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/deoptimize-reason.h"
12c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/globals.h"
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/machine-type.h"
14f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/zone/zone-containers.h"
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Forward declarations.
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CallDescriptor;
22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstruct CommonOperatorGlobalCache;
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Operator;
24f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochclass Type;
2562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass Node;
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Prediction hint for branches.
28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierenum class BranchHint : uint8_t { kNone, kTrue, kFalse };
29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochinline BranchHint NegateBranchHint(BranchHint hint) {
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (hint) {
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BranchHint::kNone:
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return hint;
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BranchHint::kTrue:
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return BranchHint::kFalse;
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BranchHint::kFalse:
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return BranchHint::kTrue;
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return hint;
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierinline size_t hash_value(BranchHint hint) { return static_cast<size_t>(hint); }
44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
45c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochV8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, BranchHint);
46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
47c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochV8_EXPORT_PRIVATE BranchHint BranchHintOf(const Operator* const);
48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Helper function for return nodes, because returns have a hidden value input.
5062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochint ValueInputCountOfReturn(Operator const* const op);
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Parameters for the {Deoptimize} operator.
53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass DeoptimizeParameters final {
54f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
55f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizeParameters(DeoptimizeKind kind, DeoptimizeReason reason)
56f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : kind_(kind), reason_(reason) {}
57f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
58f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizeKind kind() const { return kind_; }
59f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizeReason reason() const { return reason_; }
60f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
61f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
62f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizeKind const kind_;
63f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizeReason const reason_;
64f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
66f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool operator==(DeoptimizeParameters, DeoptimizeParameters);
67f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool operator!=(DeoptimizeParameters, DeoptimizeParameters);
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
69f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochsize_t hast_value(DeoptimizeParameters p);
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
71f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstd::ostream& operator<<(std::ostream&, DeoptimizeParameters p);
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
73f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochDeoptimizeParameters const& DeoptimizeParametersOf(Operator const* const);
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass SelectParameters final {
77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit SelectParameters(MachineRepresentation representation,
79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                            BranchHint hint = BranchHint::kNone)
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : representation_(representation), hint_(hint) {}
81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MachineRepresentation representation() const { return representation_; }
83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BranchHint hint() const { return hint_; }
84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const MachineRepresentation representation_;
87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const BranchHint hint_;
88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool operator==(SelectParameters const&, SelectParameters const&);
91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool operator!=(SelectParameters const&, SelectParameters const&);
92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniersize_t hash_value(SelectParameters const& p);
94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream&, SelectParameters const& p);
96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
97c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochV8_EXPORT_PRIVATE SelectParameters const& SelectParametersOf(
98c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    const Operator* const);
99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
100c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochV8_EXPORT_PRIVATE CallDescriptor const* CallDescriptorOf(const Operator* const);
101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
102c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochV8_EXPORT_PRIVATE size_t ProjectionIndexOf(const Operator* const);
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
104c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochV8_EXPORT_PRIVATE MachineRepresentation
105c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochPhiRepresentationOf(const Operator* const);
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// The {IrOpcode::kParameter} opcode represents an incoming parameter to the
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// function. This class bundles the index and a debug name for such operators.
109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ParameterInfo final {
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ParameterInfo(int index, const char* debug_name)
112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : index_(index), debug_name_(debug_name) {}
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int index() const { return index_; }
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const char* debug_name() const { return debug_name_; }
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int index_;
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const char* debug_name_;
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstd::ostream& operator<<(std::ostream&, ParameterInfo const&);
123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
124c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochV8_EXPORT_PRIVATE int ParameterIndexOf(const Operator* const);
125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst ParameterInfo& ParameterInfoOf(const Operator* const);
126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
127bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochclass RelocatablePtrConstantInfo final {
128bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch public:
129bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  enum Type { kInt32, kInt64 };
130bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
131bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RelocatablePtrConstantInfo(int32_t value, RelocInfo::Mode rmode)
132bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      : value_(value), rmode_(rmode), type_(kInt32) {}
133bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RelocatablePtrConstantInfo(int64_t value, RelocInfo::Mode rmode)
134bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      : value_(value), rmode_(rmode), type_(kInt64) {}
135bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
136bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  intptr_t value() const { return value_; }
137bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RelocInfo::Mode rmode() const { return rmode_; }
138bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Type type() const { return type_; }
139bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
140bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch private:
141bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  intptr_t value_;
142bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RelocInfo::Mode rmode_;
143bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Type type_;
144bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch};
145bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
146bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool operator==(RelocatablePtrConstantInfo const& lhs,
147bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                RelocatablePtrConstantInfo const& rhs);
148bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool operator!=(RelocatablePtrConstantInfo const& lhs,
149bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                RelocatablePtrConstantInfo const& rhs);
15013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
151bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochstd::ostream& operator<<(std::ostream&, RelocatablePtrConstantInfo const&);
15213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
153bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochsize_t hash_value(RelocatablePtrConstantInfo const& p);
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
15562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Used to define a sparse set of inputs. This can be used to efficiently encode
15662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// nodes that can have a lot of inputs, but where many inputs can have the same
15762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// value.
15862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass SparseInputMask final {
15962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public:
16062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  typedef uint32_t BitMaskType;
16162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
16262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // The mask representing a dense input set.
16362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static const BitMaskType kDenseBitMask = 0x0;
16462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // The bits representing the end of a sparse input set.
16562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static const BitMaskType kEndMarker = 0x1;
16662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // The mask for accessing a sparse input entry in the bitmask.
16762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static const BitMaskType kEntryMask = 0x1;
16862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
16962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // The number of bits in the mask, minus one for the end marker.
17062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static const int kMaxSparseInputs = (sizeof(BitMaskType) * kBitsPerByte - 1);
17162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
17262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // An iterator over a node's sparse inputs.
17362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  class InputIterator final {
17462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch   public:
17562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    InputIterator() {}
17662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    InputIterator(BitMaskType bit_mask, Node* parent);
17762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
17862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* parent() const { return parent_; }
17962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int real_index() const { return real_index_; }
18062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
18162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Advance the iterator to the next sparse input. Only valid if the iterator
18262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // has not reached the end.
18362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    void Advance();
18462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
18562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Get the current sparse input's real node value. Only valid if the
18662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // current sparse input is real.
18762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* GetReal() const;
18862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
18962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Get the current sparse input, returning either a real input node if
19062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // the current sparse input is real, or the given {empty_value} if the
19162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // current sparse input is empty.
19262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* Get(Node* empty_value) const {
19362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return IsReal() ? GetReal() : empty_value;
19462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
19562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
19662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // True if the current sparse input is a real input node.
19762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool IsReal() const;
19862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
19962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // True if the current sparse input is an empty value.
20062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool IsEmpty() const { return !IsReal(); }
20162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
20262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // True if the iterator has reached the end of the sparse inputs.
20362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool IsEnd() const;
20462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
20562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch   private:
20662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    BitMaskType bit_mask_;
20762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* parent_;
20862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int real_index_;
20962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  };
21062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
21162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  explicit SparseInputMask(BitMaskType bit_mask) : bit_mask_(bit_mask) {}
21262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
21362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Provides a SparseInputMask representing a dense input set.
21462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static SparseInputMask Dense() { return SparseInputMask(kDenseBitMask); }
21562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
21662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BitMaskType mask() const { return bit_mask_; }
21762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
21862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool IsDense() const { return bit_mask_ == SparseInputMask::kDenseBitMask; }
21962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
22062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Counts how many real values are in the sparse array. Only valid for
22162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // non-dense masks.
22262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int CountReal() const;
22362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
22462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Returns an iterator over the sparse inputs of {node}.
22562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  InputIterator IterateOverInputs(Node* node);
22662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
22762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch private:
22862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //
22962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // The sparse input mask has a bitmask specifying if the node's inputs are
23062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // represented sparsely. If the bitmask value is 0, then the inputs are dense;
23162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // otherwise, they should be interpreted as follows:
23262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //
23362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //   * The bitmask represents which values are real, with 1 for real values
23462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //     and 0 for empty values.
23562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //   * The inputs to the node are the real values, in the order of the 1s from
23662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //     least- to most-significant.
23762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //   * The top bit of the bitmask is a guard indicating the end of the values,
23862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //     whether real or empty (and is not representative of a real input
23962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //     itself). This is used so that we don't have to additionally store a
24062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //     value count.
24162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  //
24262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // So, for N 1s in the bitmask, there are N - 1 inputs into the node.
24362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BitMaskType bit_mask_;
24462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch};
24562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
24662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool operator==(SparseInputMask const& lhs, SparseInputMask const& rhs);
24762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool operator!=(SparseInputMask const& lhs, SparseInputMask const& rhs);
24862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
24962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass TypedStateValueInfo final {
25062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public:
25162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  TypedStateValueInfo(ZoneVector<MachineType> const* machine_types,
25262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                      SparseInputMask sparse_input_mask)
25362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      : machine_types_(machine_types), sparse_input_mask_(sparse_input_mask) {}
25462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
25562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ZoneVector<MachineType> const* machine_types() const {
25662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return machine_types_;
25762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
25862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  SparseInputMask sparse_input_mask() const { return sparse_input_mask_; }
25962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
26062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch private:
26162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ZoneVector<MachineType> const* machine_types_;
26262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  SparseInputMask sparse_input_mask_;
26362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch};
26462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
26562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool operator==(TypedStateValueInfo const& lhs, TypedStateValueInfo const& rhs);
26662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool operator!=(TypedStateValueInfo const& lhs, TypedStateValueInfo const& rhs);
26762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
26862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochstd::ostream& operator<<(std::ostream&, TypedStateValueInfo const&);
26962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
27062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochsize_t hash_value(TypedStateValueInfo const& p);
27162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
27213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Used to mark a region (as identified by BeginRegion/FinishRegion) as either
27313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// JavaScript-observable or not (i.e. allocations are not JavaScript observable
27413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// themselves, but transitioning stores are).
27513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochenum class RegionObservability : uint8_t { kObservable, kNotObservable };
27613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
27713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochsize_t hash_value(RegionObservability);
27813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
27913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochstd::ostream& operator<<(std::ostream&, RegionObservability);
28013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
28113e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochRegionObservability RegionObservabilityOf(Operator const*) WARN_UNUSED_RESULT;
28213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
28313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochstd::ostream& operator<<(std::ostream& os,
28413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                         const ZoneVector<MachineType>* types);
28513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
286f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochType* TypeGuardTypeOf(Operator const*) WARN_UNUSED_RESULT;
287f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
288c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochint OsrValueIndexOf(Operator const*);
289c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
290c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochenum class OsrGuardType { kUninitialized, kSignedSmall, kAny };
291c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochsize_t hash_value(OsrGuardType type);
292c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstd::ostream& operator<<(std::ostream&, OsrGuardType);
293c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochOsrGuardType OsrGuardTypeOf(Operator const*);
294c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
29562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochSparseInputMask SparseInputMaskOf(Operator const*);
29662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
297c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochZoneVector<MachineType> const* MachineTypesOf(Operator const*)
298c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    WARN_UNUSED_RESULT;
299c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Interface for building common operators that can be used at any level of IR,
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// including JavaScript, mid-level, and low-level.
302c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass V8_EXPORT_PRIVATE CommonOperatorBuilder final
303c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    : public NON_EXPORTED_BASE(ZoneObject) {
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit CommonOperatorBuilder(Zone* zone);
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* Dead();
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* End(size_t control_input_count);
309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const Operator* Branch(BranchHint = BranchHint::kNone);
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* IfTrue();
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* IfFalse();
312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* IfSuccess();
313f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Operator* IfException();
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* Switch(size_t control_output_count);
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* IfValue(int32_t value);
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* IfDefault();
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* Throw();
318f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Operator* Deoptimize(DeoptimizeKind kind, DeoptimizeReason reason);
31962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  const Operator* DeoptimizeIf(DeoptimizeKind kind, DeoptimizeReason reason);
32062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  const Operator* DeoptimizeUnless(DeoptimizeKind kind,
32162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                   DeoptimizeReason reason);
32262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  const Operator* TrapIf(int32_t trap_id);
32362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  const Operator* TrapUnless(int32_t trap_id);
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* Return(int value_input_count = 1);
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* Terminate();
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* Start(int value_output_count);
328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const Operator* Loop(int control_input_count);
329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const Operator* Merge(int control_input_count);
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* Parameter(int index, const char* debug_name = nullptr);
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* OsrNormalEntry();
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* OsrLoopEntry();
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* OsrValue(int index);
335c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  const Operator* OsrGuard(OsrGuardType type);
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* Int32Constant(int32_t);
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* Int64Constant(int64_t);
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* Float32Constant(volatile float);
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* Float64Constant(volatile double);
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* ExternalConstant(const ExternalReference&);
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* NumberConstant(volatile double);
343c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  const Operator* PointerConstant(intptr_t);
344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* HeapConstant(const Handle<HeapObject>&);
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
346bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  const Operator* RelocatableInt32Constant(int32_t value,
347bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                           RelocInfo::Mode rmode);
348bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  const Operator* RelocatableInt64Constant(int64_t value,
349bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                           RelocInfo::Mode rmode);
350bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* Select(MachineRepresentation, BranchHint = BranchHint::kNone);
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* Phi(MachineRepresentation representation,
353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      int value_input_count);
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* EffectPhi(int effect_input_count);
355f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Operator* InductionVariablePhi(int value_input_count);
356f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Operator* LoopExit();
357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Operator* LoopExitValue();
358f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Operator* LoopExitEffect();
35913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  const Operator* Checkpoint();
36013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  const Operator* BeginRegion(RegionObservability);
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* FinishRegion();
36262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  const Operator* StateValues(int arguments, SparseInputMask bitmask);
36362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  const Operator* TypedStateValues(const ZoneVector<MachineType>* types,
36462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                   SparseInputMask bitmask);
36562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  const Operator* ArgumentsObjectState();
366c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  const Operator* ObjectState(int pointer_slots);
367c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  const Operator* TypedObjectState(const ZoneVector<MachineType>* types);
368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* FrameState(BailoutId bailout_id,
369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             OutputFrameStateCombine state_combine,
370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             const FrameStateFunctionInfo* function_info);
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* Call(const CallDescriptor* descriptor);
372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* TailCall(const CallDescriptor* descriptor);
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* Projection(size_t index);
374f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Operator* Retain();
375f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Operator* TypeGuard(Type* type);
376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Constructs a new merge or phi operator with the same opcode as {op}, but
378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // with {size} inputs.
379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Operator* ResizeMergeOrPhi(const Operator* op, int size);
380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Constructs function info for frame state construction.
382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const FrameStateFunctionInfo* CreateFrameStateFunctionInfo(
383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FrameStateType type, int parameter_count, int local_count,
384109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Handle<SharedFunctionInfo> shared_info);
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone() const { return zone_; }
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const CommonOperatorGlobalCache& cache_;
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* const zone_;
391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DISALLOW_COPY_AND_ASSIGN(CommonOperatorBuilder);
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace compiler
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace internal
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_COMPILER_COMMON_OPERATOR_H_
400