From c0f3b725555df38fc4d9be6154af95dad83694f8 Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Fri, 21 Mar 2014 17:24:48 +0000 Subject: 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 --- include/llvm/ProfileData/InstrProf.h | 52 +++++++++++++ include/llvm/ProfileData/InstrProfReader.h | 119 +++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 include/llvm/ProfileData/InstrProf.h create mode 100644 include/llvm/ProfileData/InstrProfReader.h (limited to 'include/llvm') diff --git a/include/llvm/ProfileData/InstrProf.h b/include/llvm/ProfileData/InstrProf.h new file mode 100644 index 0000000000..21cc170065 --- /dev/null +++ b/include/llvm/ProfileData/InstrProf.h @@ -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(E), instrprof_category()); +} + +template <> struct is_error_code_enum : std::true_type {}; +template <> struct is_error_code_enum + : std::true_type {}; + +} // end namespace llvm + +#endif // LLVM_PROFILEDATA_INSTRPROF_H__ diff --git a/include/llvm/ProfileData/InstrProfReader.h b/include/llvm/ProfileData/InstrProfReader.h new file mode 100644 index 0000000000..a45318b0a9 --- /dev/null +++ b/include/llvm/ProfileData/InstrProfReader.h @@ -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 + +namespace llvm { + +class InstrProfReader; + +/// Profiling information for a single function. +struct InstrProfRecord { + StringRef Name; + uint64_t Hash; + ArrayRef Counts; +}; + +/// A file format agnostic iterator over profiling data. +class InstrProfIterator : public std::iterator { + 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 &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 DataBuffer; + /// Iterator over the profile data. + line_iterator Line; + /// The current set of counter values. + std::vector Counts; + + TextInstrProfReader(const TextInstrProfReader &) LLVM_DELETED_FUNCTION; + TextInstrProfReader &operator=(const TextInstrProfReader &) + LLVM_DELETED_FUNCTION; +public: + TextInstrProfReader(std::unique_ptr &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__ -- cgit v1.2.3