Delete profile support from MIPS simulator, use sim/common/sim-profile

module instead.
Generate a "gmon.out" (gprof) when profiling the target PC.
Add target PC profiling option --profile-pc-granularity (bucket size)
This commit is contained in:
Andrew Cagney 1997-10-21 03:41:21 +00:00
parent 70ee778220
commit e2f8ffb736
5 changed files with 46 additions and 225 deletions

View File

@ -1,5 +1,32 @@
Tue Oct 21 10:42:38 1997 Andrew Cagney <cagney@b1.cygnus.com>
* sim-profile.h (PROFILE_PC_BUCKET_SIZE): Treat a shift of zero as
a bucket size of zero.
* sim-profile.c (OPTION_PROFILE_PC_GRANULARITY,
OPTION_PROFILE_PC): Define.
(profile_option_handler): Add support for --profile-pc and
--profile-pc-granularity options.
(profile_pc_init): When possible, compute nr buckets from bucket
size.
* sim-profile.c (profile_pc_init): Align the profile-pc end
address with the profile-pc bucket size.
* sim-profile.h (PROFILE_PC_NR_BUCKETS): Rename PROFILE_PC_SIZE to
something less ambiguous.
(PROFILE_PC_BUCKET_SIZE): Ditto for PROFILE_PC_SAMPLE_SIZE.
* sim-profile.c (profile_pc_cleanup): New function. Move
profile_pc_uninstall code to here.
(profile_pc_uninstall): Call.
(profile_pc_init): Call.
Mon Oct 20 17:23:58 1997 Andrew Cagney <cagney@b1.cygnus.com>
* sim-profile.c (profile_print_pc): Dump pc profile to dmon.out
file using BSD gprof format.
* sim-bits.h (LSBIT, MSBIT, BIT): Force result to type
unsigned_word.
(LSBIT8, LSBIT16, LSBIT32, LSBIT64, MSBIT8, MSBIT16, MSBIT32,

View File

@ -1,3 +1,18 @@
Mon Oct 20 13:31:20 1997 Andrew Cagney <cagney@b1.cygnus.com>
* Makefile.in (SIM_OBJS): Add sim-profile.o module.
* sim-main.h (WITH_PROFILE): Do not define, defined in
common/sim-config.h. Use sim-profile module.
(simPROFILE): Delete defintion.
* interp.c (PROFILE): Delete definition.
(mips_option_handler): Delete 'p', 'y' and 'x' profile options.
(sim_close): Delete code writing profile histogram.
(mips_set_profile, mips_set_profile_size, writeout16, writeout32):
Delete.
(sim_engine_run): Delete code profiling the PC.
Mon Oct 20 13:31:20 1997 Andrew Cagney <cagney@b1.cygnus.com>
* sim-main.h (SIGNEXTEND): Force type of result to unsigned_word.

View File

@ -21,6 +21,7 @@ SIM_OBJS = interp.o \
sim-module.o \
sim-trace.o \
sim-options.o \
sim-profile.o \
sim-core.o \
sim-watch.o

View File

@ -31,13 +31,11 @@ code on the hardware.
*/
/* The TRACE and PROFILE manifests enable the provision of extra
features. If they are not defined then a simpler (quicker)
simulator is constructed without the required run-time checks,
etc. */
/* The TRACE manifests enable the provision of extra features. If they
are not defined then a simpler (quicker) simulator is constructed
without the required run-time checks, etc. */
#if 1 /* 0 to allow user build selection, 1 to force inclusion */
#define TRACE (1)
#define PROFILE (1)
#endif
#include "bfd.h"
@ -114,24 +112,12 @@ static void dotrace PARAMS((SIM_DESC sd,FILE *tracefh,int type,SIM_ADDR address,
static void ColdReset PARAMS((SIM_DESC sd));
static long getnum PARAMS((SIM_DESC sd, char *value));
static unsigned int power2 PARAMS((unsigned int value));
static void mips_set_profile PARAMS((SIM_DESC sd, int n));
static void mips_set_profile_size PARAMS((SIM_DESC sd, int n));
static void mips_size PARAMS((SIM_DESC sd, int n));
/*---------------------------------------------------------------------------*/
#if !defined(FASTSIM) || defined(PROFILE)
/* At the moment these values will be the same, since we do not have
access to the pipeline cycle count information from the simulator
engine. */
/* FIXME: These will be replaced by ../common/sim-profile.h */
static unsigned int instruction_fetches = 0;
static unsigned int instruction_fetch_overflow = 0;
#endif
#define DELAYSLOT() {\
if (STATE & simDELAYSLOT)\
sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
@ -175,16 +161,6 @@ static FILE *tracefh = NULL;
static void open_trace PARAMS((SIM_DESC sd));
#endif /* TRACE */
#if defined(PROFILE)
static unsigned profile_frequency = 256;
static unsigned profile_nsamples = (128 << 10);
static unsigned short *profile_hist = NULL;
static ut_reg profile_minpc;
static ut_reg profile_maxpc;
static int profile_shift = 0; /* address shift amount */
#endif /* PROFILE */
static SIM_RC
mips_option_handler (sd, opt, arg)
SIM_DESC sd;
@ -254,29 +230,6 @@ Re-compile simulator with \"-DTRACE\" to enable this option.\n");
#endif /* TRACE */
return SIM_RC_OK;
case 'p':
#if defined(PROFILE)
STATE |= simPROFILE;
return SIM_RC_OK;
#else /* !PROFILE */
fprintf(stderr,"\
Simulator constructed without profiling support (for performance).\n\
Re-compile simulator with \"-DPROFILE\" to enable this option.\n");
return SIM_RC_FAIL;
#endif /* !PROFILE */
case 'x':
#if defined(PROFILE)
profile_nsamples = (unsigned)getnum(sd, optarg);
#endif /* PROFILE */
return SIM_RC_OK;
case 'y':
#if defined(PROFILE)
mips_set_profile(sd, (int)getnum(sd, optarg));
#endif /* PROFILE */
return SIM_RC_OK;
}
return SIM_RC_OK;
@ -290,21 +243,12 @@ static const OPTION mips_options[] =
{ {"name", required_argument, NULL,'n'},
'n', "MODEL", "Select arch model",
mips_option_handler },
{ {"profile", optional_argument, NULL,'p'},
'p', "on|off", "Enable profiling",
mips_option_handler },
{ {"trace", optional_argument, NULL,'t'},
't', "on|off", "Enable tracing",
mips_option_handler },
{ {"tracefile",required_argument, NULL,'z'},
'z', "FILE", "Write trace to file",
mips_option_handler },
{ {"frequency",required_argument, NULL,'y'},
'y', "FREQ", "Profile frequency",
mips_option_handler },
{ {"samples", required_argument, NULL,'x'},
'x', "SIZE", "Profile sample size",
mips_option_handler },
{ {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
};
@ -580,61 +524,6 @@ open_trace(sd)
}
#endif /* TRACE */
/* For the profile writing, we write the data in the host
endianness. This unfortunately means we are assuming that the
profile file we create is processed on the same host executing the
simulator. The gmon.out file format should either have an explicit
endianness, or a method of encoding the endianness in the file
header. */
static int
writeout32(sd,fh,val)
SIM_DESC sd;
FILE *fh;
unsigned int val;
{
char buff[4];
int res = 1;
if (CURRENT_HOST_BYTE_ORDER == BIG_ENDIAN) {
buff[3] = ((val >> 0) & 0xFF);
buff[2] = ((val >> 8) & 0xFF);
buff[1] = ((val >> 16) & 0xFF);
buff[0] = ((val >> 24) & 0xFF);
} else {
buff[0] = ((val >> 0) & 0xFF);
buff[1] = ((val >> 8) & 0xFF);
buff[2] = ((val >> 16) & 0xFF);
buff[3] = ((val >> 24) & 0xFF);
}
if (fwrite(buff,4,1,fh) != 1) {
sim_io_eprintf(sd,"Failed to write 4bytes to the profile file\n");
res = 0;
}
return(res);
}
static int
writeout16(sd,fh,val)
SIM_DESC sd;
FILE *fh;
unsigned short val;
{
char buff[2];
int res = 1;
if (CURRENT_HOST_BYTE_ORDER == BIG_ENDIAN) {
buff[1] = ((val >> 0) & 0xFF);
buff[0] = ((val >> 8) & 0xFF);
} else {
buff[0] = ((val >> 0) & 0xFF);
buff[1] = ((val >> 8) & 0xFF);
}
if (fwrite(buff,2,1,fh) != 1) {
sim_io_eprintf(sd,"Failed to write 2bytes to the profile file\n");
res = 0;
}
return(res);
}
void
sim_close (sd, quitting)
SIM_DESC sd;
@ -650,42 +539,6 @@ sim_close (sd, quitting)
mechanism are released: */
sim_io_shutdown (sd);
#if defined(PROFILE)
if ((STATE & simPROFILE) && (profile_hist != NULL)) {
FILE *pf = fopen("gmon.out","wb");
unsigned loop;
if (pf == NULL)
sim_io_eprintf(sd,"Failed to open \"gmon.out\" profile file\n");
else {
int ok;
#ifdef DEBUG
printf("DBG: minpc = 0x%s\n",pr_addr(profile_minpc));
printf("DBG: maxpc = 0x%s\n",pr_addr(profile_maxpc));
#endif /* DEBUG */
ok = writeout32(pf,(unsigned int)profile_minpc);
if (ok)
ok = writeout32(pf,(unsigned int)profile_maxpc);
if (ok)
ok = writeout32(pf,(profile_nsamples * 2) + 12); /* size of sample buffer (+ header) */
#ifdef DEBUG
printf("DBG: nsamples = %d (size = 0x%08X)\n",profile_nsamples,((profile_nsamples * 2) + 12));
#endif /* DEBUG */
for (loop = 0; (ok && (loop < profile_nsamples)); loop++) {
ok = writeout16(pf,profile_hist[loop]);
if (!ok)
break;
}
fclose(pf);
}
free(profile_hist);
profile_hist = NULL;
STATE &= ~simPROFILE;
}
#endif /* PROFILE */
#if defined(TRACE)
if (tracefh != NULL && tracefh != stderr)
fclose(tracefh);
@ -1085,56 +938,6 @@ sim_do_command (sd,cmd)
world. */
/* The profiling format is described in the "gmon_out.h" header file */
static void
mips_set_profile (sd,n)
SIM_DESC sd;
int n;
{
#if defined(PROFILE)
profile_frequency = n;
STATE |= simPROFILE;
#endif /* PROFILE */
return;
}
static void
mips_set_profile_size (sd,n)
SIM_DESC sd;
int n;
{
#if defined(PROFILE)
if (STATE & simPROFILE) {
int bsize;
/* Since we KNOW that the memory banks are a power-of-2 in size: */
profile_nsamples = power2(n);
profile_minpc = STATE_MEM_BASE (sd);
profile_maxpc = (STATE_MEM_BASE (sd) + STATE_MEM_SIZE (sd));
/* Just in-case we are sampling every address: NOTE: The shift
right of 2 is because we only have word-aligned PC addresses. */
if (profile_nsamples > (STATE_MEM_SIZE (sd) >> 2))
profile_nsamples = (STATE_MEM_SIZE (sd) >> 2);
/* Since we are dealing with power-of-2 values: */
profile_shift = (((STATE_MEM_SIZE (sd) >> 2) / profile_nsamples) - 1);
bsize = (profile_nsamples * sizeof(unsigned short));
if (profile_hist == NULL)
profile_hist = (unsigned short *)calloc(64,(bsize / 64));
else
profile_hist = (unsigned short *)realloc(profile_hist,bsize);
if (profile_hist == NULL) {
sim_io_eprintf(sd,"Failed to allocate VM for profiling buffer (0x%08X bytes)\n",bsize);
STATE &= ~simPROFILE;
}
}
#endif /* PROFILE */
return;
}
static void
mips_size(sd, newsize)
SIM_DESC sd;
@ -1159,12 +962,7 @@ mips_size(sd, newsize)
} else {
STATE_MEM_SIZE (sd) = (unsigned)newsize;
STATE_MEMORY (sd) = new;
#if defined(PROFILE)
/* Ensure that we sample across the new memory range */
mips_set_profile_size(sd, profile_nsamples);
#endif /* PROFILE */
}
return;
}
@ -3844,24 +3642,6 @@ sim_engine_run (sd, next_cpu_nr, siggnal)
sim_io_printf(sd,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction,pr_addr(PC));
#endif /* DEBUG */
#if !defined(FASTSIM) || defined(PROFILE)
instruction_fetches++;
/* Since we increment above, the value should only ever be zero if
we have just overflowed: */
if (instruction_fetches == 0)
instruction_fetch_overflow++;
#if defined(PROFILE)
if ((STATE & simPROFILE) && ((instruction_fetches % profile_frequency) == 0) && profile_hist) {
unsigned n = ((unsigned int)(PC - profile_minpc) >> (profile_shift + 2));
if (n < profile_nsamples) {
/* NOTE: The counts for the profiling bins are only 16bits wide */
if (profile_hist[n] != USHRT_MAX)
(profile_hist[n])++;
}
}
#endif /* PROFILE */
#endif /* !FASTSIM && PROFILE */
IPC = PC; /* copy PC for this instruction */
/* This is required by exception processing, to ensure that we can
cope with exceptions in the delay slots of branches that may

View File

@ -30,7 +30,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
/* hobble some common features for moment */
#define WITH_PROFILE 0
#define WITH_TRACE 0
#define WITH_WATCHPOINTS 1
@ -324,7 +323,6 @@ struct _sim_cpu {
#define simHALTEX (1 << 2) /* 0 = run; 1 = halt on exception */
#define simHALTIN (1 << 3) /* 0 = run; 1 = halt on interrupt */
#define simTRACE (1 << 8) /* 0 = do nothing; 1 = trace address activity */
#define simPROFILE (1 << 9) /* 0 = do nothing; 1 = gather profiling samples */
#define simPCOC0 (1 << 17) /* COC[1] from current */
#define simPCOC1 (1 << 18) /* COC[1] from previous */
#define simDELAYSLOT (1 << 24) /* 0 = do nothing; 1 = delay slot entry exists */