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

Generated on Wed Sep 30 2020 14:02:09 for gem5 by doxygen 1.8.17