[TableGen] Only store direct superclasses in Record (#123072)
In Record only store the direct superclasses instead of all superclasses. getSuperClasses recurses to find all superclasses when necessary. This gives a small reduction in memory usage. On lib/Target/X86/X86.td I measured about 2.0% reduction in total bytes allocated (measured by valgrind) and 1.3% reduction in peak memory usage (measured by /usr/bin/time -v). --------- Co-authored-by: Min-Yih Hsu <min@myhsu.dev>
This commit is contained in:
parent
6e3b16bec3
commit
2bc6f9d4b6
@ -1526,7 +1526,8 @@ createArgument(const Record &Arg, StringRef Attr,
|
|||||||
|
|
||||||
if (!Ptr) {
|
if (!Ptr) {
|
||||||
// Search in reverse order so that the most-derived type is handled first.
|
// Search in reverse order so that the most-derived type is handled first.
|
||||||
for (const auto &[Base, _] : reverse(Search->getSuperClasses())) {
|
std::vector<const Record *> SCs = Search->getSuperClasses();
|
||||||
|
for (const Record *Base : reverse(SCs)) {
|
||||||
if ((Ptr = createArgument(Arg, Attr, Base)))
|
if ((Ptr = createArgument(Arg, Attr, Base)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1856,17 +1857,16 @@ static LateAttrParseKind getLateAttrParseKind(const Record *Attr) {
|
|||||||
auto *LAPK = Attr->getValueAsDef(LateParsedStr);
|
auto *LAPK = Attr->getValueAsDef(LateParsedStr);
|
||||||
|
|
||||||
// Typecheck the `LateParsed` field.
|
// Typecheck the `LateParsed` field.
|
||||||
SmallVector<const Record *, 1> SuperClasses;
|
if (LAPK->getDirectSuperClasses().size() != 1)
|
||||||
LAPK->getDirectSuperClasses(SuperClasses);
|
|
||||||
if (SuperClasses.size() != 1)
|
|
||||||
PrintFatalError(Attr, "Field `" + Twine(LateParsedStr) +
|
PrintFatalError(Attr, "Field `" + Twine(LateParsedStr) +
|
||||||
"`should only have one super class");
|
"`should only have one super class");
|
||||||
|
|
||||||
if (SuperClasses[0]->getName() != LateAttrParseKindStr)
|
const Record *SuperClass = LAPK->getDirectSuperClasses()[0].first;
|
||||||
|
if (SuperClass->getName() != LateAttrParseKindStr)
|
||||||
PrintFatalError(
|
PrintFatalError(
|
||||||
Attr, "Field `" + Twine(LateParsedStr) + "`should only have type `" +
|
Attr, "Field `" + Twine(LateParsedStr) + "`should only have type `" +
|
||||||
Twine(LateAttrParseKindStr) + "` but found type `" +
|
Twine(LateAttrParseKindStr) + "` but found type `" +
|
||||||
SuperClasses[0]->getName() + "`");
|
SuperClass->getName() + "`");
|
||||||
|
|
||||||
// Get Kind and verify the enum name matches the name in `Attr.td`.
|
// Get Kind and verify the enum name matches the name in `Attr.td`.
|
||||||
unsigned Kind = LAPK->getValueAsInt(KindFieldStr);
|
unsigned Kind = LAPK->getValueAsInt(KindFieldStr);
|
||||||
@ -2465,8 +2465,8 @@ static void emitStringSwitchCases(std::map<StringRef, FSIVecTy> &Map,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool isTypeArgument(const Record *Arg) {
|
static bool isTypeArgument(const Record *Arg) {
|
||||||
return !Arg->getSuperClasses().empty() &&
|
return !Arg->getDirectSuperClasses().empty() &&
|
||||||
Arg->getSuperClasses().back().first->getName() == "TypeArgument";
|
Arg->getDirectSuperClasses().back().first->getName() == "TypeArgument";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emits the first-argument-is-type property for attributes.
|
/// Emits the first-argument-is-type property for attributes.
|
||||||
@ -2507,8 +2507,9 @@ static void emitClangAttrArgContextList(const RecordKeeper &Records,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool isIdentifierArgument(const Record *Arg) {
|
static bool isIdentifierArgument(const Record *Arg) {
|
||||||
return !Arg->getSuperClasses().empty() &&
|
return !Arg->getDirectSuperClasses().empty() &&
|
||||||
StringSwitch<bool>(Arg->getSuperClasses().back().first->getName())
|
StringSwitch<bool>(
|
||||||
|
Arg->getDirectSuperClasses().back().first->getName())
|
||||||
.Case("IdentifierArgument", true)
|
.Case("IdentifierArgument", true)
|
||||||
.Case("EnumArgument", true)
|
.Case("EnumArgument", true)
|
||||||
.Case("VariadicEnumArgument", true)
|
.Case("VariadicEnumArgument", true)
|
||||||
@ -2516,33 +2517,35 @@ static bool isIdentifierArgument(const Record *Arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool isVariadicIdentifierArgument(const Record *Arg) {
|
static bool isVariadicIdentifierArgument(const Record *Arg) {
|
||||||
return !Arg->getSuperClasses().empty() &&
|
return !Arg->getDirectSuperClasses().empty() &&
|
||||||
StringSwitch<bool>(Arg->getSuperClasses().back().first->getName())
|
StringSwitch<bool>(
|
||||||
|
Arg->getDirectSuperClasses().back().first->getName())
|
||||||
.Case("VariadicIdentifierArgument", true)
|
.Case("VariadicIdentifierArgument", true)
|
||||||
.Case("VariadicParamOrParamIdxArgument", true)
|
.Case("VariadicParamOrParamIdxArgument", true)
|
||||||
.Default(false);
|
.Default(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isVariadicExprArgument(const Record *Arg) {
|
static bool isVariadicExprArgument(const Record *Arg) {
|
||||||
return !Arg->getSuperClasses().empty() &&
|
return !Arg->getDirectSuperClasses().empty() &&
|
||||||
StringSwitch<bool>(Arg->getSuperClasses().back().first->getName())
|
StringSwitch<bool>(
|
||||||
|
Arg->getDirectSuperClasses().back().first->getName())
|
||||||
.Case("VariadicExprArgument", true)
|
.Case("VariadicExprArgument", true)
|
||||||
.Default(false);
|
.Default(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isStringLiteralArgument(const Record *Arg) {
|
static bool isStringLiteralArgument(const Record *Arg) {
|
||||||
if (Arg->getSuperClasses().empty())
|
if (Arg->getDirectSuperClasses().empty())
|
||||||
return false;
|
return false;
|
||||||
StringRef ArgKind = Arg->getSuperClasses().back().first->getName();
|
StringRef ArgKind = Arg->getDirectSuperClasses().back().first->getName();
|
||||||
if (ArgKind == "EnumArgument")
|
if (ArgKind == "EnumArgument")
|
||||||
return Arg->getValueAsBit("IsString");
|
return Arg->getValueAsBit("IsString");
|
||||||
return ArgKind == "StringArgument";
|
return ArgKind == "StringArgument";
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isVariadicStringLiteralArgument(const Record *Arg) {
|
static bool isVariadicStringLiteralArgument(const Record *Arg) {
|
||||||
if (Arg->getSuperClasses().empty())
|
if (Arg->getDirectSuperClasses().empty())
|
||||||
return false;
|
return false;
|
||||||
StringRef ArgKind = Arg->getSuperClasses().back().first->getName();
|
StringRef ArgKind = Arg->getDirectSuperClasses().back().first->getName();
|
||||||
if (ArgKind == "VariadicEnumArgument")
|
if (ArgKind == "VariadicEnumArgument")
|
||||||
return Arg->getValueAsBit("IsString");
|
return Arg->getValueAsBit("IsString");
|
||||||
return ArgKind == "VariadicStringArgument";
|
return ArgKind == "VariadicStringArgument";
|
||||||
@ -2631,8 +2634,9 @@ static void emitClangAttrStrictIdentifierArgList(const RecordKeeper &Records,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool keywordThisIsaIdentifierInArgument(const Record *Arg) {
|
static bool keywordThisIsaIdentifierInArgument(const Record *Arg) {
|
||||||
return !Arg->getSuperClasses().empty() &&
|
return !Arg->getDirectSuperClasses().empty() &&
|
||||||
StringSwitch<bool>(Arg->getSuperClasses().back().first->getName())
|
StringSwitch<bool>(
|
||||||
|
Arg->getDirectSuperClasses().back().first->getName())
|
||||||
.Case("VariadicParamOrParamIdxArgument", true)
|
.Case("VariadicParamOrParamIdxArgument", true)
|
||||||
.Default(false);
|
.Default(false);
|
||||||
}
|
}
|
||||||
@ -2718,11 +2722,11 @@ static void emitAttributes(const RecordKeeper &Records, raw_ostream &OS,
|
|||||||
if (!R.getValueAsBit("ASTNode"))
|
if (!R.getValueAsBit("ASTNode"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ArrayRef<std::pair<const Record *, SMRange>> Supers = R.getSuperClasses();
|
std::vector<const Record *> Supers = R.getSuperClasses();
|
||||||
assert(!Supers.empty() && "Forgot to specify a superclass for the attr");
|
assert(!Supers.empty() && "Forgot to specify a superclass for the attr");
|
||||||
std::string SuperName;
|
std::string SuperName;
|
||||||
bool Inheritable = false;
|
bool Inheritable = false;
|
||||||
for (const auto &[R, _] : reverse(Supers)) {
|
for (const Record *R : reverse(Supers)) {
|
||||||
if (R->getName() != "TargetSpecificAttr" &&
|
if (R->getName() != "TargetSpecificAttr" &&
|
||||||
R->getName() != "DeclOrTypeAttr" && SuperName.empty())
|
R->getName() != "DeclOrTypeAttr" && SuperName.empty())
|
||||||
SuperName = R->getName().str();
|
SuperName = R->getName().str();
|
||||||
@ -3419,10 +3423,10 @@ namespace {
|
|||||||
AttrClass *findSuperClass(const Record *R) const {
|
AttrClass *findSuperClass(const Record *R) const {
|
||||||
// TableGen flattens the superclass list, so we just need to walk it
|
// TableGen flattens the superclass list, so we just need to walk it
|
||||||
// in reverse.
|
// in reverse.
|
||||||
auto SuperClasses = R->getSuperClasses();
|
std::vector<const Record *> SuperClasses = R->getSuperClasses();
|
||||||
for (signed i = 0, e = SuperClasses.size(); i != e; ++i) {
|
for (const Record *R : reverse(SuperClasses)) {
|
||||||
auto SuperClass = findClassByRecord(SuperClasses[e - i - 1].first);
|
if (AttrClass *SuperClass = findClassByRecord(R))
|
||||||
if (SuperClass) return SuperClass;
|
return SuperClass;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -4661,8 +4665,9 @@ static void GenerateHandleDeclAttribute(const Record &Attr, raw_ostream &OS) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool isParamExpr(const Record *Arg) {
|
static bool isParamExpr(const Record *Arg) {
|
||||||
return !Arg->getSuperClasses().empty() &&
|
return !Arg->getDirectSuperClasses().empty() &&
|
||||||
StringSwitch<bool>(Arg->getSuperClasses().back().first->getName())
|
StringSwitch<bool>(
|
||||||
|
Arg->getDirectSuperClasses().back().first->getName())
|
||||||
.Case("ExprArgument", true)
|
.Case("ExprArgument", true)
|
||||||
.Case("VariadicExprArgument", true)
|
.Case("VariadicExprArgument", true)
|
||||||
.Default(false);
|
.Default(false);
|
||||||
@ -4785,7 +4790,7 @@ void EmitClangAttrParsedAttrImpl(const RecordKeeper &Records, raw_ostream &OS) {
|
|||||||
if (Arg->getValueAsBitOrUnset("Fake", UnusedUnset))
|
if (Arg->getValueAsBitOrUnset("Fake", UnusedUnset))
|
||||||
continue;
|
continue;
|
||||||
ArgNames.push_back(Arg->getValueAsString("Name").str());
|
ArgNames.push_back(Arg->getValueAsString("Name").str());
|
||||||
for (const auto &[Class, _] : Arg->getSuperClasses()) {
|
for (const Record *Class : Arg->getSuperClasses()) {
|
||||||
if (Class->getName().starts_with("Variadic")) {
|
if (Class->getName().starts_with("Variadic")) {
|
||||||
ArgNames.back().append("...");
|
ArgNames.back().append("...");
|
||||||
break;
|
break;
|
||||||
|
@ -2029,8 +2029,8 @@ void NeonEmitter::createIntrinsic(const Record *R,
|
|||||||
std::vector<TypeSpec> TypeSpecs = TypeSpec::fromTypeSpecs(Types);
|
std::vector<TypeSpec> TypeSpecs = TypeSpec::fromTypeSpecs(Types);
|
||||||
|
|
||||||
ClassKind CK = ClassNone;
|
ClassKind CK = ClassNone;
|
||||||
if (R->getSuperClasses().size() >= 2)
|
if (!R->getDirectSuperClasses().empty())
|
||||||
CK = ClassMap[R->getSuperClasses()[1].first];
|
CK = ClassMap[R->getDirectSuperClasses()[0].first];
|
||||||
|
|
||||||
std::vector<std::pair<TypeSpec, TypeSpec>> NewTypeSpecs;
|
std::vector<std::pair<TypeSpec, TypeSpec>> NewTypeSpecs;
|
||||||
if (!CartesianProductWith.empty()) {
|
if (!CartesianProductWith.empty()) {
|
||||||
|
@ -610,29 +610,28 @@ functions returns null.
|
|||||||
Getting Record Superclasses
|
Getting Record Superclasses
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
The ``Record`` class provides a function to obtain the superclasses of a
|
The ``Record`` class provides a function to obtain the direct superclasses
|
||||||
record. It is named ``getSuperClasses`` and returns an ``ArrayRef`` of an
|
of a record. It is named ``getDirectSuperClasses`` and returns an
|
||||||
array of ``std::pair`` pairs. The superclasses are in post-order: the order
|
``ArrayRef`` of an array of ``std::pair`` pairs. Each pair consists of a
|
||||||
in which the superclasses were visited while copying their fields into the
|
pointer to the ``Record`` instance for a superclass record and an instance
|
||||||
record. Each pair consists of a pointer to the ``Record`` instance for a
|
of the ``SMRange`` class. The range indicates the source file locations of
|
||||||
superclass record and an instance of the ``SMRange`` class. The range
|
the beginning and end of the class definition.
|
||||||
indicates the source file locations of the beginning and end of the class
|
|
||||||
definition.
|
|
||||||
|
|
||||||
This example obtains the superclasses of the ``Prototype`` record and then
|
This example obtains the direct superclasses of the ``Prototype`` record and
|
||||||
iterates over the pairs in the returned array.
|
then iterates over the pairs in the returned array.
|
||||||
|
|
||||||
.. code-block:: text
|
.. code-block:: text
|
||||||
|
|
||||||
ArrayRef<std::pair<const Record *, SMRange>>
|
ArrayRef<std::pair<const Record *, SMRange>>
|
||||||
Superclasses = Prototype->getSuperClasses();
|
Superclasses = Prototype->getDirectSuperClasses();
|
||||||
for (const auto &SuperPair : Superclasses) {
|
for (const auto &[Super, Range] : Superclasses) {
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
The ``Record`` class also provides a function, ``getDirectSuperClasses``, to
|
The ``Record`` class also provides a function, ``getSuperClasses``, to
|
||||||
append the *direct* superclasses of a record to a given vector of type
|
return a vector of *all* superclasses of a record. The superclasses are in
|
||||||
``SmallVectorImpl<Record *>``.
|
post-order: the order in which the superclasses were visited while copying
|
||||||
|
their fields into the record.
|
||||||
|
|
||||||
Emitting Text to the Output Stream
|
Emitting Text to the Output Stream
|
||||||
==================================
|
==================================
|
||||||
|
@ -1667,9 +1667,9 @@ private:
|
|||||||
SmallVector<AssertionInfo, 0> Assertions;
|
SmallVector<AssertionInfo, 0> Assertions;
|
||||||
SmallVector<DumpInfo, 0> Dumps;
|
SmallVector<DumpInfo, 0> Dumps;
|
||||||
|
|
||||||
// All superclasses in the inheritance forest in post-order (yes, it
|
// Direct superclasses, which are roots of the inheritance forest (yes, it
|
||||||
// must be a forest; diamond-shaped inheritance is not allowed).
|
// must be a forest; diamond-shaped inheritance is not allowed).
|
||||||
SmallVector<std::pair<const Record *, SMRange>, 0> SuperClasses;
|
SmallVector<std::pair<const Record *, SMRange>, 0> DirectSuperClasses;
|
||||||
|
|
||||||
// Tracks Record instances. Not owned by Record.
|
// Tracks Record instances. Not owned by Record.
|
||||||
RecordKeeper &TrackedRecords;
|
RecordKeeper &TrackedRecords;
|
||||||
@ -1703,8 +1703,9 @@ public:
|
|||||||
Record(const Record &O)
|
Record(const Record &O)
|
||||||
: Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs),
|
: Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs),
|
||||||
Values(O.Values), Assertions(O.Assertions),
|
Values(O.Values), Assertions(O.Assertions),
|
||||||
SuperClasses(O.SuperClasses), TrackedRecords(O.TrackedRecords),
|
DirectSuperClasses(O.DirectSuperClasses),
|
||||||
ID(getNewUID(O.getRecords())), Kind(O.Kind) {}
|
TrackedRecords(O.TrackedRecords), ID(getNewUID(O.getRecords())),
|
||||||
|
Kind(O.Kind) {}
|
||||||
|
|
||||||
static unsigned getNewUID(RecordKeeper &RK);
|
static unsigned getNewUID(RecordKeeper &RK);
|
||||||
|
|
||||||
@ -1755,15 +1756,30 @@ public:
|
|||||||
ArrayRef<AssertionInfo> getAssertions() const { return Assertions; }
|
ArrayRef<AssertionInfo> getAssertions() const { return Assertions; }
|
||||||
ArrayRef<DumpInfo> getDumps() const { return Dumps; }
|
ArrayRef<DumpInfo> getDumps() const { return Dumps; }
|
||||||
|
|
||||||
ArrayRef<std::pair<const Record *, SMRange>> getSuperClasses() const {
|
/// Append all superclasses in post-order to \p Classes.
|
||||||
return SuperClasses;
|
void getSuperClasses(std::vector<const Record *> &Classes) const {
|
||||||
|
for (const Record *SC : make_first_range(DirectSuperClasses)) {
|
||||||
|
SC->getSuperClasses(Classes);
|
||||||
|
Classes.push_back(SC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return all superclasses in post-order.
|
||||||
|
std::vector<const Record *> getSuperClasses() const {
|
||||||
|
std::vector<const Record *> Classes;
|
||||||
|
getSuperClasses(Classes);
|
||||||
|
return Classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determine whether this record has the specified direct superclass.
|
/// Determine whether this record has the specified direct superclass.
|
||||||
bool hasDirectSuperClass(const Record *SuperClass) const;
|
bool hasDirectSuperClass(const Record *SuperClass) const {
|
||||||
|
return is_contained(make_first_range(DirectSuperClasses), SuperClass);
|
||||||
|
}
|
||||||
|
|
||||||
/// Append the direct superclasses of this record to Classes.
|
/// Return the direct superclasses of this record.
|
||||||
void getDirectSuperClasses(SmallVectorImpl<const Record *> &Classes) const;
|
ArrayRef<std::pair<const Record *, SMRange>> getDirectSuperClasses() const {
|
||||||
|
return DirectSuperClasses;
|
||||||
|
}
|
||||||
|
|
||||||
bool isTemplateArg(const Init *Name) const {
|
bool isTemplateArg(const Init *Name) const {
|
||||||
return llvm::is_contained(TemplateArgs, Name);
|
return llvm::is_contained(TemplateArgs, Name);
|
||||||
@ -1831,29 +1847,32 @@ public:
|
|||||||
void checkUnusedTemplateArgs();
|
void checkUnusedTemplateArgs();
|
||||||
|
|
||||||
bool isSubClassOf(const Record *R) const {
|
bool isSubClassOf(const Record *R) const {
|
||||||
for (const auto &[SC, _] : SuperClasses)
|
for (const Record *SC : make_first_range(DirectSuperClasses)) {
|
||||||
if (SC == R)
|
if (SC == R || SC->isSubClassOf(R))
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSubClassOf(StringRef Name) const {
|
bool isSubClassOf(StringRef Name) const {
|
||||||
for (const auto &[SC, _] : SuperClasses) {
|
for (const Record *SC : make_first_range(DirectSuperClasses)) {
|
||||||
if (const auto *SI = dyn_cast<StringInit>(SC->getNameInit())) {
|
if (const auto *SI = dyn_cast<StringInit>(SC->getNameInit())) {
|
||||||
if (SI->getValue() == Name)
|
if (SI->getValue() == Name)
|
||||||
return true;
|
return true;
|
||||||
} else if (SC->getNameInitAsString() == Name) {
|
} else if (SC->getNameInitAsString() == Name) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (SC->isSubClassOf(Name))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addSuperClass(const Record *R, SMRange Range) {
|
void addDirectSuperClass(const Record *R, SMRange Range) {
|
||||||
assert(!CorrespondingDefInit &&
|
assert(!CorrespondingDefInit &&
|
||||||
"changing type of record after it has been referenced");
|
"changing type of record after it has been referenced");
|
||||||
assert(!isSubClassOf(R) && "Already subclassing record!");
|
assert(!isSubClassOf(R) && "Already subclassing record!");
|
||||||
SuperClasses.emplace_back(R, Range);
|
DirectSuperClasses.emplace_back(R, Range);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If there are any field references that refer to fields that have been
|
/// If there are any field references that refer to fields that have been
|
||||||
|
@ -152,15 +152,14 @@ void DetailedRecordsEmitter::printTemplateArgs(const Record &Rec,
|
|||||||
// are enclosed in parentheses.
|
// are enclosed in parentheses.
|
||||||
void DetailedRecordsEmitter::printSuperclasses(const Record &Rec,
|
void DetailedRecordsEmitter::printSuperclasses(const Record &Rec,
|
||||||
raw_ostream &OS) {
|
raw_ostream &OS) {
|
||||||
ArrayRef<std::pair<const Record *, SMRange>> Superclasses =
|
std::vector<const Record *> Superclasses = Rec.getSuperClasses();
|
||||||
Rec.getSuperClasses();
|
|
||||||
if (Superclasses.empty()) {
|
if (Superclasses.empty()) {
|
||||||
OS << " Superclasses: (none)\n";
|
OS << " Superclasses: (none)\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OS << " Superclasses:";
|
OS << " Superclasses:";
|
||||||
for (const auto &[ClassRec, Loc] : Superclasses) {
|
for (const Record *ClassRec : Superclasses) {
|
||||||
if (Rec.hasDirectSuperClass(ClassRec))
|
if (Rec.hasDirectSuperClass(ClassRec))
|
||||||
OS << formatv(" {0}", ClassRec->getNameInitAsString());
|
OS << formatv(" {0}", ClassRec->getNameInitAsString());
|
||||||
else
|
else
|
||||||
|
@ -151,7 +151,7 @@ void JSONEmitter::run(raw_ostream &OS) {
|
|||||||
|
|
||||||
json::Array SuperClasses;
|
json::Array SuperClasses;
|
||||||
// Add this def to the instance list for each of its superclasses.
|
// Add this def to the instance list for each of its superclasses.
|
||||||
for (const auto &[SuperClass, Loc] : Def->getSuperClasses()) {
|
for (const Record *SuperClass : Def->getSuperClasses()) {
|
||||||
std::string SuperName = SuperClass->getNameInitAsString();
|
std::string SuperName = SuperClass->getNameInitAsString();
|
||||||
SuperClasses.push_back(SuperName);
|
SuperClasses.push_back(SuperName);
|
||||||
InstanceLists[SuperName].push_back(Name);
|
InstanceLists[SuperName].push_back(Name);
|
||||||
|
@ -336,7 +336,7 @@ static const RecordRecTy *resolveRecordTypes(const RecordRecTy *T1,
|
|||||||
if (T2->isSubClassOf(R)) {
|
if (T2->isSubClassOf(R)) {
|
||||||
CommonSuperClasses.push_back(R);
|
CommonSuperClasses.push_back(R);
|
||||||
} else {
|
} else {
|
||||||
R->getDirectSuperClasses(Stack);
|
append_range(Stack, make_first_range(R->getDirectSuperClasses()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2482,11 +2482,8 @@ const DefInit *VarDefInit::instantiate() {
|
|||||||
|
|
||||||
NewRec->resolveReferences(R);
|
NewRec->resolveReferences(R);
|
||||||
|
|
||||||
// Add superclasses.
|
// Add superclass.
|
||||||
for (const auto &[SC, Loc] : Class->getSuperClasses())
|
NewRec->addDirectSuperClass(
|
||||||
NewRec->addSuperClass(SC, Loc);
|
|
||||||
|
|
||||||
NewRec->addSuperClass(
|
|
||||||
Class, SMRange(Class->getLoc().back(), Class->getLoc().back()));
|
Class, SMRange(Class->getLoc().back(), Class->getLoc().back()));
|
||||||
|
|
||||||
// Resolve internal references and store in record keeper
|
// Resolve internal references and store in record keeper
|
||||||
@ -2962,7 +2959,7 @@ void Record::checkName() {
|
|||||||
|
|
||||||
const RecordRecTy *Record::getType() const {
|
const RecordRecTy *Record::getType() const {
|
||||||
SmallVector<const Record *, 4> DirectSCs;
|
SmallVector<const Record *, 4> DirectSCs;
|
||||||
getDirectSuperClasses(DirectSCs);
|
append_range(DirectSCs, make_first_range(getDirectSuperClasses()));
|
||||||
return RecordRecTy::get(TrackedRecords, DirectSCs);
|
return RecordRecTy::get(TrackedRecords, DirectSCs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2994,35 +2991,6 @@ void Record::setName(const Init *NewName) {
|
|||||||
// this. See TGParser::ParseDef and TGParser::ParseDefm.
|
// this. See TGParser::ParseDef and TGParser::ParseDefm.
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE for the next two functions:
|
|
||||||
// Superclasses are in post-order, so the final one is a direct
|
|
||||||
// superclass. All of its transitive superclases immediately precede it,
|
|
||||||
// so we can step through the direct superclasses in reverse order.
|
|
||||||
|
|
||||||
bool Record::hasDirectSuperClass(const Record *Superclass) const {
|
|
||||||
ArrayRef<std::pair<const Record *, SMRange>> SCs = getSuperClasses();
|
|
||||||
|
|
||||||
for (int I = SCs.size() - 1; I >= 0; --I) {
|
|
||||||
const Record *SC = SCs[I].first;
|
|
||||||
if (SC == Superclass)
|
|
||||||
return true;
|
|
||||||
I -= SC->getSuperClasses().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Record::getDirectSuperClasses(
|
|
||||||
SmallVectorImpl<const Record *> &Classes) const {
|
|
||||||
ArrayRef<std::pair<const Record *, SMRange>> SCs = getSuperClasses();
|
|
||||||
|
|
||||||
while (!SCs.empty()) {
|
|
||||||
const Record *SC = SCs.back().first;
|
|
||||||
SCs = SCs.drop_back(1 + SC->getSuperClasses().size());
|
|
||||||
Classes.push_back(SC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Record::resolveReferences(Resolver &R, const RecordVal *SkipVal) {
|
void Record::resolveReferences(Resolver &R, const RecordVal *SkipVal) {
|
||||||
const Init *OldName = getNameInit();
|
const Init *OldName = getNameInit();
|
||||||
const Init *NewName = Name->resolveReferences(R);
|
const Init *NewName = Name->resolveReferences(R);
|
||||||
@ -3096,10 +3064,10 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
OS << " {";
|
OS << " {";
|
||||||
ArrayRef<std::pair<const Record *, SMRange>> SC = R.getSuperClasses();
|
std::vector<const Record *> SCs = R.getSuperClasses();
|
||||||
if (!SC.empty()) {
|
if (!SCs.empty()) {
|
||||||
OS << "\t//";
|
OS << "\t//";
|
||||||
for (const auto &[SC, _] : SC)
|
for (const Record *SC : SCs)
|
||||||
OS << " " << SC->getNameInitAsString();
|
OS << " " << SC->getNameInitAsString();
|
||||||
}
|
}
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
|
@ -312,7 +312,7 @@ const RecVec *SetTheory::expand(const Record *Set) {
|
|||||||
return &I->second;
|
return &I->second;
|
||||||
|
|
||||||
// This is the first time we see Set. Find a suitable expander.
|
// This is the first time we see Set. Find a suitable expander.
|
||||||
for (const auto &[SuperClass, Loc] : Set->getSuperClasses()) {
|
for (const Record *SuperClass : Set->getSuperClasses()) {
|
||||||
// Skip unnamed superclasses.
|
// Skip unnamed superclasses.
|
||||||
if (!isa<StringInit>(SuperClass->getNameInit()))
|
if (!isa<StringInit>(SuperClass->getNameInit()))
|
||||||
continue;
|
continue;
|
||||||
|
@ -332,17 +332,10 @@ bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
|
|||||||
|
|
||||||
// Since everything went well, we can now set the "superclass" list for the
|
// Since everything went well, we can now set the "superclass" list for the
|
||||||
// current record.
|
// current record.
|
||||||
for (const auto &[SC, Loc] : SC->getSuperClasses()) {
|
|
||||||
if (CurRec->isSubClassOf(SC))
|
|
||||||
return Error(SubClass.RefRange.Start,
|
|
||||||
"Already subclass of '" + SC->getName() + "'!\n");
|
|
||||||
CurRec->addSuperClass(SC, Loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CurRec->isSubClassOf(SC))
|
if (CurRec->isSubClassOf(SC))
|
||||||
return Error(SubClass.RefRange.Start,
|
return Error(SubClass.RefRange.Start,
|
||||||
"Already subclass of '" + SC->getName() + "'!\n");
|
"Already subclass of '" + SC->getName() + "'!\n");
|
||||||
CurRec->addSuperClass(SC, SubClass.RefRange);
|
CurRec->addDirectSuperClass(SC, SubClass.RefRange);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4056,7 +4049,7 @@ bool TGParser::ParseClass() {
|
|||||||
if (CurRec) {
|
if (CurRec) {
|
||||||
// If the body was previously defined, this is an error.
|
// If the body was previously defined, this is an error.
|
||||||
if (!CurRec->getValues().empty() ||
|
if (!CurRec->getValues().empty() ||
|
||||||
!CurRec->getSuperClasses().empty() ||
|
!CurRec->getDirectSuperClasses().empty() ||
|
||||||
!CurRec->getTemplateArgs().empty())
|
!CurRec->getTemplateArgs().empty())
|
||||||
return TokError("Class '" + CurRec->getNameInitAsString() +
|
return TokError("Class '" + CurRec->getNameInitAsString() +
|
||||||
"' already defined");
|
"' already defined");
|
||||||
|
@ -110,11 +110,10 @@ void CallingConvEmitter::emitCallingConv(const Record *CC, raw_ostream &O) {
|
|||||||
for (unsigned I = 0, E = CCActions->size(); I != E; ++I) {
|
for (unsigned I = 0, E = CCActions->size(); I != E; ++I) {
|
||||||
const Record *Action = CCActions->getElementAsRecord(I);
|
const Record *Action = CCActions->getElementAsRecord(I);
|
||||||
SwiftAction =
|
SwiftAction =
|
||||||
llvm::any_of(Action->getSuperClasses(),
|
llvm::any_of(Action->getSuperClasses(), [](const Record *Class) {
|
||||||
[](const std::pair<const Record *, SMRange> &Class) {
|
std::string Name = Class->getNameInitAsString();
|
||||||
std::string Name = Class.first->getNameInitAsString();
|
return StringRef(Name).starts_with("CCIfSwift");
|
||||||
return StringRef(Name).starts_with("CCIfSwift");
|
});
|
||||||
});
|
|
||||||
|
|
||||||
O << "\n";
|
O << "\n";
|
||||||
emitAction(Action, indent(2), O);
|
emitAction(Action, indent(2), O);
|
||||||
|
@ -704,8 +704,8 @@ struct TupleExpander : SetTheory::Expander {
|
|||||||
"Register tuple redefines register '" + Name + "'.");
|
"Register tuple redefines register '" + Name + "'.");
|
||||||
|
|
||||||
// Copy Proto super-classes.
|
// Copy Proto super-classes.
|
||||||
for (const auto &[Super, Loc] : Proto->getSuperClasses())
|
for (const auto &[Super, Loc] : Proto->getDirectSuperClasses())
|
||||||
NewReg->addSuperClass(Super, Loc);
|
NewReg->addDirectSuperClass(Super, Loc);
|
||||||
|
|
||||||
// Copy Proto fields.
|
// Copy Proto fields.
|
||||||
for (unsigned i = 0, e = Proto->getValues().size(); i != e; ++i) {
|
for (unsigned i = 0, e = Proto->getValues().size(); i != e; ++i) {
|
||||||
|
@ -834,7 +834,7 @@ void SearchableTableEmitter::run(raw_ostream &OS) {
|
|||||||
const Record *SearchableTable = Records.getClass("SearchableTable");
|
const Record *SearchableTable = Records.getClass("SearchableTable");
|
||||||
for (auto &NameRec : Records.getClasses()) {
|
for (auto &NameRec : Records.getClasses()) {
|
||||||
const Record *Class = NameRec.second.get();
|
const Record *Class = NameRec.second.get();
|
||||||
if (Class->getSuperClasses().size() != 1 ||
|
if (Class->getDirectSuperClasses().size() != 1 ||
|
||||||
!Class->isSubClassOf(SearchableTable))
|
!Class->isSubClassOf(SearchableTable))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ getBaseValue(const Record *record, const RecordVal *value) {
|
|||||||
// On success, `record` is updated to the new parent record.
|
// On success, `record` is updated to the new parent record.
|
||||||
StringRef valueName = value->getName();
|
StringRef valueName = value->getName();
|
||||||
auto findValueInSupers = [&](const Record *&record) -> const RecordVal * {
|
auto findValueInSupers = [&](const Record *&record) -> const RecordVal * {
|
||||||
for (auto [parentRecord, loc] : record->getSuperClasses()) {
|
for (const Record *parentRecord : record->getSuperClasses()) {
|
||||||
if (auto *newBase = parentRecord->getValue(valueName)) {
|
if (auto *newBase = parentRecord->getValue(valueName)) {
|
||||||
record = parentRecord;
|
record = parentRecord;
|
||||||
return newBase;
|
return newBase;
|
||||||
|
@ -72,11 +72,10 @@ static StringRef extractOmpClauseName(const Record *clause) {
|
|||||||
assert(ompClause && "base OpenMP records expected to be defined");
|
assert(ompClause && "base OpenMP records expected to be defined");
|
||||||
|
|
||||||
StringRef clauseClassName;
|
StringRef clauseClassName;
|
||||||
SmallVector<const Record *, 1> clauseSuperClasses;
|
|
||||||
clause->getDirectSuperClasses(clauseSuperClasses);
|
|
||||||
|
|
||||||
// Check if OpenMP_Clause is a direct superclass.
|
// Check if OpenMP_Clause is a direct superclass.
|
||||||
for (const Record *superClass : clauseSuperClasses) {
|
for (const Record *superClass :
|
||||||
|
llvm::make_first_range(clause->getDirectSuperClasses())) {
|
||||||
if (superClass == ompClause) {
|
if (superClass == ompClause) {
|
||||||
clauseClassName = clause->getName();
|
clauseClassName = clause->getName();
|
||||||
break;
|
break;
|
||||||
@ -85,7 +84,7 @@ static StringRef extractOmpClauseName(const Record *clause) {
|
|||||||
|
|
||||||
// Support indirectly-inherited OpenMP_Clauses.
|
// Support indirectly-inherited OpenMP_Clauses.
|
||||||
if (clauseClassName.empty()) {
|
if (clauseClassName.empty()) {
|
||||||
for (auto [superClass, _] : clause->getSuperClasses()) {
|
for (const Record *superClass : clause->getSuperClasses()) {
|
||||||
if (superClass->isSubClassOf(ompClause)) {
|
if (superClass->isSubClassOf(ompClause)) {
|
||||||
clauseClassName = superClass->getName();
|
clauseClassName = superClass->getName();
|
||||||
break;
|
break;
|
||||||
@ -214,7 +213,7 @@ static StringRef translateArgumentType(ArrayRef<SMLoc> loc,
|
|||||||
const Record *def = cast<DefInit>(init)->getDef();
|
const Record *def = cast<DefInit>(init)->getDef();
|
||||||
|
|
||||||
llvm::StringSet<> superClasses;
|
llvm::StringSet<> superClasses;
|
||||||
for (auto [sc, _] : def->getSuperClasses())
|
for (const Record *sc : def->getSuperClasses())
|
||||||
superClasses.insert(sc->getNameInitAsString());
|
superClasses.insert(sc->getNameInitAsString());
|
||||||
|
|
||||||
// Handle wrapper-style superclasses.
|
// Handle wrapper-style superclasses.
|
||||||
|
@ -115,13 +115,12 @@ Availability::Availability(const Record *def) : def(def) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StringRef Availability::getClass() const {
|
StringRef Availability::getClass() const {
|
||||||
SmallVector<const Record *, 1> parentClass;
|
if (def->getDirectSuperClasses().size() != 1) {
|
||||||
def->getDirectSuperClasses(parentClass);
|
|
||||||
if (parentClass.size() != 1) {
|
|
||||||
PrintFatalError(def->getLoc(),
|
PrintFatalError(def->getLoc(),
|
||||||
"expected to only have one direct superclass");
|
"expected to only have one direct superclass");
|
||||||
}
|
}
|
||||||
return parentClass.front()->getName();
|
const Record *parentClass = def->getDirectSuperClasses().front().first;
|
||||||
|
return parentClass->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef Availability::getInterfaceClassNamespace() const {
|
StringRef Availability::getInterfaceClassNamespace() const {
|
||||||
@ -205,18 +204,17 @@ static bool emitInterfaceDefs(const RecordKeeper &records, raw_ostream &os) {
|
|||||||
auto defs = records.getAllDerivedDefinitions("Availability");
|
auto defs = records.getAllDerivedDefinitions("Availability");
|
||||||
SmallVector<const Record *, 1> handledClasses;
|
SmallVector<const Record *, 1> handledClasses;
|
||||||
for (const Record *def : defs) {
|
for (const Record *def : defs) {
|
||||||
SmallVector<const Record *, 1> parent;
|
if (def->getDirectSuperClasses().size() != 1) {
|
||||||
def->getDirectSuperClasses(parent);
|
|
||||||
if (parent.size() != 1) {
|
|
||||||
PrintFatalError(def->getLoc(),
|
PrintFatalError(def->getLoc(),
|
||||||
"expected to only have one direct superclass");
|
"expected to only have one direct superclass");
|
||||||
}
|
}
|
||||||
if (llvm::is_contained(handledClasses, parent.front()))
|
const Record *parent = def->getDirectSuperClasses().front().first;
|
||||||
|
if (llvm::is_contained(handledClasses, parent))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Availability availability(def);
|
Availability availability(def);
|
||||||
emitInterfaceDef(availability, os);
|
emitInterfaceDef(availability, os);
|
||||||
handledClasses.push_back(parent.front());
|
handledClasses.push_back(parent);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -294,18 +292,17 @@ static bool emitInterfaceDecls(const RecordKeeper &records, raw_ostream &os) {
|
|||||||
auto defs = records.getAllDerivedDefinitions("Availability");
|
auto defs = records.getAllDerivedDefinitions("Availability");
|
||||||
SmallVector<const Record *, 4> handledClasses;
|
SmallVector<const Record *, 4> handledClasses;
|
||||||
for (const Record *def : defs) {
|
for (const Record *def : defs) {
|
||||||
SmallVector<const Record *, 1> parent;
|
if (def->getDirectSuperClasses().size() != 1) {
|
||||||
def->getDirectSuperClasses(parent);
|
|
||||||
if (parent.size() != 1) {
|
|
||||||
PrintFatalError(def->getLoc(),
|
PrintFatalError(def->getLoc(),
|
||||||
"expected to only have one direct superclass");
|
"expected to only have one direct superclass");
|
||||||
}
|
}
|
||||||
if (llvm::is_contained(handledClasses, parent.front()))
|
const Record *parent = def->getDirectSuperClasses().front().first;
|
||||||
|
if (llvm::is_contained(handledClasses, parent))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Availability avail(def);
|
Availability avail(def);
|
||||||
emitInterfaceDecl(avail, os);
|
emitInterfaceDecl(avail, os);
|
||||||
handledClasses.push_back(parent.front());
|
handledClasses.push_back(parent);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -100,13 +100,11 @@ Availability::Availability(const llvm::Record *def) : def(def) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StringRef Availability::getClass() const {
|
StringRef Availability::getClass() const {
|
||||||
SmallVector<const Record *, 1> parentClass;
|
if (def->getDirectSuperClasses().size() != 1) {
|
||||||
def->getDirectSuperClasses(parentClass);
|
|
||||||
if (parentClass.size() != 1) {
|
|
||||||
PrintFatalError(def->getLoc(),
|
PrintFatalError(def->getLoc(),
|
||||||
"expected to only have one direct superclass");
|
"expected to only have one direct superclass");
|
||||||
}
|
}
|
||||||
return parentClass.front()->getName();
|
return def->getDirectSuperClasses().front().first->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef Availability::getQueryFnRetType() const {
|
StringRef Availability::getQueryFnRetType() const {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user