Skip to content

Commit 9152fd1

Browse files
committedMay 19, 2016
Retry^3 "[ProfileData] (llvm) Use Error in InstrProf and Coverage, NFC"
Transition InstrProf and Coverage over to the stricter Error/Expected interface. Changes since the initial commit: - Fix error message printing in llvm-profdata. - Check errors in loadTestingFormat() + annotateAllFunctions(). - Defer error handling in InstrProfIterator to InstrProfReader. - Remove the base ProfError class to work around an MSVC ICE. Differential Revision: http://reviews.llvm.org/D19901 llvm-svn: 270020
1 parent b784ed3 commit 9152fd1

18 files changed

+619
-511
lines changed
 

‎llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h

+37-22
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@
2323
#include "llvm/ProfileData/InstrProf.h"
2424
#include "llvm/Support/Debug.h"
2525
#include "llvm/Support/Endian.h"
26-
#include "llvm/Support/ErrorOr.h"
2726
#include "llvm/Support/raw_ostream.h"
2827
#include <system_error>
2928
#include <tuple>
3029

3130
namespace llvm {
3231
namespace coverage {
32+
3333
enum class coveragemap_error {
3434
success = 0,
3535
eof,
@@ -38,14 +38,37 @@ enum class coveragemap_error {
3838
truncated,
3939
malformed
4040
};
41-
} // end of coverage namespace.
41+
42+
const std::error_category &coveragemap_category();
43+
44+
inline std::error_code make_error_code(coveragemap_error E) {
45+
return std::error_code(static_cast<int>(E), coveragemap_category());
4246
}
4347

44-
namespace std {
45-
template <>
46-
struct is_error_code_enum<llvm::coverage::coveragemap_error> : std::true_type {
48+
class CoverageMapError : public ErrorInfo<CoverageMapError> {
49+
public:
50+
CoverageMapError(coveragemap_error Err) : Err(Err) {
51+
assert(Err != coveragemap_error::success && "Not an error");
52+
}
53+
54+
std::string message() const override;
55+
56+
void log(raw_ostream &OS) const override { OS << message(); }
57+
58+
std::error_code convertToErrorCode() const override {
59+
return make_error_code(Err);
60+
}
61+
62+
coveragemap_error get() const { return Err; }
63+
64+
static char ID;
65+
66+
private:
67+
coveragemap_error Err;
4768
};
48-
}
69+
70+
} // end of coverage namespace.
71+
} // end of llvm namespace
4972

5073
namespace llvm {
5174
class IndexedInstrProfReader;
@@ -265,7 +288,7 @@ class CounterMappingContext {
265288

266289
/// \brief Return the number of times that a region of code associated with
267290
/// this counter was executed.
268-
ErrorOr<int64_t> evaluate(const Counter &C) const;
291+
Expected<int64_t> evaluate(const Counter &C) const;
269292
};
270293

271294
/// \brief Code coverage information for a single function.
@@ -415,12 +438,12 @@ class CoverageMapping {
415438

416439
public:
417440
/// \brief Load the coverage mapping using the given readers.
418-
static ErrorOr<std::unique_ptr<CoverageMapping>>
441+
static Expected<std::unique_ptr<CoverageMapping>>
419442
load(CoverageMappingReader &CoverageReader,
420443
IndexedInstrProfReader &ProfileReader);
421444

422445
/// \brief Load the coverage mapping from the given files.
423-
static ErrorOr<std::unique_ptr<CoverageMapping>>
446+
static Expected<std::unique_ptr<CoverageMapping>>
424447
load(StringRef ObjectFilename, StringRef ProfileFilename,
425448
StringRef Arch = StringRef());
426449

@@ -466,12 +489,6 @@ class CoverageMapping {
466489
CoverageData getCoverageForExpansion(const ExpansionRecord &Expansion);
467490
};
468491

469-
const std::error_category &coveragemap_category();
470-
471-
inline std::error_code make_error_code(coveragemap_error E) {
472-
return std::error_code(static_cast<int>(E), coveragemap_category());
473-
}
474-
475492
// Profile coverage map has the following layout:
476493
// [CoverageMapFileHeader]
477494
// [ArrayStart]
@@ -501,14 +518,13 @@ template <class IntPtrT> struct CovMapFunctionRecordV1 {
501518
}
502519
// Return the PGO name of the function */
503520
template <support::endianness Endian>
504-
std::error_code getFuncName(InstrProfSymtab &ProfileNames,
505-
StringRef &FuncName) const {
521+
Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
506522
IntPtrT NameRef = getFuncNameRef<Endian>();
507523
uint32_t NameS = support::endian::byte_swap<uint32_t, Endian>(NameSize);
508524
FuncName = ProfileNames.getFuncName(NameRef, NameS);
509525
if (NameS && FuncName.empty())
510-
return coveragemap_error::malformed;
511-
return std::error_code();
526+
return make_error<CoverageMapError>(coveragemap_error::malformed);
527+
return Error::success();
512528
}
513529
};
514530

@@ -530,11 +546,10 @@ struct CovMapFunctionRecord {
530546
}
531547
// Return the PGO name of the function */
532548
template <support::endianness Endian>
533-
std::error_code getFuncName(InstrProfSymtab &ProfileNames,
534-
StringRef &FuncName) const {
549+
Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
535550
uint64_t NameRef = getFuncNameRef<Endian>();
536551
FuncName = ProfileNames.getFuncName(NameRef);
537-
return std::error_code();
552+
return Error::success();
538553
}
539554
};
540555

‎llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h

+12-12
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class CoverageMappingIterator
6969

7070
class CoverageMappingReader {
7171
public:
72-
virtual std::error_code readNextRecord(CoverageMappingRecord &Record) = 0;
72+
virtual Error readNextRecord(CoverageMappingRecord &Record) = 0;
7373
CoverageMappingIterator begin() { return CoverageMappingIterator(this); }
7474
CoverageMappingIterator end() { return CoverageMappingIterator(); }
7575
virtual ~CoverageMappingReader() {}
@@ -82,10 +82,10 @@ class RawCoverageReader {
8282

8383
RawCoverageReader(StringRef Data) : Data(Data) {}
8484

85-
std::error_code readULEB128(uint64_t &Result);
86-
std::error_code readIntMax(uint64_t &Result, uint64_t MaxPlus1);
87-
std::error_code readSize(uint64_t &Result);
88-
std::error_code readString(StringRef &Result);
85+
Error readULEB128(uint64_t &Result);
86+
Error readIntMax(uint64_t &Result, uint64_t MaxPlus1);
87+
Error readSize(uint64_t &Result);
88+
Error readString(StringRef &Result);
8989
};
9090

9191
/// \brief Reader for the raw coverage filenames.
@@ -100,7 +100,7 @@ class RawCoverageFilenamesReader : public RawCoverageReader {
100100
RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames)
101101
: RawCoverageReader(Data), Filenames(Filenames) {}
102102

103-
std::error_code read();
103+
Error read();
104104
};
105105

106106
/// \brief Reader for the raw coverage mapping data.
@@ -125,12 +125,12 @@ class RawCoverageMappingReader : public RawCoverageReader {
125125
Filenames(Filenames), Expressions(Expressions),
126126
MappingRegions(MappingRegions) {}
127127

128-
std::error_code read();
128+
Error read();
129129

130130
private:
131-
std::error_code decodeCounter(unsigned Value, Counter &C);
132-
std::error_code readCounter(Counter &C);
133-
std::error_code
131+
Error decodeCounter(unsigned Value, Counter &C);
132+
Error readCounter(Counter &C);
133+
Error
134134
readMappingRegionsSubArray(std::vector<CounterMappingRegion> &MappingRegions,
135135
unsigned InferredFileID, size_t NumFileIDs);
136136
};
@@ -170,11 +170,11 @@ class BinaryCoverageReader : public CoverageMappingReader {
170170
BinaryCoverageReader() : CurrentRecord(0) {}
171171

172172
public:
173-
static ErrorOr<std::unique_ptr<BinaryCoverageReader>>
173+
static Expected<std::unique_ptr<BinaryCoverageReader>>
174174
create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
175175
StringRef Arch);
176176

177-
std::error_code readNextRecord(CoverageMappingRecord &Record) override;
177+
Error readNextRecord(CoverageMappingRecord &Record) override;
178178
};
179179

180180
} // end namespace coverage

‎llvm/include/llvm/ProfileData/InstrProf.h

+59-23
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include "llvm/ProfileData/ProfileCommon.h"
2626
#include "llvm/Support/Endian.h"
2727
#include "llvm/Support/ErrorHandling.h"
28-
#include "llvm/Support/ErrorOr.h"
2928
#include "llvm/Support/MD5.h"
3029
#include "llvm/Support/MathExtras.h"
3130
#include <cstdint>
@@ -204,20 +203,17 @@ StringRef getFuncNameWithoutPrefix(StringRef PGOFuncName,
204203
/// third field is the uncompressed strings; otherwise it is the
205204
/// compressed string. When the string compression is off, the
206205
/// second field will have value zero.
207-
std::error_code
208-
collectPGOFuncNameStrings(const std::vector<std::string> &NameStrs,
209-
bool doCompression, std::string &Result);
206+
Error collectPGOFuncNameStrings(const std::vector<std::string> &NameStrs,
207+
bool doCompression, std::string &Result);
210208
/// Produce \c Result string with the same format described above. The input
211209
/// is vector of PGO function name variables that are referenced.
212-
std::error_code
213-
collectPGOFuncNameStrings(const std::vector<GlobalVariable *> &NameVars,
214-
std::string &Result, bool doCompression = true);
210+
Error collectPGOFuncNameStrings(const std::vector<GlobalVariable *> &NameVars,
211+
std::string &Result, bool doCompression = true);
215212
class InstrProfSymtab;
216213
/// \c NameStrings is a string composed of one of more sub-strings encoded in
217214
/// the format described above. The substrings are seperated by 0 or more zero
218215
/// bytes. This method decodes the string and populates the \c Symtab.
219-
std::error_code readPGOFuncNameStrings(StringRef NameStrings,
220-
InstrProfSymtab &Symtab);
216+
Error readPGOFuncNameStrings(StringRef NameStrings, InstrProfSymtab &Symtab);
221217

222218
enum InstrProfValueKind : uint32_t {
223219
#define VALUE_PROF_KIND(Enumerator, Value) Enumerator = Value,
@@ -284,6 +280,39 @@ inline std::error_code make_error_code(instrprof_error E) {
284280
return std::error_code(static_cast<int>(E), instrprof_category());
285281
}
286282

283+
class InstrProfError : public ErrorInfo<InstrProfError> {
284+
public:
285+
InstrProfError(instrprof_error Err) : Err(Err) {
286+
assert(Err != instrprof_error::success && "Not an error");
287+
}
288+
289+
std::string message() const override;
290+
291+
void log(raw_ostream &OS) const override { OS << message(); }
292+
293+
std::error_code convertToErrorCode() const override {
294+
return make_error_code(Err);
295+
}
296+
297+
instrprof_error get() const { return Err; }
298+
299+
/// Consume an Error and return the raw enum value contained within it. The
300+
/// Error must either be a success value, or contain a single InstrProfError.
301+
static instrprof_error take(Error E) {
302+
auto Err = instrprof_error::success;
303+
handleAllErrors(std::move(E), [&Err](const InstrProfError &IPE) {
304+
assert(Err == instrprof_error::success && "Multiple errors encountered");
305+
Err = IPE.get();
306+
});
307+
return Err;
308+
}
309+
310+
static char ID;
311+
312+
private:
313+
instrprof_error Err;
314+
};
315+
287316
class SoftInstrProfErrors {
288317
/// Count the number of soft instrprof_errors encountered and keep track of
289318
/// the first such error for reporting purposes.
@@ -309,6 +338,11 @@ class SoftInstrProfErrors {
309338
NumCountMismatches(0), NumCounterOverflows(0),
310339
NumValueSiteCountMismatches(0) {}
311340

341+
~SoftInstrProfErrors() {
342+
assert(FirstError == instrprof_error::success &&
343+
"Unchecked soft error encountered");
344+
}
345+
312346
/// Track a soft error (\p IE) and increment its associated counter.
313347
void addError(instrprof_error IE);
314348

@@ -326,8 +360,15 @@ class SoftInstrProfErrors {
326360
return NumValueSiteCountMismatches;
327361
}
328362

329-
/// Return an error code for the first encountered error.
330-
std::error_code getError() const { return make_error_code(FirstError); }
363+
/// Return the first encountered error and reset FirstError to a success
364+
/// value.
365+
Error takeError() {
366+
if (FirstError == instrprof_error::success)
367+
return Error::success();
368+
auto E = make_error<InstrProfError>(FirstError);
369+
FirstError = instrprof_error::success;
370+
return E;
371+
}
331372
};
332373

333374
namespace object {
@@ -372,14 +413,14 @@ class InstrProfSymtab {
372413
/// only initialize the symtab with reference to the data and
373414
/// the section base address. The decompression will be delayed
374415
/// until before it is used. See also \c create(StringRef) method.
375-
std::error_code create(object::SectionRef &Section);
416+
Error create(object::SectionRef &Section);
376417
/// This interface is used by reader of CoverageMapping test
377418
/// format.
378-
inline std::error_code create(StringRef D, uint64_t BaseAddr);
419+
inline Error create(StringRef D, uint64_t BaseAddr);
379420
/// \c NameStrings is a string composed of one of more sub-strings
380421
/// encoded in the format described in \c collectPGOFuncNameStrings.
381422
/// This method is a wrapper to \c readPGOFuncNameStrings method.
382-
inline std::error_code create(StringRef NameStrings);
423+
inline Error create(StringRef NameStrings);
383424
/// A wrapper interface to populate the PGO symtab with functions
384425
/// decls from module \c M. This interface is used by transformation
385426
/// passes such as indirect function call promotion. Variable \c InLTO
@@ -424,13 +465,13 @@ class InstrProfSymtab {
424465
inline StringRef getNameData() const { return Data; }
425466
};
426467

427-
std::error_code InstrProfSymtab::create(StringRef D, uint64_t BaseAddr) {
468+
Error InstrProfSymtab::create(StringRef D, uint64_t BaseAddr) {
428469
Data = D;
429470
Address = BaseAddr;
430-
return std::error_code();
471+
return Error::success();
431472
}
432473

433-
std::error_code InstrProfSymtab::create(StringRef NameStrings) {
474+
Error InstrProfSymtab::create(StringRef NameStrings) {
434475
return readPGOFuncNameStrings(NameStrings, *this);
435476
}
436477

@@ -572,7 +613,7 @@ struct InstrProfRecord {
572613
}
573614

574615
/// Get the error contained within the record's soft error counter.
575-
std::error_code getError() const { return SIPE.getError(); }
616+
Error takeError() { return SIPE.takeError(); }
576617

577618
private:
578619
std::vector<InstrProfValueSiteRecord> IndirectCallSites;
@@ -869,9 +910,4 @@ struct Header {
869910

870911
} // end namespace llvm
871912

872-
namespace std {
873-
template <>
874-
struct is_error_code_enum<llvm::instrprof_error> : std::true_type {};
875-
}
876-
877913
#endif // LLVM_PROFILEDATA_INSTRPROF_H

‎llvm/include/llvm/ProfileData/InstrProfData.inc

+3-4
Original file line numberDiff line numberDiff line change
@@ -322,16 +322,15 @@ typedef struct ValueProfData {
322322
static std::unique_ptr<ValueProfData>
323323
serializeFrom(const InstrProfRecord &Record);
324324
/*!
325-
* Check the integrity of the record. Return the error code when
326-
* an error is detected, otherwise return instrprof_error::success.
325+
* Check the integrity of the record.
327326
*/
328-
instrprof_error checkIntegrity();
327+
Error checkIntegrity();
329328
/*!
330329
* Return a pointer to \c ValueProfileData instance ready to be read.
331330
* All data in the instance are properly byte swapped. The input
332331
* data is assumed to be in little endian order.
333332
*/
334-
static ErrorOr<std::unique_ptr<ValueProfData>>
333+
static Expected<std::unique_ptr<ValueProfData>>
335334
getValueProfData(const unsigned char *SrcBuffer,
336335
const unsigned char *const SrcBufferEnd,
337336
support::endianness SrcDataEndianness);

0 commit comments

Comments
 (0)
Please sign in to comment.