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

Generated on Thu May 28 2020 16:21:31 for gem5 by doxygen 1.8.13