diff options
Diffstat (limited to 'llvm/tools/llvm-profdata/llvm-profdata.cpp')
-rw-r--r-- | llvm/tools/llvm-profdata/llvm-profdata.cpp | 79 |
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; } |