// Copyright 2017 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_JS_TYPE_HINT_LOWERING_H_
#define V8_COMPILER_JS_TYPE_HINT_LOWERING_H_

#include "src/base/flags.h"
#include "src/compiler/graph-reducer.h"
#include "src/deoptimizer/deoptimize-reason.h"
#include "src/handles/handles.h"

namespace v8 {
namespace internal {

// Forward declarations.
class FeedbackSlot;

namespace compiler {

// Forward declarations.
class JSGraph;
class Node;
class Operator;

// The type-hint lowering consumes feedback about high-level operations in order
// to potentially emit nodes using speculative simplified operators in favor of
// the generic JavaScript operators.
//
// This lowering is implemented as an early reduction and can be applied before
// nodes are placed into the initial graph. It provides the ability to shortcut
// the JavaScript-level operators and directly emit simplified-level operators
// even during initial graph building. This is the reason this lowering doesn't
// follow the interface of the reducer framework used after graph construction.
// The result of the lowering is encapsulated in
// {the JSTypeHintLowering::LoweringResult} class.
class JSTypeHintLowering {
 public:
  // Flags that control the mode of operation.
  enum Flag { kNoFlags = 0u, kBailoutOnUninitialized = 1u << 1 };
  using Flags = base::Flags<Flag>;

  JSTypeHintLowering(JSHeapBroker* broker, JSGraph* jsgraph,
                     FeedbackVectorRef feedback_vector, Flags flags);
  JSTypeHintLowering(const JSTypeHintLowering&) = delete;
  JSTypeHintLowering& operator=(const JSTypeHintLowering&) = delete;

  // {LoweringResult} describes the result of lowering. The following outcomes
  // are possible:
  //
  // - operation was lowered to a side-effect-free operation, the resulting
  //   value, effect and control can be obtained by the {value}, {effect} and
  //   {control} methods.
  //
  // - operation was lowered to a graph exit (deoptimization). The caller
  //   should connect {effect} and {control} nodes to the end.
  //
  // - no lowering happened. The caller needs to create the generic version
  //   of the operation.
  class LoweringResult {
   public:
    Node* value() const { return value_; }
    Node* effect() const { return effect_; }
    Node* control() const { return control_; }

    bool Changed() const { return kind_ != LoweringResultKind::kNoChange; }
    bool IsExit() const { return kind_ == LoweringResultKind::kExit; }
    bool IsSideEffectFree() const {
      return kind_ == LoweringResultKind::kSideEffectFree;
    }

    static LoweringResult SideEffectFree(Node* value, Node* effect,
                                         Node* control) {
      DCHECK_NOT_NULL(effect);
      DCHECK_NOT_NULL(control);
      DCHECK(value->op()->HasProperty(Operator::kNoThrow));
      return LoweringResult(LoweringResultKind::kSideEffectFree, value, effect,
                            control);
    }

    static LoweringResult NoChange() {
      return LoweringResult(LoweringResultKind::kNoChange, nullptr, nullptr,
                            nullptr);
    }

    static LoweringResult Exit(Node* control) {
      return LoweringResult(LoweringResultKind::kExit, nullptr, nullptr,
                            control);
    }

   private:
    enum class LoweringResultKind { kNoChange, kSideEffectFree, kExit };

    LoweringResult(LoweringResultKind kind, Node* value, Node* effect,
                   Node* control)
        : kind_(kind), value_(value), effect_(effect), control_(control) {}

    LoweringResultKind kind_;
    Node* value_;
    Node* effect_;
    Node* control_;
  };

  // Potential reduction of unary operations (e.g. negation).
  LoweringResult ReduceUnaryOperation(const Operator* op, Node* operand,
                                      Node* effect, Node* control,
                                      FeedbackSlot slot) const;

  // Potential reduction of binary (arithmetic, logical, shift and relational
  // comparison) operations.
  LoweringResult ReduceBinaryOperation(const Operator* op, Node* left,
                                       Node* right, Node* effect, Node* control,
                                       FeedbackSlot slot) const;

  // Potential reduction to for..in operations
  LoweringResult ReduceForInNextOperation(Node* receiver, Node* cache_array,
                                          Node* cache_type, Node* index,
                                          Node* effect, Node* control,
                                          FeedbackSlot slot) const;
  LoweringResult ReduceForInPrepareOperation(Node* enumerator, Node* effect,
                                             Node* control,
                                             FeedbackSlot slot) const;

  // Potential reduction to ToNumber operations
  LoweringResult ReduceToNumberOperation(Node* value, Node* effect,
                                         Node* control,
                                         FeedbackSlot slot) const;

  // Potential reduction of call operations.
  LoweringResult ReduceCallOperation(const Operator* op, Node* const* args,
                                     int arg_count, Node* effect, Node* control,
                                     FeedbackSlot slot) const;

  // Potential reduction of construct operations.
  LoweringResult ReduceConstructOperation(const Operator* op, Node* const* args,
                                          int arg_count, Node* effect,
                                          Node* control,
                                          FeedbackSlot slot) const;

  // Potential reduction of property access and call operations.
  LoweringResult ReduceGetIteratorOperation(const Operator* op, Node* obj,
                                            Node* effect, Node* control,
                                            FeedbackSlot load_slot,
                                            FeedbackSlot call_slot) const;

  // Potential reduction of property access operations.
  LoweringResult ReduceLoadNamedOperation(const Operator* op, Node* effect,
                                          Node* control,
                                          FeedbackSlot slot) const;
  LoweringResult ReduceLoadKeyedOperation(const Operator* op, Node* obj,
                                          Node* key, Node* effect,
                                          Node* control,
                                          FeedbackSlot slot) const;
  LoweringResult ReduceStoreNamedOperation(const Operator* op, Node* obj,
                                           Node* val, Node* effect,
                                           Node* control,
                                           FeedbackSlot slot) const;
  LoweringResult ReduceStoreKeyedOperation(const Operator* op, Node* obj,
                                           Node* key, Node* val, Node* effect,
                                           Node* control,
                                           FeedbackSlot slot) const;

 private:
  friend class JSSpeculativeBinopBuilder;

  BinaryOperationHint GetBinaryOperationHint(FeedbackSlot slot) const;
  CompareOperationHint GetCompareOperationHint(FeedbackSlot slot) const;
  Node* TryBuildSoftDeopt(FeedbackSlot slot, Node* effect, Node* control,
                          DeoptimizeReason reson) const;

  JSHeapBroker* broker() const { return broker_; }
  JSGraph* jsgraph() const { return jsgraph_; }
  Isolate* isolate() const;
  Flags flags() const { return flags_; }
  FeedbackVectorRef const& feedback_vector() const { return feedback_vector_; }

  JSHeapBroker* const broker_;
  JSGraph* const jsgraph_;
  Flags const flags_;
  FeedbackVectorRef const feedback_vector_;
};

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

#endif  // V8_COMPILER_JS_TYPE_HINT_LOWERING_H_
