114034Sjavier.bueno@metempsy.com/* 214034Sjavier.bueno@metempsy.com * Copyright 2019 Texas A&M University 314034Sjavier.bueno@metempsy.com * 414034Sjavier.bueno@metempsy.com * Redistribution and use in source and binary forms, with or without 514034Sjavier.bueno@metempsy.com * modification, are permitted provided that the following conditions are met: 614034Sjavier.bueno@metempsy.com * 714034Sjavier.bueno@metempsy.com * 1. Redistributions of source code must retain the above copyright notice, 814034Sjavier.bueno@metempsy.com * this list of conditions and the following disclaimer. 914034Sjavier.bueno@metempsy.com * 1014034Sjavier.bueno@metempsy.com * 2. Redistributions in binary form must reproduce the above copyright notice, 1114034Sjavier.bueno@metempsy.com * this list of conditions and the following disclaimer in the documentation 1214034Sjavier.bueno@metempsy.com * and/or other materials provided with the distribution. 1314034Sjavier.bueno@metempsy.com * 1414034Sjavier.bueno@metempsy.com * 3. Neither the name of the copyright holder nor the names of its 1514034Sjavier.bueno@metempsy.com * contributors may be used to endorse or promote products derived from this 1614034Sjavier.bueno@metempsy.com * software without specific prior written permission. 1714034Sjavier.bueno@metempsy.com * 1814034Sjavier.bueno@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1914034Sjavier.bueno@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2014034Sjavier.bueno@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2114034Sjavier.bueno@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2214034Sjavier.bueno@metempsy.com * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2314034Sjavier.bueno@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2414034Sjavier.bueno@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2514034Sjavier.bueno@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2614034Sjavier.bueno@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2714034Sjavier.bueno@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2814034Sjavier.bueno@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2914034Sjavier.bueno@metempsy.com * 3014034Sjavier.bueno@metempsy.com * Author: Daniel A. Jiménez 3114034Sjavier.bueno@metempsy.com * Adapted to gem5 by: Javier Bueno Hedo 3214034Sjavier.bueno@metempsy.com * 3314034Sjavier.bueno@metempsy.com */ 3414034Sjavier.bueno@metempsy.com 3514034Sjavier.bueno@metempsy.com/* 3614034Sjavier.bueno@metempsy.com * Multiperspective Perceptron Predictor (by Daniel A. Jiménez) 3714034Sjavier.bueno@metempsy.com */ 3814034Sjavier.bueno@metempsy.com 3914034Sjavier.bueno@metempsy.com#ifndef __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_HH__ 4014034Sjavier.bueno@metempsy.com#define __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_HH__ 4114034Sjavier.bueno@metempsy.com 4214034Sjavier.bueno@metempsy.com#include <array> 4314034Sjavier.bueno@metempsy.com#include <vector> 4414034Sjavier.bueno@metempsy.com 4514034Sjavier.bueno@metempsy.com#include "cpu/pred/bpred_unit.hh" 4614034Sjavier.bueno@metempsy.com#include "params/MultiperspectivePerceptron.hh" 4714034Sjavier.bueno@metempsy.com 4814034Sjavier.bueno@metempsy.comclass MultiperspectivePerceptron : public BPredUnit 4914034Sjavier.bueno@metempsy.com{ 5014034Sjavier.bueno@metempsy.com protected: 5114034Sjavier.bueno@metempsy.com /** 5214034Sjavier.bueno@metempsy.com * Branch information data 5314034Sjavier.bueno@metempsy.com */ 5414034Sjavier.bueno@metempsy.com class MPPBranchInfo { 5514034Sjavier.bueno@metempsy.com /** pc of the branch */ 5614034Sjavier.bueno@metempsy.com const unsigned int pc; 5714034Sjavier.bueno@metempsy.com /** pc of the branch, shifted 2 bits to the right */ 5814034Sjavier.bueno@metempsy.com const unsigned short int pc2; 5914034Sjavier.bueno@metempsy.com /** pc of the branch, hashed */ 6014034Sjavier.bueno@metempsy.com const unsigned short int hpc; 6114034Sjavier.bueno@metempsy.com /** Whether this is a conditional branch */ 6214034Sjavier.bueno@metempsy.com const bool condBranch; 6314034Sjavier.bueno@metempsy.com 6414034Sjavier.bueno@metempsy.com /** 6514034Sjavier.bueno@metempsy.com * PC Hash functions 6614034Sjavier.bueno@metempsy.com */ 6714034Sjavier.bueno@metempsy.com static inline unsigned int hash1(unsigned int a) 6814034Sjavier.bueno@metempsy.com { 6914034Sjavier.bueno@metempsy.com a = (a ^ 0xdeadbeef) + (a<<4); 7014034Sjavier.bueno@metempsy.com a = a ^ (a>>10); 7114034Sjavier.bueno@metempsy.com a = a + (a<<7); 7214034Sjavier.bueno@metempsy.com a = a ^ (a>>13); 7314034Sjavier.bueno@metempsy.com return a; 7414034Sjavier.bueno@metempsy.com } 7514034Sjavier.bueno@metempsy.com 7614034Sjavier.bueno@metempsy.com static inline unsigned int hash2(unsigned int key) 7714034Sjavier.bueno@metempsy.com { 7814034Sjavier.bueno@metempsy.com int c2 = 0x27d4eb2d; // a prime or an odd constant 7914034Sjavier.bueno@metempsy.com key = (key ^ 61) ^ (key >> 16); 8014034Sjavier.bueno@metempsy.com key = key + (key << 3); 8114034Sjavier.bueno@metempsy.com key = key ^ (key >> 4); 8214034Sjavier.bueno@metempsy.com key = key * c2; 8314034Sjavier.bueno@metempsy.com key = key ^ (key >> 15); 8414034Sjavier.bueno@metempsy.com return key; 8514034Sjavier.bueno@metempsy.com } 8614034Sjavier.bueno@metempsy.com 8714034Sjavier.bueno@metempsy.com static inline unsigned int hash(unsigned int key, unsigned int i) 8814034Sjavier.bueno@metempsy.com { 8914034Sjavier.bueno@metempsy.com return hash2(key) * i + hash1(key); 9014034Sjavier.bueno@metempsy.com } 9114034Sjavier.bueno@metempsy.com 9214034Sjavier.bueno@metempsy.com static inline unsigned int hashPC(unsigned int pc, int pcshift) 9314034Sjavier.bueno@metempsy.com { 9414034Sjavier.bueno@metempsy.com if (pcshift < 0) { 9514034Sjavier.bueno@metempsy.com return hash(pc, -pcshift); 9614034Sjavier.bueno@metempsy.com } else if (pcshift < 11) { 9714034Sjavier.bueno@metempsy.com unsigned int x = pc; 9814034Sjavier.bueno@metempsy.com x ^= (pc >> pcshift); 9914034Sjavier.bueno@metempsy.com return x; 10014034Sjavier.bueno@metempsy.com } else { 10114034Sjavier.bueno@metempsy.com return pc >> (pcshift-11); 10214034Sjavier.bueno@metempsy.com } 10314034Sjavier.bueno@metempsy.com } 10414034Sjavier.bueno@metempsy.com 10514034Sjavier.bueno@metempsy.com public: 10614034Sjavier.bueno@metempsy.com /** Whether this branch has been filtered by the prefetcher */ 10714034Sjavier.bueno@metempsy.com bool filtered; 10814034Sjavier.bueno@metempsy.com /** Result of the prediction (true is taken) */ 10914034Sjavier.bueno@metempsy.com bool prediction; 11014034Sjavier.bueno@metempsy.com /** Score of the perceptron */ 11114034Sjavier.bueno@metempsy.com int yout; 11214034Sjavier.bueno@metempsy.com 11314034Sjavier.bueno@metempsy.com MPPBranchInfo(Addr _pc, int pcshift, bool cb) : pc((unsigned int)_pc), 11414034Sjavier.bueno@metempsy.com pc2(pc >> 2), hpc(hashPC(pc, pcshift)), condBranch(cb), 11514034Sjavier.bueno@metempsy.com filtered(false), prediction(false), yout(0) 11614034Sjavier.bueno@metempsy.com { } 11714034Sjavier.bueno@metempsy.com 11814034Sjavier.bueno@metempsy.com unsigned int getPC() const 11914034Sjavier.bueno@metempsy.com { 12014034Sjavier.bueno@metempsy.com return pc; 12114034Sjavier.bueno@metempsy.com } 12214034Sjavier.bueno@metempsy.com unsigned short int getPC2() const 12314034Sjavier.bueno@metempsy.com { 12414034Sjavier.bueno@metempsy.com return pc2; 12514034Sjavier.bueno@metempsy.com } 12614034Sjavier.bueno@metempsy.com unsigned short int getHPC() const 12714034Sjavier.bueno@metempsy.com { 12814034Sjavier.bueno@metempsy.com return hpc; 12914034Sjavier.bueno@metempsy.com } 13014034Sjavier.bueno@metempsy.com unsigned int getHashFilter(bool last_ghist_bit) const 13114034Sjavier.bueno@metempsy.com { 13214034Sjavier.bueno@metempsy.com return last_ghist_bit ^ hpc; 13314034Sjavier.bueno@metempsy.com } 13414034Sjavier.bueno@metempsy.com bool isUnconditional() const 13514034Sjavier.bueno@metempsy.com { 13614034Sjavier.bueno@metempsy.com return !condBranch; 13714034Sjavier.bueno@metempsy.com } 13814034Sjavier.bueno@metempsy.com }; 13914034Sjavier.bueno@metempsy.com 14014034Sjavier.bueno@metempsy.com /** 14114034Sjavier.bueno@metempsy.com * Entry of the branch filter 14214034Sjavier.bueno@metempsy.com */ 14314034Sjavier.bueno@metempsy.com struct FilterEntry { 14414034Sjavier.bueno@metempsy.com /** Has this branch been taken at least once? */ 14514034Sjavier.bueno@metempsy.com bool seenTaken; 14614034Sjavier.bueno@metempsy.com /** Has this branch been not taken at least once? */ 14714034Sjavier.bueno@metempsy.com bool seenUntaken; 14814034Sjavier.bueno@metempsy.com 14914034Sjavier.bueno@metempsy.com FilterEntry() : seenTaken(false), seenUntaken(false) {} 15014034Sjavier.bueno@metempsy.com 15114034Sjavier.bueno@metempsy.com /** Whether this branch has always been observed as not taken */ 15214034Sjavier.bueno@metempsy.com bool alwaysNotTakenSoFar() const { 15314034Sjavier.bueno@metempsy.com return seenUntaken & !seenTaken; 15414034Sjavier.bueno@metempsy.com } 15514034Sjavier.bueno@metempsy.com /** Whether this branch has always been observed as taken */ 15614034Sjavier.bueno@metempsy.com bool alwaysTakenSoFar() const { 15714034Sjavier.bueno@metempsy.com return seenTaken & !seenUntaken; 15814034Sjavier.bueno@metempsy.com } 15914034Sjavier.bueno@metempsy.com /** Whether this branch has been observed before */ 16014034Sjavier.bueno@metempsy.com bool neverSeen() const { 16114034Sjavier.bueno@metempsy.com return !seenTaken && !seenUntaken; 16214034Sjavier.bueno@metempsy.com } 16314034Sjavier.bueno@metempsy.com }; 16414034Sjavier.bueno@metempsy.com 16514034Sjavier.bueno@metempsy.com 16614034Sjavier.bueno@metempsy.com /** 16714034Sjavier.bueno@metempsy.com * Local history entries, each enty contains the history of directions 16814034Sjavier.bueno@metempsy.com * taken by a given branch. 16914034Sjavier.bueno@metempsy.com */ 17014034Sjavier.bueno@metempsy.com class LocalHistories { 17114034Sjavier.bueno@metempsy.com /** The array of histories */ 17214034Sjavier.bueno@metempsy.com std::vector<unsigned int> localHistories; 17314034Sjavier.bueno@metempsy.com /** Size in bits of each history entry */ 17414034Sjavier.bueno@metempsy.com const int localHistoryLength; 17514034Sjavier.bueno@metempsy.com 17614034Sjavier.bueno@metempsy.com /** Index function given the pc of the branch */ 17714034Sjavier.bueno@metempsy.com unsigned int index(Addr pc) const { 17814034Sjavier.bueno@metempsy.com return (pc >> 2) % localHistories.size(); 17914034Sjavier.bueno@metempsy.com } 18014034Sjavier.bueno@metempsy.com public: 18114034Sjavier.bueno@metempsy.com LocalHistories(int nlocal_histories, int histo_len) : 18214034Sjavier.bueno@metempsy.com localHistories(nlocal_histories), localHistoryLength(histo_len) {} 18314034Sjavier.bueno@metempsy.com 18414034Sjavier.bueno@metempsy.com /** Obtains the local history entry of a given branch */ 18514034Sjavier.bueno@metempsy.com unsigned int operator[](Addr pc) const 18614034Sjavier.bueno@metempsy.com { 18714034Sjavier.bueno@metempsy.com return localHistories[index(pc)]; 18814034Sjavier.bueno@metempsy.com } 18914034Sjavier.bueno@metempsy.com 19014034Sjavier.bueno@metempsy.com /** Adds a history bit to the local history entry of a given branch */ 19114034Sjavier.bueno@metempsy.com void update(Addr pc, bool value) 19214034Sjavier.bueno@metempsy.com { 19314034Sjavier.bueno@metempsy.com assert(localHistories.size() > 0); 19414034Sjavier.bueno@metempsy.com unsigned int &pos = localHistories[index(pc)]; 19514034Sjavier.bueno@metempsy.com pos <<= 1; 19614034Sjavier.bueno@metempsy.com pos |= value; 19714034Sjavier.bueno@metempsy.com pos &= ((1<<localHistoryLength)-1); 19814034Sjavier.bueno@metempsy.com } 19914034Sjavier.bueno@metempsy.com 20014034Sjavier.bueno@metempsy.com /** Returns the number of bits of each local history entry */ 20114034Sjavier.bueno@metempsy.com int getLocalHistoryLength() const 20214034Sjavier.bueno@metempsy.com { 20314034Sjavier.bueno@metempsy.com return localHistoryLength; 20414034Sjavier.bueno@metempsy.com } 20514034Sjavier.bueno@metempsy.com 20614034Sjavier.bueno@metempsy.com /** Size in bits required by all history entries */ 20714034Sjavier.bueno@metempsy.com int getSize() const 20814034Sjavier.bueno@metempsy.com { 20914034Sjavier.bueno@metempsy.com return localHistoryLength * localHistories.size(); 21014034Sjavier.bueno@metempsy.com } 21114034Sjavier.bueno@metempsy.com }; 21214034Sjavier.bueno@metempsy.com 21314034Sjavier.bueno@metempsy.com /** 21414034Sjavier.bueno@metempsy.com * Base class to implement the predictor tables. 21514034Sjavier.bueno@metempsy.com */ 21614034Sjavier.bueno@metempsy.com struct HistorySpec { 21714034Sjavier.bueno@metempsy.com /** First parameter */ 21814034Sjavier.bueno@metempsy.com const int p1; 21914034Sjavier.bueno@metempsy.com /** Second parameter */ 22014034Sjavier.bueno@metempsy.com const int p2; 22114034Sjavier.bueno@metempsy.com /** Third parameter */ 22214034Sjavier.bueno@metempsy.com const int p3; 22314034Sjavier.bueno@metempsy.com /** Coefficient of the feature, models the accuracy of the feature */ 22414034Sjavier.bueno@metempsy.com const double coeff; 22514034Sjavier.bueno@metempsy.com /** Pre-assigned size in bits assigned to this feature */ 22614034Sjavier.bueno@metempsy.com const int size; 22714034Sjavier.bueno@metempsy.com /** Width of the table in bits */ 22814034Sjavier.bueno@metempsy.com const int width; 22914034Sjavier.bueno@metempsy.com /** Reference to the branch predictor class */ 23014034Sjavier.bueno@metempsy.com MultiperspectivePerceptron &mpp; 23114034Sjavier.bueno@metempsy.com 23214034Sjavier.bueno@metempsy.com HistorySpec(int _p1, int _p2, int _p3, double _coeff, int _size, 23314034Sjavier.bueno@metempsy.com int _width, MultiperspectivePerceptron &_mpp) : p1(_p1), 23414034Sjavier.bueno@metempsy.com p2(_p2), p3(_p3), coeff(_coeff), size(_size), width(_width), 23514034Sjavier.bueno@metempsy.com mpp(_mpp) 23614034Sjavier.bueno@metempsy.com {} 23714034Sjavier.bueno@metempsy.com 23814034Sjavier.bueno@metempsy.com /** 23914034Sjavier.bueno@metempsy.com * Gets the hash to index the table, using the pc of the branch, 24014034Sjavier.bueno@metempsy.com * and the index of the table. 24114034Sjavier.bueno@metempsy.com * @param tid Thread ID of the branch 24214034Sjavier.bueno@metempsy.com * @param pc address of the branch 24314034Sjavier.bueno@metempsy.com * @param pc2 address of the branch shifted 2 bits to the right 24414034Sjavier.bueno@metempsy.com * @param t integer index of the table 24514034Sjavier.bueno@metempsy.com * @result resulting hash value that will be used to index the table 24614034Sjavier.bueno@metempsy.com */ 24714034Sjavier.bueno@metempsy.com virtual unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) 24814034Sjavier.bueno@metempsy.com const = 0; 24914034Sjavier.bueno@metempsy.com /** 25014034Sjavier.bueno@metempsy.com * Sets the size requirements of the table, used when initializing 25114034Sjavier.bueno@metempsy.com * to set the proper size of the tables 25214034Sjavier.bueno@metempsy.com */ 25314034Sjavier.bueno@metempsy.com virtual void setBitRequirements() const {} 25414034Sjavier.bueno@metempsy.com }; 25514034Sjavier.bueno@metempsy.com 25614034Sjavier.bueno@metempsy.com /** Predictor parameters */ 25714034Sjavier.bueno@metempsy.com const int blockSize; 25814034Sjavier.bueno@metempsy.com const int pcshift; 25914034Sjavier.bueno@metempsy.com const int threshold; 26014034Sjavier.bueno@metempsy.com const int bias0; 26114034Sjavier.bueno@metempsy.com const int bias1; 26214034Sjavier.bueno@metempsy.com const int biasmostly0; 26314034Sjavier.bueno@metempsy.com const int biasmostly1; 26414034Sjavier.bueno@metempsy.com const int nbest; 26514034Sjavier.bueno@metempsy.com const int tunebits; 26614034Sjavier.bueno@metempsy.com const int hshift; 26714034Sjavier.bueno@metempsy.com const unsigned long long int imli_mask1; 26814034Sjavier.bueno@metempsy.com const unsigned long long int imli_mask4; 26914034Sjavier.bueno@metempsy.com const unsigned long long int recencypos_mask; 27014034Sjavier.bueno@metempsy.com const double fudge; 27114034Sjavier.bueno@metempsy.com const int n_sign_bits; 27214034Sjavier.bueno@metempsy.com const int pcbit; 27314034Sjavier.bueno@metempsy.com const int decay; 27414034Sjavier.bueno@metempsy.com const unsigned int record_mask; 27514034Sjavier.bueno@metempsy.com const bool hash_taken; 27614034Sjavier.bueno@metempsy.com const bool tuneonly; 27714034Sjavier.bueno@metempsy.com const int extra_rounds; 27814034Sjavier.bueno@metempsy.com const int speed; 27914034Sjavier.bueno@metempsy.com const int budgetbits; 28014034Sjavier.bueno@metempsy.com const bool speculative_update; 28114034Sjavier.bueno@metempsy.com 28214034Sjavier.bueno@metempsy.com /** Transfer function for 6-width tables */ 28314034Sjavier.bueno@metempsy.com static int xlat[]; 28414034Sjavier.bueno@metempsy.com /** Transfer function for 5-width tables */ 28514034Sjavier.bueno@metempsy.com static int xlat4[]; 28614034Sjavier.bueno@metempsy.com 28714034Sjavier.bueno@metempsy.com /** History data is kept for each thread */ 28814034Sjavier.bueno@metempsy.com struct ThreadData { 28914034Sjavier.bueno@metempsy.com ThreadData(int num_filter, int n_local_histories, 29014034Sjavier.bueno@metempsy.com int local_history_length, int assoc, 29114034Sjavier.bueno@metempsy.com const std::vector<std::vector<int>> &blurrypath_bits, 29214034Sjavier.bueno@metempsy.com int path_length, int ghist_length, int block_size, 29314034Sjavier.bueno@metempsy.com const std::vector<std::vector<std::vector<bool>>> &acyclic_bits, 29414034Sjavier.bueno@metempsy.com const std::vector<int> &modhist_indices, 29514034Sjavier.bueno@metempsy.com const std::vector<int> &modhist_lengths, 29614034Sjavier.bueno@metempsy.com const std::vector<int> &modpath_indices, 29714034Sjavier.bueno@metempsy.com const std::vector<int> &modpath_lengths, 29814034Sjavier.bueno@metempsy.com const std::vector<int> &table_sizes, int n_sign_bits); 29914034Sjavier.bueno@metempsy.com 30014034Sjavier.bueno@metempsy.com std::vector<FilterEntry> filterTable; 30114034Sjavier.bueno@metempsy.com std::vector<std::vector<bool>> acyclic_histories; 30214034Sjavier.bueno@metempsy.com std::vector<std::vector<unsigned int>> acyclic2_histories; 30314034Sjavier.bueno@metempsy.com 30414034Sjavier.bueno@metempsy.com void updateAcyclic(bool hashed_taken, unsigned int hpc) { 30514034Sjavier.bueno@metempsy.com for (int i = 0; i < acyclic_histories.size(); i += 1) { 30614034Sjavier.bueno@metempsy.com if (acyclic_histories[i].size() > 0) { 30714034Sjavier.bueno@metempsy.com acyclic_histories[i][hpc%(i+2)] = hashed_taken; 30814034Sjavier.bueno@metempsy.com acyclic2_histories[i][hpc%(i+2)] = hpc; 30914034Sjavier.bueno@metempsy.com } 31014034Sjavier.bueno@metempsy.com } 31114034Sjavier.bueno@metempsy.com } 31214034Sjavier.bueno@metempsy.com 31314034Sjavier.bueno@metempsy.com std::vector<std::vector<unsigned int>> blurrypath_histories; 31414034Sjavier.bueno@metempsy.com std::vector<unsigned int> ghist_words; 31514034Sjavier.bueno@metempsy.com std::vector<std::vector<unsigned short int>> modpath_histories; 31614034Sjavier.bueno@metempsy.com std::vector<std::vector<bool>> mod_histories; 31714034Sjavier.bueno@metempsy.com std::vector<unsigned short int> path_history; 31814034Sjavier.bueno@metempsy.com std::vector<unsigned int> imli_counter; 31914034Sjavier.bueno@metempsy.com LocalHistories localHistories; 32014034Sjavier.bueno@metempsy.com std::vector<unsigned int short> recency_stack; 32114034Sjavier.bueno@metempsy.com 32214034Sjavier.bueno@metempsy.com void insertRecency(unsigned int pc, int assoc) { 32314034Sjavier.bueno@metempsy.com int i = 0; 32414034Sjavier.bueno@metempsy.com for (i = 0; i < assoc; i += 1) { 32514034Sjavier.bueno@metempsy.com if (recency_stack[i] == pc) { 32614034Sjavier.bueno@metempsy.com break; 32714034Sjavier.bueno@metempsy.com } 32814034Sjavier.bueno@metempsy.com } 32914034Sjavier.bueno@metempsy.com if (i == assoc) { 33014034Sjavier.bueno@metempsy.com i = assoc-1; 33114034Sjavier.bueno@metempsy.com recency_stack[i] = pc; 33214034Sjavier.bueno@metempsy.com } 33314034Sjavier.bueno@metempsy.com int j; 33414034Sjavier.bueno@metempsy.com unsigned int b = recency_stack[i]; 33514034Sjavier.bueno@metempsy.com for (j = i; j >= 1; j -= 1) { 33614034Sjavier.bueno@metempsy.com recency_stack[j] = recency_stack[j-1]; 33714034Sjavier.bueno@metempsy.com } 33814034Sjavier.bueno@metempsy.com recency_stack[0] = b; 33914034Sjavier.bueno@metempsy.com } 34014034Sjavier.bueno@metempsy.com 34114034Sjavier.bueno@metempsy.com bool last_ghist_bit; 34214034Sjavier.bueno@metempsy.com int occupancy; 34314034Sjavier.bueno@metempsy.com 34414034Sjavier.bueno@metempsy.com std::vector<int> mpreds; 34514034Sjavier.bueno@metempsy.com std::vector<std::vector<short int>> tables; 34614034Sjavier.bueno@metempsy.com std::vector<std::vector<std::array<bool, 2>>> sign_bits; 34714034Sjavier.bueno@metempsy.com }; 34814034Sjavier.bueno@metempsy.com std::vector<ThreadData *> threadData; 34914034Sjavier.bueno@metempsy.com 35014034Sjavier.bueno@metempsy.com /** Predictor tables */ 35114034Sjavier.bueno@metempsy.com std::vector<HistorySpec *> specs; 35214034Sjavier.bueno@metempsy.com std::vector<int> table_sizes; 35314034Sjavier.bueno@metempsy.com 35414034Sjavier.bueno@metempsy.com /** runtime values and data used to count the size in bits */ 35514034Sjavier.bueno@metempsy.com bool doing_local; 35614034Sjavier.bueno@metempsy.com bool doing_recency; 35714034Sjavier.bueno@metempsy.com int assoc; 35814034Sjavier.bueno@metempsy.com int ghist_length; 35914034Sjavier.bueno@metempsy.com int modghist_length; 36014034Sjavier.bueno@metempsy.com int path_length; 36114034Sjavier.bueno@metempsy.com int thresholdCounter; 36214034Sjavier.bueno@metempsy.com int theta; 36314081Sjavier.bueno@metempsy.com int extrabits; 36414034Sjavier.bueno@metempsy.com std::vector<int> imli_counter_bits; 36514034Sjavier.bueno@metempsy.com std::vector<int> modhist_indices; 36614034Sjavier.bueno@metempsy.com std::vector<int> modhist_lengths; 36714034Sjavier.bueno@metempsy.com std::vector<int> modpath_indices; 36814034Sjavier.bueno@metempsy.com std::vector<int> modpath_lengths; 36914034Sjavier.bueno@metempsy.com std::vector<std::vector<int>> blurrypath_bits; 37014034Sjavier.bueno@metempsy.com std::vector<std::vector<std::vector<bool>>> acyclic_bits; 37114034Sjavier.bueno@metempsy.com 37214034Sjavier.bueno@metempsy.com /** Auxiliary function for MODHIST and GHISTMODPATH features */ 37314034Sjavier.bueno@metempsy.com void insertModhistSpec(int p1, int p2) { 37414034Sjavier.bueno@metempsy.com int j = insert(modhist_indices, p1); 37514034Sjavier.bueno@metempsy.com if (modhist_lengths.size() < (j + 1)) { 37614034Sjavier.bueno@metempsy.com modhist_lengths.resize(j + 1); 37714034Sjavier.bueno@metempsy.com } 37814034Sjavier.bueno@metempsy.com if (modhist_lengths[j] < p2 + 1) { 37914034Sjavier.bueno@metempsy.com modhist_lengths[j] = p2 + 1; 38014034Sjavier.bueno@metempsy.com } 38114034Sjavier.bueno@metempsy.com if (p2 >= modghist_length) { 38214034Sjavier.bueno@metempsy.com modghist_length = p2 + 1; 38314034Sjavier.bueno@metempsy.com } 38414034Sjavier.bueno@metempsy.com } 38514034Sjavier.bueno@metempsy.com 38614034Sjavier.bueno@metempsy.com /** Auxiliary function for MODPATH and GHISTMODPATH features */ 38714034Sjavier.bueno@metempsy.com void insertModpathSpec(int p1, int p2) { 38814034Sjavier.bueno@metempsy.com int j = insert(modpath_indices, p1); 38914034Sjavier.bueno@metempsy.com if (modpath_lengths.size() < (j + 1)) { 39014034Sjavier.bueno@metempsy.com modpath_lengths.resize(j + 1); 39114034Sjavier.bueno@metempsy.com } 39214034Sjavier.bueno@metempsy.com if (modpath_lengths[j] < p2 + 1) { 39314034Sjavier.bueno@metempsy.com modpath_lengths[j] = p2 + 1; 39414034Sjavier.bueno@metempsy.com } 39514034Sjavier.bueno@metempsy.com if (p2 >= path_length) { 39614034Sjavier.bueno@metempsy.com path_length = p2 + 1; 39714034Sjavier.bueno@metempsy.com } 39814034Sjavier.bueno@metempsy.com } 39914034Sjavier.bueno@metempsy.com 40014034Sjavier.bueno@metempsy.com /** Auxiliary function used by insertModhistSpec and insertModpathSpec*/ 40114034Sjavier.bueno@metempsy.com int insert(std::vector<int> &v, int x) 40214034Sjavier.bueno@metempsy.com { 40314034Sjavier.bueno@metempsy.com for (int i = 0; i < v.size(); i += 1) { 40414034Sjavier.bueno@metempsy.com if (v[i] == x) { 40514034Sjavier.bueno@metempsy.com return i; 40614034Sjavier.bueno@metempsy.com } 40714034Sjavier.bueno@metempsy.com } 40814034Sjavier.bueno@metempsy.com v.push_back(x); 40914034Sjavier.bueno@metempsy.com return v.size()-1; 41014034Sjavier.bueno@metempsy.com } 41114034Sjavier.bueno@metempsy.com 41214034Sjavier.bueno@metempsy.com /** 41314034Sjavier.bueno@metempsy.com * Computes the size in bits of the structures needed to keep track 41414034Sjavier.bueno@metempsy.com * of the history and the predictor tables and assigns the sizes of 41514034Sjavier.bueno@metempsy.com * those tables that did not had their size specified. 41614034Sjavier.bueno@metempsy.com * @param num_filter_entries number of entries of the filter 41714034Sjavier.bueno@metempsy.com * @param nlocal_histories number of local history entries 41814034Sjavier.bueno@metempsy.com * @param local_history_length size of each local history entry 41914081Sjavier.bueno@metempsy.com * @param ignore_path_size ignore the path length storage 42014034Sjavier.bueno@metempsy.com */ 42114034Sjavier.bueno@metempsy.com void computeBits(int num_filter_entries, int nlocal_histories, 42214081Sjavier.bueno@metempsy.com int local_history_length, bool ignore_path_size); 42314034Sjavier.bueno@metempsy.com 42414034Sjavier.bueno@metempsy.com /** 42514034Sjavier.bueno@metempsy.com * Creates the tables of the predictor 42614034Sjavier.bueno@metempsy.com */ 42714034Sjavier.bueno@metempsy.com virtual void createSpecs() = 0; 42814034Sjavier.bueno@metempsy.com 42914034Sjavier.bueno@metempsy.com /** 43014034Sjavier.bueno@metempsy.com * Get the position index of a predictor table 43114034Sjavier.bueno@metempsy.com * @param tid Thread ID of the branch 43214034Sjavier.bueno@metempsy.com * @param bi branch informaiton data 43314034Sjavier.bueno@metempsy.com * @param spec predictor table 43414034Sjavier.bueno@metempsy.com * @param index integer index of the predictor table 43514034Sjavier.bueno@metempsy.com * @result index to access the predictor table 43614034Sjavier.bueno@metempsy.com */ 43714034Sjavier.bueno@metempsy.com unsigned int getIndex(ThreadID tid, const MPPBranchInfo &bi, 43814034Sjavier.bueno@metempsy.com const HistorySpec &spec, int index) const; 43914034Sjavier.bueno@metempsy.com /** 44014034Sjavier.bueno@metempsy.com * Finds the best subset of features to use in case of a low-confidence 44114034Sjavier.bueno@metempsy.com * branch, returns the result as an ordered vector of the indices to the 44214034Sjavier.bueno@metempsy.com * predictor tables 44314034Sjavier.bueno@metempsy.com * @param tid Thread ID of the branch 44414034Sjavier.bueno@metempsy.com * @param vector to write the ordered list of indices of the best tables 44514034Sjavier.bueno@metempsy.com */ 44614034Sjavier.bueno@metempsy.com void findBest(ThreadID tid, std::vector<int> &best_preds) const; 44714034Sjavier.bueno@metempsy.com 44814034Sjavier.bueno@metempsy.com /** 44914034Sjavier.bueno@metempsy.com * Computes the output of the predictor for a given branch and the 45014034Sjavier.bueno@metempsy.com * resulting best value in case the prediction has low confidence 45114034Sjavier.bueno@metempsy.com * @param tid Thread ID of the branch 45214034Sjavier.bueno@metempsy.com * @param bi branch informaiton data 45314034Sjavier.bueno@metempsy.com * @return resulting sum for low-confidence branch 45414034Sjavier.bueno@metempsy.com */ 45514034Sjavier.bueno@metempsy.com int computeOutput(ThreadID tid, MPPBranchInfo &bi); 45614034Sjavier.bueno@metempsy.com 45714034Sjavier.bueno@metempsy.com /** 45814034Sjavier.bueno@metempsy.com * Trains the branch predictor with the given branch and direction 45914034Sjavier.bueno@metempsy.com * @param tid Thread ID of the branch 46014034Sjavier.bueno@metempsy.com * @param bi branch informaiton data 46114034Sjavier.bueno@metempsy.com * @param taken whether the branch was taken 46214034Sjavier.bueno@metempsy.com */ 46314034Sjavier.bueno@metempsy.com void train(ThreadID tid, MPPBranchInfo &bi, bool taken); 46414034Sjavier.bueno@metempsy.com 46514034Sjavier.bueno@metempsy.com /** 46614034Sjavier.bueno@metempsy.com * Auxiliary function to increase a table counter depending on the 46714034Sjavier.bueno@metempsy.com * direction of the branch 46814034Sjavier.bueno@metempsy.com * @param taken whether the branch was taken 46914034Sjavier.bueno@metempsy.com * @param sign current sign of the table 47014034Sjavier.bueno@metempsy.com * @param c current value of the table 47114034Sjavier.bueno@metempsy.com * @param max_weight maximum value of the counter 47214034Sjavier.bueno@metempsy.com */ 47314034Sjavier.bueno@metempsy.com void satIncDec(bool taken, bool &sign, int &c, int max_weight) const; 47414034Sjavier.bueno@metempsy.com 47514034Sjavier.bueno@metempsy.com /** Add a table spec to the prefetcher */ 47614034Sjavier.bueno@metempsy.com void addSpec(HistorySpec *spec) 47714034Sjavier.bueno@metempsy.com { 47814034Sjavier.bueno@metempsy.com specs.push_back(spec); 47914034Sjavier.bueno@metempsy.com } 48014034Sjavier.bueno@metempsy.com 48114034Sjavier.bueno@metempsy.com /** Available features */ 48214034Sjavier.bueno@metempsy.com 48314034Sjavier.bueno@metempsy.com class GHIST : public HistorySpec { 48414034Sjavier.bueno@metempsy.com public: 48514034Sjavier.bueno@metempsy.com GHIST(int p1, int p2, double coeff, int size, int width, 48614034Sjavier.bueno@metempsy.com MultiperspectivePerceptron &mpp) 48714034Sjavier.bueno@metempsy.com : HistorySpec(p1, p2, 0, coeff, size, width, mpp) 48814034Sjavier.bueno@metempsy.com {} 48914034Sjavier.bueno@metempsy.com 49014034Sjavier.bueno@metempsy.com unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const 49114034Sjavier.bueno@metempsy.com override 49214034Sjavier.bueno@metempsy.com { 49314034Sjavier.bueno@metempsy.com return hash(mpp.threadData[tid]->ghist_words, mpp.blockSize, p1, 49414034Sjavier.bueno@metempsy.com p2); 49514034Sjavier.bueno@metempsy.com } 49614034Sjavier.bueno@metempsy.com 49714034Sjavier.bueno@metempsy.com static unsigned int hash(const std::vector<unsigned int> &ghist_words, 49814034Sjavier.bueno@metempsy.com int block_size, int start_pos, int end_pos) 49914034Sjavier.bueno@metempsy.com { 50014034Sjavier.bueno@metempsy.com int a = start_pos; 50114034Sjavier.bueno@metempsy.com int b = end_pos; 50214034Sjavier.bueno@metempsy.com 50314034Sjavier.bueno@metempsy.com unsigned int x = 0; 50414034Sjavier.bueno@metempsy.com // am is the next multiple of block_size after a 50514034Sjavier.bueno@metempsy.com int am = (((a/block_size)*block_size)+block_size); 50614034Sjavier.bueno@metempsy.com // bm is the previous multiple of block_size before b 50714034Sjavier.bueno@metempsy.com int bm = (b/block_size)*block_size; 50814034Sjavier.bueno@metempsy.com 50914034Sjavier.bueno@metempsy.com // the 0th bit of ghist_words[a/block_size] is the most recent bit. 51014034Sjavier.bueno@metempsy.com // so the number of bits between a and am is the number to shift 51114034Sjavier.bueno@metempsy.com // right? 51214034Sjavier.bueno@metempsy.com 51314034Sjavier.bueno@metempsy.com // start out x as remainder bits from the beginning: 51414034Sjavier.bueno@metempsy.com // x = [ . . . . . b b b b b ] 51514034Sjavier.bueno@metempsy.com x += ghist_words[a / block_size] >> (a-am); 51614034Sjavier.bueno@metempsy.com // add in bits from the middle 51714034Sjavier.bueno@metempsy.com for (int i=am; i<bm; i+=block_size) { 51814034Sjavier.bueno@metempsy.com x += ghist_words[i / block_size]; 51914034Sjavier.bueno@metempsy.com } 52014034Sjavier.bueno@metempsy.com // add in remainder bits from end: 52114034Sjavier.bueno@metempsy.com // x += [ b b b b b . . . . . ] 52214034Sjavier.bueno@metempsy.com unsigned int y = ghist_words[bm / block_size] & ((1<<(b - bm))-1); 52314034Sjavier.bueno@metempsy.com x += y << (block_size - (b - bm)); 52414034Sjavier.bueno@metempsy.com return x; 52514034Sjavier.bueno@metempsy.com } 52614034Sjavier.bueno@metempsy.com void setBitRequirements() const override 52714034Sjavier.bueno@metempsy.com { 52814034Sjavier.bueno@metempsy.com if (mpp.ghist_length <= p2) { 52914034Sjavier.bueno@metempsy.com mpp.ghist_length = p2 + 1; 53014034Sjavier.bueno@metempsy.com } 53114034Sjavier.bueno@metempsy.com } 53214034Sjavier.bueno@metempsy.com }; 53314034Sjavier.bueno@metempsy.com 53414034Sjavier.bueno@metempsy.com class ACYCLIC : public HistorySpec { 53514034Sjavier.bueno@metempsy.com public: 53614034Sjavier.bueno@metempsy.com ACYCLIC(int p1, int p2, int p3, double coeff, int size, int width, 53714034Sjavier.bueno@metempsy.com MultiperspectivePerceptron &mpp) 53814034Sjavier.bueno@metempsy.com : HistorySpec(p1, p2, p3, coeff, size, width, mpp) 53914034Sjavier.bueno@metempsy.com {} 54014034Sjavier.bueno@metempsy.com 54114034Sjavier.bueno@metempsy.com unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const 54214034Sjavier.bueno@metempsy.com override 54314034Sjavier.bueno@metempsy.com { 54414034Sjavier.bueno@metempsy.com int a = p1; 54514034Sjavier.bueno@metempsy.com int shift = p2; 54614034Sjavier.bueno@metempsy.com int style = p3; 54714034Sjavier.bueno@metempsy.com std::vector<std::vector<bool>> &acyclic_histories = 54814034Sjavier.bueno@metempsy.com mpp.threadData[tid]->acyclic_histories; 54914034Sjavier.bueno@metempsy.com std::vector<std::vector<unsigned int>> &acyclic2_histories = 55014034Sjavier.bueno@metempsy.com mpp.threadData[tid]->acyclic2_histories; 55114034Sjavier.bueno@metempsy.com 55214034Sjavier.bueno@metempsy.com unsigned int x = 0; 55314034Sjavier.bueno@metempsy.com if (style == -1) { 55414034Sjavier.bueno@metempsy.com unsigned int k = 0; 55514034Sjavier.bueno@metempsy.com for (int i = 0; i < a + 2; i += 1) { 55614034Sjavier.bueno@metempsy.com x ^= acyclic_histories[a][i] << k; 55714034Sjavier.bueno@metempsy.com k += 1; 55814034Sjavier.bueno@metempsy.com k %= mpp.blockSize; 55914034Sjavier.bueno@metempsy.com } 56014034Sjavier.bueno@metempsy.com } else { 56114034Sjavier.bueno@metempsy.com for (int i = 0; i < a + 2; i += 1) { 56214034Sjavier.bueno@metempsy.com x <<= shift; 56314034Sjavier.bueno@metempsy.com x += acyclic2_histories[a][i]; 56414034Sjavier.bueno@metempsy.com } 56514034Sjavier.bueno@metempsy.com } 56614034Sjavier.bueno@metempsy.com return x; 56714034Sjavier.bueno@metempsy.com } 56814034Sjavier.bueno@metempsy.com void setBitRequirements() const override 56914034Sjavier.bueno@metempsy.com { 57014034Sjavier.bueno@metempsy.com if (mpp.acyclic_bits.size() < (p1 + 1)) { 57114034Sjavier.bueno@metempsy.com mpp.acyclic_bits.resize(p1 + 1); 57214034Sjavier.bueno@metempsy.com } 57314034Sjavier.bueno@metempsy.com if (mpp.acyclic_bits[p1].size() < (p1 + 2)) { 57414034Sjavier.bueno@metempsy.com mpp.acyclic_bits[p1].resize(p1 + 2, std::vector<bool>(2)); 57514034Sjavier.bueno@metempsy.com } 57614034Sjavier.bueno@metempsy.com for (int j = 0; j < p1 + 2; j += 1) { 57714034Sjavier.bueno@metempsy.com mpp.acyclic_bits[p1][j][!p3] = true; 57814034Sjavier.bueno@metempsy.com } 57914034Sjavier.bueno@metempsy.com } 58014034Sjavier.bueno@metempsy.com }; 58114034Sjavier.bueno@metempsy.com 58214034Sjavier.bueno@metempsy.com class MODHIST : public HistorySpec { 58314034Sjavier.bueno@metempsy.com public: 58414034Sjavier.bueno@metempsy.com MODHIST(int p1, int p2, double coeff, int size, int width, 58514034Sjavier.bueno@metempsy.com MultiperspectivePerceptron &mpp) 58614034Sjavier.bueno@metempsy.com : HistorySpec(p1, p2, 0, coeff, size, width, mpp) 58714034Sjavier.bueno@metempsy.com {} 58814034Sjavier.bueno@metempsy.com 58914034Sjavier.bueno@metempsy.com unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const 59014034Sjavier.bueno@metempsy.com override 59114034Sjavier.bueno@metempsy.com { 59214034Sjavier.bueno@metempsy.com int a = p1; 59314034Sjavier.bueno@metempsy.com int b = p2; 59414034Sjavier.bueno@metempsy.com std::vector<std::vector<bool>> &mod_histories = 59514034Sjavier.bueno@metempsy.com mpp.threadData[tid]->mod_histories; 59614034Sjavier.bueno@metempsy.com 59714034Sjavier.bueno@metempsy.com unsigned int x = 0, k = 0; 59814034Sjavier.bueno@metempsy.com for (int i = 0; i < b; i += 1) { 59914034Sjavier.bueno@metempsy.com x ^= mod_histories[a][i] << k; 60014034Sjavier.bueno@metempsy.com k += 1; 60114034Sjavier.bueno@metempsy.com k %= mpp.blockSize; 60214034Sjavier.bueno@metempsy.com } 60314034Sjavier.bueno@metempsy.com return x; 60414034Sjavier.bueno@metempsy.com } 60514034Sjavier.bueno@metempsy.com void setBitRequirements() const override 60614034Sjavier.bueno@metempsy.com { 60714034Sjavier.bueno@metempsy.com mpp.insertModhistSpec(p1, p2); 60814034Sjavier.bueno@metempsy.com } 60914034Sjavier.bueno@metempsy.com }; 61014034Sjavier.bueno@metempsy.com 61114034Sjavier.bueno@metempsy.com class BIAS : public HistorySpec { 61214034Sjavier.bueno@metempsy.com public: 61314034Sjavier.bueno@metempsy.com BIAS(double coeff, int size, int width, 61414034Sjavier.bueno@metempsy.com MultiperspectivePerceptron &mpp) 61514034Sjavier.bueno@metempsy.com : HistorySpec(0, 0, 0, coeff, size, width, mpp) 61614034Sjavier.bueno@metempsy.com {} 61714034Sjavier.bueno@metempsy.com 61814034Sjavier.bueno@metempsy.com unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const 61914034Sjavier.bueno@metempsy.com override 62014034Sjavier.bueno@metempsy.com { 62114034Sjavier.bueno@metempsy.com return 0; 62214034Sjavier.bueno@metempsy.com } 62314034Sjavier.bueno@metempsy.com }; 62414034Sjavier.bueno@metempsy.com 62514034Sjavier.bueno@metempsy.com 62614034Sjavier.bueno@metempsy.com class RECENCY : public HistorySpec { 62714034Sjavier.bueno@metempsy.com public: 62814034Sjavier.bueno@metempsy.com RECENCY(int p1, int p2, int p3, double coeff, int size, int width, 62914034Sjavier.bueno@metempsy.com MultiperspectivePerceptron &mpp) 63014034Sjavier.bueno@metempsy.com : HistorySpec(p1, p2, p3, coeff, size, width, mpp) 63114034Sjavier.bueno@metempsy.com {} 63214034Sjavier.bueno@metempsy.com 63314034Sjavier.bueno@metempsy.com unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const 63414034Sjavier.bueno@metempsy.com override 63514034Sjavier.bueno@metempsy.com { 63614034Sjavier.bueno@metempsy.com int depth = p1; 63714034Sjavier.bueno@metempsy.com int shift = p2; 63814034Sjavier.bueno@metempsy.com int style = p3; 63914034Sjavier.bueno@metempsy.com std::vector<unsigned int short> &recency_stack = 64014034Sjavier.bueno@metempsy.com mpp.threadData[tid]->recency_stack; 64114034Sjavier.bueno@metempsy.com 64214034Sjavier.bueno@metempsy.com if (style == -1) { 64314034Sjavier.bueno@metempsy.com unsigned int x = 0; 64414034Sjavier.bueno@metempsy.com for (int i = 0; i < depth; i += 1) { 64514034Sjavier.bueno@metempsy.com x <<= shift; 64614034Sjavier.bueno@metempsy.com x += recency_stack[i]; 64714034Sjavier.bueno@metempsy.com } 64814034Sjavier.bueno@metempsy.com return x; 64914034Sjavier.bueno@metempsy.com } else { 65014034Sjavier.bueno@metempsy.com unsigned int x = 0, k = 0; 65114034Sjavier.bueno@metempsy.com for (int i = 0; i < depth; i += 1) { 65214034Sjavier.bueno@metempsy.com x ^= (!!(recency_stack[i] & (1 << shift))) << k; 65314034Sjavier.bueno@metempsy.com k += 1; 65414034Sjavier.bueno@metempsy.com k %= mpp.blockSize; 65514034Sjavier.bueno@metempsy.com } 65614034Sjavier.bueno@metempsy.com return x; 65714034Sjavier.bueno@metempsy.com } 65814034Sjavier.bueno@metempsy.com } 65914034Sjavier.bueno@metempsy.com void setBitRequirements() const override 66014034Sjavier.bueno@metempsy.com { 66114034Sjavier.bueno@metempsy.com if (mpp.assoc < p1) { 66214034Sjavier.bueno@metempsy.com mpp.assoc = p1; 66314034Sjavier.bueno@metempsy.com } 66414034Sjavier.bueno@metempsy.com mpp.doing_recency = true; 66514034Sjavier.bueno@metempsy.com } 66614034Sjavier.bueno@metempsy.com }; 66714034Sjavier.bueno@metempsy.com 66814034Sjavier.bueno@metempsy.com class IMLI : public HistorySpec { 66914034Sjavier.bueno@metempsy.com public: 67014034Sjavier.bueno@metempsy.com IMLI(int p1, double coeff, int size, int width, 67114034Sjavier.bueno@metempsy.com MultiperspectivePerceptron &mpp) 67214034Sjavier.bueno@metempsy.com : HistorySpec(p1, 0, 0, coeff, size, width, mpp) 67314034Sjavier.bueno@metempsy.com {} 67414034Sjavier.bueno@metempsy.com 67514034Sjavier.bueno@metempsy.com unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const 67614034Sjavier.bueno@metempsy.com override 67714034Sjavier.bueno@metempsy.com { 67814034Sjavier.bueno@metempsy.com assert(p1 >= 1); 67914034Sjavier.bueno@metempsy.com assert(p1 <= 4); 68014034Sjavier.bueno@metempsy.com return mpp.threadData[tid]->imli_counter[p1-1]; 68114034Sjavier.bueno@metempsy.com } 68214034Sjavier.bueno@metempsy.com 68314034Sjavier.bueno@metempsy.com void setBitRequirements() const override 68414034Sjavier.bueno@metempsy.com { 68514034Sjavier.bueno@metempsy.com mpp.imli_counter_bits[p1 - 1] = 32; 68614034Sjavier.bueno@metempsy.com } 68714034Sjavier.bueno@metempsy.com }; 68814034Sjavier.bueno@metempsy.com 68914034Sjavier.bueno@metempsy.com class PATH : public HistorySpec { 69014034Sjavier.bueno@metempsy.com public: 69114034Sjavier.bueno@metempsy.com PATH(int p1, int p2, int p3, double coeff, int size, int width, 69214034Sjavier.bueno@metempsy.com MultiperspectivePerceptron &mpp) 69314034Sjavier.bueno@metempsy.com : HistorySpec(p1, p2, p3, coeff, size, width, mpp) 69414034Sjavier.bueno@metempsy.com {} 69514034Sjavier.bueno@metempsy.com 69614034Sjavier.bueno@metempsy.com unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const 69714034Sjavier.bueno@metempsy.com override 69814034Sjavier.bueno@metempsy.com { 69914034Sjavier.bueno@metempsy.com int depth = p1; 70014034Sjavier.bueno@metempsy.com int shift = p2; 70114034Sjavier.bueno@metempsy.com int style = p3; 70214034Sjavier.bueno@metempsy.com std::vector<unsigned short int> &path_history = 70314034Sjavier.bueno@metempsy.com mpp.threadData[tid]->path_history; 70414034Sjavier.bueno@metempsy.com 70514034Sjavier.bueno@metempsy.com if (style == -1) { 70614034Sjavier.bueno@metempsy.com unsigned int x = 0; 70714034Sjavier.bueno@metempsy.com for (int i = 0; i < depth; i += 1) { 70814034Sjavier.bueno@metempsy.com x <<= shift; 70914034Sjavier.bueno@metempsy.com x += path_history[i]; 71014034Sjavier.bueno@metempsy.com } 71114034Sjavier.bueno@metempsy.com return x; 71214034Sjavier.bueno@metempsy.com } else { 71314034Sjavier.bueno@metempsy.com unsigned int x = 0; 71414034Sjavier.bueno@metempsy.com int bm = (depth / mpp.blockSize) * mpp.blockSize; 71514034Sjavier.bueno@metempsy.com for (int i = 0; i < bm; i += mpp.blockSize) { 71614034Sjavier.bueno@metempsy.com for (int j = 0; j < mpp.blockSize; j += 1) { 71714034Sjavier.bueno@metempsy.com x ^= (!!(path_history[i + j] & (1 << shift))) << j; 71814034Sjavier.bueno@metempsy.com } 71914034Sjavier.bueno@metempsy.com } 72014034Sjavier.bueno@metempsy.com int k = 0; 72114034Sjavier.bueno@metempsy.com for (int i = bm; i < depth; i += 1) { 72214034Sjavier.bueno@metempsy.com x ^= (!!(path_history[i] & (1 << shift))) << k++; 72314034Sjavier.bueno@metempsy.com } 72414034Sjavier.bueno@metempsy.com return x; 72514034Sjavier.bueno@metempsy.com } 72614034Sjavier.bueno@metempsy.com } 72714034Sjavier.bueno@metempsy.com void setBitRequirements() const override 72814034Sjavier.bueno@metempsy.com { 72914034Sjavier.bueno@metempsy.com if (mpp.path_length <= p1) { 73014034Sjavier.bueno@metempsy.com mpp.path_length = p1 + 1; 73114034Sjavier.bueno@metempsy.com } 73214034Sjavier.bueno@metempsy.com } 73314034Sjavier.bueno@metempsy.com }; 73414034Sjavier.bueno@metempsy.com 73514034Sjavier.bueno@metempsy.com class LOCAL : public HistorySpec { 73614034Sjavier.bueno@metempsy.com public: 73714034Sjavier.bueno@metempsy.com LOCAL(int p1, double coeff, int size, int width, 73814034Sjavier.bueno@metempsy.com MultiperspectivePerceptron &mpp) 73914034Sjavier.bueno@metempsy.com : HistorySpec(p1, 0, 0, coeff, size, width, mpp) 74014034Sjavier.bueno@metempsy.com {} 74114034Sjavier.bueno@metempsy.com 74214034Sjavier.bueno@metempsy.com unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const 74314034Sjavier.bueno@metempsy.com override 74414034Sjavier.bueno@metempsy.com { 74514034Sjavier.bueno@metempsy.com unsigned int x = mpp.threadData[tid]->localHistories[pc]; 74614034Sjavier.bueno@metempsy.com if (p1 != -1) { 74714034Sjavier.bueno@metempsy.com x &= ((1 << p1) - 1); 74814034Sjavier.bueno@metempsy.com } 74914034Sjavier.bueno@metempsy.com return x; 75014034Sjavier.bueno@metempsy.com } 75114034Sjavier.bueno@metempsy.com void setBitRequirements() const override 75214034Sjavier.bueno@metempsy.com { 75314034Sjavier.bueno@metempsy.com mpp.doing_local = true; 75414034Sjavier.bueno@metempsy.com } 75514034Sjavier.bueno@metempsy.com }; 75614034Sjavier.bueno@metempsy.com 75714034Sjavier.bueno@metempsy.com class MODPATH : public HistorySpec { 75814034Sjavier.bueno@metempsy.com public: 75914034Sjavier.bueno@metempsy.com MODPATH(int p1, int p2, int p3, double coeff, int size, int width, 76014034Sjavier.bueno@metempsy.com MultiperspectivePerceptron &mpp) 76114034Sjavier.bueno@metempsy.com : HistorySpec(p1, p2, p3, coeff, size, width, mpp) 76214034Sjavier.bueno@metempsy.com {} 76314034Sjavier.bueno@metempsy.com 76414034Sjavier.bueno@metempsy.com unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const 76514034Sjavier.bueno@metempsy.com override 76614034Sjavier.bueno@metempsy.com { 76714034Sjavier.bueno@metempsy.com int a = p1; 76814034Sjavier.bueno@metempsy.com int depth = p2; 76914034Sjavier.bueno@metempsy.com int shift = p3; 77014034Sjavier.bueno@metempsy.com 77114034Sjavier.bueno@metempsy.com unsigned int x = 0; 77214034Sjavier.bueno@metempsy.com for (int i=0; i<depth; i += 1) { 77314034Sjavier.bueno@metempsy.com x <<= shift; 77414034Sjavier.bueno@metempsy.com x += mpp.threadData[tid]->modpath_histories[a][i]; 77514034Sjavier.bueno@metempsy.com } 77614034Sjavier.bueno@metempsy.com return x; 77714034Sjavier.bueno@metempsy.com } 77814034Sjavier.bueno@metempsy.com void setBitRequirements() const override 77914034Sjavier.bueno@metempsy.com { 78014034Sjavier.bueno@metempsy.com mpp.insertModpathSpec(p1, p2); 78114034Sjavier.bueno@metempsy.com } 78214034Sjavier.bueno@metempsy.com }; 78314034Sjavier.bueno@metempsy.com 78414034Sjavier.bueno@metempsy.com class GHISTPATH : public HistorySpec { 78514034Sjavier.bueno@metempsy.com public: 78614034Sjavier.bueno@metempsy.com GHISTPATH(int p1, int p2, int p3, double coeff, int size, int width, 78714034Sjavier.bueno@metempsy.com MultiperspectivePerceptron &mpp) 78814034Sjavier.bueno@metempsy.com : HistorySpec(p1, p2, p3, coeff, size, width, mpp) 78914034Sjavier.bueno@metempsy.com {} 79014034Sjavier.bueno@metempsy.com 79114034Sjavier.bueno@metempsy.com unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const 79214034Sjavier.bueno@metempsy.com override 79314034Sjavier.bueno@metempsy.com { 79414034Sjavier.bueno@metempsy.com int depth = p1; 79514034Sjavier.bueno@metempsy.com int shift = p2; 79614034Sjavier.bueno@metempsy.com int style = p3; 79714034Sjavier.bueno@metempsy.com std::vector<unsigned int> &ghist_words = 79814034Sjavier.bueno@metempsy.com mpp.threadData[tid]->ghist_words; 79914034Sjavier.bueno@metempsy.com std::vector<unsigned short int> &path_history = 80014034Sjavier.bueno@metempsy.com mpp.threadData[tid]->path_history; 80114034Sjavier.bueno@metempsy.com 80214034Sjavier.bueno@metempsy.com if (style == -1) { 80314034Sjavier.bueno@metempsy.com unsigned int x = 0; 80414034Sjavier.bueno@metempsy.com int bm = (depth / mpp.blockSize) * mpp.blockSize; 80514034Sjavier.bueno@metempsy.com unsigned int w; 80614034Sjavier.bueno@metempsy.com for (int i = 0; i < bm; i += mpp.blockSize) { 80714034Sjavier.bueno@metempsy.com w = ghist_words[i / mpp.blockSize]; 80814034Sjavier.bueno@metempsy.com for (int j = 0; j < mpp.blockSize; j += 1) { 80914034Sjavier.bueno@metempsy.com x <<= shift; 81014034Sjavier.bueno@metempsy.com x += (path_history[i + j] << 1) | (w & 1); 81114034Sjavier.bueno@metempsy.com w >>= 1; 81214034Sjavier.bueno@metempsy.com } 81314034Sjavier.bueno@metempsy.com } 81414034Sjavier.bueno@metempsy.com w = ghist_words[bm / mpp.blockSize]; 81514034Sjavier.bueno@metempsy.com for (int i = bm; i < depth; i += 1) { 81614034Sjavier.bueno@metempsy.com x <<= shift; 81714034Sjavier.bueno@metempsy.com x += (path_history[i] << 1) | (w & 1); 81814034Sjavier.bueno@metempsy.com w >>= 1; 81914034Sjavier.bueno@metempsy.com } 82014034Sjavier.bueno@metempsy.com return x; 82114034Sjavier.bueno@metempsy.com } else { 82214034Sjavier.bueno@metempsy.com unsigned int x = 0; 82314034Sjavier.bueno@metempsy.com int bm = (depth / mpp.blockSize) * mpp.blockSize; 82414034Sjavier.bueno@metempsy.com unsigned int w = 0; 82514034Sjavier.bueno@metempsy.com for (int i = 0; i < bm; i += mpp.blockSize) { 82614034Sjavier.bueno@metempsy.com w = ghist_words[i / mpp.blockSize]; 82714034Sjavier.bueno@metempsy.com for (int j = 0; j < mpp.blockSize; j += 1) { 82814034Sjavier.bueno@metempsy.com x ^= (!!(path_history[i + j] & (1 << shift))) << j; 82914034Sjavier.bueno@metempsy.com x ^= (w & 1) << j; 83014034Sjavier.bueno@metempsy.com w >>= 1; 83114034Sjavier.bueno@metempsy.com } 83214034Sjavier.bueno@metempsy.com } 83314034Sjavier.bueno@metempsy.com w = ghist_words[bm/mpp.blockSize]; 83414034Sjavier.bueno@metempsy.com int k = 0; 83514034Sjavier.bueno@metempsy.com for (int i = bm; i < depth; i += 1) { 83614034Sjavier.bueno@metempsy.com x ^= (!!(path_history[i] & (1 << shift))) << k; 83714034Sjavier.bueno@metempsy.com x ^= (w & 1) << k; 83814034Sjavier.bueno@metempsy.com w >>= 1; 83914034Sjavier.bueno@metempsy.com k += 1; 84014034Sjavier.bueno@metempsy.com } 84114034Sjavier.bueno@metempsy.com return x; 84214034Sjavier.bueno@metempsy.com } 84314034Sjavier.bueno@metempsy.com } 84414034Sjavier.bueno@metempsy.com 84514034Sjavier.bueno@metempsy.com void setBitRequirements() const override 84614034Sjavier.bueno@metempsy.com { 84714034Sjavier.bueno@metempsy.com if (mpp.ghist_length <= p1) { 84814034Sjavier.bueno@metempsy.com mpp.ghist_length = p1 + 1; 84914034Sjavier.bueno@metempsy.com } 85014034Sjavier.bueno@metempsy.com if (mpp.path_length <= p1) { 85114034Sjavier.bueno@metempsy.com mpp.path_length = p1 + 1; 85214034Sjavier.bueno@metempsy.com } 85314034Sjavier.bueno@metempsy.com } 85414034Sjavier.bueno@metempsy.com }; 85514034Sjavier.bueno@metempsy.com 85614034Sjavier.bueno@metempsy.com class GHISTMODPATH : public HistorySpec { 85714034Sjavier.bueno@metempsy.com public: 85814034Sjavier.bueno@metempsy.com GHISTMODPATH(int p1, int p2, int p3, double coeff, int size, int width, 85914034Sjavier.bueno@metempsy.com MultiperspectivePerceptron &mpp) 86014034Sjavier.bueno@metempsy.com : HistorySpec(p1, p2, p3, coeff, size, width, mpp) 86114034Sjavier.bueno@metempsy.com {} 86214034Sjavier.bueno@metempsy.com 86314034Sjavier.bueno@metempsy.com unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const 86414034Sjavier.bueno@metempsy.com override 86514034Sjavier.bueno@metempsy.com { 86614034Sjavier.bueno@metempsy.com int a = p1; 86714034Sjavier.bueno@metempsy.com int depth = p2; 86814034Sjavier.bueno@metempsy.com int shift = p3; 86914034Sjavier.bueno@metempsy.com std::vector<std::vector<unsigned short int>> &modpath_histories = 87014034Sjavier.bueno@metempsy.com mpp.threadData[tid]->modpath_histories; 87114034Sjavier.bueno@metempsy.com std::vector<std::vector<bool>> &mod_histories = 87214034Sjavier.bueno@metempsy.com mpp.threadData[tid]->mod_histories; 87314034Sjavier.bueno@metempsy.com 87414034Sjavier.bueno@metempsy.com unsigned int x = 0; 87514034Sjavier.bueno@metempsy.com for (int i = 0; i < depth; i += 1) { 87614034Sjavier.bueno@metempsy.com x <<= shift; 87714034Sjavier.bueno@metempsy.com x += (modpath_histories[a][i] << 1) | mod_histories[a][i]; 87814034Sjavier.bueno@metempsy.com } 87914034Sjavier.bueno@metempsy.com return x; 88014034Sjavier.bueno@metempsy.com } 88114034Sjavier.bueno@metempsy.com void setBitRequirements() const override 88214034Sjavier.bueno@metempsy.com { 88314034Sjavier.bueno@metempsy.com mpp.insertModhistSpec(p1, p2); 88414034Sjavier.bueno@metempsy.com mpp.insertModpathSpec(p1, p2); 88514034Sjavier.bueno@metempsy.com } 88614034Sjavier.bueno@metempsy.com }; 88714034Sjavier.bueno@metempsy.com 88814034Sjavier.bueno@metempsy.com class BLURRYPATH : public HistorySpec { 88914034Sjavier.bueno@metempsy.com public: 89014034Sjavier.bueno@metempsy.com BLURRYPATH(int p1, int p2, int p3, double coeff, int size, int width, 89114034Sjavier.bueno@metempsy.com MultiperspectivePerceptron &mpp) 89214034Sjavier.bueno@metempsy.com : HistorySpec(p1, p2, p3, coeff, size, width, mpp) 89314034Sjavier.bueno@metempsy.com {} 89414034Sjavier.bueno@metempsy.com 89514034Sjavier.bueno@metempsy.com unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const 89614034Sjavier.bueno@metempsy.com override 89714034Sjavier.bueno@metempsy.com { 89814034Sjavier.bueno@metempsy.com int scale = p1; 89914034Sjavier.bueno@metempsy.com int depth = p2; 90014034Sjavier.bueno@metempsy.com int shiftdelta = p3; 90114034Sjavier.bueno@metempsy.com 90214034Sjavier.bueno@metempsy.com if (shiftdelta == -1) shiftdelta = 0; 90314034Sjavier.bueno@metempsy.com int sdint = shiftdelta >> 2; 90414034Sjavier.bueno@metempsy.com int sdfrac = shiftdelta & 3; 90514034Sjavier.bueno@metempsy.com unsigned int x = 0; 90614034Sjavier.bueno@metempsy.com int shift = 0; 90714034Sjavier.bueno@metempsy.com int count = 0; 90814034Sjavier.bueno@metempsy.com for (int i = 0; i < depth; i += 1) { 90914034Sjavier.bueno@metempsy.com x += mpp.threadData[tid]->blurrypath_histories[scale][i] >> 91014034Sjavier.bueno@metempsy.com shift; 91114034Sjavier.bueno@metempsy.com count += 1; 91214034Sjavier.bueno@metempsy.com if (count == sdfrac) { 91314034Sjavier.bueno@metempsy.com shift += sdint; 91414034Sjavier.bueno@metempsy.com count = 0; 91514034Sjavier.bueno@metempsy.com } 91614034Sjavier.bueno@metempsy.com } 91714034Sjavier.bueno@metempsy.com return x; 91814034Sjavier.bueno@metempsy.com 91914034Sjavier.bueno@metempsy.com } 92014034Sjavier.bueno@metempsy.com void setBitRequirements() const override 92114034Sjavier.bueno@metempsy.com { 92214034Sjavier.bueno@metempsy.com if (mpp.blurrypath_bits.size() < (p1 + 1)) { 92314034Sjavier.bueno@metempsy.com mpp.blurrypath_bits.resize(p1 + 1); 92414034Sjavier.bueno@metempsy.com } 92514034Sjavier.bueno@metempsy.com if (mpp.blurrypath_bits[p1].size() < p2) { 92614034Sjavier.bueno@metempsy.com mpp.blurrypath_bits[p1].resize(p2); 92714034Sjavier.bueno@metempsy.com } 92814034Sjavier.bueno@metempsy.com for (int j = 0; j < p2; j += 1) { 92914034Sjavier.bueno@metempsy.com mpp.blurrypath_bits[p1][j] = 32 - p1; 93014034Sjavier.bueno@metempsy.com } 93114034Sjavier.bueno@metempsy.com } 93214034Sjavier.bueno@metempsy.com }; 93314034Sjavier.bueno@metempsy.com 93414034Sjavier.bueno@metempsy.com class RECENCYPOS : public HistorySpec { 93514034Sjavier.bueno@metempsy.com public: 93614034Sjavier.bueno@metempsy.com RECENCYPOS(int p1, double coeff, int size, int width, 93714034Sjavier.bueno@metempsy.com MultiperspectivePerceptron &mpp) 93814034Sjavier.bueno@metempsy.com : HistorySpec(p1, 0, 0, coeff, size, width, mpp) 93914034Sjavier.bueno@metempsy.com {} 94014034Sjavier.bueno@metempsy.com 94114034Sjavier.bueno@metempsy.com unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const 94214034Sjavier.bueno@metempsy.com override 94314034Sjavier.bueno@metempsy.com { 94414034Sjavier.bueno@metempsy.com return hash(mpp.threadData[tid]->recency_stack, mpp.table_sizes, 94514034Sjavier.bueno@metempsy.com pc2, p1, t); 94614034Sjavier.bueno@metempsy.com } 94714034Sjavier.bueno@metempsy.com 94814034Sjavier.bueno@metempsy.com static unsigned int hash( 94914034Sjavier.bueno@metempsy.com const std::vector<unsigned int short> &recency_stack, 95014034Sjavier.bueno@metempsy.com const std::vector<int> &table_sizes, unsigned short int pc, int l, 95114034Sjavier.bueno@metempsy.com int t) 95214034Sjavier.bueno@metempsy.com { 95314034Sjavier.bueno@metempsy.com // search for the PC 95414034Sjavier.bueno@metempsy.com 95514034Sjavier.bueno@metempsy.com for (int i = 0; i < l; i += 1) { 95614034Sjavier.bueno@metempsy.com if (recency_stack[i] == pc) { 95714034Sjavier.bueno@metempsy.com return i * table_sizes[t] / l; 95814034Sjavier.bueno@metempsy.com } 95914034Sjavier.bueno@metempsy.com } 96014034Sjavier.bueno@metempsy.com 96114034Sjavier.bueno@metempsy.com // return last index in table on a miss 96214034Sjavier.bueno@metempsy.com 96314034Sjavier.bueno@metempsy.com return table_sizes[t] - 1; 96414034Sjavier.bueno@metempsy.com } 96514034Sjavier.bueno@metempsy.com 96614034Sjavier.bueno@metempsy.com void setBitRequirements() const override 96714034Sjavier.bueno@metempsy.com { 96814034Sjavier.bueno@metempsy.com if (mpp.assoc < p1) { 96914034Sjavier.bueno@metempsy.com mpp.assoc = p1; 97014034Sjavier.bueno@metempsy.com } 97114034Sjavier.bueno@metempsy.com mpp.doing_recency = true; 97214034Sjavier.bueno@metempsy.com } 97314034Sjavier.bueno@metempsy.com }; 97414034Sjavier.bueno@metempsy.com 97514034Sjavier.bueno@metempsy.com class SGHISTPATH : public HistorySpec { 97614034Sjavier.bueno@metempsy.com public: 97714034Sjavier.bueno@metempsy.com SGHISTPATH(int p1, int p2, int p3, double coeff, int size, int width, 97814034Sjavier.bueno@metempsy.com MultiperspectivePerceptron &mpp) 97914034Sjavier.bueno@metempsy.com : HistorySpec(p1, p2, p3, coeff, size, width, mpp) 98014034Sjavier.bueno@metempsy.com {} 98114034Sjavier.bueno@metempsy.com 98214034Sjavier.bueno@metempsy.com unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const 98314034Sjavier.bueno@metempsy.com override 98414034Sjavier.bueno@metempsy.com { 98514034Sjavier.bueno@metempsy.com int a = p1; 98614034Sjavier.bueno@metempsy.com int b = p2; 98714034Sjavier.bueno@metempsy.com int shift = p3; 98814034Sjavier.bueno@metempsy.com std::vector<unsigned int> &ghist_words = 98914034Sjavier.bueno@metempsy.com mpp.threadData[tid]->ghist_words; 99014034Sjavier.bueno@metempsy.com std::vector<unsigned short int> &path_history = 99114034Sjavier.bueno@metempsy.com mpp.threadData[tid]->path_history; 99214034Sjavier.bueno@metempsy.com 99314034Sjavier.bueno@metempsy.com unsigned int x = 0; 99414034Sjavier.bueno@metempsy.com int bm = (b / mpp.blockSize) * mpp.blockSize; 99514034Sjavier.bueno@metempsy.com unsigned int w; 99614034Sjavier.bueno@metempsy.com for (int i = a; i < bm; i += mpp.blockSize) { 99714034Sjavier.bueno@metempsy.com w = ghist_words[i / mpp.blockSize]; 99814034Sjavier.bueno@metempsy.com for (int j = 0; j < mpp.blockSize; j += 1) { 99914034Sjavier.bueno@metempsy.com x <<= shift; 100014034Sjavier.bueno@metempsy.com x += (path_history[i+j] << 1) | (w & 1); 100114034Sjavier.bueno@metempsy.com w >>= 1; 100214034Sjavier.bueno@metempsy.com } 100314034Sjavier.bueno@metempsy.com } 100414034Sjavier.bueno@metempsy.com w = ghist_words[bm / mpp.blockSize]; 100514034Sjavier.bueno@metempsy.com for (int i = bm; i < b; i += 1) { 100614034Sjavier.bueno@metempsy.com x <<= shift; 100714034Sjavier.bueno@metempsy.com x += (path_history[i] << 1) | (w & 1); 100814034Sjavier.bueno@metempsy.com w >>= 1; 100914034Sjavier.bueno@metempsy.com } 101014034Sjavier.bueno@metempsy.com return x; 101114034Sjavier.bueno@metempsy.com } 101214034Sjavier.bueno@metempsy.com }; 101314034Sjavier.bueno@metempsy.com 101414034Sjavier.bueno@metempsy.com public: 101514034Sjavier.bueno@metempsy.com MultiperspectivePerceptron(const MultiperspectivePerceptronParams *params); 101614034Sjavier.bueno@metempsy.com 101714081Sjavier.bueno@metempsy.com /** 101814081Sjavier.bueno@metempsy.com * Sets the starting number of storage bits to compute the number of 101914081Sjavier.bueno@metempsy.com * table entries 102014081Sjavier.bueno@metempsy.com * @param bits number of bits used 102114081Sjavier.bueno@metempsy.com */ 102214081Sjavier.bueno@metempsy.com void setExtraBits(int bits); 102314081Sjavier.bueno@metempsy.com 102414034Sjavier.bueno@metempsy.com void init() override; 102514034Sjavier.bueno@metempsy.com 102614034Sjavier.bueno@metempsy.com void uncondBranch(ThreadID tid, Addr pc, void * &bp_history) override; 102714034Sjavier.bueno@metempsy.com void squash(ThreadID tid, void *bp_history) override; 102814034Sjavier.bueno@metempsy.com bool lookup(ThreadID tid, Addr instPC, void * &bp_history) override; 102914034Sjavier.bueno@metempsy.com void update(ThreadID tid, Addr instPC, bool taken, 103014034Sjavier.bueno@metempsy.com void *bp_history, bool squashed, 103114034Sjavier.bueno@metempsy.com const StaticInstPtr & inst, 103214034Sjavier.bueno@metempsy.com Addr corrTarget = MaxAddr) override; 103314034Sjavier.bueno@metempsy.com void btbUpdate(ThreadID tid, Addr branch_addr, void* &bp_history) override; 103414034Sjavier.bueno@metempsy.com}; 103514034Sjavier.bueno@metempsy.com#endif//__CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_HH__ 1036