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

source code of llvm/include/llvm/MC/MCSubtargetInfo.h