gem5  v21.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 template <class Impl>
70 void
72 {
73  // This will get reset by commit if it was switched out at the
74  // time of this event processing.
75  trapSquash[tid] = true;
76 }
77 
78 template <class Impl>
79 DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, const DerivO3CPUParams &params)
80  : commitPolicy(params.smtCommitPolicy),
81  cpu(_cpu),
82  iewToCommitDelay(params.iewToCommitDelay),
83  commitToIEWDelay(params.commitToIEWDelay),
84  renameToROBDelay(params.renameToROBDelay),
85  fetchToCommitDelay(params.commitToFetchDelay),
86  renameWidth(params.renameWidth),
87  commitWidth(params.commitWidth),
88  numThreads(params.numThreads),
89  drainPending(false),
90  drainImminent(false),
91  trapLatency(params.trapLatency),
92  canHandleInterrupts(true),
93  avoidQuiesceLiveLock(false),
94  stats(_cpu, this)
95 {
96  if (commitWidth > Impl::MaxWidth)
97  fatal("commitWidth (%d) is larger than compiled limit (%d),\n"
98  "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
99  commitWidth, static_cast<int>(Impl::MaxWidth));
100 
101  _status = Active;
103 
104  if (commitPolicy == CommitPolicy::RoundRobin) {
105  //Set-Up Priority List
106  for (ThreadID tid = 0; tid < numThreads; tid++) {
107  priority_list.push_back(tid);
108  }
109  }
110 
111  for (ThreadID tid = 0; tid < Impl::MaxThreads; tid++) {
112  commitStatus[tid] = Idle;
113  changedROBNumEntries[tid] = false;
114  trapSquash[tid] = false;
115  tcSquash[tid] = false;
116  squashAfterInst[tid] = nullptr;
117  pc[tid].set(0);
118  youngestSeqNum[tid] = 0;
119  lastCommitedSeqNum[tid] = 0;
120  trapInFlight[tid] = false;
121  committedStores[tid] = false;
122  checkEmptyROB[tid] = false;
123  renameMap[tid] = nullptr;
124  htmStarts[tid] = 0;
125  htmStops[tid] = 0;
126  }
127  interrupt = NoFault;
128 }
129 
130 template <class Impl>
131 std::string
133 {
134  return cpu->name() + ".commit";
135 }
136 
137 template <class Impl>
138 void
140 {
141  ppCommit = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Commit");
142  ppCommitStall = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "CommitStall");
143  ppSquash = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Squash");
144 }
145 
146 template <class Impl>
148  DefaultCommit *commit)
149  : Stats::Group(cpu, "commit"),
150  ADD_STAT(commitSquashedInsts, UNIT_COUNT,
151  "The number of squashed insts skipped by commit"),
152  ADD_STAT(commitNonSpecStalls, UNIT_COUNT,
153  "The number of times commit has been forced to stall to "
154  "communicate backwards"),
155  ADD_STAT(branchMispredicts, UNIT_COUNT,
156  "The number of times a branch was mispredicted"),
157  ADD_STAT(numCommittedDist, UNIT_COUNT,
158  "Number of insts commited each cycle"),
159  ADD_STAT(instsCommitted, UNIT_COUNT, "Number of instructions committed"),
160  ADD_STAT(opsCommitted, UNIT_COUNT,
161  "Number of ops (including micro ops) committed"),
162  ADD_STAT(memRefs, UNIT_COUNT, "Number of memory references committed"),
163  ADD_STAT(loads, UNIT_COUNT, "Number of loads committed"),
164  ADD_STAT(amos, UNIT_COUNT, "Number of atomic instructions committed"),
165  ADD_STAT(membars, UNIT_COUNT, "Number of memory barriers committed"),
166  ADD_STAT(branches, UNIT_COUNT, "Number of branches committed"),
167  ADD_STAT(vectorInstructions, UNIT_COUNT,
168  "Number of committed Vector instructions."),
169  ADD_STAT(floating, UNIT_COUNT,
170  "Number of committed floating point instructions."),
171  ADD_STAT(integer, UNIT_COUNT,
172  "Number of committed integer instructions."),
173  ADD_STAT(functionCalls, UNIT_COUNT,
174  "Number of function calls committed."),
175  ADD_STAT(committedInstType, UNIT_COUNT,
176  "Class of committed instruction"),
177  ADD_STAT(commitEligibleSamples, UNIT_CYCLE,
178  "number cycles where commit BW limit reached")
179 {
180  using namespace Stats;
181 
185 
187  .init(0,commit->commitWidth,1)
188  .flags(Stats::pdf);
189 
191  .init(cpu->numThreads)
192  .flags(total);
193 
195  .init(cpu->numThreads)
196  .flags(total);
197 
198  memRefs
199  .init(cpu->numThreads)
200  .flags(total);
201 
202  loads
203  .init(cpu->numThreads)
204  .flags(total);
205 
206  amos
207  .init(cpu->numThreads)
208  .flags(total);
209 
210  membars
211  .init(cpu->numThreads)
212  .flags(total);
213 
214  branches
215  .init(cpu->numThreads)
216  .flags(total);
217 
219  .init(cpu->numThreads)
220  .flags(total);
221 
222  floating
223  .init(cpu->numThreads)
224  .flags(total);
225 
226  integer
227  .init(cpu->numThreads)
228  .flags(total);
229 
231  .init(commit->numThreads)
232  .flags(total);
233 
235  .init(commit->numThreads,Enums::Num_OpClass)
236  .flags(total | pdf | dist);
237 
238  committedInstType.ysubnames(Enums::OpClassStrings);
239 }
240 
241 template <class Impl>
242 void
244 {
245  thread = threads;
246 }
247 
248 template <class Impl>
249 void
251 {
252  timeBuffer = tb_ptr;
253 
254  // Setup wire to send information back to IEW.
255  toIEW = timeBuffer->getWire(0);
256 
257  // Setup wire to read data from IEW (for the ROB).
259 }
260 
261 template <class Impl>
262 void
264 {
265  fetchQueue = fq_ptr;
266 
267  // Setup wire to get instructions from rename (for the ROB).
269 }
270 
271 template <class Impl>
272 void
274 {
275  renameQueue = rq_ptr;
276 
277  // Setup wire to get instructions from rename (for the ROB).
279 }
280 
281 template <class Impl>
282 void
284 {
285  iewQueue = iq_ptr;
286 
287  // Setup wire to get instructions from IEW.
289 }
290 
291 template <class Impl>
292 void
294 {
295  iewStage = iew_stage;
296 }
297 
298 template<class Impl>
299 void
301 {
302  activeThreads = at_ptr;
303 }
304 
305 template <class Impl>
306 void
308 {
309  for (ThreadID tid = 0; tid < numThreads; tid++)
310  renameMap[tid] = &rm_ptr[tid];
311 }
312 
313 template <class Impl>
314 void
316 {
317  rob = rob_ptr;
318 }
319 
320 template <class Impl>
321 void
323 {
325  rob->resetEntries();
326 
327  // Broadcast the number of free entries.
328  for (ThreadID tid = 0; tid < numThreads; tid++) {
329  toIEW->commitInfo[tid].usedROB = true;
330  toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
331  toIEW->commitInfo[tid].emptyROB = true;
332  }
333 
334  // Commit must broadcast the number of free entries it has at the
335  // start of the simulation, so it starts as active.
336  cpu->activateStage(O3CPU::CommitIdx);
337 
338  cpu->activityThisCycle();
339 }
340 
341 template <class Impl>
342 void
344 {
345  commitStatus[tid] = Idle;
346  changedROBNumEntries[tid] = false;
347  checkEmptyROB[tid] = false;
348  trapInFlight[tid] = false;
349  committedStores[tid] = false;
350  trapSquash[tid] = false;
351  tcSquash[tid] = false;
352  pc[tid].set(0);
353  lastCommitedSeqNum[tid] = 0;
354  squashAfterInst[tid] = NULL;
355 }
356 
357 template <class Impl>
358 void
360 {
361  drainPending = true;
362 }
363 
364 template <class Impl>
365 void
367 {
368  drainPending = false;
369  drainImminent = false;
370 }
371 
372 template <class Impl>
373 void
375 {
376  assert(isDrained());
378 
379  // hardware transactional memory
380  // cannot drain partially through a transaction
381  for (ThreadID tid = 0; tid < numThreads; tid++) {
382  if (executingHtmTransaction(tid)) {
383  panic("cannot drain partially through a HTM transaction");
384  }
385  }
386 }
387 
388 template <class Impl>
389 bool
391 {
392  /* Make sure no one is executing microcode. There are two reasons
393  * for this:
394  * - Hardware virtualized CPUs can't switch into the middle of a
395  * microcode sequence.
396  * - The current fetch implementation will most likely get very
397  * confused if it tries to start fetching an instruction that
398  * is executing in the middle of a ucode sequence that changes
399  * address mappings. This can happen on for example x86.
400  */
401  for (ThreadID tid = 0; tid < numThreads; tid++) {
402  if (pc[tid].microPC() != 0)
403  return false;
404  }
405 
406  /* Make sure that all instructions have finished committing before
407  * declaring the system as drained. We want the pipeline to be
408  * completely empty when we declare the CPU to be drained. This
409  * makes debugging easier since CPU handover and restoring from a
410  * checkpoint with a different CPU should have the same timing.
411  */
412  return rob->isEmpty() &&
413  interrupt == NoFault;
414 }
415 
416 template <class Impl>
417 void
419 {
420  _status = Active;
422  for (ThreadID tid = 0; tid < numThreads; tid++) {
423  commitStatus[tid] = Idle;
424  changedROBNumEntries[tid] = false;
425  trapSquash[tid] = false;
426  tcSquash[tid] = false;
427  squashAfterInst[tid] = NULL;
428  }
429  rob->takeOverFrom();
430 }
431 
432 template <class Impl>
433 void
435 {
436  std::list<ThreadID>::iterator thread_it = std::find(priority_list.begin(),
437  priority_list.end(), tid);
438 
439  if (thread_it != priority_list.end()) {
440  priority_list.erase(thread_it);
441  }
442 }
443 
444 template <class Impl>
445 bool
447 {
448  if (tid == InvalidThreadID)
449  return false;
450  else
451  return (htmStarts[tid] > htmStops[tid]);
452 }
453 
454 template <class Impl>
455 void
457 {
458  if (tid != InvalidThreadID)
459  {
460  htmStarts[tid] = 0;
461  htmStops[tid] = 0;
462  }
463 }
464 
465 
466 template <class Impl>
467 void
469 {
470  // reset ROB changed variable
471  std::list<ThreadID>::iterator threads = activeThreads->begin();
473 
474  while (threads != end) {
475  ThreadID tid = *threads++;
476 
477  changedROBNumEntries[tid] = false;
478 
479  // Also check if any of the threads has a trap pending
480  if (commitStatus[tid] == TrapPending ||
481  commitStatus[tid] == FetchTrapPending) {
483  }
484  }
485 
486  if (_nextStatus == Inactive && _status == Active) {
487  DPRINTF(Activity, "Deactivating stage.\n");
488  cpu->deactivateStage(O3CPU::CommitIdx);
489  } else if (_nextStatus == Active && _status == Inactive) {
490  DPRINTF(Activity, "Activating stage.\n");
491  cpu->activateStage(O3CPU::CommitIdx);
492  }
493 
495 }
496 
497 template <class Impl>
498 bool
500 {
501  std::list<ThreadID>::iterator threads = activeThreads->begin();
503 
504  while (threads != end) {
505  ThreadID tid = *threads++;
506 
507  if (changedROBNumEntries[tid]) {
508  return true;
509  }
510  }
511 
512  return false;
513 }
514 
515 template <class Impl>
516 size_t
518 {
519  return rob->numFreeEntries(tid);
520 }
521 
522 template <class Impl>
523 void
525 {
526  DPRINTF(Commit, "Generating trap event for [tid:%i]\n", tid);
527 
529  [this, tid]{ processTrapEvent(tid); },
530  "Trap", true, Event::CPU_Tick_Pri);
531 
532  Cycles latency = std::dynamic_pointer_cast<SyscallRetryFault>(inst_fault) ?
533  cpu->syscallRetryLatency : trapLatency;
534 
535  // hardware transactional memory
536  if (inst_fault != nullptr &&
537  std::dynamic_pointer_cast<GenericHtmFailureFault>(inst_fault)) {
538  // TODO
539  // latency = default abort/restore latency
540  // could also do some kind of exponential back off if desired
541  }
542 
543  cpu->schedule(trap, cpu->clockEdge(latency));
544  trapInFlight[tid] = true;
545  thread[tid]->trapPending = true;
546 }
547 
548 template <class Impl>
549 void
551 {
552  assert(!trapInFlight[tid]);
553  DPRINTF(Commit, "Generating TC squash event for [tid:%i]\n", tid);
554 
555  tcSquash[tid] = true;
556 }
557 
558 template <class Impl>
559 void
561 {
562  // If we want to include the squashing instruction in the squash,
563  // then use one older sequence number.
564  // Hopefully this doesn't mess things up. Basically I want to squash
565  // all instructions of this thread.
566  InstSeqNum squashed_inst = rob->isEmpty(tid) ?
567  lastCommitedSeqNum[tid] : rob->readHeadInst(tid)->seqNum - 1;
568 
569  // All younger instructions will be squashed. Set the sequence
570  // number as the youngest instruction in the ROB (0 in this case.
571  // Hopefully nothing breaks.)
573 
574  rob->squash(squashed_inst, tid);
575  changedROBNumEntries[tid] = true;
576 
577  // Send back the sequence number of the squashed instruction.
578  toIEW->commitInfo[tid].doneSeqNum = squashed_inst;
579 
580  // Send back the squash signal to tell stages that they should
581  // squash.
582  toIEW->commitInfo[tid].squash = true;
583 
584  // Send back the rob squashing signal so other stages know that
585  // the ROB is in the process of squashing.
586  toIEW->commitInfo[tid].robSquashing = true;
587 
588  toIEW->commitInfo[tid].mispredictInst = NULL;
589  toIEW->commitInfo[tid].squashInst = NULL;
590 
591  toIEW->commitInfo[tid].pc = pc[tid];
592 }
593 
594 template <class Impl>
595 void
597 {
598  squashAll(tid);
599 
600  DPRINTF(Commit, "Squashing from trap, restarting at PC %s\n", pc[tid]);
601 
602  thread[tid]->trapPending = false;
603  thread[tid]->noSquashFromTC = false;
604  trapInFlight[tid] = false;
605 
606  trapSquash[tid] = false;
607 
608  commitStatus[tid] = ROBSquashing;
609  cpu->activityThisCycle();
610 }
611 
612 template <class Impl>
613 void
615 {
616  squashAll(tid);
617 
618  DPRINTF(Commit, "Squashing from TC, restarting at PC %s\n", pc[tid]);
619 
620  thread[tid]->noSquashFromTC = false;
621  assert(!thread[tid]->trapPending);
622 
623  commitStatus[tid] = ROBSquashing;
624  cpu->activityThisCycle();
625 
626  tcSquash[tid] = false;
627 }
628 
629 template <class Impl>
630 void
632 {
633  DPRINTF(Commit, "Squashing after squash after request, "
634  "restarting at PC %s\n", pc[tid]);
635 
636  squashAll(tid);
637  // Make sure to inform the fetch stage of which instruction caused
638  // the squash. It'll try to re-fetch an instruction executing in
639  // microcode unless this is set.
640  toIEW->commitInfo[tid].squashInst = squashAfterInst[tid];
641  squashAfterInst[tid] = NULL;
642 
643  commitStatus[tid] = ROBSquashing;
644  cpu->activityThisCycle();
645 }
646 
647 template <class Impl>
648 void
650 {
651  DPRINTF(Commit, "Executing squash after for [tid:%i] inst [sn:%llu]\n",
652  tid, head_inst->seqNum);
653 
654  assert(!squashAfterInst[tid] || squashAfterInst[tid] == head_inst);
656  squashAfterInst[tid] = head_inst;
657 }
658 
659 template <class Impl>
660 void
662 {
663  wroteToTimeBuffer = false;
665 
666  if (activeThreads->empty())
667  return;
668 
669  std::list<ThreadID>::iterator threads = activeThreads->begin();
671 
672  // Check if any of the threads are done squashing. Change the
673  // status if they are done.
674  while (threads != end) {
675  ThreadID tid = *threads++;
676 
677  // Clear the bit saying if the thread has committed stores
678  // this cycle.
679  committedStores[tid] = false;
680 
681  if (commitStatus[tid] == ROBSquashing) {
682 
683  if (rob->isDoneSquashing(tid)) {
684  commitStatus[tid] = Running;
685  } else {
686  DPRINTF(Commit,"[tid:%i] Still Squashing, cannot commit any"
687  " insts this cycle.\n", tid);
688  rob->doSquash(tid);
689  toIEW->commitInfo[tid].robSquashing = true;
690  wroteToTimeBuffer = true;
691  }
692  }
693  }
694 
695  commit();
696 
698 
699  threads = activeThreads->begin();
700 
701  while (threads != end) {
702  ThreadID tid = *threads++;
703 
704  if (!rob->isEmpty(tid) && rob->readHeadInst(tid)->readyToCommit()) {
705  // The ROB has more instructions it can commit. Its next status
706  // will be active.
708 
709  M5_VAR_USED const DynInstPtr &inst = rob->readHeadInst(tid);
710 
711  DPRINTF(Commit,"[tid:%i] Instruction [sn:%llu] PC %s is head of"
712  " ROB and ready to commit\n",
713  tid, inst->seqNum, inst->pcState());
714 
715  } else if (!rob->isEmpty(tid)) {
716  const DynInstPtr &inst = rob->readHeadInst(tid);
717 
718  ppCommitStall->notify(inst);
719 
720  DPRINTF(Commit,"[tid:%i] Can't commit, Instruction [sn:%llu] PC "
721  "%s is head of ROB and not ready\n",
722  tid, inst->seqNum, inst->pcState());
723  }
724 
725  DPRINTF(Commit, "[tid:%i] ROB has %d insts & %d free entries.\n",
726  tid, rob->countInsts(tid), rob->numFreeEntries(tid));
727  }
728 
729 
730  if (wroteToTimeBuffer) {
731  DPRINTF(Activity, "Activity This Cycle.\n");
732  cpu->activityThisCycle();
733  }
734 
735  updateStatus();
736 }
737 
738 template <class Impl>
739 void
741 {
742  // Verify that we still have an interrupt to handle
743  if (!cpu->checkInterrupts(0)) {
744  DPRINTF(Commit, "Pending interrupt is cleared by requestor before "
745  "it got handled. Restart fetching from the orig path.\n");
746  toIEW->commitInfo[0].clearInterrupt = true;
747  interrupt = NoFault;
748  avoidQuiesceLiveLock = true;
749  return;
750  }
751 
752  // Wait until all in flight instructions are finished before enterring
753  // the interrupt.
754  if (canHandleInterrupts && cpu->instList.empty()) {
755  // Squash or record that I need to squash this cycle if
756  // an interrupt needed to be handled.
757  DPRINTF(Commit, "Interrupt detected.\n");
758 
759  // Clear the interrupt now that it's going to be handled
760  toIEW->commitInfo[0].clearInterrupt = true;
761 
762  assert(!thread[0]->noSquashFromTC);
763  thread[0]->noSquashFromTC = true;
764 
765  if (cpu->checker) {
766  cpu->checker->handlePendingInt();
767  }
768 
769  // CPU will handle interrupt. Note that we ignore the local copy of
770  // interrupt. This is because the local copy may no longer be the
771  // interrupt that the interrupt controller thinks is being handled.
772  cpu->processInterrupts(cpu->getInterrupts());
773 
774  thread[0]->noSquashFromTC = false;
775 
777 
778  interrupt = NoFault;
779 
780  // Generate trap squash event.
782 
783  avoidQuiesceLiveLock = false;
784  } else {
785  DPRINTF(Commit, "Interrupt pending: instruction is %sin "
786  "flight, ROB is %sempty\n",
787  canHandleInterrupts ? "not " : "",
788  cpu->instList.empty() ? "" : "not " );
789  }
790 }
791 
792 template <class Impl>
793 void
795 {
796  // Don't propagate intterupts if we are currently handling a trap or
797  // in draining and the last observable instruction has been committed.
798  if (commitStatus[0] == TrapPending || interrupt || trapSquash[0] ||
799  tcSquash[0] || drainImminent)
800  return;
801 
802  // Process interrupts if interrupts are enabled, not in PAL
803  // mode, and no other traps or external squashes are currently
804  // pending.
805  // @todo: Allow other threads to handle interrupts.
806 
807  // Get any interrupt that happened
808  interrupt = cpu->getInterrupts();
809 
810  // Tell fetch that there is an interrupt pending. This
811  // will make fetch wait until it sees a non PAL-mode PC,
812  // at which point it stops fetching instructions.
813  if (interrupt != NoFault)
814  toIEW->commitInfo[0].interruptPending = true;
815 }
816 
817 template <class Impl>
818 void
820 {
821  if (FullSystem) {
822  // Check if we have a interrupt and get read to handle it
823  if (cpu->checkInterrupts(0))
825  }
826 
828  // Check for any possible squashes, handle them first
830  std::list<ThreadID>::iterator threads = activeThreads->begin();
832 
833  int num_squashing_threads = 0;
834 
835  while (threads != end) {
836  ThreadID tid = *threads++;
837 
838  // Not sure which one takes priority. I think if we have
839  // both, that's a bad sign.
840  if (trapSquash[tid]) {
841  assert(!tcSquash[tid]);
842  squashFromTrap(tid);
843 
844  // If the thread is trying to exit (i.e., an exit syscall was
845  // executed), this trapSquash was originated by the exit
846  // syscall earlier. In this case, schedule an exit event in
847  // the next cycle to fully terminate this thread
848  if (cpu->isThreadExiting(tid))
849  cpu->scheduleThreadExitEvent(tid);
850  } else if (tcSquash[tid]) {
851  assert(commitStatus[tid] != TrapPending);
852  squashFromTC(tid);
853  } else if (commitStatus[tid] == SquashAfterPending) {
854  // A squash from the previous cycle of the commit stage (i.e.,
855  // commitInsts() called squashAfter) is pending. Squash the
856  // thread now.
858  }
859 
860  // Squashed sequence number must be older than youngest valid
861  // instruction in the ROB. This prevents squashes from younger
862  // instructions overriding squashes from older instructions.
863  if (fromIEW->squash[tid] &&
864  commitStatus[tid] != TrapPending &&
865  fromIEW->squashedSeqNum[tid] <= youngestSeqNum[tid]) {
866 
867  if (fromIEW->mispredictInst[tid]) {
868  DPRINTF(Commit,
869  "[tid:%i] Squashing due to branch mispred "
870  "PC:%#x [sn:%llu]\n",
871  tid,
872  fromIEW->mispredictInst[tid]->instAddr(),
873  fromIEW->squashedSeqNum[tid]);
874  } else {
875  DPRINTF(Commit,
876  "[tid:%i] Squashing due to order violation [sn:%llu]\n",
877  tid, fromIEW->squashedSeqNum[tid]);
878  }
879 
880  DPRINTF(Commit, "[tid:%i] Redirecting to PC %#x\n",
881  tid,
882  fromIEW->pc[tid].nextInstAddr());
883 
884  commitStatus[tid] = ROBSquashing;
885 
886  // If we want to include the squashing instruction in the squash,
887  // then use one older sequence number.
888  InstSeqNum squashed_inst = fromIEW->squashedSeqNum[tid];
889 
890  if (fromIEW->includeSquashInst[tid]) {
891  squashed_inst--;
892  }
893 
894  // All younger instructions will be squashed. Set the sequence
895  // number as the youngest instruction in the ROB.
896  youngestSeqNum[tid] = squashed_inst;
897 
898  rob->squash(squashed_inst, tid);
899  changedROBNumEntries[tid] = true;
900 
901  toIEW->commitInfo[tid].doneSeqNum = squashed_inst;
902 
903  toIEW->commitInfo[tid].squash = true;
904 
905  // Send back the rob squashing signal so other stages know that
906  // the ROB is in the process of squashing.
907  toIEW->commitInfo[tid].robSquashing = true;
908 
909  toIEW->commitInfo[tid].mispredictInst =
910  fromIEW->mispredictInst[tid];
911  toIEW->commitInfo[tid].branchTaken =
912  fromIEW->branchTaken[tid];
913  toIEW->commitInfo[tid].squashInst =
914  rob->findInst(tid, squashed_inst);
915  if (toIEW->commitInfo[tid].mispredictInst) {
916  if (toIEW->commitInfo[tid].mispredictInst->isUncondCtrl()) {
917  toIEW->commitInfo[tid].branchTaken = true;
918  }
919  ++stats.branchMispredicts;
920  }
921 
922  toIEW->commitInfo[tid].pc = fromIEW->pc[tid];
923  }
924 
925  if (commitStatus[tid] == ROBSquashing) {
926  num_squashing_threads++;
927  }
928  }
929 
930  // If commit is currently squashing, then it will have activity for the
931  // next cycle. Set its next status as active.
932  if (num_squashing_threads) {
934  }
935 
936  if (num_squashing_threads != numThreads) {
937  // If we're not currently squashing, then get instructions.
938  getInsts();
939 
940  // Try to commit any instructions.
941  commitInsts();
942  }
943 
944  //Check for any activity
945  threads = activeThreads->begin();
946 
947  while (threads != end) {
948  ThreadID tid = *threads++;
949 
950  if (changedROBNumEntries[tid]) {
951  toIEW->commitInfo[tid].usedROB = true;
952  toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
953 
954  wroteToTimeBuffer = true;
955  changedROBNumEntries[tid] = false;
956  if (rob->isEmpty(tid))
957  checkEmptyROB[tid] = true;
958  }
959 
960  // ROB is only considered "empty" for previous stages if: a)
961  // ROB is empty, b) there are no outstanding stores, c) IEW
962  // stage has received any information regarding stores that
963  // committed.
964  // c) is checked by making sure to not consider the ROB empty
965  // on the same cycle as when stores have been committed.
966  // @todo: Make this handle multi-cycle communication between
967  // commit and IEW.
968  if (checkEmptyROB[tid] && rob->isEmpty(tid) &&
969  !iewStage->hasStoresToWB(tid) && !committedStores[tid]) {
970  checkEmptyROB[tid] = false;
971  toIEW->commitInfo[tid].usedROB = true;
972  toIEW->commitInfo[tid].emptyROB = true;
973  toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
974  wroteToTimeBuffer = true;
975  }
976 
977  }
978 }
979 
980 template <class Impl>
981 void
983 {
985  // Handle commit
986  // Note that commit will be handled prior to putting new
987  // instructions in the ROB so that the ROB only tries to commit
988  // instructions it has in this current cycle, and not instructions
989  // it is writing in during this cycle. Can't commit and squash
990  // things at the same time...
992 
993  DPRINTF(Commit, "Trying to commit instructions in the ROB.\n");
994 
995  unsigned num_committed = 0;
996 
997  DynInstPtr head_inst;
998 
999  // Commit as many instructions as possible until the commit bandwidth
1000  // limit is reached, or it becomes impossible to commit any more.
1001  while (num_committed < commitWidth) {
1002  // hardware transactionally memory
1003  // If executing within a transaction,
1004  // need to handle interrupts specially
1005 
1006  ThreadID commit_thread = getCommittingThread();
1007 
1008  // Check for any interrupt that we've already squashed for
1009  // and start processing it.
1010  if (interrupt != NoFault) {
1011  // If inside a transaction, postpone interrupts
1012  if (executingHtmTransaction(commit_thread)) {
1013  cpu->clearInterrupts(0);
1014  toIEW->commitInfo[0].clearInterrupt = true;
1015  interrupt = NoFault;
1016  avoidQuiesceLiveLock = true;
1017  } else {
1018  handleInterrupt();
1019  }
1020  }
1021 
1022  // ThreadID commit_thread = getCommittingThread();
1023 
1024  if (commit_thread == -1 || !rob->isHeadReady(commit_thread))
1025  break;
1026 
1027  head_inst = rob->readHeadInst(commit_thread);
1028 
1029  ThreadID tid = head_inst->threadNumber;
1030 
1031  assert(tid == commit_thread);
1032 
1033  DPRINTF(Commit,
1034  "Trying to commit head instruction, [tid:%i] [sn:%llu]\n",
1035  tid, head_inst->seqNum);
1036 
1037  // If the head instruction is squashed, it is ready to retire
1038  // (be removed from the ROB) at any time.
1039  if (head_inst->isSquashed()) {
1040 
1041  DPRINTF(Commit, "Retiring squashed instruction from "
1042  "ROB.\n");
1043 
1044  rob->retireHead(commit_thread);
1045 
1046  ++stats.commitSquashedInsts;
1047  // Notify potential listeners that this instruction is squashed
1048  ppSquash->notify(head_inst);
1049 
1050  // Record that the number of ROB entries has changed.
1051  changedROBNumEntries[tid] = true;
1052  } else {
1053  pc[tid] = head_inst->pcState();
1054 
1055  // Increment the total number of non-speculative instructions
1056  // executed.
1057  // Hack for now: it really shouldn't happen until after the
1058  // commit is deemed to be successful, but this count is needed
1059  // for syscalls.
1060  thread[tid]->funcExeInst++;
1061 
1062  // Try to commit the head instruction.
1063  bool commit_success = commitHead(head_inst, num_committed);
1064 
1065  if (commit_success) {
1066  ++num_committed;
1067  stats.committedInstType[tid][head_inst->opClass()]++;
1068  ppCommit->notify(head_inst);
1069 
1070  // hardware transactional memory
1071 
1072  // update nesting depth
1073  if (head_inst->isHtmStart())
1074  htmStarts[tid]++;
1075 
1076  // sanity check
1077  if (head_inst->inHtmTransactionalState()) {
1078  assert(executingHtmTransaction(tid));
1079  } else {
1080  assert(!executingHtmTransaction(tid));
1081  }
1082 
1083  // update nesting depth
1084  if (head_inst->isHtmStop())
1085  htmStops[tid]++;
1086 
1087  changedROBNumEntries[tid] = true;
1088 
1089  // Set the doneSeqNum to the youngest committed instruction.
1090  toIEW->commitInfo[tid].doneSeqNum = head_inst->seqNum;
1091 
1092  if (tid == 0)
1093  canHandleInterrupts = !head_inst->isDelayedCommit();
1094 
1095  // at this point store conditionals should either have
1096  // been completed or predicated false
1097  assert(!head_inst->isStoreConditional() ||
1098  head_inst->isCompleted() ||
1099  !head_inst->readPredicate());
1100 
1101  // Updates misc. registers.
1102  head_inst->updateMiscRegs();
1103 
1104  // Check instruction execution if it successfully commits and
1105  // is not carrying a fault.
1106  if (cpu->checker) {
1107  cpu->checker->verify(head_inst);
1108  }
1109 
1110  cpu->traceFunctions(pc[tid].instAddr());
1111 
1112  TheISA::advancePC(pc[tid], head_inst->staticInst);
1113 
1114  // Keep track of the last sequence number commited
1115  lastCommitedSeqNum[tid] = head_inst->seqNum;
1116 
1117  // If this is an instruction that doesn't play nicely with
1118  // others squash everything and restart fetch
1119  if (head_inst->isSquashAfter())
1120  squashAfter(tid, head_inst);
1121 
1122  if (drainPending) {
1123  if (pc[tid].microPC() == 0 && interrupt == NoFault &&
1124  !thread[tid]->trapPending) {
1125  // Last architectually committed instruction.
1126  // Squash the pipeline, stall fetch, and use
1127  // drainImminent to disable interrupts
1128  DPRINTF(Drain, "Draining: %i:%s\n", tid, pc[tid]);
1129  squashAfter(tid, head_inst);
1130  cpu->commitDrained(tid);
1131  drainImminent = true;
1132  }
1133  }
1134 
1135  bool onInstBoundary = !head_inst->isMicroop() ||
1136  head_inst->isLastMicroop() ||
1137  !head_inst->isDelayedCommit();
1138 
1139  if (onInstBoundary) {
1140  int count = 0;
1141  Addr oldpc;
1142  // Make sure we're not currently updating state while
1143  // handling PC events.
1144  assert(!thread[tid]->noSquashFromTC &&
1145  !thread[tid]->trapPending);
1146  do {
1147  oldpc = pc[tid].instAddr();
1148  thread[tid]->pcEventQueue.service(
1149  oldpc, thread[tid]->getTC());
1150  count++;
1151  } while (oldpc != pc[tid].instAddr());
1152  if (count > 1) {
1153  DPRINTF(Commit,
1154  "PC skip function event, stopping commit\n");
1155  break;
1156  }
1157  }
1158 
1159  // Check if an instruction just enabled interrupts and we've
1160  // previously had an interrupt pending that was not handled
1161  // because interrupts were subsequently disabled before the
1162  // pipeline reached a place to handle the interrupt. In that
1163  // case squash now to make sure the interrupt is handled.
1164  //
1165  // If we don't do this, we might end up in a live lock situation
1166  if (!interrupt && avoidQuiesceLiveLock &&
1167  onInstBoundary && cpu->checkInterrupts(0))
1168  squashAfter(tid, head_inst);
1169  } else {
1170  DPRINTF(Commit, "Unable to commit head instruction PC:%s "
1171  "[tid:%i] [sn:%llu].\n",
1172  head_inst->pcState(), tid ,head_inst->seqNum);
1173  break;
1174  }
1175  }
1176  }
1177 
1178  DPRINTF(CommitRate, "%i\n", num_committed);
1179  stats.numCommittedDist.sample(num_committed);
1180 
1181  if (num_committed == commitWidth) {
1182  stats.commitEligibleSamples++;
1183  }
1184 }
1185 
1186 template <class Impl>
1187 bool
1188 DefaultCommit<Impl>::commitHead(const DynInstPtr &head_inst, unsigned inst_num)
1189 {
1190  assert(head_inst);
1191 
1192  ThreadID tid = head_inst->threadNumber;
1193 
1194  // If the instruction is not executed yet, then it will need extra
1195  // handling. Signal backwards that it should be executed.
1196  if (!head_inst->isExecuted()) {
1197  // Keep this number correct. We have not yet actually executed
1198  // and committed this instruction.
1199  thread[tid]->funcExeInst--;
1200 
1201  // Make sure we are only trying to commit un-executed instructions we
1202  // think are possible.
1203  assert(head_inst->isNonSpeculative() || head_inst->isStoreConditional()
1204  || head_inst->isReadBarrier() || head_inst->isWriteBarrier()
1205  || head_inst->isAtomic()
1206  || (head_inst->isLoad() && head_inst->strictlyOrdered()));
1207 
1208  DPRINTF(Commit,
1209  "Encountered a barrier or non-speculative "
1210  "instruction [tid:%i] [sn:%llu] "
1211  "at the head of the ROB, PC %s.\n",
1212  tid, head_inst->seqNum, head_inst->pcState());
1213 
1214  if (inst_num > 0 || iewStage->hasStoresToWB(tid)) {
1215  DPRINTF(Commit,
1216  "[tid:%i] [sn:%llu] "
1217  "Waiting for all stores to writeback.\n",
1218  tid, head_inst->seqNum);
1219  return false;
1220  }
1221 
1222  toIEW->commitInfo[tid].nonSpecSeqNum = head_inst->seqNum;
1223 
1224  // Change the instruction so it won't try to commit again until
1225  // it is executed.
1226  head_inst->clearCanCommit();
1227 
1228  if (head_inst->isLoad() && head_inst->strictlyOrdered()) {
1229  DPRINTF(Commit, "[tid:%i] [sn:%llu] "
1230  "Strictly ordered load, PC %s.\n",
1231  tid, head_inst->seqNum, head_inst->pcState());
1232  toIEW->commitInfo[tid].strictlyOrdered = true;
1233  toIEW->commitInfo[tid].strictlyOrderedLoad = head_inst;
1234  } else {
1235  ++stats.commitNonSpecStalls;
1236  }
1237 
1238  return false;
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->regs.flattenedDestIdx(i),
1353  head_inst->regs.renamedDestIdx(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->isFullMemBarrier()) {
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.vectorInstructions[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  std::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  std::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:661
InvalidThreadID
const ThreadID InvalidThreadID
Definition: types.hh:234
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:614
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:149
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:524
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:201
DefaultCommit::squashFromSquashAfter
void squashFromSquashAfter(ThreadID tid)
Handles a squash from a squashAfter() request.
Definition: commit_impl.hh:631
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:418
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:456
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:233
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:649
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:549
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:486
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:359
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:560
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:156
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:516
FullSystem
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:204
DefaultCommit::clearStates
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition: commit_impl.hh:343
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:299
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:499
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:392
DefaultCommit::DefaultCommit
DefaultCommit(O3CPU *_cpu, const DerivO3CPUParams &params)
Construct a DefaultCommit with the given parameters.
Definition: commit_impl.hh:79
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:1112
Stats::DataWrap::flags
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:339
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:459
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:374
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:353
DefaultCommit::setROB
void setROB(ROB *rob_ptr)
Sets pointer to the ROB.
Definition: commit_impl.hh:315
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:237
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:71
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:246
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:142
cpu.hh
ROB::drainSanityCheck
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: rob_impl.hh:133
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:215
DefaultCommit::setActiveThreads
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to list of active threads.
Definition: commit_impl.hh:300
DefaultCommit::handleInterrupt
void handleInterrupt()
Handles processing an interrupt.
Definition: commit_impl.hh:740
DefaultCommit::CommitStats::vectorInstructions
Stats::Vector vectorInstructions
Total number of vector instructions.
Definition: commit.hh:515
thread_state.hh
DefaultCommit::processTrapEvent
void processTrapEvent(ThreadID tid)
Mark the thread as processing a trap.
Definition: commit_impl.hh:71
DefaultCommit::regProbePoints
void regProbePoints()
Registers probes.
Definition: commit_impl.hh:139
DefaultCommit::setTimeBuffer
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets the main time buffer pointer, used for backwards communication.
Definition: commit_impl.hh:250
ROB::doSquash
void doSquash(ThreadID tid)
Executes the squash, marking squashed instructions.
Definition: rob_impl.hh:319
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:468
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:273
InstSeqNum
uint64_t InstSeqNum
Definition: inst_seq.hh:37
UNIT_COUNT
#define UNIT_COUNT
Definition: units.hh:49
NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:251
DefaultCommit::name
std::string name() const
Returns the name of the DefaultCommit.
Definition: commit_impl.hh:132
ROB::isHeadReady
bool isHeadReady(ThreadID tid)
Is the oldest instruction across all threads ready.
Definition: rob_impl.hh:274
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:148
DefaultCommit::TrapPending
@ TrapPending
Definition: commit.hh:115
StaticInst::nullStaticInstPtr
static StaticInstPtr nullStaticInstPtr
Pointer to a statically allocated "null" instruction object.
Definition: static_inst.hh:253
Stats::dist
const FlagsType dist
Print the distribution.
Definition: info.hh:56
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:1028
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:550
DefaultCommit::startupStage
void startupStage()
Initializes stage by sending back the number of free entries.
Definition: commit_impl.hh:322
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:1188
DefaultCommit::CommitStats::CommitStats
CommitStats(O3CPU *cpu, DefaultCommit *commit)
Definition: commit_impl.hh:147
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:390
DefaultCommit::RenameMap
CPUPol::RenameMap RenameMap
Definition: commit.hh:89
DefaultCommit::drainResume
void drainResume()
Resumes execution after draining.
Definition: commit_impl.hh:366
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:283
DefaultCommit::propagateInterrupt
void propagateInterrupt()
Get fetch redirecting so we can handle an interrupt.
Definition: commit_impl.hh:794
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:263
DefaultCommit::setRenameMap
void setRenameMap(RenameMap rm_ptr[Impl::MaxThreads])
Sets pointer to the commited state rename map.
Definition: commit_impl.hh:307
DefaultCommit::squashFromTrap
void squashFromTrap(ThreadID tid)
Handles squashing due to a trap.
Definition: commit_impl.hh:596
ROB::retireHead
void retireHead(ThreadID tid)
Retires the head instruction, removing it from the ROB.
Definition: rob_impl.hh:239
Stats::Distribution::init
Distribution & init(Counter min, Counter max, Counter bkt)
Set the parameters of this distribution.
Definition: statistics.hh:2113
Stats::pdf
const FlagsType pdf
Print the percent of the total that this entry represents.
Definition: info.hh:52
Stats::Vector2dBase::init
Derived & init(size_type _x, size_type _y)
Definition: statistics.hh:1166
logging.hh
Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:79
UNIT_CYCLE
#define UNIT_CYCLE
Convenience macros to declare the unit of a stat.
Definition: units.hh:39
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:183
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:982
Stats
Definition: statistics.cc:53
curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:43
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:434
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:819
DefaultCommit::setIEWStage
void setIEWStage(IEW *iew_stage)
Sets the pointer to the IEW stage.
Definition: commit_impl.hh:293
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:50
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:305
DefaultCommit::setThreads
void setThreads(std::vector< Thread * > &threads)
Sets the list of threads.
Definition: commit_impl.hh:243
DefaultCommit::executingHtmTransaction
bool executingHtmTransaction(ThreadID) const
Is the CPU currently processing a HTM transaction?
Definition: commit_impl.hh:446
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
ROB::insertInst
void insertInst(const DynInstPtr &inst)
Function to insert an instruction into the ROB.
Definition: rob_impl.hh:202
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:125
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:517

Generated on Tue Mar 23 2021 19:41:24 for gem5 by doxygen 1.8.17