forked from llvm-mirror/llvm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ProfileData: Introduce the InstrProfReader interface and a text reader
This introduces the ProfileData library and updates llvm-profdata to use this library for reading profiles. InstrProfReader is an abstract base class that will be subclassed for both the raw instrprof data from compiler-rt and the efficient instrprof format that will be used for PGO. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204482 91177308-0d34-0410-b5e6-96231b3b80d8
- Loading branch information
Showing
15 changed files
with
400 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
//=-- InstrProf.h - Instrumented profiling format support ---------*- C++ -*-=// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Instrumentation-based profiling data is generated by instrumented | ||
// binaries through library functions in compiler-rt, and read by the clang | ||
// frontend to feed PGO. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_PROFILEDATA_INSTRPROF_H__ | ||
#define LLVM_PROFILEDATA_INSTRPROF_H__ | ||
|
||
#include "llvm/Support/system_error.h" | ||
|
||
namespace llvm { | ||
|
||
const error_category &instrprof_category(); | ||
|
||
struct instrprof_error { | ||
enum ErrorType { | ||
success = 0, | ||
eof, | ||
bad_magic, | ||
unsupported_version, | ||
too_large, | ||
truncated, | ||
malformed, | ||
unknown_function | ||
}; | ||
ErrorType V; | ||
|
||
instrprof_error(ErrorType V) : V(V) {} | ||
operator ErrorType() const { return V; } | ||
}; | ||
|
||
inline error_code make_error_code(instrprof_error E) { | ||
return error_code(static_cast<int>(E), instrprof_category()); | ||
} | ||
|
||
template <> struct is_error_code_enum<instrprof_error> : std::true_type {}; | ||
template <> struct is_error_code_enum<instrprof_error::ErrorType> | ||
: std::true_type {}; | ||
|
||
} // end namespace llvm | ||
|
||
#endif // LLVM_PROFILEDATA_INSTRPROF_H__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
//=-- InstrProfReader.h - Instrumented profiling readers ----------*- C++ -*-=// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file contains support for reading profiling data for instrumentation | ||
// based PGO and coverage. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_PROFILEDATA_INSTRPROF_READER_H__ | ||
#define LLVM_PROFILEDATA_INSTRPROF_READER_H__ | ||
|
||
#include "llvm/ADT/ArrayRef.h" | ||
#include "llvm/ProfileData/InstrProf.h" | ||
#include "llvm/Support/LineIterator.h" | ||
#include "llvm/Support/MemoryBuffer.h" | ||
|
||
#include <iterator> | ||
|
||
namespace llvm { | ||
|
||
class InstrProfReader; | ||
|
||
/// Profiling information for a single function. | ||
struct InstrProfRecord { | ||
StringRef Name; | ||
uint64_t Hash; | ||
ArrayRef<uint64_t> Counts; | ||
}; | ||
|
||
/// A file format agnostic iterator over profiling data. | ||
class InstrProfIterator : public std::iterator<std::input_iterator_tag, | ||
InstrProfRecord> { | ||
InstrProfReader *Reader; | ||
InstrProfRecord Record; | ||
|
||
void Increment(); | ||
public: | ||
InstrProfIterator() : Reader(nullptr) {} | ||
InstrProfIterator(InstrProfReader *Reader) : Reader(Reader) { Increment(); } | ||
|
||
InstrProfIterator &operator++() { Increment(); return *this; } | ||
bool operator==(const InstrProfIterator &RHS) { return Reader == RHS.Reader; } | ||
bool operator!=(const InstrProfIterator &RHS) { return Reader != RHS.Reader; } | ||
InstrProfRecord &operator*() { return Record; } | ||
InstrProfRecord *operator->() { return &Record; } | ||
}; | ||
|
||
/// Base class and interface for reading profiling data of any known instrprof | ||
/// format. Provides an iterator over InstrProfRecords. | ||
class InstrProfReader { | ||
error_code LastError; | ||
public: | ||
InstrProfReader() : LastError(instrprof_error::success) {} | ||
virtual ~InstrProfReader() {} | ||
|
||
/// Read a single record. | ||
virtual error_code readNextRecord(InstrProfRecord &Record) = 0; | ||
/// Iterator over profile data. | ||
InstrProfIterator begin() { return InstrProfIterator(this); } | ||
InstrProfIterator end() { return InstrProfIterator(); } | ||
|
||
/// Set the current error_code and return same. | ||
error_code error(error_code EC) { | ||
LastError = EC; | ||
return EC; | ||
} | ||
/// Clear the current error code and return a successful one. | ||
error_code success() { return error(instrprof_error::success); } | ||
|
||
/// Return true if the reader has finished reading the profile data. | ||
bool isEOF() { return LastError == instrprof_error::eof; } | ||
/// Return true if the reader encountered an error reading profiling data. | ||
bool hasError() { return LastError && !isEOF(); } | ||
/// Get the current error code. | ||
error_code getError() { return LastError; } | ||
|
||
/// Factory method to create an appropriately typed reader for the given | ||
/// instrprof file. | ||
static error_code create(std::string Path, | ||
std::unique_ptr<InstrProfReader> &Result); | ||
}; | ||
|
||
/// Reader for the simple text based instrprof format. | ||
/// | ||
/// This format is a simple text format that's suitable for test data. Records | ||
/// are separated by one or more blank lines, and record fields are separated by | ||
/// new lines. | ||
/// | ||
/// Each record consists of a function name, a function hash, a number of | ||
/// counters, and then each counter value, in that order. | ||
class TextInstrProfReader : public InstrProfReader { | ||
private: | ||
/// The profile data file contents. | ||
std::unique_ptr<MemoryBuffer> DataBuffer; | ||
/// Iterator over the profile data. | ||
line_iterator Line; | ||
/// The current set of counter values. | ||
std::vector<uint64_t> Counts; | ||
|
||
TextInstrProfReader(const TextInstrProfReader &) LLVM_DELETED_FUNCTION; | ||
TextInstrProfReader &operator=(const TextInstrProfReader &) | ||
LLVM_DELETED_FUNCTION; | ||
public: | ||
TextInstrProfReader(std::unique_ptr<MemoryBuffer> &DataBuffer_) | ||
: DataBuffer(DataBuffer_.release()), Line(*DataBuffer, '#') {} | ||
|
||
/// Read a single record. | ||
error_code readNextRecord(InstrProfRecord &Record) override; | ||
}; | ||
|
||
} // end namespace llvm | ||
|
||
#endif // LLVM_PROFILEDATA_INSTRPROF_READER_H__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
add_llvm_library(LLVMProfileData | ||
InstrProf.cpp | ||
InstrProfReader.cpp | ||
|
||
LINK_LIBS | ||
LLVMSupport | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
//=-- InstrProf.cpp - Instrumented profiling format support -----------------=// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file contains support for clang's instrumentation based PGO and | ||
// coverage. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "llvm/ProfileData/InstrProf.h" | ||
#include "llvm/Support/ErrorHandling.h" | ||
|
||
using namespace llvm; | ||
|
||
namespace { | ||
class InstrProfErrorCategoryType : public error_category { | ||
const char *name() const override { return "llvm.instrprof"; } | ||
std::string message(int IE) const override { | ||
instrprof_error::ErrorType E = static_cast<instrprof_error::ErrorType>(IE); | ||
switch (E) { | ||
case instrprof_error::success: | ||
return "Success"; | ||
case instrprof_error::eof: | ||
return "End of File"; | ||
case instrprof_error::bad_magic: | ||
return "Invalid file format (bad magic)"; | ||
case instrprof_error::unsupported_version: | ||
return "Unsupported format version"; | ||
case instrprof_error::too_large: | ||
return "Too much profile data"; | ||
case instrprof_error::truncated: | ||
return "Truncated profile data"; | ||
case instrprof_error::malformed: | ||
return "Malformed profile data"; | ||
case instrprof_error::unknown_function: | ||
return "No profile data available for function"; | ||
} | ||
llvm_unreachable("A value of instrprof_error has no message."); | ||
} | ||
error_condition default_error_condition(int EV) const { | ||
if (EV == instrprof_error::success) | ||
return errc::success; | ||
return errc::invalid_argument; | ||
} | ||
}; | ||
} | ||
|
||
const error_category &llvm::instrprof_category() { | ||
static InstrProfErrorCategoryType C; | ||
return C; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
//=-- InstrProfReader.cpp - Instrumented profiling reader -------------------=// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file contains support for reading profiling data for clang's | ||
// instrumentation based PGO and coverage. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "llvm/ProfileData/InstrProfReader.h" | ||
#include "llvm/ProfileData/InstrProf.h" | ||
#include "llvm/Support/Endian.h" | ||
|
||
#include <cassert> | ||
|
||
using namespace llvm; | ||
|
||
error_code InstrProfReader::create(std::string Path, | ||
std::unique_ptr<InstrProfReader> &Result) { | ||
std::unique_ptr<MemoryBuffer> Buffer; | ||
if (error_code EC = MemoryBuffer::getFileOrSTDIN(Path, Buffer)) | ||
return EC; | ||
|
||
// Sanity check the file. | ||
if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max()) | ||
return instrprof_error::too_large; | ||
|
||
// FIXME: This needs to determine which format the file is and construct the | ||
// correct subclass. | ||
Result.reset(new TextInstrProfReader(Buffer)); | ||
|
||
return instrprof_error::success; | ||
} | ||
|
||
void InstrProfIterator::Increment() { | ||
if (Reader->readNextRecord(Record)) | ||
*this = InstrProfIterator(); | ||
} | ||
|
||
error_code TextInstrProfReader::readNextRecord(InstrProfRecord &Record) { | ||
// Skip empty lines. | ||
while (!Line.is_at_end() && Line->empty()) | ||
++Line; | ||
// If we hit EOF while looking for a name, we're done. | ||
if (Line.is_at_end()) | ||
return error(instrprof_error::eof); | ||
|
||
// Read the function name. | ||
Record.Name = *Line++; | ||
|
||
// Read the function hash. | ||
if (Line.is_at_end()) | ||
return error(instrprof_error::truncated); | ||
if ((Line++)->getAsInteger(10, Record.Hash)) | ||
return error(instrprof_error::malformed); | ||
|
||
// Read the number of counters. | ||
uint64_t NumCounters; | ||
if (Line.is_at_end()) | ||
return error(instrprof_error::truncated); | ||
if ((Line++)->getAsInteger(10, NumCounters)) | ||
return error(instrprof_error::malformed); | ||
|
||
// Read each counter and fill our internal storage with the values. | ||
Counts.clear(); | ||
Counts.reserve(NumCounters); | ||
for (uint64_t I = 0; I < NumCounters; ++I) { | ||
if (Line.is_at_end()) | ||
return error(instrprof_error::truncated); | ||
uint64_t Count; | ||
if ((Line++)->getAsInteger(10, Count)) | ||
return error(instrprof_error::malformed); | ||
Counts.push_back(Count); | ||
} | ||
// Give the record a reference to our internal counter storage. | ||
Record.Counts = Counts; | ||
|
||
return success(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
;===- ./lib/ProfileData/LLVMBuild.txt --------------------------*- Conf -*--===; | ||
; | ||
; The LLVM Compiler Infrastructure | ||
; | ||
; This file is distributed under the University of Illinois Open Source | ||
; License. See LICENSE.TXT for details. | ||
; | ||
;===------------------------------------------------------------------------===; | ||
; | ||
; This is an LLVMBuild description file for the components in this subdirectory. | ||
; | ||
; For more information on the LLVMBuild system, please see: | ||
; | ||
; http://llvm.org/docs/LLVMBuild.html | ||
; | ||
;===------------------------------------------------------------------------===; | ||
|
||
[component_0] | ||
type = Library | ||
name = ProfileData | ||
parent = Libraries | ||
required_libraries = Support |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
##===- lib/ProfileData/Makefile ----------------------------*- Makefile -*-===## | ||
# | ||
# The LLVM Compiler Infrastructure | ||
# | ||
# This file is distributed under the University of Illinois Open Source | ||
# License. See LICENSE.TXT for details. | ||
# | ||
##===----------------------------------------------------------------------===## | ||
|
||
LEVEL = ../.. | ||
LIBRARYNAME = LLVMProfileData | ||
BUILD_ARCHIVE := 1 | ||
|
||
include $(LEVEL)/Makefile.common |
Oops, something went wrong.