gem5  v21.1.0.2
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/O3CPU.hh"
54 
55 namespace gem5
56 {
57 
58 namespace o3
59 {
60 
61 Rename::Rename(CPU *_cpu, const O3CPUParams &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->numIntDestRegs(),
660  inst->numFPDestRegs(),
661  inst->numVecDestRegs(),
662  inst->numVecElemDestRegs(),
663  inst->numVecPredDestRegs(),
664  inst->numCCDestRegs())) {
665  DPRINTF(Rename,
666  "Blocking due to "
667  " lack of free physical registers to rename to.\n");
668  blockThisCycle = true;
669  insts_to_rename.push_front(inst);
671 
672  break;
673  }
674 
675  // Handle serializeAfter/serializeBefore instructions.
676  // serializeAfter marks the next instruction as serializeBefore.
677  // serializeBefore makes the instruction wait in rename until the ROB
678  // is empty.
679 
680  // In this model, IPR accesses are serialize before
681  // instructions, and store conditionals are serialize after
682  // instructions. This is mainly due to lack of support for
683  // out-of-order operations of either of those classes of
684  // instructions.
685  if (inst->isSerializeBefore() && !inst->isSerializeHandled()) {
686  DPRINTF(Rename, "Serialize before instruction encountered.\n");
687 
688  if (!inst->isTempSerializeBefore()) {
689  stats.serializing++;
690  inst->setSerializeHandled();
691  } else {
693  }
694 
695  // Change status over to SerializeStall so that other stages know
696  // what this is blocked on.
698 
699  serializeInst[tid] = inst;
700 
701  blockThisCycle = true;
702 
703  break;
704  } else if ((inst->isStoreConditional() || inst->isSerializeAfter()) &&
705  !inst->isSerializeHandled()) {
706  DPRINTF(Rename, "Serialize after instruction encountered.\n");
707 
708  stats.serializing++;
709 
710  inst->setSerializeHandled();
711 
712  serializeAfter(insts_to_rename, tid);
713  }
714 
715  renameSrcRegs(inst, inst->threadNumber);
716 
717  renameDestRegs(inst, inst->threadNumber);
718 
719  if (inst->isAtomic() || inst->isStore()) {
720  storesInProgress[tid]++;
721  } else if (inst->isLoad()) {
722  loadsInProgress[tid]++;
723  }
724 
725  ++renamed_insts;
726  // Notify potential listeners that source and destination registers for
727  // this instruction have been renamed.
728  ppRename->notify(inst);
729 
730  // Put instruction in rename queue.
731  toIEW->insts[toIEWIndex] = inst;
732  ++(toIEW->size);
733 
734  // Increment which instruction we're on.
735  ++toIEWIndex;
736 
737  // Decrement how many instructions are available.
738  --insts_available;
739  }
740 
741  instsInProgress[tid] += renamed_insts;
742  stats.renamedInsts += renamed_insts;
743 
744  // If we wrote to the time buffer, record this.
745  if (toIEWIndex) {
746  wroteToTimeBuffer = true;
747  }
748 
749  // Check if there's any instructions left that haven't yet been renamed.
750  // If so then block.
751  if (insts_available) {
752  blockThisCycle = true;
753  }
754 
755  if (blockThisCycle) {
756  block(tid);
757  toDecode->renameUnblock[tid] = false;
758  }
759 }
760 
761 void
763 {
764  DynInstPtr inst = NULL;
765 
766  while (!insts[tid].empty()) {
767  inst = insts[tid].front();
768 
769  insts[tid].pop_front();
770 
771  assert(tid == inst->threadNumber);
772 
773  DPRINTF(Rename, "[tid:%i] Inserting [sn:%llu] PC: %s into Rename "
774  "skidBuffer\n", tid, inst->seqNum, inst->pcState());
775 
776  ++stats.skidInsts;
777 
778  skidBuffer[tid].push_back(inst);
779  }
780 
781  if (skidBuffer[tid].size() > skidBufferMax) {
782  InstQueue::iterator it;
783  warn("Skidbuffer contents:\n");
784  for (it = skidBuffer[tid].begin(); it != skidBuffer[tid].end(); it++) {
785  warn("[tid:%i] %s [sn:%llu].\n", tid,
786  (*it)->staticInst->disassemble(inst->instAddr()),
787  (*it)->seqNum);
788  }
789  panic("Skidbuffer Exceeded Max Size");
790  }
791 }
792 
793 void
795 {
796  int insts_from_decode = fromDecode->size;
797  for (int i = 0; i < insts_from_decode; ++i) {
798  const DynInstPtr &inst = fromDecode->insts[i];
799  insts[inst->threadNumber].push_back(inst);
800 #if TRACING_ON
801  if (debug::O3PipeView) {
802  inst->renameTick = curTick() - inst->fetchTick;
803  }
804 #endif
805  }
806 }
807 
808 bool
810 {
811  std::list<ThreadID>::iterator threads = activeThreads->begin();
813 
814  while (threads != end) {
815  ThreadID tid = *threads++;
816 
817  if (!skidBuffer[tid].empty())
818  return false;
819  }
820 
821  return true;
822 }
823 
824 void
826 {
827  bool any_unblocking = false;
828 
829  std::list<ThreadID>::iterator threads = activeThreads->begin();
831 
832  while (threads != end) {
833  ThreadID tid = *threads++;
834 
835  if (renameStatus[tid] == Unblocking) {
836  any_unblocking = true;
837  break;
838  }
839  }
840 
841  // Rename will have activity if it's unblocking.
842  if (any_unblocking) {
843  if (_status == Inactive) {
844  _status = Active;
845 
846  DPRINTF(Activity, "Activating stage.\n");
847 
849  }
850  } else {
851  // If it's not unblocking, then rename will not have any internal
852  // activity. Switch it to inactive.
853  if (_status == Active) {
854  _status = Inactive;
855  DPRINTF(Activity, "Deactivating stage.\n");
856 
858  }
859  }
860 }
861 
862 bool
864 {
865  DPRINTF(Rename, "[tid:%i] Blocking.\n", tid);
866 
867  // Add the current inputs onto the skid buffer, so they can be
868  // reprocessed when this stage unblocks.
869  skidInsert(tid);
870 
871  // Only signal backwards to block if the previous stages do not think
872  // rename is already blocked.
873  if (renameStatus[tid] != Blocked) {
874  // If resumeUnblocking is set, we unblocked during the squash,
875  // but now we're have unblocking status. We need to tell earlier
876  // stages to block.
877  if (resumeUnblocking || renameStatus[tid] != Unblocking) {
878  toDecode->renameBlock[tid] = true;
879  toDecode->renameUnblock[tid] = false;
880  wroteToTimeBuffer = true;
881  }
882 
883  // Rename can not go from SerializeStall to Blocked, otherwise
884  // it would not know to complete the serialize stall.
885  if (renameStatus[tid] != SerializeStall) {
886  // Set status to Blocked.
887  renameStatus[tid] = Blocked;
888  return true;
889  }
890  }
891 
892  return false;
893 }
894 
895 bool
897 {
898  DPRINTF(Rename, "[tid:%i] Trying to unblock.\n", tid);
899 
900  // Rename is done unblocking if the skid buffer is empty.
901  if (skidBuffer[tid].empty() && renameStatus[tid] != SerializeStall) {
902 
903  DPRINTF(Rename, "[tid:%i] Done unblocking.\n", tid);
904 
905  toDecode->renameUnblock[tid] = true;
906  wroteToTimeBuffer = true;
907 
908  renameStatus[tid] = Running;
909  return true;
910  }
911 
912  return false;
913 }
914 
915 void
916 Rename::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid)
917 {
918  auto hb_it = historyBuffer[tid].begin();
919 
920  // After a syscall squashes everything, the history buffer may be empty
921  // but the ROB may still be squashing instructions.
922  // Go through the most recent instructions, undoing the mappings
923  // they did and freeing up the registers.
924  while (!historyBuffer[tid].empty() &&
925  hb_it->instSeqNum > squashed_seq_num) {
926  assert(hb_it != historyBuffer[tid].end());
927 
928  DPRINTF(Rename, "[tid:%i] Removing history entry with sequence "
929  "number %i (archReg: %d, newPhysReg: %d, prevPhysReg: %d).\n",
930  tid, hb_it->instSeqNum, hb_it->archReg.index(),
931  hb_it->newPhysReg->index(), hb_it->prevPhysReg->index());
932 
933  // Undo the rename mapping only if it was really a change.
934  // Special regs that are not really renamed (like misc regs
935  // and the zero reg) can be recognized because the new mapping
936  // is the same as the old one. While it would be merely a
937  // waste of time to update the rename table, we definitely
938  // don't want to put these on the free list.
939  if (hb_it->newPhysReg != hb_it->prevPhysReg) {
940  // Tell the rename map to set the architected register to the
941  // previous physical register that it was renamed to.
942  renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
943 
944  // Put the renamed physical register back on the free list.
945  freeList->addReg(hb_it->newPhysReg);
946  }
947 
948  // Notify potential listeners that the register mapping needs to be
949  // removed because the instruction it was mapped to got squashed. Note
950  // that this is done before hb_it is incremented.
951  ppSquashInRename->notify(std::make_pair(hb_it->instSeqNum,
952  hb_it->newPhysReg));
953 
954  historyBuffer[tid].erase(hb_it++);
955 
956  ++stats.undoneMaps;
957  }
958 
959  // Check if we need to change vector renaming mode after squashing
961 }
962 
963 void
965 {
966  DPRINTF(Rename, "[tid:%i] Removing a committed instruction from the "
967  "history buffer %u (size=%i), until [sn:%llu].\n",
968  tid, tid, historyBuffer[tid].size(), inst_seq_num);
969 
970  auto hb_it = historyBuffer[tid].end();
971 
972  --hb_it;
973 
974  if (historyBuffer[tid].empty()) {
975  DPRINTF(Rename, "[tid:%i] History buffer is empty.\n", tid);
976  return;
977  } else if (hb_it->instSeqNum > inst_seq_num) {
978  DPRINTF(Rename, "[tid:%i] [sn:%llu] "
979  "Old sequence number encountered. "
980  "Ensure that a syscall happened recently.\n",
981  tid,inst_seq_num);
982  return;
983  }
984 
985  // Commit all the renames up until (and including) the committed sequence
986  // number. Some or even all of the committed instructions may not have
987  // rename histories if they did not have destination registers that were
988  // renamed.
989  while (!historyBuffer[tid].empty() &&
990  hb_it != historyBuffer[tid].end() &&
991  hb_it->instSeqNum <= inst_seq_num) {
992 
993  DPRINTF(Rename, "[tid:%i] Freeing up older rename of reg %i (%s), "
994  "[sn:%llu].\n",
995  tid, hb_it->prevPhysReg->index(),
996  hb_it->prevPhysReg->className(),
997  hb_it->instSeqNum);
998 
999  // Don't free special phys regs like misc and zero regs, which
1000  // can be recognized because the new mapping is the same as
1001  // the old one.
1002  if (hb_it->newPhysReg != hb_it->prevPhysReg) {
1003  freeList->addReg(hb_it->prevPhysReg);
1004  }
1005 
1006  ++stats.committedMaps;
1007 
1008  historyBuffer[tid].erase(hb_it--);
1009  }
1010 }
1011 
1012 void
1014 {
1015  gem5::ThreadContext *tc = inst->tcBase();
1016  UnifiedRenameMap *map = renameMap[tid];
1017  unsigned num_src_regs = inst->numSrcRegs();
1018 
1019  // Get the architectual register numbers from the source and
1020  // operands, and redirect them to the right physical register.
1021  for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
1022  const RegId& src_reg = inst->srcRegIdx(src_idx);
1023  PhysRegIdPtr renamed_reg;
1024 
1025  renamed_reg = map->lookup(tc->flattenRegId(src_reg));
1026  switch (src_reg.classValue()) {
1027  case IntRegClass:
1028  stats.intLookups++;
1029  break;
1030  case FloatRegClass:
1031  stats.fpLookups++;
1032  break;
1033  case VecRegClass:
1034  case VecElemClass:
1035  stats.vecLookups++;
1036  break;
1037  case VecPredRegClass:
1039  break;
1040  case CCRegClass:
1041  case MiscRegClass:
1042  break;
1043 
1044  default:
1045  panic("Invalid register class: %d.", src_reg.classValue());
1046  }
1047 
1048  DPRINTF(Rename,
1049  "[tid:%i] "
1050  "Looking up %s arch reg %i, got phys reg %i (%s)\n",
1051  tid, src_reg.className(),
1052  src_reg.index(), renamed_reg->index(),
1053  renamed_reg->className());
1054 
1055  inst->renameSrcReg(src_idx, renamed_reg);
1056 
1057  // See if the register is ready or not.
1058  if (scoreboard->getReg(renamed_reg)) {
1059  DPRINTF(Rename,
1060  "[tid:%i] "
1061  "Register %d (flat: %d) (%s) is ready.\n",
1062  tid, renamed_reg->index(), renamed_reg->flatIndex(),
1063  renamed_reg->className());
1064 
1065  inst->markSrcRegReady(src_idx);
1066  } else {
1067  DPRINTF(Rename,
1068  "[tid:%i] "
1069  "Register %d (flat: %d) (%s) is not ready.\n",
1070  tid, renamed_reg->index(), renamed_reg->flatIndex(),
1071  renamed_reg->className());
1072  }
1073 
1074  ++stats.lookups;
1075  }
1076 }
1077 
1078 void
1080 {
1081  gem5::ThreadContext *tc = inst->tcBase();
1082  UnifiedRenameMap *map = renameMap[tid];
1083  unsigned num_dest_regs = inst->numDestRegs();
1084 
1085  // Rename the destination registers.
1086  for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
1087  const RegId& dest_reg = inst->destRegIdx(dest_idx);
1088  UnifiedRenameMap::RenameInfo rename_result;
1089 
1090  RegId flat_dest_regid = tc->flattenRegId(dest_reg);
1091  flat_dest_regid.setNumPinnedWrites(dest_reg.getNumPinnedWrites());
1092 
1093  rename_result = map->rename(flat_dest_regid);
1094 
1095  inst->regs.flattenedDestIdx(dest_idx, flat_dest_regid);
1096 
1097  scoreboard->unsetReg(rename_result.first);
1098 
1099  DPRINTF(Rename,
1100  "[tid:%i] "
1101  "Renaming arch reg %i (%s) to physical reg %i (%i).\n",
1102  tid, dest_reg.index(), dest_reg.className(),
1103  rename_result.first->index(),
1104  rename_result.first->flatIndex());
1105 
1106  // Record the rename information so that a history can be kept.
1107  RenameHistory hb_entry(inst->seqNum, flat_dest_regid,
1108  rename_result.first,
1109  rename_result.second);
1110 
1111  historyBuffer[tid].push_front(hb_entry);
1112 
1113  DPRINTF(Rename, "[tid:%i] [sn:%llu] "
1114  "Adding instruction to history buffer (size=%i).\n",
1115  tid,(*historyBuffer[tid].begin()).instSeqNum,
1116  historyBuffer[tid].size());
1117 
1118  // Tell the instruction to rename the appropriate destination
1119  // register (dest_idx) to the new physical register
1120  // (rename_result.first), and record the previous physical
1121  // register that the same logical register was renamed to
1122  // (rename_result.second).
1123  inst->renameDestReg(dest_idx,
1124  rename_result.first,
1125  rename_result.second);
1126 
1128  }
1129 }
1130 
1131 int
1133 {
1134  int num_free = freeEntries[tid].robEntries -
1135  (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
1136 
1137  //DPRINTF(Rename,"[tid:%i] %i rob free\n",tid,num_free);
1138 
1139  return num_free;
1140 }
1141 
1142 int
1144 {
1145  int num_free = freeEntries[tid].iqEntries -
1146  (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
1147 
1148  //DPRINTF(Rename,"[tid:%i] %i iq free\n",tid,num_free);
1149 
1150  return num_free;
1151 }
1152 
1153 int
1155 {
1156  int num_free = freeEntries[tid].lqEntries -
1157  (loadsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLQ);
1158  DPRINTF(Rename,
1159  "calcFreeLQEntries: free lqEntries: %d, loadsInProgress: %d, "
1160  "loads dispatchedToLQ: %d\n",
1161  freeEntries[tid].lqEntries, loadsInProgress[tid],
1162  fromIEW->iewInfo[tid].dispatchedToLQ);
1163  return num_free;
1164 }
1165 
1166 int
1168 {
1169  int num_free = freeEntries[tid].sqEntries -
1170  (storesInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToSQ);
1171  DPRINTF(Rename, "calcFreeSQEntries: free sqEntries: %d, "
1172  "storesInProgress: %d, stores dispatchedToSQ: %d\n",
1173  freeEntries[tid].sqEntries, storesInProgress[tid],
1174  fromIEW->iewInfo[tid].dispatchedToSQ);
1175  return num_free;
1176 }
1177 
1178 unsigned
1180 {
1181  unsigned inst_count = 0;
1182 
1183  for (int i=0; i<fromDecode->size; i++) {
1184  if (!fromDecode->insts[i]->isSquashed())
1185  inst_count++;
1186  }
1187 
1188  return inst_count;
1189 }
1190 
1191 void
1193 {
1194  if (fromIEW->iewBlock[tid]) {
1195  stalls[tid].iew = true;
1196  }
1197 
1198  if (fromIEW->iewUnblock[tid]) {
1199  assert(stalls[tid].iew);
1200  stalls[tid].iew = false;
1201  }
1202 }
1203 
1204 bool
1206 {
1207  bool ret_val = false;
1208 
1209  if (stalls[tid].iew) {
1210  DPRINTF(Rename,"[tid:%i] Stall from IEW stage detected.\n", tid);
1211  ret_val = true;
1212  } else if (calcFreeROBEntries(tid) <= 0) {
1213  DPRINTF(Rename,"[tid:%i] Stall: ROB has 0 free entries.\n", tid);
1214  ret_val = true;
1215  } else if (calcFreeIQEntries(tid) <= 0) {
1216  DPRINTF(Rename,"[tid:%i] Stall: IQ has 0 free entries.\n", tid);
1217  ret_val = true;
1218  } else if (calcFreeLQEntries(tid) <= 0 && calcFreeSQEntries(tid) <= 0) {
1219  DPRINTF(Rename,"[tid:%i] Stall: LSQ has 0 free entries.\n", tid);
1220  ret_val = true;
1221  } else if (renameMap[tid]->numFreeEntries() <= 0) {
1222  DPRINTF(Rename,"[tid:%i] Stall: RenameMap has 0 free entries.\n", tid);
1223  ret_val = true;
1224  } else if (renameStatus[tid] == SerializeStall &&
1225  (!emptyROB[tid] || instsInProgress[tid])) {
1226  DPRINTF(Rename,"[tid:%i] Stall: Serialize stall and ROB is not "
1227  "empty.\n",
1228  tid);
1229  ret_val = true;
1230  }
1231 
1232  return ret_val;
1233 }
1234 
1235 void
1237 {
1238  if (fromIEW->iewInfo[tid].usedIQ)
1239  freeEntries[tid].iqEntries = fromIEW->iewInfo[tid].freeIQEntries;
1240 
1241  if (fromIEW->iewInfo[tid].usedLSQ) {
1242  freeEntries[tid].lqEntries = fromIEW->iewInfo[tid].freeLQEntries;
1243  freeEntries[tid].sqEntries = fromIEW->iewInfo[tid].freeSQEntries;
1244  }
1245 
1246  if (fromCommit->commitInfo[tid].usedROB) {
1247  freeEntries[tid].robEntries =
1248  fromCommit->commitInfo[tid].freeROBEntries;
1249  emptyROB[tid] = fromCommit->commitInfo[tid].emptyROB;
1250  }
1251 
1252  DPRINTF(Rename, "[tid:%i] Free IQ: %i, Free ROB: %i, "
1253  "Free LQ: %i, Free SQ: %i, FreeRM %i(%i %i %i %i %i)\n",
1254  tid,
1255  freeEntries[tid].iqEntries,
1256  freeEntries[tid].robEntries,
1257  freeEntries[tid].lqEntries,
1258  freeEntries[tid].sqEntries,
1259  renameMap[tid]->numFreeEntries(),
1260  renameMap[tid]->numFreeIntEntries(),
1261  renameMap[tid]->numFreeFloatEntries(),
1262  renameMap[tid]->numFreeVecEntries(),
1263  renameMap[tid]->numFreePredEntries(),
1264  renameMap[tid]->numFreeCCEntries());
1265 
1266  DPRINTF(Rename, "[tid:%i] %i instructions not yet in ROB\n",
1267  tid, instsInProgress[tid]);
1268 }
1269 
1270 bool
1272 {
1273  // Check if there's a squash signal, squash if there is
1274  // Check stall signals, block if necessary.
1275  // If status was blocked
1276  // check if stall conditions have passed
1277  // if so then go to unblocking
1278  // If status was Squashing
1279  // check if squashing is not high. Switch to running this cycle.
1280  // If status was serialize stall
1281  // check if ROB is empty and no insts are in flight to the ROB
1282 
1283  readFreeEntries(tid);
1284  readStallSignals(tid);
1285 
1286  if (fromCommit->commitInfo[tid].squash) {
1287  DPRINTF(Rename, "[tid:%i] Squashing instructions due to squash from "
1288  "commit.\n", tid);
1289 
1290  squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
1291 
1292  return true;
1293  }
1294 
1295  if (checkStall(tid)) {
1296  return block(tid);
1297  }
1298 
1299  if (renameStatus[tid] == Blocked) {
1300  DPRINTF(Rename, "[tid:%i] Done blocking, switching to unblocking.\n",
1301  tid);
1302 
1303  renameStatus[tid] = Unblocking;
1304 
1305  unblock(tid);
1306 
1307  return true;
1308  }
1309 
1310  if (renameStatus[tid] == Squashing) {
1311  // Switch status to running if rename isn't being told to block or
1312  // squash this cycle.
1313  if (resumeSerialize) {
1314  DPRINTF(Rename,
1315  "[tid:%i] Done squashing, switching to serialize.\n", tid);
1316 
1318  return true;
1319  } else if (resumeUnblocking) {
1320  DPRINTF(Rename,
1321  "[tid:%i] Done squashing, switching to unblocking.\n",
1322  tid);
1323  renameStatus[tid] = Unblocking;
1324  return true;
1325  } else {
1326  DPRINTF(Rename, "[tid:%i] Done squashing, switching to running.\n",
1327  tid);
1328  renameStatus[tid] = Running;
1329  return false;
1330  }
1331  }
1332 
1333  if (renameStatus[tid] == SerializeStall) {
1334  // Stall ends once the ROB is free.
1335  DPRINTF(Rename, "[tid:%i] Done with serialize stall, switching to "
1336  "unblocking.\n", tid);
1337 
1338  DynInstPtr serial_inst = serializeInst[tid];
1339 
1340  renameStatus[tid] = Unblocking;
1341 
1342  unblock(tid);
1343 
1344  DPRINTF(Rename, "[tid:%i] Processing instruction [%lli] with "
1345  "PC %s.\n", tid, serial_inst->seqNum, serial_inst->pcState());
1346 
1347  // Put instruction into queue here.
1348  serial_inst->clearSerializeBefore();
1349 
1350  if (!skidBuffer[tid].empty()) {
1351  skidBuffer[tid].push_front(serial_inst);
1352  } else {
1353  insts[tid].push_front(serial_inst);
1354  }
1355 
1356  DPRINTF(Rename, "[tid:%i] Instruction must be processed by rename."
1357  " Adding to front of list.\n", tid);
1358 
1359  serializeInst[tid] = NULL;
1360 
1361  return true;
1362  }
1363 
1364  // If we've reached this point, we have not gotten any signals that
1365  // cause rename to change its status. Rename remains the same as before.
1366  return false;
1367 }
1368 
1369 void
1371 {
1372  if (inst_list.empty()) {
1373  // Mark a bit to say that I must serialize on the next instruction.
1374  serializeOnNextInst[tid] = true;
1375  return;
1376  }
1377 
1378  // Set the next instruction as serializing.
1379  inst_list.front()->setSerializeBefore();
1380 }
1381 
1382 void
1384 {
1385  switch (source) {
1386  case ROB:
1387  ++stats.ROBFullEvents;
1388  break;
1389  case IQ:
1390  ++stats.IQFullEvents;
1391  break;
1392  case LQ:
1393  ++stats.LQFullEvents;
1394  break;
1395  case SQ:
1396  ++stats.SQFullEvents;
1397  break;
1398  default:
1399  panic("Rename full stall stat should be incremented for a reason!");
1400  break;
1401  }
1402 }
1403 
1404 void
1406 {
1408 
1409  for (ThreadID tid = 0; tid < numThreads; tid++) {
1410 
1411  buf_it = historyBuffer[tid].begin();
1412 
1413  while (buf_it != historyBuffer[tid].end()) {
1414  cprintf("Seq num: %i\nArch reg[%s]: %i New phys reg:"
1415  " %i[%s] Old phys reg: %i[%s]\n",
1416  (*buf_it).instSeqNum,
1417  (*buf_it).archReg.className(),
1418  (*buf_it).archReg.index(),
1419  (*buf_it).newPhysReg->index(),
1420  (*buf_it).newPhysReg->className(),
1421  (*buf_it).prevPhysReg->index(),
1422  (*buf_it).prevPhysReg->className());
1423 
1424  buf_it++;
1425  }
1426  }
1427 }
1428 
1429 } // namespace o3
1430 } // namespace gem5
gem5::o3::Rename::isDrained
bool isDrained() const
Has the stage drained?
Definition: rename.cc:305
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:189
gem5::o3::Rename::decodeToRenameDelay
int decodeToRenameDelay
Delay between decode and rename, in ticks.
Definition: rename.hh:432
gem5::VecElemClass
@ VecElemClass
Vector Register Native Elem lane.
Definition: reg_class.hh:62
gem5::CCRegClass
@ CCRegClass
Condition-code register.
Definition: reg_class.hh:64
gem5::o3::Rename::freeEntries
FreeEntries freeEntries[MaxThreads]
Per-thread tracking of the number of free entries of back-end structures.
Definition: rename.hh:402
gem5::o3::Rename::storesInProgress
int storesInProgress[MaxThreads]
Count of Store instructions in progress that have been sent off to the IQ and ROB,...
Definition: rename.hh:381
gem5::o3::Rename::tick
void tick()
Ticks rename, which processes all input signals and attempts to rename as many instructions as possib...
Definition: rename.cc:389
gem5::o3::Rename::serializeOnNextInst
bool serializeOnNextInst[MaxThreads]
Records if rename needs to serialize on the next instruction for any thread.
Definition: rename.hh:426
warn
#define warn(...)
Definition: logging.hh:245
gem5::o3::Rename::drainSanityCheck
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: rename.cc:325
gem5::o3::Rename::squash
void squash(const InstSeqNum &squash_seq_num, ThreadID tid)
Squashes all instructions in a thread.
Definition: rename.cc:336
gem5::o3::Rename::iew_ptr
IEW * iew_ptr
Pointer to IEW stage.
Definition: rename.hh:157
gem5::cprintf
void cprintf(const char *format, const Args &...args)
Definition: cprintf.hh:155
gem5::o3::Rename::FreeEntries::sqEntries
unsigned sqEntries
Definition: rename.hh:396
gem5::RegId::getNumPinnedWrites
int getNumPinnedWrites() const
Definition: reg_class.hh:184
gem5::o3::Rename::dumpHistory
void dumpHistory()
Debugging function used to dump history buffer of renamings.
Definition: rename.cc:1405
gem5::o3::Rename::setRenameQueue
void setRenameQueue(TimeBuffer< RenameStruct > *rq_ptr)
Sets pointer to time buffer used to communicate to the next stage.
Definition: rename.cc:203
gem5::o3::Rename::calcFreeROBEntries
int calcFreeROBEntries(ThreadID tid)
Calculates the number of free ROB entries for a specific thread.
Definition: rename.cc:1132
gem5::o3::Rename::validInsts
unsigned validInsts()
Returns the number of valid instructions coming from decode.
Definition: rename.cc:1179
gem5::o3::Rename::RenameStats::blockCycles
statistics::Scalar blockCycles
Stat for total number of cycles spent blocking.
Definition: rename.hh:488
gem5::o3::Scoreboard::getReg
bool getReg(PhysRegIdPtr phys_reg) const
Checks if the register is ready.
Definition: scoreboard.hh:86
rename.hh
gem5::o3::Rename::setRenameMap
void setRenameMap(UnifiedRenameMap rm_ptr[MaxThreads])
Sets pointer to rename maps (per-thread structures).
Definition: rename.cc:286
gem5::o3::Rename::RenameStats::runCycles
statistics::Scalar runCycles
Stat for total number of cycles spent running normally.
Definition: rename.hh:493
gem5::o3::Rename::wroteToTimeBuffer
bool wroteToTimeBuffer
Variable that tracks if decode has written to the time buffer this cycle.
Definition: rename.hh:386
gem5::o3::Rename::_status
RenameStatus _status
Rename status.
Definition: rename.hh:111
gem5::o3::Rename::Squashing
@ Squashing
Definition: rename.hh:103
gem5::o3::Rename::resumeSerialize
bool resumeSerialize
Whether or not rename needs to resume a serialize instruction after squashing.
Definition: rename.hh:450
gem5::o3::Rename::instsInProgress
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
gem5::o3::Rename::skidInsert
void skidInsert(ThreadID tid)
Inserts unused instructions from a given thread into the skid buffer, to be renamed once rename unblo...
Definition: rename.cc:762
gem5::o3::Rename::commitToRenameDelay
unsigned commitToRenameDelay
Delay between commit and rename, in ticks.
Definition: rename.hh:435
gem5::o3::Rename::removeFromHistory
void removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid)
Removes a committed instruction's rename history.
Definition: rename.cc:964
gem5::o3::Rename::RenameStats::RenameStats
RenameStats(statistics::Group *parent)
Definition: rename.cc:97
gem5::o3::Rename::freeList
UnifiedFreeList * freeList
Free list interface.
Definition: rename.hh:360
gem5::o3::CPU::RenameIdx
@ RenameIdx
Definition: cpu.hh:539
gem5::o3::Rename::renameQueue
TimeBuffer< RenameStruct > * renameQueue
Rename instruction queue.
Definition: rename.hh:339
gem5::o3::Rename::setScoreboard
void setScoreboard(Scoreboard *_scoreboard)
Sets pointer to the scoreboard.
Definition: rename.cc:299
gem5::o3::Rename::RenameStats::renamedInsts
statistics::Scalar renamedInsts
Stat for total number of renamed instructions.
Definition: rename.hh:497
gem5::o3::Rename::RenameStats::vecPredLookups
statistics::Scalar vecPredLookups
Definition: rename.hh:523
gem5::o3::Rename::historyBuffer
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
gem5::o3::Rename::block
bool block(ThreadID tid)
Switches rename to blocking, and signals back that rename has become blocked.
Definition: rename.cc:863
gem5::FloatRegClass
@ FloatRegClass
Floating-point register.
Definition: reg_class.hh:58
gem5::o3::Rename::FreeEntries::iqEntries
unsigned iqEntries
Definition: rename.hh:393
gem5::o3::Rename::unblock
bool unblock(ThreadID tid)
Switches rename to unblocking if the skid buffer is empty, and signals back that rename has unblocked...
Definition: rename.cc:896
gem5::o3::Rename::timeBuffer
TimeBuffer< TimeStruct > * timeBuffer
Pointer to main time buffer used for backwards communication.
Definition: rename.hh:327
gem5::o3::Rename::renameDestRegs
void renameDestRegs(const DynInstPtr &inst, ThreadID tid)
Renames the destination registers of an instruction.
Definition: rename.cc:1079
gem5::MiscRegClass
@ MiscRegClass
Control (misc) register.
Definition: reg_class.hh:65
gem5::o3::Rename::ppSquashInRename
ProbePointArg< SeqNumRegPair > * ppSquashInRename
To probe when an instruction is squashed and the register mapping for it needs to be undone.
Definition: rename.hh:124
gem5::o3::UnifiedFreeList
FreeList class that simply holds the list of free integer and floating point registers.
Definition: free_list.hh:122
gem5::VecPredRegClass
@ VecPredRegClass
Definition: reg_class.hh:63
gem5::o3::Rename::RenameStats::fpLookups
statistics::Scalar fpLookups
Definition: rename.hh:521
gem5::o3::Scoreboard
Implements a simple scoreboard to track which registers are ready.
Definition: scoreboard.hh:53
gem5::o3::Rename::numThreads
ThreadID numThreads
The number of threads active in rename.
Definition: rename.hh:457
gem5::o3::Rename::skidsEmpty
bool skidsEmpty()
Returns if all of the skid buffers are empty.
Definition: rename.cc:809
dyn_inst.hh
gem5::o3::Rename::RenameStats::SQFullEvents
statistics::Scalar SQFullEvents
Stat for total number of times that the SQ starts a stall in rename.
Definition: rename.hh:512
gem5::RegId::classValue
RegClass classValue() const
Class accessor.
Definition: reg_class.hh:180
gem5::o3::Rename::sortInsts
void sortInsts()
Separates instructions from decode into individual lists of instructions sorted by thread.
Definition: rename.cc:794
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:66
gem5::o3::Rename::skidBufferMax
unsigned skidBufferMax
The maximum skid buffer size.
Definition: rename.hh:460
gem5::RegId::index
RegIndex index() const
Index accessors.
Definition: reg_class.hh:154
gem5::o3::Rename::RenameStats::undoneMaps
statistics::Scalar undoneMaps
Stat for total number of mappings that were undone due to a squash.
Definition: rename.hh:528
gem5::o3::Rename::Stalls::iew
bool iew
Definition: rename.hh:413
gem5::o3::Rename::RenameStats::serializeStallCycles
statistics::Scalar serializeStallCycles
Stat for total number of cycles spent stalling for a serializing inst.
Definition: rename.hh:491
gem5::o3::Rename::RenameStats::skidInsts
statistics::Scalar skidInsts
Number of instructions inserted into skid buffers.
Definition: rename.hh:534
gem5::o3::Rename::RenameStats::unblockCycles
statistics::Scalar unblockCycles
Stat for total number of cycles spent unblocking.
Definition: rename.hh:495
gem5::RefCountingPtr< DynInst >
gem5::TimeBuffer
Definition: timebuf.hh:40
gem5::o3::Rename::Blocked
@ Blocked
Definition: rename.hh:104
gem5::o3::Rename::Unblocking
@ Unblocking
Definition: rename.hh:105
gem5::o3::Rename::calcFreeLQEntries
int calcFreeLQEntries(ThreadID tid)
Calculates the number of free LQ entries for a specific thread.
Definition: rename.cc:1154
gem5::o3::Commit::numROBFreeEntries
size_t numROBFreeEntries(ThreadID tid)
Returns the number of free ROB entries for a specific thread.
Definition: commit.cc:493
gem5::o3::Rename::Inactive
@ Inactive
Definition: rename.hh:94
gem5::o3::Rename::RenameStats::serializing
statistics::Scalar serializing
Number of serialize instructions handled.
Definition: rename.hh:530
gem5::o3::CPU::deactivateStage
void deactivateStage(const StageIdx idx)
Changes a stage's status to inactive within the activity recorder.
Definition: cpu.hh:576
gem5::o3::Rename::decodeQueue
TimeBuffer< DecodeStruct > * decodeQueue
Decode instruction queue interface.
Definition: rename.hh:345
gem5::o3::Rename::rename
void rename(bool &status_change, ThreadID tid)
Determines what to do based on rename's current status.
Definition: rename.cc:452
gem5::o3::IEW::instQueue
InstructionQueue instQueue
Instruction queue.
Definition: iew.hh:355
gem5::o3::Rename::Running
@ Running
Definition: rename.hh:100
gem5::o3::Rename::Active
@ Active
Definition: rename.hh:93
gem5::o3::Rename::clearStates
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition: rename.cc:227
gem5::o3::Rename::renameSrcRegs
void renameSrcRegs(const DynInstPtr &inst, ThreadID tid)
Renames the source registers of an instruction.
Definition: rename.cc:1013
gem5::o3::Rename::ROB
@ ROB
Definition: rename.hh:467
gem5::o3::Rename::renameWidth
unsigned renameWidth
Rename width, in instructions.
Definition: rename.hh:438
gem5::o3::Rename::scoreboard
Scoreboard * scoreboard
Pointer to the scoreboard.
Definition: rename.hh:366
gem5::RegId::setNumPinnedWrites
void setNumPinnedWrites(int num_writes)
Definition: reg_class.hh:185
gem5::PhysRegId::flatIndex
const RegIndex & flatIndex() const
Flat index accessor.
Definition: reg_class.hh:263
gem5::o3::Rename::LQ
@ LQ
Definition: rename.hh:469
gem5::o3::CPU
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
Definition: cpu.hh:95
gem5::o3::Rename::stalls
Stalls stalls[MaxThreads]
Tracks which stages are telling decode to stall.
Definition: rename.hh:418
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:93
gem5::o3::Rename::IQ
@ IQ
Definition: rename.hh:468
gem5::Named::name
virtual std::string name() const
Definition: named.hh:47
gem5::ThreadContext::flattenRegId
virtual RegId flattenRegId(const RegId &reg_id) const =0
gem5::o3::Rename::name
std::string name() const
Returns the name of rename.
Definition: rename.cc:92
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
gem5::o3::Rename::updateStatus
void updateStatus()
Updates overall rename status based on all of the threads' statuses.
Definition: rename.cc:825
gem5::o3::Rename::Idle
@ Idle
Definition: rename.hh:101
gem5::o3::Rename::RenameStats::idleCycles
statistics::Scalar idleCycles
Stat for total number of cycles spent idle.
Definition: rename.hh:486
gem5::o3::Rename::fromDecode
TimeBuffer< DecodeStruct >::wire fromDecode
Wire to get decode's output from decode queue.
Definition: rename.hh:348
gem5::o3::Rename::ppRename
ProbePointArg< DynInstPtr > * ppRename
To probe when register renaming for an instruction is complete.
Definition: rename.hh:119
gem5::o3::Rename::RenameStats::tempSerializing
statistics::Scalar tempSerializing
Number of instructions marked as temporarily serializing.
Definition: rename.hh:532
gem5::o3::Rename::doSquash
void doSquash(const InstSeqNum &squash_seq_num, ThreadID tid)
Executes actual squash, removing squashed instructions.
Definition: rename.cc:916
gem5::o3::Rename::checkStall
bool checkStall(ThreadID tid)
Checks if any stages are telling rename to block.
Definition: rename.cc:1205
gem5::o3::Rename::resetStage
void resetStage()
Reset this pipeline stage.
Definition: rename.cc:248
gem5::o3::Rename::RenameHistory
Holds the information for each destination register rename.
Definition: rename.hh:297
gem5::o3::CPU::activateStage
void activateStage(const StageIdx idx)
Changes a stage's status to active within the activity recorder.
Definition: cpu.hh:572
gem5::o3::LSQ::numFreeLoadEntries
unsigned numFreeLoadEntries()
Returns the number of free load entries.
Definition: lsq.cc:515
gem5::o3::InstructionQueue::numFreeEntries
unsigned numFreeEntries()
Returns total number of free entries.
Definition: inst_queue.cc:509
gem5::o3::Rename::insts
InstQueue insts[MaxThreads]
Queue of all instructions coming from decode this cycle.
Definition: rename.hh:351
gem5::o3::Rename::calcFreeIQEntries
int calcFreeIQEntries(ThreadID tid)
Calculates the number of free IQ entries for a specific thread.
Definition: rename.cc:1143
gem5::o3::Rename::SQ
@ SQ
Definition: rename.hh:470
gem5::o3::MaxWidth
static constexpr int MaxWidth
Definition: limits.hh:37
gem5::o3::Rename::loadsInProgress
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
gem5::RegId::className
const char * className() const
Return a const char* with the register class name.
Definition: reg_class.hh:182
gem5::o3::Rename::RenameStats::lookups
statistics::Scalar lookups
Stat for total number of source register rename lookups.
Definition: rename.hh:519
std::pair
STL pair class.
Definition: stl.hh:58
gem5::o3::Rename::cpu
CPU * cpu
Pointer to CPU.
Definition: rename.hh:324
gem5::o3::Rename::toIEWIndex
unsigned toIEWIndex
The index of the instruction in the time buffer to IEW that rename is currently using.
Definition: rename.hh:443
gem5::o3::Rename::renameMap
UnifiedRenameMap * renameMap[MaxThreads]
Rename map interface.
Definition: rename.hh:357
gem5::o3::Rename::RenameStats::fullRegistersEvents
statistics::Scalar fullRegistersEvents
Stat for total number of times that rename runs out of free registers to use to rename.
Definition: rename.hh:515
gem5::o3::Rename::RenameStats::renamedOperands
statistics::Scalar renamedOperands
Stat for total number of renamed destination registers.
Definition: rename.hh:517
gem5::o3::Scoreboard::unsetReg
void unsetReg(PhysRegIdPtr phys_reg)
Sets the register as not ready.
Definition: scoreboard.hh:123
gem5::o3::Rename::RenameStats::IQFullEvents
statistics::Scalar IQFullEvents
Stat for total number of times that the IQ starts a stall in rename.
Definition: rename.hh:506
gem5::o3::Rename::setTimeBuffer
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets the main backwards communication time buffer pointer.
Definition: rename.cc:188
gem5::ProbePointArg
ProbePointArg generates a point for the class of Arg.
Definition: thermal_domain.hh:54
gem5::o3::Rename::serializeAfter
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:1370
gem5::o3::Rename::FreeEntries::robEntries
unsigned robEntries
Definition: rename.hh:394
gem5::SimObject::getProbeManager
ProbeManager * getProbeManager()
Get the probe manager for this object.
Definition: sim_object.cc:120
gem5::o3::MaxThreads
static constexpr int MaxThreads
Definition: limits.hh:38
gem5::o3::Rename::Rename
Rename(CPU *_cpu, const O3CPUParams &params)
Rename constructor.
Definition: rename.cc:61
gem5::o3::Rename
Rename handles both single threaded and SMT rename.
Definition: rename.hh:78
gem5::VecRegClass
@ VecRegClass
Vector Register.
Definition: reg_class.hh:60
gem5::o3::CPU::activityThisCycle
void activityThisCycle()
Records that there was time buffer activity this cycle.
Definition: cpu.hh:569
gem5::o3::Rename::iewToRenameDelay
int iewToRenameDelay
Delay between iew and rename, in ticks.
Definition: rename.hh:429
gem5::o3::Rename::stats
gem5::o3::Rename::RenameStats stats
gem5::o3::Rename::RenameStats::ROBFullEvents
statistics::Scalar ROBFullEvents
Stat for total number of times that the ROB starts a stall in rename.
Definition: rename.hh:503
gem5::o3::Rename::incrFullStat
void incrFullStat(const FullSource &source)
Function used to increment the stat that corresponds to the source of the stall.
Definition: rename.cc:1383
gem5::statistics::DataWrap::prereq
Derived & prereq(const Stat &prereq)
Set the prerequisite stat and marks this stat to print at the end of simulation.
Definition: statistics.hh:369
gem5::PhysRegId::className
const char * className() const
Return a const char* with the register class name.
Definition: reg_class.hh:182
gem5::o3::Rename::calcFreeSQEntries
int calcFreeSQEntries(ThreadID tid)
Calculates the number of free SQ entries for a specific thread.
Definition: rename.cc:1167
gem5::o3::CPU::switchRenameMode
void switchRenameMode(ThreadID tid, UnifiedFreeList *freelist)
Check if a change in renaming is needed for vector registers.
Definition: cpu.cc:860
gem5::o3::Rename::RenameStats::vecLookups
statistics::Scalar vecLookups
Definition: rename.hh:522
gem5::o3::Rename::setDecodeQueue
void setDecodeQueue(TimeBuffer< DecodeStruct > *dq_ptr)
Sets pointer to time buffer coming from decode.
Definition: rename.cc:212
gem5::o3::Rename::fromCommit
TimeBuffer< TimeStruct >::wire fromCommit
Wire to get commit's output from backwards time buffer.
Definition: rename.hh:333
std::deque< DynInstPtr >
gem5::o3::Rename::emptyROB
bool emptyROB[MaxThreads]
Records if the ROB is empty.
Definition: rename.hh:408
gem5::o3::Rename::SerializeStall
@ SerializeStall
Definition: rename.hh:106
gem5::o3::LSQ::numFreeStoreEntries
unsigned numFreeStoreEntries()
Returns the number of free store entries.
Definition: lsq.cc:532
reg_class.hh
gem5::o3::UnifiedRenameMap::lookup
PhysRegIdPtr lookup(const RegId &arch_reg) const
Look up the physical register mapped to an architectural register.
Definition: rename_map.hh:266
gem5::o3::Rename::checkSignalsAndUpdate
bool checkSignalsAndUpdate(ThreadID tid)
Checks the signals and updates the status.
Definition: rename.cc:1271
gem5::statistics::Group
Statistics container.
Definition: group.hh:93
gem5::InstSeqNum
uint64_t InstSeqNum
Definition: inst_seq.hh:40
gem5::PhysRegId
Physical register ID.
Definition: reg_class.hh:198
gem5::o3::Rename::startupStage
void startupStage()
Initializes variables for the stage.
Definition: rename.cc:221
gem5::o3::Rename::setFreeList
void setFreeList(UnifiedFreeList *fl_ptr)
Sets pointer to the free list.
Definition: rename.cc:293
gem5::o3::Rename::RenameStats::committedMaps
statistics::Scalar committedMaps
Stat for total number of committed renaming mappings.
Definition: rename.hh:525
gem5::o3::Rename::blockThisCycle
bool blockThisCycle
Whether or not rename needs to block this cycle.
Definition: rename.hh:446
gem5::o3::Rename::FullSource
FullSource
Enum to record the source of a structure full stall.
Definition: rename.hh:465
gem5::o3::Rename::fromIEW
TimeBuffer< TimeStruct >::wire fromIEW
Wire to get IEW's output from backwards time buffer.
Definition: rename.hh:330
gem5::o3::Rename::readStallSignals
void readStallSignals(ThreadID tid)
Reads signals telling rename to block/unblock.
Definition: rename.cc:1192
gem5::o3::Rename::regProbePoints
void regProbePoints()
Registers probes.
Definition: rename.cc:179
gem5::o3::Rename::serializeInst
DynInstPtr serializeInst[MaxThreads]
The serialize instruction that rename has stalled on.
Definition: rename.hh:421
gem5::statistics::DataWrap::flags
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:355
gem5::o3::IEW::ldstQueue
LSQ ldstQueue
Load / store queue.
Definition: iew.hh:358
cpu.hh
std::list< ThreadID >
gem5::o3::Rename::renameInsts
void renameInsts(ThreadID tid)
Renames instructions for the given thread.
Definition: rename.cc:507
gem5::o3::Rename::RenameStats::squashedInsts
statistics::Scalar squashedInsts
Stat for total number of squashed instructions that rename discards.
Definition: rename.hh:500
gem5::o3::Rename::RenameStats::squashCycles
statistics::Scalar squashCycles
Stat for total number of cycles spent squashing.
Definition: rename.hh:484
gem5::o3::Rename::toDecode
TimeBuffer< TimeStruct >::wire toDecode
Wire to write infromation heading to previous stages.
Definition: rename.hh:336
gem5::IntRegClass
@ IntRegClass
Integer register.
Definition: reg_class.hh:57
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::statistics::total
const FlagsType total
Print the total.
Definition: info.hh:60
limits.hh
gem5::o3::Rename::takeOverFrom
void takeOverFrom()
Takes over from another CPU's thread.
Definition: rename.cc:319
gem5::o3::Rename::activeThreads
std::list< ThreadID > * activeThreads
Pointer to the list of active threads.
Definition: rename.hh:363
gem5::o3::Rename::RenameStats::LQFullEvents
statistics::Scalar LQFullEvents
Stat for total number of times that the LQ starts a stall in rename.
Definition: rename.hh:509
gem5::o3::Rename::FreeEntries::lqEntries
unsigned lqEntries
Definition: rename.hh:395
gem5::o3::Rename::RenameStats::intLookups
statistics::Scalar intLookups
Definition: rename.hh:520
gem5::o3::UnifiedRenameMap::rename
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:226
gem5::PhysRegId::index
RegIndex index() const
Visible RegId methods.
Definition: reg_class.hh:154
gem5::o3::Rename::toIEW
TimeBuffer< RenameStruct >::wire toIEW
Wire to write any information heading to IEW.
Definition: rename.hh:342
gem5::o3::Rename::renameStatus
ThreadStatus renameStatus[MaxThreads]
Per-thread status.
Definition: rename.hh:114
gem5::o3::Rename::resumeUnblocking
bool resumeUnblocking
Whether or not rename needs to resume clearing out the skidbuffer after squashing.
Definition: rename.hh:454
gem5::o3::Rename::readFreeEntries
void readFreeEntries(ThreadID tid)
Gets the number of free entries for a specific thread.
Definition: rename.cc:1236
gem5::o3::UnifiedFreeList::addReg
void addReg(PhysRegIdPtr freed_reg)
Adds a register back to the free list.
Definition: free_list.hh:303
gem5::ThreadID
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:242
gem5::o3::Rename::commit_ptr
Commit * commit_ptr
Pointer to commit stage.
Definition: rename.hh:160
gem5::RegId
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:88
gem5::o3::Rename::skidBuffer
InstQueue skidBuffer[MaxThreads]
Skid buffer between rename and decode.
Definition: rename.hh:354
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:177
gem5::o3::UnifiedRenameMap::setEntry
void setEntry(const RegId &arch_reg, PhysRegIdPtr phys_reg)
Update rename map with a specific mapping.
Definition: rename_map.hh:309
gem5::o3::Rename::setActiveThreads
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to list of active threads.
Definition: rename.cc:279
gem5::o3::UnifiedRenameMap
Unified register rename map for all classes of registers.
Definition: rename_map.hh:174

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