From: David Blaikie Date: Fri, 28 Nov 2014 21:20:24 +0000 (+0000) Subject: Simplify some more ownership using forward_list rather than vector> X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=3ec563c51d5b54348c714f3143033dc86231765f Simplify some more ownership using forward_list rather than vector> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222935 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 234c38ca69e..6365fb59077 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -616,7 +616,7 @@ public: std::forward_list Classes; /// The information on the matchables to match. - std::vector> Matchables; + std::forward_list Matchables; /// Info for custom matching operands by user defined methods. std::vector OperandMatchInfo; @@ -1285,8 +1285,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,8 +1297,7 @@ void AsmMatcherInfo::buildOperandMatchInfo() { for (const auto &OCM : OpClassMask) { unsigned OpMask = OCM.second; ClassInfo *CI = OCM.first; - OperandMatchInfo.push_back(OperandMatchEntry::create(MI.get(), CI, - OpMask)); + OperandMatchInfo.push_back(OperandMatchEntry::create(&MI, CI, OpMask)); } } } @@ -1345,16 +1344,15 @@ void AsmMatcherInfo::buildInfo() { if (CGI->TheDef->getValueAsBit("isCodeGenOnly")) continue; - std::unique_ptr II(new MatchableInfo(*CGI)); + Matchables.emplace_front(*CGI); + MatchableInfo *II = &Matchables.front(); 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)) - continue; - - Matchables.push_back(std::move(II)); + Matchables.pop_front(); } // Parse all of the InstAlias definitions and stick them in the list of @@ -1372,14 +1370,13 @@ void AsmMatcherInfo::buildInfo() { .startswith( MatchPrefix)) continue; - std::unique_ptr II(new MatchableInfo(Alias)); + Matchables.emplace_front(Alias); + MatchableInfo *II = &Matchables.front(); II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix); // Validate the alias definitions. II->validate(CommentDelimiter, false); - - Matchables.push_back(std::move(II)); } } @@ -1391,17 +1388,17 @@ void AsmMatcherInfo::buildInfo() { // Build the information about matchables, now that we have fully formed // classes. - std::vector> NewMatchables; + std::forward_list 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"); @@ -1426,35 +1423,30 @@ void AsmMatcherInfo::buildInfo() { else OperandName = Token.substr(1); - if (II->DefRec.is()) - buildInstructionOperandReference(II.get(), OperandName, i); + if (II.DefRec.is()) + buildInstructionOperandReference(&II, OperandName, i); else - buildAliasOperandReference(II.get(), OperandName, Op); + buildAliasOperandReference(&II, 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. - std::unique_ptr AliasII(new MatchableInfo(*II)); + NewMatchables.emplace_front(II); // Adjust it to be a two-operand alias. - AliasII->formTwoOperandAlias(Constraint); - - // Add the alias to the matchables list. - NewMatchables.push_back(std::move(AliasII)); + NewMatchables.front().formTwoOperandAlias(Constraint); } } else - II->buildAliasResultOperands(); + II.buildAliasResultOperands(); } - if (!NewMatchables.empty()) - std::move(NewMatchables.begin(), NewMatchables.end(), - std::back_inserter(Matchables)); + Matchables.splice_after(Matchables.before_begin(), NewMatchables); // Process token alias definitions and set up the associated superclass // information. @@ -1679,9 +1671,8 @@ static unsigned getConverterOperandID(const std::string &Name, return ID; } - static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, - std::vector> &Infos, + std::forward_list &Infos, raw_ostream &OS) { SetVector OperandConversionKinds; SetVector InstructionConversionKinds; @@ -1748,10 +1739,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)) @@ -1783,17 +1774,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. @@ -1916,7 +1907,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. @@ -2602,23 +2593,21 @@ 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. - std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(), - [](const std::unique_ptr &a, - const std::unique_ptr &b){ - return *a < *b;}); + Info.Matchables.sort(); DEBUG_WITH_TYPE("instruction_info", { for (const auto &MI : Info.Matchables) - MI->dump(); + 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) { - const MatchableInfo &A = *Info.Matchables[i]; - const 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"; @@ -2739,11 +2728,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)); } @@ -2767,8 +2756,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " " << getMinimalTypeForRange(MaxMnemonicIndex) << " Mnemonic;\n"; OS << " uint16_t Opcode;\n"; - OS << " " << getMinimalTypeForRange(Info.Matchables.size()) - << " ConvertFn;\n"; + OS << " " << getMinimalTypeForRange(std::distance(Info.Matchables.begin(), + Info.Matchables.end())) + << " ConvertFn;\n"; OS << " " << getMinimalRequiredFeaturesType(Info) << " RequiredFeatures;\n"; OS << " " << getMinimalTypeForRange( @@ -2803,29 +2793,28 @@ 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;