gem5  v19.0.0.0
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  * Authors: Kevin Lim
43  */
44 
45 #include "cpu/pred/bpred_unit.hh"
46 
47 #include <algorithm>
48 
49 #include "arch/isa_traits.hh"
50 #include "arch/types.hh"
51 #include "arch/utility.hh"
52 #include "base/trace.hh"
53 #include "config/the_isa.hh"
54 #include "debug/Branch.hh"
55 
57  : SimObject(params),
58  numThreads(params->numThreads),
59  predHist(numThreads),
60  BTB(params->BTBEntries,
61  params->BTBTagSize,
62  params->instShiftAmt,
63  params->numThreads),
64  RAS(numThreads),
65  iPred(params->indirectBranchPred),
66  instShiftAmt(params->instShiftAmt)
67 {
68  for (auto& r : RAS)
69  r.init(params->RASSize);
70 }
71 
72 void
74 {
76 
77  lookups
78  .name(name() + ".lookups")
79  .desc("Number of BP lookups")
80  ;
81 
83  .name(name() + ".condPredicted")
84  .desc("Number of conditional branches predicted")
85  ;
86 
88  .name(name() + ".condIncorrect")
89  .desc("Number of conditional branches incorrect")
90  ;
91 
93  .name(name() + ".BTBLookups")
94  .desc("Number of BTB lookups")
95  ;
96 
97  BTBHits
98  .name(name() + ".BTBHits")
99  .desc("Number of BTB hits")
100  ;
101 
102  BTBCorrect
103  .name(name() + ".BTBCorrect")
104  .desc("Number of correct BTB predictions (this stat may not "
105  "work properly.")
106  ;
107 
108  BTBHitPct
109  .name(name() + ".BTBHitPct")
110  .desc("BTB Hit Percentage")
111  .precision(6);
112  BTBHitPct = (BTBHits / BTBLookups) * 100;
113 
114  usedRAS
115  .name(name() + ".usedRAS")
116  .desc("Number of times the RAS was used to get a target.")
117  ;
118 
120  .name(name() + ".RASInCorrect")
121  .desc("Number of incorrect RAS predictions.")
122  ;
123 
125  .name(name() + ".indirectLookups")
126  .desc("Number of indirect predictor lookups.")
127  ;
128 
130  .name(name() + ".indirectHits")
131  .desc("Number of indirect target hits.")
132  ;
133 
135  .name(name() + ".indirectMisses")
136  .desc("Number of indirect misses.")
137  ;
138 
140  .name(name() + "indirectMispredicted")
141  .desc("Number of mispredicted indirect branches.")
142  ;
143 
144 }
145 
148 {
150  ptr.reset(new ProbePoints::PMU(getProbeManager(), name));
151 
152  return ptr;
153 }
154 
155 void
157 {
158  ppBranches = pmuProbePoint("Branches");
159  ppMisses = pmuProbePoint("Misses");
160 }
161 
162 void
164 {
165  // We shouldn't have any outstanding requests when we resume from
166  // a drained system.
167  for (const auto& ph M5_VAR_USED : predHist)
168  assert(ph.empty());
169 }
170 
171 bool
172 BPredUnit::predict(const StaticInstPtr &inst, const InstSeqNum &seqNum,
174 {
175  // See if branch predictor predicts taken.
176  // If so, get its target addr either from the BTB or the RAS.
177  // Save off record of branch stuff so the RAS can be fixed
178  // up once it's done.
179 
180  bool pred_taken = false;
181  TheISA::PCState target = pc;
182 
183  ++lookups;
184  ppBranches->notify(1);
185 
186  void *bp_history = NULL;
187  void *indirect_history = NULL;
188 
189  if (inst->isUncondCtrl()) {
190  DPRINTF(Branch, "[tid:%i] [sn:%llu] "
191  "Unconditional control\n",
192  tid,seqNum);
193  pred_taken = true;
194  // Tell the BP there was an unconditional branch.
195  uncondBranch(tid, pc.instAddr(), bp_history);
196  } else {
197  ++condPredicted;
198  pred_taken = lookup(tid, pc.instAddr(), bp_history);
199 
200  DPRINTF(Branch, "[tid:%i] [sn:%llu] "
201  "Branch predictor predicted %i for PC %s\n",
202  tid, seqNum, pred_taken, pc);
203  }
204 
205  const bool orig_pred_taken = pred_taken;
206  if (iPred) {
207  iPred->genIndirectInfo(tid, indirect_history);
208  }
209 
210  DPRINTF(Branch, "[tid:%i] [sn:%llu] "
211  "Creating prediction history "
212  "for PC %s\n", tid, seqNum, pc);
213 
214  PredictorHistory predict_record(seqNum, pc.instAddr(), pred_taken,
215  bp_history, indirect_history, tid, inst);
216 
217  // Now lookup in the BTB or RAS.
218  if (pred_taken) {
219  if (inst->isReturn()) {
220  ++usedRAS;
221  predict_record.wasReturn = true;
222  // If it's a function return call, then look up the address
223  // in the RAS.
224  TheISA::PCState rasTop = RAS[tid].top();
225  target = TheISA::buildRetPC(pc, rasTop);
226 
227  // Record the top entry of the RAS, and its index.
228  predict_record.usedRAS = true;
229  predict_record.RASIndex = RAS[tid].topIdx();
230  predict_record.RASTarget = rasTop;
231 
232  RAS[tid].pop();
233 
234  DPRINTF(Branch, "[tid:%i] [sn:%llu] Instruction %s is a return, "
235  "RAS predicted target: %s, RAS index: %i\n",
236  tid, seqNum, pc, target, predict_record.RASIndex);
237  } else {
238  ++BTBLookups;
239 
240  if (inst->isCall()) {
241  RAS[tid].push(pc);
242  predict_record.pushedRAS = true;
243 
244  // Record that it was a call so that the top RAS entry can
245  // be popped off if the speculation is incorrect.
246  predict_record.wasCall = true;
247 
248  DPRINTF(Branch,
249  "[tid:%i] [sn:%llu] Instruction %s was a call, adding "
250  "%s to the RAS index: %i\n",
251  tid, seqNum, pc, pc, RAS[tid].topIdx());
252  }
253 
254  if (inst->isDirectCtrl() || !iPred) {
255  // Check BTB on direct branches
256  if (BTB.valid(pc.instAddr(), tid)) {
257  ++BTBHits;
258  // If it's not a return, use the BTB to get target addr.
259  target = BTB.lookup(pc.instAddr(), tid);
260  DPRINTF(Branch,
261  "[tid:%i] [sn:%llu] Instruction %s predicted "
262  "target is %s\n",
263  tid, seqNum, pc, target);
264  } else {
265  DPRINTF(Branch, "[tid:%i] [sn:%llu] BTB doesn't have a "
266  "valid entry\n",tid,seqNum);
267  pred_taken = false;
268  // The Direction of the branch predictor is altered
269  // because the BTB did not have an entry
270  // The predictor needs to be updated accordingly
271  if (!inst->isCall() && !inst->isReturn()) {
272  btbUpdate(tid, pc.instAddr(), bp_history);
273  DPRINTF(Branch,
274  "[tid:%i] [sn:%llu] btbUpdate "
275  "called for %s\n",
276  tid, seqNum, pc);
277  } else if (inst->isCall() && !inst->isUncondCtrl()) {
278  RAS[tid].pop();
279  predict_record.pushedRAS = false;
280  }
281  TheISA::advancePC(target, inst);
282  }
283  } else {
284  predict_record.wasIndirect = true;
285  ++indirectLookups;
286  //Consult indirect predictor on indirect control
287  if (iPred->lookup(pc.instAddr(), target, tid)) {
288  // Indirect predictor hit
289  ++indirectHits;
290  DPRINTF(Branch,
291  "[tid:%i] [sn:%llu] "
292  "Instruction %s predicted "
293  "indirect target is %s\n",
294  tid, seqNum, pc, target);
295  } else {
296  ++indirectMisses;
297  pred_taken = false;
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:229
virtual void deleteIndirectInfo(ThreadID tid, void *indirect_history)=0
Stats::Scalar indirectHits
Stat for the number of indirect target hits.
Definition: bpred_unit.hh:313
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:300
virtual void genIndirectInfo(ThreadID tid, void *&indirect_history)=0
Stats::Scalar usedRAS
Stat for number of times the RAS is used to get a target.
Definition: bpred_unit.hh:306
virtual void updateDirectionInfo(ThreadID tid, bool actually_taken)=0
virtual void regStats()
Callback to set stat parameters.
Definition: group.cc:66
BranchPredictorParams Params
Definition: bpred_unit.hh:70
std::vector< History > predHist
The per-thread predictor history.
Definition: bpred_unit.hh:280
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:289
bool isReturn() const
Definition: static_inst.hh:175
Stats::Scalar condIncorrect
Stat for number of conditional branches predicted incorrectly.
Definition: bpred_unit.hh:296
Stats::Scalar BTBCorrect
Stat for number of times the BTB is correct.
Definition: bpred_unit.hh:302
bool isDirectCtrl() const
Definition: static_inst.hh:176
bool isUncondCtrl() const
Definition: static_inst.hh:179
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:156
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:304
void dump()
Definition: bpred_unit.cc:544
Stats::Scalar indirectMisses
Stat for the number of indirect target misses.
Definition: bpred_unit.hh:315
std::unique_ptr< PMU > PMUUPtr
Definition: pmu.hh:57
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:294
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:298
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:172
uint64_t InstSeqNum
Definition: inst_seq.hh:40
bool isCall() const
Definition: static_inst.hh:174
ProbePoints::PMUUPtr pmuProbePoint(const char *name)
Helper method to instantiate probe points belonging to this object.
Definition: bpred_unit.cc:147
DefaultBTB BTB
The BTB.
Definition: bpred_unit.hh:283
void update(Addr instPC, const TheISA::PCState &targetPC, ThreadID tid)
Updates the BTB with the target of a branch.
Definition: btb.cc:130
TheISA::PCState lookup(Addr instPC, ThreadID tid)
Looks up an address in the BTB.
Definition: btb.cc:112
Derived & precision(int _precision)
Set the precision and marks this stat to print at the end of simulation.
Definition: statistics.hh:324
ProbePoints::PMUUPtr ppMisses
Miss-predicted branches.
Definition: bpred_unit.hh:346
virtual const std::string name() const
Definition: sim_object.hh:120
void advancePC(PCState &pc, const StaticInstPtr &inst)
Definition: utility.hh:98
void regStats() override
Registers statistics.
Definition: bpred_unit.cc:73
PCState buildRetPC(const PCState &curPC, const PCState &callPC)
Definition: utility.hh:46
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:286
Stats::Scalar RASIncorrect
Stat for number of times the RAS is incorrect.
Definition: bpred_unit.hh:308
STL deque class.
Definition: stl.hh:47
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
Definition: statistics.hh:279
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:227
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:91
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: bpred_unit.cc:163
GenericISA::SimplePCState< MachInst > PCState
Definition: types.hh:43
ProbeManager * getProbeManager()
Get the probe manager for this object.
Definition: sim_object.cc:120
Stats::Scalar indirectMispredicted
Stat for the number of indirect target mispredictions.
Definition: bpred_unit.hh:317
BPredUnit(const Params *p)
Definition: bpred_unit.cc:56
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:312
static const int NumArgumentRegs M5_VAR_USED
Definition: process.cc:84
Stats::Scalar indirectLookups
Stat for the number of indirect target lookups.
Definition: bpred_unit.hh:311
ProbePoints::PMUUPtr ppBranches
Branches seen by the branch predictor.
Definition: bpred_unit.hh:343
Abstract superclass for simulation objects.
Definition: sim_object.hh:96
Stats::Scalar lookups
Stat for number of BP lookups.
Definition: bpred_unit.hh:292
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:156

Generated on Fri Feb 28 2020 16:26:59 for gem5 by doxygen 1.8.13