diff --git a/compiler-rt/test/profile/Linux/instrprof-d.c b/compiler-rt/test/profile/Linux/instrprof-d.c new file mode 100644 --- /dev/null +++ b/compiler-rt/test/profile/Linux/instrprof-d.c @@ -0,0 +1,16 @@ +// REQUIRES: zlib + +// RUN: %clang_pgogen -o %t -g -mllvm --debug-info-correlate -mllvm --disable-vp=true %s +// RUN: llvm-profdata show --verify-correlation %t | FileCheck %s + +// RUN: %clang_pgogen -o %t.no.dbg -mllvm --debug-info-correlate -mllvm --disable-vp=true %s +// RUN: not llvm-profdata show --verify-correlation %t.no.dbg 2>&1 | FileCheck %s --check-prefix NO-DBG +// NO-DBG: unable to correlate profile: could not find any profile metadata in debug info + +// CHECK: Found 3 profiled functions. +// CHECK: a +// CHECK: b +// CHECK: main +void a() {} +void b() {} +int main() { return 0; } diff --git a/llvm/include/llvm/ProfileData/InstrProfCorrelator.h b/llvm/include/llvm/ProfileData/InstrProfCorrelator.h --- a/llvm/include/llvm/ProfileData/InstrProfCorrelator.h +++ b/llvm/include/llvm/ProfileData/InstrProfCorrelator.h @@ -35,6 +35,15 @@ /// to their functions. virtual Error correlateProfileData() = 0; + /// Return the number of ProfileData elements. + llvm::Optional getDataSize() const; + + /// Return a pointer to the names string that this class constructs. + const char *getNamesPointer() const { return Names.c_str(); } + + /// Return the number of bytes in the names string. + size_t getNamesSize() const { return Names.size(); } + static const char *FunctionNameAttributeName; static const char *CFGHashAttributeName; static const char *NumCountersAttributeName; @@ -59,6 +68,9 @@ InstrProfCorrelator(InstrProfCorrelatorKind K, std::unique_ptr Ctx) : Ctx(std::move(Ctx)), Kind(K) {} + std::string Names; + std::vector NamesVec; + private: static llvm::Expected> get(std::unique_ptr Buffer); @@ -83,19 +95,12 @@ /// Return the number of ProfileData elements. size_t getDataSize() const { return Data.size(); } - /// Return a pointer to the names string that this class constructs. - const char *getNamesPointer() const { return Names.c_str(); } - - /// Return the number of bytes in the names string. - size_t getNamesSize() const { return Names.size(); } - static llvm::Expected>> get(std::unique_ptr Ctx, const object::ObjectFile &Obj); protected: std::vector> Data; - std::string Names; Error correlateProfileData() override; virtual void correlateProfileDataImpl() = 0; @@ -107,7 +112,6 @@ InstrProfCorrelatorImpl(InstrProfCorrelatorKind Kind, std::unique_ptr Ctx) : InstrProfCorrelator(Kind, std::move(Ctx)){}; - std::vector NamesVec; llvm::DenseSet CounterOffsets; // Byte-swap the value if necessary. diff --git a/llvm/lib/ProfileData/InstrProfCorrelator.cpp b/llvm/lib/ProfileData/InstrProfCorrelator.cpp --- a/llvm/lib/ProfileData/InstrProfCorrelator.cpp +++ b/llvm/lib/ProfileData/InstrProfCorrelator.cpp @@ -88,6 +88,16 @@ instrprof_error::unable_to_correlate_profile, "not an object file"); } +Optional InstrProfCorrelator::getDataSize() const { + if (const auto *C = dyn_cast>(this)) { + return C->getDataSize(); + } else if (const auto *C = + dyn_cast>(this)) { + return C->getDataSize(); + } + return {}; +} + namespace llvm { template <> diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp --- a/llvm/tools/llvm-profdata/llvm-profdata.cpp +++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp @@ -2486,6 +2486,19 @@ return 0; } +static int showCorrelation(const std::string &Filename, raw_fd_ostream &OS) { + std::unique_ptr Correlator; + if (auto Err = InstrProfCorrelator::get(Filename).moveInto(Correlator)) + exitWithError(std::move(Err), Filename); + if (auto Err = Correlator->correlateProfileData()) + exitWithError(std::move(Err), Filename); + + OS << "Found " << Correlator->getDataSize() << " profiled functions.\n"; + // list names + + return 0; +} + static int show_main(int argc, const char *argv[]) { cl::opt Filename(cl::Positional, cl::Required, cl::desc("")); @@ -2549,6 +2562,8 @@ "extbinary format")); cl::opt ShowBinaryIds("binary-ids", cl::init(false), cl::desc("Show binary ids in the profile. ")); + cl::opt VerifyCorrelation("verify-correlation", cl::init(false), + cl::desc("")); cl::ParseCommandLineOptions(argc, argv, "LLVM profile data summary\n"); @@ -2566,6 +2581,10 @@ if (ShowAllFunctions && !ShowFunction.empty()) WithColor::warning() << "-function argument ignored: showing all functions\n"; + if (VerifyCorrelation) { + return showCorrelation(Filename, OS); + } + if (ProfileKind == instr) return showInstrProfile( Filename, ShowCounts, TopNFunctions, ShowIndirectCallTargets,