summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-10-28 21:08:18 +0000
committerChris Lattner <sabre@nondot.org>2003-10-28 21:08:18 +0000
commit7a78d819b77e3143b678864f8431fd0b724786d5 (patch)
tree7270739d9bf06d517d332e67a805a6f244c71779 /tools
parente436779c5a275e98a488b9ddbceada223f238a8b (diff)
downloadexternal_llvm-7a78d819b77e3143b678864f8431fd0b724786d5.zip
external_llvm-7a78d819b77e3143b678864f8431fd0b724786d5.tar.gz
external_llvm-7a78d819b77e3143b678864f8431fd0b724786d5.tar.bz2
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
Diffstat (limited to 'tools')
-rw-r--r--tools/llvm-prof/ProfileInfo.cpp36
-rw-r--r--tools/llvm-prof/ProfileInfo.h13
-rw-r--r--tools/llvm-prof/llvm-prof.cpp40
3 files changed, 78 insertions, 11 deletions
diff --git a/tools/llvm-prof/ProfileInfo.cpp b/tools/llvm-prof/ProfileInfo.cpp
index acafdfb..2341db0 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 <iostream>
#include <sys/types.h>
#include <sys/stat.h>
@@ -20,9 +21,9 @@
#include <stdio.h>
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<std::pair<Function*,
+ unsigned> > &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 8f823aa..360d5fa 100644
--- a/tools/llvm-prof/ProfileInfo.h
+++ b/tools/llvm-prof/ProfileInfo.h
@@ -17,15 +17,26 @@
#include <vector>
#include <string>
+#include <utility>
+class Module;
+class Function;
class ProfileInfo {
+ Module &M;
std::vector<std::string> CommandLines;
std::vector<unsigned> FunctionCounts;
std::vector<unsigned> 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<std::pair<Function*, unsigned> > &Counts);
+
};
#endif
diff --git a/tools/llvm-prof/llvm-prof.cpp b/tools/llvm-prof/llvm-prof.cpp
index e527cfe..cb90725 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 <iostream>
+#include <cstdio>
namespace {
cl::opt<std::string>
@@ -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<class T>
+struct PairSecondSort
+ : public std::binary_function<std::pair<T, unsigned>,
+ std::pair<T, unsigned>, bool> {
+ bool operator()(const std::pair<T, unsigned> &LHS,
+ const std::pair<T, unsigned> &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<std::pair<Function*, unsigned> > FunctionCounts;
+ PI.getFunctionCounts(FunctionCounts);
+
+ // Sort by the frequency, backwards.
+ std::sort(FunctionCounts.begin(), FunctionCounts.end(),
+ std::not2(PairSecondSort<Function*>()));
+ 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;
}