File:  [gforth] / gforth / engine / profile.c
Revision 1.1: download - view: text, annotated - select for diffs
Tue Feb 27 21:17:11 2001 UTC (20 years, 1 month ago) by anton
Branches: MAIN
CVS tags: HEAD
good start at profiling for peephole optimization
backtrace now also works for calls done with CALL

    1: /* VM profiling support stuff
    2: 
    3:   Copyright (C) 2001 Free Software Foundation, Inc.
    4: 
    5:   This file is part of Gforth.
    6: 
    7:   Gforth is free software; you can redistribute it and/or
    8:   modify it under the terms of the GNU General Public License
    9:   as published by the Free Software Foundation; either version 2
   10:   of the License, or (at your option) any later version.
   11: 
   12:   This program is distributed in the hope that it will be useful,
   13:   but WITHOUT ANY WARRANTY; without even the implied warranty of
   14:   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15:   GNU General Public License for more details.
   16: 
   17:   You should have received a copy of the GNU General Public License
   18:   along with this program; if not, write to the Free Software
   19:   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
   20: */
   21: 
   22: #include "config.h"
   23: #include <stdlib.h>
   24: #include <stdio.h>
   25: #include "forth.h"
   26: 
   27: /* data structure: simple hash table with external chaining */
   28: 
   29: #define HASH_SIZE (1<<20)
   30: 
   31: typedef struct block_count {
   32:   struct block_count *next; /* next in hash table */
   33:   struct block_count *fallthrough; /* the block that this one falls
   34:                                        through to without SUPER_END */
   35:   Xt *ip;
   36:   long long count;
   37:   char **insts;
   38:   size_t ninsts;
   39: } block_count;
   40: 
   41: block_count *blocks[HASH_SIZE];
   42: 
   43: #define hash(p) ((((Cell)(p))/sizeof(Xt))&(HASH_SIZE-1))
   44: 
   45: block_count *block_lookup(Xt *ip)
   46: {
   47:   block_count *b = blocks[hash(ip)];
   48: 
   49:   while (b!=NULL && b->ip!=ip)
   50:     b = b->next;
   51:   return b;
   52: }
   53: 
   54: /* looks up present elements, inserts absent elements */
   55: block_count *block_insert(Xt *ip)
   56: { 
   57:   block_count *b = block_lookup(ip);
   58:   block_count *new;
   59: 
   60:   if (b != NULL)
   61:     return b;
   62:   new = (block_count *)malloc(sizeof(block_count));
   63:   new->next = blocks[hash(ip)];
   64:   new->fallthrough = NULL;
   65:   new->ip = ip;
   66:   new->count = 0LL;
   67:   new->insts = malloc(0);
   68:   new->ninsts = 0;
   69:   blocks[hash(ip)] = new;
   70:   return new;
   71: }
   72: 
   73: void add_inst(block_count *b, char *inst)
   74: {
   75:   b->insts = realloc(b->insts, b->ninsts * sizeof(char *));
   76:   b->insts[b->ninsts++] = inst;
   77: }
   78: 
   79: void vm_count_block(Xt *ip)
   80: {
   81:   block_insert(ip)->count++;
   82: }
   83: 
   84: /* !! fix this */
   85: #define VM_INST(n) NULL
   86: 
   87: void postprocess_block(block_count *b)
   88: {
   89:   Xt *ip = b->ip;
   90:   block_count *next_block;
   91: 
   92:   do {
   93: #include "profile.i"
   94:     /* else */
   95:     {
   96:       add_inst(b,"unknown");
   97:       ip++;
   98:     }
   99:     next_block = block_lookup(ip);
  100:   } while (next_block == NULL);
  101:   /* we fell through, so set fallthrough and update the count */
  102:   b->fallthrough = next_block;
  103:   /* also update the counts of all following fallthrough blocks that
  104:      have already been processed */
  105:   while (next_block != NULL) {
  106:     next_block->count += b->count;
  107:     next_block = next_block->fallthrough;
  108:   }
  109: }
  110: 
  111: /* Deal with block entry by falling through from non-SUPER_END
  112:    instructions.  And fill the insts and ninsts fields. */
  113: void postprocess(void)
  114: {
  115:   size_t i;
  116: 
  117:   for (i=0; i<HASH_SIZE; i++) {
  118:     block_count *b = blocks[i];
  119:     for (; b!=0; b = b->next)
  120:       postprocess_block(b);
  121:    }
  122: }
  123: 
  124: void print_block(FILE *file, block_count *b)
  125: {
  126:   fprintf(file,"%12lld ip=%p\n",b->count,b->ip);
  127: }
  128: 
  129: void vm_print_profile(FILE *file)
  130: {
  131:   size_t i;
  132: 
  133:   postprocess();
  134:   for (i=0; i<HASH_SIZE; i++) {
  135:     block_count *b = blocks[i];
  136:     for (; b!=0; b = b->next)
  137:       print_block(file, b);
  138:    }
  139: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>