mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-25 23:00:15 +00:00
Keep track of canonical decls in Redeclarable.
More than 2x speedup on modules builds with large redecl chains. Roughly 15-20% speedup on non-modules builds for very large TUs. Between 2-3% cost in memory on large TUs. llvm-svn: 233228
This commit is contained in:
parent
70c1665d83
commit
093b2d48b4
@ -3738,8 +3738,6 @@ void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
|
||||
assert(RedeclLink.NextIsLatest() &&
|
||||
"setPreviousDecl on a decl already in a redeclaration chain");
|
||||
|
||||
decl_type *First;
|
||||
|
||||
if (PrevDecl) {
|
||||
// Point to previous. Make sure that this is actually the most recent
|
||||
// redeclaration, or we can build invalid chains. If the most recent
|
||||
|
@ -121,14 +121,15 @@ protected:
|
||||
///
|
||||
/// If there is only one declaration, it is <pointer to self, true>
|
||||
DeclLink RedeclLink;
|
||||
decl_type *First;
|
||||
|
||||
decl_type *getNextRedeclaration() const {
|
||||
return RedeclLink.getNext(static_cast<const decl_type *>(this));
|
||||
}
|
||||
|
||||
public:
|
||||
Redeclarable(const ASTContext &Ctx)
|
||||
: RedeclLink(LatestDeclLink(Ctx)) {}
|
||||
Redeclarable(const ASTContext &Ctx)
|
||||
: RedeclLink(LatestDeclLink(Ctx)), First(static_cast<decl_type *>(this)) {}
|
||||
|
||||
/// \brief Return the previous declaration of this declaration or NULL if this
|
||||
/// is the first declaration.
|
||||
@ -144,21 +145,11 @@ public:
|
||||
|
||||
/// \brief Return the first declaration of this declaration or itself if this
|
||||
/// is the only declaration.
|
||||
decl_type *getFirstDecl() {
|
||||
decl_type *D = static_cast<decl_type*>(this);
|
||||
while (D->getPreviousDecl())
|
||||
D = D->getPreviousDecl();
|
||||
return D;
|
||||
}
|
||||
decl_type *getFirstDecl() { return First; }
|
||||
|
||||
/// \brief Return the first declaration of this declaration or itself if this
|
||||
/// is the only declaration.
|
||||
const decl_type *getFirstDecl() const {
|
||||
const decl_type *D = static_cast<const decl_type*>(this);
|
||||
while (D->getPreviousDecl())
|
||||
D = D->getPreviousDecl();
|
||||
return D;
|
||||
}
|
||||
const decl_type *getFirstDecl() const { return First; }
|
||||
|
||||
/// \brief True if this is the first declaration in its redeclaration chain.
|
||||
bool isFirstDecl() const { return RedeclLink.NextIsLatest(); }
|
||||
|
@ -2106,6 +2106,7 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
|
||||
// which is the one that matters and mark the real previous DeclID to be
|
||||
// loaded & attached later on.
|
||||
D->RedeclLink = Redeclarable<T>::PreviousDeclLink(FirstDecl);
|
||||
D->First = FirstDecl->getCanonicalDecl();
|
||||
}
|
||||
|
||||
// Note that this declaration has been deserialized.
|
||||
@ -2209,6 +2210,7 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing,
|
||||
// of the existing declaration, so that this declaration has the
|
||||
// appropriate canonical declaration.
|
||||
D->RedeclLink = Redeclarable<T>::PreviousDeclLink(ExistingCanon);
|
||||
D->First = ExistingCanon;
|
||||
|
||||
// When we merge a namespace, update its pointer to the first namespace.
|
||||
// We cannot have loaded any redeclarations of this declaration yet, so
|
||||
@ -2828,6 +2830,7 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
|
||||
Redeclarable<DeclT> *D,
|
||||
Decl *Previous, Decl *Canon) {
|
||||
D->RedeclLink.setPrevious(cast<DeclT>(Previous));
|
||||
D->First = cast<DeclT>(Previous)->First;
|
||||
}
|
||||
namespace clang {
|
||||
template<>
|
||||
@ -2838,6 +2841,7 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
|
||||
FunctionDecl *PrevFD = cast<FunctionDecl>(Previous);
|
||||
|
||||
FD->RedeclLink.setPrevious(PrevFD);
|
||||
FD->First = PrevFD->First;
|
||||
|
||||
// If the previous declaration is an inline function declaration, then this
|
||||
// declaration is too.
|
||||
|
Loading…
Reference in New Issue
Block a user