|
|
1.1 root 1: #include "stdio.h"
2: #include "ctype.h"
3: typedef unsigned long ul;
4: typedef struct {
5: char *fname;
6: int len; /* how many counts have been seen */
7: int quot; /* how much has been allocated for cnt */
8: int flag;
9: unsigned long *cnt; /* the basic block counts */
10: int *instrcnt; /* instrs per basic block, from .sL */
11: int *lastline; /* last source line containing instr from bb */
12: } stab;
13: stab *tab;
14: int ntab, ltab;
15: unsigned long N, B, L, V; /* for summary */
16: double A, U;
17: FILE *fd, *sfd, *cfd;
18: extern FILE *popen();
19: char fname[512] = "/"; /* not checked for overflow */
20: char buf[256];
21: char curfunc[256];
22: extern char *malloc();
23: char flg[128];
24: unsigned long val;
25: char prcmd[128] = "pr -h %s "; /* space for extra args */
26:
27: main(argc, argv)
28: char **argv;
29: { int i, j, seenpart = 0;
30: if((fd = fopen("prof.out", "r")) == 0) {
31: perror("prof.out");
32: exit(1);
33: }
34: readall();
35: fclose(fd);
36: for(i = 1; i < argc; i++)
37: if(argv[i][0] != '-') {
38: seenpart++;
39: okfile(argv[i]);
40: }
41: else for(j = 1; argv[i][j]; j++)
42: switch(argv[i][j]) {
43: default: /* assume whole thing is for pr */
44: strcat(prcmd, argv[i]);
45: strcat(prcmd, " ");
46: break;
47: case 'b': /* each bb */
48: flg['b']++;
49: break;
50: case 'a': /* intermediate everything */
51: flg['a']++;
52: break;
53: case 'i': /* count machine instrs */
54: flg['i']++;
55: break;
56: case 'f': /* counts by function */
57: flg['f']++;
58: flg['s']++;
59: break;
60: case 'p': /* print, in addition */
61: flg['p']++;
62: break;
63: case 's': /* bb summary */
64: flg['s']++;
65: break;
66: case 'c': /* compress prof.out */
67: flg['c']++;
68: break;
69: }
70: if(argc <= seenpart + 1)
71: flg['p']++;
72: if(!seenpart)
73: for(i = 0; i < ntab; i++)
74: tab[i].flag = 1;
75: if(flg['f']) {
76: for(i = 0; i < ntab; i++)
77: fsum(tab + i);
78: }
79: if(flg['s']) {
80: for(i = 0; i < ntab; i++)
81: summary(tab + i);
82: if(ntab > 1)
83: printf("%.0fie %ui %uin %.0fbbe %ubb %ubbne total\n",
84: A, N, B, U, L, V);
85: }
86: if(flg['c']) {
87: fd = fopen("prof.out", "w");
88: if(fd == 0) {
89: perror("rewriting prof.out");
90: exit(1);
91: }
92: for(i = 0; i < ntab; i++) {
93: fprintf(fd, "%s\n", tab[i].fname);
94: for(j = 0; j < tab[i].len; j++)
95: fprintf(fd, "%u\n", tab[i].cnt[j]);
96: }
97: fclose(fd);
98: }
99: if(flg['p'] || flg['i'] || flg['a'] || flg['b'])
100: giantprint();
101: exit(0);
102: }
103:
104: okfile(s)
105: char *s;
106: { int i, j, k;
107: j = strlen(s);
108: for(i = 0; i < ntab; i++) {
109: k = strlen(tab[i].fname);
110: if(strcmp(s, tab[i].fname + k - j) == 0) {
111: tab[i].flag = 1;
112: return;
113: }
114: }
115: fprintf(stderr, "argument %s not a source file\n", s);
116: exit(1);
117: }
118:
119: readall()
120: { int c, i, index;
121: stab *curtab = 0;
122: sawnl:
123: if((c = getc(fd)) == EOF)
124: return;
125: if(c == '\n')
126: goto sawnl;
127: if(c == '/') {
128: fscanf(fd, "%s", fname+1);
129: for(i = 0; i < ntab; i++)
130: if(strcmp(fname, tab[i].fname) == 0)
131: break;
132: if(i >= ntab) { /* new file */
133: if(ltab == 0) {
134: tab = (stab *)malloc(20 * sizeof(stab));
135: ltab = 20;
136: }
137: else if(ntab >= ltab)
138: tab = (stab *)realloc((char *)tab,
139: (ltab += 20) * sizeof(stab));
140: tab[ntab].fname = malloc(sizeof(fname) + 1);
141: strcpy(tab[ntab].fname, fname);
142: tab[ntab].flag = tab[ntab].len = tab[ntab].quot = 0;
143: ntab++;
144: }
145: curtab = tab + i;
146: index = 0;
147: }
148: else if(c < '0' || c > '9') {
149: fprintf(stderr, "prof.out has weird format\n");
150: abort();
151: }
152: else {
153: ungetc(c, fd);
154: fscanf(fd, "%d", &val);
155: if(curtab->len <= index) {
156: if(curtab->quot == 0) {
157: curtab->cnt = (ul *)malloc(100*sizeof(long));
158: curtab->quot = 100;
159: for(i = 0; i < 100; i++)
160: curtab->cnt[i] = 0;
161: }
162: else if(curtab->len >= curtab->quot) {
163: curtab->cnt = (ul *)realloc((char *)curtab->cnt,
164: (curtab->quot += 200) * sizeof(long));
165: for(i = curtab->quot-200; i < curtab->quot; i++)
166: curtab->cnt[i] = 0;
167: }
168: curtab->len++;
169: }
170: curtab->cnt[index++] += val;
171: }
172: goto sawnl;
173: }
174:
175: summary(x)
176: stab *x;
177: { unsigned long i, v, n, b;
178: double a, u;
179: for(i = u = v = 0; i < x->len; i++)
180: if(x->cnt[i])
181: u += x->cnt[i];
182: else
183: v++;
184: n = strlen(x->fname);
185: strcpy(buf, x->fname);
186: strcpy(buf + n - 2, ".sL");
187: if((fd = fopen(buf, "r")) == 0) {
188: perror(buf);
189: printf("%s %u bbs %.0f execs %u untouched\n",
190: x->fname, x->len, u, v);
191: return;
192: }
193: for(n = a = b = 0; ;) {
194: (void) fgets(buf, sizeof(buf), fd);
195: if(feof(fd))
196: break;
197: if(hascolon(buf))
198: continue;
199: n++;
200: i = atoi(buf)/4 - 3;
201: if(x->cnt[i])
202: a += x->cnt[i];
203: else
204: b++;
205: }
206: printf("%.0fie %ui %uine %.0fbbe %ubb %ubbne %s\n", a, n, b, u, x->len,
207: v, x->fname);
208: fclose(fd);
209: A += a; N += n; B += b; U += u; L += x->len; V += v;
210: }
211:
212: fsum(x)
213: stab *x;
214: { unsigned i, v, n, b, cnt;
215: double a, u;
216: char *p;
217: strcpy(buf, x->fname);
218: n = strlen(x->fname);
219: strcpy(buf + n - 2, ".sL");
220: if((fd = fopen(buf, "r")) == 0) {
221: perror(buf);
222: return;
223: }
224: curfunc[0] = 0;
225: for(cnt = v = n = b = a = u = 0;;) {
226: (void) fgets(buf, sizeof(buf), fd);
227: if(feof(fd))
228: break;
229: if(hascolon(buf)) {
230: /* 24 foo.c: 456 or
231: * 24 foo.c: _funcjunk */
232: for(p = buf; *p != ':'; p++)
233: ;
234: while(isspace(*++p))
235: ;
236: if(isdigit(*p))
237: continue;
238: if(curfunc[0] != 0)
239: printf("%.0fie %dcalls %ui %uine %s\n",
240: a, v, n, b, curfunc);
241: for(i = 0; *p && *p != '\n'; i++)
242: curfunc[i] = *p++;
243: curfunc[i] = 0;
244: a = n = b = 0;
245: i = atoi(buf)/4 - 3;
246: v = x->cnt[i];
247: continue;
248: }
249: n++;
250: i = atoi(buf)/4 - 3;
251: if(x->cnt[i])
252: a += x->cnt[i];
253: else
254: b++;
255: }
256: if(n > 0)
257: printf("%.0fie %dcalls %ui %uine %s\n", a, v, n, b, curfunc);
258: fclose(fd);
259: }
260:
261: giantprint()
262: { int i, n;
263: for(i = 0; i < ntab; i++) {
264: if(tab[i].flag == 0)
265: continue;
266: /* the fname file is the source, there should be a corresponding
267: * .sL file for correlation between basic blocks and source.
268: * If fname is a .s file, the .sL file is all there is */
269: n = strlen(tab[i].fname);
270: if(strcmp(".s", tab[i].fname + n - 2) == 0) {
271: sfile(tab + i);
272: continue;
273: }
274: sfd = fopen(tab[i].fname, "r");
275: if(sfd == 0 && !flg['a']) {
276: perror(tab[i].fname);
277: return;
278: }
279: strcpy(buf, tab[i].fname);
280: strcpy(buf + n - 1, "sL");
281: if((cfd = fopen(buf, "r")) == 0) {
282: fprintf(stderr, "no intermediate listing file ");
283: perror(buf);
284: fclose(sfd);
285: return;
286: }
287: sprintf(buf, prcmd, tab[i].fname);
288: if(!flg['a'])
289: fd = popen(buf, "w");
290: if(!flg['a'])
291: xlistit(tab + i);
292: else
293: listit(tab + i);
294: if(fd)
295: pclose(fd);
296: if(sfd)
297: fclose(sfd);
298: fclose(cfd);
299: }
300: }
301:
302: sfile(x)
303: stab *x;
304: { int i;
305: char *p;
306: strcpy(buf, x->fname);
307: strcat(buf, "L");
308: sfd = fopen(buf, "r");
309: if(sfd == 0) {
310: perror(buf);
311: return;
312: }
313: sprintf(buf, "pr -h %s", x->fname);
314: fd = popen(buf, "w");
315: if(fd == 0) {
316: perror(buf);
317: fclose(sfd);
318: return;
319: }
320: for(;;) {
321: (void) fgets(buf, sizeof(buf), sfd);
322: if(feof(sfd)) {
323: pclose(fd);
324: fclose(sfd);
325: return;
326: }
327: for(i = 0, p = buf; *p >= '0' && *p <= '9'; p++)
328: i = 10 * i + *p - '0';
329: i = i/4 - 3;
330: fprintf(fd, "%u\t%s", x->cnt[i], p);
331: }
332: }
333:
334: /* function added, so name (stripnum) is now misleading */
335: char *
336: stripnum(s)
337: char *s;
338: { char *p;
339: while(*s && (isdigit(*s) || isspace(*s)))
340: s++;
341: for(p = s; *p && *p != '\n'; p++)
342: ;
343: if(*p == '\n')
344: *p = ' ';
345: return(s);
346: }
347:
348: listit(x)
349: stab *x;
350: { int i;
351: char *p;
352: for(;;) {
353: (void) fgets(buf, sizeof(buf), cfd);
354: if(feof(cfd))
355: break;
356: for(p = buf; *p && *p != ':' ; p++)
357: ;
358: if(*p++ != ':') { /* these are instructions */
359: i = x->cnt[atoi(buf)/4 - 3];
360: printf("%d\t%s\n", i, stripnum(buf));
361: continue;
362: }
363: else {
364: printf("%s", stripnum(buf));
365: if(atoi(p) == 0) { /* foo.c: _main */
366: putchar('\n');
367: continue;
368: }
369: (void) fgets(buf, sizeof(buf), sfd);
370: printf("%s", buf);
371: continue;
372: }
373: }
374: }
375:
376: xlistit(x)
377: stab *x;
378: { int lnum, i, icnt, bcnt;
379: char *p;
380: x->instrcnt = (int *) malloc(x->len * sizeof(int));
381: x->lastline = (int *) malloc(x->len * sizeof(int));
382: if(!x->instrcnt || !x->lastline) {
383: fprintf(stderr, "out of memory\n");
384: return;
385: }
386: for(i = 0; i < x->len; i++)
387: x->instrcnt[i] = x->lastline[i] = 0;
388: for(;;) {
389: (void) fgets(buf, sizeof(buf), cfd);
390: if(feof(cfd))
391: break;
392: for(p = buf; *p && *p != ':'; p++)
393: ;
394: if(*p++ != ':') { /* instruction */
395: x->instrcnt[atoi(buf)/4 - 3]++;
396: continue;
397: }
398: lnum = atoi(p); /* hmm (atoi (" x..") is zero?)*/
399: if(lnum <= 0)
400: continue;
401: i = atoi(buf)/4 - 3;
402: x->lastline[i] = lnum;
403: }
404: /* now read all the source lines and print out appropriate stuff */
405: for(lnum = 1, i = 0;; lnum++) {
406: (void) fgets(buf, sizeof(buf), sfd);
407: if(feof(sfd))
408: return;
409: icnt = bcnt = 0;
410: for(; i < x->len && x->lastline[i] <= lnum; i++) {
411: if(flg['b'] && flg['i'])
412: fprintf(fd, "%u,%ui ", x->cnt[i],
413: x->cnt[i] * x->instrcnt[i]);
414: else if(flg['b'])
415: fprintf(fd, "%u ", x->cnt[i]);
416: else {
417: icnt += x->cnt[i] * x->instrcnt[i];
418: bcnt += x->cnt[i];
419: }
420: }
421: if(!flg['b'] && flg['p'] && bcnt)
422: fprintf(fd, "%u ", bcnt);
423: if(!flg['b'] && flg['i'] && icnt)
424: fprintf(fd, "%ui ", icnt);
425: fprintf(fd, "\t%s", buf);
426: }
427: }
428:
429: hascolon(s)
430: register char *s;
431: {
432: for(; *s && *s != ':'; s++)
433: ;
434: if(*s == ':')
435: return(1);
436: else
437: return(0);
438: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.