class AsmVariantInfo {
public:
+ std::string RegisterPrefix;
std::string TokenizingCharacters;
std::string SeparatorCharacters;
std::string BreakCharacters;
+ int AsmVariantNo;
};
/// MatchableInfo - Helper class for storing the necessary information for an
void initialize(const AsmMatcherInfo &Info,
SmallPtrSetImpl<Record*> &SingletonRegisters,
- int AsmVariantNo, StringRef RegisterPrefix,
AsmVariantInfo const &Variant);
/// validate - Return true if this matchable is a valid thing to match against
void MatchableInfo::initialize(const AsmMatcherInfo &Info,
SmallPtrSetImpl<Record*> &SingletonRegisters,
- int AsmVariantNo, StringRef RegisterPrefix,
AsmVariantInfo const &Variant) {
- AsmVariantID = AsmVariantNo;
+ AsmVariantID = Variant.AsmVariantNo;
AsmString =
- CodeGenInstruction::FlattenAsmStringVariants(AsmString, AsmVariantNo);
+ CodeGenInstruction::FlattenAsmStringVariants(AsmString,
+ Variant.AsmVariantNo);
tokenizeAsmString(Info, Variant);
// Collect singleton registers, if used.
for (MatchableInfo::AsmOperand &Op : AsmOperands) {
- extractSingletonRegisterForAsmOperand(Op, Info, RegisterPrefix);
+ extractSingletonRegisterForAsmOperand(Op, Info, Variant.RegisterPrefix);
if (Record *Reg = Op.SingletonReg)
SingletonRegisters.insert(Reg);
}
// Also, check for instructions which reference the operand multiple times;
// this implies a constraint we would not honor.
std::set<std::string> OperandNames;
- for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
- StringRef Tok = AsmOperands[i].Token;
+ for (const AsmOperand &Op : AsmOperands) {
+ StringRef Tok = Op.Token;
if (Tok[0] == '$' && Tok.find(':') != StringRef::npos)
PrintFatalError(TheDef->getLoc(),
"matchable with operand modifier '" + Tok +
Record *AsmVariant = Target.getAsmParserVariant(VC);
std::string CommentDelimiter =
AsmVariant->getValueAsString("CommentDelimiter");
- std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix");
AsmVariantInfo Variant;
+ Variant.RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix");
Variant.TokenizingCharacters =
AsmVariant->getValueAsString("TokenizingCharacters");
Variant.SeparatorCharacters =
AsmVariant->getValueAsString("SeparatorCharacters");
Variant.BreakCharacters =
AsmVariant->getValueAsString("BreakCharacters");
- int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
+ Variant.AsmVariantNo = AsmVariant->getValueAsInt("Variant");
for (const CodeGenInstruction *CGI : Target.instructions()) {
auto II = llvm::make_unique<MatchableInfo>(*CGI);
- II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix,
- Variant);
+ II->initialize(*this, SingletonRegisters, Variant);
// Ignore instructions which shouldn't be matched and diagnose invalid
// instruction definitions with an error.
Records.getAllDerivedDefinitions("InstAlias");
for (unsigned i = 0, e = AllInstAliases.size(); i != e; ++i) {
auto Alias = llvm::make_unique<CodeGenInstAlias>(AllInstAliases[i],
- AsmVariantNo, Target);
+ Variant.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
auto II = llvm::make_unique<MatchableInfo>(std::move(Alias));
- II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix,
- Variant);
+ II->initialize(*this, SingletonRegisters, Variant);
// Validate the alias definitions.
II->validate(CommentDelimiter, false);
OS << " if (A == B)\n";
OS << " return true;\n\n";
- std::string OStr;
- raw_string_ostream SS(OStr);
- unsigned Count = 0;
- SS << " switch (A) {\n";
- SS << " default:\n";
- SS << " return false;\n";
+ bool EmittedSwitch = false;
for (const auto &A : Infos) {
std::vector<StringRef> SuperClasses;
for (const auto &B : Infos) {
if (SuperClasses.empty())
continue;
- ++Count;
- SS << "\n case " << A.Name << ":\n";
+ // If this is the first SuperClass, emit the switch header.
+ if (!EmittedSwitch) {
+ OS << " switch (A) {\n"
+ OS << " default:\n";
+ OS << " return false;\n";
+ EmittedSwitch = true;
+ }
+
+ OS << "\n case " << A.Name << ":\n";
if (SuperClasses.size() == 1) {
- SS << " return B == " << SuperClasses.back().str() << ";\n";
+ OS << " return B == " << SuperClasses.back().str() << ";\n";
continue;
}
if (!SuperClasses.empty()) {
- SS << " switch (B) {\n";
- SS << " default: return false;\n";
- for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
- SS << " case " << SuperClasses[i].str() << ": return true;\n";
- SS << " }\n";
+ OS << " switch (B) {\n";
+ OS << " default: return false;\n";
+ for (StringRef SC : SuperClasses)
+ OS << " case " << SC << ": return true;\n";
+ OS << " }\n";
} else {
// No case statement to emit
- SS << " return false;\n";
+ OS << " return false;\n";
}
}
- SS << " }\n";
+ OS << " }\n";
- // If there were case statements emitted into the string stream, write them
- // to the output stream, otherwise write the default.
- if (Count)
- OS << SS.str();
- else
+ // If there were case statements emitted into the string stream write the
+ // default.
+ if (!EmittedSwitch)
OS << " return false;\n";
OS << "}\n\n";