Skip to content

Commit

Permalink
[Modules] Don't re-generate template specialization in the importer
Browse files Browse the repository at this point in the history
Close #60693.

In this issue, we can find that the importer will try to generate the
template specialization again in the importer, which is not good and
wastes time. This patch tries to address the problem.
  • Loading branch information
ChuanqiXu9 committed Feb 14, 2023
1 parent 46cdf7f commit 1ba93c3
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 9 deletions.
2 changes: 1 addition & 1 deletion clang/include/clang/AST/ASTContext.h
Expand Up @@ -3043,7 +3043,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
}

GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const;
GVALinkage GetGVALinkageForVariable(const VarDecl *VD);
GVALinkage GetGVALinkageForVariable(const VarDecl *VD) const;

/// Determines if the decl can be CodeGen'ed or deserialized from PCH
/// lazily, only when used; this is only relevant for function or file scoped
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/ASTContext.cpp
Expand Up @@ -11764,7 +11764,7 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,
llvm_unreachable("Invalid Linkage!");
}

GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) {
GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) const {
return adjustGVALinkageForExternalDefinitionKind(*this, VD,
adjustGVALinkageForAttributes(*this, VD,
basicGVALinkageForVariable(*this, VD)));
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Serialization/ASTWriterDecl.cpp
Expand Up @@ -1068,7 +1068,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
if (D->getStorageDuration() == SD_Static) {
bool ModulesCodegen = false;
if (Writer.WritingModule &&
!D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo()) {
!D->getDescribedVarTemplate()) {
// When building a C++20 module interface unit or a partition unit, a
// strong definition in the module interface is provided by the
// compilation of that unit, not by its users. (Inline variables are still
Expand All @@ -1077,7 +1077,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
(Writer.WritingModule->isInterfaceOrPartition() ||
(D->hasAttr<DLLExportAttr>() &&
Writer.Context->getLangOpts().BuildingPCHWithObjectFile)) &&
Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal;
Writer.Context->GetGVALinkageForVariable(D) >= GVA_StrongExternal;
}
Record.push_back(ModulesCodegen);
if (ModulesCodegen)
Expand Down Expand Up @@ -2550,7 +2550,7 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
// compilation of that unit, not by its users. (Inline functions are still
// emitted in module users.)
Linkage = Writer->Context->GetGVALinkageForFunction(FD);
ModulesCodegen = *Linkage == GVA_StrongExternal;
ModulesCodegen = *Linkage >= GVA_StrongExternal;
}
if (Writer->Context->getLangOpts().ModulesCodegen ||
(FD->hasAttr<DLLExportAttr>() &&
Expand Down
8 changes: 4 additions & 4 deletions clang/test/Modules/pr59780.cppm
Expand Up @@ -33,14 +33,14 @@ struct Y<int> {

int Y<int>::value = 0;

// CHECK-NOT: @_ZW1a1xIiE = {{.*}}available_externally{{.*}}global
// CHECK-NOT: @_ZNW1a1YIiE5valueE = {{.*}}available_externally{{.*}}global
// CHECK-NOT: @_ZW1a1xIiE = {{.*}}external{{.*}}global
// CHECK-NOT: @_ZNW1a1YIiE5valueE = {{.*}}external{{.*}}global

//--- use.cpp
import a;
int foo() {
return x<int> + Y<int>::value;
}

// CHECK: @_ZW1a1xIiE = {{.*}}available_externally{{.*}}global
// CHECK: @_ZNW1a1YIiE5valueE = {{.*}}available_externally{{.*}}global
// CHECK: @_ZW1a1xIiE = {{.*}}external{{.*}}global
// CHECK: @_ZNW1a1YIiE5valueE = {{.*}}external{{.*}}global
54 changes: 54 additions & 0 deletions clang/test/Modules/pr60693.cppm
@@ -0,0 +1,54 @@
// Address: https://github.com/llvm/llvm-project/issues/60693
//
// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: split-file %s %t
//
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/a.cppm -emit-module-interface -o %t/a.pcm
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple -fmodule-file=a=%t/a.pcm %t/c.cpp -S -emit-llvm -disable-llvm-passes -o - | FileCheck %t/c.cpp

//--- a.cppm
export module a;

constexpr bool f() {
for (unsigned n = 0; n != 10; ++n) {
}
return true;
}

export template<typename>
struct s {
static constexpr auto a = f();
static constexpr auto b = f();
static constexpr auto c = f();
static constexpr auto d = f();
int foo() {
return 43;
}
int bar() {
return 44;
}
};

template struct s<int>;
template struct s<long>;

//--- c.cpp
import a;

extern "C" int use() {
s<int> _;
return _.a + _.b + _.c + _.d;
}

extern "C" long use2() {
s<long> _;
return _.foo();
}

// CHECK: define{{.*}}@use(
// CHECK-NOT: }
// CHECK: ret{{.*}} 4

// CHECK: declare{{.*}}@_ZNW1a1sIlE3fooEv
// CHECK-NOT: _ZNW1a1sIlE3barEv

0 comments on commit 1ba93c3

Please sign in to comment.