//===- 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
/// This file declares various useful types and classes that have widespread use
/// across Subzero.  Every Subzero source file is expected to include IceDefs.h.
///
//===----------------------------------------------------------------------===//

#ifndef SUBZERO_SRC_ICEDEFS_H
#define SUBZERO_SRC_ICEDEFS_H

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

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Allocator.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 <vector>

namespace Ice {

class Assembler;
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;

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

ArenaAllocator<> *getCurrentCfgAllocator();

template <typename T> struct CfgLocalAllocator {
  using value_type = T;
  CfgLocalAllocator() = default;
  template <class U> CfgLocalAllocator(const CfgLocalAllocator<U> &) {}
  T *allocate(std::size_t Num) {
    return getCurrentCfgAllocator()->Allocate<T>(Num);
  }
  void deallocate(T *, std::size_t) {}
};
template <typename T, typename U>
inline bool operator==(const CfgLocalAllocator<T> &,
                       const CfgLocalAllocator<U> &) {
  return true;
}
template <typename T, typename U>
inline bool operator!=(const CfgLocalAllocator<T> &,
                       const CfgLocalAllocator<U> &) {
  return false;
}

// 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

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

// Containers that are arena-allocated from the Cfg's allocator.
typedef std::vector<Operand *, CfgLocalAllocator<Operand *>> OperandList;
typedef std::vector<Variable *, CfgLocalAllocator<Variable *>> VarList;
typedef std::vector<CfgNode *, CfgLocalAllocator<CfgNode *>> NodeList;

// Contains that use the default (global) allocator.
typedef std::vector<Constant *> ConstantList;
typedef std::vector<FunctionDeclaration *> FunctionDeclarationList;
typedef std::vector<VariableDeclaration *> VariableDeclarationList;

/// 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.
typedef uint32_t SizeT;

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

/// 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.
typedef std::pair<SizeT, InstNumberT> LiveBeginEndMapEntry;
typedef std::vector<LiveBeginEndMapEntry,
                    CfgLocalAllocator<LiveBeginEndMapEntry>> LiveBeginEndMap;
typedef llvm::BitVector LivenessBV;

typedef uint32_t TimerStackIdT;
typedef uint32_t TimerIdT;

/// 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.
typedef int32_t RelocOffsetT;
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_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_All = ~IceV_None,
  IceV_Most = IceV_All & ~IceV_LinearScan
};
typedef uint32_t VerboseMask;

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

typedef llvm::raw_ostream Ostream;
typedef llvm::raw_fd_ostream Fdstream;

typedef std::mutex GlobalLockType;

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
};

} // end of namespace Ice

#endif // SUBZERO_SRC_ICEDEFS_H
