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

Generated on Wed Sep 30 2020 14:02:09 for gem5 by doxygen 1.8.17