[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