summaryrefslogtreecommitdiff
path: root/src/cpu/o3/rename_impl.hh
diff options
context:
space:
mode:
authorSteve Reinhardt <steve.reinhardt@amd.com>2013-10-15 14:22:44 -0400
committerSteve Reinhardt <steve.reinhardt@amd.com>2013-10-15 14:22:44 -0400
commit552622184752dc798bc81f9b0b395db68aee9511 (patch)
treef8867449ca560470442878da448118277f561cbd /src/cpu/o3/rename_impl.hh
parent219c423f1fb0f9a559bfa87f9812426d5e2c3e29 (diff)
downloadgem5-552622184752dc798bc81f9b0b395db68aee9511.tar.xz
cpu/o3: clean up rename map and free list
Restructured rename map and free list to clean up some extraneous code and separate out common code that can be reused across different register classes (int and fp at this point). Both components now consist of a set of Simple* objects that are stand-alone rename map & free list for each class, plus a Unified* object that presents a unified interface across all register classes and then redirects accesses to the appropriate Simple* object as needed. Moved free list initialization to PhysRegFile to better isolate knowledge of physical register index mappings to that class (and remove the need to pass a number of parameters to the free list constructor). Causes a small change to these stats: cpu.rename.int_rename_lookups cpu.rename.fp_rename_lookups because they are now categorized on a per-operand basis rather than a per-instruction basis. That is, an instruction with mixed fp/int/misc operand types will have each operand categorized independently, where previously the lookup was categorized based on the instruction type.
Diffstat (limited to 'src/cpu/o3/rename_impl.hh')
-rw-r--r--src/cpu/o3/rename_impl.hh135
1 files changed, 69 insertions, 66 deletions
diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh
index 60a929551..6bfc7d952 100644
--- a/src/cpu/o3/rename_impl.hh
+++ b/src/cpu/o3/rename_impl.hh
@@ -871,18 +871,26 @@ DefaultRename<Impl>::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid)
// Go through the most recent instructions, undoing the mappings
// they did and freeing up the registers.
while (!historyBuffer[tid].empty() &&
- (*hb_it).instSeqNum > squashed_seq_num) {
+ hb_it->instSeqNum > squashed_seq_num) {
assert(hb_it != historyBuffer[tid].end());
DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence "
- "number %i.\n", tid, (*hb_it).instSeqNum);
-
- // Tell the rename map to set the architected register to the
- // previous physical register that it was renamed to.
- renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
-
- // Put the renamed physical register back on the free list.
- freeList->addReg(hb_it->newPhysReg);
+ "number %i.\n", tid, hb_it->instSeqNum);
+
+ // Undo the rename mapping only if it was really a change.
+ // Special regs that are not really renamed (like misc regs
+ // and the zero reg) can be recognized because the new mapping
+ // is the same as the old one. While it would be merely a
+ // waste of time to update the rename table, we definitely
+ // don't want to put these on the free list.
+ if (hb_it->newPhysReg != hb_it->prevPhysReg) {
+ // Tell the rename map to set the architected register to the
+ // previous physical register that it was renamed to.
+ renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
+
+ // Put the renamed physical register back on the free list.
+ freeList->addReg(hb_it->newPhysReg);
+ }
historyBuffer[tid].erase(hb_it++);
@@ -918,13 +926,19 @@ DefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid)
// renamed.
while (!historyBuffer[tid].empty() &&
hb_it != historyBuffer[tid].end() &&
- (*hb_it).instSeqNum <= inst_seq_num) {
+ hb_it->instSeqNum <= inst_seq_num) {
DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i, "
"[sn:%lli].\n",
- tid, (*hb_it).prevPhysReg, (*hb_it).instSeqNum);
+ tid, hb_it->prevPhysReg, hb_it->instSeqNum);
+
+ // Don't free special phys regs like misc and zero regs, which
+ // can be recognized because the new mapping is the same as
+ // the old one.
+ if (hb_it->newPhysReg != hb_it->prevPhysReg) {
+ freeList->addReg(hb_it->prevPhysReg);
+ }
- freeList->addReg((*hb_it).prevPhysReg);
++renameCommittedMaps;
historyBuffer[tid].erase(hb_it--);
@@ -935,54 +949,49 @@ template <class Impl>
inline void
DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid)
{
- assert(renameMap[tid] != 0);
-
+ ThreadContext *tc = inst->tcBase();
+ RenameMap *map = renameMap[tid];
unsigned num_src_regs = inst->numSrcRegs();
// Get the architectual register numbers from the source and
- // destination operands, and redirect them to the right register.
- // Will need to mark dependencies though.
+ // operands, and redirect them to the right physical register.
for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
RegIndex src_reg = inst->srcRegIdx(src_idx);
- RegIndex flat_src_reg = src_reg;
- switch (regIdxToClass(src_reg)) {
+ RegIndex rel_src_reg;
+ RegIndex flat_rel_src_reg;
+ PhysRegIndex renamed_reg;
+
+ switch (regIdxToClass(src_reg, &rel_src_reg)) {
case IntRegClass:
- flat_src_reg = inst->tcBase()->flattenIntIndex(src_reg);
- DPRINTF(Rename, "Flattening index %d to %d.\n",
- (int)src_reg, (int)flat_src_reg);
+ flat_rel_src_reg = tc->flattenIntIndex(rel_src_reg);
+ renamed_reg = map->lookupInt(flat_rel_src_reg);
+ intRenameLookups++;
break;
case FloatRegClass:
- src_reg = src_reg - TheISA::FP_Reg_Base;
- flat_src_reg = inst->tcBase()->flattenFloatIndex(src_reg);
- DPRINTF(Rename, "Flattening index %d to %d.\n",
- (int)src_reg, (int)flat_src_reg);
- flat_src_reg += TheISA::NumIntRegs;
+ flat_rel_src_reg = tc->flattenFloatIndex(rel_src_reg);
+ renamed_reg = map->lookupFloat(flat_rel_src_reg);
+ fpRenameLookups++;
break;
case MiscRegClass:
- flat_src_reg = src_reg - TheISA::Misc_Reg_Base +
- TheISA::NumFloatRegs + TheISA::NumIntRegs;
- DPRINTF(Rename, "Adjusting reg index from %d to %d.\n",
- src_reg, flat_src_reg);
+ // misc regs don't get flattened
+ flat_rel_src_reg = rel_src_reg;
+ renamed_reg = map->lookupMisc(flat_rel_src_reg);
break;
default:
panic("Reg index is out of bound: %d.", src_reg);
}
- // Look up the source registers to get the phys. register they've
- // been renamed to, and set the sources to those registers.
- PhysRegIndex renamed_reg = renameMap[tid]->lookup(flat_src_reg);
-
- DPRINTF(Rename, "[tid:%u]: Looking up arch reg %i, got "
- "physical reg %i.\n", tid, (int)flat_src_reg,
- (int)renamed_reg);
+ DPRINTF(Rename, "[tid:%u]: Looking up %s arch reg %i (flattened %i), "
+ "got phys reg %i\n", tid, RegClassStrings[regIdxToClass(src_reg)],
+ (int)src_reg, (int)flat_rel_src_reg, (int)renamed_reg);
inst->renameSrcReg(src_idx, renamed_reg);
// See if the register is ready or not.
- if (scoreboard->getReg(renamed_reg) == true) {
+ if (scoreboard->getReg(renamed_reg)) {
DPRINTF(Rename, "[tid:%u]: Register %d is ready.\n",
tid, renamed_reg);
@@ -993,7 +1002,6 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid)
}
++renameRenameLookups;
- inst->isFloating() ? fpRenameLookups++ : intRenameLookups++;
}
}
@@ -1001,58 +1009,53 @@ template <class Impl>
inline void
DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid)
{
- typename RenameMap::RenameInfo rename_result;
-
+ ThreadContext *tc = inst->tcBase();
+ RenameMap *map = renameMap[tid];
unsigned num_dest_regs = inst->numDestRegs();
// Rename the destination registers.
for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
RegIndex dest_reg = inst->destRegIdx(dest_idx);
- RegIndex flat_dest_reg = dest_reg;
- switch (regIdxToClass(dest_reg)) {
+ RegIndex rel_dest_reg;
+ RegIndex flat_rel_dest_reg;
+ RegIndex flat_uni_dest_reg;
+ typename RenameMap::RenameInfo rename_result;
+
+ switch (regIdxToClass(dest_reg, &rel_dest_reg)) {
case IntRegClass:
- // Integer registers are flattened.
- flat_dest_reg = inst->tcBase()->flattenIntIndex(dest_reg);
- DPRINTF(Rename, "Flattening index %d to %d.\n",
- (int)dest_reg, (int)flat_dest_reg);
+ flat_rel_dest_reg = tc->flattenIntIndex(rel_dest_reg);
+ rename_result = map->renameInt(flat_rel_dest_reg);
+ flat_uni_dest_reg = flat_rel_dest_reg; // 1:1 mapping
break;
case FloatRegClass:
- dest_reg = dest_reg - TheISA::FP_Reg_Base;
- flat_dest_reg = inst->tcBase()->flattenFloatIndex(dest_reg);
- DPRINTF(Rename, "Flattening index %d to %d.\n",
- (int)dest_reg, (int)flat_dest_reg);
- flat_dest_reg += TheISA::NumIntRegs;
+ flat_rel_dest_reg = tc->flattenFloatIndex(rel_dest_reg);
+ rename_result = map->renameFloat(flat_rel_dest_reg);
+ flat_uni_dest_reg = flat_rel_dest_reg + TheISA::FP_Reg_Base;
break;
case MiscRegClass:
- // Floating point and Miscellaneous registers need their indexes
- // adjusted to account for the expanded number of flattened int regs.
- flat_dest_reg = dest_reg - TheISA::Misc_Reg_Base +
- TheISA::NumIntRegs + TheISA::NumFloatRegs;
- DPRINTF(Rename, "Adjusting reg index from %d to %d.\n",
- dest_reg, flat_dest_reg);
+ // misc regs don't get flattened
+ flat_rel_dest_reg = rel_dest_reg;
+ rename_result = map->renameMisc(flat_rel_dest_reg);
+ flat_uni_dest_reg = flat_rel_dest_reg + TheISA::Misc_Reg_Base;
break;
default:
panic("Reg index is out of bound: %d.", dest_reg);
}
- inst->flattenDestReg(dest_idx, flat_dest_reg);
-
- // Get the physical register that the destination will be
- // renamed to.
- rename_result = renameMap[tid]->rename(flat_dest_reg);
+ inst->flattenDestReg(dest_idx, flat_uni_dest_reg);
- //Mark Scoreboard entry as not ready
+ // Mark Scoreboard entry as not ready
scoreboard->unsetReg(rename_result.first);
DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical "
- "reg %i.\n", tid, (int)flat_dest_reg,
+ "reg %i.\n", tid, (int)flat_rel_dest_reg,
(int)rename_result.first);
// Record the rename information so that a history can be kept.
- RenameHistory hb_entry(inst->seqNum, flat_dest_reg,
+ RenameHistory hb_entry(inst->seqNum, flat_uni_dest_reg,
rename_result.first,
rename_result.second);