#include <map>
#include <set>
#include <sstream>
+#include <forward_list>
using namespace llvm;
#define DEBUG_TYPE "asm-matcher-emitter"
CodeGenTarget &Target;
/// The classes which are needed for matching.
- std::vector<std::unique_ptr<ClassInfo>> Classes;
+ std::forward_list<ClassInfo> Classes;
/// The information on the matchables to match.
std::vector<std::unique_ptr<MatchableInfo>> Matchables;
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(std::unique_ptr<ClassInfo>(Entry));
}
return Entry;
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(std::unique_ptr<ClassInfo>(CI));
RegisterSetClasses.insert(std::make_pair(RS, CI));
++Index;
}
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();
- Classes.push_back(std::unique_ptr<ClassInfo>(CI));
++Index;
}
}
}
// Reorder classes so that classes precede super classes.
- std::sort(Classes.begin(), Classes.end(),
- [](const std::unique_ptr<ClassInfo> &a,
- const std::unique_ptr<ClassInfo> &b){
- return *a < *b;});
+ Classes.sort();
}
/// buildInstructionOperandReference - The specified operand is a reference to a
/// emitMatchClassEnumeration - Emit the enumeration for match class kinds.
static void emitMatchClassEnumeration(CodeGenTarget &Target,
- std::vector<std::unique_ptr<ClassInfo>> &Infos,
- raw_ostream &OS) {
+ std::forward_list<ClassInfo> &Infos,
+ raw_ostream &OS) {
OS << "namespace {\n\n";
OS << "/// MatchClassKind - The kinds of classes which participate in\n"
OS << "enum MatchClassKind {\n";
OS << " InvalidMatchClass = 0,\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";
+ 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 auto &CI : Info.Classes) {
- if (!CI->isUserClass())
+ 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<std::unique_ptr<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";
for (const auto &A : Infos) {
std::vector<StringRef> SuperClasses;
for (const auto &B : Infos) {
- if (A != B && A->isSubsetOf(*B))
- SuperClasses.push_back(B->Name);
+ 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<std::unique_ptr<ClassInfo>> &Infos,
+ std::forward_list<ClassInfo> &Infos,
raw_ostream &OS) {
// Construct the match list.
std::vector<StringMatcher::StringPair> Matches;
for (const auto &CI : Infos) {
- if (CI->Kind == ClassInfo::Token)
- Matches.push_back(StringMatcher::StringPair(CI->ValueName,
- "return " + CI->Name + ";"));
+ if (CI.Kind == ClassInfo::Token)
+ Matches.push_back(StringMatcher::StringPair(CI.ValueName,
+ "return " + CI.Name + ";"));
}
OS << "static MatchClassKind matchTokenString(StringRef Name) {\n";
<< " 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";
<< " switch(MCK) {\n";
for (const auto &CI : Info.Classes) {
- if (CI->ParserMethod.empty())
+ 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";
<< " 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";