aboutsummaryrefslogtreecommitdiffstats
path: root/utils/TableGen/AsmMatcherEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/AsmMatcherEmitter.cpp')
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp429
1 files changed, 184 insertions, 245 deletions
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp
index 891328f..65a34d3 100644
--- a/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/utils/TableGen/AsmMatcherEmitter.cpp
@@ -115,6 +115,7 @@
#include <map>
#include <set>
#include <sstream>
+#include <forward_list>
using namespace llvm;
#define DEBUG_TYPE "asm-matcher-emitter"
@@ -255,9 +256,8 @@ public:
return true;
// ... or if any of its super classes are a subset of RHS.
- for (std::vector<ClassInfo*>::const_iterator it = SuperClasses.begin(),
- ie = SuperClasses.end(); it != ie; ++it)
- if ((*it)->isSubsetOf(RHS))
+ for (const ClassInfo *CI : SuperClasses)
+ if (CI->isSubsetOf(RHS))
return true;
return false;
@@ -391,6 +391,10 @@ struct MatchableInfo {
/// AsmVariantID - Target's assembly syntax variant no.
int AsmVariantID;
+ /// AsmString - The assembly string for this instruction (with variants
+ /// removed), e.g. "movsx $src, $dst".
+ std::string AsmString;
+
/// TheDef - This is the definition of the instruction or InstAlias that this
/// matchable came from.
Record *const TheDef;
@@ -408,10 +412,6 @@ struct MatchableInfo {
/// MCInst.
SmallVector<ResOperand, 8> ResOperands;
- /// AsmString - The assembly string for this instruction (with variants
- /// removed), e.g. "movsx $src, $dst".
- std::string AsmString;
-
/// Mnemonic - This is the first token of the matched instruction, its
/// mnemonic.
StringRef Mnemonic;
@@ -423,7 +423,7 @@ struct MatchableInfo {
SmallVector<AsmOperand, 8> AsmOperands;
/// Predicates - The required subtarget features to match this instruction.
- SmallVector<SubtargetFeatureInfo*, 4> RequiredFeatures;
+ SmallVector<const SubtargetFeatureInfo *, 4> RequiredFeatures;
/// ConversionFnKind - The enum value which is passed to the generated
/// convertToMCInst to convert parsed operands into an MCInst for this
@@ -434,13 +434,15 @@ struct MatchableInfo {
bool HasDeprecation;
MatchableInfo(const CodeGenInstruction &CGI)
- : AsmVariantID(0), TheDef(CGI.TheDef), DefRec(&CGI),
- AsmString(CGI.AsmString) {
+ : AsmVariantID(0), AsmString(CGI.AsmString), TheDef(CGI.TheDef), DefRec(&CGI) {
}
- MatchableInfo(const CodeGenInstAlias *Alias)
- : AsmVariantID(0), TheDef(Alias->TheDef), DefRec(Alias),
- AsmString(Alias->AsmString) {
+ MatchableInfo(std::unique_ptr<const CodeGenInstAlias> Alias)
+ : AsmVariantID(0), AsmString(Alias->AsmString), TheDef(Alias->TheDef), DefRec(Alias.release()) {
+ }
+
+ ~MatchableInfo() {
+ delete DefRec.dyn_cast<const CodeGenInstAlias*>();
}
// Two-operand aliases clone from the main matchable, but mark the second
@@ -516,7 +518,7 @@ struct MatchableInfo {
/// couldMatchAmbiguouslyWith - Check whether this matchable could
/// ambiguously match the same set of operands as \p RHS (without being a
/// strictly superior match).
- bool couldMatchAmbiguouslyWith(const MatchableInfo &RHS) {
+ bool couldMatchAmbiguouslyWith(const MatchableInfo &RHS) const {
// The primary comparator is the instruction mnemonic.
if (Mnemonic != RHS.Mnemonic)
return false;
@@ -552,7 +554,7 @@ struct MatchableInfo {
return !(HasLT ^ HasGT);
}
- void dump();
+ void dump() const;
private:
void tokenizeAsmString(const AsmMatcherInfo &Info);
@@ -574,7 +576,7 @@ struct SubtargetFeatureInfo {
return "Feature_" + TheDef->getName();
}
- void dump() {
+ void dump() const {
errs() << getEnumName() << " " << Index << "\n";
TheDef->dump();
}
@@ -582,10 +584,10 @@ struct SubtargetFeatureInfo {
struct OperandMatchEntry {
unsigned OperandMask;
- MatchableInfo* MI;
+ const MatchableInfo* MI;
ClassInfo *CI;
- static OperandMatchEntry create(MatchableInfo* mi, ClassInfo *ci,
+ static OperandMatchEntry create(const MatchableInfo *mi, ClassInfo *ci,
unsigned opMask) {
OperandMatchEntry X;
X.OperandMask = opMask;
@@ -608,10 +610,10 @@ public:
CodeGenTarget &Target;
/// The classes which are needed for matching.
- std::vector<ClassInfo*> Classes;
+ std::forward_list<ClassInfo> Classes;
/// The information on the matchables to match.
- std::vector<MatchableInfo*> Matchables;
+ std::vector<std::unique_ptr<MatchableInfo>> Matchables;
/// Info for custom matching operands by user defined methods.
std::vector<OperandMatchEntry> OperandMatchInfo;
@@ -621,7 +623,7 @@ public:
RegisterClassesTy RegisterClasses;
/// Map of Predicate records to their subtarget information.
- std::map<Record*, SubtargetFeatureInfo*, LessRecordByID> SubtargetFeatures;
+ std::map<Record *, SubtargetFeatureInfo, LessRecordByID> SubtargetFeatures;
/// Map of AsmOperandClass records to their class information.
std::map<Record*, ClassInfo*> AsmOperandClasses;
@@ -669,11 +671,10 @@ public:
/// getSubtargetFeature - Lookup or create the subtarget feature info for the
/// given operand.
- SubtargetFeatureInfo *getSubtargetFeature(Record *Def) const {
+ const SubtargetFeatureInfo *getSubtargetFeature(Record *Def) const {
assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!");
- std::map<Record*, SubtargetFeatureInfo*, LessRecordByID>::const_iterator I =
- SubtargetFeatures.find(Def);
- return I == SubtargetFeatures.end() ? nullptr : I->second;
+ const auto &I = SubtargetFeatures.find(Def);
+ return I == SubtargetFeatures.end() ? nullptr : &I->second;
}
RecordKeeper &getRecords() const {
@@ -683,11 +684,11 @@ public:
} // End anonymous namespace
-void MatchableInfo::dump() {
+void MatchableInfo::dump() const {
errs() << TheDef->getName() << " -- " << "flattened:\"" << AsmString <<"\"\n";
for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
- AsmOperand &Op = AsmOperands[i];
+ const AsmOperand &Op = AsmOperands[i];
errs() << " op[" << i << "] = " << Op.Class->ClassName << " - ";
errs() << '\"' << Op.Token << "\"\n";
}
@@ -777,8 +778,8 @@ void MatchableInfo::initialize(const AsmMatcherInfo &Info,
// Compute the require features.
std::vector<Record*> Predicates =TheDef->getValueAsListOfDefs("Predicates");
for (unsigned i = 0, e = Predicates.size(); i != e; ++i)
- if (SubtargetFeatureInfo *Feature =
- Info.getSubtargetFeature(Predicates[i]))
+ if (const SubtargetFeatureInfo *Feature =
+ Info.getSubtargetFeature(Predicates[i]))
RequiredFeatures.push_back(Feature);
// Collect singleton registers, if used.
@@ -978,6 +979,7 @@ static std::string getEnumNameForToken(StringRef Str) {
case '.': Res += "_DOT_"; break;
case '<': Res += "_LT_"; break;
case '>': Res += "_GT_"; break;
+ case '-': Res += "_MINUS_"; break;
default:
if ((*it >= 'A' && *it <= 'Z') ||
(*it >= 'a' && *it <= 'z') ||
@@ -995,7 +997,8 @@ ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) {
ClassInfo *&Entry = TokenClasses[Token];
if (!Entry) {
- Entry = new ClassInfo();
+ Classes.emplace_front();
+ Entry = &Classes.front();
Entry->Kind = ClassInfo::Token;
Entry->ClassName = "Token";
Entry->Name = "MCK_" + getEnumNameForToken(Token);
@@ -1004,7 +1007,6 @@ ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) {
Entry->RenderMethod = "<invalid>";
Entry->ParserMethod = "";
Entry->DiagnosticType = "";
- Classes.push_back(Entry);
}
return Entry;
@@ -1076,10 +1078,8 @@ struct LessRegisterSet {
void AsmMatcherInfo::
buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) {
- const std::vector<CodeGenRegister*> &Registers =
- Target.getRegBank().getRegisters();
- ArrayRef<CodeGenRegisterClass*> RegClassList =
- Target.getRegBank().getRegClasses();
+ const auto &Registers = Target.getRegBank().getRegisters();
+ auto &RegClassList = Target.getRegBank().getRegClasses();
typedef std::set<RegisterSet, LessRegisterSet> RegisterSetSet;
@@ -1087,15 +1087,12 @@ buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) {
RegisterSetSet RegisterSets;
// Gather the defined sets.
- for (ArrayRef<CodeGenRegisterClass*>::const_iterator it =
- RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it)
- RegisterSets.insert(RegisterSet(
- (*it)->getOrder().begin(), (*it)->getOrder().end()));
+ for (const CodeGenRegisterClass &RC : RegClassList)
+ RegisterSets.insert(
+ RegisterSet(RC.getOrder().begin(), RC.getOrder().end()));
// Add any required singleton sets.
- for (SmallPtrSetImpl<Record*>::iterator it = SingletonRegisters.begin(),
- ie = SingletonRegisters.end(); it != ie; ++it) {
- Record *Rec = *it;
+ for (Record *Rec : SingletonRegisters) {
RegisterSets.insert(RegisterSet(&Rec, &Rec + 1));
}
@@ -1103,19 +1100,16 @@ buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) {
// a unique register set class), and build the mapping of registers to the set
// they should classify to.
std::map<Record*, RegisterSet> RegisterMap;
- for (std::vector<CodeGenRegister*>::const_iterator it = Registers.begin(),
- ie = Registers.end(); it != ie; ++it) {
- const CodeGenRegister &CGR = **it;
+ for (const CodeGenRegister &CGR : Registers) {
// Compute the intersection of all sets containing this register.
RegisterSet ContainingSet;
- for (RegisterSetSet::iterator it = RegisterSets.begin(),
- ie = RegisterSets.end(); it != ie; ++it) {
- if (!it->count(CGR.TheDef))
+ for (const RegisterSet &RS : RegisterSets) {
+ if (!RS.count(CGR.TheDef))
continue;
if (ContainingSet.empty()) {
- ContainingSet = *it;
+ ContainingSet = RS;
continue;
}
@@ -1123,7 +1117,7 @@ buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) {
std::swap(Tmp, ContainingSet);
std::insert_iterator<RegisterSet> II(ContainingSet,
ContainingSet.begin());
- std::set_intersection(Tmp.begin(), Tmp.end(), it->begin(), it->end(), II,
+ std::set_intersection(Tmp.begin(), Tmp.end(), RS.begin(), RS.end(), II,
LessRecordByID());
}
@@ -1136,39 +1130,35 @@ buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) {
// Construct the register classes.
std::map<RegisterSet, ClassInfo*, LessRegisterSet> RegisterSetClasses;
unsigned Index = 0;
- for (RegisterSetSet::iterator it = RegisterSets.begin(),
- ie = RegisterSets.end(); it != ie; ++it, ++Index) {
- ClassInfo *CI = new ClassInfo();
+ for (const RegisterSet &RS : RegisterSets) {
+ Classes.emplace_front();
+ ClassInfo *CI = &Classes.front();
CI->Kind = ClassInfo::RegisterClass0 + Index;
CI->ClassName = "Reg" + utostr(Index);
CI->Name = "MCK_Reg" + utostr(Index);
CI->ValueName = "";
CI->PredicateMethod = ""; // unused
CI->RenderMethod = "addRegOperands";
- CI->Registers = *it;
+ CI->Registers = RS;
// FIXME: diagnostic type.
CI->DiagnosticType = "";
- Classes.push_back(CI);
- RegisterSetClasses.insert(std::make_pair(*it, CI));
+ RegisterSetClasses.insert(std::make_pair(RS, CI));
+ ++Index;
}
// Find the superclasses; we could compute only the subgroup lattice edges,
// but there isn't really a point.
- for (RegisterSetSet::iterator it = RegisterSets.begin(),
- ie = RegisterSets.end(); it != ie; ++it) {
- ClassInfo *CI = RegisterSetClasses[*it];
- for (RegisterSetSet::iterator it2 = RegisterSets.begin(),
- ie2 = RegisterSets.end(); it2 != ie2; ++it2)
- if (*it != *it2 &&
- std::includes(it2->begin(), it2->end(), it->begin(), it->end(),
+ for (const RegisterSet &RS : RegisterSets) {
+ ClassInfo *CI = RegisterSetClasses[RS];
+ for (const RegisterSet &RS2 : RegisterSets)
+ if (RS != RS2 &&
+ std::includes(RS2.begin(), RS2.end(), RS.begin(), RS.end(),
LessRecordByID()))
- CI->SuperClasses.push_back(RegisterSetClasses[*it2]);
+ CI->SuperClasses.push_back(RegisterSetClasses[RS2]);
}
// Name the register classes which correspond to a user defined RegisterClass.
- for (ArrayRef<CodeGenRegisterClass*>::const_iterator
- it = RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) {
- const CodeGenRegisterClass &RC = **it;
+ for (const CodeGenRegisterClass &RC : RegClassList) {
// Def will be NULL for non-user defined register classes.
Record *Def = RC.getDef();
if (!Def)
@@ -1191,9 +1181,7 @@ buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) {
RegisterClasses[it->first] = RegisterSetClasses[it->second];
// Name the register classes which correspond to singleton registers.
- for (SmallPtrSetImpl<Record*>::iterator it = SingletonRegisters.begin(),
- ie = SingletonRegisters.end(); it != ie; ++it) {
- Record *Rec = *it;
+ for (Record *Rec : SingletonRegisters) {
ClassInfo *CI = RegisterClasses[Rec];
assert(CI && "Missing singleton register class info!");
@@ -1211,36 +1199,36 @@ void AsmMatcherInfo::buildOperandClasses() {
Records.getAllDerivedDefinitions("AsmOperandClass");
// Pre-populate AsmOperandClasses map.
- for (std::vector<Record*>::iterator it = AsmOperands.begin(),
- ie = AsmOperands.end(); it != ie; ++it)
- AsmOperandClasses[*it] = new ClassInfo();
+ for (Record *Rec : AsmOperands) {
+ Classes.emplace_front();
+ AsmOperandClasses[Rec] = &Classes.front();
+ }
unsigned Index = 0;
- for (std::vector<Record*>::iterator it = AsmOperands.begin(),
- ie = AsmOperands.end(); it != ie; ++it, ++Index) {
- ClassInfo *CI = AsmOperandClasses[*it];
+ for (Record *Rec : AsmOperands) {
+ ClassInfo *CI = AsmOperandClasses[Rec];
CI->Kind = ClassInfo::UserClass0 + Index;
- ListInit *Supers = (*it)->getValueAsListInit("SuperClasses");
+ ListInit *Supers = Rec->getValueAsListInit("SuperClasses");
for (unsigned i = 0, e = Supers->getSize(); i != e; ++i) {
DefInit *DI = dyn_cast<DefInit>(Supers->getElement(i));
if (!DI) {
- PrintError((*it)->getLoc(), "Invalid super class reference!");
+ PrintError(Rec->getLoc(), "Invalid super class reference!");
continue;
}
ClassInfo *SC = AsmOperandClasses[DI->getDef()];
if (!SC)
- PrintError((*it)->getLoc(), "Invalid super class reference!");
+ PrintError(Rec->getLoc(), "Invalid super class reference!");
else
CI->SuperClasses.push_back(SC);
}
- CI->ClassName = (*it)->getValueAsString("Name");
+ CI->ClassName = Rec->getValueAsString("Name");
CI->Name = "MCK_" + CI->ClassName;
- CI->ValueName = (*it)->getName();
+ CI->ValueName = Rec->getName();
// Get or construct the predicate method name.
- Init *PMName = (*it)->getValueInit("PredicateMethod");
+ Init *PMName = Rec->getValueInit("PredicateMethod");
if (StringInit *SI = dyn_cast<StringInit>(PMName)) {
CI->PredicateMethod = SI->getValue();
} else {
@@ -1249,7 +1237,7 @@ void AsmMatcherInfo::buildOperandClasses() {
}
// Get or construct the render method name.
- Init *RMName = (*it)->getValueInit("RenderMethod");
+ Init *RMName = Rec->getValueInit("RenderMethod");
if (StringInit *SI = dyn_cast<StringInit>(RMName)) {
CI->RenderMethod = SI->getValue();
} else {
@@ -1258,18 +1246,17 @@ void AsmMatcherInfo::buildOperandClasses() {
}
// Get the parse method name or leave it as empty.
- Init *PRMName = (*it)->getValueInit("ParserMethod");
+ Init *PRMName = Rec->getValueInit("ParserMethod");
if (StringInit *SI = dyn_cast<StringInit>(PRMName))
CI->ParserMethod = SI->getValue();
// Get the diagnostic type or leave it as empty.
// Get the parse method name or leave it as empty.
- Init *DiagnosticType = (*it)->getValueInit("DiagnosticType");
+ Init *DiagnosticType = Rec->getValueInit("DiagnosticType");
if (StringInit *SI = dyn_cast<StringInit>(DiagnosticType))
CI->DiagnosticType = SI->getValue();
- AsmOperandClasses[*it] = CI;
- Classes.push_back(CI);
+ ++Index;
}
}
@@ -1288,16 +1275,13 @@ void AsmMatcherInfo::buildOperandMatchInfo() {
typedef std::map<ClassInfo *, unsigned, less_ptr<ClassInfo>> OpClassMaskTy;
OpClassMaskTy OpClassMask;
- for (std::vector<MatchableInfo*>::const_iterator it =
- Matchables.begin(), ie = Matchables.end();
- it != ie; ++it) {
- MatchableInfo &II = **it;
+ for (const auto &MI : Matchables) {
OpClassMask.clear();
// Keep track of all operands of this instructions which belong to the
// same class.
- for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) {
- MatchableInfo::AsmOperand &Op = II.AsmOperands[i];
+ for (unsigned i = 0, e = MI->AsmOperands.size(); i != e; ++i) {
+ const MatchableInfo::AsmOperand &Op = MI->AsmOperands[i];
if (Op.Class->ParserMethod.empty())
continue;
unsigned &OperandMask = OpClassMask[Op.Class];
@@ -1305,11 +1289,11 @@ void AsmMatcherInfo::buildOperandMatchInfo() {
}
// Generate operand match info for each mnemonic/operand class pair.
- for (OpClassMaskTy::iterator iit = OpClassMask.begin(),
- iie = OpClassMask.end(); iit != iie; ++iit) {
- unsigned OpMask = iit->second;
- ClassInfo *CI = iit->first;
- OperandMatchInfo.push_back(OperandMatchEntry::create(&II, CI, OpMask));
+ for (const auto &OCM : OpClassMask) {
+ unsigned OpMask = OCM.second;
+ ClassInfo *CI = OCM.first;
+ OperandMatchInfo.push_back(OperandMatchEntry::create(MI.get(), CI,
+ OpMask));
}
}
}
@@ -1327,10 +1311,10 @@ void AsmMatcherInfo::buildInfo() {
if (Pred->getName().empty())
PrintFatalError(Pred->getLoc(), "Predicate has no name!");
- uint64_t FeatureNo = SubtargetFeatures.size();
- SubtargetFeatures[Pred] = new SubtargetFeatureInfo(Pred, FeatureNo);
- DEBUG(SubtargetFeatures[Pred]->dump());
- assert(FeatureNo < 64 && "Too many subtarget features!");
+ SubtargetFeatures.insert(std::make_pair(
+ Pred, SubtargetFeatureInfo(Pred, SubtargetFeatures.size())));
+ DEBUG(SubtargetFeatures.find(Pred)->second.dump());
+ assert(SubtargetFeatures.size() <= 64 && "Too many subtarget features!");
}
// Parse the instructions; we need to do this first so that we can gather the
@@ -1344,20 +1328,18 @@ void AsmMatcherInfo::buildInfo() {
std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix");
int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
- for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
- E = Target.inst_end(); I != E; ++I) {
- const CodeGenInstruction &CGI = **I;
+ for (const CodeGenInstruction *CGI : Target.instructions()) {
// If the tblgen -match-prefix option is specified (for tblgen hackers),
// filter the set of instructions we consider.
- if (!StringRef(CGI.TheDef->getName()).startswith(MatchPrefix))
+ if (!StringRef(CGI->TheDef->getName()).startswith(MatchPrefix))
continue;
// Ignore "codegen only" instructions.
- if (CGI.TheDef->getValueAsBit("isCodeGenOnly"))
+ if (CGI->TheDef->getValueAsBit("isCodeGenOnly"))
continue;
- std::unique_ptr<MatchableInfo> II(new MatchableInfo(CGI));
+ std::unique_ptr<MatchableInfo> II(new MatchableInfo(*CGI));
II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
@@ -1366,14 +1348,7 @@ void AsmMatcherInfo::buildInfo() {
if (!II->validate(CommentDelimiter, true))
continue;
- // Ignore "Int_*" and "*_Int" instructions, which are internal aliases.
- //
- // FIXME: This is a total hack.
- if (StringRef(II->TheDef->getName()).startswith("Int_") ||
- StringRef(II->TheDef->getName()).endswith("_Int"))
- continue;
-
- Matchables.push_back(II.release());
+ Matchables.push_back(std::move(II));
}
// Parse all of the InstAlias definitions and stick them in the list of
@@ -1381,8 +1356,8 @@ void AsmMatcherInfo::buildInfo() {
std::vector<Record*> AllInstAliases =
Records.getAllDerivedDefinitions("InstAlias");
for (unsigned i = 0, e = AllInstAliases.size(); i != e; ++i) {
- CodeGenInstAlias *Alias =
- new CodeGenInstAlias(AllInstAliases[i], AsmVariantNo, Target);
+ auto Alias = llvm::make_unique<CodeGenInstAlias>(AllInstAliases[i],
+ AsmVariantNo, Target);
// If the tblgen -match-prefix option is specified (for tblgen hackers),
// filter the set of instruction aliases we consider, based on the target
@@ -1391,14 +1366,14 @@ void AsmMatcherInfo::buildInfo() {
.startswith( MatchPrefix))
continue;
- std::unique_ptr<MatchableInfo> II(new MatchableInfo(Alias));
+ std::unique_ptr<MatchableInfo> II(new MatchableInfo(std::move(Alias)));
II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
// Validate the alias definitions.
II->validate(CommentDelimiter, false);
- Matchables.push_back(II.release());
+ Matchables.push_back(std::move(II));
}
}
@@ -1410,11 +1385,8 @@ void AsmMatcherInfo::buildInfo() {
// Build the information about matchables, now that we have fully formed
// classes.
- std::vector<MatchableInfo*> NewMatchables;
- for (std::vector<MatchableInfo*>::iterator it = Matchables.begin(),
- ie = Matchables.end(); it != ie; ++it) {
- MatchableInfo *II = *it;
-
+ std::vector<std::unique_ptr<MatchableInfo>> NewMatchables;
+ for (auto &II : Matchables) {
// Parse the tokens after the mnemonic.
// Note: buildInstructionOperandReference may insert new AsmOperands, so
// don't precompute the loop bound.
@@ -1449,9 +1421,9 @@ void AsmMatcherInfo::buildInfo() {
OperandName = Token.substr(1);
if (II->DefRec.is<const CodeGenInstruction*>())
- buildInstructionOperandReference(II, OperandName, i);
+ buildInstructionOperandReference(II.get(), OperandName, i);
else
- buildAliasOperandReference(II, OperandName, Op);
+ buildAliasOperandReference(II.get(), OperandName, Op);
}
if (II->DefRec.is<const CodeGenInstruction*>()) {
@@ -1469,14 +1441,14 @@ void AsmMatcherInfo::buildInfo() {
AliasII->formTwoOperandAlias(Constraint);
// Add the alias to the matchables list.
- NewMatchables.push_back(AliasII.release());
+ NewMatchables.push_back(std::move(AliasII));
}
} else
II->buildAliasResultOperands();
}
if (!NewMatchables.empty())
- Matchables.insert(Matchables.end(), NewMatchables.begin(),
- NewMatchables.end());
+ std::move(NewMatchables.begin(), NewMatchables.end(),
+ std::back_inserter(Matchables));
// Process token alias definitions and set up the associated superclass
// information.
@@ -1493,7 +1465,7 @@ void AsmMatcherInfo::buildInfo() {
}
// Reorder classes so that classes precede super classes.
- std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>());
+ Classes.sort();
}
/// buildInstructionOperandReference - The specified operand is a reference to a
@@ -1703,7 +1675,7 @@ static unsigned getConverterOperandID(const std::string &Name,
static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
- std::vector<MatchableInfo*> &Infos,
+ std::vector<std::unique_ptr<MatchableInfo>> &Infos,
raw_ostream &OS) {
SetVector<std::string> OperandConversionKinds;
SetVector<std::string> InstructionConversionKinds;
@@ -1767,16 +1739,13 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
OperandConversionKinds.insert("CVT_Tied");
enum { CVT_Done, CVT_Reg, CVT_Tied };
- for (std::vector<MatchableInfo*>::const_iterator it = Infos.begin(),
- ie = Infos.end(); it != ie; ++it) {
- MatchableInfo &II = **it;
-
+ for (auto &II : Infos) {
// Check if we have a custom match function.
std::string AsmMatchConverter =
- II.getResultInst()->TheDef->getValueAsString("AsmMatchConverter");
+ II->getResultInst()->TheDef->getValueAsString("AsmMatchConverter");
if (!AsmMatchConverter.empty()) {
std::string Signature = "ConvertCustom_" + AsmMatchConverter;
- II.ConversionFnKind = Signature;
+ II->ConversionFnKind = Signature;
// Check if we have already generated this signature.
if (!InstructionConversionKinds.insert(Signature))
@@ -1808,16 +1777,17 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
std::vector<uint8_t> ConversionRow;
// Compute the convert enum and the case body.
- MaxRowLength = std::max(MaxRowLength, II.ResOperands.size()*2 + 1 );
+ MaxRowLength = std::max(MaxRowLength, II->ResOperands.size()*2 + 1 );
- for (unsigned i = 0, e = II.ResOperands.size(); i != e; ++i) {
- const MatchableInfo::ResOperand &OpInfo = II.ResOperands[i];
+ for (unsigned i = 0, e = II->ResOperands.size(); i != e; ++i) {
+ const MatchableInfo::ResOperand &OpInfo = II->ResOperands[i];
// Generate code to populate each result operand.
switch (OpInfo.Kind) {
case MatchableInfo::ResOperand::RenderAsmOperand: {
// This comes from something we parsed.
- MatchableInfo::AsmOperand &Op = II.AsmOperands[OpInfo.AsmOperandNum];
+ const MatchableInfo::AsmOperand &Op =
+ II->AsmOperands[OpInfo.AsmOperandNum];
// Registers are always converted the same, don't duplicate the
// conversion function based on them.
@@ -1879,6 +1849,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
case MatchableInfo::ResOperand::ImmOperand: {
int64_t Val = OpInfo.ImmVal;
std::string Ty = "imm_" + itostr(Val);
+ Ty = getEnumNameForToken(Ty);
Signature += "__" + Ty;
std::string Name = "CVT_" + Ty;
@@ -1940,7 +1911,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
if (Signature == "Convert")
Signature += "_NoOperands";
- II.ConversionFnKind = Signature;
+ II->ConversionFnKind = Signature;
// Save the signature. If we already have it, don't add a new row
// to the table.
@@ -2003,7 +1974,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
/// emitMatchClassEnumeration - Emit the enumeration for match class kinds.
static void emitMatchClassEnumeration(CodeGenTarget &Target,
- std::vector<ClassInfo*> &Infos,
+ std::forward_list<ClassInfo> &Infos,
raw_ostream &OS) {
OS << "namespace {\n\n";
@@ -2011,9 +1982,7 @@ static void emitMatchClassEnumeration(CodeGenTarget &Target,
<< "/// instruction matching.\n";
OS << "enum MatchClassKind {\n";
OS << " InvalidMatchClass = 0,\n";
- for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
- ie = Infos.end(); it != ie; ++it) {
- ClassInfo &CI = **it;
+ for (const auto &CI : Infos) {
OS << " " << CI.Name << ", // ";
if (CI.Kind == ClassInfo::Token) {
OS << "'" << CI.ValueName << "'\n";
@@ -2053,10 +2022,7 @@ static void emitValidateOperandClass(AsmMatcherInfo &Info,
// Check the user classes. We don't care what order since we're only
// actually matching against one of them.
- for (std::vector<ClassInfo*>::iterator it = Info.Classes.begin(),
- ie = Info.Classes.end(); it != ie; ++it) {
- ClassInfo &CI = **it;
-
+ for (const auto &CI : Info.Classes) {
if (!CI.isUserClass())
continue;
@@ -2075,11 +2041,9 @@ static void emitValidateOperandClass(AsmMatcherInfo &Info,
OS << " MatchClassKind OpKind;\n";
OS << " switch (Operand.getReg()) {\n";
OS << " default: OpKind = InvalidMatchClass; break;\n";
- for (AsmMatcherInfo::RegisterClassesTy::iterator
- it = Info.RegisterClasses.begin(), ie = Info.RegisterClasses.end();
- it != ie; ++it)
+ for (const auto &RC : Info.RegisterClasses)
OS << " case " << Info.Target.getName() << "::"
- << it->first->getName() << ": OpKind = " << it->second->Name
+ << RC.first->getName() << ": OpKind = " << RC.second->Name
<< "; break;\n";
OS << " }\n";
OS << " return isSubclass(OpKind, Kind) ? "
@@ -2094,7 +2058,7 @@ static void emitValidateOperandClass(AsmMatcherInfo &Info,
/// emitIsSubclass - Emit the subclass predicate function.
static void emitIsSubclass(CodeGenTarget &Target,
- std::vector<ClassInfo*> &Infos,
+ std::forward_list<ClassInfo> &Infos,
raw_ostream &OS) {
OS << "/// isSubclass - Compute whether \\p A is a subclass of \\p B.\n";
OS << "static bool isSubclass(MatchClassKind A, MatchClassKind B) {\n";
@@ -2107,15 +2071,9 @@ static void emitIsSubclass(CodeGenTarget &Target,
SS << " switch (A) {\n";
SS << " default:\n";
SS << " return false;\n";
- for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
- ie = Infos.end(); it != ie; ++it) {
- ClassInfo &A = **it;
-
+ for (const auto &A : Infos) {
std::vector<StringRef> SuperClasses;
- for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
- ie = Infos.end(); it != ie; ++it) {
- ClassInfo &B = **it;
-
+ for (const auto &B : Infos) {
if (&A != &B && A.isSubsetOf(B))
SuperClasses.push_back(B.Name);
}
@@ -2157,17 +2115,14 @@ static void emitIsSubclass(CodeGenTarget &Target,
/// emitMatchTokenString - Emit the function to match a token string to the
/// appropriate match class value.
static void emitMatchTokenString(CodeGenTarget &Target,
- std::vector<ClassInfo*> &Infos,
+ std::forward_list<ClassInfo> &Infos,
raw_ostream &OS) {
// Construct the match list.
std::vector<StringMatcher::StringPair> Matches;
- for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
- ie = Infos.end(); it != ie; ++it) {
- ClassInfo &CI = **it;
-
+ for (const auto &CI : Infos) {
if (CI.Kind == ClassInfo::Token)
- Matches.push_back(StringMatcher::StringPair(CI.ValueName,
- "return " + CI.Name + ";"));
+ Matches.push_back(
+ StringMatcher::StringPair(CI.ValueName, "return " + CI.Name + ";"));
}
OS << "static MatchClassKind matchTokenString(StringRef Name) {\n";
@@ -2184,16 +2139,14 @@ static void emitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser,
raw_ostream &OS) {
// Construct the match list.
std::vector<StringMatcher::StringPair> Matches;
- const std::vector<CodeGenRegister*> &Regs =
- Target.getRegBank().getRegisters();
- for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
- const CodeGenRegister *Reg = Regs[i];
- if (Reg->TheDef->getValueAsString("AsmName").empty())
+ const auto &Regs = Target.getRegBank().getRegisters();
+ for (const CodeGenRegister &Reg : Regs) {
+ if (Reg.TheDef->getValueAsString("AsmName").empty())
continue;
- Matches.push_back(StringMatcher::StringPair(
- Reg->TheDef->getValueAsString("AsmName"),
- "return " + utostr(Reg->EnumValue) + ";"));
+ Matches.push_back(
+ StringMatcher::StringPair(Reg.TheDef->getValueAsString("AsmName"),
+ "return " + utostr(Reg.EnumValue) + ";"));
}
OS << "static unsigned MatchRegisterName(StringRef Name) {\n";
@@ -2230,10 +2183,8 @@ static void emitSubtargetFeatureFlagEnumeration(AsmMatcherInfo &Info,
<< "instruction matching.\n";
OS << "enum SubtargetFeatureFlag : " << getMinimalRequiredFeaturesType(Info)
<< " {\n";
- for (std::map<Record*, SubtargetFeatureInfo*, LessRecordByID>::const_iterator
- it = Info.SubtargetFeatures.begin(),
- ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
- SubtargetFeatureInfo &SFI = *it->second;
+ for (const auto &SF : Info.SubtargetFeatures) {
+ const SubtargetFeatureInfo &SFI = SF.second;
OS << " " << SFI.getEnumName() << " = (1ULL << " << SFI.Index << "),\n";
}
OS << " Feature_None = 0\n";
@@ -2268,10 +2219,8 @@ static void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) {
<< "static const char *getSubtargetFeatureName(uint64_t Val) {\n";
if (!Info.SubtargetFeatures.empty()) {
OS << " switch(Val) {\n";
- typedef std::map<Record*, SubtargetFeatureInfo*, LessRecordByID> RecFeatMap;
- for (RecFeatMap::const_iterator it = Info.SubtargetFeatures.begin(),
- ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
- SubtargetFeatureInfo &SFI = *it->second;
+ for (const auto &SF : Info.SubtargetFeatures) {
+ const SubtargetFeatureInfo &SFI = SF.second;
// FIXME: Totally just a placeholder name to get the algorithm working.
OS << " case " << SFI.getEnumName() << ": return \""
<< SFI.TheDef->getValueAsString("PredicateName") << "\";\n";
@@ -2295,10 +2244,8 @@ static void emitComputeAvailableFeatures(AsmMatcherInfo &Info,
OS << "uint64_t " << Info.Target.getName() << ClassName << "::\n"
<< "ComputeAvailableFeatures(uint64_t FB) const {\n";
OS << " uint64_t Features = 0;\n";
- for (std::map<Record*, SubtargetFeatureInfo*, LessRecordByID>::const_iterator
- it = Info.SubtargetFeatures.begin(),
- ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
- SubtargetFeatureInfo &SFI = *it->second;
+ for (const auto &SF : Info.SubtargetFeatures) {
+ const SubtargetFeatureInfo &SFI = SF.second;
OS << " if (";
std::string CondStorage =
@@ -2344,7 +2291,7 @@ static std::string GetAliasRequiredFeatures(Record *R,
std::string Result;
unsigned NumFeatures = 0;
for (unsigned i = 0, e = ReqFeatures.size(); i != e; ++i) {
- SubtargetFeatureInfo *F = Info.getSubtargetFeature(ReqFeatures[i]);
+ const SubtargetFeatureInfo *F = Info.getSubtargetFeature(ReqFeatures[i]);
if (!F)
PrintFatalError(R->getLoc(), "Predicate '" + ReqFeatures[i]->getName() +
@@ -2488,8 +2435,8 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
<< " RequiredFeatures;\n";
OS << " " << getMinimalTypeForRange(MaxMnemonicIndex)
<< " Mnemonic;\n";
- OS << " " << getMinimalTypeForRange(Info.Classes.size())
- << " Class;\n";
+ OS << " " << getMinimalTypeForRange(std::distance(
+ Info.Classes.begin(), Info.Classes.end())) << " Class;\n";
OS << " " << getMinimalTypeForRange(MaxMask)
<< " OperandMask;\n\n";
OS << " StringRef getMnemonic() const {\n";
@@ -2566,13 +2513,11 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
<< " &Operands,\n unsigned MCK) {\n\n"
<< " switch(MCK) {\n";
- for (std::vector<ClassInfo*>::const_iterator it = Info.Classes.begin(),
- ie = Info.Classes.end(); it != ie; ++it) {
- ClassInfo *CI = *it;
- if (CI->ParserMethod.empty())
+ for (const auto &CI : Info.Classes) {
+ if (CI.ParserMethod.empty())
continue;
- OS << " case " << CI->Name << ":\n"
- << " return " << CI->ParserMethod << "(Operands);\n";
+ OS << " case " << CI.Name << ":\n"
+ << " return " << CI.ParserMethod << "(Operands);\n";
}
OS << " default:\n";
@@ -2651,22 +2596,23 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
// stable_sort to ensure that ambiguous instructions are still
// deterministically ordered.
std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(),
- less_ptr<MatchableInfo>());
+ [](const std::unique_ptr<MatchableInfo> &a,
+ const std::unique_ptr<MatchableInfo> &b){
+ return *a < *b;});
DEBUG_WITH_TYPE("instruction_info", {
- for (std::vector<MatchableInfo*>::iterator
- it = Info.Matchables.begin(), ie = Info.Matchables.end();
- it != ie; ++it)
- (*it)->dump();
+ for (const auto &MI : Info.Matchables)
+ MI->dump();
});
// Check for ambiguous matchables.
DEBUG_WITH_TYPE("ambiguous_instrs", {
unsigned NumAmbiguous = 0;
- for (unsigned i = 0, e = Info.Matchables.size(); i != e; ++i) {
- for (unsigned j = i + 1; j != e; ++j) {
- MatchableInfo &A = *Info.Matchables[i];
- MatchableInfo &B = *Info.Matchables[j];
+ for (auto I = Info.Matchables.begin(), E = Info.Matchables.end(); I != E;
+ ++I) {
+ for (auto J = std::next(I); J != E; ++J) {
+ const MatchableInfo &A = **I;
+ const MatchableInfo &B = **J;
if (A.couldMatchAmbiguouslyWith(B)) {
errs() << "warning: ambiguous matchables:\n";
@@ -2701,15 +2647,13 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " void convertToMapAndConstraints(unsigned Kind,\n ";
OS << " const OperandVector &Operands) override;\n";
OS << " bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) override;\n";
- OS << " unsigned MatchInstructionImpl(\n";
- OS.indent(27);
- OS << "const OperandVector &Operands,\n"
+ OS << " unsigned MatchInstructionImpl(const OperandVector &Operands,\n"
<< " MCInst &Inst,\n"
<< " uint64_t &ErrorInfo,"
<< " bool matchingInlineAsm,\n"
<< " unsigned VariantID = 0);\n";
- if (Info.OperandMatchInfo.size()) {
+ if (!Info.OperandMatchInfo.empty()) {
OS << "\n enum OperandMatchResultTy {\n";
OS << " MatchOperand_Success, // operand matched successfully\n";
OS << " MatchOperand_NoMatch, // operand did not match\n";
@@ -2786,15 +2730,12 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
size_t MaxNumOperands = 0;
unsigned MaxMnemonicIndex = 0;
bool HasDeprecation = false;
- for (std::vector<MatchableInfo*>::const_iterator it =
- Info.Matchables.begin(), ie = Info.Matchables.end();
- it != ie; ++it) {
- MatchableInfo &II = **it;
- MaxNumOperands = std::max(MaxNumOperands, II.AsmOperands.size());
- HasDeprecation |= II.HasDeprecation;
+ for (const auto &MI : Info.Matchables) {
+ MaxNumOperands = std::max(MaxNumOperands, MI->AsmOperands.size());
+ HasDeprecation |= MI->HasDeprecation;
// Store a pascal-style length byte in the mnemonic.
- std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str();
+ std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.str();
MaxMnemonicIndex = std::max(MaxMnemonicIndex,
StringTable.GetOrAddStringOffset(LenMnemonic, false));
}
@@ -2822,8 +2763,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
<< " ConvertFn;\n";
OS << " " << getMinimalRequiredFeaturesType(Info)
<< " RequiredFeatures;\n";
- OS << " " << getMinimalTypeForRange(Info.Classes.size())
- << " Classes[" << MaxNumOperands << "];\n";
+ OS << " " << getMinimalTypeForRange(
+ std::distance(Info.Classes.begin(), Info.Classes.end()))
+ << " Classes[" << MaxNumOperands << "];\n";
OS << " StringRef getMnemonic() const {\n";
OS << " return StringRef(MnemonicTable + Mnemonic + 1,\n";
OS << " MnemonicTable[Mnemonic]);\n";
@@ -2852,33 +2794,30 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << "static const MatchEntry MatchTable" << VC << "[] = {\n";
- for (std::vector<MatchableInfo*>::const_iterator it =
- Info.Matchables.begin(), ie = Info.Matchables.end();
- it != ie; ++it) {
- MatchableInfo &II = **it;
- if (II.AsmVariantID != AsmVariantNo)
+ for (const auto &MI : Info.Matchables) {
+ if (MI->AsmVariantID != AsmVariantNo)
continue;
// Store a pascal-style length byte in the mnemonic.
- std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str();
+ std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.str();
OS << " { " << StringTable.GetOrAddStringOffset(LenMnemonic, false)
- << " /* " << II.Mnemonic << " */, "
+ << " /* " << MI->Mnemonic << " */, "
<< Target.getName() << "::"
- << II.getResultInst()->TheDef->getName() << ", "
- << II.ConversionFnKind << ", ";
+ << MI->getResultInst()->TheDef->getName() << ", "
+ << MI->ConversionFnKind << ", ";
// Write the required features mask.
- if (!II.RequiredFeatures.empty()) {
- for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
+ if (!MI->RequiredFeatures.empty()) {
+ for (unsigned i = 0, e = MI->RequiredFeatures.size(); i != e; ++i) {
if (i) OS << "|";
- OS << II.RequiredFeatures[i]->getEnumName();
+ OS << MI->RequiredFeatures[i]->getEnumName();
}
} else
OS << "0";
OS << ", { ";
- for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) {
- MatchableInfo::AsmOperand &Op = II.AsmOperands[i];
+ for (unsigned i = 0, e = MI->AsmOperands.size(); i != e; ++i) {
+ const MatchableInfo::AsmOperand &Op = MI->AsmOperands[i];
if (i) OS << ", ";
OS << Op.Class->Name;
@@ -2895,7 +2834,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " // Find the appropriate table for this asm variant.\n";
OS << " const MatchEntry *Start, *End;\n";
OS << " switch (VariantID) {\n";
- OS << " default: // unreachable\n";
+ OS << " default: llvm_unreachable(\"invalid variant!\");\n";
for (unsigned VC = 0; VC != VariantCount; ++VC) {
Record *AsmVariant = Target.getAsmParserVariant(VC);
int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
@@ -2911,10 +2850,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
// Finally, build the match function.
OS << "unsigned " << Target.getName() << ClassName << "::\n"
- << "MatchInstructionImpl(const OperandVector"
- << " &Operands,\n";
- OS << " MCInst &Inst,\n"
- << "uint64_t &ErrorInfo, bool matchingInlineAsm, unsigned VariantID) {\n";
+ << "MatchInstructionImpl(const OperandVector &Operands,\n";
+ OS << " MCInst &Inst, uint64_t &ErrorInfo,\n"
+ << " bool matchingInlineAsm, unsigned VariantID) {\n";
OS << " // Eliminate obvious mismatches.\n";
OS << " if (Operands.size() > " << (MaxNumOperands+1) << ") {\n";
@@ -2949,7 +2887,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " // Find the appropriate table for this asm variant.\n";
OS << " const MatchEntry *Start, *End;\n";
OS << " switch (VariantID) {\n";
- OS << " default: // unreachable\n";
+ OS << " default: llvm_unreachable(\"invalid variant!\");\n";
for (unsigned VC = 0; VC != VariantCount; ++VC) {
Record *AsmVariant = Target.getAsmParserVariant(VC);
int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
@@ -3018,12 +2956,13 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " HadMatchOtherThanFeatures = true;\n";
OS << " uint64_t NewMissingFeatures = it->RequiredFeatures & "
"~AvailableFeatures;\n";
- OS << " if (CountPopulation_64(NewMissingFeatures) <=\n"
- " CountPopulation_64(MissingFeatures))\n";
+ OS << " if (countPopulation(NewMissingFeatures) <=\n"
+ " countPopulation(MissingFeatures))\n";
OS << " MissingFeatures = NewMissingFeatures;\n";
OS << " continue;\n";
OS << " }\n";
OS << "\n";
+ OS << " Inst.clear();\n\n";
OS << " if (matchingInlineAsm) {\n";
OS << " Inst.setOpcode(it->Opcode);\n";
OS << " convertToMapAndConstraints(it->ConvertFn, Operands);\n";
@@ -3072,7 +3011,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " return Match_MissingFeature;\n";
OS << "}\n\n";
- if (Info.OperandMatchInfo.size())
+ if (!Info.OperandMatchInfo.empty())
emitCustomOperandParsing(OS, Target, Info, ClassName, StringTable,
MaxMnemonicIndex);