//===--- 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/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/Support/Compiler.h"
#include <cassert>
#include <limits>
#include <map>
#include <string>
#include <tuple>
#include <utility>

namespace llvm {

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) {
  auto AI = A.begin();
  auto BI = B.begin();

  // Skip default mode, but remember if we had one.
  bool HasDefault = false;
  if (AI != A.end() && AI->first == DefaultMode) {
    HasDefault = true;
    ++AI;
  }
  if (BI != B.end() && BI->first == DefaultMode) {
    HasDefault = true;
    ++BI;
  }

  while (AI != A.end()) {
    // If we're done with B, finish A.
    if (BI == B.end()) {
      for (; AI != A.end(); ++AI)
        Modes.push_back(AI->first);
      break;
    }

    if (BI->first < AI->first) {
      Modes.push_back(BI->first);
      ++BI;
    } else {
      Modes.push_back(AI->first);
      if (AI->first == BI->first)
        ++BI;
      ++AI;
    }
  }

  // Finish B.
  for (; BI != B.end(); ++BI)
    Modes.push_back(BI->first);

  // Make sure that the default mode is last on the list.
  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 !Map.empty() && Map.begin()->first == DefaultMode;
  }

  InfoT &get(unsigned Mode) {
    auto F = Map.find(Mode);
    if (F != Map.end())
      return F->second;

    // Copy and insert the default mode which should be first.
    assert(hasDefault());
    auto P = Map.insert({Mode, Map.begin()->second});
    return P.first->second;
  }
  const InfoT &get(unsigned Mode) const {
    auto F = Map.find(Mode);
    if (F != Map.end())
      return F->second;
    // Get the default mode which should be first.
    F = Map.begin();
    assert(F != Map.end() && F->first == DefaultMode);
    return F->second;
  }

  LLVM_ATTRIBUTE_ALWAYS_INLINE
  bool isSimple() const {
    return Map.size() == 1 && Map.begin()->first == DefaultMode;
  }
  LLVM_ATTRIBUTE_ALWAYS_INLINE
  const 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
