gem5 v23.0.0.1
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
bpred_unit.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011-2012, 2014 ARM Limited
3 * Copyright (c) 2010 The University of Edinburgh
4 * Copyright (c) 2012 Mark D. Hill and David A. Wood
5 * All rights reserved
6 *
7 * The license below extends only to copyright in the software and shall
8 * not be construed as granting a license to any other intellectual
9 * property including but not limited to intellectual property relating
10 * to a hardware implementation of the functionality of the software
11 * licensed hereunder. You may use the software subject to the license
12 * terms below provided that you ensure that this notice is replicated
13 * unmodified and in its entirety in all distributions of the software,
14 * modified or unmodified, in source code or in binary form.
15 *
16 * Copyright (c) 2004-2005 The Regents of The University of Michigan
17 * All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are
21 * met: redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer;
23 * redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution;
26 * neither the name of the copyright holders nor the names of its
27 * contributors may be used to endorse or promote products derived from
28 * this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 */
42
44
45#include <algorithm>
46
48#include "base/compiler.hh"
49#include "base/trace.hh"
50#include "debug/Branch.hh"
51
52namespace gem5
53{
54
55namespace branch_prediction
56{
57
59 : SimObject(params),
60 numThreads(params.numThreads),
61 predHist(numThreads),
62 BTB(params.BTBEntries,
63 params.BTBTagSize,
64 params.instShiftAmt,
65 params.numThreads),
66 RAS(numThreads),
67 iPred(params.indirectBranchPred),
68 stats(this),
69 instShiftAmt(params.instShiftAmt)
70{
71 for (auto& r : RAS)
72 r.init(params.RASSize);
73}
74
76 : statistics::Group(parent),
77 ADD_STAT(lookups, statistics::units::Count::get(),
78 "Number of BP lookups"),
79 ADD_STAT(condPredicted, statistics::units::Count::get(),
80 "Number of conditional branches predicted"),
81 ADD_STAT(condIncorrect, statistics::units::Count::get(),
82 "Number of conditional branches incorrect"),
83 ADD_STAT(BTBLookups, statistics::units::Count::get(),
84 "Number of BTB lookups"),
85 ADD_STAT(BTBUpdates, statistics::units::Count::get(),
86 "Number of BTB updates"),
87 ADD_STAT(BTBHits, statistics::units::Count::get(), "Number of BTB hits"),
88 ADD_STAT(BTBHitRatio, statistics::units::Ratio::get(), "BTB Hit Ratio",
89 BTBHits / BTBLookups),
90 ADD_STAT(RASUsed, statistics::units::Count::get(),
91 "Number of times the RAS was used to get a target."),
92 ADD_STAT(RASIncorrect, statistics::units::Count::get(),
93 "Number of incorrect RAS predictions."),
94 ADD_STAT(indirectLookups, statistics::units::Count::get(),
95 "Number of indirect predictor lookups."),
96 ADD_STAT(indirectHits, statistics::units::Count::get(),
97 "Number of indirect target hits."),
98 ADD_STAT(indirectMisses, statistics::units::Count::get(),
99 "Number of indirect misses."),
100 ADD_STAT(indirectMispredicted, statistics::units::Count::get(),
101 "Number of mispredicted indirect branches.")
102{
104}
105
108{
110 ptr.reset(new probing::PMU(getProbeManager(), name));
111
112 return ptr;
113}
114
115void
117{
118 ppBranches = pmuProbePoint("Branches");
119 ppMisses = pmuProbePoint("Misses");
120}
121
122void
124{
125 // We shouldn't have any outstanding requests when we resume from
126 // a drained system.
127 for ([[maybe_unused]] const auto& ph : predHist)
128 assert(ph.empty());
129}
130
131bool
132BPredUnit::predict(const StaticInstPtr &inst, const InstSeqNum &seqNum,
133 PCStateBase &pc, ThreadID tid)
134{
135 // See if branch predictor predicts taken.
136 // If so, get its target addr either from the BTB or the RAS.
137 // Save off record of branch stuff so the RAS can be fixed
138 // up once it's done.
139
140 bool pred_taken = false;
141 std::unique_ptr<PCStateBase> target(pc.clone());
142
143 ++stats.lookups;
144 ppBranches->notify(1);
145
146 void *bp_history = NULL;
147 void *indirect_history = NULL;
148
149 if (inst->isUncondCtrl()) {
150 DPRINTF(Branch, "[tid:%i] [sn:%llu] Unconditional control\n",
151 tid,seqNum);
152 pred_taken = true;
153 // Tell the BP there was an unconditional branch.
154 uncondBranch(tid, pc.instAddr(), bp_history);
155 } else {
157 pred_taken = lookup(tid, pc.instAddr(), bp_history);
158
159 DPRINTF(Branch, "[tid:%i] [sn:%llu] "
160 "Branch predictor predicted %i for PC %s\n",
161 tid, seqNum, pred_taken, pc);
162 }
163
164 const bool orig_pred_taken = pred_taken;
165 if (iPred) {
166 iPred->genIndirectInfo(tid, indirect_history);
167 }
168
170 "[tid:%i] [sn:%llu] Creating prediction history for PC %s\n",
171 tid, seqNum, pc);
172
173 PredictorHistory predict_record(seqNum, pc.instAddr(), pred_taken,
174 bp_history, indirect_history, tid, inst);
175
176 // Now lookup in the BTB or RAS.
177 if (pred_taken) {
178 // Note: The RAS may be both popped and pushed to
179 // support coroutines.
180 if (inst->isReturn()) {
181 ++stats.RASUsed;
182 predict_record.wasReturn = true;
183 // If it's a function return call, then look up the address
184 // in the RAS.
185 const PCStateBase *ras_top = RAS[tid].top();
186 if (ras_top)
187 set(target, inst->buildRetPC(pc, *ras_top));
188
189 // Record the top entry of the RAS, and its index.
190 predict_record.usedRAS = true;
191 predict_record.RASIndex = RAS[tid].topIdx();
192 set(predict_record.RASTarget, ras_top);
193
194 RAS[tid].pop();
195
196 DPRINTF(Branch, "[tid:%i] [sn:%llu] Instruction %s is a return, "
197 "RAS predicted target: %s, RAS index: %i\n",
198 tid, seqNum, pc, *target, predict_record.RASIndex);
199 }
200
201 if (inst->isCall()) {
202 RAS[tid].push(pc);
203 predict_record.pushedRAS = true;
204
205 // Record that it was a call so that the top RAS entry can
206 // be popped off if the speculation is incorrect.
207 predict_record.wasCall = true;
208
210 "[tid:%i] [sn:%llu] Instruction %s was a call, adding "
211 "%s to the RAS index: %i\n",
212 tid, seqNum, pc, pc, RAS[tid].topIdx());
213 }
214
215 // The target address is not predicted by RAS.
216 // Thus, BTB/IndirectBranch Predictor is employed.
217 if (!inst->isReturn()) {
218 if (inst->isDirectCtrl() || !iPred) {
220 // Check BTB on direct branches
221 if (BTB.valid(pc.instAddr(), tid)) {
222 ++stats.BTBHits;
223 // If it's not a return, use the BTB to get target addr.
224 set(target, BTB.lookup(pc.instAddr(), tid));
226 "[tid:%i] [sn:%llu] Instruction %s predicted "
227 "target is %s\n",
228 tid, seqNum, pc, *target);
229 } else {
230 DPRINTF(Branch, "[tid:%i] [sn:%llu] BTB doesn't have a "
231 "valid entry\n", tid, seqNum);
232 pred_taken = false;
233 predict_record.predTaken = pred_taken;
234 // The Direction of the branch predictor is altered
235 // because the BTB did not have an entry
236 // The predictor needs to be updated accordingly
237 if (!inst->isCall() && !inst->isReturn()) {
238 btbUpdate(tid, pc.instAddr(), bp_history);
240 "[tid:%i] [sn:%llu] btbUpdate "
241 "called for %s\n",
242 tid, seqNum, pc);
243 } else if (inst->isCall() && !inst->isUncondCtrl()) {
244 RAS[tid].pop();
245 predict_record.pushedRAS = false;
246 }
247 inst->advancePC(*target);
248 }
249 } else {
250 predict_record.wasIndirect = true;
252 //Consult indirect predictor on indirect control
253 if (iPred->lookup(pc.instAddr(), *target, tid)) {
254 // Indirect predictor hit
257 "[tid:%i] [sn:%llu] Instruction %s predicted "
258 "indirect target is %s\n",
259 tid, seqNum, pc, *target);
260 } else {
262 pred_taken = false;
263 predict_record.predTaken = pred_taken;
265 "[tid:%i] [sn:%llu] Instruction %s no indirect "
266 "target\n",
267 tid, seqNum, pc);
268 if (!inst->isCall() && !inst->isReturn()) {
269
270 } else if (inst->isCall() && !inst->isUncondCtrl()) {
271 RAS[tid].pop();
272 predict_record.pushedRAS = false;
273 }
274 inst->advancePC(*target);
275 }
276 iPred->recordIndirect(pc.instAddr(), target->instAddr(),
277 seqNum, tid);
278 }
279 }
280 } else {
281 if (inst->isReturn()) {
282 predict_record.wasReturn = true;
283 }
284 inst->advancePC(*target);
285 }
286 predict_record.target = target->instAddr();
287
288 set(pc, *target);
289
290 if (iPred) {
291 // Update the indirect predictor with the direction prediction
292 // Note that this happens after indirect lookup, so it does not use
293 // the new information
294 // Note also that we use orig_pred_taken instead of pred_taken in
295 // as this is the actual outcome of the direction prediction
296 iPred->updateDirectionInfo(tid, orig_pred_taken);
297 }
298
299 predHist[tid].push_front(predict_record);
300
302 "[tid:%i] [sn:%llu] History entry added. "
303 "predHist.size(): %i\n",
304 tid, seqNum, predHist[tid].size());
305
306 return pred_taken;
307}
308
309void
311{
312 DPRINTF(Branch, "[tid:%i] Committing branches until "
313 "sn:%llu]\n", tid, done_sn);
314
315 while (!predHist[tid].empty() &&
316 predHist[tid].back().seqNum <= done_sn) {
317 // Update the branch predictor with the correct results.
318 update(tid, predHist[tid].back().pc,
319 predHist[tid].back().predTaken,
320 predHist[tid].back().bpHistory, false,
321 predHist[tid].back().inst,
322 predHist[tid].back().target);
323
324 if (iPred) {
325 iPred->commit(done_sn, tid, predHist[tid].back().indirectHistory);
326 }
327
328 predHist[tid].pop_back();
329 }
330}
331
332void
333BPredUnit::squash(const InstSeqNum &squashed_sn, ThreadID tid)
334{
335 History &pred_hist = predHist[tid];
336
337 if (iPred) {
338 iPred->squash(squashed_sn, tid);
339 }
340
341 while (!pred_hist.empty() &&
342 pred_hist.front().seqNum > squashed_sn) {
343 if (pred_hist.front().wasCall && pred_hist.front().pushedRAS) {
344 // Was a call but predicated false. Pop RAS here
345 DPRINTF(Branch, "[tid:%i] [squash sn:%llu] Squashing"
346 " Call [sn:%llu] PC: %s Popping RAS\n", tid, squashed_sn,
347 pred_hist.front().seqNum, pred_hist.front().pc);
348 RAS[tid].pop();
349 }
350 if (pred_hist.front().usedRAS) {
351 if (pred_hist.front().RASTarget != nullptr) {
352 DPRINTF(Branch, "[tid:%i] [squash sn:%llu]"
353 " Restoring top of RAS to: %i,"
354 " target: %s\n", tid, squashed_sn,
355 pred_hist.front().RASIndex,
356 *pred_hist.front().RASTarget);
357 }
358 else {
359 DPRINTF(Branch, "[tid:%i] [squash sn:%llu]"
360 " Restoring top of RAS to: %i,"
361 " target: INVALID_TARGET\n", tid, squashed_sn,
362 pred_hist.front().RASIndex);
363 }
364
365 RAS[tid].restore(pred_hist.front().RASIndex,
366 pred_hist.front().RASTarget.get());
367 }
368
369 // This call should delete the bpHistory.
370 squash(tid, pred_hist.front().bpHistory);
371 if (iPred) {
372 iPred->deleteIndirectInfo(tid, pred_hist.front().indirectHistory);
373 }
374
375 DPRINTF(Branch, "[tid:%i] [squash sn:%llu] "
376 "Removing history for [sn:%llu] "
377 "PC %#x\n", tid, squashed_sn, pred_hist.front().seqNum,
378 pred_hist.front().pc);
379
380 pred_hist.pop_front();
381
382 DPRINTF(Branch, "[tid:%i] [squash sn:%llu] predHist.size(): %i\n",
383 tid, squashed_sn, predHist[tid].size());
384 }
385}
386
387void
388BPredUnit::squash(const InstSeqNum &squashed_sn,
389 const PCStateBase &corr_target,
390 bool actually_taken, ThreadID tid)
391{
392 // Now that we know that a branch was mispredicted, we need to undo
393 // all the branches that have been seen up until this branch and
394 // fix up everything.
395 // NOTE: This should be call conceivably in 2 scenarios:
396 // (1) After an branch is executed, it updates its status in the ROB
397 // The commit stage then checks the ROB update and sends a signal to
398 // the fetch stage to squash history after the mispredict
399 // (2) In the decode stage, you can find out early if a unconditional
400 // PC-relative, branch was predicted incorrectly. If so, a signal
401 // to the fetch stage is sent to squash history after the mispredict
402
403 History &pred_hist = predHist[tid];
404
406 ppMisses->notify(1);
407
408 DPRINTF(Branch, "[tid:%i] Squashing from sequence number %i, "
409 "setting target to %s\n", tid, squashed_sn, corr_target);
410
411 // Squash All Branches AFTER this mispredicted branch
412 squash(squashed_sn, tid);
413
414 // If there's a squash due to a syscall, there may not be an entry
415 // corresponding to the squash. In that case, don't bother trying to
416 // fix up the entry.
417 if (!pred_hist.empty()) {
418
419 auto hist_it = pred_hist.begin();
420 //HistoryIt hist_it = find(pred_hist.begin(), pred_hist.end(),
421 // squashed_sn);
422
423 //assert(hist_it != pred_hist.end());
424 if (pred_hist.front().seqNum != squashed_sn) {
425 DPRINTF(Branch, "Front sn %i != Squash sn %i\n",
426 pred_hist.front().seqNum, squashed_sn);
427
428 assert(pred_hist.front().seqNum == squashed_sn);
429 }
430
431
432 if ((*hist_it).usedRAS) {
435 "[tid:%i] [squash sn:%llu] Incorrect RAS [sn:%llu]\n",
436 tid, squashed_sn, hist_it->seqNum);
437 }
438
439 // There are separate functions for in-order and out-of-order
440 // branch prediction, but not for update. Therefore, this
441 // call should take into account that the mispredicted branch may
442 // be on the wrong path (i.e., OoO execution), and that the counter
443 // counter table(s) should not be updated. Thus, this call should
444 // restore the state of the underlying predictor, for instance the
445 // local/global histories. The counter tables will be updated when
446 // the branch actually commits.
447
448 // Remember the correct direction for the update at commit.
449 pred_hist.front().predTaken = actually_taken;
450 pred_hist.front().target = corr_target.instAddr();
451
452 update(tid, (*hist_it).pc, actually_taken,
453 pred_hist.front().bpHistory, true, pred_hist.front().inst,
454 corr_target.instAddr());
455
456 if (iPred) {
458 pred_hist.front().indirectHistory, actually_taken);
459 }
460
461 if (actually_taken) {
462 if (hist_it->wasReturn && !hist_it->usedRAS) {
463 DPRINTF(Branch, "[tid:%i] [squash sn:%llu] "
464 "Incorrectly predicted "
465 "return [sn:%llu] PC: %#x\n", tid, squashed_sn,
466 hist_it->seqNum,
467 hist_it->pc);
468 RAS[tid].pop();
469 hist_it->usedRAS = true;
470 }
471 if (hist_it->wasIndirect) {
473 if (iPred) {
475 hist_it->seqNum, pred_hist.front().indirectHistory,
476 corr_target, tid);
477 }
478 } else {
479 DPRINTF(Branch,"[tid:%i] [squash sn:%llu] "
480 "BTB Update called for [sn:%llu] "
481 "PC %#x\n", tid, squashed_sn,
482 hist_it->seqNum, hist_it->pc);
483
485 BTB.update(hist_it->pc, corr_target, tid);
486 }
487 } else {
488 //Actually not Taken
489 if (hist_it->wasCall && hist_it->pushedRAS) {
490 //Was a Call but predicated false. Pop RAS here
492 "[tid:%i] [squash sn:%llu] "
493 "Incorrectly predicted "
494 "Call [sn:%llu] PC: %s Popping RAS\n",
495 tid, squashed_sn,
496 hist_it->seqNum, hist_it->pc);
497 RAS[tid].pop();
498 hist_it->pushedRAS = false;
499 }
500 if (hist_it->usedRAS) {
502 "[tid:%i] [squash sn:%llu] Incorrectly predicted "
503 "return [sn:%llu] PC: %#x Restoring RAS\n", tid,
504 squashed_sn,
505 hist_it->seqNum, hist_it->pc);
507 "[tid:%i] [squash sn:%llu] Restoring top of RAS "
508 "to: %i, target: %s\n", tid, squashed_sn,
509 hist_it->RASIndex, *hist_it->RASTarget);
510 RAS[tid].restore(hist_it->RASIndex, hist_it->RASTarget.get());
511 hist_it->usedRAS = false;
512 }
513 }
514 } else {
515 DPRINTF(Branch, "[tid:%i] [sn:%llu] pred_hist empty, can't "
516 "update\n", tid, squashed_sn);
517 }
518}
519
520void
522{
523 int i = 0;
524 for (const auto& ph : predHist) {
525 if (!ph.empty()) {
526 auto pred_hist_it = ph.begin();
527
528 cprintf("predHist[%i].size(): %i\n", i++, ph.size());
529
530 while (pred_hist_it != ph.end()) {
531 cprintf("sn:%llu], PC:%#x, tid:%i, predTaken:%i, "
532 "bpHistory:%#x\n",
533 pred_hist_it->seqNum, pred_hist_it->pc,
534 pred_hist_it->tid, pred_hist_it->predTaken,
535 pred_hist_it->bpHistory);
536 pred_hist_it++;
537 }
538
539 cprintf("\n");
540 }
541 }
542}
543
544} // namespace branch_prediction
545} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
virtual std::string name() const
Definition named.hh:47
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
Definition pcstate.hh:107
ProbePointArg generates a point for the class of Arg.
Definition probe.hh:263
Abstract superclass for simulation objects.
Base class for branch operations.
Definition branch.hh:49
virtual std::unique_ptr< PCStateBase > buildRetPC(const PCStateBase &cur_pc, const PCStateBase &call_pc) const
bool isDirectCtrl() const
bool isUncondCtrl() const
virtual void advancePC(PCStateBase &pc_state) const =0
bool isReturn() const
bool isCall() const
std::vector< History > predHist
The per-thread predictor history.
virtual void uncondBranch(ThreadID tid, Addr pc, void *&bp_history)=0
probing::PMUUPtr pmuProbePoint(const char *name)
Helper method to instantiate probe points belonging to this object.
virtual void btbUpdate(ThreadID tid, Addr instPC, void *&bp_history)=0
If a branch is not taken, because the BTB address is invalid or missing, this function sets the appro...
void update(const InstSeqNum &done_sn, ThreadID tid)
Tells the branch predictor to commit any updates until the given sequence number.
bool predict(const StaticInstPtr &inst, const InstSeqNum &seqNum, PCStateBase &pc, ThreadID tid)
Predicts whether or not the instruction is a taken branch, and the target of the branch if it is take...
probing::PMUUPtr ppMisses
Miss-predicted branches.
virtual bool lookup(ThreadID tid, Addr instPC, void *&bp_history)=0
Looks up a given PC in the BP to see if it is taken or not taken.
void drainSanityCheck() const
Perform sanity checks after a drain.
IndirectPredictor * iPred
The indirect target predictor.
probing::PMUUPtr ppBranches
Branches seen by the branch predictor.
void regProbePoints() override
Register probe points for this object.
std::vector< ReturnAddrStack > RAS
The per-thread return address stack.
BranchPredictorParams Params
Definition bpred_unit.hh:71
void squash(const InstSeqNum &squashed_sn, ThreadID tid)
Squashes all outstanding updates until a given sequence number.
gem5::branch_prediction::BPredUnit::BPredUnitStats stats
bool valid(Addr instPC, ThreadID tid)
Checks if a branch is in the BTB.
Definition btb.cc:95
void update(Addr inst_pc, const PCStateBase &target_pc, ThreadID tid)
Updates the BTB with the target of a branch.
Definition btb.cc:134
const PCStateBase * lookup(Addr instPC, ThreadID tid)
Looks up an address in the BTB.
Definition btb.cc:116
virtual void commit(InstSeqNum seq_num, ThreadID tid, void *indirect_history)=0
virtual void squash(InstSeqNum seq_num, ThreadID tid)=0
virtual void deleteIndirectInfo(ThreadID tid, void *indirect_history)=0
virtual void updateDirectionInfo(ThreadID tid, bool actually_taken)=0
virtual void changeDirectionPrediction(ThreadID tid, void *indirect_history, bool actually_taken)=0
virtual bool lookup(Addr br_addr, PCStateBase &br_target, ThreadID tid)=0
virtual void recordIndirect(Addr br_addr, Addr tgt_addr, InstSeqNum seq_num, ThreadID tid)=0
virtual void recordTarget(InstSeqNum seq_num, void *indirect_history, const PCStateBase &target, ThreadID tid)=0
virtual void genIndirectInfo(ThreadID tid, void *&indirect_history)=0
Derived & precision(int _precision)
Set the precision and marks this stat to print at the end of simulation.
Statistics container.
Definition group.hh:93
STL deque class.
Definition stl.hh:44
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition group.hh:75
const Params & params() const
ProbeManager * getProbeManager()
Get the probe manager for this object.
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 12, 11 > set
Bitfield< 4 > pc
std::unique_ptr< PMU > PMUUPtr
Definition pmu.hh:60
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
int16_t ThreadID
Thread index/ID type.
Definition types.hh:235
void cprintf(const char *format, const Args &...args)
Definition cprintf.hh:155
uint64_t InstSeqNum
Definition inst_seq.hh:40
statistics::Scalar BTBUpdates
Stat for number of BTB updates.
statistics::Scalar indirectMispredicted
Stat for the number of indirect target mispredictions.
statistics::Scalar BTBLookups
Stat for number of BTB lookups.
statistics::Scalar condIncorrect
Stat for number of conditional branches predicted incorrectly.
statistics::Scalar indirectLookups
Stat for the number of indirect target lookups.
statistics::Scalar indirectHits
Stat for the number of indirect target hits.
statistics::Scalar RASUsed
Stat for number of times the RAS is used to get a target.
statistics::Scalar condPredicted
Stat for number of conditional branches predicted.
statistics::Formula BTBHitRatio
Stat for the ratio between BTB hits and BTB lookups.
statistics::Scalar indirectMisses
Stat for the number of indirect target misses.
statistics::Scalar RASIncorrect
Stat for number of times the RAS is incorrect.
statistics::Scalar lookups
Stat for number of BP lookups.
statistics::Scalar BTBHits
Stat for number of BTB hits.
bool predTaken
Whether or not it was predicted taken.
unsigned RASIndex
The RAS index of the instruction (only valid if a call).
bool wasReturn
Whether or not the instruction was a return.
bool wasIndirect
Wether this instruction was an indirect branch.
bool wasCall
Whether or not the instruction was a call.
std::unique_ptr< PCStateBase > RASTarget
The RAS target (only valid if a return).
bool usedRAS
Whether or not the RAS was used.

Generated on Mon Jul 10 2023 15:32:01 for gem5 by doxygen 1.9.7