LLVM: lib/Target/Hexagon/HexagonTargetObjectFile.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
32
33#define DEBUG_TYPE "hexagon-sdata"
34
35using namespace llvm;
36
39 cl::desc("The maximum size of an object in the sdata section"));
40
43
46 cl::desc("Allow static variables in .sdata"));
47
50 cl::desc("Trace global value placement"));
51
54 cl::desc("Emit hexagon jump tables in function section"));
55
58 cl::desc("Emit hexagon lookup tables in function section"));
59
60
61
62
63#define TRACE_TO(s, X) s << X
64#ifdef NDEBUG
65#define TRACE(X) \
66 do { \
67 if (TraceGVPlacement) { \
68 TRACE_TO(errs(), X); \
69 } \
70 } while (false)
71#else
72#define TRACE(X) \
73 do { \
74 if (TraceGVPlacement) { \
75 TRACE_TO(errs(), X); \
76 } else { \
77 LLVM_DEBUG(TRACE_TO(dbgs(), X)); \
78 } \
79 } while (false)
80#endif
81
82
83
84
85
87
88
89 if (Sec == ".sdata" || Sec == ".sbss" || Sec == ".scommon")
90 return true;
91
92
95}
96
98 switch (Size) {
99 default:
100 return "";
101 case 1:
102 return ".1";
103 case 2:
104 return ".2";
105 case 4:
106 return ".4";
107 case 8:
108 return ".8";
109 }
110}
111
115
116 SmallDataSection =
120 SmallBSSSection =
124}
125
128 TRACE("[SelectSectionForGlobal] GO(" << GO->getName() << ") ");
130
137 << (Kind.isCommon() ? "kind_common " : "" )
138 << (Kind.isBSS() ? "kind_bss " : "" )
139 << (Kind.isBSSLocal() ? "kind_bss_local " : "" ));
140
141
142
145 return selectSectionForLookupTable(GO, TM, Fn);
146 }
147
149 return selectSmallSectionForGlobal(GO, Kind, TM);
150
151 if (Kind.isCommon()) {
152
153
154
155
157 }
158
159 TRACE("default_ELF_section\n");
160
162}
163
166 TRACE("[getExplicitSectionGlobal] GO(" << GO->getName() << ") from("
174 << (Kind.isCommon() ? "kind_common " : "" )
175 << (Kind.isBSS() ? "kind_bss " : "" )
176 << (Kind.isBSSLocal() ? "kind_bss_local " : "" ));
177
180 if (Section.contains(".access.text.group"))
183 if (Section.contains(".access.data.group"))
186 }
187
189 return selectSmallSectionForGlobal(GO, Kind, TM);
190
191
192 TRACE("default_ELF_section\n");
194}
195
196
197
201 if (!HaveSData)
202 LLVM_DEBUG(dbgs() << "Small-data allocation is disabled, but symbols "
203 "may have explicit section assignments...\n");
204
205 LLVM_DEBUG(dbgs() << "Checking if value is in small-data, -G"
207 const GlobalVariable *GVar = dyn_cast(GO);
208 if (!GVar) {
210 return false;
211 }
212
213
214
215
219 << ", has section: " << GVar->getSection() << '\n');
220 return IsSmall;
221 }
222
223
224 if (!HaveSData) {
225 LLVM_DEBUG(dbgs() << "no, small-data allocation is disabled\n");
226 return false;
227 }
228
231 return false;
232 }
233
237 return false;
238 }
239
241 if (isa(GType)) {
243 return false;
244 }
245
246
247
248
249
250 if (StructType *ST = dyn_cast(GType)) {
251 if (ST->isOpaque()) {
253 return false;
254 }
255 }
256
258 if (Size == 0) {
260 return false;
261 }
263 LLVM_DEBUG(dbgs() << "no, size exceeds sdata threshold: " << Size << '\n');
264 return false;
265 }
266
268 return true;
269}
270
272 const {
274}
275
278}
279
281 bool UsesLabelDifference, const Function &F) const {
283}
284
285
286
287
288unsigned HexagonTargetObjectFile::getSmallestAddressableSize(const Type *Ty,
290
291
292 unsigned SmallestElement = 8;
293
294 if (!Ty)
295 return 0;
298 const StructType *STy = cast(Ty);
299 for (auto &E : STy->elements()) {
300 unsigned AtomicSize = getSmallestAddressableSize(E, GV, TM);
301 if (AtomicSize < SmallestElement)
302 SmallestElement = AtomicSize;
303 }
304 return (STy->getNumElements() == 0) ? 0 : SmallestElement;
305 }
307 const ArrayType *ATy = cast(Ty);
308 return getSmallestAddressableSize(ATy->getElementType(), GV, TM);
309 }
312 const VectorType *PTy = cast(Ty);
313 return getSmallestAddressableSize(PTy->getElementType(), GV, TM);
314 }
321
322 return DL.getTypeAllocSize(const_cast<Type*>(Ty));
323 }
336 return 0;
337 }
338
339 return 0;
340}
341
342MCSection *HexagonTargetObjectFile::selectSmallSectionForGlobal(
345 unsigned Size = getSmallestAddressableSize(GTy, GO, TM);
346
347
348
350
351 TRACE("Small data. Size(" << Size << ")");
352
353 if (Kind.isBSS() || Kind.isBSSLocal()) {
354
355
356
357
358
359
361 TRACE(" default sbss\n");
362 return SmallBSSSection;
363 }
364
368
369 if (EmitUniquedSection) {
370 Name.append(".");
372 }
373 TRACE(" unique sbss(" << Name << ")\n");
376 }
377
378 if (Kind.isCommon()) {
379
380
381
382
385
387 TRACE(" small COMMON (" << Name << ")\n");
388
392 }
393
394
395
396 if (Kind.isMergeableConst()) {
397 TRACE(" const_object_as_data ");
398 const GlobalVariable *GVar = dyn_cast(GO);
401 }
402
403 if (Kind.isData()) {
405 TRACE(" default sdata\n");
406 return SmallDataSection;
407 }
408
412
413 if (EmitUniquedSection) {
414 Name.append(".");
416 }
417 TRACE(" unique sdata(" << Name << ")\n");
420 }
421
422 TRACE("default ELF section\n");
423
425}
426
427
428
429
432 const Function *ReturnFn = nullptr;
433 for (const auto *U : GO->users()) {
434
435 auto *I = dyn_cast(U);
436 if ()
437 continue;
438 auto *Bb = I->getParent();
439 if (!Bb)
440 continue;
441 auto *UserFn = Bb->getParent();
442 if (!ReturnFn)
443 ReturnFn = UserFn;
444 else if (ReturnFn != UserFn)
445 return nullptr;
446 }
447 return ReturnFn;
448}
449
450MCSection *HexagonTargetObjectFile::selectSectionForLookupTable(
452
454
455
458
459 const auto *FuncObj = dyn_cast(Fn);
461}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< bool > TraceGVPlacement("trace-gv-placement", cl::Hidden, cl::init(false), cl::desc("Trace global value placement"))
static cl::opt< bool > EmitJtInText("hexagon-emit-jt-text", cl::Hidden, cl::init(false), cl::desc("Emit hexagon jump tables in function section"))
static cl::opt< unsigned > SmallDataThreshold("hexagon-small-data-threshold", cl::init(8), cl::Hidden, cl::desc("The maximum size of an object in the sdata section"))
static cl::opt< bool > StaticsInSData("hexagon-statics-in-small-data", cl::Hidden, cl::desc("Allow static variables in .sdata"))
static const char * getSectionSuffixForSize(unsigned Size)
static cl::opt< bool > EmitLutInText("hexagon-emit-lut-text", cl::Hidden, cl::init(false), cl::desc("Emit hexagon lookup tables in function section"))
static cl::opt< bool > NoSmallDataSorting("mno-sort-sda", cl::init(false), cl::Hidden, cl::desc("Disable small data sections sorting"))
static bool isSmallDataSection(StringRef Sec)
Module.h This file contains the declarations for the Module class.
This file defines the SmallString class.
A parsed version of the target data layout string in and methods for querying it.
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
bool hasLocalLinkage() const
bool hasPrivateLinkage() const
bool hasInternalLinkage() const
const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
bool hasCommonLinkage() 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...
bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference, const Function &F) const override
bool isSmallDataEnabled(const TargetMachine &TM) const
void Initialize(MCContext &Ctx, const TargetMachine &TM) override
This method must be called before any actual lowering is done.
bool isGlobalInSmallSection(const GlobalObject *GO, const TargetMachine &TM) const
Return true if this global value should be placed into small data/bss section.
MCSection * SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override
unsigned getSmallDataSize() const
MCSection * getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override
Targets should implement this method to assign a section to globals with an explicit section specfied...
const Function * getLutUsedFunction(const GlobalObject *GO) const
Context object for machine code objects.
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
MCSection * BSSSection
Section that is default initialized to zero.
MCContext & getContext() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
SectionKind - This is a simple POD value that classifies the properties of a section.
static SectionKind getText()
static SectionKind getData()
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef - Represent a constant reference to a string, i.e.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Class to represent struct types.
ArrayRef< Type * > elements() const
unsigned getNumElements() const
Random access to the elements.
void Initialize(MCContext &Ctx, const TargetMachine &TM) override
This method must be called before any actual lowering is done.
MCSection * SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override
MCSection * getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override
Targets should implement this method to assign a section to globals with an explicit section specfied...
Primary interface to the complete machine description for the target machine.
bool isPositionIndependent() const
bool getDataSections() const
Return true if data objects should be emitted into their own section, corresponds to -fdata-sections.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
@ X86_AMXTyID
AMX vectors (8192 bits, X86 specific)
@ TypedPointerTyID
Typed pointer used by some GPU targets.
@ HalfTyID
16-bit floating point type
@ TargetExtTyID
Target extension type.
@ VoidTyID
type with no size
@ ScalableVectorTyID
Scalable SIMD vector type.
@ FloatTyID
32-bit floating point type
@ IntegerTyID
Arbitrary bit width integers.
@ FixedVectorTyID
Fixed width SIMD vector type.
@ BFloatTyID
16-bit floating point type (7-bit significand)
@ DoubleTyID
64-bit floating point type
@ X86_FP80TyID
80-bit floating point type (X87)
@ PPC_FP128TyID
128-bit floating point type (two 64-bits, PowerPC)
@ FP128TyID
128-bit floating point type (112-bit significand)
TypeID getTypeID() const
Return the type id for the type.
iterator_range< user_iterator > users()
StringRef getName() const
Return a constant reference to the value's name.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.