/* * Copyright 2019 Texas A&M University * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Author: Daniel A. Jiménez * Adapted to gem5 by: Javier Bueno Hedo * */ /* * Multiperspective Perceptron Predictor with TAGE (by Daniel A. Jiménez) */ #ifndef __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_TAGE_HH__ #define __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_TAGE_HH__ #include "cpu/pred/loop_predictor.hh" #include "cpu/pred/multiperspective_perceptron.hh" #include "cpu/pred/statistical_corrector.hh" #include "cpu/pred/tage_base.hh" #include "params/MPP_LoopPredictor.hh" #include "params/MPP_StatisticalCorrector.hh" #include "params/MPP_TAGE.hh" #include "params/MultiperspectivePerceptronTAGE.hh" class MPP_TAGE : public TAGEBase { std::vector tunedHistoryLengths; public: struct BranchInfo : public TAGEBase::BranchInfo { BranchInfo(TAGEBase &tage) : TAGEBase::BranchInfo(tage) {} virtual ~BranchInfo() {} }; MPP_TAGE(const MPP_TAGEParams *p) : TAGEBase(p), tunedHistoryLengths(p->tunedHistoryLengths) {} void calculateParameters() override; void handleTAGEUpdate(Addr branch_pc, bool taken, TAGEBase::BranchInfo* bi) override; void handleAllocAndUReset(bool alloc, bool taken, TAGEBase::BranchInfo* bi, int nrand) override; void handleUReset() override; void resetUctr(uint8_t &u) override; int bindex(Addr pc_in) const override; bool isHighConfidence(TAGEBase::BranchInfo *bi) const override; unsigned getUseAltIdx(TAGEBase::BranchInfo* bi, Addr branch_pc) override; void adjustAlloc(bool & alloc, bool taken, bool pred_taken) override; void updateHistories(ThreadID tid, Addr branch_pc, bool taken, TAGEBase::BranchInfo* b, bool speculative, const StaticInstPtr &inst, Addr target) override; void updatePathAndGlobalHistory(ThreadHistory& tHist, int brtype, bool taken, Addr branch_pc, Addr target); }; class MPP_LoopPredictor : public LoopPredictor { public: MPP_LoopPredictor(MPP_LoopPredictorParams *p) : LoopPredictor(p) {} bool calcConf(int index) const override; bool optionalAgeInc() const override; }; class MPP_StatisticalCorrector : public StatisticalCorrector { protected: int8_t thirdH; // global branch history variation GEHL const unsigned pnb; const unsigned logPnb; std::vector pm; std::vector * pgehl; std::vector wp; // global branch history GEHL const unsigned gnb; const unsigned logGnb; std::vector gm; std::vector * ggehl; std::vector wg; struct MPP_SCThreadHistory : public StatisticalCorrector::SCThreadHistory { MPP_SCThreadHistory() : globalHist(0), historyStack(16, 0), historyStackPointer(0) {} int64_t globalHist; // global history std::vector historyStack; unsigned int historyStackPointer; int64_t getHistoryStackEntry() const { return historyStack[historyStackPointer]; } void updateHistoryStack(Addr target, bool taken, bool is_call, bool is_return) { unsigned int truncated_target = target; historyStack[historyStackPointer] = (historyStack[historyStackPointer] << 1) ^ (truncated_target ^ (truncated_target >> 5) ^ taken); if (is_return) { historyStackPointer = (historyStackPointer - 1) % historyStack.size(); } if (is_call) { int index = (historyStackPointer + 1) % historyStack.size(); historyStack[index] = historyStack[historyStackPointer]; historyStackPointer = index; } } unsigned int getPointer() const { return historyStackPointer; } }; public: struct BranchInfo : public StatisticalCorrector::BranchInfo { virtual ~BranchInfo() {} }; MPP_StatisticalCorrector(const MPP_StatisticalCorrectorParams *p); void initBias() override; unsigned getIndBias(Addr branch_pc, StatisticalCorrector::BranchInfo* bi, bool bias) const override; unsigned getIndBiasSK(Addr branch_pc, StatisticalCorrector::BranchInfo* bi) const override; unsigned getIndBiasBank(Addr branch_pc, StatisticalCorrector::BranchInfo* bi, int hitBank, int altBank) const override; unsigned getIndUpd(Addr branch_pc) const override; int gIndexLogsSubstr(int nbr, int i) override; bool scPredict(ThreadID tid, Addr branch_pc, bool cond_branch, StatisticalCorrector::BranchInfo* bi, bool prev_pred_taken, bool bias_bit, bool use_conf_ctr, int8_t conf_ctr, unsigned conf_bits, int hitBank, int altBank, int64_t phist, int init_lsum) override; void condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken, StatisticalCorrector::BranchInfo *bi, Addr corrTarget, bool b, int hitBank, int altBank, int64_t phist) override; virtual void getBiasLSUM(Addr branch_pc, StatisticalCorrector::BranchInfo *bi, int &lsum) const = 0; void gUpdate( Addr branch_pc, bool taken, int64_t hist, std::vector & length, std::vector * tab, int nbr, int logs, std::vector &w, StatisticalCorrector::BranchInfo* bi) override; }; class MultiperspectivePerceptronTAGE : public MultiperspectivePerceptron { TAGEBase *tage; LoopPredictor *loopPredictor; StatisticalCorrector *statisticalCorrector; /** * Branch information data type */ struct MPPTAGEBranchInfo : public MPPBranchInfo { TAGEBase::BranchInfo *tageBranchInfo; LoopPredictor::BranchInfo *lpBranchInfo; StatisticalCorrector::BranchInfo *scBranchInfo; bool predictedTaken; MPPTAGEBranchInfo(Addr pc, int pcshift, bool cond, TAGEBase &tage, LoopPredictor &loopPredictor, StatisticalCorrector &statisticalCorrector) : MPPBranchInfo(pc, pcshift, cond), tageBranchInfo(tage.makeBranchInfo()), lpBranchInfo(loopPredictor.makeBranchInfo()), scBranchInfo(statisticalCorrector.makeBranchInfo()), predictedTaken(false) {} virtual ~MPPTAGEBranchInfo() { delete tageBranchInfo; delete lpBranchInfo; delete scBranchInfo; } }; unsigned int getIndex(ThreadID tid, MPPTAGEBranchInfo &bi, const HistorySpec &spec, int index) const; int computePartialSum(ThreadID tid, MPPTAGEBranchInfo &bi) const; void updatePartial(ThreadID tid, MPPTAGEBranchInfo &bi, bool taken); void updateHistories(ThreadID tid, MPPTAGEBranchInfo &bi, bool taken); public: MultiperspectivePerceptronTAGE( const MultiperspectivePerceptronTAGEParams *p); void init() override; bool lookup(ThreadID tid, Addr instPC, void * &bp_history) override; void update(ThreadID tid, Addr instPC, bool taken, void *bp_history, bool squashed, const StaticInstPtr & inst, Addr corrTarget = MaxAddr) override; void uncondBranch(ThreadID tid, Addr pc, void * &bp_history) override; void squash(ThreadID tid, void *bp_history) override; }; #endif//__CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_TAGE_HH__