InfoByHwMode.cpp 6.6 KB

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