diff options
Diffstat (limited to 'src/cpu/o3')
-rw-r--r-- | src/cpu/o3/free_list.hh | 9 | ||||
-rw-r--r-- | src/cpu/o3/iew_impl.hh | 13 | ||||
-rw-r--r-- | src/cpu/o3/inst_queue_impl.hh | 13 | ||||
-rw-r--r-- | src/cpu/o3/regfile.cc | 6 | ||||
-rw-r--r-- | src/cpu/o3/regfile.hh | 6 | ||||
-rw-r--r-- | src/cpu/o3/rename_impl.hh | 8 | ||||
-rw-r--r-- | src/cpu/o3/rename_map.cc | 25 |
7 files changed, 51 insertions, 29 deletions
diff --git a/src/cpu/o3/free_list.hh b/src/cpu/o3/free_list.hh index 46bebf30d..82ff25d3b 100644 --- a/src/cpu/o3/free_list.hh +++ b/src/cpu/o3/free_list.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 ARM Limited + * Copyright (c) 2016-2018 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -79,10 +79,9 @@ class SimpleFreeList template<class InputIt> void addRegs(InputIt first, InputIt last) { - std::for_each(first, last, - [this](const typename InputIt::value_type& reg) { - this->freeRegs.push(®); - }); + std::for_each(first, last, [this](typename InputIt::value_type& reg) { + this->freeRegs.push(®); + }); } /** Get the next available register from the free list */ diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index 56c182564..5872f90d2 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -1480,11 +1480,14 @@ DefaultIEW<Impl>::writebackInsts() int dependents = instQueue.wakeDependents(inst); for (int i = 0; i < inst->numDestRegs(); i++) { - //mark as Ready - DPRINTF(IEW,"Setting Destination Register %i (%s)\n", - inst->renamedDestRegIdx(i)->index(), - inst->renamedDestRegIdx(i)->className()); - scoreboard->setReg(inst->renamedDestRegIdx(i)); + // Mark register as ready if not pinned + if (inst->renamedDestRegIdx(i)-> + getNumPinnedWritesToComplete() == 0) { + DPRINTF(IEW,"Setting Destination Register %i (%s)\n", + inst->renamedDestRegIdx(i)->index(), + inst->renamedDestRegIdx(i)->className()); + scoreboard->setReg(inst->renamedDestRegIdx(i)); + } } if (dependents) { diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh index 20b41e51d..c3e3fdf32 100644 --- a/src/cpu/o3/inst_queue_impl.hh +++ b/src/cpu/o3/inst_queue_impl.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, 2017-2018 ARM Limited + * Copyright (c) 2011-2014, 2017-2019 ARM Limited * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved. * @@ -1033,6 +1033,17 @@ InstructionQueue<Impl>::wakeDependents(const DynInstPtr &completed_inst) continue; } + // Avoid waking up dependents if the register is pinned + dest_reg->decrNumPinnedWritesToComplete(); + if (dest_reg->isPinned()) + completed_inst->setPinnedRegsWritten(); + + if (dest_reg->getNumPinnedWritesToComplete() != 0) { + DPRINTF(IQ, "Reg %d [%s] is pinned, skipping\n", + dest_reg->index(), dest_reg->className()); + continue; + } + DPRINTF(IQ, "Waking any dependents on register %i (%s).\n", dest_reg->index(), dest_reg->className()); diff --git a/src/cpu/o3/regfile.cc b/src/cpu/o3/regfile.cc index cc4bba6b0..afed8f9fa 100644 --- a/src/cpu/o3/regfile.cc +++ b/src/cpu/o3/regfile.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 ARM Limited + * Copyright (c) 2016-2018 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -216,8 +216,8 @@ PhysRegFile::getRegIds(RegClass cls) -> IdRange return std::make_pair(miscRegIds.begin(), miscRegIds.end()); } /* There is no way to make an empty iterator */ - return std::make_pair(PhysIds::const_iterator(), - PhysIds::const_iterator()); + return std::make_pair(PhysIds::iterator(), + PhysIds::iterator()); } PhysRegIdPtr diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh index d4b6602ad..352e6ac93 100644 --- a/src/cpu/o3/regfile.hh +++ b/src/cpu/o3/regfile.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 ARM Limited + * Copyright (c) 2016-2018 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -70,8 +70,8 @@ class PhysRegFile using VecMode = Enums::VecRegRenameMode; using VecPredRegContainer = TheISA::VecPredRegContainer; public: - using IdRange = std::pair<PhysIds::const_iterator, - PhysIds::const_iterator>; + using IdRange = std::pair<PhysIds::iterator, + PhysIds::iterator>; private: static constexpr auto NumVecElemPerVecReg = TheISA::NumVecElemPerVecReg; diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index 43f0b2746..d55bed655 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2012, 2014-2016 ARM Limited + * Copyright (c) 2010-2012, 2014-2019 ARM Limited * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved. * @@ -976,7 +976,9 @@ DefaultRename<Impl>::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid) assert(hb_it != historyBuffer[tid].end()); DPRINTF(Rename, "[tid:%i] Removing history entry with sequence " - "number %i.\n", tid, hb_it->instSeqNum); + "number %i (archReg: %d, newPhysReg: %d, prevPhysReg: %d).\n", + tid, hb_it->instSeqNum, hb_it->archReg.index(), + hb_it->newPhysReg->index(), hb_it->prevPhysReg->index()); // Undo the rename mapping only if it was really a change. // Special regs that are not really renamed (like misc regs @@ -1140,12 +1142,12 @@ DefaultRename<Impl>::renameDestRegs(const DynInstPtr &inst, ThreadID tid) typename RenameMap::RenameInfo rename_result; RegId flat_dest_regid = tc->flattenRegId(dest_reg); + flat_dest_regid.setNumPinnedWrites(dest_reg.getNumPinnedWrites()); rename_result = map->rename(flat_dest_regid); inst->flattenDestReg(dest_idx, flat_dest_regid); - // Mark Scoreboard entry as not ready scoreboard->unsetReg(rename_result.first); DPRINTF(Rename, diff --git a/src/cpu/o3/rename_map.cc b/src/cpu/o3/rename_map.cc index 9d912e582..64f3dbf8c 100644 --- a/src/cpu/o3/rename_map.cc +++ b/src/cpu/o3/rename_map.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017,2019 ARM Limited + * Copyright (c) 2016-2018,2019 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -78,16 +78,23 @@ SimpleRenameMap::rename(const RegId& arch_reg) // requested architected register. PhysRegIdPtr prev_reg = map[arch_reg.flatIndex()]; - // If it's not referencing the zero register, then rename the - // register. - if (arch_reg != zeroReg) { - renamed_reg = freeList->getReg(); - - map[arch_reg.flatIndex()] = renamed_reg; - } else { - // Otherwise return the zero register so nothing bad happens. + if (arch_reg == zeroReg) { assert(prev_reg->isZeroReg()); renamed_reg = prev_reg; + } else if (prev_reg->getNumPinnedWrites() > 0) { + // Do not rename if the register is pinned + assert(arch_reg.getNumPinnedWrites() == 0); // Prevent pinning the + // same register twice + DPRINTF(Rename, "Renaming pinned reg, numPinnedWrites %d\n", + prev_reg->getNumPinnedWrites()); + renamed_reg = prev_reg; + renamed_reg->decrNumPinnedWrites(); + } else { + renamed_reg = freeList->getReg(); + map[arch_reg.flatIndex()] = renamed_reg; + renamed_reg->setNumPinnedWrites(arch_reg.getNumPinnedWrites()); + renamed_reg->setNumPinnedWritesToComplete( + arch_reg.getNumPinnedWrites() + 1); } DPRINTF(Rename, "Renamed reg %d to physical reg %d (%d) old mapping was" |