[X86] Use "l" prefix for data sections under medium/large code model

And also set the SHF_X86_64_LARGE section flag.

gcc only uses the "l" prefix and SHF_X86_64_LARGE in the medium code model for data larger than -mlarge-data-threshold. But it seems more consistent to use it in the large code model as well in case separate parts of the binary aren't compiled with the large code model and also have a .data/.bss/.rodata section.

Reviewed By: MaskRay, tkoeppe

Differential Revision: https://reviews.llvm.org/D148836
This commit is contained in:
Arthur Eubanks 2023-05-10 13:13:43 -07:00
parent 87acf6ddc7
commit 43249378da
4 changed files with 72 additions and 7 deletions

View File

@ -235,6 +235,8 @@ public:
/// Set the code model.
void setCodeModel(CodeModel::Model CM) { CMModel = CM; }
bool isLargeData() const;
bool isPositionIndependent() const;
bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const;

View File

@ -614,21 +614,21 @@ static unsigned getEntrySizeForKind(SectionKind Kind) {
/// Return the section prefix name used by options FunctionsSections and
/// DataSections.
static StringRef getSectionPrefixForGlobal(SectionKind Kind) {
static StringRef getSectionPrefixForGlobal(SectionKind Kind, bool IsLarge) {
if (Kind.isText())
return ".text";
if (Kind.isReadOnly())
return ".rodata";
return IsLarge ? ".lrodata" : ".rodata";
if (Kind.isBSS())
return ".bss";
return IsLarge ? ".lbss" : ".bss";
if (Kind.isThreadData())
return ".tdata";
if (Kind.isThreadBSS())
return ".tbss";
if (Kind.isData())
return ".data";
return IsLarge ? ".ldata" : ".data";
if (Kind.isReadOnlyWithRel())
return ".data.rel.ro";
return IsLarge ? ".ldata.rel.ro" : ".data.rel.ro";
llvm_unreachable("Unknown section kind");
}
@ -650,7 +650,10 @@ getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind,
Name = ".rodata.cst";
Name += utostr(EntrySize);
} else {
Name = getSectionPrefixForGlobal(Kind);
bool IsLarge = false;
if (isa<GlobalVariable>(GO))
IsLarge = TM.isLargeData();
Name = getSectionPrefixForGlobal(Kind, IsLarge);
}
bool HasPrefix = false;
@ -852,6 +855,12 @@ static MCSectionELF *selectELFSectionForGlobal(
Group = C->getName();
IsComdat = C->getSelectionKind() == Comdat::Any;
}
if (isa<GlobalVariable>(GO)) {
if (TM.isLargeData()) {
assert(TM.getTargetTriple().getArch() == Triple::x86_64);
Flags |= ELF::SHF_X86_64_LARGE;
}
}
// Get the section entry size based on the kind.
unsigned EntrySize = getEntrySizeForKind(Kind);
@ -2165,7 +2174,7 @@ static MCSectionWasm *selectWasmSectionForGlobal(
}
bool UniqueSectionNames = TM.getUniqueSectionNames();
SmallString<128> Name = getSectionPrefixForGlobal(Kind);
SmallString<128> Name = getSectionPrefixForGlobal(Kind, /*IsLarge=*/false);
if (const auto *F = dyn_cast<Function>(GO)) {
const auto &OptionalPrefix = F->getSectionPrefix();

View File

@ -21,6 +21,7 @@
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
using namespace llvm;
@ -38,6 +39,16 @@ TargetMachine::TargetMachine(const Target &T, StringRef DataLayoutString,
TargetMachine::~TargetMachine() = default;
bool TargetMachine::isLargeData() const {
if (getTargetTriple().getArch() != Triple::x86_64)
return false;
// Large data under the large code model still needs to be thought about, so
// restrict this to medium.
if (getCodeModel() != CodeModel::Medium)
return false;
return true;
}
bool TargetMachine::isPositionIndependent() const {
return getRelocationModel() == Reloc::PIC_;
}

View File

@ -0,0 +1,43 @@
; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=small -o %t
; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SMALL
; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=medium -o %t
; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=LARGE
; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=large -o %t
; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SMALL
; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=small -data-sections -o %t
; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SMALL-DS
; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=medium -data-sections -o %t
; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=LARGE-DS
; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=large -data-sections -o %t
; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SMALL-DS
; SMALL: .data {{.*}} WA {{.*}}
; SMALL: .bss {{.*}} WA {{.*}}
; SMALL: .rodata {{.*}} A {{.*}}
; SMALL: .data.rel.ro {{.*}} WA {{.*}}
; SMALL-DS: .data.data {{.*}} WA {{.*}}
; SMALL-DS: .bss.bss {{.*}} WA {{.*}}
; SMALL-DS: .rodata.rodata {{.*}} A {{.*}}
; SMALL-DS: .data.rel.ro.relro {{.*}} WA {{.*}}
; LARGE: .ldata {{.*}} WAl {{.*}}
; LARGE: .lbss {{.*}} WAl {{.*}}
; LARGE: .lrodata {{.*}} Al {{.*}}
; LARGE: .ldata.rel.ro {{.*}} WAl {{.*}}
; LARGE-DS: .ldata.data {{.*}} WAl {{.*}}
; LARGE-DS: .lbss.bss {{.*}} WAl {{.*}}
; LARGE-DS: .lrodata.rodata {{.*}} Al {{.*}}
; LARGE-DS: .ldata.rel.ro.relro {{.*}} WAl {{.*}}
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64--linux"
@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]
@bss = internal global [10 x i64] zeroinitializer
@rodata = internal constant [10 x i64] zeroinitializer
@relro = internal constant [10 x ptr] [ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func]
declare void @func()