[llvm] 1feb00a - [X86] Introduce a large data threshold for the medium code model

Arthur Eubanks via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 14 15:09:40 PDT 2023


Author: Arthur Eubanks
Date: 2023-09-14T15:09:25-07:00
New Revision: 1feb00a28c9fdab162da08a15fcc9d088a36c352

URL: https://github.com/llvm/llvm-project/commit/1feb00a28c9fdab162da08a15fcc9d088a36c352
DIFF: https://github.com/llvm/llvm-project/commit/1feb00a28c9fdab162da08a15fcc9d088a36c352.diff

LOG: [X86] Introduce a large data threshold for the medium code model

Currently clang's medium code model treats all data as large, putting them in a large data section and using more expensive instruction sequences to access them.

Following gcc's -mlarge-data-threshold, which allows putting data under a certain size in a normal data section as opposed to a large data section. This allows using cheaper code sequences to access some portion of data in the binary (which will be implemented in LLVM in a future patch).

And under the medium codel mode, only put data above the large data threshold into large data sections, not all data.

Reviewed By: MaskRay, rnk

Differential Revision: https://reviews.llvm.org/D149288

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/CommandFlags.h
    llvm/include/llvm/Target/TargetMachine.h
    llvm/lib/CodeGen/CommandFlags.cpp
    llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/lib/Target/TargetMachine.cpp
    llvm/test/CodeGen/X86/code-model-elf-sections.ll
    llvm/tools/llc/llc.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/CommandFlags.h b/llvm/include/llvm/CodeGen/CommandFlags.h
index fa10ddd4447dc99..732d6d0211c9969 100644
--- a/llvm/include/llvm/CodeGen/CommandFlags.h
+++ b/llvm/include/llvm/CodeGen/CommandFlags.h
@@ -45,6 +45,9 @@ ThreadModel::Model getThreadModel();
 CodeModel::Model getCodeModel();
 std::optional<CodeModel::Model> getExplicitCodeModel();
 
+uint64_t getLargeDataThreshold();
+std::optional<uint64_t> getExplicitLargeDataThreshold();
+
 llvm::ExceptionHandling getExceptionModel();
 
 std::optional<CodeGenFileType> getExplicitFileType();

diff  --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h
index 38070f42b495746..f3fcb22ddefb1d8 100644
--- a/llvm/include/llvm/Target/TargetMachine.h
+++ b/llvm/include/llvm/Target/TargetMachine.h
@@ -100,6 +100,7 @@ class TargetMachine {
 
   Reloc::Model RM = Reloc::Static;
   CodeModel::Model CMModel = CodeModel::Small;
+  uint64_t LargeDataThreshold = 0;
   CodeGenOptLevel OptLevel = CodeGenOptLevel::Default;
 
   /// Contains target specific asm information.
@@ -238,7 +239,8 @@ class TargetMachine {
   /// Set the code model.
   void setCodeModel(CodeModel::Model CM) { CMModel = CM; }
 
-  bool isLargeData() const;
+  void setLargeDataThreshold(uint64_t LDT) { LargeDataThreshold = LDT; }
+  bool isLargeData(const GlobalVariable *GV) const;
 
   bool isPositionIndependent() const;
 

diff  --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp
index 59bd6dad3b6ff1d..1eba979f83db0c9 100644
--- a/llvm/lib/CodeGen/CommandFlags.cpp
+++ b/llvm/lib/CodeGen/CommandFlags.cpp
@@ -58,6 +58,7 @@ CGLIST(std::string, MAttrs)
 CGOPT_EXP(Reloc::Model, RelocModel)
 CGOPT(ThreadModel::Model, ThreadModel)
 CGOPT_EXP(CodeModel::Model, CodeModel)
+CGOPT_EXP(uint64_t, LargeDataThreshold)
 CGOPT(ExceptionHandling, ExceptionModel)
 CGOPT_EXP(CodeGenFileType, FileType)
 CGOPT(FramePointerKind, FramePointerUsage)
@@ -162,6 +163,12 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
                  clEnumValN(CodeModel::Large, "large", "Large code model")));
   CGBINDOPT(CodeModel);
 
+  static cl::opt<uint64_t> LargeDataThreshold(
+      "large-data-threshold",
+      cl::desc("Choose large data threshold for x86_64 medium code model"),
+      cl::init(0));
+  CGBINDOPT(LargeDataThreshold);
+
   static cl::opt<ExceptionHandling> ExceptionModel(
       "exception-model", cl::desc("exception model"),
       cl::init(ExceptionHandling::None),

diff  --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 55fb522554fad25..622c8addc548f4f 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -651,8 +651,8 @@ getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind,
     Name += utostr(EntrySize);
   } else {
     bool IsLarge = false;
-    if (isa<GlobalVariable>(GO))
-      IsLarge = TM.isLargeData();
+    if (auto *GV = dyn_cast<GlobalVariable>(GO))
+      IsLarge = TM.isLargeData(GV);
     Name = getSectionPrefixForGlobal(Kind, IsLarge);
   }
 
@@ -855,8 +855,8 @@ static MCSectionELF *selectELFSectionForGlobal(
     Group = C->getName();
     IsComdat = C->getSelectionKind() == Comdat::Any;
   }
-  if (isa<GlobalVariable>(GO)) {
-    if (TM.isLargeData()) {
+  if (auto *GV = dyn_cast<GlobalVariable>(GO)) {
+    if (TM.isLargeData(GV)) {
       assert(TM.getTargetTriple().getArch() == Triple::x86_64);
       Flags |= ELF::SHF_X86_64_LARGE;
     }

diff  --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp
index 0b4a251e5414e2a..2119167deaed484 100644
--- a/llvm/lib/Target/TargetMachine.cpp
+++ b/llvm/lib/Target/TargetMachine.cpp
@@ -39,14 +39,16 @@ TargetMachine::TargetMachine(const Target &T, StringRef DataLayoutString,
 
 TargetMachine::~TargetMachine() = default;
 
-bool TargetMachine::isLargeData() const {
+bool TargetMachine::isLargeData(const GlobalVariable *GV) const {
   if (getTargetTriple().getArch() != Triple::x86_64)
     return false;
   // Large data under the large code model still needs to be thought about, so
   // restrict this to medium.
   if (getCodeModel() != CodeModel::Medium)
     return false;
-  return true;
+  const DataLayout &DL = GV->getParent()->getDataLayout();
+  uint64_t Size = DL.getTypeSizeInBits(GV->getValueType()) / 8;
+  return Size == 0 || Size > LargeDataThreshold;
 }
 
 bool TargetMachine::isPositionIndependent() const {

diff  --git a/llvm/test/CodeGen/X86/code-model-elf-sections.ll b/llvm/test/CodeGen/X86/code-model-elf-sections.ll
index 24c672d10e95a45..941c4dd1f8c9851 100644
--- a/llvm/test/CodeGen/X86/code-model-elf-sections.ll
+++ b/llvm/test/CodeGen/X86/code-model-elf-sections.ll
@@ -2,6 +2,10 @@
 ; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SMALL
 ; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=medium -o %t
 ; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=LARGE
+; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=medium -large-data-threshold=79 -o %t
+; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=LARGE
+; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=medium -large-data-threshold=80 -o %t
+; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SMALL
 ; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=large -o %t
 ; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SMALL
 

diff  --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp
index e6fdf631e791289..0ca06cda20b6e66 100644
--- a/llvm/tools/llc/llc.cpp
+++ b/llvm/tools/llc/llc.cpp
@@ -591,6 +591,8 @@ static int compileModule(char **argv, LLVMContext &Context) {
     std::optional<CodeModel::Model> CM_IR = M->getCodeModel();
     if (!CM && CM_IR)
       Target->setCodeModel(*CM_IR);
+    if (std::optional<uint64_t> LDT = codegen::getExplicitLargeDataThreshold())
+      Target->setLargeDataThreshold(*LDT);
   } else {
     TheTriple = Triple(Triple::normalize(TargetTriple));
     if (TheTriple.getTriple().empty())


        


More information about the llvm-commits mailing list