#include <map>
#include <set>
#include <sstream>
+#include <forward_list>
using namespace llvm;
#define DEBUG_TYPE "asm-matcher-emitter"
/// 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;
/// 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;
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
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
/// 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;
return !(HasLT ^ HasGT);
}
- void dump();
+ void dump() const;
private:
void tokenizeAsmString(const AsmMatcherInfo &Info);
return "Feature_" + TheDef->getName();
}
- void dump() {
+ void dump() const {
errs() << getEnumName() << " " << Index << "\n";
TheDef->dump();
}
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;
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;
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;
/// 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 {
} // 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";
}
// 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.
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);
Entry->RenderMethod = "<invalid>";
Entry->ParserMethod = "";
Entry->DiagnosticType = "";
- Classes.push_back(Entry);
}
return Entry;
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;
RegisterSetSet RegisterSets;
// Gather the defined sets.
- for (const CodeGenRegisterClass *RC : RegClassList)
- RegisterSets.insert(RegisterSet(RC->getOrder().begin(),
- RC->getOrder().end()));
+ for (const CodeGenRegisterClass &RC : RegClassList)
+ RegisterSets.insert(
+ RegisterSet(RC.getOrder().begin(), RC.getOrder().end()));
// Add any required singleton sets.
for (Record *Rec : 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 (const CodeGenRegister *CGR : Registers) {
+ for (const CodeGenRegister &CGR : Registers) {
// Compute the intersection of all sets containing this register.
RegisterSet ContainingSet;
for (const RegisterSet &RS : RegisterSets) {
- if (!RS.count(CGR->TheDef))
+ if (!RS.count(CGR.TheDef))
continue;
if (ContainingSet.empty()) {
if (!ContainingSet.empty()) {
RegisterSets.insert(ContainingSet);
- RegisterMap.insert(std::make_pair(CGR->TheDef, ContainingSet));
+ RegisterMap.insert(std::make_pair(CGR.TheDef, ContainingSet));
}
}
std::map<RegisterSet, ClassInfo*, LessRegisterSet> RegisterSetClasses;
unsigned Index = 0;
for (const RegisterSet &RS : RegisterSets) {
- ClassInfo *CI = new ClassInfo();
+ Classes.emplace_front();
+ ClassInfo *CI = &Classes.front();
CI->Kind = ClassInfo::RegisterClass0 + Index;
CI->ClassName = "Reg" + utostr(Index);
CI->Name = "MCK_Reg" + utostr(Index);
CI->Registers = RS;
// FIXME: diagnostic type.
CI->DiagnosticType = "";
- Classes.push_back(CI);
RegisterSetClasses.insert(std::make_pair(RS, CI));
++Index;
}
}
// Name the register classes which correspond to a user defined RegisterClass.
- for (const CodeGenRegisterClass *RC : RegClassList) {
+ for (const CodeGenRegisterClass &RC : RegClassList) {
// Def will be NULL for non-user defined register classes.
- Record *Def = RC->getDef();
+ Record *Def = RC.getDef();
if (!Def)
continue;
- ClassInfo *CI = RegisterSetClasses[RegisterSet(RC->getOrder().begin(),
- RC->getOrder().end())];
+ ClassInfo *CI = RegisterSetClasses[RegisterSet(RC.getOrder().begin(),
+ RC.getOrder().end())];
if (CI->ValueName.empty()) {
- CI->ClassName = RC->getName();
- CI->Name = "MCK_" + RC->getName();
- CI->ValueName = RC->getName();
+ CI->ClassName = RC.getName();
+ CI->Name = "MCK_" + RC.getName();
+ CI->ValueName = RC.getName();
} else
- CI->ValueName = CI->ValueName + "," + RC->getName();
+ CI->ValueName = CI->ValueName + "," + RC.getName();
RegisterClassClasses.insert(std::make_pair(Def, CI));
}
Records.getAllDerivedDefinitions("AsmOperandClass");
// Pre-populate AsmOperandClasses map.
- for (Record *Rec : AsmOperands)
- AsmOperandClasses[Rec] = new ClassInfo();
+ for (Record *Rec : AsmOperands) {
+ Classes.emplace_front();
+ AsmOperandClasses[Rec] = &Classes.front();
+ }
unsigned Index = 0;
for (Record *Rec : AsmOperands) {
if (StringInit *SI = dyn_cast<StringInit>(DiagnosticType))
CI->DiagnosticType = SI->getValue();
- AsmOperandClasses[Rec] = CI;
- Classes.push_back(CI);
++Index;
}
}
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];
}
// 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));
}
}
}
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
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
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
.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));
}
}
// Build the information about matchables, now that we have fully formed
// classes.
- std::vector<MatchableInfo*> NewMatchables;
- for (MatchableInfo *II : Matchables) {
+ 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.
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*>()) {
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.
}
// 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
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;
OperandConversionKinds.insert("CVT_Tied");
enum { CVT_Done, CVT_Reg, CVT_Tied };
- for (MatchableInfo *II : Infos) {
+ for (auto &II : Infos) {
// Check if we have a custom match function.
std::string AsmMatchConverter =
II->getResultInst()->TheDef->getValueAsString("AsmMatchConverter");
/// 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";
<< "/// instruction matching.\n";
OS << "enum MatchClassKind {\n";
OS << " InvalidMatchClass = 0,\n";
- for (const ClassInfo *CI : Infos) {
- OS << " " << CI->Name << ", // ";
- if (CI->Kind == ClassInfo::Token) {
- OS << "'" << CI->ValueName << "'\n";
- } else if (CI->isRegisterClass()) {
- if (!CI->ValueName.empty())
- OS << "register class '" << CI->ValueName << "'\n";
+ for (const auto &CI : Infos) {
+ OS << " " << CI.Name << ", // ";
+ if (CI.Kind == ClassInfo::Token) {
+ OS << "'" << CI.ValueName << "'\n";
+ } else if (CI.isRegisterClass()) {
+ if (!CI.ValueName.empty())
+ OS << "register class '" << CI.ValueName << "'\n";
else
OS << "derived register class\n";
} else {
- OS << "user defined class '" << CI->ValueName << "'\n";
+ OS << "user defined class '" << CI.ValueName << "'\n";
}
}
OS << " NumMatchClassKinds\n";
// Check the user classes. We don't care what order since we're only
// actually matching against one of them.
- for (const ClassInfo *CI : Info.Classes) {
- if (!CI->isUserClass())
+ for (const auto &CI : Info.Classes) {
+ if (!CI.isUserClass())
continue;
- OS << " // '" << CI->ClassName << "' class\n";
- OS << " if (Kind == " << CI->Name << ") {\n";
- OS << " if (Operand." << CI->PredicateMethod << "())\n";
+ OS << " // '" << CI.ClassName << "' class\n";
+ OS << " if (Kind == " << CI.Name << ") {\n";
+ OS << " if (Operand." << CI.PredicateMethod << "())\n";
OS << " return MCTargetAsmParser::Match_Success;\n";
- if (!CI->DiagnosticType.empty())
+ if (!CI.DiagnosticType.empty())
OS << " return " << Info.Target.getName() << "AsmParser::Match_"
- << CI->DiagnosticType << ";\n";
+ << CI.DiagnosticType << ";\n";
OS << " }\n\n";
}
/// 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";
SS << " switch (A) {\n";
SS << " default:\n";
SS << " return false;\n";
- for (const ClassInfo *A : Infos) {
+ for (const auto &A : Infos) {
std::vector<StringRef> SuperClasses;
- for (const ClassInfo *B : Infos) {
- if (A != B && A->isSubsetOf(*B))
- SuperClasses.push_back(B->Name);
+ for (const auto &B : Infos) {
+ if (&A != &B && A.isSubsetOf(B))
+ SuperClasses.push_back(B.Name);
}
if (SuperClasses.empty())
continue;
++Count;
- SS << "\n case " << A->Name << ":\n";
+ SS << "\n case " << A.Name << ":\n";
if (SuperClasses.size() == 1) {
SS << " return B == " << SuperClasses.back().str() << ";\n";
/// 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 (const ClassInfo *CI : Infos) {
- if (CI->Kind == ClassInfo::Token)
- Matches.push_back(StringMatcher::StringPair(CI->ValueName,
- "return " + CI->Name + ";"));
+ for (const auto &CI : Infos) {
+ if (CI.Kind == ClassInfo::Token)
+ Matches.push_back(
+ StringMatcher::StringPair(CI.ValueName, "return " + CI.Name + ";"));
}
OS << "static MatchClassKind matchTokenString(StringRef Name) {\n";
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";
<< "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";
<< "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";
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 =
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() +
<< " 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";
<< " &Operands,\n unsigned MCK) {\n\n"
<< " switch(MCK) {\n";
- for (const ClassInfo *CI : Info.Classes) {
- 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";
// 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";
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));
}
<< " 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";
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;
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";