"I am a person who works hard and plays hard."

Yuan Wei
Second Year Graduate Student Department of Computer Science
University of Virginia Charlottesville, VA 22903
Email: yw3f@cs.virginia.edu


Source Code Analysis

Main Page   Compound List   File List   Compound Members   File Members  

bpred.h

Go to the documentation of this file.
00001 /*
00002  * bpred.h - branch predictor interfaces
00003  *
00004  * This file is a part of the SimpleScalar tool suite written by
00005  * Todd M. Austin as a part of the Multiscalar Research Project.
00006  *  
00007  * The tool suite is currently maintained by Doug Burger and Todd M. Austin.
00008  * 
00009  * Copyright (C) 1994, 1995, 1996, 1997, 1998 by Todd M. Austin
00010  *
00011  * This source file is distributed "as is" in the hope that it will be
00012  * useful.  The tool set comes with no warranty, and no author or
00013  * distributor accepts any responsibility for the consequences of its
00014  * use. 
00015  * 
00016  * Everyone is granted permission to copy, modify and redistribute
00017  * this tool set under the following conditions:
00018  * 
00019  *    This source code is distributed for non-commercial use only. 
00020  *    Please contact the maintainer for restrictions applying to 
00021  *    commercial use.
00022  *
00023  *    Permission is granted to anyone to make or distribute copies
00024  *    of this source code, either as received or modified, in any
00025  *    medium, provided that all copyright notices, permission and
00026  *    nonwarranty notices are preserved, and that the distributor
00027  *    grants the recipient permission for further redistribution as
00028  *    permitted by this document.
00029  *
00030  *    Permission is granted to distribute this file in compiled
00031  *    or executable form under the same conditions that apply for
00032  *    source code, provided that either:
00033  *
00034  *    A. it is accompanied by the corresponding machine-readable
00035  *       source code,
00036  *    B. it is accompanied by a written offer, with no time limit,
00037  *       to give anyone a machine-readable copy of the corresponding
00038  *       source code in return for reimbursement of the cost of
00039  *       distribution.  This written offer must permit verbatim
00040  *       duplication by anyone, or
00041  *    C. it is distributed by someone who received only the
00042  *       executable form, and is accompanied by a copy of the
00043  *       written offer of source code that they received concurrently.
00044  *
00045  * In other words, you are welcome to use, share and improve this
00046  * source file.  You are forbidden to forbid anyone else to use, share
00047  * and improve what you give them.
00048  *
00049  * INTERNET: dburger@cs.wisc.edu
00050  * US Mail:  1210 W. Dayton Street, Madison, WI 53706
00051  *
00052  * $Id: bpred.h,v 1.1.1.1 2000/05/26 15:18:57 taustin Exp $
00053  *
00054  * $Log: bpred.h,v $
00055  * Revision 1.1.1.1  2000/05/26 15:18:57  taustin
00056  * SimpleScalar Tool Set
00057  *
00058  *
00059  * Revision 1.5  1998/08/31 17:12:11  taustin
00060  * eliminated unportable "uint" reference
00061  *
00062  * Revision 1.4  1998/08/27 08:00:15  taustin
00063  * implemented host interface description in host.h
00064  * explicit BTB sizing option added to branch predictors, use
00065  *       "-btb" option to configure BTB
00066  * return address stack (RAS) performance stats improved
00067  *
00068  * Revision 1.1.1.1  1997/05/22 18:04:05  aklauser
00069  *
00070  * Revision 1.8  1997/05/01 20:23:06  skadron
00071  * BTB bug fixes; jumps no longer update direction state; non-taken
00072  *    branches non longer update BTB
00073  *
00074  * Revision 1.7  1997/05/01 00:05:51  skadron
00075  * Separated BTB from direction-predictor
00076  *
00077  * Revision 1.6  1997/04/29  23:50:44  skadron
00078  * Added r31 info to distinguish between return-JRs and other JRs for bpred
00079  *
00080  * Revision 1.5  1997/04/29  22:53:10  skadron
00081  * Hopefully bpred is now right: bpred now allocates entries only for
00082  *    branches; on a BTB miss it still returns a direction; and it uses a
00083  *    return-address stack.  Returns are not yet distinguished among JR's
00084  *
00085  * Revision 1.4  1997/04/28  17:37:09  skadron
00086  * Bpred now allocates entries for any instruction instead of only
00087  *    branches; also added return-address stack
00088  *
00089  * Revision 1.3  1997/04/24  16:57:27  skadron
00090  * Bpred used to return no prediction if the indexing branch didn't match
00091  *    in the BTB.  Now it can predict a direction even on a BTB address
00092  *    conflict
00093  *
00094  * Revision 1.2  1997/03/25 16:17:21  skadron
00095  * Added function called after priming
00096  *
00097  * Revision 1.1  1997/02/16  22:23:54  skadron
00098  * Initial revision
00099  *
00100  *
00101  */
00102 
00103 #ifndef BPRED_H
00104 #define BPRED_H
00105 
00106 #define dassert(a) assert(a)
00107 
00108 #include <stdio.h>
00109 
00110 #include "host.h"
00111 #include "misc.h"
00112 #include "machine.h"
00113 #include "stats.h"
00114 
00115 /*
00116  * This module implements a number of branch predictor mechanisms.  The
00117  * following predictors are supported:
00118  *
00119  *      BPred2Level:  two level adaptive branch predictor
00120  *
00121  *              It can simulate many prediction mechanisms that have up to
00122  *              two levels of tables. Parameters are:
00123  *                   N   # entries in first level (# of shift register(s))
00124  *                   W   width of shift register(s)
00125  *                   M   # entries in 2nd level (# of counters, or other FSM)
00126  *              One BTB entry per level-2 counter.
00127  *
00128  *              Configurations:   N, W, M
00129  *
00130  *                  counter based: 1, 0, M
00131  *
00132  *                  GAg          : 1, W, 2^W
00133  *                  GAp          : 1, W, M (M > 2^W)
00134  *                  PAg          : N, W, 2^W
00135  *                  PAp          : N, W, M (M == 2^(N+W))
00136  *
00137  *      BPred2bit:  a simple direct mapped bimodal predictor
00138  *
00139  *              This predictor has a table of two bit saturating counters.
00140  *              Where counter states 0 & 1 are predict not taken and
00141  *              counter states 2 & 3 are predict taken, the per-branch counters
00142  *              are incremented on taken branches and decremented on
00143  *              no taken branches.  One BTB entry per counter.
00144  *
00145  *      BPredTaken:  static predict branch taken
00146  *
00147  *      BPredNotTaken:  static predict branch not taken
00148  *
00149  */
00150 
00151 /* branch predictor types */
00152 enum bpred_class {
00153   BPredComb,                    /* combined predictor (McFarling) */
00154   BPred2Level,                  /* 2-level correlating pred w/2-bit counters */
00155   BPred2bit,                    /* 2-bit saturating cntr pred (dir mapped) */
00156   BPredTaken,                   /* static predict taken */
00157   BPredNotTaken,                /* static predict not taken */
00158   BPred_NUM
00159 };
00160 
00161 /* an entry in a BTB */
00162 struct bpred_btb_ent_t {
00163   md_addr_t addr;               /* address of branch being tracked */
00164   enum md_opcode op;            /* opcode of branch corresp. to addr */
00165   md_addr_t target;             /* last destination of branch when taken */
00166   struct bpred_btb_ent_t *prev, *next; /* lru chaining pointers */
00167 };
00168 
00169 /* direction predictor def */
00170 struct bpred_dir_t {
00171   enum bpred_class class;       /* type of predictor */
00172   union {
00173     struct {
00174       unsigned int size;        /* number of entries in direct-mapped table */
00175       unsigned char *table;     /* prediction state table */
00176     } bimod;
00177     struct {
00178       int l1size;               /* level-1 size, number of history regs */
00179       int l2size;               /* level-2 size, number of pred states */
00180       int shift_width;          /* amount of history in level-1 shift regs */
00181       int xor;                  /* history xor address flag */
00182       int *shiftregs;           /* level-1 history table */
00183       unsigned char *l2table;   /* level-2 prediction state table */
00184     } two;
00185   } config;
00186 };
00187 
00188 /* branch predictor def */
00189 struct bpred_t {
00190   enum bpred_class class;       /* type of predictor */
00191   struct {
00192     struct bpred_dir_t *bimod;    /* first direction predictor */
00193     struct bpred_dir_t *twolev;   /* second direction predictor */
00194     struct bpred_dir_t *meta;     /* meta predictor */
00195   } dirpred;
00196 
00197   struct {
00198     int sets;                   /* num BTB sets */
00199     int assoc;                  /* BTB associativity */
00200     struct bpred_btb_ent_t *btb_data; /* BTB addr-prediction table */
00201   } btb;
00202 
00203   struct {
00204     int size;                   /* return-address stack size */
00205     int tos;                    /* top-of-stack */
00206     struct bpred_btb_ent_t *stack; /* return-address stack */
00207   } retstack;
00208 
00209   /* stats */
00210   counter_t addr_hits;          /* num correct addr-predictions */
00211   counter_t dir_hits;           /* num correct dir-predictions (incl addr) */
00212   counter_t used_ras;           /* num RAS predictions used */
00213   counter_t used_bimod;         /* num bimodal predictions used (BPredComb) */
00214   counter_t used_2lev;          /* num 2-level predictions used (BPredComb) */
00215   counter_t jr_hits;            /* num correct addr-predictions for JR's */
00216   counter_t jr_seen;            /* num JR's seen */
00217   counter_t jr_non_ras_hits;    /* num correct addr-preds for non-RAS JR's */
00218   counter_t jr_non_ras_seen;    /* num non-RAS JR's seen */
00219   counter_t misses;             /* num incorrect predictions */
00220 
00221   counter_t lookups;            /* num lookups */
00222   counter_t retstack_pops;      /* number of times a value was popped */
00223   counter_t retstack_pushes;    /* number of times a value was pushed */
00224   counter_t ras_hits;           /* num correct return-address predictions */
00225 };
00226 
00227 /* branch predictor update information */
00228 struct bpred_update_t {
00229   char *pdir1;          /* direction-1 predictor counter */
00230   char *pdir2;          /* direction-2 predictor counter */
00231   char *pmeta;          /* meta predictor counter */
00232   struct {              /* predicted directions */
00233     unsigned int ras    : 1;    /* RAS used */
00234     unsigned int bimod  : 1;    /* bimodal predictor */
00235     unsigned int twolev : 1;    /* 2-level predictor */
00236     unsigned int meta   : 1;    /* meta predictor (0..bimod / 1..2lev) */
00237   } dir;
00238 };
00239 
00240 /* create a branch predictor */
00241 struct bpred_t *                        /* branch predictory instance */
00242 bpred_create(enum bpred_class class,    /* type of predictor to create */
00243              unsigned int bimod_size,   /* bimod table size */
00244              unsigned int l1size,       /* level-1 table size */
00245              unsigned int l2size,       /* level-2 table size */
00246              unsigned int meta_size,    /* meta predictor table size */
00247              unsigned int shift_width,  /* history register width */
00248              unsigned int xor,          /* history xor address flag */
00249              unsigned int btb_sets,     /* number of sets in BTB */ 
00250              unsigned int btb_assoc,    /* BTB associativity */
00251              unsigned int retstack_size);/* num entries in ret-addr stack */
00252 
00253 /* create a branch direction predictor */
00254 struct bpred_dir_t *            /* branch direction predictor instance */
00255 bpred_dir_create (
00256   enum bpred_class class,       /* type of predictor to create */
00257   unsigned int l1size,          /* level-1 table size */
00258   unsigned int l2size,          /* level-2 table size (if relevant) */
00259   unsigned int shift_width,     /* history register width */
00260   unsigned int xor);            /* history xor address flag */
00261 
00262 /* print branch predictor configuration */
00263 void
00264 bpred_config(struct bpred_t *pred,      /* branch predictor instance */
00265              FILE *stream);             /* output stream */
00266 
00267 /* print predictor stats */
00268 void
00269 bpred_stats(struct bpred_t *pred,       /* branch predictor instance */
00270             FILE *stream);              /* output stream */
00271 
00272 /* register branch predictor stats */
00273 void
00274 bpred_reg_stats(struct bpred_t *pred,   /* branch predictor instance */
00275                 struct stat_sdb_t *sdb);/* stats database */
00276 
00277 /* reset stats after priming, if appropriate */
00278 void bpred_after_priming(struct bpred_t *bpred);
00279 
00280 /* probe a predictor for a next fetch address, the predictor is probed
00281    with branch address BADDR, the branch target is BTARGET (used for
00282    static predictors), and OP is the instruction opcode (used to simulate
00283    predecode bits; a pointer to the predictor state entry (or null for jumps)
00284    is returned in *DIR_UPDATE_PTR (used for updating predictor state),
00285    and the non-speculative top-of-stack is returned in stack_recover_idx 
00286    (used for recovering ret-addr stack after mis-predict).  */
00287 md_addr_t                               /* predicted branch target addr */
00288 bpred_lookup(struct bpred_t *pred,      /* branch predictor instance */
00289              md_addr_t baddr,           /* branch address */
00290              md_addr_t btarget,         /* branch target if taken */
00291              enum md_opcode op,         /* opcode of instruction */
00292              int is_call,               /* non-zero if inst is fn call */
00293              int is_return,             /* non-zero if inst is fn return */
00294              struct bpred_update_t *dir_update_ptr, /* pred state pointer */
00295              int *stack_recover_idx);   /* Non-speculative top-of-stack;
00296                                          * used on mispredict recovery */
00297 
00298 /* Speculative execution can corrupt the ret-addr stack.  So for each
00299  * lookup we return the top-of-stack (TOS) at that point; a mispredicted
00300  * branch, as part of its recovery, restores the TOS using this value --
00301  * hopefully this uncorrupts the stack. */
00302 void
00303 bpred_recover(struct bpred_t *pred,     /* branch predictor instance */
00304               md_addr_t baddr,          /* branch address */
00305               int stack_recover_idx);   /* Non-speculative top-of-stack;
00306                                          * used on mispredict recovery */
00307 
00308 /* update the branch predictor, only useful for stateful predictors; updates
00309    entry for instruction type OP at address BADDR.  BTB only gets updated
00310    for branches which are taken.  Inst was determined to jump to
00311    address BTARGET and was taken if TAKEN is non-zero.  Predictor 
00312    statistics are updated with result of prediction, indicated by CORRECT and 
00313    PRED_TAKEN, predictor state to be updated is indicated by *DIR_UPDATE_PTR 
00314    (may be NULL for jumps, which shouldn't modify state bits).  Note if
00315    bpred_update is done speculatively, branch-prediction may get polluted. */
00316 void
00317 bpred_update(struct bpred_t *pred,      /* branch predictor instance */
00318              md_addr_t baddr,           /* branch address */
00319              md_addr_t btarget,         /* resolved branch target */
00320              int taken,                 /* non-zero if branch was taken */
00321              int pred_taken,            /* non-zero if branch was pred taken */
00322              int correct,               /* was earlier prediction correct? */
00323              enum md_opcode op,         /* opcode of instruction */
00324              struct bpred_update_t *dir_update_ptr); /* pred state pointer */
00325 
00326 
00327 #ifdef foo0
00328 /* OBSOLETE */
00329 /* dump branch predictor state (for debug) */
00330 void
00331 bpred_dump(struct bpred_t *pred,        /* branch predictor instance */
00332            FILE *stream);               /* output stream */
00333 #endif
00334 
00335 #endif /* BPRED_H */


UVa CS Department of Computer Science
School of Engineering, University of Virginia
151 Engineer's Way, P.O. Box 400740
Charlottesville, Virginia 22904-4740

(434) 982-2200  Fax: (434) 982-2214