//===- subzero/src/IceMemory.h - Memory management declarations -*- C++ -*-===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Declares some useful data structures and routines dealing with
/// memory management in Subzero (mostly, allocator types.)
///
//===----------------------------------------------------------------------===//

#ifndef SUBZERO_SRC_ICEMEMORY_H
#define SUBZERO_SRC_ICEMEMORY_H

#include "IceTLS.h"

#include "llvm/Support/Allocator.h"

#include <cstddef>
#include <mutex>

namespace Ice {

class Cfg;
class GlobalContext;
class Liveness;

using ArenaAllocator =
    llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, /*SlabSize=*/1024 * 1024>;

class LockedArenaAllocator {
  LockedArenaAllocator() = delete;
  LockedArenaAllocator(const LockedArenaAllocator &) = delete;
  LockedArenaAllocator &operator=(const LockedArenaAllocator &) = delete;

public:
  LockedArenaAllocator(ArenaAllocator *Alloc, std::mutex *Mutex)
      : Alloc(Alloc), AutoLock(*Mutex) {}
  LockedArenaAllocator(LockedArenaAllocator &&) = default;
  LockedArenaAllocator &operator=(LockedArenaAllocator &&) = default;
  ~LockedArenaAllocator() = default;

  ArenaAllocator *operator->() { return Alloc; }

private:
  ArenaAllocator *Alloc;
  std::unique_lock<std::mutex> AutoLock;
};

template <typename T, typename Traits> struct sz_allocator {
  /// std::allocator interface implementation.
  /// @{
  using value_type = T;
  using pointer = T *;
  using const_pointer = const T *;
  using reference = T &;
  using const_reference = const T &;
  using size_type = std::size_t;
  using difference_type = std::ptrdiff_t;

  sz_allocator() : Current() {}
  template <class U>
  sz_allocator(const sz_allocator<U, Traits> &)
      : Current() {}

  pointer address(reference x) const {
    return reinterpret_cast<pointer>(&reinterpret_cast<char &>(x));
  }
  const_pointer address(const_reference x) const {
    return reinterpret_cast<const_pointer>(&reinterpret_cast<const char &>(x));
  }

  pointer allocate(size_type num) {
    assert(current() != nullptr);
    return current()->template Allocate<T>(num);
  }

  template <typename... A> void construct(pointer P, A &&... Args) {
    new (static_cast<void *>(P)) T(std::forward<A>(Args)...);
  }

  void deallocate(pointer, size_type) {}

  template <class U> struct rebind { typedef sz_allocator<U, Traits> other; };

  void destroy(pointer P) { P->~T(); }
  /// @}

  /// Manages the current underlying allocator.
  /// @{
  typename Traits::allocator_type current() {
    if (!Traits::cache_allocator) {
      // TODO(jpp): allocators should always be cacheable... maybe. Investigate.
      return Traits::current();
    }
    if (Current == nullptr) {
      Current = Traits::current();
    }
    assert(Current == Traits::current());
    return Current;
  }
  static void init() { Traits::init(); }
  /// @}
  typename Traits::allocator_type Current;
};

template <class Traits> struct sz_allocator_scope {
  explicit sz_allocator_scope(typename Traits::manager_type *Manager) {
    Traits::set_current(Manager);
  }

  ~sz_allocator_scope() { Traits::set_current(nullptr); }
};

template <typename T, typename U, typename Traits>
inline bool operator==(const sz_allocator<T, Traits> &,
                       const sz_allocator<U, Traits> &) {
  return true;
}

template <typename T, typename U, typename Traits>
inline bool operator!=(const sz_allocator<T, Traits> &,
                       const sz_allocator<U, Traits> &) {
  return false;
}

class CfgAllocatorTraits {
  CfgAllocatorTraits() = delete;
  CfgAllocatorTraits(const CfgAllocatorTraits &) = delete;
  CfgAllocatorTraits &operator=(const CfgAllocatorTraits &) = delete;
  ~CfgAllocatorTraits() = delete;

public:
  using allocator_type = ArenaAllocator *;
  using manager_type = Cfg;
  static constexpr bool cache_allocator = false;

  static void init() { ICE_TLS_INIT_FIELD(CfgAllocator); };

  static allocator_type current();
  static void set_current(const manager_type *Manager);
  static void set_current(ArenaAllocator *Allocator);
  static void set_current(std::nullptr_t);

private:
  ICE_TLS_DECLARE_FIELD(ArenaAllocator *, CfgAllocator);
};

template <typename T>
using CfgLocalAllocator = sz_allocator<T, CfgAllocatorTraits>;

using CfgLocalAllocatorScope = sz_allocator_scope<CfgAllocatorTraits>;

class LivenessAllocatorTraits {
  LivenessAllocatorTraits() = delete;
  LivenessAllocatorTraits(const LivenessAllocatorTraits &) = delete;
  LivenessAllocatorTraits &operator=(const LivenessAllocatorTraits &) = delete;
  ~LivenessAllocatorTraits() = delete;

public:
  using allocator_type = ArenaAllocator *;
  using manager_type = Liveness;
  static constexpr bool cache_allocator = true;

  static void init() { ICE_TLS_INIT_FIELD(LivenessAllocator); };

  static allocator_type current();
  static void set_current(const manager_type *Manager);

private:
  ICE_TLS_DECLARE_FIELD(ArenaAllocator *, LivenessAllocator);
};

template <typename T>
using LivenessAllocator = sz_allocator<T, LivenessAllocatorTraits>;

using LivenessAllocatorScope = sz_allocator_scope<LivenessAllocatorTraits>;

} // end of namespace Ice

#endif // SUBZERO_SRC_ICEMEMORY_H
