[llvm] [X86] Change how we treat functions with explicit sections as small/large (PR #88172)
Arthur Eubanks via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 16 11:20:21 PDT 2024
https://github.com/aeubanks updated https://github.com/llvm/llvm-project/pull/88172
>From 838f4b1abc42d2e50d4124876ebee6773d3adc4e Mon Sep 17 00:00:00 2001
From: Arthur Eubanks <aeubanks at google.com>
Date: Mon, 8 Apr 2024 16:40:19 -0600
Subject: [PATCH 1/2] [X86] Change how we treat functions with explicit
sections as small/large
Following #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 #87838 with a check for non-ELF platforms in
TargetMachine::isLargeGlobalValue(), otherwise MCJIT on Windows tests
fail.
---
llvm/lib/Target/TargetMachine.cpp | 23 ++++++++++++++-----
.../X86/code-model-elf-text-sections.ll | 23 +++++++++++++++++++
2 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp
index a7fe329b064ee1..4ae6a468df21f3 100644
--- a/llvm/lib/Target/TargetMachine.cpp
+++ b/llvm/lib/Target/TargetMachine.cpp
@@ -43,6 +43,9 @@ bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {
if (getTargetTriple().getArch() != Triple::x86_64)
return false;
+ if (!getTargetTriple().isOSBinFormatELF())
+ return getCodeModel() == CodeModel::Large;
+
auto *GO = GVal->getAliaseeObject();
// Be conservative if we can't find an underlying GlobalObject.
@@ -51,9 +54,20 @@ bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {
auto *GV = dyn_cast<GlobalVariable>(GO);
+ auto IsPrefix = [](StringRef Name, StringRef Prefix) {
+ return Name.consume_front(Prefix) && (Name.empty() || Name[0] == '.');
+ };
+
// Functions/GlobalIFuncs are only large under the large code model.
- if (!GV)
+ if (!GV) {
+ // Handle explicit sections as we do for GlobalVariables with an explicit
+ // section, see comments below.
+ if (GO->hasSection()) {
+ StringRef Name = GO->getSection();
+ return IsPrefix(Name, ".ltext");
+ }
return getCodeModel() == CodeModel::Large;
+ }
if (GV->isThreadLocal())
return false;
@@ -73,11 +87,8 @@ bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {
// data sections. The code model attribute overrides this above.
if (GV->hasSection()) {
StringRef Name = GV->getSection();
- auto IsPrefix = [&](StringRef Prefix) {
- StringRef S = Name;
- return S.consume_front(Prefix) && (S.empty() || S[0] == '.');
- };
- return IsPrefix(".lbss") || IsPrefix(".ldata") || IsPrefix(".lrodata");
+ return IsPrefix(Name, ".lbss") || IsPrefix(Name, ".ldata") ||
+ IsPrefix(Name, ".lrodata");
}
// Respect large data threshold for medium and large code models.
diff --git a/llvm/test/CodeGen/X86/code-model-elf-text-sections.ll b/llvm/test/CodeGen/X86/code-model-elf-text-sections.ll
index 016c9a4d7b8390..66a6fd37675427 100644
--- a/llvm/test/CodeGen/X86/code-model-elf-text-sections.ll
+++ b/llvm/test/CodeGen/X86/code-model-elf-text-sections.ll
@@ -13,9 +13,20 @@
; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=LARGE-DS
; SMALL: .text {{.*}} AX {{.*}}
+; SMALL: .ltext {{.*}} AXl {{.*}}
+; SMALL: .ltext.2 {{.*}} AXl {{.*}}
+; SMALL: .foo {{.*}} AX {{.*}}
; SMALL-DS: .text.func {{.*}} AX {{.*}}
+; SMALL-DS: .ltext {{.*}} AXl {{.*}}
+; SMALL-DS: .ltext.2 {{.*}} AXl {{.*}}
+; SMALL-DS: .foo {{.*}} AX {{.*}}
; LARGE: .ltext {{.*}} AXl {{.*}}
+; LARGE: .ltext.2 {{.*}} AXl {{.*}}
+; LARGE: .foo {{.*}} AX {{.*}}
; LARGE-DS: .ltext.func {{.*}} AXl {{.*}}
+; LARGE-DS: .ltext {{.*}} AXl {{.*}}
+; LARGE-DS: .ltext.2 {{.*}} AXl {{.*}}
+; LARGE-DS: .foo {{.*}} AX {{.*}}
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64--linux"
@@ -23,3 +34,15 @@ target triple = "x86_64--linux"
define void @func() {
ret void
}
+
+define void @ltext() section ".ltext" {
+ ret void
+}
+
+define void @ltext2() section ".ltext.2" {
+ ret void
+}
+
+define void @foo() section ".foo" {
+ ret void
+}
>From fa0655b3f3ddbb8d82232bdffd846615abc74e75 Mon Sep 17 00:00:00 2001
From: Arthur Eubanks <aeubanks at google.com>
Date: Tue, 16 Apr 2024 18:20:04 +0000
Subject: [PATCH 2/2] add comment
---
llvm/lib/Target/TargetMachine.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp
index 4ae6a468df21f3..8ddc742004292b 100644
--- a/llvm/lib/Target/TargetMachine.cpp
+++ b/llvm/lib/Target/TargetMachine.cpp
@@ -43,6 +43,9 @@ bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {
if (getTargetTriple().getArch() != Triple::x86_64)
return false;
+ // Remaining logic below is ELF-specific. For other object file formats where
+ // the large code model is mostly used for JIT compilation, just look at the
+ // code model.
if (!getTargetTriple().isOSBinFormatELF())
return getCodeModel() == CodeModel::Large;
More information about the llvm-commits
mailing list