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

Generated on Tue Mar 23 2021 19:41:25 for gem5 by doxygen 1.8.17