2008-04-11 15:06:57 +08:00
|
|
|
//===- IdentifierResolver.cpp - Lexical Scope Name lookup -------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// 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"
|
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"
|
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(IdDeclInfoPool *Next) : Next(Next) {}
|
|
|
|
|
|
|
|
IdDeclInfoPool *Next;
|
|
|
|
IdDeclInfo Pool[POOL_SIZE];
|
|
|
|
};
|
|
|
|
|
|
|
|
IdDeclInfoPool *CurPool;
|
2008-04-11 15:06:57 +08:00
|
|
|
unsigned int CurIndex;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-04-11 15:06:57 +08:00
|
|
|
public:
|
2010-02-16 03:38:00 +08:00
|
|
|
IdDeclInfoMap() : CurPool(0), CurIndex(POOL_SIZE) {}
|
|
|
|
|
|
|
|
~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-04-14 08:09:21 +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)
|
2012-03-11 15:00:24 +08:00
|
|
|
: LangOpt(PP.getLangOpts()), PP(PP),
|
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
|
|
|
IdDeclInfos(new IdDeclInfoMap) {
|
2008-09-10 05:32:02 +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
|
|
|
|
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,
|
2011-03-08 00:54:27 +08:00
|
|
|
bool ExplicitInstantiationOrSpecialization) const {
|
2010-08-31 08:36:30 +08:00
|
|
|
Ctx = Ctx->getRedeclContext();
|
2009-01-06 03:45:36 +08:00
|
|
|
|
2012-02-29 18:24:19 +08:00
|
|
|
if (Ctx->isFunctionOrMethod() || 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
|
|
|
|
2011-03-08 00:54:27 +08:00
|
|
|
DeclContext *DCtx = D->getDeclContext()->getRedeclContext();
|
|
|
|
return ExplicitInstantiationOrSpecialization
|
|
|
|
? 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
|
|
|
|
2008-11-18 04:34:05 +08:00
|
|
|
void *Ptr = Name.getFETokenInfo<void>();
|
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)) {
|
2008-11-18 04:34:05 +08:00
|
|
|
Name.setFETokenInfo(NULL);
|
|
|
|
IDI = &(*IdDeclInfos)[Name];
|
2008-05-10 07:39:43 +08:00
|
|
|
NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
|
|
|
|
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);
|
|
|
|
|
2011-03-15 05:19:51 +08:00
|
|
|
void *Ptr = Name.getFETokenInfo<void>();
|
|
|
|
|
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.
|
|
|
|
NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
|
|
|
|
RemoveDecl(PrevD);
|
|
|
|
AddDecl(D);
|
|
|
|
AddDecl(PrevD);
|
|
|
|
} else {
|
|
|
|
// Add new declaration after the existing declaration.
|
|
|
|
AddDecl(D);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-03-15 05:19:51 +08:00
|
|
|
// General case: insert the declaration at the appropriate point in the
|
|
|
|
// 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
|
|
|
|
2008-11-18 04:34:05 +08:00
|
|
|
void *Ptr = Name.getFETokenInfo<void>();
|
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!");
|
2008-11-18 04:34:05 +08:00
|
|
|
Name.setFETokenInfo(NULL);
|
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);
|
|
|
|
|
2008-11-18 04:34:05 +08:00
|
|
|
void *Ptr = Name.getFETokenInfo<void>();
|
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))
|
|
|
|
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 {
|
|
|
|
enum DeclMatchKind {
|
|
|
|
DMK_Different,
|
|
|
|
DMK_Replace,
|
|
|
|
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
|
|
|
|
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
|
|
|
/// \brief Compare two declarations to see whether they are different or,
|
|
|
|
/// if they are the same, whether the new declaration should replace the
|
|
|
|
/// 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()) {
|
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.
|
|
|
|
for (Decl::redecl_iterator RD = New->redecls_begin(),
|
|
|
|
RDEnd = New->redecls_end();
|
|
|
|
RD != RDEnd; ++RD) {
|
2012-06-07 04:45:41 +08:00
|
|
|
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;
|
|
|
|
|
|
|
|
if (RD->isCanonicalDecl())
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
}
|
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);
|
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 *Ptr = Name.getFETokenInfo<void>();
|
|
|
|
|
|
|
|
if (!Ptr) {
|
|
|
|
Name.setFETokenInfo(D);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
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;
|
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
|
|
|
|
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)) {
|
|
|
|
NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
|
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;
|
|
|
|
|
|
|
|
case DMK_Ignore:
|
|
|
|
return false;
|
|
|
|
|
|
|
|
case DMK_Replace:
|
|
|
|
Name.setFETokenInfo(D);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
Name.setFETokenInfo(NULL);
|
|
|
|
IDI = &(*IdDeclInfos)[Name];
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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.
|
|
|
|
for (IdDeclInfo::DeclsTy::iterator I = IDI->decls_begin(),
|
|
|
|
IEnd = IDI->decls_end();
|
|
|
|
I != IEnd; ++I) {
|
|
|
|
|
|
|
|
switch (compareDeclarations(*I, D)) {
|
|
|
|
case DMK_Different:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DMK_Ignore:
|
|
|
|
return false;
|
|
|
|
|
|
|
|
case DMK_Replace:
|
|
|
|
*I = D;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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())
|
|
|
|
PP.getExternalSource()->updateOutOfDateIdentifier(II);
|
|
|
|
}
|
|
|
|
|
|
|
|
void IdentifierResolver::updatingIdentifier(IdentifierInfo &II) {
|
|
|
|
if (II.isOutOfDate())
|
|
|
|
PP.getExternalSource()->updateOutOfDateIdentifier(II);
|
|
|
|
|
|
|
|
if (II.isFromAST())
|
|
|
|
II.setChangedSinceDeserialization();
|
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) {
|
|
|
|
void *Ptr = Name.getFETokenInfo<void>();
|
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;
|
|
|
|
void *InfoPtr = D->getDeclName().getFETokenInfo<void>();
|
|
|
|
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();
|
|
|
|
}
|