//===--- InfoByHwMode.h -----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Classes that implement data parameterized by HW modes for instruction
// selection. Currently it is ValueTypeByHwMode (parameterized ValueType),
// and RegSizeInfoByHwMode (parameterized register/spill size and alignment
// data).
//===----------------------------------------------------------------------===//

#ifndef LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
#define LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H

#include "CodeGenHwModes.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/Support/MachineValueType.h"

#include <map>
#include <string>
#include <vector>

namespace llvm {

struct CodeGenHwModes;
class Record;
class raw_ostream;

template <typename InfoT> struct InfoByHwMode;

std::string getModeName(unsigned Mode);

enum : unsigned {
  DefaultMode = CodeGenHwModes::DefaultMode,
};

template <typename InfoT>
void union_modes(const InfoByHwMode<InfoT> &A,
                 const InfoByHwMode<InfoT> &B,
                 SmallVectorImpl<unsigned> &Modes) {
  SmallSet<unsigned, 4> U;
  for (const auto &P : A)
    U.insert(P.first);
  for (const auto &P : B)
    U.insert(P.first);
  // Make sure that the default mode is last on the list.
  bool HasDefault = false;
  for (unsigned M : U)
    if (M != DefaultMode)
      Modes.push_back(M);
    else
      HasDefault = true;
  if (HasDefault)
    Modes.push_back(DefaultMode);
}

template <typename InfoT>
struct InfoByHwMode {
  typedef std::map<unsigned,InfoT> MapType;
  typedef typename MapType::value_type PairType;
  typedef typename MapType::iterator iterator;
  typedef typename MapType::const_iterator const_iterator;

  InfoByHwMode() = default;
  InfoByHwMode(const MapType &M) : Map(M) {}

  LLVM_ATTRIBUTE_ALWAYS_INLINE
  iterator begin() { return Map.begin(); }
  LLVM_ATTRIBUTE_ALWAYS_INLINE
  iterator end()   { return Map.end(); }
  LLVM_ATTRIBUTE_ALWAYS_INLINE
  const_iterator begin() const { return Map.begin(); }
  LLVM_ATTRIBUTE_ALWAYS_INLINE
  const_iterator end() const   { return Map.end(); }
  LLVM_ATTRIBUTE_ALWAYS_INLINE
  bool empty() const { return Map.empty(); }

  LLVM_ATTRIBUTE_ALWAYS_INLINE
  bool hasMode(unsigned M) const { return Map.find(M) != Map.end(); }
  LLVM_ATTRIBUTE_ALWAYS_INLINE
  bool hasDefault() const { return hasMode(DefaultMode); }

  InfoT &get(unsigned Mode) {
    if (!hasMode(Mode)) {
      assert(hasMode(DefaultMode));
      Map.insert({Mode, Map.at(DefaultMode)});
    }
    return Map.at(Mode);
  }
  const InfoT &get(unsigned Mode) const {
    auto F = Map.find(Mode);
    if (Mode != DefaultMode && F == Map.end())
      F = Map.find(DefaultMode);
    assert(F != Map.end());
    return F->second;
  }

  LLVM_ATTRIBUTE_ALWAYS_INLINE
  bool isSimple() const {
    return Map.size() == 1 && Map.begin()->first == DefaultMode;
  }
  LLVM_ATTRIBUTE_ALWAYS_INLINE
  InfoT getSimple() const {
    assert(isSimple());
    return Map.begin()->second;
  }
  void makeSimple(unsigned Mode) {
    assert(hasMode(Mode) || hasDefault());
    InfoT I = get(Mode);
    Map.clear();
    Map.insert(std::make_pair(DefaultMode, I));
  }

protected:
  MapType Map;
};

struct ValueTypeByHwMode : public InfoByHwMode<MVT> {
  ValueTypeByHwMode(Record *R, const CodeGenHwModes &CGH);
  ValueTypeByHwMode(Record *R, MVT T);
  ValueTypeByHwMode(MVT T) { Map.insert({DefaultMode,T}); }
  ValueTypeByHwMode() = default;

  bool operator== (const ValueTypeByHwMode &T) const;
  bool operator< (const ValueTypeByHwMode &T) const;

  bool isValid() const {
    return !Map.empty();
  }
  MVT getType(unsigned Mode) const { return get(Mode); }
  MVT &getOrCreateTypeForMode(unsigned Mode, MVT Type);

  static StringRef getMVTName(MVT T);
  void writeToStream(raw_ostream &OS) const;
  void dump() const;

  unsigned PtrAddrSpace = std::numeric_limits<unsigned>::max();
  bool isPointer() const {
    return PtrAddrSpace != std::numeric_limits<unsigned>::max();
  }
};

ValueTypeByHwMode getValueTypeByHwMode(Record *Rec,
                                       const CodeGenHwModes &CGH);

struct RegSizeInfo {
  unsigned RegSize;
  unsigned SpillSize;
  unsigned SpillAlignment;

  RegSizeInfo(Record *R, const CodeGenHwModes &CGH);
  RegSizeInfo() = default;
  bool operator< (const RegSizeInfo &I) const;
  bool operator== (const RegSizeInfo &I) const {
    return std::tie(RegSize, SpillSize, SpillAlignment) ==
           std::tie(I.RegSize, I.SpillSize, I.SpillAlignment);
  }
  bool operator!= (const RegSizeInfo &I) const {
    return !(*this == I);
  }

  bool isSubClassOf(const RegSizeInfo &I) const;
  void writeToStream(raw_ostream &OS) const;
};

struct RegSizeInfoByHwMode : public InfoByHwMode<RegSizeInfo> {
  RegSizeInfoByHwMode(Record *R, const CodeGenHwModes &CGH);
  RegSizeInfoByHwMode() = default;
  bool operator< (const RegSizeInfoByHwMode &VI) const;
  bool operator== (const RegSizeInfoByHwMode &VI) const;
  bool operator!= (const RegSizeInfoByHwMode &VI) const {
    return !(*this == VI);
  }

  bool isSubClassOf(const RegSizeInfoByHwMode &I) const;
  bool hasStricterSpillThan(const RegSizeInfoByHwMode &I) const;

  void writeToStream(raw_ostream &OS) const;

  void insertRegSizeForMode(unsigned Mode, RegSizeInfo Info) {
    Map.insert(std::make_pair(Mode, Info));
  }
};

raw_ostream &operator<<(raw_ostream &OS, const ValueTypeByHwMode &T);
raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfo &T);
raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfoByHwMode &T);

struct EncodingInfoByHwMode : public InfoByHwMode<Record*> {
  EncodingInfoByHwMode(Record *R, const CodeGenHwModes &CGH);
  EncodingInfoByHwMode() = default;
};

} // namespace llvm

#endif // LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
