Skip to content

Commit 1feb00a

Browse files
committed
[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
1 parent 5093413 commit 1feb00a

File tree

7 files changed

+27
-7
lines changed

7 files changed

+27
-7
lines changed

llvm/include/llvm/CodeGen/CommandFlags.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ ThreadModel::Model getThreadModel();
4545
CodeModel::Model getCodeModel();
4646
std::optional<CodeModel::Model> getExplicitCodeModel();
4747

48+
uint64_t getLargeDataThreshold();
49+
std::optional<uint64_t> getExplicitLargeDataThreshold();
50+
4851
llvm::ExceptionHandling getExceptionModel();
4952

5053
std::optional<CodeGenFileType> getExplicitFileType();

llvm/include/llvm/Target/TargetMachine.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ class TargetMachine {
100100

101101
Reloc::Model RM = Reloc::Static;
102102
CodeModel::Model CMModel = CodeModel::Small;
103+
uint64_t LargeDataThreshold = 0;
103104
CodeGenOptLevel OptLevel = CodeGenOptLevel::Default;
104105

105106
/// Contains target specific asm information.
@@ -238,7 +239,8 @@ class TargetMachine {
238239
/// Set the code model.
239240
void setCodeModel(CodeModel::Model CM) { CMModel = CM; }
240241

241-
bool isLargeData() const;
242+
void setLargeDataThreshold(uint64_t LDT) { LargeDataThreshold = LDT; }
243+
bool isLargeData(const GlobalVariable *GV) const;
242244

243245
bool isPositionIndependent() const;
244246

llvm/lib/CodeGen/CommandFlags.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ CGLIST(std::string, MAttrs)
5858
CGOPT_EXP(Reloc::Model, RelocModel)
5959
CGOPT(ThreadModel::Model, ThreadModel)
6060
CGOPT_EXP(CodeModel::Model, CodeModel)
61+
CGOPT_EXP(uint64_t, LargeDataThreshold)
6162
CGOPT(ExceptionHandling, ExceptionModel)
6263
CGOPT_EXP(CodeGenFileType, FileType)
6364
CGOPT(FramePointerKind, FramePointerUsage)
@@ -162,6 +163,12 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
162163
clEnumValN(CodeModel::Large, "large", "Large code model")));
163164
CGBINDOPT(CodeModel);
164165

166+
static cl::opt<uint64_t> LargeDataThreshold(
167+
"large-data-threshold",
168+
cl::desc("Choose large data threshold for x86_64 medium code model"),
169+
cl::init(0));
170+
CGBINDOPT(LargeDataThreshold);
171+
165172
static cl::opt<ExceptionHandling> ExceptionModel(
166173
"exception-model", cl::desc("exception model"),
167174
cl::init(ExceptionHandling::None),

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -651,8 +651,8 @@ getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind,
651651
Name += utostr(EntrySize);
652652
} else {
653653
bool IsLarge = false;
654-
if (isa<GlobalVariable>(GO))
655-
IsLarge = TM.isLargeData();
654+
if (auto *GV = dyn_cast<GlobalVariable>(GO))
655+
IsLarge = TM.isLargeData(GV);
656656
Name = getSectionPrefixForGlobal(Kind, IsLarge);
657657
}
658658

@@ -855,8 +855,8 @@ static MCSectionELF *selectELFSectionForGlobal(
855855
Group = C->getName();
856856
IsComdat = C->getSelectionKind() == Comdat::Any;
857857
}
858-
if (isa<GlobalVariable>(GO)) {
859-
if (TM.isLargeData()) {
858+
if (auto *GV = dyn_cast<GlobalVariable>(GO)) {
859+
if (TM.isLargeData(GV)) {
860860
assert(TM.getTargetTriple().getArch() == Triple::x86_64);
861861
Flags |= ELF::SHF_X86_64_LARGE;
862862
}

llvm/lib/Target/TargetMachine.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,16 @@ TargetMachine::TargetMachine(const Target &T, StringRef DataLayoutString,
3939

4040
TargetMachine::~TargetMachine() = default;
4141

42-
bool TargetMachine::isLargeData() const {
42+
bool TargetMachine::isLargeData(const GlobalVariable *GV) const {
4343
if (getTargetTriple().getArch() != Triple::x86_64)
4444
return false;
4545
// Large data under the large code model still needs to be thought about, so
4646
// restrict this to medium.
4747
if (getCodeModel() != CodeModel::Medium)
4848
return false;
49-
return true;
49+
const DataLayout &DL = GV->getParent()->getDataLayout();
50+
uint64_t Size = DL.getTypeSizeInBits(GV->getValueType()) / 8;
51+
return Size == 0 || Size > LargeDataThreshold;
5052
}
5153

5254
bool TargetMachine::isPositionIndependent() const {

llvm/test/CodeGen/X86/code-model-elf-sections.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SMALL
33
; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=medium -o %t
44
; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=LARGE
5+
; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=medium -large-data-threshold=79 -o %t
6+
; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=LARGE
7+
; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=medium -large-data-threshold=80 -o %t
8+
; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SMALL
59
; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=large -o %t
610
; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SMALL
711

llvm/tools/llc/llc.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,8 @@ static int compileModule(char **argv, LLVMContext &Context) {
591591
std::optional<CodeModel::Model> CM_IR = M->getCodeModel();
592592
if (!CM && CM_IR)
593593
Target->setCodeModel(*CM_IR);
594+
if (std::optional<uint64_t> LDT = codegen::getExplicitLargeDataThreshold())
595+
Target->setLargeDataThreshold(*LDT);
594596
} else {
595597
TheTriple = Triple(Triple::normalize(TargetTriple));
596598
if (TheTriple.getTriple().empty())

0 commit comments

Comments
 (0)