mem_dep_unit_impl.hh revision 10510
18713Sandreas.hansson@arm.com/* 27586SAli.Saidi@arm.com * Copyright (c) 2012, 2014 ARM Limited 37586SAli.Saidi@arm.com * All rights reserved 47586SAli.Saidi@arm.com * 57586SAli.Saidi@arm.com * The license below extends only to copyright in the software and shall 67586SAli.Saidi@arm.com * not be construed as granting a license to any other intellectual 77586SAli.Saidi@arm.com * property including but not limited to intellectual property relating 87586SAli.Saidi@arm.com * to a hardware implementation of the functionality of the software 97586SAli.Saidi@arm.com * licensed hereunder. You may use the software subject to the license 107586SAli.Saidi@arm.com * terms below provided that you ensure that this notice is replicated 117586SAli.Saidi@arm.com * unmodified and in its entirety in all distributions of the software, 127586SAli.Saidi@arm.com * modified or unmodified, in source code or in binary form. 133970Sgblack@eecs.umich.edu * 143005Sstever@eecs.umich.edu * Copyright (c) 2004-2006 The Regents of The University of Michigan 153005Sstever@eecs.umich.edu * All rights reserved. 163005Sstever@eecs.umich.edu * 173005Sstever@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 183005Sstever@eecs.umich.edu * modification, are permitted provided that the following conditions are 193005Sstever@eecs.umich.edu * met: redistributions of source code must retain the above copyright 203005Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 213005Sstever@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 223005Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 233005Sstever@eecs.umich.edu * documentation and/or other materials provided with the distribution; 243005Sstever@eecs.umich.edu * neither the name of the copyright holders nor the names of its 253005Sstever@eecs.umich.edu * contributors may be used to endorse or promote products derived from 263005Sstever@eecs.umich.edu * this software without specific prior written permission. 273005Sstever@eecs.umich.edu * 283005Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 293005Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 303005Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 313005Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 323005Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 333005Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 343005Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 353005Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 363005Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 373005Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 383005Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 393005Sstever@eecs.umich.edu * 403005Sstever@eecs.umich.edu * Authors: Kevin Lim 416654Snate@binkert.org */ 426654Snate@binkert.org 436654Snate@binkert.org#ifndef __CPU_O3_MEM_DEP_UNIT_IMPL_HH__ 442889SN/A#define __CPU_O3_MEM_DEP_UNIT_IMPL_HH__ 452710SN/A 466654Snate@binkert.org#include <map> 476654Snate@binkert.org 486654Snate@binkert.org#include "cpu/o3/inst_queue.hh" 495457Ssaidi@eecs.umich.edu#include "cpu/o3/mem_dep_unit.hh" 506654Snate@binkert.org#include "debug/MemDepUnit.hh" 516654Snate@binkert.org#include "params/DerivO3CPU.hh" 525457Ssaidi@eecs.umich.edu 536654Snate@binkert.orgtemplate <class MemDepPred, class Impl> 546654Snate@binkert.orgMemDepUnit<MemDepPred, Impl>::MemDepUnit() 552934SN/A : loadBarrier(false), loadBarrierSN(0), storeBarrier(false), 562549SN/A storeBarrierSN(0), iqPtr(NULL) 572995SN/A{ 583395Shsul@eecs.umich.edu} 596981SLisa.Hsu@amd.com 603448Shsul@eecs.umich.edutemplate <class MemDepPred, class Impl> 612549SN/AMemDepUnit<MemDepPred, Impl>::MemDepUnit(DerivO3CPUParams *params) 623444Sktlim@umich.edu : _name(params->name + ".memdepunit"), 633444Sktlim@umich.edu depPred(params->store_set_clear_period, params->SSITSize, 643444Sktlim@umich.edu params->LFSTSize), 653444Sktlim@umich.edu loadBarrier(false), loadBarrierSN(0), storeBarrier(false), 662889SN/A storeBarrierSN(0), iqPtr(NULL) 672710SN/A{ 687861Sgblack@eecs.umich.edu DPRINTF(MemDepUnit, "Creating MemDepUnit object.\n"); 697861Sgblack@eecs.umich.edu} 707861Sgblack@eecs.umich.edu 717861Sgblack@eecs.umich.edutemplate <class MemDepPred, class Impl> 723873Sbinkertn@umich.eduMemDepUnit<MemDepPred, Impl>::~MemDepUnit() 733873Sbinkertn@umich.edu{ 743873Sbinkertn@umich.edu for (ThreadID tid = 0; tid < Impl::MaxThreads; tid++) { 758635Schris.emmons@arm.com 768635Schris.emmons@arm.com ListIt inst_list_it = instList[tid].begin(); 778635Schris.emmons@arm.com 788635Schris.emmons@arm.com MemDepHashIt hash_it; 797586SAli.Saidi@arm.com 807586SAli.Saidi@arm.com while (!instList[tid].empty()) { 817586SAli.Saidi@arm.com hash_it = memDepHash.find((*inst_list_it)->seqNum); 827586SAli.Saidi@arm.com 837586SAli.Saidi@arm.com assert(hash_it != memDepHash.end()); 843322Shsul@eecs.umich.edu 852995SN/A memDepHash.erase(hash_it); 862995SN/A 872995SN/A instList[tid].erase(inst_list_it++); 882995SN/A } 892995SN/A } 903143Shsul@eecs.umich.edu 913322Shsul@eecs.umich.edu#ifdef DEBUG 923322Shsul@eecs.umich.edu assert(MemDepEntry::memdep_count == 0); 933025Ssaidi@eecs.umich.edu#endif 943143Shsul@eecs.umich.edu} 953143Shsul@eecs.umich.edu 963322Shsul@eecs.umich.edutemplate <class MemDepPred, class Impl> 973444Sktlim@umich.eduvoid 983322Shsul@eecs.umich.eduMemDepUnit<MemDepPred, Impl>::init(DerivO3CPUParams *params, ThreadID tid) 992710SN/A{ 1002710SN/A DPRINTF(MemDepUnit, "Creating MemDepUnit %i object.\n",tid); 1012710SN/A 1022710SN/A _name = csprintf("%s.memDep%d", params->name, tid); 1032710SN/A id = tid; 1042710SN/A 1053322Shsul@eecs.umich.edu depPred.init(params->store_set_clear_period, params->SSITSize, 1063304Sstever@eecs.umich.edu params->LFSTSize); 1073322Shsul@eecs.umich.edu} 1083322Shsul@eecs.umich.edu 1093304Sstever@eecs.umich.edutemplate <class MemDepPred, class Impl> 1103481Shsul@eecs.umich.eduvoid 1113481Shsul@eecs.umich.eduMemDepUnit<MemDepPred, Impl>::regStats() 1122566SN/A{ 1133322Shsul@eecs.umich.edu insertedLoads 1143322Shsul@eecs.umich.edu .name(name() + ".insertedLoads") 1152995SN/A .desc("Number of loads inserted to the mem dependence unit."); 1162995SN/A 1173304Sstever@eecs.umich.edu insertedStores 1183304Sstever@eecs.umich.edu .name(name() + ".insertedStores") 1193304Sstever@eecs.umich.edu .desc("Number of stores inserted to the mem dependence unit."); 1202995SN/A 1212995SN/A conflictingLoads 1222995SN/A .name(name() + ".conflictingLoads") 1232917SN/A .desc("Number of conflicting loads."); 1242995SN/A 1253304Sstever@eecs.umich.edu conflictingStores 1262995SN/A .name(name() + ".conflictingStores") 1273304Sstever@eecs.umich.edu .desc("Number of conflicting stores."); 1283304Sstever@eecs.umich.edu} 1296135Sgblack@eecs.umich.edu 1306135Sgblack@eecs.umich.edutemplate <class MemDepPred, class Impl> 1316654Snate@binkert.orgbool 1323819Shsul@eecs.umich.eduMemDepUnit<MemDepPred, Impl>::isDrained() const 1336654Snate@binkert.org{ 1345222Sksewell@umich.edu bool drained = instsToReplay.empty() 1356654Snate@binkert.org && memDepHash.empty() 1363819Shsul@eecs.umich.edu && instsToReplay.empty(); 1376654Snate@binkert.org for (int i = 0; i < Impl::MaxThreads; ++i) 1387925Sgblack@eecs.umich.edu drained = drained && instList[i].empty(); 1397925Sgblack@eecs.umich.edu 1407586SAli.Saidi@arm.com return drained; 1418061SAli.Saidi@ARM.com} 1428061SAli.Saidi@ARM.com 1438061SAli.Saidi@ARM.comtemplate <class MemDepPred, class Impl> 1448354Sgedare@gwmail.gwu.eduvoid 1453819Shsul@eecs.umich.eduMemDepUnit<MemDepPred, Impl>::drainSanityCheck() const 1466654Snate@binkert.org{ 1473819Shsul@eecs.umich.edu assert(instsToReplay.empty()); 1483873Sbinkertn@umich.edu assert(memDepHash.empty()); 1493873Sbinkertn@umich.edu for (int i = 0; i < Impl::MaxThreads; ++i) 1503873Sbinkertn@umich.edu assert(instList[i].empty()); 1513873Sbinkertn@umich.edu assert(instsToReplay.empty()); 1523873Sbinkertn@umich.edu assert(memDepHash.empty()); 1533873Sbinkertn@umich.edu} 1548659SAli.Saidi@ARM.com 1558659SAli.Saidi@ARM.comtemplate <class MemDepPred, class Impl> 1566995Sgblack@eecs.umich.eduvoid 1573668Srdreslin@umich.eduMemDepUnit<MemDepPred, Impl>::takeOverFrom() 1586995Sgblack@eecs.umich.edu{ 1595142Ssaidi@eecs.umich.edu // Be sure to reset all state. 1608713Sandreas.hansson@arm.com loadBarrier = storeBarrier = false; 1618713Sandreas.hansson@arm.com loadBarrierSN = storeBarrierSN = 0; 1628713Sandreas.hansson@arm.com depPred.clear(); 1638713Sandreas.hansson@arm.com} 1646636Ssteve.reinhardt@amd.com 1657586SAli.Saidi@arm.comtemplate <class MemDepPred, class Impl> 1665142Ssaidi@eecs.umich.eduvoid 1675142Ssaidi@eecs.umich.eduMemDepUnit<MemDepPred, Impl>::setIQ(InstructionQueue<Impl> *iq_ptr) 1688713Sandreas.hansson@arm.com{ 1698713Sandreas.hansson@arm.com iqPtr = iq_ptr; 1708723Sandreas.hansson@arm.com} 1718713Sandreas.hansson@arm.com 1728713Sandreas.hansson@arm.comtemplate <class MemDepPred, class Impl> 1735142Ssaidi@eecs.umich.eduvoid 1743312Sstever@eecs.umich.eduMemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst) 1754968Sacolyte@umich.edu{ 1764968Sacolyte@umich.edu ThreadID tid = inst->threadNumber; 1774968Sacolyte@umich.edu 1786654Snate@binkert.org MemDepEntryPtr inst_entry = std::make_shared<MemDepEntry>(inst); 1795254Sksewell@umich.edu 1805222Sksewell@umich.edu // Add the MemDepEntry to the hash. 1813005Sstever@eecs.umich.edu memDepHash.insert( 1826654Snate@binkert.org std::pair<InstSeqNum, MemDepEntryPtr>(inst->seqNum, inst_entry)); 1833819Shsul@eecs.umich.edu#ifdef DEBUG 1846654Snate@binkert.org MemDepEntry::memdep_insert++; 1855222Sksewell@umich.edu#endif 1866654Snate@binkert.org 1873819Shsul@eecs.umich.edu instList[tid].push_back(inst); 1886654Snate@binkert.org 1896135Sgblack@eecs.umich.edu inst_entry->listIt = --(instList[tid].end()); 1907586SAli.Saidi@arm.com 1918661SAli.Saidi@ARM.com // Check any barriers and the dependence predictor for any 1928661SAli.Saidi@ARM.com // producing memrefs/stores. 1933322Shsul@eecs.umich.edu InstSeqNum producing_store; 1947876Sgblack@eecs.umich.edu if (inst->isLoad() && loadBarrier) { 1954968Sacolyte@umich.edu DPRINTF(MemDepUnit, "Load barrier [sn:%lli] in flight\n", 1964968Sacolyte@umich.edu loadBarrierSN); 1974837Ssaidi@eecs.umich.edu producing_store = loadBarrierSN; 1984837Ssaidi@eecs.umich.edu } else if (inst->isStore() && storeBarrier) { 1994837Ssaidi@eecs.umich.edu DPRINTF(MemDepUnit, "Store barrier [sn:%lli] in flight\n", 2008659SAli.Saidi@ARM.com storeBarrierSN); 2018801Sgblack@eecs.umich.edu producing_store = storeBarrierSN; 2023005Sstever@eecs.umich.edu } else { 2038801Sgblack@eecs.umich.edu producing_store = depPred.checkInst(inst->instAddr()); 2043005Sstever@eecs.umich.edu } 2053005Sstever@eecs.umich.edu 2063005Sstever@eecs.umich.edu MemDepEntryPtr store_entry = NULL; 2072566SN/A 2087861Sgblack@eecs.umich.edu // If there is a producing store, try to find the entry. 2097861Sgblack@eecs.umich.edu if (producing_store != 0) { 2107861Sgblack@eecs.umich.edu DPRINTF(MemDepUnit, "Searching for producer\n"); 2118635Schris.emmons@arm.com MemDepHashIt hash_it = memDepHash.find(producing_store); 2128635Schris.emmons@arm.com 2138635Schris.emmons@arm.com if (hash_it != memDepHash.end()) { 2143481Shsul@eecs.umich.edu store_entry = (*hash_it).second; 215 DPRINTF(MemDepUnit, "Proucer found\n"); 216 } 217 } 218 219 // If no store entry, then instruction can issue as soon as the registers 220 // are ready. 221 if (!store_entry) { 222 DPRINTF(MemDepUnit, "No dependency for inst PC " 223 "%s [sn:%lli].\n", inst->pcState(), inst->seqNum); 224 225 inst_entry->memDepReady = true; 226 227 if (inst->readyToIssue()) { 228 inst_entry->regsReady = true; 229 230 moveToReady(inst_entry); 231 } 232 } else { 233 // Otherwise make the instruction dependent on the store/barrier. 234 DPRINTF(MemDepUnit, "Adding to dependency list; " 235 "inst PC %s is dependent on [sn:%lli].\n", 236 inst->pcState(), producing_store); 237 238 if (inst->readyToIssue()) { 239 inst_entry->regsReady = true; 240 } 241 242 // Clear the bit saying this instruction can issue. 243 inst->clearCanIssue(); 244 245 // Add this instruction to the list of dependents. 246 store_entry->dependInsts.push_back(inst_entry); 247 248 if (inst->isLoad()) { 249 ++conflictingLoads; 250 } else { 251 ++conflictingStores; 252 } 253 } 254 255 if (inst->isStore()) { 256 DPRINTF(MemDepUnit, "Inserting store PC %s [sn:%lli].\n", 257 inst->pcState(), inst->seqNum); 258 259 depPred.insertStore(inst->instAddr(), inst->seqNum, inst->threadNumber); 260 261 ++insertedStores; 262 } else if (inst->isLoad()) { 263 ++insertedLoads; 264 } else { 265 panic("Unknown type! (most likely a barrier)."); 266 } 267} 268 269template <class MemDepPred, class Impl> 270void 271MemDepUnit<MemDepPred, Impl>::insertNonSpec(DynInstPtr &inst) 272{ 273 ThreadID tid = inst->threadNumber; 274 275 MemDepEntryPtr inst_entry = std::make_shared<MemDepEntry>(inst); 276 277 // Insert the MemDepEntry into the hash. 278 memDepHash.insert( 279 std::pair<InstSeqNum, MemDepEntryPtr>(inst->seqNum, inst_entry)); 280#ifdef DEBUG 281 MemDepEntry::memdep_insert++; 282#endif 283 284 // Add the instruction to the list. 285 instList[tid].push_back(inst); 286 287 inst_entry->listIt = --(instList[tid].end()); 288 289 // Might want to turn this part into an inline function or something. 290 // It's shared between both insert functions. 291 if (inst->isStore()) { 292 DPRINTF(MemDepUnit, "Inserting store PC %s [sn:%lli].\n", 293 inst->pcState(), inst->seqNum); 294 295 depPred.insertStore(inst->instAddr(), inst->seqNum, inst->threadNumber); 296 297 ++insertedStores; 298 } else if (inst->isLoad()) { 299 ++insertedLoads; 300 } else { 301 panic("Unknown type! (most likely a barrier)."); 302 } 303} 304 305template <class MemDepPred, class Impl> 306void 307MemDepUnit<MemDepPred, Impl>::insertBarrier(DynInstPtr &barr_inst) 308{ 309 InstSeqNum barr_sn = barr_inst->seqNum; 310 // Memory barriers block loads and stores, write barriers only stores. 311 if (barr_inst->isMemBarrier()) { 312 loadBarrier = true; 313 loadBarrierSN = barr_sn; 314 storeBarrier = true; 315 storeBarrierSN = barr_sn; 316 DPRINTF(MemDepUnit, "Inserted a memory barrier %s SN:%lli\n", 317 barr_inst->pcState(),barr_sn); 318 } else if (barr_inst->isWriteBarrier()) { 319 storeBarrier = true; 320 storeBarrierSN = barr_sn; 321 DPRINTF(MemDepUnit, "Inserted a write barrier\n"); 322 } 323 324 ThreadID tid = barr_inst->threadNumber; 325 326 MemDepEntryPtr inst_entry = std::make_shared<MemDepEntry>(barr_inst); 327 328 // Add the MemDepEntry to the hash. 329 memDepHash.insert( 330 std::pair<InstSeqNum, MemDepEntryPtr>(barr_sn, inst_entry)); 331#ifdef DEBUG 332 MemDepEntry::memdep_insert++; 333#endif 334 335 // Add the instruction to the instruction list. 336 instList[tid].push_back(barr_inst); 337 338 inst_entry->listIt = --(instList[tid].end()); 339} 340 341template <class MemDepPred, class Impl> 342void 343MemDepUnit<MemDepPred, Impl>::regsReady(DynInstPtr &inst) 344{ 345 DPRINTF(MemDepUnit, "Marking registers as ready for " 346 "instruction PC %s [sn:%lli].\n", 347 inst->pcState(), inst->seqNum); 348 349 MemDepEntryPtr inst_entry = findInHash(inst); 350 351 inst_entry->regsReady = true; 352 353 if (inst_entry->memDepReady) { 354 DPRINTF(MemDepUnit, "Instruction has its memory " 355 "dependencies resolved, adding it to the ready list.\n"); 356 357 moveToReady(inst_entry); 358 } else { 359 DPRINTF(MemDepUnit, "Instruction still waiting on " 360 "memory dependency.\n"); 361 } 362} 363 364template <class MemDepPred, class Impl> 365void 366MemDepUnit<MemDepPred, Impl>::nonSpecInstReady(DynInstPtr &inst) 367{ 368 DPRINTF(MemDepUnit, "Marking non speculative " 369 "instruction PC %s as ready [sn:%lli].\n", 370 inst->pcState(), inst->seqNum); 371 372 MemDepEntryPtr inst_entry = findInHash(inst); 373 374 moveToReady(inst_entry); 375} 376 377template <class MemDepPred, class Impl> 378void 379MemDepUnit<MemDepPred, Impl>::reschedule(DynInstPtr &inst) 380{ 381 instsToReplay.push_back(inst); 382} 383 384template <class MemDepPred, class Impl> 385void 386MemDepUnit<MemDepPred, Impl>::replay() 387{ 388 DynInstPtr temp_inst; 389 390 // For now this replay function replays all waiting memory ops. 391 while (!instsToReplay.empty()) { 392 temp_inst = instsToReplay.front(); 393 394 MemDepEntryPtr inst_entry = findInHash(temp_inst); 395 396 DPRINTF(MemDepUnit, "Replaying mem instruction PC %s [sn:%lli].\n", 397 temp_inst->pcState(), temp_inst->seqNum); 398 399 moveToReady(inst_entry); 400 401 instsToReplay.pop_front(); 402 } 403} 404 405template <class MemDepPred, class Impl> 406void 407MemDepUnit<MemDepPred, Impl>::completed(DynInstPtr &inst) 408{ 409 DPRINTF(MemDepUnit, "Completed mem instruction PC %s [sn:%lli].\n", 410 inst->pcState(), inst->seqNum); 411 412 ThreadID tid = inst->threadNumber; 413 414 // Remove the instruction from the hash and the list. 415 MemDepHashIt hash_it = memDepHash.find(inst->seqNum); 416 417 assert(hash_it != memDepHash.end()); 418 419 instList[tid].erase((*hash_it).second->listIt); 420 421 (*hash_it).second = NULL; 422 423 memDepHash.erase(hash_it); 424#ifdef DEBUG 425 MemDepEntry::memdep_erase++; 426#endif 427} 428 429template <class MemDepPred, class Impl> 430void 431MemDepUnit<MemDepPred, Impl>::completeBarrier(DynInstPtr &inst) 432{ 433 wakeDependents(inst); 434 completed(inst); 435 436 InstSeqNum barr_sn = inst->seqNum; 437 DPRINTF(MemDepUnit, "barrier completed: %s SN:%lli\n", inst->pcState(), 438 inst->seqNum); 439 if (inst->isMemBarrier()) { 440 if (loadBarrierSN == barr_sn) 441 loadBarrier = false; 442 if (storeBarrierSN == barr_sn) 443 storeBarrier = false; 444 } else if (inst->isWriteBarrier()) { 445 if (storeBarrierSN == barr_sn) 446 storeBarrier = false; 447 } 448} 449 450template <class MemDepPred, class Impl> 451void 452MemDepUnit<MemDepPred, Impl>::wakeDependents(DynInstPtr &inst) 453{ 454 // Only stores and barriers have dependents. 455 if (!inst->isStore() && !inst->isMemBarrier() && !inst->isWriteBarrier()) { 456 return; 457 } 458 459 MemDepEntryPtr inst_entry = findInHash(inst); 460 461 for (int i = 0; i < inst_entry->dependInsts.size(); ++i ) { 462 MemDepEntryPtr woken_inst = inst_entry->dependInsts[i]; 463 464 if (!woken_inst->inst) { 465 // Potentially removed mem dep entries could be on this list 466 continue; 467 } 468 469 DPRINTF(MemDepUnit, "Waking up a dependent inst, " 470 "[sn:%lli].\n", 471 woken_inst->inst->seqNum); 472 473 if (woken_inst->regsReady && !woken_inst->squashed) { 474 moveToReady(woken_inst); 475 } else { 476 woken_inst->memDepReady = true; 477 } 478 } 479 480 inst_entry->dependInsts.clear(); 481} 482 483template <class MemDepPred, class Impl> 484void 485MemDepUnit<MemDepPred, Impl>::squash(const InstSeqNum &squashed_num, 486 ThreadID tid) 487{ 488 if (!instsToReplay.empty()) { 489 ListIt replay_it = instsToReplay.begin(); 490 while (replay_it != instsToReplay.end()) { 491 if ((*replay_it)->threadNumber == tid && 492 (*replay_it)->seqNum > squashed_num) { 493 instsToReplay.erase(replay_it++); 494 } else { 495 ++replay_it; 496 } 497 } 498 } 499 500 ListIt squash_it = instList[tid].end(); 501 --squash_it; 502 503 MemDepHashIt hash_it; 504 505 while (!instList[tid].empty() && 506 (*squash_it)->seqNum > squashed_num) { 507 508 DPRINTF(MemDepUnit, "Squashing inst [sn:%lli]\n", 509 (*squash_it)->seqNum); 510 511 if ((*squash_it)->seqNum == loadBarrierSN) 512 loadBarrier = false; 513 514 if ((*squash_it)->seqNum == storeBarrierSN) 515 storeBarrier = false; 516 517 hash_it = memDepHash.find((*squash_it)->seqNum); 518 519 assert(hash_it != memDepHash.end()); 520 521 (*hash_it).second->squashed = true; 522 523 (*hash_it).second = NULL; 524 525 memDepHash.erase(hash_it); 526#ifdef DEBUG 527 MemDepEntry::memdep_erase++; 528#endif 529 530 instList[tid].erase(squash_it--); 531 } 532 533 // Tell the dependency predictor to squash as well. 534 depPred.squash(squashed_num, tid); 535} 536 537template <class MemDepPred, class Impl> 538void 539MemDepUnit<MemDepPred, Impl>::violation(DynInstPtr &store_inst, 540 DynInstPtr &violating_load) 541{ 542 DPRINTF(MemDepUnit, "Passing violating PCs to store sets," 543 " load: %#x, store: %#x\n", violating_load->instAddr(), 544 store_inst->instAddr()); 545 // Tell the memory dependence unit of the violation. 546 depPred.violation(store_inst->instAddr(), violating_load->instAddr()); 547} 548 549template <class MemDepPred, class Impl> 550void 551MemDepUnit<MemDepPred, Impl>::issue(DynInstPtr &inst) 552{ 553 DPRINTF(MemDepUnit, "Issuing instruction PC %#x [sn:%lli].\n", 554 inst->instAddr(), inst->seqNum); 555 556 depPred.issued(inst->instAddr(), inst->seqNum, inst->isStore()); 557} 558 559template <class MemDepPred, class Impl> 560inline typename MemDepUnit<MemDepPred,Impl>::MemDepEntryPtr & 561MemDepUnit<MemDepPred, Impl>::findInHash(const DynInstPtr &inst) 562{ 563 MemDepHashIt hash_it = memDepHash.find(inst->seqNum); 564 565 assert(hash_it != memDepHash.end()); 566 567 return (*hash_it).second; 568} 569 570template <class MemDepPred, class Impl> 571inline void 572MemDepUnit<MemDepPred, Impl>::moveToReady(MemDepEntryPtr &woken_inst_entry) 573{ 574 DPRINTF(MemDepUnit, "Adding instruction [sn:%lli] " 575 "to the ready list.\n", woken_inst_entry->inst->seqNum); 576 577 assert(!woken_inst_entry->squashed); 578 579 iqPtr->addReadyMemInst(woken_inst_entry->inst); 580} 581 582 583template <class MemDepPred, class Impl> 584void 585MemDepUnit<MemDepPred, Impl>::dumpLists() 586{ 587 for (ThreadID tid = 0; tid < Impl::MaxThreads; tid++) { 588 cprintf("Instruction list %i size: %i\n", 589 tid, instList[tid].size()); 590 591 ListIt inst_list_it = instList[tid].begin(); 592 int num = 0; 593 594 while (inst_list_it != instList[tid].end()) { 595 cprintf("Instruction:%i\nPC: %s\n[sn:%i]\n[tid:%i]\nIssued:%i\n" 596 "Squashed:%i\n\n", 597 num, (*inst_list_it)->pcState(), 598 (*inst_list_it)->seqNum, 599 (*inst_list_it)->threadNumber, 600 (*inst_list_it)->isIssued(), 601 (*inst_list_it)->isSquashed()); 602 inst_list_it++; 603 ++num; 604 } 605 } 606 607 cprintf("Memory dependence hash size: %i\n", memDepHash.size()); 608 609#ifdef DEBUG 610 cprintf("Memory dependence entries: %i\n", MemDepEntry::memdep_count); 611#endif 612} 613 614#endif//__CPU_O3_MEM_DEP_UNIT_IMPL_HH__ 615