loop_predictor.cc revision 13627
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 3913627Sjavier.bueno@metempsy.com#include "params/LoopPredictor.hh" 4013627Sjavier.bueno@metempsy.com 4113627Sjavier.bueno@metempsy.comLoopPredictor::LoopPredictor(LoopPredictorParams *p) 4213627Sjavier.bueno@metempsy.com : SimObject(p), logSizeLoopPred(p->logSizeLoopPred), 4313627Sjavier.bueno@metempsy.com loopTableAgeBits(p->loopTableAgeBits), 4413627Sjavier.bueno@metempsy.com loopTableConfidenceBits(p->loopTableConfidenceBits), 4513627Sjavier.bueno@metempsy.com loopTableTagBits(p->loopTableTagBits), 4613627Sjavier.bueno@metempsy.com loopTableIterBits(p->loopTableIterBits), 4713627Sjavier.bueno@metempsy.com logLoopTableAssoc(p->logLoopTableAssoc), 4813627Sjavier.bueno@metempsy.com confidenceThreshold((1 << loopTableConfidenceBits) - 1), 4913627Sjavier.bueno@metempsy.com loopTagMask((1 << loopTableTagBits) - 1), 5013627Sjavier.bueno@metempsy.com loopNumIterMask((1 << loopTableIterBits) - 1), 5113627Sjavier.bueno@metempsy.com loopSetMask((1 << (logSizeLoopPred - logLoopTableAssoc)) - 1), 5213627Sjavier.bueno@metempsy.com loopUseCounter(-1), 5313627Sjavier.bueno@metempsy.com withLoopBits(p->withLoopBits), 5413627Sjavier.bueno@metempsy.com useDirectionBit(p->useDirectionBit), 5513627Sjavier.bueno@metempsy.com useSpeculation(p->useSpeculation), 5613627Sjavier.bueno@metempsy.com useHashing(p->useHashing), 5713627Sjavier.bueno@metempsy.com restrictAllocation(p->restrictAllocation), 5813627Sjavier.bueno@metempsy.com initialLoopIter(p->initialLoopIter), 5913627Sjavier.bueno@metempsy.com initialLoopAge(p->initialLoopAge), 6013627Sjavier.bueno@metempsy.com optionalAgeReset(p->optionalAgeReset) 6113627Sjavier.bueno@metempsy.com{ 6213627Sjavier.bueno@metempsy.com assert(initialLoopAge <= ((1 << loopTableAgeBits) - 1)); 6313627Sjavier.bueno@metempsy.com} 6413627Sjavier.bueno@metempsy.com 6513627Sjavier.bueno@metempsy.comvoid 6613627Sjavier.bueno@metempsy.comLoopPredictor::init() 6713627Sjavier.bueno@metempsy.com{ 6813627Sjavier.bueno@metempsy.com // we use uint16_t type for these vales, so they cannot be more than 6913627Sjavier.bueno@metempsy.com // 16 bits 7013627Sjavier.bueno@metempsy.com assert(loopTableTagBits <= 16); 7113627Sjavier.bueno@metempsy.com assert(loopTableIterBits <= 16); 7213627Sjavier.bueno@metempsy.com 7313627Sjavier.bueno@metempsy.com assert(logSizeLoopPred >= logLoopTableAssoc); 7413627Sjavier.bueno@metempsy.com 7513627Sjavier.bueno@metempsy.com ltable = new LoopEntry[ULL(1) << logSizeLoopPred]; 7613627Sjavier.bueno@metempsy.com} 7713627Sjavier.bueno@metempsy.com 7813627Sjavier.bueno@metempsy.comLoopPredictor::BranchInfo* 7913627Sjavier.bueno@metempsy.comLoopPredictor::makeBranchInfo() 8013627Sjavier.bueno@metempsy.com{ 8113627Sjavier.bueno@metempsy.com return new BranchInfo(); 8213627Sjavier.bueno@metempsy.com} 8313627Sjavier.bueno@metempsy.com 8413627Sjavier.bueno@metempsy.comint 8513627Sjavier.bueno@metempsy.comLoopPredictor::lindex(Addr pc_in, unsigned instShiftAmt) const 8613627Sjavier.bueno@metempsy.com{ 8713627Sjavier.bueno@metempsy.com // The loop table is implemented as a linear table 8813627Sjavier.bueno@metempsy.com // If associativity is N (N being 1 << logLoopTableAssoc), 8913627Sjavier.bueno@metempsy.com // the first N entries are for set 0, the next N entries are for set 1, 9013627Sjavier.bueno@metempsy.com // and so on. 9113627Sjavier.bueno@metempsy.com // Thus, this function calculates the set and then it gets left shifted 9213627Sjavier.bueno@metempsy.com // by logLoopTableAssoc in order to return the index of the first of the 9313627Sjavier.bueno@metempsy.com // N entries of the set 9413627Sjavier.bueno@metempsy.com Addr pc = pc_in >> instShiftAmt; 9513627Sjavier.bueno@metempsy.com if (useHashing) { 9613627Sjavier.bueno@metempsy.com pc ^= pc_in; 9713627Sjavier.bueno@metempsy.com } 9813627Sjavier.bueno@metempsy.com return ((pc & loopSetMask) << logLoopTableAssoc); 9913627Sjavier.bueno@metempsy.com} 10013627Sjavier.bueno@metempsy.com 10113627Sjavier.bueno@metempsy.comint 10213627Sjavier.bueno@metempsy.comLoopPredictor::finallindex(int index, int lowPcBits, int way) const 10313627Sjavier.bueno@metempsy.com{ 10413627Sjavier.bueno@metempsy.com return (useHashing ? (index ^ ((lowPcBits >> way) << logLoopTableAssoc)) : 10513627Sjavier.bueno@metempsy.com (index)) 10613627Sjavier.bueno@metempsy.com + way; 10713627Sjavier.bueno@metempsy.com} 10813627Sjavier.bueno@metempsy.com 10913627Sjavier.bueno@metempsy.com//loop prediction: only used if high confidence 11013627Sjavier.bueno@metempsy.combool 11113627Sjavier.bueno@metempsy.comLoopPredictor::getLoop(Addr pc, BranchInfo* bi, bool speculative, 11213627Sjavier.bueno@metempsy.com unsigned instShiftAmt) const 11313627Sjavier.bueno@metempsy.com{ 11413627Sjavier.bueno@metempsy.com bi->loopHit = -1; 11513627Sjavier.bueno@metempsy.com bi->loopPredValid = false; 11613627Sjavier.bueno@metempsy.com bi->loopIndex = lindex(pc, instShiftAmt); 11713627Sjavier.bueno@metempsy.com 11813627Sjavier.bueno@metempsy.com if (useHashing) { 11913627Sjavier.bueno@metempsy.com unsigned pcShift = logSizeLoopPred - logLoopTableAssoc; 12013627Sjavier.bueno@metempsy.com bi->loopIndexB = (pc >> pcShift) & loopSetMask; 12113627Sjavier.bueno@metempsy.com bi->loopTag = (pc >> pcShift) ^ (pc >> (pcShift + loopTableTagBits)); 12213627Sjavier.bueno@metempsy.com bi->loopTag &= loopTagMask; 12313627Sjavier.bueno@metempsy.com } else { 12413627Sjavier.bueno@metempsy.com unsigned pcShift = instShiftAmt + logSizeLoopPred - logLoopTableAssoc; 12513627Sjavier.bueno@metempsy.com bi->loopTag = (pc >> pcShift) & loopTagMask; 12613627Sjavier.bueno@metempsy.com // bi->loopIndexB is not used without hash 12713627Sjavier.bueno@metempsy.com } 12813627Sjavier.bueno@metempsy.com 12913627Sjavier.bueno@metempsy.com for (int i = 0; i < (1 << logLoopTableAssoc); i++) { 13013627Sjavier.bueno@metempsy.com int idx = finallindex(bi->loopIndex, bi->loopIndexB, i); 13113627Sjavier.bueno@metempsy.com if (ltable[idx].tag == bi->loopTag) { 13213627Sjavier.bueno@metempsy.com bi->loopHit = i; 13313627Sjavier.bueno@metempsy.com bi->loopPredValid = calcConf(idx); 13413627Sjavier.bueno@metempsy.com 13513627Sjavier.bueno@metempsy.com uint16_t iter = speculative ? ltable[idx].currentIterSpec 13613627Sjavier.bueno@metempsy.com : ltable[idx].currentIter; 13713627Sjavier.bueno@metempsy.com 13813627Sjavier.bueno@metempsy.com if ((iter + 1) == ltable[idx].numIter) { 13913627Sjavier.bueno@metempsy.com return useDirectionBit ? !(ltable[idx].dir) : false; 14013627Sjavier.bueno@metempsy.com } else { 14113627Sjavier.bueno@metempsy.com return useDirectionBit ? (ltable[idx].dir) : true; 14213627Sjavier.bueno@metempsy.com } 14313627Sjavier.bueno@metempsy.com } 14413627Sjavier.bueno@metempsy.com } 14513627Sjavier.bueno@metempsy.com return false; 14613627Sjavier.bueno@metempsy.com} 14713627Sjavier.bueno@metempsy.com 14813627Sjavier.bueno@metempsy.combool 14913627Sjavier.bueno@metempsy.comLoopPredictor::calcConf(int index) const 15013627Sjavier.bueno@metempsy.com{ 15113627Sjavier.bueno@metempsy.com return ltable[index].confidence == confidenceThreshold; 15213627Sjavier.bueno@metempsy.com} 15313627Sjavier.bueno@metempsy.com 15413627Sjavier.bueno@metempsy.comvoid 15513627Sjavier.bueno@metempsy.comLoopPredictor::specLoopUpdate(bool taken, BranchInfo* bi) 15613627Sjavier.bueno@metempsy.com{ 15713627Sjavier.bueno@metempsy.com if (bi->loopHit>=0) { 15813627Sjavier.bueno@metempsy.com int index = finallindex(bi->loopIndex, bi->loopIndexB, bi->loopHit); 15913627Sjavier.bueno@metempsy.com if (taken != ltable[index].dir) { 16013627Sjavier.bueno@metempsy.com ltable[index].currentIterSpec = 0; 16113627Sjavier.bueno@metempsy.com } else { 16213627Sjavier.bueno@metempsy.com ltable[index].currentIterSpec = 16313627Sjavier.bueno@metempsy.com (ltable[index].currentIterSpec + 1) & loopNumIterMask; 16413627Sjavier.bueno@metempsy.com } 16513627Sjavier.bueno@metempsy.com } 16613627Sjavier.bueno@metempsy.com} 16713627Sjavier.bueno@metempsy.com 16813627Sjavier.bueno@metempsy.combool 16913627Sjavier.bueno@metempsy.comLoopPredictor::optionalAgeInc(int nrand) const 17013627Sjavier.bueno@metempsy.com{ 17113627Sjavier.bueno@metempsy.com return false; 17213627Sjavier.bueno@metempsy.com} 17313627Sjavier.bueno@metempsy.com 17413627Sjavier.bueno@metempsy.comvoid 17513627Sjavier.bueno@metempsy.comLoopPredictor::loopUpdate(Addr pc, bool taken, BranchInfo* bi, bool tage_pred, 17613627Sjavier.bueno@metempsy.com int random0, int random1, int random2) 17713627Sjavier.bueno@metempsy.com{ 17813627Sjavier.bueno@metempsy.com int idx = finallindex(bi->loopIndex, bi->loopIndexB, bi->loopHit); 17913627Sjavier.bueno@metempsy.com if (bi->loopHit >= 0) { 18013627Sjavier.bueno@metempsy.com //already a hit 18113627Sjavier.bueno@metempsy.com if (bi->loopPredValid) { 18213627Sjavier.bueno@metempsy.com if (taken != bi->loopPred) { 18313627Sjavier.bueno@metempsy.com // free the entry 18413627Sjavier.bueno@metempsy.com ltable[idx].numIter = 0; 18513627Sjavier.bueno@metempsy.com ltable[idx].age = 0; 18613627Sjavier.bueno@metempsy.com ltable[idx].confidence = 0; 18713627Sjavier.bueno@metempsy.com ltable[idx].currentIter = 0; 18813627Sjavier.bueno@metempsy.com return; 18913627Sjavier.bueno@metempsy.com } else if (bi->loopPred != tage_pred || optionalAgeInc(random0)) { 19013627Sjavier.bueno@metempsy.com unsignedCtrUpdate(ltable[idx].age, true, loopTableAgeBits); 19113627Sjavier.bueno@metempsy.com } 19213627Sjavier.bueno@metempsy.com } 19313627Sjavier.bueno@metempsy.com 19413627Sjavier.bueno@metempsy.com ltable[idx].currentIter = 19513627Sjavier.bueno@metempsy.com (ltable[idx].currentIter + 1) & loopNumIterMask; 19613627Sjavier.bueno@metempsy.com if (ltable[idx].currentIter > ltable[idx].numIter) { 19713627Sjavier.bueno@metempsy.com ltable[idx].confidence = 0; 19813627Sjavier.bueno@metempsy.com if (ltable[idx].numIter != 0) { 19913627Sjavier.bueno@metempsy.com // free the entry 20013627Sjavier.bueno@metempsy.com ltable[idx].numIter = 0; 20113627Sjavier.bueno@metempsy.com if (optionalAgeReset) { 20213627Sjavier.bueno@metempsy.com ltable[idx].age = 0; 20313627Sjavier.bueno@metempsy.com } 20413627Sjavier.bueno@metempsy.com } 20513627Sjavier.bueno@metempsy.com } 20613627Sjavier.bueno@metempsy.com 20713627Sjavier.bueno@metempsy.com if (taken != (useDirectionBit ? ltable[idx].dir : true)) { 20813627Sjavier.bueno@metempsy.com if (ltable[idx].currentIter == ltable[idx].numIter) { 20913627Sjavier.bueno@metempsy.com unsignedCtrUpdate(ltable[idx].confidence, true, 21013627Sjavier.bueno@metempsy.com loopTableConfidenceBits); 21113627Sjavier.bueno@metempsy.com //just do not predict when the loop count is 1 or 2 21213627Sjavier.bueno@metempsy.com if (ltable[idx].numIter < 3) { 21313627Sjavier.bueno@metempsy.com // free the entry 21413627Sjavier.bueno@metempsy.com ltable[idx].dir = taken; // ignored if no useDirectionBit 21513627Sjavier.bueno@metempsy.com ltable[idx].numIter = 0; 21613627Sjavier.bueno@metempsy.com ltable[idx].age = 0; 21713627Sjavier.bueno@metempsy.com ltable[idx].confidence = 0; 21813627Sjavier.bueno@metempsy.com } 21913627Sjavier.bueno@metempsy.com } else { 22013627Sjavier.bueno@metempsy.com if (ltable[idx].numIter == 0) { 22113627Sjavier.bueno@metempsy.com // first complete nest; 22213627Sjavier.bueno@metempsy.com ltable[idx].confidence = 0; 22313627Sjavier.bueno@metempsy.com ltable[idx].numIter = ltable[idx].currentIter; 22413627Sjavier.bueno@metempsy.com } else { 22513627Sjavier.bueno@metempsy.com //not the same number of iterations as last time: free the 22613627Sjavier.bueno@metempsy.com //entry 22713627Sjavier.bueno@metempsy.com ltable[idx].numIter = 0; 22813627Sjavier.bueno@metempsy.com if (optionalAgeReset) { 22913627Sjavier.bueno@metempsy.com ltable[idx].age = 0; 23013627Sjavier.bueno@metempsy.com } 23113627Sjavier.bueno@metempsy.com ltable[idx].confidence = 0; 23213627Sjavier.bueno@metempsy.com } 23313627Sjavier.bueno@metempsy.com } 23413627Sjavier.bueno@metempsy.com ltable[idx].currentIter = 0; 23513627Sjavier.bueno@metempsy.com } 23613627Sjavier.bueno@metempsy.com 23713627Sjavier.bueno@metempsy.com } else if (useDirectionBit ? (bi->predTaken != taken) : taken) { 23813627Sjavier.bueno@metempsy.com if ((random2 & 3) == 0 || !restrictAllocation) { 23913627Sjavier.bueno@metempsy.com //try to allocate an entry on taken branch 24013627Sjavier.bueno@metempsy.com int nrand = random1; 24113627Sjavier.bueno@metempsy.com for (int i = 0; i < (1 << logLoopTableAssoc); i++) { 24213627Sjavier.bueno@metempsy.com int loop_hit = (nrand + i) & ((1 << logLoopTableAssoc) - 1); 24313627Sjavier.bueno@metempsy.com idx = finallindex(bi->loopIndex, bi->loopIndexB, loop_hit); 24413627Sjavier.bueno@metempsy.com if (ltable[idx].age == 0) { 24513627Sjavier.bueno@metempsy.com ltable[idx].dir = !taken; // ignored if no useDirectionBit 24613627Sjavier.bueno@metempsy.com ltable[idx].tag = bi->loopTag; 24713627Sjavier.bueno@metempsy.com ltable[idx].numIter = 0; 24813627Sjavier.bueno@metempsy.com ltable[idx].age = initialLoopAge; 24913627Sjavier.bueno@metempsy.com ltable[idx].confidence = 0; 25013627Sjavier.bueno@metempsy.com ltable[idx].currentIter = initialLoopIter; 25113627Sjavier.bueno@metempsy.com break; 25213627Sjavier.bueno@metempsy.com 25313627Sjavier.bueno@metempsy.com } else { 25413627Sjavier.bueno@metempsy.com ltable[idx].age--; 25513627Sjavier.bueno@metempsy.com } 25613627Sjavier.bueno@metempsy.com if (restrictAllocation) { 25713627Sjavier.bueno@metempsy.com break; 25813627Sjavier.bueno@metempsy.com } 25913627Sjavier.bueno@metempsy.com } 26013627Sjavier.bueno@metempsy.com } 26113627Sjavier.bueno@metempsy.com } 26213627Sjavier.bueno@metempsy.com} 26313627Sjavier.bueno@metempsy.com 26413627Sjavier.bueno@metempsy.combool 26513627Sjavier.bueno@metempsy.comLoopPredictor::loopPredict(ThreadID tid, Addr branch_pc, bool cond_branch, 26613627Sjavier.bueno@metempsy.com BranchInfo* bi, bool prev_pred_taken, unsigned instShiftAmt) 26713627Sjavier.bueno@metempsy.com{ 26813627Sjavier.bueno@metempsy.com bool pred_taken = prev_pred_taken; 26913627Sjavier.bueno@metempsy.com if (cond_branch) { 27013627Sjavier.bueno@metempsy.com // loop prediction 27113627Sjavier.bueno@metempsy.com bi->loopPred = getLoop(branch_pc, bi, useSpeculation, instShiftAmt); 27213627Sjavier.bueno@metempsy.com 27313627Sjavier.bueno@metempsy.com if ((loopUseCounter >= 0) && bi->loopPredValid) { 27413627Sjavier.bueno@metempsy.com pred_taken = bi->loopPred; 27513627Sjavier.bueno@metempsy.com bi->loopPredUsed = true; 27613627Sjavier.bueno@metempsy.com } 27713627Sjavier.bueno@metempsy.com 27813627Sjavier.bueno@metempsy.com if (useSpeculation) { 27913627Sjavier.bueno@metempsy.com specLoopUpdate(pred_taken, bi); 28013627Sjavier.bueno@metempsy.com } 28113627Sjavier.bueno@metempsy.com } 28213627Sjavier.bueno@metempsy.com 28313627Sjavier.bueno@metempsy.com return pred_taken; 28413627Sjavier.bueno@metempsy.com} 28513627Sjavier.bueno@metempsy.com 28613627Sjavier.bueno@metempsy.comvoid 28713627Sjavier.bueno@metempsy.comLoopPredictor::squash(ThreadID tid, BranchInfo *bi) 28813627Sjavier.bueno@metempsy.com{ 28913627Sjavier.bueno@metempsy.com if (bi->loopHit >= 0) { 29013627Sjavier.bueno@metempsy.com int idx = finallindex(bi->loopIndex, 29113627Sjavier.bueno@metempsy.com bi->loopIndexB, 29213627Sjavier.bueno@metempsy.com bi->loopHit); 29313627Sjavier.bueno@metempsy.com ltable[idx].currentIterSpec = bi->currentIter; 29413627Sjavier.bueno@metempsy.com } 29513627Sjavier.bueno@metempsy.com} 29613627Sjavier.bueno@metempsy.com 29713627Sjavier.bueno@metempsy.comvoid 29813627Sjavier.bueno@metempsy.comLoopPredictor::squashLoop(BranchInfo* bi) 29913627Sjavier.bueno@metempsy.com{ 30013627Sjavier.bueno@metempsy.com if (bi->loopHit >= 0) { 30113627Sjavier.bueno@metempsy.com int idx = finallindex(bi->loopIndex, 30213627Sjavier.bueno@metempsy.com bi->loopIndexB, 30313627Sjavier.bueno@metempsy.com bi->loopHit); 30413627Sjavier.bueno@metempsy.com ltable[idx].currentIterSpec = bi->currentIter; 30513627Sjavier.bueno@metempsy.com } 30613627Sjavier.bueno@metempsy.com} 30713627Sjavier.bueno@metempsy.com 30813627Sjavier.bueno@metempsy.comvoid 30913627Sjavier.bueno@metempsy.comLoopPredictor::updateStats(bool taken, BranchInfo* bi) 31013627Sjavier.bueno@metempsy.com{ 31113627Sjavier.bueno@metempsy.com if (taken == bi->loopPred) { 31213627Sjavier.bueno@metempsy.com loopPredictorCorrect++; 31313627Sjavier.bueno@metempsy.com } else { 31413627Sjavier.bueno@metempsy.com loopPredictorWrong++; 31513627Sjavier.bueno@metempsy.com } 31613627Sjavier.bueno@metempsy.com} 31713627Sjavier.bueno@metempsy.com 31813627Sjavier.bueno@metempsy.comvoid 31913627Sjavier.bueno@metempsy.comLoopPredictor::condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken, 32013627Sjavier.bueno@metempsy.com bool tage_pred, BranchInfo* bi, 32113627Sjavier.bueno@metempsy.com unsigned instShiftAmt, int rand0, int rand1, 32213627Sjavier.bueno@metempsy.com int rand2) 32313627Sjavier.bueno@metempsy.com{ 32413627Sjavier.bueno@metempsy.com if (useSpeculation) { 32513627Sjavier.bueno@metempsy.com // recalculate loop prediction without speculation 32613627Sjavier.bueno@metempsy.com // It is ok to overwrite the loop prediction fields in bi 32713627Sjavier.bueno@metempsy.com // as the stats have already been updated with the previous 32813627Sjavier.bueno@metempsy.com // values 32913627Sjavier.bueno@metempsy.com bi->loopPred = getLoop(branch_pc, bi, false, instShiftAmt); 33013627Sjavier.bueno@metempsy.com } 33113627Sjavier.bueno@metempsy.com 33213627Sjavier.bueno@metempsy.com if (bi->loopPredValid) { 33313627Sjavier.bueno@metempsy.com if (bi->predTaken != bi->loopPred) { 33413627Sjavier.bueno@metempsy.com signedCtrUpdate(loopUseCounter, 33513627Sjavier.bueno@metempsy.com (bi->loopPred == taken), 33613627Sjavier.bueno@metempsy.com withLoopBits); 33713627Sjavier.bueno@metempsy.com } 33813627Sjavier.bueno@metempsy.com } 33913627Sjavier.bueno@metempsy.com 34013627Sjavier.bueno@metempsy.com loopUpdate(branch_pc, taken, bi, tage_pred, rand0, rand1, rand2); 34113627Sjavier.bueno@metempsy.com} 34213627Sjavier.bueno@metempsy.com 34313627Sjavier.bueno@metempsy.comvoid 34413627Sjavier.bueno@metempsy.comLoopPredictor::regStats() 34513627Sjavier.bueno@metempsy.com{ 34613627Sjavier.bueno@metempsy.com loopPredictorCorrect 34713627Sjavier.bueno@metempsy.com .name(name() + ".loopPredictorCorrect") 34813627Sjavier.bueno@metempsy.com .desc("Number of times the loop predictor is the provider and " 34913627Sjavier.bueno@metempsy.com "the prediction is correct"); 35013627Sjavier.bueno@metempsy.com 35113627Sjavier.bueno@metempsy.com loopPredictorWrong 35213627Sjavier.bueno@metempsy.com .name(name() + ".loopPredictorWrong") 35313627Sjavier.bueno@metempsy.com .desc("Number of times the loop predictor is the provider and " 35413627Sjavier.bueno@metempsy.com "the prediction is wrong"); 35513627Sjavier.bueno@metempsy.com} 35613627Sjavier.bueno@metempsy.com 35713627Sjavier.bueno@metempsy.comLoopPredictor * 35813627Sjavier.bueno@metempsy.comLoopPredictorParams::create() 35913627Sjavier.bueno@metempsy.com{ 36013627Sjavier.bueno@metempsy.com return new LoopPredictor(this); 36113627Sjavier.bueno@metempsy.com} 362