//===- subzero/src/IceDefs.h - Common Subzero 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 various useful types and classes that have widespread use
/// across Subzero.
///
//===----------------------------------------------------------------------===//

#ifndef SUBZERO_SRC_ICEDEFS_H
#define SUBZERO_SRC_ICEDEFS_H

#include "IceBuildDefs.h" // TODO(stichnot): move into individual files
#include "IceMemory.h"
#include "IceTLS.h"

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/raw_ostream.h"

#include <cassert>
#include <cstdint>
#include <cstdio>     // snprintf
#include <functional> // std::less
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <string>
#include <system_error>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define XSTRINGIFY(x) STRINGIFY(x)
#define STRINGIFY(x) #x

namespace Ice {

class Assembler;
template <template <typename> class> class BitVectorTmpl;
class Cfg;
class CfgNode;
class Constant;
class ELFFileStreamer;
class ELFObjectWriter;
class ELFStreamer;
class FunctionDeclaration;
class GlobalContext;
class GlobalDeclaration;
class Inst;
class InstAssign;
class InstJumpTable;
class InstPhi;
class InstSwitch;
class InstTarget;
class LiveRange;
class Liveness;
class Operand;
class TargetDataLowering;
class TargetLowering;
class Variable;
class VariableDeclaration;
class VariablesMetadata;

/// SizeT is for holding small-ish limits like number of source operands in an
/// instruction. It is used instead of size_t (which may be 64-bits wide) when
/// we want to save space.
using SizeT = uint32_t;

constexpr char GlobalOffsetTable[] = "_GLOBAL_OFFSET_TABLE_";
// makeUnique should be used when memory is expected to be allocated from the
// heap (as opposed to allocated from some Allocator.) It is intended to be
// used instead of new.
//
// The expected usage is as follows
//
// class MyClass {
// public:
//   static std::unique_ptr<MyClass> create(<ctor_args>) {
//     return makeUnique<MyClass>(<ctor_args>);
//   }
//
// private:
//   ENABLE_MAKE_UNIQUE;
//
//   MyClass(<ctor_args>) ...
// }
//
// ENABLE_MAKE_UNIQUE is a trick that is necessary if MyClass' ctor is private.
// Private ctors are highly encouraged when you're writing a class that you'd
// like to have allocated with makeUnique as it would prevent users from
// declaring stack allocated variables.
namespace Internal {
struct MakeUniqueEnabler {
  template <class T, class... Args>
  static std::unique_ptr<T> create(Args &&... TheArgs) {
    std::unique_ptr<T> Unique(new T(std::forward<Args>(TheArgs)...));
    return Unique;
  }
};
} // end of namespace Internal

template <class T, class... Args>
static std::unique_ptr<T> makeUnique(Args &&... TheArgs) {
  return ::Ice::Internal::MakeUniqueEnabler::create<T>(
      std::forward<Args>(TheArgs)...);
}

#define ENABLE_MAKE_UNIQUE friend struct ::Ice::Internal::MakeUniqueEnabler

using InstList = llvm::ilist<Inst>;
// Ideally PhiList would be llvm::ilist<InstPhi>, and similar for AssignList,
// but this runs into issues with SFINAE.
using PhiList = InstList;
using AssignList = InstList;

// Standard library containers with CfgLocalAllocator.
template <typename T> using CfgList = std::list<T, CfgLocalAllocator<T>>;
template <typename T, typename H = std::hash<T>, typename Eq = std::equal_to<T>>
using CfgUnorderedSet = std::unordered_set<T, H, Eq, CfgLocalAllocator<T>>;
template <typename T, typename Cmp = std::less<T>>
using CfgSet = std::set<T, Cmp, CfgLocalAllocator<T>>;
template <typename T, typename U, typename H = std::hash<T>,
          typename Eq = std::equal_to<T>>
using CfgUnorderedMap =
    std::unordered_map<T, U, H, Eq, CfgLocalAllocator<std::pair<const T, U>>>;
template <typename T> using CfgVector = std::vector<T, CfgLocalAllocator<T>>;

// Containers that are arena-allocated from the Cfg's allocator.
using OperandList = CfgVector<Operand *>;
using VarList = CfgVector<Variable *>;
using NodeList = CfgVector<CfgNode *>;

// Containers that use the default (global) allocator.
using ConstantList = std::vector<Constant *>;
using FunctionDeclarationList = std::vector<FunctionDeclaration *>;

/// VariableDeclarationList is a container for holding VariableDeclarations --
/// i.e., Global Variables. It is also used to create said variables, and their
/// initializers in an arena.
class VariableDeclarationList {
  VariableDeclarationList(const VariableDeclarationList &) = delete;
  VariableDeclarationList &operator=(const VariableDeclarationList &) = delete;
  VariableDeclarationList(VariableDeclarationList &&) = delete;
  VariableDeclarationList &operator=(VariableDeclarationList &&) = delete;

public:
  using VariableDeclarationArray = std::vector<VariableDeclaration *>;

  VariableDeclarationList() : Arena(new ArenaAllocator()) {}

  ~VariableDeclarationList() { clearAndPurge(); }

  template <typename T> T *allocate_initializer(SizeT Count = 1) {
    static_assert(
        std::is_trivially_destructible<T>::value,
        "allocate_initializer can only allocate trivially destructible types.");
    return Arena->Allocate<T>(Count);
  }

  template <typename T> T *allocate_variable_declaration() {
    static_assert(!std::is_trivially_destructible<T>::value,
                  "allocate_variable_declaration expects non-trivially "
                  "destructible types.");
    T *Ret = Arena->Allocate<T>();
    Dtors.emplace_back([Ret]() { Ret->~T(); });
    return Ret;
  }

  // This do nothing method is invoked when a global variable is created, but it
  // will not be emitted. If we ever need to track the created variable, having
  // this hook is handy.
  void willNotBeEmitted(VariableDeclaration *) {}

  /// Merges Other with this, effectively resetting Other to an empty state.
  void merge(VariableDeclarationList *Other) {
    assert(Other != nullptr);
    addArena(std::move(Other->Arena));
    for (std::size_t i = 0; i < Other->MergedArenas.size(); ++i) {
      addArena(std::move(Other->MergedArenas[i]));
    }
    Other->MergedArenas.clear();

    Dtors.insert(Dtors.end(), Other->Dtors.begin(), Other->Dtors.end());
    Other->Dtors.clear();

    Globals.insert(Globals.end(), Other->Globals.begin(), Other->Globals.end());
    Other->Globals.clear();
  }

  /// Destroys all GlobalVariables and initializers that this knows about
  /// (including those merged with it), and releases memory.
  void clearAndPurge() {
    if (Arena == nullptr) {
      // Arena is only null if this was merged, so we ensure there's no state
      // being held by this.
      assert(Dtors.empty());
      assert(Globals.empty());
      assert(MergedArenas.empty());
      return;
    }
    // Invokes destructors in reverse creation order.
    for (auto Dtor = Dtors.rbegin(); Dtor != Dtors.rend(); ++Dtor) {
      (*Dtor)();
    }
    Dtors.clear();
    Globals.clear();
    MergedArenas.clear();
    Arena->Reset();
  }

  /// Adapt the relevant parts of the std::vector<VariableDeclaration *>
  /// interface.
  /// @{
  VariableDeclarationArray::iterator begin() { return Globals.begin(); }

  VariableDeclarationArray::iterator end() { return Globals.end(); }

  VariableDeclarationArray::const_iterator begin() const {
    return Globals.begin();
  }

  VariableDeclarationArray::const_iterator end() const { return Globals.end(); }

  bool empty() const { return Globals.empty(); }

  VariableDeclarationArray::size_type size() const { return Globals.size(); }

  VariableDeclarationArray::reference
  at(VariableDeclarationArray::size_type Pos) {
    return Globals.at(Pos);
  }

  void push_back(VariableDeclaration *Global) { Globals.push_back(Global); }

  void reserve(VariableDeclarationArray::size_type Capacity) {
    Globals.reserve(Capacity);
  }

  void clear() { Globals.clear(); }

  VariableDeclarationArray::reference back() { return Globals.back(); }
  /// @}

private:
  using ArenaPtr = std::unique_ptr<ArenaAllocator>;
  using DestructorsArray = std::vector<std::function<void()>>;

  void addArena(ArenaPtr NewArena) {
    MergedArenas.emplace_back(std::move(NewArena));
  }

  ArenaPtr Arena;
  VariableDeclarationArray Globals;
  DestructorsArray Dtors;
  std::vector<ArenaPtr> MergedArenas;
};

/// InstNumberT is for holding an instruction number. Instruction numbers are
/// used for representing Variable live ranges.
using InstNumberT = int32_t;

/// A LiveBeginEndMapEntry maps a Variable::Number value to an Inst::Number
/// value, giving the instruction number that begins or ends a variable's live
/// range.
template <typename T>
using LivenessVector = std::vector<T, LivenessAllocator<T>>;
using LiveBeginEndMapEntry = std::pair<SizeT, InstNumberT>;
using LiveBeginEndMap = LivenessVector<LiveBeginEndMapEntry>;
using LivenessBV = BitVectorTmpl<LivenessAllocator>;

using TimerStackIdT = uint32_t;
using TimerIdT = uint32_t;

/// Use alignas(MaxCacheLineSize) to isolate variables/fields that might be
/// contended while multithreading. Assumes the maximum cache line size is 64.
enum { MaxCacheLineSize = 64 };
// Use ICE_CACHELINE_BOUNDARY to force the next field in a declaration
// list to be aligned to the next cache line.
#if defined(_MSC_VER)
#define ICE_CACHELINE_BOUNDARY __declspec(align(MaxCacheLineSize)) int : 0;
#else // !defined(_MSC_VER)
// Note: zero is added to work around the following GCC 4.8 bug (fixed in 4.9):
//       https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55382
#define ICE_CACHELINE_BOUNDARY                                                 \
  __attribute__((aligned(MaxCacheLineSize + 0))) int : 0
#endif // !defined(_MSC_VER)

/// PNaCl is ILP32, so theoretically we should only need 32-bit offsets.
using RelocOffsetT = int32_t;
enum { RelocAddrSize = 4 };

enum LivenessMode {
  /// Basic version of live-range-end calculation. Marks the last uses of
  /// variables based on dataflow analysis. Records the set of live-in and
  /// live-out variables for each block. Identifies and deletes dead
  /// instructions (primarily stores).
  Liveness_Basic,

  /// In addition to Liveness_Basic, also calculate the complete live range for
  /// each variable in a form suitable for interference calculation and register
  /// allocation.
  Liveness_Intervals
};

enum LCSEOptions {
  LCSE_Disabled,
  LCSE_EnabledSSA,  // Default Mode, assumes SSA.
  LCSE_EnabledNoSSA // Does not assume SSA, to be enabled if CSE is done later.
};

enum RegAllocKind {
  RAK_Unknown,
  RAK_Global,       /// full, global register allocation
  RAK_SecondChance, /// second-chance bin-packing after full regalloc attempt
  RAK_Phi,          /// infinite-weight Variables with active spilling/filling
  RAK_InfOnly       /// allocation only for infinite-weight Variables
};

enum VerboseItem {
  IceV_None = 0,
  IceV_Instructions = 1 << 0,
  IceV_Deleted = 1 << 1,
  IceV_InstNumbers = 1 << 2,
  IceV_Preds = 1 << 3,
  IceV_Succs = 1 << 4,
  IceV_Liveness = 1 << 5,
  IceV_RegOrigins = 1 << 6,
  IceV_LinearScan = 1 << 7,
  IceV_Frame = 1 << 8,
  IceV_AddrOpt = 1 << 9,
  IceV_Folding = 1 << 10,
  IceV_RMW = 1 << 11,
  IceV_Loop = 1 << 12,
  IceV_Mem = 1 << 13,
  // Leave some extra space to make it easier to add new per-pass items.
  IceV_NO_PER_PASS_DUMP_BEYOND = 1 << 19,
  // Items greater than IceV_NO_PER_PASS_DUMP_BEYOND don't by themselves trigger
  // per-pass Cfg dump output.
  IceV_Status = 1 << 20,
  IceV_AvailableRegs = 1 << 21,
  IceV_GlobalInit = 1 << 22,
  IceV_ConstPoolStats = 1 << 23,
  IceV_Wasm = 1 << 24,
  IceV_ShufMat = 1 << 25,
  IceV_All = ~IceV_None,
  IceV_Most =
      IceV_All & ~IceV_LinearScan & ~IceV_GlobalInit & ~IceV_ConstPoolStats
};
using VerboseMask = uint32_t;

enum FileType {
  FT_Elf, /// ELF .o file
  FT_Asm, /// Assembly .s file
  FT_Iasm /// "Integrated assembler" .byte-style .s file
};

enum ABI {
  ABI_PNaCl,   /// x32 for unsandboxed 64-bit x86
  ABI_Platform /// Native executable ABI
};

using Ostream = llvm::raw_ostream;
using Fdstream = llvm::raw_fd_ostream;

using GlobalLockType = std::mutex;

/// LockedPtr is an RAII wrapper that allows automatically locked access to a
/// given pointer, automatically unlocking it when when the LockedPtr goes out
/// of scope.
template <typename T> class LockedPtr {
  LockedPtr() = delete;
  LockedPtr(const LockedPtr &) = delete;
  LockedPtr &operator=(const LockedPtr &) = delete;

public:
  LockedPtr(T *Value, GlobalLockType *Lock) : Value(Value), Lock(Lock) {
    Lock->lock();
  }
  LockedPtr(LockedPtr &&Other) : Value(Other.Value), Lock(Other.Lock) {
    Other.Value = nullptr;
    Other.Lock = nullptr;
  }
  ~LockedPtr() {
    if (Lock != nullptr)
      Lock->unlock();
  }
  T *operator->() const { return Value; }
  T &operator*() const { return *Value; }
  T *get() { return Value; }

private:
  T *Value;
  GlobalLockType *Lock;
};

enum ErrorCodes { EC_None = 0, EC_Args, EC_Bitcode, EC_Translation };

/// Wrapper around std::error_code for allowing multiple errors to be folded
/// into one. The current implementation keeps track of the first error, which
/// is likely to be the most useful one, and this could be extended to e.g.
/// collect a vector of errors.
class ErrorCode : public std::error_code {
  ErrorCode(const ErrorCode &) = delete;
  ErrorCode &operator=(const ErrorCode &) = delete;

public:
  ErrorCode() = default;
  void assign(ErrorCodes Code) {
    if (!HasError) {
      HasError = true;
      std::error_code::assign(Code, std::generic_category());
    }
  }
  void assign(int Code) { assign(static_cast<ErrorCodes>(Code)); }

private:
  bool HasError = false;
};

/// Reverse range adaptors written in terms of llvm::make_range().
template <typename T>
llvm::iterator_range<typename T::const_reverse_iterator>
reverse_range(const T &Container) {
  return llvm::make_range(Container.rbegin(), Container.rend());
}
template <typename T>
llvm::iterator_range<typename T::reverse_iterator> reverse_range(T &Container) {
  return llvm::make_range(Container.rbegin(), Container.rend());
}

using RelocOffsetArray = llvm::SmallVector<class RelocOffset *, 4>;

} // end of namespace Ice

#endif // SUBZERO_SRC_ICEDEFS_H
