summaryrefslogtreecommitdiff
path: root/src/cpu/o3
diff options
context:
space:
mode:
authorGiacomo Gabrielli <giacomo.gabrielli@arm.com>2018-02-26 13:41:08 +0000
committerGiacomo Gabrielli <giacomo.gabrielli@arm.com>2019-05-30 15:55:59 +0000
commitfc61172dbe4e3a93f941227a1f36b7f07e97ab68 (patch)
tree264b957011c381cdda74d08642c5404ece247b45 /src/cpu/o3
parent5365c18f2e309b54d3e37dc98d8cca20ec9d4219 (diff)
downloadgem5-fc61172dbe4e3a93f941227a1f36b7f07e97ab68.tar.xz
cpu-o3: Add support for pinned writes
This patch adds support for pinning registers for a certain number of consecutive writes. This is only relevant for timing CPU models (functional-only models are unaffected), and it is primarily needed to provide a realistic execution model for micro-coded operations whose microops can write to non-overlapping portions of a destination register, e.g. vector gather loads. In those cases, this mechanism can disable renaming for a sequence of consecutive writes, thus making the resulting execution more efficient: allocating a new physical register for each microop would introduce a read-modify-write chain of dependencies, while with these modifications the microops can write back in parallel. Please note that this new feature is only leveraged by O3CPU for the time being. Additional authors: - Gabor Dozsa <gabor.dozsa@arm.com> Change-Id: I07eb5fdbd1fa0b748c9bdc1174d9f330fda34f81 Signed-off-by: Giacomo Gabrielli <giacomo.gabrielli@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/13520 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'src/cpu/o3')
-rw-r--r--src/cpu/o3/free_list.hh9
-rw-r--r--src/cpu/o3/iew_impl.hh13
-rw-r--r--src/cpu/o3/inst_queue_impl.hh13
-rw-r--r--src/cpu/o3/regfile.cc6
-rw-r--r--src/cpu/o3/regfile.hh6
-rw-r--r--src/cpu/o3/rename_impl.hh8
-rw-r--r--src/cpu/o3/rename_map.cc25
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(&reg);
- });
+ std::for_each(first, last, [this](typename InputIt::value_type& reg) {
+ this->freeRegs.push(&reg);
+ });
}
/** 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"