From 2582965c160486f9e3b0680f1cebc5ffdef9620c Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Thu, 14 Mar 2024 15:06:54 +0800 Subject: [PATCH] [C++20] [Modules] [Reduced BMI] Generate the function body from implicitly instantiated class and constant variables After this patch, we will generate the function body from implicitly instantiated class. This is important for consumers with same template arguments. Otherwise the consumers won't see the function body. Since the consumers won't instantiate the templates again if they find an instantiation. Also we will generate the variable definition if the variable is non-inline but known as constant. Such variables may not affect the ABI, but they may get involved into the compile time constant computation in the consumer's code. So we have to generate such definitions. --- clang/lib/Serialization/ASTWriterDecl.cpp | 9 ++++- .../Modules/reduced-bmi-generating-codes.cppm | 40 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 clang/test/Modules/reduced-bmi-generating-codes.cppm diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index d04e1c781b4e28..86f64bf2a24250 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -281,11 +281,18 @@ bool clang::CanElideDeclDef(const Decl *D) { if (FD->isDependentContext()) return false; + + if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) + return false; } if (auto *VD = dyn_cast(D)) { if (!VD->getDeclContext()->getRedeclContext()->isFileContext() || - VD->isInline() || VD->isConstexpr() || isa(VD)) + VD->isInline() || VD->isConstexpr() || isa(VD) || + // Constant initialized variable may not affect the ABI, but they + // may be used in constant evaluation in the frontend, so we have + // to remain them. + VD->hasConstantInitialization()) return false; if (VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) diff --git a/clang/test/Modules/reduced-bmi-generating-codes.cppm b/clang/test/Modules/reduced-bmi-generating-codes.cppm new file mode 100644 index 00000000000000..13dcda06437b29 --- /dev/null +++ b/clang/test/Modules/reduced-bmi-generating-codes.cppm @@ -0,0 +1,40 @@ +// Although the reduced BMI are not designed to be generated, +// it is helpful for testing whether we've reduced the definitions. +// +// 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 \ +// RUN: -emit-reduced-module-interface -o %t/a.pcm +// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/b.cpp \ +// RUN: -fmodule-file=a=%t/a.pcm -S -emit-llvm -o - \ +// RUN: | FileCheck %t/b.cpp + +//--- a.cppm +export module a; + +export template +class A { +public: + int member() { + return 43; + } +}; + +// Instantiate `A::member()`. +export int a_member = A().member(); + +export const int a = 43; + +//--- b.cpp +import a; + +static_assert(a == 43); + +int b() { + A a; + return a.member(); +} + +// CHECK: define{{.*}}@_ZNW1a1AIiE6memberEv