Skip to content

Commit 4a3b51f

Browse files
aeubanksZentrik
authored andcommitted
[X86] Change how we treat functions with explicit sections as small/large (llvm#88172)
Following llvm#78348, we should treat functions with an explicit section as small, unless the section name is (or has the prefix) ".ltext". Clang emits global initializers into a ".text.startup" section on Linux. If we mix small/medium code model object files with large code model object files, we'll end up mixing sections with and without the large section flag. Reland of llvm#87838 with a check for non-ELF platforms in TargetMachine::isLargeGlobalValue(), otherwise MCJIT on Windows tests fail.
1 parent 223a288 commit 4a3b51f

File tree

2 files changed

+43
-6
lines changed

2 files changed

+43
-6
lines changed

llvm/lib/Target/TargetMachine.cpp

+20-6
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {
4343
if (getTargetTriple().getArch() != Triple::x86_64)
4444
return false;
4545

46+
// Remaining logic below is ELF-specific. For other object file formats where
47+
// the large code model is mostly used for JIT compilation, just look at the
48+
// code model.
49+
if (!getTargetTriple().isOSBinFormatELF())
50+
return getCodeModel() == CodeModel::Large;
51+
4652
auto *GO = GVal->getAliaseeObject();
4753

4854
// Be conservative if we can't find an underlying GlobalObject.
@@ -51,9 +57,20 @@ bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {
5157

5258
auto *GV = dyn_cast<GlobalVariable>(GO);
5359

60+
auto IsPrefix = [](StringRef Name, StringRef Prefix) {
61+
return Name.consume_front(Prefix) && (Name.empty() || Name[0] == '.');
62+
};
63+
5464
// Functions/GlobalIFuncs are only large under the large code model.
55-
if (!GV)
65+
if (!GV) {
66+
// Handle explicit sections as we do for GlobalVariables with an explicit
67+
// section, see comments below.
68+
if (GO->hasSection()) {
69+
StringRef Name = GO->getSection();
70+
return IsPrefix(Name, ".ltext");
71+
}
5672
return getCodeModel() == CodeModel::Large;
73+
}
5774

5875
if (GV->isThreadLocal())
5976
return false;
@@ -73,11 +90,8 @@ bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {
7390
// data sections. The code model attribute overrides this above.
7491
if (GV->hasSection()) {
7592
StringRef Name = GV->getSection();
76-
auto IsPrefix = [&](StringRef Prefix) {
77-
StringRef S = Name;
78-
return S.consume_front(Prefix) && (S.empty() || S[0] == '.');
79-
};
80-
return IsPrefix(".lbss") || IsPrefix(".ldata") || IsPrefix(".lrodata");
93+
return IsPrefix(Name, ".lbss") || IsPrefix(Name, ".ldata") ||
94+
IsPrefix(Name, ".lrodata");
8195
}
8296

8397
// Respect large data threshold for medium and large code models.

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

+23
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,36 @@
1313
; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=LARGE-DS
1414

1515
; SMALL: .text {{.*}} AX {{.*}}
16+
; SMALL: .ltext {{.*}} AXl {{.*}}
17+
; SMALL: .ltext.2 {{.*}} AXl {{.*}}
18+
; SMALL: .foo {{.*}} AX {{.*}}
1619
; SMALL-DS: .text.func {{.*}} AX {{.*}}
20+
; SMALL-DS: .ltext {{.*}} AXl {{.*}}
21+
; SMALL-DS: .ltext.2 {{.*}} AXl {{.*}}
22+
; SMALL-DS: .foo {{.*}} AX {{.*}}
1723
; LARGE: .ltext {{.*}} AXl {{.*}}
24+
; LARGE: .ltext.2 {{.*}} AXl {{.*}}
25+
; LARGE: .foo {{.*}} AX {{.*}}
1826
; LARGE-DS: .ltext.func {{.*}} AXl {{.*}}
27+
; LARGE-DS: .ltext {{.*}} AXl {{.*}}
28+
; LARGE-DS: .ltext.2 {{.*}} AXl {{.*}}
29+
; LARGE-DS: .foo {{.*}} AX {{.*}}
1930

2031
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2132
target triple = "x86_64--linux"
2233

2334
define void @func() {
2435
ret void
2536
}
37+
38+
define void @ltext() section ".ltext" {
39+
ret void
40+
}
41+
42+
define void @ltext2() section ".ltext.2" {
43+
ret void
44+
}
45+
46+
define void @foo() section ".foo" {
47+
ret void
48+
}

0 commit comments

Comments
 (0)