bpred_unit.cc (13831:4fba790d88be) bpred_unit.cc (13957:25e9c77a8a99)
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

--- 48 unchanged lines hidden (view full) ---

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),
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

--- 48 unchanged lines hidden (view full) ---

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 useIndirect(params->useIndirect),
66 iPred(params->indirectHashGHR,
67 params->indirectHashTargets,
68 params->indirectSets,
69 params->indirectWays,
70 params->indirectTagSize,
71 params->indirectPathLength,
72 params->instShiftAmt,
73 params->numThreads,
74 params->indirectGHRBits),
65 iPred(params->indirectBranchPred),
75 instShiftAmt(params->instShiftAmt)
76{
77 for (auto& r : RAS)
78 r.init(params->RASSize);
79}
80
81void
82BPredUnit::regStats()

--- 124 unchanged lines hidden (view full) ---

207 pred_taken = lookup(tid, pc.instAddr(), bp_history);
208
209 DPRINTF(Branch, "[tid:%i] [sn:%llu] "
210 "Branch predictor predicted %i for PC %s\n",
211 tid, seqNum, pred_taken, pc);
212 }
213
214 const bool orig_pred_taken = pred_taken;
66 instShiftAmt(params->instShiftAmt)
67{
68 for (auto& r : RAS)
69 r.init(params->RASSize);
70}
71
72void
73BPredUnit::regStats()

--- 124 unchanged lines hidden (view full) ---

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;
215 if (useIndirect) {
216 iPred.genIndirectInfo(tid, indirect_history);
206 if (iPred) {
207 iPred->genIndirectInfo(tid, indirect_history);
217 }
218
219 DPRINTF(Branch, "[tid:%i] [sn:%llu] "
220 "Creating prediction history "
221 "for PC %s\n", tid, seqNum, pc);
222
223 PredictorHistory predict_record(seqNum, pc.instAddr(), pred_taken,
224 bp_history, indirect_history, tid, inst);

--- 30 unchanged lines hidden (view full) ---

255 predict_record.wasCall = true;
256
257 DPRINTF(Branch,
258 "[tid:%i] [sn:%llu] Instruction %s was a call, adding "
259 "%s to the RAS index: %i\n",
260 tid, seqNum, pc, pc, RAS[tid].topIdx());
261 }
262
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);

--- 30 unchanged lines hidden (view full) ---

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
263 if (inst->isDirectCtrl() || !useIndirect) {
254 if (inst->isDirectCtrl() || !iPred) {
264 // Check BTB on direct branches
265 if (BTB.valid(pc.instAddr(), tid)) {
266 ++BTBHits;
267 // If it's not a return, use the BTB to get target addr.
268 target = BTB.lookup(pc.instAddr(), tid);
269 DPRINTF(Branch,
270 "[tid:%i] [sn:%llu] Instruction %s predicted "
271 "target is %s\n",

--- 16 unchanged lines hidden (view full) ---

288 predict_record.pushedRAS = false;
289 }
290 TheISA::advancePC(target, inst);
291 }
292 } else {
293 predict_record.wasIndirect = true;
294 ++indirectLookups;
295 //Consult indirect predictor on indirect control
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",

--- 16 unchanged lines hidden (view full) ---

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
296 if (iPred.lookup(pc.instAddr(), target, tid)) {
287 if (iPred->lookup(pc.instAddr(), target, tid)) {
297 // Indirect predictor hit
298 ++indirectHits;
299 DPRINTF(Branch,
300 "[tid:%i] [sn:%llu] "
301 "Instruction %s predicted "
302 "indirect target is %s\n",
303 tid, seqNum, pc, target);
304 } else {

--- 7 unchanged lines hidden (view full) ---

312 if (!inst->isCall() && !inst->isReturn()) {
313
314 } else if (inst->isCall() && !inst->isUncondCtrl()) {
315 RAS[tid].pop();
316 predict_record.pushedRAS = false;
317 }
318 TheISA::advancePC(target, inst);
319 }
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 {

--- 7 unchanged lines hidden (view full) ---

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 }
320 iPred.recordIndirect(pc.instAddr(), target.instAddr(), seqNum,
311 iPred->recordIndirect(pc.instAddr(), target.instAddr(), seqNum,
321 tid);
322 }
323 }
324 } else {
325 if (inst->isReturn()) {
326 predict_record.wasReturn = true;
327 }
328 TheISA::advancePC(target, inst);
329 }
330 predict_record.target = target.instAddr();
331
332 pc = target;
333
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
334 if (useIndirect) {
325 if (iPred) {
335 // Update the indirect predictor with the direction prediction
336 // Note that this happens after indirect lookup, so it does not use
337 // the new information
338 // Note also that we use orig_pred_taken instead of pred_taken in
339 // as this is the actual outcome of the direction prediction
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
340 iPred.updateDirectionInfo(tid, orig_pred_taken);
331 iPred->updateDirectionInfo(tid, orig_pred_taken);
341 }
342
343 predHist[tid].push_front(predict_record);
344
345 DPRINTF(Branch,
346 "[tid:%i] [sn:%llu] History entry added. "
347 "predHist.size(): %i\n",
348 tid, seqNum, predHist[tid].size());

--- 11 unchanged lines hidden (view full) ---

360 predHist[tid].back().seqNum <= done_sn) {
361 // Update the branch predictor with the correct results.
362 update(tid, predHist[tid].back().pc,
363 predHist[tid].back().predTaken,
364 predHist[tid].back().bpHistory, false,
365 predHist[tid].back().inst,
366 predHist[tid].back().target);
367
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());

--- 11 unchanged lines hidden (view full) ---

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
368 if (useIndirect) {
369 iPred.commit(done_sn, tid, predHist[tid].back().indirectHistory);
359 if (iPred) {
360 iPred->commit(done_sn, tid, predHist[tid].back().indirectHistory);
370 }
371
372 predHist[tid].pop_back();
373 }
374}
375
376void
377BPredUnit::squash(const InstSeqNum &squashed_sn, ThreadID tid)
378{
379 History &pred_hist = predHist[tid];
380
361 }
362
363 predHist[tid].pop_back();
364 }
365}
366
367void
368BPredUnit::squash(const InstSeqNum &squashed_sn, ThreadID tid)
369{
370 History &pred_hist = predHist[tid];
371
381 if (useIndirect) {
382 iPred.squash(squashed_sn, tid);
372 if (iPred) {
373 iPred->squash(squashed_sn, tid);
383 }
384
385 while (!pred_hist.empty() &&
386 pred_hist.front().seqNum > squashed_sn) {
387 if (pred_hist.front().usedRAS) {
388 DPRINTF(Branch, "[tid:%i] [squash sn:%llu]"
389 " Restoring top of RAS to: %i,"
390 " target: %s\n", tid, squashed_sn,

--- 6 unchanged lines hidden (view full) ---

397 DPRINTF(Branch, "[tid:%i] [squash sn:%llu] Squashing"
398 " Call [sn:%llu] PC: %s Popping RAS\n", tid, squashed_sn,
399 pred_hist.front().seqNum, pred_hist.front().pc);
400 RAS[tid].pop();
401 }
402
403 // This call should delete the bpHistory.
404 squash(tid, pred_hist.front().bpHistory);
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,

--- 6 unchanged lines hidden (view full) ---

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);
405 if (useIndirect) {
406 iPred.deleteIndirectInfo(tid, pred_hist.front().indirectHistory);
396 if (iPred) {
397 iPred->deleteIndirectInfo(tid, pred_hist.front().indirectHistory);
407 }
408
409 DPRINTF(Branch, "[tid:%i] [squash sn:%llu] "
410 "Removing history for [sn:%llu] "
411 "PC %#x\n", tid, squashed_sn, pred_hist.front().seqNum,
412 pred_hist.front().pc);
413
414 pred_hist.pop_front();

--- 67 unchanged lines hidden (view full) ---

482 // Remember the correct direction for the update at commit.
483 pred_hist.front().predTaken = actually_taken;
484 pred_hist.front().target = corrTarget.instAddr();
485
486 update(tid, (*hist_it).pc, actually_taken,
487 pred_hist.front().bpHistory, true, pred_hist.front().inst,
488 corrTarget.instAddr());
489
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();

--- 67 unchanged lines hidden (view full) ---

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
490 if (useIndirect) {
491 iPred.changeDirectionPrediction(tid,
481 if (iPred) {
482 iPred->changeDirectionPrediction(tid,
492 pred_hist.front().indirectHistory, actually_taken);
493 }
494
495 if (actually_taken) {
496 if (hist_it->wasReturn && !hist_it->usedRAS) {
497 DPRINTF(Branch, "[tid:%i] [squash sn:%llu] "
498 "Incorrectly predicted "
499 "return [sn:%llu] PC: %#x\n", tid, squashed_sn,
500 hist_it->seqNum,
501 hist_it->pc);
502 RAS[tid].pop();
503 hist_it->usedRAS = true;
504 }
505 if (hist_it->wasIndirect) {
506 ++indirectMispredicted;
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) {
497 ++indirectMispredicted;
507 iPred.recordTarget(
508 hist_it->seqNum, pred_hist.front().indirectHistory,
509 corrTarget, tid);
498 if (iPred) {
499 iPred->recordTarget(
500 hist_it->seqNum, pred_hist.front().indirectHistory,
501 corrTarget, tid);
502 }
510 } else {
511 DPRINTF(Branch,"[tid:%i] [squash sn:%llu] "
512 "BTB Update called for [sn:%llu] "
513 "PC %#x\n", tid, squashed_sn,
514 hist_it->seqNum, hist_it->pc);
515
516 BTB.update((*hist_it).pc, corrTarget, tid);
517 }

--- 56 unchanged lines hidden ---
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 }

--- 56 unchanged lines hidden ---