Skip to content

Commit 2232881

Browse files
committed
[C++20] [Modules] Avoid comparing primary module name to decide isInSameModule all the time
Previously, we decide if two module units are in the same module by comparing name of the primary module interface. But it looks not efficiency if we always compare the strings. It should be good to avoid the expensive string operations if possible. In this patch, we introduced a `llvm::StringMap` to map primary module name to a Module* and a `llvm::DenseMap<Module*, Module*>` to map a Module* to a representative Module *. The representative Module* is one of the Module units belonging to a certain module. The module units have the same representative Module* should belong to the same module. We choose the representative Module* by the first module lookup for a certain primary module name. So the following module units have the same primary module name would get the same representative modules. So that for every modules, there will be only one hash process for the primary module name.
1 parent 090e0c4 commit 2232881

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,14 @@ class ASTContext : public RefCountedBase<ASTContext> {
467467
/// This is the top-level (C++20) Named module we are building.
468468
Module *CurrentCXXNamedModule = nullptr;
469469

470+
/// Help structures to decide whether two `const Module *` belongs
471+
/// to the same conceptual module to avoid the expensive to string comparison
472+
/// if possible.
473+
///
474+
/// Not serialized intentionally.
475+
llvm::StringMap<const Module *> PrimaryModuleNameMap;
476+
llvm::DenseMap<const Module *, const Module *> SameModuleLookupSet;
477+
470478
static constexpr unsigned ConstantArrayTypesLog2InitSize = 8;
471479
static constexpr unsigned GeneralTypesLog2InitSize = 9;
472480
static constexpr unsigned FunctionProtoTypesLog2InitSize = 12;

clang/lib/AST/ASTContext.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,9 +1114,25 @@ bool ASTContext::isInSameModule(const Module *M1, const Module *M2) {
11141114
if (!M1 != !M2)
11151115
return false;
11161116

1117+
/// Get the representative module for M. The representative module is the
1118+
/// first module unit for a specific primary module name. So that the module
1119+
/// units have the same representative module belongs to the same module.
1120+
///
1121+
/// The process is helpful to reduce the expensive string operations.
1122+
auto GetRepresentativeModule = [this](const Module *M) {
1123+
auto Iter = SameModuleLookupSet.find(M);
1124+
if (Iter != SameModuleLookupSet.end())
1125+
return Iter->second;
1126+
1127+
const Module *RepresentativeModule =
1128+
PrimaryModuleNameMap.try_emplace(M->getPrimaryModuleInterfaceName(), M)
1129+
.first->second;
1130+
SameModuleLookupSet[M] = RepresentativeModule;
1131+
return RepresentativeModule;
1132+
};
1133+
11171134
assert(M1 && "Shouldn't call `isInSameModule` if both M1 and M2 are none.");
1118-
return M1->getPrimaryModuleInterfaceName() ==
1119-
M2->getPrimaryModuleInterfaceName();
1135+
return GetRepresentativeModule(M1) == GetRepresentativeModule(M2);
11201136
}
11211137

11221138
ExternCContextDecl *ASTContext::getExternCContextDecl() const {

0 commit comments

Comments
 (0)