Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/ProfileData/InstrProfReader.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- InstrProfReader.cpp - Instrumented profiling reader ----------------===//
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 support for reading profiling data for clang's
11
// instrumentation based PGO and coverage.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "llvm/ProfileData/InstrProfReader.h"
16
#include "llvm/ADT/ArrayRef.h"
17
#include "llvm/ADT/STLExtras.h"
18
#include "llvm/ADT/StringRef.h"
19
#include "llvm/IR/ProfileSummary.h"
20
#include "llvm/ProfileData/InstrProf.h"
21
#include "llvm/ProfileData/ProfileCommon.h"
22
#include "llvm/Support/Endian.h"
23
#include "llvm/Support/Error.h"
24
#include "llvm/Support/ErrorOr.h"
25
#include "llvm/Support/MemoryBuffer.h"
26
#include "llvm/Support/SwapByteOrder.h"
27
#include <algorithm>
28
#include <cctype>
29
#include <cstddef>
30
#include <cstdint>
31
#include <limits>
32
#include <memory>
33
#include <system_error>
34
#include <utility>
35
#include <vector>
36
37
using namespace llvm;
38
39
static Expected<std::unique_ptr<MemoryBuffer>>
40
382
setupMemoryBuffer(const Twine &Path) {
41
382
  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
42
382
      MemoryBuffer::getFileOrSTDIN(Path);
43
382
  if (std::error_code EC = BufferOrErr.getError())
44
4
    return errorCodeToError(EC);
45
378
  return std::move(BufferOrErr.get());
46
378
}
47
48
495
static Error initializeReader(InstrProfReader &Reader) {
49
495
  return Reader.readHeader();
50
495
}
51
52
Expected<std::unique_ptr<InstrProfReader>>
53
192
InstrProfReader::create(const Twine &Path) {
54
192
  // Set up the buffer to read.
55
192
  auto BufferOrError = setupMemoryBuffer(Path);
56
192
  if (Error E = BufferOrError.takeError())
57
0
    return std::move(E);
58
192
  return InstrProfReader::create(std::move(BufferOrError.get()));
59
192
}
60
61
Expected<std::unique_ptr<InstrProfReader>>
62
192
InstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer) {
63
192
  // Sanity check the buffer.
64
192
  if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max())
65
0
    return make_error<InstrProfError>(instrprof_error::too_large);
66
192
67
192
  
if (192
Buffer->getBufferSize() == 0192
)
68
3
    return make_error<InstrProfError>(instrprof_error::empty_raw_profile);
69
189
70
189
  std::unique_ptr<InstrProfReader> Result;
71
189
  // Create the reader.
72
189
  if (IndexedInstrProfReader::hasFormat(*Buffer))
73
51
    Result.reset(new IndexedInstrProfReader(std::move(Buffer)));
74
138
  else 
if (138
RawInstrProfReader64::hasFormat(*Buffer)138
)
75
8
    Result.reset(new RawInstrProfReader64(std::move(Buffer)));
76
130
  else 
if (130
RawInstrProfReader32::hasFormat(*Buffer)130
)
77
2
    Result.reset(new RawInstrProfReader32(std::move(Buffer)));
78
128
  else 
if (128
TextInstrProfReader::hasFormat(*Buffer)128
)
79
127
    Result.reset(new TextInstrProfReader(std::move(Buffer)));
80
128
  else
81
1
    return make_error<InstrProfError>(instrprof_error::unrecognized_format);
82
188
83
188
  // Initialize the reader and return the result.
84
188
  
if (Error 188
E188
= initializeReader(*Result))
85
2
    return std::move(E);
86
186
87
186
  return std::move(Result);
88
186
}
89
90
Expected<std::unique_ptr<IndexedInstrProfReader>>
91
190
IndexedInstrProfReader::create(const Twine &Path) {
92
190
  // Set up the buffer to read.
93
190
  auto BufferOrError = setupMemoryBuffer(Path);
94
190
  if (Error E = BufferOrError.takeError())
95
4
    return std::move(E);
96
186
  return IndexedInstrProfReader::create(std::move(BufferOrError.get()));
97
186
}
98
99
Expected<std::unique_ptr<IndexedInstrProfReader>>
100
307
IndexedInstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer) {
101
307
  // Sanity check the buffer.
102
307
  if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max())
103
0
    return make_error<InstrProfError>(instrprof_error::too_large);
104
307
105
307
  // Create the reader.
106
307
  
if (307
!IndexedInstrProfReader::hasFormat(*Buffer)307
)
107
0
    return make_error<InstrProfError>(instrprof_error::bad_magic);
108
307
  auto Result = llvm::make_unique<IndexedInstrProfReader>(std::move(Buffer));
109
307
110
307
  // Initialize the reader and return the result.
111
307
  if (Error E = initializeReader(*Result))
112
0
    return std::move(E);
113
307
114
307
  return std::move(Result);
115
307
}
116
117
609
void InstrProfIterator::Increment() {
118
609
  if (auto 
E609
= Reader->readNextRecord(Record)) {
119
191
    // Handle errors in the reader.
120
191
    InstrProfError::take(std::move(E));
121
191
    *this = InstrProfIterator();
122
191
  }
123
609
}
124
125
128
bool TextInstrProfReader::hasFormat(const MemoryBuffer &Buffer) {
126
128
  // Verify that this really looks like plain ASCII text by checking a
127
128
  // 'reasonable' number of characters (up to profile magic size).
128
128
  size_t count = std::min(Buffer.getBufferSize(), sizeof(uint64_t));
129
128
  StringRef buffer = Buffer.getBufferStart();
130
128
  return count == 0 ||
131
128
         std::all_of(buffer.begin(), buffer.begin() + count,
132
1.00k
                     [](char c) 
{ return ::isprint(c) || 1.00k
::isspace(c)161
; });
133
128
}
134
135
// Read the profile variant flag from the header: ":FE" means this is a FE
136
// generated profile. ":IR" means this is an IR level profile. Other strings
137
// with a leading ':' will be reported an error format.
138
127
Error TextInstrProfReader::readHeader() {
139
127
  Symtab.reset(new InstrProfSymtab());
140
127
  bool IsIRInstr = false;
141
127
  if (
!Line->startswith(":")127
) {
142
100
    IsIRLevelProfile = false;
143
100
    return success();
144
100
  }
145
27
  StringRef Str = (Line)->substr(1);
146
27
  if (Str.equals_lower("ir"))
147
26
    IsIRInstr = true;
148
1
  else 
if (1
Str.equals_lower("fe")1
)
149
1
    IsIRInstr = false;
150
1
  else
151
0
    return error(instrprof_error::bad_header);
152
27
153
27
  ++Line;
154
27
  IsIRLevelProfile = IsIRInstr;
155
27
  return success();
156
27
}
157
158
Error
159
240
TextInstrProfReader::readValueProfileData(InstrProfRecord &Record) {
160
240
161
240
#define CHECK_LINE_END(Line)                                                   \
162
175
  
if (175
Line.is_at_end()157
) \
163
175
    return error(instrprof_error::truncated);
164
240
#define READ_NUM(Str, Dst)                                                     \
165
210
  
if (210
(Str).getAsInteger(10, (Dst))210
) \
166
210
    return error(instrprof_error::malformed);
167
240
#define VP_READ_ADVANCE(Val)                                                   \
168
91
  
CHECK_LINE_END73
(Line); \
169
72
  uint32_t Val;                                                                \
170
72
  
READ_NUM72
((*Line), (Val)); \
171
72
  Line++;
172
240
173
240
  if (Line.is_at_end())
174
110
    return success();
175
130
176
130
  uint32_t NumValueKinds;
177
130
  if (
Line->getAsInteger(10, NumValueKinds)130
) {
178
117
    // No value profile data
179
117
    return success();
180
117
  }
181
13
  
if (13
NumValueKinds == 0 || 13
NumValueKinds > IPVK_Last + 113
)
182
0
    return error(instrprof_error::malformed);
183
13
  Line++;
184
13
185
28
  for (uint32_t VK = 0; 
VK < NumValueKinds28
;
VK++15
) {
186
18
    
VP_READ_ADVANCE18
(ValueKind);
187
18
    if (ValueKind > IPVK_Last)
188
0
      return error(instrprof_error::malformed);
189
18
    
VP_READ_ADVANCE18
(NumValueSites);
190
18
    if (!NumValueSites)
191
0
      continue;
192
18
193
18
    Record.reserveSites(VK, NumValueSites);
194
52
    for (uint32_t S = 0; 
S < NumValueSites52
;
S++34
) {
195
37
      
VP_READ_ADVANCE37
(NumValueData);
196
72
197
72
      std::vector<InstrProfValueData> CurrentValues;
198
118
      for (uint32_t V = 0; 
V < NumValueData118
;
V++82
) {
199
84
        
CHECK_LINE_END84
(Line);
200
84
        std::pair<StringRef, StringRef> VD = Line->rsplit(':');
201
84
        uint64_t TakenCount, Value;
202
84
        if (
ValueKind == IPVK_IndirectCallTarget84
) {
203
30
          if (Error E = Symtab->addFuncName(VD.first))
204
0
            return E;
205
30
          Value = IndexedInstrProf::ComputeHash(VD.first);
206
84
        } else {
207
54
          
READ_NUM54
(VD.first, Value);
208
54
        }
209
84
        
READ_NUM84
(VD.second, TakenCount)84
;
210
82
        CurrentValues.push_back({Value, TakenCount});
211
82
        Line++;
212
82
      }
213
34
      Record.addValueData(ValueKind, S, CurrentValues.data(), NumValueData,
214
34
                          nullptr);
215
34
    }
216
18
  }
217
10
  return success();
218
240
219
240
#undef CHECK_LINE_END
220
240
#undef READ_NUM
221
240
#undef VP_READ_ADVANCE
222
240
}
223
224
365
Error TextInstrProfReader::readNextRecord(NamedInstrProfRecord &Record) {
225
365
  // Skip empty lines and comments.
226
365
  while (
!Line.is_at_end() && 365
(Line->empty() || 246
Line->startswith("#")246
))
227
0
    ++Line;
228
365
  // If we hit EOF while looking for a name, we're done.
229
365
  if (
Line.is_at_end()365
) {
230
119
    Symtab->finalizeSymtab();
231
119
    return error(instrprof_error::eof);
232
119
  }
233
246
234
246
  // Read the function name.
235
246
  Record.Name = *Line++;
236
246
  if (Error E = Symtab->addFuncName(Record.Name))
237
0
    return E;
238
246
239
246
  // Read the function hash.
240
246
  
if (246
Line.is_at_end()246
)
241
0
    return error(instrprof_error::truncated);
242
246
  
if (246
(Line++)->getAsInteger(0, Record.Hash)246
)
243
2
    return error(instrprof_error::malformed);
244
244
245
244
  // Read the number of counters.
246
244
  uint64_t NumCounters;
247
244
  if (Line.is_at_end())
248
0
    return error(instrprof_error::truncated);
249
244
  
if (244
(Line++)->getAsInteger(10, NumCounters)244
)
250
0
    return error(instrprof_error::malformed);
251
244
  
if (244
NumCounters == 0244
)
252
1
    return error(instrprof_error::malformed);
253
243
254
243
  // Read each counter and fill our internal storage with the values.
255
243
  Record.Clear();
256
243
  Record.Counts.reserve(NumCounters);
257
874
  for (uint64_t I = 0; 
I < NumCounters874
;
++I631
) {
258
633
    if (Line.is_at_end())
259
0
      return error(instrprof_error::truncated);
260
633
    uint64_t Count;
261
633
    if ((Line++)->getAsInteger(10, Count))
262
2
      return error(instrprof_error::malformed);
263
631
    Record.Counts.push_back(Count);
264
631
  }
265
243
266
243
  // Check if value profile data exists and read it if so.
267
241
  
if (Error 241
E241
= readValueProfileData(Record))
268
3
    return E;
269
238
270
238
  // This is needed to avoid two pass parsing because llvm-profdata
271
238
  // does dumping while reading.
272
238
  Symtab->finalizeSymtab();
273
238
  return success();
274
238
}
275
276
template <class IntPtrT>
277
278
bool RawInstrProfReader<IntPtrT>::hasFormat(const MemoryBuffer &DataBuffer) {
278
278
  if (DataBuffer.getBufferSize() < sizeof(uint64_t))
279
6
    return false;
280
272
  uint64_t Magic =
281
272
    *reinterpret_cast<const uint64_t *>(DataBuffer.getBufferStart());
282
272
  return RawInstrProf::getMagic<IntPtrT>() == Magic ||
283
258
         sys::getSwappedBytes(RawInstrProf::getMagic<IntPtrT>()) == Magic;
284
278
}
llvm::RawInstrProfReader<unsigned int>::hasFormat(llvm::MemoryBuffer const&)
Line
Count
Source
277
132
bool RawInstrProfReader<IntPtrT>::hasFormat(const MemoryBuffer &DataBuffer) {
278
132
  if (DataBuffer.getBufferSize() < sizeof(uint64_t))
279
3
    return false;
280
129
  uint64_t Magic =
281
129
    *reinterpret_cast<const uint64_t *>(DataBuffer.getBufferStart());
282
129
  return RawInstrProf::getMagic<IntPtrT>() == Magic ||
283
127
         sys::getSwappedBytes(RawInstrProf::getMagic<IntPtrT>()) == Magic;
284
132
}
llvm::RawInstrProfReader<unsigned long long>::hasFormat(llvm::MemoryBuffer const&)
Line
Count
Source
277
146
bool RawInstrProfReader<IntPtrT>::hasFormat(const MemoryBuffer &DataBuffer) {
278
146
  if (DataBuffer.getBufferSize() < sizeof(uint64_t))
279
3
    return false;
280
143
  uint64_t Magic =
281
143
    *reinterpret_cast<const uint64_t *>(DataBuffer.getBufferStart());
282
143
  return RawInstrProf::getMagic<IntPtrT>() == Magic ||
283
131
         sys::getSwappedBytes(RawInstrProf::getMagic<IntPtrT>()) == Magic;
284
146
}
285
286
template <class IntPtrT>
287
10
Error RawInstrProfReader<IntPtrT>::readHeader() {
288
10
  if (!hasFormat(*DataBuffer))
289
0
    return error(instrprof_error::bad_magic);
290
10
  
if (10
DataBuffer->getBufferSize() < sizeof(RawInstrProf::Header)10
)
291
2
    return error(instrprof_error::bad_header);
292
8
  auto *Header = reinterpret_cast<const RawInstrProf::Header *>(
293
8
      DataBuffer->getBufferStart());
294
8
  ShouldSwapBytes = Header->Magic != RawInstrProf::getMagic<IntPtrT>();
295
8
  return readHeader(*Header);
296
8
}
llvm::RawInstrProfReader<unsigned long long>::readHeader()
Line
Count
Source
287
8
Error RawInstrProfReader<IntPtrT>::readHeader() {
288
8
  if (!hasFormat(*DataBuffer))
289
0
    return error(instrprof_error::bad_magic);
290
8
  
if (8
DataBuffer->getBufferSize() < sizeof(RawInstrProf::Header)8
)
291
2
    return error(instrprof_error::bad_header);
292
6
  auto *Header = reinterpret_cast<const RawInstrProf::Header *>(
293
6
      DataBuffer->getBufferStart());
294
6
  ShouldSwapBytes = Header->Magic != RawInstrProf::getMagic<IntPtrT>();
295
6
  return readHeader(*Header);
296
6
}
llvm::RawInstrProfReader<unsigned int>::readHeader()
Line
Count
Source
287
2
Error RawInstrProfReader<IntPtrT>::readHeader() {
288
2
  if (!hasFormat(*DataBuffer))
289
0
    return error(instrprof_error::bad_magic);
290
2
  
if (2
DataBuffer->getBufferSize() < sizeof(RawInstrProf::Header)2
)
291
0
    return error(instrprof_error::bad_header);
292
2
  auto *Header = reinterpret_cast<const RawInstrProf::Header *>(
293
2
      DataBuffer->getBufferStart());
294
2
  ShouldSwapBytes = Header->Magic != RawInstrProf::getMagic<IntPtrT>();
295
2
  return readHeader(*Header);
296
2
}
297
298
template <class IntPtrT>
299
9
Error RawInstrProfReader<IntPtrT>::readNextHeader(const char *CurrentPos) {
300
9
  const char *End = DataBuffer->getBufferEnd();
301
9
  // Skip zero padding between profiles.
302
9
  while (
CurrentPos != End && 9
*CurrentPos == 01
)
303
0
    ++CurrentPos;
304
9
  // If there's nothing left, we're done.
305
9
  if (CurrentPos == End)
306
8
    return make_error<InstrProfError>(instrprof_error::eof);
307
1
  // If there isn't enough space for another header, this is probably just
308
1
  // garbage at the end of the file.
309
1
  
if (1
CurrentPos + sizeof(RawInstrProf::Header) > End1
)
310
0
    return make_error<InstrProfError>(instrprof_error::malformed);
311
1
  // The writer ensures each profile is padded to start at an aligned address.
312
1
  
if (1
reinterpret_cast<size_t>(CurrentPos) % alignof(uint64_t)1
)
313
0
    return make_error<InstrProfError>(instrprof_error::malformed);
314
1
  // The magic should have the same byte order as in the previous header.
315
1
  uint64_t Magic = *reinterpret_cast<const uint64_t *>(CurrentPos);
316
1
  if (Magic != swap(RawInstrProf::getMagic<IntPtrT>()))
317
0
    return make_error<InstrProfError>(instrprof_error::bad_magic);
318
1
319
1
  // There's another profile to read, so we need to process the header.
320
1
  auto *Header = reinterpret_cast<const RawInstrProf::Header *>(CurrentPos);
321
1
  return readHeader(*Header);
322
1
}
llvm::RawInstrProfReader<unsigned long long>::readNextHeader(char const*)
Line
Count
Source
299
7
Error RawInstrProfReader<IntPtrT>::readNextHeader(const char *CurrentPos) {
300
7
  const char *End = DataBuffer->getBufferEnd();
301
7
  // Skip zero padding between profiles.
302
7
  while (
CurrentPos != End && 7
*CurrentPos == 01
)
303
0
    ++CurrentPos;
304
7
  // If there's nothing left, we're done.
305
7
  if (CurrentPos == End)
306
6
    return make_error<InstrProfError>(instrprof_error::eof);
307
1
  // If there isn't enough space for another header, this is probably just
308
1
  // garbage at the end of the file.
309
1
  
if (1
CurrentPos + sizeof(RawInstrProf::Header) > End1
)
310
0
    return make_error<InstrProfError>(instrprof_error::malformed);
311
1
  // The writer ensures each profile is padded to start at an aligned address.
312
1
  
if (1
reinterpret_cast<size_t>(CurrentPos) % alignof(uint64_t)1
)
313
0
    return make_error<InstrProfError>(instrprof_error::malformed);
314
1
  // The magic should have the same byte order as in the previous header.
315
1
  uint64_t Magic = *reinterpret_cast<const uint64_t *>(CurrentPos);
316
1
  if (Magic != swap(RawInstrProf::getMagic<IntPtrT>()))
317
0
    return make_error<InstrProfError>(instrprof_error::bad_magic);
318
1
319
1
  // There's another profile to read, so we need to process the header.
320
1
  auto *Header = reinterpret_cast<const RawInstrProf::Header *>(CurrentPos);
321
1
  return readHeader(*Header);
322
1
}
llvm::RawInstrProfReader<unsigned int>::readNextHeader(char const*)
Line
Count
Source
299
2
Error RawInstrProfReader<IntPtrT>::readNextHeader(const char *CurrentPos) {
300
2
  const char *End = DataBuffer->getBufferEnd();
301
2
  // Skip zero padding between profiles.
302
2
  while (
CurrentPos != End && 2
*CurrentPos == 00
)
303
0
    ++CurrentPos;
304
2
  // If there's nothing left, we're done.
305
2
  if (CurrentPos == End)
306
2
    return make_error<InstrProfError>(instrprof_error::eof);
307
0
  // If there isn't enough space for another header, this is probably just
308
0
  // garbage at the end of the file.
309
0
  
if (0
CurrentPos + sizeof(RawInstrProf::Header) > End0
)
310
0
    return make_error<InstrProfError>(instrprof_error::malformed);
311
0
  // The writer ensures each profile is padded to start at an aligned address.
312
0
  
if (0
reinterpret_cast<size_t>(CurrentPos) % alignof(uint64_t)0
)
313
0
    return make_error<InstrProfError>(instrprof_error::malformed);
314
0
  // The magic should have the same byte order as in the previous header.
315
0
  uint64_t Magic = *reinterpret_cast<const uint64_t *>(CurrentPos);
316
0
  if (Magic != swap(RawInstrProf::getMagic<IntPtrT>()))
317
0
    return make_error<InstrProfError>(instrprof_error::bad_magic);
318
0
319
0
  // There's another profile to read, so we need to process the header.
320
0
  auto *Header = reinterpret_cast<const RawInstrProf::Header *>(CurrentPos);
321
0
  return readHeader(*Header);
322
0
}
323
324
template <class IntPtrT>
325
9
Error RawInstrProfReader<IntPtrT>::createSymtab(InstrProfSymtab &Symtab) {
326
9
  if (Error E = Symtab.create(StringRef(NamesStart, NamesSize)))
327
0
    return error(std::move(E));
328
55
  
for (const RawInstrProf::ProfileData<IntPtrT> *I = Data; 9
I != DataEnd55
;
++I46
) {
329
46
    const IntPtrT FPtr = swap(I->FunctionPointer);
330
46
    if (!FPtr)
331
10
      continue;
332
36
    Symtab.mapAddress(FPtr, I->NameRef);
333
36
  }
334
9
  Symtab.finalizeSymtab();
335
9
  return success();
336
9
}
llvm::RawInstrProfReader<unsigned long long>::createSymtab(llvm::InstrProfSymtab&)
Line
Count
Source
325
7
Error RawInstrProfReader<IntPtrT>::createSymtab(InstrProfSymtab &Symtab) {
326
7
  if (Error E = Symtab.create(StringRef(NamesStart, NamesSize)))
327
0
    return error(std::move(E));
328
49
  
for (const RawInstrProf::ProfileData<IntPtrT> *I = Data; 7
I != DataEnd49
;
++I42
) {
329
42
    const IntPtrT FPtr = swap(I->FunctionPointer);
330
42
    if (!FPtr)
331
6
      continue;
332
36
    Symtab.mapAddress(FPtr, I->NameRef);
333
36
  }
334
7
  Symtab.finalizeSymtab();
335
7
  return success();
336
7
}
llvm::RawInstrProfReader<unsigned int>::createSymtab(llvm::InstrProfSymtab&)
Line
Count
Source
325
2
Error RawInstrProfReader<IntPtrT>::createSymtab(InstrProfSymtab &Symtab) {
326
2
  if (Error E = Symtab.create(StringRef(NamesStart, NamesSize)))
327
0
    return error(std::move(E));
328
6
  
for (const RawInstrProf::ProfileData<IntPtrT> *I = Data; 2
I != DataEnd6
;
++I4
) {
329
4
    const IntPtrT FPtr = swap(I->FunctionPointer);
330
4
    if (!FPtr)
331
4
      continue;
332
0
    Symtab.mapAddress(FPtr, I->NameRef);
333
0
  }
334
2
  Symtab.finalizeSymtab();
335
2
  return success();
336
2
}
337
338
template <class IntPtrT>
339
Error RawInstrProfReader<IntPtrT>::readHeader(
340
9
    const RawInstrProf::Header &Header) {
341
9
  Version = swap(Header.Version);
342
9
  if (
GET_VERSION9
(Version) != RawInstrProf::Version9
)
343
0
    return error(instrprof_error::unsupported_version);
344
9
345
9
  CountersDelta = swap(Header.CountersDelta);
346
9
  NamesDelta = swap(Header.NamesDelta);
347
9
  auto DataSize = swap(Header.DataSize);
348
9
  auto CountersSize = swap(Header.CountersSize);
349
9
  NamesSize = swap(Header.NamesSize);
350
9
  ValueKindLast = swap(Header.ValueKindLast);
351
9
352
9
  auto DataSizeInBytes = DataSize * sizeof(RawInstrProf::ProfileData<IntPtrT>);
353
9
  auto PaddingSize = getNumPaddingBytes(NamesSize);
354
9
355
9
  ptrdiff_t DataOffset = sizeof(RawInstrProf::Header);
356
9
  ptrdiff_t CountersOffset = DataOffset + DataSizeInBytes;
357
9
  ptrdiff_t NamesOffset = CountersOffset + sizeof(uint64_t) * CountersSize;
358
9
  ptrdiff_t ValueDataOffset = NamesOffset + NamesSize + PaddingSize;
359
9
360
9
  auto *Start = reinterpret_cast<const char *>(&Header);
361
9
  if (Start + ValueDataOffset > DataBuffer->getBufferEnd())
362
0
    return error(instrprof_error::bad_header);
363
9
364
9
  Data = reinterpret_cast<const RawInstrProf::ProfileData<IntPtrT> *>(
365
9
      Start + DataOffset);
366
9
  DataEnd = Data + DataSize;
367
9
  CountersStart = reinterpret_cast<const uint64_t *>(Start + CountersOffset);
368
9
  NamesStart = Start + NamesOffset;
369
9
  ValueDataStart = reinterpret_cast<const uint8_t *>(Start + ValueDataOffset);
370
9
371
9
  std::unique_ptr<InstrProfSymtab> NewSymtab = make_unique<InstrProfSymtab>();
372
9
  if (Error E = createSymtab(*NewSymtab.get()))
373
0
    return E;
374
9
375
9
  Symtab = std::move(NewSymtab);
376
9
  return success();
377
9
}
llvm::RawInstrProfReader<unsigned int>::readHeader(llvm::RawInstrProf::Header const&)
Line
Count
Source
340
2
    const RawInstrProf::Header &Header) {
341
2
  Version = swap(Header.Version);
342
2
  if (
GET_VERSION2
(Version) != RawInstrProf::Version2
)
343
0
    return error(instrprof_error::unsupported_version);
344
2
345
2
  CountersDelta = swap(Header.CountersDelta);
346
2
  NamesDelta = swap(Header.NamesDelta);
347
2
  auto DataSize = swap(Header.DataSize);
348
2
  auto CountersSize = swap(Header.CountersSize);
349
2
  NamesSize = swap(Header.NamesSize);
350
2
  ValueKindLast = swap(Header.ValueKindLast);
351
2
352
2
  auto DataSizeInBytes = DataSize * sizeof(RawInstrProf::ProfileData<IntPtrT>);
353
2
  auto PaddingSize = getNumPaddingBytes(NamesSize);
354
2
355
2
  ptrdiff_t DataOffset = sizeof(RawInstrProf::Header);
356
2
  ptrdiff_t CountersOffset = DataOffset + DataSizeInBytes;
357
2
  ptrdiff_t NamesOffset = CountersOffset + sizeof(uint64_t) * CountersSize;
358
2
  ptrdiff_t ValueDataOffset = NamesOffset + NamesSize + PaddingSize;
359
2
360
2
  auto *Start = reinterpret_cast<const char *>(&Header);
361
2
  if (Start + ValueDataOffset > DataBuffer->getBufferEnd())
362
0
    return error(instrprof_error::bad_header);
363
2
364
2
  Data = reinterpret_cast<const RawInstrProf::ProfileData<IntPtrT> *>(
365
2
      Start + DataOffset);
366
2
  DataEnd = Data + DataSize;
367
2
  CountersStart = reinterpret_cast<const uint64_t *>(Start + CountersOffset);
368
2
  NamesStart = Start + NamesOffset;
369
2
  ValueDataStart = reinterpret_cast<const uint8_t *>(Start + ValueDataOffset);
370
2
371
2
  std::unique_ptr<InstrProfSymtab> NewSymtab = make_unique<InstrProfSymtab>();
372
2
  if (Error E = createSymtab(*NewSymtab.get()))
373
0
    return E;
374
2
375
2
  Symtab = std::move(NewSymtab);
376
2
  return success();
377
2
}
llvm::RawInstrProfReader<unsigned long long>::readHeader(llvm::RawInstrProf::Header const&)
Line
Count
Source
340
7
    const RawInstrProf::Header &Header) {
341
7
  Version = swap(Header.Version);
342
7
  if (
GET_VERSION7
(Version) != RawInstrProf::Version7
)
343
0
    return error(instrprof_error::unsupported_version);
344
7
345
7
  CountersDelta = swap(Header.CountersDelta);
346
7
  NamesDelta = swap(Header.NamesDelta);
347
7
  auto DataSize = swap(Header.DataSize);
348
7
  auto CountersSize = swap(Header.CountersSize);
349
7
  NamesSize = swap(Header.NamesSize);
350
7
  ValueKindLast = swap(Header.ValueKindLast);
351
7
352
7
  auto DataSizeInBytes = DataSize * sizeof(RawInstrProf::ProfileData<IntPtrT>);
353
7
  auto PaddingSize = getNumPaddingBytes(NamesSize);
354
7
355
7
  ptrdiff_t DataOffset = sizeof(RawInstrProf::Header);
356
7
  ptrdiff_t CountersOffset = DataOffset + DataSizeInBytes;
357
7
  ptrdiff_t NamesOffset = CountersOffset + sizeof(uint64_t) * CountersSize;
358
7
  ptrdiff_t ValueDataOffset = NamesOffset + NamesSize + PaddingSize;
359
7
360
7
  auto *Start = reinterpret_cast<const char *>(&Header);
361
7
  if (Start + ValueDataOffset > DataBuffer->getBufferEnd())
362
0
    return error(instrprof_error::bad_header);
363
7
364
7
  Data = reinterpret_cast<const RawInstrProf::ProfileData<IntPtrT> *>(
365
7
      Start + DataOffset);
366
7
  DataEnd = Data + DataSize;
367
7
  CountersStart = reinterpret_cast<const uint64_t *>(Start + CountersOffset);
368
7
  NamesStart = Start + NamesOffset;
369
7
  ValueDataStart = reinterpret_cast<const uint8_t *>(Start + ValueDataOffset);
370
7
371
7
  std::unique_ptr<InstrProfSymtab> NewSymtab = make_unique<InstrProfSymtab>();
372
7
  if (Error E = createSymtab(*NewSymtab.get()))
373
0
    return E;
374
7
375
7
  Symtab = std::move(NewSymtab);
376
7
  return success();
377
7
}
378
379
template <class IntPtrT>
380
46
Error RawInstrProfReader<IntPtrT>::readName(NamedInstrProfRecord &Record) {
381
46
  Record.Name = getName(Data->NameRef);
382
46
  return success();
383
46
}
llvm::RawInstrProfReader<unsigned int>::readName(llvm::NamedInstrProfRecord&)
Line
Count
Source
380
4
Error RawInstrProfReader<IntPtrT>::readName(NamedInstrProfRecord &Record) {
381
4
  Record.Name = getName(Data->NameRef);
382
4
  return success();
383
4
}
llvm::RawInstrProfReader<unsigned long long>::readName(llvm::NamedInstrProfRecord&)
Line
Count
Source
380
42
Error RawInstrProfReader<IntPtrT>::readName(NamedInstrProfRecord &Record) {
381
42
  Record.Name = getName(Data->NameRef);
382
42
  return success();
383
42
}
384
385
template <class IntPtrT>
386
46
Error RawInstrProfReader<IntPtrT>::readFuncHash(NamedInstrProfRecord &Record) {
387
46
  Record.Hash = swap(Data->FuncHash);
388
46
  return success();
389
46
}
llvm::RawInstrProfReader<unsigned long long>::readFuncHash(llvm::NamedInstrProfRecord&)
Line
Count
Source
386
42
Error RawInstrProfReader<IntPtrT>::readFuncHash(NamedInstrProfRecord &Record) {
387
42
  Record.Hash = swap(Data->FuncHash);
388
42
  return success();
389
42
}
llvm::RawInstrProfReader<unsigned int>::readFuncHash(llvm::NamedInstrProfRecord&)
Line
Count
Source
386
4
Error RawInstrProfReader<IntPtrT>::readFuncHash(NamedInstrProfRecord &Record) {
387
4
  Record.Hash = swap(Data->FuncHash);
388
4
  return success();
389
4
}
390
391
template <class IntPtrT>
392
Error RawInstrProfReader<IntPtrT>::readRawCounts(
393
46
    InstrProfRecord &Record) {
394
46
  uint32_t NumCounters = swap(Data->NumCounters);
395
46
  IntPtrT CounterPtr = Data->CounterPtr;
396
46
  if (NumCounters == 0)
397
0
    return error(instrprof_error::malformed);
398
46
399
46
  auto RawCounts = makeArrayRef(getCounter(CounterPtr), NumCounters);
400
46
  auto *NamesStartAsCounter = reinterpret_cast<const uint64_t *>(NamesStart);
401
46
402
46
  // Check bounds.
403
46
  if (RawCounts.data() < CountersStart ||
404
46
      RawCounts.data() + RawCounts.size() > NamesStartAsCounter)
405
0
    return error(instrprof_error::malformed);
406
46
407
46
  
if (46
ShouldSwapBytes46
) {
408
4
    Record.Counts.clear();
409
4
    Record.Counts.reserve(RawCounts.size());
410
4
    for (uint64_t Count : RawCounts)
411
6
      Record.Counts.push_back(swap(Count));
412
4
  } else
413
42
    Record.Counts = RawCounts;
414
46
415
46
  return success();
416
46
}
llvm::RawInstrProfReader<unsigned long long>::readRawCounts(llvm::InstrProfRecord&)
Line
Count
Source
393
42
    InstrProfRecord &Record) {
394
42
  uint32_t NumCounters = swap(Data->NumCounters);
395
42
  IntPtrT CounterPtr = Data->CounterPtr;
396
42
  if (NumCounters == 0)
397
0
    return error(instrprof_error::malformed);
398
42
399
42
  auto RawCounts = makeArrayRef(getCounter(CounterPtr), NumCounters);
400
42
  auto *NamesStartAsCounter = reinterpret_cast<const uint64_t *>(NamesStart);
401
42
402
42
  // Check bounds.
403
42
  if (RawCounts.data() < CountersStart ||
404
42
      RawCounts.data() + RawCounts.size() > NamesStartAsCounter)
405
0
    return error(instrprof_error::malformed);
406
42
407
42
  
if (42
ShouldSwapBytes42
) {
408
2
    Record.Counts.clear();
409
2
    Record.Counts.reserve(RawCounts.size());
410
2
    for (uint64_t Count : RawCounts)
411
3
      Record.Counts.push_back(swap(Count));
412
2
  } else
413
40
    Record.Counts = RawCounts;
414
42
415
42
  return success();
416
42
}
llvm::RawInstrProfReader<unsigned int>::readRawCounts(llvm::InstrProfRecord&)
Line
Count
Source
393
4
    InstrProfRecord &Record) {
394
4
  uint32_t NumCounters = swap(Data->NumCounters);
395
4
  IntPtrT CounterPtr = Data->CounterPtr;
396
4
  if (NumCounters == 0)
397
0
    return error(instrprof_error::malformed);
398
4
399
4
  auto RawCounts = makeArrayRef(getCounter(CounterPtr), NumCounters);
400
4
  auto *NamesStartAsCounter = reinterpret_cast<const uint64_t *>(NamesStart);
401
4
402
4
  // Check bounds.
403
4
  if (RawCounts.data() < CountersStart ||
404
4
      RawCounts.data() + RawCounts.size() > NamesStartAsCounter)
405
0
    return error(instrprof_error::malformed);
406
4
407
4
  
if (4
ShouldSwapBytes4
) {
408
2
    Record.Counts.clear();
409
2
    Record.Counts.reserve(RawCounts.size());
410
2
    for (uint64_t Count : RawCounts)
411
3
      Record.Counts.push_back(swap(Count));
412
2
  } else
413
2
    Record.Counts = RawCounts;
414
4
415
4
  return success();
416
4
}
417
418
template <class IntPtrT>
419
Error RawInstrProfReader<IntPtrT>::readValueProfilingData(
420
46
    InstrProfRecord &Record) {
421
46
  Record.clearValueData();
422
46
  CurValueDataSize = 0;
423
46
  // Need to match the logic in value profile dumper code in compiler-rt:
424
46
  uint32_t NumValueKinds = 0;
425
138
  for (uint32_t I = 0; 
I < IPVK_Last + 1138
;
I++92
)
426
92
    NumValueKinds += (Data->NumValueSites[I] != 0);
427
46
428
46
  if (!NumValueKinds)
429
46
    return success();
430
0
431
0
  Expected<std::unique_ptr<ValueProfData>> VDataPtrOrErr =
432
0
      ValueProfData::getValueProfData(
433
0
          ValueDataStart, (const unsigned char *)DataBuffer->getBufferEnd(),
434
0
          getDataEndianness());
435
0
436
0
  if (Error E = VDataPtrOrErr.takeError())
437
0
    return E;
438
0
439
0
  // Note that besides deserialization, this also performs the conversion for
440
0
  // indirect call targets.  The function pointers from the raw profile are
441
0
  // remapped into function name hashes.
442
0
  VDataPtrOrErr.get()->deserializeTo(Record, &Symtab->getAddrHashMap());
443
0
  CurValueDataSize = VDataPtrOrErr.get()->getSize();
444
0
  return success();
445
0
}
llvm::RawInstrProfReader<unsigned int>::readValueProfilingData(llvm::InstrProfRecord&)
Line
Count
Source
420
4
    InstrProfRecord &Record) {
421
4
  Record.clearValueData();
422
4
  CurValueDataSize = 0;
423
4
  // Need to match the logic in value profile dumper code in compiler-rt:
424
4
  uint32_t NumValueKinds = 0;
425
12
  for (uint32_t I = 0; 
I < IPVK_Last + 112
;
I++8
)
426
8
    NumValueKinds += (Data->NumValueSites[I] != 0);
427
4
428
4
  if (!NumValueKinds)
429
4
    return success();
430
0
431
0
  Expected<std::unique_ptr<ValueProfData>> VDataPtrOrErr =
432
0
      ValueProfData::getValueProfData(
433
0
          ValueDataStart, (const unsigned char *)DataBuffer->getBufferEnd(),
434
0
          getDataEndianness());
435
0
436
0
  if (Error E = VDataPtrOrErr.takeError())
437
0
    return E;
438
0
439
0
  // Note that besides deserialization, this also performs the conversion for
440
0
  // indirect call targets.  The function pointers from the raw profile are
441
0
  // remapped into function name hashes.
442
0
  VDataPtrOrErr.get()->deserializeTo(Record, &Symtab->getAddrHashMap());
443
0
  CurValueDataSize = VDataPtrOrErr.get()->getSize();
444
0
  return success();
445
0
}
llvm::RawInstrProfReader<unsigned long long>::readValueProfilingData(llvm::InstrProfRecord&)
Line
Count
Source
420
42
    InstrProfRecord &Record) {
421
42
  Record.clearValueData();
422
42
  CurValueDataSize = 0;
423
42
  // Need to match the logic in value profile dumper code in compiler-rt:
424
42
  uint32_t NumValueKinds = 0;
425
126
  for (uint32_t I = 0; 
I < IPVK_Last + 1126
;
I++84
)
426
84
    NumValueKinds += (Data->NumValueSites[I] != 0);
427
42
428
42
  if (!NumValueKinds)
429
42
    return success();
430
0
431
0
  Expected<std::unique_ptr<ValueProfData>> VDataPtrOrErr =
432
0
      ValueProfData::getValueProfData(
433
0
          ValueDataStart, (const unsigned char *)DataBuffer->getBufferEnd(),
434
0
          getDataEndianness());
435
0
436
0
  if (Error E = VDataPtrOrErr.takeError())
437
0
    return E;
438
0
439
0
  // Note that besides deserialization, this also performs the conversion for
440
0
  // indirect call targets.  The function pointers from the raw profile are
441
0
  // remapped into function name hashes.
442
0
  VDataPtrOrErr.get()->deserializeTo(Record, &Symtab->getAddrHashMap());
443
0
  CurValueDataSize = VDataPtrOrErr.get()->getSize();
444
0
  return success();
445
0
}
446
447
template <class IntPtrT>
448
54
Error RawInstrProfReader<IntPtrT>::readNextRecord(NamedInstrProfRecord &Record) {
449
54
  if (atEnd())
450
54
    // At this point, ValueDataStart field points to the next header.
451
9
    
if (Error 9
E9
= readNextHeader(getNextHeaderPos()))
452
8
      return E;
453
46
454
46
  // Read name ad set it in Record.
455
46
  
if (Error 46
E46
= readName(Record))
456
0
    return E;
457
46
458
46
  // Read FuncHash and set it in Record.
459
46
  
if (Error 46
E46
= readFuncHash(Record))
460
0
    return E;
461
46
462
46
  // Read raw counts and set Record.
463
46
  
if (Error 46
E46
= readRawCounts(Record))
464
0
    return E;
465
46
466
46
  // Read value data and set Record.
467
46
  
if (Error 46
E46
= readValueProfilingData(Record))
468
0
    return E;
469
46
470
46
  // Iterate.
471
46
  advanceData();
472
46
  return success();
473
46
}
llvm::RawInstrProfReader<unsigned int>::readNextRecord(llvm::NamedInstrProfRecord&)
Line
Count
Source
448
6
Error RawInstrProfReader<IntPtrT>::readNextRecord(NamedInstrProfRecord &Record) {
449
6
  if (atEnd())
450
6
    // At this point, ValueDataStart field points to the next header.
451
2
    
if (Error 2
E2
= readNextHeader(getNextHeaderPos()))
452
2
      return E;
453
4
454
4
  // Read name ad set it in Record.
455
4
  
if (Error 4
E4
= readName(Record))
456
0
    return E;
457
4
458
4
  // Read FuncHash and set it in Record.
459
4
  
if (Error 4
E4
= readFuncHash(Record))
460
0
    return E;
461
4
462
4
  // Read raw counts and set Record.
463
4
  
if (Error 4
E4
= readRawCounts(Record))
464
0
    return E;
465
4
466
4
  // Read value data and set Record.
467
4
  
if (Error 4
E4
= readValueProfilingData(Record))
468
0
    return E;
469
4
470
4
  // Iterate.
471
4
  advanceData();
472
4
  return success();
473
4
}
llvm::RawInstrProfReader<unsigned long long>::readNextRecord(llvm::NamedInstrProfRecord&)
Line
Count
Source
448
48
Error RawInstrProfReader<IntPtrT>::readNextRecord(NamedInstrProfRecord &Record) {
449
48
  if (atEnd())
450
48
    // At this point, ValueDataStart field points to the next header.
451
7
    
if (Error 7
E7
= readNextHeader(getNextHeaderPos()))
452
6
      return E;
453
42
454
42
  // Read name ad set it in Record.
455
42
  
if (Error 42
E42
= readName(Record))
456
0
    return E;
457
42
458
42
  // Read FuncHash and set it in Record.
459
42
  
if (Error 42
E42
= readFuncHash(Record))
460
0
    return E;
461
42
462
42
  // Read raw counts and set Record.
463
42
  
if (Error 42
E42
= readRawCounts(Record))
464
0
    return E;
465
42
466
42
  // Read value data and set Record.
467
42
  
if (Error 42
E42
= readValueProfilingData(Record))
468
0
    return E;
469
42
470
42
  // Iterate.
471
42
  advanceData();
472
42
  return success();
473
42
}
474
475
namespace llvm {
476
477
template class RawInstrProfReader<uint32_t>;
478
template class RawInstrProfReader<uint64_t>;
479
480
} // end namespace llvm
481
482
InstrProfLookupTrait::hash_value_type
483
507
InstrProfLookupTrait::ComputeHash(StringRef K) {
484
507
  return IndexedInstrProf::ComputeHash(HashType, K);
485
507
}
486
487
using data_type = InstrProfLookupTrait::data_type;
488
using offset_type = InstrProfLookupTrait::offset_type;
489
490
bool InstrProfLookupTrait::readValueProfilingData(
491
516
    const unsigned char *&D, const unsigned char *const End) {
492
516
  Expected<std::unique_ptr<ValueProfData>> VDataPtrOrErr =
493
516
      ValueProfData::getValueProfData(D, End, ValueProfDataEndianness);
494
516
495
516
  if (VDataPtrOrErr.takeError())
496
0
    return false;
497
516
498
516
  VDataPtrOrErr.get()->deserializeTo(DataBuffer.back(), nullptr);
499
516
  D += VDataPtrOrErr.get()->TotalSize;
500
516
501
516
  return true;
502
516
}
503
504
data_type InstrProfLookupTrait::ReadData(StringRef K, const unsigned char *D,
505
593
                                         offset_type N) {
506
593
  using namespace support;
507
593
508
593
  // Check if the data is corrupt. If so, don't try to read it.
509
593
  if (N % sizeof(uint64_t))
510
0
    return data_type();
511
593
512
593
  DataBuffer.clear();
513
593
  std::vector<uint64_t> CounterBuffer;
514
593
515
593
  const unsigned char *End = D + N;
516
1.20k
  while (
D < End1.20k
) {
517
613
    // Read hash.
518
613
    if (D + sizeof(uint64_t) >= End)
519
0
      return data_type();
520
613
    uint64_t Hash = endian::readNext<uint64_t, little, unaligned>(D);
521
613
522
613
    // Initialize number of counters for GET_VERSION(FormatVersion) == 1.
523
613
    uint64_t CountsSize = N / sizeof(uint64_t) - 1;
524
613
    // If format version is different then read the number of counters.
525
613
    if (
GET_VERSION613
(FormatVersion) != IndexedInstrProf::ProfVersion::Version1613
) {
526
589
      if (D + sizeof(uint64_t) > End)
527
0
        return data_type();
528
589
      CountsSize = endian::readNext<uint64_t, little, unaligned>(D);
529
589
    }
530
613
    // Read counter values.
531
613
    
if (613
D + CountsSize * sizeof(uint64_t) > End613
)
532
0
      return data_type();
533
613
534
613
    CounterBuffer.clear();
535
613
    CounterBuffer.reserve(CountsSize);
536
2.72k
    for (uint64_t J = 0; 
J < CountsSize2.72k
;
++J2.10k
)
537
2.10k
      CounterBuffer.push_back(endian::readNext<uint64_t, little, unaligned>(D));
538
613
539
613
    DataBuffer.emplace_back(K, Hash, std::move(CounterBuffer));
540
613
541
613
    // Read value profiling data.
542
613
    if (
GET_VERSION613
(FormatVersion) > IndexedInstrProf::ProfVersion::Version2 &&
543
613
        
!readValueProfilingData(D, End)516
) {
544
0
      DataBuffer.clear();
545
0
      return data_type();
546
0
    }
547
613
  }
548
593
  return DataBuffer;
549
593
}
550
551
template <typename HashTableImpl>
552
Error InstrProfReaderIndex<HashTableImpl>::getRecords(
553
507
    StringRef FuncName, ArrayRef<NamedInstrProfRecord> &Data) {
554
507
  auto Iter = HashTable->find(FuncName);
555
507
  if (Iter == HashTable->end())
556
48
    return make_error<InstrProfError>(instrprof_error::unknown_function);
557
459
558
459
  Data = (*Iter);
559
459
  if (Data.empty())
560
0
    return make_error<InstrProfError>(instrprof_error::malformed);
561
459
562
459
  return Error::success();
563
459
}
564
565
template <typename HashTableImpl>
566
Error InstrProfReaderIndex<HashTableImpl>::getRecords(
567
190
    ArrayRef<NamedInstrProfRecord> &Data) {
568
190
  if (atEnd())
569
56
    return make_error<InstrProfError>(instrprof_error::eof);
570
134
571
134
  Data = *RecordIterator;
572
134
573
134
  if (Data.empty())
574
0
    return make_error<InstrProfError>(instrprof_error::malformed);
575
134
576
134
  return Error::success();
577
134
}
578
579
template <typename HashTableImpl>
580
InstrProfReaderIndex<HashTableImpl>::InstrProfReaderIndex(
581
    const unsigned char *Buckets, const unsigned char *const Payload,
582
    const unsigned char *const Base, IndexedInstrProf::HashT HashType,
583
358
    uint64_t Version) {
584
358
  FormatVersion = Version;
585
358
  HashTable.reset(HashTableImpl::Create(
586
358
      Buckets, Payload, Base,
587
358
      typename HashTableImpl::InfoType(HashType, Version)));
588
358
  RecordIterator = HashTable->data_begin();
589
358
}
590
591
496
bool IndexedInstrProfReader::hasFormat(const MemoryBuffer &DataBuffer) {
592
496
  using namespace support;
593
496
594
496
  if (DataBuffer.getBufferSize() < 8)
595
3
    return false;
596
493
  uint64_t Magic =
597
493
      endian::read<uint64_t, little, aligned>(DataBuffer.getBufferStart());
598
493
  // Verify that it's magical.
599
493
  return Magic == IndexedInstrProf::Magic;
600
493
}
601
602
const unsigned char *
603
IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,
604
358
                                    const unsigned char *Cur) {
605
358
  using namespace IndexedInstrProf;
606
358
  using namespace support;
607
358
608
358
  if (
Version >= IndexedInstrProf::Version4358
) {
609
321
    const IndexedInstrProf::Summary *SummaryInLE =
610
321
        reinterpret_cast<const IndexedInstrProf::Summary *>(Cur);
611
321
    uint64_t NFields =
612
321
        endian::byte_swap<uint64_t, little>(SummaryInLE->NumSummaryFields);
613
321
    uint64_t NEntries =
614
321
        endian::byte_swap<uint64_t, little>(SummaryInLE->NumCutoffEntries);
615
321
    uint32_t SummarySize =
616
321
        IndexedInstrProf::Summary::getSize(NFields, NEntries);
617
321
    std::unique_ptr<IndexedInstrProf::Summary> SummaryData =
618
321
        IndexedInstrProf::allocSummary(SummarySize);
619
321
620
321
    const uint64_t *Src = reinterpret_cast<const uint64_t *>(SummaryInLE);
621
321
    uint64_t *Dst = reinterpret_cast<uint64_t *>(SummaryData.get());
622
20.2k
    for (unsigned I = 0; 
I < SummarySize / sizeof(uint64_t)20.2k
;
I++19.9k
)
623
19.9k
      Dst[I] = endian::byte_swap<uint64_t, little>(Src[I]);
624
321
625
321
    SummaryEntryVector DetailedSummary;
626
6.09k
    for (unsigned I = 0; 
I < SummaryData->NumCutoffEntries6.09k
;
I++5.77k
) {
627
5.77k
      const IndexedInstrProf::Summary::Entry &Ent = SummaryData->getEntry(I);
628
5.77k
      DetailedSummary.emplace_back((uint32_t)Ent.Cutoff, Ent.MinBlockCount,
629
5.77k
                                   Ent.NumBlocks);
630
5.77k
    }
631
321
    // initialize InstrProfSummary using the SummaryData from disk.
632
321
    this->Summary = llvm::make_unique<ProfileSummary>(
633
321
        ProfileSummary::PSK_Instr, DetailedSummary,
634
321
        SummaryData->get(Summary::TotalBlockCount),
635
321
        SummaryData->get(Summary::MaxBlockCount),
636
321
        SummaryData->get(Summary::MaxInternalBlockCount),
637
321
        SummaryData->get(Summary::MaxFunctionCount),
638
321
        SummaryData->get(Summary::TotalNumBlocks),
639
321
        SummaryData->get(Summary::TotalNumFunctions));
640
321
    return Cur + SummarySize;
641
0
  } else {
642
37
    // For older version of profile data, we need to compute on the fly:
643
37
    using namespace IndexedInstrProf;
644
37
645
37
    InstrProfSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs);
646
37
    // FIXME: This only computes an empty summary. Need to call addRecord for
647
37
    // all NamedInstrProfRecords to get the correct summary.
648
37
    this->Summary = Builder.getSummary();
649
37
    return Cur;
650
37
  }
651
0
}
652
653
358
Error IndexedInstrProfReader::readHeader() {
654
358
  using namespace support;
655
358
656
358
  const unsigned char *Start =
657
358
      (const unsigned char *)DataBuffer->getBufferStart();
658
358
  const unsigned char *Cur = Start;
659
358
  if ((const unsigned char *)DataBuffer->getBufferEnd() - Cur < 24)
660
0
    return error(instrprof_error::truncated);
661
358
662
358
  auto *Header = reinterpret_cast<const IndexedInstrProf::Header *>(Cur);
663
358
  Cur += sizeof(IndexedInstrProf::Header);
664
358
665
358
  // Check the magic number.
666
358
  uint64_t Magic = endian::byte_swap<uint64_t, little>(Header->Magic);
667
358
  if (Magic != IndexedInstrProf::Magic)
668
0
    return error(instrprof_error::bad_magic);
669
358
670
358
  // Read the version.
671
358
  uint64_t FormatVersion = endian::byte_swap<uint64_t, little>(Header->Version);
672
358
  if (
GET_VERSION358
(FormatVersion) >
673
358
      IndexedInstrProf::ProfVersion::CurrentVersion)
674
0
    return error(instrprof_error::unsupported_version);
675
358
676
358
  Cur = readSummary((IndexedInstrProf::ProfVersion)FormatVersion, Cur);
677
358
678
358
  // Read the hash type and start offset.
679
358
  IndexedInstrProf::HashT HashType = static_cast<IndexedInstrProf::HashT>(
680
358
      endian::byte_swap<uint64_t, little>(Header->HashType));
681
358
  if (HashType > IndexedInstrProf::HashT::Last)
682
0
    return error(instrprof_error::unsupported_hash_type);
683
358
684
358
  uint64_t HashOffset = endian::byte_swap<uint64_t, little>(Header->HashOffset);
685
358
686
358
  // The rest of the file is an on disk hash table.
687
358
  InstrProfReaderIndexBase *IndexPtr = nullptr;
688
358
  IndexPtr = new InstrProfReaderIndex<OnDiskHashTableImplV3>(
689
358
      Start + HashOffset, Cur, Start, HashType, FormatVersion);
690
358
  Index.reset(IndexPtr);
691
358
  return success();
692
358
}
693
694
5
InstrProfSymtab &IndexedInstrProfReader::getSymtab() {
695
5
  if (Symtab.get())
696
3
    return *Symtab.get();
697
2
698
2
  std::unique_ptr<InstrProfSymtab> NewSymtab = make_unique<InstrProfSymtab>();
699
2
  if (Error 
E2
= Index->populateSymtab(*NewSymtab.get())) {
700
0
    consumeError(error(InstrProfError::take(std::move(E))));
701
0
  }
702
5
703
5
  Symtab = std::move(NewSymtab);
704
5
  return *Symtab.get();
705
5
}
706
707
Expected<InstrProfRecord>
708
IndexedInstrProfReader::getInstrProfRecord(StringRef FuncName,
709
507
                                           uint64_t FuncHash) {
710
507
  ArrayRef<NamedInstrProfRecord> Data;
711
507
  Error Err = Index->getRecords(FuncName, Data);
712
507
  if (Err)
713
48
    return std::move(Err);
714
459
  // Found it. Look for counters with the right hash.
715
481
  
for (unsigned I = 0, E = Data.size(); 459
I < E481
;
++I22
) {
716
471
    // Check for a match and fill the vector if there is one.
717
471
    if (
Data[I].Hash == FuncHash471
) {
718
449
      return std::move(Data[I]);
719
449
    }
720
471
  }
721
10
  return error(instrprof_error::hash_mismatch);
722
507
}
723
724
Error IndexedInstrProfReader::getFunctionCounts(StringRef FuncName,
725
                                                uint64_t FuncHash,
726
326
                                                std::vector<uint64_t> &Counts) {
727
326
  Expected<InstrProfRecord> Record = getInstrProfRecord(FuncName, FuncHash);
728
326
  if (Error E = Record.takeError())
729
36
    return error(std::move(E));
730
290
731
290
  Counts = Record.get().Counts;
732
290
  return success();
733
290
}
734
735
190
Error IndexedInstrProfReader::readNextRecord(NamedInstrProfRecord &Record) {
736
190
  static unsigned RecordIndex = 0;
737
190
738
190
  ArrayRef<NamedInstrProfRecord> Data;
739
190
740
190
  Error E = Index->getRecords(Data);
741
190
  if (E)
742
56
    return error(std::move(E));
743
134
744
134
  Record = Data[RecordIndex++];
745
134
  if (
RecordIndex >= Data.size()134
) {
746
133
    Index->advanceToNextKey();
747
133
    RecordIndex = 0;
748
133
  }
749
190
  return success();
750
190
}