// Copyright 2014 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_GRAPH_H_
#define V8_COMPILER_JS_GRAPH_H_

#include "src/base/compiler-specific.h"
#include "src/compiler/common-node-cache.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/graph.h"
#include "src/compiler/js-operator.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/node-properties.h"
#include "src/globals.h"
#include "src/isolate.h"

namespace v8 {
namespace internal {
namespace compiler {

class SimplifiedOperatorBuilder;
class Typer;

// Implements a facade on a Graph, enhancing the graph with JS-specific
// notions, including various builders for operators, canonicalized global
// constants, and various helper methods.
class V8_EXPORT_PRIVATE JSGraph : public NON_EXPORTED_BASE(ZoneObject) {
 public:
  JSGraph(Isolate* isolate, Graph* graph, CommonOperatorBuilder* common,
          JSOperatorBuilder* javascript, SimplifiedOperatorBuilder* simplified,
          MachineOperatorBuilder* machine)
      : isolate_(isolate),
        graph_(graph),
        common_(common),
        javascript_(javascript),
        simplified_(simplified),
        machine_(machine),
        cache_(zone()) {
    for (int i = 0; i < kNumCachedNodes; i++) cached_nodes_[i] = nullptr;
  }

  // Canonicalized global constants.
  Node* AllocateInNewSpaceStubConstant();
  Node* AllocateInOldSpaceStubConstant();
  Node* ToNumberBuiltinConstant();
  Node* CEntryStubConstant(int result_size,
                           SaveFPRegsMode save_doubles = kDontSaveFPRegs,
                           ArgvMode argv_mode = kArgvOnStack,
                           bool builtin_exit_frame = false);
  Node* EmptyFixedArrayConstant();
  Node* EmptyStringConstant();
  Node* FixedArrayMapConstant();
  Node* FixedDoubleArrayMapConstant();
  Node* HeapNumberMapConstant();
  Node* OptimizedOutConstant();
  Node* StaleRegisterConstant();
  Node* UndefinedConstant();
  Node* TheHoleConstant();
  Node* TrueConstant();
  Node* FalseConstant();
  Node* NullConstant();
  Node* ZeroConstant();
  Node* OneConstant();
  Node* NaNConstant();

  // Creates a HeapConstant node, possibly canonicalized, and may access the
  // heap to inspect the object.
  Node* HeapConstant(Handle<HeapObject> value);

  // Creates a Constant node of the appropriate type for the given object.
  // Accesses the heap to inspect the object and determine whether one of the
  // canonicalized globals or a number constant should be returned.
  Node* Constant(Handle<Object> value);

  // Creates a NumberConstant node, usually canonicalized.
  Node* Constant(double value);

  // Creates a NumberConstant node, usually canonicalized.
  Node* Constant(int32_t value);

  // Creates a NumberConstant node, usually canonicalized.
  Node* Constant(uint32_t value);

  // Creates a Int32Constant node, usually canonicalized.
  Node* Int32Constant(int32_t value);
  Node* Uint32Constant(uint32_t value) {
    return Int32Constant(bit_cast<int32_t>(value));
  }

  // Creates a HeapConstant node for either true or false.
  Node* BooleanConstant(bool is_true) {
    return is_true ? TrueConstant() : FalseConstant();
  }

  // Creates a Int64Constant node, usually canonicalized.
  Node* Int64Constant(int64_t value);
  Node* Uint64Constant(uint64_t value) {
    return Int64Constant(bit_cast<int64_t>(value));
  }

  // Creates a Int32Constant/Int64Constant node, depending on the word size of
  // the target machine.
  // TODO(turbofan): Code using Int32Constant/Int64Constant to store pointer
  // constants is probably not serializable.
  Node* IntPtrConstant(intptr_t value) {
    return machine()->Is32() ? Int32Constant(static_cast<int32_t>(value))
                             : Int64Constant(static_cast<int64_t>(value));
  }

  Node* RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode);
  Node* RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode);
  Node* RelocatableIntPtrConstant(intptr_t value, RelocInfo::Mode rmode);

  // Creates a Float32Constant node, usually canonicalized.
  Node* Float32Constant(float value);

  // Creates a Float64Constant node, usually canonicalized.
  Node* Float64Constant(double value);

  // Creates a PointerConstant node (asm.js only).
  Node* PointerConstant(intptr_t value);
  template <typename T>
  Node* PointerConstant(T* value) {
    return PointerConstant(bit_cast<intptr_t>(value));
  }

  // Creates an ExternalConstant node, usually canonicalized.
  Node* ExternalConstant(ExternalReference ref);
  Node* ExternalConstant(Runtime::FunctionId function_id);

  Node* SmiConstant(int32_t immediate) {
    DCHECK(Smi::IsValid(immediate));
    return Constant(immediate);
  }

  // Creates a dummy Constant node, used to satisfy calling conventions of
  // stubs and runtime functions that do not require a context.
  Node* NoContextConstant() { return ZeroConstant(); }

  // Creates an empty StateValues node, used when we don't have any concrete
  // values for a certain part of the frame state.
  Node* EmptyStateValues();

  // Create a control node that serves as dependency for dead nodes.
  Node* Dead();

  CommonOperatorBuilder* common() const { return common_; }
  JSOperatorBuilder* javascript() const { return javascript_; }
  SimplifiedOperatorBuilder* simplified() const { return simplified_; }
  MachineOperatorBuilder* machine() const { return machine_; }
  Graph* graph() const { return graph_; }
  Zone* zone() const { return graph()->zone(); }
  Isolate* isolate() const { return isolate_; }
  Factory* factory() const { return isolate()->factory(); }

  void GetCachedNodes(NodeVector* nodes);

 private:
  enum CachedNode {
    kAllocateInNewSpaceStubConstant,
    kAllocateInOldSpaceStubConstant,
    kToNumberBuiltinConstant,
    kCEntryStub1Constant,
    kCEntryStub2Constant,
    kCEntryStub3Constant,
    kCEntryStub1WithBuiltinExitFrameConstant,
    kEmptyFixedArrayConstant,
    kEmptyStringConstant,
    kFixedArrayMapConstant,
    kFixedDoubleArrayMapConstant,
    kHeapNumberMapConstant,
    kOptimizedOutConstant,
    kStaleRegisterConstant,
    kUndefinedConstant,
    kTheHoleConstant,
    kTrueConstant,
    kFalseConstant,
    kNullConstant,
    kZeroConstant,
    kOneConstant,
    kNaNConstant,
    kEmptyStateValues,
    kDead,
    kNumCachedNodes  // Must remain last.
  };

  Isolate* isolate_;
  Graph* graph_;
  CommonOperatorBuilder* common_;
  JSOperatorBuilder* javascript_;
  SimplifiedOperatorBuilder* simplified_;
  MachineOperatorBuilder* machine_;
  CommonNodeCache cache_;
  Node* cached_nodes_[kNumCachedNodes];

  Node* NumberConstant(double value);

  DISALLOW_COPY_AND_ASSIGN(JSGraph);
};

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

#endif
