Coverage Report

Created: 2018-11-16 02:38

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/MC/MCLinkerOptimizationHint.h
Line
Count
Source (jump to first uncovered line)
1
//===- MCLinkerOptimizationHint.h - LOH interface ---------------*- C++ -*-===//
2
//
3
//
4
//                     The LLVM Compiler Infrastructure
5
//
6
// This file is distributed under the University of Illinois Open Source
7
// License. See LICENSE.TXT for details.
8
//
9
//===----------------------------------------------------------------------===//
10
//
11
// This file declares some helpers classes to handle Linker Optimization Hint
12
// (LOH).
13
//
14
// FIXME: LOH interface supports only MachO format at the moment.
15
//===----------------------------------------------------------------------===//
16
17
#ifndef LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
18
#define LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
19
20
#include "llvm/ADT/SmallVector.h"
21
#include "llvm/ADT/StringRef.h"
22
#include "llvm/ADT/StringSwitch.h"
23
#include "llvm/Support/raw_ostream.h"
24
#include <cassert>
25
#include <cstdint>
26
27
namespace llvm {
28
29
class MachObjectWriter;
30
class MCAsmLayout;
31
class MCSymbol;
32
33
/// Linker Optimization Hint Type.
34
enum MCLOHType {
35
  MCLOH_AdrpAdrp = 0x1u,      ///< Adrp xY, _v1@PAGE -> Adrp xY, _v2@PAGE.
36
  MCLOH_AdrpLdr = 0x2u,       ///< Adrp _v@PAGE -> Ldr _v@PAGEOFF.
37
  MCLOH_AdrpAddLdr = 0x3u,    ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Ldr.
38
  MCLOH_AdrpLdrGotLdr = 0x4u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Ldr.
39
  MCLOH_AdrpAddStr = 0x5u,    ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Str.
40
  MCLOH_AdrpLdrGotStr = 0x6u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Str.
41
  MCLOH_AdrpAdd = 0x7u,       ///< Adrp _v@PAGE -> Add _v@PAGEOFF.
42
  MCLOH_AdrpLdrGot = 0x8u     ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF.
43
};
44
45
694
static inline StringRef MCLOHDirectiveName() {
46
694
  return StringRef(".loh");
47
694
}
AArch64AsmParser.cpp:llvm::MCLOHDirectiveName()
Line
Count
Source
45
457
static inline StringRef MCLOHDirectiveName() {
46
457
  return StringRef(".loh");
47
457
}
MCAsmStreamer.cpp:llvm::MCLOHDirectiveName()
Line
Count
Source
45
237
static inline StringRef MCLOHDirectiveName() {
46
237
  return StringRef(".loh");
47
237
}
48
49
11
static inline bool isValidMCLOHType(unsigned Kind) {
50
11
  return Kind >= MCLOH_AdrpAdrp && Kind <= MCLOH_AdrpLdrGot;
51
11
}
52
53
12
static inline int MCLOHNameToId(StringRef Name) {
54
96
#define MCLOHCaseNameToId(Name)     .Case(#Name, MCLOH_ ## Name)
55
12
  return StringSwitch<int>(Name)
56
12
    MCLOHCaseNameToId(AdrpAdrp)
57
12
    MCLOHCaseNameToId(AdrpLdr)
58
12
    MCLOHCaseNameToId(AdrpAddLdr)
59
12
    MCLOHCaseNameToId(AdrpLdrGotLdr)
60
12
    MCLOHCaseNameToId(AdrpAddStr)
61
12
    MCLOHCaseNameToId(AdrpLdrGotStr)
62
12
    MCLOHCaseNameToId(AdrpAdd)
63
12
    MCLOHCaseNameToId(AdrpLdrGot)
64
12
    .Default(-1);
65
12
}
66
67
237
static inline StringRef MCLOHIdToName(MCLOHType Kind) {
68
237
#define MCLOHCaseIdToName(Name)      case MCLOH_ ## Name: return StringRef(#Name);
69
237
  switch (Kind) {
70
237
    
MCLOHCaseIdToName13
(AdrpAdrp);
71
64
    MCLOHCaseIdToName
(AdrpLdr)0
;
72
4
    MCLOHCaseIdToName
(AdrpAddLdr)0
;
73
40
    MCLOHCaseIdToName
(AdrpLdrGotLdr)0
;
74
3
    MCLOHCaseIdToName
(AdrpAddStr)0
;
75
16
    MCLOHCaseIdToName
(AdrpLdrGotStr)0
;
76
24
    MCLOHCaseIdToName
(AdrpAdd)0
;
77
73
    MCLOHCaseIdToName
(AdrpLdrGot)0
;0
78
237
  }
79
237
  
return StringRef()0
;
80
237
}
81
82
21
static inline int MCLOHIdToNbArgs(MCLOHType Kind) {
83
21
  switch (Kind) {
84
21
    // LOH with two arguments
85
21
  case MCLOH_AdrpAdrp:
86
13
  case MCLOH_AdrpLdr:
87
13
  case MCLOH_AdrpAdd:
88
13
  case MCLOH_AdrpLdrGot:
89
13
    return 2;
90
13
    // LOH with three arguments
91
13
  case MCLOH_AdrpAddLdr:
92
8
  case MCLOH_AdrpLdrGotLdr:
93
8
  case MCLOH_AdrpAddStr:
94
8
  case MCLOH_AdrpLdrGotStr:
95
8
    return 3;
96
0
  }
97
0
  return -1;
98
0
}
99
100
/// Store Linker Optimization Hint information (LOH).
101
class MCLOHDirective {
102
  MCLOHType Kind;
103
104
  /// Arguments of this directive. Order matters.
105
  SmallVector<MCSymbol *, 3> Args;
106
107
  /// Emit this directive in \p OutStream using the information available
108
  /// in the given \p ObjWriter and \p Layout to get the address of the
109
  /// arguments within the object file.
110
  void emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter,
111
                 const MCAsmLayout &Layout) const;
112
113
public:
114
  using LOHArgs = SmallVectorImpl<MCSymbol *>;
115
116
  MCLOHDirective(MCLOHType Kind, const LOHArgs &Args)
117
677k
      : Kind(Kind), Args(Args.begin(), Args.end()) {
118
677k
    assert(isValidMCLOHType(Kind) && "Invalid LOH directive type!");
119
677k
  }
120
121
  MCLOHType getKind() const { return Kind; }
122
123
  const LOHArgs &getArgs() const { return Args; }
124
125
  /// Emit this directive as:
126
  /// <kind, numArgs, addr1, ..., addrN>
127
  void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const;
128
129
  /// Get the size in bytes of this directive if emitted in \p ObjWriter with
130
  /// the given \p Layout.
131
  uint64_t getEmitSize(const MachObjectWriter &ObjWriter,
132
                       const MCAsmLayout &Layout) const;
133
};
134
135
class MCLOHContainer {
136
  /// Keep track of the emit size of all the LOHs.
137
  mutable uint64_t EmitSize = 0;
138
139
  /// Keep track of all LOH directives.
140
  SmallVector<MCLOHDirective, 32> Directives;
141
142
public:
143
  using LOHDirectives = SmallVectorImpl<MCLOHDirective>;
144
145
42.6k
  MCLOHContainer() = default;
146
147
  /// Const accessor to the directives.
148
0
  const LOHDirectives &getDirectives() const {
149
0
    return Directives;
150
0
  }
151
152
  /// Add the directive of the given kind \p Kind with the given arguments
153
  /// \p Args to the container.
154
677k
  void addDirective(MCLOHType Kind, const MCLOHDirective::LOHArgs &Args) {
155
677k
    Directives.push_back(MCLOHDirective(Kind, Args));
156
677k
  }
157
158
  /// Get the size of the directives if emitted.
159
  uint64_t getEmitSize(const MachObjectWriter &ObjWriter,
160
14.0k
                       const MCAsmLayout &Layout) const {
161
14.0k
    if (!EmitSize) {
162
14.0k
      for (const MCLOHDirective &D : Directives)
163
677k
        EmitSize += D.getEmitSize(ObjWriter, Layout);
164
14.0k
    }
165
14.0k
    return EmitSize;
166
14.0k
  }
167
168
  /// Emit all Linker Optimization Hint in one big table.
169
  /// Each line of the table is emitted by LOHDirective::emit.
170
6.57k
  void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {
171
6.57k
    for (const MCLOHDirective &D : Directives)
172
677k
      D.emit(ObjWriter, Layout);
173
6.57k
  }
174
175
28.6k
  void reset() {
176
28.6k
    Directives.clear();
177
28.6k
    EmitSize = 0;
178
28.6k
  }
179
};
180
181
// Add types for specialized template using MCSymbol.
182
using MCLOHArgs = MCLOHDirective::LOHArgs;
183
using MCLOHDirectives = MCLOHContainer::LOHDirectives;
184
185
} // end namespace llvm
186
187
#endif // LLVM_MC_MCLINKEROPTIMIZATIONHINT_H