LLVM  6.0.0svn
SubtargetFeature.cpp
Go to the documentation of this file.
1 //===- SubtargetFeature.cpp - CPU characteristics Implementation ----------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file Implements the SubtargetFeature interface.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/Triple.h"
20 #include "llvm/Support/Compiler.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/Support/Format.h"
24 #include <algorithm>
25 #include <cassert>
26 #include <cstddef>
27 #include <cstring>
28 #include <iterator>
29 #include <string>
30 #include <vector>
31 
32 using namespace llvm;
33 
34 /// Determine if a feature has a flag; '+' or '-'
35 static inline bool hasFlag(StringRef Feature) {
36  assert(!Feature.empty() && "Empty string");
37  // Get first character
38  char Ch = Feature[0];
39  // Check if first character is '+' or '-' flag
40  return Ch == '+' || Ch =='-';
41 }
42 
43 /// Return string stripped of flag.
44 static inline std::string StripFlag(StringRef Feature) {
45  return hasFlag(Feature) ? Feature.substr(1) : Feature;
46 }
47 
48 /// Return true if enable flag; '+'.
49 static inline bool isEnabled(StringRef Feature) {
50  assert(!Feature.empty() && "Empty string");
51  // Get first character
52  char Ch = Feature[0];
53  // Check if first character is '+' for enabled
54  return Ch == '+';
55 }
56 
57 /// Splits a string of comma separated items in to a vector of strings.
58 static void Split(std::vector<std::string> &V, StringRef S) {
60  S.split(Tmp, ',', -1, false /* KeepEmpty */);
61  V.assign(Tmp.begin(), Tmp.end());
62 }
63 
65  // Don't add empty features.
66  if (!String.empty())
67  // Convert to lowercase, prepend flag if we don't already have a flag.
68  Features.push_back(hasFlag(String) ? String.lower()
69  : (Enable ? "+" : "-") + String.lower());
70 }
71 
72 /// Find KV in array using binary search.
75  // Binary search the array
76  auto F = std::lower_bound(A.begin(), A.end(), S);
77  // If not found then return NULL
78  if (F == A.end() || StringRef(F->Key) != S) return nullptr;
79  // Return the found array item
80  return F;
81 }
82 
83 /// Return the length of the longest entry in the table.
85  size_t MaxLen = 0;
86  for (auto &I : Table)
87  MaxLen = std::max(MaxLen, std::strlen(I.Key));
88  return MaxLen;
89 }
90 
91 /// Display help for feature choices.
92 static void Help(ArrayRef<SubtargetFeatureKV> CPUTable,
93  ArrayRef<SubtargetFeatureKV> FeatTable) {
94  // Determine the length of the longest CPU and Feature entries.
95  unsigned MaxCPULen = getLongestEntryLength(CPUTable);
96  unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
97 
98  // Print the CPU table.
99  errs() << "Available CPUs for this target:\n\n";
100  for (auto &CPU : CPUTable)
101  errs() << format(" %-*s - %s.\n", MaxCPULen, CPU.Key, CPU.Desc);
102  errs() << '\n';
103 
104  // Print the Feature table.
105  errs() << "Available features for this target:\n\n";
106  for (auto &Feature : FeatTable)
107  errs() << format(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
108  errs() << '\n';
109 
110  errs() << "Use +feature to enable a feature, or -feature to disable it.\n"
111  "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n";
112 }
113 
115  // Break up string into separate features
116  Split(Features, Initial);
117 }
118 
119 std::string SubtargetFeatures::getString() const {
120  return join(Features.begin(), Features.end(), ",");
121 }
122 
123 /// For each feature that is (transitively) implied by this feature, set it.
124 static
126  ArrayRef<SubtargetFeatureKV> FeatureTable) {
127  for (const SubtargetFeatureKV &FE : FeatureTable) {
128  if (FeatureEntry.Value == FE.Value) continue;
129 
130  if ((FeatureEntry.Implies & FE.Value).any()) {
131  Bits |= FE.Value;
132  SetImpliedBits(Bits, FE, FeatureTable);
133  }
134  }
135 }
136 
137 /// For each feature that (transitively) implies this feature, clear it.
138 static
140  const SubtargetFeatureKV &FeatureEntry,
141  ArrayRef<SubtargetFeatureKV> FeatureTable) {
142  for (const SubtargetFeatureKV &FE : FeatureTable) {
143  if (FeatureEntry.Value == FE.Value) continue;
144 
145  if ((FE.Implies & FeatureEntry.Value).any()) {
146  Bits &= ~FE.Value;
147  ClearImpliedBits(Bits, FE, FeatureTable);
148  }
149  }
150 }
151 
152 void
154  ArrayRef<SubtargetFeatureKV> FeatureTable) {
155  // Find feature in table.
156  const SubtargetFeatureKV *FeatureEntry =
157  Find(StripFlag(Feature), FeatureTable);
158  // If there is a match
159  if (FeatureEntry) {
160  if ((Bits & FeatureEntry->Value) == FeatureEntry->Value) {
161  Bits &= ~FeatureEntry->Value;
162  // For each feature that implies this, clear it.
163  ClearImpliedBits(Bits, *FeatureEntry, FeatureTable);
164  } else {
165  Bits |= FeatureEntry->Value;
166 
167  // For each feature that this implies, set it.
168  SetImpliedBits(Bits, *FeatureEntry, FeatureTable);
169  }
170  } else {
171  errs() << "'" << Feature << "' is not a recognized feature for this target"
172  << " (ignoring feature)\n";
173  }
174 }
175 
177  ArrayRef<SubtargetFeatureKV> FeatureTable) {
178  assert(hasFlag(Feature));
179 
180  // Find feature in table.
181  const SubtargetFeatureKV *FeatureEntry =
182  Find(StripFlag(Feature), FeatureTable);
183  // If there is a match
184  if (FeatureEntry) {
185  // Enable/disable feature in bits
186  if (isEnabled(Feature)) {
187  Bits |= FeatureEntry->Value;
188 
189  // For each feature that this implies, set it.
190  SetImpliedBits(Bits, *FeatureEntry, FeatureTable);
191  } else {
192  Bits &= ~FeatureEntry->Value;
193 
194  // For each feature that implies this, clear it.
195  ClearImpliedBits(Bits, *FeatureEntry, FeatureTable);
196  }
197  } else {
198  errs() << "'" << Feature << "' is not a recognized feature for this target"
199  << " (ignoring feature)\n";
200  }
201 }
202 
206  ArrayRef<SubtargetFeatureKV> FeatureTable) {
207  if (CPUTable.empty() || FeatureTable.empty())
208  return FeatureBitset();
209 
210  assert(std::is_sorted(std::begin(CPUTable), std::end(CPUTable)) &&
211  "CPU table is not sorted");
212  assert(std::is_sorted(std::begin(FeatureTable), std::end(FeatureTable)) &&
213  "CPU features table is not sorted");
214  // Resulting bits
216 
217  // Check if help is needed
218  if (CPU == "help")
219  Help(CPUTable, FeatureTable);
220 
221  // Find CPU entry if CPU name is specified.
222  else if (!CPU.empty()) {
223  const SubtargetFeatureKV *CPUEntry = Find(CPU, CPUTable);
224 
225  // If there is a match
226  if (CPUEntry) {
227  // Set base feature bits
228  Bits = CPUEntry->Value;
229 
230  // Set the feature implied by this CPU feature, if any.
231  for (auto &FE : FeatureTable) {
232  if ((CPUEntry->Value & FE.Value).any())
233  SetImpliedBits(Bits, FE, FeatureTable);
234  }
235  } else {
236  errs() << "'" << CPU << "' is not a recognized processor for this target"
237  << " (ignoring processor)\n";
238  }
239  }
240 
241  // Iterate through each feature
242  for (const std::string &Feature : Features) {
243  // Check for help
244  if (Feature == "+help")
245  Help(CPUTable, FeatureTable);
246 
247  ApplyFeatureFlag(Bits, Feature, FeatureTable);
248  }
249 
250  return Bits;
251 }
252 
254  for (auto &F : Features)
255  OS << F << " ";
256  OS << "\n";
257 }
258 
259 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
261  print(dbgs());
262 }
263 #endif
264 
266  // FIXME: This is an inelegant way of specifying the features of a
267  // subtarget. It would be better if we could encode this information
268  // into the IR. See <rdar://5972456>.
269  if (Triple.getVendor() == Triple::Apple) {
270  if (Triple.getArch() == Triple::ppc) {
271  // powerpc-apple-*
272  AddFeature("altivec");
273  } else if (Triple.getArch() == Triple::ppc64) {
274  // powerpc64-apple-*
275  AddFeature("64bit");
276  AddFeature("altivec");
277  }
278  }
279 }
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:244
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:235
static void Help(ArrayRef< SubtargetFeatureKV > CPUTable, ArrayRef< SubtargetFeatureKV > FeatTable)
Display help for feature choices.
void print(raw_ostream &OS) const
Prints feature string.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
void getDefaultSubtargetFeatures(const Triple &Triple)
Adds the default features for the specified target triple.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
Definition: Compiler.h:449
iterator begin() const
Definition: ArrayRef.h:137
static size_t getLongestEntryLength(ArrayRef< SubtargetFeatureKV > Table)
Return the length of the longest entry in the table.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
std::string getString() const
Returns features as a string.
static std::string StripFlag(StringRef Feature)
Return string stripped of flag.
F(f)
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
Definition: StringExtras.h:327
void AddFeature(StringRef String, bool Enable=true)
Adds Features.
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
Definition: Triple.h:285
FeatureBitset Value
K-V integer value.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:133
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:33
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:598
static void SetImpliedBits(FeatureBitset &Bits, const SubtargetFeatureKV &FeatureEntry, 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;.
Container class for subtarget features.
VendorType getVendor() const
getVendor - Get the parsed vendor type of this triple.
Definition: Triple.h:291
static const SubtargetFeatureKV * Find(StringRef S, ArrayRef< SubtargetFeatureKV > A)
Find KV in array using binary search.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:116
static void ToggleFeature(FeatureBitset &Bits, StringRef String, ArrayRef< SubtargetFeatureKV > FeatureTable)
Toggles a feature and update the feature bits.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:864
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:727
iterator end() const
Definition: ArrayRef.h:138
SubtargetFeatures(StringRef Initial="")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
static void ClearImpliedBits(FeatureBitset &Bits, const SubtargetFeatureKV &FeatureEntry, ArrayRef< SubtargetFeatureKV > FeatureTable)
For each feature that (transitively) implies this feature, clear it.
auto lower_bound(R &&Range, ForwardIt I) -> decltype(std::begin(Range))
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:859
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:120
#define I(x, y, z)
Definition: MD5.cpp:58
static bool isEnabled(StringRef Feature)
Return true if enable flag; &#39;+&#39;.
LLVM_NODISCARD std::string lower() const
Definition: StringRef.cpp:123
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static void ApplyFeatureFlag(FeatureBitset &Bits, StringRef Feature, ArrayRef< SubtargetFeatureKV > FeatureTable)
Applies the feature flag and update the feature bits.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
FeatureBitset Implies
K-V bit mask.
FeatureBitset getFeatureBits(StringRef CPU, ArrayRef< SubtargetFeatureKV > CPUTable, ArrayRef< SubtargetFeatureKV > FeatureTable)
Returns feature bits of a CPU.
static void Split(std::vector< std::string > &V, StringRef S)
Splits a string of comma separated items in to a vector of strings.
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:144