17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Copyright 2013 the V8 project authors. All rights reserved.
27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// found in the LICENSE file.
47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
57d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifndef V8_COMPILER_OPERATOR_H_
67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define V8_COMPILER_OPERATOR_H_
77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org#include "src/base/flags.h"
97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/ostreams.h"
107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/unique.h"
117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace v8 {
137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace internal {
147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace compiler {
157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// An operator represents description of the "computation" of a node in the
177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// compiler IR. A computation takes values (i.e. data) as input and produces
187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// zero or more values as output. The side-effects of a computation must be
197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// captured by additional control and data dependencies which are part of the
207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// IR graph.
217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Operators are immutable and describe the statically-known parts of a
227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// computation. Thus they can be safely shared by many different nodes in the
237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// IR graph, or even globally between graphs. Operators can have "static
247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// parameters" which are compile-time constant parameters to the operator, such
257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// as the name for a named field access, the ID of a runtime function, etc.
267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Static parameters are private to the operator and only semantically
277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// meaningful to the operator itself.
287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass Operator : public ZoneObject {
297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
3021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  typedef uint8_t Opcode;
317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Properties inform the operator-independent optimizer about legal
337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // transformations for nodes that have this operator.
347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  enum Property {
357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    kNoProperties = 0,
367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    kReducible = 1 << 0,    // Participates in strength reduction.
377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    kCommutative = 1 << 1,  // OP(a, b) == OP(b, a) for all inputs.
387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    kAssociative = 1 << 2,  // OP(a, OP(b,c)) == OP(OP(a,b), c) for all inputs.
397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    kIdempotent = 1 << 3,   // OP(a); OP(a) == OP(a).
407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    kNoRead = 1 << 4,       // Has no scheduling dependency on Effects
417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    kNoWrite = 1 << 5,      // Does not modify any Effects and thereby
427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                            // create new scheduling dependencies.
437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    kNoThrow = 1 << 6,      // Can never generate an exception.
447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    kFoldable = kNoRead | kNoWrite,
457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    kEliminatable = kNoWrite | kNoThrow,
467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    kPure = kNoRead | kNoWrite | kNoThrow | kIdempotent
477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  };
4821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  typedef base::Flags<Property, uint8_t> Properties;
4921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org
5021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  Operator(Opcode opcode, Properties properties, const char* mnemonic)
5121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org      : opcode_(opcode), properties_(properties), mnemonic_(mnemonic) {}
5221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  virtual ~Operator();
537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // A small integer unique to all instances of a particular kind of operator,
557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // useful for quick matching for specific kinds of operators. For fast access
567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // the opcode is stored directly in the operator object.
5721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  Opcode opcode() const { return opcode_; }
587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Returns a constant string representing the mnemonic of the operator,
607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // without the static parameters. Useful for debugging.
6121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  const char* mnemonic() const { return mnemonic_; }
627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Check if this operator equals another operator. Equivalent operators can
647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // be merged, and nodes with equivalent operators and equivalent inputs
657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // can be merged.
6621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  virtual bool Equals(const Operator* other) const = 0;
677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Compute a hashcode to speed up equivalence-set checking.
697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Equal operators should always have equal hashcodes, and unequal operators
707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // should have unequal hashcodes with high probability.
7121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  virtual int HashCode() const = 0;
727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Check whether this operator has the given property.
7421d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  bool HasProperty(Property property) const {
7521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    return (properties() & property) == property;
767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Number of data inputs to the operator, for verifying graph structure.
7921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  virtual int InputCount() const = 0;
807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Number of data outputs from the operator, for verifying graph structure.
8221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  virtual int OutputCount() const = 0;
837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
8421d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  Properties properties() const { return properties_; }
857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // TODO(titzer): API for input and output types, for typechecking graph.
8721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org protected:
887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Print the full operator into the given stream, including any
897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // static parameters. Useful for debugging and visualizing the IR.
907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  virtual OStream& PrintTo(OStream& os) const = 0;  // NOLINT
917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  friend OStream& operator<<(OStream& os, const Operator& op);
927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
9321d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org private:
9421d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  Opcode opcode_;
9521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  Properties properties_;
9621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  const char* mnemonic_;
9721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org
9821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  DISALLOW_COPY_AND_ASSIGN(Operator);
997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
1007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
10121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.orgDEFINE_OPERATORS_FOR_FLAGS(Operator::Properties)
10221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org
1037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgOStream& operator<<(OStream& os, const Operator& op);
1047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// An implementation of Operator that has no static parameters. Such operators
1067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// have just a name, an opcode, and a fixed number of inputs and outputs.
1077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// They can represented by singletons and shared globally.
1086313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.orgclass SimpleOperator : public Operator {
1097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
11021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  SimpleOperator(Opcode opcode, Properties properties, int input_count,
11121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org                 int output_count, const char* mnemonic);
11221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  ~SimpleOperator();
1137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1146313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  virtual bool Equals(const Operator* that) const FINAL {
11521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    return opcode() == that->opcode();
11621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  }
1176313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  virtual int HashCode() const FINAL { return opcode(); }
1186313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  virtual int InputCount() const FINAL { return input_count_; }
1196313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  virtual int OutputCount() const FINAL { return output_count_; }
1207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private:
1226313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  virtual OStream& PrintTo(OStream& os) const FINAL {  // NOLINT
12321d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    return os << mnemonic();
1247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int input_count_;
1277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int output_count_;
12821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org
12921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  DISALLOW_COPY_AND_ASSIGN(SimpleOperator);
1307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
1317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Template specialization implements a kind of type class for dealing with the
1337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// static parameters of Operator1 automatically.
1347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtemplate <typename T>
1357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstruct StaticParameterTraits {
1367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static OStream& PrintTo(OStream& os, T val) {  // NOLINT
1377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return os << "??";
1387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static int HashCode(T a) { return 0; }
1407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static bool Equals(T a, T b) {
1417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return false;  // Not every T has a ==. By default, be conservative.
1427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
1447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Specialization for static parameters of type {int}.
1467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtemplate <>
1477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstruct StaticParameterTraits<int> {
1487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static OStream& PrintTo(OStream& os, int val) {  // NOLINT
1497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return os << val;
1507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static int HashCode(int a) { return a; }
1527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static bool Equals(int a, int b) { return a == b; }
1537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
1547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Specialization for static parameters of type {double}.
1567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtemplate <>
1577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstruct StaticParameterTraits<double> {
1587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static OStream& PrintTo(OStream& os, double val) {  // NOLINT
1597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return os << val;
1607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static int HashCode(double a) {
162e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org    return static_cast<int>(bit_cast<int64_t>(a));
1637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static bool Equals(double a, double b) {
165e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org    return bit_cast<int64_t>(a) == bit_cast<int64_t>(b);
1667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
1687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1691af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org// Specialization for static parameters of type {Unique<Object>}.
1707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtemplate <>
1711af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orgstruct StaticParameterTraits<Unique<Object> > {
1721af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org  static OStream& PrintTo(OStream& os, Unique<Object> val) {  // NOLINT
1731af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org    return os << Brief(*val.handle());
1747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1751af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org  static int HashCode(Unique<Object> a) {
1767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return static_cast<int>(a.Hashcode());
1777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1781af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org  static bool Equals(Unique<Object> a, Unique<Object> b) { return a == b; }
1797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
1807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1811af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org// Specialization for static parameters of type {Unique<Name>}.
1827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtemplate <>
1831af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orgstruct StaticParameterTraits<Unique<Name> > {
1841af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org  static OStream& PrintTo(OStream& os, Unique<Name> val) {  // NOLINT
1851af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org    return os << Brief(*val.handle());
1867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1871af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org  static int HashCode(Unique<Name> a) { return static_cast<int>(a.Hashcode()); }
1881af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org  static bool Equals(Unique<Name> a, Unique<Name> b) { return a == b; }
1897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
1907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#if DEBUG
1927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Specialization for static parameters of type {Handle<Object>} to prevent any
1937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// direct usage of Handles in constants.
1947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtemplate <>
1957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstruct StaticParameterTraits<Handle<Object> > {
1967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static OStream& PrintTo(OStream& os, Handle<Object> val) {  // NOLINT
1971af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org    UNREACHABLE();  // Should use Unique<Object> instead
1987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return os;
1997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static int HashCode(Handle<Object> a) {
2011af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org    UNREACHABLE();  // Should use Unique<Object> instead
2027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return 0;
2037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static bool Equals(Handle<Object> a, Handle<Object> b) {
2051af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org    UNREACHABLE();  // Should use Unique<Object> instead
2067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return false;
2077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
2097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif
2107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// A templatized implementation of Operator that has one static parameter of
2127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// type {T}. If a specialization of StaticParameterTraits<{T}> exists, then
2137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// operators of this kind can automatically be hashed, compared, and printed.
2147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtemplate <typename T>
2157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass Operator1 : public Operator {
2167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
21721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  Operator1(Opcode opcode, Properties properties, int input_count,
2187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org            int output_count, const char* mnemonic, T parameter)
21921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org      : Operator(opcode, properties, mnemonic),
2207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        input_count_(input_count),
2217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        output_count_(output_count),
2227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        parameter_(parameter) {}
2237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  const T& parameter() const { return parameter_; }
2257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
22621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  virtual bool Equals(const Operator* other) const OVERRIDE {
2277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (opcode() != other->opcode()) return false;
22821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    const Operator1<T>* that = static_cast<const Operator1<T>*>(other);
22921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    return StaticParameterTraits<T>::Equals(this->parameter_, that->parameter_);
2307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
23121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  virtual int HashCode() const OVERRIDE {
2327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return opcode() + 33 * StaticParameterTraits<T>::HashCode(this->parameter_);
2337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
23421d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  virtual int InputCount() const OVERRIDE { return input_count_; }
23521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  virtual int OutputCount() const OVERRIDE { return output_count_; }
2367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  virtual OStream& PrintParameter(OStream& os) const {  // NOLINT
2377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return StaticParameterTraits<T>::PrintTo(os << "[", parameter_) << "]";
2387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
24021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org protected:
24121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  virtual OStream& PrintTo(OStream& os) const FINAL {  // NOLINT
24221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    return PrintParameter(os << mnemonic());
2437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
24521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org private:
2467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int input_count_;
2477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int output_count_;
2487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  T parameter_;
2497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
2507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2511af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org
2521af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org// Helper to extract parameters from Operator1<*> operator.
2531af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orgtemplate <typename T>
254e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.orgstatic inline const T& OpParameter(const Operator* op) {
2551af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org  return reinterpret_cast<const Operator1<T>*>(op)->parameter();
2561af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org}
25721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org
25821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org}  // namespace compiler
25921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org}  // namespace internal
26021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org}  // namespace v8
2617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif  // V8_COMPILER_OPERATOR_H_
263