gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
tage_base.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014 The University of Wisconsin
3 * Copyright (c) 2024 Technical University of Munich
4 *
5 * Copyright (c) 2006 INRIA (Institut National de Recherche en
6 * Informatique et en Automatique / French National Research Institute
7 * for Computer Science and Applied Mathematics)
8 *
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are
13 * met: redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer;
15 * redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution;
18 * neither the name of the copyright holders nor the names of its
19 * contributors may be used to endorse or promote products derived from
20 * this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/* @file
36 * Implementation of a TAGE branch predictor. TAGE is a global-history based
37 * branch predictor. It features a PC-indexed bimodal predictor and N
38 * partially tagged tables, indexed with a hash of the PC and the global
39 * branch history. The different lengths of global branch history used to
40 * index the partially tagged tables grow geometrically. A small path history
41 * is also used in the hash.
42 *
43 * All TAGE tables are accessed in parallel, and the one using the longest
44 * history that matches provides the prediction (some exceptions apply).
45 * Entries are allocated in components using a longer history than the
46 * one that predicted when the prediction is incorrect.
47 */
48
49#ifndef __CPU_PRED_TAGE_BASE_HH__
50#define __CPU_PRED_TAGE_BASE_HH__
51
52#include <vector>
53
54#include "base/statistics.hh"
56#include "cpu/static_inst.hh"
57#include "params/TAGEBase.hh"
58#include "sim/sim_object.hh"
59
60namespace gem5
61{
62
63namespace branch_prediction
64{
65
66class TAGEBase : public SimObject
67{
68 public:
69 TAGEBase(const TAGEBaseParams &p);
70 void init() override;
71
72 protected:
73 // Prediction Structures
74
75 // Tage Entry
76 struct TageEntry
77 {
78 int8_t ctr;
79 uint16_t tag;
80 uint8_t u;
81 TageEntry() : ctr(0), tag(0), u(0) { }
82 };
83
84 // Folded History Table - compressed history
85 // to mix with instruction PC to index partially
86 // tagged tables.
88 {
89 unsigned comp;
94
96 {
97 comp = 0;
98 }
99
100 void init(int original_length, int compressed_length)
101 {
102 origLength = original_length;
103 compLength = compressed_length;
104 outpoint = original_length % compressed_length;
105 }
106
107 void update(uint8_t * h)
108 {
109 comp = (comp << 1) | h[0];
110 comp ^= h[origLength] << outpoint;
111 comp ^= (comp >> compLength);
112 comp &= (1ULL << compLength) - 1;
113 }
114
115 void restore(uint8_t * h)
116 {
117 comp ^= h[origLength] << outpoint;
118 auto tmp = (comp & 1) ^ h[0];
119 comp = (tmp << (compLength-1)) | (comp >> 1);
120 }
121 };
122
123 public:
124
125 // provider type
126 enum
127 {
133 };
134
135 // Primary branch history entry
137 {
139 const bool condBranch;
140
148
153
154 // Pointer to dynamically allocated storage
155 // to save table indices and folded histories.
156 // To do one call to new instead of five.
158
159 // Pointers to actual saved array within the dynamically
160 // allocated storage.
163 int *ci;
164 int *ct0;
165 int *ct1;
166
167 // for stats purposes
168 unsigned provider;
169
170 // The bit vector and the number of bits of global
171 // history used for this branch.
172 uint64_t ghist;
173 uint8_t nGhist;
174
175 // A flag to indicate if this history entry has
176 // modified the histories
178 // A flag to indicate if the indies and tags are valid.
179 bool valid;
180
181 BranchInfo(const TAGEBase &tage, Addr pc, bool conditional)
182 : branchPC(pc), condBranch(conditional),
183 hitBank(0), hitBankIndex(0),
184 altBank(0), altBankIndex(0),
185 bimodalIndex(0),
186 tagePred(false), altTaken(false),
187 longestMatchPred(false),
188 pseudoNewAlloc(false),
189 provider(-1),
190 ghist(0), nGhist(0),
191 modified(false),
192 valid(false)
193 {
194 int sz = tage.nHistoryTables + 1;
195 storage = new int [sz * 5];
197 tableTags = storage + sz;
198 ci = tableTags + sz;
199 ct0 = ci + sz;
200 ct1 = ct0 + sz;
201 }
202
203 virtual ~BranchInfo()
204 {
205 delete[] storage;
206 }
207 };
208
209 virtual BranchInfo *makeBranchInfo(Addr pc, bool conditional);
210
211
217 virtual int bindex(Addr pc_in) const;
218
227 virtual int gindex(ThreadID tid, Addr pc, int bank) const;
228
236 virtual int F(int phist, int size, int bank) const;
237
245 virtual uint16_t gtag(ThreadID tid, Addr pc, int bank) const;
246
254 template<typename T>
255 static void ctrUpdate(T & ctr, bool taken, int nbits);
256
264 static void unsignedCtrUpdate(uint8_t & ctr, bool up, unsigned nbits);
265
273 virtual bool getBimodePred(Addr pc, BranchInfo* bi) const;
274
282 void baseUpdate(Addr pc, bool taken, BranchInfo* bi);
283
294 void updateGHist(ThreadID tid, uint64_t bv, uint8_t n);
295
306 void update(ThreadID tid, Addr branch_pc, bool taken, BranchInfo* bi);
307
323 virtual void updateHistories(ThreadID tid, Addr branch_pc,
324 bool speculative, bool taken, Addr target,
325 const StaticInstPtr &inst, BranchInfo* bi);
333
341
351 virtual void updatePathAndGlobalHistory(ThreadID tid, int brtype,
352 bool taken, Addr branch_pc, Addr target, BranchInfo* bi);
353
357 virtual int branchTypeExtra(const StaticInstPtr & inst) { return 0; }
358
373 virtual void squash(ThreadID tid, bool taken, Addr target,
374 const StaticInstPtr &inst, BranchInfo *bi);
375
388 virtual void condBranchUpdate(
389 ThreadID tid, Addr branch_pc, bool taken, BranchInfo* bi,
390 int nrand, Addr corrTarget, bool pred, bool preAdjustAlloc = false);
391
400 bool tagePredict(
401 ThreadID tid, Addr branch_pc, bool cond_branch, BranchInfo* bi);
402
409 virtual void updateStats(bool taken, BranchInfo* bi);
410
414 virtual void buildTageTables();
415
420 virtual void calculateParameters();
421
426 virtual void calculateIndicesAndTags(
427 ThreadID tid, Addr branch_pc, BranchInfo* bi);
428
433 virtual unsigned getUseAltIdx(BranchInfo* bi, Addr branch_pc);
434
440 virtual void adjustAlloc(bool & alloc, bool taken, bool pred_taken);
441
445 virtual void handleAllocAndUReset(
446 bool alloc, bool taken, BranchInfo* bi, int nrand);
447
451 virtual void handleUReset();
452
456 virtual void handleTAGEUpdate(
457 Addr branch_pc, bool taken, BranchInfo* bi);
458
462 virtual void resetUctr(uint8_t & u);
463
468 virtual void extraAltCalc(BranchInfo* bi);
469
470 virtual bool isHighConfidence(BranchInfo* bi) const
471 {
472 return false;
473 }
474
475 unsigned getGHR(ThreadID tid) const;
476 int8_t getCtr(int hitBank, int hitBankIndex) const;
477 unsigned getTageCtrBits() const;
478 int getPathHist(ThreadID tid, bool speculative=true) const;
479 int calcNewPathHist(ThreadID tid, Addr pc, int cur_phist) const;
480 bool isSpeculativeUpdateEnabled() const;
481 size_t getSizeInBits() const;
482
483 protected:
485 const unsigned nHistoryTables;
486 const unsigned tagTableCounterBits;
487 const unsigned tagTableUBits;
488 const unsigned histBufferSize;
489 const unsigned minHist;
490 const unsigned maxHist;
491 const unsigned pathHistBits;
492
495
499
500 // Keep per-thread histories to
501 // support SMT.
503 {
504 // Speculative path history
505 // (LSB of branch address)
507 // Non-speculative path history
509
510 // Speculative branch direction
511 // history (circular buffer)
512 // @TODO Convert to std::vector<bool>
514
515 // Pointer to most recent branch outcome
516 uint8_t* gHist;
517
518 // Index to most recent branch outcome
520
521 // Speculative folded histories.
524 };
525
527
531 virtual void initFoldedHistories(ThreadHistory & history);
532
536
538 int64_t tCounter;
540 const int64_t initialTCounterValue;
543 unsigned maxNumAlloc;
544
545 // Tells which tables are active
546 // (for the base TAGE implementation all are active)
547 // Some other classes use this for handling associativity
549
551
552 const unsigned instShiftAmt;
553
555
574};
575
576} // namespace branch_prediction
577} // namespace gem5
578
579#endif // __CPU_PRED_TAGE_BASE_HH__
int getPathHist(ThreadID tid, bool speculative=true) const
Definition tage_base.cc:852
TAGEBase(const TAGEBaseParams &p)
Definition tage_base.cc:52
virtual int branchTypeExtra(const StaticInstPtr &inst)
This function acts as a hook for other TAGE implementations to adjust the branch type.
Definition tage_base.hh:357
virtual BranchInfo * makeBranchInfo(Addr pc, bool conditional)
Definition tage_base.cc:83
virtual void handleAllocAndUReset(bool alloc, bool taken, BranchInfo *bi, int nrand)
Handles Allocation and U bits reset on an update.
Definition tage_base.cc:446
void update(ThreadID tid, Addr branch_pc, bool taken, BranchInfo *bi)
Update TAGE.
virtual void initFoldedHistories(ThreadHistory &history)
Initialization of the folded histories.
Definition tage_base.cc:153
static void ctrUpdate(T &ctr, bool taken, int nbits)
Updates a direction counter based on the actual branch outcome.
Definition tage_base.cc:244
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition tage_base.cc:88
virtual unsigned getUseAltIdx(BranchInfo *bi, Addr branch_pc)
Calculation of the index for useAltPredForNewlyAllocated On this base TAGE implementation it is alway...
Definition tage_base.cc:358
virtual void resetUctr(uint8_t &u)
Algorithm for resetting a single U counter.
Definition tage_base.cc:510
virtual void extraAltCalc(BranchInfo *bi)
Extra steps for calculating altTaken For this base TAGE class it does nothing.
Definition tage_base.cc:727
int calcNewPathHist(ThreadID tid, Addr pc, int cur_phist) const
Definition tage_base.cc:711
static void unsignedCtrUpdate(uint8_t &ctr, bool up, unsigned nbits)
Updates an unsigned counter based on up/down parameter.
Definition tage_base.cc:262
virtual void handleUReset()
Handles the U bits reset.
Definition tage_base.cc:495
virtual void updateStats(bool taken, BranchInfo *bi)
Update the stats.
Definition tage_base.cc:734
virtual void calculateParameters()
Calculates the history lengths and some other paramters in derived classes.
Definition tage_base.cc:176
const unsigned logRatioBiModalHystEntries
Definition tage_base.hh:484
std::vector< bool > btableHysteresis
Definition tage_base.hh:497
std::vector< bool > btablePrediction
Definition tage_base.hh:496
virtual void adjustAlloc(bool &alloc, bool taken, bool pred_taken)
Extra calculation to tell whether TAGE allocaitons may happen or not on an update For this base TAGE ...
Definition tage_base.cc:440
void recordHistState(ThreadID tid, BranchInfo *bi)
Records the current state of the histories to be able to restore it in case of a mispredicted specula...
Definition tage_base.cc:663
std::vector< ThreadHistory > threadHistory
Definition tage_base.hh:526
virtual void calculateIndicesAndTags(ThreadID tid, Addr branch_pc, BranchInfo *bi)
On a prediction, calculates the TAGE indices and tags for all the different history lengths.
Definition tage_base.cc:344
virtual bool getBimodePred(Addr pc, BranchInfo *bi) const
Get a branch prediction from the bimodal predictor.
Definition tage_base.cc:276
int8_t getCtr(int hitBank, int hitBankIndex) const
Definition tage_base.cc:840
virtual void squash(ThreadID tid, bool taken, Addr target, const StaticInstPtr &inst, BranchInfo *bi)
Restores speculatively updated path and direction histories.
Definition tage_base.cc:720
virtual uint16_t gtag(ThreadID tid, Addr pc, int bank) const
Computes the partial tag of a tagged table.
Definition tage_base.cc:231
std::vector< int > logTagTableSizes
Definition tage_base.hh:494
void baseUpdate(Addr pc, bool taken, BranchInfo *bi)
Updates the bimodal predictor.
Definition tage_base.cc:285
virtual bool isHighConfidence(BranchInfo *bi) const
Definition tage_base.hh:470
virtual int F(int phist, int size, int bank) const
Utility function to shuffle the path history depending on which tagged table we are accessing.
Definition tage_base.cc:196
bool tagePredict(ThreadID tid, Addr branch_pc, bool cond_branch, BranchInfo *bi)
TAGE prediction called from TAGE::predict.
Definition tage_base.cc:365
std::vector< int8_t > useAltPredForNewlyAllocated
Definition tage_base.hh:537
unsigned getGHR(ThreadID tid) const
Definition tage_base.cc:783
virtual void updatePathAndGlobalHistory(ThreadID tid, int brtype, bool taken, Addr branch_pc, Addr target, BranchInfo *bi)
Does the actual update of path and global history.
Definition tage_base.cc:590
virtual void updateHistories(ThreadID tid, Addr branch_pc, bool speculative, bool taken, Addr target, const StaticInstPtr &inst, BranchInfo *bi)
(Speculatively) updates global histories (path and direction).
Definition tage_base.cc:608
std::vector< unsigned > tagTableTagWidths
Definition tage_base.hh:493
gem5::branch_prediction::TAGEBase::TAGEBaseStats stats
virtual void condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken, BranchInfo *bi, int nrand, Addr corrTarget, bool pred, bool preAdjustAlloc=false)
Update TAGE for conditional branches.
Definition tage_base.cc:516
virtual void buildTageTables()
Instantiates the TAGE table entries.
Definition tage_base.cc:168
void updateGHist(ThreadID tid, uint64_t bv, uint8_t n)
Internal history update function.
Definition tage_base.cc:305
virtual int gindex(ThreadID tid, Addr pc, int bank) const
Computes the index used to access a partially tagged table.
Definition tage_base.cc:213
virtual void handleTAGEUpdate(Addr branch_pc, bool taken, BranchInfo *bi)
Handles the update of the TAGE entries.
Definition tage_base.cc:557
virtual int bindex(Addr pc_in) const
Computes the index used to access the bimodal table.
Definition tage_base.cc:190
void restoreHistState(ThreadID tid, BranchInfo *bi)
Restore the state of the histories in case of detecting a mispredicted speculative update.
Definition tage_base.cc:677
Statistics container.
Definition group.hh:93
This is a simple scalar statistic, like a counter.
A vector of scalar stats.
STL vector class.
Definition stl.hh:37
SimObject(const Params &p)
Definition sim_object.cc:58
Bitfield< 31 > n
Bitfield< 23 > up
Definition types.hh:124
Bitfield< 22 > u
Bitfield< 4 > pc
Bitfield< 0 > p
Bitfield< 20, 16 > bi
Definition types.hh:80
Bitfield< 27, 24 > pred
Definition types.hh:91
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
int16_t ThreadID
Thread index/ID type.
Definition types.hh:235
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
RefCountingPtr< StaticInst > StaticInstPtr
Declaration of Statistics objects.
BranchInfo(const TAGEBase &tage, Addr pc, bool conditional)
Definition tage_base.hh:181
void init(int original_length, int compressed_length)
Definition tage_base.hh:100
TAGEBaseStats(statistics::Group *parent, unsigned nHistoryTables)
Definition tage_base.cc:797

Generated on Mon May 26 2025 09:19:08 for gem5 by doxygen 1.13.2