// Copyright 2018 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/constant-folding-reducer.h"

#include "src/compiler/js-graph.h"
#include "src/objects/objects-inl.h"

namespace v8 {
namespace internal {
namespace compiler {

namespace {
Node* TryGetConstant(JSGraph* jsgraph, Node* node) {
  Type type = NodeProperties::GetType(node);
  Node* result;
  if (type.IsNone()) {
    result = nullptr;
  } else if (type.Is(Type::Null())) {
    result = jsgraph->NullConstant();
  } else if (type.Is(Type::Undefined())) {
    result = jsgraph->UndefinedConstant();
  } else if (type.Is(Type::MinusZero())) {
    result = jsgraph->MinusZeroConstant();
  } else if (type.Is(Type::NaN())) {
    result = jsgraph->NaNConstant();
  } else if (type.Is(Type::Hole())) {
    result = jsgraph->TheHoleConstant();
  } else if (type.IsHeapConstant()) {
    result = jsgraph->Constant(type.AsHeapConstant()->Ref());
  } else if (type.Is(Type::PlainNumber()) && type.Min() == type.Max()) {
    result = jsgraph->Constant(type.Min());
  } else {
    result = nullptr;
  }
  DCHECK_EQ(result != nullptr, type.IsSingleton());
  DCHECK_IMPLIES(result != nullptr,
                 type.Equals(NodeProperties::GetType(result)));
  return result;
}

bool IsAlreadyBeingFolded(Node* node) {
  DCHECK(FLAG_assert_types);
  if (node->opcode() == IrOpcode::kFoldConstant) return true;
  for (Edge edge : node->use_edges()) {
    if (NodeProperties::IsValueEdge(edge) &&
        edge.from()->opcode() == IrOpcode::kFoldConstant) {
      // Note: {node} may have gained new value uses since the time it was
      // "constant-folded", and theses uses should ideally be rewritten as well.
      // For simplicity, we ignore them here.
      return true;
    }
  }
  return false;
}
}  // namespace

ConstantFoldingReducer::ConstantFoldingReducer(Editor* editor, JSGraph* jsgraph,
                                               JSHeapBroker* broker)
    : AdvancedReducer(editor), jsgraph_(jsgraph), broker_(broker) {}

ConstantFoldingReducer::~ConstantFoldingReducer() = default;

Reduction ConstantFoldingReducer::Reduce(Node* node) {
  DisallowHeapAccess no_heap_access;
  if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) &&
      node->op()->HasProperty(Operator::kEliminatable) &&
      node->opcode() != IrOpcode::kFinishRegion) {
    Node* constant = TryGetConstant(jsgraph(), node);
    if (constant != nullptr) {
      DCHECK(NodeProperties::IsTyped(constant));
      if (!FLAG_assert_types) {
        DCHECK_EQ(node->op()->ControlOutputCount(), 0);
        ReplaceWithValue(node, constant);
        return Replace(constant);
      } else if (!IsAlreadyBeingFolded(node)) {
        // Delay the constant folding (by inserting a FoldConstant operation
        // instead) in order to keep type assertions meaningful.
        Node* fold_constant = jsgraph()->graph()->NewNode(
            jsgraph()->common()->FoldConstant(), node, constant);
        DCHECK(NodeProperties::IsTyped(fold_constant));
        ReplaceWithValue(node, fold_constant, node, node);
        fold_constant->ReplaceInput(0, node);
        DCHECK(IsAlreadyBeingFolded(node));
        DCHECK(IsAlreadyBeingFolded(fold_constant));
        return Changed(node);
      }
    }
  }
  return NoChange();
}

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