//===- 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/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.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 <string>
#include <system_error>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

namespace Ice {

class Assembler;
template <template <typename> class> class BitVectorTmpl;
class Cfg;
class CfgNode;
class Constant;
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 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.
// 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

/// 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 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_Random = 1 << 10,
  IceV_Folding = 1 << 11,
  IceV_RMW = 1 << 12,
  IceV_Loop = 1 << 13,
  IceV_Mem = 1 << 14,
  // 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
};

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() { 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());
}

/// Options for pooling and randomization of immediates.
enum RandomizeAndPoolImmediatesEnum { RPI_None, RPI_Randomize, RPI_Pool };

/// Salts for Random number generator for different randomization passes.
enum RandomizationPassesEnum {
  RPE_BasicBlockReordering,
  RPE_ConstantBlinding,
  RPE_FunctionReordering,
  RPE_GlobalVariableReordering,
  RPE_NopInsertion,
  RPE_PooledConstantReordering,
  RPE_RegAllocRandomization,
  RPE_num
};

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

} // end of namespace Ice

#endif // SUBZERO_SRC_ICEDEFS_H
