Skip to content

Commit

Permalink
Profile: Add a library for the instrumentation based profiling format
Browse files Browse the repository at this point in the history
This provides a library to work with the instrumentation based
profiling format that is used by clang's -fprofile-instr-* options and
by the llvm-profdata tool. This is a binary format, rather than the
textual one that's currently in use.

The tests are in the subsequent commits that use this.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203703 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
bogner committed Mar 12, 2014
1 parent 7eb747e commit 02da814
Show file tree
Hide file tree
Showing 12 changed files with 553 additions and 2 deletions.
55 changes: 55 additions & 0 deletions include/llvm/Profile/ProfileData.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//=-- ProfileData.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.
//
//===----------------------------------------------------------------------===//
//
// This file contains support for instrumentation based PGO and coverage.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_PROFILE_PROFILEDATA_H__
#define LLVM_PROFILE_PROFILEDATA_H__

#include "llvm/Support/DataTypes.h"
#include "llvm/Support/system_error.h"

#include <vector>

namespace llvm {

const char PROFILEDATA_MAGIC[4] = {'L', 'P', 'R', 'F'};
const uint32_t PROFILEDATA_VERSION = 1;

const error_category &profiledata_category();

struct profiledata_error {
enum ErrorType {
success = 0,
bad_magic,
unsupported_version,
too_large,
truncated,
malformed,
unknown_function
};
ErrorType V;

profiledata_error(ErrorType V) : V(V) {}
operator ErrorType() const { return V; }
};

inline error_code make_error_code(profiledata_error E) {
return error_code(static_cast<int>(E), profiledata_category());
}

template <> struct is_error_code_enum<profiledata_error> : std::true_type {};
template <> struct is_error_code_enum<profiledata_error::ErrorType>
: std::true_type {};

} // end namespace llvm

#endif // LLVM_PROFILE_PROFILEDATA_H__
93 changes: 93 additions & 0 deletions include/llvm/Profile/ProfileDataReader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//=-- ProfileDataReader.h - Instrumented profiling reader ---------*- 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_PROFILE_PROFILEDATA_READER_H__
#define LLVM_PROFILE_PROFILEDATA_READER_H__

#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"

#include <vector>

namespace llvm {

class ProfileDataCursor;

/// Reader for the profile data that is used for instrumentation based PGO.
class ProfileDataReader {
private:
/// The profile data file contents.
std::unique_ptr<MemoryBuffer> DataBuffer;
/// Offsets into DataBuffer for each function's counters.
StringMap<uint32_t> DataOffsets;
/// The maximal execution count among all functions.
uint64_t MaxFunctionCount;

ProfileDataReader(const ProfileDataReader &) LLVM_DELETED_FUNCTION;
ProfileDataReader &operator=(const ProfileDataReader &) LLVM_DELETED_FUNCTION;
protected:
ProfileDataReader(std::unique_ptr<MemoryBuffer> &DataBuffer)
: DataBuffer(DataBuffer.release()) {}

/// Populate internal state using the profile data's index
error_code readIndex();
public:

class name_iterator {
typedef StringMap<unsigned>::const_iterator IterTy;
IterTy Ix;
public:
explicit name_iterator(const IterTy &Ix) : Ix(Ix) {}

StringRef operator*() const { return Ix->getKey(); }

bool operator==(const name_iterator &RHS) const { return Ix == RHS.Ix; }
bool operator!=(const name_iterator &RHS) const { return Ix != RHS.Ix; }

inline name_iterator& operator++() { ++Ix; return *this; }
};

/// Iterators over the names of indexed items
name_iterator begin() const {
return name_iterator(DataOffsets.begin());
}
name_iterator end() const {
return name_iterator(DataOffsets.end());
}

private:
error_code findFunctionCounts(StringRef FuncName, uint64_t &FunctionHash,
ProfileDataCursor &Cursor);
public:
/// The number of profiled functions
size_t numProfiledFunctions() { return DataOffsets.size(); }
/// Fill Counts with the profile data for the given function name.
error_code getFunctionCounts(StringRef FuncName, uint64_t &FunctionHash,
std::vector<uint64_t> &Counts);
/// Get the frequency with which a function is called relative to the function
/// that is called most often in the program.
error_code getCallFrequency(StringRef FuncName, uint64_t &FunctionHash,
double &F);

static error_code create(std::string Path,
std::unique_ptr<ProfileDataReader> &Result);
};

} // end namespace llvm

#endif // LLVM_PROFILE_PROFILEDATA_READER_H__
54 changes: 54 additions & 0 deletions include/llvm/Profile/ProfileDataWriter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//=-- ProfileDataWriter.h - Instrumented profiling writer ---------*- 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 writing profiling data for instrumentation
// based PGO and coverage.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_PROFILE_PROFILEDATA_WRITER_H__
#define LLVM_PROFILE_PROFILEDATA_WRITER_H__

#include "llvm/ADT/StringMap.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/raw_ostream.h"

#include <vector>

namespace llvm {

struct __attribute__((packed)) ProfileDataHeader {
char Magic[4];
uint32_t Version;
uint32_t DataStart;
uint32_t Padding;
uint64_t MaxFunctionCount;
};

/// Writer for instrumentation based profile data
class ProfileDataWriter {
StringMap<size_t> FunctionOffsets;
std::vector<uint64_t> FunctionData;
uint32_t DataStart;
uint64_t MaxFunctionCount;

void write32(raw_ostream &OS, uint32_t Value);
void write64(raw_ostream &OS, uint64_t Value);
public:
ProfileDataWriter()
: DataStart(sizeof(ProfileDataHeader)), MaxFunctionCount(0) {}

void addFunctionCounts(StringRef FuncName, uint64_t FunctionHash,
uint64_t NumCounters, const uint64_t *Counters);
void write(raw_ostream &OS);
};

} // end namespace llvm

#endif // LLVM_PROFILE_PROFILEDATA_WRITER_H__
1 change: 1 addition & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ add_subdirectory(ExecutionEngine)
add_subdirectory(Target)
add_subdirectory(AsmParser)
add_subdirectory(LineEditor)
add_subdirectory(Profile)
2 changes: 1 addition & 1 deletion lib/LLVMBuild.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
;===------------------------------------------------------------------------===;

[common]
subdirectories = Analysis AsmParser Bitcode CodeGen DebugInfo ExecutionEngine LineEditor Linker IR IRReader LTO MC Object Option Support TableGen Target Transforms
subdirectories = Analysis AsmParser Bitcode CodeGen DebugInfo ExecutionEngine LineEditor Linker IR IRReader LTO MC Object Option Profile Support TableGen Target Transforms

[component_0]
type = Group
Expand Down
2 changes: 1 addition & 1 deletion lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ include $(LEVEL)/Makefile.config

PARALLEL_DIRS := IR AsmParser Bitcode Analysis Transforms CodeGen Target \
ExecutionEngine Linker LTO MC Object Option DebugInfo \
IRReader LineEditor
IRReader LineEditor Profile

include $(LEVEL)/Makefile.common
5 changes: 5 additions & 0 deletions lib/Profile/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
add_llvm_library(LLVMProfile
ProfileData.cpp
ProfileDataReader.cpp
ProfileDataWriter.cpp
)
21 changes: 21 additions & 0 deletions lib/Profile/LLVMBuild.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
;===- ./lib/Profile/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 = Profile
parent = Libraries
14 changes: 14 additions & 0 deletions lib/Profile/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
##===- lib/Profile/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 = LLVMProfile
BUILD_ARCHIVE := 1

include $(LEVEL)/Makefile.common
54 changes: 54 additions & 0 deletions lib/Profile/ProfileData.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//=-- ProfileData.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/Profile/ProfileData.h"
#include "llvm/Support/ErrorHandling.h"

using namespace llvm;

namespace {
class ProfileDataErrorCategoryType : public _do_message {
const char *name() const override { return "llvm.profiledata"; }
std::string message(int IE) const {
profiledata_error::ErrorType E =
static_cast<profiledata_error::ErrorType>(IE);
switch (E) {
case profiledata_error::success: return "Success";
case profiledata_error::bad_magic:
return "Invalid file format (bad magic)";
case profiledata_error::unsupported_version:
return "Unsupported format version";
case profiledata_error::too_large:
return "Too much profile data";
case profiledata_error::truncated:
return "Truncated profile data";
case profiledata_error::malformed:
return "Malformed profile data";
case profiledata_error::unknown_function:
return "No profile data available for function";
}
llvm_unreachable("A value of profiledata_error has no message.");
}
error_condition default_error_condition(int EV) const {
if (EV == profiledata_error::success)
return errc::success;
return errc::invalid_argument;
}
};
}

const error_category &llvm::profiledata_category() {
static ProfileDataErrorCategoryType C;
return C;
}
Loading

0 comments on commit 02da814

Please sign in to comment.