1fa3d789dSPierre van Houtryve //===--- InfoByHwMode.cpp -------------------------------------------------===// 2fa3d789dSPierre van Houtryve // 3fa3d789dSPierre van Houtryve // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fa3d789dSPierre van Houtryve // See https://llvm.org/LICENSE.txt for license information. 5fa3d789dSPierre van Houtryve // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fa3d789dSPierre van Houtryve // 7fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 8fa3d789dSPierre van Houtryve // Classes that implement data parameterized by HW modes for instruction 9fa3d789dSPierre van Houtryve // selection. Currently it is ValueTypeByHwMode (parameterized ValueType), 10fa3d789dSPierre van Houtryve // and RegSizeInfoByHwMode (parameterized register/spill size and alignment 11fa3d789dSPierre van Houtryve // data). 12fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 13fa3d789dSPierre van Houtryve 14fa3d789dSPierre van Houtryve #include "InfoByHwMode.h" 15fa3d789dSPierre van Houtryve #include "CodeGenTarget.h" 16fa3d789dSPierre van Houtryve #include "llvm/ADT/STLExtras.h" 17fa3d789dSPierre van Houtryve #include "llvm/ADT/Twine.h" 18fa3d789dSPierre van Houtryve #include "llvm/Support/Debug.h" 19fa3d789dSPierre van Houtryve #include "llvm/Support/raw_ostream.h" 20fa3d789dSPierre van Houtryve #include "llvm/TableGen/Record.h" 21fa3d789dSPierre van Houtryve #include <string> 22fa3d789dSPierre van Houtryve 23fa3d789dSPierre van Houtryve using namespace llvm; 24fa3d789dSPierre van Houtryve 25fa3d789dSPierre van Houtryve std::string llvm::getModeName(unsigned Mode) { 26fa3d789dSPierre van Houtryve if (Mode == DefaultMode) 27fa3d789dSPierre van Houtryve return "*"; 28fa3d789dSPierre van Houtryve return (Twine('m') + Twine(Mode)).str(); 29fa3d789dSPierre van Houtryve } 30fa3d789dSPierre van Houtryve 317c6592f5SRahul Joshi ValueTypeByHwMode::ValueTypeByHwMode(const Record *R, 327c6592f5SRahul Joshi const CodeGenHwModes &CGH) { 33fa3d789dSPierre van Houtryve const HwModeSelect &MS = CGH.getHwModeSelect(R); 34fa3d789dSPierre van Houtryve for (const HwModeSelect::PairType &P : MS.Items) { 35fa3d789dSPierre van Houtryve auto I = Map.insert({P.first, MVT(llvm::getValueType(P.second))}); 36fa3d789dSPierre van Houtryve assert(I.second && "Duplicate entry?"); 37fa3d789dSPierre van Houtryve (void)I; 38fa3d789dSPierre van Houtryve } 39fa3d789dSPierre van Houtryve if (R->isSubClassOf("PtrValueType")) 40fa3d789dSPierre van Houtryve PtrAddrSpace = R->getValueAsInt("AddrSpace"); 41fa3d789dSPierre van Houtryve } 42fa3d789dSPierre van Houtryve 437c6592f5SRahul Joshi ValueTypeByHwMode::ValueTypeByHwMode(const Record *R, MVT T) 447c6592f5SRahul Joshi : ValueTypeByHwMode(T) { 45fa3d789dSPierre van Houtryve if (R->isSubClassOf("PtrValueType")) 46fa3d789dSPierre van Houtryve PtrAddrSpace = R->getValueAsInt("AddrSpace"); 47fa3d789dSPierre van Houtryve } 48fa3d789dSPierre van Houtryve 49fa3d789dSPierre van Houtryve bool ValueTypeByHwMode::operator==(const ValueTypeByHwMode &T) const { 50fa3d789dSPierre van Houtryve assert(isValid() && T.isValid() && "Invalid type in assignment"); 51fa3d789dSPierre van Houtryve bool Simple = isSimple(); 52fa3d789dSPierre van Houtryve if (Simple != T.isSimple()) 53fa3d789dSPierre van Houtryve return false; 54fa3d789dSPierre van Houtryve if (Simple) 55fa3d789dSPierre van Houtryve return getSimple() == T.getSimple(); 56fa3d789dSPierre van Houtryve 57fa3d789dSPierre van Houtryve return Map == T.Map; 58fa3d789dSPierre van Houtryve } 59fa3d789dSPierre van Houtryve 60fa3d789dSPierre van Houtryve bool ValueTypeByHwMode::operator<(const ValueTypeByHwMode &T) const { 61fa3d789dSPierre van Houtryve assert(isValid() && T.isValid() && "Invalid type in comparison"); 62fa3d789dSPierre van Houtryve // Default order for maps. 63fa3d789dSPierre van Houtryve return Map < T.Map; 64fa3d789dSPierre van Houtryve } 65fa3d789dSPierre van Houtryve 66fa3d789dSPierre van Houtryve MVT &ValueTypeByHwMode::getOrCreateTypeForMode(unsigned Mode, MVT Type) { 67fa3d789dSPierre van Houtryve auto F = Map.find(Mode); 68fa3d789dSPierre van Houtryve if (F != Map.end()) 69fa3d789dSPierre van Houtryve return F->second; 70fa3d789dSPierre van Houtryve // If Mode is not in the map, look up the default mode. If it exists, 71fa3d789dSPierre van Houtryve // make a copy of it for Mode and return it. 72fa3d789dSPierre van Houtryve auto D = Map.begin(); 73fa3d789dSPierre van Houtryve if (D != Map.end() && D->first == DefaultMode) 74*4e8c9d28SJay Foad return Map.try_emplace(Mode, D->second).first->second; 75fa3d789dSPierre van Houtryve // If default mode is not present either, use provided Type. 76*4e8c9d28SJay Foad return Map.try_emplace(Mode, Type).first->second; 77fa3d789dSPierre van Houtryve } 78fa3d789dSPierre van Houtryve 79fa3d789dSPierre van Houtryve StringRef ValueTypeByHwMode::getMVTName(MVT T) { 80fa3d789dSPierre van Houtryve StringRef N = llvm::getEnumName(T.SimpleTy); 81fa3d789dSPierre van Houtryve N.consume_front("MVT::"); 82fa3d789dSPierre van Houtryve return N; 83fa3d789dSPierre van Houtryve } 84fa3d789dSPierre van Houtryve 85fa3d789dSPierre van Houtryve void ValueTypeByHwMode::writeToStream(raw_ostream &OS) const { 86fa3d789dSPierre van Houtryve if (isSimple()) { 87fa3d789dSPierre van Houtryve OS << getMVTName(getSimple()); 88fa3d789dSPierre van Houtryve return; 89fa3d789dSPierre van Houtryve } 90fa3d789dSPierre van Houtryve 91fa3d789dSPierre van Houtryve std::vector<const PairType *> Pairs; 92fa3d789dSPierre van Houtryve for (const auto &P : Map) 93fa3d789dSPierre van Houtryve Pairs.push_back(&P); 94fa3d789dSPierre van Houtryve llvm::sort(Pairs, deref<std::less<PairType>>()); 95fa3d789dSPierre van Houtryve 96fa3d789dSPierre van Houtryve OS << '{'; 97fa3d789dSPierre van Houtryve ListSeparator LS(","); 98fa3d789dSPierre van Houtryve for (const PairType *P : Pairs) 99fa3d789dSPierre van Houtryve OS << LS << '(' << getModeName(P->first) << ':' 100fa3d789dSPierre van Houtryve << getMVTName(P->second).str() << ')'; 101fa3d789dSPierre van Houtryve OS << '}'; 102fa3d789dSPierre van Houtryve } 103fa3d789dSPierre van Houtryve 104fa3d789dSPierre van Houtryve LLVM_DUMP_METHOD 105fa3d789dSPierre van Houtryve void ValueTypeByHwMode::dump() const { dbgs() << *this << '\n'; } 106fa3d789dSPierre van Houtryve 1077c6592f5SRahul Joshi ValueTypeByHwMode llvm::getValueTypeByHwMode(const Record *Rec, 108fa3d789dSPierre van Houtryve const CodeGenHwModes &CGH) { 109fa3d789dSPierre van Houtryve #ifndef NDEBUG 110fa3d789dSPierre van Houtryve if (!Rec->isSubClassOf("ValueType")) 111fa3d789dSPierre van Houtryve Rec->dump(); 112fa3d789dSPierre van Houtryve #endif 113fa3d789dSPierre van Houtryve assert(Rec->isSubClassOf("ValueType") && 114fa3d789dSPierre van Houtryve "Record must be derived from ValueType"); 115fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("HwModeSelect")) 116fa3d789dSPierre van Houtryve return ValueTypeByHwMode(Rec, CGH); 117fa3d789dSPierre van Houtryve return ValueTypeByHwMode(Rec, llvm::getValueType(Rec)); 118fa3d789dSPierre van Houtryve } 119fa3d789dSPierre van Houtryve 120985600dcSRahul Joshi RegSizeInfo::RegSizeInfo(const Record *R) { 121fa3d789dSPierre van Houtryve RegSize = R->getValueAsInt("RegSize"); 122fa3d789dSPierre van Houtryve SpillSize = R->getValueAsInt("SpillSize"); 123fa3d789dSPierre van Houtryve SpillAlignment = R->getValueAsInt("SpillAlignment"); 124fa3d789dSPierre van Houtryve } 125fa3d789dSPierre van Houtryve 126fa3d789dSPierre van Houtryve bool RegSizeInfo::operator<(const RegSizeInfo &I) const { 127fa3d789dSPierre van Houtryve return std::tie(RegSize, SpillSize, SpillAlignment) < 128fa3d789dSPierre van Houtryve std::tie(I.RegSize, I.SpillSize, I.SpillAlignment); 129fa3d789dSPierre van Houtryve } 130fa3d789dSPierre van Houtryve 131fa3d789dSPierre van Houtryve bool RegSizeInfo::isSubClassOf(const RegSizeInfo &I) const { 132fa3d789dSPierre van Houtryve return RegSize <= I.RegSize && SpillAlignment && 133fa3d789dSPierre van Houtryve I.SpillAlignment % SpillAlignment == 0 && SpillSize <= I.SpillSize; 134fa3d789dSPierre van Houtryve } 135fa3d789dSPierre van Houtryve 136fa3d789dSPierre van Houtryve void RegSizeInfo::writeToStream(raw_ostream &OS) const { 137fa3d789dSPierre van Houtryve OS << "[R=" << RegSize << ",S=" << SpillSize << ",A=" << SpillAlignment 138fa3d789dSPierre van Houtryve << ']'; 139fa3d789dSPierre van Houtryve } 140fa3d789dSPierre van Houtryve 141985600dcSRahul Joshi RegSizeInfoByHwMode::RegSizeInfoByHwMode(const Record *R, 142985600dcSRahul Joshi const CodeGenHwModes &CGH) { 143fa3d789dSPierre van Houtryve const HwModeSelect &MS = CGH.getHwModeSelect(R); 144fa3d789dSPierre van Houtryve for (const HwModeSelect::PairType &P : MS.Items) { 145fa3d789dSPierre van Houtryve auto I = Map.insert({P.first, RegSizeInfo(P.second)}); 146fa3d789dSPierre van Houtryve assert(I.second && "Duplicate entry?"); 147fa3d789dSPierre van Houtryve (void)I; 148fa3d789dSPierre van Houtryve } 149fa3d789dSPierre van Houtryve } 150fa3d789dSPierre van Houtryve 151fa3d789dSPierre van Houtryve bool RegSizeInfoByHwMode::operator<(const RegSizeInfoByHwMode &I) const { 152fa3d789dSPierre van Houtryve unsigned M0 = Map.begin()->first; 153fa3d789dSPierre van Houtryve return get(M0) < I.get(M0); 154fa3d789dSPierre van Houtryve } 155fa3d789dSPierre van Houtryve 156fa3d789dSPierre van Houtryve bool RegSizeInfoByHwMode::operator==(const RegSizeInfoByHwMode &I) const { 157fa3d789dSPierre van Houtryve unsigned M0 = Map.begin()->first; 158fa3d789dSPierre van Houtryve return get(M0) == I.get(M0); 159fa3d789dSPierre van Houtryve } 160fa3d789dSPierre van Houtryve 161fa3d789dSPierre van Houtryve bool RegSizeInfoByHwMode::isSubClassOf(const RegSizeInfoByHwMode &I) const { 162fa3d789dSPierre van Houtryve unsigned M0 = Map.begin()->first; 163fa3d789dSPierre van Houtryve return get(M0).isSubClassOf(I.get(M0)); 164fa3d789dSPierre van Houtryve } 165fa3d789dSPierre van Houtryve 166fa3d789dSPierre van Houtryve bool RegSizeInfoByHwMode::hasStricterSpillThan( 167fa3d789dSPierre van Houtryve const RegSizeInfoByHwMode &I) const { 168fa3d789dSPierre van Houtryve unsigned M0 = Map.begin()->first; 169fa3d789dSPierre van Houtryve const RegSizeInfo &A0 = get(M0); 170fa3d789dSPierre van Houtryve const RegSizeInfo &B0 = I.get(M0); 171fa3d789dSPierre van Houtryve return std::tie(A0.SpillSize, A0.SpillAlignment) > 172fa3d789dSPierre van Houtryve std::tie(B0.SpillSize, B0.SpillAlignment); 173fa3d789dSPierre van Houtryve } 174fa3d789dSPierre van Houtryve 175fa3d789dSPierre van Houtryve void RegSizeInfoByHwMode::writeToStream(raw_ostream &OS) const { 176fa3d789dSPierre van Houtryve typedef typename decltype(Map)::value_type PairType; 177fa3d789dSPierre van Houtryve std::vector<const PairType *> Pairs; 178fa3d789dSPierre van Houtryve for (const auto &P : Map) 179fa3d789dSPierre van Houtryve Pairs.push_back(&P); 180fa3d789dSPierre van Houtryve llvm::sort(Pairs, deref<std::less<PairType>>()); 181fa3d789dSPierre van Houtryve 182fa3d789dSPierre van Houtryve OS << '{'; 183fa3d789dSPierre van Houtryve ListSeparator LS(","); 184fa3d789dSPierre van Houtryve for (const PairType *P : Pairs) 185fa3d789dSPierre van Houtryve OS << LS << '(' << getModeName(P->first) << ':' << P->second << ')'; 186fa3d789dSPierre van Houtryve OS << '}'; 187fa3d789dSPierre van Houtryve } 188fa3d789dSPierre van Houtryve 189985600dcSRahul Joshi SubRegRange::SubRegRange(const Record *R) { 190baf66ec0SCraig Topper Size = R->getValueAsInt("Size"); 191baf66ec0SCraig Topper Offset = R->getValueAsInt("Offset"); 192baf66ec0SCraig Topper } 193baf66ec0SCraig Topper 194985600dcSRahul Joshi SubRegRangeByHwMode::SubRegRangeByHwMode(const Record *R, 195985600dcSRahul Joshi const CodeGenHwModes &CGH) { 196baf66ec0SCraig Topper const HwModeSelect &MS = CGH.getHwModeSelect(R); 197baf66ec0SCraig Topper for (const HwModeSelect::PairType &P : MS.Items) { 198baf66ec0SCraig Topper auto I = Map.insert({P.first, SubRegRange(P.second)}); 199baf66ec0SCraig Topper assert(I.second && "Duplicate entry?"); 200baf66ec0SCraig Topper (void)I; 201baf66ec0SCraig Topper } 202baf66ec0SCraig Topper } 203baf66ec0SCraig Topper 204985600dcSRahul Joshi EncodingInfoByHwMode::EncodingInfoByHwMode(const Record *R, 205fa3d789dSPierre van Houtryve const CodeGenHwModes &CGH) { 206fa3d789dSPierre van Houtryve const HwModeSelect &MS = CGH.getHwModeSelect(R); 207fa3d789dSPierre van Houtryve for (const HwModeSelect::PairType &P : MS.Items) { 208fa3d789dSPierre van Houtryve assert(P.second && P.second->isSubClassOf("InstructionEncoding") && 209fa3d789dSPierre van Houtryve "Encoding must subclass InstructionEncoding"); 210fa3d789dSPierre van Houtryve auto I = Map.insert({P.first, P.second}); 211fa3d789dSPierre van Houtryve assert(I.second && "Duplicate entry?"); 212fa3d789dSPierre van Houtryve (void)I; 213fa3d789dSPierre van Houtryve } 214fa3d789dSPierre van Houtryve } 215fa3d789dSPierre van Houtryve 216fa3d789dSPierre van Houtryve namespace llvm { 217fa3d789dSPierre van Houtryve raw_ostream &operator<<(raw_ostream &OS, const ValueTypeByHwMode &T) { 218fa3d789dSPierre van Houtryve T.writeToStream(OS); 219fa3d789dSPierre van Houtryve return OS; 220fa3d789dSPierre van Houtryve } 221fa3d789dSPierre van Houtryve 222fa3d789dSPierre van Houtryve raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfo &T) { 223fa3d789dSPierre van Houtryve T.writeToStream(OS); 224fa3d789dSPierre van Houtryve return OS; 225fa3d789dSPierre van Houtryve } 226fa3d789dSPierre van Houtryve 227fa3d789dSPierre van Houtryve raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfoByHwMode &T) { 228fa3d789dSPierre van Houtryve T.writeToStream(OS); 229fa3d789dSPierre van Houtryve return OS; 230fa3d789dSPierre van Houtryve } 231fa3d789dSPierre van Houtryve } // namespace llvm 232