00001 #include <stdio.h>
00002 #include <stdlib.h>
00003
00004
00005 struct callsite {
00006 char *file, *name;
00007 union coordinate {
00008 struct { unsigned int index:6,x:10,y:16; } be;
00009 struct { unsigned int y:16,x:10,index:6; } le;
00010 unsigned int coord;
00011 } u;
00012 } *_caller;
00013
00014 static struct _bbdata {
00015 struct _bbdata *link;
00016 unsigned npoints, *counts;
00017 union coordinate *coords;
00018 char **files;
00019 struct func {
00020 struct func *link;
00021 struct caller {
00022 struct caller *link;
00023 struct callsite *caller;
00024 unsigned count;
00025 } *callers;
00026 char *name;
00027 union coordinate src;
00028 } *funcs;
00029 } tail, *_bblist = &tail;
00030
00031 static void unpack(unsigned int coord, int *index, int *x, int *y) {
00032 static union { int x; char endian; } little = { 1 };
00033 union coordinate u;
00034
00035 u.coord = coord;
00036 if (little.endian) {
00037 *index = u.le.index;
00038 *x = u.le.x;
00039 *y = u.le.y;
00040 } else {
00041 *index = u.be.index;
00042 *x = u.be.x;
00043 *y = u.be.y;
00044 }
00045 }
00046
00047 static void profout(struct _bbdata *p, FILE *fp) {
00048 int i, index, x, y;
00049 struct func *f;
00050 struct caller *q;
00051
00052 for (i = 0; p->files[i]; i++)
00053 ;
00054 fprintf(fp, "%d\n", i);
00055 for (i = 0; p->files[i]; i++)
00056 fprintf(fp, "%s\n", p->files[i]);
00057 for (i = 0, f = p->funcs; f; i++, f = f->link)
00058 if (q = f->callers)
00059 for (i--; q; q = q->link)
00060 i++;
00061 fprintf(fp, "%d\n", i);
00062 for (f = p->funcs; f; f = f->link) {
00063 int n = 0;
00064 for (q = f->callers; q; n += q->count, q = q->link) {
00065 unpack(f->src.coord, &index, &x, &y);
00066 fprintf(fp, "%s %d %d %d %d", f->name, index, x, y, q->count);
00067 if (q->caller) {
00068 unpack(q->caller->u.coord, &index, &x, &y);
00069 fprintf(fp, " %s %s %d %d\n", q->caller->name, q->caller->file, x, y);
00070 } else
00071 fprintf(fp, " ? ? 0 0\n");
00072 }
00073 if (n == 0) {
00074 unpack(f->src.coord, &index, &x, &y);
00075 fprintf(fp, "%s %d %d %d 0 ? ? 0 0\n", f->name, index, x, y);
00076 }
00077 }
00078 fprintf(fp, "%d\n", p->npoints);
00079 for (i = 0; i < p->npoints; i++) {
00080 unpack(p->coords[i].coord, &index, &x, &y);
00081 fprintf(fp, "%d %d %d %d\n", index, x, y, p->counts[i]);
00082 }
00083 }
00084
00085 static void bbexit(void) {
00086 FILE *fp;
00087
00088 if (_bblist != &tail && (fp = fopen("prof.out", "a"))) {
00089 for ( ; _bblist != &tail; _bblist = _bblist->link)
00090 profout(_bblist, fp);
00091 fclose(fp);
00092 }
00093 }
00094
00095 void _epilogue(struct func *callee) {
00096 _caller = 0;
00097 }
00098
00099 void _prologue(struct func *callee, struct _bbdata *yylink) {
00100 static struct caller callers[4096];
00101 static int next;
00102 struct caller *p;
00103
00104 if (!yylink->link) {
00105 yylink->link = _bblist;
00106 _bblist = yylink;
00107 if (next == 0)
00108 atexit(bbexit);
00109 }
00110 for (p = callee->callers; p; p = p->link)
00111 if (p->caller == _caller) {
00112 p->count++;
00113 break;
00114 }
00115 if (!p && next < sizeof callers/sizeof callers[0]) {
00116 p = &callers[next++];
00117 p->caller = _caller;
00118 p->count = 1;
00119 p->link = callee->callers;
00120 callee->callers = p;
00121 }
00122 _caller = 0;
00123 }