Home | History | Annotate | Line # | Download | only in TableGen
      1 //===--- InfoByHwMode.cpp -------------------------------------------------===//
      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 #include "CodeGenTarget.h"
     15 #include "InfoByHwMode.h"
     16 #include "llvm/ADT/STLExtras.h"
     17 #include "llvm/ADT/Twine.h"
     18 #include "llvm/Support/Debug.h"
     19 #include "llvm/Support/raw_ostream.h"
     20 
     21 #include <set>
     22 #include <string>
     23 
     24 using namespace llvm;
     25 
     26 std::string llvm::getModeName(unsigned Mode) {
     27   if (Mode == DefaultMode)
     28     return "*";
     29   return (Twine('m') + Twine(Mode)).str();
     30 }
     31 
     32 ValueTypeByHwMode::ValueTypeByHwMode(Record *R, const CodeGenHwModes &CGH) {
     33   const HwModeSelect &MS = CGH.getHwModeSelect(R);
     34   for (const HwModeSelect::PairType &P : MS.Items) {
     35     auto I = Map.insert({P.first, MVT(llvm::getValueType(P.second))});
     36     assert(I.second && "Duplicate entry?");
     37     (void)I;
     38   }
     39 }
     40 
     41 ValueTypeByHwMode::ValueTypeByHwMode(Record *R, MVT T) : ValueTypeByHwMode(T) {
     42   if (R->isSubClassOf("PtrValueType"))
     43     PtrAddrSpace = R->getValueAsInt("AddrSpace");
     44 }
     45 
     46 bool ValueTypeByHwMode::operator== (const ValueTypeByHwMode &T) const {
     47   assert(isValid() && T.isValid() && "Invalid type in assignment");
     48   bool Simple = isSimple();
     49   if (Simple != T.isSimple())
     50     return false;
     51   if (Simple)
     52     return getSimple() == T.getSimple();
     53 
     54   return Map == T.Map;
     55 }
     56 
     57 bool ValueTypeByHwMode::operator< (const ValueTypeByHwMode &T) const {
     58   assert(isValid() && T.isValid() && "Invalid type in comparison");
     59   // Default order for maps.
     60   return Map < T.Map;
     61 }
     62 
     63 MVT &ValueTypeByHwMode::getOrCreateTypeForMode(unsigned Mode, MVT Type) {
     64   auto F = Map.find(Mode);
     65   if (F != Map.end())
     66     return F->second;
     67   // If Mode is not in the map, look up the default mode. If it exists,
     68   // make a copy of it for Mode and return it.
     69   auto D = Map.find(DefaultMode);
     70   if (D != Map.end())
     71     return Map.insert(std::make_pair(Mode, D->second)).first->second;
     72   // If default mode is not present either, use provided Type.
     73   return Map.insert(std::make_pair(Mode, Type)).first->second;
     74 }
     75 
     76 StringRef ValueTypeByHwMode::getMVTName(MVT T) {
     77   StringRef N = llvm::getEnumName(T.SimpleTy);
     78   N.consume_front("MVT::");
     79   return N;
     80 }
     81 
     82 void ValueTypeByHwMode::writeToStream(raw_ostream &OS) const {
     83   if (isSimple()) {
     84     OS << getMVTName(getSimple());
     85     return;
     86   }
     87 
     88   std::vector<const PairType*> Pairs;
     89   for (const auto &P : Map)
     90     Pairs.push_back(&P);
     91   llvm::sort(Pairs, deref<std::less<PairType>>());
     92 
     93   OS << '{';
     94   ListSeparator LS(",");
     95   for (const PairType *P : Pairs)
     96     OS << LS << '(' << getModeName(P->first) << ':'
     97        << getMVTName(P->second).str() << ')';
     98   OS << '}';
     99 }
    100 
    101 LLVM_DUMP_METHOD
    102 void ValueTypeByHwMode::dump() const {
    103   dbgs() << *this << '\n';
    104 }
    105 
    106 ValueTypeByHwMode llvm::getValueTypeByHwMode(Record *Rec,
    107                                              const CodeGenHwModes &CGH) {
    108 #ifndef NDEBUG
    109   if (!Rec->isSubClassOf("ValueType"))
    110     Rec->dump();
    111 #endif
    112   assert(Rec->isSubClassOf("ValueType") &&
    113          "Record must be derived from ValueType");
    114   if (Rec->isSubClassOf("HwModeSelect"))
    115     return ValueTypeByHwMode(Rec, CGH);
    116   return ValueTypeByHwMode(Rec, llvm::getValueType(Rec));
    117 }
    118 
    119 RegSizeInfo::RegSizeInfo(Record *R, const CodeGenHwModes &CGH) {
    120   RegSize = R->getValueAsInt("RegSize");
    121   SpillSize = R->getValueAsInt("SpillSize");
    122   SpillAlignment = R->getValueAsInt("SpillAlignment");
    123 }
    124 
    125 bool RegSizeInfo::operator< (const RegSizeInfo &I) const {
    126   return std::tie(RegSize, SpillSize, SpillAlignment) <
    127          std::tie(I.RegSize, I.SpillSize, I.SpillAlignment);
    128 }
    129 
    130 bool RegSizeInfo::isSubClassOf(const RegSizeInfo &I) const {
    131   return RegSize <= I.RegSize &&
    132          SpillAlignment && I.SpillAlignment % SpillAlignment == 0 &&
    133          SpillSize <= I.SpillSize;
    134 }
    135 
    136 void RegSizeInfo::writeToStream(raw_ostream &OS) const {
    137   OS << "[R=" << RegSize << ",S=" << SpillSize
    138      << ",A=" << SpillAlignment << ']';
    139 }
    140 
    141 RegSizeInfoByHwMode::RegSizeInfoByHwMode(Record *R,
    142       const CodeGenHwModes &CGH) {
    143   const HwModeSelect &MS = CGH.getHwModeSelect(R);
    144   for (const HwModeSelect::PairType &P : MS.Items) {
    145     auto I = Map.insert({P.first, RegSizeInfo(P.second, CGH)});
    146     assert(I.second && "Duplicate entry?");
    147     (void)I;
    148   }
    149 }
    150 
    151 bool RegSizeInfoByHwMode::operator< (const RegSizeInfoByHwMode &I) const {
    152   unsigned M0 = Map.begin()->first;
    153   return get(M0) < I.get(M0);
    154 }
    155 
    156 bool RegSizeInfoByHwMode::operator== (const RegSizeInfoByHwMode &I) const {
    157   unsigned M0 = Map.begin()->first;
    158   return get(M0) == I.get(M0);
    159 }
    160 
    161 bool RegSizeInfoByHwMode::isSubClassOf(const RegSizeInfoByHwMode &I) const {
    162   unsigned M0 = Map.begin()->first;
    163   return get(M0).isSubClassOf(I.get(M0));
    164 }
    165 
    166 bool RegSizeInfoByHwMode::hasStricterSpillThan(const RegSizeInfoByHwMode &I)
    167       const {
    168   unsigned M0 = Map.begin()->first;
    169   const RegSizeInfo &A0 = get(M0);
    170   const RegSizeInfo &B0 = I.get(M0);
    171   return std::tie(A0.SpillSize, A0.SpillAlignment) >
    172          std::tie(B0.SpillSize, B0.SpillAlignment);
    173 }
    174 
    175 void RegSizeInfoByHwMode::writeToStream(raw_ostream &OS) const {
    176   typedef typename decltype(Map)::value_type PairType;
    177   std::vector<const PairType*> Pairs;
    178   for (const auto &P : Map)
    179     Pairs.push_back(&P);
    180   llvm::sort(Pairs, deref<std::less<PairType>>());
    181 
    182   OS << '{';
    183   ListSeparator LS(",");
    184   for (const PairType *P : Pairs)
    185     OS << LS << '(' << getModeName(P->first) << ':' << P->second << ')';
    186   OS << '}';
    187 }
    188 
    189 EncodingInfoByHwMode::EncodingInfoByHwMode(Record *R, const CodeGenHwModes &CGH) {
    190   const HwModeSelect &MS = CGH.getHwModeSelect(R);
    191   for (const HwModeSelect::PairType &P : MS.Items) {
    192     assert(P.second && P.second->isSubClassOf("InstructionEncoding") &&
    193            "Encoding must subclass InstructionEncoding");
    194     auto I = Map.insert({P.first, P.second});
    195     assert(I.second && "Duplicate entry?");
    196     (void)I;
    197   }
    198 }
    199 
    200 namespace llvm {
    201   raw_ostream &operator<<(raw_ostream &OS, const ValueTypeByHwMode &T) {
    202     T.writeToStream(OS);
    203     return OS;
    204   }
    205 
    206   raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfo &T) {
    207     T.writeToStream(OS);
    208     return OS;
    209   }
    210 
    211   raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfoByHwMode &T) {
    212     T.writeToStream(OS);
    213     return OS;
    214   }
    215 }
    216