Skip to content

Commit c60c237

Browse files
committed
---
yaml --- r: 348411 b: refs/heads/master c: 7bca729 h: refs/heads/master i: 348409: 5878e98 348407: 8bc523d
1 parent cdd837b commit c60c237

File tree

13 files changed

+562
-58
lines changed

13 files changed

+562
-58
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: a4b80f50ca73994cee1ad1e0b7e02b1c71a66489
2+
refs/heads/master: 7bca7291e2a58d90b6ae9f082e3e58c976550e97
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/include/swift/AST/ASTContext.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ namespace swift {
112112

113113
enum class KnownProtocolKind : uint8_t;
114114

115+
namespace namelookup {
116+
class ImportCache;
117+
}
118+
115119
namespace syntax {
116120
class SyntaxArena;
117121
}
@@ -683,7 +687,9 @@ class ASTContext final {
683687
/// If there is no Clang module loader, returns a null pointer.
684688
/// The loader is owned by the AST context.
685689
ClangModuleLoader *getDWARFModuleLoader() const;
686-
690+
691+
namelookup::ImportCache &getImportCache() const;
692+
687693
/// Asks every module loader to verify the ASTs it has loaded.
688694
///
689695
/// Does nothing in non-asserts (NDEBUG) builds.

trunk/include/swift/AST/ImportCache.h

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
//===--- ImportCache.h - Caching the import graph ---------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines interfaces for querying the module import graph in an
14+
// efficient manner.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef SWIFT_AST_IMPORT_CACHE_H
19+
#define SWIFT_AST_IMPORT_CACHE_H
20+
21+
#include "swift/AST/Module.h"
22+
#include "llvm/ADT/DenseMap.h"
23+
#include "llvm/ADT/FoldingSet.h"
24+
25+
namespace swift {
26+
class DeclContext;
27+
28+
namespace namelookup {
29+
30+
/// An object describing a set of modules visible from a DeclContext.
31+
///
32+
/// This consists of two arrays of modules; the top-level imports and the
33+
/// transitive imports.
34+
///
35+
/// The top-level imports contains all public imports of the parent module
36+
/// of 'dc', together with any private imports in the source file containing
37+
/// 'dc', if there is one.
38+
///
39+
/// The transitive imports contains all public imports reachable from the
40+
/// set of top-level imports.
41+
///
42+
/// Both sets only contain unique elements. The top-level imports always
43+
/// include the parent module of 'dc' explicitly.
44+
///
45+
/// The set of transitive imports does not contain any elements found in
46+
/// the top-level imports.
47+
///
48+
/// The Swift standard library module is not included in either set unless
49+
/// it was explicitly imported (or re-exported).
50+
class ImportSet final :
51+
public llvm::FoldingSetNode,
52+
private llvm::TrailingObjects<ImportSet, ModuleDecl::ImportedModule> {
53+
friend TrailingObjects;
54+
friend ImportCache;
55+
56+
unsigned NumTopLevelImports;
57+
unsigned NumTransitiveImports;
58+
59+
ImportSet(ArrayRef<ModuleDecl::ImportedModule> topLevelImports,
60+
ArrayRef<ModuleDecl::ImportedModule> transitiveImports);
61+
62+
ImportSet(const ImportSet &) = delete;
63+
void operator=(const ImportSet &) = delete;
64+
65+
public:
66+
void Profile(llvm::FoldingSetNodeID &ID) {
67+
Profile(ID, getTopLevelImports());
68+
}
69+
static void Profile(
70+
llvm::FoldingSetNodeID &ID,
71+
ArrayRef<ModuleDecl::ImportedModule> topLevelImports);
72+
73+
size_t numTrailingObjects(OverloadToken<ModuleDecl::ImportedModule>) const {
74+
return NumTopLevelImports + NumTransitiveImports;
75+
}
76+
77+
ArrayRef<ModuleDecl::ImportedModule> getTopLevelImports() const {
78+
return {getTrailingObjects<ModuleDecl::ImportedModule>(),
79+
NumTopLevelImports};
80+
}
81+
82+
ArrayRef<ModuleDecl::ImportedModule> getTransitiveImports() const {
83+
return {getTrailingObjects<ModuleDecl::ImportedModule>() +
84+
NumTopLevelImports,
85+
NumTransitiveImports};
86+
}
87+
88+
ArrayRef<ModuleDecl::ImportedModule> getAllImports() const {
89+
return {getTrailingObjects<ModuleDecl::ImportedModule>(),
90+
NumTopLevelImports + NumTransitiveImports};
91+
}
92+
};
93+
94+
class alignas(ModuleDecl::ImportedModule) ImportCache {
95+
ImportCache(const ImportCache &) = delete;
96+
void operator=(const ImportCache &) = delete;
97+
98+
llvm::FoldingSet<ImportSet> ImportSets;
99+
llvm::DenseMap<const DeclContext *, ImportSet *> ImportSetForDC;
100+
llvm::DenseMap<std::tuple<const ModuleDecl *,
101+
const DeclContext *>,
102+
ArrayRef<ModuleDecl::AccessPathTy>> VisibilityCache;
103+
llvm::DenseMap<std::tuple<const ModuleDecl *,
104+
const ModuleDecl *,
105+
const DeclContext *>,
106+
ArrayRef<ModuleDecl::AccessPathTy>> ShadowCache;
107+
108+
ModuleDecl::AccessPathTy EmptyAccessPath;
109+
110+
ArrayRef<ModuleDecl::AccessPathTy> allocateArray(
111+
ASTContext &ctx,
112+
SmallVectorImpl<ModuleDecl::AccessPathTy> &results);
113+
114+
ImportSet &getImportSet(ASTContext &ctx,
115+
ArrayRef<ModuleDecl::ImportedModule> topLevelImports);
116+
117+
public:
118+
ImportCache() {}
119+
120+
/// Returns an object descripting all modules transtiively imported
121+
/// from 'dc'.
122+
ImportSet &getImportSet(const DeclContext *dc);
123+
124+
/// Returns all access paths into 'mod' that are visible from 'dc',
125+
/// including transitively, via re-exports.
126+
ArrayRef<ModuleDecl::AccessPathTy>
127+
getAllVisibleAccessPaths(const ModuleDecl *mod, const DeclContext *dc);
128+
129+
bool isImportedBy(const ModuleDecl *mod,
130+
const DeclContext *dc) {
131+
return !getAllVisibleAccessPaths(mod, dc).empty();
132+
}
133+
134+
/// Determines if 'mod' is visible from 'dc' as a result of a scoped import.
135+
/// Note that if 'mod' was not imported from 'dc' at all, this also returns
136+
/// false.
137+
bool isScopedImport(const ModuleDecl *mod, DeclBaseName name,
138+
const DeclContext *dc) {
139+
auto accessPaths = getAllVisibleAccessPaths(mod, dc);
140+
for (auto accessPath : accessPaths) {
141+
if (accessPath.empty())
142+
continue;
143+
if (ModuleDecl::matchesAccessPath(accessPath, name))
144+
return true;
145+
}
146+
147+
return false;
148+
}
149+
150+
/// Returns all access paths in 'mod' that are visible from 'dc' if we
151+
/// subtract imports of 'other'.
152+
ArrayRef<ModuleDecl::AccessPathTy>
153+
getAllAccessPathsNotShadowedBy(const ModuleDecl *mod,
154+
const ModuleDecl *other,
155+
const DeclContext *dc);
156+
157+
/// Returns 'true' if a declaration named 'name' defined in 'other' shadows
158+
/// defined in 'mod', because no access paths can find 'name' in 'mod' from
159+
/// 'dc' if we ignore imports of 'other'.
160+
bool isShadowedBy(const ModuleDecl *mod,
161+
const ModuleDecl *other,
162+
DeclBaseName name,
163+
const DeclContext *dc) {
164+
auto accessPaths = getAllAccessPathsNotShadowedBy(mod, other, dc);
165+
return llvm::none_of(accessPaths,
166+
[&](ModuleDecl::AccessPathTy accessPath) {
167+
return ModuleDecl::matchesAccessPath(accessPath, name);
168+
});
169+
}
170+
171+
/// Qualified lookup into types uses a slightly different check that does not
172+
/// take access paths into account.
173+
bool isShadowedBy(const ModuleDecl *mod,
174+
const ModuleDecl *other,
175+
const DeclContext *dc) {
176+
auto accessPaths = getAllAccessPathsNotShadowedBy(mod, other, dc);
177+
return accessPaths.empty();
178+
}
179+
180+
/// This is a hack to cope with main file parsing and REPL parsing, where
181+
/// we can add ImportDecls after name binding.
182+
void clear() {
183+
ImportSetForDC.clear();
184+
}
185+
};
186+
187+
} // namespace namelookup
188+
189+
} // namespace swift
190+
191+
#endif

trunk/include/swift/AST/NameLookup.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,11 +378,11 @@ bool removeOverriddenDecls(SmallVectorImpl<ValueDecl*> &decls);
378378
/// other declarations in that set.
379379
///
380380
/// \param decls The set of declarations being considered.
381-
/// \param curModule The current module.
381+
/// \param dc The DeclContext from which the lookup was performed.
382382
///
383383
/// \returns true if any shadowed declarations were removed.
384384
bool removeShadowedDecls(SmallVectorImpl<ValueDecl*> &decls,
385-
const ModuleDecl *curModule);
385+
const DeclContext *dc);
386386

387387
/// Finds decls visible in the given context and feeds them to the given
388388
/// VisibleDeclConsumer. If the current DeclContext is nested in a function,

trunk/include/swift/Basic/Statistics.def

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,19 @@ FRONTEND_STATISTIC(AST, NumBraceStmtASTScopeExpansions)
175175
/// Number of ASTScope lookups
176176
FRONTEND_STATISTIC(AST, NumASTScopeLookups)
177177

178+
/// Number of lookups of the cached import graph for a module or
179+
/// source file.
180+
FRONTEND_STATISTIC(AST, ImportSetFoldHit)
181+
FRONTEND_STATISTIC(AST, ImportSetFoldMiss)
182+
183+
FRONTEND_STATISTIC(AST, ImportSetCacheHit)
184+
FRONTEND_STATISTIC(AST, ImportSetCacheMiss)
185+
186+
FRONTEND_STATISTIC(AST, ModuleVisibilityCacheHit)
187+
FRONTEND_STATISTIC(AST, ModuleVisibilityCacheMiss)
188+
189+
FRONTEND_STATISTIC(AST, ModuleShadowCacheHit)
190+
FRONTEND_STATISTIC(AST, ModuleShadowCacheMiss)
178191

179192
/// Number of full function bodies parsed.
180193
FRONTEND_STATISTIC(Parse, NumFunctionsParsed)

trunk/lib/AST/ASTContext.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "swift/AST/GenericEnvironment.h"
2626
#include "swift/AST/GenericSignature.h"
2727
#include "swift/AST/GenericSignatureBuilder.h"
28+
#include "swift/AST/ImportCache.h"
2829
#include "swift/AST/KnownProtocols.h"
2930
#include "swift/AST/LazyResolver.h"
3031
#include "swift/AST/ModuleLoader.h"
@@ -252,6 +253,9 @@ FOR_KNOWN_FOUNDATION_TYPES(CACHE_FOUNDATION_DECL)
252253
/// ASTContext.
253254
SmallVector<std::unique_ptr<swift::ModuleLoader>, 4> ModuleLoaders;
254255

256+
/// Singleton used to cache the import graph.
257+
swift::namelookup::ImportCache TheImportCache;
258+
255259
/// The module loader used to load Clang modules.
256260
ClangModuleLoader *TheClangModuleLoader = nullptr;
257261

@@ -1494,6 +1498,10 @@ void ASTContext::verifyAllLoadedModules() const {
14941498
#endif
14951499
}
14961500

1501+
swift::namelookup::ImportCache &ASTContext::getImportCache() const {
1502+
return getImpl().TheImportCache;
1503+
}
1504+
14971505
ClangModuleLoader *ASTContext::getClangModuleLoader() const {
14981506
return getImpl().TheClangModuleLoader;
14991507
}

trunk/lib/AST/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ add_swift_host_library(swiftAST STATIC
5050
GenericSignature.cpp
5151
GenericSignatureBuilder.cpp
5252
Identifier.cpp
53+
ImportCache.cpp
5354
InlinableText.cpp
5455
LayoutConstraint.cpp
5556
Module.cpp

0 commit comments

Comments
 (0)