LLVM 24.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"
13#include "llvm/IR/DataLayout.h"
15#include "llvm/MC/MCContext.h"
19using namespace llvm;
20
22SSThreshold("mips-ssection-threshold", cl::Hidden,
23 cl::desc("Small data and bss section threshold size (default=8)"),
24 cl::init(8));
25
26static cl::opt<bool>
27LocalSData("mlocal-sdata", cl::Hidden,
28 cl::desc("MIPS: Use gp_rel for object-local data."),
29 cl::init(true));
30
31static cl::opt<bool>
32ExternSData("mextern-sdata", cl::Hidden,
33 cl::desc("MIPS: Use gp_rel for data that is not defined by the "
34 "current object."),
35 cl::init(true));
36
37static cl::opt<bool>
38EmbeddedData("membedded-data", cl::Hidden,
39 cl::desc("MIPS: Try to allocate variables in the following"
40 " sections if possible: .rodata, .sdata, .data ."),
41 cl::init(false));
42
54
55// A address must be loaded from a small section if its size is less than the
56// small section size threshold. Data in this section must be addressed using
57// gp_rel operator.
59 // gcc has traditionally not treated zero-sized objects as small data, so this
60 // is effectively part of the ABI.
61 return Size > 0 && Size <= SSThreshold;
62}
63
64/// Return true if this global address should be placed into small data/bss
65/// section.
66bool MipsTargetObjectFile::IsGlobalInSmallSection(
67 const GlobalObject *GO) const {
68 // We first check the case where global is a declaration, because finding
69 // section kind using getKindForGlobal() is only allowed for global
70 // definitions.
72 return IsGlobalInSmallSectionImpl(GO);
73
74 return IsGlobalInSmallSection(GO, getKindForGlobal(GO, *TM));
75}
76
77/// Return true if this global address should be placed into small data/bss
78/// section.
79bool MipsTargetObjectFile::IsGlobalInSmallSection(const GlobalObject *GO,
80 SectionKind Kind) const {
81 return IsGlobalInSmallSectionImpl(GO) &&
82 (Kind.isData() || Kind.isBSS() || Kind.isCommon() ||
83 Kind.isReadOnly());
84}
85
86/// Return true if this global address should be placed into small data/bss
87/// section. This method does all the work, except for checking the section
88/// kind.
89bool MipsTargetObjectFile::IsGlobalInSmallSectionImpl(
90 const GlobalObject *GO) const {
91 // Only global variables, not functions.
93 if (!GVA)
94 return false;
95
96 // If the variable has an explicit section, it is placed in that section but
97 // it's addressing mode may change.
98 if (GVA->hasSection()) {
99 StringRef Section = GVA->getSection();
100
101 // Explicitly placing any variable in the small data section overrides
102 // the global -G value.
103 if (Section == ".sdata" || Section == ".sbss")
104 return true;
105
106 // Otherwise reject accessing it through the gp pointer. There are some
107 // historic cases which GCC doesn't appear to respect any more. These
108 // are .lit4, .lit8 and .srdata. For the moment reject these as well.
109 return false;
110 }
111
112 // Implicit global placement follows the default subtarget, independently of
113 // the features of the functions that reference the global. Explicit small
114 // sections above also allow GP-relative accesses from functions that enable
115 // them when the default subtarget does not.
116 if (!UseSmallSection)
117 return false;
118
119 // Enforce -mlocal-sdata.
120 if (!LocalSData && GVA->hasLocalLinkage())
121 return false;
122
123 // Enforce -mextern-sdata.
124 if (!ExternSData && ((GVA->hasExternalLinkage() && GVA->isDeclaration()) ||
125 GVA->hasCommonLinkage()))
126 return false;
127
128 // Enforce -membedded-data.
129 if (EmbeddedData && GVA->isConstant())
130 return false;
131
132 Type *Ty = GVA->getValueType();
133
134 // It is possible that the type of the global is unsized, i.e. a declaration
135 // of a extern struct. In this case don't presume it is in the small data
136 // section. This happens e.g. when building the FreeBSD kernel.
137 if (!Ty->isSized())
138 return false;
139
140 return IsInSmallSection(
142}
143
145 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
146 // TODO: Could also support "weak" symbols as well with ".gnu.linkonce.s.*"
147 // sections?
148
149 // Handle Small Section classification here.
150 if (IsGlobalInSmallSection(GO, Kind)) {
151 if (Kind.isBSS())
152 return SmallBSSSection;
153 if (Kind.isData() || Kind.isReadOnly())
154 return SmallDataSection;
155 }
156
157 // Otherwise, we work the same as ELF.
159}
160
161/// Return true if this constant should be placed into small data section.
163 const Constant *CN,
164 const Function *F) const {
165 bool UseSmallSection =
166 F ? TM->getSubtarget<MipsSubtarget>(*F).useSmallSection()
167 : this->UseSmallSection;
168 return UseSmallSection && CN && LocalSData &&
169 IsInSmallSection(DL.getTypeAllocSize(CN->getType()));
170}
171
172/// Return true if this constant should be placed into small data section.
174 const DataLayout &DL, SectionKind Kind, const Constant *C, Align &Alignment,
175 const Function *F) const {
177 return SmallDataSection;
178
179 // Otherwise, we work the same as ELF.
181 Alignment, F);
182}
183
184const MCExpr *
unsigned uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static cl::opt< unsigned > SSThreshold("lanai-ssection-threshold", cl::Hidden, cl::desc("Small data and bss section threshold size (default=0)"), cl::init(0))
#define F(x, y, z)
Definition MD5.cpp:54
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:64
LLVM_ABI 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:408
bool hasLocalLinkage() const
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Definition Globals.cpp:205
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:342
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:550
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:580
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:213
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
bool useSmallSection() const
bool IsConstantInSmallSection(const DataLayout &DL, const Constant *CN, const Function *F) const
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.
MCSection * getSectionForConstant(const DataLayout &DL, SectionKind Kind, const Constant *C, Align &Alignment, const Function *F) const override
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
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
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 Function *F) 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() const
Return true if it makes sense to take the size of this type.
Definition Type.h:321
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
@ SHF_ALLOC
Definition ELF.h:1259
@ SHF_MIPS_GPREL
Definition ELF.h:1342
@ SHF_WRITE
Definition ELF.h:1256
@ SHT_PROGBITS
Definition ELF.h:1157
@ SHT_NOBITS
Definition ELF.h:1164
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:643
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39