Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Lanai/LanaiTargetObjectFile.cpp
Line
Count
Source (jump to first uncovered line)
1
//
2
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3
// See https://llvm.org/LICENSE.txt for license information.
4
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5
//
6
//===----------------------------------------------------------------------===//
7
8
#include "LanaiTargetObjectFile.h"
9
10
#include "LanaiSubtarget.h"
11
#include "LanaiTargetMachine.h"
12
#include "llvm/BinaryFormat/ELF.h"
13
#include "llvm/IR/DataLayout.h"
14
#include "llvm/IR/DerivedTypes.h"
15
#include "llvm/IR/GlobalVariable.h"
16
#include "llvm/MC/MCContext.h"
17
#include "llvm/MC/MCSectionELF.h"
18
#include "llvm/Support/CommandLine.h"
19
#include "llvm/Target/TargetMachine.h"
20
21
using namespace llvm;
22
23
static cl::opt<unsigned> SSThreshold(
24
    "lanai-ssection-threshold", cl::Hidden,
25
    cl::desc("Small data and bss section threshold size (default=0)"),
26
    cl::init(0));
27
28
void LanaiTargetObjectFile::Initialize(MCContext &Ctx,
29
22
                                       const TargetMachine &TM) {
30
22
  TargetLoweringObjectFileELF::Initialize(Ctx, TM);
31
22
  InitializeELF(TM.Options.UseInitArray);
32
22
33
22
  SmallDataSection = getContext().getELFSection(
34
22
      ".sdata", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
35
22
  SmallBSSSection = getContext().getELFSection(".sbss", ELF::SHT_NOBITS,
36
22
                                               ELF::SHF_WRITE | ELF::SHF_ALLOC);
37
22
}
38
39
// A address must be loaded from a small section if its size is less than the
40
// small section size threshold. Data in this section must be addressed using
41
// gp_rel operator.
42
0
static bool isInSmallSection(uint64_t Size) {
43
0
  // gcc has traditionally not treated zero-sized objects as small data, so this
44
0
  // is effectively part of the ABI.
45
0
  return Size > 0 && Size <= SSThreshold;
46
0
}
47
48
// Return true if this global address should be placed into small data/bss
49
// section.
50
bool LanaiTargetObjectFile::isGlobalInSmallSection(
51
9
    const GlobalObject *GO, const TargetMachine &TM) const {
52
9
  if (GO == nullptr) 
return TM.getCodeModel() == CodeModel::Small0
;
53
9
54
9
  // We first check the case where global is a declaration, because finding
55
9
  // section kind using getKindForGlobal() is only allowed for global
56
9
  // definitions.
57
9
  if (GO->isDeclaration() || 
GO->hasAvailableExternallyLinkage()5
)
58
4
    return isGlobalInSmallSectionImpl(GO, TM);
59
5
60
5
  return isGlobalInSmallSection(GO, TM, getKindForGlobal(GO, TM));
61
5
}
62
63
// Return true if this global address should be placed into small data/bss
64
// section.
65
bool LanaiTargetObjectFile::isGlobalInSmallSection(const GlobalObject *GO,
66
                                                   const TargetMachine &TM,
67
6
                                                   SectionKind Kind) const {
68
6
  return isGlobalInSmallSectionImpl(GO, TM);
69
6
}
70
71
// Return true if this global address should be placed into small data/bss
72
// section. This method does all the work, except for checking the section
73
// kind.
74
bool LanaiTargetObjectFile::isGlobalInSmallSectionImpl(
75
10
    const GlobalObject *GO, const TargetMachine &TM) const {
76
10
  const auto *GVA = dyn_cast<GlobalVariable>(GO);
77
10
78
10
  // If not a GlobalVariable, only consider the code model.
79
10
  if (!GVA) 
return TM.getCodeModel() == CodeModel::Small0
;
80
10
81
10
  // Global values placed in sections starting with .ldata do not fit in
82
10
  // 21-bits, so always use large memory access for them. FIXME: This is a
83
10
  // workaround for a tool limitation.
84
10
  if (GVA->getSection().startswith(".ldata"))
85
2
    return false;
86
8
87
8
  if (TM.getCodeModel() == CodeModel::Small)
88
2
    return true;
89
6
90
6
  if (GVA->hasLocalLinkage())
91
1
    return false;
92
5
93
5
  if (((GVA->hasExternalLinkage() && 
GVA->isDeclaration()2
) ||
94
5
       
GVA->hasCommonLinkage()3
))
95
5
    return false;
96
0
97
0
  Type *Ty = GVA->getValueType();
98
0
  return isInSmallSection(
99
0
      GVA->getParent()->getDataLayout().getTypeAllocSize(Ty));
100
0
}
101
102
MCSection *LanaiTargetObjectFile::SelectSectionForGlobal(
103
93
    const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
104
93
  // Handle Small Section classification here.
105
93
  if (Kind.isBSS() && 
isGlobalInSmallSection(GO, TM, Kind)1
)
106
0
    return SmallBSSSection;
107
93
  if (Kind.isData() && 
isGlobalInSmallSection(GO, TM, Kind)0
)
108
0
    return SmallDataSection;
109
93
110
93
  // Otherwise, we work the same as ELF.
111
93
  return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM);
112
93
}
113
114
/// Return true if this constant should be placed into small data section.
115
bool LanaiTargetObjectFile::isConstantInSmallSection(const DataLayout &DL,
116
0
                                                     const Constant *CN) const {
117
0
  return isInSmallSection(DL.getTypeAllocSize(CN->getType()));
118
0
}
119
120
MCSection *LanaiTargetObjectFile::getSectionForConstant(const DataLayout &DL,
121
                                                        SectionKind Kind,
122
                                                        const Constant *C,
123
0
                                                        unsigned &Align) const {
124
0
  if (isConstantInSmallSection(DL, C))
125
0
    return SmallDataSection;
126
0
127
0
  // Otherwise, we work the same as ELF.
128
0
  return TargetLoweringObjectFileELF::getSectionForConstant(DL, Kind, C, Align);
129
0
}