📄 sim-profile.c
字号:
/* * sim-profile.c - sample functional simulator implementation w/ profiling * * This file is a part of the SimpleScalar tool suite written by * Todd M. Austin as a part of the Multiscalar Research Project. * * The tool suite is currently maintained by Doug Burger and Todd M. Austin. * * Copyright (C) 1994, 1995, 1996, 1997 by Todd M. Austin * * This source file is distributed "as is" in the hope that it will be * useful. The tool set comes with no warranty, and no author or * distributor accepts any responsibility for the consequences of its * use. * * Everyone is granted permission to copy, modify and redistribute * this tool set under the following conditions: * * This source code is distributed for non-commercial use only. * Please contact the maintainer for restrictions applying to * commercial use. * * Permission is granted to anyone to make or distribute copies * of this source code, either as received or modified, in any * medium, provided that all copyright notices, permission and * nonwarranty notices are preserved, and that the distributor * grants the recipient permission for further redistribution as * permitted by this document. * * Permission is granted to distribute this file in compiled * or executable form under the same conditions that apply for * source code, provided that either: * * A. it is accompanied by the corresponding machine-readable * source code, * B. it is accompanied by a written offer, with no time limit, * to give anyone a machine-readable copy of the corresponding * source code in return for reimbursement of the cost of * distribution. This written offer must permit verbatim * duplication by anyone, or * C. it is distributed by someone who received only the * executable form, and is accompanied by a copy of the * written offer of source code that they received concurrently. * * In other words, you are welcome to use, share and improve this * source file. You are forbidden to forbid anyone else to use, share * and improve what you give them. * * INTERNET: dburger@cs.wisc.edu * US Mail: 1210 W. Dayton Street, Madison, WI 53706 * * $Id: sim-profile.c,v 1.1 1997/03/11 01:33:36 taustin Exp taustin $ * * $Log: sim-profile.c,v $ * Revision 1.1 1997/03/11 01:33:36 taustin * Initial revision * * */#include <stdio.h>#include <stdlib.h>#include <math.h>#include "misc.h"#include "ss.h"#include "regs.h"#include "memory.h"#include "loader.h"#include "syscall.h"#include "dlite.h"#include "symbol.h"#include "options.h"#include "stats.h"#include "sim.h"/* * This file implements a functional simulator with profiling support. Run * with the `-h' flag to see profiling options available. *//* track number of insn and refs */static SS_COUNTER_TYPE sim_num_insn = 0;static SS_COUNTER_TYPE sim_num_refs = 0;/* profiling options */static int prof_all /* = FALSE */;static int prof_ic /* = FALSE */;static int prof_inst /* = FALSE */;static int prof_bc /* = FALSE */;static int prof_am /* = FALSE */;static int prof_seg /* = FALSE */;static int prof_tsyms /* = FALSE */;static int prof_dsyms /* = FALSE */;static int load_locals /* = FALSE */;static int prof_taddr /* = FALSE */;/* text-based stat profiles */#define MAX_PCSTAT_VARS 8static int pcstat_nelt = 0;static char *pcstat_vars[MAX_PCSTAT_VARS];/* register simulator-specific options */voidsim_reg_options(struct opt_odb_t *odb){ opt_reg_header(odb, "sim-profile: This simulator implements a functional simulator with\n""profiling support. Run with the `-h' flag to see profiling options\n""available.\n" ); opt_reg_flag(odb, "-all", "enable all profile options", &prof_all, /* default */FALSE, /* print */TRUE, NULL); opt_reg_flag(odb, "-iclass", "enable instruction class profiling", &prof_ic, /* default */FALSE, /* print */TRUE, NULL); opt_reg_flag(odb, "-iprof", "enable instruction profiling", &prof_inst, /* default */FALSE, /* print */TRUE, NULL); opt_reg_flag(odb, "-brprof", "enable branch instruction profiling", &prof_bc, /* default */FALSE, /* print */TRUE, NULL); opt_reg_flag(odb, "-amprof", "enable address mode profiling", &prof_am, /* default */FALSE, /* print */TRUE, NULL); opt_reg_flag(odb, "-segprof", "enable load/store address segment profiling", &prof_seg, /* default */FALSE, /* print */TRUE, NULL); opt_reg_flag(odb, "-tsymprof", "enable text symbol profiling", &prof_tsyms, /* default */FALSE, /* print */TRUE, NULL); opt_reg_flag(odb, "-taddrprof", "enable text address profiling", &prof_taddr, /* default */FALSE, /* print */TRUE, NULL); opt_reg_flag(odb, "-dsymprof", "enable data symbol profiling", &prof_dsyms, /* default */FALSE, /* print */TRUE, NULL); opt_reg_flag(odb, "-internal", "include compiler-internal symbols during symbol profiling", &load_locals, /* default */FALSE, /* print */TRUE, NULL); opt_reg_string_list(odb, "-pcstat", "profile stat(s) against text addr's (mult uses ok)", pcstat_vars, MAX_PCSTAT_VARS, &pcstat_nelt, NULL, /* !print */FALSE, /* format */NULL, /* accrue */TRUE);}/* check simulator-specific option values */voidsim_check_options(struct opt_odb_t *odb, int argc, char **argv){ if (prof_all) { /* enable all options */ prof_ic = TRUE; prof_inst = TRUE; prof_bc = TRUE; prof_am = TRUE; prof_seg = TRUE; prof_tsyms = TRUE; prof_dsyms = TRUE; prof_taddr = TRUE; }}/* instruction classes */enum inst_class_t { ic_load, /* load inst */ ic_store, /* store inst */ ic_uncond, /* uncond branch */ ic_cond, /* cond branch */ ic_icomp, /* all other integer computation */ ic_fcomp, /* all floating point computation */ ic_trap, /* system call */ ic_NUM};/* instruction class strings */static char *inst_class_str[ic_NUM] = { "load", /* load inst */ "store", /* store inst */ "uncond branch", /* uncond branch */ "cond branch", /* cond branch */ "int computation", /* all other integer computation */ "fp computation", /* all floating point computation */ "trap" /* system call */};/* instruction class profile */static struct stat_stat_t *ic_prof = NULL;/* instruction description strings */static char *inst_str[OP_MAX];/* instruction profile */static struct stat_stat_t *inst_prof = NULL;/* branch class profile */enum branch_class_t { bc_uncond_dir, /* direct unconditional branch */ bc_cond_dir, /* direct conditional branch */ bc_call_dir, /* direct functional call */ bc_uncond_indir, /* indirect unconditional branch */ bc_cond_indir, /* indirect conditional branch */ bc_call_indir, /* indirect function call */ bc_NUM};/* branch class description strings */static char *branch_class_str[bc_NUM] = { "uncond direct", /* direct unconditional branch */ "cond direct", /* direct conditional branch */ "call direct", /* direct functional call */ "uncond indirect", /* indirect unconditional branch */ "cond indirect", /* indirect conditional branch */ "call indirect" /* indirect function call */};/* branch profile */static struct stat_stat_t *bc_prof = NULL;/* address modes */enum addr_mode_t { am_imm, /* immediate addressing mode */ am_gp, /* global data access through global pointer */ am_sp, /* stack access through stack pointer */ am_fp, /* stack access through frame pointer */ am_disp, /* (reg + const) addressing */ am_rr, /* (reg + reg) addressing */ am_NUM};/* address mode description strings */static char *addr_mode_str[am_NUM] = { "(const)", /* immediate addressing mode */ "(gp + const)", /* global data access through global pointer */ "(sp + const)", /* stack access through stack pointer */ "(fp + const)", /* stack access through frame pointer */ "(reg + const)", /* (reg + const) addressing */ "(reg + reg)" /* (reg + reg) addressing */};/* addressing mode profile */static struct stat_stat_t *am_prof = NULL;/* address segments */enum addr_seg_t { seg_data, /* data segment */ seg_heap, /* heap segment */ seg_stack, /* stack segment */ seg_NUM};/* address segment strings */static char *addr_seg_str[seg_NUM] = { "data segment", /* data segment */ "heap segment", /* heap segment */ "stack segment", /* stack segment */};/* address segment profile */static struct stat_stat_t *seg_prof = NULL;/* bind ADDR to the segment it references */static enum addr_seg_t /* segment referenced by ADDR */bind_to_seg(SS_ADDR_TYPE addr) /* address to bind to a segment */{ if (ld_data_base <= addr && addr < (ld_data_base + ld_data_size)) return seg_data; else if ((ld_data_base + ld_data_size) <= addr && addr < mem_brk_point) return seg_heap; else if (mem_stack_min <= addr && addr < SS_STACK_BASE) return seg_stack; else panic("cannot bind address to segment");}/* text symbol profile */static struct stat_stat_t *tsym_prof = NULL;static char **tsym_names = NULL;/* data symbol profile */static struct stat_stat_t *dsym_prof = NULL;static char **dsym_names = NULL;/* text address profile */static struct stat_stat_t *taddr_prof = NULL;/* text-based stat profiles */static struct stat_stat_t *pcstat_stats[MAX_PCSTAT_VARS];static SS_COUNTER_TYPE pcstat_lastvals[MAX_PCSTAT_VARS];static struct stat_stat_t *pcstat_sdists[MAX_PCSTAT_VARS];/* wedge all stat values into a SS_COUNTER_TYPE */#define STATVAL(STAT) \ ((STAT)->sc == sc_int \ ? (SS_COUNTER_TYPE)*((STAT)->variant.for_int.var) \ : ((STAT)->sc == sc_uint \ ? (SS_COUNTER_TYPE)*((STAT)->variant.for_uint.var) \ : ((STAT)->sc == sc_counter \ ? *((STAT)->variant.for_counter.var) \ : (panic("bad stat class"), 0))))/* register simulator-specific statistics */voidsim_reg_stats(struct stat_sdb_t *sdb){ int i; stat_reg_counter(sdb, "sim_num_insn", "total number of instructions executed", &sim_num_insn, 0, NULL); stat_reg_counter(sdb, "sim_num_refs", "total number of loads and stores executed", &sim_num_refs, 0, NULL); stat_reg_int(sdb, "sim_elapsed_time", "total simulation time in seconds", (int *)&sim_elapsed_time, 0, NULL); stat_reg_formula(sdb, "sim_inst_rate", "simulation speed (in insts/sec)", "sim_num_insn / sim_elapsed_time", NULL); if (prof_ic) { /* instruction class profile */ ic_prof = stat_reg_dist(sdb, "sim_inst_class_prof", "instruction class profile", /* initial value */0, /* array size */ic_NUM, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */inst_class_str, /* print fn */NULL); } if (prof_inst) { int i; char buf[512]; /* conjure up appropriate instruction description strings */ for (i=0; i < /* skip NA */OP_MAX-1; i++) { sprintf(buf, "%-8s %-6s", ss_op2name[i+1], ss_op2format[i+1]); inst_str[i] = mystrdup(buf); } /* instruction profile */ inst_prof = stat_reg_dist(sdb, "sim_inst_prof", "instruction profile", /* initial value */0, /* array size */ /* skip NA */OP_MAX-1, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */inst_str, /* print fn */NULL); } if (prof_bc) { /* instruction branch profile */ bc_prof = stat_reg_dist(sdb, "sim_branch_prof", "branch instruction profile", /* initial value */0, /* array size */bc_NUM, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */branch_class_str, /* print fn */NULL); } if (prof_am) { /* instruction branch profile */ am_prof = stat_reg_dist(sdb, "sim_addr_mode_prof", "addressing mode profile", /* initial value */0, /* array size */am_NUM, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */addr_mode_str, /* print fn */NULL); } if (prof_seg) { /* instruction branch profile */ seg_prof = stat_reg_dist(sdb, "sim_addr_seg_prof", "load/store address segment profile", /* initial value */0, /* array size */seg_NUM, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */addr_seg_str, /* print fn */NULL); } if (prof_tsyms) { int i; /* load program symbols */ sym_loadsyms(ld_prog_fname, load_locals); /* conjure up appropriate instruction description strings */ tsym_names = (char **)calloc(sym_ntextsyms, sizeof(char *)); for (i=0; i < sym_ntextsyms; i++) tsym_names[i] = sym_textsyms[i]->name; /* text symbol profile */ tsym_prof = stat_reg_dist(sdb, "sim_text_sym_prof", "text symbol profile", /* initial value */0, /* array size */sym_ntextsyms, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */tsym_names, /* print fn */NULL); } if (prof_dsyms) { int i; /* load program symbols */ sym_loadsyms(ld_prog_fname, load_locals); /* conjure up appropriate instruction description strings */ dsym_names = (char **)calloc(sym_ndatasyms, sizeof(char *)); for (i=0; i < sym_ndatasyms; i++) dsym_names[i] = sym_datasyms[i]->name; /* data symbol profile */ dsym_prof = stat_reg_dist(sdb, "sim_data_sym_prof", "data symbol profile", /* initial value */0, /* array size */sym_ndatasyms, /* bucket size */1, /* print format */(PF_COUNT|PF_PDF), /* format */NULL, /* index map */dsym_names, /* print fn */NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -