Add code to gather some stats on register usage.

This commit is contained in:
gbeauche 2005-06-23 11:37:01 +00:00
parent c33f09b2d8
commit 2deca51ca4
3 changed files with 65 additions and 3 deletions

View File

@ -136,4 +136,15 @@
#define PPC_PROFILE_GENERIC_CALLS 0
#endif
/**
* PPC_PROFILE_REGS_USE
*
* Define to enable some statistics about registers use.
**/
#ifndef PPC_PROFILE_REGS_USE
#define PPC_PROFILE_REGS_USE 0
#endif
#endif /* PPC_CONFIG_H */

View File

@ -19,6 +19,7 @@
*/
#include "sysdeps.h"
#include <stdlib.h>
#include "vm_alloc.h"
#include "cpu/vm.hpp"
#include "cpu/ppc/ppc-cpu.hpp"
@ -43,7 +44,6 @@ uint32 powerpc_cpu::generic_calls_count[PPC_I(MAX)];
static int generic_calls_ids[PPC_I(MAX)];
const int generic_calls_top_ten = 20;
#include <stdlib.h>
int generic_calls_compare(const void *e1, const void *e2)
{
const int id1 = *(const int *)e1;
@ -52,6 +52,15 @@ int generic_calls_compare(const void *e1, const void *e2)
}
#endif
#if PPC_PROFILE_REGS_USE
int register_info_compare(const void *e1, const void *e2)
{
const powerpc_cpu::register_info *ri1 = (powerpc_cpu::register_info *)e1;
const powerpc_cpu::register_info *ri2 = (powerpc_cpu::register_info *)e2;
return ri1->count < ri2->count;
}
#endif
static int ppc_refcount = 0;
void powerpc_cpu::set_register(int id, any_register const & value)
@ -280,6 +289,14 @@ void powerpc_cpu::initialize()
compile_time = 0;
emul_start_time = clock();
#endif
#if PPC_PROFILE_REGS_USE
reginfo = new register_info[32];
for (int i = 0; i < 32; i++) {
reginfo[i].id = i;
reginfo[i].count = 0;
}
#endif
}
#ifdef SHEEPSHAVER
@ -351,6 +368,23 @@ powerpc_cpu::~powerpc_cpu()
}
#endif
#if PPC_PROFILE_REGS_USE
printf("\n### Statistics for register usage\n");
uint64 tot_reg_count = 0;
for (int i = 0; i < 32; i++)
tot_reg_count += reginfo[i].count;
qsort(reginfo, 32, sizeof(register_info), register_info_compare);
uint64 cum_reg_count = 0;
for (int i = 0; i < 32; i++) {
cum_reg_count += reginfo[i].count;
printf("r%-2d : %16lld %2.1f%% [%3.1f%%]\n",
reginfo[i].id, reginfo[i].count,
100.0*double(reginfo[i].count)/double(tot_reg_count),
100.0*double(cum_reg_count)/double(tot_reg_count));
}
delete reginfo;
#endif
kill_decode_cache();
#if ENABLE_MON

View File

@ -40,6 +40,23 @@ class powerpc_cpu
{
powerpc_registers regs;
#if PPC_PROFILE_REGS_USE
// Registers use statistics
// NOTE: the emulator is designed to access registers only through
// the gpr() accessors. The number of calls to gpr() matches exactly
// the number of register operands for an instruction.
public:
struct register_info {
int id;
uint64 count;
};
private:
register_info *reginfo;
void log_reg(int r) const { reginfo[r].count++; }
#else
void log_reg(int r) { }
#endif
protected:
powerpc_spcflags & spcflags() { return regs.spcflags; }
@ -77,8 +94,8 @@ protected:
public:
uint32 & gpr(int i) { return regs.gpr[i]; }
uint32 gpr(int i) const { return regs.gpr[i]; }
uint32 & gpr(int i) { log_reg(i); return regs.gpr[i]; }
uint32 gpr(int i) const { log_reg(i); return regs.gpr[i]; }
double & fpr(int i) { return regs.fpr[i].d; }
double fpr(int i) const { return regs.fpr[i].d; }
uint64 & fpr_dw(int i) { return regs.fpr[i].j; }