OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_2_x/] [or1ksim/] [profiler.c] - Rev 173

Go to most recent revision | Compare with Previous | Blame | View Log

/* Command line utility, that displays profiling information, generated
   by or1ksim. (use -profile option at command line, when running or1ksim. 
   GNU License (C) Marko Mlinar 2001.  */
 
#include <stdio.h>
 
#define MAX_STACK 1024
#define MAX_FUNCS 1024
 
struct stack_struct {
  unsigned int cycles;
  unsigned int raddr;
  unsigned int addr;
  char name[33];
} stack[MAX_STACK];
 
struct func_struct {
  unsigned int addr;
  char name[33];
  long cum_cycles;
  long calls;
} func[MAX_FUNCS];
 
int nfuncs = 0;
int nstack = 0;
int maxstack = 0, cycles = 0;
int cumulative = 0;
 
FILE *fprof = 0;
 
int main (int argc, char *argv[]) {
  char fprofname[50] = "sim-profile";
  int line = 0;
  if (argc > 4 || argc < 2) {
    fprintf (stderr, "USAGE: profiler [--cumulative|-c] --generate|-g [profile_file_name]\n");
    exit(1);
  }
  argv++; argc--;
  while (argc > 0) {
    if (!strcmp(argv[0], "-c") || !strcmp(argv[0], "--cumulative")) {
      cumulative = 1;
      argv++; argc--;
    } else if (strcmp(argv[0], "-g") && strcmp(argv[0], "--generate")) {
      fprintf (stderr, "USAGE: profiler [--cumulative|-c] [--generate|-g] [profile_file_name]\n");
      exit(1);
    } else {
      argv++; argc--;
      if (argv[0] && argv[0][0] != '-') {
        strcpy (&fprofname[0], argv[0]);
	argv++; argc--;
      }
    }
  }
 
  fprof = fopen (&fprofname[0], "rt");
 
  if (!fprof) {
    fprintf (stderr, "Cannot open profile file: %s\n", &fprofname[0]);
    exit(1);
  }
 
  while (1) {
    char dir = fgetc (fprof);
    line++;
    if (dir == '+') {
      if (fscanf (fprof, "%08X %08X %08X %s\n", &stack[nstack].cycles, &stack[nstack].raddr,
		  &stack[nstack].addr, &stack[nstack].name[0]) != 4)
	fprintf (stderr, "Error reading line #%i\n", line);
      else {
	cycles = stack[nstack].cycles;
	nstack++;
	if (nstack > maxstack)
	  maxstack = nstack;
      }
    } else if (dir == '-') {
      struct stack_struct s;
      if (fscanf (fprof, "%08X %08X\n", &s.cycles, &s.raddr) != 2)
	fprintf (stderr, "Error reading line #%i\n", line);
      else {
	int i;
	cycles = s.cycles;
	for (i = nstack - 1; i >= 0; i--)
	  if (stack[i].raddr == s.raddr) break;
	if (i >= 0) {
	  int j;
	  long time = s.cycles - stack[nstack - 1].cycles;
 
	  /* Whether in normal mode, we must substract called function from execution time.  */
	  if (!cumulative)
	    for (j = 0; j < nstack - 1; j++)
	      stack[j].cycles += time;
 
	  /* pop everything above from current from stack,
	     if more than one, something went wrong */
	  while (i < nstack) {
	    nstack--;
	    if (i != nstack)
	      fprintf (stderr, "WARNING: Missaligned return call for %s (%08X) (found %s @ %08X), closing.\n", stack[nstack].name, stack[nstack].raddr, stack[i].name, stack[i].raddr);
	    for (j = 0; j < nfuncs; j++)
	      if (stack[nstack].addr == func[j].addr) { /* function exists, append. */
		func[j].cum_cycles += s.cycles - stack[nstack].cycles;
		func[j].calls++;
		break;
	      }
	    if (j >= nfuncs) { /* function does not yet exist, create new. */
	      func[nfuncs].cum_cycles = s.cycles - stack[nstack].cycles;
	      func[nfuncs].calls = 1;
	      func[nfuncs].addr = stack[nstack].addr;
	      strcpy (func[nfuncs].name, stack[nstack].name);
	      nfuncs++;
	    }
	  }
	} else fprintf (stderr, "WARNING: Cannot find return call for (%08X), ignoring.\n", s.raddr);
      }
    } else
      break;
  }
  fclose(fprof);
 
  /* Now we have all data acquired. Print out. */
  {
    int i, j;
    if (cumulative)
      printf ("CUMULATIVE TIMES\n");
    printf ("---------------------------------------------------------------------------\n");
    printf ("|function name            |addr    |# calls |avg cycles  |total cyles     |\n");
    printf ("|-------------------------+--------+--------+------------+----------------|\n");
    for (j = 0; j < nfuncs; j++) {
      int bestcyc = 0, besti = 0;
      for (i = 0; i < nfuncs; i++)
	if (func[i].cum_cycles > bestcyc) {
	  bestcyc = func[i].cum_cycles;
	  besti = i;
	}
      i = besti;
      printf ("| %-24s|%08X|%8i|%12.1f|%11i,%3.0f%%|\n",
	      func[i].name, func[i].addr, func[i].calls, ((double)func[i].cum_cycles / func[i].calls), func[i].cum_cycles, (100. * func[i].cum_cycles / cycles));
      func[i].cum_cycles = -1;
    }
    printf ("---------------------------------------------------------------------------\n");
  }
  printf("Total %i functions (max depth %i), %i cycles.\n", nfuncs, maxstack, cycles);
}
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.