diff --git a/llvm/tools/llvm-profgen/PerfReader.h b/llvm/tools/llvm-profgen/PerfReader.h --- a/llvm/tools/llvm-profgen/PerfReader.h +++ b/llvm/tools/llvm-profgen/PerfReader.h @@ -531,13 +531,16 @@ const ProfiledBinary *Binary; }; -// Load binaries and read perf trace to parse the events and samples +// Read perf trace to parse the events and samples class PerfReaderBase { public: - PerfReaderBase(StringRef BinaryPath); + PerfReaderBase(ProfiledBinary *B) : Binary(B) { + // Initialize the base address to preferred address. + Binary->setBaseAddress(Binary->getPreferredBaseAddress()); + }; virtual ~PerfReaderBase() = default; static std::unique_ptr - create(StringRef BinaryPath, cl::list &PerfTraceFilenames); + create(ProfiledBinary *Binary, cl::list &PerfTraceFilenames); // A LBR sample is like: // 0x5c6313f/0x5c63170/P/-/-/0 0x5c630e7/0x5c63130/P/-/-/0 ... @@ -593,8 +596,6 @@ StringRef BinaryPath; }; - /// Load symbols and disassemble the code of a given binary. - void loadBinary(const StringRef BinaryPath); void updateBinaryAddress(const MMapEvent &Event); ProfiledBinary *getBinary() const { return Binary; } PerfScriptType getPerfScriptType() const { return PerfType; } @@ -605,9 +606,6 @@ } protected: - /// Validate the command line input - static void validateCommandLine(StringRef BinaryPath, - cl::list &PerfTraceFilenames); static PerfScriptType extractPerfType(cl::list &PerfTraceFilenames); /// Parse a single line of a PERF_RECORD_MMAP2 event looking for a @@ -654,7 +652,7 @@ */ class HybridPerfReader : public PerfReaderBase { public: - HybridPerfReader(StringRef BinaryPath) : PerfReaderBase(BinaryPath) { + HybridPerfReader(ProfiledBinary *Binary) : PerfReaderBase(Binary) { PerfType = PERF_LBR_STACK; }; // Parse the hybrid sample including the call and LBR line diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp --- a/llvm/tools/llvm-profgen/PerfReader.cpp +++ b/llvm/tools/llvm-profgen/PerfReader.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "PerfReader.h" #include "ProfileGenerator.h" -#include "llvm/Support/FileSystem.h" static cl::opt ShowMmapEvents("show-mmap-events", cl::ReallyHidden, cl::init(false), cl::ZeroOrMore, @@ -244,41 +243,13 @@ return true; } -void PerfReaderBase::validateCommandLine( - StringRef BinaryPath, cl::list &PerfTraceFilenames) { - // Allow the invalid perfscript if we only use to show binary disassembly - if (!ShowDisassemblyOnly) { - for (auto &File : PerfTraceFilenames) { - if (!llvm::sys::fs::exists(File)) { - std::string Msg = "Input perf script(" + File + ") doesn't exist!"; - exitWithError(Msg); - } - } - } - - if (!llvm::sys::fs::exists(BinaryPath)) { - std::string Msg = "Input binary(" + BinaryPath.str() + ") doesn't exist!"; - exitWithError(Msg); - } - - if (CSProfileGenerator::MaxCompressionSize < -1) { - exitWithError("Value of --compress-recursion should >= -1"); - } - if (ShowSourceLocations && !ShowDisassemblyOnly) { - exitWithError("--show-source-locations should work together with " - "--show-disassembly-only!"); - } -} - std::unique_ptr -PerfReaderBase::create(StringRef BinaryPath, +PerfReaderBase::create(ProfiledBinary *Binary, cl::list &PerfTraceFilenames) { - validateCommandLine(BinaryPath, PerfTraceFilenames); - PerfScriptType PerfType = extractPerfType(PerfTraceFilenames); std::unique_ptr PerfReader; if (PerfType == PERF_LBR_STACK) { - PerfReader.reset(new HybridPerfReader(BinaryPath)); + PerfReader.reset(new HybridPerfReader(Binary)); } else if (PerfType == PERF_LBR) { // TODO: exitWithError("Unsupported perfscript!"); @@ -289,18 +260,6 @@ return PerfReader; } -PerfReaderBase::PerfReaderBase(StringRef BinaryPath) { - // Load the binary. - loadBinary(BinaryPath); -} - -void PerfReaderBase::loadBinary(const StringRef BinaryPath) { - // Call to load the binary in the ctor of ProfiledBinary. - Binary = new ProfiledBinary(BinaryPath); - // Initialize the base address to preferred address. - Binary->setBaseAddress(Binary->getPreferredBaseAddress()); -} - void PerfReaderBase::updateBinaryAddress(const MMapEvent &Event) { // Drop the event which doesn't belong to user-provided binary StringRef BinaryName = llvm::sys::path::filename(Event.BinaryPath); diff --git a/llvm/tools/llvm-profgen/llvm-profgen.cpp b/llvm/tools/llvm-profgen/llvm-profgen.cpp --- a/llvm/tools/llvm-profgen/llvm-profgen.cpp +++ b/llvm/tools/llvm-profgen/llvm-profgen.cpp @@ -15,6 +15,7 @@ #include "ProfileGenerator.h" #include "ProfiledBinary.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/TargetSelect.h" @@ -33,10 +34,32 @@ cl::cat(ProfGenCategory)); extern cl::opt ShowDisassemblyOnly; +extern cl::opt ShowSourceLocations; using namespace llvm; using namespace sampleprof; +// Validate the command line input +static void validateCommandLine(cl::list &PerfTraceFilenames) { + // Allow the invalid perfscript if we only use to show binary disassembly + if (!ShowDisassemblyOnly) { + for (auto &File : PerfTraceFilenames) { + if (!llvm::sys::fs::exists(File)) { + std::string Msg = "Input perf script(" + File + ") doesn't exist!"; + exitWithError(Msg); + } + } + } + + if (CSProfileGenerator::MaxCompressionSize < -1) { + exitWithError("Value of --compress-recursion should >= -1"); + } + if (ShowSourceLocations && !ShowDisassemblyOnly) { + exitWithError("--show-source-locations should work together with " + "--show-disassembly-only!"); + } +} + int main(int argc, const char *argv[]) { InitLLVM X(argc, argv); @@ -47,20 +70,21 @@ cl::HideUnrelatedOptions({&ProfGenCategory, &getColorCategory()}); cl::ParseCommandLineOptions(argc, argv, "llvm SPGO profile generator\n"); + validateCommandLine(PerfTraceFilenames); - if (ShowDisassemblyOnly) { - (void)ProfiledBinary(BinaryPath); + // Load symbols and disassemble the code of a given binary. + std::unique_ptr Binary = + std::make_unique(BinaryPath); + if (ShowDisassemblyOnly) return EXIT_SUCCESS; - } - // Load binaries and parse perf events and samples + // Parse perf events and samples std::unique_ptr Reader = - PerfReaderBase::create(BinaryPath, PerfTraceFilenames); + PerfReaderBase::create(Binary.get(), PerfTraceFilenames); Reader->parsePerfTraces(PerfTraceFilenames); - std::unique_ptr Generator = - ProfileGenerator::create(Reader->getBinary(), Reader->getSampleCounters(), - Reader->getPerfScriptType()); + std::unique_ptr Generator = ProfileGenerator::create( + Binary.get(), Reader->getSampleCounters(), Reader->getPerfScriptType()); Generator->generateProfile(); Generator->write();