[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