1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 03:23:01 +02:00

Provide an accessor for getting function count information. Print a simple

report

llvm-svn: 9557
This commit is contained in:
Chris Lattner 2003-10-28 21:08:18 +00:00
parent f3c4c4f96e
commit f6c2a91b0e
3 changed files with 78 additions and 11 deletions

View File

@ -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]));
}

View File

@ -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

View File

@ -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;
}