Home | History | Annotate | Line # | Download | only in TableGen
      1 //===--- InfoByHwMode.h -----------------------------------------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 // Classes that implement data parameterized by HW modes for instruction
      9 // selection. Currently it is ValueTypeByHwMode (parameterized ValueType),
     10 // and RegSizeInfoByHwMode (parameterized register/spill size and alignment
     11 // data).
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
     15 #define LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
     16 
     17 #include "CodeGenHwModes.h"
     18 #include "llvm/ADT/SmallSet.h"
     19 #include "llvm/Support/MachineValueType.h"
     20 
     21 #include <map>
     22 #include <string>
     23 #include <vector>
     24 
     25 namespace llvm {
     26 
     27 struct CodeGenHwModes;
     28 class Record;
     29 class raw_ostream;
     30 
     31 template <typename InfoT> struct InfoByHwMode;
     32 
     33 std::string getModeName(unsigned Mode);
     34 
     35 enum : unsigned {
     36   DefaultMode = CodeGenHwModes::DefaultMode,
     37 };
     38 
     39 template <typename InfoT>
     40 void union_modes(const InfoByHwMode<InfoT> &A,
     41                  const InfoByHwMode<InfoT> &B,
     42                  SmallVectorImpl<unsigned> &Modes) {
     43   SmallSet<unsigned, 4> U;
     44   for (const auto &P : A)
     45     U.insert(P.first);
     46   for (const auto &P : B)
     47     U.insert(P.first);
     48   // Make sure that the default mode is last on the list.
     49   bool HasDefault = false;
     50   for (unsigned M : U)
     51     if (M != DefaultMode)
     52       Modes.push_back(M);
     53     else
     54       HasDefault = true;
     55   if (HasDefault)
     56     Modes.push_back(DefaultMode);
     57 }
     58 
     59 template <typename InfoT>
     60 struct InfoByHwMode {
     61   typedef std::map<unsigned,InfoT> MapType;
     62   typedef typename MapType::value_type PairType;
     63   typedef typename MapType::iterator iterator;
     64   typedef typename MapType::const_iterator const_iterator;
     65 
     66   InfoByHwMode() = default;
     67   InfoByHwMode(const MapType &M) : Map(M) {}
     68 
     69   LLVM_ATTRIBUTE_ALWAYS_INLINE
     70   iterator begin() { return Map.begin(); }
     71   LLVM_ATTRIBUTE_ALWAYS_INLINE
     72   iterator end()   { return Map.end(); }
     73   LLVM_ATTRIBUTE_ALWAYS_INLINE
     74   const_iterator begin() const { return Map.begin(); }
     75   LLVM_ATTRIBUTE_ALWAYS_INLINE
     76   const_iterator end() const   { return Map.end(); }
     77   LLVM_ATTRIBUTE_ALWAYS_INLINE
     78   bool empty() const { return Map.empty(); }
     79 
     80   LLVM_ATTRIBUTE_ALWAYS_INLINE
     81   bool hasMode(unsigned M) const { return Map.find(M) != Map.end(); }
     82   LLVM_ATTRIBUTE_ALWAYS_INLINE
     83   bool hasDefault() const { return hasMode(DefaultMode); }
     84 
     85   InfoT &get(unsigned Mode) {
     86     if (!hasMode(Mode)) {
     87       assert(hasMode(DefaultMode));
     88       Map.insert({Mode, Map.at(DefaultMode)});
     89     }
     90     return Map.at(Mode);
     91   }
     92   const InfoT &get(unsigned Mode) const {
     93     auto F = Map.find(Mode);
     94     if (Mode != DefaultMode && F == Map.end())
     95       F = Map.find(DefaultMode);
     96     assert(F != Map.end());
     97     return F->second;
     98   }
     99 
    100   LLVM_ATTRIBUTE_ALWAYS_INLINE
    101   bool isSimple() const {
    102     return Map.size() == 1 && Map.begin()->first == DefaultMode;
    103   }
    104   LLVM_ATTRIBUTE_ALWAYS_INLINE
    105   InfoT getSimple() const {
    106     assert(isSimple());
    107     return Map.begin()->second;
    108   }
    109   void makeSimple(unsigned Mode) {
    110     assert(hasMode(Mode) || hasDefault());
    111     InfoT I = get(Mode);
    112     Map.clear();
    113     Map.insert(std::make_pair(DefaultMode, I));
    114   }
    115 
    116 protected:
    117   MapType Map;
    118 };
    119 
    120 struct ValueTypeByHwMode : public InfoByHwMode<MVT> {
    121   ValueTypeByHwMode(Record *R, const CodeGenHwModes &CGH);
    122   ValueTypeByHwMode(Record *R, MVT T);
    123   ValueTypeByHwMode(MVT T) { Map.insert({DefaultMode,T}); }
    124   ValueTypeByHwMode() = default;
    125 
    126   bool operator== (const ValueTypeByHwMode &T) const;
    127   bool operator< (const ValueTypeByHwMode &T) const;
    128 
    129   bool isValid() const {
    130     return !Map.empty();
    131   }
    132   MVT getType(unsigned Mode) const { return get(Mode); }
    133   MVT &getOrCreateTypeForMode(unsigned Mode, MVT Type);
    134 
    135   static StringRef getMVTName(MVT T);
    136   void writeToStream(raw_ostream &OS) const;
    137   void dump() const;
    138 
    139   unsigned PtrAddrSpace = std::numeric_limits<unsigned>::max();
    140   bool isPointer() const {
    141     return PtrAddrSpace != std::numeric_limits<unsigned>::max();
    142   }
    143 };
    144 
    145 ValueTypeByHwMode getValueTypeByHwMode(Record *Rec,
    146                                        const CodeGenHwModes &CGH);
    147 
    148 struct RegSizeInfo {
    149   unsigned RegSize;
    150   unsigned SpillSize;
    151   unsigned SpillAlignment;
    152 
    153   RegSizeInfo(Record *R, const CodeGenHwModes &CGH);
    154   RegSizeInfo() = default;
    155   bool operator< (const RegSizeInfo &I) const;
    156   bool operator== (const RegSizeInfo &I) const {
    157     return std::tie(RegSize, SpillSize, SpillAlignment) ==
    158            std::tie(I.RegSize, I.SpillSize, I.SpillAlignment);
    159   }
    160   bool operator!= (const RegSizeInfo &I) const {
    161     return !(*this == I);
    162   }
    163 
    164   bool isSubClassOf(const RegSizeInfo &I) const;
    165   void writeToStream(raw_ostream &OS) const;
    166 };
    167 
    168 struct RegSizeInfoByHwMode : public InfoByHwMode<RegSizeInfo> {
    169   RegSizeInfoByHwMode(Record *R, const CodeGenHwModes &CGH);
    170   RegSizeInfoByHwMode() = default;
    171   bool operator< (const RegSizeInfoByHwMode &VI) const;
    172   bool operator== (const RegSizeInfoByHwMode &VI) const;
    173   bool operator!= (const RegSizeInfoByHwMode &VI) const {
    174     return !(*this == VI);
    175   }
    176 
    177   bool isSubClassOf(const RegSizeInfoByHwMode &I) const;
    178   bool hasStricterSpillThan(const RegSizeInfoByHwMode &I) const;
    179 
    180   void writeToStream(raw_ostream &OS) const;
    181 
    182   void insertRegSizeForMode(unsigned Mode, RegSizeInfo Info) {
    183     Map.insert(std::make_pair(Mode, Info));
    184   }
    185 };
    186 
    187 raw_ostream &operator<<(raw_ostream &OS, const ValueTypeByHwMode &T);
    188 raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfo &T);
    189 raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfoByHwMode &T);
    190 
    191 struct EncodingInfoByHwMode : public InfoByHwMode<Record*> {
    192   EncodingInfoByHwMode(Record *R, const CodeGenHwModes &CGH);
    193   EncodingInfoByHwMode() = default;
    194 };
    195 
    196 } // namespace llvm
    197 
    198 #endif // LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
    199