// 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_COMMON_NODE_CACHE_H_
#define V8_COMPILER_COMMON_NODE_CACHE_H_

#include "src/compiler/node-cache.h"

namespace v8 {
namespace internal {

// Forward declarations.
class ExternalReference;
class HeapObject;
template <typename>
class Handle;


namespace compiler {

// Bundles various caches for common nodes.
class CommonNodeCache final {
 public:
  explicit CommonNodeCache(Zone* zone) : zone_(zone) {}
  ~CommonNodeCache() {}

  Node** FindInt32Constant(int32_t value) {
    return int32_constants_.Find(zone(), value);
  }

  Node** FindInt64Constant(int64_t value) {
    return int64_constants_.Find(zone(), value);
  }

  Node** FindFloat32Constant(float value) {
    // We canonicalize float constants at the bit representation level.
    return float32_constants_.Find(zone(), bit_cast<int32_t>(value));
  }

  Node** FindFloat64Constant(double value) {
    // We canonicalize double constants at the bit representation level.
    return float64_constants_.Find(zone(), bit_cast<int64_t>(value));
  }

  Node** FindExternalConstant(ExternalReference value);

  Node** FindPointerConstant(intptr_t value) {
    return pointer_constants_.Find(zone(), value);
  }

  Node** FindNumberConstant(double value) {
    // We canonicalize double constants at the bit representation level.
    return number_constants_.Find(zone(), bit_cast<int64_t>(value));
  }

  Node** FindHeapConstant(Handle<HeapObject> value);

  Node** FindRelocatableInt32Constant(int32_t value, RelocInfoMode rmode) {
    return relocatable_int32_constants_.Find(zone(),
                                             std::make_pair(value, rmode));
  }

  Node** FindRelocatableInt64Constant(int64_t value, RelocInfoMode rmode) {
    return relocatable_int64_constants_.Find(zone(),
                                             std::make_pair(value, rmode));
  }

  // Return all nodes from the cache.
  void GetCachedNodes(ZoneVector<Node*>* nodes);

  Zone* zone() const { return zone_; }

 private:
  Int32NodeCache int32_constants_;
  Int64NodeCache int64_constants_;
  Int32NodeCache float32_constants_;
  Int64NodeCache float64_constants_;
  IntPtrNodeCache external_constants_;
  IntPtrNodeCache pointer_constants_;
  Int64NodeCache number_constants_;
  IntPtrNodeCache heap_constants_;
  RelocInt32NodeCache relocatable_int32_constants_;
  RelocInt64NodeCache relocatable_int64_constants_;
  Zone* const zone_;

  DISALLOW_COPY_AND_ASSIGN(CommonNodeCache);
};

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

#endif  // V8_COMPILER_COMMON_NODE_CACHE_H_
