loop_predictor.cc revision 14081
113627Sjavier.bueno@metempsy.com/* 213627Sjavier.bueno@metempsy.com * Copyright (c) 2014 The University of Wisconsin 313627Sjavier.bueno@metempsy.com * 413627Sjavier.bueno@metempsy.com * Copyright (c) 2006 INRIA (Institut National de Recherche en 513627Sjavier.bueno@metempsy.com * Informatique et en Automatique / French National Research Institute 613627Sjavier.bueno@metempsy.com * for Computer Science and Applied Mathematics) 713627Sjavier.bueno@metempsy.com * 813627Sjavier.bueno@metempsy.com * All rights reserved. 913627Sjavier.bueno@metempsy.com * 1013627Sjavier.bueno@metempsy.com * Redistribution and use in source and binary forms, with or without 1113627Sjavier.bueno@metempsy.com * modification, are permitted provided that the following conditions are 1213627Sjavier.bueno@metempsy.com * met: redistributions of source code must retain the above copyright 1313627Sjavier.bueno@metempsy.com * notice, this list of conditions and the following disclaimer; 1413627Sjavier.bueno@metempsy.com * redistributions in binary form must reproduce the above copyright 1513627Sjavier.bueno@metempsy.com * notice, this list of conditions and the following disclaimer in the 1613627Sjavier.bueno@metempsy.com * documentation and/or other materials provided with the distribution; 1713627Sjavier.bueno@metempsy.com * neither the name of the copyright holders nor the names of its 1813627Sjavier.bueno@metempsy.com * contributors may be used to endorse or promote products derived from 1913627Sjavier.bueno@metempsy.com * this software without specific prior written permission. 2013627Sjavier.bueno@metempsy.com * 2113627Sjavier.bueno@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2213627Sjavier.bueno@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2313627Sjavier.bueno@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2413627Sjavier.bueno@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2513627Sjavier.bueno@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2613627Sjavier.bueno@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2713627Sjavier.bueno@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2813627Sjavier.bueno@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2913627Sjavier.bueno@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3013627Sjavier.bueno@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3113627Sjavier.bueno@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3213627Sjavier.bueno@metempsy.com * 3313627Sjavier.bueno@metempsy.com * Authors: Vignyan Reddy, Dibakar Gope and Arthur Perais, 3413627Sjavier.bueno@metempsy.com * from André Seznec's code. 3513627Sjavier.bueno@metempsy.com */ 3613627Sjavier.bueno@metempsy.com 3713627Sjavier.bueno@metempsy.com#include "cpu/pred/loop_predictor.hh" 3813627Sjavier.bueno@metempsy.com 3913685Sjavier.bueno@metempsy.com#include "base/random.hh" 4013685Sjavier.bueno@metempsy.com#include "debug/LTage.hh" 4113627Sjavier.bueno@metempsy.com#include "params/LoopPredictor.hh" 4213627Sjavier.bueno@metempsy.com 4313627Sjavier.bueno@metempsy.comLoopPredictor::LoopPredictor(LoopPredictorParams *p) 4413627Sjavier.bueno@metempsy.com : SimObject(p), logSizeLoopPred(p->logSizeLoopPred), 4513627Sjavier.bueno@metempsy.com loopTableAgeBits(p->loopTableAgeBits), 4613627Sjavier.bueno@metempsy.com loopTableConfidenceBits(p->loopTableConfidenceBits), 4713627Sjavier.bueno@metempsy.com loopTableTagBits(p->loopTableTagBits), 4813627Sjavier.bueno@metempsy.com loopTableIterBits(p->loopTableIterBits), 4913627Sjavier.bueno@metempsy.com logLoopTableAssoc(p->logLoopTableAssoc), 5013627Sjavier.bueno@metempsy.com confidenceThreshold((1 << loopTableConfidenceBits) - 1), 5113627Sjavier.bueno@metempsy.com loopTagMask((1 << loopTableTagBits) - 1), 5213627Sjavier.bueno@metempsy.com loopNumIterMask((1 << loopTableIterBits) - 1), 5313627Sjavier.bueno@metempsy.com loopSetMask((1 << (logSizeLoopPred - logLoopTableAssoc)) - 1), 5413627Sjavier.bueno@metempsy.com loopUseCounter(-1), 5513627Sjavier.bueno@metempsy.com withLoopBits(p->withLoopBits), 5613627Sjavier.bueno@metempsy.com useDirectionBit(p->useDirectionBit), 5713627Sjavier.bueno@metempsy.com useSpeculation(p->useSpeculation), 5813627Sjavier.bueno@metempsy.com useHashing(p->useHashing), 5913627Sjavier.bueno@metempsy.com restrictAllocation(p->restrictAllocation), 6013627Sjavier.bueno@metempsy.com initialLoopIter(p->initialLoopIter), 6113627Sjavier.bueno@metempsy.com initialLoopAge(p->initialLoopAge), 6213627Sjavier.bueno@metempsy.com optionalAgeReset(p->optionalAgeReset) 6313627Sjavier.bueno@metempsy.com{ 6413627Sjavier.bueno@metempsy.com assert(initialLoopAge <= ((1 << loopTableAgeBits) - 1)); 6513627Sjavier.bueno@metempsy.com} 6613627Sjavier.bueno@metempsy.com 6713627Sjavier.bueno@metempsy.comvoid 6813627Sjavier.bueno@metempsy.comLoopPredictor::init() 6913627Sjavier.bueno@metempsy.com{ 7013627Sjavier.bueno@metempsy.com // we use uint16_t type for these vales, so they cannot be more than 7113627Sjavier.bueno@metempsy.com // 16 bits 7213627Sjavier.bueno@metempsy.com assert(loopTableTagBits <= 16); 7313627Sjavier.bueno@metempsy.com assert(loopTableIterBits <= 16); 7413627Sjavier.bueno@metempsy.com 7513627Sjavier.bueno@metempsy.com assert(logSizeLoopPred >= logLoopTableAssoc); 7613627Sjavier.bueno@metempsy.com 7713627Sjavier.bueno@metempsy.com ltable = new LoopEntry[ULL(1) << logSizeLoopPred]; 7813627Sjavier.bueno@metempsy.com} 7913627Sjavier.bueno@metempsy.com 8013627Sjavier.bueno@metempsy.comLoopPredictor::BranchInfo* 8113627Sjavier.bueno@metempsy.comLoopPredictor::makeBranchInfo() 8213627Sjavier.bueno@metempsy.com{ 8313627Sjavier.bueno@metempsy.com return new BranchInfo(); 8413627Sjavier.bueno@metempsy.com} 8513627Sjavier.bueno@metempsy.com 8613627Sjavier.bueno@metempsy.comint 8713627Sjavier.bueno@metempsy.comLoopPredictor::lindex(Addr pc_in, unsigned instShiftAmt) const 8813627Sjavier.bueno@metempsy.com{ 8913627Sjavier.bueno@metempsy.com // The loop table is implemented as a linear table 9013627Sjavier.bueno@metempsy.com // If associativity is N (N being 1 << logLoopTableAssoc), 9113627Sjavier.bueno@metempsy.com // the first N entries are for set 0, the next N entries are for set 1, 9213627Sjavier.bueno@metempsy.com // and so on. 9313627Sjavier.bueno@metempsy.com // Thus, this function calculates the set and then it gets left shifted 9413627Sjavier.bueno@metempsy.com // by logLoopTableAssoc in order to return the index of the first of the 9513627Sjavier.bueno@metempsy.com // N entries of the set 9613627Sjavier.bueno@metempsy.com Addr pc = pc_in >> instShiftAmt; 9713627Sjavier.bueno@metempsy.com if (useHashing) { 9813627Sjavier.bueno@metempsy.com pc ^= pc_in; 9913627Sjavier.bueno@metempsy.com } 10013627Sjavier.bueno@metempsy.com return ((pc & loopSetMask) << logLoopTableAssoc); 10113627Sjavier.bueno@metempsy.com} 10213627Sjavier.bueno@metempsy.com 10313627Sjavier.bueno@metempsy.comint 10413627Sjavier.bueno@metempsy.comLoopPredictor::finallindex(int index, int lowPcBits, int way) const 10513627Sjavier.bueno@metempsy.com{ 10613627Sjavier.bueno@metempsy.com return (useHashing ? (index ^ ((lowPcBits >> way) << logLoopTableAssoc)) : 10713627Sjavier.bueno@metempsy.com (index)) 10813627Sjavier.bueno@metempsy.com + way; 10913627Sjavier.bueno@metempsy.com} 11013627Sjavier.bueno@metempsy.com 11113627Sjavier.bueno@metempsy.com//loop prediction: only used if high confidence 11213627Sjavier.bueno@metempsy.combool 11313627Sjavier.bueno@metempsy.comLoopPredictor::getLoop(Addr pc, BranchInfo* bi, bool speculative, 11413627Sjavier.bueno@metempsy.com unsigned instShiftAmt) const 11513627Sjavier.bueno@metempsy.com{ 11613627Sjavier.bueno@metempsy.com bi->loopHit = -1; 11713627Sjavier.bueno@metempsy.com bi->loopPredValid = false; 11813627Sjavier.bueno@metempsy.com bi->loopIndex = lindex(pc, instShiftAmt); 11913627Sjavier.bueno@metempsy.com 12013627Sjavier.bueno@metempsy.com if (useHashing) { 12113627Sjavier.bueno@metempsy.com unsigned pcShift = logSizeLoopPred - logLoopTableAssoc; 12213627Sjavier.bueno@metempsy.com bi->loopIndexB = (pc >> pcShift) & loopSetMask; 12313627Sjavier.bueno@metempsy.com bi->loopTag = (pc >> pcShift) ^ (pc >> (pcShift + loopTableTagBits)); 12413627Sjavier.bueno@metempsy.com bi->loopTag &= loopTagMask; 12513627Sjavier.bueno@metempsy.com } else { 12613627Sjavier.bueno@metempsy.com unsigned pcShift = instShiftAmt + logSizeLoopPred - logLoopTableAssoc; 12713627Sjavier.bueno@metempsy.com bi->loopTag = (pc >> pcShift) & loopTagMask; 12813627Sjavier.bueno@metempsy.com // bi->loopIndexB is not used without hash 12913627Sjavier.bueno@metempsy.com } 13013627Sjavier.bueno@metempsy.com 13113627Sjavier.bueno@metempsy.com for (int i = 0; i < (1 << logLoopTableAssoc); i++) { 13213627Sjavier.bueno@metempsy.com int idx = finallindex(bi->loopIndex, bi->loopIndexB, i); 13313627Sjavier.bueno@metempsy.com if (ltable[idx].tag == bi->loopTag) { 13413627Sjavier.bueno@metempsy.com bi->loopHit = i; 13513627Sjavier.bueno@metempsy.com bi->loopPredValid = calcConf(idx); 13613627Sjavier.bueno@metempsy.com 13713627Sjavier.bueno@metempsy.com uint16_t iter = speculative ? ltable[idx].currentIterSpec 13813627Sjavier.bueno@metempsy.com : ltable[idx].currentIter; 13913627Sjavier.bueno@metempsy.com 14013627Sjavier.bueno@metempsy.com if ((iter + 1) == ltable[idx].numIter) { 14113627Sjavier.bueno@metempsy.com return useDirectionBit ? !(ltable[idx].dir) : false; 14213627Sjavier.bueno@metempsy.com } else { 14313627Sjavier.bueno@metempsy.com return useDirectionBit ? (ltable[idx].dir) : true; 14413627Sjavier.bueno@metempsy.com } 14513627Sjavier.bueno@metempsy.com } 14613627Sjavier.bueno@metempsy.com } 14713627Sjavier.bueno@metempsy.com return false; 14813627Sjavier.bueno@metempsy.com} 14913627Sjavier.bueno@metempsy.com 15013627Sjavier.bueno@metempsy.combool 15113627Sjavier.bueno@metempsy.comLoopPredictor::calcConf(int index) const 15213627Sjavier.bueno@metempsy.com{ 15313627Sjavier.bueno@metempsy.com return ltable[index].confidence == confidenceThreshold; 15413627Sjavier.bueno@metempsy.com} 15513627Sjavier.bueno@metempsy.com 15613627Sjavier.bueno@metempsy.comvoid 15713627Sjavier.bueno@metempsy.comLoopPredictor::specLoopUpdate(bool taken, BranchInfo* bi) 15813627Sjavier.bueno@metempsy.com{ 15913627Sjavier.bueno@metempsy.com if (bi->loopHit>=0) { 16013627Sjavier.bueno@metempsy.com int index = finallindex(bi->loopIndex, bi->loopIndexB, bi->loopHit); 16113627Sjavier.bueno@metempsy.com if (taken != ltable[index].dir) { 16213627Sjavier.bueno@metempsy.com ltable[index].currentIterSpec = 0; 16313627Sjavier.bueno@metempsy.com } else { 16413627Sjavier.bueno@metempsy.com ltable[index].currentIterSpec = 16513627Sjavier.bueno@metempsy.com (ltable[index].currentIterSpec + 1) & loopNumIterMask; 16613627Sjavier.bueno@metempsy.com } 16713627Sjavier.bueno@metempsy.com } 16813627Sjavier.bueno@metempsy.com} 16913627Sjavier.bueno@metempsy.com 17013627Sjavier.bueno@metempsy.combool 17113685Sjavier.bueno@metempsy.comLoopPredictor::optionalAgeInc() const 17213627Sjavier.bueno@metempsy.com{ 17313627Sjavier.bueno@metempsy.com return false; 17413627Sjavier.bueno@metempsy.com} 17513627Sjavier.bueno@metempsy.com 17613627Sjavier.bueno@metempsy.comvoid 17713685Sjavier.bueno@metempsy.comLoopPredictor::loopUpdate(Addr pc, bool taken, BranchInfo* bi, bool tage_pred) 17813627Sjavier.bueno@metempsy.com{ 17913627Sjavier.bueno@metempsy.com int idx = finallindex(bi->loopIndex, bi->loopIndexB, bi->loopHit); 18013627Sjavier.bueno@metempsy.com if (bi->loopHit >= 0) { 18113627Sjavier.bueno@metempsy.com //already a hit 18213627Sjavier.bueno@metempsy.com if (bi->loopPredValid) { 18313627Sjavier.bueno@metempsy.com if (taken != bi->loopPred) { 18413627Sjavier.bueno@metempsy.com // free the entry 18513627Sjavier.bueno@metempsy.com ltable[idx].numIter = 0; 18613627Sjavier.bueno@metempsy.com ltable[idx].age = 0; 18713627Sjavier.bueno@metempsy.com ltable[idx].confidence = 0; 18813627Sjavier.bueno@metempsy.com ltable[idx].currentIter = 0; 18913627Sjavier.bueno@metempsy.com return; 19013685Sjavier.bueno@metempsy.com } else if (bi->loopPred != tage_pred || optionalAgeInc()) { 19113685Sjavier.bueno@metempsy.com DPRINTF(LTage, "Loop Prediction success:%lx\n",pc); 19213627Sjavier.bueno@metempsy.com unsignedCtrUpdate(ltable[idx].age, true, loopTableAgeBits); 19313627Sjavier.bueno@metempsy.com } 19413627Sjavier.bueno@metempsy.com } 19513627Sjavier.bueno@metempsy.com 19613627Sjavier.bueno@metempsy.com ltable[idx].currentIter = 19713627Sjavier.bueno@metempsy.com (ltable[idx].currentIter + 1) & loopNumIterMask; 19813627Sjavier.bueno@metempsy.com if (ltable[idx].currentIter > ltable[idx].numIter) { 19913627Sjavier.bueno@metempsy.com ltable[idx].confidence = 0; 20013627Sjavier.bueno@metempsy.com if (ltable[idx].numIter != 0) { 20113627Sjavier.bueno@metempsy.com // free the entry 20213627Sjavier.bueno@metempsy.com ltable[idx].numIter = 0; 20313627Sjavier.bueno@metempsy.com if (optionalAgeReset) { 20413627Sjavier.bueno@metempsy.com ltable[idx].age = 0; 20513627Sjavier.bueno@metempsy.com } 20613627Sjavier.bueno@metempsy.com } 20713627Sjavier.bueno@metempsy.com } 20813627Sjavier.bueno@metempsy.com 20913627Sjavier.bueno@metempsy.com if (taken != (useDirectionBit ? ltable[idx].dir : true)) { 21013627Sjavier.bueno@metempsy.com if (ltable[idx].currentIter == ltable[idx].numIter) { 21113685Sjavier.bueno@metempsy.com DPRINTF(LTage, "Loop End predicted successfully:%lx\n", pc); 21213627Sjavier.bueno@metempsy.com unsignedCtrUpdate(ltable[idx].confidence, true, 21313627Sjavier.bueno@metempsy.com loopTableConfidenceBits); 21413627Sjavier.bueno@metempsy.com //just do not predict when the loop count is 1 or 2 21513627Sjavier.bueno@metempsy.com if (ltable[idx].numIter < 3) { 21613627Sjavier.bueno@metempsy.com // free the entry 21713627Sjavier.bueno@metempsy.com ltable[idx].dir = taken; // ignored if no useDirectionBit 21813627Sjavier.bueno@metempsy.com ltable[idx].numIter = 0; 21913627Sjavier.bueno@metempsy.com ltable[idx].age = 0; 22013627Sjavier.bueno@metempsy.com ltable[idx].confidence = 0; 22113627Sjavier.bueno@metempsy.com } 22213627Sjavier.bueno@metempsy.com } else { 22313685Sjavier.bueno@metempsy.com DPRINTF(LTage, "Loop End predicted incorrectly:%lx\n", pc); 22413627Sjavier.bueno@metempsy.com if (ltable[idx].numIter == 0) { 22513627Sjavier.bueno@metempsy.com // first complete nest; 22613627Sjavier.bueno@metempsy.com ltable[idx].confidence = 0; 22713627Sjavier.bueno@metempsy.com ltable[idx].numIter = ltable[idx].currentIter; 22813627Sjavier.bueno@metempsy.com } else { 22913627Sjavier.bueno@metempsy.com //not the same number of iterations as last time: free the 23013627Sjavier.bueno@metempsy.com //entry 23113627Sjavier.bueno@metempsy.com ltable[idx].numIter = 0; 23213627Sjavier.bueno@metempsy.com if (optionalAgeReset) { 23313627Sjavier.bueno@metempsy.com ltable[idx].age = 0; 23413627Sjavier.bueno@metempsy.com } 23513627Sjavier.bueno@metempsy.com ltable[idx].confidence = 0; 23613627Sjavier.bueno@metempsy.com } 23713627Sjavier.bueno@metempsy.com } 23813627Sjavier.bueno@metempsy.com ltable[idx].currentIter = 0; 23913627Sjavier.bueno@metempsy.com } 24013627Sjavier.bueno@metempsy.com 24113627Sjavier.bueno@metempsy.com } else if (useDirectionBit ? (bi->predTaken != taken) : taken) { 24213685Sjavier.bueno@metempsy.com if ((random_mt.random<int>() & 3) == 0 || !restrictAllocation) { 24313627Sjavier.bueno@metempsy.com //try to allocate an entry on taken branch 24413685Sjavier.bueno@metempsy.com int nrand = random_mt.random<int>(); 24513627Sjavier.bueno@metempsy.com for (int i = 0; i < (1 << logLoopTableAssoc); i++) { 24613627Sjavier.bueno@metempsy.com int loop_hit = (nrand + i) & ((1 << logLoopTableAssoc) - 1); 24713627Sjavier.bueno@metempsy.com idx = finallindex(bi->loopIndex, bi->loopIndexB, loop_hit); 24813627Sjavier.bueno@metempsy.com if (ltable[idx].age == 0) { 24913685Sjavier.bueno@metempsy.com DPRINTF(LTage, 25013685Sjavier.bueno@metempsy.com "Allocating loop pred entry for branch %lx\n", 25113685Sjavier.bueno@metempsy.com pc); 25213627Sjavier.bueno@metempsy.com ltable[idx].dir = !taken; // ignored if no useDirectionBit 25313627Sjavier.bueno@metempsy.com ltable[idx].tag = bi->loopTag; 25413627Sjavier.bueno@metempsy.com ltable[idx].numIter = 0; 25513627Sjavier.bueno@metempsy.com ltable[idx].age = initialLoopAge; 25613627Sjavier.bueno@metempsy.com ltable[idx].confidence = 0; 25713627Sjavier.bueno@metempsy.com ltable[idx].currentIter = initialLoopIter; 25813627Sjavier.bueno@metempsy.com break; 25913627Sjavier.bueno@metempsy.com 26013627Sjavier.bueno@metempsy.com } else { 26113627Sjavier.bueno@metempsy.com ltable[idx].age--; 26213627Sjavier.bueno@metempsy.com } 26313627Sjavier.bueno@metempsy.com if (restrictAllocation) { 26413627Sjavier.bueno@metempsy.com break; 26513627Sjavier.bueno@metempsy.com } 26613627Sjavier.bueno@metempsy.com } 26713627Sjavier.bueno@metempsy.com } 26813627Sjavier.bueno@metempsy.com } 26913627Sjavier.bueno@metempsy.com} 27013627Sjavier.bueno@metempsy.com 27113627Sjavier.bueno@metempsy.combool 27213627Sjavier.bueno@metempsy.comLoopPredictor::loopPredict(ThreadID tid, Addr branch_pc, bool cond_branch, 27313627Sjavier.bueno@metempsy.com BranchInfo* bi, bool prev_pred_taken, unsigned instShiftAmt) 27413627Sjavier.bueno@metempsy.com{ 27513627Sjavier.bueno@metempsy.com bool pred_taken = prev_pred_taken; 27613627Sjavier.bueno@metempsy.com if (cond_branch) { 27713627Sjavier.bueno@metempsy.com // loop prediction 27813627Sjavier.bueno@metempsy.com bi->loopPred = getLoop(branch_pc, bi, useSpeculation, instShiftAmt); 27913627Sjavier.bueno@metempsy.com 28013627Sjavier.bueno@metempsy.com if ((loopUseCounter >= 0) && bi->loopPredValid) { 28113627Sjavier.bueno@metempsy.com pred_taken = bi->loopPred; 28213627Sjavier.bueno@metempsy.com bi->loopPredUsed = true; 28313627Sjavier.bueno@metempsy.com } 28413627Sjavier.bueno@metempsy.com 28513627Sjavier.bueno@metempsy.com if (useSpeculation) { 28613627Sjavier.bueno@metempsy.com specLoopUpdate(pred_taken, bi); 28713627Sjavier.bueno@metempsy.com } 28813627Sjavier.bueno@metempsy.com } 28913627Sjavier.bueno@metempsy.com 29013627Sjavier.bueno@metempsy.com return pred_taken; 29113627Sjavier.bueno@metempsy.com} 29213627Sjavier.bueno@metempsy.com 29313627Sjavier.bueno@metempsy.comvoid 29413627Sjavier.bueno@metempsy.comLoopPredictor::squash(ThreadID tid, BranchInfo *bi) 29513627Sjavier.bueno@metempsy.com{ 29613627Sjavier.bueno@metempsy.com if (bi->loopHit >= 0) { 29713627Sjavier.bueno@metempsy.com int idx = finallindex(bi->loopIndex, 29813627Sjavier.bueno@metempsy.com bi->loopIndexB, 29913627Sjavier.bueno@metempsy.com bi->loopHit); 30013627Sjavier.bueno@metempsy.com ltable[idx].currentIterSpec = bi->currentIter; 30113627Sjavier.bueno@metempsy.com } 30213627Sjavier.bueno@metempsy.com} 30313627Sjavier.bueno@metempsy.com 30413627Sjavier.bueno@metempsy.comvoid 30513627Sjavier.bueno@metempsy.comLoopPredictor::squashLoop(BranchInfo* bi) 30613627Sjavier.bueno@metempsy.com{ 30713627Sjavier.bueno@metempsy.com if (bi->loopHit >= 0) { 30813627Sjavier.bueno@metempsy.com int idx = finallindex(bi->loopIndex, 30913627Sjavier.bueno@metempsy.com bi->loopIndexB, 31013627Sjavier.bueno@metempsy.com bi->loopHit); 31113627Sjavier.bueno@metempsy.com ltable[idx].currentIterSpec = bi->currentIter; 31213627Sjavier.bueno@metempsy.com } 31313627Sjavier.bueno@metempsy.com} 31413627Sjavier.bueno@metempsy.com 31513627Sjavier.bueno@metempsy.comvoid 31613627Sjavier.bueno@metempsy.comLoopPredictor::updateStats(bool taken, BranchInfo* bi) 31713627Sjavier.bueno@metempsy.com{ 31813627Sjavier.bueno@metempsy.com if (taken == bi->loopPred) { 31913627Sjavier.bueno@metempsy.com loopPredictorCorrect++; 32013627Sjavier.bueno@metempsy.com } else { 32113627Sjavier.bueno@metempsy.com loopPredictorWrong++; 32213627Sjavier.bueno@metempsy.com } 32313627Sjavier.bueno@metempsy.com} 32413627Sjavier.bueno@metempsy.com 32513627Sjavier.bueno@metempsy.comvoid 32613627Sjavier.bueno@metempsy.comLoopPredictor::condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken, 32713627Sjavier.bueno@metempsy.com bool tage_pred, BranchInfo* bi, 32813685Sjavier.bueno@metempsy.com unsigned instShiftAmt) 32913627Sjavier.bueno@metempsy.com{ 33013627Sjavier.bueno@metempsy.com if (useSpeculation) { 33113627Sjavier.bueno@metempsy.com // recalculate loop prediction without speculation 33213627Sjavier.bueno@metempsy.com // It is ok to overwrite the loop prediction fields in bi 33313627Sjavier.bueno@metempsy.com // as the stats have already been updated with the previous 33413627Sjavier.bueno@metempsy.com // values 33513627Sjavier.bueno@metempsy.com bi->loopPred = getLoop(branch_pc, bi, false, instShiftAmt); 33613627Sjavier.bueno@metempsy.com } 33713627Sjavier.bueno@metempsy.com 33813627Sjavier.bueno@metempsy.com if (bi->loopPredValid) { 33913627Sjavier.bueno@metempsy.com if (bi->predTaken != bi->loopPred) { 34013627Sjavier.bueno@metempsy.com signedCtrUpdate(loopUseCounter, 34113627Sjavier.bueno@metempsy.com (bi->loopPred == taken), 34213627Sjavier.bueno@metempsy.com withLoopBits); 34313627Sjavier.bueno@metempsy.com } 34413627Sjavier.bueno@metempsy.com } 34513627Sjavier.bueno@metempsy.com 34613685Sjavier.bueno@metempsy.com loopUpdate(branch_pc, taken, bi, tage_pred); 34713627Sjavier.bueno@metempsy.com} 34813627Sjavier.bueno@metempsy.com 34913627Sjavier.bueno@metempsy.comvoid 35013627Sjavier.bueno@metempsy.comLoopPredictor::regStats() 35113627Sjavier.bueno@metempsy.com{ 35213627Sjavier.bueno@metempsy.com loopPredictorCorrect 35313627Sjavier.bueno@metempsy.com .name(name() + ".loopPredictorCorrect") 35413627Sjavier.bueno@metempsy.com .desc("Number of times the loop predictor is the provider and " 35513627Sjavier.bueno@metempsy.com "the prediction is correct"); 35613627Sjavier.bueno@metempsy.com 35713627Sjavier.bueno@metempsy.com loopPredictorWrong 35813627Sjavier.bueno@metempsy.com .name(name() + ".loopPredictorWrong") 35913627Sjavier.bueno@metempsy.com .desc("Number of times the loop predictor is the provider and " 36013627Sjavier.bueno@metempsy.com "the prediction is wrong"); 36113627Sjavier.bueno@metempsy.com} 36213627Sjavier.bueno@metempsy.com 36314081Sjavier.bueno@metempsy.comsize_t 36414081Sjavier.bueno@metempsy.comLoopPredictor::getSizeInBits() const 36514081Sjavier.bueno@metempsy.com{ 36614081Sjavier.bueno@metempsy.com return (1ULL << logSizeLoopPred) * 36714081Sjavier.bueno@metempsy.com ((useSpeculation ? 3 : 2) * loopTableIterBits + 36814081Sjavier.bueno@metempsy.com loopTableConfidenceBits + loopTableTagBits + 36914081Sjavier.bueno@metempsy.com loopTableAgeBits + useDirectionBit); 37014081Sjavier.bueno@metempsy.com} 37114081Sjavier.bueno@metempsy.com 37213627Sjavier.bueno@metempsy.comLoopPredictor * 37313627Sjavier.bueno@metempsy.comLoopPredictorParams::create() 37413627Sjavier.bueno@metempsy.com{ 37513627Sjavier.bueno@metempsy.com return new LoopPredictor(this); 37613627Sjavier.bueno@metempsy.com} 377