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

Paul Robinson via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 2 11:00:19 PST 2023


probinson created this revision.
probinson added a reviewer: 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, the programmer is indicating the function has
some special purpose, and is not expected to be garbage collected.

In that case, add the function to the "llvm.used" list, which for ELF
adds SHF_GNU_RETAIN to the section flags, preventing GC.


https://reviews.llvm.org/D145173

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


Index: clang/test/CodeGen/section-retain.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/section-retain.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm -o - %s | \
+// RUN:     FileCheck %s --check-prefix=UNUSED
+// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm -ffunction-sections -o - %s | \
+// RUN:     FileCheck %s --check-prefix=USED
+
+// 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; }
+
+// UNUSED-NOT: llvm.used
+// USED: @llvm.used = {{.*}} [ptr
+// USED-NOT: ftemplate
+// USED-SAME: fglobal
+// USED-NOT: ftemplate
+// USED-SAME: ]
+
+// USED-DAG: define {{.*}}ftemplate{{.*}} section "foo"
+// USED-DAG: define {{.*}}fglobal{{.*}} section "foo"
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -2279,6 +2279,11 @@
       if (auto *SA = D->getAttr<PragmaClangTextSectionAttr>())
         if (!D->getAttr<SectionAttr>())
           F->addFnAttr("implicit-section-name", SA->getName());
+      // If we have -ffunction-sections, and an explicit section name,
+      // and the function is not COMDAT, explicitly retain it.
+      if (CodeGenOpts.FunctionSections && D->hasAttr<SectionAttr>() &&
+          !F->getComdat())
+        addUsedGlobal(F);
 
       llvm::AttrBuilder Attrs(F->getContext());
       if (GetCPUAndFeaturesAttributes(GD, Attrs)) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D145173.501926.patch
Type: text/x-patch
Size: 1656 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230302/7bc90c98/attachment.bin>


More information about the cfe-commits mailing list