Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/Lanai/LanaiTargetObjectFile.cpp
35271 views
1
//
2
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3
// See https://llvm.org/LICENSE.txt for license information.
4
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5
//
6
//===----------------------------------------------------------------------===//
7
8
#include "LanaiTargetObjectFile.h"
9
10
#include "LanaiSubtarget.h"
11
#include "LanaiTargetMachine.h"
12
#include "llvm/BinaryFormat/ELF.h"
13
#include "llvm/IR/DataLayout.h"
14
#include "llvm/IR/DerivedTypes.h"
15
#include "llvm/IR/GlobalVariable.h"
16
#include "llvm/MC/MCContext.h"
17
#include "llvm/MC/MCSectionELF.h"
18
#include "llvm/Support/CommandLine.h"
19
#include "llvm/Target/TargetMachine.h"
20
21
using namespace llvm;
22
23
static cl::opt<unsigned> SSThreshold(
24
"lanai-ssection-threshold", cl::Hidden,
25
cl::desc("Small data and bss section threshold size (default=0)"),
26
cl::init(0));
27
28
void LanaiTargetObjectFile::Initialize(MCContext &Ctx,
29
const TargetMachine &TM) {
30
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
31
32
SmallDataSection = getContext().getELFSection(
33
".sdata", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
34
SmallBSSSection = getContext().getELFSection(".sbss", ELF::SHT_NOBITS,
35
ELF::SHF_WRITE | ELF::SHF_ALLOC);
36
}
37
38
// A address must be loaded from a small section if its size is less than the
39
// small section size threshold. Data in this section must be addressed using
40
// gp_rel operator.
41
static bool isInSmallSection(uint64_t Size) {
42
// gcc has traditionally not treated zero-sized objects as small data, so this
43
// is effectively part of the ABI.
44
return Size > 0 && Size <= SSThreshold;
45
}
46
47
// Return true if this global address should be placed into small data/bss
48
// section.
49
bool LanaiTargetObjectFile::isGlobalInSmallSection(
50
const GlobalObject *GO, const TargetMachine &TM) const {
51
if (GO == nullptr) return TM.getCodeModel() == CodeModel::Small;
52
53
// We first check the case where global is a declaration, because finding
54
// section kind using getKindForGlobal() is only allowed for global
55
// definitions.
56
if (GO->isDeclaration() || GO->hasAvailableExternallyLinkage())
57
return isGlobalInSmallSectionImpl(GO, TM);
58
59
return isGlobalInSmallSection(GO, TM, getKindForGlobal(GO, TM));
60
}
61
62
// Return true if this global address should be placed into small data/bss
63
// section.
64
bool LanaiTargetObjectFile::isGlobalInSmallSection(const GlobalObject *GO,
65
const TargetMachine &TM,
66
SectionKind Kind) const {
67
return isGlobalInSmallSectionImpl(GO, TM);
68
}
69
70
// Return true if this global address should be placed into small data/bss
71
// section. This method does all the work, except for checking the section
72
// kind.
73
bool LanaiTargetObjectFile::isGlobalInSmallSectionImpl(
74
const GlobalObject *GO, const TargetMachine &TM) const {
75
const auto *GVA = dyn_cast<GlobalVariable>(GO);
76
77
// If not a GlobalVariable, only consider the code model.
78
if (!GVA) return TM.getCodeModel() == CodeModel::Small;
79
80
// Global values placed in sections starting with .ldata do not fit in
81
// 21-bits, so always use large memory access for them. FIXME: This is a
82
// workaround for a tool limitation.
83
if (GVA->getSection().starts_with(".ldata"))
84
return false;
85
86
if (TM.getCodeModel() == CodeModel::Small)
87
return true;
88
89
if (GVA->hasLocalLinkage())
90
return false;
91
92
if (((GVA->hasExternalLinkage() && GVA->isDeclaration()) ||
93
GVA->hasCommonLinkage()))
94
return false;
95
96
Type *Ty = GVA->getValueType();
97
return isInSmallSection(
98
GVA->getDataLayout().getTypeAllocSize(Ty));
99
}
100
101
MCSection *LanaiTargetObjectFile::SelectSectionForGlobal(
102
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
103
// Handle Small Section classification here.
104
if (Kind.isBSS() && isGlobalInSmallSection(GO, TM, Kind))
105
return SmallBSSSection;
106
if (Kind.isData() && isGlobalInSmallSection(GO, TM, Kind))
107
return SmallDataSection;
108
109
// Otherwise, we work the same as ELF.
110
return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM);
111
}
112
113
/// Return true if this constant should be placed into small data section.
114
bool LanaiTargetObjectFile::isConstantInSmallSection(const DataLayout &DL,
115
const Constant *CN) const {
116
return isInSmallSection(DL.getTypeAllocSize(CN->getType()));
117
}
118
119
MCSection *LanaiTargetObjectFile::getSectionForConstant(
120
const DataLayout &DL, SectionKind Kind, const Constant *C,
121
Align &Alignment) const {
122
if (isConstantInSmallSection(DL, C))
123
return SmallDataSection;
124
125
// Otherwise, we work the same as ELF.
126
return TargetLoweringObjectFileELF::getSectionForConstant(DL, Kind, C,
127
Alignment);
128
}
129
130