59#include "debug/Activity.hh"
60#include "debug/Commit.hh"
61#include "debug/CommitRate.hh"
62#include "debug/Drain.hh"
63#include "debug/ExecFaulting.hh"
64#include "debug/HtmCpu.hh"
65#include "params/BaseO3CPU.hh"
101 fatal(
"commitWidth (%d) is larger than compiled limit (%d),\n"
102 "\tincrease MaxWidth in src/cpu/o3/limits.hh\n",
121 pc[tid].reset(params.isa[0]->newPCState());
140 cpu->getProbeManager(),
"Commit");
142 cpu->getProbeManager(),
"CommitStall");
144 cpu->getProbeManager(),
"Squash");
150 "The number of squashed insts skipped by commit"),
152 "The number of times commit has been forced to stall to "
153 "communicate backwards"),
155 "The number of times a branch was mispredicted"),
157 "Number of insts commited each cycle"),
159 "Number of atomic instructions committed"),
161 "Number of memory barriers committed"),
163 "Class of committed instruction"),
165 "number cycles where commit BW limit reached")
174 .init(0,
commit->commitWidth,1)
178 .init(
cpu->numThreads)
182 .init(
cpu->numThreads)
186 .init(
commit->numThreads,enums::Num_OpClass)
266 toIEW->commitInfo[tid].usedROB =
true;
267 toIEW->commitInfo[tid].freeROBEntries =
rob->numFreeEntries(tid);
268 toIEW->commitInfo[tid].emptyROB =
true;
275 cpu->activityThisCycle();
288 pc[tid].reset(
cpu->tcBase(tid)->getIsaPtr()->newPCState());
295 cpu->timeBuffer[
i].commitInfo[tid] = {};
312 rob->drainSanityCheck();
318 panic(
"cannot drain partially through a HTM transaction");
336 if (
pc[tid]->microPC() != 0)
346 return rob->isEmpty() &&
368 auto thread_it = std::find(
411 DPRINTF(Activity,
"Deactivating stage.\n");
414 DPRINTF(Activity,
"Activating stage.\n");
436 return rob->numFreeEntries(tid);
442 DPRINTF(
Commit,
"Generating trap event for [tid:%i]\n", tid);
448 Cycles latency = std::dynamic_pointer_cast<SyscallRetryFault>(inst_fault) ?
452 if (inst_fault !=
nullptr &&
453 std::dynamic_pointer_cast<GenericHtmFailureFault>(inst_fault)) {
459 cpu->schedule(trap,
cpu->clockEdge(latency));
461 thread[tid]->trapPending =
true;
462 toIEW->commitInfo[tid].trapPending =
true;
469 DPRINTF(
Commit,
"Generating TC squash event for [tid:%i]\n", tid);
489 rob->squash(squashed_inst, tid);
493 toIEW->commitInfo[tid].doneSeqNum = squashed_inst;
497 toIEW->commitInfo[tid].squash =
true;
501 toIEW->commitInfo[tid].robSquashing =
true;
503 toIEW->commitInfo[tid].mispredictInst = NULL;
504 toIEW->commitInfo[tid].squashInst = NULL;
514 DPRINTF(
Commit,
"Squashing from trap, restarting at PC %s\n", *
pc[tid]);
516 thread[tid]->trapPending =
false;
517 thread[tid]->noSquashFromTC =
false;
519 toIEW->commitInfo[tid].trapPending =
false;
524 cpu->activityThisCycle();
534 thread[tid]->noSquashFromTC =
false;
535 assert(!
thread[tid]->trapPending);
538 cpu->activityThisCycle();
547 "restarting at PC %s\n", *
pc[tid]);
557 cpu->activityThisCycle();
563 DPRINTF(
Commit,
"Executing squash after for [tid:%i] inst [sn:%llu]\n",
564 tid, head_inst->seqNum);
589 if (
rob->isDoneSquashing(tid)) {
593 " insts this cycle.\n", tid);
595 toIEW->commitInfo[tid].robSquashing =
true;
606 if (!
rob->isEmpty(tid) &&
rob->readHeadInst(tid)->readyToCommit()) {
611 [[maybe_unused]]
const DynInstPtr &inst =
rob->readHeadInst(tid);
613 DPRINTF(
Commit,
"[tid:%i] Instruction [sn:%llu] PC %s is head of"
614 " ROB and ready to commit\n",
615 tid, inst->seqNum, inst->pcState());
617 }
else if (!
rob->isEmpty(tid)) {
622 DPRINTF(
Commit,
"[tid:%i] Can't commit, Instruction [sn:%llu] PC "
623 "%s is head of ROB and not ready\n",
624 tid, inst->seqNum, inst->pcState());
627 DPRINTF(
Commit,
"[tid:%i] ROB has %d insts & %d free entries.\n",
628 tid,
rob->countInsts(tid),
rob->numFreeEntries(tid));
633 DPRINTF(Activity,
"Activity This Cycle.\n");
634 cpu->activityThisCycle();
644 if (!
cpu->checkInterrupts(0)) {
645 DPRINTF(
Commit,
"Pending interrupt is cleared by requestor before "
646 "it got handled. Restart fetching from the orig path.\n");
647 toIEW->commitInfo[0].clearInterrupt =
true;
661 toIEW->commitInfo[0].clearInterrupt =
true;
663 assert(!
thread[0]->noSquashFromTC);
664 thread[0]->noSquashFromTC =
true;
667 cpu->checker->handlePendingInt();
673 cpu->processInterrupts(
cpu->getInterrupts());
675 thread[0]->noSquashFromTC =
false;
687 "flight, ROB is %sempty\n",
689 cpu->instList.empty() ?
"" :
"not " );
714 toIEW->commitInfo[0].interruptPending =
true;
722 if (
cpu->checkInterrupts(0))
730 int num_squashing_threads = 0;
742 if (
cpu->isThreadExiting(tid))
743 cpu->scheduleThreadExitEvent(tid);
761 if (
fromIEW->mispredictInst[tid]) {
763 "[tid:%i] Squashing due to branch mispred "
764 "PC:%#x [sn:%llu]\n",
766 fromIEW->mispredictInst[tid]->pcState().instAddr(),
770 "[tid:%i] Squashing due to order violation [sn:%llu]\n",
771 tid,
fromIEW->squashedSeqNum[tid]);
783 if (
fromIEW->includeSquashInst[tid]) {
791 rob->squash(squashed_inst, tid);
794 toIEW->commitInfo[tid].doneSeqNum = squashed_inst;
796 toIEW->commitInfo[tid].squash =
true;
800 toIEW->commitInfo[tid].robSquashing =
true;
802 toIEW->commitInfo[tid].mispredictInst =
804 toIEW->commitInfo[tid].branchTaken =
806 toIEW->commitInfo[tid].squashInst =
807 rob->findInst(tid, squashed_inst);
808 if (
toIEW->commitInfo[tid].mispredictInst) {
809 if (
toIEW->commitInfo[tid].mispredictInst->isUncondCtrl()) {
810 toIEW->commitInfo[tid].branchTaken =
true;
812 ++
stats.branchMispredicts;
819 num_squashing_threads++;
825 if (num_squashing_threads) {
840 toIEW->commitInfo[tid].usedROB =
true;
841 toIEW->commitInfo[tid].freeROBEntries =
rob->numFreeEntries(tid);
845 if (
rob->isEmpty(tid))
860 toIEW->commitInfo[tid].usedROB =
true;
861 toIEW->commitInfo[tid].emptyROB =
true;
862 toIEW->commitInfo[tid].freeROBEntries =
rob->numFreeEntries(tid);
881 DPRINTF(
Commit,
"Trying to commit instructions in the ROB.\n");
883 unsigned num_committed = 0;
901 cpu->clearInterrupts(0);
902 toIEW->commitInfo[0].clearInterrupt =
true;
912 if (commit_thread == -1 || !
rob->isHeadReady(commit_thread))
915 head_inst =
rob->readHeadInst(commit_thread);
917 ThreadID tid = head_inst->threadNumber;
919 assert(tid == commit_thread);
922 "Trying to commit head instruction, [tid:%i] [sn:%llu]\n",
923 tid, head_inst->seqNum);
927 if (head_inst->isSquashed()) {
932 rob->retireHead(commit_thread);
934 ++
stats.commitSquashedInsts;
943 }
else if (head_inst->noCapableFU() &&
944 head_inst->getFault() ==
NoFault) {
945 panic(
"CPU cannot execute [sn:%llu] op_class: %s but"
946 " did not trigger a fault. Do you need to update"
947 " the configuration and add a functional unit for"
950 enums::OpClassStrings[head_inst->opClass()]);
952 set(
pc[tid], head_inst->pcState());
955 bool commit_success =
commitHead(head_inst, num_committed);
957 if (commit_success) {
959 cpu->commitStats[tid]
960 ->committedInstType[head_inst->opClass()]++;
961 stats.committedInstType[tid][head_inst->opClass()]++;
967 if (head_inst->isHtmStart())
971 if (head_inst->inHtmTransactionalState()) {
978 if (head_inst->isHtmStop())
984 toIEW->commitInfo[tid].doneSeqNum = head_inst->seqNum;
991 assert(!head_inst->isStoreConditional() ||
992 head_inst->isCompleted() ||
993 !head_inst->readPredicate());
996 head_inst->updateMiscRegs();
1001 cpu->checker->verify(head_inst);
1004 cpu->traceFunctions(
pc[tid]->instAddr());
1006 head_inst->staticInst->advancePC(*
pc[tid]);
1013 if (head_inst->isSquashAfter())
1018 !
thread[tid]->trapPending) {
1022 DPRINTF(Drain,
"Draining: %i:%s\n", tid, *
pc[tid]);
1024 cpu->commitDrained(tid);
1029 bool onInstBoundary = !head_inst->isMicroop() ||
1030 head_inst->isLastMicroop() ||
1031 !head_inst->isDelayedCommit();
1033 if (onInstBoundary) {
1038 assert(!
thread[tid]->noSquashFromTC &&
1039 !
thread[tid]->trapPending);
1041 oldpc =
pc[tid]->instAddr();
1042 thread[tid]->pcEventQueue.service(
1043 oldpc,
thread[tid]->getTC());
1045 }
while (oldpc !=
pc[tid]->instAddr());
1048 "PC skip function event, stopping commit\n");
1062 onInstBoundary &&
cpu->checkInterrupts(0))
1066 "[tid:%i] [sn:%llu].\n",
1067 head_inst->pcState(), tid ,head_inst->seqNum);
1073 DPRINTF(CommitRate,
"%i\n", num_committed);
1074 stats.numCommittedDist.sample(num_committed);
1077 stats.commitEligibleSamples++;
1086 ThreadID tid = head_inst->threadNumber;
1090 if (!head_inst->isExecuted()) {
1093 assert(head_inst->isNonSpeculative() || head_inst->isStoreConditional()
1094 || head_inst->isReadBarrier() || head_inst->isWriteBarrier()
1095 || head_inst->isAtomic()
1096 || (head_inst->isLoad() && head_inst->strictlyOrdered()));
1099 "Encountered a barrier or non-speculative "
1100 "instruction [tid:%i] [sn:%llu] "
1101 "at the head of the ROB, PC %s.\n",
1102 tid, head_inst->seqNum, head_inst->pcState());
1104 if (inst_num > 0 ||
iewStage->hasStoresToWB(tid)) {
1106 "[tid:%i] [sn:%llu] "
1107 "Waiting for all stores to writeback.\n",
1108 tid, head_inst->seqNum);
1112 toIEW->commitInfo[tid].nonSpecSeqNum = head_inst->seqNum;
1116 head_inst->clearCanCommit();
1118 if (head_inst->isLoad() && head_inst->strictlyOrdered()) {
1120 "Strictly ordered load, PC %s.\n",
1121 tid, head_inst->seqNum, head_inst->pcState());
1122 toIEW->commitInfo[tid].strictlyOrdered =
true;
1123 toIEW->commitInfo[tid].strictlyOrderedLoad = head_inst;
1125 ++
stats.commitNonSpecStalls;
1132 Fault inst_fault = head_inst->getFault();
1137 if (inst_fault !=
NoFault && head_inst->inHtmTransactionalState()) {
1139 if (!std::dynamic_pointer_cast<GenericHtmFailureFault>(inst_fault)) {
1140 DPRINTF(HtmCpu,
"%s - fault (%s) encountered within transaction"
1141 " - converting to GenericHtmFailureFault\n",
1142 head_inst->staticInst->getName(), inst_fault->name());
1143 inst_fault = std::make_shared<GenericHtmFailureFault>(
1144 head_inst->getHtmTransactionUid(),
1152 if (!head_inst->isStore() && inst_fault ==
NoFault) {
1153 head_inst->setCompleted();
1157 DPRINTF(
Commit,
"Inst [tid:%i] [sn:%llu] PC %s has a fault\n",
1158 tid, head_inst->seqNum, head_inst->pcState());
1160 if (
iewStage->hasStoresToWB(tid) || inst_num > 0) {
1162 "[tid:%i] [sn:%llu] "
1163 "Stores outstanding, fault must wait.\n",
1164 tid, head_inst->seqNum);
1168 head_inst->setCompleted();
1174 cpu->checker->verify(head_inst);
1177 assert(!
thread[tid]->noSquashFromTC);
1181 thread[tid]->noSquashFromTC =
true;
1189 cpu->trap(inst_fault, tid,
1191 head_inst->staticInst);
1194 thread[tid]->noSquashFromTC =
false;
1199 "[tid:%i] [sn:%llu] Committing instruction with fault\n",
1200 tid, head_inst->seqNum);
1201 if (head_inst->traceData) {
1204 if (debug::ExecFaulting
1205 &&
dynamic_cast<ReExec*
>(inst_fault.get()) ==
nullptr) {
1207 head_inst->traceData->setFaulting(
true);
1208 head_inst->traceData->setFetchSeq(head_inst->seqNum);
1209 head_inst->traceData->setCPSeq(
thread[tid]->numOp);
1210 head_inst->traceData->dump();
1212 delete head_inst->traceData;
1213 head_inst->traceData = NULL;
1224 "[tid:%i] [sn:%llu] Committing instruction with PC %s\n",
1225 tid, head_inst->seqNum, head_inst->pcState());
1227 if (head_inst->isReturn()) {
1229 "[tid:%i] [sn:%llu] Return Instruction Committed PC %s \n",
1230 tid, head_inst->seqNum, head_inst->pcState());
1234 for (
int i = 0;
i < head_inst->numDestRegs();
i++) {
1235 renameMap[tid]->setEntry(head_inst->flattenedDestIdx(
i),
1236 head_inst->renamedDestIdx(
i));
1241 if (head_inst->isHtmStart())
1242 iewStage->setLastRetiredHtmUid(tid, head_inst->getHtmTransactionUid());
1245 rob->retireHead(tid);
1247 head_inst->commitTick =
curTick() - head_inst->fetchTick;
1249 if (head_inst->traceData) {
1250 head_inst->traceData->setFetchSeq(head_inst->seqNum);
1251 head_inst->traceData->setCPSeq(
thread[tid]->numOp);
1252 head_inst->traceData->dump();
1253 delete head_inst->traceData;
1254 head_inst->traceData = NULL;
1258 if (head_inst->isStore() || head_inst->isAtomic())
1268 DPRINTF(
Commit,
"Getting instructions from Rename stage.\n");
1273 for (
int inst_num = 0; inst_num < insts_to_process; ++inst_num) {
1277 if (!inst->isSquashed() &&
1282 DPRINTF(
Commit,
"[tid:%i] [sn:%llu] Inserting PC %s into ROB.\n",
1283 tid, inst->seqNum, inst->pcState());
1285 rob->insertInst(inst);
1287 assert(
rob->getThreadEntries(tid) <=
rob->getMaxEntries(tid));
1292 "Instruction PC %s was squashed, skipping.\n",
1293 tid, inst->seqNum, inst->pcState());
1303 for (
int inst_num = 0; inst_num <
fromIEW->size; ++inst_num) {
1304 assert(
fromIEW->insts[inst_num]);
1305 if (!
fromIEW->insts[inst_num]->isSquashed()) {
1308 fromIEW->insts[inst_num]->threadNumber,
1309 fromIEW->insts[inst_num]->pcState(),
1310 fromIEW->insts[inst_num]->seqNum);
1313 fromIEW->insts[inst_num]->setCanCommit();
1321 const ThreadID tid = inst->threadNumber;
1322 const bool in_user_mode =
cpu->inUserMode(tid);
1326 if (!inst->isMicroop() || inst->isLastMicroop()) {
1327 cpu->commitStats[tid]->numInsts++;
1328 cpu->baseStats.numInsts++;
1330 cpu->commitStats[tid]->numUserInsts++;
1334 cpu->commitStats[tid]->numOps++;
1336 cpu->commitStats[tid]->numUserOps++;
1341 if (!inst->isNop() && !inst->isInstPrefetch()) {
1342 cpu->instDone(tid, inst);
1348 cpu->commitStats[tid]->updateComCtrlStats(inst->staticInst);
1353 if (inst->isMemRef()) {
1354 cpu->commitStats[tid]->numMemRefs++;
1356 if (inst->isLoad()) {
1357 cpu->commitStats[tid]->numLoadInsts++;
1360 if (inst->isStore() || inst->isAtomic()) {
1361 cpu->commitStats[tid]->numStoreInsts++;
1365 if (inst->isFullMemBarrier()) {
1366 stats.membars[tid]++;
1370 if (inst->isInteger()) {
1371 cpu->commitStats[tid]->numIntInsts++;
1375 if (inst->isFloating()) {
1376 cpu->commitStats[tid]->numFpInsts++;
1379 if (inst->isVector()) {
1380 cpu->commitStats[tid]->numVecInsts++;
1384 if (inst->isCall()) {
1385 cpu->commitStats[tid]->functionCalls++;
1388 if (inst->isCall() || inst->isReturn()) {
1389 cpu->commitStats[tid]->numCallsReturns++;
1409 if (
cpu->isThreadExiting(tid) &&
1410 !
rob->isEmpty(tid) &&
1414 assert(
rob->isHeadReady(tid) &&
1415 rob->readHeadInst(tid)->isSquashed());
1421 case CommitPolicy::RoundRobin:
1424 case CommitPolicy::OldestReady:
1450 while (pri_iter != end) {
1457 if (
rob->isHeadReady(tid)) {
1474 unsigned oldest = 0;
1475 unsigned oldest_seq_num = 0;
1479 if (!
rob->isEmpty(tid) &&
1484 if (
rob->isHeadReady(tid)) {
1490 oldest_seq_num = head_inst->seqNum;
1492 }
else if (head_inst->seqNum < oldest_seq_num) {
1494 oldest_seq_num = head_inst->seqNum;
Cycles is a wrapper class for representing cycle counts, i.e.
ProbePointArg generates a point for the class of Arg.
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
ThreadStatus commitStatus[MaxThreads]
Per-thread status.
TimeBuffer< IEWStruct >::wire fromIEW
Wire to read information from IEW queue.
std::vector< ThreadState * > thread
Vector of all of the threads.
ThreadID oldestReady()
Returns the thread ID to use based on an oldest instruction policy.
ProbePointArg< DynInstPtr > * ppCommitStall
void squashFromSquashAfter(ThreadID tid)
Handles a squash from a squashAfter() request.
void squashAll(ThreadID tid)
Squashes all in flight instructions.
void startupStage()
Initializes stage by sending back the number of free entries.
bool changedROBNumEntries[MaxThreads]
Records if the number of ROB entries has changed this cycle.
bool changedROBEntries()
Returns if any of the threads have the number of ROB entries changed on this cycle.
DynInstPtr squashAfterInst[MaxThreads]
Instruction passed to squashAfter().
bool executingHtmTransaction(ThreadID) const
Is the CPU currently processing a HTM transaction?
CommitStatus _status
Overall commit status.
gem5::o3::Commit::CommitStats stats
void setIEWQueue(TimeBuffer< IEWStruct > *iq_ptr)
Sets the pointer to the queue coming from IEW.
size_t numROBFreeEntries(ThreadID tid)
Returns the number of free ROB entries for a specific thread.
void setFetchQueue(TimeBuffer< FetchStruct > *fq_ptr)
void processTrapEvent(ThreadID tid)
Mark the thread as processing a trap.
void setRenameQueue(TimeBuffer< RenameStruct > *rq_ptr)
Sets the pointer to the queue coming from rename.
bool checkEmptyROB[MaxThreads]
Records if commit should check if the ROB is truly empty (see commit_impl.hh).
void generateTrapEvent(ThreadID tid, Fault inst_fault)
Generates an event to schedule a squash due to a trap.
void deactivateThread(ThreadID tid)
Deschedules a thread from scheduling.
TimeBuffer< TimeStruct >::wire toIEW
Wire to write information heading to previous stages.
CPU * cpu
Pointer to O3CPU.
void squashFromTC(ThreadID tid)
Handles squashing due to an TC write.
const ThreadID numThreads
Number of Active Threads.
ProbePointArg< DynInstPtr > * ppSquash
To probe when an instruction is squashed.
Commit(CPU *_cpu, const BaseO3CPUParams ¶ms)
Construct a Commit with the given parameters.
bool trapInFlight[MaxThreads]
Records if there is a trap currently in flight.
void handleInterrupt()
Handles processing an interrupt.
const Cycles fetchToCommitDelay
void propagateInterrupt()
Get fetch redirecting so we can handle an interrupt.
std::string name() const
Returns the name of the Commit.
TimeBuffer< FetchStruct > * fetchQueue
void setROB(ROB *rob_ptr)
Sets pointer to the ROB.
int htmStarts[MaxThreads]
CommitPolicy commitPolicy
Commit policy used in SMT mode.
TimeBuffer< TimeStruct >::wire robInfoFromIEW
Wire to read information from IEW (for ROB).
void tick()
Ticks the commit stage, which tries to commit instructions.
void setIEWStage(IEW *iew_stage)
Sets the pointer to the IEW stage.
const unsigned renameWidth
Rename width, in instructions.
bool drainPending
Is a drain pending?
const Cycles trapLatency
The latency to handle a trap.
ProbePointArg< DynInstPtr > * ppCommit
Probe Points.
bool wroteToTimeBuffer
Records that commit has written to the time buffer this cycle.
TimeBuffer< IEWStruct > * iewQueue
IEW instruction queue interface.
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets the main time buffer pointer, used for backwards communication.
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to list of active threads.
const Cycles renameToROBDelay
Rename to ROB delay.
std::list< ThreadID > * activeThreads
Pointer to the list of active threads.
void updateStatus()
Updates the overall status of commit with the nextStatus, and tell the CPU if commit is active/inacti...
void squashAfter(ThreadID tid, const DynInstPtr &head_inst)
Handle squashing from instruction with SquashAfter set.
bool commitHead(const DynInstPtr &head_inst, unsigned inst_num)
Tries to commit the head ROB instruction passed in.
void resetHtmStartsStops(ThreadID)
void getInsts()
Gets instructions from rename and inserts them into the ROB.
bool tcSquash[MaxThreads]
Records if a thread has to squash this cycle due to an XC write.
const Cycles commitToIEWDelay
Commit to IEW delay.
void drainSanityCheck() const
Perform sanity checks after a drain.
void takeOverFrom()
Takes over from another CPU's thread.
void clearStates(ThreadID tid)
Clear all thread-specific states.
void drainResume()
Resumes execution after draining.
TimeBuffer< RenameStruct > * renameQueue
Rename instruction queue interface, for ROB.
void drain()
Initializes the draining of commit.
bool trapSquash[MaxThreads]
Records if a thread has to squash this cycle due to a trap.
InstSeqNum youngestSeqNum[MaxThreads]
The sequence number of the youngest valid instruction in the ROB.
InstSeqNum lastCommitedSeqNum[MaxThreads]
The sequence number of the last commited instruction.
CommitStatus _nextStatus
Next commit status, to be set at the end of the cycle.
bool drainImminent
Is a drain imminent?
void commitInsts()
Commits as many instructions as possible.
void markCompletedInsts()
Marks completed instructions using information sent from IEW.
bool canHandleInterrupts
True if last committed microop can be followed by an interrupt.
TimeBuffer< TimeStruct > * timeBuffer
Time buffer interface.
TimeBuffer< RenameStruct >::wire fromRename
Wire to read information from rename queue.
ThreadID roundRobin()
Returns the thread ID to use based on a round robin policy.
void generateTCEvent(ThreadID tid)
Records that commit needs to initiate a squash due to an external state update through the TC.
std::unique_ptr< PCStateBase > pc[MaxThreads]
The commit PC state of each thread.
void regProbePoints()
Registers probes.
IEW * iewStage
The pointer to the IEW stage.
void setThreads(std::vector< ThreadState * > &threads)
Sets the list of threads.
void updateComInstStats(const DynInstPtr &inst)
Updates commit stats based on this instruction.
ThreadID getCommittingThread()
Gets the thread to commit, based on the SMT policy.
const Cycles iewToCommitDelay
IEW to Commit delay.
bool avoidQuiesceLiveLock
Have we had an interrupt pending and then seen it de-asserted because of a masking change?
std::list< ThreadID > priority_list
Priority List used for Commit Policy.
void commit()
Handles any squashes that are sent from IEW, and adds instructions to the ROB and tries to commit ins...
UnifiedRenameMap * renameMap[MaxThreads]
Rename map interface.
void setRenameMap(UnifiedRenameMap::PerThreadUnifiedRenameMap &rm_ptr)
Sets pointer to the commited state rename map.
void squashFromTrap(ThreadID tid)
Handles squashing due to a trap.
bool committedStores[MaxThreads]
Records if there were any stores committed this cycle.
const unsigned commitWidth
Commit width, in instructions.
bool isDrained() const
Has the stage drained?
Fault interrupt
The interrupt fault.
TimeBuffer< FetchStruct >::wire fromFetch
IEW handles both single threaded and SMT IEW (issue/execute/writeback).
std::array< UnifiedRenameMap, MaxThreads > PerThreadUnifiedRenameMap
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
#define panic(...)
This implements a cprintf based panic() function.
#define fatal(...)
This implements a cprintf based fatal() function.
static constexpr int MaxThreads
RefCountingPtr< DynInst > DynInstPtr
static constexpr int MaxWidth
const FlagsType pdf
Print the percent of the total that this entry represents.
const FlagsType total
Print the total.
const FlagsType dist
Print the distribution.
Copyright (c) 2024 Arm Limited All rights reserved.
std::shared_ptr< FaultBase > Fault
int16_t ThreadID
Thread index/ID type.
const ThreadID InvalidThreadID
Tick curTick()
The universal simulation clock.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
const StaticInstPtr nullStaticInstPtr
Statically allocated null StaticInstPtr.
constexpr decltype(nullptr) NoFault
statistics::Vector amos
Stat for the total number of committed atomics.
CommitStats(CPU *cpu, Commit *commit)
statistics::Distribution numCommittedDist
Distribution of the number of committed instructions each cycle.
statistics::Scalar commitNonSpecStalls
Stat for the total number of times commit has had to stall due to a non-speculative instruction reach...
statistics::Scalar commitEligibleSamples
Number of cycles where the commit bandwidth limit is reached.
statistics::Scalar commitSquashedInsts
Stat for the total number of squashed instructions discarded by commit.
statistics::Scalar branchMispredicts
Stat for the total number of branch mispredicts that caused a squash.
statistics::Vector2d committedInstType
Committed instructions by instruction type (OpClass)
statistics::Vector membars
Total number of committed memory barriers.