[X86] Respect code_model when determining if a global is small/large#74498
[X86] Respect code_model when determining if a global is small/large#74498
Conversation
|
@llvm/pr-subscribers-backend-x86 Author: Arthur Eubanks (aeubanks) ChangesUsing the GlobalVariable code_model property added in #72077. code_model = "small" means the global should be treated as small regardless of the TargetMachine code model. Inferring small/large based on a known section name still takes precedence for correctness. The intention is to use this for globals that are accessed very infrequently but also take up a lot of space in the binary to mitigate relocation overflows. Prime examples are globals that go in "__llvm_prf_names" for coverage/PGO instrumented builds and "asan_globals" for ASan builds. Full diff: https://github.com/llvm/llvm-project/pull/74498.diff 2 Files Affected:
diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp
index 8a14334551b00..ff496d29b3912 100644
--- a/llvm/lib/Target/TargetMachine.cpp
+++ b/llvm/lib/Target/TargetMachine.cpp
@@ -66,6 +66,16 @@ bool TargetMachine::isLargeGlobalObject(const GlobalObject *GO) const {
return true;
}
+ // For x86-64, we treat an explicit GlobalVariable small code model to mean
+ // that the global should be placed in a small section, and ditto for large.
+ // Well-known section names above take precedence for correctness.
+ if (auto CM = GV->getCodeModel()) {
+ if (*CM == CodeModel::Small)
+ return false;
+ if (*CM == CodeModel::Large)
+ return true;
+ }
+
if (getCodeModel() == CodeModel::Medium ||
getCodeModel() == CodeModel::Large) {
const DataLayout &DL = GV->getParent()->getDataLayout();
diff --git a/llvm/test/CodeGen/X86/code-model-elf-sections.ll b/llvm/test/CodeGen/X86/code-model-elf-sections.ll
index f72880e172bdc..6c88791520413 100644
--- a/llvm/test/CodeGen/X86/code-model-elf-sections.ll
+++ b/llvm/test/CodeGen/X86/code-model-elf-sections.ll
@@ -24,6 +24,8 @@
; SMALL: .ldata {{.*}} WAl {{.*}}
; SMALL: .ldata.x {{.*}} WAl {{.*}}
; SMALL: .ldata0 {{.*}} WA {{.*}}
+; SMALL: force_small {{.*}} WA {{.*}}
+; SMALL: force_large {{.*}} WAl {{.*}}
; SMALL: foo {{.*}} WA {{.*}}
; SMALL: .bss {{.*}} WA {{.*}}
; SMALL: .lbss {{.*}} WAl {{.*}}
@@ -40,6 +42,8 @@
; SMALL-DS: .ldata.x {{.*}} WAl {{.*}}
; SMALL-DS: .ldata0 {{.*}} WA {{.*}}
; SMALL-DS: .data.data {{.*}} WA {{.*}}
+; SMALL-DS: force_small {{.*}} WA {{.*}}
+; SMALL-DS: force_large {{.*}} WAl {{.*}}
; SMALL-DS: foo {{.*}} WA {{.*}}
; SMALL-DS: .lbss {{.*}} WAl {{.*}}
; SMALL-DS: .bss.bss {{.*}} WA {{.*}}
@@ -55,6 +59,8 @@
; LARGE: .ldata {{.*}} WAl {{.*}}
; LARGE: .ldata.x {{.*}} WAl {{.*}}
; LARGE: .ldata0 {{.*}} WAl {{.*}}
+; LARGE: force_small {{.*}} WA {{.*}}
+; LARGE: force_large {{.*}} WAl {{.*}}
; LARGE: foo {{.*}} WAl {{.*}}
; LARGE: .bss {{.*}} WA {{.*}}
; LARGE: .lbss {{.*}} WAl {{.*}}
@@ -71,6 +77,8 @@
; LARGE-DS: .ldata.x {{.*}} WAl {{.*}}
; LARGE-DS: .ldata0 {{.*}} WAl {{.*}}
; LARGE-DS: .ldata.data {{.*}} WAl {{.*}}
+; LARGE-DS: force_small {{.*}} WA {{.*}}
+; LARGE-DS: force_large {{.*}} WAl {{.*}}
; LARGE-DS: foo {{.*}} WAl {{.*}}
; LARGE-DS: .bss {{.*}} WA {{.*}}
; LARGE-DS: .lbss.bss {{.*}} WAl {{.*}}
@@ -90,6 +98,9 @@ target triple = "x86_64--linux"
@ldata_with_explicit_section2 = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], section ".ldata.x"
@ldata_with_explicit_section0 = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], section ".ldata0"
@data = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0]
+@data_force_small = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], code_model "small", section "force_small"
+@data_force_large = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], code_model "large", section "force_large"
+@data_force_small_ldata = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], code_model "small", section ".ldata"
@foo_with_explicit_section = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], section "foo"
@bss_with_explicit_section = internal global [10 x i64] zeroinitializer, section ".bss"
@lbss_with_explicit_section = internal global [10 x i64] zeroinitializer, section ".lbss"
|
Using the GlobalVariable code_model property added in llvm#72077. code_model = "small" means the global should be treated as small regardless of the TargetMachine code model. code_model = "large" means the global should be treated as large regardless of the TargetMachine code model. Inferring small/large based on a known section name still takes precedence for correctness. The intention is to use this for globals that are accessed very infrequently but also take up a lot of space in the binary to mitigate relocation overflows. Prime examples are globals that go in "__llvm_prf_names" for coverage/PGO instrumented builds and "asan_globals" for ASan builds.
|
@heiher fyi |
We'd like to make the asan_globals section large to make it not contribute to relocation pressure since there are no direct PC32 references to it. Following llvm#74498, we can do that by marking the code model for the global explicitly large. Without this change, asan_globals gets placed between .data and .bss. With this change, it gets placed after .bss.
We'd like to make the asan_globals section large to make it not contribute to relocation pressure since there are no direct PC32 references to it. Following #74498, we can do that by marking the code model for the global explicitly large. Without this change, asan_globals gets placed between .data and .bss. With this change, it gets placed after .bss.
…l/large (llvm#74498)" This reverts commit ddebce7.
…l/large (llvm#74498)" This reverts commit ddebce7.
Using the GlobalVariable code_model property added in #72077.
code_model = "small" means the global should be treated as small regardless of the TargetMachine code model.
code_model = "large" means the global should be treated as large regardless of the TargetMachine code model.
Inferring small/large based on a known section name still takes precedence for correctness.
The intention is to use this for globals that are accessed very infrequently but also take up a lot of space in the binary to mitigate relocation overflows. Prime examples are globals that go in "__llvm_prf_names" for coverage/PGO instrumented builds and "asan_globals" for ASan builds.