llvm-6502/lib/ProfileData/SampleProfWriter.cpp
Diego Novillo 9657de5f22 Add show and merge tools for sample PGO profiles.
Summary:
This patch extends the 'show' and 'merge' commands in llvm-profdata to handle
sample PGO formats. Using the 'merge' command it is now possible to convert
one sample PGO format to another.

The only format that is currently not working is 'gcc'. I still need to
implement support for it in lib/ProfileData.

The changes in the sample profile support classes are needed for the
merge operation.

Reviewers: bogner

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D6065

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221032 91177308-0d34-0410-b5e6-96231b3b80d8
2014-11-01 00:56:55 +00:00

125 lines
3.9 KiB
C++

//===- SampleProfWriter.cpp - Write LLVM sample profile data --------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the class that writes LLVM sample profiles. It
// supports two file formats: text and binary. The textual representation
// is useful for debugging and testing purposes. The binary representation
// is more compact, resulting in smaller file sizes. However, they can
// both be used interchangeably.
//
// See lib/ProfileData/SampleProfReader.cpp for documentation on each of the
// supported formats.
//
//===----------------------------------------------------------------------===//
#include "llvm/ProfileData/SampleProfWriter.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/Regex.h"
using namespace llvm::sampleprof;
using namespace llvm;
/// \brief Write samples to a text file.
bool SampleProfileWriterText::write(StringRef FName, const FunctionSamples &S) {
if (S.empty())
return true;
OS << FName << ":" << S.getTotalSamples() << ":" << S.getHeadSamples()
<< "\n";
for (const auto &I : S.getBodySamples()) {
LineLocation Loc = I.first;
const SampleRecord &Sample = I.second;
if (Loc.Discriminator == 0)
OS << Loc.LineOffset << ": ";
else
OS << Loc.LineOffset << "." << Loc.Discriminator << ": ";
OS << Sample.getSamples();
for (const auto &J : Sample.getCallTargets())
OS << " " << J.first() << ":" << J.second;
OS << "\n";
}
return true;
}
SampleProfileWriterBinary::SampleProfileWriterBinary(StringRef F,
std::error_code &EC)
: SampleProfileWriter(F, EC, sys::fs::F_None) {
if (EC)
return;
// Write the file header.
encodeULEB128(SPMagic(), OS);
encodeULEB128(SPVersion(), OS);
}
/// \brief Write samples to a binary file.
///
/// \returns true if the samples were written successfully, false otherwise.
bool SampleProfileWriterBinary::write(StringRef FName,
const FunctionSamples &S) {
if (S.empty())
return true;
OS << FName;
encodeULEB128(0, OS);
encodeULEB128(S.getTotalSamples(), OS);
encodeULEB128(S.getHeadSamples(), OS);
encodeULEB128(S.getBodySamples().size(), OS);
for (const auto &I : S.getBodySamples()) {
LineLocation Loc = I.first;
const SampleRecord &Sample = I.second;
encodeULEB128(Loc.LineOffset, OS);
encodeULEB128(Loc.Discriminator, OS);
encodeULEB128(Sample.getSamples(), OS);
encodeULEB128(Sample.getCallTargets().size(), OS);
for (const auto &J : Sample.getCallTargets()) {
std::string Callee = J.first();
unsigned CalleeSamples = J.second;
OS << Callee;
encodeULEB128(0, OS);
encodeULEB128(CalleeSamples, OS);
}
}
return true;
}
/// \brief Create a sample profile writer based on the specified format.
///
/// \param Filename The file to create.
///
/// \param Writer The writer to instantiate according to the specified format.
///
/// \param Format Encoding format for the profile file.
///
/// \returns an error code indicating the status of the created writer.
std::error_code
SampleProfileWriter::create(StringRef Filename,
std::unique_ptr<SampleProfileWriter> &Writer,
SampleProfileFormat Format) {
std::error_code EC;
if (Format == SPF_Binary)
Writer.reset(new SampleProfileWriterBinary(Filename, EC));
else if (Format == SPF_Text)
Writer.reset(new SampleProfileWriterText(Filename, EC));
else
EC = sampleprof_error::unrecognized_format;
return EC;
}