blob: 3a92e3cf07aedd58538e56e8a6d9354307df59ce [file] [log] [blame]
/*
* 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"
namespace gem5
{
namespace branch_prediction
{
class MPP_TAGE : public TAGEBase
{
std::vector<unsigned int> 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(const 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<int> pm;
std::vector<int8_t> * pgehl;
std::vector<int8_t> wp;
// global branch history GEHL
const unsigned gnb;
const unsigned logGnb;
std::vector<int> gm;
std::vector<int8_t> * ggehl;
std::vector<int8_t> wg;
struct MPP_SCThreadHistory : public StatisticalCorrector::SCThreadHistory
{
MPP_SCThreadHistory() : globalHist(0), historyStack(16, 0),
historyStackPointer(0) {}
int64_t globalHist; // global history
std::vector<int64_t> 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<int> & length,
std::vector<int8_t> * tab, int nbr, int logs,
std::vector<int8_t> &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) override;
void uncondBranch(ThreadID tid, Addr pc, void * &bp_history) override;
void squash(ThreadID tid, void *bp_history) override;
};
} // namespace branch_prediction
} // namespace gem5
#endif//__CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_TAGE_HH__