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

Generated on Mon Oct 27 2025 04:13:00 for gem5 by doxygen 1.14.0