forked from OSchip/llvm-project
Use unique_ptr to fix some memory leaks in Tablegen AsmMatcherEmitter.
llvm-svn: 222909
This commit is contained in:
parent
42bd819882
commit
f34dad9aa3
|
@ -607,10 +607,10 @@ public:
|
||||||
CodeGenTarget &Target;
|
CodeGenTarget &Target;
|
||||||
|
|
||||||
/// The classes which are needed for matching.
|
/// 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.
|
/// 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.
|
/// Info for custom matching operands by user defined methods.
|
||||||
std::vector<OperandMatchEntry> OperandMatchInfo;
|
std::vector<OperandMatchEntry> OperandMatchInfo;
|
||||||
|
@ -620,7 +620,8 @@ public:
|
||||||
RegisterClassesTy RegisterClasses;
|
RegisterClassesTy RegisterClasses;
|
||||||
|
|
||||||
/// Map of Predicate records to their subtarget information.
|
/// 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.
|
/// Map of AsmOperandClass records to their class information.
|
||||||
std::map<Record*, ClassInfo*> AsmOperandClasses;
|
std::map<Record*, ClassInfo*> AsmOperandClasses;
|
||||||
|
@ -671,7 +672,7 @@ public:
|
||||||
SubtargetFeatureInfo *getSubtargetFeature(Record *Def) const {
|
SubtargetFeatureInfo *getSubtargetFeature(Record *Def) const {
|
||||||
assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!");
|
assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!");
|
||||||
const auto &I = SubtargetFeatures.find(Def);
|
const auto &I = SubtargetFeatures.find(Def);
|
||||||
return I == SubtargetFeatures.end() ? nullptr : I->second;
|
return I == SubtargetFeatures.end() ? nullptr : I->second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordKeeper &getRecords() const {
|
RecordKeeper &getRecords() const {
|
||||||
|
@ -1002,7 +1003,7 @@ ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) {
|
||||||
Entry->RenderMethod = "<invalid>";
|
Entry->RenderMethod = "<invalid>";
|
||||||
Entry->ParserMethod = "";
|
Entry->ParserMethod = "";
|
||||||
Entry->DiagnosticType = "";
|
Entry->DiagnosticType = "";
|
||||||
Classes.push_back(Entry);
|
Classes.push_back(std::unique_ptr<ClassInfo>(Entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Entry;
|
return Entry;
|
||||||
|
@ -1139,7 +1140,7 @@ buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) {
|
||||||
CI->Registers = RS;
|
CI->Registers = RS;
|
||||||
// FIXME: diagnostic type.
|
// FIXME: diagnostic type.
|
||||||
CI->DiagnosticType = "";
|
CI->DiagnosticType = "";
|
||||||
Classes.push_back(CI);
|
Classes.push_back(std::unique_ptr<ClassInfo>(CI));
|
||||||
RegisterSetClasses.insert(std::make_pair(RS, CI));
|
RegisterSetClasses.insert(std::make_pair(RS, CI));
|
||||||
++Index;
|
++Index;
|
||||||
}
|
}
|
||||||
|
@ -1252,8 +1253,7 @@ void AsmMatcherInfo::buildOperandClasses() {
|
||||||
if (StringInit *SI = dyn_cast<StringInit>(DiagnosticType))
|
if (StringInit *SI = dyn_cast<StringInit>(DiagnosticType))
|
||||||
CI->DiagnosticType = SI->getValue();
|
CI->DiagnosticType = SI->getValue();
|
||||||
|
|
||||||
AsmOperandClasses[Rec] = CI;
|
Classes.push_back(std::unique_ptr<ClassInfo>(CI));
|
||||||
Classes.push_back(CI);
|
|
||||||
++Index;
|
++Index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1273,7 +1273,7 @@ void AsmMatcherInfo::buildOperandMatchInfo() {
|
||||||
typedef std::map<ClassInfo *, unsigned, less_ptr<ClassInfo>> OpClassMaskTy;
|
typedef std::map<ClassInfo *, unsigned, less_ptr<ClassInfo>> OpClassMaskTy;
|
||||||
OpClassMaskTy OpClassMask;
|
OpClassMaskTy OpClassMask;
|
||||||
|
|
||||||
for (const MatchableInfo *MI : Matchables) {
|
for (const auto &MI : Matchables) {
|
||||||
OpClassMask.clear();
|
OpClassMask.clear();
|
||||||
|
|
||||||
// Keep track of all operands of this instructions which belong to the
|
// Keep track of all operands of this instructions which belong to the
|
||||||
|
@ -1290,7 +1290,8 @@ void AsmMatcherInfo::buildOperandMatchInfo() {
|
||||||
for (const auto &OCM : OpClassMask) {
|
for (const auto &OCM : OpClassMask) {
|
||||||
unsigned OpMask = OCM.second;
|
unsigned OpMask = OCM.second;
|
||||||
ClassInfo *CI = OCM.first;
|
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!");
|
PrintFatalError(Pred->getLoc(), "Predicate has no name!");
|
||||||
|
|
||||||
uint64_t FeatureNo = SubtargetFeatures.size();
|
uint64_t FeatureNo = SubtargetFeatures.size();
|
||||||
SubtargetFeatures[Pred] = new SubtargetFeatureInfo(Pred, FeatureNo);
|
SubtargetFeatures[Pred] =
|
||||||
|
llvm::make_unique<SubtargetFeatureInfo>(Pred, FeatureNo);
|
||||||
DEBUG(SubtargetFeatures[Pred]->dump());
|
DEBUG(SubtargetFeatures[Pred]->dump());
|
||||||
assert(FeatureNo < 64 && "Too many subtarget features!");
|
assert(FeatureNo < 64 && "Too many subtarget features!");
|
||||||
}
|
}
|
||||||
|
@ -1345,7 +1347,7 @@ void AsmMatcherInfo::buildInfo() {
|
||||||
if (!II->validate(CommentDelimiter, true))
|
if (!II->validate(CommentDelimiter, true))
|
||||||
continue;
|
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
|
// Parse all of the InstAlias definitions and stick them in the list of
|
||||||
|
@ -1370,7 +1372,7 @@ void AsmMatcherInfo::buildInfo() {
|
||||||
// Validate the alias definitions.
|
// Validate the alias definitions.
|
||||||
II->validate(CommentDelimiter, false);
|
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
|
// Build the information about matchables, now that we have fully formed
|
||||||
// classes.
|
// classes.
|
||||||
std::vector<MatchableInfo*> NewMatchables;
|
std::vector<std::unique_ptr<MatchableInfo>> NewMatchables;
|
||||||
for (MatchableInfo *II : Matchables) {
|
for (auto &II : Matchables) {
|
||||||
// Parse the tokens after the mnemonic.
|
// Parse the tokens after the mnemonic.
|
||||||
// Note: buildInstructionOperandReference may insert new AsmOperands, so
|
// Note: buildInstructionOperandReference may insert new AsmOperands, so
|
||||||
// don't precompute the loop bound.
|
// don't precompute the loop bound.
|
||||||
|
@ -1418,9 +1420,9 @@ void AsmMatcherInfo::buildInfo() {
|
||||||
OperandName = Token.substr(1);
|
OperandName = Token.substr(1);
|
||||||
|
|
||||||
if (II->DefRec.is<const CodeGenInstruction*>())
|
if (II->DefRec.is<const CodeGenInstruction*>())
|
||||||
buildInstructionOperandReference(II, OperandName, i);
|
buildInstructionOperandReference(II.get(), OperandName, i);
|
||||||
else
|
else
|
||||||
buildAliasOperandReference(II, OperandName, Op);
|
buildAliasOperandReference(II.get(), OperandName, Op);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (II->DefRec.is<const CodeGenInstruction*>()) {
|
if (II->DefRec.is<const CodeGenInstruction*>()) {
|
||||||
|
@ -1438,14 +1440,14 @@ void AsmMatcherInfo::buildInfo() {
|
||||||
AliasII->formTwoOperandAlias(Constraint);
|
AliasII->formTwoOperandAlias(Constraint);
|
||||||
|
|
||||||
// Add the alias to the matchables list.
|
// Add the alias to the matchables list.
|
||||||
NewMatchables.push_back(AliasII.release());
|
NewMatchables.push_back(std::move(AliasII));
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
II->buildAliasResultOperands();
|
II->buildAliasResultOperands();
|
||||||
}
|
}
|
||||||
if (!NewMatchables.empty())
|
if (!NewMatchables.empty())
|
||||||
Matchables.insert(Matchables.end(), NewMatchables.begin(),
|
std::move(NewMatchables.begin(), NewMatchables.end(),
|
||||||
NewMatchables.end());
|
std::back_inserter(Matchables));
|
||||||
|
|
||||||
// Process token alias definitions and set up the associated superclass
|
// Process token alias definitions and set up the associated superclass
|
||||||
// information.
|
// information.
|
||||||
|
@ -1462,7 +1464,10 @@ void AsmMatcherInfo::buildInfo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reorder classes so that classes precede super classes.
|
// 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
|
/// 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,
|
static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
|
||||||
std::vector<MatchableInfo*> &Infos,
|
std::vector<std::unique_ptr<MatchableInfo>> &Infos,
|
||||||
raw_ostream &OS) {
|
raw_ostream &OS) {
|
||||||
SetVector<std::string> OperandConversionKinds;
|
SetVector<std::string> OperandConversionKinds;
|
||||||
SetVector<std::string> InstructionConversionKinds;
|
SetVector<std::string> InstructionConversionKinds;
|
||||||
|
@ -1736,7 +1741,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
|
||||||
OperandConversionKinds.insert("CVT_Tied");
|
OperandConversionKinds.insert("CVT_Tied");
|
||||||
enum { CVT_Done, CVT_Reg, 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.
|
// Check if we have a custom match function.
|
||||||
std::string AsmMatchConverter =
|
std::string AsmMatchConverter =
|
||||||
II->getResultInst()->TheDef->getValueAsString("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.
|
/// emitMatchClassEnumeration - Emit the enumeration for match class kinds.
|
||||||
static void emitMatchClassEnumeration(CodeGenTarget &Target,
|
static void emitMatchClassEnumeration(CodeGenTarget &Target,
|
||||||
std::vector<ClassInfo*> &Infos,
|
std::vector<std::unique_ptr<ClassInfo>> &Infos,
|
||||||
raw_ostream &OS) {
|
raw_ostream &OS) {
|
||||||
OS << "namespace {\n\n";
|
OS << "namespace {\n\n";
|
||||||
|
|
||||||
OS << "/// MatchClassKind - The kinds of classes which participate in\n"
|
OS << "/// MatchClassKind - The kinds of classes which participate in\n"
|
||||||
<< "/// instruction matching.\n";
|
<< "/// instruction matching.\n";
|
||||||
OS << "enum MatchClassKind {\n";
|
OS << "enum MatchClassKind {\n";
|
||||||
OS << " InvalidMatchClass = 0,\n";
|
OS << " InvalidMatchClass = 0,\n";
|
||||||
for (const ClassInfo *CI : Infos) {
|
for (const auto &CI : Infos) {
|
||||||
OS << " " << CI->Name << ", // ";
|
OS << " " << CI->Name << ", // ";
|
||||||
if (CI->Kind == ClassInfo::Token) {
|
if (CI->Kind == ClassInfo::Token) {
|
||||||
OS << "'" << CI->ValueName << "'\n";
|
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
|
// Check the user classes. We don't care what order since we're only
|
||||||
// actually matching against one of them.
|
// actually matching against one of them.
|
||||||
for (const ClassInfo *CI : Info.Classes) {
|
for (const auto &CI : Info.Classes) {
|
||||||
if (!CI->isUserClass())
|
if (!CI->isUserClass())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -2054,7 +2059,7 @@ static void emitValidateOperandClass(AsmMatcherInfo &Info,
|
||||||
|
|
||||||
/// emitIsSubclass - Emit the subclass predicate function.
|
/// emitIsSubclass - Emit the subclass predicate function.
|
||||||
static void emitIsSubclass(CodeGenTarget &Target,
|
static void emitIsSubclass(CodeGenTarget &Target,
|
||||||
std::vector<ClassInfo*> &Infos,
|
std::vector<std::unique_ptr<ClassInfo>> &Infos,
|
||||||
raw_ostream &OS) {
|
raw_ostream &OS) {
|
||||||
OS << "/// isSubclass - Compute whether \\p A is a subclass of \\p B.\n";
|
OS << "/// isSubclass - Compute whether \\p A is a subclass of \\p B.\n";
|
||||||
OS << "static bool isSubclass(MatchClassKind A, MatchClassKind 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 << " switch (A) {\n";
|
||||||
SS << " default:\n";
|
SS << " default:\n";
|
||||||
SS << " return false;\n";
|
SS << " return false;\n";
|
||||||
for (const ClassInfo *A : Infos) {
|
for (const auto &A : Infos) {
|
||||||
std::vector<StringRef> SuperClasses;
|
std::vector<StringRef> SuperClasses;
|
||||||
for (const ClassInfo *B : Infos) {
|
for (const auto &B : Infos) {
|
||||||
if (A != B && A->isSubsetOf(*B))
|
if (A != B && A->isSubsetOf(*B))
|
||||||
SuperClasses.push_back(B->Name);
|
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
|
/// emitMatchTokenString - Emit the function to match a token string to the
|
||||||
/// appropriate match class value.
|
/// appropriate match class value.
|
||||||
static void emitMatchTokenString(CodeGenTarget &Target,
|
static void emitMatchTokenString(CodeGenTarget &Target,
|
||||||
std::vector<ClassInfo*> &Infos,
|
std::vector<std::unique_ptr<ClassInfo>> &Infos,
|
||||||
raw_ostream &OS) {
|
raw_ostream &OS) {
|
||||||
// Construct the match list.
|
// Construct the match list.
|
||||||
std::vector<StringMatcher::StringPair> Matches;
|
std::vector<StringMatcher::StringPair> Matches;
|
||||||
for (const ClassInfo *CI : Infos) {
|
for (const auto &CI : Infos) {
|
||||||
if (CI->Kind == ClassInfo::Token)
|
if (CI->Kind == ClassInfo::Token)
|
||||||
Matches.push_back(StringMatcher::StringPair(CI->ValueName,
|
Matches.push_back(StringMatcher::StringPair(CI->ValueName,
|
||||||
"return " + CI->Name + ";"));
|
"return " + CI->Name + ";"));
|
||||||
|
@ -2511,7 +2516,7 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
|
||||||
<< " &Operands,\n unsigned MCK) {\n\n"
|
<< " &Operands,\n unsigned MCK) {\n\n"
|
||||||
<< " switch(MCK) {\n";
|
<< " switch(MCK) {\n";
|
||||||
|
|
||||||
for (const ClassInfo *CI : Info.Classes) {
|
for (const auto &CI : Info.Classes) {
|
||||||
if (CI->ParserMethod.empty())
|
if (CI->ParserMethod.empty())
|
||||||
continue;
|
continue;
|
||||||
OS << " case " << CI->Name << ":\n"
|
OS << " case " << CI->Name << ":\n"
|
||||||
|
@ -2594,10 +2599,12 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||||
// stable_sort to ensure that ambiguous instructions are still
|
// stable_sort to ensure that ambiguous instructions are still
|
||||||
// deterministically ordered.
|
// deterministically ordered.
|
||||||
std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(),
|
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", {
|
DEBUG_WITH_TYPE("instruction_info", {
|
||||||
for (const MatchableInfo *MI : Info.Matchables)
|
for (const auto &MI : Info.Matchables)
|
||||||
MI->dump();
|
MI->dump();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2727,7 +2734,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||||
size_t MaxNumOperands = 0;
|
size_t MaxNumOperands = 0;
|
||||||
unsigned MaxMnemonicIndex = 0;
|
unsigned MaxMnemonicIndex = 0;
|
||||||
bool HasDeprecation = false;
|
bool HasDeprecation = false;
|
||||||
for (const MatchableInfo *MI : Info.Matchables) {
|
for (const auto &MI : Info.Matchables) {
|
||||||
MaxNumOperands = std::max(MaxNumOperands, MI->AsmOperands.size());
|
MaxNumOperands = std::max(MaxNumOperands, MI->AsmOperands.size());
|
||||||
HasDeprecation |= MI->HasDeprecation;
|
HasDeprecation |= MI->HasDeprecation;
|
||||||
|
|
||||||
|
@ -2790,7 +2797,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||||
|
|
||||||
OS << "static const MatchEntry MatchTable" << VC << "[] = {\n";
|
OS << "static const MatchEntry MatchTable" << VC << "[] = {\n";
|
||||||
|
|
||||||
for (const MatchableInfo *MI : Info.Matchables) {
|
for (const auto &MI : Info.Matchables) {
|
||||||
if (MI->AsmVariantID != AsmVariantNo)
|
if (MI->AsmVariantID != AsmVariantNo)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue