mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 16:33:28 +00:00
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
This commit is contained in:
parent
e436779c5a
commit
7a78d819b7
@ -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]));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user