[llvm] r222909 - Use unique_ptr to fix some memory leaks in Tablegen AsmMatcherEmitter.

Craig Topper craig.topper at gmail.com
Thu Nov 27 19:53:02 PST 2014


Author: ctopper
Date: Thu Nov 27 21:53:02 2014
New Revision: 222909

URL: http://llvm.org/viewvc/llvm-project?rev=222909&view=rev
Log:
Use unique_ptr to fix some memory leaks in Tablegen AsmMatcherEmitter.

Modified:
    llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp

Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=222909&r1=222908&r2=222909&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Thu Nov 27 21:53:02 2014
@@ -607,10 +607,10 @@ public:
   CodeGenTarget &Target;
 
   /// The classes which are needed for matching.
-  std::vector<ClassInfo*> Classes;
+  std::vector<std::unique_ptr<ClassInfo>> Classes;
 
   /// The information on the matchables to match.
-  std::vector<MatchableInfo*> Matchables;
+  std::vector<std::unique_ptr<MatchableInfo>> Matchables;
 
   /// Info for custom matching operands by user defined methods.
   std::vector<OperandMatchEntry> OperandMatchInfo;
@@ -620,7 +620,8 @@ public:
   RegisterClassesTy RegisterClasses;
 
   /// Map of Predicate records to their subtarget information.
-  std::map<Record*, SubtargetFeatureInfo*, LessRecordByID> SubtargetFeatures;
+  std::map<Record*, std::unique_ptr<SubtargetFeatureInfo>,
+           LessRecordByID> SubtargetFeatures;
 
   /// Map of AsmOperandClass records to their class information.
   std::map<Record*, ClassInfo*> 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
     Entry->RenderMethod = "<invalid>";
     Entry->ParserMethod = "";
     Entry->DiagnosticType = "";
-    Classes.push_back(Entry);
+    Classes.push_back(std::unique_ptr<ClassInfo>(Entry));
   }
 
   return Entry;
@@ -1139,7 +1140,7 @@ buildRegisterClasses(SmallPtrSetImpl<Rec
     CI->Registers = RS;
     // FIXME: diagnostic type.
     CI->DiagnosticType = "";
-    Classes.push_back(CI);
+    Classes.push_back(std::unique_ptr<ClassInfo>(CI));
     RegisterSetClasses.insert(std::make_pair(RS, CI));
     ++Index;
   }
@@ -1252,8 +1253,7 @@ void AsmMatcherInfo::buildOperandClasses
     if (StringInit *SI = dyn_cast<StringInit>(DiagnosticType))
       CI->DiagnosticType = SI->getValue();
 
-    AsmOperandClasses[Rec] = CI;
-    Classes.push_back(CI);
+    Classes.push_back(std::unique_ptr<ClassInfo>(CI));
     ++Index;
   }
 }
@@ -1273,7 +1273,7 @@ void AsmMatcherInfo::buildOperandMatchIn
   typedef std::map<ClassInfo *, unsigned, less_ptr<ClassInfo>> 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::buildOperandMatchIn
     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<SubtargetFeatureInfo>(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<MatchableInfo*> NewMatchables;
-  for (MatchableInfo *II : Matchables) {
+  std::vector<std::unique_ptr<MatchableInfo>> 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<const CodeGenInstruction*>())
-        buildInstructionOperandReference(II, OperandName, i);
+        buildInstructionOperandReference(II.get(), OperandName, i);
       else
-        buildAliasOperandReference(II, OperandName, Op);
+        buildAliasOperandReference(II.get(), OperandName, Op);
     }
 
     if (II->DefRec.is<const CodeGenInstruction*>()) {
@@ -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<ClassInfo>());
+  std::sort(Classes.begin(), Classes.end(),
+            [](const std::unique_ptr<ClassInfo> &a,
+               const std::unique_ptr<ClassInfo> &b){
+              return *a < *b;});
 }
 
 /// buildInstructionOperandReference - The specified operand is a reference to a
@@ -1672,7 +1677,7 @@ static unsigned getConverterOperandID(co
 
 
 static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
-                             std::vector<MatchableInfo*> &Infos,
+                             std::vector<std::unique_ptr<MatchableInfo>> &Infos,
                              raw_ostream &OS) {
   SetVector<std::string> OperandConversionKinds;
   SetVector<std::string> InstructionConversionKinds;
@@ -1736,7 +1741,7 @@ static void emitConvertFuncs(CodeGenTarg
   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(CodeGenTarg
 
 /// emitMatchClassEnumeration - Emit the enumeration for match class kinds.
 static void emitMatchClassEnumeration(CodeGenTarget &Target,
-                                      std::vector<ClassInfo*> &Infos,
-                                      raw_ostream &OS) {
+                                 std::vector<std::unique_ptr<ClassInfo>> &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(Asm
 
   // 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(Asm
 
 /// emitIsSubclass - Emit the subclass predicate function.
 static void emitIsSubclass(CodeGenTarget &Target,
-                           std::vector<ClassInfo*> &Infos,
+                           std::vector<std::unique_ptr<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";
@@ -2067,9 +2072,9 @@ static void emitIsSubclass(CodeGenTarget
   SS << "  switch (A) {\n";
   SS << "  default:\n";
   SS << "    return false;\n";
-  for (const ClassInfo *A : Infos) {
+  for (const auto &A : Infos) {
     std::vector<StringRef> 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
 /// emitMatchTokenString - Emit the function to match a token string to the
 /// appropriate match class value.
 static void emitMatchTokenString(CodeGenTarget &Target,
-                                 std::vector<ClassInfo*> &Infos,
+                                 std::vector<std::unique_ptr<ClassInfo>> &Infos,
                                  raw_ostream &OS) {
   // Construct the match list.
   std::vector<StringMatcher::StringPair> 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
      << " &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
   // stable_sort to ensure that ambiguous instructions are still
   // deterministically ordered.
   std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(),
-                   less_ptr<MatchableInfo>());
+                   [](const std::unique_ptr<MatchableInfo> &a,
+                      const std::unique_ptr<MatchableInfo> &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
   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 << "static const MatchEntry MatchTable" << VC << "[] = {\n";
 
-    for (const MatchableInfo *MI : Info.Matchables) {
+    for (const auto &MI : Info.Matchables) {
       if (MI->AsmVariantID != AsmVariantNo)
         continue;
 





More information about the llvm-commits mailing list