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