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

#include "src/compiler/change-lowering.h"

#include "src/code-factory.h"
#include "src/compiler/diamond.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/linkage.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/node-properties-inl.h"

namespace v8 {
namespace internal {
namespace compiler {

ChangeLowering::~ChangeLowering() {}


Reduction ChangeLowering::Reduce(Node* node) {
  Node* control = graph()->start();
  switch (node->opcode()) {
    case IrOpcode::kChangeBitToBool:
      return ChangeBitToBool(node->InputAt(0), control);
    case IrOpcode::kChangeBoolToBit:
      return ChangeBoolToBit(node->InputAt(0));
    case IrOpcode::kChangeFloat64ToTagged:
      return ChangeFloat64ToTagged(node->InputAt(0), control);
    case IrOpcode::kChangeInt32ToTagged:
      return ChangeInt32ToTagged(node->InputAt(0), control);
    case IrOpcode::kChangeTaggedToFloat64:
      return ChangeTaggedToFloat64(node->InputAt(0), control);
    case IrOpcode::kChangeTaggedToInt32:
      return ChangeTaggedToUI32(node->InputAt(0), control, kSigned);
    case IrOpcode::kChangeTaggedToUint32:
      return ChangeTaggedToUI32(node->InputAt(0), control, kUnsigned);
    case IrOpcode::kChangeUint32ToTagged:
      return ChangeUint32ToTagged(node->InputAt(0), control);
    default:
      return NoChange();
  }
  UNREACHABLE();
  return NoChange();
}


Node* ChangeLowering::HeapNumberValueIndexConstant() {
  STATIC_ASSERT(HeapNumber::kValueOffset % kPointerSize == 0);
  const int heap_number_value_offset =
      ((HeapNumber::kValueOffset / kPointerSize) * (machine()->Is64() ? 8 : 4));
  return jsgraph()->IntPtrConstant(heap_number_value_offset - kHeapObjectTag);
}


Node* ChangeLowering::SmiMaxValueConstant() {
  const int smi_value_size = machine()->Is32() ? SmiTagging<4>::SmiValueSize()
                                               : SmiTagging<8>::SmiValueSize();
  return jsgraph()->Int32Constant(
      -(static_cast<int>(0xffffffffu << (smi_value_size - 1)) + 1));
}


Node* ChangeLowering::SmiShiftBitsConstant() {
  const int smi_shift_size = machine()->Is32() ? SmiTagging<4>::SmiShiftSize()
                                               : SmiTagging<8>::SmiShiftSize();
  return jsgraph()->IntPtrConstant(smi_shift_size + kSmiTagSize);
}


Node* ChangeLowering::AllocateHeapNumberWithValue(Node* value, Node* control) {
  // The AllocateHeapNumberStub does not use the context, so we can safely pass
  // in Smi zero here.
  Callable callable = CodeFactory::AllocateHeapNumber(isolate());
  CallDescriptor* descriptor = linkage()->GetStubCallDescriptor(
      callable.descriptor(), 0, CallDescriptor::kNoFlags);
  Node* target = jsgraph()->HeapConstant(callable.code());
  Node* context = jsgraph()->NoContextConstant();
  Node* effect = graph()->NewNode(common()->ValueEffect(1), value);
  Node* heap_number = graph()->NewNode(common()->Call(descriptor), target,
                                       context, effect, control);
  Node* store = graph()->NewNode(
      machine()->Store(StoreRepresentation(kMachFloat64, kNoWriteBarrier)),
      heap_number, HeapNumberValueIndexConstant(), value, heap_number, control);
  return graph()->NewNode(common()->Finish(1), heap_number, store);
}


Node* ChangeLowering::ChangeInt32ToFloat64(Node* value) {
  return graph()->NewNode(machine()->ChangeInt32ToFloat64(), value);
}


Node* ChangeLowering::ChangeSmiToFloat64(Node* value) {
  return ChangeInt32ToFloat64(ChangeSmiToInt32(value));
}


Node* ChangeLowering::ChangeSmiToInt32(Node* value) {
  value = graph()->NewNode(machine()->WordSar(), value, SmiShiftBitsConstant());
  if (machine()->Is64()) {
    value = graph()->NewNode(machine()->TruncateInt64ToInt32(), value);
  }
  return value;
}


Node* ChangeLowering::ChangeUint32ToFloat64(Node* value) {
  return graph()->NewNode(machine()->ChangeUint32ToFloat64(), value);
}


Node* ChangeLowering::ChangeUint32ToSmi(Node* value) {
  if (machine()->Is64()) {
    value = graph()->NewNode(machine()->ChangeUint32ToUint64(), value);
  }
  return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant());
}


Node* ChangeLowering::LoadHeapNumberValue(Node* value, Node* control) {
  return graph()->NewNode(machine()->Load(kMachFloat64), value,
                          HeapNumberValueIndexConstant(), graph()->start(),
                          control);
}


Node* ChangeLowering::TestNotSmi(Node* value) {
  STATIC_ASSERT(kSmiTag == 0);
  STATIC_ASSERT(kSmiTagMask == 1);
  return graph()->NewNode(machine()->WordAnd(), value,
                          jsgraph()->IntPtrConstant(kSmiTagMask));
}


Node* ChangeLowering::Uint32LessThanOrEqual(Node* lhs, Node* rhs) {
  return graph()->NewNode(machine()->Uint32LessThanOrEqual(), lhs, rhs);
}


Reduction ChangeLowering::ChangeBitToBool(Node* val, Node* control) {
  MachineType const type = static_cast<MachineType>(kTypeBool | kRepTagged);
  return Replace(graph()->NewNode(common()->Select(type), val,
                                  jsgraph()->TrueConstant(),
                                  jsgraph()->FalseConstant()));
}


Reduction ChangeLowering::ChangeBoolToBit(Node* val) {
  return Replace(
      graph()->NewNode(machine()->WordEqual(), val, jsgraph()->TrueConstant()));
}


Reduction ChangeLowering::ChangeFloat64ToTagged(Node* val, Node* control) {
  return Replace(AllocateHeapNumberWithValue(val, control));
}


Reduction ChangeLowering::ChangeInt32ToTagged(Node* value, Node* control) {
  if (machine()->Is64()) {
    return Replace(graph()->NewNode(
        machine()->Word64Shl(),
        graph()->NewNode(machine()->ChangeInt32ToInt64(), value),
        SmiShiftBitsConstant()));
  } else if (NodeProperties::GetBounds(value).upper->Is(Type::SignedSmall())) {
    return Replace(
        graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant()));
  }

  Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value);
  Node* ovf = graph()->NewNode(common()->Projection(1), add);

  Diamond d(graph(), common(), ovf, BranchHint::kFalse);
  d.Chain(control);
  return Replace(
      d.Phi(kMachAnyTagged,
            AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), d.if_true),
            graph()->NewNode(common()->Projection(0), add)));
}


Reduction ChangeLowering::ChangeTaggedToUI32(Node* value, Node* control,
                                             Signedness signedness) {
  const MachineType type = (signedness == kSigned) ? kMachInt32 : kMachUint32;
  const Operator* op = (signedness == kSigned)
                           ? machine()->ChangeFloat64ToInt32()
                           : machine()->ChangeFloat64ToUint32();
  Diamond d(graph(), common(), TestNotSmi(value), BranchHint::kFalse);
  d.Chain(control);
  return Replace(
      d.Phi(type, graph()->NewNode(op, LoadHeapNumberValue(value, d.if_true)),
            ChangeSmiToInt32(value)));
}


namespace {

bool CanCover(Node* value, IrOpcode::Value opcode) {
  if (value->opcode() != opcode) return false;
  bool first = true;
  for (Edge const edge : value->use_edges()) {
    if (NodeProperties::IsEffectEdge(edge)) continue;
    DCHECK(NodeProperties::IsValueEdge(edge));
    if (!first) return false;
    first = false;
  }
  return true;
}

}  // namespace


Reduction ChangeLowering::ChangeTaggedToFloat64(Node* value, Node* control) {
  if (CanCover(value, IrOpcode::kJSToNumber)) {
    // ChangeTaggedToFloat64(JSToNumber(x)) =>
    //   if IsSmi(x) then ChangeSmiToFloat64(x)
    //   else let y = JSToNumber(x) in
    //     if IsSmi(y) then ChangeSmiToFloat64(y)
    //     else LoadHeapNumberValue(y)
    Node* const object = NodeProperties::GetValueInput(value, 0);
    Node* const context = NodeProperties::GetContextInput(value);
    Node* const effect = NodeProperties::GetEffectInput(value);
    Node* const control = NodeProperties::GetControlInput(value);

    Diamond d1(graph(), common(), TestNotSmi(object), BranchHint::kFalse);
    d1.Chain(control);

    Node* number =
        graph()->NewNode(value->op(), object, context, effect, d1.if_true);
    Diamond d2(graph(), common(), TestNotSmi(number));
    d2.Nest(d1, true);
    Node* phi2 = d2.Phi(kMachFloat64, LoadHeapNumberValue(number, d2.if_true),
                        ChangeSmiToFloat64(number));

    Node* phi1 = d1.Phi(kMachFloat64, phi2, ChangeSmiToFloat64(object));
    Node* ephi1 = d1.EffectPhi(number, effect);

    for (Edge edge : value->use_edges()) {
      if (NodeProperties::IsEffectEdge(edge)) {
        edge.UpdateTo(ephi1);
      }
    }
    return Replace(phi1);
  }

  Diamond d(graph(), common(), TestNotSmi(value), BranchHint::kFalse);
  d.Chain(control);
  Node* load = LoadHeapNumberValue(value, d.if_true);
  Node* number = ChangeSmiToFloat64(value);
  return Replace(d.Phi(kMachFloat64, load, number));
}


Reduction ChangeLowering::ChangeUint32ToTagged(Node* value, Node* control) {
  Diamond d(graph(), common(),
            Uint32LessThanOrEqual(value, SmiMaxValueConstant()),
            BranchHint::kTrue);
  d.Chain(control);
  return Replace(d.Phi(
      kMachAnyTagged, ChangeUint32ToSmi(value),
      AllocateHeapNumberWithValue(ChangeUint32ToFloat64(value), d.if_false)));
}


Isolate* ChangeLowering::isolate() const { return jsgraph()->isolate(); }


Graph* ChangeLowering::graph() const { return jsgraph()->graph(); }


CommonOperatorBuilder* ChangeLowering::common() const {
  return jsgraph()->common();
}


MachineOperatorBuilder* ChangeLowering::machine() const {
  return jsgraph()->machine();
}

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