gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
bi_mode.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022-2023 The University of Edinburgh
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2014 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
41/* @file
42 * Implementation of a bi-mode branch predictor
43 */
44
45#include "cpu/pred/bi_mode.hh"
46
47#include "base/bitfield.hh"
48#include "base/intmath.hh"
49
50namespace gem5
51{
52
53namespace branch_prediction
54{
55
81
82/*
83 * For an unconditional branch we set its history such that
84 * everything is set to taken. I.e., its choice predictor
85 * chooses the taken array and the taken array predicts taken.
86 */
87void
88BiModeBP::uncondBranch(ThreadID tid, Addr pc, void * &bp_history)
89{
90 BPHistory *history = new BPHistory;
91 history->globalHistoryReg = globalHistoryReg[tid];
92 history->takenUsed = true;
93 history->takenPred = true;
94 history->notTakenPred = true;
95 history->finalPred = true;
96 bp_history = static_cast<void*>(history);
97}
98
99void
100BiModeBP::updateHistories(ThreadID tid, Addr pc, bool uncond, bool taken,
101 Addr target, const StaticInstPtr &inst,
102 void * &bp_history)
103{
104 assert(uncond || bp_history);
105 if (uncond) {
106 uncondBranch(tid, pc, bp_history);
107 }
108 updateGlobalHistReg(tid, taken);
109}
110
111
112void
113BiModeBP::squash(ThreadID tid, void * &bp_history)
114{
115 BPHistory *history = static_cast<BPHistory*>(bp_history);
116 globalHistoryReg[tid] = history->globalHistoryReg;
117
118 delete history;
119 bp_history = nullptr;
120}
121
122/*
123 * Here we lookup the actual branch prediction. We use the PC to
124 * identify the bias of a particular branch, which is based on the
125 * prediction in the choice array. A hash of the global history
126 * register and a branch's PC is used to index into both the taken
127 * and not-taken predictors, which both present a prediction. The
128 * choice array's prediction is used to select between the two
129 * direction predictors for the final branch prediction.
130 */
131bool
132BiModeBP::lookup(ThreadID tid, Addr branchAddr, void * &bp_history)
133{
134 unsigned choiceHistoryIdx = ((branchAddr >> instShiftAmt)
136 unsigned globalHistoryIdx = (((branchAddr >> instShiftAmt)
137 ^ globalHistoryReg[tid])
139
140 assert(choiceHistoryIdx < choicePredictorSize);
141 assert(globalHistoryIdx < globalPredictorSize);
142
143 bool choicePrediction = choiceCounters[choiceHistoryIdx]
145 bool takenGHBPrediction = takenCounters[globalHistoryIdx]
147 bool notTakenGHBPrediction = notTakenCounters[globalHistoryIdx]
149 bool finalPrediction;
150
151 BPHistory *history = new BPHistory;
152 history->globalHistoryReg = globalHistoryReg[tid];
153 history->takenUsed = choicePrediction;
154 history->takenPred = takenGHBPrediction;
155 history->notTakenPred = notTakenGHBPrediction;
156
157 if (choicePrediction) {
158 finalPrediction = takenGHBPrediction;
159 } else {
160 finalPrediction = notTakenGHBPrediction;
161 }
162
163 history->finalPred = finalPrediction;
164 bp_history = static_cast<void*>(history);
165
166 return finalPrediction;
167}
168
169
170/* Only the selected direction predictor will be updated with the final
171 * outcome; the status of the unselected one will not be altered. The choice
172 * predictor is always updated with the branch outcome, except when the
173 * choice is opposite to the branch outcome but the selected counter of
174 * the direction predictors makes a correct final prediction.
175 */
176void
177BiModeBP::update(ThreadID tid, Addr branchAddr, bool taken,void * &bp_history,
178 bool squashed, const StaticInstPtr & inst, Addr target)
179{
180 assert(bp_history);
181
182 BPHistory *history = static_cast<BPHistory*>(bp_history);
183
184 // We do not update the counters speculatively on a squash.
185 // We just restore the global history register.
186 if (squashed) {
187 globalHistoryReg[tid] = (history->globalHistoryReg << 1) | taken;
188 return;
189 }
190
191 unsigned choiceHistoryIdx = ((branchAddr >> instShiftAmt)
193 unsigned globalHistoryIdx = (((branchAddr >> instShiftAmt)
194 ^ history->globalHistoryReg)
196
197 assert(choiceHistoryIdx < choicePredictorSize);
198 assert(globalHistoryIdx < globalPredictorSize);
199
200 if (history->takenUsed) {
201 // if the taken array's prediction was used, update it
202 if (taken) {
203 takenCounters[globalHistoryIdx]++;
204 } else {
205 takenCounters[globalHistoryIdx]--;
206 }
207 } else {
208 // if the not-taken array's prediction was used, update it
209 if (taken) {
210 notTakenCounters[globalHistoryIdx]++;
211 } else {
212 notTakenCounters[globalHistoryIdx]--;
213 }
214 }
215
216 if (history->finalPred == taken) {
217 /* If the final prediction matches the actual branch's
218 * outcome and the choice predictor matches the final
219 * outcome, we update the choice predictor, otherwise it
220 * is not updated. While the designers of the bi-mode
221 * predictor don't explicity say why this is done, one
222 * can infer that it is to preserve the choice predictor's
223 * bias with respect to the branch being predicted; afterall,
224 * the whole point of the bi-mode predictor is to identify the
225 * atypical case when a branch deviates from its bias.
226 */
227 if (history->finalPred == history->takenUsed) {
228 if (taken) {
229 choiceCounters[choiceHistoryIdx]++;
230 } else {
231 choiceCounters[choiceHistoryIdx]--;
232 }
233 }
234 } else {
235 // always update the choice predictor on an incorrect prediction
236 if (taken) {
237 choiceCounters[choiceHistoryIdx]++;
238 } else {
239 choiceCounters[choiceHistoryIdx]--;
240 }
241 }
242
243 delete history;
244 bp_history = nullptr;
245}
246
247void
249{
250 globalHistoryReg[tid] = taken ? (globalHistoryReg[tid] << 1) | 1 :
251 (globalHistoryReg[tid] << 1);
253}
254
255} // namespace branch_prediction
256} // namespace gem5
BPredUnit(const Params &p)
Branch Predictor Unit (BPU) interface functions.
Definition bpred_unit.cc:58
const unsigned numThreads
Number of the threads for which the branch history is maintained.
const unsigned instShiftAmt
Number of bits to shift instructions by for predictor addresses.
std::vector< unsigned > globalHistoryReg
Definition bi_mode.hh:110
std::vector< SatCounter8 > notTakenCounters
Definition bi_mode.hh:126
void updateGlobalHistReg(ThreadID tid, bool taken)
Definition bi_mode.cc:248
void uncondBranch(ThreadID tid, Addr pc, void *&bp_history)
Definition bi_mode.cc:88
void updateHistories(ThreadID tid, Addr pc, bool uncond, bool taken, Addr target, const StaticInstPtr &inst, void *&bp_history) override
Ones done with the prediction this function updates the path and global history.
Definition bi_mode.cc:100
void squash(ThreadID tid, void *&bp_history) override
Definition bi_mode.cc:113
std::vector< SatCounter8 > takenCounters
Definition bi_mode.hh:124
void update(ThreadID tid, Addr pc, bool taken, void *&bp_history, bool squashed, const StaticInstPtr &inst, Addr target) override
Updates the BP with taken/not taken information.
Definition bi_mode.cc:177
std::vector< SatCounter8 > choiceCounters
Definition bi_mode.hh:122
bool lookup(ThreadID tid, Addr pc, void *&bp_history) override
Looks up a given conditional branch PC of in the BP to see if it is taken or not taken.
Definition bi_mode.cc:132
BiModeBP(const BiModeBPParams &params)
Definition bi_mode.cc:56
static constexpr int ceilLog2(const T &n)
Definition intmath.hh:84
static constexpr bool isPowerOf2(const T &n)
Definition intmath.hh:98
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:232
GenericSatCounter< uint8_t > SatCounter8
const Params & params() const
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 4 > pc
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

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