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