|
|
researchv10 Norman
#include "stdio.h"
#include "ctype.h"
typedef unsigned long ul;
typedef struct {
char *fname;
int len; /* how many counts have been seen */
int quot; /* how much has been allocated for cnt */
int flag;
unsigned long *cnt; /* the basic block counts */
int *instrcnt; /* instrs per basic block, from .sL */
int *lastline; /* last source line containing instr from bb */
} stab;
stab *tab;
int ntab, ltab;
unsigned long N, B, L, V; /* for summary */
double A, U;
FILE *fd, *sfd, *cfd;
extern FILE *popen();
char fname[512] = "/"; /* not checked for overflow */
char buf[256];
char curfunc[256];
extern char *malloc();
char flg[128];
unsigned long val;
char prcmd[128] = "pr -h %s "; /* space for extra args */
main(argc, argv)
char **argv;
{ int i, j, seenpart = 0;
if((fd = fopen("prof.out", "r")) == 0) {
perror("prof.out");
exit(1);
}
readall();
fclose(fd);
for(i = 1; i < argc; i++)
if(argv[i][0] != '-') {
seenpart++;
okfile(argv[i]);
}
else for(j = 1; argv[i][j]; j++)
switch(argv[i][j]) {
default: /* assume whole thing is for pr */
strcat(prcmd, argv[i]);
strcat(prcmd, " ");
break;
case 'b': /* each bb */
flg['b']++;
break;
case 'a': /* intermediate everything */
flg['a']++;
break;
case 'i': /* count machine instrs */
flg['i']++;
break;
case 'f': /* counts by function */
flg['f']++;
flg['s']++;
break;
case 'p': /* print, in addition */
flg['p']++;
break;
case 's': /* bb summary */
flg['s']++;
break;
case 'c': /* compress prof.out */
flg['c']++;
break;
}
if(argc <= seenpart + 1)
flg['p']++;
if(!seenpart)
for(i = 0; i < ntab; i++)
tab[i].flag = 1;
if(flg['f']) {
for(i = 0; i < ntab; i++)
fsum(tab + i);
}
if(flg['s']) {
for(i = 0; i < ntab; i++)
summary(tab + i);
if(ntab > 1)
printf("%.0fie %ui %uin %.0fbbe %ubb %ubbne total\n",
A, N, B, U, L, V);
}
if(flg['c']) {
fd = fopen("prof.out", "w");
if(fd == 0) {
perror("rewriting prof.out");
exit(1);
}
for(i = 0; i < ntab; i++) {
fprintf(fd, "%s\n", tab[i].fname);
for(j = 0; j < tab[i].len; j++)
fprintf(fd, "%u\n", tab[i].cnt[j]);
}
fclose(fd);
}
if(flg['p'] || flg['i'] || flg['a'] || flg['b'])
giantprint();
exit(0);
}
okfile(s)
char *s;
{ int i, j, k;
j = strlen(s);
for(i = 0; i < ntab; i++) {
k = strlen(tab[i].fname);
if(strcmp(s, tab[i].fname + k - j) == 0) {
tab[i].flag = 1;
return;
}
}
fprintf(stderr, "argument %s not a source file\n", s);
exit(1);
}
readall()
{ int c, i, index;
stab *curtab = 0;
sawnl:
if((c = getc(fd)) == EOF)
return;
if(c == '\n')
goto sawnl;
if(c == '/') {
fscanf(fd, "%s", fname+1);
for(i = 0; i < ntab; i++)
if(strcmp(fname, tab[i].fname) == 0)
break;
if(i >= ntab) { /* new file */
if(ltab == 0) {
tab = (stab *)malloc(20 * sizeof(stab));
ltab = 20;
}
else if(ntab >= ltab)
tab = (stab *)realloc((char *)tab,
(ltab += 20) * sizeof(stab));
tab[ntab].fname = malloc(sizeof(fname) + 1);
strcpy(tab[ntab].fname, fname);
tab[ntab].flag = tab[ntab].len = tab[ntab].quot = 0;
ntab++;
}
curtab = tab + i;
index = 0;
}
else if(c < '0' || c > '9') {
fprintf(stderr, "prof.out has weird format\n");
abort();
}
else {
ungetc(c, fd);
fscanf(fd, "%d", &val);
if(curtab->len <= index) {
if(curtab->quot == 0) {
curtab->cnt = (ul *)malloc(100*sizeof(long));
curtab->quot = 100;
for(i = 0; i < 100; i++)
curtab->cnt[i] = 0;
}
else if(curtab->len >= curtab->quot) {
curtab->cnt = (ul *)realloc((char *)curtab->cnt,
(curtab->quot += 200) * sizeof(long));
for(i = curtab->quot-200; i < curtab->quot; i++)
curtab->cnt[i] = 0;
}
curtab->len++;
}
curtab->cnt[index++] += val;
}
goto sawnl;
}
summary(x)
stab *x;
{ unsigned long i, v, n, b;
double a, u;
for(i = u = v = 0; i < x->len; i++)
if(x->cnt[i])
u += x->cnt[i];
else
v++;
n = strlen(x->fname);
strcpy(buf, x->fname);
strcpy(buf + n - 2, ".sL");
if((fd = fopen(buf, "r")) == 0) {
perror(buf);
printf("%s %u bbs %.0f execs %u untouched\n",
x->fname, x->len, u, v);
return;
}
for(n = a = b = 0; ;) {
(void) fgets(buf, sizeof(buf), fd);
if(feof(fd))
break;
if(hascolon(buf))
continue;
n++;
i = atoi(buf)/4 - 3;
if(x->cnt[i])
a += x->cnt[i];
else
b++;
}
printf("%.0fie %ui %uine %.0fbbe %ubb %ubbne %s\n", a, n, b, u, x->len,
v, x->fname);
fclose(fd);
A += a; N += n; B += b; U += u; L += x->len; V += v;
}
fsum(x)
stab *x;
{ unsigned i, v, n, b, cnt;
double a, u;
char *p;
strcpy(buf, x->fname);
n = strlen(x->fname);
strcpy(buf + n - 2, ".sL");
if((fd = fopen(buf, "r")) == 0) {
perror(buf);
return;
}
curfunc[0] = 0;
for(cnt = v = n = b = a = u = 0;;) {
(void) fgets(buf, sizeof(buf), fd);
if(feof(fd))
break;
if(hascolon(buf)) {
/* 24 foo.c: 456 or
* 24 foo.c: _funcjunk */
for(p = buf; *p != ':'; p++)
;
while(isspace(*++p))
;
if(isdigit(*p))
continue;
if(curfunc[0] != 0)
printf("%.0fie %dcalls %ui %uine %s\n",
a, v, n, b, curfunc);
for(i = 0; *p && *p != '\n'; i++)
curfunc[i] = *p++;
curfunc[i] = 0;
a = n = b = 0;
i = atoi(buf)/4 - 3;
v = x->cnt[i];
continue;
}
n++;
i = atoi(buf)/4 - 3;
if(x->cnt[i])
a += x->cnt[i];
else
b++;
}
if(n > 0)
printf("%.0fie %dcalls %ui %uine %s\n", a, v, n, b, curfunc);
fclose(fd);
}
giantprint()
{ int i, n;
for(i = 0; i < ntab; i++) {
if(tab[i].flag == 0)
continue;
/* the fname file is the source, there should be a corresponding
* .sL file for correlation between basic blocks and source.
* If fname is a .s file, the .sL file is all there is */
n = strlen(tab[i].fname);
if(strcmp(".s", tab[i].fname + n - 2) == 0) {
sfile(tab + i);
continue;
}
sfd = fopen(tab[i].fname, "r");
if(sfd == 0 && !flg['a']) {
perror(tab[i].fname);
return;
}
strcpy(buf, tab[i].fname);
strcpy(buf + n - 1, "sL");
if((cfd = fopen(buf, "r")) == 0) {
fprintf(stderr, "no intermediate listing file ");
perror(buf);
fclose(sfd);
return;
}
sprintf(buf, prcmd, tab[i].fname);
if(!flg['a'])
fd = popen(buf, "w");
if(!flg['a'])
xlistit(tab + i);
else
listit(tab + i);
if(fd)
pclose(fd);
if(sfd)
fclose(sfd);
fclose(cfd);
}
}
sfile(x)
stab *x;
{ int i;
char *p;
strcpy(buf, x->fname);
strcat(buf, "L");
sfd = fopen(buf, "r");
if(sfd == 0) {
perror(buf);
return;
}
sprintf(buf, "pr -h %s", x->fname);
fd = popen(buf, "w");
if(fd == 0) {
perror(buf);
fclose(sfd);
return;
}
for(;;) {
(void) fgets(buf, sizeof(buf), sfd);
if(feof(sfd)) {
pclose(fd);
fclose(sfd);
return;
}
for(i = 0, p = buf; *p >= '0' && *p <= '9'; p++)
i = 10 * i + *p - '0';
i = i/4 - 3;
fprintf(fd, "%u\t%s", x->cnt[i], p);
}
}
/* function added, so name (stripnum) is now misleading */
char *
stripnum(s)
char *s;
{ char *p;
while(*s && (isdigit(*s) || isspace(*s)))
s++;
for(p = s; *p && *p != '\n'; p++)
;
if(*p == '\n')
*p = ' ';
return(s);
}
listit(x)
stab *x;
{ int i;
char *p;
for(;;) {
(void) fgets(buf, sizeof(buf), cfd);
if(feof(cfd))
break;
for(p = buf; *p && *p != ':' ; p++)
;
if(*p++ != ':') { /* these are instructions */
i = x->cnt[atoi(buf)/4 - 3];
printf("%d\t%s\n", i, stripnum(buf));
continue;
}
else {
printf("%s", stripnum(buf));
if(atoi(p) == 0) { /* foo.c: _main */
putchar('\n');
continue;
}
(void) fgets(buf, sizeof(buf), sfd);
printf("%s", buf);
continue;
}
}
}
xlistit(x)
stab *x;
{ int lnum, i, icnt, bcnt;
char *p;
x->instrcnt = (int *) malloc(x->len * sizeof(int));
x->lastline = (int *) malloc(x->len * sizeof(int));
if(!x->instrcnt || !x->lastline) {
fprintf(stderr, "out of memory\n");
return;
}
for(i = 0; i < x->len; i++)
x->instrcnt[i] = x->lastline[i] = 0;
for(;;) {
(void) fgets(buf, sizeof(buf), cfd);
if(feof(cfd))
break;
for(p = buf; *p && *p != ':'; p++)
;
if(*p++ != ':') { /* instruction */
x->instrcnt[atoi(buf)/4 - 3]++;
continue;
}
lnum = atoi(p); /* hmm (atoi (" x..") is zero?)*/
if(lnum <= 0)
continue;
i = atoi(buf)/4 - 3;
x->lastline[i] = lnum;
}
/* now read all the source lines and print out appropriate stuff */
for(lnum = 1, i = 0;; lnum++) {
(void) fgets(buf, sizeof(buf), sfd);
if(feof(sfd))
return;
icnt = bcnt = 0;
for(; i < x->len && x->lastline[i] <= lnum; i++) {
if(flg['b'] && flg['i'])
fprintf(fd, "%u,%ui ", x->cnt[i],
x->cnt[i] * x->instrcnt[i]);
else if(flg['b'])
fprintf(fd, "%u ", x->cnt[i]);
else {
icnt += x->cnt[i] * x->instrcnt[i];
bcnt += x->cnt[i];
}
}
if(!flg['b'] && flg['p'] && bcnt)
fprintf(fd, "%u ", bcnt);
if(!flg['b'] && flg['i'] && icnt)
fprintf(fd, "%ui ", icnt);
fprintf(fd, "\t%s", buf);
}
}
hascolon(s)
register char *s;
{
for(; *s && *s != ':'; s++)
;
if(*s == ':')
return(1);
else
return(0);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.