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

Generated on Mon May 26 2025 09:19:08 for gem5 by doxygen 1.13.2