-
Notifications
You must be signed in to change notification settings - Fork 18k
Expand file tree
/
Copy pathAArch64TargetParser.h
More file actions
301 lines (244 loc) · 11.6 KB
/
Copy pathAArch64TargetParser.h
File metadata and controls
301 lines (244 loc) · 11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
//===-- AArch64TargetParser - Parser for AArch64 features -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements a target parser to recognise AArch64 hardware features
// such as FPU/CPU/ARCH and extension names.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TARGETPARSER_AARCH64TARGETPARSER_H
#define LLVM_TARGETPARSER_AARCH64TARGETPARSER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Bitset.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringTable.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/SubtargetFeature.h"
#include <set>
#include <vector>
namespace llvm {
class Triple;
namespace AArch64 {
struct ArchInfo;
struct CpuInfo;
#include "llvm/TargetParser/AArch64CPUFeatures.inc"
#include "llvm/TargetParser/AArch64FeatPriorities.inc"
static_assert(FEAT_MAX < 62,
"Number of features in CPUFeatures are limited to 62 entries");
static_assert(PRIOR_MAX < 120, "FeatPriorities is limited to 120 entries");
// Emit the StringTable StrTab to which all offsets refer.
#define EMIT_STRTAB
#include "llvm/TargetParser/AArch64TargetParserDef.inc"
// Each ArchExtKind correponds directly to a possible -target-feature.
#define EMIT_ARCHEXTKIND_ENUM
#include "llvm/TargetParser/AArch64TargetParserDef.inc"
using ExtensionBitset = Bitset<AEK_NUM_EXTENSIONS>;
// Represents an extension that can be enabled with -march=<arch>+<extension>.
// Typically these correspond to Arm Architecture extensions, unlike
// SubtargetFeature which may represent either an actual extension or some
// internal LLVM property.
struct ExtensionInfo {
StringTable::Offset
UserVisibleName; // Human readable name used in -march, -cpu
// and target func attribute, e.g. "profile".
StringTable::Offset Alias; // An alias for this extension, if one exists.
ArchExtKind ID; // Corresponding to the ArchExtKind, this
// extensions representation in the bitfield.
StringTable::Offset ArchFeatureName; // The feature name defined by the
// Architecture, e.g. FEAT_AdvSIMD.
StringTable::Offset Description; // The textual description of the extension.
StringTable::Offset PosTargetFeature; // -target-feature/-mattr enable string,
// e.g. "+spe".
StringTable::Offset NegTargetFeature; // -target-feature/-mattr disable
// string, e.g. "-spe".
};
#define EMIT_EXTENSIONS
#include "llvm/TargetParser/AArch64TargetParserDef.inc"
struct FMVInfo {
StringRef Name; // The target_version/target_clones spelling.
std::optional<CPUFeatures>
FeatureBit; // Index of the bit in the FMV feature bitset.
FeatPriorities PriorityBit; // Index of the bit in the FMV priority bitset.
std::optional<ArchExtKind> ID; // The architecture extension to enable.
FMVInfo(StringRef Name, std::optional<CPUFeatures> FeatureBit,
FeatPriorities PriorityBit, std::optional<ArchExtKind> ID)
: Name(Name), FeatureBit(FeatureBit), PriorityBit(PriorityBit), ID(ID) {};
};
LLVM_ABI const std::vector<FMVInfo> &getFMVInfo();
// Represents a dependency between two architecture extensions. Later is the
// feature which was added to the architecture after Earlier, and expands the
// functionality provided by it. If Later is enabled, then Earlier will also be
// enabled. If Earlier is disabled, then Later will also be disabled.
struct ExtensionDependency {
ArchExtKind Earlier;
ArchExtKind Later;
};
#define EMIT_EXTENSION_DEPENDENCIES
#include "llvm/TargetParser/AArch64TargetParserDef.inc"
enum ArchProfile { AProfile = 'A', RProfile = 'R', InvalidProfile = '?' };
// Information about a specific architecture, e.g. V8.1-A
struct ArchInfo {
VersionTuple Version; // Architecture version, major + minor.
ArchProfile Profile; // Architecuture profile
StringTable::Offset Name; // Name as supplied to -march e.g. "armv8.1-a"
StringTable::Offset
ArchFeature; // Name as supplied to -target-feature, e.g. "+v8a"
AArch64::ExtensionBitset
DefaultExts; // bitfield of default extensions ArchExtKind
bool operator==(const ArchInfo &Other) const {
return this->Name == Other.Name;
}
bool operator!=(const ArchInfo &Other) const {
return this->Name != Other.Name;
}
// Defines the following partial order, indicating when an architecture is
// a superset of another:
//
// v9.7a > v9.6a > v9.5a > v9.4a > v9.3a > v9.2a > v9.1a > v9a;
// v v v v v
// v8.9a > v8.8a > v8.7a > v8.6a > v8.5a > ... > v8a;
//
// v8r has no relation to anything. This is used to determine which
// features to enable for a given architecture. See
// AArch64TargetInfo::setFeatureEnabled.
bool implies(const ArchInfo &Other) const {
if (this->Profile != Other.Profile)
return false; // ARMV8R
if (this->Version.getMajor() == Other.Version.getMajor()) {
return this->Version > Other.Version;
}
if (this->Version.getMajor() == 9 && Other.Version.getMajor() == 8) {
assert(this->Version.getMinor() && Other.Version.getMinor() &&
"AArch64::ArchInfo should have a minor version.");
return this->Version.getMinor().value_or(0) + 5 >=
Other.Version.getMinor().value_or(0);
}
return false;
}
// True if this architecture is a superset of Other (including being equal to
// it).
bool is_superset(const ArchInfo &Other) const {
return (*this == Other) || implies(Other);
}
// Return ArchFeature without the leading "+".
StringRef getSubArch() const { return StrTab[ArchFeature].substr(1); }
// Search for ArchInfo by SubArch name
LLVM_ABI static std::optional<ArchInfo> findBySubArch(StringRef SubArch);
};
#define EMIT_ARCHITECTURES
#include "llvm/TargetParser/AArch64TargetParserDef.inc"
// Details of a specific CPU.
struct CpuInfo {
StringTable::Offset Name; // Name, as written for -mcpu.
unsigned ArchIdx;
AArch64::ExtensionBitset
DefaultExtensions; // Default extensions for this CPU.
};
#define EMIT_CPU_INFO
#include "llvm/TargetParser/AArch64TargetParserDef.inc"
struct ExtensionSet {
// Set of extensions which are currently enabled.
ExtensionBitset Enabled;
// Set of extensions which have been enabled or disabled at any point. Used
// to avoid cluttering the cc1 command-line with lots of unneeded features.
ExtensionBitset Touched;
// Base architecture version, which we need to know because some feature
// dependencies change depending on this.
const ArchInfo *BaseArch;
ExtensionSet() : Enabled(), Touched(), BaseArch(nullptr) {}
// Enable the given architecture extension, and any other extensions it
// depends on. Does not change the base architecture, or follow dependencies
// between features which are only related by required arcitecture versions.
LLVM_ABI void enable(ArchExtKind E);
// Disable the given architecture extension, and any other extensions which
// depend on it. Does not change the base architecture, or follow
// dependencies between features which are only related by required
// arcitecture versions.
LLVM_ABI void disable(ArchExtKind E);
// Add default extensions for the given CPU. Records the base architecture,
// to later resolve dependencies which depend on it.
LLVM_ABI void addCPUDefaults(const CpuInfo &CPU);
// Add default extensions for the given architecture version. Records the
// base architecture, to later resolve dependencies which depend on it.
LLVM_ABI void addArchDefaults(const ArchInfo &Arch);
// Add or remove a feature based on a modifier string. The string must be of
// the form "<name>" to enable a feature or "no<name>" to disable it. This
// will also enable or disable any features as required by the dependencies
// between them.
LLVM_ABI bool parseModifier(StringRef Modifier,
const bool AllowNoDashForm = false);
// Constructs a new ExtensionSet by toggling the corresponding bits for every
// feature in the \p Features list without expanding their dependencies. Used
// for reconstructing an ExtensionSet from the output of toLLVMFeatures().
// Features that are not recognized are pushed back to \p NonExtensions.
LLVM_ABI void
reconstructFromParsedFeatures(const std::vector<std::string> &Features,
std::vector<std::string> &NonExtensions);
// Convert the set of enabled extension to an LLVM feature list, appending
// them to Features.
template <typename T> void toLLVMFeatureList(std::vector<T> &Features) const {
if (BaseArch && !StrTab[BaseArch->ArchFeature].empty())
Features.emplace_back(T(StrTab[BaseArch->ArchFeature]));
for (const auto &E : Extensions) {
if (!Touched.test(E.ID))
continue;
if (Enabled.test(E.ID))
Features.emplace_back(T(StrTab[E.PosTargetFeature]));
else
Features.emplace_back(T(StrTab[E.NegTargetFeature]));
}
}
LLVM_ABI void dump() const;
};
// Name alias.
struct Alias {
StringTable::Offset AltName;
StringTable::Offset Name;
};
#define EMIT_CPU_ALIAS
#include "llvm/TargetParser/AArch64TargetParserDef.inc"
LLVM_ABI const ExtensionInfo &getExtensionByID(ArchExtKind(ExtID));
LLVM_ABI bool getExtensionFeatures(const AArch64::ExtensionBitset &Extensions,
std::vector<StringRef> &Features);
LLVM_ABI StringRef getArchExtFeature(StringRef ArchExt);
LLVM_ABI StringRef resolveCPUAlias(StringRef CPU);
// Information by Name
LLVM_ABI const ArchInfo *getArchForCpu(StringRef CPU);
// Parser
LLVM_ABI const ArchInfo *parseArch(StringRef Arch);
// Return the extension which has the given -target-feature name.
LLVM_ABI std::optional<ExtensionInfo>
targetFeatureToExtension(StringRef TargetFeature);
// Parse a name as defined by the Extension class in tablegen.
LLVM_ABI std::optional<ExtensionInfo> parseArchExtension(StringRef Extension);
// Parse a name as defined by the FMVInfo class in tablegen.
LLVM_ABI std::optional<FMVInfo> parseFMVExtension(StringRef Extension);
// Given the name of a CPU or alias, return the correponding CpuInfo.
LLVM_ABI std::optional<CpuInfo> parseCpu(StringRef Name);
// Used by target parser tests
LLVM_ABI void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values);
LLVM_ABI bool isX18ReservedByDefault(const Triple &TT);
// For a given set of feature names, which can be either target-features, or
// fmv-features metadata, expand their dependencies and then return a bitmask
// corresponding to the entries of AArch64::FeatPriorities.
LLVM_ABI APInt getFMVPriority(ArrayRef<StringRef> Features);
// For a given set of FMV feature names, expand their dependencies and then
// return a bitmask corresponding to the entries of AArch64::CPUFeatures.
// The values in CPUFeatures are not bitmasks themselves, they are sequential
// (0, 1, 2, 3, ...). The resulting bitmask is used at runtime to test whether
// a certain FMV feature is available on the host.
LLVM_ABI APInt getCpuSupportsMask(ArrayRef<StringRef> Features);
LLVM_ABI void PrintSupportedExtensions();
LLVM_ABI void
printEnabledExtensions(const std::set<StringRef> &EnabledFeatureNames);
} // namespace AArch64
} // namespace llvm
#endif