X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=utils%2FTableGen%2FAsmMatcherEmitter.cpp;h=3663de77581b71df35d9b35da8df02733d3b7d80;hp=6365fb5907779916d7fac3c48056f13df6d7cfea;hb=1b153045997072ec74f84f8ec2cb89ec362cfd39;hpb=3ec563c51d5b54348c714f3143033dc86231765f diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 6365fb59077..3663de77581 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -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 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 AsmOperands; /// Predicates - The required subtarget features to match this instruction. - SmallVector RequiredFeatures; + SmallVector RequiredFeatures; /// ConversionFnKind - The enum value which is passed to the generated /// convertToMCInst to convert parsed operands into an MCInst for this @@ -434,18 +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 Alias) + : AsmVariantID(0), AsmString(Alias->AsmString), TheDef(Alias->TheDef), DefRec(Alias.release()) { } ~MatchableInfo() { - if (DefRec.is()) - delete DefRec.get(); + delete DefRec.dyn_cast(); } // Two-operand aliases clone from the main matchable, but mark the second @@ -616,7 +613,7 @@ public: std::forward_list Classes; /// The information on the matchables to match. - std::forward_list Matchables; + std::vector> Matchables; /// Info for custom matching operands by user defined methods. std::vector OperandMatchInfo; @@ -626,8 +623,7 @@ public: RegisterClassesTy RegisterClasses; /// Map of Predicate records to their subtarget information. - std::map, - LessRecordByID> SubtargetFeatures; + std::map SubtargetFeatures; /// Map of AsmOperandClass records to their class information. std::map AsmOperandClasses; @@ -675,10 +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!"); const auto &I = SubtargetFeatures.find(Def); - return I == SubtargetFeatures.end() ? nullptr : I->second.get(); + return I == SubtargetFeatures.end() ? nullptr : &I->second; } RecordKeeper &getRecords() const { @@ -782,8 +778,8 @@ void MatchableInfo::initialize(const AsmMatcherInfo &Info, // Compute the require features. std::vector 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. @@ -1081,10 +1077,8 @@ struct LessRegisterSet { void AsmMatcherInfo:: buildRegisterClasses(SmallPtrSetImpl &SingletonRegisters) { - const std::vector &Registers = - Target.getRegBank().getRegisters(); - ArrayRef RegClassList = - Target.getRegBank().getRegClasses(); + const auto &Registers = Target.getRegBank().getRegisters(); + auto &RegClassList = Target.getRegBank().getRegClasses(); typedef std::set RegisterSetSet; @@ -1092,9 +1086,9 @@ buildRegisterClasses(SmallPtrSetImpl &SingletonRegisters) { 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) { @@ -1105,12 +1099,12 @@ buildRegisterClasses(SmallPtrSetImpl &SingletonRegisters) { // a unique register set class), and build the mapping of registers to the set // they should classify to. std::map 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()) { @@ -1128,7 +1122,7 @@ buildRegisterClasses(SmallPtrSetImpl &SingletonRegisters) { if (!ContainingSet.empty()) { RegisterSets.insert(ContainingSet); - RegisterMap.insert(std::make_pair(CGR->TheDef, ContainingSet)); + RegisterMap.insert(std::make_pair(CGR.TheDef, ContainingSet)); } } @@ -1163,19 +1157,19 @@ buildRegisterClasses(SmallPtrSetImpl &SingletonRegisters) { } // 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)); } @@ -1285,8 +1279,8 @@ void AsmMatcherInfo::buildOperandMatchInfo() { // Keep track of all operands of this instructions which belong to the // same class. - for (unsigned i = 0, e = MI.AsmOperands.size(); i != e; ++i) { - const MatchableInfo::AsmOperand &Op = MI.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]; @@ -1297,7 +1291,8 @@ void AsmMatcherInfo::buildOperandMatchInfo() { for (const auto &OCM : OpClassMask) { unsigned OpMask = OCM.second; ClassInfo *CI = OCM.first; - OperandMatchInfo.push_back(OperandMatchEntry::create(&MI, CI, OpMask)); + OperandMatchInfo.push_back(OperandMatchEntry::create(MI.get(), CI, + OpMask)); } } } @@ -1315,11 +1310,10 @@ void AsmMatcherInfo::buildInfo() { if (Pred->getName().empty()) PrintFatalError(Pred->getLoc(), "Predicate has no name!"); - uint64_t FeatureNo = SubtargetFeatures.size(); - SubtargetFeatures[Pred] = - llvm::make_unique(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,15 +1338,16 @@ void AsmMatcherInfo::buildInfo() { if (CGI->TheDef->getValueAsBit("isCodeGenOnly")) continue; - Matchables.emplace_front(*CGI); - MatchableInfo *II = &Matchables.front(); + std::unique_ptr II(new MatchableInfo(*CGI)); II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix); // Ignore instructions which shouldn't be matched and diagnose invalid // instruction definitions with an error. if (!II->validate(CommentDelimiter, true)) - Matchables.pop_front(); + continue; + + Matchables.push_back(std::move(II)); } // Parse all of the InstAlias definitions and stick them in the list of @@ -1360,8 +1355,8 @@ void AsmMatcherInfo::buildInfo() { std::vector 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(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 @@ -1370,13 +1365,14 @@ void AsmMatcherInfo::buildInfo() { .startswith( MatchPrefix)) continue; - Matchables.emplace_front(Alias); - MatchableInfo *II = &Matchables.front(); + std::unique_ptr II(new MatchableInfo(std::move(Alias))); II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix); // Validate the alias definitions. II->validate(CommentDelimiter, false); + + Matchables.push_back(std::move(II)); } } @@ -1388,17 +1384,17 @@ void AsmMatcherInfo::buildInfo() { // Build the information about matchables, now that we have fully formed // classes. - std::forward_list NewMatchables; + std::vector> NewMatchables; for (auto &II : Matchables) { // Parse the tokens after the mnemonic. // Note: buildInstructionOperandReference may insert new AsmOperands, so // don't precompute the loop bound. - for (unsigned i = 0; i != II.AsmOperands.size(); ++i) { - MatchableInfo::AsmOperand &Op = II.AsmOperands[i]; + for (unsigned i = 0; i != II->AsmOperands.size(); ++i) { + MatchableInfo::AsmOperand &Op = II->AsmOperands[i]; StringRef Token = Op.Token; // Check for singleton registers. - if (Record *RegRecord = II.AsmOperands[i].SingletonReg) { + if (Record *RegRecord = II->AsmOperands[i].SingletonReg) { Op.Class = RegisterClasses[RegRecord]; assert(Op.Class && Op.Class->Registers.size() == 1 && "Unexpected class for singleton register"); @@ -1423,30 +1419,35 @@ void AsmMatcherInfo::buildInfo() { else OperandName = Token.substr(1); - if (II.DefRec.is()) - buildInstructionOperandReference(&II, OperandName, i); + if (II->DefRec.is()) + buildInstructionOperandReference(II.get(), OperandName, i); else - buildAliasOperandReference(&II, OperandName, Op); + buildAliasOperandReference(II.get(), OperandName, Op); } - if (II.DefRec.is()) { - II.buildInstructionResultOperands(); + if (II->DefRec.is()) { + II->buildInstructionResultOperands(); // If the instruction has a two-operand alias, build up the // matchable here. We'll add them in bulk at the end to avoid // confusing this loop. std::string Constraint = - II.TheDef->getValueAsString("TwoOperandAliasConstraint"); + II->TheDef->getValueAsString("TwoOperandAliasConstraint"); if (Constraint != "") { // Start by making a copy of the original matchable. - NewMatchables.emplace_front(II); + std::unique_ptr AliasII(new MatchableInfo(*II)); // Adjust it to be a two-operand alias. - NewMatchables.front().formTwoOperandAlias(Constraint); + AliasII->formTwoOperandAlias(Constraint); + + // Add the alias to the matchables list. + NewMatchables.push_back(std::move(AliasII)); } } else - II.buildAliasResultOperands(); + II->buildAliasResultOperands(); } - Matchables.splice_after(Matchables.before_begin(), NewMatchables); + if (!NewMatchables.empty()) + std::move(NewMatchables.begin(), NewMatchables.end(), + std::back_inserter(Matchables)); // Process token alias definitions and set up the associated superclass // information. @@ -1671,8 +1672,9 @@ static unsigned getConverterOperandID(const std::string &Name, return ID; } + static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, - std::forward_list &Infos, + std::vector> &Infos, raw_ostream &OS) { SetVector OperandConversionKinds; SetVector InstructionConversionKinds; @@ -1739,10 +1741,10 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, 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)) @@ -1774,17 +1776,17 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, std::vector 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. const MatchableInfo::AsmOperand &Op = - II.AsmOperands[OpInfo.AsmOperandNum]; + II->AsmOperands[OpInfo.AsmOperandNum]; // Registers are always converted the same, don't duplicate the // conversion function based on them. @@ -1907,7 +1909,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. @@ -2135,16 +2137,14 @@ static void emitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser, raw_ostream &OS) { // Construct the match list. std::vector Matches; - const std::vector &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"; @@ -2182,7 +2182,7 @@ static void emitSubtargetFeatureFlagEnumeration(AsmMatcherInfo &Info, OS << "enum SubtargetFeatureFlag : " << getMinimalRequiredFeaturesType(Info) << " {\n"; for (const auto &SF : Info.SubtargetFeatures) { - SubtargetFeatureInfo &SFI = *SF.second; + const SubtargetFeatureInfo &SFI = SF.second; OS << " " << SFI.getEnumName() << " = (1ULL << " << SFI.Index << "),\n"; } OS << " Feature_None = 0\n"; @@ -2218,7 +2218,7 @@ static void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) { if (!Info.SubtargetFeatures.empty()) { OS << " switch(Val) {\n"; for (const auto &SF : Info.SubtargetFeatures) { - SubtargetFeatureInfo &SFI = *SF.second; + 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"; @@ -2243,7 +2243,7 @@ static void emitComputeAvailableFeatures(AsmMatcherInfo &Info, << "ComputeAvailableFeatures(uint64_t FB) const {\n"; OS << " uint64_t Features = 0;\n"; for (const auto &SF : Info.SubtargetFeatures) { - SubtargetFeatureInfo &SFI = *SF.second; + const SubtargetFeatureInfo &SFI = SF.second; OS << " if ("; std::string CondStorage = @@ -2289,7 +2289,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() + @@ -2593,11 +2593,14 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { // Sort the instruction table using the partial order on classes. We use // stable_sort to ensure that ambiguous instructions are still // deterministically ordered. - Info.Matchables.sort(); + std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(), + [](const std::unique_ptr &a, + const std::unique_ptr &b){ + return *a < *b;}); DEBUG_WITH_TYPE("instruction_info", { for (const auto &MI : Info.Matchables) - MI.dump(); + MI->dump(); }); // Check for ambiguous matchables. @@ -2606,8 +2609,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { 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; + const MatchableInfo &A = **I; + const MatchableInfo &B = **J; if (A.couldMatchAmbiguouslyWith(B)) { errs() << "warning: ambiguous matchables:\n"; @@ -2728,11 +2731,11 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { unsigned MaxMnemonicIndex = 0; bool HasDeprecation = false; for (const auto &MI : Info.Matchables) { - MaxNumOperands = std::max(MaxNumOperands, MI.AsmOperands.size()); - HasDeprecation |= MI.HasDeprecation; + MaxNumOperands = std::max(MaxNumOperands, MI->AsmOperands.size()); + HasDeprecation |= MI->HasDeprecation; // Store a pascal-style length byte in the mnemonic. - std::string LenMnemonic = char(MI.Mnemonic.size()) + MI.Mnemonic.str(); + std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.str(); MaxMnemonicIndex = std::max(MaxMnemonicIndex, StringTable.GetOrAddStringOffset(LenMnemonic, false)); } @@ -2756,9 +2759,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " " << getMinimalTypeForRange(MaxMnemonicIndex) << " Mnemonic;\n"; OS << " uint16_t Opcode;\n"; - OS << " " << getMinimalTypeForRange(std::distance(Info.Matchables.begin(), - Info.Matchables.end())) - << " ConvertFn;\n"; + OS << " " << getMinimalTypeForRange(Info.Matchables.size()) + << " ConvertFn;\n"; OS << " " << getMinimalRequiredFeaturesType(Info) << " RequiredFeatures;\n"; OS << " " << getMinimalTypeForRange( @@ -2793,28 +2795,29 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "static const MatchEntry MatchTable" << VC << "[] = {\n"; for (const auto &MI : Info.Matchables) { - if (MI.AsmVariantID != AsmVariantNo) + if (MI->AsmVariantID != AsmVariantNo) continue; // Store a pascal-style length byte in the mnemonic. - std::string LenMnemonic = char(MI.Mnemonic.size()) + MI.Mnemonic.str(); + std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.str(); OS << " { " << StringTable.GetOrAddStringOffset(LenMnemonic, false) - << " /* " << MI.Mnemonic << " */, " << Target.getName() - << "::" << MI.getResultInst()->TheDef->getName() << ", " - << MI.ConversionFnKind << ", "; + << " /* " << MI->Mnemonic << " */, " + << Target.getName() << "::" + << MI->getResultInst()->TheDef->getName() << ", " + << MI->ConversionFnKind << ", "; // Write the required features mask. - if (!MI.RequiredFeatures.empty()) { - for (unsigned i = 0, e = MI.RequiredFeatures.size(); i != e; ++i) { + if (!MI->RequiredFeatures.empty()) { + for (unsigned i = 0, e = MI->RequiredFeatures.size(); i != e; ++i) { if (i) OS << "|"; - OS << MI.RequiredFeatures[i]->getEnumName(); + OS << MI->RequiredFeatures[i]->getEnumName(); } } else OS << "0"; OS << ", { "; - for (unsigned i = 0, e = MI.AsmOperands.size(); i != e; ++i) { - const MatchableInfo::AsmOperand &Op = MI.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; @@ -2960,6 +2963,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { 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";