/*
 * Copyright 2019 Texas A&M University
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  Author: Daniel A. Jiménez
 *  Adapted to gem5 by: Javier Bueno Hedo
 *
 */

 /*
  * Multiperspective Perceptron Predictor (by Daniel A. Jiménez)
  */

#include "cpu/pred/multiperspective_perceptron.hh"

#include "base/random.hh"
#include "debug/Branch.hh"

namespace gem5
{

int
MultiperspectivePerceptron::xlat[] =
    {1,3,4,5,7,8,9,11,12,14,15,17,19,21,23,25,27,29,32,34,37,41,45,49,53,58,63,
     69,76,85,94,106,};
int
MultiperspectivePerceptron::xlat4[] =
    {0,4,5,7,9,11,12,14,16,17,19,22,28,33,39,45,};

MultiperspectivePerceptron::ThreadData::ThreadData(int num_filters,
        int n_local_histories, int local_history_length, int assoc,
        const std::vector<std::vector<int>> &blurrypath_bits, int path_length,
        int ghist_length, int block_size,
        const std::vector<std::vector<std::vector<bool>>> &acyclic_bits,
        const std::vector<int> &modhist_indices,
        const std::vector<int> &modhist_lengths,
        const std::vector<int> &modpath_indices,
        const std::vector<int> &modpath_lengths,
        const std::vector<int> &table_sizes, int n_sign_bits)
      : filterTable(num_filters), acyclic_histories(acyclic_bits.size()),
        acyclic2_histories(acyclic_bits.size()),
        blurrypath_histories(blurrypath_bits.size()),
        ghist_words(ghist_length/block_size+1, 0),
        path_history(path_length, 0), imli_counter(4,0),
        localHistories(n_local_histories, local_history_length),
        recency_stack(assoc), last_ghist_bit(false), occupancy(0)
{
    for (int i = 0; i < blurrypath_bits.size(); i+= 1) {
        blurrypath_histories[i].resize(blurrypath_bits[i].size());
    }

    for (int i = 0; i < acyclic_bits.size(); i += 1) {
        acyclic_histories[i].resize(acyclic_bits[i].size());
        acyclic2_histories[i].resize(acyclic_bits[i].size());
    }

    int max_modhist_idx = -1;
    for (auto &elem : modhist_indices) {
        max_modhist_idx = (max_modhist_idx < elem) ? elem : max_modhist_idx;
    }
    if (max_modhist_idx >= 0) {
        mod_histories.resize(max_modhist_idx + 1);
    }
    for (int i = 0; i < modhist_lengths.size(); i+= 1) {
        mod_histories[modhist_indices[i]].resize(modhist_lengths[i]);
    }

    int max_modpath_idx = -1;
    for (auto &elem : modpath_indices) {
        max_modpath_idx = (max_modpath_idx < elem) ? elem : max_modpath_idx;
    }
    if (max_modpath_idx >= 0) {
        modpath_histories.resize(max_modpath_idx + 1);
    }
    for (int i = 0; i < modpath_lengths.size(); i+= 1) {
        modpath_histories[modpath_indices[i]].resize(modpath_lengths[i]);
    }

    for (int i = 0; i < table_sizes.size(); i += 1) {
        mpreds.push_back(0);
        tables.push_back(std::vector<short int>(table_sizes[i]));
        sign_bits.push_back(std::vector<std::array<bool, 2>>(table_sizes[i]));
        for (int j = 0; j < table_sizes[i]; j += 1) {
            for (int k = 0; k < n_sign_bits; k += 1) {
                sign_bits[i][j][k] = (i & 1) | (k & 1);
            }
        }
    }
}

MultiperspectivePerceptron::MultiperspectivePerceptron(
    const MultiperspectivePerceptronParams &p) : BPredUnit(p),
    blockSize(p.block_size), pcshift(p.pcshift), threshold(p.threshold),
    bias0(p.bias0), bias1(p.bias1), biasmostly0(p.biasmostly0),
    biasmostly1(p.biasmostly1), nbest(p.nbest), tunebits(p.tunebits),
    hshift(p.hshift), imli_mask1(p.imli_mask1), imli_mask4(p.imli_mask4),
    recencypos_mask(p.recencypos_mask), fudge(p.fudge),
    n_sign_bits(p.n_sign_bits), pcbit(p.pcbit), decay(p.decay),
    record_mask(p.record_mask), hash_taken(p.hash_taken),
    tuneonly(p.tuneonly), extra_rounds(p.extra_rounds), speed(p.speed),
    budgetbits(p.budgetbits), speculative_update(p.speculative_update),
    threadData(p.numThreads, nullptr), doing_local(false),
    doing_recency(false), assoc(0), ghist_length(p.initial_ghist_length),
    modghist_length(1), path_length(1), thresholdCounter(0),
    theta(p.initial_theta), extrabits(0), imli_counter_bits(4),
    modhist_indices(), modhist_lengths(), modpath_indices(), modpath_lengths()
{
    fatal_if(speculative_update, "Speculative update not implemented");
}

void
MultiperspectivePerceptron::setExtraBits(int bits)
{
    extrabits = bits;
}

void
MultiperspectivePerceptron::init()
{
    createSpecs();

    for (auto &spec : specs) {
        // initial assignation of values
        table_sizes.push_back(spec->size);
    }

    // Update bit requirements and runtime values
    for (auto &spec : specs) {
        spec->setBitRequirements();
    }
    const MultiperspectivePerceptronParams &p =
        static_cast<const MultiperspectivePerceptronParams &>(params());

    computeBits(p.num_filter_entries, p.num_local_histories,
                p.local_history_length, p.ignore_path_size);

    for (int i = 0; i < threadData.size(); i += 1) {
        threadData[i] = new ThreadData(p.num_filter_entries,
                                       p.num_local_histories,
                                       p.local_history_length, assoc,
                                       blurrypath_bits, path_length,
                                       ghist_length, blockSize, acyclic_bits,
                                       modhist_indices, modhist_lengths,
                                       modpath_indices, modpath_lengths,
                                       table_sizes, n_sign_bits);
    }
}

void
MultiperspectivePerceptron::computeBits(int num_filter_entries,
        int nlocal_histories, int local_history_length, bool ignore_path_size)
{
    int totalbits = extrabits;
    for (auto &imli_bits : imli_counter_bits) {
        totalbits += imli_bits;
    }
    totalbits += ghist_length;
    if (!ignore_path_size) {
        totalbits += path_length * 16;
    }
    totalbits += (threshold >= 0) ? (tunebits * specs.size()) : 0;
    for (auto &len : modhist_lengths) {
        totalbits += len;
    }
    if (!ignore_path_size) {
        for (auto &len : modpath_lengths) {
            totalbits += 16 * len;
        }
    }
    totalbits += doing_local ? (nlocal_histories * local_history_length) : 0;
    totalbits += doing_recency ? (assoc * 16) : 0;

    for (auto &bv : blurrypath_bits) {
        for (auto &bve : bv) {
            totalbits += bve;
        }
    }
    totalbits += num_filter_entries * 2;

    for (auto &abi : acyclic_bits) {
        for (auto &abj : abi) {
            for (auto abk : abj) {
                totalbits += abk;
            }
        }
    }

    int remaining = budgetbits - totalbits;

    // count the tables that have already been assigned sizes
    int num_sized = 0;
    for (int i = 0; i < specs.size(); i +=1) {
        if (table_sizes[i] != 0) {
            int sz = table_sizes[i] * (specs[i]->width + (n_sign_bits - 1));
            totalbits += sz;
            remaining -= sz;
            num_sized += 1;
        }
    }

    // whatever is left, we divide among the rest of the tables
    int table_size_bits = (remaining / (specs.size()-num_sized));
    for (int i = 0; i < specs.size(); i += 1) {
        // if a table doesn't have a size yet, give it one and count those bits
        if (!table_sizes[i]) {
            int my_table_size = table_size_bits /
                (specs[i]->width + (n_sign_bits - 1)); // extra sign bits
            table_sizes[i] = my_table_size;
            totalbits += my_table_size * (specs[i]->width + (n_sign_bits - 1));
        }
    }

    DPRINTF(Branch, "%d bits of metadata so far, %d left out of "
            "%d total budget\n", totalbits, remaining, budgetbits);
    DPRINTF(Branch, "table size is %d bits, %d entries for 5 bit, %d entries "
            "for 6 bit\n", table_size_bits,
            table_size_bits / (5 + (n_sign_bits - 1)),
            table_size_bits / (6 + (n_sign_bits - 1)));
    DPRINTF(Branch, "%d total bits (%0.2fKB)\n", totalbits,
            totalbits / 8192.0);
}

void
MultiperspectivePerceptron::findBest(ThreadID tid,
                                     std::vector<int> &best_preds) const
{
    if (threshold < 0) {
        return;
    }
    struct BestPair
    {
        int index;
        int mpreds;
        bool operator<(BestPair const &bp) const
        {
            return mpreds < bp.mpreds;
        }
    };
    std::vector<BestPair> pairs(best_preds.size());
    for (int i = 0; i < best_preds.size(); i += 1) {
        pairs[i].index = i;
        pairs[i].mpreds = threadData[tid]->mpreds[i];
    }
    std::sort(pairs.begin(), pairs.end());
    for (int i = 0; i < (std::min(nbest, (int) best_preds.size())); i += 1) {
        best_preds[i] = pairs[i].index;
    }
}

unsigned int
MultiperspectivePerceptron::getIndex(ThreadID tid, const MPPBranchInfo &bi,
                                     const HistorySpec &spec, int index) const
{
    unsigned int g = spec.getHash(tid, bi.getPC(), bi.getPC2(), index);
    unsigned long long int h = g;
     // shift the hash from the feature to xor with the hashed PC
    if (hshift < 0) {
        h <<= -hshift;
        h ^= bi.getPC2();
    } else {
        h <<= hshift;
        h ^= bi.getHPC();
    }
    // xor in the imli counter(s) and/or recency position based on the masks
    if ((1ull<<index) & imli_mask1) {
        h ^= threadData[tid]->imli_counter[0];
    }
    if ((1ull<<index) & imli_mask4) {
        h ^= threadData[tid]->imli_counter[3];
    }
    if (doing_recency) {
        if ((1ull<<index) & recencypos_mask) {
            h ^= RECENCYPOS::hash(threadData[tid]->recency_stack, table_sizes,
                    bi.getPC2(), 31, index);
        }
    }
    h %= table_sizes[index];
    return h;
}

int
MultiperspectivePerceptron::computeOutput(ThreadID tid, MPPBranchInfo &bi)
{
    // list of best predictors
    std::vector<int> best_preds(specs.size(), -1);

    // initialize sum
    bi.yout = 0;

    // bias the prediction by whether the local history is
    // one of four distinctive patterns
    int lhist = threadData[tid]->localHistories[bi.getPC()];
    int history_len = threadData[tid]->localHistories.getLocalHistoryLength();
    if (lhist == 0) {
        bi.yout = bias0;
    } else if (lhist == ((1<<history_len)-1)) {
        bi.yout = bias1;
    } else if (lhist == (1<<(history_len-1))) {
        bi.yout = biasmostly0;
    } else if (lhist == ((1<<(history_len-1))-1)) {
        bi.yout = biasmostly1;
    }
    // find the best subset of features to use in case of a low-confidence
    // branch
    findBest(tid, best_preds);

    // begin computation of the sum for low-confidence branch
    int bestval = 0;

    for (int i = 0; i < specs.size(); i += 1) {
        HistorySpec const &spec = *specs[i];
        // get the hash to index the table
        unsigned int hashed_idx = getIndex(tid, bi, spec, i);
        // add the weight; first get the weight's magnitude
        int counter = threadData[tid]->tables[i][hashed_idx];
        // get the sign
        bool sign =
          threadData[tid]->sign_bits[i][hashed_idx][bi.getHPC() % n_sign_bits];
        // apply the transfer function and multiply by a coefficient
        int weight = spec.coeff * ((spec.width == 5) ?
                                   xlat4[counter] : xlat[counter]);
        // apply the sign
        int val = sign ? -weight : weight;
        // add the value
        bi.yout += val;
        // if this is one of those good features, add the value to bestval
        if (threshold >= 0) {
            for (int j = 0;
                 j < std::min(nbest, (int) best_preds.size());
                 j += 1)
            {
                if (best_preds[j] == i) {
                    bestval += val;
                    break;
                }
            }
        }
    }
    // apply a fudge factor to affect when training is triggered
    bi.yout *= fudge;
    return bestval;
}

void
MultiperspectivePerceptron::satIncDec(bool taken, bool &sign, int &counter,
                                      int max_weight) const
{
    if (taken) {
        // increment sign/magnitude
        if (sign) {
            // go toward 0 away from negative max weight
            if (counter == 0) {
                sign = false; // moved to positive 0
            } else {
                counter -= 1;
            }
        } else {
            // go toward max weight away from 0
            if (counter < max_weight) {
                counter += 1;
            }
        }
    } else {
        // decrement sign/magnitude
        if (sign) {
            // go toward negative max weight down from 0
            if (counter < max_weight) {
                counter += 1;
            }
        } else {
            // go toward 0 away from max weight
            if (counter == 0) {
                sign = true; // negative 0
            } else {
                counter -= 1;
            }
        }
    }
}

void
MultiperspectivePerceptron::train(ThreadID tid, MPPBranchInfo &bi, bool taken)
{
    std::vector<std::vector<short int>> &tables = threadData[tid]->tables;
    std::vector<std::vector<std::array<bool, 2>>> &sign_bits =
            threadData[tid]->sign_bits;
    std::vector<int> &mpreds = threadData[tid]->mpreds;
    // was the prediction correct?
    bool correct = (bi.yout >= 1) == taken;
    // what is the magnitude of yout?
    int abs_yout = abs(bi.yout);
    // keep track of mispredictions per table
    if (threshold >= 0) if (!tuneonly || (abs_yout <= threshold)) {
        bool halve = false;

        // for each table, figure out if there was a misprediction
        for (int i = 0; i < specs.size(); i += 1) {
            HistorySpec const &spec = *specs[i];
            // get the hash to index the table
            unsigned int hashed_idx = getIndex(tid, bi, spec, i);
            bool sign = sign_bits[i][hashed_idx][bi.getHPC() % n_sign_bits];
            int counter = tables[i][hashed_idx];
            int weight = spec.coeff * ((spec.width == 5) ?
                                       xlat4[counter] : xlat[counter]);
            if (sign) weight = -weight;
            bool pred = weight >= 1;
            if (pred != taken) {
                mpreds[i] += 1;
                if (mpreds[i] == (1 << tunebits) - 1) {
                    halve = true;
                }
            }
        }
        // if we reach the maximum counter value, halve all the counters
        if (halve) {
            for (int i = 0; i < specs.size(); i += 1) {
                mpreds[i] /= 2;
            }
        }
    }
    // if the branch was predicted incorrectly or the correct
    // prediction was weak, update the weights
    bool do_train = !correct || (abs_yout <= theta);
    if (!do_train) return;

    // adaptive theta training, adapted from O-GEHL
    if (!correct) {
        thresholdCounter += 1;
        if (thresholdCounter >= speed) {
            theta += 1;
            thresholdCounter = 0;
        }
    }
    if (correct && abs_yout < theta) {
        thresholdCounter -= 1;
        if (thresholdCounter <= -speed) {
            theta -= 1;
            thresholdCounter = 0;
        }
    }

    // train the weights, computing what the value of yout
    // would have been if these updates had been applied before
    int newyout = 0;
    for (int i = 0; i < specs.size(); i += 1) {
        HistorySpec const &spec = *specs[i];
        // get the magnitude
        unsigned int hashed_idx = getIndex(tid, bi, spec, i);
        int counter = tables[i][hashed_idx];
        // get the sign
        bool sign = sign_bits[i][hashed_idx][bi.getHPC() % n_sign_bits];
        // increment/decrement if taken/not taken
        satIncDec(taken, sign, counter, (1 << (spec.width - 1)) - 1);
        // update the magnitude and sign
        tables[i][hashed_idx] = counter;
        sign_bits[i][hashed_idx][bi.getHPC() % n_sign_bits] = sign;
        int weight = ((spec.width == 5) ? xlat4[counter] : xlat[counter]);
        // update the new version of yout
        if (sign) {
            newyout -= weight;
        } else {
            newyout += weight;
        }
    }

    // if the prediction still would have been incorrect even
    // with the updated weights, update some more weights to
    // try to fix the problem
    if ((newyout >= 1) != taken) {
        if (extra_rounds != -1) {
            int round_counter = 0;
            bool found;
            do {
                // udpate a random weight
                int besti = -1;
                int nrand = random_mt.random<int>() % specs.size();
                int pout;
                found = false;
                for (int j = 0; j < specs.size(); j += 1) {
                    int i = (nrand + j) % specs.size();
                    HistorySpec const &spec = *specs[i];
                    unsigned int hashed_idx = getIndex(tid, bi, spec, i);
                    int counter = tables[i][hashed_idx];
                    bool sign =
                        sign_bits[i][hashed_idx][bi.getHPC() % n_sign_bits];
                    int weight = ((spec.width == 5) ?
                            xlat4[counter] : xlat[counter]);
                    int signed_weight = sign ? -weight : weight;
                    pout = newyout - signed_weight;
                    if ((pout >= 1) == taken) {
                        // we have found a weight that if we blow
                        // it away will help!
                        besti = i;
                        break;
                    }
                }
                if (besti != -1) {
                    int i = besti;
                    HistorySpec const &spec = *specs[i];
                    unsigned int hashed_idx = getIndex(tid, bi, spec, i);
                    int counter = tables[i][hashed_idx];
                    bool sign =
                        sign_bits[i][hashed_idx][bi.getHPC() % n_sign_bits];
                    if (counter > 1) {
                        counter--;
                        tables[i][hashed_idx] = counter;
                    }
                    int weight = ((spec.width == 5) ?
                            xlat4[counter] : xlat[counter]);
                    int signed_weight = sign ? -weight : weight;
                    int out = pout + signed_weight;
                    round_counter += 1;
                    if ((out >= 1) != taken) {
                        found = true;
                    }
                }
            } while (found && round_counter < extra_rounds);
        }
    }
}

void
MultiperspectivePerceptron::uncondBranch(ThreadID tid, Addr pc,
                                         void * &bp_history)
{
    MPPBranchInfo *bi = new MPPBranchInfo(pc, pcshift, false);
    std::vector<unsigned int> &ghist_words = threadData[tid]->ghist_words;

    bp_history = (void *)bi;
    unsigned short int pc2 = pc >> 2;
    bool ab = !(pc & (1<<pcbit));
    for (int i = 0; i < ghist_length / blockSize + 1; i += 1) {
        bool ab_new = (ghist_words[i] >> (blockSize - 1)) & 1;
        ghist_words[i] <<= 1;
        ghist_words[i] |= ab;
        ghist_words[i] &= (1 << blockSize) - 1;
        ab = ab_new;
    }
    memmove(&threadData[tid]->path_history[1],
            &threadData[tid]->path_history[0],
            sizeof(unsigned short int) * (path_length - 1));
    threadData[tid]->path_history[0] = pc2;
}

bool
MultiperspectivePerceptron::lookup(ThreadID tid, Addr instPC,
                                   void * &bp_history)
{
    MPPBranchInfo *bi = new MPPBranchInfo(instPC, pcshift, true);
    bp_history = (void *)bi;

    bool use_static = false;

    if (!threadData[tid]->filterTable.empty()) {
        unsigned int findex =
            bi->getHashFilter(threadData[tid]->last_ghist_bit) %
            threadData[tid]->filterTable.size();
        FilterEntry &f = threadData[tid]->filterTable[findex];
        if (f.alwaysNotTakenSoFar()) {
            bi->filtered = true;
            bi->prediction = false;
            return false;
        } else if (f.alwaysTakenSoFar()) {
            bi->filtered = true;
            bi->prediction = true;
            return true;
        }
        if (f.neverSeen()) {
            use_static = true;
        }
    }

    int bestval = computeOutput(tid, *bi);
    if (use_static) {
        bi->prediction = false;
    } else {
        if (abs(bi->yout) <= threshold) {
            bi->prediction = (bestval >= 1);
        } else {
            bi->prediction = (bi->yout >= 1);
        }
    }

    return bi->prediction;
}

void
MultiperspectivePerceptron::update(ThreadID tid, Addr instPC, bool taken,
                                   void *bp_history, bool squashed,
                                   const StaticInstPtr & inst,
                                   Addr corrTarget)
{
    assert(bp_history);
    MPPBranchInfo *bi = static_cast<MPPBranchInfo*>(bp_history);
    if (squashed) {
        //delete bi;
        return;
    }

    if (bi->isUnconditional()) {
        delete bi;
        return;
    }

    bool do_train = true;

    if (!threadData[tid]->filterTable.empty()) {
        int findex = bi->getHashFilter(threadData[tid]->last_ghist_bit) %
                                       threadData[tid]->filterTable.size();
        FilterEntry &f = threadData[tid]->filterTable[findex];

        // compute this first, so we don't not train on the
        // first time a branch is seen.
        bool transition = false;
        if (f.alwaysNotTakenSoFar() || f.alwaysTakenSoFar()) {
            do_train = false;
        }
        if (taken) {
            if (f.alwaysNotTakenSoFar()) {
                transition = true;
            }
            f.seenTaken = true;
        } else {
            if (f.alwaysTakenSoFar()) {
                transition = true;
            }
            f.seenUntaken = true;
        }
        // is this the first time time the branch has gone both ways?
        if (transition) {
            threadData[tid]->occupancy += 1;
        }
        // for every new dynamic branch, when there ar
        // more than 'decay' number of branches in the
        // filter, blow a random filter entry away
        if (decay && transition &&
            ((threadData[tid]->occupancy > decay) || (decay == 1))) {
            int rnd = random_mt.random<int>() %
                      threadData[tid]->filterTable.size();
            FilterEntry &frand = threadData[tid]->filterTable[rnd];
            if (frand.seenTaken && frand.seenUntaken) {
                threadData[tid]->occupancy -= 1;
            }
            frand.seenTaken = false;
            frand.seenUntaken = false;
        }
    }

    if (do_train) {
        train(tid, *bi, taken);
    }

    enum RecordFiltered
    {
        Imli = 1,
        GHist = 2,
        Path = 4,
        Acyclic = 8,
        Mod = 16,
        Blurry = 32,
        // Should never record a filtered local branch - duh!
        Local = 64,
        Recency = 128
    };

    // four different styles of IMLI
    if (!bi->filtered || (record_mask & Imli)) {
        unsigned int target = corrTarget;
        if (target < bi->getPC()) {
            if (taken) {
                threadData[tid]->imli_counter[0] += 1;
            } else {
                threadData[tid]->imli_counter[0] = 0;
            }
            if (!taken) {
                threadData[tid]->imli_counter[1] += 1;
            } else {
                threadData[tid]->imli_counter[1] = 0;
            }
        } else {
            if (taken) {
                threadData[tid]->imli_counter[2] += 1;
            } else {
                threadData[tid]->imli_counter[2] = 0;
            }
            if (!taken) {
                threadData[tid]->imli_counter[3] += 1;
            } else {
                threadData[tid]->imli_counter[3] = 0;
            }
        }
    }

    bool hashed_taken = hash_taken ? (taken ^ !!(bi->getPC() & (1<<pcbit)))
                                   : taken;
    // record into ghist
    if (!bi->filtered || (record_mask & GHist)) {
        bool ab = hashed_taken;
        assert(threadData[tid]->ghist_words.size() > 0);
        for (int i = 0; i < ghist_length / blockSize + 1; i += 1) {
            unsigned int a = threadData[tid]->ghist_words[i];
            bool ab_new = (a >> (blockSize - 1)) & 1;
            a <<= 1;
            a |= ab;
            ab = ab_new;
            a &= (1 << blockSize) - 1;
            threadData[tid]->ghist_words[i] = a;
        }
    }

    // record into path history
    if (!bi->filtered || (record_mask & Path)) {
        assert(threadData[tid]->path_history.size() > 0);
        memmove(&threadData[tid]->path_history[1],
                &threadData[tid]->path_history[0],
                sizeof(unsigned short int) * (path_length - 1));
        threadData[tid]->path_history[0] = bi->getPC2();
    }

    // record into acyclic history
    if (!bi->filtered || (record_mask & Acyclic)) {
        threadData[tid]->updateAcyclic(hashed_taken, bi->getHPC());
    }

    // record into modulo path history
    if (!bi->filtered || (record_mask & Mod)) {
        for (int ii = 0; ii < modpath_indices.size(); ii += 1) {
            int i = modpath_indices[ii];
            if (bi->getHPC() % (i + 2) == 0) {
                memmove(&threadData[tid]->modpath_histories[i][1],
                        &threadData[tid]->modpath_histories[i][0],
                        sizeof(unsigned short int) * (modpath_lengths[ii]-1));
                threadData[tid]->modpath_histories[i][0] = bi->getPC2();
            }
        }
    }

    // update blurry history
    if (!bi->filtered || (record_mask & Blurry)) {
        std::vector<std::vector<unsigned int>> &blurrypath_histories =
             threadData[tid]->blurrypath_histories;

        for (int i = 0; i < blurrypath_histories.size(); i += 1)
        {
            if (blurrypath_histories[i].size() > 0) {
                unsigned int z = bi->getPC() >> i;
                if (blurrypath_histories[i][0] != z) {
                    memmove(&blurrypath_histories[i][1],
                            &blurrypath_histories[i][0],
                            sizeof(unsigned int) *
                            (blurrypath_histories[i].size() - 1));
                    blurrypath_histories[i][0] = z;
                }
            }
        }
    }

    // record into modulo pattern history
    if (!bi->filtered || (record_mask & Mod)) {
        for (int ii = 0; ii < modhist_indices.size(); ii += 1) {
            int i = modhist_indices[ii];
            if (bi->getHPC() % (i + 2) == 0) {
                for (int j = modhist_lengths[ii] - 1; j > 0; j -= 1) {
                    threadData[tid]->mod_histories[i][j] =
                        threadData[tid]->mod_histories[i][j-1];
                }
                threadData[tid]->mod_histories[i][0] = hashed_taken;
            }
        }
    }

    // insert this PC into the recency stack
    if (doing_recency) {
        if (!bi->filtered || (record_mask & Recency)) {
            threadData[tid]->insertRecency(bi->getPC2(), assoc);
        }
    }

    // record into a local history
    if (!bi->filtered || (record_mask & Local)) {
        threadData[tid]->localHistories.update(bi->getPC(), hashed_taken);
    }

    // update last ghist bit, used to index filter
    threadData[tid]->last_ghist_bit = taken;

    delete bi;
}

void
MultiperspectivePerceptron::btbUpdate(ThreadID tid, Addr branch_pc,
                                      void* &bp_history)
{
}

void
MultiperspectivePerceptron::squash(ThreadID tid, void *bp_history)
{
    assert(bp_history);
    MPPBranchInfo *bi = static_cast<MPPBranchInfo*>(bp_history);
    delete bi;
}

} // namespace gem5
