From 7a78d819b77e3143b678864f8431fd0b724786d5 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 28 Oct 2003 21:08:18 +0000 Subject: [PATCH] Provide an accessor for getting function count information. Print a simple report git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9557 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-prof/ProfileInfo.cpp | 36 +++++++++++++++++++++++------ tools/llvm-prof/ProfileInfo.h | 13 ++++++++++- tools/llvm-prof/llvm-prof.cpp | 40 ++++++++++++++++++++++++++++++--- 3 files changed, 78 insertions(+), 11 deletions(-) diff --git a/tools/llvm-prof/ProfileInfo.cpp b/tools/llvm-prof/ProfileInfo.cpp index acafdfb3eb8..2341db0bb9f 100644 --- a/tools/llvm-prof/ProfileInfo.cpp +++ b/tools/llvm-prof/ProfileInfo.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "ProfileInfo.h" +#include "llvm/Module.h" #include #include #include @@ -20,9 +21,9 @@ #include enum ProfilingType { - Arguments = 1, // The command line argument block - Function = 2, // Function profiling information - Block = 3, // Block profiling information + ArgumentInfo = 1, // The command line argument block + FunctionInfo = 2, // Function profiling information + BlockInfo = 3, // Block profiling information }; // ByteSwap - Byteswap 'Var' if 'Really' is true. @@ -74,7 +75,8 @@ static void ReadProfilingBlock(const char *ToolName, FILE *F, // ProfileInfo ctor - Read the specified profiling data file, exiting the // program if the file is invalid or broken. // -ProfileInfo::ProfileInfo(const char *ToolName, const std::string &Filename) { +ProfileInfo::ProfileInfo(const char *ToolName, const std::string &Filename, + Module &TheModule) : M(TheModule) { FILE *F = fopen(Filename.c_str(), "r"); if (F == 0) { std::cerr << ToolName << ": Error opening '" << Filename << ": "; @@ -92,7 +94,7 @@ ProfileInfo::ProfileInfo(const char *ToolName, const std::string &Filename) { PacketType = ByteSwap(PacketType, ShouldByteSwap); switch (PacketType) { - case Arguments: { + case ArgumentInfo: { unsigned ArgLength; if (fread(&ArgLength, sizeof(unsigned), 1, F) != 1) { std::cerr << ToolName << ": arguments packet truncated!\n"; @@ -114,11 +116,11 @@ ProfileInfo::ProfileInfo(const char *ToolName, const std::string &Filename) { break; } - case Function: + case FunctionInfo: ReadProfilingBlock(ToolName, F, ShouldByteSwap, FunctionCounts); break; - case Block: + case BlockInfo: ReadProfilingBlock(ToolName, F, ShouldByteSwap, BlockCounts); break; @@ -130,3 +132,23 @@ ProfileInfo::ProfileInfo(const char *ToolName, const std::string &Filename) { fclose(F); } + + +// getFunctionCounts - This method is used by consumers of function counting +// information. If we do not directly have function count information, we +// compute it from other, more refined, types of profile information. +// +void ProfileInfo::getFunctionCounts(std::vector > &Counts) { + if (FunctionCounts.empty()) { + std::cerr << "Function counts not available, and no synthesis " + << "is implemented yet!\n"; + return; + } + + unsigned Counter = 0; + for (Module::iterator I = M.begin(), E = M.end(); + I != E && Counter != FunctionCounts.size(); ++I, ++Counter) + if (!I->isExternal()) + Counts.push_back(std::make_pair(I, FunctionCounts[Counter])); +} diff --git a/tools/llvm-prof/ProfileInfo.h b/tools/llvm-prof/ProfileInfo.h index 8f823aadaba..360d5fa1c92 100644 --- a/tools/llvm-prof/ProfileInfo.h +++ b/tools/llvm-prof/ProfileInfo.h @@ -17,15 +17,26 @@ #include #include +#include +class Module; +class Function; class ProfileInfo { + Module &M; std::vector CommandLines; std::vector FunctionCounts; std::vector BlockCounts; public: // ProfileInfo ctor - Read the specified profiling data file, exiting the // program if the file is invalid or broken. - ProfileInfo(const char *ToolName, const std::string &Filename); + ProfileInfo(const char *ToolName, const std::string &Filename, Module &M); + + // getFunctionCounts - This method is used by consumers of function counting + // information. If we do not directly have function count information, we + // compute it from other, more refined, types of profile information. + // + void getFunctionCounts(std::vector > &Counts); + }; #endif diff --git a/tools/llvm-prof/llvm-prof.cpp b/tools/llvm-prof/llvm-prof.cpp index e527cfecaee..cb907258e5d 100644 --- a/tools/llvm-prof/llvm-prof.cpp +++ b/tools/llvm-prof/llvm-prof.cpp @@ -14,9 +14,11 @@ //===----------------------------------------------------------------------===// #include "ProfileInfo.h" +#include "llvm/Function.h" #include "llvm/Bytecode/Reader.h" #include "Support/CommandLine.h" #include +#include namespace { cl::opt @@ -28,20 +30,52 @@ namespace { cl::Optional, cl::init("llvmprof.out")); } +// PairSecondSort - A sorting predicate to sort by the second element of a pair. +template +struct PairSecondSort + : public std::binary_function, + std::pair, bool> { + bool operator()(const std::pair &LHS, + const std::pair &RHS) const { + return LHS.second < RHS.second; + } +}; + + int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, " llvm profile dump decoder\n"); // Read in the bytecode file... std::string ErrorMessage; - Module *Result = ParseBytecodeFile(BytecodeFile, &ErrorMessage); - if (Result == 0) { + Module *M = ParseBytecodeFile(BytecodeFile, &ErrorMessage); + if (M == 0) { std::cerr << argv[0] << ": " << BytecodeFile << ": " << ErrorMessage << "\n"; return 1; } // Read the profiling information - ProfileInfo PI(argv[0], ProfileDataFile); + ProfileInfo PI(argv[0], ProfileDataFile, *M); + + // Output a report. Eventually, there will be multiple reports selectable on + // the command line, for now, just keep things simple. + + // Emit the most frequent function table... + std::vector > FunctionCounts; + PI.getFunctionCounts(FunctionCounts); + + // Sort by the frequency, backwards. + std::sort(FunctionCounts.begin(), FunctionCounts.end(), + std::not2(PairSecondSort())); + unsigned TotalExecutions = 0; + for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i) + TotalExecutions += FunctionCounts[i].second; + + // Print out the function frequencies... + printf(" ## Frequency\n"); + for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i) + printf("%3d. %5d/%d %s\n", i, FunctionCounts[i].second, TotalExecutions, + FunctionCounts[i].first->getName().c_str()); return 0; } -- 2.34.1