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

Generated on Fri Feb 28 2020 16:26:59 for gem5 by doxygen 1.8.13