~ubuntu-branches/ubuntu/precise/openarena/precise

« back to all changes in this revision

Viewing changes to code/tools/lcc/src/prof.c

  • Committer: Bazaar Package Importer
  • Author(s): Bruno "Fuddl" Kleinert
  • Date: 2007-01-20 12:28:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070120122809-2yza5ojt7nqiyiam
Tags: upstream-0.6.0
ImportĀ upstreamĀ versionĀ 0.6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "c.h"
 
2
 
 
3
 
 
4
struct callsite {
 
5
        char *file, *name;
 
6
        union coordinate {
 
7
                unsigned int coord;
 
8
                struct { unsigned int y:16,x:10,index:6; } le;
 
9
                struct { unsigned int index:6,x:10,y:16; } be;
 
10
        } u;
 
11
};
 
12
struct func {
 
13
        struct func *link;
 
14
        struct caller *callers;
 
15
        char *name;
 
16
        union coordinate src;
 
17
};
 
18
struct map {            /* source code map; 200 coordinates/map */
 
19
        int size;
 
20
        union coordinate u[200];
 
21
};
 
22
 
 
23
int npoints;            /* # of execution points if -b specified */
 
24
int ncalled = -1;       /* #times prof.out says current function was called */
 
25
static Symbol YYlink;   /* symbol for file's struct _bbdata */
 
26
static Symbol YYcounts; /* symbol for _YYcounts if -b specified */
 
27
static List maplist;    /* list of struct map *'s */
 
28
static List filelist;   /* list of file names */
 
29
static Symbol funclist; /* list of struct func *'s */
 
30
static Symbol afunc;    /* current function's struct func */
 
31
 
 
32
/* bbcall - build tree to set _callsite at call site *cp, emit call site data */
 
33
static void bbcall(Symbol yycounts, Coordinate *cp, Tree *e) {
 
34
        static Symbol caller;
 
35
        Value v;
 
36
        union coordinate u;
 
37
        Symbol p = genident(STATIC, array(voidptype, 0, 0), GLOBAL);
 
38
        Tree t = *e;
 
39
 
 
40
        defglobal(p, LIT);
 
41
        defpointer(cp->file ? mkstr(cp->file)->u.c.loc : (Symbol)0);
 
42
        defpointer(mkstr(cfunc->name)->u.c.loc);
 
43
        if (IR->little_endian) {
 
44
                u.le.x = cp->x;
 
45
                u.le.y = cp->y;
 
46
        } else {
 
47
                u.be.x = cp->x;
 
48
                u.be.y = cp->y;
 
49
        }
 
50
        (*IR->defconst)(U, unsignedtype->size, (v.u = u.coord, v));
 
51
        if (caller == 0) {
 
52
                caller = mksymbol(EXTERN, "_caller", ptr(voidptype));
 
53
                caller->defined = 0;
 
54
        }
 
55
        if (generic((*e)->op) != CALL)
 
56
                t = (*e)->kids[0];
 
57
        assert(generic(t->op) == CALL);
 
58
        t = tree(t->op, t->type,
 
59
                tree(RIGHT, t->kids[0]->type,
 
60
                        t->kids[0],
 
61
                        tree(RIGHT, t->kids[0]->type, asgn(caller, idtree(p)), t->kids[0])),
 
62
                t->kids[1]);
 
63
        if (generic((*e)->op) != CALL)
 
64
                t = tree((*e)->op, (*e)->type, t, (*e)->kids[1]);
 
65
        *e = t;
 
66
}
 
67
 
 
68
/* bbentry - return tree for _prologue(&afunc, &YYlink)' */
 
69
static void bbentry(Symbol yylink, Symbol f) {
 
70
        static Symbol prologue;
 
71
        
 
72
        afunc = genident(STATIC, array(voidptype, 4, 0), GLOBAL);
 
73
        if (prologue == 0) {
 
74
                prologue = mksymbol(EXTERN, "_prologue", ftype(inttype, voidptype));
 
75
                prologue->defined = 0;
 
76
        }
 
77
        walk(vcall(prologue, voidtype, pointer(idtree(afunc)), pointer(idtree(yylink)), NULL), 0, 0);
 
78
 
 
79
}
 
80
 
 
81
/* bbexit - return tree for _epilogue(&afunc)' */
 
82
static void bbexit(Symbol yylink, Symbol f, Tree e) {
 
83
        static Symbol epilogue;
 
84
        
 
85
        if (epilogue == 0) {
 
86
                epilogue = mksymbol(EXTERN, "_epilogue", ftype(inttype, voidptype));
 
87
                epilogue->defined = 0;
 
88
        }
 
89
        walk(vcall(epilogue, voidtype, pointer(idtree(afunc)), NULL), 0, 0);
 
90
}
 
91
 
 
92
/* bbfile - add file to list of file names, return its index */
 
93
static int bbfile(char *file) {
 
94
        if (file) {
 
95
                List lp;
 
96
                int i = 1;
 
97
                if ((lp = filelist) != NULL)
 
98
                        do {
 
99
                                lp = lp->link;
 
100
                                if (((Symbol)lp->x)->u.c.v.p == file)
 
101
                                        return i;
 
102
                                i++;
 
103
                        } while (lp != filelist);
 
104
                filelist = append(mkstr(file), filelist);
 
105
                return i;
 
106
        }
 
107
        return 0;
 
108
}
 
109
 
 
110
/* bbfunc - emit function name and src coordinates */
 
111
static void bbfunc(Symbol yylink, Symbol f) {
 
112
        Value v;
 
113
        union coordinate u;
 
114
 
 
115
        defglobal(afunc, DATA);
 
116
        defpointer(funclist);
 
117
        defpointer(NULL);
 
118
        defpointer(mkstr(f->name)->u.c.loc);
 
119
        if (IR->little_endian) {
 
120
                u.le.x = f->u.f.pt.x;
 
121
                u.le.y = f->u.f.pt.y;
 
122
                u.le.index = bbfile(f->u.f.pt.file);
 
123
        } else {
 
124
                u.be.x = f->u.f.pt.x;
 
125
                u.be.y = f->u.f.pt.y;
 
126
                u.be.index = bbfile(f->u.f.pt.file);
 
127
        }
 
128
        (*IR->defconst)(U, unsignedtype->size, (v.u = u.coord, v));
 
129
        funclist = afunc;
 
130
}
 
131
 
 
132
/* bbincr - build tree to increment execution point at *cp */
 
133
static void bbincr(Symbol yycounts, Coordinate *cp, Tree *e) {
 
134
        struct map *mp = maplist->x;
 
135
        Tree t;
 
136
 
 
137
        /* append *cp to source map */
 
138
        if (mp->size >= NELEMS(mp->u)) {
 
139
                NEW(mp, PERM);
 
140
                mp->size = 0;
 
141
                maplist = append(mp, maplist);
 
142
        }
 
143
        if (IR->little_endian) {
 
144
                mp->u[mp->size].le.x = cp->x;
 
145
                mp->u[mp->size].le.y = cp->y;
 
146
                mp->u[mp->size++].le.index = bbfile(cp->file);
 
147
        } else {
 
148
                mp->u[mp->size].be.x = cp->x;
 
149
                mp->u[mp->size].be.y = cp->y;
 
150
                mp->u[mp->size++].be.index = bbfile(cp->file);
 
151
        }
 
152
        t = incr('+', rvalue((*optree['+'])(ADD, pointer(idtree(yycounts)),
 
153
                consttree(npoints++, inttype))), consttree(1, inttype));
 
154
        if (*e)
 
155
                *e = tree(RIGHT, (*e)->type, t, *e);
 
156
        else
 
157
                *e = t;
 
158
}
 
159
 
 
160
/* bbvars - emit definition for basic block counting data */
 
161
static void bbvars(Symbol yylink) {
 
162
        int i, j, n = npoints;
 
163
        Value v;
 
164
        struct map **mp;
 
165
        Symbol coords, files, *p;
 
166
 
 
167
        if (!YYcounts && !yylink)
 
168
                return;
 
169
        if (YYcounts) {
 
170
                if (n <= 0)
 
171
                        n = 1;
 
172
                YYcounts->type = array(unsignedtype, n, 0);
 
173
                defglobal(YYcounts, BSS);
 
174
        }
 
175
        files = genident(STATIC, array(charptype, 1, 0), GLOBAL);
 
176
        defglobal(files, LIT);
 
177
        for (p = ltov(&filelist, PERM); *p; p++)
 
178
                defpointer((*p)->u.c.loc);
 
179
        defpointer(NULL);
 
180
        coords = genident(STATIC, array(unsignedtype, n, 0), GLOBAL);
 
181
        defglobal(coords, LIT);
 
182
        for (i = n, mp = ltov(&maplist, PERM); *mp; i -= (*mp)->size, mp++)
 
183
                for (j = 0; j < (*mp)->size; j++)
 
184
                        (*IR->defconst)(U, unsignedtype->size, (v.u = (*mp)->u[j].coord, v));
 
185
        if (i > 0)
 
186
                (*IR->space)(i*coords->type->type->size);
 
187
        defpointer(NULL);
 
188
        defglobal(yylink, DATA);
 
189
        defpointer(NULL);
 
190
        (*IR->defconst)(U, unsignedtype->size, (v.u = n, v));
 
191
        defpointer(YYcounts);
 
192
        defpointer(coords);
 
193
        defpointer(files);
 
194
        defpointer(funclist);
 
195
}
 
196
 
 
197
/* profInit - initialize basic block profiling options */
 
198
void prof_init(int argc, char *argv[]) {
 
199
        int i;
 
200
        static int inited;
 
201
 
 
202
        if (inited)
 
203
                return;
 
204
        inited = 1;
 
205
        type_init(argc, argv);
 
206
        if (IR) {
 
207
                for (i = 1; i < argc; i++)
 
208
                        if (strncmp(argv[i], "-a", 2) == 0) {
 
209
                                if (ncalled == -1
 
210
                                && process(argv[i][2] ? &argv[i][2] : "prof.out") > 0)
 
211
                                        ncalled = 0;
 
212
                        } else if ((strcmp(argv[i], "-b") == 0
 
213
                                 || strcmp(argv[i], "-C") == 0) && YYlink == 0) {
 
214
                                YYlink = genident(STATIC, array(unsignedtype, 0, 0), GLOBAL);
 
215
                                attach((Apply)bbentry, YYlink, &events.entry);
 
216
                                attach((Apply)bbexit,  YYlink, &events.returns);
 
217
                                attach((Apply)bbfunc,  YYlink, &events.exit);
 
218
                                attach((Apply)bbvars,  YYlink, &events.end);
 
219
                                if (strcmp(argv[i], "-b") == 0) {
 
220
                                        YYcounts = genident(STATIC, array(unsignedtype, 0, 0), GLOBAL);
 
221
                                        maplist = append(allocate(sizeof (struct map), PERM), maplist);
 
222
                                        ((struct map *)maplist->x)->size = 0;
 
223
                                        attach((Apply)bbcall, YYcounts, &events.calls);
 
224
                                        attach((Apply)bbincr, YYcounts, &events.points);
 
225
                                }
 
226
                        }
 
227
  }
 
228
}