Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
Line
Count
Source (jump to first uncovered line)
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
16
#include "HexagonTargetObjectFile.h"
17
#include "llvm/ADT/SmallString.h"
18
#include "llvm/ADT/StringRef.h"
19
#include "llvm/ADT/Twine.h"
20
#include "llvm/BinaryFormat/ELF.h"
21
#include "llvm/IR/DataLayout.h"
22
#include "llvm/IR/DerivedTypes.h"
23
#include "llvm/IR/GlobalObject.h"
24
#include "llvm/IR/GlobalValue.h"
25
#include "llvm/IR/GlobalVariable.h"
26
#include "llvm/IR/Type.h"
27
#include "llvm/MC/MCContext.h"
28
#include "llvm/MC/SectionKind.h"
29
#include "llvm/Support/Casting.h"
30
#include "llvm/Support/CommandLine.h"
31
#include "llvm/Support/Debug.h"
32
#include "llvm/Support/raw_ostream.h"
33
#include "llvm/Target/TargetMachine.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",
45
  cl::init(false), cl::Hidden, cl::ZeroOrMore,
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
static cl::opt<bool>
53
    EmitJtInText("hexagon-emit-jt-text", cl::Hidden, cl::init(false),
54
                 cl::desc("Emit hexagon jump tables in function section"));
55
56
static cl::opt<bool>
57
    EmitLutInText("hexagon-emit-lut-text", cl::Hidden, cl::init(false),
58
                 cl::desc("Emit hexagon lookup tables in function section"));
59
60
// TraceGVPlacement controls messages for all builds. For builds with assertions
61
// (debug or release), messages are also controlled by the usual debug flags
62
// (e.g. -debug and -debug-only=globallayout)
63
0
#define TRACE_TO(s, X) 
s << 0
X0
64
#ifdef NDEBUG
65
#define TRACE(X)                                                               \
66
12.5k
  
do 12.5k
{ \
67
10.1k
    if (
TraceGVPlacement10.1k
) { \
68
0
      TRACE_TO(errs(), X);                                                     \
69
0
    }                                                                          \
70
12.5k
  } while (false)
71
#else
72
#define TRACE(X)                                                               \
73
  do {                                                                         \
74
    if (TraceGVPlacement) {                                                    \
75
      TRACE_TO(errs(), X);                                                     \
76
    } else {                                                                   \
77
      DEBUG(TRACE_TO(dbgs(), X));                                              \
78
    }                                                                          \
79
  } while (false)
80
#endif
81
82
// Returns true if the section name is such that the symbol will be put
83
// in a small data section.
84
// For instance, global variables with section attributes such as ".sdata"
85
// ".sdata.*", ".sbss", and ".sbss.*" will go into small data.
86
15
static bool isSmallDataSection(StringRef Sec) {
87
15
  // sectionName is either ".sdata" or ".sbss". Looking for an exact match
88
15
  // obviates the need for checks for section names such as ".sdatafoo".
89
15
  if (
Sec.equals(".sdata") || 15
Sec.equals(".sbss")13
||
Sec.equals(".scommon")11
)
90
4
    return true;
91
11
  // If either ".sdata." or ".sbss." is a substring of the section name
92
11
  // then put the symbol in small data.
93
11
  return Sec.find(".sdata.") != StringRef::npos ||
94
9
         Sec.find(".sbss.") != StringRef::npos ||
95
7
         Sec.find(".scommon.") != StringRef::npos;
96
15
}
97
98
36
static const char *getSectionSuffixForSize(unsigned Size) {
99
36
  switch (Size) {
100
0
  default:
101
0
    return "";
102
4
  case 1:
103
4
    return ".1";
104
0
  case 2:
105
0
    return ".2";
106
19
  case 4:
107
19
    return ".4";
108
13
  case 8:
109
13
    return ".8";
110
0
  }
111
0
}
112
113
void HexagonTargetObjectFile::Initialize(MCContext &Ctx,
114
440
      const TargetMachine &TM) {
115
440
  TargetLoweringObjectFileELF::Initialize(Ctx, TM);
116
440
  InitializeELF(TM.Options.UseInitArray);
117
440
118
440
  SmallDataSection =
119
440
    getContext().getELFSection(".sdata", ELF::SHT_PROGBITS,
120
440
                               ELF::SHF_WRITE | ELF::SHF_ALLOC |
121
440
                               ELF::SHF_HEX_GPREL);
122
440
  SmallBSSSection =
123
440
    getContext().getELFSection(".sbss", ELF::SHT_NOBITS,
124
440
                               ELF::SHF_WRITE | ELF::SHF_ALLOC |
125
440
                               ELF::SHF_HEX_GPREL);
126
440
}
127
128
MCSection *HexagonTargetObjectFile::SelectSectionForGlobal(
129
2.50k
    const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
130
2.50k
  TRACE("[SelectSectionForGlobal] GO(" << GO->getName() << ") ");
131
2.50k
  TRACE("input section(" << GO->getSection() << ") ");
132
2.50k
133
2.50k
  TRACE((GO->hasPrivateLinkage() ? "private_linkage " : "")
134
2.50k
         << (GO->hasLocalLinkage() ? "local_linkage " : "")
135
2.50k
         << (GO->hasInternalLinkage() ? "internal " : "")
136
2.50k
         << (GO->hasExternalLinkage() ? "external " : "")
137
2.50k
         << (GO->hasCommonLinkage() ? "common_linkage " : "")
138
2.50k
         << (GO->hasCommonLinkage() ? "common " : "" )
139
2.50k
         << (Kind.isCommon() ? "kind_common " : "" )
140
2.50k
         << (Kind.isBSS() ? "kind_bss " : "" )
141
2.50k
         << (Kind.isBSSLocal() ? "kind_bss_local " : "" ));
142
2.50k
143
2.50k
  // If the lookup table is used by more than one function, do not place
144
2.50k
  // it in text section.
145
2.50k
  if (
EmitLutInText && 2.50k
GO->getName().startswith("switch.table")11
) {
146
5
    if (const Function *Fn = getLutUsedFunction(GO))
147
4
      return selectSectionForLookupTable(GO, TM, Fn);
148
2.50k
  }
149
2.50k
150
2.50k
  
if (2.50k
isGlobalInSmallSection(GO, TM)2.50k
)
151
36
    return selectSmallSectionForGlobal(GO, Kind, TM);
152
2.46k
153
2.46k
  
if (2.46k
Kind.isCommon()2.46k
) {
154
0
    // This is purely for LTO+Linker Script because commons don't really have a
155
0
    // section. However, the BitcodeSectionWriter pass will query for the
156
0
    // sections of commons (and the linker expects us to know their section) so
157
0
    // we'll return one here.
158
0
    return BSSSection;
159
0
  }
160
2.46k
161
2.46k
  
TRACE2.46k
("default_ELF_section\n");
162
2.46k
  // Otherwise, we work the same as ELF.
163
2.46k
  return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM);
164
2.46k
}
165
166
MCSection *HexagonTargetObjectFile::getExplicitSectionGlobal(
167
12
    const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
168
12
  TRACE("[getExplicitSectionGlobal] GO(" << GO->getName() << ") from("
169
12
        << GO->getSection() << ") ");
170
12
  TRACE((GO->hasPrivateLinkage() ? "private_linkage " : "")
171
12
         << (GO->hasLocalLinkage() ? "local_linkage " : "")
172
12
         << (GO->hasInternalLinkage() ? "internal " : "")
173
12
         << (GO->hasExternalLinkage() ? "external " : "")
174
12
         << (GO->hasCommonLinkage() ? "common_linkage " : "")
175
12
         << (GO->hasCommonLinkage() ? "common " : "" )
176
12
         << (Kind.isCommon() ? "kind_common " : "" )
177
12
         << (Kind.isBSS() ? "kind_bss " : "" )
178
12
         << (Kind.isBSSLocal() ? "kind_bss_local " : "" ));
179
12
180
12
  if (
GO->hasSection()12
) {
181
12
    StringRef Section = GO->getSection();
182
12
    if (Section.find(".access.text.group") != StringRef::npos)
183
0
      return getContext().getELFSection(GO->getSection(), ELF::SHT_PROGBITS,
184
0
                                        ELF::SHF_ALLOC | ELF::SHF_EXECINSTR);
185
12
    
if (12
Section.find(".access.data.group") != StringRef::npos12
)
186
0
      return getContext().getELFSection(GO->getSection(), ELF::SHT_PROGBITS,
187
0
                                        ELF::SHF_WRITE | ELF::SHF_ALLOC);
188
12
  }
189
12
190
12
  
if (12
isGlobalInSmallSection(GO, TM)12
)
191
4
    return selectSmallSectionForGlobal(GO, Kind, TM);
192
8
193
8
  // Otherwise, we work the same as ELF.
194
8
  
TRACE8
("default_ELF_section\n");
195
8
  return TargetLoweringObjectFileELF::getExplicitSectionGlobal(GO, Kind, TM);
196
8
}
197
198
/// Return true if this global value should be placed into small data/bss
199
/// section.
200
bool HexagonTargetObjectFile::isGlobalInSmallSection(const GlobalObject *GO,
201
2.96k
      const TargetMachine &TM) const {
202
2.96k
  // Only global variables, not functions.
203
2.96k
  DEBUG(dbgs() << "Checking if value is in small-data, -G"
204
2.96k
               << SmallDataThreshold << ": \"" << GO->getName() << "\": ");
205
2.96k
  const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO);
206
2.96k
  if (
!GVar2.96k
) {
207
2.41k
    DEBUG(dbgs() << "no, not a global variable\n");
208
2.41k
    return false;
209
2.41k
  }
210
547
211
547
  // Globals with external linkage that have an original section set must be
212
547
  // emitted to that section, regardless of whether we would put them into
213
547
  // small data or not. This is how we can support mixing -G0/-G8 in LTO.
214
547
  
if (547
GVar->hasSection()547
) {
215
15
    bool IsSmall = isSmallDataSection(GVar->getSection());
216
15
    DEBUG(dbgs() << (IsSmall ? "yes" : "no") << ", has section: "
217
15
                 << GVar->getSection() << '\n');
218
15
    return IsSmall;
219
15
  }
220
532
221
532
  
if (532
GVar->isConstant()532
) {
222
84
    DEBUG(dbgs() << "no, is a constant\n");
223
84
    return false;
224
84
  }
225
448
226
448
  bool IsLocal = GVar->hasLocalLinkage();
227
448
  if (
!StaticsInSData && 448
IsLocal448
) {
228
5
    DEBUG(dbgs() << "no, is static\n");
229
5
    return false;
230
5
  }
231
443
232
443
  Type *GType = GVar->getType();
233
443
  if (PointerType *PT = dyn_cast<PointerType>(GType))
234
443
    GType = PT->getElementType();
235
443
236
443
  if (
isa<ArrayType>(GType)443
) {
237
179
    DEBUG(dbgs() << "no, is an array\n");
238
179
    return false;
239
179
  }
240
264
241
264
  // If the type is a struct with no body provided, treat is conservatively.
242
264
  // There cannot be actual definitions of object of such a type in this CU
243
264
  // (only references), so assuming that they are not in sdata is safe. If
244
264
  // these objects end up in the sdata, the references will still be valid.
245
264
  
if (StructType *264
ST264
= dyn_cast<StructType>(GType)) {
246
21
    if (
ST->isOpaque()21
) {
247
0
      DEBUG(dbgs() << "no, has opaque type\n");
248
0
      return false;
249
0
    }
250
264
  }
251
264
252
264
  unsigned Size = GVar->getParent()->getDataLayout().getTypeAllocSize(GType);
253
264
  if (
Size == 0264
) {
254
0
    DEBUG(dbgs() << "no, has size 0\n");
255
0
    return false;
256
0
  }
257
264
  
if (264
Size > SmallDataThreshold264
) {
258
76
    DEBUG(dbgs() << "no, size exceeds sdata threshold: " << Size << '\n');
259
76
    return false;
260
76
  }
261
188
262
188
  
DEBUG188
(dbgs() << "yes\n");
263
188
  return true;
264
188
}
265
266
2.41k
bool HexagonTargetObjectFile::isSmallDataEnabled() const {
267
2.41k
  return SmallDataThreshold > 0;
268
2.41k
}
269
270
0
unsigned HexagonTargetObjectFile::getSmallDataSize() const {
271
0
  return SmallDataThreshold;
272
0
}
273
274
bool HexagonTargetObjectFile::shouldPutJumpTableInFunctionSection(
275
4
    bool UsesLabelDifference, const Function &F) const {
276
4
  return EmitJtInText;
277
4
}
278
279
/// Descends any type down to "elementary" components,
280
/// discovering the smallest addressable one.
281
/// If zero is returned, declaration will not be modified.
282
unsigned HexagonTargetObjectFile::getSmallestAddressableSize(const Type *Ty,
283
40
      const GlobalValue *GV, const TargetMachine &TM) const {
284
40
  // Assign the smallest element access size to the highest
285
40
  // value which assembler can handle.
286
40
  unsigned SmallestElement = 8;
287
40
288
40
  if (!Ty)
289
0
    return 0;
290
40
  switch (Ty->getTypeID()) {
291
0
  case Type::StructTyID: {
292
0
    const StructType *STy = cast<const StructType>(Ty);
293
0
    for (auto &E : STy->elements()) {
294
0
      unsigned AtomicSize = getSmallestAddressableSize(E, GV, TM);
295
0
      if (AtomicSize < SmallestElement)
296
0
        SmallestElement = AtomicSize;
297
0
    }
298
0
    return (STy->getNumElements() == 0) ? 
00
:
SmallestElement0
;
299
40
  }
300
0
  case Type::ArrayTyID: {
301
0
    const ArrayType *ATy = cast<const ArrayType>(Ty);
302
0
    return getSmallestAddressableSize(ATy->getElementType(), GV, TM);
303
40
  }
304
0
  case Type::VectorTyID: {
305
0
    const VectorType *PTy = cast<const VectorType>(Ty);
306
0
    return getSmallestAddressableSize(PTy->getElementType(), GV, TM);
307
40
  }
308
40
  case Type::PointerTyID:
309
40
  case Type::HalfTyID:
310
40
  case Type::FloatTyID:
311
40
  case Type::DoubleTyID:
312
40
  case Type::IntegerTyID: {
313
40
    const DataLayout &DL = GV->getParent()->getDataLayout();
314
40
    // It is unfortunate that DL's function take non-const Type*.
315
40
    return DL.getTypeAllocSize(const_cast<Type*>(Ty));
316
40
  }
317
0
  case Type::FunctionTyID:
318
0
  case Type::VoidTyID:
319
0
  case Type::X86_FP80TyID:
320
0
  case Type::FP128TyID:
321
0
  case Type::PPC_FP128TyID:
322
0
  case Type::LabelTyID:
323
0
  case Type::MetadataTyID:
324
0
  case Type::X86_MMXTyID:
325
0
  case Type::TokenTyID:
326
0
    return 0;
327
0
  }
328
0
329
0
  return 0;
330
0
}
331
332
MCSection *HexagonTargetObjectFile::selectSmallSectionForGlobal(
333
40
    const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
334
40
  const Type *GTy = GO->getType()->getElementType();
335
40
  unsigned Size = getSmallestAddressableSize(GTy, GO, TM);
336
40
337
40
  // If we have -ffunction-section or -fdata-section then we should emit the
338
40
  // global value to a unique section specifically for it... even for sdata.
339
40
  bool EmitUniquedSection = TM.getDataSections();
340
40
341
40
  TRACE("Small data. Size(" << Size << ")");
342
40
  // Handle Small Section classification here.
343
40
  if (
Kind.isBSS() || 40
Kind.isBSSLocal()20
) {
344
20
    // If -mno-sort-sda is not set, find out smallest accessible entity in
345
20
    // declaration and add it to the section name string.
346
20
    // Note. It does not track the actual usage of the value, only its de-
347
20
    // claration. Also, compiler adds explicit pad fields to some struct
348
20
    // declarations - they are currently counted towards smallest addres-
349
20
    // sable entity.
350
20
    if (
NoSmallDataSorting20
) {
351
0
      TRACE(" default sbss\n");
352
0
      return SmallBSSSection;
353
0
    }
354
20
355
20
    StringRef Prefix(".sbss");
356
20
    SmallString<128> Name(Prefix);
357
20
    Name.append(getSectionSuffixForSize(Size));
358
20
359
20
    if (
EmitUniquedSection20
) {
360
0
      Name.append(".");
361
0
      Name.append(GO->getName());
362
0
    }
363
20
    TRACE(" unique sbss(" << Name << ")\n");
364
20
    return getContext().getELFSection(Name.str(), ELF::SHT_NOBITS,
365
20
                ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_HEX_GPREL);
366
20
  }
367
20
368
20
  
if (20
Kind.isCommon()20
) {
369
0
    // This is purely for LTO+Linker Script because commons don't really have a
370
0
    // section. However, the BitcodeSectionWriter pass will query for the
371
0
    // sections of commons (and the linker expects us to know their section) so
372
0
    // we'll return one here.
373
0
    if (NoSmallDataSorting)
374
0
      return BSSSection;
375
0
376
0
    Twine Name = Twine(".scommon") + getSectionSuffixForSize(Size);
377
0
    TRACE(" small COMMON (" << Name << ")\n");
378
0
379
0
    return getContext().getELFSection(Name.str(), ELF::SHT_NOBITS,
380
0
                                      ELF::SHF_WRITE | ELF::SHF_ALLOC |
381
0
                                      ELF::SHF_HEX_GPREL);
382
0
  }
383
20
384
20
  // We could have changed sdata object to a constant... in this
385
20
  // case the Kind could be wrong for it.
386
20
  
if (20
Kind.isMergeableConst()20
) {
387
0
    TRACE(" const_object_as_data ");
388
0
    const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO);
389
0
    if (
GVar->hasSection() && 0
isSmallDataSection(GVar->getSection())0
)
390
0
      Kind = SectionKind::getData();
391
0
  }
392
20
393
20
  if (
Kind.isData()20
) {
394
16
    if (
NoSmallDataSorting16
) {
395
0
      TRACE(" default sdata\n");
396
0
      return SmallDataSection;
397
0
    }
398
16
399
16
    StringRef Prefix(".sdata");
400
16
    SmallString<128> Name(Prefix);
401
16
    Name.append(getSectionSuffixForSize(Size));
402
16
403
16
    if (
EmitUniquedSection16
) {
404
0
      Name.append(".");
405
0
      Name.append(GO->getName());
406
0
    }
407
16
    TRACE(" unique sdata(" << Name << ")\n");
408
16
    return getContext().getELFSection(Name.str(), ELF::SHT_PROGBITS,
409
16
                ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_HEX_GPREL);
410
16
  }
411
4
412
4
  
TRACE4
("default ELF section\n");
413
4
  // Otherwise, we work the same as ELF.
414
4
  return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM);
415
4
}
416
417
// Return the function that uses the lookup table. If there are more
418
// than one live function that uses this look table, bail out and place
419
// the lookup table in default section.
420
const Function *
421
5
HexagonTargetObjectFile::getLutUsedFunction(const GlobalObject *GO) const {
422
5
  const Function *ReturnFn = nullptr;
423
6
  for (auto U : GO->users()) {
424
6
    // validate each instance of user to be a live function.
425
6
    auto *I = dyn_cast<Instruction>(U);
426
6
    if (!I)
427
0
      continue;
428
6
    auto *Bb = I->getParent();
429
6
    if (!Bb)
430
0
      continue;
431
6
    auto *UserFn = Bb->getParent();
432
6
    if (!ReturnFn)
433
5
      ReturnFn = UserFn;
434
1
    else 
if (1
ReturnFn != UserFn1
)
435
1
      return nullptr;
436
4
  }
437
4
  return ReturnFn;
438
4
}
439
440
MCSection *HexagonTargetObjectFile::selectSectionForLookupTable(
441
4
    const GlobalObject *GO, const TargetMachine &TM, const Function *Fn) const {
442
4
443
4
  SectionKind Kind = SectionKind::getText();
444
4
  // If the function has explicit section, place the lookup table in this
445
4
  // explicit section.
446
4
  if (Fn->hasSection())
447
2
    return getExplicitSectionGlobal(Fn, Kind, TM);
448
2
449
2
  const auto *FuncObj = dyn_cast<GlobalObject>(Fn);
450
2
  return SelectSectionForGlobal(FuncObj, Kind, TM);
451
2
}