aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-profdata/llvm-profdata.cpp
diff options
context:
space:
mode:
authorKazu Hirata <kazu@google.com>2024-12-07 20:22:05 -0800
committerGitHub <noreply@github.com>2024-12-07 20:22:05 -0800
commit684e79f25415250afa51bfcd294d793720aa4bae (patch)
tree2f565fe57cca778cee5b500aa528875cad4a068c /llvm/tools/llvm-profdata/llvm-profdata.cpp
parent9a156f6b2b0c892d8713ba907f07f027b24953d8 (diff)
downloadllvm-684e79f25415250afa51bfcd294d793720aa4bae.zip
llvm-684e79f25415250afa51bfcd294d793720aa4bae.tar.gz
llvm-684e79f25415250afa51bfcd294d793720aa4bae.tar.bz2
[memprof] Add YAML read/write support to llvm-profdata (#118915)
This patch adds YAML read/write support to llvm-profdata. The primary intent is to accommodate MemProf profiles in test cases, thereby avoiding the binary format. The read support is via llvm-profdata merge. This is useful when we want to verify that the compiler does the right thing on a given .ll file and a MemProf profile in a test case. In the test case, we would convert the MemProf profile in YAML to an indexed profile and invoke the compiler on the .ll file along with the indexed profile. The write support is via llvm-profdata show --memory. This is useful when we wish to convert an indexed MemProf profile to YAML while writing tests. We would compile a test case in C++, run it for an indexed MemProf profile, and then convert it to the text format.
Diffstat (limited to 'llvm/tools/llvm-profdata/llvm-profdata.cpp')
-rw-r--r--llvm/tools/llvm-profdata/llvm-profdata.cpp79
1 files changed, 67 insertions, 12 deletions
diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp
index 1d9d7bcf..f34d99e 100644
--- a/llvm/tools/llvm-profdata/llvm-profdata.cpp
+++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp
@@ -723,6 +723,43 @@ loadInput(const WeightedFile &Input, SymbolRemapper *Remapper,
return;
}
+ using ::llvm::memprof::YAMLMemProfReader;
+ if (YAMLMemProfReader::hasFormat(Input.Filename)) {
+ auto ReaderOrErr = YAMLMemProfReader::create(Input.Filename);
+ if (!ReaderOrErr)
+ exitWithError(ReaderOrErr.takeError(), Input.Filename);
+ std::unique_ptr<YAMLMemProfReader> Reader = std::move(ReaderOrErr.get());
+ // Check if the profile types can be merged, e.g. clang frontend profiles
+ // should not be merged with memprof profiles.
+ if (Error E = WC->Writer.mergeProfileKind(Reader->getProfileKind())) {
+ consumeError(std::move(E));
+ WC->Errors.emplace_back(
+ make_error<StringError>(
+ "Cannot merge MemProf profile with incompatible profile.",
+ std::error_code()),
+ Filename);
+ return;
+ }
+
+ auto MemProfError = [&](Error E) {
+ auto [ErrorCode, Msg] = InstrProfError::take(std::move(E));
+ WC->Errors.emplace_back(make_error<InstrProfError>(ErrorCode, Msg),
+ Filename);
+ };
+
+ auto MemProfData = Reader->takeMemProfData();
+
+ // Check for the empty input in case the YAML file is invalid.
+ if (MemProfData.Records.empty()) {
+ WC->Errors.emplace_back(
+ make_error<StringError>("The profile is empty.", std::error_code()),
+ Filename);
+ }
+
+ WC->Writer.addMemProfData(std::move(MemProfData), MemProfError);
+ return;
+ }
+
auto FS = vfs::getRealFileSystem();
// TODO: This only saves the first non-fatal error from InstrProfReader, and
// then added to WriterContext::Errors. However, this is not extensible, if
@@ -3242,18 +3279,36 @@ static int showSampleProfile(ShowFormat SFormat, raw_fd_ostream &OS) {
static int showMemProfProfile(ShowFormat SFormat, raw_fd_ostream &OS) {
if (SFormat == ShowFormat::Json)
exitWithError("JSON output is not supported for MemProf");
- auto ReaderOr = llvm::memprof::RawMemProfReader::create(
- Filename, ProfiledBinary, /*KeepNames=*/true);
- if (Error E = ReaderOr.takeError())
- // Since the error can be related to the profile or the binary we do not
- // pass whence. Instead additional context is provided where necessary in
- // the error message.
- exitWithError(std::move(E), /*Whence*/ "");
-
- std::unique_ptr<llvm::memprof::RawMemProfReader> Reader(
- ReaderOr.get().release());
-
- Reader->printYAML(OS);
+
+ // Show the raw profile in YAML.
+ if (memprof::RawMemProfReader::hasFormat(Filename)) {
+ auto ReaderOr = llvm::memprof::RawMemProfReader::create(
+ Filename, ProfiledBinary, /*KeepNames=*/true);
+ if (Error E = ReaderOr.takeError()) {
+ // Since the error can be related to the profile or the binary we do not
+ // pass whence. Instead additional context is provided where necessary in
+ // the error message.
+ exitWithError(std::move(E), /*Whence*/ "");
+ }
+
+ std::unique_ptr<llvm::memprof::RawMemProfReader> Reader(
+ ReaderOr.get().release());
+
+ Reader->printYAML(OS);
+ return 0;
+ }
+
+ // Show the indexed MemProf profile in YAML.
+ auto FS = vfs::getRealFileSystem();
+ auto ReaderOrErr = IndexedInstrProfReader::create(Filename, *FS);
+ if (Error E = ReaderOrErr.takeError())
+ exitWithError(std::move(E), Filename);
+
+ auto Reader = std::move(ReaderOrErr.get());
+ memprof::AllMemProfData Data = Reader->getAllMemProfData();
+ yaml::Output Yout(OS);
+ Yout << Data;
+
return 0;
}