gem5  v20.0.0.3
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 
43 #include "cpu/pred/bpred_unit.hh"
44 
45 #include <algorithm>
46 
47 #include "arch/isa_traits.hh"
48 #include "arch/types.hh"
49 #include "arch/utility.hh"
50 #include "base/trace.hh"
51 #include "config/the_isa.hh"
52 #include "debug/Branch.hh"
53 
55  : SimObject(params),
56  numThreads(params->numThreads),
57  predHist(numThreads),
58  BTB(params->BTBEntries,
59  params->BTBTagSize,
60  params->instShiftAmt,
61  params->numThreads),
62  RAS(numThreads),
63  iPred(params->indirectBranchPred),
64  instShiftAmt(params->instShiftAmt)
65 {
66  for (auto& r : RAS)
67  r.init(params->RASSize);
68 }
69 
70 void
72 {
74 
75  lookups
76  .name(name() + ".lookups")
77  .desc("Number of BP lookups")
78  ;
79 
81  .name(name() + ".condPredicted")
82  .desc("Number of conditional branches predicted")
83  ;
84 
86  .name(name() + ".condIncorrect")
87  .desc("Number of conditional branches incorrect")
88  ;
89 
91  .name(name() + ".BTBLookups")
92  .desc("Number of BTB lookups")
93  ;
94 
95  BTBHits
96  .name(name() + ".BTBHits")
97  .desc("Number of BTB hits")
98  ;
99 
100  BTBCorrect
101  .name(name() + ".BTBCorrect")
102  .desc("Number of correct BTB predictions (this stat may not "
103  "work properly.")
104  ;
105 
106  BTBHitPct
107  .name(name() + ".BTBHitPct")
108  .desc("BTB Hit Percentage")
109  .precision(6);
110  BTBHitPct = (BTBHits / BTBLookups) * 100;
111 
112  usedRAS
113  .name(name() + ".usedRAS")
114  .desc("Number of times the RAS was used to get a target.")
115  ;
116 
118  .name(name() + ".RASInCorrect")
119  .desc("Number of incorrect RAS predictions.")
120  ;
121 
123  .name(name() + ".indirectLookups")
124  .desc("Number of indirect predictor lookups.")
125  ;
126 
128  .name(name() + ".indirectHits")
129  .desc("Number of indirect target hits.")
130  ;
131 
133  .name(name() + ".indirectMisses")
134  .desc("Number of indirect misses.")
135  ;
136 
138  .name(name() + "indirectMispredicted")
139  .desc("Number of mispredicted indirect branches.")
140  ;
141 
142 }
143 
146 {
148  ptr.reset(new ProbePoints::PMU(getProbeManager(), name));
149 
150  return ptr;
151 }
152 
153 void
155 {
156  ppBranches = pmuProbePoint("Branches");
157  ppMisses = pmuProbePoint("Misses");
158 }
159 
160 void
162 {
163  // We shouldn't have any outstanding requests when we resume from
164  // a drained system.
165  for (const auto& ph M5_VAR_USED : predHist)
166  assert(ph.empty());
167 }
168 
169 bool
170 BPredUnit::predict(const StaticInstPtr &inst, const InstSeqNum &seqNum,
172 {
173  // See if branch predictor predicts taken.
174  // If so, get its target addr either from the BTB or the RAS.
175  // Save off record of branch stuff so the RAS can be fixed
176  // up once it's done.
177 
178  bool pred_taken = false;
179  TheISA::PCState target = pc;
180 
181  ++lookups;
182  ppBranches->notify(1);
183 
184  void *bp_history = NULL;
185  void *indirect_history = NULL;
186 
187  if (inst->isUncondCtrl()) {
188  DPRINTF(Branch, "[tid:%i] [sn:%llu] "
189  "Unconditional control\n",
190  tid,seqNum);
191  pred_taken = true;
192  // Tell the BP there was an unconditional branch.
193  uncondBranch(tid, pc.instAddr(), bp_history);
194  } else {
195  ++condPredicted;
196  pred_taken = lookup(tid, pc.instAddr(), bp_history);
197 
198  DPRINTF(Branch, "[tid:%i] [sn:%llu] "
199  "Branch predictor predicted %i for PC %s\n",
200  tid, seqNum, pred_taken, pc);
201  }
202 
203  const bool orig_pred_taken = pred_taken;
204  if (iPred) {
205  iPred->genIndirectInfo(tid, indirect_history);
206  }
207 
208  DPRINTF(Branch, "[tid:%i] [sn:%llu] "
209  "Creating prediction history "
210  "for PC %s\n", tid, seqNum, pc);
211 
212  PredictorHistory predict_record(seqNum, pc.instAddr(), pred_taken,
213  bp_history, indirect_history, tid, inst);
214 
215  // Now lookup in the BTB or RAS.
216  if (pred_taken) {
217  if (inst->isReturn()) {
218  ++usedRAS;
219  predict_record.wasReturn = true;
220  // If it's a function return call, then look up the address
221  // in the RAS.
222  TheISA::PCState rasTop = RAS[tid].top();
223  target = TheISA::buildRetPC(pc, rasTop);
224 
225  // Record the top entry of the RAS, and its index.
226  predict_record.usedRAS = true;
227  predict_record.RASIndex = RAS[tid].topIdx();
228  predict_record.RASTarget = rasTop;
229 
230  RAS[tid].pop();
231 
232  DPRINTF(Branch, "[tid:%i] [sn:%llu] Instruction %s is a return, "
233  "RAS predicted target: %s, RAS index: %i\n",
234  tid, seqNum, pc, target, predict_record.RASIndex);
235  } else {
236 
237  if (inst->isCall()) {
238  RAS[tid].push(pc);
239  predict_record.pushedRAS = true;
240 
241  // Record that it was a call so that the top RAS entry can
242  // be popped off if the speculation is incorrect.
243  predict_record.wasCall = true;
244 
245  DPRINTF(Branch,
246  "[tid:%i] [sn:%llu] Instruction %s was a call, adding "
247  "%s to the RAS index: %i\n",
248  tid, seqNum, pc, pc, RAS[tid].topIdx());
249  }
250 
251  if (inst->isDirectCtrl() || !iPred) {
252  ++BTBLookups;
253  // Check BTB on direct branches
254  if (BTB.valid(pc.instAddr(), tid)) {
255  ++BTBHits;
256  // If it's not a return, use the BTB to get target addr.
257  target = BTB.lookup(pc.instAddr(), tid);
258  DPRINTF(Branch,
259  "[tid:%i] [sn:%llu] Instruction %s predicted "
260  "target is %s\n",
261  tid, seqNum, pc, target);
262  } else {
263  DPRINTF(Branch, "[tid:%i] [sn:%llu] BTB doesn't have a "
264  "valid entry\n",tid,seqNum);
265  pred_taken = false;
266  predict_record.predTaken = pred_taken;
267  // The Direction of the branch predictor is altered
268  // because the BTB did not have an entry
269  // The predictor needs to be updated accordingly
270  if (!inst->isCall() && !inst->isReturn()) {
271  btbUpdate(tid, pc.instAddr(), bp_history);
272  DPRINTF(Branch,
273  "[tid:%i] [sn:%llu] btbUpdate "
274  "called for %s\n",
275  tid, seqNum, pc);
276  } else if (inst->isCall() && !inst->isUncondCtrl()) {
277  RAS[tid].pop();
278  predict_record.pushedRAS = false;
279  }
280  TheISA::advancePC(target, inst);
281  }
282  } else {
283  predict_record.wasIndirect = true;
284  ++indirectLookups;
285  //Consult indirect predictor on indirect control
286  if (iPred->lookup(pc.instAddr(), target, tid)) {
287  // Indirect predictor hit
288  ++indirectHits;
289  DPRINTF(Branch,
290  "[tid:%i] [sn:%llu] "
291  "Instruction %s predicted "
292  "indirect target is %s\n",
293  tid, seqNum, pc, target);
294  } else {
295  ++indirectMisses;
296  pred_taken = false;
297  predict_record.predTaken = pred_taken;
298  DPRINTF(Branch,
299  "[tid:%i] [sn:%llu] "
300  "Instruction %s no indirect "
301  "target\n",
302  tid, seqNum, pc);
303  if (!inst->isCall() && !inst->isReturn()) {
304 
305  } else if (inst->isCall() && !inst->isUncondCtrl()) {
306  RAS[tid].pop();
307  predict_record.pushedRAS = false;
308  }
309  TheISA::advancePC(target, inst);
310  }
311  iPred->recordIndirect(pc.instAddr(), target.instAddr(), seqNum,
312  tid);
313  }
314  }
315  } else {
316  if (inst->isReturn()) {
317  predict_record.wasReturn = true;
318  }
319  TheISA::advancePC(target, inst);
320  }
321  predict_record.target = target.instAddr();
322 
323  pc = target;
324 
325  if (iPred) {
326  // Update the indirect predictor with the direction prediction
327  // Note that this happens after indirect lookup, so it does not use
328  // the new information
329  // Note also that we use orig_pred_taken instead of pred_taken in
330  // as this is the actual outcome of the direction prediction
331  iPred->updateDirectionInfo(tid, orig_pred_taken);
332  }
333 
334  predHist[tid].push_front(predict_record);
335 
336  DPRINTF(Branch,
337  "[tid:%i] [sn:%llu] History entry added. "
338  "predHist.size(): %i\n",
339  tid, seqNum, predHist[tid].size());
340 
341  return pred_taken;
342 }
343 
344 void
346 {
347  DPRINTF(Branch, "[tid:%i] Committing branches until "
348  "sn:%llu]\n", tid, done_sn);
349 
350  while (!predHist[tid].empty() &&
351  predHist[tid].back().seqNum <= done_sn) {
352  // Update the branch predictor with the correct results.
353  update(tid, predHist[tid].back().pc,
354  predHist[tid].back().predTaken,
355  predHist[tid].back().bpHistory, false,
356  predHist[tid].back().inst,
357  predHist[tid].back().target);
358 
359  if (iPred) {
360  iPred->commit(done_sn, tid, predHist[tid].back().indirectHistory);
361  }
362 
363  predHist[tid].pop_back();
364  }
365 }
366 
367 void
368 BPredUnit::squash(const InstSeqNum &squashed_sn, ThreadID tid)
369 {
370  History &pred_hist = predHist[tid];
371 
372  if (iPred) {
373  iPred->squash(squashed_sn, tid);
374  }
375 
376  while (!pred_hist.empty() &&
377  pred_hist.front().seqNum > squashed_sn) {
378  if (pred_hist.front().usedRAS) {
379  DPRINTF(Branch, "[tid:%i] [squash sn:%llu]"
380  " Restoring top of RAS to: %i,"
381  " target: %s\n", tid, squashed_sn,
382  pred_hist.front().RASIndex, pred_hist.front().RASTarget);
383 
384  RAS[tid].restore(pred_hist.front().RASIndex,
385  pred_hist.front().RASTarget);
386  } else if (pred_hist.front().wasCall && pred_hist.front().pushedRAS) {
387  // Was a call but predicated false. Pop RAS here
388  DPRINTF(Branch, "[tid:%i] [squash sn:%llu] Squashing"
389  " Call [sn:%llu] PC: %s Popping RAS\n", tid, squashed_sn,
390  pred_hist.front().seqNum, pred_hist.front().pc);
391  RAS[tid].pop();
392  }
393 
394  // This call should delete the bpHistory.
395  squash(tid, pred_hist.front().bpHistory);
396  if (iPred) {
397  iPred->deleteIndirectInfo(tid, pred_hist.front().indirectHistory);
398  }
399 
400  DPRINTF(Branch, "[tid:%i] [squash sn:%llu] "
401  "Removing history for [sn:%llu] "
402  "PC %#x\n", tid, squashed_sn, pred_hist.front().seqNum,
403  pred_hist.front().pc);
404 
405  pred_hist.pop_front();
406 
407  DPRINTF(Branch, "[tid:%i] [squash sn:%llu] predHist.size(): %i\n",
408  tid, squashed_sn, predHist[tid].size());
409  }
410 }
411 
412 void
413 BPredUnit::squash(const InstSeqNum &squashed_sn,
414  const TheISA::PCState &corrTarget,
415  bool actually_taken, ThreadID tid)
416 {
417  // Now that we know that a branch was mispredicted, we need to undo
418  // all the branches that have been seen up until this branch and
419  // fix up everything.
420  // NOTE: This should be call conceivably in 2 scenarios:
421  // (1) After an branch is executed, it updates its status in the ROB
422  // The commit stage then checks the ROB update and sends a signal to
423  // the fetch stage to squash history after the mispredict
424  // (2) In the decode stage, you can find out early if a unconditional
425  // PC-relative, branch was predicted incorrectly. If so, a signal
426  // to the fetch stage is sent to squash history after the mispredict
427 
428  History &pred_hist = predHist[tid];
429 
430  ++condIncorrect;
431  ppMisses->notify(1);
432 
433  DPRINTF(Branch, "[tid:%i] Squashing from sequence number %i, "
434  "setting target to %s\n", tid, squashed_sn, corrTarget);
435 
436  // Squash All Branches AFTER this mispredicted branch
437  squash(squashed_sn, tid);
438 
439  // If there's a squash due to a syscall, there may not be an entry
440  // corresponding to the squash. In that case, don't bother trying to
441  // fix up the entry.
442  if (!pred_hist.empty()) {
443 
444  auto hist_it = pred_hist.begin();
445  //HistoryIt hist_it = find(pred_hist.begin(), pred_hist.end(),
446  // squashed_sn);
447 
448  //assert(hist_it != pred_hist.end());
449  if (pred_hist.front().seqNum != squashed_sn) {
450  DPRINTF(Branch, "Front sn %i != Squash sn %i\n",
451  pred_hist.front().seqNum, squashed_sn);
452 
453  assert(pred_hist.front().seqNum == squashed_sn);
454  }
455 
456 
457  if ((*hist_it).usedRAS) {
458  ++RASIncorrect;
459  DPRINTF(Branch,
460  "[tid:%i] [squash sn:%llu] Incorrect RAS [sn:%llu]\n",
461  tid, squashed_sn, hist_it->seqNum);
462  }
463 
464  // There are separate functions for in-order and out-of-order
465  // branch prediction, but not for update. Therefore, this
466  // call should take into account that the mispredicted branch may
467  // be on the wrong path (i.e., OoO execution), and that the counter
468  // counter table(s) should not be updated. Thus, this call should
469  // restore the state of the underlying predictor, for instance the
470  // local/global histories. The counter tables will be updated when
471  // the branch actually commits.
472 
473  // Remember the correct direction for the update at commit.
474  pred_hist.front().predTaken = actually_taken;
475  pred_hist.front().target = corrTarget.instAddr();
476 
477  update(tid, (*hist_it).pc, actually_taken,
478  pred_hist.front().bpHistory, true, pred_hist.front().inst,
479  corrTarget.instAddr());
480 
481  if (iPred) {
483  pred_hist.front().indirectHistory, actually_taken);
484  }
485 
486  if (actually_taken) {
487  if (hist_it->wasReturn && !hist_it->usedRAS) {
488  DPRINTF(Branch, "[tid:%i] [squash sn:%llu] "
489  "Incorrectly predicted "
490  "return [sn:%llu] PC: %#x\n", tid, squashed_sn,
491  hist_it->seqNum,
492  hist_it->pc);
493  RAS[tid].pop();
494  hist_it->usedRAS = true;
495  }
496  if (hist_it->wasIndirect) {
498  if (iPred) {
500  hist_it->seqNum, pred_hist.front().indirectHistory,
501  corrTarget, tid);
502  }
503  } else {
504  DPRINTF(Branch,"[tid:%i] [squash sn:%llu] "
505  "BTB Update called for [sn:%llu] "
506  "PC %#x\n", tid, squashed_sn,
507  hist_it->seqNum, hist_it->pc);
508 
509  BTB.update((*hist_it).pc, corrTarget, tid);
510  }
511  } else {
512  //Actually not Taken
513  if (hist_it->usedRAS) {
514  DPRINTF(Branch,
515  "[tid:%i] [squash sn:%llu] Incorrectly predicted "
516  "return [sn:%llu] PC: %#x Restoring RAS\n", tid,
517  squashed_sn,
518  hist_it->seqNum, hist_it->pc);
519  DPRINTF(Branch,
520  "[tid:%i] [squash sn:%llu] Restoring top of RAS "
521  "to: %i, target: %s\n", tid, squashed_sn,
522  hist_it->RASIndex, hist_it->RASTarget);
523  RAS[tid].restore(hist_it->RASIndex, hist_it->RASTarget);
524  hist_it->usedRAS = false;
525  } else if (hist_it->wasCall && hist_it->pushedRAS) {
526  //Was a Call but predicated false. Pop RAS here
527  DPRINTF(Branch,
528  "[tid:%i] [squash sn:%llu] "
529  "Incorrectly predicted "
530  "Call [sn:%llu] PC: %s Popping RAS\n",
531  tid, squashed_sn,
532  hist_it->seqNum, hist_it->pc);
533  RAS[tid].pop();
534  hist_it->pushedRAS = false;
535  }
536  }
537  } else {
538  DPRINTF(Branch, "[tid:%i] [sn:%llu] pred_hist empty, can't "
539  "update\n", tid, squashed_sn);
540  }
541 }
542 
543 void
545 {
546  int i = 0;
547  for (const auto& ph : predHist) {
548  if (!ph.empty()) {
549  auto pred_hist_it = ph.begin();
550 
551  cprintf("predHist[%i].size(): %i\n", i++, ph.size());
552 
553  while (pred_hist_it != ph.end()) {
554  cprintf("sn:%llu], PC:%#x, tid:%i, predTaken:%i, "
555  "bpHistory:%#x\n",
556  pred_hist_it->seqNum, pred_hist_it->pc,
557  pred_hist_it->tid, pred_hist_it->predTaken,
558  pred_hist_it->bpHistory);
559  pred_hist_it++;
560  }
561 
562  cprintf("\n");
563  }
564  }
565 }
566 
#define DPRINTF(x,...)
Definition: trace.hh:225
virtual void deleteIndirectInfo(ThreadID tid, void *indirect_history)=0
Stats::Scalar indirectHits
Stat for the number of indirect target hits.
Definition: bpred_unit.hh:308
virtual void recordIndirect(Addr br_addr, Addr tgt_addr, InstSeqNum seq_num, ThreadID tid)=0
Bitfield< 7 > i
Stats::Scalar BTBHits
Stat for number of BTB hits.
Definition: bpred_unit.hh:295
virtual void genIndirectInfo(ThreadID tid, void *&indirect_history)=0
PCState buildRetPC(const PCState &curPC, const PCState &callPC)
Definition: utility.hh:59
Stats::Scalar usedRAS
Stat for number of times the RAS is used to get a target.
Definition: bpred_unit.hh:301
virtual void updateDirectionInfo(ThreadID tid, bool actually_taken)=0
BranchPredictorParams Params
Definition: bpred_unit.hh:65
std::vector< History > predHist
The per-thread predictor history.
Definition: bpred_unit.hh:275
void update(const InstSeqNum &done_sn, ThreadID tid)
Tells the branch predictor to commit any updates until the given sequence number. ...
Definition: bpred_unit.cc:345
IndirectPredictor * iPred
The indirect target predictor.
Definition: bpred_unit.hh:284
bool isReturn() const
Definition: static_inst.hh:177
Stats::Scalar condIncorrect
Stat for number of conditional branches predicted incorrectly.
Definition: bpred_unit.hh:291
Stats::Scalar BTBCorrect
Stat for number of times the BTB is correct.
Definition: bpred_unit.hh:297
bool isDirectCtrl() const
Definition: static_inst.hh:178
bool isUncondCtrl() const
Definition: static_inst.hh:181
virtual void commit(InstSeqNum seq_num, ThreadID tid, void *indirect_history)=0
void regProbePoints() override
Register probe points for this object.
Definition: bpred_unit.cc:154
Bitfield< 4 > pc
virtual void changeDirectionPrediction(ThreadID tid, void *indirect_history, bool actually_taken)=0
Stats::Formula BTBHitPct
Stat for percent times an entry in BTB found.
Definition: bpred_unit.hh:299
void dump()
Definition: bpred_unit.cc:544
Stats::Scalar indirectMisses
Stat for the number of indirect target misses.
Definition: bpred_unit.hh:310
std::unique_ptr< PMU > PMUUPtr
Definition: pmu.hh:56
virtual void uncondBranch(ThreadID tid, Addr pc, void *&bp_history)=0
Stats::Scalar condPredicted
Stat for number of conditional branches predicted.
Definition: bpred_unit.hh:289
virtual bool lookup(Addr br_addr, TheISA::PCState &br_target, ThreadID tid)=0
virtual void squash(InstSeqNum seq_num, ThreadID tid)=0
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...
Stats::Scalar BTBLookups
Stat for number of BTB lookups.
Definition: bpred_unit.hh:293
bool predict(const StaticInstPtr &inst, const InstSeqNum &seqNum, TheISA::PCState &pc, ThreadID tid)
Predicts whether or not the instruction is a taken branch, and the target of the branch if it is take...
Definition: bpred_unit.cc:170
uint64_t InstSeqNum
Definition: inst_seq.hh:37
bool isCall() const
Definition: static_inst.hh:176
ProbePoints::PMUUPtr pmuProbePoint(const char *name)
Helper method to instantiate probe points belonging to this object.
Definition: bpred_unit.cc:145
DefaultBTB BTB
The BTB.
Definition: bpred_unit.hh:278
void advancePC(PCState &pc, const StaticInstPtr &inst)
Definition: utility.hh:393
void update(Addr instPC, const TheISA::PCState &targetPC, ThreadID tid)
Updates the BTB with the target of a branch.
Definition: btb.cc:128
TheISA::PCState lookup(Addr instPC, ThreadID tid)
Looks up an address in the BTB.
Definition: btb.cc:110
Derived & precision(int _precision)
Set the precision and marks this stat to print at the end of simulation.
Definition: statistics.hh:321
ProbePoints::PMUUPtr ppMisses
Miss-predicted branches.
Definition: bpred_unit.hh:341
void regStats() override
Registers statistics.
Definition: bpred_unit.cc:71
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.
std::vector< ReturnAddrStack > RAS
The per-thread return address stack.
Definition: bpred_unit.hh:281
Stats::Scalar RASIncorrect
Stat for number of times the RAS is incorrect.
Definition: bpred_unit.hh:303
STL deque class.
Definition: stl.hh:44
ProbeManager * getProbeManager()
Get the probe manager for this object.
Definition: sim_object.cc:117
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
Definition: statistics.hh:276
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:225
virtual const std::string name() const
Definition: sim_object.hh:129
ProbePointArg generates a point for the class of Arg.
bool valid(Addr instPC, ThreadID tid)
Checks if a branch is in the BTB.
Definition: btb.cc:89
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: bpred_unit.cc:161
Stats::Scalar indirectMispredicted
Stat for the number of indirect target mispredictions.
Definition: bpred_unit.hh:312
BPredUnit(const Params *p)
Definition: bpred_unit.cc:54
void squash(const InstSeqNum &squashed_sn, ThreadID tid)
Squashes all outstanding updates until a given sequence number.
Definition: bpred_unit.cc:368
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
Definition: statistics.hh:309
virtual void regStats()
Callback to set stat parameters.
Definition: group.cc:64
GenericISA::DelaySlotPCState< MachInst > PCState
Definition: types.hh:41
Stats::Scalar indirectLookups
Stat for the number of indirect target lookups.
Definition: bpred_unit.hh:306
ProbePoints::PMUUPtr ppBranches
Branches seen by the branch predictor.
Definition: bpred_unit.hh:338
Abstract superclass for simulation objects.
Definition: sim_object.hh:93
Stats::Scalar lookups
Stat for number of BP lookups.
Definition: bpred_unit.hh:287
virtual void recordTarget(InstSeqNum seq_num, void *indirect_history, const TheISA::PCState &target, ThreadID tid)=0
void cprintf(const char *format, const Args &...args)
Definition: cprintf.hh:152

Generated on Fri Jul 3 2020 15:53:00 for gem5 by doxygen 1.8.13