Skip to content

Commit 00647a1

Browse files
authored
[X86] Don't respect large data threshold for globals with an explicit section (#78348)
If multiple globals are placed in an explicit section, there's a chance that the large data threshold will cause the different globals to be inconsistent in whether they're large or small. Mixing sections with mismatched large section flags can cause undesirable issues like increased relocation pressure because there may be 32-bit references to the section in some TUs, but the section is considered large since input section flags are unioned and other TUs added the large section flag. An explicit code model on the global still overrides the decision. We can do this for globals without any references to them, like what we did with asan_globals in #74514. If we have some precompiled small code model files where asan_globals is not considered large mixed with medium/large code model files, that's ok because the section is considered large and placed farther. However, overriding the code model for globals in some TUs but not others and having references to them from code will still result in the above undesired behavior. This mitigates a whole class of mismatched large section flag issues like what #77986 was trying to fix. This ends up not adding the SHF_X86_64_LARGE section flag on explicit sections in the medium/large code model. This is ok for the large code model since all references from large text must use 64-bit relocations anyway.
1 parent 1b60ddd commit 00647a1

File tree

2 files changed

+20
-22
lines changed

2 files changed

+20
-22
lines changed

llvm/lib/Target/TargetMachine.cpp

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,31 +58,29 @@ bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {
5858
if (GV->isThreadLocal())
5959
return false;
6060

61-
// We should properly mark well-known section name prefixes as small/large,
62-
// because otherwise the output section may have the wrong section flags and
63-
// the linker will lay it out in an unexpected way.
64-
StringRef Name = GV->getSection();
65-
if (!Name.empty()) {
66-
auto IsPrefix = [&](StringRef Prefix) {
67-
StringRef S = Name;
68-
return S.consume_front(Prefix) && (S.empty() || S[0] == '.');
69-
};
70-
if (IsPrefix(".bss") || IsPrefix(".data") || IsPrefix(".rodata"))
71-
return false;
72-
if (IsPrefix(".lbss") || IsPrefix(".ldata") || IsPrefix(".lrodata"))
73-
return true;
74-
}
75-
7661
// For x86-64, we treat an explicit GlobalVariable small code model to mean
7762
// that the global should be placed in a small section, and ditto for large.
78-
// Well-known section names above take precedence for correctness.
7963
if (auto CM = GV->getCodeModel()) {
8064
if (*CM == CodeModel::Small)
8165
return false;
8266
if (*CM == CodeModel::Large)
8367
return true;
8468
}
8569

70+
// Treat all globals in explicit sections as small, except for the standard
71+
// large sections of .lbss, .ldata, .lrodata. This reduces the risk of linking
72+
// together small and large sections, resulting in small references to large
73+
// data sections. The code model attribute overrides this above.
74+
if (GV->hasSection()) {
75+
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");
81+
}
82+
83+
// Respect large data threshold for medium and large code models.
8684
if (getCodeModel() == CodeModel::Medium ||
8785
getCodeModel() == CodeModel::Large) {
8886
if (!GV->getValueType()->isSized())

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,13 @@
5555

5656
; LARGE: .data {{.*}} WA {{.*}}
5757
; LARGE: .data.x {{.*}} WA {{.*}}
58-
; LARGE: .data0 {{.*}} WAl {{.*}}
58+
; LARGE: .data0 {{.*}} WA {{.*}}
5959
; LARGE: .ldata {{.*}} WAl {{.*}}
6060
; LARGE: .ldata.x {{.*}} WAl {{.*}}
61-
; LARGE: .ldata0 {{.*}} WAl {{.*}}
61+
; LARGE: .ldata0 {{.*}} WA {{.*}}
6262
; LARGE: force_small {{.*}} WA {{.*}}
6363
; LARGE: force_large {{.*}} WAl {{.*}}
64-
; LARGE: foo {{.*}} WAl {{.*}}
64+
; LARGE: foo {{.*}} WA {{.*}}
6565
; LARGE: .bss {{.*}} WA {{.*}}
6666
; LARGE: .lbss {{.*}} WAl {{.*}}
6767
; LARGE: .rodata {{.*}} A {{.*}}
@@ -72,14 +72,14 @@
7272

7373
; LARGE-DS: .data {{.*}} WA {{.*}}
7474
; LARGE-DS: .data.x {{.*}} WA {{.*}}
75-
; LARGE-DS: .data0 {{.*}} WAl {{.*}}
75+
; LARGE-DS: .data0 {{.*}} WA {{.*}}
7676
; LARGE-DS: .ldata {{.*}} WAl {{.*}}
7777
; LARGE-DS: .ldata.x {{.*}} WAl {{.*}}
78-
; LARGE-DS: .ldata0 {{.*}} WAl {{.*}}
78+
; LARGE-DS: .ldata0 {{.*}} WA {{.*}}
7979
; LARGE-DS: .ldata.data {{.*}} WAl {{.*}}
8080
; LARGE-DS: force_small {{.*}} WA {{.*}}
8181
; LARGE-DS: force_large {{.*}} WAl {{.*}}
82-
; LARGE-DS: foo {{.*}} WAl {{.*}}
82+
; LARGE-DS: foo {{.*}} WA {{.*}}
8383
; LARGE-DS: .bss {{.*}} WA {{.*}}
8484
; LARGE-DS: .lbss.bss {{.*}} WAl {{.*}}
8585
; LARGE-DS: .rodata {{.*}} A {{.*}}

0 commit comments

Comments
 (0)