Coverage Report

Created: 2019-07-24 05:18

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