gem5  v21.1.0.2
commit.cc
Go to the documentation of this file.
1 /*
2  * Copyright 2014 Google, Inc.
3  * Copyright (c) 2010-2014, 2017, 2020 ARM Limited
4  * All rights reserved
5  *
6  * The license below extends only to copyright in the software and shall
7  * not be construed as granting a license to any other intellectual
8  * property including but not limited to intellectual property relating
9  * to a hardware implementation of the functionality of the software
10  * licensed hereunder. You may use the software subject to the license
11  * terms below provided that you ensure that this notice is replicated
12  * unmodified and in its entirety in all distributions of the software,
13  * modified or unmodified, in source code or in binary form.
14  *
15  * Copyright (c) 2004-2005 The Regents of The University of Michigan
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions are
20  * met: redistributions of source code must retain the above copyright
21  * notice, this list of conditions and the following disclaimer;
22  * redistributions in binary form must reproduce the above copyright
23  * notice, this list of conditions and the following disclaimer in the
24  * documentation and/or other materials provided with the distribution;
25  * neither the name of the copyright holders nor the names of its
26  * contributors may be used to endorse or promote products derived from
27  * this software without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  */
41 
42 #include "cpu/o3/commit.hh"
43 
44 #include <algorithm>
45 #include <set>
46 #include <string>
47 
48 #include "base/compiler.hh"
49 #include "base/loader/symtab.hh"
50 #include "base/logging.hh"
51 #include "config/the_isa.hh"
52 #include "cpu/base.hh"
53 #include "cpu/checker/cpu.hh"
54 #include "cpu/exetrace.hh"
55 #include "cpu/o3/cpu.hh"
56 #include "cpu/o3/dyn_inst.hh"
57 #include "cpu/o3/limits.hh"
58 #include "cpu/o3/thread_state.hh"
59 #include "cpu/timebuf.hh"
60 #include "debug/Activity.hh"
61 #include "debug/Commit.hh"
62 #include "debug/CommitRate.hh"
63 #include "debug/Drain.hh"
64 #include "debug/ExecFaulting.hh"
65 #include "debug/HtmCpu.hh"
66 #include "debug/O3PipeView.hh"
67 #include "params/O3CPU.hh"
68 #include "sim/faults.hh"
69 #include "sim/full_system.hh"
70 
71 namespace gem5
72 {
73 
74 namespace o3
75 {
76 
77 void
79 {
80  // This will get reset by commit if it was switched out at the
81  // time of this event processing.
82  trapSquash[tid] = true;
83 }
84 
85 Commit::Commit(CPU *_cpu, const O3CPUParams &params)
86  : commitPolicy(params.smtCommitPolicy),
87  cpu(_cpu),
88  iewToCommitDelay(params.iewToCommitDelay),
89  commitToIEWDelay(params.commitToIEWDelay),
90  renameToROBDelay(params.renameToROBDelay),
91  fetchToCommitDelay(params.commitToFetchDelay),
92  renameWidth(params.renameWidth),
93  commitWidth(params.commitWidth),
94  numThreads(params.numThreads),
95  drainPending(false),
96  drainImminent(false),
97  trapLatency(params.trapLatency),
98  canHandleInterrupts(true),
99  avoidQuiesceLiveLock(false),
100  stats(_cpu, this)
101 {
102  if (commitWidth > MaxWidth)
103  fatal("commitWidth (%d) is larger than compiled limit (%d),\n"
104  "\tincrease MaxWidth in src/cpu/o3/limits.hh\n",
105  commitWidth, static_cast<int>(MaxWidth));
106 
107  _status = Active;
109 
110  if (commitPolicy == CommitPolicy::RoundRobin) {
111  //Set-Up Priority List
112  for (ThreadID tid = 0; tid < numThreads; tid++) {
113  priority_list.push_back(tid);
114  }
115  }
116 
117  for (ThreadID tid = 0; tid < MaxThreads; tid++) {
118  commitStatus[tid] = Idle;
119  changedROBNumEntries[tid] = false;
120  trapSquash[tid] = false;
121  tcSquash[tid] = false;
122  squashAfterInst[tid] = nullptr;
123  pc[tid].set(0);
124  youngestSeqNum[tid] = 0;
125  lastCommitedSeqNum[tid] = 0;
126  trapInFlight[tid] = false;
127  committedStores[tid] = false;
128  checkEmptyROB[tid] = false;
129  renameMap[tid] = nullptr;
130  htmStarts[tid] = 0;
131  htmStops[tid] = 0;
132  }
133  interrupt = NoFault;
134 }
135 
136 std::string Commit::name() const { return cpu->name() + ".commit"; }
137 
138 void
140 {
142  cpu->getProbeManager(), "Commit");
144  cpu->getProbeManager(), "CommitStall");
146  cpu->getProbeManager(), "Squash");
147 }
148 
150  : statistics::Group(cpu, "commit"),
151  ADD_STAT(commitSquashedInsts, statistics::units::Count::get(),
152  "The number of squashed insts skipped by commit"),
153  ADD_STAT(commitNonSpecStalls, statistics::units::Count::get(),
154  "The number of times commit has been forced to stall to "
155  "communicate backwards"),
156  ADD_STAT(branchMispredicts, statistics::units::Count::get(),
157  "The number of times a branch was mispredicted"),
158  ADD_STAT(numCommittedDist, statistics::units::Count::get(),
159  "Number of insts commited each cycle"),
160  ADD_STAT(instsCommitted, statistics::units::Count::get(),
161  "Number of instructions committed"),
162  ADD_STAT(opsCommitted, statistics::units::Count::get(),
163  "Number of ops (including micro ops) committed"),
164  ADD_STAT(memRefs, statistics::units::Count::get(),
165  "Number of memory references committed"),
166  ADD_STAT(loads, statistics::units::Count::get(), "Number of loads committed"),
167  ADD_STAT(amos, statistics::units::Count::get(),
168  "Number of atomic instructions committed"),
169  ADD_STAT(membars, statistics::units::Count::get(),
170  "Number of memory barriers committed"),
171  ADD_STAT(branches, statistics::units::Count::get(),
172  "Number of branches committed"),
173  ADD_STAT(vectorInstructions, statistics::units::Count::get(),
174  "Number of committed Vector instructions."),
175  ADD_STAT(floating, statistics::units::Count::get(),
176  "Number of committed floating point instructions."),
177  ADD_STAT(integer, statistics::units::Count::get(),
178  "Number of committed integer instructions."),
179  ADD_STAT(functionCalls, statistics::units::Count::get(),
180  "Number of function calls committed."),
181  ADD_STAT(committedInstType, statistics::units::Count::get(),
182  "Class of committed instruction"),
183  ADD_STAT(commitEligibleSamples, statistics::units::Cycle::get(),
184  "number cycles where commit BW limit reached")
185 {
186  using namespace statistics;
187 
191 
193  .init(0,commit->commitWidth,1)
195 
197  .init(cpu->numThreads)
198  .flags(total);
199 
201  .init(cpu->numThreads)
202  .flags(total);
203 
204  memRefs
205  .init(cpu->numThreads)
206  .flags(total);
207 
208  loads
209  .init(cpu->numThreads)
210  .flags(total);
211 
212  amos
213  .init(cpu->numThreads)
214  .flags(total);
215 
216  membars
217  .init(cpu->numThreads)
218  .flags(total);
219 
220  branches
221  .init(cpu->numThreads)
222  .flags(total);
223 
225  .init(cpu->numThreads)
226  .flags(total);
227 
228  floating
229  .init(cpu->numThreads)
230  .flags(total);
231 
232  integer
233  .init(cpu->numThreads)
234  .flags(total);
235 
237  .init(commit->numThreads)
238  .flags(total);
239 
241  .init(commit->numThreads,enums::Num_OpClass)
242  .flags(total | pdf | dist);
243 
244  committedInstType.ysubnames(enums::OpClassStrings);
245 }
246 
247 void
249 {
250  thread = threads;
251 }
252 
253 void
255 {
256  timeBuffer = tb_ptr;
257 
258  // Setup wire to send information back to IEW.
259  toIEW = timeBuffer->getWire(0);
260 
261  // Setup wire to read data from IEW (for the ROB).
263 }
264 
265 void
267 {
268  fetchQueue = fq_ptr;
269 
270  // Setup wire to get instructions from rename (for the ROB).
272 }
273 
274 void
276 {
277  renameQueue = rq_ptr;
278 
279  // Setup wire to get instructions from rename (for the ROB).
281 }
282 
283 void
285 {
286  iewQueue = iq_ptr;
287 
288  // Setup wire to get instructions from IEW.
289  fromIEW = iewQueue->getWire(-iewToCommitDelay);
290 }
291 
292 void
294 {
295  iewStage = iew_stage;
296 }
297 
298 void
300 {
301  activeThreads = at_ptr;
302 }
303 
304 void
306 {
307  for (ThreadID tid = 0; tid < numThreads; tid++)
308  renameMap[tid] = &rm_ptr[tid];
309 }
310 
311 void Commit::setROB(ROB *rob_ptr) { rob = rob_ptr; }
312 
313 void
315 {
317  rob->resetEntries();
318 
319  // Broadcast the number of free entries.
320  for (ThreadID tid = 0; tid < numThreads; tid++) {
321  toIEW->commitInfo[tid].usedROB = true;
322  toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
323  toIEW->commitInfo[tid].emptyROB = true;
324  }
325 
326  // Commit must broadcast the number of free entries it has at the
327  // start of the simulation, so it starts as active.
329 
331 }
332 
333 void
335 {
336  commitStatus[tid] = Idle;
337  changedROBNumEntries[tid] = false;
338  checkEmptyROB[tid] = false;
339  trapInFlight[tid] = false;
340  committedStores[tid] = false;
341  trapSquash[tid] = false;
342  tcSquash[tid] = false;
343  pc[tid].set(0);
344  lastCommitedSeqNum[tid] = 0;
345  squashAfterInst[tid] = NULL;
346 }
347 
348 void Commit::drain() { drainPending = true; }
349 
350 void
352 {
353  drainPending = false;
354  drainImminent = false;
355 }
356 
357 void
359 {
360  assert(isDrained());
362 
363  // hardware transactional memory
364  // cannot drain partially through a transaction
365  for (ThreadID tid = 0; tid < numThreads; tid++) {
366  if (executingHtmTransaction(tid)) {
367  panic("cannot drain partially through a HTM transaction");
368  }
369  }
370 }
371 
372 bool
374 {
375  /* Make sure no one is executing microcode. There are two reasons
376  * for this:
377  * - Hardware virtualized CPUs can't switch into the middle of a
378  * microcode sequence.
379  * - The current fetch implementation will most likely get very
380  * confused if it tries to start fetching an instruction that
381  * is executing in the middle of a ucode sequence that changes
382  * address mappings. This can happen on for example x86.
383  */
384  for (ThreadID tid = 0; tid < numThreads; tid++) {
385  if (pc[tid].microPC() != 0)
386  return false;
387  }
388 
389  /* Make sure that all instructions have finished committing before
390  * declaring the system as drained. We want the pipeline to be
391  * completely empty when we declare the CPU to be drained. This
392  * makes debugging easier since CPU handover and restoring from a
393  * checkpoint with a different CPU should have the same timing.
394  */
395  return rob->isEmpty() &&
396  interrupt == NoFault;
397 }
398 
399 void
401 {
402  _status = Active;
404  for (ThreadID tid = 0; tid < numThreads; tid++) {
405  commitStatus[tid] = Idle;
406  changedROBNumEntries[tid] = false;
407  trapSquash[tid] = false;
408  tcSquash[tid] = false;
409  squashAfterInst[tid] = NULL;
410  }
411  rob->takeOverFrom();
412 }
413 
414 void
416 {
417  std::list<ThreadID>::iterator thread_it = std::find(priority_list.begin(),
418  priority_list.end(), tid);
419 
420  if (thread_it != priority_list.end()) {
421  priority_list.erase(thread_it);
422  }
423 }
424 
425 bool
427 {
428  if (tid == InvalidThreadID)
429  return false;
430  else
431  return (htmStarts[tid] > htmStops[tid]);
432 }
433 
434 void
436 {
437  if (tid != InvalidThreadID)
438  {
439  htmStarts[tid] = 0;
440  htmStops[tid] = 0;
441  }
442 }
443 
444 
445 void
447 {
448  // reset ROB changed variable
449  std::list<ThreadID>::iterator threads = activeThreads->begin();
451 
452  while (threads != end) {
453  ThreadID tid = *threads++;
454 
455  changedROBNumEntries[tid] = false;
456 
457  // Also check if any of the threads has a trap pending
458  if (commitStatus[tid] == TrapPending ||
459  commitStatus[tid] == FetchTrapPending) {
461  }
462  }
463 
464  if (_nextStatus == Inactive && _status == Active) {
465  DPRINTF(Activity, "Deactivating stage.\n");
467  } else if (_nextStatus == Active && _status == Inactive) {
468  DPRINTF(Activity, "Activating stage.\n");
470  }
471 
473 }
474 
475 bool
477 {
478  std::list<ThreadID>::iterator threads = activeThreads->begin();
480 
481  while (threads != end) {
482  ThreadID tid = *threads++;
483 
484  if (changedROBNumEntries[tid]) {
485  return true;
486  }
487  }
488 
489  return false;
490 }
491 
492 size_t
494 {
495  return rob->numFreeEntries(tid);
496 }
497 
498 void
500 {
501  DPRINTF(Commit, "Generating trap event for [tid:%i]\n", tid);
502 
504  [this, tid]{ processTrapEvent(tid); },
505  "Trap", true, Event::CPU_Tick_Pri);
506 
507  Cycles latency = std::dynamic_pointer_cast<SyscallRetryFault>(inst_fault) ?
509 
510  // hardware transactional memory
511  if (inst_fault != nullptr &&
512  std::dynamic_pointer_cast<GenericHtmFailureFault>(inst_fault)) {
513  // TODO
514  // latency = default abort/restore latency
515  // could also do some kind of exponential back off if desired
516  }
517 
518  cpu->schedule(trap, cpu->clockEdge(latency));
519  trapInFlight[tid] = true;
520  thread[tid]->trapPending = true;
521 }
522 
523 void
525 {
526  assert(!trapInFlight[tid]);
527  DPRINTF(Commit, "Generating TC squash event for [tid:%i]\n", tid);
528 
529  tcSquash[tid] = true;
530 }
531 
532 void
534 {
535  // If we want to include the squashing instruction in the squash,
536  // then use one older sequence number.
537  // Hopefully this doesn't mess things up. Basically I want to squash
538  // all instructions of this thread.
539  InstSeqNum squashed_inst = rob->isEmpty(tid) ?
540  lastCommitedSeqNum[tid] : rob->readHeadInst(tid)->seqNum - 1;
541 
542  // All younger instructions will be squashed. Set the sequence
543  // number as the youngest instruction in the ROB (0 in this case.
544  // Hopefully nothing breaks.)
546 
547  rob->squash(squashed_inst, tid);
548  changedROBNumEntries[tid] = true;
549 
550  // Send back the sequence number of the squashed instruction.
551  toIEW->commitInfo[tid].doneSeqNum = squashed_inst;
552 
553  // Send back the squash signal to tell stages that they should
554  // squash.
555  toIEW->commitInfo[tid].squash = true;
556 
557  // Send back the rob squashing signal so other stages know that
558  // the ROB is in the process of squashing.
559  toIEW->commitInfo[tid].robSquashing = true;
560 
561  toIEW->commitInfo[tid].mispredictInst = NULL;
562  toIEW->commitInfo[tid].squashInst = NULL;
563 
564  toIEW->commitInfo[tid].pc = pc[tid];
565 }
566 
567 void
569 {
570  squashAll(tid);
571 
572  DPRINTF(Commit, "Squashing from trap, restarting at PC %s\n", pc[tid]);
573 
574  thread[tid]->trapPending = false;
575  thread[tid]->noSquashFromTC = false;
576  trapInFlight[tid] = false;
577 
578  trapSquash[tid] = false;
579 
580  commitStatus[tid] = ROBSquashing;
582 }
583 
584 void
586 {
587  squashAll(tid);
588 
589  DPRINTF(Commit, "Squashing from TC, restarting at PC %s\n", pc[tid]);
590 
591  thread[tid]->noSquashFromTC = false;
592  assert(!thread[tid]->trapPending);
593 
594  commitStatus[tid] = ROBSquashing;
596 
597  tcSquash[tid] = false;
598 }
599 
600 void
602 {
603  DPRINTF(Commit, "Squashing after squash after request, "
604  "restarting at PC %s\n", pc[tid]);
605 
606  squashAll(tid);
607  // Make sure to inform the fetch stage of which instruction caused
608  // the squash. It'll try to re-fetch an instruction executing in
609  // microcode unless this is set.
610  toIEW->commitInfo[tid].squashInst = squashAfterInst[tid];
611  squashAfterInst[tid] = NULL;
612 
613  commitStatus[tid] = ROBSquashing;
615 }
616 
617 void
619 {
620  DPRINTF(Commit, "Executing squash after for [tid:%i] inst [sn:%llu]\n",
621  tid, head_inst->seqNum);
622 
623  assert(!squashAfterInst[tid] || squashAfterInst[tid] == head_inst);
625  squashAfterInst[tid] = head_inst;
626 }
627 
628 void
630 {
631  wroteToTimeBuffer = false;
633 
634  if (activeThreads->empty())
635  return;
636 
637  std::list<ThreadID>::iterator threads = activeThreads->begin();
639 
640  // Check if any of the threads are done squashing. Change the
641  // status if they are done.
642  while (threads != end) {
643  ThreadID tid = *threads++;
644 
645  // Clear the bit saying if the thread has committed stores
646  // this cycle.
647  committedStores[tid] = false;
648 
649  if (commitStatus[tid] == ROBSquashing) {
650 
651  if (rob->isDoneSquashing(tid)) {
652  commitStatus[tid] = Running;
653  } else {
654  DPRINTF(Commit,"[tid:%i] Still Squashing, cannot commit any"
655  " insts this cycle.\n", tid);
656  rob->doSquash(tid);
657  toIEW->commitInfo[tid].robSquashing = true;
658  wroteToTimeBuffer = true;
659  }
660  }
661  }
662 
663  commit();
664 
666 
667  threads = activeThreads->begin();
668 
669  while (threads != end) {
670  ThreadID tid = *threads++;
671 
672  if (!rob->isEmpty(tid) && rob->readHeadInst(tid)->readyToCommit()) {
673  // The ROB has more instructions it can commit. Its next status
674  // will be active.
676 
677  GEM5_VAR_USED const DynInstPtr &inst = rob->readHeadInst(tid);
678 
679  DPRINTF(Commit,"[tid:%i] Instruction [sn:%llu] PC %s is head of"
680  " ROB and ready to commit\n",
681  tid, inst->seqNum, inst->pcState());
682 
683  } else if (!rob->isEmpty(tid)) {
684  const DynInstPtr &inst = rob->readHeadInst(tid);
685 
686  ppCommitStall->notify(inst);
687 
688  DPRINTF(Commit,"[tid:%i] Can't commit, Instruction [sn:%llu] PC "
689  "%s is head of ROB and not ready\n",
690  tid, inst->seqNum, inst->pcState());
691  }
692 
693  DPRINTF(Commit, "[tid:%i] ROB has %d insts & %d free entries.\n",
694  tid, rob->countInsts(tid), rob->numFreeEntries(tid));
695  }
696 
697 
698  if (wroteToTimeBuffer) {
699  DPRINTF(Activity, "Activity This Cycle.\n");
701  }
702 
703  updateStatus();
704 }
705 
706 void
708 {
709  // Verify that we still have an interrupt to handle
710  if (!cpu->checkInterrupts(0)) {
711  DPRINTF(Commit, "Pending interrupt is cleared by requestor before "
712  "it got handled. Restart fetching from the orig path.\n");
713  toIEW->commitInfo[0].clearInterrupt = true;
714  interrupt = NoFault;
715  avoidQuiesceLiveLock = true;
716  return;
717  }
718 
719  // Wait until all in flight instructions are finished before enterring
720  // the interrupt.
721  if (canHandleInterrupts && cpu->instList.empty()) {
722  // Squash or record that I need to squash this cycle if
723  // an interrupt needed to be handled.
724  DPRINTF(Commit, "Interrupt detected.\n");
725 
726  // Clear the interrupt now that it's going to be handled
727  toIEW->commitInfo[0].clearInterrupt = true;
728 
729  assert(!thread[0]->noSquashFromTC);
730  thread[0]->noSquashFromTC = true;
731 
732  if (cpu->checker) {
733  cpu->checker->handlePendingInt();
734  }
735 
736  // CPU will handle interrupt. Note that we ignore the local copy of
737  // interrupt. This is because the local copy may no longer be the
738  // interrupt that the interrupt controller thinks is being handled.
740 
741  thread[0]->noSquashFromTC = false;
742 
744 
745  interrupt = NoFault;
746 
747  // Generate trap squash event.
749 
750  avoidQuiesceLiveLock = false;
751  } else {
752  DPRINTF(Commit, "Interrupt pending: instruction is %sin "
753  "flight, ROB is %sempty\n",
754  canHandleInterrupts ? "not " : "",
755  cpu->instList.empty() ? "" : "not " );
756  }
757 }
758 
759 void
761 {
762  // Don't propagate intterupts if we are currently handling a trap or
763  // in draining and the last observable instruction has been committed.
764  if (commitStatus[0] == TrapPending || interrupt || trapSquash[0] ||
765  tcSquash[0] || drainImminent)
766  return;
767 
768  // Process interrupts if interrupts are enabled, not in PAL
769  // mode, and no other traps or external squashes are currently
770  // pending.
771  // @todo: Allow other threads to handle interrupts.
772 
773  // Get any interrupt that happened
775 
776  // Tell fetch that there is an interrupt pending. This
777  // will make fetch wait until it sees a non PAL-mode PC,
778  // at which point it stops fetching instructions.
779  if (interrupt != NoFault)
780  toIEW->commitInfo[0].interruptPending = true;
781 }
782 
783 void
785 {
786  if (FullSystem) {
787  // Check if we have a interrupt and get read to handle it
788  if (cpu->checkInterrupts(0))
790  }
791 
793  // Check for any possible squashes, handle them first
795  std::list<ThreadID>::iterator threads = activeThreads->begin();
797 
798  int num_squashing_threads = 0;
799 
800  while (threads != end) {
801  ThreadID tid = *threads++;
802 
803  // Not sure which one takes priority. I think if we have
804  // both, that's a bad sign.
805  if (trapSquash[tid]) {
806  assert(!tcSquash[tid]);
807  squashFromTrap(tid);
808 
809  // If the thread is trying to exit (i.e., an exit syscall was
810  // executed), this trapSquash was originated by the exit
811  // syscall earlier. In this case, schedule an exit event in
812  // the next cycle to fully terminate this thread
813  if (cpu->isThreadExiting(tid))
815  } else if (tcSquash[tid]) {
816  assert(commitStatus[tid] != TrapPending);
817  squashFromTC(tid);
818  } else if (commitStatus[tid] == SquashAfterPending) {
819  // A squash from the previous cycle of the commit stage (i.e.,
820  // commitInsts() called squashAfter) is pending. Squash the
821  // thread now.
823  }
824 
825  // Squashed sequence number must be older than youngest valid
826  // instruction in the ROB. This prevents squashes from younger
827  // instructions overriding squashes from older instructions.
828  if (fromIEW->squash[tid] &&
829  commitStatus[tid] != TrapPending &&
830  fromIEW->squashedSeqNum[tid] <= youngestSeqNum[tid]) {
831 
832  if (fromIEW->mispredictInst[tid]) {
833  DPRINTF(Commit,
834  "[tid:%i] Squashing due to branch mispred "
835  "PC:%#x [sn:%llu]\n",
836  tid,
837  fromIEW->mispredictInst[tid]->instAddr(),
838  fromIEW->squashedSeqNum[tid]);
839  } else {
840  DPRINTF(Commit,
841  "[tid:%i] Squashing due to order violation [sn:%llu]\n",
842  tid, fromIEW->squashedSeqNum[tid]);
843  }
844 
845  DPRINTF(Commit, "[tid:%i] Redirecting to PC %#x\n",
846  tid,
847  fromIEW->pc[tid].nextInstAddr());
848 
849  commitStatus[tid] = ROBSquashing;
850 
851  // If we want to include the squashing instruction in the squash,
852  // then use one older sequence number.
853  InstSeqNum squashed_inst = fromIEW->squashedSeqNum[tid];
854 
855  if (fromIEW->includeSquashInst[tid]) {
856  squashed_inst--;
857  }
858 
859  // All younger instructions will be squashed. Set the sequence
860  // number as the youngest instruction in the ROB.
861  youngestSeqNum[tid] = squashed_inst;
862 
863  rob->squash(squashed_inst, tid);
864  changedROBNumEntries[tid] = true;
865 
866  toIEW->commitInfo[tid].doneSeqNum = squashed_inst;
867 
868  toIEW->commitInfo[tid].squash = true;
869 
870  // Send back the rob squashing signal so other stages know that
871  // the ROB is in the process of squashing.
872  toIEW->commitInfo[tid].robSquashing = true;
873 
874  toIEW->commitInfo[tid].mispredictInst =
875  fromIEW->mispredictInst[tid];
876  toIEW->commitInfo[tid].branchTaken =
877  fromIEW->branchTaken[tid];
878  toIEW->commitInfo[tid].squashInst =
879  rob->findInst(tid, squashed_inst);
880  if (toIEW->commitInfo[tid].mispredictInst) {
881  if (toIEW->commitInfo[tid].mispredictInst->isUncondCtrl()) {
882  toIEW->commitInfo[tid].branchTaken = true;
883  }
884  ++stats.branchMispredicts;
885  }
886 
887  toIEW->commitInfo[tid].pc = fromIEW->pc[tid];
888  }
889 
890  if (commitStatus[tid] == ROBSquashing) {
891  num_squashing_threads++;
892  }
893  }
894 
895  // If commit is currently squashing, then it will have activity for the
896  // next cycle. Set its next status as active.
897  if (num_squashing_threads) {
899  }
900 
901  if (num_squashing_threads != numThreads) {
902  // If we're not currently squashing, then get instructions.
903  getInsts();
904 
905  // Try to commit any instructions.
906  commitInsts();
907  }
908 
909  //Check for any activity
910  threads = activeThreads->begin();
911 
912  while (threads != end) {
913  ThreadID tid = *threads++;
914 
915  if (changedROBNumEntries[tid]) {
916  toIEW->commitInfo[tid].usedROB = true;
917  toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
918 
919  wroteToTimeBuffer = true;
920  changedROBNumEntries[tid] = false;
921  if (rob->isEmpty(tid))
922  checkEmptyROB[tid] = true;
923  }
924 
925  // ROB is only considered "empty" for previous stages if: a)
926  // ROB is empty, b) there are no outstanding stores, c) IEW
927  // stage has received any information regarding stores that
928  // committed.
929  // c) is checked by making sure to not consider the ROB empty
930  // on the same cycle as when stores have been committed.
931  // @todo: Make this handle multi-cycle communication between
932  // commit and IEW.
933  if (checkEmptyROB[tid] && rob->isEmpty(tid) &&
934  !iewStage->hasStoresToWB(tid) && !committedStores[tid]) {
935  checkEmptyROB[tid] = false;
936  toIEW->commitInfo[tid].usedROB = true;
937  toIEW->commitInfo[tid].emptyROB = true;
938  toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
939  wroteToTimeBuffer = true;
940  }
941 
942  }
943 }
944 
945 void
947 {
949  // Handle commit
950  // Note that commit will be handled prior to putting new
951  // instructions in the ROB so that the ROB only tries to commit
952  // instructions it has in this current cycle, and not instructions
953  // it is writing in during this cycle. Can't commit and squash
954  // things at the same time...
956 
957  DPRINTF(Commit, "Trying to commit instructions in the ROB.\n");
958 
959  unsigned num_committed = 0;
960 
961  DynInstPtr head_inst;
962 
963  // Commit as many instructions as possible until the commit bandwidth
964  // limit is reached, or it becomes impossible to commit any more.
965  while (num_committed < commitWidth) {
966  // hardware transactionally memory
967  // If executing within a transaction,
968  // need to handle interrupts specially
969 
970  ThreadID commit_thread = getCommittingThread();
971 
972  // Check for any interrupt that we've already squashed for
973  // and start processing it.
974  if (interrupt != NoFault) {
975  // If inside a transaction, postpone interrupts
976  if (executingHtmTransaction(commit_thread)) {
977  cpu->clearInterrupts(0);
978  toIEW->commitInfo[0].clearInterrupt = true;
979  interrupt = NoFault;
980  avoidQuiesceLiveLock = true;
981  } else {
982  handleInterrupt();
983  }
984  }
985 
986  // ThreadID commit_thread = getCommittingThread();
987 
988  if (commit_thread == -1 || !rob->isHeadReady(commit_thread))
989  break;
990 
991  head_inst = rob->readHeadInst(commit_thread);
992 
993  ThreadID tid = head_inst->threadNumber;
994 
995  assert(tid == commit_thread);
996 
997  DPRINTF(Commit,
998  "Trying to commit head instruction, [tid:%i] [sn:%llu]\n",
999  tid, head_inst->seqNum);
1000 
1001  // If the head instruction is squashed, it is ready to retire
1002  // (be removed from the ROB) at any time.
1003  if (head_inst->isSquashed()) {
1004 
1005  DPRINTF(Commit, "Retiring squashed instruction from "
1006  "ROB.\n");
1007 
1008  rob->retireHead(commit_thread);
1009 
1010  ++stats.commitSquashedInsts;
1011  // Notify potential listeners that this instruction is squashed
1012  ppSquash->notify(head_inst);
1013 
1014  // Record that the number of ROB entries has changed.
1015  changedROBNumEntries[tid] = true;
1016  } else {
1017  pc[tid] = head_inst->pcState();
1018 
1019  // Try to commit the head instruction.
1020  bool commit_success = commitHead(head_inst, num_committed);
1021 
1022  if (commit_success) {
1023  ++num_committed;
1024  stats.committedInstType[tid][head_inst->opClass()]++;
1025  ppCommit->notify(head_inst);
1026 
1027  // hardware transactional memory
1028 
1029  // update nesting depth
1030  if (head_inst->isHtmStart())
1031  htmStarts[tid]++;
1032 
1033  // sanity check
1034  if (head_inst->inHtmTransactionalState()) {
1035  assert(executingHtmTransaction(tid));
1036  } else {
1037  assert(!executingHtmTransaction(tid));
1038  }
1039 
1040  // update nesting depth
1041  if (head_inst->isHtmStop())
1042  htmStops[tid]++;
1043 
1044  changedROBNumEntries[tid] = true;
1045 
1046  // Set the doneSeqNum to the youngest committed instruction.
1047  toIEW->commitInfo[tid].doneSeqNum = head_inst->seqNum;
1048 
1049  if (tid == 0)
1050  canHandleInterrupts = !head_inst->isDelayedCommit();
1051 
1052  // at this point store conditionals should either have
1053  // been completed or predicated false
1054  assert(!head_inst->isStoreConditional() ||
1055  head_inst->isCompleted() ||
1056  !head_inst->readPredicate());
1057 
1058  // Updates misc. registers.
1059  head_inst->updateMiscRegs();
1060 
1061  // Check instruction execution if it successfully commits and
1062  // is not carrying a fault.
1063  if (cpu->checker) {
1064  cpu->checker->verify(head_inst);
1065  }
1066 
1067  cpu->traceFunctions(pc[tid].instAddr());
1068 
1069  head_inst->staticInst->advancePC(pc[tid]);
1070 
1071  // Keep track of the last sequence number commited
1072  lastCommitedSeqNum[tid] = head_inst->seqNum;
1073 
1074  // If this is an instruction that doesn't play nicely with
1075  // others squash everything and restart fetch
1076  if (head_inst->isSquashAfter())
1077  squashAfter(tid, head_inst);
1078 
1079  if (drainPending) {
1080  if (pc[tid].microPC() == 0 && interrupt == NoFault &&
1081  !thread[tid]->trapPending) {
1082  // Last architectually committed instruction.
1083  // Squash the pipeline, stall fetch, and use
1084  // drainImminent to disable interrupts
1085  DPRINTF(Drain, "Draining: %i:%s\n", tid, pc[tid]);
1086  squashAfter(tid, head_inst);
1087  cpu->commitDrained(tid);
1088  drainImminent = true;
1089  }
1090  }
1091 
1092  bool onInstBoundary = !head_inst->isMicroop() ||
1093  head_inst->isLastMicroop() ||
1094  !head_inst->isDelayedCommit();
1095 
1096  if (onInstBoundary) {
1097  int count = 0;
1098  Addr oldpc;
1099  // Make sure we're not currently updating state while
1100  // handling PC events.
1101  assert(!thread[tid]->noSquashFromTC &&
1102  !thread[tid]->trapPending);
1103  do {
1104  oldpc = pc[tid].instAddr();
1105  thread[tid]->pcEventQueue.service(
1106  oldpc, thread[tid]->getTC());
1107  count++;
1108  } while (oldpc != pc[tid].instAddr());
1109  if (count > 1) {
1110  DPRINTF(Commit,
1111  "PC skip function event, stopping commit\n");
1112  break;
1113  }
1114  }
1115 
1116  // Check if an instruction just enabled interrupts and we've
1117  // previously had an interrupt pending that was not handled
1118  // because interrupts were subsequently disabled before the
1119  // pipeline reached a place to handle the interrupt. In that
1120  // case squash now to make sure the interrupt is handled.
1121  //
1122  // If we don't do this, we might end up in a live lock
1123  // situation.
1124  if (!interrupt && avoidQuiesceLiveLock &&
1125  onInstBoundary && cpu->checkInterrupts(0))
1126  squashAfter(tid, head_inst);
1127  } else {
1128  DPRINTF(Commit, "Unable to commit head instruction PC:%s "
1129  "[tid:%i] [sn:%llu].\n",
1130  head_inst->pcState(), tid ,head_inst->seqNum);
1131  break;
1132  }
1133  }
1134  }
1135 
1136  DPRINTF(CommitRate, "%i\n", num_committed);
1137  stats.numCommittedDist.sample(num_committed);
1138 
1139  if (num_committed == commitWidth) {
1140  stats.commitEligibleSamples++;
1141  }
1142 }
1143 
1144 bool
1145 Commit::commitHead(const DynInstPtr &head_inst, unsigned inst_num)
1146 {
1147  assert(head_inst);
1148 
1149  ThreadID tid = head_inst->threadNumber;
1150 
1151  // If the instruction is not executed yet, then it will need extra
1152  // handling. Signal backwards that it should be executed.
1153  if (!head_inst->isExecuted()) {
1154  // Make sure we are only trying to commit un-executed instructions we
1155  // think are possible.
1156  assert(head_inst->isNonSpeculative() || head_inst->isStoreConditional()
1157  || head_inst->isReadBarrier() || head_inst->isWriteBarrier()
1158  || head_inst->isAtomic()
1159  || (head_inst->isLoad() && head_inst->strictlyOrdered()));
1160 
1161  DPRINTF(Commit,
1162  "Encountered a barrier or non-speculative "
1163  "instruction [tid:%i] [sn:%llu] "
1164  "at the head of the ROB, PC %s.\n",
1165  tid, head_inst->seqNum, head_inst->pcState());
1166 
1167  if (inst_num > 0 || iewStage->hasStoresToWB(tid)) {
1168  DPRINTF(Commit,
1169  "[tid:%i] [sn:%llu] "
1170  "Waiting for all stores to writeback.\n",
1171  tid, head_inst->seqNum);
1172  return false;
1173  }
1174 
1175  toIEW->commitInfo[tid].nonSpecSeqNum = head_inst->seqNum;
1176 
1177  // Change the instruction so it won't try to commit again until
1178  // it is executed.
1179  head_inst->clearCanCommit();
1180 
1181  if (head_inst->isLoad() && head_inst->strictlyOrdered()) {
1182  DPRINTF(Commit, "[tid:%i] [sn:%llu] "
1183  "Strictly ordered load, PC %s.\n",
1184  tid, head_inst->seqNum, head_inst->pcState());
1185  toIEW->commitInfo[tid].strictlyOrdered = true;
1186  toIEW->commitInfo[tid].strictlyOrderedLoad = head_inst;
1187  } else {
1188  ++stats.commitNonSpecStalls;
1189  }
1190 
1191  return false;
1192  }
1193 
1194  // Check if the instruction caused a fault. If so, trap.
1195  Fault inst_fault = head_inst->getFault();
1196 
1197  // hardware transactional memory
1198  // if a fault occurred within a HTM transaction
1199  // ensure that the transaction aborts
1200  if (inst_fault != NoFault && head_inst->inHtmTransactionalState()) {
1201  // There exists a generic HTM fault common to all ISAs
1202  if (!std::dynamic_pointer_cast<GenericHtmFailureFault>(inst_fault)) {
1203  DPRINTF(HtmCpu, "%s - fault (%s) encountered within transaction"
1204  " - converting to GenericHtmFailureFault\n",
1205  head_inst->staticInst->getName(), inst_fault->name());
1206  inst_fault = std::make_shared<GenericHtmFailureFault>(
1207  head_inst->getHtmTransactionUid(),
1209  }
1210  // If this point is reached and the fault inherits from the HTM fault,
1211  // then there is no need to raise a new fault
1212  }
1213 
1214  // Stores mark themselves as completed.
1215  if (!head_inst->isStore() && inst_fault == NoFault) {
1216  head_inst->setCompleted();
1217  }
1218 
1219  if (inst_fault != NoFault) {
1220  DPRINTF(Commit, "Inst [tid:%i] [sn:%llu] PC %s has a fault\n",
1221  tid, head_inst->seqNum, head_inst->pcState());
1222 
1223  if (iewStage->hasStoresToWB(tid) || inst_num > 0) {
1224  DPRINTF(Commit,
1225  "[tid:%i] [sn:%llu] "
1226  "Stores outstanding, fault must wait.\n",
1227  tid, head_inst->seqNum);
1228  return false;
1229  }
1230 
1231  head_inst->setCompleted();
1232 
1233  // If instruction has faulted, let the checker execute it and
1234  // check if it sees the same fault and control flow.
1235  if (cpu->checker) {
1236  // Need to check the instruction before its fault is processed
1237  cpu->checker->verify(head_inst);
1238  }
1239 
1240  assert(!thread[tid]->noSquashFromTC);
1241 
1242  // Mark that we're in state update mode so that the trap's
1243  // execution doesn't generate extra squashes.
1244  thread[tid]->noSquashFromTC = true;
1245 
1246  // Execute the trap. Although it's slightly unrealistic in
1247  // terms of timing (as it doesn't wait for the full timing of
1248  // the trap event to complete before updating state), it's
1249  // needed to update the state as soon as possible. This
1250  // prevents external agents from changing any specific state
1251  // that the trap need.
1252  cpu->trap(inst_fault, tid,
1253  head_inst->notAnInst() ? nullStaticInstPtr :
1254  head_inst->staticInst);
1255 
1256  // Exit state update mode to avoid accidental updating.
1257  thread[tid]->noSquashFromTC = false;
1258 
1259  commitStatus[tid] = TrapPending;
1260 
1261  DPRINTF(Commit,
1262  "[tid:%i] [sn:%llu] Committing instruction with fault\n",
1263  tid, head_inst->seqNum);
1264  if (head_inst->traceData) {
1265  // We ignore ReExecution "faults" here as they are not real
1266  // (architectural) faults but signal flush/replays.
1267  if (debug::ExecFaulting
1268  && dynamic_cast<ReExec*>(inst_fault.get()) == nullptr) {
1269 
1270  head_inst->traceData->setFaulting(true);
1271  head_inst->traceData->setFetchSeq(head_inst->seqNum);
1272  head_inst->traceData->setCPSeq(thread[tid]->numOp);
1273  head_inst->traceData->dump();
1274  }
1275  delete head_inst->traceData;
1276  head_inst->traceData = NULL;
1277  }
1278 
1279  // Generate trap squash event.
1280  generateTrapEvent(tid, inst_fault);
1281  return false;
1282  }
1283 
1284  updateComInstStats(head_inst);
1285 
1286  DPRINTF(Commit,
1287  "[tid:%i] [sn:%llu] Committing instruction with PC %s\n",
1288  tid, head_inst->seqNum, head_inst->pcState());
1289  if (head_inst->traceData) {
1290  head_inst->traceData->setFetchSeq(head_inst->seqNum);
1291  head_inst->traceData->setCPSeq(thread[tid]->numOp);
1292  head_inst->traceData->dump();
1293  delete head_inst->traceData;
1294  head_inst->traceData = NULL;
1295  }
1296  if (head_inst->isReturn()) {
1297  DPRINTF(Commit,
1298  "[tid:%i] [sn:%llu] Return Instruction Committed PC %s \n",
1299  tid, head_inst->seqNum, head_inst->pcState());
1300  }
1301 
1302  // Update the commit rename map
1303  for (int i = 0; i < head_inst->numDestRegs(); i++) {
1304  renameMap[tid]->setEntry(head_inst->regs.flattenedDestIdx(i),
1305  head_inst->regs.renamedDestIdx(i));
1306  }
1307 
1308  // hardware transactional memory
1309  // the HTM UID is purely for correctness and debugging purposes
1310  if (head_inst->isHtmStart())
1311  iewStage->setLastRetiredHtmUid(tid, head_inst->getHtmTransactionUid());
1312 
1313  // Finally clear the head ROB entry.
1314  rob->retireHead(tid);
1315 
1316 #if TRACING_ON
1317  if (debug::O3PipeView) {
1318  head_inst->commitTick = curTick() - head_inst->fetchTick;
1319  }
1320 #endif
1321 
1322  // If this was a store, record it for this cycle.
1323  if (head_inst->isStore() || head_inst->isAtomic())
1324  committedStores[tid] = true;
1325 
1326  // Return true to indicate that we have committed an instruction.
1327  return true;
1328 }
1329 
1330 void
1332 {
1333  DPRINTF(Commit, "Getting instructions from Rename stage.\n");
1334 
1335  // Read any renamed instructions and place them into the ROB.
1336  int insts_to_process = std::min((int)renameWidth, fromRename->size);
1337 
1338  for (int inst_num = 0; inst_num < insts_to_process; ++inst_num) {
1339  const DynInstPtr &inst = fromRename->insts[inst_num];
1340  ThreadID tid = inst->threadNumber;
1341 
1342  if (!inst->isSquashed() &&
1343  commitStatus[tid] != ROBSquashing &&
1344  commitStatus[tid] != TrapPending) {
1345  changedROBNumEntries[tid] = true;
1346 
1347  DPRINTF(Commit, "[tid:%i] [sn:%llu] Inserting PC %s into ROB.\n",
1348  tid, inst->seqNum, inst->pcState());
1349 
1350  rob->insertInst(inst);
1351 
1352  assert(rob->getThreadEntries(tid) <= rob->getMaxEntries(tid));
1353 
1354  youngestSeqNum[tid] = inst->seqNum;
1355  } else {
1356  DPRINTF(Commit, "[tid:%i] [sn:%llu] "
1357  "Instruction PC %s was squashed, skipping.\n",
1358  tid, inst->seqNum, inst->pcState());
1359  }
1360  }
1361 }
1362 
1363 void
1365 {
1366  // Grab completed insts out of the IEW instruction queue, and mark
1367  // instructions completed within the ROB.
1368  for (int inst_num = 0; inst_num < fromIEW->size; ++inst_num) {
1369  assert(fromIEW->insts[inst_num]);
1370  if (!fromIEW->insts[inst_num]->isSquashed()) {
1371  DPRINTF(Commit, "[tid:%i] Marking PC %s, [sn:%llu] ready "
1372  "within ROB.\n",
1373  fromIEW->insts[inst_num]->threadNumber,
1374  fromIEW->insts[inst_num]->pcState(),
1375  fromIEW->insts[inst_num]->seqNum);
1376 
1377  // Mark the instruction as ready to commit.
1378  fromIEW->insts[inst_num]->setCanCommit();
1379  }
1380  }
1381 }
1382 
1383 void
1385 {
1386  ThreadID tid = inst->threadNumber;
1387 
1388  if (!inst->isMicroop() || inst->isLastMicroop())
1389  stats.instsCommitted[tid]++;
1390  stats.opsCommitted[tid]++;
1391 
1392  // To match the old model, don't count nops and instruction
1393  // prefetches towards the total commit count.
1394  if (!inst->isNop() && !inst->isInstPrefetch()) {
1395  cpu->instDone(tid, inst);
1396  }
1397 
1398  //
1399  // Control Instructions
1400  //
1401  if (inst->isControl())
1402  stats.branches[tid]++;
1403 
1404  //
1405  // Memory references
1406  //
1407  if (inst->isMemRef()) {
1408  stats.memRefs[tid]++;
1409 
1410  if (inst->isLoad()) {
1411  stats.loads[tid]++;
1412  }
1413 
1414  if (inst->isAtomic()) {
1415  stats.amos[tid]++;
1416  }
1417  }
1418 
1419  if (inst->isFullMemBarrier()) {
1420  stats.membars[tid]++;
1421  }
1422 
1423  // Integer Instruction
1424  if (inst->isInteger())
1425  stats.integer[tid]++;
1426 
1427  // Floating Point Instruction
1428  if (inst->isFloating())
1429  stats.floating[tid]++;
1430  // Vector Instruction
1431  if (inst->isVector())
1432  stats.vectorInstructions[tid]++;
1433 
1434  // Function Calls
1435  if (inst->isCall())
1436  stats.functionCalls[tid]++;
1437 
1438 }
1439 
1441 // //
1442 // SMT COMMIT POLICY MAINTAINED HERE //
1443 // //
1445 ThreadID
1447 {
1448  if (numThreads > 1) {
1449  switch (commitPolicy) {
1450  case CommitPolicy::RoundRobin:
1451  return roundRobin();
1452 
1453  case CommitPolicy::OldestReady:
1454  return oldestReady();
1455 
1456  default:
1457  return InvalidThreadID;
1458  }
1459  } else {
1460  assert(!activeThreads->empty());
1461  ThreadID tid = activeThreads->front();
1462 
1463  if (commitStatus[tid] == Running ||
1464  commitStatus[tid] == Idle ||
1465  commitStatus[tid] == FetchTrapPending) {
1466  return tid;
1467  } else {
1468  return InvalidThreadID;
1469  }
1470  }
1471 }
1472 
1473 ThreadID
1475 {
1476  std::list<ThreadID>::iterator pri_iter = priority_list.begin();
1478 
1479  while (pri_iter != end) {
1480  ThreadID tid = *pri_iter;
1481 
1482  if (commitStatus[tid] == Running ||
1483  commitStatus[tid] == Idle ||
1484  commitStatus[tid] == FetchTrapPending) {
1485 
1486  if (rob->isHeadReady(tid)) {
1487  priority_list.erase(pri_iter);
1488  priority_list.push_back(tid);
1489 
1490  return tid;
1491  }
1492  }
1493 
1494  pri_iter++;
1495  }
1496 
1497  return InvalidThreadID;
1498 }
1499 
1500 ThreadID
1502 {
1503  unsigned oldest = 0;
1504  unsigned oldest_seq_num = 0;
1505  bool first = true;
1506 
1507  std::list<ThreadID>::iterator threads = activeThreads->begin();
1509 
1510  while (threads != end) {
1511  ThreadID tid = *threads++;
1512 
1513  if (!rob->isEmpty(tid) &&
1514  (commitStatus[tid] == Running ||
1515  commitStatus[tid] == Idle ||
1516  commitStatus[tid] == FetchTrapPending)) {
1517 
1518  if (rob->isHeadReady(tid)) {
1519 
1520  const DynInstPtr &head_inst = rob->readHeadInst(tid);
1521 
1522  if (first) {
1523  oldest = tid;
1524  oldest_seq_num = head_inst->seqNum;
1525  first = false;
1526  } else if (head_inst->seqNum < oldest_seq_num) {
1527  oldest = tid;
1528  oldest_seq_num = head_inst->seqNum;
1529  }
1530  }
1531  }
1532  }
1533 
1534  if (!first) {
1535  return oldest;
1536  } else {
1537  return InvalidThreadID;
1538  }
1539 }
1540 
1541 } // namespace o3
1542 } // namespace gem5
gem5::o3::Commit::drainPending
bool drainPending
Is a drain pending? Commit is looking for an instruction boundary while there are no pending interrup...
Definition: commit.hh:414
gem5::o3::Commit::setActiveThreads
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to list of active threads.
Definition: commit.cc:299
gem5::o3::Commit::renameMap
UnifiedRenameMap * renameMap[MaxThreads]
Rename map interface.
Definition: commit.hh:456
gem5::o3::Commit::setROB
void setROB(ROB *rob_ptr)
Sets pointer to the ROB.
Definition: commit.cc:311
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::o3::Commit::TrapPending
@ TrapPending
Definition: commit.hh:109
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:189
gem5::o3::Commit::fetchToCommitDelay
const Cycles fetchToCommitDelay
Definition: commit.hh:398
gem5::o3::ROB::doSquash
void doSquash(ThreadID tid)
Executes the squash, marking squashed instructions.
Definition: rob.cc:309
gem5::o3::Commit::takeOverFrom
void takeOverFrom()
Takes over from another CPU's thread.
Definition: commit.cc:400
gem5::o3::Commit::CommitStats::instsCommitted
statistics::Vector instsCommitted
Total number of instructions committed.
Definition: commit.hh:493
gem5::NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:260
gem5::o3::Commit::squashFromTC
void squashFromTC(ThreadID tid)
Handles squashing due to an TC write.
Definition: commit.cc:585
gem5::o3::ROB::squash
void squash(InstSeqNum squash_num, ThreadID tid)
Squashes all instructions younger than the given sequence number for the specific thread.
Definition: rob.cc:473
gem5::o3::Commit::regProbePoints
void regProbePoints()
Registers probes.
Definition: commit.cc:139
gem5::o3::Commit::Commit
Commit(CPU *_cpu, const O3CPUParams &params)
Construct a Commit with the given parameters.
Definition: commit.cc:85
commit.hh
gem5::o3::Commit::CommitStats::loads
statistics::Vector loads
Stat for the total number of committed loads.
Definition: commit.hh:499
gem5::o3::Commit::renameWidth
const unsigned renameWidth
Rename width, in instructions.
Definition: commit.hh:403
gem5::o3::Commit::setIEWQueue
void setIEWQueue(TimeBuffer< IEWStruct > *iq_ptr)
Sets the pointer to the queue coming from IEW.
Definition: commit.cc:284
gem5::o3::Commit::CommitStats::numCommittedDist
statistics::Distribution numCommittedDist
Distribution of the number of committed instructions each cycle.
Definition: commit.hh:490
gem5::o3::Commit::drain
void drain()
Initializes the draining of commit.
Definition: commit.cc:348
gem5::o3::Commit::CommitStats::committedInstType
statistics::Vector2d committedInstType
Committed instructions by instruction type (OpClass)
Definition: commit.hh:515
gem5::o3::Commit::pc
TheISA::PCState pc[MaxThreads]
The commit PC state of each thread.
Definition: commit.hh:434
gem5::o3::Commit::renameQueue
TimeBuffer< RenameStruct > * renameQueue
Rename instruction queue interface, for ROB.
Definition: commit.hh:345
gem5::o3::Commit::ppSquash
ProbePointArg< DynInstPtr > * ppSquash
To probe when an instruction is squashed.
Definition: commit.hh:128
gem5::o3::Commit::squashAfterInst
DynInstPtr squashAfterInst[MaxThreads]
Instruction passed to squashAfter().
Definition: commit.hh:384
gem5::statistics::Vector2dBase::init
Derived & init(size_type _x, size_type _y)
Definition: statistics.hh:1171
gem5::o3::Commit::setThreads
void setThreads(std::vector< ThreadState * > &threads)
Sets the list of threads.
Definition: commit.cc:248
gem5::o3::Commit::timeBuffer
TimeBuffer< TimeStruct > * timeBuffer
Time buffer interface.
Definition: commit.hh:326
gem5::o3::Commit::fromIEW
TimeBuffer< IEWStruct >::wire fromIEW
Wire to read information from IEW queue.
Definition: commit.hh:342
gem5::o3::CPU::processInterrupts
void processInterrupts(const Fault &interrupt)
Processes any an interrupt fault.
Definition: cpu.cc:886
gem5::o3::CPU::getInterrupts
Fault getInterrupts()
Returns the Fault for any valid interrupt.
Definition: cpu.cc:879
gem5::o3::Commit::priority_list
std::list< ThreadID > priority_list
Priority List used for Commit Policy.
Definition: commit.hh:387
gem5::o3::Commit::wroteToTimeBuffer
bool wroteToTimeBuffer
Records that commit has written to the time buffer this cycle.
Definition: commit.hh:364
gem5::o3::ROB::insertInst
void insertInst(const DynInstPtr &inst)
Function to insert an instruction into the ROB.
Definition: rob.cc:197
gem5::o3::Commit::changedROBEntries
bool changedROBEntries()
Returns if any of the threads have the number of ROB entries changed on this cycle.
Definition: commit.cc:476
gem5::o3::Commit::startupStage
void startupStage()
Initializes stage by sending back the number of free entries.
Definition: commit.cc:314
gem5::o3::ROB::drainSanityCheck
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: rob.cc:134
exetrace.hh
gem5::o3::Commit::setRenameMap
void setRenameMap(UnifiedRenameMap rm_ptr[MaxThreads])
Sets pointer to the commited state rename map.
Definition: commit.cc:305
gem5::o3::Commit::commitInsts
void commitInsts()
Commits as many instructions as possible.
Definition: commit.cc:946
gem5::o3::Commit::ppCommit
ProbePointArg< DynInstPtr > * ppCommit
Probe Points.
Definition: commit.hh:125
gem5::o3::ROB::isDoneSquashing
bool isDoneSquashing(ThreadID tid) const
Reads the PC of the oldest head instruction.
Definition: rob.hh:250
gem5::EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1019
std::vector
STL vector class.
Definition: stl.hh:37
dyn_inst.hh
gem5::o3::CPU::instList
std::list< DynInstPtr > instList
List of all the instructions in flight.
Definition: cpu.hh:462
gem5::o3::Commit::FetchTrapPending
@ FetchTrapPending
Definition: commit.hh:110
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:66
faults.hh
gem5::o3::Commit::squashFromSquashAfter
void squashFromSquashAfter(ThreadID tid)
Handles a squash from a squashAfter() request.
Definition: commit.cc:601
gem5::o3::ROB::numFreeEntries
unsigned numFreeEntries()
Returns the number of total free entries in the ROB.
Definition: rob.cc:297
gem5::o3::Commit::setRenameQueue
void setRenameQueue(TimeBuffer< RenameStruct > *rq_ptr)
Sets the pointer to the queue coming from rename.
Definition: commit.cc:275
gem5::o3::Commit::committedStores
bool committedStores[MaxThreads]
Records if there were any stores committed this cycle.
Definition: commit.hh:446
gem5::o3::Commit::generateTrapEvent
void generateTrapEvent(ThreadID tid, Fault inst_fault)
Generates an event to schedule a squash due to a trap.
Definition: commit.cc:499
gem5::o3::Commit::deactivateThread
void deactivateThread(ThreadID tid)
Deschedules a thread from scheduling.
Definition: commit.cc:415
gem5::o3::ROB::resetEntries
void resetEntries()
Re-adjust ROB partitioning.
Definition: rob.cc:148
gem5::statistics::dist
const FlagsType dist
Print the distribution.
Definition: info.hh:66
gem5::RefCountingPtr< DynInst >
gem5::TimeBuffer
Definition: timebuf.hh:40
gem5::o3::Commit::numROBFreeEntries
size_t numROBFreeEntries(ThreadID tid)
Returns the number of free ROB entries for a specific thread.
Definition: commit.cc:493
gem5::o3::CPU::checker
gem5::Checker< DynInstPtr > * checker
Pointer to the checker, which can dynamically verify instruction results at run time.
Definition: cpu.hh:602
gem5::Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:78
gem5::o3::Commit::htmStarts
int htmStarts[MaxThreads]
Definition: commit.hh:471
gem5::o3::ROB::getMaxEntries
unsigned getMaxEntries(ThreadID tid)
Returns the maximum number of entries for a specific thread.
Definition: rob.hh:179
gem5::o3::CPU::deactivateStage
void deactivateStage(const StageIdx idx)
Changes a stage's status to inactive within the activity recorder.
Definition: cpu.hh:576
gem5::HtmFailureFaultCause::EXCEPTION
@ EXCEPTION
gem5::o3::Commit::name
std::string name() const
Returns the name of the Commit.
Definition: commit.cc:136
gem5::o3::Commit::CommitStats::branchMispredicts
statistics::Scalar branchMispredicts
Stat for the total number of branch mispredicts that caused a squash.
Definition: commit.hh:488
gem5::o3::Commit::iewStage
IEW * iewStage
The pointer to the IEW stage.
Definition: commit.hh:164
gem5::statistics::pdf
const FlagsType pdf
Print the percent of the total that this entry represents.
Definition: info.hh:62
timebuf.hh
gem5::BaseCPU::numThreads
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
Definition: base.hh:368
gem5::o3::Commit::activeThreads
std::list< ThreadID > * activeThreads
Pointer to the list of active threads.
Definition: commit.hh:453
gem5::o3::Commit::changedROBNumEntries
bool changedROBNumEntries[MaxThreads]
Records if the number of ROB entries has changed this cycle.
Definition: commit.hh:369
gem5::o3::Commit::iewQueue
TimeBuffer< IEWStruct > * iewQueue
IEW instruction queue interface.
Definition: commit.hh:339
gem5::nullStaticInstPtr
const StaticInstPtr nullStaticInstPtr
Statically allocated null StaticInstPtr.
Definition: null_static_inst.cc:36
gem5::o3::Commit::generateTCEvent
void generateTCEvent(ThreadID tid)
Records that commit needs to initiate a squash due to an external state update through the TC.
Definition: commit.cc:524
gem5::o3::Commit::renameToROBDelay
const Cycles renameToROBDelay
Rename to ROB delay.
Definition: commit.hh:396
gem5::o3::Commit::squashAll
void squashAll(ThreadID tid)
Squashes all in flight instructions.
Definition: commit.cc:533
gem5::o3::Commit::CommitStats::floating
statistics::Vector floating
Total number of floating point instructions.
Definition: commit.hh:509
gem5::o3::CPU
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
Definition: cpu.hh:95
gem5::statistics::Distribution::init
Distribution & init(Counter min, Counter max, Counter bkt)
Set the parameters of this distribution.
Definition: statistics.hh:2110
gem5::o3::Commit
Commit handles single threaded and SMT commit.
Definition: commit.hh:91
gem5::o3::Commit::propagateInterrupt
void propagateInterrupt()
Get fetch redirecting so we can handle an interrupt.
Definition: commit.cc:760
gem5::Named::name
virtual std::string name() const
Definition: named.hh:47
gem5::Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:255
gem5::o3::Commit::Running
@ Running
Definition: commit.hh:106
gem5::o3::Commit::processTrapEvent
void processTrapEvent(ThreadID tid)
Mark the thread as processing a trap.
Definition: commit.cc:78
gem5::o3::Commit::isDrained
bool isDrained() const
Has the stage drained?
Definition: commit.cc:373
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::o3::Commit::rob
ROB * rob
ROB interface.
Definition: commit.hh:352
gem5::o3::Commit::commitStatus
ThreadStatus commitStatus[MaxThreads]
Per-thread status.
Definition: commit.hh:120
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
gem5::o3::Commit::roundRobin
ThreadID roundRobin()
Returns the thread ID to use based on a round robin policy.
Definition: commit.cc:1474
gem5::o3::Commit::microPC
Addr microPC(ThreadID tid)
Reads the micro PC of a specific thread.
Definition: commit.hh:322
gem5::X86ISA::count
count
Definition: misc.hh:709
gem5::o3::Commit::Active
@ Active
Definition: commit.hh:99
gem5::o3::Commit::getInsts
void getInsts()
Gets instructions from rename and inserts them into the ROB.
Definition: commit.cc:1331
gem5::o3::ROB::readHeadInst
const DynInstPtr & readHeadInst(ThreadID tid)
Returns pointer to the head instruction within the ROB.
Definition: rob.cc:502
gem5::o3::Commit::avoidQuiesceLiveLock
bool avoidQuiesceLiveLock
Have we had an interrupt pending and then seen it de-asserted because of a masking change?...
Definition: commit.hh:465
gem5::o3::Commit::htmStops
int htmStops[MaxThreads]
Definition: commit.hh:472
gem5::o3::Commit::ROBSquashing
@ ROBSquashing
Definition: commit.hh:108
gem5::o3::CPU::scheduleThreadExitEvent
void scheduleThreadExitEvent(ThreadID tid)
If a thread is trying to exit and its corresponding trap event has been completed,...
Definition: cpu.cc:1681
gem5::o3::CPU::CommitIdx
@ CommitIdx
Definition: cpu.hh:541
gem5::o3::IEW
IEW handles both single threaded and SMT IEW (issue/execute/writeback).
Definition: iew.hh:87
cpu.hh
gem5::o3::Commit::commitHead
bool commitHead(const DynInstPtr &head_inst, unsigned inst_num)
Tries to commit the head ROB instruction passed in.
Definition: commit.cc:1145
gem5::o3::CPU::activateStage
void activateStage(const StageIdx idx)
Changes a stage's status to active within the activity recorder.
Definition: cpu.hh:572
gem5::o3::Commit::toIEW
TimeBuffer< TimeStruct >::wire toIEW
Wire to write information heading to previous stages.
Definition: commit.hh:329
gem5::o3::Commit::resetHtmStartsStops
void resetHtmStartsStops(ThreadID)
Definition: commit.cc:435
gem5::ReExec
Definition: faults.hh:92
gem5::o3::Commit::squashAfter
void squashAfter(ThreadID tid, const DynInstPtr &head_inst)
Handle squashing from instruction with SquashAfter set.
Definition: commit.cc:618
gem5::o3::Commit::oldestReady
ThreadID oldestReady()
Returns the thread ID to use based on an oldest instruction policy.
Definition: commit.cc:1501
gem5::o3::ROB::setActiveThreads
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to the list of active threads.
Definition: rob.cc:127
gem5::o3::Commit::CommitStats::commitSquashedInsts
statistics::Scalar commitSquashedInsts
Stat for the total number of squashed instructions discarded by commit.
Definition: commit.hh:480
gem5::o3::Commit::commitWidth
const unsigned commitWidth
Commit width, in instructions.
Definition: commit.hh:406
gem5::o3::Commit::clearStates
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition: commit.cc:334
thread_state.hh
gem5::InvalidThreadID
const ThreadID InvalidThreadID
Definition: types.hh:243
gem5::o3::MaxWidth
static constexpr int MaxWidth
Definition: limits.hh:37
gem5::o3::Commit::thread
std::vector< ThreadState * > thread
Vector of all of the threads.
Definition: commit.hh:359
compiler.hh
gem5::o3::Commit::cpu
CPU * cpu
Pointer to O3CPU.
Definition: commit.hh:356
gem5::o3::ROB::isHeadReady
bool isHeadReady(ThreadID tid)
Is the oldest instruction across all threads ready.
Definition: rob.cc:268
gem5::o3::Commit::checkEmptyROB
bool checkEmptyROB[MaxThreads]
Records if commit should check if the ROB is truly empty (see commit_impl.hh).
Definition: commit.hh:450
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::o3::Commit::CommitStats::integer
statistics::Vector integer
Total number of integer instructions.
Definition: commit.hh:511
gem5::o3::Commit::instAddr
Addr instAddr(ThreadID tid)
Returns the PC of a specific thread.
Definition: commit.hh:316
gem5::o3::Commit::fromFetch
TimeBuffer< FetchStruct >::wire fromFetch
Definition: commit.hh:336
gem5::o3::Commit::CommitStats::vectorInstructions
statistics::Vector vectorInstructions
Total number of vector instructions.
Definition: commit.hh:507
gem5::o3::Commit::updateComInstStats
void updateComInstStats(const DynInstPtr &inst)
Updates commit stats based on this instruction.
Definition: commit.cc:1384
gem5::Clocked::clockEdge
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Definition: clocked_object.hh:177
full_system.hh
gem5::o3::Commit::getCommittingThread
ThreadID getCommittingThread()
Gets the thread to commit, based on the SMT policy.
Definition: commit.cc:1446
gem5::ProbePointArg
ProbePointArg generates a point for the class of Arg.
Definition: thermal_domain.hh:54
gem5::EventFunctionWrapper
Definition: eventq.hh:1115
gem5::o3::Commit::commit
void commit()
Handles any squashes that are sent from IEW, and adds instructions to the ROB and tries to commit ins...
Definition: commit.cc:784
gem5::FullSystem
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:223
gem5::o3::ROB::getThreadEntries
unsigned getThreadEntries(ThreadID tid)
Returns the number of entries being used by a specific thread.
Definition: rob.hh:183
gem5::o3::IEW::setLastRetiredHtmUid
void setLastRetiredHtmUid(ThreadID tid, uint64_t htmUid)
Definition: iew.hh:234
gem5::SimObject::getProbeManager
ProbeManager * getProbeManager()
Get the probe manager for this object.
Definition: sim_object.cc:120
gem5::o3::MaxThreads
static constexpr int MaxThreads
Definition: limits.hh:38
gem5::o3::CPU::activityThisCycle
void activityThisCycle()
Records that there was time buffer activity this cycle.
Definition: cpu.hh:569
gem5::o3::Commit::CommitStats::amos
statistics::Vector amos
Stat for the total number of committed atomics.
Definition: commit.hh:501
gem5::o3::Commit::drainResume
void drainResume()
Resumes execution after draining.
Definition: commit.cc:351
gem5::o3::ROB::findInst
DynInstPtr findInst(ThreadID tid, InstSeqNum squash_inst)
Returns a pointer to the instruction with the given sequence if it is in the ROB.
Definition: rob.cc:534
gem5::o3::Commit::executingHtmTransaction
bool executingHtmTransaction(ThreadID) const
Is the CPU currently processing a HTM transaction?
Definition: commit.cc:426
base.hh
gem5::BaseCPU::traceFunctions
void traceFunctions(Addr pc)
Definition: base.hh:563
gem5::statistics::DataWrap::prereq
Derived & prereq(const Stat &prereq)
Set the prerequisite stat and marks this stat to print at the end of simulation.
Definition: statistics.hh:369
gem5::o3::CPU::commitDrained
void commitDrained(ThreadID tid)
Commit has reached a safe point to drain a thread.
Definition: cpu.cc:1046
gem5::o3::Commit::SquashAfterPending
@ SquashAfterPending
Definition: commit.hh:111
gem5::o3::Commit::Idle
@ Idle
Definition: commit.hh:107
gem5::o3::CPU::trap
void trap(const Fault &fault, ThreadID tid, const StaticInstPtr &inst)
Traps to handle given fault.
Definition: cpu.cc:902
gem5::o3::Commit::interrupt
Fault interrupt
The interrupt fault.
Definition: commit.hh:429
gem5::BaseCPU::checkInterrupts
bool checkInterrupts(ThreadID tid) const
Definition: base.hh:256
gem5::o3::Commit::lastCommitedSeqNum
InstSeqNum lastCommitedSeqNum[MaxThreads]
The sequence number of the last commited instruction.
Definition: commit.hh:440
gem5::o3::ROB::isEmpty
bool isEmpty() const
Returns if the ROB is empty.
Definition: rob.hh:195
gem5::o3::Commit::setFetchQueue
void setFetchQueue(TimeBuffer< FetchStruct > *fq_ptr)
Definition: commit.cc:266
gem5::o3::Commit::trapSquash
bool trapSquash[MaxThreads]
Records if a thread has to squash this cycle due to a trap.
Definition: commit.hh:372
gem5::o3::CPU::isThreadExiting
bool isThreadExiting(ThreadID tid) const
Is the thread trying to exit?
Definition: cpu.cc:1675
gem5::o3::Commit::commitPolicy
CommitPolicy commitPolicy
Commit policy used in SMT mode.
Definition: commit.hh:122
gem5::o3::Commit::trapInFlight
bool trapInFlight[MaxThreads]
Records if there is a trap currently in flight.
Definition: commit.hh:443
gem5::o3::Commit::_status
CommitStatus _status
Overall commit status.
Definition: commit.hh:116
logging.hh
gem5::BaseCPU::syscallRetryLatency
Cycles syscallRetryLatency
Definition: base.hh:615
gem5::o3::Commit::pcState
TheISA::PCState pcState(ThreadID tid)
Reads the PC of a specific thread.
Definition: commit.hh:309
gem5::statistics::Group
Statistics container.
Definition: group.hh:93
gem5::o3::Commit::CommitStats::memRefs
statistics::Vector memRefs
Stat for the total number of committed memory references.
Definition: commit.hh:497
gem5::o3::Commit::_nextStatus
CommitStatus _nextStatus
Next commit status, to be set at the end of the cycle.
Definition: commit.hh:118
gem5::statistics::Group::stats
std::vector< Info * > stats
Definition: group.hh:221
gem5::statistics::DataWrapVec2d::ysubnames
Derived & ysubnames(const char **names)
Definition: statistics.hh:475
gem5::InstSeqNum
uint64_t InstSeqNum
Definition: inst_seq.hh:40
gem5::o3::Commit::CommitStats::opsCommitted
statistics::Vector opsCommitted
Total number of ops (including micro ops) committed.
Definition: commit.hh:495
gem5::o3::ROB::retireHead
void retireHead(ThreadID tid)
Retires the head instruction, removing it from the ROB.
Definition: rob.cc:234
gem5::o3::Commit::CommitStats::CommitStats
CommitStats(CPU *cpu, Commit *commit)
Definition: commit.cc:149
gem5::o3::Commit::CommitStats::commitNonSpecStalls
statistics::Scalar commitNonSpecStalls
Stat for the total number of times commit has had to stall due to a non-speculative instruction reach...
Definition: commit.hh:484
gem5::o3::Commit::tick
void tick()
Ticks the commit stage, which tries to commit instructions.
Definition: commit.cc:629
gem5::o3::Commit::Inactive
@ Inactive
Definition: commit.hh:100
symtab.hh
gem5::statistics::DataWrap::flags
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:355
gem5::o3::Commit::ppCommitStall
ProbePointArg< DynInstPtr > * ppCommitStall
Definition: commit.hh:126
cpu.hh
std::list< ThreadID >
gem5::EventBase::CPU_Tick_Pri
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
Definition: eventq.hh:204
gem5::o3::Commit::youngestSeqNum
InstSeqNum youngestSeqNum[MaxThreads]
The sequence number of the youngest valid instruction in the ROB.
Definition: commit.hh:437
gem5::o3::Commit::CommitStats::functionCalls
statistics::Vector functionCalls
Total number of function calls.
Definition: commit.hh:513
gem5::o3::IEW::hasStoresToWB
bool hasStoresToWB()
Returns if the LSQ has any stores to writeback.
Definition: iew.hh:221
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::o3::ROB::countInsts
int countInsts()
This is more of a debugging function than anything.
Definition: rob.cc:180
gem5::o3::Commit::numThreads
const ThreadID numThreads
Number of Active Threads.
Definition: commit.hh:409
gem5::statistics::total
const FlagsType total
Print the total.
Definition: info.hh:60
limits.hh
gem5::statistics::VectorBase::init
Derived & init(size_type size)
Set this vector to have the given size.
Definition: statistics.hh:1037
gem5::o3::Commit::markCompletedInsts
void markCompletedInsts()
Marks completed instructions using information sent from IEW.
Definition: commit.cc:1364
gem5::o3::Commit::drainImminent
bool drainImminent
Is a drain imminent? Commit has found an instruction boundary while no interrupts were present or in ...
Definition: commit.hh:421
gem5::o3::Commit::updateStatus
void updateStatus()
Updates the overall status of commit with the nextStatus, and tell the CPU if commit is active/inacti...
Definition: commit.cc:446
gem5::o3::ROB
ROB class.
Definition: rob.hh:72
gem5::o3::Commit::setTimeBuffer
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets the main time buffer pointer, used for backwards communication.
Definition: commit.cc:254
gem5::BaseCPU::clearInterrupts
void clearInterrupts(ThreadID tid)
Definition: base.hh:250
gem5::o3::Commit::squashFromTrap
void squashFromTrap(ThreadID tid)
Handles squashing due to a trap.
Definition: commit.cc:568
gem5::o3::Commit::trapLatency
const Cycles trapLatency
The latency to handle a trap.
Definition: commit.hh:426
gem5::o3::Commit::canHandleInterrupts
bool canHandleInterrupts
True if last committed microop can be followed by an interrupt.
Definition: commit.hh:459
gem5::o3::Commit::handleInterrupt
void handleInterrupt()
Handles processing an interrupt.
Definition: commit.cc:707
gem5::o3::Commit::setIEWStage
void setIEWStage(IEW *iew_stage)
Sets the pointer to the IEW stage.
Definition: commit.cc:293
gem5::o3::Commit::fromRename
TimeBuffer< RenameStruct >::wire fromRename
Wire to read information from rename queue.
Definition: commit.hh:348
gem5::o3::Commit::CommitStats::branches
statistics::Vector branches
Total number of committed branches.
Definition: commit.hh:505
gem5::o3::Commit::drainSanityCheck
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: commit.cc:358
gem5::o3::CPU::instDone
void instDone(ThreadID tid, const DynInstPtr &inst)
Function to tell the CPU that an instruction has completed.
Definition: cpu.cc:1420
gem5::ThreadID
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:242
gem5::o3::ROB::takeOverFrom
void takeOverFrom()
Takes over another CPU's thread.
Definition: rob.cc:142
gem5::o3::Commit::CommitStats::membars
statistics::Vector membars
Total number of committed memory barriers.
Definition: commit.hh:503
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:177
gem5::o3::UnifiedRenameMap::setEntry
void setEntry(const RegId &arch_reg, PhysRegIdPtr phys_reg)
Update rename map with a specific mapping.
Definition: rename_map.hh:309
gem5::o3::UnifiedRenameMap
Unified register rename map for all classes of registers.
Definition: rename_map.hh:174
gem5::o3::Commit::iewToCommitDelay
const Cycles iewToCommitDelay
IEW to Commit delay.
Definition: commit.hh:390
gem5::o3::Commit::robInfoFromIEW
TimeBuffer< TimeStruct >::wire robInfoFromIEW
Wire to read information from IEW (for ROB).
Definition: commit.hh:332
gem5::o3::Commit::fetchQueue
TimeBuffer< FetchStruct > * fetchQueue
Definition: commit.hh:334
gem5::o3::Commit::tcSquash
bool tcSquash[MaxThreads]
Records if a thread has to squash this cycle due to an XC write.
Definition: commit.hh:375

Generated on Tue Sep 21 2021 12:25:03 for gem5 by doxygen 1.8.17