3 static char rcsid
[] = "$Id$";
9 struct { unsigned int y
:16,x
:10,index
:6; } le
;
10 struct { unsigned int index
:6,x
:10,y
:16; } be
;
15 struct caller
*callers
;
19 struct map
{ /* source code map; 200 coordinates/map */
21 union coordinate u
[200];
24 int npoints
; /* # of execution points if -b specified */
25 int ncalled
= -1; /* #times prof.out says current function was called */
26 static Symbol YYlink
; /* symbol for file's struct _bbdata */
27 static Symbol YYcounts
; /* symbol for _YYcounts if -b specified */
28 static List maplist
; /* list of struct map *'s */
29 static List filelist
; /* list of file names */
30 static Symbol funclist
; /* list of struct func *'s */
31 static Symbol afunc
; /* current function's struct func */
33 /* bbpad - emit space, if necessary, to make size%align == 0; return new size */
34 static int bbpad(int size
, int align
) {
36 (*IR
->space
)(align
- size
%align
);
37 size
= roundup(size
, align
);
42 /* bbcall - build tree to set _callsite at call site *cp, emit call site data */
43 static void bbcall(Symbol yycounts
, Coordinate
*cp
, Tree
*e
) {
47 Symbol p
= genident(STATIC
, array(voidptype
, 0, 0), GLOBAL
);
51 defpointer(cp
->file
? mkstr(cp
->file
)->u
.c
.loc
: (Symbol
)0);
52 defpointer(mkstr(cfunc
->name
)->u
.c
.loc
);
53 if (IR
->little_endian
) {
60 (*IR
->defconst
)(U
, unsignedtype
->size
, (v
.u
= u
.coord
, v
));
61 bbpad(2*voidptype
->size
+ unsignedtype
->size
, p
->type
->align
);
63 caller
= mksymbol(EXTERN
, "_caller", ptr(voidptype
));
66 for (t
= *e
; generic(t
->op
) != CALL
; t
= t
->kids
[0])
67 assert(t
->op
== RIGHT
|| !t
->kids
[1]);
68 assert(generic(t
->op
) == CALL
);
69 t
= tree(t
->op
, t
->type
,
70 tree(RIGHT
, t
->kids
[0]->type
,
72 tree(RIGHT
, t
->kids
[0]->type
, asgn(caller
, idtree(p
)), t
->kids
[0])),
74 for ( ; generic((*e
)->op
) != CALL
; e
= &(*e
)->kids
[0])
79 /* bbentry - return tree for _prologue(&afunc, &YYlink)' */
80 static void bbentry(Symbol yylink
, Symbol f
, void *ignore
) {
81 static Symbol prologue
;
83 afunc
= genident(STATIC
, array(voidptype
, 4, 0), GLOBAL
);
85 prologue
= mksymbol(EXTERN
, "_prologue", ftype(inttype
, voidptype
, voidptype
, NULL
));
86 prologue
->defined
= 0;
88 walk(vcall(prologue
, voidtype
, pointer(idtree(afunc
)), pointer(idtree(yylink
)), NULL
), 0, 0);
91 /* bbexit - return tree for _epilogue(&afunc)' */
92 static void bbexit(Symbol yylink
, Symbol f
, Tree e
) {
93 static Symbol epilogue
;
96 epilogue
= mksymbol(EXTERN
, "_epilogue", ftype(inttype
, voidptype
, NULL
));
97 epilogue
->defined
= 0;
99 walk(vcall(epilogue
, voidtype
, pointer(idtree(afunc
)), NULL
), 0, 0);
102 /* bbfile - add file to list of file names, return its index */
103 static int bbfile(char *file
) {
107 if ((lp
= filelist
) != NULL
)
110 if (((Symbol
)lp
->x
)->u
.c
.v
.p
== file
)
113 } while (lp
!= filelist
);
114 filelist
= append(mkstr(file
), filelist
);
120 /* bbfunc - emit function name and src coordinates */
121 static void bbfunc(Symbol yylink
, Symbol f
, void *ignore
) {
125 defglobal(afunc
, DATA
);
126 defpointer(funclist
);
128 defpointer(mkstr(f
->name
)->u
.c
.loc
);
129 if (IR
->little_endian
) {
130 u
.le
.x
= f
->u
.f
.pt
.x
;
131 u
.le
.y
= f
->u
.f
.pt
.y
;
132 u
.le
.index
= bbfile(f
->u
.f
.pt
.file
);
134 u
.be
.x
= f
->u
.f
.pt
.x
;
135 u
.be
.y
= f
->u
.f
.pt
.y
;
136 u
.be
.index
= bbfile(f
->u
.f
.pt
.file
);
138 (*IR
->defconst
)(U
, unsignedtype
->size
, (v
.u
= u
.coord
, v
));
139 bbpad(3*voidptype
->size
+ unsignedtype
->size
, afunc
->type
->align
);
143 /* bbincr - build tree to increment execution point at *cp */
144 static void bbincr(Symbol yycounts
, Coordinate
*cp
, Tree
*e
) {
145 struct map
*mp
= maplist
->x
;
150 /* append *cp to source map */
151 if (mp
->size
>= NELEMS(mp
->u
)) {
154 maplist
= append(mp
, maplist
);
156 if (IR
->little_endian
) {
157 mp
->u
[mp
->size
].le
.x
= cp
->x
;
158 mp
->u
[mp
->size
].le
.y
= cp
->y
;
159 mp
->u
[mp
->size
++].le
.index
= bbfile(cp
->file
);
161 mp
->u
[mp
->size
].be
.x
= cp
->x
;
162 mp
->u
[mp
->size
].be
.y
= cp
->y
;
163 mp
->u
[mp
->size
++].be
.index
= bbfile(cp
->file
);
165 t
= incr('+', rvalue((*optree
['+'])(ADD
, pointer(idtree(yycounts
)),
166 consttree(npoints
++, inttype
))), consttree(1, inttype
));
168 *e
= tree(RIGHT
, (*e
)->type
, t
, *e
);
173 /* bbvars - emit definition for basic block counting data */
174 static void bbvars(Symbol yylink
, void *ignore
, void *ignore2
) {
175 int i
, j
, n
= npoints
;
178 Symbol coords
, files
, *p
;
180 if (!YYcounts
&& !yylink
)
185 YYcounts
->type
= array(inttype
, n
, 0);
186 defglobal(YYcounts
, BSS
);
187 (*IR
->space
)(YYcounts
->type
->size
);
189 files
= genident(STATIC
, array(charptype
, 1, 0), GLOBAL
);
190 defglobal(files
, LIT
);
191 for (p
= ltov(&filelist
, PERM
); *p
; p
++)
192 defpointer((*p
)->u
.c
.loc
);
194 coords
= genident(STATIC
, array(unsignedtype
, n
, 0), GLOBAL
);
195 defglobal(coords
, LIT
);
196 for (i
= n
, mp
= ltov(&maplist
, PERM
); *mp
; i
-= (*mp
)->size
, mp
++)
197 for (j
= 0; j
< (*mp
)->size
; j
++)
198 (*IR
->defconst
)(U
, unsignedtype
->size
, (v
.u
= (*mp
)->u
[j
].coord
, v
));
200 (*IR
->space
)(i
*coords
->type
->type
->size
);
201 (*IR
->defconst
)(U
, unsignedtype
->size
, (v
.u
= 0, v
));
202 defglobal(yylink
, DATA
);
204 (*IR
->defconst
)(U
, inttype
->size
, (v
.u
= n
, v
));
205 bbpad(voidptype
->size
+ inttype
->size
, yylink
->type
->align
);
206 defpointer(YYcounts
);
209 defpointer(funclist
);
212 /* profInit - initialize basic block profiling options */
213 void profInit(char *arg
) {
214 if (strncmp(arg
, "-a", 2) == 0) {
216 && process(arg
[2] ? &arg
[2] : "prof.out") > 0)
218 } else if ((strcmp(arg
, "-b") == 0
219 || strcmp(arg
, "-C") == 0) && YYlink
== 0) {
220 YYlink
= genident(STATIC
, array(voidptype
, 0, 0), GLOBAL
);
221 attach((Apply
)bbentry
, YYlink
, &events
.entry
);
222 attach((Apply
)bbexit
, YYlink
, &events
.returns
);
223 attach((Apply
)bbfunc
, YYlink
, &events
.exit
);
224 attach((Apply
)bbvars
, YYlink
, &events
.end
);
225 if (strcmp(arg
, "-b") == 0) {
226 YYcounts
= genident(STATIC
, array(inttype
, 0, 0), GLOBAL
);
227 maplist
= append(allocate(sizeof (struct map
), PERM
), maplist
);
228 ((struct map
*)maplist
->x
)->size
= 0;
229 attach((Apply
)bbcall
, YYcounts
, &events
.calls
);
230 attach((Apply
)bbincr
, YYcounts
, &events
.points
);