2018-02-21 09:45:26 +08:00
|
|
|
//===- IdentifierResolver.cpp - Lexical Scope Name lookup -----------------===//
|
2008-04-11 15:06:57 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2008-04-12 09:50:47 +08:00
|
|
|
// This file implements the IdentifierResolver class, which is used for lexical
|
2008-11-18 04:34:05 +08:00
|
|
|
// scoped lookup, based on declaration names.
|
2008-04-11 15:06:57 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-08-13 04:07:10 +08:00
|
|
|
#include "clang/Sema/IdentifierResolver.h"
|
2010-08-24 15:21:54 +08:00
|
|
|
#include "clang/AST/Decl.h"
|
2018-02-21 09:45:26 +08:00
|
|
|
#include "clang/AST/DeclBase.h"
|
|
|
|
#include "clang/AST/DeclarationName.h"
|
|
|
|
#include "clang/Basic/IdentifierTable.h"
|
2008-09-10 05:57:58 +08:00
|
|
|
#include "clang/Basic/LangOptions.h"
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
#include "clang/Lex/ExternalPreprocessorSource.h"
|
|
|
|
#include "clang/Lex/Preprocessor.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/Sema/Scope.h"
|
2018-02-21 09:45:26 +08:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
#include <cassert>
|
|
|
|
#include <cstdint>
|
2008-04-11 15:06:57 +08:00
|
|
|
|
|
|
|
using namespace clang;
|
|
|
|
|
2008-09-10 03:28:27 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// IdDeclInfoMap class
|
|
|
|
//===----------------------------------------------------------------------===//
|
2008-04-11 15:06:57 +08:00
|
|
|
|
2008-11-18 04:34:05 +08:00
|
|
|
/// IdDeclInfoMap - Associates IdDeclInfos with declaration names.
|
2008-04-12 09:50:47 +08:00
|
|
|
/// Allocates 'pools' (vectors of IdDeclInfos) to avoid allocating each
|
2008-04-11 15:06:57 +08:00
|
|
|
/// individual IdDeclInfo to heap.
|
2008-05-10 07:39:43 +08:00
|
|
|
class IdentifierResolver::IdDeclInfoMap {
|
2010-02-16 03:38:00 +08:00
|
|
|
static const unsigned int POOL_SIZE = 512;
|
|
|
|
|
|
|
|
/// We use our own linked-list implementation because it is sadly
|
|
|
|
/// impossible to add something to a pre-C++0x STL container without
|
|
|
|
/// a completely unnecessary copy.
|
|
|
|
struct IdDeclInfoPool {
|
|
|
|
IdDeclInfoPool *Next;
|
|
|
|
IdDeclInfo Pool[POOL_SIZE];
|
2018-02-21 09:45:26 +08:00
|
|
|
|
|
|
|
IdDeclInfoPool(IdDeclInfoPool *Next) : Next(Next) {}
|
2010-02-16 03:38:00 +08:00
|
|
|
};
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2018-02-21 09:45:26 +08:00
|
|
|
IdDeclInfoPool *CurPool = nullptr;
|
|
|
|
unsigned int CurIndex = POOL_SIZE;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-04-11 15:06:57 +08:00
|
|
|
public:
|
2018-02-21 09:45:26 +08:00
|
|
|
IdDeclInfoMap() = default;
|
2010-02-16 03:38:00 +08:00
|
|
|
|
|
|
|
~IdDeclInfoMap() {
|
|
|
|
IdDeclInfoPool *Cur = CurPool;
|
|
|
|
while (IdDeclInfoPool *P = Cur) {
|
|
|
|
Cur = Cur->Next;
|
|
|
|
delete P;
|
|
|
|
}
|
|
|
|
}
|
2008-04-11 15:06:57 +08:00
|
|
|
|
2008-11-18 04:34:05 +08:00
|
|
|
/// Returns the IdDeclInfo associated to the DeclarationName.
|
2008-04-11 15:06:57 +08:00
|
|
|
/// It creates a new IdDeclInfo if one was not created before for this id.
|
2008-11-18 04:34:05 +08:00
|
|
|
IdDeclInfo &operator[](DeclarationName Name);
|
2008-04-11 15:06:57 +08:00
|
|
|
};
|
|
|
|
|
2008-09-10 03:28:27 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// IdDeclInfo Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// RemoveDecl - Remove the decl from the scope chain.
|
|
|
|
/// The decl must already be part of the decl chain.
|
|
|
|
void IdentifierResolver::IdDeclInfo::RemoveDecl(NamedDecl *D) {
|
|
|
|
for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
|
|
|
|
if (D == *(I-1)) {
|
|
|
|
Decls.erase(I-1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Didn't find this decl on its identifier's chain!");
|
2008-09-10 03:28:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// IdentifierResolver Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
IdentifierResolver::IdentifierResolver(Preprocessor &PP)
|
2018-02-21 09:45:26 +08:00
|
|
|
: LangOpt(PP.getLangOpts()), PP(PP), IdDeclInfos(new IdDeclInfoMap) {}
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
|
2008-04-14 08:09:21 +08:00
|
|
|
IdentifierResolver::~IdentifierResolver() {
|
2008-05-10 07:39:43 +08:00
|
|
|
delete IdDeclInfos;
|
2008-04-14 08:09:21 +08:00
|
|
|
}
|
2008-04-11 15:06:57 +08:00
|
|
|
|
2008-09-10 03:28:27 +08:00
|
|
|
/// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
|
|
|
|
/// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
|
|
|
|
/// true if 'D' belongs to the given declaration context.
|
2012-12-17 11:51:09 +08:00
|
|
|
bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S,
|
2013-12-05 12:30:04 +08:00
|
|
|
bool AllowInlineNamespace) const {
|
2010-08-31 08:36:30 +08:00
|
|
|
Ctx = Ctx->getRedeclContext();
|
2009-01-06 03:45:36 +08:00
|
|
|
|
2015-03-23 11:25:59 +08:00
|
|
|
if (Ctx->isFunctionOrMethod() || (S && S->isFunctionPrototypeScope())) {
|
2009-01-06 03:45:36 +08:00
|
|
|
// Ignore the scopes associated within transparent declaration contexts.
|
2013-10-09 01:08:03 +08:00
|
|
|
while (S->getEntity() && S->getEntity()->isTransparentContext())
|
2009-01-06 03:45:36 +08:00
|
|
|
S = S->getParent();
|
|
|
|
|
2010-08-21 17:40:31 +08:00
|
|
|
if (S->isDeclScope(D))
|
2008-09-10 05:57:58 +08:00
|
|
|
return true;
|
|
|
|
if (LangOpt.CPlusPlus) {
|
2008-12-22 00:41:36 +08:00
|
|
|
// C++ 3.3.2p3:
|
|
|
|
// The name declared in a catch exception-declaration is local to the
|
|
|
|
// handler and shall not be redeclared in the outermost block of the
|
|
|
|
// handler.
|
2008-09-10 05:57:58 +08:00
|
|
|
// C++ 3.3.2p4:
|
|
|
|
// Names declared in the for-init-statement, and in the condition of if,
|
|
|
|
// while, for, and switch statements are local to the if, while, for, or
|
|
|
|
// switch statement (including the controlled statement), and shall not be
|
|
|
|
// redeclared in a subsequent condition of that statement nor in the
|
|
|
|
// outermost block (or, for the if statement, any of the outermost blocks)
|
|
|
|
// of the controlled statement.
|
|
|
|
//
|
|
|
|
assert(S->getParent() && "No TUScope?");
|
2012-11-10 09:04:23 +08:00
|
|
|
if (S->getParent()->getFlags() & Scope::ControlScope) {
|
2012-11-13 06:25:41 +08:00
|
|
|
S = S->getParent();
|
|
|
|
if (S->isDeclScope(D))
|
|
|
|
return true;
|
2012-11-10 09:04:23 +08:00
|
|
|
}
|
2012-11-13 06:25:41 +08:00
|
|
|
if (S->getFlags() & Scope::FnTryCatchScope)
|
|
|
|
return S->getParent()->isDeclScope(D);
|
2008-09-10 05:57:58 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2008-09-10 03:28:27 +08:00
|
|
|
|
2014-08-28 06:31:34 +08:00
|
|
|
// FIXME: If D is a local extern declaration, this check doesn't make sense;
|
|
|
|
// we should be checking its lexical context instead in that case, because
|
|
|
|
// that is its scope.
|
2011-03-08 00:54:27 +08:00
|
|
|
DeclContext *DCtx = D->getDeclContext()->getRedeclContext();
|
2013-12-05 12:30:04 +08:00
|
|
|
return AllowInlineNamespace ? Ctx->InEnclosingNamespaceSetOf(DCtx)
|
|
|
|
: Ctx->Equals(DCtx);
|
2008-09-10 03:28:27 +08:00
|
|
|
}
|
|
|
|
|
2008-04-12 09:50:47 +08:00
|
|
|
/// AddDecl - Link the decl to its shadowed decl chain.
|
2008-05-10 07:39:43 +08:00
|
|
|
void IdentifierResolver::AddDecl(NamedDecl *D) {
|
2008-11-18 04:34:05 +08:00
|
|
|
DeclarationName Name = D->getDeclName();
|
2010-07-31 01:25:10 +08:00
|
|
|
if (IdentifierInfo *II = Name.getAsIdentifierInfo())
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
updatingIdentifier(*II);
|
2010-07-31 01:25:10 +08:00
|
|
|
|
[AST] Various optimizations + refactoring in DeclarationName(Table)
Introduce the following optimizations in DeclarationName(Table):
1. Store common kinds inline in DeclarationName instead of
DeclarationNameExtra. Currently the kind of C++ constructor, destructor,
conversion function and overloaded operator names is stored in
DeclarationNameExtra. Instead store it inline in DeclarationName.
To do this align IdentifierInfo, CXXSpecialName, DeclarationNameExtra
and CXXOperatorIdName to 8 bytes so that we can use the lower 3 bits of
DeclarationName::Ptr. This is already the case on 64 bits archs anyway.
This also allow us to remove DeclarationNameExtra from CXXSpecialName
and CXXOperatorIdName, which shave off a pointer from CXXSpecialName.
2. Synchronize the enumerations DeclarationName::NameKind,
DeclarationName::StoredNameKind and Selector::IdentifierInfoFlag.
This makes DeclarationName::getNameKind much more efficient since we can
replace the switch table by a single comparison and an addition.
3. Put the overloaded operator names inline in DeclarationNameTable to remove
an indirection. This increase the size of DeclarationNameTable a little
bit but this is not important since it is only used in ASTContext, and
never copied nor moved from. This also get rid of the last dynamic
allocation in DeclarationNameTable.
Altogether these optimizations cut the run time of parsing all of Boost by
about 0.8%. While we are at it, do the following NFC modifications:
1. Put the internal classes CXXSpecialName, CXXDeductionGuideNameExtra,
CXXOperatorIdName, CXXLiteralOperatorIdName and DeclarationNameExtra
in a namespace detail since these classes are only meant to be used by
DeclarationName and DeclarationNameTable. Make this more explicit by making
the members of these classes private and friending DeclarationName(Table).
2. Make DeclarationName::getFETokenInfo a non-template since every users are
using it to get a void *. It was supposed to be used with a type to avoid
a subsequent static_cast.
3. Change the internal functions DeclarationName::getAs* to castAs* since when
we use them we already know the correct kind. This has no external impact
since all of these are private.
Reviewed By: erichkeane, rjmccall
Differential Revision: https://reviews.llvm.org/D52267
llvm-svn: 342729
2018-09-21 20:53:22 +08:00
|
|
|
void *Ptr = Name.getFETokenInfo();
|
2008-04-11 15:06:57 +08:00
|
|
|
|
|
|
|
if (!Ptr) {
|
2008-11-18 04:34:05 +08:00
|
|
|
Name.setFETokenInfo(D);
|
2008-04-11 15:06:57 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
IdDeclInfo *IDI;
|
|
|
|
|
|
|
|
if (isDeclPtr(Ptr)) {
|
2014-05-26 14:22:03 +08:00
|
|
|
Name.setFETokenInfo(nullptr);
|
2008-11-18 04:34:05 +08:00
|
|
|
IDI = &(*IdDeclInfos)[Name];
|
2018-04-06 06:15:42 +08:00
|
|
|
NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
|
2008-05-10 07:39:43 +08:00
|
|
|
IDI->AddDecl(PrevD);
|
2008-04-11 15:06:57 +08:00
|
|
|
} else
|
|
|
|
IDI = toIdDeclInfo(Ptr);
|
|
|
|
|
2008-05-10 07:39:43 +08:00
|
|
|
IDI->AddDecl(D);
|
2008-04-11 15:06:57 +08:00
|
|
|
}
|
|
|
|
|
2011-03-17 00:39:03 +08:00
|
|
|
void IdentifierResolver::InsertDeclAfter(iterator Pos, NamedDecl *D) {
|
2011-03-15 05:19:51 +08:00
|
|
|
DeclarationName Name = D->getDeclName();
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
if (IdentifierInfo *II = Name.getAsIdentifierInfo())
|
|
|
|
updatingIdentifier(*II);
|
2018-07-31 03:24:48 +08:00
|
|
|
|
[AST] Various optimizations + refactoring in DeclarationName(Table)
Introduce the following optimizations in DeclarationName(Table):
1. Store common kinds inline in DeclarationName instead of
DeclarationNameExtra. Currently the kind of C++ constructor, destructor,
conversion function and overloaded operator names is stored in
DeclarationNameExtra. Instead store it inline in DeclarationName.
To do this align IdentifierInfo, CXXSpecialName, DeclarationNameExtra
and CXXOperatorIdName to 8 bytes so that we can use the lower 3 bits of
DeclarationName::Ptr. This is already the case on 64 bits archs anyway.
This also allow us to remove DeclarationNameExtra from CXXSpecialName
and CXXOperatorIdName, which shave off a pointer from CXXSpecialName.
2. Synchronize the enumerations DeclarationName::NameKind,
DeclarationName::StoredNameKind and Selector::IdentifierInfoFlag.
This makes DeclarationName::getNameKind much more efficient since we can
replace the switch table by a single comparison and an addition.
3. Put the overloaded operator names inline in DeclarationNameTable to remove
an indirection. This increase the size of DeclarationNameTable a little
bit but this is not important since it is only used in ASTContext, and
never copied nor moved from. This also get rid of the last dynamic
allocation in DeclarationNameTable.
Altogether these optimizations cut the run time of parsing all of Boost by
about 0.8%. While we are at it, do the following NFC modifications:
1. Put the internal classes CXXSpecialName, CXXDeductionGuideNameExtra,
CXXOperatorIdName, CXXLiteralOperatorIdName and DeclarationNameExtra
in a namespace detail since these classes are only meant to be used by
DeclarationName and DeclarationNameTable. Make this more explicit by making
the members of these classes private and friending DeclarationName(Table).
2. Make DeclarationName::getFETokenInfo a non-template since every users are
using it to get a void *. It was supposed to be used with a type to avoid
a subsequent static_cast.
3. Change the internal functions DeclarationName::getAs* to castAs* since when
we use them we already know the correct kind. This has no external impact
since all of these are private.
Reviewed By: erichkeane, rjmccall
Differential Revision: https://reviews.llvm.org/D52267
llvm-svn: 342729
2018-09-21 20:53:22 +08:00
|
|
|
void *Ptr = Name.getFETokenInfo();
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2011-03-24 18:35:39 +08:00
|
|
|
if (!Ptr) {
|
2011-03-17 00:39:03 +08:00
|
|
|
AddDecl(D);
|
2011-03-15 05:19:51 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-03-24 18:35:39 +08:00
|
|
|
if (isDeclPtr(Ptr)) {
|
|
|
|
// We only have a single declaration: insert before or after it,
|
|
|
|
// as appropriate.
|
|
|
|
if (Pos == iterator()) {
|
|
|
|
// Add the new declaration before the existing declaration.
|
2018-04-06 06:15:42 +08:00
|
|
|
NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
|
2011-03-24 18:35:39 +08:00
|
|
|
RemoveDecl(PrevD);
|
|
|
|
AddDecl(D);
|
|
|
|
AddDecl(PrevD);
|
|
|
|
} else {
|
|
|
|
// Add new declaration after the existing declaration.
|
|
|
|
AddDecl(D);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-07-31 03:24:48 +08:00
|
|
|
// General case: insert the declaration at the appropriate point in the
|
2011-03-15 05:19:51 +08:00
|
|
|
// list, which already has at least two elements.
|
|
|
|
IdDeclInfo *IDI = toIdDeclInfo(Ptr);
|
2011-03-17 00:39:03 +08:00
|
|
|
if (Pos.isIterator()) {
|
|
|
|
IDI->InsertDecl(Pos.getIterator() + 1, D);
|
|
|
|
} else
|
2011-03-15 05:19:51 +08:00
|
|
|
IDI->InsertDecl(IDI->decls_begin(), D);
|
|
|
|
}
|
|
|
|
|
2008-04-12 09:50:47 +08:00
|
|
|
/// RemoveDecl - Unlink the decl from its shadowed decl chain.
|
2008-04-11 15:06:57 +08:00
|
|
|
/// The decl must already be part of the decl chain.
|
|
|
|
void IdentifierResolver::RemoveDecl(NamedDecl *D) {
|
|
|
|
assert(D && "null param passed");
|
2008-11-18 04:34:05 +08:00
|
|
|
DeclarationName Name = D->getDeclName();
|
2010-07-31 01:25:10 +08:00
|
|
|
if (IdentifierInfo *II = Name.getAsIdentifierInfo())
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
updatingIdentifier(*II);
|
2010-07-31 01:25:10 +08:00
|
|
|
|
[AST] Various optimizations + refactoring in DeclarationName(Table)
Introduce the following optimizations in DeclarationName(Table):
1. Store common kinds inline in DeclarationName instead of
DeclarationNameExtra. Currently the kind of C++ constructor, destructor,
conversion function and overloaded operator names is stored in
DeclarationNameExtra. Instead store it inline in DeclarationName.
To do this align IdentifierInfo, CXXSpecialName, DeclarationNameExtra
and CXXOperatorIdName to 8 bytes so that we can use the lower 3 bits of
DeclarationName::Ptr. This is already the case on 64 bits archs anyway.
This also allow us to remove DeclarationNameExtra from CXXSpecialName
and CXXOperatorIdName, which shave off a pointer from CXXSpecialName.
2. Synchronize the enumerations DeclarationName::NameKind,
DeclarationName::StoredNameKind and Selector::IdentifierInfoFlag.
This makes DeclarationName::getNameKind much more efficient since we can
replace the switch table by a single comparison and an addition.
3. Put the overloaded operator names inline in DeclarationNameTable to remove
an indirection. This increase the size of DeclarationNameTable a little
bit but this is not important since it is only used in ASTContext, and
never copied nor moved from. This also get rid of the last dynamic
allocation in DeclarationNameTable.
Altogether these optimizations cut the run time of parsing all of Boost by
about 0.8%. While we are at it, do the following NFC modifications:
1. Put the internal classes CXXSpecialName, CXXDeductionGuideNameExtra,
CXXOperatorIdName, CXXLiteralOperatorIdName and DeclarationNameExtra
in a namespace detail since these classes are only meant to be used by
DeclarationName and DeclarationNameTable. Make this more explicit by making
the members of these classes private and friending DeclarationName(Table).
2. Make DeclarationName::getFETokenInfo a non-template since every users are
using it to get a void *. It was supposed to be used with a type to avoid
a subsequent static_cast.
3. Change the internal functions DeclarationName::getAs* to castAs* since when
we use them we already know the correct kind. This has no external impact
since all of these are private.
Reviewed By: erichkeane, rjmccall
Differential Revision: https://reviews.llvm.org/D52267
llvm-svn: 342729
2018-09-21 20:53:22 +08:00
|
|
|
void *Ptr = Name.getFETokenInfo();
|
2008-04-11 15:06:57 +08:00
|
|
|
|
|
|
|
assert(Ptr && "Didn't find this decl on its identifier's chain!");
|
|
|
|
|
|
|
|
if (isDeclPtr(Ptr)) {
|
|
|
|
assert(D == Ptr && "Didn't find this decl on its identifier's chain!");
|
2014-05-26 14:22:03 +08:00
|
|
|
Name.setFETokenInfo(nullptr);
|
2008-04-11 15:06:57 +08:00
|
|
|
return;
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-05-10 07:39:43 +08:00
|
|
|
return toIdDeclInfo(Ptr)->RemoveDecl(D);
|
2008-04-11 15:06:57 +08:00
|
|
|
}
|
|
|
|
|
Eliminated LookupCriteria, whose creation was causing a bottleneck for
LookupName et al. Instead, use an enum and a bool to describe its
contents.
Optimized the C/Objective-C path through LookupName, eliminating any
unnecessarily C++isms. Simplify IdentifierResolver::iterator, removing
some code and arguments that are no longer used.
Eliminated LookupDeclInScope/LookupDeclInContext, moving all callers
over to LookupName, LookupQualifiedName, or LookupParsedName, as
appropriate.
All together, I'm seeing a 0.2% speedup on Cocoa.h with PTH and
-disable-free. Plus, we're down to three name-lookup routines.
llvm-svn: 63354
2009-01-30 09:04:22 +08:00
|
|
|
/// begin - Returns an iterator for decls with name 'Name'.
|
2008-05-10 07:39:43 +08:00
|
|
|
IdentifierResolver::iterator
|
Eliminated LookupCriteria, whose creation was causing a bottleneck for
LookupName et al. Instead, use an enum and a bool to describe its
contents.
Optimized the C/Objective-C path through LookupName, eliminating any
unnecessarily C++isms. Simplify IdentifierResolver::iterator, removing
some code and arguments that are no longer used.
Eliminated LookupDeclInScope/LookupDeclInContext, moving all callers
over to LookupName, LookupQualifiedName, or LookupParsedName, as
appropriate.
All together, I'm seeing a 0.2% speedup on Cocoa.h with PTH and
-disable-free. Plus, we're down to three name-lookup routines.
llvm-svn: 63354
2009-01-30 09:04:22 +08:00
|
|
|
IdentifierResolver::begin(DeclarationName Name) {
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
if (IdentifierInfo *II = Name.getAsIdentifierInfo())
|
|
|
|
readingIdentifier(*II);
|
2018-07-31 03:24:48 +08:00
|
|
|
|
[AST] Various optimizations + refactoring in DeclarationName(Table)
Introduce the following optimizations in DeclarationName(Table):
1. Store common kinds inline in DeclarationName instead of
DeclarationNameExtra. Currently the kind of C++ constructor, destructor,
conversion function and overloaded operator names is stored in
DeclarationNameExtra. Instead store it inline in DeclarationName.
To do this align IdentifierInfo, CXXSpecialName, DeclarationNameExtra
and CXXOperatorIdName to 8 bytes so that we can use the lower 3 bits of
DeclarationName::Ptr. This is already the case on 64 bits archs anyway.
This also allow us to remove DeclarationNameExtra from CXXSpecialName
and CXXOperatorIdName, which shave off a pointer from CXXSpecialName.
2. Synchronize the enumerations DeclarationName::NameKind,
DeclarationName::StoredNameKind and Selector::IdentifierInfoFlag.
This makes DeclarationName::getNameKind much more efficient since we can
replace the switch table by a single comparison and an addition.
3. Put the overloaded operator names inline in DeclarationNameTable to remove
an indirection. This increase the size of DeclarationNameTable a little
bit but this is not important since it is only used in ASTContext, and
never copied nor moved from. This also get rid of the last dynamic
allocation in DeclarationNameTable.
Altogether these optimizations cut the run time of parsing all of Boost by
about 0.8%. While we are at it, do the following NFC modifications:
1. Put the internal classes CXXSpecialName, CXXDeductionGuideNameExtra,
CXXOperatorIdName, CXXLiteralOperatorIdName and DeclarationNameExtra
in a namespace detail since these classes are only meant to be used by
DeclarationName and DeclarationNameTable. Make this more explicit by making
the members of these classes private and friending DeclarationName(Table).
2. Make DeclarationName::getFETokenInfo a non-template since every users are
using it to get a void *. It was supposed to be used with a type to avoid
a subsequent static_cast.
3. Change the internal functions DeclarationName::getAs* to castAs* since when
we use them we already know the correct kind. This has no external impact
since all of these are private.
Reviewed By: erichkeane, rjmccall
Differential Revision: https://reviews.llvm.org/D52267
llvm-svn: 342729
2018-09-21 20:53:22 +08:00
|
|
|
void *Ptr = Name.getFETokenInfo();
|
2008-07-18 01:49:50 +08:00
|
|
|
if (!Ptr) return end();
|
2008-04-11 15:06:57 +08:00
|
|
|
|
2009-03-04 14:34:08 +08:00
|
|
|
if (isDeclPtr(Ptr))
|
2018-04-06 06:15:42 +08:00
|
|
|
return iterator(static_cast<NamedDecl*>(Ptr));
|
2008-04-11 15:06:57 +08:00
|
|
|
|
2008-07-18 01:49:50 +08:00
|
|
|
IdDeclInfo *IDI = toIdDeclInfo(Ptr);
|
2008-05-10 07:39:43 +08:00
|
|
|
|
2009-01-06 03:45:36 +08:00
|
|
|
IdDeclInfo::DeclsTy::iterator I = IDI->decls_end();
|
2008-07-18 01:49:50 +08:00
|
|
|
if (I != IDI->decls_begin())
|
Eliminated LookupCriteria, whose creation was causing a bottleneck for
LookupName et al. Instead, use an enum and a bool to describe its
contents.
Optimized the C/Objective-C path through LookupName, eliminating any
unnecessarily C++isms. Simplify IdentifierResolver::iterator, removing
some code and arguments that are no longer used.
Eliminated LookupDeclInScope/LookupDeclInContext, moving all callers
over to LookupName, LookupQualifiedName, or LookupParsedName, as
appropriate.
All together, I'm seeing a 0.2% speedup on Cocoa.h with PTH and
-disable-free. Plus, we're down to three name-lookup routines.
llvm-svn: 63354
2009-01-30 09:04:22 +08:00
|
|
|
return iterator(I-1);
|
2009-03-04 14:34:08 +08:00
|
|
|
// No decls found.
|
|
|
|
return end();
|
2008-07-18 01:49:50 +08:00
|
|
|
}
|
2008-04-11 15:06:57 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
namespace {
|
2018-02-21 09:45:26 +08:00
|
|
|
|
|
|
|
enum DeclMatchKind {
|
|
|
|
DMK_Different,
|
|
|
|
DMK_Replace,
|
|
|
|
DMK_Ignore
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace
|
Lazy deserialization of the declaration chains associated with
identifiers from a precompiled header.
This patch changes the primary name lookup method for entities within
a precompiled header. Previously, we would load all of the names of
declarations at translation unit scope into a large DenseMap (inside
the TranslationUnitDecl's DeclContext), and then perform a special
"last resort" lookup into this DeclContext when we knew there was a
PCH file (see Sema::LookupName). Now, when we see an identifier named
for the first time, we load all of the declarations with that name
that are visible from the translation unit into the IdentifierInfo's
chain of declarations. Thus, the explicit "look into the translation
unit's DeclContext" code is gone, and Sema effectively uses the same
IdentifierInfo-based name lookup mechanism whether we are using a PCH
file or not.
This approach should help PCH scale with the size of the input program
rather than the size of the PCH file. The "Hello, World!" application
with Carbon.h as a PCH file now loads 20% of the identifiers in the
PCH file rather than 85% of the identifiers.
90% of the 20% of identifiers loaded are actually loaded when we
deserialize the preprocessor state. The next step is to make the
preprocessor load macros lazily, which should drastically reduce the
number of types, declarations, and identifiers loaded for "Hello,
World".
llvm-svn: 69737
2009-04-22 06:25:48 +08:00
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Compare two declarations to see whether they are different or,
|
2018-07-31 03:24:48 +08:00
|
|
|
/// if they are the same, whether the new declaration should replace the
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
/// existing declaration.
|
|
|
|
static DeclMatchKind compareDeclarations(NamedDecl *Existing, NamedDecl *New) {
|
|
|
|
// If the declarations are identical, ignore the new one.
|
|
|
|
if (Existing == New)
|
|
|
|
return DMK_Ignore;
|
|
|
|
|
|
|
|
// If the declarations have different kinds, they're obviously different.
|
|
|
|
if (Existing->getKind() != New->getKind())
|
|
|
|
return DMK_Different;
|
|
|
|
|
|
|
|
// If the declarations are redeclarations of each other, keep the newest one.
|
|
|
|
if (Existing->getCanonicalDecl() == New->getCanonicalDecl()) {
|
2015-03-06 07:24:12 +08:00
|
|
|
// If we're adding an imported declaration, don't replace another imported
|
|
|
|
// declaration.
|
|
|
|
if (Existing->isFromASTFile() && New->isFromASTFile())
|
|
|
|
return DMK_Different;
|
|
|
|
|
2013-02-12 02:16:18 +08:00
|
|
|
// If either of these is the most recent declaration, use it.
|
|
|
|
Decl *MostRecent = Existing->getMostRecentDecl();
|
|
|
|
if (Existing == MostRecent)
|
|
|
|
return DMK_Ignore;
|
|
|
|
|
|
|
|
if (New == MostRecent)
|
|
|
|
return DMK_Replace;
|
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
// If the existing declaration is somewhere in the previous declaration
|
|
|
|
// chain of the new declaration, then prefer the new declaration.
|
2014-03-07 07:45:36 +08:00
|
|
|
for (auto RD : New->redecls()) {
|
|
|
|
if (RD == Existing)
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
return DMK_Replace;
|
2018-07-31 03:24:48 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
if (RD->isCanonicalDecl())
|
|
|
|
break;
|
|
|
|
}
|
2018-07-31 03:24:48 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
return DMK_Ignore;
|
Lazy deserialization of the declaration chains associated with
identifiers from a precompiled header.
This patch changes the primary name lookup method for entities within
a precompiled header. Previously, we would load all of the names of
declarations at translation unit scope into a large DenseMap (inside
the TranslationUnitDecl's DeclContext), and then perform a special
"last resort" lookup into this DeclContext when we knew there was a
PCH file (see Sema::LookupName). Now, when we see an identifier named
for the first time, we load all of the declarations with that name
that are visible from the translation unit into the IdentifierInfo's
chain of declarations. Thus, the explicit "look into the translation
unit's DeclContext" code is gone, and Sema effectively uses the same
IdentifierInfo-based name lookup mechanism whether we are using a PCH
file or not.
This approach should help PCH scale with the size of the input program
rather than the size of the PCH file. The "Hello, World!" application
with Carbon.h as a PCH file now loads 20% of the identifiers in the
PCH file rather than 85% of the identifiers.
90% of the 20% of identifiers loaded are actually loaded when we
deserialize the preprocessor state. The next step is to make the
preprocessor load macros lazily, which should drastically reduce the
number of types, declarations, and identifiers loaded for "Hello,
World".
llvm-svn: 69737
2009-04-22 06:25:48 +08:00
|
|
|
}
|
2018-07-31 03:24:48 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
return DMK_Different;
|
|
|
|
}
|
Lazy deserialization of the declaration chains associated with
identifiers from a precompiled header.
This patch changes the primary name lookup method for entities within
a precompiled header. Previously, we would load all of the names of
declarations at translation unit scope into a large DenseMap (inside
the TranslationUnitDecl's DeclContext), and then perform a special
"last resort" lookup into this DeclContext when we knew there was a
PCH file (see Sema::LookupName). Now, when we see an identifier named
for the first time, we load all of the declarations with that name
that are visible from the translation unit into the IdentifierInfo's
chain of declarations. Thus, the explicit "look into the translation
unit's DeclContext" code is gone, and Sema effectively uses the same
IdentifierInfo-based name lookup mechanism whether we are using a PCH
file or not.
This approach should help PCH scale with the size of the input program
rather than the size of the PCH file. The "Hello, World!" application
with Carbon.h as a PCH file now loads 20% of the identifiers in the
PCH file rather than 85% of the identifiers.
90% of the 20% of identifiers loaded are actually loaded when we
deserialize the preprocessor state. The next step is to make the
preprocessor load macros lazily, which should drastically reduce the
number of types, declarations, and identifiers loaded for "Hello,
World".
llvm-svn: 69737
2009-04-22 06:25:48 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
bool IdentifierResolver::tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name){
|
|
|
|
if (IdentifierInfo *II = Name.getAsIdentifierInfo())
|
2012-01-24 23:24:38 +08:00
|
|
|
readingIdentifier(*II);
|
2018-07-31 03:24:48 +08:00
|
|
|
|
[AST] Various optimizations + refactoring in DeclarationName(Table)
Introduce the following optimizations in DeclarationName(Table):
1. Store common kinds inline in DeclarationName instead of
DeclarationNameExtra. Currently the kind of C++ constructor, destructor,
conversion function and overloaded operator names is stored in
DeclarationNameExtra. Instead store it inline in DeclarationName.
To do this align IdentifierInfo, CXXSpecialName, DeclarationNameExtra
and CXXOperatorIdName to 8 bytes so that we can use the lower 3 bits of
DeclarationName::Ptr. This is already the case on 64 bits archs anyway.
This also allow us to remove DeclarationNameExtra from CXXSpecialName
and CXXOperatorIdName, which shave off a pointer from CXXSpecialName.
2. Synchronize the enumerations DeclarationName::NameKind,
DeclarationName::StoredNameKind and Selector::IdentifierInfoFlag.
This makes DeclarationName::getNameKind much more efficient since we can
replace the switch table by a single comparison and an addition.
3. Put the overloaded operator names inline in DeclarationNameTable to remove
an indirection. This increase the size of DeclarationNameTable a little
bit but this is not important since it is only used in ASTContext, and
never copied nor moved from. This also get rid of the last dynamic
allocation in DeclarationNameTable.
Altogether these optimizations cut the run time of parsing all of Boost by
about 0.8%. While we are at it, do the following NFC modifications:
1. Put the internal classes CXXSpecialName, CXXDeductionGuideNameExtra,
CXXOperatorIdName, CXXLiteralOperatorIdName and DeclarationNameExtra
in a namespace detail since these classes are only meant to be used by
DeclarationName and DeclarationNameTable. Make this more explicit by making
the members of these classes private and friending DeclarationName(Table).
2. Make DeclarationName::getFETokenInfo a non-template since every users are
using it to get a void *. It was supposed to be used with a type to avoid
a subsequent static_cast.
3. Change the internal functions DeclarationName::getAs* to castAs* since when
we use them we already know the correct kind. This has no external impact
since all of these are private.
Reviewed By: erichkeane, rjmccall
Differential Revision: https://reviews.llvm.org/D52267
llvm-svn: 342729
2018-09-21 20:53:22 +08:00
|
|
|
void *Ptr = Name.getFETokenInfo();
|
2018-07-31 03:24:48 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
if (!Ptr) {
|
|
|
|
Name.setFETokenInfo(D);
|
|
|
|
return true;
|
|
|
|
}
|
2018-07-31 03:24:48 +08:00
|
|
|
|
Lazy deserialization of the declaration chains associated with
identifiers from a precompiled header.
This patch changes the primary name lookup method for entities within
a precompiled header. Previously, we would load all of the names of
declarations at translation unit scope into a large DenseMap (inside
the TranslationUnitDecl's DeclContext), and then perform a special
"last resort" lookup into this DeclContext when we knew there was a
PCH file (see Sema::LookupName). Now, when we see an identifier named
for the first time, we load all of the declarations with that name
that are visible from the translation unit into the IdentifierInfo's
chain of declarations. Thus, the explicit "look into the translation
unit's DeclContext" code is gone, and Sema effectively uses the same
IdentifierInfo-based name lookup mechanism whether we are using a PCH
file or not.
This approach should help PCH scale with the size of the input program
rather than the size of the PCH file. The "Hello, World!" application
with Carbon.h as a PCH file now loads 20% of the identifiers in the
PCH file rather than 85% of the identifiers.
90% of the 20% of identifiers loaded are actually loaded when we
deserialize the preprocessor state. The next step is to make the
preprocessor load macros lazily, which should drastically reduce the
number of types, declarations, and identifiers loaded for "Hello,
World".
llvm-svn: 69737
2009-04-22 06:25:48 +08:00
|
|
|
IdDeclInfo *IDI;
|
2018-07-31 03:24:48 +08:00
|
|
|
|
Lazy deserialization of the declaration chains associated with
identifiers from a precompiled header.
This patch changes the primary name lookup method for entities within
a precompiled header. Previously, we would load all of the names of
declarations at translation unit scope into a large DenseMap (inside
the TranslationUnitDecl's DeclContext), and then perform a special
"last resort" lookup into this DeclContext when we knew there was a
PCH file (see Sema::LookupName). Now, when we see an identifier named
for the first time, we load all of the declarations with that name
that are visible from the translation unit into the IdentifierInfo's
chain of declarations. Thus, the explicit "look into the translation
unit's DeclContext" code is gone, and Sema effectively uses the same
IdentifierInfo-based name lookup mechanism whether we are using a PCH
file or not.
This approach should help PCH scale with the size of the input program
rather than the size of the PCH file. The "Hello, World!" application
with Carbon.h as a PCH file now loads 20% of the identifiers in the
PCH file rather than 85% of the identifiers.
90% of the 20% of identifiers loaded are actually loaded when we
deserialize the preprocessor state. The next step is to make the
preprocessor load macros lazily, which should drastically reduce the
number of types, declarations, and identifiers loaded for "Hello,
World".
llvm-svn: 69737
2009-04-22 06:25:48 +08:00
|
|
|
if (isDeclPtr(Ptr)) {
|
2018-04-06 06:15:42 +08:00
|
|
|
NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
|
2018-07-31 03:24:48 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
switch (compareDeclarations(PrevD, D)) {
|
|
|
|
case DMK_Different:
|
|
|
|
break;
|
2018-07-31 03:24:48 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
case DMK_Ignore:
|
|
|
|
return false;
|
2018-07-31 03:24:48 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
case DMK_Replace:
|
|
|
|
Name.setFETokenInfo(D);
|
|
|
|
return true;
|
|
|
|
}
|
2014-05-26 14:22:03 +08:00
|
|
|
|
|
|
|
Name.setFETokenInfo(nullptr);
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
IDI = &(*IdDeclInfos)[Name];
|
2018-07-31 03:24:48 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
// If the existing declaration is not visible in translation unit scope,
|
|
|
|
// then add the new top-level declaration first.
|
|
|
|
if (!PrevD->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
|
|
|
|
IDI->AddDecl(D);
|
|
|
|
IDI->AddDecl(PrevD);
|
|
|
|
} else {
|
|
|
|
IDI->AddDecl(PrevD);
|
|
|
|
IDI->AddDecl(D);
|
|
|
|
}
|
|
|
|
return true;
|
2018-07-31 03:24:48 +08:00
|
|
|
}
|
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
IDI = toIdDeclInfo(Ptr);
|
Lazy deserialization of the declaration chains associated with
identifiers from a precompiled header.
This patch changes the primary name lookup method for entities within
a precompiled header. Previously, we would load all of the names of
declarations at translation unit scope into a large DenseMap (inside
the TranslationUnitDecl's DeclContext), and then perform a special
"last resort" lookup into this DeclContext when we knew there was a
PCH file (see Sema::LookupName). Now, when we see an identifier named
for the first time, we load all of the declarations with that name
that are visible from the translation unit into the IdentifierInfo's
chain of declarations. Thus, the explicit "look into the translation
unit's DeclContext" code is gone, and Sema effectively uses the same
IdentifierInfo-based name lookup mechanism whether we are using a PCH
file or not.
This approach should help PCH scale with the size of the input program
rather than the size of the PCH file. The "Hello, World!" application
with Carbon.h as a PCH file now loads 20% of the identifiers in the
PCH file rather than 85% of the identifiers.
90% of the 20% of identifiers loaded are actually loaded when we
deserialize the preprocessor state. The next step is to make the
preprocessor load macros lazily, which should drastically reduce the
number of types, declarations, and identifiers loaded for "Hello,
World".
llvm-svn: 69737
2009-04-22 06:25:48 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
// See whether this declaration is identical to any existing declarations.
|
|
|
|
// If not, find the right place to insert it.
|
2018-07-31 03:24:48 +08:00
|
|
|
for (IdDeclInfo::DeclsTy::iterator I = IDI->decls_begin(),
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
IEnd = IDI->decls_end();
|
|
|
|
I != IEnd; ++I) {
|
2018-07-31 03:24:48 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
switch (compareDeclarations(*I, D)) {
|
|
|
|
case DMK_Different:
|
|
|
|
break;
|
2018-07-31 03:24:48 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
case DMK_Ignore:
|
|
|
|
return false;
|
2018-07-31 03:24:48 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
case DMK_Replace:
|
|
|
|
*I = D;
|
|
|
|
return true;
|
|
|
|
}
|
2018-07-31 03:24:48 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
if (!(*I)->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
|
|
|
|
// We've found a declaration that is not visible from the translation
|
|
|
|
// unit (it's in an inner scope). Insert our declaration here.
|
|
|
|
IDI->InsertDecl(I, D);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2018-07-31 03:24:48 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
// Add the declaration to the end.
|
Lazy deserialization of the declaration chains associated with
identifiers from a precompiled header.
This patch changes the primary name lookup method for entities within
a precompiled header. Previously, we would load all of the names of
declarations at translation unit scope into a large DenseMap (inside
the TranslationUnitDecl's DeclContext), and then perform a special
"last resort" lookup into this DeclContext when we knew there was a
PCH file (see Sema::LookupName). Now, when we see an identifier named
for the first time, we load all of the declarations with that name
that are visible from the translation unit into the IdentifierInfo's
chain of declarations. Thus, the explicit "look into the translation
unit's DeclContext" code is gone, and Sema effectively uses the same
IdentifierInfo-based name lookup mechanism whether we are using a PCH
file or not.
This approach should help PCH scale with the size of the input program
rather than the size of the PCH file. The "Hello, World!" application
with Carbon.h as a PCH file now loads 20% of the identifiers in the
PCH file rather than 85% of the identifiers.
90% of the 20% of identifiers loaded are actually loaded when we
deserialize the preprocessor state. The next step is to make the
preprocessor load macros lazily, which should drastically reduce the
number of types, declarations, and identifiers loaded for "Hello,
World".
llvm-svn: 69737
2009-04-22 06:25:48 +08:00
|
|
|
IDI->AddDecl(D);
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IdentifierResolver::readingIdentifier(IdentifierInfo &II) {
|
|
|
|
if (II.isOutOfDate())
|
2018-07-31 03:24:48 +08:00
|
|
|
PP.getExternalSource()->updateOutOfDateIdentifier(II);
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void IdentifierResolver::updatingIdentifier(IdentifierInfo &II) {
|
|
|
|
if (II.isOutOfDate())
|
|
|
|
PP.getExternalSource()->updateOutOfDateIdentifier(II);
|
2018-07-31 03:24:48 +08:00
|
|
|
|
Make the loading of information attached to an IdentifierInfo from an
AST file more lazy, so that we don't eagerly load that information for
all known identifiers each time a new AST file is loaded. The eager
reloading made some sense in the context of precompiled headers, since
very few identifiers were defined before PCH load time. With modules,
however, a huge amount of code can get parsed before we see an
@import, so laziness becomes important here.
The approach taken to make this information lazy is fairly simple:
when we load a new AST file, we mark all of the existing identifiers
as being out-of-date. Whenever we want to access information that may
come from an AST (e.g., whether the identifier has a macro definition,
or what top-level declarations have that name), we check the
out-of-date bit and, if it's set, ask the AST reader to update the
IdentifierInfo from the AST files. The update is a merge, and we now
take care to merge declarations before/after imports with declarations
from multiple imports.
The results of this optimization are fairly dramatic. On a small
application that brings in 14 non-trivial modules, this takes modules
from being > 3x slower than a "perfect" PCH file down to 30% slower
for a full rebuild. A partial rebuild (where the PCH file or modules
can be re-used) is down to 7% slower. Making the PCH file just a
little imperfect (e.g., adding two smallish modules used by a bunch of
.m files that aren't in the PCH file) tips the scales in favor of the
modules approach, with 24% faster partial rebuilds.
This is just a first step; the lazy scheme could possibly be improved
by adding versioning, so we don't search into modules we already
searched. Moreover, we'll need similar lazy schemes for all of the
other lookup data structures, such as DeclContexts.
llvm-svn: 143100
2011-10-27 17:33:13 +08:00
|
|
|
if (II.isFromAST())
|
2016-02-06 03:03:40 +08:00
|
|
|
II.setFETokenInfoChangedSinceDeserialization();
|
Lazy deserialization of the declaration chains associated with
identifiers from a precompiled header.
This patch changes the primary name lookup method for entities within
a precompiled header. Previously, we would load all of the names of
declarations at translation unit scope into a large DenseMap (inside
the TranslationUnitDecl's DeclContext), and then perform a special
"last resort" lookup into this DeclContext when we knew there was a
PCH file (see Sema::LookupName). Now, when we see an identifier named
for the first time, we load all of the declarations with that name
that are visible from the translation unit into the IdentifierInfo's
chain of declarations. Thus, the explicit "look into the translation
unit's DeclContext" code is gone, and Sema effectively uses the same
IdentifierInfo-based name lookup mechanism whether we are using a PCH
file or not.
This approach should help PCH scale with the size of the input program
rather than the size of the PCH file. The "Hello, World!" application
with Carbon.h as a PCH file now loads 20% of the identifiers in the
PCH file rather than 85% of the identifiers.
90% of the 20% of identifiers loaded are actually loaded when we
deserialize the preprocessor state. The next step is to make the
preprocessor load macros lazily, which should drastically reduce the
number of types, declarations, and identifiers loaded for "Hello,
World".
llvm-svn: 69737
2009-04-22 06:25:48 +08:00
|
|
|
}
|
|
|
|
|
2008-09-10 03:28:27 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// IdDeclInfoMap Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2008-11-18 04:34:05 +08:00
|
|
|
/// Returns the IdDeclInfo associated to the DeclarationName.
|
2008-04-11 15:06:57 +08:00
|
|
|
/// It creates a new IdDeclInfo if one was not created before for this id.
|
2008-05-10 07:39:43 +08:00
|
|
|
IdentifierResolver::IdDeclInfo &
|
2008-11-18 04:34:05 +08:00
|
|
|
IdentifierResolver::IdDeclInfoMap::operator[](DeclarationName Name) {
|
[AST] Various optimizations + refactoring in DeclarationName(Table)
Introduce the following optimizations in DeclarationName(Table):
1. Store common kinds inline in DeclarationName instead of
DeclarationNameExtra. Currently the kind of C++ constructor, destructor,
conversion function and overloaded operator names is stored in
DeclarationNameExtra. Instead store it inline in DeclarationName.
To do this align IdentifierInfo, CXXSpecialName, DeclarationNameExtra
and CXXOperatorIdName to 8 bytes so that we can use the lower 3 bits of
DeclarationName::Ptr. This is already the case on 64 bits archs anyway.
This also allow us to remove DeclarationNameExtra from CXXSpecialName
and CXXOperatorIdName, which shave off a pointer from CXXSpecialName.
2. Synchronize the enumerations DeclarationName::NameKind,
DeclarationName::StoredNameKind and Selector::IdentifierInfoFlag.
This makes DeclarationName::getNameKind much more efficient since we can
replace the switch table by a single comparison and an addition.
3. Put the overloaded operator names inline in DeclarationNameTable to remove
an indirection. This increase the size of DeclarationNameTable a little
bit but this is not important since it is only used in ASTContext, and
never copied nor moved from. This also get rid of the last dynamic
allocation in DeclarationNameTable.
Altogether these optimizations cut the run time of parsing all of Boost by
about 0.8%. While we are at it, do the following NFC modifications:
1. Put the internal classes CXXSpecialName, CXXDeductionGuideNameExtra,
CXXOperatorIdName, CXXLiteralOperatorIdName and DeclarationNameExtra
in a namespace detail since these classes are only meant to be used by
DeclarationName and DeclarationNameTable. Make this more explicit by making
the members of these classes private and friending DeclarationName(Table).
2. Make DeclarationName::getFETokenInfo a non-template since every users are
using it to get a void *. It was supposed to be used with a type to avoid
a subsequent static_cast.
3. Change the internal functions DeclarationName::getAs* to castAs* since when
we use them we already know the correct kind. This has no external impact
since all of these are private.
Reviewed By: erichkeane, rjmccall
Differential Revision: https://reviews.llvm.org/D52267
llvm-svn: 342729
2018-09-21 20:53:22 +08:00
|
|
|
void *Ptr = Name.getFETokenInfo();
|
2008-04-11 15:06:57 +08:00
|
|
|
|
2008-05-10 07:39:43 +08:00
|
|
|
if (Ptr) return *toIdDeclInfo(Ptr);
|
2008-04-11 15:06:57 +08:00
|
|
|
|
2010-02-16 03:38:00 +08:00
|
|
|
if (CurIndex == POOL_SIZE) {
|
|
|
|
CurPool = new IdDeclInfoPool(CurPool);
|
2008-04-11 15:06:57 +08:00
|
|
|
CurIndex = 0;
|
|
|
|
}
|
2010-02-16 03:38:00 +08:00
|
|
|
IdDeclInfo *IDI = &CurPool->Pool[CurIndex];
|
2008-11-18 04:34:05 +08:00
|
|
|
Name.setFETokenInfo(reinterpret_cast<void*>(
|
2008-04-11 15:06:57 +08:00
|
|
|
reinterpret_cast<uintptr_t>(IDI) | 0x1)
|
|
|
|
);
|
|
|
|
++CurIndex;
|
|
|
|
return *IDI;
|
|
|
|
}
|
2010-08-24 15:21:54 +08:00
|
|
|
|
|
|
|
void IdentifierResolver::iterator::incrementSlowCase() {
|
|
|
|
NamedDecl *D = **this;
|
[AST] Various optimizations + refactoring in DeclarationName(Table)
Introduce the following optimizations in DeclarationName(Table):
1. Store common kinds inline in DeclarationName instead of
DeclarationNameExtra. Currently the kind of C++ constructor, destructor,
conversion function and overloaded operator names is stored in
DeclarationNameExtra. Instead store it inline in DeclarationName.
To do this align IdentifierInfo, CXXSpecialName, DeclarationNameExtra
and CXXOperatorIdName to 8 bytes so that we can use the lower 3 bits of
DeclarationName::Ptr. This is already the case on 64 bits archs anyway.
This also allow us to remove DeclarationNameExtra from CXXSpecialName
and CXXOperatorIdName, which shave off a pointer from CXXSpecialName.
2. Synchronize the enumerations DeclarationName::NameKind,
DeclarationName::StoredNameKind and Selector::IdentifierInfoFlag.
This makes DeclarationName::getNameKind much more efficient since we can
replace the switch table by a single comparison and an addition.
3. Put the overloaded operator names inline in DeclarationNameTable to remove
an indirection. This increase the size of DeclarationNameTable a little
bit but this is not important since it is only used in ASTContext, and
never copied nor moved from. This also get rid of the last dynamic
allocation in DeclarationNameTable.
Altogether these optimizations cut the run time of parsing all of Boost by
about 0.8%. While we are at it, do the following NFC modifications:
1. Put the internal classes CXXSpecialName, CXXDeductionGuideNameExtra,
CXXOperatorIdName, CXXLiteralOperatorIdName and DeclarationNameExtra
in a namespace detail since these classes are only meant to be used by
DeclarationName and DeclarationNameTable. Make this more explicit by making
the members of these classes private and friending DeclarationName(Table).
2. Make DeclarationName::getFETokenInfo a non-template since every users are
using it to get a void *. It was supposed to be used with a type to avoid
a subsequent static_cast.
3. Change the internal functions DeclarationName::getAs* to castAs* since when
we use them we already know the correct kind. This has no external impact
since all of these are private.
Reviewed By: erichkeane, rjmccall
Differential Revision: https://reviews.llvm.org/D52267
llvm-svn: 342729
2018-09-21 20:53:22 +08:00
|
|
|
void *InfoPtr = D->getDeclName().getFETokenInfo();
|
2010-08-24 15:21:54 +08:00
|
|
|
assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
|
|
|
|
IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
|
|
|
|
|
|
|
|
BaseIter I = getIterator();
|
|
|
|
if (I != Info->decls_begin())
|
|
|
|
*this = iterator(I-1);
|
|
|
|
else // No more decls.
|
|
|
|
*this = iterator();
|
|
|
|
}
|