[clang] 1ba93c3 - [Modules] Don't re-generate template specialization in the importer
Chuanqi Xu via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 14 01:15:54 PST 2023
Author: Chuanqi Xu
Date: 2023-02-14T17:15:33+08:00
New Revision: 1ba93c3c30dcdf2659e3020ba462e0025187d8e1
URL: https://github.com/llvm/llvm-project/commit/1ba93c3c30dcdf2659e3020ba462e0025187d8e1
DIFF: https://github.com/llvm/llvm-project/commit/1ba93c3c30dcdf2659e3020ba462e0025187d8e1.diff
LOG: [Modules] Don't re-generate template specialization in the importer
Close https://github.com/llvm/llvm-project/issues/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.
Added:
clang/test/Modules/pr60693.cppm
Modified:
clang/include/clang/AST/ASTContext.h
clang/lib/AST/ASTContext.cpp
clang/lib/Serialization/ASTWriterDecl.cpp
clang/test/Modules/pr59780.cppm
Removed:
################################################################################
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 006063e21eb3d..0f4decc14579b 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -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
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index a188837d4144c..a5f7f6a019f87 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -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)));
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 9e1e58a7fa7e2..69d192612bccf 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -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
@@ -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)
@@ -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>() &&
diff --git a/clang/test/Modules/pr59780.cppm b/clang/test/Modules/pr59780.cppm
index 9578325b976ba..d4bbd52c13f1a 100644
--- a/clang/test/Modules/pr59780.cppm
+++ b/clang/test/Modules/pr59780.cppm
@@ -33,8 +33,8 @@ 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;
@@ -42,5 +42,5 @@ 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
diff --git a/clang/test/Modules/pr60693.cppm b/clang/test/Modules/pr60693.cppm
new file mode 100644
index 0000000000000..117a0f2753d0a
--- /dev/null
+++ b/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
More information about the cfe-commits
mailing list