#include "cpu/o3/inst_queue.hh"
#include "cpu/o3/mem_dep_unit.hh"
+template <class MemDepPred, class Impl>
+MemDepUnit<MemDepPred, Impl>::MemDepUnit()
+ : loadBarrier(false), loadBarrierSN(0), storeBarrier(false),
+ storeBarrierSN(0), iqPtr(NULL)
+{
+}
+
template <class MemDepPred, class Impl>
MemDepUnit<MemDepPred, Impl>::MemDepUnit(Params *params)
: depPred(params->SSITSize, params->LFSTSize), loadBarrier(false),
}
}
+#ifdef DEBUG
assert(MemDepEntry::memdep_count == 0);
+#endif
}
template <class MemDepPred, class Impl>
void
MemDepUnit<MemDepPred, Impl>::switchOut()
{
+ assert(instList[0].empty());
+ assert(instsToReplay.empty());
+ assert(memDepHash.empty());
+ // Clear any state.
for (int i = 0; i < Impl::MaxThreads; ++i) {
instList[i].clear();
}
void
MemDepUnit<MemDepPred, Impl>::takeOverFrom()
{
+ // Be sure to reset all state.
loadBarrier = storeBarrier = false;
loadBarrierSN = storeBarrierSN = 0;
depPred.clear();
// Add the MemDepEntry to the hash.
memDepHash.insert(
std::pair<InstSeqNum, MemDepEntryPtr>(inst->seqNum, inst_entry));
+#ifdef DEBUG
MemDepEntry::memdep_insert++;
+#endif
instList[tid].push_back(inst);
inst_entry->listIt = --(instList[tid].end());
// Check any barriers and the dependence predictor for any
- // producing stores.
+ // producing memrefs/stores.
InstSeqNum producing_store;
if (inst->isLoad() && loadBarrier) {
+ DPRINTF(MemDepUnit, "Load barrier [sn:%lli] in flight\n",
+ loadBarrierSN);
producing_store = loadBarrierSN;
} else if (inst->isStore() && storeBarrier) {
+ DPRINTF(MemDepUnit, "Store barrier [sn:%lli] in flight\n",
+ storeBarrierSN);
producing_store = storeBarrierSN;
} else {
producing_store = depPred.checkInst(inst->readPC());
// If there is a producing store, try to find the entry.
if (producing_store != 0) {
+ DPRINTF(MemDepUnit, "Searching for producer\n");
MemDepHashIt hash_it = memDepHash.find(producing_store);
if (hash_it != memDepHash.end()) {
store_entry = (*hash_it).second;
+ DPRINTF(MemDepUnit, "Proucer found\n");
}
}
inst_entry->regsReady = true;
}
+ // Clear the bit saying this instruction can issue.
+ inst->clearCanIssue();
+
// Add this instruction to the list of dependents.
store_entry->dependInsts.push_back(inst_entry);
// Insert the MemDepEntry into the hash.
memDepHash.insert(
std::pair<InstSeqNum, MemDepEntryPtr>(inst->seqNum, inst_entry));
+#ifdef DEBUG
MemDepEntry::memdep_insert++;
+#endif
// Add the instruction to the list.
instList[tid].push_back(inst);
MemDepUnit<MemDepPred, Impl>::insertBarrier(DynInstPtr &barr_inst)
{
InstSeqNum barr_sn = barr_inst->seqNum;
+ // Memory barriers block loads and stores, write barriers only stores.
if (barr_inst->isMemBarrier()) {
loadBarrier = true;
loadBarrierSN = barr_sn;
// Add the MemDepEntry to the hash.
memDepHash.insert(
std::pair<InstSeqNum, MemDepEntryPtr>(barr_sn, inst_entry));
+#ifdef DEBUG
MemDepEntry::memdep_insert++;
+#endif
// Add the instruction to the instruction list.
instList[tid].push_back(barr_inst);
MemDepUnit<MemDepPred, Impl>::replay(DynInstPtr &inst)
{
DynInstPtr temp_inst;
- bool found_inst = false;
+ // For now this replay function replays all waiting memory ops.
while (!instsToReplay.empty()) {
temp_inst = instsToReplay.front();
moveToReady(inst_entry);
- if (temp_inst == inst) {
- found_inst = true;
- }
-
instsToReplay.pop_front();
}
-
- assert(found_inst);
}
template <class MemDepPred, class Impl>
(*hash_it).second = NULL;
memDepHash.erase(hash_it);
+#ifdef DEBUG
MemDepEntry::memdep_erase++;
+#endif
}
template <class MemDepPred, class Impl>
(*hash_it).second = NULL;
memDepHash.erase(hash_it);
+#ifdef DEBUG
MemDepEntry::memdep_erase++;
+#endif
instList[tid].erase(squash_it--);
}
cprintf("Memory dependence hash size: %i\n", memDepHash.size());
+#ifdef DEBUG
cprintf("Memory dependence entries: %i\n", MemDepEntry::memdep_count);
+#endif
}