aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/Lanai/LanaiTargetObjectFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Lanai/LanaiTargetObjectFile.cpp')
-rw-r--r--lib/Target/Lanai/LanaiTargetObjectFile.cpp51
1 files changed, 30 insertions, 21 deletions
diff --git a/lib/Target/Lanai/LanaiTargetObjectFile.cpp b/lib/Target/Lanai/LanaiTargetObjectFile.cpp
index 4048c8535215b..7475dbd68ae49 100644
--- a/lib/Target/Lanai/LanaiTargetObjectFile.cpp
+++ b/lib/Target/Lanai/LanaiTargetObjectFile.cpp
@@ -49,22 +49,25 @@ static bool isInSmallSection(uint64_t Size) {
// Return true if this global address should be placed into small data/bss
// section.
bool LanaiTargetObjectFile::isGlobalInSmallSection(
- const GlobalValue *GV, const TargetMachine &TM) const {
+ const GlobalObject *GO, const TargetMachine &TM) const {
+ if (GO == nullptr)
+ return false;
+
// We first check the case where global is a declaration, because finding
// section kind using getKindForGlobal() is only allowed for global
// definitions.
- if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage())
- return isGlobalInSmallSectionImpl(GV, TM);
+ if (GO->isDeclaration() || GO->hasAvailableExternallyLinkage())
+ return isGlobalInSmallSectionImpl(GO, TM);
- return isGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM));
+ return isGlobalInSmallSection(GO, TM, getKindForGlobal(GO, TM));
}
// Return true if this global address should be placed into small data/bss
// section.
-bool LanaiTargetObjectFile::isGlobalInSmallSection(const GlobalValue *GV,
+bool LanaiTargetObjectFile::isGlobalInSmallSection(const GlobalObject *GO,
const TargetMachine &TM,
SectionKind Kind) const {
- return (isGlobalInSmallSectionImpl(GV, TM) &&
+ return (isGlobalInSmallSectionImpl(GO, TM) &&
(Kind.isData() || Kind.isBSS() || Kind.isCommon()));
}
@@ -72,37 +75,43 @@ bool LanaiTargetObjectFile::isGlobalInSmallSection(const GlobalValue *GV,
// section. This method does all the work, except for checking the section
// kind.
bool LanaiTargetObjectFile::isGlobalInSmallSectionImpl(
- const GlobalValue *GV, const TargetMachine & /*TM*/) const {
+ const GlobalObject *GO, const TargetMachine &TM) const {
// Only global variables, not functions.
- const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV);
+ const auto *GVA = dyn_cast<GlobalVariable>(GO);
if (!GVA)
return false;
- if (GV->hasLocalLinkage())
+ // Global values placed in sections starting with .ldata do not fit in
+ // 21-bits, so always use large memory access for them. FIXME: This is a
+ // workaround for a tool limitation.
+ if (GVA->getSection().startswith(".ldata"))
+ return false;
+
+ if (TM.getCodeModel() == CodeModel::Small)
+ return true;
+
+ if (GVA->hasLocalLinkage())
return false;
- if (((GV->hasExternalLinkage() && GV->isDeclaration()) ||
- GV->hasCommonLinkage()))
+ if (((GVA->hasExternalLinkage() && GVA->isDeclaration()) ||
+ GVA->hasCommonLinkage()))
return false;
- Type *Ty = GV->getType()->getElementType();
+ Type *Ty = GVA->getValueType();
return isInSmallSection(
- GV->getParent()->getDataLayout().getTypeAllocSize(Ty));
+ GVA->getParent()->getDataLayout().getTypeAllocSize(Ty));
}
-MCSection *
-LanaiTargetObjectFile::SelectSectionForGlobal(const GlobalValue *GV,
- SectionKind Kind, Mangler &Mang,
- const TargetMachine &TM) const {
+MCSection *LanaiTargetObjectFile::SelectSectionForGlobal(
+ const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
// Handle Small Section classification here.
- if (Kind.isBSS() && isGlobalInSmallSection(GV, TM, Kind))
+ if (Kind.isBSS() && isGlobalInSmallSection(GO, TM, Kind))
return SmallBSSSection;
- if (Kind.isData() && isGlobalInSmallSection(GV, TM, Kind))
+ if (Kind.isData() && isGlobalInSmallSection(GO, TM, Kind))
return SmallDataSection;
// Otherwise, we work the same as ELF.
- return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,
- TM);
+ return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM);
}
/// Return true if this constant should be placed into small data section.