diff options
Diffstat (limited to 'src/cpu/pred/indirect.cc')
-rw-r--r-- | src/cpu/pred/indirect.cc | 200 |
1 files changed, 0 insertions, 200 deletions
diff --git a/src/cpu/pred/indirect.cc b/src/cpu/pred/indirect.cc index 2f88566b4..2f0aca1af 100644 --- a/src/cpu/pred/indirect.cc +++ b/src/cpu/pred/indirect.cc @@ -29,203 +29,3 @@ */ #include "cpu/pred/indirect.hh" - -#include "base/intmath.hh" -#include "debug/Indirect.hh" - -IndirectPredictor::IndirectPredictor(bool hash_ghr, bool hash_targets, - unsigned num_sets, unsigned num_ways, - unsigned tag_bits, unsigned path_len, unsigned inst_shift, - unsigned num_threads, unsigned ghr_size) - : hashGHR(hash_ghr), hashTargets(hash_targets), - numSets(num_sets), numWays(num_ways), tagBits(tag_bits), - pathLength(path_len), instShift(inst_shift), - ghrNumBits(ghr_size), ghrMask((1 << ghr_size)-1) -{ - if (!isPowerOf2(numSets)) { - panic("Indirect predictor requires power of 2 number of sets"); - } - - threadInfo.resize(num_threads); - - targetCache.resize(numSets); - for (unsigned i = 0; i < numSets; i++) { - targetCache[i].resize(numWays); - } - - fatal_if(ghrNumBits > (sizeof(ThreadInfo::ghr)*8), "ghr_size is too big"); -} - -void -IndirectPredictor::genIndirectInfo(ThreadID tid, void* & indirect_history) -{ - // record the GHR as it was before this prediction - // It will be used to recover the history in case this prediction is - // wrong or belongs to bad path - indirect_history = new unsigned(threadInfo[tid].ghr); -} - -void -IndirectPredictor::updateDirectionInfo( - ThreadID tid, bool actually_taken) -{ - threadInfo[tid].ghr <<= 1; - threadInfo[tid].ghr |= actually_taken; - threadInfo[tid].ghr &= ghrMask; -} - -void -IndirectPredictor::changeDirectionPrediction(ThreadID tid, - void * indirect_history, bool actually_taken) -{ - unsigned * previousGhr = static_cast<unsigned *>(indirect_history); - threadInfo[tid].ghr = ((*previousGhr) << 1) + actually_taken; - threadInfo[tid].ghr &= ghrMask; -} - -bool -IndirectPredictor::lookup(Addr br_addr, TheISA::PCState& target, - ThreadID tid) -{ - Addr set_index = getSetIndex(br_addr, threadInfo[tid].ghr, tid); - Addr tag = getTag(br_addr); - - assert(set_index < numSets); - - DPRINTF(Indirect, "Looking up %x (set:%d)\n", br_addr, set_index); - const auto &iset = targetCache[set_index]; - for (auto way = iset.begin(); way != iset.end(); ++way) { - if (way->tag == tag) { - DPRINTF(Indirect, "Hit %x (target:%s)\n", br_addr, way->target); - target = way->target; - return true; - } - } - DPRINTF(Indirect, "Miss %x\n", br_addr); - return false; -} - -void -IndirectPredictor::recordIndirect(Addr br_addr, Addr tgt_addr, - InstSeqNum seq_num, ThreadID tid) -{ - DPRINTF(Indirect, "Recording %x seq:%d\n", br_addr, seq_num); - HistoryEntry entry(br_addr, tgt_addr, seq_num); - threadInfo[tid].pathHist.push_back(entry); -} - -void -IndirectPredictor::commit(InstSeqNum seq_num, ThreadID tid, - void * indirect_history) -{ - DPRINTF(Indirect, "Committing seq:%d\n", seq_num); - ThreadInfo &t_info = threadInfo[tid]; - - // we do not need to recover the GHR, so delete the information - unsigned * previousGhr = static_cast<unsigned *>(indirect_history); - delete previousGhr; - - if (t_info.pathHist.empty()) return; - - if (t_info.headHistEntry < t_info.pathHist.size() && - t_info.pathHist[t_info.headHistEntry].seqNum <= seq_num) { - if (t_info.headHistEntry >= pathLength) { - t_info.pathHist.pop_front(); - } else { - ++t_info.headHistEntry; - } - } -} - -void -IndirectPredictor::squash(InstSeqNum seq_num, ThreadID tid) -{ - DPRINTF(Indirect, "Squashing seq:%d\n", seq_num); - ThreadInfo &t_info = threadInfo[tid]; - auto squash_itr = t_info.pathHist.begin(); - while (squash_itr != t_info.pathHist.end()) { - if (squash_itr->seqNum > seq_num) { - break; - } - ++squash_itr; - } - if (squash_itr != t_info.pathHist.end()) { - DPRINTF(Indirect, "Squashing series starting with sn:%d\n", - squash_itr->seqNum); - } - t_info.pathHist.erase(squash_itr, t_info.pathHist.end()); -} - -void -IndirectPredictor::deleteIndirectInfo(ThreadID tid, void * indirect_history) -{ - unsigned * previousGhr = static_cast<unsigned *>(indirect_history); - threadInfo[tid].ghr = *previousGhr; - - delete previousGhr; -} - -void -IndirectPredictor::recordTarget( - InstSeqNum seq_num, void * indirect_history, const TheISA::PCState& target, - ThreadID tid) -{ - ThreadInfo &t_info = threadInfo[tid]; - - unsigned * ghr = static_cast<unsigned *>(indirect_history); - - // Should have just squashed so this branch should be the oldest - auto hist_entry = *(t_info.pathHist.rbegin()); - // Temporarily pop it off the history so we can calculate the set - t_info.pathHist.pop_back(); - Addr set_index = getSetIndex(hist_entry.pcAddr, *ghr, tid); - Addr tag = getTag(hist_entry.pcAddr); - hist_entry.targetAddr = target.instAddr(); - t_info.pathHist.push_back(hist_entry); - - assert(set_index < numSets); - - auto &iset = targetCache[set_index]; - for (auto way = iset.begin(); way != iset.end(); ++way) { - if (way->tag == tag) { - DPRINTF(Indirect, "Updating Target (seq: %d br:%x set:%d target:" - "%s)\n", seq_num, hist_entry.pcAddr, set_index, target); - way->target = target; - return; - } - } - - DPRINTF(Indirect, "Allocating Target (seq: %d br:%x set:%d target:%s)\n", - seq_num, hist_entry.pcAddr, set_index, target); - // Did not find entry, random replacement - auto &way = iset[rand() % numWays]; - way.tag = tag; - way.target = target; -} - - -inline Addr -IndirectPredictor::getSetIndex(Addr br_addr, unsigned ghr, ThreadID tid) -{ - ThreadInfo &t_info = threadInfo[tid]; - - Addr hash = br_addr >> instShift; - if (hashGHR) { - hash ^= ghr; - } - if (hashTargets) { - unsigned hash_shift = floorLog2(numSets) / pathLength; - for (int i = t_info.pathHist.size()-1, p = 0; - i >= 0 && p < pathLength; i--, p++) { - hash ^= (t_info.pathHist[i].targetAddr >> - (instShift + p*hash_shift)); - } - } - return hash & (numSets-1); -} - -inline Addr -IndirectPredictor::getTag(Addr br_addr) -{ - return (br_addr >> instShift) & ((0x1<<tagBits)-1); -} |