home *** CD-ROM | disk | FTP | other *** search
/ Total Destruction / Total_Destruction.iso / addons / Lccwin32.exe / Lccwin32 / lccpub / src / prof.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-11  |  6.2 KB  |  218 lines

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