1 //===- SubtargetFeatureInfo.cpp - Helpers for subtarget features ----------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "SubtargetFeatureInfo.h"
11 #include "llvm/Config/llvm-config.h"
12 #include "llvm/TableGen/Error.h"
13 #include "llvm/TableGen/Record.h"
17 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
18 LLVM_DUMP_METHOD
void SubtargetFeatureInfo::dump() const {
19 errs() << getEnumName() << " " << Index
<< "\n" << *TheDef
;
23 std::vector
<std::pair
<Record
*, SubtargetFeatureInfo
>>
24 SubtargetFeatureInfo::getAll(const RecordKeeper
&Records
) {
25 std::vector
<std::pair
<Record
*, SubtargetFeatureInfo
>> SubtargetFeatures
;
26 std::vector
<Record
*> AllPredicates
=
27 Records
.getAllDerivedDefinitions("Predicate");
28 for (Record
*Pred
: AllPredicates
) {
29 // Ignore predicates that are not intended for the assembler.
31 // The "AssemblerMatcherPredicate" string should be promoted to an argument
32 // if we re-use the machinery for non-assembler purposes in future.
33 if (!Pred
->getValueAsBit("AssemblerMatcherPredicate"))
36 if (Pred
->getName().empty())
37 PrintFatalError(Pred
->getLoc(), "Predicate has no name!");
39 // Ignore always true predicates.
40 if (Pred
->getValueAsString("CondString").empty())
43 SubtargetFeatures
.emplace_back(
44 Pred
, SubtargetFeatureInfo(Pred
, SubtargetFeatures
.size()));
46 return SubtargetFeatures
;
49 void SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(
50 const SubtargetFeatureInfoMap
&SubtargetFeatures
, raw_ostream
&OS
,
51 const std::map
<std::string
, unsigned> *HwModes
) {
52 OS
<< "// Bits for subtarget features that participate in "
53 << "instruction matching.\n";
54 unsigned Size
= SubtargetFeatures
.size();
56 Size
+= HwModes
->size();
58 OS
<< "enum SubtargetFeatureBits : " << getMinimalTypeForRange(Size
)
60 for (const auto &SF
: SubtargetFeatures
) {
61 const SubtargetFeatureInfo
&SFI
= SF
.second
;
62 OS
<< " " << SFI
.getEnumBitName() << " = " << SFI
.Index
<< ",\n";
66 unsigned Offset
= SubtargetFeatures
.size();
67 for (const auto &M
: *HwModes
) {
68 OS
<< " Feature_HwMode" << M
.second
<< "Bit = " << (M
.second
+ Offset
)
76 void SubtargetFeatureInfo::emitNameTable(
77 SubtargetFeatureInfoMap
&SubtargetFeatures
, raw_ostream
&OS
) {
78 // Need to sort the name table so that lookup by the log of the enum value
79 // gives the proper name. More specifically, for a feature of value 1<<n,
80 // SubtargetFeatureNames[n] should be the name of the feature.
82 for (const auto &SF
: SubtargetFeatures
)
83 if (IndexUB
<= SF
.second
.Index
)
84 IndexUB
= SF
.second
.Index
+1;
86 std::vector
<std::string
> Names
;
88 Names
.resize(IndexUB
);
89 for (const auto &SF
: SubtargetFeatures
)
90 Names
[SF
.second
.Index
] = SF
.second
.getEnumName();
92 OS
<< "static const char *SubtargetFeatureNames[] = {\n";
93 for (uint64_t I
= 0; I
< IndexUB
; ++I
)
94 OS
<< " \"" << Names
[I
] << "\",\n";
96 // A small number of targets have no predicates. Null terminate the array to
97 // avoid a zero-length array.
102 void SubtargetFeatureInfo::emitComputeAvailableFeatures(
103 StringRef TargetName
, StringRef ClassName
, StringRef FuncName
,
104 const SubtargetFeatureInfoMap
&SubtargetFeatures
, raw_ostream
&OS
,
105 StringRef ExtraParams
, const std::map
<std::string
, unsigned> *HwModes
) {
106 OS
<< "PredicateBitset " << ClassName
<< "::\n"
107 << FuncName
<< "(const " << TargetName
<< "Subtarget *Subtarget";
108 if (!ExtraParams
.empty())
109 OS
<< ", " << ExtraParams
;
111 OS
<< " PredicateBitset Features;\n";
112 for (const auto &SF
: SubtargetFeatures
) {
113 const SubtargetFeatureInfo
&SFI
= SF
.second
;
114 StringRef CondStr
= SFI
.TheDef
->getValueAsString("CondString");
115 assert(!CondStr
.empty() && "true predicate should have been filtered");
117 OS
<< " if (" << CondStr
<< ")\n";
118 OS
<< " Features.set(" << SFI
.getEnumBitName() << ");\n";
122 for (const auto &M
: *HwModes
) {
123 OS
<< " if (" << M
.first
<< ")\n";
124 OS
<< " Features.set(Feature_HwMode" << M
.second
<< "Bit);\n";
128 OS
<< " return Features;\n";
132 // If ParenIfBinOp is true, print a surrounding () if Val uses && or ||.
133 static bool emitFeaturesAux(StringRef TargetName
, const Init
&Val
,
134 bool ParenIfBinOp
, raw_ostream
&OS
) {
135 if (auto *D
= dyn_cast
<DefInit
>(&Val
)) {
136 if (!D
->getDef()->isSubClassOf("SubtargetFeature"))
138 OS
<< "FB[" << TargetName
<< "::" << D
->getAsString() << "]";
141 if (auto *D
= dyn_cast
<DagInit
>(&Val
)) {
142 auto *Op
= dyn_cast
<DefInit
>(D
->getOperator());
145 StringRef OpName
= Op
->getDef()->getName();
146 if (OpName
== "not" && D
->getNumArgs() == 1) {
148 return emitFeaturesAux(TargetName
, *D
->getArg(0), true, OS
);
150 if ((OpName
== "any_of" || OpName
== "all_of") && D
->getNumArgs() > 0) {
151 bool Paren
= D
->getNumArgs() > 1 && std::exchange(ParenIfBinOp
, true);
154 ListSeparator
LS(OpName
== "any_of" ? " || " : " && ");
155 for (auto *Arg
: D
->getArgs()) {
157 if (emitFeaturesAux(TargetName
, *Arg
, ParenIfBinOp
, OS
))
168 void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
169 StringRef TargetName
, StringRef ClassName
, StringRef FuncName
,
170 SubtargetFeatureInfoMap
&SubtargetFeatures
, raw_ostream
&OS
) {
171 OS
<< "FeatureBitset ";
172 if (!ClassName
.empty())
173 OS
<< TargetName
<< ClassName
<< "::\n";
174 OS
<< FuncName
<< "(const FeatureBitset &FB) ";
175 if (!ClassName
.empty())
178 OS
<< " FeatureBitset Features;\n";
179 for (const auto &SF
: SubtargetFeatures
) {
180 const SubtargetFeatureInfo
&SFI
= SF
.second
;
183 emitFeaturesAux(TargetName
, *SFI
.TheDef
->getValueAsDag("AssemblerCondDag"),
184 /*ParenIfBinOp=*/false, OS
);
186 OS
<< " Features.set(" << SFI
.getEnumBitName() << ");\n";
188 OS
<< " return Features;\n";