[PATCH] D143745: Make section attribute and -ffunction-sections play nicely

Paul Robinson via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 10 08:17:21 PST 2023


probinson created this revision.
probinson added reviewers: rjmccall, MaskRay.
Herald added a project: All.
probinson requested review of this revision.

People use -ffunction-sections to put each function into its own
object-file section; this makes linker garbage-collection simpler.
However, if there's an explicit __attribute__((section("name"))
on the function, all functions with that attribute end up in a
single section, defeating the linker GC.

Use section groups to make these things work together.


https://reviews.llvm.org/D143745

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGen/section-attr-comdat.cpp


Index: clang/test/CodeGen/section-attr-comdat.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/section-attr-comdat.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple=x86_64-linux -emit-llvm  %s -o - | \
+// RUN:     FileCheck %s --check-prefix=NOCOMDAT
+// RUN: %clang_cc1 -triple=x86_64-linux -emit-llvm -ffunction-sections %s -o - | \
+// RUN:     FileCheck %s --check-prefix=COMDAT
+
+// template function = comdat always.
+template<typename T>
+__attribute__((section("foo"))) T ftemplate(T a) { return a + 1; }
+__attribute__((section("foo"))) int fglobal(int a) { return ftemplate(a) + 2; }
+
+// NOCOMDAT-DAG: ${{.*}}ftemplate{{.*}} = comdat any
+// NOCOMDAT-DAG: define {{.*}}ftemplate{{.*}} section "foo" comdat {
+// NOCOMDAT-DAG: define {{.*}}fglobal{{.*}} section "foo" {
+
+// COMDAT-DAG: ${{.*}}ftemplate{{.*}} = comdat any
+// COMDAT-DAG: ${{.*}}fglobal{{.*}} = comdat nodeduplicate
+// COMDAT-DAG: define {{.*}}ftemplate{{.*}} section "foo" comdat {
+// COMDAT-DAG: define {{.*}}fglobal{{.*}} section "foo" comdat {
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -2293,6 +2293,18 @@
       if (auto *SA = D->getAttr<PragmaClangTextSectionAttr>())
         if (!D->getAttr<SectionAttr>())
           F->addFnAttr("implicit-section-name", SA->getName());
+      // If we have -ffunction-sections, and also an explicit section name,
+      // put the function into a section group so that various linker GC
+      // operations will still work with this function.
+      if (CodeGenOpts.FunctionSections && getTriple().supportsCOMDAT() &&
+          D->hasAttr<SectionAttr>()) {
+        // Don't replace a real comdat.
+        if (!F->getComdat()) {
+          llvm::Comdat *C = TheModule.getOrInsertComdat(F->getName());
+          C->setSelectionKind(llvm::Comdat::NoDeduplicate);
+          F->setComdat(C);
+        }
+      }
 
       llvm::AttrBuilder Attrs(F->getContext());
       if (GetCPUAndFeaturesAttributes(GD, Attrs)) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D143745.496485.patch
Type: text/x-patch
Size: 2155 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230210/d92bcbb1/attachment.bin>


More information about the cfe-commits mailing list