gem5  v22.1.0.0
rename.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2012, 2014-2019 ARM Limited
3  * Copyright (c) 2013 Advanced Micro Devices, Inc.
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 
42 #include "cpu/o3/rename.hh"
43 
44 #include <list>
45 
46 #include "cpu/o3/cpu.hh"
47 #include "cpu/o3/dyn_inst.hh"
48 #include "cpu/o3/limits.hh"
49 #include "cpu/reg_class.hh"
50 #include "debug/Activity.hh"
51 #include "debug/O3PipeView.hh"
52 #include "debug/Rename.hh"
53 #include "params/BaseO3CPU.hh"
54 
55 namespace gem5
56 {
57 
58 namespace o3
59 {
60 
61 Rename::Rename(CPU *_cpu, const BaseO3CPUParams &params)
62  : cpu(_cpu),
63  iewToRenameDelay(params.iewToRenameDelay),
64  decodeToRenameDelay(params.decodeToRenameDelay),
65  commitToRenameDelay(params.commitToRenameDelay),
66  renameWidth(params.renameWidth),
67  numThreads(params.numThreads),
68  stats(_cpu)
69 {
70  if (renameWidth > MaxWidth)
71  fatal("renameWidth (%d) is larger than compiled limit (%d),\n"
72  "\tincrease MaxWidth in src/cpu/o3/limits.hh\n",
73  renameWidth, static_cast<int>(MaxWidth));
74 
75  // @todo: Make into a parameter.
76  skidBufferMax = (decodeToRenameDelay + 1) * params.decodeWidth;
77  for (uint32_t tid = 0; tid < MaxThreads; tid++) {
78  renameStatus[tid] = Idle;
79  renameMap[tid] = nullptr;
80  instsInProgress[tid] = 0;
81  loadsInProgress[tid] = 0;
82  storesInProgress[tid] = 0;
83  freeEntries[tid] = {0, 0, 0, 0};
84  emptyROB[tid] = true;
85  stalls[tid] = {false, false};
86  serializeInst[tid] = nullptr;
87  serializeOnNextInst[tid] = false;
88  }
89 }
90 
91 std::string
92 Rename::name() const
93 {
94  return cpu->name() + ".rename";
95 }
96 
98  : statistics::Group(parent, "rename"),
99  ADD_STAT(squashCycles, statistics::units::Cycle::get(),
100  "Number of cycles rename is squashing"),
101  ADD_STAT(idleCycles, statistics::units::Cycle::get(),
102  "Number of cycles rename is idle"),
103  ADD_STAT(blockCycles, statistics::units::Cycle::get(),
104  "Number of cycles rename is blocking"),
105  ADD_STAT(serializeStallCycles, statistics::units::Cycle::get(),
106  "count of cycles rename stalled for serializing inst"),
107  ADD_STAT(runCycles, statistics::units::Cycle::get(),
108  "Number of cycles rename is running"),
109  ADD_STAT(unblockCycles, statistics::units::Cycle::get(),
110  "Number of cycles rename is unblocking"),
111  ADD_STAT(renamedInsts, statistics::units::Count::get(),
112  "Number of instructions processed by rename"),
113  ADD_STAT(squashedInsts, statistics::units::Count::get(),
114  "Number of squashed instructions processed by rename"),
115  ADD_STAT(ROBFullEvents, statistics::units::Count::get(),
116  "Number of times rename has blocked due to ROB full"),
117  ADD_STAT(IQFullEvents, statistics::units::Count::get(),
118  "Number of times rename has blocked due to IQ full"),
119  ADD_STAT(LQFullEvents, statistics::units::Count::get(),
120  "Number of times rename has blocked due to LQ full" ),
121  ADD_STAT(SQFullEvents, statistics::units::Count::get(),
122  "Number of times rename has blocked due to SQ full"),
123  ADD_STAT(fullRegistersEvents, statistics::units::Count::get(),
124  "Number of times there has been no free registers"),
125  ADD_STAT(renamedOperands, statistics::units::Count::get(),
126  "Number of destination operands rename has renamed"),
127  ADD_STAT(lookups, statistics::units::Count::get(),
128  "Number of register rename lookups that rename has made"),
129  ADD_STAT(intLookups, statistics::units::Count::get(),
130  "Number of integer rename lookups"),
131  ADD_STAT(fpLookups, statistics::units::Count::get(),
132  "Number of floating rename lookups"),
133  ADD_STAT(vecLookups, statistics::units::Count::get(),
134  "Number of vector rename lookups"),
135  ADD_STAT(vecPredLookups, statistics::units::Count::get(),
136  "Number of vector predicate rename lookups"),
137  ADD_STAT(committedMaps, statistics::units::Count::get(),
138  "Number of HB maps that are committed"),
139  ADD_STAT(undoneMaps, statistics::units::Count::get(),
140  "Number of HB maps that are undone due to squashing"),
141  ADD_STAT(serializing, statistics::units::Count::get(),
142  "count of serializing insts renamed"),
143  ADD_STAT(tempSerializing, statistics::units::Count::get(),
144  "count of temporary serializing insts renamed"),
145  ADD_STAT(skidInsts, statistics::units::Count::get(),
146  "count of insts added to the skid buffer")
147 {
154 
157 
163 
170 
176 }
177 
178 void
180 {
182  cpu->getProbeManager(), "Rename");
184  "SquashInRename");
185 }
186 
187 void
189 {
190  timeBuffer = tb_ptr;
191 
192  // Setup wire to read information from time buffer, from IEW stage.
193  fromIEW = timeBuffer->getWire(-iewToRenameDelay);
194 
195  // Setup wire to read infromation from time buffer, from commit stage.
197 
198  // Setup wire to write information to previous stages.
199  toDecode = timeBuffer->getWire(0);
200 }
201 
202 void
204 {
205  renameQueue = rq_ptr;
206 
207  // Setup wire to write information to future stages.
208  toIEW = renameQueue->getWire(0);
209 }
210 
211 void
213 {
214  decodeQueue = dq_ptr;
215 
216  // Setup wire to get information from decode.
218 }
219 
220 void
222 {
223  resetStage();
224 }
225 
226 void
228 {
229  renameStatus[tid] = Idle;
230 
235  emptyROB[tid] = true;
236 
237  stalls[tid].iew = false;
238  serializeInst[tid] = NULL;
239 
240  instsInProgress[tid] = 0;
241  loadsInProgress[tid] = 0;
242  storesInProgress[tid] = 0;
243 
244  serializeOnNextInst[tid] = false;
245 }
246 
247 void
249 {
250  _status = Inactive;
251 
252  resumeSerialize = false;
253  resumeUnblocking = false;
254 
255  // Grab the number of free entries directly from the stages.
256  for (ThreadID tid = 0; tid < numThreads; tid++) {
257  renameStatus[tid] = Idle;
258 
260  freeEntries[tid].lqEntries =
262  freeEntries[tid].sqEntries =
265  emptyROB[tid] = true;
266 
267  stalls[tid].iew = false;
268  serializeInst[tid] = NULL;
269 
270  instsInProgress[tid] = 0;
271  loadsInProgress[tid] = 0;
272  storesInProgress[tid] = 0;
273 
274  serializeOnNextInst[tid] = false;
275  }
276 }
277 
278 void
280 {
281  activeThreads = at_ptr;
282 }
283 
284 
285 void
287 {
288  for (ThreadID tid = 0; tid < numThreads; tid++)
289  renameMap[tid] = &rm_ptr[tid];
290 }
291 
292 void
294 {
295  freeList = fl_ptr;
296 }
297 
298 void
300 {
301  scoreboard = _scoreboard;
302 }
303 
304 bool
306 {
307  for (ThreadID tid = 0; tid < numThreads; tid++) {
308  if (instsInProgress[tid] != 0 ||
309  !historyBuffer[tid].empty() ||
310  !skidBuffer[tid].empty() ||
311  !insts[tid].empty() ||
312  (renameStatus[tid] != Idle && renameStatus[tid] != Running))
313  return false;
314  }
315  return true;
316 }
317 
318 void
320 {
321  resetStage();
322 }
323 
324 void
326 {
327  for (ThreadID tid = 0; tid < numThreads; tid++) {
328  assert(historyBuffer[tid].empty());
329  assert(insts[tid].empty());
330  assert(skidBuffer[tid].empty());
331  assert(instsInProgress[tid] == 0);
332  }
333 }
334 
335 void
336 Rename::squash(const InstSeqNum &squash_seq_num, ThreadID tid)
337 {
338  DPRINTF(Rename, "[tid:%i] [squash sn:%llu] Squashing instructions.\n",
339  tid,squash_seq_num);
340 
341  // Clear the stall signal if rename was blocked or unblocking before.
342  // If it still needs to block, the blocking should happen the next
343  // cycle and there should be space to hold everything due to the squash.
344  if (renameStatus[tid] == Blocked ||
345  renameStatus[tid] == Unblocking) {
346  toDecode->renameUnblock[tid] = 1;
347 
348  resumeSerialize = false;
349  serializeInst[tid] = NULL;
350  } else if (renameStatus[tid] == SerializeStall) {
351  if (serializeInst[tid]->seqNum <= squash_seq_num) {
352  DPRINTF(Rename, "[tid:%i] [squash sn:%llu] "
353  "Rename will resume serializing after squash\n",
354  tid,squash_seq_num);
355  resumeSerialize = true;
356  assert(serializeInst[tid]);
357  } else {
358  resumeSerialize = false;
359  toDecode->renameUnblock[tid] = 1;
360 
361  serializeInst[tid] = NULL;
362  }
363  }
364 
365  // Set the status to Squashing.
366  renameStatus[tid] = Squashing;
367 
368  // Squash any instructions from decode.
369  for (int i=0; i<fromDecode->size; i++) {
370  if (fromDecode->insts[i]->threadNumber == tid &&
371  fromDecode->insts[i]->seqNum > squash_seq_num) {
372  fromDecode->insts[i]->setSquashed();
373  wroteToTimeBuffer = true;
374  }
375 
376  }
377 
378  // Clear the instruction list and skid buffer in case they have any
379  // insts in them.
380  insts[tid].clear();
381 
382  // Clear the skid buffer in case it has any data in it.
383  skidBuffer[tid].clear();
384 
385  doSquash(squash_seq_num, tid);
386 }
387 
388 void
390 {
391  wroteToTimeBuffer = false;
392 
393  blockThisCycle = false;
394 
395  bool status_change = false;
396 
397  toIEWIndex = 0;
398 
399  sortInsts();
400 
401  std::list<ThreadID>::iterator threads = activeThreads->begin();
403 
404  // Check stall and squash signals.
405  while (threads != end) {
406  ThreadID tid = *threads++;
407 
408  DPRINTF(Rename, "Processing [tid:%i]\n", tid);
409 
410  status_change = checkSignalsAndUpdate(tid) || status_change;
411 
412  rename(status_change, tid);
413  }
414 
415  if (status_change) {
416  updateStatus();
417  }
418 
419  if (wroteToTimeBuffer) {
420  DPRINTF(Activity, "Activity this cycle.\n");
422  }
423 
424  threads = activeThreads->begin();
425 
426  while (threads != end) {
427  ThreadID tid = *threads++;
428 
429  // If we committed this cycle then doneSeqNum will be > 0
430  if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
431  !fromCommit->commitInfo[tid].squash &&
432  renameStatus[tid] != Squashing) {
433 
434  removeFromHistory(fromCommit->commitInfo[tid].doneSeqNum,
435  tid);
436  }
437  }
438 
439  // @todo: make into updateProgress function
440  for (ThreadID tid = 0; tid < numThreads; tid++) {
441  instsInProgress[tid] -= fromIEW->iewInfo[tid].dispatched;
442  loadsInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToLQ;
443  storesInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToSQ;
444  assert(loadsInProgress[tid] >= 0);
445  assert(storesInProgress[tid] >= 0);
446  assert(instsInProgress[tid] >=0);
447  }
448 
449 }
450 
451 void
452 Rename::rename(bool &status_change, ThreadID tid)
453 {
454  // If status is Running or idle,
455  // call renameInsts()
456  // If status is Unblocking,
457  // buffer any instructions coming from decode
458  // continue trying to empty skid buffer
459  // check if stall conditions have passed
460 
461  if (renameStatus[tid] == Blocked) {
462  ++stats.blockCycles;
463  } else if (renameStatus[tid] == Squashing) {
465  } else if (renameStatus[tid] == SerializeStall) {
467  // If we are currently in SerializeStall and resumeSerialize
468  // was set, then that means that we are resuming serializing
469  // this cycle. Tell the previous stages to block.
470  if (resumeSerialize) {
471  resumeSerialize = false;
472  block(tid);
473  toDecode->renameUnblock[tid] = false;
474  }
475  } else if (renameStatus[tid] == Unblocking) {
476  if (resumeUnblocking) {
477  block(tid);
478  resumeUnblocking = false;
479  toDecode->renameUnblock[tid] = false;
480  }
481  }
482 
483  if (renameStatus[tid] == Running ||
484  renameStatus[tid] == Idle) {
485  DPRINTF(Rename,
486  "[tid:%i] "
487  "Not blocked, so attempting to run stage.\n",
488  tid);
489 
490  renameInsts(tid);
491  } else if (renameStatus[tid] == Unblocking) {
492  renameInsts(tid);
493 
494  if (validInsts()) {
495  // Add the current inputs to the skid buffer so they can be
496  // reprocessed when this stage unblocks.
497  skidInsert(tid);
498  }
499 
500  // If we switched over to blocking, then there's a potential for
501  // an overall status change.
502  status_change = unblock(tid) || status_change || blockThisCycle;
503  }
504 }
505 
506 void
508 {
509  // Instructions can be either in the skid buffer or the queue of
510  // instructions coming from decode, depending on the status.
511  int insts_available = renameStatus[tid] == Unblocking ?
512  skidBuffer[tid].size() : insts[tid].size();
513 
514  // Check the decode queue to see if instructions are available.
515  // If there are no available instructions to rename, then do nothing.
516  if (insts_available == 0) {
517  DPRINTF(Rename, "[tid:%i] Nothing to do, breaking out early.\n",
518  tid);
519  // Should I change status to idle?
520  ++stats.idleCycles;
521  return;
522  } else if (renameStatus[tid] == Unblocking) {
524  } else if (renameStatus[tid] == Running) {
525  ++stats.runCycles;
526  }
527 
528  // Will have to do a different calculation for the number of free
529  // entries.
530  int free_rob_entries = calcFreeROBEntries(tid);
531  int free_iq_entries = calcFreeIQEntries(tid);
532  int min_free_entries = free_rob_entries;
533 
534  FullSource source = ROB;
535 
536  if (free_iq_entries < min_free_entries) {
537  min_free_entries = free_iq_entries;
538  source = IQ;
539  }
540 
541  // Check if there's any space left.
542  if (min_free_entries <= 0) {
543  DPRINTF(Rename,
544  "[tid:%i] Blocking due to no free ROB/IQ/ entries.\n"
545  "ROB has %i free entries.\n"
546  "IQ has %i free entries.\n",
547  tid, free_rob_entries, free_iq_entries);
548 
549  blockThisCycle = true;
550 
551  block(tid);
552 
553  incrFullStat(source);
554 
555  return;
556  } else if (min_free_entries < insts_available) {
557  DPRINTF(Rename,
558  "[tid:%i] "
559  "Will have to block this cycle. "
560  "%i insts available, "
561  "but only %i insts can be renamed due to ROB/IQ/LSQ limits.\n",
562  tid, insts_available, min_free_entries);
563 
564  insts_available = min_free_entries;
565 
566  blockThisCycle = true;
567 
568  incrFullStat(source);
569  }
570 
571  InstQueue &insts_to_rename = renameStatus[tid] == Unblocking ?
572  skidBuffer[tid] : insts[tid];
573 
574  DPRINTF(Rename,
575  "[tid:%i] "
576  "%i available instructions to send iew.\n",
577  tid, insts_available);
578 
579  DPRINTF(Rename,
580  "[tid:%i] "
581  "%i insts pipelining from Rename | "
582  "%i insts dispatched to IQ last cycle.\n",
583  tid, instsInProgress[tid], fromIEW->iewInfo[tid].dispatched);
584 
585  // Handle serializing the next instruction if necessary.
586  if (serializeOnNextInst[tid]) {
587  if (emptyROB[tid] && instsInProgress[tid] == 0) {
588  // ROB already empty; no need to serialize.
589  serializeOnNextInst[tid] = false;
590  } else if (!insts_to_rename.empty()) {
591  insts_to_rename.front()->setSerializeBefore();
592  }
593  }
594 
595  int renamed_insts = 0;
596 
597  while (insts_available > 0 && toIEWIndex < renameWidth) {
598  DPRINTF(Rename, "[tid:%i] Sending instructions to IEW.\n", tid);
599 
600  assert(!insts_to_rename.empty());
601 
602  DynInstPtr inst = insts_to_rename.front();
603 
604  //For all kind of instructions, check ROB and IQ first For load
605  //instruction, check LQ size and take into account the inflight loads
606  //For store instruction, check SQ size and take into account the
607  //inflight stores
608 
609  if (inst->isLoad()) {
610  if (calcFreeLQEntries(tid) <= 0) {
611  DPRINTF(Rename, "[tid:%i] Cannot rename due to no free LQ\n",
612  tid);
613  source = LQ;
614  incrFullStat(source);
615  break;
616  }
617  }
618 
619  if (inst->isStore() || inst->isAtomic()) {
620  if (calcFreeSQEntries(tid) <= 0) {
621  DPRINTF(Rename, "[tid:%i] Cannot rename due to no free SQ\n",
622  tid);
623  source = SQ;
624  incrFullStat(source);
625  break;
626  }
627  }
628 
629  insts_to_rename.pop_front();
630 
631  if (renameStatus[tid] == Unblocking) {
632  DPRINTF(Rename,
633  "[tid:%i] "
634  "Removing [sn:%llu] PC:%s from rename skidBuffer\n",
635  tid, inst->seqNum, inst->pcState());
636  }
637 
638  if (inst->isSquashed()) {
639  DPRINTF(Rename,
640  "[tid:%i] "
641  "instruction %i with PC %s is squashed, skipping.\n",
642  tid, inst->seqNum, inst->pcState());
643 
645 
646  // Decrement how many instructions are available.
647  --insts_available;
648 
649  continue;
650  }
651 
652  DPRINTF(Rename,
653  "[tid:%i] "
654  "Processing instruction [sn:%llu] with PC %s.\n",
655  tid, inst->seqNum, inst->pcState());
656 
657  // Check here to make sure there are enough destination registers
658  // to rename to. Otherwise block.
659  if (!renameMap[tid]->canRename(inst)) {
660  DPRINTF(Rename,
661  "Blocking due to "
662  " lack of free physical registers to rename to.\n");
663  blockThisCycle = true;
664  insts_to_rename.push_front(inst);
666 
667  break;
668  }
669 
670  // Handle serializeAfter/serializeBefore instructions.
671  // serializeAfter marks the next instruction as serializeBefore.
672  // serializeBefore makes the instruction wait in rename until the ROB
673  // is empty.
674 
675  // In this model, IPR accesses are serialize before
676  // instructions, and store conditionals are serialize after
677  // instructions. This is mainly due to lack of support for
678  // out-of-order operations of either of those classes of
679  // instructions.
680  if (inst->isSerializeBefore() && !inst->isSerializeHandled()) {
681  DPRINTF(Rename, "Serialize before instruction encountered.\n");
682 
683  if (!inst->isTempSerializeBefore()) {
684  stats.serializing++;
685  inst->setSerializeHandled();
686  } else {
688  }
689 
690  // Change status over to SerializeStall so that other stages know
691  // what this is blocked on.
693 
694  serializeInst[tid] = inst;
695 
696  blockThisCycle = true;
697 
698  break;
699  } else if ((inst->isStoreConditional() || inst->isSerializeAfter()) &&
700  !inst->isSerializeHandled()) {
701  DPRINTF(Rename, "Serialize after instruction encountered.\n");
702 
703  stats.serializing++;
704 
705  inst->setSerializeHandled();
706 
707  serializeAfter(insts_to_rename, tid);
708  }
709 
710  renameSrcRegs(inst, inst->threadNumber);
711 
712  renameDestRegs(inst, inst->threadNumber);
713 
714  if (inst->isAtomic() || inst->isStore()) {
715  storesInProgress[tid]++;
716  } else if (inst->isLoad()) {
717  loadsInProgress[tid]++;
718  }
719 
720  ++renamed_insts;
721  // Notify potential listeners that source and destination registers for
722  // this instruction have been renamed.
723  ppRename->notify(inst);
724 
725  // Put instruction in rename queue.
726  toIEW->insts[toIEWIndex] = inst;
727  ++(toIEW->size);
728 
729  // Increment which instruction we're on.
730  ++toIEWIndex;
731 
732  // Decrement how many instructions are available.
733  --insts_available;
734  }
735 
736  instsInProgress[tid] += renamed_insts;
737  stats.renamedInsts += renamed_insts;
738 
739  // If we wrote to the time buffer, record this.
740  if (toIEWIndex) {
741  wroteToTimeBuffer = true;
742  }
743 
744  // Check if there's any instructions left that haven't yet been renamed.
745  // If so then block.
746  if (insts_available) {
747  blockThisCycle = true;
748  }
749 
750  if (blockThisCycle) {
751  block(tid);
752  toDecode->renameUnblock[tid] = false;
753  }
754 }
755 
756 void
758 {
759  DynInstPtr inst = NULL;
760 
761  while (!insts[tid].empty()) {
762  inst = insts[tid].front();
763 
764  insts[tid].pop_front();
765 
766  assert(tid == inst->threadNumber);
767 
768  DPRINTF(Rename, "[tid:%i] Inserting [sn:%llu] PC: %s into Rename "
769  "skidBuffer\n", tid, inst->seqNum, inst->pcState());
770 
771  ++stats.skidInsts;
772 
773  skidBuffer[tid].push_back(inst);
774  }
775 
776  if (skidBuffer[tid].size() > skidBufferMax) {
777  InstQueue::iterator it;
778  warn("Skidbuffer contents:\n");
779  for (it = skidBuffer[tid].begin(); it != skidBuffer[tid].end(); it++) {
780  warn("[tid:%i] %s [sn:%llu].\n", tid,
781  (*it)->staticInst->disassemble(
782  inst->pcState().instAddr()),
783  (*it)->seqNum);
784  }
785  panic("Skidbuffer Exceeded Max Size");
786  }
787 }
788 
789 void
791 {
792  int insts_from_decode = fromDecode->size;
793  for (int i = 0; i < insts_from_decode; ++i) {
794  const DynInstPtr &inst = fromDecode->insts[i];
795  insts[inst->threadNumber].push_back(inst);
796 #if TRACING_ON
797  if (debug::O3PipeView) {
798  inst->renameTick = curTick() - inst->fetchTick;
799  }
800 #endif
801  }
802 }
803 
804 bool
806 {
807  std::list<ThreadID>::iterator threads = activeThreads->begin();
809 
810  while (threads != end) {
811  ThreadID tid = *threads++;
812 
813  if (!skidBuffer[tid].empty())
814  return false;
815  }
816 
817  return true;
818 }
819 
820 void
822 {
823  bool any_unblocking = false;
824 
825  std::list<ThreadID>::iterator threads = activeThreads->begin();
827 
828  while (threads != end) {
829  ThreadID tid = *threads++;
830 
831  if (renameStatus[tid] == Unblocking) {
832  any_unblocking = true;
833  break;
834  }
835  }
836 
837  // Rename will have activity if it's unblocking.
838  if (any_unblocking) {
839  if (_status == Inactive) {
840  _status = Active;
841 
842  DPRINTF(Activity, "Activating stage.\n");
843 
845  }
846  } else {
847  // If it's not unblocking, then rename will not have any internal
848  // activity. Switch it to inactive.
849  if (_status == Active) {
850  _status = Inactive;
851  DPRINTF(Activity, "Deactivating stage.\n");
852 
854  }
855  }
856 }
857 
858 bool
860 {
861  DPRINTF(Rename, "[tid:%i] Blocking.\n", tid);
862 
863  // Add the current inputs onto the skid buffer, so they can be
864  // reprocessed when this stage unblocks.
865  skidInsert(tid);
866 
867  // Only signal backwards to block if the previous stages do not think
868  // rename is already blocked.
869  if (renameStatus[tid] != Blocked) {
870  // If resumeUnblocking is set, we unblocked during the squash,
871  // but now we're have unblocking status. We need to tell earlier
872  // stages to block.
873  if (resumeUnblocking || renameStatus[tid] != Unblocking) {
874  toDecode->renameBlock[tid] = true;
875  toDecode->renameUnblock[tid] = false;
876  wroteToTimeBuffer = true;
877  }
878 
879  // Rename can not go from SerializeStall to Blocked, otherwise
880  // it would not know to complete the serialize stall.
881  if (renameStatus[tid] != SerializeStall) {
882  // Set status to Blocked.
883  renameStatus[tid] = Blocked;
884  return true;
885  }
886  }
887 
888  return false;
889 }
890 
891 bool
893 {
894  DPRINTF(Rename, "[tid:%i] Trying to unblock.\n", tid);
895 
896  // Rename is done unblocking if the skid buffer is empty.
897  if (skidBuffer[tid].empty() && renameStatus[tid] != SerializeStall) {
898 
899  DPRINTF(Rename, "[tid:%i] Done unblocking.\n", tid);
900 
901  toDecode->renameUnblock[tid] = true;
902  wroteToTimeBuffer = true;
903 
904  renameStatus[tid] = Running;
905  return true;
906  }
907 
908  return false;
909 }
910 
911 void
912 Rename::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid)
913 {
914  auto hb_it = historyBuffer[tid].begin();
915 
916  // After a syscall squashes everything, the history buffer may be empty
917  // but the ROB may still be squashing instructions.
918  // Go through the most recent instructions, undoing the mappings
919  // they did and freeing up the registers.
920  while (!historyBuffer[tid].empty() &&
921  hb_it->instSeqNum > squashed_seq_num) {
922  assert(hb_it != historyBuffer[tid].end());
923 
924  DPRINTF(Rename, "[tid:%i] Removing history entry with sequence "
925  "number %i (archReg: %d, newPhysReg: %d, prevPhysReg: %d).\n",
926  tid, hb_it->instSeqNum, hb_it->archReg.index(),
927  hb_it->newPhysReg->index(), hb_it->prevPhysReg->index());
928 
929  // Undo the rename mapping only if it was really a change.
930  // Special regs that are not really renamed (like misc regs
931  // and the zero reg) can be recognized because the new mapping
932  // is the same as the old one. While it would be merely a
933  // waste of time to update the rename table, we definitely
934  // don't want to put these on the free list.
935  if (hb_it->newPhysReg != hb_it->prevPhysReg) {
936  // Tell the rename map to set the architected register to the
937  // previous physical register that it was renamed to.
938  renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
939 
940  // Put the renamed physical register back on the free list.
941  freeList->addReg(hb_it->newPhysReg);
942  }
943 
944  // Notify potential listeners that the register mapping needs to be
945  // removed because the instruction it was mapped to got squashed. Note
946  // that this is done before hb_it is incremented.
947  ppSquashInRename->notify(std::make_pair(hb_it->instSeqNum,
948  hb_it->newPhysReg));
949 
950  historyBuffer[tid].erase(hb_it++);
951 
952  ++stats.undoneMaps;
953  }
954 }
955 
956 void
958 {
959  DPRINTF(Rename, "[tid:%i] Removing a committed instruction from the "
960  "history buffer %u (size=%i), until [sn:%llu].\n",
961  tid, tid, historyBuffer[tid].size(), inst_seq_num);
962 
963  auto hb_it = historyBuffer[tid].end();
964 
965  --hb_it;
966 
967  if (historyBuffer[tid].empty()) {
968  DPRINTF(Rename, "[tid:%i] History buffer is empty.\n", tid);
969  return;
970  } else if (hb_it->instSeqNum > inst_seq_num) {
971  DPRINTF(Rename, "[tid:%i] [sn:%llu] "
972  "Old sequence number encountered. "
973  "Ensure that a syscall happened recently.\n",
974  tid,inst_seq_num);
975  return;
976  }
977 
978  // Commit all the renames up until (and including) the committed sequence
979  // number. Some or even all of the committed instructions may not have
980  // rename histories if they did not have destination registers that were
981  // renamed.
982  while (!historyBuffer[tid].empty() &&
983  hb_it != historyBuffer[tid].end() &&
984  hb_it->instSeqNum <= inst_seq_num) {
985 
986  DPRINTF(Rename, "[tid:%i] Freeing up older rename of reg %i (%s), "
987  "[sn:%llu].\n",
988  tid, hb_it->prevPhysReg->index(),
989  hb_it->prevPhysReg->className(),
990  hb_it->instSeqNum);
991 
992  // Don't free special phys regs like misc and zero regs, which
993  // can be recognized because the new mapping is the same as
994  // the old one.
995  if (hb_it->newPhysReg != hb_it->prevPhysReg) {
996  freeList->addReg(hb_it->prevPhysReg);
997  }
998 
1000 
1001  historyBuffer[tid].erase(hb_it--);
1002  }
1003 }
1004 
1005 void
1007 {
1008  gem5::ThreadContext *tc = inst->tcBase();
1009  UnifiedRenameMap *map = renameMap[tid];
1010  unsigned num_src_regs = inst->numSrcRegs();
1011  auto *isa = tc->getIsaPtr();
1012 
1013  // Get the architectual register numbers from the source and
1014  // operands, and redirect them to the right physical register.
1015  for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
1016  const RegId& src_reg = inst->srcRegIdx(src_idx);
1017  const RegId flat_reg = src_reg.flatten(*isa);
1018  PhysRegIdPtr renamed_reg;
1019 
1020  renamed_reg = map->lookup(flat_reg);
1021  switch (flat_reg.classValue()) {
1022  case InvalidRegClass:
1023  break;
1024  case IntRegClass:
1025  stats.intLookups++;
1026  break;
1027  case FloatRegClass:
1028  stats.fpLookups++;
1029  break;
1030  case VecRegClass:
1031  case VecElemClass:
1032  stats.vecLookups++;
1033  break;
1034  case VecPredRegClass:
1036  break;
1037  case CCRegClass:
1038  case MiscRegClass:
1039  break;
1040 
1041  default:
1042  panic("Invalid register class: %d.", flat_reg.classValue());
1043  }
1044 
1045  DPRINTF(Rename,
1046  "[tid:%i] "
1047  "Looking up %s arch reg %i, got phys reg %i (%s)\n",
1048  tid, flat_reg.className(),
1049  src_reg.index(), renamed_reg->index(),
1050  renamed_reg->className());
1051 
1052  inst->renameSrcReg(src_idx, renamed_reg);
1053 
1054  // See if the register is ready or not.
1055  if (scoreboard->getReg(renamed_reg)) {
1056  DPRINTF(Rename,
1057  "[tid:%i] "
1058  "Register %d (flat: %d) (%s) is ready.\n",
1059  tid, renamed_reg->index(), renamed_reg->flatIndex(),
1060  renamed_reg->className());
1061 
1062  inst->markSrcRegReady(src_idx);
1063  } else {
1064  DPRINTF(Rename,
1065  "[tid:%i] "
1066  "Register %d (flat: %d) (%s) is not ready.\n",
1067  tid, renamed_reg->index(), renamed_reg->flatIndex(),
1068  renamed_reg->className());
1069  }
1070 
1071  ++stats.lookups;
1072  }
1073 }
1074 
1075 void
1077 {
1078  gem5::ThreadContext *tc = inst->tcBase();
1079  UnifiedRenameMap *map = renameMap[tid];
1080  unsigned num_dest_regs = inst->numDestRegs();
1081  auto *isa = tc->getIsaPtr();
1082 
1083  // Rename the destination registers.
1084  for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
1085  const RegId& dest_reg = inst->destRegIdx(dest_idx);
1086  UnifiedRenameMap::RenameInfo rename_result;
1087 
1088  RegId flat_dest_regid = dest_reg.flatten(*isa);
1089  flat_dest_regid.setNumPinnedWrites(dest_reg.getNumPinnedWrites());
1090 
1091  rename_result = map->rename(flat_dest_regid);
1092 
1093  inst->flattenedDestIdx(dest_idx, flat_dest_regid);
1094 
1095  scoreboard->unsetReg(rename_result.first);
1096 
1097  DPRINTF(Rename,
1098  "[tid:%i] "
1099  "Renaming arch reg %i (%s) to physical reg %i (%i).\n",
1100  tid, dest_reg.index(), dest_reg.className(),
1101  rename_result.first->index(),
1102  rename_result.first->flatIndex());
1103 
1104  // Record the rename information so that a history can be kept.
1105  RenameHistory hb_entry(inst->seqNum, flat_dest_regid,
1106  rename_result.first,
1107  rename_result.second);
1108 
1109  historyBuffer[tid].push_front(hb_entry);
1110 
1111  DPRINTF(Rename, "[tid:%i] [sn:%llu] "
1112  "Adding instruction to history buffer (size=%i).\n",
1113  tid,(*historyBuffer[tid].begin()).instSeqNum,
1114  historyBuffer[tid].size());
1115 
1116  // Tell the instruction to rename the appropriate destination
1117  // register (dest_idx) to the new physical register
1118  // (rename_result.first), and record the previous physical
1119  // register that the same logical register was renamed to
1120  // (rename_result.second).
1121  inst->renameDestReg(dest_idx,
1122  rename_result.first,
1123  rename_result.second);
1124 
1126  }
1127 }
1128 
1129 int
1131 {
1132  int num_free = freeEntries[tid].robEntries -
1133  (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
1134 
1135  //DPRINTF(Rename,"[tid:%i] %i rob free\n",tid,num_free);
1136 
1137  return num_free;
1138 }
1139 
1140 int
1142 {
1143  int num_free = freeEntries[tid].iqEntries -
1144  (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
1145 
1146  //DPRINTF(Rename,"[tid:%i] %i iq free\n",tid,num_free);
1147 
1148  return num_free;
1149 }
1150 
1151 int
1153 {
1154  int num_free = freeEntries[tid].lqEntries -
1155  (loadsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLQ);
1156  DPRINTF(Rename,
1157  "calcFreeLQEntries: free lqEntries: %d, loadsInProgress: %d, "
1158  "loads dispatchedToLQ: %d\n",
1159  freeEntries[tid].lqEntries, loadsInProgress[tid],
1160  fromIEW->iewInfo[tid].dispatchedToLQ);
1161  return num_free;
1162 }
1163 
1164 int
1166 {
1167  int num_free = freeEntries[tid].sqEntries -
1168  (storesInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToSQ);
1169  DPRINTF(Rename, "calcFreeSQEntries: free sqEntries: %d, "
1170  "storesInProgress: %d, stores dispatchedToSQ: %d\n",
1171  freeEntries[tid].sqEntries, storesInProgress[tid],
1172  fromIEW->iewInfo[tid].dispatchedToSQ);
1173  return num_free;
1174 }
1175 
1176 unsigned
1178 {
1179  unsigned inst_count = 0;
1180 
1181  for (int i=0; i<fromDecode->size; i++) {
1182  if (!fromDecode->insts[i]->isSquashed())
1183  inst_count++;
1184  }
1185 
1186  return inst_count;
1187 }
1188 
1189 void
1191 {
1192  if (fromIEW->iewBlock[tid]) {
1193  stalls[tid].iew = true;
1194  }
1195 
1196  if (fromIEW->iewUnblock[tid]) {
1197  assert(stalls[tid].iew);
1198  stalls[tid].iew = false;
1199  }
1200 }
1201 
1202 bool
1204 {
1205  bool ret_val = false;
1206 
1207  if (stalls[tid].iew) {
1208  DPRINTF(Rename,"[tid:%i] Stall from IEW stage detected.\n", tid);
1209  ret_val = true;
1210  } else if (calcFreeROBEntries(tid) <= 0) {
1211  DPRINTF(Rename,"[tid:%i] Stall: ROB has 0 free entries.\n", tid);
1212  ret_val = true;
1213  } else if (calcFreeIQEntries(tid) <= 0) {
1214  DPRINTF(Rename,"[tid:%i] Stall: IQ has 0 free entries.\n", tid);
1215  ret_val = true;
1216  } else if (calcFreeLQEntries(tid) <= 0 && calcFreeSQEntries(tid) <= 0) {
1217  DPRINTF(Rename,"[tid:%i] Stall: LSQ has 0 free entries.\n", tid);
1218  ret_val = true;
1219  } else if (renameMap[tid]->numFreeEntries() <= 0) {
1220  DPRINTF(Rename,"[tid:%i] Stall: RenameMap has 0 free entries.\n", tid);
1221  ret_val = true;
1222  } else if (renameStatus[tid] == SerializeStall &&
1223  (!emptyROB[tid] || instsInProgress[tid])) {
1224  DPRINTF(Rename,"[tid:%i] Stall: Serialize stall and ROB is not "
1225  "empty.\n",
1226  tid);
1227  ret_val = true;
1228  }
1229 
1230  return ret_val;
1231 }
1232 
1233 void
1235 {
1236  if (fromIEW->iewInfo[tid].usedIQ)
1237  freeEntries[tid].iqEntries = fromIEW->iewInfo[tid].freeIQEntries;
1238 
1239  if (fromIEW->iewInfo[tid].usedLSQ) {
1240  freeEntries[tid].lqEntries = fromIEW->iewInfo[tid].freeLQEntries;
1241  freeEntries[tid].sqEntries = fromIEW->iewInfo[tid].freeSQEntries;
1242  }
1243 
1244  if (fromCommit->commitInfo[tid].usedROB) {
1245  freeEntries[tid].robEntries =
1246  fromCommit->commitInfo[tid].freeROBEntries;
1247  emptyROB[tid] = fromCommit->commitInfo[tid].emptyROB;
1248  }
1249 
1250  DPRINTF(Rename, "[tid:%i] Free IQ: %i, Free ROB: %i, "
1251  "Free LQ: %i, Free SQ: %i, FreeRM %i(%i %i %i %i %i %i)\n",
1252  tid,
1253  freeEntries[tid].iqEntries,
1254  freeEntries[tid].robEntries,
1255  freeEntries[tid].lqEntries,
1256  freeEntries[tid].sqEntries,
1257  renameMap[tid]->numFreeEntries(),
1258  renameMap[tid]->numFreeEntries(IntRegClass),
1259  renameMap[tid]->numFreeEntries(FloatRegClass),
1260  renameMap[tid]->numFreeEntries(VecRegClass),
1261  renameMap[tid]->numFreeEntries(VecElemClass),
1262  renameMap[tid]->numFreeEntries(VecPredRegClass),
1263  renameMap[tid]->numFreeEntries(CCRegClass));
1264 
1265  DPRINTF(Rename, "[tid:%i] %i instructions not yet in ROB\n",
1266  tid, instsInProgress[tid]);
1267 }
1268 
1269 bool
1271 {
1272  // Check if there's a squash signal, squash if there is
1273  // Check stall signals, block if necessary.
1274  // If status was blocked
1275  // check if stall conditions have passed
1276  // if so then go to unblocking
1277  // If status was Squashing
1278  // check if squashing is not high. Switch to running this cycle.
1279  // If status was serialize stall
1280  // check if ROB is empty and no insts are in flight to the ROB
1281 
1282  readFreeEntries(tid);
1283  readStallSignals(tid);
1284 
1285  if (fromCommit->commitInfo[tid].squash) {
1286  DPRINTF(Rename, "[tid:%i] Squashing instructions due to squash from "
1287  "commit.\n", tid);
1288 
1289  squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
1290 
1291  return true;
1292  }
1293 
1294  if (checkStall(tid)) {
1295  return block(tid);
1296  }
1297 
1298  if (renameStatus[tid] == Blocked) {
1299  DPRINTF(Rename, "[tid:%i] Done blocking, switching to unblocking.\n",
1300  tid);
1301 
1302  renameStatus[tid] = Unblocking;
1303 
1304  unblock(tid);
1305 
1306  return true;
1307  }
1308 
1309  if (renameStatus[tid] == Squashing) {
1310  // Switch status to running if rename isn't being told to block or
1311  // squash this cycle.
1312  if (resumeSerialize) {
1313  DPRINTF(Rename,
1314  "[tid:%i] Done squashing, switching to serialize.\n", tid);
1315 
1317  return true;
1318  } else if (resumeUnblocking) {
1319  DPRINTF(Rename,
1320  "[tid:%i] Done squashing, switching to unblocking.\n",
1321  tid);
1322  renameStatus[tid] = Unblocking;
1323  return true;
1324  } else {
1325  DPRINTF(Rename, "[tid:%i] Done squashing, switching to running.\n",
1326  tid);
1327  renameStatus[tid] = Running;
1328  return false;
1329  }
1330  }
1331 
1332  if (renameStatus[tid] == SerializeStall) {
1333  // Stall ends once the ROB is free.
1334  DPRINTF(Rename, "[tid:%i] Done with serialize stall, switching to "
1335  "unblocking.\n", tid);
1336 
1337  DynInstPtr serial_inst = serializeInst[tid];
1338 
1339  renameStatus[tid] = Unblocking;
1340 
1341  unblock(tid);
1342 
1343  DPRINTF(Rename, "[tid:%i] Processing instruction [%lli] with "
1344  "PC %s.\n", tid, serial_inst->seqNum, serial_inst->pcState());
1345 
1346  // Put instruction into queue here.
1347  serial_inst->clearSerializeBefore();
1348 
1349  if (!skidBuffer[tid].empty()) {
1350  skidBuffer[tid].push_front(serial_inst);
1351  } else {
1352  insts[tid].push_front(serial_inst);
1353  }
1354 
1355  DPRINTF(Rename, "[tid:%i] Instruction must be processed by rename."
1356  " Adding to front of list.\n", tid);
1357 
1358  serializeInst[tid] = NULL;
1359 
1360  return true;
1361  }
1362 
1363  // If we've reached this point, we have not gotten any signals that
1364  // cause rename to change its status. Rename remains the same as before.
1365  return false;
1366 }
1367 
1368 void
1370 {
1371  if (inst_list.empty()) {
1372  // Mark a bit to say that I must serialize on the next instruction.
1373  serializeOnNextInst[tid] = true;
1374  return;
1375  }
1376 
1377  // Set the next instruction as serializing.
1378  inst_list.front()->setSerializeBefore();
1379 }
1380 
1381 void
1383 {
1384  switch (source) {
1385  case ROB:
1386  ++stats.ROBFullEvents;
1387  break;
1388  case IQ:
1389  ++stats.IQFullEvents;
1390  break;
1391  case LQ:
1392  ++stats.LQFullEvents;
1393  break;
1394  case SQ:
1395  ++stats.SQFullEvents;
1396  break;
1397  default:
1398  panic("Rename full stall stat should be incremented for a reason!");
1399  break;
1400  }
1401 }
1402 
1403 void
1405 {
1407 
1408  for (ThreadID tid = 0; tid < numThreads; tid++) {
1409 
1410  buf_it = historyBuffer[tid].begin();
1411 
1412  while (buf_it != historyBuffer[tid].end()) {
1413  cprintf("Seq num: %i\nArch reg[%s]: %i New phys reg:"
1414  " %i[%s] Old phys reg: %i[%s]\n",
1415  (*buf_it).instSeqNum,
1416  (*buf_it).archReg.className(),
1417  (*buf_it).archReg.index(),
1418  (*buf_it).newPhysReg->index(),
1419  (*buf_it).newPhysReg->className(),
1420  (*buf_it).prevPhysReg->index(),
1421  (*buf_it).prevPhysReg->className());
1422 
1423  buf_it++;
1424  }
1425  }
1426 }
1427 
1428 } // namespace o3
1429 } // namespace gem5
#define DPRINTF(x,...)
Definition: trace.hh:186
virtual std::string name() const
Definition: named.hh:47
Physical register ID.
Definition: reg_class.hh:392
constexpr RegIndex index() const
Visible RegId methods.
Definition: reg_class.hh:148
constexpr const char * className() const
Return a const char* with the register class name.
Definition: reg_class.hh:273
const RegIndex & flatIndex() const
Flat index accessor.
Definition: reg_class.hh:449
ProbePointArg generates a point for the class of Arg.
Definition: probe.hh:264
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:91
constexpr RegClassType classValue() const
Definition: reg_class.hh:272
void setNumPinnedWrites(int num_writes)
Definition: reg_class.hh:160
constexpr RegIndex index() const
Index accessors.
Definition: reg_class.hh:148
int getNumPinnedWrites() const
Definition: reg_class.hh:159
RegId flatten(const BaseISA &isa) const
Definition: reg_class.hh:277
constexpr const char * className() const
Return a const char* with the register class name.
Definition: reg_class.hh:273
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual BaseISA * getIsaPtr() const =0
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
Definition: cpu.hh:94
void activityThisCycle()
Records that there was time buffer activity this cycle.
Definition: cpu.hh:485
@ RenameIdx
Definition: cpu.hh:455
void deactivateStage(const StageIdx idx)
Changes a stage's status to inactive within the activity recorder.
Definition: cpu.hh:496
void activateStage(const StageIdx idx)
Changes a stage's status to active within the activity recorder.
Definition: cpu.hh:489
size_t numROBFreeEntries(ThreadID tid)
Returns the number of free ROB entries for a specific thread.
Definition: commit.cc:492
InstructionQueue instQueue
Instruction queue.
Definition: iew.hh:355
LSQ ldstQueue
Load / store queue.
Definition: iew.hh:358
unsigned numFreeEntries()
Returns total number of free entries.
Definition: inst_queue.cc:512
unsigned numFreeLoadEntries()
Returns the number of free load entries.
Definition: lsq.cc:524
unsigned numFreeStoreEntries()
Returns the number of free store entries.
Definition: lsq.cc:541
Rename handles both single threaded and SMT rename.
Definition: rename.hh:79
DynInstPtr serializeInst[MaxThreads]
The serialize instruction that rename has stalled on.
Definition: rename.hh:421
void incrFullStat(const FullSource &source)
Function used to increment the stat that corresponds to the source of the stall.
Definition: rename.cc:1382
ThreadID numThreads
The number of threads active in rename.
Definition: rename.hh:457
TimeBuffer< RenameStruct >::wire toIEW
Wire to write any information heading to IEW.
Definition: rename.hh:342
void sortInsts()
Separates instructions from decode into individual lists of instructions sorted by thread.
Definition: rename.cc:790
ThreadStatus renameStatus[MaxThreads]
Per-thread status.
Definition: rename.hh:114
Rename(CPU *_cpu, const BaseO3CPUParams &params)
Rename constructor.
Definition: rename.cc:61
TimeBuffer< TimeStruct >::wire toDecode
Wire to write infromation heading to previous stages.
Definition: rename.hh:336
TimeBuffer< RenameStruct > * renameQueue
Rename instruction queue.
Definition: rename.hh:339
unsigned commitToRenameDelay
Delay between commit and rename, in ticks.
Definition: rename.hh:435
int storesInProgress[MaxThreads]
Count of Store instructions in progress that have been sent off to the IQ and ROB,...
Definition: rename.hh:381
int instsInProgress[MaxThreads]
Count of instructions in progress that have been sent off to the IQ and ROB, but are not yet included...
Definition: rename.hh:371
int calcFreeIQEntries(ThreadID tid)
Calculates the number of free IQ entries for a specific thread.
Definition: rename.cc:1141
void startupStage()
Initializes variables for the stage.
Definition: rename.cc:221
ProbePointArg< DynInstPtr > * ppRename
To probe when register renaming for an instruction is complete.
Definition: rename.hh:119
bool blockThisCycle
Whether or not rename needs to block this cycle.
Definition: rename.hh:446
void renameSrcRegs(const DynInstPtr &inst, ThreadID tid)
Renames the source registers of an instruction.
Definition: rename.cc:1006
void doSquash(const InstSeqNum &squash_seq_num, ThreadID tid)
Executes actual squash, removing squashed instructions.
Definition: rename.cc:912
void renameDestRegs(const DynInstPtr &inst, ThreadID tid)
Renames the destination registers of an instruction.
Definition: rename.cc:1076
unsigned skidBufferMax
The maximum skid buffer size.
Definition: rename.hh:460
std::list< ThreadID > * activeThreads
Pointer to the list of active threads.
Definition: rename.hh:363
UnifiedFreeList * freeList
Free list interface.
Definition: rename.hh:360
void tick()
Ticks rename, which processes all input signals and attempts to rename as many instructions as possib...
Definition: rename.cc:389
void readFreeEntries(ThreadID tid)
Gets the number of free entries for a specific thread.
Definition: rename.cc:1234
int calcFreeROBEntries(ThreadID tid)
Calculates the number of free ROB entries for a specific thread.
Definition: rename.cc:1130
int iewToRenameDelay
Delay between iew and rename, in ticks.
Definition: rename.hh:429
RenameStatus _status
Rename status.
Definition: rename.hh:111
void renameInsts(ThreadID tid)
Renames instructions for the given thread.
Definition: rename.cc:507
void setFreeList(UnifiedFreeList *fl_ptr)
Sets pointer to the free list.
Definition: rename.cc:293
bool emptyROB[MaxThreads]
Records if the ROB is empty.
Definition: rename.hh:408
void rename(bool &status_change, ThreadID tid)
Determines what to do based on rename's current status.
Definition: rename.cc:452
TimeBuffer< TimeStruct >::wire fromIEW
Wire to get IEW's output from backwards time buffer.
Definition: rename.hh:330
std::string name() const
Returns the name of rename.
Definition: rename.cc:92
std::list< RenameHistory > historyBuffer[MaxThreads]
A per-thread list of all destination register renames, used to either undo rename mappings or free ol...
Definition: rename.hh:321
TimeBuffer< DecodeStruct >::wire fromDecode
Wire to get decode's output from decode queue.
Definition: rename.hh:348
void serializeAfter(InstQueue &inst_list, ThreadID tid)
Either serializes on the next instruction available in the InstQueue, or records that it must seriali...
Definition: rename.cc:1369
gem5::o3::Rename::RenameStats stats
TimeBuffer< DecodeStruct > * decodeQueue
Decode instruction queue interface.
Definition: rename.hh:345
unsigned renameWidth
Rename width, in instructions.
Definition: rename.hh:438
bool resumeUnblocking
Whether or not rename needs to resume clearing out the skidbuffer after squashing.
Definition: rename.hh:454
InstQueue skidBuffer[MaxThreads]
Skid buffer between rename and decode.
Definition: rename.hh:354
Scoreboard * scoreboard
Pointer to the scoreboard.
Definition: rename.hh:366
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: rename.cc:325
bool skidsEmpty()
Returns if all of the skid buffers are empty.
Definition: rename.cc:805
IEW * iew_ptr
Pointer to IEW stage.
Definition: rename.hh:157
int calcFreeSQEntries(ThreadID tid)
Calculates the number of free SQ entries for a specific thread.
Definition: rename.cc:1165
void dumpHistory()
Debugging function used to dump history buffer of renamings.
Definition: rename.cc:1404
FullSource
Enum to record the source of a structure full stall.
Definition: rename.hh:466
UnifiedRenameMap * renameMap[MaxThreads]
Rename map interface.
Definition: rename.hh:357
bool block(ThreadID tid)
Switches rename to blocking, and signals back that rename has become blocked.
Definition: rename.cc:859
int loadsInProgress[MaxThreads]
Count of Load instructions in progress that have been sent off to the IQ and ROB, but are not yet inc...
Definition: rename.hh:376
TimeBuffer< TimeStruct >::wire fromCommit
Wire to get commit's output from backwards time buffer.
Definition: rename.hh:333
bool unblock(ThreadID tid)
Switches rename to unblocking if the skid buffer is empty, and signals back that rename has unblocked...
Definition: rename.cc:892
TimeBuffer< TimeStruct > * timeBuffer
Pointer to main time buffer used for backwards communication.
Definition: rename.hh:327
unsigned toIEWIndex
The index of the instruction in the time buffer to IEW that rename is currently using.
Definition: rename.hh:443
void removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid)
Removes a committed instruction's rename history.
Definition: rename.cc:957
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets the main backwards communication time buffer pointer.
Definition: rename.cc:188
void takeOverFrom()
Takes over from another CPU's thread.
Definition: rename.cc:319
void setRenameMap(UnifiedRenameMap rm_ptr[MaxThreads])
Sets pointer to rename maps (per-thread structures).
Definition: rename.cc:286
Stalls stalls[MaxThreads]
Tracks which stages are telling decode to stall.
Definition: rename.hh:418
void regProbePoints()
Registers probes.
Definition: rename.cc:179
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to list of active threads.
Definition: rename.cc:279
void resetStage()
Reset this pipeline stage.
Definition: rename.cc:248
bool checkStall(ThreadID tid)
Checks if any stages are telling rename to block.
Definition: rename.cc:1203
InstQueue insts[MaxThreads]
Queue of all instructions coming from decode this cycle.
Definition: rename.hh:351
void skidInsert(ThreadID tid)
Inserts unused instructions from a given thread into the skid buffer, to be renamed once rename unblo...
Definition: rename.cc:757
void readStallSignals(ThreadID tid)
Reads signals telling rename to block/unblock.
Definition: rename.cc:1190
void updateStatus()
Updates overall rename status based on all of the threads' statuses.
Definition: rename.cc:821
bool checkSignalsAndUpdate(ThreadID tid)
Checks the signals and updates the status.
Definition: rename.cc:1270
void squash(const InstSeqNum &squash_seq_num, ThreadID tid)
Squashes all instructions in a thread.
Definition: rename.cc:336
bool isDrained() const
Has the stage drained?
Definition: rename.cc:305
void setScoreboard(Scoreboard *_scoreboard)
Sets pointer to the scoreboard.
Definition: rename.cc:299
FreeEntries freeEntries[MaxThreads]
Per-thread tracking of the number of free entries of back-end structures.
Definition: rename.hh:402
int calcFreeLQEntries(ThreadID tid)
Calculates the number of free LQ entries for a specific thread.
Definition: rename.cc:1152
Commit * commit_ptr
Pointer to commit stage.
Definition: rename.hh:160
bool serializeOnNextInst[MaxThreads]
Records if rename needs to serialize on the next instruction for any thread.
Definition: rename.hh:426
ProbePointArg< SeqNumRegPair > * ppSquashInRename
To probe when an instruction is squashed and the register mapping for it needs to be undone.
Definition: rename.hh:124
int decodeToRenameDelay
Delay between decode and rename, in ticks.
Definition: rename.hh:432
CPU * cpu
Pointer to CPU.
Definition: rename.hh:324
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition: rename.cc:227
bool wroteToTimeBuffer
Variable that tracks if decode has written to the time buffer this cycle.
Definition: rename.hh:386
void setDecodeQueue(TimeBuffer< DecodeStruct > *dq_ptr)
Sets pointer to time buffer coming from decode.
Definition: rename.cc:212
bool resumeSerialize
Whether or not rename needs to resume a serialize instruction after squashing.
Definition: rename.hh:450
void setRenameQueue(TimeBuffer< RenameStruct > *rq_ptr)
Sets pointer to time buffer used to communicate to the next stage.
Definition: rename.cc:203
unsigned validInsts()
Returns the number of valid instructions coming from decode.
Definition: rename.cc:1177
Implements a simple scoreboard to track which registers are ready.
Definition: scoreboard.hh:55
bool getReg(PhysRegIdPtr phys_reg) const
Checks if the register is ready.
Definition: scoreboard.hh:83
void unsetReg(PhysRegIdPtr phys_reg)
Sets the register as not ready.
Definition: scoreboard.hh:115
FreeList class that simply holds the list of free integer and floating point registers.
Definition: free_list.hh:125
void addReg(PhysRegIdPtr freed_reg)
Adds a register back to the free list.
Definition: free_list.hh:174
Unified register rename map for all classes of registers.
Definition: rename_map.hh:169
void setEntry(const RegId &arch_reg, PhysRegIdPtr phys_reg)
Update rename map with a specific mapping.
Definition: rename_map.hh:247
PhysRegIdPtr lookup(const RegId &arch_reg) const
Look up the physical register mapped to an architectural register.
Definition: rename_map.hh:225
RenameInfo rename(const RegId &arch_reg)
Tell rename map to get a new free physical register to remap the specified architectural register.
Definition: rename_map.hh:204
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:358
Derived & prereq(const Stat &prereq)
Set the prerequisite stat and marks this stat to print at the end of simulation.
Definition: statistics.hh:372
Statistics container.
Definition: group.hh:94
STL pair class.
Definition: stl.hh:58
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:190
ProbeManager * getProbeManager()
Get the probe manager for this object.
Definition: sim_object.cc:120
#define warn(...)
Definition: logging.hh:246
Bitfield< 7 > i
Definition: misc_types.hh:67
static constexpr int MaxThreads
Definition: limits.hh:38
static constexpr int MaxWidth
Definition: limits.hh:37
const FlagsType total
Print the total.
Definition: info.hh:60
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:235
void cprintf(const char *format, const Args &...args)
Definition: cprintf.hh:155
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
uint64_t InstSeqNum
Definition: inst_seq.hh:40
@ VecPredRegClass
Definition: reg_class.hh:66
@ FloatRegClass
Floating-point register.
Definition: reg_class.hh:61
@ CCRegClass
Condition-code register.
Definition: reg_class.hh:67
@ VecRegClass
Vector Register.
Definition: reg_class.hh:63
@ IntRegClass
Integer register.
Definition: reg_class.hh:60
@ InvalidRegClass
Definition: reg_class.hh:69
@ MiscRegClass
Control (misc) register.
Definition: reg_class.hh:68
@ VecElemClass
Vector Register Native Elem lane.
Definition: reg_class.hh:65
Holds the information for each destination register rename.
Definition: rename.hh:298
statistics::Scalar blockCycles
Stat for total number of cycles spent blocking.
Definition: rename.hh:488
statistics::Scalar ROBFullEvents
Stat for total number of times that the ROB starts a stall in rename.
Definition: rename.hh:503
statistics::Scalar renamedOperands
Stat for total number of renamed destination registers.
Definition: rename.hh:517
statistics::Scalar fpLookups
Definition: rename.hh:521
statistics::Scalar fullRegistersEvents
Stat for total number of times that rename runs out of free registers to use to rename.
Definition: rename.hh:515
statistics::Scalar squashedInsts
Stat for total number of squashed instructions that rename discards.
Definition: rename.hh:500
statistics::Scalar IQFullEvents
Stat for total number of times that the IQ starts a stall in rename.
Definition: rename.hh:506
statistics::Scalar vecPredLookups
Definition: rename.hh:523
statistics::Scalar squashCycles
Stat for total number of cycles spent squashing.
Definition: rename.hh:484
statistics::Scalar renamedInsts
Stat for total number of renamed instructions.
Definition: rename.hh:497
statistics::Scalar LQFullEvents
Stat for total number of times that the LQ starts a stall in rename.
Definition: rename.hh:509
statistics::Scalar lookups
Stat for total number of source register rename lookups.
Definition: rename.hh:519
statistics::Scalar vecLookups
Definition: rename.hh:522
statistics::Scalar tempSerializing
Number of instructions marked as temporarily serializing.
Definition: rename.hh:532
statistics::Scalar serializing
Number of serialize instructions handled.
Definition: rename.hh:530
statistics::Scalar undoneMaps
Stat for total number of mappings that were undone due to a squash.
Definition: rename.hh:528
statistics::Scalar runCycles
Stat for total number of cycles spent running normally.
Definition: rename.hh:493
statistics::Scalar committedMaps
Stat for total number of committed renaming mappings.
Definition: rename.hh:525
statistics::Scalar intLookups
Definition: rename.hh:520
statistics::Scalar unblockCycles
Stat for total number of cycles spent unblocking.
Definition: rename.hh:495
statistics::Scalar idleCycles
Stat for total number of cycles spent idle.
Definition: rename.hh:486
RenameStats(statistics::Group *parent)
Definition: rename.cc:97
statistics::Scalar SQFullEvents
Stat for total number of times that the SQ starts a stall in rename.
Definition: rename.hh:512
statistics::Scalar skidInsts
Number of instructions inserted into skid buffers.
Definition: rename.hh:534
statistics::Scalar serializeStallCycles
Stat for total number of cycles spent stalling for a serializing inst.
Definition: rename.hh:491

Generated on Wed Dec 21 2022 10:22:31 for gem5 by doxygen 1.9.1