// Copyright 2013 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_OPERATOR_H_
#define V8_COMPILER_OPERATOR_H_

#include <ostream>  // NOLINT(readability/streams)

#include "src/base/compiler-specific.h"
#include "src/base/flags.h"
#include "src/base/functional.h"
#include "src/globals.h"
#include "src/handles.h"
#include "src/zone/zone.h"

namespace v8 {
namespace internal {
namespace compiler {

// An operator represents description of the "computation" of a node in the
// compiler IR. A computation takes values (i.e. data) as input and produces
// zero or more values as output. The side-effects of a computation must be
// captured by additional control and data dependencies which are part of the
// IR graph.
// Operators are immutable and describe the statically-known parts of a
// computation. Thus they can be safely shared by many different nodes in the
// IR graph, or even globally between graphs. Operators can have "static
// parameters" which are compile-time constant parameters to the operator, such
// as the name for a named field access, the ID of a runtime function, etc.
// Static parameters are private to the operator and only semantically
// meaningful to the operator itself.
class V8_EXPORT_PRIVATE Operator : public NON_EXPORTED_BASE(ZoneObject) {
 public:
  typedef uint16_t Opcode;

  // Properties inform the operator-independent optimizer about legal
  // transformations for nodes that have this operator.
  enum Property {
    kNoProperties = 0,
    kCommutative = 1 << 0,  // OP(a, b) == OP(b, a) for all inputs.
    kAssociative = 1 << 1,  // OP(a, OP(b,c)) == OP(OP(a,b), c) for all inputs.
    kIdempotent = 1 << 2,   // OP(a); OP(a) == OP(a).
    kNoRead = 1 << 3,       // Has no scheduling dependency on Effects
    kNoWrite = 1 << 4,      // Does not modify any Effects and thereby
                            // create new scheduling dependencies.
    kNoThrow = 1 << 5,      // Can never generate an exception.
    kNoDeopt = 1 << 6,      // Can never generate an eager deoptimization exit.
    kFoldable = kNoRead | kNoWrite,
    kKontrol = kNoDeopt | kFoldable | kNoThrow,
    kEliminatable = kNoDeopt | kNoWrite | kNoThrow,
    kPure = kNoDeopt | kNoRead | kNoWrite | kNoThrow | kIdempotent
  };

// List of all bits, for the visualizer.
#define OPERATOR_PROPERTY_LIST(V) \
  V(Commutative)                  \
  V(Associative) V(Idempotent) V(NoRead) V(NoWrite) V(NoThrow) V(NoDeopt)

  typedef base::Flags<Property, uint8_t> Properties;
  enum class PrintVerbosity { kVerbose, kSilent };

  // Constructor.
  Operator(Opcode opcode, Properties properties, const char* mnemonic,
           size_t value_in, size_t effect_in, size_t control_in,
           size_t value_out, size_t effect_out, size_t control_out);

  virtual ~Operator() {}

  // A small integer unique to all instances of a particular kind of operator,
  // useful for quick matching for specific kinds of operators. For fast access
  // the opcode is stored directly in the operator object.
  Opcode opcode() const { return opcode_; }

  // Returns a constant string representing the mnemonic of the operator,
  // without the static parameters. Useful for debugging.
  const char* mnemonic() const { return mnemonic_; }

  // Check if this operator equals another operator. Equivalent operators can
  // be merged, and nodes with equivalent operators and equivalent inputs
  // can be merged.
  virtual bool Equals(const Operator* that) const {
    return this->opcode() == that->opcode();
  }

  // Compute a hashcode to speed up equivalence-set checking.
  // Equal operators should always have equal hashcodes, and unequal operators
  // should have unequal hashcodes with high probability.
  virtual size_t HashCode() const { return base::hash<Opcode>()(opcode()); }

  // Check whether this operator has the given property.
  bool HasProperty(Property property) const {
    return (properties() & property) == property;
  }

  Properties properties() const { return properties_; }

  // TODO(titzer): convert return values here to size_t.
  int ValueInputCount() const { return value_in_; }
  int EffectInputCount() const { return effect_in_; }
  int ControlInputCount() const { return control_in_; }

  int ValueOutputCount() const { return value_out_; }
  int EffectOutputCount() const { return effect_out_; }
  int ControlOutputCount() const { return control_out_; }

  static size_t ZeroIfEliminatable(Properties properties) {
    return (properties & kEliminatable) == kEliminatable ? 0 : 1;
  }

  static size_t ZeroIfNoThrow(Properties properties) {
    return (properties & kNoThrow) == kNoThrow ? 0 : 2;
  }

  static size_t ZeroIfPure(Properties properties) {
    return (properties & kPure) == kPure ? 0 : 1;
  }

  // TODO(titzer): API for input and output types, for typechecking graph.

  // Print the full operator into the given stream, including any
  // static parameters. Useful for debugging and visualizing the IR.
  void PrintTo(std::ostream& os,
               PrintVerbosity verbose = PrintVerbosity::kVerbose) const {
    // We cannot make PrintTo virtual, because default arguments to virtual
    // methods are banned in the style guide.
    return PrintToImpl(os, verbose);
  }

  void PrintPropsTo(std::ostream& os) const;

 protected:
  virtual void PrintToImpl(std::ostream& os, PrintVerbosity verbose) const;

 private:
  const char* mnemonic_;
  Opcode opcode_;
  Properties properties_;
  uint32_t value_in_;
  uint16_t effect_in_;
  uint16_t control_in_;
  uint32_t value_out_;
  uint8_t effect_out_;
  uint32_t control_out_;

  DISALLOW_COPY_AND_ASSIGN(Operator);
};

DEFINE_OPERATORS_FOR_FLAGS(Operator::Properties)

std::ostream& operator<<(std::ostream& os, const Operator& op);


// Default equality function for below Operator1<*> class.
template <typename T>
struct OpEqualTo : public std::equal_to<T> {};


// Default hashing function for below Operator1<*> class.
template <typename T>
struct OpHash : public base::hash<T> {};


// A templatized implementation of Operator that has one static parameter of
// type {T} with the proper default equality and hashing functions.
template <typename T, typename Pred = OpEqualTo<T>, typename Hash = OpHash<T>>
class Operator1 : public Operator {
 public:
  Operator1(Opcode opcode, Properties properties, const char* mnemonic,
            size_t value_in, size_t effect_in, size_t control_in,
            size_t value_out, size_t effect_out, size_t control_out,
            T parameter, Pred const& pred = Pred(), Hash const& hash = Hash())
      : Operator(opcode, properties, mnemonic, value_in, effect_in, control_in,
                 value_out, effect_out, control_out),
        parameter_(parameter),
        pred_(pred),
        hash_(hash) {}

  T const& parameter() const { return parameter_; }

  bool Equals(const Operator* other) const final {
    if (opcode() != other->opcode()) return false;
    const Operator1<T, Pred, Hash>* that =
        reinterpret_cast<const Operator1<T, Pred, Hash>*>(other);
    return this->pred_(this->parameter(), that->parameter());
  }
  size_t HashCode() const final {
    return base::hash_combine(this->opcode(), this->hash_(this->parameter()));
  }
  // For most parameter types, we have only a verbose way to print them, namely
  // ostream << parameter. But for some types it is particularly useful to have
  // a shorter way to print them for the node labels in Turbolizer. The
  // following method can be overridden to provide a concise and a verbose
  // printing of a parameter.

  virtual void PrintParameter(std::ostream& os, PrintVerbosity verbose) const {
    os << "[" << parameter() << "]";
  }

  virtual void PrintToImpl(std::ostream& os, PrintVerbosity verbose) const {
    os << mnemonic();
    PrintParameter(os, verbose);
  }

 private:
  T const parameter_;
  Pred const pred_;
  Hash const hash_;
};


// Helper to extract parameters from Operator1<*> operator.
template <typename T>
inline T const& OpParameter(const Operator* op) {
  return reinterpret_cast<const Operator1<T, OpEqualTo<T>, OpHash<T>>*>(op)
      ->parameter();
}


// NOTE: We have to be careful to use the right equal/hash functions below, for
// float/double we always use the ones operating on the bit level, for Handle<>
// we always use the ones operating on the location level.
template <>
struct OpEqualTo<float> : public base::bit_equal_to<float> {};
template <>
struct OpHash<float> : public base::bit_hash<float> {};

template <>
struct OpEqualTo<double> : public base::bit_equal_to<double> {};
template <>
struct OpHash<double> : public base::bit_hash<double> {};

template <>
struct OpEqualTo<Handle<HeapObject>> : public Handle<HeapObject>::equal_to {};
template <>
struct OpHash<Handle<HeapObject>> : public Handle<HeapObject>::hash {};

template <>
struct OpEqualTo<Handle<String>> : public Handle<String>::equal_to {};
template <>
struct OpHash<Handle<String>> : public Handle<String>::hash {};

template <>
struct OpEqualTo<Handle<ScopeInfo>> : public Handle<ScopeInfo>::equal_to {};
template <>
struct OpHash<Handle<ScopeInfo>> : public Handle<ScopeInfo>::hash {};

}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_OPERATOR_H_
