bpred_unit.hh revision 6216
18706Sandreas.hansson@arm.com/*
28706Sandreas.hansson@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan
38706Sandreas.hansson@arm.com * All rights reserved.
48706Sandreas.hansson@arm.com *
58706Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68706Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
78706Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
88706Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
98706Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
108706Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
118706Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
128706Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
136892SBrad.Beckmann@amd.com * contributors may be used to endorse or promote products derived from
146892SBrad.Beckmann@amd.com * this software without specific prior written permission.
156892SBrad.Beckmann@amd.com *
166892SBrad.Beckmann@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176892SBrad.Beckmann@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186892SBrad.Beckmann@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196892SBrad.Beckmann@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206892SBrad.Beckmann@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216892SBrad.Beckmann@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226892SBrad.Beckmann@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236892SBrad.Beckmann@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246892SBrad.Beckmann@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256892SBrad.Beckmann@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266892SBrad.Beckmann@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276892SBrad.Beckmann@amd.com *
286892SBrad.Beckmann@amd.com * Authors: Kevin Lim
296892SBrad.Beckmann@amd.com */
306892SBrad.Beckmann@amd.com
316892SBrad.Beckmann@amd.com#ifndef __CPU_O3_BPRED_UNIT_HH__
326892SBrad.Beckmann@amd.com#define __CPU_O3_BPRED_UNIT_HH__
336892SBrad.Beckmann@amd.com
346892SBrad.Beckmann@amd.com#include <list>
356892SBrad.Beckmann@amd.com
366892SBrad.Beckmann@amd.com#include "base/statistics.hh"
376892SBrad.Beckmann@amd.com#include "base/types.hh"
386892SBrad.Beckmann@amd.com#include "cpu/inst_seq.hh"
396892SBrad.Beckmann@amd.com#include "cpu/o3/2bit_local_pred.hh"
406892SBrad.Beckmann@amd.com#include "cpu/o3/btb.hh"
416892SBrad.Beckmann@amd.com#include "cpu/o3/ras.hh"
427563SBrad.Beckmann@amd.com#include "cpu/o3/tournament_pred.hh"
436892SBrad.Beckmann@amd.com
446892SBrad.Beckmann@amd.comclass DerivO3CPUParams;
456892SBrad.Beckmann@amd.com
466892SBrad.Beckmann@amd.com/**
477538SBrad.Beckmann@amd.com * Basically a wrapper class to hold both the branch predictor
488939SBrad.Beckmann@amd.com * and the BTB.
498939SBrad.Beckmann@amd.com */
508939SBrad.Beckmann@amd.comtemplate<class Impl>
517538SBrad.Beckmann@amd.comclass BPredUnit
527538SBrad.Beckmann@amd.com{
537538SBrad.Beckmann@amd.com  private:
547538SBrad.Beckmann@amd.com    typedef typename Impl::DynInstPtr DynInstPtr;
557538SBrad.Beckmann@amd.com
567661Snate@binkert.org    enum PredType {
577538SBrad.Beckmann@amd.com        Local,
588612Stushar@csail.mit.edu        Tournament
598612Stushar@csail.mit.edu    };
607538SBrad.Beckmann@amd.com
617538SBrad.Beckmann@amd.com    PredType predictor;
627917SBrad.Beckmann@amd.com
637563SBrad.Beckmann@amd.com    const std::string _name;
647563SBrad.Beckmann@amd.com
657538SBrad.Beckmann@amd.com  public:
667538SBrad.Beckmann@amd.com
677538SBrad.Beckmann@amd.com    /**
687538SBrad.Beckmann@amd.com     * @param params The params object, that has the size of the BP and BTB.
697538SBrad.Beckmann@amd.com     */
707566SBrad.Beckmann@amd.com    BPredUnit(DerivO3CPUParams *params);
717566SBrad.Beckmann@amd.com
727809Snilay@cs.wisc.edu    const std::string &name() const { return _name; }
737809Snilay@cs.wisc.edu
747809Snilay@cs.wisc.edu    /**
757809Snilay@cs.wisc.edu     * Registers statistics.
768638Sgloh     */
778638Sgloh    void regStats();
787538SBrad.Beckmann@amd.com
797538SBrad.Beckmann@amd.com    void switchOut();
807538SBrad.Beckmann@amd.com
817538SBrad.Beckmann@amd.com    void takeOverFrom();
829100SBrad.Beckmann@amd.com
839100SBrad.Beckmann@amd.com    /**
849100SBrad.Beckmann@amd.com     * Predicts whether or not the instruction is a taken branch, and the
859100SBrad.Beckmann@amd.com     * target of the branch if it is taken.
869100SBrad.Beckmann@amd.com     * @param inst The branch instruction.
879100SBrad.Beckmann@amd.com     * @param PC The predicted PC is passed back through this parameter.
889100SBrad.Beckmann@amd.com     * @param tid The thread id.
899100SBrad.Beckmann@amd.com     * @return Returns if the branch is taken or not.
909100SBrad.Beckmann@amd.com     */
919100SBrad.Beckmann@amd.com    bool predict(DynInstPtr &inst, Addr &PC, unsigned tid);
928929Snilay@cs.wisc.edu
936892SBrad.Beckmann@amd.com    // @todo: Rename this function.
948638Sgloh    void BPUncond(void * &bp_history);
958690Snilay@cs.wisc.edu
968690Snilay@cs.wisc.edu    /**
978436SBrad.Beckmann@amd.com     * Tells the branch predictor to commit any updates until the given
988436SBrad.Beckmann@amd.com     * sequence number.
997032SBrad.Beckmann@amd.com     * @param done_sn The sequence number to commit any older updates up until.
1007032SBrad.Beckmann@amd.com     * @param tid The thread id.
1016923SBrad.Beckmann@amd.com     */
1029100SBrad.Beckmann@amd.com    void update(const InstSeqNum &done_sn, unsigned tid);
1038929Snilay@cs.wisc.edu
1047557SBrad.Beckmann@amd.com    /**
1056923SBrad.Beckmann@amd.com     * Squashes all outstanding updates until a given sequence number.
1066923SBrad.Beckmann@amd.com     * @param squashed_sn The sequence number to squash any younger updates up
1077557SBrad.Beckmann@amd.com     * until.
1088257SBrad.Beckmann@amd.com     * @param tid The thread id.
1098706Sandreas.hansson@arm.com     */
1108706Sandreas.hansson@arm.com    void squash(const InstSeqNum &squashed_sn, unsigned tid);
1118706Sandreas.hansson@arm.com
1128923Sandreas.hansson@arm.com    /**
1138706Sandreas.hansson@arm.com     * Squashes all outstanding updates until a given sequence number, and
1148706Sandreas.hansson@arm.com     * corrects that sn's update with the proper address and taken/not taken.
1158706Sandreas.hansson@arm.com     * @param squashed_sn The sequence number to squash any younger updates up
1168706Sandreas.hansson@arm.com     * until.
1178732Sandreas.hansson@arm.com     * @param corr_target The correct branch target.
1188839Sandreas.hansson@arm.com     * @param actually_taken The correct branch direction.
1198732Sandreas.hansson@arm.com     * @param tid The thread id.
1208732Sandreas.hansson@arm.com     */
1218257SBrad.Beckmann@amd.com    void squash(const InstSeqNum &squashed_sn, const Addr &corr_target,
1228257SBrad.Beckmann@amd.com                bool actually_taken, unsigned tid);
1238257SBrad.Beckmann@amd.com
1248257SBrad.Beckmann@amd.com    /**
1258257SBrad.Beckmann@amd.com     * @param bp_history Pointer to the history object.  The predictor
1268257SBrad.Beckmann@amd.com     * will need to update any state and delete the object.
1278257SBrad.Beckmann@amd.com     */
1288257SBrad.Beckmann@amd.com    void BPSquash(void *bp_history);
1298257SBrad.Beckmann@amd.com
1308257SBrad.Beckmann@amd.com    /**
1318257SBrad.Beckmann@amd.com     * Looks up a given PC in the BP to see if it is taken or not taken.
1328257SBrad.Beckmann@amd.com     * @param inst_PC The PC to look up.
1338257SBrad.Beckmann@amd.com     * @param bp_history Pointer that will be set to an object that
1348257SBrad.Beckmann@amd.com     * has the branch predictor state associated with the lookup.
1358257SBrad.Beckmann@amd.com     * @return Whether the branch is taken or not taken.
1368258SBrad.Beckmann@amd.com     */
1378258SBrad.Beckmann@amd.com    bool BPLookup(Addr &inst_PC, void * &bp_history);
1388257SBrad.Beckmann@amd.com
1399148Spowerjg@cs.wisc.edu    /**
1406892SBrad.Beckmann@amd.com     * Looks up a given PC in the BTB to see if a matching entry exists.
1419100SBrad.Beckmann@amd.com     * @param inst_PC The PC to look up.
1429100SBrad.Beckmann@amd.com     * @return Whether the BTB contains the given PC.
1439148Spowerjg@cs.wisc.edu     */
1446892SBrad.Beckmann@amd.com    bool BTBValid(Addr &inst_PC)
1459148Spowerjg@cs.wisc.edu    { return BTB.valid(inst_PC, 0); }
1469148Spowerjg@cs.wisc.edu
1479148Spowerjg@cs.wisc.edu    /**
1489148Spowerjg@cs.wisc.edu     * Looks up a given PC in the BTB to get the predicted target.
1499148Spowerjg@cs.wisc.edu     * @param inst_PC The PC to look up.
1509148Spowerjg@cs.wisc.edu     * @return The address of the target of the branch.
1519148Spowerjg@cs.wisc.edu     */
1529148Spowerjg@cs.wisc.edu    Addr BTBLookup(Addr &inst_PC)
1539148Spowerjg@cs.wisc.edu    { return BTB.lookup(inst_PC, 0); }
1549148Spowerjg@cs.wisc.edu
1559148Spowerjg@cs.wisc.edu    /**
1568257SBrad.Beckmann@amd.com     * Updates the BP with taken/not taken information.
1578612Stushar@csail.mit.edu     * @param inst_PC The branch's PC that will be updated.
1588612Stushar@csail.mit.edu     * @param taken Whether the branch was taken or not taken.
1598612Stushar@csail.mit.edu     * @param bp_history Pointer to the branch predictor state that is
1608612Stushar@csail.mit.edu     * associated with the branch lookup that is being updated.
1618612Stushar@csail.mit.edu     * @todo Make this update flexible enough to handle a global predictor.
1628612Stushar@csail.mit.edu     */
1638612Stushar@csail.mit.edu    void BPUpdate(Addr &inst_PC, bool taken, void *bp_history);
1646892SBrad.Beckmann@amd.com
1656903SBrad.Beckmann@amd.com    /**
1667563SBrad.Beckmann@amd.com     * Updates the BTB with the target of a branch.
1677025SBrad.Beckmann@amd.com     * @param inst_PC The branch's PC that will be updated.
1689148Spowerjg@cs.wisc.edu     * @param target_PC The branch's target that will be added to the BTB.
1697025SBrad.Beckmann@amd.com     */
1707025SBrad.Beckmann@amd.com    void BTBUpdate(Addr &inst_PC, Addr &target_PC)
1717563SBrad.Beckmann@amd.com    { BTB.update(inst_PC, target_PC,0); }
1726903SBrad.Beckmann@amd.com
1736903SBrad.Beckmann@amd.com    void dump();
1747563SBrad.Beckmann@amd.com
1757563SBrad.Beckmann@amd.com  private:
1767563SBrad.Beckmann@amd.com    struct PredictorHistory {
1777563SBrad.Beckmann@amd.com        /**
1787563SBrad.Beckmann@amd.com         * Makes a predictor history struct that contains any
1797563SBrad.Beckmann@amd.com         * information needed to update the predictor, BTB, and RAS.
1807563SBrad.Beckmann@amd.com         */
1817663SBrad.Beckmann@amd.com        PredictorHistory(const InstSeqNum &seq_num, const Addr &inst_PC,
1827663SBrad.Beckmann@amd.com                         const bool pred_taken, void *bp_history,
1837663SBrad.Beckmann@amd.com                         const unsigned _tid)
1847663SBrad.Beckmann@amd.com            : seqNum(seq_num), PC(inst_PC), RASTarget(0),
1857663SBrad.Beckmann@amd.com              RASIndex(0), tid(_tid), predTaken(pred_taken), usedRAS(0),
1869148Spowerjg@cs.wisc.edu              wasCall(0), bpHistory(bp_history)
1876903SBrad.Beckmann@amd.com        { }
1886903SBrad.Beckmann@amd.com
1897563SBrad.Beckmann@amd.com        bool operator==(const PredictorHistory &entry) const {
1909148Spowerjg@cs.wisc.edu            return this->seqNum == entry.seqNum;
1919232Sandreas.hansson@arm.com        }
1929232Sandreas.hansson@arm.com
1938931Sandreas.hansson@arm.com        /** The sequence number for the predictor history entry. */
1946892SBrad.Beckmann@amd.com        InstSeqNum seqNum;
1958436SBrad.Beckmann@amd.com
1968436SBrad.Beckmann@amd.com        /** The PC associated with the sequence number. */
1978436SBrad.Beckmann@amd.com        Addr PC;
1988436SBrad.Beckmann@amd.com
1998436SBrad.Beckmann@amd.com        /** The RAS target (only valid if a return). */
2008322Ssteve.reinhardt@amd.com        Addr RASTarget;
2017809Snilay@cs.wisc.edu
202        /** The RAS index of the instruction (only valid if a call). */
203        unsigned RASIndex;
204
205        /** The thread id. */
206        unsigned tid;
207
208        /** Whether or not it was predicted taken. */
209        bool predTaken;
210
211        /** Whether or not the RAS was used. */
212        bool usedRAS;
213
214        /** Whether or not the instruction was a call. */
215        bool wasCall;
216
217        /** Pointer to the history object passed back from the branch
218         * predictor.  It is used to update or restore state of the
219         * branch predictor.
220         */
221        void *bpHistory;
222    };
223
224    typedef std::list<PredictorHistory> History;
225    typedef typename History::iterator HistoryIt;
226
227    /**
228     * The per-thread predictor history. This is used to update the predictor
229     * as instructions are committed, or restore it to the proper state after
230     * a squash.
231     */
232    History predHist[Impl::MaxThreads];
233
234    /** The local branch predictor. */
235    LocalBP *localBP;
236
237    /** The tournament branch predictor. */
238    TournamentBP *tournamentBP;
239
240    /** The BTB. */
241    DefaultBTB BTB;
242
243    /** The per-thread return address stack. */
244    ReturnAddrStack RAS[Impl::MaxThreads];
245
246    /** Stat for number of BP lookups. */
247    Stats::Scalar lookups;
248    /** Stat for number of conditional branches predicted. */
249    Stats::Scalar condPredicted;
250    /** Stat for number of conditional branches predicted incorrectly. */
251    Stats::Scalar condIncorrect;
252    /** Stat for number of BTB lookups. */
253    Stats::Scalar BTBLookups;
254    /** Stat for number of BTB hits. */
255    Stats::Scalar BTBHits;
256    /** Stat for number of times the BTB is correct. */
257    Stats::Scalar BTBCorrect;
258    /** Stat for number of times the RAS is used to get a target. */
259    Stats::Scalar usedRAS;
260    /** Stat for number of times the RAS is incorrect. */
261    Stats::Scalar RASIncorrect;
262};
263
264#endif // __CPU_O3_BPRED_UNIT_HH__
265