LLVM  4.0.0
HexagonTargetObjectFile.cpp
Go to the documentation of this file.
1 //===-- HexagonTargetObjectFile.cpp ---------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the declarations of the HexagonTargetAsmInfo properties.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #define DEBUG_TYPE "hexagon-sdata"
15 
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/Twine.h"
20 #include "llvm/IR/DataLayout.h"
21 #include "llvm/IR/DerivedTypes.h"
22 #include "llvm/IR/GlobalObject.h"
23 #include "llvm/IR/GlobalValue.h"
24 #include "llvm/IR/GlobalVariable.h"
25 #include "llvm/IR/Type.h"
26 #include "llvm/MC/MCContext.h"
27 #include "llvm/MC/SectionKind.h"
28 #include "llvm/Support/Casting.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/ELF.h"
34 
35 using namespace llvm;
36 
37 static cl::opt<unsigned> SmallDataThreshold("hexagon-small-data-threshold",
38  cl::init(8), cl::Hidden,
39  cl::desc("The maximum size of an object in the sdata section"));
40 
41 static cl::opt<bool> NoSmallDataSorting("mno-sort-sda", cl::init(false),
42  cl::Hidden, cl::desc("Disable small data sections sorting"));
43 
44 static cl::opt<bool> StaticsInSData("hexagon-statics-in-small-data",
46  cl::desc("Allow static variables in .sdata"));
47 
48 static cl::opt<bool> TraceGVPlacement("trace-gv-placement",
49  cl::Hidden, cl::init(false),
50  cl::desc("Trace global value placement"));
51 
52 // TraceGVPlacement controls messages for all builds. For builds with assertions
53 // (debug or release), messages are also controlled by the usual debug flags
54 // (e.g. -debug and -debug-only=globallayout)
55 #define TRACE_TO(s, X) s << X
56 #ifdef NDEBUG
57 #define TRACE(X) \
58  do { \
59  if (TraceGVPlacement) { \
60  TRACE_TO(errs(), X); \
61  } \
62  } while (false)
63 #else
64 #define TRACE(X) \
65  do { \
66  if (TraceGVPlacement) { \
67  TRACE_TO(errs(), X); \
68  } else { \
69  DEBUG(TRACE_TO(dbgs(), X)); \
70  } \
71  } while (false)
72 #endif
73 
74 // Returns true if the section name is such that the symbol will be put
75 // in a small data section.
76 // For instance, global variables with section attributes such as ".sdata"
77 // ".sdata.*", ".sbss", and ".sbss.*" will go into small data.
78 static bool isSmallDataSection(StringRef Sec) {
79  // sectionName is either ".sdata" or ".sbss". Looking for an exact match
80  // obviates the need for checks for section names such as ".sdatafoo".
81  if (Sec.equals(".sdata") || Sec.equals(".sbss") || Sec.equals(".scommon"))
82  return true;
83  // If either ".sdata." or ".sbss." is a substring of the section name
84  // then put the symbol in small data.
85  return Sec.find(".sdata.") != StringRef::npos ||
86  Sec.find(".sbss.") != StringRef::npos ||
87  Sec.find(".scommon.") != StringRef::npos;
88 }
89 
90 static const char *getSectionSuffixForSize(unsigned Size) {
91  switch (Size) {
92  default:
93  return "";
94  case 1:
95  return ".1";
96  case 2:
97  return ".2";
98  case 4:
99  return ".4";
100  case 8:
101  return ".8";
102  }
103 }
104 
106  const TargetMachine &TM) {
109 
110  SmallDataSection =
114  SmallBSSSection =
118 }
119 
121  const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
122  TRACE("[SelectSectionForGlobal] GO(" << GO->getName() << ") ");
123  TRACE("input section(" << GO->getSection() << ") ");
124 
125  TRACE((GO->hasPrivateLinkage() ? "private_linkage " : "")
126  << (GO->hasLocalLinkage() ? "local_linkage " : "")
127  << (GO->hasInternalLinkage() ? "internal " : "")
128  << (GO->hasExternalLinkage() ? "external " : "")
129  << (GO->hasCommonLinkage() ? "common_linkage " : "")
130  << (GO->hasCommonLinkage() ? "common " : "" )
131  << (Kind.isCommon() ? "kind_common " : "" )
132  << (Kind.isBSS() ? "kind_bss " : "" )
133  << (Kind.isBSSLocal() ? "kind_bss_local " : "" ));
134 
135  if (isGlobalInSmallSection(GO, TM))
136  return selectSmallSectionForGlobal(GO, Kind, TM);
137 
138  if (Kind.isCommon()) {
139  // This is purely for LTO+Linker Script because commons don't really have a
140  // section. However, the BitcodeSectionWriter pass will query for the
141  // sections of commons (and the linker expects us to know their section) so
142  // we'll return one here.
143  return BSSSection;
144  }
145 
146  TRACE("default_ELF_section\n");
147  // Otherwise, we work the same as ELF.
149 }
150 
152  const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
153  TRACE("[getExplicitSectionGlobal] GO(" << GO->getName() << ") from("
154  << GO->getSection() << ") ");
155  TRACE((GO->hasPrivateLinkage() ? "private_linkage " : "")
156  << (GO->hasLocalLinkage() ? "local_linkage " : "")
157  << (GO->hasInternalLinkage() ? "internal " : "")
158  << (GO->hasExternalLinkage() ? "external " : "")
159  << (GO->hasCommonLinkage() ? "common_linkage " : "")
160  << (GO->hasCommonLinkage() ? "common " : "" )
161  << (Kind.isCommon() ? "kind_common " : "" )
162  << (Kind.isBSS() ? "kind_bss " : "" )
163  << (Kind.isBSSLocal() ? "kind_bss_local " : "" ));
164 
165  if (GO->hasSection()) {
166  StringRef Section = GO->getSection();
167  if (Section.find(".access.text.group") != StringRef::npos)
170  if (Section.find(".access.data.group") != StringRef::npos)
173  }
174 
175  if (isGlobalInSmallSection(GO, TM))
176  return selectSmallSectionForGlobal(GO, Kind, TM);
177 
178  // Otherwise, we work the same as ELF.
179  TRACE("default_ELF_section\n");
181 }
182 
183 /// Return true if this global value should be placed into small data/bss
184 /// section.
186  const TargetMachine &TM) const {
187  // Only global variables, not functions.
188  DEBUG(dbgs() << "Checking if value is in small-data, -G"
189  << SmallDataThreshold << ": \"" << GO->getName() << "\": ");
190  const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO);
191  if (!GVar) {
192  DEBUG(dbgs() << "no, not a global variable\n");
193  return false;
194  }
195 
196  // Globals with external linkage that have an original section set must be
197  // emitted to that section, regardless of whether we would put them into
198  // small data or not. This is how we can support mixing -G0/-G8 in LTO.
199  if (GVar->hasSection()) {
200  bool IsSmall = isSmallDataSection(GVar->getSection());
201  DEBUG(dbgs() << (IsSmall ? "yes" : "no") << ", has section: "
202  << GVar->getSection() << '\n');
203  return IsSmall;
204  }
205 
206  if (GVar->isConstant()) {
207  DEBUG(dbgs() << "no, is a constant\n");
208  return false;
209  }
210 
211  bool IsLocal = GVar->hasLocalLinkage();
212  if (!StaticsInSData && IsLocal) {
213  DEBUG(dbgs() << "no, is static\n");
214  return false;
215  }
216 
217  Type *GType = GVar->getType();
218  if (PointerType *PT = dyn_cast<PointerType>(GType))
219  GType = PT->getElementType();
220 
221  if (isa<ArrayType>(GType)) {
222  DEBUG(dbgs() << "no, is an array\n");
223  return false;
224  }
225 
226  // If the type is a struct with no body provided, treat is conservatively.
227  // There cannot be actual definitions of object of such a type in this CU
228  // (only references), so assuming that they are not in sdata is safe. If
229  // these objects end up in the sdata, the references will still be valid.
230  if (StructType *ST = dyn_cast<StructType>(GType)) {
231  if (ST->isOpaque()) {
232  DEBUG(dbgs() << "no, has opaque type\n");
233  return false;
234  }
235  }
236 
237  unsigned Size = GVar->getParent()->getDataLayout().getTypeAllocSize(GType);
238  if (Size == 0) {
239  DEBUG(dbgs() << "no, has size 0\n");
240  return false;
241  }
242  if (Size > SmallDataThreshold) {
243  DEBUG(dbgs() << "no, size exceeds sdata threshold: " << Size << '\n');
244  return false;
245  }
246 
247  DEBUG(dbgs() << "yes\n");
248  return true;
249 }
250 
252  return SmallDataThreshold > 0;
253 }
254 
256  return SmallDataThreshold;
257 }
258 
259 /// Descends any type down to "elementary" components,
260 /// discovering the smallest addressable one.
261 /// If zero is returned, declaration will not be modified.
262 unsigned HexagonTargetObjectFile::getSmallestAddressableSize(const Type *Ty,
263  const GlobalValue *GV, const TargetMachine &TM) const {
264  // Assign the smallest element access size to the highest
265  // value which assembler can handle.
266  unsigned SmallestElement = 8;
267 
268  if (!Ty)
269  return 0;
270  switch (Ty->getTypeID()) {
271  case Type::StructTyID: {
272  const StructType *STy = cast<const StructType>(Ty);
273  for (auto &E : STy->elements()) {
274  unsigned AtomicSize = getSmallestAddressableSize(E, GV, TM);
275  if (AtomicSize < SmallestElement)
276  SmallestElement = AtomicSize;
277  }
278  return (STy->getNumElements() == 0) ? 0 : SmallestElement;
279  }
280  case Type::ArrayTyID: {
281  const ArrayType *ATy = cast<const ArrayType>(Ty);
282  return getSmallestAddressableSize(ATy->getElementType(), GV, TM);
283  }
284  case Type::VectorTyID: {
285  const VectorType *PTy = cast<const VectorType>(Ty);
286  return getSmallestAddressableSize(PTy->getElementType(), GV, TM);
287  }
288  case Type::PointerTyID:
289  case Type::HalfTyID:
290  case Type::FloatTyID:
291  case Type::DoubleTyID:
292  case Type::IntegerTyID: {
293  const DataLayout &DL = GV->getParent()->getDataLayout();
294  // It is unfortunate that DL's function take non-const Type*.
295  return DL.getTypeAllocSize(const_cast<Type*>(Ty));
296  }
297  case Type::FunctionTyID:
298  case Type::VoidTyID:
299  case Type::X86_FP80TyID:
300  case Type::FP128TyID:
301  case Type::PPC_FP128TyID:
302  case Type::LabelTyID:
303  case Type::MetadataTyID:
304  case Type::X86_MMXTyID:
305  case Type::TokenTyID:
306  return 0;
307  }
308 
309  return 0;
310 }
311 
312 MCSection *HexagonTargetObjectFile::selectSmallSectionForGlobal(
313  const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
314  const Type *GTy = GO->getType()->getElementType();
315  unsigned Size = getSmallestAddressableSize(GTy, GO, TM);
316 
317  // If we have -ffunction-section or -fdata-section then we should emit the
318  // global value to a unique section specifically for it... even for sdata.
319  bool EmitUniquedSection = TM.getDataSections();
320 
321  TRACE("Small data. Size(" << Size << ")");
322  // Handle Small Section classification here.
323  if (Kind.isBSS() || Kind.isBSSLocal()) {
324  // If -mno-sort-sda is not set, find out smallest accessible entity in
325  // declaration and add it to the section name string.
326  // Note. It does not track the actual usage of the value, only its de-
327  // claration. Also, compiler adds explicit pad fields to some struct
328  // declarations - they are currently counted towards smallest addres-
329  // sable entity.
330  if (NoSmallDataSorting) {
331  TRACE(" default sbss\n");
332  return SmallBSSSection;
333  }
334 
335  StringRef Prefix(".sbss");
337  Name.append(getSectionSuffixForSize(Size));
338 
339  if (EmitUniquedSection) {
340  Name.append(".");
341  Name.append(GO->getName());
342  }
343  TRACE(" unique sbss(" << Name << ")\n");
346  }
347 
348  if (Kind.isCommon()) {
349  // This is purely for LTO+Linker Script because commons don't really have a
350  // section. However, the BitcodeSectionWriter pass will query for the
351  // sections of commons (and the linker expects us to know their section) so
352  // we'll return one here.
353  if (NoSmallDataSorting)
354  return BSSSection;
355 
356  Twine Name = Twine(".scommon") + getSectionSuffixForSize(Size);
357  TRACE(" small COMMON (" << Name << ")\n");
358 
359  return getContext().getELFSection(Name.str(), ELF::SHT_NOBITS,
362  }
363 
364  // We could have changed sdata object to a constant... in this
365  // case the Kind could be wrong for it.
366  if (Kind.isMergeableConst()) {
367  TRACE(" const_object_as_data ");
368  const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO);
369  if (GVar->hasSection() && isSmallDataSection(GVar->getSection()))
370  Kind = SectionKind::getData();
371  }
372 
373  if (Kind.isData()) {
374  if (NoSmallDataSorting) {
375  TRACE(" default sdata\n");
376  return SmallDataSection;
377  }
378 
379  StringRef Prefix(".sdata");
381  Name.append(getSectionSuffixForSize(Size));
382 
383  if (EmitUniquedSection) {
384  Name.append(".");
385  Name.append(GO->getName());
386  }
387  TRACE(" unique sdata(" << Name << ")\n");
390  }
391 
392  TRACE("default ELF section\n");
393  // Otherwise, we work the same as ELF.
395 }
Instances of this class represent a uniqued identifier for a section in the current translation unit...
Definition: MCSection.h:40
7: Labels
Definition: Type.h:63
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:102
static SectionKind getData()
Definition: SectionKind.h:202
bool isMergeableConst() const
Definition: SectionKind.h:136
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...
2: 32-bit floating point type
Definition: Type.h:58
static const char * getSectionSuffixForSize(unsigned Size)
bool isBSS() const
Definition: SectionKind.h:160
13: Structures
Definition: Type.h:72
4: 80-bit floating point type (X87)
Definition: Type.h:60
1: 16-bit floating point type
Definition: Type.h:57
15: Pointers
Definition: Type.h:74
Type * getElementType() const
Definition: DerivedTypes.h:462
12: Functions
Definition: Type.h:71
#define TRACE(X)
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:191
std::string str() const
Return the twine contents as a std::string.
Definition: Twine.cpp:17
bool hasCommonLinkage() const
Definition: GlobalValue.h:419
static cl::opt< bool > NoSmallDataSorting("mno-sort-sda", cl::init(false), cl::Hidden, cl::desc("Disable small data sections sorting"))
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
Class to represent struct types.
Definition: DerivedTypes.h:199
virtual void Initialize(MCContext &ctx, const TargetMachine &TM)
This method must be called before any actual lowering is done.
bool hasInternalLinkage() const
Definition: GlobalValue.h:413
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:166
bool hasPrivateLinkage() const
Definition: GlobalValue.h:414
MCSection * SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override
Context object for machine code objects.
Definition: MCContext.h:51
ArrayRef< Type * > const elements() const
Definition: DerivedTypes.h:281
Class to represent array types.
Definition: DerivedTypes.h:345
StringRef getSection() const
Get the custom section of this global if it has one.
Definition: GlobalObject.h:81
TypeID getTypeID() const
Return the type id for the type.
Definition: Type.h:136
Type * getElementType() const
Definition: DerivedTypes.h:336
Class to represent pointers.
Definition: DerivedTypes.h:443
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
11: Arbitrary bit width integers
Definition: Type.h:70
bool hasSection() const
Check if this global has a custom object file section.
Definition: GlobalObject.h:73
0: type with no size
Definition: Type.h:56
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:395
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:295
MCSection * SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
10: Tokens
Definition: Type.h:66
static bool isSmallDataSection(StringRef Sec)
SectionKind - This is a simple POD value that classifies the properties of a section.
Definition: SectionKind.h:23
6: 128-bit floating point type (two 64-bits, PowerPC)
Definition: Type.h:62
bool isBSSLocal() const
Definition: SectionKind.h:161
bool getDataSections() const
Return true if data objects should be emitted into their own section, corresponds to -fdata-sections...
14: Arrays
Definition: Type.h:73
bool hasExternalLinkage() const
Definition: GlobalValue.h:401
unsigned UseInitArray
UseInitArray - Use .init_array instead of .ctors for static constructors.
16: SIMD 'packed' format, or other vector type
Definition: Type.h:75
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Definition: DataLayout.h:408
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"))
void Initialize(MCContext &Ctx, const TargetMachine &TM) override
This method must be called before any actual lowering is done.
static cl::opt< bool > TraceGVPlacement("trace-gv-placement", cl::Hidden, cl::init(false), cl::desc("Trace global value placement"))
static cl::opt< bool > StaticsInSData("hexagon-statics-in-small-data", cl::init(false), cl::Hidden, cl::ZeroOrMore, cl::desc("Allow static variables in .sdata"))
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
8: Metadata
Definition: Type.h:64
Class to represent vector types.
Definition: DerivedTypes.h:369
bool isData() const
Definition: SectionKind.h:166
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:259
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:384
static const size_t npos
Definition: StringRef.h:51
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:287
bool isCommon() const
Definition: SectionKind.h:164
bool hasLocalLinkage() const
Definition: GlobalValue.h:415
const unsigned Kind
3: 64-bit floating point type
Definition: Type.h:59
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:341
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:537
#define DEBUG(X)
Definition: Debug.h:100
Primary interface to the complete machine description for the target machine.
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...
MCSection * BSSSection
Section that is default initialized to zero.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
bool isGlobalInSmallSection(const GlobalObject *GO, const TargetMachine &TM) const
Return true if this global value should be placed into small data/bss section.
9: MMX vectors (64 bits, X86 specific)
Definition: Type.h:65
unsigned getNumElements() const
Random access to the elements.
Definition: DerivedTypes.h:289
5: 128-bit floating point type (112-bit mantissa)
Definition: Type.h:61