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

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc1/] [or1ksim/] [profiler.c] - Blame information for rev 847

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

Line No. Rev Author Line
1 547 markom
/* profiler.c -- profiling utility
2
   Copyright (C) 2001 Marko Mlinar, markom@opencores.org
3
 
4
This file is part of OpenRISC 1000 Architectural Simulator.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20 173 markom
/* Command line utility, that displays profiling information, generated
21 547 markom
   by or1ksim. (use --profile option at command line, when running or1ksim.  */
22 173 markom
 
23
#include <stdio.h>
24 632 ivang
#include "profiler.h"
25 173 markom
 
26
struct stack_struct {
27 533 markom
  /* Function address */
28
  unsigned int addr;
29
 
30
  /* Cycles of function start; cycles of subfunctions are added later */
31 173 markom
  unsigned int cycles;
32 533 markom
 
33
  /* Return address */
34 173 markom
  unsigned int raddr;
35 533 markom
 
36
  /* Name of the function */
37 173 markom
  char name[33];
38
} stack[MAX_STACK];
39
 
40
struct func_struct {
41 533 markom
  /* Start address of function */
42 173 markom
  unsigned int addr;
43 533 markom
 
44
  /* Name of the function */
45 173 markom
  char name[33];
46 533 markom
 
47
  /* Total cycles spent in function */
48 173 markom
  long cum_cycles;
49 533 markom
 
50
  /* Calls to this function */
51 173 markom
  long calls;
52
} func[MAX_FUNCS];
53
 
54 533 markom
/* Total number of functions */
55 173 markom
int nfuncs = 0;
56 533 markom
 
57
/* Current depth */
58 173 markom
int nstack = 0;
59
 
60 533 markom
/* Max depth */
61
int maxstack = 0;
62 173 markom
 
63 533 markom
/* Number of total calls */
64
int ntotcalls = 0;
65
 
66
/* Number of covered calls */
67
int nfunccalls = 0;
68
 
69
/* Current cycles */
70
static int cycles = 0;
71
 
72
/* Whether we are in cumulative mode */
73
static int cumulative = 0;
74
 
75
/* Whether we should not report warnings */
76
static int quiet = 0;
77
 
78 847 markom
void prof_help ()
79
{
80
  printf ("profiler [-c] [-q] -g [profile_file_name]\n");
81
  printf ("\t-c\t--cumulative\t\tcumulative sum of cycles in functions\n");
82
  printf ("\t-q\t--quiet\t\t\tsuppress messages\n");
83
  printf ("\t-g\t--generate [profile_file_name]\n");
84
  printf ("\t\t\t\t\toutput profiling results to\n");
85
  printf ("\t\t\t\t\tstdout/profile_file_name\n");
86
}
87
 
88 533 markom
/* File to read from */
89
static FILE *fprof = 0;
90
 
91 847 markom
int main_profiler (int argc, char *argv[]) {
92 264 markom
  char fprofname[50] = "sim.profile";
93 173 markom
  int line = 0;
94 632 ivang
 
95 173 markom
  if (argc > 4 || argc < 2) {
96 847 markom
    prof_help ();
97
    return 1;
98 173 markom
  }
99 632 ivang
 
100 173 markom
  argv++; argc--;
101
  while (argc > 0) {
102 533 markom
    if (!strcmp(argv[0], "-q") || !strcmp(argv[0], "--quiet")) {
103
      quiet = 1;
104
      argv++; argc--;
105
    } else if (!strcmp(argv[0], "-c") || !strcmp(argv[0], "--cumulative")) {
106 173 markom
      cumulative = 1;
107
      argv++; argc--;
108
    } else if (strcmp(argv[0], "-g") && strcmp(argv[0], "--generate")) {
109 847 markom
      prof_help ();
110
      return -1;
111 173 markom
    } else {
112
      argv++; argc--;
113
      if (argv[0] && argv[0][0] != '-') {
114
        strcpy (&fprofname[0], argv[0]);
115 239 markom
        argv++; argc--;
116 173 markom
      }
117
    }
118
  }
119
 
120 847 markom
  fprof = fopen (fprofname, "rt");
121 173 markom
 
122
  if (!fprof) {
123 847 markom
    fprintf (stderr, "Cannot open profile file: %s\n", fprofname);
124
    return 1;
125 173 markom
  }
126
 
127
  while (1) {
128
    char dir = fgetc (fprof);
129
    line++;
130
    if (dir == '+') {
131
      if (fscanf (fprof, "%08X %08X %08X %s\n", &stack[nstack].cycles, &stack[nstack].raddr,
132 239 markom
                  &stack[nstack].addr, &stack[nstack].name[0]) != 4)
133
        fprintf (stderr, "Error reading line #%i\n", line);
134 173 markom
      else {
135 533 markom
        cycles = stack[nstack].cycles;
136
        nstack++;
137
        if (nstack > maxstack)
138
          maxstack = nstack;
139
      }
140
      ntotcalls++;
141
    } else if (dir == '-') {
142 173 markom
      struct stack_struct s;
143
      if (fscanf (fprof, "%08X %08X\n", &s.cycles, &s.raddr) != 2)
144 239 markom
        fprintf (stderr, "Error reading line #%i\n", line);
145 173 markom
      else {
146 239 markom
        int i;
147
        cycles = s.cycles;
148
        for (i = nstack - 1; i >= 0; i--)
149
          if (stack[i].raddr == s.raddr) break;
150
        if (i >= 0) {
151 533 markom
          /* pop everything above current from stack,
152 239 markom
             if more than one, something went wrong */
153 533 markom
          while (nstack > i) {
154
            int j;
155
            long time;
156 239 markom
            nstack--;
157 533 markom
            time = s.cycles - stack[nstack].cycles;
158
            if (!quiet && time < 0) {
159
              fprintf (stderr, "WARNING: Negative time at %s (return addr = %08X).\n", stack[i].name, stack[i].raddr);
160
              time = 0;
161
            }
162
 
163
            /* Whether in normal mode, we must substract called function from execution time.  */
164
            if (!cumulative)
165
              for (j = 0; j < nstack; j++)
166
                stack[j].cycles += time;
167
 
168
            if (!quiet && i != nstack)
169 239 markom
              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);
170 533 markom
 
171 239 markom
            for (j = 0; j < nfuncs; j++)
172
              if (stack[nstack].addr == func[j].addr) { /* function exists, append. */
173 533 markom
                func[j].cum_cycles += time;
174 239 markom
                func[j].calls++;
175 533 markom
                nfunccalls++;
176 239 markom
                break;
177
              }
178
            if (j >= nfuncs) { /* function does not yet exist, create new. */
179 533 markom
              func[nfuncs].cum_cycles = time;
180 239 markom
              func[nfuncs].calls = 1;
181 533 markom
              nfunccalls++;
182 239 markom
              func[nfuncs].addr = stack[nstack].addr;
183
              strcpy (func[nfuncs].name, stack[nstack].name);
184
              nfuncs++;
185
            }
186
          }
187 533 markom
        } else if (!quiet) fprintf (stderr, "WARNING: Cannot find return call for (%08X), ignoring.\n", s.raddr);
188 173 markom
      }
189
    } else
190
      break;
191
  }
192
  fclose(fprof);
193
 
194
  /* Now we have all data acquired. Print out. */
195
  {
196
    int i, j;
197
    if (cumulative)
198
      printf ("CUMULATIVE TIMES\n");
199
    printf ("---------------------------------------------------------------------------\n");
200
    printf ("|function name            |addr    |# calls |avg cycles  |total cyles     |\n");
201
    printf ("|-------------------------+--------+--------+------------+----------------|\n");
202
    for (j = 0; j < nfuncs; j++) {
203
      int bestcyc = 0, besti = 0;
204
      for (i = 0; i < nfuncs; i++)
205 239 markom
        if (func[i].cum_cycles > bestcyc) {
206
          bestcyc = func[i].cum_cycles;
207
          besti = i;
208
        }
209 173 markom
      i = besti;
210
      printf ("| %-24s|%08X|%8i|%12.1f|%11i,%3.0f%%|\n",
211 239 markom
              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));
212 173 markom
      func[i].cum_cycles = -1;
213
    }
214
    printf ("---------------------------------------------------------------------------\n");
215
  }
216 533 markom
  printf ("Total %i functions, %i cycles.\n", nfuncs, cycles);
217
  printf ("Total function calls %i/%i (max depth %i).\n", nfunccalls, ntotcalls, maxstack);
218
  return 0;
219 173 markom
}

powered by: WebSVN 2.1.0

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