LLVM 23.0.0git
RISCVTargetObjectFile.cpp
Go to the documentation of this file.
1//===-- RISCVTargetObjectFile.cpp - RISC-V Object Info --------------------===//
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 "RISCVTargetMachine.h"
13#include "llvm/IR/Mangler.h"
14#include "llvm/IR/Module.h"
15#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCValue.h"
18
19using namespace llvm;
20
25
27 const TargetMachine &TM) {
29
30 PLTPCRelativeSpecifier = ELF::R_RISCV_PLT32;
32
33 SmallDataSection = getContext().getELFSection(
35 SmallBSSSection = getContext().getELFSection(".sbss", ELF::SHT_NOBITS,
37 SmallRODataSection =
39 SmallROData4Section = getContext().getELFSection(
40 ".srodata.cst4", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 4);
41 SmallROData8Section = getContext().getELFSection(
42 ".srodata.cst8", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 8);
43 SmallROData16Section = getContext().getELFSection(
44 ".srodata.cst16", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 16);
45 SmallROData32Section = getContext().getELFSection(
46 ".srodata.cst32", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 32);
47}
48
50 const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV,
51 int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {
52 auto &Ctx = getContext();
53 const MCExpr *Res = MCSymbolRefExpr::create(Sym, Ctx);
55 Res, MCConstantExpr::create(Offset + MV.getConstant(), Ctx), Ctx);
56 return MCSpecifierExpr::create(Res, ELF::R_RISCV_GOT32_PCREL, Ctx);
57}
58
59// A address must be loaded from a small section if its size is less than the
60// small section size threshold. Data in this section could be addressed by
61// using gp_rel operator.
63 // gcc has traditionally not treated zero-sized objects as small data, so this
64 // is effectively part of the ABI.
65 return Size > 0 && Size <= SSThreshold;
66}
67
68// Return true if this global address should be placed into small data/bss
69// section.
71 const GlobalObject *GO, const TargetMachine &TM) const {
72 // Only global variables, not functions.
74 if (!GVA)
75 return false;
76
77 // If the variable has an explicit section, it is placed in that section.
78 if (GVA->hasSection()) {
79 StringRef Section = GVA->getSection();
80
81 // Explicitly placing any variable in the small data section overrides
82 // the global -G value.
83 if (Section == ".sdata" || Section == ".sbss")
84 return true;
85
86 // Otherwise reject putting the variable to small section if it has an
87 // explicit section name.
88 return false;
89 }
90
91 if (((GVA->hasExternalLinkage() && GVA->isDeclaration()) ||
92 GVA->hasCommonLinkage()))
93 return false;
94
95 Type *Ty = GVA->getValueType();
96 // It is possible that the type of the global is unsized, i.e. a declaration
97 // of a extern struct. In this case don't presume it is in the small data
98 // section. This happens e.g. when building the FreeBSD kernel.
99 if (!Ty->isSized())
100 return false;
101
102 return isInSmallSection(
104}
105
107 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
108 // Handle Small Section classification here.
109 if (isGlobalInSmallSection(GO, TM)) {
110 // Emit to an unique sdata/sbss section when -fdata-section is set.
111 // However, if a symbol has an explicit sdata/sbss section, place it in that
112 // section.
113 bool EmitUniquedSection = TM.getDataSections() && !GO->hasSection();
114
115 if (Kind.isBSS()) {
116 if (EmitUniquedSection) {
117 SmallString<128> Name(".sbss.");
118 Name.append(GO->getName());
119 return getContext().getELFSection(Name.str(), ELF::SHT_NOBITS,
121 }
122
123 return SmallBSSSection;
124 }
125
126 if (Kind.isData()) {
127 if (EmitUniquedSection) {
128 SmallString<128> Name(".sdata.");
129 Name.append(GO->getName());
130 return getContext().getELFSection(Name.str(), ELF::SHT_PROGBITS,
132 }
133
134 return SmallDataSection;
135 }
136 }
137
138 // Otherwise, we work the same as ELF.
140}
141
145 M.getModuleFlagsMetadata(ModuleFlags);
146
147 for (const auto &MFE : ModuleFlags) {
148 StringRef Key = MFE.Key->getString();
149 if (Key == "SmallDataLimit") {
150 SSThreshold = mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue();
151 break;
152 }
153 }
154}
155
156/// Return true if this constant should be placed into small data section.
158 const DataLayout &DL, const Constant *CN) const {
159 return isInSmallSection(DL.getTypeAllocSize(CN->getType()));
160}
161
163 const DataLayout &DL, SectionKind Kind, const Constant *C,
164 Align &Alignment) const {
165 if (C && isConstantInSmallSection(DL, C)) {
166 if (Kind.isMergeableConst4())
167 return SmallROData4Section;
168 if (Kind.isMergeableConst8())
169 return SmallROData8Section;
170 if (Kind.isMergeableConst16())
171 return SmallROData16Section;
172 if (Kind.isMergeableConst32())
173 return SmallROData32Section;
174 // LLVM only generate up to .rodata.cst32, and use .rodata section if more
175 // than 32 bytes, so just use .srodata here.
176 return SmallRODataSection;
177 }
178
179 // Otherwise, we work the same as ELF.
181 Alignment);
182}
183
185 SmallVectorImpl<char> &OutName, const GlobalValue *GV,
186 const TargetMachine &TM) const {
187 // RISC-V does not use section-relative relocations so any global symbol must
188 // be accessed via at least a linker-private symbol.
189 getMangler().getNameWithPrefix(OutName, GV, /*CannotUsePrivateLabel=*/true);
190}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Module.h This file contains the declarations for the Module class.
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:329
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Definition Globals.cpp:133
bool hasCommonLinkage() const
Type * getValueType() const
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:553
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:516
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:743
Streaming machine code generation interface.
Definition MCStreamer.h:221
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
int64_t getConstant() const
Definition MCValue.h:44
This class contains meta information specific to a module.
LLVM_ABI void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
Definition Mangler.cpp:121
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
bool isGlobalInSmallSection(const GlobalObject *GO, const TargetMachine &TM) const
Return true if this global address should be placed into small data/bss section.
MCSection * SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override
void getModuleMetadata(Module &M) override
Get the module-level metadata that the platform cares about.
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.
bool isInSmallSection(uint64_t Size) const
void Initialize(MCContext &Ctx, const TargetMachine &TM) override
This method must be called before any actual lowering is done.
unsigned getTextSectionAlignment() const override
bool isConstantInSmallSection(const DataLayout &DL, const Constant *CN) const
Return true if this constant should be placed into small data section.
const MCExpr * getIndirectSymViaGOTPCRel(const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV, int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const override
Get the target specific PC relative GOT entry relocation.
unsigned getTextSectionAlignment() const override
void getNameWithPrefix(SmallVectorImpl< char > &OutName, const GlobalValue *GV, const TargetMachine &TM) const override
SectionKind - This is a simple POD value that classifies the properties of a section.
Definition SectionKind.h:22
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
void getModuleMetadata(Module &M) override
Get the module-level metadata that the platform cares about.
MCSection * SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override
Primary interface to the complete machine description for the target machine.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:256
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:322
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ SHF_MERGE
Definition ELF.h:1256
@ SHF_ALLOC
Definition ELF.h:1250
@ SHF_WRITE
Definition ELF.h:1247
@ SHT_PROGBITS
Definition ELF.h:1149
@ SHT_NOBITS
Definition ELF.h:1156
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:668
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39