ltage.cc revision 13493
111784Sarthur.perais@inria.fr/*
211784Sarthur.perais@inria.fr * Copyright (c) 2014 The University of Wisconsin
311784Sarthur.perais@inria.fr *
411784Sarthur.perais@inria.fr * Copyright (c) 2006 INRIA (Institut National de Recherche en
511784Sarthur.perais@inria.fr * Informatique et en Automatique  / French National Research Institute
611784Sarthur.perais@inria.fr * for Computer Science and Applied Mathematics)
711784Sarthur.perais@inria.fr *
811784Sarthur.perais@inria.fr * All rights reserved.
911784Sarthur.perais@inria.fr *
1011784Sarthur.perais@inria.fr * Redistribution and use in source and binary forms, with or without
1111784Sarthur.perais@inria.fr * modification, are permitted provided that the following conditions are
1211784Sarthur.perais@inria.fr * met: redistributions of source code must retain the above copyright
1311784Sarthur.perais@inria.fr * notice, this list of conditions and the following disclaimer;
1411784Sarthur.perais@inria.fr * redistributions in binary form must reproduce the above copyright
1511784Sarthur.perais@inria.fr * notice, this list of conditions and the following disclaimer in the
1611784Sarthur.perais@inria.fr * documentation and/or other materials provided with the distribution;
1711784Sarthur.perais@inria.fr * neither the name of the copyright holders nor the names of its
1811784Sarthur.perais@inria.fr * contributors may be used to endorse or promote products derived from
1911784Sarthur.perais@inria.fr * this software without specific prior written permission.
2011784Sarthur.perais@inria.fr *
2111784Sarthur.perais@inria.fr * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2211784Sarthur.perais@inria.fr * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2311784Sarthur.perais@inria.fr * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2411784Sarthur.perais@inria.fr * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2511784Sarthur.perais@inria.fr * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2611784Sarthur.perais@inria.fr * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2711784Sarthur.perais@inria.fr * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2811784Sarthur.perais@inria.fr * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2911784Sarthur.perais@inria.fr * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3011784Sarthur.perais@inria.fr * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3111784Sarthur.perais@inria.fr * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3211784Sarthur.perais@inria.fr *
3311784Sarthur.perais@inria.fr * Authors: Vignyan Reddy, Dibakar Gope and Arthur Perais,
3411784Sarthur.perais@inria.fr * from André Seznec's code.
3511784Sarthur.perais@inria.fr */
3611784Sarthur.perais@inria.fr
3711784Sarthur.perais@inria.fr/* @file
3811784Sarthur.perais@inria.fr * Implementation of a L-TAGE branch predictor
3911784Sarthur.perais@inria.fr */
4011784Sarthur.perais@inria.fr
4111784Sarthur.perais@inria.fr#include "cpu/pred/ltage.hh"
4211784Sarthur.perais@inria.fr
4311784Sarthur.perais@inria.fr#include "base/intmath.hh"
4412334Sgabeblack@google.com#include "base/logging.hh"
4511784Sarthur.perais@inria.fr#include "base/random.hh"
4611784Sarthur.perais@inria.fr#include "base/trace.hh"
4711784Sarthur.perais@inria.fr#include "debug/Fetch.hh"
4811784Sarthur.perais@inria.fr#include "debug/LTage.hh"
4911784Sarthur.perais@inria.fr
5011784Sarthur.perais@inria.frLTAGE::LTAGE(const LTAGEParams *params)
5113454Spau.cabre@metempsy.com  : TAGE(params),
5211784Sarthur.perais@inria.fr    logSizeLoopPred(params->logSizeLoopPred),
5313442Spau.cabre@metempsy.com    loopTableAgeBits(params->loopTableAgeBits),
5413442Spau.cabre@metempsy.com    loopTableConfidenceBits(params->loopTableConfidenceBits),
5513442Spau.cabre@metempsy.com    loopTableTagBits(params->loopTableTagBits),
5613442Spau.cabre@metempsy.com    loopTableIterBits(params->loopTableIterBits),
5713444Spau.cabre@metempsy.com    logLoopTableAssoc(params->logLoopTableAssoc),
5813442Spau.cabre@metempsy.com    confidenceThreshold((1 << loopTableConfidenceBits) - 1),
5913442Spau.cabre@metempsy.com    loopTagMask((1 << loopTableTagBits) - 1),
6013442Spau.cabre@metempsy.com    loopNumIterMask((1 << loopTableIterBits) - 1),
6113493Spau.cabre@metempsy.com    loopSetMask((1 << (logSizeLoopPred - logLoopTableAssoc)) - 1),
6213454Spau.cabre@metempsy.com    loopUseCounter(0),
6313493Spau.cabre@metempsy.com    withLoopBits(params->withLoopBits),
6413493Spau.cabre@metempsy.com    useDirectionBit(params->useDirectionBit),
6513493Spau.cabre@metempsy.com    useSpeculation(params->useSpeculation),
6613493Spau.cabre@metempsy.com    useHashing(params->useHashing)
6711784Sarthur.perais@inria.fr{
6813442Spau.cabre@metempsy.com    // we use uint16_t type for these vales, so they cannot be more than
6913442Spau.cabre@metempsy.com    // 16 bits
7013442Spau.cabre@metempsy.com    assert(loopTableTagBits <= 16);
7113442Spau.cabre@metempsy.com    assert(loopTableIterBits <= 16);
7213442Spau.cabre@metempsy.com
7313444Spau.cabre@metempsy.com    assert(logSizeLoopPred >= logLoopTableAssoc);
7413444Spau.cabre@metempsy.com
7511784Sarthur.perais@inria.fr    ltable = new LoopEntry[ULL(1) << logSizeLoopPred];
7611784Sarthur.perais@inria.fr}
7711784Sarthur.perais@inria.fr
7811784Sarthur.perais@inria.frint
7911784Sarthur.perais@inria.frLTAGE::lindex(Addr pc_in) const
8011784Sarthur.perais@inria.fr{
8113444Spau.cabre@metempsy.com    // The loop table is implemented as a linear table
8213444Spau.cabre@metempsy.com    // If associativity is N (N being 1 << logLoopTableAssoc),
8313444Spau.cabre@metempsy.com    // the first N entries are for set 0, the next N entries are for set 1,
8413444Spau.cabre@metempsy.com    // and so on.
8513444Spau.cabre@metempsy.com    // Thus, this function calculates the set and then it gets left shifted
8613444Spau.cabre@metempsy.com    // by logLoopTableAssoc in order to return the index of the first of the
8713444Spau.cabre@metempsy.com    // N entries of the set
8813444Spau.cabre@metempsy.com    Addr mask = (ULL(1) << (logSizeLoopPred - logLoopTableAssoc)) - 1;
8913493Spau.cabre@metempsy.com    Addr pc = pc_in >> instShiftAmt;
9013493Spau.cabre@metempsy.com    if (useHashing) {
9113493Spau.cabre@metempsy.com        // copied from TAGE-SC-L
9213493Spau.cabre@metempsy.com        // (http://www.jilp.org/cbp2016/code/AndreSeznecLimited.tar.gz)
9313493Spau.cabre@metempsy.com        pc ^= (pc_in >> (instShiftAmt + logLoopTableAssoc));
9413493Spau.cabre@metempsy.com    }
9513493Spau.cabre@metempsy.com    return ((pc & mask) << logLoopTableAssoc);
9613493Spau.cabre@metempsy.com}
9713493Spau.cabre@metempsy.com
9813493Spau.cabre@metempsy.comint
9913493Spau.cabre@metempsy.comLTAGE::finallindex(int index, int lowPcBits, int way) const
10013493Spau.cabre@metempsy.com{
10113493Spau.cabre@metempsy.com    // copied from TAGE-SC-L
10213493Spau.cabre@metempsy.com    // (http://www.jilp.org/cbp2016/code/AndreSeznecLimited.tar.gz)
10313493Spau.cabre@metempsy.com    return (useHashing ? (index ^ ((lowPcBits >> way) << logLoopTableAssoc)) :
10413493Spau.cabre@metempsy.com                         (index))
10513493Spau.cabre@metempsy.com           + way;
10611784Sarthur.perais@inria.fr}
10711784Sarthur.perais@inria.fr
10811784Sarthur.perais@inria.fr//loop prediction: only used if high confidence
10911784Sarthur.perais@inria.frbool
11013493Spau.cabre@metempsy.comLTAGE::getLoop(Addr pc, LTageBranchInfo* bi, bool speculative) const
11111784Sarthur.perais@inria.fr{
11211784Sarthur.perais@inria.fr    bi->loopHit = -1;
11311784Sarthur.perais@inria.fr    bi->loopPredValid = false;
11411784Sarthur.perais@inria.fr    bi->loopIndex = lindex(pc);
11513444Spau.cabre@metempsy.com    unsigned pcShift = instShiftAmt + logSizeLoopPred - logLoopTableAssoc;
11613444Spau.cabre@metempsy.com    bi->loopTag = ((pc) >> pcShift) & loopTagMask;
11711784Sarthur.perais@inria.fr
11813493Spau.cabre@metempsy.com    if (useHashing) {
11913493Spau.cabre@metempsy.com        bi->loopTag ^= ((pc >> (pcShift + logSizeLoopPred)) & loopTagMask);
12013493Spau.cabre@metempsy.com        bi->loopLowPcBits = (pc >> pcShift) & loopSetMask;
12113493Spau.cabre@metempsy.com    }
12213493Spau.cabre@metempsy.com
12313444Spau.cabre@metempsy.com    for (int i = 0; i < (1 << logLoopTableAssoc); i++) {
12413493Spau.cabre@metempsy.com        int idx = finallindex(bi->loopIndex, bi->loopLowPcBits, i);
12513493Spau.cabre@metempsy.com        if (ltable[idx].tag == bi->loopTag) {
12611784Sarthur.perais@inria.fr            bi->loopHit = i;
12713442Spau.cabre@metempsy.com            bi->loopPredValid =
12813493Spau.cabre@metempsy.com                ltable[idx].confidence == confidenceThreshold;
12913493Spau.cabre@metempsy.com
13013493Spau.cabre@metempsy.com            uint16_t iter = speculative ? ltable[idx].currentIterSpec
13113493Spau.cabre@metempsy.com                                        : ltable[idx].currentIter;
13213493Spau.cabre@metempsy.com
13313493Spau.cabre@metempsy.com            if ((iter + 1) == ltable[idx].numIter) {
13413493Spau.cabre@metempsy.com                return useDirectionBit ? !(ltable[idx].dir) : false;
13513493Spau.cabre@metempsy.com            } else {
13613493Spau.cabre@metempsy.com                return useDirectionBit ? (ltable[idx].dir) : true;
13711784Sarthur.perais@inria.fr            }
13811784Sarthur.perais@inria.fr        }
13911784Sarthur.perais@inria.fr    }
14011784Sarthur.perais@inria.fr    return false;
14111784Sarthur.perais@inria.fr}
14211784Sarthur.perais@inria.fr
14311784Sarthur.perais@inria.frvoid
14413493Spau.cabre@metempsy.comLTAGE::specLoopUpdate(bool taken, LTageBranchInfo* bi)
14511784Sarthur.perais@inria.fr{
14611784Sarthur.perais@inria.fr    if (bi->loopHit>=0) {
14713493Spau.cabre@metempsy.com        int index = finallindex(bi->loopIndex, bi->loopLowPcBits, bi->loopHit);
14811784Sarthur.perais@inria.fr        if (taken != ltable[index].dir) {
14911784Sarthur.perais@inria.fr            ltable[index].currentIterSpec = 0;
15011784Sarthur.perais@inria.fr        } else {
15113442Spau.cabre@metempsy.com            ltable[index].currentIterSpec =
15213442Spau.cabre@metempsy.com                (ltable[index].currentIterSpec + 1) & loopNumIterMask;
15311784Sarthur.perais@inria.fr        }
15411784Sarthur.perais@inria.fr    }
15511784Sarthur.perais@inria.fr}
15611784Sarthur.perais@inria.fr
15711784Sarthur.perais@inria.frvoid
15813454Spau.cabre@metempsy.comLTAGE::loopUpdate(Addr pc, bool taken, LTageBranchInfo* bi)
15911784Sarthur.perais@inria.fr{
16013493Spau.cabre@metempsy.com    int idx = finallindex(bi->loopIndex, bi->loopLowPcBits, bi->loopHit);
16111784Sarthur.perais@inria.fr    if (bi->loopHit >= 0) {
16211784Sarthur.perais@inria.fr        //already a hit
16311784Sarthur.perais@inria.fr        if (bi->loopPredValid) {
16411784Sarthur.perais@inria.fr            if (taken != bi->loopPred) {
16511784Sarthur.perais@inria.fr                // free the entry
16611784Sarthur.perais@inria.fr                ltable[idx].numIter = 0;
16711784Sarthur.perais@inria.fr                ltable[idx].age = 0;
16811784Sarthur.perais@inria.fr                ltable[idx].confidence = 0;
16911784Sarthur.perais@inria.fr                ltable[idx].currentIter = 0;
17011784Sarthur.perais@inria.fr                return;
17111784Sarthur.perais@inria.fr            } else if (bi->loopPred != bi->tagePred) {
17211784Sarthur.perais@inria.fr                DPRINTF(LTage, "Loop Prediction success:%lx\n",pc);
17313442Spau.cabre@metempsy.com                unsignedCtrUpdate(ltable[idx].age, true, loopTableAgeBits);
17411784Sarthur.perais@inria.fr            }
17511784Sarthur.perais@inria.fr        }
17611784Sarthur.perais@inria.fr
17713442Spau.cabre@metempsy.com        ltable[idx].currentIter =
17813442Spau.cabre@metempsy.com            (ltable[idx].currentIter + 1) & loopNumIterMask;
17911784Sarthur.perais@inria.fr        if (ltable[idx].currentIter > ltable[idx].numIter) {
18011784Sarthur.perais@inria.fr            ltable[idx].confidence = 0;
18111784Sarthur.perais@inria.fr            if (ltable[idx].numIter != 0) {
18211784Sarthur.perais@inria.fr                // free the entry
18311784Sarthur.perais@inria.fr                ltable[idx].numIter = 0;
18411784Sarthur.perais@inria.fr                ltable[idx].age = 0;
18511784Sarthur.perais@inria.fr                ltable[idx].confidence = 0;
18611784Sarthur.perais@inria.fr            }
18711784Sarthur.perais@inria.fr        }
18811784Sarthur.perais@inria.fr
18913493Spau.cabre@metempsy.com        if (taken != (useDirectionBit ? ltable[idx].dir : true)) {
19011784Sarthur.perais@inria.fr            if (ltable[idx].currentIter == ltable[idx].numIter) {
19111784Sarthur.perais@inria.fr                DPRINTF(LTage, "Loop End predicted successfully:%lx\n", pc);
19211784Sarthur.perais@inria.fr
19313442Spau.cabre@metempsy.com                unsignedCtrUpdate(ltable[idx].confidence, true,
19413442Spau.cabre@metempsy.com                                  loopTableConfidenceBits);
19511784Sarthur.perais@inria.fr                //just do not predict when the loop count is 1 or 2
19611784Sarthur.perais@inria.fr                if (ltable[idx].numIter < 3) {
19711784Sarthur.perais@inria.fr                    // free the entry
19813493Spau.cabre@metempsy.com                    ltable[idx].dir = taken; // ignored if no useDirectionBit
19911784Sarthur.perais@inria.fr                    ltable[idx].numIter = 0;
20011784Sarthur.perais@inria.fr                    ltable[idx].age = 0;
20111784Sarthur.perais@inria.fr                    ltable[idx].confidence = 0;
20211784Sarthur.perais@inria.fr                }
20311784Sarthur.perais@inria.fr            } else {
20411784Sarthur.perais@inria.fr                DPRINTF(LTage, "Loop End predicted incorrectly:%lx\n", pc);
20511784Sarthur.perais@inria.fr                if (ltable[idx].numIter == 0) {
20611784Sarthur.perais@inria.fr                    // first complete nest;
20711784Sarthur.perais@inria.fr                    ltable[idx].confidence = 0;
20811784Sarthur.perais@inria.fr                    ltable[idx].numIter = ltable[idx].currentIter;
20911784Sarthur.perais@inria.fr                } else {
21011784Sarthur.perais@inria.fr                    //not the same number of iterations as last time: free the
21111784Sarthur.perais@inria.fr                    //entry
21211784Sarthur.perais@inria.fr                    ltable[idx].numIter = 0;
21311784Sarthur.perais@inria.fr                    ltable[idx].age = 0;
21411784Sarthur.perais@inria.fr                    ltable[idx].confidence = 0;
21511784Sarthur.perais@inria.fr                }
21611784Sarthur.perais@inria.fr            }
21711784Sarthur.perais@inria.fr            ltable[idx].currentIter = 0;
21811784Sarthur.perais@inria.fr        }
21911784Sarthur.perais@inria.fr
22013493Spau.cabre@metempsy.com    } else if (useDirectionBit ?
22113493Spau.cabre@metempsy.com                ((bi->loopPredValid ? bi->loopPred : bi->tagePred) != taken) :
22213493Spau.cabre@metempsy.com                taken) {
22311784Sarthur.perais@inria.fr        //try to allocate an entry on taken branch
22411784Sarthur.perais@inria.fr        int nrand = random_mt.random<int>();
22513444Spau.cabre@metempsy.com        for (int i = 0; i < (1 << logLoopTableAssoc); i++) {
22613444Spau.cabre@metempsy.com            int loop_hit = (nrand + i) & ((1 << logLoopTableAssoc) - 1);
22711784Sarthur.perais@inria.fr            idx = bi->loopIndex + loop_hit;
22811784Sarthur.perais@inria.fr            if (ltable[idx].age == 0) {
22911784Sarthur.perais@inria.fr                DPRINTF(LTage, "Allocating loop pred entry for branch %lx\n",
23011784Sarthur.perais@inria.fr                        pc);
23113493Spau.cabre@metempsy.com                ltable[idx].dir = !taken; // ignored if no useDirectionBit
23211784Sarthur.perais@inria.fr                ltable[idx].tag = bi->loopTag;
23311784Sarthur.perais@inria.fr                ltable[idx].numIter = 0;
23413442Spau.cabre@metempsy.com                ltable[idx].age = (1 << loopTableAgeBits) - 1;
23511784Sarthur.perais@inria.fr                ltable[idx].confidence = 0;
23611784Sarthur.perais@inria.fr                ltable[idx].currentIter = 1;
23711784Sarthur.perais@inria.fr                break;
23811784Sarthur.perais@inria.fr
23911784Sarthur.perais@inria.fr            }
24011784Sarthur.perais@inria.fr            else
24111784Sarthur.perais@inria.fr                ltable[idx].age--;
24211784Sarthur.perais@inria.fr        }
24311784Sarthur.perais@inria.fr    }
24411784Sarthur.perais@inria.fr
24511784Sarthur.perais@inria.fr}
24611784Sarthur.perais@inria.fr
24711784Sarthur.perais@inria.fr//prediction
24811784Sarthur.perais@inria.frbool
24911784Sarthur.perais@inria.frLTAGE::predict(ThreadID tid, Addr branch_pc, bool cond_branch, void* &b)
25011784Sarthur.perais@inria.fr{
25113454Spau.cabre@metempsy.com    LTageBranchInfo *bi = new LTageBranchInfo(nHistoryTables+1);
25211784Sarthur.perais@inria.fr    b = (void*)(bi);
25313454Spau.cabre@metempsy.com
25413454Spau.cabre@metempsy.com    bool pred_taken = tagePredict(tid, branch_pc, cond_branch, bi);
25511784Sarthur.perais@inria.fr
25611784Sarthur.perais@inria.fr    if (cond_branch) {
25713493Spau.cabre@metempsy.com        // loop prediction
25813493Spau.cabre@metempsy.com        bi->loopPred = getLoop(branch_pc, bi, useSpeculation);
25911784Sarthur.perais@inria.fr
26013454Spau.cabre@metempsy.com        if ((loopUseCounter >= 0) && bi->loopPredValid) {
26113454Spau.cabre@metempsy.com            pred_taken = bi->loopPred;
26213455Spau.cabre@metempsy.com            bi->provider = LOOP;
26311784Sarthur.perais@inria.fr        }
26411784Sarthur.perais@inria.fr        DPRINTF(LTage, "Predict for %lx: taken?:%d, loopTaken?:%d, "
26511784Sarthur.perais@inria.fr                "loopValid?:%d, loopUseCounter:%d, tagePred:%d, altPred:%d\n",
26611784Sarthur.perais@inria.fr                branch_pc, pred_taken, bi->loopPred, bi->loopPredValid,
26711784Sarthur.perais@inria.fr                loopUseCounter, bi->tagePred, bi->altTaken);
26813493Spau.cabre@metempsy.com
26913493Spau.cabre@metempsy.com        if (useSpeculation) {
27013493Spau.cabre@metempsy.com            specLoopUpdate(pred_taken, bi);
27113493Spau.cabre@metempsy.com        }
27211784Sarthur.perais@inria.fr    }
27313454Spau.cabre@metempsy.com
27411784Sarthur.perais@inria.fr    return pred_taken;
27511784Sarthur.perais@inria.fr}
27611784Sarthur.perais@inria.fr
27711784Sarthur.perais@inria.frvoid
27813454Spau.cabre@metempsy.comLTAGE::condBranchUpdate(Addr branch_pc, bool taken,
27913454Spau.cabre@metempsy.com                        TageBranchInfo* tage_bi, int nrand)
28011784Sarthur.perais@inria.fr{
28113454Spau.cabre@metempsy.com    LTageBranchInfo* bi = static_cast<LTageBranchInfo*>(tage_bi);
28211784Sarthur.perais@inria.fr
28313493Spau.cabre@metempsy.com    if (useSpeculation) {
28413493Spau.cabre@metempsy.com        // recalculate loop prediction without speculation
28513493Spau.cabre@metempsy.com        // It is ok to overwrite the loop prediction fields in bi
28613493Spau.cabre@metempsy.com        // as the stats have already been updated with the previous
28713493Spau.cabre@metempsy.com        // values
28813493Spau.cabre@metempsy.com        bi->loopPred = getLoop(branch_pc, bi, false);
28913493Spau.cabre@metempsy.com    }
29011784Sarthur.perais@inria.fr
29113454Spau.cabre@metempsy.com    if (bi->loopPredValid) {
29213454Spau.cabre@metempsy.com        if (bi->tagePred != bi->loopPred) {
29313454Spau.cabre@metempsy.com            ctrUpdate(loopUseCounter,
29413454Spau.cabre@metempsy.com                      (bi->loopPred == taken),
29513454Spau.cabre@metempsy.com                      withLoopBits);
29613454Spau.cabre@metempsy.com        }
29711784Sarthur.perais@inria.fr    }
29811784Sarthur.perais@inria.fr
29913493Spau.cabre@metempsy.com    loopUpdate(branch_pc, taken, bi);
30013493Spau.cabre@metempsy.com
30113454Spau.cabre@metempsy.com    TAGE::condBranchUpdate(branch_pc, taken, bi, nrand);
30211784Sarthur.perais@inria.fr}
30311784Sarthur.perais@inria.fr
30411784Sarthur.perais@inria.frvoid
30511784Sarthur.perais@inria.frLTAGE::squash(ThreadID tid, bool taken, void *bp_history)
30611784Sarthur.perais@inria.fr{
30713454Spau.cabre@metempsy.com    TAGE::squash(tid, taken, bp_history);
30813454Spau.cabre@metempsy.com
30913454Spau.cabre@metempsy.com    LTageBranchInfo* bi = (LTageBranchInfo*)(bp_history);
31011784Sarthur.perais@inria.fr
31111784Sarthur.perais@inria.fr    if (bi->condBranch) {
31211784Sarthur.perais@inria.fr        if (bi->loopHit >= 0) {
31313493Spau.cabre@metempsy.com            int idx = finallindex(bi->loopIndex,
31413493Spau.cabre@metempsy.com                                  bi->loopLowPcBits,
31513493Spau.cabre@metempsy.com                                  bi->loopHit);
31611784Sarthur.perais@inria.fr            ltable[idx].currentIterSpec = bi->currentIter;
31711784Sarthur.perais@inria.fr        }
31811784Sarthur.perais@inria.fr    }
31911784Sarthur.perais@inria.fr}
32011784Sarthur.perais@inria.fr
32111784Sarthur.perais@inria.frvoid
32211784Sarthur.perais@inria.frLTAGE::squash(ThreadID tid, void *bp_history)
32311784Sarthur.perais@inria.fr{
32413454Spau.cabre@metempsy.com    LTageBranchInfo* bi = (LTageBranchInfo*)(bp_history);
32511784Sarthur.perais@inria.fr    if (bi->condBranch) {
32611784Sarthur.perais@inria.fr        if (bi->loopHit >= 0) {
32713493Spau.cabre@metempsy.com            int idx = finallindex(bi->loopIndex,
32813493Spau.cabre@metempsy.com                                  bi->loopLowPcBits,
32913493Spau.cabre@metempsy.com                                  bi->loopHit);
33011784Sarthur.perais@inria.fr            ltable[idx].currentIterSpec = bi->currentIter;
33111784Sarthur.perais@inria.fr        }
33211784Sarthur.perais@inria.fr    }
33311784Sarthur.perais@inria.fr
33413454Spau.cabre@metempsy.com    TAGE::squash(tid, bp_history);
33511784Sarthur.perais@inria.fr}
33611784Sarthur.perais@inria.fr
33713455Spau.cabre@metempsy.com
33813455Spau.cabre@metempsy.comvoid
33913455Spau.cabre@metempsy.comLTAGE::updateStats(bool taken, TageBranchInfo* bi)
34013455Spau.cabre@metempsy.com{
34113455Spau.cabre@metempsy.com    TAGE::updateStats(taken, bi);
34213455Spau.cabre@metempsy.com
34313455Spau.cabre@metempsy.com    LTageBranchInfo * ltage_bi = static_cast<LTageBranchInfo *>(bi);
34413455Spau.cabre@metempsy.com
34513455Spau.cabre@metempsy.com    if (ltage_bi->provider == LOOP) {
34613455Spau.cabre@metempsy.com        if (taken == ltage_bi->loopPred) {
34713455Spau.cabre@metempsy.com            loopPredictorCorrect++;
34813455Spau.cabre@metempsy.com        } else {
34913455Spau.cabre@metempsy.com            loopPredictorWrong++;
35013455Spau.cabre@metempsy.com        }
35113455Spau.cabre@metempsy.com    }
35213455Spau.cabre@metempsy.com}
35313455Spau.cabre@metempsy.com
35413455Spau.cabre@metempsy.com
35513455Spau.cabre@metempsy.com
35613455Spau.cabre@metempsy.comvoid
35713455Spau.cabre@metempsy.comLTAGE::regStats()
35813455Spau.cabre@metempsy.com{
35913455Spau.cabre@metempsy.com    TAGE::regStats();
36013455Spau.cabre@metempsy.com
36113455Spau.cabre@metempsy.com    loopPredictorCorrect
36213455Spau.cabre@metempsy.com        .name(name() + ".loopPredictorCorrect")
36313455Spau.cabre@metempsy.com        .desc("Number of times the loop predictor is the provider and "
36413455Spau.cabre@metempsy.com              "the prediction is correct");
36513455Spau.cabre@metempsy.com
36613455Spau.cabre@metempsy.com    loopPredictorWrong
36713455Spau.cabre@metempsy.com        .name(name() + ".loopPredictorWrong")
36813455Spau.cabre@metempsy.com        .desc("Number of times the loop predictor is the provier and "
36913455Spau.cabre@metempsy.com              "the prediction is wrong");
37013455Spau.cabre@metempsy.com}
37113455Spau.cabre@metempsy.com
37213455Spau.cabre@metempsy.com
37313455Spau.cabre@metempsy.com
37411784Sarthur.perais@inria.frLTAGE*
37511784Sarthur.perais@inria.frLTAGEParams::create()
37611784Sarthur.perais@inria.fr{
37711784Sarthur.perais@inria.fr    return new LTAGE(this);
37811784Sarthur.perais@inria.fr}
379