MCSubtargetInfo.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. //===- llvm/MC/MCSubtargetInfo.h - Subtarget Information --------*- 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. //
  9. // This file describes the subtarget options of a Target machine.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_MC_MCSUBTARGETINFO_H
  13. #define LLVM_MC_MCSUBTARGETINFO_H
  14. #include "llvm/ADT/ArrayRef.h"
  15. #include "llvm/ADT/StringRef.h"
  16. #include "llvm/ADT/Triple.h"
  17. #include "llvm/MC/MCInstrItineraries.h"
  18. #include "llvm/MC/MCSchedule.h"
  19. #include "llvm/MC/SubtargetFeature.h"
  20. #include <algorithm>
  21. #include <cassert>
  22. #include <cstdint>
  23. #include <string>
  24. namespace llvm {
  25. class MCInst;
  26. //===----------------------------------------------------------------------===//
  27. /// Used to provide key value pairs for feature and CPU bit flags.
  28. struct SubtargetFeatureKV {
  29. const char *Key; ///< K-V key string
  30. const char *Desc; ///< Help descriptor
  31. unsigned Value; ///< K-V integer value
  32. FeatureBitArray Implies; ///< K-V bit mask
  33. /// Compare routine for std::lower_bound
  34. bool operator<(StringRef S) const {
  35. return StringRef(Key) < S;
  36. }
  37. /// Compare routine for std::is_sorted.
  38. bool operator<(const SubtargetFeatureKV &Other) const {
  39. return StringRef(Key) < StringRef(Other.Key);
  40. }
  41. };
  42. //===----------------------------------------------------------------------===//
  43. /// Used to provide key value pairs for feature and CPU bit flags.
  44. struct SubtargetSubTypeKV {
  45. const char *Key; ///< K-V key string
  46. FeatureBitArray Implies; ///< K-V bit mask
  47. FeatureBitArray TuneImplies; ///< K-V bit mask
  48. const MCSchedModel *SchedModel;
  49. /// Compare routine for std::lower_bound
  50. bool operator<(StringRef S) const {
  51. return StringRef(Key) < S;
  52. }
  53. /// Compare routine for std::is_sorted.
  54. bool operator<(const SubtargetSubTypeKV &Other) const {
  55. return StringRef(Key) < StringRef(Other.Key);
  56. }
  57. };
  58. //===----------------------------------------------------------------------===//
  59. ///
  60. /// Generic base class for all target subtargets.
  61. ///
  62. class MCSubtargetInfo {
  63. Triple TargetTriple;
  64. std::string CPU; // CPU being targeted.
  65. std::string TuneCPU; // CPU being tuned for.
  66. ArrayRef<SubtargetFeatureKV> ProcFeatures; // Processor feature list
  67. ArrayRef<SubtargetSubTypeKV> ProcDesc; // Processor descriptions
  68. // Scheduler machine model
  69. const MCWriteProcResEntry *WriteProcResTable;
  70. const MCWriteLatencyEntry *WriteLatencyTable;
  71. const MCReadAdvanceEntry *ReadAdvanceTable;
  72. const MCSchedModel *CPUSchedModel;
  73. const InstrStage *Stages; // Instruction itinerary stages
  74. const unsigned *OperandCycles; // Itinerary operand cycles
  75. const unsigned *ForwardingPaths;
  76. FeatureBitset FeatureBits; // Feature bits for current CPU + FS
  77. std::string FeatureString; // Feature string
  78. public:
  79. MCSubtargetInfo(const MCSubtargetInfo &) = default;
  80. MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef TuneCPU,
  81. StringRef FS, ArrayRef<SubtargetFeatureKV> PF,
  82. ArrayRef<SubtargetSubTypeKV> PD,
  83. const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
  84. const MCReadAdvanceEntry *RA, const InstrStage *IS,
  85. const unsigned *OC, const unsigned *FP);
  86. MCSubtargetInfo() = delete;
  87. MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
  88. MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
  89. virtual ~MCSubtargetInfo() = default;
  90. const Triple &getTargetTriple() const { return TargetTriple; }
  91. StringRef getCPU() const { return CPU; }
  92. StringRef getTuneCPU() const { return TuneCPU; }
  93. const FeatureBitset& getFeatureBits() const { return FeatureBits; }
  94. void setFeatureBits(const FeatureBitset &FeatureBits_) {
  95. FeatureBits = FeatureBits_;
  96. }
  97. StringRef getFeatureString() const { return FeatureString; }
  98. bool hasFeature(unsigned Feature) const {
  99. return FeatureBits[Feature];
  100. }
  101. protected:
  102. /// Initialize the scheduling model and feature bits.
  103. ///
  104. /// FIXME: Find a way to stick this in the constructor, since it should only
  105. /// be called during initialization.
  106. void InitMCProcessorInfo(StringRef CPU, StringRef TuneCPU, StringRef FS);
  107. public:
  108. /// Set the features to the default for the given CPU and TuneCPU, with ano
  109. /// appended feature string.
  110. void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
  111. /// Toggle a feature and return the re-computed feature bits.
  112. /// This version does not change the implied bits.
  113. FeatureBitset ToggleFeature(uint64_t FB);
  114. /// Toggle a feature and return the re-computed feature bits.
  115. /// This version does not change the implied bits.
  116. FeatureBitset ToggleFeature(const FeatureBitset& FB);
  117. /// Toggle a set of features and return the re-computed feature bits.
  118. /// This version will also change all implied bits.
  119. FeatureBitset ToggleFeature(StringRef FS);
  120. /// Apply a feature flag and return the re-computed feature bits, including
  121. /// all feature bits implied by the flag.
  122. FeatureBitset ApplyFeatureFlag(StringRef FS);
  123. /// Set/clear additional feature bits, including all other bits they imply.
  124. FeatureBitset SetFeatureBitsTransitively(const FeatureBitset& FB);
  125. FeatureBitset ClearFeatureBitsTransitively(const FeatureBitset &FB);
  126. /// Check whether the subtarget features are enabled/disabled as per
  127. /// the provided string, ignoring all other features.
  128. bool checkFeatures(StringRef FS) const;
  129. /// Get the machine model of a CPU.
  130. const MCSchedModel &getSchedModelForCPU(StringRef CPU) const;
  131. /// Get the machine model for this subtarget's CPU.
  132. const MCSchedModel &getSchedModel() const { return *CPUSchedModel; }
  133. /// Return an iterator at the first process resource consumed by the given
  134. /// scheduling class.
  135. const MCWriteProcResEntry *getWriteProcResBegin(
  136. const MCSchedClassDesc *SC) const {
  137. return &WriteProcResTable[SC->WriteProcResIdx];
  138. }
  139. const MCWriteProcResEntry *getWriteProcResEnd(
  140. const MCSchedClassDesc *SC) const {
  141. return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
  142. }
  143. const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
  144. unsigned DefIdx) const {
  145. assert(DefIdx < SC->NumWriteLatencyEntries &&
  146. "MachineModel does not specify a WriteResource for DefIdx");
  147. return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
  148. }
  149. int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
  150. unsigned WriteResID) const {
  151. // TODO: The number of read advance entries in a class can be significant
  152. // (~50). Consider compressing the WriteID into a dense ID of those that are
  153. // used by ReadAdvance and representing them as a bitset.
  154. for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
  155. *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
  156. if (I->UseIdx < UseIdx)
  157. continue;
  158. if (I->UseIdx > UseIdx)
  159. break;
  160. // Find the first WriteResIdx match, which has the highest cycle count.
  161. if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
  162. return I->Cycles;
  163. }
  164. }
  165. return 0;
  166. }
  167. /// Return the set of ReadAdvance entries declared by the scheduling class
  168. /// descriptor in input.
  169. ArrayRef<MCReadAdvanceEntry>
  170. getReadAdvanceEntries(const MCSchedClassDesc &SC) const {
  171. if (!SC.NumReadAdvanceEntries)
  172. return ArrayRef<MCReadAdvanceEntry>();
  173. return ArrayRef<MCReadAdvanceEntry>(&ReadAdvanceTable[SC.ReadAdvanceIdx],
  174. SC.NumReadAdvanceEntries);
  175. }
  176. /// Get scheduling itinerary of a CPU.
  177. InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
  178. /// Initialize an InstrItineraryData instance.
  179. void initInstrItins(InstrItineraryData &InstrItins) const;
  180. /// Resolve a variant scheduling class for the given MCInst and CPU.
  181. virtual unsigned resolveVariantSchedClass(unsigned SchedClass,
  182. const MCInst *MI,
  183. const MCInstrInfo *MCII,
  184. unsigned CPUID) const {
  185. return 0;
  186. }
  187. /// Check whether the CPU string is valid.
  188. bool isCPUStringValid(StringRef CPU) const {
  189. auto Found = llvm::lower_bound(ProcDesc, CPU);
  190. return Found != ProcDesc.end() && StringRef(Found->Key) == CPU;
  191. }
  192. virtual unsigned getHwMode() const { return 0; }
  193. /// Return the cache size in bytes for the given level of cache.
  194. /// Level is zero-based, so a value of zero means the first level of
  195. /// cache.
  196. ///
  197. virtual Optional<unsigned> getCacheSize(unsigned Level) const;
  198. /// Return the cache associatvity for the given level of cache.
  199. /// Level is zero-based, so a value of zero means the first level of
  200. /// cache.
  201. ///
  202. virtual Optional<unsigned> getCacheAssociativity(unsigned Level) const;
  203. /// Return the target cache line size in bytes at a given level.
  204. ///
  205. virtual Optional<unsigned> getCacheLineSize(unsigned Level) const;
  206. /// Return the target cache line size in bytes. By default, return
  207. /// the line size for the bottom-most level of cache. This provides
  208. /// a more convenient interface for the common case where all cache
  209. /// levels have the same line size. Return zero if there is no
  210. /// cache model.
  211. ///
  212. virtual unsigned getCacheLineSize() const {
  213. Optional<unsigned> Size = getCacheLineSize(0);
  214. if (Size)
  215. return *Size;
  216. return 0;
  217. }
  218. /// Return the preferred prefetch distance in terms of instructions.
  219. ///
  220. virtual unsigned getPrefetchDistance() const;
  221. /// Return the maximum prefetch distance in terms of loop
  222. /// iterations.
  223. ///
  224. virtual unsigned getMaxPrefetchIterationsAhead() const;
  225. /// \return True if prefetching should also be done for writes.
  226. ///
  227. virtual bool enableWritePrefetching() const;
  228. /// Return the minimum stride necessary to trigger software
  229. /// prefetching.
  230. ///
  231. virtual unsigned getMinPrefetchStride(unsigned NumMemAccesses,
  232. unsigned NumStridedMemAccesses,
  233. unsigned NumPrefetches,
  234. bool HasCall) const;
  235. };
  236. } // end namespace llvm
  237. #endif // LLVM_MC_MCSUBTARGETINFO_H