// Copyright 2015 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.

#include "src/compiler/graph-assembler.h"

#include "src/code-factory.h"
#include "src/compiler/linkage.h"
#include "src/objects-inl.h"

namespace v8 {
namespace internal {
namespace compiler {

GraphAssembler::GraphAssembler(JSGraph* jsgraph, Node* effect, Node* control,
                               Zone* zone)
    : temp_zone_(zone),
      jsgraph_(jsgraph),
      current_effect_(effect),
      current_control_(control) {}

Node* GraphAssembler::IntPtrConstant(intptr_t value) {
  return jsgraph()->IntPtrConstant(value);
}

Node* GraphAssembler::Int32Constant(int32_t value) {
  return jsgraph()->Int32Constant(value);
}

Node* GraphAssembler::UniqueInt32Constant(int32_t value) {
  return graph()->NewNode(common()->Int32Constant(value));
}

Node* GraphAssembler::SmiConstant(int32_t value) {
  return jsgraph()->SmiConstant(value);
}

Node* GraphAssembler::Uint32Constant(int32_t value) {
  return jsgraph()->Uint32Constant(value);
}

Node* GraphAssembler::Float64Constant(double value) {
  return jsgraph()->Float64Constant(value);
}

Node* GraphAssembler::HeapConstant(Handle<HeapObject> object) {
  return jsgraph()->HeapConstant(object);
}


Node* GraphAssembler::ExternalConstant(ExternalReference ref) {
  return jsgraph()->ExternalConstant(ref);
}

Node* GraphAssembler::CEntryStubConstant(int result_size) {
  return jsgraph()->CEntryStubConstant(result_size);
}

#define SINGLETON_CONST_DEF(Name) \
  Node* GraphAssembler::Name() { return jsgraph()->Name(); }
JSGRAPH_SINGLETON_CONSTANT_LIST(SINGLETON_CONST_DEF)
#undef SINGLETON_CONST_DEF

#define PURE_UNOP_DEF(Name)                            \
  Node* GraphAssembler::Name(Node* input) {            \
    return graph()->NewNode(machine()->Name(), input); \
  }
PURE_ASSEMBLER_MACH_UNOP_LIST(PURE_UNOP_DEF)
#undef PURE_UNOP_DEF

#define PURE_BINOP_DEF(Name)                                 \
  Node* GraphAssembler::Name(Node* left, Node* right) {      \
    return graph()->NewNode(machine()->Name(), left, right); \
  }
PURE_ASSEMBLER_MACH_BINOP_LIST(PURE_BINOP_DEF)
#undef PURE_BINOP_DEF

#define CHECKED_BINOP_DEF(Name)                                                \
  Node* GraphAssembler::Name(Node* left, Node* right) {                        \
    return graph()->NewNode(machine()->Name(), left, right, current_control_); \
  }
CHECKED_ASSEMBLER_MACH_BINOP_LIST(CHECKED_BINOP_DEF)
#undef CHECKED_BINOP_DEF

Node* GraphAssembler::Float64RoundDown(Node* value) {
  if (machine()->Float64RoundDown().IsSupported()) {
    return graph()->NewNode(machine()->Float64RoundDown().op(), value);
  }
  return nullptr;
}

Node* GraphAssembler::Projection(int index, Node* value) {
  return graph()->NewNode(common()->Projection(index), value, current_control_);
}

Node* GraphAssembler::Allocate(PretenureFlag pretenure, Node* size) {
  return current_effect_ =
             graph()->NewNode(simplified()->Allocate(NOT_TENURED), size,
                              current_effect_, current_control_);
}

Node* GraphAssembler::LoadField(FieldAccess const& access, Node* object) {
  return current_effect_ =
             graph()->NewNode(simplified()->LoadField(access), object,
                              current_effect_, current_control_);
}

Node* GraphAssembler::LoadElement(ElementAccess const& access, Node* object,
                                  Node* index) {
  return current_effect_ =
             graph()->NewNode(simplified()->LoadElement(access), object, index,
                              current_effect_, current_control_);
}

Node* GraphAssembler::StoreField(FieldAccess const& access, Node* object,
                                 Node* value) {
  return current_effect_ =
             graph()->NewNode(simplified()->StoreField(access), object, value,
                              current_effect_, current_control_);
}

Node* GraphAssembler::StoreElement(ElementAccess const& access, Node* object,
                                   Node* index, Node* value) {
  return current_effect_ =
             graph()->NewNode(simplified()->StoreElement(access), object, index,
                              value, current_effect_, current_control_);
}

Node* GraphAssembler::Store(StoreRepresentation rep, Node* object, Node* offset,
                            Node* value) {
  return current_effect_ =
             graph()->NewNode(machine()->Store(rep), object, offset, value,
                              current_effect_, current_control_);
}

Node* GraphAssembler::Load(MachineType rep, Node* object, Node* offset) {
  return current_effect_ =
             graph()->NewNode(machine()->Load(rep), object, offset,
                              current_effect_, current_control_);
}

Node* GraphAssembler::Retain(Node* buffer) {
  return current_effect_ =
             graph()->NewNode(common()->Retain(), buffer, current_effect_);
}

Node* GraphAssembler::UnsafePointerAdd(Node* base, Node* external) {
  return current_effect_ =
             graph()->NewNode(machine()->UnsafePointerAdd(), base, external,
                              current_effect_, current_control_);
}

Node* GraphAssembler::ToNumber(Node* value) {
  return current_effect_ =
             graph()->NewNode(ToNumberOperator(), ToNumberBuiltinConstant(),
                              value, NoContextConstant(), current_effect_);
}

Node* GraphAssembler::DeoptimizeIf(DeoptimizeReason reason, Node* condition,
                                   Node* frame_state) {
  return current_control_ = current_effect_ = graph()->NewNode(
             common()->DeoptimizeIf(DeoptimizeKind::kEager, reason), condition,
             frame_state, current_effect_, current_control_);
}

Node* GraphAssembler::DeoptimizeUnless(DeoptimizeKind kind,
                                       DeoptimizeReason reason, Node* condition,
                                       Node* frame_state) {
  return current_control_ = current_effect_ = graph()->NewNode(
             common()->DeoptimizeUnless(kind, reason), condition, frame_state,
             current_effect_, current_control_);
}

Node* GraphAssembler::DeoptimizeUnless(DeoptimizeReason reason, Node* condition,
                                       Node* frame_state) {
  return DeoptimizeUnless(DeoptimizeKind::kEager, reason, condition,
                          frame_state);
}

void GraphAssembler::Branch(Node* condition,
                            GraphAssemblerStaticLabel<1>* if_true,
                            GraphAssemblerStaticLabel<1>* if_false) {
  DCHECK_NOT_NULL(current_control_);

  BranchHint hint = BranchHint::kNone;
  if (if_true->IsDeferred() != if_false->IsDeferred()) {
    hint = if_false->IsDeferred() ? BranchHint::kTrue : BranchHint::kFalse;
  }

  Node* branch =
      graph()->NewNode(common()->Branch(hint), condition, current_control_);

  current_control_ = graph()->NewNode(common()->IfTrue(), branch);
  MergeState(if_true);

  current_control_ = graph()->NewNode(common()->IfFalse(), branch);
  MergeState(if_false);

  current_control_ = nullptr;
  current_effect_ = nullptr;
}

// Extractors (should be only used when destructing the assembler.
Node* GraphAssembler::ExtractCurrentControl() {
  Node* result = current_control_;
  current_control_ = nullptr;
  return result;
}

Node* GraphAssembler::ExtractCurrentEffect() {
  Node* result = current_effect_;
  current_effect_ = nullptr;
  return result;
}

void GraphAssembler::Reset(Node* effect, Node* control) {
  current_effect_ = effect;
  current_control_ = control;
}

Operator const* GraphAssembler::ToNumberOperator() {
  if (!to_number_operator_.is_set()) {
    Callable callable = CodeFactory::ToNumber(jsgraph()->isolate());
    CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
    CallDescriptor* desc = Linkage::GetStubCallDescriptor(
        jsgraph()->isolate(), graph()->zone(), callable.descriptor(), 0, flags,
        Operator::kEliminatable);
    to_number_operator_.set(common()->Call(desc));
  }
  return to_number_operator_.get();
}

Node* GraphAssemblerLabel::PhiAt(size_t index) {
  DCHECK(IsBound());
  return GetBindingsPtrFor(index)[0];
}

GraphAssemblerLabel::GraphAssemblerLabel(GraphAssemblerLabelType is_deferred,
                                         size_t merge_count, size_t var_count,
                                         MachineRepresentation* representations,
                                         Zone* zone)
    : is_deferred_(is_deferred == GraphAssemblerLabelType::kDeferred),
      max_merge_count_(merge_count),
      var_count_(var_count) {
  effects_ = zone->NewArray<Node*>(MaxMergeCount() + 1);
  for (size_t i = 0; i < MaxMergeCount() + 1; i++) {
    effects_[i] = nullptr;
  }

  controls_ = zone->NewArray<Node*>(MaxMergeCount());
  for (size_t i = 0; i < MaxMergeCount(); i++) {
    controls_[i] = nullptr;
  }

  size_t num_bindings = (MaxMergeCount() + 1) * PhiCount() + 1;
  bindings_ = zone->NewArray<Node*>(num_bindings);
  for (size_t i = 0; i < num_bindings; i++) {
    bindings_[i] = nullptr;
  }

  representations_ = zone->NewArray<MachineRepresentation>(PhiCount() + 1);
  for (size_t i = 0; i < PhiCount(); i++) {
    representations_[i] = representations[i];
  }
}

GraphAssemblerLabel::~GraphAssemblerLabel() {
  DCHECK(IsBound() || MergedCount() == 0);
}

Node** GraphAssemblerLabel::GetBindingsPtrFor(size_t phi_index) {
  DCHECK_LT(phi_index, PhiCount());
  return &bindings_[phi_index * (MaxMergeCount() + 1)];
}

void GraphAssemblerLabel::SetBinding(size_t phi_index, size_t merge_index,
                                     Node* binding) {
  DCHECK_LT(phi_index, PhiCount());
  DCHECK_LT(merge_index, MaxMergeCount());
  bindings_[phi_index * (MaxMergeCount() + 1) + merge_index] = binding;
}

MachineRepresentation GraphAssemblerLabel::GetRepresentationFor(
    size_t phi_index) {
  DCHECK_LT(phi_index, PhiCount());
  return representations_[phi_index];
}

Node** GraphAssemblerLabel::GetControlsPtr() { return controls_; }

Node** GraphAssemblerLabel::GetEffectsPtr() { return effects_; }

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