[llvm] [RISCV] Place mergeable small read only data into srodata section (PR #82214)

Kito Cheng via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 18 22:19:25 PST 2024


https://github.com/kito-cheng created https://github.com/llvm/llvm-project/pull/82214

Small mergeable read only data was place on the sdata before, but it also means it lose the mergeable property, which means lose some code size optimization opportunity during link time.

>From c764701eb08c1356937a045a45a6029389ef12c2 Mon Sep 17 00:00:00 2001
From: Kito Cheng <kito.cheng at sifive.com>
Date: Fri, 16 Feb 2024 17:03:45 +0800
Subject: [PATCH] [RISCV] Place mergeable small read only data into srodata
 section

Small mergeable read only data was place on the sdata before, but it also
means it lose the mergeable property, which means lose some code size
optimization opportunity during link time.
---
 .../Target/RISCV/RISCVTargetObjectFile.cpp    | 26 +++++++++-
 llvm/lib/Target/RISCV/RISCVTargetObjectFile.h |  5 ++
 llvm/test/CodeGen/RISCV/srodata.ll            | 47 +++++++++++++++++++
 3 files changed, 76 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/RISCV/srodata.ll

diff --git a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
index 1535149b919b55..30abbd461cd236 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
@@ -32,6 +32,16 @@ void RISCVELFTargetObjectFile::Initialize(MCContext &Ctx,
       ".sdata", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
   SmallBSSSection = getContext().getELFSection(".sbss", ELF::SHT_NOBITS,
                                                ELF::SHF_WRITE | ELF::SHF_ALLOC);
+  SmallRODataSection =
+      getContext().getELFSection(".srodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
+  SmallROData4Section = getContext().getELFSection(
+      ".srodata.cst4", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 4);
+  SmallROData8Section = getContext().getELFSection(
+      ".srodata.cst8", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 8);
+  SmallROData16Section = getContext().getELFSection(
+      ".srodata.cst16", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 16);
+  SmallROData32Section = getContext().getELFSection(
+      ".srodata.cst32", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 32);
 }
 
 const MCExpr *RISCVELFTargetObjectFile::getIndirectSymViaGOTPCRel(
@@ -126,8 +136,20 @@ bool RISCVELFTargetObjectFile::isConstantInSmallSection(
 MCSection *RISCVELFTargetObjectFile::getSectionForConstant(
     const DataLayout &DL, SectionKind Kind, const Constant *C,
     Align &Alignment) const {
-  if (isConstantInSmallSection(DL, C))
-    return SmallDataSection;
+  if (isConstantInSmallSection(DL, C)) {
+    if (Kind.isMergeableConst4())
+      return SmallROData4Section;
+    else if (Kind.isMergeableConst8())
+      return SmallROData8Section;
+    else if (Kind.isMergeableConst16())
+      return SmallROData16Section;
+    else if (Kind.isMergeableConst32())
+      return SmallROData32Section;
+    else
+      // LLVM only generate up to .rodata.cst32, and use .rodata section if more
+      // than 32 bytes, so just use .srodata here.
+      return SmallRODataSection;
+  }
 
   // Otherwise, we work the same as ELF.
   return TargetLoweringObjectFileELF::getSectionForConstant(DL, Kind, C,
diff --git a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.h b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.h
index 0910fbd3d95041..05e61ac874abba 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.h
+++ b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.h
@@ -16,6 +16,11 @@ namespace llvm {
 /// This implementation is used for RISC-V ELF targets.
 class RISCVELFTargetObjectFile : public TargetLoweringObjectFileELF {
   MCSection *SmallDataSection;
+  MCSection *SmallRODataSection;
+  MCSection *SmallROData4Section;
+  MCSection *SmallROData8Section;
+  MCSection *SmallROData16Section;
+  MCSection *SmallROData32Section;
   MCSection *SmallBSSSection;
   unsigned SSThreshold = 8;
 
diff --git a/llvm/test/CodeGen/RISCV/srodata.ll b/llvm/test/CodeGen/RISCV/srodata.ll
new file mode 100644
index 00000000000000..1d5bd904f233fe
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/srodata.ll
@@ -0,0 +1,47 @@
+; RUN: sed 's/SMALL_DATA_LIMIT/0/g' %s | \
+; RUN:   llc -mtriple=riscv32 -mattr=+d | \
+; RUN:   FileCheck -check-prefix=CHECK-SDL-0 %s
+; RUN: sed 's/SMALL_DATA_LIMIT/0/g' %s | \
+; RUN:   llc -mtriple=riscv64 -mattr=+d | \
+; RUN:   FileCheck -check-prefix=CHECK-SDL-0 %s
+; RUN: sed 's/SMALL_DATA_LIMIT/4/g' %s | \
+; RUN:   llc -mtriple=riscv32 -mattr=+d | \
+; RUN:   FileCheck -check-prefix=CHECK-SDL-4 %s
+; RUN: sed 's/SMALL_DATA_LIMIT/4/g' %s | \
+; RUN:   llc -mtriple=riscv64 -mattr=+d | \
+; RUN:   FileCheck -check-prefix=CHECK-SDL-4 %s
+; RUN: sed 's/SMALL_DATA_LIMIT/8/g' %s | \
+; RUN:   llc -mtriple=riscv32 -mattr=+d | \
+; RUN:   FileCheck -check-prefix=CHECK-SDL-8 %s
+; RUN: sed 's/SMALL_DATA_LIMIT/8/g' %s | \
+; RUN:   llc -mtriple=riscv64 -mattr=+d | \
+; RUN:   FileCheck -check-prefix=CHECK-SDL-8 %s
+; RUN: sed 's/SMALL_DATA_LIMIT/16/g' %s | \
+; RUN:   llc -mtriple=riscv32 -mattr=+d | \
+; RUN:   FileCheck -check-prefix=CHECK-SDL-16 %s
+; RUN: sed 's/SMALL_DATA_LIMIT/16/g' %s | \
+; RUN:   llc -mtriple=riscv64 -mattr=+d | \
+; RUN:   FileCheck -check-prefix=CHECK-SDL-16 %s
+
+define dso_local float @foof() {
+entry:
+  ret float 0x400A08ACA0000000
+}
+
+define dso_local double @foo() {
+entry:
+  ret double 0x400A08AC91C3E242
+}
+
+!llvm.module.flags = !{!0}
+
+!0 = !{i32 8, !"SmallDataLimit", i32 SMALL_DATA_LIMIT}
+
+; CHECK-SDL-0-NOT:    .section        .srodata.cst4
+; CHECK-SDL-0-NOT:    .section        .srodata.cst8
+; CHECK-SDL-4:        .section        .srodata.cst4
+; CHECK-SDL-4-NOT:    .section        .srodata.cst8
+; CHECK-SDL-8:        .section        .srodata.cst4
+; CHECK-SDL-8:        .section        .srodata.cst8
+; CHECK-SDL-16:       .section        .srodata.cst4
+; CHECK-SDL-16:       .section        .srodata.cst8



More information about the llvm-commits mailing list