ltage.cc revision 13626
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;
17113626Sjairo.balart@metempsy.com            } else if (bi->loopPred != bi->tageBranchInfo->tagePred) {
17211784Sarthur.perais@inria.fr                DPRINTF(LTage, "Loop Prediction success:%lx\n",pc);
17313626Sjairo.balart@metempsy.com                TAGEBase::unsignedCtrUpdate(ltable[idx].age, true,
17413626Sjairo.balart@metempsy.com                                            loopTableAgeBits);
17511784Sarthur.perais@inria.fr            }
17611784Sarthur.perais@inria.fr        }
17711784Sarthur.perais@inria.fr
17813442Spau.cabre@metempsy.com        ltable[idx].currentIter =
17913442Spau.cabre@metempsy.com            (ltable[idx].currentIter + 1) & loopNumIterMask;
18011784Sarthur.perais@inria.fr        if (ltable[idx].currentIter > ltable[idx].numIter) {
18111784Sarthur.perais@inria.fr            ltable[idx].confidence = 0;
18211784Sarthur.perais@inria.fr            if (ltable[idx].numIter != 0) {
18311784Sarthur.perais@inria.fr                // free the entry
18411784Sarthur.perais@inria.fr                ltable[idx].numIter = 0;
18511784Sarthur.perais@inria.fr                ltable[idx].age = 0;
18611784Sarthur.perais@inria.fr                ltable[idx].confidence = 0;
18711784Sarthur.perais@inria.fr            }
18811784Sarthur.perais@inria.fr        }
18911784Sarthur.perais@inria.fr
19013493Spau.cabre@metempsy.com        if (taken != (useDirectionBit ? ltable[idx].dir : true)) {
19111784Sarthur.perais@inria.fr            if (ltable[idx].currentIter == ltable[idx].numIter) {
19211784Sarthur.perais@inria.fr                DPRINTF(LTage, "Loop End predicted successfully:%lx\n", pc);
19311784Sarthur.perais@inria.fr
19413626Sjairo.balart@metempsy.com                TAGEBase::unsignedCtrUpdate(ltable[idx].confidence, true,
19513442Spau.cabre@metempsy.com                                  loopTableConfidenceBits);
19611784Sarthur.perais@inria.fr                //just do not predict when the loop count is 1 or 2
19711784Sarthur.perais@inria.fr                if (ltable[idx].numIter < 3) {
19811784Sarthur.perais@inria.fr                    // free the entry
19913493Spau.cabre@metempsy.com                    ltable[idx].dir = taken; // ignored if no useDirectionBit
20011784Sarthur.perais@inria.fr                    ltable[idx].numIter = 0;
20111784Sarthur.perais@inria.fr                    ltable[idx].age = 0;
20211784Sarthur.perais@inria.fr                    ltable[idx].confidence = 0;
20311784Sarthur.perais@inria.fr                }
20411784Sarthur.perais@inria.fr            } else {
20511784Sarthur.perais@inria.fr                DPRINTF(LTage, "Loop End predicted incorrectly:%lx\n", pc);
20611784Sarthur.perais@inria.fr                if (ltable[idx].numIter == 0) {
20711784Sarthur.perais@inria.fr                    // first complete nest;
20811784Sarthur.perais@inria.fr                    ltable[idx].confidence = 0;
20911784Sarthur.perais@inria.fr                    ltable[idx].numIter = ltable[idx].currentIter;
21011784Sarthur.perais@inria.fr                } else {
21111784Sarthur.perais@inria.fr                    //not the same number of iterations as last time: free the
21211784Sarthur.perais@inria.fr                    //entry
21311784Sarthur.perais@inria.fr                    ltable[idx].numIter = 0;
21411784Sarthur.perais@inria.fr                    ltable[idx].age = 0;
21511784Sarthur.perais@inria.fr                    ltable[idx].confidence = 0;
21611784Sarthur.perais@inria.fr                }
21711784Sarthur.perais@inria.fr            }
21811784Sarthur.perais@inria.fr            ltable[idx].currentIter = 0;
21911784Sarthur.perais@inria.fr        }
22011784Sarthur.perais@inria.fr
22113493Spau.cabre@metempsy.com    } else if (useDirectionBit ?
22213626Sjairo.balart@metempsy.com                ((bi->loopPredValid ?
22313626Sjairo.balart@metempsy.com                    bi->loopPred : bi->tageBranchInfo->tagePred) != taken) :
22413493Spau.cabre@metempsy.com                taken) {
22511784Sarthur.perais@inria.fr        //try to allocate an entry on taken branch
22613626Sjairo.balart@metempsy.com        int nrand = TAGEBase::getRandom();
22713444Spau.cabre@metempsy.com        for (int i = 0; i < (1 << logLoopTableAssoc); i++) {
22813444Spau.cabre@metempsy.com            int loop_hit = (nrand + i) & ((1 << logLoopTableAssoc) - 1);
22911784Sarthur.perais@inria.fr            idx = bi->loopIndex + loop_hit;
23011784Sarthur.perais@inria.fr            if (ltable[idx].age == 0) {
23111784Sarthur.perais@inria.fr                DPRINTF(LTage, "Allocating loop pred entry for branch %lx\n",
23211784Sarthur.perais@inria.fr                        pc);
23313493Spau.cabre@metempsy.com                ltable[idx].dir = !taken; // ignored if no useDirectionBit
23411784Sarthur.perais@inria.fr                ltable[idx].tag = bi->loopTag;
23511784Sarthur.perais@inria.fr                ltable[idx].numIter = 0;
23613442Spau.cabre@metempsy.com                ltable[idx].age = (1 << loopTableAgeBits) - 1;
23711784Sarthur.perais@inria.fr                ltable[idx].confidence = 0;
23811784Sarthur.perais@inria.fr                ltable[idx].currentIter = 1;
23911784Sarthur.perais@inria.fr                break;
24011784Sarthur.perais@inria.fr
24111784Sarthur.perais@inria.fr            }
24211784Sarthur.perais@inria.fr            else
24311784Sarthur.perais@inria.fr                ltable[idx].age--;
24411784Sarthur.perais@inria.fr        }
24511784Sarthur.perais@inria.fr    }
24611784Sarthur.perais@inria.fr
24711784Sarthur.perais@inria.fr}
24811784Sarthur.perais@inria.fr
24911784Sarthur.perais@inria.fr//prediction
25011784Sarthur.perais@inria.frbool
25111784Sarthur.perais@inria.frLTAGE::predict(ThreadID tid, Addr branch_pc, bool cond_branch, void* &b)
25211784Sarthur.perais@inria.fr{
25313626Sjairo.balart@metempsy.com    LTageBranchInfo *bi = new LTageBranchInfo(*tage);
25411784Sarthur.perais@inria.fr    b = (void*)(bi);
25513454Spau.cabre@metempsy.com
25613626Sjairo.balart@metempsy.com    bool pred_taken = tage->tagePredict(tid, branch_pc, cond_branch,
25713626Sjairo.balart@metempsy.com                                        bi->tageBranchInfo);
25811784Sarthur.perais@inria.fr
25911784Sarthur.perais@inria.fr    if (cond_branch) {
26013493Spau.cabre@metempsy.com        // loop prediction
26113493Spau.cabre@metempsy.com        bi->loopPred = getLoop(branch_pc, bi, useSpeculation);
26211784Sarthur.perais@inria.fr
26313454Spau.cabre@metempsy.com        if ((loopUseCounter >= 0) && bi->loopPredValid) {
26413454Spau.cabre@metempsy.com            pred_taken = bi->loopPred;
26513626Sjairo.balart@metempsy.com            bi->tageBranchInfo->provider = LOOP;
26611784Sarthur.perais@inria.fr        }
26711784Sarthur.perais@inria.fr        DPRINTF(LTage, "Predict for %lx: taken?:%d, loopTaken?:%d, "
26811784Sarthur.perais@inria.fr                "loopValid?:%d, loopUseCounter:%d, tagePred:%d, altPred:%d\n",
26911784Sarthur.perais@inria.fr                branch_pc, pred_taken, bi->loopPred, bi->loopPredValid,
27013626Sjairo.balart@metempsy.com                loopUseCounter, bi->tageBranchInfo->tagePred,
27113626Sjairo.balart@metempsy.com                bi->tageBranchInfo->altTaken);
27213493Spau.cabre@metempsy.com
27313493Spau.cabre@metempsy.com        if (useSpeculation) {
27413493Spau.cabre@metempsy.com            specLoopUpdate(pred_taken, bi);
27513493Spau.cabre@metempsy.com        }
27611784Sarthur.perais@inria.fr    }
27713454Spau.cabre@metempsy.com
27811784Sarthur.perais@inria.fr    return pred_taken;
27911784Sarthur.perais@inria.fr}
28011784Sarthur.perais@inria.fr
28111784Sarthur.perais@inria.frvoid
28213626Sjairo.balart@metempsy.comLTAGE::update(ThreadID tid, Addr branch_pc, bool taken, void* bp_history,
28313626Sjairo.balart@metempsy.com              bool squashed, const StaticInstPtr & inst, Addr corrTarget)
28411784Sarthur.perais@inria.fr{
28513626Sjairo.balart@metempsy.com    assert(bp_history);
28611784Sarthur.perais@inria.fr
28713626Sjairo.balart@metempsy.com    LTageBranchInfo* bi = static_cast<LTageBranchInfo*>(bp_history);
28813626Sjairo.balart@metempsy.com
28913626Sjairo.balart@metempsy.com    if (squashed) {
29013626Sjairo.balart@metempsy.com        if (tage->isSpeculativeUpdateEnabled()) {
29113626Sjairo.balart@metempsy.com            // This restores the global history, then update it
29213626Sjairo.balart@metempsy.com            // and recomputes the folded histories.
29313626Sjairo.balart@metempsy.com            tage->squash(tid, taken, bi->tageBranchInfo, corrTarget);
29413626Sjairo.balart@metempsy.com            squashLoop(bi);
29513626Sjairo.balart@metempsy.com        }
29613626Sjairo.balart@metempsy.com        return;
29713493Spau.cabre@metempsy.com    }
29811784Sarthur.perais@inria.fr
29913626Sjairo.balart@metempsy.com    int nrand = TAGEBase::getRandom() & 3;
30013626Sjairo.balart@metempsy.com    if (bi->tageBranchInfo->condBranch) {
30113626Sjairo.balart@metempsy.com        DPRINTF(LTage, "Updating tables for branch:%lx; taken?:%d\n",
30213626Sjairo.balart@metempsy.com                branch_pc, taken);
30313626Sjairo.balart@metempsy.com        tage->updateStats(taken, bi->tageBranchInfo);
30413626Sjairo.balart@metempsy.com        // update stats
30513626Sjairo.balart@metempsy.com        if (bi->tageBranchInfo->provider == LOOP) {
30613626Sjairo.balart@metempsy.com            if (taken == bi->loopPred) {
30713626Sjairo.balart@metempsy.com                loopPredictorCorrect++;
30813626Sjairo.balart@metempsy.com            } else {
30913626Sjairo.balart@metempsy.com                loopPredictorWrong++;
31013626Sjairo.balart@metempsy.com            }
31113454Spau.cabre@metempsy.com        }
31213626Sjairo.balart@metempsy.com        // cond Branch Update
31313626Sjairo.balart@metempsy.com        if (useSpeculation) {
31413626Sjairo.balart@metempsy.com            // recalculate loop prediction without speculation
31513626Sjairo.balart@metempsy.com            // It is ok to overwrite the loop prediction fields in bi
31613626Sjairo.balart@metempsy.com            // as the stats have already been updated with the previous
31713626Sjairo.balart@metempsy.com            // values
31813626Sjairo.balart@metempsy.com            bi->loopPred = getLoop(branch_pc, bi, false);
31913626Sjairo.balart@metempsy.com        }
32013626Sjairo.balart@metempsy.com        if (bi->loopPredValid) {
32113626Sjairo.balart@metempsy.com            if (bi->tageBranchInfo->tagePred != bi->loopPred) {
32213626Sjairo.balart@metempsy.com                TAGEBase::ctrUpdate(loopUseCounter,
32313626Sjairo.balart@metempsy.com                        (bi->loopPred == taken),
32413626Sjairo.balart@metempsy.com                        withLoopBits);
32513626Sjairo.balart@metempsy.com            }
32613626Sjairo.balart@metempsy.com        }
32713626Sjairo.balart@metempsy.com
32813626Sjairo.balart@metempsy.com        loopUpdate(branch_pc, taken, bi);
32913626Sjairo.balart@metempsy.com
33013626Sjairo.balart@metempsy.com        tage->condBranchUpdate(tid, branch_pc, taken, bi->tageBranchInfo,
33113626Sjairo.balart@metempsy.com                               nrand, corrTarget);
33211784Sarthur.perais@inria.fr    }
33311784Sarthur.perais@inria.fr
33413626Sjairo.balart@metempsy.com    tage->updateHistories(tid, branch_pc, taken, bi->tageBranchInfo, false,
33513626Sjairo.balart@metempsy.com                          inst, corrTarget);
33613493Spau.cabre@metempsy.com
33713626Sjairo.balart@metempsy.com    delete bi;
33811784Sarthur.perais@inria.fr}
33911784Sarthur.perais@inria.fr
34011784Sarthur.perais@inria.frvoid
34113626Sjairo.balart@metempsy.comLTAGE::squashLoop(LTageBranchInfo* bi)
34211784Sarthur.perais@inria.fr{
34313626Sjairo.balart@metempsy.com    if (bi->tageBranchInfo->condBranch) {
34411784Sarthur.perais@inria.fr        if (bi->loopHit >= 0) {
34513493Spau.cabre@metempsy.com            int idx = finallindex(bi->loopIndex,
34613493Spau.cabre@metempsy.com                                  bi->loopLowPcBits,
34713493Spau.cabre@metempsy.com                                  bi->loopHit);
34811784Sarthur.perais@inria.fr            ltable[idx].currentIterSpec = bi->currentIter;
34911784Sarthur.perais@inria.fr        }
35011784Sarthur.perais@inria.fr    }
35111784Sarthur.perais@inria.fr}
35211784Sarthur.perais@inria.fr
35311784Sarthur.perais@inria.frvoid
35411784Sarthur.perais@inria.frLTAGE::squash(ThreadID tid, void *bp_history)
35511784Sarthur.perais@inria.fr{
35613454Spau.cabre@metempsy.com    LTageBranchInfo* bi = (LTageBranchInfo*)(bp_history);
35713626Sjairo.balart@metempsy.com
35813626Sjairo.balart@metempsy.com    if (bi->tageBranchInfo->condBranch) {
35913626Sjairo.balart@metempsy.com        squashLoop(bi);
36011784Sarthur.perais@inria.fr    }
36111784Sarthur.perais@inria.fr
36213454Spau.cabre@metempsy.com    TAGE::squash(tid, bp_history);
36311784Sarthur.perais@inria.fr}
36411784Sarthur.perais@inria.fr
36513455Spau.cabre@metempsy.comvoid
36613455Spau.cabre@metempsy.comLTAGE::regStats()
36713455Spau.cabre@metempsy.com{
36813455Spau.cabre@metempsy.com    TAGE::regStats();
36913455Spau.cabre@metempsy.com
37013455Spau.cabre@metempsy.com    loopPredictorCorrect
37113455Spau.cabre@metempsy.com        .name(name() + ".loopPredictorCorrect")
37213455Spau.cabre@metempsy.com        .desc("Number of times the loop predictor is the provider and "
37313455Spau.cabre@metempsy.com              "the prediction is correct");
37413455Spau.cabre@metempsy.com
37513455Spau.cabre@metempsy.com    loopPredictorWrong
37613455Spau.cabre@metempsy.com        .name(name() + ".loopPredictorWrong")
37713494Spau.cabre@metempsy.com        .desc("Number of times the loop predictor is the provider and "
37813455Spau.cabre@metempsy.com              "the prediction is wrong");
37913455Spau.cabre@metempsy.com}
38013455Spau.cabre@metempsy.com
38113455Spau.cabre@metempsy.com
38213455Spau.cabre@metempsy.com
38311784Sarthur.perais@inria.frLTAGE*
38411784Sarthur.perais@inria.frLTAGEParams::create()
38511784Sarthur.perais@inria.fr{
38611784Sarthur.perais@inria.fr    return new LTAGE(this);
38711784Sarthur.perais@inria.fr}
388