[llvm] [RISCV] Let -data-sections also work on sbss/sdata sections (PR #87040)

via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 29 00:40:50 PDT 2024


https://github.com/KaiYG created https://github.com/llvm/llvm-project/pull/87040

Add an unique suffix to .sbss/.sdata if -fdata-sections.
Without assigning an unique .sbss/.sdata section to each symbols, a linker may not be able to remove unused part when gc-section since all used and unused symbols are all mixed in the same .sbss/.sdata section.
I believe this also matches the behavior of gcc.

>From 26180ed93536588f4ce65c648ff1e9fce962f654 Mon Sep 17 00:00:00 2001
From: Kai Kai-Yi Weng <kaiweng at andestech.com>
Date: Wed, 20 Mar 2024 09:25:32 +0800
Subject: [PATCH 1/2] [RISCV] Pre-commit a test showing apply -data-sections on
 sbss/sdata sections

Copied from sdata-limit-8.ll and update the CHECKs, otherwise it matches
any .sbss/.sdata regardless having a suffix or not.
---
 llvm/test/CodeGen/RISCV/sdata-sections.ll | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/sdata-sections.ll

diff --git a/llvm/test/CodeGen/RISCV/sdata-sections.ll b/llvm/test/CodeGen/RISCV/sdata-sections.ll
new file mode 100644
index 00000000000000..ec9db289301940
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/sdata-sections.ll
@@ -0,0 +1,18 @@
+; RUN: llc -mtriple=riscv32 -data-sections < %s | FileCheck -check-prefix=RV32 %s
+; RUN: llc -mtriple=riscv64 -data-sections < %s | FileCheck -check-prefix=RV64 %s
+
+; FIXME: Should append an unique name to each sdata/sbss section if -data-sections,
+; otherwise gc-section cannot remove them. This also matches the behavior on gcc.
+
+ at v = dso_local global i32 0, align 4
+ at r = dso_local global i64 7, align 8
+
+; SmallDataLimit set to 8, so we expect @v will be put in sbss
+; and @r will be put in sdata.
+!llvm.module.flags = !{!0}
+!0 = !{i32 8, !"SmallDataLimit", i32 8}
+
+; RV32:    .section        .sbss,"aw"
+; RV32:    .section        .sdata,"aw"
+; RV64:    .section        .sbss,"aw"
+; RV64:    .section        .sdata,"aw"

>From eccdabb499f4340647d7432ecccb8a41826fdcda Mon Sep 17 00:00:00 2001
From: Kai Kai-Yi Weng <kaiweng at andestech.com>
Date: Wed, 20 Mar 2024 14:10:33 +0800
Subject: [PATCH 2/2] [RISCV] Let -data-sections also work on sbss/sdata
 sections

Without assigning an unique .sbss/.sdata section to each symbols, a linker
may not be able to remove unused part when gc-section since all used and
unused symbols are all mixed in the same .sbss/.sdata section.
I believe this also matches the behavior of gcc.
---
 .../Target/RISCV/RISCVTargetObjectFile.cpp    | 34 ++++++++++++++++---
 llvm/test/CodeGen/RISCV/sdata-sections.ll     | 11 +++---
 2 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
index e7c1a7e5d8bca1..b13df905249ab5 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
@@ -104,10 +104,36 @@ bool RISCVELFTargetObjectFile::isGlobalInSmallSection(
 MCSection *RISCVELFTargetObjectFile::SelectSectionForGlobal(
     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
   // Handle Small Section classification here.
-  if (Kind.isBSS() && isGlobalInSmallSection(GO, TM))
-    return SmallBSSSection;
-  if (Kind.isData() && isGlobalInSmallSection(GO, TM))
-    return SmallDataSection;
+  if (isGlobalInSmallSection(GO, TM)) {
+    // Emit a unique section for sdata/sbss when -fdata-section.
+    bool EmitUniquedSection = TM.getDataSections();
+
+    if (Kind.isBSS()) {
+      if (EmitUniquedSection) {
+        StringRef Prefix(".sbss");
+        SmallString<128> Name(Prefix);
+        Name.append(".");
+        Name.append(GO->getName());
+        return getContext().getELFSection(Name.str(), ELF::SHT_NOBITS,
+                                          ELF::SHF_WRITE | ELF::SHF_ALLOC);
+      }
+
+      return SmallBSSSection;
+    }
+
+    if (Kind.isData()) {
+      if (EmitUniquedSection) {
+        StringRef Prefix(".sdata");
+        SmallString<128> Name(Prefix);
+        Name.append(".");
+        Name.append(GO->getName());
+        return getContext().getELFSection(Name.str(), ELF::SHT_PROGBITS,
+                                          ELF::SHF_WRITE | ELF::SHF_ALLOC);
+      }
+
+      return SmallDataSection;
+    }
+  }
 
   // Otherwise, we work the same as ELF.
   return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM);
diff --git a/llvm/test/CodeGen/RISCV/sdata-sections.ll b/llvm/test/CodeGen/RISCV/sdata-sections.ll
index ec9db289301940..175e6d744843a8 100644
--- a/llvm/test/CodeGen/RISCV/sdata-sections.ll
+++ b/llvm/test/CodeGen/RISCV/sdata-sections.ll
@@ -1,8 +1,7 @@
 ; RUN: llc -mtriple=riscv32 -data-sections < %s | FileCheck -check-prefix=RV32 %s
 ; RUN: llc -mtriple=riscv64 -data-sections < %s | FileCheck -check-prefix=RV64 %s
 
-; FIXME: Should append an unique name to each sdata/sbss section if -data-sections,
-; otherwise gc-section cannot remove them. This also matches the behavior on gcc.
+; Append an unique name to each sdata/sbss section when -data-section.
 
 @v = dso_local global i32 0, align 4
 @r = dso_local global i64 7, align 8
@@ -12,7 +11,7 @@
 !llvm.module.flags = !{!0}
 !0 = !{i32 8, !"SmallDataLimit", i32 8}
 
-; RV32:    .section        .sbss,"aw"
-; RV32:    .section        .sdata,"aw"
-; RV64:    .section        .sbss,"aw"
-; RV64:    .section        .sdata,"aw"
+; RV32:    .section        .sbss.v,"aw"
+; RV32:    .section        .sdata.r,"aw"
+; RV64:    .section        .sbss.v,"aw"
+; RV64:    .section        .sdata.r,"aw"



More information about the llvm-commits mailing list