xref: /freebsd/contrib/llvm-project/llvm/include/llvm/MC/MCSubtargetInfo.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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 
13 #ifndef LLVM_MC_MCSUBTARGETINFO_H
14 #define LLVM_MC_MCSUBTARGETINFO_H
15 
16 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/MC/MCInstrItineraries.h"
20 #include "llvm/MC/MCSchedule.h"
21 #include "llvm/Support/Compiler.h"
22 #include "llvm/TargetParser/SubtargetFeature.h"
23 #include "llvm/TargetParser/Triple.h"
24 #include <cassert>
25 #include <cstdint>
26 #include <optional>
27 #include <string>
28 
29 namespace llvm {
30 
31 class MCInst;
32 
33 //===----------------------------------------------------------------------===//
34 
35 /// Used to provide key value pairs for feature and CPU bit flags.
36 struct SubtargetFeatureKV {
37   const char *Key;                      ///< K-V key string
38   const char *Desc;                     ///< Help descriptor
39   unsigned Value;                       ///< K-V integer value
40   FeatureBitArray Implies;              ///< K-V bit mask
41 
42   /// Compare routine for std::lower_bound
43   bool operator<(StringRef S) const {
44     return StringRef(Key) < S;
45   }
46 
47   /// Compare routine for std::is_sorted.
48   bool operator<(const SubtargetFeatureKV &Other) const {
49     return StringRef(Key) < StringRef(Other.Key);
50   }
51 };
52 
53 //===----------------------------------------------------------------------===//
54 
55 /// Used to provide key value pairs for feature and CPU bit flags.
56 struct SubtargetSubTypeKV {
57   const char *Key;                      ///< K-V key string
58   FeatureBitArray Implies;              ///< K-V bit mask
59   FeatureBitArray TuneImplies;          ///< K-V bit mask
60   const MCSchedModel *SchedModel;
61 
62   /// Compare routine for std::lower_bound
63   bool operator<(StringRef S) const {
64     return StringRef(Key) < S;
65   }
66 
67   /// Compare routine for std::is_sorted.
68   bool operator<(const SubtargetSubTypeKV &Other) const {
69     return StringRef(Key) < StringRef(Other.Key);
70   }
71 };
72 
73 //===----------------------------------------------------------------------===//
74 ///
75 /// Generic base class for all target subtargets.
76 ///
77 class LLVM_ABI MCSubtargetInfo {
78   Triple TargetTriple;
79   std::string CPU; // CPU being targeted.
80   std::string TuneCPU; // CPU being tuned for.
81   ArrayRef<StringRef> ProcNames; // Processor list, including aliases
82   ArrayRef<SubtargetFeatureKV> ProcFeatures;  // Processor feature list
83   ArrayRef<SubtargetSubTypeKV> ProcDesc;  // Processor descriptions
84 
85   // Scheduler machine model
86   const MCWriteProcResEntry *WriteProcResTable;
87   const MCWriteLatencyEntry *WriteLatencyTable;
88   const MCReadAdvanceEntry *ReadAdvanceTable;
89   const MCSchedModel *CPUSchedModel;
90 
91   const InstrStage *Stages;            // Instruction itinerary stages
92   const unsigned *OperandCycles;       // Itinerary operand cycles
93   const unsigned *ForwardingPaths;
94   FeatureBitset FeatureBits;           // Feature bits for current CPU + FS
95   std::string FeatureString;           // Feature string
96 
97 public:
98   MCSubtargetInfo(const MCSubtargetInfo &) = default;
99   MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef TuneCPU,
100                   StringRef FS, ArrayRef<StringRef> PN,
101                   ArrayRef<SubtargetFeatureKV> PF,
102                   ArrayRef<SubtargetSubTypeKV> PD,
103                   const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
104                   const MCReadAdvanceEntry *RA, const InstrStage *IS,
105                   const unsigned *OC, const unsigned *FP);
106   MCSubtargetInfo() = delete;
107   MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
108   MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
109   virtual ~MCSubtargetInfo() = default;
110 
getTargetTriple()111   const Triple &getTargetTriple() const { return TargetTriple; }
getCPU()112   StringRef getCPU() const { return CPU; }
getTuneCPU()113   StringRef getTuneCPU() const { return TuneCPU; }
114 
getFeatureBits()115   const FeatureBitset& getFeatureBits() const { return FeatureBits; }
setFeatureBits(const FeatureBitset & FeatureBits_)116   void setFeatureBits(const FeatureBitset &FeatureBits_) {
117     FeatureBits = FeatureBits_;
118   }
119 
getFeatureString()120   StringRef getFeatureString() const { return FeatureString; }
121 
hasFeature(unsigned Feature)122   bool hasFeature(unsigned Feature) const {
123     return FeatureBits[Feature];
124   }
125 
126 protected:
127   /// Initialize the scheduling model and feature bits.
128   ///
129   /// FIXME: Find a way to stick this in the constructor, since it should only
130   /// be called during initialization.
131   void InitMCProcessorInfo(StringRef CPU, StringRef TuneCPU, StringRef FS);
132 
133 public:
134   /// Set the features to the default for the given CPU and TuneCPU, with ano
135   /// appended feature string.
136   void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
137 
138   /// Toggle a feature and return the re-computed feature bits.
139   /// This version does not change the implied bits.
140   FeatureBitset ToggleFeature(uint64_t FB);
141 
142   /// Toggle a feature and return the re-computed feature bits.
143   /// This version does not change the implied bits.
144   FeatureBitset ToggleFeature(const FeatureBitset& FB);
145 
146   /// Toggle a set of features and return the re-computed feature bits.
147   /// This version will also change all implied bits.
148   FeatureBitset ToggleFeature(StringRef FS);
149 
150   /// Apply a feature flag and return the re-computed feature bits, including
151   /// all feature bits implied by the flag.
152   FeatureBitset ApplyFeatureFlag(StringRef FS);
153 
154   /// Set/clear additional feature bits, including all other bits they imply.
155   FeatureBitset SetFeatureBitsTransitively(const FeatureBitset& FB);
156   FeatureBitset ClearFeatureBitsTransitively(const FeatureBitset &FB);
157 
158   /// Check whether the subtarget features are enabled/disabled as per
159   /// the provided string, ignoring all other features.
160   bool checkFeatures(StringRef FS) const;
161 
162   /// Get the machine model of a CPU.
163   const MCSchedModel &getSchedModelForCPU(StringRef CPU) const;
164 
165   /// Get the machine model for this subtarget's CPU.
getSchedModel()166   const MCSchedModel &getSchedModel() const { return *CPUSchedModel; }
167 
168   /// Return an iterator at the first process resource consumed by the given
169   /// scheduling class.
getWriteProcResBegin(const MCSchedClassDesc * SC)170   const MCWriteProcResEntry *getWriteProcResBegin(
171     const MCSchedClassDesc *SC) const {
172     return &WriteProcResTable[SC->WriteProcResIdx];
173   }
getWriteProcResEnd(const MCSchedClassDesc * SC)174   const MCWriteProcResEntry *getWriteProcResEnd(
175     const MCSchedClassDesc *SC) const {
176     return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
177   }
178 
getWriteLatencyEntry(const MCSchedClassDesc * SC,unsigned DefIdx)179   const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
180                                                   unsigned DefIdx) const {
181     assert(DefIdx < SC->NumWriteLatencyEntries &&
182            "MachineModel does not specify a WriteResource for DefIdx");
183 
184     return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
185   }
186 
getReadAdvanceCycles(const MCSchedClassDesc * SC,unsigned UseIdx,unsigned WriteResID)187   int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
188                            unsigned WriteResID) const {
189     // TODO: The number of read advance entries in a class can be significant
190     // (~50). Consider compressing the WriteID into a dense ID of those that are
191     // used by ReadAdvance and representing them as a bitset.
192     for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
193            *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
194       if (I->UseIdx < UseIdx)
195         continue;
196       if (I->UseIdx > UseIdx)
197         break;
198       // Find the first WriteResIdx match, which has the highest cycle count.
199       if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
200         return I->Cycles;
201       }
202     }
203     return 0;
204   }
205 
206   /// Return the set of ReadAdvance entries declared by the scheduling class
207   /// descriptor in input.
208   ArrayRef<MCReadAdvanceEntry>
getReadAdvanceEntries(const MCSchedClassDesc & SC)209   getReadAdvanceEntries(const MCSchedClassDesc &SC) const {
210     if (!SC.NumReadAdvanceEntries)
211       return ArrayRef<MCReadAdvanceEntry>();
212     return ArrayRef<MCReadAdvanceEntry>(&ReadAdvanceTable[SC.ReadAdvanceIdx],
213                                         SC.NumReadAdvanceEntries);
214   }
215 
216   /// Get scheduling itinerary of a CPU.
217   InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
218 
219   /// Initialize an InstrItineraryData instance.
220   void initInstrItins(InstrItineraryData &InstrItins) const;
221 
222   /// Resolve a variant scheduling class for the given MCInst and CPU.
resolveVariantSchedClass(unsigned SchedClass,const MCInst * MI,const MCInstrInfo * MCII,unsigned CPUID)223   virtual unsigned resolveVariantSchedClass(unsigned SchedClass,
224                                             const MCInst *MI,
225                                             const MCInstrInfo *MCII,
226                                             unsigned CPUID) const {
227     return 0;
228   }
229 
230   /// Check whether the CPU string is valid.
isCPUStringValid(StringRef CPU)231   virtual bool isCPUStringValid(StringRef CPU) const {
232     auto Found = llvm::lower_bound(ProcDesc, CPU);
233     return Found != ProcDesc.end() && StringRef(Found->Key) == CPU;
234   }
235 
236   /// Return processor descriptions.
getAllProcessorDescriptions()237   ArrayRef<SubtargetSubTypeKV> getAllProcessorDescriptions() const {
238     return ProcDesc;
239   }
240 
241   /// Return processor features.
getAllProcessorFeatures()242   ArrayRef<SubtargetFeatureKV> getAllProcessorFeatures() const {
243     return ProcFeatures;
244   }
245 
246   /// Return the list of processor features currently enabled.
247   std::vector<SubtargetFeatureKV> getEnabledProcessorFeatures() const;
248 
249   /// HwMode IDs are stored and accessed in a bit set format, enabling
250   /// users to efficiently retrieve specific IDs, such as the RegInfo
251   /// HwMode ID, from the set as required. Using this approach, various
252   /// types of HwMode IDs can be added to a subtarget to manage different
253   /// attributes within that subtarget, significantly enhancing the
254   /// scalability and usability of HwMode. Moreover, to ensure compatibility,
255   /// this method also supports controlling multiple attributes with a single
256   /// HwMode ID, just as was done previously.
257   enum HwModeType {
258     HwMode_Default,   // Return the smallest HwMode ID of current subtarget.
259     HwMode_ValueType, // Return the HwMode ID that controls the ValueType.
260     HwMode_RegInfo,   // Return the HwMode ID that controls the RegSizeInfo and
261                       // SubRegRange.
262     HwMode_EncodingInfo // Return the HwMode ID that controls the EncodingInfo.
263   };
264 
265   /// Return a bit set containing all HwMode IDs of the current subtarget.
getHwModeSet()266   virtual unsigned getHwModeSet() const { return 0; }
267 
268   /// HwMode ID corresponding to the 'type' parameter is retrieved from the
269   /// HwMode bit set of the current subtarget. It’s important to note that if
270   /// the current subtarget possesses two HwMode IDs and both control a single
271   /// attribute (such as RegInfo), this interface will result in an error.
272   virtual unsigned getHwMode(enum HwModeType type = HwMode_Default) const {
273     return 0;
274   }
275 
276   /// Return the cache size in bytes for the given level of cache.
277   /// Level is zero-based, so a value of zero means the first level of
278   /// cache.
279   ///
280   virtual std::optional<unsigned> getCacheSize(unsigned Level) const;
281 
282   /// Return the cache associatvity for the given level of cache.
283   /// Level is zero-based, so a value of zero means the first level of
284   /// cache.
285   ///
286   virtual std::optional<unsigned> getCacheAssociativity(unsigned Level) const;
287 
288   /// Return the target cache line size in bytes at a given level.
289   ///
290   virtual std::optional<unsigned> getCacheLineSize(unsigned Level) const;
291 
292   /// Return the target cache line size in bytes.  By default, return
293   /// the line size for the bottom-most level of cache.  This provides
294   /// a more convenient interface for the common case where all cache
295   /// levels have the same line size.  Return zero if there is no
296   /// cache model.
297   ///
getCacheLineSize()298   virtual unsigned getCacheLineSize() const {
299     std::optional<unsigned> Size = getCacheLineSize(0);
300     if (Size)
301       return *Size;
302 
303     return 0;
304   }
305 
306   /// Return the preferred prefetch distance in terms of instructions.
307   ///
308   virtual unsigned getPrefetchDistance() const;
309 
310   /// Return the maximum prefetch distance in terms of loop
311   /// iterations.
312   ///
313   virtual unsigned getMaxPrefetchIterationsAhead() const;
314 
315   /// \return True if prefetching should also be done for writes.
316   ///
317   virtual bool enableWritePrefetching() const;
318 
319   /// Return the minimum stride necessary to trigger software
320   /// prefetching.
321   ///
322   virtual unsigned getMinPrefetchStride(unsigned NumMemAccesses,
323                                         unsigned NumStridedMemAccesses,
324                                         unsigned NumPrefetches,
325                                         bool HasCall) const;
326 
327   /// \return if target want to issue a prefetch in address space \p AS.
328   virtual bool shouldPrefetchAddressSpace(unsigned AS) const;
329 };
330 
331 } // end namespace llvm
332 
333 #endif // LLVM_MC_MCSUBTARGETINFO_H
334