LLVM 22.0.0git
MipsTargetObjectFile.cpp
Go to the documentation of this file.
1//===-- MipsTargetObjectFile.cpp - Mips Object Files ----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "MipsSubtarget.h"
12#include "MipsTargetMachine.h"
14#include "llvm/IR/DataLayout.h"
16#include "llvm/MC/MCContext.h"
20using namespace llvm;
21
23SSThreshold("mips-ssection-threshold", cl::Hidden,
24 cl::desc("Small data and bss section threshold size (default=8)"),
25 cl::init(8));
26
27static cl::opt<bool>
28LocalSData("mlocal-sdata", cl::Hidden,
29 cl::desc("MIPS: Use gp_rel for object-local data."),
30 cl::init(true));
31
32static cl::opt<bool>
33ExternSData("mextern-sdata", cl::Hidden,
34 cl::desc("MIPS: Use gp_rel for data that is not defined by the "
35 "current object."),
36 cl::init(true));
37
38static cl::opt<bool>
39EmbeddedData("membedded-data", cl::Hidden,
40 cl::desc("MIPS: Try to allocate variables in the following"
41 " sections if possible: .rodata, .sdata, .data ."),
42 cl::init(false));
43
46
47 SmallDataSection = getContext().getELFSection(
48 ".sdata", ELF::SHT_PROGBITS,
50
51 SmallBSSSection = getContext().getELFSection(".sbss", ELF::SHT_NOBITS,
54 this->TM = &static_cast<const MipsTargetMachine &>(TM);
55}
56
57// A address must be loaded from a small section if its size is less than the
58// small section size threshold. Data in this section must be addressed using
59// gp_rel operator.
61 // gcc has traditionally not treated zero-sized objects as small data, so this
62 // is effectively part of the ABI.
63 return Size > 0 && Size <= SSThreshold;
64}
65
66/// Return true if this global address should be placed into small data/bss
67/// section.
68bool MipsTargetObjectFile::IsGlobalInSmallSection(
69 const GlobalObject *GO, const TargetMachine &TM) const {
70 // We first check the case where global is a declaration, because finding
71 // section kind using getKindForGlobal() is only allowed for global
72 // definitions.
74 return IsGlobalInSmallSectionImpl(GO, TM);
75
76 return IsGlobalInSmallSection(GO, TM, getKindForGlobal(GO, TM));
77}
78
79/// Return true if this global address should be placed into small data/bss
80/// section.
81bool MipsTargetObjectFile::
82IsGlobalInSmallSection(const GlobalObject *GO, const TargetMachine &TM,
83 SectionKind Kind) const {
84 return IsGlobalInSmallSectionImpl(GO, TM) &&
85 (Kind.isData() || Kind.isBSS() || Kind.isCommon() ||
86 Kind.isReadOnly());
87}
88
89/// Return true if this global address should be placed into small data/bss
90/// section. This method does all the work, except for checking the section
91/// kind.
92bool MipsTargetObjectFile::
93IsGlobalInSmallSectionImpl(const GlobalObject *GO,
94 const TargetMachine &TM) const {
95 const MipsSubtarget &Subtarget =
96 *static_cast<const MipsTargetMachine &>(TM).getSubtargetImpl();
97
98 // Return if small section is not available.
99 if (!Subtarget.useSmallSection())
100 return false;
101
102 // Only global variables, not functions.
104 if (!GVA)
105 return false;
106
107 // If the variable has an explicit section, it is placed in that section but
108 // it's addressing mode may change.
109 if (GVA->hasSection()) {
110 StringRef Section = GVA->getSection();
111
112 // Explicitly placing any variable in the small data section overrides
113 // the global -G value.
114 if (Section == ".sdata" || Section == ".sbss")
115 return true;
116
117 // Otherwise reject accessing it through the gp pointer. There are some
118 // historic cases which GCC doesn't appear to respect any more. These
119 // are .lit4, .lit8 and .srdata. For the moment reject these as well.
120 return false;
121 }
122
123 // Enforce -mlocal-sdata.
124 if (!LocalSData && GVA->hasLocalLinkage())
125 return false;
126
127 // Enforce -mextern-sdata.
128 if (!ExternSData && ((GVA->hasExternalLinkage() && GVA->isDeclaration()) ||
129 GVA->hasCommonLinkage()))
130 return false;
131
132 // Enforce -membedded-data.
133 if (EmbeddedData && GVA->isConstant())
134 return false;
135
136 Type *Ty = GVA->getValueType();
137
138 // It is possible that the type of the global is unsized, i.e. a declaration
139 // of a extern struct. In this case don't presume it is in the small data
140 // section. This happens e.g. when building the FreeBSD kernel.
141 if (!Ty->isSized())
142 return false;
143
144 return IsInSmallSection(
146}
147
149 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
150 // TODO: Could also support "weak" symbols as well with ".gnu.linkonce.s.*"
151 // sections?
152
153 // Handle Small Section classification here.
154 if (Kind.isBSS() && IsGlobalInSmallSection(GO, TM, Kind))
155 return SmallBSSSection;
156 if (Kind.isData() && IsGlobalInSmallSection(GO, TM, Kind))
157 return SmallDataSection;
158 if (Kind.isReadOnly() && IsGlobalInSmallSection(GO, TM, Kind))
159 return SmallDataSection;
160
161 // Otherwise, we work the same as ELF.
163}
164
165/// Return true if this constant should be placed into small data section.
167 const DataLayout &DL, const Constant *CN, const TargetMachine &TM) const {
168 return (static_cast<const MipsTargetMachine &>(TM)
169 .getSubtargetImpl()
170 ->useSmallSection() &&
171 LocalSData && IsInSmallSection(DL.getTypeAllocSize(CN->getType())));
172}
173
174/// Return true if this constant should be placed into small data section.
176 SectionKind Kind,
177 const Constant *C,
178 Align &Alignment) const {
179 if (IsConstantInSmallSection(DL, C, *TM))
180 return SmallDataSection;
181
182 // Otherwise, we work the same as ELF.
184 Alignment);
185}
186
187const MCExpr *
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< unsigned > SSThreshold("lanai-ssection-threshold", cl::Hidden, cl::desc("Small data and bss section threshold size (default=0)"), cl::init(0))
static cl::opt< bool > ExternSData("mextern-sdata", cl::Hidden, cl::desc("MIPS: Use gp_rel for data that is not defined by the " "current object."), cl::init(true))
static cl::opt< unsigned > SSThreshold("mips-ssection-threshold", cl::Hidden, cl::desc("Small data and bss section threshold size (default=8)"), cl::init(8))
static cl::opt< bool > LocalSData("mlocal-sdata", cl::Hidden, cl::desc("MIPS: Use gp_rel for object-local data."), cl::init(true))
static bool IsInSmallSection(uint64_t Size)
static cl::opt< bool > EmbeddedData("membedded-data", cl::Hidden, cl::desc("MIPS: Try to allocate variables in the following" " sections if possible: .rodata, .sdata, .data ."), cl::init(false))
This is an important base class in LLVM.
Definition Constant.h:43
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:63
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
StringRef getSection() const
Get the custom section of this global if it has one.
bool hasSection() const
Check if this global has a custom object file section.
bool hasExternalLinkage() const
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:316
bool hasLocalLinkage() const
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Definition Globals.cpp:132
bool hasCommonLinkage() const
bool hasAvailableExternallyLinkage() const
Type * getValueType() const
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:343
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Context object for machine code objects.
Definition MCContext.h:83
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition MCContext.h:549
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
MCContext & getContext() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition MCSection.h:496
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:743
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:214
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
bool useSmallSection() const
MCSection * getSectionForConstant(const DataLayout &DL, SectionKind Kind, const Constant *C, Align &Alignment) const override
Return true if this constant should be placed into small data section.
MCSection * SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override
const MCExpr * getDebugThreadLocalSymbol(const MCSymbol *Sym) const override
Describe a TLS variable address within debug info.
bool IsConstantInSmallSection(const DataLayout &DL, const Constant *CN, const TargetMachine &TM) const
Return true if this constant should be placed into small data section.
void Initialize(MCContext &Ctx, const TargetMachine &TM) override
This method must be called before any actual lowering is done.
SectionKind - This is a simple POD value that classifies the properties of a section.
Definition SectionKind.h:22
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
void Initialize(MCContext &Ctx, const TargetMachine &TM) override
This method must be called before any actual lowering is done.
MCSection * getSectionForConstant(const DataLayout &DL, SectionKind Kind, const Constant *C, Align &Alignment) const override
Given a constant with the SectionKind, return a section that it should be placed in.
MCSection * SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override
static SectionKind getKindForGlobal(const GlobalObject *GO, const TargetMachine &TM)
Classify the specified global variable into a set of target independent categories embodied in Sectio...
Primary interface to the complete machine description for the target machine.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition Type.h:311
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:256
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ SHT_PROGBITS
Definition ELF.h:1140
@ SHT_NOBITS
Definition ELF.h:1147
@ SHF_ALLOC
Definition ELF.h:1240
@ SHF_MIPS_GPREL
Definition ELF.h:1323
@ SHF_WRITE
Definition ELF.h:1237
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39