bpred_unit.hh revision 2292
16313Sgblack@eecs.umich.edu/*
26313Sgblack@eecs.umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan
36313Sgblack@eecs.umich.edu * All rights reserved.
46313Sgblack@eecs.umich.edu *
56313Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
66313Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
76313Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
86313Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
96313Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
106313Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
116313Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
126313Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
136313Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
146313Sgblack@eecs.umich.edu * this software without specific prior written permission.
156313Sgblack@eecs.umich.edu *
166313Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176313Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186313Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196313Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206313Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216313Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226313Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236313Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246313Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256313Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266313Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276313Sgblack@eecs.umich.edu */
286313Sgblack@eecs.umich.edu
296313Sgblack@eecs.umich.edu#ifndef __CPU_O3_BPRED_UNIT_HH__
306313Sgblack@eecs.umich.edu#define __CPU_O3_BPRED_UNIT_HH__
316313Sgblack@eecs.umich.edu
326313Sgblack@eecs.umich.edu// For Addr type.
336313Sgblack@eecs.umich.edu#include "arch/isa_traits.hh"
346334Sgblack@eecs.umich.edu#include "base/statistics.hh"
356334Sgblack@eecs.umich.edu#include "cpu/inst_seq.hh"
366334Sgblack@eecs.umich.edu
376334Sgblack@eecs.umich.edu#include "cpu/o3/2bit_local_pred.hh"
386334Sgblack@eecs.umich.edu#include "cpu/o3/btb.hh"
396313Sgblack@eecs.umich.edu#include "cpu/o3/ras.hh"
406334Sgblack@eecs.umich.edu#include "cpu/o3/tournament_pred.hh"
417878Sgblack@eecs.umich.edu
426313Sgblack@eecs.umich.edu#include <list>
436334Sgblack@eecs.umich.edu
446313Sgblack@eecs.umich.edu/**
456313Sgblack@eecs.umich.edu * Basically a wrapper class to hold both the branch predictor
466334Sgblack@eecs.umich.edu * and the BTB.  Right now I'm unsure of the implementation; it would
476313Sgblack@eecs.umich.edu * be nicer to have something closer to the CPUPolicy or the Impl where
486313Sgblack@eecs.umich.edu * this is just typedefs, but it forces the upper level stages to be
496313Sgblack@eecs.umich.edu * aware of the constructors of the BP and the BTB.  The nicer thing
506313Sgblack@eecs.umich.edu * to do is have this templated on the Impl, accept the usual Params
516313Sgblack@eecs.umich.edu * object, and be able to call the constructors on the BP and BTB.
526334Sgblack@eecs.umich.edu */
536334Sgblack@eecs.umich.edutemplate<class Impl>
546334Sgblack@eecs.umich.educlass TwobitBPredUnit
556334Sgblack@eecs.umich.edu{
566313Sgblack@eecs.umich.edu  public:
578181Sksewell@umich.edu    typedef typename Impl::Params Params;
588181Sksewell@umich.edu    typedef typename Impl::DynInstPtr DynInstPtr;
598181Sksewell@umich.edu
608181Sksewell@umich.edu    /**
616334Sgblack@eecs.umich.edu     * @param params The params object, that has the size of the BP and BTB.
626334Sgblack@eecs.umich.edu     */
636334Sgblack@eecs.umich.edu    TwobitBPredUnit(Params *params);
646334Sgblack@eecs.umich.edu
656334Sgblack@eecs.umich.edu    /**
666334Sgblack@eecs.umich.edu     * Registers statistics.
676334Sgblack@eecs.umich.edu     */
686334Sgblack@eecs.umich.edu    void regStats();
696334Sgblack@eecs.umich.edu
706334Sgblack@eecs.umich.edu    /**
716313Sgblack@eecs.umich.edu     * Predicts whether or not the instruction is a taken branch, and the
728181Sksewell@umich.edu     * target of the branch if it is taken.
736313Sgblack@eecs.umich.edu     * @param inst The branch instruction.
748181Sksewell@umich.edu     * @param PC The predicted PC is passed back through this parameter.
756334Sgblack@eecs.umich.edu     * @param tid The thread id.
768181Sksewell@umich.edu     * @return Returns if the branch is taken or not.
776334Sgblack@eecs.umich.edu     */
786334Sgblack@eecs.umich.edu    bool predict(DynInstPtr &inst, Addr &PC, unsigned tid);
796334Sgblack@eecs.umich.edu
806334Sgblack@eecs.umich.edu    /**
816334Sgblack@eecs.umich.edu     * Tells the branch predictor to commit any updates until the given
826334Sgblack@eecs.umich.edu     * sequence number.
836334Sgblack@eecs.umich.edu     * @param done_sn The sequence number to commit any older updates up until.
846334Sgblack@eecs.umich.edu     * @param tid The thread id.
856334Sgblack@eecs.umich.edu     */
866334Sgblack@eecs.umich.edu    void update(const InstSeqNum &done_sn, unsigned tid);
876334Sgblack@eecs.umich.edu
886334Sgblack@eecs.umich.edu    /**
896334Sgblack@eecs.umich.edu     * Squashes all outstanding updates until a given sequence number.
906334Sgblack@eecs.umich.edu     * @param squashed_sn The sequence number to squash any younger updates up
916334Sgblack@eecs.umich.edu     * until.
926334Sgblack@eecs.umich.edu     * @param tid The thread id.
936334Sgblack@eecs.umich.edu     */
946334Sgblack@eecs.umich.edu    void squash(const InstSeqNum &squashed_sn, unsigned tid);
956334Sgblack@eecs.umich.edu
966334Sgblack@eecs.umich.edu    /**
976334Sgblack@eecs.umich.edu     * Squashes all outstanding updates until a given sequence number, and
986334Sgblack@eecs.umich.edu     * corrects that sn's update with the proper address and taken/not taken.
996334Sgblack@eecs.umich.edu     * @param squashed_sn The sequence number to squash any younger updates up
1006334Sgblack@eecs.umich.edu     * until.
1016334Sgblack@eecs.umich.edu     * @param corr_target The correct branch target.
1026334Sgblack@eecs.umich.edu     * @param actually_taken The correct branch direction.
1036334Sgblack@eecs.umich.edu     * @param tid The thread id.
1046334Sgblack@eecs.umich.edu     */
1056334Sgblack@eecs.umich.edu    void squash(const InstSeqNum &squashed_sn, const Addr &corr_target,
1066334Sgblack@eecs.umich.edu                bool actually_taken, unsigned tid);
1076334Sgblack@eecs.umich.edu
1086334Sgblack@eecs.umich.edu    /**
1096334Sgblack@eecs.umich.edu     * Looks up a given PC in the BP to see if it is taken or not taken.
1106334Sgblack@eecs.umich.edu     * @param inst_PC The PC to look up.
1116334Sgblack@eecs.umich.edu     * @return Whether the branch is taken or not taken.
1126334Sgblack@eecs.umich.edu     */
1136334Sgblack@eecs.umich.edu    bool BPLookup(Addr &inst_PC)
1146334Sgblack@eecs.umich.edu    { return BP.lookup(inst_PC); }
1156334Sgblack@eecs.umich.edu
1166334Sgblack@eecs.umich.edu    /**
1176334Sgblack@eecs.umich.edu     * Looks up a given PC in the BTB to see if a matching entry exists.
1186334Sgblack@eecs.umich.edu     * @param inst_PC The PC to look up.
1196334Sgblack@eecs.umich.edu     * @return Whether the BTB contains the given PC.
1206334Sgblack@eecs.umich.edu     */
1216313Sgblack@eecs.umich.edu    bool BTBValid(Addr &inst_PC)
1226334Sgblack@eecs.umich.edu    { return BTB.valid(inst_PC, 0); }
1236334Sgblack@eecs.umich.edu
1246334Sgblack@eecs.umich.edu    /**
1256334Sgblack@eecs.umich.edu     * Looks up a given PC in the BTB to get the predicted target.
1266334Sgblack@eecs.umich.edu     * @param inst_PC The PC to look up.
1276313Sgblack@eecs.umich.edu     * @return The address of the target of the branch.
1286334Sgblack@eecs.umich.edu     */
1296334Sgblack@eecs.umich.edu    Addr BTBLookup(Addr &inst_PC)
1306334Sgblack@eecs.umich.edu    { return BTB.lookup(inst_PC, 0); }
1316313Sgblack@eecs.umich.edu
1326334Sgblack@eecs.umich.edu    /**
1336334Sgblack@eecs.umich.edu     * Updates the BP with taken/not taken information.
1346313Sgblack@eecs.umich.edu     * @param inst_PC The branch's PC that will be updated.
1356334Sgblack@eecs.umich.edu     * @param taken Whether the branch was taken or not taken.
1366334Sgblack@eecs.umich.edu     * @todo Make this update flexible enough to handle a global predictor.
1376334Sgblack@eecs.umich.edu     */
1386334Sgblack@eecs.umich.edu    void BPUpdate(Addr &inst_PC, bool taken)
1396334Sgblack@eecs.umich.edu    { BP.update(inst_PC, taken); }
1406334Sgblack@eecs.umich.edu
1416334Sgblack@eecs.umich.edu    /**
1426334Sgblack@eecs.umich.edu     * Updates the BTB with the target of a branch.
1436334Sgblack@eecs.umich.edu     * @param inst_PC The branch's PC that will be updated.
1446334Sgblack@eecs.umich.edu     * @param target_PC The branch's target that will be added to the BTB.
1456334Sgblack@eecs.umich.edu     */
1466806Sgblack@eecs.umich.edu    void BTBUpdate(Addr &inst_PC, Addr &target_PC)
1476334Sgblack@eecs.umich.edu    { BTB.update(inst_PC, target_PC,0); }
1486334Sgblack@eecs.umich.edu
1496334Sgblack@eecs.umich.edu  private:
1506806Sgblack@eecs.umich.edu    struct PredictorHistory {
1516334Sgblack@eecs.umich.edu        /**
1526334Sgblack@eecs.umich.edu         * Makes a predictor history struct that contains a sequence number,
1536334Sgblack@eecs.umich.edu         * the PC of its instruction, and whether or not it was predicted
1546334Sgblack@eecs.umich.edu         * taken.
1556334Sgblack@eecs.umich.edu         */
1566334Sgblack@eecs.umich.edu        PredictorHistory(const InstSeqNum &seq_num, const Addr &inst_PC,
1576334Sgblack@eecs.umich.edu                         const bool pred_taken, const unsigned _tid)
1586313Sgblack@eecs.umich.edu            : seqNum(seq_num), PC(inst_PC), RASTarget(0), globalHistory(0),
1596313Sgblack@eecs.umich.edu              RASIndex(0), tid(_tid), predTaken(pred_taken), usedRAS(0),
1606313Sgblack@eecs.umich.edu              wasCall(0)
1616313Sgblack@eecs.umich.edu        { }
1626313Sgblack@eecs.umich.edu
1636313Sgblack@eecs.umich.edu        /** The sequence number for the predictor history entry. */
1646313Sgblack@eecs.umich.edu        InstSeqNum seqNum;
1656313Sgblack@eecs.umich.edu
1666313Sgblack@eecs.umich.edu        /** The PC associated with the sequence number. */
1676313Sgblack@eecs.umich.edu        Addr PC;
1686313Sgblack@eecs.umich.edu
1696313Sgblack@eecs.umich.edu        /** The RAS target (only valid if a return). */
1706313Sgblack@eecs.umich.edu        Addr RASTarget;
1716678Sgblack@eecs.umich.edu
1726678Sgblack@eecs.umich.edu        /** The global history at the time this entry was created. */
1736678Sgblack@eecs.umich.edu        unsigned globalHistory;
1746678Sgblack@eecs.umich.edu
1756678Sgblack@eecs.umich.edu        /** The RAS index of the instruction (only valid if a call). */
1766313Sgblack@eecs.umich.edu        unsigned RASIndex;
1776313Sgblack@eecs.umich.edu
1786313Sgblack@eecs.umich.edu        /** The thread id. */
1796313Sgblack@eecs.umich.edu        unsigned tid;
180
181        /** Whether or not it was predicted taken. */
182        bool predTaken;
183
184        /** Whether or not the RAS was used. */
185        bool usedRAS;
186
187        /** Whether or not the instruction was a call. */
188        bool wasCall;
189    };
190
191    typedef std::list<PredictorHistory> History;
192
193    /**
194     * The per-thread predictor history. This is used to update the predictor
195     * as instructions are committed, or restore it to the proper state after
196     * a squash.
197     */
198    History predHist[Impl::MaxThreads];
199
200    /** The branch predictor. */
201    DefaultBP BP;
202
203    /** The BTB. */
204    DefaultBTB BTB;
205
206    /** The per-thread return address stack. */
207    ReturnAddrStack RAS[Impl::MaxThreads];
208
209    /** Stat for number of BP lookups. */
210    Stats::Scalar<> lookups;
211    /** Stat for number of conditional branches predicted. */
212    Stats::Scalar<> condPredicted;
213    /** Stat for number of conditional branches predicted incorrectly. */
214    Stats::Scalar<> condIncorrect;
215    /** Stat for number of BTB lookups. */
216    Stats::Scalar<> BTBLookups;
217    /** Stat for number of BTB hits. */
218    Stats::Scalar<> BTBHits;
219    /** Stat for number of times the BTB is correct. */
220    Stats::Scalar<> BTBCorrect;
221    /** Stat for number of times the RAS is used to get a target. */
222    Stats::Scalar<> usedRAS;
223    /** Stat for number of times the RAS is incorrect. */
224    Stats::Scalar<> RASIncorrect;
225};
226
227#endif // __CPU_O3_BPRED_UNIT_HH__
228