diff options
author | Steve Reinhardt <steve.reinhardt@amd.com> | 2013-10-15 14:22:44 -0400 |
---|---|---|
committer | Steve Reinhardt <steve.reinhardt@amd.com> | 2013-10-15 14:22:44 -0400 |
commit | 552622184752dc798bc81f9b0b395db68aee9511 (patch) | |
tree | f8867449ca560470442878da448118277f561cbd /src/cpu/o3/rename_impl.hh | |
parent | 219c423f1fb0f9a559bfa87f9812426d5e2c3e29 (diff) | |
download | gem5-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.hh | 135 |
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); |