From e2f8ffb736886de349eadebffe1274fddea5d077 Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Tue, 21 Oct 1997 03:41:21 +0000 Subject: [PATCH] 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) --- sim/common/ChangeLog | 27 ++++++ sim/mips/ChangeLog | 15 +++ sim/mips/Makefile.in | 1 + sim/mips/interp.c | 226 +------------------------------------------ sim/mips/sim-main.h | 2 - 5 files changed, 46 insertions(+), 225 deletions(-) diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog index 2be05ff902..f5896e0e56 100644 --- a/sim/common/ChangeLog +++ b/sim/common/ChangeLog @@ -1,5 +1,32 @@ +Tue Oct 21 10:42:38 1997 Andrew Cagney + + * 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 + * 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, diff --git a/sim/mips/ChangeLog b/sim/mips/ChangeLog index ea4da46d5e..22594aef0b 100644 --- a/sim/mips/ChangeLog +++ b/sim/mips/ChangeLog @@ -1,3 +1,18 @@ +Mon Oct 20 13:31:20 1997 Andrew Cagney + + * 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 * sim-main.h (SIGNEXTEND): Force type of result to unsigned_word. diff --git a/sim/mips/Makefile.in b/sim/mips/Makefile.in index fe9fb0215e..194e639385 100644 --- a/sim/mips/Makefile.in +++ b/sim/mips/Makefile.in @@ -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 diff --git a/sim/mips/interp.c b/sim/mips/interp.c index 613208b105..386d28a71d 100644 --- a/sim/mips/interp.c +++ b/sim/mips/interp.c @@ -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 diff --git a/sim/mips/sim-main.h b/sim/mips/sim-main.h index 4a07706da6..6a3d4f7fb7 100644 --- a/sim/mips/sim-main.h +++ b/sim/mips/sim-main.h @@ -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 */