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)) {


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)) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to