LLVM 19.0.0git
MCSubtargetInfo.cpp
Go to the documentation of this file.
1//===- MCSubtargetInfo.cpp - Subtarget Information ------------------------===//
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
10#include "llvm/ADT/ArrayRef.h"
11#include "llvm/ADT/StringRef.h"
13#include "llvm/MC/MCSchedule.h"
14#include "llvm/Support/Format.h"
17#include <algorithm>
18#include <cassert>
19#include <cstring>
20#include <optional>
21
22using namespace llvm;
23
24/// Find KV in array using binary search.
25template <typename T>
26static const T *Find(StringRef S, ArrayRef<T> A) {
27 // Binary search the array
28 auto F = llvm::lower_bound(A, S);
29 // If not found then return NULL
30 if (F == A.end() || StringRef(F->Key) != S) return nullptr;
31 // Return the found array item
32 return F;
33}
34
35/// For each feature that is (transitively) implied by this feature, set it.
36static
37void SetImpliedBits(FeatureBitset &Bits, const FeatureBitset &Implies,
38 ArrayRef<SubtargetFeatureKV> FeatureTable) {
39 // OR the Implies bits in outside the loop. This allows the Implies for CPUs
40 // which might imply features not in FeatureTable to use this.
41 Bits |= Implies;
42 for (const SubtargetFeatureKV &FE : FeatureTable)
43 if (Implies.test(FE.Value))
44 SetImpliedBits(Bits, FE.Implies.getAsBitset(), FeatureTable);
45}
46
47/// For each feature that (transitively) implies this feature, clear it.
48static
50 ArrayRef<SubtargetFeatureKV> FeatureTable) {
51 for (const SubtargetFeatureKV &FE : FeatureTable) {
52 if (FE.Implies.getAsBitset().test(Value)) {
53 Bits.reset(FE.Value);
54 ClearImpliedBits(Bits, FE.Value, FeatureTable);
55 }
56 }
57}
58
59static void ApplyFeatureFlag(FeatureBitset &Bits, StringRef Feature,
60 ArrayRef<SubtargetFeatureKV> FeatureTable) {
62 "Feature flags should start with '+' or '-'");
63
64 // Find feature in table.
65 const SubtargetFeatureKV *FeatureEntry =
66 Find(SubtargetFeatures::StripFlag(Feature), FeatureTable);
67 // If there is a match
68 if (FeatureEntry) {
69 // Enable/disable feature in bits
70 if (SubtargetFeatures::isEnabled(Feature)) {
71 Bits.set(FeatureEntry->Value);
72
73 // For each feature that this implies, set it.
74 SetImpliedBits(Bits, FeatureEntry->Implies.getAsBitset(), FeatureTable);
75 } else {
76 Bits.reset(FeatureEntry->Value);
77
78 // For each feature that implies this, clear it.
79 ClearImpliedBits(Bits, FeatureEntry->Value, FeatureTable);
80 }
81 } else {
82 errs() << "'" << Feature << "' is not a recognized feature for this target"
83 << " (ignoring feature)\n";
84 }
85}
86
87/// Return the length of the longest entry in the table.
88template <typename T>
89static size_t getLongestEntryLength(ArrayRef<T> Table) {
90 size_t MaxLen = 0;
91 for (auto &I : Table)
92 MaxLen = std::max(MaxLen, std::strlen(I.Key));
93 return MaxLen;
94}
95
96/// Display help for feature and mcpu choices.
99 // the static variable ensures that the help information only gets
100 // printed once even though a target machine creates multiple subtargets
101 static bool PrintOnce = false;
102 if (PrintOnce) {
103 return;
104 }
105
106 // Determine the length of the longest CPU and Feature entries.
107 unsigned MaxCPULen = getLongestEntryLength(CPUTable);
108 unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
109
110 // Print the CPU table.
111 errs() << "Available CPUs for this target:\n\n";
112 for (auto &CPU : CPUTable)
113 errs() << format(" %-*s - Select the %s processor.\n", MaxCPULen, CPU.Key,
114 CPU.Key);
115 errs() << '\n';
116
117 // Print the Feature table.
118 errs() << "Available features for this target:\n\n";
119 for (auto &Feature : FeatTable)
120 errs() << format(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
121 errs() << '\n';
122
123 errs() << "Use +feature to enable a feature, or -feature to disable it.\n"
124 "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n";
125
126 PrintOnce = true;
127}
128
129/// Display help for mcpu choices only
131 // the static variable ensures that the help information only gets
132 // printed once even though a target machine creates multiple subtargets
133 static bool PrintOnce = false;
134 if (PrintOnce) {
135 return;
136 }
137
138 // Print the CPU table.
139 errs() << "Available CPUs for this target:\n\n";
140 for (auto &CPU : CPUTable)
141 errs() << "\t" << CPU.Key << "\n";
142 errs() << '\n';
143
144 errs() << "Use -mcpu or -mtune to specify the target's processor.\n"
145 "For example, clang --target=aarch64-unknown-linux-gnu "
146 "-mcpu=cortex-a35\n";
147
148 PrintOnce = true;
149}
150
153 ArrayRef<SubtargetFeatureKV> ProcFeatures) {
154 SubtargetFeatures Features(FS);
155
156 if (ProcDesc.empty() || ProcFeatures.empty())
157 return FeatureBitset();
158
159 assert(llvm::is_sorted(ProcDesc) && "CPU table is not sorted");
160 assert(llvm::is_sorted(ProcFeatures) && "CPU features table is not sorted");
161 // Resulting bits
162 FeatureBitset Bits;
163
164 // Check if help is needed
165 if (CPU == "help")
166 Help(ProcDesc, ProcFeatures);
167
168 // Find CPU entry if CPU name is specified.
169 else if (!CPU.empty()) {
170 const SubtargetSubTypeKV *CPUEntry = Find(CPU, ProcDesc);
171
172 // If there is a match
173 if (CPUEntry) {
174 // Set the features implied by this CPU feature, if any.
175 SetImpliedBits(Bits, CPUEntry->Implies.getAsBitset(), ProcFeatures);
176 } else {
177 errs() << "'" << CPU << "' is not a recognized processor for this target"
178 << " (ignoring processor)\n";
179 }
180 }
181
182 if (!TuneCPU.empty()) {
183 const SubtargetSubTypeKV *CPUEntry = Find(TuneCPU, ProcDesc);
184
185 // If there is a match
186 if (CPUEntry) {
187 // Set the features implied by this CPU feature, if any.
188 SetImpliedBits(Bits, CPUEntry->TuneImplies.getAsBitset(), ProcFeatures);
189 } else if (TuneCPU != CPU) {
190 errs() << "'" << TuneCPU << "' is not a recognized processor for this "
191 << "target (ignoring processor)\n";
192 }
193 }
194
195 // Iterate through each feature
196 for (const std::string &Feature : Features.getFeatures()) {
197 // Check for help
198 if (Feature == "+help")
199 Help(ProcDesc, ProcFeatures);
200 else if (Feature == "+cpuhelp")
201 cpuHelp(ProcDesc);
202 else
203 ApplyFeatureFlag(Bits, Feature, ProcFeatures);
204 }
205
206 return Bits;
207}
208
210 StringRef FS) {
211 FeatureBits = getFeatures(CPU, TuneCPU, FS, ProcDesc, ProcFeatures);
212 FeatureString = std::string(FS);
213
214 if (!TuneCPU.empty())
215 CPUSchedModel = &getSchedModelForCPU(TuneCPU);
216 else
217 CPUSchedModel = &MCSchedModel::Default;
218}
219
221 StringRef FS) {
222 FeatureBits = getFeatures(CPU, TuneCPU, FS, ProcDesc, ProcFeatures);
223 FeatureString = std::string(FS);
224}
225
229 const MCWriteProcResEntry *WPR,
230 const MCWriteLatencyEntry *WL,
231 const MCReadAdvanceEntry *RA,
232 const InstrStage *IS, const unsigned *OC,
233 const unsigned *FP)
234 : TargetTriple(TT), CPU(std::string(C)), TuneCPU(std::string(TC)),
235 ProcFeatures(PF), ProcDesc(PD), WriteProcResTable(WPR),
236 WriteLatencyTable(WL), ReadAdvanceTable(RA), Stages(IS),
237 OperandCycles(OC), ForwardingPaths(FP) {
238 InitMCProcessorInfo(CPU, TuneCPU, FS);
239}
240
242 FeatureBits.flip(FB);
243 return FeatureBits;
244}
245
247 FeatureBits ^= FB;
248 return FeatureBits;
249}
250
252 const FeatureBitset &FB) {
253 SetImpliedBits(FeatureBits, FB, ProcFeatures);
254 return FeatureBits;
255}
256
258 const FeatureBitset &FB) {
259 for (unsigned I = 0, E = FB.size(); I < E; I++) {
260 if (FB[I]) {
261 FeatureBits.reset(I);
262 ClearImpliedBits(FeatureBits, I, ProcFeatures);
263 }
264 }
265 return FeatureBits;
266}
267
269 // Find feature in table.
270 const SubtargetFeatureKV *FeatureEntry =
271 Find(SubtargetFeatures::StripFlag(Feature), ProcFeatures);
272 // If there is a match
273 if (FeatureEntry) {
274 if (FeatureBits.test(FeatureEntry->Value)) {
275 FeatureBits.reset(FeatureEntry->Value);
276 // For each feature that implies this, clear it.
277 ClearImpliedBits(FeatureBits, FeatureEntry->Value, ProcFeatures);
278 } else {
279 FeatureBits.set(FeatureEntry->Value);
280
281 // For each feature that this implies, set it.
282 SetImpliedBits(FeatureBits, FeatureEntry->Implies.getAsBitset(),
283 ProcFeatures);
284 }
285 } else {
286 errs() << "'" << Feature << "' is not a recognized feature for this target"
287 << " (ignoring feature)\n";
288 }
289
290 return FeatureBits;
291}
292
294 ::ApplyFeatureFlag(FeatureBits, FS, ProcFeatures);
295 return FeatureBits;
296}
297
300 FeatureBitset Set, All;
301 for (std::string F : T.getFeatures()) {
302 ::ApplyFeatureFlag(Set, F, ProcFeatures);
303 if (F[0] == '-')
304 F[0] = '+';
305 ::ApplyFeatureFlag(All, F, ProcFeatures);
306 }
307 return (FeatureBits & All) == Set;
308}
309
311 assert(llvm::is_sorted(ProcDesc) &&
312 "Processor machine model table is not sorted");
313
314 // Find entry
315 const SubtargetSubTypeKV *CPUEntry = Find(CPU, ProcDesc);
316
317 if (!CPUEntry) {
318 if (CPU != "help") // Don't error if the user asked for help.
319 errs() << "'" << CPU
320 << "' is not a recognized processor for this target"
321 << " (ignoring processor)\n";
323 }
324 assert(CPUEntry->SchedModel && "Missing processor SchedModel value");
325 return *CPUEntry->SchedModel;
326}
327
330 const MCSchedModel &SchedModel = getSchedModelForCPU(CPU);
331 return InstrItineraryData(SchedModel, Stages, OperandCycles, ForwardingPaths);
332}
333
335 InstrItins = InstrItineraryData(getSchedModel(), Stages, OperandCycles,
336 ForwardingPaths);
337}
338
339std::optional<unsigned> MCSubtargetInfo::getCacheSize(unsigned Level) const {
340 return std::nullopt;
341}
342
343std::optional<unsigned>
345 return std::nullopt;
346}
347
348std::optional<unsigned>
350 return std::nullopt;
351}
352
354 return 0;
355}
356
358 return UINT_MAX;
359}
360
362 return false;
363}
364
365unsigned MCSubtargetInfo::getMinPrefetchStride(unsigned NumMemAccesses,
366 unsigned NumStridedMemAccesses,
367 unsigned NumPrefetches,
368 bool HasCall) const {
369 return 1;
370}
371
373 return !AS;
374}
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static void ApplyFeatureFlag(FeatureBitset &Bits, StringRef Feature, ArrayRef< SubtargetFeatureKV > FeatureTable)
static const T * Find(StringRef S, ArrayRef< T > A)
Find KV in array using binary search.
static void SetImpliedBits(FeatureBitset &Bits, const FeatureBitset &Implies, ArrayRef< SubtargetFeatureKV > FeatureTable)
For each feature that is (transitively) implied by this feature, set it.
static void cpuHelp(ArrayRef< SubtargetSubTypeKV > CPUTable)
Display help for mcpu choices only.
static size_t getLongestEntryLength(ArrayRef< T > Table)
Return the length of the longest entry in the table.
static void Help(ArrayRef< SubtargetSubTypeKV > CPUTable, ArrayRef< SubtargetFeatureKV > FeatTable)
Display help for feature and mcpu choices.
static void ClearImpliedBits(FeatureBitset &Bits, unsigned Value, ArrayRef< SubtargetFeatureKV > FeatureTable)
For each feature that (transitively) implies this feature, clear it.
static FeatureBitset getFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:160
const FeatureBitset & getAsBitset() const
Container class for subtarget features.
constexpr FeatureBitset & reset(unsigned I)
constexpr bool test(unsigned I) const
constexpr FeatureBitset & flip(unsigned I)
FeatureBitset & set()
constexpr size_t size() const
Itinerary data supplied by a subtarget to be used by a target.
virtual unsigned getCacheLineSize() const
Return the target cache line size in bytes.
bool checkFeatures(StringRef FS) const
Check whether the subtarget features are enabled/disabled as per the provided string,...
virtual std::optional< unsigned > getCacheSize(unsigned Level) const
Return the cache size in bytes for the given level of cache.
virtual bool shouldPrefetchAddressSpace(unsigned AS) const
const MCSchedModel & getSchedModelForCPU(StringRef CPU) const
Get the machine model of a CPU.
virtual unsigned getMinPrefetchStride(unsigned NumMemAccesses, unsigned NumStridedMemAccesses, unsigned NumPrefetches, bool HasCall) const
Return the minimum stride necessary to trigger software prefetching.
virtual bool enableWritePrefetching() const
virtual unsigned getMaxPrefetchIterationsAhead() const
Return the maximum prefetch distance in terms of loop iterations.
virtual unsigned getPrefetchDistance() const
Return the preferred prefetch distance in terms of instructions.
FeatureBitset ApplyFeatureFlag(StringRef FS)
Apply a feature flag and return the re-computed feature bits, including all feature bits implied by t...
virtual std::optional< unsigned > getCacheAssociativity(unsigned Level) const
Return the cache associatvity for the given level of cache.
FeatureBitset SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const
Get scheduling itinerary of a CPU.
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
void InitMCProcessorInfo(StringRef CPU, StringRef TuneCPU, StringRef FS)
Initialize the scheduling model and feature bits.
void initInstrItins(InstrItineraryData &InstrItins) const
Initialize an InstrItineraryData instance.
FeatureBitset ClearFeatureBitsTransitively(const FeatureBitset &FB)
const MCSchedModel & getSchedModel() const
Get the machine model for this subtarget's CPU.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
Manages the enabling and disabling of subtarget specific features.
const std::vector< std::string > & getFeatures() const
Returns the vector of individual subtarget features.
static bool hasFlag(StringRef Feature)
Determine if a feature has a flag; '+' or '-'.
static StringRef StripFlag(StringRef Feature)
Return string stripped of flag.
static bool isEnabled(StringRef Feature)
Return true if enable flag; '+'.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
LLVM Value Representation.
Definition: Value.h:74
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
Definition: STLExtras.h:1911
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:125
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1950
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
These values represent a non-pipelined step in the execution of an instruction.
Specify the number of cycles allowed after instruction issue before a particular use operand reads it...
Definition: MCSchedule.h:103
Machine model for scheduling, bundling, and heuristics.
Definition: MCSchedule.h:253
static const MCSchedModel Default
Returns the default initialized model.
Definition: MCSchedule.h:393
Specify the latency in cpu cycles for a particular scheduling class and def index.
Definition: MCSchedule.h:86
Identify one of the processor resource kinds consumed by a particular scheduling class for the specif...
Definition: MCSchedule.h:63
Used to provide key value pairs for feature and CPU bit flags.
unsigned Value
K-V integer value.
FeatureBitArray Implies
K-V bit mask.
Used to provide key value pairs for feature and CPU bit flags.
const MCSchedModel * SchedModel
FeatureBitArray Implies
K-V bit mask.
FeatureBitArray TuneImplies
K-V bit mask.