Code Search for Developers
 
 
  

prof.c from Nxabega at Krugle


Show prof.c syntax highlighted

#include "c.h"


struct callsite {
	char *file, *name;
	union coordinate {
		unsigned int coord;
		struct { unsigned int y:16,x:10,index:6; } le;
		struct { unsigned int index:6,x:10,y:16; } be;
	} u;
};
struct func {
	struct func *link;
	struct caller *callers;
	char *name;
	union coordinate src;
};
struct map {		/* source code map; 200 coordinates/map */
	int size;
	union coordinate u[200];
};

int npoints;		/* # of execution points if -b specified */
int ncalled = -1;	/* #times prof.out says current function was called */
static Symbol YYlink;	/* symbol for file's struct _bbdata */
static Symbol YYcounts;	/* symbol for _YYcounts if -b specified */
static List maplist;	/* list of struct map *'s */
static List filelist;	/* list of file names */
static Symbol funclist;	/* list of struct func *'s */
static Symbol afunc;	/* current function's struct func */

/* bbcall - build tree to set _callsite at call site *cp, emit call site data */
static void bbcall(Symbol yycounts, Coordinate *cp, Tree *e) {
	static Symbol caller;
	Value v;
	union coordinate u;
	Symbol p = genident(STATIC, array(voidptype, 0, 0), GLOBAL);
	Tree t = *e;

	defglobal(p, LIT);
	defpointer(cp->file ? mkstr(cp->file)->u.c.loc : (Symbol)0);
	defpointer(mkstr(cfunc->name)->u.c.loc);
	if (IR->little_endian) {
		u.le.x = cp->x;
		u.le.y = cp->y;
	} else {
		u.be.x = cp->x;
		u.be.y = cp->y;
	}
	(*IR->defconst)(U, unsignedtype->size, (v.u = u.coord, v));
	if (caller == 0) {
		caller = mksymbol(EXTERN, "_caller", ptr(voidptype));
		caller->defined = 0;
	}
	if (generic((*e)->op) != CALL)
		t = (*e)->kids[0];
	assert(generic(t->op) == CALL);
	t = tree(t->op, t->type,
		tree(RIGHT, t->kids[0]->type,
			t->kids[0],
			tree(RIGHT, t->kids[0]->type, asgn(caller, idtree(p)), t->kids[0])),
		t->kids[1]);
	if (generic((*e)->op) != CALL)
		t = tree((*e)->op, (*e)->type, t, (*e)->kids[1]);
	*e = t;
}

/* bbentry - return tree for _prologue(&afunc, &YYlink)' */
static void bbentry(Symbol yylink, Symbol f) {
	static Symbol prologue;
	
	afunc = genident(STATIC, array(voidptype, 4, 0), GLOBAL);
	if (prologue == 0) {
		prologue = mksymbol(EXTERN, "_prologue", ftype(inttype, voidptype));
		prologue->defined = 0;
	}
	walk(vcall(prologue, voidtype, pointer(idtree(afunc)), pointer(idtree(yylink)), NULL), 0, 0);

}

/* bbexit - return tree for _epilogue(&afunc)' */
static void bbexit(Symbol yylink, Symbol f, Tree e) {
	static Symbol epilogue;
	
	if (epilogue == 0) {
		epilogue = mksymbol(EXTERN, "_epilogue", ftype(inttype, voidptype));
		epilogue->defined = 0;
	}
	walk(vcall(epilogue, voidtype, pointer(idtree(afunc)), NULL), 0, 0);
}

/* bbfile - add file to list of file names, return its index */
static int bbfile(char *file) {
	if (file) {
		List lp;
		int i = 1;
		if ((lp = filelist) != NULL)
			do {
				lp = lp->link;
				if (((Symbol)lp->x)->u.c.v.p == file)
					return i;
				i++;
			} while (lp != filelist);
		filelist = append(mkstr(file), filelist);
		return i;
	}
	return 0;
}

/* bbfunc - emit function name and src coordinates */
static void bbfunc(Symbol yylink, Symbol f) {
	Value v;
	union coordinate u;

	defglobal(afunc, DATA);
	defpointer(funclist);
	defpointer(NULL);
	defpointer(mkstr(f->name)->u.c.loc);
	if (IR->little_endian) {
		u.le.x = f->u.f.pt.x;
		u.le.y = f->u.f.pt.y;
		u.le.index = bbfile(f->u.f.pt.file);
	} else {
		u.be.x = f->u.f.pt.x;
		u.be.y = f->u.f.pt.y;
		u.be.index = bbfile(f->u.f.pt.file);
	}
	(*IR->defconst)(U, unsignedtype->size, (v.u = u.coord, v));
	funclist = afunc;
}

/* bbincr - build tree to increment execution point at *cp */
static void bbincr(Symbol yycounts, Coordinate *cp, Tree *e) {
	struct map *mp = maplist->x;
	Tree t;

	/* append *cp to source map */
	if (mp->size >= NELEMS(mp->u)) {
		NEW(mp, PERM);
		mp->size = 0;
		maplist = append(mp, maplist);
	}
	if (IR->little_endian) {
		mp->u[mp->size].le.x = cp->x;
		mp->u[mp->size].le.y = cp->y;
		mp->u[mp->size++].le.index = bbfile(cp->file);
	} else {
		mp->u[mp->size].be.x = cp->x;
		mp->u[mp->size].be.y = cp->y;
		mp->u[mp->size++].be.index = bbfile(cp->file);
	}
	t = incr('+', rvalue((*optree['+'])(ADD, pointer(idtree(yycounts)),
		consttree(npoints++, inttype))), consttree(1, inttype));
	if (*e)
		*e = tree(RIGHT, (*e)->type, t, *e);
	else
		*e = t;
}

/* bbvars - emit definition for basic block counting data */
static void bbvars(Symbol yylink) {
	int i, j, n = npoints;
	Value v;
	struct map **mp;
	Symbol coords, files, *p;

	if (!YYcounts && !yylink)
		return;
	if (YYcounts) {
		if (n <= 0)
			n = 1;
		YYcounts->type = array(unsignedtype, n, 0);
		defglobal(YYcounts, BSS);
	}
	files = genident(STATIC, array(charptype, 1, 0), GLOBAL);
	defglobal(files, LIT);
	for (p = ltov(&filelist, PERM); *p; p++)
		defpointer((*p)->u.c.loc);
	defpointer(NULL);
	coords = genident(STATIC, array(unsignedtype, n, 0), GLOBAL);
	defglobal(coords, LIT);
	for (i = n, mp = ltov(&maplist, PERM); *mp; i -= (*mp)->size, mp++)
		for (j = 0; j < (*mp)->size; j++)
			(*IR->defconst)(U, unsignedtype->size, (v.u = (*mp)->u[j].coord, v));
	if (i > 0)
		(*IR->space)(i*coords->type->type->size);
	defpointer(NULL);
	defglobal(yylink, DATA);
	defpointer(NULL);
	(*IR->defconst)(U, unsignedtype->size, (v.u = n, v));
	defpointer(YYcounts);
	defpointer(coords);
	defpointer(files);
	defpointer(funclist);
}

/* profInit - initialize basic block profiling options */
void prof_init(int argc, char *argv[]) {
	int i;
	static int inited;

	if (inited)
		return;
	inited = 1;
	type_init(argc, argv);
	if (IR)
		for (i = 1; i < argc; i++)
			if (strncmp(argv[i], "-a", 2) == 0) {
				if (ncalled == -1
				&& process(argv[i][2] ? &argv[i][2] : "prof.out") > 0)
					ncalled = 0;
			} else if ((strcmp(argv[i], "-b") == 0
			         || strcmp(argv[i], "-C") == 0) && YYlink == 0) {
				YYlink = genident(STATIC, array(unsignedtype, 0, 0), GLOBAL);
				attach((Apply)bbentry, YYlink, &events.entry);
				attach((Apply)bbexit,  YYlink, &events.returns);
				attach((Apply)bbfunc,  YYlink, &events.exit);
				attach((Apply)bbvars,  YYlink, &events.end);
				if (strcmp(argv[i], "-b") == 0) {
					YYcounts = genident(STATIC, array(unsignedtype, 0, 0), GLOBAL);
					maplist = append(allocate(sizeof (struct map), PERM), maplist);
					((struct map *)maplist->x)->size = 0;
					attach((Apply)bbcall, YYcounts, &events.calls);
					attach((Apply)bbincr, YYcounts, &events.points);
				}
			}
}




See more files for this project here

Nxabega

Nxabega is a First Person Shooter (FPS) based upon the open sourced Quake 3 engine and game code. The final intention is to provide a rich single player game.

Project homepage: http://sourceforge.net/projects/nxabega
Programming language(s): C,C++
License: other

  2html.c
  alloc.c
  alpha.md
  asdl.c
  bind.c
  bytecode.c
  c.h
  config.h
  dag.c
  dagcheck.md
  decl.c
  enode.c
  error.c
  event.c
  expr.c
  gen.c
  init.c
  inits.c
  input.c
  lex.c
  list.c
  main.c
  mips.md
  null.c
  output.c
  pass2.c
  prof.c
  profio.c
  rcc.asdl
  run.sh
  simp.c
  sparc.md
  stab.c
  stab.h
  stmt.c
  string.c
  sym.c
  symbolic.c
  token.h
  trace.c
  tree.c
  types.c
  x86.md
  x86linux.md