// Copyright 2013 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.h"

#include <algorithm>

#include "src/base/bits.h"
#include "src/compiler/graph-visualizer.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/node.h"
#include "src/compiler/verifier.h"

namespace v8 {
namespace internal {
namespace compiler {

Graph::Graph(Zone* zone)
    : zone_(zone),
      start_(nullptr),
      end_(nullptr),
      mark_max_(0),
      next_node_id_(0),
      decorators_(zone) {}


void Graph::Decorate(Node* node) {
  for (GraphDecorator* const decorator : decorators_) {
    decorator->Decorate(node);
  }
}


void Graph::AddDecorator(GraphDecorator* decorator) {
  decorators_.push_back(decorator);
}


void Graph::RemoveDecorator(GraphDecorator* decorator) {
  auto const it = std::find(decorators_.begin(), decorators_.end(), decorator);
  DCHECK(it != decorators_.end());
  decorators_.erase(it);
}

Node* Graph::NewNode(const Operator* op, int input_count, Node* const* inputs,
                     bool incomplete) {
  Node* node = NewNodeUnchecked(op, input_count, inputs, incomplete);
  Verifier::VerifyNode(node);
  return node;
}

Node* Graph::NewNodeUnchecked(const Operator* op, int input_count,
                              Node* const* inputs, bool incomplete) {
  Node* const node =
      Node::New(zone(), NextNodeId(), op, input_count, inputs, incomplete);
  Decorate(node);
  return node;
}


Node* Graph::CloneNode(const Node* node) {
  DCHECK_NOT_NULL(node);
  Node* const clone = Node::Clone(zone(), NextNodeId(), node);
  Decorate(clone);
  return clone;
}


NodeId Graph::NextNodeId() {
  NodeId const id = next_node_id_;
  CHECK(!base::bits::UnsignedAddOverflow32(id, 1, &next_node_id_));
  return id;
}

#if defined(DISABLE_GRAPHS_STARBOARD)
void Graph::Print() const {}
#else
void Graph::Print() const { StdoutStream{} << AsRPO(*this); }
#endif

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