1/* 2 * Copyright 2019 Texas A&M University 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * 3. Neither the name of the copyright holder nor the names of its 15 * contributors may be used to endorse or promote products derived from this 16 * software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Author: Daniel A. Jiménez 31 * Adapted to gem5 by: Javier Bueno Hedo 32 * 33 */ 34 35/* 36 * Multiperspective Perceptron Predictor with TAGE (by Daniel A. Jiménez) 37 */ 38 39#include "cpu/pred/multiperspective_perceptron_tage.hh" 40 41#include "base/random.hh" 42 43void 44MPP_TAGE::calculateParameters() 45{ 46 assert(tunedHistoryLengths.size() == (nHistoryTables+1)); 47 for (int i = 0; i <= nHistoryTables; i += 1) { 48 histLengths[i] = tunedHistoryLengths[i]; 49 } 50} 51 52void 53MPP_TAGE::handleTAGEUpdate(Addr branch_pc, bool taken, 54 TAGEBase::BranchInfo* bi) 55{ 56 if (bi->hitBank > 0) { 57 if (abs (2 * gtable[bi->hitBank][bi->hitBankIndex].ctr + 1) == 1) { 58 if (bi->longestMatchPred != taken) { 59 // acts as a protection 60 if (bi->altBank > 0) { 61 ctrUpdate(gtable[bi->altBank][bi->altBankIndex].ctr, taken, 62 tagTableCounterBits); 63 } 64 if (bi->altBank == 0){ 65 baseUpdate(branch_pc, taken, bi); 66 } 67 } 68 } 69 70 ctrUpdate(gtable[bi->hitBank][bi->hitBankIndex].ctr, taken, 71 tagTableCounterBits); 72 73 //sign changes: no way it can have been useful 74 if (abs (2 * gtable[bi->hitBank][bi->hitBankIndex].ctr + 1) == 1) { 75 gtable[bi->hitBank][bi->hitBankIndex].u = 0; 76 } 77 } else { 78 baseUpdate(branch_pc, taken, bi); 79 } 80 81 if ((bi->longestMatchPred != bi->altTaken) && 82 (bi->longestMatchPred == taken) && 83 (gtable[bi->hitBank][bi->hitBankIndex].u < (1 << tagTableUBits) -1)) { 84 gtable[bi->hitBank][bi->hitBankIndex].u++; 85 } 86} 87 88void 89MPP_TAGE::handleAllocAndUReset(bool alloc, bool taken, 90 TAGEBase::BranchInfo* bi, int nrand) 91{ 92 if (!alloc) { 93 return; 94 } 95 96 int a = 1; 97 98 if ((random_mt.random<int>() & 127) < 32) { 99 a = 2; 100 } 101 int dep = bi->hitBank + a; 102 103 int penalty = 0; 104 int numAllocated = 0; 105 int T = 1; 106 107 for (int i = dep; i <= nHistoryTables; i += 1) { 108 if (noSkip[i]) { 109 if (gtable[i][bi->tableIndices[i]].u == 0) { 110 gtable[i][bi->tableIndices[i]].tag = bi->tableTags[i]; 111 gtable[i][bi->tableIndices[i]].ctr = taken ? 0 : -1; 112 numAllocated++; 113 if (T <= 0) { 114 break; 115 } 116 i += 1; 117 T -= 1; 118 } else { 119 penalty++; 120 } 121 } else { assert(false); } 122 } 123 124 tCounter += (penalty - numAllocated); 125 126 handleUReset(); 127} 128 129void 130MPP_TAGE::handleUReset() 131{ 132 //just the best formula for the Championship: 133 //In practice when one out of two entries are useful 134 if (tCounter < 0) { 135 tCounter = 0; 136 } 137 138 if (tCounter >= ((ULL(1) << logUResetPeriod))) { 139 // Update the u bits for the short tags table 140 for (int i = 1; i <= nHistoryTables; i++) { 141 for (int j = 0; j < (ULL(1) << logTagTableSizes[i]); j++) { 142 resetUctr(gtable[i][j].u); 143 } 144 } 145 146 tCounter = 0; 147 } 148} 149 150void 151MPP_TAGE::resetUctr(uint8_t &u) 152{ 153 // On real HW it should be u >>= 1 instead of if > 0 then u-- 154 if (u > 0) { 155 u--; 156 } 157} 158 159 160int 161MPP_TAGE::bindex(Addr pc_in) const 162{ 163 uint32_t pc = (uint32_t) pc_in; 164 return ((pc ^ (pc >> 4)) & 165 ((ULL(1) << (logTagTableSizes[0])) - 1)); 166} 167 168unsigned 169MPP_TAGE::getUseAltIdx(TAGEBase::BranchInfo* bi, Addr branch_pc) 170{ 171 uint32_t hpc = ((uint32_t) branch_pc); 172 hpc = (hpc ^(hpc >> 4)); 173 return 2 * ((hpc & ((numUseAltOnNa/2)-1)) ^ bi->longestMatchPred) + 174 ((bi->hitBank > (nHistoryTables / 3)) ? 1 : 0); 175} 176 177void 178MPP_TAGE::adjustAlloc(bool & alloc, bool taken, bool pred_taken) 179{ 180 // Do not allocate too often if the prediction is ok 181 if ((taken == pred_taken) && ((random_mt.random<int>() & 31) != 0)) { 182 alloc = false; 183 } 184} 185 186void 187MPP_TAGE::updateHistories( 188 ThreadID tid, Addr branch_pc, bool taken, TAGEBase::BranchInfo* b, 189 bool speculative, const StaticInstPtr &inst, Addr target) 190{ 191 if (speculative != speculativeHistUpdate) { 192 return; 193 } 194 // speculation is not implemented 195 assert(! speculative); 196 197 ThreadHistory& tHist = threadHistory[tid]; 198 199 int brtype = inst->isDirectCtrl() ? 0 : 2; 200 if (! inst->isUncondCtrl()) { 201 ++brtype; 202 } 203 updatePathAndGlobalHistory(tHist, brtype, taken, branch_pc, target); 204} 205 206void 207MPP_TAGE::updatePathAndGlobalHistory( 208 ThreadHistory& tHist, int brtype, bool taken, Addr branch_pc, Addr target) 209{ 210 // TAGE update 211 int tmp = (branch_pc << 1) + taken; 212 int path = branch_pc; 213 214 int maxt = (brtype & 1) ? 1 : 4; 215 216 for (int t = 0; t < maxt; t++) { 217 bool dir = (tmp & 1); 218 tmp >>= 1; 219 int pathbit = (path & 127); 220 path >>= 1; 221 updateGHist(tHist.gHist, dir, tHist.globalHistory, tHist.ptGhist); 222 tHist.pathHist = (tHist.pathHist << 1) ^ pathbit; 223 for (int i = 1; i <= nHistoryTables; i++) { 224 tHist.computeIndices[i].update(tHist.gHist); 225 tHist.computeTags[0][i].update(tHist.gHist); 226 tHist.computeTags[1][i].update(tHist.gHist); 227 } 228 } 229} 230 231bool 232MPP_TAGE::isHighConfidence(TAGEBase::BranchInfo *bi) const 233{ 234 if (bi->hitBank > 0) { 235 return (abs(2 * gtable[bi->hitBank][bi->hitBankIndex].ctr + 1)) >= 236 ((1 << tagTableCounterBits) - 1); 237 } else { 238 int bim = (btablePrediction[bi->bimodalIndex] << 1) 239 + btableHysteresis[bi->bimodalIndex >> logRatioBiModalHystEntries]; 240 return (bim == 0) || (bim == 3); 241 } 242 243} 244 245MPP_TAGE* 246MPP_TAGEParams::create() 247{ 248 return new MPP_TAGE(this); 249} 250 251bool 252MPP_LoopPredictor::calcConf(int index) const 253{ 254 return LoopPredictor::calcConf(index) || 255 (ltable[index].confidence * ltable[index].numIter > 128); 256} 257 258bool 259MPP_LoopPredictor::optionalAgeInc() const 260{ 261 return ((random_mt.random<int>() & 7) == 0); 262} 263 264MPP_LoopPredictor* 265MPP_LoopPredictorParams::create() 266{ 267 return new MPP_LoopPredictor(this); 268} 269 270MPP_StatisticalCorrector::MPP_StatisticalCorrector( 271 const MPP_StatisticalCorrectorParams *p) : StatisticalCorrector(p), 272 thirdH(0), pnb(p->pnb), logPnb(p->logPnb), pm(p->pm), gnb(p->gnb), 273 logGnb(p->logGnb), gm(p->gm) 274{ 275 initGEHLTable(pnb, pm, pgehl, logPnb, wp, -1); 276 initGEHLTable(gnb, gm, ggehl, logGnb, wg, -1); 277 278 for (int8_t &pos : wl) { 279 pos = -1; 280 } 281} 282 283void 284MPP_StatisticalCorrector::initBias() 285{ 286 for (int j = 0; j < (1 << logBias); j++) { 287 if (j & 1) { 288 bias[j] = 15; 289 biasSK[j] = 15; 290 } else { 291 bias[j] = -16; 292 biasSK[j] = -16; 293 } 294 } 295} 296 297unsigned 298MPP_StatisticalCorrector::getIndBias(Addr branch_pc, 299 StatisticalCorrector::BranchInfo* bi, bool bias) const 300{ 301 unsigned int truncated_pc = branch_pc; 302 return ((truncated_pc << 1) + bi->predBeforeSC) & ((1 << logBias) - 1); 303} 304 305unsigned 306MPP_StatisticalCorrector::getIndBiasSK(Addr branch_pc, 307 StatisticalCorrector::BranchInfo* bi) const 308{ 309 return (((branch_pc ^ (branch_pc >> (logBias - 1))) << 1) 310 + bi->predBeforeSC) & ((1 << logBias) - 1); 311} 312 313unsigned 314MPP_StatisticalCorrector::getIndBiasBank(Addr branch_pc, 315 StatisticalCorrector::BranchInfo* bi, int hitBank, int altBank) const 316{ 317 return 0; 318} 319 320int 321MPP_StatisticalCorrector::gIndexLogsSubstr(int nbr, int i) 322{ 323 return (i >= (nbr - 2)) ? 1 : 0; 324} 325 326unsigned 327MPP_StatisticalCorrector::getIndUpd(Addr branch_pc) const 328{ 329 return ((branch_pc ^ (branch_pc >> 4)) & ((1 << (logSizeUp)) - 1)); 330} 331 332void 333MPP_StatisticalCorrector::gUpdate(Addr branch_pc, bool taken, int64_t hist, 334 std::vector<int> & length, std::vector<int8_t> * tab, 335 int nbr, int logs, std::vector<int8_t> & w, 336 StatisticalCorrector::BranchInfo* bi) 337{ 338 int percsum = 0; 339 for (int i = 0; i < nbr; i++) { 340 int64_t bhist = hist & ((int64_t) ((1 << length[i]) - 1)); 341 int64_t index = gIndex(branch_pc, bhist, logs, nbr, i); 342 percsum += (2 * tab[i][index] + 1); 343 ctrUpdate(tab[i][index], taken, scCountersWidth - (i < (nbr - 1))); 344 } 345} 346 347bool 348MPP_StatisticalCorrector::scPredict(ThreadID tid, Addr branch_pc, 349 bool cond_branch, StatisticalCorrector::BranchInfo* bi, 350 bool prev_pred_taken, bool bias_bit, bool use_conf_ctr, 351 int8_t conf_ctr, unsigned conf_bits, int hitBank, int altBank, 352 int64_t phist, int init_lsum) 353{ 354 bool pred_taken = prev_pred_taken; 355 if (cond_branch) { 356 357 bi->predBeforeSC = prev_pred_taken; 358 359 int lsum = init_lsum; 360 361 getBiasLSUM(branch_pc, bi, lsum); 362 363 int thres = gPredictions(tid, branch_pc, bi, lsum, phist); 364 365 // These will be needed at update time 366 bi->lsum = lsum; 367 bi->thres = thres; 368 bi->scPred = (lsum >= 0); 369 370 if (pred_taken != bi->scPred) { 371 pred_taken = bi->scPred; 372 373 if (bi->highConf /* comes from tage prediction */) { 374 if ((abs(lsum) < thres / 3)) 375 pred_taken = (firstH < 0) ? bi->scPred : prev_pred_taken; 376 else if ((abs(lsum) < 2 * thres / 3)) 377 pred_taken = (secondH < 0) ? bi->scPred : prev_pred_taken; 378 else if ((abs(lsum) < thres)) 379 pred_taken = (thirdH < 0) ? bi->scPred : prev_pred_taken; 380 } 381 } 382 } 383 384 return pred_taken; 385} 386 387MultiperspectivePerceptronTAGE::MultiperspectivePerceptronTAGE( 388 const MultiperspectivePerceptronTAGEParams *p) 389 : MultiperspectivePerceptron(p), tage(p->tage), 390 loopPredictor(p->loop_predictor), 391 statisticalCorrector(p->statistical_corrector) 392{ 393 fatal_if(tage->isSpeculativeUpdateEnabled(), 394 "Speculative updates support is not implemented"); 395} 396 397void 398MultiperspectivePerceptronTAGE::init() 399{ 400 tage->init(); 401 int numBitsTage = tage->getSizeInBits(); 402 int numBitsLoopPred = loopPredictor->getSizeInBits(); 403 int numBitsStatisticalCorrector = statisticalCorrector->getSizeInBits(); 404 405 setExtraBits(numBitsTage + numBitsLoopPred + numBitsStatisticalCorrector); 406 MultiperspectivePerceptron::init(); 407} 408 409 410unsigned int 411MultiperspectivePerceptronTAGE::getIndex(ThreadID tid, MPPTAGEBranchInfo &bi, 412 const HistorySpec &spec, int index) const 413{ 414 // get the hash for the feature 415 unsigned int g = spec.getHash(tid, bi.getPC(), bi.getPC() >> 2, index); 416 // shift it and xor it with the hashed PC 417 unsigned long long int h = g; 418 h <<= 20; 419 h ^= (bi.getPC() ^ (bi.getPC() >> 2)); 420 421 // maybe xor in an IMLI counter 422 if ((1ull << index) & imli_mask1) { 423 h += threadData[tid]->imli_counter[0]; 424 } 425 if ((1ull << index) & imli_mask4) { 426 h += threadData[tid]->imli_counter[3]; 427 } 428 429 // return it modulo the table size 430 return h % table_sizes[index]; 431} 432 433 434int 435MultiperspectivePerceptronTAGE::computePartialSum(ThreadID tid, 436 MPPTAGEBranchInfo &bi) const 437{ 438 int yout = 0; 439 for (int i = 0; i < specs.size(); i += 1) { 440 yout += specs[i]->coeff * 441 threadData[tid]->tables[i][getIndex(tid, bi, *specs[i], i)]; 442 } 443 return yout; 444} 445 446void 447MultiperspectivePerceptronTAGE::updatePartial(ThreadID tid, 448 MPPTAGEBranchInfo &bi, 449 bool taken) 450{ 451 // update tables 452 for (int i = 0; i < specs.size(); i += 1) { 453 unsigned int idx = getIndex(tid, bi, *specs[i], i); 454 short int *c = 455 &threadData[tid]->tables[i][idx]; 456 short int max_weight = (1 << (specs[i]->width - 1)) - 1; 457 short int min_weight = -(1 << (specs[i]->width - 1)); 458 if (taken) { 459 if (*c < max_weight) { 460 *c += 1; 461 } 462 } else { 463 if (*c > min_weight) { 464 *c -= 1; 465 } 466 } 467 } 468} 469 470void 471MultiperspectivePerceptronTAGE::updateHistories(ThreadID tid, 472 MPPTAGEBranchInfo &bi, 473 bool taken) 474{ 475 unsigned int hpc = (bi.getPC() ^ (bi.getPC() >> 2)); 476 unsigned int pc = bi.getPC(); 477 478 // update recency stack 479 unsigned short recency_pc = pc >> 2; 480 threadData[tid]->insertRecency(recency_pc, assoc); 481 482 // update acyclic history 483 threadData[tid]->updateAcyclic(taken, hpc); 484 485 // update modpath histories 486 for (int ii = 0; ii < modpath_indices.size(); ii +=1) { 487 int i = modpath_indices[ii]; 488 if (hpc % (i + 2) == 0) { 489 memmove(&threadData[tid]->modpath_histories[i][1], 490 &threadData[tid]->modpath_histories[i][0], 491 sizeof(unsigned short int) * (modpath_lengths[ii] - 1)); 492 threadData[tid]->modpath_histories[i][0] = hpc; 493 } 494 } 495 496 // update modulo histories 497 for (int ii = 0; ii < modhist_indices.size(); ii += 1) { 498 int i = modhist_indices[ii]; 499 if (hpc % (i + 2) == 0) { 500 for (int j = modhist_lengths[ii] - 1; j > 0; j -= 1) { 501 threadData[tid]->mod_histories[i][j] = 502 threadData[tid]->mod_histories[i][j-1]; 503 } 504 threadData[tid]->mod_histories[i][0] = taken; 505 } 506 } 507 508 // update blurry history 509 std::vector<std::vector<unsigned int>> &blurrypath_histories = 510 threadData[tid]->blurrypath_histories; 511 for (int i = 0; i < blurrypath_histories.size(); i += 1) 512 { 513 if (blurrypath_histories[i].size() > 0) { 514 unsigned int z = pc >> i; 515 if (blurrypath_histories[i][0] != z) { 516 memmove(&blurrypath_histories[i][1], 517 &blurrypath_histories[i][0], 518 sizeof(unsigned int) * 519 (blurrypath_histories[i].size() - 1)); 520 blurrypath_histories[i][0] = z; 521 } 522 } 523 } 524} 525 526bool 527MultiperspectivePerceptronTAGE::lookup(ThreadID tid, Addr instPC, 528 void * &bp_history) 529{ 530 MPPTAGEBranchInfo *bi = 531 new MPPTAGEBranchInfo(instPC, pcshift, true, *tage, *loopPredictor, 532 *statisticalCorrector); 533 bp_history = (void *)bi; 534 bool pred_taken = tage->tagePredict(tid, instPC, true, bi->tageBranchInfo); 535 536 pred_taken = loopPredictor->loopPredict(tid, instPC, true, 537 bi->lpBranchInfo, pred_taken, instShiftAmt); 538 539 bi->scBranchInfo->highConf = tage->isHighConfidence(bi->tageBranchInfo); 540 541 int init_lsum = 22; 542 if (!pred_taken) { 543 init_lsum = -init_lsum; 544 } 545 init_lsum += computePartialSum(tid, *bi); 546 547 pred_taken = statisticalCorrector->scPredict(tid, instPC, true, 548 bi->scBranchInfo, pred_taken, false /* bias_bit: unused */, 549 false /* use_tage_ctr: unused */, 0 /* conf_ctr: unused */, 550 0 /* conf_bits: unused */, 0 /* hitBank: unused */, 551 0 /* altBank: unused */, tage->getPathHist(tid), init_lsum); 552 bi->predictedTaken = pred_taken; 553 bi->lpBranchInfo->predTaken = pred_taken; 554 return pred_taken; 555} 556 557 558void 559MPP_StatisticalCorrector::condBranchUpdate(ThreadID tid, Addr branch_pc, 560 bool taken, StatisticalCorrector::BranchInfo *bi, Addr corrTarget, 561 bool bias_bit, int hitBank, int altBank, int64_t phist) 562{ 563 bool scPred = (bi->lsum >= 0); 564 565 if (bi->predBeforeSC != scPred) { 566 if (abs(bi->lsum) < bi->thres) { 567 if (bi->highConf) { 568 if (abs(bi->lsum) < bi->thres / 3) { 569 ctrUpdate(firstH, (bi->predBeforeSC == taken), 570 chooserConfWidth); 571 } else if (abs(bi->lsum) < 2 * bi->thres / 3) { 572 ctrUpdate(secondH, (bi->predBeforeSC == taken), 573 chooserConfWidth); 574 } else if (abs(bi->lsum) < bi->thres) { 575 ctrUpdate(thirdH, (bi->predBeforeSC == taken), 576 chooserConfWidth); 577 } 578 } 579 } 580 } 581 582 if ((scPred != taken) || ((abs(bi->lsum) < bi->thres))) { 583 584 ctrUpdate(pUpdateThreshold[getIndUpd(branch_pc)], (scPred != taken), 585 pUpdateThresholdWidth + 1); //+1 because the sign is ignored 586 if (pUpdateThreshold[getIndUpd(branch_pc)] < 0) 587 pUpdateThreshold[getIndUpd(branch_pc)] = 0; 588 589 unsigned indBias = getIndBias(branch_pc, bi, false); 590 unsigned indBiasSK = getIndBiasSK(branch_pc, bi); 591 592 ctrUpdate(bias[indBias], taken, scCountersWidth); 593 ctrUpdate(biasSK[indBiasSK], taken, scCountersWidth); 594 595 gUpdates(tid, branch_pc, taken, bi, phist); 596 } 597} 598 599void 600MultiperspectivePerceptronTAGE::update(ThreadID tid, Addr instPC, bool taken, 601 void *bp_history, bool squashed, 602 const StaticInstPtr & inst, 603 Addr corrTarget) 604{ 605 assert(bp_history); 606 MPPTAGEBranchInfo *bi = static_cast<MPPTAGEBranchInfo*>(bp_history); 607 608 assert(corrTarget != MaxAddr); 609 610 if (squashed) { 611 if (tage->isSpeculativeUpdateEnabled()) { 612 // This restores the global history, then update it 613 // and recomputes the folded histories. 614 tage->squash(tid, taken, bi->tageBranchInfo, corrTarget); 615 if (bi->tageBranchInfo->condBranch) { 616 loopPredictor->squashLoop(bi->lpBranchInfo); 617 } 618 } 619 return; 620 } 621 622 if (bi->isUnconditional()) { 623 statisticalCorrector->scHistoryUpdate(instPC, inst, taken, 624 bi->scBranchInfo, corrTarget); 625 tage->updateHistories(tid, instPC, taken, bi->tageBranchInfo, false, 626 inst, corrTarget); 627 } else { 628 tage->updateStats(taken, bi->tageBranchInfo); 629 loopPredictor->updateStats(taken, bi->lpBranchInfo); 630 statisticalCorrector->updateStats(taken, bi->scBranchInfo); 631 632 loopPredictor->condBranchUpdate(tid, instPC, taken, 633 bi->tageBranchInfo->tagePred, bi->lpBranchInfo, instShiftAmt); 634 635 bool scPred = (bi->scBranchInfo->lsum >= 0); 636 if ((scPred != taken) || 637 ((abs(bi->scBranchInfo->lsum) < bi->scBranchInfo->thres))) { 638 updatePartial(tid, *bi, taken); 639 } 640 statisticalCorrector->condBranchUpdate(tid, instPC, taken, 641 bi->scBranchInfo, corrTarget, false /* bias_bit: unused */, 642 0 /* hitBank: unused */, 0 /* altBank: unused*/, 643 tage->getPathHist(tid)); 644 645 tage->condBranchUpdate(tid, instPC, taken, bi->tageBranchInfo, 646 random_mt.random<int>(), corrTarget, 647 bi->predictedTaken, true); 648 649 updateHistories(tid, *bi, taken); 650 651 if (!tage->isSpeculativeUpdateEnabled()) { 652 if (inst->isCondCtrl() && inst->isDirectCtrl() 653 && !inst->isCall() && !inst->isReturn()) { 654 uint32_t truncated_target = corrTarget; 655 uint32_t truncated_pc = instPC; 656 if (truncated_target < truncated_pc) { 657 if (!taken) { 658 threadData[tid]->imli_counter[0] = 0; 659 } else { 660 threadData[tid]->imli_counter[0] += 1; 661 } 662 } else { 663 if (taken) { 664 threadData[tid]->imli_counter[3] = 0; 665 } else { 666 threadData[tid]->imli_counter[3] += 1; 667 } 668 } 669 } 670 671 statisticalCorrector->scHistoryUpdate(instPC, inst, taken, 672 bi->scBranchInfo, corrTarget); 673 674 tage->updateHistories(tid, instPC, taken, bi->tageBranchInfo, 675 false, inst, corrTarget); 676 } 677 } 678 delete bi; 679} 680 681void 682MultiperspectivePerceptronTAGE::uncondBranch(ThreadID tid, Addr pc, 683 void * &bp_history) 684{ 685 MPPTAGEBranchInfo *bi = 686 new MPPTAGEBranchInfo(pc, pcshift, false, *tage, *loopPredictor, 687 *statisticalCorrector); 688 bp_history = (void *) bi; 689} 690 691void 692MultiperspectivePerceptronTAGE::squash(ThreadID tid, void *bp_history) 693{ 694 assert(bp_history); 695 MPPTAGEBranchInfo *bi = static_cast<MPPTAGEBranchInfo*>(bp_history); 696 delete bi; 697} 698