Skip to content

Commit

Permalink
GCC AutoFDO profile reader - Initial support.
Browse files Browse the repository at this point in the history
This adds enough machinery to support reading simple GCC AutoFDO
profiles. It now supports reading flat profiles (no function calls).
Subsequent patches will add support for:

- Inlined calls (in particular, the inline call stack is not traversed
  to accumulate samples).

- Working sets and modules. These are used mostly for GCC's LIPO
  optimizations, so they're not needed in LLVM atm. I'm not sure that
  we will ever need them. For now, I've if0'd around the calls.

The patch also adds support in GCOV.h for gcov version V704 (generated
by GCC's profile conversion tool).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247874 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
dnovillo committed Sep 17, 2015
1 parent 1e5eaad commit d139c5d
Show file tree
Hide file tree
Showing 7 changed files with 580 additions and 13 deletions.
3 changes: 2 additions & 1 deletion include/llvm/ProfileData/SampleProf.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ enum class sampleprof_error {
too_large,
truncated,
malformed,
unrecognized_format
unrecognized_format,
not_implemented
};

inline std::error_code make_error_code(sampleprof_error E) {
Expand Down
85 changes: 83 additions & 2 deletions include/llvm/ProfileData/SampleProfReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/GCOV.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"

Expand Down Expand Up @@ -57,7 +58,7 @@ namespace sampleprof {
///
/// The reader supports two file formats: text and binary. The text format
/// is useful for debugging and testing, while the binary format is more
/// compact. They can both be used interchangeably.
/// compact and I/O efficient. They can both be used interchangeably.
class SampleProfileReader {
public:
SampleProfileReader(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)
Expand Down Expand Up @@ -86,7 +87,7 @@ class SampleProfileReader {
StringMap<FunctionSamples> &getProfiles() { return Profiles; }

/// \brief Report a parse error message.
void reportParseError(int64_t LineNumber, Twine Msg) const {
void reportError(int64_t LineNumber, Twine Msg) const {
Ctx.diagnose(DiagnosticInfoSampleProfile(Buffer->getBufferIdentifier(),
LineNumber, Msg));
}
Expand Down Expand Up @@ -163,6 +164,86 @@ class SampleProfileReaderBinary : public SampleProfileReader {
const uint8_t *End;
};

// Represents the source position in GCC sample profiles.
struct SourceInfo {
SourceInfo()
: FuncName(), DirName(), FileName(), StartLine(0), Line(0),
Discriminator(0) {}

SourceInfo(StringRef FuncName, StringRef DirName, StringRef FileName,
uint32_t StartLine, uint32_t Line, uint32_t Discriminator)
: FuncName(FuncName), DirName(DirName), FileName(FileName),
StartLine(StartLine), Line(Line), Discriminator(Discriminator) {}

bool operator<(const SourceInfo &p) const;

uint32_t Offset() const { return ((Line - StartLine) << 16) | Discriminator; }

bool Malformed() const { return Line < StartLine; }

StringRef FuncName;
StringRef DirName;
StringRef FileName;
uint32_t StartLine;
uint32_t Line;
uint32_t Discriminator;
};

typedef std::vector<SourceInfo> SourceStack;

// Supported histogram types in GCC. Currently, we only need support for
// call target histograms.
enum HistType {
HIST_TYPE_INTERVAL,
HIST_TYPE_POW2,
HIST_TYPE_SINGLE_VALUE,
HIST_TYPE_CONST_DELTA,
HIST_TYPE_INDIR_CALL,
HIST_TYPE_AVERAGE,
HIST_TYPE_IOR,
HIST_TYPE_INDIR_CALL_TOPN
};

class SampleProfileReaderGCC : public SampleProfileReader {
public:
SampleProfileReaderGCC(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)
: SampleProfileReader(std::move(B), C), GcovBuffer(Buffer.get()) {}

/// \brief Read and validate the file header.
std::error_code readHeader() override;

/// \brief Read sample profiles from the associated file.
std::error_code read() override;

/// \brief Return true if \p Buffer is in the format supported by this class.
static bool hasFormat(const MemoryBuffer &Buffer);

protected:
std::error_code readNameTable();
std::error_code addSourceCount(StringRef Name, const SourceStack &Src,
uint64_t Count);
std::error_code readOneFunctionProfile(const SourceStack &Stack, bool Update);
std::error_code readFunctionProfiles();
std::error_code readModuleGroup();
std::error_code readWorkingSet();
std::error_code skipNextWord();
template <typename T> ErrorOr<T> readNumber();
ErrorOr<StringRef> readString();

/// \brief Read the section tag and check that it's the same as \p Expected.
std::error_code readSectionTag(uint32_t Expected);

/// GCOV buffer containing the profile.
GCOVBuffer GcovBuffer;

/// Function names in this profile.
std::vector<std::string> Names;

/// GCOV tags used to separate sections in the profile file.
static const uint32_t GCOVTagAFDOFileNames = 0xaa000000;
static const uint32_t GCOVTagAFDOFunction = 0xac000000;
};

} // End namespace sampleprof

} // End namespace llvm
Expand Down
7 changes: 6 additions & 1 deletion include/llvm/Support/GCOV.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class GCOVBlock;
class FileInfo;

namespace GCOV {
enum GCOVVersion { V402, V404 };
enum GCOVVersion { V402, V404, V704 };
} // end GCOV namespace

/// GCOVOptions - A struct for passing gcov options between functions.
Expand Down Expand Up @@ -90,6 +90,11 @@ class GCOVBuffer {
Version = GCOV::V404;
return true;
}
if (VersionStr == "*704") {
Cursor += 4;
Version = GCOV::V704;
return true;
}
errs() << "Unexpected version: " << VersionStr << ".\n";
return false;
}
Expand Down
2 changes: 2 additions & 0 deletions lib/ProfileData/SampleProf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class SampleProfErrorCategoryType : public std::error_category {
return "Malformed profile data";
case sampleprof_error::unrecognized_format:
return "Unrecognized profile encoding format";
case sampleprof_error::not_implemented:
return "Unimplemented feature";
}
llvm_unreachable("A value of sampleprof_error has no message.");
}
Expand Down
Loading

0 comments on commit d139c5d

Please sign in to comment.