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

Generated on Tue Jun 18 2024 16:24:02 for gem5 by doxygen 1.11.0