From: Craig Topper Date: Fri, 28 Nov 2014 03:53:02 +0000 (+0000) Subject: Use unique_ptr to fix some memory leaks in Tablegen AsmMatcherEmitter. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=44ebfb7f7cd788d4b874c865502210cc2df086e8;p=oota-llvm.git Use unique_ptr to fix some memory leaks in Tablegen AsmMatcherEmitter. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222909 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 2612ba735f1..45fc26801d3 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -607,10 +607,10 @@ public: CodeGenTarget &Target; /// The classes which are needed for matching. - std::vector Classes; + std::vector> Classes; /// The information on the matchables to match. - std::vector Matchables; + std::vector> Matchables; /// Info for custom matching operands by user defined methods. std::vector OperandMatchInfo; @@ -620,7 +620,8 @@ public: RegisterClassesTy RegisterClasses; /// Map of Predicate records to their subtarget information. - std::map SubtargetFeatures; + std::map, + LessRecordByID> SubtargetFeatures; /// Map of AsmOperandClass records to their class information. std::map AsmOperandClasses; @@ -671,7 +672,7 @@ public: 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; + return I == SubtargetFeatures.end() ? nullptr : I->second.get(); } RecordKeeper &getRecords() const { @@ -1002,7 +1003,7 @@ ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) { Entry->RenderMethod = ""; Entry->ParserMethod = ""; Entry->DiagnosticType = ""; - Classes.push_back(Entry); + Classes.push_back(std::unique_ptr(Entry)); } return Entry; @@ -1139,7 +1140,7 @@ buildRegisterClasses(SmallPtrSetImpl &SingletonRegisters) { CI->Registers = RS; // FIXME: diagnostic type. CI->DiagnosticType = ""; - Classes.push_back(CI); + Classes.push_back(std::unique_ptr(CI)); RegisterSetClasses.insert(std::make_pair(RS, CI)); ++Index; } @@ -1252,8 +1253,7 @@ void AsmMatcherInfo::buildOperandClasses() { if (StringInit *SI = dyn_cast(DiagnosticType)) CI->DiagnosticType = SI->getValue(); - AsmOperandClasses[Rec] = CI; - Classes.push_back(CI); + Classes.push_back(std::unique_ptr(CI)); ++Index; } } @@ -1273,7 +1273,7 @@ void AsmMatcherInfo::buildOperandMatchInfo() { typedef std::map> OpClassMaskTy; OpClassMaskTy OpClassMask; - for (const MatchableInfo *MI : Matchables) { + for (const auto &MI : Matchables) { OpClassMask.clear(); // Keep track of all operands of this instructions which belong to the @@ -1290,7 +1290,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)); } } } @@ -1309,7 +1310,8 @@ void AsmMatcherInfo::buildInfo() { PrintFatalError(Pred->getLoc(), "Predicate has no name!"); uint64_t FeatureNo = SubtargetFeatures.size(); - SubtargetFeatures[Pred] = new SubtargetFeatureInfo(Pred, FeatureNo); + SubtargetFeatures[Pred] = + llvm::make_unique(Pred, FeatureNo); DEBUG(SubtargetFeatures[Pred]->dump()); assert(FeatureNo < 64 && "Too many subtarget features!"); } @@ -1345,7 +1347,7 @@ void AsmMatcherInfo::buildInfo() { if (!II->validate(CommentDelimiter, true)) 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 @@ -1370,7 +1372,7 @@ void AsmMatcherInfo::buildInfo() { // Validate the alias definitions. II->validate(CommentDelimiter, false); - Matchables.push_back(II.release()); + Matchables.push_back(std::move(II)); } } @@ -1382,8 +1384,8 @@ void AsmMatcherInfo::buildInfo() { // Build the information about matchables, now that we have fully formed // classes. - std::vector NewMatchables; - for (MatchableInfo *II : Matchables) { + 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. @@ -1418,9 +1420,9 @@ void AsmMatcherInfo::buildInfo() { OperandName = Token.substr(1); if (II->DefRec.is()) - buildInstructionOperandReference(II, OperandName, i); + buildInstructionOperandReference(II.get(), OperandName, i); else - buildAliasOperandReference(II, OperandName, Op); + buildAliasOperandReference(II.get(), OperandName, Op); } if (II->DefRec.is()) { @@ -1438,14 +1440,14 @@ void AsmMatcherInfo::buildInfo() { 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. @@ -1462,7 +1464,10 @@ void AsmMatcherInfo::buildInfo() { } // Reorder classes so that classes precede super classes. - std::sort(Classes.begin(), Classes.end(), less_ptr()); + std::sort(Classes.begin(), Classes.end(), + [](const std::unique_ptr &a, + const std::unique_ptr &b){ + return *a < *b;}); } /// buildInstructionOperandReference - The specified operand is a reference to a @@ -1672,7 +1677,7 @@ static unsigned getConverterOperandID(const std::string &Name, static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, - std::vector &Infos, + std::vector> &Infos, raw_ostream &OS) { SetVector OperandConversionKinds; SetVector InstructionConversionKinds; @@ -1736,7 +1741,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, 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"); @@ -1970,15 +1975,15 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, /// emitMatchClassEnumeration - Emit the enumeration for match class kinds. static void emitMatchClassEnumeration(CodeGenTarget &Target, - std::vector &Infos, - raw_ostream &OS) { + std::vector> &Infos, + raw_ostream &OS) { OS << "namespace {\n\n"; OS << "/// MatchClassKind - The kinds of classes which participate in\n" << "/// instruction matching.\n"; OS << "enum MatchClassKind {\n"; OS << " InvalidMatchClass = 0,\n"; - for (const ClassInfo *CI : Infos) { + for (const auto &CI : Infos) { OS << " " << CI->Name << ", // "; if (CI->Kind == ClassInfo::Token) { OS << "'" << CI->ValueName << "'\n"; @@ -2018,7 +2023,7 @@ static void emitValidateOperandClass(AsmMatcherInfo &Info, // 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) { + for (const auto &CI : Info.Classes) { if (!CI->isUserClass()) continue; @@ -2054,7 +2059,7 @@ static void emitValidateOperandClass(AsmMatcherInfo &Info, /// emitIsSubclass - Emit the subclass predicate function. static void emitIsSubclass(CodeGenTarget &Target, - std::vector &Infos, + std::vector> &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"; @@ -2067,9 +2072,9 @@ static void emitIsSubclass(CodeGenTarget &Target, SS << " switch (A) {\n"; SS << " default:\n"; SS << " return false;\n"; - for (const ClassInfo *A : Infos) { + for (const auto &A : Infos) { std::vector SuperClasses; - for (const ClassInfo *B : Infos) { + for (const auto &B : Infos) { if (A != B && A->isSubsetOf(*B)) SuperClasses.push_back(B->Name); } @@ -2111,11 +2116,11 @@ static void emitIsSubclass(CodeGenTarget &Target, /// emitMatchTokenString - Emit the function to match a token string to the /// appropriate match class value. static void emitMatchTokenString(CodeGenTarget &Target, - std::vector &Infos, + std::vector> &Infos, raw_ostream &OS) { // Construct the match list. std::vector Matches; - for (const ClassInfo *CI : Infos) { + for (const auto &CI : Infos) { if (CI->Kind == ClassInfo::Token) Matches.push_back(StringMatcher::StringPair(CI->ValueName, "return " + CI->Name + ";")); @@ -2511,7 +2516,7 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, << " &Operands,\n unsigned MCK) {\n\n" << " switch(MCK) {\n"; - for (const ClassInfo *CI : Info.Classes) { + for (const auto &CI : Info.Classes) { if (CI->ParserMethod.empty()) continue; OS << " case " << CI->Name << ":\n" @@ -2594,10 +2599,12 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { // stable_sort to ensure that ambiguous instructions are still // deterministically ordered. std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(), - less_ptr()); + [](const std::unique_ptr &a, + const std::unique_ptr &b){ + return *a < *b;}); DEBUG_WITH_TYPE("instruction_info", { - for (const MatchableInfo *MI : Info.Matchables) + for (const auto &MI : Info.Matchables) MI->dump(); }); @@ -2727,7 +2734,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { size_t MaxNumOperands = 0; unsigned MaxMnemonicIndex = 0; bool HasDeprecation = false; - for (const MatchableInfo *MI : Info.Matchables) { + for (const auto &MI : Info.Matchables) { MaxNumOperands = std::max(MaxNumOperands, MI->AsmOperands.size()); HasDeprecation |= MI->HasDeprecation; @@ -2790,7 +2797,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "static const MatchEntry MatchTable" << VC << "[] = {\n"; - for (const MatchableInfo *MI : Info.Matchables) { + for (const auto &MI : Info.Matchables) { if (MI->AsmVariantID != AsmVariantNo) continue;